@qiaolei81/copilot-session-viewer 0.3.5 → 0.3.7
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.
- package/README.md +3 -3
- package/dist/server.min.js +45 -40
- package/package.json +10 -8
- package/public/js/homepage.min.js +9 -9
- package/public/js/session-detail.min.js +105 -7
- package/views/index.ejs +243 -0
- package/views/session-vue.ejs +140 -2
package/views/index.ejs
CHANGED
|
@@ -175,6 +175,7 @@
|
|
|
175
175
|
-webkit-line-clamp: 3;
|
|
176
176
|
-webkit-box-orient: vertical;
|
|
177
177
|
overflow: hidden;
|
|
178
|
+
cursor: help;
|
|
178
179
|
}
|
|
179
180
|
.session-divider {
|
|
180
181
|
height: 1px;
|
|
@@ -562,6 +563,248 @@
|
|
|
562
563
|
.date-group-header:first-child {
|
|
563
564
|
margin-top: 0;
|
|
564
565
|
}
|
|
566
|
+
|
|
567
|
+
/* Custom summary tooltip */
|
|
568
|
+
.summary-tooltip {
|
|
569
|
+
display: none;
|
|
570
|
+
position: fixed;
|
|
571
|
+
z-index: 9999;
|
|
572
|
+
background: #1c2128;
|
|
573
|
+
border: 1px solid #30363d;
|
|
574
|
+
border-radius: 8px;
|
|
575
|
+
padding: 12px 16px;
|
|
576
|
+
max-width: 600px;
|
|
577
|
+
width: max-content;
|
|
578
|
+
max-height: 400px;
|
|
579
|
+
overflow-y: auto;
|
|
580
|
+
font-size: 13px;
|
|
581
|
+
line-height: 1.6;
|
|
582
|
+
color: #c9d1d9;
|
|
583
|
+
white-space: normal;
|
|
584
|
+
word-break: break-word;
|
|
585
|
+
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
|
586
|
+
pointer-events: none;
|
|
587
|
+
}
|
|
588
|
+
.summary-tooltip.visible {
|
|
589
|
+
display: block;
|
|
590
|
+
pointer-events: auto;
|
|
591
|
+
}
|
|
592
|
+
/* Markdown prose styles inside tooltip */
|
|
593
|
+
.summary-tooltip h1, .summary-tooltip h2, .summary-tooltip h3,
|
|
594
|
+
.summary-tooltip h4, .summary-tooltip h5, .summary-tooltip h6 {
|
|
595
|
+
color: #e6edf3; margin: 8px 0 4px; font-weight: 600;
|
|
596
|
+
}
|
|
597
|
+
.summary-tooltip h1 { font-size: 15px; }
|
|
598
|
+
.summary-tooltip h2 { font-size: 14px; }
|
|
599
|
+
.summary-tooltip h3, .summary-tooltip h4 { font-size: 13px; }
|
|
600
|
+
.summary-tooltip p { margin: 4px 0; }
|
|
601
|
+
.summary-tooltip ul, .summary-tooltip ol { margin: 4px 0; padding-left: 18px; }
|
|
602
|
+
.summary-tooltip li { margin: 2px 0; }
|
|
603
|
+
.summary-tooltip code {
|
|
604
|
+
background: #2d333b; border-radius: 3px;
|
|
605
|
+
padding: 1px 4px; font-size: 12px; font-family: monospace;
|
|
606
|
+
}
|
|
607
|
+
.summary-tooltip pre {
|
|
608
|
+
background: #2d333b; border-radius: 6px;
|
|
609
|
+
padding: 8px 10px; overflow-x: auto; margin: 6px 0;
|
|
610
|
+
}
|
|
611
|
+
.summary-tooltip pre code { background: none; padding: 0; }
|
|
612
|
+
.summary-tooltip strong { color: #e6edf3; }
|
|
613
|
+
.summary-tooltip hr { border-color: #30363d; margin: 8px 0; }
|
|
614
|
+
|
|
615
|
+
/* Hide hover tooltip on touch devices */
|
|
616
|
+
@media (hover: none) {
|
|
617
|
+
.summary-tooltip { display: none !important; }
|
|
618
|
+
}
|
|
619
|
+
/* Bottom sheet for mobile long-press */
|
|
620
|
+
.bottom-sheet-overlay {
|
|
621
|
+
display: none;
|
|
622
|
+
position: fixed;
|
|
623
|
+
inset: 0;
|
|
624
|
+
background: rgba(0,0,0,0.5);
|
|
625
|
+
z-index: 1000;
|
|
626
|
+
touch-action: none;
|
|
627
|
+
}
|
|
628
|
+
.bottom-sheet-overlay.visible { display: block; }
|
|
629
|
+
.bottom-sheet {
|
|
630
|
+
position: fixed;
|
|
631
|
+
bottom: 0;
|
|
632
|
+
left: 0;
|
|
633
|
+
right: 0;
|
|
634
|
+
background: #161b22;
|
|
635
|
+
border-top: 1px solid #30363d;
|
|
636
|
+
border-radius: 16px 16px 0 0;
|
|
637
|
+
padding: 0 16px max(env(safe-area-inset-bottom, 0px), 24px);
|
|
638
|
+
max-height: 70vh;
|
|
639
|
+
overflow-y: auto;
|
|
640
|
+
z-index: 1001;
|
|
641
|
+
transform: translateY(100%);
|
|
642
|
+
transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
|
|
643
|
+
}
|
|
644
|
+
.bottom-sheet.visible { transform: translateY(0); }
|
|
645
|
+
.bottom-sheet-handle {
|
|
646
|
+
width: 36px;
|
|
647
|
+
height: 4px;
|
|
648
|
+
background: #444c56;
|
|
649
|
+
border-radius: 2px;
|
|
650
|
+
margin: 12px auto 16px;
|
|
651
|
+
}
|
|
652
|
+
.bottom-sheet-content {
|
|
653
|
+
font-size: 14px;
|
|
654
|
+
line-height: 1.6;
|
|
655
|
+
color: #c9d1d9;
|
|
656
|
+
}
|
|
657
|
+
.bottom-sheet-content h1, .bottom-sheet-content h2, .bottom-sheet-content h3 { color: #e6edf3; margin: 12px 0 6px; }
|
|
658
|
+
.bottom-sheet-content h1 { font-size: 16px; }
|
|
659
|
+
.bottom-sheet-content h2 { font-size: 15px; }
|
|
660
|
+
.bottom-sheet-content h3 { font-size: 14px; }
|
|
661
|
+
.bottom-sheet-content p { margin: 6px 0; }
|
|
662
|
+
.bottom-sheet-content ul, .bottom-sheet-content ol { margin: 6px 0; padding-left: 20px; }
|
|
663
|
+
.bottom-sheet-content li { margin: 3px 0; }
|
|
664
|
+
.bottom-sheet-content code { background: #0d1117; padding: 1px 5px; border-radius: 4px; font-size: 13px; }
|
|
665
|
+
.bottom-sheet-content pre { background: #0d1117; padding: 10px; border-radius: 6px; overflow-x: auto; }
|
|
666
|
+
.bottom-sheet-content pre code { background: none; padding: 0; }
|
|
667
|
+
.bottom-sheet-content strong { color: #e6edf3; }
|
|
668
|
+
.bottom-sheet-content hr { border-color: #30363d; margin: 10px 0; }
|
|
565
669
|
</style>
|
|
670
|
+
|
|
671
|
+
<script src="https://cdn.jsdelivr.net/npm/marked@9/marked.min.js"></script>
|
|
672
|
+
<div id="summary-tooltip" class="summary-tooltip"></div>
|
|
673
|
+
|
|
674
|
+
<script>
|
|
675
|
+
const tooltip = document.getElementById('summary-tooltip');
|
|
676
|
+
let tooltipTarget = null;
|
|
677
|
+
let hideTimer = null;
|
|
678
|
+
let showTimer = null;
|
|
679
|
+
let pendingEl = null;
|
|
680
|
+
let pendingEvent = null;
|
|
681
|
+
|
|
682
|
+
function showTooltip(el, e) {
|
|
683
|
+
clearTimeout(hideTimer);
|
|
684
|
+
tooltipTarget = el;
|
|
685
|
+
if (!el.dataset.tooltipText) {
|
|
686
|
+
el.dataset.tooltipText = el.getAttribute('title');
|
|
687
|
+
el.removeAttribute('title');
|
|
688
|
+
}
|
|
689
|
+
const md = el.dataset.tooltipText || '';
|
|
690
|
+
tooltip.innerHTML = (typeof marked !== 'undefined')
|
|
691
|
+
? marked.parse(md, { breaks: true })
|
|
692
|
+
: md.replace(/</g, '<').replace(/\n/g, '<br>');
|
|
693
|
+
tooltip.classList.add('visible');
|
|
694
|
+
positionTooltip(e);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
function scheduleShow(el, e) {
|
|
698
|
+
clearTimeout(showTimer);
|
|
699
|
+
pendingEl = el;
|
|
700
|
+
pendingEvent = e;
|
|
701
|
+
showTimer = setTimeout(() => {
|
|
702
|
+
if (pendingEl) showTooltip(pendingEl, pendingEvent);
|
|
703
|
+
}, 500);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
function cancelShow() {
|
|
707
|
+
clearTimeout(showTimer);
|
|
708
|
+
pendingEl = null;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function scheduleHide() {
|
|
712
|
+
cancelShow();
|
|
713
|
+
hideTimer = setTimeout(() => {
|
|
714
|
+
tooltipTarget = null;
|
|
715
|
+
tooltip.classList.remove('visible');
|
|
716
|
+
}, 120);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
document.addEventListener('mouseover', e => {
|
|
720
|
+
const el = e.target.closest('.session-summary');
|
|
721
|
+
if (el) { clearTimeout(hideTimer); scheduleShow(el, e); return; }
|
|
722
|
+
if (e.target.closest('#summary-tooltip')) { clearTimeout(hideTimer); cancelShow(); return; }
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
document.addEventListener('mousemove', e => {
|
|
726
|
+
if (pendingEl) { pendingEvent = e; }
|
|
727
|
+
if (!tooltipTarget) return;
|
|
728
|
+
if (e.target.closest('#summary-tooltip')) return;
|
|
729
|
+
positionTooltip(e);
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
document.addEventListener('mouseout', e => {
|
|
733
|
+
const toEl = e.relatedTarget;
|
|
734
|
+
if (toEl && (toEl.closest('.session-summary') || toEl.closest('#summary-tooltip'))) return;
|
|
735
|
+
scheduleHide();
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
tooltip.addEventListener('mouseleave', () => scheduleHide());
|
|
739
|
+
|
|
740
|
+
function positionTooltip(e) {
|
|
741
|
+
const pad = 14;
|
|
742
|
+
const tw = tooltip.offsetWidth;
|
|
743
|
+
const th = tooltip.offsetHeight;
|
|
744
|
+
let x = e.clientX + pad;
|
|
745
|
+
let y = e.clientY + pad;
|
|
746
|
+
if (x + tw > window.innerWidth - 8) x = e.clientX - tw - pad;
|
|
747
|
+
if (y + th > window.innerHeight - 8) y = e.clientY - th - pad;
|
|
748
|
+
tooltip.style.left = x + 'px';
|
|
749
|
+
tooltip.style.top = y + 'px';
|
|
750
|
+
}
|
|
751
|
+
</script>
|
|
752
|
+
|
|
753
|
+
<!-- Bottom sheet for mobile long-press summary -->
|
|
754
|
+
<div id="sheet-overlay" class="bottom-sheet-overlay">
|
|
755
|
+
<div id="bottom-sheet" class="bottom-sheet">
|
|
756
|
+
<div class="bottom-sheet-handle"></div>
|
|
757
|
+
<div id="sheet-content" class="bottom-sheet-content"></div>
|
|
758
|
+
</div>
|
|
759
|
+
</div>
|
|
760
|
+
|
|
761
|
+
<script>
|
|
762
|
+
const sheetOverlay = document.getElementById('sheet-overlay');
|
|
763
|
+
const bottomSheet = document.getElementById('bottom-sheet');
|
|
764
|
+
const sheetContent = document.getElementById('sheet-content');
|
|
765
|
+
|
|
766
|
+
function openSheet(md) {
|
|
767
|
+
sheetContent.innerHTML = (typeof marked !== 'undefined')
|
|
768
|
+
? marked.parse(md, { breaks: true })
|
|
769
|
+
: md.replace(/</g, '<').replace(/\n/g, '<br>');
|
|
770
|
+
sheetOverlay.classList.add('visible');
|
|
771
|
+
requestAnimationFrame(() => bottomSheet.classList.add('visible'));
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
function closeSheet() {
|
|
775
|
+
bottomSheet.classList.remove('visible');
|
|
776
|
+
setTimeout(() => sheetOverlay.classList.remove('visible'), 280);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
sheetOverlay.addEventListener('click', e => {
|
|
780
|
+
if (!bottomSheet.contains(e.target)) closeSheet();
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
// Long-press detection (500ms)
|
|
784
|
+
let lpTimer = null;
|
|
785
|
+
let lpMoved = false;
|
|
786
|
+
|
|
787
|
+
document.addEventListener('touchstart', e => {
|
|
788
|
+
const el = e.target.closest('.session-summary');
|
|
789
|
+
if (!el) return;
|
|
790
|
+
lpMoved = false;
|
|
791
|
+
const md = el.dataset.tooltipText || el.getAttribute('title') || '';
|
|
792
|
+
if (!md) return;
|
|
793
|
+
lpTimer = setTimeout(() => {
|
|
794
|
+
if (!lpMoved) {
|
|
795
|
+
e.preventDefault();
|
|
796
|
+
openSheet(md);
|
|
797
|
+
}
|
|
798
|
+
}, 500);
|
|
799
|
+
}, { passive: false });
|
|
800
|
+
|
|
801
|
+
document.addEventListener('touchmove', () => {
|
|
802
|
+
lpMoved = true;
|
|
803
|
+
clearTimeout(lpTimer);
|
|
804
|
+
}, { passive: true });
|
|
805
|
+
|
|
806
|
+
document.addEventListener('touchend', () => clearTimeout(lpTimer), { passive: true });
|
|
807
|
+
document.addEventListener('touchcancel', () => clearTimeout(lpTimer), { passive: true });
|
|
808
|
+
</script>
|
|
566
809
|
</body>
|
|
567
810
|
</html>
|
package/views/session-vue.ejs
CHANGED
|
@@ -475,6 +475,119 @@
|
|
|
475
475
|
color: #f85149;
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
/* Usage Section */
|
|
479
|
+
.usage-container {
|
|
480
|
+
font-size: 12px;
|
|
481
|
+
}
|
|
482
|
+
.usage-compact {
|
|
483
|
+
padding: 8px;
|
|
484
|
+
background: #21262d;
|
|
485
|
+
border: 1px solid #30363d;
|
|
486
|
+
border-radius: 4px;
|
|
487
|
+
color: #c9d1d9;
|
|
488
|
+
cursor: pointer;
|
|
489
|
+
transition: all 0.2s;
|
|
490
|
+
display: flex;
|
|
491
|
+
align-items: center;
|
|
492
|
+
justify-content: space-between;
|
|
493
|
+
}
|
|
494
|
+
.usage-compact:hover {
|
|
495
|
+
background: #30363d;
|
|
496
|
+
border-color: #58a6ff;
|
|
497
|
+
}
|
|
498
|
+
.usage-expand-icon {
|
|
499
|
+
color: #8b949e;
|
|
500
|
+
font-size: 10px;
|
|
501
|
+
}
|
|
502
|
+
.usage-expanded {
|
|
503
|
+
margin-top: 12px;
|
|
504
|
+
padding: 12px;
|
|
505
|
+
background: rgba(110, 118, 129, 0.05);
|
|
506
|
+
border: 1px solid #30363d;
|
|
507
|
+
border-radius: 6px;
|
|
508
|
+
}
|
|
509
|
+
.usage-section {
|
|
510
|
+
margin-bottom: 12px;
|
|
511
|
+
}
|
|
512
|
+
.usage-section:last-child {
|
|
513
|
+
margin-bottom: 0;
|
|
514
|
+
}
|
|
515
|
+
.usage-section-title {
|
|
516
|
+
font-size: 11px;
|
|
517
|
+
font-weight: 600;
|
|
518
|
+
color: #8b949e;
|
|
519
|
+
text-transform: uppercase;
|
|
520
|
+
letter-spacing: 0.5px;
|
|
521
|
+
margin-bottom: 8px;
|
|
522
|
+
}
|
|
523
|
+
.usage-model {
|
|
524
|
+
padding: 8px;
|
|
525
|
+
background: #161b22;
|
|
526
|
+
border-radius: 4px;
|
|
527
|
+
margin-bottom: 6px;
|
|
528
|
+
}
|
|
529
|
+
.usage-model:last-child {
|
|
530
|
+
margin-bottom: 0;
|
|
531
|
+
}
|
|
532
|
+
.usage-model-name {
|
|
533
|
+
font-size: 11px;
|
|
534
|
+
font-weight: 600;
|
|
535
|
+
color: #58a6ff;
|
|
536
|
+
margin-bottom: 4px;
|
|
537
|
+
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
|
538
|
+
}
|
|
539
|
+
.usage-model-details {
|
|
540
|
+
font-size: 12px;
|
|
541
|
+
color: #c9d1d9;
|
|
542
|
+
display: flex;
|
|
543
|
+
flex-direction: column;
|
|
544
|
+
gap: 2px;
|
|
545
|
+
}
|
|
546
|
+
.usage-model-details > div {
|
|
547
|
+
display: flex;
|
|
548
|
+
gap: 8px;
|
|
549
|
+
align-items: center;
|
|
550
|
+
}
|
|
551
|
+
.usage-token-label {
|
|
552
|
+
color: #8b949e;
|
|
553
|
+
font-weight: 500;
|
|
554
|
+
min-width: 40px;
|
|
555
|
+
}
|
|
556
|
+
.usage-cache-ratio {
|
|
557
|
+
color: #3fb950;
|
|
558
|
+
font-weight: 600;
|
|
559
|
+
}
|
|
560
|
+
.usage-context {
|
|
561
|
+
font-size: 12px;
|
|
562
|
+
color: #c9d1d9;
|
|
563
|
+
display: flex;
|
|
564
|
+
flex-direction: column;
|
|
565
|
+
gap: 4px;
|
|
566
|
+
}
|
|
567
|
+
.usage-context > div {
|
|
568
|
+
display: flex;
|
|
569
|
+
gap: 8px;
|
|
570
|
+
align-items: center;
|
|
571
|
+
}
|
|
572
|
+
.usage-code-changes {
|
|
573
|
+
font-size: 12px;
|
|
574
|
+
color: #c9d1d9;
|
|
575
|
+
display: flex;
|
|
576
|
+
gap: 8px;
|
|
577
|
+
align-items: center;
|
|
578
|
+
}
|
|
579
|
+
.usage-code-added {
|
|
580
|
+
color: #3fb950;
|
|
581
|
+
font-weight: 600;
|
|
582
|
+
}
|
|
583
|
+
.usage-code-removed {
|
|
584
|
+
color: #f85149;
|
|
585
|
+
font-weight: 600;
|
|
586
|
+
}
|
|
587
|
+
.usage-code-files {
|
|
588
|
+
color: #8b949e;
|
|
589
|
+
}
|
|
590
|
+
|
|
478
591
|
/* Content */
|
|
479
592
|
.content {
|
|
480
593
|
flex: 1;
|
|
@@ -807,7 +920,6 @@
|
|
|
807
920
|
text-align: left;
|
|
808
921
|
font-size: 13px;
|
|
809
922
|
}
|
|
810
|
-
|
|
811
923
|
/* Model change styling */
|
|
812
924
|
.model-change-content {
|
|
813
925
|
margin-top: 6px;
|
|
@@ -894,6 +1006,22 @@
|
|
|
894
1006
|
.event-content p {
|
|
895
1007
|
margin: 6px 0;
|
|
896
1008
|
}
|
|
1009
|
+
|
|
1010
|
+
/* Reasoning text: muted color — placed after .event-content markdown rules
|
|
1011
|
+
so the higher-specificity selectors (0,2,1) override .event-content strong etc. (0,1,1) */
|
|
1012
|
+
.reasoning-text-content.event-content,
|
|
1013
|
+
.reasoning-text-content.event-content strong,
|
|
1014
|
+
.reasoning-text-content.event-content em,
|
|
1015
|
+
.reasoning-text-content.event-content h1,
|
|
1016
|
+
.reasoning-text-content.event-content h2,
|
|
1017
|
+
.reasoning-text-content.event-content h3,
|
|
1018
|
+
.reasoning-text-content.event-content h4,
|
|
1019
|
+
.reasoning-text-content.event-content h5,
|
|
1020
|
+
.reasoning-text-content.event-content h6,
|
|
1021
|
+
.reasoning-text-content.event-content code,
|
|
1022
|
+
.reasoning-text-content.event-content a {
|
|
1023
|
+
color: #7d8590;
|
|
1024
|
+
}
|
|
897
1025
|
|
|
898
1026
|
/* Markdown table styling */
|
|
899
1027
|
.event-content table {
|
|
@@ -1016,6 +1144,16 @@
|
|
|
1016
1144
|
line-height: 1.3;
|
|
1017
1145
|
color: #e6edf3;
|
|
1018
1146
|
}
|
|
1147
|
+
.tool-timing-line {
|
|
1148
|
+
display: flex;
|
|
1149
|
+
flex-wrap: wrap;
|
|
1150
|
+
gap: 4px 16px;
|
|
1151
|
+
}
|
|
1152
|
+
.tool-timing-label {
|
|
1153
|
+
color: #8b949e;
|
|
1154
|
+
font-weight: 500;
|
|
1155
|
+
margin-right: 3px;
|
|
1156
|
+
}
|
|
1019
1157
|
|
|
1020
1158
|
/* Turn divider - Design 3: Slack Style (居中对称) */
|
|
1021
1159
|
.turn-divider {
|
|
@@ -1101,7 +1239,7 @@
|
|
|
1101
1239
|
|
|
1102
1240
|
/* Bottom spacer for last event visibility */
|
|
1103
1241
|
.scroller-bottom-spacer {
|
|
1104
|
-
height: max(env(safe-area-inset-bottom, 0px),
|
|
1242
|
+
height: max(env(safe-area-inset-bottom, 0px), 16px);
|
|
1105
1243
|
flex-shrink: 0;
|
|
1106
1244
|
}
|
|
1107
1245
|
|