@polderlabs/bizar 5.6.0-beta.16 → 5.6.0-beta.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,10 @@
1
1
  # DESIGN.md — Bizar Dashboard
2
2
 
3
- > The BizarHarness dashboard. Norse-pantheon inspired, operator-quality
4
- > surfaces, dark-mode-first. v6.0.0.
3
+ > The BizarHarness dashboard. Norse-pantheon operator surface, dark-mode
4
+ > first, dense by intent. **v7.0** — adds the comprehensive view index,
5
+ > per-view data shapes, and the patterns needed for the eight secondary
6
+ > tabs (Overview, Agents, Active, Skills, Memory, Mods, Schedules,
7
+ > Settings) that v6 didn't fully document.
5
8
 
6
9
  ## 0 · How to use this file
7
10
 
@@ -11,14 +14,23 @@ derivable from the tokens and rules below. If a future change isn't
11
14
  covered here, **add it to this file first**, then implement it.
12
15
 
13
16
  **Token binding.** Components consume CSS variables (`--bg`,
14
- `--text-strong`, etc.) defined in `:root` of `styles/main.css`. Do not
15
- hardcode hex outside `:root`. Derive with `color-mix(in oklab,
16
- var(--accent), )` rather than inventing new tokens.
17
-
18
- **Themes.** The dashboard ships two themes — **dark** (default,
19
- `color-scheme: dark`) and **light** (`[data-theme='light']`). Both share
20
- the same token names; only the values change. Every component must read
21
- correctly in both themes without per-component overrides.
17
+ `--text-strong`, `--accent`) defined in `:root` of `styles/main.css`.
18
+ Do not hardcode hex outside `:root`. Derive tints with
19
+ `color-mix(in oklch, var(--accent) 12%, transparent)` rather than
20
+ inventing new tokens.
21
+
22
+ **Themes.** The dashboard ships two themes — **dark** (default) and
23
+ **light** (`[data-theme="light"]`). Both share the same token names;
24
+ only the values change. Every component must read correctly in both
25
+ themes without per-component overrides. Tokens are written in
26
+ **OKLch** because the lightness/chroma/hue model flips cleanly across
27
+ themes without the dark-mode channel separation that hex/rgb needs.
28
+
29
+ **Visual contract for new screens.** A new view must:
30
+ 1. Sit on one of three layouts (topbar / sidebar / both).
31
+ 2. Use tokens from §3-§8 only.
32
+ 3. Document its data shape in §15.
33
+ 4. Have a P0 entry in the checklist (§14) and pass it.
22
34
 
23
35
  ---
24
36
 
@@ -31,14 +43,14 @@ them in order; if two conflict, the higher rule wins.
31
43
  numeric, monospace-friendly. Information per square inch matters
32
44
  more than breathing room. Whitespace is spent on legibility, not
33
45
  decoration.
34
- 2. **One accent, used with intent.** The accent (`--accent`) earns its
35
- place by signaling primary action, active state, or data emphasis.
36
- No "AI sparkle" gradients. No purple washes behind text. No purple
37
- stripes on container edges.
46
+ 2. **One accent, used with intent.** The accent earns its place by
47
+ signaling primary action, active state, or data emphasis. No AI
48
+ gradients. No purple washes behind text. No purple stripes on
49
+ container edges.
38
50
  3. **State is signal, not decoration.** Active, streaming, awaiting,
39
51
  error, success — every state must be distinguishable at a glance
40
52
  without reading copy. Use weight, glow, motion, and color — but
41
- never vertical accent edges on containers.
53
+ **never vertical accent edges on containers**.
42
54
  4. **Type does hierarchy.** `Inter` carries the body, `JetBrains Mono`
43
55
  carries the metadata. Tabular numerics on every number. Display
44
56
  sizes scale with container, not viewport. Long copy wraps pretty.
@@ -53,17 +65,17 @@ them in order; if two conflict, the higher rule wins.
53
65
  | | |
54
66
  |--|--|
55
67
  | **Wordmark** | Bizar · runic `ᛒ` glyph in `var(--accent)` |
56
- | **Version pill** | `var(--version)` text in mono, accent-tinted gradient background |
57
- | **Voice** | Direct, technical, never marketing. "404 not found" not "Oops! Something went wrong". Numbers with units. |
68
+ | **Version pill** | mono text on a `var(--accent)` `oklch(0.55 0.22 25)` gradient |
69
+ | **Voice** | Direct, technical, never marketing. "404 not found" not "Oops! Something went wrong." Numbers with units. |
58
70
  | **Tab labels** | Single noun (`Chat`, `Agents`, `Tasks`). No icons-in-paragraphs. |
