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:

ActionDoes
worktree_create:PATH[@branch]Add a worktree branched from HEAD and open it in a tab
worktree_open:PATHOpen an existing worktree in a tab
worktree_remove:PATHRemove 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.

Tip

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.

Where to next