sidekick-shared 0.25.0 → 0.26.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 (116) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +49 -3
  3. package/dist/accountChanges.js +22 -3
  4. package/dist/accountRegistry.d.ts +22 -1
  5. package/dist/accountRegistry.js +37 -14
  6. package/dist/accountStatus.d.ts +9 -1
  7. package/dist/accountStatus.js +3 -3
  8. package/dist/accounts.d.ts +3 -1
  9. package/dist/accounts.js +84 -64
  10. package/dist/aggregation/EventAggregator.d.ts +15 -2
  11. package/dist/aggregation/EventAggregator.js +54 -9
  12. package/dist/aggregation/costProvenance.d.ts +14 -0
  13. package/dist/aggregation/costProvenance.js +35 -0
  14. package/dist/aggregation/snapshot.d.ts +13 -2
  15. package/dist/aggregation/snapshot.js +57 -6
  16. package/dist/aggregation/types.d.ts +30 -1
  17. package/dist/analytics/compactionLedger.js +15 -5
  18. package/dist/analytics/qualityScore.js +2 -1
  19. package/dist/browser.d.ts +11 -1
  20. package/dist/browser.js +29 -1
  21. package/dist/codexProfiles.d.ts +3 -1
  22. package/dist/codexProfiles.js +4 -2
  23. package/dist/codexQuota.d.ts +2 -0
  24. package/dist/codexQuota.js +11 -66
  25. package/dist/failingTools.d.ts +37 -0
  26. package/dist/failingTools.js +70 -0
  27. package/dist/formatters/sessionDump.js +13 -7
  28. package/dist/formatting.d.ts +13 -0
  29. package/dist/formatting.js +35 -0
  30. package/dist/historicalStore.d.ts +47 -0
  31. package/dist/historicalStore.js +312 -0
  32. package/dist/index.d.ts +46 -12
  33. package/dist/index.js +112 -24
  34. package/dist/node.d.ts +19 -0
  35. package/dist/node.js +47 -1
  36. package/dist/observedContextWindows.d.ts +7 -0
  37. package/dist/observedContextWindows.js +17 -2
  38. package/dist/observedSessionCollector.d.ts +3 -8
  39. package/dist/observedSessionCollector.js +10 -27
  40. package/dist/parsers/sessionActivityDetector.d.ts +24 -2
  41. package/dist/parsers/sessionActivityDetector.js +95 -17
  42. package/dist/parsers/sessionPathResolver.d.ts +11 -0
  43. package/dist/parsers/sessionPathResolver.js +13 -10
  44. package/dist/peakHours.d.ts +34 -3
  45. package/dist/peakHours.js +92 -7
  46. package/dist/pricingCatalog.d.ts +7 -0
  47. package/dist/pricingCatalog.js +8 -5
  48. package/dist/providers/claudeCode.js +11 -96
  49. package/dist/providers/codex.d.ts +2 -0
  50. package/dist/providers/codex.js +94 -259
  51. package/dist/providers/detect.d.ts +2 -0
  52. package/dist/providers/detect.js +29 -24
  53. package/dist/providers/factory.d.ts +6 -0
  54. package/dist/providers/openCode.d.ts +2 -0
  55. package/dist/providers/openCode.js +105 -121
  56. package/dist/providers/rolloutWalker.d.ts +53 -0
  57. package/dist/providers/rolloutWalker.js +209 -0
  58. package/dist/providers/types.d.ts +30 -0
  59. package/dist/quota.d.ts +30 -3
  60. package/dist/quota.js +35 -3
  61. package/dist/quotaHistory.d.ts +1 -1
  62. package/dist/quotaHistory.js +36 -35
  63. package/dist/quotaResolver.d.ts +81 -0
  64. package/dist/quotaResolver.js +213 -0
  65. package/dist/quotaSnapshots.d.ts +15 -2
  66. package/dist/quotaSnapshots.js +25 -3
  67. package/dist/quotaThresholds.d.ts +60 -0
  68. package/dist/quotaThresholds.js +90 -0
  69. package/dist/report/htmlReportGenerator.js +10 -4
  70. package/dist/report/sessionReportInputs.d.ts +23 -0
  71. package/dist/report/sessionReportInputs.js +34 -0
  72. package/dist/schemas/index.d.ts +2 -0
  73. package/dist/schemas/index.js +10 -1
  74. package/dist/schemas/quota.d.ts +139 -0
  75. package/dist/schemas/quota.js +17 -2
  76. package/dist/schemas/quotaHistory.d.ts +1 -0
  77. package/dist/schemas/quotaHistory.js +1 -1
  78. package/dist/schemas/sessionEvent.d.ts +6 -0
  79. package/dist/schemas/sessionEvent.js +1 -0
  80. package/dist/schemas/stateFile.d.ts +198 -0
  81. package/dist/schemas/stateFile.js +77 -0
  82. package/dist/schemas/transcript.js +2 -0
  83. package/dist/sessionFingerprint.d.ts +25 -0
  84. package/dist/sessionFingerprint.js +46 -0
  85. package/dist/sessionPreviews.d.ts +7 -1
  86. package/dist/sessionPreviews.js +15 -3
  87. package/dist/sessionStats.d.ts +51 -0
  88. package/dist/sessionStats.js +166 -0
  89. package/dist/stateFile.d.ts +113 -0
  90. package/dist/stateFile.js +160 -0
  91. package/dist/statusline/claudeStatuslinePayload.d.ts +89 -0
  92. package/dist/statusline/claudeStatuslinePayload.js +152 -0
  93. package/dist/statusline/formatter.d.ts +13 -0
  94. package/dist/statusline/formatter.js +48 -6
  95. package/dist/statusline/index.d.ts +10 -2
  96. package/dist/statusline/index.js +19 -1
  97. package/dist/tokenSummary.d.ts +62 -0
  98. package/dist/tokenSummary.js +72 -0
  99. package/dist/transcript.d.ts +5 -0
  100. package/dist/transcript.js +2 -0
  101. package/dist/types/observedSessionV1.d.ts +2 -0
  102. package/dist/types/observedSessionV1.js +75 -18
  103. package/dist/types/sessionEvent.d.ts +2 -0
  104. package/dist/usage/billingBlocks.d.ts +85 -0
  105. package/dist/usage/billingBlocks.js +153 -0
  106. package/dist/usage/importSessionHistory.d.ts +53 -0
  107. package/dist/usage/importSessionHistory.js +88 -0
  108. package/dist/usage/usageEvents.d.ts +92 -0
  109. package/dist/usage/usageEvents.js +322 -0
  110. package/dist/usage/usageReports.d.ts +76 -0
  111. package/dist/usage/usageReports.js +208 -0
  112. package/dist/watchers/factory.d.ts +6 -0
  113. package/dist/watchers/factory.js +30 -25
  114. package/dist/zaiQuotaApi.d.ts +2 -0
  115. package/dist/zaiQuotaApi.js +2 -0
  116. package/package.json +1 -1
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ /**
3
+ * Pure mutations of the `historical-data.json` store.
4
+ *
5
+ * Ported verbatim from the VS Code extension's HistoricalDataService so the
6
+ * CLI importer and the extension apply session summaries the same way:
7
+ * a session's previous contribution is subtracted before the new one is
8
+ * added (idempotent replacement), daily, hourly, monthly, and all-time
9
+ * buckets are updated together, and the per-session record list is capped
10
+ * at `HISTORICAL_SESSION_RETENTION_LIMIT`. Browser-safe: no Node imports.
11
+ *
12
+ * @module historicalStore
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.removeSessionSummary = removeSessionSummary;
16
+ exports.applySessionSummary = applySessionSummary;
17
+ exports.isFileImported = isFileImported;
18
+ exports.markFileImported = markFileImported;
19
+ exports.sessionSummaryFromStats = sessionSummaryFromStats;
20
+ const formatting_1 = require("./formatting");
21
+ const historicalData_1 = require("./types/historicalData");
22
+ function mergeModelUsage(existing, incoming) {
23
+ const map = new Map();
24
+ for (const record of existing)
25
+ map.set(record.model, { ...record });
26
+ for (const record of incoming) {
27
+ const current = map.get(record.model);
28
+ if (current) {
29
+ current.calls += record.calls;
30
+ current.tokens += record.tokens;
31
+ current.cost += record.cost;
32
+ // Unpriced taints: if either side was unpriced, the merged row is too.
33
+ // Legacy v1 records (priced === undefined) are assumed priced.
34
+ if (record.priced === false || current.priced === false)
35
+ current.priced = false;
36
+ }
37
+ else {
38
+ map.set(record.model, { ...record });
39
+ }
40
+ }
41
+ return Array.from(map.values());
42
+ }
43
+ function mergeToolUsage(existing, incoming) {
44
+ const map = new Map();
45
+ for (const record of existing)
46
+ map.set(record.tool, { ...record });
47
+ for (const record of incoming) {
48
+ const current = map.get(record.tool);
49
+ if (current) {
50
+ current.calls += record.calls;
51
+ current.successCount += record.successCount;
52
+ current.failureCount += record.failureCount;
53
+ }
54
+ else {
55
+ map.set(record.tool, { ...record });
56
+ }
57
+ }
58
+ return Array.from(map.values());
59
+ }
60
+ function subtractTokenTotals(target, contribution) {
61
+ target.inputTokens = Math.max(0, target.inputTokens - contribution.inputTokens);
62
+ target.outputTokens = Math.max(0, target.outputTokens - contribution.outputTokens);
63
+ target.cacheWriteTokens = Math.max(0, target.cacheWriteTokens - contribution.cacheWriteTokens);
64
+ target.cacheReadTokens = Math.max(0, target.cacheReadTokens - contribution.cacheReadTokens);
65
+ }
66
+ function subtractModelUsage(existing, outgoing) {
67
+ const map = new Map(existing.map((record) => [record.model, { ...record }]));
68
+ for (const record of outgoing) {
69
+ const current = map.get(record.model);
70
+ if (!current)
71
+ continue;
72
+ current.calls = Math.max(0, current.calls - record.calls);
73
+ current.tokens = Math.max(0, current.tokens - record.tokens);
74
+ current.cost = Math.max(0, current.cost - record.cost);
75
+ if (current.calls === 0 && current.tokens === 0)
76
+ map.delete(record.model);
77
+ }
78
+ return [...map.values()];
79
+ }
80
+ function subtractToolUsage(existing, outgoing) {
81
+ const map = new Map(existing.map((record) => [record.tool, { ...record }]));
82
+ for (const record of outgoing) {
83
+ const current = map.get(record.tool);
84
+ if (!current)
85
+ continue;
86
+ current.calls = Math.max(0, current.calls - record.calls);
87
+ current.successCount = Math.max(0, current.successCount - record.successCount);
88
+ current.failureCount = Math.max(0, current.failureCount - record.failureCount);
89
+ if (current.calls === 0)
90
+ map.delete(record.tool);
91
+ }
92
+ return [...map.values()];
93
+ }
94
+ function subtractSummary(bucket, summary, now) {
95
+ subtractTokenTotals(bucket.tokens, summary.tokens);
96
+ bucket.totalCost = Math.max(0, bucket.totalCost - summary.totalCost);
97
+ bucket.messageCount = Math.max(0, bucket.messageCount - summary.messageCount);
98
+ bucket.sessionCount = Math.max(0, bucket.sessionCount - 1);
99
+ bucket.modelUsage = subtractModelUsage(bucket.modelUsage, summary.modelUsage);
100
+ bucket.toolUsage = subtractToolUsage(bucket.toolUsage, summary.toolUsage);
101
+ bucket.updatedAt = now.toISOString();
102
+ }
103
+ function accumulateSummary(bucket, summary, now) {
104
+ bucket.tokens.inputTokens += summary.tokens.inputTokens;
105
+ bucket.tokens.outputTokens += summary.tokens.outputTokens;
106
+ bucket.tokens.cacheWriteTokens += summary.tokens.cacheWriteTokens;
107
+ bucket.tokens.cacheReadTokens += summary.tokens.cacheReadTokens;
108
+ bucket.totalCost += summary.totalCost;
109
+ bucket.messageCount += summary.messageCount;
110
+ bucket.sessionCount += 1;
111
+ bucket.modelUsage = mergeModelUsage(bucket.modelUsage, summary.modelUsage);
112
+ bucket.toolUsage = mergeToolUsage(bucket.toolUsage, summary.toolUsage);
113
+ bucket.updatedAt = now.toISOString();
114
+ }
115
+ function emptyDaily(date, now) {
116
+ return {
117
+ date,
118
+ tokens: (0, historicalData_1.createEmptyTokenTotals)(),
119
+ totalCost: 0,
120
+ messageCount: 0,
121
+ sessionCount: 0,
122
+ modelUsage: [],
123
+ toolUsage: [],
124
+ updatedAt: now.toISOString(),
125
+ };
126
+ }
127
+ function emptyMonthly(month, now) {
128
+ return {
129
+ month,
130
+ tokens: (0, historicalData_1.createEmptyTokenTotals)(),
131
+ totalCost: 0,
132
+ messageCount: 0,
133
+ sessionCount: 0,
134
+ modelUsage: [],
135
+ toolUsage: [],
136
+ updatedAt: now.toISOString(),
137
+ };
138
+ }
139
+ function refreshAllTimeDateRange(store) {
140
+ const dates = Object.keys(store.daily).sort();
141
+ store.allTime.firstDate = dates[0] ?? '';
142
+ store.allTime.lastDate = dates[dates.length - 1] ?? '';
143
+ }
144
+ /** Subtract a previously saved session's contribution from every bucket. */
145
+ function removeSessionSummary(store, record, now = new Date()) {
146
+ const summary = {
147
+ sessionId: record.sessionId,
148
+ startTime: record.startTime,
149
+ endTime: record.endTime,
150
+ tokens: { ...record.tokens },
151
+ totalCost: record.totalCost,
152
+ messageCount: record.messageCount,
153
+ modelUsage: record.modelUsage?.map((usage) => ({ ...usage })) ?? [],
154
+ toolUsage: record.toolUsage?.map((usage) => ({ ...usage })) ?? [],
155
+ unpricedModelIds: record.unpricedModelIds ? [...record.unpricedModelIds] : undefined,
156
+ };
157
+ const date = (0, formatting_1.formatLocalDateKey)(new Date(record.startTime));
158
+ const month = date.substring(0, 7);
159
+ const daily = store.daily[date];
160
+ if (daily) {
161
+ subtractSummary(daily, summary, now);
162
+ if (daily.sessionCount === 0)
163
+ delete store.daily[date];
164
+ }
165
+ const hourly = store.hourly?.[date];
166
+ if (hourly && store.hourly) {
167
+ const hour = new Date(record.startTime).getHours();
168
+ const bucket = hourly.find((entry) => entry.hour === hour);
169
+ if (bucket) {
170
+ subtractTokenTotals(bucket.tokens, summary.tokens);
171
+ bucket.totalCost = Math.max(0, bucket.totalCost - summary.totalCost);
172
+ bucket.messageCount = Math.max(0, bucket.messageCount - summary.messageCount);
173
+ bucket.sessionCount = Math.max(0, bucket.sessionCount - 1);
174
+ }
175
+ store.hourly[date] = hourly.filter((entry) => entry.sessionCount > 0);
176
+ if (store.hourly[date].length === 0)
177
+ delete store.hourly[date];
178
+ }
179
+ const monthly = store.monthly[month];
180
+ if (monthly) {
181
+ subtractSummary(monthly, summary, now);
182
+ if (monthly.sessionCount === 0)
183
+ delete store.monthly[month];
184
+ }
185
+ subtractSummary(store.allTime, summary, now);
186
+ }
187
+ /**
188
+ * Apply a completed session to the daily, hourly, monthly, and all-time
189
+ * buckets and the capped per-session list. Re-applying the same session id
190
+ * replaces its earlier contribution instead of double counting it.
191
+ *
192
+ * Returns the stored per-session record.
193
+ */
194
+ function applySessionSummary(store, summary, options = {}) {
195
+ const now = options.now ?? new Date();
196
+ const retentionLimit = options.retentionLimit ?? historicalData_1.HISTORICAL_SESSION_RETENTION_LIMIT;
197
+ const date = (0, formatting_1.formatLocalDateKey)(new Date(summary.startTime));
198
+ const month = date.substring(0, 7);
199
+ store.sessions ??= [];
200
+ const previous = store.sessions.find((session) => session.sessionId === summary.sessionId);
201
+ if (previous)
202
+ removeSessionSummary(store, previous, now);
203
+ // Daily
204
+ store.daily[date] ??= emptyDaily(date, now);
205
+ accumulateSummary(store.daily[date], summary, now);
206
+ // Hourly (by the session's local start hour)
207
+ store.hourly ??= {};
208
+ store.hourly[date] ??= [];
209
+ const hour = new Date(summary.startTime).getHours();
210
+ let hourly = store.hourly[date].find((entry) => entry.hour === hour);
211
+ if (!hourly) {
212
+ hourly = {
213
+ hour,
214
+ tokens: (0, historicalData_1.createEmptyTokenTotals)(),
215
+ totalCost: 0,
216
+ messageCount: 0,
217
+ sessionCount: 0,
218
+ };
219
+ store.hourly[date].push(hourly);
220
+ }
221
+ hourly.tokens.inputTokens += summary.tokens.inputTokens;
222
+ hourly.tokens.outputTokens += summary.tokens.outputTokens;
223
+ hourly.tokens.cacheWriteTokens += summary.tokens.cacheWriteTokens;
224
+ hourly.tokens.cacheReadTokens += summary.tokens.cacheReadTokens;
225
+ hourly.totalCost += summary.totalCost;
226
+ hourly.messageCount += summary.messageCount;
227
+ hourly.sessionCount += 1;
228
+ // Monthly
229
+ store.monthly[month] ??= emptyMonthly(month, now);
230
+ accumulateSummary(store.monthly[month], summary, now);
231
+ // All-time
232
+ accumulateSummary(store.allTime, summary, now);
233
+ if (!store.allTime.firstDate || date < store.allTime.firstDate)
234
+ store.allTime.firstDate = date;
235
+ if (!store.allTime.lastDate || date > store.allTime.lastDate)
236
+ store.allTime.lastDate = date;
237
+ const record = {
238
+ sessionId: summary.sessionId,
239
+ provider: summary.provider ?? 'unknown',
240
+ project: summary.project ?? 'unknown',
241
+ startTime: summary.startTime,
242
+ endTime: summary.endTime,
243
+ tokens: { ...summary.tokens },
244
+ totalCost: summary.totalCost,
245
+ messageCount: summary.messageCount,
246
+ modelUsage: summary.modelUsage.map((usage) => ({ ...usage })),
247
+ toolUsage: summary.toolUsage.map((usage) => ({ ...usage })),
248
+ unpricedModelIds: summary.unpricedModelIds ? [...summary.unpricedModelIds] : undefined,
249
+ qualityScore: summary.qualityScore ?? 0,
250
+ qualityFactors: summary.qualityFactors ?? [],
251
+ additions: summary.additions ?? 0,
252
+ deletions: summary.deletions ?? 0,
253
+ costPerChangedLine: summary.costPerChangedLine ?? null,
254
+ };
255
+ store.sessions = [
256
+ ...store.sessions.filter((session) => session.sessionId !== summary.sessionId),
257
+ record,
258
+ ].slice(-retentionLimit);
259
+ refreshAllTimeDateRange(store);
260
+ return record;
261
+ }
262
+ /** Whether a session file has already been folded into the store. */
263
+ function isFileImported(store, filePath) {
264
+ return store.importedFiles?.includes(filePath) ?? false;
265
+ }
266
+ /** Record a session file as imported. Returns false when it was already listed. */
267
+ function markFileImported(store, filePath, now = new Date()) {
268
+ store.importedFiles ??= [];
269
+ if (store.importedFiles.includes(filePath))
270
+ return false;
271
+ store.importedFiles.push(filePath);
272
+ store.lastImportTimestamp = now.toISOString();
273
+ return true;
274
+ }
275
+ /**
276
+ * Build the summary the history store expects from unified session stats,
277
+ * so the CLI importer and the extension's first-activation import store the
278
+ * same per-model cost, tool success/failure split, and unpriced markers.
279
+ * Pending tool calls count as successes (stats only split out failures).
280
+ */
281
+ function sessionSummaryFromStats(stats, options = {}) {
282
+ const modelUsage = Object.entries(stats.modelUsage).map(([model, usage]) => ({
283
+ model,
284
+ calls: usage.calls,
285
+ tokens: usage.tokens,
286
+ cost: usage.costUsd,
287
+ priced: usage.priced,
288
+ }));
289
+ const unpricedModelIds = modelUsage.filter((m) => m.priced === false).map((m) => m.model);
290
+ const toolUsage = Object.entries(stats.toolUsage).map(([tool, calls]) => {
291
+ const failureCount = stats.toolFailures[tool] ?? 0;
292
+ return { tool, calls, successCount: Math.max(0, calls - failureCount), failureCount };
293
+ });
294
+ return {
295
+ sessionId: stats.sessionId,
296
+ startTime: stats.startTime,
297
+ endTime: stats.endTime || stats.startTime,
298
+ tokens: {
299
+ inputTokens: stats.tokens.input,
300
+ outputTokens: stats.tokens.output,
301
+ cacheWriteTokens: stats.tokens.cacheWrite,
302
+ cacheReadTokens: stats.tokens.cacheRead,
303
+ },
304
+ totalCost: stats.costUsd,
305
+ messageCount: stats.messageCount,
306
+ modelUsage,
307
+ toolUsage,
308
+ ...(unpricedModelIds.length > 0 ? { unpricedModelIds } : {}),
309
+ provider: options.provider ?? stats.providerId,
310
+ project: options.project ?? 'unknown',
311
+ };
312
+ }
package/dist/index.d.ts CHANGED
@@ -3,11 +3,30 @@
3
3
  */
4
4
  export { normalizeProviderUsage, extractNormalizedUsage, calculateNormalizedUsageCost, } from './usageNormalization';
5
5
  export type { UsageProvider, UsageSemantics, UsageNormalizationProvenance, ProviderUsageInput, AnthropicUsageInput, OpenAIUsageInput, SidekickUsageInput, NormalizedUsage, PricingProvenance, NormalizedUsageCostInput, NormalizedUsageCost, } from './usageNormalization';
6
+ export { summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
7
+ export type { TokenSummary, TokenTotalsLike } from './tokenSummary';
6
8
  export { estimateTextTokens, estimateSerializedTokens } from './tokenEstimation';
7
9
  export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod, TokenEstimationConfidence, TokenEstimationOptions, TokenEstimate, } from './tokenEstimation';
8
10
  export { projectSessionTranscript } from './transcript';
9
11
  export type { TranscriptFidelity, TranscriptSourceProvenance, CanonicalTranscriptBlock, CanonicalTranscriptMessage, CanonicalToolCall, CanonicalTranscriptUsageTotals, CanonicalSessionTranscript, ProjectSessionTranscriptOptions, } from './transcript';
10
12
  export { listRecentSessions, readSessionTranscript } from './sessionTranscripts';
13
+ export { computeSessionFileStats, firstUserPrompt, providerContextSizeFn, readSessionFileStats, } from './sessionStats';
14
+ export { readSessionReportInputs } from './report/sessionReportInputs';
15
+ export type { SessionReportInputs } from './report/sessionReportInputs';
16
+ export { fingerprintString, sessionFingerprintParts } from './sessionFingerprint';
17
+ export { STATE_FILE_NAME, STATE_FILE_SCHEMA_VERSION, billingBlockToStateFile, getStateFilePath, quotaToStateFile, readStateFile, writeStateFile, } from './stateFile';
18
+ export type { SidekickStateFile, SidekickStateInput, StateFileAccount, StateFileBillingBlock, StateFileContext, StateFileQuota, StateFileQuotaWindow, StateFileSession, StateFileWriter, WriteStateFileOptions, } from './stateFile';
19
+ export type { ComputeSessionFileStatsOptions, ReadSessionFileStatsOptions } from './sessionStats';
20
+ export { BILLING_BLOCK_DURATION_MS, computeBillingBlocks, findActiveBillingBlock, } from './usage/billingBlocks';
21
+ export type { BillingBlock, BillingBlockInput, BillingBlockModelUsage, BillingBlockTokens, ComputeBillingBlocksOptions, } from './usage/billingBlocks';
22
+ export { MAX_USAGE_CACHE_FILES, USAGE_CACHE_VERSION, collectUsageEvents, getUsageCacheDir, pruneUsageCache, } from './usage/usageEvents';
23
+ export type { CollectUsageEventsOptions, CollectUsageEventsResult, UsageEventRecord, UsageSessionRecord, } from './usage/usageEvents';
24
+ export { applySessionSummary, isFileImported, markFileImported, removeSessionSummary, sessionSummaryFromStats, } from './historicalStore';
25
+ export type { ApplySessionSummaryOptions, SessionSummaryFromStatsOptions } from './historicalStore';
26
+ export { ACTIVE_SESSION_MTIME_THRESHOLD_MS, importSessionHistory, } from './usage/importSessionHistory';
27
+ export type { ImportSessionHistoryOptions, ImportSessionHistoryResult, } from './usage/importSessionHistory';
28
+ export { bucketUsage, summarizeUsageRows, usageBucketKey, weekKey } from './usage/usageReports';
29
+ export type { BucketUsageOptions, UsageBucketRow, UsageGranularity, UsageGroupDimension, UsageTotals, } from './usage/usageReports';
11
30
  export type { ProviderSessionIndex, ListRecentSessionsOptions } from './sessionTranscripts';
