@linxiraos/pi-stats 1.1.7 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +2 -6
  2. package/dist/client/index.css +1 -1
  3. package/dist/client/index.js +101 -101
  4. package/dist/client/styles.css +362 -98
  5. package/dist/types/client/api.d.ts +7 -1
  6. package/dist/types/client/app/routes.d.ts +1 -1
  7. package/dist/types/client/data/useHashRoute.d.ts +2 -0
  8. package/dist/types/client/routes/TracesRoute.d.ts +11 -0
  9. package/dist/types/client/routes/index.d.ts +1 -0
  10. package/dist/types/client/traces/AggregatesPanel.d.ts +9 -0
  11. package/dist/types/client/traces/Minimap.d.ts +14 -0
  12. package/dist/types/client/traces/SpanDrawer.d.ts +14 -0
  13. package/dist/types/client/traces/SummaryStrip.d.ts +9 -0
  14. package/dist/types/client/traces/TimelineCanvas.d.ts +25 -0
  15. package/dist/types/client/traces/TraceView.d.ts +11 -0
  16. package/dist/types/client/traces/TranscriptList.d.ts +24 -0
  17. package/dist/types/client/traces/time-scale.d.ts +40 -0
  18. package/dist/types/client/traces/trace-colors.d.ts +31 -0
  19. package/dist/types/db.d.ts +24 -1
  20. package/dist/types/index.d.ts +1 -1
  21. package/dist/types/parser.d.ts +8 -0
  22. package/dist/types/server.d.ts +3 -2
  23. package/dist/types/shared-types.d.ts +130 -0
  24. package/dist/types/trace.d.ts +33 -0
  25. package/dist/types/types.d.ts +35 -1
  26. package/package.json +4 -4
  27. package/src/client/App.tsx +11 -1
  28. package/src/client/api.ts +23 -0
  29. package/src/client/app/routes.ts +7 -0
  30. package/src/client/data/useHashRoute.ts +28 -10
  31. package/src/client/routes/ProvidersRoute.tsx +1 -0
  32. package/src/client/routes/TracesRoute.tsx +182 -0
  33. package/src/client/routes/index.ts +1 -0
  34. package/src/client/styles.css +433 -111
  35. package/src/client/traces/AggregatesPanel.tsx +88 -0
  36. package/src/client/traces/Minimap.tsx +177 -0
  37. package/src/client/traces/SpanDrawer.tsx +309 -0
  38. package/src/client/traces/SummaryStrip.tsx +37 -0
  39. package/src/client/traces/TimelineCanvas.tsx +768 -0
  40. package/src/client/traces/TraceView.tsx +344 -0
  41. package/src/client/traces/TranscriptList.tsx +166 -0
  42. package/src/client/traces/time-scale.ts +250 -0
  43. package/src/client/traces/trace-colors.ts +77 -0
  44. package/src/db.ts +77 -0
  45. package/src/index.ts +1 -6
  46. package/src/parser.ts +55 -2
  47. package/src/server.ts +69 -17
  48. package/src/shared-types.ts +138 -0
  49. package/src/trace.ts +1002 -0
  50. package/src/types.ts +45 -1
@@ -481,36 +481,31 @@
481
481
  }
