@linxiraos/pi-stats 1.1.26 → 1.2.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 (125) hide show
  1. package/CHANGELOG.md +12 -5
  2. package/build.ts +4 -0
  3. package/dist/client/favicon.ico +0 -0
  4. package/dist/client/index.css +1 -1
  5. package/dist/client/index.html +1 -0
  6. package/dist/client/index.js +96 -96
  7. package/dist/types/aggregator.d.ts +4 -1
  8. package/dist/types/client/api.d.ts +5 -1
  9. package/dist/types/client/app/nav.d.ts +5 -2
  10. package/dist/types/client/data/formatters.d.ts +7 -2
  11. package/dist/types/client/data/live.d.ts +16 -11
  12. package/dist/types/client/data/query-store.d.ts +39 -0
  13. package/dist/types/client/data/query.d.ts +10 -5
  14. package/dist/types/client/data/range.d.ts +4 -3
  15. package/dist/types/client/i18n/format.d.ts +9 -0
  16. package/dist/types/client/i18n/index.d.ts +18 -0
  17. package/dist/types/client/i18n/messages/charts.d.ts +8 -0
  18. package/dist/types/client/i18n/messages/common.d.ts +153 -0
  19. package/dist/types/client/i18n/messages/costs.d.ts +92 -0
  20. package/dist/types/client/i18n/messages/en.d.ts +1255 -0
  21. package/dist/types/client/i18n/messages/errors.d.ts +78 -0
  22. package/dist/types/client/i18n/messages/frustration.d.ts +191 -0
  23. package/dist/types/client/i18n/messages/gain.d.ts +54 -0
  24. package/dist/types/client/i18n/messages/models.d.ts +94 -0
  25. package/dist/types/client/i18n/messages/nav.d.ts +46 -0
  26. package/dist/types/client/i18n/messages/overview.d.ts +80 -0
  27. package/dist/types/client/i18n/messages/projects.d.ts +84 -0
  28. package/dist/types/client/i18n/messages/providers.d.ts +142 -0
  29. package/dist/types/client/i18n/messages/requests.d.ts +72 -0
  30. package/dist/types/client/i18n/messages/tools.d.ts +119 -0
  31. package/dist/types/client/i18n/messages/traces.d.ts +144 -0
  32. package/dist/types/client/i18n/messages/ui.d.ts +44 -0
  33. package/dist/types/client/i18n/messages/zh-CN.d.ts +13 -0
  34. package/dist/types/client/i18n/types.d.ts +15 -0
  35. package/dist/types/client/traces/Minimap.d.ts +2 -0
  36. package/dist/types/client/traces/TimelineCanvas.d.ts +29 -8
  37. package/dist/types/client/traces/TranscriptList.d.ts +3 -1
  38. package/dist/types/db.d.ts +14 -21
  39. package/dist/types/embedded-client.d.ts +5 -0
  40. package/dist/types/frustration.d.ts +18 -9
  41. package/dist/types/live.d.ts +5 -3
  42. package/dist/types/locale.d.ts +16 -0
  43. package/dist/types/parser.d.ts +0 -17
  44. package/dist/types/rollup.d.ts +9 -1
  45. package/dist/types/server.d.ts +6 -0
  46. package/dist/types/shared-types.d.ts +7 -0
  47. package/dist/types/trace.d.ts +18 -6
  48. package/dist/types/types.d.ts +13 -1
  49. package/dist/types/user-metrics.d.ts +23 -1
  50. package/package.json +5 -5
  51. package/src/aggregator.ts +31 -11
  52. package/src/client/api.ts +40 -5
  53. package/src/client/app/LiveChip.tsx +14 -13
  54. package/src/client/app/Shell.tsx +19 -13
  55. package/src/client/app/ThemeToggle.tsx +4 -3
  56. package/src/client/app/nav.ts +19 -16
  57. package/src/client/data/formatters.ts +80 -13
  58. package/src/client/data/live.tsx +85 -45
  59. package/src/client/data/query-store.ts +108 -0
  60. package/src/client/data/query.ts +47 -56
  61. package/src/client/data/range.ts +34 -14
  62. package/src/client/data/series.ts +7 -1
  63. package/src/client/favicon.ico +0 -0
  64. package/src/client/i18n/format.ts +28 -0
  65. package/src/client/i18n/index.ts +53 -0
  66. package/src/client/i18n/messages/charts.ts +8 -0
  67. package/src/client/i18n/messages/common.ts +157 -0
  68. package/src/client/i18n/messages/costs.ts +104 -0
  69. package/src/client/i18n/messages/en.ts +40 -0
  70. package/src/client/i18n/messages/errors.ts +80 -0
  71. package/src/client/i18n/messages/frustration.ts +198 -0
  72. package/src/client/i18n/messages/gain.ts +54 -0
  73. package/src/client/i18n/messages/models.ts +94 -0
  74. package/src/client/i18n/messages/nav.ts +46 -0
  75. package/src/client/i18n/messages/overview.ts +90 -0
  76. package/src/client/i18n/messages/projects.ts +84 -0
  77. package/src/client/i18n/messages/providers.ts +165 -0
  78. package/src/client/i18n/messages/requests.ts +73 -0
  79. package/src/client/i18n/messages/tools.ts +120 -0
  80. package/src/client/i18n/messages/traces.ts +160 -0
  81. package/src/client/i18n/messages/ui.ts +46 -0
  82. package/src/client/i18n/messages/zh-CN.ts +43 -0
  83. package/src/client/i18n/types.ts +19 -0
  84. package/src/client/index.tsx +4 -0
  85. package/src/client/routes/CostsRoute.tsx +61 -48
  86. package/src/client/routes/ErrorsRoute.tsx +71 -47
  87. package/src/client/routes/FrustrationRoute.tsx +131 -116
  88. package/src/client/routes/GainRoute.tsx +42 -30
  89. package/src/client/routes/ModelsRoute.tsx +90 -73
  90. package/src/client/routes/OverviewRoute.tsx +109 -63
  91. package/src/client/routes/ProjectsRoute.tsx +73 -46
  92. package/src/client/routes/ProvidersRoute.tsx +151 -114
  93. package/src/client/routes/RequestsRoute.tsx +69 -46
  94. package/src/client/routes/ToolsRoute.tsx +108 -94
  95. package/src/client/routes/TracesRoute.tsx +25 -23
  96. package/src/client/styles.css +5 -2
  97. package/src/client/traces/AggregatesPanel.tsx +19 -8
  98. package/src/client/traces/Minimap.tsx +65 -27
  99. package/src/client/traces/SpanDrawer.tsx +46 -21
  100. package/src/client/traces/SummaryStrip.tsx +27 -11
  101. package/src/client/traces/TimelineCanvas.tsx +245 -116
  102. package/src/client/traces/TraceView.tsx +51 -36
  103. package/src/client/traces/TranscriptList.tsx +20 -11
  104. package/src/client/traces/traces.css +26 -0
  105. package/src/client/ui/JsonBlock.tsx +3 -2
  106. package/src/client/ui/Modal.tsx +3 -2
  107. package/src/client/ui/RequestDrawer.tsx +33 -30
  108. package/src/client/ui/SearchInput.tsx +2 -1
  109. package/src/client/ui/States.tsx +3 -2
  110. package/src/client/ui/Table.tsx +7 -3
  111. package/src/db.ts +150 -135
  112. package/src/embedded-client.ts +9 -0
  113. package/src/frustration.ts +9 -30
  114. package/src/index.ts +2 -1
  115. package/src/live.ts +36 -11
  116. package/src/locale.ts +29 -0
  117. package/src/parser.ts +37 -72
  118. package/src/port-conflict.ts +1 -1
  119. package/src/prompts/judge/frustration.json +19 -0
  120. package/src/rollup.ts +41 -20
  121. package/src/server.ts +67 -27
  122. package/src/shared-types.ts +7 -0
  123. package/src/trace.ts +54 -40
  124. package/src/types.ts +13 -1
  125. package/src/user-metrics.ts +220 -6
