← volver Escritorio de desarrollador débilmente iluminado a la hora dorada con teclado mecánico, dos monitores mostrando output de terminal, y una taza de té fría

Claude Code Hooks: La Capa de Automatización Que Desearía Haber Configurado Antes

Tres meses. Ese es el tiempo que dejé los hooks de Claude Code sin leer en la documentación, mientras me quejaba de que la IA seguía generando código que ignoraba mis convenciones de formato. Configuré Claude Code en enero, comencé a enviar features con él casi inmediatamente, y me dije a mí mismo que "me ocuparía del tema de los hooks después". Clásico.

Resultó que los hooks no eran un agradable extra. Eran la pieza faltante que hacía que Claude Code realmente se ajustara a un flujo de trabajo de agencia real en lugar de ser un autocompletado muy costoso que ocasionalmente ignoraba ESLint.

Qué Son Realmente los Hooks de Claude Code (Sin Abstracciones Vagas)

Los hooks son comandos shell que Claude Code ejecuta en puntos específicos durante su propia operación. Piénsalos como eventos del ciclo de vida, similares a los hooks de Git si alguna vez escribiste un script pre-commit, pero conectados al bucle de uso de herramientas del AI en lugar del pipeline de commits de Git.

Hay cuatro tipos de eventos por ahora:

  • PreToolUse, se ejecuta antes de que Claude llame a cualquier herramienta (ediciones de archivo, comandos bash, etc.)
  • PostToolUse, se ejecuta después de que una llamada a herramienta se completa
  • Notification, se dispara cuando Claude te envía una notificación
  • Stop, se ejecuta cuando Claude termina su turno de respuesta completa

Los configuras en un archivo settings.json dentro de la carpeta .claude/ de tu proyecto, o globalmente en ~/.claude/settings.json si quieres que estén disponibles en todas partes. Cada hook obtiene un matcher (qué herramienta o evento lo dispara) y un array de hooks de comandos shell para ejecutar.

El output de tu hook se alimenta nuevamente al contexto de Claude. Ese último detalle es lo que hace esto genuinamente interesante en lugar de ser solo un fancy cron job.

Por Qué Esto Es Diferente a Simplemente Ejecutar Scripts Tú Mismo

Podrías ejecutar Prettier manualmente después de cada edición de Claude. Lo hice, durante aproximadamente dos semanas, hasta que olvidé durante un empujón de deadline y hice push a un PR con 47 violaciones de formato. Los hooks se ejecutan automáticamente, dentro de la sesión, y Claude puede leer su output. Entonces si tu linter lanza una advertencia, Claude la ve y puede actuar en consecuencia en la misma sesión. Ese ciclo de retroalimentación es todo el punto.

La Configuración Que Realmente Funcionó para Proyectos de Seahawk

Voy a ser específico aquí porque el consejo genérico "añade hooks a tu configuración" que encontrarás en la mayoría de write-ups es inútil sin contexto.

En Seahawk, una gran parte de nuestro trabajo son builds de WordPress y customizaciones de WooCommerce. También hacemos frontends de React para setups headless, y hemos estado usando Next.js fuertemente desde 2022. La configuración de hooks que implementé aborda problemas específicos de esos stacks.

Aquí está la estructura de settings.json que uso para un proyecto Next.js:

`` { "hooks": { "PostToolUse": [ { "matcher": "Write|Edit|MultiEdit", "hooks": [ { "type": "command", "command": "npx prettier --write $CLAUDE_FILE_PATHS && npx eslint --fix $CLAUDE_FILE_PATHS" } ] } ], "Stop": [ { "matcher": ".*", "hooks": [ { "type": "command", "command": "npx tsc --noEmit 2>&1 | head -20" } ] } ] } } ``

El hook PostToolUse ejecuta Prettier y ESLint inmediatamente después de que Claude toca un archivo. El hook Stop ejecuta una verificación de tipos TypeScript al final de cada turno y muestra las primeras 20 líneas de cualquier error. Claude lee ese output, y si hay errores de tipo, los corrige antes de que yo vea siquiera la respuesta.

Esa verificación de TypeScript por sí sola me ahorró probablemente cuatro horas el mes pasado en un proyecto de dashboard fintech donde el cliente tenía strict noImplicitAny configurado. Claude seguía generando tipos any en funciones utilitarias. Después de que añadí el hook Stop, comenzó a autocorregirse dentro del mismo turno.

Los Hooks Que Uso en Proyectos WordPress / PHP

