Modern Angular
Um CLAUDE.md para Angular moderno: memória, não só regras
O Claude Code não lê o seu AGENTS.md. Ele lê o CLAUDE.md, e carrega esse arquivo em toda sessão, sozinho. O ng generate ai-config --tool claude escreve um em .claude/CLAUDE.md, um caminho que o Claude Code já trata como memória de projeto. O ganho num repo Angular não é um arquivo de regras maior. É estrutura: uma hierarquia, imports e regras com escopo de path que batem com a forma como o workspace já é organizado.
AGENTS.md é o quê; CLAUDE.md é como o Claude Code carrega
Se você já escreveu um AGENTS.md pro seu repo Angular, tem um detalhe que pega os times de surpresa: o Claude Code não lê ele. Ele lê o CLAUDE.md, e lê sozinho. No começo da sessão ele sobe a árvore de diretórios e carrega todo CLAUDE.md que encontra, então o arquivo já está no contexto antes de você digitar qualquer coisa. Um AGENTS.md do lado fica ignorado, a menos que você puxe ele de propósito.
São dois lugares de projeto que o Claude Code aceita: ./CLAUDE.md na raiz do repo, ou ./.claude/CLAUDE.md dentro da pasta .claude/. Os dois valem igual. Esse segundo caminho é o que importa pro Angular, porque é exatamente ali que o ng generate ai-config --tool claude escreve. O arquivo que o CLI gera já é um arquivo de memória que o Claude Code vai carregar, então você não precisa mover nada.
As restrições que vão dentro, o pin de versão, a fronteira Signals e RxJS, as regras de template, são as mesmas que eu destrinchei pra um AGENTS.md. Aquele guia é o quê. Este aqui é sobre como o Claude Code carrega e organiza, que é onde está a alavanca.
| Arquivo | Quando carrega | Para que serve |
|---|---|---|
| ~/.claude/CLAUDE.md | Toda sessão, todo projeto | Seus defaults pessoais, não os do time |
| .claude/CLAUDE.md ou ./CLAUDE.md | No começo da sessão, no topo da árvore | As regras de Angular que o time inteiro compartilha |
| CLAUDE.local.md | No começo da sessão, depois do CLAUDE.md | Suas notas só da sua máquina, no gitignore |
| src/app/feature/CLAUDE.md | Sob demanda, quando o Claude abre arquivo ali | Regras de uma feature ou lib só |
Importe o AGENTS.md, não copie pra dentro do CLAUDE.md
O jeito errado de manter os dois arquivos é colar as regras de Angular em cada um. Aí você fica com duas cópias que divergem, e o ng generate ai-config vai alegremente regerar uma delas por baixo dos panos. O Claude Code tem um import pra isso. Uma linha que começa com @ puxa outro arquivo pro CLAUDE.md na hora de carregar, então uma fonte só alimenta as duas ferramentas.
Eu deixo as restrições de Angular no AGENTS.md, o arquivo que o CLI mantém, e deixo o CLAUDE.md importar ele e adicionar só o que é específico do Claude: quando usar plan mode, quais diretórios são proibidos, como o time roda os testes. Os imports resolvem em relação ao arquivo e vão até quatro níveis de profundidade, mais que suficiente pra um @AGENTS.md.
# CLAUDE.md
@AGENTS.md
## Trabalhando neste repo
- Pergunte antes de adicionar dependência; este repo fica enxuto.
- Use plan mode antes de mexer em qualquer coisa sob src/app/**/state/.
- Rode os testes com `npm test` (Vitest). Não traga o Karma de volta.
- Nunca edite arquivos sob src/generated/.Regras com escopo de path batem com um workspace Angular
Um arquivo de regras único tenta cobrir componente, estado e teste de uma vez, e o agente lê tudo, esteja escrevendo um pipe ou um spec. O Claude Code consegue dar escopo de path nas regras. Um arquivo em .claude/rules/ com um glob de paths no frontmatter carrega só quando o Claude abre um arquivo que casa. Um workspace Angular já tem essas fronteiras: specs, componentes, estado.
É aqui que as regras de teste ganham arquivo próprio. O conselho que importa num .spec.ts (use Vitest, os helpers de fakeAsync precisam do patch de zone, não chame detectChanges a cada mudança) é só ruído num arquivo sobre componente. E é uma decisão por si só. Dê escopo nessas regras nos specs e elas aparecem exatamente quando o agente está escrevendo um.
---
paths:
- "src/app/**/*.spec.ts"
---
# Regras de teste
Use Vitest. Não traga Karma ou Jasmine de volta.
fakeAsync, tick e flush só funcionam com o vitest-patch do zone.js ligado.
Prefira fake timers ou async nativo no lugar de fakeAsync em spec novo.
Não chame detectChanges depois de cada mutação; isso esconde notificação que falta.Deixe o arquivo da raiz curto; a árvore carrega o resto
Memória não é de graça. Tudo no CLAUDE.md e tudo que ele importa fica no contexto a sessão inteira, e um arquivo inchado não custa só token, o agente também segue ele menos à risca. A orientação é manter um CLAUDE.md abaixo de umas duzentas linhas e empurrar o detalhe pra fora: imports pras regras compartilhadas, arquivos com escopo de path pras partes que só importam às vezes.
Um monorepo Angular te dá o outro eixo de graça. Um CLAUDE.md dentro de uma feature library carrega só quando o Claude está trabalhando naquela lib, então regra de app e de lib não pesa em toda sessão. O /init rascunha um arquivo inicial a partir do seu codebase, e o /memory lista o que está carregado agora, que é o jeito mais rápido de pegar um arquivo que você esqueceu que existia.
| Regra | Onde fica | Por quê |
|---|---|---|
| Pin de versão, fronteira Signals/RxJS, sintaxe de template | AGENTS.md, importado no CLAUDE.md | Uma fonte só que o CLI mantém atual |
| Plan mode, diretórios proibidos, como rodar os testes | CLAUDE.md da raiz | Específico do Claude, sempre verdade |
| Regras de Vitest e fakeAsync | .claude/rules/testing.md, escopo em *.spec.ts | Carrega só quando escreve um spec |
| Convenções de estado e store | .claude/rules/state.md, escopo na pasta de estado | Carrega só no código de estado |
| As manias de uma lib | lib/CLAUDE.md | Sob demanda, quando trabalha naquela lib |
Um CLAUDE.md velho engana em toda sessão
Todo arquivo aqui tem o mesmo modo de falha de um arquivo de regras escrito à mão, com uma diferença: como o CLAUDE.md carrega em toda sessão, uma linha velha não é um documento que alguém pode ler errado. É uma instrução que o agente segue em toda tarefa, sem alarde, até alguém notar que o código gerado está uma versão atrás.
Então a regra de manutenção é a que eu amarro ao AGENTS.md: quando o time sobe um major do Angular, os arquivos de memória passam pela mesma revisão que as dependências. O pin de versão, a lista de API experimental, as notas de teste, tudo. Um CLAUDE.md que ainda chama Signal Forms de experimental vai afastar o agente de uma API que virou estável no v22, com toda a confiança, em toda execução.
Artefato para reaproveitar
Um setup de CLAUDE.md pra um repo Angular
- Arquivo de memória em .claude/CLAUDE.md ou ./CLAUDE.md (os dois carregam); o CLI do ai-config escreve o primeiro.
- AGENTS.md importado com @AGENTS.md, não copiado, pra regra mantida pelo CLI seguir como fonte única.
- Regras de teste com escopo em *.spec.ts no .claude/rules/, pras notas de Vitest e fakeAsync carregarem só nos specs.
- Regras de estado e de componente com escopo de path do mesmo jeito; o arquivo da raiz fica só com o que é sempre verdade.
- CLAUDE.md da raiz abaixo de umas 200 linhas; um CLAUDE.md por lib pras features do monorepo.
- Um gatilho de revisão amarrado aos majors do Angular, pro pin de versão e a lista de API experimental nunca envelhecerem.
Fontes consultadas
- https://code.claude.com/docs/en/memory
- https://code.claude.com/docs/en/claude-directory
- https://angular.dev/cli/generate/ai-config
- https://angular.dev/ai/develop-with-ai
- https://angular.dev/ai
- https://angular.dev/ai/mcp
- https://angular.dev/guide/testing
- https://angular.dev/style-guide
- https://blog.angular.dev/announcing-angular-v21-57946c34f14b
Modern Angular Playbook
Este artigo é um play.
O Playbook do Angular Moderno reúne o diagnóstico, a matriz de adoção, onze jogadas e o plano de 30 dias. Grátis, em inglês e português.
Você recebe os dois PDFs por email, pela lista do Dojo IA.
André Ramosdisponível para vagas remotas, UTC−3Entre em contato →