@@ -0,0 +1,13 @@
1
+ import type { MessageKey } from "./en.js";
2
+ /**
3
+ * Simplified Chinese overrides. Incomplete on purpose in source: the coverage
4
+ * test (`packages/stats/test/i18n-coverage.test.ts`) fails on any missing key,
5
+ * which keeps a half-translated page out of a release without breaking builds
6
+ * mid-flight.
7
+ */
8
+ export declare const zhCNMessages: Partial<Record<MessageKey, string>>;
9
+ /** The Simplified Chinese locale pack. */
10
+ export declare const zhCNLocale: {
11
+ readonly id: "zh-CN";
12
+ readonly messages: Partial<Record<"common.aborted" | "common.average" | "common.cache-read" | "common.cache-write" | "common.cancel" | "common.close" | "common.copied" | "common.copy" | "common.cost" | "common.duration" | "common.entry-id" | "common.error" | "common.error-rate" | "common.failed" | "common.filter" | "common.input" | "common.model" | "common.models" | "common.no-data-in-range" | "common.nothing-here-yet" | "common.other-n" | "common.output" | "common.output-message" | "common.output-tokens-per-second" | "common.pages" | "common.premium" | "common.premium-requests" | "common.project" | "common.provider" | "common.providers" | "common.range-1h" | "common.range-24h" | "common.range-30d" | "common.range-7d" | "common.range-90d" | "common.range-all" | "common.request" | "common.request-id" | "common.requests" | "common.root" | "common.session-entry" | "common.share" | "common.show-more" | "common.started" | "common.time-range" | "common.tokens" | "common.tokens-per-second" | "common.total" | "common.unknown" | "common.window-1h" | "common.window-24h" | "common.window-30d" | "common.window-7d" | "common.window-90d" | "common.window-all" | "costs.active-days-n" | "costs.active-days-one" | "costs.all-priced" | "costs.api-equivalent-estimate" | "costs.api-estimate-title" | "costs.average-per-day" | "costs.average-per-day-title" | "costs.by-component" | "costs.by-model" | "costs.by-model-description" | "costs.daily-by-component" | "costs.daily-by-model" | "costs.daily-estimate" | "costs.description" | "costs.empty-hint" | "costs.estimate" | "costs.estimate-by-component" | "costs.estimate-title" | "costs.no-priced-usage" | "costs.no-usage-in-range" | "costs.nothing-priced-yet" | "costs.per-priced-request" | "costs.per-priced-request-title" | "costs.per-request" | "costs.per-request-title" | "costs.priced-n" | "costs.requests-n" | "costs.split" | "costs.split-by" | "costs.split-title" | "costs.title" | "costs.top-model" | "costs.top-model-hint" | "costs.unpriced" | "costs.unpriced-column-title" | "costs.unpriced-hint" | "costs.unpriced-note-n" | "costs.unpriced-note-one" | "costs.unpriced-requests" | "costs.unpriced-title" | "costs.where-it-went" | "errors.affected-models" | "errors.by-model" | "errors.by-model-description" | "errors.cost-hint" | "errors.description" | "errors.empty-all-succeeded" | "errors.empty-no-affected-models" | "errors.empty-no-failures" | "errors.error-signatures" | "errors.failures" | "errors.filtered-of-total" | "errors.footer" | "errors.group-meta" | "errors.hint-in-window" | "errors.hint-latest-loaded" | "errors.last-failure" | "errors.last-seen" | "errors.load-latest" | "errors.loading" | "errors.loading-failures" | "errors.more-models" | "errors.no-match" | "errors.no-match-hint" | "errors.none-in-window" | "errors.open-latest" | "errors.search-placeholder" | "errors.signature" | "errors.signatures" | "errors.signatures-card-description" | "errors.signatures-hint" | "errors.signatures-top" | "errors.title" | "errors.unknown-error" | "errors.when" | "frustration.all-classes" | "frustration.all-judged" | "frustration.angry" | "frustration.angry-title" | "frustration.annoyed" | "frustration.annoyed-title" | "frustration.at-assistant" | "frustration.at-assistant-title" | "frustration.by-model" | "frustration.by-model-description" | "frustration.cancel-run" | "frustration.cancelled" | "frustration.cancelling" | "frustration.classify" | "frustration.column-judged" | "frustration.column-messages" | "frustration.column-model-ids" | "frustration.cost-so-far" | "frustration.coverage-hint" | "frustration.coverage-unscored" | "frustration.description" | "frustration.done" | "frustration.elapsed" | "frustration.estimate-note" | "frustration.estimated-cost" | "frustration.estimating" | "frustration.every-model-class" | "frustration.failed" | "frustration.failed-n" | "frustration.failed-suffix" | "frustration.hatch-title" | "frustration.hide-regex-title" | "frustration.in-flight" | "frustration.in-time" | "frustration.include-small" | "frustration.input-tokens" | "frustration.judge-coverage" | "frustration.judge-coverage-title" | "frustration.judge-description" | "frustration.judge-model" | "frustration.judge-panel" | "frustration.judge-running" | "frustration.judge-with" | "frustration.last-run-cancelled" | "frustration.last-run-done" | "frustration.last-run-failed" | "frustration.legend-angry" | "frustration.legend-annoyed-any" | "frustration.legend-assistant" | "frustration.legend-hatched" | "frustration.legend-hatched-run" | "frustration.legend-hue" | "frustration.legend-other" | "frustration.legend-trend" | "frustration.messages-n" | "frustration.messages-progress" | "frustration.model-class" | "frustration.model-versions" | "frustration.mostly-regex" | "frustration.no-messages" | "frustration.no-model-match" | "frustration.no-run-yet" | "frustration.not-run-yet" | "frustration.proceed" | "frustration.prose-chars" | "frustration.quote-title" | "frustration.regex-badge" | "frustration.regex-only" | "frustration.row-mostly-regex" | "frustration.run-cancelled-after" | "frustration.run-cancelled-line" | "frustration.run-done-line" | "frustration.run-failed-after" | "frustration.run-failed-line" | "frustration.run-judged" | "frustration.running" | "frustration.small-models-title" | "frustration.stack-relation" | "frustration.starting" | "frustration.table-description" | "frustration.title" | "frustration.try-longer-range" | "frustration.unclassified" | "frustration.unjudged-messages" | "frustration.unknown-error" | "frustration.unscored-line" | "frustration.user-messages" | "frustration.user-messages-title" | "gain.all-projects" | "gain.by-source" | "gain.by-source-description" | "gain.cumulative" | "gain.description" | "gain.description-scoped" | "gain.empty-hint-all" | "gain.empty-hint-longer-range" | "gain.empty-title" | "gain.empty-title-scoped" | "gain.hits" | "gain.reduction" | "gain.reduction-title" | "gain.reduction-unknown" | "gain.saved-bytes" | "gain.saved-per-day" | "gain.saved-per-hit" | "gain.saved-tokens" | "gain.savings-over-time" | "gain.savings-over-time-description" | "gain.source" | "gain.title" | "models.across-providers" | "models.across-providers-one" | "models.all-models" | "models.api-cost" | "models.api-cost-title" | "models.avg-duration" | "models.avg-ttft" | "models.bucket-5m" | "models.bucket-day" | "models.bucket-hour" | "models.cache-rate" | "models.cache-savings" | "models.cache-title" | "models.cost-title" | "models.count-desc" | "models.efficiency" | "models.empty-hint" | "models.empty-title" | "models.errors" | "models.failed-n" | "models.first-last-seen" | "models.latency" | "models.most-used" | "models.most-used-hint" | "models.no-samples-hint" | "models.no-samples-title" | "models.performance-per-bucket" | "models.request-share" | "models.share-desc" | "models.share-mode-aria" | "models.subtitle" | "models.table-desc" | "models.tok-per-second" | "models.tokens-title" | "models.tps-title" | "models.trend" | "models.trend-title" | "models.ttft" | "models.ttft-title" | "models.uncached-input" | "models.unpriced-n" | "models.used" | "nav.activity" | "nav.breadcrumb-stats" | "nav.costs" | "nav.dashboard" | "nav.errors" | "nav.frustration" | "nav.gain" | "nav.insights" | "nav.models" | "nav.open-navigation" | "nav.overview" | "nav.pages" | "nav.projects" | "nav.providers" | "nav.requests" | "nav.tools" | "nav.traces" | "nav.usage" | "overview.activity" | "overview.advisor" | "overview.all-requests" | "overview.api-cost-title" | "overview.api-equivalent" | "overview.api-equivalent-cost" | "overview.avg-latency" | "overview.avg-ttft" | "overview.by-agent" | "overview.cache-rate" | "overview.cache-rate-title" | "overview.cache-saved" | "overview.conversation-tokens" | "overview.description" | "overview.failed-n" | "overview.latest-requests" | "overview.latest-requests-description" | "overview.main-agent" | "overview.ok" | "overview.output-n" | "overview.per-5m" | "overview.per-day" | "overview.per-hour" | "overview.requests-short" | "overview.status" | "overview.subagents" | "overview.succeeded" | "overview.succeeded-n" | "overview.title" | "overview.token-mix" | "overview.token-mix-description" | "overview.tokens-title" | "overview.uncached-input" | "overview.unpriced-n" | "overview.when" | "projects.api-equivalent-cost" | "projects.api-equivalent-cost-hint" | "projects.api-equivalent-cost-rates" | "projects.avg-duration" | "projects.cache-rate" | "projects.cache-rate-hint" | "projects.cache-rate-hint-all" | "projects.cache-savings" | "projects.cache-savings-hint" | "projects.conversation-tokens" | "projects.conversation-tokens-hint" | "projects.description" | "projects.empty-no-folders" | "projects.empty-no-match" | "projects.empty-only-temporary" | "projects.errors" | "projects.failed-n" | "projects.filter-placeholder" | "projects.folder" | "projects.folders" | "projects.folders-n" | "projects.folders-of-n" | "projects.hide-temporary" | "projects.hide-temporary-hint" | "projects.hint-longer-range" | "projects.hint-temporary-hidden" | "projects.last-active" | "projects.share-of-cost" | "projects.share-of-requests" | "projects.temp" | "projects.temporary-n" | "projects.title" | "projects.top-by-cost" | "projects.top-by-cost-description" | "projects.top-by-requests" | "projects.top-by-requests-description" | "projects.unpriced-n" | "providers.account" | "providers.accounts" | "providers.accounts-needed" | "providers.accounts-needed-title" | "providers.accounts-title" | "providers.all-providers" | "providers.api-cost-title" | "providers.api-equivalent-cost" | "providers.bucket-5m" | "providers.bucket-day" | "providers.bucket-hour" | "providers.burn" | "providers.burn-description" | "providers.burn-estimate-description" | "providers.cost-title" | "providers.description" | "providers.exhausted" | "providers.exhausted-n" | "providers.exhaustions" | "providers.exhaustions-title" | "providers.failed-n" | "providers.high" | "providers.hours-description" | "providers.ideal-accounts" | "providers.latest-used" | "providers.models-title" | "providers.most-tokens" | "providers.no-activity-in-range" | "providers.no-provider-activity" | "providers.no-reading" | "providers.no-requests-in-range" | "providers.no-snapshots-in-range" | "providers.no-utilization-readings" | "providers.peak-burn-hours" | "providers.peak-hours-description" | "providers.peak-in-range" | "providers.peak-utilization" | "providers.peak-utilization-title" | "providers.premium-title" | "providers.recorded" | "providers.resets" | "providers.resets-title" | "providers.share-title" | "providers.snapshot-hint" | "providers.snapshots" | "providers.status" | "providers.subscription-windows" | "providers.subscription-windows-description" | "providers.succeeded-n" | "providers.tokens-peak-hour" | "providers.tokens-per-window" | "providers.tokens-per-window-title" | "providers.tokens-title" | "providers.too-little-consumed" | "providers.totals" | "providers.totals-description" | "providers.totals-description-unpriced-n" | "providers.totals-description-unpriced-one" | "providers.tps-title" | "providers.unpriced-n" | "providers.utilization" | "providers.utilization-description" | "providers.utilization-description-plain" | "providers.window" | "providers.windows-burned" | "providers.windows-burned-title" | "requests.api-equivalent-cost" | "requests.cache-read-title" | "requests.cache-write" | "requests.cost-estimate" | "requests.cost-hint" | "requests.description" | "requests.empty-in-window" | "requests.empty-no-match" | "requests.empty-no-match-hint" | "requests.failed-hint" | "requests.footer" | "requests.load-latest" | "requests.loading" | "requests.log-count-in-window" | "requests.log-count-latest" | "requests.log-loading" | "requests.log-title" | "requests.median-duration" | "requests.median-ttft" | "requests.none-in-window" | "requests.p95" | "requests.search-placeholder" | "requests.since" | "requests.status" | "requests.status-all" | "requests.tokens-hint" | "requests.ttft" | "requests.ttft-hint" | "requests.uncached-input" | "requests.unpriced-n" | "requests.when" | "shell.building-rollups" | "shell.dark-theme" | "shell.indexing" | "shell.ingesting" | "shell.jump-hint" | "shell.just-now" | "shell.light-theme" | "shell.live" | "shell.lost-connection" | "shell.range-suffix" | "shell.reconnecting" | "shell.sync-failed" | "shell.sync-now" | "shell.syncing" | "shell.system-theme" | "tools.all-tools" | "tools.api-equivalent" | "tools.args" | "tools.args-chars-title" | "tools.attr-cost" | "tools.attr-tokens" | "tools.attributed-cost" | "tools.attributed-tokens" | "tools.attribution-estimate" | "tools.attribution-note" | "tools.avg-args-per-call" | "tools.avg-result-per-call" | "tools.bucket-5m" | "tools.bucket-day" | "tools.bucket-hour" | "tools.by-tool" | "tools.by-tool-and-model" | "tools.by-tool-and-model-description" | "tools.by-tool-description" | "tools.call-arguments" | "tools.calls" | "tools.calls-over-time" | "tools.chars" | "tools.chart-description" | "tools.clear-tool-filter" | "tools.description" | "tools.distinct-tools" | "tools.error-rate-title" | "tools.errors" | "tools.errors-over-time" | "tools.errors-title" | "tools.failed-n" | "tools.filter-by-tool" | "tools.last-used" | "tools.most-used" | "tools.no-calls-to-tool" | "tools.no-tool-calls" | "tools.no-tool-errors" | "tools.result" | "tools.result-chars-title" | "tools.result-per-call" | "tools.result-per-call-title" | "tools.result-text" | "tools.share-of-calls" | "tools.share-of-cost" | "tools.share-of-tokens" | "tools.succeeded-n" | "tools.title" | "tools.tokens-output" | "tools.tool" | "tools.tool-calls" | "tools.trend" | "tools.trend-title" | "tools.unpriced-requests-n" | "trace.agent" | "trace.agents" | "trace.args" | "trace.avg" | "trace.axis-mode" | "trace.background" | "trace.bg" | "trace.calls" | "trace.canvas-aria" | "trace.collapse-all" | "trace.collapse-track" | "trace.compress-idle" | "trace.copy-json" | "trace.description" | "trace.empty-hint" | "trace.empty-title" | "trace.error-message" | "trace.errors" | "trace.expand-all" | "trace.expand-track" | "trace.failed-n" | "trace.filter-placeholder" | "trace.idle" | "trace.io-cached" | "trace.load-failed" | "trace.max" | "trace.minimap-aria" | "trace.mode-calls-title" | "trace.mode-time-title" | "trace.mode-turns-title" | "trace.model-time" | "trace.most-recent" | "trace.most-recent-filtered" | "trace.next-match" | "trace.no-matching-events" | "trace.no-matching-hint" | "trace.no-matching-title" | "trace.of-wall" | "trace.open-child-track" | "trace.previous-match" | "trace.raw-entry" | "trace.refresh" | "trace.search-placeholder" | "trace.session" | "trace.sessions" | "trace.start" | "trace.stop-reason" | "trace.task" | "trace.text" | "trace.thinking" | "trace.timeline" | "trace.timeline-hint" | "trace.title" | "trace.tok" | "trace.tool" | "trace.tool-aggregates" | "trace.tool-aggregates-desc" | "trace.tool-calls-n" | "trace.tool-time" | "trace.tools" | "trace.track" | "trace.transcript" | "trace.transcript-description" | "trace.ttft" | "trace.turns" | "trace.unterminated" | "trace.wall-time" | "ui.api" | "ui.delta-new" | "ui.json" | "ui.open-trace" | "ui.retry" | "ui.section-cost" | "ui.section-identity" | "ui.section-timing" | "ui.session-file" | "ui.show-fewer" | "ui.stats-row" | "ui.status-ok" | "ui.stop-reason" | "ui.table-shown-of" | "ui.time-to-first-token" | "ui.trace" | "ui.uncached-input", string>>;
13
+ };
@@ -0,0 +1,15 @@
1
+ export type { StatsLocale } from "../../locale.js";
2
+ import type { StatsLocale } from "../../locale.js";
3
+ /** Values a message may interpolate through `{name}` placeholders. */
4
+ export type TranslationParams = Record<string, string | number>;
5
+ /** A locale pack: the messages one locale overrides, keyed by slug. */
6
+ export interface LocalePack {
7
+ readonly id: StatsLocale;
8
+ readonly messages: Readonly<Record<string, string>>;
9
+ }
10
+ /**
11
+ * Messages for every locale, keyed first by locale id. `undefined` is part of
12
+ * the value type because a locale may override only some keys (English is the
13
+ * fallback for the rest).
14
+ */
15
+ export type MessagesByLocale = Readonly<Record<StatsLocale, Readonly<Record<string, string | undefined>>>>;
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Timeline overview strip: per-category density over the full virtual domain
3
3
  * plus a draggable/resizable viewport brush, mirroring DevTools' overview.
4
+ * The density layer is painted once per trace/scale/size/theme into an
5
+ * offscreen canvas; pan and zoom only blit it and redraw the brush.
4
6
  */
5
7
  import type { TraceTrack } from "../types.js";
6
8
  import type { TimelineViewport } from "./TimelineCanvas.js";
@@ -1,10 +1,11 @@
1
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.
2
+ * The trace flamegraph: a DPR-scaled scene canvas with DOM hover/selection
3
+ * boxes on top, a DOM gutter (track/lane labels, collapse chevrons) and a
4
+ * DOM tooltip. Implements the Chrome DevTools interaction contract:
5
+ * cursor-anchored wheel zoom, drag pan, WASD, fit/focus keys, hover tooltips,
6
+ * click-to-select, double-click-to-zoom.
6
7
  */
7
- import type { TraceTrack } from "../types.js";
8
+ import type { TraceSpan, TraceTrack } from "../types.js";
8
9
  import { type TraceScale } from "./time-scale.js";
9
10
  export interface TimelineViewport {
10
11
  u0: number;
@@ -15,11 +16,31 @@ export interface TimelineCanvasProps {
15
16
  scale: TraceScale;
16
17
  viewport: TimelineViewport;
17
18
  onViewportChange: (viewport: TimelineViewport) => void;
18
- selection: string | null;
19
+ /** The selected span with its track (resolved by the trace view). */
20
+ selected: {
21
+ span: TraceSpan;
22
+ track: TraceTrack;
23
+ } | null;
19
24
  onSelect: (spanId: string | null) => void;
20
- search: string;
25
+ /** Spans matching the search; `null` when not searching (everything at full opacity). */
26
+ matchIds: ReadonlySet<string> | null;
21
27
  collapsed: ReadonlySet<string>;
22
28
  onToggleCollapse: (trackId: string) => void;
23
29
  traceStart: number;
24
30
  }
25
- export declare function TimelineCanvas({ tracks, scale, viewport, onViewportChange, selection, onSelect, search, collapsed, onToggleCollapse, traceStart, }: TimelineCanvasProps): import("react").JSX.Element;
31
+ /** Per-lane span positions on the virtual axis, parallel to `LaneRow.spans`. */
32
+ interface LaneAxis {
33
+ startU: Float64Array;
34
+ endU: Float64Array;
35
+ /** Running max of `endU`; monotonic, so the first visible span is a binary search away. */
36
+ maxEndU: Float64Array;
37
+ }
38
+ export declare function buildLaneAxes(layout: {
39
+ lanes: ReadonlyArray<{
40
+ spans: ReadonlyArray<Pick<TraceSpan, "start" | "end">>;
41
+ }>;
42
+ }, scale: Pick<TraceScale, "toU">): LaneAxis[];
43
+ /** First index whose running-max end reaches `u0`: every earlier span ends before the viewport. */
44
+ export declare function firstVisible(maxEndU: Float64Array, u0: number): number;
45
+ export declare function TimelineCanvas({ tracks, scale, viewport, onViewportChange, selected, onSelect, matchIds, collapsed, onToggleCollapse, traceStart, }: TimelineCanvasProps): import("react").JSX.Element;
46
+ export {};
@@ -17,8 +17,10 @@ export interface TranscriptListProps {
17
17
  selection: string | null;
18
18
  onSelect: (spanId: string) => void;
19
19
  search: string;
20
+ /** Spans matching `search` (from the trace view); `null` when not searching. */
21
+ matchIds: ReadonlySet<string> | null;
20
22
  traceStart: number;
21
23
  }
22
24
  /** Flatten all spans and markers across tracks into chronological rows. */
23
25
  export declare function buildTranscriptRows(tracks: TraceTrack[]): TranscriptRow[];
24
- export declare function TranscriptList({ tracks, selection, onSelect, search, traceStart }: TranscriptListProps): import("react").JSX.Element;
26
+ export declare const TranscriptList: import("react").MemoExoticComponent<({ tracks, selection, onSelect, search, matchIds, traceStart, }: TranscriptListProps) => import("react").JSX.Element>;
@@ -49,12 +49,23 @@ export interface ParsedSession {
49
49
  /** Recover missing rows from a full-history scan without rewriting unchanged records. */
50
50
  replay: boolean;
51
51
  }
52
- /** Commit distinct transcripts' rows, reconciliation state, and cursors together; failure rolls back the batch. */
52
+ /**
53
+ * Commit distinct transcripts' rows, reconciliation state, and cursors together; failure rolls back the batch.
54
+ * `changes` counts stored rows inserted, updated or deleted (cursor bookkeeping excluded), so callers can
55
+ * tell a batch that changed nothing.
56
+ */
53
57
  export declare function applySessionParseResults(sessions: ParsedSession[]): {
54
58
  processed: number;
55
59
  files: number;
56
60
  reconcile: boolean;
61
+ changes: number;
57
62
  };
63
+ /**
64
+ * SQLite `PRAGMA data_version` of the open connection, or null before
65
+ * {@link initDb}. It moves only when another connection (another omp process)
66
+ * commits, so a caller can detect foreign writes without scanning.
67
+ */
68
+ export declare function getDataVersion(): number | null;
58
69
  export declare function prepareSessionSync(): boolean;
59
70
  export declare function completeSessionSync(reconcile: boolean): void;
60
71
  /**
@@ -90,32 +101,14 @@ export declare function getMessageById(id: number): MessageStats | null;
90
101
  * Self-initializing (opens the stats DB on first use) so the coding-agent TUI
91
102
  * can query without the dashboard server's init flow. Days use the machine's
92
103
  * timezone — this is a localhost tool, same rationale as
93
- * {@link getProviderHourlyBurn}.
104
+ * {@link getProviderHourlyBurn}. Reads the hourly rollup, falling back to the
105
+ * raw rows while its rebuild backlog is too large for exact reads.
94
106
  */
95
107
  export declare function getDailyActivity(days?: number): Promise<DailyActivityPoint[]>;
96
108
  /**
97
109
  * Settle every full-session backfill after a successful sync pass.
98
110
  */
99
111
  export declare function markSessionBackfillsComplete(): void;
100
- export interface PruneOrphanResult {
101
- /** Distinct session files whose rows were removed. */
102
- prunedFiles: number;
103
- /** Total rows removed across all session-keyed tables. */
104
- deletedRows: number;
105
- }
106
- /**
107
- * Delete every row whose `session_file` no longer exists on disk. Deleted
108
- * projects (tmp test suites, wiped transcripts) otherwise keep surfacing in
109
- * the Operational Feed and models list forever. Runs in one transaction; the
110
- * existing-file set is collected by the caller before any DELETE so the
111
- * comparison is a single in-memory set probe per stored path.
112
- */
113
- export declare function pruneOrphanSessionsInDb(database: Database, existingFiles: readonly string[]): PruneOrphanResult;
114
- /**
115
- * {@link pruneOrphanSessionsInDb} against the module DB handle. No-op when
116
- * {@link initDb} has not run.
117
- */
118
- export declare function pruneOrphanSessions(existingFiles: readonly string[]): PruneOrphanResult;
119
112
  /**
120
113
  * Insert user-message stats. Idempotent via UNIQUE(session_file, entry_id).
121
114
  * The `WHERE NOT EXISTS` clause matches {@link insertMessageStats}: forks
@@ -7,6 +7,11 @@
7
7
  * prepacked npm bundle, and reset to an empty file afterwards so the dev tree
8
8
  * keeps building the dashboard from source.
9
9
  */
10
+ /**
11
+ * Cheap check whether the generated text carries a gzip archive: sniffs the
12
+ * base64 of the gzip magic (`1f 8b 08`) without decoding megabytes.
13
+ */
14
+ export declare function hasEmbeddedClientArchive(txt: string): boolean;
10
15
  /**
11
16
  * Decode the generated archive text.
12
17
  *
@@ -16,26 +16,35 @@
16
16
  * using the judge the omp host registered through `startServer`. Standalone
17
17
  * `omp-stats` has none and only shows the regex fallback.
18
18
  */
19
- import type { ChoiceQuestion, Judge, Model, ScoreQuestion } from "@linxiraos/pi-ai";
19
+ import { type Judge, type Model } from "@linxiraos/pi-ai";
20
20
  import { type FrustrationModelRow } from "./db.js";
21
21
  import type { FrustrationDashboardStats, FrustrationEstimate, FrustrationJobStatus, FrustrationModelStats } from "./shared-types.js";
22
22
  /** Judge supplied by the omp host process; `primaryModel` prices the pre-run estimate. */
23
23
  export interface StatsJudge extends Judge {
24
24
  primaryModel(): Model | undefined;
25
25
  }
26
- /** Lazily resolves the host judge on first estimate/run so `omp stats` startup stays fast. */
26
+ /** Lazily resolves the host judge on first estimate/run so `zetacode stats` startup stays fast. */
27
27
  export type StatsJudgeProvider = () => Promise<StatsJudge>;
28
- /** Where the user's annoyance is aimed. */
29
- export type FrustrationTarget = "assistant" | "other" | "none";
30
28
  /**
31
- * The two questions asked about every prose text, in ONE judge request.
29
+ * The two questions asked about every prose text, in ONE judge request:
30
+ * `annoyed` (four levels) and `target` (`assistant`, `other`, or `none`).
32
31
  * The cost constants below were measured with exactly these strings; changing
33
32
  * them invalidates both the estimate and every cached verdict's meaning.
34
33
  */
35
- export declare const FRUSTRATION_QUESTIONS: {
36
- annoyed: ScoreQuestion;
37
- target: ChoiceQuestion<FrustrationTarget>;
38
- };
34
+ export declare const FRUSTRATION_QUESTIONS: import("@linxiraos/pi-ai").QuestionsFor<{
35
+ annoyed: {
36
+ instructions: string;
37
+ criteria: string[];
38
+ };
39
+ target: {
40
+ instructions: string;
41
+ criteria: {
42
+ assistant: string;
43
+ other: string;
44
+ none: string;
45
+ };
46
+ };
47
+ }>;
39
48
  /** Register (or replace) the host judge. Called by `startServer`. */
40
49
  export declare function setStatsJudgeProvider(provider: StatsJudgeProvider | undefined): void;
41
50
  /** Snapshot of the current run's progress. */
@@ -5,11 +5,13 @@
5
5
  * The dashboard never waits for ingest. {@link StatsLive.start} kicks a full
6
6
  * sync in the background and watches the sessions directory; changed
7
7
  * transcripts are re-synced (only those files) shortly after they are written.
8
- * Every committed batch bumps {@link LiveStatus.version} (throttled), so open
9
- * pages refetch and fill in while parsing is still running.
8
+ * Every batch that changes stored rows bumps {@link LiveStatus.version}
9
+ * (throttled), so open pages refetch and fill in while parsing is still
10
+ * running; syncs that change nothing leave the version alone.
10
11
  */
11
12
  import type { LiveStatus } from "./shared-types.js";
12
- type Listener = (status: LiveStatus) => void;
13
+ /** Receives each distinct status and its JSON serialization (shared by every listener). */
14
+ type Listener = (status: LiveStatus, frame: string) => void;
13
15
  /** One per process; owned by the dashboard server (see `startServer`). */
14
16
  export declare class StatsLive {
15
17
  #private;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Locale resolution shared by the stats server (which stamps the host's
3
+ * language into the served HTML) and the client bundle (which renders it).
4
+ * Lives outside `client/` so the server never imports browser code.
5
+ */
6
+ /** Locales the dashboard ships: English and Simplified Chinese. */
7
+ export type StatsLocale = "en" | "zh-CN";
8
+ /**
9
+ * Map a language tag to a shipped locale. Any `zh` variant is Simplified
10
+ * Chinese (the dashboard ships no Traditional pack); everything else —
11
+ * including browser tags such as `tr-TR` — is English, matching the
12
+ * dashboard's single number/date convention rather than the browser's.
13
+ */
14
+ export declare function resolveLocaleTag(tag: string | undefined | null): StatsLocale;
15
+ /** Pick the first shipped locale from a `navigator.languages` list; English when none match. */
16
+ export declare function resolveBrowserLocale(languages: readonly string[] | undefined): StatsLocale;
@@ -18,23 +18,6 @@ export declare function classifyAgentType(sessionPath: string): AgentType;
18
18
  * The folder part uses -- as path separator.
19
19
  */
20
20
  export declare function extractFolderFromPath(sessionPath: string): string;
21
- /**
22
- * Decode a session project folder name back to its source cwd, mirroring the
23
- * encoder in the coding agent's session-paths module: home-relative cwds
24
- * encode as `-<segments>`, temp-relative ones as `-tmp<segments>`, and legacy
25
- * absolute ones as `--<absolute>--`, with `/`, `\`, and `:` collapsed to `-`.
26
- * Returns null when the name carries no decodable cwd.
27
- */
28
- export declare function decodeProjectFolderCwd(projectDir: string): string | null;
29
- /**
30
- * Whether a session project folder decodes to a cwd inside the OS temp dir.
31
- * Test suites spawn agents under `os.tmpdir()` and re-create their transcripts
32
- * on every run; those sessions are throwaway usage that must not reach the
33
- * stats DB. The `-` collapse in the encoder is lossy (a literal `-` inside a
34
- * path segment is indistinguishable from a separator), which can only produce
35
- * false positives here — a skipped ingestion, never a misattributed row.
36
- */
37
- export declare function isTempProjectFolder(projectDir: string): boolean;
38
21
  /**
39
22
  * Token-bucket view for total derivation. Persisted session payloads are
40
23
  * outside-controlled (old versions, foreign producers), so every counter is
@@ -25,7 +25,7 @@
25
25
  * (an hour of data is small and indexed by timestamp).
26
26
  */
27
27
  import type { Database } from "bun:sqlite";
28
- import type { AgentTypeStats, AggregatedStats, CostTimeSeriesPoint, FolderStats, ModelPerformancePoint, ModelStats, ModelTimeSeriesPoint, ProviderAggregate, ProviderHourlyPoint, ProviderTimeSeriesPoint, TimeSeriesPoint, ToolModelStats, ToolTimeSeriesPoint, ToolUsageStats } from "./types.js";
28
+ import type { AgentTypeStats, AggregatedStats, CostTimeSeriesPoint, DailyActivityPoint, FolderStats, ModelPerformancePoint, ModelStats, ModelTimeSeriesPoint, ProviderAggregate, ProviderHourlyPoint, ProviderTimeSeriesPoint, TimeSeriesPoint, ToolModelStats, ToolTimeSeriesPoint, ToolUsageStats } from "./types.js";
29
29
  /**
30
30
  * Create (or rebuild after a version bump) the rollup tables and the triggers
31
31
  * that mark hours dirty. Called from `initDb` after the raw tables exist.
@@ -87,6 +87,14 @@ export declare function getStatsByProvider(cutoff?: number | null): ProviderAggr
87
87
  * up to 30 minutes.
88
88
  */
89
89
  export declare function getProviderHourlyBurn(cutoff?: number | null): ProviderHourlyPoint[];
90
+ /**
91
+ * Per-local-day request/token/cost totals since `cutoff`, oldest first, read
92
+ * from the hourly rollup. Returns null when the local UTC offset is not a whole
93
+ * hour (now or at `cutoff`), since hourly buckets then straddle local midnight,
94
+ * or while the dirty backlog is too large for exact reads; callers then
95
+ * aggregate the raw rows instead.
96
+ */
97
+ export declare function getDailyActivityFromRollup(cutoff: number): DailyActivityPoint[] | null;
90
98
  /** Tokens/cost per bucket per provider. */
91
99
  export declare function getProviderTimeSeries({ cutoff, bucketMs }: RangeWindow): ProviderTimeSeriesPoint[];
92
100
  /** Per-transcript-file rollup for the Traces session list. */
@@ -16,5 +16,11 @@ export interface StatsServerHandle {
16
16
  export interface StartServerOptions {
17
17
  /** Host judge for the Frustration dashboard's judge runs; replaces any previously registered one. */
18
18
  judge?: StatsJudgeProvider;
19
+ /**
20
+ * Host UI language (`zh`, `zh-CN`, `en`, …). Stamped into the served page so
21
+ * the dashboard renders in the same language as the CLI that launched it;
22
+ * anything unrecognized resolves to English.
23
+ */
24
+ language?: string;
19
25
  }
20
26
  export declare function startServer(port?: number, hostname?: string, options?: StartServerOptions): Promise<StatsServerHandle>;
@@ -191,6 +191,13 @@ export interface FrustrationCounts {
191
191
  messages: number;
192
192
  /** Messages whose prose has a cached judge verdict; the rest use regex fallback. */
193
193
  judged: number;
194
+ /**
195
+ * Unjudged messages whose prose is written in a script no lexicon covers
196
+ * (Kana, Hangul, Cyrillic, …). Their regex counts are zeros because there is
197
+ * no lexicon, not because the user was calm - the dashboard says so instead
198
+ * of folding them into "not annoyed", and the judge is the fix for them.
199
+ */
200
+ unscored: number;
194
201
  /** Annoyed at anything (the assistant, tooling, other people, ...). */
195
202
  annoyed: number;
196
203
  /** Annoyed and aimed at the assistant. Subset of `annoyed`. */
@@ -18,18 +18,30 @@ export declare class TracePathError extends Error {
18
18
  * against an unchanged transcript mtime.
19
19
  */
20
20
  export declare const TRACE_ETAG_VERSION = 3;
21
+ /** Freshness of a root trace: root mtime plus the child-transcript set fingerprint. */
22
+ export interface TraceFingerprint {
23
+ rootMtimeMs: number;
24
+ childFingerprint: string;
25
+ }
21
26
  /**
22
- * Freshness fingerprint for the trace ETag pre-check: root mtime plus the
23
- * child-transcript set fingerprint (readdir+stat walk, no parse). Returns
24
- * undefined when the path is rejected or missing (the caller falls through
25
- * to the full build, which maps those to 400/404).
27
+ * Freshness fingerprint for the trace ETag pre-check; `SessionTrace.etag` is
28
+ * `${rootMtimeMs}:${childFingerprint}` for an unraced build. Returns undefined
29
+ * when the path is rejected or missing (the caller falls through to the full
30
+ * build, which maps those to 400/404).
26
31
  */
27
- export declare function traceFingerprintForEtag(fileParam: string): Promise<string | undefined>;
32
+ export declare function traceFingerprintForEtag(fileParam: string): Promise<TraceFingerprint | undefined>;
28
33
  export declare function traceMemoForTests(): {
29
34
  file: string;
30
35
  mtimeMs: number;
31
36
  } | undefined;
32
- export declare function buildSessionTrace(fileParam: string): Promise<SessionTrace>;
37
+ /**
38
+ * Assemble the full span tree for one root session transcript.
39
+ * Throws {@link TracePathError} for paths outside the sessions root; ENOENT
40
+ * passes through for the caller's 404 mapping. `fingerprint` may carry the
41
+ * {@link traceFingerprintForEtag} value the caller just computed for the same
42
+ * file (its ETag pre-check), sparing a second walk.
43
+ */
44
+ export declare function buildSessionTrace(fileParam: string, fingerprint?: TraceFingerprint): Promise<SessionTrace>;
33
45
  /** Fetch one full journal entry by id from a transcript, for the span drawer. */
34
46
  export declare function getTraceEntry(fileParam: string, entryId: string): Promise<SessionEntry | null>;
35
47
  /**
@@ -33,6 +33,14 @@ export interface MessageStats {
33
33
  usage: Usage;
34
34
  /** Which agent produced this message (main agent, task subagent, advisor) */
35
35
  agentType: AgentType;
36
+ /**
37
+ * Service tier the provider reported serving this turn, or `null` when the
38
+ * provider reported none. Lets consumers separate a fast serving path's
39
+ * throughput and premium traffic from standard-tier traffic. Always written by
40
+ * `rowToMessageStats`; optional only because session fixtures that stand in
41
+ * for ingest input are typed as `MessageStats` too.
42
+ */
43
+ serviceTier?: ServiceTier | null;
36
44
  /**
37
45
  * Ingest refused to price this request: a scheduled (time-based) card with no
38
46
  * recoverable request timestamp, so `usage.cost.total` of 0 is unknown spend
@@ -61,7 +69,7 @@ export interface MessageStatsInput extends Omit<MessageStats, "usage" | "costUnp
61
69
  export interface RequestDetails extends MessageStats {
62
70
  /** The full conversation history or just the last turn. */
63
71
  messages: unknown[];
64
- /** The model's response. */
72
+ /** The model's response; `null` for `model_usage` entries, which journal no payload. */
65
73
  output: unknown;
66
74
  }
67
75
  /**
@@ -162,6 +170,10 @@ export interface UserMessageStats {
162
170
  repetition: number;
163
171
  /** Second-person reproach ("you didnt", "why did you", "stop X-ing") */
164
172
  blame: number;
173
+ /** Emphatic CJK/voice markers the caps-based yelling cannot see (see `UserMessageMetrics.emphasis`). */
174
+ emphasis: number;
175
+ /** 1 when the prose leans on a script no lexicon covers; such rows are unscored, not calm. */
176
+ unsupportedScript: number;
165
177
  /** Judge-facing prose (see `judgeProse`); empty when the message was all markup. */
166
178
  prose: string;
167
179
  /** Hex `Bun.hash` of `prose`, keying the shared verdict cache; empty when `prose` is. */
@@ -60,6 +60,10 @@ export interface UserMessageMetrics {
60
60
  *
61
61
  * Bare `still` / `again` are too ambiguous to count alone (they show up
62
62
  * in normal speech like "try again" or "still works").
63
+ *
64
+ * Also counts the Chinese recall/still markers (`我说过`, `还是不行`, `又错了`)
65
+ * and whole-message repetition of the previous user message (`prevText`),
66
+ * which is the signal that survives both languages and voice input.
63
67
  */
64
68
  repetition: number;
65
69
  /**
@@ -68,8 +72,24 @@ export interface UserMessageMetrics {
68
72
  * - `you (didn't|did not|broke|missed|forgot|keep|always|never|still|ignored)`
69
73
  * - `why (would|did) (you|u)`
70
74
  * - sentence-leading `stop <verb>ing` imperatives
75
+ * - the Chinese forms (`你怎么又`, `你没改`, `我明明说过`, `不是让你`)
71
76
  */
72
77
  blame: number;
78
+ /**
79
+ * Emphatic markers the caps-based {@link yelling} cannot see, because they
80
+ * are how Chinese - and any voice-transcribed text - shouts: full-width
81
+ * `!?` bursts, a Han character or short word repeated three or more times
82
+ * (`不不不`, `不对不对不对`), and elongated interjections (`啊啊啊`).
83
+ * English text scores 0 here; its shouting is already in {@link yelling}.
84
+ */
85
+ emphasis: number;
86
+ /**
87
+ * 1 when the prose is dominated by a script no shipped lexicon covers
88
+ * (Kana, Hangul, Cyrillic, Arabic, …). The other counts are then *not*
89
+ * evidence of calm - they are evidence of a missing lexicon, and the
90
+ * dashboard reports those messages as unscored rather than as content.
91
+ */
92
+ unsupportedScript: number;
73
93
  }
74
94
  /** Cap on the judge-facing prose stored per user message; longer prose is truncated. */
75
95
  export declare const PROSE_MAX_CHARS = 4000;
@@ -84,6 +104,8 @@ export declare function judgeProse(text: string): string;
84
104
  *
85
105
  * `text` may be empty or whitespace; in that case every metric is 0.
86
106
  */
87
- export declare function computeUserMessageMetrics(text: string): UserMessageMetrics;
107
+ export declare function computeUserMessageMetrics(text: string, options?: {
108
+ /** The user message before this one in the same session, for whole-message repetition. */ prevText?: string;
109
+ }): UserMessageMetrics;
88
110
  /** Empty metrics constant for callers that need a default. */
89
111
  export declare const EMPTY_USER_METRICS: UserMessageMetrics;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@linxiraos/pi-stats",
4
- "version": "1.1.26",
5
- "description": "Local observability dashboard for zeta AI usage statistics",
4
+ "version": "1.2.0",
5
+ "description": "Local observability dashboard for omp AI usage statistics",
6
6
  "homepage": "https://linxira-os.github.io/zeta/",
7
7
  "author": "Linxira-OS",
8
8
  "license": "MIT",
@@ -39,9 +39,9 @@
39
39
  "fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
40
40
  },
41
41
  "dependencies": {
42
- "@linxiraos/pi-ai": "1.1.26",
43
- "@linxiraos/pi-catalog": "1.1.26",
44
- "@linxiraos/pi-utils": "1.1.26",
42
+ "@linxiraos/pi-ai": "1.2.0",
43
+ "@linxiraos/pi-catalog": "1.2.0",
44
+ "@linxiraos/pi-utils": "1.2.0",
45
45
  "lucide-react": "^1.24.0",
46
46
  "react": "19.2.7",
47
47
  "react-dom": "19.2.7"