import type { SyncProgressEvent } from "./cli/sync.js"; /** Absolute path of the shared progress snapshot. Exported for the watcher + tests. */ export declare function syncProgressPath(): string; export interface SyncProgressSnapshot { schema: 1; /** PID of the writing sync — lets a watcher detect a dead/stale holder. */ pid: number; /** Company slug, null for the personal vault, or "multiple" for fanout aggregation. */ company: string | null; /** Which leg is running. */ phase: "pull" | "push"; filesTotal: number; filesDone: number; conflicts: number; /** Path of the file currently transferring, or null before the first one. */ currentFile: string | null; startedAt: string; updatedAt: string; status: "syncing"; } export interface SyncProgressRecorderOptions { company?: string | null; phase: "pull" | "push"; } export interface FanoutProgressRecorder { /** Mark a target active before its potentially slow planning phase begins. */ startTarget(target: string, company: string | null, phase: "pull" | "push"): void; /** Feed one target's engine event into the aggregate snapshot. */ record(target: string, phase: "pull" | "push", event: SyncProgressEvent): void; /** Stop heartbeating a completed target; completed work stays in the totals. */ finishTarget(target: string): void; /** Stop the heartbeat if fanout initialization itself aborts. */ dispose(): void; } /** * Aggregate every concurrent company leg into the one legacy snapshot format. * Totals are cumulative for the run, so they cannot move backward when a leg * finishes or another begins its next phase. A lightweight heartbeat keeps the * snapshot fresh while a target is in slow, event-silent planning. */ export declare function createFanoutProgressRecorder(): FanoutProgressRecorder; /** * Build an event sink that accumulates a sync's progress and atomic-writes the * shared snapshot on each meaningful event. Wrap the engine's `onEvent` with * it: `const emit = (e) => { baseEmit(e); record(e); }`. */ export declare function createSyncProgressRecorder(opts: SyncProgressRecorderOptions): (event: SyncProgressEvent) => void; /** * Read the current snapshot, or null if absent/unreadable. Consumers should * additionally treat a snapshot whose `updatedAt` is older than a few seconds * (or whose `pid` is dead) as idle. */ export declare function readSyncProgress(): SyncProgressSnapshot | null; /** * End-of-pass record for a host app that does not read the runner's stdout * (the desktop app when `hq daemon` runs sync). A `--watch` runner writes it * once per pass, when `all-complete` is emitted, so the host can run its * per-pass work (journal, conflict and plan-limit notices, git mirror, recent * changes) from the file. It is separate from the live snapshot above so the * next pass cannot overwrite a finished pass before the host reads it. */ export declare function syncLastPassPath(): string; /** Per-file progress events kept per pass; the rest are counted, not stored. */ export declare const PASS_SUMMARY_MAX_PROGRESS = 200; /** One runner protocol event, as printed on stdout. */ export type PassEvent = { type: string; } & Record; export interface SyncLastPass { schema: 1; pid: number; /** Unique per pass, so a host handles each pass once. */ passId: string; completedAt: string; /** Progress events past PASS_SUMMARY_MAX_PROGRESS that were left out. */ droppedProgress: number; /** The pass's events a host acts on, in the order they were emitted; the last is `all-complete`. */ events: PassEvent[]; } export interface PassSummaryRecorder { /** Feed every event the runner emits; writes the record on `all-complete`. */ record(event: PassEvent): void; } export declare function createPassSummaryRecorder(): PassSummaryRecorder; /** The last finished `--watch` pass, or null if none was recorded or it is unreadable. */ export declare function readSyncLastPass(): SyncLastPass | null; //# sourceMappingURL=sync-progress.d.ts.map