import { spawn } from "node:child_process"; export declare function isSafeLabHandle(value: string): boolean; export interface LaunchRunOptions { cwd: string; /** The manifest handle (filename stem), as `humanish lab run` takes it. */ lab: string; /** Exact selected manifest, avoiding a same-name committed lab shadowing a local copy. */ manifestPath?: string; mode: "dry-run" | "live"; /** Injected in tests; defaults to the real spawn. */ spawn?: typeof spawn; /** Injected in tests; defaults to the CLI beside this module. */ cliPath?: string; env?: NodeJS.ProcessEnv; /** Injected clock so a test can pin the log filename. */ now?: () => Date; } export interface LaunchedRun { /** The spawned CLI's pid. The run's `status.json` stamps the same value. */ pid: number; /** * When the launch happened. A pid ALONE cannot identify a run: pids are recycled by the OS and a * finished run keeps its pid in `status.json` forever, so a week-old record can carry the pid the * kernel just handed this child. Anything matching on pid must also require the record to be * newer than this. */ launchedAt: string; /** Absolute path to the launch log; the only diagnosis when a run dies before writing evidence. */ logPath: string; /** Exactly what was executed, so a failure can be reproduced by hand. */ command: readonly string[]; } export type LaunchRunResult = { ok: true; run: LaunchedRun; } | { ok: false; error: { code: LaunchErrorCode; message: string; }; }; export type LaunchErrorCode = "HUMANISH_LAUNCH_INVALID_LAB" | "HUMANISH_LAUNCH_FAILED"; /** * Start a run and return as soon as it is running. Never throws: a launch that cannot happen is a * result the surface can render, not an exception that would tear down the screen. */ export declare function launchRun(options: LaunchRunOptions): Promise; /** Read the tail of a launch log — the only account of a run that died before writing evidence. */ export declare function readLaunchLogTail(logPath: string, maxBytes?: number): Promise;