Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cbe1e92
feat(bash): add real-time streaming and heartbeat monitoring
victormartingil Feb 11, 2026
ee24ffc
feat(build): add real-time streaming and heartbeat to build tools
victormartingil Feb 11, 2026
4cf2d0f
chore(release): bump version to 1.6.0 and update CHANGELOG
victormartingil Feb 11, 2026
29b43cc
feat(repl): add concurrent input handling with interruption classifier
victormartingil Feb 11, 2026
10ac61c
docs(changelog): update v1.6.0 with concurrent input management
victormartingil Feb 11, 2026
2f56031
fix(tests): resolve oxlint warnings in test mocks
victormartingil Feb 11, 2026
e075087
fix(repl): disable concurrent input feature (blocked by input handler)
victormartingil Feb 11, 2026
332e54e
feat(repl): implement full concurrent input with exceptional UX
victormartingil Feb 11, 2026
cb6bc57
fix(repl): ensure stdin properly resumes for background capture
victormartingil Feb 11, 2026
22b4d56
feat(repl): implement Claude Code-style concurrent input
victormartingil Feb 11, 2026
036de01
refactor(repl): persistent bottom prompt with LED status indicator
victormartingil Feb 11, 2026
be8d77c
fix(repl): prevent spinner from overlapping bottom prompt
victormartingil Feb 11, 2026
4b2175b
fix(repl): clear previous prompt renders to prevent duplication
victormartingil Feb 11, 2026
094c849
fix(repl): restore cursor position after rendering prompt
victormartingil Feb 11, 2026
7ecac92
feat(repl): implement concurrent UI with log-update
victormartingil Feb 11, 2026
5f031b4
feat(concurrent-ui): add visual feedback for queued messages
victormartingil Feb 11, 2026
54942c7
feat(concurrent-input): implement intelligent message routing
victormartingil Feb 11, 2026
158a666
test(build): fix streaming subprocess mock for event-based output
victormartingil Feb 11, 2026
20ef8af
refactor(concurrent-input): natural LLM explanations instead of UI fe…
victormartingil Feb 11, 2026
d5f0ef0
fix(concurrent-input): keep spinner running during interruption proce…
victormartingil Feb 11, 2026
a7c5343
fix(concurrent-input): remove console.log that breaks spinner rendering
victormartingil Feb 11, 2026
bdddbbe
fix(concurrent-input): persist spinner state across REPL iterations
victormartingil Feb 11, 2026
d6e2c5d
feat(concurrent-input): immediate feedback when user sends message
victormartingil Feb 11, 2026
c077365
fix(concurrent-input): use logUpdate.clear() to prevent spinner dupli…
victormartingil Feb 11, 2026
200691f
fix(concurrent-input): stop/restart render loop when showing feedback
victormartingil Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,50 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [1.6.0] - 2026-02-11

### Added
- **Real-time command streaming with heartbeat:** Long-running shell/build commands now show live progress instead of black box spinner
- Stream stdout/stderr output in real-time instead of buffering until completion
- CommandHeartbeat monitor shows elapsed time every 10 seconds for commands running >10s
- Warning alerts when command silent for >30 seconds to detect hung processes
- Applied to bash tool (bash_exec) for all shell commands
- Applied to all build tools: runScriptTool (npm/pnpm/yarn scripts), installDepsTool (package installation), makeTool (Makefile targets), tscTool (TypeScript compilation)
- Eliminates "black box" experience during npm install, webpack builds, and other long operations (360+ second operations now have visible progress)

- **Concurrent task management:** ✅ **FULLY WORKING** - Users can now provide input while COCO works
- Interruption handler captures user input during agent execution using background line capture
- LLM-based interruption classifier intelligently routes user input:
- **Modify:** Add context to current task ("also add validation", "use PostgreSQL instead")
- **Interrupt:** Cancel current work ("stop", "cancel", "wait")
- **Queue:** Add new tasks to background queue ("also create a README", "add tests for X")
- **Clarification:** Ask questions about ongoing work ("why did you choose X?", "what's the status?")
- Background task manager integration for queued tasks
- Visual feedback showing received interruptions and routing decisions
- Synthesized messages automatically added to session for "modify" actions
- **UX:** Clean visual indicator shows when interruption mode is active
- **Input:** User sees their typing normally, not mixed with agent output

