Saltar al contenido principalSaltar al contenido
Análisis a fondo

Cómo saber cuándo Claude Code, Codex u OpenCode te están esperando

Claude Code te avisa de que está esperando con tres hooks: PreToolUse sobre AskUserQuestion, una Notification de tipo permission_prompt y un Stop cuyo último mensaje termina con una pregunta. Ignora idle_prompt, que llega tras cualquier respuesta que nadie contesta. Este es el mapa que usa Foxl Code para las terminales remotas de Claude Code, Codex, OpenCode y Hermes, lo que cada CLI no puede notificar y cómo escribir un hook que le cueste poco al agente y nunca hable con el modelo por accidente.

Foxl Team14 min de lectura

Una ventana de terminal dibujada a mano cuyo cursor está bajo un signo de interrogación; una línea que sale de la ventana termina en un anzuelo que ha atrapado un teléfono con una campana.
En esta página
Revisado el 23 de octubre de 2026 con la implementación publicada y las pruebas que se conservan.

Los hooks de Claude Code ejecutan un comando que tú configuras cuando ocurre un evento concreto, y tres de ellos te dicen que te está esperando. Un hook PreToolUse sobre la herramienta AskUserQuestion se dispara cuando abre su diálogo de pregunta. Un hook Notification de tipo permission_prompt se dispara cuando un diálogo de permiso lleva unos segundos abierto. Un hook Stop se dispara al final de cada respuesta y lleva el texto de la respuesta en last_assistant_message, así que puedes comprobar si terminó con una pregunta. Ignora idle_prompt: llega más o menos un minuto después de cualquier respuesta tras la que nadie ha escrito nada, no solo después de una pregunta.

Foxl Code, que ejecuta agentes de programación en terminales remotas, usa exactamente estos tres para marcar una terminal remota de Claude Code como a la espera de su usuario. Desde v0.9.3-beta.5, el mismo comando de aviso lee también Codex, OpenCode y Hermes a través de sus propios hooks y plugins. A continuación, el mapa de cada CLI, las trampas de cada una y cómo escribir el hook para que le cueste al agente lo menos posible y nunca cuele texto en el contexto del modelo. Ninguna terminal en vivo en la nube ha notificado todavía una pregunta; la última sección explica qué falta por verificar.

¿Por qué no ves que un agente en una terminal te está esperando?

Quien ejecuta agentes en terminales remotas puede tener varias abiertas a la vez y no estar mirando ninguna. El 21 de octubre de 2026, una terminal remota de Claude Code hizo una pregunta de sí o no y se quedó parada en su prompt mientras la propia API de Foxl decía que ninguna tarea esperaba a nadie. La barra lateral de Foxl Code, su lista "Requiere tu atención" de tareas que esperan a una persona y la app del teléfono no dijeron nada. Antes de este cambio, nada en Foxl Code estaba pendiente de ese momento.

Leer la pantalla parece la solución, pero se rompe con facilidad. Para un lector externo, las pantallas de pensando, terminado y preguntando se diferencian en unos pocos caracteres del propio dibujo de la CLI, y cualquier versión puede redibujarlas. Una vez que actualizamos las versiones de las CLI que distribuimos, las nuevas compilaciones dibujaban una primera pantalla distinta de la que esperaba nuestra comprobación de entrada, y las terminales remotas de Codex y OpenCode ignoraron en silencio lo que se escribía durante diez días. Un hook es la propia declaración de la CLI de lo que acaba de pasar, con un contenido documentado, así que eso es lo que escuchamos.

¿Qué hooks de Claude Code significan "te estoy esperando"?

Nuestras imágenes en la nube fijan Claude Code 2.1.296. Cuando un detalle de abajo aparece como leído del paquete, procede del paquete npm de esa versión, no de una terminal en ejecución.

hookqué significalo tratamos como
PreToolUse, matcher AskUserQuestionel diálogo de pregunta está a punto de abrirse; tool_input lleva las preguntas y sus opcionesuna pregunta, con sus opciones
Notification, matcher permission_promptun diálogo de permiso lleva unos seis segundos abierto sin ninguna pulsación (leído del paquete)una solicitud de permiso
Stopla respuesta ha terminado; last_assistant_message es su textouna pregunta si el texto termina en ?; si no, el final de un turno
UserPromptSubmit, PostToolUse, PostToolUseFailure, SessionEndla persona escribió, la herramienta aprobada se ejecutó o falló, la CLI terminórespondida
Notification, tipo idle_prompt"Claude finished responding about 60 seconds ago and you haven't typed since"ignorado