59
71
  | **Status copy** | "Streaming" not "Loading…". "Awaiting your reply" not "Ready". "13 of 47" not "Lots". |
60
72
 
61
- **Banned tropes** (audited by anti-slop spot-check):
73
+ **Banned tropes** (audited before each PR):
62
74
 
63
75
  - Aggressive purple gradient backgrounds behind text or as page chrome.
64
- - Vertical accent stripes on containers (`box-shadow: inset 2px 0 0 …`).
65
- State-encoded or not. Active state uses background, weight, glow, or
66
- motion — never a left-edge bar.
76
+ - Vertical accent stripes on containers (`box-shadow: inset 2px 0 0 …`,
77
+ `border-left: 3px solid …`). State-encoded or not. Active state uses
78
+ background, weight, glow, or motion — **never a left-edge bar**.
67
79
  - Generic emoji icons in feature lists (✨ 🚀 🎯 ❓). Use Lucide.
68
80
  - Inter as a display face for hero/section titles (Inter is body;
69
81
  display uses larger sizes of the same family but tighter tracking).
@@ -73,85 +85,90 @@ them in order; if two conflict, the higher rule wins.
73
85
 
74
86
  ## 3 · Color tokens
75
87
 
88
+ All values written in OKLch where possible. Hex kept only for legacy
89
+ or external-tool interop.
90
+
76
91
  ### 3.1 Surface scale (dark, default)
77
92
 
78
93
  ```
79
- --bg #0b0e14 page canvas
80
- --bg-elev #12161f cards, panels, topbar
81
- --bg-elev-2 #1a1f2b nested surfaces (modal over modal)
82
- --bg-elev-3 #232a39 hover / pressed surfaces
83
- --border #232a39 hairlines
84
- --border-strong #2d3648 heavier dividers, focus rings
94
+ --bg oklch(15% 0.012 260) #0b0e14 page canvas
95
+ --bg-elev oklch(18% 0.012 260) #12161f cards, topbar, sidebars
96
+ --bg-elev-2 oklch(22% 0.014 260) #1a1f2b nested surfaces
97
+ --bg-elev-3 oklch(27% 0.016 260) #232a39 hover / pressed surfaces
98
+ --border oklch(27% 0.016 260) #232a39 hairlines
99
+ --border-strong oklch(33% 0.018 260) #2d3648 focus rings, dividers
85
100
  ```
86
101
 
102
+ `--bg-1` and `--bg-2` from v6.x are deprecated; use `--bg-elev` and
103
+ `--bg-elev-2` instead. (The chat composer backdrop uses
104
+ `color-mix(in oklch, var(--bg-elev), black 12%)` for that nested feel.)
105
+
87
106
  ### 3.2 Surface scale (light)
88
107
 
89
108
  ```
90
- --bg #f7f8fa
91
- --bg-elev #ffffff
92
- --bg-elev-2 #f0f3f8
93
- --bg-elev-3 #e6ebf2
94
- --border #e2e8f0
95
- --border-strong #cbd5e1
109
+ --bg oklch(98% 0.004 240) #f7f8fa
110
+ --bg-elev oklch(100% 0 0) #ffffff
111
+ --bg-elev-2 oklch(96% 0.006 240) #f0f3f8
112
+ --bg-elev-3 oklch(92% 0.008 240) #e6ebf2
113
+ --border oklch(90% 0.008 240) #e2e8f0
114
+ --border-strong oklch(82% 0.012 240) #cbd5e1
96
115
  ```
97
116
 
98
117
  ### 3.3 Text scale
99
118
 
100
- | Token | Dark | Light | Use |
119
+ | Token | Dark (OKLch) | Light (hex) | Use |
101
120
  |---|---|---|---|
102
- | `--text-strong` | `#f0f6fc` | `#0f172a` | Headings, primary content |
103
- | `--text` | `#c9d1d9` | `#1f2937` | Body |
104
- | `--text-dim` (= `--text-muted`) | `#b4bcd0` | `#475569` | Captions, metadata |
105
- | `--text-on-accent` | `#ffffff` | `#ffffff` | Text over accent fills |
121
+ | `--text-strong` | `oklch(96% 0.005 240)` | `#0f172a` | Headings, primary content |
122
+ | `--text` | `oklch(82% 0.010 245)` | `#1f2937` | Body |
123
+ | `--text-dim` | `oklch(72% 0.012 245)` | `#475569` | Captions, metadata |
124
+ | `--text-on-accent` | `oklch(100% 0 0)` | `#ffffff` | Text over accent fills |
106
125
 
107
126
  ### 3.4 Brand accent
108
127
 
109
128
  | Token | Dark | Light | Use |
110
129
  |---|---|---|---|
111
- | `--accent` | `#8b5cf6` | `#7c3aed` | Primary action, active state, focus |
112
- | `--accent-2` | `#a78bfa` | `#6d28d9` | Hover state on accent |
113
- | `--accent-3` | `#c4b5fd` | `#5b21b6` | Subdued accent text |
114
- | `--accent-bg` | `rgba(139,92,246,0.12)` | `rgba(124,58,237,0.08)` | Tinted panel backgrounds |
115
- | `--accent-border` | `rgba(139,92,246,0.4)` | `rgba(124,58,237,0.3)` | Tinted borders |
116
- | `--accent-glow` | `rgba(139,92,246,0.18)` | `rgba(124,58,237,0.18)` | Focus glow shadow |
117
- | `--accent-soft` | `rgba(139,92,246,0.08)` | `rgba(124,58,237,0.06)` | Hover wash on neutral surface |
130
+ | `--accent` | `oklch(0.62 0.18 273)` | `oklch(0.55 0.20 273)` | Primary action, active state, focus |
131
+ | `--accent-2` | `oklch(0.72 0.16 273)` | `oklch(0.48 0.20 273)` | Hover state on accent |
132
+ | `--accent-3` | `oklch(0.82 0.10 273)` | `oklch(0.40 0.18 273)` | Subdued accent text |
133
+ | `--accent-bg` | `color-mix(in oklch, var(--accent) 12%, transparent)` | same, 8% | Tinted panel backgrounds |
134
+ | `--accent-border` | `color-mix(in oklch, var(--accent) 40%, transparent)` | same, 30% | Tinted borders |
135
+ | `--accent-glow` | `color-mix(in oklch, var(--accent) 18%, transparent)` | same | Focus glow shadow |
136
+ | `--accent-soft` | `color-mix(in oklch, var(--accent) 8%, transparent)` | same, 6% | Hover wash on neutral surface |
118
137
 
119
138
  **Accent budget.** Two uses per region, max. Default allocation:
120
139
  1. Active nav item background OR primary CTA fill.
121
140
  2. Active state badge OR streaming pill.
122
141
 
123
- ### 3.5 Status colors
142
+ ### 3.5 Status colors (OKLch in both themes)
124
143
 
125
- | Token | Dark (OKLch) | Light (hex) | Use |
144
+ | Token | Dark | Light | Use |
126
145
  |---|---|---|---|
127
- | `--success` | `oklch(0.72 0.16 145)` | `#047857` | Streaming OK, task done, connected |
128
- | `--warning` | `oklch(0.78 0.14 70)` | `#b45309` | Stuck agent, retry, cost spike |
129
- | `--error` | `oklch(0.66 0.20 25)` | `#b91c1c` | Failed, deleted, auth error |
130
- | `--info` | `oklch(0.72 0.13 235)` | `#1d4ed8` | Neutral informational |
131
- | `--success-soft` | `rgba(52,211,153,0.15)` | `rgba(5,150,105,0.12)` | Status pill background |
132
- | `--error-soft` | `rgba(248,113,113,0.12)` | `rgba(190,18,60,0.10)` | Error region background |
133
- | `--warning-soft` | `rgba(251,191,36,0.15)` | `rgba(180,83,9,0.10)` | Warning region background |
146
+ | `--success` | `oklch(0.72 0.16 145)` | `oklch(0.50 0.15 145)` | Streaming OK, task done, connected |
147
+ | `--warning` | `oklch(0.78 0.14 70)` | `oklch(0.55 0.15 70)` | Stuck agent, retry, cost spike |
148
+ | `--error` | `oklch(0.66 0.20 25)` | `oklch(0.52 0.20 25)` | Failed, deleted, auth error |
149
+ | `--info` | `oklch(0.72 0.13 235)` | `oklch(0.50 0.15 235)` | Neutral informational |
150
+ | `--success-soft` | `color-mix(in oklch, var(--success) 15%, transparent)` | same, 12% | Status pill bg |
151
+ | `--error-soft` | `color-mix(in oklch, var(--error) 12%, transparent)` | same, 10% | Error region bg |
152
+ | `--warning-soft` | `color-mix(in oklch, var(--warning) 15%, transparent)` | same, 10% | Warning region bg |
134
153
 
135
- ### 3.6 Derived tokens (chat overhaul, v3.21)
154
+ ### 3.6 Derived tokens (chat overhaul, v3.21 — preserved)
136
155
 
137
156
  ```
138
- --bg-1 #18181b Gemini-style nested surface (chat composer backdrop)
139
- --bg-2 #27272a Chat composer input + tokens bar
140
- --gradient-hello 90deg, accent-lightened → accent
141
- --gradient-name 90deg, accent → accent→red35 → accent→red65
157
+ --gradient-hello linear 90deg, var(--accent-3) var(--accent)
158
+ --gradient-name linear 90deg, var(--accent) oklch(0.55 0.22 25)
142
159
  ```