### Changed
- Bash tool (`bashExecTool`) now uses streaming mode with `buffer: false` for immediate output visibility
- All build tools now use streaming mode for real-time feedback
- Command execution provides live feedback with heartbeat statistics showing elapsed time
- Test mocks updated to use Promise with Object.assign instead of thenable pattern (oxlint compliance)
- `consumeInterruptions()` returns full `QueuedInterruption[]` objects instead of just strings
- `QueuedInterruption` type exported from interruption-handler for external use
- Input handler refactored with `enableBackgroundCapture()` and `disableBackgroundCapture()` methods
- REPL loop now uses background capture instead of full pause during agent turns
- Main REPL loop integrates interruption classification and background task management

### Fixed
- Long-running commands no longer appear frozen or hung - users see real-time progress
- Users can now tell if command is progressing or actually stalled
- Oxlint warnings in test mocks resolved (no-thenable, no-unused-vars)
- Users can now interact during long-running agent tasks - stdin capture works in background
- User input during agent work is properly classified and routed (modify/interrupt/queue/clarification)

---

## [1.5.0] - 2026-02-11

### Added
Expand Down
61 changes: 61 additions & 0 deletions cuento.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
La Espada del Lobo Gris

En las tierras heladas de Skandivia, donde los fiordos se adentran como dedos oscuros en el corazón de la tierra, vivía un joven vikingo llamado Erik. No era el más alto de su clan, ni el más fuerte, pero en sus ojos azules como el hielo de un glaciar ardía una determinación que superaba a la de cualquier guerrero.

Erik pertenecía al clan del Lobo Gris, cuyos antepasados habían navegado hasta las costas de Inglaterra y regresado con riquezas y gloria. Pero ahora, las tierras del norte sufrían un invierno cruel que no terminaba, y el clan agonizaba lentamente.

Una noche, mientras la aurora boreal bailaba sobre las montañas, la anciana vidente del clan, una mujer llamada Sigrid cuyo cabello blanco rivalizaba con la nieve, convocó a Erik.

—El destino te ha elegido, joven lobo —dijo Sigrid, sus ojos ciegos mirando más allá del mundo visible—. En las montañas de Jotunheim, donde los gigantes de hielo aún caminan, yace la Espada del Lobo Gris. Forjada por los enanos en tiempos inmemoriales, su filo puede partir el hielo eterno y traer la primavera de vuelta a nuestras tierras.

—¿Por qué yo? —preguntó Erik—. Hay guerreros más valientes, más fuertes...

—Porque tú tienes algo que ellos no poseen —interrumpió Sigrid—. Tienes un corazón puro. La espada solo obedece a quien no busca poder para sí mismo, sino para su pueblo.

Al amanecer, Erik partió solo hacia el norte. Cruzó valles donde el viento cortaba como cuchillo, escaló acantilados donde ni las águilas se atrevían a anidar, y finalmente llegó a las puertas de Jotunheim.

Allí, en una cueva de hielo azul que brillaba con luz propia, encontró a la guardiana: un lobo gigante de pelaje plateado y ojos dorados. Era Fenrir, el último descendiente de los antiguos lobos divinos.

—Muchos han venido —gruñó el lobo, su voz resonando en la caverna—. Todos han caído. ¿Qué te hace diferente, pequeño humano?

Erik no desenvainó su hacha. No adoptó postura de combate. Simplemente se arrodilló y habló con honestidad:

—Vengo no por gloria, ni por riquezas, ni por poder. Vengo porque mi pueblo muere de frío y hambre. Si debo morir aquí para que ellos vivan, que así sea. Pero si existe alguna esperanza...

