/** * Walk-free code-index health (T14021): where the index stands against the * base branch and HEAD, which indexed files are gone from disk, the stale * policy, and the read-only per-project probe `cleo doctor --all-projects` * runs. Kept apart from `freshness.ts` so the doctor probe does not pull the * analysis pipeline (and its write path) into the health check. * * Code placed in `packages/core/` per Package-Boundary Check — verified against AGENTS.md. * * @module nexus/index-health * @task T14021 */ import type { GraphIndexFreshness } from '@cleocode/contracts'; import type { getNexusDb } from '../store/nexus-sqlite.js'; /** * Where the index stands against the base branch (T14007): the indexed * revision, the base ref and its commit, the commits the index has not seen, * and its age. Measured against the base ref, never the working tree or HEAD, * so a checkout on an old branch cannot make a stale index look fresh. * * @param db - Project graph database. * @param sourceRoot - Repository the index describes. * @param lastIndexedAt - Assessment time of the published generation. * @returns The revision fields of {@link GraphIndexFreshness}. */ export declare function measureAgainstBase(db: Awaited>, sourceRoot: string, lastIndexedAt: string | null): Promise>; /** * Indexed paths that no longer exist under `sourceRoot`, sorted (T14021). One * `existsSync` per path: no walk and no hashing. * * @param sourceRoot - Repository the index describes. * @param paths - Indexed POSIX paths relative to `sourceRoot`. * @returns The absent paths. */ export declare function missingIndexedPaths(sourceRoot: string, paths: Iterable): string[]; /** One project's code-index health, as `cleo doctor --all-projects` reports it (T14021). */ export interface NexusIndexHealth { /** A published generation with a file manifest exists. */ indexed: boolean; /** When the index was built. */ lastIndexedAt: string | null; /** Whole days since it was built. */ ageDays: number | null; /** Revision it indexed. */ indexedRevision: string | null; /** Commits on the base branch it has not seen (reported only). */ commitsBehind: number | null; /** Commits on the checked-out HEAD it has not seen; judged against the policy. */ commitsBehindHead: number | null; /** Indexed files no longer on disk. */ missingFileCount: number; /** A bounded sample of them. */ missingPaths: string[]; /** Too far behind HEAD for `nexus.freshness.maxCommitsBehind`, or holding missing files. */ stale: boolean; /** Why the index is stale or could not be read; absent when fresh. */ reason?: string; } /** * Probe a project's code index without a walk and without opening its store * through the migrating chokepoint (T14021): a read-only snapshot of the * project's `cleo.db`, the recorded manifest and revision, `git rev-list` * counts, and one `existsSync` per indexed file. A project that was never * indexed is not stale. * * @param projectRoot - Project whose index is probed. * @param dbPath - The project's `cleo.db`. * @param options - `sampleLimit` for missing paths. * @returns The index health; never throws. * @example * ```ts * const health = await probeNexusIndexHealth('/repo', '/repo/.cleo/cleo.db'); * if (health.stale) console.log(health.reason); * ``` */ export declare function probeNexusIndexHealth(projectRoot: string, dbPath: string, options?: { sampleLimit?: number; }): Promise; /** Default for `nexus.freshness.maxCommitsBehind` (T14008, lead decision 2026-10-24). */ export declare const DEFAULT_MAX_COMMITS_BEHIND = 50; /** Env var that accepts a stale answer for any graph query (T14008). */ export declare const NEXUS_ALLOW_STALE_ENV = "CLEO_NEXUS_ALLOW_STALE"; /** When a graph answer from a stale index is refused (T14008). */ export interface NexusStalePolicy { /** Most commits the index may trail the base branch. */ maxCommitsBehind: number; /** The caller accepted a stale answer (`--allow-stale` or {@link NEXUS_ALLOW_STALE_ENV}). */ allowStale: boolean; } /** * Read the stale-answer policy: `nexus.freshness.maxCommitsBehind` (default * {@link DEFAULT_MAX_COMMITS_BEHIND}) and the caller's opt-out. * * @param projectRoot - Project whose merged config is read. * @param options - `allowStale` from the caller's flag. * @returns The effective policy. * @example * ```ts * const policy = await readNexusStalePolicy(root, { allowStale: args['allow-stale'] }); * ``` */ export declare function readNexusStalePolicy(projectRoot: string, options?: { allowStale?: boolean; }): Promise; /** * Read an on/off env value (`true`/`false`, `1`/`0`, `yes`/`no`, `on`/`off`). * * @param value - Raw env value. * @returns The switch, or `undefined` when unrecognised. */ export declare function envSwitch(value: unknown): boolean | undefined; //# sourceMappingURL=index-health.d.ts.map