@oh-my-pi/omp-stats 18.15.0 → 18.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/client/index.css +1 -1
  3. package/dist/client/index.js +102 -99
  4. package/dist/types/client/api.d.ts +4 -1
  5. package/dist/types/client/app/nav.d.ts +1 -1
  6. package/dist/types/client/charts/Chart.d.ts +16 -8
  7. package/dist/types/client/charts/DotWhisker.d.ts +50 -0
  8. package/dist/types/client/charts/Sparkline.d.ts +1 -1
  9. package/dist/types/client/charts/Waterfall.d.ts +26 -0
  10. package/dist/types/client/charts/index.d.ts +2 -0
  11. package/dist/types/client/charts/types.d.ts +8 -2
  12. package/dist/types/client/routes/SpotlightRoute.d.ts +7 -0
  13. package/dist/types/client/routes/index.d.ts +1 -0
  14. package/dist/types/client/spotlight/Compounding.d.ts +8 -0
  15. package/dist/types/client/spotlight/Coverage.d.ts +6 -0
  16. package/dist/types/client/spotlight/Economics.d.ts +10 -0
  17. package/dist/types/client/spotlight/FetchBack.d.ts +9 -0
  18. package/dist/types/client/spotlight/Hero.d.ts +12 -0
  19. package/dist/types/client/spotlight/Overhead.d.ts +6 -0
  20. package/dist/types/client/spotlight/Ranking.d.ts +6 -0
  21. package/dist/types/client/spotlight/ResultsFeed.d.ts +6 -0
  22. package/dist/types/client/spotlight/Savings.d.ts +10 -0
  23. package/dist/types/client/spotlight/ShareTrend.d.ts +8 -0
  24. package/dist/types/client/spotlight/Steps.d.ts +6 -0
  25. package/dist/types/client/spotlight/TimeCost.d.ts +6 -0
  26. package/dist/types/client/spotlight/chips.d.ts +16 -0
  27. package/dist/types/client/spotlight/meta.d.ts +64 -0
  28. package/dist/types/db.d.ts +26 -0
  29. package/dist/types/index.d.ts +2 -1
  30. package/dist/types/parser.d.ts +4 -0
  31. package/dist/types/rollup.d.ts +22 -1
  32. package/dist/types/shared-types.d.ts +419 -0
  33. package/dist/types/spotlight-aggregator.d.ts +189 -0
  34. package/dist/types/spotlight-bootstrap.d.ts +32 -0
  35. package/dist/types/spotlight-ingest.d.ts +258 -0
  36. package/dist/types/spotlight-measures.d.ts +51 -0
  37. package/package.json +5 -5
  38. package/src/aggregator.ts +3 -1
  39. package/src/client/App.tsx +3 -0
  40. package/src/client/api.ts +21 -0
  41. package/src/client/app/nav.ts +4 -1
  42. package/src/client/charts/Chart.tsx +105 -22
  43. package/src/client/charts/DotWhisker.tsx +149 -0
  44. package/src/client/charts/Sparkline.tsx +3 -2
  45. package/src/client/charts/Waterfall.tsx +86 -0
  46. package/src/client/charts/index.ts +2 -0
  47. package/src/client/charts/types.ts +9 -2
  48. package/src/client/data/query.ts +12 -4
  49. package/src/client/react-css.d.ts +1 -1
  50. package/src/client/routes/SpotlightRoute.tsx +138 -0
  51. package/src/client/routes/index.ts +1 -0
  52. package/src/client/spotlight/Compounding.tsx +222 -0
  53. package/src/client/spotlight/Coverage.tsx +96 -0
  54. package/src/client/spotlight/Economics.tsx +167 -0
  55. package/src/client/spotlight/FetchBack.tsx +222 -0
  56. package/src/client/spotlight/Hero.tsx +177 -0
  57. package/src/client/spotlight/Overhead.tsx +135 -0
  58. package/src/client/spotlight/Ranking.tsx +248 -0
  59. package/src/client/spotlight/ResultsFeed.tsx +354 -0
  60. package/src/client/spotlight/Savings.tsx +355 -0
  61. package/src/client/spotlight/ShareTrend.tsx +103 -0
  62. package/src/client/spotlight/Steps.tsx +225 -0
  63. package/src/client/spotlight/TimeCost.tsx +64 -0
  64. package/src/client/spotlight/chips.tsx +63 -0
  65. package/src/client/spotlight/meta.ts +206 -0
  66. package/src/client/spotlight/spotlight.css +1387 -0
  67. package/src/client/styles.css +289 -1
  68. package/src/client/traces/SpanDrawer.tsx +2 -1
  69. package/src/db.ts +480 -2
  70. package/src/index.ts +10 -1
  71. package/src/live.ts +21 -9
  72. package/src/parser.ts +44 -8
  73. package/src/rollup.ts +203 -10
  74. package/src/server.ts +42 -0
  75. package/src/shared-types.ts +453 -0
  76. package/src/spotlight-aggregator.ts +1738 -0
  77. package/src/spotlight-bootstrap.ts +110 -0
  78. package/src/spotlight-ingest.ts +981 -0
  79. package/src/spotlight-measures.ts +667 -0
