@oh-my-pi/omp-stats 15.1.0 → 15.1.2

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 (32) hide show
  1. package/dist/client/index.css +1 -0
  2. package/dist/client/index.html +13 -0
  3. package/dist/client/index.js +257 -0
  4. package/dist/client/styles.css +1159 -0
  5. package/dist/types/aggregator.d.ts +65 -0
  6. package/dist/types/client/App.d.ts +1 -0
  7. package/dist/types/client/api.d.ts +10 -0
  8. package/dist/types/client/components/BehaviorChart.d.ts +6 -0
  9. package/dist/types/client/components/BehaviorModelsTable.d.ts +7 -0
  10. package/dist/types/client/components/BehaviorSummary.d.ts +7 -0
  11. package/dist/types/client/components/ChartsContainer.d.ts +6 -0
  12. package/dist/types/client/components/CostChart.d.ts +6 -0
  13. package/dist/types/client/components/CostSummary.d.ts +6 -0
  14. package/dist/types/client/components/Header.d.ts +12 -0
  15. package/dist/types/client/components/ModelsTable.d.ts +7 -0
  16. package/dist/types/client/components/RequestDetail.d.ts +6 -0
  17. package/dist/types/client/components/RequestList.d.ts +8 -0
  18. package/dist/types/client/components/StatsGrid.d.ts +6 -0
  19. package/dist/types/client/components/chart-shared.d.ts +192 -0
  20. package/dist/types/client/components/models-table-shared.d.ts +195 -0
  21. package/dist/types/client/index.d.ts +1 -0
  22. package/dist/types/client/types.d.ts +62 -0
  23. package/dist/types/client/useSystemTheme.d.ts +2 -0
  24. package/dist/types/db.d.ts +93 -0
  25. package/dist/types/index.d.ts +5 -0
  26. package/dist/types/parser.d.ts +40 -0
  27. package/dist/types/server.d.ts +7 -0
  28. package/dist/types/shared-types.d.ts +192 -0
  29. package/dist/types/sync-worker.d.ts +31 -0
  30. package/dist/types/types.d.ts +120 -0
  31. package/dist/types/user-metrics.d.ts +72 -0
  32. package/package.json +12 -10
@@ -0,0 +1,65 @@
1
+ import type { BehaviorDashboardStats, DashboardStats, MessageStats, RequestDetails } from "./types";
2
+ /**
3
+ * Progress event emitted after each session file is fully processed.
4
+ * `current` is the number of files completed (skipped + parsed),
5
+ * `total` is the size of the work set. `processed` is the running total
6
+ * of inserted rows.
7
+ */
8
+ export interface SyncProgress {
9
+ current: number;
10
+ total: number;
11
+ processed: number;
12
+ sessionFile: string;
13
+ }
14
+ export interface SyncOptions {
15
+ /** Called after each file completes. Synchronous; keep it cheap. */
16
+ onProgress?: (event: SyncProgress) => void;
17
+ /**
18
+ * Worker pool size. Defaults to a sensible value derived from the host
19
+ * (capped to avoid drowning a small machine in workers). Set to `1` to
20
+ * force serial parsing without spawning workers.
21
+ */
22
+ workers?: number;
23
+ }
24
+ /**
25
+ * Smoke test: spawns one sync worker, pings it, asserts the pong response,
26
+ * then terminates. Used by `omp --smoke-test` so the install-method CI jobs
27
+ * catch the silent worker-load failure that hit compiled binaries in #1011
28
+ * and #1027 — neither `--version` nor `stats --summary` exercises the worker
29
+ * spawn path on a fresh install (no session files = early return), so a
30
+ * dedicated probe is the only reliable signal.
31
+ *
32
+ * Resolves with the worker's `import.meta.url` (caller-visible diagnostics);
33
+ * rejects on transport error, error response, or timeout.
34
+ */
35
+ export declare function smokeTestSyncWorker({ timeoutMs }?: {
36
+ timeoutMs?: number;
37
+ }): Promise<void>;
38
+ /**
39
+ * Sync all session files to the database.
40
+ *
41
+ * Parsing fans out across a worker pool (one in-flight job per worker)
42
+ * while DB writes and offset bookkeeping stay on the calling thread so the
43
+ * single SQLite handle stays uncontended. `onProgress` fires once per
44
+ * completed file (skipped files included so the bar walks at a steady
45
+ * rate).
46
+ */
47
+ export declare function syncAllSessions(opts?: SyncOptions): Promise<{
48
+ processed: number;
49
+ files: number;
50
+ }>;
51
+ /**
52
+ * Get all dashboard stats.
53
+ */
54
+ export declare function getDashboardStats(range?: string | null): Promise<DashboardStats>;
55
+ export declare function getOverviewStats(range?: string | null): Promise<Pick<DashboardStats, "overall" | "timeSeries">>;
56
+ export declare function getModelDashboardStats(range?: string | null): Promise<Pick<DashboardStats, "byModel" | "modelSeries" | "modelPerformanceSeries">>;
57
+ export declare function getCostDashboardStats(range?: string | null): Promise<Pick<DashboardStats, "costSeries">>;
58
+ export declare function getRecentRequests(limit?: number): Promise<MessageStats[]>;
59
+ export declare function getRecentErrors(limit?: number): Promise<MessageStats[]>;
60
+ export declare function getRequestDetails(id: number): Promise<RequestDetails | null>;
61
+ /**
62
+ * Get the current message count in the database.
63
+ */
64
+ export declare function getTotalMessageCount(): Promise<number>;
65
+ export declare function getBehaviorDashboardStats(range?: string | null): Promise<BehaviorDashboardStats>;
@@ -0,0 +1 @@
1
+ export default function App(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { BehaviorDashboardStats, CostDashboardStats, DashboardStats, MessageStats, ModelDashboardStats, OverviewStats, RequestDetails } from "./types";
2
+ export declare function getStats(range?: string): Promise<DashboardStats>;
3
+ export declare function getOverviewStats(range?: string): Promise<OverviewStats>;
4
+ export declare function getModelDashboardStats(range?: string): Promise<ModelDashboardStats>;
5
+ export declare function getCostDashboardStats(range?: string): Promise<CostDashboardStats>;
6
+ export declare function getRecentRequests(limit?: number): Promise<MessageStats[]>;
7
+ export declare function getRecentErrors(limit?: number): Promise<MessageStats[]>;
8
+ export declare function getRequestDetails(id: number): Promise<RequestDetails>;
9
+ export declare function sync(): Promise<any>;
10
+ export declare function getBehaviorDashboardStats(range?: string): Promise<BehaviorDashboardStats>;
@@ -0,0 +1,6 @@
1
+ import type { BehaviorTimeSeriesPoint } from "../types";
2
+ interface BehaviorChartProps {
3
+ behaviorSeries: BehaviorTimeSeriesPoint[];
4
+ }
5
+ export declare function BehaviorChart({ behaviorSeries }: BehaviorChartProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { BehaviorModelStats, BehaviorTimeSeriesPoint } from "../types";
2
+ interface BehaviorModelsTableProps {
3
+ models: BehaviorModelStats[];
4
+ behaviorSeries: BehaviorTimeSeriesPoint[];
5
+ }
6
+ export declare function BehaviorModelsTable({ models, behaviorSeries }: BehaviorModelsTableProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { BehaviorOverallStats, BehaviorTimeSeriesPoint } from "../types";
2
+ interface BehaviorSummaryProps {
3
+ overall: BehaviorOverallStats;
4
+ behaviorSeries: BehaviorTimeSeriesPoint[];
5
+ }
6
+ export declare function BehaviorSummary({ overall, behaviorSeries }: BehaviorSummaryProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { ModelTimeSeriesPoint } from "../types";
2
+ interface ChartsContainerProps {
3
+ modelSeries: ModelTimeSeriesPoint[];
4
+ }
5
+ export declare function ChartsContainer({ modelSeries }: ChartsContainerProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { CostTimeSeriesPoint } from "../types";
2
+ interface CostChartProps {
3
+ costSeries: CostTimeSeriesPoint[];
4
+ }
5
+ export declare function CostChart({ costSeries }: CostChartProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { CostTimeSeriesPoint } from "../types";
2
+ interface CostSummaryProps {
3
+ costSeries: CostTimeSeriesPoint[];
4
+ }
5
+ export declare function CostSummary({ costSeries }: CostSummaryProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { TimeRange } from "../types";
2
+ type Tab = "overview" | "requests" | "errors" | "models" | "costs" | "behavior";
3
+ interface HeaderProps {
4
+ activeTab: Tab;
5
+ onTabChange: (tab: Tab) => void;
6
+ onSync: () => void;
7
+ syncing: boolean;
8
+ timeRange: TimeRange;
9
+ onTimeRangeChange: (timeRange: TimeRange) => void;
10
+ }
11
+ export declare function Header({ activeTab, onTabChange, onSync, syncing, timeRange, onTimeRangeChange }: HeaderProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { ModelPerformancePoint, ModelStats } from "../types";
2
+ interface ModelsTableProps {
3
+ models: ModelStats[];
4
+ performanceSeries: ModelPerformancePoint[];
5
+ }
6
+ export declare function ModelsTable({ models, performanceSeries }: ModelsTableProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ interface RequestDetailProps {
2
+ id: number;
3
+ onClose: () => void;
4
+ }
5
+ export declare function RequestDetail({ id, onClose }: RequestDetailProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { MessageStats } from "../types";
2
+ interface RequestListProps {
3
+ requests: MessageStats[];
4
+ onSelect: (req: MessageStats) => void;
5
+ title: string;
6
+ }
7
+ export declare function RequestList({ requests, onSelect, title }: RequestListProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { AggregatedStats } from "../types";
2
+ interface StatsGridProps {
3
+ stats: AggregatedStats;
4
+ }
5
+ export declare function StatsGrid({ stats }: StatsGridProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Shared chart primitives for the dashboard timeline charts (BehaviorChart,
3
+ * CostChart). Each chart owns its data shape and metric labels — this module
4
+ * owns the layout, theme, legend/tooltip plumbing, and the top-N-by-model
5
+ * bucketing scaffold that's identical between cost and behavior series.
6
+ */
7
+ export declare const MODEL_COLORS: string[];
8
+ export declare const CHART_THEMES: {
9
+ readonly dark: {
10
+ readonly legendLabel: "#94a3b8";
11
+ readonly tooltipBackground: "#16161e";
12
+ readonly tooltipTitle: "#f8fafc";
13
+ readonly tooltipBody: "#94a3b8";
14
+ readonly tooltipBorder: "rgba(255, 255, 255, 0.1)";
15
+ readonly grid: "rgba(255, 255, 255, 0.06)";
16
+ readonly tick: "#64748b";
17
+ };
18
+ readonly light: {
19
+ readonly legendLabel: "#475569";
20
+ readonly tooltipBackground: "#ffffff";
21
+ readonly tooltipTitle: "#0f172a";
22
+ readonly tooltipBody: "#334155";
23
+ readonly tooltipBorder: "rgba(15, 23, 42, 0.18)";
24
+ readonly grid: "rgba(15, 23, 42, 0.08)";
25
+ readonly tick: "#64748b";
26
+ };
27
+ };
28
+ export type ChartTheme = (typeof CHART_THEMES)[keyof typeof CHART_THEMES];
29
+ export interface ChartSeries {
30
+ labels: string[];
31
+ datasets: Array<{
32
+ label: string;
33
+ data: number[];
34
+ }>;
35
+ }
36
+ interface TooltipItem {
37
+ parsed: {
38
+ y: number | null;
39
+ };
40
+ }
41
+ /** Tooltip + legend config common to bar and line variants of the time charts. */
42
+ export declare function buildSharedPlugins(opts: {
43
+ chartTheme: ChartTheme;
44
+ showLegend: boolean;
45
+ defaultLabel: string;
46
+ formatValue: (n: number) => string;
47
+ footer?: (items: TooltipItem[]) => string | undefined;
48
+ }): {
49
+ legend: {
50
+ display: boolean;
51
+ position: "top";
52
+ align: "start";
53
+ labels: {
54
+ color: "#475569" | "#94a3b8";
55
+ usePointStyle: boolean;
56
+ padding: number;
57
+ font: {
58
+ size: number;
59
+ };
60
+ boxWidth: number;
61
+ };
62
+ };
63
+ tooltip: {
64
+ backgroundColor: "#16161e" | "#ffffff";
65
+ titleColor: "#0f172a" | "#f8fafc";
66
+ bodyColor: "#334155" | "#94a3b8";
67
+ borderColor: "rgba(15, 23, 42, 0.18)" | "rgba(255, 255, 255, 0.1)";
68
+ borderWidth: number;
69
+ padding: number;
70
+ cornerRadius: number;
71
+ callbacks: {
72
+ label: (ctx: {
73
+ dataset: {
74
+ label?: string;
75
+ };
76
+ parsed: {
77
+ y: number | null;
78
+ };
79
+ }) => string;
80
+ footer?: ((items: TooltipItem[]) => string | undefined) | undefined;
81
+ };
82
+ };
83
+ };
84
+ /** Y-axis tick formatter + grid/tick styling shared by both charts. */
85
+ export declare function buildSharedScales(opts: {
86
+ chartTheme: ChartTheme;
87
+ formatY: (n: number) => string;
88
+ }): {
89
+ sharedScaleBase: {
90
+ grid: {
91
+ color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)";
92
+ drawBorder: boolean;
93
+ };
94
+ ticks: {
95
+ color: "#64748b";
96
+ font: {
97
+ size: number;
98
+ };
99
+ };
100
+ };
101
+ yScale: {
102
+ grid: {
103
+ color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)";
104
+ drawBorder: boolean;
105
+ };
106
+ ticks: {
107
+ color: "#64748b";
108
+ font: {
109
+ size: number;
110
+ };
111
+ callback: (value: number | string) => string;
112
+ };
113
+ min: number;
114
+ };
115
+ };
116
+ /** Stylistic defaults for a single line dataset in a stacked/by-model chart. */
117
+ export declare function lineDatasetStyle(color: string): {
118
+ borderColor: string;
119
+ backgroundColor: string;
120
+ fill: boolean;
121
+ tension: number;
122
+ pointRadius: number;
123
+ pointHoverRadius: number;
124
+ borderWidth: number;
125
+ };
126
+ /** Stylistic defaults for a single bar dataset in a stacked chart. */
127
+ export declare function barDatasetStyle(color: string): {
128
+ backgroundColor: string;
129
+ borderColor: string;
130
+ borderWidth: number;
131
+ borderRadius: number;
132
+ };
133
+ /**
134
+ * Map a generic ChartSeries' datasets through a per-index style function so
135
+ * callers can supply line or bar styling without repeating the label/data
136
+ * spread at every chart site.
137
+ */
138
+ export declare function styleDatasets(series: ChartSeries, styleFor: (index: number) => Record<string, unknown>): {
139
+ label: string;
140
+ data: number[];
141
+ }[];
142
+ /**
143
+ * Bucket points by day into a single aggregate series. Caller supplies the
144
+ * per-bucket accumulator + final value extractor; mirrors the shape of
145
+ * `buildTopNByModelSeries` for the non-by-model variant of each time chart.
146
+ */
147
+ export declare function buildAggregateTimeSeries<T extends {
148
+ timestamp: number;
149
+ }, B>(points: T[], label: string, opts: {
150
+ initBucket: () => B;
151
+ accumulate: (bucket: B, point: T) => void;
152
+ bucketToValue: (bucket: B) => number;
153
+ }): ChartSeries;
154
+ interface ModelKeyedPoint {
155
+ timestamp: number;
156
+ model: string;
157
+ provider: string;
158
+ }
159
+ /**
160
+ * Bucket points by day and by top-N model (with an "Other" rollup), producing
161
+ * a ChartSeries. Caller controls how points contribute to ranking and to each
162
+ * day-bucket value via the `rankWeight`/`accumulate`/`bucketToValue` callbacks
163
+ * — keeps the behavior chart's rate math separate from the cost chart's sum.
164
+ */
165
+ export declare function buildTopNByModelSeries<T extends ModelKeyedPoint, B>(points: T[], opts: {
166
+ topN?: number;
167
+ rankWeight: (point: T) => number;
168
+ initBucket: () => B;
169
+ accumulate: (bucket: B, point: T) => void;
170
+ bucketToValue: (bucket: B) => number;
171
+ }): ChartSeries;
172
+ /** All Models / By Model segmented toggle — identical UI in every time chart. */
173
+ export declare function ByModelToggle({ byModel, onChange }: {
174
+ byModel: boolean;
175
+ onChange: (v: boolean) => void;
176
+ }): import("react/jsx-runtime").JSX.Element;
177
+ /**
178
+ * Outer surface card used by both time charts. `controls` slot covers
179
+ * chart-specific tabs (e.g. behavior metric picker); the by-model toggle and
180
+ * empty-state are part of the frame so callers don't redeclare them.
181
+ */
182
+ export declare function ChartFrame({ title, subtitle, empty, emptyMessage, controls, byModel, onByModelChange, children }: {
183
+ title: string;
184
+ subtitle: string;
185
+ empty: boolean;
186
+ emptyMessage: string;
187
+ controls?: React.ReactNode;
188
+ byModel: boolean;
189
+ onByModelChange: (v: boolean) => void;
190
+ children: React.ReactNode;
191
+ }): import("react/jsx-runtime").JSX.Element;
192
+ export {};
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Shared primitives for the per-model breakdown tables (ModelsTable,
3
+ * BehaviorModelsTable). Each table still owns its column definitions, sort
4
+ * order, sidebar contents and chart type — this module owns the surface
5
+ * chrome, expand-row plumbing, theme palette, and the mini-sparkline plus
6
+ * the shared plugin/scale config consumed by multi-line detail charts.
7
+ */
8
+ export { MODEL_COLORS } from "./chart-shared";
9
+ export declare const TABLE_CHART_THEMES: {
10
+ readonly dark: {
11
+ readonly legendLabel: "#cbd5e1";
12
+ readonly tooltipBackground: "#16161e";
13
+ readonly tooltipTitle: "#f8fafc";
14
+ readonly tooltipBody: "#94a3b8";
15
+ readonly tooltipBorder: "rgba(255, 255, 255, 0.1)";
16
+ readonly grid: "rgba(255, 255, 255, 0.06)";
17
+ readonly tick: "#94a3b8";
18
+ };
19
+ readonly light: {
20
+ readonly legendLabel: "#334155";
21
+ readonly tooltipBackground: "#ffffff";
22
+ readonly tooltipTitle: "#0f172a";
23
+ readonly tooltipBody: "#334155";
24
+ readonly tooltipBorder: "rgba(15, 23, 42, 0.18)";
25
+ readonly grid: "rgba(15, 23, 42, 0.08)";
26
+ readonly tick: "#475569";
27
+ };
28
+ };
29
+ export type TableChartTheme = (typeof TABLE_CHART_THEMES)[keyof typeof TABLE_CHART_THEMES];
30
+ /** Style defaults for one line in a non-stacked detail chart. */
31
+ export declare function lineSeriesStyle(color: string): {
32
+ borderColor: string;
33
+ backgroundColor: string;
34
+ tension: number;
35
+ pointRadius: number;
36
+ borderWidth: number;
37
+ };
38
+ /**
39
+ * No-axis, no-legend single-series sparkline used in the trend cell of every
40
+ * model row. Caller supplies the already-extracted numeric series so this
41
+ * stays agnostic of the row's underlying data shape.
42
+ */
43
+ export declare function MiniSparkline({ timestamps, values, color }: {
44
+ timestamps: number[];
45
+ values: number[];
46
+ color: string;
47
+ }): import("react/jsx-runtime").JSX.Element;
48
+ /**
49
+ * Plugin block (legend + tooltip) shared by every multi-series detail chart
50
+ * in the table expanded views.
51
+ */
52
+ export declare function detailChartPlugins(chartTheme: TableChartTheme): {
53
+ legend: {
54
+ display: boolean;
55
+ position: "top";
56
+ labels: {
57
+ color: "#334155" | "#cbd5e1";
58
+ usePointStyle: boolean;
59
+ padding: number;
60
+ font: {
61
+ size: number;
62
+ };
63
+ };
64
+ };
65
+ tooltip: {
66
+ backgroundColor: "#16161e" | "#ffffff";
67
+ titleColor: "#0f172a" | "#f8fafc";
68
+ bodyColor: "#334155" | "#94a3b8";
69
+ borderColor: "rgba(15, 23, 42, 0.18)" | "rgba(255, 255, 255, 0.1)";
70
+ borderWidth: number;
71
+ cornerRadius: number;
72
+ };
73
+ };
74
+ /**
75
+ * Single-Y-axis scales for a detail chart (used when every series shares a
76
+ * unit, e.g. behavior counts). Min anchored at 0.
77
+ */
78
+ export declare function detailChartScalesSingleAxis(chartTheme: TableChartTheme): {
79
+ x: {
80
+ grid: {
81
+ color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)";
82
+ };
83
+ ticks: {
84
+ color: "#475569" | "#94a3b8";
85
+ font: {
86
+ size: number;
87
+ };
88
+ };
89
+ };
90
+ y: {
91
+ grid: {
92
+ color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)";
93
+ };
94
+ ticks: {
95
+ color: "#475569" | "#94a3b8";
96
+ font: {
97
+ size: number;
98
+ };
99
+ };
100
+ min: number;
101
+ };
102
+ };
103
+ /**
104
+ * Dual-Y-axis scales for a detail chart with mixed units (e.g. TTFT seconds
105
+ * on left, tokens/s on right). Right-axis grid is suppressed so it doesn't
106
+ * collide with the left.
107
+ */
108
+ export declare function detailChartScalesDualAxis(chartTheme: TableChartTheme): {
109
+ x: {
110
+ grid: {
111
+ color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)";
112
+ };
113
+ ticks: {
114
+ color: "#475569" | "#94a3b8";
115
+ font: {
116
+ size: number;
117
+ };
118
+ };
119
+ };
120
+ y: {
121
+ type: "linear";
122
+ display: boolean;
123
+ position: "left";
124
+ grid: {
125
+ color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)";
126
+ };
127
+ ticks: {
128
+ color: "#475569" | "#94a3b8";
129
+ font: {
130
+ size: number;
131
+ };
132
+ };
133
+ };
134
+ y1: {
135
+ type: "linear";
136
+ display: boolean;
137
+ position: "right";
138
+ grid: {
139
+ drawOnChartArea: boolean;
140
+ };
141
+ ticks: {
142
+ color: "#475569" | "#94a3b8";
143
+ font: {
144
+ size: number;
145
+ };
146
+ };
147
+ };
148
+ };
149
+ export interface TableColumn {
150
+ label: string;
151
+ align?: "left" | "right" | "center";
152
+ }
153
+ /** Outer card + section title used by every model table. */
154
+ export declare function ModelTableShell({ title, subtitle, children }: {
155
+ title: string;
156
+ subtitle?: string;
157
+ children: React.ReactNode;
158
+ }): import("react/jsx-runtime").JSX.Element;
159
+ /** Sticky column-header row for a model table. */
160
+ export declare function ModelTableHeader({ columns, gridTemplate }: {
161
+ columns: TableColumn[];
162
+ gridTemplate: string;
163
+ }): import("react/jsx-runtime").JSX.Element;
164
+ /** Scroll wrapper for the row stack — capped to fit the dashboard viewport. */
165
+ export declare function ModelTableBody({ children }: {
166
+ children: React.ReactNode;
167
+ }): import("react/jsx-runtime").JSX.Element;
168
+ /**
169
+ * Two-line model identity cell (model name + provider) shared by every
170
+ * per-model table. Kept as a stable named contract so callers don't restate
171
+ * the same two divs and font-utility classes.
172
+ */
173
+ export declare function ModelNameCell({ model, provider }: {
174
+ model: string;
175
+ provider: string;
176
+ }): import("react/jsx-runtime").JSX.Element;
177
+ /**
178
+ * One expandable model row. `cells` matches the column order from
179
+ * `ModelTableHeader` plus the trend cell at the end (caller controls the
180
+ * sparkline / placeholder). `expandedContent` is the panel revealed on toggle.
181
+ */
182
+ export declare function ExpandableModelRow({ gridTemplate, cells, trendCell, isExpanded, onToggle, expandedContent }: {
183
+ gridTemplate: string;
184
+ cells: React.ReactNode[];
185
+ trendCell: React.ReactNode;
186
+ isExpanded: boolean;
187
+ onToggle: () => void;
188
+ expandedContent: React.ReactNode;
189
+ }): import("react/jsx-runtime").JSX.Element;
190
+ /** Placeholder shown in the trend cell when a model has no time-series data. */
191
+ export declare function TrendEmpty(): import("react/jsx-runtime").JSX.Element;
192
+ /** Placeholder shown in the expanded detail-chart slot when data is missing. */
193
+ export declare function DetailChartEmpty({ message }: {
194
+ message?: string;
195
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ import "./styles.css";
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Client-side type definitions.
3
+ *
4
+ * Shared shapes (aggregations, time-series, dashboard payloads) live in
5
+ * `../shared-types` and are re-exported here. The types declared inline below
6
+ * are deliberately client-only because:
7
+ * - `Usage` is redeclared locally so the client bundle avoids importing
8
+ * `@oh-my-pi/pi-ai` (the server-side AI types package).
9
+ * - `MessageStats.stopReason` is widened from the server's `StopReason`
10
+ * enum to `string`, again to keep the client free of pi-ai types.
11
+ * - `TimeRange`, `OverviewStats`, `ModelDashboardStats`,
12
+ * `CostDashboardStats` are UI-only view shapes the server never produces.
13
+ */
14
+ import type { AggregatedStats, CostTimeSeriesPoint, ModelPerformancePoint, ModelStats, ModelTimeSeriesPoint, TimeSeriesPoint } from "../shared-types";
15
+ export * from "../shared-types";
16
+ export interface Usage {
17
+ input: number;
18
+ output: number;
19
+ cacheRead: number;
20
+ cacheWrite: number;
21
+ totalTokens: number;
22
+ premiumRequests?: number;
23
+ cost: {
24
+ input: number;
25
+ output: number;
26
+ cacheRead: number;
27
+ cacheWrite: number;
28
+ total: number;
29
+ };
30
+ }
31
+ export interface MessageStats {
32
+ id?: number;
33
+ sessionFile: string;
34
+ entryId: string;
35
+ folder: string;
36
+ model: string;
37
+ provider: string;
38
+ api: string;
39
+ timestamp: number;
40
+ duration: number | null;
41
+ ttft: number | null;
42
+ stopReason: string;
43
+ errorMessage: string | null;
44
+ usage: Usage;
45
+ }
46
+ export interface RequestDetails extends MessageStats {
47
+ messages: unknown[];
48
+ output: unknown;
49
+ }
50
+ export type TimeRange = "1h" | "24h" | "7d" | "30d" | "90d" | "all";
51
+ export interface OverviewStats {
52
+ overall: AggregatedStats;
53
+ timeSeries: TimeSeriesPoint[];
54
+ }
55
+ export interface ModelDashboardStats {
56
+ byModel: ModelStats[];
57
+ modelSeries: ModelTimeSeriesPoint[];
58
+ modelPerformanceSeries: ModelPerformancePoint[];
59
+ }
60
+ export interface CostDashboardStats {
61
+ costSeries: CostTimeSeriesPoint[];
62
+ }
@@ -0,0 +1,2 @@
1
+ export type SystemTheme = "light" | "dark";
2
+ export declare function useSystemTheme(): SystemTheme;