Ver un loop en marcha: la cuenta atrás en vivo que acaba de llegar a CLI, TUI y Desktop

Programaste un loop para vigilar un deploy cada tres minutos y volviste a lo que estabas haciendo. Diez minutos después miras de reojo la terminal y sigue diciendo lo mismo que decía al empezar — next in 3m — así que te haces la pregunta que todo usuario de loops acaba haciéndose: ¿esto sigue vivo, o se ha detenido sin avisar? Esa ambigüedad es exactamente lo que se propuso eliminar un PR mergeado el 15 de octubre, y lo hizo en las tres superficies a la vez.
Qué es un loop permanente, en un párrafo
/loop vuelve a ejecutar un prompt dentro de tu sesión actual con la cadencia que tú elijas, o con la que él mismo decida:
/loop 5m check the deploy status and tell me if it's live yet
Cada wakeup es un turno de agente normal, así que lee el estado actual — el último resultado de CI, la profundidad de la cola, el archivo tal y como está ahora — en vez de reproducir un resumen. Funciona en el CLI, el TUI, el chat del dashboard, la app de escritorio y todas las plataformas del gateway, y vive en esa sesión: las condiciones de parada son LOOP_COMPLETE por parte del agente, --times N, --until <condition>, loops.max_ticks como presupuesto de seguridad (100 por defecto), o tú, con /loop stop y /loop pause.
El problema: una cuenta atrás pintada una sola vez
El comportamiento anterior era una única línea del transcript — ↻ Loop: next in 3m. — impresa cuando se aceptaba el loop. Nunca se movía. En la app de escritorio era peor de una forma más sutil: el next ~45m de la tarjeta del loop se calculaba una vez por render, así que el número quedaba congelado en el valor que tuviera cuando la tarjeta se dibujó por primera vez. La información que necesitabas (cuánto falta para el siguiente wakeup, si está corriendo ahora mismo, si está en pausa) existía en la sesión, pero nada la volvía a pintar.
Lo que muestran ahora las tres superficies
CLI. El dock de trabajo en vivo — el panel que ya sigue goals, subagentes, procesos y la cola — gana una fila de loop:
↻ loop · every 3m · 1 run · next in 2m · <prompt>
La cuenta atrás avanza por minutos y cambia a segundos en el último minuto, de modo que un prompt inactivo se repinta como mucho una vez por minuto en lugar de una vez por segundo. Durante un wakeup muestra running now, y cuando el loop está en pausa indica el motivo de la pausa. Si colapsas el dock, el encabezado lleva un badge compacto — ↻ loop next in 2m — así que sigues teniendo la respuesta sin desplegar nada. Con el dock visible, se elimina la vieja línea estática ↻ Loop: next in 3m. del transcript, porque mantener ambas era simplemente ruido duplicado.
TUI. hermes --tui incorpora una LoopBar situada bajo la GoalBar, con el mismo texto, alimentada por el snapshot de la sesión y un reloj de un segundo que solo repinta cuando la etiqueta cambia de verdad.
Desktop. La tarjeta del loop ahora comparte el reloj de cuenta atrás de un segundo del heartbeat — next 00:02:09 — y una vez pasada la fecha límite dice due — waiting for idle en lugar de mostrar un número que ya se ha vuelto negativo. Esa última cadena se comparte con la tarjeta del heartbeat, y por eso se renombró a una clave común en vez de duplicarla.
La parte que no notarías: el gateway tenía que publicarlo
Una cuenta atrás en el CLI es sencilla — ese proceso es dueño de su terminal. Las barras de Ink en el TUI y la tarjeta en la app de escritorio son otra cosa: leen un snapshot de sesión que el gateway publica como session.control.update. Y esa actualización solo se publicaba cuando alguien hacía clic en un botón de una tarjeta del escritorio. Escribe /loop 3m … en un chat y el estado nunca llegaba a las superficies que debían renderizarlo.
El fix traslada la publicación a los puntos donde el estado del loop cambia de verdad: el owner publica después de un comando slash de automatización, después de los hooks de goal y loop post-turno de una sesión local, y después de que se dispare un wakeup de loop o se asiente un tick de slash. La ruta heredada tui_gateway recibe las mismas dos publicaciones para que los clientes antiguos también vean los wakeups.
Esa es la lección interesante de este PR: añadir un indicador a un valor en vivo rara vez es solo un cambio de indicador. Si el valor lo publica otro, el fix incluye convencerlo de que publique en los momentos correctos — de lo contrario entregas una barra de progreso que solo es honesta en el primer frame.
Cómo saber si ya lo tienes
El cambio se mergeó el 15 de octubre a las 15:34 UTC, y v0.22.2 ya se había publicado esa misma mañana, así que de momento esto está solo en main — el trabajo que solo está en main se publica con v0.23.0. Comprobación práctica:
hermes version
Si estás en una build de release, el dock seguirá mostrando la vieja línea estática. Si necesitas visibilidad del loop hoy y no puedes ejecutar main, el sustituto viable es /loop status, que informa la cadencia, los ticks disparados y el tiempo hasta el siguiente wakeup a petición — una pulsación en lugar de un vistazo, pero sí responde a la pregunta «¿sigue vivo?».
Dos detalles relacionados que conviene saber antes de fiarte de una cuenta atrás: un wakeup es un turno normal con rol de usuario, y el coste en tokens escala con la cadencia, así que un loop de un minuto que no tiene nada que hacer sigue costando un turno por minuto — mejor deja que marque su propio ritmo cuando esperas algo que cambia según su propia agenda. Y para trabajo que debe sobrevivir al cierre de tu terminal, esta no es la herramienta adecuada: una programación desatendida corresponde a un cron job, mientras que /loop es para monitorizar dentro de una sesión en la que ya estás.
También conviene saberlo
loops.min_interval_seconds(30),loops.self_paced_floor_seconds(60) yloops.self_paced_ceiling_seconds(900) son las palancas que hay detrás de la cadencia;loops.max_ticks(100,0para ilimitado) es el tope de seguridad.- Un
/goalactivo es dueño de la sesión: mientras un goal está siendo dirigido por su judge, los wakeups del loop se difieren y se reanudan cuando el goal termina, se pausa o se aparca en una barrera de espera. - Un loop por sesión — definir un nuevo
/loopreemplaza al anterior; varios loops significan varias sesiones (o cron). - En el escritorio y el dashboard, una sesión con un loop activo queda exenta del reaper de sesiones desconectadas, así que los wakeups siguen disparándose después de que cierres la ventana — siempre que el propio proceso backend siga en marcha.
- Ctrl+C en un turno de wakeup pausa el loop en lugar de destruirlo;
/loop resumelo retoma.
Si /loop es nuevo para ti, la guía del comando loop cubre los conceptos básicos sobre los que se apoya esta cuenta atrás.
Fuentes: PR #139187 (/loop shows a live countdown to the next wakeup on CLI, TUI and Desktop, mergeado el 15 de octubre de 2026) y su tabla de validación; website/docs/user-guide/features/loops.md en main para los comandos, los modos de cadencia, las claves de configuración y la comparación entre /loop, /goal y cron.