jfl 0.2.4 → 0.3.0

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.
Files changed (105) hide show
  1. package/README.md +16 -0
  2. package/dist/commands/agent.d.ts +7 -0
  3. package/dist/commands/agent.d.ts.map +1 -0
  4. package/dist/commands/agent.js +170 -0
  5. package/dist/commands/agent.js.map +1 -0
  6. package/dist/commands/context-hub.d.ts.map +1 -1
  7. package/dist/commands/context-hub.js +274 -27
  8. package/dist/commands/context-hub.js.map +1 -1
  9. package/dist/commands/digest.d.ts.map +1 -1
  10. package/dist/commands/digest.js +45 -0
  11. package/dist/commands/digest.js.map +1 -1
  12. package/dist/commands/doctor.d.ts +7 -0
  13. package/dist/commands/doctor.d.ts.map +1 -0
  14. package/dist/commands/doctor.js +236 -0
  15. package/dist/commands/doctor.js.map +1 -0
  16. package/dist/commands/eval.d.ts +6 -0
  17. package/dist/commands/eval.d.ts.map +1 -0
  18. package/dist/commands/eval.js +236 -0
  19. package/dist/commands/eval.js.map +1 -0
  20. package/dist/commands/hooks.d.ts +2 -0
  21. package/dist/commands/hooks.d.ts.map +1 -1
  22. package/dist/commands/hooks.js +1 -0
  23. package/dist/commands/hooks.js.map +1 -1
  24. package/dist/commands/init.d.ts.map +1 -1
  25. package/dist/commands/init.js +230 -145
  26. package/dist/commands/init.js.map +1 -1
  27. package/dist/commands/portfolio.d.ts +6 -0
  28. package/dist/commands/portfolio.d.ts.map +1 -0
  29. package/dist/commands/portfolio.js +296 -0
  30. package/dist/commands/portfolio.js.map +1 -0
  31. package/dist/commands/scope.d.ts +1 -0
  32. package/dist/commands/scope.d.ts.map +1 -1
  33. package/dist/commands/scope.js +189 -2
  34. package/dist/commands/scope.js.map +1 -1
  35. package/dist/commands/update.d.ts.map +1 -1
  36. package/dist/commands/update.js +6 -0
  37. package/dist/commands/update.js.map +1 -1
  38. package/dist/commands/voice.js.map +1 -1
  39. package/dist/dashboard/components.d.ts +1 -1
  40. package/dist/dashboard/components.d.ts.map +1 -1
  41. package/dist/dashboard/components.js +418 -6
  42. package/dist/dashboard/components.js.map +1 -1
  43. package/dist/dashboard/index.d.ts.map +1 -1
  44. package/dist/dashboard/index.js +32 -5
  45. package/dist/dashboard/index.js.map +1 -1
  46. package/dist/dashboard/pages.d.ts +1 -1
  47. package/dist/dashboard/pages.d.ts.map +1 -1
  48. package/dist/dashboard/pages.js +961 -123
  49. package/dist/dashboard/pages.js.map +1 -1
  50. package/dist/dashboard/styles.d.ts +1 -1
  51. package/dist/dashboard/styles.d.ts.map +1 -1
  52. package/dist/dashboard/styles.js +701 -88
  53. package/dist/dashboard/styles.js.map +1 -1
  54. package/dist/index.js +88 -45
  55. package/dist/index.js.map +1 -1
  56. package/dist/lib/agent-manifest.d.ts +35 -0
  57. package/dist/lib/agent-manifest.d.ts.map +1 -0
  58. package/dist/lib/agent-manifest.js +75 -0
  59. package/dist/lib/agent-manifest.js.map +1 -0
  60. package/dist/lib/eval-store.d.ts +15 -0
  61. package/dist/lib/eval-store.d.ts.map +1 -0
  62. package/dist/lib/eval-store.js +179 -0
  63. package/dist/lib/eval-store.js.map +1 -0
  64. package/dist/lib/flow-engine.d.ts +12 -0
  65. package/dist/lib/flow-engine.d.ts.map +1 -1
  66. package/dist/lib/flow-engine.js +181 -4
  67. package/dist/lib/flow-engine.js.map +1 -1
  68. package/dist/lib/kuva.d.ts +45 -0
  69. package/dist/lib/kuva.d.ts.map +1 -0
  70. package/dist/lib/kuva.js +131 -0
  71. package/dist/lib/kuva.js.map +1 -0
  72. package/dist/lib/service-gtm.d.ts +10 -1
  73. package/dist/lib/service-gtm.d.ts.map +1 -1
  74. package/dist/lib/service-gtm.js +35 -2
  75. package/dist/lib/service-gtm.js.map +1 -1
  76. package/dist/lib/trajectory-loader.d.ts +82 -0
  77. package/dist/lib/trajectory-loader.d.ts.map +1 -0
  78. package/dist/lib/trajectory-loader.js +406 -0
  79. package/dist/lib/trajectory-loader.js.map +1 -0
  80. package/dist/mcp/context-hub-mcp.js +60 -0
  81. package/dist/mcp/context-hub-mcp.js.map +1 -1
  82. package/dist/types/eval.d.ts +18 -0
  83. package/dist/types/eval.d.ts.map +1 -0
  84. package/dist/types/eval.js +5 -0
  85. package/dist/types/eval.js.map +1 -0
  86. package/dist/types/flows.d.ts +7 -0
  87. package/dist/types/flows.d.ts.map +1 -1
  88. package/dist/types/journal.d.ts +133 -0
  89. package/dist/types/journal.d.ts.map +1 -0
  90. package/dist/types/journal.js +59 -0
  91. package/dist/types/journal.js.map +1 -0
  92. package/dist/types/map.d.ts +1 -1
  93. package/dist/types/map.d.ts.map +1 -1
  94. package/dist/types/map.js.map +1 -1
  95. package/dist/ui/service-dashboard.js.map +1 -1
  96. package/dist/utils/wallet.js.map +1 -1
  97. package/package.json +1 -1
  98. package/scripts/migrate-to-branch-sessions.sh +201 -0
  99. package/scripts/session/fix-tracked-logs.sh +97 -0
  100. package/scripts/session/session-cleanup.sh +28 -10
  101. package/scripts/session/session-end.sh +0 -10
  102. package/scripts/session/session-init.sh +0 -16
  103. package/template/THEORY.md +26 -0
  104. package/template/scripts/session/session-cleanup.sh +28 -10
  105. package/template/scripts/session/session-sync.sh +10 -0
