import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { EventEmitter } from "events";
import * as fs from "fs/promises";
import * as path from "path";
import { execSync } from "child_process";
class EnhancedPreClearHooks extends EventEmitter {
  frameManager;
  dbManager;
  clearSurvival;
  handoffGenerator;
  projectRoot;
  constructor(frameManager, dbManager, clearSurvival, handoffGenerator, projectRoot) {
    super();
    this.frameManager = frameManager;
    this.dbManager = dbManager;
    this.clearSurvival = clearSurvival;
    this.handoffGenerator = handoffGenerator;
    this.projectRoot = projectRoot;
  }
  /**
   * Comprehensive pre-clear context capture
   */
  async capturePreClearContext(trigger) {
    console.log("\u{1F50D} Capturing comprehensive session context...");
    const context = {
      sessionId: await this.dbManager.getCurrentSessionId(),
      timestamp: (/* @__PURE__ */ new Date()).toISOString(),
      trigger,
      contextUsage: await this.analyzeContextUsage(),
      workingState: await this.captureWorkingState(),
      conversationState: await this.captureConversationState(),
      codeContext: await this.captureCodeContext(),
      cognitiveState: await this.captureCognitiveState(),
      environment: await this.captureEnvironment()
    };
    await this.saveEnhancedContext(context);
    this.emit("context:captured", context);
    console.log("\u2705 Comprehensive context captured");
    return context;
  }
  /**
   * Analyze current context usage with detailed breakdown
   */
  async analyzeContextUsage() {
    const sessionId = await this.dbManager.getCurrentSessionId();
    const frames = await this.dbManager.getRecentFrames(sessionId, 1e3);
    const traces = await this.dbManager.getRecentTraces(sessionId, 1e3);
    const frameTokens = frames.length * 200;
    const traceTokens = traces.length * 100;
    const conversationTokens = await this.estimateConversationTokens();
    const codeBlockTokens = await this.estimateCodeBlockTokens();
    const estimatedTokens = frameTokens + traceTokens + conversationTokens + codeBlockTokens;
    const maxTokens = 1e5;
    return {
      estimatedTokens,
      maxTokens,
      percentage: estimatedTokens / maxTokens,
      components: {
        frames: frameTokens,
        traces: traceTokens,
        conversations: conversationTokens,
        codeBlocks: codeBlockTokens
      }
    };
  }
  /**
   * Capture current working state
   */
  async captureWorkingState() {
    const activeFrame = await this.getCurrentActiveFrame();
    const recentTraces = await this.dbManager.getRecentTraces(
      await this.dbManager.getCurrentSessionId(),
      50
    );
    const activeFiles = this.extractActiveFiles(recentTraces);
    const recentCommands = recentTraces.filter((t) => t.type === "bash" || t.type === "command").map((t) => t.content.command).slice(0, 10);
    const pendingActions = this.extractPendingActions(activeFrame);
    const blockers = this.extractBlockers(recentTraces);
    return {
      currentTask: activeFrame?.description || "No active task",
      activeFiles,
      recentCommands,
      pendingActions,
      blockers
    };
  }
  /**
   * Capture conversation state and recent context
   */
  async captureConversationState() {
    const sessionId = await this.dbManager.getCurrentSessionId();
    const recentTraces = await this.dbManager.getRecentTraces(sessionId, 100);
    const userMessages = recentTraces.filter((t) => t.type === "user_message" || t.type === "input").slice(0, 5);
    const assistantMessages = recentTraces.filter((t) => t.type === "assistant_message" || t.type === "response").slice(0, 5);
    const conversationTopic = this.inferConversationTopic(recentTraces);
    const recentContext = this.buildRecentContextSummary(recentTraces);
    return {
      lastUserMessage: userMessages[0]?.content.message || "No recent user message",
      lastAssistantMessage: assistantMessages[0]?.content.message || "No recent assistant message",
      conversationTopic,
      messageCount: userMessages.length + assistantMessages.length,
      recentContext
    };
  }
  /**
   * Capture comprehensive code context
   */
  async captureCodeContext() {
    const gitStatus = await this.captureGitStatus();
    const modifiedFiles = await this.captureModifiedFiles();
    const testResults = await this.captureTestResults();
    const buildStatus = await this.captureBuildStatus();
    const dependencies = await this.captureDependencies();
    return {
      modifiedFiles,
      gitStatus,
      testResults,
      buildStatus,
      dependencies
    };
  }
  /**
   * Capture cognitive state and mental model
   */
  async captureCognitiveState() {
    const sessionId = await this.dbManager.getCurrentSessionId();
    const recentTraces = await this.dbManager.getRecentTraces(sessionId, 100);
    const currentFocus = await this.extractCurrentFocus();
    const mentalModel = this.extractMentalModel(recentTraces);
    const assumptions = this.extractAssumptions(recentTraces);
    const hypotheses = this.extractHypotheses(recentTraces);
    const explorationPaths = this.extractExplorationPaths(recentTraces);
    return {
      currentFocus,
      mentalModel,
      assumptions,
      hypotheses,
      explorationPaths
    };
  }
  /**
   * Capture environment snapshot
   */
  async captureEnvironment() {
    const gitBranch = await this.getCurrentGitBranch();
    const packageJson = await this.getPackageJson();
    const environmentVars = this.getRelevantEnvVars();
    return {
      workingDirectory: this.projectRoot,
      gitBranch,
      nodeVersion: process.version,
      packageJson,
      environmentVars
    };
  }
  /**
   * Save enhanced context to multiple locations for reliability
   */
  async saveEnhancedContext(context) {
    const timestamp = context.timestamp.replace(/[:.]/g, "-");
    const primaryPath = path.join(
      this.projectRoot,
      ".stackmemory",
      "pre-clear",
      `context-${timestamp}.json`
    );
    const backupPath = path.join(
      this.projectRoot,
      ".stackmemory",
      "pre-clear",
      "latest-context.json"
    );
    const markdownPath = path.join(
      this.projectRoot,
      ".stackmemory",
      "pre-clear",
      `context-${timestamp}.md`
    );
    await fs.mkdir(path.dirname(primaryPath), { recursive: true });
    await fs.writeFile(primaryPath, JSON.stringify(context, null, 2), "utf-8");
    await fs.writeFile(backupPath, JSON.stringify(context, null, 2), "utf-8");
    const markdown = this.generateMarkdownSummary(context);
    await fs.writeFile(markdownPath, markdown, "utf-8");
    console.log(
      `\u{1F4C1} Context saved to ${path.relative(this.projectRoot, primaryPath)}`
    );
  }
  /**
   * Generate human-readable markdown summary
   */
  generateMarkdownSummary(context) {
    const lines = [
      `# Pre-Clear Context Snapshot`,
      `**Timestamp**: ${new Date(context.timestamp).toLocaleString()}`,
      `**Trigger**: ${context.trigger}`,
      `**Session ID**: ${context.sessionId}`,
      "",
      `## \u{1F4CA} Context Usage`,
      `- **Total Tokens**: ${context.contextUsage.estimatedTokens.toLocaleString()} / ${context.contextUsage.maxTokens.toLocaleString()} (${Math.round(context.contextUsage.percentage * 100)}%)`,
      `- **Frames**: ${context.contextUsage.components.frames} tokens`,
      `- **Traces**: ${context.contextUsage.components.traces} tokens`,
      `- **Conversations**: ${context.contextUsage.components.conversations} tokens`,
      `- **Code Blocks**: ${context.contextUsage.components.codeBlocks} tokens`,
      "",
      `## \u{1F3AF} Current Work State`,
      `**Task**: ${context.workingState.currentTask}`,
      `**Active Files** (${context.workingState.activeFiles.length}):`,
      ...context.workingState.activeFiles.slice(0, 10).map((f) => `- ${f}`),
      "",
      `**Recent Commands**:`,
      ...context.workingState.recentCommands.slice(0, 5).map((c) => `- \`${c}\``),
      "",
      `## \u{1F4AC} Conversation State`,
      `**Topic**: ${context.conversationState.conversationTopic}`,
      `**Messages**: ${context.conversationState.messageCount}`,
      `**Last User**: ${context.conversationState.lastUserMessage.substring(0, 100)}...`,
      "",
      `## \u{1F4DD} Code Context`,
      `**Git Branch**: ${context.codeContext.gitStatus.branch}`,
      `**Modified Files**: ${context.codeContext.modifiedFiles.length}`,
      `**Staged**: ${context.codeContext.gitStatus.staged.length}`,
      `**Unstaged**: ${context.codeContext.gitStatus.unstaged.length}`,
      "",
      `## \u{1F9E0} Cognitive State`,
      `**Current Focus**: ${context.cognitiveState.currentFocus}`,
      `**Mental Model**:`,
      ...context.cognitiveState.mentalModel.slice(0, 5).map((m) => `- ${m}`),
      "",
      `## \u{1F30D} Environment`,
      `**Directory**: ${context.environment.workingDirectory}`,
      `**Node Version**: ${context.environment.nodeVersion}`,
      `**Git Branch**: ${context.environment.gitBranch}`,
      ""
    ];
    return lines.filter((l) => l !== void 0).join("\n");
  }
  // Helper methods (simplified implementations)
  async estimateConversationTokens() {
    return 15e3;
  }
  async estimateCodeBlockTokens() {
    return 8e3;
  }
  async getCurrentActiveFrame() {
    const stack = await this.frameManager.getStack();
    return stack.frames.find((f) => f.status === "open");
  }
  extractActiveFiles(traces) {
    const files = /* @__PURE__ */ new Set();
    traces.forEach((trace) => {
      if (trace.content?.file_path) files.add(trace.content.file_path);
      if (trace.content?.path) files.add(trace.content.path);
    });
    return Array.from(files).slice(0, 20);
  }
  extractPendingActions(frame) {
    if (!frame?.metadata?.pendingActions) return [];
    return frame.metadata.pendingActions;
  }
  extractBlockers(traces) {
    return traces.filter((t) => t.type === "error" && !t.metadata?.resolved).map((t) => t.content.error || "Unknown error").slice(0, 5);
  }
  inferConversationTopic(traces) {
    return "Code implementation and debugging";
  }
  buildRecentContextSummary(traces) {
    return traces.slice(0, 10).map(
      (t) => `${t.type}: ${t.content.summary || t.content.description || "No description"}`
    ).filter((s) => s.length > 10);
  }
  async captureGitStatus() {
    try {
      const branch = execSync("git branch --show-current", {
        encoding: "utf-8",
        cwd: this.projectRoot
      }).trim();
      const staged = execSync("git diff --cached --name-only", {
        encoding: "utf-8",
        cwd: this.projectRoot
      }).trim().split("\n").filter(Boolean);
      const unstaged = execSync("git diff --name-only", {
        encoding: "utf-8",
        cwd: this.projectRoot
      }).trim().split("\n").filter(Boolean);
      const untracked = execSync("git ls-files --others --exclude-standard", {
        encoding: "utf-8",
        cwd: this.projectRoot
      }).trim().split("\n").filter(Boolean);
      return {
        branch,
        ahead: 0,
        // Would implement git status parsing
        behind: 0,
        staged,
        unstaged,
        untracked,
        lastCommit: {
          hash: "abc123",
          // Would get from git log
          message: "Recent commit",
          timestamp: (/* @__PURE__ */ new Date()).toISOString()
        }
      };
    } catch (error) {
      return {
        branch: "unknown",
        ahead: 0,
        behind: 0,
        staged: [],
        unstaged: [],
        untracked: [],
        lastCommit: { hash: "", message: "", timestamp: "" }
      };
    }
  }
  async captureModifiedFiles() {
    try {
      const output = execSync("git diff --name-status", {
        encoding: "utf-8",
        cwd: this.projectRoot
      });
      return output.trim().split("\n").filter(Boolean).map((line) => {
        const [status, path2] = line.split("	");
        return {
          path: path2,
          lastModified: (/* @__PURE__ */ new Date()).toISOString(),
          changeType: status === "A" ? "created" : status === "D" ? "deleted" : "modified",
          lineChanges: { added: 0, removed: 0 },
          // Would get from git diff --stat
          purpose: "Code changes",
          relatedFiles: []
        };
      });
    } catch (error) {
      return [];
    }
  }
  async captureTestResults() {
    return void 0;
  }
  async captureBuildStatus() {
    return void 0;
  }
  async captureDependencies() {
    try {
      const packageJsonPath = path.join(this.projectRoot, "package.json");
      const content = await fs.readFile(packageJsonPath, "utf-8");
      const packageJson = JSON.parse(content);
      const deps = [];
      Object.entries(packageJson.dependencies || {}).forEach(
        ([name, version]) => {
          deps.push({
            name,
            version,
            type: "dependency",
            critical: ["react", "express", "next"].includes(name)
          });
        }
      );
      return deps;
    } catch (error) {
      return [];
    }
  }
  async extractCurrentFocus() {
    const activeFrame = await this.getCurrentActiveFrame();
    return activeFrame?.description || "No current focus";
  }
  extractMentalModel(traces) {
    return [
      "Component architecture",
      "Data flow patterns",
      "Error handling strategy"
    ];
  }
  extractAssumptions(traces) {
    return [
      "User input is validated",
      "Database is available",
      "Network is stable"
    ];
  }
  extractHypotheses(traces) {
    return [
      "Bug is in validation logic",
      "Performance issue is database-related"
    ];
  }
  extractExplorationPaths(traces) {
    return [
      "Try different algorithm",
      "Refactor data structure",
      "Add caching layer"
    ];
  }
  async getCurrentGitBranch() {
    try {
      return execSync("git branch --show-current", {
        encoding: "utf-8",
        cwd: this.projectRoot
      }).trim();
    } catch (error) {
      return "unknown";
    }
  }
  async getPackageJson() {
    try {
      const content = await fs.readFile(
        path.join(this.projectRoot, "package.json"),
        "utf-8"
      );
      return JSON.parse(content);
    } catch (error) {
      return null;
    }
  }
  getRelevantEnvVars() {
    const relevantVars = ["NODE_ENV", "DEBUG", "PORT", "DATABASE_URL"];
    const result = {};
    relevantVars.forEach((varName) => {
      if (process.env[varName]) {
        result[varName] = process.env[varName];
      }
    });
    return result;
  }
  /**
   * Restore context after /clear
   */
  async restoreFromEnhancedContext() {
    const latestPath = path.join(
      this.projectRoot,
      ".stackmemory",
      "pre-clear",
      "latest-context.json"
    );
    try {
      const content = await fs.readFile(latestPath, "utf-8");
      const context = JSON.parse(content);
      console.log("\u{1F4DA} Restoring enhanced context...");
      console.log(`  Session: ${context.sessionId}`);
      console.log(`  Task: ${context.workingState.currentTask}`);
      console.log(`  Files: ${context.workingState.activeFiles.length}`);
      console.log(`  Focus: ${context.cognitiveState.currentFocus}`);
      await this.clearSurvival.restoreFromLedger();
      return true;
    } catch (error) {
      console.error("Failed to restore enhanced context:", error);
      return false;
    }
  }
}
export {
  EnhancedPreClearHooks
};
//# sourceMappingURL=enhanced-pre-clear-hooks.js.map
