import { type CancelReasonCode } from "@claudexor/schema"; import { type CommandAuthority } from "./command-authority.js"; import { type DelegationAdmissionAuthority } from "./delegation-admission.js"; import { JOB_STATES, jobStateFromResult, type JobRecord } from "./job-record.js"; import { type DaemonServingModeSnapshot } from "./serving-admission.js"; import { socketAlive } from "./socket-probe.js"; import { type RuntimeReplacementAuthority } from "./daemon-shutdown-rpc.js"; import { type TurnEnqueueProblem as TurnEnqueueProblemValue } from "@claudexor/schema"; export { JOB_STATES, jobStateFromResult, socketAlive, type JobRecord }; export interface RunContext { jobId: string; signal: AbortSignal; onRunStart: (info: { runId: string; taskId: string; runDir: string; }) => void; } export type RunnerFn = (params: unknown, ctx: RunContext) => Promise; export interface DaemonOptions extends RuntimeReplacementAuthority { socketPath: string; token: string; runner: RunnerFn; maxConcurrent?: number; commands: CommandAuthority; delegationAuthority?: DelegationAdmissionAuthority; maxHistory?: number; idempotencyRetentionMs?: number; now?: () => Date; /** Called when a job reaches a terminal state (any path) with its runId — * used to drop pending interactions so a dead run never advertises * waiting_on_user. */ onRunTerminal?: (runId: string, threadId?: string) => void; /** Best-effort observer after a durable terminal; it must not throw. */ onCommandTerminal?: (record: JobRecord) => void; /** Called when a job that carried a pre-created thread turn (params.turnId) * settles failure-shaped WITHOUT ever binding a run — i.e. the refusal * happened before the run materialized (trust gate, preflight validation). * The observer persists one sanitized typed problem on the turn so it is * never a silent orphan bubble and no recovery field is dropped. */ onTurnEnqueueFailed?: (turnId: string, problem: TurnEnqueueProblemValue) => void; onShutdownRequested?: () => Promise; onRuntimeReplacementRequested?: () => Promise; /** Issue #165 D5 admission snapshot; absent embedders always serve normal. */ servingMode?: DaemonServingModeSnapshot; /** Test-only barriers around command authority acquisition. */ startupBarrier?: (barrier: "before_registry_load" | "after_registry_load") => void | Promise; } /** Unix-socket worker pool; scheduling stays in the injected Orchestrator. */ export declare class DaemonServer { private readonly opts; private server?; private readonly followers; private readonly queue; private readonly cancelled; private readonly controllers; private readonly activeTasks; private readonly taskFailures; private active; private readonly startedAt; private stopping; private startPromise?; private stopPromise?; private resolveShutdown; private readonly shutdownPromise; constructor(opts: DaemonOptions); start(): Promise; private startOnce; stop(): Promise; private stopOnce; /** Resolves when the daemon is shut down via RPC. */ waitForShutdown(): Promise; private onConnection; private send; private handle; private dispatch; private get maxConcurrent(); /** Daemon-owned cancellation primitive used by RPC and the Delegate drain * barrier. It is safe to repeat and preserves queued-admission cleanup. */ cancelJob(jid: string, reasonCode?: CancelReasonCode): { id: string; cancelled: true; }; private stoppingError; /** Age/cap and params-byte command retention: at normal admission and after every terminal. */ pruneHistory(): void; private acceptCommand; private allRecords; private getRecord; private updateRecord; private threadIdOf; /** * Schedule queued jobs up to the concurrency limit (non-blocking), plus the * single Delegate-child overflow lane documented below. * * One active run per thread: a thread is a linear conversation and an in-place * turn mutates the live tree, so two concurrent turns on the same thread would * race the same files. We pick the first queued job whose thread is idle rather * than always taking the head; thread-less jobs (CLI/MCP) keep running in * parallel as before. drain() re-runs on every completion, so a thread's next * turn starts as soon as its previous one settles. */ private drain; private runJob; } //# sourceMappingURL=server.d.ts.map