Como dizer ao Claude Code em qual pacote do monorepo ele deve mexer?

como restringir o Claude Code monorepo ao pacote certo com CLAUDE.md
Resposta rápida

Em monorepo, o Claude Code não adivinha a fronteira do seu pacote: quem delimita é você. A doc oficial avisa que, em codebase grande, os defaults (pensados para projetos pequenos) enchem a janela de contexto com instruções e leituras sem relação com a tarefa, gastando tokens e degradando o desempenho. O caminho prático: abrir a sessão de dentro do pacote (assim carrega o CLAUDE.md dele mais o da raiz, e nada dos outros), conferir com /context, nomear os arquivos com @-mentions, citar a restrição no enunciado e barrar caminhos com regras de Read em permissions.deny

Você pede uma linha em packages/api e o diff volta com arquivo mexido em packages/web

Aí você abre pra revisar e percebe que o agente passeou pelo repositório inteiro pra resolver uma coisa que cabia dentro de um pacote só

A doc oficial explica o porquê sem rodeio: em codebases grandes, os defaults do Claude Code foram pensados para projetos pequenos, e acabam enchendo a janela de contexto com instruções e leituras de arquivo sem relação com a tarefa, gastando tokens e degradando o desempenho

Ou seja, não é birra do modelo, é escopo mal definido

E escopo, aqui, mora em dois lugares: no enunciado do prompt e nas configurações do projeto

Bora ver na prática? 🙂

O que você precisa saber antes de escopar o prompt

Três conceitos rápidos, senão o passo a passo vira receita decorada

Onde os CLAUDE.md vivem e quando cada um entra:

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 116 aulas
  • 4 projetos
  • 9h 23min

O CLAUDE.md da raiz entra na abertura da sessão

Junto com ele entra o CLAUDE.md do diretório de onde você abriu a sessão: iniciando de dentro de packages/api/, carregam packages/api/CLAUDE.md e o CLAUDE.md da raiz, e nada de packages/web/ entra no contexto

Já os CLAUDE.md dos outros subdiretórios carregam sob demanda, quando o Claude lê um arquivo daquele diretório

Então, se você abre da raiz do repositório, o CLAUDE.md de packages/api/ só entra no contexto no momento em que ele lê um arquivo de lá

A ideia de apontar o agente para o pacote certo começa exatamente aí

O comando /context mostra o que está ocupando a janela:

Esse é o teu instrumento de medida

O /context mostra a quebra do que está ocupando a janela de contexto, incluindo quais arquivos CLAUDE.md e de memória automática foram carregados

Sem ele, escopo vira achismo

O arquivo onde a regra é gravada define o alcance dela:

Isso vale pra qualquer regra de permissão que a gente for escrever depois

  • .claude/settings.json: vale pra todo mundo do repositório
  • .claude/settings.local.json na raiz do repositório: vale só pra você
  • managed settings: vale em toda sessão, sem que configurações de projeto ou de usuário sobrescrevam

Mesma regra, alcance diferente, só por causa do arquivo em que ela foi parar

E o .claudeignore, funciona?

Aqui vai o aviso honesto, porque esse arquivo aparece muito em tutorial por aí

O .claudeignore não é suportado oficialmente pelo Claude Code: não é recurso nativo, existe apenas como solução de comunidade via hook PreToolUse

O caminho oficial pra barrar caminho é permissions.deny no settings.json, que é o que a gente usa no passo 5

Passo a passo para apontar o pacote alvo ao Claude Code

  1. Abra a sessão de dentro do pacote

Essa é a delimitação mais barata que existe, e a maioria das pessoas pula

cd packages/api
claude

Com isso, entram no contexto o packages/api/CLAUDE.md e o CLAUDE.md da raiz

O erro comum deste passo: abrir tudo da raiz por costume e depois reclamar que o agente mistura os pacotes

  1. Confira o que entrou com /context

Antes de escrever qualquer prompt, roda:

/context

Ele te devolve a quebra do que está ocupando a janela, com os CLAUDE.md e os arquivos de memória automática que foram carregados

O erro comum deste passo: assumir que o contexto está limpo sem nunca ter olhado

  1. Nomeie os arquivos no enunciado com @-mentions

As @-mentions referenciam arquivos ou pastas direto no prompt: você digita @ seguido do nome e o Claude lê aquele conteúdo

