cdee320fed53bffb8dd8a59f50395816d622c2ca
B8, both halves. They share index.ts, so they share a commit. In-flight turns: `opencode run` is spawned, not supervised, so pm2 restart officer-opencode left every turn ALIVE — reparented, still spending tokens, still writing files as the agent, with the only reader of its stdout gone. The transcript stopped mid-tool-call, which reads as the agent hanging. stopAllOpenCodeTurns kills them and settles each synchronously, because the caller is about to process.exit and nothing waiting on proc.exited would ever run. Settling writes a reason, so a reload after a restart explains itself instead of trailing off. Turns are stopped BEFORE the connection is destroyed — that write travels over it — and the flush is bounded, since losing the explanation is bad but hanging the restart is worse. Stale serves: the sweep read /proc, so it was a no-op on macOS and orphaned serves piled up, one per unclean exit, each holding a port. Added a pidfile sweep alongside it. A pid we wrote ourselves needs no cwd guard to prove it is ours, which is the part ps cannot answer portably (macOS would need lsof), and a serve started by hand is never in the file. The guard checks command AND subcommand: matching the word serve anywhere in the line would sweep a running turn whose prompt merely mentioned it. Fixtures are real ps output from both machines, not invented. Split into serve-sweep.ts because index.ts spawns a serve at module scope, so a test importing it would start one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
42 MiB
Languages
TypeScript
90.9%
Shell
4.7%
JavaScript
4.1%
CSS
0.2%
HTML
0.1%