Ele não precisa ser chamado. Simplesmente está lá, observando cada movimento, esperando o gatilho que o aciona.
O que é um Hook?
Quatro características que separam um hook de qualquer outra peça do ecossistema.
Comando de shell
Um script que o sistema executa sem que você precise digitar nada.
Sentinela do agente
Intercepta cada ação antes ou depois da execução da ferramenta.
Bloqueia ou observa
Pode permitir, modificar ou impedir a ação que está acontecendo.
Vigilância delegada
Você configura uma vez. Ele vigia sempre, sem cansar nem dormir.
Hooks ≠ Skills
Vivem em lugares diferentes, têm propósitos diferentes e poderes diferentes. A confusão é cara.
Onde os hooks moram
Hooks não ficam dentro das skills. Vivem no arquivo de configuração, no nível do sistema.
// Hooks vivem fora das skills, no settings.json { "hooks": { "PreToolUse": [ { "matcher": "Edit", "command": "python scripts/check_protected.py \"$FILE_PATH\"" } ], "PostToolUse": [ { "matcher": "Bash", "command": "python scripts/log_action.py \"$TOOL_NAME\" \"$EXIT_CODE\"" } ] } }
matcher
Filtra qual ferramenta dispara o hook (Edit, Bash, *).
command
Shell command que será executado pelo sistema, não pelo agente.
PreToolUse
O Smith que bloqueia
Antes da ferramenta rodar, o hook intercepta. Se ele retorna exit 1, o agente nunca executa.
Proteção explícita
O script recebe o caminho, checa a lista de protegidos e retorna exit 1 para bloquear.
Lista de arquivos protegidos no topo
Compara com o argumento recebido
sys.exit(1) bloqueia a ação
import sys PROTECTED = [ 'config/production.yaml', '.env', 'credentials.json' ] file_path = sys.argv[1] for protected in PROTECTED: if file_path.endswith(protected): print(f'BLOQUEADO: {file_path} é protegido.') sys.exit(1) # recusa sys.exit(0) # libera
PostToolUse
O Smith que inspeciona
Depois que a ferramenta roda, o hook acorda. Não bloqueia nada, porque a ação já aconteceu. Ele observa, registra e devolve feedback.
import subprocess import sys result = subprocess.run( ['python', '-m', 'pytest', 'tests/', '-q'], capture_output=True, text=True ) if result.returncode != 0: print('ALERTA: testes falharam após a edição.') print(result.stdout) print(result.stderr) else: print('Testes passaram.') sys.exit(0) # nunca bloqueia
Reação automática
Roda os testes depois de cada edição. O resultado volta para o agente como feedback do próximo ciclo.
Executa pytest via subprocess
Imprime resultado para o agente ler
exit(0) sempre, nunca bloqueia
O ciclo de proteção
Cada ação do agente atravessa dois Smiths. Um pergunta antes, outro inspeciona depois. O loop nunca para.
Seu primeiro hook: "Valeu Sandeco"
O mais simples possível. Toda mensagem sua dispara o hook, que imprime uma frase antes da resposta.
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "echo '{\"systemMessage\": \"Valeu Sandeco\"}'",
"shell": "bash"
}
]
}
]
}
}
UserPromptSubmit não usa matcher. Para a mensagem aparecer visível ao usuário, o hook devolve JSON com o campo systemMessage.
A mensagem aparece no terminal antes da resposta do Claude. Como veio em systemMessage, é exibida ao usuário pela interface.
Crie o arquivo
.claude/settings.json na raiz do projeto, com o JSON ao lado.
Reinicie o Claude Code
Hooks são lidos no boot. Aceite o registro quando ele pedir confirmação.
Mande qualquer mensagem
Antes da resposta, Valeu Sandeco aparece. Funciona em todo prompt.
O universo dos 28 hooks
Pre e Post são só o começo. O Claude Code expõe 28 eventos diferentes ao longo de toda a sessão.
Categoria · 6 eventos
Sessão & configuração
Categoria · 5 eventos
Turno do usuário
Categoria · 6 eventos · loop agentic
Ferramentas
Categoria · 7 eventos
Subagentes, tarefas e arquivos
2 eventos
Compactação
2 eventos
MCP
Como um hook bloqueia uma ação
Três formas equivalentes de dizer "não" ao agente, em ordem do mais simples ao mais expressivo.
sys.exit(2)
O mais simples. Qualquer linguagem.
{"decision":
"block"}
Permite mensagem de feedback ao agente.
{"permission
Decision":
"deny"}
Específico de eventos de permissão.
Exemplos práticos
Cinco sentinelas que você pode configurar hoje, sem tocar em uma única ferramenta.
Hook 1 · SessionStart
Boas-vindas com contexto
Ao abrir o Claude Code, o hook roda git status e os últimos commits. O agente já começa sabendo exatamente onde você parou.
// Roda quando a sessão inicia { "hooks": { "SessionStart": [ { "command": "python scripts/git_briefing.py" } ] } }
import subprocess status = subprocess.run( ['git', 'status', '--short'], capture_output=True, text=True ).stdout log = subprocess.run( ['git', 'log', '--oneline', '-n', '3'], capture_output=True, text=True ).stdout print(f'Branch:\n{status}\nUltimos:\n{log}')
Ganho prático: nada de explicar de novo onde você estava. O agente abre a sessão já sabendo o estado do repositório.
Hook 2 · UserPromptSubmit
Auditoria de prompts
Cada mensagem que você envia para o agente é gravada em logs/prompts.jsonl com data e hora. Histórico completo do que você pediu, sem precisar lembrar.
// Roda a cada prompt enviado { "hooks": { "UserPromptSubmit": [ { "command": "python scripts/audit.py" } ] } }
import json, os, sys from datetime import datetime prompt = sys.stdin.read() os.makedirs('logs', exist_ok=True) with open('logs/prompts.jsonl', 'a') as f: f.write(json.dumps({ 'time': datetime.now().isoformat(), 'prompt': prompt }) + '\n')
Ganho prático: revise depois o que pediu, treine prompts melhores, descubra padrões. Memória persistente sem custo.
Quer dominar cada um deles?
O livro Engenharia de Software para Agentes Inteligentes destrincha hooks, skills, MCP, subagents e tudo que faz o agente trabalhar a seu favor.
·
@canalsandeco
Hook 3 · Stop
Som quando o agente termina
Você saiu para o café enquanto o agente trabalhava? O hook dispara um beep e uma notificação desktop assim que ele para de responder. Volte à janela só quando ouvir o sinal.
// Roda quando o agente para { "hooks": { "Stop": [ { "command": "python scripts/notify.py" } ] } }
import winsound from plyer import notification # Beep curto: 880 Hz por 300 ms winsound.Beep(880, 300) # Notificação no Windows notification.notify( title='Claude Code', message='O agente terminou. Volte à janela.', timeout=5 )
Ganho prático: trabalho assíncrono de verdade. Você delega, faz outra coisa, volta quando o agente avisa.
Hook 4 · PreCompact
Snapshot antes da compactação
Quando o contexto fica grande, o Claude comprime a conversa para caber. Se algo importante for cortado, o hook já salvou o original em snapshots/ antes do corte.
// Roda antes da compactação { "hooks": { "PreCompact": [ { "command": "python scripts/snapshot.py" } ] } }
import os, sys from datetime import datetime stamp = datetime.now().strftime('%Y%m%d-%H%M%S') dest = f'snapshots/{stamp}.md' os.makedirs('snapshots', exist_ok=True) with open(dest, 'w', encoding='utf-8') as f: f.write(sys.stdin.read()) print(f'Snapshot salvo em {dest}')
Ganho prático: compactação sem medo. O original fica no disco e você nunca perde uma decisão importante.
Hook 5 · SessionStart
Lembrete de pendências
Toda sessão começa lendo o TODO.md do projeto e mostrando o que ainda falta. Você abre o Claude Code já alinhado com as tarefas pendentes.
// Dois hooks no mesmo evento { "hooks": { "SessionStart": [ { "command": "python scripts/git_briefing.py" }, { "command": "python scripts/show_todo.py" } ] } }
import os, re, sys if not os.path.exists('TODO.md'): sys.exit(0) with open('TODO.md', encoding='utf-8') as f: pendentes = re.findall(r'- \[ \] (.+)', f.read()) if pendentes: print(f'Voce tem {len(pendentes)} pendentes:') for t in pendentes[:5]: print(f' - {t}')
Ganho prático: bônus, dois hooks no mesmo evento. Ambos rodam em ordem antes do agente carregar.
Os cinco sentinelas lado a lado
Resumo dos hooks práticos que você acabou de ver.
| Evento | O que faz | Ganho | |
|---|---|---|---|
| SessionStart | Injeta git status e últimos commits no contexto inicial | Começa onde você parou | |
| UserPromptSubmit | Grava cada prompt em logs/prompts.jsonl com timestamp | Histórico sem esforço | |
| Stop | Toca beep e dispara notificação quando o agente termina | Trabalho assíncrono | |
| PreCompact | Salva conversa completa em snapshots/ antes do corte | Compactação sem perdas | |
| SessionStart | Lê TODO.md e exibe pendências do projeto | Foco do primeiro segundo |
Nenhum destes hooks usa PreToolUse ou PostToolUse. O Claude Code expõe vinte e oito eventos, você acabou de usar quatro deles.
Poderoso o suficiente para ser útil, limitado o suficiente para ser confiável.
Trinity com o programa de pilotagem e Agent Smith vigiando cada manobra. É assim que se opera a Matrix sem perder o controle.