Plan: Restore agent-runner.log in agent-worker InvocationProcessor#
Summary#
Port the human-readable agent-runner.log writing logic into InvocationProcessor in the agent-worker repo. The processor currently pipes stdout/stderr directly to file descriptors; it must switch to 'pipe' mode, parse stream-json chunks for log formatting, and write timestamped entries to meta/agent-runner.log alongside existing outputs.
Files#
| File | Action | Description |
|---|---|---|
agent-worker/src/invocation/invocation.processor.ts | modify | Add log stream creation, switch stdio to pipe, parse JSON lines, write formatted log entries |
agent-worker/src/invocation/invocation.processor.spec.ts | create | Unit tests for agent-runner.log creation, format, logEnded guard, and error paths |
Steps#
- Add
cetTs()helper — Add a privatecetTs()method or module-level function returningnew Date().toLocaleString('sv-SE', { timeZone: 'Europe/Berlin' })for CET/CEST timestamps. - Create log WriteStream — Open
{metaDir}/agent-runner.logwithflags: 'a'and write a start header:{ts} - {phase} - Starting Claude invocation. - Switch stdio from fd to pipe — Change
stdiofrom['ignore', stdoutFd, stderrFd]to['ignore', 'pipe', 'pipe']so stdout/stderr are available as streams. - Pipe stdout to both output file and log — Attach
child.stdout.on('data')handler: write raw chunks to the output file WriteStream, parse JSON lines to extracttype(tool_use →[tool:ToolName], text →[text]), and write formatted entries to the log stream. - Pipe stderr to both stderr file and log — Attach
child.stderr.on('data')handler: write raw chunks to the stderr file WriteStream, write{ts} - {phase} - stderr: {chunk}to the log stream. - Add logEnded guard — Introduce a
logEndedboolean flag; set ittrueon stream close/error; check before everylogStream.write()call. - Write completion footer — In the
closehandler, write{ts} - {phase} - Completed with exit code {code}to the log, then close the log stream. - Handle error path — In the
errorhandler, write an error entry and close the log stream with thelogEndedguard. - Write unit tests — Test: log file created with correct header/footer, JSON line parsing produces correct
[tool:X]/[text]prefixes,logEndedprevents write-after-end, missing taskDir handled gracefully.
Verification#
- Run
npm run lintandnpm run testin agent-worker — all pass - After an invocation,
meta/agent-runner.logexists with timestamped start header, per-chunk entries, and completion footer - Viewer no longer returns 404 for the log
Risks#
- Stream backpressure — Switching from fd to pipe adds buffering; mitigate by keeping log writes synchronous and non-blocking (WriteStream handles this)
- JSON parse errors — Malformed stdout lines from Claude; mitigate by wrapping JSON.parse in try/catch and falling back to raw line logging