export type ShellKind = 'bash' | 'pwsh' | 'powershell' | 'cmd' | 'unknown'; export interface ShellProbeReport { /** Whether a usable bash was located. `false` ⇒ caller MUST NOT silently fall back to PowerShell. */ readonly available: boolean; /** The recommended shell command name. `'bash'` on success, `'pwsh'` / `'powershell'` only as an explicit non-silent fallback (with available=false). */ readonly shell: ShellKind; /** Absolute path to the resolved binary, when found. `null` otherwise. */ readonly path: string | null; /** * Why the probe returned what it returned. Always populated — * `null` reasons are forbidden. `'unavailable'` carries a single- * line explanation the orchestrator can render to the user. */ readonly reason: string; /** Wall-clock duration of the probe (ms). Useful for the dispatch envelope's `notes[]`. */ readonly elapsedMs: number; /** Probe platform — `win32` triggers the Git-Bash preference. */ readonly platform: NodeJS.Platform; } export interface ShellProbeOptions { /** * Override `process.platform`. Tests use this to simulate Windows * hosts on Linux CI (and vice versa) without mutating process. */ readonly platform?: NodeJS.Platform; /** * Override the runner that performs the `which bash` / `where * bash` probe. The default delegates to `child_process.spawn`; the * test seam injects a fake. */ readonly runner?: ShellProbeRunner; /** * Override the process env. Default: process.env. */ readonly env?: NodeJS.ProcessEnv; /** * Probe timeout (ms). Default: 3000. A sub-agent that hangs the * probe would itself be a stall; bounded so the call site fails * fast and the orchestrator can surface `available: false`. */ readonly timeoutMs?: number; /** * Wall clock for tests. */ readonly now?: () => number; /** * Test seam: override the literal-path probe. The default * delegates to `node:fs#existsSync`; the test seam injects a * fake so the Windows-no-bash scenario can be exercised on a * host that has Git Bash installed (and vice versa). */ readonly probeFile?: (absPath: string) => Promise | boolean; } export interface ShellProbeRunner { /** * Run a command. Returns the captured stdout on success and * throws (or returns `null`) on failure. The probe treats * `null`-returns the same as thrown errors. */ run(command: string, args: readonly string[], opts: { timeoutMs: number; }): Promise<{ stdout: string; } | null>; } /** * Probe the host shell. The returned report is the single source of * truth: callers MUST surface `reason` when `available: false` rather * than silently falling back to PowerShell. */ export declare function probeShell(options?: ShellProbeOptions): Promise;