A terminal-first workflow for running multiple AI coding agents (Claude Code, Cursor) in parallel, each isolated in its own tmux session and git worktree. Agents get macOS notifications when they need attention, and you can switch between them instantly.
- fish shell — primary shell
- tmux — session/window/pane multiplexer
- gum — interactive prompts and fuzzy filtering (charmbracelet/gum)
- alerter — macOS native notifications from the terminal
- Claude Code — AI coding agent (CLI)
This workflow is part of a chezmoi-managed dotfiles repo. You have two options: install the full dotfiles, or cherry-pick just the agent workflow files.
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply rafaelrinaldiThis sets up fish, tmux, the agent functions, notifications, and all dependencies via Homebrew. See the repo's install.sh for the full bootstrap process.
If you already have your own dotfiles and just want the agent tooling:
brew install gum vjeantet/tap/alerterCopy these files into ~/.config/fish/functions/:
| File | Purpose |
|---|---|
a.fish |
Agent dashboard menu |
aa.fish |
Create new agent session |
af.fish |
Fork agent session |
al.fish |
Switch to running agent |
ar.fish |
Kill agent sessions + cleanup |
_is_agent_session.fish |
Helper: detects agent sessions by / in name |
_claude_count.fish |
Helper: counts agents in current tmux session |
gwl.fish |
List/navigate worktrees (optional) |
gwn.fish |
Create new worktree (optional) |
Grab them from the dotfiles repo's dot_config/fish/functions/:
https://github.com/rafaelrinaldi/dotfiles
mkdir -p ~/.config/tmux/scripts
# Copy from the repo's dot_config/tmux/scripts/:
# cheatsheet.fish
# agent-dashboard.fish
chmod +x ~/.config/tmux/scripts/*.fishAdd to your ~/.tmux.conf:
# Agent dashboard popup
bind-key a display-popup -E -w 100 -h 60% -b double "fish -c a"
# Cheatsheet popup (tmux + agent shortcuts)
bind-key ? display-popup -E -w 52 -h 60% -b double \
"rm -f /tmp/tmux-cheatsheet-cmd && ~/.config/tmux/scripts/cheatsheet.fish && test -f /tmp/tmux-cheatsheet-cmd && tmux source-file /tmp/tmux-cheatsheet-cmd"
# Home key toggles zoom (handy for fullscreening an agent pane)
bind-key -n Home resize-pane -ZCopy dot_config/agent-notify/notify.sh to ~/.config/agent-notify/notify.sh and make it executable.
Then add the hook to ~/.claude/settings.json:
{
"hooks": {
"Notification": [
{
"type": "command",
"command": "AGENT_SOURCE=claude ~/.config/agent-notify/notify.sh"
}
]
}
}This sends a macOS notification whenever Claude Code needs input. Clicking "Show" switches tmux to the right pane.
Each agent task runs in a dedicated tmux session with a hierarchical name like project/task-name. The / in the name is what marks it as an "agent session" — all the tooling keys off that convention.
Each agent session can optionally get its own git worktree, so agents work on separate branches without stepping on each other or your manual work.
| Command | What it does |
|---|---|
a |
Opens the agent dashboard (interactive menu for all commands below) |
aa |
Create a new agent session |
af |
Fork an existing agent session into a new branch/worktree |
al |
Fuzzy-find and switch to any running agent |
ar |
Kill agent sessions and clean up their worktrees |
- Prompts for a session name (pre-filled with
current-session/as prefix) - Asks whether to use a git worktree or just check out a branch
- If worktree: creates
.worktrees/<slug>inside the repo root with a new or existing branch - If no worktree: checks out the branch in the current repo
- Opens a new tmux session at that path and launches
claudeinside it - Switches you to the new session
Designed for when an agent's work needs to split into a separate direction:
- Lists all running agent sessions and lets you pick one to fork
- Detects the source session's working directory and current branch
- Finds the Claude Code session ID from the source (by inspecting process trees and session files)
- Creates a new worktree branching from the source's HEAD
- Copies the Claude conversation history into the new worktree's project directory
- Launches Claude with
--resume <id> --fork-sessionso the new agent starts with full context from the original
Finds every running claude (and cursor-agent) process, walks up each process tree to find which tmux pane owns it, then presents a fuzzy-filterable list showing:
SESSION SUMMARY ACTIVE
project/auth-fix Refactor auth middleware 2m
project/api-tests Add integration tests for /users endpoint now
- SESSION — the tmux session name
- SUMMARY — pulled from Claude Code's pane title (it sets this to a summary of the current task)
- ACTIVE — how long ago the session was last active
Pick one and you're switched to it instantly.
Multi-select agent sessions to kill. Confirms before proceeding. Automatically removes any .worktrees/ directories associated with killed sessions via git worktree remove.
The tmux config (Ctrl-a prefix) adds these bindings:
| Key | Action |
|---|---|
Prefix + a |
Opens the agent dashboard as a tmux popup |
Prefix + ? |
Opens a searchable cheatsheet (tmux + agent shortcuts) as a popup |
Home |
Toggle zoom on the current pane (fullscreen an agent) |
The agent dashboard popup is a minimal single-keypress menu:
Agent Dashboard
a New agent session
l Switch to agent
r Kill agent sessions
q Close
When an agent needs input (permission prompt, question, idle), a macOS notification appears via alerter:
- Title: the agent's task summary (from Claude Code's pane title)
- Subtitle: first user message from the conversation (truncated to 80 chars)
- Message: what the agent needs ("Needs permission", "Waiting for input", "Has a question")
- Sound: "Pop"
Clicking Show focuses WezTerm and switches tmux to the correct session, window, and pane — even if you've navigated away.
This is configured via Claude Code's built-in hooks.Notification in ~/.claude/settings.json, which calls ~/.config/agent-notify/notify.sh.
Two extra commands for manual worktree use outside of agent sessions:
| Command | What it does |
|---|---|
gwl |
List all git worktrees, fuzzy-select one, and cd into it |
gwn |
Create a new worktree as a sibling directory (e.g. repo-feature-name/) |
- Open your project in tmux
aato spin up an agent — give it a name likemobile/fix-login-bug, say yes to worktree- The agent launches Claude Code in an isolated worktree on its own branch
aaagain for a second task —mobile/add-tests— another worktree, another branch- Both agents work independently, no git conflicts
- A notification pops up: "Needs permission" — click Show or run
alto jump to it - When an agent finishes,
arto kill the session and clean up the worktree - If mid-task you want to split an agent's work:
afforks its conversation and worktree