16 Ciclo de vida de los hooks16 Ciclo de vida de los hooks
17</h2>17</h2>
18 18
19Los hooks se activan en puntos específicos durante una sesión de Claude Code. Cuando se activa un evento y un matcher coincide, Claude Code pasa contexto JSON sobre el evento a su controlador de hook. Para hooks de comando, la entrada llega en stdin. Para hooks HTTP, llega como el cuerpo de la solicitud POST. Su controlador puede entonces inspeccionar la entrada, tomar medidas y opcionalmente devolver una decisión. Los eventos se dividen en tres cadencias: una vez por sesión (`SessionStart`, `SessionEnd`), una vez por turno (`UserPromptSubmit`, `Stop`, `StopFailure`) y en cada llamada a herramienta dentro del bucle agentico (`PreToolUse`, `PostToolUse`):19Los hooks se activan en puntos específicos durante una sesión de Claude Code. Cuando se activa un evento y un matcher coincide, Claude Code pasa contexto JSON sobre el evento a su controlador de hook. Para hooks de comando, la entrada llega en stdin. Para hooks HTTP, llega como el cuerpo de la solicitud POST. Su controlador puede entonces inspeccionar la entrada, tomar medidas y opcionalmente devolver una decisión.
20
21Los eventos se dividen en tres cadencias:
22
23* una vez por sesión: `SessionStart` y `SessionEnd`
24* una vez por turno: `UserPromptSubmit`, `Stop` y `StopFailure`
25* en cada llamada a herramienta dentro del bucle agentico: `PreToolUse` y `PostToolUse`
20 26
21<div style={{maxWidth: "500px", margin: "0 auto"}}>27<div style={{maxWidth: "500px", margin: "0 auto"}}>
22 <Frame>28 <Frame>
182| [Plugin](/es/plugins) `hooks/hooks.json` | Cuando el plugin está habilitado | Sí, incluido con el plugin |188| [Plugin](/es/plugins) `hooks/hooks.json` | Cuando el plugin está habilitado | Sí, incluido con el plugin |
183| [Skill](/es/skills) o [agent](/es/sub-agents) frontmatter | Mientras el componente está activo | Sí, definido en el archivo del componente |189| [Skill](/es/skills) o [agent](/es/sub-agents) frontmatter | Mientras el componente está activo | Sí, definido en el archivo del componente |
184 190
185Para obtener detalles sobre la resolución de archivos de configuración, consulte [settings](/es/settings). Los administradores empresariales pueden usar `allowManagedHooksOnly` para bloquear hooks de usuario, proyecto y plugin. Los hooks de plugins habilitados forzosamente en la configuración administrada `enabledPlugins` están exentos, por lo que los administradores pueden distribuir hooks verificados a través de un mercado de la organización. Consulte [Hook configuration](/es/settings#hook-configuration).191Para obtener detalles sobre la resolución de archivos de configuración, consulte [settings](/es/settings).
192
193Los administradores empresariales pueden usar `allowManagedHooksOnly` para bloquear hooks de usuario, proyecto y plugin. Los hooks de plugins habilitados forzosamente en la configuración administrada `enabledPlugins` están exentos, por lo que los administradores pueden distribuir hooks verificados a través de un mercado de la organización. Consulte [Hook configuration](/es/settings#hook-configuration).
186 194
187<h3 id="matcher-patterns">195<h3 id="matcher-patterns">
188 Patrones de matcher196 Patrones de matcher
214| `SessionStart` | cómo comenzó la sesión | `startup`, `resume`, `clear`, `compact` |222| `SessionStart` | cómo comenzó la sesión | `startup`, `resume`, `clear`, `compact` |
215| `Setup` | qué bandera CLI desencadenó la configuración | `init`, `maintenance` |223| `Setup` | qué bandera CLI desencadenó la configuración | `init`, `maintenance` |
216| `SessionEnd` | por qué terminó la sesión | `clear`, `resume`, `logout`, `prompt_input_exit`, `bypass_permissions_disabled`, `other` |224| `SessionEnd` | por qué terminó la sesión | `clear`, `resume`, `logout`, `prompt_input_exit`, `bypass_permissions_disabled`, `other` |
217| `Notification` | tipo de notificación | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog`, `elicitation_complete`, `elicitation_response` |225| `Notification` | tipo de notificación | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog`, `elicitation_complete`, `elicitation_response`, `agent_needs_input`, `agent_completed` |
218| `SubagentStart` | tipo de agente | `general-purpose`, `Explore`, `Plan`, nombres de agentes personalizados, o nombres con alcance de plugin como `^my-plugin:reviewer$` |226| `SubagentStart` | tipo de agente | `general-purpose`, `Explore`, `Plan`, nombres de agentes personalizados, o nombres con alcance de plugin como `^my-plugin:reviewer$` |
219| `PreCompact`, `PostCompact` | qué desencadenó la compactación | `manual`, `auto` |227| `PreCompact`, `PostCompact` | qué desencadenó la compactación | `manual`, `auto` |
220| `SubagentStop` | tipo de agente | los mismos valores que `SubagentStart` |228| `SubagentStop` | tipo de agente | los mismos valores que `SubagentStart` |
317 325
318Todos los hooks coincidentes se ejecutan en paralelo, y los controladores idénticos se deduplicarán automáticamente. Los hooks de comando se deduplicarán por cadena de comando y `args`, y los hooks HTTP se deduplicarán por URL.326Todos los hooks coincidentes se ejecutan en paralelo, y los controladores idénticos se deduplicarán automáticamente. Los hooks de comando se deduplicarán por cadena de comando y `args`, y los hooks HTTP se deduplicarán por URL.
319 327
320Los controladores se ejecutan en el directorio actual con el entorno de Claude Code. La variable de entorno `$CLAUDE_CODE_REMOTE` se establece en `"true"` en entornos web remotos y no se establece en la CLI local.328Los controladores se ejecutan en el directorio actual con el entorno de Claude Code. La variable de entorno `$CLAUDE_CODE_REMOTE` se establece en `"true"` en entornos web remotos y no se establece en la CLI local. {/* min-version: 2.1.199 */}A partir de v2.1.199, [`$CLAUDE_CODE_BRIDGE_SESSION_ID`](/es/env-vars) se establece en el ID de sesión de [Remote Control](/es/remote-control) mientras la sesión local tiene una conexión Remote Control activa.
321 329
322<h4 id="common-fields">330<h4 id="common-fields">
323 Campos comunes331 Campos comunes
704El código de salida 2 es la forma en que un hook señala "detente, no hagas esto". El efecto depende del evento, porque algunos eventos representan acciones que pueden bloquearse (como una llamada a herramienta que aún no ha sucedido) y otros representan cosas que ya sucedieron o no pueden prevenirse.712El código de salida 2 es la forma en que un hook señala "detente, no hagas esto". El efecto depende del evento, porque algunos eventos representan acciones que pueden bloquearse (como una llamada a herramienta que aún no ha sucedido) y otros representan cosas que ya sucedieron o no pueden prevenirse.
705 713
706| Evento de hook | ¿Puede bloquear? | Qué sucede en exit 2 |714| Evento de hook | ¿Puede bloquear? | Qué sucede en exit 2 |
707| :-------------------- | :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- |715| :-------------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- |
708| `PreToolUse` | Sí | Bloquea la llamada a herramienta |716| `PreToolUse` | Sí | Bloquea la llamada a herramienta |
709| `PermissionRequest` | Sí | Deniega el permiso |717| `PermissionRequest` | Sí | Deniega el permiso |
710| `UserPromptSubmit` | Sí | Bloquea el procesamiento del prompt y borra el prompt |718| `UserPromptSubmit` | Sí | Bloquea el procesamiento del prompt y borra el prompt |
711| `UserPromptExpansion` | Sí | Bloquea la expansión |719| `UserPromptExpansion` | Sí | Bloquea la expansión |
712| `Stop` | Sí | Evita que Claude se detenga, continúa la conversación |720| `Stop` | Sí | Evita que Claude se detenga, continúa la conversación |
713| `SubagentStop` | Sí | Evita que el subagente se detenga |721| `SubagentStop` | Sí | Evita que el subagente se detenga |
714| `TeammateIdle` | Sí | Evita que el compañero se quede inactivo (el compañero continúa trabajando) |722| `TeammateIdle` | Sí | Evita que el compañero se quede inactivo, por lo que continúa trabajando |
715| `TaskCreated` | Sí | Revierte la creación de la tarea |723| `TaskCreated` | Sí | Revierte la creación de la tarea |
716| `TaskCompleted` | Sí | Evita que la tarea se marque como completada |724| `TaskCompleted` | Sí | Evita que la tarea se marque como completada |
717| `ConfigChange` | Sí | Bloquea que el cambio de configuración tenga efecto (excepto `policy_settings`) |725| `ConfigChange` | Sí | Bloquea que el cambio de configuración tenga efecto (excepto `policy_settings`) |
718| `StopFailure` | No | La salida y el código de salida se ignoran |726| `StopFailure` | No | La salida y el código de salida se ignoran |
719| `PostToolUse` | No | Muestra stderr a Claude (la herramienta ya se ejecutó) |727| `PostToolUse` | No | Muestra stderr a Claude; la herramienta ya se ejecutó |
720| `PostToolUseFailure` | No | Muestra stderr a Claude (la herramienta ya falló) |728| `PostToolUseFailure` | No | Muestra stderr a Claude; la herramienta ya falló |
721| `PostToolBatch` | Sí | Detiene el bucle agentico antes de la siguiente llamada al modelo |729| `PostToolBatch` | Sí | Detiene el bucle agentico antes de la siguiente llamada al modelo |
722| `PermissionDenied` | No | El código de salida y stderr se ignoran (la denegación ya ocurrió). Use JSON `hookSpecificOutput.retry: true` para decirle al modelo que puede reintentar |730| `PermissionDenied` | No | El código de salida y stderr se ignoran porque la denegación ya ocurrió. Use JSON `hookSpecificOutput.retry: true` para decirle al modelo que puede reintentar |
723| `Notification` | No | Muestra stderr solo al usuario |731| `Notification` | No | Muestra stderr solo al usuario |
724| `SubagentStart` | No | Muestra stderr solo al usuario |732| `SubagentStart` | No | Muestra stderr solo al usuario |
725| `SessionStart` | No | Muestra stderr solo al usuario |733| `SessionStart` | No | Muestra stderr solo al usuario |
736| `InstructionsLoaded` | No | El código de salida se ignora |744| `InstructionsLoaded` | No | El código de salida se ignora |
737| `MessageDisplay` | No | Se muestra el texto original |745| `MessageDisplay` | No | Se muestra el texto original |
738 746
747Para `SessionStart`, `Setup` y `SubagentStart`, el stderr del código de salida 2 se renderiza en la transcripción como un aviso `<hook name> hook error`, de la misma manera que un [error sin bloqueo](#exit-code-output). Claude no lo ve, y la sesión o subagente procede. Para `SubagentStart`, el aviso aparece en la propia transcripción del subagente, no en la conversación principal.
748
749A partir de Claude Code v2.1.199, `SessionStart`, `Setup` y `SubagentStart` muestran stderr del código de salida 2 en la transcripción. Las versiones anteriores lo escribían solo en el registro de depuración.
750
739<h3 id="http-response-handling">751<h3 id="http-response-handling">
740 Manejo de respuesta HTTP752 Manejo de respuesta HTTP
741</h3>753</h3>
963 Entrada de SessionStart975 Entrada de SessionStart
964</h4>976</h4>
965 977
966Además de los [campos de entrada comunes](#common-input-fields), los hooks SessionStart reciben `source` y opcionalmente `model`, `agent_type` y `session_title`. El campo `source` indica cómo comenzó la sesión: `"startup"` para nuevas sesiones, `"resume"` para sesiones reanudadas, `"clear"` después de `/clear` o `"compact"` después de compactación. El campo `model` contiene el identificador del modelo activo. Puede omitirse, por ejemplo después de `/clear` o cuando se restaura una sesión a través de recuperación de conversación, así que verifique el campo antes de leerlo. Si inicia Claude Code con `claude --agent <name>`, un campo `agent_type` contiene el nombre del agente. El campo `session_title` lleva el título de sesión actual si ya está establecido, por ejemplo a través de `--name` o `/rename`. Un hook que emite `sessionTitle` puede verificar `session_title` primero para evitar sobrescribir un título que el usuario estableció explícitamente.978Además de los [campos de entrada comunes](#common-input-fields), los hooks SessionStart reciben `source` y opcionalmente `model`, `agent_type` y `session_title`:
979
980| Campo | Descripción |
981| :-------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
982| `source` | Cómo comenzó la sesión: `"startup"` para nuevas sesiones, `"resume"` para sesiones reanudadas, `"clear"` después de `/clear` o `"compact"` después de compactación |
983| `model` | El identificador del modelo activo. Puede omitirse, por ejemplo después de `/clear` o cuando se restaura una sesión a través de recuperación de conversación, así que verifique el campo antes de leerlo |
984| `agent_type` | El nombre del agente, presente cuando inicia Claude Code con `claude --agent <name>` |
985| `session_title` | El título de sesión actual si ya está establecido, por ejemplo a través de `--name` o `/rename`. Un hook que emite `sessionTitle` puede verificar `session_title` primero para evitar sobrescribir un título que el usuario estableció explícitamente |
967 986
968```json theme={null}987```json theme={null}
969{988{
983Cualquier texto que su script de hook imprima en stdout se agrega como contexto para Claude. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, puede devolver estos campos específicos del evento:1002Cualquier texto que su script de hook imprima en stdout se agrega como contexto para Claude. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, puede devolver estos campos específicos del evento:
984 1003
985| Campo | Descripción |1004| Campo | Descripción |
986| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |1005| :------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
987| `additionalContext` | Cadena agregada al contexto de Claude al inicio de la conversación, antes del primer prompt. Consulte [Agregar contexto para Claude](#add-context-for-claude) para saber cómo se entrega el texto y qué poner en él |1006| `additionalContext` | Cadena agregada al contexto de Claude al inicio de la conversación, antes del primer prompt. Consulte [Agregar contexto para Claude](#add-context-for-claude) para saber cómo se entrega el texto y qué poner en él |
988| `initialUserMessage` | Cadena utilizada como el primer mensaje de usuario de la sesión. Se aplica en [modo no interactivo](/es/headless) (`-p`), donde se convierte en el primer turno incluso si no se proporciona ningún prompt. Si se proporciona un prompt, sigue como el siguiente turno. A diferencia de `additionalContext`, que se adjunta a un turno existente, esto crea el turno |1007| `initialUserMessage` | Cadena utilizada como el primer mensaje de usuario de la sesión. Se aplica en [modo no interactivo](/es/headless) con la bandera `-p`, donde se convierte en el primer turno incluso si no se proporciona ningún prompt. Si se proporciona un prompt, sigue como el siguiente turno. A diferencia de `additionalContext`, que se adjunta a un turno existente, esto crea el turno |
989| `sessionTitle` | Establece el título de la sesión, con el mismo efecto que `/rename`. Use para nombrar sesiones automáticamente desde la carpeta de lanzamiento, rama de git o nombre de worktree. Se aplica solo cuando `source` es `"startup"` o `"resume"`; se ignora en `"clear"` y `"compact"` |1008| `sessionTitle` | Establece el título de la sesión, con el mismo efecto que `/rename`. Use para nombrar sesiones automáticamente desde la carpeta de lanzamiento, rama de git o nombre de worktree. Se aplica solo cuando `source` es `"startup"` o `"resume"`; se ignora en `"clear"` y `"compact"` |
990| `watchPaths` | Array de rutas absolutas para monitorear eventos [FileChanged](#filechanged) durante esta sesión |1009| `watchPaths` | Array de rutas absolutas para monitorear eventos [FileChanged](#filechanged) durante esta sesión |
991| `reloadSkills` | Booleano. Cuando es `true`, Claude Code vuelve a escanear los directorios [skill](/es/skills) y de comandos después de que se completen los hooks SessionStart, por lo que las skills que instaló el hook están disponibles en la misma sesión, comenzando con el primer prompt |1010| `reloadSkills` | Booleano. Cuando es `true`, Claude Code vuelve a escanear los directorios [skill](/es/skills) y de comandos después de que se completen los hooks SessionStart, por lo que las skills que instaló el hook están disponibles en la misma sesión, comenzando con el primer prompt |
1062 Setup1081 Setup
1063</h3>1082</h3>
1064 1083
1065Se activa solo cuando inicia Claude Code con `--init-only`, o con `--init` o `--maintenance` en modo de impresión (`-p`). No se activa en el inicio normal. Úselo para instalación de dependencias única o limpieza programada que desencadena explícitamente desde CI o scripts, separado del inicio de sesión normal. Para inicialización por sesión, use [SessionStart](#sessionstart) en su lugar.1084Se activa solo cuando inicia Claude Code con `--init-only`, o con `--init` o `--maintenance` en [modo no interactivo](/es/headless) con la bandera `-p`. No se activa en el inicio normal. Úselo para instalación de dependencias única o limpieza programada que desencadena explícitamente desde CI o scripts, separado del inicio de sesión normal. Para inicialización por sesión, use [SessionStart](#sessionstart) en su lugar.
1066 1085
1067El valor del matcher corresponde a la bandera CLI que desencadenó el hook:1086El valor del matcher corresponde a la bandera CLI que desencadenó el hook:
1068 1087
1071| `init` | `claude --init-only` o `claude -p --init` |1090| `init` | `claude --init-only` o `claude -p --init` |
1072| `maintenance` | `claude -p --maintenance` |1091| `maintenance` | `claude -p --maintenance` |
1073 1092
1074`--init-only` ejecuta hooks Setup y hooks SessionStart con el matcher `startup`, luego sale sin iniciar una conversación. `--init` y `--maintenance` activan hooks Setup solo cuando se combinan con `-p` (modo de impresión); en una sesión interactiva esas dos banderas actualmente no activan hooks Setup.1093`--init-only` ejecuta hooks Setup y hooks SessionStart con el matcher `startup`, luego sale sin iniciar una conversación. `--init` y `--maintenance` activan hooks Setup solo cuando se combinan con `-p`; en una sesión interactiva esas dos banderas actualmente no activan hooks Setup.
1075 1094
1076Debido a que Setup no se activa en cada lanzamiento, un plugin que necesita una dependencia instalada no puede confiar solo en Setup. El patrón práctico es verificar la dependencia en el primer uso e instalar si falta, por ejemplo un hook o skill que pruebe `${CLAUDE_PLUGIN_DATA}/node_modules` y ejecute `npm install` si está ausente. Consulte el [directorio de datos persistentes](/es/plugins-reference#persistent-data-directory) para saber dónde almacenar dependencias instaladas.1095Debido a que Setup no se activa en cada lanzamiento, un plugin que necesita una dependencia instalada no puede confiar solo en Setup. El patrón práctico es verificar la dependencia en el primer uso e instalar si falta, por ejemplo un hook o skill que pruebe `${CLAUDE_PLUGIN_DATA}/node_modules` y ejecute `npm install` si está ausente. Consulte el [directorio de datos persistentes](/es/plugins-reference#persistent-data-directory) para saber dónde almacenar dependencias instaladas.
1077 1096
1095 Control de decisión de Setup1114 Control de decisión de Setup
1096</h4>1115</h4>
1097 1116
1098Los hooks Setup no pueden bloquear. En código de salida 2, stderr se muestra al usuario; en cualquier otro código de salida distinto de cero, stderr aparece solo cuando inicia con `--verbose`. En ambos casos la ejecución continúa. Para pasar información al contexto de Claude, devuelva `additionalContext` en salida JSON; el stdout plano se escribe solo en el registro de depuración. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, puede devolver estos campos específicos del evento:1117Los hooks Setup no pueden bloquear. Cualquier código de salida distinto de cero, incluyendo 2, muestra stderr al usuario como un aviso de `<hook name> hook error`, y la ejecución continúa. En [modo no interactivo](/es/headless), la salida del hook aparece solo cuando inicia con `--verbose`.
1118
1119Para pasar información al contexto de Claude, devuelva `additionalContext` en salida JSON; el stdout plano se escribe solo en el registro de depuración. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, puede devolver estos campos específicos del evento:
1099 1120
1100| Campo | Descripción |1121| Campo | Descripción |
1101| :------------------ | :---------------------------------------------------------------------------------- |1122| :------------------ | :---------------------------------------------------------------------------------- |
1191* **Stdout de texto plano**: cualquier texto que no sea JSON escrito en stdout se agrega como contexto1212* **Stdout de texto plano**: cualquier texto que no sea JSON escrito en stdout se agrega como contexto
1192* **JSON con `additionalContext`**: use el formato JSON a continuación para más control. El campo `additionalContext` se agrega como contexto1213* **JSON con `additionalContext`**: use el formato JSON a continuación para más control. El campo `additionalContext` se agrega como contexto
1193 1214
1194El stdout plano se muestra como salida de hook en la transcripción. El campo `additionalContext` se agrega de forma más discreta.1215El stdout plano se muestra como salida de hook en la transcripción. El valor de `additionalContext` se inyecta como un recordatorio del sistema que Claude lee sin una entrada de transcripción visible.
1195 1216
1196Para bloquear un prompt, devuelva un objeto JSON con `decision` establecido en `"block"`:1217Para bloquear un prompt, devuelva un objeto JSON con `decision` establecido en `"block"`:
1197 1218
1215}1236}
1216```1237```
1217 1238
1218<Note>
1219 El formato JSON no es necesario para casos de uso simples. Para agregar contexto, puede imprimir texto plano en stdout con código de salida 0. Use JSON cuando necesite bloquear prompts o desee un control más estructurado.
1220</Note>
1221
1222<h3 id="userpromptexpansion">1239<h3 id="userpromptexpansion">
1223 UserPromptExpansion1240 UserPromptExpansion
1224</h3>1241</h3>
1545En `PostToolUse`, `tool_response` para una llamada Agent completada lleva el texto final del subagente junto con telemetría de uso. Lea estos campos para registrar el costo por subagente desde un hook:1562En `PostToolUse`, `tool_response` para una llamada Agent completada lleva el texto final del subagente junto con telemetría de uso. Lea estos campos para registrar el costo por subagente desde un hook:
1546 1563
1547| Campo | Tipo | Ejemplo | Descripción |1564| Campo | Tipo | Ejemplo | Descripción |
1548| :------------------ | :----- | :---------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |1565| :------------------ | :----- | :---------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1549| `status` | string | `"completed"` | `"completed"` para llamadas sincrónicas, `"async_launched"` para `run_in_background: true` |1566| `status` | string | `"completed"` | `"completed"` para subagentes en primer plano, `"async_launched"` para subagentes en segundo plano. {/* min-version: 2.1.198 */}A partir de v2.1.198, los subagentes se ejecutan en segundo plano por defecto, por lo que un `run_in_background` omitido también produce `"async_launched"` |
1550| `agentId` | string | `"a4d2c8f1e0b3a297"` | Identificador para la ejecución del subagente |1567| `agentId` | string | `"a4d2c8f1e0b3a297"` | Identificador para la ejecución del subagente |
1551| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Los bloques de texto finales del subagente |1568| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Los bloques de texto finales del subagente |
1552| `resolvedModel` | string | `"claude-sonnet-4-5"` | Modelo en el que se ejecutó el subagente, que puede diferir del modelo solicitado. {/* min-version: 2.1.174 */}Requiere Claude Code v2.1.174 o posterior |1569| `resolvedModel` | string | `"claude-sonnet-4-5"` | Modelo en el que se ejecutó el subagente, que puede diferir del modelo solicitado. {/* min-version: 2.1.174 */}Requiere Claude Code v2.1.174 o posterior |
1555| `totalToolUseCount` | number | `7` | Recuento de llamadas a herramientas que hizo el subagente |1572| `totalToolUseCount` | number | `7` | Recuento de llamadas a herramientas que hizo el subagente |
1556| `usage` | object | `{"input_tokens": 8320, ...}` | Desglose de tokens por tipo: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |1573| `usage` | object | `{"input_tokens": 8320, ...}` | Desglose de tokens por tipo: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |
1557 1574
1558Para llamadas `run_in_background: true`, la herramienta regresa inmediatamente después de lanzar el subagente, por lo que `tool_response` no lleva campos de uso. Tiene `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` y `resolvedModel`.1575Para subagentes en segundo plano, la herramienta regresa inmediatamente después de lanzar, por lo que `tool_response` no lleva campos de uso. Tiene `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` y `resolvedModel`.
1559 1576
1560El campo `resolvedModel` nombra el modelo en el que se ejecuta realmente el subagente, que puede diferir del valor `model` en `tool_input`, como cuando `availableModels` u otra anulación se aplica. Requiere Claude Code v2.1.174 o posterior.1577El campo `resolvedModel` nombra el modelo en el que se ejecuta realmente el subagente, que puede diferir del valor `model` en `tool_input`, como cuando `availableModels` u otra anulación se aplica. Requiere Claude Code v2.1.174 o posterior.
1561 1578
1593Los hooks `PreToolUse` pueden controlar si procede una llamada a herramienta. A diferencia de otros hooks que usan un campo `decision` de nivel superior, PreToolUse devuelve su decisión dentro de un objeto `hookSpecificOutput`. Esto le da control más rico: cuatro resultados (permitir, denegar, preguntar o diferir) más la capacidad de modificar la entrada de la herramienta antes de la ejecución.1610Los hooks `PreToolUse` pueden controlar si procede una llamada a herramienta. A diferencia de otros hooks que usan un campo `decision` de nivel superior, PreToolUse devuelve su decisión dentro de un objeto `hookSpecificOutput`. Esto le da control más rico: cuatro resultados (permitir, denegar, preguntar o diferir) más la capacidad de modificar la entrada de la herramienta antes de la ejecución.
1594 1611
1595| Campo | Descripción |1612| Campo | Descripción |
1596| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |1613| :------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1597| `permissionDecision` | `"allow"` omite el sistema de permisos. `"deny"` evita la llamada a herramienta. `"ask"` solicita al usuario que confirme. `"defer"` sale correctamente para que la herramienta pueda reanudarse más tarde. Las reglas [Deny and ask](/es/permissions#manage-permissions) aún se evalúan independientemente de lo que devuelva el hook |1614| `permissionDecision` | `"allow"` omite el sistema de permisos, excepto para [herramientas que requieren interacción del usuario](#pretooluse-decision-control). `"deny"` evita la llamada a herramienta. `"ask"` solicita al usuario que confirme. `"defer"` sale correctamente para que la herramienta pueda reanudarse más tarde. Las reglas [Deny and ask](/es/permissions#manage-permissions) aún se evalúan independientemente de lo que devuelva el hook |
1598| `permissionDecisionReason` | Para `"allow"` y `"ask"`, se muestra al usuario pero no a Claude. Para `"deny"`, se muestra a Claude. Para `"defer"`, se ignora |1615| `permissionDecisionReason` | Para `"allow"` y `"ask"`, se muestra al usuario pero no a Claude. Para `"deny"`, se muestra a Claude. Para `"defer"`, se ignora |
1599| `updatedInput` | Modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza el objeto de entrada completo, así que incluya campos sin cambios junto con los modificados. Combinar con `"allow"` para aprobación automática, o `"ask"` para mostrar la entrada modificada al usuario. Para `"defer"`, se ignora |1616| `updatedInput` | Modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza el objeto de entrada completo, así que incluya campos sin cambios junto con los modificados. Combinar con `"allow"` para aprobación automática, o `"ask"` para mostrar la entrada modificada al usuario. Para `"defer"`, se ignora |
1600| `additionalContext` | Cadena agregada al contexto de Claude junto con el resultado de la herramienta. Ignorado cuando `permissionDecision` es `"defer"`. Consulte [Agregar contexto para Claude](#add-context-for-claude) |1617| `additionalContext` | Cadena agregada al contexto de Claude junto con el resultado de la herramienta. Ignorado cuando `permissionDecision` es `"defer"`. Consulte [Agregar contexto para Claude](#add-context-for-claude) |
1619 1636
1620`AskUserQuestion` y `ExitPlanMode` requieren interacción del usuario y normalmente se bloquean en [modo no interactivo](/es/headless) con la bandera `-p`. Devolver `permissionDecision: "allow"` junto con `updatedInput` satisface ese requisito: el hook lee la entrada de la herramienta desde stdin, recopila la respuesta a través de su propia interfaz de usuario y la devuelve en `updatedInput` para que la herramienta se ejecute sin solicitar. Devolver `"allow"` solo no es suficiente para estas herramientas. Para `AskUserQuestion`, repita el array `questions` original y agregue un objeto [`answers`](#askuserquestion) que asigne el texto de cada pregunta a la respuesta elegida.1637`AskUserQuestion` y `ExitPlanMode` requieren interacción del usuario y normalmente se bloquean en [modo no interactivo](/es/headless) con la bandera `-p`. Devolver `permissionDecision: "allow"` junto con `updatedInput` satisface ese requisito: el hook lee la entrada de la herramienta desde stdin, recopila la respuesta a través de su propia interfaz de usuario y la devuelve en `updatedInput` para que la herramienta se ejecute sin solicitar. Devolver `"allow"` solo no es suficiente para estas herramientas. Para `AskUserQuestion`, repita el array `questions` original y agregue un objeto [`answers`](#askuserquestion) que asigne el texto de cada pregunta a la respuesta elegida.
1621 1638
1639A partir de v2.1.199, una herramienta MCP cuyo servidor la marca con [`_meta["anthropic/requiresUserInteraction"]`](/es/mcp#require-approval-for-a-specific-tool) es más estricta: un hook no puede omitir su solicitud de aprobación con `"allow"`, con o sin `updatedInput`, porque Claude Code no puede confirmar que el hook recopiló la interacción que la herramienta necesita.
1640
1622<Note>1641<Note>
1623 PreToolUse anteriormente usaba campos `decision` y `reason` de nivel superior, pero estos están deprecados para este evento. Use `hookSpecificOutput.permissionDecision` y `hookSpecificOutput.permissionDecisionReason` en su lugar. Los valores deprecados `"approve"` y `"block"` se asignan a `"allow"` y `"deny"` respectivamente. Otros eventos como PostToolUse y Stop continúan usando `decision` y `reason` de nivel superior como su formato actual.1642 PreToolUse anteriormente usaba campos `decision` y `reason` de nivel superior, pero estos están deprecados para este evento. Use `hookSpecificOutput.permissionDecision` y `hookSpecificOutput.permissionDecisionReason` en su lugar. Los valores deprecados `"approve"` y `"block"` se asignan a `"allow"` y `"deny"` respectivamente. Otros eventos como PostToolUse y Stop continúan usando `decision` y `reason` de nivel superior como su formato actual.
1624</Note>1643</Note>
2016 Notification2035 Notification
2017</h3>2036</h3>
2018 2037
2019Se ejecuta cuando Claude Code envía notificaciones. Coincide en el tipo de notificación: `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog`, `elicitation_complete`, `elicitation_response`. Omita el matcher para ejecutar hooks para todos los tipos de notificación.2038Se ejecuta cuando Claude Code envía notificaciones. Coincide en el tipo de notificación. Omita el matcher para ejecutar hooks para todos los tipos de notificación.
2039
2040| Matcher | Cuándo se activa |
2041| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
2042| `permission_prompt` | Claude necesita que apruebe un uso de herramienta |
2043| `idle_prompt` | Claude está hecho y esperando su siguiente prompt |
2044| `auth_success` | La autenticación se completa |
2045| `elicitation_dialog` | Un servidor MCP abre un formulario de elicitación |
2046| `elicitation_complete` | Un formulario de elicitación MCP se envía o se descarta |
2047| `elicitation_response` | Una respuesta de elicitación MCP se envía de vuelta al servidor |
2048| `agent_needs_input` | Una sesión en segundo plano comienza a esperar su entrada. Se activa solo mientras [agent view](/es/agent-view) está abierto en una terminal |
2049| `agent_completed` | Una sesión en segundo plano termina o falla. Se activa solo mientras [agent view](/es/agent-view) está abierto en una terminal |
2050
2051Los tipos `agent_needs_input` y `agent_completed` requieren Claude Code v2.1.198 o posterior.
2020 2052
2021Use matchers separados para ejecutar diferentes controladores dependiendo del tipo de notificación. Esta configuración desencadena un script de alerta específico de permiso cuando Claude necesita aprobación de permiso y una notificación diferente cuando Claude ha estado inactivo:2053Use matchers separados para ejecutar diferentes controladores dependiendo del tipo de notificación. Esta configuración desencadena un script de alerta específico de permiso cuando Claude necesita aprobación de permiso y una notificación diferente cuando Claude ha estado inactivo:
2022 2054
2079 Entrada de SubagentStart2111 Entrada de SubagentStart
2080</h4>2112</h4>
2081 2113
2082Además de los [campos de entrada comunes](#common-input-fields), los hooks SubagentStart reciben `agent_id` con el identificador único para el subagente y `agent_type` con el nombre del agente (agentes integrados como `"general-purpose"`, `"Explore"`, `"Plan"` o nombres de agentes personalizados).2114Además de los [campos de entrada comunes](#common-input-fields), los hooks SubagentStart reciben `agent_id` con el identificador único para el subagente y `agent_type` con el nombre del agente que el matcher filtra.
2083 2115
2084```json theme={null}2116```json theme={null}
2085{2117{
2561Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, los hooks CwdChanged pueden devolver `watchPaths` para establecer dinámicamente qué rutas de archivo [FileChanged](#filechanged) monitorea:2593Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, los hooks CwdChanged pueden devolver `watchPaths` para establecer dinámicamente qué rutas de archivo [FileChanged](#filechanged) monitorea:
2562 2594
2563| Campo | Descripción |2595| Campo | Descripción |
2564| :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |2596| :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2565| `watchPaths` | Array de rutas absolutas. Reemplaza la lista de monitoreo dinámica actual (las rutas de su configuración de `matcher` siempre se monitorean). Devolver un array vacío borra la lista dinámica, que es típico al entrar en un nuevo directorio |2597| `watchPaths` | Array de rutas absolutas. Reemplaza la lista de monitoreo dinámica actual. Las rutas de su configuración de `matcher` siempre se monitorean. Devolver un array vacío borra la lista dinámica, que es típico al entrar en un nuevo directorio |
2566 2598
2567Los hooks CwdChanged no tienen control de decisión. No pueden bloquear el cambio de directorio.2599Los hooks CwdChanged no tienen control de decisión. No pueden bloquear el cambio de directorio.
2568 2600
2586Además de los [campos de entrada comunes](#common-input-fields), los hooks FileChanged reciben `file_path` y `event`.2618Además de los [campos de entrada comunes](#common-input-fields), los hooks FileChanged reciben `file_path` y `event`.
2587 2619
2588| Campo | Descripción |2620| Campo | Descripción |
2589| :---------- | :------------------------------------------------------------------------------------------------------ |2621| :---------- | :------------------------------------------------------------------------------------------------------------------------ |
2590| `file_path` | Ruta absoluta al archivo que cambió |2622| `file_path` | Ruta absoluta al archivo que cambió |
2591| `event` | Qué sucedió: `"change"` (archivo modificado), `"add"` (archivo creado) o `"unlink"` (archivo eliminado) |2623| `event` | Qué sucedió: `"change"` para un archivo modificado, `"add"` para un archivo creado o `"unlink"` para un archivo eliminado |
2592 2624
2593```json theme={null}2625```json theme={null}
2594{2626{
2608Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, los hooks FileChanged pueden devolver `watchPaths` para actualizar dinámicamente qué rutas de archivo se monitorean:2640Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, los hooks FileChanged pueden devolver `watchPaths` para actualizar dinámicamente qué rutas de archivo se monitorean:
2609 2641
2610| Campo | Descripción |2642| Campo | Descripción |
2611| :----------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |2643| :----------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2612| `watchPaths` | Array de rutas absolutas. Reemplaza la lista de monitoreo dinámica actual (las rutas de su configuración de `matcher` siempre se monitorean). Use esto cuando su script de hook descubra archivos adicionales para monitorear basados en el archivo cambiado |2644| `watchPaths` | Array de rutas absolutas. Reemplaza la lista de monitoreo dinámica actual. Las rutas de su configuración de `matcher` siempre se monitorean. Use esto cuando su script de hook descubra archivos adicionales para monitorear basados en el archivo cambiado |
2613 2645
2614Los hooks FileChanged no tienen control de decisión. No pueden bloquear el cambio de archivo.2646Los hooks FileChanged no tienen control de decisión. No pueden bloquear el cambio de archivo.
2615 2647
2617 WorktreeCreate2649 WorktreeCreate
2618</h3>2650</h3>
2619 2651
2620Cuando ejecuta `claude --worktree` o un [subagente usa `isolation: "worktree"`](/es/sub-agents#choose-the-subagent-scope), Claude Code crea una copia de trabajo aislada usando `git worktree`. Si configura un hook WorktreeCreate, reemplaza el comportamiento predeterminado de git, permitiéndole usar un sistema de control de versiones diferente como SVN, Perforce o Mercurial.2652Se ejecuta cuando se está creando un worktree, ya sea desde `claude --worktree` o desde un [subagente usando `isolation: "worktree"`](/es/sub-agents#choose-the-subagent-scope). Por defecto Claude Code crea la copia de trabajo aislada con `git worktree`. Configurar un hook WorktreeCreate reemplaza ese comportamiento predeterminado de git, permitiéndole usar un sistema de control de versiones diferente como SVN, Perforce o Mercurial.
2621 2653
2622Debido a que el hook reemplaza el comportamiento predeterminado completamente, [`.worktreeinclude`](/es/worktrees#copy-gitignored-files-into-worktrees) no se procesa. Si necesita copiar archivos de configuración local como `.env` en el nuevo worktree, hágalo dentro de su script de hook.2654Debido a que el hook reemplaza el comportamiento predeterminado completamente, [`.worktreeinclude`](/es/worktrees#copy-gitignored-files-into-worktrees) no se procesa. Si necesita copiar archivos de configuración local como `.env` en el nuevo worktree, hágalo dentro de su script de hook.
2623 2655
2648 Entrada de WorktreeCreate2680 Entrada de WorktreeCreate
2649</h4>2681</h4>
2650 2682
2651Además de los [campos de entrada comunes](#common-input-fields), los hooks WorktreeCreate reciben el campo `name`. Este es un identificador slug para el nuevo worktree, especificado por el usuario o generado automáticamente (por ejemplo, `bold-oak-a3f2`).2683Además de los [campos de entrada comunes](#common-input-fields), los hooks WorktreeCreate reciben el campo `name`. Este es un identificador slug para el nuevo worktree, especificado por el usuario o generado automáticamente, por ejemplo `bold-oak-a3f2`.
2652 2684
2653```json theme={null}2685```json theme={null}
2654{2686{
2675 WorktreeRemove2707 WorktreeRemove
2676</h3>2708</h3>
2677 2709
2678La contraparte de limpieza de [WorktreeCreate](#worktreecreate). Este hook se activa cuando se está eliminando un worktree, ya sea cuando sale de una sesión `--worktree` y elige eliminarlo, o cuando un subagente con `isolation: "worktree"` finaliza. Para worktrees basados en git, Claude maneja la limpieza automáticamente con `git worktree remove`. Si configuró un hook WorktreeCreate para un sistema de control de versiones que no es git, emparéjelo con un hook WorktreeRemove para manejar la limpieza. Sin uno, el directorio de worktree se deja en el disco.2710Se ejecuta cuando se está eliminando un worktree, ya sea cuando sale de una sesión `--worktree` y elige eliminarlo, o cuando un subagente con `isolation: "worktree"` finaliza. Esta es la contraparte de limpieza de [WorktreeCreate](#worktreecreate).
2711
2712Para worktrees basados en git, Claude Code maneja la limpieza automáticamente con `git worktree remove`. Si configuró un hook WorktreeCreate para un sistema de control de versiones que no es git, emparéjelo con un hook WorktreeRemove para manejar la limpieza. Sin uno, el directorio de worktree se deja en el disco.
2679 2713
2680Claude Code pasa la ruta devuelta por WorktreeCreate como `worktree_path` en la entrada del hook. Este ejemplo lee esa ruta y elimina el directorio:2714Claude Code pasa la ruta devuelta por WorktreeCreate como `worktree_path` en la entrada del hook. Este ejemplo lee esa ruta y elimina el directorio:
2681 2715
3064 3098
3065Si necesita un control más fino en cualquier evento, use un [hook de comando](#command-hook-fields) con los campos por evento descritos en [Control de decisión](#decision-control).3099Si necesita un control más fino en cualquier evento, use un [hook de comando](#command-hook-fields) con los campos por evento descritos en [Control de decisión](#decision-control).
3066 3100
3067<h3 id="example-multi-criteria-stop-hook">3101<h3 id="check-multiple-conditions-before-stopping">
3068 Ejemplo: Hook Stop de múltiples criterios3102 Verificar múltiples condiciones antes de detener
3069</h3>3103</h3>
3070 3104
3071Este hook `Stop` usa un prompt detallado para verificar tres condiciones antes de permitir que Claude se detenga. Si `"ok"` es `false`, Claude continúa trabajando con la razón proporcionada como su siguiente instrucción. Los hooks `SubagentStop` usan el mismo formato para evaluar si un [subagente](/es/sub-agents) debe detenerse:3105Este hook `Stop` usa un prompt detallado para verificar tres condiciones antes de permitir que Claude se detenga. Los hooks `SubagentStop` usan el mismo formato para evaluar si un [subagente](/es/sub-agents) debe detenerse. Si `"ok"` es `false`, Claude continúa trabajando con la razón proporcionada como su siguiente instrucción:
3072 3106
3073```json theme={null}3107```json theme={null}
3074{3108{
3192 3226
3193Las notificaciones de finalización de hooks asincronos se suprimen por defecto. Para verlas, habilite el modo detallado con `Ctrl+O` o inicie Claude Code con `--verbose`.3227Las notificaciones de finalización de hooks asincronos se suprimen por defecto. Para verlas, habilite el modo detallado con `Ctrl+O` o inicie Claude Code con `--verbose`.
3194 3228
3195<h3 id="example-run-tests-after-file-changes">3229<h3 id="run-tests-after-file-changes">
3196 Ejemplo: ejecutar pruebas después de cambios de archivo3230 Ejecutar pruebas después de cambios de archivo
3197</h3>3231</h3>
3198 3232
3199Este hook inicia un conjunto de pruebas en segundo plano cada vez que Claude escribe un archivo, luego reporta los resultados a Claude cuando las pruebas finalizan. Guarde este script en `.claude/hooks/run-tests-async.sh` en su proyecto y hágalo ejecutable con `chmod +x`:3233Este hook inicia un conjunto de pruebas en segundo plano cada vez que Claude escribe un archivo, luego reporta los resultados a Claude cuando las pruebas finalizan. Guarde este script en `.claude/hooks/run-tests-async.sh` en su proyecto y hágalo ejecutable con `chmod +x`:
3287 Herramienta PowerShell en Windows3321 Herramienta PowerShell en Windows
3288</h2>3322</h2>
3289 3323
3290En Windows, puede ejecutar hooks individuales en PowerShell estableciendo `"shell": "powershell"` en un hook de comando. Los hooks generan PowerShell directamente, por lo que esto funciona independientemente de si `CLAUDE_CODE_USE_POWERSHELL_TOOL` está establecido. Claude Code detecta automáticamente `pwsh.exe` (PowerShell 7+) con un respaldo a `powershell.exe` (5.1).3324En Windows, puede ejecutar hooks individuales en PowerShell estableciendo `"shell": "powershell"` en un hook de comando. Los hooks generan PowerShell directamente, por lo que esto funciona independientemente de si `CLAUDE_CODE_USE_POWERSHELL_TOOL` está establecido. Claude Code detecta automáticamente `pwsh.exe`, el ejecutable de PowerShell 7 y posterior, y recurre a `powershell.exe` para Windows PowerShell 5.1.
3291 3325
3292```json theme={null}3326```json theme={null}
3293{3327{
3308}3342}
3309```3343```
3310 3344
3311Para hacer referencia al directorio raíz del proyecto desde un comando de forma shell de PowerShell, léalo como una variable de entorno con `$env:CLAUDE_PROJECT_DIR`. PowerShell trata la forma desnuda `${CLAUDE_PROJECT_DIR}` como una variable local, no como una búsqueda de entorno, y Claude Code sustituye ese marcador de posición en forma shell solo para [hooks de plugins](#reference-scripts-by-path). Para un hook definido en `settings.json`, use la forma `$env:` o cambie a [forma exec](#exec-form-and-shell-form), donde `${CLAUDE_PROJECT_DIR}` se sustituye en cada elemento `args` independientemente de dónde se defina el hook.3345Para hacer referencia al directorio raíz del proyecto desde un comando de forma shell de PowerShell, escriba `${CLAUDE_PROJECT_DIR}` o `$env:CLAUDE_PROJECT_DIR`. A partir de v2.1.198, Claude Code reescribe los marcadores de posición `${CLAUDE_PROJECT_DIR}`, `${CLAUDE_PLUGIN_ROOT}` y `${CLAUDE_PLUGIN_DATA}` en un comando de forma shell de PowerShell a la forma `${env:NAME}` de PowerShell, ya sea que el hook esté definido en `settings.json`, un plugin o una skill. PowerShell luego resuelve el valor del entorno exportado después del análisis, por lo que el marcador de posición funciona dentro de cadenas entre comillas dobles pero no dentro de cadenas entre comillas simples, donde PowerShell nunca expande variables.
3346
3347Antes de v2.1.198, esta reescritura se aplicaba solo a hooks de plugins. En versiones anteriores, un hook de `settings.json` necesita la forma `$env:` o [forma exec](#exec-form-and-shell-form), donde `${CLAUDE_PROJECT_DIR}` se sustituye en cada elemento `args` independientemente de dónde se defina el hook.
3348
3349No escriba la ortografía desnuda `$CLAUDE_PROJECT_DIR` en un hook de PowerShell. PowerShell la analiza como una variable local indefinida y la resuelve a `$null`, lo que deja la ruta del script sin su prefijo de directorio raíz del proyecto. Claude Code no reescribe esa forma; en su lugar, registra una advertencia en el [registro de depuración](#debug-hooks).
3312 3350
3313El ejemplo a continuación muestra un hook de `settings.json` que ejecuta un script del proyecto con la forma `$env:`:3351El ejemplo a continuación muestra un hook de `settings.json` que ejecuta un script del proyecto con la forma `$env:`, que funciona en todas las versiones:
3314 3352
3315```json theme={null}3353```json theme={null}
3316{3354{