BlogParallel agents

How can I see what Claude Code subagents are doing?

In the terminal, running subagents appear in the subagent panel below the prompt input. Select a row to open that subagent's transcript, run /tasks to list background work, or press Ctrl+O for the detailed transcript viewer. Claude Code also saves every subagent's transcript on disk, under ~/.claude/projects/<project>/<sessionId>/subagents/, so you can read or script against it after the fact.

Why subagents feel opaque

A subagent works in its own context window and returns a summary to the session that spawned it. That is the point: the main conversation stays clean. As of October 2026, subagents that Claude spawns from your main conversation start in the background by default, so you keep working while they run. The side effect is that you see their result, not their path, unless you go looking.

Without Kanbell: five ways to look inside

1. The subagent panel

Background subagents appear as rows in a panel below the prompt input.

  • Use the arrow keys to select a row, and Esc to go back to the prompt.
  • Open a row to see the subagent's transcript. While it's open, your messages go to that subagent, not to the main conversation.
  • Nested subagents show as a tree. A row that still has descendants shows a (+N) count; opening it shows its siblings and direct children with a path back to main.

A successful subagent leaves the panel immediately; a failed or stopped one stays for 30 seconds. Select that row and press x to clear it sooner.

2. /tasks

/tasks

Lists the background work in the current session: subagents, background shell commands, and more. A completed subagent stays there, marked done, for 30 seconds; press Enter on it to open its transcript. The footer shows /tasks to see subagents during that window. /tasks runs immediately, even while Claude is responding.

Named background subagents also appear in the @ mention typeahead with their status.

3. The transcript viewer

Press Ctrl+O. It shows detailed tool usage and execution, with a timestamp and the model on each assistant message, and expands lines that are collapsed by default.

4. The transcripts on disk

Each subagent is stored as its own file:

~/.claude/projects/<project>/<sessionId>/subagents/agent-<agentId>.jsonl
~/.claude/projects/<project>/<sessionId>/subagents/agent-<agentId>.meta.json

<project> is your working directory path with non-alphanumeric characters replaced by -. To follow the most recent subagent live:

cd ~/.claude/projects/-Users-me-code-myapp/
ls -t */subagents/*.jsonl | head -1 | xargs tail -f

These files are unaffected when the main conversation compacts, and Claude Code deletes them after cleanupPeriodDays (30 days by default).

5. A hook that logs every result

SubagentStop runs when a subagent finishes. Its input includes agent_type, agent_transcript_path and last_assistant_message. One catch: since v2.1.271, a subagent that has the SubagentHandback tool, which Claude Code provides in auto mode, delivers its report through that tool, and last_assistant_message then holds only its closing text. To capture the report itself, match a PostToolUse hook on SubagentHandback and read tool_input.message.

Save this as ~/.claude/hooks/log-subagent.sh (needs jq):

#!/bin/sh
jq -r '"[\(.agent_type)] \(.last_assistant_message)\n"' >> "$HOME/.claude/subagent-log.md"

Register it in ~/.claude/settings.json:

{
  "hooks": {
    "SubagentStop": [
      { "hooks": [{ "type": "command", "command": "$HOME/.claude/hooks/log-subagent.sh" }] }
    ]
  }
}

SubagentStart runs when a subagent spawns or resumes, if you also want a start line. Note that Claude Code runs some internal agents too, such as prompt suggestions and /btw, and those can fire SubagentStop as well.

Also useful

  • Ask for a file. Tell the subagent to write its findings to a file in the repository. You get a readable artifact instead of a summary that scrolls away.
  • In Claude Code Desktop, the tasks pane (⋮ menu → Background tasks) lists subagents, background commands and workflows; click one to see its output.

Limits of these methods

  • Per session. The panel and /tasks show one session's subagents. With four sessions running, you check four places.
  • Short windows. Finished subagents leave the panel at once and /tasks after 30 seconds. After that, you go to the files.
  • Raw files. The transcripts are JSONL, written for Claude Code, not for reading.
  • Background sessions hide them. Agent view doesn't list subagents as separate rows.

With Kanbell

Kanbell is a macOS app (Apple Silicon) with an agent map: for Claude Code, it shows the agents running in a project and the subagents they spawn, with each one's state (working, waiting or done). You see agents and subagents in one place instead of opening the panel in each terminal.

Around it:

  • Waiting is visible: when an agent waits on a question or a permission, an orange dot appears in the window, the menu bar and the overview, with a macOS notification. ⌘⇧J jumps to it.
  • Real terminals in panes and tabs, one window per project, so you can still open the panel or /tasks in any session.

Limits: the subagent tree is Claude Code only. Codex CLI has no subagent tree in Kanbell yet, and Gemini CLI doesn't publish subagents. No account and no Kanbell server.

FAQ

Where are subagent transcripts stored?

In ~/.claude/projects/{project}/{sessionId}/subagents/, one agent-{agentId}.jsonl file per subagent, next to an agent-{agentId}.meta.json file. They are deleted after cleanupPeriodDays, 30 days by default.

Why did a finished subagent disappear from the panel?

A subagent that finishes successfully leaves the panel at once. For 30 seconds, /tasks still lists it and Enter opens its transcript.

Can I talk to a running subagent?

Yes. While its row is in the subagent panel, open its transcript and type a message; it goes to that subagent rather than the main conversation.

Can a hook record what each subagent concluded?

Yes. SubagentStop hooks receive agent_type, agent_transcript_path and last_assistant_message. In auto mode, a subagent that hands its report back with the SubagentHandback tool leaves only its closing text there; a PostToolUse hook on SubagentHandback gets the report as tool_input.message.