
Hooks do Claude Code: O Guia Completo para Programadores com Exemplos Prontos para Produção
O Claude Code é excelente a escrever código, mas continua a ser um sistema probabilístico. Pode pedir-lhe para executar o Prettier após cada edição de ficheiro. Pode colocar essa instrução no seu CLAUDE.md. E, por vezes, ele simplesmente... esquece-se. Os hooks do Claude Code resolvem isto, dando-lhe um controlo determinístico e garantido sobre o que acontece antes, durante e depois de cada ação que o Claude executa.
Tenho configurado hooks em dezenas de projetos nos últimos meses, e tornaram-se discretamente a parte mais importante da minha configuração do Claude Code. Este guia cobre tudo, desde os conceitos básicos até um kit inicial pronto para produção que pode usar em qualquer projeto hoje mesmo. Se já usou o Claude Code em conjunto com ferramentas como o Cursor ou o Copilot, já conhece o valor da personalização, os hooks levam isso ainda mais longe.
O que são os Hooks do Claude Code (e porque é que te deves preocupar)?
Os hooks do Claude Code são comandos de shell, endpoints HTTP ou prompts de LLM definidos pelo utilizador, executados automaticamente em pontos específicos do ciclo de vida do Claude Code. De acordo com a documentação oficial da Anthropic, ao contrário das instruções de prompt que o Claude pode ignorar, os hooks são acionados de forma determinística em todas as execuções, o que te garante controlo total sobre formatação, segurança, notificações e automação de fluxos de trabalho.
O Problema Probabilístico
A questão é esta quanto às instruções do CLAUDE.md: são sugestões, não contratos. Pode escrever "executa sempre npx prettier --write depois de editar ficheiros TypeScript" no contexto do seu projeto, e o Claude seguirá essa instrução na maioria das vezes. Mas "na maioria das vezes" não é suficiente quando se está a impor formatação de código a toda uma equipa, ou a bloquear pushes para produção, ou a registar cada comando de shell para uma auditoria de segurança.
Esta é a tensão central em qualquer ferramenta de programação com IA. O Claude é um modelo de linguagem — opera com base em probabilidades. A sua engenharia de contexto pode influenciar o comportamento, mas não o pode garantir.
Como os Hooks Resolvem Isto
Os hooks contornam completamente o LLM. São scripts de shell, chamadas HTTP ou avaliações de IA que são acionados em eventos específicos do ciclo de vida: antes de uma ferramenta ser executada (PreToolUse), depois de esta ser concluída (PostToolUse), quando surge uma notificação, quando uma sessão é iniciada ou quando o Claude para. Pensa neles como os hooks do Git, mas para o teu assistente de programação com IA.
Existem quatro tipos de hooks: command (scripts de shell), HTTP (pedidos POST de webhook), prompt (avaliações sim/não do Claude num único turno) e agent (gera um subagente com acesso a ferramentas). Vamos analisar cada um deles mais à frente — os hooks de command cobrem cerca de 90% do que vais precisar.
Como Funcionam os Hooks do Claude Code: O Fluxo do Ciclo de Vida
Os hooks do Claude Code são executados num ciclo de vida definido: um evento é acionado (por exemplo, PreToolUse), o matcher verifica se o hook se aplica, o script do hook é executado e recebe JSON em stdin, e o código de saída determina o que acontece a seguir. O código de saída 0 significa prosseguir, o código de saída 2 significa bloquear a ação. Este fluxo é o mesmo, independentemente do tipo de hook que está a utilizar.
Evento -> Matcher -> Hook -> Código de Saída (O Fluxo em 4 Passos)
É assim que funciona cada execução de um hook:
1. EVENT FIRES e.g., PreToolUse(Write)
|
2. MATCHER CHECKS Does "Write" match the hook's matcher pattern?
|
3. HOOK EXECUTES Shell script runs, receives JSON via stdin
|
4. EXIT CODE DECIDES 0 = proceed | 2 = block | other = errorO JSON que chega ao stdin contém tudo sobre o evento: o tool_name, o tool_input (caminho do ficheiro, conteúdo, comando) e os metadados da sessão. O teu script lê este JSON, executa a lógica que precisar e termina com o código apropriado.
Nos hooks PreToolUse, o código de saída 2 é o mais poderoso — bloqueia completamente a ação e devolve a tua mensagem de stdout ao Claude como feedback. O Claude vê a tua mensagem e pode ajustar a sua abordagem.
Âmbitos de configuração: utilizador, projeto e local
Os hooks encontram-se no settings.json em três níveis:
| Âmbito | Ficheiro | Comitado no Git? | Caso de utilização |
|---|---|---|---|
| Utilizador | ~/.claude/settings.json | Não | Predefinições pessoais (notificações, preferências de formatação) |
| Projeto | .claude/settings.json | Sim | Hooks partilhados pela equipa (proteção de ficheiros, executores de testes, linting) |
| Local | .claude/settings.local.json | Não (ignorado pelo git) | Substituições pessoais para este projeto |
As definições de projeto são as mais úteis para as equipas. Coloque os seus hooks em .claude/settings.json, faça commit e todos os programadores da equipa obtêm automaticamente as mesmas salvaguardas.
O campo if: Filtragem fina
Desde o Claude Code v2.1.85, os hooks suportam um campo if que permite filtrar pelos argumentos das ferramentas, e não apenas pelos seus nomes. Conforme documentado na referência de hooks da Anthropic, isto significa que pode escrever um hook que só é acionado em comandos Bash que correspondam a git push, em vez de ser disparado em todas as invocações de Bash.
{
"matcher": "Bash",
"if": "tool_input.command matches 'git push'",
"hooks": [{ "type": "command", "command": "./scripts/check-branch.sh" }]
}Isto representou uma grande melhoria. Antes do if, ou a correspondência era demasiado ampla (todos os comandos Bash) ou a filtragem era feita dentro do script (confuso).
Todos os Eventos de Hook do Claude Code: Tabela de Referência Rápida
O Claude Code disponibiliza mais de 20 eventos de hook ao longo do seu ciclo de vida, conforme documentado na referência oficial de hooks e no changelog do Claude Code. Os mais utilizados são PreToolUse, PostToolUse, Notification e Stop, mas eventos mais recentes como ConfigChange e FileChanged abrem portas a padrões avançados de automação.
Eis a referência completa:
| Evento | Quando é acionado | Pode bloquear? | Caso de uso comum |
|---|---|---|---|
| PreToolUse | Antes de uma ferramenta ser executada | Sim (exit 2) | Bloquear comandos perigosos, proteger ficheiros |
| PostToolUse | Depois de uma ferramenta concluir | Não | Formatação automática, execução de testes, registo de ações |
| Notification | Quando o Claude envia uma notificação | Não | Alertas no ambiente de trabalho, mensagens no Slack |
| Stop | Quando o Claude termina uma resposta | Não | Limpeza, geração de resumo |
| SessionStart | Na inicialização da sessão | Não | Injetar contexto, configurar o ambiente |
| UserPromptSubmit | Quando o utilizador submete um prompt | Sim (exit 2) | Validação de input, filtragem de conteúdo |
| PreCompact | Antes da compactação do contexto | Não | Guardar o estado antes de a memória ser reduzida |
| PostCompact | Depois da compactação do contexto | Não | Reinjetar contexto crítico |
| ConfigChange | Quando as definições mudam | Não | Hot-reload de variáveis de ambiente |
| FileChanged | Quando um ficheiro monitorizado muda | Não | Despoletar rebuilds, invalidar caches |
| TaskCreated | Quando uma nova tarefa é criada | Não | Acompanhamento de tarefas, alocação de recursos |
| PermissionDenied | Quando uma verificação de permissão falha | Não | Registo de auditoria, alerta sobre ações bloqueadas |
| WorktreeCreate | Quando uma nova worktree Git é criada | Não | Inicializar definições específicas da worktree |
| SubagentStart | Quando um subagente é iniciado | Não | Monitorizar a atividade do subagente |
| SubagentStop | Quando um subagente termina | Não | Validar o output do subagente |
Dica profissional: Irá usar PreToolUse e PostToolUse em 80% dos seus hooks. SessionStart é o mais útil a seguir, sendo perfeito para injetar o contexto do projeto de que o Claude precisa no início de cada sessão.
Os 4 Tipos de Hooks do Claude Code Explicados
O Claude Code suporta quatro tipos de handlers de hooks: os hooks de comando executam scripts de shell, os hooks HTTP fazem POST para URLs, os hooks de prompt fazem uma pergunta de sim/não ao Claude e os hooks de agente geram um subagente com acesso a ferramentas. Na nossa experiência, os hooks de comando cobrem 90% dos casos de uso. Use HTTP para integrações externas, e hooks de prompt e de agente para decisões mais complexas que exigem o julgamento da IA.
| Tipo | Velocidade | Complexidade | Mais Indicado Para | Exemplo |
|---|---|---|---|---|
| Comando | Rápida | Baixa | Formatação, bloqueio, registo | Executar o Prettier após editar um ficheiro |
| HTTP | Média | Média | Serviços externos, webhooks | POST para o Slack ao concluir |
| Prompt | Lenta | Média | Decisões subjetivas | "Este código é seguro para executar?" |
| Agente | Mais lenta | Alta | Verificação complexa com consciência dos ficheiros | Verificar se o código novo segue os padrões do projeto |
Hooks de Comando (O Cavalo de Batalha)
Os hooks de comando executam um comando de shell e utilizam o código de saída para determinar o resultado. Recebem os dados JSON do evento via stdin.
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "jq -r '.tool_input.command' | grep -q 'rm -rf /' && exit 2 || exit 0"
}]
}]
}
}É isto que vais usar para formatação, proteção de ficheiros, notificações e a maioria das automações. Rápido, simples e previsível.
HTTP Hooks (Integrações Externas)
Os HTTP hooks enviam um pedido POST para um URL com o JSON do evento como corpo. O código de estado da resposta determina o resultado (200 = prosseguir, 403 = bloquear).
{
"hooks": {
"Stop": [{
"matcher": "",
"hooks": [{
"type": "http",
"url": "https://your-api.com/claude-webhook"
}]
}]
}
}Ideal para enviar eventos para o Slack, Discord, PagerDuty ou um dashboard personalizado. Poderia ainda utilizar isto para consultar um motor de políticas externo antes de permitir a execução de uma ferramenta.
Prompt Hooks (Decisões Potenciadas por IA)
Os prompt hooks passam os dados do evento ao próprio Claude para uma avaliação de sim/não de turno único. O Claude devolve uma resposta JSON com \"decision\": \"allow\" ou \"decision\": \"block\", acompanhada do raciocínio.
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "prompt",
"prompt": "Is this bash command safe to run in a production environment? Consider: does it modify system files, delete data, or access sensitive credentials?"
}]
}]
}
}Utilize-os com moderação. Acrescentam latência (uma chamada LLM completa por cada execução de hook) e custo. Mas para verificações de segurança genuinamente subjetivas, como "esta migração de base de dados parece destrutiva?", são difíceis de superar. Se tiver curiosidade sobre mudar os modelos do Claude Code, o modelo utilizado para os prompt hooks segue o modelo da sua sessão atual.
Agent Hooks (Verificação Assistida por Ferramentas)
Os agent hooks geram um subagente com acesso às ferramentas Read, Grep e Glob. O subagente pode inspecionar ficheiros antes de tomar a sua decisão.
{
"hooks": {
"PreToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "agent",
"prompt": "Check if the file being written follows the project's naming conventions and import patterns. Read .claude/CONVENTIONS.md for the rules."
}]
}]
}
}Este é o tipo de hook mais poderoso, mas também o mais lento. Reserve-o para verificações de alto risco em que precise de contexto de ficheiros para tomar uma boa decisão.
7 Exemplos de Hooks do Claude Code Prontos para Produção (Prontos a Copiar e Colar)
Os hooks mais úteis do Claude Code incluem a formatação automática com o Prettier ou o Black após a edição de ficheiros, o bloqueio de escritas em ficheiros protegidos, o envio de notificações no ambiente de trabalho ao concluir uma tarefa, a injeção de contexto do projeto no início da sessão, a execução de testes após alterações ao código, a imposição de proteção de branches e a auditoria de toda a utilização de ferramentas. Tenho usado variações destes exemplos em todos os projetos nos últimos três meses.
Cada exemplo abaixo é um excerto completo de settings.json que pode colocar no seu .claude/settings.json. Coleções da comunidade como a awesome-claude-code têm ainda mais padrões.
1. Formatação automática ao guardar
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; esac; exit 0"
}]
}]
}
}Isto é acionado após cada Write ou Edit, extrai o caminho do ficheiro do JSON do stdin e executa o formatador adequado. O exit 0 no final garante que o hook nunca bloqueia — as falhas de formatação não devem impedir o Claude.
Dica profissional: Adiciona *.go com gofmt e *.rs com rustfmt se trabalhares em várias linguagens.
2. Bloquear Escritas em Ficheiros Protegidos
{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit",
"if": "tool_input.file_path matches '(\\.env|\\.env\\.local|package-lock\\.json|yarn\\.lock|pnpm-lock\\.yaml)'",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"BLOCKED: This file is protected. Edit it manually.\"}' && exit 2"
}]
}]
}
}O código de saída 2 bloqueia a ação e envia a mensagem JSON de volta ao Claude. O Claude vê o feedback e ajusta-se — por norma, informa-o de que pretendia modificar o ficheiro e pede-lhe que o faça manualmente. O campo if impede que isto seja acionado em cada Write.
3. Notificação de ambiente de trabalho ao concluir
{
"hooks": {
"Notification": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "MSG=$(jq -r '.message // \"Claude Code task finished\"' /dev/stdin); if [ \"$(uname)\" = 'Darwin' ]; then osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\"; else notify-send 'Claude Code' \"$MSG\"; fi; exit 0"
}]
}]
}
}Funciona no macOS (osascript) e no Linux (notify-send). O matcher vazio significa que é acionado em todas as notificações. Isto é genuinamente útil quando inicia uma tarefa longa e muda para outra janela.
4. Injeção de Contexto no Início da Sessão
{
"hooks": {
"SessionStart": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null || echo none)\"' | Last commit: '\"$(git log --oneline -1 2>/dev/null || echo none)\"'\"}'; exit 0"
}]
}]
}
}Isto injeta o nome do projeto atual, o branch do Git e o último commit em cada sessão. O Claude recebe este contexto automaticamente, sem que seja necessário indicar-lhe em que branch se encontra.
5. Executar Testes Automaticamente Após Alterações de Código
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"if": "tool_input.file_path matches '\\.(ts|tsx|js|jsx|py)$'",
"hooks": [{
"type": "command",
"command": "FILE=$(jq -r '.tool_input.file_path' /dev/stdin); TEST_FILE=$(echo \"$FILE\" | sed 's/\\.[^.]*$/.test&/'); if [ -f \"$TEST_FILE\" ]; then npx jest \"$TEST_FILE\" --no-coverage 2>&1 | tail -5; fi; exit 0",
"timeout": 30000
}]
}]
}
}Se existir um ficheiro de teste correspondente, este é executado automaticamente depois de o Claude editar o código-fonte. O tail -5 mantém o output conciso, e o timeout impede que as suites de teste fujam ao controlo. Isto combina bem com um fluxo de trabalho de revisão de código com IA.
6. Aplicação de Proteção de Branch (Avançado)
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"if": "tool_input.command matches 'git push.*(main|master|production)'",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"BLOCKED: Direct push to protected branch. Use a feature branch and open a PR.\"}' && exit 2"
}]
}]
}
}Isto bloqueia qualquer git push que tenha como destino os branches main, master ou production. O Claude recebe o feedback e sugerirá a criação de um branch de funcionalidade em alternativa.
7. Registo de Auditoria de Segurança (Avançado)
{
"hooks": {
"PostToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "INPUT=$(cat /dev/stdin); CMD=$(echo \"$INPUT\" | jq -r '.tool_input.command'); echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] BASH: $CMD\" >> .claude/audit.log; exit 0"
}]
}]
}
}Regista todos os comandos Bash que o Claude executa num ficheiro de auditoria com um carimbo temporal UTC. Inestimável para revisões de segurança e para compreender o que o Claude realmente fez durante uma sessão. Mantenha .claude/audit.log no seu .gitignore.
Hooks vs. MCP vs. Skills vs. CLAUDE.md: Quando Usar Cada Um
Use hooks para automação determinística que deve ser sempre executada (formatação, bloqueio, notificações). Use MCP para dar ao Claude acesso a ferramentas e dados externos. Use Skills para pacotes de prompts reutilizáveis. Use CLAUDE.md para orientação comportamental e contexto do projeto. Os hooks são garantidos; tudo o resto é probabilístico. Esta é a distinção mais importante de todas, e é a ela que volto sempre quando aconselho equipas.
A Matriz de Decisão
| Mecanismo | Determinístico? | Quando é Executado | Mais Indicado Para | Exemplo |
|---|---|---|---|---|
| Hooks | Sim | Automaticamente em eventos de ciclo de vida | Aplicação de regras, automação, notificações | Formatação automática, bloqueio de escrita de ficheiros |
| MCP | Não (o Claude decide) | Quando o Claude chama a ferramenta MCP | Novas funcionalidades, acesso a dados externos | Consultar uma base de dados, pesquisar no Notion |
| Skills | Não (o utilizador aciona) | Quando o utilizador invoca um comando de barra | Conjuntos de instruções reutilizáveis | /review para um fluxo de revisão de código |
| CLAUDE.md | Não (orientação) | Lido no início da sessão | Contexto do projeto, normas de programação | "Use Tailwind, escreva testes para todo o código novo" |
Para uma análise aprofundada sobre o MCP, consulte o nosso guia de MCP. Se vem do Cursor, o sistema de regras do Cursor é aproximadamente análogo ao CLAUDE.md, mas o Cursor não tem nada semelhante a hooks.
Quando se Sobrepõem (e Como Escolher)
Aqui está o fluxograma que uso:
- "Isto PRECISA de acontecer sempre, sem exceções?", Hook. Formatar código, bloquear ficheiros protegidos, enviar notificações. Zero ambiguidade.
- "O Claude precisa de uma nova CAPACIDADE que não tem?", servidor MCP. Aceder a uma base de dados, chamar uma API, pesquisar documentação externa.
- "Quero INSTRUÇÕES reutilizáveis para um fluxo de trabalho específico?", Skill (comando slash). Modelos de revisão de código, checklists de implementação.
- "Quero moldar o COMPORTAMENTO do Claude neste projeto?", CLAUDE.md. Normas de código, decisões de arquitetura, bibliotecas preferidas.
Exemplos reais que esclarecem a fronteira:
- "Formatar sempre com Prettier" = Hook (tem de acontecer sempre)
- "Usar Prettier para formatação" no CLAUDE.md = Orientação (o Claude pode esquecer-se)
- "Pesquisar a documentação da nossa empresa" = MCP (nova capacidade)
- "Seguir o nosso guia de estilo ao rever código" = Skill ou CLAUDE.md
Conforme descrito no anúncio de plugins da Anthropic, os hooks são uma peça de um ecossistema de plugins mais vasto que também inclui MCP e Skills. Foram concebidos para se complementarem, não para competirem.
O Kit Inicial: Configuração de Hooks do Claude Code Pronta a Usar em Qualquer Projeto
Uma configuração inicial de hooks para o Claude Code deve incluir formatação automática ao editar ficheiros, notificação ao concluir tarefas, proteção de ficheiros sensíveis, injeção de contexto de sessão e um hook de paragem para limpeza. É exatamente esta a configuração que uso em todos os projetos novos, adaptada à stack, mas a estrutura mantém-se sempre a mesma.
A Configuração
{
"hooks": {
"SessionStart": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null)\"' | Node: '\"$(node -v 2>/dev/null)\"'\"}'; exit 0"
}]
}],
"PreToolUse": [{
"matcher": "Write|Edit",
"if": "tool_input.file_path matches '(\\.env|\\.env\\..+|.*lock\\.json|.*lock\\.yaml)'",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"Protected file. Edit manually.\"}' && exit 2"
}]
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; *.go) gofmt -w \"$FILE\" 2>/dev/null;; esac; exit 0"
}]
}],
"Notification": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "MSG=$(jq -r '.message // \"Done\"' /dev/stdin); osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\" 2>/dev/null || notify-send 'Claude Code' \"$MSG\" 2>/dev/null; exit 0"
}]
}],
"Stop": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '[STOP] '\"$(date +%H:%M:%S)\"'' >> .claude/session.log; exit 0"
}]
}]
}
}Como Personalizar para a Sua Stack
| Stack | Comando de Formatação | Comando de Teste | Extensões de Monitorização |
|---|---|---|---|
| Node/TypeScript | npx prettier --write | npx jest --no-coverage | .ts, .tsx, .js, .jsx |
| Python | black | pytest -x | .py |
| Go | gofmt -w | go test ./... | .go |
| Rust | rustfmt | cargo test | .rs |
Substitua os comandos de formatação e de teste na configuração acima para corresponder à sua stack. A estrutura mantém-se idêntica.
Verificar que os Hooks Funcionam
Três formas de confirmar que os hooks estão ativos:
- Comando
/hooks, Escreva/hooksno Claude Code para ver todos os hooks registados, os seus matchers e o seu estado. - Inspeção da transcrição, Depois de um hook ser acionado, verifique a transcrição da sessão. As execuções dos hooks aparecem com o seu output e código de saída.
- Interruptor rápido, Adicione
"disableAllHooks": trueao seu settings.json para desativar temporariamente todos os hooks sem eliminar a configuração. Remova-o (ou defina comofalse) para os reativar.
Integração de CI/CD: Hooks do Claude Code em Modo Headless
Os hooks do Claude Code funcionam em modo headless (claude -p) com algumas diferenças: os hooks de Notificação continuam a ser acionados, mas deve redirecioná-los para registo (logging) em vez de alertas no ambiente de trabalho. Os hooks PreToolUse com código de saída 2 podem pausar sessões headless para revisão humana. O GitHub Actions utiliza anthropics/claude-code-action@v1 em conjunto com hooks para fluxos de trabalho automatizados.
Comportamento do Modo Headless
| Evento do Hook | Modo Interativo | Modo Headless (-p) | Recomendação para CI |
|---|---|---|---|
| PreToolUse (saída 2) | Bloqueia e mostra a mensagem | Pausa a aguardar --resume | Usar para aprovações humanas obrigatórias |
| PostToolUse | Executa normalmente | Executa normalmente | Manter formatadores e loggers |
| Notification | Alerta no ambiente de trabalho | Continua a disparar (sem UI) | Redirecionar para ficheiro de log ou webhook do Slack |
| Stop | Executa a limpeza | Executa a limpeza | Bom para recolha de artefactos de CI |
| SessionStart | Injeta contexto | Injeta contexto | Injetar variáveis de ambiente de CI |
A grande surpresa no modo headless: os hooks PreToolUse que terminam com o código 2 não falham simplesmente em silêncio. Pausam a sessão e permitem retomá-la com --resume, o que oferece um padrão human-in-the-loop para pipelines de CI.
Integração com o GitHub Actions
Aqui está um workflow mínimo do GitHub Actions que utiliza o Claude Code com hooks. Conforme documentado no guia oficial do GitHub Actions:
- name: Run Claude Code
uses: anthropics/claude-code-action@v1
with:
prompt: "Review this PR and suggest improvements"
allowed_tools: "Read,Grep,Glob"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}Os hooks do seu .claude/settings.json acompanham o repositório, pelo que serão acionados em CI exatamente como são localmente. Certifique-se apenas de que quaisquer hooks que dependam de ferramentas específicas do desktop (como osascript) tenham alternativas ou condicionais.
Gestão de Hooks da Equipa
Um padrão que funciona bem para equipas:
.claude/settings.json(confirmado), Hooks partilhados pela equipa: proteção de ficheiros, formatadores, proteção de branches. Todos recebem estes..claude/settings.local.json(ignorado no git), Hooks pessoais: preferências de notificação, registo personalizado, hooks experimentais.~/.claude/settings.json(global do utilizador), As suas predefinições em todos os projetos: estilo de notificação, preferências pessoais de formatação.
Isto reflete o funcionamento do .editorconfig (confirmado) e das definições locais do IDE (pessoais). Como observado no guia de CI/CD de Angelo Lima, as equipas que padronizam em hooks partilhados encontram menos problemas de "funciona na minha máquina" com o Claude Code.
Resolução de Problemas com Hooks do Claude Code e Erros Comuns
Os problemas mais comuns com os hooks do Claude Code incluem hooks que não são acionados (verifique a ortografia do matcher e a localização do settings.json), hooks que são executados mas não bloqueiam (código de saída incorreto, use 2 e não 1), ciclos infinitos (o hook Stop a acionar-se a si próprio) e arranque lento (demasiados hooks síncronos). O erro mais comum que vejo é a confusão com os códigos de saída: os programadores usam exit 1 quando querem dizer exit 2.
O Hook Não Dispara
Sintomas: Adicionaste um hook, mas nada acontece quando o evento ocorre.
Correções:
- Erro no matcher, Os matchers são sensíveis a maiúsculas/minúsculas.
"write"não corresponde à ferramentaWrite. Verifica os nomes exatos das ferramentas com/hooks. - Ficheiro de definições errado, Os hooks em
~/.claude/settings.jsonnão aparecem no output de/hookspara o âmbito do projeto. Experimenta.claude/settings.jsonna raiz do projeto. - Erro de sintaxe JSON, Uma vírgula a mais ou um parêntesis em falta desativa silenciosamente toda a configuração de hooks. Valida o teu settings.json com
jq .. disableAllHooks: true, Verifica se alguém (ou uma sessão de depuração anterior) deixou esta flag ativada.
O Hook é Executado mas Não Bloqueia
Sintomas: O seu hook PreToolUse é executado, mas a ação avança na mesma.
Correções:
- Código de saída incorreto: O código de saída 1 significa "erro" (o hook falhou), não "bloqueio". Use
exit 2para bloquear uma ação. Isto confunde quase toda a gente, conforme indicado na documentação oficial. - JSON em falta no stdout: Para hooks de bloqueio, devolva uma mensagem JSON para que o Claude saiba por que razão a ação foi bloqueada:
echo '{"message": "Blocked: reason"}'
Ciclos Infinitos
Sintomas: O Claude continua a repetir a mesma ação, ou a tua máquina aquece de forma suspeita.
Soluções:
- Hook Stop a desencadear ações, Se o teu hook Stop escrever um ficheiro ou executar um comando que faça o Claude responder, criaste um ciclo. Os hooks Stop devem apenas fazer coisas passivas: registar, notificar, limpar.
- Hook PostToolUse a causar edições, Um hook PostToolUse que modifique um ficheiro desencadeia outro evento PostToolUse. Evita isto com matchers específicos ou com o campo
if.
Problemas de desempenho
Sintomas: O Claude demora visivelmente mais tempo a iniciar ou a executar ferramentas.
Correções:
- Demasiados hooks SessionStart, cada um é executado de forma síncrona no arranque. Mantenha-os leves (menos de 1 segundo cada).
- Scripts pesados em caminhos críticos, os hooks em PreToolUse e PostToolUse são acionados com frequência. Se o seu script fizer pedidos de rede ou cálculos pesados, adicione um campo
timeout(milissegundos) e considere se não deverá ser antes um hook HTTP. - Sem cache, se estiver a verificar a mesma coisa repetidamente (como "este branch é protegido?"), guarde o resultado em cache num ficheiro temporário em vez de executar comandos Git em cada invocação de hook.
Perguntas Frequentes
O que são hooks do Claude Code e como funcionam?
Os hooks do Claude Code são scripts de automação definidos pelo utilizador que são executados em eventos específicos do ciclo de vida durante uma sessão do Claude Code. São configurados no settings.json com um padrão de correspondência e um handler (comando shell, endpoint HTTP, prompt ou agente). Quando o evento correspondente é acionado, o hook é executado automaticamente e utiliza códigos de saída para controlar o resultado.
Como configuro os hooks no settings.json do Claude Code?
Adicione um objeto \"hooks\" a qualquer um dos três locais de configuração: ~/.claude/settings.json (global do utilizador), .claude/settings.json (partilhado do projeto) ou .claude/settings.local.json (pessoal do projeto). Cada tipo de evento é mapeado para um array de definições de hook com matcher, um campo if opcional e um array hooks que contém objetos handler com type e command ou url.
Qual é a diferença entre os hooks PreToolUse e PostToolUse?
O PreToolUse é acionado antes de uma ferramenta ser executada, dando-lhe a capacidade de a bloquear com o código de saída 2. O PostToolUse é acionado após a conclusão da execução, sendo útil para formatação, testes ou registo. O PreToolUse destina-se à prevenção e ao controlo de acesso. O PostToolUse destina-se à validação e à limpeza. Ambos recebem o nome da ferramenta e a entrada em JSON através do stdin.
Os hooks do Claude Code conseguem bloquear comandos perigosos?
Sim. Os hooks PreToolUse com código de saída 2 bloqueiam qualquer execução de ferramentas. Pode proteger ficheiros sensíveis contra escrita, bloquear comandos de shell que correspondam a padrões perigosos como rm -rf ou git push main, e impedir o acesso a bases de dados de produção. A mensagem de bloqueio é devolvida ao Claude como feedback, para que possa ajustar a sua abordagem.
Que eventos de hook estão disponíveis no Claude Code?
O Claude Code disponibiliza mais de 15 eventos: PreToolUse e PostToolUse para execução de ferramentas, Notification para alertas, Stop para o fim da sessão, SessionStart para inicialização, UserPromptSubmit para filtragem de input, PreCompact e PostCompact para gestão de contexto, e eventos mais recentes como ConfigChange, FileChanged, TaskCreated e PermissionDenied. Consulte a tabela de referência completa na secção de eventos de hook acima.
Em que diferem os hooks das ferramentas MCP e das Skills?
Os hooks são determinísticos — disparam sempre em eventos correspondentes, independentemente do que o Claude decidir. As ferramentas MCP expandem as capacidades do Claude (acesso a bases de dados, chamadas de API), mas é o Claude que escolhe quando as utilizar. As Skills são pacotes de instruções reutilizáveis, invocados através de comandos de barra. O CLAUDE.md fornece orientações comportamentais. Utilize hooks quando algo tem de acontecer sempre, e MCP quando o Claude precisa de novas capacidades.
Os hooks do Claude Code funcionam em modo headless?
Sim, com algumas ressalvas. Os hooks são acionados normalmente em modo headless (claude -p), mas hooks específicos do ambiente de trabalho, como as notificações do macOS, necessitam de mecanismos de recurso. Importa referir que os hooks PreToolUse que terminam com o código 2 podem pausar sessões headless para aprovação humana através de --resume. Isto possibilita pipelines de CI/CD com intervenção humana (human-in-the-loop), em que determinadas ações requerem validação manual.
Quantos hooks são demasiados? Os hooks tornam o Claude Code mais lento?
Não existe um limite rígido, mas cada hook síncrono acrescenta latência. Os hooks de SessionStart são executados no arranque, por isso devem ser rápidos (menos de 1 segundo cada). Os hooks PreToolUse e PostToolUse são acionados em cada chamada de ferramenta correspondente — scripts pesados aqui acumulam-se rapidamente. Recomendo manter o total de hooks abaixo de 10 a 15, usar o campo if para restringir o âmbito e adicionar valores de timeout para evitar scripts descontrolados.
Posso usar hooks para formatar automaticamente o código com o Prettier ou o Black?
Sim, é o caso de uso mais popular dos hooks. Crie um hook PostToolUse que corresponda a Write|Edit, extraia o caminho do ficheiro a partir do JSON do stdin e execute o formatador adequado com base na extensão do ficheiro. Consulte o exemplo número um na secção de exemplos de produção para uma configuração completa, pronta a copiar e colar, que processa ficheiros TypeScript, JavaScript e Python.
Os hooks do Claude Code são seguros? Quais são os riscos de segurança?
Os hooks são executados com as suas permissões completas de utilizador, não existe qualquer sandbox. Um hook malicioso pode ler as suas chaves SSH, eliminar ficheiros ou exfiltrar dados. Utilize apenas hooks de fontes de confiança, reveja qualquer .claude/settings.json partilhado antes de o aceitar no seu projeto e utilize .claude/settings.local.json para hooks pessoais que não devam ser partilhados. Para padrões mais abrangentes de segurança de IA, consulte o nosso guia de guardrails de LLM.