Cycles
Design · c59

inventory

flaggedflagged in c69 sweep — shipped but unclosedcreated 2026-08-02· last activity 2026-09-11

Design qdash inventory page to surface agent status and footprint at a glance

Why

Currently designing a new inventory page for qdash (replacing localhost:7878/inventory) following the design site's page-mock workflow. The page needs to give users an immediate sense of what agents are running and their footprint. Exploring both general inventory views and agent-focused perspectives, informed by available data (MCP servers, repos, tools). Design is the process of eliminating noise so the signal cuts through.

Objective

Phase 0: Clarify page purpose, explore available data, and produce a clear design brief with optional wireframe. Understand what's most important to surface and how to make sense of it at a glance.

Phase 2: Execute one or more page mockups on the design site based on Phase 0 insights.

Scope

Design site page mocks only (not implementation in qdash). Explore agents running and their footprint. Consider MCP servers, repos, and tools in context. Compare general inventory view vs agent-focused views. May use bob-wire for exploratory wireframes.

Key Changes

  • Phase 0 complete (2026-08-02): design-brief.md — page purpose (fleet-lens substrate: what exists, is it alive, what's its footprint, what's unmonitored), three-tier data reality from a full qdash data-model audit (live / captured-but-hidden / permanently-NULL), at-a-glance hierarchy (presence → coverage → footprint → risk-as-exception), and three design directions (V1 Roster, V2 Ledger, V3 Footprint) with a recommendation to mock V1 + V2 and fold V3 in as a lens. Mock data to speak the Meridian staged world.
  • Phase 2 complete (2026-08-02): two page mocks built per plan.md, registered in page-registry.ts (group inventory), dev-server smoke-checked (200s, no Vue warnings):
    • /pages/inventory-roster — V1 presence-first: dark canvas, AgentMiniCard grid grouped by user, coverage header (87% · 34/39) with clickable shadow chips, footprint strip, shadow installs as dashed ghost cards inline in their machine's group, search + state filters ("chen" acceptance test passes).
    • /pages/inventory-ledger — V2 dense ledger: coverage/footprint band, four lenses (Agents / Machines / Harnesses / Surface). Agents lens = UxTableList with sorters, posture regression marker ("↓ was Critical" on marcus), "new · 7d" on chen, and the designed expand-row (fingerprint, quota bar with overage pill, cwd-derived repo chips, MCP servers with oauth-pending, recent runs, denied-calls line). Surface lens folds in the V3 general-inventory idea (Models / MCP Servers / Repos / Tools panels). Numbers cross-foot with the roster and the Meridian world.
  • Candidate layer extractions logged (out of c59 scope): footprint strip, coverage stat, shadow/ghost card (AgentMiniCard has no ghost state), posture badge with regression marker, the designed agent expand-row (replaces qdash's INTERIM AgentExpandDetail).
  • Iteration 2 (2026-08-02, from revisions.md — ledger chosen as the direction): two new pages so v1 stays archived, registered and smoke-checked (200s, clean log):
    • /pages/inventory-ledger-v2 (Stacked) — overview as a proportional 39-segment coverage bar (34 neutral / 5 amber shadow segments with hover identity), footprint counts + risk line beneath; all four lenses open as stacked sections with a sticky anchor-pill jump nav.
    • /pages/inventory-ledger-v3 (Composite) — overview as a DataMetric_Base tile row (Coverage 87, At-risk 5, five footprint tiles) with shadow chips in a strip below; no tabs — agents table primary, Machines / Harnesses / Surface as a three-rail band underneath.
  • Iteration 3 (2026-08-02): /pages/inventory-overview-ideas — three overview concepts rendered working on one page for visual comparison: (1) trend-aware tiles with DataMetricSpark sparklines telling the Meridian story (coverage 89→87 dip on chen's Windsurf, day-61 at-risk spike/recovery); (2) the coverage bar regrouped as a clickable 14-machine fleet map with a detail line (chen-mba preselected — could replace the machines table); (3) hybrid — v3's tile row with the proportional 39-segment bar inside the coverage tile.
  • Iteration 4 (2026-08-02, Mark's picks folded back into v2): ledger-v2 overview revised — hybrid's mini coverage tile (compact 39-segment bar) + At-risk tile replace the full-width bar, right side left empty; footprint items keep their small text and gain the grey 90-day sparks + trend captions beneath (idea 1, without the big-tile treatment). Jump nav moved beneath the overview. Sparks are hand-rolled inline SVG (min-max normalized, stroke-only line) — DataMetricSpark needs a baseline/min-max mode + line-only stroke to absorb this (layer candidate).
  • Buildability audit (2026-08-02): buildability.md — ledger-v2 audited element-by-element against qcontrol. ~85% buildable today; a 5-item backend punch list converts the captured-but-unserved rest; only agent pawn-states and trend sparks are genuinely staged (both on qdash's own roadmap: liveness states, IA-doc §8 trend reconstruction).
  • AgentInline extracted to the layer (2026-08-02): new q-nuxt-layer/components/agent/Inline.vue — pixel pawn + bold name + "Vendor / kind / ● status" sub-line for table rows; status ∈ active/idle/stopped/errored (honest qdash vocabulary — idle renders the sleeping body, stopped dims + hollow dot). Required adding a decorations prop to AgentPawn (suppresses floating zzz/binary/alert that would overflow rows). Ledger-v2's lead cell now uses it (page states converted working/needs-input → active) with a status legend in the section header. Documented: _demos/AgentInline.vue + registry entry (AgentPawn entry updated for decorations). Needs NUXT_LOCAL_LAYER=1 dev restart to render (new layer component + new demo glob).
  • Theme-compatible pixel art (2026-08-02, approved plan): new UxPixelArt layer component inlines pawn + pixel-icon SVGs and rewrites their palette hexes to --px-* CSS variables at load time (Illustrator exports untouched — future b-exports drop in unchanged). Handles both art shapes: style-block classes (pawns) and fill attributes (icons), plus the fill-less pupil rects. --px-* roles added to tokens/semantic.mjs (pixelArt export, hex form) and emitted by tokens/build.mjs into tokens.css; light values = art hexes verbatim (zero visual change), dark values = conservative first pass for Mark to tune. AgentPawn body/decor and AgentMiniCard icons now render through it (provider overlay stays <img> — brand marks don't theme). Documented: _demos/UxPixelArt.vue + registry entry, theme-contexts scenario in the AgentPawn demo. Follow-up logged: AgentInputBubble is still hard-coded dark.
  • Iteration 5 (2026-08-03, the primary slot): analysis of the v2 overview against the fleet-lens questions — the band answers coverage (#2) and risk (#4) but never presence (#1, "alive right now"), and "34 of 39 installs" beside "34 monitored" agents leaves the page's noun ambiguous. Four concepts appended to /pages/inventory-overview-ideas as a Round 2 (smoke-checked, 200): (4) presence hero — 34-agent count + state-segmented bar in the coverage bar's visual language (AgentInline vocabulary; 20 active · 10 idle · 2 stopped · 2 errored, per-segment hover for who); (5) presence funnel — 39 installs → 34 monitored → 31 seen 7d → 20 active now, a dormancy step that breaks the unrealistic 34-installs = 34-agents coincidence; (6) shadow-first exception — the five named unmonitored chips with onboard → promoted to the hero, the % demoted to sub-line; (7) recommended composition — hero + funnel sub-line, coverage relabeled "Install coverage" + at-risk demoted into v2's deliberately-empty right side, v2 footprint strip verbatim. Backing roster of 34 cross-foots per-machine monitored counts and harness totals (CC 20 · Codex 6 · Cursor 6 · Gemini 2). Caveat carried from buildability.md: presence states are category C (running/stopped + derivable errored/idle today) — the hero makes that bet prominent by design.
  • Iteration 6 (2026-08-03, Mark's review of Round 2): Idea 7 refined into Idea 7b "Uniform tiles" (7 preserved as-built): the 44/36 hero-vs-secondary size split read as misalignment, so all three tiles share :size=44 and one sub-item rhythm (number → h-4 bar row → text-12 caption; At-risk's caption sits on the bar line). Verbiage: coverage tile relabeled "Visibility - what is monitored" (the do-we-have-eyes-on-it word; plain hyphen), its caption switched to the Agents-legend totals style (swatch dot + bold count: ● 34 monitored · ● 5 shadow); funnel chain moved to a caption beneath the box; secondaries left-aligned (a floor-alignment experiment was tried and reverted). At-risk renumbered fleet-wide 5 → 4 (2 critical + 2 at-risk) on the active pages (ledger-v2 + all overview-ideas tiles + the Idea-1 spark) — the double-5 next to "5 shadow" manufactured a redundancy read; the two are different axes (posture of the monitored vs installs unseen), and 7b's At-risk label now says so: "At-risk - agent posture". Shadow stays amber, not red: red = confirmed bad (critical/errored), amber = unknown/attention — consistent with every c59 shadow surface. Archived pages (roster, ledger v1/v3) keep the old 5 as historical snapshots. Also fixed while reviewing: SparkChartOld.vue's un-scoped polygon, polyline { v-bind(...) } style block leaked document-wide and turned every hand-rolled spark solid black (fill collapsed to the SVG default outside the component); scoped it plus Trend.vue/TrendDirection.vue — gotcha added to memory.
  • Iteration 6 addendum (2026-08-03): layer additions from the round — DataMetric_Base gained a default slot (content renders inside the inline-block root so the label hairline spans it; documented in the demo + registry), and DataMetricValue got line-height: 1.05 on both value and unit (display-numeral leading: the inherited 1.5 reserved ~22px of dead air under 44px values, and the unit's taller line box misaligned tiles with units). 7b also lost its vertical separators and widened to gap-x-20. The finished 7b band was then applied to /pages/inventory-ledger-v2 as its overview (34-agent roster + presence helpers copied over, funnel caption beneath the box, provenance comment updated) — the ledger mock now leads with presence. Both layer changes ride the pending release.
  • Iteration 7 (2026-08-06, the designed expand-row): /pages/inventory-agent-expand — the designed agent expand-row from Mark's designer comp, the deliverable design-brief.md queued when it marked qdash's expand panel INTERIM. A 4-row mini ledger (row cells verbatim from ledger-v2) whose expand card composes: AgentPawn + name header with the AgentInline sub-line scaled up, the agent-detail identity strip (User / Credential / Host / Terminal DataIdentityItems + Organization / Account IDs) with dashed staged pills on the two Tier-3 fields, a deliberately blank Quick Overview (comp annotates "Leave blank, TBD"), a Recent Sessions mini-table, and four agent-scoped Surface panels copied from qcontrol's live /inventoryapp/components/inventory/SurfacePanel.vue is a byte-diffable replica of qdash's components/inventory/SurfacePanel.vue (only pct inlined), kept 1:1 for the eventual layer extraction. Featured row (samir's sparse brand-new install, per the comp) auto-opens on load; priya's row carries 12 tool rows so the Tools panel demos UxShowMore overflow. Cross-foot rule: row Sessions/MCP/Tools counts equal the card's workspace-runs total and panel row counts. Layer gaps logged: UxTableListExpandRow's isOpen prop is dead (shadowed by a local ref — no declarative default-open; the mock simulates a click), and the layer has no github icon (qdash-only), so workspace rows all use folder. Flagged for Mark: posture vocabulary divergence — the comp says "Standard" (qdash's danger_level word) where the c59 ledgers say "Healthy"; the page shows both. Addendum: SurfacePanel gained a compact mode (Mark's ask: no border, no padding, tighter leading, smaller fonts — one type notch down across title/caption/headers/rows; #row now passes compact so consumer cells can adapt their padding/pills). Applied as an identical additive diff to both copies (design replica + qdash's original, default false so qdash pages are untouched) to preserve diffability; the expand card's four Surface panels now render compact, and the Quick Overview / Recent Sessions row was made non-responsive (always [2fr_3fr]) after review.
  • Iteration 7 addendum (2026-08-06, sectioned expand row): Mark's stacked-cards comp executed per expand-row-sections-plan.md — new layer component UxTableListExpandSection (ux/table-list/ExpandSection.vue): a borderless white section card (rounded-12 bg-surface p-6 shadow-lg, no props, default slot) for stacking inside an UxTableListExpandRow #details well; the consumer owns stack spacing (space-y-4) so the well tint shows through the gaps. Close stays the ExpandRow's sticky X (no per-section X). New evaluation page /pages/inventory-agent-expand-v2 — the agent-expand mock rebuilt as three sections (header+identity · Quick Overview/Recent Sessions · Surface), the original single-card page kept untouched for side-by-side comparison; both registered in page-registry.ts. Documented: _demos/UxTableListExpandSection.vue + registry entry (table group). Headless-verified 11/11 (3 borderless 24px-pad cards, 16px tinted gaps, X collapses, compact-panel invariants, Show all 12 toggle, clean console). Flagged for Mark: the ExpandRow X abuts section 1's right edge in the px-8 gutter (dx 0) rather than sitting inside the card padding as the comp draws — same geometry as the single-card page; moving it means touching ExpandRow's right-14, which qdash consumes. Joins the pending layer release (with NavJumpPills, AgentInline, UxShowMore, UxPixelArt, the SurfacePanel-era compact props).
  • Iteration 8 (2026-08-07, v2 refined + shipped to qcontrol): the v2 mock iterated with Mark to its final form — Recent Sessions restyled as a SurfacePanel (compact ranked rows: run id + model + when, status pill + cost, token bar), captions dropped across all panels, row caps at 7, and the header simplified per the comp: pawn + name · Security Score (DataSmile, per-agent score) · Spend · stroke UxButton "View Full Agent Details"; the old identity strip became a Metadata column beside sessions. Two gotchas logged to memory along the way: divide-* containers hijack direct children's border colors (the grey stroke-button bug), and the close affordance moved out of ExpandRow. Close X redesign (layer API): the sticky viewport-anchored X is gone; UxTableListExpandSection now renders a card-anchored X only when an @close listener is attached, and ExpandRow wraps its #details slot in one ExpandSection by default (same chrome as DataTable's old hand-rolled wrapper, now with the X) — a bare prop opts out for sectioned stacks, the details slot scope provides close, and open()/close() are exposed for template refs (the mock's programmatic-click hack retired). DataTable dropped its wrapper and gained bareDetails + close forwarding. Extraction: DataSurfacePanel (data/SurfacePanel.vue, from the byte-diffable replica; grid template moved to inline style per the layer's no-arbitrary-classes rule) — both local copies deleted, all design + qdash usage sites swapped, demo + registry entry added. qcontrol port (Stage B): new qdash ui/app/components/inventory/AgentCard.vue — the three-section card wired to real data (roster row renders the header instantly; lazy /api/agent fetch feeds metadata, quota bar + governance denied-count (kept from the old expand per Mark), rich sessions with running/ok/error pills, and the four Surface panels with drill-down + listing links, oauth-pending joined by server name). Replaces AgentExpand.vue on /inventory and AgentExpandDetail on machine detail (Teams keeps the interim card until its redesign). Opportunistic fixes: PawnAgentAgentPawn on agent detail (component never resolved — pawn was invisible in prod), EXPAND_CAP 15 → 50 TODO, dead SurfaceMore.vue deleted. All 133 qdash vitest tests pass; Vite transforms clean. Ships as layer v0.9.6 (with Mark's UxButton size + grape-600 default and the AgentPawn zzz tweak) + a qdash dist rebuild.

Visual record

18 captures — heroes, page slices, and full-page renders. Click to view.

Five design-pass concepts — headline verdict, decision queue, Δ-column scorecard, activity timeline, adoption strip
Five design-pass concepts — headline verdict, decision queue, Δ-column scorecard, activity timeline, adoption strip
Detail iteration — combined header from the expand-v2 card (pawn, score smile, cost, identity + metadata toggle), straight to access tables
Detail iteration — combined header from the expand-v2 card (pawn, score smile, cost, identity + metadata toggle), straight to access tables
Presence-first fleet roster — mini cards by user, coverage with shadow-install ghosts, footprint strip
Presence-first fleet roster — mini cards by user, coverage with shadow-install ghosts, footprint strip
Dense fleet ledger — agents/machines/harnesses/surface lenses, designed expand-row, posture regression markers
Dense fleet ledger — agents/machines/harnesses/surface lenses, designed expand-row, posture regression markers
Ledger iteration — DataMetric tile overview, agents table primary with machines/harnesses/surface rails
Ledger iteration — DataMetric tile overview, agents table primary with machines/harnesses/surface rails
Three overview concepts side by side — trend-aware tiles, machine-grouped fleet-map bar, tiles+bar hybrid
Three overview concepts side by side — trend-aware tiles, machine-grouped fleet-map bar, tiles+bar hybrid
Designed agent expand-row — identity-strip header, Quick Overview/Recent Sessions, four agent-scoped Surface panels
Designed agent expand-row — identity-strip header, Quick Overview/Recent Sessions, four agent-scoped Surface panels
Expand card rebuilt as stacked UxTableListExpandSection cards — well tint through the gaps, ExpandRow X over section one
Expand card rebuilt as stacked UxTableListExpandSection cards — well tint through the gaps, ExpandRow X over section one
c59 hero
c59 full
c59 full
c59 full
c59 full
c59 full
c59 full
c59 full
c59 full
c59 full

In the archive

Artifacts

  • initial-prompt.md
  • buildability.md
  • design-brief.md
  • initial-prompt.md
  • plan.md
  • revisions.md

Qpoint Brand Style Guide