Lines 1-31javascript
1import { execFile } from "node:child_process";
2import { remoteConfig, withRemote } from "./remote.js";
HighChild Process
Package source references child process execution.
dist/worker.jsView on unpkg · L1 3import { buildService } from "./lib.js";
4/** execFile-based Exec that never throws: captures stdout+stderr, exit code, timeouts. */
5export const defaultExec = (cmd, args, opts) => new Promise((resolve) => {
6 const child = execFile(cmd, args, {
8 ...(opts.timeoutMs ? { timeout: opts.timeoutMs, killSignal: "SIGKILL" } : {}),
9 // Agent CLIs (`claude`, `codex`) are .cmd shims on Windows; Node refuses to spawn
10 // .cmd without a shell (CVE-2024-27980), so runners set shell:true. Their args are
11 // all static — the untrusted prompt goes via stdin, never the command line.
12 ...(opts.shell ? { shell: true } : {}),
13 // cmd.exe needs verbatim args or Node's quoting breaks `/c <template>`.
14 windowsVerbatimArguments: cmd === "cmd",
15 maxBuffer: 10 * 1024 * 1024,
16 }, (err, stdout, stderr) => {
17 const out = `${stdout ?? ""}${stderr ?? ""}`;
19 return resolve({ code: 0, out });
20 const timedOut = Boolean(err.killed || err.signal === "SIGKILL");
21 const code = typeof err.code === "number" ? err.code : 1;
22 resolve({ code: code === 0 ? 1 : code, out, timedOut });
24 if (opts.input != null && child.stdin) {
25 child.stdin.on("error", () => { }); // ignore EPIPE if the child exits early
26 child.stdin.end(opts.input);
29/** The headless command for each runner. Exported for tests and docs honesty. */
30export function runnerCommand(opts, prompt, platform = process.platform) {
31 // claude/codex take the prompt on stdin, and run via the shell so the Windows `.cmd`