// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/validator/gates/convention-gates.ts — conventions and lint baseline gates
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
const PASCAL_CASE_PATTERN = /(?:^|\/)([A-Z][a-z]+(?:[A-Z][a-z]+)+)\.(?:ts|js|tsx|jsx)/;
/**
 * Read and parse planu/conventions.json. Returns null if absent.
 */
async function readConventions(projectPath) {
    const filePath = join(projectPath, 'planu', 'conventions.json');
    try {
        const raw = await readFile(filePath, 'utf-8');
        return JSON.parse(raw);
    }
    catch {
        return null;
    }
}
/**
 * Extract new file names mentioned in progress.md content.
 */
function extractNewFilesFromProgress(progressContent) {
    const pattern = /src\/[\w/.%-]+\.(?:ts|js|tsx|jsx)/g;
    const matches = progressContent.match(pattern) ?? [];
    return [...new Set(matches)];
}
/**
 * Gate: conventions-gate
 * Checks that new file names from progress.md don't violate detected conventions.
 */
export async function runConventionsGate(projectPath, progressContent) {
    const conventions = await readConventions(projectPath);
    if (!conventions) {
        return {
            gate: 'conventions-gate',
            status: 'skipped',
            reason: 'run init_project to detect conventions',
        };
    }
    if (!progressContent) {
        return { gate: 'conventions-gate', status: 'passed' };
    }
    // If convention is kebab-case files, check for PascalCase violations
    const fileNaming = conventions.fileNaming ?? '';
    if (!fileNaming.toLowerCase().includes('kebab')) {
        return { gate: 'conventions-gate', status: 'passed' };
    }
    const newFiles = extractNewFilesFromProgress(progressContent);
    const violations = newFiles.filter((f) => PASCAL_CASE_PATTERN.test(f));
    if (violations.length > 0) {
        return {
            gate: 'conventions-gate',
            status: 'failed',
            detail: `PascalCase file names violate kebab-case convention: ${violations.join(', ')}`,
        };
    }
    return { gate: 'conventions-gate', status: 'passed' };
}
/**
 * Gate: lint-baseline-gate
 * Validates that a lint baseline exists in conventions.json.
 * Cannot check regression without running linter — just validates baseline exists.
 */
export async function runLintBaselineGate(projectPath) {
    const conventions = await readConventions(projectPath);
    if (!conventions) {
        return {
            gate: 'lint-baseline-gate',
            status: 'skipped',
            reason: 'run init_project to detect conventions',
        };
    }
    const lintWarnings = conventions.baseline?.lintWarnings;
    if (lintWarnings === null || lintWarnings === undefined) {
        return {
            gate: 'lint-baseline-gate',
            status: 'skipped',
            reason: 'no lint baseline recorded',
        };
    }
    // Baseline exists — we accept it (can't check regression without running linter)
    return { gate: 'lint-baseline-gate', status: 'passed' };
}
//# sourceMappingURL=convention-gates.js.map