Claude Code Hooks: automações que não dependem de prompt
Pedir no prompt é sugestão; hook é regra. Como usar os eventos do Claude Code para garantir formatação, bloquear comandos perigosos e rodar teste sem depender de o modelo lembrar.
O problema
Você pede "sempre rode o formatter depois de editar" e funciona nas primeiras vezes. Vinte mensagens depois, o modelo esquece. Instrução em prompt é probabilística. Se o comportamento precisa acontecer sempre, ele não pertence ao prompt, pertence à configuração.
Hook é um comando de shell que o Claude Code executa em pontos determinados do ciclo de vida da sessão. Ele roda sempre, independente do que o modelo decidiu fazer. É código, não intenção.
Onde fica a configuração
.claude/settings.json: versionado, vale para o time inteiro.claude/settings.local.json: só para você, fora do controle de versão~/.claude/settings.json: global, vale para todos os seus projetos
Os eventos
- PreToolUse: antes de executar uma ferramenta. É o único que consegue bloquear.
- PostToolUse: depois que a ferramenta rodou com sucesso.
- UserPromptSubmit: quando você envia uma mensagem; dá para injetar contexto.
- SessionStart: no início da sessão.
- Stop / SubagentStop: quando o agente termina de responder.
- PreCompact: antes de a conversa ser compactada.
Formatar depois de toda edição
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write --ignore-unknown $(jq -r '.tool_input.file_path')"
}
]
}
]
}
}O matcher é uma expressão regular sobre o nome da ferramenta. O hook recebe um JSON no stdin com o contexto da chamada. É daí que o jq lê .tool_input.file_path.
Bloquear antes de acontecer
Em PreToolUse, sair com código 2 cancela a chamada da ferramenta e devolve o stderr ao modelo como explicação. É assim que se cria uma trava que nenhum prompt derruba.
#!/usr/bin/env bash
# .claude/hooks/protege-env.sh
payload=$(cat)
caminho=$(echo "$payload" | jq -r '.tool_input.file_path // empty')
case "$caminho" in
*.env|*.env.*|*/secrets/*)
echo "Bloqueado: $caminho guarda credenciais. Edite manualmente." >&2
exit 2
;;
esac
exit 0{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": ".claude/hooks/protege-env.sh" }
]
}
]
}
}Onde isso vale a pena
O critério é um só: o comportamento pode falhar às vezes? Se puder, prompt resolve. Se não puder, vira hook.
- Formatter e linter depois de editar: não pode falhar
- Bloqueio de arquivo sensível: não pode falhar
- Rodar a suíte de testes ao encerrar a resposta: não pode falhar
- Escolher um nome de variável melhor: pode ficar no prompt
É a mesma lógica de qualquer automação de processo, e é por isso que este conteúdo está aqui e não numa categoria separada de IA: a decisão não é sobre o modelo, é sobre qual parte do processo precisa de garantia determinística.
Tecnologias e temas
Materiais
- RepositórioRepositório com os hooks deste conteúdosettings.json comentado + scripts prontosem breve
- DocumentoDocumentação oficial de hooks
Conteúdos relacionados
Estruturando dados antes de criar um agente de IA
Agente bom com dado bagunçado continua errando, só que com mais confiança. O checklist que aplicamos antes de escrever a primeira linha de um agente.
Power Apps: fórmulas na prática
As fórmulas que resolvem 90% dos apps internos, e as três armadilhas que fazem um app funcionar com 200 registros e travar com 3.000.