Multi-repo no Claude Code: abrir num repo só ou na raiz do workspace?
Trabalho que cruza 3-5 repositórios o tempo todo me obrigou a escolher entre abrir o Claude Code dentro de um repo (e usar /add-dir nas exceções) ou na raiz que contém todos. Aqui estão as 5 diferenças que pesaram.
Stack distribuída tem um padrão chato: uma feature pequena toca 3, 4, 5 repositórios. Um evento sai de service-A, é consumido por service-B, atualiza service-C e dispara um job em service-D. Pra arrumar um bug, você precisa ler tudo isso junto.
Eu venho dessa rotina há um tempo. Demorei pra perceber que a decisão de onde abrir o Claude Code mudava mais do trabalho do que qualquer prompt ou hook que eu configurasse depois.
O problema
Comecei abrindo o Claude Code dentro do repo da vez. Sempre que precisava ler outro, /add-dir — mais um, e mais um, e mais um. Virou ritual diário. E pior: meus slash commands custom só funcionavam no repo onde a sessão tinha começado, então eu vivia colando os mesmos prompts à mão nos outros.
Testei a alternativa: abrir o Claude Code na raiz do workspace que contém todos os repos. Em ~3 dias parou de doer. Vou listar o que mudou, na ordem que senti.
1. Carregamento de CLAUDE.md em cascata
Esse é o mais importante. O Claude Code percorre os ancestrais do cwd carregando CLAUDE.md de cada um, do root até o cwd, concatenando o conteúdo.
Pra subdiretórios o carregamento é diferente: é lazy. O CLAUDE.md de uma subpasta só entra no contexto quando o Claude lê algum arquivo lá dentro.
Implicação prática:
- Abrir num repo só: carrega o
CLAUDE.mddaquele repo + dos ancestrais. OCLAUDE.mddos repos vizinhos nunca entra, mesmo via/add-dir(ele ignoraCLAUDE.mdpor padrão — só carrega se você setarCLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1). - Abrir na raiz do workspace: carrega o
CLAUDE.mdda raiz na hora; o de cada repo entra automaticamente conforme você toca arquivos lá.
Isso virou desbloqueio: regras universais (padrão de commit, política de PR, fluxo de release) num CLAUDE.md na raiz; regras locais (stack, convenções, paths) no CLAUDE.md de cada repo. Sem duplicação, sem drift.
2. Escopo de skills e slash commands
Skills (.claude/skills/) e slash commands custom (.claude/commands/) têm regras parecidas mas não idênticas. O resumo do que importa:
- Skills da raiz da sessão são carregadas no início; skills de subdiretórios são auto-descobertas sob demanda quando o Claude trabalha em arquivos daquela subpasta.
- Skills via
/add-dircarregam (com live reload). .claude/commands/da raiz carregam; commands de subdiretórios não auto-carregam com a mesma certeza que skills (no meu teste, quem auto-discoverer é o sistema de skills; a doc não detalha o mesmo comportamento pra commands legados).- Skills/commands em
~/.claude/valem globalmente, independentemente de onde a sessão começou.
Tradução: se sua bateria de comandos vive em ~/.claude/, dá no mesmo. Se vive em .claude/ por repo, abrir na raiz do workspace deixa todos os comandos disponíveis em qualquer turno.
3. /add-dir é tool de exceção, não de fluxo
Eu já tinha escrito sobre /add-dir antes, mas só fui sentir o limite quando ele virou meu ritual.
/add-dir é session-scoped (some quando a sessão fecha), não carrega CLAUDE.md do dir adicionado por padrão, não carrega commands, não carrega hooks, e os hooks que existem podem resolver paths relativos errado — porque o cwd não muda.
Isso resolve “preciso ver uma coisa específica fora do meu escopo normal”. Não resolve “trabalho cruza repos toda hora”. Se você está digitando /add-dir mais de duas vezes por sessão, é sinal pra mudar de raiz.
Se você só precisa de acesso pontual a outro diretório,
/add-dirresolve — esse post compara o setup base, não o uso pontual.
4. Análise cross-repo
Comandos do tipo “rastreia esse evento entre o producer e os consumers” ou “lista todos os lugares que chamam esse endpoint” só funcionam se o Claude tem acesso a tudo. Abrir num repo só limita visibilidade — análise fica parcial e o modelo às vezes nem percebe que está cega.
Abrir na raiz permite grep amplo e busca por arquivo cobrindo todos os repos. Pra debug em sistemas distribuídos, isso muda completamente a qualidade da resposta.
5. Performance / contexto
A preocupação razoável: workspace com muitos repos = mais código indexado.
Na prática, o Claude lê sob demanda via grep/glob, não pré-indexa tudo no contexto. O custo extra existe (a busca varre mais arquivos), mas só vira dor real em monorepos gigantes — centenas de milhares de arquivos.
Pra um workspace típico de 5-10 repos de tamanho normal, não senti diferença.
Quando cada um faz sentido
- Trabalho >80% num repo só → abre nele. Cascade de ancestrais ainda te dá o
CLAUDE.mdda raiz. - Trabalho cruza repos com frequência → abre na raiz do workspace.
- Caso intermediário (cruzamento ocasional) → mantém a sessão no repo principal e usa
/add-dirquando o assunto sobe.
Como organizei meu CLAUDE.md
workspace/
├── CLAUDE.md ← regras universais (commit, fluxo, PR)
├── service-a/
│ ├── CLAUDE.md ← stack, convenções locais, paths
│ └── ...
├── service-b/
│ ├── CLAUDE.md
│ └── ...
└── service-c/
├── CLAUDE.md
└── ...
A regra de hierarquia é simples: o CLAUDE.md específico complementa o universal (a doc descreve concatenação, não override). Quando há conflito real, escrevo a regra específica como “no repo X, ignore a regra universal de Y porque Z” — explícito é melhor que implícito.
Resumindo
Troquei pra abrir na raiz do workspace e foi melhor. Cascade do CLAUDE.md fez o trabalho dobrado de manter regras virar “escreva uma vez no lugar certo”. Comandos compartilhados pararam de ser drama. /add-dir virou exceção honesta — pra quando preciso espiar fora do workspace, não pra cruzar repos que eu já sabia que ia cruzar.
Se você ainda está usando /add-dir como fluxo, vale testar uma semana com a sessão na raiz. Eu não voltei.