Os hooks do Claude Code são comandos shell definidos pelo usuário que executam em vários pontos do ciclo de vida do Claude Code. Os hooks fornecem controle determinístico sobre o comportamento do Claude Code, garantindo que certas ações sempre aconteçam em vez de depender do LLM para escolher executá-las.
Para documentação de referência sobre hooks, veja Referência de Hooks.
Exemplos de casos de uso para hooks incluem:
  • Notificações: Personalize como você é notificado quando o Claude Code está aguardando sua entrada ou permissão para executar algo.
  • Formatação automática: Execute prettier em arquivos .ts, gofmt em arquivos .go, etc. após cada edição de arquivo.
  • Logging: Rastreie e conte todos os comandos executados para conformidade ou depuração.
  • Feedback: Forneça feedback automatizado quando o Claude Code produz código que não segue as convenções da sua base de código.
  • Permissões personalizadas: Bloqueie modificações em arquivos de produção ou diretórios sensíveis.
Ao codificar essas regras como hooks em vez de instruções de prompt, você transforma sugestões em código de nível de aplicação que executa toda vez que é esperado que execute.
Você deve considerar as implicações de segurança dos hooks ao adicioná-los, porque os hooks executam automaticamente durante o loop do agente com as credenciais do seu ambiente atual. Por exemplo, código malicioso de hooks pode exfiltrar seus dados. Sempre revise sua implementação de hooks antes de registrá-los.Para as melhores práticas completas de segurança, veja Considerações de Segurança na documentação de referência de hooks.

Visão Geral dos Eventos de Hook

O Claude Code fornece vários eventos de hook que executam em diferentes pontos no fluxo de trabalho:
  • PreToolUse: Executa antes das chamadas de ferramenta (pode bloqueá-las)
  • PostToolUse: Executa após as chamadas de ferramenta serem concluídas
  • UserPromptSubmit: Executa quando o usuário envia um prompt, antes do Claude processá-lo
  • Notification: Executa quando o Claude Code envia notificações
  • Stop: Executa quando o Claude Code termina de responder
  • SubagentStop: Executa quando as tarefas de subagente são concluídas
  • PreCompact: Executa antes do Claude Code executar uma operação de compactação
  • SessionStart: Executa quando o Claude Code inicia uma nova sessão ou retoma uma sessão existente
  • SessionEnd: Executa quando a sessão do Claude Code termina
Cada evento recebe dados diferentes e pode controlar o comportamento do Claude de maneiras diferentes.

Início Rápido

Neste início rápido, você adicionará um hook que registra os comandos shell que o Claude Code executa.

Pré-requisitos

Instale jq para processamento JSON na linha de comando.

Passo 1: Abrir configuração de hooks

Execute o comando slash /hooks e selecione o evento de hook PreToolUse. Os hooks PreToolUse executam antes das chamadas de ferramenta e podem bloqueá-las enquanto fornecem feedback ao Claude sobre o que fazer diferente.

Passo 2: Adicionar um matcher

Selecione + Add new matcher… para executar seu hook apenas em chamadas de ferramenta Bash. Digite Bash para o matcher.
Você pode usar * para corresponder a todas as ferramentas.

Passo 3: Adicionar o hook

Selecione + Add new hook… e insira este comando:
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt

Passo 4: Salvar sua configuração

Para localização de armazenamento, selecione User settings já que você está registrando no seu diretório home. Este hook então se aplicará a todos os projetos, não apenas ao seu projeto atual. Então pressione Esc até retornar ao REPL. Seu hook agora está registrado!

Passo 5: Verificar seu hook

Execute /hooks novamente ou verifique ~/.claude/settings.json para ver sua configuração:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
          }
        ]
      }
    ]
  }
}

Passo 6: Testar seu hook

Peça ao Claude para executar um comando simples como ls e verifique seu arquivo de log:
cat ~/.claude/bash-command-log.txt
Você deve ver entradas como:
ls - Lists files and directories

Mais Exemplos

Para uma implementação de exemplo completa, veja o exemplo de validador de comando bash em nossa base de código pública.

Hook de Formatação de Código

