Esta página es una traducción de la documentación en inglés. Los comandos, identificadores y ejemplos no cambian. Runtime 7.24.4 · SDK 2.6.7. Original en inglés
Hooks de ciclo de vida
Estado: Activo Alcance: estado actual Última revisión: 2026-08-23 Responsable: entorno de ejecución de ax-code
Los hooks de ciclo de vida permiten ejecutar comandos de shell ante eventos del agente sin recompilar el entorno de ejecución. Complementan las reglas de permiso y el sandbox de aislamiento: los hooks son efectos secundarios deterministas («formatea siempre», «nunca hagas force-push»), mientras que los prompts siguen siendo orientativos.
Eventos
| Evento | Cuándo | ¿Puede bloquear? |
|---|---|---|
| PreToolUse | Antes de que se ejecute una herramienta | Sí (blockOnFailure: true) |
| PostToolUse | Después de que una herramienta termina (args: los argumentos de la herramienta). La stdout acotada o la opinión estructurada se añade al resultado de la herramienta que ve el modelo; véase más abajo |
No |
| PostToolUseFailure | Después de que una herramienta lanza un error (args: { args, error }, texto de error limitado a 4,000 caracteres). Se dispara y se olvida; el error sigue llegando al modelo sin cambios |
No |
| Stop | Cuando se completa un turno de sesión (los paquetes pueden ejecutarse al detenerse mediante automatización) | No |
| UserPromptSubmit | Cuando se envía un prompt de usuario, antes de que el mensaje se persista | Sí (blockOnFailure: true) |
| PreCompact | Antes de que se ejecute la compactación de la sesión (args: { auto, overflow }) |
No |
| SubagentStop | Cuando termina un subagente task (args: { agent, status }) |
No |
| SessionStart | Cuando se crea una sesión de nivel superior (args: { sessionID, title, time }) |
No |
| SessionEnd | Cuando una sesión se elimina o se archiva (args: { sessionID, reason }, reason es "remove" o "archive") |
No |
| PostCompact | Después de que una compactación de sesión termina con éxito (args: { sessionID, reason }, reason es "auto" o "manual"; no se dispara cuando la compactación aborta, por ejemplo por desbordamiento de contexto) |
No |
| Interrupt | Cuando un usuario o un operador cancela de forma explícita un turno en curso (args: { sessionID }; no se dispara en la finalización normal del turno ni en la limpieza interna) |
No |
Los cuatro eventos de ciclo de vida de la sesión (SessionStart, SessionEnd, PostCompact, Interrupt) y PostToolUseFailure son solo de observación: se disparan y se olvidan, nunca bloquean la vía del ciclo de vida, y sus cargas llevan solo ids, motivos y marcas de tiempo: nunca texto de la conversación, resúmenes ni salida de herramientas. Las sesiones de subagente no disparan SessionStart (ya aparecen mediante SubagentStop). SubagentStop se dispara para los hijos iniciados tanto por task como por task_parallel.
La opinión de PostToolUse llega al modelo
Un hook PostToolUse puede devolver texto al modelo. Se añade al resultado de la herramienta dentro de un
bloque <hook_feedback event="PostToolUse">, después de la propia salida de la herramienta; nunca sustituye la salida y nunca bloquea.
- Entradas heredadas (sin
protocol): stdout recortada de un hook que salió con 0. - Entradas
protocol: "claude-code":hookSpecificOutput.additionalContext, elreasonde un veredicto{"decision": "block", "reason": "..."}, o stderr cuando el hook sale con 2. Las demás salidas distintas de cero no aportan nada.
La opinión se limita a 4,000 caracteres por hook y 8,000 caracteres por llamada a herramienta, así que un hook ruidoso no puede inundar el
contexto. Esto es lo que hace útil el paquete format-after-edit: su recordatorio llega ahora al siguiente turno del modelo en lugar
de quedarse solo en el registro.
Estos nombres se corresponden con los disparadores internos de plugins de AX Code (tool.execute.before / tool.execute.after) más los hooks de prompt, compactación, subagente y parada a nivel de sesión. Los prompts sintéticos de continuación (prompts internos agentRouting: "preserve") no disparan UserPromptSubmit.
Activar paquetes
Los hooks y los plugins del proyecto ejecutan código controlado por el repositorio, así que .ax-code/hooks.json, .ax-code/plugin/ y los plugins configurados por el proyecto están desactivados de forma predeterminada. Después de revisarlos, opta por ellos fuera del repositorio al iniciar AX Code:
AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code
Luego crea .ax-code/hooks.json en tu proyecto:
{
"packs": ["format-after-edit", "block-force-push", "require-tests-on-stop", "protect-env-files", "log-bash-commands"]
}
Paquetes oficiales (≥5)
| Paquete | Eventos | Descripción |
|---|---|---|
format-after-edit |
PostToolUse | Recuerda al agente que formatee después de las ediciones |
block-force-push |
PreToolUse | Bloquea git push --force / -f |
require-tests-on-stop |
Stop | Recuerda verificar después de las mutaciones |
protect-env-files |
PreToolUse | Avisa cuando las herramientas tocan .env |
log-bash-commands |
PreToolUse | Registra los comandos bash para auditoría |
Hooks personalizados:
{
"hooks": [
{
"event": "PreToolUse",
"matcher": "bash",
"command": "echo running bash",
"blockOnFailure": false
}
]
}
Protocolo de cable de Claude Code (optativo)
Si ya tienes hooks escritos para Claude Code, una entrada puede optar por el
protocolo de cable de Claude Code con "protocol": "claude-code":
{
"hooks": [
{
"event": "PreToolUse",
"matcher": "bash",
"command": "my-claude-code-hook.sh",
"protocol": "claude-code"
}
]
}
Para los eventos que pueden bloquear (PreToolUse, UserPromptSubmit), las entradas que optaron
se decodifican con la semántica de Claude Code en lugar de la comprobación
blockOnFailure:
- Salida 2 bloquea la acción; el stderr del hook se muestra como motivo. Una stdout mal formada también bloquea (a prueba de fallos).
- Salida 0 con JSON de stdout
{"permissionDecision": "allow"|"deny"|"ask", "reason"?}:allowcontinúa;denybloquea conreason;askpausa la llamada a la herramienta en un prompt de permiso interactivohookque muestra el motivo (predeterminado"hook requested user confirmation"). El prompt es solo interactivo: ninguna reglaalways, concesión comodín ni autoaprobación autónoma puede responderlo, y una ejecución headless lo rechaza, lo que el modelo ve como un rechazo ordinario de permiso. Un hook posterior que respondadenygana sobre unaskanterior.UserPromptSubmitno tiene una llamada a herramienta a la que adjuntar un prompt, así queasksigue bloqueando ahí. La forma anidada de Claude Code{"hookSpecificOutput": {"permissionDecision": "...", "permissionDecisionReason": "..."}}se acepta como alias. - Cualquier otra salida es un error que no bloquea (se registra y la acción continúa).
Los eventos solo de observación ignoran el decodificador por completo: nunca pueden bloquear.
Las entradas sin el campo protocol se comportan exactamente como antes.
Variables de entorno disponibles para los comandos de hook:
HOOK_EVENT— PreToolUse · PostToolUse · PostToolUseFailure · Stop · UserPromptSubmit · PreCompact · SubagentStop · SessionStart · SessionEnd · PostCompact · InterruptHOOK_TOOL— id de la herramientaHOOK_SESSION_IDHOOK_ARGS_JSON— argumentos de la herramienta en JSONHOOK_ARGS_STDIN=1— los argumentos JSON completos están siempre disponibles en stdin;HOOK_ARGS_JSONestá vacío para cargas mayores de 32 KiBHOOK_PACK— nombre del paquete cuando corresponde
Los procesos hijos del hook heredan una versión saneada del entorno de AX Code. AX Code conserva las variables ordinarias de plataforma y
de herramientas, pero elimina los nombres con aspecto de secreto, las URL que llevan credenciales, las ayudas de credenciales como SSH_AUTH_SOCK
y las variables de inyección de proceso como NODE_OPTIONS. Las variables de protocolo HOOK_* de arriba se añaden después del
saneamiento y están siempre disponibles.
Los hooks heredados de plena confianza que necesitan credenciales del ambiente pueden restaurar el comportamiento anterior fuera del repositorio:
AX_CODE_HOOKS_FULL_ENV=1 AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code
Esta vía de escape expone cada variable de entorno a cada hook activado. Un repositorio no puede solicitarla mediante
.ax-code/hooks.json; úsala solo después de revisar todos los hooks y los paquetes.
Nota de seguridad: el saneamiento del entorno reduce la exposición de credenciales del ambiente, pero no aísla los comandos del hook. Los hooks siguen siendo código de shell arbitrario que puede leer archivos accesibles y usar la red del host. Trátalos como código de confianza y revisa cada hook y cada paquete activados.
Relación con el aislamiento
Los hooks no sustituyen al sandbox. Usa:
- Aislamiento de la aplicación para límites portables de escritura y de red
- Aislamiento del sistema operativo (el backend predeterminado
"auto") para el sandbox de bash impuesto por el núcleo cuando esté disponible - Hooks para efectos secundarios de política y bloqueos duros como el force-push
Consulta modo sandbox y SECURITY.md.