Configurar hooks en Claude Code: eventos y settings.json
Hola, bienvenido. En la lección anterior vimos qué es un hook, los 5 tipos que existen y cuándo tiene sentido usarlo en lugar de un permiso, una rule o una skill, y en esta lección vamos a bajar a la configuración. Veremos los 3 eventos que vamos a usar en claude-tasks, cómo se escribe un hook dentro de settings.json, por qué vamos a usar la forma exec, qué hace el campo timeout, para qué necesitamos jq, cuándo se ejecutan los hooks de un proyecto según la confianza en la carpeta y cómo comprobar con /hooks lo que ha cargado Claude Code. Todavía no vamos a registrar ningún hook: el primero, el de seguridad, llega en la siguiente lección, y todo lo que veamos aquí es lo que vas a necesitar para entenderlo línea a línea.
¿Por qué dedicarle una lección entera a la configuración? Porque un hook mal configurado falla sin que te des cuenta. Un filtro con una mayúscula de menos, una ruta que no existe o un script sin permiso de ejecución no paran la sesión: Claude Code muestra un aviso breve, la acción sigue adelante y el hook no hace nada. Si ese hook era el que tenía que bloquear un comando destructivo, te acabas de quedar sin barrera, y la documentación lo avisa expresamente: una ruta mal escrita en settings.json deja la barrera desactivada sin que nada falle a la vista. Así que antes de escribir el primer script conviene saber exactamente qué lee Claude Code, en qué momento y qué hace con lo que le devuelve el hook.
Para seguir esta lección necesitas claude-tasks tal y como lo dejamos en la sección de skills, con el .claude/settings.json de la lección del sandbox, y Claude Code actualizado. La forma exec, que es la que vamos a usar en todos los hooks del curso, necesita la versión 2.1.139 o posterior.
Los eventos que vamos a usar
La lista de eventos de Claude Code pasa de 30, y no hace falta conocerlos todos. En claude-tasks vamos a usar 3, uno antes de cada herramienta, otro después y otro cuando envías un prompt:
| Evento | Cuándo se dispara | Qué puede hacer el hook | Filtro | Tiempo máximo por defecto |
|---|---|---|---|---|
PreToolUse |
Antes de que se ejecute una herramienta | Bloquearla, pedirte confirmación o añadir contexto para Claude | Nombre de la herramienta | 600 segundos |
PostToolUse |
Después de que una herramienta termina con éxito | Añadir contexto o un motivo junto al resultado, sin deshacer nada | Nombre de la herramienta | 600 segundos |
UserPromptSubmit |
Cuando envías un prompt, antes de que Claude lo procese | Añadir contexto al prompt o rechazarlo | No admite filtro | 30 segundos |
Fíjate en 3 detalles de la tabla que nos van a afectar. El primero, que PostToolUse solo se dispara cuando la herramienta termina bien: si falla, el evento es PostToolUseFailure, que no vamos a usar. El segundo, que PreToolUse solo se dispara cuando Claude llama a una herramienta, así que los archivos que mencionas con @ en el prompt no pasan por él, porque Claude Code los añade al prompt sin ninguna llamada. Para esos archivos lo que manda es la regla Read(./.env) que pusimos en deny, y por eso el hook de seguridad de la siguiente lección se suma a esa regla en lugar de sustituirla. Y el tercero, que UserPromptSubmit tiene un tiempo máximo más corto que el resto, 30 segundos, porque se ejecuta antes de cada prompt y bloquea la sesión hasta que termina.
El resto de eventos cubre momentos como el inicio y el final de la sesión, la compactación, el final de cada respuesta con Stop o el trabajo de los subagentes. Algunos han llegado en 2026, como MessageDisplay, que se dispara mientras se muestra el texto de una respuesta y llegó en la versión 2.1.152, DirectoryAdded, cuando añades un directorio de trabajo con /add-dir, desde la 2.1.219, o PreModelSwitch y PostModelSwitch, antes y después de un cambio de modelo, desde la 2.1.251. Si algún día necesitas uno de ellos, la referencia de hooks tiene la entrada y la salida de cada uno.
- 02Cómo se escribe un hook en settings.json
- 03Qué recibe y qué devuelve un hook
- 04Cuándo se ejecutan los hooks de un proyecto
- 05Comprobar los hooks con /hooks