PostToolUse executa depois de qualquer tool call completar — independente de sucesso ou falha. Diferente do PreToolUse (que decide se executa), o PostToolUse reage ao resultado: tem acesso ao input original e ao output gerado. Usos principais: auto-lint depois de edições, notificações, logging de auditoria, disparo condicional de testes. O hook não pode desfazer a ação — só reagir a ela.
A analogia: o evento “onChange” depois do commit
Em frontend, você conhece o padrão de event listeners: onChange, onSubmit, onComplete. Você registra um handler que executa após o evento — não para prevenir, mas para reagir. Se o usuário clicou “salvar”, o handler pode sincronizar com o servidor, atualizar o estado local, e disparar uma notificação. O handler não cancela o que já foi salvo.
PostToolUse é exatamente isso. O agente editou um arquivo — o arquivo já foi editado. Não há como voltar atrás. O PostToolUse hook executa e pode: rodar o linter no arquivo novo, logar o que foi alterado, disparar os testes relacionados, notificar que algo aconteceu. É reação, não controle.
Isso cria uma separação de responsabilidades clara: PreToolUse previne, PostToolUse automatiza. A prevenção vem antes. A automação vem depois.
O mecanismo exato
Após cada tool call completar (com sucesso ou falha), o runtime:
sequenceDiagram
participant Agent as Agente (modelo)
participant Runtime as Runtime CC
participant Tool as Tool (Edit, Bash...)
participant Hook as PostToolUse script
Agent->>Runtime: Tool call com input
Runtime->>Tool: Executa
Tool-->>Runtime: Output (sucesso ou falha)
Runtime->>Hook: stdin = JSON com input + output
Note over Hook: Reage ao resultado<br>Log, lint, notifica, testa
Hook-->>Runtime: exit code (ignorado para controle de fluxo)
Runtime-->>Agent: Resultado original da tool
Pontos críticos do mecanismo:
O hook executa sempre — independente do exit code da tool
O hook tem acesso ao output completo da tool (o que o agente não usaria diretamente)
O exit code do hook não bloqueia a sessão — não é como o PreToolUse
O output do hook é logado internamente, mas não é injetado no contexto do agente por padrão
PostToolUse não bloqueia
Um exit code não-zero no PostToolUse não para a sessão. É por design — é um hook de reação. Se você precisa de controle (bloquear, aprovar), use PreToolUse. PostToolUse é para o “e depois disso?”
Estrutura do input recebido pelo hook
O hook recebe via stdin um JSON com o input e o output da tool call:
O campo tool_output é o que diferencia PostToolUse do PreToolUse — você sabe o que de fato aconteceu, não apenas o que o agente pretendia fazer.
Variáveis de ambiente disponíveis
Além do stdin, o runtime injeta:
$CLAUDE_TOOL_NAME # Nome da tool: "Bash", "Edit", "Write", etc.$CLAUDE_TOOL_INPUT # Input serializado como JSON string$CLAUDE_TOOL_OUTPUT # Output serializado como JSON string$CLAUDE_TOOL_EXIT_CODE # Exit code da tool (para Bash)$CLAUDE_SESSION_ID # ID único da sessão atual
Canal: Claude (Anthropic) | Duração: ~3min | Idioma: EN
Vídeo oficial curto que resume por que hooks são determinísticos (rodam sempre, ao contrário de instruções em CLAUDE.md) e usa o auto-format via PostToolUse como o exemplo central — exatamente o Caso de uso 1 abaixo.
Trecho de destaque [1:24]: “The most common hook. Auto formatting after edits. You set a post-tool-use hook with a matcher of edit or multi-edit… it fires whenever Claude modifies a file.”
Por que isso importa: o agente pode editar arquivos em rápida sucessão sem rodar lint entre elas. Ao final, você recebe código que já passou no linter — não precisa rodar npm run lint no final da sessão.
Esse mesmo princípio — reagir automaticamente ao resultado de uma ação, sem intervenção manual — é o que sustenta pipelines de CI/CD: veja 02 - CI-CD com GitHub Actions para o mesmo padrão aplicado no nível de pipeline, em vez de tool call individual.
Caso de uso 2 — Auto-format (Prettier)
Similar ao lint, mas sem semântica de erro — só formatação consistente:
#!/bin/bash# hooks/auto-format.shINPUT=$(cat)FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')FORMATTABLE_EXTENSIONS=("ts" "tsx" "js" "jsx" "json" "css" "md" "yaml" "yml")EXTENSION="${FILE##*.}"for ext in "${FORMATTABLE_EXTENSIONS[@]}"; do if [[ "$EXTENSION" == "$ext" ]]; then npx prettier --write "$FILE" --log-level silent 2>/dev/null break fidoneexit 0
Combinar lint + format
Configure os dois em sequência no mesmo matcher. O format normaliza o estilo, o lint captura problemas semânticos:
A diferença crucial: o PostToolUse tem o campo success e output — você sabe se o agente conseguiu fazer o que queria ou se falhou. Útil para detectar padrões de falha sistemática.
Caso de uso 4 — Notificações de tarefas longas
Quando o agente roda npm test ou cargo build, você pode estar em outra janela. O PostToolUse notifica quando concluir:
Quando o agente edita código de implementação, rodar os testes relacionados imediatamente:
#!/bin/bash# hooks/auto-run-related-tests.shINPUT=$(cat)TOOL=$(echo "$INPUT" | jq -r '.tool_name')FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')SUCCESS=$(echo "$INPUT" | jq -r '.tool_output.success // false')if [[ "$TOOL" != "Edit" ]] || [[ "$SUCCESS" != "true" ]]; then exit 0; fi# Só para arquivos de implementação (não para testes ou config)if [[ ! "$FILE" =~ src/.+\.(ts|js)$ ]]; then exit 0; fi# Derivar o arquivo de teste correspondenteTEST_FILE=$(echo "$FILE" | sed 's|src/|tests/|' | sed 's|\.\(ts\|js\)$|.test.\1|')if [[ -f "$TEST_FILE" ]]; then echo "Rodando testes para $FILE..." npx jest "$TEST_FILE" --no-coverage --silent 2>&1 | tail -10fiexit 0
Cuidado com performance
Rodar testes em cada Edit pode tornar sessões lentas. Avalie: use apenas em src/services/* ou outros diretórios críticos, não em todos os arquivos src/**.
Caso de uso 6 — Logging de comandos que falharam
Para debugging de sessões longas — saber quais comandos o agente tentou e que falharam:
Os dois hooks se complementam: PreToolUse é a política, PostToolUse é a automação. Um projeto bem configurado usa os dois em camadas.
Armadilhas
Hook pesado em PostToolUse
O hook executa a cada tool call. Um hook que demora 3 segundos em cada Edit vai tornar a sessão muito mais lenta — se o agente fizer 20 edições, você perde 1 minuto só em hooks. Mantenha PostToolUse leve: lint rápido (--quiet), log simples, verificações de existência de arquivo.
Tentar desfazer a ação
PostToolUse não pode reverter o que a tool fez. O arquivo já foi editado, o comando já executou. Se você precisa prevenir, use PreToolUse. PostToolUse é para o que acontece depois de.
Depender do exit code para controle
O exit code do PostToolUse não bloqueia a sessão — é ignorado pelo runtime para controle de fluxo. Se você colocar exit 1 em um PostToolUse e esperar que o agente pare, não vai acontecer.
Loops de edição
Se o PostToolUse edita o arquivo (ex: Prettier reescrevendo), isso pode disparar novamente o PostToolUse recursivamente. Não é um problema na prática (o hook vê o mesmo arquivo e não produz mais mudanças), mas vale ter ciência.
Assumir que success reflete o resultado real
O campo success em tool_output pode não ser granular o suficiente para todos os casos. Para Bash, cheque exit_code também: um processo pode terminar com success: false mas ter um output parcialmente útil.
Checklist — PostToolUse
Scripts são executáveis: chmod +x hooks/*.sh
Scripts têm guardas de ferramenta (if [[ "$TOOL" != "Edit" ]]; then exit 0; fi)
Scripts têm guardas de extensão para lint/format (não rodar lint em arquivos .md)
Scripts têm guardas de sucesso (não rodar testes em edições que falharam)
Hooks são rápidos — nada que demora mais de 1-2s por tool call
Logging redireciona para arquivo, não para stdout/stderr do hook
Testados isoladamente com JSON de exemplo antes de configurar
Como explicar em inglês
Português
Inglês
Hook de pós-execução
PostToolUse hook
Reagir ao resultado
React to the result
Auditoria pós-ação
Post-action audit
Disparar ação secundária
Trigger a secondary action
Independente de sucesso ou falha
Regardless of success or failure
Frases úteis:
“PostToolUse hooks fire after every tool call completes — whether it succeeded or failed. They receive both the original input and the resulting output.”
“Unlike PreToolUse, PostToolUse can’t block or modify execution — the action already happened. Its job is to react: lint the edited file, log the result, send a notification, trigger tests.”
“Think of PreToolUse as policy enforcement, PostToolUse as workflow automation. They’re complementary: one prevents, the other automates.”
O que vem a seguir
PostToolUse fecha o ciclo de reação por tool call: o agente age, o hook reage — lint, log, notificação, teste. Mas e quando a sessão inteira termina? Nenhum dos hooks vistos até aqui olha para o quadro completo: quantos arquivos foram tocados, quantos tokens foram gastos, o que vale registrar como sumário. Esse é o papel do último hook do ciclo de vida: o 04 - Stop hook, que executa uma única vez, no encerramento da sessão, para notificar, sumarizar e limpar.