Hooks — Automatizacion Basada en Eventos
Que Son los Hooks
Los hooks son scripts o comandos que se ejecutan automaticamente en respuesta a eventos especificos durante una sesion de Claude Code. Cuando Claude lee un archivo, escribe codigo, ejecuta un comando o finaliza una tarea, los hooks te permiten interceptar esos eventos y ejecutar tu propia logica -- validando entrada, formateando salida, bloqueando operaciones peligrosas o activando procesos posteriores.
Piensa en los hooks como oyentes de eventos para tu flujo de trabajo de desarrollo con IA. Igual que un pre-commit hook en git ejecuta tu linter antes de cada commit, un hook PreToolUse en Claude Code puede validar las entradas de herramientas antes de que Claude tome accion. La diferencia es que los hooks cubren un rango mucho mas amplio de eventos y pueden hacer mucho mas que simples verificaciones de pasa/falla.
Eventos de Hooks
Claude Code expone un conjunto rico de eventos a los que puedes conectarte. Los mas comunmente usados caen en cuatro categorias:
Eventos del ciclo de vida de herramientas:
PreToolUse-- se dispara antes de que Claude use cualquier herramienta (leer un archivo, escribir codigo, ejecutar un comando)PostToolUse-- se dispara despues de que una herramienta se completa, dandote acceso al resultado
Eventos de sesion:
SessionStart-- se dispara cuando comienza una nueva sesion de Claude CodeSessionEnd-- se dispara cuando se cierra una sesionStop-- se dispara cuando Claude termina de responder y esta a punto de devolver el controlSubagentStop-- se dispara cuando un subagente completa su trabajo
Eventos de interaccion del usuario:
UserPromptSubmit-- se dispara cuando el usuario envia un prompt, antes de que Claude lo proceseNotification-- se dispara cuando Claude envia una notificacion
Eventos de contexto:
PreCompact-- se dispara antes de que Claude compacte la conversacion, permitiendote influir en lo que se preserva
Cada evento recibe datos de contexto relevantes: para eventos de herramientas, obtienes el nombre de la herramienta y sus entradas o salidas. Para eventos de sesion, obtienes metadatos de la sesion. Este contexto permite que tus hooks tomen decisiones informadas.
Tipos de Hooks
Hay cuatro tipos de hooks, cada uno adecuado para diferentes casos de uso:
command -- Ejecuta un comando de shell. El tipo mas simple y comun. Bueno para ejecutar linters, formateadores, validadores y scripts.
http -- Envia una solicitud HTTP a una URL de webhook. Usa esto para notificar servicios externos, activar pipelines de CI o registrar eventos en sistemas de monitoreo.
prompt -- Envia el contexto del evento a un modelo de IA para evaluacion. El tipo mas poderoso -- te permite crear reglas que son evaluadas por IA en lugar de simple coincidencia de patrones.
agent -- Lanza un subagente para manejar el evento. Usa esto para manejo complejo de eventos que requiere razonamiento de multiples pasos.
Configuracion
Los hooks se configuran en tu archivo de settings. Puedes establecerlos a nivel global (~/.claude/settings.json) o a nivel de proyecto (.claude/settings.json). Aqui esta la estructura basica:
{
"hooks": [
{
"event": "PreToolUse",
"type": "command",
"command": "node .claude/hooks/validate-tool.js",
"matchers": ["Bash"]
}
]
}
Cada definicion de hook tiene:
event-- que evento escuchartype-- command, http, prompt o agentcommand(ourl,prompt,agent) -- que ejecutarmatchers-- array opcional de nombres de herramientas para filtrar que invocaciones de herramientas activan el hook
Matchers: Filtrando Que Herramientas Activan Hooks
Los matchers te permiten apuntar a herramientas especificas para que tu hook no se dispare en cada llamada a herramienta. Sin matchers, un hook PreToolUse se dispara cada vez que Claude usa cualquier herramienta -- lo cual podria ser docenas de veces por sesion.
{
"hooks": [
{
"event": "PreToolUse",
"type": "command",
"command": "node .claude/hooks/block-dangerous.js",
"matchers": ["Bash"]
},
{
"event": "PostToolUse",
"type": "command",
"command": "npx prettier --write",
"matchers": ["Write"]
}
]
}
En este ejemplo, el primer hook solo se dispara cuando Claude esta a punto de ejecutar un comando de shell (herramienta Bash), y el segundo hook solo se dispara despues de que Claude escribe un archivo (herramienta Write).
PreToolUse: Bloqueando Comandos Peligrosos
El caso de uso mas popular para hooks es prevenir que Claude ejecute comandos que consideras peligrosos. Aqui hay un script que bloquea operaciones destructivas:
// Archivo: .claude/hooks/block-dangerous.js
// Lee la entrada de la herramienta desde stdin y bloquea comandos peligrosos
import { readFileSync } from "fs";
const input = JSON.parse(readFileSync("/dev/stdin", "utf-8"));
const command = input.tool_input?.command || "";
const blocked = [
/rm\s+-rf\s+\//, // Borrado recursivo desde la raiz
/git\s+push\s+--force/, // Force push
/git\s+reset\s+--hard/, // Hard reset
/DROP\s+TABLE/i, // SQL drop table
/DROP\s+DATABASE/i, // SQL drop database
/:\(\)\{.*\|.*\}/, // Fork bomb
];
for (const pattern of blocked) {
if (pattern.test(command)) {
// Salida JSON para bloquear la accion
console.log(JSON.stringify({
action: "block",
message: `Comando peligroso bloqueado: ${command}`
}));
process.exit(0);
}
}
// Permitir que el comando proceda
console.log(JSON.stringify({ action: "allow" }));
Cuando este hook bloquea un comando, Claude recibe el mensaje de bloqueo y puede informar al usuario o tomar un enfoque alternativo.
PostToolUse: Auto-Formateo Despues de Escrituras
Despues de que Claude escribe un archivo, podrias querer ejecutar automaticamente tu formateador para asegurar que el codigo coincida con el estilo de tu proyecto:
{
"hooks": [
{
"event": "PostToolUse",
"type": "command",
"command": "node .claude/hooks/auto-format.js",
"matchers": ["Write"]
}
]
}
// Archivo: .claude/hooks/auto-format.js
import { readFileSync } from "fs";
const input = JSON.parse(readFileSync("/dev/stdin", "utf-8"));
const filePath = input.tool_input?.file_path || "";
// Solo formatear archivos de codigo fuente
const formattable = /\.(ts|tsx|js|jsx|css|json|md)$/;
if (formattable.test(filePath)) {
// La salida le dice a Claude Code que ejecute el formateador
console.log(JSON.stringify({
action: "allow",
commands: [`npx prettier --write "${filePath}"`]
}));
} else {
console.log(JSON.stringify({ action: "allow" }));
}
Esto asegura que cada archivo que Claude escribe sea automaticamente formateado, eliminando inconsistencias de estilo sin ninguna intervencion manual.
Hook Stop: Ejecutando Verificaciones Cuando Claude Finaliza
El hook Stop se dispara cuando Claude completa una respuesta. Este es el lugar perfecto para ejecutar linting, verificacion de tipos o suites de tests para validar el trabajo de Claude:
{
"hooks": [
{
"event": "Stop",
"type": "command",
"command": "node .claude/hooks/post-check.js"
}
]
}
// Archivo: .claude/hooks/post-check.js
// Ejecutar linter despues de que Claude termina de hacer cambios
import { readFileSync } from "fs";
const input = JSON.parse(readFileSync("/dev/stdin", "utf-8"));
// Verificar si algun archivo fue modificado en este turno
const filesModified = input.tool_results?.some(
(r) => r.tool_name === "Write"
);
if (filesModified) {
console.log(JSON.stringify({
action: "allow",
commands: ["npm run lint -- --quiet"]
}));
} else {
console.log(JSON.stringify({ action: "allow" }));
}
UserPromptSubmit: Validando Entrada
El hook UserPromptSubmit te permite inspeccionar y opcionalmente modificar los prompts del usuario antes de que Claude los procese. Esto es util para hacer cumplir convenciones o agregar contexto automatico:
{
"hooks": [
{
"event": "UserPromptSubmit",
"type": "command",
"command": "node .claude/hooks/enrich-prompt.js"
}
]
}
Podrias usar esto para agregar automaticamente contexto relevante, hacer cumplir convenciones de nombres en solicitudes o registrar prompts para fines de auditoria.
Prompt Hooks: Reglas Evaluadas por IA
Los prompt hooks son el tipo de hook mas poderoso. En lugar de escribir logica procedural, escribes una regla en lenguaje natural que es evaluada por un modelo de IA:
{
"hooks": [
{
"event": "PreToolUse",
"type": "prompt",
"prompt": "Review this shell command for security risks. Block the command if it could delete data, modify system files, access the network in unexpected ways, or expose secrets. Allow the command if it is a standard development operation like running tests, building, or linting.",
"matchers": ["Bash"]
}
]
}
La IA evalua la entrada de la herramienta contra tu regla y decide si permitir o bloquear. Esto es mucho mas flexible que patrones regex -- puede entender contexto e intencion, capturando casos limite que las reglas procedurales no detectarian.
Ejemplo Completo de Configuracion de Hooks
Aqui hay un .claude/settings.json completo con multiples hooks trabajando juntos:
{
"hooks": [
{
"event": "PreToolUse",
"type": "command",
"command": "node .claude/hooks/block-dangerous.js",
"matchers": ["Bash"]
},
{
"event": "PostToolUse",
"type": "command",
"command": "node .claude/hooks/auto-format.js",
"matchers": ["Write"]
},
{
"event": "Stop",
"type": "command",
"command": "node .claude/hooks/run-lint.js"
},
{
"event": "PreToolUse",
"type": "prompt",
"prompt": "Verify this file write does not overwrite test fixtures, migration files, or lock files without explicit user intent.",
"matchers": ["Write"]
}
]
}
Esta configuracion bloquea comandos de shell peligrosos, auto-formatea archivos escritos, ejecuta el linter despues de cada respuesta y usa IA para evaluar escrituras de archivos contra una politica. Juntos, estos hooks crean una red de seguridad integral alrededor de las acciones de Claude.
Respuestas de Hooks
Los hooks se comunican de vuelta a Claude Code a traves de salida JSON:
{"action": "allow"}-- permite que la operacion proceda{"action": "block", "message": "razon"}-- detiene la operacion y muestra el mensaje{"action": "allow", "commands": ["cmd1", "cmd2"]}-- permite y ejecuta comandos de seguimiento
Para hooks PreToolUse, tambien puedes modificar la entrada de la herramienta antes de que se ejecute, dandote la capacidad de sanitizar o transformar las operaciones previstas de Claude.
Mejores Practicas
Manten los hooks rapidos. Cada hook agrega latencia al flujo de trabajo de Claude. Los hooks de comandos de shell deben completarse en menos de un segundo. Si necesitas procesamiento complejo, considera ejecutarlo de forma asincrona o moverlo a un hook PostToolUse o Stop donde la latencia es menos notable.
Usa matchers agresivamente. Un hook que se dispara en cada llamada a herramienta se acumula rapidamente. Apunta solo a las herramientas donde tu hook agrega valor.
Prueba los hooks exhaustivamente antes de desplegarlos a tu equipo. Un hook PreToolUse con bugs puede bloquear operaciones legitimas y frustrar a los usuarios. Comienza ejecutando tu script de hook manualmente con entrada de ejemplo para verificar que maneja todos los casos correctamente.
Prueba este ejercicio: agrega un hook PreToolUse que bloquee cualquier comando Bash que contenga sudo. Agrega un hook PostToolUse que registre cada escritura de archivo en un archivo local .claude/audit.log con una marca de tiempo. Ejecuta una sesion de Claude Code con estos hooks activos y verifica que funcionen como se espera. Luego comparte la configuracion con tu equipo haciendo commit del .claude/settings.json y los scripts de hooks en el control de versiones.