Pular para o conteúdo
Conteúdo
Tutorial8 min de leitura

Claude Code Hooks: automações que não dependem de prompt

Pedir no prompt é sugestão; hook é regra. Como usar os eventos do Claude Code para garantir formatação, bloquear comandos perigosos e rodar teste sem depender de o modelo lembrar.

O problema

Você pede "sempre rode o formatter depois de editar" e funciona nas primeiras vezes. Vinte mensagens depois, o modelo esquece. Instrução em prompt é probabilística. Se o comportamento precisa acontecer sempre, ele não pertence ao prompt, pertence à configuração.

Hook é um comando de shell que o Claude Code executa em pontos determinados do ciclo de vida da sessão. Ele roda sempre, independente do que o modelo decidiu fazer. É código, não intenção.

Onde fica a configuração

  • .claude/settings.json: versionado, vale para o time inteiro
  • .claude/settings.local.json: só para você, fora do controle de versão
  • ~/.claude/settings.json: global, vale para todos os seus projetos

Os eventos

  • PreToolUse: antes de executar uma ferramenta. É o único que consegue bloquear.
  • PostToolUse: depois que a ferramenta rodou com sucesso.
  • UserPromptSubmit: quando você envia uma mensagem; dá para injetar contexto.
  • SessionStart: no início da sessão.
  • Stop / SubagentStop: quando o agente termina de responder.
  • PreCompact: antes de a conversa ser compactada.

Formatar depois de toda edição

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write --ignore-unknown $(jq -r '.tool_input.file_path')"
          }
        ]
      }
    ]
  }
}

O matcher é uma expressão regular sobre o nome da ferramenta. O hook recebe um JSON no stdin com o contexto da chamada. É daí que o jq.tool_input.file_path.

Bloquear antes de acontecer

Em PreToolUse, sair com código 2 cancela a chamada da ferramenta e devolve o stderr ao modelo como explicação. É assim que se cria uma trava que nenhum prompt derruba.

bash
#!/usr/bin/env bash
# .claude/hooks/protege-env.sh
payload=$(cat)
caminho=$(echo "$payload" | jq -r '.tool_input.file_path // empty')

case "$caminho" in
  *.env|*.env.*|*/secrets/*)
    echo "Bloqueado: $caminho guarda credenciais. Edite manualmente." >&2
    exit 2
    ;;
esac
exit 0
json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/protege-env.sh" }
        ]
      }
    ]
  }
}

Onde isso vale a pena

O critério é um só: o comportamento pode falhar às vezes? Se puder, prompt resolve. Se não puder, vira hook.

  • Formatter e linter depois de editar: não pode falhar
  • Bloqueio de arquivo sensível: não pode falhar
  • Rodar a suíte de testes ao encerrar a resposta: não pode falhar
  • Escolher um nome de variável melhor: pode ficar no prompt

É a mesma lógica de qualquer automação de processo, e é por isso que este conteúdo está aqui e não numa categoria separada de IA: a decisão não é sobre o modelo, é sobre qual parte do processo precisa de garantia determinística.

Tecnologias e temas

IABoas PráticasClaude CodeJSONShell

Materiais

Conteúdos relacionados

Guia9 min

Power Apps: fórmulas na prática

As fórmulas que resolvem 90% dos apps internos, e as três armadilhas que fazem um app funcionar com 200 registros e travar com 3.000.

Power AppsBoas Práticas