interface ConsoleLockPayload { readonly pid: number; readonly host: string; readonly port: number; readonly endpoint: string; readonly startedAt: number; readonly token: string; readonly version: string; readonly owner?: ConsoleOwnerMetadata; } interface ConsoleOwnerMetadata { readonly kind: "cli" | "desktop"; readonly id: string; readonly protocolVersion: number; } interface ConsoleHealth { readonly ok: true; readonly pid: number; readonly host: string; readonly port: number; readonly portMode: "dynamic" | "static"; readonly requestedPort: number | null; readonly effectivePort: number; readonly portHonored: boolean; readonly endpoint: string; readonly startedAt: number; readonly version: string; readonly channel?: "stable" | "local"; readonly owner?: ConsoleOwnerMetadata; readonly workspaceCount: number; } /** * 브라우저 실행기가 실제로 떴는지에 대한 답. 실패를 삼키면 CLI가 "열었다"고 말한 뒤 * 아무것도 뜨지 않는 화면만 남으므로, 이 결과는 호출자가 사용자에게 전할 사실이다. */ interface BrowserOpenResult { readonly opened: boolean; readonly reason?: string; } interface OpenBrowserDeps { readonly platform?: NodeJS.Platform; readonly spawnBrowser?: (command: string, args: readonly string[], options: { readonly detached: true; readonly stdio: "ignore"; readonly windowsHide: true; }) => void | Promise; } interface ConsoleProbeResult { readonly healthy: boolean; readonly lock: ConsoleLockPayload | null; readonly health?: ConsoleHealth; readonly error?: string; } interface ConsoleHealthDeps { readonly fetch?: typeof fetch; readonly now?: () => number; } interface ConsoleProbeOptions { /** primary와 legacy probe가 함께 나눠 쓰는 전체 시간 예산. */ readonly timeoutMs?: number; /** 호출자의 수명주기가 끝나면 현재 endpoint 요청도 함께 중단한다. */ readonly signal?: AbortSignal; } declare function createConsoleHealthClient(deps?: ConsoleHealthDeps): { probe: (lock: ConsoleLockPayload | null, options?: ConsoleProbeOptions) => Promise; }; type ConsoleCliMode = "start" | "stop" | "restart" | "status" | "help"; interface ConsoleDaemonProcess { readonly pid?: number; once(event: "error", listener: (error: Error) => void): this; once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this; kill(signal?: NodeJS.Signals | number): boolean; unref(): void; } type ConsoleDaemonSpawner = (execPath: string, args: readonly string[], options: { readonly detached: true; readonly env: NodeJS.ProcessEnv; readonly stdio: "ignore"; readonly windowsHide: true; }) => ConsoleDaemonProcess; interface ConsoleDaemonLifecycleDeps { readonly env?: NodeJS.ProcessEnv; readonly execPath?: string; readonly serverModulePath?: string; /** * 게시된 ./cli 소비자가 쓰던 legacy seam. 반환값이 없으므로 소유 프로세스 정리는 보장하지 못하지만, * 기존 injector가 깨지지 않도록 유지한다. 새 테스트와 런타임 구현은 spawnDaemon을 사용한다. */ readonly spawnDetached?: (execPath: string, args: readonly string[], options: { readonly detached: true; readonly env: NodeJS.ProcessEnv; readonly stdio: "ignore"; readonly windowsHide: true; }) => void; readonly spawnDaemon?: ConsoleDaemonSpawner; readonly sleep?: (ms: number) => Promise; readonly now?: () => number; readonly startupTimeoutMs?: number; readonly pollIntervalMs?: number; readonly cleanupGraceMs?: number; readonly health?: ReturnType; } interface OpenFleetConsoleDeps { readonly lifecycle?: Pick, "ensureDaemon" | "probe">; readonly openBrowser?: (url: string, deps?: OpenBrowserDeps) => void | Promise; } interface OpenFleetConsoleResult { readonly url: string; /** 브라우저 실행기가 실제로 떴는지. 거짓이면 호출자가 주소를 사용자에게 직접 건네야 한다. */ readonly browserOpened: boolean; readonly browserError?: string; } interface ConsoleStatusDeps { readonly lifecycle?: Pick, "probe">; } interface ConsoleStopDeps { readonly lifecycle?: Pick, "stop">; } type ConsoleHookCommand = { readonly command: "capture-session"; readonly provider: "claude"; } | { readonly command: "turn-start"; } | { readonly command: "turn-end"; } | { readonly command: "background-report"; } | { readonly command: "background-spawn"; } | { readonly command: "background-stop"; } | { readonly command: "attention"; } | { readonly command: "auto-name"; }; interface ConsoleRestartDeps { readonly lifecycle?: Pick, "stop" | "ensureDaemon" | "probe">; readonly openBrowser?: (url: string, deps?: OpenBrowserDeps) => void; } interface BuildConsoleHelpTextOptions { readonly env?: NodeJS.ProcessEnv; readonly isTTY?: boolean; readonly release?: string; } declare function parseConsoleCliMode(argv: readonly string[]): ConsoleCliMode; declare function parseConsoleHookCommand(argv: readonly string[]): ConsoleHookCommand; declare function buildConsoleHelpText(options?: BuildConsoleHelpTextOptions): string; declare function createConsoleDaemonLifecycle(deps?: ConsoleDaemonLifecycleDeps): { ensureDaemon: () => Promise; probe: (timeoutMs?: number, signal?: AbortSignal) => Promise<{ buildStale: boolean; healthy: boolean; lock: ConsoleLockPayload | null; health?: ConsoleHealth; error?: string; }>; runServer: () => Promise; stop: () => Promise; }; declare function openFleetConsole(deps?: OpenFleetConsoleDeps): Promise; declare function runConsoleStatus(deps?: ConsoleStatusDeps): Promise; declare function runConsoleStop(deps?: ConsoleStopDeps): Promise; declare function assertCliCanControlDaemon(payload: ConsoleLockPayload): void; declare function isLockProcessAlive(pid: number): boolean; declare function runConsoleRestart(deps?: ConsoleRestartDeps): Promise; declare function main(): Promise; declare function resolveDefaultServerModulePath(moduleUrl?: string): string; declare function isCliDirectRun(argv1: string | undefined, moduleUrl?: string): boolean; export { type BuildConsoleHelpTextOptions, type ConsoleCliMode, type ConsoleDaemonLifecycleDeps, type ConsoleDaemonProcess, type ConsoleDaemonSpawner, type ConsoleHookCommand, type ConsoleRestartDeps, type ConsoleStatusDeps, type ConsoleStopDeps, type OpenFleetConsoleDeps, type OpenFleetConsoleResult, assertCliCanControlDaemon, buildConsoleHelpText, createConsoleDaemonLifecycle, isCliDirectRun, isLockProcessAlive, main, openFleetConsole, parseConsoleCliMode, parseConsoleHookCommand, resolveDefaultServerModulePath, runConsoleRestart, runConsoleStatus, runConsoleStop };