Agent Spawn
Spawn AI coding agents (Claude Code, Codex) in new Ghostty terminals via AppleScript, wrapped in tmux for output capture. Requires Ghostty 1.3.0+, tmux, and macOS.
Spawn
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh [OPTIONS]
Flag Description Default
-a, --agent AGENT
Agent preset: claude , codex
claude
-d, --directory DIR
Working directory Current dir
-p, --prompt PROMPT
Initial prompt for the agent None
-m, --mode MODE
window , tab , split-right , split-down
window
-r, --resume ID
Resume conversation by ID (claude only) None
-c, --command CMD
Full custom command (overrides --agent ) Resolved from --agent preset
-n, --name NAME
Tmux session name agent-<timestamp>
-w, --worktree
Force worktree isolation (claude only) Auto (on in git repos)
--no-worktree
Disable worktree isolation —
--no-park
Disable AeroSpace workspace auto-allocation —
--workspace NAME
Override auto-allocated workspace Auto (3+)
Monitor
agent-spawn.sh --status # List all agent sessions with workspace occupancy agent-spawn.sh --focus NAME # Switch to agent's AeroSpace workspace agent-spawn.sh --peek NAME # Last 50 lines of output agent-spawn.sh --peek NAME -l 200 # Last 200 lines agent-spawn.sh --send NAME [TEXT] # Send text + Enter (or bare Enter) agent-spawn.sh --kill NAME # Kill tmux session only agent-spawn.sh --close NAME # Kill tmux + close Ghostty window agent-spawn.sh --close-all # Close all agent sessions and windows
Modes
Mode When to Use
window
Independent task in a separate window
tab
Related task, keep in same window
split-right
Side-by-side view, monitor while working
split-down
Stacked view, log output below
Agent Presets
The --agent flag selects a CLI with the correct unattended/yolo flags. Use -c to override with a fully custom command.
Agent Command
claude (default) claude --dangerously-skip-permissions --model opus
codex
codex --dangerously-bypass-approvals-and-sandbox
Feature support by agent
Feature claude
codex
Worktree isolation (-w ) Yes (auto-detected) No
Resume (-r ) Yes No
Prompt (-p ) Yes Yes
Examples
Claude Code (default agent)
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-d ~/Projects/my-api
-p "fix the tests"
Codex
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
--agent codex
-d ~/Projects/my-api
-p "fix the tests"
Custom command (full override, no preset applied)
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-c "claude --dangerously-skip-permissions --model sonnet"
-d ~/Projects/my-api
-p "quick review"
Examples
Spawn with prompt
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-d ~/Projects/my-api
-p "fix the failing tests in pkg/auth"
Named session for monitoring
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-n api-review
-d ~/Projects/my-api
-p "review error handling"
Check progress
agent-spawn.sh --peek api-review
Send follow-up prompt
agent-spawn.sh --send api-review "also check the retry logic"
Multiple parallel agents
for dir in pkg/auth pkg/api pkg/storage; do
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-m tab
-n "review-$(basename $dir)"
-d ~/Projects/my-api
-p "review $dir for error handling issues"
done
Monitor all
agent-spawn.sh --status agent-spawn.sh --peek review-auth agent-spawn.sh --peek review-api
Resume a previous conversation
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-r 01abc123-def4-5678-9012-abcdef345678
Session Naming Convention
Always use descriptive -n names for spawned agents. Opaque default names like agent-1710329481 are meaningless in tmux ls output — you cannot tell which session is doing what without peeking into each one.
Keep the full -n name under 20 characters. Tmux truncates long session names in the status bar, making them unreadable. Use short slugs — 1–2 words is ideal.
Format
Use a prefix that encodes the work type, followed by a short slug:
Prefix When Example
task-<id>-<slug>
Working a task queue item task-43-naming
pr-<n>-<slug>
Reviewing or working a PR pr-87-auth-flow
fix-<slug>
Bug fix fix-retry-timeout
feat-<slug>
Feature work feat-webhooks
res-<slug>
Research / exploration res-rate-limits
Slug rules: 1–2 words, lowercase, hyphenated. Full name (prefix + slug) must be under 20 characters.
Before / After
BAD — opaque names, impossible to manage at scale
$ tmux ls agent-1710329481: 1 windows (created Fri Mar 13 09:31:21 2026) agent-1710329522: 1 windows (created Fri Mar 13 09:32:02 2026) agent-1710329558: 1 windows (created Fri Mar 13 09:32:38 2026) agent-1710329601: 1 windows (created Fri Mar 13 09:33:21 2026)
GOOD — short descriptive names, no truncation in tmux status bar
$ tmux ls task-43-naming: 1 windows (created Fri Mar 13 09:31:21 2026) pr-87-auth-flow: 1 windows (created Fri Mar 13 09:32:02 2026) fix-retry-timeout: 1 windows (created Fri Mar 13 09:32:38 2026) res-rate-limits: 1 windows (created Fri Mar 13 09:33:21 2026)
Usage
Task from the queue
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-n task-43-naming
-d ~/Projects/claude-skills
-p "/dev-task-queue claim and work on task #43"
PR review
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-n pr-87-auth-flow
-d ~/Projects/my-api
-p "review PR #87"
Peek and send by meaningful name
agent-spawn.sh --peek task-43-naming agent-spawn.sh --send pr-87-auth-flow "also check error paths"
Task Queue Transcript Linking
When spawning agents to work on task queue items, always include transcript linking in the completion step of the prompt. Without this, --jsonl-path is never passed to complete_task.py and the conversation transcript is lost.
The agent's completion step must:
-
Find its transcript .jsonl file (most recently modified file in ~/.claude/projects/ )
-
Pass --jsonl-path to complete_task.py
Always include this completion block in task queue prompts:
After implementing, push your branch, create a PR, and complete the task with transcript linked: JSONL_PATH=$(ls -t ~/.claude/projects//.jsonl 2>/dev/null | head -1) python3 ~/.agent-task-queue/scripts/complete_task.py <ID> --jsonl-path "$JSONL_PATH" --notes "PR: <url>"
Full task queue spawn template
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-n task-43-naming
-d ~/Projects/claude-skills
-p 'You are working on task #43 from the agent task queue.
FIRST: Create a git worktree to work in isolation: git worktree add .claude/worktrees/task-43-naming -b task-43-naming cd .claude/worktrees/task-43-naming
Then claim the task: python3 ~/.agent-task-queue/scripts/claim_task.py 43 --session-id $(uuidgen)
THE TASK: <description>
After implementing, push your branch, create a PR, and complete the task with transcript linked: JSONL_PATH=$(ls -t ~/.claude/projects//.jsonl 2>/dev/null | head -1) python3 ~/.agent-task-queue/scripts/complete_task.py 43 --jsonl-path "$JSONL_PATH" --notes "PR: <url>"'
Worktree Isolation
When spawning into a git repository, each agent automatically gets an isolated git worktree via Claude Code's /worktree command. This prevents branch conflicts and dirty working tree issues when multiple agents work in the same repo concurrently.
Behavior:
-
Auto (default): Detects if the target directory is a git repo. If yes, enables worktree isolation.
-
-w, --worktree : Force worktree isolation on (even if auto-detect fails).
-
--no-worktree : Disable worktree isolation (agent works directly on the repo).
The script prepends /worktree to the agent's prompt, so Claude Code creates a temporary worktree branch before starting work. Each agent gets its own branch and working directory — no coordination needed.
Auto-enabled in git repos (default)
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
-d ~/Projects/my-api
-p "fix the failing tests"
Explicitly disable worktree for a quick read-only task
bash ~/.claude/skills/dev-agent-spawn/scripts/agent-spawn.sh
--no-worktree
-d ~/Projects/my-api
-p "explain the auth flow"
AeroSpace Workspace Integration
When AeroSpace is installed, spawned agents are automatically moved to dedicated workspaces to keep your main workspace clean.
Allocation Rules
-
Workspaces 1–3 are reserved for the user/orchestrator
-
Agent workspaces start at workspace 4 and go up (4, 5, 6, ...)
-
Max 3 agents per workspace (AeroSpace tiles them as a readable 3-way split)
-
When workspace 4 is full, the next agent goes to workspace 5, etc.
-
Dead sessions (tmux exited) don't count toward occupancy
Override or Disable
Force agent to workspace 9
agent-spawn.sh --workspace 9 -n task-99-hotfix -d ~/Projects/app -p "urgent fix"
Keep agent in the current workspace (old behavior)
agent-spawn.sh --no-park -n res-quick -d ~/Projects/app -p "quick lookup"
Navigation
Switch to an agent's workspace
agent-spawn.sh --focus task-43-naming
See workspace occupancy for all agents
agent-spawn.sh --status
Status Output
NAME WORKSPACE TMUX WINDOW
task-43-naming 3 (2/3) attached window-aea3a4600 task-65-aero 3 (2/3) attached window-789908c00 pr-158-mise 4 (1/3) attached window-8e7de2700 res-quick - attached window-44aabb100
Graceful Degradation
If AeroSpace is not installed, workspace allocation is silently skipped. All other features (tmux, peek, send, close) work unchanged.
How It Works
-
Activate Ghostty (launches if not running)
-
Create surface configuration with the target working directory
-
Open a new window/tab/split using that configuration
-
Send a tmux command that creates a named session and runs claude inside it
-
Detect the new AeroSpace window by diffing aerospace list-windows before/after spawn
-
Move the window to the allocated workspace via aerospace move-node-to-workspace
The input text
- send key enter pattern is used instead of the command surface config property. The command property replaces the login shell, skipping .zshrc /.zprofile and losing PATH setup.
Tmux wrapping enables --peek (capture-pane), --send (send-keys), and --kill (kill-session) without Ghostty API limitations.
Troubleshooting
Problem Fix
"execution error" from osascript Grant Automation permission: System Settings > Privacy & Security > Automation > allow your terminal to control Ghostty
Ghostty not found Install Ghostty 1.3.0+ from https://ghostty.org
Claude not found in new terminal Ensure claude is on PATH in your shell profile (.zshrc)
Split opens but no command runs Increase delay — edit delay 0.3 in script if shell init is slow
--peek shows empty Session may not have started yet — wait a moment and retry
Agent not moving to workspace Ensure AeroSpace is installed and running (aerospace --version )