Skip to content

Web mission control

The daemon embeds a React dashboard (Astro + React) and serves it at http://localhost:8765 alongside the REST API — no separate server required.

Terminal window
warden daemon
open http://localhost:8765

The warden web dashboard on its Cockpit home: a routed mission-control shell with a Fleet summary header (totals · busy · waiting · errored · pressure) above the agent grid, grouped by directory, with Pipelines, Metrics, Archive, and Others tabs alongside.

The dashboard is a URL-routed mission-control shell. Tabs are real URLs (History-API routing — back/forward, refresh, and shareable deep links all work), not client-only state. Each surface has its own address:

RouteTabWhat’s there
/cockpitCockpitThe home view (/ redirects here). A slim Fleet header — totals · busy · waiting · errored, pressure, per-directory counts — above the full agent grid.
/pipelinesPipelinesPipeline list + live DAG / per-job drawer.
/metrics📊 MetricsPer-agent and fleet-wide charts — see below.
/archive🗄 ArchiveEnded sessions with since/type filters.
/othersOthersThe former Overview, renamed to a catch-all (sits last): Needs you (attention queue), File conflicts, and Recent activity. New/not-yet-homed widgets land here first.
/agent/<id><id>A pinned agent’s live terminal (one closeable tab per pinned agent).
/tui(top-bar ▢ TUI button)The full warden tui, streamed full-screen — not a tab; launched from the highlighted top-bar button and exited with Ctrl+Q. See Full-screen TUI.

/ redirects to /cockpit, so there is a single canonical home URL. Deep-linking and refresh work because the daemon serves the SPA for any non-API path.

In the Cockpit you can group the fleet by directory, task type, status, tag, or agent (the AI backend — claude/aider/…) to keep a large fleet legible:

The Cockpit grouped by task type: agents collected under collapsible analysis and development sections, each with a per-group count.

Each agent card also shows the brand logo of the backend driving it in the tile header, so you can spot claude vs aider agents at a glance. An agent with no recorded backend (anything spawned before backend selection shipped) shows as claude; an unrecognized backend falls back to a small monochrome lettermark.

FeatureDescription
URL routingReal History-API routes (above) — back/forward, refresh, middle-click-open-in-new-tab, and shareable deep links all work.
Cockpit homeThe default view: a Fleet summary header above the canonical agent grid. The old Quick spawn widget and duplicate All agents mini-grid were removed.
Live fleet over SSENo manual refresh; coloured busy/idle badges (Starting, Busy, Needs input, Idle, Done, Error, Orphaned) + each agent’s subject.
Attention queueIn the Others tab: surfaces agents in waiting_for_input/errored/orphaned, with one-click approval buttons.
Metrics viewA dedicated /metrics tab — see Metrics view.
Context & Messages overlayOpened from a small 🗒 header button as a dismissible overlay (Esc closes); it’s no longer a tab.
Interactive terminalPin an agent to get a live tmux attach bridged to the browser over a WebSocket (xterm.js) — type into the agent and watch it respond. Mobile-friendly: swipe to scroll back through history (the swipe drives tmux/the agent’s scrollback the same way a mouse wheel does), plus a sticky on-screen key bar (Esc, Tab, Ctrl-C, ↑/↓, jump-to-bottom) for the keys a phone keyboard lacks. The layout tracks the visible viewport, so the bottom tab nav and the key bar stay put above the soft keyboard.
Full-screen TUIThe whole warden tui in the browser, launched from the top bar — see Full-screen TUI.
Create agent+ New agent prompt box with a directory picker (live prefix autocomplete) and a Supervised checkbox.
Terminate with git guardSurfaces a 409 → Force + optional hard-delete when there’s uncommitted/unpushed work.
Digest panelView an agent’s completion digest in the browser.
Browser notificationsOpt-in desktop notification when an agent enters waiting_for_input (gated to hidden tabs).
Group the fleetIn the Cockpit, group agents by directory, task type, status, tag, or agent (the backend driving each session) to keep a large fleet legible.
Backend logo on cardsEach agent card’s header shows the brand mark of its backend (claude/aider/…); empty/legacy ⇒ claude, unknown backends ⇒ a monochrome lettermark.
Batch operationsSelect multiple agents and act on them at once (e.g. terminate / delete).
Search & archiveFull-text search across the fleet; browse archived (closed) agents from the Archive tab.
Theme toggleLight / dark / system theming.
Keyboard shortcutsGlobal shortcuts for navigation and actions (19 jump to a tab, j/k next/previous, Esc close), with a ? help overlay listing them.

The web dashboard also has a Pipelines tab: it lists pipelines, shows a selected pipeline’s jobs as status-colored cards with dependency chips, and a per-job drawer with the prompt/handoff/output, a Cancel (pipeline) / Retry (job) control, and an Open terminal link to a running job’s session. (Creating / editing pipelines in the browser is not yet available — use warden pipeline create -f.)

The highlighted ▢ TUI button in the top bar opens the full terminal cockpit — the literal warden tui (/tui) — streamed full-screen into the browser, so you can drive the entire fleet from a laptop exactly as you do locally. It isn’t a tab: it takes the whole viewport, edge-to-edge and non-scrollable, with none of the dashboard chrome, and you exit with Ctrl+Q from any pane (which lands you back on the home view).

