NeuralOS
GuideAdvanced

Hooks do Claude Code · automatize seu fluxo com os eventos do ciclo de vida do agente

Você já sabe escrever um bom contrato para o seu agente: você diz a ele no AGENTS.md como quer que ele trabalhe. O problema é que um LLM lê esse contrato e decide de novo a cada turno — então a regra crítica é cumprida quase sempre, e esse \"quase\" é justamente o que te morde. Os hooks são o degrau seguinte: você tira a regra da cabeça do modelo e a coloca na infraestrutura, para que aconteça 100% das vezes sem depender do critério dele. Vou te explicar os eventos do ciclo de vida onde você engancha, a anatomia do JSON, onde vive cada hook e por que importa, e te deixo três hooks reais prontos para colar (autoformatação, bloqueio de comandos perigosos, notificação de desktop) tirados da documentação oficial da Anthropic. Um único prompt mestre para montar o seu primeiro com a segurança posta — porque um hook roda shell com as suas permissões. É o salto de \"escreva o contrato\" para \"faça o contrato se executar sozinho\".

Jul 19, 202614 min
Para quem é isto?
Para você, que já constrói com IA no Claude Code e passa semanas repetindo a mesma frase: "lembre de formatar", "não mexa no .env", "rode os testes antes de commitar". Você esquece, a IA esquece, e um dia entra uma mudança que não devia. Os hooks são o salto de "peço que ela lembre" para "acontece sempre, mesmo que ninguém lembre". Você não precisa ser programador: precisa entender um padrão e copiar três blocos de JSON.

1. O momento · quando você descobre que "pedir para a IA" não basta

Chega um ponto em todo projeto com IA em que você para de confiar na boa vontade do modelo. Você escreveu no seu AGENTS.md que ele formate o código, que não toque nos arquivos sensíveis, que rode os testes. E 90% das vezes ele faz. Mas os 10% restantes são justamente os que te mordem: a vez que ele editou o .env de produção, a vez que pulou a formatação e o commit ficou sujo, a vez que executou um rm -rf na pasta errada porque "parecia temporária".

O momento dos hooks é quando você pensa: "e se isso não dependesse de o modelo decidir fazer certo? E se simplesmente acontecesse, sempre, sem depender do critério dele?". É exatamente essa a promessa que a documentação oficial do Claude Code coloca no centro da página de hooks: eles dão "controle determinístico" sobre o comportamento do agente, "garantindo que certas ações sempre aconteçam em vez de depender de o LLM escolher executá-las" (tradução fiel do original em inglês). Essa frase é a tese inteira do recurso.

Imagine assim
Um contrato (seu AGENTS.md) é como o regulamento pregado na parede de uma fábrica: diz como as coisas devem ser feitas, e você confia que cada operário o leia e o cumpra. Um hook é o sensor na esteira transportadora que para a máquina fisicamente se uma peça sai errada. O regulamento persuade; o sensor obriga. Os hooks são o sensor — não pedem por favor, cortam a corrente.

2. A dor · de onde ela vem e por que acontece

A dor não é um apocalipse, é uma erosão. Você pediu à IA que fizesse algo "sempre" e às vezes ela não faz, porque um LLM não é determinístico: a cada turno ele decide de novo, e num turno carregado de contexto, o seu lembrete de formatar pode ficar soterrado sob mil tokens de outra coisa. Não é que a IA seja desobediente — é que você está pedindo consistência a um sistema probabilístico. É como pedir a alguém brilhante mas distraído que nunca esqueça de fechar o registro do gás: na maioria das noites ela fecha, e é justamente por isso que você baixa a guarda.

