import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { execSync } from "child_process";
import {
  existsSync,
  readFileSync,
  readdirSync,
  statSync,
  writeFileSync,
  mkdirSync
} from "fs";
import { basename, join } from "path";
import { homedir, tmpdir } from "os";
import { globSync } from "glob";
let countTokens;
try {
  const tokenizer = await import("@anthropic-ai/tokenizer");
  countTokens = tokenizer.countTokens;
} catch {
  countTokens = (text) => Math.ceil(text.length / 3.5);
}
function loadSessionDecisions(projectRoot) {
  const storePath = join(projectRoot, ".stackmemory", "session-decisions.json");
  if (existsSync(storePath)) {
    try {
      const store = JSON.parse(readFileSync(storePath, "utf-8"));
      return store.decisions || [];
    } catch {
      return [];
    }
  }
  return [];
}
function loadReviewFeedback(projectRoot) {
  const storePath = join(projectRoot, ".stackmemory", "review-feedback.json");
  if (existsSync(storePath)) {
    try {
      const store = JSON.parse(
        readFileSync(storePath, "utf-8")
      );
      const cutoff = Date.now() - 24 * 60 * 60 * 1e3;
      return store.feedbacks.filter(
        (f) => new Date(f.timestamp).getTime() > cutoff
      );
    } catch {
      return [];
    }
  }
  return [];
}
function saveReviewFeedback(projectRoot, feedbacks) {
  const dir = join(projectRoot, ".stackmemory");
  if (!existsSync(dir)) {
    mkdirSync(dir, { recursive: true });
  }
  const storePath = join(dir, "review-feedback.json");
  let existing = [];
  if (existsSync(storePath)) {
    try {
      const store2 = JSON.parse(
        readFileSync(storePath, "utf-8")
      );
      existing = store2.feedbacks || [];
    } catch {
    }
  }
  const seen = /* @__PURE__ */ new Set();
  const merged = [];
  for (const f of [...feedbacks, ...existing]) {
    const key = `${f.source}:${f.keyPoints[0] || ""}`;
    if (!seen.has(key)) {
      seen.add(key);
      merged.push(f);
    }
  }
  const store = {
    feedbacks: merged.slice(0, 20),
    lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
  };
  writeFileSync(storePath, JSON.stringify(store, null, 2));
}
function findAgentOutputDirs(projectRoot) {
  const dirs = [];
  const tmpBase = process.env["TMPDIR"] || tmpdir() || "/tmp";
  const projectPathEncoded = projectRoot.replace(/\//g, "-").replace(/^-/, "");
  const pattern1 = join(tmpBase, "claude", `*${projectPathEncoded}*`, "tasks");
  try {
    const matches = globSync(pattern1);
    dirs.push(...matches);
  } catch {
  }
  if (tmpBase !== "/private/tmp") {
    const pattern2 = join(
      "/private/tmp",
      "claude",
      `*${projectPathEncoded}*`,
      "tasks"
    );
    try {
      const matches = globSync(pattern2);
      dirs.push(...matches);
    } catch {
    }
  }
  const homeClaudeDir = join(homedir(), ".claude", "projects");
  if (existsSync(homeClaudeDir)) {
    try {
      const projectDirs = readdirSync(homeClaudeDir);
      for (const d of projectDirs) {
        const tasksDir = join(homeClaudeDir, d, "tasks");
        if (existsSync(tasksDir)) {
          dirs.push(tasksDir);
        }
      }
    } catch {
    }
  }
  return [...new Set(dirs)];
}
class EnhancedHandoffGenerator {
  projectRoot;
  claudeProjectsDir;
  constructor(projectRoot) {
    this.projectRoot = projectRoot;
    this.claudeProjectsDir = join(homedir(), ".claude", "projects");
  }
  /**
   * Generate a high-efficacy handoff
   */
  async generate() {
    const handoff = {
      timestamp: (/* @__PURE__ */ new Date()).toISOString(),
      project: basename(this.projectRoot),
      branch: this.getCurrentBranch(),
      activeWork: await this.extractActiveWork(),
      decisions: await this.extractDecisions(),
      architecture: await this.extractArchitecture(),
      blockers: await this.extractBlockers(),
      reviewFeedback: await this.extractReviewFeedback(),
      nextActions: await this.extractNextActions(),
      codePatterns: await this.extractCodePatterns(),
      estimatedTokens: 0
    };
    const markdown = this.toMarkdown(handoff);
    handoff.estimatedTokens = countTokens(markdown);
    return handoff;
  }
  /**
   * Extract what we're currently building from git and recent files
   */
  async extractActiveWork() {
    const recentCommits = this.getRecentCommits(5);
    const recentFiles = this.getRecentlyModifiedFiles(10);
    let description = "Unknown - check git log for context";
    let status = "in_progress";
    if (recentCommits.length > 0) {
      const lastCommit = recentCommits[0];
      if (lastCommit.includes("feat:") || lastCommit.includes("implement")) {
        description = lastCommit.replace(/^[a-f0-9]+\s+/, "");
      } else if (lastCommit.includes("fix:")) {
        description = "Bug fix: " + lastCommit.replace(/^[a-f0-9]+\s+/, "");
      } else if (lastCommit.includes("chore:") || lastCommit.includes("refactor:")) {
        description = lastCommit.replace(/^[a-f0-9]+\s+/, "");
      } else {
        description = lastCommit.replace(/^[a-f0-9]+\s+/, "");
      }
    }
    const gitStatus = this.getGitStatus();
    if (gitStatus.includes("conflict")) {
      status = "blocked";
    }
    return {
      description,
      status,
      keyFiles: recentFiles.slice(0, 5),
      progress: recentCommits.length > 0 ? `${recentCommits.length} commits in current session` : void 0
    };
  }
  /**
   * Extract decisions from session store, git commits, and decision logs
   */
  async extractDecisions() {
    const decisions = [];
    const sessionDecisions = loadSessionDecisions(this.projectRoot);
    for (const d of sessionDecisions) {
      decisions.push({
        what: d.what,
        why: d.why,
        alternatives: d.alternatives
      });
    }
    const commits = this.getRecentCommits(20);
    for (const commit of commits) {
      if (commit.toLowerCase().includes("use ") || commit.toLowerCase().includes("switch to ") || commit.toLowerCase().includes("default to ") || commit.toLowerCase().includes("make ") && commit.toLowerCase().includes("optional")) {
        const commitText = commit.replace(/^[a-f0-9]+\s+/, "");
        if (!decisions.some((d) => d.what.includes(commitText.slice(0, 30)))) {
          decisions.push({
            what: commitText,
            why: "See commit for details"
          });
        }
      }
    }
    const decisionsFile = join(
      this.projectRoot,
      ".stackmemory",
      "decisions.md"
    );
    if (existsSync(decisionsFile)) {
      const content = readFileSync(decisionsFile, "utf-8");
      const parsed = this.parseDecisionsFile(content);
      decisions.push(...parsed);
    }
    return decisions.slice(0, 10);
  }
  /**
   * Parse a decisions.md file
   */
  parseDecisionsFile(content) {
    const decisions = [];
    const lines = content.split("\n");
    let currentDecision = null;
    for (const line of lines) {
      if (line.startsWith("## ") || line.startsWith("### ")) {
        if (currentDecision) {
          decisions.push(currentDecision);
        }
        currentDecision = { what: line.replace(/^#+\s+/, ""), why: "" };
      } else if (currentDecision && line.toLowerCase().includes("rationale:")) {
        currentDecision.why = line.replace(/rationale:\s*/i, "").trim();
      } else if (currentDecision && line.toLowerCase().includes("why:")) {
        currentDecision.why = line.replace(/why:\s*/i, "").trim();
      } else if (currentDecision && line.toLowerCase().includes("alternatives:")) {
        currentDecision.alternatives = [];
      } else if (currentDecision?.alternatives && line.trim().startsWith("-")) {
        currentDecision.alternatives.push(line.replace(/^\s*-\s*/, "").trim());
      }
    }
    if (currentDecision) {
      decisions.push(currentDecision);
    }
    return decisions;
  }
  /**
   * Extract architecture context from key files
   */
  async extractArchitecture() {
    const keyComponents = [];
    const patterns = [];
    const recentFiles = this.getRecentlyModifiedFiles(20);
    const codeFiles = recentFiles.filter(
      (f) => f.endsWith(".ts") || f.endsWith(".js") || f.endsWith(".tsx")
    );
    for (const file of codeFiles.slice(0, 8)) {
      const purpose = this.inferFilePurpose(file);
      if (purpose) {
        keyComponents.push({ file, purpose });
      }
    }
    if (codeFiles.some((f) => f.includes("/daemon/"))) {
      patterns.push("Daemon/background process pattern");
    }
    if (codeFiles.some((f) => f.includes("/cli/"))) {
      patterns.push("CLI command pattern");
    }
    if (codeFiles.some((f) => f.includes(".test.") || f.includes("__tests__"))) {
      patterns.push("Test files present");
    }
    if (codeFiles.some((f) => f.includes("/core/"))) {
      patterns.push("Core/domain separation");
    }
    return { keyComponents, patterns };
  }
  /**
   * Infer purpose from file name and path
   */
  inferFilePurpose(filePath) {
    const name = basename(filePath).replace(/\.(ts|js|tsx)$/, "");
    const path = filePath.toLowerCase();
    if (path.includes("daemon")) return "Background daemon/service";
    if (path.includes("cli/command")) return "CLI command handler";
    if (path.includes("config")) return "Configuration management";
    if (path.includes("storage")) return "Data storage layer";
    if (path.includes("handoff")) return "Session handoff logic";
    if (path.includes("service")) return "Service orchestration";
    if (path.includes("manager")) return "Resource/state management";
    if (path.includes("handler")) return "Event/request handler";
    if (path.includes("util") || path.includes("helper"))
      return "Utility functions";
    if (path.includes("types") || path.includes("interface"))
      return "Type definitions";
    if (path.includes("test")) return null;
    if (name.includes("-")) {
      return name.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
    }
    return null;
  }
  /**
   * Extract blockers from git status and recent errors
   */
  async extractBlockers() {
    const blockers = [];
    const gitStatus = this.getGitStatus();
    if (gitStatus.includes("UU ") || gitStatus.includes("both modified")) {
      blockers.push({
        issue: "Merge conflict detected",
        attempted: ["Check git status for affected files"],
        status: "open"
      });
    }
    try {
      const testResult = execSync("npm test 2>&1 || true", {
        encoding: "utf-8",
        cwd: this.projectRoot,
        timeout: 3e4
      });
      if (testResult.includes("FAIL") || testResult.includes("failed")) {
        const failCount = (testResult.match(/(\d+) failed/i) || ["", "?"])[1];
        blockers.push({
          issue: `Test failures: ${failCount} tests failing`,
          attempted: ["Run npm test for details"],
          status: "open"
        });
      }
    } catch {
    }
    try {
      const lintResult = execSync("npm run lint 2>&1 || true", {
        encoding: "utf-8",
        cwd: this.projectRoot,
        timeout: 3e4
      });
      if (lintResult.includes("error") && !lintResult.includes("0 errors")) {
        blockers.push({
          issue: "Lint errors present",
          attempted: ["Run npm run lint for details"],
          status: "open"
        });
      }
    } catch {
    }
    return blockers;
  }
  /**
   * Extract review feedback from agent output files and persisted storage
   */
  async extractReviewFeedback() {
    const feedback = [];
    const newFeedbacks = [];
    const outputDirs = findAgentOutputDirs(this.projectRoot);
    for (const tmpDir of outputDirs) {
      if (!existsSync(tmpDir)) continue;
      try {
        const files = readdirSync(tmpDir).filter((f) => f.endsWith(".output"));
        const recentFiles = files.map((f) => ({
          name: f,
          path: join(tmpDir, f),
          stat: statSync(join(tmpDir, f))
        })).filter((f) => Date.now() - f.stat.mtimeMs < 36e5).sort((a, b) => b.stat.mtimeMs - a.stat.mtimeMs).slice(0, 3);
        for (const file of recentFiles) {
          const content = readFileSync(file.path, "utf-8");
          const extracted = this.extractKeyPointsFromReview(content);
          if (extracted.keyPoints.length > 0) {
            feedback.push(extracted);
            newFeedbacks.push({
              timestamp: (/* @__PURE__ */ new Date()).toISOString(),
              source: extracted.source,
              keyPoints: extracted.keyPoints,
              actionItems: extracted.actionItems,
              sourceFile: file.name
            });
          }
        }
      } catch {
      }
    }
    if (newFeedbacks.length > 0) {
      saveReviewFeedback(this.projectRoot, newFeedbacks);
    }
    if (feedback.length === 0) {
      const stored = loadReviewFeedback(this.projectRoot);
      for (const s of stored.slice(0, 3)) {
        feedback.push({
          source: s.source,
          keyPoints: s.keyPoints,
          actionItems: s.actionItems
        });
      }
    }
    return feedback.length > 0 ? feedback : void 0;
  }
  /**
   * Extract key points from a review output
   */
  extractKeyPointsFromReview(content) {
    const keyPoints = [];
    const actionItems = [];
    let source = "Agent Review";
    if (content.includes("Product Manager") || content.includes("product-manager")) {
      source = "Product Manager";
    } else if (content.includes("Staff Architect") || content.includes("staff-architect")) {
      source = "Staff Architect";
    }
    const lines = content.split("\n");
    let inRecommendations = false;
    let inActionItems = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.toLowerCase().includes("recommendation") || trimmed.toLowerCase().includes("key finding")) {
        inRecommendations = true;
        inActionItems = false;
        continue;
      }
      if (trimmed.toLowerCase().includes("action") || trimmed.toLowerCase().includes("next step") || trimmed.toLowerCase().includes("priority")) {
        inActionItems = true;
        inRecommendations = false;
        continue;
      }
      if (trimmed.startsWith("- ") || trimmed.startsWith("* ") || /^\d+\.\s/.test(trimmed)) {
        const point = trimmed.replace(/^[-*]\s+/, "").replace(/^\d+\.\s+/, "");
        if (point.length > 10 && point.length < 200) {
          if (inActionItems) {
            actionItems.push(point);
          } else if (inRecommendations) {
            keyPoints.push(point);
          }
        }
      }
    }
    return {
      source,
      keyPoints: keyPoints.slice(0, 5),
      actionItems: actionItems.slice(0, 5)
    };
  }
  /**
   * Extract next actions from todo state and git
   */
  async extractNextActions() {
    const actions = [];
    const gitStatus = this.getGitStatus();
    if (gitStatus.trim()) {
      actions.push("Commit pending changes");
    }
    const recentFiles = this.getRecentlyModifiedFiles(5);
    for (const file of recentFiles) {
      try {
        const fullPath = join(this.projectRoot, file);
        if (existsSync(fullPath)) {
          const content = readFileSync(fullPath, "utf-8");
          const todos = content.match(/\/\/\s*TODO:?\s*.+/gi) || [];
          for (const todo of todos.slice(0, 2)) {
            actions.push(todo.replace(/\/\/\s*TODO:?\s*/i, "TODO: "));
          }
        }
      } catch {
      }
    }
    const tasksFile = join(this.projectRoot, ".stackmemory", "tasks.json");
    if (existsSync(tasksFile)) {
      try {
        const tasks = JSON.parse(readFileSync(tasksFile, "utf-8"));
        const pending = tasks.filter(
          (t) => t.status === "pending" || t.status === "in_progress"
        );
        for (const task of pending.slice(0, 3)) {
          actions.push(task.title || task.description);
        }
      } catch {
      }
    }
    return actions.slice(0, 8);
  }
  /**
   * Extract established code patterns
   */
  async extractCodePatterns() {
    const patterns = [];
    const eslintConfig = join(this.projectRoot, "eslint.config.js");
    if (existsSync(eslintConfig)) {
      const content = readFileSync(eslintConfig, "utf-8");
      if (content.includes("argsIgnorePattern")) {
        patterns.push("Underscore prefix for unused vars (_var)");
      }
      if (content.includes("ignores") && content.includes("test")) {
        patterns.push("Test files excluded from lint");
      }
    }
    const tsconfig = join(this.projectRoot, "tsconfig.json");
    if (existsSync(tsconfig)) {
      const content = readFileSync(tsconfig, "utf-8");
      if (content.includes('"strict": true')) {
        patterns.push("TypeScript strict mode enabled");
      }
      if (content.includes("ES2022") || content.includes("ESNext")) {
        patterns.push("ESM module system");
      }
    }
    return patterns;
  }
  /**
   * Get recent git commits
   */
  getRecentCommits(count) {
    try {
      const result = execSync(`git log --oneline -${count}`, {
        encoding: "utf-8",
        cwd: this.projectRoot
      });
      return result.trim().split("\n").filter(Boolean);
    } catch {
      return [];
    }
  }
  /**
   * Get current git branch
   */
  getCurrentBranch() {
    try {
      return execSync("git rev-parse --abbrev-ref HEAD", {
        encoding: "utf-8",
        cwd: this.projectRoot
      }).trim();
    } catch {
      return "unknown";
    }
  }
  /**
   * Get git status
   */
  getGitStatus() {
    try {
      return execSync("git status --short", {
        encoding: "utf-8",
        cwd: this.projectRoot
      });
    } catch {
      return "";
    }
  }
  /**
   * Get recently modified files
   */
  getRecentlyModifiedFiles(count) {
    try {
      const result = execSync(
        `git diff --name-only HEAD~10 HEAD 2>/dev/null || git diff --name-only`,
        {
          encoding: "utf-8",
          cwd: this.projectRoot
        }
      );
      return result.trim().split("\n").filter(Boolean).slice(0, count);
    } catch {
      return [];
    }
  }
  /**
   * Convert handoff to markdown (verbose format)
   */
  toMarkdown(handoff) {
    const lines = [];
    lines.push(`# Session Handoff - ${handoff.timestamp.split("T")[0]}`);
    lines.push("");
    lines.push(`**Project**: ${handoff.project}`);
    lines.push(`**Branch**: ${handoff.branch}`);
    lines.push("");
    lines.push("## Active Work");
    lines.push(`- **Building**: ${handoff.activeWork.description}`);
    lines.push(`- **Status**: ${handoff.activeWork.status}`);
    if (handoff.activeWork.keyFiles.length > 0) {
      lines.push(`- **Key files**: ${handoff.activeWork.keyFiles.join(", ")}`);
    }
    if (handoff.activeWork.progress) {
      lines.push(`- **Progress**: ${handoff.activeWork.progress}`);
    }
    lines.push("");
    if (handoff.decisions.length > 0) {
      lines.push("## Key Decisions");
      for (const d of handoff.decisions) {
        lines.push(`1. **${d.what}**`);
        if (d.why) {
          lines.push(`   - Rationale: ${d.why}`);
        }
        if (d.alternatives && d.alternatives.length > 0) {
          lines.push(
            `   - Alternatives considered: ${d.alternatives.join(", ")}`
          );
        }
      }
      lines.push("");
    }
    if (handoff.architecture.keyComponents.length > 0) {
      lines.push("## Architecture Context");
      for (const c of handoff.architecture.keyComponents) {
        lines.push(`- \`${c.file}\`: ${c.purpose}`);
      }
      if (handoff.architecture.patterns.length > 0) {
        lines.push("");
        lines.push("**Patterns**: " + handoff.architecture.patterns.join(", "));
      }
      lines.push("");
    }
    if (handoff.blockers.length > 0) {
      lines.push("## Blockers");
      for (const b of handoff.blockers) {
        lines.push(`- **${b.issue}** [${b.status}]`);
        if (b.attempted.length > 0) {
          lines.push(`  - Tried: ${b.attempted.join(", ")}`);
        }
      }
      lines.push("");
    }
    if (handoff.reviewFeedback && handoff.reviewFeedback.length > 0) {
      lines.push("## Review Feedback");
      for (const r of handoff.reviewFeedback) {
        lines.push(`### ${r.source}`);
        if (r.keyPoints.length > 0) {
          lines.push("**Key Points**:");
          for (const p of r.keyPoints) {
            lines.push(`- ${p}`);
          }
        }
        if (r.actionItems.length > 0) {
          lines.push("**Action Items**:");
          for (const a of r.actionItems) {
            lines.push(`- ${a}`);
          }
        }
        lines.push("");
      }
    }
    if (handoff.nextActions.length > 0) {
      lines.push("## Next Actions");
      for (const a of handoff.nextActions) {
        lines.push(`1. ${a}`);
      }
      lines.push("");
    }
    if (handoff.codePatterns && handoff.codePatterns.length > 0) {
      lines.push("## Established Patterns");
      for (const p of handoff.codePatterns) {
        lines.push(`- ${p}`);
      }
      lines.push("");
    }
    lines.push("---");
    lines.push(`*Estimated tokens: ~${handoff.estimatedTokens}*`);
    lines.push(`*Generated at ${handoff.timestamp}*`);
    return lines.join("\n");
  }
  /**
   * Convert handoff to compact format (~50% smaller)
   * Optimized for minimal context window usage
   */
  toCompact(handoff) {
    const lines = [];
    lines.push(`# Handoff: ${handoff.project}@${handoff.branch}`);
    const status = handoff.activeWork.status === "in_progress" ? "WIP" : handoff.activeWork.status;
    lines.push(`## Work: ${handoff.activeWork.description} [${status}]`);
    if (handoff.activeWork.keyFiles.length > 0) {
      const files = handoff.activeWork.keyFiles.slice(0, 5).map((f) => basename(f)).join(", ");
      const progress = handoff.activeWork.progress ? ` (${handoff.activeWork.progress.replace(" in current session", "")})` : "";
      lines.push(`Files: ${files}${progress}`);
    }
    if (handoff.decisions.length > 0) {
      lines.push("");
      lines.push("## Decisions");
      for (const d of handoff.decisions.slice(0, 7)) {
        const what = d.what.length > 40 ? d.what.slice(0, 37) + "..." : d.what;
        const why = d.why ? ` \u2192 ${d.why.slice(0, 50)}` : "";
        lines.push(`- ${what}${why}`);
      }
    }
    if (handoff.blockers.length > 0) {
      lines.push("");
      lines.push("## Blockers");
      for (const b of handoff.blockers) {
        const status2 = b.status === "open" ? "!" : "\u2713";
        const tried = b.attempted.length > 0 ? ` \u2192 ${b.attempted[0]}` : "";
        lines.push(`${status2} ${b.issue}${tried}`);
      }
    }
    if (handoff.reviewFeedback && handoff.reviewFeedback.length > 0) {
      lines.push("");
      lines.push("## Feedback");
      for (const r of handoff.reviewFeedback.slice(0, 2)) {
        lines.push(`[${r.source}]`);
        for (const p of r.keyPoints.slice(0, 3)) {
          lines.push(`- ${p.slice(0, 60)}`);
        }
        for (const a of r.actionItems.slice(0, 2)) {
          lines.push(`\u2192 ${a.slice(0, 60)}`);
        }
      }
    }
    if (handoff.nextActions.length > 0) {
      lines.push("");
      lines.push("## Next");
      for (const a of handoff.nextActions.slice(0, 3)) {
        lines.push(`- ${a.slice(0, 60)}`);
      }
    }
    lines.push("");
    lines.push(`---`);
    lines.push(
      `~${handoff.estimatedTokens} tokens | ${handoff.timestamp.split("T")[0]}`
    );
    return lines.join("\n");
  }
  /**
   * Convert handoff to ultra-compact pipe-delimited format (~90% smaller)
   * Optimized for minimal token usage while preserving critical context
   * Target: ~100-150 tokens
   */
  toUltraCompact(handoff) {
    const lines = [];
    const status = handoff.activeWork.status === "in_progress" ? "WIP" : handoff.activeWork.status;
    const commitCount = handoff.activeWork.progress?.match(/(\d+)/)?.[1] || "0";
    lines.push(
      `[H]${handoff.project}@${handoff.branch}|${status}|${commitCount}c`
    );
    if (handoff.activeWork.keyFiles.length > 0) {
      const files = handoff.activeWork.keyFiles.slice(0, 5).map((f) => basename(f).replace(/\.(ts|js|tsx|jsx)$/, "")).join(",");
      lines.push(`[F]${files}`);
    }
    if (handoff.decisions.length > 0) {
      const decisions = handoff.decisions.slice(0, 5).map((d) => {
        const what = d.what.slice(0, 25).replace(/\|/g, "/");
        const why = d.why ? `\u2192${d.why.slice(0, 20)}` : "";
        return `${what}${why}`;
      }).join("|");
      lines.push(`[D]${decisions}`);
    }
    if (handoff.blockers.length > 0) {
      const blockers = handoff.blockers.slice(0, 3).map((b) => {
        const marker = b.status === "open" ? "!" : "\u2713";
        const issue = b.issue.slice(0, 20).replace(/\|/g, "/");
        const tried = b.attempted.length > 0 ? `\u2192${b.attempted[0].slice(0, 15)}` : "";
        return `${marker}${issue}${tried}`;
      }).join("|");
      lines.push(`[B]${blockers}`);
    }
    if (handoff.nextActions.length > 0) {
      const actions = handoff.nextActions.slice(0, 3).map((a) => a.slice(0, 25).replace(/\|/g, "/")).join("|");
      lines.push(`[N]${actions}`);
    }
    const ultraCompactContent = lines.join("\n");
    const tokens = countTokens(ultraCompactContent);
    lines.push(`~${tokens}t|${handoff.timestamp.split("T")[0]}`);
    return lines.join("\n");
  }
  /**
   * Auto-select format based on context budget and content complexity
   * Returns: 'ultra' | 'compact' | 'verbose'
   */
  selectFormat(handoff, contextBudget) {
    if (contextBudget !== void 0) {
      if (contextBudget < 500) return "ultra";
      if (contextBudget < 2e3) return "compact";
      return "verbose";
    }
    const complexity = handoff.decisions.length + handoff.blockers.length + (handoff.reviewFeedback?.length || 0) * 2 + handoff.nextActions.length;
    if (complexity <= 3 && handoff.activeWork.keyFiles.length <= 3) {
      return "ultra";
    }
    if (complexity > 8 || handoff.reviewFeedback && handoff.reviewFeedback.length > 1) {
      return "verbose";
    }
    return "compact";
  }
  /**
   * Generate handoff in auto-selected format
   */
  toAutoFormat(handoff, contextBudget) {
    const format = this.selectFormat(handoff, contextBudget);
    switch (format) {
      case "ultra":
        return this.toUltraCompact(handoff);
      case "verbose":
        return this.toMarkdown(handoff);
      default:
        return this.toCompact(handoff);
    }
  }
}
export {
  EnhancedHandoffGenerator
};
//# sourceMappingURL=enhanced-handoff.js.map
