Pain
During live dogfood, all diagnostic signal lives in the interactive chat scrollback. When a session does something unexpected (see #47 for an example: 21.7k tokens, 0 MCP tool calls, 18s latency), the only way to debug is to screenshot or copy-paste the output into an issue. No structured capture, no grep-able history, nothing to attach to a bug report.
Proposal
Per-session log files, auto-saved under .claude/tmb/logs/<YYYY-MM-DD-HHMMSS>-<session-id>.log, capturing:
- Timestamped user prompts.
- Agent spawn names (tmb:bro, tmb:architect, etc.).
- Per-spawn token counts + latency + tool use count (the
(0 tool uses · 21.7k tokens · 18s) line).
- Every MCP tool call and its JSON response.
- Error responses / permission denials / forbidden-role rejections.
Not in scope
- Full chat transcript capture — Claude Code already owns the transcript; we shouldn't duplicate.
- User-facing notifications about what's logged — the file is a developer tool.
- Upload/export — everything stays local under
.claude/tmb/, gitignored.
Options
A. MCP-only capture via audit table (cheapest)
Every MCP call already passes through the server. Have the server write a per-session JSONL line to <db-dir>/logs/<timestamp>.log in addition to the audit table. ledger_log calls are already there. Just add a file writer.
- Pro: zero CC-level integration; server-owned file; gitignored path already.
- Con: only captures MCP calls, not agent spawns or tool-use counts from CC.
B. CC SessionStart / SessionEnd hooks + tee
A SessionStart hook opens the log file and a SessionEnd hook flushes. Agent spawns and tool counts visible from CC's event stream. Requires figuring out whether CC exposes per-spawn stats to hooks.
- Pro: full picture — agent spawns, token counts, tool counts all logged.
- Con: depends on CC hook event surface; may need CC-side feature.
C. Wrapper script (tmb-test.sh)
Users run ./tmb-test.sh instead of claude --plugin-dir .... The script tees stderr/stdout to a file. No plugin change.
- Pro: trivial; works today.
- Con: opt-in per session; easy to forget.
Recommendation
Ship A + C together:
- A as a plugin-native feature: MCP server writes a structured JSONL log per session. Cheap, always on, gitignored.
- C as a documented helper in
docs/local-testing.md for capturing chat scrollback alongside the MCP log.
- B deferred until CC exposes richer hook events — file a sub-issue referencing this when the hook API is clearer.
Acceptance criteria
Related
Pain
During live dogfood, all diagnostic signal lives in the interactive chat scrollback. When a session does something unexpected (see #47 for an example: 21.7k tokens, 0 MCP tool calls, 18s latency), the only way to debug is to screenshot or copy-paste the output into an issue. No structured capture, no grep-able history, nothing to attach to a bug report.
Proposal
Per-session log files, auto-saved under
.claude/tmb/logs/<YYYY-MM-DD-HHMMSS>-<session-id>.log, capturing:(0 tool uses · 21.7k tokens · 18s)line).Not in scope
.claude/tmb/, gitignored.Options
A. MCP-only capture via
audittable (cheapest)Every MCP call already passes through the server. Have the server write a per-session JSONL line to
<db-dir>/logs/<timestamp>.login addition to theaudittable.ledger_logcalls are already there. Just add a file writer.B. CC
SessionStart/SessionEndhooks + teeA SessionStart hook opens the log file and a SessionEnd hook flushes. Agent spawns and tool counts visible from CC's event stream. Requires figuring out whether CC exposes per-spawn stats to hooks.
C. Wrapper script (
tmb-test.sh)Users run
./tmb-test.shinstead ofclaude --plugin-dir .... The script tees stderr/stdout to a file. No plugin change.Recommendation
Ship A + C together:
docs/local-testing.mdfor capturing chat scrollback alongside the MCP log.Acceptance criteria
<db-dir>/logs/<YYYY-MM-DD>-<session-id>.log, one line per tool call with: timestamp, tool name, agent arg, args (sans sensitive keys), response status, response body (truncated at 4KB).docs/local-testing.mdadds a "Debug logs" section showing where to find them and an optionalclaude ... 2>&1 | teepattern..gitignoreexcludes.claude/tmb/logs/(already covered by.claude/blanket, but document explicitly).identity_setproduces exactly one matching log entry.Related