3

Como impedi que sessões paralelas do Claude Code derrubassem os servidores umas das outras

Rodo várias sessões do Claude Code na mesma máquina, geralmente uma por git worktree. O git separa as branches, mas a máquina é compartilhada: um agente "reinicia o servidor dele" com pkill node e derruba o dev server de todas as outras worktrees, duas sessões disputam a porta 3000, três builds começam no mesmo minuto e a máquina trava.

Para isso escrevi o claude-bulkhead, um conjunto de hooks PreToolUse (MIT, sem dependências).

Como funciona. Não há daemon. Antes de cada comando de shell, o Claude Code chama um script Node pequeno. Ele lê o comando como sintaxe de shell e compara com o que as outras sessões estão fazendo: quais processos e portas pertencem a qual sessão, quanta RAM sobra e em qual árvore git cada sessão trabalha. Se houver colisão, bloqueia e devolve ao Claude o motivo e um comando alternativo: matar pelo PID, usar uma porta livre, esperar numa fila de RAM, commitar pelo nome do arquivo. Cada verificação leva cerca de 50 ms.

Quantas vezes isso já aconteceu? O Claude Code guarda as transcrições em ~/.claude/projects. O bulkhead scan reexecuta cada comando dessas transcrições contra os guards, só lendo, sem enviar nada. No meu Mac, duas semanas (7,0 GB, 100 mil comandos) levaram 39 segundos:

  • até 13 sessões rodando ao mesmo tempo
  • 507 comandos que teriam sido bloqueados
  • 25 deles eram git add -A numa árvore que outra sessão estava editando, o que joga o trabalho pela metade da outra sessão no seu commit

Limites. É análise de string de comando, não um sandbox. Portas e RAM não podem ser reproduzidas a partir das transcrições.

Para testar (Node 18+, macOS, Linux e Windows):

/plugin marketplace add dooly6276/claude-bulkhead
/plugin install bulkhead@bulkhead
/bulkhead:scan 30d

README em português: https://github.com/dooly6276/claude-bulkhead/blob/main/README.pt-BR.md

Carregando publicação patrocinada...
1

O scan em cima das transcrições foi a parte que mais me pegou, a ponto de eu ficar com medo de rodar nas minhas.

Briga de porta eu resolvo com a porta no .env de cada worktree, servidor e testes inclusos.

Já no git, semana passada caí numa variação que talvez escape da análise de string: fiz git add só nos meus arquivos, rodei git commit, e foram junto três posts de blog que outra sessão tinha deixado no stage, direto pra main, que nesse repo é produção. O git commit leva o índice inteiro. Nenhum comando ali parecia perigoso.

Hoje commito com git commit -- <arquivos>. Fiquei curioso: o guard de commit olha o git diff --cached na hora, ou só o texto do comando?