import type { AugmentConfig } from "../config.js"; /** * Thrown when a healthy daemon already owns this state dir. The daemon process * itself (not just the connect-or-start client) must refuse to start a second * time: two daemons co-opening the same sqlite index race on writes and produce * intermittent SQLITE_BUSY. Callers that spawn the daemon treat this as a clean * "already up" exit, not a failure. */ export declare class DaemonAlreadyRunningError extends Error { readonly endpoint: string; readonly pid: number; constructor(endpoint: string, pid: number); } /** Handle to the single-instance slot; release() frees it for the next start. */ export interface InstanceLock { release(): Promise; } /** * Claim the sole-daemon slot for `config.stateDir`, or throw * {@link DaemonAlreadyRunningError} if another daemon already holds it. * * Two independent signals guard the slot: * - the recorded daemon's /health endpoint (authoritative — a daemon that * answers /health owning this stateDir is unambiguously already serving), and * - an exclusive `daemon.pid` lockfile that closes the cold-start window before * the winner becomes healthy. A pidfile is reclaimed when its holder is * provably dead, or when it has aged past the grace window (a crash-stranded * orphan, possibly with a since-reused pid); a live, recent holder is honored. * Reclamation is atomic — an orphan is renamed aside, so of two racing starts * at most one reclaims and the loser honors whoever recreates the slot. */ export declare function acquireSingleInstance(config: AugmentConfig): Promise;