Sintomas de que você precisa de hooks
Você repete a mesma instrução em cada sessão ("formata", "não mexa em X", "roda os testes") e mesmo assim às vezes ela pula.
Você descobriu depois que a IA editou um arquivo que jamais deveria tocar: .env, um package-lock.json, algo dentro de .git/.
Um commit entrou com formatação inconsistente e sujou o diff de todo o time.
Você fica com um certo medo de deixar a IA com permissões amplas porque não há uma rede de segurança que não dependa dela mesma.
Seu AGENTS.md tem regras críticas escritas em prosa, e "escrito" não é o mesmo que "garantido".
O mal-entendido mais comum
Muita gente acha que, se escrever a regra em MAIÚSCULAS e com pontos de exclamação no AGENTS.md, ela já está "forçada". Não está. Por mais enfática que seja, continua sendo texto que o modelo lê e decide obedecer ou não. A única forma de algo acontecer de verdade —100% das vezes, sem exceção— é tirá-lo da cabeça do LLM e colocá-lo na infraestrutura. Isso são os hooks.

E aqui está o ângulo que torna este recurso avançado: se você já leu sobre escrever um bom contrato para o seu agente (o AGENTS.md), os hooks são o próximo degrau. Você passa de "escreva o contrato" (declarativo: você diz o que quer) para "faça o contrato se executar sozinho" (determinístico: a máquina o cumpre por você). É a diferença entre uma lei escrita num papel e um guarda parado na esquina.

3. O que é um hook (sem enrolação, em uma frase)

Um hook é um comando de shell que o Claude Code executa automaticamente num ponto específico do seu ciclo de vida. Você o declara uma vez num arquivo settings.json; a partir daí, cada vez que esse ponto do ciclo acontecer, o seu comando roda. Quem o dispara não é o modelo com o critério dele: é o evento. Aí está a mágica — é determinístico, não opinável.

A ideia de fundo
O Claude Code vai emitindo sinais enquanto trabalha: "acabei de receber um prompt", "estou prestes a usar uma ferramenta", "terminei de editar um arquivo", "vou comprimir o contexto", "terminei de responder". Um hook é enganchar em um desses sinais e dizer: "quando isso acontecer, roda ISTO". Enganchar (to hook) — daí o nome e o emoji 🪝.

4. Os eventos do ciclo de vida (os pontos onde você engancha)

A documentação oficial lista muitos eventos do ciclo de vida — há um para quase qualquer momento do trabalho do agente. Não decore o número nem a lista completa: aprenda a ideia e fique com os que você de fato vai usar 95% do tempo. Estes são, com os nomes reais tal como aparecem na doc:

Os eventos que importam (nomes reais da doc oficial)
`SessionStart` — quando uma sessão inicia ou é retomada. Ideal para injetar contexto fresco (ex. suas convenções, os últimos commits). Sua saída no stdout é adicionada ao contexto do Claude.
`UserPromptSubmit` — logo quando você envia um prompt, antes de o Claude processá-lo. Você pode adicionar contexto ou até bloquear o prompt.
`PreToolUse`antes de uma ferramenta ser executada. Este pode bloquear a ação. É o seu guarda-costas: aqui você freia um rm -rf ou uma edição em um arquivo protegido.
`PostToolUse`depois de uma ferramenta ter sucesso. Aqui você formata o arquivo recém-editado, roda um lint, o que quiser.
`Notification` — quando o Claude precisa de você (pede permissão ou está esperando). Perfeito para uma notificação de desktop.
`Stop` / `SubagentStop` — quando o Claude (ou um subagente) termina de responder. Útil para uma checagem final antes de dar o turno por encerrado.
`PreCompact` (e SessionStart com matcher compact) — em torno da compactação do contexto, para não perder o importante quando a memória é comprimida.
`SessionEnd` — quando a sessão termina. Para limpar arquivos temporários, fechar coisas.
A distinção que esclarece tudo · Pre vs. Post
`PreToolUse` acontece ANTES e PODE bloquear (a ferramenta ainda não foi executada, então você pode vetá-la). `PostToolUse` acontece DEPOIS e NÃO pode desfazer (a ferramenta já rodou; a doc diz isso sem rodeios). Regra mental: se você quer impedir algo, engancha no Pre. Se quer reagir a algo que já aconteceu (formatar, avisar, registrar), engancha no Post.

5. Como se declara um hook (a anatomia do JSON)