@@ -110,7 +110,8 @@
110
110
  }
111
111
 
112
112
  :root {
113
- --font-sans: "Inter var", "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
113
+ --font-sans:
114
+ "Inter var", "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
114
115
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace;
115
116
 
116
117
  --r-chip: 6px;
@@ -278,6 +279,19 @@ kbd {
278
279
  min-width: 0;
279
280
  }
280
281
 
282
+ /* Text for screen readers only (e.g. the word behind an icon + count pill). */
283
+ .sr-only {
284
+ position: absolute;
285
+ width: 1px;
286
+ height: 1px;
287
+ margin: -1px;
288
+ padding: 0;
289
+ overflow: hidden;
290
+ clip-path: inset(50%);
291
+ white-space: nowrap;
292
+ border: 0;
293
+ }
294
+
281
295
  .tone-ok {
282
296
  color: var(--ok);
283
297
  }
@@ -1666,6 +1680,23 @@ select.input {
1666
1680
  vector-effect: non-scaling-stroke;
1667
1681
  }
1668
1682
 
1683
+ .chart-dots circle {
1684
+ fill-opacity: 0.55;
1685
+ transition: r var(--dur-1) var(--ease);
1686
+ }
1687
+
1688
+ .chart-marker line {
1689
+ stroke: var(--line-4);
1690
+ stroke-dasharray: 2 3;
1691
+ shape-rendering: crispEdges;
1692
+ }
1693
+
1694
+ .chart-marker text {
1695
+ fill: var(--ink-3);
1696
+ font-family: var(--font-mono);
1697
+ font-size: 10.5px;
1698
+ }
1699
+
1669
1700
  .chart-empty {
1670
1701
  position: absolute;
1671
1702
  inset: 0;
@@ -1782,6 +1813,263 @@ button.legend-item:hover {
1782
1813
  transition: flex-grow var(--dur-3) var(--ease-out);
1783
1814
  }
1784
1815
 
1816
+ /* Horizontal waterfall (bridge) chart. */
1817
+ .waterfall {
1818
+ display: flex;
1819
+ flex-direction: column;
1820
+ }
1821
+
1822
+ .waterfall-row {
1823
+ display: grid;
1824
+ grid-template-columns: minmax(92px, 9.5rem) minmax(0, 1fr) minmax(84px, auto);
1825
+ align-items: center;
1826
+ gap: 14px;
1827
+ height: 38px;
1828
+ }
1829
+
1830
+ .waterfall-label {
1831
+ display: flex;
1832
+ align-items: center;
1833
+ gap: 8px;
1834
+ min-width: 0;
1835
+ overflow: hidden;
1836
+ white-space: nowrap;
1837
+ text-overflow: ellipsis;
1838
+ font-size: 12.5px;
1839
+ color: var(--ink-2);
1840
+ }
1841
+
1842
+ .waterfall-row[data-kind="total"] .waterfall-label {
1843
+ color: var(--ink-1);
1844
+ font-weight: 500;
1845
+ }
1846
+
1847
+ .waterfall-track {
1848
+ position: relative;
1849
+ height: 100%;
1850
+ }
1851
+
1852
+ .waterfall-bar {
1853
+ position: absolute;
1854
+ top: 50%;
1855
+ height: 16px;
1856
+ min-width: 2px;
1857
+ transform: translateY(-50%);
1858
+ border-radius: 4px;
1859
+ background: var(--bar);
1860
+ transition:
1861
+ left var(--dur-3) var(--ease-out),
1862
+ width var(--dur-3) var(--ease-out);
1863
+ }
1864
+
1865
+ /* What a step takes away is hatched: the bar shows the part that is gone. */
1866
+ .waterfall-row[data-kind="delta"] .waterfall-bar {
1867
+ height: 12px;
1868
+ border-radius: 3px;
1869
+ background: repeating-linear-gradient(
1870
+ -45deg,
1871
+ var(--bar) 0 2px,
1872
+ color-mix(in srgb, var(--bar) 28%, transparent) 2px 5px
1873
+ );
1874
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bar) 55%, transparent);
1875
+ }
1876
+
1877
+ .waterfall-bar[data-empty="true"] {
1878
+ opacity: 0.35;
1879
+ }
1880
+
1881
+ .waterfall-link {
1882
+ position: absolute;
1883
+ top: -12px;
1884
+ height: 24px;
1885
+ border-left: 1px dashed var(--line-4);
1886
+ }
1887
+
1888
+ .waterfall-zero {
1889
+ position: absolute;
1890
+ top: 4px;
1891
+ bottom: 4px;
1892
+ border-left: 1px solid var(--line-3);
1893
+ }
1894
+
1895
+ .waterfall-value {
1896
+ display: flex;
1897
+ align-items: baseline;
1898
+ justify-content: flex-end;
1899
+ gap: 8px;
1900
+ white-space: nowrap;
1901
+ color: var(--ink-1);
1902
+ }
1903
+
1904
+ .waterfall-note {
1905
+ min-width: 3.4em;
1906
+ text-align: right;
1907
+ font-family: var(--font-mono);
1908
+ font-size: 11px;
1909
+ color: var(--ink-3);
1910
+ font-variant-numeric: tabular-nums;
1911
+ }
1912
+
1913
+ /* Dot-and-whisker rows on one shared axis. */
1914
+ .dw {
1915
+ display: flex;
1916
+ flex-direction: column;
1917
+ }
1918
+
1919
+ .dw-row {
1920
+ display: grid;
1921
+ grid-template-columns: minmax(104px, 8.5rem) minmax(0, 1fr) 96px;
1922
+ align-items: center;
1923
+ gap: 12px;
1924
+ height: 36px;
1925
+ }
1926
+
1927
+ .dw-label {
1928
+ display: flex;
1929
+ align-items: center;
1930
+ gap: 8px;
1931
+ min-width: 0;
1932
+ font-size: 12.5px;
1933
+ color: var(--ink-1);
1934
+ }
1935
+
1936
+ .dw-track {
1937
+ position: relative;
1938
+ height: 100%;
1939
+ }
1940
+
1941
+ .dw-track::before {
1942
+ content: "";
1943
+ position: absolute;
1944
+ left: 0;
1945
+ right: 0;
1946
+ top: 50%;
1947
+ border-top: 1px solid var(--line-1);
1948
+ }
1949
+
1950
+ .dw-guide {
1951
+ position: absolute;
1952
+ top: 0;
1953
+ bottom: 0;
1954
+ border-left: 1px dashed var(--guide);
1955
+ opacity: 0.75;
1956
+ }
1957
+
1958
+ .dw-band {
1959
+ position: absolute;
1960
+ top: 0;
1961
+ bottom: 0;
1962
+ background: color-mix(in srgb, var(--band) 11%, transparent);
1963
+ }
1964
+
1965
+ .dw-mark {
1966
+ position: absolute;
1967
+ inset: 0;
1968
+ pointer-events: none;
1969
+ }
1970
+
1971
+ .dw-whisker {
1972
+ position: absolute;
1973
+ top: calc(50% + var(--dy, 0px));
1974
+ height: 2px;
1975
+ margin-top: -1px;
1976
+ border-radius: 1px;
1977
+ background: var(--dot);
1978
+ opacity: 0.85;
1979
+ }
1980
+
1981
+ .dw-whisker::before,
1982
+ .dw-whisker::after {
1983
+ content: "";
1984
+ position: absolute;
1985
+ top: -4px;
1986
+ width: 1.5px;
1987
+ height: 10px;
1988
+ border-radius: 1px;
1989
+ background: var(--dot);
1990
+ }
1991
+
1992
+ .dw-whisker::before {
1993
+ left: 0;
1994
+ }
1995
+
1996
+ .dw-whisker::after {
1997
+ right: 0;
1998
+ }
1999
+
2000
+ .dw-dot {
2001
+ position: absolute;
2002
+ top: calc(50% + var(--dy, 0px));
2003
+ width: 10px;
2004
+ height: 10px;
2005
+ margin: -5px 0 0 -5px;
2006
+ border-radius: 50%;
2007
+ background: var(--dot);
2008
+ box-shadow: 0 0 0 3px var(--card);
2009
+ pointer-events: auto;
2010
+ transition: left var(--dur-3) var(--ease-out);
2011
+ }
2012
+
2013
+ .dw-mark[data-shape="ring"] .dw-dot {
2014
+ background: var(--card);
2015
+ border: 2px solid var(--dot);
2016
+ }
2017
+
2018
+ .dw-mark[data-shape="diamond"] .dw-dot {
2019
+ width: 8px;
2020
+ height: 8px;
2021
+ margin: -4px 0 0 -4px;
2022
+ border-radius: 1.5px;
2023
+ box-shadow: 0 0 0 2px var(--card);
2024
+ transform: rotate(45deg);
2025
+ }
2026
+
2027
+ .dw-mark[data-shape="square"] .dw-dot {
2028
+ width: 9px;
2029
+ height: 9px;
2030
+ margin: -4.5px 0 0 -4.5px;
2031
+ border-radius: 2px;
2032
+ box-shadow: 0 0 0 2.5px var(--card);
2033
+ }
2034
+
2035
+ .dw-mark[data-shape="diamond"] .dw-whisker {
2036
+ opacity: 0.55;
2037
+ }
2038
+
2039
+ .dw-value {
2040
+ display: flex;
2041
+ flex-direction: column;
2042
+ align-items: flex-end;
2043
+ line-height: 1.25;
2044
+ color: var(--ink-1);
2045
+ min-width: 0;
2046
+ }
2047
+
2048
+ .dw-detail {
2049
+ font-family: var(--font-mono);
2050
+ font-size: 10.5px;
2051
+ color: var(--ink-3);
2052
+ white-space: nowrap;
2053
+ }
2054
+
2055
+ .dw-axis {
2056
+ height: 20px;
2057
+ }
2058
+
2059
+ .dw-axis .dw-track::before {
2060
+ display: none;
2061
+ }
2062
+
2063
+ .dw-tick {
2064
+ position: absolute;
2065
+ top: 3px;
2066
+ transform: translateX(-50%);
2067
+ font-family: var(--font-mono);
2068
+ font-size: 10.5px;
2069
+ color: var(--chart-axis);
2070
+ white-space: nowrap;
2071
+ }
2072
+
1785
2073
  /* Ranked horizontal bar list. */
1786
2074
  .bar-list {
1787
2075
  display: flex;
@@ -4,6 +4,7 @@
4
4
  * + text blocks, tool args/result, user text, subagent task text.
5
5
  */
6
6
 
7
+ import { toError } from "@oh-my-pi/pi-utils/type-guards";
7
8
  import { Check, Copy, X } from "lucide-react";
8
9
  import { type ReactNode, useEffect, useRef, useState } from "react";
9
10
  import { getSessionEntryDetail } from "../api";
@@ -112,7 +113,7 @@ export function SpanDrawer({
112
113
  })
113
114
  .catch(err => {
114
115
  if (controller.signal.aborted) return;
115
- setError(err instanceof Error ? err : new Error(String(err)));
116
+ setError(toError(err));
116
117
  })
117
118
  .finally(() => {
118
119
  if (!controller.signal.aborted) setLoading(false);