// engine/skill-discovery/progressive-splitter.ts — SPEC-606: Progressive disclosure for large skills
// Splits large skill content into a compact body + reference files so that
// the primary skill file stays within an LLM's practical context budget.
const DEFAULT_MAX_BODY_LINES = 200;
const FRONTMATTER_DELIMITER = '---';
const REFERENCE_SECTION_MARKER = /^#{1,3}\s+/;
/** Return true if the line starts the YAML frontmatter block. */
function isFrontmatterDelimiter(line) {
    return line.trim() === FRONTMATTER_DELIMITER;
}
/**
 * Extract YAML frontmatter (everything between the first two `---` delimiters)
 * and return it together with the body that follows.
 */
function extractFrontmatter(lines) {
    if (lines[0]?.trim() !== FRONTMATTER_DELIMITER) {
        return { frontmatter: [], body: lines };
    }
    const closeIdx = lines.slice(1).findIndex(isFrontmatterDelimiter);
    if (closeIdx === -1) {
        return { frontmatter: [], body: lines };
    }
    // +2 accounts for the slice(1) offset and the closing delimiter itself
    const frontmatter = lines.slice(0, closeIdx + 2);
    const body = lines.slice(closeIdx + 2);
    return { frontmatter, body };
}
/**
 * Find major section boundaries (markdown headings) in `lines`.
 * Returns an array of indices where a new section starts.
 */
function findSectionBoundaries(lines) {
    const boundaries = [];
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        if (line !== undefined && REFERENCE_SECTION_MARKER.test(line)) {
            boundaries.push(i);
        }
    }
    return boundaries;
}
/**
 * Split skill content into a compact body (≤ maxBodyLines) and overflow reference files.
 *
 * Algorithm:
 *  1. Extract frontmatter — always included in body.
 *  2. Walk through body sections. Include sections until maxBodyLines is reached.
 *  3. Overflow sections become reference files keyed by heading slug.
 *
 * If the content fits within maxBodyLines, references is empty.
 */
export function splitSkillContent(content, maxBodyLines = DEFAULT_MAX_BODY_LINES) {
    const lines = content.split('\n');
    if (lines.length <= maxBodyLines) {
        return { body: content, references: new Map() };
    }
    const { frontmatter, body: bodyLines } = extractFrontmatter(lines);
    const boundaries = findSectionBoundaries(bodyLines);
    const references = new Map();
    let includedLines = [...frontmatter];
    let sectionIdx = 0;
    for (const boundary of boundaries) {
        const nextBoundary = boundaries[sectionIdx + 1] ?? bodyLines.length;
        const sectionLines = bodyLines.slice(boundary, nextBoundary);
        sectionIdx++;
        if (includedLines.length + sectionLines.length <= maxBodyLines) {
            includedLines = [...includedLines, ...sectionLines];
        }
        else {
            const heading = bodyLines[boundary] ?? `section-${String(sectionIdx)}`;
            const slug = headingToSlug(heading);
            references.set(`${slug}.md`, sectionLines.join('\n'));
        }
    }
    // If references exist, append a navigation footer to the body
    if (references.size > 0) {
        includedLines.push('');
        includedLines.push('<!-- References (split for context efficiency) -->');
        for (const key of references.keys()) {
            includedLines.push(`<!-- See: references/${key} -->`);
        }
    }
    return { body: includedLines.join('\n'), references };
}
/** Convert a markdown heading line to a URL-safe slug. */
function headingToSlug(heading) {
    return (heading
        .replace(/^#+\s*/, '')
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-|-$/g, '')
        .slice(0, 64) || 'section');
}
//# sourceMappingURL=progressive-splitter.js.map