Background agents you can't see are just faith with a progress spinner. Now that Claude Code's /fork creates real background sessions that outlive the moment, the question stops being "did it work" and becomes "what are all of these doing right now?" Here's how to answer that without hovering.
1. List the sessions#
Everything starts at the agents view:
claude agents
Every running or parked session shows up here, including the background sessions that /fork now creates as their own rows. When you want status a script can read — for a dashboard, a poll loop, or a notifier — ask for JSON:
claude agents --json
That's the same information as structured data. The field you care about most is the session's state.
2. Read the state: "Needs input" is the one that matters#
The most useful recent change is quiet. As of 2.1.203, a session that is waiting on a sandbox approval, an MCP input prompt, or a managed-settings decision reports Needs input instead of the old catch-all Working. That single relabel is the difference between "this agent is thinking" and "this agent has been silently blocked for ten minutes because nothing is attached to answer its prompt."
So the first thing to scan for across parallel runs is Needs input. A busy agent will finish on its own; a blocked one needs you, and now it says so.
3. See the reasoning, not just the result#
The agents view tells you that a session is running. To see what a subagent is actually doing — its text and its thinking — run headless with the streaming format and forward subagent output:
claude -p "refactor the auth module and run the tests" \
--output-format stream-json --verbose --include-partial-messages \
--forward-subagent-text
Each line of that stream is a JSON event. Subagent messages arrive as assistant/user events whose parent_tool_use_id is the tool call that spawned them (main-conversation messages carry null there), so you can tell which agent said what. By default Claude Code emits only a subagent's tool_use and tool_result blocks; --forward-subagent-text (added in 2.1.211; CLAUDE_CODE_FORWARD_SUBAGENT_TEXT=1 is the same switch) also emits its text and thinking, so you can reconstruct each subagent's full transcript instead of seeing only a final message. Pipe it through jq to render just the text as it streams.
This is the observability half of the week's redesign:/forkmade background work durable,--forward-subagent-textmakes it legible.
4. Bound it, and let it end itself#
Watching is not the same as controlling. Pair observability with the two per-session budgets that shipped in 2.1.212:
export CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION=50
export CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION=100
Both default to 200; /clear resets the budget mid-session. These are loop-breakers, not spend caps — set them to how many agents and searches one session should ever be allowed to launch on your behalf. (We go deeper on why the spawn cap isn't a bill cap in How to Cap a Runaway Claude Code Agent.)
Finally, let finished work clean up after itself. The EndConversation tool (added 2.1.214) lets an agent close its own session when the job is done, so background sessions don't pile up in the agents view. A well-run background agent starts with a /fork, reports honest status in the agents view, streams its reasoning when you ask, respects its caps, and ends itself.
The loop, end to end: fork durable work → scan claude agents for Needs input → forward subagent text when you need detail → cap the fan-out → let it end. That's how one person supervises ten agents without watching any of them.



