warp viz redesign — design spec
warp viz redesign — design spec
Section titled “warp viz redesign — design spec”Look it up. The build spec for the redesigned
/warppage (bob warp viz). The committed reference design is warp-viz-mock.html — open it in a browser, switch the mock state bar (live / needs you / stale / no run), and resize to 390 wide for the phone layout. The exploration canvas it came from is the “Warp Viz Redesign” artifact (dark, filled cards); where the two differ, the mock and this spec win, because they follow the bob viz design checklist.
The page today opens on the phase graph, with the session facts in a tabbed pane beside it. The operator watches runs from across the room and from a phone, with 20/200 acuity. The questions he asks the page, in order:
- Does it need me?
- What is it doing right now, and is that normal?
- How far along is it?
- What just happened?
- Details: plan, commits, tree, CI, issues.
The redesign puts those answers top to bottom in that order, in large type, and moves the full state graph one click down.
Who and how big
Section titled “Who and how big”- Primary reader: the operator — 20/200 acuity. Body text is the
large token scale (
--text-base, 24px), never--text-dense-*. The current phase is--text-3xl. Nothing is smaller than--text-xs. - Text size control:
A−/A+in the header step a page-local multiplier--warp-scalefrom 0.75 to 1.5 in steps of 0.125 (default 1). Every size and space on the page iscalc(var(--token) * var(--warp-scale)), so one control scales type, spacing, targets and bars together. No px literal in the stylesheet. - Targets: every control is at least
--space-2xl(48px × scale) tall.
Page order
Section titled “Page order”| # | Region | Shown when | Collapsible | Cycles |
|---|---|---|---|---|
| 0 | Header | always | — | — |
| 1 | Needs you | at least one ask | yes | asks |
| 2 | Run (the “now” block) | always | yes | sessions |
| 3 | Where it is (phase map) | a run is active | no | — |
| 4 | Acceptance · Time by phase · Activity | a run is active | no | — |
| 5 | Context tabs | a run is active | no | — |
| 6 | Sources line | always | — | — |
Regions 1 and 2 are <details>/<summary> drawn by renderSection in
scripts/dashboard/bob-controls.js (checklist: Page controls). Collapsed, the
summary still says what the region holds (see each region below). Open/closed
state persists per viewer under warp-viz-view/1, every storage call in
try/catch.
The cycle control (‹ 1/3 › inside a summary) is new. Build it once in
bob-controls.js next to renderSection, never inline in the page:
two <button type="button"> with aria-labels, a position read-out in
--font-mono, wrap-around, and clicks that do not toggle the <details>
(stop propagation). Arrow keys on a focused cycle button step it.
0. Header
Section titled “0. Header”<project> · live badge · updated Ns ago · spacer · A− A+ ·
Copy attach · Theme.
- Live badge:
● livein--state-active;● stalein--state-bad(st.stale);idlein--text-mutedwhen no active session. Always a word, never the dot alone. Copy attachcopiesst.host.attach; hidden when there is none.- Title:
(!)prefix and favicon swap whilest.attention.waiting— keep the #1586 behaviour unchanged. - Removed from the header: the session
<select>(replaced by the Run cycle), thekindselect,view: flat/iso(moves into the full-graph view),notify(keep the behaviour, move it to the Needs-you summary as a smallNotify metoggle when the Notification API is available).
1. Needs you
Section titled “1. Needs you”Summary (collapsed and open): N need you in --state-bad · the current
ask’s kind and short line (ellipsis, full text in title) · cycle.
Open body: when line (muted) · the question as a heading (--text-xl) · the
detail (muted, max ~38em) · actions.
Ask list, in this order:
- The run’s own pending decision:
st.attentionwhenwaiting— kind from the attention reason (budget_exceeded,continue?, a decision), question fromreason, link toattention.issue. - The project’s open asks:
GET /control/asks.json?project=<name>(bob-control-asks/1, already ordered by priority then age).
Actions — the page stays read-only:
Answer in Control→/control?ask=<owner/repo#N>(the existing ask screen, #3820), primary.Copy attachfor the run’s own decision.- No answer buttons on
/warpitself. (The canvas showed option buttons; they are deferred until Control’s ask screen exposes an answer endpoint.)
If asks.json is available: false, the region still renders the run’s own
ask and the Sources line names asks as not read. It never says “nothing needs
you” while a source could not be read.
2. Run
Section titled “2. Run”Summary: Run · state word (running / paused / stale, coloured active
or bad) · phase label bold · session name · chunk i of n · cycle.
Cycle: the sessions from /warp/sessions.json (the #1587 scanner). Stepping
navigates ?root=<worktree> like today’s switcher. With one session the cycle
shows 1/1 with both buttons disabled.
Open body, two columns that wrap:
- Main —
Now· phase label (--text-3xl,--state-active, or--state-badwhen stale) · time in phase ·usually a–b· stale line when stale · issue link + title (--text-lg) · chunk segments · facts row (Chunk i of n·Requirement j of m·Running <age>) · muted row (host · branch). - Vitals
<dl>, 2×2: Commits · Tokens used (percent of budget, or raw count when no budget) · CI (✓ pass/✗ failwith the word /not measured) · Retries.
Chunk segments: one per chunk; done = --text fill, current =
--state-active, to come = hairline outline. role="img" with
aria-label="chunk i of n". The words under it carry the same fact.
No run: the summary reads no active run; the body says when the last run
ended with a link to its session report, and the command to start one.
Regions 3–5 are hidden.
3. Where it is
Section titled “3. Where it is”The happy path as three groups, left to right, wrapping:
- Set up (once): preflight · discover · plan · chunk
- Chunk loop (
i of n): code · docs · test · commit · drift · report - Finish (per requirement): req done · qa · merge · promote
Each step: name + time spent this run (--font-mono, --text-sm).
Done steps: ✓ name in ink. Current: ● name, --state-active, thick
underline. To come: --text-dim, —.
Side trips (blocked, budget_exceeded, awaiting_continue, aborted,
prerequisites) are not drawn unless current: then the current group gains
that step after the step it left, in --state-bad, with its word.
Full state graph (section head button) opens today’s SVG graph — flat and
iso views, tooltips (#1740), loop counts — in a full-width section below the
tabs (or a <dialog>). The graph code moves, it does not change.
Group membership is derived from the engine phases, not hard-coded in the
page: add a group field (setup / loop / finish / side) and a short
label to PHASE_META and serve it on /warp/graph.json with the topology.
4. Acceptance · Time by phase · Activity
Section titled “4. Acceptance · Time by phase · Activity”Two columns that wrap (left: Acceptance over Time by phase; right: Activity).
- Acceptance —
/warp/acs.json, unchanged source. Head carriesdone / total.☑rows in muted ink,☐rows in full ink. Hidden when no req or no checkboxes, as today. - Time by phase — from the session history (today’s durations table). The testing row is split by check (#4449): its longest four checks, from the engine’s
check_durations.by_check(this run’s time per check), sit indented under it on the same scale, so a long testing phase shows which check took the time. Bars in--text; the current phase’s bar in--state-active. Top six phases by time, longest first. - Activity — one newest-first list merging phase transitions
(
st.history), commits (/warp/gitlog.json), chunk starts, reports filed and loop-backs. Each row: time (--font-mono, muted) · kind word · text. Kind words:phase,chunk,commit,report,retry, plus the current phase name for the live row. Onlyretry(--state-bad) and the live row (--state-active) are coloured. Show 8, fold the rest with the bob-controls fold (FOLD_FIRST/FOLD_STEP).
5. Context tabs
Section titled “5. Context tabs”Plan #N (only when flightplan-scoped) · Commits · Tree · CI ·
Issues. These are the existing PANES rows — flightplan, gitlog, tree, ci,
feed — with the same endpoints, polling and #1604 error handling.
The warp pane is gone: its sections are regions 2–4 now. Selected tab persists in
warp-viz-view/1. Real tablist semantics: role="tablist"/tab/tabpanel,
aria-selected, arrow keys move between tabs.
The draggable/collapsible utility pane and the 75/25 split are retired; the page is one column that wraps.
6. Sources line
Section titled “6. Sources line”Every source read. or Not read: <source> — <reason>. for each of
asks, acs, ci, flightplan, gitlog, issues that failed (checklist: Honesty).
Includes the #1968 “server can no longer run gh” notice.
Data map
Section titled “Data map”| On screen | Source | Exists today? |
|---|---|---|
| Live / stale / idle | st.active, st.stale, st.stale_cause (SSE /warp/events) |
yes |
| Phase label | st.display_phase ∥ st.phase, label from phase_meta |
label: new (PHASE_META.label) |
| Time in phase | last st.history entry’s timestamp → now |
yes (derive) |
usually a–b |
p25–p75 of this phase’s duration across this project’s recent sessions | new — omit the phrase when fewer than 3 samples; never invent it |
| Issue + title | workLabel(st), title via acs.json / issues |
yes |
| Chunk i of n | st.chunk.index + 1, st.chunk.total |
yes |
| Requirement j of m | flightplan items done/total (/warp/flightplan.json) or scope (st.scope) |
yes (derive); hide when neither |
| Running age | first st.history timestamp → now |
yes (derive) |
| Host, attach | st.host.label, st.host.kind, st.host.attach |
yes |
| Branch | st.branch |
yes |
| Commits | st.metrics.commits |
yes |
| Tokens | st.token_usage (+ .budget.remaining_pct) |
yes |
| CI | current branch’s newest run in /warp/ci.json |
yes |
| Retries | count of loop-back edges traversed (today’s Loops section) | yes |
| Phase groups | /warp/graph.json + PHASE_META.group |
group: new |
| Per-phase time | session history (today’s durations) | yes |
| Asks | st.attention + /control/asks.json?project= |
yes (cross-server fetch: see below) |
| Ask time-out | decision-timeout policy for the pending decision | new — omit the clause when not exposed |
| Sessions to cycle | /warp/sessions.json |
yes |
| Working now (workflows, their phases and agents, background subagents) | /warp/activity.json (bob-warp-activity/1: the project’s Claude Code session folders, #4394) |
yes |
Building <items> in a workflow (N agents) |
/warp/activity.json building, shown in awaiting_continue / discovering |
yes |
Idle between items since HH:MM |
/warp/activity.json idle (over 3 min in those phases with nothing running or just ended, counted from the latest of entering them, the newest workflow end and the newest background agent stop) |
yes |
/control/asks.json is served by the Control server, not the per-project
dashboard. Either proxy it through the project server as
/warp/asks.json (preferred: one origin, ?root=-aware, same #1604 error
path) or fetch it cross-origin from the fleet front door. Decide in the
requirement.
Colour
Section titled “Colour”Checklist rules, applied:
- Only
--state-active(in flight: live badge, current phase, current chunk, current bar, live activity row) and--state-bad(needs you, stale, retry, failed CI, a side-trip step) colour anything. - Done reads in plain ink with
✓; to come reads in--text-dim. Every coloured value is also a word or glyph. - No card fills, no borders around regions or rows. Hairline rules only under section heads, the tab list and activity rows. Controls have borders.
- Both themes. Dark and light state pairs validated with the dataviz
validator, as
/bobis.
Phone (390 wide)
Section titled “Phone (390 wide)”Same page, same order. Differences:
- Phase label drops to
--text-2xl. - Where it is: only the Chunk loop group; done steps fold to
✓ n done. - Vitals stay 2×2.
- Tabs wrap. Heads wrap. 16px side gutter. No horizontal scroll.
Accessibility
Section titled “Accessibility”<details>/<summary>regions; cycle buttons havearia-labels; disclosure state is native.- Visible focus ring (3px
--state-active) on every control and link. - Links underlined; never colour alone.
- Chunk segments and bars are
role="img"with a label, oraria-hiddenbeside an equivalent text fact. - The
(!)title prefix and favicon swap stay as the out-of-tab signal.
Keep, move, drop
Section titled “Keep, move, drop”| Today | Redesign |
|---|---|
| Phase graph as the main surface (flat/iso) | Behind Full state graph; unchanged code |
warp utility tab (meta, burn, ACs, durations, loops) |
Regions 2–4 |
This project elsewhere fleet links |
Dropped from /warp — bob viz / BoB Control own the fleet |
| flightplan · feed · gitlog · tree · ci tabs | Context tabs (feed renamed Issues) |
Session <select> + all sessions link |
Run cycle; all sessions link moves into the Run summary |
| Attention banner | Needs-you region (first ask) |
| Dispatch drawer, terminal drawer | Unchanged, below the tabs — out of scope here |
kind select (decompose / do machine screens) |
Unchanged behaviour; machine screens render in place of regions 3–5 |
| Utility pane drag-resize / collapse | Retired |
Checklist conformance
Section titled “Checklist conformance”Copy the bob viz design checklist into the requirement. One box does not hold as written and needs a decision issue linked from the requirement:
- Type and spacing — “sizes come from
--text-dense-*”./warpuses the large scale (--text-*) times--warp-scale, for the operator’s acuity. Proposed rewording: a page uses one scale fromdesign-tokens.js;/bobuses dense,/warpuses large; a page-local multiplier is allowed when it multiplies tokens and never introduces a px literal.
Tests to expect
Section titled “Tests to expect”tests/test-warp-viz-*.shassertions on the utility pane’s 75/25 layout, drag-resize and thewarptab go away or move; flightplan tab visibility (#1644) and the stale treatment (test-warp-viz-stale.sh) carry over.- New: regions render in the order above; asks cycle and wrap; the cycle does
not toggle its
<details>; open state and tab persist underwarp-viz-view/1;--warp-scaleclamps at 0.75 / 1.5; no px literal in the page stylesheet; the Sources line names each unread source; no “nothing needs you” while asks were not read. - Screenshots in both themes at 1440 and 390 via
node scripts/dashboard/bob-viz-shots.js(add/warpto it).
Suggested chunks
Section titled “Suggested chunks”PHASE_META.group+.labelon/warp/graph.json; cycle control inbob-controls.jswith tests.- Page shell: header,
--warp-scale, Run region (sessions cycle), phase map, graph moved behind its button; retire the utility pane. - Acceptance / Time / Activity columns; context tabs on the existing PANES.
- Needs-you region:
/warp/asks.jsonproxy, ask cycle, Sources line. - Phone layout, both themes, screenshots, checklist decision issue.