@qiaolei81/copilot-session-viewer 0.3.8 → 0.4.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.
@@ -1,1570 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Session <%= sessionId %> - Vue Virtual Scroller</title>
7
-
8
- <!-- Vue 3 -->
9
- <script src="/public/vendor/vue.global.prod.min.js"></script>
10
-
11
- <!-- vue-virtual-scroller Vue 3 -->
12
- <link rel="stylesheet" href="/public/vendor/vue-virtual-scroller.css">
13
- <script src="/public/vendor/vue-virtual-scroller.min.js"></script>
14
-
15
- <!-- Markdown rendering -->
16
- <script src="/public/vendor/marked.umd.min.js"></script>
17
-
18
- <!-- DOMPurify for XSS protection -->
19
- <script src="/public/vendor/purify.min.js"></script>
20
-
21
- <%- include('telemetry-snippet') %>
22
-
23
- <style>
24
- * { margin: 0; padding: 0; box-sizing: border-box; }
25
- body {
26
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
27
- background: #0d1117;
28
- color: #c9d1d9;
29
- line-height: 1.5;
30
- overflow: hidden;
31
- }
32
- .container {
33
- max-width: 100%;
34
- height: 100vh;
35
- display: flex;
36
- flex-direction: column;
37
- padding: 0;
38
- }
39
-
40
- /* Focus indicators for accessibility */
41
- button:focus-visible,
42
- input:focus-visible,
43
- .turn-btn:focus-visible,
44
- .filter-dropdown-toggle:focus-visible {
45
- outline: 2px solid #58a6ff;
46
- outline-offset: 2px;
47
- box-shadow: 0 0 0 4px rgba(88, 166, 255, 0.2);
48
- }
49
-
50
- /* Header */
51
- .header {
52
- padding: 16px 20px;
53
- border-bottom: 1px solid #30363d;
54
- flex-shrink: 0;
55
- display: flex;
56
- align-items: center;
57
- gap: 16px;
58
- }
59
- .home-btn {
60
- padding: 6px 12px;
61
- background: #21262d;
62
- border: 1px solid #30363d;
63
- border-radius: 6px;
64
- color: #c9d1d9;
65
- text-decoration: none;
66
- font-size: 14px;
67
- transition: all 0.2s;
68
- }
69
- .home-btn:hover {
70
- background: #30363d;
71
- border-color: #58a6ff;
72
- }
73
- .time-analyze-btn {
74
- padding: 6px 12px;
75
- background: #1f6feb;
76
- border: 1px solid #388bfd;
77
- border-radius: 6px;
78
- color: #fff;
79
- text-decoration: none;
80
- font-size: 14px;
81
- font-weight: 500;
82
- transition: all 0.2s;
83
- white-space: nowrap;
84
- }
85
- .time-analyze-btn:hover {
86
- background: #388bfd;
87
- border-color: #58a6ff;
88
- }
89
- .export-btn {
90
- padding: 6px 12px;
91
- background: #238636;
92
- border: 1px solid #2ea043;
93
- border-radius: 6px;
94
- color: #fff;
95
- font-size: 14px;
96
- font-weight: 500;
97
- cursor: pointer;
98
- transition: all 0.2s;
99
- white-space: nowrap;
100
- }
101
- .export-btn:hover:not(:disabled) {
102
- background: #2ea043;
103
- border-color: #3fb950;
104
- }
105
- .export-btn:disabled {
106
- opacity: 0.6;
107
- cursor: not-allowed;
108
- }
109
- h1 {
110
- color: #58a6ff;
111
- font-size: 20px;
112
- margin: 0;
113
- flex: 1;
114
- }
115
-
116
- /* Main layout */
117
- .main-layout {
118
- display: flex;
119
- flex: 1;
120
- overflow: hidden;
121
- }
122
-
123
- /* Sidebar */
124
- .sidebar {
125
- width: 320px;
126
- flex-shrink: 0;
127
- background: #161b22;
128
- border-right: 1px solid #30363d;
129
- overflow-y: auto;
130
- padding: 16px;
131
- transition: all 0.3s ease;
132
- }
133
- .sidebar.collapsed {
134
- width: 0;
135
- padding: 0;
136
- border-right: none;
137
- overflow: hidden;
138
- }
139
-
140
- /* Sidebar toggle */
141
- .sidebar-toggle {
142
- background: #21262d;
143
- border: 1px solid #30363d;
144
- border-radius: 4px;
145
- color: #c9d1d9;
146
- cursor: pointer;
147
- padding: 4px 8px;
148
- font-size: 14px;
149
- transition: all 0.2s;
150
- }
151
- .sidebar-toggle:hover {
152
- background: #30363d;
153
- color: #58a6ff;
154
- }
155
-
156
- /* Sidebar sections */
157
- .sidebar-section {
158
- margin-bottom: 20px;
159
- }
160
- .sidebar-section-title {
161
- font-size: 12px;
162
- font-weight: 600;
163
- color: #c9d1d9;
164
- margin-bottom: 12px;
165
- text-transform: uppercase;
166
- letter-spacing: 0.5px;
167
- }
168
-
169
- /* Session Info */
170
- .session-info {
171
- font-size: 13px;
172
- }
173
-
174
- /* Session info table */
175
- .session-info-table {
176
- width: 100%;
177
- font-size: 12px;
178
- }
179
- .session-info-table td {
180
- padding: 6px 8px;
181
- border-bottom: 1px solid rgba(110, 118, 129, 0.15);
182
- vertical-align: top;
183
- }
184
- .session-info-table td:first-child {
185
- color: #8b949e;
186
- font-weight: 500;
187
- white-space: nowrap;
188
- width: 85px;
189
- }
190
- .session-info-table td:last-child {
191
- color: #c9d1d9;
192
- word-break: break-all;
193
- }
194
- .session-info-table tr:last-child td {
195
- border-bottom: none;
196
- }
197
-
198
- /* Source badges */
199
- .source-badge {
200
- display: inline-block;
201
- font-size: 11px;
202
- font-weight: 600;
203
- padding: 2px 8px;
204
- border-radius: 3px;
205
- text-transform: uppercase;
206
- letter-spacing: 0.5px;
207
- }
208
- .source-cli {
209
- background: rgba(35, 134, 54, 0.2);
210
- color: #3fb950;
211
- border: 1px solid rgba(35, 134, 54, 0.4);
212
- }
213
- .source-vscode {
214
- background: rgba(31, 111, 235, 0.2);
215
- color: #58a6ff;
216
- border: 1px solid rgba(31, 111, 235, 0.4);
217
- }
218
- .source-copilot {
219
- background: rgba(88, 166, 255, 0.2);
220
- color: #58a6ff;
221
- border: 1px solid rgba(88, 166, 255, 0.4);
222
- }
223
- .source-claude {
224
- background: rgba(210, 153, 34, 0.2);
225
- color: #d29922;
226
- border: 1px solid rgba(210, 153, 34, 0.4);
227
- }
228
- .source-pi-mono {
229
- background: rgba(138, 102, 204, 0.2);
230
- color: #a78bdb;
231
- border: 1px solid rgba(138, 102, 204, 0.4);
232
- }
233
- .source-modernize {
234
- background: rgba(76, 175, 80, 0.2);
235
- color: #66bb6a;
236
- border: 1px solid rgba(76, 175, 80, 0.4);
237
- }
238
- .source-vscode {
239
- background: rgba(0, 122, 204, 0.2);
240
- color: #4fc3f7;
241
- border: 1px solid rgba(0, 122, 204, 0.4);
242
- }
243
-
244
- /* Turn buttons */
245
- .turn-buttons {
246
- display: flex;
247
- flex-direction: column;
248
- gap: 6px;
249
- }
250
- .turn-btn {
251
- padding: 12px 10px;
252
- min-height: 44px;
253
- background: #21262d;
254
- border: 1px solid #30363d;
255
- border-radius: 4px;
256
- color: #c9d1d9;
257
- font-size: 13px;
258
- cursor: pointer;
259
- transition: all 0.2s;
260
- text-align: left;
261
- width: 100%;
262
- margin-bottom: 10px;
263
- }
264
- .turn-btn-id {
265
- font-weight: 600;
266
- color: #c9d1d9;
267
- font-size: 12px;
268
- }
269
- .turn-btn-message {
270
- font-size: 12px;
271
- color: #6e7681;
272
- overflow: hidden;
273
- text-overflow: ellipsis;
274
- white-space: nowrap;
275
- margin-top: 2px;
276
- }
277
- .turn-btn:hover {
278
- background: #30363d;
279
- border-color: #58a6ff;
280
- }
281
- .turn-btn:hover .turn-btn-id {
282
- color: #58a6ff;
283
- }
284
- .turn-btn.active {
285
- background: #1f6feb;
286
- border-color: #1f6feb;
287
- color: #fff;
288
- }
289
- .turn-btn.active .turn-btn-id,
290
- .turn-btn.active .turn-btn-message {
291
- color: #fff;
292
- }
293
-
294
- /* Event filters — removed from sidebar, now in unified toolbar */
295
-
296
- /* Session Tags */
297
- .session-tags-container {
298
- margin-top: 16px;
299
- }
300
- .tags-display {
301
- display: flex;
302
- flex-wrap: wrap;
303
- gap: 6px;
304
- min-height: 28px;
305
- align-items: flex-start;
306
- }
307
- .tag-label {
308
- display: inline-flex;
309
- align-items: center;
310
- gap: 4px;
311
- padding: 4px 10px;
312
- border-radius: 12px;
313
- font-size: 12px;
314
- font-weight: 500;
315
- color: #fff;
316
- cursor: default;
317
- transition: opacity 0.2s;
318
- }
319
- .tag-label:hover {
320
- opacity: 0.8;
321
- }
322
- .tag-remove {
323
- background: none;
324
- border: none;
325
- color: rgba(255, 255, 255, 0.7);
326
- cursor: pointer;
327
- font-size: 14px;
328
- line-height: 1;
329
- padding: 0;
330
- margin-left: 2px;
331
- transition: color 0.2s;
332
- }
333
- .tag-remove:hover {
334
- color: #fff;
335
- }
336
- .tags-edit-btn {
337
- background: none;
338
- border: 1px solid #30363d;
339
- border-radius: 4px;
340
- color: #8b949e;
341
- cursor: pointer;
342
- padding: 4px 8px;
343
- font-size: 12px;
344
- transition: all 0.2s;
345
- display: inline-flex;
346
- align-items: center;
347
- gap: 4px;
348
- }
349
- .tags-edit-btn:hover {
350
- border-color: #58a6ff;
351
- color: #58a6ff;
352
- }
353
- .tags-dropdown {
354
- position: relative;
355
- margin-top: 8px;
356
- }
357
- .tags-input-container {
358
- display: flex;
359
- flex-wrap: wrap;
360
- gap: 6px;
361
- padding: 8px;
362
- background: #161b22;
363
- border: 1px solid #30363d;
364
- border-radius: 6px;
365
- min-height: 38px;
366
- }
367
- .tags-input-container:focus-within {
368
- border-color: #58a6ff;
369
- }
370
- .tag-input-chip {
371
- display: inline-flex;
372
- align-items: center;
373
- gap: 4px;
374
- padding: 4px 8px;
375
- border-radius: 12px;
376
- font-size: 12px;
377
- font-weight: 500;
378
- color: #fff;
379
- }
380
- .tag-input-chip button {
381
- background: none;
382
- border: none;
383
- color: rgba(255, 255, 255, 0.7);
384
- cursor: pointer;
385
- font-size: 12px;
386
- padding: 0;
387
- margin-left: 2px;
388
- }
389
- .tag-input-chip button:hover {
390
- color: #fff;
391
- }
392
- .tags-text-input {
393
- flex: 1;
394
- min-width: 120px;
395
- background: transparent;
396
- border: none;
397
- outline: none;
398
- color: #c9d1d9;
399
- font-size: 13px;
400
- padding: 4px;
401
- }
402
- .tags-text-input::placeholder {
403
- color: #6e7681;
404
- }
405
- .tags-autocomplete {
406
- position: absolute;
407
- top: 100%;
408
- left: 0;
409
- right: 0;
410
- background: #161b22;
411
- border: 1px solid #30363d;
412
- border-radius: 6px;
413
- margin-top: 4px;
414
- max-height: 200px;
415
- overflow-y: auto;
416
- z-index: 100;
417
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
418
- }
419
- .tags-autocomplete-item {
420
- padding: 8px 12px;
421
- font-size: 13px;
422
- color: #c9d1d9;
423
- cursor: pointer;
424
- transition: background 0.2s;
425
- }
426
- .tags-autocomplete-item:hover {
427
- background: rgba(88, 166, 255, 0.15);
428
- }
429
- .tags-autocomplete-item.selected {
430
- background: rgba(88, 166, 255, 0.25);
431
- }
432
- .tags-error {
433
- margin-top: 6px;
434
- font-size: 12px;
435
- color: #f85149;
436
- }
437
-
438
- /* Usage Section */
439
- .usage-container {
440
- font-size: 12px;
441
- display: flex;
442
- flex-direction: column;
443
- gap: 12px;
444
- }
445
- .usage-summary {
446
- padding: 14px;
447
- background: linear-gradient(180deg, rgba(88, 166, 255, 0.16) 0%, rgba(22, 27, 34, 0.94) 100%);
448
- border: 1px solid rgba(88, 166, 255, 0.22);
449
- border-radius: 10px;
450
- color: #c9d1d9;
451
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
452
- }
453
- .usage-summary-eyebrow {
454
- font-size: 10px;
455
- font-weight: 700;
456
- color: #8b949e;
457
- text-transform: uppercase;
458
- letter-spacing: 0.7px;
459
- margin-bottom: 6px;
460
- }
461
- .usage-summary-total {
462
- font-size: 24px;
463
- line-height: 1;
464
- font-weight: 700;
465
- color: #e6edf3;
466
- display: flex;
467
- align-items: baseline;
468
- gap: 6px;
469
- }
470
- .usage-summary-total-unit {
471
- font-size: 11px;
472
- font-weight: 600;
473
- text-transform: uppercase;
474
- letter-spacing: 0.5px;
475
- color: #8b949e;
476
- }
477
- .usage-summary-caption {
478
- margin-top: 6px;
479
- font-size: 12px;
480
- color: #8b949e;
481
- }
482
- .usage-summary-metrics {
483
- display: grid;
484
- grid-template-columns: repeat(3, minmax(0, 1fr));
485
- gap: 8px;
486
- margin-top: 12px;
487
- }
488
- .usage-expanded {
489
- display: flex;
490
- flex-direction: column;
491
- gap: 12px;
492
- }
493
- .usage-section {
494
- padding: 12px;
495
- background: rgba(110, 118, 129, 0.05);
496
- border: 1px solid #30363d;
497
- border-radius: 10px;
498
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
499
- }
500
- .usage-section-header {
501
- display: flex;
502
- align-items: center;
503
- justify-content: space-between;
504
- gap: 8px;
505
- margin-bottom: 10px;
506
- }
507
- .usage-section-title {
508
- font-size: 11px;
509
- font-weight: 600;
510
- color: #8b949e;
511
- text-transform: uppercase;
512
- letter-spacing: 0.5px;
513
- margin: 0;
514
- }
515
- .usage-section-badge {
516
- display: inline-flex;
517
- align-items: center;
518
- justify-content: center;
519
- min-width: 24px;
520
- padding: 2px 8px;
521
- border-radius: 999px;
522
- background: rgba(88, 166, 255, 0.12);
523
- border: 1px solid rgba(88, 166, 255, 0.22);
524
- color: #79c0ff;
525
- font-size: 10px;
526
- font-weight: 700;
527
- }
528
- .usage-model-list {
529
- display: flex;
530
- flex-direction: column;
531
- gap: 8px;
532
- }
533
- .usage-model {
534
- padding: 10px;
535
- background: linear-gradient(180deg, rgba(13, 17, 23, 0.96) 0%, rgba(22, 27, 34, 0.96) 100%);
536
- border: 1px solid rgba(48, 54, 61, 0.9);
537
- border-radius: 8px;
538
- }
539
- .usage-model-header {
540
- display: flex;
541
- flex-direction: column;
542
- align-items: stretch;
543
- gap: 8px;
544
- margin-bottom: 10px;
545
- }
546
- .usage-model-name {
547
- display: block;
548
- max-width: 100%;
549
- font-size: 11px;
550
- font-weight: 600;
551
- line-height: 1.35;
552
- color: #79c0ff;
553
- font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
554
- white-space: nowrap;
555
- word-break: normal;
556
- overflow-wrap: normal;
557
- overflow-x: auto;
558
- overflow-y: hidden;
559
- scrollbar-width: thin;
560
- scrollbar-color: rgba(110, 118, 129, 0.55) transparent;
561
- padding-bottom: 2px;
562
- }
563
- .usage-model-name::-webkit-scrollbar {
564
- height: 4px;
565
- }
566
- .usage-model-name::-webkit-scrollbar-thumb {
567
- background: rgba(110, 118, 129, 0.55);
568
- border-radius: 999px;
569
- }
570
- .usage-model-name::-webkit-scrollbar-track {
571
- background: transparent;
572
- }
573
- .usage-model-meta {
574
- display: flex;
575
- flex-wrap: wrap;
576
- justify-content: flex-start;
577
- gap: 6px;
578
- }
579
- .usage-meta-pill {
580
- display: inline-flex;
581
- align-items: center;
582
- padding: 2px 8px;
583
- border-radius: 999px;
584
- background: rgba(110, 118, 129, 0.12);
585
- border: 1px solid rgba(110, 118, 129, 0.2);
586
- color: #c9d1d9;
587
- font-size: 10px;
588
- font-weight: 600;
589
- }
590
- .usage-meta-pill-premium {
591
- color: #d29922;
592
- border-color: rgba(210, 153, 34, 0.25);
593
- background: rgba(210, 153, 34, 0.12);
594
- }
595
- .usage-meta-pill-cache {
596
- color: #3fb950;
597
- border-color: rgba(63, 185, 80, 0.25);
598
- background: rgba(63, 185, 80, 0.12);
599
- }
600
- .usage-metric-grid {
601
- display: grid;
602
- grid-template-columns: repeat(2, minmax(0, 1fr));
603
- gap: 8px;
604
- }
605
- .usage-metric-grid-compact {
606
- grid-template-columns: repeat(3, minmax(0, 1fr));
607
- }
608
- .usage-metric-card {
609
- display: flex;
610
- flex-direction: column;
611
- gap: 4px;
612
- min-width: 0;
613
- padding: 9px 10px;
614
- border-radius: 8px;
615
- border: 1px solid rgba(48, 54, 61, 0.8);
616
- background: rgba(13, 17, 23, 0.5);
617
- }
618
- .usage-metric-card-summary {
619
- background: rgba(13, 17, 23, 0.42);
620
- border-color: rgba(88, 166, 255, 0.14);
621
- }
622
- .usage-metric-label {
623
- font-size: 10px;
624
- font-weight: 700;
625
- color: #8b949e;
626
- text-transform: uppercase;
627
- letter-spacing: 0.5px;
628
- }
629
- .usage-metric-value {
630
- font-size: 14px;
631
- line-height: 1.2;
632
- font-weight: 700;
633
- color: #e6edf3;
634
- overflow-wrap: anywhere;
635
- }
636
- .usage-metric-value-added {
637
- color: #3fb950;
638
- }
639
- .usage-metric-value-removed {
640
- color: #f85149;
641
- }
642
-
643
- /* Tool Calling Summary */
644
- .tool-summary-list {
645
- display: flex;
646
- flex-direction: column;
647
- gap: 4px;
648
- }
649
- .tool-summary-item {
650
- position: relative;
651
- display: flex;
652
- justify-content: space-between;
653
- align-items: center;
654
- padding: 3px 6px;
655
- font-size: 12px;
656
- border-radius: 3px;
657
- overflow: hidden;
658
- }
659
- .tool-summary-bar {
660
- position: absolute;
661
- left: 0;
662
- top: 0;
663
- bottom: 0;
664
- background: rgba(158, 106, 3, 0.15);
665
- border-radius: 3px;
666
- transition: width 0.3s ease;
667
- }
668
- .tool-summary-name {
669
- position: relative;
670
- color: #c9d1d9;
671
- overflow: hidden;
672
- text-overflow: ellipsis;
673
- white-space: nowrap;
674
- min-width: 0;
675
- flex: 1;
676
- }
677
- .tool-summary-count {
678
- position: relative;
679
- color: #d29922;
680
- font-weight: 600;
681
- margin-left: 8px;
682
- flex-shrink: 0;
683
- }
684
-
685
- /* Content */
686
- .content {
687
- flex: 1;
688
- display: flex;
689
- flex-direction: column;
690
- overflow: hidden;
691
- position: relative;
692
- }
693
-
694
- .unified-filter-bar {
695
- background: #0d1117;
696
- border-bottom: 1px solid #30363d;
697
- flex-shrink: 0;
698
- }
699
- .filter-bar-row {
700
- display: flex;
701
- align-items: center;
702
- gap: 8px;
703
- padding: 8px 12px;
704
- flex-wrap: wrap;
705
- }
706
- .filter-bar-search {
707
- display: flex;
708
- align-items: center;
709
- gap: 4px;
710
- flex: 1;
711
- min-width: 160px;
712
- }
713
- .filter-bar-divider {
714
- width: 1px;
715
- height: 20px;
716
- background: #30363d;
717
- flex-shrink: 0;
718
- }
719
- /* Event type dropdown wrapper */
720
- .filter-type-wrapper {
721
- position: relative;
722
- }
723
- .filter-type-toggle {
724
- padding: 4px 10px;
725
- background: #161b22;
726
- border: 1px solid #30363d;
727
- border-radius: 6px;
728
- color: #c9d1d9;
729
- font-size: 13px;
730
- cursor: pointer;
731
- white-space: nowrap;
732
- transition: all 0.2s;
733
- }
734
- .filter-type-toggle:hover {
735
- border-color: #58a6ff;
736
- background: #0d1117;
737
- }
738
- .filter-type-toggle.active {
739
- border-color: #58a6ff;
740
- color: #58a6ff;
741
- background: rgba(88, 166, 255, 0.1);
742
- }
743
- .filter-type-menu {
744
- position: absolute;
745
- top: calc(100% + 4px);
746
- left: 0;
747
- background: #161b22;
748
- border: 1px solid #30363d;
749
- border-radius: 6px;
750
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
751
- min-width: 250px;
752
- z-index: 1000;
753
- }
754
- .filter-type-menu-header {
755
- padding: 8px 12px;
756
- border-bottom: 1px solid #30363d;
757
- font-size: 12px;
758
- font-weight: 600;
759
- color: #c9d1d9;
760
- }
761
- .filter-type-menu-options {
762
- max-height: 300px;
763
- overflow-y: auto;
764
- padding: 4px 0;
765
- }
766
- .filter-type-menu-item {
767
- display: flex;
768
- align-items: center;
769
- justify-content: space-between;
770
- padding: 6px 12px;
771
- cursor: pointer;
772
- transition: background 0.15s;
773
- font-size: 13px;
774
- color: #c9d1d9;
775
- }
776
- .filter-type-menu-item:hover {
777
- background: rgba(88, 166, 255, 0.1);
778
- }
779
- .filter-type-menu-item.active {
780
- background: rgba(88, 166, 255, 0.2);
781
- color: #58a6ff;
782
- }
783
- .filter-type-menu-label {
784
- flex: 1;
785
- overflow: hidden;
786
- text-overflow: ellipsis;
787
- white-space: nowrap;
788
- }
789
- .filter-type-menu-count {
790
- color: #7d8590;
791
- font-size: 12px;
792
- margin-left: 8px;
793
- flex-shrink: 0;
794
- }
795
- /* Active filter chips bar */
796
- .active-filters-bar {
797
- display: flex;
798
- align-items: center;
799
- gap: 6px;
800
- padding: 4px 12px 8px;
801
- flex-wrap: wrap;
802
- }
803
- .filter-chip {
804
- display: inline-flex;
805
- align-items: center;
806
- gap: 4px;
807
- padding: 2px 8px;
808
- background: rgba(88, 166, 255, 0.15);
809
- border: 1px solid rgba(88, 166, 255, 0.3);
810
- border-radius: 12px;
811
- font-size: 12px;
812
- color: #58a6ff;
813
- white-space: nowrap;
814
- }
815
- .filter-chip-remove {
816
- background: none;
817
- border: none;
818
- color: #58a6ff;
819
- cursor: pointer;
820
- font-size: 14px;
821
- padding: 0 2px;
822
- line-height: 1;
823
- opacity: 0.7;
824
- transition: opacity 0.15s;
825
- }
826
- .filter-chip-remove:hover {
827
- opacity: 1;
828
- }
829
- .clear-all-filters-btn {
830
- background: none;
831
- border: none;
832
- color: #f85149;
833
- cursor: pointer;
834
- font-size: 12px;
835
- padding: 2px 6px;
836
- border-radius: 3px;
837
- transition: background 0.2s;
838
- }
839
- .clear-all-filters-btn:hover {
840
- background: rgba(248, 81, 73, 0.1);
841
- }
842
-
843
- .subagent-selector {
844
- display: flex;
845
- align-items: center;
846
- gap: 8px;
847
- }
848
-
849
- .subagent-dropdown {
850
- padding: 4px 8px;
851
- background: #161b22;
852
- border: 1px solid #30363d;
853
- border-radius: 6px;
854
- color: #c9d1d9;
855
- font-size: 13px;
856
- cursor: pointer;
857
- max-width: 220px;
858
- }
859
-
860
- .subagent-dropdown:hover {
861
- border-color: #58a6ff;
862
- }
863
-
864
- .subagent-dropdown:focus {
865
- outline: none;
866
- border-color: #58a6ff;
867
- box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.3);
868
- }
869
-
870
- .subagent-usage-badge {
871
- font-size: 11px;
872
- color: #7d8590;
873
- white-space: nowrap;
874
- }
875
-
876
- .scroll-float-btns {
877
- position: fixed;
878
- bottom: 24px;
879
- right: 24px;
880
- display: flex;
881
- flex-direction: column;
882
- gap: 8px;
883
- z-index: 9999;
884
- }
885
- .scroll-edge-btn {
886
- background: #21262d;
887
- color: #c9d1d9;
888
- border: 1px solid #30363d;
889
- border-radius: 50%;
890
- width: 32px;
891
- height: 32px;
892
- font-size: 13px;
893
- cursor: pointer;
894
- display: flex;
895
- align-items: center;
896
- justify-content: center;
897
- box-shadow: 0 2px 8px rgba(0,0,0,0.4);
898
- transition: background 0.15s, transform 0.1s, opacity 0.15s;
899
- padding: 0;
900
- opacity: 0.3;
901
- }
902
- .scroll-edge-btn:hover {
903
- background: #388bfd;
904
- border-color: #388bfd;
905
- color: #fff;
906
- transform: scale(1.1);
907
- opacity: 1;
908
- }
909
- .search-input {
910
- flex: 1;
911
- min-width: 120px;
912
- padding: 6px 12px;
913
- background: #161b22;
914
- border: 1px solid #30363d;
915
- border-radius: 6px;
916
- color: #c9d1d9;
917
- font-size: 13px;
918
- outline: none;
919
- transition: border-color 0.2s;
920
- }
921
-
922
- .search-input:focus {
923
- border-color: #58a6ff;
924
- background: #0d1117;
925
- }
926
-
927
- .search-input::placeholder {
928
- color: #6e7681;
929
- }
930
-
931
- /* Search highlight */
932
- .search-highlight {
933
- background: #ffd33d;
934
- color: #1f2328;
935
- padding: 1px 2px;
936
- border-radius: 2px;
937
- font-weight: 500;
938
- }
939
-
940
- /* Search result counter */
941
- .search-result-count {
942
- font-size: 12px;
943
- color: #c9d1d9;
944
- padding: 4px 8px;
945
- background: #21262d;
946
- border-radius: 4px;
947
- white-space: nowrap;
948
- }
949
-
950
- /* Turn navigation in toolbar */
951
- .turn-dropdown {
952
- padding: 6px 12px;
953
- background: #161b22;
954
- border: 1px solid #30363d;
955
- border-radius: 6px;
956
- color: #c9d1d9;
957
- font-size: 13px;
958
- cursor: pointer;
959
- min-width: 260px;
960
- transition: border-color 0.2s;
961
- }
962
-
963
- .turn-dropdown:hover {
964
- border-color: #58a6ff;
965
- }
966
-
967
- .turn-dropdown:focus {
968
- outline: none;
969
- border-color: #58a6ff;
970
- }
971
-
972
- .turn-dropdown optgroup {
973
- font-weight: 600;
974
- font-style: normal;
975
- color: #e6edf3;
976
- background: #21262d;
977
- padding: 4px 0;
978
- }
979
-
980
- .turn-dropdown option {
981
- font-weight: 400;
982
- color: #c9d1d9;
983
- background: #161b22;
984
- padding: 4px 8px;
985
- }
986
-
987
- /* Virtual Scroller */
988
- .vue-recycle-scroller {
989
- flex: 1;
990
- overflow-x: hidden !important;
991
- padding-bottom: env(safe-area-inset-bottom, 0px);
992
- }
993
- .vue-recycle-scroller__item-wrapper {
994
- overflow: visible !important;
995
- }
996
-
997
- /* Events */
998
- .event {
999
- background: #161b22;
1000
- border-left: 3px solid #30363d;
1001
- padding: 6px 12px 6px 12px;
1002
- margin: 0;
1003
- border-radius: 0;
1004
- font-size: 13px;
1005
- }
1006
- .event:nth-child(even) {
1007
- background: #1c2128;
1008
- }
1009
- /* Separator inside event (properly measured by virtual scroller) */
1010
- .event-separator {
1011
- height: 1px;
1012
- background: #0d1117;
1013
- margin: 12px 0 0 0;
1014
- }
1015
- .event.turn-boundary {
1016
- background: #1c2128;
1017
- border-left: 4px solid #8250df;
1018
- padding: 8px 12px;
1019
- box-shadow: 0 0 8px rgba(130, 80, 223, 0.15);
1020
- }
1021
- .event-header {
1022
- display: flex;
1023
- align-items: center;
1024
- gap: 8px;
1025
- margin-bottom: 6px;
1026
- }
1027
- .event-badge {
1028
- padding: 2px 8px;
1029
- border-radius: 3px;
1030
- font-size: 12px;
1031
- font-weight: 600;
1032
- white-space: nowrap;
1033
- min-width: 90px;
1034
- text-align: center;
1035
- display: inline-block;
1036
- line-height: 1.4;
1037
- }
1038
- .badge-user { background: #1f6feb; color: #fff; }
1039
- .badge-assistant { background: #238636; color: #fff; }
1040
- .badge-reasoning { background: #a371f7; color: #fff; }
1041
- .badge-turn { background: #8250df; color: #fff; }
1042
- .badge-tool { background: #9e6a03; color: #fff; }
1043
- .badge-subagent { background: #8957e5; color: #fff; }
1044
- .badge-skill { background: #bf3989; color: #fff; }
1045
- .badge-session { background: #6e7681; color: #fff; }
1046
- .badge-system { background: #444c56; color: #adbac7; font-style: italic; }
1047
- .badge-truncation { background: #e5534b; color: #fff; }
1048
- .badge-compaction { background: #c2442d; color: #fff; }
1049
- .badge-error { background: #da3633; color: #fff; }
1050
- .badge-warning { background: #d29922; color: #000; }
1051
- .badge-info { background: #58a6ff; color: #fff; }
1052
-
1053
- .event-content {
1054
- color: #c9d1d9;
1055
- text-align: left;
1056
- font-size: 13px;
1057
- }
1058
- /* Model change styling */
1059
- .model-change-content {
1060
- margin-top: 6px;
1061
- }
1062
-
1063
- .model-change-text {
1064
- font-size: 13px;
1065
- color: #e6edf3;
1066
- }
1067
-
1068
- .model-name {
1069
- color: #58a6ff;
1070
- font-weight: 600;
1071
- font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
1072
- font-size: 13px;
1073
- }
1074
-
1075
- .model-arrow {
1076
- color: #7d8590;
1077
- margin: 0 8px;
1078
- }
1079
-
1080
- /* Markdown styling */
1081
- .event-content code {
1082
- background: #161b22;
1083
- padding: 2px 6px;
1084
- border-radius: 3px;
1085
- font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
1086
- font-size: 12px;
1087
- color: #f0883e;
1088
- }
1089
- .event-content pre {
1090
- background: #161b22;
1091
- padding: 12px;
1092
- border-radius: 6px;
1093
- overflow-x: auto;
1094
- margin: 8px 0;
1095
- border: 1px solid #30363d;
1096
- font-size: 13px;
1097
- }
1098
- .event-content pre code {
1099
- background: none;
1100
- padding: 0;
1101
- color: #e6edf3;
1102
- }
1103
- .event-content a {
1104
- color: #58a6ff;
1105
- text-decoration: none;
1106
- }
1107
- .event-content a:hover {
1108
- text-decoration: underline;
1109
- }
1110
- .event-content ul, .event-content ol {
1111
- padding-left: 24px;
1112
- margin: 8px 0;
1113
- }
1114
- .event-content li {
1115
- margin: 4px 0;
1116
- }
1117
- .event-content blockquote {
1118
- border-left: 3px solid #30363d;
1119
- padding-left: 12px;
1120
- margin: 8px 0;
1121
- color: #c9d1d9;
1122
- }
1123
- .event-content strong {
1124
- color: #e6edf3;
1125
- font-weight: 600;
1126
- }
1127
- .event-content em {
1128
- color: #e6edf3;
1129
- font-style: italic;
1130
- }
1131
- .event-content h1, .event-content h2, .event-content h3,
1132
- .event-content h4, .event-content h5, .event-content h6 {
1133
- color: #e6edf3;
1134
- margin: 12px 0 6px 0;
1135
- font-weight: 600;
1136
- }
1137
- .event-content h1 { font-size: 16px; }
1138
- .event-content h2 { font-size: 15px; }
1139
- .event-content h3 { font-size: 14px; }
1140
- .event-content h4 { font-size: 13px; }
1141
- .event-content p {
1142
- margin: 6px 0;
1143
- }
1144
-
1145
- /* Reasoning text: muted color — placed after .event-content markdown rules
1146
- so the higher-specificity selectors (0,2,1) override .event-content strong etc. (0,1,1) */
1147
- .reasoning-text-content.event-content,
1148
- .reasoning-text-content.event-content strong,
1149
- .reasoning-text-content.event-content em,
1150
- .reasoning-text-content.event-content h1,
1151
- .reasoning-text-content.event-content h2,
1152
- .reasoning-text-content.event-content h3,
1153
- .reasoning-text-content.event-content h4,
1154
- .reasoning-text-content.event-content h5,
1155
- .reasoning-text-content.event-content h6,
1156
- .reasoning-text-content.event-content code,
1157
- .reasoning-text-content.event-content a {
1158
- color: #7d8590;
1159
- }
1160
-
1161
- /* Markdown table styling */
1162
- .event-content table {
1163
- border-collapse: collapse;
1164
- width: 100%;
1165
- margin: 12px 0;
1166
- background: #161b22;
1167
- border: 1px solid #30363d;
1168
- border-radius: 6px;
1169
- overflow: hidden;
1170
- }
1171
- .event-content th {
1172
- background: #21262d;
1173
- padding: 8px 12px;
1174
- text-align: left;
1175
- font-weight: 600;
1176
- color: #e6edf3;
1177
- border-bottom: 1px solid #30363d;
1178
- }
1179
- .event-content td {
1180
- padding: 8px 12px;
1181
- border-bottom: 1px solid #30363d;
1182
- }
1183
- .event-content tr:last-child td {
1184
- border-bottom: none;
1185
- }
1186
- .event-content tbody tr:hover {
1187
- background: rgba(110, 118, 129, 0.1);
1188
- }
1189
-
1190
- .event-timestamp {
1191
- font-size: 12px;
1192
- color: #c9d1d9;
1193
- }
1194
-
1195
- /* Tool calls */
1196
- .tool-list {
1197
- margin-top: 6px;
1198
- padding-left: 0;
1199
- }
1200
- .tool-item {
1201
- padding: 2px 0;
1202
- }
1203
- .tool-header-line {
1204
- color: #c9d1d9;
1205
- font-size: 13px;
1206
- font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
1207
- cursor: pointer;
1208
- user-select: none;
1209
- line-height: 1.4;
1210
- display: flex;
1211
- align-items: baseline;
1212
- gap: 0;
1213
- padding: 2px 0;
1214
- flex-wrap: wrap;
1215
- }
1216
- .tool-header-line:hover {
1217
- color: #c9d1d9;
1218
- }
1219
- .tool-connector {
1220
- color: #6e7681;
1221
- margin-right: 0;
1222
- flex-shrink: 0;
1223
- line-height: 1;
1224
- }
1225
- .tool-expand-icon {
1226
- color: #6e7681;
1227
- margin: 0 4px;
1228
- display: inline-flex;
1229
- align-items: center;
1230
- justify-content: center;
1231
- width: 12px;
1232
- height: 12px;
1233
- flex-shrink: 0;
1234
- line-height: 1;
1235
- transform: translateY(-1px);
1236
- }
1237
- .tool-name {
1238
- color: #f0883e;
1239
- flex-shrink: 0;
1240
- margin-right: 4px;
1241
- }
1242
- .tool-status-success {
1243
- color: #238636;
1244
- }
1245
- .tool-status-error {
1246
- color: #da3633;
1247
- }
1248
- .tool-status-running {
1249
- color: #d29922;
1250
- }
1251
- .tool-detail {
1252
- margin-top: 4px;
1253
- padding: 8px;
1254
- background: rgba(110, 118, 129, 0.05);
1255
- border-radius: 3px;
1256
- border: 1px solid #30363d;
1257
- font-size: 12px;
1258
- }
1259
- .tool-detail-section {
1260
- margin-bottom: 6px;
1261
- }
1262
- .tool-detail-section:last-child {
1263
- margin-bottom: 0;
1264
- }
1265
- .tool-detail-title {
1266
- color: #7d8590;
1267
- margin-bottom: 2px;
1268
- font-weight: 600;
1269
- font-size: 12px;
1270
- }
1271
- .tool-detail-content pre {
1272
- margin: 0;
1273
- padding: 4px 6px;
1274
- background: #0d1117;
1275
- border-radius: 3px;
1276
- overflow-x: auto;
1277
- max-height: 200px;
1278
- font-size: 12px;
1279
- line-height: 1.3;
1280
- color: #e6edf3;
1281
- }
1282
- .tool-timing-line {
1283
- display: flex;
1284
- flex-wrap: wrap;
1285
- gap: 4px 16px;
1286
- }
1287
- .tool-timing-label {
1288
- color: #8b949e;
1289
- font-weight: 500;
1290
- margin-right: 3px;
1291
- }
1292
-
1293
- /* Turn divider - Design 3: Slack Style (居中对称) */
1294
- .turn-divider {
1295
- display: flex;
1296
- align-items: center;
1297
- gap: 12px;
1298
- padding: 12px 12px;
1299
- margin: 0;
1300
- background: transparent;
1301
- }
1302
- .turn-divider::before,
1303
- .turn-divider::after {
1304
- content: '';
1305
- flex: 1;
1306
- height: 1px;
1307
- background: #30363d;
1308
- }
1309
- .turn-divider-text {
1310
- color: #7d8590;
1311
- font-size: 12px;
1312
- font-weight: 600;
1313
- text-transform: uppercase;
1314
- letter-spacing: 0.8px;
1315
- white-space: nowrap;
1316
- padding: 2px 8px;
1317
- background: #0d1117;
1318
- border-radius: 10px;
1319
- border: 1px solid #21262d;
1320
- margin: 0;
1321
- display: flex;
1322
- align-items: center;
1323
- gap: 6px;
1324
- }
1325
- .turn-time { color: #58a6ff; font-weight: 500; text-transform: none; letter-spacing: 0; }
1326
- .turn-duration { color: #3fb950; font-weight: 500; text-transform: none; letter-spacing: 0; }
1327
- .turn-duration::before { content: '⏱ '; }
1328
- .turn-divider-line-left,
1329
- .turn-divider-line-right {
1330
- display: none;
1331
- }
1332
-
1333
- /* Divider separator (for turn and subagent dividers) - HIDDEN */
1334
- .divider-separator {
1335
- display: none;
1336
- }
1337
-
1338
- /* Subagent divider - Slack Style (unified color) */
1339
- .subagent-divider {
1340
- display: flex;
1341
- align-items: center;
1342
- gap: 12px;
1343
- padding: 12px 12px;
1344
- margin: 0;
1345
- background: transparent;
1346
- }
1347
- .subagent-divider::before,
1348
- .subagent-divider::after {
1349
- content: '';
1350
- flex: 1;
1351
- height: 1px;
1352
- background: var(--sa-color, #58a6ff);
1353
- }
1354
- .subagent-divider-text {
1355
- font-size: 12px;
1356
- font-weight: 600;
1357
- white-space: nowrap;
1358
- letter-spacing: 0.8px;
1359
- padding: 2px 8px;
1360
- border-radius: 10px;
1361
- border: 1px solid #58a6ff;
1362
- margin: 0;
1363
- text-transform: uppercase;
1364
- color: #58a6ff;
1365
- background: rgba(88, 166, 255, 0.1);
1366
- }
1367
- .subagent-divider-line-left,
1368
- .subagent-divider-line-right {
1369
- display: none;
1370
- }
1371
- .event.event-in-subagent { border-left-color: var(--subagent-border-color, #58a6ff); }
1372
- .subagent-owner-tag { font-size: 11px; padding: 1px 6px; border-radius: 8px; border: 1px solid; border-color: var(--subagent-color, #58a6ff); color: var(--subagent-color, #58a6ff); white-space: nowrap; opacity: 0.85; cursor: pointer; transition: opacity 0.15s; }
1373
- .subagent-owner-tag:hover { opacity: 1; background: var(--subagent-hover-bg, rgba(88, 166, 255, 0.15)); }
1374
- .subagent-name-badge { font-size: 11px; padding: 2px 8px; border-radius: 4px; border: 1px solid; white-space: nowrap; font-weight: 600; max-width: 280px; overflow: hidden; text-overflow: ellipsis; }
1375
-
1376
- /* Bottom spacer for last event visibility */
1377
- .scroller-bottom-spacer {
1378
- height: max(env(safe-area-inset-bottom, 0px), 16px);
1379
- flex-shrink: 0;
1380
- }
1381
-
1382
- /* Sidebar backdrop — hidden by default, shown via mobile media query */
1383
- .sidebar-backdrop {
1384
- display: none;
1385
- }
1386
-
1387
- /* ── Tablet responsive ─────────────────────────────────── */
1388
- @media (max-width: 768px) {
1389
- .filter-bar-search {
1390
- flex: 1 1 100%;
1391
- order: 1;
1392
- }
1393
- .filter-bar-row {
1394
- flex-wrap: wrap;
1395
- }
1396
- .filter-bar-divider {
1397
- display: none;
1398
- }
1399
- .subagent-usage-badge {
1400
- display: none;
1401
- }
1402
- }
1403
-
1404
- /* ── Mobile responsive ────────────────────────────────────── */
1405
- @media (max-width: 640px) {
1406
- /* Header: smaller, wrap if needed */
1407
- .header {
1408
- padding: 8px 12px;
1409
- flex-wrap: wrap;
1410
- gap: 8px;
1411
- }
1412
- .header-title {
1413
- font-size: 13px;
1414
- overflow: hidden;
1415
- text-overflow: ellipsis;
1416
- white-space: nowrap;
1417
- max-width: calc(100vw - 80px);
1418
- }
1419
- .time-analyze-btn,
1420
- .share-btn {
1421
- padding: 5px 8px;
1422
- font-size: 12px;
1423
- }
1424
-
1425
- /* Sidebar backdrop (mobile only) */
1426
- .sidebar-backdrop {
1427
- display: block;
1428
- position: fixed;
1429
- inset: 0;
1430
- background: rgba(0,0,0,0.5);
1431
- z-index: 999;
1432
- }
1433
-
1434
- /* Sidebar: hidden by default on mobile, overlay when open */
1435
- .sidebar {
1436
- position: fixed;
1437
- top: 0;
1438
- left: 0;
1439
- height: 100%;
1440
- width: 280px !important;
1441
- z-index: 1000;
1442
- box-shadow: 4px 0 16px rgba(0,0,0,0.6);
1443
- transform: translateX(-100%);
1444
- transition: transform 0.3s ease;
1445
- }
1446
- .sidebar:not(.collapsed) {
1447
- transform: translateX(0);
1448
- }
1449
- .sidebar.collapsed {
1450
- transform: translateX(-100%);
1451
- width: 280px !important;
1452
- padding: 16px !important;
1453
- border-right: 1px solid #30363d !important;
1454
- overflow-y: auto !important;
1455
- }
1456
-
1457
- /* Content: full width */
1458
- .content {
1459
- width: 100%;
1460
- }
1461
-
1462
- /* Toolbar: unified responsive layout */
1463
- .filter-bar-row {
1464
- flex-wrap: wrap;
1465
- gap: 4px;
1466
- padding: 6px 8px;
1467
- }
1468
- .filter-bar-search {
1469
- flex: 1 1 100%;
1470
- order: 1;
1471
- }
1472
- .sidebar-toggle {
1473
- order: 0;
1474
- }
1475
- .filter-bar-divider {
1476
- display: none;
1477
- }
1478
- .turn-dropdown {
1479
- order: 2;
1480
- flex: 1;
1481
- min-width: 0;
1482
- max-width: 140px;
1483
- font-size: 12px;
1484
- }
1485
- .subagent-selector {
1486
- order: 3;
1487
- }
1488
- .filter-type-wrapper {
1489
- order: 4;
1490
- }
1491
- .search-input {
1492
- flex: 1;
1493
- min-width: 0;
1494
- font-size: 12px;
1495
- }
1496
- .subagent-dropdown {
1497
- max-width: 130px;
1498
- font-size: 12px;
1499
- }
1500
- .subagent-usage-badge {
1501
- display: none;
1502
- }
1503
-
1504
- .usage-summary {
1505
- padding: 12px;
1506
- }
1507
- .usage-summary-total {
1508
- font-size: 20px;
1509
- }
1510
- .usage-summary-metrics,
1511
- .usage-metric-grid-compact {
1512
- grid-template-columns: repeat(2, minmax(0, 1fr));
1513
- }
1514
- .usage-model-header {
1515
- gap: 6px;
1516
- }
1517
- .usage-model-meta {
1518
- justify-content: flex-start;
1519
- }
1520
-
1521
- /* Float buttons: slightly smaller, keep fixed */
1522
- .scroll-float-btns {
1523
- bottom: 16px;
1524
- right: 12px;
1525
- }
1526
-
1527
- /* Prevent content from stretching wider than viewport */
1528
- .event-card {
1529
- max-width: 100%;
1530
- overflow-x: hidden;
1531
- }
1532
- .event-content pre {
1533
- max-width: calc(100vw - 32px);
1534
- }
1535
- .tool-command {
1536
- word-break: break-all;
1537
- }
1538
- /* Tool command text wraps on mobile */
1539
- .tool-header-line {
1540
- overflow-wrap: anywhere;
1541
- word-break: break-all;
1542
- }
1543
- /* Extra bottom padding for mobile browser nav bar */
1544
- .vue-recycle-scroller {
1545
- padding-bottom: max(env(safe-area-inset-bottom, 0px), 80px);
1546
- }
1547
- .scroller-bottom-spacer {
1548
- height: max(env(safe-area-inset-bottom, 0px), 100px);
1549
- }
1550
- .scroll-edge-btn {
1551
- width: 28px;
1552
- height: 28px;
1553
- font-size: 12px;
1554
- }
1555
- }
1556
- </style>
1557
- </head>
1558
- <body>
1559
- <div id="app"></div>
1560
-
1561
- <script>
1562
- window.__PAGE_DATA = {
1563
- sessionId: "<%= sessionId %>",
1564
- events: <%- JSON.stringify(events) %>,
1565
- metadata: <%- JSON.stringify(metadata) %>
1566
- };
1567
- </script>
1568
- <script src="/public/js/session-detail.min.js"></script>
1569
- </body>
1570
- </html>