Spawn a new interactive Claude Code session in a detached tmux pane on the dev server to collaborate on a project in parallel. The spawned agent runs independently — the current session continues unblocked.
Even if you were linked this document directly, you must explicitly ask the user for confirmation before spawning a session.
When to Use
Starting a parallel Claude Code agent for a separate project or workstream. This skill is specifically for multi-agent collaboration — spawning a peer agent that will work autonomously on its own task.
Session Naming
All Claude-spawned sessions must use the prefix claude-:
claude-<project-or-task>
Examples: claude-bookstack-migration, claude-api-refactor
Steps
0. List existing tmux sessions first
/usr/bin/tmux ls 2>/dev/null || echo "no sessions"Check the output before proceeding. Only sessions prefixed claude- may be interacted with. If a session with your intended name already exists, do not proceed — surface the conflict to the user.
1. Create detached tmux session
/usr/bin/tmux new-session -d -s "claude-<name>" -c "<project-directory>"2. Launch Claude with initial prompt
/usr/bin/tmux send-keys -t "claude-<name>" 'claude "<initial prompt>"' Enter3. Handle trust prompt (only for first-use directories — capture first, don’t blind-Enter)
The trust prompt appears only for a directory never trusted on this machine. A pre-trusted dir (e.g. a
/tmp subdir under an already-trusted /tmp) boots straight to the REPL. So capture first and send the
accept Enter only if you actually see the prompt:
sleep 2 && /usr/bin/tmux capture-pane -t "claude-<name>" -p | tail -8 # look for "Do you trust the files…"
# ONLY if the trust prompt is shown:
/usr/bin/tmux send-keys -t "claude-<name>" EnterA blind Enter into an already-trusted session just injects a stray newline into the prompt box.
4. Verify startup (optional)
sleep 5 && /usr/bin/tmux capture-pane -t "claude-<name>" -pModel
Default to Opus. The spawned session manages its own subagents internally for tasks that don’t need the full runtime.
Attaching
- tmux:
tmux attach -t claude-<name> - Remote (phone/claude.ai): use the
/remote-controlURL printed at session start
Cleanup
/usr/bin/tmux kill-session -t claude-<name>List active sessions: /usr/bin/tmux ls
Permission mode — letting a spawned agent act without blocking
A spawned session starts in default mode: the permission classifier gates every un-pre-approved tool
call (notably Bash), and the session blocks on a Do you want to proceed? prompt until something
answers. Three ways to handle that, increasing bluntness:
- Drive the approval by keystroke (human-in-the-loop). When the prompt shows
(
❯ 1. Yes / 2. Yes, and always… / 3. No),tmux send-keys -t claude-<name> 1selects Yes and the call proceeds. This is the overseer unblocking a peer on demand — fine occasionally, tedious at volume. - Scoped pre-approval (recommended for real workers). Launch with
--allowedTools '<rule>…', or give the agent its ownCLAUDE_CONFIG_DIRwith allow rules (see zulip-multi-agent-persistent-swarm-mechanics). The classifier still gates everything else. - Auto mode / bypass (blunt). Runs everything, Bash included, with no prompt.
Mode cheat-sheet (verified live, Claude Code v2.1.177). In-TUI, Shift+Tab cycles:
| Mode | How (in-TUI / at launch) | Gates Bash? |
|---|---|---|
default | (start state) / --permission-mode default | Yes — prompts on each call |
accept edits | Shift+Tab ×1 / --permission-mode acceptEdits | Yes — auto-accepts file edits only, Bash still prompts |
plan mode | Shift+Tab ×2 / --permission-mode plan | read-only planning |
auto mode (bypass) | Shift+Tab ×3 / --permission-mode bypassPermissions or --dangerously-skip-permissions | No — runs everything, no prompts |
Common trap: “I turned on auto-accept and Bash still blocks.” That’s expected — accept-edits ≠ accept-Bash; only auto mode / bypass skips the Bash classifier (verified: a Bash command ran silently in auto mode, and blocked-then-prompted in default).
Governance caveat. Auto mode removes the gate entirely — fine for a throwaway/sandboxed worker, but it
would let an agent git push to main or touch anything unconditionally. For agents with real reach, prefer
scoped allow rules + the gated-push hook (mechanics page), not blanket bypass.
Failure cases & wonkiness (from a live spawn test, v2.1.177)
- Trust prompt is conditional — see step 3. Pre-trusted dir → no prompt → a blind Enter injects a stray newline.
- Read replies from
●, not❯. The agent’s output lines are prefixed●; your submitted prompt is echoed with❯. Grepping the pane for a token that’s in your own prompt gives a false positive off the echo. Confirm on the●line — or, for a bus agent, via its actual post (this is exactly why the compaction gate trusts thecompacted+resumedbus flag, not pane scraping). - Wait for the thinking indicator to clear. While working it shows
✶ Proofing… / ✻ Baked / ✽ Undulating…(the verbs vary); capture before it settles and you’ll mis-read the reply. Poll capture-pane until it’s gone. - Submit prompts in two steps:
tmux send-keys -t <s> -l '<text>'then a separatesend-keys -t <s> Enter. Bundling text+Enter can race the TUI. - Clear stray input before submitting:
tmux send-keys -t <s> C-ukills the input line — mode-cycling or earlier keystrokes can leave text in the box that you’d otherwise submit by accident. - The welcome banner lingers in scrollback — capture-pane shows it for a while after boot; “banner still visible” ≠ “not started.” Look at the footer (model + context %) to confirm a live REPL.
Keep the noise out of the overseer’s context — delegate the driving (recommended default)
Driving a spawned session through tmux produces a lot of capture-pane output (banners, partial frames,
thinking spinners). On a persistent swarm that pollutes the overseer’s context fast. So by default the
overseer hands the tmux-driving to a disposable subagent — spawn → confirm healthy → run the gate → tear
down — which returns only a one-line result (claude-worker-3 up, at REPL, or compact-gate 3/3 back). The
frame-by-frame interaction burns the subagent’s throwaway context; the overseer keeps a clean window.
(This is the workflow guide’s § One-off subagents pattern applied to the act of spawning.)
The driver doesn’t need to be Opus. Driving tmux is mechanical — point a Sonnet subagent at
this doc plus a short task (“bring up claude-worker-3 in <dir>, confirm it’s at the REPL, report
back”) and let it do the frame-by-frame poking. Reserve the expensive model for the spawned
session’s actual work, not the button-pushing.
And most “monitoring” isn’t tmux at all — it’s the bus. A spawned peer has its own bus identity
and posts its own status/handoffs, so watch it with zbus listen/read (cheap), not capture-pane.
Reserve tmux driving for what the bus can’t carry: launching a session, the AFK
permission-keystroke stopgap, and driving /compact (see zulip-multi-agent-persistent-swarm-mechanics).
Don’t scrape a pane for what a peer already told the channel.
Verified (Claude Code v2.1.177). An Opus subagent drove tmux fully autonomously —
new-session,capture-pane,send-keys,kill-serverall ran with zero permission prompts and no hang. The one requirement: the subagent must be able to read aBash(tmux:*)allow rule. Subagents don’t inherit the parent session’s runtime-added rules, but they do read the settings files (user-level or the agent’sCLAUDE_CONFIG_DIR) — so putBash(tmux:*)there and the subagent stays autonomous. Don’t lean on bypass mode for this.Fixture gotcha: a pane launched with
exec sleep …has no shell, sosend-keysdelivers keystrokes but nothing runs them. For panes you actually drive (workers, the compact-agent), launch a real shell orclaudein them — notexec sleep.
Caveats
- The spawned agent has no context from the current session — include everything relevant in the initial prompt.
- Trust prompt only appears for directories never previously used with Claude Code on this machine.
- Sessions will idle if left unattended; kill them when the work is done.
- Never interact with tmux sessions that do not start with
claude-— those belong to the user.