Claude Agent View
A VS Code sidebar that shows what Claude Code's workflows and subagents are doing
right now — phases, per-agent state, tokens and the tool each agent is holding.
Not affiliated with or endorsed by Anthropic. It reads Claude Code's on-disk
session files, which are an internal layout rather than a published interface,
so a Claude Code release can change or break what this shows. It only ever
reads: nothing here writes to those files, and the worst case is an empty view.
The panel
The layout follows Claude Code on the web's "Background tasks" panel, measured
from the live page rather than eyeballed:
| Element |
Value |
| agent cell |
6×6px, 2px radius, 2px grid gap |
| running / stalled / error |
#2a78d6 / #fab219 / #d03b3b |
| done cell |
20% alpha of the foreground |
| card / phase band |
5% alpha of the foreground, 10px / 4px radius |
| agent table |
12px, numbers right-aligned, tabular figures |
Every surface is color-mixed from --vscode-foreground, so the panel follows
whatever VS Code theme is active instead of pinning a light one.
Three values were measured, then changed, because Claude's own are tuned for its
own backgrounds and did not survive the move:
- the 20% done cell measured 1.40:1 on a light ground and 1.64:1 on a dark one,
well under the 3:1 a meaningful non-text mark needs. It is 62% / 52% now,
reaching 3.34 and 3.56.
- the amber
#fab219 reads at 1.46:1 on light, so light uses #9c6606 (3.88).
- the web panel tints a running phase's title with its warning colour. Lightened
for a dark theme that lands on the stalled amber, and it put one state in two
colours a row apart, so a running phase is blue here — the same blue as its
cells.
Every state mark now clears 3:1 in both themes. Muted label text reaches
4.06–4.42 on light rather than 4.5: --vscode-foreground is #3b3b3b in Light
Modern, so no alpha of it gets there. Body text is 5.2+.
Why
Claude Code's /workflows browser is a terminal-only view: its slash command is
registered as a terminal-rendered command with no equivalent for the VS Code
extension, so there is nothing to draw there. The extension's own progress UI
tracks Task-tool subagents but not workflow runs — a running workflow reaches it
only as the "session is busy" spinner, with no detail behind it.
So this reads the same run data from disk instead.
Where the data comes from
Everything is read from ~/.claude/projects/<project>/<session>/. Nothing is
written, and Claude Code's own configuration is left untouched.
| Path |
Contents |
Live? |
subagents/workflows/wf_<id>/journal.jsonl |
launched / started / result per agent, with label and phase |
yes, appended during the run |
subagents/workflows/wf_<id>/agent-<id>.jsonl |
one agent's transcript — tool calls and usage |
yes |
subagents/workflows/wf_<id>/agent-<id>.meta.json |
agentType, description, workflowPhase, spawnDepth |
written at spawn |
workflows/scripts/<name>-wf_<id>.js |
the script, and the run's name in its filename |
written at launch |
workflows/wf_<id>.json |
full snapshot: workflowProgress, per-agent tokens, toolCalls, state, durationMs |
only at the end |
subagents/agent-<id>.{jsonl,meta.json} |
plain Agent-tool subagents, same shape |
yes |
Which session a run or a subagent came from is read from
~/.claude/sessions/<pid>.json, keyed by sessionId. Its name is the label
Claude Code's Rename edits (nameSource says whether it was renamed or
generated), and its pid plus procStart say whether that session is still
running — matching the process start time as well as the pid, because pids are
recycled. Sessions with no record, such as a headless -p run, fall back to a
short session id.
A live run records neither the model nor a per-agent duration in its metadata —
both are only in the end-of-run snapshot. They are recovered from the transcript
instead: assistant messages carry model, and the first and last timestamps
bracket the agent's runtime.
The snapshot is the richest source but it is written once, when the run reaches a
terminal state — polling confirmed a single write across a whole run. So:
- Finished runs are rendered from the snapshot. One small JSON per run
instead of every transcript, which took a cold scan of 49 runs from 33s to 0.6s.
- Running runs are rendered from the journal plus incremental reads of each
agent transcript.
Reading a transcript
Clicking an agent opens a reading view rather than its raw .jsonl: the prompt,
the assistant's replies, and each tool call as a row showing the tool and what it
was actually asked to do — the command for Bash, the path for Read, the
pattern for Grep. A row opens to its input and result; string fields are shown
as themselves, so a shell command reads as a shell command instead of one line of
escaped JSON. Failed calls are outlined and marked. "Open raw JSONL" is still
there for when the raw record is what you want.
Long transcripts reach tens of megabytes, so the view caps at 500 steps and
clips very long inputs and results, saying so where it does.
Agent state
| State |
How it is decided |
done |
a result line in the journal, or a transcript ending on an assistant message that called no tool |
running |
started, and still writing |
stalled |
running, but the transcript has been quiet for staleSeconds |
queued |
a meta file exists but nothing has been written yet |
stopped |
stoppedByUser in the meta, or unfinished when the run ended |
error |
an error entry in the journal, or state: "error" in the snapshot |
unknown |
a meta file with no transcript beside it, old enough that the transcript is not merely late |
A run with no snapshot whose files have been quiet for ten minutes is reported as
abandoned rather than running — that is a session that died mid-run.
A run whose agents are all done still reports as running until its snapshot
lands. That is not a lag in this view: the script itself is still finishing, and
the run is not over until Claude Code says it is.
Transcripts reach several megabytes, so they are never re-read whole. Each file
keeps a byte offset and only newly appended bytes are parsed. A transcript that
was already cold when the extension first saw it is primed from its last 64 KB,
which is enough to decide the state; its token and tool totals are reported as
unknown rather than guessed. Steady-state scans measured 1–17 ms.
That leaves blanks in a run that was already going when the view opened, so
those agents are queued and re-read in full, four per scan. Measured on a live
29-agent run: first paint 181 ms, every total filled by the fifth scan.
Settings
| Setting |
Default |
Meaning |
claudeAgentView.scope |
workspace |
workspace matches the open folder; all shows every project |
claudeAgentView.lookbackHours |
24 |
ignore sessions older than this |
claudeAgentView.pollIntervalMs |
1500 |
re-scan interval while the view is visible |
claudeAgentView.showCompleted |
true |
show finished runs and agents |
claudeAgentView.staleSeconds |
90 |
quiet-for-this-long marks a running agent stalled |
Install
npx @vscode/vsce package --allow-missing-repository --skip-license
code --install-extension claude-agent-view-0.1.0.vsix
Then reload the window. The view lives in the activity bar; a status bar item
appears while any agent is running.
Caveats
Every path and file shape above is Claude Code's internal on-disk layout, not a
published interface. It was read from version 2.1.266 and can change in any
release. Nothing here writes to those files, so the worst case is an empty view.
The extension has to run wherever Claude Code runs. If you use Claude Code
inside WSL or a container, install it into that remote, not the local UI side —
otherwise it has no ~/.claude to read.