@@ -1,32 +1,31 @@
1
1
  /**
2
2
  * Dashboard CSS styles
3
3
  *
4
- * @purpose CSS string with brand colors from theme.ts for the web dashboard
4
+ * @purpose CSS string with Paperclip-inspired oklch monochromatic design system for the web dashboard
5
5
  */
6
6
  export function getDashboardStyles() {
7
7
  return `
8
8
  :root {
9
- --accent: #FFD700;
10
- --accent-soft: #FFA500;
11
- --accent-dim: #B8860B;
12
- --success: #00FF88;
13
- --error: #FF4444;
14
- --warning: #FFAA00;
15
- --info: #4FC3F7;
16
- --bg: #0f172a;
17
- --bg-card: #1e293b;
18
- --bg-card-hover: #334155;
19
- --text: #f8fafc;
20
- --text-soft: #94a3b8;
21
- --text-dim: #64748b;
22
- --border: #334155;
9
+ --background: oklch(0.145 0 0);
10
+ --card: oklch(0.205 0 0);
11
+ --card-hover: oklch(0.25 0 0);
12
+ --border: oklch(0.269 0 0);
13
+ --foreground: oklch(0.985 0 0);
14
+ --muted-foreground: oklch(0.708 0 0);
15
+ --dim: oklch(0.45 0 0);
16
+
17
+ --success: oklch(0.696 0.17 162.48);
18
+ --error: oklch(0.637 0.237 25.331);
19
+ --warning: oklch(0.795 0.184 86.047);
20
+ --info: oklch(0.588 0.158 241.966);
21
+ --accent: oklch(0.588 0.158 241.966);
23
22
  }
24
23
 
25
24
  * { box-sizing: border-box; margin: 0; padding: 0; }
26
25
 
27
26
  body {
28
- background: var(--bg);
29
- color: var(--text);
27
+ background: var(--background);
28
+ color: var(--foreground);
30
29
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
31
30
  min-height: 100vh;
32
31
  }
@@ -35,7 +34,7 @@ export function getDashboardStyles() {
35
34
 
36
35
  .sidebar {
37
36
  width: 220px;
38
- background: var(--bg-card);
37
+ background: var(--card);
39
38
  border-right: 1px solid var(--border);
40
39
  padding: 1.5rem 0;
41
40
  display: flex;
@@ -56,13 +55,13 @@ export function getDashboardStyles() {
56
55
  .sidebar-brand h1 {
57
56
  font-size: 1.125rem;
58
57
  font-weight: 700;
59
- color: var(--accent);
58
+ color: var(--foreground);
60
59
  letter-spacing: -0.02em;
61
60
  }
62
61
 
63
62
  .sidebar-brand .port-badge {
64
63
  font-size: 0.75rem;
65
- color: var(--text-soft);
64
+ color: var(--muted-foreground);
66
65
  margin-top: 0.25rem;
67
66
  }
68
67
 
@@ -71,7 +70,7 @@ export function getDashboardStyles() {
71
70
  .nav-item {
72
71
  display: block;
73
72
  padding: 0.625rem 1.25rem;
74
- color: var(--text-soft);
73
+ color: var(--muted-foreground);
75
74
  text-decoration: none;
76
75
  cursor: pointer;
77
76
  font-size: 0.875rem;
@@ -80,13 +79,13 @@ export function getDashboardStyles() {
80
79
  }
81
80
 
82
81
  .nav-item:hover {
83
- color: var(--text);
84
- background: rgba(255, 255, 255, 0.04);
82
+ color: var(--foreground);
83
+ background: oklch(0.985 0 0 / 0.04);
85
84
  }
86
85
 
87
86
  .nav-item.active {
88
- color: var(--accent);
89
- background: rgba(255, 215, 0, 0.06);
87
+ color: var(--foreground);
88
+ background: oklch(0.588 0.158 241.966 / 0.08);
90
89
  border-left-color: var(--accent);
91
90
  font-weight: 600;
92
91
  }
@@ -105,18 +104,27 @@ export function getDashboardStyles() {
105
104
  letter-spacing: -0.02em;
106
105
  }
107
106
 
107
+ .section-header {
108
+ font-size: 0.75rem;
109
+ font-weight: 600;
110
+ color: var(--muted-foreground);
111
+ text-transform: uppercase;
112
+ letter-spacing: 0.05em;
113
+ margin-bottom: 0.75rem;
114
+ }
115
+
108
116
  .card {
109
- background: var(--bg-card);
117
+ background: var(--card);
110
118
  border: 1px solid var(--border);
111
- border-radius: 0.75rem;
112
- padding: 1.25rem;
119
+ border-radius: 0;
120
+ padding: 1.5rem;
113
121
  margin-bottom: 1rem;
114
122
  }
115
123
 
116
124
  .card-title {
117
- font-size: 0.875rem;
125
+ font-size: 0.75rem;
118
126
  font-weight: 600;
119
- color: var(--text-soft);
127
+ color: var(--muted-foreground);
120
128
  text-transform: uppercase;
121
129
  letter-spacing: 0.05em;
122
130
  margin-bottom: 0.75rem;
@@ -132,33 +140,296 @@ export function getDashboardStyles() {
132
140
  .grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; }
133
141
  .grid-4 { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 1rem; }
134
142
 
135
- .badge {
136
- display: inline-block;
137
- padding: 0.125rem 0.5rem;
138
- border-radius: 9999px;
143
+ /* Metric card (Paperclip pattern) */
144
+ .metric-card {
145
+ background: var(--card);
146
+ border: 1px solid var(--border);
147
+ border-radius: 0;
148
+ padding: 1.5rem;
149
+ cursor: pointer;
150
+ transition: background 0.15s, border-color 0.15s;
151
+ }
152
+
153
+ .metric-card:hover {
154
+ background: oklch(0.588 0.158 241.966 / 0.06);
155
+ border-color: oklch(0.588 0.158 241.966 / 0.2);
156
+ }
157
+
158
+ .metric-value {
159
+ font-size: 1.875rem;
160
+ font-weight: 600;
161
+ letter-spacing: -0.02em;
162
+ line-height: 1;
163
+ }
164
+
165
+ .metric-label {
139
166
  font-size: 0.75rem;
167
+ font-weight: 500;
168
+ color: var(--muted-foreground);
169
+ margin-top: 0.25rem;
170
+ }
171
+
172
+ .metric-description {
173
+ font-size: 0.7rem;
174
+ color: var(--dim);
175
+ margin-top: 0.25rem;
176
+ }
177
+
178
+ /* Chart card */
179
+ .chart-card {
180
+ background: var(--card);
181
+ border: 1px solid var(--border);
182
+ border-radius: 0;
183
+ padding: 1.5rem;
184
+ margin-bottom: 1rem;
185
+ }
186
+
187
+ .chart-card-title {
188
+ font-size: 0.875rem;
140
189
  font-weight: 600;
141
- text-transform: uppercase;
142
- letter-spacing: 0.05em;
190
+ color: var(--foreground);
191
+ }
192
+
193
+ .chart-card-subtitle {
194
+ font-size: 0.75rem;
195
+ color: var(--muted-foreground);
196
+ margin-top: 0.125rem;
143
197
  }
144
198
 
145
- .badge-ok { background: rgba(0, 255, 136, 0.15); color: var(--success); }
146
- .badge-down { background: rgba(255, 68, 68, 0.15); color: var(--error); }
147
- .badge-zombie { background: rgba(255, 68, 68, 0.15); color: var(--error); }
148
- .badge-stale { background: rgba(255, 170, 0, 0.15); color: var(--warning); }
149
- .badge-unknown { background: rgba(148, 163, 184, 0.15); color: var(--text-soft); }
199
+ /* Pure CSS stacked bar chart */
200
+ .stacked-bars {
201
+ display: flex;
202
+ align-items: flex-end;
203
+ gap: 3px;
204
+ height: 5rem;
205
+ }
150
206
 
151
- .badge-feature { background: rgba(79, 195, 247, 0.15); color: var(--info); }
152
- .badge-fix { background: rgba(255, 68, 68, 0.15); color: var(--error); }
153
- .badge-decision { background: rgba(255, 215, 0, 0.15); color: var(--accent); }
154
- .badge-discovery { background: rgba(0, 255, 136, 0.15); color: var(--success); }
155
- .badge-milestone { background: rgba(255, 170, 0, 0.15); color: var(--warning); }
207
+ .stacked-bar {
208
+ display: flex;
209
+ flex-direction: column-reverse;
210
+ gap: 1px;
211
+ min-width: 6px;
212
+ flex: 1;
213
+ }
214
+
215
+ .stacked-bar-segment {
216
+ min-height: 2px;
217
+ border-radius: 1px;
218
+ }
156
219
 
157
- .badge-peter { background: rgba(79, 195, 247, 0.15); color: var(--info); }
158
- .badge-task { background: rgba(0, 255, 136, 0.15); color: var(--success); }
159
- .badge-session { background: rgba(255, 215, 0, 0.15); color: var(--accent); }
160
- .badge-system { background: rgba(148, 163, 184, 0.15); color: var(--text-soft); }
220
+ .stacked-bar-segment-success { background: var(--success); }
221
+ .stacked-bar-segment-error { background: var(--error); }
222
+ .stacked-bar-segment-warning { background: var(--warning); }
223
+
224
+ .stacked-bar-empty {
225
+ background: oklch(0.708 0 0 / 0.2);
226
+ height: 2px;
227
+ border-radius: 1px;
228
+ }
161
229
 
230
+ .stacked-bar-label {
231
+ font-size: 0.6rem;
232
+ color: var(--dim);
233
+ text-align: center;
234
+ margin-top: 0.25rem;
235
+ }
236
+
237
+ /* Activity row with entrance animation */
238
+ .activity-row {
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 0.75rem;
242
+ padding: 0.5rem 0.75rem;
243
+ font-size: 0.875rem;
244
+ transition: background 0.15s;
245
+ border-bottom: 1px solid var(--border);
246
+ }
247
+
248
+ .activity-row:last-child { border-bottom: none; }
249
+
250
+ .activity-row:hover {
251
+ background: oklch(0.588 0.158 241.966 / 0.06);
252
+ }
253
+
254
+ .activity-row-enter {
255
+ animation: activityEnter 0.5s ease-out;
256
+ }
257
+
258
+ @keyframes activityEnter {
259
+ from {
260
+ transform: translateY(-14px) scale(0.985);
261
+ opacity: 0;
262
+ filter: blur(4px);
263
+ }
264
+ to {
265
+ transform: none;
266
+ opacity: 1;
267
+ filter: none;
268
+ }
269
+ }
270
+
271
+ /* Active agent card with blue glow */
272
+ .active-agent-card {
273
+ background: var(--card);
274
+ border: 1px solid var(--border);
275
+ border-radius: 0;
276
+ padding: 1rem;
277
+ transition: border-color 0.15s;
278
+ }
279
+
280
+ .active-agent-card:hover {
281
+ border-color: oklch(0.588 0.158 241.966 / 0.3);
282
+ }
283
+
284
+ .active-agent-card-live {
285
+ border-color: oklch(0.588 0.158 241.966 / 0.3);
286
+ box-shadow: 0 0 12px rgba(59, 130, 246, 0.08);
287
+ }
288
+
289
+ .active-agent-header {
290
+ display: flex;
291
+ justify-content: space-between;
292
+ align-items: center;
293
+ margin-bottom: 0.5rem;
294
+ }
295
+
296
+ .active-agent-task {
297
+ font-size: 0.75rem;
298
+ color: var(--muted-foreground);
299
+ background: oklch(0.588 0.158 241.966 / 0.06);
300
+ border-left: 2px solid var(--accent);
301
+ padding: 0.25rem 0.5rem;
302
+ margin-bottom: 0.5rem;
303
+ border-radius: 0 2px 2px 0;
304
+ }
305
+
306
+ /* Agent run feed (monospace) */
307
+ .run-feed {
308
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
309
+ font-size: 0.6875rem;
310
+ max-height: 140px;
311
+ overflow-y: auto;
312
+ border-top: 1px solid var(--border);
313
+ padding-top: 0.375rem;
314
+ }
315
+
316
+ .run-feed-line {
317
+ display: flex;
318
+ gap: 0.5rem;
319
+ padding: 0.125rem 0;
320
+ align-items: baseline;
321
+ }
322
+
323
+ .run-feed-seq {
324
+ color: var(--dim);
325
+ min-width: 18px;
326
+ flex-shrink: 0;
327
+ }
328
+
329
+ .run-feed-type {
330
+ min-width: 70px;
331
+ flex-shrink: 0;
332
+ font-weight: 600;
333
+ }
334
+
335
+ .run-feed-data {
336
+ color: var(--muted-foreground);
337
+ overflow: hidden;
338
+ text-overflow: ellipsis;
339
+ white-space: nowrap;
340
+ }
341
+
342
+ .feed-line-error { color: var(--error); }
343
+ .feed-line-warn { color: var(--warning); }
344
+ .feed-line-success { color: var(--success); }
345
+ .feed-line-info { color: var(--info); }
346
+ .feed-line-dim { color: var(--dim); }
347
+
348
+ /* Utilization bar */
349
+ .util-bar {
350
+ height: 0.5rem;
351
+ background: oklch(0.269 0 0);
352
+ border-radius: 9999px;
353
+ overflow: hidden;
354
+ }
355
+
356
+ .util-bar-fill {
357
+ height: 100%;
358
+ border-radius: 9999px;
359
+ transition: width 0.3s, background 0.3s;
360
+ }
361
+
362
+ .util-bar-green { background: var(--success); }
363
+ .util-bar-yellow { background: var(--warning); }
364
+ .util-bar-red { background: var(--error); }
365
+
366
+ /* Pulsing dot */
367
+ .pulse-dot {
368
+ position: relative;
369
+ display: inline-flex;
370
+ height: 0.625rem;
371
+ width: 0.625rem;
372
+ }
373
+
374
+ .pulse-dot-ping {
375
+ position: absolute;
376
+ display: inline-flex;
377
+ height: 100%;
378
+ width: 100%;
379
+ border-radius: 9999px;
380
+ opacity: 0.75;
381
+ animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;
382
+ }
383
+
384
+ .pulse-dot-core {
385
+ position: relative;
386
+ display: inline-flex;
387
+ border-radius: 9999px;
388
+ height: 0.625rem;
389
+ width: 0.625rem;
390
+ }
391
+
392
+ @keyframes ping {
393
+ 75%, 100% {
394
+ transform: scale(2);
395
+ opacity: 0;
396
+ }
397
+ }
398
+
399
+ /* Badges */
400
+ .badge {
401
+ display: inline-block;
402
+ padding: 0.1rem 0.4rem;
403
+ border-radius: 9999px;
404
+ font-size: 0.6875rem;
405
+ font-weight: 600;
406
+ text-transform: uppercase;
407
+ letter-spacing: 0.04em;
408
+ }
409
+
410
+ .badge-ok { background: oklch(0.696 0.17 162.48 / 0.12); color: var(--success); }
411
+ .badge-down { background: oklch(0.637 0.237 25.331 / 0.12); color: var(--error); }
412
+ .badge-zombie { background: oklch(0.637 0.237 25.331 / 0.12); color: var(--error); }
413
+ .badge-stale { background: oklch(0.795 0.184 86.047 / 0.12); color: var(--warning); }
414
+ .badge-unknown { background: oklch(0.708 0 0 / 0.12); color: var(--muted-foreground); }
415
+
416
+ .badge-feature { background: oklch(0.588 0.158 241.966 / 0.12); color: var(--info); }
417
+ .badge-fix { background: oklch(0.637 0.237 25.331 / 0.12); color: var(--error); }
418
+ .badge-decision { background: oklch(0.588 0.158 241.966 / 0.12); color: var(--accent); }
419
+ .badge-discovery { background: oklch(0.696 0.17 162.48 / 0.12); color: var(--success); }
420
+ .badge-milestone { background: oklch(0.795 0.184 86.047 / 0.12); color: var(--warning); }
421
+
422
+ .badge-peter { background: oklch(0.588 0.158 241.966 / 0.12); color: var(--info); }
423
+ .badge-task { background: oklch(0.696 0.17 162.48 / 0.12); color: var(--success); }
424
+ .badge-session { background: oklch(0.588 0.158 241.966 / 0.12); color: var(--accent); }
425
+ .badge-system { background: oklch(0.708 0 0 / 0.12); color: var(--muted-foreground); }
426
+
427
+ .badge-gated { background: oklch(0.795 0.184 86.047 / 0.12); color: var(--warning); }
428
+ .badge-completed { background: oklch(0.696 0.17 162.48 / 0.12); color: var(--success); }
429
+ .badge-error { background: oklch(0.637 0.237 25.331 / 0.12); color: var(--error); }
430
+ .badge-approval { background: oklch(0.795 0.184 86.047 / 0.12); color: var(--warning); }
431
+
432
+ /* Tables */
162
433
  table {
163
434
  width: 100%;
164
435
  border-collapse: collapse;
@@ -168,7 +439,7 @@ export function getDashboardStyles() {
168
439
  th {
169
440
  text-align: left;
170
441
  padding: 0.625rem 0.75rem;
171
- color: var(--text-soft);
442
+ color: var(--muted-foreground);
172
443
  font-weight: 600;
173
444
  border-bottom: 1px solid var(--border);
174
445
  font-size: 0.75rem;
@@ -178,28 +449,29 @@ export function getDashboardStyles() {
178
449
 
179
450
  td {
180
451
  padding: 0.625rem 0.75rem;
181
- border-bottom: 1px solid rgba(51, 65, 85, 0.5);
182
- color: var(--text);
452
+ border-bottom: 1px solid var(--border);
453
+ color: var(--foreground);
183
454
  }
184
455
 
185
- tr:hover td { background: rgba(255, 255, 255, 0.02); }
456
+ tr:hover td { background: oklch(0.985 0 0 / 0.02); }
186
457
 
458
+ /* Search input */
187
459
  .search-input {
188
460
  width: 100%;
189
461
  padding: 0.625rem 0.875rem;
190
- background: var(--bg);
462
+ background: var(--background);
191
463
  border: 1px solid var(--border);
192
- border-radius: 0.5rem;
193
- color: var(--text);
464
+ border-radius: 0;
465
+ color: var(--foreground);
194
466
  font-size: 0.875rem;
195
467
  outline: none;
196
468
  transition: border-color 0.15s;
197
469
  }
198
470
 
199
471
  .search-input:focus { border-color: var(--accent); }
472
+ .search-input::placeholder { color: var(--dim); }
200
473
 
201
- .search-input::placeholder { color: var(--text-dim); }
202
-
474
+ /* Live dot */
203
475
  .live-dot {
204
476
  display: inline-block;
205
477
  width: 8px;
@@ -215,30 +487,34 @@ export function getDashboardStyles() {
215
487
  50% { opacity: 0.4; }
216
488
  }
217
489
 
490
+ /* Event row */
218
491
  .event-row {
219
492
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
220
493
  font-size: 0.8rem;
221
494
  }
222
495
 
223
- .event-time { color: var(--text-dim); white-space: nowrap; }
496
+ .event-time { color: var(--dim); white-space: nowrap; }
224
497
 
225
498
  .event-payload {
226
- color: var(--text-soft);
499
+ color: var(--muted-foreground);
227
500
  max-width: 400px;
228
501
  overflow: hidden;
229
502
  text-overflow: ellipsis;
230
503
  white-space: nowrap;
231
504
  }
232
505
 
506
+ /* Stat row */
233
507
  .stat-row {
234
508
  display: flex;
235
509
  justify-content: space-between;
236
510
  padding: 0.375rem 0;
237
511
  font-size: 0.875rem;
512
+ border-bottom: 1px solid var(--border);
238
513
  }
239
514
 
240
- .stat-label { color: var(--text-soft); }
241
- .stat-value { color: var(--text); font-weight: 600; }
515
+ .stat-row:last-child { border-bottom: none; }
516
+ .stat-label { color: var(--muted-foreground); }
517
+ .stat-value { color: var(--foreground); font-weight: 600; }
242
518
 
243
519
  /* Agent status dots */
244
520
  .agent-dot {
@@ -256,7 +532,7 @@ export function getDashboardStyles() {
256
532
  }
257
533
 
258
534
  .agent-dot-idle {
259
- background: var(--text-dim);
535
+ background: var(--dim);
260
536
  }
261
537
 
262
538
  .agent-dot-error {
@@ -272,17 +548,17 @@ export function getDashboardStyles() {
272
548
  border-radius: 4px;
273
549
  text-transform: uppercase;
274
550
  letter-spacing: 0.05em;
275
- background: rgba(255, 215, 0, 0.12);
551
+ background: oklch(0.588 0.158 241.966 / 0.12);
276
552
  color: var(--accent);
277
553
  }
278
554
 
279
- /* Runtime badges (fly, local) */
555
+ /* Runtime badges */
280
556
  .runtime-badge {
281
557
  font-size: 0.6rem;
282
558
  font-weight: 600;
283
559
  padding: 0.1rem 0.375rem;
284
560
  border-radius: 4px;
285
- background: rgba(79, 195, 247, 0.12);
561
+ background: oklch(0.588 0.158 241.966 / 0.12);
286
562
  color: var(--info);
287
563
  text-transform: lowercase;
288
564
  }
@@ -290,14 +566,15 @@ export function getDashboardStyles() {
290
566
  .empty-state {
291
567
  text-align: center;
292
568
  padding: 3rem 1rem;
293
- color: var(--text-dim);
569
+ color: var(--dim);
294
570
  }
295
571
 
296
572
  .empty-state-icon { font-size: 2rem; margin-bottom: 0.75rem; }
297
573
 
574
+ /* Buttons */
298
575
  .btn {
299
576
  padding: 0.5rem 1rem;
300
- border-radius: 0.5rem;
577
+ border-radius: 0;
301
578
  font-size: 0.875rem;
302
579
  font-weight: 600;
303
580
  border: none;
@@ -307,26 +584,44 @@ export function getDashboardStyles() {
307
584
 
308
585
  .btn-primary {
309
586
  background: var(--accent);
310
- color: var(--bg);
587
+ color: var(--background);
311
588
  }
312
589
 
313
- .btn-primary:hover { background: var(--accent-soft); }
590
+ .btn-primary:hover { background: oklch(0.65 0.158 241.966); }
314
591
 
315
592
  .btn-secondary {
316
- background: var(--bg-card);
317
- color: var(--text);
593
+ background: var(--card);
594
+ color: var(--foreground);
318
595
  border: 1px solid var(--border);
319
596
  }
320
597
 
321
- .btn-secondary:hover { background: var(--bg-card-hover); }
598
+ .btn-secondary:hover { background: var(--card-hover); }
599
+
600
+ .btn-ghost {
601
+ background: transparent;
602
+ color: var(--muted-foreground);
603
+ border: 1px solid transparent;
604
+ }
605
+
606
+ .btn-ghost:hover {
607
+ background: oklch(0.985 0 0 / 0.04);
608
+ color: var(--foreground);
609
+ }
610
+
611
+ .btn-ghost.active {
612
+ background: oklch(0.588 0.158 241.966 / 0.08);
613
+ color: var(--foreground);
614
+ border-color: oklch(0.588 0.158 241.966 / 0.2);
615
+ }
322
616
 
617
+ /* Form */
323
618
  .form-group { margin-bottom: 0.75rem; }
324
619
 
325
620
  .form-label {
326
621
  display: block;
327
622
  font-size: 0.75rem;
328
623
  font-weight: 600;
329
- color: var(--text-soft);
624
+ color: var(--muted-foreground);
330
625
  margin-bottom: 0.375rem;
331
626
  }
332
627
 
@@ -360,7 +655,7 @@ export function getDashboardStyles() {
360
655
  align-items: center;
361
656
  justify-content: center;
362
657
  padding: 2rem;
363
- color: var(--text-dim);
658
+ color: var(--dim);
364
659
  }
365
660
 
366
661
  .loading::after {
@@ -380,8 +675,8 @@ export function getDashboardStyles() {
380
675
 
381
676
  /* Journal entries */
382
677
  .journal-entry {
383
- padding: 0.625rem 0;
384
- border-bottom: 1px solid rgba(51, 65, 85, 0.4);
678
+ padding: 0.5rem 0;
679
+ border-bottom: 1px solid var(--border);
385
680
  }
386
681
 
387
682
  .journal-entry:last-child { border-bottom: none; }
@@ -395,7 +690,7 @@ export function getDashboardStyles() {
395
690
  .journal-entry-title {
396
691
  font-size: 0.85rem;
397
692
  font-weight: 600;
398
- color: var(--text);
693
+ color: var(--foreground);
399
694
  flex: 1;
400
695
  overflow: hidden;
401
696
  text-overflow: ellipsis;
@@ -404,14 +699,14 @@ export function getDashboardStyles() {
404
699
 
405
700
  .journal-entry-time {
406
701
  font-size: 0.7rem;
407
- color: var(--text-dim);
702
+ color: var(--dim);
408
703
  white-space: nowrap;
409
704
  flex-shrink: 0;
410
705
  }
411
706
 
412
707
  .journal-entry-content {
413
708
  font-size: 0.75rem;
414
- color: var(--text-soft);
709
+ color: var(--muted-foreground);
415
710
  margin-top: 0.25rem;
416
711
  padding-left: calc(0.5rem + 60px);
417
712
  line-height: 1.5;
@@ -423,7 +718,7 @@ export function getDashboardStyles() {
423
718
  align-items: center;
424
719
  gap: 0.5rem;
425
720
  padding: 0.375rem 0;
426
- border-bottom: 1px solid rgba(51, 65, 85, 0.3);
721
+ border-bottom: 1px solid var(--border);
427
722
  }
428
723
 
429
724
  .knowledge-row:last-child { border-bottom: none; }
@@ -438,20 +733,20 @@ export function getDashboardStyles() {
438
733
  .knowledge-name {
439
734
  font-size: 0.8rem;
440
735
  font-weight: 500;
441
- color: var(--text);
736
+ color: var(--foreground);
442
737
  flex: 1;
443
738
  }
444
739
 
445
740
  .knowledge-words {
446
741
  font-size: 0.7rem;
447
- color: var(--text-dim);
742
+ color: var(--dim);
448
743
  font-family: monospace;
449
744
  }
450
745
 
451
746
  /* Decision rows */
452
747
  .decision-row {
453
748
  padding: 0.5rem 0;
454
- border-bottom: 1px solid rgba(51, 65, 85, 0.3);
749
+ border-bottom: 1px solid var(--border);
455
750
  }
456
751
 
457
752
  .decision-row:last-child { border-bottom: none; }
@@ -464,13 +759,13 @@ export function getDashboardStyles() {
464
759
 
465
760
  .decision-meta {
466
761
  font-size: 0.65rem;
467
- color: var(--text-dim);
762
+ color: var(--dim);
468
763
  margin-top: 0.125rem;
469
764
  }
470
765
 
471
766
  .decision-summary {
472
767
  font-size: 0.7rem;
473
- color: var(--text-soft);
768
+ color: var(--muted-foreground);
474
769
  margin-top: 0.25rem;
475
770
  line-height: 1.4;
476
771
  }
@@ -478,19 +773,337 @@ export function getDashboardStyles() {
478
773
  /* Memory search results */
479
774
  .memory-result {
480
775
  padding: 0.5rem 0;
481
- border-bottom: 1px solid rgba(51, 65, 85, 0.3);
776
+ border-bottom: 1px solid var(--border);
482
777
  }
483
778
 
484
779
  .memory-result:last-child { border-bottom: none; }
485
780
 
781
+ /* Health grid */
782
+ .health-grid {
783
+ display: grid;
784
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
785
+ gap: 1rem;
786
+ }
787
+
788
+ .health-card {
789
+ transition: border-color 0.15s;
790
+ }
791
+
792
+ .health-card:hover {
793
+ border-color: oklch(0.588 0.158 241.966 / 0.2);
794
+ }
795
+
796
+ .health-dot {
797
+ width: 10px;
798
+ height: 10px;
799
+ border-radius: 50%;
800
+ display: inline-block;
801
+ flex-shrink: 0;
802
+ }
803
+
804
+ .health-dot-ok {
805
+ background: var(--success);
806
+ box-shadow: 0 0 6px var(--success);
807
+ }
808
+
809
+ .health-dot-error {
810
+ background: var(--error);
811
+ box-shadow: 0 0 6px var(--error);
812
+ }
813
+
814
+ .health-dot-down {
815
+ background: var(--dim);
816
+ }
817
+
818
+ /* Delta badges */
819
+ .delta-up {
820
+ display: inline-block;
821
+ font-size: 0.75rem;
822
+ font-weight: 700;
823
+ color: var(--success);
824
+ background: oklch(0.696 0.17 162.48 / 0.1);
825
+ padding: 0.1rem 0.375rem;
826
+ border-radius: 4px;
827
+ }
828
+
829
+ .delta-down {
830
+ display: inline-block;
831
+ font-size: 0.75rem;
832
+ font-weight: 700;
833
+ color: var(--error);
834
+ background: oklch(0.637 0.237 25.331 / 0.1);
835
+ padding: 0.1rem 0.375rem;
836
+ border-radius: 4px;
837
+ }
838
+
839
+ .delta-neutral {
840
+ display: inline-block;
841
+ font-size: 0.75rem;
842
+ color: var(--dim);
843
+ padding: 0.1rem 0.375rem;
844
+ }
845
+
846
+ /* Eval chart */
847
+ .eval-chart-container {
848
+ width: 100%;
849
+ overflow: hidden;
850
+ }
851
+
852
+ .eval-chart-container svg {
853
+ width: 100%;
854
+ height: auto;
855
+ }
856
+
857
+ .eval-point circle {
858
+ transition: r 0.15s;
859
+ }
860
+
861
+ .eval-point:hover circle {
862
+ r: 5;
863
+ }
864
+
865
+ .sparkline {
866
+ display: inline-block;
867
+ vertical-align: middle;
868
+ }
869
+
870
+ /* Mode badge */
871
+ .mode-badge {
872
+ display: inline-block;
873
+ font-size: 0.65rem;
874
+ font-weight: 700;
875
+ padding: 0.15rem 0.5rem;
876
+ border-radius: 4px;
877
+ letter-spacing: 0.08em;
878
+ margin-top: 0.375rem;
879
+ }
880
+
881
+ .mode-portfolio {
882
+ background: oklch(0.588 0.158 241.966 / 0.12);
883
+ color: var(--accent);
884
+ }
885
+
886
+ .mode-gtm {
887
+ background: oklch(0.696 0.17 162.48 / 0.12);
888
+ color: var(--success);
889
+ }
890
+
891
+ .mode-service {
892
+ background: oklch(0.588 0.158 241.966 / 0.12);
893
+ color: var(--info);
894
+ }
895
+
896
+ .mode-standalone {
897
+ background: oklch(0.708 0 0 / 0.12);
898
+ color: var(--muted-foreground);
899
+ }
900
+
901
+ /* Scope graph */
902
+ .scope-graph {
903
+ padding: 1.5rem;
904
+ }
905
+
906
+ .scope-node {
907
+ fill: var(--card);
908
+ stroke: var(--border);
909
+ stroke-width: 1.5;
910
+ rx: 0;
911
+ }
912
+
913
+ .scope-node-self {
914
+ stroke: var(--accent);
915
+ stroke-width: 2;
916
+ }
917
+
918
+ .scope-line {
919
+ stroke: var(--border);
920
+ stroke-width: 1.5;
921
+ }
922
+
923
+ .scope-label {
924
+ fill: var(--foreground);
925
+ font-size: 12px;
926
+ font-weight: 600;
927
+ text-anchor: middle;
928
+ }
929
+
930
+ .scope-badge-produces {
931
+ fill: oklch(0.696 0.17 162.48 / 0.15);
932
+ stroke: var(--success);
933
+ }
934
+
935
+ .scope-badge-consumes {
936
+ fill: oklch(0.588 0.158 241.966 / 0.15);
937
+ stroke: var(--info);
938
+ }
939
+
940
+ .scope-badge-denied {
941
+ fill: oklch(0.637 0.237 25.331 / 0.15);
942
+ stroke: var(--error);
943
+ }
944
+
945
+ .scope-badge-text {
946
+ font-size: 9px;
947
+ font-weight: 600;
948
+ text-anchor: middle;
949
+ }
950
+
951
+ /* Agent selector */
952
+ .agent-select {
953
+ padding: 0.5rem 0.75rem;
954
+ background: var(--background);
955
+ border: 1px solid var(--border);
956
+ border-radius: 0;
957
+ color: var(--foreground);
958
+ font-size: 0.875rem;
959
+ outline: none;
960
+ cursor: pointer;
961
+ }
962
+
963
+ .agent-select:focus {
964
+ border-color: var(--accent);
965
+ }
966
+
967
+ /* Cost bar (token split) */
968
+ .cost-bar {
969
+ display: flex;
970
+ height: 8px;
971
+ border-radius: 0;
972
+ overflow: hidden;
973
+ background: var(--border);
974
+ min-width: 80px;
975
+ }
976
+
977
+ .cost-bar-prompt {
978
+ background: var(--info);
979
+ height: 100%;
980
+ transition: width 0.3s;
981
+ }
982
+
983
+ .cost-bar-completion {
984
+ background: var(--accent);
985
+ height: 100%;
986
+ transition: width 0.3s;
987
+ }
988
+
989
+ .cost-bar-empty {
990
+ width: 100%;
991
+ text-align: center;
992
+ font-size: 0.6rem;
993
+ color: var(--dim);
994
+ line-height: 8px;
995
+ }
996
+
997
+ /* Success rate bar */
998
+ .success-bar {
999
+ position: relative;
1000
+ height: 8px;
1001
+ border-radius: 9999px;
1002
+ background: var(--border);
1003
+ overflow: hidden;
1004
+ min-width: 60px;
1005
+ }
1006
+
1007
+ .success-bar-fill {
1008
+ height: 100%;
1009
+ border-radius: 9999px;
1010
+ transition: width 0.3s;
1011
+ }
1012
+
1013
+ .success-bar-label {
1014
+ position: absolute;
1015
+ right: -30px;
1016
+ top: -3px;
1017
+ font-size: 0.65rem;
1018
+ color: var(--muted-foreground);
1019
+ font-weight: 600;
1020
+ }
1021
+
1022
+ /* Utilization ring */
1023
+ .util-ring {
1024
+ display: inline-flex;
1025
+ align-items: center;
1026
+ justify-content: center;
1027
+ }
1028
+
1029
+ /* Tab group */
1030
+ .tab-group {
1031
+ display: flex;
1032
+ gap: 0.25rem;
1033
+ border-bottom: 1px solid var(--border);
1034
+ padding-bottom: 0;
1035
+ }
1036
+
1037
+ .tab-btn {
1038
+ padding: 0.5rem 1rem;
1039
+ background: none;
1040
+ border: none;
1041
+ border-bottom: 2px solid transparent;
1042
+ color: var(--muted-foreground);
1043
+ font-size: 0.875rem;
1044
+ font-weight: 600;
1045
+ cursor: pointer;
1046
+ transition: all 0.15s;
1047
+ margin-bottom: -1px;
1048
+ }
1049
+
1050
+ .tab-btn:hover {
1051
+ color: var(--foreground);
1052
+ }
1053
+
1054
+ .tab-btn-active {
1055
+ color: var(--foreground);
1056
+ border-bottom-color: var(--accent);
1057
+ }
1058
+
1059
+ /* Approve/reject buttons */
1060
+ .btn-approve {
1061
+ padding: 0.375rem 1rem;
1062
+ border-radius: 0;
1063
+ font-size: 0.8rem;
1064
+ font-weight: 700;
1065
+ border: none;
1066
+ cursor: pointer;
1067
+ background: var(--success);
1068
+ color: var(--background);
1069
+ transition: all 0.15s;
1070
+ }
1071
+
1072
+ .btn-approve:hover {
1073
+ background: oklch(0.75 0.17 162.48);
1074
+ }
1075
+
1076
+ .btn-reject {
1077
+ padding: 0.375rem 1rem;
1078
+ border-radius: 0;
1079
+ font-size: 0.8rem;
1080
+ font-weight: 700;
1081
+ border: none;
1082
+ cursor: pointer;
1083
+ background: var(--error);
1084
+ color: var(--background);
1085
+ transition: all 0.15s;
1086
+ }
1087
+
1088
+ .btn-reject:hover {
1089
+ background: oklch(0.7 0.237 25.331);
1090
+ }
1091
+
1092
+ /* Divide-y pattern for lists */
1093
+ .divide-y > * + * {
1094
+ border-top: 1px solid var(--border);
1095
+ }
1096
+
486
1097
  @media (max-width: 768px) {
487
1098
  .sidebar { width: 60px; padding: 1rem 0; }
488
1099
  .sidebar-brand h1 { display: none; }
489
1100
  .sidebar-brand .port-badge { display: none; }
1101
+ .sidebar-brand .mode-badge { display: none; }
490
1102
  .nav-item { padding: 0.625rem; text-align: center; font-size: 0; }
491
1103
  .nav-item::before { font-size: 1rem; }
492
1104
  .main-content { margin-left: 60px; padding: 1rem; }
493
1105
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
1106
+ .health-grid { grid-template-columns: 1fr; }
494
1107
  }
495
1108
  `;
496
1109
  }