import {
  toKebabCase
} from "./chunk-KET4QQZB.js";
import {
  listPersonas,
  loadPersona
} from "./chunk-L3CEN42B.js";
import {
  GENERATED_HEADER_AGENT,
  VALID_PLATFORMS,
  applySyncPlan,
  computeSyncPlan
} from "./chunk-3ISINLYT.js";
import {
  resolvePersonasDir,
  resolveSkillsDir
} from "./chunk-6B6UN6SG.js";
import {
  CLIError,
  ExitCode,
  handleError
} from "./chunk-3WGJMBKH.js";

// src/commands/generate-agent-definitions.ts
import { Command } from "commander";
import * as fs from "fs";
import * as path from "path";
import * as os from "os";

// src/agent-definitions/generator.ts
var AGENT_DESCRIPTIONS = {
  "code-reviewer": "Perform code review and address review findings using harness methodology. Use when reviewing code, fixing review findings, responding to review feedback, or when a code review has produced issues that need to be addressed.",
  "task-executor": "Execute implementation plans task-by-task with state tracking, TDD, and verification. Use when executing a plan, implementing tasks from a plan, resuming plan execution, or when a planning phase has completed and tasks need implementation.",
  "parallel-coordinator": "Dispatch independent tasks across isolated agents for parallel execution. Use when multiple independent tasks need to run concurrently, splitting work across agents, or coordinating parallel implementation.",
  "architecture-enforcer": "Validate architectural constraints and dependency rules. Use when checking layer boundaries, detecting circular dependencies, or verifying import direction compliance.",
  "documentation-maintainer": "Keep documentation in sync with source code. Use when detecting documentation drift, validating doc coverage, or aligning docs with code changes.",
  "entropy-cleaner": "Detect and fix codebase entropy including drift, dead code, and pattern violations. Use when running cleanup, detecting dead code, or fixing pattern violations.",
  planner: "Create detailed implementation plans from specs with task breakdown, dependency ordering, and checkpoint placement. Use when planning a phase, breaking a spec into tasks, or creating an execution plan.",
  verifier: "Verify implementation completeness against spec and plan at three tiers (EXISTS, SUBSTANTIVE, WIRED). Use when checking if built code matches what was planned, validating phase completion, or auditing implementation quality."
};
var DEFAULT_TOOLS = ["Bash", "Read", "Write", "Edit", "Glob", "Grep"];
var GEMINI_TOOL_MAP = {
  Bash: "run_shell_command",
  Read: "read_file",
  Write: "write_file",
  Edit: "replace",
  Glob: "glob",
  Grep: "search_file_content"
};
function generateAgentDefinition(persona, skillContents) {
  const kebabName = toKebabCase(persona.name);
  const name = `harness-${kebabName}`;
  const description = AGENT_DESCRIPTIONS[kebabName] ?? persona.description;
  const methodologyParts = [];
  for (const skillName of persona.skills) {
    const content = skillContents.get(skillName);
    if (content) {
      methodologyParts.push(content);
    }
  }
  return {
    name,
    description,
    tools: [...DEFAULT_TOOLS],
    role: persona.role,
    skills: persona.skills,
    steps: persona.steps,
    methodology: methodologyParts.join("\n\n---\n\n")
  };
}

// src/agent-definitions/render-claude-code.ts
function formatStep(step, index) {
  if ("command" in step && step.command) {
    const cmd = step.command;
    const when = step.when ?? "always";
    return `${index + 1}. Run \`harness ${cmd}\` (${when})`;
  }
  if ("skill" in step && step.skill) {
    const skill = step.skill;
    const when = step.when ?? "always";
    return `${index + 1}. Execute ${skill} skill (${when})`;
  }
  return `${index + 1}. Unknown step`;
}
function renderClaudeCodeAgent(def) {
  const lines = ["---"];
  lines.push(`name: ${def.name}`);
  lines.push(`description: >`);
  lines.push(`  ${def.description}`);
  lines.push(`tools: ${def.tools.join(", ")}`);
  lines.push("---");
  lines.push("");
  lines.push(GENERATED_HEADER_AGENT);
  lines.push("");
  lines.push("## Role");
  lines.push("");
  lines.push(def.role);
  lines.push("");
  lines.push("## Skills");
  lines.push("");
  for (const skill of def.skills) {
    lines.push(`- ${skill}`);
  }
  lines.push("");
  lines.push("## Steps");
  lines.push("");
  def.steps.forEach((step, i) => {
    lines.push(formatStep(step, i));
  });
  lines.push("");
  if (def.methodology) {
    lines.push("## Methodology");
    lines.push("");
    lines.push(def.methodology);
    lines.push("");
  }
  return lines.join("\n");
}

// src/agent-definitions/render-gemini-cli.ts
function toGeminiToolName(tool) {
  return GEMINI_TOOL_MAP[tool] ?? tool;
}
function formatStep2(step, index) {
  if ("command" in step && step.command) {
    const cmd = step.command;
    const when = step.when ?? "always";
    return `${index + 1}. Run \`harness ${cmd}\` (${when})`;
  }
  if ("skill" in step && step.skill) {
    const skill = step.skill;
    const when = step.when ?? "always";
    return `${index + 1}. Execute ${skill} skill (${when})`;
  }
  return `${index + 1}. Unknown step`;
}
function renderGeminiAgent(def) {
  const lines = ["---"];
  lines.push(`name: ${def.name}`);
  lines.push(`description: >`);
  lines.push(`  ${def.description}`);
  if (def.tools.length > 0) {
    lines.push("tools:");
    for (const tool of def.tools) {
      lines.push(`  - ${toGeminiToolName(tool)}`);
    }
  }
  lines.push("---");
  lines.push("");
  lines.push(GENERATED_HEADER_AGENT);
  lines.push("");
  lines.push("## Role");
  lines.push("");
  lines.push(def.role);
  lines.push("");
  lines.push("## Skills");
  lines.push("");
  for (const skill of def.skills) {
    lines.push(`- ${skill}`);
  }
  lines.push("");
  lines.push("## Steps");
  lines.push("");
  def.steps.forEach((step, i) => {
    lines.push(formatStep2(step, i));
  });
  lines.push("");
  if (def.methodology) {
    lines.push("## Methodology");
    lines.push("");
    lines.push(def.methodology);
    lines.push("");
  }
  return lines.join("\n");
}

// src/agent-definitions/render-cursor.ts
function formatStep3(step, index) {
  if ("command" in step && step.command) {
    const cmd = step.command;
    const when = step.when ?? "always";
    return `${index + 1}. Run \`harness ${cmd}\` (${when})`;
  }
  if ("skill" in step && step.skill) {
    const skill = step.skill;
    const when = step.when ?? "always";
    return `${index + 1}. Execute ${skill} skill (${when})`;
  }
  return `${index + 1}. Unknown step`;
}
function renderCursorAgent(def) {
  const lines = ["---"];
  lines.push(`name: ${def.name}`);
  lines.push(`description: >`);
  lines.push(`  ${def.description}`);
  lines.push("---");
  lines.push("");
  lines.push(GENERATED_HEADER_AGENT);
  lines.push("");
  lines.push("## Role");
  lines.push("");
  lines.push(def.role);
  lines.push("");
  lines.push("## Skills");
  lines.push("");
  for (const skill of def.skills) {
    lines.push(`- ${skill}`);
  }
  lines.push("");
  lines.push("## Steps");
  lines.push("");
  def.steps.forEach((step, i) => {
    lines.push(formatStep3(step, i));
  });
  lines.push("");
  if (def.methodology) {
    lines.push("## Methodology");
    lines.push("");
    lines.push(def.methodology);
    lines.push("");
  }
  return lines.join("\n");
}

