/**
 * Health endpoints — surface git working-tree state and vector-index health
 * so operators can detect drift / index lag before it accumulates.
 *
 * The dirty endpoint reads `gitService.hasUncommittedChanges()` directly
 * (NOT the SessionManager dirty Map) — the in-memory map is the very
 * thing we don't trust, so the health signal must come from disk truth.
 *
 * Vector index health is rolled up from VectorService's in-memory counters.
 * Index ops are fire-and-forget at the call sites (graph.ts) so we can't
 * fail writes when indexing fails; the operator-visible signal lives here
 * instead. Audit (2026-05) flagged the previous `.catch(console.warn)` as
 * effectively undetectable.
 */
const STALE_THRESHOLD_MS = 30 * 60_000; // 30 minutes
export async function registerHealthApiRoutes(fastify, workspaceManager, sessionManager) {
    // GET /api/health/dirty — per-repo uncommitted state + vector-index health
    fastify.get('/api/health/dirty', async (_req, reply) => {
        const now = Date.now();
        const repoStates = [];
        for (const repoName of workspaceManager.getRepoNames()) {
            try {
                const graph = workspaceManager.getGraph(repoName);
                const gitService = graph.getGitService();
                if (!gitService)
                    continue;
                const status = gitService.getStatus();
                const fileCount = status.modified.length +
                    status.added.length +
                    status.deleted.length +
                    status.untracked.length;
                repoStates.push({
                    repo: repoName,
                    dirty: fileCount > 0,
                    fileCount,
                    modified: status.modified.length,
                    added: status.added.length,
                    deleted: status.deleted.length,
                    untracked: status.untracked.length,
                });
            }
            catch {
                // Skip unloadable repos.
            }
        }
        const sessions = sessionManager.getDirtySessions().map(s => ({
            repo: s.repo,
            user: s.user,
            entityCount: s.entities.length,
            ageMinutes: Math.floor((now - s.lastActivityAt) / 60_000),
        }));
        // Vector-index health: rolled up from in-memory counters on
        // VectorService. `null` when the workspace was started without a vector
        // service (rare; only if construction failed). Operators want both
        // `failureCount` (steady-state leak detector) and `inFlight` (queue
        // depth — sustained growth here means writes are outpacing indexing).
        const vector = workspaceManager.vectorService?.getHealth() ?? null;
        const dirtyRepos = repoStates.filter(r => r.dirty);
        const staleSessions = sessions.filter(s => s.ageMinutes >= STALE_THRESHOLD_MS / 60_000);
        const vectorUnhealthy = !!(vector && !vector.healthy);
        const healthy = dirtyRepos.length === 0 && staleSessions.length === 0 && !vectorUnhealthy;
        return reply.send({
            healthy,
            checkedAt: new Date().toISOString(),
            repos: repoStates,
            sessions,
            dirtyRepoCount: dirtyRepos.length,
            staleSessionCount: staleSessions.length,
            staleThresholdMinutes: STALE_THRESHOLD_MS / 60_000,
            vector,
        });
    });
}
//# sourceMappingURL=health.js.map