import { type ChildProcess, type ChildProcessByStdio, type SpawnOptions, type SpawnOptionsWithStdioTuple, type SpawnSyncOptionsWithStringEncoding, type SpawnSyncReturns, type StdioNull, type StdioPipe } from "node:child_process";
import type { Readable } from "node:stream";
type WaitForChildProcessOptions = {
    platform?: NodeJS.Platform;
    isWindowsProcessAlive?: (pid: number) => boolean;
    windowsExitPollIntervalMs?: number;
    windowsExitCodeGraceMs?: number;
};
export declare function shouldUseWindowsShell(command: string): boolean;
export declare function spawnProcess(command: string, args: string[], options: SpawnOptionsWithStdioTuple<StdioNull, StdioPipe, StdioPipe>): ChildProcessByStdio<null, Readable, Readable>;
export declare function spawnProcess(command: string, args: string[], options: SpawnOptions): ChildProcess;
export declare function spawnProcessSync(command: string, args: string[], options: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns<string>;
/**
 * Wait for a child process to terminate without hanging on inherited stdio handles.
 *
 * A short-lived child can `exit` while a detached descendant keeps its stdout/stderr
 * pipe open. We must not resolve and destroy the streams on a short fixed deadline
 * measured from `exit`, or finite post-exit output still being written past that
 * deadline is silently lost (earendil-works/pi#5303). Instead, after `exit` we wait
 * for the pipes to fall idle: the grace timer is re-armed on every chunk, so finite
 * post-exit writers drain while active, while a quiet inherited handle (e.g. a
 * Windows daemonized descendant that never lets `close` fire) releases promptly
 * after the grace elapses. A longer active-drain hard cap is armed once on `exit`
 * so an endlessly noisy descendant cannot keep the wait pending forever.
 */
export declare function waitForChildProcess(child: ChildProcess, options?: WaitForChildProcessOptions): Promise<number | null>;
export {};
//# sourceMappingURL=child-process.d.ts.map