Skip to content

Instantly share code, notes, and snippets.

@rafaelrinaldi
Last active March 31, 2026 20:45
Show Gist options
  • Select an option

  • Save rafaelrinaldi/898024d0dca557739ebcea2256e06041 to your computer and use it in GitHub Desktop.

Select an option

Save rafaelrinaldi/898024d0dca557739ebcea2256e06041 to your computer and use it in GitHub Desktop.
AI Agent Workflow: tmux + git worktrees + fish

AI Agent Workflow: tmux + git worktrees + fish

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.

Prerequisites

  • 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)

Installation

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.

Option A: Full dotfiles install (gets everything)

sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply rafaelrinaldi

This sets up fish, tmux, the agent functions, notifications, and all dependencies via Homebrew. See the repo's install.sh for the full bootstrap process.

Option B: Cherry-pick just the agent workflow

If you already have your own dotfiles and just want the agent tooling:

1. Install dependencies

brew install gum vjeantet/tap/alerter

2. Copy fish functions

Copy 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

3. Copy tmux scripts

mkdir -p ~/.config/tmux/scripts
# Copy from the repo's dot_config/tmux/scripts/:
#   cheatsheet.fish
#   agent-dashboard.fish
chmod +x ~/.config/tmux/scripts/*.fish

4. Add tmux keybindings

Add 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 -Z

5. Set up notifications (optional)

Copy 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.

Core concept

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.

The commands

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

aa — New agent session

  1. Prompts for a session name (pre-filled with current-session/ as prefix)
  2. Asks whether to use a git worktree or just check out a branch
  3. If worktree: creates .worktrees/<slug> inside the repo root with a new or existing branch
  4. If no worktree: checks out the branch in the current repo
  5. Opens a new tmux session at that path and launches claude inside it
  6. Switches you to the new session

af — Fork an agent session

Designed for when an agent's work needs to split into a separate direction:

  1. Lists all running agent sessions and lets you pick one to fork
  2. Detects the source session's working directory and current branch
  3. Finds the Claude Code session ID from the source (by inspecting process trees and session files)
  4. Creates a new worktree branching from the source's HEAD
  5. Copies the Claude conversation history into the new worktree's project directory
  6. Launches Claude with --resume <id> --fork-session so the new agent starts with full context from the original

al — Switch to agent

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.

ar — Kill agent sessions

Multi-select agent sessions to kill. Confirms before proceeding. Automatically removes any .worktrees/ directories associated with killed sessions via git worktree remove.

tmux integration

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

Notifications

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.

Worktree helpers (standalone)

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/)

Typical workflow

  1. Open your project in tmux
  2. aa to spin up an agent — give it a name like mobile/fix-login-bug, say yes to worktree
  3. The agent launches Claude Code in an isolated worktree on its own branch
  4. aa again for a second task — mobile/add-tests — another worktree, another branch
  5. Both agents work independently, no git conflicts
  6. A notification pops up: "Needs permission" — click Show or run al to jump to it
  7. When an agent finishes, ar to kill the session and clean up the worktree
  8. If mid-task you want to split an agent's work: af forks its conversation and worktree
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment