// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/ai-cost-estimator/spec-loader.ts — Loads spec content and counts acceptance criteria.
// Extracted from core.ts to keep file sizes within limits.
import { readFile, readdir } from 'node:fs/promises';
import { join } from 'node:path';
import { stripFrontmatter } from '../frontmatter-parser.js';
/**
 * Reads canonical spec content from planu/specs.
 * Tries to find the spec directory by matching specId prefix.
 */
export async function loadSpecContent(specId, projectPath = process.cwd()) {
    const specsRoot = join(projectPath, 'planu', 'specs');
    let topEntries;
    try {
        topEntries = await readdir(specsRoot);
    }
    catch {
        throw new Error(`Spec directory not found at "${specsRoot}". ` +
            'Make sure you are running from the project root.');
    }
    const flatMatch = topEntries.find((entry) => entry.startsWith(specId));
    if (!flatMatch) {
        throw new Error(`Spec "${specId}" not found in "${specsRoot}". Check that the spec directory exists.`);
    }
    const specDir = join(specsRoot, flatMatch);
    const specPath = join(specDir, 'spec.md');
    try {
        const raw = await readFile(specPath, 'utf-8');
        return { content: stripFrontmatter(raw), specDir };
    }
    catch {
        throw new Error(`Spec "${specId}" has no canonical spec.md at "${specPath}". ` +
            'Run Planu migration/strict cleanup before estimating cost.');
    }
}
/** Counts acceptance criteria (lines starting with "- [ ]" or "- [x]") in spec content. */
export function countAcceptanceCriteria(specContent) {
    const matches = specContent.match(/^- \[[ xX]\]/gm);
    return matches?.length ?? 0;
}
/** Reads average tokens per call from usage.json if available. */
export async function readUsageAvgTokensPerCall() {
    try {
        const { readFile: rf } = await import('node:fs/promises');
        const raw = await rf('data/global/usage.json', 'utf-8');
        /* v8 ignore start */
        const log = JSON.parse(raw);
        if (!Array.isArray(log.events) || log.events.length === 0) {
            return undefined;
        }
        // Usage events don't track token counts — return undefined to use defaults
        return undefined;
        /* v8 ignore stop */
    }
    catch {
        return undefined;
    }
}
//# sourceMappingURL=spec-loader.js.map