🎣 O que sao Hooks
Hooks sao pontos de extensao que permitem executar scripts ou comandos em momentos especificos do fluxo de trabalho do Claude Code. Similar a Git hooks, eles reagem a eventos automaticamente.
🔄 Fluxo de Eventos
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ EVENTO │ → │ HOOK │ → │ ACAO │ │(PreToolUse) │ │ (seu script)│ │ (continua │ │ │ │ │ │ ou bloqueia)│ └─────────────┘ └─────────────┘ └─────────────┘
- • PreToolUse: Executa ANTES da ferramenta (pode bloquear com exit code 2)
- • PostToolUse: Executa DEPOIS da ferramenta (para cleanup/notificacoes)
📊 Eventos de Hook Disponiveis
Eventos de Tool
- •
PreToolUse- antes de executar ferramenta - •
PostToolUse- depois de executar ferramenta - •
PermissionRequest- ao pedir permissao
Eventos de Sessao
- •
SessionStart- inicio de sessao - •
SessionEnd- fim de sessao - •
Stop- agente termina resposta - •
SubagentStop- subagente termina - •
Notification- alertas do Claude
⚙️ Configurando Hooks
Hooks sao configurados em arquivos settings.json em diferentes niveis:
usuario (~/.claude/settings.json), projeto (.claude/settings.json)
ou local (.claude/settings.local.json).
Configuracao em .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/caminho/para/validate-edit.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/caminho/para/format-code.sh"
}
]
}
]
}
}
Localizacao dos Arquivos de Configuracao
~/.claude/settings.json # Hooks globais (todos projetos) .claude/settings.json # Hooks do projeto (compartilhavel) .claude/settings.local.json # Hooks locais (nao commitar)
Configuracoes de projeto tem prioridade sobre configuracoes de usuario.
matcher
Ferramentas que ativam o hook (Edit|Write|Bash|Read|Grep)
type
Tipo do hook: "command"
command
Caminho absoluto do script
✍️ Hook pre-edit: Validacao
O hook PreToolUse e executado antes de Claude usar uma ferramenta (Edit, Write, Bash, etc). Use o matcher para filtrar quais ferramentas ativam o hook.
Exemplo: Proteger arquivos criticos
#!/bin/bash # validate-edit.sh # Hook recebe JSON via stdin com detalhes da operacao # Ler input JSON do stdin INPUT=$(cat) FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty') PROTECTED_FILES=( "package-lock.json" ".env" ".env.production" ) for pattern in "${PROTECTED_FILES[@]}"; do if [[ "$FILE_PATH" == *"$pattern"* ]]; then echo "BLOQUEADO: $FILE_PATH e um arquivo protegido" >&2 exit 2 # Exit 2 = bloqueia a acao fi done exit 0 # Exit 0 = permite a acao
Exemplo: Backup automatico
#!/bin/bash
# backup-pre-edit.sh - Criar backup antes de cada edicao
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
BACKUP_DIR="$CLAUDE_PROJECT_DIR/.claude/backups/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
if [ -f "$FILE_PATH" ]; then
TIMESTAMP=$(date +%H%M%S)
BASENAME=$(basename "$FILE_PATH")
cp "$FILE_PATH" "$BACKUP_DIR/${BASENAME}.${TIMESTAMP}.bak"
fi
exit 0
💡 Variaveis de Ambiente e Exit Codes
$CLAUDE_PROJECT_DIR
Caminho raiz do projeto
Exit code 0
Sucesso - acao permitida
$CLAUDE_CODE_REMOTE
"true" se ambiente web
Exit code 2
Erro bloqueante - acao impedida
🔔 Hook post-edit: Notificacoes
Hooks PostToolUse sao ideais para notificacoes, formatacao automatica, logging e integracoes que nao devem bloquear o fluxo.
Exemplo: Notificacao Slack
#!/bin/bash
# notify-slack.sh - Hook PostToolUse
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
SLACK_WEBHOOK="$SLACK_CLAUDE_WEBHOOK"
PROJECT_NAME=$(basename "$CLAUDE_PROJECT_DIR")
curl -X POST "$SLACK_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{
\"text\": \"🤖 Claude executou $TOOL_NAME\",
\"blocks\": [{
\"type\": \"section\",
\"text\": {
\"type\": \"mrkdwn\",
\"text\": \"*Projeto:* $PROJECT_NAME\n*Arquivo:* $FILE_PATH\n*Ferramenta:* $TOOL_NAME\"
}
}]
}"
Exemplo: Log de Auditoria
#!/bin/bash
# audit-log.sh - Log todas operacoes em arquivo JSON
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // "N/A"')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"')
LOG_FILE="$CLAUDE_PROJECT_DIR/.claude/audit-log.jsonl"
echo "{
\"timestamp\": \"$(date -Iseconds)\",
\"file\": \"$FILE_PATH\",
\"tool\": \"$TOOL_NAME\",
\"project\": \"$CLAUDE_PROJECT_DIR\"
}" >> "$LOG_FILE"
Casos de Uso
- • Notificacao em Slack/Teams
- • Log de auditoria
- • Trigger de CI/CD
- • Sincronizacao com ferramentas
Evitar em post-hooks
- • Operacoes lentas (> 3s)
- • Modificar o arquivo editado
- • Dependencias de rede criticas
- • Logica que deveria bloquear
🛡️ Hook pre-bash: Seguranca
Use PreToolUse com matcher: "Bash"
para validar comandos antes de Claude executa-los. Sua ultima linha de defesa contra comandos perigosos.
Exemplo: Bloquear comandos destrutivos
#!/bin/bash # validate-bash.sh - PreToolUse hook com matcher "Bash" INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty') BLOCKED_PATTERNS=( "rm -rf /" "rm -rf ~" "rm -rf \$HOME" "> /dev/sda" "mkfs" "dd if=" ":(){ :|:& };:" "chmod -R 777 /" ) for pattern in "${BLOCKED_PATTERNS[@]}"; do if [[ "$COMMAND" == *"$pattern"* ]]; then echo "BLOQUEADO: Comando potencialmente destrutivo detectado" >&2 echo "Comando: $COMMAND" >&2 exit 2 # Exit 2 = bloqueia fi done # Alertar para comandos com sudo (nao bloqueia) if [[ "$COMMAND" == *"sudo"* ]]; then echo "ALERTA: Comando com sudo detectado" fi exit 0
⚠️ Comandos a Bloquear
rm -rf /
mkfs.*
dd if=
> /dev/*
chmod 777
fork bomb
💡 Dica Pro
Combine pre-bash hooks com o sistema de permissoes do Claude Code. O hook e uma camada adicional de seguranca, nao um substituto.
📚 Biblioteca de Hooks
Colecao de hooks prontos para usar. Copie, adapte e combine conforme necessario.
Auto-format com Prettier (PostToolUse)
#!/bin/bash
# format-code.sh - PostToolUse com matcher "Edit|Write"
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE_PATH" =~ \.(js|ts|jsx|tsx|json|css|md)$ ]]; then
npx prettier --write "$FILE_PATH" 2>/dev/null
echo "Formatado: $FILE_PATH"
fi
Git auto-stage (PostToolUse)
#!/bin/bash
# auto-stage.sh - PostToolUse com matcher "Edit|Write"
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if git rev-parse --git-dir > /dev/null 2>&1; then
git add "$FILE_PATH"
echo "Staged: $FILE_PATH"
fi
Configuracao Completa em settings.json
{
"hooks": {
"PreToolUse": [
{ "matcher": "Edit|Write", "hooks": [{"type": "command", "command": "./hooks/validate.sh"}] },
{ "matcher": "Bash", "hooks": [{"type": "command", "command": "./hooks/validate-bash.sh"}] }
],
"PostToolUse": [
{ "matcher": "Edit|Write", "hooks": [{"type": "command", "command": "./hooks/format.sh"}] }
]
}
}
Estrutura de Retorno JSON (Avancado)
# Hook pode retornar JSON para controle avancado: { "decision": "approve", # approve, block, allow, deny "reason": "Validacao OK", # Explicacao para Claude "updatedInput": {...} # Modificar parametros (v2.0.10+) }
O retorno JSON permite modificar inputs de ferramentas antes da execucao.
📋 Resumo do Modulo
Proximo Modulo:
3.5 - Subagentes Customizados - crie agentes especializados para tarefas especificas