Skip to main content
  1. Posts/

Running Several AI Coding Agents Without Losing Track

··867 words·5 mins·
Nick Liu
Author
Nick Liu
Building infrastructure for Facebook Feed Ranking at Meta. Previously at Walmart, Twitter, AWS, and eBay. MS in Computer Science at Georgia Tech.
Table of Contents
Taming Claude Code Sessions - This article is part of a series.
Part 4: This Article
Once you're comfortable with AI coding agents, you start running several at once: one refactoring here, one writing tests there, one stuck waiting for your approval. Keeping them straight is its own little skill.
Tested with Claude Code 2.1.x Β· macOS / Linux

Here are two ways to do it: a lightweight tmux plugin, and (briefly) dedicated “AI terminal” apps.

Option A: a tmux plugin (lightweight, works over SSH)
#

tmux-claude-session-manager adds two keystrokes to tmux:

  • prefix + y: launch (or jump back to) a Claude session for the current folder.
  • prefix + u: open a searchable picker of your live Claude sessions, showing each one’s status (πŸ”΄ working / 🟑 waiting for you / 🟒 idle) plus a live preview, with the ones needing attention sorted to the top.

It uses fzf (a fast fuzzy finder) for the picker, so you just start typing to filter.

Installing it (with TPM)
#

Most people manage tmux plugins with TPM, the Tmux Plugin Manager. If you don’t have it yet:

git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

…and add this near the bottom of ~/.tmux.conf (it must come before the TPM run line):

run '~/.tmux/plugins/tpm/tpm'

Now add the plugin. Put this line above that run line:

set -g @plugin 'craftzdog/tmux-claude-session-manager'

Reload tmux (prefix + r or tmux source-file ~/.tmux.conf), then press prefix + I (capital i) to install. Done. prefix + y and prefix + u now work. You’ll also need fzf installed (brew install fzf).

Making the status dots light up
#

The picker can show working/waiting/idle, but it needs to know the state. It learns this from Claude Code hooks (we met hooks in Part 2). The plugin ships a tiny script, scripts/state.sh, that you wire into a few hook events in ~/.claude/settings.json:

{
  "hooks": {
    "UserPromptSubmit": [
      { "matcher": "", "hooks": [ { "type": "command",
        "command": "~/.tmux/plugins/tmux-claude-session-manager/scripts/state.sh working" } ] }
    ],
    "Notification": [
      { "matcher": "permission_prompt", "hooks": [ { "type": "command",
        "command": "~/.tmux/plugins/tmux-claude-session-manager/scripts/state.sh waiting" } ] }
    ],
    "Stop": [
      { "matcher": "", "hooks": [ { "type": "command",
        "command": "~/.tmux/plugins/tmux-claude-session-manager/scripts/state.sh idle" } ] }
    ]
  }
}

(Merge these into any hooks you already have rather than replacing the whole block.) Translation: “when I submit a prompt β†’ mark working; when Claude asks permission β†’ waiting; when it stops β†’ idle.” Now the dots are live. The three hook events drive a simple state machine:

UserPromptSubmit

Notification
(permission_prompt)

you approve

Stop

UserPromptSubmit

working

waiting

idle

πŸ”΄ running

🟑 needs you

🟒 done

UserPromptSubmit

Notification
(permission_prompt)

you approve

Stop

UserPromptSubmit

working

waiting

idle

πŸ”΄ running

🟑 needs you

🟒 done

Heads-up on hooks and trust. You’re telling Claude Code to run a third-party script on its lifecycle events. Read state.sh first (it’s short; it just records a status into a tmux variable). Only wire in hooks you understand and trust.

Why this is great for remote servers
#

If you SSH into a remote machine and run Claude in tmux there, this plugin runs on that machine, so your picker and status work on the remote too. That’s a big deal: GUI-based managers on your laptop can’t see what’s happening inside an SSH session, but a tmux plugin lives right where the agents do.

Option B: a dedicated “AI terminal” app
#

There’s a newer category of macOS apps built specifically for running many agents in parallel, with sidebars showing each agent’s status, git branch, and so on. Two popular ones:

  • cmux: a native macOS terminal for parallel AI agents (vertical tabs, per-pane notifications). Unrelated to tmux despite the name.
  • Supacode: a terminal “command center” (built on Ghostty’s engine) that runs each agent in its own isolated git worktree, with GitHub integration for opening PRs and reviewing CI checks.

These are slick and worth a look if you do a lot of local, parallel, many-agents-on-one-repo work.

tmux vs. a dedicated app: how to choose
#

If you…Lean toward
Mostly work on remote servers over SSHtmux (the app can’t reach remote agents)
Already love tmux + your shell setuptmux (keep your muscle memory)
Want sessions to survive disconnectstmux (built-in; reattach any time)
Do bursts of 3+ local agents on one repoa dedicated app can shine
Want zero terminal config, a GUI sidebara dedicated app

There’s no wrong answer, and they’re not exclusive. You can keep tmux as home base and trial a dedicated app for heavy local days. For my own SSH-heavy workflow, staying in tmux won out.

The whole series, in one breath
#

  1. Part 1: Find them

    1 / 4

    Sessions live in ~/.claude/projects; find them with claude -r β†’ Ctrl+A. Read β†’
  2. Part 2: Name them

    2 / 4

    A SessionStart hook auto-names sessions so search actually works. Read β†’
  3. Part 3: Label tmux

    3 / 4

    A shell wrapper + set-titles label your tmux window and terminal tab. Read β†’
  4. Part 4: Juggle many

    4 / 4

    A tmux plugin (or a dedicated app) helps you manage many live agents. (this post)

Put together, you go from “where did that conversation go?” to “type three letters, hit Enter, back in business.” Happy hacking.

Taming Claude Code Sessions - This article is part of a series.
Part 4: This Article

Related

Running six agents made tab patrol my biggest time sink. So: a herdr trial.

Once I had six Claude Code sessions open at once, the most expensive part of my workflow was not writing code. It was patrol: cycling through tabs to see which agent was still running and which one had been sitting on a question for ten minutes. tmux has no concept of any of this. To tmux, every pane is a rectangle of terminal, equally interesting, equally mute. herdr’s pitch lands exactly on that pain: panes are still real terminals, but a sidebar shows each agent’s live state. So it got a one-month trial, with exit conditions written down before it started. The verdict lands on August 16, and this post is honest about still being inside the window.

Git worktrees gave each Claude agent its own sandbox. And scattered my sessions.

··978 words·5 mins
I run four or more Claude Code agents at once, and until recently they all shared one working tree. Two agents editing the same repo means one of them eventually builds against the other's half-finished changes. Git worktrees fix that cleanly. What nobody warned me about is that the fix multiplies a different problem I already had: forgetting which folder a session lives in. Taming Claude Code Sessions Β· Part 5 of 6 1 2 3 4 5 6 πŸ§ͺ Tested with Claude Code 2.1.x Β· macOS The symptom # With several agents in one directory, the working tree is shared mutable state. Agent A refactors a partial, agent B runs the build, and B’s “failure” is really A’s work in flight. I had been dodging this by scoping agents to different subdirectories, which works until it does not.

Four review claims sounded right. Each took two minutes to disprove.

··1323 words·7 mins
After a month of overhauling my dotfiles with AI in the loop, the real value was not "the AI writes my configs". It was two much more boring properties: the research side keeps finding things I cannot see, and I verify every claim it makes before acting. Skip the first and you only ever fix problems you already knew about. Skip the second and a plausible-sounding wrong answer walks you into a ditch. The loop # claim fails verification