757 Entrada y salida de hooks757 Entrada y salida de hooks
758</h2>758</h2>
759 759
760Los hooks de comando reciben datos JSON a través de stdin y comunican resultados a través de códigos de salida, stdout y stderr. Los hooks HTTP reciben el mismo JSON que el cuerpo de la solicitud POST y comunican resultados a través del cuerpo de la respuesta HTTP. Esta sección cubre campos y comportamiento comunes a todos los eventos. Cada sección de evento bajo [Hook events](#hook-events) incluye su esquema de entrada específico y opciones de control de decisión.760Los hooks de comando reciben datos JSON a través de stdin y comunican resultados a través de códigos de salida, stdout y stderr. Los hooks HTTP reciben el mismo JSON como cuerpo de la solicitud POST y comunican resultados a través del cuerpo de la respuesta HTTP. Esta sección cubre campos y comportamiento comunes a todos los eventos. Cada sección de evento bajo [Eventos de hook](#hook-events) incluye su esquema de entrada específico y opciones de control de decisión.
761 761
762En macOS y Linux, los hooks de comando se ejecutan en su propia sesión sin una terminal de control. El proceso de hook y cualquier proceso secundario no pueden abrir `/dev/tty` o enviar secuencias de escape directamente a la interfaz de Claude Code. Windows no tiene `/dev/tty`.762En macOS y Linux, los hooks de comando se ejecutan en su propia sesión sin una terminal de control. El proceso del hook y cualquier proceso secundario no pueden abrir `/dev/tty` ni enviar secuencias de escape directamente a la interfaz de Claude Code. Windows no tiene `/dev/tty`.
763 763
764Para mostrar un mensaje al usuario en cualquier plataforma, devuelva [`systemMessage`](#json-output) en la salida JSON. Algunos eventos lo descartan o lo entregan en otro lugar, y cada [sección de evento](#hook-events) lo indica. Para activar una notificación de escritorio, establecer un título de ventana o sonar la campana, devuelva [`terminalSequence`](#emit-terminal-notifications) en su lugar.764Para mostrar un mensaje al usuario en cualquier plataforma, devuelve [`systemMessage`](#json-output) en la salida JSON. Algunos eventos lo descartan o lo entregan en otro lugar, y cada [sección de evento](#hook-events) lo indica. Para activar una notificación de escritorio, establecer un título de ventana o hacer sonar la campana, devuelve [`terminalSequence`](#emit-terminal-notifications) en su lugar.
765 765
766<h3 id="common-input-fields">766<h3 id="common-input-fields">
767 Campos de entrada comunes767 Campos de entrada comunes
768</h3>768</h3>
769 769
770Los eventos de hook reciben estos campos como JSON, además de campos específicos del evento documentados en cada sección [hook event](#hook-events). Para hooks de comando, este JSON llega a través de stdin. Para hooks HTTP, llega como el cuerpo de la solicitud POST.770Los eventos de hook reciben estos campos como JSON, además de campos específicos del evento documentados en cada sección de [evento de hook](#hook-events). Para hooks de comando, este JSON llega a través de stdin. Para hooks HTTP, llega como el cuerpo de la solicitud POST.
771 771
772| Campo | Descripción |772| Campo | Descripción |
773| :- | :- |773| :- | :- |
774| `session_id` | Identificador de sesión actual |774| `session_id` | Identificador de sesión actual |
775| `prompt_id` | UUID que identifica el prompt del usuario que se está procesando actualmente. Coincide con el [atributo `prompt.id` en eventos de OpenTelemetry](/docs/es/monitoring-usage#event-correlation-attributes), para que puedas correlacionar la salida del hook con la telemetría de un único prompt. Ausente hasta la primera entrada del usuario |775| `prompt_id` | UUID que identifica el prompt del usuario que se está procesando actualmente. Coincide con el [atributo `prompt.id` en eventos de OpenTelemetry](/docs/es/monitoring-usage#event-correlation-attributes), para que puedas correlacionar la salida del hook con la telemetría de un único prompt. Ausente hasta la primera entrada del usuario |
776| `transcript_path` | Ruta al JSON de conversación. El archivo de transcripción se escribe de forma asincrónica y puede rezagarse con respecto a la conversación en memoria, por lo que es posible que aún no incluya los mensajes más recientes del turno actual cuando se activa un hook. Los hooks que necesitan el texto del asistente final del turno actual deben usar `last_assistant_message` en [Stop](#stop) y [SubagentStop](#subagentstop) en lugar de leer la transcripción |776| `transcript_path` | Ruta al JSON de conversación. El archivo de transcripción se escribe de forma asincrónica y puede rezagarse con respecto a la conversación en memoria, por lo que es posible que aún no incluya los mensajes más recientes del turno actual cuando se activa un hook. Los hooks que necesitan el texto final del asistente del turno actual deben usar `last_assistant_message` en [Stop](#stop) y [SubagentStop](#subagentstop) en lugar de leer la transcripción |
777| `cwd` | Directorio de trabajo actual cuando se invoca el hook |777| `cwd` | Directorio de trabajo actual cuando se invoca el hook |
778| `scratchpad_dir` | Ruta al [directorio de scratchpad de la sesión](/docs/es/claude-directory#session-scratchpad-directory), donde Claude mantiene archivos de trabajo temporales. Ausente cuando la sesión no tiene scratchpad o el directorio temporal no está disponible. Requiere Claude Code v2.1.257 o posterior |778| `scratchpad_dir` | Ruta al [directorio de scratchpad de la sesión](/docs/es/claude-directory#session-scratchpad-directory), donde Claude mantiene archivos de trabajo temporales. Ausente cuando la sesión no tiene scratchpad o el directorio temporal no está disponible. Requiere Claude Code v2.1.257 o posterior |
779| `permission_mode` | [Modo de permiso](/docs/es/permissions#permission-modes) actual: `"default"`, `"plan"`, `"acceptEdits"`, `"auto"`, `"dontAsk"` o `"bypassPermissions"`. El modo etiquetado como **Manual** llega como `"default"`, nunca como `"manual"`, por lo que los scripts que coinciden con `"default"` siguen funcionando. No todos los eventos reciben este campo. Consulte el ejemplo JSON en cada sección [hook event](#hook-events) |779| `permission_mode` | [Modo de permisos](/docs/es/permissions#permission-modes) actual: `"default"`, `"plan"`, `"acceptEdits"`, `"auto"`, `"dontAsk"` o `"bypassPermissions"`. El modo etiquetado como **Manual** llega como `"default"`, nunca como `"manual"`, por lo que los scripts que coinciden con `"default"` siguen funcionando. No todos los eventos reciben este campo. Consulta el ejemplo JSON en cada sección de [evento de hook](#hook-events) |
780| `effort` | Objeto con un campo `level` que contiene el [nivel de esfuerzo](/docs/es/model-config#adjust-effort-level) en vigor cuando se ejecuta el hook: `"low"`, `"medium"`, `"high"`, `"xhigh"` o `"max"`. Si establece un nivel que el modelo activo no admite, `level` reporta el nivel que Claude Code ejecutó en su lugar; [Adjust effort level](/docs/es/model-config#adjust-effort-level) dice cómo lo elige. El objeto coincide con el campo `effort` de la [línea de estado](/docs/es/statusline#available-data). Presente para eventos que se activan dentro de un contexto de uso de herramienta, como `PreToolUse`, `PostToolUse`, `Stop` y `SubagentStop`, cuando el modelo actual admite el parámetro de esfuerzo. El nivel también está disponible para comandos de hook y la herramienta Bash como la variable de entorno `$CLAUDE_EFFORT`. |780| `effort` | Objeto con un campo `level` que contiene el [nivel de esfuerzo](/docs/es/model-config#adjust-effort-level) en vigor cuando se ejecuta el hook: `"low"`, `"medium"`, `"high"`, `"xhigh"` o `"max"`. Si estableces un nivel que el modelo activo no admite, `level` reporta el nivel que Claude Code ejecutó en su lugar; [Ajustar el nivel de esfuerzo](/docs/es/model-config#adjust-effort-level) explica cómo lo elige. El objeto coincide con el campo `effort` de la [línea de estado](/docs/es/statusline#available-data). Presente para eventos que se activan dentro de un contexto de uso de herramienta, como `PreToolUse`, `PostToolUse`, `Stop` y `SubagentStop`, cuando el modelo actual admite el parámetro de esfuerzo. El nivel también está disponible para comandos de hook y la herramienta Bash como la variable de entorno `$CLAUDE_EFFORT`. |
781| `hook_event_name` | Nombre del evento que se activó |781| `hook_event_name` | Nombre del evento que se activó |
782 782
783Cuando se ejecuta con `--agent` o dentro de un subagente, se incluyen dos campos adicionales:783Cuando se ejecuta con `--agent` o dentro de un subagente, se incluyen dos campos adicionales:
784 784
785| Campo | Descripción |785| Campo | Descripción |
786| :- | :- |786| :- | :- |
787| `agent_id` | Identificador único para el subagente. Presente solo cuando el hook se activa dentro de una llamada de subagente. Use esto para distinguir llamadas de hook de subagente de llamadas de hilo principal. |787| `agent_id` | Identificador único para el subagente. Presente solo cuando el hook se activa dentro de una llamada de subagente. Usa esto para distinguir llamadas de hook de subagente de llamadas del hilo principal. |
788| `agent_type` | Nombre del agente (por ejemplo, `"Explore"` o `"security-reviewer"`). Presente cuando la sesión usa `--agent` o el hook se activa dentro de un subagente. Para subagentes, el tipo del subagente tiene precedencia sobre el valor `--agent` de la sesión. Consulte [SubagentStart](#subagentstart) para los valores que los subagentes personalizados y de plugin reportan y cómo escribir un matcher contra un nombre con alcance de plugin. |788| `agent_type` | Nombre del agente (por ejemplo, `"Explore"` o `"security-reviewer"`). Presente cuando la sesión usa `--agent` o el hook se activa dentro de un subagente. Para subagentes, el tipo del subagente tiene precedencia sobre el valor `--agent` de la sesión. Consulta [SubagentStart](#subagentstart) para ver los valores que reportan los subagentes personalizados y de plugin y cómo escribir un matcher contra un nombre con alcance de plugin. |
789 789
790Solo los hooks [`SessionStart`](#sessionstart) pueden recibir un campo `model`, y Claude Code no siempre lo incluye. Los hooks [`PreModelSwitch`](#premodelswitch) y [`PostModelSwitch`](#postmodelswitch) reciben `from_model` y `to_model` en su lugar, así que use un hook PostModelSwitch para seguir el modelo mientras cambia durante una sesión.790Solo los hooks [`SessionStart`](#sessionstart) pueden recibir un campo `model`, y Claude Code no siempre lo incluye. Los hooks [`PreModelSwitch`](#premodelswitch) y [`PostModelSwitch`](#postmodelswitch) reciben `from_model` y `to_model` en su lugar, así que usa un hook PostModelSwitch para seguir el modelo mientras cambia durante una sesión.
791 791
792No hay variable de entorno `$CLAUDE_MODEL`. El hook puede leer `$ANTHROPIC_MODEL` si lo establece en su shell, pero ese valor no cambia cuando cambia de modelos con `/model` durante una sesión.792No hay variable de entorno `$CLAUDE_MODEL`. El hook puede leer `$ANTHROPIC_MODEL` si la estableces en tu shell, pero ese valor no cambia cuando cambias de modelo con `/model` durante una sesión.
793 793
794Un proceso de hook hereda el entorno principal, aparte de las variables exportadoras `OTEL_*` que Claude Code [elimina de cada subproceso que genera](/docs/es/monitoring-usage#administrator-configuration) y, cuando [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](/docs/es/env-vars#variables) se establece en `1`, las variables que elimina. En una sesión que [recibe la configuración HIPAA](/docs/es/hipaa-setup#check-how-developers-sign-in-and-connect), Claude Code también [elimina las credenciales de Anthropic](/docs/es/hipaa-setup#anthropic-credentials-in-commands-hooks-and-mcp-servers) del entorno del hook.794Un proceso de hook hereda el entorno principal, aparte de las variables exportadoras `OTEL_*` que Claude Code [elimina de cada subproceso que genera](/docs/es/monitoring-usage#administrator-configuration) y, cuando [`CLAUDE_CODE_SUBPROCESS_ENV_SCRUB`](/docs/es/env-vars#variables) se establece en `1`, las variables que elimina. En una sesión que [recibe la configuración HIPAA](/docs/es/hipaa-setup#check-how-developers-sign-in-and-connect), Claude Code también [elimina las credenciales de Anthropic](/docs/es/hipaa-setup#anthropic-credentials-in-commands-hooks-and-mcp-servers) del entorno del hook.
795 795
815}815}
816```816```
817 817
818Los campos `tool_name`, `tool_input` y `tool_use_id` son específicos del evento. Cada sección [hook event](#hook-events) documenta los campos adicionales para ese evento.818Los campos `tool_name`, `tool_input` y `tool_use_id` son específicos del evento. Cada sección de [evento de hook](#hook-events) documenta los campos adicionales para ese evento.
819 819
820<h3 id="exit-code-output">820<h3 id="exit-code-output">
821 Salida de código de salida821 Salida por código de salida
822</h3>822</h3>
823 823
824El código de salida de su comando de hook le dice a Claude Code si la acción debe proceder, ser bloqueada o ser ignorada. El código de salida no actúa solo. Claude Code lee campos [JSON output](#json-output) desde stdout en cada código de salida, no solo en 0, y para eventos que usan el modelo de decisión estándar, un objeto analizado que pasa la validación del esquema tiene efecto junto con el código. El bloqueo de Exit 2 es el único resultado que JSON no puede anular.824El código de salida de tu comando de hook le dice a Claude Code si la acción debe continuar, ser bloqueada o ser ignorada. El código de salida no actúa solo. Claude Code lee los [campos de salida JSON](#json-output) desde stdout con cualquier código de salida, no solo con 0, y para los eventos que usan el modelo de decisión estándar, un objeto analizado que pasa la validación del esquema tiene efecto junto con el código. El bloqueo de exit 2 es el único resultado que JSON no puede sobrescribir.
825 825
826Dos tablas poseen las excepciones por evento: [Exit code 2 behavior per event](#exit-code-2-behavior-per-event) dice qué hacen los códigos de salida para cada evento, y [Decision control](#decision-control) dice qué campos de decisión honra cada evento. Los campos universales como `systemMessage` funcionan en la mayoría de eventos y se enumeran en la tabla [JSON output](#json-output).826Dos tablas recogen las excepciones por evento: [Comportamiento del código de salida 2 por evento](#exit-code-2-behavior-per-event) indica qué hacen los códigos de salida para cada evento, y [Control de decisión](#decision-control) indica qué campos de decisión respeta cada evento. Los campos universales como `systemMessage` funcionan en la mayoría de los eventos y se enumeran en la tabla de [salida JSON](#json-output).
827 827
828<h4 id="exit-code-0">828<h4 id="exit-code-0">
829 Exit code 0829 Exit code 0
830</h4>830</h4>
831 831
832Exit 0 significa éxito, y es el código de salida previsto cuando imprime JSON para control estructurado.832Exit 0 significa éxito, y es el código de salida previsto cuando imprimes JSON para control estructurado.
833 833
834Para la mayoría de eventos, Claude Code escribe stdout en el registro de depuración y no lo muestra en la transcripción. Las excepciones son `UserPromptSubmit`, `UserPromptExpansion`, `SessionStart` y `PostModelSwitch`, donde Claude Code agrega stdout de texto plano como contexto que Claude puede ver y actuar.834Para la mayoría de los eventos, Claude Code escribe stdout en el registro de depuración y no lo muestra en la transcripción. Las excepciones son `UserPromptSubmit`, `UserPromptExpansion`, `SessionStart` y `PostModelSwitch`, donde Claude Code agrega el stdout de texto plano como contexto que Claude puede ver y sobre el que puede actuar.
835 835
836Si Claude Code lee su stdout como [JSON output](#json-output) o como texto plano depende de cómo comienza y termina, ignorando espacios en blanco circundantes:836Que Claude Code lea tu stdout como [salida JSON](#json-output) o como texto plano depende de cómo comienza y termina, ignorando los espacios en blanco circundantes:
837 837
838* **Comienza con `{` y termina con `}`**: Claude Code lo analiza como JSON. Cuando la salida son dos o más líneas que cada una se analiza como JSON por su cuenta, y ninguna línea es un objeto [JSON output](#json-output) que establece un campo, Claude Code trata toda la salida como texto plano. Cuando una de esas líneas sí establece un campo, toda la salida es un fallo de análisis, descrito a continuación.838* **Comienza con `{` y termina con `}`**: Claude Code lo analiza como JSON. Cuando la salida son dos o más líneas que se analizan como JSON cada una por su cuenta, y ninguna línea es un objeto de [salida JSON](#json-output) que establezca un campo, Claude Code trata toda la salida como texto plano. Cuando una de esas líneas sí establece un campo, toda la salida es un fallo de análisis, descrito a continuación.
839* **Comienza con `{` pero no termina con `}`**: Claude Code lo trata como texto plano.839* **Comienza con `{` pero no termina con `}`**: Claude Code lo trata como texto plano.
840* **Comienza con cualquier otra cosa**: Claude Code lo trata como texto plano, incluso si es un array JSON o una cadena JSON entrecomillada.840* **Comienza con cualquier otra cosa**: Claude Code lo trata como texto plano, incluso si es un array JSON o una cadena JSON entrecomillada.
841 841
842Para eventos que usan el modelo de decisión estándar, exit 0 con un objeto analizado que falla la validación del esquema es un error sin bloqueo: la acción procede, y la transcripción muestra un aviso `<hook name> hook error` con el mensaje de validación. Lo mismo sucede en cualquier código de salida que no sea 2, mientras que [exit 2 aún bloquea](#exit-code-2).842Para los eventos que usan el modelo de decisión estándar, exit 0 con un objeto analizado que falla la validación del esquema es un error sin bloqueo: la acción continúa, y la transcripción muestra un aviso `<hook name> hook error` con el mensaje de validación. Lo mismo sucede con cualquier código de salida distinto de 2, mientras que [exit 2 sigue bloqueando](#exit-code-2).
843 843
844Para eventos que usan el modelo de decisión estándar, cuando Claude Code intenta analizar su stdout como JSON y no puede, reporta un error sin bloqueo en cada código de salida que no sea 2. La transcripción muestra un aviso `<hook name> hook error` con el mensaje de análisis. En los eventos que agregan stdout de texto plano como contexto, Claude Code no agrega el texto. Antes de v2.1.248, Claude Code trataba ese stdout como texto plano.844Para los eventos que usan el modelo de decisión estándar, cuando Claude Code intenta analizar tu stdout como JSON y no puede, reporta un error sin bloqueo con cualquier código de salida distinto de 2. La transcripción muestra un aviso `<hook name> hook error` con el mensaje de análisis. En los eventos que agregan stdout de texto plano como contexto, Claude Code no agrega el texto. Antes de v2.1.248, Claude Code trataba ese stdout como texto plano.
845 845
846Stderr de un hook que sale 0 va solo al registro de depuración, nunca a la transcripción, y Claude nunca lo ve. Para leerlo usted mismo, habilite [debug logging](#debug-hooks). Para mostrar una advertencia a Claude desde un hook `PostToolUse` o `PostToolUseFailure`, salga 2 en su lugar para que [Claude vea stderr](#exit-code-2-behavior-per-event) aunque la herramienta ya se haya ejecutado.846El stderr de un hook que sale con 0 va solo al registro de depuración, nunca a la transcripción, y Claude nunca lo ve. Para leerlo tú mismo, habilita el [registro de depuración](#debug-hooks). Para mostrarle una advertencia a Claude desde un hook `PostToolUse` o `PostToolUseFailure`, sal con 2 en su lugar para que [Claude vea el stderr](#exit-code-2-behavior-per-event) aunque la herramienta ya se haya ejecutado.
847 847
848<h4 id="exit-code-2">848<h4 id="exit-code-2">
849 Exit code 2849 Exit code 2
850</h4>850</h4>
851 851
852Exit 2 significa un error de bloqueo. En [eventos que pueden bloquear](#exit-code-2-behavior-per-event), exit 2 bloquea independientemente de si imprime JSON: incluso un `permissionDecision` JSON de `"allow"` no puede anularlo. Claude Code aún lee cualquier [JSON output](#json-output) válido en stdout. En `Elicitation` y `ElicitationResult`, el `hookSpecificOutput` de un hook exit-2 se ignora.852Exit 2 significa un error de bloqueo. En los [eventos que pueden bloquear](#exit-code-2-behavior-per-event), exit 2 bloquea independientemente de si imprimes JSON: ni siquiera un `permissionDecision` JSON de `"allow"` puede sobrescribirlo. Claude Code sigue leyendo cualquier [salida JSON](#json-output) válida en stdout. En `Elicitation` y `ElicitationResult`, el `hookSpecificOutput` de un hook que sale con 2 se ignora.
853 853
854El mensaje de bloqueo es la razón de la decisión de bloqueo de su JSON cuando hace una, y su texto stderr en caso contrario. Lo que el bloqueo hace varía según el evento: `PreToolUse` bloquea la llamada a herramienta, `UserPromptSubmit` rechaza el prompt, y así sucesivamente. [Exit code 2 behavior per event](#exit-code-2-behavior-per-event) enumera el efecto para cada evento, y cada sección de evento dice dónde va el mensaje.854El mensaje de bloqueo es la razón de la decisión de bloqueo de tu JSON cuando la incluye, y tu texto de stderr en caso contrario. Lo que hace el bloqueo varía según el evento: `PreToolUse` bloquea la llamada a herramienta, `UserPromptSubmit` rechaza el prompt, y así sucesivamente. [Comportamiento del código de salida 2 por evento](#exit-code-2-behavior-per-event) enumera el efecto para cada evento, y la sección de cada evento indica adónde va el mensaje.
855 855
856Un hook que sale 2 mientras imprime JSON que falla la validación del esquema [JSON output](#json-output) aún bloquea: Claude Code usa stderr como la razón de bloqueo y registra el fallo de validación en el registro de depuración. Antes de v2.1.214, Claude Code trataba esa combinación como un error sin bloqueo y la acción procedía.856Un hook que sale con 2 mientras imprime JSON que falla la validación del esquema de [salida JSON](#json-output) sigue bloqueando: Claude Code usa stderr como la razón del bloqueo y registra el fallo de validación en el registro de depuración. Antes de v2.1.214, Claude Code trataba esa combinación como un error sin bloqueo y la acción continuaba.
857 857
858Este script bloquea comandos `rm` saliendo 2 y deja cada otro comando al flujo de permiso normal:858Este script bloquea los comandos `rm` saliendo con 2 y deja todos los demás comandos al flujo de permisos normal:
859 859
860```bash theme={null}860```bash theme={null}
861#!/bin/bash861#!/bin/bash
875 Otros códigos de salida875 Otros códigos de salida
876</h4>876</h4>
877 877
878Cualquier otro código de salida no bloquea por su cuenta para la mayoría de eventos de hook. Lo que sucede depende de su stdout:878Cualquier otro código de salida no bloquea por sí solo en la mayoría de los eventos de hook. Lo que sucede depende de tu stdout:
879 879
880* Con un objeto analizado que pasa la validación del esquema, para eventos que usan el modelo de decisión estándar, Claude Code ignora el código de salida y solo el JSON decide el resultado:880* Con un objeto analizado que pasa la validación del esquema, para los eventos que usan el modelo de decisión estándar, Claude Code ignora el código de salida y solo el JSON decide el resultado:
881 * Cada campo que el evento admite se honra, incluyendo `permissionDecision`, `additionalContext`, `updatedInput` y `systemMessage`, y el hook no se reporta como un error.881 * Se respeta cada campo que el evento admite, incluidos `permissionDecision`, `additionalContext`, `updatedInput` y `systemMessage`, y el hook no se reporta como error.
882 * [Decision control](#decision-control) enumera los campos de decisión por evento; campos universales como `systemMessage` siguen la tabla [JSON output](#json-output).882 * [Control de decisión](#decision-control) enumera los campos de decisión por evento; los campos universales como `systemMessage` siguen la tabla de [salida JSON](#json-output).
883* Con un objeto analizado que falla la validación del esquema, para eventos que usan el modelo de decisión estándar, es el mismo error sin bloqueo que [en exit 0](#exit-code-0): la acción procede, y el aviso `<hook name> hook error` lleva el mensaje de validación.883* Con un objeto analizado que falla la validación del esquema, para los eventos que usan el modelo de decisión estándar, es el mismo error sin bloqueo que [con exit 0](#exit-code-0): la acción continúa, y el aviso `<hook name> hook error` incluye el mensaje de validación.
884* Con stdout que Claude Code [intenta analizar como JSON](#exit-code-0) y no puede, Claude Code reporta el mismo error sin bloqueo que en exit 0 para eventos que usan el modelo de decisión estándar. La acción procede, y el aviso lleva el mensaje de análisis.884* Con stdout que Claude Code [intenta analizar como JSON](#exit-code-0) y no puede, Claude Code reporta el mismo error sin bloqueo que con exit 0 para los eventos que usan el modelo de decisión estándar. La acción continúa, y el aviso incluye el mensaje de análisis.
885* Con stdout que Claude Code [trata como texto plano](#exit-code-0), o con stdout vacío, es un error sin bloqueo para la mayoría de eventos de hook: la acción procede, y la transcripción muestra un aviso `<hook name> hook error` seguido de la primera línea de stderr, prefijado con `Failed with non-blocking status code:`. Para capturar el stderr completo, habilite [debug logging](#debug-hooks).885* Con stdout que Claude Code [trata como texto plano](#exit-code-0), o con stdout vacío, es un error sin bloqueo para la mayoría de los eventos de hook: la acción continúa, y la transcripción muestra un aviso `<hook name> hook error` seguido de la primera línea de stderr, con el prefijo `Failed with non-blocking status code:`. Para capturar el stderr completo, habilita el [registro de depuración](#debug-hooks).
886 886
887Los eventos fuera del modelo de decisión estándar mantienen sus propias filas en la [tabla por evento](#exit-code-2-behavior-per-event): `WorktreeCreate` falla la creación en cualquier salida distinta de cero sin importar lo que diga su JSON, y eventos que descartan la salida del hook completamente, como `StopFailure`, ignoran su JSON en cada código de salida, aparte de campos de efecto secundario como `terminalSequence`, que aún se activan.887Los eventos fuera del modelo de decisión estándar mantienen sus propias filas en la [tabla por evento](#exit-code-2-behavior-per-event): `WorktreeCreate` hace fallar la creación con cualquier salida distinta de cero, diga lo que diga tu JSON, y los eventos que descartan por completo la salida del hook, como `StopFailure`, ignoran tu JSON con cualquier código de salida, aparte de los campos de efecto secundario como `terminalSequence`, que se siguen activando.
888 888
889Un hook que no puede iniciarse cae en el mismo cubo sin bloqueo. Cuando la ruta del script no existe o no es ejecutable, el shell sale con un código como 127 y ve el mismo aviso con el mensaje del intérprete, por ejemplo `Failed with non-blocking status code: /bin/sh: /path/to/hook.sh: No such file or directory`. Para la mayoría de eventos de hook, la acción procede. Cuando configura un hook de política, observe este aviso en su primera ejecución: una ruta mal escrita en `settings.json` deja la puerta silenciosamente deshabilitada.889Un hook que no puede iniciarse cae en la misma categoría sin bloqueo. Cuando la ruta del script no existe o no es ejecutable, el shell sale con un código como 127 y ves el mismo aviso con el mensaje del intérprete, por ejemplo `Failed with non-blocking status code: /bin/sh: /path/to/hook.sh: No such file or directory`. Para la mayoría de los eventos de hook, la acción continúa. Cuando configures un hook de política, fíjate en este aviso en su primera ejecución: una ruta mal escrita en `settings.json` deja el control deshabilitado en silencio.
890 890
891<Warning>891<Warning>
892 Para la mayoría de eventos de hook, el código de salida 2 es el único código de salida que bloquea solo a través del código. Sin JSON válido en stdout, Claude Code trata el código de salida 1 como un error sin bloqueo y procede con la acción, aunque 1 es el código de fallo convencional de Unix. Si su hook está destinado a aplicar una política, use `exit 2`. Los eventos de worktree difieren: cualquier código de salida distinto de cero de `WorktreeCreate` aborta la creación de worktree, y cualquier código de salida distinto de cero de `WorktreeRemove` hace que la eliminación de worktree falle si el directorio aún existe después.892 Para la mayoría de los eventos de hook, el código de salida 2 es el único código de salida que bloquea solo con el código. Sin JSON válido en stdout, Claude Code trata el código de salida 1 como un error sin bloqueo y continúa con la acción, aunque 1 es el código de fallo convencional de Unix. Si tu hook está pensado para aplicar una política, usa `exit 2`. Los eventos de worktree son diferentes: cualquier código de salida distinto de cero de `WorktreeCreate` aborta la creación del worktree, y cualquier código de salida distinto de cero de `WorktreeRemove` hace que la eliminación del worktree falle si el directorio sigue existiendo después.
893</Warning>893</Warning>
894 894
895<h4 id="timeouts">895<h4 id="timeouts">
896 Tiempos de espera896 Tiempos de espera
897</h4>897</h4>
898 898
899Aparte de un hook de comando que ejecuta con [`async: true`](#run-hooks-in-the-background), Claude Code cancela un hook `command`, `http` o `mcp_tool` que alcanza su [`timeout`](#common-fields), descartando la salida del hook, por lo que en la mayoría de eventos un hook agotado no renderiza decisión.899Aparte de un hook de comando que ejecutes con [`async: true`](#run-hooks-in-the-background), Claude Code cancela un hook `command`, `http` o `mcp_tool` que alcanza su [`timeout`](#common-fields), descartando la salida del hook, por lo que en la mayoría de los eventos un hook cuyo tiempo de espera se agota no emite ninguna decisión.
900 900
901En [`PreModelSwitch`](#premodelswitch), un hook cancelado en su timeout bloquea el cambio de modelo. En `PreToolUse`, las dos familias de hooks difieren:901En [`PreModelSwitch`](#premodelswitch), un hook cancelado al agotarse su tiempo de espera bloquea el cambio de modelo. En `PreToolUse`, las dos familias de hooks difieren:
902 902
903* Un hook `command`, `http` o `mcp_tool` agotado no bloquea la llamada a herramienta. La llamada continúa a través del [flujo de permiso](/docs/es/permissions) normal, así que no cuente con un hook estancado para actuar como puerta.903* Un hook `command`, `http` o `mcp_tool` cuyo tiempo de espera se agota no bloquea la llamada a herramienta. La llamada continúa a través del [flujo de permisos](/docs/es/permissions) normal, así que no cuentes con que un hook bloqueado actúe como control.
904* Un hook de callback [Agent SDK](/docs/es/agent-sdk/hooks) que excede su timeout [bloquea la llamada a herramienta](#pretooluse).904* Un [hook de callback del Agent SDK](/docs/es/agent-sdk/hooks) que excede su tiempo de espera [bloquea la llamada a herramienta](#pretooluse).
905 905
906<h4 id="exit-code-2-behavior-per-event">906<h4 id="exit-code-2-behavior-per-event">
907 Comportamiento del código de salida 2 por evento907 Comportamiento del código de salida 2 por evento
908</h4>908</h4>
909 909
910Exit code 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.910El 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 evitarse.
911 911
912| Evento de hook | ¿Puede bloquear? | Qué sucede en exit 2 |912| Evento de hook | ¿Puede bloquear? | Qué sucede con exit 2 |
913| :- | :- | :- |913| :- | :- | :- |
914| `PreToolUse` | Sí | Bloquea la llamada a herramienta |914| `PreToolUse` | Sí | Bloquea la llamada a herramienta |
915| `PermissionRequest` | No | El código de salida 2 no se honra para este evento y el flujo de permiso procede sin cambios. Deniegue a través del objeto [`decision`](#permissionrequest-decision-control) en su lugar |915| `PermissionRequest` | No | El código de salida 2 no se respeta para este evento y el flujo de permisos continúa sin cambios. Deniega a través del [objeto `decision`](#permissionrequest-decision-control) en su lugar |
916| `UserPromptSubmit` | Sí | Bloquea el prompt, por lo que nunca llega a Claude. Consulte [What a blocked prompt leaves behind](#what-a-blocked-prompt-leaves-behind) |916| `UserPromptSubmit` | Sí | Bloquea el prompt, por lo que nunca llega a Claude. Consulta [Qué deja atrás un prompt bloqueado](#what-a-blocked-prompt-leaves-behind) |
917| `UserPromptExpansion` | Sí | Bloquea la expansión |917| `UserPromptExpansion` | Sí | Bloquea la expansión |
918| `Stop` | Sí | Evita que Claude se detenga, continúa la conversación |918| `Stop` | Sí | Evita que Claude se detenga, continúa la conversación |
919| `SubagentStop` | Sí | Evita que el subagente se detenga |919| `SubagentStop` | Sí | Evita que el subagente se detenga |
920| `TeammateIdle` | Sí | Evita que el compañero se quede inactivo, por lo que continúa trabajando |920| `TeammateIdle` | Sí | Evita que el compañero quede inactivo, por lo que sigue trabajando |
921| `TaskCreated` | Sí | Revierte la creación de la tarea |921| `TaskCreated` | Sí | Revierte la creación de la tarea |
922| `TaskCompleted` | Sí | Evita que la tarea se marque como completada |922| `TaskCompleted` | Sí | Evita que la tarea se marque como completada |
923| `ConfigChange` | Sí | Bloquea que el cambio de configuración tenga efecto (excepto `policy_settings`) |923| `ConfigChange` | Sí | Impide que el cambio de configuración tenga efecto (excepto `policy_settings`) |
924| `StopFailure` | No | La salida y el código de salida se ignoran, excepto `terminalSequence` |924| `StopFailure` | No | La salida y el código de salida se ignoran, excepto `terminalSequence` |
925| `PostToolUse` | No | Muestra stderr a Claude; la herramienta ya se ejecutó |925| `PostToolUse` | No | Muestra stderr a Claude; la herramienta ya se ejecutó |
926| `PostToolUseFailure` | No | Muestra stderr a Claude; la herramienta ya falló |926| `PostToolUseFailure` | No | Muestra stderr a Claude; la herramienta ya falló |
927| `PostToolBatch` | Sí | Detiene el bucle agentico antes de la siguiente llamada al modelo |927| `PostToolBatch` | Sí | Detiene el bucle agéntico antes de la siguiente llamada al modelo |
928| `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; Claude Code ignora `retry: true` para [denegaciones sin veredicto](#permissiondenied-decision-control) |928| `PermissionDenied` | No | El código de salida y stderr se ignoran porque la denegación ya ocurrió. Usa JSON `hookSpecificOutput.retry: true` para indicarle al modelo que puede reintentar; Claude Code ignora `retry: true` para [denegaciones sin veredicto](#permissiondenied-decision-control) |
929| `Notification` | No | El código de salida y stderr se ignoran |929| `Notification` | No | El código de salida y stderr se ignoran |
930| `SubagentStart` | No | Muestra stderr solo al usuario |930| `SubagentStart` | No | Muestra stderr solo al usuario |
931| `SessionStart` | No | Muestra stderr solo al usuario |931| `SessionStart` | No | Muestra stderr solo al usuario |
938| `PostCompact` | No | Muestra stderr solo al usuario |938| `PostCompact` | No | Muestra stderr solo al usuario |
939| `PreModelSwitch` | Sí | Bloquea el cambio de modelo y muestra stderr al usuario |939| `PreModelSwitch` | Sí | Bloquea el cambio de modelo y muestra stderr al usuario |
940| `PostModelSwitch` | No | Muestra stderr solo al usuario; el modelo ya cambió |940| `PostModelSwitch` | No | Muestra stderr solo al usuario; el modelo ya cambió |
941| `Elicitation` | Sí | Deniega la elicitación |941| `Elicitation` | Sí | Rechaza la solicitud, y no aparece ningún diálogo |
942| `ElicitationResult` | Sí | Bloquea la respuesta (la acción se convierte en decline) |942| `ElicitationResult` | Sí | Bloquea la respuesta (la acción se convierte en decline) |
943| `WorktreeCreate` | Sí | Cualquier código de salida distinto de cero causa que la creación de worktree falle |943| `WorktreeCreate` | Sí | Cualquier código de salida distinto de cero hace que la creación del worktree falle |
944| `WorktreeRemove` | Sí | Cualquier código de salida distinto de cero causa que la eliminación de worktree falle si el directorio aún existe después. Consulte [WorktreeRemove](#worktreeremove) para saber qué sucede con el directorio |944| `WorktreeRemove` | Sí | Cualquier código de salida distinto de cero hace que la eliminación del worktree falle si el directorio sigue existiendo después. Consulta [WorktreeRemove](#worktreeremove) para saber qué sucede con el directorio |
945| `InstructionsLoaded` | No | El código de salida se ignora |945| `InstructionsLoaded` | No | El código de salida se ignora |
946| `MessageDisplay` | No | Se muestra el texto original |946| `MessageDisplay` | No | Se muestra el texto original |
947 947
948Para `SessionStart`, `SubagentStart` y `PostModelSwitch`, Claude Code renderiza el stderr del código de salida 2 en la transcripción como un aviso `<hook name> hook error`, de la misma manera que renderiza 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.948Para `SessionStart`, `SubagentStart` y `PostModelSwitch`, Claude Code muestra el stderr del código de salida 2 en la transcripción como un aviso `<hook name> hook error`, de la misma manera que muestra un [error sin bloqueo](#exit-code-output). Claude no lo ve, y la sesión o el subagente continúa. Para `SubagentStart`, el aviso aparece en la propia transcripción del subagente, no en la conversación principal.
949 949
950<h3 id="http-response-handling">950<h3 id="http-response-handling">
951 Manejo de respuesta HTTP951 Manejo de respuestas HTTP
952</h3>952</h3>
953 953
954Los hooks HTTP usan códigos de estado HTTP y cuerpos de respuesta en lugar de códigos de salida y stdout. Los resultados a continuación se aplican a la mayoría de eventos; un evento con su propio contrato de fallo en la [tabla por evento](#exit-code-2-behavior-per-event), como `WorktreeCreate`, aplica ese contrato a un hook HTTP fallido también:954Los hooks HTTP usan códigos de estado HTTP y cuerpos de respuesta en lugar de códigos de salida y stdout. Los resultados a continuación se aplican a la mayoría de los eventos; un evento con su propio contrato de fallo en la [tabla por evento](#exit-code-2-behavior-per-event), como `WorktreeCreate`, aplica ese contrato también a un hook HTTP fallido:
955 955
956* **2xx con un cuerpo vacío**: éxito, equivalente a código de salida 0 sin salida956* **2xx con un cuerpo vacío**: éxito, equivalente al código de salida 0 sin salida
957* **2xx con un cuerpo de objeto JSON**: analizado usando el mismo esquema [JSON output](#json-output) que los hooks de comando. Un cuerpo que falla la validación del esquema es un error sin bloqueo957* **2xx con un cuerpo de objeto JSON**: se analiza usando el mismo esquema de [salida JSON](#json-output) que los hooks de comando. Un cuerpo que falla la validación del esquema es un error sin bloqueo
958* **2xx con cualquier otro cuerpo, como texto plano**: error sin bloqueo, manejado igual que un estado que no es 2xx. Claude Code no agrega el texto al contexto de Claude958* **2xx con cualquier otro cuerpo, como texto plano**: error sin bloqueo, manejado igual que un estado que no es 2xx. Claude Code no agrega el texto al contexto de Claude
959* **Estado que no es 2xx**: error sin bloqueo, la ejecución continúa959* **Estado que no es 2xx**: error sin bloqueo, la ejecución continúa
960* **Fallo de conexión**: error sin bloqueo, la ejecución continúa960* **Fallo de conexión**: error sin bloqueo, la ejecución continúa
961* **Tiempo de espera**: el hook se cancela, como se describe bajo [Timeouts](#timeouts)961* **Tiempo de espera agotado**: el hook se cancela, como se describe en [Tiempos de espera](#timeouts)
962 962
963A diferencia de los hooks de comando, los hooks HTTP no pueden señalar un error de bloqueo solo a través de códigos de estado. Para bloquear una llamada a herramienta o denegar un permiso, devuelva una respuesta 2xx con un cuerpo JSON que contenga los campos de decisión apropiados.963A diferencia de los hooks de comando, los hooks HTTP no pueden señalar un error de bloqueo solo mediante códigos de estado. Para bloquear una llamada a herramienta o denegar un permiso, devuelve una respuesta 2xx con un cuerpo JSON que contenga los campos de decisión apropiados.
964 964
965<h3 id="json-output">965<h3 id="json-output">
966 Salida JSON966 Salida JSON
967</h3>967</h3>
968 968
969Los códigos de salida solo le permiten bloquear o permanecer en silencio, pero la salida JSON le da un control más granular. En lugar de salir con código 2 para bloquear, salga 0 e imprima un objeto JSON en stdout. Claude Code lee campos específicos de ese JSON para controlar el comportamiento, incluyendo [decision control](#decision-control) para bloquear, permitir o escalar al usuario.969Los códigos de salida solo te permiten bloquear o permanecer en silencio, pero la salida JSON te da un control más granular. En lugar de salir con código 2 para bloquear, sal con 0 e imprime un objeto JSON en stdout. Claude Code lee campos específicos de ese JSON para controlar el comportamiento, incluido el [control de decisión](#decision-control) para bloquear, permitir o escalar al usuario.
970 970
971<Note>971<Note>
972 Elija un enfoque por hook: use códigos de salida solos para señalizar, o salga 0 e imprima JSON para control estructurado. Si los mezcla, exit 2 mantiene su [efecto de bloqueo](#exit-code-2-behavior-per-event), y Claude Code aún lee los campos JSON, con la excepción de elicitación única anotada bajo [Exit code 2](#exit-code-2).972 Elige un enfoque por hook: usa solo códigos de salida para señalizar, o sal con 0 e imprime JSON para control estructurado. Si los mezclas, exit 2 mantiene su [efecto de bloqueo](#exit-code-2-behavior-per-event), y Claude Code sigue leyendo los campos JSON, con la única excepción de elicitación indicada en [Exit code 2](#exit-code-2).
973</Note>973</Note>
974 974
975El stdout de su hook debe contener solo el objeto JSON. Si su perfil de shell imprime texto al inicio, puede interferir con el análisis JSON. Consulte [Hook JSON has no effect](/docs/es/hooks-guide#hook-json-has-no-effect) en la guía de solución de problemas.975El stdout de tu hook debe contener solo el objeto JSON. Si tu perfil de shell imprime texto al iniciarse, puede interferir con el análisis del JSON. Consulta [El JSON del hook no tiene efecto](/docs/es/hooks-guide#hook-json-has-no-effect) en la guía de solución de problemas.
976 976
977Las cadenas de salida de hook, incluyendo `additionalContext`, `systemMessage` e `initialUserMessage`, y su stdout plano, están limitadas a 10.000 caracteres:977Las cadenas `additionalContext`, `systemMessage` e `initialUserMessage` de un hook, y su stdout plano, están limitadas a 10.000 caracteres:
978 978
979* **Alcance**: Claude Code mide cada cadena por su cuenta, incluso cuando varios hooks se ejecutan para el mismo evento. Para salida JSON, cada campo se mide por separado; stdout plano se mide en su totalidad.979* **Alcance**: Claude Code mide cada cadena por separado, incluso cuando varios hooks se ejecutan para el mismo evento. En la salida JSON, cada campo se mide por separado; el stdout plano se mide completo.
980* **Sobre el límite**: Claude Code guarda la salida en un archivo en el directorio de sesión y la reemplaza con la ruta del archivo y una vista previa de hasta los primeros 2.000 caracteres. Un resultado de Bash válido grande se maneja de la misma manera, descrito bajo [Output limits](/docs/es/tools-reference#output-limits). A diferencia de ese techo de Bash, este límite no tiene configuración o variable de entorno para aumentarlo.980* **Por encima del límite**: Claude Code guarda la salida en un archivo en el directorio de la sesión y la reemplaza con la ruta del archivo y una vista previa de hasta los primeros 2.000 caracteres. Un resultado de Bash válido y grande se maneja de la misma manera, como se describe en [Límites de salida](/docs/es/tools-reference#output-limits). A diferencia de ese tope de Bash, este límite no tiene ningún ajuste ni variable de entorno para aumentarlo.
981* **Lectura del archivo**: Claude Code no le pide a Claude que lea el archivo, así que mantenga cualquier cosa que Claude siempre deba ver dentro del límite.981* **Lectura del archivo**: Claude Code no le pide a Claude que lea el archivo, así que mantén dentro del límite todo lo que Claude deba ver siempre.
982 982
983El objeto JSON admite tres tipos de campos:983El objeto JSON admite tres tipos de campos:
984 984
985* **Campos universales** como `continue` se enumeran en la tabla a continuación. Cada evento los acepta, pero algunos eventos los descartan o entregan `systemMessage` en otro lugar que no sea la transcripción. Cada sección de evento lo indica. `terminalSequence` funciona en esos eventos también, con las excepciones enumeradas bajo [Emit terminal notifications](#emit-terminal-notifications).985* **Campos universales** como `continue`, que se enumeran en la tabla a continuación. Todos los eventos los aceptan, pero algunos eventos los descartan o entregan `systemMessage` en un lugar distinto de la transcripción. La sección de cada evento lo indica. `terminalSequence` también funciona en esos eventos, con las excepciones enumeradas en [Emitir notificaciones de terminal](#emit-terminal-notifications).
986* **`decision` y `reason` de nivel superior** son utilizados por algunos eventos para bloquear o proporcionar retroalimentación.986* **`decision` y `reason` de nivel superior**, que algunos eventos usan para bloquear o proporcionar retroalimentación.
987* **`hookSpecificOutput`** es un objeto anidado para eventos que necesitan control más rico. Requiere un campo `hookEventName` establecido en el nombre del evento.987* **`hookSpecificOutput`**, un objeto anidado para eventos que necesitan un control más rico. Requiere un campo `hookEventName` establecido en el nombre del evento.
988 988
989| Campo | Predeterminado | Descripción |989| Campo | Predeterminado | Descripción |
990| :- | :- | :- |990| :- | :- | :- |
991| `continue` | `true` | Si es `false`, Claude detiene el procesamiento completamente después de que se ejecuta el hook. Tiene precedencia sobre cualquier campo de decisión específico del evento |991| `continue` | `true` | Si es `false`, Claude detiene el procesamiento por completo después de que se ejecuta el hook. Tiene precedencia sobre cualquier campo de decisión específico del evento |
992| `stopReason` | ninguno | Mensaje mostrado al usuario cuando `continue` es `false`. Se queda en la conversación, por lo que Claude lo ve si la conversación continúa |992| `stopReason` | ninguno | Mensaje mostrado al usuario cuando `continue` es `false`. Permanece en la conversación, por lo que Claude lo ve si la conversación continúa |
993| `suppressOutput` | `false` | No tiene efecto: Claude Code acepta el campo pero no actúa sobre él. El stdout de un hook exitoso nunca se muestra en la transcripción y se registra en el registro de depuración |993| `suppressOutput` | `false` | No tiene efecto: Claude Code acepta el campo pero no actúa sobre él. El stdout de un hook exitoso nunca se muestra en la transcripción y se registra en el registro de depuración |
994| `systemMessage` | ninguno | Mensaje de advertencia mostrado al usuario. En [Agent SDK](/docs/es/agent-sdk/overview) y salida [`--output-format stream-json`](/docs/es/headless), puede llegar como un [`SDKInformationalMessage`](/docs/es/agent-sdk/typescript#sdkinformationalmessage) |994| `systemMessage` | ninguno | Mensaje de advertencia mostrado al usuario. En la salida del [Agent SDK](/docs/es/agent-sdk/overview) y de [`--output-format stream-json`](/docs/es/headless), puede llegar como un [`SDKInformationalMessage`](/docs/es/agent-sdk/typescript#sdkinformationalmessage) |
995| `terminalSequence` | ninguno | Una secuencia de escape de terminal para que Claude Code emita en su nombre, como una notificación de escritorio, título de ventana o campana. Restringido a OSC `0`/`1`/`2`/`9`/`99`/`777` y BEL. Si el valor contiene algo fuera de la lista de permitidos, el campo se ignora. Use esto en lugar de escribir en `/dev/tty`, que no está disponible para hooks |995| `terminalSequence` | ninguno | Una secuencia de escape de terminal para que Claude Code la emita en tu nombre, como una notificación de escritorio, un título de ventana o una campana. Restringida a OSC `0`/`1`/`2`/`9`/`99`/`777` y BEL. Si el valor contiene algo fuera de la lista de permitidos, el campo se ignora. Usa esto en lugar de escribir en `/dev/tty`, que no está disponible para los hooks |
996 996
997Para detener Claude completamente:997Para detener a Claude por completo:
998 998
999```json theme={null}999```json theme={null}
1000{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }1000{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }
1001```1001```
1002 1002
1003Para hooks `PreToolUse` y `PostToolUse`, la parada se aplica incluso cuando la llamada a herramienta falla o se completa mientras Claude aún está transmitiendo una respuesta.1003Para los hooks `PreToolUse` y `PostToolUse`, la detención se aplica incluso cuando la llamada a herramienta falla o se completa mientras Claude todavía está transmitiendo una respuesta en streaming.
1004 1004
1005<h4 id="emit-terminal-notifications">1005<h4 id="emit-terminal-notifications">
1006 Emitir notificaciones de terminal1006 Emitir notificaciones de terminal
1007</h4>1007</h4>
1008 1008
1009Los hooks se ejecutan sin una terminal de control, por lo que escribir secuencias de escape directamente en `/dev/tty` falla. En su lugar, devuelva la secuencia de escape en el campo `terminalSequence` y Claude Code la emite por usted a través de su propia ruta de escritura de terminal. Esto es libre de carreras, funciona dentro de tmux y GNU screen, y funciona en Windows donde no hay `/dev/tty`.1009Los hooks se ejecutan sin una terminal de control, por lo que escribir secuencias de escape directamente en `/dev/tty` falla. En su lugar, devuelve la secuencia de escape en el campo `terminalSequence` y Claude Code la emite por ti a través de su propia ruta de escritura en la terminal. Esto está libre de condiciones de carrera, funciona dentro de tmux y GNU screen, y funciona en Windows, donde no hay `/dev/tty`.
1010 1010
1011El campo acepta una cadena de una o más secuencias de escape permitidas:1011El campo acepta una cadena de una o más secuencias de escape permitidas:
1012 1012
1013* OSC `0`, `1`, `2`: títulos de ventana e icono1013* OSC `0`, `1`, `2`: títulos de ventana e icono
1014* OSC `9`: notificaciones de iTerm2, ConEmu, Windows Terminal y WezTerm, incluyendo progreso de barra de tareas `9;4`1014* OSC `9`: notificaciones de iTerm2, ConEmu, Windows Terminal y WezTerm, incluido el progreso de la barra de tareas `9;4`
1015* OSC `99`: notificaciones de Kitty1015* OSC `99`: notificaciones de Kitty
1016* OSC `777`: notificaciones de urxvt, Ghostty y Warp1016* OSC `777`: notificaciones de urxvt, Ghostty y Warp
1017* BEL desnudo1017* BEL sin más
1018 1018
1019Las secuencias pueden terminarse con BEL o con ST. Cualquier cosa fuera de la lista de permitidos, incluyendo secuencias de cursor y color CSI, secuencias de paleta OSC, hipervínculos OSC 8, escrituras de portapapeles OSC 52 y OSC 1337, se rechaza y el campo se ignora.1019Las secuencias pueden terminar con BEL o con ST. Cualquier cosa fuera de la lista de permitidos, incluidas las secuencias CSI de cursor y color, las secuencias OSC de paleta, los hipervínculos OSC 8, las escrituras al portapapeles OSC 52 y OSC 1337, se rechaza y el campo se ignora.
1020 1020
1021Claude Code escribe la secuencia en sí cuando procesa la salida de su hook, por lo que el campo funciona en eventos que descartan `systemMessage` y `continue`, como `Notification` y `StopFailure`. Tiene dos límites:1021Claude Code escribe la secuencia por sí mismo cuando procesa la salida de tu hook, por lo que el campo funciona en eventos que descartan `systemMessage` y `continue`, como `Notification` y `StopFailure`. Tiene dos limitaciones:
1022 1022
1023* Claude Code escribe la secuencia solo en una sesión interactiva, y solo mientras su interfaz está en pantalla. En modo no interactivo con la bandera `-p` y en Agent SDK, ignora el campo.1023* Claude Code escribe la secuencia solo en una sesión interactiva, y solo mientras su interfaz está en pantalla. En modo no interactivo con el flag `-p` y en el Agent SDK, ignora el campo.
1024* Un hook de comando `WorktreeCreate` no puede devolver JSON, porque Claude Code lee su stdout como la ruta de worktree. Un hook HTTP `WorktreeCreate` devuelve JSON y puede incluir el campo.1024* Un hook de comando `WorktreeCreate` no puede devolver JSON, porque Claude Code lee su stdout como la ruta del worktree. Un hook HTTP `WorktreeCreate` devuelve JSON y puede incluir el campo.
1025 1025
1026El ejemplo a continuación dispara una notificación de escritorio desde un hook `Notification`. La secuencia de escape se construye con escapes octales `printf` para que los bytes de control nunca aparezcan en la línea de comandos del shell, y `jq -n --arg` construye la salida JSON para que las comillas, barras invertidas y saltos de línea en el mensaje de notificación se escapen correctamente:1026El ejemplo a continuación dispara una notificación de escritorio desde un hook `Notification`. La secuencia de escape se construye con escapes octales de `printf` para que los bytes de control nunca aparezcan en la línea de comandos del shell, y `jq -n --arg` construye la salida JSON para que las comillas, barras invertidas y saltos de línea del mensaje de notificación se escapen correctamente:
1027 1027
1028```bash theme={null}1028```bash theme={null}
1029#!/bin/bash1029#!/bin/bash
1041 Agregar contexto para Claude1041 Agregar contexto para Claude
1042</h4>1042</h4>
1043 1043
1044El campo `additionalContext` pasa una cadena de su hook a la ventana de contexto de Claude. Claude Code envuelve la cadena en un [recordatorio del sistema](/docs/es/glossary#system-reminder) e la inserta en la conversación en el punto donde se activó el hook. Claude lee el recordatorio en la siguiente solicitud del modelo, pero no aparece como un mensaje de chat en la interfaz.1044El campo `additionalContext` pasa una cadena desde tu hook a la ventana de contexto de Claude. Claude Code envuelve la cadena en un [recordatorio del sistema](/docs/es/glossary#system-reminder) y la inserta en la conversación en el punto donde se activó el hook. Claude lee el recordatorio en la siguiente solicitud al modelo, pero no aparece como un mensaje de chat en la interfaz.
1045 1045
1046Devuelva `additionalContext` dentro de `hookSpecificOutput` junto al nombre del evento:1046Devuelve `additionalContext` dentro de `hookSpecificOutput` junto al nombre del evento:
1047 1047
1048```json theme={null}1048```json theme={null}
1049{1049{
1059* [SessionStart](#sessionstart) y [SubagentStart](#subagentstart): al inicio de la conversación, antes del primer prompt1059* [SessionStart](#sessionstart) y [SubagentStart](#subagentstart): al inicio de la conversación, antes del primer prompt
1060* [UserPromptSubmit](#userpromptsubmit) y [UserPromptExpansion](#userpromptexpansion): junto al prompt enviado1060* [UserPromptSubmit](#userpromptsubmit) y [UserPromptExpansion](#userpromptexpansion): junto al prompt enviado
1061* [PreToolUse](#pretooluse), [PostToolUse](#posttooluse), [PostToolUseFailure](#posttoolusefailure) y [PostToolBatch](#posttoolbatch): junto al resultado de la herramienta1061* [PreToolUse](#pretooluse), [PostToolUse](#posttooluse), [PostToolUseFailure](#posttoolusefailure) y [PostToolBatch](#posttoolbatch): junto al resultado de la herramienta
1062* [Stop](#stop) y [SubagentStop](#subagentstop): al final del turno. La conversación continúa para que Claude pueda actuar sobre la retroalimentación. Consulte [Stop decision control](#stop-decision-control)1062* [Stop](#stop) y [SubagentStop](#subagentstop): al final del turno. La conversación continúa para que Claude pueda actuar sobre la retroalimentación. Consulta [Control de decisión de Stop](#stop-decision-control)
1063* [PostModelSwitch](#postmodelswitch): con la siguiente solicitud después del cambio. Consulte [PostModelSwitch decision control](#postmodelswitch-decision-control) para el tiempo1063* [PostModelSwitch](#postmodelswitch): con la siguiente solicitud después del cambio. Consulta [Control de decisión de PostModelSwitch](#postmodelswitch-decision-control) para ver cuándo ocurre
1064 1064
1065Cuando varios hooks devuelven `additionalContext` para el mismo evento, Claude recibe todos los valores.1065Cuando varios hooks devuelven `additionalContext` para el mismo evento, Claude recibe todos los valores.
1066 1066
1067Si un valor excede 10.000 caracteres, Claude Code escribe el texto en un archivo en el directorio de sesión y pasa a Claude la ruta del archivo con una vista previa de hasta los primeros 2.000 caracteres en su lugar. Claude puede leer el archivo, pero Claude Code no se lo pide.1067Si un valor supera los 10.000 caracteres, Claude Code escribe el texto en un archivo en el directorio de la sesión y, en su lugar, le pasa a Claude la ruta del archivo con una vista previa de hasta los primeros 2.000 caracteres. Claude puede leer el archivo, pero Claude Code no se lo pide.
1068 1068
1069Use `additionalContext` para información que Claude debe conocer sobre el estado actual de su entorno o la operación que acaba de ejecutarse:1069Usa `additionalContext` para información que Claude debe conocer sobre el estado actual de tu entorno o sobre la operación que acaba de ejecutarse:
1070 1070
1071* **Estado del entorno**: la rama actual, destino de implementación o banderas de características activas1071* **Estado del entorno**: la rama actual, el destino de despliegue o los feature flags activos
1072* **Reglas de proyecto condicionales**: qué comando de prueba se aplica al archivo que acaba de editar, qué directorios son de solo lectura en este worktree1072* **Reglas de proyecto condicionales**: qué comando de prueba se aplica al archivo que se acaba de editar, qué directorios son de solo lectura en este worktree
1073* **Datos externos**: problemas abiertos asignados a usted, resultados recientes de CI, contenido obtenido de un servicio interno1073* **Datos externos**: issues abiertos asignados a ti, resultados recientes de CI, contenido obtenido de un servicio interno
1074 1074
1075Para instrucciones que nunca cambian, prefiera [CLAUDE.md](/docs/es/memory). Se carga sin ejecutar un script y es el lugar estándar para convenciones de proyecto estáticas.1075Para instrucciones que nunca cambian, prefiere [CLAUDE.md](/docs/es/memory). Se carga sin ejecutar un script y es el lugar estándar para las convenciones estáticas del proyecto.
1076 1076
1077Escriba el texto como declaraciones factuales en lugar de instrucciones de sistema imperativas. Frases como "El destino de implementación es producción" o "Este repositorio usa `bun test`" se leen como información del proyecto. El texto enmarcado como comandos de sistema fuera de banda puede activar las defensas de inyección de prompts de Claude, lo que hace que Claude le muestre el texto en lugar de tratarlo como contexto.1077Escribe el texto como afirmaciones de hechos en lugar de instrucciones de sistema imperativas. Frases como "El destino de despliegue es producción" o "Este repositorio usa `bun test`" se leen como información del proyecto. El texto planteado como comandos de sistema fuera de banda puede activar las defensas contra la inyección de prompts de Claude, lo que hace que Claude te muestre el texto en lugar de tratarlo como contexto.
1078 1078
1079Claude Code guarda el texto inyectado en la transcripción de sesión. Para eventos a mitad de sesión como `PostToolUse` o `UserPromptSubmit`, cuando reanuda con `--continue` o `--resume`, Claude Code reproduce el texto guardado en lugar de volver a ejecutar el hook para turnos anteriores, por lo que valores como marcas de tiempo o SHAs de commit se vuelven obsoletos. Los hooks `SessionStart` se ejecutan nuevamente al reanudar con `source` establecido en `"resume"`, o `"fork"` si agregó `--fork-session`, por lo que pueden actualizar su contexto.1079Claude Code guarda el texto inyectado en la transcripción de la sesión. Para eventos a mitad de sesión como `PostToolUse` o `UserPromptSubmit`, cuando reanudas con `--continue` o `--resume`, Claude Code reproduce el texto guardado en lugar de volver a ejecutar el hook para los turnos anteriores, por lo que valores como marcas de tiempo o SHAs de commits quedan obsoletos. Los hooks `SessionStart` se ejecutan de nuevo al reanudar con `source` establecido en `"resume"`, o en `"fork"` si agregaste `--fork-session`, por lo que pueden actualizar su contexto.
1080 1080
1081<h4 id="decision-control">1081<h4 id="decision-control">
1082 Control de decisión1082 Control de decisión
1083</h4>1083</h4>
1084 1084
1085No todos los eventos admiten bloqueo o control de comportamiento a través de JSON. Los eventos que lo hacen cada uno usan un conjunto diferente de campos para expresar esa decisión. Use esta tabla como referencia rápida antes de escribir un hook:1085No todos los eventos admiten bloquear o controlar el comportamiento mediante JSON. Los que sí lo admiten usan cada uno un conjunto distinto de campos para expresar esa decisión. Usa esta tabla como referencia rápida antes de escribir un hook:
1086 1086
1087| Eventos | Patrón de decisión | Campos clave |1087| Eventos | Patrón de decisión | Campos clave |
1088| :- | :- | :- |1088| :- | :- | :- |
1089| UserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, SubagentStop, ConfigChange, PreCompact | `decision` de nivel superior | `decision: "block"`, `reason`. Stop y SubagentStop también aceptan `hookSpecificOutput.additionalContext` para [retroalimentación sin error que continúa la conversación](#stop-decision-control) |1089| UserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, SubagentStop, ConfigChange, PreCompact | `decision` de nivel superior | `decision: "block"`, `reason`. Stop y SubagentStop también aceptan `hookSpecificOutput.additionalContext` para [retroalimentación sin error que continúa la conversación](#stop-decision-control) |
1090| TeammateIdle, TaskCompleted | Código de salida o `continue: false` | El código de salida 2 bloquea la acción con retroalimentación de stderr. JSON `{"continue": false, "stopReason": "..."}` también detiene al compañero completamente, coincidiendo con el comportamiento del hook `Stop`; [TaskCompleted lo ignora cuando la herramienta `TaskUpdate` activó el evento](#taskcompleted-decision-control) |1090| TeammateIdle, TaskCompleted | Código de salida o `continue: false` | El código de salida 2 bloquea la acción con retroalimentación de stderr. JSON `{"continue": false, "stopReason": "..."}` también detiene al compañero por completo, igual que el comportamiento del hook `Stop`; [TaskCompleted lo ignora cuando la herramienta `TaskUpdate` activó el evento](#taskcompleted-decision-control) |
1091| TaskCreated | Código de salida o `decision` de nivel superior | El código de salida 2 o `decision: "block"` [cancela la tarea](#taskcreated-decision-control) y devuelve el mensaje a Claude. `continue: false` se ignora |1091| TaskCreated | Código de salida o `decision` de nivel superior | El código de salida 2 o `decision: "block"` [cancela la tarea](#taskcreated-decision-control) y devuelve el mensaje a Claude. `continue: false` se ignora |
1092| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask/defer), `permissionDecisionReason` |1092| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask/defer), `permissionDecisionReason` |
1093| PreModelSwitch | `hookSpecificOutput` o `decision` de nivel superior | `permissionDecision` (allow/deny/ask), `permissionDecisionReason`. `decision: "block"` también [cancela el cambio](#premodelswitch-decision-control) |1093| PreModelSwitch | `hookSpecificOutput` o `decision` de nivel superior | `permissionDecision` (allow/deny/ask), `permissionDecisionReason`. `decision: "block"` también [cancela el cambio](#premodelswitch-decision-control) |
1094| PermissionRequest | `hookSpecificOutput` | `decision.behavior` (allow/deny) |1094| PermissionRequest | `hookSpecificOutput` | `decision.behavior` (allow/deny) |
1095| PermissionDenied | `hookSpecificOutput` | `retry: true` le dice al modelo que puede reintentar la llamada a herramienta denegada; Claude Code ignora `retry: true` para [denegaciones sin veredicto](#permissiondenied-decision-control) |1095| PermissionDenied | `hookSpecificOutput` | `retry: true` le indica al modelo que puede reintentar la llamada a herramienta denegada; Claude Code lo ignora para [denegaciones sin veredicto](#permissiondenied-decision-control) |
1096| WorktreeCreate | ruta return | El hook de comando imprime la ruta en stdout; el hook HTTP devuelve `hookSpecificOutput.worktreePath`. El fallo del hook o la ruta faltante falla la creación |1096| WorktreeCreate | devolución de ruta | El hook de comando imprime la ruta en stdout; el hook HTTP devuelve `hookSpecificOutput.worktreePath`. Un fallo del hook o la falta de ruta hace fallar la creación |
1097| WorktreeRemove | Código de salida | Cualquier código de salida distinto de cero hace que la eliminación falle si el directorio aún existe después. La salida JSON se descarta |1097| WorktreeRemove | Código de salida | Cualquier código de salida distinto de cero hace que la eliminación falle si el directorio sigue existiendo después. La salida JSON se descarta |
1098| Elicitation | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (valores de campo de formulario para accept) |1098| Elicitation, ElicitationResult | `hookSpecificOutput` o `decision` de nivel superior | `action` (accept/decline/cancel), `content` (valores de los campos del formulario). `decision: "block"` también [rechaza](#other-ways-to-decline-an-elicitation) |
1099| ElicitationResult | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (valores de campo de formulario override) |1099| MessageDisplay | `hookSpecificOutput` | `displayContent` reemplaza el texto mostrado en pantalla. Solo afecta a la visualización: la transcripción y lo que Claude ve conservan el original |
1100| MessageDisplay | `hookSpecificOutput` | `displayContent` reemplaza el texto mostrado en pantalla. Solo visualización: la transcripción y lo que Claude ve mantienen el original |1100| SessionStart, SubagentStart, PostModelSwitch | Solo contexto | `hookSpecificOutput.additionalContext` agrega contexto para Claude. SessionStart también acepta [`initialUserMessage`, `watchPaths`, `sessionTitle` y `reloadSkills`](#sessionstart-decision-control). Sin bloqueo ni control de decisión |
1101| SessionStart, SubagentStart, PostModelSwitch | Solo contexto | `hookSpecificOutput.additionalContext` agrega contexto para Claude. SessionStart también acepta [`initialUserMessage`, `watchPaths`, `sessionTitle` y `reloadSkills`](#sessionstart-decision-control). Sin bloqueo o control de decisión |1101| Setup, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, DirectoryAdded, FileChanged | Ninguno | Sin control de decisión. Se usan para efectos secundarios como registro o limpieza |
1102| Setup, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, DirectoryAdded, FileChanged | Ninguno | Sin control de decisión. Se usa para efectos secundarios como registro o limpieza |1102
1103 1103Algunos eventos también pueden reescribir contenido en lugar de solo permitirlo o bloquearlo:
1104Algunos eventos también pueden reescribir contenido en lugar de solo permitir o bloquearlo:1104
1105 1105* `PreToolUse`: `updatedInput` directamente bajo `hookSpecificOutput` reemplaza los argumentos de una herramienta antes de que se ejecute. Consulta [Control de decisión de PreToolUse](#pretooluse-decision-control)
1106* `PreToolUse`: `updatedInput` directamente bajo `hookSpecificOutput` reemplaza los argumentos de una herramienta antes de que se ejecute. Consulte [PreToolUse decision control](#pretooluse-decision-control)1106* `PermissionRequest`: `updatedInput` dentro del objeto `decision`. Consulta [Control de decisión de PermissionRequest](#permissionrequest-decision-control)
1107* `PermissionRequest`: `updatedInput` dentro del objeto `decision`. Consulte [PermissionRequest decision control](#permissionrequest-decision-control)1107* `PostToolUse`: `updatedToolOutput` reemplaza el resultado de la herramienta. Consulta [Control de decisión de PostToolUse](#posttooluse-decision-control)
1108* `PostToolUse`: `updatedToolOutput` reemplaza el resultado de la herramienta. Consulte [PostToolUse decision control](#posttooluse-decision-control)
1109* `UserPromptSubmit`: no puede reemplazar el prompt; solo inyecta `additionalContext` junto a él1108* `UserPromptSubmit`: no puede reemplazar el prompt; solo inyecta `additionalContext` junto a él
1110 1109
1111Para casos de uso de redacción o transformación, intercepte en `PreToolUse` para entradas de herramientas salientes y `PostToolUse` para resultados de herramientas entrantes.1110Para casos de uso de redacción o transformación, intercepta en `PreToolUse` las entradas salientes de herramientas y en `PostToolUse` los resultados entrantes de herramientas.
1112 1111
1113Aquí hay ejemplos de cada patrón en acción:1112Aquí hay ejemplos de cada patrón en acción:
1114 1113
1115<Tabs>1114<Tabs>
1116 <Tab title="Decisión de nivel superior">1115 <Tab title="Decisión de nivel superior">
1117 El único valor para `decision` es `"block"`. Para permitir que la acción continúe, omita `decision` de su JSON, o salga 0 sin ningún JSON en absoluto:1116 El único valor para `decision` es `"block"`. Para permitir que la acción continúe, omite `decision` de tu JSON, o sal con 0 sin ningún JSON:
1118 1117
1119 ```json theme={null}1118 ```json theme={null}
1120 {1119 {
1125 </Tab>1124 </Tab>
1126 1125
1127 <Tab title="PreToolUse">1126 <Tab title="PreToolUse">
1128 Usa `hookSpecificOutput` para control más rico: permitir, denegar, o escalar al usuario. También puede modificar la entrada de la herramienta antes de que se ejecute o inyectar contexto adicional para Claude. Consulte [PreToolUse decision control](#pretooluse-decision-control) para el conjunto completo de opciones.1127 Usa `hookSpecificOutput` para un control más rico: permitir, denegar o escalar al usuario. También puedes modificar la entrada de la herramienta antes de que se ejecute o inyectar contexto adicional para Claude. Consulta [Control de decisión de PreToolUse](#pretooluse-decision-control) para ver el conjunto completo de opciones.
1129 1128
1130 ```json theme={null}1129 ```json theme={null}
1131 {1130 {
1139 </Tab>1138 </Tab>
1140 1139
1141 <Tab title="PermissionRequest">1140 <Tab title="PermissionRequest">
1142 Usa `hookSpecificOutput` para permitir o denegar una solicitud de permiso en nombre del usuario. Al permitir, también puede modificar la entrada de la herramienta o aplicar reglas de permiso para que el usuario no sea solicitado nuevamente. Consulte [PermissionRequest decision control](#permissionrequest-decision-control) para el conjunto completo de opciones.1141 Usa `hookSpecificOutput` para permitir o denegar una solicitud de permiso en nombre del usuario. Al permitir, también puedes modificar la entrada de la herramienta o aplicar reglas de permisos para que no se le vuelva a preguntar al usuario. Consulta [Control de decisión de PermissionRequest](#permissionrequest-decision-control) para ver el conjunto completo de opciones.
1143 1142
1144 ```json theme={null}1143 ```json theme={null}
1145 {1144 {
1157 </Tab>1156 </Tab>
1158</Tabs>1157</Tabs>
1159 1158
1160Para ejemplos extendidos incluyendo validación de comandos Bash, filtrado de prompts y scripts de aprobación automática, consulte [What you can automate](/docs/es/hooks-guide#what-you-can-automate) en la guía y la [implementación de referencia del validador de comandos Bash](https://github.com/anthropics/claude-code/blob/main/examples/hooks/bash_command_validator_example.py).1159Para ejemplos más extensos, incluidos la validación de comandos Bash, el filtrado de prompts y scripts de aprobación automática, consulta [Qué puedes automatizar](/docs/es/hooks-guide#what-you-can-automate) en la guía y la [implementación de referencia del validador de comandos Bash](https://github.com/anthropics/claude-code/blob/main/examples/hooks/bash_command_validator_example.py).
1161 1160
1162<h2 id="hook-events">1161<h2 id="hook-events">
1163 Eventos de hooks1162 Eventos de hooks
1164</h2>1163</h2>
1165 1164
1166Cada evento corresponde a un punto del ciclo de vida de Claude Code en el que pueden ejecutarse hooks. Las secciones siguientes están ordenadas según el ciclo de vida: desde la configuración de la sesión, pasando por el bucle agéntico, hasta el final de la sesión. Cada sección describe cuándo se dispara el evento, qué matchers admite, la entrada JSON que recibe y cómo controlar el comportamiento mediante la salida.1165Cada evento corresponde a un punto del ciclo de vida de Claude Code en el que pueden ejecutarse hooks. Las secciones siguientes están ordenadas según el ciclo de vida: desde la configuración de la sesión, pasando por el bucle agéntico, hasta el final de la sesión. Cada sección describe cuándo se activa el evento, qué matchers admite, la entrada JSON que recibe y cómo controlar el comportamiento mediante la salida.
1167 1166
1168<h3 id="sessionstart">1167<h3 id="sessionstart">
1169 SessionStart1168 SessionStart
1171 1170
1172Se ejecuta cuando Claude Code inicia una sesión nueva o reanuda una sesión existente. Es útil para cargar contexto de desarrollo, como issues existentes o cambios recientes en tu base de código, o para configurar variables de entorno. Para contexto estático que no requiere un script, usa [CLAUDE.md](/docs/es/memory) en su lugar.1171Se ejecuta cuando Claude Code inicia una sesión nueva o reanuda una sesión existente. Es útil para cargar contexto de desarrollo, como issues existentes o cambios recientes en tu base de código, o para configurar variables de entorno. Para contexto estático que no requiere un script, usa [CLAUDE.md](/docs/es/memory) en su lugar.
1173 1172
1174SessionStart se ejecuta en cada sesión, así que mantén estos hooks rápidos. Solo se admiten hooks `type: "command"` y `type: "mcp_tool"`. Consulta [Campos de hooks de herramientas MCP](#mcp-tool-hook-fields) para saber cuándo se ejecutan los hooks `mcp_tool`.1173SessionStart se ejecuta en cada sesión, así que mantén estos hooks rápidos. Solo se admiten hooks `type: "command"` y `type: "mcp_tool"`. Consulta [campos de hooks de herramientas MCP](#mcp-tool-hook-fields) para saber cuándo se ejecutan los hooks `mcp_tool`.
1175 1174
1176El valor del matcher corresponde a cómo se inició la sesión:1175El valor del matcher corresponde a cómo se inició la sesión:
1177 1176
1178| Matcher | Cuándo se dispara |1177| Matcher | Cuándo se activa |
1179| :- | :- |1178| :- | :- |
1180| `startup` | Sesión nueva |1179| `startup` | Sesión nueva |
1181| `resume` | `--resume`, `--continue` o `/resume` |1180| `resume` | `--resume`, `--continue` o `/resume` |
1182| `clear` | `/clear` |1181| `clear` | `/clear` |
1183| `compact` | Compactación automática o manual |1182| `compact` | Compactación automática o manual |
1184| `fork` | Una sesión nueva bifurcada de una existente: `--fork-session` con `--resume` o `--continue`, la copia en segundo plano de `/fork`, `/branch` o una conversación que [mueves al segundo plano](/docs/es/agent-view#from-inside-a-session) |1183| `fork` | Una sesión nueva bifurcada de una existente: `--fork-session` con `--resume` o `--continue`, la copia en segundo plano de `/fork`, `/branch`, o una conversación que [mueves a segundo plano](/docs/es/agent-view#from-inside-a-session) |
1185 1184
1186Antes de la v2.1.214, las sesiones bifurcadas informaban el origen `"resume"`.1185Antes de la v2.1.214, las sesiones bifurcadas informaban el origen `"resume"`.
1187 1186
1191 1190
1192La misma espera se aplica al arrancar, incluida una sesión reanudada: un prompt que envías mientras los hooks SessionStart todavía se están ejecutando no llega a Claude hasta que terminan.1191La misma espera se aplica al arrancar, incluida una sesión reanudada: un prompt que envías mientras los hooks SessionStart todavía se están ejecutando no llega a Claude hasta que terminan.
1193 1192
1194Durante cualquiera de las dos esperas, presiona `Esc` para devolver el prompt a la entrada sin enviarlo. Los hooks siguen ejecutándose.1193Durante cualquiera de las dos esperas, presiona `Esc` para devolver el prompt al campo de entrada sin enviarlo. Los hooks siguen ejecutándose.
1195 1194
1196<h4 id="sessionstart-input">1195<h4 id="sessionstart-input">
1197 Entrada de SessionStart1196 Entrada de SessionStart
1201 1200
1202| Campo | Descripción |1201| Campo | Descripción |
1203| :- | :- |1202| :- | :- |
1204| `source` | Cómo se inició la sesión: `"startup"` para sesiones nuevas, `"resume"` para sesiones reanudadas, `"clear"` después de `/clear`, `"compact"` después de la compactación o `"fork"` para una sesión nueva bifurcada de una existente |1203| `source` | Cómo se inició la sesión: `"startup"` para sesiones nuevas, `"resume"` para sesiones reanudadas, `"clear"` después de `/clear`, `"compact"` después de la compactación, o `"fork"` para una sesión nueva bifurcada de una existente |
1205| `model` | El identificador del modelo activo. Puede omitirse, por ejemplo después de `/clear` o cuando una sesión se restaura mediante la recuperación de conversaciones, así que comprueba que el campo exista antes de leerlo |1204| `model` | El identificador del modelo activo. Puede omitirse, por ejemplo después de `/clear` o cuando una sesión se restaura mediante la recuperación de conversaciones, así que verifica que el campo exista antes de leerlo |
1206| `agent_type` | El nombre del agente, presente cuando inicias Claude Code con `claude --agent <name>` |1205| `agent_type` | El nombre del agente, presente cuando inicias Claude Code con `claude --agent <name>` |
1207| `session_title` | El título personalizado de la sesión, presente cuando hay uno definido, por ejemplo con `--name`, `/rename`, la salida `sessionTitle` de un hook o `renameSession()` del Agent SDK. Un hook que emite `sessionTitle` puede comprobar primero este campo para evitar sobrescribir un título personalizado existente |1206| `session_title` | El título personalizado de la sesión, presente cuando hay uno establecido, por ejemplo con `--name`, `/rename`, la salida `sessionTitle` de un hook o `renameSession()` del Agent SDK. Un hook que emite `sessionTitle` puede revisar primero este campo para evitar sobrescribir un título personalizado existente |
1208 1207
1209Una sesión a la que no le has puesto nombre puede tener igualmente un [título generado](/docs/es/sessions#name-your-sessions). Ese título no es un título personalizado y no aparece en `session_title`.1208Una sesión a la que no le has puesto nombre puede tener igualmente un [título generado](/docs/es/sessions#name-your-sessions). Ese título no es un título personalizado y no aparece en `session_title`.
1210 1209
1212 1211
1213| Campo | Descripción |1212| Campo | Descripción |
1214| :- | :- |1213| :- | :- |
1215| `seconds_since_last_response` | Segundos de tiempo real desde la última respuesta en la transcripción reanudada |1214| `seconds_since_last_response` | Segundos de tiempo real transcurridos desde la última respuesta en la transcripción reanudada |
1216| `context_tokens` | Tokens que la primera solicitud de la sesión reanudada vuelve a enviar como su prompt |1215| `context_tokens` | Tokens que la primera solicitud de la sesión reanudada vuelve a enviar como su prompt |
1217| `prompt_cache_likely_expired` | `true` cuando la última respuesta es más antigua que la [vida útil de la caché de prompts](/docs/es/prompt-caching#cache-lifetime) de la sesión o una compactación posterior reemplazó la conversación almacenada en caché |1216| `prompt_cache_likely_expired` | `true` cuando la última respuesta es más antigua que la [duración de la caché de prompts](/docs/es/prompt-caching#cache-lifetime) de la sesión o cuando una compactación posterior reemplazó la conversación almacenada en caché |
1218| `estimated_cache_write_usd` | Costo estimado en dólares estadounidenses de escribir `context_tokens` en la caché de prompts con el modelo de la sesión, sin incluir la respuesta |1217| `estimated_cache_write_usd` | Costo estimado en dólares estadounidenses de escribir `context_tokens` en la caché de prompts con el modelo de la sesión, sin incluir la respuesta |
1219 1218
1220Este ejemplo muestra la entrada de una sesión reanudada 90 minutos después de su última respuesta:1219Este ejemplo muestra la entrada de una sesión reanudada 90 minutos después de su última respuesta:
1242 1241
1243| Campo | Descripción |1242| Campo | Descripción |
1244| :- | :- |1243| :- | :- |
1245| `additionalContext` | Cadena agregada al contexto de Claude al inicio de la conversación, antes del primer prompt. Consulta [Agregar contexto para Claude](#add-context-for-claude) para saber cómo se entrega el texto y qué poner en él |1244| `additionalContext` | Cadena agregada al contexto de Claude al inicio de la conversación, antes del primer prompt. Consulta [Agregar contexto para Claude](#add-context-for-claude) para saber cómo se entrega el texto y qué incluir en él |
1246| `initialUserMessage` | Cadena usada como primer mensaje de usuario de la sesión. Se aplica en [modo no interactivo](/docs/es/headless) con el flag `-p`, donde se convierte en el primer turno incluso si no se proporciona ningún prompt. Si se proporciona un prompt, este sigue como el siguiente turno. A diferencia de `additionalContext`, que se adjunta a un turno existente, esto crea el turno |1245| `initialUserMessage` | Cadena usada como el primer mensaje del usuario de la sesión. Se aplica en el [modo no interactivo](/docs/es/headless) con el flag `-p`, donde se convierte en el primer turno aunque no se proporcione ningún prompt. Si se proporciona un prompt, este sigue como el siguiente turno. A diferencia de `additionalContext`, que se adjunta a un turno existente, este crea el turno |
1247| `sessionTitle` | Establece el título de la sesión, con el mismo efecto que `/rename`. Úsalo para nombrar sesiones automáticamente a partir de la carpeta de inicio, la rama de git o el nombre del worktree. Se aplica cuando `source` es `"startup"`, `"resume"` o `"fork"`; se ignora con `"clear"` y `"compact"` |1246| `sessionTitle` | Establece el título de la sesión, con el mismo efecto que `/rename`. Úsalo para nombrar sesiones automáticamente a partir de la carpeta de inicio, la rama de git o el nombre del worktree. Se aplica cuando `source` es `"startup"`, `"resume"` o `"fork"`; se ignora en `"clear"` y `"compact"` |
1248| `watchPaths` | Array de rutas absolutas que se vigilan para eventos [FileChanged](#filechanged) durante esta sesión |1247| `watchPaths` | Array de rutas absolutas que se vigilarán para eventos [FileChanged](#filechanged) durante esta sesión |
1249| `reloadSkills` | Booleano. Cuando es `true`, Claude Code vuelve a examinar los directorios de [skills](/docs/es/skills) y comandos después de que terminan los hooks SessionStart, de modo que los skills que instaló el hook están disponibles en la misma sesión, a partir del primer prompt |1248| `reloadSkills` | Booleano. Cuando es `true`, Claude Code vuelve a escanear los directorios de [skills](/docs/es/skills) y de comandos después de que terminan los hooks SessionStart, de modo que los skills que instaló el hook estén disponibles en la misma sesión, a partir del primer prompt |
1250 1249
1251```json theme={null}1250```json theme={null}
1252{1251{
1258}1257}
1259```1258```
1260 1259
1261Como la stdout en texto plano ya llega a Claude para este evento, un hook que solo carga contexto puede imprimir directamente en stdout sin construir JSON. Usa la forma JSON cuando necesites combinar contexto con otros campos, como `sessionTitle`.1260Como la stdout en texto plano ya llega a Claude en este evento, un hook que solo carga contexto puede imprimir directamente en stdout sin construir JSON. Usa el formato JSON cuando necesites combinar contexto con otros campos como `sessionTitle`.
1262 1261
1263Usa `reloadSkills` cuando un hook SessionStart instala o actualiza skills. El descubrimiento de skills normalmente se ejecuta antes de que terminen los hooks SessionStart, por lo que los archivos que el hook escribe en `~/.claude/skills/` o `.claude/skills/` solo aparecerían en la siguiente sesión. Este ejemplo sincroniza un repositorio compartido de skills y solicita el nuevo examen:1262Usa `reloadSkills` cuando un hook SessionStart instala o actualiza skills. El descubrimiento de skills normalmente se ejecuta antes de que terminen los hooks SessionStart, así que los archivos que el hook escribe en `~/.claude/skills/` o `.claude/skills/` de otro modo solo aparecerían en la siguiente sesión. Este ejemplo sincroniza un repositorio compartido de skills y solicita el nuevo escaneo:
1264 1263
1265```bash theme={null}1264```bash theme={null}
1266#!/bin/bash1265#!/bin/bash
1271echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'1270echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'
1272```1271```
1273 1272
1274La URL del repositorio es un marcador de posición; reemplázala por tu propio repositorio de skills. Con el marcador de posición, el clon falla e imprime un mensaje `fatal:` en stderr. La stderr de un hook SessionStart que sale con 0 es solo informativa, así que la solicitud `reloadSkills` se sigue aplicando.1273La URL del repositorio es un marcador de posición; reemplázala por tu propio repositorio de skills. Con el marcador de posición, la clonación falla e imprime un mensaje `fatal:` en stderr. La stderr de un hook SessionStart que termina con 0 es solo informativa, así que la solicitud `reloadSkills` se aplica de todos modos.
1275 1274
1276<h4 id="persist-environment-variables">1275<h4 id="persist-environment-variables">
1277 Persistir variables de entorno1276 Persistir variables de entorno
1279 1278
1280Los hooks SessionStart tienen acceso a la variable de entorno `CLAUDE_ENV_FILE`, que proporciona una ruta de archivo donde puedes persistir variables de entorno para los comandos Bash posteriores.1279Los hooks SessionStart tienen acceso a la variable de entorno `CLAUDE_ENV_FILE`, que proporciona una ruta de archivo donde puedes persistir variables de entorno para los comandos Bash posteriores.
1281 1280
1282Para establecer variables de entorno individuales, escribe instrucciones `export` en `CLAUDE_ENV_FILE`. Usa la anexión (`>>`) para conservar las variables establecidas por otros hooks:1281Para establecer variables de entorno individuales, escribe sentencias `export` en `CLAUDE_ENV_FILE`. Usa la adición (`>>`) para conservar las variables establecidas por otros hooks:
1283 1282
1284```bash theme={null}1283```bash theme={null}
1285#!/bin/bash1284#!/bin/bash
1293exit 01292exit 0
1294```1293```
1295 1294
1296Para capturar todos los cambios del entorno de los comandos de configuración, compara las variables exportadas antes y después:1295Para capturar todos los cambios de entorno de los comandos de configuración, compara las variables exportadas antes y después:
1297 1296
1298```bash theme={null}1297```bash theme={null}
1299#!/bin/bash1298#!/bin/bash
1320 Setup1319 Setup
1321</h3>1320</h3>
1322 1321
1323Se dispara solo cuando inicias Claude Code con `--init-only`, o con `--init` o `--maintenance` en [modo no interactivo](/docs/es/headless) con el flag `-p`. No se dispara en un inicio normal. Úsalo para la instalación única de dependencias o para limpiezas programadas que activas explícitamente desde CI o scripts, de forma separada del inicio normal de la sesión. Para la inicialización por sesión, usa [SessionStart](#sessionstart) en su lugar.1322Se activa solo cuando inicias Claude Code con `--init-only`, o con `--init` o `--maintenance` en el [modo no interactivo](/docs/es/headless) con el flag `-p`. No se activa en el inicio normal. Úsalo para la instalación de dependencias de una sola vez o para una limpieza programada que activas explícitamente desde CI o scripts, separada del inicio normal de la sesión. Para la inicialización por sesión, usa [SessionStart](#sessionstart) en su lugar.
1324 1323
1325El valor del matcher corresponde al flag de la CLI que activó el hook:1324El valor del matcher corresponde al flag de la CLI que activó el hook:
1326 1325
1327| Matcher | Cuándo se dispara |1326| Matcher | Cuándo se activa |
1328| :- | :- |1327| :- | :- |
1329| `init` | `claude --init-only` o `claude -p --init` |1328| `init` | `claude --init-only` o `claude -p --init` |
1330| `maintenance` | `claude -p --maintenance` |1329| `maintenance` | `claude -p --maintenance` |
1331 1330
1332Cuando ejecutas `claude --init-only`, Claude Code ejecuta los hooks Setup y los hooks `SessionStart` con el matcher `startup`, y luego sale sin iniciar una conversación.1331Cuando ejecutas `claude --init-only`, Claude Code ejecuta los hooks Setup y los hooks `SessionStart` con el matcher `startup`, y luego sale sin iniciar una conversación.
1333 1332
1334Cuando inicias o continúas una conversación con `-p`, también necesitas proporcionar un prompt, como argumento o mediante una canalización por stdin. Puedes omitir el prompt cuando un hook `SessionStart` proporciona [`initialUserMessage`](#sessionstart-decision-control) o cuando reanudas una sesión con una [llamada a herramienta diferida](#defer-a-tool-call-for-later).1333Cuando inicias o continúas una conversación con `-p`, también necesitas proporcionar un prompt, como argumento o canalizado por stdin. Puedes omitir el prompt cuando un hook `SessionStart` proporciona [`initialUserMessage`](#sessionstart-decision-control) o cuando reanudas una sesión con una [llamada a herramienta diferida](#defer-a-tool-call-for-later).
1335 1334
1336Si tiene éxito, `--init-only` no imprime nada en la terminal. Para confirmar que los hooks se ejecutaron, inicia con `claude --debug-file <path> --init-only`, reemplazando `<path>` por la ubicación de un archivo de log, y revisa el registro en busca de las entradas de los hooks Setup y SessionStart.1335Si tiene éxito, `--init-only` no imprime nada en la terminal. Para confirmar que los hooks se ejecutaron, inicia con `claude --debug-file <path> --init-only`, reemplazando `<path>` por la ubicación de un archivo de log, y revisa el registro en busca de las entradas de los hooks Setup y SessionStart.
1337 1336
1338Como Setup no se dispara en cada inicio, un plugin que necesita una dependencia instalada no puede depender solo de Setup. El patrón práctico es comprobar la dependencia en el primer uso e instalarla si falta, por ejemplo con un hook o skill que compruebe `${CLAUDE_PLUGIN_DATA}/node_modules` y ejecute `npm install` si no existe. Consulta el [directorio de datos persistentes](/docs/es/plugins/components#path-variables-and-persistent-data) para saber dónde almacenar las dependencias instaladas. Si distribuyes tu plugin a través de un marketplace, es posible que no necesites este patrón: Claude Code [instala automáticamente las dependencias de paquetes de Node.js aptas](/docs/es/plugins/loading#node-js-package-dependencies) cuando almacena el plugin en caché.1337Como Setup no se activa en cada inicio, un plugin que necesita instalar una dependencia no puede depender solo de Setup. El patrón práctico es verificar la dependencia en el primer uso e instalarla si falta, por ejemplo con un hook o skill que compruebe `${CLAUDE_PLUGIN_DATA}/node_modules` y ejecute `npm install` si no existe. Consulta el [directorio de datos persistentes](/docs/es/plugins/components#path-variables-and-persistent-data) para saber dónde almacenar las dependencias instaladas. Si distribuyes tu plugin a través de un marketplace, es posible que no necesites este patrón: Claude Code [instala automáticamente las dependencias de paquetes de Node.js elegibles](/docs/es/plugins/loading#node-js-package-dependencies) cuando almacena el plugin en caché.
1339 1338
1340<h4 id="setup-input">1339<h4 id="setup-input">
1341 Entrada de Setup1340 Entrada de Setup
1359 1358
1360Los hooks Setup no pueden bloquear; la ejecución continúa con cualquier código de salida. Con cualquier código de salida, Claude Code descarta los [campos de salida JSON](#json-output) de un hook Setup, como `systemMessage`, `continue` y `hookSpecificOutput.additionalContext`. Con `-p`, la stdout, la stderr y el código de salida de un hook Setup aparecen en la salida de la ejecución solo como [eventos `hook_response`](/docs/es/headless#read-session-metadata) cuando inicias con `--output-format stream-json --verbose`.1359Los hooks Setup no pueden bloquear; la ejecución continúa con cualquier código de salida. Con cualquier código de salida, Claude Code descarta los [campos de salida JSON](#json-output) de un hook Setup, como `systemMessage`, `continue` y `hookSpecificOutput.additionalContext`. Con `-p`, la stdout, la stderr y el código de salida de un hook Setup aparecen en la salida de la ejecución solo como [eventos `hook_response`](/docs/es/headless#read-session-metadata) cuando inicias con `--output-format stream-json --verbose`.
1361 1360
1362Los hooks Setup tienen acceso a `CLAUDE_ENV_FILE`. Las variables escritas en ese archivo persisten en los comandos Bash posteriores de la sesión, como en los [hooks SessionStart](#persist-environment-variables). Solo los hooks `type: "command"` se ejecutan en `Setup`. Un hook `type: "mcp_tool"` en `Setup` siempre se omite, como se describe en [Campos de hooks de herramientas MCP](#mcp-tool-hook-fields).1361Los hooks Setup tienen acceso a `CLAUDE_ENV_FILE`. Las variables escritas en ese archivo persisten en los comandos Bash posteriores de la sesión, como en los [hooks SessionStart](#persist-environment-variables). Solo los hooks `type: "command"` se ejecutan en `Setup`. Un hook `type: "mcp_tool"` en `Setup` siempre se omite, como se describe en [campos de hooks de herramientas MCP](#mcp-tool-hook-fields).
1363 1362
1364<h3 id="instructionsloaded">1363<h3 id="instructionsloaded">
1365 InstructionsLoaded1364 InstructionsLoaded
1366</h3>1365</h3>
1367 1366
1368Se dispara cuando un archivo `CLAUDE.md` o `.claude/rules/*.md` se carga en el contexto. Este evento se dispara al inicio de la sesión para los archivos cargados de forma anticipada y de nuevo más adelante cuando los archivos se cargan de forma diferida, por ejemplo cuando Claude accede a un subdirectorio que contiene un `CLAUDE.md` anidado o cuando coinciden reglas condicionales con frontmatter `paths:`. El hook no admite bloqueo ni control de decisiones. Se ejecuta de forma asíncrona con fines de observabilidad.1367Se activa cuando un archivo `CLAUDE.md` o `.claude/rules/*.md` se carga en el contexto. Este evento se activa al inicio de la sesión para los archivos que se cargan de forma anticipada y otra vez más adelante cuando los archivos se cargan de forma diferida, por ejemplo cuando Claude accede a un subdirectorio que contiene un `CLAUDE.md` anidado o cuando coinciden reglas condicionales con frontmatter `paths:`. El hook no admite bloqueo ni control de decisiones. Se ejecuta de forma asíncrona con fines de observabilidad.
1369 1368
1370Este evento no se dispara cuando Claude [lee `AGENTS.md` directamente](/docs/es/memory#agents-md) mediante el ajuste **Project instructions**. Sí se dispara cuando un `CLAUDE.md` importa tu `AGENTS.md`, con `load_reason` establecido en `include` como para cualquier otro archivo importado, y cuando `CLAUDE.md` es un enlace simbólico a él, como una carga normal de `CLAUDE.md`.1369Este evento no se activa cuando Claude [lee `AGENTS.md` directamente](/docs/es/memory#agents-md) mediante el ajuste **Project instructions**. Sí se activa cuando un `CLAUDE.md` importa tu `AGENTS.md`, con `load_reason` establecido en `include` como para cualquier otro archivo importado, y cuando `CLAUDE.md` es un enlace simbólico a él, como una carga normal de `CLAUDE.md`.
1371 1370
1372El matcher se evalúa contra `load_reason`. Por ejemplo, usa `"matcher": "session_start"` para dispararse solo con los archivos cargados al inicio de la sesión, o `"matcher": "path_glob_match|nested_traversal"` para dispararse solo con las cargas diferidas.1371El matcher se evalúa contra `load_reason`. Por ejemplo, usa `"matcher": "session_start"` para que se active solo con los archivos cargados al inicio de la sesión, o `"matcher": "path_glob_match|nested_traversal"` para que se active solo con cargas diferidas.
1373 1372
1374<h4 id="instructionsloaded-input">1373<h4 id="instructionsloaded-input">
1375 Entrada de InstructionsLoaded1374 Entrada de InstructionsLoaded
1381| :- | :- |1380| :- | :- |
1382| `file_path` | Ruta absoluta al archivo de instrucciones que se cargó |1381| `file_path` | Ruta absoluta al archivo de instrucciones que se cargó |
1383| `memory_type` | Alcance del archivo: `"User"`, `"Project"`, `"Local"` o `"Managed"` |1382| `memory_type` | Alcance del archivo: `"User"`, `"Project"`, `"Local"` o `"Managed"` |
1384| `load_reason` | Por qué se cargó el archivo: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` o `"compact"`. El valor `"compact"` se dispara cuando los archivos de instrucciones se vuelven a cargar después de un evento de compactación |1383| `load_reason` | Por qué se cargó el archivo: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` o `"compact"`. El valor `"compact"` se activa cuando los archivos de instrucciones se vuelven a cargar después de un evento de compactación |
1385| `globs` | Patrones glob de rutas del frontmatter `paths:` del archivo, si los hay. Presente solo en las cargas `path_glob_match` |1384| `globs` | Patrones glob de ruta del frontmatter `paths:` del archivo, si los hay. Presente solo en cargas `path_glob_match` |
1386| `trigger_file_path` | Ruta al archivo cuyo acceso activó esta carga, en las cargas diferidas |1385| `trigger_file_path` | Ruta al archivo cuyo acceso desencadenó esta carga, en cargas diferidas |
1387| `parent_file_path` | Ruta al archivo de instrucciones padre que incluyó este, en las cargas `include` |1386| `parent_file_path` | Ruta al archivo de instrucciones padre que incluyó este, en cargas `include` |
1388 1387
1389```json theme={null}1388```json theme={null}
1390{1389{
1412agregar contexto adicional según el prompt o la conversación, validar prompts o1411agregar contexto adicional según el prompt o la conversación, validar prompts o
1413bloquear ciertos tipos de prompts.1412bloquear ciertos tipos de prompts.
1414 1413
1415Los hooks `UserPromptSubmit` no se disparan solo con los prompts que escribes. Claude Code también los ejecuta cuando:1414Los hooks `UserPromptSubmit` no se activan solo con los prompts que escribes. Claude Code también los ejecuta cuando:
1416 1415
1417* Se dispara una [tarea programada](/docs/es/scheduled-tasks), incluida una iteración de `/loop`1416* Se activa una [tarea programada](/docs/es/scheduled-tasks), incluida una iteración de `/loop`
1418* Un [subagente en segundo plano](/docs/es/sub-agents#run-subagents-in-foreground-or-background) informa a la sesión que lo inició1417* Un [subagente en segundo plano](/docs/es/sub-agents#run-subagents-in-foreground-or-background) informa a la sesión que lo inició
1419* Llega a tu conversación principal un [mensaje que envía otra sesión](/docs/es/cross-session-messaging)1418* Llega a tu conversación principal un [mensaje que envía otra sesión](/docs/es/cross-session-messaging)
1420 1419
1421Los hooks `UserPromptSubmit` tienen un tiempo de espera predeterminado de 30 segundos para los tipos `command`, `http` y `mcp_tool`, más corto que el predeterminado de 600 segundos para esos tipos en la mayoría de los demás eventos. Como este hook se ejecuta antes de cada prompt y bloquea el procesamiento del modelo hasta que termina, un hook atascado detiene la sesión. Si tu hook necesita más tiempo, establece el campo `timeout` en la entrada del hook.1420Los hooks `UserPromptSubmit` tienen un tiempo de espera predeterminado de 30 segundos para los tipos `command`, `http` y `mcp_tool`, más corto que el valor predeterminado de 600 segundos para esos tipos en la mayoría de los demás eventos. Como este hook se ejecuta antes de cada prompt y bloquea el procesamiento del modelo hasta que termina, un hook atascado detiene la sesión. Si tu hook necesita más tiempo, establece el campo `timeout` en la entrada del hook.
1422 1421
1423Salvo un hook de comando que ejecutas con [`async: true`](#run-hooks-in-the-background), un hook de comando, HTTP o de herramienta MCP de `UserPromptSubmit` que agota su tiempo de espera se cancela y su salida, incluido cualquier `additionalContext`, se descarta. El prompt sigue llegando a Claude sin ese contexto. La transcripción muestra un aviso que nombra el hook, el tiempo de espera que se agotó y que la salida se descartó.1422Salvo un hook de comando que ejecutes con [`async: true`](#run-hooks-in-the-background), cuando a un hook de comando, HTTP o de herramienta MCP de `UserPromptSubmit` se le agota el tiempo de espera, se cancela y su salida, incluido cualquier `additionalContext`, se descarta. El prompt llega igualmente a Claude sin ese contexto. La transcripción muestra un aviso con el nombre del hook, el tiempo de espera que se agotó y que la salida se descartó.
1424 1423
1425Un [hook de callback del Agent SDK](/docs/es/agent-sdk/hooks) en `UserPromptSubmit` que agota su tiempo de espera bloquea el prompt con un mensaje que nombra el hook y el tiempo de espera, porque un callback ahí puede actuar como una barrera de políticas que no debe fallar en abierto. La sesión continúa. Antes de la v2.1.208, un tiempo de espera agotado de un callback en ese evento terminaba el turno con un error de ejecución.1424Cuando a un [hook de callback del Agent SDK](/docs/es/agent-sdk/hooks) en `UserPromptSubmit` se le agota el tiempo de espera, bloquea el prompt con un mensaje que nombra el hook y el tiempo de espera, porque un callback ahí puede estar actuando como una barrera de políticas que no debe fallar de forma abierta. La sesión continúa. Antes de la v2.1.208, agotar el tiempo de espera de un callback en ese evento terminaba el turno con un error de ejecución.
1426 1425
1427<h4 id="userpromptsubmit-input">1426<h4 id="userpromptsubmit-input">
1428 Entrada de UserPromptSubmit1427 Entrada de UserPromptSubmit
1429</h4>1428</h4>
1430 1429
1431Además de los [campos de entrada comunes](#common-input-fields), los hooks UserPromptSubmit reciben el campo `prompt` con el texto enviado. El contenido pegado que se contrajo en un marcador de posición `[Pasted text #N]` llega expandido en su lugar. En las sesiones en las que Claude Code [marca el texto pegado para Claude](/docs/es/terminal-config#how-claude-treats-pasted-text), ese contenido expandido se sitúa entre una línea `<pasted_content id="…">` y una línea `</pasted_content id="…">`, así que ten en cuenta esas líneas si tu hook analiza el prompt.1430Además de los [campos de entrada comunes](#common-input-fields), los hooks UserPromptSubmit reciben el campo `prompt` que contiene el texto enviado. El contenido pegado que se contrajo en un marcador `[Pasted text #N]` llega expandido en su lugar. En las sesiones en las que Claude Code [marca el texto pegado para Claude](/docs/es/terminal-config#how-claude-treats-pasted-text), ese contenido expandido se ubica entre una línea `<pasted_content id="…">` y una línea `</pasted_content id="…">`, así que tenlas en cuenta si tu hook analiza el prompt.
1432 1431
1433Los hooks UserPromptSubmit también reciben `session_title` cuando la sesión tiene un título personalizado, con el mismo significado que el [campo `session_title` de SessionStart](#sessionstart-input).1432Los hooks UserPromptSubmit también reciben `session_title` cuando la sesión tiene un título personalizado, con el mismo significado que el [campo `session_title` de SessionStart](#sessionstart-input).
1434 1433
1452Hay dos formas de agregar contexto a la conversación con el código de salida 0:1451Hay dos formas de agregar contexto a la conversación con el código de salida 0:
1453 1452
1454* **Stdout en texto plano**: Claude Code agrega al contexto de Claude la stdout que [trata como texto plano](#exit-code-0)1453* **Stdout en texto plano**: Claude Code agrega al contexto de Claude la stdout que [trata como texto plano](#exit-code-0)
1455* **JSON con `additionalContext`**: usa el formato JSON siguiente para tener más control. El campo `additionalContext` se agrega como contexto1454* **JSON con `additionalContext`**: usa el formato JSON a continuación para tener más control. El campo `additionalContext` se agrega como contexto
1456 1455
1457Ninguno de los dos canales produce una entrada visible en la transcripción. La stdout en texto plano y el valor de `additionalContext` se inyectan cada uno como un recordatorio del sistema que comienza con el nombre del hook; Claude lee ambos. Para confirmar la entrega, revisa el [registro de depuración](#debug-hooks).1456Ninguno de los dos canales produce una entrada visible en la transcripción. La stdout en texto plano y el valor de `additionalContext` se inyectan cada uno como un recordatorio del sistema que comienza con el nombre del hook; Claude lee ambos. Para confirmar la entrega, revisa el [registro de depuración](#debug-hooks).
1458 1457
1464| `reason` | Se muestra al usuario cuando `decision` es `"block"`. No se agrega al contexto |1463| `reason` | Se muestra al usuario cuando `decision` es `"block"`. No se agrega al contexto |
1465| `additionalContext` | Cadena agregada al contexto de Claude junto con el prompt enviado. Consulta [Agregar contexto para Claude](#add-context-for-claude) |1464| `additionalContext` | Cadena agregada al contexto de Claude junto con el prompt enviado. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
1466| `sessionTitle` | Establece el título de la sesión. Úsalo para nombrar sesiones automáticamente según el contenido del prompt |1465| `sessionTitle` | Establece el título de la sesión. Úsalo para nombrar sesiones automáticamente según el contenido del prompt |
1467| `suppressOriginalPrompt` | Si es `true` cuando el hook bloquea el prompt, deja el texto del prompt fuera del mensaje de bloqueo. Consulta [Lo que deja un prompt bloqueado](#what-a-blocked-prompt-leaves-behind) |1466| `suppressOriginalPrompt` | Si es `true` cuando el hook bloquea el prompt, deja el texto del prompt fuera del mensaje de bloqueo. Consulta [Qué deja atrás un prompt bloqueado](#what-a-blocked-prompt-leaves-behind) |
1468 1467
1469Un hook que bloquea saliendo con 2 se encamina igual que `reason`: el mensaje de bloqueo muestra el texto de stderr al usuario y no se agrega al contexto.1468Un hook que bloquea terminando con 2 se enruta igual que `reason`: el mensaje de bloqueo muestra al usuario el texto de stderr, y no se agrega al contexto.
1470 1469
1471```json theme={null}1470```json theme={null}
1472{1471{
1482```1481```
1483 1482
1484<h4 id="what-a-blocked-prompt-leaves-behind">1483<h4 id="what-a-blocked-prompt-leaves-behind">
1485 Lo que deja un prompt bloqueado1484 Qué deja atrás un prompt bloqueado
1486</h4>1485</h4>
1487 1486
1488Un prompt bloqueado nunca llega a Claude, pero su texto no se elimina de todas partes. De forma predeterminada, el mensaje de bloqueo que se muestra al usuario termina con `Original prompt:` seguido del texto enviado, y Claude Code escribe ese mensaje en el archivo de transcripción de la sesión en el disco. Para dejar el texto fuera del mensaje, imprime JSON con `"suppressOriginalPrompt": true` dentro de `hookSpecificOutput`. Esto funciona tanto si el hook bloquea con `decision: "block"` como si termina con 2.1487Un prompt bloqueado nunca llega a Claude, pero su texto no se elimina en todas partes. De forma predeterminada, el mensaje de bloqueo que se muestra al usuario termina con `Original prompt:` seguido del texto enviado, y Claude Code escribe ese mensaje en el archivo de transcripción de la sesión en el disco. Para dejar el texto fuera del mensaje, imprime JSON con `"suppressOriginalPrompt": true` dentro de `hookSpecificOutput`. Esto funciona tanto si el hook bloquea con `decision: "block"` como si lo hace terminando con 2.
1489 1488
1490`suppressOriginalPrompt` solo cambia el mensaje de bloqueo. El texto enviado puede seguir apareciendo en archivos locales, como la transcripción de la sesión y tu historial de prompts, así que un hook de bloqueo no es una forma de mantener un secreto fuera del disco. Para limitar o eliminar esos archivos, consulta [Almacenamiento en texto plano](/docs/es/claude-directory#plaintext-storage) y [Borrar datos locales](/docs/es/claude-directory#clear-local-data).1489`suppressOriginalPrompt` solo cambia el mensaje de bloqueo. El texto enviado puede seguir apareciendo en archivos locales, como la transcripción de la sesión y tu historial de prompts, así que un hook de bloqueo no es una forma de mantener un secreto fuera del disco. Para limitar o eliminar esos archivos, consulta [Almacenamiento en texto plano](/docs/es/claude-directory#plaintext-storage) y [Borrar datos locales](/docs/es/claude-directory#clear-local-data).
1491 1490
1493 UserPromptExpansion1492 UserPromptExpansion
1494</h3>1493</h3>
1495 1494
1496Se ejecuta cuando un comando escrito por el usuario se expande en un prompt antes de llegar a Claude. Úsalo para impedir la invocación directa de comandos específicos, inyectar contexto para un skill en particular o registrar qué comandos invocan los usuarios. Por ejemplo, un hook que coincide con `deploy` puede bloquear `/deploy` a menos que exista un archivo de aprobación, o un hook que coincide con un skill de revisión puede anexar la lista de verificación de revisión del equipo como `additionalContext`.1495Se ejecuta cuando un comando escrito por el usuario se expande en un prompt antes de llegar a Claude. Úsalo para bloquear la invocación directa de comandos específicos, inyectar contexto para un skill en particular o registrar qué comandos invocan los usuarios. Por ejemplo, un hook que coincide con `deploy` puede bloquear `/deploy` a menos que exista un archivo de aprobación, o un hook que coincide con un skill de revisión puede agregar la lista de verificación de revisión del equipo como `additionalContext`.
1497 1496
1498Este evento cubre la ruta que `PreToolUse` no cubre: un hook `PreToolUse` que coincide con la herramienta `Skill` se dispara solo cuando Claude llama a la herramienta, pero escribir `/skillname` directamente evita `PreToolUse`. `UserPromptExpansion` se dispara en esa ruta directa.1497Este evento cubre el camino que `PreToolUse` no cubre: un hook `PreToolUse` que coincide con la herramienta `Skill` se activa solo cuando Claude llama a la herramienta, pero escribir `/skillname` directamente omite `PreToolUse`. `UserPromptExpansion` se activa en ese camino directo.
1499 1498
1500Coincide con `command_name`. Deja el matcher vacío para dispararse con cada comando de tipo prompt.1499Coincide con `command_name`. Deja el matcher vacío para que se active con cada comando de tipo prompt.
1501 1500
1502<h4 id="userpromptexpansion-input">1501<h4 id="userpromptexpansion-input">
1503 Entrada de UserPromptExpansion1502 Entrada de UserPromptExpansion
1532| `reason` | Se muestra al usuario cuando `decision` es `"block"` |1531| `reason` | Se muestra al usuario cuando `decision` es `"block"` |
1533| `additionalContext` | Cadena agregada al contexto de Claude junto con el prompt expandido. Consulta [Agregar contexto para Claude](#add-context-for-claude) |1532| `additionalContext` | Cadena agregada al contexto de Claude junto con el prompt expandido. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
1534 1533
1535Un hook que bloquea saliendo con 2 se encamina igual que `reason`: el mensaje de bloqueo muestra el texto de stderr al usuario.1534Un hook que bloquea terminando con 2 se enruta igual que `reason`: el mensaje de bloqueo muestra al usuario el texto de stderr.
1536 1535
1537```json theme={null}1536```json theme={null}
1538{1537{
1549 MessageDisplay1548 MessageDisplay
1550</h3>1549</h3>
1551 1550
1552Se ejecuta mientras un mensaje del asistente se transmite a la pantalla. Claude Code muestra el mensaje en incrementos: cada vez que un lote de líneas recién completadas está listo para renderizarse, el hook se ejecuta una vez con esas líneas y Claude Code renderiza el texto de reemplazo del hook en su lugar. Un mensaje largo produce varias llamadas; un mensaje corto puede producir solo una.1551Se ejecuta mientras un mensaje del asistente se transmite a la pantalla. Claude Code muestra el mensaje por incrementos: cada vez que un lote de líneas recién completadas está listo para renderizarse, el hook se ejecuta una vez con esas líneas y Claude Code renderiza el texto de reemplazo del hook en su lugar. Un mensaje largo produce varias llamadas; un mensaje corto puede producir solo una.
1553 1552
1554Usa MessageDisplay para:1553Usa MessageDisplay para:
1555 1554
1557* transformar el texto que una aplicación del Agent SDK muestra a sus usuarios1556* transformar el texto que una aplicación del Agent SDK muestra a sus usuarios
1558* ocultar claves de API o nombres de host internos de las respuestas de Claude1557* ocultar claves de API o nombres de host internos de las respuestas de Claude
1559 1558
1560Claude Code retiene cada lote hasta que tu hook devuelve, así que mantén el hook rápido. Si el hook falla o se agota su tiempo de espera, Claude Code muestra el texto original. El tiempo de espera predeterminado de este evento es de 10 segundos; si tu hook necesita más tiempo, establece el campo `timeout` en la entrada del hook.1559Claude Code retiene cada lote hasta que tu hook responde, así que mantén el hook rápido. Si el hook falla o se agota su tiempo de espera, Claude Code muestra el texto original. El tiempo de espera predeterminado para este evento es de 10 segundos; si tu hook necesita más tiempo, establece el campo `timeout` en la entrada del hook.
1561 1560
1562MessageDisplay es solo de visualización: el texto de reemplazo cambia solo lo que se renderiza en pantalla. La transcripción y lo que ve Claude conservan el texto original, así que Claude nunca ve el reemplazo, y el modo detallado muestra el original. El hook recibe solo el texto de los mensajes del asistente, por lo que los resultados de herramientas y el texto que escribes se renderizan sin cambios.1561MessageDisplay es solo de visualización: el texto de reemplazo cambia únicamente lo que se renderiza en la pantalla. La transcripción y lo que ve Claude conservan el texto original, así que Claude nunca ve el reemplazo, y el modo detallado muestra el original. El hook recibe solo el texto de los mensajes del asistente, así que los resultados de herramientas y el texto que escribes se renderizan sin cambios.
1563 1562
1564MessageDisplay no admite matchers y se dispara con cada mensaje del asistente que transmite texto; los mensajes sin texto, como las respuestas que solo contienen llamadas a herramientas, no lo activan.1563MessageDisplay no admite matchers y se activa con cada mensaje del asistente que transmite texto; los mensajes sin texto, como las respuestas que solo contienen llamadas a herramientas, no lo activan.
1565 1564
1566En las ejecuciones no interactivas, incluidas las consultas del Agent SDK y `claude -p`, MessageDisplay se ejecuta una vez por mensaje del asistente en lugar de una vez por lote de líneas. La única llamada llega después de que el mensaje se completa y lleva el texto completo del mensaje: `index` es `0`, `final` es `true` y `delta` contiene el mensaje entero. Un hook que recopila el texto de `delta` de cada mensaje recibe el mismo texto total en ambos modos.1565En las ejecuciones no interactivas, incluidas las consultas del Agent SDK y `claude -p`, MessageDisplay se ejecuta una vez por mensaje del asistente en lugar de una vez por lote de líneas. La única llamada llega después de que el mensaje termina y contiene el texto completo del mensaje: `index` es `0`, `final` es `true` y `delta` contiene el mensaje entero. Un hook que recopila el texto `delta` de cada mensaje recibe el mismo texto total en ambos modos.
1567 1566
1568<h4 id="messagedisplay-input">1567<h4 id="messagedisplay-input">
1569 Entrada de MessageDisplay1568 Entrada de MessageDisplay
1570</h4>1569</h4>
1571 1570
1572Además de los [campos de entrada comunes](#common-input-fields), los hooks MessageDisplay reciben identificadores del turno y del mensaje, la posición de esta llamada dentro del mensaje y el texto nuevo en `delta`. Los límites de los lotes dependen de cómo se transmite el texto, así que usa `index` y `final` para seguir el progreso a lo largo de un mensaje en lugar de esperar que las líneas se agrupen de una forma particular.1571Además de los [campos de entrada comunes](#common-input-fields), los hooks MessageDisplay reciben identificadores del turno y del mensaje, la posición de esta llamada dentro del mensaje y el texto nuevo en `delta`. Los límites de los lotes dependen de cómo se transmite el texto, así que usa `index` y `final` para seguir el avance a través de un mensaje en lugar de esperar que las líneas se agrupen de una manera determinada.
1573 1572
1574| Campo | Descripción |1573| Campo | Descripción |
1575| :- | :- |1574| :- | :- |
1576| `turn_id` | UUID del turno actual |1575| `turn_id` | UUID del turno actual |
1577| `message_id` | UUID del mensaje del asistente que se está mostrando. Es estable en todos los lotes del mismo mensaje. No es el id `msg_…` de la API, así que no se puede correlacionar con los ids de los mensajes de la transcripción |1576| `message_id` | UUID del mensaje del asistente que se está mostrando. Se mantiene estable en todos los lotes del mismo mensaje. No es el id `msg_…` de la API, así que no se puede correlacionar con los ids de mensajes de la transcripción |
1578| `index` | Índice, con base cero, de este lote dentro del mensaje |1577| `index` | Índice, empezando en cero, de este lote dentro del mensaje |
1579| `final` | `true` en el último lote del mensaje. Cada mensaje tiene exactamente un lote final |1578| `final` | `true` en el último lote del mensaje. Cada mensaje tiene exactamente un lote final |
1580| `delta` | Las líneas recién completadas desde el lote anterior, incluidos los saltos de línea finales. Siempre son líneas completas, excepto el lote final, que puede terminar a mitad de línea. En las ejecuciones interactivas, el delta del lote final está vacío cuando el mensaje termina en un salto de línea, así que trata `final`, y no un delta no vacío, como la señal de fin de mensaje. En las ejecuciones del Agent SDK y de `claude -p`, la única llamada lleva el mensaje completo |1579| `delta` | Las líneas recién completadas desde el lote anterior, incluidos los saltos de línea finales. Siempre son líneas completas, excepto el lote final, que puede terminar a mitad de línea. En las ejecuciones interactivas, el delta del lote final está vacío cuando el mensaje termina en un salto de línea, así que trata `final`, y no un delta no vacío, como la señal de fin de mensaje. En las ejecuciones del Agent SDK y de `claude -p`, la única llamada contiene el mensaje entero |
1581 1580
1582```json theme={null}1581```json theme={null}
1583{1582{
1597 Salida de MessageDisplay1596 Salida de MessageDisplay
1598</h4>1597</h4>
1599 1598
1600Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, los hooks MessageDisplay pueden devolver `displayContent` para reemplazar el delta en pantalla:1599Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, los hooks MessageDisplay pueden devolver `displayContent` para reemplazar el delta en la pantalla:
1601 1600
1602| Campo | Descripción |1601| Campo | Descripción |
1603| :- | :- |1602| :- | :- |
1605 1604
1606Los hooks MessageDisplay no tienen control de decisiones. No pueden bloquear el mensaje ni cambiar lo que se almacena en la transcripción o se envía a Claude. Claude Code actúa sobre `displayContent` de su salida JSON y descarta `systemMessage` y `continue`.1605Los hooks MessageDisplay no tienen control de decisiones. No pueden bloquear el mensaje ni cambiar lo que se almacena en la transcripción o se envía a Claude. Claude Code actúa sobre `displayContent` de su salida JSON y descarta `systemMessage` y `continue`.
1607 1606
1608Este ejemplo quita el formato markdown de las respuestas de Claude para una visualización en texto plano. El script lee cada lote desde stdin, elimina los marcadores de negrita y las comillas invertidas del código en línea de `delta`, y devuelve el resultado como `displayContent`.1607Este ejemplo quita el formato markdown de las respuestas de Claude para una visualización en texto plano. El script lee cada lote desde stdin, elimina los marcadores de negrita y las comillas invertidas de código en línea de `delta`, y devuelve el resultado como `displayContent`.
1609 1608
1610<Tabs>1609<Tabs>
1611 <Tab title="macOS/Linux">1610 <Tab title="macOS/Linux">
1664 }1663 }
1665 ```1664 ```
1666 1665
1667 El flag `-NoProfile` omite la carga de tu perfil de PowerShell para que el hook arranque rápido, y `-ExecutionPolicy Bypass` permite que PowerShell ejecute el archivo de script local.1666 El flag `-NoProfile` omite la carga de tu perfil de PowerShell para que el hook inicie rápido, y `-ExecutionPolicy Bypass` permite que PowerShell ejecute el archivo de script local.
1668 1667
1669 Guarda este script en `.claude/hooks/plain-display.ps1` en tu proyecto:1668 Guarda este script en `.claude/hooks/plain-display.ps1` en tu proyecto:
1670 1669
1681 </Tab>1680 </Tab>
1682</Tabs>1681</Tabs>
1683 1682
1684Los lotes sin markdown pasan sin cambios. Si el script falla, por ejemplo porque falta `jq`, Claude Code muestra el texto original y anota el fallo solo en la [salida de depuración](#debug-hooks), no en la sesión.1683Los lotes sin markdown pasan sin cambios. Si el script falla, por ejemplo porque falta `jq`, Claude Code muestra el texto original y registra el fallo solo en la [salida de depuración](#debug-hooks), no en la sesión.
1685 1684
1686<h3 id="pretooluse">1685<h3 id="pretooluse">
1687 PreToolUse1686 PreToolUse
1689 1688
1690Se ejecuta después de que Claude crea los parámetros de la herramienta y antes de procesar la llamada a herramienta. Coincide con cualquier nombre de herramienta excepto `EndConversation`: herramientas integradas como `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion` y `ExitPlanMode`, y cualquier [nombre de herramienta MCP](#match-mcp-tools).1689Se ejecuta después de que Claude crea los parámetros de la herramienta y antes de procesar la llamada a herramienta. Coincide con cualquier nombre de herramienta excepto `EndConversation`: herramientas integradas como `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion` y `ExitPlanMode`, y cualquier [nombre de herramienta MCP](#match-mcp-tools).
1691 1690
1692Para ejecutar un hook cuando un archivo específico cambia en disco, sin importar qué lo escribió, usa [FileChanged](#filechanged) en lugar de hacer coincidir por nombre las herramientas de edición de archivos. A diferencia de PreToolUse, Claude Code ejecuta los hooks FileChanged después del cambio, y no tienen control de decisiones, así que no pueden bloquear la escritura.1691Para ejecutar un hook cuando un archivo específico cambia en el disco, sin importar qué lo escribió, usa [FileChanged](#filechanged) en lugar de hacer coincidir por nombre las herramientas de edición de archivos. A diferencia de PreToolUse, Claude Code ejecuta los hooks FileChanged después del cambio, y no tienen control de decisiones, así que no pueden bloquear la escritura.
1693 1692
1694<Warning>1693<Warning>
1695 PreToolUse solo se ejecuta cuando Claude llama a una herramienta. Los archivos que [referencias con `@` en tu prompt](/docs/es/common-workflows#reference-files-and-directories) se agregan sin ninguna llamada a herramienta: Claude Code inserta su contenido mientras construye el prompt, así que no se dispara ningún hook PreToolUse para ellos, incluidos los hooks que coinciden con `Read`. Para bloquear rutas específicas de las referencias con `@`, usa una [regla de denegación de `Read`](/docs/es/permissions#read-and-edit) en su lugar.1694 PreToolUse solo se ejecuta cuando Claude llama a una herramienta. Los archivos que [referencias con `@` en tu prompt](/docs/es/common-workflows#reference-files-and-directories) se agregan sin ninguna llamada a herramienta: Claude Code inserta su contenido mientras construye el prompt, así que no se activa ningún hook PreToolUse para ellos, incluidos los hooks que coinciden con `Read`. Para bloquear rutas específicas en las referencias con `@`, usa una [regla de denegación de `Read`](/docs/es/permissions#read-and-edit) en su lugar.
1696 1695
1697 PreToolUse tampoco se dispara para [`EndConversation`](/docs/es/tools-reference#endconversation-tool-behavior).1696 PreToolUse tampoco se activa para [`EndConversation`](/docs/es/tools-reference#endconversation-tool-behavior).
1698</Warning>1697</Warning>
1699 1698
1700Usa el [control de decisiones de PreToolUse](#pretooluse-decision-control) para permitir, denegar, preguntar o diferir la llamada a herramienta.1699Usa el [control de decisiones de PreToolUse](#pretooluse-decision-control) para permitir, denegar, preguntar o diferir la llamada a herramienta.
1707 1706
1708Además de los [campos de entrada comunes](#common-input-fields), los hooks PreToolUse reciben `tool_name`, `tool_input` y `tool_use_id`.1707Además de los [campos de entrada comunes](#common-input-fields), los hooks PreToolUse reciben `tool_name`, `tool_input` y `tool_use_id`.
1709 1708
1710Para una [herramienta MCP](#match-mcp-tools), la entrada también lleva `mcp_server`, un objeto con el `name` del servidor y un `source` que indica de dónde proviene la definición del servidor. Los valores de `source` incluyen `plugin`, `sdk` y alcances de configuración como `user` y `project`. [`McpServerProvenance`](/docs/es/agent-sdk/typescript#mcpserverprovenance) en la referencia del Agent SDK los enumera todos e indica cómo tratar uno que no reconozcas. Basa las decisiones de confianza en `source` en lugar de en `name` o en el prefijo de nombre de herramienta `mcp__<server>__`. El campo `mcp_server` requiere Claude Code v2.1.274 o posterior.1709Para una [herramienta MCP](#match-mcp-tools), la entrada también incluye `mcp_server`, un objeto con el `name` del servidor y un `source` que indica de dónde proviene la definición del servidor. Los valores de `source` incluyen `plugin`, `sdk` y alcances de configuración como `user` y `project`. [`McpServerProvenance`](/docs/es/agent-sdk/typescript#mcpserverprovenance) en la referencia del Agent SDK los enumera todos e indica cómo tratar uno que no reconozcas. Basa las decisiones de confianza en `source` en lugar de en `name` o en el prefijo de nombre de herramienta `mcp__<server>__`. El campo `mcp_server` requiere Claude Code v2.1.274 o posterior.
1711 1710
1712Para las herramientas de archivos `Write`, `Edit` y `Read`, `tool_input.file_path` siempre es absoluta:1711Para las herramientas de archivos `Write`, `Edit` y `Read`, `tool_input.file_path` siempre es absoluta:
1713 1712
1714* Claude Code expande `~` y las rutas relativas antes de que se ejecuten los hooks, así que un hook que coincide con rutas no se puede eludir mediante `~` o una forma relativa de escribir la misma ruta1713* Claude Code expande `~` y las rutas relativas antes de que se ejecuten los hooks, así que un hook que hace coincidir rutas no se puede eludir mediante `~` o una forma relativa de escribir la misma ruta
1715* En Windows, la ruta llega con separadores de barra invertida, incluso cuando tu hook se ejecuta en Git Bash, donde `$PWD` se ve como `/c/project`1714* En Windows, la ruta llega con separadores de barra invertida, incluso cuando tu hook se ejecuta en Git Bash, donde `$PWD` se ve como `/c/project`
1716* Una comparación escrita con barras diagonales, como una comprobación de `/src/`, nunca coincide con una ruta con barras invertidas, y la llamada a herramienta continúa como si el hook no tuviera nada que bloquear1715* Una comparación escrita con barras normales, como una comprobación de `/src/`, nunca coincide con una ruta con barras invertidas, y la llamada a herramienta continúa como si el hook no tuviera nada que bloquear
1717* Normaliza los separadores antes de comparar: `FILE_PATH="${FILE_PATH//\\//}"` en Bash, o `file_path.replace("\\", "/")` en Python, y luego haz coincidir un segmento de ruta como `/src/` en lugar de anclar con `^`, ya que la ruta es absoluta1716* Normaliza los separadores antes de comparar: `FILE_PATH="${FILE_PATH//\\//}"` en Bash, o `file_path.replace("\\", "/")` en Python, y luego haz coincidir un segmento de ruta como `/src/` en lugar de anclar con `^`, ya que la ruta es absoluta
1718 1717
1719Una llamada a `Write` en Windows entrega:1718Una llamada a `Write` en Windows entrega:
1738 Bash1737 Bash
1739</h5>1738</h5>
1740 1739
1741Ejecuta comandos del shell.1740Ejecuta comandos de shell.
1742 1741
1743| Campo | Tipo | Ejemplo | Descripción |1742| Campo | Tipo | Ejemplo | Descripción |
1744| :- | :- | :- | :- |1743| :- | :- | :- | :- |
1745| `command` | string | `"npm test"` | El comando del shell que se ejecutará |1744| `command` | string | `"npm test"` | El comando de shell que se ejecutará |
1746| `description` | string | `"Run test suite"` | Descripción opcional de lo que hace el comando |1745| `description` | string | `"Run test suite"` | Descripción opcional de lo que hace el comando |
1747| `timeout` | number | `120000` | Tiempo de espera opcional en milisegundos. Los valores por encima del [máximo](/docs/es/tools-reference#bash-tool-behavior) se reducen al máximo en lugar de rechazarse |1746| `timeout` | number | `120000` | Tiempo de espera opcional en milisegundos. Los valores por encima del [máximo](/docs/es/tools-reference#bash-tool-behavior) se reducen al máximo en lugar de rechazarse |
1748| `run_in_background` | boolean | `false` | Si el comando se ejecuta en segundo plano |1747| `run_in_background` | boolean | `false` | Si se ejecuta el comando en segundo plano |
1749 1748
1750Cuando un comando Bash cambia archivos en un repositorio Git, Claude Code puede registrar lo que cambió. Registra los cambios en todos los modos de permisos cuando el ajuste [`bashEditDiffEnabled`](/docs/es/settings-reference#basheditdiffenabled) activa el registro; la entrada de ese ajuste indica qué archivos pueden establecerlo. De lo contrario, solo los registra en modo automático y en modo `bypassPermissions`, y solo cuando Claude Code indica a Claude que edite archivos mediante Bash. Establece `bashEditDiffEnabled` en `false` para desactivar el registro. Los comandos en segundo plano y los comandos de solo lectura no llevan diff.1749Cuando un comando Bash cambia archivos en un repositorio de Git, Claude Code puede registrar lo que cambió. Registra los cambios en todos los modos de permisos cuando el ajuste [`bashEditDiffEnabled`](/docs/es/settings-reference#basheditdiffenabled) activa el registro; la entrada de ese ajuste indica qué archivos pueden establecerlo. De lo contrario, solo los registra en el modo automático y en el modo `bypassPermissions`, y solo cuando Claude Code indica a Claude que edite archivos mediante Bash. Establece `bashEditDiffEnabled` en `false` para desactivar el registro. Los comandos en segundo plano y los comandos de solo lectura no incluyen diff.
1751 1750
1752Tu [hook PostToolUse](#posttooluse) recibe entonces los archivos modificados en `tool_response.bashEditDiff`. La lista cubre lo que cambió dentro del repositorio mientras se ejecutaba el comando. Los archivos que Git ignora y los archivos de los submódulos no se incluyen. Requiere Claude Code v2.1.269 o posterior.1751Luego, tu [hook PostToolUse](#posttooluse) recibe los archivos cambiados en `tool_response.bashEditDiff`. La lista cubre lo que cambió dentro del repositorio mientras se ejecutaba el comando. Los archivos que Git ignora y los archivos en submódulos no se incluyen. Requiere Claude Code v2.1.269 o posterior.
1753 1752
1754<Note>1753<Note>
1755 La lista es de mejor esfuerzo y está en beta pública. Claude Code puede pasar por alto un cambio, incluir un archivo que otro proceso cambió al mismo tiempo o detenerse en sus límites de tamaño. La forma del campo puede cambiar. Usa la lista para encontrar qué revisar, no para aplicar una política.1754 La lista se genera en la medida de lo posible y está en beta pública. Claude Code puede pasar por alto un cambio, incluir un archivo que otro proceso cambió al mismo tiempo o detenerse al alcanzar sus límites de tamaño. La forma del campo puede cambiar. Usa la lista para encontrar qué revisar, no para hacer cumplir una política.
1756</Note>1755</Note>
1757 1756
1758`changedFiles` y `files` enumeran lo que cambió el comando; los campos restantes indican qué tan completa y qué tan fiable es esa lista.1757`changedFiles` y `files` enumeran lo que cambió el comando; los demás campos indican qué tan completa y qué tan confiable es esa lista.
1759 1758
1760| Campo | Tipo | Ejemplo | Descripción |1759| Campo | Tipo | Ejemplo | Descripción |
1761| :- | :- | :- | :- |1760| :- | :- | :- | :- |
1762| `changedFiles` | array | `["/path/to/src/app.ts"]` | Rutas absolutas de los archivos que cambió el comando, como máximo 200. Presente siempre que `files` contenga un diff o `moreFiles` sea mayor que cero |1761| `changedFiles` | array | `["/path/to/src/app.ts"]` | Rutas absolutas de los archivos que cambió el comando, como máximo 200. Presente siempre que `files` contenga un diff o `moreFiles` sea mayor que cero |
1763| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diffs de hasta 5 archivos modificados, para mostrar. `created` o `deleted` es `true` para un archivo que el comando agregó o eliminó |1762| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diffs de hasta 5 archivos cambiados, para mostrar. `created` o `deleted` es `true` para un archivo que el comando agregó o eliminó |
1764| `moreFiles` | number | `2` | Cantidad de archivos modificados sin diff en `files` |1763| `moreFiles` | number | `2` | Cantidad de archivos cambiados sin diff en `files` |
1765| `unavailable` | boolean | `true` | Se establece cuando el diff está incompleto o no se pudo obtener |1764| `unavailable` | boolean | `true` | Se establece cuando el diff está incompleto o no se pudo obtener |
1766| `skipped` | boolean | `true` | Se establece para un comando de Git que mueve el árbol de trabajo, como `git checkout` o `git stash`, de modo que Claude Code no obtiene ningún diff |1765| `skipped` | boolean | `true` | Se establece para un comando de Git que mueve el árbol de trabajo, como `git checkout` o `git stash`, de modo que Claude Code no obtiene ningún diff |
1767| `shared` | boolean | `true` | Se establece cuando otra llamada a la herramienta Bash, como la de un subagente, se ejecutó en el mismo repositorio al mismo tiempo, por lo que algunos cambios enumerados pueden ser de ese comando |1766| `shared` | boolean | `true` | Se establece cuando otra llamada a la herramienta Bash, como la de un subagente, se ejecutó en el mismo repositorio al mismo tiempo, de modo que algunos cambios enumerados pueden ser de ese comando |
1768 1767
1769<a id="powershell" />1768<a id="powershell" />
1770 1769
1781| `command` | string | `"Get-ChildItem -Recurse"` | El comando de PowerShell que se ejecutará |1780| `command` | string | `"Get-ChildItem -Recurse"` | El comando de PowerShell que se ejecutará |
1782| `description` | string | `"List files recursively"` | Descripción opcional de lo que hace el comando |1781| `description` | string | `"List files recursively"` | Descripción opcional de lo que hace el comando |
1783| `timeout` | number | `120000` | Tiempo de espera opcional en milisegundos |1782| `timeout` | number | `120000` | Tiempo de espera opcional en milisegundos |
1784| `run_in_background` | boolean | `false` | Si el comando se ejecuta en segundo plano |1783| `run_in_background` | boolean | `false` | Si se ejecuta el comando en segundo plano |
1785 1784
1786Haz coincidir `Bash|PowerShell` en los hooks que inspeccionan comandos del shell, para que cubran ambas herramientas:1785Usa `Bash|PowerShell` como matcher en los hooks que inspeccionan comandos de shell, para que cubran ambas herramientas:
1787 1786
1788* En Windows, dondequiera que la herramienta PowerShell esté habilitada, Claude trata PowerShell como el shell principal y encamina los comandos del shell a través de él.1787* En Windows, dondequiera que la herramienta PowerShell esté habilitada, Claude trata PowerShell como el shell principal y enruta los comandos de shell a través de él.
1789* En Windows sin Git Bash, la herramienta se habilita automáticamente y Claude Code no registra la herramienta Bash en absoluto.1788* En Windows sin Git Bash, la herramienta se habilita automáticamente y Claude Code no registra la herramienta Bash en absoluto.
1790* Un hook que solo coincide con `Bash` nunca se dispara ahí.1789* Un hook que coincide solo con `Bash` nunca se activa ahí.
1791 1790
1792<h5 id="write">1791<h5 id="write">
1793 Write1792 Write
1822| Campo | Tipo | Ejemplo | Descripción |1821| Campo | Tipo | Ejemplo | Descripción |
1823| :- | :- | :- | :- |1822| :- | :- | :- | :- |
1824| `file_path` | string | `"/path/to/file.txt"` | Ruta absoluta al archivo que se leerá |1823| `file_path` | string | `"/path/to/file.txt"` | Ruta absoluta al archivo que se leerá |
1825| `offset` | number | `10` | Número de línea opcional desde el que empezar a leer |1824| `offset` | number | `10` | Número de línea opcional desde el que se empieza a leer |
1826| `limit` | number | `50` | Número opcional de líneas que se leerán |1825| `limit` | number | `50` | Número opcional de líneas que se leerán |
1827 1826
1828<h5 id="glob">1827<h5 id="glob">
1829 Glob1828 Glob
1830</h5>1829</h5>
1831 1830
1832Busca archivos que coinciden con un patrón glob.1831Encuentra archivos que coinciden con un patrón glob.
1833 1832
1834| Campo | Tipo | Ejemplo | Descripción |1833| Campo | Tipo | Ejemplo | Descripción |
1835| :- | :- | :- | :- |1834| :- | :- | :- | :- |
1836| `pattern` | string | `"**/*.ts"` | Patrón glob con el que comparar los archivos |1835| `pattern` | string | `"**/*.ts"` | Patrón glob con el que se compararán los archivos |
1837| `path` | string | `"/path/to/dir"` | Directorio opcional en el que buscar. De forma predeterminada, el directorio de trabajo actual |1836| `path` | string | `"/path/to/dir"` | Directorio opcional en el que buscar. De forma predeterminada es el directorio de trabajo actual |
1838 1837
1839<h5 id="grep">1838<h5 id="grep">
1840 Grep1839 Grep
1847| `pattern` | string | `"TODO.*fix"` | Patrón de expresión regular que se buscará |1846| `pattern` | string | `"TODO.*fix"` | Patrón de expresión regular que se buscará |
1848| `path` | string | `"/path/to/dir"` | Archivo o directorio opcional en el que buscar |1847| `path` | string | `"/path/to/dir"` | Archivo o directorio opcional en el que buscar |
1849| `glob` | string | `"*.ts"` | Patrón glob opcional para filtrar archivos |1848| `glob` | string | `"*.ts"` | Patrón glob opcional para filtrar archivos |
1850| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"` o `"count"`. De forma predeterminada, `"files_with_matches"` |1849| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"` o `"count"`. De forma predeterminada es `"files_with_matches"` |
1851| `-i` | boolean | `true` | Búsqueda sin distinguir mayúsculas de minúsculas |1850| `-i` | boolean | `true` | Búsqueda sin distinguir mayúsculas de minúsculas |
1852| `multiline` | boolean | `false` | Habilita la coincidencia multilínea |1851| `multiline` | boolean | `false` | Habilita la coincidencia multilínea |
1853 1852
1859 1858
1860| Campo | Tipo | Ejemplo | Descripción |1859| Campo | Tipo | Ejemplo | Descripción |
1861| :- | :- | :- | :- |1860| :- | :- | :- | :- |
1862| `url` | string | `"https://example.com/api"` | URL de la que obtener el contenido |1861| `url` | string | `"https://example.com/api"` | URL de la que se obtendrá el contenido |
1863| `prompt` | string | `"Extract the API endpoints"` | Prompt que se ejecutará sobre el contenido obtenido |1862| `prompt` | string | `"Extract the API endpoints"` | Prompt que se ejecutará sobre el contenido obtenido |
1864 1863
1865<h5 id="websearch">1864<h5 id="websearch">
1878 Agent1877 Agent
1879</h5>1878</h5>
1880 1879
1881Genera un [subagente](/docs/es/sub-agents).1880Inicia un [subagente](/docs/es/sub-agents).
1882 1881
1883| Campo | Tipo | Ejemplo | Descripción |1882| Campo | Tipo | Ejemplo | Descripción |
1884| :- | :- | :- | :- |1883| :- | :- | :- | :- |
1887| `subagent_type` | string | `"Explore"` | Tipo de agente especializado que se usará |1886| `subagent_type` | string | `"Explore"` | Tipo de agente especializado que se usará |
1888| `model` | string | `"sonnet"` | Alias de modelo opcional para sobrescribir el predeterminado |1887| `model` | string | `"sonnet"` | Alias de modelo opcional para sobrescribir el predeterminado |
1889 1888
1890Cuando una llamada a Agent en primer plano termina, tu [hook PostToolUse](#posttooluse) recibe el resultado del subagente y la telemetría de la ejecución en `tool_response`. Lee estos campos para inspeccionar la ejecución; para totales de tokens y costos entre subagentes, usa los [contadores de tokens y costos](/docs/es/monitoring-usage#token-counter) filtrados por `query_source` `"subagent"`, ya que `totalTokens` y `usage` cubren solo la solicitud final:1889Cuando una llamada a Agent en primer plano termina, tu [hook PostToolUse](#posttooluse) recibe el resultado del subagente y la telemetría de la ejecución en `tool_response`. Lee estos campos para inspeccionar la ejecución; para los totales de tokens y costos de todos los subagentes, usa los [contadores de tokens y costos](/docs/es/monitoring-usage#token-counter) filtrados por `query_source` `"subagent"`, ya que `totalTokens` y `usage` cubren solo la solicitud final:
1891 1890
1892| Campo | Tipo | Ejemplo | Descripción |1891| Campo | Tipo | Ejemplo | Descripción |
1893| :- | :- | :- | :- |1892| :- | :- | :- | :- |
1894| `status` | string | `"completed"` | `"completed"` para subagentes en primer plano, `"async_launched"` para subagentes en segundo plano. Los subagentes se ejecutan en segundo plano de forma predeterminada, así que una llamada a Agent que omite `run_in_background` también produce `"async_launched"` |1893| `status` | string | `"completed"` | `"completed"` para subagentes en primer plano, `"async_launched"` para subagentes en segundo plano. Los subagentes se ejecutan en segundo plano de forma predeterminada, así que una llamada a Agent que omite `run_in_background` también produce `"async_launched"` |
1895| `agentId` | string | `"a4d2c8f1e0b3a297"` | Identificador de la ejecución del subagente |1894| `agentId` | string | `"a4d2c8f1e0b3a297"` | Identificador de la ejecución del subagente |
1896| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Los bloques de texto finales del subagente o, para un subagente cuyo informe pasa por `SubagentHandback`, una nota breve sobre esa entrega en su lugar |1895| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Los bloques de texto finales del subagente o, en el caso de un subagente cuyo informe pasa por `SubagentHandback`, una nota breve sobre esa entrega en su lugar |
1897| `resolvedModel` | string | `"claude-sonnet-4-5"` | Modelo con el que empezó el subagente, que puede diferir del modelo solicitado |1896| `resolvedModel` | string | `"claude-sonnet-4-5"` | Modelo con el que empezó el subagente, que puede ser distinto del modelo solicitado |
1898| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | Modelos usados en orden, con las repeticiones consecutivas contraídas; se establece solo cuando el modelo se cambió a mitad de la ejecución. Requiere Claude Code v2.1.212 o posterior |1897| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | Modelos usados en orden, con las repeticiones consecutivas contraídas; se establece solo cuando el modelo se cambió a mitad de la ejecución. Requiere Claude Code v2.1.212 o posterior |
1899| `totalTokens` | number | `12450` | Cantidad de tokens de la solicitud final a la API del subagente: tokens de entrada, de salida y de caché combinados. No es un total de toda la ejecución |1898| `totalTokens` | number | `12450` | Cantidad de tokens de la solicitud final a la API del subagente: tokens de entrada, de salida y de caché combinados. No es un total de toda la ejecución |
1900| `totalDurationMs` | number | `48211` | Duración en tiempo real de la ejecución del subagente |1899| `totalDurationMs` | number | `48211` | Duración en tiempo real de la ejecución del subagente |
1901| `totalToolUseCount` | number | `7` | Cantidad de llamadas a herramientas que hizo el subagente |1900| `totalToolUseCount` | number | `7` | Cantidad de llamadas a herramientas que hizo el subagente |
1902| `usage` | object | `{"input_tokens": 8320, ...}` | Desglose de tokens por tipo de la solicitud final a la API: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |1901| `usage` | object | `{"input_tokens": 8320, ...}` | Desglose de tokens por tipo de la solicitud final a la API: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |
1903 1902
1904En Claude Code v2.1.271 o posterior, un subagente que se ejecuta con la herramienta [`SubagentHandback`](/docs/es/tools-reference), que Claude Code proporciona en [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode), entrega su informe mediante esa herramienta en lugar de devolverlo como texto. El campo `content` de su resultado `completed` lleva entonces una nota breve sobre esa entrega en lugar del informe en sí. Para leer el informe, haz coincidir un hook `PreToolUse` o `PostToolUse` con `SubagentHandback` y lee `tool_input.message`.1903En Claude Code v2.1.271 o posterior, un subagente que se ejecuta con la herramienta [`SubagentHandback`](/docs/es/tools-reference), que Claude Code proporciona en el [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode), entrega su informe mediante esa herramienta en lugar de devolverlo como texto. El campo `content` de su resultado `completed` contiene entonces una nota breve sobre esa entrega en lugar del informe mismo. Para leer el informe, haz coincidir un hook `PreToolUse` o `PostToolUse` con `SubagentHandback` y lee `tool_input.message`.
1905 1904
1906Para los subagentes en segundo plano, la herramienta devuelve cuando la tarea pasa a segundo plano, así que `tool_response` no lleva campos de uso: un inicio en segundo plano devuelve de inmediato, y una tarea en primer plano que Claude Code pasa a segundo plano a mitad de la ejecución devuelve en esa transición. Tiene `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` y `resolvedModel`.1905Para los subagentes en segundo plano, la herramienta responde cuando la tarea pasa a segundo plano, así que `tool_response` no incluye campos de uso: un inicio en segundo plano responde de inmediato, y una tarea en primer plano que Claude Code pasa a segundo plano a mitad de la ejecución responde en esa transición. Contiene `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` y `resolvedModel`.
1907 1906
1908En una respuesta `completed`, `resolvedModel` nombra el modelo con el que empezó el subagente, que puede diferir del valor de `model` en `tool_input`, por ejemplo cuando se aplica `availableModels` u otra sobrescritura. En una respuesta `async_launched`, `resolvedModel` nombra el modelo en uso cuando el agente pasó a segundo plano, de modo que un cambio ocurrido antes de pasar a segundo plano se refleja ahí. `modelsUsed` y el comportamiento de `resolvedModel` en el momento de pasar a segundo plano requieren Claude Code v2.1.212 o posterior.1907En una respuesta `completed`, `resolvedModel` nombra el modelo con el que empezó el subagente, que puede ser distinto del valor `model` en `tool_input`, por ejemplo cuando se aplica `availableModels` u otra sobrescritura. En una respuesta `async_launched`, `resolvedModel` nombra el modelo en uso cuando el agente pasó a segundo plano, así que un cambio que ocurrió antes de pasar a segundo plano se refleja ahí. `modelsUsed` y el comportamiento de `resolvedModel` en el momento de pasar a segundo plano requieren Claude Code v2.1.212 o posterior.
1909 1908
1910<a id="askuserquestion" />1909<a id="askuserquestion" />
1911 1910
1918| Campo | Tipo | Ejemplo | Descripción |1917| Campo | Tipo | Ejemplo | Descripción |
1919| :- | :- | :- | :- |1918| :- | :- | :- | :- |
1920| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | Preguntas que se presentarán, cada una con una cadena `question`, un `header` breve, un array `options` y un flag `multiSelect` opcional |1919| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | Preguntas que se presentarán, cada una con una cadena `question`, un `header` breve, un array `options` y un flag `multiSelect` opcional |
1921| `answers` | object | `{"Which framework?": "React"}` | Opcional. Asigna el texto de la pregunta a la etiqueta de la opción seleccionada. Las respuestas de selección múltiple unen las etiquetas con comas. Claude no establece este campo; proporciónalo mediante `updatedInput` para responder de forma programática |1920| `answers` | object | `{"Which framework?": "React"}` | Opcional. Asigna el texto de la pregunta a la etiqueta de la opción seleccionada. Las respuestas de selección múltiple unen las etiquetas con comas. Claude no establece este campo; proporciónalo mediante `updatedInput` para responder mediante programación |
1922 1921
1923<h5 id="exitplanmode">1922<h5 id="exitplanmode">
1924 ExitPlanMode1923 ExitPlanMode
1925</h5>1924</h5>
1926 1925
1927Presenta un plan y pide al usuario que lo apruebe antes de que Claude salga del [modo plan](/docs/es/permission-modes#analyze-before-you-edit-with-plan-mode). Claude escribe el plan en un archivo en disco antes de llamar a la herramienta, así que el `tool_input` literal del modelo suele estar vacío. Claude Code inyecta el contenido del plan y la ruta del archivo antes de pasar la entrada a los hooks.1926Presenta un plan y pide al usuario que lo apruebe antes de que Claude salga del [modo plan](/docs/es/permission-modes#analyze-before-you-edit-with-plan-mode). Claude escribe el plan en un archivo en el disco antes de llamar a la herramienta, así que el `tool_input` literal del modelo suele estar vacío. Claude Code inyecta el contenido del plan y la ruta del archivo antes de pasar la entrada a los hooks.
1928 1927
1929| Campo | Tipo | Ejemplo | Descripción |1928| Campo | Tipo | Ejemplo | Descripción |
1930| :- | :- | :- | :- |1929| :- | :- | :- | :- |
1931| `plan` | string | `"## Refactor auth\n1. Extract..."` | Contenido del plan en Markdown. Se inyecta desde el archivo del plan en disco |1930| `plan` | string | `"## Refactor auth\n1. Extract..."` | Contenido del plan en Markdown. Se inyecta desde el archivo del plan en el disco |
1932| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Ruta al archivo del plan. Se inyecta |1931| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Ruta al archivo del plan. Se inyecta |
1933| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Obsoleto. Claude Code acepta el campo pero lo ignora. Antes de la v2.1.205, llevaba los permisos basados en prompts que Claude solicitaba para implementar el plan |1932| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Obsoleto. Claude Code acepta el campo pero lo ignora. Antes de la v2.1.205, contenía los permisos basados en prompts que Claude solicitaba para implementar el plan |
1934 1933
1935En `PostToolUse`, `tool_response` es un objeto con los campos `plan` y `filePath`, que contienen el plan aprobado, además de flags de estado internos. Lee `tool_response.plan` para obtener el contenido del plan en lugar de volver a leer el archivo desde el disco.1934En `PostToolUse`, `tool_response` es un objeto con los campos `plan` y `filePath` que contienen el plan aprobado, además de flags de estado internos. Lee `tool_response.plan` para obtener el contenido del plan en lugar de volver a leer el archivo del disco.
1936 1935
1937<h4 id="pretooluse-decision-control">1936<h4 id="pretooluse-decision-control">
1938 Control de decisiones de PreToolUse1937 Control de decisiones de PreToolUse
1939</h4>1938</h4>
1940 1939
1941Los hooks `PreToolUse` pueden controlar si una llamada a herramienta continúa. 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 un control más rico: cuatro resultados (permitir, denegar, preguntar o diferir) además de la capacidad de modificar la entrada de la herramienta antes de la ejecución.1940Los hooks `PreToolUse` pueden controlar si una llamada a herramienta continúa. 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 un control más completo: cuatro resultados (permitir, denegar, preguntar o diferir) más la capacidad de modificar la entrada de la herramienta antes de la ejecución.
1942 1941
1943| Campo | Descripción |1942| Campo | Descripción |
1944| :- | :- |1943| :- | :- |
1945| `permissionDecision` | `"allow"` omite la solicitud de permiso, excepto para las [acciones que ningún modo aprueba automáticamente](/docs/es/permission-modes#actions-no-mode-auto-approves) y para `AskUserQuestion` y `ExitPlanMode`, que necesitan [`updatedInput` emparejado con él](#allow-with-updatedinput). `"deny"` impide la llamada a herramienta. `"ask"` pide al usuario que confirme. `"defer"` sale de forma controlada para que la herramienta pueda reanudarse más tarde. Las [reglas de denegación y de pregunta](/docs/es/permissions#manage-permissions) se siguen evaluando independientemente de lo que devuelva el hook |1944| `permissionDecision` | `"allow"` omite la solicitud de permiso, excepto para las [acciones que ningún modo aprueba automáticamente](/docs/es/permission-modes#actions-no-mode-auto-approves) y para `AskUserQuestion` y `ExitPlanMode`, que necesitan [`updatedInput` junto con él](#allow-with-updatedinput). `"deny"` impide la llamada a herramienta. `"ask"` pide al usuario que confirme. `"defer"` sale de forma ordenada para que la herramienta pueda reanudarse más tarde. Las [reglas de denegación y de pregunta](/docs/es/permissions#manage-permissions) se siguen evaluando sin importar lo que devuelva el hook |
1946| `permissionDecisionReason` | Para `"ask"`, se muestra al usuario en la solicitud de permiso. Cuando Claude Code [deniega la llamada](/docs/es/headless#turn-off-permission-prompts-in-unattended-runs) en una ejecución `-p` en la que nadie puede responder a esa solicitud, Claude lee el motivo en el resultado de la herramienta. Para `"deny"`, se muestra a Claude. Para `"allow"` y `"defer"`, se escribe solo en el [registro de depuración](#debug-hooks) |1945| `permissionDecisionReason` | Para `"ask"`, se muestra al usuario en la solicitud de permiso. Cuando Claude Code [deniega la llamada](/docs/es/headless#turn-off-permission-prompts-in-unattended-runs) en una ejecución con `-p` en la que nadie puede responder esa solicitud, Claude lee el motivo en el resultado de la herramienta. Para `"deny"`, se muestra a Claude. Para `"allow"` y `"defer"`, solo se escribe en el [registro de depuración](#debug-hooks) |
1947| `updatedInput` | Modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza todo el objeto de entrada, así que incluye los campos sin cambios junto con los modificados. Claude Code evalúa las reglas de permisos y la [aptitud para pasar automáticamente a segundo plano](/docs/es/tools-reference#foreground-commands-that-move-to-the-background) de un comando Bash contra la entrada que devuelve tu hook, no contra la entrada que envió Claude. Combínalo con `"allow"` para aprobar automáticamente, o con `"ask"` para mostrar la entrada modificada al usuario. Para `"defer"`, se ignora |1946| `updatedInput` | Modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza todo el objeto de entrada, así que incluye los campos sin cambios junto con los modificados. Claude Code evalúa las reglas de permisos y la [elegibilidad para pasar automáticamente a segundo plano](/docs/es/tools-reference#foreground-commands-that-move-to-the-background) de un comando Bash contra la entrada que devuelve tu hook, no contra la entrada que envió Claude. Combínalo con `"allow"` para aprobar automáticamente, o con `"ask"` para mostrar al usuario la entrada modificada. Para `"defer"`, se ignora |
1948| `additionalContext` | Cadena agregada al contexto de Claude junto con el resultado de la herramienta. Se ignora cuando `permissionDecision` es `"defer"`. Consulta [Agregar contexto para Claude](#add-context-for-claude) |1947| `additionalContext` | Cadena agregada al contexto de Claude junto con el resultado de la herramienta. Se ignora cuando `permissionDecision` es `"defer"`. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
1949 1948
1950Cuando varios hooks PreToolUse devuelven decisiones diferentes, la precedencia es `deny` > `defer` > `ask` > `allow`.1949Cuando varios hooks PreToolUse devuelven decisiones diferentes, la precedencia es `deny` > `defer` > `ask` > `allow`.
1951 1950
1952Un hook que bloquea saliendo con 2 se encamina igual que `"deny"`: Claude ve el mensaje de stderr como el motivo de la denegación.1951Un hook que bloquea terminando con 2 se enruta igual que `"deny"`: Claude ve el mensaje de stderr como el motivo de la denegación.
1953 1952
1954Cuando un hook devuelve `"ask"`, la solicitud de permiso que se muestra al usuario incluye una etiqueta que identifica de dónde proviene el hook: `[settings]` para un hook de cualquier archivo de configuración o del frontmatter de un agente, `[plugin:<name>]` para el hook de un plugin, o `[skill]` para un hook del frontmatter de un skill. Esto ayuda a los usuarios a entender qué fuente de configuración está solicitando la confirmación.1953Cuando un hook devuelve `"ask"`, la solicitud de permiso que se muestra al usuario incluye una etiqueta que identifica de dónde proviene el hook: `[settings]` para un hook de cualquier archivo de configuración o del frontmatter de un agente, `[plugin:<name>]` para el hook de un plugin, o `[skill]` para un hook del frontmatter de un skill. Esto ayuda a los usuarios a entender qué fuente de configuración está pidiendo confirmación.
1955 1954
1956El `"ask"` de un hook también fuerza una solicitud de permiso en [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode): el clasificador todavía puede denegar la llamada a herramienta, pero no puede aprobarla en silencio. Antes de la v2.1.211, el clasificador podía aprobar un comando Bash que se ejecutaba fuera del [sandbox](/docs/es/sandboxing) sin mostrar la solicitud que pedía el hook; el clasificador seguía aplicando sus propias reglas de seguridad a ese comando, y un `"deny"` de un hook siempre se respetaba.1955Un `"ask"` de un hook también fuerza una solicitud de permiso en el [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode): el clasificador puede seguir denegando la llamada a herramienta, pero no puede aprobarla de forma silenciosa. Antes de la v2.1.211, el clasificador podía aprobar un comando Bash que se ejecutaba fuera del [sandbox](/docs/es/sandboxing) sin mostrar la solicitud que pedía el hook; el clasificador seguía aplicando sus propias reglas de seguridad a ese comando, y un `"deny"` de un hook siempre se respetaba.
1957 1956
1958```json theme={null}1957```json theme={null}
1959{1958{
1970```1969```
1971 1970
1972<Note>1971<Note>
1973 PreToolUse usaba anteriormente los campos de nivel superior `decision` y `reason`, pero están obsoletos para este evento. Usa `hookSpecificOutput.permissionDecision` y `hookSpecificOutput.permissionDecisionReason` en su lugar. Los valores obsoletos `"approve"` y `"block"` se asignan a `"allow"` y `"deny"` respectivamente. Otros eventos como PostToolUse y Stop siguen usando `decision` y `reason` de nivel superior como su formato actual.1972 PreToolUse usaba anteriormente los campos `decision` y `reason` de nivel superior, pero están obsoletos para este evento. Usa `hookSpecificOutput.permissionDecision` y `hookSpecificOutput.permissionDecisionReason` en su lugar. Los valores obsoletos `"approve"` y `"block"` se asignan a `"allow"` y `"deny"` respectivamente. Otros eventos como PostToolUse y Stop siguen usando `decision` y `reason` de nivel superior como su formato actual.
1974</Note>1973</Note>
1975 1974
1976<h4 id="allow-with-updatedinput">1975<h4 id="allow-with-updatedinput">
1977 Herramientas que requieren interacción del usuario1976 Herramientas que requieren interacción del usuario
1978</h4>1977</h4>
1979 1978
1980`AskUserQuestion` y `ExitPlanMode` requieren interacción del usuario. En [modo no interactivo](/docs/es/headless) con el flag `-p`, Claude Code solo las ofrece cuando la ejecución tiene un [host de permisos](/docs/es/headless#turn-off-permission-prompts-in-unattended-runs) que reciba la solicitud, como un callback `canUseTool` del Agent SDK.1979`AskUserQuestion` y `ExitPlanMode` requieren interacción del usuario. En el [modo no interactivo](/docs/es/headless) con el flag `-p`, Claude Code las ofrece solo cuando la ejecución tiene un [host de permisos](/docs/es/headless#turn-off-permission-prompts-in-unattended-runs) que reciba la solicitud, como un callback `canUseTool` del Agent SDK.
1981 1980
1982Un hook `PreToolUse` satisface ese requisito cuando hace lo siguiente:1981Un hook `PreToolUse` cumple ese requisito cuando hace lo siguiente:
1983 1982
19841. Lee la entrada de la herramienta desde stdin19831. Lee la entrada de la herramienta desde stdin
19852. Recopila la respuesta mediante tu propia interfaz de usuario19842. Recopila la respuesta mediante tu propia interfaz de usuario
2009}2008}
2010```2009```
2011 2010
2012Una herramienta MCP cuyo servidor la marca con [`_meta["anthropic/requiresUserInteraction"]`](/docs/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.2011Una herramienta MCP cuyo servidor la marca con [`_meta["anthropic/requiresUserInteraction"]`](/docs/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 necesita la herramienta.
2013 2012
2014<h4 id="defer-a-tool-call-for-later">2013<h4 id="defer-a-tool-call-for-later">
2015 Diferir una llamada a herramienta para más tarde2014 Diferir una llamada a herramienta para más tarde
2016</h4>2015</h4>
2017 2016
2018`"defer"` está pensado para integraciones que ejecutan `claude -p` como subproceso y leen su salida JSON, como una aplicación del Agent SDK o una interfaz personalizada construida sobre Claude Code. Permite que ese proceso que llama pause a Claude en una llamada a herramienta, recopile la entrada mediante su propia interfaz y reanude donde lo dejó. Claude Code respeta este valor solo en [modo no interactivo](/docs/es/headless) con el flag `-p`. En las sesiones interactivas, registra una advertencia e ignora el resultado del hook.2017`"defer"` está pensado para integraciones que ejecutan `claude -p` como subproceso y leen su salida JSON, como una aplicación del Agent SDK o una interfaz de usuario personalizada construida sobre Claude Code. Permite que ese proceso que hace la llamada pause a Claude en una llamada a herramienta, recopile entrada mediante su propia interfaz y reanude donde se quedó. Claude Code respeta este valor solo en el [modo no interactivo](/docs/es/headless) con el flag `-p`. En las sesiones interactivas, registra una advertencia e ignora el resultado del hook.
2019 2018
2020La herramienta `AskUserQuestion` es el caso típico: Claude quiere preguntarle algo al usuario, pero no hay ninguna terminal en la que responder. Una ejecución `-p` ofrece `AskUserQuestion` solo cuando tiene un [host de permisos](/docs/es/headless#turn-off-permission-prompts-in-unattended-runs), como una herramienta MCP que pasas con `--permission-prompt-tool`, así que inicia la ejecución con uno. El recorrido completo funciona así:2019La herramienta `AskUserQuestion` es el caso típico: Claude quiere preguntarle algo al usuario, pero no hay una terminal en la que responder. Una ejecución con `-p` ofrece `AskUserQuestion` solo cuando tiene un [host de permisos](/docs/es/headless#turn-off-permission-prompts-in-unattended-runs), como una herramienta MCP que pasas con `--permission-prompt-tool`, así que inicia la ejecución con uno. El ciclo completo funciona así:
2021 2020
20221. Claude llama a `AskUserQuestion`. Se dispara el hook `PreToolUse`.20211. Claude llama a `AskUserQuestion`. Se activa el hook `PreToolUse`.
20232. El hook devuelve `permissionDecision: "defer"`. La herramienta no se ejecuta. El proceso sale con `stop_reason: "tool_deferred"` y la llamada a herramienta pendiente queda conservada en la transcripción.20222. El hook devuelve `permissionDecision: "defer"`. La herramienta no se ejecuta. El proceso sale con `stop_reason: "tool_deferred"` y la llamada a herramienta pendiente se conserva en la transcripción.
20243. El proceso que llama lee `deferred_tool_use` del resultado del SDK, muestra la pregunta en su propia interfaz y espera una respuesta.20233. El proceso que hace la llamada lee `deferred_tool_use` del resultado del SDK, muestra la pregunta en su propia interfaz de usuario y espera una respuesta.
20254. El proceso que llama ejecuta `claude -p --resume <session-id>` con el mismo host de permisos. La misma llamada a herramienta vuelve a disparar `PreToolUse`.20244. El proceso que hace la llamada ejecuta `claude -p --resume <session-id>` con el mismo host de permisos. La misma llamada a herramienta vuelve a activar `PreToolUse`.
20265. El hook devuelve `permissionDecision: "allow"` con la respuesta en `updatedInput`. La herramienta se ejecuta y Claude continúa.20255. El hook devuelve `permissionDecision: "allow"` con la respuesta en `updatedInput`. La herramienta se ejecuta y Claude continúa.
2027 2026
2028El campo `deferred_tool_use` lleva el `id`, el `name` y el `input` de la herramienta. El `input` son los parámetros que Claude generó para la llamada a herramienta, capturados antes de la ejecución:2027El campo `deferred_tool_use` contiene el `id`, el `name` y el `input` de la herramienta. El `input` son los parámetros que Claude generó para la llamada a herramienta, capturados antes de la ejecución:
2029 2028
2030```json theme={null}2029```json theme={null}
2031{2030{
2041}2040}
2042```2041```
2043 2042
2044No hay tiempo de espera ni límite de reintentos. La sesión permanece en disco hasta que la reanudas, sujeta a la limpieza de retención de [`cleanupPeriodDays`](/docs/es/settings-reference#cleanupperioddays), que elimina los archivos de sesión después de 30 días de forma predeterminada, según las [reglas de limpieza de retención](/docs/es/claude-directory#cleaned-up-automatically). Si la respuesta no está lista cuando reanudas, el hook puede devolver `"defer"` de nuevo y el proceso sale de la misma forma. El proceso que llama controla cuándo romper el bucle devolviendo finalmente `"allow"` o `"deny"` desde el hook.2043No hay tiempo de espera ni límite de reintentos. La sesión permanece en el disco hasta que la reanudes, sujeta a la limpieza por retención de [`cleanupPeriodDays`](/docs/es/settings-reference#cleanupperioddays), que elimina los archivos de sesión después de 30 días de forma predeterminada, según las [reglas de limpieza por retención](/docs/es/claude-directory#cleaned-up-automatically). Si la respuesta no está lista cuando reanudas, el hook puede volver a devolver `"defer"` y el proceso sale de la misma manera. El proceso que hace la llamada controla cuándo romper el ciclo devolviendo finalmente `"allow"` o `"deny"` desde el hook.
2045 2044
2046`"defer"` solo funciona cuando Claude hace una única llamada a herramienta en el turno. Si Claude hace varias llamadas a herramientas a la vez, `"defer"` se ignora con una advertencia y la herramienta continúa por el flujo de permisos normal. La restricción existe porque la reanudación solo puede volver a ejecutar una herramienta: no hay forma de diferir una llamada de un lote sin dejar las demás sin resolver.2045`"defer"` solo funciona cuando Claude hace una sola llamada a herramienta en el turno. Si Claude hace varias llamadas a herramientas a la vez, `"defer"` se ignora con una advertencia y la herramienta continúa por el flujo de permisos normal. La restricción existe porque la reanudación solo puede volver a ejecutar una herramienta: no hay forma de diferir una llamada de un lote sin dejar las demás sin resolver.
2047 2046
2048Si la herramienta diferida ya no está disponible cuando reanudas, el proceso sale con `stop_reason: "tool_deferred_unavailable"` e `is_error: true` antes de que se dispare el hook. Esto ocurre cuando un servidor MCP que proporcionaba la herramienta no está conectado en la sesión reanudada. El payload `deferred_tool_use` se sigue incluyendo para que puedas identificar qué herramienta desapareció.2047Si la herramienta diferida ya no está disponible cuando reanudas, el proceso sale con `stop_reason: "tool_deferred_unavailable"` e `is_error: true` antes de que se active el hook. Esto ocurre cuando un servidor MCP que proporcionaba la herramienta no está conectado en la sesión reanudada. El payload `deferred_tool_use` se incluye de todos modos para que puedas identificar qué herramienta falta.
2049 2048
2050<Note>2049<Note>
2051 Para reanudar una sesión diferida en modo plan, pasa [`--permission-prompt-tool`](/docs/es/cli-reference#cli-flags) junto con `--resume` para que Claude Code pueda presentar el plan para su aprobación. Si pasas ciertos otros flags de inicio, la ejecución reanudada no vuelve al modo plan; consulta [Reanudar en modo plan con `-p`](/docs/es/sessions#resume-in-plan-mode-with-p). Requiere Claude Code v2.1.246 o posterior.2050 Para reanudar una sesión diferida en modo plan, pasa [`--permission-prompt-tool`](/docs/es/cli-reference#cli-flags) junto con `--resume` para que Claude Code pueda presentar el plan para su aprobación. Si pasas ciertos otros flags de inicio, la ejecución reanudada no vuelve al modo plan; consulta [Reanudar en modo plan con `-p`](/docs/es/sessions#resume-in-plan-mode-with-p). Requiere Claude Code v2.1.246 o posterior.
2052 2051
2053 Cuando reanudas con `-p`, Claude Code no restaura ningún otro modo de permisos almacenado. Inicia la ejecución en el modo de permisos en el que se iniciaría una nueva ejecución `claude -p`, así que vuelve a pasar `--permission-mode` o `--dangerously-skip-permissions` si la sesión diferida usaba alguno. Cuando reanudas con `claude --resume <session-id>` sin `-p`, Claude Code restaura el modo de permisos almacenado, con las excepciones enumeradas en [modo de permisos al reanudar](/docs/es/sessions#permission-mode-on-resume).2052 Cuando reanudas con `-p`, Claude Code no restaura ningún otro modo de permisos almacenado. Inicia la ejecución en el modo de permisos en el que empezaría una nueva ejecución de `claude -p`, así que vuelve a pasar `--permission-mode` o `--dangerously-skip-permissions` si la sesión diferida usaba alguno. Cuando reanudas con `claude --resume <session-id>` sin `-p`, Claude Code restaura el modo de permisos almacenado, con las excepciones enumeradas en [modo de permisos al reanudar](/docs/es/sessions#permission-mode-on-resume).
2054</Note>2053</Note>
2055 2054
2056<h3 id="permissionrequest">2055<h3 id="permissionrequest">
2057 PermissionRequest2056 PermissionRequest
2058</h3>2057</h3>
2059 2058
2060Se ejecuta cuando Claude Code está a punto de pedirte permiso para usar una herramienta. En las sesiones que no pueden mostrar una solicitud, como los subagentes en segundo plano en [modo no interactivo](/docs/es/headless), Claude Code sigue ejecutando estos hooks y, si ningún hook devuelve una decisión, deniega la llamada a herramienta. Para una llamada que llega a un `--permission-prompt-tool` o al [callback `canUseTool`](/docs/es/agent-sdk/permissions) del Agent SDK, los hooks se ejecutan junto con tu host, y se aplica la decisión del que decida primero.2059Se ejecuta cuando Claude Code está a punto de pedirte permiso para usar una herramienta. En las sesiones que no pueden mostrar una solicitud, como los subagentes en segundo plano en el [modo no interactivo](/docs/es/headless), Claude Code sigue ejecutando estos hooks y, si ningún hook devuelve una decisión, deniega la llamada a herramienta. En una llamada que llega a un `--permission-prompt-tool` o al [callback `canUseTool`](/docs/es/agent-sdk/permissions) del Agent SDK, los hooks se ejecutan junto con tu host, y se aplica el que decida primero.
2061Usa el [control de decisiones de PermissionRequest](#permissionrequest-decision-control) para permitir o denegar en nombre del usuario.2060Usa el [control de decisiones de PermissionRequest](#permissionrequest-decision-control) para permitir o denegar en nombre del usuario.
2062 2061
2063Usa este evento cuando necesites una señal en el momento en que Claude pide permiso para usar una herramienta. Claude Code ejecuta un hook [Notification](#notification) con el tipo `permission_prompt` solo después de que la solicitud ha esperado unos seis segundos.2062Usa este evento cuando necesites una señal en el momento en que Claude pide permiso para usar una herramienta. Claude Code ejecuta un hook [Notification](#notification) con el tipo `permission_prompt` solo después de que la solicitud lleva esperando unos seis segundos.
2064 2063
2065Claude Code no ejecuta hooks PermissionRequest para la [solicitud de red](/docs/es/sandboxing#network-isolation) de un comando en el sandbox. Para obtener una señal de esa solicitud, usa el tipo de notificación `permission_prompt`.2064Claude Code no ejecuta hooks PermissionRequest para la [solicitud de red](/docs/es/sandboxing#network-isolation) de un comando en el sandbox. Para obtener una señal de esa solicitud de permiso, usa el tipo de notificación `permission_prompt`.
2066 2065
2067Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.2066Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.
2068 2067
2072 2071
2073Los hooks PermissionRequest reciben los campos `tool_name` y `tool_input` como los hooks PreToolUse, pero sin `tool_use_id`. Para una herramienta MCP, también reciben el objeto [`mcp_server`](#pretooluse-input). Un array opcional `permission_suggestions` contiene las [actualizaciones de permisos](#permission-update-entries) que Claude Code sugiere para esta solicitud, como agregar una regla de permiso o cambiar el modo de permisos.2072Los hooks PermissionRequest reciben los campos `tool_name` y `tool_input` como los hooks PreToolUse, pero sin `tool_use_id`. Para una herramienta MCP, también reciben el objeto [`mcp_server`](#pretooluse-input). Un array opcional `permission_suggestions` contiene las [actualizaciones de permisos](#permission-update-entries) que Claude Code sugiere para esta solicitud, como agregar una regla de permiso o cambiar el modo de permisos.
2074 2073
2075El array `permission_suggestions` no es una lista exacta de las opciones que ves, porque cada diálogo de permisos construye sus propias opciones. Algunos diálogos, como el de las ediciones de archivos, no leen el array en absoluto y derivan sus opciones de la propia solicitud. Un diálogo que sí lo lee puede seguir ocultando una opción cuya sugerencia permanece en el array, por ejemplo cuando [`allowManagedPermissionRulesOnly`](/docs/es/settings-reference#allowmanagedpermissionrulesonly) oculta las opciones para guardar reglas. También puede ofrecer opciones que no tienen ninguna entrada de sugerencia, como [**Yes, and switch to auto mode**](/docs/es/permission-modes#switch-permission-modes), que cambia el modo de permisos directamente en lugar de hacerlo mediante una actualización de permisos.2074El array `permission_suggestions` no es una lista exacta de las opciones que ves, porque cada cuadro de diálogo de permisos construye sus propias opciones. Algunos cuadros de diálogo, como el de las ediciones de archivos, no leen el array en absoluto y derivan sus opciones de la propia solicitud. Un cuadro de diálogo que sí lo lee puede aun así ocultar una opción cuya sugerencia permanece en el array, por ejemplo cuando [`allowManagedPermissionRulesOnly`](/docs/es/settings-reference#allowmanagedpermissionrulesonly) oculta las opciones para guardar reglas. También puede ofrecer opciones que no tienen una entrada de sugerencia, como [**Yes, and switch to auto mode**](/docs/es/permission-modes#switch-permission-modes), que cambia el modo de permisos directamente en lugar de hacerlo mediante una actualización de permisos.
2076 2075
2077Los hooks PreToolUse se ejecutan antes de cada llamada a herramienta, necesite o no permiso. Los hooks PermissionRequest se ejecutan solo cuando Claude Code está a punto de pedirte permiso, o cuando de otro modo denegaría automáticamente una llamada que no puede mostrar una solicitud. Ninguno de los dos eventos se dispara para [`EndConversation`](/docs/es/tools-reference#endconversation-tool-behavior).2076Los hooks PreToolUse se ejecutan antes de cada llamada a herramienta, necesite permiso o no. Los hooks PermissionRequest se ejecutan solo cuando Claude Code está a punto de pedirte permiso, o cuando de otro modo denegaría automáticamente una llamada que no puede mostrar una solicitud. Ninguno de los dos eventos se activa para [`EndConversation`](/docs/es/tools-reference#endconversation-tool-behavior).
2078 2077
2079```json theme={null}2078```json theme={null}
2080{2079{
2110| `behavior` | `"allow"` concede el permiso, `"deny"` lo deniega. Las [reglas de denegación y de pregunta](/docs/es/permissions#manage-permissions) se siguen evaluando, así que un hook que devuelve `"allow"` no sobrescribe una regla de denegación que coincida |2109| `behavior` | `"allow"` concede el permiso, `"deny"` lo deniega. Las [reglas de denegación y de pregunta](/docs/es/permissions#manage-permissions) se siguen evaluando, así que un hook que devuelve `"allow"` no sobrescribe una regla de denegación que coincida |
2111| `updatedInput` | Solo para `"allow"`: modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza todo el objeto de entrada, así que incluye los campos sin cambios junto con los modificados. La entrada modificada se vuelve a evaluar contra las reglas de denegación y de pregunta |2110| `updatedInput` | Solo para `"allow"`: modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza todo el objeto de entrada, así que incluye los campos sin cambios junto con los modificados. La entrada modificada se vuelve a evaluar contra las reglas de denegación y de pregunta |
2112| `updatedPermissions` | Solo para `"allow"`: array de [entradas de actualización de permisos](#permission-update-entries) que se aplicarán, como agregar una regla de permiso o cambiar el modo de permisos de la sesión |2111| `updatedPermissions` | Solo para `"allow"`: array de [entradas de actualización de permisos](#permission-update-entries) que se aplicarán, como agregar una regla de permiso o cambiar el modo de permisos de la sesión |
2113| `message` | Solo para `"deny"`: le dice a Claude por qué se denegó el permiso |2112| `message` | Solo para `"deny"`: le indica a Claude por qué se denegó el permiso |
2114| `interrupt` | Solo para `"deny"`: si es `true`, detiene a Claude |2113| `interrupt` | Solo para `"deny"`: si es `true`, detiene a Claude |
2115 2114
2116Un hook que sale con 2 sin un objeto `decision` deja el flujo de permisos sin cambios, y su stderr se descarta. Solo el objeto `decision` puede conceder o denegar la solicitud.2115Un hook que termina con 2 sin un objeto `decision` deja el flujo de permisos sin cambios, y su stderr se descarta. Solo el objeto `decision` puede conceder o denegar la solicitud.
2117 2116
2118```json theme={null}2117```json theme={null}
2119{2118{
2133 Entradas de actualización de permisos2132 Entradas de actualización de permisos
2134</h4>2133</h4>
2135 2134
2136El campo de salida `updatedPermissions` y el [campo de entrada `permission_suggestions`](#permissionrequest-input) usan el mismo array de objetos de entrada. Cada entrada tiene un `type` que determina sus demás campos, y un `destination` que controla dónde se escribe el cambio.2135El campo de salida `updatedPermissions` y el [campo de entrada `permission_suggestions`](#permissionrequest-input) usan el mismo array de objetos de entrada. Cada entrada tiene un `type` que determina sus demás campos y un `destination` que controla dónde se escribe el cambio.
2137 2136
2138| `type` | Campos | Efecto |2137| `type` | Campos | Efecto |
2139| :- | :- | :- |2138| :- | :- | :- |
2140| `addRules` | `rules`, `behavior`, `destination` | Agrega reglas de permisos. `rules` es un array de objetos `{toolName, ruleContent?}`. Omite `ruleContent` para coincidir con toda la herramienta. `behavior` es `"allow"`, `"deny"` o `"ask"` |2139| `addRules` | `rules`, `behavior`, `destination` | Agrega reglas de permisos. `rules` es un array de objetos `{toolName, ruleContent?}`. Omite `ruleContent` para que coincida con toda la herramienta. `behavior` es `"allow"`, `"deny"` o `"ask"` |
2141| `replaceRules` | `rules`, `behavior`, `destination` | Reemplaza todas las reglas del `behavior` indicado en el `destination` con las `rules` proporcionadas |2140| `replaceRules` | `rules`, `behavior`, `destination` | Reemplaza todas las reglas del `behavior` indicado en el `destination` con las `rules` proporcionadas |
2142| `removeRules` | `rules`, `behavior`, `destination` | Elimina las reglas que coinciden del `behavior` indicado |2141| `removeRules` | `rules`, `behavior`, `destination` | Elimina las reglas coincidentes del `behavior` indicado |
2143| `setMode` | `mode`, `destination` | Cambia el modo de permisos. Los modos válidos son `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan` y `manual` como alias de `default` |2142| `setMode` | `mode`, `destination` | Cambia el modo de permisos. Los modos válidos son `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan` y `manual` como alias de `default` |
2144| `addDirectories` | `directories`, `destination` | Agrega directorios de trabajo. `directories` es un array de cadenas de rutas |2143| `addDirectories` | `directories`, `destination` | Agrega directorios de trabajo. `directories` es un array de cadenas de rutas |
2145| `removeDirectories` | `directories`, `destination` | Elimina directorios de trabajo |2144| `removeDirectories` | `directories`, `destination` | Elimina directorios de trabajo |
2146 2145
2147<Note>2146<Note>
2148 `setMode` con `bypassPermissions` solo surte efecto si iniciaste la sesión con el modo bypass ya disponible: `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions` o `permissions.defaultMode: "bypassPermissions"` en la [configuración de usuario, de `--settings` o administrada](/docs/es/settings-reference#permissions-defaultmode). De lo contrario, la actualización no tiene efecto. La actualización tampoco tiene efecto cuando [`permissions.disableBypassPermissionsMode`](/docs/es/permissions#managed-settings) deshabilita el modo, o cuando la sesión se inicia en [modo restringido](/docs/es/cli-reference#cli-flags).2147 `setMode` con `bypassPermissions` solo tiene efecto si iniciaste la sesión con el modo bypass ya disponible: `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions` o `permissions.defaultMode: "bypassPermissions"` en [la configuración de usuario, `--settings` o la configuración administrada](/docs/es/settings-reference#permissions-defaultmode). De lo contrario, la actualización no tiene efecto. La actualización tampoco tiene efecto cuando [`permissions.disableBypassPermissionsMode`](/docs/es/permissions#managed-settings) desactiva el modo, o cuando la sesión se inicia en [modo restringido](/docs/es/cli-reference#cli-flags).
2149 2148
2150 `bypassPermissions` nunca se persiste como `defaultMode`, independientemente de `destination`.2149 `bypassPermissions` nunca se guarda como `defaultMode`, independientemente de `destination`.
2151</Note>2150</Note>
2152 2151
2153El campo `destination` de cada entrada determina si el cambio permanece en memoria o se persiste en un archivo de configuración.2152El campo `destination` de cada entrada determina si el cambio se queda en memoria o se guarda en un archivo de configuración.
2154 2153
2155| `destination` | Escribe en |2154| `destination` | Escribe en |
2156| :- | :- |2155| :- | :- |
2167 2166
2168Se ejecuta inmediatamente después de que una herramienta se completa correctamente.2167Se ejecuta inmediatamente después de que una herramienta se completa correctamente.
2169 2168
2170Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.2169Hace coincidencia por nombre de herramienta, con los mismos valores que PreToolUse.
2171 2170
2172Usa una coincidencia más amplia cuando el nombre de la herramienta no sea el filtro adecuado:2171Haz coincidencias más amplias cuando el nombre de la herramienta no sea el filtro adecuado:
2173 2172
2174* Para ejecutar un hook después de que cualquier herramienta se complete correctamente, omite el `matcher` o establécelo en `"*"`. Tu hook puede entonces descubrir por sí mismo qué cambió, por ejemplo ejecutando `git status --porcelain`, que también lista los archivos sin seguimiento que `git diff` no muestra. Para las llamadas a herramientas que fallan, agrega el mismo hook en [PostToolUseFailure](#posttoolusefailure).2173* Para ejecutar un hook después de que cualquier herramienta se complete correctamente, omite el `matcher` o establécelo en `"*"`. Así, tu hook puede descubrir por sí mismo qué cambió, por ejemplo ejecutando `git status --porcelain`, que también lista los archivos sin seguimiento que `git diff` pasa por alto. Para las llamadas a herramientas que fallan, agrega el mismo hook en [PostToolUseFailure](#posttoolusefailure).
2175* Para ejecutar un hook cuando un archivo específico cambia en disco, sin importar qué lo escribió, usa [FileChanged](#filechanged). Claude Code no ejecuta un hook `PostToolUse` que coincide con `Edit|Write` cuando un comando `Bash` o un proceso fuera de Claude Code reescribe el mismo archivo.2174* Para ejecutar un hook cuando un archivo específico cambia en el disco, sin importar qué lo escribió, usa [FileChanged](#filechanged). Claude Code no ejecuta un hook `PostToolUse` que coincida con `Edit|Write` cuando un comando `Bash` o un proceso fuera de Claude Code reescribe el mismo archivo.
2176 2175
2177<h4 id="posttooluse-input">2176<h4 id="posttooluse-input">
2178 Entrada de PostToolUse2177 Entrada de PostToolUse
2216| `decision` | `"block"` agrega el `reason` junto al resultado de la herramienta. Claude sigue viendo la salida original; para reemplazarla, usa `updatedToolOutput` |2215| `decision` | `"block"` agrega el `reason` junto al resultado de la herramienta. Claude sigue viendo la salida original; para reemplazarla, usa `updatedToolOutput` |
2217| `reason` | Explicación que se muestra a Claude cuando `decision` es `"block"` |2216| `reason` | Explicación que se muestra a Claude cuando `decision` es `"block"` |
2218| `additionalContext` | Cadena que se agrega al contexto de Claude junto con el resultado de la herramienta. Consulta [Agregar contexto para Claude](#add-context-for-claude) |2217| `additionalContext` | Cadena que se agrega al contexto de Claude junto con el resultado de la herramienta. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
2219| `classifierContext` | Nota breve sobre el resultado de esta llamada destinada al clasificador del [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode) en lugar de a Claude. Consulta [Anotar un resultado para el clasificador del modo automático](#annotate-a-result-for-the-auto-mode-classifier). Requiere Claude Code v2.1.236 o posterior |2218| `classifierContext` | Nota breve sobre el resultado de esta llamada destinada al clasificador del [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode) y no a Claude. Consulta [Anotar un resultado para el clasificador del modo automático](#annotate-a-result-for-the-auto-mode-classifier). Requiere Claude Code v2.1.236 o posterior |
2220| `updatedToolOutput` | Reemplaza la salida de la herramienta con el valor proporcionado antes de enviarla a Claude. El valor debe coincidir con la forma de salida de la herramienta |2219| `updatedToolOutput` | Reemplaza la salida de la herramienta con el valor proporcionado antes de enviarla a Claude. El valor debe coincidir con la forma de salida de la herramienta |
2221| `updatedMCPToolOutput` | Reemplaza la salida solo para [herramientas MCP](#match-mcp-tools). Es preferible `updatedToolOutput`, que funciona para todas las herramientas |2220| `updatedMCPToolOutput` | Reemplaza la salida solo para [herramientas MCP](#match-mcp-tools). Es preferible usar `updatedToolOutput`, que funciona para todas las herramientas |
2222 2221
2223El siguiente ejemplo reemplaza la salida de una llamada a `Bash`. El valor de reemplazo coincide con la forma de salida de la herramienta `Bash`:2222El siguiente ejemplo reemplaza la salida de una llamada a `Bash`. El valor de reemplazo coincide con la forma de salida de la herramienta `Bash`:
2224 2223
2238```2237```
2239 2238
2240<Warning>2239<Warning>
2241 `updatedToolOutput` solo cambia lo que ve Claude. La herramienta ya se ejecutó cuando se activa el hook, por lo que cualquier archivo escrito, comando ejecutado o solicitud de red enviada ya surtió efecto. La telemetría, como los spans de herramientas de OpenTelemetry y los eventos de análisis, también captura la salida original antes de que se ejecute el hook. Para impedir o modificar una llamada a herramienta antes de que se ejecute, usa en su lugar un hook [PreToolUse](#pretooluse).2240 `updatedToolOutput` solo cambia lo que Claude ve. La herramienta ya se ejecutó cuando se activa el hook, por lo que cualquier archivo escrito, comando ejecutado o solicitud de red enviada ya tuvo efecto. La telemetría, como los spans de herramientas de OpenTelemetry y los eventos de analítica, también captura la salida original antes de que se ejecute el hook. Para impedir o modificar una llamada a herramienta antes de que se ejecute, usa en su lugar un hook [PreToolUse](#pretooluse).
2242 2241
2243 El valor de reemplazo debe coincidir con la forma de salida de la herramienta. Las herramientas integradas devuelven objetos estructurados en lugar de cadenas simples. Por ejemplo, `Bash` devuelve un objeto con los campos `stdout`, `stderr`, `interrupted` e `isImage`. Para las herramientas integradas, un valor que no coincide con el esquema de salida de la herramienta se ignora y se usa la salida original. La salida de las herramientas MCP se pasa sin validación de esquema. Eliminar detalles de errores que Claude necesita puede hacer que proceda con una suposición falsa.2242 El valor de reemplazo debe coincidir con la forma de salida de la herramienta. Las herramientas integradas devuelven objetos estructurados en lugar de cadenas simples. Por ejemplo, `Bash` devuelve un objeto con los campos `stdout`, `stderr`, `interrupted` e `isImage`. Para las herramientas integradas, un valor que no coincide con el esquema de salida de la herramienta se ignora y se usa la salida original. La salida de las herramientas MCP se transmite sin validación de esquema. Eliminar detalles de error que Claude necesita puede hacer que continúe basándose en una suposición falsa.
2244</Warning>2243</Warning>
2245 2244
2246<h4 id="annotate-a-result-for-the-auto-mode-classifier">2245<h4 id="annotate-a-result-for-the-auto-mode-classifier">
2247 Anotar un resultado para el clasificador del modo automático2246 Anotar un resultado para el clasificador del modo automático
2248</h4>2247</h4>
2249 2248
2250Devuelve `classifierContext` para enviar una nota breve sobre el resultado de la llamada a herramienta al clasificador del [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode) en lugar de a Claude. El clasificador [nunca recibe los resultados de las herramientas en sí](/docs/es/permission-modes#how-the-classifier-evaluates-actions), por lo que este campo es la forma admitida de comunicarle algo sobre lo que devolvió una llamada antes de que revise acciones posteriores. El campo requiere Claude Code v2.1.236 o posterior.2249Devuelve `classifierContext` para enviar una nota breve sobre el resultado de la llamada a herramienta al clasificador del [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode) en lugar de a Claude. El clasificador [nunca recibe los resultados de las herramientas en sí](/docs/es/permission-modes#how-the-classifier-evaluates-actions), así que este campo es la forma admitida de indicarle algo sobre lo que devolvió una llamada antes de que revise acciones posteriores. El campo requiere Claude Code v2.1.236 o posterior.
2251 2250
2252El siguiente ejemplo le indica al clasificador de dónde provino la salida de una consulta:2251El siguiente ejemplo le indica al clasificador de dónde provino la salida de una consulta:
2253 2252
2262 2261
2263El peso que el clasificador le da a la nota depende de dónde configuraste el hook:2262El peso que el clasificador le da a la nota depende de dónde configuraste el hook:
2264 2263
2265* **Hooks configurados en Claude Code**: para los hooks de archivos de configuración, plugins, skills y frontmatter de agentes, el clasificador trata la nota como contexto no verificado proporcionado por la aplicación. La nota nunca establece la intención del usuario y, si afirma que aprobaste o solicitaste algo, el clasificador contrasta esa afirmación con tus propios mensajes en la conversación2264* **Hooks configurados en Claude Code**: para los hooks de archivos de configuración, plugins, skills y frontmatter de agentes, el clasificador trata la nota como contexto no verificado proporcionado por la aplicación. La nota nunca establece la intención del usuario, y si afirma que aprobaste o solicitaste algo, el clasificador verifica esa afirmación contra tus propios mensajes en la conversación
2266* **Callbacks del Agent SDK en proceso**: cuando una aplicación que integra Claude Code registra el hook como un [callback del SDK de TypeScript](/docs/es/agent-sdk/hooks) y devuelve la nota durante la sesión en vivo, el clasificador puede considerar como intención del usuario una declaración del usuario transmitida en la nota. Esa declaración puede satisfacer un requisito de consentimiento que el clasificador aceptaría de un mensaje que envíes, pero nunca levanta un bloqueo que tu propio mensaje tampoco podría levantar. Después de que se reanuda una sesión, Claude Code trata las notas restauradas como contexto no verificado. Cuando hooks de ambos grupos anotan la misma llamada, el clasificador trata la nota combinada como no verificada2265* **Callbacks en proceso del Agent SDK**: cuando una aplicación que integra Claude Code registra el hook como un [callback del SDK de TypeScript](/docs/es/agent-sdk/hooks) y devuelve la nota durante la sesión activa, el clasificador puede considerar como intención del usuario una declaración del usuario transmitida en la nota. Dicha declaración puede satisfacer un requisito de consentimiento que el clasificador aceptaría de un mensaje que tú envías, pero nunca levanta un bloqueo que tu propio mensaje tampoco podría levantar. Después de que una sesión se reanuda, Claude Code trata las notas restauradas como contexto no verificado. Cuando hooks de ambos grupos anotan la misma llamada, el clasificador trata la nota combinada como no verificada
2267 2266
2268Claude Code aplica estos límites al entregar la nota:2267Claude Code aplica estos límites al entregar la nota:
2269 2268
2270* **Longitud**: Claude Code limita las notas de una llamada a herramienta a 2000 caracteres y trunca el resto. El límite se comparte entre todos los hooks que responden a esa llamada2269* **Longitud**: Claude Code limita las notas de una llamada a herramienta a 2,000 caracteres y trunca el resto. El límite se comparte entre todos los hooks que responden a esa llamada
2271* **Solo respuestas síncronas**: Claude Code ignora el campo en la respuesta de un hook que [se ejecuta en segundo plano](#run-hooks-in-the-background), porque esa respuesta llega después de que Claude Code registra el resultado de la herramienta2270* **Solo respuestas síncronas**: Claude Code ignora el campo en la respuesta de un hook que [se ejecuta en segundo plano](#run-hooks-in-the-background), porque esa respuesta llega después de que Claude Code registra el resultado de la herramienta
2272* **Llamadas que el clasificador no registra**: la transcripción del clasificador omite las consultas de solo lectura, como las lecturas de archivos y las búsquedas. Claude Code descarta una nota adjunta a una de esas llamadas2271* **Llamadas que el clasificador no registra**: la transcripción del clasificador omite las consultas de solo lectura, como lecturas de archivos y búsquedas. Claude Code descarta una nota adjunta a una de esas llamadas
2273* **Interacción con reescrituras**: cuando la nota describe una salida que estás reemplazando con `updatedToolOutput`, devuelve ambos campos en la misma respuesta del hook. Claude Code descarta la nota si esa reescritura se rechaza o si la reescritura de otro hook la reemplaza. Claude Code entrega una nota que devuelves sin reescritura incluso cuando otro hook reescribe la salida2272* **Interacción con reescrituras**: cuando la nota describe una salida que estás reemplazando con `updatedToolOutput`, devuelve ambos campos en la misma respuesta del hook. Claude Code descarta la nota si esa reescritura se rechaza o si la reescritura de otro hook la reemplaza. Claude Code entrega una nota que devuelves sin una reescritura incluso cuando otro hook reescribe la salida
2274 2273
2275<Warning>2274<Warning>
2276 El clasificador lee el contenido que colocas en `classifierContext` como información de la aplicación que aloja la sesión, así que no copies en él salida de herramientas no confiable ni texto de terceros. Limita la nota a una afirmación breve sobre esta única llamada, como un dato sobre su origen o una declaración del usuario al respecto; no uses el campo para entregar mensajes no relacionados ni un flujo de eventos.2275 El clasificador lee el contenido que colocas en `classifierContext` como información de la aplicación que aloja la sesión, así que no copies en él salidas de herramientas no confiables ni texto de terceros. Limita la nota a una afirmación breve sobre esta única llamada, como un dato sobre su origen o una declaración del usuario al respecto; no uses el campo para entregar mensajes no relacionados ni un flujo de eventos.
2277</Warning>2276</Warning>
2278 2277
2279<h3 id="posttoolusefailure">2278<h3 id="posttoolusefailure">
2280 PostToolUseFailure2279 PostToolUseFailure
2281</h3>2280</h3>
2282 2281
2283Se ejecuta cuando falla una herramienta que comenzó a ejecutarse: la herramienta lanzó un error o una herramienta MCP devolvió un resultado de error. Úsalo para registrar fallas, enviar alertas o proporcionar retroalimentación correctiva a Claude.2282Se ejecuta cuando falla una herramienta que comenzó a ejecutarse: la herramienta lanzó un error o una herramienta MCP devolvió un resultado de error. Úsalo para registrar fallos, enviar alertas o proporcionar retroalimentación correctiva a Claude.
2284 2283
2285Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.2284Hace coincidencia por nombre de herramienta, con los mismos valores que PreToolUse.
2286 2285
2287<Note>2286<Note>
2288 Este evento no se activa para llamadas a herramientas rechazadas antes de la ejecución: un nombre de herramienta desconocido, una entrada que no supera la validación de esquema o la validación específica de la herramienta, o una denegación de permiso. Los rechazos de validación se devuelven como resultados `tool_use_error` y ocurren antes de que se ejecuten los hooks, por lo que no activan ni `PreToolUse` ni `PostToolUseFailure`. Las denegaciones de permiso activan `PreToolUse` pero no este evento; consulta [PermissionDenied](#permissiondenied).2287 Este evento no se activa para las llamadas a herramientas rechazadas antes de la ejecución: un nombre de herramienta desconocido, una entrada que no supera la validación del esquema o la validación específica de la herramienta, o una denegación de permiso. Los rechazos por validación se devuelven como resultados `tool_use_error` y ocurren antes de que se ejecuten los hooks, por lo que no activan ni `PreToolUse` ni `PostToolUseFailure`. Las denegaciones de permiso activan `PreToolUse` pero no este evento; consulta [PermissionDenied](#permissiondenied).
2289</Note>2288</Note>
2290 2289
2291<h4 id="posttoolusefailure-input">2290<h4 id="posttoolusefailure-input">
2316| Campo | Descripción |2315| Campo | Descripción |
2317| :- | :- |2316| :- | :- |
2318| `error` | Cadena que describe qué salió mal. El formato depende de la herramienta que falló |2317| `error` | Cadena que describe qué salió mal. El formato depende de la herramienta que falló |
2319| `is_interrupt` | Booleano opcional. Es verdadero cuando la falla llegó a Claude Code como una cancelación en lugar de como un error informado por la herramienta. Cancelar una herramienta en ejecución no activa este hook; en su lugar, el resultado de la herramienta contiene el mensaje de interrupción |2318| `is_interrupt` | Booleano opcional. Es true cuando el fallo llegó a Claude Code como una cancelación y no como un error informado por la herramienta. Cancelar una herramienta en ejecución no activa este hook; en su lugar, el resultado de la herramienta incluye el mensaje de interrupción |
2320| `duration_ms` | Opcional. Tiempo de ejecución de la herramienta en milisegundos. Excluye el tiempo dedicado a solicitudes de permiso y a hooks PreToolUse |2319| `duration_ms` | Opcional. Tiempo de ejecución de la herramienta en milisegundos. Excluye el tiempo dedicado a solicitudes de permiso y a hooks PreToolUse |
2321 2320
2322La cadena `error` es generalmente el mismo texto que Claude recibe como resultado de la herramienta fallida. Su formato varía según la herramienta y la falla. Basa tu hook en `tool_name`, `is_interrupt` y la primera línea `Exit code N`; trata el resto de la cadena como texto para mostrar, no como un formato estable.2321La cadena `error` suele ser el mismo texto que Claude recibe como resultado de la herramienta fallida. Su formato varía según la herramienta y el fallo. Basa tu hook en `tool_name`, `is_interrupt` y la primera línea `Exit code N`; trata el resto de la cadena como texto para mostrar, no como un formato estable.
2323 2322
2324* Para Bash y PowerShell, un comando que se ejecutó y terminó produce una primera línea `Exit code N`, seguida de cualquier salida que haya producido el comando como un solo bloque con stdout y stderr intercalados2323* Para Bash y PowerShell, un comando que se ejecutó y terminó produce una primera línea `Exit code N`, seguida de cualquier salida que haya producido el comando como un solo bloque con stdout y stderr intercalados
2325* Un payload también puede contener un mensaje de falla simple sin línea de código de salida, cuando Claude Code no pudo iniciar el proceso del shell2324* Un payload también puede contener un mensaje de fallo simple sin línea de código de salida, cuando Claude Code no pudo iniciar el proceso del shell en sí
2326* Claude Code trunca por el medio las cadenas largas alrededor de un marcador `... [N characters truncated] ...` y puede insertar líneas propias, como `Command timed out after 2m 0s`2325* Claude Code trunca por la mitad las cadenas largas alrededor de un marcador `... [N characters truncated] ...` y puede insertar líneas propias, como `Command timed out after 2m 0s`
2327 2326
2328<h4 id="posttoolusefailure-decision-control">2327<h4 id="posttoolusefailure-decision-control">
2329 Control de decisiones de PostToolUseFailure2328 Control de decisiones de PostToolUseFailure
2330</h4>2329</h4>
2331 2330
2332Los hooks `PostToolUseFailure` pueden proporcionar contexto a Claude después de una falla de herramienta. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, tu script de hook puede devolver estos campos específicos del evento:2331Los hooks `PostToolUseFailure` pueden proporcionar contexto a Claude después de un fallo de herramienta. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, tu script de hook puede devolver estos campos específicos del evento:
2333 2332
2334| Campo | Descripción |2333| Campo | Descripción |
2335| :- | :- |2334| :- | :- |
2348 PostToolBatch2347 PostToolBatch
2349</h3>2348</h3>
2350 2349
2351Se ejecuta una vez después de que se haya resuelto cada llamada a herramienta de un lote, antes de que Claude Code envíe la siguiente solicitud al modelo. `PostToolUse` se activa una vez por herramienta, lo que significa que se activa de forma concurrente cuando Claude hace llamadas a herramientas en paralelo. `PostToolBatch` se activa exactamente una vez con el lote completo, por lo que es el lugar adecuado para inyectar contexto que depende del conjunto de herramientas que se ejecutaron en lugar de una sola herramienta. No hay matcher para este evento.2350Se ejecuta una vez después de que se resuelven todas las llamadas a herramientas de un lote, antes de que Claude Code envíe la siguiente solicitud al modelo. `PostToolUse` se activa una vez por herramienta, lo que significa que se activa de forma concurrente cuando Claude hace llamadas a herramientas en paralelo. `PostToolBatch` se activa exactamente una vez con el lote completo, por lo que es el lugar adecuado para inyectar contexto que depende del conjunto de herramientas que se ejecutaron y no de una sola herramienta. No hay matcher para este evento.
2352 2351
2353<h4 id="posttoolbatch-input">2352<h4 id="posttoolbatch-input">
2354 Entrada de PostToolBatch2353 Entrada de PostToolBatch
2355</h4>2354</h4>
2356 2355
2357Además de los [campos de entrada comunes](#common-input-fields), los hooks PostToolBatch reciben `tool_calls`, un arreglo que describe cada llamada a herramienta del lote:2356Además de los [campos de entrada comunes](#common-input-fields), los hooks PostToolBatch reciben `tool_calls`, un array que describe cada llamada a herramienta del lote:
2358 2357
2359```json theme={null}2358```json theme={null}
2360{2359{
2380}2379}
2381```2380```
2382 2381
2383`tool_response` contiene el mismo contenido que el modelo recibe en el bloque `tool_result` correspondiente. El valor es una cadena serializada o un arreglo de bloques de contenido, exactamente como lo emitió la herramienta. Para `Read`, eso significa texto con prefijo de número de línea en lugar del contenido sin procesar del archivo. Las respuestas pueden ser grandes, así que analiza solo los campos que necesitas.2382`tool_response` contiene el mismo contenido que el modelo recibe en el bloque `tool_result` correspondiente. El valor es una cadena serializada o un array de bloques de contenido, exactamente como lo emitió la herramienta. Para `Read`, eso significa texto con prefijo de número de línea en lugar del contenido sin procesar del archivo. Las respuestas pueden ser grandes, así que analiza solo los campos que necesites.
2384 2383
2385<Note>2384<Note>
2386 La forma de `tool_response` difiere de la de `PostToolUse`. `PostToolUse` pasa el objeto `Output` estructurado de la herramienta, como `{filePath: "...", type: "create"}` para `Write`; `PostToolBatch` pasa el contenido serializado de `tool_result` que ve el modelo.2385 La forma de `tool_response` difiere de la de `PostToolUse`. `PostToolUse` pasa el objeto `Output` estructurado de la herramienta, como `{filePath: "...", type: "create"}` para `Write`; `PostToolBatch` pasa el contenido serializado de `tool_result` que ve el modelo.
2394 2393
2395| Campo | Descripción |2394| Campo | Descripción |
2396| :- | :- |2395| :- | :- |
2397| `additionalContext` | Cadena de contexto inyectada una vez antes de la siguiente llamada al modelo. Consulta [Agregar contexto para Claude](#add-context-for-claude) para conocer los detalles de entrega, qué incluir y cómo las sesiones reanudadas manejan los valores anteriores |2396| `additionalContext` | Cadena de contexto que se inyecta una vez antes de la siguiente llamada al modelo. Consulta [Agregar contexto para Claude](#add-context-for-claude) para ver detalles de entrega, qué incluir y cómo las sesiones reanudadas manejan los valores anteriores |
2398 2397
2399```json theme={null}2398```json theme={null}
2400{2399{
2405}2404}
2406```2405```
2407 2406
2408Devolver `decision: "block"` o `continue: false` detiene el bucle agéntico antes de la siguiente llamada al modelo. El mensaje de bloqueo proviene del `reason` o `stopReason` del JSON, o de stderr con el código de salida 2. Lo ves como una advertencia en la transcripción y permanece en la conversación, por lo que Claude lo ve cuando la conversación continúa.2407Devolver `decision: "block"` o `continue: false` detiene el bucle agéntico antes de la siguiente llamada al modelo. El mensaje de bloqueo proviene del `reason` o `stopReason` del JSON, o de stderr con el código de salida 2. Lo ves como una advertencia en la transcripción, y permanece en la conversación, por lo que Claude lo ve cuando la conversación continúa.
2409 2408
2410<h3 id="permissiondenied">2409<h3 id="permissiondenied">
2411 PermissionDenied2410 PermissionDenied
2412</h3>2411</h3>
2413 2412
2414Se ejecuta cuando el [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode) deniega una llamada a herramienta, incluso cuando la deniega sin un veredicto del clasificador porque [una verificación de seguridad independiente del modo automático rechazó la propia solicitud del clasificador](/docs/es/errors#auto-mode-cannot-determine-the-safety-of-an-action) o su respuesta no se pudo analizar. Este hook solo se activa en modo automático: no se ejecuta cuando deniegas manualmente un cuadro de diálogo de permisos, cuando un hook `PreToolUse` bloquea una llamada ni cuando coincide una regla `deny`. Úsalo para registrar denegaciones, ajustar la configuración o indicarle al modelo que puede reintentar la llamada a herramienta.2413Se ejecuta cuando el [modo automático](/docs/es/permission-modes#eliminate-prompts-with-auto-mode) deniega una llamada a herramienta, incluso cuando la deniega sin un veredicto del clasificador porque [una verificación de seguridad independiente del modo automático rechazó la propia solicitud del clasificador](/docs/es/errors#auto-mode-cannot-determine-the-safety-of-an-action) o su respuesta no se pudo analizar. Este hook solo se activa en modo automático: no se ejecuta cuando deniegas manualmente un diálogo de permisos, cuando un hook `PreToolUse` bloquea una llamada ni cuando coincide una regla `deny`. Úsalo para registrar denegaciones, ajustar la configuración o indicarle al modelo que puede reintentar la llamada a herramienta.
2415 2414
2416Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.2415Hace coincidencia por nombre de herramienta, con los mismos valores que PreToolUse.
2417 2416
2418<h4 id="permissiondenied-input">2417<h4 id="permissiondenied-input">
2419 Entrada de PermissionDenied2418 Entrada de PermissionDenied
2440 2439
2441| Campo | Descripción |2440| Campo | Descripción |
2442| :- | :- |2441| :- | :- |
2443| `reason` | El motivo de la denegación. Para un veredicto del clasificador, en la mayoría de las sesiones nombra la regla que coincidió entre corchetes, como `[Data Exfiltration]`; consulta [Revisar denegaciones](/docs/es/auto-mode-config#review-denials) para ver las otras formas. Para una [denegación sin veredicto](#permissiondenied-decision-control), comienza con `Auto mode could not evaluate this action and is blocking it for safety`. Para una denegación porque el modelo clasificador no estaba disponible, es el texto fijo `Classifier unavailable` |2442| `reason` | El motivo de la denegación. Para un veredicto del clasificador, en la mayoría de las sesiones nombra la regla coincidente entre corchetes, como `[Data Exfiltration]`; consulta [Revisar denegaciones](/docs/es/auto-mode-config#review-denials) para ver las demás formas. Para una [denegación sin veredicto](#permissiondenied-decision-control), comienza con `Auto mode could not evaluate this action and is blocking it for safety`. Para una denegación porque el modelo del clasificador no estaba disponible, es el texto fijo `Classifier unavailable` |
2444 2443
2445<h4 id="permissiondenied-decision-control">2444<h4 id="permissiondenied-decision-control">
2446 Control de decisiones de PermissionDenied2445 Control de decisiones de PermissionDenied
2459 2458
2460Cuando `retry` es `true`, Claude Code agrega un mensaje a la conversación que le indica al modelo que puede reintentar la llamada a herramienta. Claude Code no revierte la denegación en sí. Si tu hook no devuelve JSON, o devuelve `retry: false`, la denegación se mantiene y el modelo recibe el mensaje de rechazo original.2459Cuando `retry` es `true`, Claude Code agrega un mensaje a la conversación que le indica al modelo que puede reintentar la llamada a herramienta. Claude Code no revierte la denegación en sí. Si tu hook no devuelve JSON, o devuelve `retry: false`, la denegación se mantiene y el modelo recibe el mensaje de rechazo original.
2461 2460
2462Claude Code ignora `retry: true` cuando el clasificador no produjo [ningún veredicto sobre la acción](/docs/es/errors#auto-mode-cannot-determine-the-safety-of-an-action): su respuesta no se pudo analizar, o una verificación de seguridad independiente del modo automático rechazó la propia solicitud del clasificador. Para esas denegaciones, Claude Code ya le indica al modelo en el mensaje de rechazo si debe reintentar más tarde o continuar.2461Claude Code ignora `retry: true` cuando el clasificador no produjo [ningún veredicto sobre la acción](/docs/es/errors#auto-mode-cannot-determine-the-safety-of-an-action): su respuesta no se pudo analizar, o una verificación de seguridad independiente del modo automático rechazó la propia solicitud del clasificador. Para esas denegaciones, Claude Code ya le indica al modelo en el mensaje de rechazo si debe reintentar más tarde o continuar con otra cosa.
2463 2462
2464<h3 id="notification">2463<h3 id="notification">
2465 Notification2464 Notification
2466</h3>2465</h3>
2467 2466
2468Se ejecuta cuando Claude Code envía notificaciones. Coincide con el tipo de notificación. Omite el matcher para ejecutar hooks para todos los tipos de notificación.2467Se ejecuta cuando Claude Code envía notificaciones. Hace coincidencia por tipo de notificación. Omite el matcher para ejecutar hooks para todos los tipos de notificación.
2469 2468
2470Recibes estos eventos de hook incluso con las notificaciones de escritorio desactivadas: el ajuste `preferredNotifChannel`, incluido `notifications_disabled`, solo cambia cómo se te alerta, no si tu hook se ejecuta.2469Recibes estos eventos de hook incluso con las notificaciones de escritorio desactivadas: el ajuste `preferredNotifChannel`, incluido `notifications_disabled`, solo cambia cómo se te avisa, no si tu hook se ejecuta.
2471 2470
2472| Matcher | Cuándo se activa |2471| Matcher | Cuándo se activa |
2473| :- | :- |2472| :- | :- |
2474| `permission_prompt` | Claude necesita que apruebes el uso de una herramienta o la [solicitud de red](/docs/es/sandboxing#network-isolation) de un comando en el sandbox, y la solicitud lleva esperando unos seis segundos |2473| `permission_prompt` | Claude necesita que apruebes el uso de una herramienta o la [solicitud de red](/docs/es/sandboxing#network-isolation) de un comando en el sandbox, y la solicitud lleva unos seis segundos esperando |
2475| `idle_prompt` | Claude terminó de responder hace unos 60 segundos y no has escrito nada desde entonces |2474| `idle_prompt` | Claude terminó de responder hace unos 60 segundos y no has escrito nada desde entonces |
2476| `auth_success` | Se completa la autenticación |2475| `auth_success` | Se completa la autenticación |
2477| `elicitation_dialog` | Un servidor MCP abre un formulario de elicitación y no has escrito nada durante unos seis segundos |2476| `elicitation_dialog` | Un servidor MCP abre un formulario de elicitación y no has escrito durante unos seis segundos |
2478| `elicitation_url_dialog` | Un servidor MCP te pide abrir una URL en el navegador y no has escrito nada durante unos seis segundos |2477| `elicitation_url_dialog` | Un servidor MCP te pide abrir una URL en el navegador y no has escrito durante unos seis segundos |
2479| `elicitation_complete` | Un servidor MCP informa que una [elicitación en modo URL](#elicitation-input) está completa |2478| `elicitation_complete` | Un servidor MCP informa que una [elicitación en modo URL](#elicitation-input) se completó |
2480| `elicitation_response` | Se envía una respuesta de elicitación MCP de vuelta al servidor |2479| `elicitation_response` | Se envía una respuesta de elicitación MCP de vuelta al servidor |
2481| `agent_needs_input` | Una sesión en segundo plano comienza a esperar tu entrada mientras la [vista de agentes](/docs/es/agent-view) está abierta en una terminal. También se activa cuando una sesión de terminal te muestra una [pregunta de configuración de terminal de un compañero de un equipo de agentes](/docs/es/agent-teams#choose-a-display-mode) o el aviso del modo automático sobre [cargos por solicitudes del clasificador](/docs/es/auto-mode-classifier-billing) y no has escrito nada durante unos seis segundos |2480| `agent_needs_input` | Una sesión en segundo plano empieza a esperar tu entrada mientras la [vista de agentes](/docs/es/agent-view) está abierta en una terminal. También se activa cuando una sesión de terminal te muestra la [pregunta de configuración de terminal de un compañero de un equipo de agentes](/docs/es/agent-teams#choose-a-display-mode) o el aviso del modo automático sobre los [cargos por solicitudes del clasificador](/docs/es/auto-mode-classifier-billing) y no has escrito durante unos seis segundos |
2482| `agent_completed` | Una sesión en segundo plano termina o falla. Se activa solo mientras la [vista de agentes](/docs/es/agent-view) está abierta en una terminal |2481| `agent_completed` | Una sesión en segundo plano termina o falla. Solo se activa mientras la [vista de agentes](/docs/es/agent-view) está abierta en una terminal |
2483| `quota_auto_resume_fired` | Claude Code continúa tu tarea después de que un límite de uso de claude.ai la pausó: en el restablecimiento, o antes cuando algo que haces en Claude Code durante la espera, como agregar créditos de uso, mejorar tu plan o cambiar de modelo, vuelve a habilitar el uso, con la [excepción del ajuste de modelo](/docs/es/interactive-mode#wait-for-a-usage-limit-to-reset) |2482| `quota_auto_resume_fired` | Claude Code continúa tu tarea después de que un límite de uso de claude.ai la pausara: en el restablecimiento, o antes cuando algo que haces en Claude Code durante la espera, como agregar créditos de uso, mejorar tu plan o cambiar de modelo, vuelve a hacer disponible el uso, con la [excepción del ajuste de modelo](/docs/es/interactive-mode#wait-for-a-usage-limit-to-reset) |
2484| `quota_auto_resume_stale` | Un límite de uso de claude.ai se restableció mientras tu computadora estuvo suspendida durante más de unos 30 minutos. Claude Code espera a que presiones `Enter` en lugar de continuar. Después de una suspensión más corta, continúa y activa `quota_auto_resume_fired` en su lugar |2483| `quota_auto_resume_stale` | Un límite de uso de claude.ai se restableció mientras tu computadora estuvo suspendida durante más de unos 30 minutos. Claude Code espera a que presiones `Enter` en lugar de continuar. Después de una suspensión más corta, continúa y activa `quota_auto_resume_fired` en su lugar |
2485| `quota_auto_resume_disabled` | Claude Code termina su espera por un límite de uso de claude.ai sin continuar tu tarea: se desactivó [`autoContinueAtUsageLimit`](/docs/es/settings-reference#autocontinueatusagelimit) o el restablecimiento se alejó más de 24 horas durante una espera que Claude Code inició por su cuenta, la tarea continuada siguió alcanzando el límite, o la continuación se bloqueó antes de llegar al modelo. No se activa cuando presionas `Esc` o `Ctrl+C`, ni cuando eliges **Don't continue automatically** |2484| `quota_auto_resume_disabled` | Claude Code termina su espera por un límite de uso de claude.ai sin continuar tu tarea: [`autoContinueAtUsageLimit`](/docs/es/settings-reference#autocontinueatusagelimit) se desactivó o el restablecimiento se movió a más de 24 horas durante una espera que Claude Code inició por su cuenta, la tarea continuada siguió alcanzando el límite, o la continuación se bloqueó antes de llegar al modelo. No se activa cuando presionas `Esc` o `Ctrl+C`, ni cuando eliges **Don't continue automatically** |
2486 2485
2487Los tipos `quota_auto_resume_fired`, `quota_auto_resume_stale` y `quota_auto_resume_disabled` requieren Claude Code v2.1.234 o posterior.2486Los tipos `quota_auto_resume_fired`, `quota_auto_resume_stale` y `quota_auto_resume_disabled` requieren Claude Code v2.1.234 o posterior.
2488 2487
2491`agent_needs_input` para la pregunta de configuración de terminal de un compañero requiere Claude Code v2.1.248 o posterior.2490`agent_needs_input` para la pregunta de configuración de terminal de un compañero requiere Claude Code v2.1.248 o posterior.
2492 2491
2493<Note>2492<Note>
2494 Los tipos `permission_prompt`, `idle_prompt`, `elicitation_dialog` y `elicitation_url_dialog` comparten su temporización con las notificaciones de escritorio, por lo que en las sesiones de terminal solo los ves cuando parece que estás lejos de la terminal:2493 Los tipos `permission_prompt`, `idle_prompt`, `elicitation_dialog` y `elicitation_url_dialog` comparten su temporización con las notificaciones de escritorio, por lo que en sesiones de terminal solo los ves cuando parece que estás lejos de la terminal:
2495 2494
2496 * Espera `permission_prompt` una vez que no hayas escrito nada durante unos seis segundos. El temporizador comienza cuando aparece la solicitud de permiso, y cada pulsación de tecla lo aplaza. Para ejecutar un hook inmediatamente cuando Claude pide permiso para usar una herramienta, usa [PermissionRequest](#permissionrequest) en su lugar.2495 * Espera `permission_prompt` una vez que no hayas escrito durante unos seis segundos. El temporizador comienza cuando aparece la solicitud de permiso, y cada pulsación de tecla lo pospone. Para ejecutar un hook inmediatamente cuando Claude pide permiso para usar una herramienta, usa [PermissionRequest](#permissionrequest) en su lugar.
2497 * Espera `idle_prompt` unos 60 segundos después de que Claude termine de responder, y solo si no has escrito nada desde entonces y ningún agente en segundo plano, como un [subagente](/docs/es/sub-agents) en segundo plano, sigue en ejecución. Claude Code no envía `idle_prompt` mientras espera a que se restablezca un límite de uso de claude.ai. Cuando la espera termina por sí sola, se activa en su lugar uno de los tipos `quota_auto_resume_*`.2496 * Espera `idle_prompt` unos 60 segundos después de que Claude termine de responder, y solo si no has escrito desde entonces y ningún agente en segundo plano, como un [subagente](/docs/es/sub-agents) en segundo plano, sigue ejecutándose. Claude Code no envía `idle_prompt` mientras espera que se restablezca un límite de uso de claude.ai. Cuando la espera termina por sí sola, se activa en su lugar uno de los tipos `quota_auto_resume_*`.
2498 * Espera `elicitation_dialog` para un formulario de elicitación, o `elicitation_url_dialog` para una solicitud de URL del navegador, una vez que no hayas escrito nada durante unos seis segundos. Ambos comparten el mismo umbral de seis segundos que `permission_prompt`: el temporizador comienza cuando aparece el cuadro de diálogo, y cada pulsación de tecla lo aplaza.2497 * Espera `elicitation_dialog` para un formulario de elicitación, o `elicitation_url_dialog` para una solicitud de URL en el navegador, una vez que no hayas escrito durante unos seis segundos. Ambos comparten la misma espera de seis segundos que `permission_prompt`: el temporizador comienza cuando aparece el diálogo, y cada pulsación de tecla lo pospone.
2499 2498
2500 Una solicitud de permiso o elicitación que llega mientras otro cuadro de diálogo está en pantalla mantiene el mismo umbral de seis segundos, contado desde que llega la solicitud. Su notificación puede llegarte mientras la solicitud sigue esperando detrás del cuadro de diálogo abierto.2499 Una solicitud de permiso o una elicitación que llega mientras otro diálogo está en pantalla mantiene la misma espera de seis segundos, contada desde que llega la solicitud. Su notificación puede llegarte mientras la solicitud sigue esperando detrás del diálogo abierto.
2501</Note>2500</Note>
2502 2501
2503Claude Code temporiza `permission_prompt` de forma diferente en las sesiones en las que envía solicitudes de permiso al [callback `canUseTool`](/docs/es/agent-sdk/user-input) del Agent SDK, que es como Claude Desktop y la extensión de VS Code alojan Claude Code:2502Claude Code temporiza `permission_prompt` de forma diferente en las sesiones donde envía las solicitudes de permiso al [callback `canUseTool`](/docs/es/agent-sdk/user-input) del Agent SDK, que es como Claude Desktop y la extensión de VS Code alojan Claude Code:
2504 2503
2505* Espera `permission_prompt` unos seis segundos después de que Claude pida permiso. Claude Code no lo aplaza mientras escribes.2504* Espera `permission_prompt` unos seis segundos después de que Claude pida permiso. Claude Code no lo pospone mientras escribes.
2506* Si tú o un hook [PermissionRequest](#permissionrequest) responden antes, Claude Code no ejecuta `permission_prompt`.2505* Si tú o un hook [PermissionRequest](#permissionrequest) responden antes, Claude Code no ejecuta `permission_prompt`.
2507* Establece [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/es/env-vars) en `1` para desactivar `permission_prompt` en estas sesiones.2506* Establece [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/es/env-vars) en `1` para desactivar `permission_prompt` en estas sesiones.
2508 2507
2509Antes de v2.1.233, `permission_prompt` no se activaba en estas sesiones.2508Antes de v2.1.233, `permission_prompt` no se activaba en estas sesiones.
2510 2509
2511Usa matchers separados para ejecutar distintos manejadores según el tipo de notificación. Esta configuración activa un script de alerta específico de permisos cuando Claude necesita aprobación de permisos y una notificación diferente cuando Claude ha estado inactivo:2510Usa matchers separados para ejecutar distintos controladores según el tipo de notificación. Esta configuración activa un script de alerta específico de permisos cuando Claude necesita aprobación de permisos y una notificación diferente cuando Claude ha estado inactivo:
2512 2511
2513```json theme={null}2512```json theme={null}
2514{2513{
2561 SubagentStart2560 SubagentStart
2562</h3>2561</h3>
2563 2562
2564Se ejecuta cuando Claude genera un subagente con la herramienta Agent, cuando Claude [reanuda un subagente](/docs/es/sub-agents#resume-subagents) y cada vez que un compañero en proceso de un [equipo de agentes](/docs/es/agent-teams) maneja un mensaje nuevo. Admite matchers para filtrar por nombre de tipo de agente. Para los agentes integrados, es el nombre del agente, como `general-purpose`, `Explore` o `Plan`. Para los [subagentes personalizados](/docs/es/sub-agents), es el campo `name` del frontmatter del agente, no el nombre del archivo.2563Se ejecuta cuando Claude genera un subagente con la herramienta Agent, cuando Claude [reanuda un subagente](/docs/es/sub-agents#resume-subagents) y cada vez que un compañero en proceso de un [equipo de agentes](/docs/es/agent-teams) gestiona un mensaje nuevo. Admite matchers para filtrar por nombre de tipo de agente. Para los agentes integrados, es el nombre del agente, como `general-purpose`, `Explore` o `Plan`. Para los [subagentes personalizados](/docs/es/sub-agents), es el campo `name` del frontmatter del agente, no el nombre del archivo.
2565 2564
2566Para los subagentes incluidos en un [plugin](/docs/es/plugins/overview), el tipo de agente es el identificador con ámbito del plugin, como `my-plugin:reviewer`, no el nombre simple del frontmatter. Los dos puntos colocan un nombre con ámbito de plugin en la ruta de expresión regular, así que ancla el matcher con `^` y `$` para una coincidencia exacta: `^my-plugin:reviewer$`.2565Para los subagentes incluidos en un [plugin](/docs/es/plugins/overview), el tipo de agente es el identificador con ámbito de plugin, como `my-plugin:reviewer`, no el nombre simple del frontmatter. Los dos puntos hacen que un nombre con ámbito de plugin se evalúe como expresión regular, así que ancla el matcher con `^` y `$` para una coincidencia exacta: `^my-plugin:reviewer$`.
2567 2566
2568<h4 id="subagentstart-input">2567<h4 id="subagentstart-input">
2569 Entrada de SubagentStart2568 Entrada de SubagentStart
2586 2585
2587| Campo | Descripción |2586| Campo | Descripción |
2588| :- | :- |2587| :- | :- |
2589| `additionalContext` | Cadena que se agrega al contexto del subagente al comienzo de su conversación, antes de su primer prompt. Consulta [Agregar contexto para Claude](#add-context-for-claude) |2588| `additionalContext` | Cadena que se agrega al contexto del subagente al inicio de su conversación, antes de su primer prompt. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
2590 2589
2591```json theme={null}2590```json theme={null}
2592{2591{
2603 SubagentStop2602 SubagentStop
2604</h3>2603</h3>
2605 2604
2606Se ejecuta cuando un subagente de Claude Code terminó de responder. Coincide con el tipo de agente, con los mismos valores que SubagentStart.2605Se ejecuta cuando un subagente de Claude Code terminó de responder. Hace coincidencia por tipo de agente, con los mismos valores que SubagentStart.
2607 2606
2608<h4 id="subagentstop-input">2607<h4 id="subagentstop-input">
2609 Entrada de SubagentStop2608 Entrada de SubagentStop
2615 2614
2616Un `matcher` que nombra tipos de agente no coincide con un `agent_type` vacío. Un hook cuyo matcher se omite, es `""` o `"*"`, o es una expresión regular que coincide con una cadena vacía, también se ejecuta para eventos con un `agent_type` vacío.2615Un `matcher` que nombra tipos de agente no coincide con un `agent_type` vacío. Un hook cuyo matcher se omite, es `""` o `"*"`, o es una expresión regular que coincide con una cadena vacía, también se ejecuta para eventos con un `agent_type` vacío.
2617 2616
2618En Claude Code v2.1.271 o posterior, un subagente que se ejecuta con la herramienta [`SubagentHandback`](/docs/es/tools-reference) entrega su informe a través de esa herramienta antes de detenerse. El campo `last_assistant_message` contiene entonces el texto de cierre del subagente, si lo hay, que no es el informe entregado. El informe es la entrada `message` de esa llamada, que un hook `PreToolUse` o `PostToolUse` que coincide con `SubagentHandback` recibe como `tool_input.message`.2617En Claude Code v2.1.271 o posterior, un subagente que se ejecuta con la herramienta [`SubagentHandback`](/docs/es/tools-reference) entrega su informe a través de esa herramienta antes de detenerse. En ese caso, el campo `last_assistant_message` contiene el texto de cierre del subagente, si lo hay, que no es el informe entregado. El informe es la entrada `message` de esa llamada, que un hook `PreToolUse` o `PostToolUse` con coincidencia en `SubagentHandback` recibe como `tool_input.message`.
2619 2618
2620Los hooks SubagentStop también reciben los arreglos `background_tasks` y `session_crons` descritos en [Entrada de Stop](#stop-input). Ambos arreglos tienen como ámbito la sesión principal, no el subagente.2619Los hooks SubagentStop también reciben los arrays `background_tasks` y `session_crons` descritos en [Entrada de Stop](#stop-input). Ambos arrays tienen como ámbito la sesión principal, no el subagente.
2621 2620
2622```json theme={null}2621```json theme={null}
2623{2622{
2636}2635}
2637```2636```
2638 2637
2639Los hooks SubagentStop usan el mismo formato de control de decisiones que los [hooks Stop](#stop-decision-control), incluido `hookSpecificOutput.additionalContext` con `hookEventName` establecido en `"SubagentStop"`, para retroalimentación que no es de error y que mantiene al subagente en ejecución. Devolver `decision: "block"` con un `reason` mantiene al subagente en ejecución y le entrega `reason` como su siguiente instrucción. Un hook que bloquea al terminar con código 2 entrega su mensaje de stderr de la misma manera. Para inyectar contexto en la sesión principal después de que un subagente regresa, usa en su lugar un hook [`PostToolUse`](#posttooluse) sobre la herramienta `Agent`.2638Los hooks SubagentStop usan el mismo formato de control de decisiones que los [hooks Stop](#stop-decision-control), incluido `hookSpecificOutput.additionalContext` con `hookEventName` establecido en `"SubagentStop"`, para retroalimentación que no es de error y que mantiene al subagente en ejecución. Devolver `decision: "block"` con un `reason` mantiene al subagente en ejecución y le entrega `reason` al subagente como su siguiente instrucción. Un hook que bloquea saliendo con código 2 entrega su mensaje de stderr de la misma forma. Para inyectar contexto en la sesión principal después de que un subagente regrese, usa en su lugar un hook [`PostToolUse`](#posttooluse) sobre la herramienta `Agent`.
2640 2639
2641<h3 id="taskcreated">2640<h3 id="taskcreated">
2642 TaskCreated2641 TaskCreated
2643</h3>2642</h3>
2644 2643
2645Se ejecuta cuando se está creando una tarea mediante la herramienta `TaskCreate`. Úsalo para aplicar convenciones de nomenclatura, exigir descripciones de tareas o impedir que se creen ciertas tareas. En una [sesión sin las herramientas Task](/docs/es/tools-reference#task-tool-availability), este evento no se activa.2644Se ejecuta cuando se está creando una tarea mediante la herramienta `TaskCreate`. Úsalo para aplicar convenciones de nombres, exigir descripciones de tareas o impedir que se creen ciertas tareas. En una [sesión sin las herramientas Task](/docs/es/tools-reference#task-tool-availability), este evento no se activa.
2646 2645
2647Los hooks TaskCreated no admiten matchers y se activan en cada ocurrencia.2646Los hooks TaskCreated no admiten matchers y se activan en cada ocurrencia.
2648 2647
2670| :- | :- |2669| :- | :- |
2671| `task_id` | Identificador de la tarea que se está creando |2670| `task_id` | Identificador de la tarea que se está creando |
2672| `task_subject` | Título de la tarea |2671| `task_subject` | Título de la tarea |
2673| `task_description` | Descripción detallada de la tarea. Puede no estar presente |2672| `task_description` | Descripción detallada de la tarea. Puede estar ausente |
2674| `teammate_name` | Nombre del compañero que crea la tarea. Puede no estar presente |2673| `teammate_name` | Nombre del compañero que crea la tarea. Puede estar ausente |
2675| `team_name` | Obsoleto. Nombre del equipo derivado de la sesión; se eliminará en una versión futura |2674| `team_name` | Obsoleto. Nombre del equipo derivado de la sesión; se eliminará en una versión futura |
2675| `agent_id` | En este evento, el [campo de entrada común](#common-input-fields) identifica al subagente o al [compañero en proceso](/docs/es/agent-teams#choose-a-display-mode) que crea la tarea. Puede estar ausente. Requiere Claude Code v2.1.290 o posterior |
2676 2676
2677<h4 id="taskcreated-decision-control">2677<h4 id="taskcreated-decision-control">
2678 Control de decisiones de TaskCreated2678 Control de decisiones de TaskCreated
2679</h4>2679</h4>
2680 2680
2681Un hook TaskCreated puede bloquear la creación de dos maneras. En cualquier caso, Claude Code elimina la tarea y devuelve tu mensaje a Claude como el error de la herramienta. Claude Code ignora `continue: false` de este evento y Claude sigue trabajando.2681Un hook TaskCreated puede bloquear la creación de dos maneras. En ambos casos, Claude Code elimina la tarea y devuelve tu mensaje a Claude como el error de la herramienta. Claude Code ignora `continue: false` de este evento y Claude sigue trabajando.
2682 2682
2683* **Código de salida 2**: Claude Code devuelve el texto de stderr como mensaje.2683* **Código de salida 2**: Claude Code devuelve el texto de stderr como mensaje.
2684* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code devuelve `reason` como mensaje.2684* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code devuelve `reason` como mensaje.
2702 TaskCompleted2702 TaskCompleted
2703</h3>2703</h3>
2704 2704
2705Se ejecuta cuando una tarea se está marcando como completada. Se activa en dos situaciones: cuando cualquier agente marca explícitamente una tarea como completada mediante la herramienta TaskUpdate, o cuando un compañero de un [equipo de agentes](/docs/es/agent-teams) termina su turno con tareas en curso. Úsalo para aplicar criterios de finalización, como exigir que pasen las pruebas o las verificaciones de lint antes de que una tarea pueda cerrarse.2705Se ejecuta cuando una tarea se está marcando como completada. Se activa en dos situaciones: cuando cualquier agente marca explícitamente una tarea como completada mediante la herramienta TaskUpdate, o cuando un compañero de un [equipo de agentes](/docs/es/agent-teams) termina su turno con tareas en curso. Úsalo para aplicar criterios de finalización, como que pasen las pruebas o las verificaciones de lint, antes de que una tarea pueda cerrarse.
2706 2706
2707Los hooks TaskCompleted no admiten matchers y se activan en cada ocurrencia.2707Los hooks TaskCompleted no admiten matchers y se activan en cada ocurrencia.
2708 2708
2731| :- | :- |2731| :- | :- |
2732| `task_id` | Identificador de la tarea que se está completando |2732| `task_id` | Identificador de la tarea que se está completando |
2733| `task_subject` | Título de la tarea |2733| `task_subject` | Título de la tarea |
2734| `task_description` | Descripción detallada de la tarea. Puede no estar presente |2734| `task_description` | Descripción detallada de la tarea. Puede estar ausente |
2735| `teammate_name` | Nombre del compañero que completa la tarea. Puede no estar presente |2735| `teammate_name` | Nombre del compañero que completa la tarea. Puede estar ausente |
2736| `team_name` | Obsoleto. Nombre del equipo derivado de la sesión; se eliminará en una versión futura |2736| `team_name` | Obsoleto. Nombre del equipo derivado de la sesión; se eliminará en una versión futura |
2737| `agent_id` | En este evento, el [campo de entrada común](#common-input-fields) identifica al subagente o al [compañero en proceso](/docs/es/agent-teams#choose-a-display-mode) que completa la tarea. Puede estar ausente. Requiere Claude Code v2.1.290 o posterior |
2737 2738
2738<h4 id="taskcompleted-decision-control">2739<h4 id="taskcompleted-decision-control">
2739 Control de decisiones de TaskCompleted2740 Control de decisiones de TaskCompleted
2742Los hooks TaskCompleted admiten dos formas de controlar la finalización de tareas:2743Los hooks TaskCompleted admiten dos formas de controlar la finalización de tareas:
2743 2744
2744* **Código de salida 2**: la tarea no se marca como completada y el mensaje de stderr se devuelve al modelo como retroalimentación.2745* **Código de salida 2**: la tarea no se marca como completada y el mensaje de stderr se devuelve al modelo como retroalimentación.
2745* **JSON `{"continue": false, "stopReason": "..."}`**: cuando el evento lo activó un compañero que terminaba su turno, detiene al compañero por completo, igual que el comportamiento del hook `Stop`. El `stopReason` se muestra al usuario. Cuando el evento lo activó la herramienta `TaskUpdate`, Claude Code ignora `continue: false`; el código de salida 2 sigue bloqueando la finalización.2746* **JSON `{"continue": false, "stopReason": "..."}`**: cuando el evento lo activó un compañero que terminaba su turno, detiene por completo al compañero, igual que el comportamiento del hook `Stop`. El `stopReason` se muestra al usuario. Cuando el evento lo activó la herramienta `TaskUpdate`, Claude Code ignora `continue: false`; el código de salida 2 sigue bloqueando la finalización.
2746 2747
2747Este ejemplo ejecuta pruebas y bloquea la finalización de la tarea si fallan:2748Este ejemplo ejecuta pruebas y bloquea la finalización de la tarea si fallan:
2748 2749
2765</h3>2766</h3>
2766 2767
2767Se ejecuta cuando el agente principal de Claude Code terminó de responder. No se ejecuta si2768Se ejecuta cuando el agente principal de Claude Code terminó de responder. No se ejecuta si
2768la detención se produjo por una interrupción del usuario. Los errores de la API activan2769la detención se produjo por una interrupción del usuario. Los errores de API activan
2769[StopFailure](#stopfailure) en su lugar.2770[StopFailure](#stopfailure) en su lugar.
2770 2771
2771<Tip>2772<Tip>
2776 Entrada de Stop2777 Entrada de Stop
2777</h4>2778</h4>
2778 2779
2779Además de los [campos de entrada comunes](#common-input-fields), los hooks Stop reciben `stop_hook_active`, `last_assistant_message`, `background_tasks` y `session_crons`. El campo `stop_hook_active` es `true` cuando Claude Code ya está continuando como resultado de un hook de detención. Comprueba este valor o procesa la transcripción para evitar bloquear por una condición que nunca se resolverá.2780Además de los [campos de entrada comunes](#common-input-fields), los hooks Stop reciben `stop_hook_active`, `last_assistant_message`, `background_tasks` y `session_crons`. El campo `stop_hook_active` es `true` cuando Claude Code ya está continuando como resultado de un hook Stop. Comprueba este valor o procesa la transcripción para evitar bloquear en una condición que nunca se resolverá.
2780 2781
2781Claude Code aplica un límite de 8 continuaciones consecutivas: después de que los hooks de detención hayan continuado el turno ocho veces seguidas, Claude Code sobrescribe el siguiente bloqueo y termina el turno. El conteo de continuaciones consecutivas se reinicia cada vez que Claude llama a una herramienta. Para aumentar el límite, establece [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/es/env-vars).2782Claude Code aplica un límite de 8 continuaciones consecutivas: después de que los hooks Stop hayan continuado el turno ocho veces seguidas, Claude Code sobrescribe el siguiente bloqueo y termina el turno. El conteo de continuaciones consecutivas se reinicia cada vez que Claude llama a una herramienta. Para aumentar el límite, establece [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/es/env-vars).
2782 2783
2783El campo `last_assistant_message` contiene el contenido de texto de la respuesta final de Claude, para que los hooks puedan acceder a él sin analizar el archivo de transcripción. Para los hooks que actúan sobre el turno recién completado, como los hooks de lectura en voz alta o de notificación, usa este campo en lugar de leer `transcript_path`: no se garantiza que el archivo de transcripción incluya el mensaje final en el momento de Stop en todas las versiones.2784El campo `last_assistant_message` contiene el contenido de texto de la respuesta final de Claude, para que los hooks puedan acceder a él sin analizar el archivo de transcripción. Para los hooks que actúan sobre el turno recién completado, como los hooks de lectura en voz alta o de notificación, usa este campo en lugar de leer `transcript_path`: no se garantiza que el archivo de transcripción incluya el mensaje final en el momento de Stop en todas las versiones.
2784 2785
2785Los arreglos `background_tasks` y `session_crons` permiten a los hooks distinguir entre "la sesión terminó" y "la sesión está en pausa esperando que un trabajo en segundo plano la reactive". Ambos arreglos están presentes cuando el registro de tareas es accesible y están vacíos cuando no hay nada en curso ni programado.2786Los arrays `background_tasks` y `session_crons` permiten a los hooks distinguir entre "la sesión terminó" y "la sesión está en pausa esperando a que un trabajo en segundo plano la reactive". Ambos arrays están presentes cuando el registro de tareas es accesible y están vacíos cuando no hay nada en curso ni programado.
2786 2787
2787Cada entrada de `background_tasks` describe una tarea en curso y usa estos campos:2788Cada entrada de `background_tasks` describe una tarea en curso y usa estos campos:
2788 2789
2789| Campo | Descripción |2790| Campo | Descripción |
2790| :- | :- |2791| :- | :- |
2791| `id` | Identificador de la tarea |2792| `id` | Identificador de la tarea |
2792| `type` | Etiqueta legible del tipo de tarea, como `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session` o `MCP task`. Cada etiqueta identifica qué función de Claude Code creó la tarea. Recurre al discriminante sin procesar para tipos no reconocidos |2793| `type` | Etiqueta legible del tipo de tarea, como `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session` o `MCP task`. Cada etiqueta identifica qué función de Claude Code creó la tarea. Recurre al discriminante sin procesar para los tipos no reconocidos |
2793| `status` | Estado actual de la tarea |2794| `status` | Estado actual de la tarea |
2794| `description` | Descripción de texto libre, limitada a 1000 caracteres con un marcador `… [+N chars]` dentro de la cadena cuando se recorta |2795| `description` | Descripción en texto libre, limitada a 1000 caracteres con un marcador `… [+N chars]` dentro de la cadena cuando se recorta |
2795| `command` | Línea de comando del shell, limitada a 1000 caracteres. Presente solo para tareas `shell` |2796| `command` | Línea de comando del shell, limitada a 1000 caracteres. Solo está presente para tareas `shell` |
2796| `agent_type` | Nombre del tipo de subagente. Presente solo para tareas `subagent` |2797| `agent_type` | Nombre del tipo de subagente. Solo está presente para tareas `subagent` |
2797| `server` | Nombre del servidor MCP. Presente solo para tareas `monitor` y `MCP task` |2798| `server` | Nombre del servidor MCP. Solo está presente para tareas `monitor` y `MCP task` |
2798| `tool` | Nombre de la herramienta MCP. Presente solo para tareas `monitor` y `MCP task` |2799| `tool` | Nombre de la herramienta MCP. Solo está presente para tareas `monitor` y `MCP task` |
2799| `name` | Nombre del workflow. Presente solo para tareas `workflow` |2800| `name` | Nombre del workflow. Solo está presente para tareas `workflow` |
2800 2801
2801Cada entrada de `session_crons` describe una reactivación programada con ámbito de sesión, procedente de `CronCreate`, `ScheduleWakeup` y `/loop`:2802Cada entrada de `session_crons` describe una reactivación programada con ámbito de sesión, proveniente de `CronCreate`, `ScheduleWakeup` y `/loop`:
2802 2803
2803| Campo | Descripción |2804| Campo | Descripción |
2804| :- | :- |2805| :- | :- |
2805| `id` | Identificador de la tarea cron |2806| `id` | Identificador de la tarea cron |
2806| `schedule` | Expresión cron, por ejemplo `0 9 * * 1-5` |2807| `schedule` | Expresión cron, por ejemplo `0 9 * * 1-5` |
2807| `recurring` | `false` para reactivaciones únicas cuya programación codifica un solo momento de activación, `true` para tareas que se vuelven a activar en cada coincidencia |2808| `recurring` | `false` para reactivaciones únicas cuya programación codifica una sola hora de activación, `true` para tareas que se vuelven a activar en cada coincidencia |
2808| `prompt` | Prompt enviado cuando se activa el cron, limitado a 1000 caracteres con el mismo marcador `… [+N chars]` |2809| `prompt` | Prompt que se envía cuando se activa el cron, limitado a 1000 caracteres con el mismo marcador `… [+N chars]` |
2809 2810
2810Este ejemplo muestra una entrada de Stop con una tarea de shell en curso y un cron recurrente:2811Este ejemplo muestra una entrada de Stop con una tarea de shell en curso y un cron recurrente:
2811 2812
2848| :- | :- |2849| :- | :- |
2849| `decision` | `"block"` impide que Claude se detenga. Omítelo para permitir que Claude se detenga |2850| `decision` | `"block"` impide que Claude se detenga. Omítelo para permitir que Claude se detenga |
2850| `reason` | Obligatorio cuando `decision` es `"block"`. Le indica a Claude por qué debe continuar |2851| `reason` | Obligatorio cuando `decision` es `"block"`. Le indica a Claude por qué debe continuar |
2851| `hookSpecificOutput.additionalContext` | Retroalimentación para Claude que no es de error. La conversación continúa para que Claude pueda actuar en consecuencia, pero a diferencia de `decision: "block"` se muestra en la transcripción como retroalimentación del hook en lugar de como un error del hook |2852| `hookSpecificOutput.additionalContext` | Retroalimentación para Claude que no es de error. La conversación continúa para que Claude pueda actuar en consecuencia, pero, a diferencia de `decision: "block"`, se muestra en la transcripción como retroalimentación del hook y no como un error del hook |
2852 2853
2853Un hook que bloquea al terminar con código 2 se enruta igual que `reason`: Claude recibe el mensaje de stderr como la explicación de por qué debe continuar.2854Un hook que bloquea saliendo con código 2 se enruta de la misma forma que `reason`: Claude recibe el mensaje de stderr como la explicación de por qué debe continuar.
2854 2855
2855```json theme={null}2856```json theme={null}
2856{2857{
2859}2860}
2860```2861```
2861 2862
2862Usa `additionalContext` cuando el hook funciona según lo previsto y le da orientación a Claude, como "ejecuta el conjunto de pruebas antes de terminar". Mantiene la conversación en marcha a través de las mismas protecciones contra bucles que `decision: "block"`, es decir, la entrada `stop_hook_active` y el límite de 8 continuaciones consecutivas, pero la transcripción lo etiqueta como `Stop hook feedback` y no se muestra ninguna notificación de error del hook:2863Usa `additionalContext` cuando el hook funciona según lo diseñado y le da orientación a Claude, como "ejecuta el conjunto de pruebas antes de terminar". Mantiene la conversación en marcha a través de las mismas protecciones contra bucles que `decision: "block"`, es decir, la entrada `stop_hook_active` y el límite de 8 continuaciones consecutivas, pero la transcripción lo etiqueta como `Stop hook feedback` y no se muestra ninguna notificación de error del hook:
2863 2864
2864```json theme={null}2865```json theme={null}
2865{2866{
2874 StopFailure2875 StopFailure
2875</h3>2876</h3>
2876 2877
2877Se ejecuta en lugar de [Stop](#stop) cuando el turno termina debido a un error de la API. Claude Code ignora la salida y el código de salida del hook, excepto [`terminalSequence`](#emit-terminal-notifications). Úsalo para registrar fallas, enviar alertas o tomar medidas de recuperación cuando Claude no puede completar una respuesta debido a rate limits, problemas de autenticación u otros errores de la API.2878Se ejecuta en lugar de [Stop](#stop) cuando el turno termina debido a un error de API. Claude Code ignora la salida y el código de salida del hook, salvo [`terminalSequence`](#emit-terminal-notifications). Úsalo para registrar fallos, enviar alertas o tomar acciones de recuperación cuando Claude no puede completar una respuesta debido a rate limits, problemas de autenticación u otros errores de API.
2878 2879
2879<h4 id="stopfailure-input">2880<h4 id="stopfailure-input">
2880 Entrada de StopFailure2881 Entrada de StopFailure
2906 TeammateIdle2907 TeammateIdle
2907</h3>2908</h3>
2908 2909
2909Se ejecuta cuando un compañero de un [equipo de agentes](/docs/es/agent-teams) está a punto de quedar inactivo después de terminar su turno. Úsalo para aplicar controles de calidad antes de que un compañero deje de trabajar, como exigir que pasen las verificaciones de lint o verificar que existan los archivos de salida.2910Se ejecuta cuando un compañero de un [equipo de agentes](/docs/es/agent-teams) está a punto de quedar inactivo después de terminar su turno. Úsalo para aplicar controles de calidad antes de que un compañero deje de trabajar, como exigir que pasen las verificaciones de lint o comprobar que existan los archivos de salida.
2910 2911
2911Los hooks TeammateIdle no admiten matchers y se activan en cada ocurrencia.2912Los hooks TeammateIdle no admiten matchers y se activan en cada ocurrencia.
2912 2913
2932| :- | :- |2933| :- | :- |
2933| `teammate_name` | Nombre del compañero que está a punto de quedar inactivo |2934| `teammate_name` | Nombre del compañero que está a punto de quedar inactivo |
2934| `team_name` | Obsoleto. Nombre del equipo derivado de la sesión; se eliminará en una versión futura |2935| `team_name` | Obsoleto. Nombre del equipo derivado de la sesión; se eliminará en una versión futura |
2936| `agent_id` | En este evento, el [campo de entrada común](#common-input-fields) identifica al [compañero en proceso](/docs/es/agent-teams#choose-a-display-mode) que está a punto de quedar inactivo. Puede estar ausente. Requiere Claude Code v2.1.290 o posterior |
2935 2937
2936<h4 id="teammateidle-decision-control">2938<h4 id="teammateidle-decision-control">
2937 Control de decisiones de TeammateIdle2939 Control de decisiones de TeammateIdle
2940Los hooks TeammateIdle admiten dos formas de controlar el comportamiento del compañero:2942Los hooks TeammateIdle admiten dos formas de controlar el comportamiento del compañero:
2941 2943
2942* **Código de salida 2**: el compañero recibe el mensaje de stderr como retroalimentación y sigue trabajando en lugar de quedar inactivo.2944* **Código de salida 2**: el compañero recibe el mensaje de stderr como retroalimentación y sigue trabajando en lugar de quedar inactivo.
2943* **JSON `{"continue": false, "stopReason": "..."}`**: detiene al compañero por completo, igual que el comportamiento del hook `Stop`. El `stopReason` se muestra al usuario.2945* **JSON `{"continue": false, "stopReason": "..."}`**: detiene por completo al compañero, igual que el comportamiento del hook `Stop`. El `stopReason` se muestra al usuario.
2944 2946
2945Este ejemplo verifica que exista un artefacto de compilación antes de permitir que un compañero quede inactivo:2947Este ejemplo comprueba que exista un artefacto de compilación antes de permitir que un compañero quede inactivo:
2946 2948
2947```bash theme={null}2949```bash theme={null}
2948#!/bin/bash2950#!/bin/bash
2959 ConfigChange2961 ConfigChange
2960</h3>2962</h3>
2961 2963
2962Se ejecuta cuando un archivo de configuración cambia durante una sesión. Úsalo para auditar cambios de configuración, aplicar políticas de seguridad o bloquear modificaciones no autorizadas a los archivos de configuración.2964Se ejecuta cuando un archivo de configuración cambia durante una sesión. Úsalo para auditar cambios de configuración, aplicar políticas de seguridad o bloquear modificaciones no autorizadas de los archivos de configuración.
2963 2965
2964Claude Code ejecuta los hooks ConfigChange cuando cambia un archivo de configuración, un archivo de política administrada o un archivo de skill. Para la política administrada, solo los ejecuta cuando cambia `managed-settings.json` o un archivo en `managed-settings.d/`. Aplica la [configuración administrada por el servidor](/docs/es/server-managed-settings) y los cambios en las preferencias administradas de macOS o en la política del registro de Windows sin ejecutarlos. En WSL con [`wslInheritsWindowsSettings`](/docs/es/settings-reference#wslinheritswindowssettings), también aplica un archivo de configuración administrada del lado de Windows que cambió en su sondeo de políticas sin ejecutarlos.2966Claude Code ejecuta los hooks ConfigChange cuando cambia un archivo de configuración, un archivo de política administrada o un archivo de skill. Para la política administrada, solo los ejecuta cuando cambia `managed-settings.json` o un archivo en `managed-settings.d/`. Aplica la [configuración administrada por el servidor](/docs/es/server-managed-settings) y los cambios en las preferencias administradas de macOS o en la política del registro de Windows sin ejecutarlos. En WSL con [`wslInheritsWindowsSettings`](/docs/es/settings-reference#wslinheritswindowssettings), también aplica un archivo de configuración administrada del lado de Windows que haya cambiado en su sondeo de políticas sin ejecutarlos.
2965 2967
2966El matcher filtra según el origen de la configuración:2968El matcher filtra por el origen de la configuración:
2967 2969
2968| Matcher | Cuándo se activa |2970| Matcher | Cuándo se activa |
2969| :- | :- |2971| :- | :- |
2973| `policy_settings` | Cambia `managed-settings.json` o un archivo en `managed-settings.d/` |2975| `policy_settings` | Cambia `managed-settings.json` o un archivo en `managed-settings.d/` |
2974| `skills` | Cambia un archivo de skill en `.claude/skills/` |2976| `skills` | Cambia un archivo de skill en `.claude/skills/` |
2975 2977
2976Este ejemplo registra todos los cambios de configuración para auditorías de seguridad:2978Este ejemplo registra todos los cambios de configuración para auditoría de seguridad:
2977 2979
2978```json theme={null}2980```json theme={null}
2979{2981{
2997 Entrada de ConfigChange2999 Entrada de ConfigChange
2998</h4>3000</h4>
2999 3001
3000Además de los [campos de entrada comunes](#common-input-fields), los hooks ConfigChange reciben `source` y, opcionalmente, `file_path`. El campo `source` indica qué tipo de configuración cambió, y `file_path` proporciona la ruta del archivo específico que se modificó.3002Además de los [campos de entrada comunes](#common-input-fields), los hooks ConfigChange reciben `source` y, opcionalmente, `file_path`. El campo `source` indica qué tipo de configuración cambió, y `file_path` proporciona la ruta al archivo específico que se modificó.
3001 3003
3002```json theme={null}3004```json theme={null}
3003{3005{
3030 3032
3031Los cambios de `policy_settings` no se pueden bloquear. Los hooks siguen activándose para los orígenes `policy_settings` cuando cambia un archivo de configuración administrada en la máquina, así que puedes usarlos para registrar esas ediciones, pero cualquier decisión de bloqueo se ignora. Esto garantiza que la configuración administrada por la empresa siempre surta efecto. Claude Code no ejecuta hooks `ConfigChange` cuando llega o se actualiza la [configuración administrada por el servidor](/docs/es/server-managed-settings).3033Los cambios de `policy_settings` no se pueden bloquear. Los hooks siguen activándose para los orígenes `policy_settings` cuando cambia un archivo de configuración administrada en la máquina, así que puedes usarlos para registrar esas ediciones, pero cualquier decisión de bloqueo se ignora. Esto garantiza que la configuración administrada por la empresa siempre surta efecto. Claude Code no ejecuta hooks `ConfigChange` cuando llega o se actualiza la [configuración administrada por el servidor](/docs/es/server-managed-settings).
3032 3034
3033Claude Code actúa según la decisión de bloqueo de la salida JSON de un hook ConfigChange y descarta `systemMessage` y `continue`. Un cambio bloqueado no muestra ningún mensaje ni a ti ni a Claude, ya sea que bloquees con `reason` o con stderr y código de salida 2. Claude Code solo escribe una línea en el registro de depuración.3035Claude Code actúa según la decisión de bloqueo de la salida JSON de un hook ConfigChange y descarta `systemMessage` y `continue`. Un cambio bloqueado no muestra ningún mensaje ni a ti ni a Claude, ya sea que bloquees con `reason` o con stderr y el código de salida 2. Claude Code solo escribe una línea en el registro de depuración.
3034 3036
3035<h3 id="cwdchanged">3037<h3 id="cwdchanged">
3036 CwdChanged3038 CwdChanged
3037</h3>3039</h3>
3038 3040
3039Se ejecuta cuando un comando de shell en la conversación principal cambia el directorio de trabajo, por ejemplo cuando Claude ejecuta un comando `cd`. Úsalo para reaccionar a los cambios de directorio: recargar variables de entorno, activar cadenas de herramientas específicas del proyecto o ejecutar scripts de configuración automáticamente. Se combina con [FileChanged](#filechanged) para herramientas como [direnv](https://direnv.net/) que administran el entorno por directorio.3041Se ejecuta cuando un comando de shell en la conversación principal cambia el directorio de trabajo, por ejemplo cuando Claude ejecuta un comando `cd`. Úsalo para reaccionar a los cambios de directorio: recargar variables de entorno, activar toolchains específicas del proyecto o ejecutar scripts de configuración automáticamente. Se complementa con [FileChanged](#filechanged) para herramientas como [direnv](https://direnv.net/) que gestionan el entorno por directorio.
3040 3042
3041Los hooks CwdChanged tienen acceso a [`CLAUDE_ENV_FILE`](#persist-environment-variables). Las variables escritas en ese archivo persisten en los comandos Bash posteriores hasta el siguiente evento CwdChanged, cuando Claude Code las borra.3043Los hooks CwdChanged tienen acceso a [`CLAUDE_ENV_FILE`](#persist-environment-variables). Las variables escritas en ese archivo persisten en los comandos Bash posteriores hasta el siguiente evento CwdChanged, cuando Claude Code las borra.
3042 3044
3067 3069
3068| Campo | Descripción |3070| Campo | Descripción |
3069| :- | :- |3071| :- | :- |
3070| `watchPaths` | Arreglo de rutas absolutas. Reemplaza la lista de vigilancia dinámica actual. Las rutas de tu configuración de `matcher` siempre se vigilan. Devolver un arreglo vacío borra la lista dinámica, lo cual es habitual al entrar en un directorio nuevo |3072| `watchPaths` | Array de rutas absolutas. Reemplaza la lista de vigilancia dinámica actual. Las rutas de tu configuración de `matcher` siempre se vigilan. Devolver un array vacío borra la lista dinámica, lo que es típico al entrar en un directorio nuevo |
3071 3073
3072Los hooks CwdChanged no tienen control de decisiones. No pueden bloquear el cambio de directorio.3074Los hooks CwdChanged no tienen control de decisiones. No pueden bloquear el cambio de directorio.
3073 3075
3085* Agregas un directorio en la pestaña Workspace de `/permissions`3087* Agregas un directorio en la pestaña Workspace de `/permissions`
3086* Agregas un directorio que ya es un directorio de trabajo o que está dentro de uno3088* Agregas un directorio que ya es un directorio de trabajo o que está dentro de uno
3087 3089
3088Claude Code activa DirectoryAdded después de actualizar el estado del sandbox y de los permisos, por lo que las herramientas en el sandbox ya ven el nuevo directorio cuando se ejecuta tu hook. Los comandos de los hooks en sí se ejecutan fuera del sandbox.3090Claude Code activa DirectoryAdded después de actualizar el estado del sandbox y de los permisos, por lo que las herramientas en el sandbox ya ven el nuevo directorio cuando se ejecuta tu hook. Los propios comandos del hook se ejecutan fuera del sandbox.
3089 3091
3090Claude Code no espera al hook: la adición se completa inmediatamente y el hook se ejecuta en segundo plano con el tiempo de espera predeterminado de 600 segundos.3092Claude Code no espera al hook: la adición se completa inmediatamente y el hook se ejecuta en segundo plano con el tiempo de espera predeterminado de 600 segundos.
3091 3093
3118}3120}
3119```3121```
3120 3122
3121Los hooks DirectoryAdded no tienen control de decisiones. No pueden bloquear la adición, que ya se completó cuando se ejecuta el hook. Claude Code descarta el campo `continue` de su salida JSON y presenta el resto de forma diferente según el origen:3123Los hooks DirectoryAdded no tienen control de decisiones. No pueden bloquear la adición, que ya se completó cuando se ejecuta el hook. Claude Code descarta el campo `continue` de su salida JSON y muestra el resto de forma diferente según el origen:
3122 3124
3123* `slash_command`: Claude Code entrega el `systemMessage` del hook a Claude como contexto en el siguiente turno de la conversación, en lugar de mostrártelo a ti. En la transcripción aparece un recuento de hooks fallidos. La salida completa de las fallas va al registro de depuración3125* `slash_command`: Claude Code entrega el `systemMessage` del hook a Claude como contexto en el siguiente turno de la conversación, en lugar de mostrártelo a ti. En la transcripción aparece un recuento de los hooks fallidos. La salida completa del fallo va al registro de depuración
3124* `register_repo_root`: Claude Code escribe la salida de `systemMessage` y la salida de las fallas solo en el registro de depuración3126* `register_repo_root`: Claude Code escribe la salida de `systemMessage` y la salida de fallos solo en el registro de depuración
3125 3127
3126<h3 id="filechanged">3128<h3 id="filechanged">
3127 FileChanged3129 FileChanged
3128</h3>3130</h3>
3129 3131
3130Se ejecuta cuando un archivo vigilado cambia en disco. Claude Code detecta los cambios con un observador del sistema de archivos, no inspeccionando las llamadas a herramientas, por lo que ejecuta el hook sin importar qué cambió el archivo: una llamada a la herramienta `Edit` o `Write`, un script que Claude ejecuta con `Bash` o un proceso completamente ajeno a Claude Code. Un uso común es recargar variables de entorno cuando cambian los archivos de configuración del proyecto.3132Se ejecuta cuando un archivo vigilado cambia en el disco. Claude Code detecta los cambios con un observador del sistema de archivos, no inspeccionando las llamadas a herramientas, así que ejecuta el hook sin importar qué cambió el archivo: una llamada a las herramientas `Edit` o `Write`, un script que Claude ejecuta con `Bash` o un proceso completamente ajeno a Claude Code. Un uso común es recargar variables de entorno cuando cambian los archivos de configuración del proyecto.
3131 3133
3132El `matcher` de este evento cumple dos funciones:3134El `matcher` de este evento cumple dos funciones:
3133 3135
3134* **Construir la lista de vigilancia**: el valor se divide por `|` y cada segmento se registra como un nombre de archivo literal en el directorio de trabajo, así que `".envrc|.env"` vigila exactamente esos dos archivos. Los patrones de expresiones regulares no sirven aquí: un valor como `^\.env` vigilaría un archivo llamado literalmente `^\.env`.3136* **Construir la lista de vigilancia**: el valor se divide por `|` y cada segmento se registra como un nombre de archivo literal en el directorio de trabajo, así que `".envrc|.env"` vigila exactamente esos dos archivos. Los patrones de expresiones regulares no son útiles aquí: un valor como `^\.env` vigilaría un archivo llamado literalmente `^\.env`.
3135* **Filtrar qué hooks se ejecutan**: cuando cambia un archivo vigilado, el mismo valor filtra qué grupos de hooks se ejecutan usando las [reglas de matcher](#matcher-patterns) estándar contra el nombre base del archivo que cambió.3137* **Filtrar qué hooks se ejecutan**: cuando un archivo vigilado cambia, el mismo valor filtra qué grupos de hooks se ejecutan usando las [reglas estándar de matcher](#matcher-patterns) contra el nombre base del archivo modificado.
3136 3138
3137Este ejemplo normaliza los finales de línea en `data.csv` después de cualquier cambio, incluido un comando `Bash` o un script externo que reescribe el archivo:3139Este ejemplo normaliza los finales de línea en `data.csv` después de cualquier cambio, incluido un comando `Bash` o un script externo que reescriba el archivo:
3138 3140
3139```json theme={null}3141```json theme={null}
3140{3142{
3154}3156}
3155```3157```
3156 3158
3157El hook lee la ruta absoluta del archivo que cambió del campo `file_path` de la [entrada JSON](#filechanged-input) en stdin. Su verificación con `grep` comprueba lo mismo que elimina `perl`, un CR al final de una línea, así que la ejecución posterior a una normalización termina sin tocar el archivo. Una verificación más laxa entra en un bucle infinito, porque `perl -i` reescribe el archivo incluso cuando no sustituye nada y Claude Code vuelve a ejecutar el hook después de cada reescritura. Guarda este script en `/path/to/normalize-line-endings.sh` y hazlo ejecutable:3159El hook lee la ruta absoluta del archivo modificado desde el campo `file_path` de la [entrada JSON](#filechanged-input) en stdin. Su guarda `grep` comprueba lo mismo que elimina `perl`, un CR al final de una línea, de modo que la ejecución posterior a una normalización termina sin tocar el archivo. Una guarda más laxa entra en un bucle infinito, porque `perl -i` reescribe el archivo incluso cuando no sustituye nada y Claude Code vuelve a ejecutar el hook después de cada reescritura. Guarda este script en `/path/to/normalize-line-endings.sh` y hazlo ejecutable:
3158 3160
3159```bash theme={null}3161```bash theme={null}
3160#!/bin/bash3162#!/bin/bash
3164fi3166fi
3165```3167```
3166 3168
3167Para confirmar que el hook funciona, pídele a Claude que agregue una línea CRLF a `data.csv` con un comando `Bash`. Claude Code ejecuta el hook y el archivo termina con finales de línea LF.3169Para confirmar que el hook funciona, pídele a Claude que agregue una línea CRLF a `data.csv` con un comando `Bash`. Claude Code ejecuta el hook y el archivo termina con finales LF.
3168 3170
3169Para vigilar archivos que no puedes nombrar de antemano, devuelve [`watchPaths`](#filechanged-output) desde un hook para actualizar la lista de vigilancia dinámicamente. Claude Code inicia el observador solo cuando algo nombra un archivo que vigilar, así que inicializa la lista con un grupo FileChanged cuyo matcher nombre al menos un archivo, o con un hook [SessionStart](#sessionstart-decision-control) o [CwdChanged](#cwdchanged) que devuelva `watchPaths`. El matcher sigue filtrando qué grupos de hooks se ejecutan cuando cambia un archivo vigilado, así que deja sin matcher el grupo que maneja las rutas dinámicas: así coincide con todos los archivos vigilados y no agrega nada a la lista de vigilancia. Un matcher `"*"` también coincide con todos los archivos, pero Claude Code lo registra en la lista de vigilancia como cualquier otro valor, como un archivo literal llamado `*`.3171Para vigilar archivos que no puedes nombrar de antemano, devuelve [`watchPaths`](#filechanged-output) desde un hook para actualizar la lista de vigilancia dinámicamente. Claude Code inicia el observador solo cuando algo nombra un archivo que vigilar, así que inicializa la lista con un grupo FileChanged cuyo matcher nombre al menos un archivo, o con un hook [SessionStart](#sessionstart-decision-control) o [CwdChanged](#cwdchanged) que devuelva `watchPaths`. El matcher sigue filtrando qué grupos de hooks se ejecutan cuando cambia un archivo vigilado, así que deja sin matcher el grupo que gestiona las rutas dinámicas: así coincide con todos los archivos vigilados y no agrega nada a la lista de vigilancia. Un matcher `"*"` también coincide con todos los archivos, pero Claude Code lo registra en la lista de vigilancia como cualquier otro valor, como un archivo literal llamado `*`.
3170 3172
3171Los hooks FileChanged tienen acceso a [`CLAUDE_ENV_FILE`](#persist-environment-variables). Las variables escritas en ese archivo persisten en los comandos Bash posteriores hasta el siguiente evento [CwdChanged](#cwdchanged), cuando Claude Code las borra.3173Los hooks FileChanged tienen acceso a [`CLAUDE_ENV_FILE`](#persist-environment-variables). Las variables escritas en ese archivo persisten en los comandos Bash posteriores hasta el siguiente evento [CwdChanged](#cwdchanged), cuando Claude Code las borra.
3172 3174
3178 3180
3179| Campo | Descripción |3181| Campo | Descripción |
3180| :- | :- |3182| :- | :- |
3181| `file_path` | Ruta absoluta del archivo que cambió |3183| `file_path` | Ruta absoluta al archivo que cambió |
3182| `event` | Qué ocurrió: `"change"` para un archivo modificado, `"add"` para un archivo creado o `"unlink"` para un archivo eliminado |3184| `event` | Qué ocurrió: `"change"` para un archivo modificado, `"add"` para un archivo creado o `"unlink"` para un archivo eliminado |
3183 3185
3184```json theme={null}3186```json theme={null}
3200 3202
3201| Campo | Descripción |3203| Campo | Descripción |
3202| :- | :- |3204| :- | :- |
3203| `watchPaths` | Arreglo de rutas absolutas. Reemplaza la lista de vigilancia dinámica actual. Las rutas de tu configuración de `matcher` siempre se vigilan. Úsalo cuando tu script de hook descubra archivos adicionales que vigilar en función del archivo que cambió |3205| `watchPaths` | Array de rutas absolutas. Reemplaza la lista de vigilancia dinámica actual. Las rutas de tu configuración de `matcher` siempre se vigilan. Úsalo cuando tu script de hook descubra archivos adicionales que vigilar en función del archivo modificado |
3204 3206
3205Los hooks FileChanged no tienen control de decisiones. No pueden impedir que se produzca el cambio del archivo.3207Los hooks FileChanged no tienen control de decisiones. No pueden impedir que se produzca el cambio del archivo.
3206 3208
3210 WorktreeCreate3212 WorktreeCreate
3211</h3>3213</h3>
3212 3214
3213Se ejecuta cuando se está creando un worktree, ya sea desde `claude --worktree`, desde un [subagente que usa `isolation: "worktree"`](/docs/es/sub-agents#choose-the-subagent-scope) o para una [sesión en segundo plano](/docs/es/agent-view#how-file-edits-are-isolated) que Claude Code aísla en su propio worktree. De forma predeterminada, Claude Code crea la copia de trabajo aislada con `git worktree`. Configurar un hook WorktreeCreate reemplaza ese comportamiento predeterminado de git, lo que te permite usar un sistema de control de versiones diferente, como SVN, Perforce o Mercurial.3215Se ejecuta cuando se está creando un worktree, ya sea desde `claude --worktree`, desde un [subagente que usa `isolation: "worktree"`](/docs/es/sub-agents#choose-the-subagent-scope), o para una [sesión en segundo plano](/docs/es/agent-view#how-file-edits-are-isolated) que Claude Code aísla en su propio worktree. De forma predeterminada, Claude Code crea la copia de trabajo aislada con `git worktree`. Configurar un hook WorktreeCreate reemplaza ese comportamiento predeterminado de git, lo que te permite usar un sistema de control de versiones diferente como SVN, Perforce o Mercurial.
3214 3216
3215Como el hook reemplaza por completo el comportamiento predeterminado, [`.worktreeinclude`](/docs/es/worktrees#copy-gitignored-files-into-worktrees) no se procesa. Si necesitas copiar archivos de configuración locales como `.env` en el nuevo worktree, hazlo dentro de tu script de hook.3217Como el hook reemplaza por completo el comportamiento predeterminado, [`.worktreeinclude`](/docs/es/worktrees#copy-gitignored-files-into-worktrees) no se procesa. Si necesitas copiar archivos de configuración locales como `.env` al nuevo worktree, hazlo dentro de tu script del hook.
3216 3218
3217El hook debe devolver la ruta del directorio del worktree creado. Claude Code usa esta ruta como directorio de trabajo para la sesión aislada. Consulta [Salida de WorktreeCreate](#worktreecreate-output) para ver cómo devuelve la ruta cada tipo de hook.3219El hook debe devolver la ruta al directorio del worktree creado. Claude Code usa esta ruta como directorio de trabajo para la sesión aislada. Consulta [Salida de WorktreeCreate](#worktreecreate-output) para ver cómo cada tipo de hook devuelve la ruta.
3218 3220
3219Claude Code actúa según el éxito del hook y la ruta devuelta, y descarta `systemMessage` y `continue`.3221Claude Code actúa según el éxito del hook y la ruta devuelta, y descarta `systemMessage` y `continue`.
3220 3222
3237}3239}
3238```3240```
3239 3241
3240El hook lee el `name` del worktree de la entrada JSON en stdin, extrae una copia nueva en un directorio nuevo e imprime la ruta del directorio. El `echo` de la última línea es lo que Claude Code lee como la ruta del worktree. Redirige cualquier otra salida a stderr para que no interfiera con la ruta.3242El hook lee el `name` del worktree desde la entrada JSON en stdin, extrae una copia nueva en un directorio nuevo e imprime la ruta del directorio. El `echo` de la última línea es lo que Claude Code lee como la ruta del worktree. Redirige cualquier otra salida a stderr para que no interfiera con la ruta.
3241 3243
3242<h4 id="worktreecreate-input">3244<h4 id="worktreecreate-input">
3243 Entrada de WorktreeCreate3245 Entrada de WorktreeCreate
3244</h4>3246</h4>
3245 3247
3246Además de los [campos de entrada comunes](#common-input-fields), los hooks WorktreeCreate reciben el campo `name`. Es un identificador tipo slug para el nuevo worktree, especificado por el usuario o generado automáticamente, por ejemplo `bold-oak-a3f2`.3248Además de los [campos de entrada comunes](#common-input-fields), los hooks WorktreeCreate reciben el campo `name`. Es un identificador slug para el nuevo worktree, especificado por el usuario o generado automáticamente, por ejemplo `bold-oak-a3f2`.
3247 3249
3248```json theme={null}3250```json theme={null}
3249{3251{
3259 Salida de WorktreeCreate3261 Salida de WorktreeCreate
3260</h4>3262</h4>
3261 3263
3262Los hooks WorktreeCreate no usan el modelo estándar de decisión de permitir/bloquear. En su lugar, el éxito o el fallo del hook determina el resultado. El hook debe devolver la ruta al directorio del worktree creado:3264Los hooks WorktreeCreate no usan el modelo estándar de decisión de permitir/bloquear. En cambio, el éxito o fracaso del hook determina el resultado. El hook debe devolver la ruta al directorio del worktree creado:
3263 3265
3264* **Hooks de comando** (`type: "command"`): imprime la ruta como la última línea no vacía de stdout. Claude Code elimina los códigos de escape ANSI antes de leer esa línea, por lo que se ignoran los banners de inicio del shell impresos antes de tu `echo`. Redirige cualquier otra salida del hook a stderr.3266* **Hooks de comando** (`type: "command"`): imprime la ruta como la última línea no vacía de stdout. Claude Code elimina los códigos de escape ANSI antes de leer esa línea, por lo que los banners de inicio del shell impresos antes de tu `echo` se ignoran. Redirige cualquier otra salida del hook a stderr.
3265* **Hooks HTTP** (`type: "http"`): devuelve `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` en el cuerpo de la respuesta.3267* **Hooks HTTP** (`type: "http"`): devuelve `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` en el cuerpo de la respuesta.
3266 3268
3267Si el hook falla o no produce ninguna ruta, la creación del worktree falla con un error.3269Si el hook falla o no produce ninguna ruta, la creación del worktree falla con un error.
3268 3270
3269Claude Code resuelve una ruta relativa respecto al directorio en el que se ejecutó el hook, colapsando cualquier segmento `.` o `..` que contenga. Si la ruta resultante no es un directorio al que Claude Code pueda entrar, la sesión imprime un error que indica la ruta y termina con el código 1.3271Claude Code resuelve una ruta relativa con respecto al directorio en el que se ejecutó el hook, colapsando cualquier segmento `.` o `..` que contenga. Si la ruta resultante no es un directorio al que Claude Code pueda entrar, la sesión imprime un error que nombra la ruta y termina con el código 1.
3270 3272
3271Claude Code rechaza una ruta absoluta que contenga segmentos `.` o `..`, y cualquier ruta que pase por un enlace simbólico debajo de la raíz del repositorio, porque un enlace simbólico confirmado en el repositorio podría redirigir el worktree fuera de él. El error indica el componente rechazado. Devuelve una ruta normalizada que no pase por un enlace simbólico dentro del repositorio. Antes de v2.1.216, la creación del worktree seguía la ruta del hook sin esta verificación.3273Claude Code rechaza una ruta absoluta que contenga segmentos `.` o `..`, y cualquier ruta que pase por un enlace simbólico debajo de la raíz del repositorio, porque un enlace simbólico confirmado en el repositorio podría redirigir el worktree fuera de él. El error nombra el componente rechazado. Devuelve una ruta normalizada que no pase por un enlace simbólico dentro del repositorio. Antes de v2.1.216, la creación del worktree seguía la ruta del hook sin esta verificación.
3272 3274
3273<h3 id="worktreeremove">3275<h3 id="worktreeremove">
3274 WorktreeRemove3276 WorktreeRemove
3277Se ejecuta cuando Claude Code limpia un worktree que creó tu hook [`WorktreeCreate`](#worktreecreate). El evento se activa cuando:3279Se ejecuta cuando Claude Code limpia un worktree que creó tu hook [`WorktreeCreate`](#worktreecreate). El evento se activa cuando:
3278 3280
3279* Sales de una [sesión de worktree](/docs/es/worktrees#start-claude-in-a-worktree) interactiva y eliges eliminar el worktree cuando Claude Code te lo pregunta3281* Sales de una [sesión de worktree](/docs/es/worktrees#start-claude-in-a-worktree) interactiva y eliges eliminar el worktree cuando Claude Code te lo pregunta
3280* Sales de una sesión de worktree interactiva a la que no has [puesto nombre](/docs/es/sessions#name-your-sessions), Claude Code no encuentra archivos modificados ni sin seguimiento y elimina el worktree sin preguntarte3282* Sales de una sesión de worktree interactiva a la que no le has [puesto nombre](/docs/es/sessions#name-your-sessions), Claude Code no encuentra archivos modificados ni sin seguimiento, y elimina el worktree sin preguntarte
3281* Eliminas una [sesión en segundo plano](/docs/es/agent-view#what-deleting-a-session-removes) que se ejecuta en el worktree3283* Eliminas una [sesión en segundo plano](/docs/es/agent-view#what-deleting-a-session-removes) que se ejecuta en el worktree
3282 3284
3283Claude Code usa git para buscar archivos modificados o sin seguimiento, así que no encuentra ninguno en un worktree que no sea un checkout de git ni esté dentro de uno, incluso cuando el directorio contiene trabajo sin confirmar. Comprueba si existe ese trabajo en tu hook WorktreeRemove antes de que elimine nada.3285Claude Code usa git para buscar archivos modificados o sin seguimiento, por lo que no encuentra ninguno en un worktree que no sea un checkout de git ni esté dentro de uno, incluso cuando el directorio contiene trabajo sin confirmar. Comprueba si existe ese trabajo en tu hook WorktreeRemove antes de que elimine cualquier cosa.
3284 3286
3285Para los worktrees basados en git, Claude Code se encarga de la limpieza automáticamente con `git worktree remove`. Si configuraste un hook WorktreeCreate, combínalo con un hook WorktreeRemove para controlar la limpieza de los worktrees que crea:3287Para los worktrees basados en git, Claude Code gestiona la limpieza automáticamente con `git worktree remove`. Si configuraste un hook WorktreeCreate, combínalo con un hook WorktreeRemove para controlar la limpieza de los worktrees que crea:
3286 3288
3287* **Sin hook WorktreeRemove**: cuando Claude Code elimina el worktree al salir de una sesión de worktree, recurre a `git worktree remove --force` sobre la ruta que devolvió tu hook WorktreeCreate, de modo que se elimina un worktree que git reconoce. Un worktree que git no reconoce, por ejemplo uno que tu hook creó con un sistema de control de versiones distinto de git, permanece en el disco. Para saber qué ocurre con un worktree creado por un hook al eliminar una [sesión en segundo plano](/docs/es/agent-view#what-deleting-a-session-removes), consulta las reglas de eliminación de la vista de agentes.3289* **Sin hook WorktreeRemove**: cuando Claude Code elimina el worktree al salir de una sesión de worktree, recurre a `git worktree remove --force` sobre la ruta que devolvió tu hook WorktreeCreate, por lo que se elimina un worktree que git reconoce. Un worktree que git no reconoce, por ejemplo uno que tu hook creó con un sistema de control de versiones que no es git, permanece en el disco. Para saber qué hace la eliminación de una [sesión en segundo plano](/docs/es/agent-view#what-deleting-a-session-removes) con un worktree creado por un hook, consulta las reglas de eliminación de la vista de agentes.
3288* **El hook termina con 0**: el worktree se considera eliminado. Claude Code no lee nada más del hook, así que asegúrate de que tu hook haya eliminado el directorio.3290* **El hook termina con 0**: el worktree se considera eliminado. Claude Code no lee nada más del hook, así que asegúrate de que tu hook haya eliminado el directorio.
3289* **El hook termina con un código distinto de cero**: la eliminación falla si el directorio en `worktree_path` sigue existiendo después, y el worktree permanece en el disco sin recurrir a git. Un hook que eliminó el directorio antes de terminar con un código distinto de cero se considera eliminado. Para saber cómo se informa el fallo, consulta [Entrada de WorktreeRemove](#worktreeremove-input).3291* **El hook termina con un código distinto de cero**: la eliminación falla si el directorio en `worktree_path` sigue existiendo después, y el worktree permanece en el disco sin recurrir a git. Un hook que eliminó el directorio antes de terminar con un código distinto de cero se considera eliminado. Para saber cómo se informa el fallo, consulta [Entrada de WorktreeRemove](#worktreeremove-input).
3290 3292
3292 3294
3293Claude Code descarta los [campos de salida JSON](#json-output) de un hook WorktreeRemove, como `systemMessage` y `continue`.3295Claude Code descarta los [campos de salida JSON](#json-output) de un hook WorktreeRemove, como `systemMessage` y `continue`.
3294 3296
3295Al eliminar una sesión en segundo plano, Claude Code verifica la ruta del worktree almacenada antes de ejecutar el hook y rechaza una ruta que sea un enlace simbólico o que pase por uno debajo de la raíz del repositorio. El hook se ejecuta para un worktree que todavía contiene archivos solo cuando confirmas la eliminación en [agent view](/docs/es/agent-view#what-deleting-a-session-removes); para ese tipo de worktree, [`claude rm`](/docs/es/agent-view#manage-sessions-from-the-shell) conserva la sesión y el worktree. Antes de v2.1.216, el hook se ejecutaba sobre la ruta almacenada sin estas comprobaciones.3297Al eliminar una sesión en segundo plano, Claude Code verifica la ruta del worktree almacenada antes de ejecutar el hook y rechaza una ruta que sea un enlace simbólico o que pase por uno debajo de la raíz del repositorio. El hook se ejecuta para un worktree que todavía contiene archivos solo cuando confirmas la eliminación en la [vista de agentes](/docs/es/agent-view#what-deleting-a-session-removes); para un worktree así, [`claude rm`](/docs/es/agent-view#manage-sessions-from-the-shell) conserva la sesión y el worktree. Antes de v2.1.216, el hook se ejecutaba sobre la ruta almacenada sin estas comprobaciones.
3296 3298
3297Claude Code pasa la ruta devuelta por WorktreeCreate como `worktree_path` en la entrada del hook. Este ejemplo lee esa ruta y elimina el directorio:3299Claude Code pasa la ruta devuelta por WorktreeCreate como `worktree_path` en la entrada del hook. Este ejemplo lee esa ruta y elimina el directorio:
3298 3300
3332El código de salida de un hook WorktreeRemove decide el resultado. Cuando un hook termina con un código distinto de cero y el directorio en `worktree_path` sigue existiendo después, la eliminación falla:3334El código de salida de un hook WorktreeRemove decide el resultado. Cuando un hook termina con un código distinto de cero y el directorio en `worktree_path` sigue existiendo después, la eliminación falla:
3333 3335
3334* El worktree permanece en el disco, y el comando del hook y su stderr van al [registro de depuración](#debug-hooks).3336* El worktree permanece en el disco, y el comando del hook y su stderr van al [registro de depuración](#debug-hooks).
3335* Si estabas eliminando una sesión en segundo plano, la sesión también permanece. El mensaje de rechazo en [agent view](/docs/es/agent-view#what-deleting-a-session-removes) informa cómo terminó el hook, como `exited 1`, cita el inicio de su stderr e indica si volver a eliminar la sesión elimina el directorio de todos modos.3337* Si estabas eliminando una sesión en segundo plano, la sesión también permanece. El mensaje de rechazo en la [vista de agentes](/docs/es/agent-view#what-deleting-a-session-removes) informa cómo terminó el hook, como `exited 1`, cita el inicio de su stderr e indica si volver a eliminar la sesión elimina el directorio de todos modos.
3336 3338
3337<h3 id="precompact">3339<h3 id="precompact">
3338 PreCompact3340 PreCompact
3342 3344
3343El valor del matcher indica si la compactación se activó de forma manual o automática:3345El valor del matcher indica si la compactación se activó de forma manual o automática:
3344 3346
3345| Matcher | Cuándo se dispara |3347| Matcher | Cuándo se activa |
3346| :- | :- |3348| :- | :- |
3347| `manual` | `/compact` |3349| `manual` | `/compact` |
3348| `auto` | Compactación automática cuando la conversación alcanza la [ventana de compactación automática](/docs/es/model-config#set-the-auto-compact-window) |3350| `auto` | Compactación automática cuando la conversación alcanza la [ventana de compactación automática](/docs/es/model-config#set-the-auto-compact-window) |
3349 3351
3350Termina con el código 2 para bloquear la compactación. Para un `/compact` manual, el mensaje de stderr se muestra al usuario. También puedes bloquear devolviendo JSON con `"decision": "block"`.3352Termina con el código 2 para bloquear la compactación. Para un `/compact` manual, el mensaje de stderr se muestra al usuario. También puedes bloquearla devolviendo JSON con `"decision": "block"`.
3351 3353
3352Bloquear la compactación automática tiene efectos distintos según cuándo se dispare. Si la compactación se activó de forma proactiva antes del límite de contexto, Claude Code la omite y la conversación continúa sin compactar. Si la compactación se activó para recuperarse de un error de límite de contexto ya devuelto por la API, el error subyacente aparece y la solicitud actual falla.3354Bloquear la compactación automática tiene efectos diferentes según cuándo se active. Si la compactación se activó de forma proactiva antes del límite de contexto, Claude Code la omite y la conversación continúa sin compactar. Si la compactación se activó para recuperarse de un error de límite de contexto ya devuelto por la API, el error subyacente aparece y la solicitud actual falla.
3353 3355
3354Claude Code descarta los campos `systemMessage` y `continue` de un hook PreCompact.3356Claude Code descarta los campos `systemMessage` y `continue` de un hook PreCompact.
3355 3357
3378 3380
3379Se aplican los mismos valores de matcher que para `PreCompact`:3381Se aplican los mismos valores de matcher que para `PreCompact`:
3380 3382
3381| Matcher | Cuándo se dispara |3383| Matcher | Cuándo se activa |
3382| :- | :- |3384| :- | :- |
3383| `manual` | Después de `/compact` |3385| `manual` | Después de `/compact` |
3384| `auto` | Después de la compactación automática cuando la conversación alcanza la [ventana de compactación automática](/docs/es/model-config#set-the-auto-compact-window) |3386| `auto` | Después de la compactación automática cuando la conversación alcanza la [ventana de compactación automática](/docs/es/model-config#set-the-auto-compact-window) |
3416* Activar el [modo rápido](/docs/es/fast-mode) cuando eso cambia el modelo de la sesión3418* Activar el [modo rápido](/docs/es/fast-mode) cuando eso cambia el modelo de la sesión
3417* Una solicitud `set_model`, o un cambio de modelo en una solicitud `apply_flag_settings`, desde un host del [Agent SDK](/docs/es/agent-sdk/typescript#query-object) o desde [Remote Control](/docs/es/remote-control)3419* Una solicitud `set_model`, o un cambio de modelo en una solicitud `apply_flag_settings`, desde un host del [Agent SDK](/docs/es/agent-sdk/typescript#query-object) o desde [Remote Control](/docs/es/remote-control)
3418 3420
3419Claude Code no ejecuta los hooks PreModelSwitch para los cambios que hace por su cuenta, como un [respaldo automático de modelo](/docs/es/model-config#automatic-model-fallback) o la restauración del modelo cuando reanudas una sesión. Esos cambios solo llegan a [PostModelSwitch](#postmodelswitch).3421Claude Code no ejecuta hooks PreModelSwitch para los cambios que realiza por su cuenta, como un [respaldo automático de modelo](/docs/es/model-config#automatic-model-fallback) o la restauración del modelo al reanudar una sesión. Esos cambios solo llegan a [PostModelSwitch](#postmodelswitch).
3420 3422
3421Claude Code compara el matcher con el nombre canónico del modelo al que cambia la sesión, ignorando cualquier sufijo `[1m]`. Un alias como `opus`, un ID de modelo con fecha y un ID específico de un proveedor, como un ID de modelo de Amazon Bedrock, coinciden todos con el único nombre canónico al que se resuelven, por lo que `claude-opus-5` cubre todas las formas de escribir Opus 5.3423Claude Code compara el matcher con el nombre canónico del modelo al que está cambiando la sesión, ignorando cualquier sufijo `[1m]`. Un alias como `opus`, un ID de modelo con fecha y un ID específico del proveedor, como un ID de modelo de Amazon Bedrock, coinciden todos con el único nombre canónico al que se resuelven, por lo que `claude-opus-5` cubre todas las formas de escribir Opus 5.
3422 3424
3423Cuando Claude Code no puede determinar un nombre canónico para el destino, por ejemplo un ID de modelo personalizado que solo conoce tu [gateway de LLM](/docs/es/llm-gateway), ejecuta todos los hooks PreModelSwitch sin importar el matcher. Por lo tanto, un hook que bloquea debe comprobar `to_model` en su entrada en lugar de depender solo del matcher.3425Cuando Claude Code no puede determinar un nombre canónico para el destino, por ejemplo un ID de modelo personalizado que solo conoce tu [gateway de LLM](/docs/es/llm-gateway), ejecuta todos los hooks PreModelSwitch sin importar el matcher. Por lo tanto, un hook que bloquea debe comprobar `to_model` en su entrada en lugar de depender solo del matcher.
3424 3426
3425Escribe el matcher como un nombre exacto, una lista separada por `|` como `claude-opus-4-6|claude-opus-5`, o una expresión regular como `.*opus.*`. Este ejemplo usa un matcher de nombre exacto y además comprueba `to_model` en la entrada del hook, de modo que rechaza un cambio a Opus 4.6 terminando con el código 2 y deja pasar cualquier otro destino:3427Escribe el matcher como un nombre exacto, una lista separada por `|` como `claude-opus-4-6|claude-opus-5`, o una expresión regular como `.*opus.*`. Este ejemplo usa un matcher de nombre exacto y también comprueba `to_model` en la entrada del hook, por lo que rechaza un cambio a Opus 4.6 terminando con el código 2 y deja pasar cualquier otro destino:
3426 3428
3427<Tabs>3429<Tabs>
3428 <Tab title="macOS/Linux">3430 <Tab title="macOS/Linux">
3448 </Tab>3450 </Tab>
3449 3451
3450 <Tab title="Windows (PowerShell)">3452 <Tab title="Windows (PowerShell)">
3451 Registra un hook de comando que ejecute un script mediante PowerShell:3453 Registra un hook de comando que ejecute un script a través de PowerShell:
3452 3454
3453 ```json theme={null}3455 ```json theme={null}
3454 {3456 {
3494 Entrada de PreModelSwitch3496 Entrada de PreModelSwitch
3495</h4>3497</h4>
3496 3498
3497Además de los [campos de entrada comunes](#common-input-fields), los hooks PreModelSwitch reciben los campos de esta tabla. Los últimos cinco describen lo que cuesta volver a enviar la conversación al nuevo modelo, de modo que un hook puede mostrar esa cifra antes de que ocurra el cambio.3499Además de los [campos de entrada comunes](#common-input-fields), los hooks PreModelSwitch reciben los campos de esta tabla. Los últimos cinco describen lo que cuesta volver a enviar la conversación al nuevo modelo, para que un hook pueda mostrar esa cifra antes de que ocurra el cambio.
3498 3500
3499| Campo | Tipo | Descripción |3501| Campo | Tipo | Descripción |
3500| :- | :- | :- |3502| :- | :- | :- |
3501| `from_model` | string | ID del modelo desde el que se cambia |3503| `from_model` | string | ID del modelo desde el que se realiza el cambio |
3502| `to_model` | string | ID del modelo al que se cambia. El matcher se compara con el nombre canónico de este modelo |3504| `to_model` | string | ID del modelo al que se realiza el cambio. El matcher se compara con el nombre canónico de este modelo |
3503| `requested_model` | string o `null` | El modelo que indicó la solicitud: un alias como `opus`, un ID de modelo completo, o `null` cuando la solicitud era para el modelo predeterminado |3505| `requested_model` | string o `null` | El modelo que nombró la solicitud: un alias como `opus`, un ID de modelo completo, o `null` cuando la solicitud era para el modelo predeterminado |
3504| `source` | string | De dónde vino la solicitud: `"command"` para `/model <name>`, el ajuste Model en `/config` o la activación del modo rápido; `"picker"` para un selector de modelo; `"sdk"` para una solicitud `set_model`, o un cambio de modelo en una solicitud `apply_flag_settings`, desde un host del Agent SDK o desde Remote Control |3506| `source` | string | De dónde vino la solicitud: `"command"` para `/model <name>`, el ajuste Model en `/config` o la activación del modo rápido; `"picker"` para un selector de modelo; `"sdk"` para una solicitud `set_model`, o un cambio de modelo en una solicitud `apply_flag_settings`, desde un host del Agent SDK o desde Remote Control |
3505| `context_tokens` | number | Tokens que la siguiente solicitud vuelve a enviar como su prompt: los tokens de entrada, de lectura de caché, de creación de caché y de salida de la última respuesta en la conversación principal, combinados. `0` antes de la primera respuesta |3507| `context_tokens` | number | Tokens que la siguiente solicitud vuelve a enviar como su prompt: la suma de los tokens de entrada, lectura de caché, creación de caché y salida de la última respuesta en la conversación principal. `0` antes de la primera respuesta |
3506| `prompt_cache_warm` | boolean | Si la caché de prompts del modelo actual probablemente sigue caliente, lo que significa que el cambio la pierde |3508| `prompt_cache_warm` | boolean | Si es probable que la caché de prompts del modelo actual siga activa, lo que significa que el cambio la pierde |
3507| `cache_ttl` | string | [Duración de la caché de prompts](/docs/es/prompt-caching#cache-lifetime) que Claude Code solicita para esta sesión: `"5m"` o `"1h"` |3509| `cache_ttl` | string | [Duración de la caché de prompts](/docs/es/prompt-caching#cache-lifetime) que Claude Code solicita para esta sesión: `"5m"` o `"1h"` |
3508| `estimated_cache_write_usd` | number | Costo estimado en dólares estadounidenses de escribir `context_tokens` en la caché de prompts de `to_model` a la tarifa de `cache_ttl`, sin incluir la siguiente respuesta. Es posible que el servidor no necesite volver a almacenar en caché todo el contexto, así que trátalo como una estimación |3510| `estimated_cache_write_usd` | number | Costo estimado en dólares estadounidenses de escribir `context_tokens` en la caché de prompts de `to_model` con la tarifa de `cache_ttl`, sin incluir la siguiente respuesta. Es posible que el servidor no necesite volver a almacenar en caché todo el contexto, así que trátalo como una estimación |
3509| `pricing` | string | Cómo calculó Claude Code el precio de `estimated_cache_write_usd`: `"configured"` con las tarifas propias de tu organización cuando las ha configurado, `"catalog"` con el precio de lista, o `"default"` cuando `to_model` no tiene un precio conocido y Claude Code asumió una tarifa predeterminada |3511| `pricing` | string | Cómo calculó Claude Code el precio de `estimated_cache_write_usd`: `"configured"` con las tarifas propias de tu organización cuando las ha configurado, `"catalog"` con el precio de lista, o `"default"` cuando `to_model` no tiene un precio conocido y Claude Code asumió una tarifa predeterminada |
3510 3512
3511Este ejemplo muestra la entrada para `/model opus` en una sesión que usa Sonnet 5:3513Este ejemplo muestra la entrada para `/model opus` en una sesión que usa Sonnet 5:
3538 3540
3539| Campo | Descripción |3541| Campo | Descripción |
3540| :- | :- |3542| :- | :- |
3541| `permissionDecision` | `"allow"` continúa y omite la [confirmación que Claude Code muestra mientras la caché de prompts está caliente](/docs/es/prompt-caching#switching-models). `"deny"` cancela el cambio. `"ask"` pide al usuario que lo confirme |3543| `permissionDecision` | `"allow"` continúa y omite la [confirmación que Claude Code muestra mientras la caché de prompts está activa](/docs/es/prompt-caching#switching-models). `"deny"` cancela el cambio. `"ask"` pide al usuario que lo confirme |
3542| `permissionDecisionReason` | Para `"deny"`, se muestra al usuario como el motivo por el que se bloqueó el cambio, o se devuelve como el error de una solicitud `set_model`. Para `"ask"`, se muestra en la solicitud de confirmación. Se ignora para `"allow"` |3544| `permissionDecisionReason` | Para `"deny"`, se muestra al usuario como el motivo por el que se bloqueó el cambio, o se devuelve como el error de una solicitud `set_model`. Para `"ask"`, se muestra en la solicitud de confirmación. Se ignora para `"allow"` |
3543 3545
3544Solo `/model` en una sesión interactiva puede mostrar la solicitud de `"ask"`. En todas las demás superficies, incluido el modo no interactivo con el flag `-p`, `/config` y las solicitudes `set_model`, Claude Code trata `"ask"` como un rechazo.3546Solo `/model` en una sesión interactiva puede mostrar la solicitud de `"ask"`. En todas las demás superficies, incluido el modo no interactivo con el flag `-p`, `/config` y las solicitudes `set_model`, Claude Code trata `"ask"` como un rechazo.
3557 3559
3558Cuando varios hooks PreModelSwitch devuelven decisiones diferentes, la precedencia es `deny` > `ask` > `allow`.3560Cuando varios hooks PreModelSwitch devuelven decisiones diferentes, la precedencia es `deny` > `ask` > `allow`.
3559 3561
3560Claude Code muestra al usuario cualquier `systemMessage` que devuelva tu hook, independientemente de la decisión, por lo que un hook que informe del costo puede devolver `{"systemMessage": "..."}` y terminar con 0.3562Claude Code muestra al usuario cualquier `systemMessage` que devuelva tu hook, independientemente de la decisión, por lo que un hook que informa costos puede devolver `{"systemMessage": "..."}` y terminar con 0.
3561 3563
3562Un hook PreModelSwitch que no responde antes de su tiempo de espera bloquea el cambio. En [PreToolUse](#timeouts), en cambio, un hook de comando cuyo tiempo de espera se agota deja que la llamada a herramienta continúe. El tiempo de espera predeterminado para este evento es de 30 segundos. `PreModelSwitch` solo ejecuta hooks `command`, `http` y `mcp_tool`, por lo que los valores predeterminados de `prompt` y `agent` no se aplican.3564Un hook PreModelSwitch que no responde antes de su tiempo de espera bloquea el cambio. En [PreToolUse](#timeouts), en cambio, un hook de comando cuyo tiempo de espera se agota deja que la llamada a herramienta continúe. El tiempo de espera predeterminado para este evento es de 30 segundos. `PreModelSwitch` solo ejecuta hooks `command`, `http` y `mcp_tool`, por lo que los valores predeterminados de `prompt` y `agent` no se aplican.
3563 3565
3567 PostModelSwitch3569 PostModelSwitch
3568</h3>3570</h3>
3569 3571
3570Se ejecuta después de que cambia el modelo de la sesión. Úsalo para dar a Claude indicaciones específicas del modelo sin editar cada CLAUDE.md, por ejemplo una instrucción para toda la organización que se aplique en ciertos modelos.3572Se ejecuta después de que cambia el modelo de la sesión. Úsalo para darle a Claude indicaciones específicas del modelo sin editar cada CLAUDE.md, por ejemplo una instrucción para toda la organización que se aplique en ciertos modelos.
3571 3573
3572PostModelSwitch requiere Claude Code v2.1.251 o posterior. No puede bloquear, porque el modelo ya cambió. Claude Code ejecuta los hooks PostModelSwitch después de cualquiera de estos cambios:3574PostModelSwitch requiere Claude Code v2.1.251 o posterior. No puede bloquear, porque el modelo ya cambió. Claude Code ejecuta hooks PostModelSwitch después de cualquiera de estos cambios:
3573 3575
3574* Un cambio que tú o un cliente solicitaron3576* Un cambio que tú o un cliente solicitaron
3575* Un [respaldo automático de modelo](/docs/es/model-config#automatic-model-fallback), que cambia el modelo de la sesión3577* Un [respaldo automático de modelo](/docs/es/model-config#automatic-model-fallback), que cambia el modelo de la sesión
3576* Un ajuste como [`opusplan`](/docs/es/model-config#opusplan-model-setting) al entrar o salir del modo plan3578* Un ajuste como [`opusplan`](/docs/es/model-config#opusplan-model-setting) al entrar o salir del modo plan
3577* Claude Code restaurando el modelo cuando reanudas una sesión3579* Claude Code restaurando el modelo al reanudar una sesión
3578 3580
3579Claude Code no ejecuta los hooks PostModelSwitch cuando un modelo de una [cadena de modelos de respaldo](/docs/es/model-config#fallback-model-chains) atiende un turno, porque esa sustitución dura un turno y deja sin cambios el modelo de la sesión.3581Claude Code no ejecuta hooks PostModelSwitch cuando un modelo de una [cadena de modelos de respaldo](/docs/es/model-config#fallback-model-chains) atiende un turno, porque esa sustitución dura un turno y deja sin cambios el modelo de la sesión.
3580 3582
3581El matcher sigue las mismas reglas que [PreModelSwitch](#premodelswitch): Claude Code lo compara con el nombre canónico del modelo al que cambió la sesión.3583El matcher sigue las mismas reglas que [PreModelSwitch](#premodelswitch): Claude Code lo compara con el nombre canónico del modelo al que cambió la sesión.
3582 3584
3583Este ejemplo agrega indicaciones siempre que el modelo de la sesión cambia a cualquier modelo Opus:3585Este ejemplo agrega indicaciones cada vez que el modelo de la sesión cambia a cualquier modelo Opus:
3584 3586
3585```json theme={null}3587```json theme={null}
3586{3588{
3606 Entrada de PostModelSwitch3608 Entrada de PostModelSwitch
3607</h4>3609</h4>
3608 3610
3609Los hooks PostModelSwitch reciben los mismos campos que [PreModelSwitch](#premodelswitch-input), con `hook_event_name` establecido en `"PostModelSwitch"` y dos valores más de `source`: `"auto"` para un respaldo automático u otro cambio que Claude Code hizo por su cuenta, y `"resume"` para el modelo restaurado cuando reanudas una sesión.3611Los hooks PostModelSwitch reciben los mismos campos que [PreModelSwitch](#premodelswitch-input), con `hook_event_name` establecido en `"PostModelSwitch"` y dos valores adicionales de `source`: `"auto"` para un respaldo automático u otro cambio que Claude Code hizo por su cuenta, y `"resume"` para el modelo restaurado al reanudar una sesión.
3610 3612
3611`requested_model` es `null` cuando `source` es `"auto"`. Cuando `source` es `"resume"`, es el ajuste de modelo guardado que restauró Claude Code.3613`requested_model` es `null` cuando `source` es `"auto"`. Cuando `source` es `"resume"`, es el ajuste de modelo guardado que Claude Code restauró.
3612 3614
3613<h4 id="postmodelswitch-decision-control">3615<h4 id="postmodelswitch-decision-control">
3614 Control de decisión de PostModelSwitch3616 Control de decisión de PostModelSwitch
3615</h4>3617</h4>
3616 3618
3617Claude Code toma la [salida stdout en texto plano](#exit-code-0) de tu hook al terminar con 0, o `additionalContext` de la salida JSON, y la entrega a Claude con la siguiente solicitud después del cambio. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, puedes devolver:3619Claude Code toma el [stdout de texto plano](#exit-code-0) de tu hook al terminar con 0, o `additionalContext` de la salida JSON, y se lo entrega a Claude con la siguiente solicitud después del cambio. Además de los [campos de salida JSON](#json-output) disponibles para todos los hooks, puedes devolver:
3618 3620
3619| Campo | Descripción |3621| Campo | Descripción |
3620| :- | :- |3622| :- | :- |
3621| `additionalContext` | Cadena agregada al contexto de Claude con la siguiente solicitud. Consulta [Agregar contexto para Claude](#add-context-for-claude) |3623| `additionalContext` | String que se agrega al contexto de Claude con la siguiente solicitud. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
3622 3624
3623Si el hook no ha terminado en los cinco segundos posteriores a que envíes el siguiente prompt, Claude Code envía esa solicitud sin la salida y la adjunta a la solicitud siguiente. Si el modelo cambia varias veces antes de la siguiente solicitud, Claude Code entrega solo la salida correspondiente al modelo de destino del último cambio.3625Si el hook no ha terminado en los cinco segundos posteriores a que envías el siguiente prompt, Claude Code envía esa solicitud sin la salida y la adjunta a la solicitud siguiente. Si el modelo cambia varias veces antes de la siguiente solicitud, Claude Code entrega solo la salida correspondiente al modelo de destino del último cambio.
3624 3626
3625<h3 id="sessionend">3627<h3 id="sessionend">
3626 SessionEnd3628 SessionEnd
3660 3662
3661Los hooks SessionEnd tienen un tiempo de espera predeterminado de 1.5 segundos. Se aplica cuando sales, ejecutas `/clear` o cambias de sesión con `/resume` interactivo. Puedes darle más tiempo a un hook de dos maneras:3663Los hooks SessionEnd tienen un tiempo de espera predeterminado de 1.5 segundos. Se aplica cuando sales, ejecutas `/clear` o cambias de sesión con `/resume` interactivo. Puedes darle más tiempo a un hook de dos maneras:
3662 3664
3663* **`timeout` por hook**: establece `timeout` en la configuración de ese hook. El presupuesto total aumenta automáticamente hasta igualar el `timeout` por hook más alto de tus archivos de configuración, hasta 60 segundos. Si aumentas el presupuesto de esta manera, un hook sin su propio `timeout` sigue conservando el valor predeterminado. Los tiempos de espera establecidos en hooks proporcionados por plugins no aumentan el presupuesto.3665* **`timeout` por hook**: establece `timeout` en la configuración de ese hook. El presupuesto total aumenta automáticamente para coincidir con el `timeout` por hook más alto en tus archivos de configuración, hasta 60 segundos. Si aumentas el presupuesto de esta manera, un hook sin su propio `timeout` conserva el valor predeterminado. Los tiempos de espera establecidos en hooks proporcionados por plugins no aumentan el presupuesto.
3664* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: establece esta variable de entorno en milisegundos para sobrescribir el presupuesto explícitamente. El valor que establezcas también se convierte en el tiempo de espera de cada hook sin su propio `timeout`.3666* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: establece esta variable de entorno en milisegundos para sobrescribir el presupuesto de forma explícita. El valor que establezcas también se convierte en el tiempo de espera de cada hook sin su propio `timeout`.
3665 3667
3666Este ejemplo establece el presupuesto en 5 segundos:3668Este ejemplo establece el presupuesto en 5 segundos:
3667 3669
3675 Elicitation3677 Elicitation
3676</h3>3678</h3>
3677 3679
3678Se ejecuta cuando un servidor MCP solicita información al usuario en mitad de una tarea. De forma predeterminada, Claude Code muestra un cuadro de diálogo interactivo para que el usuario responda. Los hooks pueden interceptar esta solicitud y responder de forma programática, omitiendo el cuadro de diálogo por completo.3680Se ejecuta cuando un servidor MCP solicita información al usuario a mitad de una tarea. De forma predeterminada, Claude Code muestra un diálogo interactivo para que el usuario responda. Los hooks pueden interceptar esta solicitud y responder mediante programación, omitiendo el diálogo por completo.
3681
3682Para ver un hook completo con su entrada de configuración y su script, consulta [Responder una solicitud de formulario desde un script](#answer-a-form-request-from-a-script).
3679 3683
3680El campo matcher se compara con el nombre del servidor MCP.3684El campo matcher se compara con el nombre del servidor MCP.
3681 3685
3705}3709}
3706```3710```
3707 3711
3708Para la elicitación en modo URL, usada para la autenticación basada en el navegador:3712Para la elicitación en modo URL, que se usa para la autenticación basada en el navegador:
3709 3713
3710```json theme={null}3714```json theme={null}
3711{3715{
3724 Salida de Elicitation3728 Salida de Elicitation
3725</h4>3729</h4>
3726 3730
3727Para responder de forma programática sin mostrar el cuadro de diálogo, devuelve un objeto JSON con `hookSpecificOutput`:3731Un hook Elicitation puede responder la solicitud en nombre del usuario, rechazarla o cancelarla, o dejarla al diálogo. Para responder, rechazar o cancelar, termina con 0 e imprime un objeto `hookSpecificOutput` con una `action`. El servidor recibe tu respuesta y no aparece ningún diálogo. Cada fila de esta tabla muestra qué devolver para un resultado y qué recibe el servidor MCP:
3732
3733| Para | Devuelve | El servidor recibe |
3734| :- | :- | :- |
3735| Responder en nombre del usuario | `"action": "accept"`, con los valores de los campos del formulario en `content` | `accept` con tu `content` |
3736| Rechazar la solicitud | `"action": "decline"` | `decline` |
3737| Cancelar la solicitud | `"action": "cancel"` | `cancel` |
3738| Dejar la solicitud al usuario | Ninguna salida, con código de salida 0 | La respuesta del usuario desde el [diálogo](/docs/es/mcp#respond-to-mcp-elicitation-requests) |
3739
3740Esta salida responde la solicitud en modo formulario que se muestra en [Entrada de Elicitation](#elicitation-input). Las claves en `content` son los nombres de las propiedades del `requested_schema` de esa solicitud:
3728 3741
3729```json theme={null}3742```json theme={null}
3730{3743{
3738}3751}
3739```3752```
3740 3753
3741| Campo | Valores | Descripción |3754Esta salida rechaza una solicitud:
3742| :- | :- | :- |3755
3743| `action` | `accept`, `decline`, `cancel` | Si se acepta, rechaza o cancela la solicitud |3756```json theme={null}
3744| `content` | object | Valores de los campos del formulario que se envían. Solo se usa cuando `action` es `accept` |3757{
3758 "hookSpecificOutput": {
3759 "hookEventName": "Elicitation",
3760 "action": "decline"
3761 }
3762}
3763```
3764
3765En el diálogo, seleccionar **Decline** envía `decline` y presionar `Esc` envía `cancel`, así que devuelve el que quieras que vea el servidor.
3766
3767Para una solicitud en modo URL, un hook que devuelve `accept` omite el diálogo, por lo que la URL nunca se abre.
3768
3769Claude Code descarta `reason`, `systemMessage` y `continue` de la salida JSON de un hook Elicitation, sea cual sea la `action` que devuelvas.
3770
3771<h4 id="other-ways-to-decline-an-elicitation">
3772 Otras formas de rechazar una elicitación
3773</h4>
3774
3775Tu hook también puede rechazar de estas formas. El servidor recibe el mismo `decline` que con `"action": "decline"`:
3776
3777* **Termina con el código 2**: Claude Code ignora un `hookSpecificOutput` impreso por el mismo hook
3778* **Imprime un `"decision": "block"` de nivel superior**: el bloqueo sobrescribe una `action` en la misma salida
3779
3780Cuando varios hooks coinciden con la misma solicitud, un rechazo de uno de ellos sobrescribe un `accept` o `cancel` de otro.
3781
3782Este script rechaza las solicitudes en modo URL y deja las solicitudes de formulario al diálogo:
3783
3784```bash theme={null}
3785#!/bin/bash
3786if [ "$(jq -r '.mode')" = "url" ]; then
3787 exit 2
3788fi
3789```
3790
3791Ni el usuario ni el servidor ven por qué rechazó tu hook, porque Claude Code no muestra tu stderr ni tu `reason`.
3792
3793Claude Code ignoró un `decision` de nivel superior de los hooks `Elicitation` y `ElicitationResult` desde v2.1.105 hasta la corrección en v2.1.284.
3794
3795<h4 id="answer-a-form-request-from-a-script">
3796 Responder una solicitud de formulario desde un script
3797</h4>
3798
3799Este ejemplo responde una pregunta recurrente en nombre del usuario. Un servidor MCP llamado `issue-tracker` pide una clave de proyecto en un formulario, y el hook completa `DOCS`. El script acepta cuando `project_key` es el único campo del formulario. Para cualquier otra solicitud no imprime nada, por lo que aparece el diálogo.
3800
3801<Tabs>
3802 <Tab title="macOS/Linux">
3803 Registra un hook de comando para el evento en tu archivo de configuración, con el nombre del servidor como matcher:
3804
3805 ```json theme={null}
3806 {
3807 "hooks": {
3808 "Elicitation": [
3809 {
3810 "matcher": "issue-tracker",
3811 "hooks": [
3812 {
3813 "type": "command",
3814 "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/answer-project-key.sh",
3815 "args": []
3816 }
3817 ]
3818 }
3819 ]
3820 }
3821 }
3822 ```
3823
3824 Guarda este script en `.claude/hooks/answer-project-key.sh` en tu proyecto y hazlo ejecutable con `chmod +x`:
3825
3826 ```bash theme={null}
3827 #!/bin/bash
3828 input=$(cat)
3829 fields=$(jq -c '.requested_schema.properties // {} | keys' <<<"$input")
3830
3831 if [ "$fields" = '["project_key"]' ]; then
3832 jq -n '{hookSpecificOutput: {hookEventName: "Elicitation", action: "accept", content: {project_key: "DOCS"}}}'
3833 fi
3834 ```
3835 </Tab>
3836
3837 <Tab title="Windows (PowerShell)">
3838 Registra un hook de comando que ejecute el script a través de PowerShell, con el nombre del servidor como matcher:
3839
3840 ```json theme={null}
3841 {
3842 "hooks": {
3843 "Elicitation": [
3844 {
3845 "matcher": "issue-tracker",
3846 "hooks": [
3847 {
3848 "type": "command",
3849 "command": "powershell.exe",
3850 "args": [
3851 "-NoProfile",
3852 "-ExecutionPolicy",
3853 "Bypass",
3854 "-File",
3855 "${CLAUDE_PROJECT_DIR}/.claude/hooks/answer-project-key.ps1"
3856 ]
3857 }
3858 ]
3859 }
3860 ]
3861 }
3862 }
3863 ```
3864
3865 Guarda este script en `.claude/hooks/answer-project-key.ps1` en tu proyecto:
3745 3866
3746El código de salida 2 deniega la elicitación. Claude Code no muestra tu mensaje de stderr en ningún lugar.3867 ```powershell theme={null}
3868 $request = [Console]::In.ReadToEnd() | ConvertFrom-Json
3869 $fields = @($request.requested_schema.properties.PSObject.Properties.Name)
3870
3871 if ($fields.Count -eq 1 -and $fields[0] -eq 'project_key') {
3872 @{
3873 hookSpecificOutput = @{
3874 hookEventName = "Elicitation"
3875 action = "accept"
3876 content = @{ project_key = "DOCS" }
3877 }
3878 } | ConvertTo-Json -Depth 3
3879 }
3880 ```
3881 </Tab>
3882</Tabs>
3747 3883
3748Claude Code actúa según `hookSpecificOutput` de la salida JSON de un hook Elicitation y descarta `systemMessage` y `continue`.3884Para confirmar que el hook funciona, inicia Claude Code con `claude --debug` y dale a Claude una tarea que haga que el servidor pida la clave del proyecto. No aparece ningún diálogo, y el [registro de depuración](#debug-hooks) tiene una línea que termina con `Elicitation resolved by hook: {"action":"accept","content":{"project_key":"DOCS"}}`.
3749 3885
3750<h3 id="elicitationresult">3886<h3 id="elicitationresult">
3751 ElicitationResult3887 ElicitationResult
3753 3889
3754Se ejecuta después de que un usuario responde a una elicitación de MCP. Los hooks pueden observar, modificar o bloquear la respuesta antes de que se envíe de vuelta al servidor MCP.3890Se ejecuta después de que un usuario responde a una elicitación de MCP. Los hooks pueden observar, modificar o bloquear la respuesta antes de que se envíe de vuelta al servidor MCP.
3755 3891
3892Cuando un hook [Elicitation](#elicitation) responde una solicitud, Claude Code envía esa respuesta al servidor sin ejecutar hooks ElicitationResult.
3893
3756El campo matcher se compara con el nombre del servidor MCP.3894El campo matcher se compara con el nombre del servidor MCP.
3757 3895
3758<h4 id="elicitationresult-input">3896<h4 id="elicitationresult-input">
3770 "mcp_server_name": "my-mcp-server",3908 "mcp_server_name": "my-mcp-server",
3771 "action": "accept",3909 "action": "accept",
3772 "content": { "username": "alice" },3910 "content": { "username": "alice" },
3773 "mode": "form",3911 "mode": "form"
3774 "elicitation_id": "elicit-123"
3775}3912}
3776```3913```
3777 3914
3779 Salida de ElicitationResult3916 Salida de ElicitationResult
3780</h4>3917</h4>
3781 3918
3782Para sobrescribir la respuesta del usuario, devuelve un objeto JSON con `hookSpecificOutput`:3919Un hook ElicitationResult puede dejar pasar la respuesta del usuario, cambiar sus valores o bloquearla. Para cambiar o bloquear la respuesta, termina con 0 e imprime un objeto `hookSpecificOutput` con una `action`. Cada fila de esta tabla muestra qué devolver para un resultado y qué recibe el servidor MCP:
3920
3921| Para | Devuelve | El servidor recibe |
3922| :- | :- | :- |
3923| Dejar pasar la respuesta | Ninguna salida, con código de salida 0 | La respuesta del usuario, sin cambios |
3924| Cambiar los valores enviados | `"action": "accept"`, con los nuevos valores en `content` | `accept` con tu `content` en lugar de los valores del usuario |
3925| Bloquear la respuesta | `"action": "decline"` | `decline`, sin los valores del usuario |
3926| Cancelar la solicitud | `"action": "cancel"` | `cancel`, junto con los valores que envió el usuario. Para ocultarlos, devuelve `"decline"` |
3927
3928Esta salida cambia la respuesta que se muestra en [Entrada de ElicitationResult](#elicitationresult-input), de modo que el servidor recibe `alice@example.com` donde el usuario envió `alice`:
3783 3929
3784```json theme={null}3930```json theme={null}
3785{3931{
3786 "hookSpecificOutput": {3932 "hookSpecificOutput": {
3787 "hookEventName": "ElicitationResult",3933 "hookEventName": "ElicitationResult",
3788 "action": "decline",3934 "action": "accept",
3789 "content": {}3935 "content": {
3936 "username": "alice@example.com"
3937 }
3790 }3938 }
3791}3939}
3792```3940```
3793 3941
3794| Campo | Valores | Descripción |3942Tu `content` reemplaza todo el objeto `content` del usuario, así que incluye los campos que no estás cambiando. Devuelve `action` junto con él, porque Claude Code ignora un `hookSpecificOutput` que no tiene `action`.
3795| :- | :- | :- |3943
3796| `action` | `accept`, `decline`, `cancel` | Sobrescribe la acción del usuario |3944Los hooks ElicitationResult también se ejecutan cuando el usuario rechaza o cancela, y tu `action` reemplaza la suya. Comprueba que la `action` de la entrada sea `accept` antes de devolver `accept`, o tu hook convertirá una solicitud rechazada en una aceptada. Este script hace el mismo cambio cuando el usuario aceptó, conserva los demás campos y no imprime nada en caso contrario:
3797| `content` | object | Sobrescribe los valores de los campos del formulario. Solo tiene sentido cuando `action` es `accept` |3945
3946```bash theme={null}
3947#!/bin/bash
3948input=$(cat)
3949
3950if [ "$(jq -r '.action' <<<"$input")" = "accept" ]; then
3951 jq '{hookSpecificOutput: {hookEventName: "ElicitationResult", action: "accept", content: (.content + {username: (.content.username + "@example.com")})}}' <<<"$input"
3952fi
3953```
3954
3955Esta salida bloquea la respuesta:
3956
3957```json theme={null}
3958{
3959 "hookSpecificOutput": {
3960 "hookEventName": "ElicitationResult",
3961 "action": "decline"
3962 }
3963}
3964```
3798 3965
3799El código de salida 2 bloquea la respuesta y cambia la acción efectiva a `decline`. Claude Code no muestra tu mensaje de stderr en ningún lugar.3966El código de salida 2 y un `"decision": "block"` de nivel superior también bloquean la respuesta. [Otras formas de rechazar una elicitación](#other-ways-to-decline-an-elicitation) explica cuál tiene efecto cuando un hook los combina, qué ve el usuario y qué versiones ignoraron `decision`.
3800 3967
3801Claude Code actúa según `hookSpecificOutput` de la salida JSON de un hook ElicitationResult y descarta `systemMessage` y `continue`.3968Claude Code descarta `reason`, `systemMessage` y `continue` de la salida JSON de un hook ElicitationResult, sea cual sea la `action` que devuelvas.
3802 3969
3803<h2 id="prompt-based-hooks">3970<h2 id="prompt-based-hooks">
3804 Hooks basados en prompts3971 Hooks basados en prompts
3862 4029
3863Establezca `type` en `"prompt"` y proporcione una cadena `prompt` en lugar de un `command`. Use el marcador de posición `$ARGUMENTS` para inyectar datos de entrada JSON del hook en su texto de prompt.4030Establezca `type` en `"prompt"` y proporcione una cadena `prompt` en lugar de un `command`. Use el marcador de posición `$ARGUMENTS` para inyectar datos de entrada JSON del hook en su texto de prompt.
3864 4031
4032En un hook de prompt o de [agente](#agent-based-hooks), puedes escribir el `prompt` como una regla sobre qué bloquear o permitir, como "Bloquea cualquier comando Bash que lea archivos `.env`", o como una condición que debe cumplirse, como "Todas las pruebas unitarias pasan".
4033
3865Este hook `Stop` le pide al LLM que evalúe si todas las tareas están completas antes de permitir que Claude finalice:4034Este hook `Stop` le pide al LLM que evalúe si todas las tareas están completas antes de permitir que Claude finalice:
3866 4035
3867```json theme={null}4036```json theme={null}