La fila de idle_prompt es donde fallan la mayoría de las configuraciones. Su mensaje parece justo lo que buscas, pero llega después de cualquier respuesta tras la que nadie escribió, así que tratarlo como una pregunta lanza un aviso después de casi cada turno (en el caso de Foxl, una entrada en "Requiere tu atención" y una notificación en el teléfono). Registramos el hook Notification solo con el matcher permission_prompt, y el script vuelve a comprobar el tipo. Para la prueba de Stop, quitamos los espacios finales, el énfasis de Markdown, las comillas invertidas, los corchetes y paréntesis de cierre y las comillas antes de mirar, y aceptamos el ? de ancho completo que escriben los métodos de entrada CJK.

La documentación actual de Claude Code también recoge un evento específico PermissionRequest y más tipos de notificación que estos. No comprobamos si la 2.1.296 tiene el evento más reciente. permission_prompt sigue en la lista actual, y su espera de seis segundos descarta un diálogo que alguien responde delante de la pantalla. Añade los hooks al archivo de configuración de usuario de Claude Code, después de los hooks que ya haya configurados para el mismo evento, para que los existentes sigan ejecutándose:

{
  "hooks": {
    "PreToolUse": [{ "matcher": "AskUserQuestion",
      "hooks": [{ "type": "command", "command": "report-prompt", "timeout": 10 }] }],
    "Notification": [{ "matcher": "permission_prompt",
      "hooks": [{ "type": "command", "command": "report-prompt", "timeout": 10 }] }],
    "Stop": [{ "hooks": [{ "type": "command", "command": "report-prompt", "timeout": 10 }] }]
  }
}

Todos ellos llaman a un pequeño script, el comando de aviso (report-prompt arriba), que lee la credencial de la tarea de su entorno. Los eventos que significan que la persona respondió, UserPromptSubmit y el resto (los eventos de cierre), se registran de la misma forma, detrás de una guarda que se describe más abajo.

¿Cómo se escribe un hook que le cueste al agente lo menos posible?

Un hook de aviso se ejecuta dentro del propio bucle del agente, así que cualquier error en él es problema del agente. Acabamos con cinco reglas, cada una sacada de la documentación o del paquete 2.1.296:

  • No imprimas nada en stdout. En la mayoría de los eventos, Claude Code solo registra el stdout de un hook, pero en UserPromptSubmit y algunos otros "Claude Code adds plain-text stdout as context that Claude can see and act on." Una línea de estado de un script de aviso pasaría a formar parte del prompt.
  • Sal siempre con 0. El código 2 bloquea la acción en los eventos que pueden bloquear, y cualquier otro código distinto de cero muestra un aviso de error. En nuestro script, un fallo de red cuesta una línea en stderr y nada más.
  • Ejecuta de forma síncrona, con un tiempo límite corto. Los hooks pueden ejecutarse con "async": true, pero la compilación fijada imprime una línea en la terminal cada vez que termina un hook asíncrono, lo que se convierte en ruido cuando los hooks se ejecutan después de cada llamada a una herramienta. Nuestros hooks son síncronos con timeout: 10, y el script da tres segundos a su petición y sale por sí solo un momento después. En Claude Code, el coste real es un arranque de Node.js y una petición al final de cada respuesta, como mucho unos tres segundos cuando el servidor de Foxl no está accesible.
  • Filtra los eventos frecuentes en la shell. PostToolUse se dispara en cada llamada a una herramienta. El comando de aviso crea un archivo marcador cuando notifica una pregunta abierta. Los hooks de cierre solo arrancan Node.js si ese archivo existe, y si no, vacían stdin para que la CLI nunca vea una tubería rota:
    if [ -e /tmp/foxl-agent-prompt/open ]; then exec report-prompt; else cat >/dev/null; fi
    Mientras no hay nada abierto, eso es un test -e por llamada a una herramienta.
  • Deja la credencial fuera de la línea de comandos. El hook hereda el entorno de la CLI, así que el token se lee de una variable de entorno y nunca aparece en ps.

¿Cómo lo dicen Codex, OpenCode y Hermes?

Cada CLI tiene su propio punto de extensión; los leímos todos en la versión que fijan nuestras imágenes. Codex tiene un motor de hooks que acepta el formato de hooks de Claude Code. OpenCode y Hermes (la CLI de agente de Nous Research) no ejecutan hooks de shell en su interfaz de terminal; cargan plugins, y nuestros plugins pasan al mismo comando de aviso un evento normalizado. Kiro, la CLI de programación de AWS, no tiene ningún evento que escuchar.