Formate automaticamente arquivos TypeScript após edição:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }"
          }
        ]
      }
    ]
  }
}

Hook de Formatação de Markdown

Corrija automaticamente tags de linguagem ausentes e problemas de formatação em arquivos markdown:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/markdown_formatter.py"
          }
        ]
      }
    ]
  }
}
Crie .claude/hooks/markdown_formatter.py com este conteúdo:
#!/usr/bin/env python3
"""
Formatador de markdown para saída do Claude Code.
Corrige tags de linguagem ausentes e problemas de espaçamento preservando o conteúdo do código.
"""
import json
import sys
import re
import os

def detect_language(code):
    """Detecção de linguagem por melhor esforço a partir do conteúdo do código."""
    s = code.strip()
    
    # Detecção de JSON
    if re.search(r'^\s*[{\[]', s):
        try:
            json.loads(s)
            return 'json'
        except:
            pass
    
    # Detecção de Python
    if re.search(r'^\s*def\s+\w+\s*\(', s, re.M) or \
       re.search(r'^\s*(import|from)\s+\w+', s, re.M):
        return 'python'
    
    # Detecção de JavaScript  
    if re.search(r'\b(function\s+\w+\s*\(|const\s+\w+\s*=)', s) or \
       re.search(r'=>|console\.(log|error)', s):
        return 'javascript'
    
    # Detecção de Bash
    if re.search(r'^#!.*\b(bash|sh)\b', s, re.M) or \
       re.search(r'\b(if|then|fi|for|in|do|done)\b', s):
        return 'bash'
    
    # Detecção de SQL
    if re.search(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\s+', s, re.I):
        return 'sql'
        
    return 'text'

def format_markdown(content):
    """Formatar conteúdo markdown com detecção de linguagem."""
    # Corrigir cercas de código sem rótulo
    def add_lang_to_fence(match):
        indent, info, body, closing = match.groups()
        if not info.strip():
            lang = detect_language(body)
            return f"{indent}```{lang}\n{body}{closing}\n"
        return match.group(0)
    
    fence_pattern = r'(?ms)^([ \t]{0,3})```([^\n]*)\n(.*?)(\n\1```)\s*$'
    content = re.sub(fence_pattern, add_lang_to_fence, content)
    
    # Corrigir linhas em branco excessivas (apenas fora das cercas de código)
    content = re.sub(r'\n{3,}', '\n\n', content)
    
    return content.rstrip() + '\n'

# Execução principal
try:
    input_data = json.load(sys.stdin)
    file_path = input_data.get('tool_input', {}).get('file_path', '')
    
    if not file_path.endswith(('.md', '.mdx')):
        sys.exit(0)  # Não é um arquivo markdown
    
    if os.path.exists(file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        formatted = format_markdown(content)
        
        if formatted != content:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(formatted)
            print(f"✓ Formatação de markdown corrigida em {file_path}")
    
except Exception as e:
    print(f"Erro ao formatar markdown: {e}", file=sys.stderr)
    sys.exit(1)
Torne o script executável:
chmod +x .claude/hooks/markdown_formatter.py
Este hook automaticamente:
  • Detecta linguagens de programação em blocos de código sem rótulo
  • Adiciona tags de linguagem apropriadas para destaque de sintaxe
  • Corrige linhas em branco excessivas preservando o conteúdo do código
  • Processa apenas arquivos markdown (.md, .mdx)

Hook de Notificação Personalizada

Receba notificações na área de trabalho quando o Claude precisar de entrada:
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' 'Aguardando sua entrada'"
          }
        ]
      }
    ]
  }
}

Hook de Proteção de Arquivo

Bloqueie edições em arquivos sensíveis:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 -c \"import json, sys; data=json.load(sys.stdin); path=data.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(p in path for p in ['.env', 'package-lock.json', '.git/']) else 0)\""
          }
        ]
      }
    ]
  }
}

Saiba mais

  • Para documentação de referência sobre hooks, veja Referência de Hooks.
  • Para práticas abrangentes de segurança e diretrizes de segurança, veja Considerações de Segurança na documentação de referência de hooks.
  • Para passos de solução de problemas e técnicas de depuração, veja Depuração na documentação de referência de hooks.