/** * Child-process adapter for the launcher update pipeline. The launcher * (bin/deepseek.mjs) stays the single owner of update semantics — plan, * guards, and the aligned install sequence — so the TUI only spawns * `update --json` (read-only probe) and `update --apply` (streamed run) * and never re-implements version-line decisions. */ import { type ChildProcess } from 'node:child_process'; /** Spawn double acceptable to the adapter (tests inject an EventEmitter). */ export type SpawnLike = (command: string, args: readonly string[], options: { readonly stdio: readonly string[]; readonly windowsHide: boolean; }) => ChildProcess; /** Structured `update --json` payload; mirrors the launcher buildUpdateStatus. */ export interface LauncherUpdateStatus { readonly code: { readonly running: string; readonly latest: string | null; }; readonly host: { readonly installed: string | null; readonly targetLine: string | null; }; readonly profile: { readonly spec: string | null; readonly mounted: string | null; readonly localCheckout: boolean; }; readonly plan: { readonly dshSpec: string; readonly codeSpec: string; readonly pluginSpecs: readonly string[]; }; readonly blockers: { readonly registry: string | null; readonly downgrade: boolean; readonly localCheckout: readonly string[] | null; }; readonly upToDate: boolean; /** True when this install is newer than npm latest (apply would downgrade). */ readonly aheadOfRegistry?: boolean; } /** Exact specs the TUI confirmed; apply must install these, not re-query latest. */ export interface LauncherUpdatePlan { readonly dshSpec: string; readonly codeSpec: string; readonly pluginSpecs: readonly string[]; } /** The launcher entrypoint that ships beside this bundle (lib/../bin). */ export declare function launcherUpdateCommand(args: readonly string[], moduleUrl?: string): { readonly command: string; readonly args: string[]; }; /** * Split a streamed chunk sequence into complete display lines: CR is * stripped, a chunk boundary may split a line, and the trailing partial * stays pending until its newline arrives (npm writes whole lines, but a * pipe may cut anywhere). Blank lines carry no progress information and * are dropped so the panel budget is not spent on gaps. */ export declare function createLineSplitter(onLine: (line: string) => void): (chunk: string) => void; /** * Probe the aligned update status. Read-only: `update --json` never * installs anything. The probe is bounded (npm view may hang on a broken * network) and resolves with the parsed status. */ export declare function probeLauncherUpdate(spawnProcess?: SpawnLike): Promise; /** * Run the aligned update (`update --apply`) as a child process and stream * its sanitized progress lines to the caller. Resolves with the child * exit code (0 success); rejects only when the process could not start. * No timeout: an npm install may legitimately take minutes. */ export declare function applyPlanArgs(plan: LauncherUpdatePlan): string[]; export declare function applyLauncherUpdate(onLine: (line: string) => void, spawnProcess?: SpawnLike, plan?: LauncherUpdatePlan): Promise;