Files
playbook/antigravity-awesome-skills/verification/aas-v1/verifier/lib/process.mjs
T
2026-07-18 00:02:59 +00:00

52 lines
1.8 KiB
JavaScript

import { spawn } from "node:child_process";
export function runProcess(executable, args, options = {}) {
const timeoutMs = options.timeoutMs ?? 30_000;
return new Promise((resolve, reject) => {
const child = spawn(executable, args, {
cwd: options.cwd,
env: options.env,
detached: options.detached === true,
windowsHide: true,
stdio: [options.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
});
if (typeof options.onSpawn === "function") options.onSpawn(child);
const stdout = [];
const stderr = [];
let stdoutBytes = 0;
let stderrBytes = 0;
const maxOutputBytes = options.maxOutputBytes ?? 4 * 1024 * 1024;
let killedForOutput = false;
const collect = (chunks, kind) => (chunk) => {
const callback = kind === "stdout" ? options.onStdoutData : options.onStderrData;
if (typeof callback === "function") callback(chunk);
if (kind === "stdout") stdoutBytes += chunk.length;
else stderrBytes += chunk.length;
if (stdoutBytes + stderrBytes > maxOutputBytes) {
killedForOutput = true;
child.kill("SIGKILL");
return;
}
chunks.push(chunk);
};
child.stdout.on("data", collect(stdout, "stdout"));
child.stderr.on("data", collect(stderr, "stderr"));
child.once("error", reject);
if (options.stdin !== undefined) {
child.stdin.end(options.stdin);
}
const timer = setTimeout(() => child.kill("SIGKILL"), timeoutMs);
child.once("close", (code, signal) => {
clearTimeout(timer);
resolve({
code: code ?? 128,
signal,
stdout: Buffer.concat(stdout).toString("utf8"),
stderr: Buffer.concat(stderr).toString("utf8"),
timedOut: signal === "SIGKILL" && !killedForOutput,
outputLimitExceeded: killedForOutput,
});
});
});
}