// tools/create-skill.ts — SPEC-779: create_skill MCP tool
// Creates a host-aware skill for any Planu-using project.
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { detectHost } from '../engine/host-detection/detect-host.js';
import { validateEnglishOnlyArtifactText } from '../engine/spec-language/english-only.js';
import { hashContent } from '../engine/universal-rules/user-edit-detector.js';
import { hashProjectPath } from '../storage/base-store.js';
import { appendAutopilotLogEntry } from '../storage/autopilot-log-store.js';
// ---------------------------------------------------------------------------
// Host resolution
// ---------------------------------------------------------------------------
function resolveHost(input) {
    if (input.host !== 'auto') {
        return input.host;
    }
    const detected = detectHost();
    if (detected === 'codex') {
        return 'codex';
    }
    if (detected === 'gemini') {
        return 'gemini';
    }
    return 'claude-code';
}
// ---------------------------------------------------------------------------
// Writers per host
// ---------------------------------------------------------------------------
async function writeSkillForClaudeCode(name, content, description, projectPath, overwrite) {
    const dirPath = join(projectPath, '.claude', 'skills', name);
    const skillFilePath = join(dirPath, 'SKILL.md');
    // Overwrite protection
    try {
        const existing = await readFile(skillFilePath, 'utf-8');
        const existingHash = hashContent(existing);
        const newContent = buildSkillMd(name, description, content);
        const newHash = hashContent(newContent);
        if (existingHash !== newHash && !overwrite) {
            throw new Error(`Skill already exists at ${skillFilePath}. Pass overwriteExisting: true to replace.`);
        }
    }
    catch (err) {
        if (err instanceof Error && err.message.includes('overwriteExisting')) {
            throw err;
        }
        // File doesn't exist — proceed
    }
    await mkdir(dirPath, { recursive: true });
    const skillContent = buildSkillMd(name, description, content);
    await writeFile(skillFilePath, skillContent, 'utf-8');
    return { dirPath, skillFilePath };
}
function buildSkillMd(name, description, body) {
    const desc = description.length > 0 ? description : `Auto-generated skill: ${name}`;
    return `---\nname: ${name}\ndescription: "${desc}"\n---\n\n${body}\n`;
}
async function writeSkillForCodex(name, content, description, projectPath) {
    // For Codex, append to AGENTS.md with markers
    const agentsMdPath = join(projectPath, 'AGENTS.md');
    const open = `<!-- planu:skills:${name} -->`;
    const close = `<!-- /planu:skills:${name} -->`;
    const desc = description.length > 0 ? description : name;
    const block = `${open}\n## Skill: ${name}\n${desc}\n\n${content}\n${close}`;
    let existing;
    try {
        existing = await readFile(agentsMdPath, 'utf-8');
    }
    catch {
        existing = '';
    }
    const openIdx = existing.indexOf(open);
    const closeIdx = existing.indexOf(close);
    let updated;
    if (openIdx !== -1 && closeIdx !== -1 && closeIdx > openIdx) {
        updated = existing.slice(0, openIdx) + block + existing.slice(closeIdx + close.length);
    }
    else {
        updated = existing.length > 0 ? `${existing}\n\n${block}\n` : `${block}\n`;
    }
    await writeFile(agentsMdPath, updated, 'utf-8');
    return { dirPath: projectPath, skillFilePath: agentsMdPath };
}
async function writeSkillForGemini(name, content, description, projectPath) {
    const geminiDir = join(projectPath, '.gemini');
    const skillsDir = join(geminiDir, 'skills');
    await mkdir(skillsDir, { recursive: true });
    const skillFilePath = join(skillsDir, `${name}.md`);
    const desc = description.length > 0 ? description : name;
    const skillContent = buildSkillMd(name, desc, content);
    await writeFile(skillFilePath, skillContent, 'utf-8');
    return { dirPath: skillsDir, skillFilePath };
}
// ---------------------------------------------------------------------------
// Handler
// ---------------------------------------------------------------------------
export async function handleCreateSkill(input) {
    const { projectPath, name, content, overwriteExisting } = input;
    const description = input.description ?? '';
    const host = resolveHost(input);
    const languageValidation = validateEnglishOnlyArtifactText(`${name}\n\n${description}\n\n${content}`, 'skill');
    if (!languageValidation.ok) {
        return {
            content: [
                {
                    type: 'text',
                    text: `English-only skill gate blocked create_skill.\n\n` +
                        `${languageValidation.reason ?? 'Non-English prose detected.'}\n\n` +
                        'Rewrite the skill name, description, and content in English before creating it.',
                },
            ],
            isError: true,
            structuredContent: {
                error: 'SKILL_LANGUAGE_GATE_BLOCKED',
                detectedLanguage: languageValidation.detectedLanguage,
                signals: languageValidation.signals,
                fixHint: 'Rewrite skill artifacts in English.',
            },
        };
    }
    let result;
    try {
        switch (host) {
            case 'claude-code':
                result = await writeSkillForClaudeCode(name, content, description, projectPath, overwriteExisting === true);
                break;
            case 'codex':
                result = await writeSkillForCodex(name, content, description, projectPath);
                break;
            case 'gemini':
                result = await writeSkillForGemini(name, content, description, projectPath);
                break;
        }
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return {
            content: [{ type: 'text', text: msg }],
            isError: true,
        };
    }
    // Fire-and-forget autopilot log entry
    const projectId = hashProjectPath(projectPath);
    void appendAutopilotLogEntry(projectId, {
        specId: 'create_skill',
        hookName: 'skill_created',
        result: 'pass',
        timestamp: new Date().toISOString(),
        durationMs: 0,
    });
    return {
        content: [
            {
                type: 'text',
                text: `Skill \`${name}\` written to \`${result.skillFilePath}\` (host: ${host}).`,
            },
        ],
        isError: false,
    };
}
//# sourceMappingURL=create-skill.js.map