5.4 KiB
Mirage Dashboard – User Stories
The dashboard is the visual control plane for mirage. The goal is a
desktop-class experience inspired by Docker Desktop (resource cards,
prominent status, persistent left rail, command bar) and the iOS
Simulator (single hero device card, scoped device-detail toolbar, plays
of subtle motion when state changes).
Every story has acceptance criteria. The e2e/dashboard.spec.ts Playwright
suite covers each one end-to-end via the same daemon binary the user runs.
Personas
- DevOps Diego — runs a long-lived
mirage daemonand uses the dashboard to inspect profiles and clean up stale sessions. - Researcher Rita — wants to launch a one-off session, attach to a command, see its output stream, and tear it down.
- Plugin author Pat — needs to see what emulator backends are installed on this host and which plugins they expose.
1. Overview at a glance (Diego)
As a dashboard user I want the first screen to show me how many profiles and sessions exist, the health of each running session, and where on disk mirage stores its data so that I can confirm the daemon is healthy in under three seconds.
Acceptance criteria
- The route
/renders a 4-card metric strip:Profiles,Sessions,Healthy,Execs running(last number aggregates across sessions). - Every metric card is keyboard-focusable and links to its detail page.
- A
Storagepanel lists the five XDG-derived paths in a copy-friendly table. - A
Systempanel shows the daemon version + the list of detected emulator backends (each with aninstalled/not installedbadge). - The page polls
/api/sessionsevery 3 s and updates without a full reload.
2. Browse and create profiles (Pat)
As a plugin author I want to pick the emulator backend from a dropdown (showing which are installed locally) and choose plugins from a multi-select so that I never have to remember which emulator strings the daemon accepts.
Acceptance criteria
/profileslists every profile in a sortable table with: name, emulator badge, nodes, GPUs/node, exec mode, description.- A primary
New profile…button opens a modal with:- Name field (required, lowercased automatically).
- Emulator dropdown populated from
/api/emulators(shows installed badge per entry; defaults to the daemon'sdefault_emulator). - Nodes / GPUs per node number steppers.
- Exec mode segmented control (
Functional/Clocked). - Plugins multi-select fed by the chosen emulator's
available_pluginslist. - Description textarea.
- The modal validates the name, disables submit while inflight, surfaces daemon errors inline, and closes on success while triggering a table refresh.
- Each profile row exposes a kebab menu with
Duplicate,Edit JSON,Delete(Delete asks for confirmation in a modal, not aconfirm()).
3. Launch a session and watch it boot (Rita)
As a researcher I want to start a session against a profile and
watch the health badge transition from pending → starting → ready
so that I know exactly when I can attach an exec.
Acceptance criteria
/sessionsshows every session as a card (iOS-simulator-style), not just a row: profile name, ID, age, health badge, exec count.- Cards expose
Open,Stop, andCopy ID. - A persistent toolbar carries
New session…, a profile filter dropdown, and aRefreshbutton. - Starting a session opens a modal pre-filled with the most-recently used profile. While the session is starting the card shows an animated badge and a progress shimmer.
- The status badge derives from
health.stateplushealth.healthy(pending/starting/ready/unhealthy/terminal).
4. Drive an exec with live output (Rita)
As a researcher I want to type a shell command, hit run, and see streamed output in a real terminal pane (xterm) so that I can iterate on a debug command without leaving the browser.
Acceptance criteria
/sessions/:idshows session metadata in a hero card, then a two-column layout: exec list on the left, attached terminal on the right.- The terminal is an
xterm.jsinstance bound to the daemon/attachWebSocket. Resize the column → terminal resizes. - A command palette at the bottom: command input,
+env-var chip input (KEY=VALUE),keepcheckbox,Runbutton. Submitting selects the new exec automatically. - Each exec row shows: id, started timestamp, runtime, exit code (red
if non-zero, green if 0, neutral while running), kebab menu (
Attach,Send SIGINT,Send SIGKILL,Remove). - The kebab is keyboard-navigable.
5. Trust the dashboard's status (Diego)
As an operator I want transient daemon failures (network blip, 500 from the API) to show as a toast that I can dismiss so that I don't lose state when one request fails.
Acceptance criteria
- Every page registers a global toast handler. API errors push a toast with the HTTP status + message; toasts auto-dismiss after 6 s.
- Toasts stack bottom-right, are keyboard-dismissable (
Esc). - A success toast appears after profile create, session create, session destroy, and exec remove.
6. Keyboard-first navigation (everyone)
g o,g p,g snavigate to Overview / Profiles / Sessions.Cmd/Ctrl-Kopens a command palette (out of scope for this PR, but the layout reserves the slot in the header).- Sidebar links are reachable via
Taband respect:focus-visible.