// hosts/claude-code/ux/subagent-publisher.ts — SPEC-588
// Builds and writes .claude/agents/planu-*.md files (4 agents).
// Idempotent: skips files whose content already matches the template.
import { readFile, writeFile, mkdir, access } from 'node:fs/promises';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
const AGENTS_DIR = '.claude/agents';
/** Canonical agent slugs managed by SPEC-588. */
const AGENT_SLUGS = [
    'planu-spec-implementer',
    'planu-validator',
    'planu-challenger',
    'planu-readiness-auditor',
];
/**
 * Parse the frontmatter block from a markdown template to extract SubagentDefinition fields.
 * Returns null if the template has no valid frontmatter.
 */
function parseFrontmatter(content) {
    const match = /^---\n([\s\S]*?)\n---/.exec(content);
    if (!match?.[1]) {
        return null;
    }
    const block = match[1];
    const nameMatch = /^name:\s*(.+)$/m.exec(block);
    const descMatch = /^description:\s*(.+)$/m.exec(block);
    // tools section: "  - toolname" lines
    const toolsMatch = /^tools:\n((?:[ ]{2}- .+\n?)+)/m.exec(block);
    const name = nameMatch?.[1]?.trim() ?? '';
    const description = descMatch?.[1]?.trim() ?? '';
    const tools = [];
    if (toolsMatch?.[1]) {
        for (const line of toolsMatch[1].split('\n')) {
            const item = /^\s*-\s*(.+)$/.exec(line);
            if (item?.[1]) {
                tools.push(item[1].trim());
            }
        }
    }
    return { name, description, tools };
}
/** Resolve the canonical template directory (works after tsc compilation). */
function resolveTemplateDir() {
    const currentFile = fileURLToPath(new URL('.', import.meta.url));
    // From dist/hosts/claude-code/ux/ → dist/config/subagent-templates/
    return join(currentFile, '../../../config/subagent-templates');
}
async function readTemplate(slug) {
    const templateDir = resolveTemplateDir();
    try {
        return await readFile(join(templateDir, `${slug}.md`), 'utf-8');
    }
    catch {
        // Fallback minimal template when running without a build (e.g. in tests with mocked fs)
        return `---\nname: ${slug}\ndescription: Planu agent — ${slug}.\ntools:\n  - Bash\n---\n\n# ${slug}\n\nPlanu SDD agent.\n`;
    }
}
/**
 * Write a single agent file to <projectPath>/.claude/agents/<slug>.md.
 * Idempotent: only writes if the file is missing or content differs.
 * Returns the destination path and whether it was newly created.
 */
async function writeAgentFile(projectPath, slug, content) {
    const agentsDir = join(projectPath, AGENTS_DIR);
    await mkdir(agentsDir, { recursive: true });
    const dest = join(agentsDir, `${slug}.md`);
    let existing = null;
    try {
        existing = await readFile(dest, 'utf-8');
    }
    catch {
        // File doesn't exist — will create
    }
    if (existing === content) {
        return { path: dest, created: false };
    }
    await writeFile(dest, content, 'utf-8');
    return { path: dest, created: existing === null };
}
/**
 * Scaffold .claude/agents/planu-*.md files for all 4 Planu subagents.
 * Only runs when Claude Code is detected (.claude/ dir exists at projectPath).
 * Idempotent — safe to call multiple times.
 */
export async function scaffoldPlanuSubagents(projectPath) {
    // Only scaffold when Claude Code workspace is present
    const isClaudeCodeWorkspace = await access(join(projectPath, '.claude'))
        .then(() => true)
        .catch(() => false);
    if (!isClaudeCodeWorkspace) {
        return { created: [], skipped: [] };
    }
    const created = [];
    const skipped = [];
    await Promise.all(AGENT_SLUGS.map(async (slug) => {
        const content = await readTemplate(slug);
        const { path, created: wasCreated } = await writeAgentFile(projectPath, slug, content);
        if (wasCreated) {
            created.push(path);
        }
        else {
            skipped.push(path);
        }
    }));
    return { created, skipped };
}
/** Exported for tests — parses a template's frontmatter. */
export { parseFrontmatter };
/** Exported for tests — returns the 4 canonical agent slugs. */
export { AGENT_SLUGS };
// Allow introspection of which directory templates live in (tests use this)
export { resolveTemplateDir };
//# sourceMappingURL=subagent-publisher.js.map