fix: use exit event instead of close to resolve process hang with background jobs

The cross-spawn spawner relied on the 'close' event to mark a process as
complete. In Node.js, 'close' fires only after all stdio streams are closed.
When a shell spawns a background child (e.g., 'cmd &'), the child inherits
stdout/stderr pipe descriptors, keeping the streams open even after the shell
exits. This caused the 'close' event to never fire, making the bash tool hang
indefinitely.

Switching to the 'exit' event resolves this — it fires as soon as the
process terminates, regardless of inherited pipe descriptors.
pull/20901/head
Agent Core Dev 2026-04-03 22:45:53 +08:00
parent a4e75a0794
commit 4bd67f11a8
2 changed files with 3 additions and 4 deletions

1
opencode-cli 160000

@ -0,0 +1 @@
Subproject commit 224b297604143373d680621ac4e9cb0def609be6

View File

@ -272,12 +272,10 @@ export const make = Effect.gen(function* () {
resume(Effect.fail(toPlatformError("spawn", err, command)))
})
proc.on("exit", (...args) => {
exit = args
})
proc.on("close", (...args) => {
if (end) return
end = true
Deferred.doneUnsafe(signal, Exit.succeed(exit ?? args))
exit = args
Deferred.doneUnsafe(signal, Exit.succeed(exit))
})
proc.on("spawn", () => {
resume(Effect.succeed([proc, signal]))