143
160
 
144
- The two gradients are reserved for the **chat greeting** (`hello, name`)
161
+ Both gradients are reserved for the **chat greeting** (`hello, name`)
145
162
  and **brand mark** (`ᛒ Bizar`) — never used elsewhere.
146
163
 
147
164
  ### 3.7 Syntax highlight (json tree in JSON viewer)
148
165
 
149
166
  ```
150
- --syntax-key #79c0ff
151
- --syntax-string #a5d6ff
152
- --syntax-number #ffa657
153
- --syntax-boolean #ff7b72
154
- --syntax-null #ff7b72
167
+ --syntax-key oklch(0.78 0.13 235)
168
+ --syntax-string oklch(0.84 0.10 235)
169
+ --syntax-number oklch(0.78 0.16 60)
170
+ --syntax-boolean oklch(0.68 0.20 25)
171
+ --syntax-null oklch(0.68 0.20 25)
155
172
  ```
156
173
 
157
174
  ### 3.8 Anti-pattern reference colors
@@ -179,8 +196,7 @@ and **brand mark** (`ᛒ Bizar`) — never used elsewhere.
179
196
  ```
180
197
 
181
198
  Inter variable enables `cv02`, `cv03`, `cv04`, `cv11` stylistic sets
182
- for more legible numbers, parentheses, and `@` symbol — already enabled
183
- in the body rule.
199
+ for more legible numbers, parentheses, and `@` symbol.
184
200
 
185
201
  ### 4.2 Scale
186
202
 
@@ -287,10 +303,10 @@ update in place. The number just changes — no flicker, no count-up.
287
303
 
288
304
  ---
289
305
 
290
- ## 9 · Components
306
+ ## 9 · Components catalog
291
307
 
292
- The dashboard has ~50 components. Below is the canonical catalog. Every
293
- new component must slot into one of these categories.
308
+ The dashboard ships ~60 components. Every new component must slot into
309
+ one of these categories.
294
310
 
295
311
  ### 9.1 Chrome
296
312
 
@@ -303,8 +319,8 @@ new component must slot into one of these categories.
303
319
  ```
304
320
 
305
321
  - Brand block: runic `ᛒ` (24px, `--accent`) + "Bizar" wordmark +
306
- version pill. Pill uses `--gradient-name` and `text-shadow: 0 1px 0
307
- rgba(0,0,0,0.2)` so it reads on light too.
322
+ version pill. Pill uses `--gradient-name` and
323
+ `text-shadow: 0 1px 0 rgba(0,0,0,0.2)` so it reads on light too.
308
324
  - Project selector: pill button with `Folder` icon + project name +
309
325
  chevron. Dropdown is `--bg-elev-2` with 8px radius, items 32px tall.
310
326
  - Search trigger: pill button with kbd hint `⌘K`, `--border` outline.
@@ -442,7 +458,7 @@ in footer showing shortcuts.
442
458
  thread, `--bg-elev-2` + `--shadow-2`.
443
459
 
444
460
  #### Composer
445
- - Pill-shaped input, `--bg-1` (Gemini dark), `--bg-2` inner field.
461
+ - Pill-shaped input, `--bg-elev` outer, `--bg-elev-2` inner field.
446
462
  - Attachments: chip row above input.
447
463
  - Slash command suggestions: popover above, mono, `--font-mono`.
448
464
  - Agent + model selectors: pill chips on left, opens dropdown on
@@ -463,7 +479,7 @@ in footer showing shortcuts.
463
479
  letter-spacing.
464
480
  - Body row: 14px, `--text`, 12px 14px padding.
465
481
  - Numerics: `--font-mono`, `tabular-nums`, right-aligned.
466
- - Hover: `--fg-soft` (6% text-color wash) — not a colored row.
482
+ - Hover: `--bg-elev-2` wash — not a colored row.
467
483
 
468
484
  ### 9.12 Kanban (Tasks)
469
485
 
@@ -504,6 +520,41 @@ in footer showing shortcuts.
504
520
  - Each result: icon + title + path (mono, dim) + kbd hint.
505
521
  - Arrow keys to navigate, Enter to open.
506
522
 
