@linxiraos/pi-stats 1.1.8 → 1.1.9

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 (77) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/package.json +87 -94
  3. package/src/gain-aggregator.ts +1 -1
  4. package/src/index.ts +0 -0
  5. package/THIRD-PARTY-NOTICES.txt +0 -22909
  6. package/dist/client/index.css +0 -1
  7. package/dist/client/index.html +0 -24
  8. package/dist/client/index.js +0 -257
  9. package/dist/client/styles.css +0 -1956
  10. package/dist/types/aggregator.d.ts +0 -103
  11. package/dist/types/client/App.d.ts +0 -1
  12. package/dist/types/client/api.d.ts +0 -28
  13. package/dist/types/client/app/AppLayout.d.ts +0 -16
  14. package/dist/types/client/app/NavRail.d.ts +0 -7
  15. package/dist/types/client/app/RangeControl.d.ts +0 -7
  16. package/dist/types/client/app/SyncButton.d.ts +0 -14
  17. package/dist/types/client/app/ThemeToggle.d.ts +0 -1
  18. package/dist/types/client/app/TopBar.d.ts +0 -15
  19. package/dist/types/client/app/routes.d.ts +0 -12
  20. package/dist/types/client/components/AgentTokenShare.d.ts +0 -5
  21. package/dist/types/client/components/chart-shared.d.ts +0 -178
  22. package/dist/types/client/components/models-table-shared.d.ts +0 -175
  23. package/dist/types/client/components/range-meta.d.ts +0 -21
  24. package/dist/types/client/data/charts.d.ts +0 -1
  25. package/dist/types/client/data/formatters.d.ts +0 -13
  26. package/dist/types/client/data/useHashRoute.d.ts +0 -10
  27. package/dist/types/client/data/useResource.d.ts +0 -13
  28. package/dist/types/client/data/view-models.d.ts +0 -75
  29. package/dist/types/client/index.d.ts +0 -2
  30. package/dist/types/client/routes/BehaviorRoute.d.ts +0 -7
  31. package/dist/types/client/routes/CostsRoute.d.ts +0 -7
  32. package/dist/types/client/routes/ErrorsRoute.d.ts +0 -8
  33. package/dist/types/client/routes/GainRoute.d.ts +0 -7
  34. package/dist/types/client/routes/ModelsRoute.d.ts +0 -7
  35. package/dist/types/client/routes/OverviewRoute.d.ts +0 -8
  36. package/dist/types/client/routes/ProjectsRoute.d.ts +0 -7
  37. package/dist/types/client/routes/ProvidersRoute.d.ts +0 -7
  38. package/dist/types/client/routes/RequestsRoute.d.ts +0 -8
  39. package/dist/types/client/routes/ToolsRoute.d.ts +0 -7
  40. package/dist/types/client/routes/TracesRoute.d.ts +0 -11
  41. package/dist/types/client/routes/index.d.ts +0 -11
  42. package/dist/types/client/traces/AggregatesPanel.d.ts +0 -9
  43. package/dist/types/client/traces/Minimap.d.ts +0 -14
  44. package/dist/types/client/traces/SpanDrawer.d.ts +0 -14
  45. package/dist/types/client/traces/SummaryStrip.d.ts +0 -9
  46. package/dist/types/client/traces/TimelineCanvas.d.ts +0 -25
  47. package/dist/types/client/traces/TraceView.d.ts +0 -11
  48. package/dist/types/client/traces/TranscriptList.d.ts +0 -24
  49. package/dist/types/client/traces/time-scale.d.ts +0 -40
  50. package/dist/types/client/traces/trace-colors.d.ts +0 -31
  51. package/dist/types/client/types.d.ts +0 -63
  52. package/dist/types/client/ui/AsyncBoundary.d.ts +0 -12
  53. package/dist/types/client/ui/DataTable.d.ts +0 -17
  54. package/dist/types/client/ui/EmptyState.d.ts +0 -7
  55. package/dist/types/client/ui/ErrorState.d.ts +0 -6
  56. package/dist/types/client/ui/JsonBlock.d.ts +0 -7
  57. package/dist/types/client/ui/MetricCluster.d.ts +0 -5
  58. package/dist/types/client/ui/Panel.d.ts +0 -7
  59. package/dist/types/client/ui/RequestDrawer.d.ts +0 -5
  60. package/dist/types/client/ui/SegmentedControl.d.ts +0 -12
  61. package/dist/types/client/ui/Skeleton.d.ts +0 -8
  62. package/dist/types/client/ui/StatusPill.d.ts +0 -7
  63. package/dist/types/client/ui/index.d.ts +0 -11
  64. package/dist/types/client/useSystemTheme.d.ts +0 -11
  65. package/dist/types/db.d.ts +0 -183
  66. package/dist/types/embedded-client.d.ts +0 -18
  67. package/dist/types/gain-aggregator.d.ts +0 -26
  68. package/dist/types/index.d.ts +0 -17
  69. package/dist/types/parser.d.ts +0 -61
  70. package/dist/types/port-conflict.d.ts +0 -16
  71. package/dist/types/server.d.ts +0 -15
  72. package/dist/types/shared-types.d.ts +0 -551
  73. package/dist/types/sync-worker.d.ts +0 -31
  74. package/dist/types/trace.d.ts +0 -33
  75. package/dist/types/types.d.ts +0 -198
  76. package/dist/types/usage-windows.d.ts +0 -72
  77. package/dist/types/user-metrics.d.ts +0 -81
@@ -1,183 +0,0 @@
1
- import { Database } from "bun:sqlite";
2
- import type { AgentTypeStats, AggregatedStats, BehaviorModelStats, BehaviorOverallStats, BehaviorTimeSeriesPoint, CostTimeSeriesPoint, DailyActivityPoint, FolderStats, MessageStats, ModelPerformancePoint, ModelStats, ModelTimeSeriesPoint, ProviderAggregate, ProviderHourlyPoint, ProviderTimeSeriesPoint, TimeSeriesPoint, ToolCallStats, ToolModelStats, ToolResultLink, ToolTimeSeriesPoint, ToolUsageStats, UserMessageLink, UserMessageStats } from "./types.js";
3
- /**
4
- * Initialize the database and create tables.
5
- */
6
- export declare function initDb(): Promise<Database>;
7
- /**
8
- * Get the stored offset for a session file.
9
- */
10
- export declare function getFileOffset(sessionFile: string): {
11
- offset: number;
12
- lastModified: number;
13
- } | null;
14
- /**
15
- * Update the stored offset for a session file.
16
- */
17
- export declare function setFileOffset(sessionFile: string, offset: number, lastModified: number): void;
18
- /**
19
- * Insert message stats into the database.
20
- *
21
- * Forked / branched sessions (see `SessionManager.fork()` and
22
- * `createBranchedSession()` in `@linxiraos/zeta`) deep-copy a parent
23
- * session's entries into a new JSONL — same `entry_id`, `timestamp`, `model`,
24
- * `provider`, token counts, and `responseId`. The `UNIQUE(session_file,
25
- * entry_id)` constraint alone keys each row by file, so without the guard
26
- * below the same provider request would land twice and inflate every
27
- * aggregate. The `WHERE NOT EXISTS` clause skips inserts whose
28
- * `(entry_id, timestamp)` already exists under a different `session_file` —
29
- * first-write-wins across the lineage. Same-file re-syncs still hit the
30
- * `ON CONFLICT(session_file, entry_id)` upsert below, which re-derives the
31
- * stored cost (orchestration-aware) and keeps `premium_requests` monotonic, so
32
- * a forced re-parse repairs historical `premium_requests` and cost fix-ups.
33
- */
34
- export declare function insertMessageStats(stats: MessageStats[]): number;
35
- /**
36
- * Get overall aggregated stats.
37
- */
38
- export declare function getOverallStats(cutoff?: number): AggregatedStats;
39
- /**
40
- * Get stats grouped by model.
41
- */
42
- export declare function getStatsByModel(cutoff?: number): ModelStats[];
43
- /**
44
- * Get stats grouped by folder.
45
- */
46
- export declare function getStatsByFolder(cutoff?: number): FolderStats[];
47
- /**
48
- * Get token usage grouped by agent type (main agent, task subagents, advisor).
49
- * Token columns are explicit so the dashboard's share denominator matches the
50
- * counts it renders. Rows missing `agent_type` (defensive) fall back to "main".
51
- */
52
- export declare function getStatsByAgentType(cutoff?: number): AgentTypeStats[];
53
- /**
54
- * Get time series data.
55
- */
56
- export declare function getTimeSeries(hours?: number, cutoff?: number | null, bucketMs?: number): TimeSeriesPoint[];
57
- /**
58
- * Get daily performance time series data for the last N days.
59
- */
60
- /**
61
- * Get daily model usage time series data for the last N days.
62
- */
63
- export declare function getModelTimeSeries(days?: number, cutoff?: number | null, bucketMs?: number): ModelTimeSeriesPoint[];
64
- /**
65
- * Get request/token/cost totals grouped by provider.
66
- */
67
- export declare function getStatsByProvider(cutoff?: number | null): ProviderAggregate[];
68
- /**
69
- * Get token burn grouped by provider and local hour of day (0-23).
70
- * Hours use the server's timezone — the dashboard is a localhost tool, so
71
- * server-local and viewer-local time coincide.
72
- */
73
- export declare function getProviderHourlyBurn(cutoff?: number | null): ProviderHourlyPoint[];
74
- /**
75
- * Get token/cost time series grouped by provider (bucketed like the model series).
76
- */
77
- export declare function getProviderTimeSeries(days?: number, cutoff?: number | null, bucketMs?: number): ProviderTimeSeriesPoint[];
78
- /**
79
- * Get daily model performance time series data for the last N days.
80
- */
81
- export declare function getModelPerformanceSeries(days?: number, cutoff?: number | null, bucketMs?: number): ModelPerformancePoint[];
82
- /**
83
- * Get total message count.
84
- */
85
- export declare function getMessageCount(): number;
86
- /**
87
- * Close the database connection.
88
- */
89
- export declare function closeDb(): void;
90
- export declare function getRecentRequests(limit?: number): MessageStats[];
91
- export declare function getRecentErrors(limit?: number, cutoff?: number | null): MessageStats[];
92
- export declare function getMessageById(id: number): MessageStats | null;
93
- /** Per-transcript-file rollup for the Traces session list. */
94
- export interface SessionRollupRow {
95
- sessionFile: string;
96
- requests: number;
97
- startedAt: number;
98
- endedAt: number;
99
- totalTokens: number;
100
- costTotal: number;
101
- /** Comma-joined DISTINCT models. */
102
- models: string;
103
- }
104
- /** Aggregate every synced transcript file into one row (subagents unfolded). */
105
- export declare function getSessionRollups(): SessionRollupRow[];
106
- /** Tool-call counts keyed by transcript file, for the Traces session list. */
107
- export declare function getToolCallCountsBySession(): Map<string, number>;
108
- /**
109
- * Get daily cost time series data for the last N days, broken down by model.
110
- */
111
- export declare function getCostTimeSeries(days?: number, cutoff?: number | null): CostTimeSeriesPoint[];
112
- /**
113
- * Per-local-day activity aggregates for the last `days` days, oldest first.
114
- * Self-initializing (opens the stats DB on first use) so the coding-agent TUI
115
- * can query without the dashboard server's init flow. Days use the machine's
116
- * timezone — this is a localhost tool, same rationale as
117
- * {@link getProviderHourlyBurn}.
118
- */
119
- export declare function getDailyActivity(days?: number): Promise<DailyActivityPoint[]>;
120
- /**
121
- * Settle every full-session backfill after a successful sync pass.
122
- */
123
- export declare function markSessionBackfillsComplete(): void;
124
- /**
125
- * Insert user-message stats. Idempotent via UNIQUE(session_file, entry_id).
126
- * The `WHERE NOT EXISTS` clause matches {@link insertMessageStats}: forks
127
- * copy user entries verbatim into the child JSONL, so the same
128
- * `(entry_id, timestamp)` must not land twice across different session files.
129
- */
130
- export declare function insertUserMessageStats(stats: UserMessageStats[]): number;
131
- /**
132
- * Backfill the responding `model`/`provider` on user-message rows that were
133
- * persisted before their assistant reply was parsed (a side effect of
134
- * incremental `fromOffset` syncing: the `userByEntryId` map in
135
- * `parseSessionFile` only spans a single pass). Each row is updated at most
136
- * once because the `model IS NULL` guard short-circuits subsequent passes.
137
- *
138
- * Returns the number of rows actually updated.
139
- */
140
- export declare function updateUserMessageLinks(links: UserMessageLink[]): number;
141
- /**
142
- * Daily behavioral time series, grouped by responding model+provider.
143
- */
144
- export declare function getBehaviorTimeSeries(cutoff?: number | null): BehaviorTimeSeriesPoint[];
145
- /**
146
- * Overall behavioral totals across the cutoff window.
147
- */
148
- export declare function getBehaviorOverall(cutoff?: number | null): BehaviorOverallStats;
149
- /**
150
- * Per-model behavioral totals over the cutoff window. "Unknown" represents
151
- * user messages that never received an assistant reply.
152
- */
153
- export declare function getBehaviorByModel(cutoff?: number | null): BehaviorModelStats[];
154
- /**
155
- * Insert tool-call rows. Idempotent via UNIQUE(session_file, tool_call_id);
156
- * the `WHERE NOT EXISTS` guard mirrors {@link insertMessageStats}: forked
157
- * sessions deep-copy assistant entries (same `entry_id`, `timestamp`, and
158
- * tool-call ids under a new file), so first-write-wins across the lineage
159
- * keeps aggregates from double counting. Keyed on the assistant entry
160
- * identity, not the call id alone — provider call ids are not a global
161
- * namespace across unrelated sessions.
162
- */
163
- export declare function insertToolCalls(calls: ToolCallStats[]): number;
164
- /**
165
- * Attach result size / error flag to persisted tool-call rows. Results can
166
- * land in a later incremental sync pass than the call that produced them, so
167
- * this is an UPDATE keyed by (session_file, tool_call_id). The `IS NULL`
168
- * guard makes re-syncs idempotent; rows skipped by the fork guard simply
169
- * never match.
170
- */
171
- export declare function updateToolResults(links: ToolResultLink[]): number;
172
- /**
173
- * Get tool usage aggregated by tool name.
174
- */
175
- export declare function getToolStats(cutoff?: number): ToolUsageStats[];
176
- /**
177
- * Get tool usage aggregated by (tool, model, provider).
178
- */
179
- export declare function getToolStatsByModel(cutoff?: number): ToolModelStats[];
180
- /**
181
- * Get tool-call time series (one point per bucket per tool).
182
- */
183
- export declare function getToolTimeSeries(days?: number, cutoff?: number | null, bucketMs?: number): ToolTimeSeriesPoint[];
@@ -1,18 +0,0 @@
1
- /**
2
- * Embedded stats dashboard archive handling.
3
- *
4
- * `embedded-client.generated.txt` holds the base64 of a gzipped tar of the
5
- * built dashboard (`dist/client`). It is populated by
6
- * `gen:stats` for compiled binaries and the
7
- * prepacked npm bundle, and reset to an empty file afterwards so the dev tree
8
- * keeps building the dashboard from source.
9
- */
10
- /**
11
- * Decode the generated archive text.
12
- *
13
- * Returns `null` when the content is blank or not a raw gzip archive encoded as
14
- * base64 — notably the legacy placeholder that contained a TypeScript
15
- * `export const … = "";` stub, which must be treated as "no archive embedded"
16
- * rather than decoded into garbage bytes.
17
- */
18
- export declare function decodeEmbeddedClientArchive(txt: string): Buffer | null;
@@ -1,26 +0,0 @@
1
- /**
2
- * Aggregates token-savings data for the Gain dashboard.
3
- *
4
- * Source:
5
- * 1. Snapcompact: colocated with stats.db as snapcompact-savings.jsonl
6
- *
7
- * Missing files are treated as zero records — never an error.
8
- */
9
- import type { GainDashboardStats } from "./shared-types.js";
10
- /**
11
- * Collapse conventional worktree sub-paths to their logical project root.
12
- *
13
- * Rules are generic: omp internal wt paths are dropped; conventional worktree
14
- * suffixes (`.wt/`, `-wt/`, `.worktrees/`, `-worktrees/`) are stripped. No
15
- * author-specific IDE or tool paths are baked in.
16
- *
17
- * Returns null to drop temp/internal paths entirely.
18
- */
19
- export declare function normalizeProjectPath(p: string): string | null;
20
- /**
21
- * Given a raw set of paths, normalize worktree paths and remove sub-paths
22
- * that are already covered by a shorter parent at depth ≥ 4.
23
- * Returns a sorted, deduped list of meaningful project roots.
24
- */
25
- export declare function dedupeProjects(rawPaths: Set<string>): string[];
26
- export declare function getGainDashboardStats(range?: string | null, project?: string | null): Promise<GainDashboardStats>;
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env bun
2
- export { getDashboardStats, getToolDashboardStats, getTotalMessageCount, type SyncOptions, type SyncProgress, smokeTestSyncWorker, syncAllSessions, } from "./aggregator.js";
3
- export { closeDb } from "./db.js";
4
- export { getGainDashboardStats } from "./gain-aggregator.js";
5
- export { formatStatsDashboardUrl, startServer } from "./server.js";
6
- export type { GainDashboardStats, GainSource, GainSourceTotals, GainTimeSeriesPoint } from "./shared-types.js";
7
- export type { AggregatedStats, DashboardStats, FolderStats, MessageStats, ModelPerformancePoint, ModelStats, ModelTimeSeriesPoint, TimeSeriesPoint, ToolDashboardStats, ToolModelStats, ToolTimeSeriesPoint, ToolUsageStats, } from "./types.js";
8
- /** Parsed arguments for the standalone `omp-stats` entry point. */
9
- export interface StandaloneStatsArgs {
10
- port: number;
11
- host: string;
12
- json: boolean;
13
- sync: boolean;
14
- help: boolean;
15
- }
16
- /** Parse the standalone `omp-stats` arguments used by the production entry point. */
17
- export declare function parseStandaloneStatsArgs(args: string[]): StandaloneStatsArgs;
@@ -1,61 +0,0 @@
1
- import type { AgentType, MessageStats, SessionEntry, ToolCallStats, ToolResultLink, UserMessageLink, UserMessageStats } from "./types.js";
2
- /**
3
- * Classify which agent produced a transcript from its path within the sessions
4
- * directory. Layout: `<sessionsDir>/<project>/<file>.jsonl` is the `main`
5
- * agent; subagent and advisor transcripts live nested one level deeper inside
6
- * the session's artifacts dir (`<project>/<session>/<id>.jsonl`,
7
- * `<project>/<session>/__advisor.jsonl`). Any advisor transcript
8
- * (`__advisor.jsonl` or `__advisor.<slug>.jsonl`) — at any depth, including a
9
- * subagent's own advisor — counts as `advisor`; every other nested transcript
10
- * is a task `subagent`.
11
- */
12
- export declare function classifyAgentType(sessionPath: string): AgentType;
13
- /**
14
- * Extract folder name from session filename.
15
- * Session files are named like: --work--pi--/timestamp_uuid.jsonl
16
- * The folder part uses -- as path separator.
17
- */
18
- export declare function extractFolderFromPath(sessionPath: string): string;
19
- /** Parse every well-formed entry in a transcript buffer (malformed lines skipped). */
20
- export declare function parseAllSessionEntries(bytes: Uint8Array): SessionEntry[];
21
- /**
22
- * Parse a session file and extract all assistant message stats.
23
- * Uses incremental reading with offset tracking.
24
- *
25
- * Service-tier carry-over: `currentServiceTier` is a session-scoped piece of
26
- * state derived from `service_tier_change` entries that affects whether
27
- * subsequent OpenAI assistant replies count as premium requests. Incremental
28
- * syncs that resume past the most-recent tier change would otherwise lose
29
- * that state and silently record `premiumRequests = 0` for priority traffic
30
- * (the coding-agent stopped folding the tier into `usage.premiumRequests`
31
- * after 13f59162e — the parser is now the sole source of truth). When
32
- * `fromOffset > 0` we therefore scan the bytes preceding `fromOffset`
33
- * for the latest service-tier value before parsing the unprocessed tail.
34
- * The scan only keeps the current tier and does not materialize prefix
35
- * entries, preserving offset-based memory behavior for large sessions.
36
- */
37
- export interface ParseSessionResult {
38
- stats: MessageStats[];
39
- userStats: UserMessageStats[];
40
- userLinks: UserMessageLink[];
41
- toolCalls: ToolCallStats[];
42
- toolResults: ToolResultLink[];
43
- newOffset: number;
44
- }
45
- export declare function parseSessionFile(sessionPath: string, fromOffset?: number): Promise<ParseSessionResult>;
46
- /**
47
- * List all session directories (folders).
48
- */
49
- export declare function listSessionFolders(): Promise<string[]>;
50
- /**
51
- * List all session files in a folder.
52
- */
53
- export declare function listSessionFiles(folderPath: string): Promise<string[]>;
54
- /**
55
- * List all session files across all folders.
56
- */
57
- export declare function listAllSessionFiles(): Promise<string[]>;
58
- /**
59
- * Find a specific entry in a session file.
60
- */
61
- export declare function getSessionEntry(sessionPath: string, entryId: string): Promise<SessionEntry | null>;
@@ -1,16 +0,0 @@
1
- /** Header stamped on every dashboard response so reuse probes can identify us. */
2
- export declare const STATS_DASHBOARD_HEADER = "x-omp-stats-dashboard";
3
- /** Header recording the server's requested bind host so reuse cannot change its exposure scope. */
4
- export declare const STATS_DASHBOARD_HOSTNAME_HEADER = "x-omp-stats-hostname";
5
- /** Identity-header value for dashboards enforcing an explicit bind host and same-origin access. */
6
- export declare const STATS_DASHBOARD_SECURITY_VERSION = "3";
7
- /** IPv4 loopback address shared by the dashboard server and reuse probe. */
8
- export declare const STATS_DASHBOARD_HOSTNAME = "127.0.0.1";
9
- /**
10
- * Reuse a secure dashboard or reclaim an insecure HTTP dashboard before binding.
11
- * The preflight is needed on platforms that permit wildcard and loopback-specific
12
- * listeners to coexist on one port.
13
- */
14
- export declare function prepareStatsPort(port: number, hostname?: string): Promise<"retry" | "reuse">;
15
- /** Reuse or reclaim a listener found after the server bind reports EADDRINUSE. */
16
- export declare function recoverStatsPort(port: number, hostname?: string): Promise<"retry" | "reuse">;
@@ -1,15 +0,0 @@
1
- /**
2
- * Handle API requests.
3
- */
4
- export declare function handleApi(req: Request): Promise<Response>;
5
- /** Format a dashboard origin, including brackets required by IPv6 literals. */
6
- export declare function formatStatsDashboardUrl(hostname: string, port: number): string;
7
- /**
8
- * Start the HTTP server, reusing a live dashboard or reclaiming a stale omp listener.
9
- */
10
- export interface StatsServerHandle {
11
- hostname: string;
12
- port: number;
13
- stop: () => void;
14
- }
15
- export declare function startServer(port?: number, hostname?: string): Promise<StatsServerHandle>;