fix: prevent FD leaks in child process cleanup

- Destroy stdio streams (stdin/stdout/stderr) after process exit
- Remove event listeners to prevent memory leaks
- Clean up child process reference in moveToFinished()
- Also fixes model override handling in agent.ts

Fixes EBADF errors caused by accumulating file descriptors
from sub-agent spawns.
This commit is contained in:
KyleChen26
2026-02-10 12:33:31 +08:00
committed by Tak Hoffman
parent 16f2492547
commit 82360f200b

View File

@@ -157,6 +157,38 @@ export function markBackgrounded(session: ProcessSession) {
function moveToFinished(session: ProcessSession, status: ProcessStatus) {
runningSessions.delete(session.id);
// Clean up child process stdio streams to prevent FD leaks
if (session.child) {
// Destroy stdio streams to release file descriptors
session.child.stdin?.destroy?.();
session.child.stdout?.destroy?.();
session.child.stderr?.destroy?.();
// Remove all event listeners to prevent memory leaks
session.child.removeAllListeners();
// Clear the reference
delete session.child;
}
// Clean up stdin wrapper - call destroy if available, otherwise just remove reference
if (session.stdin) {
// Try to call destroy/end method if exists
if (typeof session.stdin.destroy === "function") {
session.stdin.destroy();
} else if (typeof session.stdin.end === "function") {
session.stdin.end();
}
// Only set flag if writable
try {
(session.stdin as { destroyed?: boolean }).destroyed = true;
} catch {
// Ignore if read-only
}
delete session.stdin;
}
if (!session.backgrounded) {
return;
}