import { type MonitorTickAdapters, type PhysicalWakeRequest } from "../kernel/monitor.js"; import { type PaneHealthAdapter } from "../kernel/pane-health.js"; import type { Clock, KernelPaths } from "../kernel/types.js"; import type { GithubPollAdapter } from "../kernel/github-sync.js"; import type { ProcessRunner } from "../providers/process.js"; import type { ConductorRecoveryBinding } from "../kernel/types.js"; export declare const CODEX_QUOTA_RETRY_MS: number; export interface V2ObserverBinding { readonly paths: KernelPaths; readonly recoveryBinding: ConductorRecoveryBinding; readonly owner: string; readonly processInstanceId: string; } export interface CodexQuotaObserver { readonly tick: () => { readonly limited: number; readonly available: number; readonly retries: number; }; } export interface V2ObserverAdapters extends MonitorTickAdapters { readonly codexQuota?: CodexQuotaObserver; } /** * Fixed observer loop. It owns no routing decisions: kernel timers determine * when to project pane/GitHub observations, and durable wake claims determine * when the conductor receives one opaque re-prompt. */ export declare function runV2Observer(input: V2ObserverBinding & { readonly clock: Clock; readonly adapters: V2ObserverAdapters; readonly shouldStop?: () => boolean; readonly pause?: (milliseconds: number) => Promise; }): Promise; export declare function createProductionObserverAdapters(input: { readonly binding: V2ObserverBinding; readonly clock: Clock; readonly env?: NodeJS.ProcessEnv; readonly runner?: ProcessRunner; }): V2ObserverAdapters; /** * Codex exposes lifecycle hooks but no quota hook. This observer reads only a * bounded tail from exact launch-bound Codex panes, persists no pane text, and * emits the same closed typed quota events as native hooks. */ export declare function createTmuxCodexQuotaObserver(input: { readonly paths: KernelPaths; readonly clock: Clock; readonly env?: NodeJS.ProcessEnv; readonly runner?: ProcessRunner; }): CodexQuotaObserver; export declare function detectCodexQuotaBanner(body: string): boolean; /** * Physical delivery is deliberately opaque: no event body or routing decision * enters the provider prompt. A failed tmux call throws before wake_sent is * journaled; a successful call remains pending until advance_campaign consumes it. */ export declare function createTmuxConductorWake(input: { readonly recoveryBinding: ConductorRecoveryBinding; readonly env?: NodeJS.ProcessEnv; readonly runner?: ProcessRunner; }): (request: PhysicalWakeRequest) => void; export declare function createTmuxPaneHealthAdapter(input: { readonly paths: KernelPaths; readonly env?: NodeJS.ProcessEnv; readonly runner?: ProcessRunner; }): PaneHealthAdapter; export declare function createGhGithubPollAdapter(input: { readonly paths: KernelPaths; readonly env?: NodeJS.ProcessEnv; readonly runner?: ProcessRunner; }): GithubPollAdapter; export declare function newObserverProcessInstanceId(): string; /** * Recovery-only watchdog. It does not read tickets or campaign state; every * 15 minutes it verifies the exact observer pane ownership and respawns only * that fixed observer command when the pane is dead. */ export declare function runV2ObserverWatchdog(input: { readonly workspaceRoot: string; readonly observerPane: string; readonly observerOwner: string; readonly observerEntrypoint: string; readonly bindingPath: string; readonly env?: NodeJS.ProcessEnv; readonly runner?: ProcessRunner; readonly repairConductor?: () => boolean; readonly shouldStop?: () => boolean; readonly pause?: (milliseconds: number) => Promise; }): Promise; export declare function repairObserverIfDead(input: { readonly workspaceRoot: string; readonly observerPane: string; readonly observerOwner: string; readonly observerEntrypoint: string; readonly bindingPath: string; readonly env: NodeJS.ProcessEnv; readonly runner: ProcessRunner; readonly force?: boolean; }): boolean;