Dans un précédent article, j’ai parlé de Beads, le gestionnaire de tickets adossé à git pour les agents de code IA. Mon projet Matrix est réparti sur plusieurs dépôts, chacun avec sa propre base Beads, et les dépôts sont configurés pour que, lorsque l’un d’eux a besoin d’une modification dans un autre, l’agent crée un bead dans le dépôt cible et se bloque dessus.
Ça marche bien, mais il reste une étape manuelle : quelqu’un doit ouvrir une session Claude Code dans l’autre dépôt, traiter le ticket, puis revenir. Avec cinq ou six dépôts, ce « quelqu’un » passe sa journée à jongler entre les terminaux.
Gas Town automatise cette étape. C’est un gestionnaire d’espace de travail, créé par l’auteur de Beads, qui coordonne plusieurs instances de Claude Code au-dessus de vos beads : un agent coordinateur répartit le travail, des workers tournent dans le bon dépôt avec le CLAUDE.md de ce dépôt, et les tickets bloqués sont repris dès que leur dépendance est fermée.
Ce guide parcourt l’installation complète. Tout a été testé sur macOS ; les commandes Linux sont indiquées quand elles diffèrent.
Le vocabulaire
Gas Town a beaucoup de termes à lui. Voici ceux dont vous avez besoin :
| Terme | Ce que c’est |
|---|---|
| Town | Le dossier de l’espace de travail (par ex. ~/gt-matrix). Un par projet. |
| Rig | Un dépôt dans la town, avec ses propres beads et ses agents. |
| Crew | Votre clone personnel dans un rig, où vous travaillez à la main. |
| Mayor | Le coordinateur : une instance de Claude Code qui voit tous les rigs et répartit le travail. |
| Polecat | Un agent worker lancé dans un rig pour traiter un bead, dans son propre worktree git. |
| Convoy | Un groupe de beads suivis ensemble, généralement une fonctionnalité sur plusieurs rigs. |
| Refinery | Une file de merge par rig pour les branches des polecats. |
| Witness / Deacon | Les chiens de garde : surveillance de la santé par rig et à l’échelle de la town. |
En résumé : vous parlez au Mayor, les polecats font le travail, la Refinery merge, les chiens de garde maintiennent le tout en vie.
Prérequis
- Git 2.20+
- tmux 3.0+ (les agents tournent dans des sessions tmux)
- Claude Code CLI, connecté
- Des dépôts qui utilisent déjà Beads (facultatif, mais c’est tout l’intérêt)
Étape 1 : Installer
Sur macOS, Homebrew installe gt, bd (Beads) et dolt (la base de données qu’utilise Beads) d’un coup :
brew install gastown
Sur Linux, installez d’abord Dolt, puis :
go install github.com/steveyegge/gastown/cmd/gt@latest
go install github.com/steveyegge/beads/cmd/bd@latest
Vérifiez que tout est là :
gt --version
bd --version
tmux -V
Si Beads était déjà installé, lancez which -a bd pour vous assurer qu’il n’y a qu’un seul bd dans votre PATH.
Étape 2 : Créer la town
gt install ~/gt-matrix --git
cd ~/gt-matrix
gt up
gt doctor --fix
--gitfait de la town elle-même un dépôt git, pour pouvoir versionner sa configuration.gt updémarre Dolt, un daemon en arrière-plan, le Mayor et les chiens de garde.gt doctor --fixvérifie environ quatre-vingt-dix points et répare ce qu’il peut.
Si doctor signale un .claude/settings.json obsolète qu’il refuse de supprimer parce qu’il est suivi par git, retirez-le du suivi et relancez doctor :
git rm --cached .claude/settings.json
echo ".claude/settings.json" >> .gitignore
git commit -am "Untrack generated Claude settings"
gt doctor --fix
gt up --restore
Il existe aussi une option --shell qui installe un hook proposant d’ajouter à la town chaque dépôt git dans lequel vous faites un cd. Je recommande de s’en passer, surtout si vous comptez avoir plus d’une town.
Étape 3 : Ajouter vos dépôts comme rigs
Chaque dépôt devient un rig. gt rig add le clone dans la town :
cd ~/gt-matrix
gt rig add matrix_api https://github.com/you/matrix-api.git \
--prefix mapi \
--local-repo ~/code/matrix-api
Quelques règles apprises à la dure :
- Les noms de rig n’acceptent que des lettres, des chiffres et des underscores :
matrix_api, pasmatrix-api. - Passez toujours
--prefix. Sans lui, Gas Town en déduit un à partir du nom, et deux rigs commematrix_apietmatrix_adminse retrouvent tous les deux avecmaet entrent en collision. - Utilisez le préfixe qu’utilisent déjà vos beads existants, pour que les anciens identifiants et les références inter-dépôts restent valides. Retrouvez-le avec
bd list | head -3dans le dépôt d’origine. - Préférez des préfixes courts sans tiret (
mapi, pasmatrix-api). Les préfixes avec tiret fonctionnent dans le rig, mais les recherches au niveau de la town ne lisent que jusqu’au premier tiret, donc le Mayor ne peut pas répartir ces beads. --local-repopartage les objets git avec votre clone existant, ce qui économise beaucoup d’espace disque.
Vérifiez le résultat :
gt rig list
Étape 4 : Récupérer vos beads existants
Gas Town stocke les beads de chaque rig dans son propre serveur Dolt, pas dans le dépôt. Si vos anciens beads étaient locaux (non commités), le clone ne les récupère pas. Exportez-les depuis l’ancien dépôt et importez-les dans le 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
Consultez d’abord bd import --help pour votre version. Après l’import, vérifiez un bead qui dépend d’un autre dépôt (bd show <id>) pour confirmer que les liens inter-dépôts ont survécu.
À partir de maintenant, les rigs font foi. Arrêtez d’utiliser les anciens clones, sinon vous finirez avec deux jeux de tickets qui divergent.
Étape 5 : Créer votre espace crew
Pour le travail manuel dans un seul dépôt, vous utilisez toujours une session Claude Code normale, simplement depuis votre clone crew :
gt crew add sami --rig matrix_api
cd ~/gt-matrix/matrix_api/crew/sami
claude
Elle charge le CLAUDE.md de ce dépôt et lit et écrit les beads du rig comme d’habitude. Les noms de crew suivent la même règle que les rigs : pas de tiret.
Étape 6 : Laisser le Mayor répartir le travail
Attachez-vous au Mayor :
cd ~/gt-matrix
gt mayor attach
Puis décrivez ce que vous voulez, ou indiquez-lui des beads existants. Pour regrouper une fonctionnalité sur plusieurs dépôts :
gt convoy create "Billing export" mapi-a1b mweb-c2d mwrk-e3f --notify
Et dites au Mayor : « Work convoy Billing export: sling the ready beads to their rigs, and as each one closes, dispatch the beads it unblocks. » (traite le convoy Billing export : envoie les beads prêts à leurs rigs et, à chaque fermeture, répartis les beads qu’elle débloque).
C’est tout l’intérêt de l’outil : un polecat démarre dans le bon rig, traite le bead, et quand celui-ci est fermé, le bead bloqué dans un autre dépôt devient prêt et part au tour suivant. Vous pouvez aussi répartir un seul bead vous-même :
gt sling mapi-a1b matrix_api
Détachez-vous du Mayor avec Ctrl-b puis d ; il continue de travailler.
Suivre ce qui se passe
gt agents # qui tourne
gt convoy list # avancement par fonctionnalité
gt feed # flux d'événements en direct
gt dashboard --port 8090
Le dashboard est une page web sur http://localhost:8090 qui affiche les polecats, les convoys, la file de merge et les escalades. Utilisez localhost plutôt que 127.0.0.1 si votre navigateur refuse ce dernier.
Pour poser une question au Mayor sans le laisser agir, attachez-vous et passez en plan mode (Shift+Tab), ou envoyez-lui un mail :
gt mail send mayor -s "Status" -m "Which beads are in progress?"
Étape 7 : Choisir un modèle par tâche
Définissez un alias d’agent par modèle Claude :
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
Gardez --dangerously-skip-permissions : les polecats tournent sans surveillance dans tmux, et sans cette option ils s’arrêtent à la première demande de permission sans personne pour y répondre. Mettez plutôt vos limites strictes dans un hook PreToolUse (voir l’étape suivante).
Ensuite, laissez le Mayor choisir. Écrivez un fichier de politique et référencez-le depuis le CLAUDE.md de la town :
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"
Garder la politique dans son propre fichier la protège de gt doctor --fix, qui gère le CLAUDE.md de la town.
Étape 8 : Garder les agents dans leur couloir
Des agents qui tournent sans surveillance prendront volontiers des décisions à votre place. Quelques garde-fous :
- Imposez, ne vous contentez pas de demander. Un hook
PreToolUsequi bloquegit push,sshet les commandes de déploiement est appliqué ; une phrase dans un prompt n’est qu’un conseil. - Listez les décisions qui vous reviennent dans le
CLAUDE.mdde la town : déploiements, merges, migrations, fermeture des beads, modification des rigs. Ajoutez : « If a bead is ambiguous, escalate instead of guessing. » (si un bead est ambigu, escalade au lieu de deviner). - Écrivez des beads précis : critères d’acceptation, décisions déjà prises, questions ouvertes signalées comme telles. C’est sur les beads flous que les agents improvisent.
- Exigez des preuves : un hash de commit, une sortie de tests ou la commande de vérification dans chaque note de fin.
- Gardez une validation humaine des merges sur les dépôts partagés : les polecats ouvrent des PR, vous mergez. Utilisez
--merge=locallors du sling pour que la Refinery ne merge pas non plus. - Limitez la concurrence le temps de prendre confiance :
gt config set scheduler.max_polecats 2
Au quotidien
cd ~/gt-matrix && gt up # début de journée
gt down # fin de journée
Chaque rig fait tourner un witness et une refinery qui patrouillent en continu et interrogent Dolt. Avec beaucoup de rigs, ça occupe le CPU même quand il ne se passe rien. Arrêtez les rigs que vous n’utilisez pas :
gt rig stop matrix_admin matrix_docs
Vous ne perdez rien : un sling vers un rig arrêté le redémarre automatiquement.
Astuces et pièges
- Un port Dolt par town. Une deuxième town a besoin du sien :
gt install ~/gt-other --git --dolt-port 3308. - Les nouveaux rigs demandent la confiance du dossier. La première fois qu’un agent démarre dans un nouveau rig, Claude Code demande si vous faites confiance au dossier, et Gas Town expire en attendant. Attachez-vous à la session (
tmux -L <town-socket> attach -t <session>) et acceptez une fois. - Figez la chaîne d’outils. Un
brew upgradepeut faire monter la version debd, qui exige alors une migration de schéma sur chaque base. Lancezgt downavant de mettre à jour, et épinglez les outils pour que les mises à jour courantes les ignorent :brew pin beads gastown dolt. - Les migrations peuvent dépasser le timeout de Dolt. La configuration Dolt de Gas Town coupe les requêtes à cinq minutes, et une migration de schéma Beads sur la base de la town peut prendre plus longtemps. Sauvegardez
.dolt-data(Dolt arrêté) avant de migrer, et si ça échoue aveccontext canceled, relancez-la sur un serveur avec un timeout plus long. - Les avertissements de patrouille sont connus. Dans les versions 1.x, les witnesses peuvent signaler « no active patrol found ». C’est un problème ouvert en amont dans la comptabilité des patrouilles, sans effet sur les beads, le sling ou les polecats.
- Échafaudage non commité. Les polecats terminés peuvent laisser derrière eux des dossiers
.beads,.claudeet.runtime, ce qui bloquegt rig stop. Vérifiez avecgit statusqu’il ne s’agit que d’échafaudage avant d’utiliser--force. - Surveillez le disque. Chaque rig et chaque worktree de polecat est un checkout.
--local-repoaide beaucoup.
Est-ce que ça vaut le coup ?
Pour un seul dépôt, non : une session Claude Code suffit. Gas Town devient rentable quand le travail traverse régulièrement les frontières entre dépôts et que vous voulez que les tickets circulent d’un dépôt à l’autre sans ouvrir chaque session vous-même.
C’est aussi un outil jeune qui évolue vite, alors traitez-le comme de l’infrastructure : figez les versions, sauvegardez la base de la town, arrêtez ce que vous n’utilisez pas, et gardez un humain dans la boucle de merge. Avec ça en place, la danse des tickets inter-dépôts que je faisais à la main tourne désormais toute seule.