Todo hook vive dentro de um bloco "hooks" no seu settings.json. A estrutura é sempre a mesma boneca russa: o nome do evento → um matcher (a que se aplica) → uma lista de hooks com type: "command" e o command a rodar. Olhe uma vez e nunca mais esquece:

json
{
  "hooks": {
    "PostToolUse": [                    // 1. o EVENTO do ciclo de vida
      {
        "matcher": "Edit|Write",         // 2. A QUAIS ferramentas se aplica
        "hooks": [
          {
            "type": "command",           // 3. e um comando de shell
            "command": "...seu comando..." // 4. O QUE rodar quando acontecer
          }
        ]
      }
    ]
  }
}
O matcher, de forma simples
O matcher filtra a que o hook se aplica. Para eventos de ferramenta (PreToolUse, PostToolUse) ele filtra por nome de ferramenta: "Edit|Write" significa "só quando usar Edit ou Write", "Bash" só comandos de shell. Um matcher vazio ("") dispara sempre, para tudo. A barra | separa alternativas (em versões recentes do Claude Code a vírgula também vale: "Edit, Write" é equivalente).

6. Onde vive um hook (e por que o lugar importa)

O lugar onde você coloca o hook define o alcance dele. Isto é chave: um hook de projeto é compartilhado com o seu time (é commitado no repo); um global é só seu. A tabela oficial resume onde cada coisa vai:

Os três lugares onde um hook pode viver
`~/.claude/settings.json` — global, aplica a todos os seus projetos. Não é compartilhado, é da sua máquina. Aqui vão os seus hooks pessoais (notificações de desktop, por exemplo).
`.claude/settings.json` (dentro do repo) — só aquele projeto, e pode ser commitado: todo o seu time herda a regra. Aqui vão as regras do projeto (formatação, arquivos protegidos).
`.claude/settings.local.json` — só aquele projeto, privado: o Claude Code o coloca no gitignore quando o cria. Para os seus ajustes locais que você não quer compartilhar.
A regra de ouro do lugar
Se a regra deve ser cumprida por todo mundo que trabalhar neste repo (formatar, não tocar arquivos sensíveis), ela vai em .claude/settings.json e é commitada. Assim o contrato deixa de viver na cabeça de uma pessoa e passa a viajar com o código. Esse é o poder real: a disciplina vira parte do repositório, não um post-it que alguém tem que lembrar.

7. Três hooks copy-paste que valem seu peso em ouro

Chega de teoria. Aqui estão três hooks reais, tirados da documentação oficial, prontos para colar. Comece pelo que mais te dói hoje.

a) Autoformatar depois de cada edição (PostToolUse)

O clássico. Cada vez que o Claude edita ou escreve um arquivo, o Prettier passa automaticamente. Nunca mais um commit com formatação inconsistente. Vai no .claude/settings.json do seu projeto:

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}
Como funciona por dentro (para não ser mágica)
Quando o evento dispara, o Claude Code passa ao seu comando um JSON pela entrada padrão (stdin) com os dados: qual ferramenta usou, sobre qual arquivo, etc. Aqui jq -r '.tool_input.file_path' extrai o caminho do arquivo editado desse JSON, e xargs npx prettier --write o passa para o Prettier. jq é um leitor de JSON de linha de comando — instale-o com brew install jq no macOS ou apt-get install jq no Debian/Ubuntu.

b) Bloquear comandos perigosos como rm -rf (PreToolUse)

Este é o que te tira o medo. Um hook PreToolUse que revisa cada comando de Bash antes de executá-lo e o veta se contiver algo destrutivo. Aqui sim importa um detalhe técnico que a doc deixa clarísimo: bloqueia-se saindo com código 2, e o que você escrever no stderr chega ao Claude como explicação para que ele se corrija. Primeiro o script:

bash
#!/bin/bash
# .claude/hooks/block-rm-rf.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')

if echo "$COMMAND" | grep -q "rm -rf"; then
  echo "Bloqueado: 'rm -rf' nao e permitido. Apague caminhos concretos, nao recursivo-forcado." >&2
  exit 2   # exit 2 = bloqueia a acao; stderr chega ao Claude como feedback
