Qlcube
Módulo 10 · Hooks y automatización
6 horas10 / 13
Progreso del curso
77% · Módulo 10 de 13
Módulo 10 · 6 horas

Hooks y memoria persistente

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:

HookCuándo se disparaUso típico
PreToolUseAntes de ejecutar cualquier herramienta.Validar permisos, logging, denegar.
PostToolUseDespués de una herramienta.Auto-format, lint, sync.
UserPromptSubmitAl enviar un prompt.Inyectar contexto adicional.
StopAl terminar la respuesta del agente.Resumen, notificación, commit auto.
SubagentStopAl terminar un subagente.Auditar tareas largas.
SessionStartAl 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.

8.2 Configurar un hook

En settings.json, sección hooks:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\""
          }
        ]
      }
    ]
  }
}

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

VariableContiene
$CLAUDE_TOOL_NAMENombre de la herramienta (Edit, Write, Bash…)
$CLAUDE_TOOL_INPUTJSON de los argumentos de la tool
$CLAUDE_TOOL_INPUT_FILE_PATHRuta del archivo (cuando aplica)
$CLAUDE_PROJECT_PATHRaíz del proyecto
$CLAUDE_SESSION_IDID 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:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "scripts/check-no-rm-rf.sh"
          }
        ]
      }
    ]
  }
}

El script puede leer el JSON del comando, comprobar que no contiene rm -rf, y hacer exit 1 si lo detecta. Claude Code recibirá el error y replanteará.

Practica · monta un hook de auto-format

Quieres que cada vez que el agente escriba o edite un fichero, ejecute prettier sobre él. Completa el bloque hooks del settings.json:

{ "hooks": { "": [ { "matcher": "", "hooks": [ { "type": "command", "command": "npx prettier --write \"$\"" } ] } ] } }

8.3 Recetas útiles de hooks

Receta 1 · Auto-formato al guardar

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "if [[ \"$CLAUDE_TOOL_INPUT_FILE_PATH\" =~ \\.(ts|tsx|js|jsx|json)$ ]]; then npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\"; fi"
      }]
    }]
  }
}

Receta 2 · Notificación cuando termina una tarea larga

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "osascript -e 'display notification \"Claude Code ha terminado\" with title \"Atención\" sound name \"Glass\"'"
      }]
    }]
  }
}

(macOS. En Linux usa notify-send.)

Receta 3 · Inyectar timestamp en cada prompt

{
  "hooks": {
    "UserPromptSubmit": [{
      "hooks": [{
        "type": "command",
        "command": "echo '[Contexto: ahora son las '$(date '+%H:%M %d/%m/%Y')']'"
      }]
    }]
  }
}

El stdout del hook se añade al contexto del prompt. El agente sabe la hora actual sin que tú se lo digas.

Receta 4 · Bloqueo de comandos peligrosos

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "node scripts/guard-bash.js"
      }]
    }]
  }
}

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.

Receta 5 · Auto-commit al cerrar la sesión

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "cd \"$CLAUDE_PROJECT_PATH\" && git add -A && git commit -m 'WIP: $CLAUDE_SESSION_ID' --allow-empty"
      }]
    }]
  }
}

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

  1. Repo: ./CLAUDE.md — el principal. Convenciones del proyecto, mapa, pitfalls.
  2. Subdirectorio: ./packages/web/CLAUDE.md — overrides locales en monorepos. Se carga adicionalmente cuando trabajas en ese subárbol.
  3. Usuario: ~/.claude/CLAUDE.md — preferencias globales tuyas (estilo de respuesta, idioma preferido, hábitos).

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.

Por defecto, la memoria persiste en:

~/.claude/projects/<path-codificado-del-proyecto>/memory/

El agente puede crear archivos como user_role.md, feedback_testing.md, project_constraints.md con información que será útil en futuras sesiones.

Tipos de memoria

TipoPara quéEjemplo
userQuién es el usuario, qué hace, qué sabe."Senior backend engineer, 10 años Go, primera vez con React"
feedbackReglas que el usuario ha pedido que sigas."No mockear DB en tests — bug de producción del Q3"
projectEstado del proyecto, hitos, decisiones."Merge freeze 5/3/2026 por release móvil"
referencePunteros a sistemas externos."Bugs en Linear proyecto INGEST"

Cuándo guardar en memoria

  • El usuario corrige tu enfoque y la lección debería aplicar a futuras sesiones.
  • El usuario valida una decisión no obvia ("sí, ese refactor era el correcto").
  • Aprendes algo del proyecto que no está en CLAUDE.md ni en código.
  • Te dicen explícitamente "recuerda esto".

Cuándo NO guardar

  • Cosas que se ven leyendo el código.
  • Información de la conversación actual (eso es contexto, no memoria).
  • Lo que ya está en CLAUDE.md.
  • PII, secretos, datos personales.

8.6 Estructura de la memoria

El sistema sigue un patrón simple: un fichero MEMORY.md que indexa, y archivos sueltos por tema.

~/.claude/projects/myproyecto/memory/
├── MEMORY.md            ← índice
├── user_role.md
├── feedback_tests.md
├── project_q1_goals.md
└── reference_dashboards.md

MEMORY.md tiene una línea por entrada:

- [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?

  1. PreToolUse con matcher Edit
  2. PostToolUse con matcher Write o Edit
  3. UserPromptSubmit
  4. 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?

  1. Se ignora el error.
  2. Se cancela la herramienta y el agente recibe el error.
  3. Se cierra Claude Code.
  4. 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?

  1. Todo en CLAUDE.md, la memoria persistente es legacy.
  2. Lo del proyecto en CLAUDE.md (versionado), lo del usuario / aprendizajes en memoria persistente.
  3. Todo en memoria persistente, CLAUDE.md es opcional.
  4. 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?

  1. Confiar en la memoria.
  2. Hacer grep para confirmar que sigue existiendo.
  3. Pedirle al usuario que confirme.
  4. Ignorar la memoria.

Respuesta correcta: B. La memoria es un snapshot histórico. Antes de actuar, verifica el estado actual del código.

Resumen

  • Hooks: PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, SessionStart.
  • Ú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.

0 / 0Respondidas
0 / 0Aciertos
% de acierto