Inicio/Hooks

Hooks

Los hooks son scripts de shell que se ejecutan automáticamente en respuesta a eventos de Claude Code. Te dan control total sobre el comportamiento de la herramienta.

¿Qué son los hooks?

Los hooks te permiten interceptar y reaccionar a eventos del ciclo de vida de Claude Code: antes de ejecutar una herramienta, después de hacerlo, cuando Claude termina una respuesta, etc.

Casos de uso comunes:

  • Formatear automáticamente el código tras cada edición.
  • Registrar en un log todas las operaciones de Claude.
  • Bloquear operaciones peligrosas con lógica personalizada.
  • Enviar notificaciones cuando Claude termina una tarea larga.
  • Ejecutar tests automáticamente después de cada cambio.

Tipos de hooks

EventoCuándo se disparaPuede bloquear
PreToolUseAntes de ejecutar cualquier herramienta
PostToolUseDespués de ejecutar cualquier herramientaNo
StopCuando Claude termina una respuesta completaNo
SubagentStopCuando un subagente termina su tareaNo
NotificationCuando Claude emite una notificación al usuarioNo

Configurar hooks

Los hooks se configuran en .claude/settings.json (proyecto) o ~/.claude/settings.json (global):

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write $CLAUDE_FILE_PATH"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification "Claude terminó" with title "Claude Code"'"
          }
        ]
      }
    ]
  }
}

Variables de entorno disponibles en hooks

VariableDescripción
CLAUDE_TOOL_NAMENombre de la herramienta que se ejecutó
CLAUDE_TOOL_INPUTInput de la herramienta (JSON)
CLAUDE_TOOL_OUTPUTOutput de la herramienta (PostToolUse)
CLAUDE_FILE_PATHRuta del archivo afectado (Edit/Write/Read)
CLAUDE_SESSION_IDID único de la sesión actual
CLAUDE_PROJECT_DIRDirectorio raíz del proyecto
CLAUDE_HOOK_TYPETipo de hook (PreToolUse, PostToolUse, Stop...)

El matcher

El campo matcher es una expresión regular que se compara con el nombre de la herramienta. Si no se especifica, el hook se aplica a todas las herramientas.

# Solo edición de archivos TypeScript
"matcher": "Edit"

# Herramientas de bash y edición
"matcher": "Bash|Edit|Write"

# Cualquier herramienta de lectura
"matcher": "^Read"

Hook de tipo command

El tipo más común. Ejecuta un comando de shell. El hook puede leer información del evento via variables de entorno o via stdin (JSON):

{
  "type": "command",
  "command": "bash /ruta/a/mi-hook.sh",
  "timeout": 30
}

Ejemplo: hook que lee datos del evento por stdin

#!/bin/bash
# mi-hook.sh — recibe el evento completo como JSON por stdin
EVENT=$(cat)
TOOL=$(echo $EVENT | jq -r '.tool_name')
FILE=$(echo $EVENT | jq -r '.tool_input.path // ""')

echo "Herramienta: $TOOL, Archivo: $FILE" >> ~/.claude/hook.log

Bloquear operaciones con PreToolUse

Un hook PreToolUse puede devolver un código de salida distinto de 0 para bloquear la operación:

#!/bin/bash
# Bloquear rm -rf
TOOL=$(cat | jq -r '.tool_name')
CMD=$(cat | jq -r '.tool_input.command // ""')

if [[ "$CMD" == *"rm -rf"* ]]; then
  echo "BLOQUEADO: rm -rf no permitido"
  exit 1  # exit 1 = bloquear la operación
fi

exit 0  # exit 0 = permitir

Configúralo así en settings.json:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "bash ~/.claude/hooks/bloquear-rm.sh"
      }]
    }]
  }
}

Ejemplos prácticos

Formatear con Prettier tras edición

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "npx prettier --write "$CLAUDE_FILE_PATH" 2>/dev/null || true"
      }]
    }]
  }
}

Ejecutar tests tras cambios

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "npm test --watchAll=false 2>&1 | tail -20"
      }]
    }]
  }
}

Log de todas las operaciones

{
  "hooks": {
    "PostToolUse": [{
      "hooks": [{
        "type": "command",
        "command": "echo "$(date) - $CLAUDE_TOOL_NAME: $CLAUDE_FILE_PATH" >> ~/.claude/audit.log"
      }]
    }]
  }
}
Consejo: Usa 2>/dev/null || true al final de tus comandos de hook para evitar que errores menores interrumpan el flujo de Claude.

Gestionar hooks desde la CLI

# Ver hooks configurados (dentro de Claude Code)
/hooks

# O abre settings.json directamente:
claude config