Original Reddit post

github.com/Kostakurta8/roundtable — MIT, free, runs entirely on your machine. Every Claude Code session is already written to disk as it happens: one JSONL per session under ~/.claude/projects/ , plus one per subagent. Most people never open those files. They are a complete recording of the run — every prompt, every tool call, every token. So the thing I actually wanted was a player. Not a usage total: a player. What it does You run npm start and it opens on the session you’re currently running. Then: Scrub to any second. Pick a finished session, drag the timeline, and see exactly the state at that moment — who was running, what each agent had read and edited, what it was working on. The question that made me build it was “when did it decide to rewrite that file”, and that is now a question with an answer rather than a scroll. Every subagent in one view. One row each, live: what it’s doing now, what it has touched, when it actually stopped. A twelve-way fan-out stops being a wall of interleaved text. Per-agent tokens and cost , because once you can see them side by side the interesting number is not the total, it’s which agent spent it. Strictly read-only. It opens transcripts and nothing else — no writes anywhere near ~/.claude , no telemetry, no account, no network calls at all, localhost-only binding, secrets redacted before anything crosses the socket. SECURITY.md documents what it touches. What I learned building it, which is useful even if you never run it Reading those transcripts correctly is much harder than it looks, and every tool that counts tokens from them can get these wrong: usage is written on every streamed line of a response, not once per response. Take the first line per message.id instead of the last and you undercount by roughly a third. I mentioned this to the author of another usage tool; he re-ran it on his own data, his totals moved from 33.2M to 48.8M output tokens, and he shipped a fix. The figures are deltas, not totals , and they are not strictly monotonic — one response in 400 reported its cache numbers down on a later line (cacheRead 246,389 -> 228,908), which sends a naive delta sum negative. A message.id can resume hundreds of responses later — 270 and 389 responses later in one real transcript — so an accumulator with a short memory republishes the whole response and double-counts it. A Task spawned with run_in_background returns its tool_result to the parent when the child launches, not when it finishes . Across my transcripts, 246 spawns reported “done” while the child was still writing, the worst by 995 seconds. Anything that trusts that signal retires an agent that is still working. Practicals npm run demo runs it against a synthetic session if you want to see it move before pointing it at your own work. 539 tests, CI green on Linux/macOS/Windows. MIT, no telemetry, no cloud, no account. I’d genuinely like to be told where the accounting is wrong — it’s all in server/normalize.ts with the reasoning in comments. submitted by /u/ClaudeCdGuy

Originally posted by u/ClaudeCdGuy on r/ClaudeCode