// engine/dashboard/drift-score.ts — Planu drift score computation (SPEC-748)
// Computes a 0-100 score reflecting drift between done specs and codebase.
// Formula: (driftReviewCount / doneSpecsCount) * 100, rounded to 1 decimal.
import { readJson, hashProjectPath } from '../../storage/base-store.js';
import { listSpecs } from '../../storage/spec-store.js';
import { join } from 'node:path';
// ---------------------------------------------------------------------------
// Helper: round to one decimal (half-away-from-zero)
// ---------------------------------------------------------------------------
function roundOneDecimal(value) {
    return Math.round(value * 10) / 10;
}
// ---------------------------------------------------------------------------
// computePlanuDriftScore — main exported function
// ---------------------------------------------------------------------------
export async function computePlanuDriftScore(projectRoot) {
    const projectId = hashProjectPath(projectRoot);
    // Load pending.json — drift_review entries come from audit_specs_drift
    const pendingPath = join(projectRoot, 'planu', 'pending.json');
    const pendingData = await readJson(pendingPath, {});
    const entries = pendingData.entries ?? [];
    // Filter only drift_review kind entries
    const driftReviewEntries = entries.filter((e) => e.kind === 'drift_review');
    const driftReviewCount = driftReviewEntries.length;
    // Get lastAuditAt from the most recent drift_review entry's timestamp
    const lastAuditAt = driftReviewEntries.length > 0
        ? (driftReviewEntries
            .map((e) => e.timestamp)
            .filter((t) => typeof t === 'string')
            .sort()
            .at(-1) ?? null)
        : null;
    // Count done specs
    let doneSpecsCount = 0;
    try {
        const specs = await listSpecs(projectId);
        doneSpecsCount = specs.filter((s) => s.status === 'done').length;
    }
    catch {
        // If listSpecs fails, treat done count as 0 — score will be 0.0
    }
    // Compute score — guard division by zero
    const score = doneSpecsCount === 0 ? 0.0 : roundOneDecimal((driftReviewCount / doneSpecsCount) * 100);
    return {
        score,
        lastAuditAt,
        doneSpecsCount,
        driftReviewCount,
    };
}
// ---------------------------------------------------------------------------
// Badge colour helper — pure function
// ---------------------------------------------------------------------------
export function getDriftBadgeColour(score) {
    if (score <= 5) {
        return 'green';
    }
    if (score <= 15) {
        return 'amber';
    }
    return 'red';
}
//# sourceMappingURL=drift-score.js.map