Home / Claude Code / CwdChanged e FileChanged: Seu Claude Code Ainda Usa o .env Errado?

CwdChanged e FileChanged: Seu Claude Code Ainda Usa o .env Errado?

Eu perdi uma tarde inteira debugando um bug que não existia.

O problema? O Claude Code estava rodando com as variáveis de ambiente do projeto anterior. Eu tinha feito cd para outro repositório, mas o ambiente não acompanhou. A API apontava para staging enquanto eu jurava que estava em produção. O banco era outro. O token era de outro cliente.

Se você tem mais de um projeto na sua software house — e eu sei que você tem — já passou por isso. Talvez não com IA, mas com aquele dev júnior que rodou o script no ambiente errado. Ou com você mesmo às 23h tentando entregar antes do deploy de sexta.

A boa notícia: desde a versão 2.1.83, o Claude Code resolve isso com dois hooks que a maioria dos devs ainda não conhece. CwdChanged e FileChanged — o sistema de environment reativo que faz o Claude Code se adaptar automaticamente ao contexto.

O que são CwdChanged e FileChanged

Hooks no Claude Code são comandos que executam automaticamente em momentos específicos do ciclo de vida da ferramenta. Se você acompanha o blog, já falamos sobre HTTP Hooks para controle centralizado, StopFailure como alarme de incêndio e Conditional Hooks if para filtragem cirúrgica.

CwdChanged e FileChanged são diferentes dos hooks que controlam ferramentas. Eles não bloqueiam nem aprovam nada. Eles reagem ao ambiente — e é isso que os torna poderosos.

CwdChanged — reage quando o diretório muda

Dispara toda vez que o Claude Code muda de diretório de trabalho. Se o Claude executa um cd ../outro-projeto, o hook roda imediatamente. Você recebe o diretório anterior e o novo:

{

"hook_event_name": "CwdChanged",

"cwd": "/home/dev/projeto-b",

"previous_cwd": "/home/dev/projeto-a"

}

Não tem matcher — sempre dispara em qualquer mudança de diretório. É intencional. Mudança de diretório é um sinal forte de que o contexto mudou.

FileChanged — reage quando um arquivo muda no disco

Dispara quando um arquivo monitorado é criado, modificado ou deletado. Você escolhe quais arquivos monitorar pelo matcher:

{

"hooks": {

"FileChanged": [

{

"matcher": ".envrc|.env|.tool-versions",

"hooks": [

{

"type": "command",

"command": "/path/to/reload-env.sh"

}

]

}

]

}

}

O hook recebe o caminho completo do arquivo e o tipo de mudança (created, modified ou deleted). Se o Claude editou seu .env ou se você mudou manualmente — o hook pega.

Como funciona na prática

O segredo desses dois hooks está em uma variável de ambiente que a maioria dos devs desconhece: CLAUDE_ENV_FILE.

Quando um hook CwdChanged ou FileChanged roda, ele tem acesso a essa variável. É um caminho para um arquivo temporário que o Claude Code lê antes de cada comando Bash. Qualquer variável que você escrever nesse arquivo persiste para todos os comandos subsequentes da sessão.

O setup que toda software house deveria ter

Se sua equipe já usa direnv (e se não usa, deveria), a integração é uma linha:

{

"hooks": {

"CwdChanged": [

{

"hooks": [

{

"type": "command",

"command": "direnv export bash >> \"$CLAUDE_ENV_FILE\""

}

]

}

]

}

}

O que acontece: toda vez que o Claude muda de diretório, o direnv exporta as variáveis corretas daquele diretório e grava no CLAUDE_ENV_FILE. O próximo comando Bash que o Claude rodar já usa o ambiente certo.

Para projetos sem direnv

Se você não usa direnv mas tem .env por projeto, combina CwdChanged com FileChanged:

{

"hooks": {

"CwdChanged": [

{

"hooks": [

{

"type": "command",

"command": "if [ -f \"$PWD/.env\" ] && [ -n \"$CLAUDE_ENV_FILE\" ]; then cat \"$PWD/.env\" >> \"$CLAUDE_ENV_FILE\"; fi"

}

]

}

],

"FileChanged": [

{

"matcher": ".env|.envrc",

"hooks": [

{

"type": "command",

"command": "if [ -n \"$CLAUDE_ENV_FILE\" ]; then cat \"$(jq -r '.file_path' < /dev/stdin)\" >> \"$CLAUDE_ENV_FILE\"; fi"

}

]

}

]

}

}

Agora o Claude carrega o .env ao entrar num diretório e recarrega se alguém modificar o arquivo durante a sessão.

Monorepos: o cenário onde isso brilha

Na minha experiência com 300+ software houses, a maioria dos projetos modernos são monorepos ou multi-repos com contextos diferentes. Um repositório com:

/
├── apps/
│   ├── api/          → Node 20, DATABASE_URL=postgres://prod
│   ├── admin/        → Node 18, API_URL=http://localhost:3001
│   └── mobile-bff/   → Node 20, API_URL=http://localhost:3000
├── packages/
│   └── shared/       → sem variáveis específicas
└── infra/
└── terraform/    → AWS_PROFILE=production

Cada diretório tem seu próprio .env, sua versão de Node, suas credenciais. Sem CwdChanged, o Claude usa as variáveis do diretório onde você iniciou a sessão — para tudo. Com CwdChanged, ele se adapta a cada contexto automaticamente.

Por que isso importa para sua Software House

O custo invisível do .env errado

Quantas horas sua equipe já perdeu debugando problemas que eram, na verdade, variáveis de ambiente erradas? Na minha experiência, esse é um dos bugs mais frustrantes porque:

  • Não aparece no código — o código está correto, o ambiente que está errado
  • Não aparece no log — porque o log mostra que a operação executou, só no banco/API/serviço errado
  • Não é reproduzível por todos — porque cada dev tem um setup ligeiramente diferente

Um dado que me chocou: 96% das organizações sofrem com secrets sprawl — credenciais e configurações espalhadas por repositórios, arquivos de configuração e scripts de deploy sem controle centralizado. E 88% dos data breaches envolvem credenciais comprometidas.

CwdChanged e FileChanged não resolvem security diretamente, mas resolvem o problema raiz: garantir que o ambiente correto esteja ativo no momento correto.

Para times que usam Claude Code em automação

Se sua software house já usa Claude Code em pipelines — com o modo --bare ou headless — os hooks de environment management são ainda mais críticos. Um agent que roda tarefas em múltiplos diretórios precisa ter o ambiente correto em cada um.

Cenários reais:

  • Agent de code review que navega entre packages de um monorepo e precisa rodar testes com variáveis diferentes para cada um
  • Agent de migração que precisa acessar bancos diferentes conforme o diretório do microserviço
  • Agent de deploy que alterna entre ambientes staging/production conforme o diretório

O watchPaths: FileChanged dinâmico

Um detalhe que pouca gente sabe: o CwdChanged pode retornar watchPaths no stdout para configurar dinamicamente quais arquivos o FileChanged deve monitorar. Ou seja, ao mudar de diretório, você pode dizer “agora monitore esses arquivos específicos deste projeto”.

Isso é poderoso para monorepos onde cada subprojeto tem arquivos de configuração com nomes diferentes.

O que torna esses hooks especiais

Diferente dos hooks de ferramentas (PreToolUse, PostToolUse), CwdChanged e FileChanged não têm decision control. Eles não bloqueiam nem aprovam nada. Rodam puramente por efeitos colaterais — e é exatamente o que você quer para environment management.

Essa distinção arquitetural é importante:

  • Hooks de ferramenta: “Posso executar esse comando?” → decisão
  • Hooks de ambiente: “O contexto mudou” → adaptação

É a diferença entre um guarda e um sensor. O guarda decide se você passa. O sensor ajusta a temperatura quando você entra na sala.

Comparação: antes e depois

Cenário Sem hooks Com CwdChanged/FileChanged
cd para outro projeto Variáveis antigas persistem Environment recarregado automaticamente
.env editado manualmente Claude não percebe FileChanged recarrega instantaneamente
Monorepo com 5 services Mesmo ambiente para todos Ambiente correto por diretório
Agent navegando entre repos Bugs fantasma por variáveis erradas Zero intervenção manual
direnv já configurado Não funciona no Claude Code Integração nativa com 1 linha

O que eu penso

Na minha experiência mentorando mais de 300 software houses, environment management é um daqueles problemas que todo mundo tem mas ninguém resolve direito. Cada dev tem seu jeitinho, cada projeto tem sua convenção, e quando a IA entra no meio — rodando comandos em nome do dev — o problema multiplica.

CwdChanged e FileChanged são elegantes porque não inventam nada novo. Eles se plugam no que já existe: direnv, .env files, scripts de setup. A abordagem do Claude Code aqui é reativa, não prescritiva. Ele não te obriga a mudar seu workflow — ele se adapta ao seu workflow.

Se sua software house usa Claude Code para qualquer coisa além de perguntas simples, configure esses hooks. Leva 5 minutos. Economiza horas de debug por mês.

Como configurar em 5 minutos

  • Abra ~/.claude/settings.json (global) ou .claude/settings.json (por projeto)
  • Adicione o hook CwdChanged com direnv ou com leitura de .env
  • Adicione o hook FileChanged monitorando .env, .envrc, .tool-versions
  • Teste: abra o Claude Code, mude de diretório, e verifique com echo $MINHA_VARIAVEL

Se quiser ir além, combine com os Conditional Hooks if para filtrar quando os hooks devem processar variáveis sensíveis.

Se você quer implementar esse nível de automação inteligente na sua software house, com IA que realmente entende o contexto de cada projeto, a hora é agora. As ferramentas estão prontas — falta só configurar.

Sou Thulio, mentoro 300+ SHs desde 2016.

Marcado:

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *