/**
 * Daemon lifecycle management — spawn, verify, stop, coordinate OwlCoda background daemons.
 * Extracted from cli-core.ts for modularity.
 */
import type { OwlCodaConfig } from './config.js';
import { type HealthzResponse } from './healthz-client.js';
export interface RuntimeMeta {
    pid: number;
    runtimeToken: string;
    host: string;
    port: number;
    routerUrl: string;
    version: string;
    startedAt: string;
}
export interface StaleDaemonVersionInfo {
    daemonVersion: string;
    cliVersion: string;
    activeClientCount: number;
}
export interface EnsureProxyRunningResult {
    pid: number;
    reused: boolean;
    staleDaemon?: StaleDaemonVersionInfo;
}
export type DaemonVersionPolicyAction = 'reuse_current' | 'restart_idle_stale' | 'reuse_active_stale';
export interface DaemonVersionPolicyDecision {
    action: DaemonVersionPolicyAction;
    stale: boolean;
    daemonVersion?: string;
    cliVersion: string;
    activeClientCount: number;
}
export declare function ensureOwlcodaDir(): void;
export declare function writeRuntimeMeta(meta: RuntimeMeta): void;
export declare function readRuntimeMeta(): RuntimeMeta | null;
export declare function removeRuntimeMeta(): void;
export declare function isPidAlive(pid: number): boolean;
export declare function readPid(): number | null;
export declare function writePid(pid: number): void;
export declare function removePid(): void;
export declare function getMetaBaseUrl(meta: Pick<RuntimeMeta, 'host' | 'port'>): string;
export declare function verifyManagedDaemon(meta: RuntimeMeta): Promise<HealthzResponse | null>;
export declare function decideDaemonVersionPolicy(daemonVersion: string | undefined, activeClientCount: number, cliVersion?: string): DaemonVersionPolicyDecision;
export declare function safeSendSignal(pid: number, signal: NodeJS.Signals): boolean;
export declare function stopAndWait(pid: number, baseUrl: string): Promise<void>;
export declare function buildDaemonArgs(configPath?: string, port?: number, routerUrl?: string): string[];
export declare function spawnDaemon(config: OwlCodaConfig, configPath?: string, port?: number, routerUrl?: string): {
    pid: number;
    runtimeToken: string;
    exitPromise: Promise<{
        code: number | null;
        signal: NodeJS.Signals | null;
    }>;
};
export declare function getBaseUrl(config: {
    host: string;
    port: number;
}): string;
/**
 * Unified daemon coordination — used by both start and launch.
 * 1. Check existing daemon via PID + healthz identity
 * 2. If matching config + matching version → reuse
 * 3. If matching config but stale version → restart only when no live REPL clients are attached
 * 4. If config mismatch → safe stop + restart
 * 5. If nothing running → start fresh
 * 6. Wait for healthz ready before returning
 */
export declare function ensureProxyRunning(config: OwlCodaConfig, configPath?: string, port?: number, routerUrl?: string, options?: {
    quiet?: boolean;
}): Promise<EnsureProxyRunningResult>;
/**
 * 2026-05-28: version-drift hard-block.
 *
 * Previously this was a warn-and-continue path: the CLI would emit the
 * stale-daemon warning and proceed to reuse the mismatched daemon. In
 * practice that produced subtle inconsistencies — the CLI runs the
 * latest agent / classifier / wrapper code, but HTTP error
 * classification (e.g. detailLooksLikeRateLimit from a66383e) lives in
 * the daemon process, so a stale daemon silently disabled retry logic
 * even though the CLI thought it was active. Dogfood across the
 * 0.14.36 → 0.14.39 release window made this drift visible only in
 * post-mortem audit-log inspection.
 *
 * New behaviour: refuse to proceed. The user must either close the
 * active REPL clients (daemon auto-restarts on next start) or
 * `owlcoda stop --force && owlcoda` to align. An escape hatch
 * `OWLCODA_ALLOW_VERSION_DRIFT=1` is provided for emergency cases
 * (e.g. interactive long-running session a user explicitly wants to
 * keep going on a frozen daemon).
 */
export declare function applyActiveStaleDaemonPolicy(pid: number, baseUrl: string, decision: DaemonVersionPolicyDecision): void;