Tem fuzzy matching (dá pra digitar só parte do nome) e dá pra citar vários arquivos na mesma mensagem

É a diferença entre "acha aí onde fica o serializer" e "é neste arquivo, ó"

O erro comum deste passo: descrever o arquivo por extenso em vez de referenciar, e deixar o agente sair varrendo o repositório pra encontrar

  1. Escreva o prompt pelas boas práticas oficiais

As boas práticas da doc pedem precisão em quatro frentes: referenciar arquivos específicos, citar as restrições, apontar um padrão de exemplo já existente e pedir a verificação no mesmo prompt

E tem um detalhe que muda tudo: descreva o RESULTADO, não os passos

@packages/api/src/routes/users.ts @packages/api/src/services/user-service.ts

A resposta de GET /users precisa devolver também o campo status,
seguindo o mesmo padrão de serialização que já existe em user-service.ts

Restrição: não altere nada fora de packages/api

Depois rode os testes deste pacote e me mostre a saída

Repara que a última linha faz o trabalho sozinha: pedir pra rodar, testar ou comparar dentro da mesma instrução é o que transforma o pedido num prompt que ele verifica sozinho antes de dizer que terminou

O erro comum deste passo: mandar o roteiro de como fazer, em vez do resultado esperado mais a restrição

  1. Barre o que ele não deve abrir com Read em permissions.deny

Tem código versionado que só serve pra entupir contexto: build, artefato gerado, SDK vendorizado

{
  "permissions": {
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)",
      "Read(./**/*.generated.*)",
      "Read(./vendor/**)"
    ]
  }
}

E o que significam esses símbolos? Nos padrões de caminho das regras de permissão, o casamento é ancorado no caminho de diretório inteiro: um asterisco casa exatamente um segmento e dois asteriscos casam através de segmentos

Detalhe que salva: as regras de deny cobrem as ferramentas nativas de arquivo do Claude e também comandos de arquivo reconhecidos no Bash quando o caminho negado é passado como argumento, tipo cat, head, grep e find

O erro comum deste passo: escrever um asterisco onde precisava de dois e achar que negou a pasta inteira quando negou um nível só

  1. Precisa de outro diretório? Estenda o acesso com consciência

O Claude Code oferece três formas de dar acesso a diretórios além do diretório de trabalho

Forma Onde entra Carrega .claude/skills/ do diretório adicionado
–add-dir flag na abertura da sessão sim
/add-dir comando dentro da sessão sim
permissions.additionalDirectories configuração no settings.json não, dá acesso a arquivos

A ressalva importante: adicionar um diretório estende onde o Claude pode ler e editar, mas não transforma esse diretório em raiz de configuração completa, e a maior parte do .claude/ não é descoberta a partir de diretórios adicionais

Outra coisa pra ter no radar: arquivos em diretórios adicionais seguem as mesmas regras de permissão do diretório de trabalho original, então viram legíveis sem prompt e a edição segue o modo de permissão vigente

O erro comum deste passo: adicionar o diretório esperando que toda a configuração dele venha junto

  1. Sessão cheia de correção? /clear e recomeça

Quando a conversa vira uma pilha de "não, não era isso", a doc recomenda rodar /clear e recomeçar com um prompt mais específico

/clear

Sessão limpa com prompt melhor supera quase sempre sessão longa com correções acumuladas

O erro comum deste passo: insistir por mais dez mensagens numa sessão que já está contaminada

Três situações comuns e o prompt certo para cada uma

O passo a passo linear resolve o caso simples, mas monorepo tem umas curvas 😀

A mudança atravessa pacotes de propósito:

Às vezes o certo é mexer em mais de um lugar mesmo, tipo alterar um tipo compartilhado e os pontos de chamada

Para esse caso, a doc oficial recomenda entregar a mudança inteira em uma sessão só e planejar antes de editar: passar a edição compartilhada e os pontos de chamada juntos mantém as decisões consistentes

Antes de deixar ele editar, liga o plan mode, que faz o Claude ler arquivos e responder sem alterar nada

Tem três jeitos de acionar:

  • Shift+Tab até a barra de status mostrar "⏸ plan mode on"
  • o comando /plan
  • iniciar a sessão com claude –permission-mode plan