El lobo observó largamente al joven vikingo. Luego, lentamente, apartó su enorme cuerpo, revelando una espada clavada en un pedestal de hielo. La hoja brillaba con un resplandor plateado, y en su empuñadura de madera de fresno tallada se veía la figura de un lobo aullando a la luna.

—Toma la Espada del Lobo Gris —dijo Fenrir—. Pero recuerda: su poder es un don y una carga. Cada vez que la uses para el bien, un poco de tu vida fluirá hacia ella. Úsala sabiamente.

Erik tomó la espada con ambas manos. Al hacerlo, sintió un escalofrío que recorrió su espalda, como si un hilo invisible hubiera sido tejido entre su alma y el acero.

El regreso fue más rápido. Cuando Erik llegó a su aldea, llevaba tres días sin comer y sus manos estaban congeladas, pero la espada brillaba con fuerza renovada. Se dirigió al centro del poblado, donde un antiguo monolito marcaba el corazón del territorio del clan.

—¡Pueblo del Lobo Gris! —gritó, y su voz resonó con una fuerza que no era solo suya—. ¡La primavera regresa!

Con un movimiento fluido, clavó la espada en el monolito. Un resplandor plateado explotó desde la hoja, extendiéndose en ondas por toda la tierra. El hielo comenzó a agrietarse, los ríos descongelaron sus aguas, y brotes verdes emergieron de la tierra que llevaba años muerta.

El clan celebró durante tres días y tres noches. Pero Erik notó algo diferente en sí mismo: su cabello, antes oscuro como la noche, ahora tenía mechones plateados. Su rostro, aunque joven, portaba líneas de cansancio que no estaban allí antes.

Sigrid se acercó a él mientras todos dormían.

—El precio ha comenzado a cobrarse —dijo la anciana—. Cada gran acto de poder tiene su costo.

—Lo sé —respondió Erik, mirando la espada que ahora llevaba siempre consigo—. Pero mi pueblo vive. Eso es suficiente.

Los años pasaron, y Erik se convirtió en el jarl más respetado del norte. Con la Espada del Lobo Gris, derrotó a piratas que amenazaban sus costas, negoció la paz con clanes enemigos, y guió a su pueblo a través de hambrunas y guerras. Cada vez que usaba la espada para el bien, su cabello se volvía más plateado, su rostro más curtido, su cuerpo más cansado.

A los treinta años, parecía tener cincuenta. A los cuarenta, parecía un anciano. Pero nunca dudó, nunca lamentó su elección.

En su lecho de muerte, rodeado por su familia y sus guerreros, Erik llamó a su nieto, un niño de ojos azules como los suyos.

—La espada te espera —susurró—. Pero recuerda: el verdadero poder no está en el acero, sino en el corazón que lo empuña. Usa este don sabiamente, y cuando llegue tu hora, pásala a quien sea digno.

Cuando Erik exhaló su último aliento, la Espada del Lobo Gris brilló una vez más, y en el cielo nocturno, los aldeanos juraron ver la forma de un lobo plateado aullando junto a la luna.

Así terminó la historia de Erik el Altruista, el jarl que dio su vida por su pueblo. Pero la leyenda de la Espada del Lobo Gris continuó, pasando de generación en generación, esperando siempre a quien tuviera el corazón puro necesario para blandirla.

Porque en el norte, donde el frío nunca muere del todo, siempre habrá necesidad de aquellos dispuestos a calentar el mundo con su propia luz.

---

FIN
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@corbat-tech/coco",
"version": "1.5.0",
"version": "1.6.0",
"description": "Autonomous Coding Agent with Self-Review, Quality Convergence, and Production-Ready Output",
"type": "module",
"main": "dist/index.js",
Expand Down Expand Up @@ -85,6 +85,7 @@
"glob": "^13.0.1",
"highlight.js": "^11.11.1",
"json5": "^2.2.3",
"log-update": "^7.1.0",
"marked": "^15.0.0",
"marked-terminal": "^7.0.0",
"minimatch": "^10.1.2",
Expand Down
57 changes: 57 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading