
Claude Code Hands-On (8): Sub-Agents, Worktrees, and Plan Mode
Three features that change what Claude Code can take on at once: sub-agents for parallel research, worktrees for isolation, plan mode for the moments before you let it touch anything. The boundaries between them, and when each is the wrong answer.
After hooks, the next thing that changes how Claude Code operates is concurrency control. Not in the threading sense, but in terms of how many tasks it handles, their isolation, and the level of oversight.
Three features, in increasing order of trust required.

Plan mode — the airlock#
Plan mode is the cheapest of the three. Press Shift+Tab until the indicator says plan. The model now plans without taking any actions. It will read, think, propose, and stop. You read the plan. You either approve, edit, or kill it. Only then does it execute.

How to activate it#
Here are three ways:
- Keyboard shortcut:
Shift+Tabcycles through modes:auto→plan→auto. The current mode shows in the bottom bar. - CLI flag:
claude --mode planstarts a session in plan mode. - Mid-conversation: Just press
Shift+Tabat any point. The mode switch is immediate.
A real plan mode walkthrough#
Let me show exactly what happens. Say I’m working on an Express API and want to add rate limiting.
| |
Now I can see: step 1 caught that the package is in devDependencies. Step 3 tells me where exactly in the middleware chain it goes. Step 6 reminds me about env vars. Without plan mode, Claude would have just started writing code, and I would have caught these details in review, not upfront.
When I use plan mode#
- The first 30 seconds of any non-trivial task. “Implement the X feature” gets a plan first. Almost always, the plan reveals the model misunderstood the codebase.
- Anything touching auth, payments, schema migrations, or production config. Two seconds of reading a plan saves hours of cleanup.
- When working in a repo I do not know well. The plan doubles as my own onboarding doc — it shows me the architecture through the model’s eyes.
- Before refactoring. “Refactor module X” → plan reveals the dependency graph. Sometimes the plan shows me the refactoring is not worth it.
The common mistake#
Skipping plan mode for small tasks can lead to misunderstandings. A one-line fix in the wrong file is worse than a large feature with a clear plan.
Plan mode modifiers#
You can steer the plan with instructions.
| |
The model respects the scope constraint, preventing plans from becoming 20-step novels.
Approving, editing, and rejecting#
After Claude shows the plan:
- Approve: Switch back to
automode (Shift+Tab) and say “go.” Claude executes the plan. - Edit: “Looks good, but skip step 4 and do step 3 before step 2.” Claude adjusts.
- Reject: “Actually, never mind. Let’s do Y instead.” The plan was cheap — you lost thirty seconds, not thirty minutes.
Sub-agents — for things you can run in parallel#
A sub-agent is a Claude Code instance spawned by the parent agent to handle a scoped task. It has its own context window, tool set, and instructions. The parent orchestrates, and the sub-agents do the work.

Defining a sub-agent#
The classic form lives in .claude/agents/<name>.md:
| |
More agent examples#
A test-writing agent:
| |
A documentation agent:
| |
How sub-agents are invoked#
In conversation, you can direct Claude to use a sub-agent:
| |
What sub-agents buy you#
Context isolation. The sub-agent’s context window is separate, keeping the parent’s clean. This is crucial for complex tasks that require research without cluttering the main context with 30 file reads.
Tool restriction. A research agent literally cannot edit files. That is safety as architecture, not as discipline. You do not have to trust the model to avoid editing — it does not have the capability.
Parallel work. You can fan out to multiple sub-agents when the work is independent:
| |
What sub-agents cost#
Tokens. Each sub-agent has its own system prompt, its own context, its own back-and-forth. Three sub-agents doing research cost three times the tokens of one.
Coordination. The parent has to merge the results. If sub-agent A finds something that sub-agent B needs to know, they cannot talk to each other. Plan that step explicitly.
Startup time. Spawning a sub-agent takes time. For a 10-second task, the overhead isn’t worth it.
When sub-agents are the wrong answer#
- When the parent already has the context. Spawning a sub-agent to “go read this one file and report back” is expensive recursion. Just read the file.
- When tasks are sequential. If B depends on A’s output, you cannot parallelize. Run them in sequence in the parent.
- When the task is small. If the whole job is “fix this typo,” sub-agents are overhead.
Worktrees — for parallel branches without losing your mind#