fi

exit 0     # exit 0 = sem objecao; segue o fluxo normal de permissoes

Torne-o executável e registre-o nos seus settings apontando para o script:

bash
chmod +x .claude/hooks/block-rm-rf.sh
json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-rm-rf.sh"
          }
        ]
      }
    ]
  }
}
Honestidade · este grep é uma demo, não um cadeado hermético
Um grep -q "rm -rf" pega o caso óbvio, mas escapa de um rm -fr, de um rm -rf com espaços estranhos, ou de um rm --recursive --force. Serve como rede visível e como feedback educativo para a IA, mas não o confunda com uma blindagem. A própria doc diz sem rodeios: a filtragem dos hooks é best-effort e "falha aberta" (se não consegue parsear o comando, deixa passar), então para uma proibição DURA que ninguém possa pular, use o sistema de permissões (permissions.deny), não um hook. O padrão correto é: hook para reagir e avisar; permission rules para o cadeado real.
O detalhe que te salva de verdade · o hook ganha até em modo bypass
Isto é o mais poderoso e quase ninguém sabe: segundo a doc oficial, um PreToolUse que retorna uma decisão de bloqueio veta a ferramenta MESMO em `bypassPermissions` ou com `--dangerously-skip-permissions`. Ou seja: mesmo que você (ou a IA) tenha baixado todas as barreiras de permissões, o seu hook de bloqueio continua de pé. A regra é assimétrica e foi pensada assim de propósito: os hooks podem endurecer a política, nunca afrouxá-la além do que as regras de permissões permitem. Um hook de bloqueio é uma regra que nem você consegue pular por acidente.

c) Notificação de desktop quando a IA precisa de você (Notification)

Para parar de vigiar o terminal. Quando o Claude termina ou precisa da sua permissão, salta uma notificação de desktop e você vai fazer outra coisa. Vai no seu ~/.claude/settings.json global (exemplo de macOS com osascript):

json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code precisa da sua atencao\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}
No Linux e no Windows
O mesmo hook, mudando o comando: no Linux use notify-send 'Claude Code' 'Claude Code precisa da sua atencao'; no Windows (PowerShell) um MessageBox de System.Windows.Forms. A estrutura do JSON é idêntica — só muda a linha do command. Truque de macOS que a própria guia documenta: se a notificação não aparecer, rode uma vez osascript -e 'display notification "test"' e depois dê permissão ao Script Editor em Ajustes do Sistema → Notificações.

8. O hábito · quando pensar num hook (e quando NÃO)

Os hooks não são para tudo. A regra mental é simples: se algo deve acontecer sempre, de forma mecânica e sem critério, é um hook. Se algo requer julgamento caso a caso, não o force com um hook determinístico — deixe o modelo decidir (ou use os hooks do tipo prompt/agente que a doc também suporta, mas isso é outra liga).

Momentos em que você SEMPRE deveria pensar num hook
Toda vez que você se pegar escrevendo "lembre de…" pela terceira vez no seu AGENTS.md. Se você repete, transforme em hook.
Quando houver uma ação que jamais deve acontecer (tocar .env, apagar recursivo, escrever em .git/): isso é um PreToolUse de bloqueio — respaldado por uma regra de permissões para o cadeado duro.
Quando houver uma ação que sempre deve acontecer depois de editar (formatar, ordenar imports, rodar um lint): isso é um PostToolUse.
Quando você quiser que um contexto crítico seja reinjetado depois de cada compactação, para que a IA não "esqueça" as suas convenções no meio da sessão.
O limite honesto dos hooks
Um hook de comando roda shell determinístico: serve para regras mecânicas (este caminho sim, este não), não para julgamentos matizados ("esta mudança é uma boa ideia?"). E cuidado com PostToolUse: ele não pode desfazer o que já aconteceu — só reage. Para impedir, sempre PreToolUse. Colocar lógica complexa demais num hook o torna frágil; mantenha-os curtos e de um único propósito.
Segurança · os hooks rodam shell com AS SUAS permissões
A doc oficial avisa sem rodeios e vale repetir: um hook executa comandos de shell arbitrários com as suas credenciais, automaticamente. Nunca cole um hook que você não entende, jamais copie um de uma fonte que não seja confiável, e revise cada comando antes de salvá-lo. Um hook malicioso é um comando malicioso rodando sozinho. Leia-os como leria qualquer script que vai rodar na sua máquina.

