← Blog
Oct 30, 2026

Orchestrating Claude Code across multiple repos with Gas Town

In a previous article I wrote about Beads, the git-backed issue tracker for AI coding agents. My Matrix project is split across several repositories, each with its own Beads database, and the repos are configured so that when one of them needs a change in another, the agent files a bead in the target repo and blocks on it.

That works well, but it leaves one manual step: someone has to open a Claude Code session in the other repo, work the ticket, and come back. With five or six repos, that “someone” spends the day juggling terminals.

Gas Town automates that step. It is a workspace manager, built by the author of Beads, that coordinates many Claude Code instances on top of your beads: a coordinator agent dispatches work, workers run inside the right repo with that repo’s CLAUDE.md, and blocked tickets get picked up as soon as their dependency closes.

This guide walks through the full setup. Everything was tested on macOS; Linux commands are given where they differ.

The vocabulary

Gas Town has a lot of its own terms. These are the ones you need:

TermWhat it is
TownThe workspace folder (e.g. ~/gt-matrix). One per project.
RigOne repository inside the town, with its own beads and agents.
CrewYour personal clone inside a rig, where you work by hand.
MayorThe coordinator: a Claude Code instance that sees every rig and dispatches work.
PolecatA worker agent spawned in a rig to complete one bead, in its own git worktree.
ConvoyA group of beads tracked together, usually one feature across several rigs.
RefineryA per-rig merge queue for polecat branches.
Witness / DeaconWatchdogs: per-rig and town-wide health monitoring.

In short: you talk to the Mayor, polecats do the work, the Refinery merges, the watchdogs keep things alive.

Prerequisites

Step 1: Install

On macOS, Homebrew installs gt, bd (Beads) and dolt (the database Beads uses) together:

brew install gastown

On Linux, install Dolt first, then:

go install github.com/steveyegge/gastown/cmd/gt@latest
go install github.com/steveyegge/beads/cmd/bd@latest

Check that everything is there:

gt --version
bd --version
tmux -V

If you already had Beads installed, run which -a bd to make sure only one bd is on your PATH.

Step 2: Create the town

gt install ~/gt-matrix --git
cd ~/gt-matrix
gt up
gt doctor --fix

If doctor reports a stale .claude/settings.json that it refuses to delete because it is tracked in git, untrack it and run doctor again:

git rm --cached .claude/settings.json
echo ".claude/settings.json" >> .gitignore
git commit -am "Untrack generated Claude settings"
gt doctor --fix
gt up --restore

There is also a --shell flag that installs a hook offering to add every git repo you cd into to the town. I recommend skipping it, especially if you plan to have more than one town.

Step 3: Add your repos as rigs

Each repo becomes a rig. gt rig add clones it into the town:

cd ~/gt-matrix
gt rig add matrix_api https://github.com/you/matrix-api.git \
  --prefix mapi \
  --local-repo ~/code/matrix-api

A few rules learned the hard way:

Check the result:

gt rig list

Step 4: Bring your existing beads

Gas Town stores every rig’s beads in its own Dolt server, not in the repo. If your old beads were local (not committed), the clone will not bring them. Export them from the old repo and import them into the rig:

cd ~/code/matrix-api
bd export -o /tmp/matrix-api.jsonl

cd ~/gt-matrix/matrix_api
bd import -i /tmp/matrix-api.jsonl
bd list | head

Check bd import --help on your version first. After the import, check one bead that depends on another repo (bd show <id>) to confirm the cross-repo links survived.

From now on, the rigs are the source of truth. Stop using the old clones, or you will end up with two diverging sets of tickets.

Step 5: Create your crew workspace

For hands-on work in a single repo, you still use a normal Claude Code session, just from your crew clone:

gt crew add sami --rig matrix_api
cd ~/gt-matrix/matrix_api/crew/sami
claude

It loads that repo’s CLAUDE.md and reads and writes the rig’s beads as usual. Crew names follow the same rule as rigs: no hyphens.

Step 6: Let the Mayor dispatch work

Attach to the Mayor:

cd ~/gt-matrix
gt mayor attach

Then describe what you want, or point it at existing beads. To group a feature across repos:

gt convoy create "Billing export" mapi-a1b mweb-c2d mwrk-e3f --notify

And tell the Mayor: “Work convoy Billing export: sling the ready beads to their rigs, and as each one closes, dispatch the beads it unblocks.”

That is the whole point of the tool: a polecat spawns in the right rig, works the bead, and when it closes, the blocked bead in another repo becomes ready and gets dispatched next. You can also dispatch a single bead yourself:

gt sling mapi-a1b matrix_api

Detach from the Mayor with Ctrl-b then d; it keeps working.

Watching what happens

gt agents          # who is running
gt convoy list     # progress per feature
gt feed            # live event stream
gt dashboard --port 8090

The dashboard is a web page at http://localhost:8090 showing polecats, convoys, the merge queue and escalations. Use localhost rather than 127.0.0.1 if your browser refuses the latter.

To ask the Mayor something without letting it act, attach and switch to plan mode (Shift+Tab), or send it mail:

gt mail send mayor -s "Status" -m "Which beads are in progress?"

Step 7: Pick a model per task

Define one agent alias per Claude model:

gt config agent set claude-haiku  "claude --dangerously-skip-permissions --model haiku"
gt config agent set claude-sonnet "claude --dangerously-skip-permissions --model sonnet"
gt config agent set claude-opus   "claude --dangerously-skip-permissions --model opus"
gt config default-agent claude-sonnet

Keep --dangerously-skip-permissions: polecats run unattended in tmux, and without it they stop at the first permission prompt with nobody to answer. Put your hard limits in a PreToolUse hook instead (see the next step).

Then let the Mayor choose. Write a policy file and reference it from the town CLAUDE.md:

cat > mayor/MODEL_POLICY.md <<'EOF'
# Model selection when slinging
Always pass --agent to gt sling:
- claude-haiku: docs, renames, config tweaks, small isolated changes
- claude-sonnet: normal features and bug fixes (default)
- claude-opus: migrations, auth/permissions, cross-repo contracts, or a bead that already failed once
Write the chosen agent and a one-line reason in the bead notes.
If a polecat fails or stalls, re-sling with the next model up.
EOF
printf "\n## Model selection\nFollow mayor/MODEL_POLICY.md whenever you sling work.\n" >> CLAUDE.md
git add mayor/MODEL_POLICY.md CLAUDE.md && git commit -m "Model selection policy"

Keeping the policy in its own file protects it from gt doctor --fix, which manages the town CLAUDE.md.

Step 8: Keep the agents in their lane

Agents that run unattended will happily make decisions for you. A few guardrails:

gt config set scheduler.max_polecats 2

Day to day

cd ~/gt-matrix && gt up      # start of day
gt down                      # end of day

Each rig runs a witness and a refinery that patrol continuously and query Dolt. With many rigs, that keeps the CPU busy even when nothing is happening. Stop the rigs you are not using:

gt rig stop matrix_admin matrix_docs

You do not lose anything: slinging to a stopped rig boots it automatically.

Tips and pitfalls

Is it worth it?

For a single repo, no: one Claude Code session is enough. Gas Town pays off when work regularly crosses repository boundaries and you want tickets to flow between repos without you opening every session.

It is also a young tool that moves fast, so treat it like infrastructure: pin versions, back up the town database, stop what you do not use, and keep a human in the merge loop. With that in place, the cross-repo ticket dance I used to do by hand now runs on its own.