A git worktree is a second working tree of the same repo, on a different branch, in a different directory. Claude Code knows about them: the EnterWorktree tool creates a new branch + worktree and switches the session into it.
How worktrees work under the hood#
When Claude calls EnterWorktree, here is what happens:
- A new directory is created under
.claude/worktrees/<name>/. - A new git branch is created (based on
origin/mainby default, or current HEAD if configured). git worktree addlinks the new directory to the new branch.- Claude’s working directory switches to the new worktree.
- All subsequent file operations happen in the worktree, not the original repo.
The key insight: the worktree shares the same .git object store as the original repo. Commits, branches, and refs are shared. But the working tree — the files on disk — is independent.

.git/ object store but each owns an independent working tree pinned to a unique branch.
Creating and entering a worktree#
| |
Now any file edits happen in the worktree. The original working tree is untouched.
Configuring the base ref#
By default, worktrees branch from origin/<default-branch> (usually origin/main). If you want to branch from your current HEAD instead:
The worktree.baseRef setting controls this:
fresh(default): branch fromorigin/mainhead: branch from current local HEAD
When worktrees matter#
Mid-task context switch. You are mid-task on feat/x and the user asks for an unrelated quick fix on main. Spawn a worktree, do the fix, commit, exit. Your feat/x work is untouched.
Experimental branches. You want to try two different approaches to the same problem without polluting your main branch with abandoned commits. Create two worktrees, try both, keep the winner, remove the loser.
Sub-agent isolation. You are delegating to a sub-agent and want it physically isolated from your working tree. Give it a worktree. If its work is bad, you remove the worktree and nothing in your main tree was touched.
Exiting a worktree#
Two options:
Keep the worktree:
| |
Use keep when the work is partial, when you want to come back later, or when you want to review the changes before merging.
Remove the worktree:
| |
Use remove for a clean exit when the work is done or abandoned. If the worktree has uncommitted changes, removal refuses unless you confirm with discard_changes: true. This is correct. Do not paper over it.
Merging worktree work back#
After exiting a worktree with keep, the branch still exists:
| |
Worktree gotchas#
You cannot have two worktrees on the same branch. Git enforces this. If you try to create a worktree on a branch that already has one, it fails. Solution: use different branch names.
Worktrees share the git lock. Some git operations (like gc) lock the entire repo. If one worktree is running gc, the other blocks. This is rarely a problem in practice, but it can cause confusing hangs.
IDE integration varies. Some editors detect worktrees and adjust automatically. Others get confused about which directory is the “real” repo. VS Code handles worktrees well. Other editors, check first.
Composing the three#
The real power is in composition. Here is a real-world scenario that uses all three features together.
Scenario: refactoring a monolith’s auth module#
The task: extract the authentication logic from a monolith Express app into a standalone middleware package. This involves 15+ files, a new package structure, migration of tests, and backward-compatible imports.
Step 1: Plan mode#
| |
I review the plan. The circular dependency risk is real — I did not think of it. I approve with a modification: “Do the research phase first, then we’ll revisit the plan.”
Step 2: Worktree#
| |
Now everything happens in isolation. If the extraction fails, I remove the worktree and nothing in my main branch was touched.
Step 3: Sub-agents for research#
| |
The research confirms the circular dependency. Now I know to extract shared types first.
Step 4: Implementation in the worktree#
Claude proceeds with the extraction, working entirely in the worktree. Each step gets its own commit:
| |
Step 5: Exit and merge#
| |
The whole refactoring happened in isolation. If at any point it went sideways, I could have exited with remove and started fresh.
The three features as trust gates#
Think of them as escalating levels of trust:

| Feature | Trust level | What you give up | What you gain |
|---|---|---|---|
| Plan mode | Low — you review before anything happens | Time (reading the plan) | Confidence the approach is right |
| Worktrees | Medium — edits happen but in isolation | Disk space, branch management | Ability to discard failed experiments |
| Sub-agents | High — parallel work with limited oversight | Tokens, coordination overhead | Speed on independent tasks |
The mistake is jumping to sub-agents for everything. Start with plan mode. Move to a worktree when you are confident in the approach but want isolation. Use sub-agents when you have genuinely independent work.
Limitations and when not to use each#
Plan mode limitations#
- Not persistent. The plan lives in the conversation. If the session ends, the plan is gone. For critical plans, copy them to a file or CLAUDE.md.
- Not binding. Claude can deviate from the plan during execution. It usually follows the plan, but edge cases or errors can cause drift. Review the results against the plan.
- Adds latency. For simple tasks, plan mode is overhead. “Fix the typo on line 42” does not need a plan.
Sub-agent limitations#
- No inter-agent communication. Sub-agents cannot talk to each other. If agent A discovers something agent B needs, the parent must relay it.
- No shared state. Each sub-agent starts with a fresh context. It does not know what other agents have done.
- Token cost. Three sub-agents cost three times the tokens. For exploratory work, this is fine. For routine tasks, it is wasteful.
- No guaranteed consistency. Two sub-agents editing the same file will create conflicts. Use worktrees or sequential execution for overlapping work.
Worktree limitations#
- One branch per worktree. You cannot have two worktrees on the same branch. Plan your branch names.
- Disk usage. Each worktree is a full copy of the working tree (though the .git objects are shared). On large repos, this can use significant disk space.
- Cleanup discipline. Forgotten worktrees accumulate. Run
git worktree listperiodically to see what is outstanding. - Not a substitute for proper branching. If you need three worktrees for three long-running features, you might want three terminals instead.
When to use none of them#
Most tasks. Genuinely. The 80% case is “edit this function, run the test, ship it” — plain mode, no sub-agents, no worktrees. The features above earn their keep on the 20% that are large, irreversible, or branching.
If you find yourself reaching for sub-agents and worktrees on every task, the more interesting question is whether you are making your tasks too big.

Quick reference#
| Situation | Use |
|---|---|
| Simple bug fix | Plain mode |
| Multi-file feature | Plan mode, then auto |
| Risky refactoring | Plan mode + worktree |
| Independent research | Sub-agent |
| Trying two approaches | Two worktrees |
| Large task with independent parts | Worktree + sub-agents |
| “Fix the typo on line 42” | Just let it do it |
Three trust gates, three escalations. By the time the model is editing files in a worktree with sub-agents, you have burned exactly the amount of attention the task deserves.
Claude Code Hands-On 10 parts
- 01 Claude Code Hands-On (1): Install, the Three-Layer Config, and the # @ /init Trio
- 02 Claude Code Hands-On (2): Shortcuts, the Four-State Toggle, and Thinking Modes
- 03 Claude Code Hands-On (3): Custom Slash Commands and Conversation Control
- 04 Claude Code Hands-On (4): MCP Servers, or How Claude Talks to Anything
- 05 Claude Code Hands-On (5): Hooks, or How to Stop Worrying About Yolo Mode
- 06 Claude Code Hands-On (6): The SDK, GitHub Integration, and Claude in CI
- 07 Claude Code Hands-On (7): Ten Hooks I Actually Use, with the Code
- 08 Claude Code Hands-On (8): Sub-Agents, Worktrees, and Plan Mode you are here
- 09 Claude Code Hands-On (9): settings.json, the Three-Layer Permission Model, and Env
- 10 Claude Code Hands-On (10): Skills, and When to Reach for Each Extension Mechanism