// src/commands/generate-agent-definitions.ts
function resolveOutputDir(platform, opts) {
  if (opts.output) {
    return path.join(opts.output, platform);
  }
  if (opts.global) {
    const home = os.homedir();
    if (platform === "claude-code") return path.join(home, ".claude", "agents");
    if (platform === "gemini-cli") return path.join(home, ".gemini", "agents");
    if (platform === "cursor") return path.join(home, ".cursor", "agents");
    return path.join(home, ".codex", "agents");
  }
  return path.join("agents", "agents", platform);
}
function loadSkillContent(skillName) {
  const skillsDir = resolveSkillsDir();
  const skillMdPath = path.join(skillsDir, skillName, "SKILL.md");
  if (!fs.existsSync(skillMdPath)) return null;
  return fs.readFileSync(skillMdPath, "utf-8");
}
function getRenderer(platform) {
  if (platform === "claude-code") return renderClaudeCodeAgent;
  if (platform === "cursor") return renderCursorAgent;
  return renderGeminiAgent;
}
function generateAgentDefinitions(opts) {
  const personasDir = resolvePersonasDir();
  const personaList = listPersonas(personasDir);
  if (!personaList.ok) return [];
  const personas = personaList.value.map((meta) => loadPersona(meta.filePath)).filter((r) => r.ok).map((r) => r.value);
  const allSkillNames = new Set(personas.flatMap((p) => p.skills));
  const skillContents = /* @__PURE__ */ new Map();
  for (const skillName of allSkillNames) {
    const content = loadSkillContent(skillName);
    if (content) {
      skillContents.set(skillName, content);
    }
  }
  const definitions = personas.map((p) => generateAgentDefinition(p, skillContents));
  const results = [];
  for (const platform of opts.platforms) {
    const outputDir = resolveOutputDir(platform, opts);
    const renderer = getRenderer(platform);
    const rendered = /* @__PURE__ */ new Map();
    for (const def of definitions) {
      const filename = `${def.name}.md`;
      rendered.set(filename, renderer(def));
    }
    const plan = computeSyncPlan(outputDir, rendered);
    if (!opts.dryRun) {
      applySyncPlan(outputDir, rendered, plan, false);
    }
    results.push({
      platform,
      added: plan.added,
      updated: plan.updated,
      removed: plan.removed,
      unchanged: plan.unchanged,
      outputDir
    });
  }
  return results;
}
function parsePlatforms(raw) {
  const platforms = raw.split(",").map((p) => p.trim());
  for (const p of platforms) {
    if (!VALID_PLATFORMS.includes(p)) {
      throw new CLIError(
        `Invalid platform "${p}". Valid platforms: ${VALID_PLATFORMS.join(", ")}`,
        ExitCode.VALIDATION_FAILED
      );
    }
  }
  return platforms;
}
function printAgentDefsResult(result, dryRun) {
  console.log(`
${result.platform} \u2192 ${result.outputDir}`);
  if (result.added.length > 0) {
    console.log(`  + ${result.added.length} new: ${result.added.join(", ")}`);
  }
  if (result.updated.length > 0) {
    console.log(`  ~ ${result.updated.length} updated: ${result.updated.join(", ")}`);
  }
  if (result.removed.length > 0) {
    console.log(`  - ${result.removed.length} removed: ${result.removed.join(", ")}`);
  }
  if (result.unchanged.length > 0) {
    console.log(`  = ${result.unchanged.length} unchanged`);
  }
  if (dryRun) {
    console.log("  (dry run \u2014 no files written)");
  }
}
function createGenerateAgentDefinitionsCommand() {
  return new Command("generate-agent-definitions").description(
    "Generate agent definition files from personas for Claude Code, Gemini CLI, and Cursor"
  ).option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global agent directories", false).option("--output <dir>", "Custom output directory").option("--dry-run", "Show what would change without writing", false).action(async (opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    try {
      const platforms = parsePlatforms(opts.platforms);
      const results = generateAgentDefinitions({
        platforms,
        global: opts.global,
        output: opts.output,
        dryRun: opts.dryRun
      });
      if (globalOpts.json) {
        console.log(JSON.stringify(results, null, 2));
        return;
      }
      for (const result of results) {
        printAgentDefsResult(result, opts.dryRun);
      }
    } catch (error) {
      handleError(error);
    }
  });
}

export {
  AGENT_DESCRIPTIONS,
  DEFAULT_TOOLS,
  GEMINI_TOOL_MAP,
  generateAgentDefinition,
  renderClaudeCodeAgent,
  renderGeminiAgent,
  generateAgentDefinitions,
  createGenerateAgentDefinitionsCommand
};
