Introducing Switchboard
Back in April, I wrote about concurrent programming in the age of AI: the idea that once you stop treating a coding agent as a single assistant and start treating agents like a thread pool, your job shifts from executing to scheduling. Decompose the work, hand each piece to an agent in its own isolated workspace, then review and integrate the results.
That idea has held up. The tooling around it has shifted. In that post I was using Conductor to manage my workspaces. When it looked like Conductor wouldn't be able to support CLI passthrough, I moved over to emdash. But the more I switched tools, the clearer it got that what I really wanted was something that let me stay in the terminal.
I also needed a way to keep track of everything once the thread pool got big. So I built a tool for it, and today it's ready for other people to use. It's called Switchboard.
The scheduler needs a run queue
Running agents in parallel pays off, but past two or three you start to lose the thread. Which one finished? Which one is blocked on a permission prompt? Which one is still grinding through a refactor? Without a signal, you end up tabbing through every session just to check, which is exactly the kind of polling loop we'd never tolerate in a real system.
If I'm the scheduler, I need to see the run queue. That's what Switchboard is.
What it is
Switchboard is a keyboard-only switcher and creator for git-worktree
workspaces. It lives in a persistent tmux sidebar that shows every workspace
as a tree, grouped by project:
switchboard · home
──────────────────────────────────────────
▾ api
» ⠹ rate-limiter +56 −3 #485
● new-auth-flow +124 −18 #482
◆ retry-backoff +12 −0 draft
▾ web
● dark-mode +89 −44 #211
checkout-redesign +203 −9 #214
▸ infra
──────────────────────────────────────────
↑↓ move · ↵ open · ? help
Each row tells you what you need at a glance:
- An agent dot: blue when the agent is thinking, magenta when it's waiting on you, green when it's done.
- The diff against the base branch, so you can see how much work is sitting there.
- The PR number, color-coded by status.
When an agent finishes a turn, you hear a short chime and its name goes bold until you look at it. So if something lands while I'm heads-down in another workspace, it's still waiting for my eye when I come up for air.
Keyboard only, terminal native
Staying in the terminal was the whole point. No Electron, no mouse, no
database. Switchboard is pure Ruby with zero gem dependencies, and it
discovers worktrees straight from git, so anything you create just shows up.
There's nothing to sync.
The whole muscle memory fits in five keys:
| Key | Does |
|---|---|
a | add a project (a local repo or a clone URL) |
n | create a new worktree and branch |
↵ | switch to a workspace |
/ | filter to jump straight to a workspace |
? | show the full key map |
a to make a project, n to make work, ↵ to move between it.
A new workspace comes up already working
The best part is that a new workspace doesn't start as an empty shell. You tell Switchboard which agent to launch, and it starts it for you the first time it creates the session:
# ~/.config/switchboard/config.yml
session_command: claude --dangerously-skip-permissions
A fresh worktree is also missing all the untracked files your main checkout has
picked up over time: no .env, no node_modules. So there's a setup hook that
runs once in the new worktree, before the agent starts:
worktree_creation_command:
- cp "$SWITCHBOARD_PROJECT_PATH/.env" .
- bundle install
If any step fails, the agent never starts. You land at a shell with the error on screen, instead of an agent cheerfully working in a broken checkout.
Knowing what an agent is actually doing
The dot is the single most useful thing in the sidebar, and getting it right was the trickiest part of the project. A wrong signal is worse than no signal. If a blocked agent shows up as "working," you'll ignore the one workspace that actually needs you.
Switchboard hooks into the lifecycle events that Claude Code and Codex emit, so
it knows precisely when an agent starts thinking, when it stops, and when it's
sitting on a permission prompt. It also picks up agents running background
monitors or recurring loops, shown with a steady ∞, so "watching in the
background" doesn't get mistaken for "finished and abandoned." If one of those
quiet loops actually finds what it was watching for, it can raise its hand with
a distinct alert.
Try it
As of today, you can install it with Homebrew, which pulls in tmux, git, gh, and Ruby for you:
brew tap wvmitchell/switchboard
brew trust wvmitchell/switchboard
brew install switchboard
switchboard install
switchboard
switchboard install wires up tmux and writes a starter config, and
switchboard doctor will tell you if anything isn't hooked up right. From
there, prefix-s toggles the sidebar from any tmux pane.
The README and docs cover everything else, and contributions are welcome. I've been using Switchboard every day to build Switchboard (and this post was written in one of its workspaces). If you're running more than a couple of agents at once, I hope it helps you keep your head above the thread pool too.