CLI (versión fijada)preguntarespondidano se notifica
Codex 0.162.1, un hooks.json a nivel de sistemaPermissionRequest; Stop cuyo last_assistant_message termina en ?UserPromptSubmit, PostToolUse, Interrupt, SessionEndel diálogo de pregunta del modo Plan
OpenCode 1.19.0, un plugin de servidorquestion.asked, permission.asked; session.status en idle con una respuesta que termina en ?question.replied o rejected, permission.replied, session.status en busy-
Hermes 0.19.0, un plugin de Pythonpre_tool_call para clarify, pre_approval_request, post_llm_call que termina en ?post_tool_call para clarify, post_approval_response, pre_llm_call, un on_session_end interrumpido-
Kiro 2.29.1nada-todo: no hay evento de pregunta ni de aprobación, y su Stop no lleva el texto de la respuesta

Codex. Codex revisa los hooks de tu propia configuración antes de ejecutarlos: los hooks nuevos o modificados "are marked for review and skipped until trusted." Un hook gestionado, definido en la configuración a nivel de sistema, es de confianza por política, así que instalamos los nuestros de esa forma. El propio comando de aviso solo se instala en las terminales donde Foxl Code pidió avisos de preguntas. Medido en 0.162.1, el codex exec no interactivo también ejecuta los hooks gestionados e imprime en su salida dos líneas sobre ellos por cada llamada a una herramienta, así que desactivamos los hooks en las ejecuciones que Foxl Code lanza con codex exec. Según el código fuente de 0.162.1, la interfaz de terminal de Codex muestra cualquier hook que tarde más de 300 ms, así que el comando de aviso decide si hay una pregunta, escribe su archivo marcador y pasa la petición de red a una copia de sí mismo desvinculada.

El diálogo de pregunta del modo Plan de Codex no se notifica a propósito, porque su hook PreToolUse se dispara antes de que Codex decida si la pregunta está permitida, y fuera del modo Plan Codex la rechaza. Medido en 0.162.1, el hook se disparó con la pregunta y luego Codex respondió "request_user_input is unavailable in Default mode". Las terminales de Foxl Code arrancan en el modo Default, así que notificar ese hook enviaría a tu teléfono una pregunta que nunca se le hizo a nadie. La contrapartida es que una terminal de Codex en modo Plan no lleva su diálogo de pregunta a "Requiere tu atención".

OpenCode. Nuestro plugin escucha el bus de eventos de OpenCode. Los eventos de pregunta no están en la lista de eventos de la documentación de plugins de OpenCode; están en el código fuente del esquema de v1.19.0, que es lo que leímos. Un estado idle termina un turno, y el turno cuenta como pregunta cuando su última respuesta termina en ?. Mientras hay un diálogo de pregunta o de permiso abierto, los cambios de estado se ignoran, para que el agente pasando a busy o idle alrededor del diálogo no lo cierre. Los eventos de la sesión de un subagente se omiten.

Hermes. Pese a su nombre, el on_session_end de Hermes se dispara al final de cada turno en 0.19.0, justo después de la respuesta. Cuando nuestro plugin lo trataba como un cierre, retiraba la pregunta que el turno acababa de hacer: 7 de 12 preguntas se cerraron al instante, y en 1 de 12 la pregunta llegó al servidor después de su propio cierre, así que se quedó abierta sin nada que la cerrara. Ahora solo un final de sesión interrumpido cuenta como cierre, y los avisos salen de uno en uno en el orden en que Hermes los generó.

Kiro no está cubierto, porque sus hooks no tienen evento de pregunta ni de aprobación, y el contenido de su evento de parada no lleva el texto de la respuesta. Un hook no podría ni abrir una pregunta ni distinguir una pregunta de una respuesta. La única señal es un archivo de sesión interno con un formato no publicado, y decidimos no analizarlo.

¿Qué pasa cuando Foxl lo sabe?

Cada aviso va a un único endpoint del servidor de Foxl Code, autenticado con la credencial propia de esa tarea, y abre o cierra una entrada en la misma lista "Requiere tu atención" que contiene las demás preguntas de los agentes. La tarea se marca como esperando tu respuesta, como en la figura.

