// tools/skill-registry/install.ts — Handler for skill_install tool (SPEC-150, updated SPEC-606)
import { installSkill, isSkillInstalled } from '../../engine/skill-registry/index.js';
import { splitSkillContent, writeSkillForAgents } from '../../engine/skill-discovery/index.js';
import { formatSuccess, formatWarning, toolResult } from '../response-helpers.js';
import { ti } from '../../i18n/index.js';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
const LARGE_CONTENT_THRESHOLD_LINES = 200;
const DEFAULT_AGENTS = ['claude'];
export async function handleSkillInstall(params) {
    try {
        const alreadyInstalled = await isSkillInstalled(params.projectPath, params.name);
        if (alreadyInstalled) {
            return toolResult(formatWarning('Skill already installed', `**${params.name}** is already in .claude/skills/. Use force to reinstall.`));
        }
        const source = params.source ?? params.registry ?? detectSource(params.name, params.url);
        const result = await installSkill(params.name, source, params.projectPath);
        // SPEC-606: Progressive splitting for large skill content
        const splitInfo = await applySplittingIfNeeded(result);
        // SPEC-606: Multi-agent write for requested agents
        const agents = resolveAgents(params.agents);
        const extraAgents = agents.filter((a) => a !== 'claude');
        let agentFiles = [];
        if (extraAgents.length > 0 && result.filesWritten[0]) {
            const skillContent = await readSkillContent(result.filesWritten[0]);
            const written = await writeSkillForAgents(skillContent, params.name, params.projectPath, extraAgents);
            agentFiles = written.map((f) => f.path);
        }
        const allFiles = [...result.filesWritten, ...splitInfo.referenceFiles, ...agentFiles];
        const lines = [
            `**${result.name}** installed from ${result.source}`,
            '',
            `Path: \`${result.installedPath}\``,
            `Files: ${allFiles.join(', ')}`,
        ];
        if (result.version) {
            lines.push(`Version: ${result.version}`);
        }
        if (result.securityScan) {
            lines.push('');
            if (result.securityScan.available) {
                lines.push(`Security scan: ${result.securityScan.severity} (${result.securityScan.recommendation}) — score ${String(result.securityScan.score)}/100`);
            }
            else {
                lines.push(`Security scan: unavailable (${result.securityScan.recommendation})`);
            }
        }
        if (splitInfo.splitApplied) {
            lines.push('');
            lines.push(`Note: Skill was split into ${String(splitInfo.referenceFiles.length + 1)} files for context efficiency (progressive disclosure).`);
        }
        if (agentFiles.length > 0) {
            lines.push('');
            lines.push(`Also installed for agents: ${extraAgents.join(', ')}`);
        }
        if (result.hasScripts) {
            lines.push('');
            lines.push('Warning: This skill includes executable scripts in `scripts/`. Review them before running.');
        }
        return toolResult(formatSuccess('Skill installed', lines.join('\n')), result);
    }
    catch (error) {
        const msg = error instanceof Error ? error.message : String(error);
        return toolResult(ti('errors.internalError', { message: msg }), undefined, true);
    }
}
function detectSource(name, url) {
    if (url) {
        if (url.includes('github.com')) {
            return 'github';
        }
        if (url.includes('skills.sh')) {
            return 'skillssh';
        }
        return 'external';
    }
    if (name.startsWith('anthropics/') || name.startsWith('anthropic/')) {
        return 'anthropic';
    }
    if (name.includes('/')) {
        return 'skillssh';
    }
    return 'anthropic';
}
/** Apply progressive splitting if the installed skill content exceeds the threshold. */
async function applySplittingIfNeeded(result) {
    const primaryFile = result.filesWritten[0];
    if (!primaryFile) {
        return { splitApplied: false, referenceFiles: [] };
    }
    let content;
    try {
        content = await fs.readFile(primaryFile, 'utf-8');
    }
    catch {
        return { splitApplied: false, referenceFiles: [] };
    }
    const split = splitSkillContent(content, LARGE_CONTENT_THRESHOLD_LINES);
    if (split.references.size === 0) {
        return { splitApplied: false, referenceFiles: [] };
    }
    // Write the compact body back to the primary file
    await fs.writeFile(primaryFile, split.body, 'utf-8');
    // Write reference files alongside the skill
    const skillDir = path.dirname(primaryFile);
    const refDir = path.join(skillDir, 'references');
    await fs.mkdir(refDir, { recursive: true });
    const referenceFiles = [];
    for (const [filename, refContent] of split.references) {
        const refPath = path.join(refDir, filename);
        await fs.writeFile(refPath, refContent, 'utf-8');
        referenceFiles.push(refPath);
    }
    return { splitApplied: true, referenceFiles };
}
/** Read skill content from disk, returning empty string on failure. */
async function readSkillContent(filePath) {
    try {
        return await fs.readFile(filePath, 'utf-8');
    }
    catch {
        return '';
    }
}
/** Resolve requested agents to valid SkillWriteTarget values. */
function resolveAgents(agents) {
    if (!agents || agents.length === 0) {
        return DEFAULT_AGENTS;
    }
    const valid = ['claude', 'cursor', 'copilot', 'gemini'];
    const resolved = agents.filter((a) => valid.includes(a));
    return resolved.length > 0 ? resolved : DEFAULT_AGENTS;
}
//# sourceMappingURL=install.js.map