12-Console-UI
🖥️
The console is the soul of the product. It is a live, structured log of every event in a run, designed for mobile-first reading.
1. Data source
- Backed by
agent_eventsrows (canonical) + Redis pubsubrun:{run_id}:events(live).
- Endpoint:
GET /api/runs/{run}/events?since={last_event_id}(paged, backfill).
- Stream:
GET /api/runs/{run}/events/stream(SSE; replays fromsince, then tails Redis).
2. Event row shape (UI contract)
{
"id": 91823,
"runId": 148,
"projectId": 7,
"eventType": "file_updated",
"title": "Updated app/Models/Invoice.php",
"message": "Added belongsTo(Customer::class) relationship",
"severity": "success",
"createdAt": "2026-05-11T10:14:22Z",
"payload": {
"path": "app/Models/Invoice.php",
"action": "update",
"beforeHash": "sha256:…",
"afterHash": "sha256:…",
"diffPreview": "@@ -10,3 +10,6 @@\n …",
"fileChangeUrl": "/api/runs/148/files/4421"
}
}3. Top-of-console run header
Each run view shows:
- live status pill (color-coded)
- selected agent (icon + name)
- selected model
- current step (
current_step)
- timeline scrubber (progress bar with key event markers)
- elapsed timer
- Git status badge (branch name + dirty/clean)
- RAG status (ON/OFF + last retrieval latency)
- test status (passed/failed counters, last test event)
- pause / resume / cancel buttons
4. Event row presentation
| Severity | Color | Icon |
|---|---|---|
| info | gray | • |
| success | green | ✓ |
| warning | yellow | ⚠ |
| error | red | ✕ |
| debug | blue | 🐞 |
File-related events show an inline mini-diff (first 6 changed lines), tappable to open the full diff viewer.
Command events show the command (truncated), exit code badge, and a chevron to expand stdout/stderr preview (paged from S3).
RAG events show the query and a count of chunks returned; expandable to a list of chunks (path, source_type, score, snippet).
5. Filters
Top bar exposes:
- Severity: info / success / warning / error / debug (multi-select).
- Event type: chip-row filter (
file_*,command_*,git_*,rag_*,docs_*,test_*,paused/resumed,final_summary).
- Path: text filter; matches on
payload.path.
- Time range: from / to.
Filters are client-side over the loaded buffer; for older history a server-side query ?event_types=…&severity=…&path=… is supported.
6. Actions
- Copy log (markdown or plain text), respecting current filters.
- Download log (NDJSON or markdown, signed S3 link for full export including stdout/stderr blobs).
- Collapse / expand all.
- Show JSON payload for any event (debug drawer).
- Jump to: changed file, command, RAG chunk, snapshot.
- Pin event (client-side bookmark for review).
7. Streaming behavior
- SSE delivers one event per
data:line. Client coalesces high-frequencycommand_outputlines for rendering (≤ 30 fps).
- Reconnect with
Last-Event-ID(sent automatically byURLSessionSSE consumer).
- Heartbeat every 15 s (
:ping).
- On reconnect, server replays from
Last-Event-ID + 1.
8. Empty / pending states
- Run is
queued: showWaiting for worker…with a spinner and last queue depth (if available from Horizon metrics).
- Run is
waiting_for_user: prominent banner with the question and input controls. Sending a response callsPOST /api/runs/{run}/resume.
- Run is
paused: banner with Resume action.
- Run is
failed: banner withfailed_reason, Retry action, and Restore snapshot quick actions.
9. Linked navigation
The console deep-links into:
- File change detail screen (diff viewer) for any
file_*event.
- Command detail (full stdout/stderr, exit code, duration) for any
command_*event.
- RAG chunk explorer for any
rag_search_*event.
- Snapshot detail / restore screen for any
snapshot_*event.
- Documentation diff viewer for any
docs_updatedevent.
10. Performance budget
- First paint of the console < 300 ms after run open (warm cache).
- New event render p95 < 150 ms from receipt.
- Buffer cap: 5 000 events in memory; older events lazy-loaded on scroll.