/** * wait — event-driven waiting on a Healix worker (push instead of poll). * * Replaces the 1.5 s /healix/status polling loops. The worker's GET /healix/events * long-polls its chronological stream and returns the moment a matching lifecycle event * lands, together with every console line since the caller's cursor and a fresh status. * * Fetchers are injected so the logic is unit-testable without HTTP. A worker that predates * /healix/events (404) falls back to the old status poll, so the MCP keeps working against * an older wdio-healix-service. */ import { type HealixEvent, type LogEntry, type RunSentinel } from './console-chunk.js'; export interface EventsQuery { since: number; waitMs: number; until: 'any' | 'event'; types?: string[]; limit?: number; } export interface EventsPage { entries: LogEntry[]; nextCursor: number; truncated?: boolean; reason?: string; oldestInMemory?: number; consoleLogPath?: string | null; status?: Record; serverTime?: string; } export type EventsFetcher = (q: EventsQuery) => Promise<{ status: number; body: any; }>; export type StatusFetcher = () => Promise>; export interface WaitResult { /** Every entry received since `since`, chronological (empty on the legacy path). */ entries: LogEntry[]; /** The freshest status seen (null when the session died before answering). */ status: Record | null; nextCursor: number; /** The event that ended the wait, if any. */ terminalEvent: HealixEvent | null; /** Connection refused / reset: the worker is gone. */ died: boolean; /** The cap elapsed with the run still in progress. */ timedOut: boolean; /** True when the worker has no /healix/events (status-poll fallback was used). */ legacy: boolean; /** Why the wait ended, for logging. */ reason: 'event' | 'status' | 'human' | 'paused' | 'timeout' | 'died' | 'legacy'; } export interface WaitOptions { since: number; capMs: number; sentinel: RunSentinel; fetchEvents: EventsFetcher; fetchStatus: StatusFetcher; sleep?: (ms: number) => Promise; /** Per-request long-poll window (the worker clamps at 25 s). */ maxWaitMs?: number; now?: () => number; } /** * Wait for the run identified by `sentinel` to reach a terminal state: its end event, a * pause for the agent, a BLOCKING terminal prompt (waiting on the human), an abort, the * session stopping — or the cap. */ export declare function waitForRun(opts: WaitOptions): Promise; /** * Wait for the NEXT lifecycle event (any type, or one of `types`) — the healix_wait tool. * Returns as soon as at least one event arrived, or at the cap. */ export declare function waitForNextEvent(opts: { since: number; capMs: number; types?: string[]; fetchEvents: EventsFetcher; maxWaitMs?: number; now?: () => number; }): Promise<{ entries: LogEntry[]; events: HealixEvent[]; status: Record | null; nextCursor: number; timedOut: boolean; died: boolean; legacy: boolean; }>;