I build ccdeck. The step-by-step version of this post, with every key and setting, is at ccdeck.dev/guides/read-a-session.
Four subagents, one column of text
I ask Claude Code to add rate limiting to an API. It starts a subagent to write the migration, another to update the docs, a reviewer, and a general-purpose one to chase something it found. Four agents, working at the same time.
My terminal shows that as a scroll. Every tool call from every subagent arrives in one column, interleaved, and the questions I actually have are the ones a scroll answers worst:
- What is running right now?
- What did that subagent actually do?
- Which one is stuck, and on what?
An agent session is a tree. So I wanted to look at it as a tree.
The canvas: one card per agent
ccdeck is a local dashboard for Claude Code and Codex CLI. Start it with:
npx ccdeck
It opens on http://127.0.0.1:4317 and draws every session on the machine. Each card is one agent: a session, or a subagent that a Claude Code session started. A line joins each subagent to its session. It is dashed and moving while the subagent runs, and solid once it finishes.

Demo data. One session with four subagents, of which only the reviewer is still running.
Here is how to read a card:
-
The state pill reads
LIVE,DONEorERR. -
The bubbles to the right are the card's last four tool calls: a spinner while one runs, ✓ when it finished, × when it failed. Beside a
Bashcall, a second bubble names the program it ran (such asnpm); beside a file call, the file. - The top row has the name and how long it has run. A session is named after its folder, a subagent after its type.
-
→ 4on a session means it started four subagents. -
The model chip says which model is doing the work, such as
Opus 5orSonnet 5. - The last row counts tool calls, those still in flight, and failures once there is one. A session adds its input and output tokens and its spend.
- The ring before a session's clock is the share of the model's context window in use. For Claude Code that is the deck's estimate; for Codex it is Codex's own figure. Click it for the breakdown.
Codex sessions land on the same canvas, told apart by an OpenAI model chip. They show less: Codex's log records no subagents and no title, so a Codex card has no subagent cards under it.
Getting around
The keys I use the most:
-
Ffits every agent on screen. -
J/Kgo to the next and previous agent and open its details. -
Zzooms to the selected agent and its session. -
Lopens the session list;Dthe detail panel;Esccloses what is open. - Drag the empty canvas or scroll to pan, and hold
Ctrl(Cmdon macOS) and scroll to zoom.

Demo data. The chip appears once you move the view.
Once you move the view or click a card, the deck stops pulling new sessions into view and says Auto-fit off. Resume turns it back on. F fits once and leaves auto-fit off.
The session list (L) puts sessions waiting on you first, then running ones, then finished ones. A row counts its subagents' tool calls too. Clicking a row frames that session and opens its detail panel.

Demo data. Zoomed far out, cards become small faces; hover one for its name, state and numbers.
What did that subagent actually do?
Double-click a card. (From the keyboard: Tab to the card, then Enter.) Its detail panel opens with:
- Activity: how many calls, how many are running or failed, and the calls by kind;
- Tokens: in, out, cache read and cache created;
- Identity: the folder, the session id and, for a subagent, its parent;
- Prompts: what was typed into the session, newest first;
- Tool calls: every call, newest first, with how long it took.

Demo data. The newest call is still running, so it shows … instead of a duration.
Tokens and spend belong to the session. A Claude Code session's figures include its subagents, so a subagent's own panel has no tokens, spend or prompts.
Then click any tool call. A dialog shows its Input and its Response, each with a copy button: for Bash the command and its output, for Edit the file and the change, for Read the file. Clicking a bubble on the canvas opens the same dialog.

Demo data. A finished Bash call from the migrator subagent.
This is the part I use the most. It reports what actually executed, from the hook stream, not what the agent said it did in its summary.
It survives a restart
The deck appends every event to a log and reads back up to the newest 2,000 when it starts. A restart — after an upgrade, or a reboot — redraws the sessions that were there.
- A card with
?beside its name and≥before its clock is a session the deck joined late; its clock counts from when the deck first saw it. -
npx ccdeck --statusnames each running deck's log file.--history <path>uses a file of your choosing, and--no-persistwrites and replays nothing. - Clearing the canvas (
C, or the bin in the controls) empties the log too, and asks first.
What it does not do
- Nothing is recorded while the deck is stopped. The hook forwards events to a running deck; if none is running, those events are gone.
- It keeps the last 200 calls of each agent, and the full input and response of only the newest 25. For older calls the dialog shows a short preview and says the full payloads were released.
- The board keeps six finished sessions and lets an older one go two minutes after it finishes.
- Codex has no subagent cards and no title, because its rollout log does not record them.
- It watches; it does not steer. The Claude Code hook only forwards events, so the deck cannot allow, deny or change anything an agent does.
Try it
npx ccdeck
Then ask Claude Code for something that fans out into subagents, and watch the tree grow.
- Guide: https://ccdeck.dev/guides/read-a-session/
- Repo: https://github.com/BarganConstantin/ccdeck
- Licence: AGPL-3.0
Top comments (0)