claude --permission-mode plan

No plan mode o Claude escreve o plano em um arquivo, então dá pra ler, discordar e ajustar antes de qualquer linha ser tocada

Você precisa entender o código antes de mexer:

Exploração é justamente o que mais entope contexto: dez arquivos lidos pra descobrir onde uma coisa acontece

Aqui entra o subagente

Cada subagente roda na própria janela de contexto, com system prompt, acesso a ferramentas e permissões independentes, e devolve só o resumo para a conversa principal

O Claude delega ao Explore quando precisa buscar ou entender o código sem alterar nada, mantendo as leituras grandes fora do contexto principal

É como mandar alguém ler o calhamaço e te trazer a resposta de uma linha

Cada pacote tem regra própria e você quer padronizar:

Qualquer subdiretório pode definir skills escopadas ao próprio stack, que carregam sob demanda quando o Claude julga relevante

Em monorepo, isso vira um conjunto de skills por pacote:

packages/api/.claude/skills/
packages/web/.claude/skills/

Em árvore única, o mesmo raciocínio vale por subsistema, tipo src/db/.claude/skills/

E tome cuidado com uma armadilha do CLAUDE.md aninhado: depois da compactação ele não é reinjetado automaticamente

Ele volta na próxima vez que o Claude ler um arquivo daquele subdiretório

Ou seja, se a conversa compactou e ele começou a esquecer a convenção do pacote, não é frescura tua, é comportamento conhecido

Conclusão

Escopo em monorepo não é capricho de redação, é enunciado MAIS configuração

O enunciado entra com as @-mentions, a restrição explícita, o padrão de exemplo e o pedido de verificação

A configuração entra com o diretório onde você abre a sessão, as regras de Read em permissions.deny e as skills por pacote

Próximo passo, pequeno e concreto: escolhe um pacote, abre a sessão de dentro dele, roda /context e compara com o que aparece quando você abre da raiz do repositório

A diferença na lista de arquivos carregados já responde metade das tuas dúvidas

faça o teste! e até o próximo post!

Perguntas frequentes

Como fazer o Claude Code ignorar uma pasta específica dentro do monorepo?

Não é pelo .claudeignore, porque esse arquivo não é suportado oficialmente pelo Claude Code, só existe como solução de comunidade via hook PreToolUse. O caminho oficial é escrever a regra em permissions.deny do settings.json, usando padrões como "Read(.//dist/)" pra barrar build, artefato gerado e SDK vendorizado.

Dá pra ter um CLAUDE.md diferente para cada pacote do monorepo?

Dá sim. Cada subdiretório pode ter o próprio CLAUDE.md. Se você inicia a sessão de dentro de packages/api/, entram no contexto o CLAUDE.md daquele pacote e o CLAUDE.md da raiz, sem as instruções dos outros pacotes. Já os CLAUDE.md dos subdiretórios que você não abriu carregam sob demanda, no momento em que o Claude lê um arquivo de lá.

O CLAUDE.md do pacote some depois que a conversa compacta?

Ele some do contexto, mas não é definitivo. CLAUDE.md aninhado não é reinjetado automaticamente depois da compactação: ele volta na próxima vez que o Claude ler um arquivo daquele subdiretório.

Qual a diferença entre –add-dir e permissions.additionalDirectories?

As duas formas estendem onde o Claude pode ler e editar, mas não viram raiz de configuração completa. A diferença é que –add-dir (e o comando /add-dir) carregam o .claude/skills/ do diretório adicionado como exceção, enquanto permissions.additionalDirectories dá acesso aos arquivos e não carrega skills.

Como pedir uma mudança que mexe em dois pacotes do monorepo ao mesmo tempo?

Pra mudança que atravessa pacotes, a doc oficial recomenda entregar a mudança inteira numa sessão só e planejar antes de editar, passando a edição compartilhada e os pontos de chamada juntos pra manter as decisões consistentes. O plan mode ajuda nisso: o Claude lê os arquivos e escreve o plano antes de tocar em qualquer código.

Dá pra ter skills diferentes para cada pacote do monorepo?

Sim, qualquer subdiretório pode definir skills escopadas ao próprio stack, que carregam sob demanda quando o Claude julga relevante pra tarefa. Em monorepo isso normalmente vira um conjunto de skills por pacote.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares