fix(daemon): resolve codex app-server deadlock after turn completion

The codex backend spawns a long-running app-server process that doesn't
exit after completing a turn. The lifecycle goroutine was waiting on
<-readerDone which blocks on scanner.Scan() until stdout closes — but
stdout never closes because the process stays alive. This caused the
entire poll loop to freeze, preventing any further task processing.

Fix: explicitly close stdin and cancel the context after the turn
completes, which terminates the codex process and unblocks the reader.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-03-24 17:37:52 +08:00
parent c4a7cf9726
commit 828b75c76d

View file

@ -205,6 +205,12 @@ func (b *codexBackend) Execute(ctx context.Context, prompt string, opts ExecOpti
b.cfg.Logger.Printf("[codex] finished pid=%d status=%s duration=%s",
cmd.Process.Pid, finalStatus, duration.Round(time.Millisecond))
// Close stdin and cancel context to signal the app-server to exit.
// Without this, the long-running codex process keeps stdout open and
// the reader goroutine blocks forever on scanner.Scan().
stdin.Close()
cancel()
// Wait for the reader goroutine to finish so all output is accumulated.
<-readerDone