827 827
828El código de salida de tu hook le dice a Claude Code si debe continuar con la acción que activó el hook, como una llamada a herramienta o un prompt. Una ejecución que termina tiene uno de tres resultados:828El código de salida de tu hook le dice a Claude Code si debe continuar con la acción que activó el hook, como una llamada a herramienta o un prompt. Una ejecución que termina tiene uno de tres resultados:
829 829
830* **Éxito**: tu hook sale con 0. Claude Code aplica cualquier campo de [salida JSON](#json-output) que tu hook haya impreso, y la acción continúa a menos que esos campos la bloqueen o la denieguen.830* **Éxito**: tu hook sale con 0. Claude Code aplica cualquier campo de [salida JSON](#json-output) que tu hook haya impreso, y la acción continúa a menos que esos campos la bloqueen o la denieguen. [Hooks que inician un proceso en segundo plano](#hooks-that-start-a-background-process) cubre la excepción.
831* **Error de bloqueo**: tu hook sale con 2. En los [eventos que pueden bloquear](#exit-code-2-behavior-per-event), Claude Code detiene la acción.831* **Error de bloqueo**: tu hook sale con 2. En los [eventos que pueden bloquear](#exit-code-2-behavior-per-event), Claude Code detiene la acción.
832* **Error sin bloqueo**: tu hook sale con cualquier otro código, o falla de alguna otra manera, como no iniciarse o imprimir JSON no válido. La acción continúa, y en eventos como `PreToolUse` ves un aviso `<hook name> hook error` en la transcripción. Si quieres que un hook fallido bloquee la acción, establece [`onFailure: "block"`](#block-the-action-when-a-hook-fails).832* **Error sin bloqueo**: tu hook sale con cualquier otro código, o falla de alguna otra manera, como no iniciarse o imprimir JSON no válido. La acción continúa, y en eventos como `PreToolUse` ves un aviso `<hook name> hook error` en la transcripción. Si quieres que un hook fallido bloquee la acción, establece [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
833 833
932* 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. Para bloquear la llamada cuando se agota el tiempo de espera de un hook `command` o `http`, establece [`onFailure: "block"`](#block-the-action-when-a-hook-fails).932* 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. Para bloquear la llamada cuando se agota el tiempo de espera de un hook `command` o `http`, establece [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
933* Un [hook de callback del Agent SDK](/docs/es/agent-sdk/hooks) que excede su tiempo de espera [bloquea la llamada a herramienta](#pretooluse).933* Un [hook de callback del Agent SDK](/docs/es/agent-sdk/hooks) que excede su tiempo de espera [bloquea la llamada a herramienta](#pretooluse).
934 934
935<h4 id="hooks-that-start-a-background-process">
936 Hooks que inician un proceso en segundo plano
937</h4>
938
939Si tu hook de comando toma su decisión en un proceso en segundo plano y sale, una denegación que ese proceso imprima después de que Claude Code haya dejado de leer no bloquea la llamada a herramienta. Para un hook que no es [async](#run-hooks-in-the-background), Claude Code termina de leer la salida del hook poco después de que sale el propio proceso del hook.
940
941Imprime la decisión antes de iniciar un proceso en segundo plano, y redirige el stdout y el stderr de ese proceso. Si tu script imprime un allow y luego inicia un proceso en segundo plano sin redirigir el stdout y el stderr de ese proceso, Claude Code bloquea la llamada a herramienta. El error del hook incluye `refusing to honor the suspect capture`.
942
943Este script de hook `PreToolUse` imprime la decisión con `policy-check.sh` y luego sube métricas en segundo plano:
944
945```bash theme={null}
946#!/bin/bash
947"$CLAUDE_PROJECT_DIR"/.claude/hooks/policy-check.sh || exit $?
948"$CLAUDE_PROJECT_DIR"/.claude/hooks/upload-metrics.sh >/dev/null 2>&1 &
949```
950
951El resto del script hace lo siguiente:
952
953* **`|| exit $?`**: hace que el código de salida de la verificación sea el del propio hook, de modo que una verificación que sale con 2 para denegar siga bloqueando. De lo contrario, el hook sale con el código de la última línea, que es 0.
954* **`>/dev/null 2>&1 &`**: ejecuta `upload-metrics.sh` en segundo plano con su salida redirigida, para que no mantenga abierta la salida del hook.
955
956Para probar el script, haz que `policy-check.sh` salga con 2 y luego activa una llamada a herramienta que coincida con el hook. La llamada a herramienta se bloquea.
957
935<h4 id="block-the-action-when-a-hook-fails">958<h4 id="block-the-action-when-a-hook-fails">
936 Bloquear la acción cuando un hook falla959 Bloquear la acción cuando un hook falla
937</h4>960</h4>
1245 Eventos de hooks1268 Eventos de hooks
1246</h2>1269</h2>
1247 1270
1248Cada 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.1271Cada 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 preparació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.
1249 1272
1250<h3 id="sessionstart">1273<h3 id="sessionstart">
1251 SessionStart1274 SessionStart
1253 1276
1254Se 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.1277Se 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.
1255 1278
1256SessionStart 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`.1279SessionStart 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`.
1257 1280
1258El valor del matcher corresponde a cómo se inició la sesión:1281El valor del matcher corresponde a cómo se inició la sesión:
1259 1282
1260| Matcher | Cuándo se activa |1283| Matcher | Cuándo se dispara |
1261| :- | :- |1284| :- | :- |
1262| `startup` | Sesión nueva |1285| `startup` | Sesión nueva |
1263| `resume` | `--resume`, `--continue` o `/resume` |1286| `resume` | `--resume`, `--continue` o `/resume` |
1264| `clear` | `/clear` |1287| `clear` | `/clear` |
1265| `compact` | Compactación automática o manual |1288| `compact` | Compactación automática o manual |
1266| `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) |1289| `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) |
1267 1290
1268Antes de la v2.1.214, las sesiones bifurcadas informaban el origen `"resume"`.1291Antes de la v2.1.214, las sesiones bifurcadas informaban el origen `"resume"`.
1269 1292
1270Cuando inicias una sesión interactiva, reanudas una conversación al arrancar con `--continue` o `--resume`, o ejecutas `/clear`, los hooks SessionStart se ejecutan en segundo plano. Puedes escribir de inmediato, y una conversación que reanudaste aparece sin esperar a los hooks. La primera respuesta de Claude sigue esperando a que los hooks terminen, para que su contexto llegue a Claude.1293Cuando inicias una sesión interactiva, reanudas una conversación al iniciar con `--continue` o `--resume`, o ejecutas `/clear`, los hooks SessionStart se ejecutan en segundo plano. Puedes escribir de inmediato, y una conversación que reanudaste aparece sin esperar a los hooks. La primera respuesta de Claude sigue esperando a que terminen los hooks, para que su contexto llegue a Claude.
1271 1294
1272Cuando cambias de conversación con `/resume` dentro de una sesión, el cambio espera a que los hooks terminen. Si ejecutas `/clear` o cambias a otra conversación mientras los hooks en segundo plano todavía se están ejecutando, nada de lo que devuelvan se aplica a la sesión.1295Cuando cambias de conversación con `/resume` dentro de una sesión, el cambio espera a que terminen los hooks. Si ejecutas `/clear` o cambias a otra conversación mientras los hooks en segundo plano siguen ejecutándose, nada de lo que devuelvan se aplica a la sesión.
1273 1296
1274La 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.1297La misma espera se aplica al iniciar, incluida una sesión reanudada: un prompt que envíes mientras los hooks SessionStart siguen ejecutándose no llega a Claude hasta que terminen.
1275 1298
1276Durante cualquiera de las dos esperas, presiona `Esc` para devolver el prompt al campo de entrada sin enviarlo. Los hooks siguen ejecutándose.1299Durante cualquiera de las dos esperas, presiona `Esc` para recuperar el prompt en la entrada sin enviarlo. Los hooks siguen ejecutándose.
1277 1300
1278<h4 id="sessionstart-input">1301<h4 id="sessionstart-input">
1279 Entrada de SessionStart1302 Entrada de SessionStart
1283 1306
1284| Campo | Descripción |1307| Campo | Descripción |
1285| :- | :- |1308| :- | :- |
1286| `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 |1309| `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 |
1287| `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 |1310| `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 |
1288| `agent_type` | El nombre del agente, presente cuando inicias Claude Code con `claude --agent <name>` |1311| `agent_type` | El nombre del agente, presente cuando inicias Claude Code con `claude --agent <name>` |
1289| `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 |1312| `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 comprobar primero este campo para evitar sobrescribir un título personalizado existente |
1290 1313
1291Una 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`.1314Una 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`.
1292 1315
1296| :- | :- |1319| :- | :- |
1297| `seconds_since_last_response` | Segundos de tiempo real transcurridos desde la última respuesta en la transcripción reanudada |1320| `seconds_since_last_response` | Segundos de tiempo real transcurridos desde la última respuesta en la transcripción reanudada |
1298| `context_tokens` | Tokens que la primera solicitud de la sesión reanudada vuelve a enviar como su prompt |1321| `context_tokens` | Tokens que la primera solicitud de la sesión reanudada vuelve a enviar como su prompt |
1299| `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é |1322| `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é |
1300| `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 |1323| `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 |
1301 1324
1302Este ejemplo muestra la entrada de una sesión reanudada 90 minutos después de su última respuesta:1325Este ejemplo muestra la entrada de una sesión reanudada 90 minutos después de su última respuesta:
1324 1347
1325| Campo | Descripción |1348| Campo | Descripción |
1326| :- | :- |1349| :- | :- |
1327| `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 |1350| `additionalContext` | Cadena que se agrega al contexto de Claude al comienzo 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 |
1328| `initialUserMessage` | Cadena que se usa como primer mensaje del usuario de la sesión, en [modo no interactivo](/docs/es/headless) con el flag `-p`. Se convierte en el primer turno aunque no pases ningún prompt. Un prompt que sí pases va a continuación como el siguiente turno |1351| `initialUserMessage` | Cadena que se usa como primer mensaje del usuario de la sesión, en [modo no interactivo](/docs/es/headless) con el flag `-p`. Se convierte en el primer turno aunque no pases ningún prompt. Un prompt que sí pases sigue como el siguiente turno |
1329| `sessionTitle` | Establece el título de la sesión, con el mismo efecto que `/rename`. Se aplica cuando `source` es `"startup"`, `"resume"` o `"fork"` |1352| `sessionTitle` | Establece el título de la sesión, con el mismo efecto que `/rename`. Se aplica cuando `source` es `"startup"`, `"resume"` o `"fork"` |
1330| `watchPaths` | Array de rutas absolutas que se vigilarán para eventos [FileChanged](#filechanged) durante esta sesión |1353| `watchPaths` | Array de rutas absolutas que se vigilan para eventos [FileChanged](#filechanged) durante esta sesión |
1331| `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. Consulta [Recargar los skills que instala un hook](#reload-skills-that-a-hook-installs) |1354| `reloadSkills` | Booleano. Cuando es `true`, Claude Code vuelve a escanear los directorios de [skills](/docs/es/skills) y comandos después de que terminen los hooks SessionStart. Consulta [Recargar los skills que instala un hook](#reload-skills-that-a-hook-installs) |
1332 1355
1333Esta salida agrega contexto y le pone nombre a la sesión:1356Esta salida agrega contexto y le pone nombre a la sesión:
1334 1357
1342}1365}
1343```1366```
1344 1367
1345Un hook que solo agrega contexto puede imprimirlo sin construir JSON, porque Claude Code agrega al contexto de Claude la [stdout en texto plano](#exit-code-0) de un hook SessionStart.1368Un hook que solo agrega contexto puede imprimirlo sin construir JSON, porque Claude Code agrega la [salida stdout en texto plano](#exit-code-0) de un hook SessionStart al contexto de Claude.
1346 1369
1347Si el hook SessionStart de tu plugin proporciona `initialUserMessage` o `sessionTitle`, instala el plugin antes de que se inicie la sesión. Claude Code ignora ambos campos de un plugin que termina de instalarse después de que se hayan ejecutado los hooks SessionStart.1370Si el hook SessionStart de tu plugin proporciona `initialUserMessage` o `sessionTitle`, instala el plugin antes de que comience la sesión. Claude Code ignora ambos campos de un plugin que termina de instalarse después de que se hayan ejecutado los hooks SessionStart.
1348 1371
1349<h4 id="reload-skills-that-a-hook-installs">1372<h4 id="reload-skills-that-a-hook-installs">
1350 Recargar los skills que instala un hook1373 Recargar los skills que instala un hook
1351</h4>1374</h4>
1352 1375
1353Para que los skills que instala un hook SessionStart estén disponibles en la misma sesión, devuelve `reloadSkills`. La detección de skills normalmente se ejecuta antes de que terminen los hooks SessionStart, así que, sin él, los archivos que un hook escribe en `~/.claude/skills/` o `.claude/skills/` pueden faltar cuando se ejecuta el primer prompt.1376Para que los skills que instala un hook SessionStart estén disponibles en la misma sesión, devuelve `reloadSkills`. El descubrimiento de skills normalmente se ejecuta antes de que terminen los hooks SessionStart, así que sin él, los archivos que un hook escribe en `~/.claude/skills/` o `.claude/skills/` pueden faltar cuando se ejecuta el primer prompt.
1354 1377
1355Este ejemplo sincroniza un repositorio compartido de skills y solicita el nuevo examen:1378Este ejemplo sincroniza un repositorio compartido de skills y solicita el nuevo escaneo:
1356 1379
1357```bash theme={null}1380```bash theme={null}
1358#!/bin/bash1381#!/bin/bash
1366La URL del repositorio es un marcador de posición. Reemplázala por tu propio repositorio de skills.1389La URL del repositorio es un marcador de posición. Reemplázala por tu propio repositorio de skills.
1367 1390
1368<h4 id="persist-environment-variables">1391<h4 id="persist-environment-variables">
1369 Persistir variables de entorno1392 Conservar variables de entorno
1370</h4>1393</h4>
1371 1394
1372Los hooks SessionStart tienen acceso a la variable de entorno `CLAUDE_ENV_FILE`, que proporciona una ruta de archivo donde puedes conservar variables de entorno para los comandos de shell que Claude ejecuta más adelante en la sesión.1395Los hooks SessionStart tienen acceso a la variable de entorno `CLAUDE_ENV_FILE`, que proporciona una ruta de archivo donde puedes conservar variables de entorno para los comandos de shell que Claude ejecute más adelante en la sesión.
1373 1396
1374Para establecer variables de entorno individuales, escribe sentencias `export` en `CLAUDE_ENV_FILE`. Usa la adición (`>>`) para conservar las variables establecidas por otros hooks:1397Para establecer variables de entorno individuales, escribe sentencias `export` en `CLAUDE_ENV_FILE`. Usa la adición (`>>`) para conservar las variables establecidas por otros hooks:
1375 1398
1385exit 01408exit 0
1386```1409```
1387 1410
1388Para capturar todos los cambios de entorno de los comandos de configuración, compara las variables exportadas antes y después:1411Para capturar todos los cambios de entorno de los comandos de preparación, compara las variables exportadas antes y después:
1389 1412
1390```bash theme={null}1413```bash theme={null}
1391#!/bin/bash1414#!/bin/bash
1404exit 01427exit 0
1405```1428```
1406 1429
1407Cada comando de Bash ejecuta el contenido del archivo como código de shell antes del propio comando, así que una línea ahí puede usar cualquier cosa que Bash evalúe, como la referencia a `$PATH` en `export PATH="$PATH:./node_modules/.bin"`.1430Cada comando de Bash ejecuta el contenido del archivo como código de shell antes del propio comando, así que una línea allí puede usar cualquier cosa que Bash evalúe, como la referencia a `$PATH` en `export PATH="$PATH:./node_modules/.bin"`.
1408 1431
1409<a id="persisted-variables-in-powershell-commands" />1432<a id="persisted-variables-in-powershell-commands" />
1410 1433
1412 Variables conservadas en comandos de PowerShell1435 Variables conservadas en comandos de PowerShell
1413</h5>1436</h5>
1414 1437
1415Los comandos de [PowerShell](/docs/es/tools-reference#powershell-tool) también reciben las variables de `CLAUDE_ENV_FILE`, en Claude Code v2.1.296 o posterior, pero PowerShell nunca ejecuta el archivo. En su lugar, Claude Code lee las asignaciones del archivo y las copia en el entorno del comando de PowerShell. Solo lo hace cuando cada línea es una de las siguientes, en todo lo que escribió cada hook de esta sesión y en cualquier script al que [hayas establecido `CLAUDE_ENV_FILE`](/docs/es/env-vars) antes de arrancar:1438Los comandos de [PowerShell](/docs/es/tools-reference#powershell-tool) también reciben las variables de `CLAUDE_ENV_FILE`, en Claude Code v2.1.296 o posterior, pero PowerShell nunca ejecuta el archivo. En su lugar, Claude Code lee las asignaciones del archivo y las copia en el entorno del comando de PowerShell. Solo lo hace cuando cada línea es de alguno de los siguientes tipos, considerando todo lo que escribió cada hook en esta sesión y cualquier script al que [hayas establecido `CLAUDE_ENV_FILE`](/docs/es/env-vars) antes de iniciar:
1416 1439
1417* Una línea en blanco o un comentario `#`1440* Una línea en blanco o un comentario `#`
1418* Una asignación al inicio de la línea, escrita como `export NAME=value`, `declare -x NAME=value` o `NAME=value`, con un valor que Bash usaría exactamente tal como está escrito, formado por cualquier combinación de estas partes: texto sin comillas que usa solo letras, dígitos y los caracteres `_ @ % + = : , . / -`, texto entre comillas simples y texto entre comillas dobles donde cualquier `$`, acento grave o `"` dentro esté escapado con una barra invertida1441* Una asignación al comienzo de la línea, escrita como `export NAME=value`, `declare -x NAME=value` o `NAME=value`, con un valor que Bash usaría exactamente tal como está escrito, formado por cualquier combinación de estas partes: texto sin comillas que use solo letras, dígitos y los caracteres `_ @ % + = : , . / -`, texto entre comillas simples y texto entre comillas dobles en el que cualquier `$`, acento grave o `"` interno esté escapado con una barra invertida
1419 1442
1420Si alguna línea es de otro tipo, como `export PATH="$PATH:./node_modules/.bin"` con su `$PATH` sin escapar, un comando `source` o las cadenas `$'...'` que imprime `direnv export bash`, los comandos de PowerShell no reciben ninguna de las variables, y `claude --debug` registra `Session environment is not all plain assignments`. Los comandos de Bash siguen recibiéndolas todas. En Windows, los comandos de PowerShell tampoco reciben una variable cuyo valor contiene `/` o `\`, porque Git Bash y Windows escriben las rutas de forma distinta. Un comando de PowerShell [en el sandbox](/docs/es/sandboxing) no recibe ninguna de las variables.1443Si alguna línea es de otro tipo, como `export PATH="$PATH:./node_modules/.bin"` con su `$PATH` sin escapar, un comando `source` o las cadenas `$'...'` que imprime `direnv export bash`, los comandos de PowerShell no reciben ninguna de las variables, y `claude --debug` registra `Session environment is not all plain assignments`. Los comandos de Bash siguen recibiéndolas todas. En Windows, los comandos de PowerShell tampoco reciben una variable cuyo valor contenga `/` o `\`, porque Git Bash y Windows escriben las rutas de forma diferente. Un comando de PowerShell [en el sandbox](/docs/es/sandboxing) no recibe ninguna de las variables.
1421 1444
1422<Note>1445<Note>
1423 `CLAUDE_ENV_FILE` está disponible para los hooks SessionStart, [Setup](#setup), [CwdChanged](#cwdchanged) y [FileChanged](#filechanged). Los demás eventos de hooks no tienen acceso a esta variable, ni tampoco un hook que se ejecuta en PowerShell, ya sea mediante [`"shell": "powershell"`](#command-hook-fields) o de forma predeterminada en Windows sin Git Bash.1446 `CLAUDE_ENV_FILE` está disponible para los hooks SessionStart, [Setup](#setup), [CwdChanged](#cwdchanged) y [FileChanged](#filechanged). Otros eventos de hooks no tienen acceso a esta variable, y tampoco un hook que se ejecuta en PowerShell, ya sea mediante [`"shell": "powershell"`](#command-hook-fields) o de forma predeterminada en Windows sin Git Bash.
1424</Note>1447</Note>
1425 1448
1426<h3 id="setup">1449<h3 id="setup">
1427 Setup1450 Setup
1428</h3>1451</h3>
1429 1452
1430Se 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.1453Se 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 el inicio normal. Úsalo para la instalación única de dependencias o para la limpieza programada 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.
1431 1454
1432El valor del matcher corresponde al flag de la CLI que activó el hook:1455El valor del matcher corresponde al flag de la CLI que activó el hook:
1433 1456
1434| Matcher | Cuándo se activa |1457| Matcher | Cuándo se dispara |
1435| :- | :- |1458| :- | :- |
1436| `init` | `claude --init-only` o `claude -p --init` |1459| `init` | `claude --init-only` o `claude -p --init` |
1437| `maintenance` | `claude -p --maintenance` |1460| `maintenance` | `claude -p --maintenance` |
1442 1465
1443Si 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.1466Si 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.
1444 1467
1445Como 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é.1468Como Setup no se dispara en cada inicio, un plugin que necesita instalar una dependencia 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, un hook o skill que comprueba si existe `${CLAUDE_PLUGIN_DATA}/node_modules` y ejecuta `npm install` si no está. 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 que cumplan los requisitos](/docs/es/plugins/loading#node-js-package-dependencies) cuando almacena el plugin en caché.
1446 1469
1447<h4 id="setup-input">1470<h4 id="setup-input">
1448 Entrada de Setup1471 Entrada de Setup
1464 Control de decisiones de Setup1487 Control de decisiones de Setup
1465</h4>1488</h4>
1466 1489
1467Los 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`.1490Los 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`, el stdout, el 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`.
1468 1491
1469Los 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).1492Los hooks Setup tienen acceso a `CLAUDE_ENV_FILE`. Las variables escritas en ese archivo se conservan en los comandos de 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).
1470 1493
1471<h3 id="instructionsloaded">1494<h3 id="instructionsloaded">
1472 InstructionsLoaded1495 InstructionsLoaded
1473</h3>1496</h3>
1474 1497
1475Se 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.1498Se dispara cuando se carga un archivo `CLAUDE.md` o `.claude/rules/*.md` 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 tarde 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.
1476 1499
1477Este 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`.1500Este 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`.
1478 1501
1479El 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.1502El matcher se evalúa contra `load_reason`. Por ejemplo, usa `"matcher": "session_start"` para que se dispare solo con los archivos cargados al inicio de la sesión, o `"matcher": "path_glob_match|nested_traversal"` para que se dispare solo con las cargas diferidas.
1480 1503
1481<h4 id="instructionsloaded-input">1504<h4 id="instructionsloaded-input">
1482 Entrada de InstructionsLoaded1505 Entrada de InstructionsLoaded
1488| :- | :- |1511| :- | :- |
1489| `file_path` | Ruta absoluta al archivo de instrucciones que se cargó |1512| `file_path` | Ruta absoluta al archivo de instrucciones que se cargó |
1490| `memory_type` | Alcance del archivo: `"User"`, `"Project"`, `"Local"` o `"Managed"` |1513| `memory_type` | Alcance del archivo: `"User"`, `"Project"`, `"Local"` o `"Managed"` |
1491| `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 |1514| `load_reason` | Por qué se cargó el archivo: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` o `"compact"`. El valor `"compact"` se produce cuando los archivos de instrucciones se vuelven a cargar después de un evento de compactación |
1492| `globs` | Patrones glob de ruta del frontmatter `paths:` del archivo, si los hay. Presente solo en cargas `path_glob_match` |1515| `globs` | Patrones glob de ruta del frontmatter `paths:` del archivo, si los hay. Presente solo en las cargas `path_glob_match` |
1493| `trigger_file_path` | Ruta al archivo cuyo acceso desencadenó esta carga, en cargas diferidas |1516| `trigger_file_path` | Ruta al archivo cuyo acceso activó esta carga, en las cargas diferidas |
1494| `parent_file_path` | Ruta al archivo de instrucciones padre que incluyó este, en cargas `include` |1517| `parent_file_path` | Ruta al archivo de instrucciones padre que incluyó este, en las cargas `include` |
1495 1518
1496```json theme={null}1519```json theme={null}
1497{1520{
1516</h3>1539</h3>
1517 1540
1518Se ejecuta cuando se envía un prompt, antes de que Claude lo procese. Esto te permite1541Se ejecuta cuando se envía un prompt, antes de que Claude lo procese. Esto te permite
1519agregar contexto adicional según el prompt o la conversación, validar prompts o1542agregar contexto adicional basado en el prompt o la conversación, validar prompts o
1520bloquear ciertos tipos de prompts.1543bloquear ciertos tipos de prompts.
1521 1544
1522Los hooks `UserPromptSubmit` no se activan solo con los prompts que escribes. Claude Code también los ejecuta cuando:1545Los hooks `UserPromptSubmit` no se disparan solo con los prompts que escribes. Claude Code también los ejecuta cuando:
1523 1546
1524* Se activa una [tarea programada](/docs/es/scheduled-tasks), incluida una iteración de `/loop`1547* Se dispara una [tarea programada](/docs/es/scheduled-tasks), incluida una iteración de `/loop`
1525* Un [subagente en segundo plano](/docs/es/sub-agents#run-subagents-in-foreground-or-background) informa a la sesión que lo inició1548* Un [subagente en segundo plano](/docs/es/sub-agents#run-subagents-in-foreground-or-background) informa a la sesión que lo inició
1526* Llega a tu conversación principal un [mensaje que envía otra sesión](/docs/es/cross-session-messaging)1549* [Otra sesión envía un mensaje](/docs/es/cross-session-messaging) a tu conversación principal
1527 1550
1528Los 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.1551Los 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.
1529 1552
1530Salvo un hook de comando que ejecutes con [`async: true`](#run-hooks-in-the-background), cuando se agota el tiempo de espera de un hook de comando, HTTP o de herramienta MCP de `UserPromptSubmit`, se cancela y se descarta su salida, incluido cualquier `additionalContext`. El prompt sigue llegando a Claude sin ese contexto. Para bloquear el prompt en su lugar, establece [`onFailure: "block"`](#block-the-action-when-a-hook-fails) en un hook de comando o HTTP. La transcripción muestra un aviso que indica el hook, el tiempo de espera que se agotó y que se descartó la salida.1553Salvo un hook de comando que ejecutes con [`async: true`](#run-hooks-in-the-background), un hook `UserPromptSubmit` de comando, HTTP o herramienta MCP que alcanza su tiempo de espera se cancela y su salida, incluido cualquier `additionalContext`, se descarta. El prompt sigue llegando a Claude sin ese contexto. Para bloquear el prompt en su lugar, establece [`onFailure: "block"`](#block-the-action-when-a-hook-fails) en un hook de comando o HTTP. La transcripción muestra un aviso que nombra el hook, el tiempo de espera que se agotó e indica que la salida se descartó.
1531 1554
1532Cuando 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.1555Un [hook de callback del Agent SDK](/docs/es/agent-sdk/hooks) en `UserPromptSubmit` que alcanza su tiempo de espera bloquea el prompt con un mensaje que nombra el hook y el tiempo de espera, porque un callback en ese punto 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.
1533 1556
1534<h4 id="userpromptsubmit-input">1557<h4 id="userpromptsubmit-input">
1535 Entrada de UserPromptSubmit1558 Entrada de UserPromptSubmit
1536</h4>1559</h4>
1537 1560
1538Ademá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.1561Ademá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 donde Claude Code [marca el texto pegado para Claude](/docs/es/terminal-config#how-claude-treats-pasted-text), ese contenido expandido se encuentra 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.
1539 1562
1540Los 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).1563Los 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).
1541 1564
1558 1581
1559Hay dos formas de agregar contexto a la conversación con el código de salida 0:1582Hay dos formas de agregar contexto a la conversación con el código de salida 0:
1560 1583
1561* **Stdout en texto plano**: Claude Code agrega al contexto de Claude la stdout que [trata como texto plano](#exit-code-0)1584* **Stdout en texto plano**: Claude Code agrega al contexto de Claude el stdout que [trata como texto plano](#exit-code-0)
1562* **JSON con `additionalContext`**: usa el formato JSON a continuación para tener más control. El campo `additionalContext` se agrega como contexto1585* **JSON con `additionalContext`**: usa el formato JSON siguiente para tener más control. El campo `additionalContext` se agrega como contexto
1563 1586
1564Ninguno 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).1587Ninguno de los dos canales produce una entrada visible en la transcripción. El stdout 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).
1565 1588
1566Para bloquear un prompt, devuelve un objeto JSON con `decision` establecido en `"block"`:1589Para bloquear un prompt, devuelve un objeto JSON con `decision` establecido en `"block"`:
1567 1590
1569| :- | :- |1592| :- | :- |
1570| `decision` | `"block"` detiene el prompt antes de que llegue a Claude. Omítelo para permitir que el prompt continúe |1593| `decision` | `"block"` detiene el prompt antes de que llegue a Claude. Omítelo para permitir que el prompt continúe |
1571| `reason` | Se muestra al usuario cuando `decision` es `"block"`. No se agrega al contexto |1594| `reason` | Se muestra al usuario cuando `decision` es `"block"`. No se agrega al contexto |
1572| `additionalContext` | Cadena agregada al contexto de Claude junto con el prompt enviado. Consulta [Agregar contexto para Claude](#add-context-for-claude) |1595| `additionalContext` | Cadena que se agrega al contexto de Claude junto con el prompt enviado. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
1573| `sessionTitle` | Establece el título de la sesión. Úsalo para nombrar sesiones automáticamente según el contenido del prompt |1596| `sessionTitle` | Establece el título de la sesión. Úsalo para nombrar sesiones automáticamente según el contenido del prompt |
1574| `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) |1597| `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) |
1575 1598
1576Un 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.1599Un hook que bloquea saliendo con 2 se enruta igual que `reason`: el mensaje de bloqueo muestra el texto de stderr al usuario, y no se agrega al contexto.
1577 1600
1578```json theme={null}1601```json theme={null}
1579{1602{
1589```1612```
1590 1613
1591<h4 id="what-a-blocked-prompt-leaves-behind">1614<h4 id="what-a-blocked-prompt-leaves-behind">
1592 Qué deja atrás un prompt bloqueado1615 Lo que deja un prompt bloqueado
1593</h4>1616</h4>
1594 1617
1595Un 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.1618Un 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 lo hace saliendo con 2.
1596 1619
1597`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).1620`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).
1598 1621
1600 UserPromptExpansion1623 UserPromptExpansion
1601</h3>1624</h3>
1602 1625
1603Se 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`.1626Se ejecuta cuando un comando escrito por el usuario se expande en un prompt antes de llegar a Claude. Úsalo para impedir que ciertos comandos se invoquen directamente, inyectar contexto para un skill concreto 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`.
1604 1627
1605Este 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.1628Este evento cubre la ruta que `PreToolUse` no cubre: un hook `PreToolUse` que coincide con la herramienta `Skill` solo se dispara cuando Claude llama a la herramienta, pero escribir `/skillname` directamente omite `PreToolUse`. `UserPromptExpansion` se dispara en esa ruta directa.
1606 1629
1607Coincide con `command_name`. Deja el matcher vacío para que se active con cada comando de tipo prompt.1630Coincide con `command_name`. Deja el matcher vacío para que se dispare con cada comando de tipo prompt.
1608 1631
1609<h4 id="userpromptexpansion-input">1632<h4 id="userpromptexpansion-input">
1610 Entrada de UserPromptExpansion1633 Entrada de UserPromptExpansion
1611</h4>1634</h4>
1612 1635
1613Además de los [campos de entrada comunes](#common-input-fields), los hooks UserPromptExpansion reciben `expansion_type`, `command_name`, `command_args`, `command_source` y la cadena `prompt` original. El campo `expansion_type` es `slash_command` para skills y comandos personalizados, o `mcp_prompt` para los prompts de servidores MCP.1636Además de los [campos de entrada comunes](#common-input-fields), los hooks UserPromptExpansion reciben `expansion_type`, `command_name`, `command_args`, `command_source` y la cadena `prompt` original. El campo `expansion_type` es `slash_command` para skills y comandos personalizados, o `mcp_prompt` para prompts de servidores MCP.
1614 1637
1615```json theme={null}1638```json theme={null}
1616{1639{
1637| :- | :- |1660| :- | :- |
1638| `decision` | `"block"` impide que el comando se expanda. Omítelo para permitir que continúe |1661| `decision` | `"block"` impide que el comando se expanda. Omítelo para permitir que continúe |
1639| `reason` | Se muestra al usuario cuando `decision` es `"block"` |1662| `reason` | Se muestra al usuario cuando `decision` es `"block"` |
1640| `additionalContext` | Cadena agregada al contexto de Claude junto con el prompt expandido. Consulta [Agregar contexto para Claude](#add-context-for-claude) |1663| `additionalContext` | Cadena que se agrega al contexto de Claude junto con el prompt expandido. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
1641 1664
1642Un hook que bloquea terminando con 2 se enruta igual que `reason`: el mensaje de bloqueo muestra al usuario el texto de stderr.1665Un hook que bloquea saliendo con 2 se enruta igual que `reason`: el mensaje de bloqueo muestra el texto de stderr al usuario.
1643 1666
1644```json theme={null}1667```json theme={null}
1645{1668{
1656 MessageDisplay1679 MessageDisplay
1657</h3>1680</h3>
1658 1681
1659Se 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.1682Se 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 en su lugar el texto de reemplazo del hook. Un mensaje largo produce varias llamadas; un mensaje corto puede producir solo una.
1660 1683
1661Usa MessageDisplay para:1684Usa MessageDisplay para:
1662 1685
1663* quitar el markdown para una visualización mínima1686* quitar el markdown para una visualización minimalista
1664* transformar el texto que una aplicación del Agent SDK muestra a sus usuarios1687* transformar el texto que una aplicación del Agent SDK muestra a sus usuarios
1665* ocultar claves de API o nombres de host internos de las respuestas de Claude1688* ocultar claves de API o nombres de host internos de las respuestas de Claude
1666 1689
1667Claude 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.1690Claude Code retiene cada lote hasta que tu hook devuelve un resultado, 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.
1668 1691
1669MessageDisplay 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.1692MessageDisplay es solo de visualización: el texto de reemplazo cambia únicamente 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, así que los resultados de herramientas y el texto que escribes se renderizan sin cambios.
1670 1693
1671MessageDisplay 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.1694MessageDisplay 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.
1672 1695
1673En 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.1696En 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 contiene 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.
1674 1697
1675<h4 id="messagedisplay-input">1698<h4 id="messagedisplay-input">
1676 Entrada de MessageDisplay1699 Entrada de MessageDisplay
1677</h4>1700</h4>
1678 1701
1679Ademá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.1702Ademá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 lo largo de un mensaje en lugar de esperar que las líneas se agrupen de una manera concreta.
1680 1703
1681| Campo | Descripción |1704| Campo | Descripción |
1682| :- | :- |1705| :- | :- |
1683| `turn_id` | UUID del turno actual |1706| `turn_id` | UUID del turno actual |
1684| `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 |1707| `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 puede correlacionarse con los ids de mensajes de la transcripción |
1685| `index` | Índice, empezando en cero, de este lote dentro del mensaje |1708| `index` | Índice, empezando en cero, de este lote dentro del mensaje |
1686| `final` | `true` en el último lote del mensaje. Cada mensaje tiene exactamente un lote final |1709| `final` | `true` en el último lote del mensaje. Cada mensaje tiene exactamente un lote final |
1687| `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 |1710| `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 con 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 `claude -p`, la única llamada contiene el mensaje completo |
1688 1711
1689```json theme={null}1712```json theme={null}
1690{1713{
1704 Salida de MessageDisplay1727 Salida de MessageDisplay
1705</h4>1728</h4>
1706 1729
1707Ademá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:1730Ademá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:
1708 1731
1709| Campo | Descripción |1732| Campo | Descripción |
1710| :- | :- |1733| :- | :- |
1711| `displayContent` | Texto que se muestra en lugar del delta. Omítelo para mostrar el original |1734| `displayContent` | Texto que se muestra en lugar del delta. Omítelo para mostrar el original |
1712 1735
1713Los 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`.1736Los 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 el `displayContent` de su salida JSON y descarta `systemMessage` y `continue`.
1714 1737
1715Este 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`.1738Este 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 los acentos graves del código en línea de `delta` y devuelve el resultado como `displayContent`.
1716 1739
1717<Tabs>1740<Tabs>
1718 <Tab title="macOS/Linux">1741 <Tab title="macOS/Linux">
1771 }1794 }
1772 ```1795 ```
1773 1796
1774 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.1797 El flag `-NoProfile` omite la carga de tu perfil de PowerShell para que el hook se inicie rápido, y `-ExecutionPolicy Bypass` permite que PowerShell ejecute el archivo de script local.
1775 1798
1776 Guarda este script en `.claude/hooks/plain-display.ps1` en tu proyecto:1799 Guarda este script en `.claude/hooks/plain-display.ps1` en tu proyecto:
1777 1800
1788 </Tab>1811 </Tab>
1789</Tabs>1812</Tabs>
1790 1813
1791Los 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.1814Los lotes sin markdown pasan sin cambios. Si el script falla, por ejemplo porque falta `jq`, Claude Code muestra el texto original e indica el fallo solo en la [salida de depuración](#debug-hooks), no en la sesión.
1792 1815
1793<h3 id="pretooluse">1816<h3 id="pretooluse">
1794 PreToolUse1817 PreToolUse
1796 1819
1797Se 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).1820Se 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).
1798 1821
1799Para 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.1822Para ejecutar un hook cuando un archivo concreto cambia en el disco, sin importar qué lo haya escrito, 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.
1800 1823
1801<Warning>1824<Warning>
1802 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.1825 PreToolUse solo se ejecuta cuando Claude llama a una herramienta. De forma predeterminada, 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 al construir el prompt, así que no se dispara ningún hook PreToolUse para ellos, incluidos los hooks que coinciden con `Read`. PreToolUse tampoco se dispara para [`EndConversation`](/docs/es/tools-reference#endconversation-tool-behavior).
1826
1827 Puedes bloquear rutas concretas de las referencias `@` o desactivar la inserción:
1803 1828
1804 PreToolUse tampoco se activa para [`EndConversation`](/docs/es/tools-reference#endconversation-tool-behavior).1829 * **Bloquear rutas concretas**: agrega una [regla de denegación de `Read`](/docs/es/permissions#read-and-edit) para ellas
1830 * **Desactivar la inserción**: establece [`CLAUDE_CODE_DISABLE_FILE_MENTIONS=1`](/docs/es/env-vars#variables) en tu shell, en la configuración de usuario o en la configuración administrada. Claude recibe entonces las rutas mencionadas con una nota para leerlas con sus herramientas de archivos. Si lo hace, se ejecutan tus hooks PreToolUse que coincidan. La variable requiere Claude Code v2.1.299 o posterior, y Claude Code la ignora en la configuración de proyecto y local.
1805</Warning>1831</Warning>
1806 1832
1807Usa el [control de decisiones de PreToolUse](#pretooluse-decision-control) para permitir, denegar, preguntar o diferir la llamada a herramienta.1833Usa el [control de decisiones de PreToolUse](#pretooluse-decision-control) para permitir, denegar, preguntar o diferir la llamada a herramienta.
1816 1842
1817Para 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.1843Para 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.
1818 1844
1819Para las herramientas de archivos `Write`, `Edit` y `Read`, `tool_input.file_path` siempre es absoluta:1845Para las herramientas de archivos `Write`, `Edit` y `Read`, `tool_input.file_path` siempre es absoluto:
1820 1846
1821* 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 ruta1847* Claude Code expande `~` y las rutas relativas antes de que se ejecuten los hooks, así que un hook que hace coincidir rutas no puede eludirse mediante `~` o una forma relativa de escribir la misma ruta
1822* 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`1848* En Windows, la ruta llega con barras invertidas como separadores, incluso cuando tu hook se ejecuta en Git Bash, donde `$PWD` tiene el aspecto de `/c/project`
1823* 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 bloquear1849* 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
1824* 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 absoluta1850* 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
1825 1851
1854| `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 |1880| `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 |
1855| `run_in_background` | boolean | `false` | Si se ejecuta el comando en segundo plano |1881| `run_in_background` | boolean | `false` | Si se ejecuta el comando en segundo plano |
1856 1882
1857Cuando 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.1883Cuando un comando de Bash cambia archivos en un repositorio de Git, Claude Code puede registrar qué 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.
1858 1884
1859Luego, 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.1885Tu [hook PostToolUse](#posttooluse) recibe entonces los archivos cambiados en `tool_response.bashEditDiff`. La lista abarca lo que cambió dentro del repositorio mientras se ejecutaba el comando. Los archivos que Git ignora y los archivos de submódulos no se incluyen. Requiere Claude Code v2.1.269 o posterior.
1860 1886
1861<Note>1887<Note>
1862 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.1888 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 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.
1863</Note>1889</Note>
1864 1890
1865`changedFiles` y `files` enumeran lo que cambió el comando; los demás campos indican qué tan completa y qué tan confiable es esa lista.1891`changedFiles` y `files` enumeran lo que cambió el comando; los campos restantes indican qué tan completa y qué tan fiable es esa lista.
1866 1892
1867| Campo | Tipo | Ejemplo | Descripción |1893| Campo | Tipo | Ejemplo | Descripción |
1868| :- | :- | :- | :- |1894| :- | :- | :- | :- |
1869| `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 |1895| `changedFiles` | array | `["/path/to/src/app.ts"]` | Rutas absolutas de los archivos que cambió el comando, 200 como máximo. Presente siempre que `files` contenga un diff o `moreFiles` sea mayor que cero |
1870| `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ó |1896| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diffs de hasta 5 archivos cambiados, para visualización. `created` o `deleted` es `true` para un archivo que el comando agregó o eliminó |
1871| `moreFiles` | number | `2` | Cantidad de archivos cambiados sin diff en `files` |1897| `moreFiles` | number | `2` | Cantidad de archivos cambiados sin diff en `files` |
1872| `unavailable` | boolean | `true` | Se establece cuando el diff está incompleto o no se pudo obtener |1898| `unavailable` | boolean | `true` | Se establece cuando el diff está incompleto o no se pudo obtener |
1873| `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 |1899| `skipped` | boolean | `true` | Se establece para un comando de Git que mueve el árbol de trabajo, como `git checkout` o `git stash`, por lo que Claude Code no obtiene ningún diff |
1874| `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 |1900| `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 |
1875 1901
1876<a id="powershell" />1902<a id="powershell" />
1877 1903
1892 1918
1893Usa `Bash|PowerShell` como matcher en los hooks que inspeccionan comandos de shell, para que cubran ambas herramientas:1919Usa `Bash|PowerShell` como matcher en los hooks que inspeccionan comandos de shell, para que cubran ambas herramientas:
1894 1920
1895* 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.1921* En Windows, siempre que la herramienta PowerShell esté habilitada, Claude trata PowerShell como el shell principal y dirige los comandos de shell a través de él.
1896* En Windows sin Git Bash, la herramienta se habilita automáticamente y Claude Code no registra la herramienta Bash en absoluto.1922* En Windows sin Git Bash, la herramienta se habilita automáticamente y Claude Code no registra la herramienta Bash en absoluto.
1897* Un hook que coincide solo con `Bash` nunca se activa ahí.1923* Un hook que coincide solo con `Bash` nunca se dispara allí.
1898 1924
1899<h5 id="write">1925<h5 id="write">
1900 Write1926 Write
1924 Read1950 Read
1925</h5>1951</h5>
1926 1952
1927Lee el contenido de archivos.1953Lee el contenido de un archivo.
1928 1954
1929| Campo | Tipo | Ejemplo | Descripción |1955| Campo | Tipo | Ejemplo | Descripción |
1930| :- | :- | :- | :- |1956| :- | :- | :- | :- |
1931| `file_path` | string | `"/path/to/file.txt"` | Ruta absoluta al archivo que se leerá |1957| `file_path` | string | `"/path/to/file.txt"` | Ruta absoluta al archivo que se leerá |
1932| `offset` | number | `10` | Número de línea opcional desde el que se empieza a leer |1958| `offset` | number | `10` | Número de línea opcional desde el cual empezar a leer |
1933| `limit` | number | `50` | Número opcional de líneas que se leerán |1959| `limit` | number | `50` | Número opcional de líneas que se leerán |
1934 1960
1935<h5 id="glob">1961<h5 id="glob">
1936 Glob1962 Glob
1937</h5>1963</h5>
1938 1964
1939Encuentra archivos que coinciden con un patrón glob.1965Busca archivos que coincidan con un patrón glob.
1940 1966
1941| Campo | Tipo | Ejemplo | Descripción |1967| Campo | Tipo | Ejemplo | Descripción |
1942| :- | :- | :- | :- |1968| :- | :- | :- | :- |
1943| `pattern` | string | `"**/*.ts"` | Patrón glob con el que se compararán los archivos |1969| `pattern` | string | `"**/*.ts"` | Patrón glob con el que se comparan los archivos |
1944| `path` | string | `"/path/to/dir"` | Directorio opcional en el que buscar. De forma predeterminada es el directorio de trabajo actual |1970| `path` | string | `"/path/to/dir"` | Directorio opcional donde buscar. De forma predeterminada, el directorio de trabajo actual |
1945 1971
1946<h5 id="grep">1972<h5 id="grep">
1947 Grep1973 Grep
1948</h5>1974</h5>
1949 1975
1950Busca en el contenido de archivos con expresiones regulares.1976Busca en el contenido de los archivos con expresiones regulares.
1951 1977
1952| Campo | Tipo | Ejemplo | Descripción |1978| Campo | Tipo | Ejemplo | Descripción |
1953| :- | :- | :- | :- |1979| :- | :- | :- | :- |
1954| `pattern` | string | `"TODO.*fix"` | Patrón de expresión regular que se buscará |1980| `pattern` | string | `"TODO.*fix"` | Patrón de expresión regular que se buscará |
1955| `path` | string | `"/path/to/dir"` | Archivo o directorio opcional en el que buscar |1981| `path` | string | `"/path/to/dir"` | Archivo o directorio opcional donde buscar |
1956| `glob` | string | `"*.ts"` | Patrón glob opcional para filtrar archivos |1982| `glob` | string | `"*.ts"` | Patrón glob opcional para filtrar archivos |
1957| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"` o `"count"`. De forma predeterminada es `"files_with_matches"` |1983| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"` o `"count"`. De forma predeterminada, `"files_with_matches"` |
1958| `-i` | boolean | `true` | Búsqueda sin distinguir mayúsculas de minúsculas |1984| `-i` | boolean | `true` | Búsqueda sin distinguir mayúsculas de minúsculas |
1959| `multiline` | boolean | `false` | Habilita la coincidencia multilínea |1985| `multiline` | boolean | `false` | Habilita la coincidencia multilínea |
1960 1986
1986 Agent2012 Agent
1987</h5>2013</h5>
1988 2014
1989Inicia un [subagente](/docs/es/sub-agents).2015Genera un [subagente](/docs/es/sub-agents).
1990 2016
1991| Campo | Tipo | Ejemplo | Descripción |2017| Campo | Tipo | Ejemplo | Descripción |
1992| :- | :- | :- | :- |2018| :- | :- | :- | :- |
1995| `subagent_type` | string | `"Explore"` | Tipo de agente especializado que se usará |2021| `subagent_type` | string | `"Explore"` | Tipo de agente especializado que se usará |
1996| `model` | string | `"sonnet"` | Alias de modelo opcional para sobrescribir el predeterminado |2022| `model` | string | `"sonnet"` | Alias de modelo opcional para sobrescribir el predeterminado |
1997 2023
1998Cuando 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:2024Cuando se completa una llamada a Agent en primer plano, 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 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` solo cubren la solicitud final:
1999 2025
2000| Campo | Tipo | Ejemplo | Descripción |2026| Campo | Tipo | Ejemplo | Descripción |
2001| :- | :- | :- | :- |2027| :- | :- | :- | :- |
2002| `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"` |2028| `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"` |
2003| `agentId` | string | `"a4d2c8f1e0b3a297"` | Identificador de la ejecución del subagente |2029| `agentId` | string | `"a4d2c8f1e0b3a297"` | Identificador de la ejecución del subagente |
2004| `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 |2030| `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 |
2005| `resolvedModel` | string | `"claude-sonnet-4-5"` | Modelo con el que empezó el subagente, que puede ser distinto del modelo solicitado |2031| `resolvedModel` | string | `"claude-sonnet-4-5"` | Modelo con el que comenzó el subagente, que puede diferir del modelo solicitado |
2006| `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 |2032| `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 |
2007| `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 |2033| `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 |
2008| `totalDurationMs` | number | `48211` | Duración en tiempo real de la ejecución del subagente |2034| `totalDurationMs` | number | `48211` | Duración en tiempo real de la ejecución del subagente |
2009| `totalToolUseCount` | number | `7` | Cantidad de llamadas a herramientas que hizo el subagente |2035| `totalToolUseCount` | number | `7` | Cantidad de llamadas a herramientas que hizo el subagente |
2010| `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` |2036| `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` |
2011 2037
2012En 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`.2038En 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 en sí. Para leer el informe, haz que un hook `PreToolUse` o `PostToolUse` coincida con `SubagentHandback` y lee `tool_input.message`.
2013 2039
2014Para 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`.2040Para los subagentes en segundo plano, la herramienta devuelve un resultado cuando la tarea pasa al segundo plano, así que `tool_response` no incluye campos de uso: un lanzamiento en segundo plano devuelve el resultado de inmediato, y una tarea en primer plano que Claude Code pasa al segundo plano a mitad de la ejecución lo devuelve en esa transición. Tiene `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` y `resolvedModel`.
2015 2041
2016En 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.2042En una respuesta `completed`, `resolvedModel` nombra el modelo con el que comenzó el subagente, que puede diferir del valor `model` de `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ó al segundo plano, así que un cambio ocurrido antes de pasar al segundo plano se refleja allí. `modelsUsed` y el comportamiento de `resolvedModel` en el momento de pasar al segundo plano requieren Claude Code v2.1.212 o posterior.
2017 2043
2018<a id="askuserquestion" />2044<a id="askuserquestion" />
2019 2045
2021 AskUserQuestion2047 AskUserQuestion
2022</h5>2048</h5>
2023 2049
2024Hace al usuario de una a cuatro preguntas de opción múltiple.2050Le hace al usuario de una a cuatro preguntas de opción múltiple.
2025 2051
2026| Campo | Tipo | Ejemplo | Descripción |2052| Campo | Tipo | Ejemplo | Descripción |
2027| :- | :- | :- | :- |2053| :- | :- | :- | :- |
2028| `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 |2054| `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 |
2029| `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 |2055| `answers` | object | `{"Which framework?": "React"}` | Opcional. Asigna el texto de cada 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 |
2030 2056
2031<h5 id="exitplanmode">2057<h5 id="exitplanmode">
2032 ExitPlanMode2058 ExitPlanMode
2033</h5>2059</h5>
2034 2060
2035Presenta 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.2061Presenta un plan y le 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.
2036 2062
2037| Campo | Tipo | Ejemplo | Descripción |2063| Campo | Tipo | Ejemplo | Descripción |
2038| :- | :- | :- | :- |2064| :- | :- | :- | :- |
2039| `plan` | string | `"## Refactor auth\n1. Extract..."` | Contenido del plan en Markdown. Se inyecta desde el archivo del plan en el disco |2065| `plan` | string | `"## Refactor auth\n1. Extract..."` | Contenido del plan en Markdown. Se inyecta desde el archivo del plan en el disco |
2040| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Ruta al archivo del plan. Se inyecta |2066| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Ruta al archivo del plan. Se inyecta |
2041| `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 |2067| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Obsoleto. Claude Code acepta el campo pero lo ignora. Antes de la v2.1.205, contenía permisos basados en prompts que Claude solicitaba para implementar el plan |
2042 2068
2043En `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.2069En `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.
2044 2070
2045<h4 id="pretooluse-decision-control">2071<h4 id="pretooluse-decision-control">
2046 Control de decisiones de PreToolUse2072 Control de decisiones de PreToolUse
2047</h4>2073</h4>
2048 2074
2049Los 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.2075Los 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) y la capacidad de modificar la entrada de la herramienta antes de la ejecución.
2050 2076
2051| Campo | Descripción |2077| Campo | Descripción |
2052| :- | :- |2078| :- | :- |
2053| `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), para las [lecturas desde rutas de red](/docs/es/permissions#network-paths), y para `AskUserQuestion` y `ExitPlanMode`, que necesitan [`updatedInput` junto con él](#allow-with-updatedinput). `"deny"` impide la llamada a herramienta. `"ask"` pide confirmación al usuario. `"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 independientemente de lo que devuelva el hook |2079| `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), para las [lecturas desde rutas de red](/docs/es/permissions#network-paths) 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 independientemente de lo que devuelva el hook |
2054| `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) |2080| `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 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) |
2055| `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 |2081| `updatedInput` | Modifica los parámetros de entrada de la herramienta antes de la ejecución. Reemplaza el objeto de entrada completo, 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 de Bash con la entrada que devuelve tu hook, no con 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 |
2056| `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) |2082| `additionalContext` | Cadena que se agrega 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) |
2057 2083
2058Cuando varios hooks PreToolUse devuelven decisiones diferentes, la precedencia es `deny` > `defer` > `ask` > `allow`.2084Cuando varios hooks PreToolUse devuelven decisiones diferentes, la precedencia es `deny` > `defer` > `ask` > `allow`.
2059 2085
2060Un hook que bloquea terminando con 2 se enruta igual que `"deny"`: Claude ve el mensaje de stderr como el motivo de la denegación.2086Un hook que bloquea saliendo con 2 se enruta igual que `"deny"`: Claude ve el mensaje de stderr como el motivo de la denegación.
2061 2087
2062Cuando 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.2088Cuando 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 solicita la confirmación.
2063 2089
2064Un `"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.2090El `"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 aún 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 de 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.
2065 2091
2066```json theme={null}2092```json theme={null}
2067{2093{
2078```2104```
2079 2105
2080<Note>2106<Note>
2081 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.2107 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.
2082</Note>2108</Note>
2083 2109
2084<h4 id="allow-with-updatedinput">2110<h4 id="allow-with-updatedinput">
2090Un hook `PreToolUse` cumple ese requisito cuando hace lo siguiente:2116Un hook `PreToolUse` cumple ese requisito cuando hace lo siguiente:
2091 2117
20921. Lee la entrada de la herramienta desde stdin21181. Lee la entrada de la herramienta desde stdin
20932. Recopila la respuesta mediante tu propia interfaz de usuario21192. Recopila la respuesta mediante tu propia interfaz
20943. Devuelve `permissionDecision: "allow"` junto con un `updatedInput` que contiene la respuesta, para que la herramienta se ejecute sin pedir confirmación21203. Devuelve `permissionDecision: "allow"` junto con un `updatedInput` que contiene la respuesta, para que la herramienta se ejecute sin pedir confirmación
2095 2121
2096Devolver solo `"allow"` no es suficiente para estas herramientas.2122Devolver solo `"allow"` no es suficiente para estas herramientas.
2117}2143}
2118```2144```
2119 2145
2120Una 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.2146Una 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 haya recopilado la interacción que necesita la herramienta.
2121 2147
2122<h4 id="defer-a-tool-call-for-later">2148<h4 id="defer-a-tool-call-for-later">
2123 Diferir una llamada a herramienta para más tarde2149 Diferir una llamada a herramienta para más tarde
2124</h4>2150</h4>
2125 2151
2126`"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.2152`"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 llamador pause a Claude en una llamada a herramienta, recopile la 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.
2127 2153
2128La 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í:2154La herramienta `AskUserQuestion` es el caso típico: Claude quiere preguntarle algo al usuario, pero no hay una terminal donde 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í:
2129 2155
21301. Claude llama a `AskUserQuestion`. Se activa el hook `PreToolUse`.21561. Claude llama a `AskUserQuestion`. Se dispara el hook `PreToolUse`.
21312. 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.21572. 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.
21323. 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.21583. El proceso llamador lee `deferred_tool_use` del resultado del SDK, muestra la pregunta en su propia interfaz y espera una respuesta.
21334. 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`.21594. El proceso llamador ejecuta `claude -p --resume <session-id>` con el mismo host de permisos. La misma llamada a herramienta vuelve a disparar `PreToolUse`.
21345. El hook devuelve `permissionDecision: "allow"` con la respuesta en `updatedInput`. La herramienta se ejecuta y Claude continúa.21605. El hook devuelve `permissionDecision: "allow"` con la respuesta en `updatedInput`. La herramienta se ejecuta y Claude continúa.
2135 2161
2136El 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:2162El 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:
2149}2175}
2150```2176```
2151 2177
2152No 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.2178No hay tiempo de espera ni límite de reintentos. La sesión permanece en el disco hasta que la reanudes, 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 manera. El proceso llamador controla cuándo romper el ciclo devolviendo finalmente `"allow"` o `"deny"` desde el hook.
2153 2179
2154`"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.2180`"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. Esta 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.
2155 2181
2156Si 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.2182Si 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 falta.
2157 2183
2158<Note>2184<Note>
2159 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. Para las demás condiciones, consulta [Reanudar en modo plan con `-p`](/docs/es/sessions#resume-in-plan-mode-with-p). Requiere Claude Code v2.1.246 o posterior.2185 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. Para las demás condiciones, consulta [Reanudar en modo plan con `-p`](/docs/es/sessions#resume-in-plan-mode-with-p). Requiere Claude Code v2.1.246 o posterior.
2160 2186
2161 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).2187 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 ejecución nueva 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 que se indican en [modo de permisos al reanudar](/docs/es/sessions#permission-mode-on-resume).
2162</Note>2188</Note>
2163 2189
2164<h3 id="permissionrequest">2190<h3 id="permissionrequest">
2165 PermissionRequest2191 PermissionRequest
2166</h3>2192</h3>
2167 2193
2168Se 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.2194Se 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 lo que decida primero.
2169Usa el [control de decisiones de PermissionRequest](#permissionrequest-decision-control) para permitir o denegar en nombre del usuario.2195Usa el [control de decisiones de PermissionRequest](#permissionrequest-decision-control) para permitir o denegar en nombre del usuario.
2170 2196
2171Usa 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.2197Usa 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 haya esperado unos seis segundos.
2172 2198
2173Claude 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`.2199Claude 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 para esa solicitud, usa el tipo de notificación `permission_prompt`.
2174 2200
2175Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.2201Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.
2176 2202
2180 2206
2181Los 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.2207Los 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.
2182 2208
2183El 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.2209El 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 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 aun así omitir 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.
2184 2210
2185Los 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).2211Los 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).
2186 2212
2187```json theme={null}2213```json theme={null}
2188{2214{
2215 2241
2216| Campo | Descripción |2242| Campo | Descripción |
2217| :- | :- |2243| :- | :- |
2218| `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 |2244| `behavior` | `"allow"` concede el permiso, `"deny"` lo deniega. Las [reglas deny y ask](/docs/es/permissions#manage-permissions) se siguen evaluando, por lo que un hook que devuelve `"allow"` no sobrescribe una regla deny coincidente |
2219| `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 |2245| `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 deny y ask |
2220| `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 |2246| `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 |
2221| `message` | Solo para `"deny"`: le indica a Claude por qué se denegó el permiso |2247| `message` | Solo para `"deny"`: le indica a Claude por qué se denegó el permiso |
2222| `interrupt` | Solo para `"deny"`: si es `true`, detiene a Claude |2248| `interrupt` | Solo para `"deny"`: si es `true`, detiene a Claude |
2223 2249
2224Un hook que sale con 2 sin un objeto `decision` deja el flujo de permisos sin cambios, y su stderr se descarta. Para conceder o denegar la solicitud, devuelve el objeto `decision`.2250Un hook que sale con 2 sin un objeto `decision` deja sin cambios el flujo de permisos, y su stderr se descarta. Para conceder o denegar la solicitud, devuelve el objeto `decision`.
2225 2251
2226```json theme={null}2252```json theme={null}
2227{2253{
2241 Entradas de actualización de permisos2267 Entradas de actualización de permisos
2242</h4>2268</h4>
2243 2269
2244El 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.2270El 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.
2245 2271
2246| `type` | Campos | Efecto |2272| `type` | Campos | Efecto |
2247| :- | :- | :- |2273| :- | :- | :- |
2253| `removeDirectories` | `directories`, `destination` | Elimina directorios de trabajo |2279| `removeDirectories` | `directories`, `destination` | Elimina directorios de trabajo |
2254 2280
2255<Note>2281<Note>
2256 `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).2282 `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).
2257 2283
2258 `bypassPermissions` nunca se guarda como `defaultMode`, independientemente de `destination`.2284 `bypassPermissions` nunca se persiste como `defaultMode`, independientemente de `destination`.
2259</Note>2285</Note>
2260 2286
2261El campo `destination` de cada entrada determina si el cambio se queda en memoria o se guarda en un archivo de configuración.2287El campo `destination` de cada entrada determina si el cambio permanece en memoria o se persiste en un archivo de configuración.
2262 2288
2263| `destination` | Escribe en |2289| `destination` | Escribe en |
2264| :- | :- |2290| :- | :- |
2267| `projectSettings` | `.claude/settings.json` |2293| `projectSettings` | `.claude/settings.json` |
2268| `userSettings` | `~/.claude/settings.json` |2294| `userSettings` | `~/.claude/settings.json` |
2269 2295
2270Un hook puede devolver una de las `permission_suggestions` que recibió como su propia salida `updatedPermissions`.2296Un hook puede repetir una de las `permission_suggestions` que recibió como su propia salida `updatedPermissions`.
2271 2297
2272<h3 id="posttooluse">2298<h3 id="posttooluse">
2273 PostToolUse2299 PostToolUse
2275 2301
2276Se ejecuta inmediatamente después de que una herramienta se completa correctamente.2302Se ejecuta inmediatamente después de que una herramienta se completa correctamente.
2277 2303
2278Hace coincidencia por nombre de herramienta, con los mismos valores que PreToolUse.2304Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.
2279 2305
2280Haz coincidencias más amplias cuando el nombre de la herramienta no sea el filtro adecuado:2306Usa una coincidencia más amplia cuando el nombre de la herramienta no sea el filtro adecuado:
2281 2307
2282* 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).2308* 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 enumera los archivos sin seguimiento que `git diff` pasa por alto. Para las llamadas a herramientas que fallan, agrega el mismo hook en [PostToolUseFailure](#posttoolusefailure).
2283* 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.2309* 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 externo a Claude Code reescribe el mismo archivo.
2284 2310
2285<h4 id="posttooluse-input">2311<h4 id="posttooluse-input">
2286 Entrada de PostToolUse2312 Entrada de PostToolUse
2287</h4>2313</h4>
2288 2314
2289Los hooks `PostToolUse` se activan después de que una herramienta ya se ejecutó correctamente. La entrada incluye tanto `tool_input`, los argumentos enviados a la herramienta, como `tool_response`, el resultado que devolvió. El esquema exacto de ambos depende de la herramienta. Las rutas de `tool_input` de las herramientas de archivos llegan en el mismo formato que para [PreToolUse](#pretooluse-input): siempre absolutas, con los separadores nativos de la plataforma, es decir, barras invertidas en Windows. Para una herramienta MCP, la entrada también incluye el objeto [`mcp_server`](#pretooluse-input).2315Los hooks `PostToolUse` se disparan después de que una herramienta ya se ejecutó correctamente. La entrada incluye tanto `tool_input`, los argumentos enviados a la herramienta, como `tool_response`, el resultado que devolvió. El esquema exacto de ambos depende de la herramienta. Las rutas de `tool_input` de las herramientas de archivos llegan en el mismo formato que para [PreToolUse](#pretooluse-input): siempre absolutas, con los separadores nativos de la plataforma, es decir, barras invertidas en Windows. Para una herramienta MCP, la entrada también incluye el objeto [`mcp_server`](#pretooluse-input).
2290 2316
2291```json theme={null}2317```json theme={null}
2292{2318{
2311 2337
2312| Campo | Descripción |2338| Campo | Descripción |
2313| :- | :- |2339| :- | :- |
2314| `duration_ms` | Opcional. Tiempo de ejecución de la herramienta en milisegundos. Excluye el tiempo dedicado a solicitudes de permiso y a hooks PreToolUse |2340| `duration_ms` | Opcional. Tiempo de ejecución de la herramienta en milisegundos. Excluye el tiempo dedicado a las solicitudes de permiso y a los hooks PreToolUse |
2315 2341
2316<h4 id="posttooluse-decision-control">2342<h4 id="posttooluse-decision-control">
2317 Control de decisiones de PostToolUse2343 Control de decisiones de PostToolUse
2324| `decision` | `"block"` agrega el `reason` junto al resultado de la herramienta. Claude sigue viendo la salida original; para reemplazarla, usa `updatedToolOutput` |2350| `decision` | `"block"` agrega el `reason` junto al resultado de la herramienta. Claude sigue viendo la salida original; para reemplazarla, usa `updatedToolOutput` |
2325| `reason` | Explicación que se muestra a Claude cuando `decision` es `"block"` |2351| `reason` | Explicación que se muestra a Claude cuando `decision` es `"block"` |
2326| `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) |2352| `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) |
2327| `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 |2353| `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 |
2328| `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 |2354| `updatedToolOutput` | Reemplaza la salida de la herramienta con el valor proporcionado antes de enviarla a Claude. El valor debe coincidir con la forma de la salida de la herramienta |
2329| `updatedMCPToolOutput` | Reemplaza la salida solo para [herramientas MCP](#match-mcp-tools). Es preferible usar `updatedToolOutput`, que funciona para todas las herramientas |2355| `updatedMCPToolOutput` | Reemplaza la salida solo para [herramientas MCP](#match-mcp-tools). Prefiere `updatedToolOutput`, que funciona para todas las herramientas |
2330 2356
2331El siguiente ejemplo reemplaza la salida de una llamada a `Bash`. El valor de reemplazo coincide con la forma de salida de la herramienta `Bash`:2357El siguiente ejemplo reemplaza la salida de una llamada a `Bash`. El valor de reemplazo coincide con la forma de la salida de la herramienta `Bash`:
2332 2358
2333```json theme={null}2359```json theme={null}
2334{2360{
2346```2372```
2347 2373
2348<Warning>2374<Warning>
2349 `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).2375 `updatedToolOutput` solo cambia lo que ve Claude. La herramienta ya se ejecutó cuando se dispara 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).
2350 2376
2351 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.2377 El valor de reemplazo debe coincidir con la forma de la 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 proceda con una suposición falsa.
2352</Warning>2378</Warning>
2353 2379
2354<h4 id="annotate-a-result-for-the-auto-mode-classifier">2380<h4 id="annotate-a-result-for-the-auto-mode-classifier">
2355 Anotar un resultado para el clasificador del modo automático2381 Anotar un resultado para el clasificador del modo automático
2356</h4>2382</h4>
2357 2383
2358Devuelve `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.2384Devuelve `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 indicarle algo sobre lo que devolvió una llamada antes de que revise acciones posteriores. El campo requiere Claude Code v2.1.236 o posterior.
2359 2385
2360El siguiente ejemplo le indica al clasificador de dónde provino la salida de una consulta:2386El siguiente ejemplo le indica al clasificador de dónde provino la salida de una consulta:
2361 2387
2370 2396
2371El peso que el clasificador le da a la nota depende de dónde configuraste el hook:2397El peso que el clasificador le da a la nota depende de dónde configuraste el hook:
2372 2398
2373* **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ón2399* **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ón
2374* **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 verificada2400* **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 en vivo, 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 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 verificada
2375 2401
2376Claude Code aplica estos límites al entregar la nota:2402Claude Code aplica estos límites al entregar la nota:
2377 2403
2378* **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 llamada2404* **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
2379* **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 herramienta2405* **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
2380* **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 llamadas2406* **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 llamadas
2381* **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 salida2407* **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
2382 2408
2383<Warning>2409<Warning>
2384 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.2410 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 hecho 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.
2385</Warning>2411</Warning>
2386 2412
2387<h3 id="posttoolusefailure">2413<h3 id="posttoolusefailure">
2390 2416
2391Se 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.2417Se 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.
2392 2418
2393Hace coincidencia por nombre de herramienta, con los mismos valores que PreToolUse.2419Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.
2394 2420
2395<Note>2421<Note>
2396 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).2422 Este evento no se dispara para 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 de validación se devuelven como resultados `tool_use_error` y ocurren antes de que se ejecuten los hooks, por lo que no disparan ni `PreToolUse` ni `PostToolUseFailure`. Las denegaciones de permiso disparan `PreToolUse` pero no este evento; consulta [PermissionDenied](#permissiondenied).
2397</Note>2423</Note>
2398 2424
2399<h4 id="posttoolusefailure-input">2425<h4 id="posttoolusefailure-input">
2424| Campo | Descripción |2450| Campo | Descripción |
2425| :- | :- |2451| :- | :- |
2426| `error` | Cadena que describe qué salió mal. El formato depende de la herramienta que falló |2452| `error` | Cadena que describe qué salió mal. El formato depende de la herramienta que falló |
2427| `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 |2453| `is_interrupt` | Booleano opcional. Es true cuando el fallo llegó a Claude Code como una interrupción en lugar de como un error reportado por la herramienta. Cancelar una herramienta en ejecución no dispara este hook; en su lugar, el resultado de la herramienta contiene el mensaje de interrupción |
2428| `duration_ms` | Opcional. Tiempo de ejecución de la herramienta en milisegundos. Excluye el tiempo dedicado a solicitudes de permiso y a hooks PreToolUse |2454| `duration_ms` | Opcional. Tiempo de ejecución de la herramienta en milisegundos. Excluye el tiempo dedicado a las solicitudes de permiso y a los hooks PreToolUse |
2429 2455
2430La 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.2456La 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.
2431 2457
2432* 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 intercalados2458* 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 único bloque con stdout y stderr intercalados
2433* 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í2459* 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í
2434* 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`2460* 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`
2435 2461
2436<h4 id="posttoolusefailure-decision-control">2462<h4 id="posttoolusefailure-decision-control">
2437 Control de decisiones de PostToolUseFailure2463 Control de decisiones de PostToolUseFailure
2438</h4>2464</h4>
2439 2465
2440Los 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:2466Los hooks `PostToolUseFailure` pueden proporcionar contexto a Claude después de un fallo de una 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:
2441 2467
2442| Campo | Descripción |2468| Campo | Descripción |
2443| :- | :- |2469| :- | :- |
2456 PostToolBatch2482 PostToolBatch
2457</h3>2483</h3>
2458 2484
2459Se 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.2485Se 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 dispara una vez por herramienta, lo que significa que se dispara de forma concurrente cuando Claude hace llamadas a herramientas en paralelo. `PostToolBatch` se dispara 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.
2460 2486
2461<h4 id="posttoolbatch-input">2487<h4 id="posttoolbatch-input">
2462 Entrada de PostToolBatch2488 Entrada de PostToolBatch
2488}2514}
2489```2515```
2490 2516
2491`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.2517`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 números de línea como prefijo en lugar del contenido sin procesar del archivo. Las respuestas pueden ser grandes, así que analiza solo los campos que necesites.
2492 2518
2493<Note>2519<Note>
2494 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.2520 La forma de `tool_response` es distinta 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.
2495</Note>2521</Note>
2496 2522
2497<h4 id="posttoolbatch-decision-control">2523<h4 id="posttoolbatch-decision-control">
2502 2528
2503| Campo | Descripción |2529| Campo | Descripción |
2504| :- | :- |2530| :- | :- |
2505| `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 |2531| `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 conocer los detalles de entrega, qué incluir y cómo las sesiones reanudadas manejan los valores anteriores |
2506 2532
2507```json theme={null}2533```json theme={null}
2508{2534{
2513}2539}
2514```2540```
2515 2541
2516Devolver `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.2542Devolver `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 al salir con 2. Lo ves como una advertencia en la transcripción, y permanece en la conversación, así que Claude lo ve cuando la conversación continúa.
2517 2543
2518<h3 id="permissiondenied">2544<h3 id="permissiondenied">
2519 PermissionDenied2545 PermissionDenied
2520</h3>2546</h3>
2521 2547
2522Se 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.2548Se 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 porque su respuesta no se pudo analizar. Este hook solo se dispara en el modo automático: no se ejecuta cuando deniegas manualmente un diálogo de permisos, cuando un hook `PreToolUse` bloquea una llamada o cuando coincide una regla `deny`. Úsalo para registrar denegaciones, ajustar la configuración o indicarle al modelo que puede reintentar la llamada a herramienta.
2523 2549
2524Hace coincidencia por nombre de herramienta, con los mismos valores que PreToolUse.2550Coincide con el nombre de la herramienta, con los mismos valores que PreToolUse.
2525 2551
2526<h4 id="permissiondenied-input">2552<h4 id="permissiondenied-input">
2527 Entrada de PermissionDenied2553 Entrada de PermissionDenied
2548 2574
2549| Campo | Descripción |2575| Campo | Descripción |
2550| :- | :- |2576| :- | :- |
2551| `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` |2577| `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 conocer 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 del clasificador no estaba disponible, es el texto fijo `Classifier unavailable` |
2552 2578
2553<h4 id="permissiondenied-decision-control">2579<h4 id="permissiondenied-decision-control">
2554 Control de decisiones de PermissionDenied2580 Control de decisiones de PermissionDenied
2567 2593
2568Cuando `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.2594Cuando `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.
2569 2595
2570Claude 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.2596Claude 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 seguir adelante.
2571 2597
2572<h3 id="notification">2598<h3 id="notification">
2573 Notification2599 Notification
2574</h3>2600</h3>
2575 2601
2576Se 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.2602Se 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.
2577 2603
2578Recibes 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.2604Recibes 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.
2579 2605
2580| Matcher | Cuándo se activa |2606| Matcher | Cuándo se dispara |
2581| :- | :- |2607| :- | :- |
2582| `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 |2608| `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 |
2583| `idle_prompt` | Claude terminó de responder hace unos 60 segundos y no has escrito nada desde entonces |2609| `idle_prompt` | Claude terminó de responder hace unos 60 segundos y no has escrito nada desde entonces |
2584| `auth_success` | Se completa la autenticación |2610| `auth_success` | Se completa la autenticación |
2585| `elicitation_dialog` | Un servidor MCP abre un formulario de elicitación y no has escrito durante unos seis segundos |2611| `elicitation_dialog` | Un servidor MCP abre un formulario de elicitación y no has escrito nada durante unos seis segundos |
2586| `elicitation_url_dialog` | Un servidor MCP te pide abrir una URL en el navegador y no has escrito durante unos seis segundos |2612| `elicitation_url_dialog` | Un servidor MCP te pide que abras una URL en el navegador y no has escrito nada durante unos seis segundos |
2587| `elicitation_complete` | Un servidor MCP informa que una [elicitación en modo URL](#elicitation-input) se completó |2613| `elicitation_complete` | Un servidor MCP informa que una [elicitación en modo URL](#elicitation-input) se completó |
2588| `elicitation_response` | Se envía una respuesta de elicitación MCP de vuelta al servidor |2614| `elicitation_response` | Se envía una respuesta de elicitación MCP de vuelta al servidor |
2589| `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 |2615| `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 dispara 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 nada durante unos seis segundos |
2590| `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 |2616| `agent_completed` | Una sesión en segundo plano termina o falla. Se dispara solo mientras la [vista de agentes](/docs/es/agent-view) está abierta en una terminal |
2591| `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) |2617| `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 momento del 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) |
2592| `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 |2618| `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. Tras una suspensión más corta, continúa y dispara `quota_auto_resume_fired` en su lugar |
2593| `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** |2619| `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 dispara cuando presionas `Esc` o `Ctrl+C`, o eliges **Don't continue automatically** |
2594 2620
2595Los tipos `quota_auto_resume_fired`, `quota_auto_resume_stale` y `quota_auto_resume_disabled` requieren Claude Code v2.1.234 o posterior.2621Los tipos `quota_auto_resume_fired`, `quota_auto_resume_stale` y `quota_auto_resume_disabled` requieren Claude Code v2.1.234 o posterior.
2596 2622
2599`agent_needs_input` para la pregunta de configuración de terminal de un compañero requiere Claude Code v2.1.248 o posterior.2625`agent_needs_input` para la pregunta de configuración de terminal de un compañero requiere Claude Code v2.1.248 o posterior.
2600 2626
2601<Note>2627<Note>
2602 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:2628 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:
2603 2629
2604 * 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.2630 * 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.
2605 * 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_*`.2631 * 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 ejecutándose. 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 dispara en su lugar uno de los tipos `quota_auto_resume_*`.
2606 * 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.2632 * 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 diálogo, y cada pulsación de tecla lo aplaza.
2607 2633
2608 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.2634 Una solicitud de permiso o elicitación que llega mientras otro 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 diálogo abierto.
2609</Note>2635</Note>
2610 2636
2611Claude 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:2637Claude Code temporiza `permission_prompt` de forma diferente en las sesiones en las que 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:
2612 2638
2613* Espera `permission_prompt` unos seis segundos después de que Claude pida permiso. Claude Code no lo pospone mientras escribes.2639* Espera `permission_prompt` unos seis segundos después de que Claude pida permiso. Claude Code no lo aplaza mientras escribes.
2614* Si tú o un hook [PermissionRequest](#permissionrequest) responden antes, Claude Code no ejecuta `permission_prompt`.2640* Si tú o un hook [PermissionRequest](#permissionrequest) responden antes, Claude Code no ejecuta `permission_prompt`.
2615* Establece [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/es/env-vars) en `1` para desactivar `permission_prompt` en estas sesiones.2641* Establece [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/es/env-vars) en `1` para desactivar `permission_prompt` en estas sesiones.
2616 2642
2617Antes de v2.1.233, `permission_prompt` no se activaba en estas sesiones.2643Antes de v2.1.233, `permission_prompt` no se disparaba en estas sesiones.
2618 2644
2619Usa 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:2645Usa matchers separados para ejecutar distintos handlers 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:
2620 2646
2621```json theme={null}2647```json theme={null}
2622{2648{
2649 Entrada de Notification2675 Entrada de Notification
2650</h4>2676</h4>
2651 2677
2652Además de los [campos de entrada comunes](#common-input-fields), los hooks Notification reciben `message` con el texto de la notificación, un `title` opcional y `notification_type`, que indica qué tipo se activó.2678Además de los [campos de entrada comunes](#common-input-fields), los hooks Notification reciben `message` con el texto de la notificación, un `title` opcional y `notification_type`, que indica qué tipo se disparó.
2653 2679
2654```json theme={null}2680```json theme={null}
2655{2681{
2669 SubagentStart2695 SubagentStart
2670</h3>2696</h3>
2671 2697
2672Se 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.2698Se 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.
2673 2699
2674Para 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$`.2700Para los subagentes incluidos en un [plugin](/docs/es/plugins/overview), el tipo de agente es el identificador con alcance del plugin, como `my-plugin:reviewer`, no el nombre simple del frontmatter. Los dos puntos hacen que un nombre con alcance de plugin se evalúe como expresión regular, así que ancla el matcher con `^` y `$` para obtener una coincidencia exacta: `^my-plugin:reviewer$`.
2675 2701
2676<h4 id="subagentstart-input">2702<h4 id="subagentstart-input">
2677 Entrada de SubagentStart2703 Entrada de SubagentStart
2678</h4>2704</h4>
2679 2705
2680Además de los [campos de entrada comunes](#common-input-fields), los hooks SubagentStart reciben `agent_id` con el identificador único del subagente y `agent_type` con el nombre del agente sobre el que filtra el matcher.2706Además de los [campos de entrada comunes](#common-input-fields), los hooks SubagentStart reciben `agent_id` con el identificador único del subagente y `agent_type` con el nombre del agente por el que filtra el matcher.
2681 2707
2682```json theme={null}2708```json theme={null}
2683{2709{
2705}2731}
2706```2732```
2707 2733
2708Cuando el hook se vuelve a ejecutar para el mismo subagente, Claude Code inyecta el contexto devuelto solo cuando el contexto del subagente aún no contiene la copia de una ejecución anterior. La copia inyectada al inicio permanece en su lugar, lo que mantiene intacta la [caché de prompts](/docs/es/prompt-caching#subagents-and-the-cache) del subagente. Después de que la [compactación automática](/docs/es/sub-agents#auto-compaction) descarta esa copia, Claude Code vuelve a inyectar el contexto de la siguiente ejecución.2734Cuando el hook se ejecuta de nuevo para el mismo subagente, Claude Code inyecta el contexto devuelto solo cuando el contexto del subagente aún no contiene la copia de una ejecución anterior. La copia inyectada al inicio permanece en su lugar, lo que deja intacta la [caché de prompts](/docs/es/prompt-caching#subagents-and-the-cache) del subagente. Después de que la [compactación automática](/docs/es/sub-agents#auto-compaction) descarta esa copia, Claude Code vuelve a inyectar el contexto de la siguiente ejecución.
2709 2735
2710<h3 id="subagentstop">2736<h3 id="subagentstop">
2711 SubagentStop2737 SubagentStop
2712</h3>2738</h3>
2713 2739
2714Se ejecuta cuando un subagente de Claude Code terminó de responder. Hace coincidencia por tipo de agente, con los mismos valores que SubagentStart.2740Se ejecuta cuando un subagente de Claude Code terminó de responder. Coincide con el tipo de agente, con los mismos valores que SubagentStart.
2715 2741
2716<h4 id="subagentstop-input">2742<h4 id="subagentstop-input">
2717 Entrada de SubagentStop2743 Entrada de SubagentStop
2718</h4>2744</h4>
2719 2745
2720Además de los [campos de entrada comunes](#common-input-fields), los hooks SubagentStop reciben `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path` y `last_assistant_message`. El campo `agent_type` es el valor que se usa para el filtrado del matcher. `transcript_path` es la transcripción de la sesión principal, mientras que `agent_transcript_path` es la transcripción propia del subagente, almacenada en una carpeta anidada `subagents/`. El campo `last_assistant_message` contiene el contenido de texto de la respuesta final del subagente, para que los hooks puedan acceder a él sin analizar el archivo de transcripción.2746Además de los [campos de entrada comunes](#common-input-fields), los hooks SubagentStop reciben `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path` y `last_assistant_message`. El campo `agent_type` es el valor que se usa para el filtrado del matcher. `transcript_path` es la transcripción de la sesión principal, mientras que `agent_transcript_path` es la transcripción propia del subagente, almacenada en una carpeta anidada `subagents/`. El campo `last_assistant_message` contiene el contenido de texto de la respuesta final del subagente, de modo que los hooks pueden acceder a él sin analizar el archivo de transcripción.
2721 2747
2722No todos los eventos SubagentStop provienen de un subagente que Claude generó. Claude Code también ejecuta agentes internos para algunas de sus propias funciones, como las [sugerencias de prompts](/docs/es/interactive-mode#prompt-suggestions) y las [preguntas laterales con `/btw`](/docs/es/interactive-mode#side-questions-with-%2Fbtw), y SubagentStop también se activa cuando uno de ellos termina. Para esos eventos, `agent_type` es el nombre del agente con el que se ejecuta la propia sesión, como uno establecido con [`--agent`](/docs/es/cli-reference#cli-flags) o con el [ajuste `agent`](/docs/es/settings-reference#agent), y una cadena vacía cuando la sesión se ejecuta sin uno.2748No todos los eventos SubagentStop provienen de un subagente que Claude generó. Claude Code también ejecuta agentes internos para algunas de sus propias funciones, como las [sugerencias de prompts](/docs/es/interactive-mode#prompt-suggestions) y las [preguntas laterales con `/btw`](/docs/es/interactive-mode#side-questions-with-%2Fbtw), y SubagentStop también se dispara cuando uno de ellos termina. Para esos eventos, `agent_type` es el nombre del agente con el que se ejecuta la propia sesión, como uno establecido con [`--agent`](/docs/es/cli-reference#cli-flags) o con el [ajuste `agent`](/docs/es/settings-reference#agent), y una cadena vacía cuando la sesión se ejecuta sin ninguno.
2723 2749
2724Un `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.2750Un `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.
2725 2751
2726En 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`.2752En Claude Code v2.1.271 o posterior, un subagente que se ejecuta con la herramienta [`SubagentHandback`](/docs/es/tools-reference) entrega su informe mediante 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 matcher en `SubagentHandback` recibe como `tool_input.message`.
2727 2753
2728Los 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.2754Los hooks SubagentStop también reciben los arrays `background_tasks` y `session_crons` descritos en [Entrada de Stop](#stop-input). Ambos arrays tienen como alcance la sesión principal, no el subagente.
2729 2755
2730```json theme={null}2756```json theme={null}
2731{2757{
2744}2770}
2745```2771```
2746 2772
2747Los 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`.2773Los 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 el subagente en ejecución. Devolver `decision: "block"` con un `reason` mantiene el subagente en ejecución y le entrega `reason` como su siguiente instrucción. Un hook que bloquea al salir con 2 entrega su mensaje de stderr de la misma forma. 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`.
2748 2774
2749<h3 id="taskcreated">2775<h3 id="taskcreated">
2750 TaskCreated2776 TaskCreated
2751</h3>2777</h3>
2752 2778
2753Se 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.2779Se 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 determinadas tareas. En una [sesión sin las herramientas Task](/docs/es/tools-reference#task-tool-availability), este evento no se dispara.
2754 2780
2755Los hooks TaskCreated no admiten matchers y se activan en cada ocurrencia.2781Los hooks TaskCreated no admiten matchers y se disparan en cada ocurrencia.
2756 2782
2757<h4 id="taskcreated-input">2783<h4 id="taskcreated-input">
2758 Entrada de TaskCreated2784 Entrada de TaskCreated
2787 Control de decisiones de TaskCreated2813 Control de decisiones de TaskCreated
2788</h4>2814</h4>
2789 2815
2790Un hook TaskCreated puede bloquear la creación con el código de salida 2 o con una decisión JSON. En cualquier caso, Claude Code elimina la tarea y devuelve tu mensaje a Claude como error de la herramienta. Claude Code ignora `continue: false` en este evento y Claude sigue trabajando.2816Un hook TaskCreated puede bloquear la creación con el código de salida 2 o con una decisión JSON. 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.
2791 2817
2792* **Código de salida 2**: Claude Code devuelve el texto de stderr como mensaje.2818* **Código de salida 2**: Claude Code devuelve el texto de stderr como mensaje.
2793* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code devuelve `reason` como mensaje.2819* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code devuelve `reason` como mensaje.
2811 TaskCompleted2837 TaskCompleted
2812</h3>2838</h3>
2813 2839
2814Se 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.2840Se ejecuta cuando una tarea se está marcando como completada. Se dispara 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 las pruebas o las comprobaciones de lint pasen antes de que una tarea pueda cerrarse.
2815 2841
2816Los hooks TaskCompleted no admiten matchers y se activan en cada ocurrencia.2842Los hooks TaskCompleted no admiten matchers y se disparan en cada ocurrencia.
2817 2843
2818<h4 id="taskcompleted-input">2844<h4 id="taskcompleted-input">
2819 Entrada de TaskCompleted2845 Entrada de TaskCompleted
2852Los hooks TaskCompleted admiten dos formas de controlar la finalización de tareas:2878Los hooks TaskCompleted admiten dos formas de controlar la finalización de tareas:
2853 2879
2854* **Código de salida 2**: la tarea no se marca como completada y el mensaje de stderr se devuelve al modelo como retroalimentación.2880* **Código de salida 2**: la tarea no se marca como completada y el mensaje de stderr se devuelve al modelo como retroalimentación.
2855* **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.2881* **JSON `{"continue": false, "stopReason": "..."}`**: cuando el evento lo desencadenó un compañero que terminó 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 desencadenó la herramienta `TaskUpdate`, Claude Code ignora `continue: false`; el código de salida 2 sigue bloqueando la finalización.
2856 2882
2857Este ejemplo ejecuta pruebas y bloquea la finalización de la tarea si fallan:2883Este ejemplo ejecuta pruebas y bloquea la finalización de la tarea si fallan:
2858 2884
2874 Stop2900 Stop
2875</h3>2901</h3>
2876 2902
2877Se ejecuta cuando el agente principal de Claude Code terminó de responder. No se ejecuta si2903Se ejecuta cuando el agente principal de Claude Code terminó de responder. No se
2878la detención se produjo por una interrupción del usuario. Los errores de API activan2904ejecuta si la detención se produjo por una interrupción del usuario. Los errores de la API disparan
2879[StopFailure](#stopfailure) en su lugar.2905[StopFailure](#stopfailure) en su lugar.
2880 2906
2881<Tip>2907<Tip>
2882 El comando [`/goal`](/docs/es/goal) es un atajo integrado para un hook Stop basado en prompts con ámbito de sesión. Úsalo cuando quieras que Claude siga trabajando hacia una condición sin escribir configuración de hooks.2908 El comando [`/goal`](/docs/es/goal) es un atajo integrado para un hook Stop basado en prompts con alcance de sesión. Úsalo cuando quieras que Claude siga trabajando hacia una condición sin escribir configuración de hooks.
2883</Tip>2909</Tip>
2884 2910
2885<h4 id="stop-input">2911<h4 id="stop-input">
2886 Entrada de Stop2912 Entrada de Stop
2887</h4>2913</h4>
2888 2914
2889Ademá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á.2915Ademá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á.
2890 2916
2891Claude 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).2917Claude 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 recuento 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).
2892 2918
2893El 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.2919El campo `last_assistant_message` contiene el contenido de texto de la respuesta final de Claude, de modo que los hooks pueden 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.
2894 2920
2895Los 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.2921Los arrays `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 arrays están presentes cuando se puede acceder al registro de tareas y están vacíos cuando no hay nada en curso ni programado.
2896 2922
2897Cada entrada de `background_tasks` describe una tarea en curso y usa estos campos:2923Cada entrada de `background_tasks` describe una tarea en curso y usa estos campos:
2898 2924
2899| Campo | Descripción |2925| Campo | Descripción |
2900| :- | :- |2926| :- | :- |
2901| `id` | Identificador de la tarea |2927| `id` | Identificador de la tarea |
2902| `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 |2928| `type` | Etiqueta descriptiva 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 |
2903| `status` | Estado actual de la tarea |2929| `status` | Estado actual de la tarea |
2904| `description` | Descripción en texto libre, limitada a 1000 caracteres con un marcador `… [+N chars]` dentro de la cadena cuando se recorta |2930| `description` | Descripción en texto libre, limitada a 1000 caracteres con un marcador `… [+N chars]` dentro de la cadena cuando se recorta |
2905| `command` | Línea de comando del shell, limitada a 1000 caracteres. Solo está presente para tareas `shell` |2931| `command` | Línea de comandos del shell, limitada a 1000 caracteres. Presente solo para tareas `shell` |
2906| `agent_type` | Nombre del tipo de subagente. Solo está presente para tareas `subagent` |2932| `agent_type` | Nombre del tipo de subagente. Presente solo para tareas `subagent` |
2907| `server` | Nombre del servidor MCP. Solo está presente para tareas `monitor` y `MCP task` |2933| `server` | Nombre del servidor MCP. Presente solo para tareas `monitor` y `MCP task` |
2908| `tool` | Nombre de la herramienta MCP. Solo está presente para tareas `monitor` y `MCP task` |2934| `tool` | Nombre de la herramienta MCP. Presente solo para tareas `monitor` y `MCP task` |
2909| `name` | Nombre del workflow. Solo está presente para tareas `workflow` |2935| `name` | Nombre del workflow. Presente solo para tareas `workflow` |
2910 2936
2911Cada entrada de `session_crons` describe una reactivación programada con ámbito de sesión, proveniente de `CronCreate`, `ScheduleWakeup` y `/loop`:2937Cada entrada de `session_crons` describe una reactivación programada con alcance de sesión, proveniente de `CronCreate`, `ScheduleWakeup` y `/loop`:
2912 2938
2913| Campo | Descripción |2939| Campo | Descripción |
2914| :- | :- |2940| :- | :- |
2915| `id` | Identificador de la tarea cron |2941| `id` | Identificador de la tarea cron |
2916| `schedule` | Expresión cron, por ejemplo `0 9 * * 1-5` |2942| `schedule` | Expresión cron, por ejemplo `0 9 * * 1-5` |
2917| `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 |2943| `recurring` | `false` para reactivaciones únicas cuyo programa codifica un único momento de disparo, `true` para tareas que se vuelven a disparar en cada coincidencia |
2918| `prompt` | Prompt que se envía cuando se activa el cron, limitado a 1000 caracteres con el mismo marcador `… [+N chars]` |2944| `prompt` | Prompt que se envía cuando se dispara el cron, limitado a 1000 caracteres con el mismo marcador `… [+N chars]` |
2919 2945
2920Este ejemplo muestra una entrada de Stop con una tarea de shell en curso y un cron recurrente:2946Este ejemplo muestra una entrada de Stop con una tarea de shell en curso y un cron recurrente:
2921 2947
2958| :- | :- |2984| :- | :- |
2959| `decision` | `"block"` impide que Claude se detenga. Omítelo para permitir que Claude se detenga |2985| `decision` | `"block"` impide que Claude se detenga. Omítelo para permitir que Claude se detenga |
2960| `reason` | Obligatorio cuando `decision` es `"block"`. Le indica a Claude por qué debe continuar |2986| `reason` | Obligatorio cuando `decision` es `"block"`. Le indica a Claude por qué debe continuar |
2961| `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 |2987| `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 |
2962 2988
2963Un 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.2989Un hook que bloquea al salir con 2 se enruta igual que `reason`: Claude recibe el mensaje de stderr como la explicación de por qué debe continuar.
2964 2990
2965```json theme={null}2991```json theme={null}
2966{2992{
2969}2995}
2970```2996```
2971 2997
2972Usa `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:2998Usa `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 con 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:
2973 2999
2974```json theme={null}3000```json theme={null}
2975{3001{
2984 StopFailure3010 StopFailure
2985</h3>3011</h3>
2986 3012
2987Se 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.3013Se 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 fallos, 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.
2988 3014
2989<h4 id="stopfailure-input">3015<h4 id="stopfailure-input">
2990 Entrada de StopFailure3016 Entrada de StopFailure
2996| :- | :- |3022| :- | :- |
2997| `error` | Tipo de error: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error` o `unknown` |3023| `error` | Tipo de error: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error` o `unknown` |
2998| `error_details` | Detalles adicionales sobre el error, cuando están disponibles |3024| `error_details` | Detalles adicionales sobre el error, cuando están disponibles |
2999| `last_assistant_message` | El texto de error renderizado que se muestra en la conversación. A diferencia de `Stop` y `SubagentStop`, donde este campo contiene la salida conversacional de Claude, para `StopFailure` contiene la propia cadena de error de la API, como `"API Error: Rate limit reached"` |3025| `last_assistant_message` | El texto de error renderizado que se muestra en la conversación. A diferencia de `Stop` y `SubagentStop`, donde este campo contiene la salida conversacional de Claude, en `StopFailure` contiene la propia cadena de error de la API, como `"API Error: Rate limit reached"` |
3000 3026
3001```json theme={null}3027```json theme={null}
3002{3028{
3016 TeammateIdle3042 TeammateIdle
3017</h3>3043</h3>
3018 3044
3019Se 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.3045Se 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 comprobaciones de lint o verificar que existan los archivos de salida.
3020 3046
3021Los hooks TeammateIdle no admiten matchers y se activan en cada ocurrencia.3047Los hooks TeammateIdle no admiten matchers y se disparan en cada ocurrencia.
3022 3048
3023<h4 id="teammateidle-input">3049<h4 id="teammateidle-input">
3024 Entrada de TeammateIdle3050 Entrada de TeammateIdle
3048 Control de decisiones de TeammateIdle3074 Control de decisiones de TeammateIdle
3049</h4>3075</h4>
3050 3076
3051Los hooks TeammateIdle admiten dos formas de controlar el comportamiento del compañero:3077Los hooks TeammateIdle admiten dos formas de controlar el comportamiento de los compañeros:
3052 3078
3053* **Código de salida 2**: el compañero recibe el mensaje de stderr como retroalimentación y sigue trabajando en lugar de quedar inactivo.3079* **Código de salida 2**: el compañero recibe el mensaje de stderr como retroalimentación y sigue trabajando en lugar de quedar inactivo.
3054* **JSON `{"continue": false, "stopReason": "..."}`**: detiene por completo al compañero, igual que el comportamiento del hook `Stop`. El `stopReason` se muestra al usuario.3080* **JSON `{"continue": false, "stopReason": "..."}`**: detiene al compañero por completo, igual que el comportamiento del hook `Stop`. El `stopReason` se muestra al usuario.
3055 3081
3056Este ejemplo comprueba que exista un artefacto de compilación antes de permitir que un compañero quede inactivo:3082Este ejemplo comprueba que exista un artefacto de compilación antes de permitir que un compañero quede inactivo:
3057 3083
3070 ConfigChange3096 ConfigChange
3071</h3>3097</h3>
3072 3098
3073Se 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.3099Se 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 en los archivos de configuración.
3074 3100
3075Claude 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.3101Claude 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, los ejecuta solo 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.
3076 3102
3077El matcher filtra por el origen de la configuración:3103El matcher filtra según el origen de la configuración:
3078 3104
3079| Matcher | Cuándo se activa |3105| Matcher | Cuándo se dispara |
3080| :- | :- |3106| :- | :- |
3081| `user_settings` | Cambia `~/.claude/settings.json` |3107| `user_settings` | Cambia `~/.claude/settings.json` |
3082| `project_settings` | Cambia `.claude/settings.json` |3108| `project_settings` | Cambia `.claude/settings.json` |
3084| `policy_settings` | Cambia `managed-settings.json` o un archivo en `managed-settings.d/` |3110| `policy_settings` | Cambia `managed-settings.json` o un archivo en `managed-settings.d/` |
3085| `skills` | Cambia un archivo de skill en `.claude/skills/` |3111| `skills` | Cambia un archivo de skill en `.claude/skills/` |
3086 3112
3087Este ejemplo registra todos los cambios de configuración para auditoría de seguridad:3113Este ejemplo registra todos los cambios de configuración para auditorías de seguridad:
3088 3114
3089```json theme={null}3115```json theme={null}
3090{3116{
3125 Control de decisiones de ConfigChange3151 Control de decisiones de ConfigChange
3126</h4>3152</h4>
3127 3153
3128Los hooks ConfigChange pueden impedir que los cambios de configuración surtan efecto. Usa el código de salida 2 o un `decision` en JSON para impedir el cambio. Cuando se bloquea, la nueva configuración no se aplica a la sesión en ejecución.3154Los hooks ConfigChange pueden impedir que los cambios de configuración surtan efecto. Usa el código de salida 2 o una `decision` JSON para impedir el cambio. Cuando se bloquea, la nueva configuración no se aplica a la sesión en ejecución.
3129 3155
3130| Campo | Descripción |3156| Campo | Descripción |
3131| :- | :- |3157| :- | :- |
3139}3165}
3140```3166```
3141 3167
3142Los 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).3168Los cambios de `policy_settings` no se pueden bloquear. Los hooks siguen disparándose para los orígenes `policy_settings` cuando cambia un archivo de configuración administrada en la máquina, por lo 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).
3143 3169
3144Claude 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.3170Claude 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, tanto si bloqueas con `reason` como con stderr al salir con 2. Claude Code solo escribe una línea en el registro de depuración.
3145 3171
3146<h3 id="cwdchanged">3172<h3 id="cwdchanged">
3147 CwdChanged3173 CwdChanged
3148</h3>3174</h3>
3149 3175
3150Se 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.3176Se 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 combina con [FileChanged](#filechanged) para herramientas como [direnv](https://direnv.net/) que administran el entorno por directorio.
3151 3177
3152Los 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.3178Los 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.
3153 3179
3154CwdChanged no admite matchers y se activa en cada ocurrencia.3180CwdChanged no admite matchers y se dispara en cada ocurrencia.
3155 3181
3156<h4 id="cwdchanged-input">3182<h4 id="cwdchanged-input">
3157 Entrada de CwdChanged3183 Entrada de CwdChanged
3178 3204
3179| Campo | Descripción |3205| Campo | Descripción |
3180| :- | :- |3206| :- | :- |
3181| `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 |3207| `watchPaths` | Array de rutas absolutas. Reemplaza la lista dinámica de vigilancia actual. Las rutas de tu configuración de `matcher` siempre se vigilan. Devolver un array vacío borra la lista dinámica, lo cual es habitual al entrar en un directorio nuevo |
3182 3208
3183Los hooks CwdChanged no tienen control de decisiones. No pueden bloquear el cambio de directorio.3209Los hooks CwdChanged no tienen control de decisiones. No pueden bloquear el cambio de directorio.
3184 3210
3188 DirectoryAdded3214 DirectoryAdded
3189</h3>3215</h3>
3190 3216
3191Se ejecuta después de que agregas un directorio de trabajo a mitad de sesión con el comando `/add-dir`, o después de que un cliente del SDK agrega uno con la solicitud de control `register_repo_root`. Úsalo para preparar un repositorio recién agregado, por ejemplo instalando sus dependencias.3217Se ejecuta después de que agregas un directorio de trabajo a mitad de la sesión con el comando `/add-dir`, o después de que un cliente del SDK agrega uno con la solicitud de control `register_repo_root`. Úsalo para preparar un repositorio recién agregado, por ejemplo instalando sus dependencias.
3192 3218
3193Claude Code no activa este evento cuando:3219Claude Code no dispara este evento cuando:
3194 3220
3195* Pasas un directorio con el flag de inicio `--add-dir`; [SessionStart](#sessionstart) cubre esos directorios3221* Pasas un directorio con el flag de inicio `--add-dir`; [SessionStart](#sessionstart) cubre esos directorios
3196* Agregas un directorio en la pestaña Workspace de `/permissions`3222* Agregas un directorio en la pestaña Workspace de `/permissions`
3197* Agregas un directorio que ya es un directorio de trabajo o que está dentro de uno3223* Agregas un directorio que ya es un directorio de trabajo o que está dentro de uno
3198 3224
3199Claude 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.3225Claude Code dispara 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.
3200 3226
3201Claude 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.3227Claude 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.
3202 3228
3203El matcher filtra según cómo se agregó el directorio:3229El matcher filtra según cómo se agregó el directorio:
3204 3230
3205| Matcher | Cuándo se activa |3231| Matcher | Cuándo se dispara |
3206| :- | :- |3232| :- | :- |
3207| `slash_command` | Agregas un directorio con `/add-dir` |3233| `slash_command` | Agregas un directorio con `/add-dir` |
3208| `register_repo_root` | Un cliente del SDK agrega un directorio con la solicitud de control `register_repo_root` |3234| `register_repo_root` | Un cliente del SDK agrega un directorio con la solicitud de control `register_repo_root` |
3231 3257
3232Los 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:3258Los 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:
3233 3259
3234* `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ón3260* `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 de los fallos va al registro de depuración
3235* `register_repo_root`: Claude Code escribe la salida de `systemMessage` y la salida de fallos solo en el registro de depuración3261* `register_repo_root`: Claude Code escribe la salida de `systemMessage` y la salida de los fallos solo en el registro de depuración
3236 3262
3237<h3 id="filechanged">3263<h3 id="filechanged">
3238 FileChanged3264 FileChanged
3239</h3>3265</h3>
3240 3266
3241Se 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.3267Se 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, 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.
3242 3268
3243El `matcher` de este evento cumple dos funciones:3269El `matcher` de este evento cumple dos funciones:
3244 3270
3245* **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`.3271* **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 regex no sirven aquí: un valor como `^\.env` vigilaría un archivo llamado literalmente `^\.env`.
3246* **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.3272* **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 modificado.
3247 3273
3248Este 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:3274Este 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:
3249 3275
3265}3291}
3266```3292```
3267 3293
3268El 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:3294El hook lee la ruta absoluta del archivo modificado desde el campo `file_path` de la [entrada JSON](#filechanged-input) en stdin. Su comprobación con `grep` busca 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 comprobación más laxa entra en un bucle infinito, porque `perl -i` reescribe el archivo aunque no sustituya 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:
3269 3295
3270```bash theme={null}3296```bash theme={null}
3271#!/bin/bash3297#!/bin/bash
3275fi3301fi
3276```3302```
3277 3303
3278Para 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.3304Para 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.
3279 3305
3280Para 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 `*`.3306Para 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 omite el matcher en 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 `*`.
3281 3307
3282Los 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.3308Los 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.
3283 3309
3311 3337
3312| Campo | Descripción |3338| Campo | Descripción |
3313| :- | :- |3339| :- | :- |
3314| `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 |3340| `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 según el archivo modificado |
3315 3341
3316Los hooks FileChanged no tienen control de decisiones. No pueden impedir que se produzca el cambio del archivo.3342Los hooks FileChanged no tienen control de decisión. No pueden impedir que ocurra el cambio del archivo.
3317 3343
3318Claude Code lee `watchPaths` y `systemMessage` de su salida JSON y descarta `continue`. En las sesiones interactivas, muestra el `systemMessage` como una breve notificación en la terminal. El mensaje no llega al flujo de mensajes del SDK.3344Claude Code lee `watchPaths` y `systemMessage` de su salida JSON y descarta `continue`. En sesiones interactivas, muestra el `systemMessage` como una breve notificación en la terminal. El mensaje no llega al flujo de mensajes del SDK.
3319 3345
3320<h3 id="worktreecreate">3346<h3 id="worktreecreate">
3321 WorktreeCreate3347 WorktreeCreate
3334 3360
3335De 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.3361De 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.
3336 3362
3337Como 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.3363Como 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 de hook.
3338 3364
3339El 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.3365El 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 devuelve la ruta cada tipo de hook.
3340 3366
3341Claude Code actúa según el éxito del hook y la ruta devuelta, y descarta `systemMessage` y `continue`.3367Claude Code actúa según el éxito del hook y la ruta devuelta, y descarta `systemMessage` y `continue`.
3342 3368
3359}3385}
3360```3386```
3361 3387
3362El 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.3388El 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.
3363 3389
3364<h4 id="worktreecreate-input">3390<h4 id="worktreecreate-input">
3365 Entrada de WorktreeCreate3391 Entrada de WorktreeCreate
3366</h4>3392</h4>
3367 3393
3368Ademá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`.3394Ademá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`.
3369 3395
3370```json theme={null}3396```json theme={null}
3371{3397{
3381 Salida de WorktreeCreate3407 Salida de WorktreeCreate
3382</h4>3408</h4>
3383 3409
3384Los 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:3410Los 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:
3385 3411
3386* **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.3412* **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, así que los banners de inicio del shell impresos antes de tu `echo` se ignoran. Redirige cualquier otra salida del hook a stderr.
3387* **Hooks HTTP** (`type: "http"`): devuelve `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` en el cuerpo de la respuesta.3413* **Hooks HTTP** (`type: "http"`): devuelve `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` en el cuerpo de la respuesta.
3388 3414
3389Si el hook falla o no produce ninguna ruta, la creación del worktree falla con un error.3415Si el hook falla o no produce ninguna ruta, la creación del worktree falla con un error.
3390 3416
3391Claude 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.3417Claude 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 nombra la ruta y termina con código 1.
3392 3418
3393Claude 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.3419Claude 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 incluido en un commit del 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 comprobación.
3394 3420
3395<h3 id="worktreeremove">3421<h3 id="worktreeremove">
3396 WorktreeRemove3422 WorktreeRemove
3397</h3>3423</h3>
3398 3424
3399Se ejecuta cuando Claude Code limpia un worktree que creó tu hook [`WorktreeCreate`](#worktreecreate). El evento se activa cuando:3425Se ejecuta cuando Claude Code limpia un worktree que creó tu hook [`WorktreeCreate`](#worktreecreate). El evento se dispara cuando:
3400 3426
3401* 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 pregunta3427* 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
3402* 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 preguntarte3428* 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
3403* Eliminas una [sesión en segundo plano](/docs/es/agent-view#what-deleting-a-session-removes) que se ejecuta en el worktree3429* Eliminas una [sesión en segundo plano](/docs/es/agent-view#what-deleting-a-session-removes) que se ejecuta en el worktree
3404* Le pides a Claude que salga y elimine el worktree durante una sesión, y Claude lo elimina con la herramienta [`ExitWorktree`](/docs/es/tools-reference)3430* Le pides a Claude que salga y elimine el worktree durante una sesión, y Claude lo elimina con la herramienta [`ExitWorktree`](/docs/es/tools-reference)
3405* Una sesión que [`claude remote-control`](/docs/es/remote-control#start-a-remote-control-session) inició en modo `worktree` termina sin fallar, y Claude Code no encuentra archivos modificados ni sin seguimiento ni commits nuevos en su worktree3431* Una sesión que [`claude remote-control`](/docs/es/remote-control#start-a-remote-control-session) inició en modo `worktree` termina sin fallar, y Claude Code no encuentra archivos modificados ni sin seguimiento ni commits nuevos en su worktree
3406* Detienes `claude remote-control` mientras las sesiones que inició en modo `worktree` siguen en ejecución, y Claude Code no encuentra archivos modificados ni sin seguimiento ni commits nuevos en sus worktrees3432* Detienes `claude remote-control` mientras las sesiones que inició en modo `worktree` siguen ejecutándose, y Claude Code no encuentra archivos modificados ni sin seguimiento ni commits nuevos en sus worktrees
3407 3433
3408Cuando un subagente o un agente de un flujo de trabajo termina, Claude Code conserva el worktree que tu hook WorktreeCreate creó para él y no ejecuta tu hook WorktreeRemove. Elimina esos worktrees tú mismo cuando el trabajo esté terminado.3434Cuando un subagente o un agente de un flujo de trabajo termina, Claude Code conserva el worktree que tu hook WorktreeCreate creó para él y no ejecuta tu hook WorktreeRemove. Elimina esos worktrees tú mismo cuando termine el trabajo.
3409 3435
3410Claude Code no te pregunta antes de que tu hook se ejecute para una llamada a `ExitWorktree` o una limpieza de `claude remote-control`. `ExitWorktree` se niega a eliminar un worktree creado por un hook a menos que la llamada pase [`discard_changes: true`](/docs/es/agent-sdk/typescript#exitworktree), lo que convierte a tu hook en la última comprobación en esa ruta.3436Claude Code no te pregunta antes de que tu hook se ejecute para una llamada a `ExitWorktree` o una limpieza de `claude remote-control`. `ExitWorktree` se niega a eliminar un worktree creado por un hook a menos que la llamada pase [`discard_changes: true`](/docs/es/agent-sdk/typescript#exitworktree), lo que convierte a tu hook en la última comprobación en esa vía.
3411 3437
3412Claude 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.3438Claude 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, aunque el directorio contenga trabajo sin commit. Comprueba ese trabajo en tu hook WorktreeRemove antes de que elimine nada.
3413 3439
3414Para 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:3440Para 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:
3415 3441
3416* **Sin hook WorktreeRemove**: Claude Code recurre a git para una eliminación al salir o mediante `ExitWorktree`, y conserva el worktree cuando `claude remote-control` hace la limpieza:3442* **Sin hook WorktreeRemove**: Claude Code recurre a git para una eliminación al salir o mediante `ExitWorktree`, y conserva el worktree cuando `claude remote-control` hace la limpieza:
3417 * **Sales de una sesión de worktree, o Claude llama a `ExitWorktree`**: Claude Code elimina la ruta que devolvió tu hook WorktreeCreate como lo haría `git worktree remove --force`, así 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, se queda en el disco.3443 * **Sales de una sesión de worktree, o Claude llama a `ExitWorktree`**: Claude Code elimina la ruta que devolvió tu hook WorktreeCreate como lo haría `git worktree remove --force`, así 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.
3418 * **`claude remote-control` limpia el worktree de una sesión**: el worktree se queda en el disco, y la terminal que ejecuta `claude remote-control` muestra `worktree removal failed, kept: <path>`.3444 * **`claude remote-control` limpia el worktree de una sesión**: el worktree permanece en el disco, y la terminal que ejecuta `claude remote-control` muestra `worktree removal failed, kept: <path>`.
3419 * **Eliminas una sesión en segundo plano**: consulta [Qué elimina borrar una sesión](/docs/es/agent-view#what-deleting-a-session-removes).3445 * **Eliminas una sesión en segundo plano**: consulta [Qué elimina borrar una sesión](/docs/es/agent-view#what-deleting-a-session-removes).
3420* **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.3446* **El hook termina con 0**: el worktree cuenta como eliminado. Claude Code no lee nada más del hook, así que asegúrate de que tu hook haya eliminado el directorio.
3421* **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).3447* **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 cuenta como eliminado. Para saber cómo se informa el fallo, consulta [Entrada de WorktreeRemove](#worktreeremove-input).
3422 3448
3423Claude Code nunca elimina una rama que pertenezca a un worktree creado por un hook, porque solo conoce la ruta que devolvió tu hook WorktreeCreate. Si tu hook WorktreeCreate crea una rama, elimínala en tu hook WorktreeRemove.3449Claude Code nunca elimina una rama perteneciente a un worktree creado por un hook, porque solo conoce la ruta que devolvió tu hook WorktreeCreate. Si tu hook WorktreeCreate crea una rama, elimínala en tu hook WorktreeRemove.
3424 3450
3425Claude Code descarta los [campos de salida JSON](#json-output) de un hook WorktreeRemove, como `systemMessage` y `continue`.3451Claude Code descarta los [campos de salida JSON](#json-output) de un hook WorktreeRemove, como `systemMessage` y `continue`.
3426 3452
3427Al 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 por debajo de la raíz del repositorio. En esa ruta, el hook se ejecuta para un worktree que aún 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 en su lugar. Antes de v2.1.216, el hook se ejecutaba sobre la ruta almacenada sin estas comprobaciones.3453Al 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. En esa vía, 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.
3428 3454
3429Claude Code pasa la ruta devuelta por WorktreeCreate como `worktree_path` en la entrada del hook. Este ejemplo lee esa ruta y elimina el directorio:3455Claude Code pasa la ruta devuelta por WorktreeCreate como `worktree_path` en la entrada del hook. Este ejemplo lee esa ruta y elimina el directorio:
3430 3456
3464El 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:3490El 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:
3465 3491
3466* El worktree permanece en el disco, y el comando del hook y su stderr van al [registro de depuración](#debug-hooks).3492* El worktree permanece en el disco, y el comando del hook y su stderr van al [registro de depuración](#debug-hooks).
3467* 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.3493* 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, por ejemplo `exited 1`, cita el comienzo de su stderr e indica si volver a eliminar la sesión elimina el directorio de todos modos.
3468* Si `claude remote-control` estaba limpiando el worktree de una sesión, la terminal que lo ejecuta muestra `worktree removal failed, kept: <path>`.3494* Si `claude remote-control` estaba limpiando el worktree de una sesión, la terminal que lo ejecuta muestra `worktree removal failed, kept: <path>`.
3469 3495
3470<h3 id="precompact">3496<h3 id="precompact">
3471 PreCompact3497 PreCompact
3472</h3>3498</h3>
3473 3499
3474Se ejecuta antes de que Claude Code esté a punto de ejecutar una operación de compactación.3500Se ejecuta antes de que Claude Code vaya a ejecutar una operación de compactación.
3475 3501
3476El valor del matcher indica si la compactación se activó de forma manual o automática:3502El valor del matcher indica si la compactación se activó manual o automáticamente:
3477 3503
3478| Matcher | Cuándo se activa |3504| Matcher | Cuándo se dispara |
3479| :- | :- |3505| :- | :- |
3480| `manual` | `/compact` |3506| `manual` | `/compact` |
3481| `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) |3507| `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), y [compactación por inactividad](/docs/es/settings-reference#idlecompaction) |
3482 3508
3483Termina 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"`.3509Termina 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"`.
3484 3510
3485Bloquear 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.3511Bloquear 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, aparece el error subyacente y la solicitud actual falla.
3486 3512
3487Claude Code descarta los campos `systemMessage` y `continue` de un hook PreCompact.3513Claude Code descarta los campos `systemMessage` y `continue` de un hook PreCompact.
3488 3514
3511 3537
3512Se aplican los mismos valores de matcher que para `PreCompact`:3538Se aplican los mismos valores de matcher que para `PreCompact`:
3513 3539
3514| Matcher | Cuándo se activa |3540| Matcher | Cuándo se dispara |
3515| :- | :- |3541| :- | :- |
3516| `manual` | Después de `/compact` |3542| `manual` | Después de `/compact` |
3517| `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) |3543| `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), y después de la [compactación por inactividad](/docs/es/settings-reference#idlecompaction) |
3518 3544
3519<h4 id="postcompact-input">3545<h4 id="postcompact-input">
3520 Entrada de PostCompact3546 Entrada de PostCompact
3539 PreModelSwitch3565 PreModelSwitch
3540</h3>3566</h3>
3541 3567
3542Se ejecuta antes de que Claude Code aplique un cambio de modelo que tú o un cliente solicitaron. Úsalo para bloquear un cambio, requerir confirmación o mostrar lo que costará el cambio antes de que ocurra.3568Se ejecuta antes de que Claude Code aplique un cambio de modelo que tú o un cliente solicitaron. Úsalo para bloquear un cambio, exigir confirmación o mostrar lo que costará el cambio antes de que ocurra.
3543 3569
3544PreModelSwitch requiere Claude Code v2.1.251 o posterior. Claude Code lo ejecuta para estas solicitudes:3570PreModelSwitch requiere Claude Code v2.1.251 o posterior. Claude Code lo ejecuta para estas solicitudes:
3545 3571
3546* `/model <name>` y el selector de `/model`3572* `/model <name>` y el selector de `/model`
3547* El selector de modelo de `Option+P` o `Alt+P`3573* El selector de modelo con `Option+P` o `Alt+P`
3548* El ajuste Model en `/config`3574* El ajuste Model en `/config`
3549* Activar el [modo rápido](/docs/es/fast-mode) cuando eso cambia el modelo de la sesión3575* Activar el [modo rápido](/docs/es/fast-mode) cuando eso cambia el modelo de la sesión
3550* 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)3576* 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 [Remote Control](/docs/es/remote-control)
3551 3577
3552Claude 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).3578Claude Code no ejecuta 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).
3553 3579
3554Claude 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.3580Claude 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 del proveedor, como un ID de modelo de Amazon Bedrock, coinciden todos con el único nombre canónico al que se resuelven, así que `claude-opus-5` cubre todas las formas de escribir Opus 5.
3555 3581
3556Cuando 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.3582Cuando 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 independientemente del matcher. Por eso, un hook que bloquea debe comprobar `to_model` en su entrada en lugar de depender solo del matcher.
3557 3583
3558Escribe 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:3584Escribe 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, así que rechaza un cambio a Opus 4.6 terminando con el código 2 y deja pasar cualquier otro destino:
3559 3585
3560<Tabs>3586<Tabs>
3561 <Tab title="macOS/Linux">3587 <Tab title="macOS/Linux">
3581 </Tab>3607 </Tab>
3582 3608
3583 <Tab title="Windows (PowerShell)">3609 <Tab title="Windows (PowerShell)">
3584 Registra un hook de comando que ejecute un script a través de PowerShell:3610 Registra un hook de comando que ejecute un script mediante PowerShell:
3585 3611
3586 ```json theme={null}3612 ```json theme={null}
3587 {3613 {
3627 Entrada de PreModelSwitch3653 Entrada de PreModelSwitch
3628</h4>3654</h4>
3629 3655
3630Ademá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.3656Ademá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 reenviar la conversación al nuevo modelo, para que un hook pueda mostrar esa cifra antes de que ocurra el cambio.
3631 3657
3632| Campo | Tipo | Descripción |3658| Campo | Tipo | Descripción |
3633| :- | :- | :- |3659| :- | :- | :- |
3634| `from_model` | string | ID del modelo desde el que se realiza el cambio |3660| `from_model` | string | ID del modelo desde el que se cambia |
3635| `to_model` | string | ID del modelo al que se realiza el cambio. El matcher se compara con el nombre canónico de este modelo |3661| `to_model` | string | ID del modelo al que se cambia. El matcher se compara con el nombre canónico de este modelo |
3636| `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 |3662| `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 |
3637| `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 |3663| `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 Remote Control |
3638| `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 |3664| `context_tokens` | number | Tokens que la siguiente solicitud reenvía 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 |
3639| `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 |3665| `prompt_cache_warm` | boolean | Si es probable que la caché de prompts del modelo actual siga caliente, lo que significa que el cambio la pierde |
3640| `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"` |3666| `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"` |
3641| `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 |3667| `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 |
3642| `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 |3668| `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"` a precio de lista, o `"default"` cuando `to_model` no tiene un precio conocido y Claude Code asumió una tarifa predeterminada |
3643 3669
3644Este ejemplo muestra la entrada para `/model opus` en una sesión que usa Sonnet 5:3670Este ejemplo muestra la entrada para `/model opus` en una sesión que usa Sonnet 5:
3645 3671
3665 Control de decisión de PreModelSwitch3691 Control de decisión de PreModelSwitch
3666</h4>3692</h4>
3667 3693
3668Los hooks `PreModelSwitch` pueden cancelar el cambio, pedir al usuario que lo confirme o dejar que continúe. El código de salida 2 o un `decision: "block"` de nivel superior cancela el cambio.3694Los hooks `PreModelSwitch` pueden cancelar el cambio, pedirle al usuario que lo confirme o dejar que continúe. El código de salida 2 o un `decision: "block"` de nivel superior cancela el cambio.
3669 3695
3670Para un control más preciso, devuelve `permissionDecision` y `permissionDecisionReason` en un objeto `hookSpecificOutput`, como en [PreToolUse](#pretooluse-decision-control). `PreModelSwitch` acepta `"allow"`, `"deny"` y `"ask"`. No acepta `"defer"`, `updatedInput` ni `additionalContext`. La siguiente tabla describe ambos campos:3696Para un control más fino, devuelve `permissionDecision` y `permissionDecisionReason` en un objeto `hookSpecificOutput`, como en [PreToolUse](#pretooluse-decision-control). `PreModelSwitch` acepta `"allow"`, `"deny"` y `"ask"`. No acepta `"defer"`, `updatedInput` ni `additionalContext`. La siguiente tabla describe ambos campos:
3671 3697
3672| Campo | Descripción |3698| Campo | Descripción |
3673| :- | :- |3699| :- | :- |
3674| `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 |3700| `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"` le pide al usuario que lo confirme |
3675| `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"` |3701| `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"` |
3676 3702
3677Solo `/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.3703Solo `/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.
3678 3704
3679Este ejemplo pide al usuario que confirme y cita el recuento de tokens de `context_tokens`:3705Este ejemplo le pide al usuario que confirme y cita el recuento de tokens de `context_tokens`:
3680 3706
3681```json theme={null}3707```json theme={null}
3682{3708{
3690 3716
3691Cuando varios hooks PreModelSwitch devuelven decisiones diferentes, la precedencia es `deny` > `ask` > `allow`.3717Cuando varios hooks PreModelSwitch devuelven decisiones diferentes, la precedencia es `deny` > `ask` > `allow`.
3692 3718
3693Claude 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.3719Claude Code le muestra al usuario cualquier `systemMessage` que devuelva tu hook independientemente de la decisión, así que un hook de informe de costos puede devolver `{"systemMessage": "..."}` y terminar con 0.
3694 3720
3695Un hook PreModelSwitch que no responde antes de que se agote su tiempo de espera bloquea el cambio. Para saber qué hace un tiempo de espera agotado en otros eventos, consulta [Tiempos de espera](#timeouts). 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.3721Un hook PreModelSwitch que no responde antes de su tiempo de espera bloquea el cambio. Para saber qué hace un tiempo de espera agotado en otros eventos, consulta [Tiempos de espera](#timeouts). El tiempo de espera predeterminado para este evento es de 30 segundos. `PreModelSwitch` solo ejecuta hooks `command`, `http` y `mcp_tool`, así que los valores predeterminados de `prompt` y `agent` no se aplican.
3696 3722
3697Un hook que termina con un código distinto de 0 o 2 y no imprime ninguna decisión JSON es un error no bloqueante, como se describe en [Otros códigos de salida](#other-exit-codes).3723Un hook que termina con un código distinto de 0 o 2 y no imprime ninguna decisión JSON es un error no bloqueante, como se describe en [Otros códigos de salida](#other-exit-codes).
3698 3724
3700 PostModelSwitch3726 PostModelSwitch
3701</h3>3727</h3>
3702 3728
3703Se 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.3729Se ejecuta después de que cambia el modelo de la sesión. Úsalo para darle a Claude orientación específica del modelo sin editar cada CLAUDE.md, por ejemplo una instrucción para toda la organización que se aplica en ciertos modelos.
3704 3730
3705PostModelSwitch 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:3731PostModelSwitch 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:
3706 3732
3707* Un cambio que tú o un cliente solicitaron3733* Un cambio que tú o un cliente solicitaron
3708* Un [respaldo automático de modelo](/docs/es/model-config#automatic-model-fallback), que cambia el modelo de la sesión3734* Un [respaldo automático de modelo](/docs/es/model-config#automatic-model-fallback), que cambia el modelo de la sesión
3709* Un ajuste como [`opusplan`](/docs/es/model-config#opusplan-model-setting) al entrar o salir del modo plan3735* Un ajuste como [`opusplan`](/docs/es/model-config#opusplan-model-setting) al entrar o salir del modo plan
3710* Claude Code restaurando el modelo al reanudar una sesión3736* Claude Code restaurando el modelo cuando reanudas una sesión
3711 3737
3712Claude 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.3738Claude 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.
3713 3739
3714El 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.3740El 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.
3715 3741
3716Este ejemplo agrega indicaciones cada vez que el modelo de la sesión cambia a cualquier modelo Opus:3742Este ejemplo agrega orientación cada vez que el modelo de la sesión cambia a cualquier modelo Opus:
3717 3743
3718```json theme={null}3744```json theme={null}
3719{3745{
3733}3759}
3734```3760```
3735 3761
3736Para confirmar que el hook funciona, cambia a un modelo Opus desde una sesión que use un modelo diferente, por ejemplo ejecuta `/model opus` desde una sesión de Sonnet, y luego pregúntale a Claude qué indicaciones tiene sobre el modelo actual.3762Para confirmar que el hook funciona, cambia a un modelo Opus desde una sesión que use un modelo diferente, por ejemplo ejecuta `/model opus` desde una sesión de Sonnet, y luego pregúntale a Claude qué orientación tiene sobre el modelo actual.
3737 3763
3738<h4 id="postmodelswitch-input">3764<h4 id="postmodelswitch-input">
3739 Entrada de PostModelSwitch3765 Entrada de PostModelSwitch
3740</h4>3766</h4>
3741 3767
3742Los 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.3768Los 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.
3743 3769
3744`requested_model` es `null` cuando `source` es `"auto"`. Cuando `source` es `"resume"`, es el ajuste de modelo guardado que Claude Code restauró.3770`requested_model` es `null` cuando `source` es `"auto"`. Cuando `source` es `"resume"`, es el ajuste de modelo guardado que Claude Code restauró.
3745 3771
3747 Control de decisión de PostModelSwitch3773 Control de decisión de PostModelSwitch
3748</h4>3774</h4>
3749 3775
3750Claude 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:3776Claude Code toma la [stdout de texto plano](#exit-code-0) de tu hook al terminar con 0, o `additionalContext` de la salida JSON, y se 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:
3751 3777
3752| Campo | Descripción |3778| Campo | Descripción |
3753| :- | :- |3779| :- | :- |
3754| `additionalContext` | String que se agrega al contexto de Claude con la siguiente solicitud. Consulta [Agregar contexto para Claude](#add-context-for-claude) |3780| `additionalContext` | Cadena que se agrega al contexto de Claude con la siguiente solicitud. Consulta [Agregar contexto para Claude](#add-context-for-claude) |
3755 3781
3756Si 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.3782Si el hook no ha terminado dentro de 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.
3757 3783
3758<h3 id="sessionend">3784<h3 id="sessionend">
3759 SessionEnd3785 SessionEnd
3760</h3>3786</h3>
3761 3787
3762Se ejecuta cuando termina una sesión de Claude Code. Es útil para tareas de limpieza, registrar estadísticas3788Se ejecuta cuando termina una sesión de Claude Code. Útil para tareas de limpieza, registrar estadísticas
3763de la sesión o guardar el estado de la sesión. Admite matchers para filtrar por motivo de salida.3789de la sesión o guardar el estado de la sesión. Admite matchers para filtrar por motivo de salida.
3764 3790
3765El campo `reason` en la entrada del hook indica por qué terminó la sesión:3791El campo `reason` en la entrada del hook indica por qué terminó la sesión:
3793 3819
3794Los 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:3820Los 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:
3795 3821
3796* **`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.3822* **`timeout` por hook**: establece `timeout` en la configuración de ese hook. El presupuesto total aumenta automáticamente para 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.
3797* **`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`.3823* **`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`.
3798 3824
3799Este ejemplo establece el presupuesto en 5 segundos:3825Este ejemplo establece el presupuesto en 5 segundos:
3800 3826
3808 Elicitation3834 Elicitation
3809</h3>3835</h3>
3810 3836
3811Se 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.3837Se ejecuta cuando un servidor MCP solicita entrada del 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.
3812 3838
3813Para 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).3839Para 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).
3814 3840
3840}3866}
3841```3867```
3842 3868
3843Para la elicitación en modo URL, que se usa para la autenticación basada en el navegador:3869Para la elicitación en modo URL, usada para la autenticación basada en navegador:
3844 3870
3845```json theme={null}3871```json theme={null}
3846{3872{
3859 Salida de Elicitation3885 Salida de Elicitation
3860</h4>3886</h4>
3861 3887
3862Un 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:3888Un 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 un `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:
3863 3889
3864| Para | Devuelve | El servidor recibe |3890| Para | Devuelve | El servidor recibe |
3865| :- | :- | :- |3891| :- | :- | :- |
3866| Responder en nombre del usuario | `"action": "accept"`, con los valores de los campos del formulario en `content` | `accept` con tu `content` |3892| Responder en nombre del usuario | `"action": "accept"`, con los valores de los campos del formulario en `content` | `accept` con tu `content` |
3867| Rechazar la solicitud | `"action": "decline"` | `decline` |3893| Rechazar la solicitud | `"action": "decline"` | `decline` |
3868| Cancelar la solicitud | `"action": "cancel"` | `cancel` |3894| Cancelar la solicitud | `"action": "cancel"` | `cancel` |
3869| 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) |3895| Dejar la solicitud al usuario | Sin salida, con código de salida 0 | La respuesta del usuario desde el [diálogo](/docs/es/mcp#respond-to-mcp-elicitation-requests) |
3870 3896
3871Esta 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:3897Esta salida responde la solicitud en modo formulario que se muestra en [Entrada de Elicitation](#elicitation-input). Las claves de `content` son los nombres de propiedad del `requested_schema` de esa solicitud:
3872 3898
3873```json theme={null}3899```json theme={null}
3874{3900{
3895 3921
3896En el diálogo, seleccionar **Decline** envía `decline` y presionar `Esc` envía `cancel`, así que devuelve el que quieras que vea el servidor.3922En el diálogo, seleccionar **Decline** envía `decline` y presionar `Esc` envía `cancel`, así que devuelve el que quieras que vea el servidor.
3897 3923
3898Para una solicitud en modo URL, un hook que devuelve `accept` omite el diálogo, por lo que la URL nunca se abre.3924Para una solicitud en modo URL, un hook que devuelve `accept` omite el diálogo, así que la URL nunca se abre.
3899 3925
3900Claude Code descarta `reason`, `systemMessage` y `continue` de la salida JSON de un hook Elicitation, sea cual sea la `action` que devuelvas.3926Claude Code descarta `reason`, `systemMessage` y `continue` de la salida JSON de un hook Elicitation, sea cual sea el `action` que devuelvas.
3901 3927
3902<h4 id="other-ways-to-decline-an-elicitation">3928<h4 id="other-ways-to-decline-an-elicitation">
3903 Otras formas de rechazar una elicitación3929 Otras formas de rechazar una elicitación
3904</h4>3930</h4>
3905 3931
3906Tu hook también puede rechazar de estas formas. El servidor recibe el mismo `decline` que con `"action": "decline"`:3932Tu hook también puede rechazar de estas maneras. El servidor recibe el mismo `decline` que con `"action": "decline"`:
3907 3933
3908* **Termina con el código 2**: Claude Code ignora un `hookSpecificOutput` impreso por el mismo hook3934* **Termina con el código 2**: Claude Code ignora un `hookSpecificOutput` impreso por el mismo hook
3909* **Imprime un `"decision": "block"` de nivel superior**: el bloqueo sobrescribe una `action` en la misma salida3935* **Imprime un `"decision": "block"` de nivel superior**: el bloqueo sobrescribe un `action` en la misma salida
3910 3936
3911Cuando varios hooks coinciden con la misma solicitud, un rechazo de uno de ellos sobrescribe un `accept` o `cancel` de otro.3937Cuando varios hooks coinciden con la misma solicitud, un rechazo de uno de ellos sobrescribe un `accept` o `cancel` de otro.
3912 3938
3919fi3945fi
3920```3946```
3921 3947
3922Ni el usuario ni el servidor ven por qué rechazó tu hook, porque Claude Code no muestra tu stderr ni tu `reason`.3948Ni el usuario ni el servidor ven por qué tu hook rechazó, porque Claude Code no muestra tu stderr ni tu `reason`.
3923 3949
3924Claude 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.3950Claude 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.
3925 3951
3927 Responder una solicitud de formulario desde un script3953 Responder una solicitud de formulario desde un script
3928</h4>3954</h4>
3929 3955
3930Este 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.3956Este 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, así que aparece el diálogo.
3931 3957
3932<Tabs>3958<Tabs>
3933 <Tab title="macOS/Linux">3959 <Tab title="macOS/Linux">
3966 </Tab>3992 </Tab>
3967 3993
3968 <Tab title="Windows (PowerShell)">3994 <Tab title="Windows (PowerShell)">
3969 Registra un hook de comando que ejecute el script a través de PowerShell, con el nombre del servidor como matcher:3995 Registra un hook de comando que ejecute el script mediante PowerShell, con el nombre del servidor como matcher:
3970 3996
3971 ```json theme={null}3997 ```json theme={null}
3972 {3998 {
4047 Salida de ElicitationResult4073 Salida de ElicitationResult
4048</h4>4074</h4>
4049 4075
4050Un 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:4076Un 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 un `action`. Cada fila de esta tabla muestra qué devolver para un resultado y qué recibe el servidor MCP:
4051 4077
4052| Para | Devuelve | El servidor recibe |4078| Para | Devuelve | El servidor recibe |
4053| :- | :- | :- |4079| :- | :- | :- |
4054| Dejar pasar la respuesta | Ninguna salida, con código de salida 0 | La respuesta del usuario, sin cambios |4080| Dejar pasar la respuesta | Sin salida, con código de salida 0 | La respuesta del usuario, sin cambios |
4055| Cambiar los valores enviados | `"action": "accept"`, con los nuevos valores en `content` | `accept` con tu `content` en lugar de los valores del usuario |4081| Cambiar los valores enviados | `"action": "accept"`, con los nuevos valores en `content` | `accept` con tu `content` en lugar de los valores del usuario |
4056| Bloquear la respuesta | `"action": "decline"` | `decline`, sin los valores del usuario |4082| Bloquear la respuesta | `"action": "decline"` | `decline`, sin los valores del usuario |
4057| Cancelar la solicitud | `"action": "cancel"` | `cancel`, junto con los valores que envió el usuario. Para ocultarlos, devuelve `"decline"` |4083| Cancelar la solicitud | `"action": "cancel"` | `cancel`, junto con los valores que envió el usuario. Para retenerlos, devuelve `"decline"` |
4058 4084
4059Esta 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`:4085Esta salida cambia la respuesta que se muestra en [Entrada de ElicitationResult](#elicitationresult-input), así que el servidor recibe `alice@example.com` donde el usuario envió `alice`:
4060 4086
4061```json theme={null}4087```json theme={null}
4062{4088{
4070}4096}
4071```4097```
4072 4098
4073Tu `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`.4099Tu `content` reemplaza todo el objeto `content` del usuario, así que incluye los campos que no vas a cambiar. Devuelve `action` junto con él, porque Claude Code ignora un `hookSpecificOutput` que no tenga `action`.
4074 4100
4075Los 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:4101Los hooks ElicitationResult también se ejecutan cuando el usuario rechaza o cancela, y tu `action` reemplaza el suyo. Comprueba que el `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:
4076 4102
4077```bash theme={null}4103```bash theme={null}
4078#!/bin/bash4104#!/bin/bash
4096 4122
4097El 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`.4123El 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`.
4098 4124
4099Claude Code descarta `reason`, `systemMessage` y `continue` de la salida JSON de un hook ElicitationResult, sea cual sea la `action` que devuelvas.4125Claude Code descarta `reason`, `systemMessage` y `continue` de la salida JSON de un hook ElicitationResult, sea cual sea el `action` que devuelvas.
4100 4126
4101<h2 id="prompt-based-hooks">4127<h2 id="prompt-based-hooks">
4102 Hooks basados en prompts4128 Hooks basados en prompts
4351* **Sola en stdout**: cuando la respuesta es el único texto en stdout, puede abarcar varias líneas, como la salida de `jq` con formato legible. Abarcar varias líneas requiere Claude Code v2.1.295 o posterior.4377* **Sola en stdout**: cuando la respuesta es el único texto en stdout, puede abarcar varias líneas, como la salida de `jq` con formato legible. Abarcar varias líneas requiere Claude Code v2.1.295 o posterior.
4352* **En una línea propia**: un hook asincrónico puede imprimir otro texto en stdout cuando la respuesta cabe por sí sola en una línea, por ejemplo con `jq -c`.4378* **En una línea propia**: un hook asincrónico puede imprimir otro texto en stdout cuando la respuesta cabe por sí sola en una línea, por ejemplo con `jq -c`.
4353 4379
4354Claude Code valida esa respuesta JSON contra el mismo [esquema de salida](#json-output) que los hooks sincronos, y descarta cualquier campo cuyo valor tenga el tipo incorrecto, como un `systemMessage` que no sea una cadena, en lugar de entregarlo. Ejecute con `--debug` para ver una advertencia que nombre cada campo descartado. Antes de v2.1.202, la salida JSON malformada de un hook asincrónico podría bloquear la sesión, y el bloqueo se repetía cada vez que se reanudaba la sesión.4380Claude Code valida esa respuesta JSON contra el mismo [esquema de salida](#json-output) que los hooks síncronos, y descarta cualquier campo cuyo valor tenga el tipo incorrecto, como un `systemMessage` que no sea una cadena, en lugar de entregarlo. Ejecuta con `--debug` para ver una advertencia que nombre cada campo descartado.
4355 4381
4356Las notificaciones de finalización de hooks asincronos se suprimen por defecto. Para verlas, habilite el modo detallado con `Ctrl+O` o inicie Claude Code con `--verbose`.4382Las notificaciones de finalización de hooks asincronos se suprimen por defecto. Para verlas, habilite el modo detallado con `Ctrl+O` o inicie Claude Code con `--verbose`.
4357 4383