import { spawn } from "node:child_process";
import { getDefaultTimeoutMs } from "../config.js";
export function runCli(
command: string,
args: string[],
timeoutMs = getDefaultTimeoutMs(),
cwd?: string,
): Promise<string> {
return new Promise((resolve, reject) => {
const child = spawn(command, args, {
stdio: ["ignore", "pipe", "pipe"],
cwd,
env: {
...process.env,
NO_COLOR: "1",
FORCE_COLOR: "0",
TERM: "dumb",
},
});
let stdout = "";
let stderr = "";
const timer = setTimeout(() => {
child.kill("SIGTERM");
reject(new Error(`${command} timed out after ${timeoutMs}ms`));
}, timeoutMs);
child.stdout.on("data", (chunk: Buffer) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk: Buffer) => {
stderr += chunk.toString();
});
child.on("error", (error) => {
clearTimeout(timer);
reject(new Error(`${command} failed to start: ${error.message}`));
});
child.on("close", (code) => {
clearTimeout(timer);
if (code === 0) {
resolve(stdout.trim() || "(empty response)");
return;
}
reject(
new Error(
`${command} exited with code ${code}: ${stderr.trim() || "no stderr"}`,
),
);
});
});
}