agentflow-dashboard 0.2.0 → 0.3.1

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.
@@ -4,386 +4,1338 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>AgentFlow Dashboard</title>
7
+ <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
8
+ <meta http-equiv="Pragma" content="no-cache">
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"></script>
7
10
  <style>
8
- * {
9
- margin: 0;
10
- padding: 0;
11
- box-sizing: border-box;
11
+ :root {
12
+ --bg-primary: #0d1117;
13
+ --bg-secondary: #161b22;
14
+ --bg-tertiary: #21262d;
15
+ --text-primary: #c9d1d9;
16
+ --text-secondary: #8b949e;
17
+ --accent-primary: #58a6ff;
18
+ --accent-success: #238636;
19
+ --accent-error: #da3633;
20
+ --accent-warning: #f0883e;
21
+ --border-color: #30363d;
12
22
  }
13
23
 
24
+ * { margin: 0; padding: 0; box-sizing: border-box; }
25
+
14
26
  body {
15
27
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16
- background: #0f1419;
17
- color: #e6e6e6;
18
- line-height: 1.6;
28
+ background: var(--bg-primary);
29
+ color: var(--text-primary);
30
+ min-height: 100vh;
31
+ overflow: hidden;
19
32
  }
20
33
 
34
+ /* Header */
21
35
  .header {
22
- background: #1a1f2e;
23
- padding: 1rem 2rem;
24
- border-bottom: 1px solid #2a2f3e;
36
+ background: var(--bg-secondary);
37
+ border-bottom: 1px solid var(--border-color);
38
+ padding: 0.75rem 1.5rem;
39
+ display: flex;
40
+ justify-content: space-between;
41
+ align-items: center;
42
+ height: 56px;
43
+ z-index: 100;
25
44
  }
26
-
27
45
  .header h1 {
28
- color: #4f96ff;
29
- font-size: 1.5rem;
46
+ font-size: 1.35rem;
30
47
  font-weight: 600;
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 0.5rem;
31
51
  }
32
-
33
- .header .subtitle {
34
- color: #9ca3af;
35
- font-size: 0.9rem;
36
- margin-top: 0.25rem;
52
+ .header h1 span { color: var(--accent-primary); }
53
+ .header-right {
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 1rem;
37
57
  }
38
-
39
- .main {
40
- display: grid;
41
- grid-template-columns: 1fr 2fr;
42
- height: calc(100vh - 80px);
58
+ .connection-status {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 0.5rem;
62
+ font-size: 0.8rem;
63
+ color: var(--text-secondary);
43
64
  }
44
-
45
- .sidebar {
46
- background: #1a1f2e;
47
- border-right: 1px solid #2a2f3e;
48
- padding: 1rem;
49
- overflow-y: auto;
65
+ .status-dot {
66
+ width: 8px;
67
+ height: 8px;
68
+ border-radius: 50%;
69
+ background: var(--accent-error);
70
+ transition: background 0.3s;
50
71
  }
51
-
52
- .content {
53
- padding: 1rem;
54
- overflow-y: auto;
72
+ .status-dot.connected {
73
+ background: var(--accent-success);
74
+ animation: pulse 2s infinite;
55
75
  }
56
-
57
- .stats-grid {
58
- display: grid;
59
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
60
- gap: 1rem;
61
- margin-bottom: 2rem;
76
+ @keyframes pulse {
77
+ 0%, 100% { opacity: 1; }
78
+ 50% { opacity: 0.5; }
62
79
  }
63
80
 
64
- .stat-card {
65
- background: #1a1f2e;
66
- border: 1px solid #2a2f3e;
67
- border-radius: 8px;
68
- padding: 1rem;
81
+ /* Layout */
82
+ .container {
83
+ display: flex;
84
+ height: calc(100vh - 56px);
69
85
  }
70
86
 
71
- .stat-card h3 {
72
- font-size: 0.8rem;
73
- color: #9ca3af;
87
+ /* Sidebar */
88
+ .sidebar {
89
+ width: 280px;
90
+ min-width: 280px;
91
+ background: var(--bg-secondary);
92
+ border-right: 1px solid var(--border-color);
93
+ display: flex;
94
+ flex-direction: column;
95
+ overflow: hidden;
96
+ }
97
+ .sidebar-header {
98
+ padding: 0.75rem 1rem;
99
+ border-bottom: 1px solid var(--border-color);
100
+ }
101
+ .sidebar-header h3 {
102
+ font-size: 0.75rem;
74
103
  text-transform: uppercase;
104
+ letter-spacing: 0.5px;
105
+ color: var(--text-secondary);
75
106
  margin-bottom: 0.5rem;
76
107
  }
108
+ .search-box {
109
+ position: relative;
110
+ }
111
+ .search-box input {
112
+ width: 100%;
113
+ padding: 0.5rem 0.75rem;
114
+ padding-left: 2rem;
115
+ background: var(--bg-tertiary);
116
+ border: 1px solid var(--border-color);
117
+ border-radius: 6px;
118
+ color: var(--text-primary);
119
+ font-size: 0.8rem;
120
+ outline: none;
121
+ }
122
+ .search-box input:focus {
123
+ border-color: var(--accent-primary);
124
+ }
125
+ .search-box::before {
126
+ content: "\1F50D";
127
+ position: absolute;
128
+ left: 0.5rem;
129
+ top: 50%;
130
+ transform: translateY(-50%);
131
+ font-size: 0.75rem;
132
+ opacity: 0.5;
133
+ }
77
134
 
78
- .stat-card .value {
79
- font-size: 1.8rem;
80
- font-weight: 700;
81
- color: #4f96ff;
135
+ /* Sidebar filters */
136
+ .sidebar-filters {
137
+ padding: 0.5rem 1rem;
138
+ border-bottom: 1px solid var(--border-color);
139
+ display: flex;
140
+ flex-direction: column;
141
+ gap: 0.5rem;
142
+ }
143
+ .filter-row {
144
+ display: flex;
145
+ gap: 0.5rem;
146
+ }
147
+ .filter-group {
148
+ flex: 1;
149
+ }
150
+ .filter-group label {
151
+ display: block;
152
+ font-size: 0.65rem;
153
+ color: var(--text-secondary);
154
+ margin-bottom: 0.15rem;
155
+ text-transform: uppercase;
156
+ letter-spacing: 0.5px;
157
+ }
158
+ .filter-group select {
159
+ width: 100%;
160
+ padding: 0.25rem 0.4rem;
161
+ background: var(--bg-tertiary);
162
+ border: 1px solid var(--border-color);
163
+ border-radius: 4px;
164
+ color: var(--text-primary);
165
+ font-size: 0.75rem;
166
+ outline: none;
167
+ }
168
+ .filter-group select:focus {
169
+ border-color: var(--accent-primary);
82
170
  }
83
171
 
84
- .agent-list {
85
- margin-bottom: 2rem;
172
+ /* Trace list */
173
+ .trace-list {
174
+ flex: 1;
175
+ overflow-y: auto;
176
+ padding: 0.25rem 0;
86
177
  }
178
+ .trace-list::-webkit-scrollbar { width: 6px; }
179
+ .trace-list::-webkit-scrollbar-track { background: transparent; }
180
+ .trace-list::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 3px; }
87
181
 
88
- .agent-item {
89
- background: #262b3d;
90
- border: 1px solid #363b4d;
91
- border-radius: 6px;
92
- padding: 1rem;
93
- margin-bottom: 0.5rem;
182
+ .session-item {
183
+ padding: 0.6rem 1rem;
94
184
  cursor: pointer;
95
- transition: all 0.2s;
185
+ border-left: 3px solid transparent;
186
+ border-bottom: 1px solid rgba(48, 54, 61, 0.5);
187
+ transition: all 0.15s;
96
188
  }
97
-
98
- .agent-item:hover {
99
- border-color: #4f96ff;
100
- background: #2a2f3e;
189
+ .session-item:hover {
190
+ background: var(--bg-tertiary);
101
191
  }
102
-
103
- .agent-item.active {
104
- border-color: #4f96ff;
105
- background: #2a2f3e;
192
+ .session-item.active {
193
+ background: var(--bg-tertiary);
194
+ border-left-color: var(--accent-primary);
106
195
  }
107
-
108
- .agent-name {
109
- font-weight: 600;
110
- color: #e6e6e6;
111
- margin-bottom: 0.25rem;
196
+ .session-id {
197
+ font-size: 0.8rem;
198
+ font-weight: 500;
199
+ white-space: nowrap;
200
+ overflow: hidden;
201
+ text-overflow: ellipsis;
202
+ margin-bottom: 0.2rem;
112
203
  }
113
-
114
- .agent-stats {
204
+ .session-meta {
115
205
  display: flex;
116
206
  justify-content: space-between;
117
- font-size: 0.8rem;
118
- color: #9ca3af;
207
+ align-items: center;
208
+ font-size: 0.7rem;
209
+ color: var(--text-secondary);
210
+ gap: 0.5rem;
119
211
  }
120
-
121
- .success-rate {
122
- color: #10b981;
212
+ .session-agent {
213
+ color: var(--accent-primary);
214
+ white-space: nowrap;
215
+ overflow: hidden;
216
+ text-overflow: ellipsis;
123
217
  }
124
218
 
125
- .success-rate.low {
126
- color: #f59e0b;
219
+ .badge {
220
+ display: inline-flex;
221
+ align-items: center;
222
+ padding: 0.1rem 0.45rem;
223
+ border-radius: 12px;
224
+ font-size: 0.65rem;
225
+ font-weight: 500;
226
+ flex-shrink: 0;
127
227
  }
128
-
129
- .success-rate.critical {
130
- color: #ef4444;
228
+ .badge-success {
229
+ background: rgba(35, 134, 54, 0.2);
230
+ color: #3fb950;
131
231
  }
132
-
133
- .traces-section {
134
- margin-bottom: 2rem;
232
+ .badge-error {
233
+ background: rgba(218, 54, 51, 0.2);
234
+ color: #f85149;
235
+ }
236
+ .badge-running {
237
+ background: rgba(88, 166, 255, 0.2);
238
+ color: var(--accent-primary);
239
+ }
240
+ .badge-unknown {
241
+ background: rgba(139, 148, 158, 0.2);
242
+ color: var(--text-secondary);
135
243
  }
136
244
 
137
- .section-title {
138
- font-size: 1.2rem;
245
+ /* Node type badges */
246
+ .badge-type {
247
+ font-size: 0.6rem;
248
+ padding: 0.05rem 0.35rem;
249
+ border-radius: 8px;
139
250
  font-weight: 600;
140
- margin-bottom: 1rem;
141
- color: #e6e6e6;
251
+ letter-spacing: 0.02em;
252
+ }
253
+ .badge-agent {
254
+ background: rgba(88, 166, 255, 0.15);
255
+ color: #79b8ff;
256
+ }
257
+ .badge-tool {
258
+ background: rgba(240, 136, 62, 0.15);
259
+ color: #f0883e;
260
+ }
261
+ .badge-subagent {
262
+ background: rgba(188, 140, 255, 0.15);
263
+ color: #bc8cff;
264
+ }
265
+ .badge-other, .badge-custom, .badge-wait, .badge-decision, .badge-exec {
266
+ background: rgba(139, 148, 158, 0.15);
267
+ color: #8b949e;
268
+ }
269
+ .badge-unknown {
270
+ background: rgba(139, 148, 158, 0.1);
271
+ color: #6e7681;
142
272
  }
143
273
 
144
- .trace-item {
145
- background: #1a1f2e;
146
- border: 1px solid #2a2f3e;
147
- border-radius: 6px;
148
- padding: 1rem;
149
- margin-bottom: 0.75rem;
274
+ .trace-count-badge {
275
+ padding: 0.5rem 1rem;
276
+ font-size: 0.75rem;
277
+ color: var(--text-secondary);
278
+ border-top: 1px solid var(--border-color);
279
+ background: var(--bg-secondary);
280
+ text-align: center;
150
281
  }
151
282
 
152
- .trace-header {
283
+ /* Main content */
284
+ .main-content {
285
+ flex: 1;
153
286
  display: flex;
154
- justify-content: space-between;
155
- align-items: center;
156
- margin-bottom: 0.5rem;
287
+ flex-direction: column;
288
+ overflow: hidden;
289
+ min-width: 0;
157
290
  }
158
291
 
159
- .trace-name {
160
- font-weight: 600;
161
- color: #e6e6e6;
292
+ /* Stats overview */
293
+ .stats-overview {
294
+ display: grid;
295
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
296
+ gap: 0.75rem;
297
+ padding: 0.75rem 1rem;
298
+ border-bottom: 1px solid var(--border-color);
299
+ background: var(--bg-secondary);
300
+ }
301
+ .stat-card-mini {
302
+ padding: 0.4rem 0.6rem;
162
303
  }
304
+ .stat-card-mini .metric-label { font-size: 0.65rem; margin-bottom: 0.15rem; }
305
+ .stat-card-mini .metric-value { font-size: 1.2rem; }
163
306
 
164
- .trace-timestamp {
307
+ /* Tabs */
308
+ .tabs {
309
+ display: flex;
310
+ background: var(--bg-secondary);
311
+ border-bottom: 1px solid var(--border-color);
312
+ padding: 0 1rem;
313
+ gap: 0;
314
+ overflow-x: auto;
315
+ }
316
+ .tab {
317
+ padding: 0.7rem 1rem;
165
318
  font-size: 0.8rem;
166
- color: #9ca3af;
319
+ color: var(--text-secondary);
320
+ cursor: pointer;
321
+ border-bottom: 2px solid transparent;
322
+ transition: all 0.15s;
323
+ white-space: nowrap;
324
+ user-select: none;
325
+ }
326
+ .tab:hover { color: var(--text-primary); }
327
+ .tab.active {
328
+ color: var(--accent-primary);
329
+ border-bottom-color: var(--accent-primary);
167
330
  }
168
331
 
169
- .trace-details {
332
+ /* Toolbar */
333
+ .toolbar {
170
334
  display: flex;
171
335
  justify-content: space-between;
336
+ align-items: center;
337
+ padding: 0.5rem 1rem;
338
+ background: var(--bg-secondary);
339
+ border-bottom: 1px solid var(--border-color);
340
+ min-height: 40px;
341
+ }
342
+ .toolbar-group {
343
+ display: flex;
344
+ gap: 0.5rem;
345
+ align-items: center;
346
+ }
347
+ .toolbar-info {
348
+ font-size: 0.75rem;
349
+ color: var(--text-secondary);
350
+ }
351
+ .btn {
352
+ padding: 0.3rem 0.7rem;
353
+ border-radius: 6px;
172
354
  font-size: 0.8rem;
355
+ cursor: pointer;
356
+ border: 1px solid var(--border-color);
357
+ background: var(--bg-tertiary);
358
+ color: var(--text-primary);
359
+ transition: all 0.15s;
360
+ white-space: nowrap;
173
361
  }
174
-
175
- .trace-agent {
176
- color: #4f96ff;
362
+ .btn:hover {
363
+ border-color: var(--accent-primary);
364
+ background: rgba(88, 166, 255, 0.1);
365
+ }
366
+ .btn-primary {
367
+ background: var(--accent-primary);
368
+ color: #fff;
369
+ border-color: var(--accent-primary);
370
+ }
371
+ .btn-primary:hover { background: #79b8ff; }
372
+ .btn-icon {
373
+ padding: 0.3rem;
177
374
  }
178
375
 
179
- .trace-trigger {
180
- color: #9ca3af;
376
+ .live-indicator {
377
+ display: flex;
378
+ align-items: center;
379
+ gap: 0.4rem;
380
+ font-size: 0.8rem;
381
+ color: var(--text-secondary);
382
+ }
383
+ .live-indicator.active {
384
+ color: var(--accent-error);
385
+ }
386
+ .live-indicator .live-dot {
387
+ font-size: 0.7rem;
181
388
  }
182
389
 
183
- .status-indicator {
184
- width: 8px;
185
- height: 8px;
186
- border-radius: 50%;
187
- display: inline-block;
188
- margin-right: 0.5rem;
390
+ /* Alert Panel */
391
+ .alert-panel {
392
+ background: rgba(218, 54, 51, 0.1);
393
+ border: 1px solid var(--accent-error);
394
+ border-radius: 0;
395
+ padding: 0.75rem 1rem;
396
+ display: none;
397
+ font-size: 0.8rem;
398
+ }
399
+ .alert-panel.show {
400
+ display: block;
401
+ }
402
+ .alert-panel ul {
403
+ margin: 0.3rem 0 0 1.2rem;
404
+ font-size: 0.75rem;
189
405
  }
190
406
 
191
- .status-success {
192
- background: #10b981;
407
+ /* Content area */
408
+ .content-area {
409
+ flex: 1;
410
+ overflow: auto;
411
+ position: relative;
412
+ }
413
+ .tab-panel {
414
+ display: none;
415
+ height: 100%;
416
+ }
417
+ .tab-panel.active {
418
+ display: flex;
419
+ flex-direction: column;
193
420
  }
194
421
 
195
- .status-failure {
196
- background: #ef4444;
422
+ /* Graph */
423
+ #cy {
424
+ flex: 1;
425
+ min-height: 0;
426
+ background: var(--bg-primary);
197
427
  }
198
428
 
199
- .status-unknown {
200
- background: #6b7280;
429
+ /* Empty / placeholder states */
430
+ .empty-state {
431
+ display: flex;
432
+ flex-direction: column;
433
+ align-items: center;
434
+ justify-content: center;
435
+ height: 100%;
436
+ color: var(--text-secondary);
437
+ gap: 0.75rem;
438
+ padding: 2rem;
439
+ }
440
+ .empty-state-icon {
441
+ font-size: 2.5rem;
442
+ opacity: 0.4;
443
+ }
444
+ .empty-state-title {
445
+ font-size: 1.1rem;
446
+ font-weight: 500;
447
+ color: var(--text-primary);
448
+ }
449
+ .empty-state-text {
450
+ font-size: 0.85rem;
451
+ text-align: center;
452
+ max-width: 360px;
201
453
  }
202
454
 
203
- .connection-status {
204
- position: fixed;
455
+ /* Node detail panel */
456
+ .node-detail-panel {
457
+ position: absolute;
205
458
  top: 1rem;
206
459
  right: 1rem;
207
- padding: 0.5rem 1rem;
208
- border-radius: 6px;
460
+ width: 320px;
461
+ background: var(--bg-secondary);
462
+ border: 1px solid var(--border-color);
463
+ border-radius: 8px;
464
+ z-index: 50;
465
+ display: none;
466
+ box-shadow: 0 8px 32px rgba(0,0,0,0.4);
467
+ max-height: calc(100% - 2rem);
468
+ overflow-y: auto;
469
+ }
470
+ .node-detail-panel.active { display: block; }
471
+ .node-detail-header {
472
+ display: flex;
473
+ justify-content: space-between;
474
+ align-items: center;
475
+ padding: 0.75rem 1rem;
476
+ border-bottom: 1px solid var(--border-color);
477
+ }
478
+ .node-detail-header h4 { font-size: 0.9rem; }
479
+ .node-detail-close {
480
+ background: none;
481
+ border: none;
482
+ color: var(--text-secondary);
483
+ cursor: pointer;
484
+ font-size: 1.2rem;
485
+ padding: 0.25rem;
486
+ line-height: 1;
487
+ }
488
+ .node-detail-close:hover { color: var(--text-primary); }
489
+ .node-detail-body { padding: 0.75rem 1rem; }
490
+ .detail-row {
491
+ display: flex;
492
+ justify-content: space-between;
493
+ align-items: flex-start;
494
+ padding: 0.4rem 0;
495
+ border-bottom: 1px solid rgba(48, 54, 61, 0.4);
209
496
  font-size: 0.8rem;
210
- font-weight: 600;
211
497
  }
212
-
213
- .connected {
214
- background: #065f46;
215
- color: #10b981;
498
+ .detail-row:last-child { border-bottom: none; }
499
+ .detail-label { color: var(--text-secondary); min-width: 80px; }
500
+ .detail-value {
501
+ color: var(--text-primary);
502
+ text-align: right;
503
+ word-break: break-all;
504
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
505
+ font-size: 0.75rem;
506
+ }
507
+ .detail-value.status-completed { color: var(--accent-success); }
508
+ .detail-value.status-failed { color: var(--accent-error); }
509
+ .detail-value.status-running { color: var(--accent-primary); }
510
+ .detail-value.status-hung { color: var(--accent-warning); }
511
+ .detail-value.status-timeout { color: var(--accent-warning); }
512
+ .detail-metadata {
513
+ margin-top: 0.5rem;
514
+ padding: 0.5rem;
515
+ background: var(--bg-tertiary);
516
+ border-radius: 4px;
517
+ font-size: 0.7rem;
518
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
519
+ color: var(--text-secondary);
520
+ max-height: 200px;
521
+ overflow-y: auto;
522
+ white-space: pre-wrap;
523
+ word-break: break-all;
216
524
  }
217
525
 
218
- .disconnected {
219
- background: #7f1d1d;
220
- color: #ef4444;
526
+ /* Timeline view */
527
+ .timeline-container {
528
+ padding: 1rem;
529
+ overflow-y: auto;
530
+ flex: 1;
221
531
  }
532
+ .timeline-item {
533
+ display: flex;
534
+ margin-bottom: 0.75rem;
535
+ padding: 0.75rem 1rem;
536
+ background: var(--bg-secondary);
537
+ border: 1px solid var(--border-color);
538
+ border-radius: 8px;
539
+ transition: all 0.2s;
540
+ }
541
+ .timeline-item:hover {
542
+ border-color: var(--accent-primary);
543
+ }
544
+ .timeline-marker {
545
+ width: 12px;
546
+ height: 12px;
547
+ border-radius: 50%;
548
+ margin-right: 1rem;
549
+ flex-shrink: 0;
550
+ margin-top: 0.2rem;
551
+ }
552
+ .timeline-marker.agent { background: var(--accent-primary); }
553
+ .timeline-marker.tool { background: var(--accent-warning); }
554
+ .timeline-marker.subagent { background: #a371f7; }
555
+ .timeline-marker.completed { background: var(--accent-success); }
556
+ .timeline-marker.failed { background: var(--accent-error); }
557
+ .timeline-marker.running { background: var(--accent-primary); }
558
+ .timeline-marker.hung, .timeline-marker.timeout { background: var(--accent-warning); }
222
559
 
223
- .loading {
224
- text-align: center;
225
- padding: 2rem;
226
- color: #9ca3af;
560
+ .timeline-content {
561
+ flex: 1;
562
+ min-width: 0;
563
+ }
564
+ .timeline-header {
565
+ display: flex;
566
+ justify-content: space-between;
567
+ margin-bottom: 0.35rem;
568
+ }
569
+ .event-type {
570
+ font-weight: 500;
571
+ font-size: 0.85rem;
572
+ }
573
+ .event-time {
574
+ font-size: 0.7rem;
575
+ color: var(--text-secondary);
576
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
577
+ }
578
+ .event-details {
579
+ font-size: 0.8rem;
580
+ color: var(--text-secondary);
581
+ }
582
+ .event-duration {
583
+ display: inline-block;
584
+ margin-top: 0.25rem;
585
+ font-size: 0.7rem;
586
+ padding: 0.1rem 0.4rem;
587
+ background: var(--bg-tertiary);
588
+ border-radius: 4px;
589
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
590
+ color: var(--text-secondary);
227
591
  }
228
592
 
229
- .process-health {
593
+ /* Metrics view */
594
+ .metrics-container {
595
+ padding: 1rem;
596
+ overflow-y: auto;
597
+ flex: 1;
598
+ }
599
+ .metrics-grid {
600
+ display: grid;
601
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
602
+ gap: 1rem;
230
603
  margin-bottom: 1.5rem;
231
604
  }
232
-
233
- .process-health-card {
234
- background: #1a1f2e;
235
- border: 1px solid #2a2f3e;
605
+ .metric-card {
606
+ background: var(--bg-secondary);
607
+ border: 1px solid var(--border-color);
236
608
  border-radius: 8px;
237
609
  padding: 1rem 1.25rem;
238
- margin-bottom: 0.75rem;
610
+ }
611
+ .metric-label {
612
+ font-size: 0.7rem;
613
+ text-transform: uppercase;
614
+ letter-spacing: 0.5px;
615
+ color: var(--text-secondary);
616
+ margin-bottom: 0.4rem;
617
+ }
618
+ .metric-value {
619
+ font-size: 1.75rem;
620
+ font-weight: 700;
621
+ }
622
+ .metric-value.primary { color: var(--accent-primary); }
623
+ .metric-value.success { color: var(--accent-success); }
624
+ .metric-value.error { color: var(--accent-error); }
625
+ .metric-value.warning { color: var(--accent-warning); }
626
+ .metric-sub {
627
+ font-size: 0.7rem;
628
+ color: var(--text-secondary);
629
+ margin-top: 0.2rem;
239
630
  }
240
631
 
241
- .process-health-card h4 {
242
- font-size: 0.85rem;
243
- color: #9ca3af;
632
+ /* Process health */
633
+ .process-health-section {
634
+ padding: 0.75rem 1rem;
635
+ border-bottom: 1px solid var(--border-color);
636
+ background: var(--bg-secondary);
637
+ }
638
+ .process-health-section h4 {
639
+ font-size: 0.7rem;
244
640
  text-transform: uppercase;
245
- margin-bottom: 0.75rem;
246
641
  letter-spacing: 0.05em;
642
+ color: var(--text-secondary);
643
+ margin-bottom: 0.5rem;
247
644
  }
248
-
249
645
  .ph-row {
250
646
  display: flex;
251
647
  align-items: center;
252
- gap: 1rem;
253
- margin-bottom: 0.5rem;
254
- font-size: 0.85rem;
648
+ gap: 0.75rem;
649
+ margin-bottom: 0.35rem;
650
+ font-size: 0.75rem;
255
651
  }
256
-
257
652
  .ph-label {
258
- color: #9ca3af;
259
- min-width: 100px;
653
+ color: var(--text-secondary);
654
+ min-width: 70px;
260
655
  }
261
-
262
656
  .ph-value {
263
- color: #e6e6e6;
264
- font-family: 'SF Mono', 'Fira Code', monospace;
657
+ color: var(--text-primary);
658
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
659
+ font-size: 0.75rem;
660
+ }
661
+ .ph-value.ok { color: var(--accent-success); }
662
+ .ph-value.warn { color: var(--accent-warning); }
663
+ .ph-value.bad { color: var(--accent-error); }
664
+ .worker-dots { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
665
+ .worker-dot {
666
+ width: 8px;
667
+ height: 8px;
668
+ border-radius: 50%;
669
+ }
670
+ .worker-dot.alive { background: var(--accent-success); }
671
+ .worker-dot.stale { background: var(--accent-error); }
672
+ .worker-dot.unknown { background: var(--text-secondary); }
673
+ .worker-dot-label { font-size: 0.65rem; color: var(--text-secondary); margin-left: 1px; }
674
+ .orphan-table {
675
+ width: 100%;
676
+ border-collapse: collapse;
677
+ font-size: 0.7rem;
678
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
679
+ margin-top: 0.5rem;
680
+ }
681
+ .orphan-table th {
682
+ text-align: left;
683
+ color: var(--text-secondary);
684
+ font-weight: 500;
685
+ padding: 0.3rem 0.5rem;
686
+ border-bottom: 1px solid var(--border-color);
687
+ }
688
+ .orphan-table td {
689
+ padding: 0.25rem 0.5rem;
690
+ color: var(--text-primary);
691
+ border-bottom: 1px solid rgba(48,54,61,0.4);
692
+ white-space: nowrap;
693
+ overflow: hidden;
694
+ text-overflow: ellipsis;
695
+ max-width: 250px;
696
+ }
697
+ .orphan-table tr:hover td { background: var(--bg-tertiary); }
698
+ .problems-list {
699
+ list-style: none;
700
+ padding: 0;
701
+ margin: 0.3rem 0 0 0;
702
+ }
703
+ .problems-list li {
704
+ font-size: 0.7rem;
705
+ color: var(--accent-error);
706
+ padding: 0.15rem 0;
707
+ }
708
+ .problems-list li::before {
709
+ content: "\2022";
710
+ margin-right: 0.4rem;
265
711
  }
266
712
 
267
- .ph-value.ok { color: #10b981; }
268
- .ph-value.warn { color: #f59e0b; }
269
- .ph-value.bad { color: #ef4444; }
713
+ /* Enhanced Process Health */
714
+ .ph-section {
715
+ margin-bottom: 1rem;
716
+ }
717
+ .process-grid {
718
+ display: grid;
719
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
720
+ gap: 0.4rem;
721
+ margin-top: 0.5rem;
722
+ }
270
723
 
271
- .worker-dots {
724
+ /* Worker cards */
725
+ .worker-card {
726
+ background: var(--bg-tertiary);
727
+ border-radius: 4px;
728
+ padding: 0.5rem;
729
+ border-left: 3px solid var(--border-color);
730
+ }
731
+ .worker-card.ok { border-left-color: var(--accent-success); }
732
+ .worker-card.warn { border-left-color: var(--accent-warning); }
733
+ .worker-card.bad { border-left-color: var(--accent-error); }
734
+ .worker-name {
735
+ font-weight: 600;
736
+ font-size: 0.75rem;
737
+ margin-bottom: 0.25rem;
738
+ }
739
+ .worker-details {
272
740
  display: flex;
273
- gap: 6px;
274
- align-items: center;
275
- flex-wrap: wrap;
741
+ flex-direction: column;
742
+ gap: 0.1rem;
743
+ font-size: 0.65rem;
744
+ color: var(--text-secondary);
276
745
  }
277
746
 
278
- .worker-dot {
279
- width: 10px;
280
- height: 10px;
281
- border-radius: 50%;
282
- display: inline-block;
283
- position: relative;
747
+ /* Service cards */
748
+ .service-card, .infra-card {
749
+ background: var(--bg-tertiary);
750
+ border-radius: 4px;
751
+ padding: 0.5rem;
752
+ border-left: 3px solid var(--border-color);
284
753
  }
285
-
286
- .worker-dot.alive { background: #10b981; }
287
- .worker-dot.stale { background: #ef4444; }
288
- .worker-dot.unknown { background: #6b7280; }
289
-
290
- .worker-dot-label {
754
+ .service-card.low, .infra-card.low { border-left-color: var(--accent-success); }
755
+ .service-card.medium, .infra-card.medium { border-left-color: var(--accent-warning); }
756
+ .service-card.high, .infra-card.high { border-left-color: var(--accent-error); }
757
+ .service-name, .infra-name {
758
+ font-weight: 600;
291
759
  font-size: 0.75rem;
292
- color: #9ca3af;
293
- margin-left: 2px;
760
+ margin-bottom: 0.25rem;
761
+ }
762
+ .service-details, .infra-details {
763
+ display: grid;
764
+ grid-template-columns: 1fr 1fr;
765
+ gap: 0.1rem 0.5rem;
766
+ font-size: 0.65rem;
767
+ color: var(--text-secondary);
294
768
  }
295
769
 
296
- .orphan-table {
770
+ /* Process Tree View */
771
+ .process-tree {
772
+ margin-top: 0.5rem;
773
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
774
+ }
775
+ .process-node {
776
+ display: flex;
777
+ align-items: center;
778
+ padding: 0.3rem 0.5rem;
779
+ margin-bottom: 0.2rem;
780
+ background: var(--bg-tertiary);
781
+ border-radius: 4px;
782
+ border-left: 3px solid var(--border-color);
783
+ transition: all 0.2s ease;
784
+ }
785
+ .process-node:hover {
786
+ background: var(--bg-secondary);
787
+ }
788
+ .process-node.agent-node.low { border-left-color: var(--accent-success); }
789
+ .process-node.agent-node.medium { border-left-color: var(--accent-warning); }
790
+ .process-node.agent-node.high { border-left-color: var(--accent-error); }
791
+ .process-node.infrastructure-node.low { border-left-color: var(--accent-success); }
792
+ .process-node.infrastructure-node.medium { border-left-color: var(--accent-warning); }
793
+ .process-node.infrastructure-node.high { border-left-color: var(--accent-error); }
794
+
795
+ .tree-connector {
796
+ color: var(--text-secondary);
797
+ font-weight: 400;
798
+ margin-right: 0.3rem;
799
+ }
800
+ .process-main {
801
+ display: flex;
802
+ align-items: center;
803
+ justify-content: space-between;
297
804
  width: 100%;
298
- border-collapse: collapse;
299
- font-size: 0.8rem;
300
- font-family: 'SF Mono', 'Fira Code', monospace;
805
+ min-height: 1.5rem;
806
+ }
807
+ .process-name {
808
+ font-weight: 600;
809
+ font-size: 0.75rem;
810
+ color: var(--text-primary);
811
+ flex: 1;
812
+ }
813
+ .process-metrics {
814
+ display: flex;
815
+ gap: 0.4rem;
816
+ align-items: center;
817
+ }
818
+ .pid-badge, .cpu-badge, .mem-badge, .time-badge {
819
+ font-size: 0.65rem;
820
+ padding: 0.1rem 0.3rem;
821
+ border-radius: 3px;
822
+ font-family: monospace;
823
+ }
824
+ .pid-badge {
825
+ background: var(--accent-primary);
826
+ color: var(--bg-primary);
827
+ font-weight: 600;
828
+ }
829
+ .cpu-badge {
830
+ background: var(--bg-primary);
831
+ color: var(--accent-warning);
832
+ border: 1px solid var(--border-color);
833
+ }
834
+ .mem-badge {
835
+ background: var(--bg-primary);
836
+ color: var(--accent-primary);
837
+ border: 1px solid var(--border-color);
838
+ }
839
+ .time-badge {
840
+ background: var(--bg-primary);
841
+ color: var(--text-secondary);
842
+ border: 1px solid var(--border-color);
301
843
  }
302
844
 
303
- .orphan-table th {
304
- text-align: left;
305
- color: #9ca3af;
306
- font-weight: 500;
307
- padding: 0.4rem 0.6rem;
308
- border-bottom: 1px solid #2a2f3e;
845
+ /* Activity Tags */
846
+ .activity-tag {
847
+ font-size: 0.6rem;
848
+ padding: 0.1rem 0.3rem;
849
+ border-radius: 2px;
850
+ margin-left: 0.3rem;
851
+ font-weight: 600;
852
+ text-transform: uppercase;
309
853
  }
854
+ .tag-main { background: var(--accent-primary); color: var(--bg-primary); }
855
+ .tag-agents { background: var(--accent-success); color: var(--bg-primary); }
856
+ .tag-browser { background: var(--accent-warning); color: var(--bg-primary); }
857
+ .tag-context { background: #bc8cff; color: var(--bg-primary); }
858
+ .tag-exec { background: #f0883e; color: var(--bg-primary); }
859
+ .tag-read { background: #58a6ff; color: var(--bg-primary); }
860
+ .tag-tool { background: #da3633; color: var(--bg-primary); }
861
+ .tag-think { background: #bc8cff; color: var(--bg-primary); }
862
+ .tag-user { background: #3fb950; color: var(--bg-primary); }
863
+ .tag-write { background: #f0883e; color: var(--bg-primary); }
864
+ .tag-other { background: var(--text-secondary); color: var(--bg-primary); }
310
865
 
311
- .orphan-table td {
312
- padding: 0.35rem 0.6rem;
313
- color: #e6e6e6;
314
- border-bottom: 1px solid #1f2433;
315
- white-space: nowrap;
866
+ /* Enhanced orphans */
867
+ .orphan-list {
868
+ margin-top: 0.5rem;
869
+ }
870
+ .orphan-row {
871
+ display: flex;
872
+ gap: 0.5rem;
873
+ padding: 0.25rem;
874
+ background: var(--bg-tertiary);
875
+ border-radius: 3px;
876
+ margin-bottom: 0.25rem;
877
+ font-size: 0.7rem;
878
+ }
879
+ .orphan-pid {
880
+ min-width: 60px;
881
+ font-family: monospace;
882
+ color: var(--accent-primary);
883
+ }
884
+ .orphan-resources {
885
+ min-width: 120px;
886
+ color: var(--text-secondary);
887
+ }
888
+ .orphan-cmd {
889
+ flex: 1;
890
+ color: var(--text-primary);
316
891
  overflow: hidden;
317
892
  text-overflow: ellipsis;
318
- max-width: 300px;
319
893
  }
320
894
 
321
- .orphan-table tr:hover td {
322
- background: #262b3d;
895
+ /* Enhanced problems */
896
+ .problems-section {
897
+ border-top: 1px solid var(--border-color);
898
+ padding-top: 0.5rem;
899
+ }
900
+ .problem-item {
901
+ background: rgba(218, 54, 51, 0.1);
902
+ border: 1px solid rgba(218, 54, 51, 0.3);
903
+ border-radius: 3px;
904
+ padding: 0.4rem;
905
+ margin-bottom: 0.25rem;
906
+ font-size: 0.7rem;
907
+ color: var(--accent-error);
323
908
  }
324
909
 
325
- .problems-list {
910
+ /* Error Heatmap */
911
+ .heatmap-container {
912
+ padding: 1rem;
913
+ overflow-y: auto;
914
+ flex: 1;
915
+ }
916
+ .heatmap-header {
917
+ font-size: 0.9rem;
918
+ margin-bottom: 1rem;
919
+ color: var(--text-primary);
920
+ }
921
+ .heatmap-grid {
922
+ display: grid;
923
+ grid-template-columns: repeat(10, 1fr);
924
+ gap: 4px;
925
+ margin-bottom: 1rem;
926
+ }
927
+ .heatmap-cell {
928
+ aspect-ratio: 1;
929
+ border-radius: 4px;
930
+ cursor: pointer;
931
+ transition: transform 0.2s;
932
+ display: flex;
933
+ align-items: center;
934
+ justify-content: center;
935
+ font-size: 0.65rem;
936
+ font-weight: 600;
937
+ color: rgba(255,255,255,0.7);
938
+ position: relative;
939
+ }
940
+ .heatmap-cell:hover {
941
+ transform: scale(1.15);
942
+ z-index: 2;
943
+ }
944
+ .heatmap-tooltip {
945
+ position: absolute;
946
+ bottom: calc(100% + 6px);
947
+ left: 50%;
948
+ transform: translateX(-50%);
949
+ background: var(--bg-secondary);
950
+ border: 1px solid var(--border-color);
951
+ border-radius: 4px;
952
+ padding: 0.4rem 0.6rem;
953
+ font-size: 0.7rem;
954
+ white-space: nowrap;
955
+ display: none;
956
+ z-index: 100;
957
+ color: var(--text-primary);
958
+ box-shadow: 0 4px 12px rgba(0,0,0,0.4);
959
+ }
960
+ .heatmap-cell:hover .heatmap-tooltip {
961
+ display: block;
962
+ }
963
+
964
+ /* State Machine */
965
+ .state-machine-container {
966
+ padding: 1rem;
967
+ overflow-y: auto;
968
+ flex: 1;
969
+ }
970
+ .state-machine {
971
+ display: flex;
972
+ justify-content: center;
973
+ align-items: center;
974
+ gap: 1.5rem;
975
+ padding: 2rem;
976
+ flex-wrap: wrap;
977
+ }
978
+ .state {
979
+ display: flex;
980
+ flex-direction: column;
981
+ align-items: center;
982
+ gap: 0.5rem;
983
+ }
984
+ .state-circle {
985
+ width: 80px;
986
+ height: 80px;
987
+ border-radius: 50%;
988
+ display: flex;
989
+ flex-direction: column;
990
+ align-items: center;
991
+ justify-content: center;
992
+ font-size: 0.65rem;
993
+ font-weight: 600;
994
+ border: 3px solid var(--border-color);
995
+ transition: all 0.3s;
996
+ }
997
+ .state-circle .state-count {
998
+ font-size: 1.2rem;
999
+ font-weight: 700;
1000
+ margin-bottom: 0.1rem;
1001
+ }
1002
+ .state-circle.pending {
1003
+ border-color: var(--text-secondary);
1004
+ background: rgba(139, 148, 158, 0.1);
1005
+ }
1006
+ .state-circle.running {
1007
+ border-color: var(--accent-primary);
1008
+ background: rgba(88, 166, 255, 0.1);
1009
+ animation: glow 2s infinite;
1010
+ }
1011
+ .state-circle.completed {
1012
+ border-color: var(--accent-success);
1013
+ background: rgba(35, 134, 54, 0.1);
1014
+ }
1015
+ .state-circle.failed {
1016
+ border-color: var(--accent-error);
1017
+ background: rgba(218, 54, 51, 0.1);
1018
+ }
1019
+ @keyframes glow {
1020
+ 0%, 100% { box-shadow: 0 0 5px var(--accent-primary); }
1021
+ 50% { box-shadow: 0 0 20px var(--accent-primary); }
1022
+ }
1023
+ .state-label {
1024
+ font-size: 0.75rem;
1025
+ color: var(--text-secondary);
1026
+ }
1027
+ .state-arrow {
1028
+ font-size: 1.5rem;
1029
+ color: var(--text-secondary);
1030
+ }
1031
+
1032
+ /* Summary View */
1033
+ .summary-container {
1034
+ padding: 1rem;
1035
+ overflow-y: auto;
1036
+ flex: 1;
1037
+ }
1038
+ .summary-card {
1039
+ background: var(--bg-secondary);
1040
+ border: 1px solid var(--border-color);
1041
+ border-radius: 8px;
1042
+ padding: 1.5rem;
1043
+ margin-bottom: 1rem;
1044
+ }
1045
+ .summary-title {
1046
+ font-size: 1.1rem;
1047
+ margin-bottom: 0.75rem;
1048
+ padding-bottom: 0.5rem;
1049
+ border-bottom: 1px solid var(--border-color);
1050
+ }
1051
+ .summary-text {
1052
+ font-size: 0.85rem;
1053
+ line-height: 1.6;
1054
+ color: var(--text-secondary);
1055
+ margin-bottom: 0.75rem;
1056
+ }
1057
+ .summary-details {
326
1058
  list-style: none;
327
1059
  padding: 0;
328
- margin: 0.5rem 0 0 0;
1060
+ margin: 0 0 1rem 0;
329
1061
  }
330
-
331
- .problems-list li {
1062
+ .summary-details li {
332
1063
  font-size: 0.8rem;
333
- color: #ef4444;
334
- padding: 0.2rem 0;
1064
+ padding: 0.25rem 0;
1065
+ color: var(--text-secondary);
335
1066
  }
336
-
337
- .problems-list li::before {
1067
+ .summary-details li::before {
338
1068
  content: "\2022";
339
1069
  margin-right: 0.5rem;
1070
+ color: var(--accent-primary);
1071
+ }
1072
+ .summary-recommendations {
1073
+ margin-top: 0.75rem;
1074
+ padding: 0.75rem;
1075
+ background: var(--bg-tertiary);
1076
+ border-radius: 6px;
1077
+ font-size: 0.8rem;
1078
+ color: var(--text-secondary);
1079
+ }
1080
+ .summary-recommendations strong {
1081
+ color: var(--text-primary);
1082
+ }
1083
+ .confidence-bar {
1084
+ display: flex;
1085
+ align-items: center;
1086
+ gap: 0.75rem;
1087
+ margin-top: 1rem;
1088
+ font-size: 0.8rem;
1089
+ }
1090
+ .bar {
1091
+ flex: 1;
1092
+ height: 8px;
1093
+ background: var(--bg-tertiary);
1094
+ border-radius: 4px;
1095
+ overflow: hidden;
1096
+ }
1097
+ .bar-fill {
1098
+ height: 100%;
1099
+ background: linear-gradient(90deg, var(--accent-error), var(--accent-warning), var(--accent-success));
1100
+ transition: width 0.3s;
340
1101
  }
341
1102
 
342
- @media (max-width: 768px) {
343
- .main {
344
- grid-template-columns: 1fr;
345
- }
1103
+ /* Loading spinner */
1104
+ .spinner {
1105
+ width: 20px;
1106
+ height: 20px;
1107
+ border: 2px solid var(--border-color);
1108
+ border-top-color: var(--accent-primary);
1109
+ border-radius: 50%;
1110
+ animation: spin 0.8s linear infinite;
1111
+ margin: 0 auto;
1112
+ }
1113
+ @keyframes spin { to { transform: rotate(360deg); } }
1114
+
1115
+ /* Scrollbars */
1116
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
1117
+ ::-webkit-scrollbar-track { background: transparent; }
1118
+ ::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 3px; }
1119
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
1120
+
1121
+ /* Chat bubbles for transcript */
1122
+ .chat-bubble { max-width: 80%; padding: 0.75rem 1rem; border-radius: 12px; margin-bottom: 0.5rem; font-size: 0.85rem; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
1123
+ .chat-user { margin-left: auto; background: rgba(88,166,255,0.15); border: 1px solid rgba(88,166,255,0.3); }
1124
+ .chat-assistant { margin-right: auto; background: var(--bg-secondary); border: 1px solid var(--border-color); }
1125
+ .chat-tool { margin: 0 auto; max-width: 90%; background: rgba(240,136,62,0.1); border: 1px solid rgba(240,136,62,0.3); font-family: monospace; font-size: 0.8rem; }
1126
+ .chat-thinking { margin-right: auto; background: rgba(188,140,255,0.08); border: 1px solid rgba(188,140,255,0.2); font-style: italic; color: var(--text-secondary); }
1127
+ .chat-meta { font-size: 0.7rem; color: var(--text-secondary); margin-top: 4px; }
1128
+ .chat-tokens { font-size: 0.65rem; color: #bc8cff; }
1129
+ .chat-thinking-toggle { cursor: pointer; user-select: none; font-size: 0.75rem; color: #bc8cff; }
1130
+ .chat-thinking-body { display: none; margin-top: 0.5rem; }
1131
+ .chat-thinking-body.open { display: block; }
346
1132
 
347
- .sidebar {
348
- display: none;
349
- }
1133
+ /* Responsive */
1134
+ @media (max-width: 900px) {
1135
+ .sidebar { width: 240px; min-width: 240px; }
1136
+ }
1137
+ @media (max-width: 768px) {
1138
+ .container { flex-direction: column; }
1139
+ .sidebar { width: 100%; min-width: 100%; max-height: 200px; }
1140
+ .state-machine { gap: 0.75rem; }
1141
+ .state-circle { width: 60px; height: 60px; font-size: 0.6rem; }
350
1142
  }
351
1143
  </style>
352
1144
  </head>
353
1145
  <body>
354
- <div class="header">
355
- <h1>AgentFlow Dashboard</h1>
356
- <div class="subtitle">Real-time monitoring for AI agent executions</div>
357
- </div>
1146
+ <header class="header">
1147
+ <h1><span>AgentFlow</span> Dashboard <span style="font-size:0.6rem;color:var(--text-secondary);font-weight:400;margin-left:8px;">v0.2.3</span></h1>
1148
+ <div class="header-right">
1149
+ <div class="connection-status">
1150
+ <span class="status-dot" id="connectionDot"></span>
1151
+ <span id="connectionText">Connecting...</span>
1152
+ </div>
1153
+ </div>
1154
+ </header>
358
1155
 
359
- <div class="connection-status disconnected" id="connectionStatus">
360
- Connecting...
361
- </div>
1156
+ <div class="container">
1157
+ <aside class="sidebar">
1158
+ <div class="sidebar-header">
1159
+ <h3>Traces</h3>
1160
+ <div class="search-box">
1161
+ <input type="text" id="traceSearch" placeholder="Filter by name or agent ID...">
1162
+ </div>
1163
+ </div>
1164
+ <div class="sidebar-filters">
1165
+ <div class="filter-row">
1166
+ <div class="filter-group">
1167
+ <label>Time Range</label>
1168
+ <select id="timeRangeFilter">
1169
+ <option value="all">All Time</option>
1170
+ <option value="1h">Last Hour</option>
1171
+ <option value="24h">Last 24 Hours</option>
1172
+ <option value="7d">Last 7 Days</option>
1173
+ </select>
1174
+ </div>
1175
+ <div class="filter-group">
1176
+ <label>Status</label>
1177
+ <select id="statusFilter">
1178
+ <option value="all">All</option>
1179
+ <option value="success">Completed</option>
1180
+ <option value="failure">Failed</option>
1181
+ <option value="running">Running</option>
1182
+ </select>
1183
+ </div>
1184
+ <div class="filter-group">
1185
+ <label>Activity</label>
1186
+ <select id="activityFilter">
1187
+ <option value="all">All</option>
1188
+ <option value="main">Main</option>
1189
+ <option value="agents">Agents</option>
1190
+ <option value="browser">Browser</option>
1191
+ <option value="context">Context</option>
1192
+ <option value="exec">Exec</option>
1193
+ <option value="read">Read</option>
1194
+ <option value="tool">Tool</option>
1195
+ <option value="think">Think</option>
1196
+ <option value="user">User</option>
1197
+ <option value="write">Write</option>
1198
+ <option value="other">Other</option>
1199
+ </select>
1200
+ </div>
1201
+ </div>
1202
+ </div>
1203
+ <div class="trace-list" id="traceList"></div>
1204
+ <div class="trace-count-badge" id="traceCount">0 traces</div>
1205
+ </aside>
1206
+
1207
+ <main class="main-content">
1208
+ <!-- Process Health (above metrics, not a tab) -->
1209
+ <div class="process-health-section" id="processHealthSection" style="display:none;"></div>
1210
+
1211
+ <div class="stats-overview" id="statsOverview">
1212
+ <div class="stat-card-mini">
1213
+ <div class="metric-label">Agents</div>
1214
+ <div class="metric-value primary" id="statAgents">--</div>
1215
+ </div>
1216
+ <div class="stat-card-mini">
1217
+ <div class="metric-label">Executions</div>
1218
+ <div class="metric-value primary" id="statExecutions">--</div>
1219
+ </div>
1220
+ <div class="stat-card-mini">
1221
+ <div class="metric-label">Success Rate</div>
1222
+ <div class="metric-value success" id="statSuccessRate">--</div>
1223
+ </div>
1224
+ <div class="stat-card-mini">
1225
+ <div class="metric-label">Active</div>
1226
+ <div class="metric-value warning" id="statActive">--</div>
1227
+ </div>
1228
+ </div>
362
1229
 
363
- <div class="main">
364
- <div class="sidebar">
365
- <h3 class="section-title">Agents</h3>
366
- <div class="agent-list" id="agentList">
367
- <div class="loading">Loading agents...</div>
1230
+ <div class="tabs">
1231
+ <div class="tab active" data-tab="timeline">Timeline</div>
1232
+ <div class="tab" data-tab="metrics">Metrics</div>
1233
+ <div class="tab" data-tab="graph">Dependency Graph</div>
1234
+ <div class="tab" data-tab="heatmap">Error Heatmap</div>
1235
+ <div class="tab" data-tab="state">State Machine</div>
1236
+ <div class="tab" data-tab="summary">Summary</div>
1237
+ <div class="tab" data-tab="transcript">Transcript</div>
368
1238
  </div>
369
- </div>
370
1239
 
371
- <div class="content">
372
- <div class="process-health" id="processHealth" style="display:none;"></div>
1240
+ <div class="toolbar" id="toolbar">
1241
+ <div class="toolbar-group">
1242
+ <button class="btn btn-icon" id="btnPlayPause" title="Pause/Resume live tail">&#9208;</button>
1243
+ <div class="live-indicator" id="liveIndicator">
1244
+ <span class="live-dot">&#9679;</span> Live Tail
1245
+ </div>
1246
+ <span class="toolbar-info" id="toolbarInfo"></span>
1247
+ </div>
1248
+ <div class="toolbar-group">
1249
+ <button class="btn" id="btnRefresh" title="Refresh data">Refresh</button>
1250
+ <button class="btn" id="btnExportPng" title="Export graph as PNG">Export PNG</button>
1251
+ <button class="btn" id="btnFit" title="Fit graph to view">Fit</button>
1252
+ <button class="btn" id="btnLayout" title="Re-run layout">Layout</button>
1253
+ </div>
1254
+ </div>
373
1255
 
374
- <div class="stats-grid" id="statsGrid">
375
- <div class="loading">Loading statistics...</div>
1256
+ <div class="alert-panel" id="alertPanel">
1257
+ <strong>Alerts:</strong>
1258
+ <ul id="alertList"></ul>
376
1259
  </div>
377
1260
 
378
- <div class="traces-section">
379
- <h3 class="section-title">Recent Executions</h3>
380
- <div class="traces-list" id="tracesList">
381
- <div class="loading">Loading traces...</div>
1261
+ <div class="content-area">
1262
+ <!-- Timeline tab -->
1263
+ <div class="tab-panel active" id="panel-timeline">
1264
+ <div class="timeline-container" id="timelineContent">
1265
+ <div class="empty-state">
1266
+ <div class="empty-state-icon">&#9776;</div>
1267
+ <div class="empty-state-title">Select a trace</div>
1268
+ <div class="empty-state-text">Choose a trace from the sidebar to view its execution timeline.</div>
1269
+ </div>
1270
+ </div>
1271
+ </div>
1272
+
1273
+ <!-- Metrics tab -->
1274
+ <div class="tab-panel" id="panel-metrics">
1275
+ <div class="metrics-container" id="metricsContent">
1276
+ <div class="empty-state">
1277
+ <div class="empty-state-text">Select a trace to view metrics.</div>
1278
+ </div>
1279
+ </div>
1280
+ </div>
1281
+
1282
+ <!-- Dependency Graph tab -->
1283
+ <div class="tab-panel" id="panel-graph">
1284
+ <div id="cy">
1285
+ <div class="empty-state" id="graphEmpty">
1286
+ <div class="empty-state-icon">&#9651;</div>
1287
+ <div class="empty-state-title">Select a trace</div>
1288
+ <div class="empty-state-text">Choose a trace from the sidebar to view its dependency graph.</div>
1289
+ </div>
1290
+ </div>
1291
+ <div class="node-detail-panel" id="nodeDetailPanel">
1292
+ <div class="node-detail-header">
1293
+ <h4 id="nodeDetailTitle">Node Details</h4>
1294
+ <button class="node-detail-close" id="nodeDetailClose">&times;</button>
1295
+ </div>
1296
+ <div class="node-detail-body" id="nodeDetailBody"></div>
1297
+ </div>
1298
+ </div>
1299
+
1300
+ <!-- Error Heatmap tab -->
1301
+ <div class="tab-panel" id="panel-heatmap">
1302
+ <div class="heatmap-container" id="heatmapContent">
1303
+ <div class="empty-state">
1304
+ <div class="empty-state-text">Select a trace to view the error heatmap.</div>
1305
+ </div>
1306
+ </div>
1307
+ </div>
1308
+
1309
+ <!-- State Machine tab -->
1310
+ <div class="tab-panel" id="panel-state">
1311
+ <div class="state-machine-container" id="stateContent">
1312
+ <div class="empty-state">
1313
+ <div class="empty-state-text">Select a trace to view state machine.</div>
1314
+ </div>
1315
+ </div>
1316
+ </div>
1317
+
1318
+ <!-- Summary tab -->
1319
+ <div class="tab-panel" id="panel-summary">
1320
+ <div class="summary-container" id="summaryContent">
1321
+ <div class="empty-state">
1322
+ <div class="empty-state-text">Select a trace to view summary.</div>
1323
+ </div>
1324
+ </div>
1325
+ </div>
1326
+
1327
+ <!-- Transcript tab -->
1328
+ <div class="tab-panel" id="panel-transcript">
1329
+ <div class="timeline-container" id="transcriptContent">
1330
+ <div class="empty-state">
1331
+ <div class="empty-state-text">Select a session trace to view transcript.</div>
1332
+ </div>
1333
+ </div>
382
1334
  </div>
383
1335
  </div>
384
- </div>
1336
+ </main>
385
1337
  </div>
386
1338
 
387
- <script src="dashboard.js"></script>
1339
+ <script src="dashboard.js?v=0.2.2"></script>
388
1340
  </body>
389
- </html>
1341
+ </html>