import { probeFleetStats, probeLocalStats, type DeviceStats } from './health.js';
import type { DeviceProfile } from './registry.js';
/**
 * Freshness bound for a cached row. Matches the agent-count mirror's window
 * (`AGENT_STATUS_STALE_MS` in `commands/ssh.ts`) so both columns of
 * `devices list` / `fleet status` share one staleness model. A row older than
 * this is never served as current — it is re-probed live (and the probe result
 * rewrites the cache, unreachable boxes included).
 */
export declare const STATS_STALE_MS: number;
/** True when a cached row is still within {@link STATS_STALE_MS}. */
export declare function isFreshDeviceStats(stats: DeviceStats, now?: number): boolean;
/**
 * Carry a device's last successfully-probed hardware facts onto a row whose
 * probe just came back unreachable (RUSH-3096).
 *
 * A failed probe knows nothing about the box — `probeDeviceStats` resolves
 * `{ host, reachable: false, fetchedAt }` — and that bare row then replaced the
 * cached one, so `agents devices list` rendered an offline device with an empty
 * `spec` cell and forgot its cores/RAM/disk until it came back up. Cores, total
 * RAM, and root-disk capacity do not change while a machine is down, so they
 * survive the failure; `loadPercent`, `memPercent`, and the free-byte counts are
 * current-state readings and stay absent rather than render a stale number as
 * live.
 *
 * `specsFetchedAt` keeps the moment the facts were actually observed while
 * `fetchedAt` advances to this attempt, so the row reads "this hardware, seen
 * then; unreachable, as of now" instead of backdating a reading that never
 * happened. A reachable probe is returned untouched — its own reading is the
 * truth, including a fact the box has stopped reporting.
 */
export declare function retainHardwareFacts(probed: DeviceStats, prior: DeviceStats | undefined): DeviceStats;
/** Read the whole cache (best-effort; a missing/corrupt file yields an empty map). */
export declare function readStatsCache(): Record<string, DeviceStats>;
/**
 * Merge freshly-probed rows into the on-disk cache (best-effort write). Rows for
 * devices not in `entries` are preserved, so a partial probe (gap-fill, or a
 * single-device refresh) never drops the rest of the fleet's cached stats.
 */
export declare function writeStatsCache(entries: Record<string, DeviceStats>): void;
/** Drop one removed device so cache-only rows cannot outlive the registry. */
export declare function removeStatsCacheEntry(name: string): void;
/** Immutable cache pruning primitive, exported for lifecycle regression tests. */
export declare function pruneStatsCache(entries: Record<string, DeviceStats>, name: string): Record<string, DeviceStats>;
export interface FleetStatsResult {
    /** name → stats for every requested device (cache-served + freshly probed). */
    stats: Map<string, DeviceStats>;
    /** Oldest `fetchedAt` among the returned rows, or null when empty. Drives the
     *  "as of …" freshness note. */
    oldestFetchedAt: number | null;
    /** True when at least one row was served from cache rather than probed this call. */
    servedFromCache: boolean;
}
export interface LoadFleetStatsOptions {
    /** Skip the cache and live-probe every device (the `--refresh`/`--live` path). */
    forceRefresh?: boolean;
    /** Device name of THIS machine — always probed locally (no ssh), never cached-served. */
    selfName?: string;
    /** Injectable probes + cache IO for tests (default to the real ssh/local/disk ones). */
    probeFleet?: typeof probeFleetStats;
    probeLocal?: typeof probeLocalStats;
    readCache?: typeof readStatsCache;
    writeCache?: typeof writeStatsCache;
    /** Clock override for tests (drives the {@link STATS_STALE_MS} bound). */
    now?: number;
}
/**
 * Load fleet stats cache-first. See the module doc for the default vs
 * `--refresh` behaviour. Never throws — an unreachable box degrades to a
 * `reachable: false` row exactly as the live probe does.
 */
export declare function loadFleetStats(devices: DeviceProfile[], opts?: LoadFleetStatsOptions): Promise<FleetStatsResult>;
