// hosts/claude-code/ux/skills-writer.ts — SPEC-588
// Builds and writes .claude/skills/planu-*.md files.
// 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';
import { assertEnglishOnlyArtifactText } from '../../../engine/spec-language/english-only.js';
const SKILLS_DIR = '.claude/skills';
/** Canonical skill slugs managed by SPEC-588. */
const SKILL_SLUGS = [
    'planu-new-spec',
    'planu-resume-work',
    'planu-release',
    'planu-validate',
    'planu-native',
];
/** Resolve the canonical skill-templates directory (works after tsc compilation). */
function resolveSkillTemplateDir() {
    const currentFile = fileURLToPath(new URL('.', import.meta.url));
    // From dist/hosts/claude-code/ux/ → dist/config/skill-templates/
    return join(currentFile, '../../../config/skill-templates');
}
async function readSkillTemplate(slug) {
    const templateDir = resolveSkillTemplateDir();
    try {
        return await readFile(join(templateDir, `${slug}.md`), 'utf-8');
    }
    catch {
        // Fallback minimal template when running without a build
        return `---\nname: ${slug}\ndescription: Planu skill — ${slug}.\ntriggers:\n  - ${slug}\n---\n\n# /${slug}\n\nPlanu SDD skill.\n`;
    }
}
/**
 * Parse the triggers list from a skill template's frontmatter.
 * Returns an empty array if the frontmatter is malformed or absent.
 */
function parseSkillTriggers(content) {
    const match = /^---\n([\s\S]*?)\n---/.exec(content);
    if (!match?.[1]) {
        return [];
    }
    // triggers section: "  - trigger phrase" lines
    const triggersMatch = /^triggers:\n((?:[ ]{2}- .+\n?)+)/m.exec(match[1]);
    if (!triggersMatch?.[1]) {
        return [];
    }
    return triggersMatch[1]
        .split('\n')
        .map((line) => {
        const item = /^\s*-\s*(.+)$/.exec(line);
        return item?.[1]?.trim() ?? '';
    })
        .filter(Boolean);
}
/**
 * Write a single skill file to <projectPath>/.claude/skills/<slug>.md.
 * Idempotent: only writes if the file is missing or content differs.
 */
async function writeSkillFile(projectPath, slug, content) {
    const skillsDir = join(projectPath, SKILLS_DIR);
    await mkdir(skillsDir, { recursive: true });
    const dest = join(skillsDir, `${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 };
    }
    assertEnglishOnlyArtifactText(content, 'skill');
    await writeFile(dest, content, 'utf-8');
    return { path: dest, created: existing === null };
}
/**
 * Scaffold .claude/skills/planu-*.md files for all 4 Planu workflow skills.
 * Only runs when Claude Code is detected (.claude/ dir exists at projectPath).
 * Idempotent — safe to call multiple times.
 */
export async function scaffoldPlanuSkills(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(SKILL_SLUGS.map(async (slug) => {
        const content = await readSkillTemplate(slug);
        const { path, created: wasCreated } = await writeSkillFile(projectPath, slug, content);
        if (wasCreated) {
            created.push(path);
        }
        else {
            skipped.push(path);
        }
    }));
    return { created, skipped };
}
/** Exported for tests — returns canonical skill slugs. */
export { SKILL_SLUGS };
/** Exported for tests — parses trigger list from frontmatter. */
export { parseSkillTriggers };
//# sourceMappingURL=skills-writer.js.map