/**
 * Quint subprocess runner — mirrors the `validateBundle v2` pattern at
 * `engines/src/bundles/validate.ts:459-504`. Probes `quint --version`
 * once; skips cleanly if the binary isn't on PATH; runs `quint typecheck`
 * with a 15s per-file timeout; returns a structured result.
 *
 * Used by `analyse-runner.ts` to validate the per-spec Quint module
 * generated by `./index.ts`. Failed typecheck = lifecycle inconsistency
 * the LLM didn't catch.
 */
import { spawnSync } from 'child_process';
/**
 * Run `quint typecheck` against a single Quint file path. Returns a
 * structured result that the analyse-runner formats into a
 * `verify-behavior.txt` log alongside `verify.txt`.
 *
 * Skip semantics: when the `quint` CLI isn't installed (common on user
 * machines), we skip without failing — Quint is an opt-in formal layer,
 * not a hard dependency.
 */
export function runQuintTypecheck(filePath) {
    const start = Date.now();
    // Probe quint availability once. Match the validateBundle v2 pattern.
    const probe = spawnSync('quint', ['--version'], { encoding: 'utf8' });
    if (probe.error || probe.status !== 0) {
        return {
            status: 'skip',
            skipReason: 'quint CLI not on PATH (install via `npm install -g @informalsystems/quint`)',
            errors: [],
            durationMs: Date.now() - start,
        };
    }
    const res = spawnSync('quint', ['typecheck', filePath], {
        encoding: 'utf8',
        timeout: 15000,
    });
    if (res.status !== 0) {
        const raw = (res.stderr || res.stdout || '').trim();
        // Truncate per-error to 400 chars (slightly more than validateBundle v2's
        // 200; per-spec lifecycles can accumulate multiple errors at once and we
        // want the LLM's retry to see context).
        const errors = raw.split(/\n\n+/).map((e) => e.slice(0, 400)).filter(Boolean);
        return {
            status: 'fail',
            errors,
            durationMs: Date.now() - start,
        };
    }
    return {
        status: 'pass',
        errors: [],
        durationMs: Date.now() - start,
    };
}
/**
 * Format a `QuintRunResult` as a human-readable text block suitable for
 * writing to `verify-behavior.txt` in the run output dir, OR feeding back
 * to the LLM as an error message in a retry prompt.
 */
export function formatQuintResult(result, sourceFilePath) {
    const lines = [];
    lines.push(`Quint 5b deterministic gate — status: ${result.status} (${result.durationMs}ms)`);
    if (sourceFilePath)
        lines.push(`Source: ${sourceFilePath}`);
    if (result.status === 'skip') {
        lines.push(`Skipped: ${result.skipReason ?? 'unknown'}`);
    }
    else if (result.status === 'fail') {
        lines.push('Errors:');
        for (const err of result.errors) {
            lines.push(`  - ${err.replace(/\n/g, '\n    ')}`);
        }
    }
    else {
        lines.push('All lifecycle invariants typecheck cleanly.');
    }
    return lines.join('\n');
}
//# sourceMappingURL=runner.js.map