// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// SPEC-597-EXEMPT: canonical mapping (npm-package↔framework, keyword catalogue)
// — must enumerate framework names by design; no detection logic to migrate.
// engine/skill-generation/stack-content-generator.ts — SPEC-607
// Generates rich, stack-aware skill content from JSON templates and detected project stack.
import { readFile } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const DIR = dirname(fileURLToPath(import.meta.url));
const TEMPLATES_DIR = join(DIR, '../../config/skill-content-templates');
// Types SkillTemplateSection and SkillContentTemplate imported from types/skill-generation.ts
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------
async function loadTemplate(skillType) {
    const filePath = join(TEMPLATES_DIR, `${skillType}.json`);
    try {
        const content = await readFile(filePath, 'utf-8');
        return JSON.parse(content);
    }
    catch {
        return null;
    }
}
function pickSections(template, stack) {
    const sectionKeys = Object.keys(template.sections);
    const matchedKeys = new Set();
    // Always include default
    if ('default' in template.sections) {
        matchedKeys.add('default');
    }
    // Match by test runner
    if (stack.testRunner && sectionKeys.includes(stack.testRunner)) {
        matchedKeys.add(stack.testRunner);
    }
    // Match by frameworks
    for (const fw of stack.frameworks) {
        const lower = fw.toLowerCase();
        if (sectionKeys.includes(lower)) {
            matchedKeys.add(lower);
        }
        // Also match partial (e.g. 'nextjs' matches section 'nextjs')
        const partial = sectionKeys.find((k) => k !== 'default' && lower.includes(k));
        if (partial) {
            matchedKeys.add(partial);
        }
    }
    // Match by bundler
    if (stack.bundler && sectionKeys.includes(stack.bundler)) {
        matchedKeys.add(stack.bundler);
    }
    // Match by language
    if (sectionKeys.includes(stack.language)) {
        matchedKeys.add(stack.language);
    }
    return [...matchedKeys]
        .map((k) => template.sections[k])
        .filter(Boolean);
}
function buildBody(_template, sections, conventions) {
    const lines = [];
    const [defaultSection, ...extraSections] = sections;
    if (defaultSection) {
        lines.push(`# ${defaultSection.title}`);
        lines.push('');
        lines.push(defaultSection.description);
        lines.push('');
        if (defaultSection.steps.length > 0) {
            lines.push('## Steps');
            lines.push('');
            defaultSection.steps.forEach((s, i) => lines.push(`${i + 1}. ${s}`));
            lines.push('');
        }
    }
    for (const section of extraSections) {
        lines.push(`## ${section.title}`);
        lines.push('');
        lines.push(section.description);
        lines.push('');
        if (section.runCommand) {
            lines.push(`**Run**: \`${section.runCommand}\``);
            lines.push('');
        }
        if (section.steps.length > 0) {
            lines.push('### Steps');
            lines.push('');
            section.steps.forEach((s, i) => lines.push(`${i + 1}. ${s}`));
            lines.push('');
        }
        if (section.tips.length > 0) {
            lines.push('### Tips');
            lines.push('');
            section.tips.forEach((t) => lines.push(`- ${t}`));
            lines.push('');
        }
    }
    // Append convention hints
    if (conventions) {
        const hints = [];
        if (conventions.testLocation === 'separate') {
            hints.push('- Tests are in a separate directory from source files');
        }
        else if (conventions.testLocation === 'colocated') {
            hints.push('- Tests are colocated next to source files');
        }
        if (conventions.fileNaming) {
            hints.push(`- File naming convention: ${conventions.fileNaming}`);
        }
        if (hints.length > 0) {
            lines.push('## Project Conventions');
            lines.push('');
            lines.push(...hints);
            lines.push('');
        }
    }
    return lines.join('\n');
}
function buildFallbackContent(skillType, stack) {
    const title = skillType
        .split('-')
        .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
        .join(' ');
    const body = [
        `# ${title}`,
        '',
        `Skill for ${title.toLowerCase()} tasks in ${stack.language} projects.`,
        '',
        '## Steps',
        '',
        '1. Review the requirements',
        '2. Implement following project conventions',
        '3. Test and verify the result',
    ].join('\n');
    return {
        title,
        body,
        suggestedAllowedTools: ['Bash', 'Read', 'Write'],
        suggestedTriggers: [],
    };
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * Generate rich, stack-aware skill content for a given skill type and project stack.
 * Uses registry-driven JSON templates from src/config/skill-content-templates/.
 */
export async function generateSkillContent(skillType, stack, conventions) {
    const template = await loadTemplate(skillType);
    if (!template) {
        return buildFallbackContent(skillType, stack);
    }
    const sections = pickSections(template, stack);
    const body = buildBody(template, sections, conventions);
    return {
        title: template.title,
        body,
        suggestedAllowedTools: template.allowedTools,
        suggestedTriggers: template.triggers,
    };
}
/**
 * List skill types that have JSON template files available.
 */
export function listSupportedSkillTypes() {
    // Hardcoded list matches the files in src/config/skill-content-templates/
    return ['testing', 'deployment', 'error-handling'];
}
//# sourceMappingURL=stack-content-generator.js.map