import { type ChildProcess } from 'node:child_process'; import { type DevFlowPathOptions } from './paths.js'; export type RuntimeStatus = 'acquiring' | 'launching' | 'ready' | 'degraded' | 'stale' | 'stopping' | 'stopped' | 'failed'; export type RuntimeFailureCode = 'RUNTIME_ALREADY_READY' | 'RUNTIME_STARTING' | 'RUNTIME_PORT_IN_USE' | 'RUNTIME_START_TIMEOUT' | 'RUNTIME_OWNER_MISMATCH' | 'RUNTIME_STALE_RECOVERED' | 'RUNTIME_PROCESS_EXITED' | 'DASHBOARD_BUNDLE_MISSING' | 'DASHBOARD_NOT_READY' | 'DATABASE_NOT_READY' | 'PROJECT_SCOPE_REQUIRED'; export interface RuntimeFailure { code: RuntimeFailureCode; stage: 'lease' | 'port' | 'spawn' | 'health' | 'ready' | 'ownership' | 'stop'; message: string; at: number; } export interface RuntimeStateV2 { schemaVersion: 'devflow.runtime.v2'; url: string; port: number; pid: number; processGroupId: number; ownerToken: string; generation: number; version: string; status: RuntimeStatus; dashboardAvailable: boolean; dashboardBuildHash?: string; startedAt: number; lastReadyAt?: number; updatedAt: number; failure?: RuntimeFailure; } export interface EnsureRuntimeInput { reason: 'cli-start' | 'cli-dashboard' | 'hook' | 'mcp'; projectRoot?: string; port?: number; explicitPort?: boolean; noStart?: boolean; server: { command: string; args: string[]; cwd: string; env?: NodeJS.ProcessEnv; }; } export interface EnsureRuntimeResult { state: RuntimeStateV2; reused: boolean; projectId?: string; } export interface ReadyProbe { health: boolean; ready: boolean; dashboard: boolean; ownerVerified?: boolean; version?: string; buildHash?: string; reason?: RuntimeFailureCode; } export interface RuntimeManagerOptions extends DevFlowPathOptions { startTimeoutMs?: number; probe?: (state: RuntimeStateV2) => Promise; launcher?: (input: EnsureRuntimeInput['server'] & { token: string; port: number; }) => Promise<{ pid: number; processGroupId?: number; child?: ChildProcess; }>; now?: () => number; ports?: { isAvailable: (port: number) => Promise; allocateEphemeral: () => Promise; }; ownership?: { inspect: (state: RuntimeStateV2) => { alive: boolean; commandMatches: boolean; tokenMatches: boolean; groupMatches: boolean; isOwned?: boolean; }; terminateGroup: (state: RuntimeStateV2) => Promise; }; } export declare function getRuntimeDir(options?: DevFlowPathOptions): string; export declare function getRuntimeStatePath(options?: DevFlowPathOptions): string; export declare function getRuntimeDatabasePath(options?: DevFlowPathOptions): string; export declare function getRuntimeLogPath(options?: DevFlowPathOptions): string; export declare function readRuntimeState(options?: DevFlowPathOptions): RuntimeStateV2 | null; export declare function writeRuntimeState(state: RuntimeStateV2, options?: DevFlowPathOptions): void; export declare function updateOwnedRuntimeState(generation: number, ownerToken: string, patch: Partial, options?: DevFlowPathOptions): boolean; export declare function assertRuntimeState(value: RuntimeStateV2): void; export declare class RuntimeManager { private readonly options; constructor(options?: RuntimeManagerOptions); readState(): RuntimeStateV2 | null; writeState(state: RuntimeStateV2): void; updateOwnedState(generation: number, ownerToken: string, patch: Partial): boolean; ensureRunning(input: EnsureRuntimeInput): Promise; openDashboard(input: EnsureRuntimeInput): Promise; status(): Promise; stop(): Promise<{ stopped: boolean; state: RuntimeStateV2 | null; }>; private reserve; private newAcquiringState; private openLeaseDatabase; private upsertLease; private writeLeaseAndState; private waitForReservation; private verifiedReady; private waitForReady; private selectPort; private launch; private owns; private terminateOwned; private processAlive; private failAndClean; private now; private probe; } export declare function createRuntimeManager(options?: RuntimeManagerOptions): RuntimeManager; //# sourceMappingURL=runtime-manager.d.ts.map