fix(headless): exit cleanly on stdout EPIPE (#804)
This commit is contained in:
@@ -134,7 +134,6 @@ export async function handleHeadlessCommand(
|
|||||||
const { toolFilter } = await import("./tools/filter");
|
const { toolFilter } = await import("./tools/filter");
|
||||||
toolFilter.setEnabledTools(values.tools as string);
|
toolFilter.setEnabledTools(values.tools as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set permission mode if provided (or via --yolo alias)
|
// Set permission mode if provided (or via --yolo alias)
|
||||||
const permissionModeValue = values["permission-mode"] as string | undefined;
|
const permissionModeValue = values["permission-mode"] as string | undefined;
|
||||||
const yoloMode = values.yolo as boolean | undefined;
|
const yoloMode = values.yolo as boolean | undefined;
|
||||||
@@ -176,6 +175,25 @@ export async function handleHeadlessCommand(
|
|||||||
const inputFormat = values["input-format"] as string | undefined;
|
const inputFormat = values["input-format"] as string | undefined;
|
||||||
const isBidirectionalMode = inputFormat === "stream-json";
|
const isBidirectionalMode = inputFormat === "stream-json";
|
||||||
|
|
||||||
|
// If headless output is being piped and the downstream closes early (e.g.
|
||||||
|
// `| head`), Node will throw EPIPE on stdout writes. Treat this as a normal
|
||||||
|
// termination rather than crashing with a stack trace.
|
||||||
|
//
|
||||||
|
// Note: this must be registered before any `console.log` in headless mode.
|
||||||
|
process.stdout.on("error", (err: unknown) => {
|
||||||
|
const code =
|
||||||
|
typeof err === "object" && err !== null && "code" in err
|
||||||
|
? (err as { code?: unknown }).code
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (code === "EPIPE") {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-throw unknown stdout errors so they surface during tests/debugging.
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
// Get prompt from either positional args or stdin (unless in bidirectional mode)
|
// Get prompt from either positional args or stdin (unless in bidirectional mode)
|
||||||
let prompt = positionals.slice(2).join(" ");
|
let prompt = positionals.slice(2).join(" ");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user