Conteúdo
"Quero formatação automática depois de cada edição." "Nunca deixe nada reescrever .env ou package-lock.json." "Bloqueie comandos perigosos como rm -rf." A forma de tornar reais essas regras de "isto precisa sempre acontecer" — sem depender dos caprichos da IA — são os hooks do Claude Code. Um hook é um comando de shell que roda automaticamente em pontos específicos do ciclo de vida do Claude Code, e os hooks também são um bloco de construção dos plugins.
Este artigo apresenta, com base na documentação oficial, o que são os hooks, a lista de eventos, como configurá-los, o contrato de entrada/saída, casos de uso e segurança. Três pontos antes de começar. ① Um hook é "lógica determinística que o harness (o próprio Claude Code) executa" — ele dispara com certeza, sem esperar que o modelo "decida" fazê-lo. ② Você escreve os hooks em settings.json como nome do evento → matcher → command. ③ Eventos como PreToolUse podem "bloquear" via código de saída 2 ou JSON — impedindo edições em arquivos protegidos ou comandos perigosos.
Dispara "com certeza" em pontos-chave do ciclo de vida
— o harness o executa de forma determinística, não o julgamento do modelo
SessionStart
A sessão começa. A saída é injetada como contexto
UserPromptSubmit
Quando um prompt é enviado [pode bloquear]
PreToolUse
Logo antes de uma ferramenta rodar = o porteiro [pode bloquear]
PostToolUse
Após uma ferramenta ter sucesso = formatação automática / auditoria
Stop
Quando uma resposta termina = continuar até os testes passarem, etc. [pode bloquear]
Em cada ponto, seu comando de shell é executado. Os clássicos: PreToolUse para barrar ações perigosas logo na porta, PostToolUse para formatação automática.
1. O que são os hooks do Claude Code?
A definição oficial diz: "Hooks são comandos de shell definidos pelo usuário que são executados em pontos específicos do ciclo de vida do Claude Code. Eles oferecem controle determinístico sobre o comportamento do Claude Code, garantindo que certas ações sempre aconteçam, em vez de depender de o LLM escolher executá-las." Você os usa para impor regras de projeto, automatizar tarefas repetitivas e integrar o Claude Code às suas ferramentas existentes.
O cerne é o determinismo. Peça ao Claude para "rodar os testes" e se ele o fará depende do seu "julgamento". Mas com um hook, o harness sempre o executa — nenhum capricho entra em jogo. Além dos comandos (command), agora também há tipos de handler como HTTP, ferramentas MCP, prompts de LLM e verificação por subagente — mas, para começar, basta pensar nos hooks como "um mecanismo para sempre rodar um comando de shell em pontos-chave".
2. Os eventos de hook
Um evento representa "onde no ciclo de vida ele dispara". Comece pelos nove clássicos ("pode bloquear" = você pode interromper essa ação via código de saída 2 ou JSON).
| Evento | Dispara quando | Bloqueia |
|---|---|---|
| SessionStart | Uma sessão começa ou é retomada (a stdout é injetada como contexto) | Não |
| UserPromptSubmit | Você envia um prompt, antes de o Claude processá-lo | Sim |
| PreToolUse | Logo antes de uma chamada de ferramenta (o porteiro principal) | Sim |
| PostToolUse | Após uma ferramenta ter sucesso (a ação em si não pode ser desfeita) | Sim |
| Notification | Em uma notificação (aguardando entrada/permissão, etc.) | Não |
| Stop | Quando o Claude termina de responder (bloquear = continuar trabalhando) | Sim |
| SubagentStop | Quando um subagente termina | Sim |
| SessionEnd | Quando uma sessão é encerrada | Não |
| PreCompact | Antes da compactação do contexto | Sim |
A documentação de 2026 adiciona muitos outros eventos — PermissionRequest, PostToolUseFailure, ConfigChange, FileChanged, WorktreeCreate, entre outros. Mas os nomes dos eventos podem ser adicionados ou alterados entre versões, então este artigo se ancora nos nove clássicos estáveis mais o contrato da próxima seção (consulte a documentação oficial para a lista atual completa).
3. Como configurar hooks
Você escreve os hooks sob a chave "hooks" em settings.json. A localização define o escopo: usuário (~/.claude/settings.json) / projeto (.claude/settings.json, compartilhável via git) / local (.claude/settings.local.json) / política gerenciada (organização) / o hooks/hooks.json de um plugin. O formato do JSON é assim.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
A estrutura é "hooks → nome do evento → um array de { matcher, hooks:[...] } → cada hook tem type + command." O matcher especifica o nome da ferramenta alvo: "*" (ou omitido) corresponde a todas, "Edit|Write" é uma lista separada por |, e outros caracteres são regex (p. ex. mcp__memory__.*). Diferencia maiúsculas de minúsculas. O comando /hooks lista os hooks configurados, mas é somente leitura — para adicionar ou alterar, edite settings.json diretamente. Desative todos com "disableAllHooks": true.
4. O contrato de entrada/saída
Um hook recebe JSON na entrada padrão (stdin) e retorna seu resultado via código de saída ou JSON na saída padrão.
Entrada (stdin): os campos comuns incluem session_id, transcript_path, cwd e hook_event_name. Eventos de ferramenta adicionam tool_name e tool_input (p. ex. {"command":"rm -rf /tmp/build"}); UserPromptSubmit adiciona prompt. Códigos de saída: 0 = sucesso (para alguns eventos, a stdout é adicionada ao contexto — embora código de saída 0 em PreToolUse não seja uma "aprovação"; o fluxo normal de permissão ainda se aplica), 2 = bloquear (a stderr é passada ao Claude como material para ajuste, e a saída JSON é ignorada).
# Exemplo: "deny" do PreToolUse via saída JSON estruturada (impressa na stdout)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Database writes are not allowed"
}
}
# Campos comuns: continue (false = parar totalmente) / decision:"block"+reason /
# additionalContext (anexado para o Claude) / updatedInput (reescrever args)
O princípio mais importante: "os hooks podem apertar restrições, mas não afrouxá-las". Retornar allow apenas pula o prompt; regras de deny em qualquer escopo (inclusive nas configurações gerenciadas) sempre têm precedência. Um deny de PreToolUse bloqueia até mesmo sob bypassPermissions / --dangerously-skip-permissions. Para o modelo de permissão mais amplo, veja modos de permissão e segurança.
5. Exemplos de uso
Os clássicos oficiais, acompanhados de sua configuração.
As automações clássicas
PostToolUse + Edit|Write roda prettier / um linter automaticamente.PreToolUse bloqueia (exit 2) edições em .env, .git/, etc.PreToolUse detecta rm -rf etc. e retorna deny.SessionStart recarrega convenções e notas toda vez (mesmo após a compactação).Notification para alertas de desktop; PostToolUse para registrar o histórico de comandos.Stop não deixa o Claude parar até os testes passarem (continuar trabalhando até ficar verde).
Observação: o Claude também pode alterar arquivos via Bash. Para capturar toda alteração, adicione um hook Stop que examine a árvore de trabalho uma vez por turno.
6. Segurança
Os hooks são poderosos, mas executam comandos de shell arbitrários automaticamente com os seus privilégios — não leve isso na brincadeira.
⚠️ O aviso oficial
"Os hooks executam comandos de shell arbitrários automaticamente. Você é o único responsável pela segurança dos hooks que configura. USE POR SUA CONTA E RISCO." Os hooks podem ler arquivos, modificar seu código-fonte, exfiltrar dados ou rodar qualquer comando — configure apenas aqueles em que você confia plenamente.
Snapshot na inicialização (um recurso de segurança fundamental): a configuração dos hooks é capturada no início da sessão, então alterações de configuração no meio da sessão não têm efeito. Isso impede que um prompt malicioso ou a saída de uma ferramenta reescreva a sua configuração de hook durante uma sessão. Aplique as alterações em uma nova sessão.
Na prática: sempre valide e coloque entre aspas as entradas (extraia com jq; variáveis sem aspas podem virar argumentos extras ou sintaxe de shell), use caminhos absolutos e ${CLAUDE_PROJECT_DIR}, não mexa em arquivos sensíveis como .env ou .ssh, e nunca faça eval da saída de ferramentas. Os hooks rodam sem um terminal de controle (sem /dev/tty). Em organizações, os administradores podem restringir os hooks com allowManagedHooksOnly.
Resumo
Os hooks do Claude Code são comandos de shell definidos pelo usuário que rodam automaticamente em pontos-chave do ciclo de vida, tornando o "isto precisa sempre acontecer" real e determinístico sem depender do julgamento do modelo. Os eventos clássicos são nove: SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / Notification / Stop / SubagentStop / SessionEnd / PreCompact (PreToolUse e outros podem bloquear — impedindo edições em arquivos protegidos ou comandos perigosos). Você os configura em settings.json sob "hooks" como evento → matcher → type + command.
A E/S é JSON na stdin, código de saída 0 (sucesso) / 2 (bloquear), ou JSON estruturado na stdout. O princípio: "você pode apertar, mas não afrouxar restrições" (deny sempre vence). Os casos de uso clássicos: formatação automática, proteger arquivos, bloquear comandos perigosos, reinjetar contexto, auditoria e testar antes de parar. Mas, como eles rodam código arbitrário, seja rigoroso em confiar apenas em hooks seguros e validar/colocar entre aspas as entradas, e entenda que a configuração é capturada na inicialização. Relacionados: plugins, MCP, erros do Claude Code.
FAQ
Q. Para que servem os hooks?
A. Eles automatizam de forma determinística o "isto precisa sempre acontecer". Coisas como "formatar após edições", "nunca deixar arquivos protegidos serem reescritos", "bloquear o perigoso rm -rf" e "passar nos testes antes de parar" são executadas com certeza pelo harness, sem depender do julgamento da IA. Um hook é um comando de shell que roda em pontos-chave do ciclo de vida, configurado em settings.json.
Q. Quais eventos (momentos) existem?
A. Os clássicos são nove: SessionStart (início), UserPromptSubmit (ao enviar), PreToolUse (logo antes de uma ferramenta), PostToolUse (após uma ferramenta), Notification, Stop (fim da resposta), SubagentStop, SessionEnd (encerramento), PreCompact (antes da compactação). Destes, PreToolUse, UserPromptSubmit, Stop, PreCompact e outros podem bloquear e interromper a ação. A versão de 2026 adiciona muitos outros eventos, mas os nomes podem mudar entre versões, então consulte a documentação oficial para a versão mais recente.
Q. Posso impedir edições em arquivos protegidos ou comandos perigosos?
A. Sim — com um hook PreToolUse. Um script inspeciona o caminho do arquivo ou o comando em tool_input, e se ele corresponder a .env, rm -rf, etc., retorna código de saída 2 (ou JSON com permissionDecision:"deny") para bloqueá-lo. Crucialmente, o deny sempre tem precedência e bloqueia até mesmo sob bypassPermissions. Os hooks só funcionam na direção de "apertar restrições".
Q. Alterei minha configuração, mas ela não está fazendo efeito.
A. Isso é intencional (um recurso de segurança). A configuração dos hooks é capturada como um snapshot no início da sessão, então alterações no meio da sessão não se aplicam. Isso impede que um prompt malicioso ou a saída de uma ferramenta reescreva silenciosamente a sua configuração de hook. Inicie uma nova sessão para aplicá-la. Note que /hooks é uma lista somente leitura; adicione ou altere hooks editando settings.json diretamente.
Q. Os hooks são seguros?
A. Não incondicionalmente. Os hooks executam comandos de shell arbitrários com os seus privilégios, e é por isso que a documentação diz "use por sua conta e risco". Configure apenas hooks em que você confia, valide e coloque entre aspas as entradas com jq, use caminhos absolutos e não mexa em .env / .ssh, e nunca faça eval da saída de ferramentas. Em organizações, os administradores podem restringir os hooks com allowManagedHooksOnly.