297| :-------------- | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |297| :-------------- | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
298| `type` | sí | `"command"`, `"http"`, `"mcp_tool"`, `"prompt"` o `"agent"` |298| `type` | sí | `"command"`, `"http"`, `"mcp_tool"`, `"prompt"` o `"agent"` |
299| `if` | no | Sintaxis de regla de permiso para filtrar cuándo se ejecuta este hook, como `"Bash(git *)"` o `"Edit(*.ts)"`. El hook solo se genera si la llamada a herramienta coincide con el patrón, o si un comando Bash es demasiado complejo para analizar. Solo se evalúa en eventos de herramientas: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest` y `PermissionDenied`. En otros eventos, un hook con `if` establecido nunca se ejecuta. Utiliza la misma sintaxis que [reglas de permiso](/es/permissions) |299| `if` | no | Sintaxis de regla de permiso para filtrar cuándo se ejecuta este hook, como `"Bash(git *)"` o `"Edit(*.ts)"`. El hook solo se genera si la llamada a herramienta coincide con el patrón, o si un comando Bash es demasiado complejo para analizar. Solo se evalúa en eventos de herramientas: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest` y `PermissionDenied`. En otros eventos, un hook con `if` establecido nunca se ejecuta. Utiliza la misma sintaxis que [reglas de permiso](/es/permissions) |
300| `timeout` | no | Segundos antes de cancelar. Valores predeterminados: 600 para comando, 30 para prompt, 60 para agente |300| `timeout` | no | Segundos antes de cancelar. Valores predeterminados: 600 para `command`, `http` y `mcp_tool`; 30 para `prompt`; 60 para `agent`. [`UserPromptSubmit`](#userpromptsubmit) reduce el valor predeterminado de `command`, `http` y `mcp_tool` a 30 |
301| `statusMessage` | no | Mensaje de spinner personalizado mostrado mientras se ejecuta el hook |301| `statusMessage` | no | Mensaje de spinner personalizado mostrado mientras se ejecuta el hook |
302| `once` | no | Si es `true`, se ejecuta una vez por sesión y luego se elimina. Solo se honra para hooks declarados en [skill frontmatter](#hooks-in-skills-and-agents); se ignora en archivos de configuración y frontmatter de agente |302| `once` | no | Si es `true`, se ejecuta una vez por sesión y luego se elimina. Solo se honra para hooks declarados en [skill frontmatter](#hooks-in-skills-and-agents); se ignora en archivos de configuración y frontmatter de agente |
303 303
558 558
559Los hooks de comando reciben datos JSON a través de stdin y comunican resultados a través de códigos de salida, stdout y stderr. Los hooks HTTP reciben el mismo JSON que el cuerpo de la solicitud POST y comunican resultados a través del cuerpo de la respuesta HTTP. Esta sección cubre campos y comportamiento comunes a todos los eventos. Cada sección de evento bajo [Hook events](#hook-events) incluye su esquema de entrada específico y opciones de control de decisión.559Los hooks de comando reciben datos JSON a través de stdin y comunican resultados a través de códigos de salida, stdout y stderr. Los hooks HTTP reciben el mismo JSON que el cuerpo de la solicitud POST y comunican resultados a través del cuerpo de la respuesta HTTP. Esta sección cubre campos y comportamiento comunes a todos los eventos. Cada sección de evento bajo [Hook events](#hook-events) incluye su esquema de entrada específico y opciones de control de decisión.
560 560
561En macOS y Linux, los hooks de comando se ejecutan en su propia sesión sin una terminal de control a partir de v2.1.139. El proceso de hook y cualquier proceso secundario no pueden abrir `/dev/tty` o enviar secuencias de escape directamente a la interfaz de Claude Code. Windows no tiene `/dev/tty`. Para mostrar un mensaje al usuario en cualquier plataforma, devuelva [`systemMessage`](#json-output) en la salida JSON. Para activar una notificación de escritorio, establecer un título de ventana o sonar la campana, devuelva [`terminalSequence`](#emit-terminal-notifications) en su lugar.
562
561### Campos de entrada comunes563### Campos de entrada comunes
562 564
563Los eventos de hook reciben estos campos como JSON, además de campos específicos del evento documentados en cada sección [hook event](#hook-events). Para hooks de comando, este JSON llega a través de stdin. Para hooks HTTP, llega como el cuerpo de la solicitud POST.565Los eventos de hook reciben estos campos como JSON, además de campos específicos del evento documentados en cada sección [hook event](#hook-events). Para hooks de comando, este JSON llega a través de stdin. Para hooks HTTP, llega como el cuerpo de la solicitud POST.
685 687
686El stdout de su hook debe contener solo el objeto JSON. Si su perfil de shell imprime texto al inicio, puede interferir con el análisis JSON. Consulte [JSON validation failed](/es/hooks-guide#json-validation-failed) en la guía de solución de problemas.688El stdout de su hook debe contener solo el objeto JSON. Si su perfil de shell imprime texto al inicio, puede interferir con el análisis JSON. Consulte [JSON validation failed](/es/hooks-guide#json-validation-failed) en la guía de solución de problemas.
687 689
688La salida de hook inyectada en contexto (`additionalContext`, `systemMessage` o stdout plano) está limitada a 10.000 caracteres. La salida que excede este límite se guarda en un archivo y se reemplaza con una vista previa y ruta de archivo, de la misma manera que se manejan los resultados de herramientas grandes.690Las cadenas de salida de hook, incluyendo `additionalContext`, `systemMessage` y stdout plano, están limitadas a 10.000 caracteres. La salida que excede este límite se guarda en un archivo y se reemplaza con una vista previa y ruta de archivo, de la misma manera que se manejan los resultados de herramientas grandes.
689 691
690El objeto JSON admite tres tipos de campos:692El objeto JSON admite tres tipos de campos:
691 693
694* **`hookSpecificOutput`** es un objeto anidado para eventos que necesitan control más rico. Requiere un campo `hookEventName` establecido en el nombre del evento.696* **`hookSpecificOutput`** es un objeto anidado para eventos que necesitan control más rico. Requiere un campo `hookEventName` establecido en el nombre del evento.
695 697
696| Campo | Predeterminado | Descripción |698| Campo | Predeterminado | Descripción |
697| :--------------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |699| :----------------- | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
698| `continue` | `true` | Si es `false`, Claude detiene el procesamiento completamente después de que se ejecuta el hook. Tiene precedencia sobre cualquier campo de decisión específico del evento |700| `continue` | `true` | Si es `false`, Claude detiene el procesamiento completamente después de que se ejecuta el hook. Tiene precedencia sobre cualquier campo de decisión específico del evento |
699| `stopReason` | ninguno | Mensaje mostrado al usuario cuando `continue` es `false`. No se muestra a Claude |701| `stopReason` | ninguno | Mensaje mostrado al usuario cuando `continue` es `false`. No se muestra a Claude |
700| `suppressOutput` | `false` | Si es `true`, omite stdout del registro de depuración |702| `suppressOutput` | `false` | Si es `true`, omite stdout del registro de depuración |
701| `systemMessage` | ninguno | Mensaje de advertencia mostrado al usuario |703| `systemMessage` | ninguno | Mensaje de advertencia mostrado al usuario |
704| `terminalSequence` | ninguno | Una secuencia de escape de terminal para que Claude Code emita en su nombre, como una notificación de escritorio, título de ventana o campana. Restringido a OSC `0`/`1`/`2`/`9`/`99`/`777` y BEL. Si el valor contiene algo fuera de la lista de permitidos, el campo se ignora. Use esto en lugar de escribir en `/dev/tty`, que no está disponible para hooks |
702 705
703Para detener Claude completamente independientemente del tipo de evento:706Para detener Claude completamente independientemente del tipo de evento:
704 707
706{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }709{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }
707```710```
708 711
712#### Emitir notificaciones de terminal
713
714El campo `terminalSequence` requiere Claude Code v2.1.141 o posterior.
715
716Los hooks se ejecutan sin una terminal de control, por lo que escribir secuencias de escape directamente en `/dev/tty` falla. En su lugar, devuelva la secuencia de escape en el campo `terminalSequence` y Claude Code la emite por usted a través de su propia ruta de escritura de terminal. Esto es libre de carreras, funciona dentro de tmux y GNU screen, y funciona en Windows donde no hay `/dev/tty`.
717
718El campo acepta una cadena de una o más secuencias de escape permitidas:
719
720* OSC `0`, `1`, `2`: títulos de ventana e icono
721* OSC `9`: notificaciones de iTerm2, ConEmu, Windows Terminal y WezTerm, incluyendo progreso de barra de tareas `9;4`
722* OSC `99`: notificaciones de Kitty
723* OSC `777`: notificaciones de urxvt, Ghostty y Warp
724* BEL desnudo
725
726Las secuencias pueden terminarse con BEL o con ST. Cualquier cosa fuera de la lista de permitidos, incluyendo secuencias de cursor y color CSI, secuencias de paleta OSC, hipervínculos OSC 8, escrituras de portapapeles OSC 52 y OSC 1337, se rechaza y el campo se ignora.
727
728El ejemplo a continuación dispara una notificación de escritorio desde un hook `Notification`. La secuencia de escape se construye con escapes octales `printf` para que los bytes de control nunca aparezcan en la línea de comandos del shell, y `jq -n --arg` construye la salida JSON para que las comillas, barras invertidas y saltos de línea en el mensaje de notificación se escapen correctamente:
729
730```bash theme={null}
731#!/bin/bash
732# Hook de notificación: ping al escritorio cuando Claude Code necesita atención.
733input=$(cat)
734title="Claude Code'
735body=$(jq -r '.message // "Needs your attention"' <<<"$input")
736seq=$(printf '\033]777;notify;%s;%s\007' "$title" "$body")
737jq -nc --arg seq "$seq" '{terminalSequence: $seq}'
738```
739
740La forma `{ "terminalSequence": "..." }` es la misma desde cualquier shell o lenguaje. En Windows, construya la cadena de escape en PowerShell o un script y emita el mismo objeto JSON.
741
742<Note>
743 `terminalSequence` es el reemplazo compatible para hooks que anteriormente escribían secuencias de escape directamente en `/dev/tty`. La lista de permitidos está restringida a secuencias que no pueden mover el cursor o alterar colores, por lo que un hook nunca puede corromper un prompt en pantalla.
744</Note>
745
709#### Agregar contexto para Claude746#### Agregar contexto para Claude
710 747
711El campo `additionalContext` pasa una cadena de su hook a la ventana de contexto de Claude. Claude Code envuelve la cadena en un recordatorio del sistema e la inserta en la conversación en el punto donde se activó el hook. Claude lee el recordatorio en la siguiente solicitud del modelo, pero no aparece como un mensaje de chat en la interfaz.748El campo `additionalContext` pasa una cadena de su hook a la ventana de contexto de Claude. Claude Code envuelve la cadena en un recordatorio del sistema e la inserta en la conversación en el punto donde se activó el hook. Claude lee el recordatorio en la siguiente solicitud del modelo, pero no aparece como un mensaje de chat en la interfaz.
989 1026
990Se ejecuta cuando el usuario envía un prompt, antes de que Claude lo procese. Esto le permite agregar contexto adicional basado en el prompt/conversación, validar prompts o bloquear ciertos tipos de prompts.1027Se ejecuta cuando el usuario envía un prompt, antes de que Claude lo procese. Esto le permite agregar contexto adicional basado en el prompt/conversación, validar prompts o bloquear ciertos tipos de prompts.
991 1028
1029Los hooks `UserPromptSubmit` tienen un tiempo de espera predeterminado de 30 segundos para tipos `command`, `http` y `mcp_tool`, más corto que el predeterminado de 600 segundos para esos tipos en otros eventos. Debido a que este hook se ejecuta antes de cada prompt y bloquea el procesamiento del modelo hasta que se completa, un hook atascado detiene la sesión. Si su hook necesita más tiempo, establezca el campo `timeout` en la entrada del hook.
1030
992#### Entrada de UserPromptSubmit1031#### Entrada de UserPromptSubmit
993 1032
994Además de los [campos de entrada comunes](#common-input-fields), los hooks UserPromptSubmit reciben el campo `prompt` que contiene el texto que el usuario envió.1033Además de los [campos de entrada comunes](#common-input-fields), los hooks UserPromptSubmit reciben el campo `prompt` que contiene el texto que el usuario envió.
2598 2637
2599Cuando se activa un hook asincrónico, Claude Code inicia el proceso del hook e inmediatamente continúa sin esperar a que finalice. El hook recibe la misma entrada JSON a través de stdin que un hook sincrónico.2638Cuando se activa un hook asincrónico, Claude Code inicia el proceso del hook e inmediatamente continúa sin esperar a que finalice. El hook recibe la misma entrada JSON a través de stdin que un hook sincrónico.
2600 2639
2601Después de que el proceso de fondo sale, si el hook produjo una respuesta JSON con un campo `systemMessage` o `additionalContext`, ese contenido se entrega a Claude como contexto en el siguiente turno de conversación.2640Después de que el proceso de fondo sale, si el hook produjo una respuesta JSON con un campo `additionalContext`, ese contenido se entrega a Claude como contexto en el siguiente turno de conversación. Un campo `systemMessage` se muestra a usted, no a Claude.
2602 2641
2603Las 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`.2642Las 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`.
2604 2643
2619 exit 02658 exit 0
2620fi2659fi
2621 2660
2622# Ejecute pruebas e informe resultados a través de systemMessage2661# Ejecute pruebas e informe resultados a Claude a través de additionalContext
2623RESULT=$(npm test 2>&1)2662RESULT=$(npm test 2>&1)
2624EXIT_CODE=$?2663EXIT_CODE=$?
2625 2664
2626if [ $EXIT_CODE -eq 0 ]; then2665if [ $EXIT_CODE -eq 0 ]; then
2627 echo "{\"systemMessage\": \"Tests passed after editing $FILE_PATH\"}"2666 MSG="Tests passed after editing $FILE_PATH"
2628else2667else
2629 echo "{\"systemMessage\": \"Tests failed after editing $FILE_PATH: $RESULT\"}"2668 MSG="Tests failed after editing $FILE_PATH: $RESULT"
2630fi2669fi
2670jq -nc --arg msg "$MSG" '{hookSpecificOutput: {hookEventName: "PostToolUse", additionalContext: $msg}}'
2631```2671```
2632 2672
2633Luego agregue esta configuración a `.claude/settings.json` en la raíz de su proyecto. La bandera `async: true` permite que Claude continúe trabajando mientras se ejecutan las pruebas:2673Luego agregue esta configuración a `.claude/settings.json` en la raíz de su proyecto. La bandera `async: true` permite que Claude continúe trabajando mientras se ejecutan las pruebas: