refactor(agents): dedupe exec spawn fallback wiring

This commit is contained in:
Peter Steinberger
2026-02-15 05:39:55 +00:00
parent 50b7607f77
commit a14d275b2a

View File

@@ -324,6 +324,20 @@ export async function runExecProcess(opts: {
let stdin: SessionStdin | undefined;
const execCommand = opts.execCommand ?? opts.command;
const spawnFallbacks = [
{
label: "no-detach",
options: { detached: false },
},
];
const handleSpawnFallback = (err: unknown, fallback: { label: string }) => {
const errText = formatSpawnError(err);
const warning = `Warning: spawn failed (${errText}); retrying with ${fallback.label}.`;
logWarn(`exec: spawn failed (${errText}); retrying with ${fallback.label}.`);
opts.warnings.push(warning);
};
// `exec` does not currently accept tool-provided stdin content. For non-PTY runs,
// keeping stdin open can cause commands like `wc -l` (or safeBins-hardened segments)
// to block forever waiting for input, leading to accidental backgrounding.
@@ -359,18 +373,8 @@ export async function runExecProcess(opts: {
stdio: ["pipe", "pipe", "pipe"],
windowsHide: true,
},
fallbacks: [
{
label: "no-detach",
options: { detached: false },
},
],
onFallback: (err, fallback) => {
const errText = formatSpawnError(err);
const warning = `Warning: spawn failed (${errText}); retrying with ${fallback.label}.`;
logWarn(`exec: spawn failed (${errText}); retrying with ${fallback.label}.`);
opts.warnings.push(warning);
},
fallbacks: spawnFallbacks,
onFallback: handleSpawnFallback,
});
child = spawned as ChildProcessWithoutNullStreams;
stdin = child.stdin;
@@ -426,18 +430,8 @@ export async function runExecProcess(opts: {
stdio: ["pipe", "pipe", "pipe"],
windowsHide: true,
},
fallbacks: [
{
label: "no-detach",
options: { detached: false },
},
],
onFallback: (fallbackErr, fallback) => {
const fallbackText = formatSpawnError(fallbackErr);
const fallbackWarning = `Warning: spawn failed (${fallbackText}); retrying with ${fallback.label}.`;
logWarn(`exec: spawn failed (${fallbackText}); retrying with ${fallback.label}.`);
opts.warnings.push(fallbackWarning);
},
fallbacks: spawnFallbacks,
onFallback: handleSpawnFallback,
});
child = spawned as ChildProcessWithoutNullStreams;
stdin = child.stdin;
@@ -453,18 +447,8 @@ export async function runExecProcess(opts: {
stdio: ["pipe", "pipe", "pipe"],
windowsHide: true,
},
fallbacks: [
{
label: "no-detach",
options: { detached: false },
},
],
onFallback: (err, fallback) => {
const errText = formatSpawnError(err);
const warning = `Warning: spawn failed (${errText}); retrying with ${fallback.label}.`;
logWarn(`exec: spawn failed (${errText}); retrying with ${fallback.label}.`);
opts.warnings.push(warning);
},
fallbacks: spawnFallbacks,
onFallback: handleSpawnFallback,
});
child = spawned as ChildProcessWithoutNullStreams;
stdin = child.stdin;