/** * Fleet view (`nexus.projects.fleet`, T12513): every project, where it lives * on each device, and its last recorded git state — local (branch, HEAD, * dirty) and remote (upstream, ahead/behind as of the last fetch) — with * staleness flags. * * ## Read path only * * This module never runs git and never touches a project's own store. It * reads the rows `nexus.projects.status` (T12511) recorded in the global * `cleo.db`: `nexus_project_registry`, `nexus_project_locations`, * `nexus_project_git_state` and `nexus_devices`. Freshness is reported, not * repaired: `git.probedAt` / `probeStale` say how old the local picture is and * `git.remote.fetchedAt` / `remote.stale` how old the remote picture is. A * live refresh is the caller's explicit choice (`--refresh`), which runs the * bounded probe for THIS device only — other devices' rows can only be * refreshed on those devices. * * ## Cost per call * * A fixed number of SQL statements, independent of the number of projects: * * 1. `COUNT(*)` of the registry (total). * 2. `COUNT(*)` of the registry under the filter (matched). * 3. One page of registry rows, `ORDER BY name, project_id LIMIT ? OFFSET ?`. * 4. The locations + git state of THAT page only (`project_id IN (page)`). * 5. One aggregate pass over locations for the project-level summary. * 6. One `GROUP BY device_id` pass for the per-device summary. * 7. The device table (one row per machine). * * `summary` and `devices` are scoped by the `device` filter only; the flag * filters narrow `matched` and the page, never those counts. * * Filters are one correlated `EXISTS` per registry row, and every join is on * the `(project_id, device_id, path)` primary key both location tables share, * so no statement scans a table per project. * * @task T12513 * @epic T12496 */ import type { NexusFleetFlag, NexusProjectsFleetParams, NexusProjectsFleetResult } from '@cleocode/contracts'; import type { NodeSQLiteDatabase } from 'drizzle-orm/node-sqlite'; import { type ProjectGitStateRow, type ProjectLocationRow } from '../store/schema/nexus-schema.js'; /** Paging defaults for the fleet view. */ export declare const FLEET_DEFAULTS: { /** Projects per page. */ readonly limit: 50; /** Largest page a caller may ask for (`0` still means "every match"). */ readonly maxLimit: 500; }; /** Registry handle subset the fleet view needs. */ export type FleetStoreHandle = Pick; /** * Flags of one location, computed from its rows. Must agree with {@link flagSql}. * * @param loc - Location row. * @param git - Its probe row, or `null` when never probed. * @param cutoff - ISO instant; older probes and fetches are stale. * @returns The flags that hold, in canonical order. */ export declare function locationFlags(loc: Pick, git: ProjectGitStateRow | null, cutoff: string): NexusFleetFlag[]; /** * Read the fleet view: counts first, then one page of projects with every * visible location, its device and its last recorded git state. * * Read-only and git-free; see the module header for the per-call cost. * * @param db - Global registry handle (`getNexusRegistryDb`). * @param params - Filters, staleness window and paging. * @param overrides - Device id and clock (tests). * @returns The fleet view. * @throws {NexusDeviceNotFoundError} When `device` names no known device. * @example * ```ts * const view = listFleetStatus(await getNexusRegistryDb(getCleoHome()), { dirty: true, limit: 20 }); * console.log(view.matched, view.projects.map((p) => p.name)); * ``` */ export declare function listFleetStatus(db: FleetStoreHandle, params?: NexusProjectsFleetParams, overrides?: { deviceId?: string; now?: Date; }): NexusProjectsFleetResult; //# sourceMappingURL=fleet-status.d.ts.map