import type { DeviceGrantStore, DeviceGrantSweepReport } from './device-grants.js'; import type { DeviceArtifactSweepReport, DeviceCaptureArtifactStore } from './device-capture-artifacts.js'; /** What one full pass removed, across both stores. */ export interface DeviceHousekeepingReport { readonly sweptAt: number; readonly trigger: 'recovery' | 'periodic' | 'manual'; readonly grants: DeviceGrantSweepReport; readonly artifacts: DeviceArtifactSweepReport; /** One-line summary a surface can render without reading the itemised lists. */ readonly summary: string; } export interface DeviceHousekeepingOptions { readonly grants: DeviceGrantStore; readonly artifacts: DeviceCaptureArtifactStore; /** Where the disclosure log is written. */ readonly disclosurePath: string; readonly now?: (() => number) | undefined; } /** * Sweeps both device stores and records the disclosure. Construct once at * startup, call `runRecoverySweep()` before serving any capability request, and * `start()` to keep sweeping on a timer. */ export declare class DeviceHousekeeper { private readonly grants; private readonly artifacts; private readonly disclosure; private readonly now; private timer; private lastReport; /** Set while a timer runs; re-read after each sweep to follow a live setting. */ private resolveInterval; private armedIntervalMs; constructor(options: DeviceHousekeepingOptions); /** The most recent report this process produced, or null before the first sweep. */ getLastReport(): DeviceHousekeepingReport | null; /** Disclosure history from disk, newest last. */ listDisclosures(): Promise; /** One full pass over both stores, with the result disclosed to disk. */ sweep(trigger: DeviceHousekeepingReport['trigger']): Promise; /** * The recovery pass. Runs before any capability request is served, so a grant * belonging to a node that is gone, or a capture torn by a crash, is removed * rather than honoured on the first request after a restart. */ runRecoverySweep(): Promise; /** * Keep sweeping on an interval. A long-lived daemon that only swept at boot * would never sweep at all, so this is not optional wiring. * * Pass a resolver instead of a number to follow a live setting: the cadence is * re-read after every sweep and the timer re-armed when it changed, so an * owner who shortens `device.capture.sweepIntervalMinutes` does not have to * restart the daemon to get the faster sweep. A resolver that returns a * nonsensical cadence (zero, negative, not finite) leaves the current one in * place rather than stopping housekeeping altogether. */ start(intervalMs: number | (() => number)): void; /** The cadence the live timer is running at, or null when stopped. */ getArmedIntervalMs(): number | null; private arm; /** Follow a cadence change without waiting for a restart. */ private rearmIfCadenceChanged; stop(): void; } //# sourceMappingURL=device-housekeeping.d.ts.map