It isn’t a reimplementation. The daemon builds a shared three-pane tmux cockpit (agent list pane + a master shell/REPL pane + a detail pane that opens the selected agent) and bridges it to an xterm.js terminal over the same WebSocket PTY that powers a per-agent attach. Because it’s the real session:

  • Every TUI keybinding worksenter open · n new · o dir · s send · a attach · i info · x kill · r refresh · ? help · j/k, g/G, Alt+Arrow to move between panes, and the rest — they reach the cockpit unchanged. (Ctrl+Q is the one chord held back by the browser, to exit.)
  • The shells are real shells. The master pane runs your $SHELL with your rc files, so tab-completion, autosuggestions, history, and fzf all behave as they do locally — nothing is emulated, only piped.
  • q exits the TUI to the dashboard. Pressing q in the top-left list pane tears the whole cockpit down and returns you to the home view — exactly as it quits the cockpit locally. It’s pane-scoped: q only exits from the list pane (where it means “quit”); in the master shell or the agent detail pane a literal q types normally. Ctrl+Q still exits from any pane. Re-open the TUI from the ▢ TUI button — the cockpit is rebuilt fresh.
  • The agent in the detail pane is the real agent (e.g. Claude Code), with its full interactive UI. Shift+Enter is mapped to its newline.
  • Shared across clients. There’s one web cockpit; the most-recently-active client drives the window size.
  • Self-healing. The cockpit lives in the tmux server, not the daemon, so it outlives daemon restarts and reinstalls. Before reusing an existing session the daemon checks it still has the right shape — three panes, with the top-left list pane genuinely running warden tui --pane=list — and silently kills and rebuilds a wedged one. You always land on a healthy cockpit, no manual tmux kill-session required. To force a fresh rebuild yourself, run warden tui --rebuild-web-cockpit (then reload the /tui view).

It’s built lazily on first attach and reused after that. While the terminal has focus the dashboard’s global single-key shortcuts stay dormant (keys flow to the TUI). The one place a browser can’t match a local terminal is a handful of browser-reserved chords (Ctrl+T/Ctrl+W/Ctrl+N) — installing the dashboard as a PWA reclaims most of them. This is a desktop/laptop surface — the three-pane cockpit wants width, so there’s no mobile key bar; on a phone, pin a single agent (above) instead.

The Metrics tab, upper half: CPU per agent beside Total CPU, Memory per agent beside Total memory, and a Cost-per-agent card (total · today · this week, with per-agent input/output token counts).

The Metrics tab, lower half: Number of agents, the Tokens-saved trend with a 24h/48h/7d/30d/All window picker and a cumulative line, a Savings-by-feature stacked area (compact / llm_offload / check / commit), and the Live-footprint resource chart.

The Metrics tab (/metrics) is a responsive grid of self-contained uPlot chart cards — two columns on wide screens (each per-agent chart sits beside its fleet-wide total), collapsing to a single column on phones:

CardWhat it shows
CPU per agentOne line series per live agent, cpu_percent over time (from the metrics history store).
Total CPUA single fleet-wide line: cpu_percent summed across all agents per sample. Sits beside CPU per agent.
Memory per agentOne line series per agent, resident memory in GiB over time.
Total memoryA single fleet-wide line: resident memory (GiB) summed across all agents. Sits beside Memory per agent.
Cost per agentA total · today · this week dollar headline over a sorted per-agent cost bar chart — the top-N costliest agents (rest folded into an others row), each bar’s measured $ cost with its input/output token counts on hover — from the cost-governance rollup (warden spend).
Context per agentOne line series per agent of its live context-window fill over time, with the legend dot coloured by ok/warning/critical. This series is accumulated client-side (a ring buffer over the live SSE feed) — it survives tab switches but starts fresh on a full page reload (a persisted history is a tracked daemon follow-up).
Number of agentsFleet size (agent_count) over time.
Tokens savedThe saved-tokens trend (from the savings ledger) with a window picker24h/48h bucket by hour, 7d/30d/All by day — so a fresh ledger still plots a real curve instead of a single point. A filled area shows tokens saved per bucket against a left axis, and a dashed line shows the running cumulative against the right axis, plus a headline saved-tokens / dollars figure. The trend is zero-filled, so idle intervals read as real zeros rather than gaps. If the ledger is disabled (savings: false) the card shows a “set savings: true” hint instead of an empty chart.
Savings by featureA per-feature stacked-area breakdown of the same trend — which lifecycle feature (llm_offload, commit, check, compact) drove the savings — over the selected window.
Live footprintThe former Resources panel — live per-agent + system resource charts.
Terminal window
make release # 1. builds the Astro UI (web/), 2. embeds it via go:embed, 3. builds bin/warden
warden daemon # start the daemon as usual

Then open http://localhost:8765 in a browser.

The UI is baked into the binary at build time. After changing anything under web/, rebuild (make release, or make ui for the frontend only) and restart the daemon. For live UI iteration, run warden daemon and make ui-dev in parallel and open http://localhost:4321 — the Astro dev server proxies /api/* (the whole REST surface, incl. the /api/v1/sessions/{id}/attach and /api/v1/cockpit/attach WebSockets and /api/v1/events/stream SSE) and /healthz to :8765, so SSE and all REST calls work without CORS configuration.