WordPress es otra cosa. Sin TypeScript, obvio, pero PHP_CodeSniffer con el ruleset de WordPress Coding Standards es lo que mantiene las cosas bajo control. Allá por 2022 tenía un dev junior en un proyecto WooCommerce que pasó dos semanas sin ejecutar PHPCS. La revisión de código fue... desagradable.

Para proyectos PHP-heavy mi hook PostToolUse corre:

`` vendor/bin/phpcs --standard=WordPress $CLAUDE_FILE_PATHS 2>&1 | tail -30 ``

Y lo emparejo con un hook PreToolUse en comandos bash:

`` { "matcher": "Bash", "hooks": [ { "type": "command", "command": "echo 'Bash tool triggered' >> ~/.claude/audit.log && date >> ~/.claude/audit.log" } ] } ``

Ese segundo es pura paranoia. Escribe cada comando bash que Claude ejecuta en un audit log. Cuando estás corriendo Claude Code en un environment staging en vivo (sí, lo he hecho, sí es un poco riesgoso), saber exactamente qué comandos de shell se ejecutaron es genuinamente tranquilizador.

Bloquear Comportamiento Con Códigos de Salida de Hook

Esta parte de la documentación me costó encontrarla. Si tu hook termina con código 2, Claude Code lo trata como un bloqueo y no procede con la llamada de tool. El código de salida 0 es éxito, cualquier cosa no-cero (pero no 2) solo devuelve el stderr como contexto.

Así que puedes escribir un hook PreToolUse que realmente le impida a Claude hacer algo. Yo lo uso en proyectos que tienen un directorio migrations/ que no quiero que Claude toque autónomamente:

`` #!/bin/bash if echo "$CLAUDE_FILE_PATHS" | grep -q "migrations/"; then echo "Migrations folder is protected. Do not edit migration files autonomously." exit 2 fi exit 0 ``

Ese script vive en .claude/hooks/guard-migrations.sh. Cuando Claude intenta escribir en cualquier cosa bajo migrations/, se bloquea y ve el mensaje. Luego me pregunta si proceder. Simple, efectivo.

Este es el tipo de control que marca la diferencia entre "más o menos confío en esta IA con mi codebase" y "realmente confío en ella con mi codebase".

Patrones de Hook Prácticos Que Vale la Pena Copiar

No son teóricos. Cada uno vino de un dolor de cabeza específico.

  1. Ejecutar tests automáticamente después de editar archivos. Corro npx jest --testPathPattern=$CLAUDE_FILE_PATHS --passWithNoTests en un hook PostToolUse. Solo corre tests relacionados con el archivo que Claude acaba de editar, no toda la suite. Lo bastante rápido para no ser molesto.
  2. Snapshot de formato listo para commit. Un hook Stop que corre git diff --stat y devuelve el resumen a Claude. Ve exactamente qué cambió durante la sesión, lo que ayuda a escribir un mensaje de commit sensato si lo pido.
  3. Verificación de seguridad de variables de entorno. Un hook PreToolUse en Write que busca patrones de secretos hardcodeados (cosas que se ven como claves API o contraseñas). Si encuentra algo sospechoso, termina con 2. Debería haber construido este hace unos 18 meses.
  4. Hook de notificación para tareas largas. Cuando Claude envía una notificación (el evento Notification), ejecuto una llamada curl a un endpoint Pushover para recibir una notificación push en mi teléfono. Genuinamente útil cuando lanzas un refactor grande y vas a prepararte un café.
  5. Verificación de sintaxis PHP antes de bash. En proyectos WordPress, un rápido php -l $CLAUDE_FILE_PATHS antes de cualquier ejecución bash. Atrapa errores de sintaxis fatal antes de que rompan un servidor staging.

La documentación oficial de Claude Code hooks tiene una referencia completa de variables de entorno disponibles dentro de scripts de hook. Vale la pena marcar.

Lo Que los Hooks No Arreglan

La honestidad importa aquí. Los hooks no son una solución para Claude generando código lógicamente incorrecto. Arreglan problemas de proceso: formato, linting, type safety, cobertura de tests. Si Claude malentiende tu modelo de datos y construye la feature equivocada, ninguna cantidad de linting post-edición lo atrapará.

Los hooks también añaden latencia. Si tu pase Prettier + ESLint toma cuatro segundos, cada edición de archivo ahora toma cuatro segundos más. En un proyecto con 200 ediciones de archivo en una sesión, eso son 13 minutos de espera. Perfila tus comandos de hook. Mantenlos rápidos. Corro variantes --fix (que modifican archivos in place) en lugar de variantes report-only precisamente porque un único pase rápido gana a un pase lento seguido de un segundo pase correctivo.