9. O protocolo de uso · monte o seu primeiro hook útil

Aqui o detalhe prático: a própria doc recomenda pedir ao Claude que escreva o hook descrevendo-o para ele. Mas para que saia bem —e seja seguro— convém dar um encargo estruturado, não um "me põe um hook". Este é O prompt mestre do recurso: um só, potente, que projeta o seu primeiro hook com os freios de segurança postos.

Prompt mestre · projete o seu primeiro hook útil (com segurança)texto
Quero montar meu primeiro hook de Claude Code para automatizar uma regra do meu fluxo. A regra que quero garantir SEMPRE é: [DESCREVA A REGRA, ex: "formatar com prettier cada arquivo que voce editar" / "bloquear qualquer comando que apague arquivos de forma recursiva" / "impedir que se edite o .env ou qualquer coisa dentro de .git/" / "me avisar por notificacao quando terminar"].

Antes de escrever nada, me ajude a projeta-lo bem respondendo isto em linguagem clara (eu nao programo):

1. O EVENTO correto do ciclo de vida para esta regra. Se a regra e IMPEDIR algo, deve ser PreToolUse (acontece antes e pode bloquear). Se e REAGIR a algo ja feito (formatar, avisar, registrar), deve ser PostToolUse ou Notification. Diga qual voce escolhe e por que.

2. O MATCHER exato (a quais ferramentas se aplica: Edit|Write, Bash, ou vazio para todas) e por que esse e nao outro. Mantenha-o o mais ESTREITO possivel: um matcher amplo demais dispara o hook onde nao deve.

3. O LUGAR onde deve viver o settings.json:
   - Se a regra deve ser cumprida por todo o time neste repo → .claude/settings.json (e commitado).
   - Se e so para minha maquina e todos os meus projetos → ~/.claude/settings.json.
   - Se e local e privada → .claude/settings.local.json.
   Diga qual e por que.

4. O BLOCO JSON completo, pronto para colar, com o hook ja montado. Se precisar de um script a parte (tipico em bloqueios com PreToolUse), me de tambem o script .sh completo e me lembre de torna-lo executavel com chmod +x.

5. SE FOR UM HOOK DE BLOQUEIO: use-o com exit 2 e uma mensagem clara no stderr que me explique por que foi bloqueado, para que voce mesmo (Claude) receba o motivo e se corrija. Nao o faca silencioso. E ME AVISE se esta regra merece tambem uma regra de permissoes (permissions.deny) como cadeado duro, porque um grep num hook e best-effort e pode ser pulado.

6. SEGURANCA, obrigatorio: me explique em uma frase QUAL comando de shell este hook vai rodar e me confirme que ele nao faz nada destrutivo nem envia dados para nenhum lugar. Me lembre que um hook roda shell com minhas permissoes e que so devo salvar comandos que eu entendo.

7. COMO EU TESTO: diga como verificar que o hook esta registrado (o comando /hooks dentro do Claude Code) e uma forma de testar que ele dispara de verdade, sem quebrar nada real.

Primeiro me mostre SO o design (evento, matcher, lugar), depois o JSON e o script se for preciso, e no fim a explicacao de seguranca e o teste. Nao modifique meu settings.json ainda: quero revisar o bloco antes de cola-lo eu mesmo.

Repare no padrão: primeiro você projeta, revisa a segurança, e você cola o bloco. Você nunca deixa um hook aparecer na sua configuração sem tê-lo entendido. É a mesma disciplina de dois passos que protege qualquer automação potente: a máquina propõe, você aprova.

10. Os caminhos mais fáceis · o que você faz por chat e o que faz por arquivo

Para não se enrolar, isto é o que você pode delegar à IA pelo chat e o que continua sendo tarefa sua:

