Hasta aquí Claude Code reacciona a tus prompts. Con hooks reacciona también a eventos: antes de cada edición, después de cada Bash, al cerrar la sesión. Y con memoria persistente recuerda entre sesiones. Estas dos piezas juntas permiten que Claude Code se comporte como un colega que conoce tu equipo, no como un consultor que llega de cero cada lunes.
Objetivos
Conocer los 6 tipos de hooks y cuándo se disparan.
Configurar un hook con settings.json.
Diferenciar CLAUDE.md a nivel proyecto, repo y usuario.
Usar memoria persistente para mantener contexto entre sesiones.
Aplicar buenas prácticas: cuándo guardar, qué no guardar.
8.1 ¿Qué es un hook?
Un hook es un comando shell que Claude Code ejecuta automáticamente cuando ocurre un evento. Tú no lo invocas — el sistema lo dispara. Es similar a los pre-commit / post-merge hooks de Git, pero a nivel de agente.
Tipos de eventos:
Hook
Cuándo se dispara
Uso típico
PreToolUse
Antes de ejecutar cualquier herramienta.
Validar permisos, logging, denegar.
PostToolUse
Después de una herramienta.
Auto-format, lint, sync.
UserPromptSubmit
Al enviar un prompt.
Inyectar contexto adicional.
Stop
Al terminar la respuesta del agente.
Resumen, notificación, commit auto.
SubagentStop
Al terminar un subagente.
Auditar tareas largas.
SessionStart
Al abrir Claude Code en un proyecto.
Cargar variables, mostrar bienvenida.
Los hooks se ejecutan en tu shell y reciben el evento por stdin (JSON). Pueden modificar lo que pasa: bloquear una llamada, añadir contexto, anotar logs, todo lo que quieras.
Significado: cada vez que el agente escribe o edita un fichero, ejecutar prettier sobre ese fichero. Resultado: tu repo nunca tiene código mal formateado, da igual lo que el agente produzca.
Variables disponibles en el comando
Variable
Contiene
$CLAUDE_TOOL_NAME
Nombre de la herramienta (Edit, Write, Bash…)
$CLAUDE_TOOL_INPUT
JSON de los argumentos de la tool
$CLAUDE_TOOL_INPUT_FILE_PATH
Ruta del archivo (cuando aplica)
$CLAUDE_PROJECT_PATH
Raíz del proyecto
$CLAUDE_SESSION_ID
ID de la sesión actual
Bloquear con un hook
Si el comando del hook devuelve exit code distinto de 0, la operación se cancela. Útil para validaciones:
El script analiza el comando que va a ejecutarse y bloquea si detecta patrones de riesgo (rm -rf, git push --force, DROP TABLE…). Más estricto que la denylist porque puedes aplicar lógica.
Hook ≠ regla de negocio. Los hooks son código que se ejecuta. Un hook mal escrito puede bloquear tu flujo o inducir efectos extraños. Empieza con uno simple, valida que funciona, y solo entonces añade más.
8.4 Memoria entre sesiones: CLAUDE.md
El fichero CLAUDE.md es la primera capa de memoria persistente. Se carga automáticamente al iniciar Claude Code en un proyecto y se mantiene en el contexto durante toda la sesión.
Las tres capas de CLAUDE.md
Repo: ./CLAUDE.md — el principal. Convenciones del proyecto, mapa, pitfalls.
Subdirectorio: ./packages/web/CLAUDE.md — overrides locales en monorepos. Se carga adicionalmente cuando trabajas en ese subárbol.
Las tres capas se cargan y mergean. Si hay conflictos, el más cercano al fichero gana (subdirectorio > repo > usuario).
Qué poner en el CLAUDE.md del repo
TL;DR del proyecto — qué es, cómo arranca.
Comandos clave — npm scripts, deploy, tests.
Arquitectura mínima — qué hay en cada carpeta.
Reglas de oro — lo que nadie debe romper sin discutirlo.
Pitfalls — los pies de banco del repo: lock files raros, comandos que se atascan, handlers globales que duelen.
Qué NO poner
Tutoriales largos. Para eso está la documentación.
Código de ejemplo extenso. Mejor referencia "ver src/...".
Cosas que cambian a diario. CLAUDE.md vive con el repo, no es un changelog.
Secretos. Nunca.
Métrica práctica: un buen CLAUDE.md cabe en 100-200 líneas. Si pasa de 400, conviene partir en sub-CLAUDE.md o factorizar a documentos referenciados.
8.5 Memoria persistente avanzada
Más allá del CLAUDE.md estático, Claude Code soporta memoria de archivo: ficheros que el agente puede crear y actualizar entre sesiones para acordarse de cosas.
- [Rol del usuario](user_role.md) — backend senior, ahora en frontend
- [Tests sin mocks](feedback_tests.md) — política tras incident Q3
- [Goals Q1](project_q1_goals.md) — entrega login passkeys el 31/3
- [Dashboards oncall](reference_dashboards.md) — Grafana endpoints
Cada fichero del que se hace puntero tiene frontmatter:
---
name: feedback-tests-no-mock
description: No mockear DB en tests de integración. Política tras incident del Q3 2025 donde mocks pasaron y prod falló.
type: feedback
---
Los tests de integración deben pegar a una BD real (postgres en docker).
Razón: en Q3 2025 la migración pasó tests con mocks y rompió prod.
Consolidación periódica: usa la skill consolidate-memory cada cierto tiempo. Hace un pase reflexivo: detecta duplicados, fusiona, actualiza el índice y elimina memoria obsoleta. Como hacer Marie Kondo a tu memoria persistente.
8.7 Verificar la memoria antes de actuar
La memoria es estática: lo que era cierto al guardarla puede haber cambiado. Antes de actuar sobre una recomendación basada en memoria:
Si la memoria menciona un fichero — comprueba que existe.
Si menciona una función — grep para confirmar.
Si menciona una política — pregúntate si sigue vigente.
"La memoria dice X" no es lo mismo que "X es cierto ahora". Esta verificación es responsabilidad del agente — pero como humano puedes recordárselo si actúa sin chequear.
Práctica
Ejercicio 8.1 · Hook de auto-format
Configura un hook PostToolUse que ejecute prettier --write sobre cualquier .ts o .tsx que el agente cree o modifique. Pruébalo pidiendo a Claude Code que cree un nuevo componente. Verifica que el archivo está formateado al final.
Ejercicio 8.2 · Bloqueo de comandos peligrosos
Crea scripts/guard-bash.js que lea de stdin el JSON de la herramienta y haga exit 1 si detecta:
rm -rf / o variantes.
git push --force.
DROP TABLE.
chmod 777.
Conéctalo como hook PreToolUse con matcher Bash. Prueba pidiendo al agente que ejecute uno de esos comandos — debe ser bloqueado.
Ejercicio 8.3 · CLAUDE.md de tu proyecto
Si trabajas en un repo real, escribe (o mejora) su CLAUDE.md. Debe incluir:
TL;DR (1 párrafo).
Cómo arrancar el proyecto.
3-5 reglas de oro.
Pitfalls reales (cosas que han roto en el pasado).
Compáralo con el CLAUDE.md autogenerado por /init. ¿Qué le falta al automático?
Test de comprensión
1. ¿Qué hook ejecutarías para auto-formatear el código?
PreToolUse con matcher Edit
PostToolUse con matcher Write o Edit
UserPromptSubmit
SessionStart
Respuesta correcta: B. PostToolUse se dispara después de que el archivo se haya escrito. Pre se dispara antes — sería demasiado pronto.
2. Tu hook PreToolUse devuelve exit 1. ¿Qué pasa?
Se ignora el error.
Se cancela la herramienta y el agente recibe el error.
Se cierra Claude Code.
Se reintenta con otro modelo.
Respuesta correcta: B. Exit no-cero cancela la operación. El agente puede leer el error en stdout/stderr y replanificar.
3. ¿Qué guardas en CLAUDE.md vs en memoria persistente?
Todo en CLAUDE.md, la memoria persistente es legacy.
Lo del proyecto en CLAUDE.md (versionado), lo del usuario / aprendizajes en memoria persistente.
Todo en memoria persistente, CLAUDE.md es opcional.
Da igual.
Respuesta correcta: B. CLAUDE.md viaja con el repo y lo lee todo el equipo. La memoria persistente es de tu instalación y captura cosas más personales o efímeras.
4. La memoria menciona la función processOrder(). Antes de recomendar usarla, ¿qué haces?
Confiar en la memoria.
Hacer grep para confirmar que sigue existiendo.
Pedirle al usuario que confirme.
Ignorar la memoria.
Respuesta correcta: B. La memoria es un snapshot histórico. Antes de actuar, verifica el estado actual del código.
Útiles para auto-format, validación, logging, notificaciones, bloqueo de comandos.
Tres capas de CLAUDE.md: usuario global, repo, subdirectorio.
Memoria persistente: ~/.claude/projects/<path>/memory/ con tipos user/feedback/project/reference.
Verifica el estado actual antes de actuar sobre lo que dice la memoria.
El siguiente módulo: el Claude Agent SDK. Cómo construir agentes propios en TypeScript / Python apoyándote en los mismos primitivos que usa Claude Code.