import { spawn } from "node:child_process"; export interface CommandResult { code: number; stdout: string; stderr: string; timedOut: boolean; } export async function runCommand( command: string, args: string[], options: { cwd: string; timeoutMs: number; env?: NodeJS.ProcessEnv; }, ): Promise { return new Promise((resolve, reject) => { const child = spawn(command, args, { cwd: options.cwd, env: { ...process.env, ...options.env, }, stdio: ["ignore", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; let timedOut = false; child.stdout.on("data", (chunk) => { stdout += chunk.toString(); }); child.stderr.on("data", (chunk) => { stderr += chunk.toString(); }); child.on("error", (error) => { reject(error); }); const timeoutId = setTimeout(() => { timedOut = true; child.kill("SIGTERM"); }, options.timeoutMs); child.on("close", (code) => { clearTimeout(timeoutId); resolve({ code: code ?? -1, stdout, stderr, timedOut, }); }); }); }