12
31
  export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, fileFingerprintParts, } from './observedSessionCollector';
13
32
  export type { KnownObservedSessionFingerprint, ObservedSessionChange, ObservedSessionChangeBatch, ObservedSessionChangeType, ObservedSessionReference, ObservedSessionFingerprintParts, ObservedSessionSourceSubscribeOptions, ObservedSessionSubscribeOptions, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnosticPhase, ObservedSessionDiagnosticSeverity, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
@@ -44,25 +63,27 @@ export { addDecision, decisionFingerprint } from './writers/decisions';
44
63
  export { addNote } from './writers/notes';
45
64
  export { renderHandoffUrlTemplate } from './handoffUrl';
46
65
  export type { HandoffUrlIdentifiers } from './handoffUrl';
47
- export type { ProviderId, SessionProvider, SessionProviderBase, SessionFileStats, SessionFileInfo, SearchHit, ProjectFolderInfo, SessionReader, SessionProviderOptions, ProviderOperationStatus, SessionProviderDiagnostic, SessionProviderDiagnosticKind, SessionProviderDiagnosticPhase, SessionProviderDiagnosticSeverity, ProviderRuntimeStatus, } from './providers/types';
66
+ export type { ProviderId, SessionProvider, SessionProviderBase, SessionFileStats, SessionFileStatsAvailability, SessionFileInfo, SearchHit, ProjectFolderInfo, SessionReader, SessionProviderOptions, ProviderOperationStatus, SessionProviderDiagnostic, SessionProviderDiagnosticKind, SessionProviderDiagnosticPhase, SessionProviderDiagnosticSeverity, ProviderRuntimeStatus, } from './providers/types';
48
67
  export { SESSION_PROVIDER_IDS } from './providers/types';
49
68
  export { createSessionProviders } from './providers/factory';
50
69
  export type { CreateSessionProvidersOptions, CreateSessionProvidersResult, } from './providers/factory';
51
- export { createProviderSessionAdapterV1, derivePendingUserRequestV1, } from './types/observedSessionV1';
70
+ export { createProviderSessionAdapterV1, derivePendingUserRequestV1, getObservedActivityReason, } from './types/observedSessionV1';
52
71
  export type { ObservationProvenanceV1, ObservedAgentSessionV1, ObservedValueV1, PendingUserRequestV1, ProviderCapabilitiesV1, ProviderSessionAdapterV1, ProviderSessionAdapterV1Options, SessionEvidenceRefV1, } from './types/observedSessionV1';
53
- export { detectProvider, getAllDetectedProviders } from './providers/detect';
72
+ export { _resetProviderDetectionCache, detectProvider, getAllDetectedProviders, } from './providers/detect';
54
73
  export { ClaudeCodeProvider } from './providers/claudeCode';
55
74
  export { OpenCodeProvider, getOpenCodeDataDir } from './providers/openCode';
56
75
  export { CodexProvider, findCodexRolloutFile } from './providers/codex';
76
+ export { walkRolloutFiles, walkRolloutFilesAsync } from './providers/rolloutWalker';
77
+ export type { RolloutFileInfo, WalkRolloutFilesOptions } from './providers/rolloutWalker';
57
78
  export type { FindCodexRolloutFileOptions } from './providers/codex';
58
79
  export { JsonlParser, TRUNCATION_PATTERNS } from './parsers/jsonl';
59
80
  export type { RawSessionEvent, JsonlParserCallbacks, JsonlParserOptions } from './parsers/jsonl';
60
81
  export { normalizeToolName, normalizeToolInput, detectPlanModeFromText, convertOpenCodeMessage, parseDbMessageData, parseDbPartData, } from './parsers/openCodeParser';
61
82
  export { CodexRolloutParser, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, } from './parsers/codexParser';
62
83
  export { scanSubagentDir, extractTaskInfo } from './parsers/subagentScanner';
63
- export { detectSessionActivity, refreshSessionActivityState, } from './parsers/sessionActivityDetector';
64
- export type { SessionActivityState, SessionActivityResult, } from './parsers/sessionActivityDetector';
65
- export { encodeWorkspacePath as encodeClaudeWorkspacePath, getSessionDirectory as getClaudeSessionDirectory, discoverSessionDirectory, findActiveSession as findActiveClaudeSession, findAllSessions as findAllClaudeSessions, findSessionsInDirectory, findSubdirectorySessionDirs, getMostRecentlyActiveSessionDir, decodeEncodedPath, getAllProjectFolders as getAllClaudeProjectFolders, resolveWorktreeMainRepo, discoverWorktreeSiblings, findAllSessionsWithWorktrees, } from './parsers/sessionPathResolver';
84
+ export { classifySessionActivity, detectSessionActivity, refreshSessionActivityState, SESSION_ACTIVITY_GRACE_PERIOD_MS, SESSION_ACTIVITY_STALENESS_MS, } from './parsers/sessionActivityDetector';
85
+ export type { ClassifySessionActivityOptions, SessionActivityState, SessionActivityResult, } from './parsers/sessionActivityDetector';
86
+ export { encodeWorkspacePath as encodeClaudeWorkspacePath, getSessionDirectory as getClaudeSessionDirectory, discoverSessionDirectory, findActiveSession as findActiveClaudeSession, findAllSessions as findAllClaudeSessions, findSessionsInDirectory, findSessionFilesWithStats, findSubdirectorySessionDirs, getMostRecentlyActiveSessionDir, decodeEncodedPath, getAllProjectFolders as getAllClaudeProjectFolders, resolveWorktreeMainRepo, discoverWorktreeSiblings, findAllSessionsWithWorktrees, } from './parsers/sessionPathResolver';
66
87
  export { scanSubagentTraces } from './parsers/subagentTraceParser';
67
88
  export type { SubagentTrace, SubagentTraceEvent } from './parsers/subagentTraceParser';
68
89
  export { parseMcpToolName } from './parsers/mcpToolName';
@@ -90,12 +111,12 @@ export type { ExtractedPlan, ExtractedPlanStep } from './parsers/planExtractor';
90
111
  export { parseChangelog } from './parsers/changelogParser';
91
112
  export type { ChangelogEntry } from './parsers/changelogParser';
92
113
  export type { FollowEvent, FollowEventType, SessionWatcher, SessionWatcherCallbacks, } from './watchers/types';
93
- export { createWatcher } from './watchers/factory';
114
+ export { createWatcher, resolveSessionPath } from './watchers/factory';
94
115
  export type { CreateWatcherOptions } from './watchers/factory';
95
116
  export { toFollowEvents } from './watchers/eventBridge';
96
117
  export { createJsonlTail } from './watchers/jsonlTail';
97
118
  export type { JsonlTail, JsonlTailBatch, JsonlTailOptions } from './watchers/jsonlTail';
98
- export { formatDurationMs, formatTokenCount } from './formatting';
119
+ export { addLocalDays, formatDurationMs, formatLocalDateKey, formatTokenCount, parseLocalDateKey, } from './formatting';
99
120
  export type { FormatDurationMsOptions, FormatTokenCountOptions } from './formatting';
100
121
  export { formatToolSummary } from './formatters/toolSummary';
101
122
  export { isHardNoise, isHardNoiseFollowEvent, getSoftNoiseReason, classifyMessage, classifyFollowEvent, shouldMergeWithPrevious, classifyNoise, } from './formatters/noiseClassifier';
@@ -110,9 +131,9 @@ export { EventAggregator, parseTodoDependencies } from './aggregation/EventAggre
110
131
  export { SessionMonitor } from './sessionMonitor';
111
132
  export type { SessionMonitorOptions, SessionMonitorSubscribeOptions } from './sessionMonitor';
112
133
  export type { SerializedAggregatorState } from './aggregation/EventAggregator';
113
- export { saveSnapshot, loadSnapshot, deleteSnapshot, isSnapshotValid, getSnapshotPath, } from './aggregation/snapshot';
134
+ export { saveSnapshot, loadSnapshot, deleteSnapshot, isSnapshotValid, pruneSnapshots, MAX_SNAPSHOT_FILES, getSnapshotPath, } from './aggregation/snapshot';
114
135
  export type { SessionSnapshot } from './aggregation/snapshot';
115
- export type { EventAggregatorOptions, AggregatedTokens, ModelUsageStats, BurnRateInfo, SubagentLifecycle, AggregatedMetrics, FrequencyMetric, PatternMetric, HeatmapBucketMetric, ErrorRollup, ErrorRollupEntry, ErrorBucketMetric, } from './aggregation/types';
136
+ export type { EventAggregatorOptions, AggregatedCostProvenance, AggregatedTokens, ModelUsageStats, BurnRateInfo, SubagentLifecycle, AggregatedMetrics, FrequencyMetric, PatternMetric, HeatmapBucketMetric, ErrorRollup, ErrorRollupEntry, ErrorBucketMetric, } from './aggregation/types';
116
137
  export { ERROR_HISTORY_SCHEMA_VERSION, MAX_ERROR_HISTORY_SESSIONS, appendErrorHistory, getTopFailingTools, readErrorHistory, } from './errorHistory';
117
138
  export type { ErrorHistorySessionRecord, ErrorHistoryStore, TopFailingTool } from './errorHistory';
118
139
  export { FrequencyTracker } from './aggregation/FrequencyTracker';
@@ -125,6 +146,8 @@ export { calculateQualityTrend, scoreSessionQuality } from './analytics/qualityS
125
146
  export type { QualityFactorContribution, QualityFactorId, SessionQualityScore, QualityTrend, } from './analytics/qualityScore';
126
147
  export { calculateCodeImpact } from './analytics/codeImpact';
127
148
  export type { CodeImpact, ModelCostInput } from './analytics/codeImpact';
149
+ export { classifyCostProvenance, describeCostProvenance } from './aggregation/costProvenance';
150
+ export type { AggregatedCostProvenanceInput } from './aggregation/costProvenance';
128
151
  export { calculateCompactionLedger, formatCompactionLedger } from './analytics/compactionLedger';
129
152
  export type { CompactionLedger } from './analytics/compactionLedger';
130
153
  export { generateHtmlReport, parseTranscript, parseTranscriptFromEvents, openInBrowser, } from './report';
@@ -142,7 +165,7 @@ export { getAccountsDir, readSavedAccountRegistry, writeSavedAccountRegistry, li
142
165
  export type { AccountProviderId, AccountIdentityMetadata, ResolvedActiveAccount, SavedAccountProfile, SavedAccountRegistry, } from './accountRegistry';
143
166
  export { ACCOUNT_PROVIDER_IDS } from './accountRegistry';
144
167
  export { getActiveAccountStatus } from './accountStatus';
145
- export type { ActiveAccountStatus, ActiveProviderAccountStatus } from './accountStatus';
168
+ export type { ActiveAccountStatus, ActiveAccountStatusOptions, ActiveProviderAccountStatus, } from './accountStatus';
146
169
  export { onAccountsChanged } from './accountChanges';
147
170
  export type { AccountsChangedEvent, OnAccountsChangedOptions } from './accountChanges';
148
171
  export { getClaudeProfilesDir, getClaudeProfileHome, claudeKeychainSuffix, claudeKeychainService, isClaudeProfileAuthenticated, readClaudeProfileIdentity, } from './claudeProfiles';
@@ -159,6 +182,15 @@ export type { QuotaFailureDescriptor } from './quotaPresentation';
159
182
  export { QuotaPoller } from './quotaPoller';
160
183
  export type { QuotaPollerOptions } from './quotaPoller';
161
184
  export { readQuotaSnapshot, writeQuotaSnapshot } from './quotaSnapshots';
185
+ export type { QuotaSnapshotRecord } from './quotaSnapshots';
186
+ export { resolveQuota } from './quotaResolver';
187
+ export type { QuotaResolution, QuotaResolveProviderId, ResolveQuotaOptions, ResolvedQuota, } from './quotaResolver';
188
+ export { classifyQuotaFreshness, formatQuotaAge, QUOTA_AGING_MAX_AGE_MS, QUOTA_FRESH_MAX_AGE_MS, } from './quota';
189
+ export type { QuotaFreshness } from './quota';
190
+ export { DEFAULT_QUOTA_THRESHOLDS, describeQuotaThresholdAlert, evaluateQuotaThresholds, } from './quotaThresholds';
191
+ export type { QuotaAlertMemory, QuotaThresholdAlert, QuotaThresholdConfig, QuotaThresholdEvaluation, QuotaThresholdWindow, } from './quotaThresholds';
192
+ export { parseClaudeStatuslinePayload, quotaFromStatuslinePayload, } from './statusline/claudeStatuslinePayload';
193
+ export type { ClaudeStatuslinePayload, ClaudeStatuslineRateLimitWindow, QuotaFromStatuslineOptions, } from './statusline/claudeStatuslinePayload';
162
194
  export { appendQuotaHistorySample, readQuotaHistoryRange, readQuotaHistoryDailyBuckets, pruneQuotaHistory, getWorkspaceIdFromPath, } from './quotaHistory';
163
195
  export type { QuotaHistorySample, QuotaHistoryAppendOptions, QuotaHistoryRangeOptions, QuotaHistoryDailyBucket, QuotaHistoryRuntimeProvider, } from './quotaHistory';
164
196
  export { fetchCodexResetCreditsFromApi, fetchCodexQuotaFromApi, quotaFromCodexRateLimits, readLatestCodexQuotaFromRollouts, resolveCodexQuota, resolveCodexQuotaFromLocalSources, } from './codexQuota';
@@ -205,5 +237,7 @@ export { fetchProviderStatus, fetchOpenAIStatus } from './providerStatus';
205
237
  export type { ProviderStatusState } from './providerStatus';
206
238
  export { formatHealthReport, getSessionDiagnostics, runDoctor } from './doctor';
207
239
  export type { DeprecatedSetting, DoctorOptions, HealthCheck, HealthCheckStatus, HealthReport, SessionDiagnostics, } from './doctor';
208
- export { createPeakHoursNotApplicableState, DEFAULT_PEAK_HOURS_TIMEOUT_MS, fetchPeakHoursStatus, isClaudeCodeSessionProvider, scopePeakHoursToSessionProvider, } from './peakHours';
240
+ export { _resetPeakHoursCache, createPeakHoursNotApplicableState, DEFAULT_PEAK_HOURS_TIMEOUT_MS, fetchPeakHoursStatus, getScheduledPeakHoursState, isClaudeCodeSessionProvider, PEAK_HOURS_CACHE_MS, PEAK_HOURS_DESCRIPTION, scopePeakHoursToSessionProvider, } from './peakHours';
209
241
  export type { FetchPeakHoursOptions, PeakHoursState } from './peakHours';
242
+ export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
243
+ export type { FailingToolTrend, FailingToolTrendRow, FailingToolWindow } from './failingTools';