/** * D7a Layer 2, pid/port discovery for the detached daemon. * * When a surface spawns the daemon as a detached, standalone process, it records * the pid/host/port to a small JSON file under the daemon home so a later surface * (or a `GET /api/service/status` call against the daemon HTTP API) can discover and adopt it without a fresh * spawn. This is deliberately a plain record, not a lock, since the daemon's own * identity probe is the source of truth for "is it actually alive and mine". */ /** File name of the detached-daemon runtime record within the daemon home dir. */ export declare const DETACHED_DAEMON_RUNTIME_FILE = "detached-daemon.json"; /** * File name of the receipt written when a stale record is reaped. Reaping is * disclosed rather than silent: a record that vanished with no trace is * indistinguishable from one that was never written. */ export declare const DETACHED_DAEMON_REAPED_FILE = "detached-daemon-reaped.json"; export interface DetachedDaemonRuntimeRecord { readonly pid: number | undefined; readonly host: string; readonly port: number; readonly command: string; readonly startedAt: string; readonly logFilePath?: string | undefined; } /** Absolute path of the runtime record file for a given daemon runtime dir. */ export declare function detachedDaemonRuntimePath(runtimeDir: string): string; /** Absolute path of the reaping receipt for a given daemon runtime dir. */ export declare function detachedDaemonReapedPath(runtimeDir: string): string; /** * The part of a runtime record that endpoint discovery actually uses: where to * dial, and whose liveness to check. Kept narrow deliberately, a caller * supplying a hint should not have to invent a `command` and a `startedAt` it * has no opinion about, and the full record satisfies this by construction. */ export interface DetachedDaemonRuntimeHint { readonly host: string; readonly port: number; readonly pid?: number | undefined; } /** Is this pid a process that still exists? Injectable so a test needs no real pid. */ export type ProcessAliveCheck = (pid: number) => boolean; /** * Default liveness check. `kill(pid, 0)` sends no signal, it only asks the * kernel whether the pid exists and is signallable. EPERM means it exists and * belongs to another user, which still counts as alive. */ export declare const defaultProcessAliveCheck: ProcessAliveCheck; /** * Whether the process this record names still exists. * * A record with NO pid cannot be checked this way and is not declared dead on * that basis, the port probe is then the only evidence, and calling it dead * here would strand a daemon that simply recorded no pid. */ export declare function detachedDaemonProcessAlive(record: DetachedDaemonRuntimeHint, isProcessAlive?: ProcessAliveCheck): boolean; /** What a reaping receipt records, so a removed record leaves evidence. */ export interface DetachedDaemonReapReceipt { readonly reapedAt: string; /** Plain-language reason: which check the record failed. */ readonly reason: string; readonly record: DetachedDaemonRuntimeHint; } /** * Remove a runtime record that has been proven not to describe a live daemon, * and leave a receipt saying so. * * Best-effort and idempotent: two processes can reap the same record * concurrently and neither throws. Removing the record is the point, while it * sits there, every endpoint discovery keeps preferring an address nothing * answers at, which is exactly the failure this reaping exists to end. */ export declare function reapDetachedDaemonRuntime(runtimeDir: string, record: DetachedDaemonRuntimeHint, reason: string): DetachedDaemonReapReceipt | null; /** Read the last reaping receipt, or null when nothing has been reaped. */ export declare function readDetachedDaemonReapReceipt(runtimeDir: string): DetachedDaemonReapReceipt | null; /** Write (or overwrite) the detached-daemon runtime record. Best-effort; never throws. */ export declare function recordDetachedDaemonRuntime(runtimeDir: string, record: DetachedDaemonRuntimeRecord): string | null; /** Read the detached-daemon runtime record, or null if missing/unparseable. */ export declare function readDetachedDaemonRuntime(runtimeDir: string): DetachedDaemonRuntimeRecord | null; //# sourceMappingURL=detached-daemon-runtime.d.ts.map