O que a IA faz por você (pelo chat)
Escrever o bloco JSON completo do hook se você descrever a regra (a doc oficial recomenda isso explicitamente).
Gerar o script .sh para os hooks de bloqueio, com o seu jq, o seu exit 2 e a sua mensagem no stderr.
Explicar qual evento e qual matcher combinam com a sua regra, e em qual settings.json ele deve viver.
Lembrar você dos passos de instalação: chmod +x do script, brew install jq se estiver faltando.
O que VOCÊ decide e faz (não delegue)
Colar o bloco no seu settings.json — depois de lê-lo e entendê-lo. A rede de segurança não pode ser código que você não revisou.
Escolher o lugar (repo compartilhado vs. global vs. local): isso define quem herda a regra.
Confirmar que o comando do hook é seguro (roda shell com as suas permissões: se você não entende, não salva).
Verificar com `/hooks` dentro do Claude Code que ele ficou registrado, e testar que dispara sem quebrar nada real.
O truque para verificar
Dentro do Claude Code, digite `/hooks` para abrir o navegador de hooks: você verá todos os configurados agrupados por evento, com o matcher e o comando de cada um. É de somente leitura (para editar, você mexe no JSON ou pede para a IA), mas é a sua confirmação de que o hook existe e está onde deve. Se não aparecer, verifique se o JSON é válido (nada de vírgulas penduradas nem comentários) e se o arquivo está no caminho correto; às vezes basta reiniciar a sessão para que o file watcher o pegue.

Resumo · seu checklist de hooks

Antes de dar um hook por montado, confirme
Escolhi o evento correto: PreToolUse para impedir, PostToolUse/Notification para reagir.
O matcher é o mais estreito possível (não dispara onde não deve).
Está no lugar correto: repo compartilhado, global seu, ou local privado.
Se bloqueia, usa `exit 2` com uma mensagem clara no stderr para que a IA se corrija — e se for uma proibição dura, respaldei com uma regra de permissões.
Entendo o comando que ele roda (shell com minhas permissões): não salvei nada que eu não revisei.
Verifiquei com `/hooks` e testei que dispara sem quebrar nada real.
Tirei a regra da prosa do meu AGENTS.md e a transformei em algo que acontece sempre.
No NeuralOS · a mesma disciplina, em escala de plataforma
Os hooks materializam uma ideia que no NeuralOS levamos a sério: a camada onde as regras críticas não dependem do critério de ninguém porque a própria infraestrutura as obriga. É exatamente o que faz, por dentro, o gate de advisors do Supabase da plataforma: antes de selar qualquer mudança de banco de dados, uma checagem automática roda sozinha e bloqueia o merge se algo viola as regras de segurança. Ninguém precisa "lembrar" de revisar — acontece sempre, como um PreToolUse que veta o que não deve entrar. É a mesma filosofia de um hook, aplicada a um time inteiro em vez de a um terminal: que a qualidade não seja uma promessa que alguém lembra, mas um sensor na esteira que não dá para pular. Você põe a regra uma vez; o sistema a cumpre para sempre.
O protocolo C-A-R · construir sem bugs
Os hooks são o braço determinístico do C-A-R: onde o protocolo pede disciplina, um hook a torna automática. A dupla perfeita para que a qualidade não dependa de lembrar.
Loop engineering · a IA trabalha sozinha rumo à meta
Quando você deixa a IA iterar sozinha em um loop, os hooks são os freios e os guarda-corpos dela: garantem que certas coisas aconteçam (ou NÃO aconteçam) a cada volta, sem depender do critério dela.
Documentação oficial · Automate actions with hooks (Anthropic)
A fonte de tudo neste recurso: os eventos do ciclo de vida, os exemplos copy-paste e as considerações de segurança. Leia-a antes de implantar hooks em um ambiente compartilhado.
#hooks#Claude Code#automação#ciclo de vida#avançado#determinismo
Ready to build?

Start building in
under 3 minutes

Join 4,200+ builders. No credit card. Build your first app with AI in minutes.