Con la evolución constante de las herramientas de desarrollo impulsadas por IA, Claude Code ha introducido una funcionalidad revolucionaria: Hooks. Esta característica permite a los desarrolladores personalizar y automatizar comportamientos específicos en el ciclo de vida de Claude Code, transformando sugerencias en código ejecutable que funciona de manera determinística.
Los hooks representan un salto cualitativo en la personalización de herramientas de IA para desarrollo, permitiendo que cada equipo y desarrollador adapte Claude Code a sus necesidades específicas y estándares de proyecto.
¿Qué son los Claude Code Hooks?
Los Claude Code Hooks son comandos de shell definidos por el usuario que se ejecutan automáticamente en varios puntos específicos del ciclo de vida de Claude Code. A diferencia de las instrucciones de prompting, los hooks garantizan que ciertas acciones siempre ocurran, proporcionando control determinístico sobre el comportamiento de la herramienta.
El Problema que Resuelven
Tradicionalmente, personalizar el comportamiento de herramientas de IA requería:
- Instrucciones repetitivas en cada conversación
- Dependencia del LLM para recordar y ejecutar acciones específicas
- Inconsistencias en la aplicación de estándares de código
- Procesos manuales para formateo, validación y logging
Los hooks eliminan estas limitaciones al codificar reglas como aplicaciones que se ejecutan automáticamente.
Casos de Uso Transformadores
1. Formateo Automático de Código
# Hook que formatea automáticamente archivos TypeScript
hook_command="if [[ \$file_path =~ \.ts$ ]]; then prettier --write \$file_path; fi"
2. Notificaciones Personalizadas
# Notificación por Slack cuando Claude solicita permisos
hook_command="curl -X POST \$SLACK_WEBHOOK -d '{\"text\":\"Claude Code necesita tu atención\"}'"
3. Logging y Compliance
# Registro de todos los comandos ejecutados para auditoría
hook_command="echo \$(date): \$command >> ~/.claude/audit.log"
4. Validación de Convenciones
# Verificar que los commits siguen el estándar del equipo
hook_command="./scripts/validate-commit-message.sh \$commit_message"
5. Permisos Personalizados
# Bloquear modificaciones a archivos de producción
hook_command="if [[ \$file_path =~ ^production/ ]]; then exit 2; fi"
Configuración Paso a Paso
Configuración Básica: Hook de Logging
Vamos a crear nuestro primer hook que registra todos los comandos bash ejecutados por Claude Code.
Paso 1: Abrir Configuración de Hooks
# En Claude Code, ejecutar el comando slash
/hooks
Selecciona el evento PreToolUse
para interceptar comandos antes de su ejecución.
Paso 2: Añadir Matcher
Matcher: Bash
Esto hace que el hook solo se ejecute para comandos de shell.
Paso 3: Configurar el Hook
# Comando que registra la ejecución
echo "$(date): Command executed by Claude Code" >> ~/.claude/command_log.txt
Paso 4: Guardar Configuración
Selecciona User settings
para aplicar el hook a todos los proyectos.
Configuración Avanzada: Formateo Automático
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "if [[ \"$file_path\" =~ \\.(js|ts|jsx|tsx)$ ]]; then prettier --write \"$file_path\"; fi"
},
{
"type": "command",
"command": "if [[ \"$file_path\" =~ \\.go$ ]]; then gofmt -w \"$file_path\"; fi"
},
{
"type": "command",
"command": "if [[ \"$file_path\" =~ \\.py$ ]]; then black \"$file_path\"; fi"
}
]
}
]
}
}
Tipos de Eventos de Hooks
1. PreToolUse
Se ejecuta antes de que Claude procese una herramienta.
Casos de uso:
- Validación de permisos
- Verificación de pre-condiciones
- Bloqueo de operaciones peligrosas
# Ejemplo: Bloquear ediciones a archivos críticos
if [[ "$file_path" =~ (package\.json|\.env) ]]; then
echo "Error: Archivo crítico protegido" >&2
exit 2 # Bloquea la operación
fi
2. PostToolUse
Se ejecuta después de que una herramienta se complete exitosamente.
Casos de uso:
- Formateo automático
- Validación post-procesamiento
- Notificaciones de cambios
# Ejemplo: Ejecutar tests después de cambios de código
if [[ "$file_path" =~ \.test\.(js|ts)$ ]]; then
npm test "$file_path"
fi
3. Notification
Se ejecuta cuando Claude Code envía notificaciones.
Casos de uso:
- Notificaciones personalizadas
- Integración con sistemas externos
- Alertas por múltiples canales
# Ejemplo: Notificación por Discord
curl -H "Content-Type: application/json" \
-d '{"content":"Claude Code requiere atención"}' \
"$DISCORD_WEBHOOK"
4. Stop
Se ejecuta cuando Claude Code termina de responder.
Casos de uso:
- Ejecutar scripts de post-procesamiento
- Generar reportes de sesión
- Limpiar archivos temporales
# Ejemplo: Generar reporte de cambios
git diff --stat > session_changes.txt
Estructura de Datos de Input
Los hooks reciben información contextual vía JSON en stdin:
PreToolUse Input
{
"event": "PreToolUse",
"session_id": "session_123",
"tool_name": "Edit",
"tool_input": {
"file_path": "src/component.tsx",
"content": "// Nuevo contenido...",
"start_line": 1,
"end_line": 10
}
}
PostToolUse Input
{
"event": "PostToolUse",
"session_id": "session_123",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
},
"tool_response": {
"exit_code": 0,
"stdout": "Tests passed",
"stderr": ""
}
}
Ejemplos Avanzados de Hooks
Sistema de Validación de Código
#!/bin/bash
# validate_code.sh - Hook de validación comprehensiva
# Leer input JSON
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
tool_name=$(echo "$input" | jq -r '.tool_name')
# Solo procesar operaciones de archivo
if [[ "$tool_name" != "Edit" && "$tool_name" != "Write" ]]; then
exit 0
fi
# Validaciones específicas por tipo de archivo
case "$file_path" in
*.js|*.ts|*.jsx|*.tsx)
# Validar sintaxis JavaScript/TypeScript
if ! npx tsc --noEmit "$file_path" 2>/dev/null; then
echo "Error: Código TypeScript inválido" >&2
exit 2
fi
# Ejecutar ESLint
if ! npx eslint "$file_path" --fix; then
echo "Warning: Problemas de linting detectados" >&2
fi
;;
*.py)
# Validar sintaxis Python
if ! python -m py_compile "$file_path"; then
echo "Error: Sintaxis Python inválida" >&2
exit 2
fi
# Formatear con black
black "$file_path"
;;
*.go)
# Validar sintaxis Go
if ! go fmt -e "$file_path"; then
echo "Error: Sintaxis Go inválida" >&2
exit 2
fi
# Ejecutar go vet
go vet "$file_path"
;;
esac
echo "Validación completada para $file_path"
Sistema de Notificaciones Inteligentes
#!/bin/bash
# smart_notifications.sh - Notificaciones contextuales
input=$(cat)
event=$(echo "$input" | jq -r '.event')
tool_name=$(echo "$input" | jq -r '.tool_name // empty')
case "$event" in
"Notification")
# Notificación por terminal
osascript -e 'display notification "Claude Code requiere atención" with title "AI Assistant"'
# Notificación por Slack en horario laboral
hour=$(date +%H)
if [[ $hour -ge 9 && $hour -le 17 ]]; then
curl -X POST "$SLACK_WEBHOOK" \
-H 'Content-type: application/json' \
-d '{"text":"Claude Code necesita input"}'
fi
;;
"Stop")
# Generar resumen de sesión
session_id=$(echo "$input" | jq -r '.session_id')
echo "Sesión $session_id completada - $(date)" >> ~/.claude/session_log.txt
;;
esac
Control de Permisos Granular
#!/bin/bash
# permission_control.sh - Control de acceso basado en contexto
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
tool_name=$(echo "$input" | jq -r '.tool_name')
command=$(echo "$input" | jq -r '.tool_input.command // empty')
# Proteger archivos de configuración críticos
protected_files=(
"package.json"
".env"
"docker-compose.yml"
"Dockerfile"
".github/workflows/*"
)
for pattern in "${protected_files[@]}"; do
if [[ "$file_path" == $pattern ]]; then
# Solicitar confirmación explícita
echo "ADVERTENCIA: Intentando modificar archivo crítico: $file_path" >&2
echo "¿Estás seguro? Este cambio podría afectar la configuración del proyecto." >&2
exit 2
fi
done
# Bloquear comandos potencialmente peligrosos
dangerous_commands=(
"rm -rf"
"sudo"
"chmod 777"
"dd"
)
for cmd in "${dangerous_commands[@]}"; do
if [[ "$command" == *"$cmd"* ]]; then
echo "Error: Comando peligroso bloqueado: $cmd" >&2
echo "Uso: Evita comandos que puedan causar daño al sistema" >&2
exit 2
fi
done
echo "Permisos validados correctamente"
Integración con MCP Tools
Claude Code hooks funcionan perfectamente con herramientas del Model Context Protocol (MCP):
Nomenclatura de Herramientas MCP
mcp__<servidor>__<herramienta>
Ejemplos:
- mcp__memory__create_entities
- mcp__filesystem__read_file
- mcp__github__search_repositories
Configuración para Herramientas MCP
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__github__.*",
"hooks": [
{
"type": "command",
"command": "echo 'GitHub operation logged' >> ~/.claude/github_ops.log"
}
]
},
{
"matcher": "mcp__filesystem__write_file",
"hooks": [
{
"type": "command",
"command": "./scripts/backup_before_write.sh \"$file_path\""
}
]
}
]
}
}
Respuestas Avanzadas con JSON
Para control sofisticado, los hooks pueden retornar JSON estructurado:
Control de Flujo PreToolUse
#!/bin/bash
# advanced_pretool_hook.sh
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
# Lógica de validación compleja...
if [[ "$file_path" =~ ^production/ ]]; then
# Bloquear operación y proporcionar feedback específico
jq -n '{
"decision": "block",
"reason": "Las modificaciones a archivos de producción requieren revisión manual. Por favor, crea un pull request.",
"continue": false,
"stopReason": "Operación bloqueada por política de seguridad"
}'
exit 0
fi
# Aprobar automáticamente archivos de desarrollo
if [[ "$file_path" =~ ^dev/ ]]; then
jq -n '{
"decision": "approve",
"reason": "Archivo de desarrollo - aprobación automática"
}'
exit 0
fi
# Continuar con flujo normal
echo '{}'
Feedback Inteligente PostToolUse
#!/bin/bash
# intelligent_feedback.sh
input=$(cat)
tool_response=$(echo "$input" | jq -r '.tool_response')
exit_code=$(echo "$tool_response" | jq -r '.exit_code // 0')
if [[ $exit_code -ne 0 ]]; then
stderr_output=$(echo "$tool_response" | jq -r '.stderr')
# Proporcionar feedback específico basado en el error
if [[ "$stderr_output" == *"permission denied"* ]]; then
jq -n '{
"decision": "block",
"reason": "Error de permisos detectado. Intenta usar sudo o verifica los permisos del archivo.",
"continue": false
}'
elif [[ "$stderr_output" == *"command not found"* ]]; then
jq -n '{
"decision": "block",
"reason": "Comando no encontrado. Verifica que la herramienta esté instalada o usa una alternativa.",
"continue": false
}'
fi
else
# Operación exitosa
echo '{"decision": "approve"}'
fi
Mejores Prácticas de Seguridad
⚠️ Consideraciones Críticas
Los hooks ejecutan comandos con permisos completos del usuario sin confirmación. Esto requiere precauciones estrictas:
1. Validación y Sanitización de Inputs
#!/bin/bash
# secure_hook_template.sh
# Función para sanitizar inputs
sanitize_input() {
local input="$1"
# Remover caracteres peligrosos
echo "$input" | sed 's/[;&|`$(){}[\]\\]//g'
}
# Función para validar paths
validate_path() {
local path="$1"
# Bloquear path traversal
if [[ "$path" == *".."* ]]; then
echo "Error: Path traversal detectado" >&2
exit 1
fi
# Asegurar que el path esté dentro del proyecto
if [[ ! "$path" =~ ^[./] ]]; then
echo "Error: Path fuera del proyecto" >&2
exit 1
fi
}
# Leer y validar input
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
if [[ -n "$file_path" ]]; then
validate_path "$file_path"
file_path=$(sanitize_input "$file_path")
fi
2. Uso Seguro de Variables
# ❌ INCORRECTO - Vulnerable a injection
command="ls $user_input"
# ✅ CORRECTO - Variables citadas apropiadamente
command="ls \"$user_input\""
# ✅ MÁS SEGURO - Validación previa
if [[ "$user_input" =~ ^[a-zA-Z0-9._/-]+$ ]]; then
command="ls \"$user_input\""
else
echo "Input inválido" >&2
exit 1
fi
3. Lista de Archivos Sensibles Protegidos
#!/bin/bash
# protect_sensitive_files.sh
SENSITIVE_PATTERNS=(
"*.env*"
"*.key"
"*.pem"
"*.p12"
"*.jks"
".ssh/*"
".aws/*"
".docker/config.json"
"secrets/*"
"password*"
"*.secret"
)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
for pattern in "${SENSITIVE_PATTERNS[@]}"; do
if [[ "$file_path" == $pattern ]]; then
echo "Error: Archivo sensible protegido: $file_path" >&2
echo "Por favor, maneja archivos de credenciales manualmente." >&2
exit 2
fi
done
Configuración Segura por Defecto
{
"hooks": {
"PreToolUse": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "./scripts/security_check.sh"
}
]
}
]
}
}
Workflow de Desarrollo Completo
Configuración de Equipo Empresarial
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"comment": "Validar permisos de archivo",
"command": "./hooks/validate_permissions.sh"
},
{
"type": "command",
"comment": "Verificar estándares de código",
"command": "./hooks/code_standards.sh"
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"comment": "Auditar comandos ejecutados",
"command": "echo \"$(date): $command\" >> ~/.claude/audit.log"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"comment": "Formateo automático",
"command": "./hooks/auto_format.sh"
},
{
"type": "command",
"comment": "Ejecutar linting",
"command": "./hooks/run_linting.sh"
},
{
"type": "command",
"comment": "Tests unitarios si aplicable",
"command": "./hooks/run_tests.sh"
}
]
}
],
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"comment": "Notificación por Slack",
"command": "./hooks/slack_notification.sh"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"comment": "Generar reporte de sesión",
"command": "./hooks/session_report.sh"
}
]
}
]
}
}
Debugging y Troubleshooting
Verificación de Configuración
# Verificar configuración actual
/hooks
# Comprobar archivos de configuración
cat ~/.claude/settings.json | jq '.hooks'
cat .claude/settings.json | jq '.hooks'
# Validar JSON
json_verify < ~/.claude/settings.json
Modo Debug
# Ejecutar Claude Code con debug habilitado
claude-code --debug
# Los hooks mostrarán información detallada:
# - Comando ejecutándose
# - Status de éxito/fallo
# - Output y mensajes de error
Testing Manual de Hooks
# Test independiente de hook
echo '{"event":"PreToolUse","tool_name":"Edit","tool_input":{"file_path":"test.js"}}' | ./my_hook.sh
# Verificar exit codes
echo $? # 0=success, 2=block, other=error
Logs y Monitoreo
# Configurar logging comprehensivo
mkdir -p ~/.claude/logs
# Hook de logging universal
echo '{"event":"'$event'","tool":"'$tool_name'","timestamp":"'$(date -Iseconds)'"}' >> ~/.claude/logs/hook_activity.log
Casos de Uso Empresariales
1. Compliance y Auditoría
#!/bin/bash
# compliance_hook.sh - Registro para auditoría SOX/SOC2
{
echo "{"
echo " \"timestamp\": \"$(date -Iseconds)\","
echo " \"user\": \"$USER\","
echo " \"session\": \"$session_id\","
echo " \"action\": \"$tool_name\","
echo " \"file\": \"$file_path\","
echo " \"command\": \"$command\""
echo "}"
} >> /var/log/claude_audit.jsonl
2. CI/CD Integration
#!/bin/bash
# cicd_trigger.sh - Integración con pipelines
if [[ "$file_path" =~ \.(js|ts|py|go)$ ]]; then
# Trigger build pipeline
curl -X POST "$CI_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{\"ref\":\"$BRANCH\",\"message\":\"Code updated by Claude\"}"
fi
3. Seguridad Corporativa
#!/bin/bash
# corporate_security.sh - Políticas de seguridad empresarial
# Verificar contra base de datos de vulnerabilidades
if command -v safety &> /dev/null && [[ "$file_path" == "requirements.txt" ]]; then
safety check --file "$file_path" --json > safety_report.json
if [[ $(jq '.vulnerabilities | length' safety_report.json) -gt 0 ]]; then
echo "Error: Vulnerabilidades detectadas en dependencias" >&2
jq '.vulnerabilities[] | .vulnerability' safety_report.json >&2
exit 2
fi
fi
El Futuro de Claude Code Hooks
Los hooks representan solo el comienzo de un ecosistema más amplio de personalización:
Funcionalidades en Desarrollo
- Hooks visuales con interfaces gráficas
- Marketplace de hooks compartidos por la comunidad
- Integración nativa con más herramientas de desarrollo
- Hooks remotos ejecutados en la nube
- AI-powered hooks que aprenden de patrones de uso
Ecosistema Emergente
- Templates de hooks para diferentes stacks tecnológicos
- Librerías de validación específicas por lenguaje
- Integraciones enterprise con herramientas corporativas
- Hooks colaborativos para equipos distribuidos
Conclusión: Transformando el Desarrollo con IA
Los Claude Code Hooks representan un paradigma fundamental en cómo las herramientas de IA se integran en workflows de desarrollo reales. Al permitir automatización determinística y personalización granular, transforman Claude Code de una herramienta de asistencia a una plataforma de desarrollo extensible.
Beneficios clave:
- ✅ Consistencia garantizada en estándares de código
- ✅ Automatización de tareas repetitivas
- ✅ Integración profunda con herramientas existentes
- ✅ Control granular sobre comportamientos de IA
- ✅ Escalabilidad empresarial con políticas centralizadas
Para comenzar:
- Identifica procesos manuales repetitivos en tu workflow
- Implementa hooks simples (logging, formateo)
- Gradualmente añade validaciones y controles más sofisticados
- Comparte configuraciones exitosas con tu equipo
Los hooks no solo mejoran la productividad individual, sino que permiten a los equipos codificar su conocimiento colectivo en automatizaciones que benefician a toda la organización.
El futuro del desarrollo de software está en herramientas que no solo asisten, sino que se adaptan y evolucionan con las necesidades específicas de cada proyecto y equipo. Claude Code Hooks marca el camino hacia esa realidad.
Enlaces útiles:
Tags: #ClaudeCode #Hooks #AI #Automation #DevOps #Workflow #Development #Productivity
Comentarios