523
+ ### 9.17 Sparkline & metric charts
524
+
525
+ - Inline SVG, 32px tall, `--accent` stroke 1.5px, gradient fill (8% → 0%).
526
+ - Right-aligned delta: `--success` for "up is good", `--error` for "up is bad".
527
+ - Numeric body always tabular-nums.
528
+
529
+ ### 9.18 Workflow DAG visualizer (v6.0.0)
530
+
531
+ Used in Tasks card detail and Eval reports.
532
+ - Nodes: rounded rectangles (8px radius), `--bg-elev-2` background, hairline border.
533
+ - Node states: idle / running / done / failed / skipped — colored border + center dot.
534
+ - Edges: 1.5px lines in `--text-dim`, animated dashed line on the "currently running" edge.
535
+ - Vertical timeline: time on the left axis in mono.
536
+
537
+ ### 9.19 Approval queue (v6.0.0)
538
+
539
+ Used in Plans & Memory tabs.
540
+ - Each row: 56px tall, agent avatar + plan title + target file (mono) + Approve / Steer / Reject buttons.
541
+ - Hairline separators; rejected plans get a thin `--error-soft` wash on hover-to-undo.
542
+ - Bulk action toolbar floats above the queue when ≥1 selected.
543
+
544
+ ### 9.20 Cost / token chart card (v6.0.0)
545
+
546
+ Used in Usage (MiniMax) and Overview.
547
+ - Card: title + period selector (24h / 7d / 30d) + big numeric + sparkline + breakdown bars.
548
+ - Breakdown bars: horizontal stacked bar by model, `--accent` for primary, `--text-dim` for others.
549
+ - Always tabular-nums. Always right-aligned.
550
+
551
+ ### 9.21 BG agent live panel (v6.0.0)
552
+
553
+ Used in Active tab.
554
+ - Row: 56px tall, agent avatar + name + status pill + elapsed (mono, 1s tick) + action buttons (pause / steer / stop).
555
+ - Status pill variants: `running` (success pulse) / `paused` (warning) / `stuck` (warning static + Retry) / `done` (text-dim).
556
+ - Collapsed by default, expands to show streaming output and tool calls.
557
+
507
558
  ---
508
559
 
509
560
  ## 10 · Patterns
@@ -609,6 +660,92 @@ Pills are pill-success / pill-warning / pill-error as appropriate.
609
660
  Progress bars: `--bg-elev-2` track, `--accent` fill. **No colored
610
661
  track backgrounds** — color stays on the fill, not on the rail.
611
662
 
663
+ ### 10.9 Overview dashboard layout (v6.0.0)
664
+
665
+ ```
666
+ ┌────────────────────────────────────────────────────────────────┐
667
+ │ HEADER: ⌂ Bizar project▾ ⌘K Search • ws·live • cline │
668
+ ├────────────────────────────────────────────────────────────────┤
669
+ │ HERO ROW (4 cards): │
670
+ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
671
+ │ │ tokens/hr │ │ latency │ │ error rate │ │ cost/hr │ │
672
+ │ │ 1.42M │ │ 842ms │ │ 0.21% │ │ $1.84 │ │
673
+ │ │ +12% ▲ │ │ −18ms ▼ │ │ +0.04 ▲ │ │ −8% ▼ │ │
674
+ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
675
+ ├────────────────────────────────────────────────────────────────┤
676
+ │ TWO-COL: │
677
+ │ ┌──────────────────────┐ ┌──────────────────────────────┐ │
678
+ │ │ Live activity feed │ │ Active agents (3 running) │ │
679
+ │ │ (timestamped rows) │ │ (status rows w/ pause) │ │
680
+ │ │ │ │ │ │
681
+ │ │ │ │ Memory health │ │
682
+ │ │ │ │ (4 sources at a glance) │ │
683
+ │ └──────────────────────┘ └──────────────────────────────┘ │
684
+ ├────────────────────────────────────────────────────────────────┤
685
+ │ GRAPH ROW: │
686
+ │ ┌──────────────────────────────────────────────────────────┐ │
687
+ │ │ Token spend · last 24h (large sparkline + breakdown) │ │
688
+ │ └──────────────────────────────────────────────────────────┘ │
689
+ └────────────────────────────────────────────────────────────────┘
690
+ ```
691
+
692
+ ### 10.10 Cost dashboard layout (Usage tab)
693
+
694
+ ```
695
+ ┌────────────────────────────────────────────────────────────────┐
696
+ │ HEADER Usage · 24h ▾ $1.84/hr −8% ▲ │
697
+ ├────────────────────────────────────────────────────────────────┤
698
+ │ STAT CARDS (4): │
699
+ │ [spent 24h] [cost/hr] [tokens/hr] [alerts] │
700
+ ├──────────────────────────────┬─────────────────────────────────┤
701
+ │ TOKEN SPEND CHART │ MODEL BREAKDOWN │
702
+ │ (stacked area, last 24h) │ (horizontal bars per model) │
703
+ │ │ │
704
+ ├──────────────────────────────┼─────────────────────────────────┤
705
+ │ RECENT ALARMS │ BUDGET STATUS │
706
+ │ (timeline of cost spikes) │ (4 budgets, percent gauges) │
707
+ └──────────────────────────────┴─────────────────────────────────┘
708
+ ```
709
+
710
+ ### 10.11 Active BG agents layout
711
+
712
+ ```
713
+ ┌────────────────────────────────────────────────────────────────┐
714
+ │ HEADER Active · 3 running 1 paused 1 stuck │
715
+ ├────────────────────────────────────────────────────────────────┤
716
+ │ ROW (collapsible, default collapsed): │
717
+ │ ● odin streaming 4m12s [pause][steer][stop][expand] │
718
+ │ ─ expanded: streaming output + tool call list ─ │
719
+ │ │
720
+ │ ● thor paused 8m03s [resume][steer][stop] │
721
+ │ ● mimir stuck 5m21s [retry][steer][stop] │
722
+ │ ● tyr done 2m41s [restart][remove] │
723
+ └────────────────────────────────────────────────────────────────┘
724
+ ```
725
+
726
+ ### 10.12 Settings mode (v4.9.0)
727
+
728
+ When the user enters the Settings tab, the sidebar replaces its
729
+ tab list with the full SettingsNav (16 sections). The active section
730
+ lights up in the sidebar and the main panel scrolls to it.
731
+
732
+ ```
733
+ ┌──────┬───────────────────────────────────────────────┐
734
+ │ ⌂ │ Theme │
735
+ │ 💬 │ ────── │
736
+ │ 🤖 │ Accent color [color picker] │
737
+ │ ... │ Font family [Inter ▾] │
738
+ │ ⚙ → │ Compact mode [▢] │
739
+ │ │ │
740
+ │ ▼ │ Layout │
741
+ │ Theme│ ────── │
742
+ │ Layo │ UI layout (•) sidebar ( ) topnav ( ) both│
743
+ │ Net │ Show header [✓] │
744
+ │ Auth │ │
745
+ │ ... │ │
746
+ └──────┴───────────────────────────────────────────────┘
747
+ ```
748
+
612
749
  ---
