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.
- package/CHANGELOG.md +57 -0
- package/README.md +49 -3
- package/dist/accountChanges.js +22 -3
- package/dist/accountRegistry.d.ts +22 -1
- package/dist/accountRegistry.js +37 -14
- package/dist/accountStatus.d.ts +9 -1
- package/dist/accountStatus.js +3 -3
- package/dist/accounts.d.ts +3 -1
- package/dist/accounts.js +84 -64
- package/dist/aggregation/EventAggregator.d.ts +15 -2
- package/dist/aggregation/EventAggregator.js +54 -9
- package/dist/aggregation/costProvenance.d.ts +14 -0
- package/dist/aggregation/costProvenance.js +35 -0
- package/dist/aggregation/snapshot.d.ts +13 -2
- package/dist/aggregation/snapshot.js +57 -6
- package/dist/aggregation/types.d.ts +30 -1
- package/dist/analytics/compactionLedger.js +15 -5
- package/dist/analytics/qualityScore.js +2 -1
- package/dist/browser.d.ts +11 -1
- package/dist/browser.js +29 -1
- package/dist/codexProfiles.d.ts +3 -1
- package/dist/codexProfiles.js +4 -2
- package/dist/codexQuota.d.ts +2 -0
- package/dist/codexQuota.js +11 -66
- package/dist/failingTools.d.ts +37 -0
- package/dist/failingTools.js +70 -0
- package/dist/formatters/sessionDump.js +13 -7
- package/dist/formatting.d.ts +13 -0
- package/dist/formatting.js +35 -0
- package/dist/historicalStore.d.ts +47 -0
- package/dist/historicalStore.js +312 -0
- package/dist/index.d.ts +46 -12
- package/dist/index.js +112 -24
- package/dist/node.d.ts +19 -0
- package/dist/node.js +47 -1
- package/dist/observedContextWindows.d.ts +7 -0
- package/dist/observedContextWindows.js +17 -2
- package/dist/observedSessionCollector.d.ts +3 -8
- package/dist/observedSessionCollector.js +10 -27
- package/dist/parsers/sessionActivityDetector.d.ts +24 -2
- package/dist/parsers/sessionActivityDetector.js +95 -17
- package/dist/parsers/sessionPathResolver.d.ts +11 -0
- package/dist/parsers/sessionPathResolver.js +13 -10
- package/dist/peakHours.d.ts +34 -3
- package/dist/peakHours.js +92 -7
- package/dist/pricingCatalog.d.ts +7 -0
- package/dist/pricingCatalog.js +8 -5
- package/dist/providers/claudeCode.js +11 -96
- package/dist/providers/codex.d.ts +2 -0
- package/dist/providers/codex.js +94 -259
- package/dist/providers/detect.d.ts +2 -0
- package/dist/providers/detect.js +29 -24
- package/dist/providers/factory.d.ts +6 -0
- package/dist/providers/openCode.d.ts +2 -0
- package/dist/providers/openCode.js +105 -121
- package/dist/providers/rolloutWalker.d.ts +53 -0
- package/dist/providers/rolloutWalker.js +209 -0
- package/dist/providers/types.d.ts +30 -0
- package/dist/quota.d.ts +30 -3
- package/dist/quota.js +35 -3
- package/dist/quotaHistory.d.ts +1 -1
- package/dist/quotaHistory.js +36 -35
- package/dist/quotaResolver.d.ts +81 -0
- package/dist/quotaResolver.js +213 -0
- package/dist/quotaSnapshots.d.ts +15 -2
- package/dist/quotaSnapshots.js +25 -3
- package/dist/quotaThresholds.d.ts +60 -0
- package/dist/quotaThresholds.js +90 -0
- package/dist/report/htmlReportGenerator.js +10 -4
- package/dist/report/sessionReportInputs.d.ts +23 -0
- package/dist/report/sessionReportInputs.js +34 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +10 -1
- package/dist/schemas/quota.d.ts +139 -0
- package/dist/schemas/quota.js +17 -2
- package/dist/schemas/quotaHistory.d.ts +1 -0
- package/dist/schemas/quotaHistory.js +1 -1
- package/dist/schemas/sessionEvent.d.ts +6 -0
- package/dist/schemas/sessionEvent.js +1 -0
- package/dist/schemas/stateFile.d.ts +198 -0
- package/dist/schemas/stateFile.js +77 -0
- package/dist/schemas/transcript.js +2 -0
- package/dist/sessionFingerprint.d.ts +25 -0
- package/dist/sessionFingerprint.js +46 -0
- package/dist/sessionPreviews.d.ts +7 -1
- package/dist/sessionPreviews.js +15 -3
- package/dist/sessionStats.d.ts +51 -0
- package/dist/sessionStats.js +166 -0
- package/dist/stateFile.d.ts +113 -0
- package/dist/stateFile.js +160 -0
- package/dist/statusline/claudeStatuslinePayload.d.ts +89 -0
- package/dist/statusline/claudeStatuslinePayload.js +152 -0
- package/dist/statusline/formatter.d.ts +13 -0
- package/dist/statusline/formatter.js +48 -6
- package/dist/statusline/index.d.ts +10 -2
- package/dist/statusline/index.js +19 -1
- package/dist/tokenSummary.d.ts +62 -0
- package/dist/tokenSummary.js +72 -0
- package/dist/transcript.d.ts +5 -0
- package/dist/transcript.js +2 -0
- package/dist/types/observedSessionV1.d.ts +2 -0
- package/dist/types/observedSessionV1.js +75 -18
- package/dist/types/sessionEvent.d.ts +2 -0
- package/dist/usage/billingBlocks.d.ts +85 -0
- package/dist/usage/billingBlocks.js +153 -0
- package/dist/usage/importSessionHistory.d.ts +53 -0
- package/dist/usage/importSessionHistory.js +88 -0
- package/dist/usage/usageEvents.d.ts +92 -0
- package/dist/usage/usageEvents.js +322 -0
- package/dist/usage/usageReports.d.ts +76 -0
- package/dist/usage/usageReports.js +208 -0
- package/dist/watchers/factory.d.ts +6 -0
- package/dist/watchers/factory.js +30 -25
- package/dist/zaiQuotaApi.d.ts +2 -0
- package/dist/zaiQuotaApi.js +2 -0
- 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';
|