Y requieren que realmente pienses en los modos de fallo de tu proyecto por adelantado. ¿Qué puede salir mal si Claude edita el archivo equivocado? ¿Qué estándares absolutamente deben ser forzados? Ese pensamiento es valioso de todos modos, pero significa que los hooks favorecen a desarrolladores experimentados más que a principiantes.

Configurar Hooks: Paso a Paso

Para cualquiera que empiece desde cero:

  1. Crea una carpeta .claude/ en la raíz de tu proyecto si no existe.
  2. Añade un archivo settings.json con tu configuración de hooks (la estructura se muestra arriba).
  3. Para cualquier cosa más que una línea, escribe un script de shell separado (.claude/hooks/tu-script.sh), hazlo ejecutable con chmod +x, y llámalo desde la configuración en lugar de incluir el comando directamente.
  4. Prueba ejecutando claude en tu proyecto y activa deliberadamente la condición del hook. Lee lo que vuelve en el contexto de la sesión.
  5. Revisa los logs de ejecución del hook en ~/.claude/logs/ si algo no se dispara como se espera.

La documentación de desarrolladores de Anthropic cubre el esquema de configuración completo. Y si estás pensando en cómo los hooks encajan en flujos de trabajo de IA más amplios, el blog de Simon Willison es donde enviaría a quien quiera pensar con más cuidado sobre herramientas de IA agentiva en proyectos reales.

Una cosa que hice mal al principio: puse todos mis hooks en el ~/.claude/settings.json global y luego me pregunté por qué mis hooks de PHP se disparan en proyectos JavaScript. La configuración a nivel de proyecto anula la global. Pon hooks específicos de tu stack en el .claude/settings.json del proyecto y guarda tu configuración global para cosas que deberían aplicarse en todas partes (como el log de auditoría y el hook de notificaciones).

FAQ

¿Funcionan los hooks de Claude Code en Windows?

Los comandos del hook se ejecutan en el shell que usa tu sistema. En Windows eso es PowerShell o CMD por defecto, lo que significa que los scripts estilo bash no funcionarán nativamente. WSL2 es la solución práctica aquí. Yo estoy en macOS y Ubuntu en mis máquinas de desarrollo, así que no me he encontrado esto personalmente, pero la documentación de Anthropic anota explícitamente la dependencia del shell.

¿Pueden los hooks acceder al contexto de conversación de Claude?

No directamente. Los hooks se ejecutan como comandos de shell y reciben variables de entorno como CLAUDE_FILE_PATHS y CLAUDE_TOOL_NAME, pero no obtienen la transcripción completa de la conversación. Lo que sí pueden hacer es escribir salida a stdout, que Claude lee como contexto después de que el hook se ejecuta.

¿Ralentizarán los hooks mis sesiones de Claude Code notablemente?

Depende completamente de qué hagan tus hooks. Una verificación de sintaxis php -l en un archivo único está bajo 100ms. Ejecutar tu suite completa de Jest en cada edición de archivo sería frustrante. Mantén los comandos individuales del hook por debajo de dos o tres segundos y apenas los notarás.

¿Es seguro usar hooks en entornos de producción?

Yo plantearía esa pregunta al revés: ¿estás ejecutando Claude Code directamente en producción? Si es sí, los hooks son lo de menos de tus preocupaciones. Úsalos en staging, usa el patrón de bloqueo PreToolUse para proteger directorios sensibles, y mantén a Claude lejos de bases de datos de producción completamente.

¿Cuál es la diferencia entre hooks a nivel de proyecto y globales?

Los hooks globales viven en ~/.claude/settings.json y se aplican a cada sesión de Claude Code en tu máquina. Los hooks a nivel de proyecto viven en .claude/settings.json dentro de un proyecto específico y solo se disparan cuando estás en ese proyecto. El nivel de proyecto tiene precedencia donde ambos definen el mismo evento.

---

El resumen honesto: los hooks no son glamorosos. Nadie va a escribir un artículo de blog sobre la arquitectura hermosa de un script de shell que ejecuta Prettier. Pero son la diferencia entre que Claude Code sea un juguete prototipo y que sea algo en lo que realmente confiarías en trabajo de clientes. Debería haberlos configurado el primer día. Probablemente tú también deberías.

← volver