๐ฅ Input via stdin JSON
Todo hook recebe um JSON no stdin. O schema varia por evento, mas a forma e constante.
๐ Input tipico de SessionStart
{
"hook_event_name": "SessionStart",
"session_id": "abc-123",
"cwd": "/home/user/projects/payments-v2",
"transcript_path": "/home/user/.claude/.../session.jsonl"
}
Input tipico de UserPromptSubmit:
{
"hook_event_name": "UserPromptSubmit",
"session_id": "abc-123",
"cwd": "/home/user/projects/payments-v2",
"transcript_path": "...",
"user_message": "Como configuro o webhook da Stripe?"
}๐ก Parse em bash
INPUT=$(cat); CWD=$(echo "$INPUT" | jq -r '.cwd') โ jq resolve 90%. Ou use Python para casos complexos.
๐ค Output via stdout JSON
Hook responde escrevendo JSON no stdout. Claude Code le e interpreta os campos conhecidos.
๐ Output para injetar contexto
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Role: backend eng\nStack: Python, FastAPI"
}
}
Output para bloquear tool (PreToolUse):
{
"decision": "block",
"reason": "Bash command contem 'rm -rf', politica interna bloqueia."
}
Output vazio (sem interferencia):
{}โ ๏ธ Sempre JSON valido
Hook que retorna string vazia ou texto solto gera warning. Sempre {} se nao quer acao.
๐จ Exit codes
Alem do stdout, exit codes carregam semantica. Util para gates simples sem precisar gerar JSON.
๐ข Semantica dos exit codes
Convencao:
- โข0: sucesso. Padrao.
- โข1: erro recuperavel. Claude loga e continua sem additionalContext.
- โข2: bloqueio duro (PreToolUse). Cancela a tool call.
- โข>2: erro critico. Claude pode abortar o hook.
๐ก Exit 2 para compliance
Em PreToolUse, exit 2 e a unica forma deterministica de bloquear uma ferramenta. Envie mensagem em stderr.
๐ Injetando texto: additionalContext
90% da Trilha 4 e sobre o que colocar nesse campo. E o canal de injecao de memoria.
๐ additionalContext: o que acontece
Quando voce retorna esse campo:
- โขClaude Code anexa o texto ao system prompt do proximo turno.
- โขO modelo recebe como se fosse parte das instrucoes do sistema.
- โขTem prioridade alta de atencao (similar ao CLAUDE.md).
- โขNao fica visivel para o usuario na interface.
๐ก Formato markdown funciona
Claude parseia markdown bem. Headers, bullets, code blocks โ tudo entendido naturalmente.
โฑ๏ธ Timeouts e limites
Hooks tem tempo limite. Estoure e voce perde a injecao silenciosamente.
๐ Timeouts tipicos
- SessionStart: ~30s (sessao espera)
- UserPromptSubmit: ~10s (usuario espera)
- PreCompact: ~20s (compactacao espera)
- SessionEnd: sem limite se async, ~30s se sync
โ ๏ธ Chamada de API lenta
Script que chama Gemini sem timeout proprio pode estourar. Sempre: timeout=20 < timeout do hook.
๐งช Testando seu hook local
Ciclo de feedback curto = hook que funciona. Teste com echo antes de integrar.
๐ Teste local rapido
# 1. Prepare input de exemplo cat > /tmp/hook_input.json <
๐ก 10x mais rapido
Testar via Claude Code demora ~10s por tentativa. Testar local demora 0.1s. Use local para iterar.
๐ Resumo do Modulo
Proximo:
3.5 โ Hooks sincronos vs assincronos