613
750
 
614
751
  ## 11 · Iconography
@@ -691,8 +828,318 @@ blocker.
691
828
 
692
829
  ---
693
830
 
694
- ## 15 · Versioning
831
+ ## 15 · View index & data shapes
832
+
833
+ Every view declares the data it consumes. Mock data lives in
834
+ `canvas.html` for visual development; the live API endpoint that
835
+ backs each view is documented in `docs/api.md`.
836
+
837
+ ### 15.1 Overview
838
+
839
+ **Layout:** §10.9. **Endpoint:** `GET /snapshot.overview`.
840
+
841
+ ```ts
842
+ interface OverviewData {
843
+ // Live activity (last 50 items, newest first)
844
+ recentActivity: ActivityItem[];
845
+
846
+ // Hero metrics
847
+ metrics: {
848
+ tokensPerHour: number;
849
+ avgLatencyMs: number;
850
+ errorRate: number; // 0..1
851
+ costPerHour: number; // USD
852
+ activeBgAgents: number;
853
+ activeSessions: number;
854
+ };
855
+
856
+ // Active agents (subset of BackgroundAgents)
857
+ activeAgents: BgInstance[];
858
+
859
+ // Memory health (4 sources)
860
+ memoryHealth: {
861
+ source: 'lightrag' | 'obsidian' | 'gitsync' | 'semantic';
862
+ state: 'ok' | 'degraded' | 'down';
863
+ lastSync: string;
864
+ }[];
865
+
866
+ // Token spend chart (last 24h, hourly buckets)
867
+ tokenSpend: { hour: string; tokens: number; cost: number }[];
868
+ }
869
+ ```
870
+
871
+ ### 15.2 Chat
872
+
873
+ **Layout:** §10.2. **Endpoints:** `GET /snapshot.sessions` (list),
874
+ `GET /api/cline-sessions` (cline), `POST /api/chat` (send),
875
+ `WS /ws` (stream).
876
+
877
+ ```ts
878
+ interface ChatSession {
879
+ id: string;
880
+ title: string;
881
+ mtime: number;
882
+ state: 'idle' | 'streaming' | 'awaiting';
883
+ source: 'bizar' | 'cline';
884
+ agent: string;
885
+ unread?: number;
886
+ pinned?: boolean;
887
+ tree?: { root: AgentTreeNode }; // orchestrator sub-agents
888
+ }
889
+
890
+ interface ChatMessage {
891
+ id: number;
892
+ role: 'user' | 'assistant' | 'tool';
893
+ author: string;
894
+ ts: string; // HH:MM
895
+ text: ReactNode;
896
+ toolCalls?: ToolCall[];
897
+ pinned?: boolean;
898
+ }
899
+ ```
900
+
901
+ ### 15.3 Agents
902
+
903
+ **Layout:** Roster grid (3-col on ≥1440px, 2-col on ≥1024px, 1-col
904
+ below). **Endpoint:** `GET /snapshot.agents`.
905
+
906
+ ```ts
907
+ interface Agent {
908
+ name: string; // 'odin', 'thor', 'mimir', ...
909
+ model: string; // 'anthropic/claude-sonnet-4-6'
910
+ mode: string; // 'plan-then-forseti'
911
+ status: 'idle' | 'busy' | 'stuck' | 'down';
912
+ lastSeen: number;
913
+ tasksCompleted: number;
914
+ avgLatencyMs: number;
915
+ }
916
+ ```
917
+
918
+ Each card: avatar (first 2 letters), name (mono), model (dim mono),
919
+ status pill, last seen time, 3 mini stats.
920
+
921
+ ### 15.4 Glyphs (Artifacts)
922
+
923
+ **Layout:** Masonry grid of square cards. **Endpoint:**
924
+ `GET /snapshot.artifacts`.
925
+
926
+ ```ts
927
+ interface Artifact {
928
+ id: string;
929
+ title: string;
930
+ kind: 'glyph' | 'note' | 'doc';
931
+ createdAt: number;
932
+ thumbnail?: string; // data URL or absent
933
+ size: number; // bytes
934
+ }
935
+ ```
936
+
937
+ ### 15.5 Tasks
938
+
939
+ **Layout:** 5-column kanban (§9.12). **Endpoint:** `GET /snapshot.tasks`.
940
+
941
+ ```ts
942
+ interface Task {
943
+ id: string; // 'T-120'
944
+ title: string;
945
+ col: 'backlog' | 'todo' | 'in_progress' | 'review' | 'done';
946
+ priority: 'high' | 'mid' | 'low';
947
+ tags: string[];
948
+ team?: boolean; // v6 team badge
949
+ by: string; // agent name
950
+ when: string; // 'now', '3h', '1d'
951
+ }
952
+ ```
953
+
954
+ ### 15.6 Activity
955
+
956
+ **Layout:** Timeline (§9.7). **Endpoint:** `WS /api/activity/stream`.
957
+
958
+ ```ts
959
+ interface ActivityItem {
960
+ kind: 'agent' | 'task' | 'error' | 'info';
961
+ ts: string; // HH:MM
962
+ text: ReactNode; // allows inline mono spans
963
+ target?: string; // optional file/task id
964
+ }
965
+ ```
966
+
967
+ ### 15.7 Active (Background agents)
968
+
969
+ **Layout:** §10.11. **Endpoints:** `GET /background`, `WS bg:*`.
970
+
971
+ ```ts
972
+ interface BgInstance {
973
+ instanceId: string;
974
+ agent: string;
975
+ prompt: string;
976
+ status: 'pending' | 'running' | 'paused' | 'done' | 'failed';
977
+ startedAt: number;
978
+ elapsedMs: number;
979
+ toolCalls: BgToolCall[];
980
+ output: string; // last 32k chars
981
+ stuck?: boolean; // server-flagged
982
+ }
983
+ ```
984
+
985
+ ### 15.8 Skills
986
+
987
+ **Layout:** Card grid (3-col), each card collapsible. **Endpoint:**
988
+ `GET /skills` (planned).
989
+
990
+ ```ts
991
+ interface Skill {
992
+ id: string; // 'design-taste-frontend'
993
+ name: string;
994
+ description: string;
995
+ enabled: boolean;
996
+ triggers: string[];
997
+ updatedAt: number;
998
+ }
999
+ ```
1000
+
1001
+ ### 15.9 Memory
1002
+
1003
+ **Layout:** 3-column (source rail · main panel · detail). **Endpoint:**
1004
+ `GET /memory/overview`, `GET /memory/{source}`, `POST /memory/search`.
1005
+
1006
+ ```ts
1007
+ interface MemoryOverview {
1008
+ sources: {
1009
+ id: 'lightrag' | 'obsidian' | 'gitsync' | 'semantic';
1010
+ state: 'ok' | 'degraded' | 'down';
1011
+ noteCount: number;
1012
+ lastSync: number;
1013
+ }[];
1014
+ recent: MemoryNote[];
1015
+ }
1016
+
1017
+ interface MemoryNote {
1018
+ id: string;
1019
+ source: MemoryOverview['sources'][number]['id'];
1020
+ title: string;
1021
+ preview: string;
1022
+ tags: string[];
1023
+ updatedAt: number;
1024
+ }
1025
+ ```
1026
+
1027
+ ### 15.10 Mods
1028
+
1029
+ **Layout:** List of installed mods with enable/disable, install new
1030
+ from URL. **Endpoint:** `GET /mods`, `POST /mods/install`.
1031
+
1032
+ ```ts
1033
+ interface Mod {
1034
+ id: string;
1035
+ name: string;
1036
+ version: string;
1037
+ enabled: boolean;
1038
+ hasViews: boolean;
1039
+ installPath: string;
1040
+ updatedAt: number;
1041
+ }
1042
+ ```
1043
+
1044
+ ### 15.11 Schedules
1045
+
1046
+ **Layout:** Card list with cron expression, last run, next run,
1047
+ toggle. **Endpoint:** `GET /schedules`.
1048
+
1049
+ ```ts
1050
+ interface Schedule {
1051
+ id: string;
1052
+ name: string;
1053
+ cron: string; // '0 */6 * * *'
1054
+ prompt: string;
1055
+ agent: string;
1056
+ enabled: boolean;
1057
+ lastRun: number | null;
1058
+ lastResult: 'ok' | 'fail' | null;
1059
+ nextRun: number;
1060
+ }
1061
+ ```
1062
+
1063
+ ### 15.12 Usage (MiniMax)
1064
+
1065
+ **Layout:** §10.10. **Endpoint:** `GET /api/usage?range=24h|7d|30d`.
1066
+
1067
+ ```ts
1068
+ interface UsageData {
1069
+ range: '24h' | '7d' | '30d';
1070
+ totalCost: number;
1071
+ totalTokens: number;
1072
+ costPerHour: number;
1073
+ byModel: { model: string; tokens: number; cost: number }[];
1074
+ byHour: { hour: string; tokens: number; cost: number }[];
1075
+ alerts: { ts: number; severity: 'warn' | 'error'; text: string }[];
1076
+ budgets: { id: string; label: string; cap: number; spent: number }[];
1077
+ }
1078
+ ```
1079
+
1080
+ ### 15.13 Eval
1081
+
1082
+ **Layout:** Run list (top) + last run detail (bottom). **Endpoint:**
1083
+ `GET /eval/runs`, `GET /eval/runs/:id`.
1084
+
1085
+ ```ts
1086
+ interface EvalRun {
1087
+ id: string;
1088
+ startedAt: number;
1089
+ finishedAt: number | null;
1090
+ passed: number;
1091
+ total: number;
1092
+ cases: { name: string; pass: boolean; latencyMs: number }[];
1093
+ }
1094
+ ```
1095
+
1096
+ ### 15.14 Doctor
1097
+
1098
+ **Layout:** Hero score + 8 subsystem cards (§9.18). **Endpoint:**
1099
+ `GET /doctor`.
1100
+
1101
+ ```ts
1102
+ interface DoctorData {
1103
+ checkedAt: number;
1104
+ overall: number; // 0..8
1105
+ subsystems: {
1106
+ name: string;
1107
+ state: 'ok' | 'degraded' | 'warning' | 'error';
1108
+ score: number;
1109
+ total: number;
1110
+ note: string;
1111
+ }[];
1112
+ }
1113
+ ```
1114
+
1115
+ ### 15.15 Harness
1116
+
1117
+ **Layout:** Audit rules list + 6/6 pass badge. **Endpoint:**
1118
+ `GET /harness/audit`.
1119
+
1120
+ ```ts
1121
+ interface HarnessAudit {
1122
+ version: string;
1123
+ rules: { rule: string; pass: boolean; detail: string }[];
1124
+ }
1125
+ ```
1126
+
1127
+ ### 15.16 Settings
1128
+
1129
+ **Layout:** §10.12. **Endpoint:** `GET /settings`, `POST /settings`.
1130
+
1131
+ 16 sections: theme, updates, layout, general, env-vars, network,
1132
+ notifications, auth, agents, dashboard, background, system-llm,
1133
+ headroom, activity-log, workspaces, about. Each section is its own
1134
+ component in `src/web/views/settings/`.
1135
+
1136
+ ---
1137
+
1138
+ ## 16 · Versioning
695
1139
 
1140
+ - v7.0 — this document. Adds view index, data shapes, 5 new component
1141
+ patterns (DAG, approvals, cost chart, BG panel, workflow). Token
1142
+ system migrated to OKLch + color-mix.
696
1143
  - v6.0.0 — Cline runtime badge, Harness tab, Tasks kanban team badge,
697
1144
  brand version pill, Mods-only navigation.
698
1145
  - v5.x — Eval framework, Doctor page.