Tutorial
Parallel agents in git worktrees
Running two coding agents in the same checkout is a recipe for collisions —
they overwrite each other's edits, trip over a half-finished change, and fight
the same git index. A git worktree fixes that: each
agent gets its own directory on its own branch, backed by the same repo. This
walkthrough gives three agents three isolated worktrees, launches one into each,
and lets you watch all of them finish — then merges and cleans up.
This builds on Run your first agent team — have
the relay enabled and an agent CLI installed. Worktrees themselves are plain
git, so nothing here is Sinclair-specific except how smoothly it wires
them into tabs.
1. Why a worktree per agent
git worktree lets one repository have several working directories
checked out at once, each on a different branch, all sharing the same object store
and history. Give frontend a worktree on feat/toggle-ui
and backend one on feat/prefs-api, and they can build,
test, and commit fully in parallel — no stashing, no waiting, no stepped-on files.
When each is done you merge its branch like any other.
2. Create a worktree
From a pane inside your repo, worktree_create:PATH runs
git worktree add branched from HEAD and opens the new
checkout in a fresh tab, already cd'd into it. Append
@branch to name the branch (otherwise the path's basename is used):
# action string — bind a fixed worktree to a key in your config
keybind = cmd+ctrl+w=worktree_create:../wt/toggle-ui@feat/toggle-ui
The companion verbs round out the lifecycle:
| Action | Does |
|---|---|
worktree_create:PATH[@branch] | Add a worktree branched from HEAD and open it in a tab |
worktree_open:PATH | Open an existing worktree in a tab |
worktree_remove:PATH | Remove a worktree (git worktree remove) |
You can bind a fixed scratch worktree to a key in your config, but the real value is dynamic paths — which is exactly what the next step does from an agent.
3. Let the agents branch themselves
The same four verbs are exposed over MCP and the single-instance socket, so an
agent driving your terminal can spin up its own isolated checkout. The MCP tools
are worktree_create (path, optional branch),
worktree_open, worktree_list, and
worktree_remove. So your supervisor can set the whole thing up in one
instruction:
For each of these tasks, create a git worktree on its own branch and open it,
then hand the task to the matching worker:
- frontend → feat/toggle-ui (dark-mode toggle UI)
- backend → feat/prefs-api (theme preference endpoint)
- reviewer → review/toggle (review both branches when they land)
The supervisor calls worktree_create three times, each opening a tab
rooted in a clean branch, then delegates over the bus. Each worker now edits,
commits, and tests entirely inside its own worktree.
4. Automate the setup with a trigger
A fresh worktree often needs the same one-time prep — install dependencies, warm a
build, copy a .env. Creating (or removing) a worktree fires the
worktree_created / worktree_removed
plugin triggers, with the worktree path as the cwd, so a
tiny plugin can do it for you:
# plugins/wtsetup/plugin.toml
id = "wtsetup"
name = "Worktree setup"
[[trigger]]
on = "worktree_created"
run = "bun install" # runs in the new worktree's directory
Now every worktree an agent (or you) creates lands ready to build. Filter with
when = "…" on a path substring if you only want it for some worktrees.
5. Watch them all at once
Three agents in three tabs is exactly where Sinclair's status dots earn their keep. Each tab carries a colored dot — 🟡 working, 🔴 blocked, 🔵 done, 🟢 idle — and the Activity sidebar rolls them all up into a single "who's blocked, working, or done" glance. You don't have to click through panes to know the backend agent finished and the reviewer is waiting on you. Wire it up with the Agent status tutorial.
On the mesh, the reviewer can call wait_status to park until both
frontend and backend report done — so it
reviews exactly once, when both branches are actually ready, instead of polling.
6. Merge and clean up
When a branch is ready, merge it from your main checkout like any other feature branch, then remove the worktree — from the pane, over MCP, or on the command line:
# in your primary checkout
git merge feat/toggle-ui
git merge feat/prefs-api
# then retire the worktrees (also: worktree_remove:PATH, or the MCP verb)
git worktree remove ../wt/toggle-ui
git worktree remove ../wt/prefs-api
Removing a worktree fires worktree_removed, so the same plugin pattern
can tear down anything the setup trigger created.
The pattern in one line
One worktree per agent, one tab per worktree, one dot per tab. Isolated branches keep the agents from colliding; tabs keep them visible; status dots keep them legible. That's how you scale from one agent to a bench of them without losing the plot.