¿Qué pasa entre tu pregunta y tu siguiente turno?
Tú escribes una pregunta. Claude responde. Acabas de leer la respuesta y, antes de seguir, te preguntas: ¿pasó algo automáticamente entre que Claude terminó y tú vas a escribir lo siguiente?
La respuesta es: depende. Si tienes hooks configurados, sí · scripts pequeños que se ejecutan en momentos concretos del ciclo de vida de Claude. Si no los tienes, no pasa nada · Claude termina su turno y espera tu prompt.
Esta entrada es sobre los hooks Stop. La parte del ciclo que mucha gente confunde con "hacer que Claude reaccione". No es eso. Vamos a precisarlo.
La analogía · el secretario invisible
Imagina que Claude es un consultor que entra en tu oficina, hace su trabajo y se va. Cuando Claude termina · puede entrar un secretario invisible que ordena los papeles del consultor: archiva, guarda copias, registra qué se hizo · y deja la oficina lista para el próximo turno.
El secretario es opcional. Si no lo contratas (no configuras hooks), el consultor termina y se va · y los papeles quedan donde los dejó. Si lo contratas (configuras un Stop hook), entra automáticamente cada vez que Claude termina · sin que tú lo llames.
Lo importante: el secretario no hace que Claude reaccione. Claude ya respondió. El secretario solo trabaja después.
Bases conceptuales · qué es un hook Stop
Los hooks de Claude Code son scripts que se ejecutan en puntos específicos del ciclo de vida. Cita verbatim de la documentación:
"Hooks are user-defined shell commands, HTTP endpoints, or LLM prompts that execute automatically at specific points in Claude Code's lifecycle." — docs.claude.com/en/hooks
Hay 12 eventos en el ciclo. Para esta entrada nos centramos en Stop. Cita verbatim de cuándo dispara:
"When Claude finishes responding" — docs.claude.com/en/hooks
Es decir, el hook Stop se ejecuta cuando Claude ha terminado de responder. No causa la respuesta. No la modifica. Se ejecuta después · independiente del contenido.
Diferencia con PostToolUse
Pequeña pero importante. PostToolUse dispara después de cada tool call que hace Claude (escribir un archivo · ejecutar un Bash · etc.). Stop dispara después del turno completo · una vez por respuesta · cuando Claude considera que ha acabado.
Un turno puede contener N tool calls. Por tanto, un turno típico:
[Tu prompt]
→ Claude piensa
→ tool call 1 (Read) · PostToolUse dispara
→ tool call 2 (Edit) · PostToolUse dispara
→ tool call 3 (Bash) · PostToolUse dispara
→ Claude termina su respuesta · Stop dispara (1 sola vez)
[Esperando tu siguiente prompt]
Demo paso a paso · tu primer Stop hook
Vamos a configurar un Stop hook que escribe una línea en un log cada vez que Claude termina de responder.
Paso 1 · localiza tu settings.json
Hay 3 ubicaciones donde puedes poner hooks. Para empezar, usa el de proyecto:
mkdir -p .claude
touch .claude/settings.jsonPaso 2 · escribe el hook
Edita .claude/settings.json:
{
"hooks": {
"Stop": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "echo \"$(date -Iseconds) · turno cerrado\" >> .claude/turn-log.txt"
}
]
}
]
}
}Paso 3 · pruébalo
Lanza una sesión de Claude Code · pídele cualquier cosa pequeña ("dime qué hora es"). Cuando termine la respuesta:
cat .claude/turn-log.txtVerás una línea con la fecha en ISO 8601. Cada vez que Claude cierra un turno, se añade otra línea. Si no aparece nada, mira la sección de debug abajo.
Paso 4 · variante útil · auto-commit
Si quieres que el hook haga algo más útil que un log, este patrón es habitual: auto-stage de cambios pendientes (sin commit · solo stage · para que tú revises antes):
{
"hooks": {
"Stop": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "git add -A && echo \"changes staged · review with git status\""
}
]
}
]
}
}Lo que NO cubre
Para mantener la regla anti-alucinación · convención clara desde el principio:
- Esto NO hace que Claude reaccione. Claude siempre responde cuando recibe un prompt · es función nativa del agente · no necesita hooks. Los hooks ejecutan scripts externos alrededor del ciclo de Claude · no causan reactividad de Claude.
- El hook Stop NO siempre cierra la sesión. Puede devolver
decision: "block"y entonces Claude continúa la conversación. Cita verbatim:"Prevents Claude from stopping, continues the conversation" — docs.claude.com/en/hooks
- No es magia. Es un script
bash(o HTTP endpoint · o LLM prompt) que se ejecuta cuando dispara el evento. Si el script falla, falla el hook · no falla Claude. - No reemplaza CI/CD. Stop hook útil para tareas locales · log · staging · cleanup. Para deploy, tests, lint serios · usa pre-commit hooks de git, GitHub Actions o lo que ya uses.
Debug · cuando un hook no dispara
Síntoma · cambias el settings.json, pides algo a Claude, no pasa nada en el archivo log. Tres cosas a revisar:
- Matcher. Asegúrate de que el matcher es
.*o coincide con el contexto. Para Stop,.*está bien. - Evento. ¿Es
Stopo queríasPostToolUse? Recuerda: Stop dispara al final del turno completo, no después de cada tool. - Permission · path. El
commandejecuta en el directorio del proyecto. Si escribes a una ruta absoluta sin permisos · falla silenciosamente. Empieza por escribir a un fichero relativo dentro del proyecto.
Próximos pasos
- SOUL.md · identidad agente. Cuando entiendes hooks · el siguiente nivel es identidad persistente del agente. SOUL.md es la convención canonical para dar voz, personalidad y reglas no negociables a Claude.
- settings.json · 3 niveles. User · project · local · cuándo cada uno · evita pisar configuraciones.
- PreToolUse · el portero antes de la acción. El hook que sí puede bloquear una operación destructiva antes de que ocurra.
Si vienes a por la versión cronológica (cómo aprendí a usar hooks en mis primeros 6 meses), está en mi diario.
Si tienes empresa y te interesa cómo aplicar hooks + agentes a procesos de negocio · visita deviam.es/biblioteca para el ángulo empresarial.