La página Work de Foxl Code. En la columna Needs you, una tarjeta dice 'Claude Code is asking' con una pregunta de sí o no sobre un trabajo que falla a propósito y un cuadro de respuesta con Send. Una segunda tarjeta dice 'Claude Code is asking' con una pregunta y tres opciones, seguida de 'Answer this in the terminal.' y un botón Show terminal. En la columna In flight, dos tareas dicen 'Waiting for your answer'.
Figura 1. La página Trabajo de Foxl Code en la compilación del pull request, con preguntas de ejemplo. Una pregunta dentro de una respuesta se puede contestar aquí; un diálogo se contesta en la terminal.

Una pregunta al final de una respuesta se puede contestar desde "Requiere tu atención" o desde el teléfono. Foxl escribe la respuesta en la terminal de esa tarea como una sola línea y envía la tecla Enter por separado un segundo después, porque un único bloque que incluya el Enter se trata como un pegado y nunca se envía. Para un diálogo de pregunta o de permiso, Foxl nunca adivina las pulsaciones que espera la interfaz de la terminal. En su lugar, su tarjeta en "Requiere tu atención" enumera las opciones, indica que se responda en la terminal y tiene un botón que la abre. Responder en la terminal cierra la tarjeta a través de los mismos hooks.

El teléfono solo recibe avisos de las preguntas que pueden pasar desapercibidas. Un diálogo de pregunta o de permiso que sigue abierto 15 segundos después de que Foxl se entere envía una notificación, porque una persona que está mirando la terminal responde en segundos. Un diálogo de permiso de Claude Code se notifica unos seis segundos después de abrirse, así que su notificación llega hacia el segundo 21. Una respuesta que termina con una pregunta se muestra en "Requiere tu atención", pero no se anuncia, porque muchas respuestas terminan con una. La pregunta del 21 de octubre era de ese tipo, así que ahora aparecería en "Requiere tu atención" y en la tarea, y seguiría sin hacer sonar el teléfono.

Un flujo de izquierda a derecha. Cuatro CLI, Claude Code, Codex, OpenCode y Hermes, avisan cada una a través de su propio hook o plugin a un pequeño comando dentro de la máquina del agente. El comando abre o cierra una pregunta en el servidor de Foxl Code con la credencial de la tarea. El servidor la muestra en Needs you y en la tarea, y solo avisa al teléfono si un diálogo sigue abierto 15 segundos después del aviso.
Figura 2. Cuatro CLI avisan a través de un solo comando; el teléfono solo se entera de un diálogo cuando nadie lo ha respondido 15 segundos después del aviso.

¿Qué falta por verificar?

En nuestras pruebas, el comando de aviso real se ejecutó con los contenidos de cada CLI fijada, los plugins se ejecutaron con Node.js y Python sobre los formatos de evento fijados, y el endpoint del servidor se ejecutó en una copia local del runtime de Cloudflare. Lo que todavía no ha ocurrido:

  • Una pregunta en vivo desde una terminal real en la nube. A fecha de 23 de octubre de 2026, la tabla de producción no contiene ninguna pregunta de una, así que la comprobación de extremo a extremo en una terminal en vivo sigue pendiente.
  • Claude Code ejecutando estos hooks. Los detalles de Claude Code, incluidos el retraso de seis segundos y la línea de los hooks asíncronos, se leyeron del paquete 2.1.296, no se vieron en una terminal en ejecución. Tenemos una prueba que ejecuta esa compilación con estos hooks; todavía no se ha ejecutado.
  • Las terminales de las otras CLI. Varios detalles de Codex, OpenCode y Hermes se leyeron del código fuente, entre ellos que OpenCode entrega los eventos de pregunta con esos nombres exactos; solo se ejecutó codex exec.

Si ejecutas agentes en tus propias terminales, la tabla de hooks de Claude Code es la parte que conviene copiar. Conecta los tres hooks a lo que sea que te llegue, ignora idle_prompt, no imprimas nada, sal con 0 y espera unos segundos antes de enviar un aviso. Para la parte de la terminal de Foxl Code, nuestro artículo sobre por qué cada pulsación llegó un tiempo a la máquina equivocada (en inglés) explica cómo llega lo que escribes a un agente remoto.

Referencias y lecturas recomendadas

  1. Claude Code: referencia de hooksDocumentación
  2. Codex: hooksDocumentación
  3. OpenCode: pluginsDocumentación
  4. Hermes Agent (Nous Research)Referencia
  5. Versión v0.9.3-beta.5 de FoxlVersión