482
482
  :root {
483
483
  color-scheme: dark;
484
- --bg: #1a1a1a;
485
- --bg-panel: #242424;
486
- --bg-hover: #2e2e2e;
487
- --bg-selected: #383838;
488
- --bg-subtle: rgba(255,255,255,0.04);
489
- --border: #3a3a3a;
490
- --border-strong: rgba(255,255,255,0.13);
491
- --text: #e8e8e8;
492
- --text-muted: #9ca3af;
493
- --text-dim: #6b7280;
494
- --accent: #60a5fa;
495
- --accent-hover: #93c5fd;
496
- --accent-fg: #0f172a;
497
- --accent-muted: rgba(96,165,250,0.18);
498
- --link: #60a5fa;
499
- --success: #22c55e;
500
- --danger: #ef4444;
501
- --warning: #f59e0b;
502
- --page: var(--bg);
503
- --surface: var(--bg-panel);
504
- --surface-2: var(--bg-hover);
505
- --muted: var(--text-muted);
506
- --dim: var(--text-dim);
484
+ --page: oklch(0.16 0.02 307);
485
+ --surface: oklch(0.19 0.022 307);
486
+ --surface-2: oklch(0.235 0.026 307);
487
+ --border: oklch(1 0 0 / 9%);
488
+ --border-strong: oklch(1 0 0 / 13%);
489
+ --text: oklch(0.92 0.01 307);
490
+ --muted: oklch(0.71 0.016 307);
491
+ --dim: oklch(0.53 0.018 307);
492
+ --accent: oklch(0.674 0.23 341);
493
+ --accent-fg: oklch(0.2 0.07 341);
494
+ --accent-muted: oklch(0.674 0.23 341 / 18%);
495
+ --link: oklch(0.817 0.112 205);
496
+ --success: oklch(0.76 0.14 150);
497
+ --danger: oklch(0.66 0.19 25);
498
+ --warning: oklch(0.79 0.14 85);
507
499
  --text-primary: var(--text);
508
- --text-secondary: var(--text-muted);
500
+ --text-secondary: var(--muted);
501
+ --text-muted: var(--dim);
509
502
  --border-subtle: var(--border);
510
503
  --accent-red: var(--danger);
511
504
  --accent-green: var(--success);
512
505
  --accent-cyan: var(--link);
513
- --bg-elevated: var(--bg-hover);
506
+ --bg-hover: var(--surface-2);
507
+ --bg-elevated: var(--surface-2);
508
+ --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
514
509
  --radius-sm: 3px;
515
510
  --radius-md: 6px;
516
511
  --radius-lg: 8px;
@@ -518,82 +513,42 @@
518
513
  @media (prefers-color-scheme: light) {
519
514
  :root:not([data-theme]) {
520
515
  color-scheme: light;
521
- --bg: #ffffff;
522
- --bg-panel: #f5f5f5;
523
- --bg-hover: #eeeeee;
524
- --bg-selected: #e8e8e8;
525
- --bg-subtle: rgba(0,0,0,0.03);
526
- --border: #e0e0e0;
527
- --border-strong: rgba(0,0,0,0.15);
528
- --text: #1a1a1a;
529
- --text-muted: #6b7280;
530
- --text-dim: #9ca3af;
531
- --accent: #2563eb;
532
- --accent-hover: #1d4ed8;
533
- --accent-fg: #ffffff;
534
- --accent-muted: rgba(37,99,235,0.14);
535
- --link: #2563eb;
536
- --success: #16a34a;
537
- --danger: #dc2626;
538
- --warning: #d97706;
539
- --page: var(--bg);
540
- --surface: var(--bg-panel);
541
- --surface-2: var(--bg-hover);
542
- --muted: var(--text-muted);
543
- --dim: var(--text-dim);
516
+ --page: oklch(0.985 0.004 307);
517
+ --surface: oklch(1 0 0);
518
+ --surface-2: oklch(0.965 0.006 307);
519
+ --border: oklch(0 0 0 / 10%);
520
+ --border-strong: oklch(0 0 0 / 15%);
521
+ --text: oklch(0.26 0.03 307);
522
+ --muted: oklch(0.46 0.03 307);
523
+ --dim: oklch(0.58 0.025 307);
524
+ --accent: oklch(0.62 0.23 341);
525
+ --accent-fg: oklch(0.99 0.01 341);
526
+ --accent-muted: oklch(0.62 0.23 341 / 14%);
527
+ --link: oklch(0.58 0.13 230);
528
+ --success: oklch(0.55 0.13 150);
529
+ --danger: oklch(0.55 0.19 25);
530
+ --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23555' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
531
+ --warning: oklch(0.6 0.13 85);
544
532
  }
545
533
  }
546
534
  [data-theme="light"] {
547
535
  color-scheme: light;
548
- --bg: #ffffff;
549
- --bg-panel: #f5f5f5;
550
- --bg-hover: #eeeeee;
551
- --bg-selected: #e8e8e8;
552
- --bg-subtle: rgba(0,0,0,0.03);
553
- --border: #e0e0e0;
554
- --border-strong: rgba(0,0,0,0.15);
555
- --text: #1a1a1a;
556
- --text-muted: #6b7280;
557
- --text-dim: #9ca3af;
558
- --accent: #2563eb;
559
- --accent-hover: #1d4ed8;
560
- --accent-fg: #ffffff;
561
- --accent-muted: rgba(37,99,235,0.14);
562
- --link: #2563eb;
563
- --success: #16a34a;
564
- --danger: #dc2626;
565
- --warning: #d97706;
566
- --page: var(--bg);
567
- --surface: var(--bg-panel);
568
- --surface-2: var(--bg-hover);
569
- --muted: var(--text-muted);
570
- --dim: var(--text-dim);
571
- }
572
- [data-theme="starfield"] {
573
- color-scheme: dark;
574
- --bg: #08090d;
575
- --bg-panel: #0d1117;
576
- --bg-hover: #161d2e;
577
- --bg-selected: #1a2540;
578
- --bg-subtle: rgba(217,155,38,0.05);
579
- --border: #1e2d45;
580
- --border-strong: rgba(217,155,38,0.2);
581
- --text: #e8eeff;
582
- --text-muted: #8fa3c0;
583
- --text-dim: #3d5070;
584
- --accent: #d99b26;
585
- --accent-hover: #f0b840;
586
- --accent-fg: #0f172a;
587
- --accent-muted: rgba(217,155,38,0.18);
588
- --link: #d99b26;
589
- --success: #22c55e;
590
- --danger: #c81d25;
591
- --warning: #e05a2b;
592
- --page: var(--bg);
593
- --surface: var(--bg-panel);
594
- --surface-2: var(--bg-hover);
595
- --muted: var(--text-muted);
596
- --dim: var(--text-dim);
536
+ --page: oklch(0.985 0.004 307);
537
+ --surface: oklch(1 0 0);
538
+ --surface-2: oklch(0.965 0.006 307);
539
+ --border: oklch(0 0 0 / 10%);
540
+ --border-strong: oklch(0 0 0 / 15%);
541
+ --text: oklch(0.26 0.03 307);
542
+ --muted: oklch(0.46 0.03 307);
543
+ --dim: oklch(0.58 0.025 307);
544
+ --accent: oklch(0.62 0.23 341);
545
+ --accent-fg: oklch(0.99 0.01 341);
546
+ --accent-muted: oklch(0.62 0.23 341 / 14%);
547
+ --link: oklch(0.58 0.13 230);
548
+ --success: oklch(0.55 0.13 150);
549
+ --danger: oklch(0.55 0.19 25);
550
+ --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23555' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
551
+ --warning: oklch(0.6 0.13 85);
597
552
  }
598
553
  @layer base {
599
554
  * {
@@ -910,6 +865,50 @@
910
865
  background: var(--surface);
911
866
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
912
867
  }
868
+ .stats-select {
869
+ appearance: none;
870
+ padding: 6px 28px 6px 12px;
871
+ font-size: 13px;
872
+ font-weight: 500;
873
+ font-family: inherit;
874
+ color: var(--text);
875
+ background-color: var(--surface-2);
876
+ background-image: var(--select-chevron);
877
+ background-repeat: no-repeat;
878
+ background-position: right 10px center;
879
+ border: 1px solid var(--border);
880
+ border-radius: var(--radius-md);
881
+ cursor: pointer;
882
+ transition: border-color 0.15s ease, background-color 0.15s ease;
883
+ max-width: 100%;
884
+ text-overflow: ellipsis;
885
+ }
886
+ .stats-select:hover:not(:disabled) {
887
+ border-color: var(--border-strong);
888
+ background-color: var(--bg-hover);
889
+ }
890
+ .stats-select:focus-visible {
891
+ outline: 2px solid var(--link);
892
+ outline-offset: 1px;
893
+ }
894
+ .stats-select:disabled {
895
+ opacity: 0.5;
896
+ cursor: not-allowed;
897
+ }
898
+ @media (pointer: coarse) {
899
+ .stats-select {
900
+ font-size: 16px;
901
+ }
902
+ }
903
+ .stats-select option {
904
+ background-color: var(--surface);
905
+ color: var(--text);
906
+ }
907
+ @media (forced-colors: active) {
908
+ .stats-select {
909
+ appearance: auto;
910
+ }
911
+ }
913
912
  .stats-sync-container {
914
913
  display: flex;
915
914
  align-items: center;
@@ -1571,7 +1570,7 @@
1571
1570
  width: 16px;
1572
1571
  height: 16px;
1573
1572
  border-radius: 4px;
1574
- background: linear-gradient(135deg, #1d4ed8 0%, #2563eb 50%, #60a5fa 100%);
1573
+ background: linear-gradient(135deg, #ed4abf 0%, #9b4dff 50%, #5ad8e6 100%);
1575
1574
  }
1576
1575
  .stats-logo-text, .stats-logo-subtext {
1577
1576
  grid-column: 2;
@@ -1632,6 +1631,271 @@
1632
1631
  transition: none;
1633
1632
  }
1634
1633
  }
1634
+ .stats-trace-view {
1635
+ display: flex;
1636
+ flex-direction: column;
1637
+ gap: 14px;
1638
+ }
1639
+ .stats-trace-header {
1640
+ display: flex;
1641
+ align-items: center;
1642
+ gap: 12px;
1643
+ flex-wrap: wrap;
1644
+ min-width: 0;
1645
+ }
1646
+ .stats-trace-back {
1647
+ display: inline-flex;
1648
+ align-items: center;
1649
+ gap: 6px;
1650
+ padding: 6px 12px;
1651
+ font-size: 12px;
1652
+ color: var(--muted);
1653
+ background: var(--surface);
1654
+ border: 1px solid var(--border);
1655
+ border-radius: var(--radius-md);
1656
+ cursor: pointer;
1657
+ transition: color 0.14s ease, border-color 0.14s ease;
1658
+ }
1659
+ .stats-trace-back:hover {
1660
+ color: var(--text);
1661
+ border-color: var(--border-strong);
1662
+ }
1663
+ .stats-trace-back:focus-visible {
1664
+ outline: 2px solid var(--link);
1665
+ outline-offset: 2px;
1666
+ }
1667
+ .stats-trace-title {
1668
+ font-size: 15px;
1669
+ font-weight: 600;
1670
+ color: var(--text);
1671
+ margin: 0;
1672
+ min-width: 0;
1673
+ overflow: hidden;
1674
+ text-overflow: ellipsis;
1675
+ white-space: nowrap;
1676
+ }
1677
+ .stats-trace-cwd {
1678
+ font-size: 11px;
1679
+ color: var(--dim);
1680
+ border: 1px solid var(--border);
1681
+ border-radius: 999px;
1682
+ padding: 3px 10px;
1683
+ max-width: 280px;
1684
+ overflow: hidden;
1685
+ text-overflow: ellipsis;
1686
+ white-space: nowrap;
1687
+ }
1688
+ .stats-trace-summary {
1689
+ display: flex;
1690
+ flex-wrap: wrap;
1691
+ background: var(--surface);
1692
+ border: 1px solid var(--border);
1693
+ border-radius: var(--radius-lg);
1694
+ overflow: hidden;
1695
+ }
1696
+ .stats-trace-summary-cell {
1697
+ display: flex;
1698
+ flex-direction: column;
1699
+ gap: 3px;
1700
+ padding: 10px 16px;
1701
+ border-right: 1px solid var(--border);
1702
+ min-width: 76px;
1703
+ }
1704
+ .stats-trace-summary-cell:last-child {
1705
+ border-right: none;
1706
+ }
1707
+ .stats-trace-summary-label {
1708
+ font-size: 9px;
1709
+ text-transform: uppercase;
1710
+ letter-spacing: 0.07em;
1711
+ color: var(--dim);
1712
+ }
1713
+ .stats-trace-summary-value {
1714
+ font-size: 13px;
1715
+ font-weight: 500;
1716
+ color: var(--text);
1717
+ font-variant-numeric: tabular-nums;
1718
+ }
1719
+ .stats-trace-toolbar {
1720
+ display: flex;
1721
+ align-items: center;
1722
+ gap: 12px;
1723
+ flex-wrap: wrap;
1724
+ }
1725
+ .stats-trace-toolbar-hint {
1726
+ font-size: 10px;
1727
+ color: var(--dim);
1728
+ margin-left: auto;
1729
+ }
1730
+ .stats-trace-input {
1731
+ background: var(--surface);
1732
+ border: 1px solid var(--border);
1733
+ border-radius: var(--radius-md);
1734
+ color: var(--text);
1735
+ font-size: 12px;
1736
+ padding: 6px 10px;
1737
+ }
1738
+ .stats-trace-input:focus-visible {
1739
+ outline: 2px solid var(--link);
1740
+ outline-offset: 1px;
1741
+ }
1742
+ .stats-trace-input::placeholder {
1743
+ color: var(--dim);
1744
+ }
1745
+ .stats-trace-check {
1746
+ display: inline-flex;
1747
+ align-items: center;
1748
+ gap: 6px;
1749
+ font-size: 12px;
1750
+ color: var(--muted);
1751
+ cursor: pointer;
1752
+ user-select: none;
1753
+ }
1754
+ .stats-trace-icon-btn {
1755
+ display: inline-flex;
1756
+ align-items: center;
1757
+ justify-content: center;
1758
+ width: 26px;
1759
+ height: 26px;
1760
+ background: transparent;
1761
+ border: 1px solid var(--border);
1762
+ border-radius: var(--radius-md);
1763
+ color: var(--muted);
1764
+ cursor: pointer;
1765
+ transition: color 0.14s ease, border-color 0.14s ease;
1766
+ }
1767
+ .stats-trace-icon-btn:hover:not(:disabled) {
1768
+ color: var(--text);
1769
+ border-color: var(--border-strong);
1770
+ }
1771
+ .stats-trace-icon-btn:focus-visible {
1772
+ outline: 2px solid var(--link);
1773
+ outline-offset: 2px;
1774
+ }
1775
+ .stats-trace-icon-btn:disabled {
1776
+ opacity: 0.4;
1777
+ cursor: default;
1778
+ }
1779
+ .stats-trace-timeline-card {
1780
+ background: var(--surface);
1781
+ border: 1px solid var(--border);
1782
+ border-radius: var(--radius-lg);
1783
+ padding: 12px;
1784
+ display: flex;
1785
+ flex-direction: column;
1786
+ gap: 10px;
1787
+ }
1788
+ .stats-trace-timeline {
1789
+ position: relative;
1790
+ display: flex;
1791
+ max-height: 560px;
1792
+ overflow-y: auto;
1793
+ overflow-x: hidden;
1794
+ }
1795
+ .stats-trace-canvas {
1796
+ cursor: grab;
1797
+ outline: none;
1798
+ touch-action: none;
1799
+ border-radius: var(--radius-sm);
1800
+ }
1801
+ .stats-trace-canvas:focus-visible {
1802
+ outline: 2px solid var(--link);
1803
+ outline-offset: 2px;
1804
+ }
1805
+ .stats-trace-canvas:active {
1806
+ cursor: grabbing;
1807
+ }
1808
+ .stats-trace-chevron {
1809
+ display: inline-flex;
1810
+ background: none;
1811
+ border: none;
1812
+ padding: 0;
1813
+ cursor: pointer;
1814
+ color: var(--muted);
1815
+ }
1816
+ .stats-trace-chevron:hover {
1817
+ color: var(--text);
1818
+ }
1819
+ .stats-trace-gutter-track {
1820
+ font-size: 11px;
1821
+ font-weight: 500;
1822
+ color: var(--text);
1823
+ }
1824
+ .stats-trace-gutter-model {
1825
+ font-size: 9px;
1826
+ color: var(--dim);
1827
+ }
1828
+ .stats-trace-gutter-lane {
1829
+ position: absolute;
1830
+ font-size: 8px;
1831
+ color: var(--dim);
1832
+ text-transform: uppercase;
1833
+ letter-spacing: 0.08em;
1834
+ }
1835
+ .stats-trace-list {
1836
+ background: var(--surface);
1837
+ border: 1px solid var(--border);
1838
+ border-radius: var(--radius-lg);
1839
+ height: 340px;
1840
+ overflow-y: auto;
1841
+ }
1842
+ .stats-trace-row {
1843
+ display: flex;
1844
+ align-items: center;
1845
+ gap: 10px;
1846
+ height: 28px;
1847
+ width: 100%;
1848
+ padding: 0 12px;
1849
+ background: transparent;
1850
+ border: none;
1851
+ border-bottom: 1px solid var(--border);
1852
+ text-align: left;
1853
+ cursor: pointer;
1854
+ transition: background 0.1s ease;
1855
+ }
1856
+ .stats-trace-row:hover {
1857
+ background: var(--bg-hover);
1858
+ }
1859
+ .stats-trace-row:focus-visible {
1860
+ outline: 2px solid var(--link);
1861
+ outline-offset: -2px;
1862
+ }
1863
+ .stats-trace-row[data-selected="true"] {
1864
+ background: var(--accent-muted);
1865
+ }
1866
+ .stats-trace-row-static {
1867
+ cursor: default;
1868
+ }
1869
+ .stats-trace-row-static:hover {
1870
+ background: transparent;
1871
+ }
1872
+ .stats-trace-kind {
1873
+ flex-shrink: 0;
1874
+ width: 58px;
1875
+ font-size: 8px;
1876
+ text-transform: uppercase;
1877
+ letter-spacing: 0.06em;
1878
+ border-radius: 3px;
1879
+ padding: 2px 0;
1880
+ text-align: center;
1881
+ overflow: hidden;
1882
+ text-overflow: ellipsis;
1883
+ white-space: nowrap;
1884
+ }
1885
+ .stats-trace-row-meta {
1886
+ flex-shrink: 0;
1887
+ margin-left: auto;
1888
+ font-size: 10px;
1889
+ color: var(--dim);
1890
+ font-variant-numeric: tabular-nums;
1891
+ display: flex;
1892
+ gap: 10px;
1893
+ }
1894
+ @media (prefers-reduced-motion: reduce) {
1895
+ .stats-trace-back, .stats-trace-icon-btn, .stats-trace-row {
1896
+ transition: none;
1897
+ }
1898
+ }
1635
1899
  @property --tw-space-y-reverse {
1636
1900
  syntax: "*";
1637
1901
  inherits: false;
@@ -1,4 +1,4 @@
1
- import type { BehaviorDashboardStats, CostDashboardStats, FolderStats, GainDashboardStats, MessageStats, ModelDashboardStats, OverviewStats, ProviderDashboardStats, RequestDetails, TimeRange, ToolDashboardStats } from "./types.js";
1
+ import type { BehaviorDashboardStats, CostDashboardStats, FolderStats, GainDashboardStats, MessageStats, ModelDashboardStats, OverviewStats, ProviderDashboardStats, RequestDetails, SessionSummary, SessionTrace, TimeRange, ToolDashboardStats } from "./types.js";
2
2
  export declare class ApiError extends Error {
3
3
  status: number;
4
4
  endpoint: string;
@@ -20,3 +20,9 @@ export declare function getFolderStats(range?: TimeRange, signal?: AbortSignal):
20
20
  export declare function getGainDashboardStats(range?: TimeRange, project?: string | null, signal?: AbortSignal): Promise<GainDashboardStats>;
21
21
  export declare function getToolDashboardStats(range?: TimeRange, signal?: AbortSignal): Promise<ToolDashboardStats>;
22
22
  export declare function getProviderDashboardStats(range?: TimeRange, signal?: AbortSignal): Promise<ProviderDashboardStats>;
23
+ export declare function getSessions(limit?: number, q?: string, signal?: AbortSignal): Promise<SessionSummary[]>;
24
+ export declare function getSessionTrace(file: string, signal?: AbortSignal): Promise<SessionTrace>;
25
+ /** Fetch one full journal entry for the span drawer. Entries are opaque JSON. */
26
+ export declare function getSessionEntryDetail(file: string, id: string, signal?: AbortSignal): Promise<{
27
+ entry: unknown;
28
+ }>;
@@ -1,5 +1,5 @@
1
1
  import type React from "react";
2
- export type DashboardSection = "overview" | "requests" | "errors" | "models" | "providers" | "tools" | "costs" | "behavior" | "projects" | "gain";
2
+ export type DashboardSection = "overview" | "requests" | "traces" | "errors" | "models" | "providers" | "tools" | "costs" | "behavior" | "projects" | "gain";
3
3
  export interface DashboardRoute {
4
4
  id: DashboardSection;
5
5
  label: string;
@@ -5,4 +5,6 @@ export declare function useHashRoute(): {
5
5
  setSection: (newSection: DashboardSection) => void;
6
6
  range: TimeRange;
7
7
  setRange: (newRange: string) => void;
8
+ session: string | null;
9
+ setSession: (file: string | null) => void;
8
10
  };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Traces section: root-session list (subagents folded in) that opens the
3
+ * flamegraph trace viewer for a selected session.
4
+ */
5
+ export interface TracesRouteProps {
6
+ active: boolean;
7
+ session: string | null;
8
+ onOpenSession: (file: string | null) => void;
9
+ refreshTrigger: number;
10
+ }
11
+ export declare function TracesRoute({ active, session, onOpenSession, refreshTrigger }: TracesRouteProps): import("react").JSX.Element;
@@ -8,3 +8,4 @@ export * from "./ProjectsRoute.js";
8
8
  export * from "./ProvidersRoute.js";
9
9
  export * from "./RequestsRoute.js";
10
10
  export * from "./ToolsRoute.js";
11
+ export * from "./TracesRoute.js";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Collapsible per-tool duration aggregates for one trace, sorted by total
3
+ * time descending (as produced by the server).
4
+ */
5
+ import type { TraceToolStat } from "../types.js";
6
+ export interface AggregatesPanelProps {
7
+ toolStats: TraceToolStat[];
8
+ }
9
+ export declare function AggregatesPanel({ toolStats }: AggregatesPanelProps): import("react").JSX.Element | null;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Timeline overview strip: per-category density over the full virtual domain
3
+ * plus a draggable/resizable viewport brush, mirroring DevTools' overview.
4
+ */
5
+ import type { TraceTrack } from "../types.js";
6
+ import type { TimelineViewport } from "./TimelineCanvas.js";
7
+ import type { TraceScale } from "./time-scale.js";
8
+ export interface MinimapProps {
9
+ tracks: TraceTrack[];
10
+ scale: TraceScale;
11
+ viewport: TimelineViewport;
12
+ onViewportChange: (viewport: TimelineViewport) => void;
13
+ }
14
+ export declare function Minimap({ tracks, scale, viewport, onViewportChange }: MinimapProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Detail drawer for a selected trace span. Fetches the full journal entry on
3
+ * demand (`/api/session/entry`) and renders per-kind detail: model usage grid
4
+ * + text blocks, tool args/result, user text, subagent task text.
5
+ */
6
+ import type { TraceSpan, TraceTrack } from "../types.js";
7
+ export interface SpanDrawerProps {
8
+ span: TraceSpan | null;
9
+ track: TraceTrack | null;
10
+ onClose: () => void;
11
+ /** Selects the first span of the given child track ("open child track"). */
12
+ onOpenChildTrack?: (childTrackId: string) => void;
13
+ }
14
+ export declare function SpanDrawer({ span, track, onClose, onOpenChildTrack }: SpanDrawerProps): import("react").JSX.Element | null;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Headline chips for one trace: wall/model/tool/idle time, turns, requests,
3
+ * tool calls, agents, tokens, cost.
4
+ */
5
+ import type { TraceSummary } from "../types.js";
6
+ export interface SummaryStripProps {
7
+ summary: TraceSummary;
8
+ }
9
+ export declare function SummaryStrip({ summary }: SummaryStripProps): import("react").JSX.Element;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The trace flamegraph: one DPR-scaled canvas with a DOM gutter (track/lane
3
+ * labels, collapse chevrons) and a DOM tooltip. Implements the Chrome
4
+ * DevTools interaction contract: cursor-anchored wheel zoom, drag pan, WASD,
5
+ * fit/focus keys, hover tooltips, click-to-select, double-click-to-zoom.
6
+ */
7
+ import type { TraceTrack } from "../types.js";
8
+ import { type TraceScale } from "./time-scale.js";
9
+ export interface TimelineViewport {
10
+ u0: number;
11
+ u1: number;
12
+ }
13
+ export interface TimelineCanvasProps {
14
+ tracks: TraceTrack[];
15
+ scale: TraceScale;
16
+ viewport: TimelineViewport;
17
+ onViewportChange: (viewport: TimelineViewport) => void;
18
+ selection: string | null;
19
+ onSelect: (spanId: string | null) => void;
20
+ search: string;
21
+ collapsed: ReadonlySet<string>;
22
+ onToggleCollapse: (trackId: string) => void;
23
+ traceStart: number;
24
+ }
25
+ export declare function TimelineCanvas({ tracks, scale, viewport, onViewportChange, selection, onSelect, search, collapsed, onToggleCollapse, traceStart, }: TimelineCanvasProps): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Single-session trace viewer: summary strip, axis-mode toolbar, minimap,
3
+ * flamegraph canvas, transcript list, tool aggregates, and the span drawer.
4
+ * Owns the shared viewport/selection state so all pieces stay in sync.
5
+ */
6
+ export interface TraceViewProps {
7
+ file: string;
8
+ active: boolean;
9
+ onBack: () => void;
10
+ }
11
+ export declare function TraceView({ file, active, onBack }: TraceViewProps): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Windowed transcript list under the timeline: all spans + markers flattened
3
+ * chronologically across tracks, bidirectionally synced with the canvas
4
+ * selection. Hand-rolled fixed-row virtualization (32px rows, spacer divs).
5
+ */
6
+ import type { TraceMarker, TraceSpan, TraceTrack } from "../types.js";
7
+ export interface TranscriptRow {
8
+ key: string;
9
+ time: number;
10
+ span?: TraceSpan;
11
+ marker?: TraceMarker;
12
+ track: TraceTrack;
13
+ depth: number;
14
+ }
15
+ export interface TranscriptListProps {
16
+ tracks: TraceTrack[];
17
+ selection: string | null;
18
+ onSelect: (spanId: string) => void;
19
+ search: string;
20
+ traceStart: number;
21
+ }
22
+ /** Flatten all spans and markers across tracks into chronological rows. */
23
+ export declare function buildTranscriptRows(tracks: TraceTrack[]): TranscriptRow[];
24
+ export declare function TranscriptList({ tracks, selection, onSelect, search, traceStart }: TranscriptListProps): import("react").JSX.Element;