🖥️

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_events rows (canonical) + Redis pubsub run:{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 from since, 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

SeverityColorIcon
infogray
successgreen
warningyellow
errorred
debugblue🐞

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-frequency command_output lines for rendering (≤ 30 fps).
  • Reconnect with Last-Event-ID (sent automatically by URLSession SSE consumer).
  • Heartbeat every 15 s (:ping).
  • On reconnect, server replays from Last-Event-ID + 1.

8. Empty / pending states

  • Run is queued: show Waiting 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 calls POST /api/runs/{run}/resume.
  • Run is paused: banner with Resume action.
  • Run is failed: banner with failed_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_updated event.

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.