sidekick-shared 0.25.0 → 0.26.1
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 +65 -0
- package/README.md +50 -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/modelContext.js +8 -3
- package/dist/modelInfo.js +45 -27
- 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/quotaPresentation.js +17 -5
- package/dist/quotaResolver.d.ts +83 -0
- package/dist/quotaResolver.js +234 -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
package/dist/pricingCatalog.js
CHANGED
|
@@ -60,6 +60,7 @@ const path = __importStar(require("node:path"));
|
|
|
60
60
|
const modelContext_1 = require("./modelContext");
|
|
61
61
|
const modelInfo_1 = require("./modelInfo");
|
|
62
62
|
const paths_1 = require("./paths");
|
|
63
|
+
const atomic_1 = require("./writers/atomic");
|
|
63
64
|
// ── Constants ──
|
|
64
65
|
exports.LITELLM_CATALOG_URL = 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';
|
|
65
66
|
const CACHE_FILE_NAME = 'pricing-catalog.json';
|
|
@@ -77,16 +78,16 @@ const DEFAULT_TIMEOUT_MS = 3_000;
|
|
|
77
78
|
* Always resolves — never throws. Offline-safe.
|
|
78
79
|
*/
|
|
79
80
|
async function hydratePricingCatalog(options = {}) {
|
|
80
|
-
const { cacheDir = (0, paths_1.getConfigDir)(), fetchImpl = globalThis.fetch, ttlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, url = exports.LITELLM_CATALOG_URL, logger, } = options;
|
|
81
|
+
const { cacheDir = (0, paths_1.getConfigDir)(), fetchImpl = globalThis.fetch, ttlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, url = exports.LITELLM_CATALOG_URL, logger, offline = false, } = options;
|
|
81
82
|
const cachePath = path.join(cacheDir, CACHE_FILE_NAME);
|
|
82
83
|
const now = Date.now();
|
|
83
|
-
// 1. Fresh cache?
|
|
84
|
+
// 1. Fresh cache? (Offline callers take any cache, however old.)
|
|
84
85
|
const cached = await readCache(cachePath);
|
|
85
|
-
if (cached && now - Date.parse(cached.fetchedAt) < ttlMs) {
|
|
86
|
+
if (cached && (offline || now - Date.parse(cached.fetchedAt) < ttlMs)) {
|
|
86
87
|
return applyCacheFile(cached, 'cache');
|
|
87
88
|
}
|
|
88
89
|
// 2. Try network.
|
|
89
|
-
if (fetchImpl) {
|
|
90
|
+
if (fetchImpl && !offline) {
|
|
90
91
|
const fetched = await fetchCatalog(url, fetchImpl, timeoutMs, logger);
|
|
91
92
|
if (fetched) {
|
|
92
93
|
const payload = {
|
|
@@ -256,7 +257,9 @@ async function readCache(cachePath) {
|
|
|
256
257
|
async function writeCache(cachePath, payload, logger) {
|
|
257
258
|
try {
|
|
258
259
|
await node_fs_1.promises.mkdir(path.dirname(cachePath), { recursive: true });
|
|
259
|
-
|
|
260
|
+
// The CLI and the extension host can both refresh the catalog at once;
|
|
261
|
+
// the atomic writer keeps a reader from ever seeing a half-written file.
|
|
262
|
+
await (0, atomic_1.atomicWriteJson)(cachePath, payload);
|
|
260
263
|
}
|
|
261
264
|
catch (err) {
|
|
262
265
|
logger?.(`pricingCatalog: failed to write cache: ${String(err)}`);
|
|
@@ -48,6 +48,7 @@ const os = __importStar(require("os"));
|
|
|
48
48
|
const path = __importStar(require("path"));
|
|
49
49
|
const string_decoder_1 = require("string_decoder");
|
|
50
50
|
const sessionContext_1 = require("../context/sessionContext");
|
|
51
|
+
const sessionStats_1 = require("../sessionStats");
|
|
51
52
|
const jsonl_1 = require("../parsers/jsonl");
|
|
52
53
|
const diagnostics_1 = require("./diagnostics");
|
|
53
54
|
const sessionPathResolver_1 = require("../parsers/sessionPathResolver");
|
|
@@ -342,16 +343,13 @@ class ClaudeCodeProvider {
|
|
|
342
343
|
const results = [];
|
|
343
344
|
const seen = new Set();
|
|
344
345
|
for (const folder of this.getAllProjectFolders()) {
|
|
345
|
-
|
|
346
|
-
|
|
346
|
+
// The directory listing already stat'ed each file; reuse it instead of
|
|
347
|
+
// stat'ing every session a second time.
|
|
348
|
+
for (const file of (0, sessionPathResolver_1.findSessionFilesWithStats)(folder.dir)) {
|
|
349
|
+
if (seen.has(file.path))
|
|
347
350
|
continue;
|
|
348
|
-
seen.add(
|
|
349
|
-
|
|
350
|
-
results.push({ path: sessionPath, mtime: fs.statSync(sessionPath).mtime });
|
|
351
|
-
}
|
|
352
|
-
catch {
|
|
353
|
-
// Skip files that vanish between listing and stat.
|
|
354
|
-
}
|
|
351
|
+
seen.add(file.path);
|
|
352
|
+
results.push({ path: file.path, mtime: file.mtime, sizeBytes: file.sizeBytes });
|
|
355
353
|
}
|
|
356
354
|
}
|
|
357
355
|
this.recordHomeStatus('listAllSessionFiles');
|
|
@@ -535,93 +533,10 @@ class ClaudeCodeProvider {
|
|
|
535
533
|
}
|
|
536
534
|
// --- Stats ---
|
|
537
535
|
readSessionStats(sessionPath) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const tokens = { input: 0, output: 0, cacheWrite: 0, cacheRead: 0 };
|
|
543
|
-
const modelUsage = {};
|
|
544
|
-
const toolUsage = {};
|
|
545
|
-
let compactionEstimate = 0;
|
|
546
|
-
let truncationCount = 0;
|
|
547
|
-
let reportedCost = 0;
|
|
548
|
-
try {
|
|
549
|
-
const content = fs.readFileSync(sessionPath, 'utf8');
|
|
550
|
-
const lines = content.split('\n');
|
|
551
|
-
for (const line of lines) {
|
|
552
|
-
const trimmed = line.trim();
|
|
553
|
-
if (!trimmed || !trimmed.startsWith('{'))
|
|
554
|
-
continue;
|
|
555
|
-
try {
|
|
556
|
-
const event = JSON.parse(trimmed);
|
|
557
|
-
if (!startTime && event.timestamp)
|
|
558
|
-
startTime = event.timestamp;
|
|
559
|
-
if (event.timestamp)
|
|
560
|
-
endTime = event.timestamp;
|
|
561
|
-
if (event.type === 'assistant' && event.message?.usage) {
|
|
562
|
-
messageCount++;
|
|
563
|
-
const u = event.message.usage;
|
|
564
|
-
tokens.input += u.input_tokens || 0;
|
|
565
|
-
tokens.output += u.output_tokens || 0;
|
|
566
|
-
tokens.cacheWrite += u.cache_creation_input_tokens || 0;
|
|
567
|
-
tokens.cacheRead += u.cache_read_input_tokens || 0;
|
|
568
|
-
if (u.reported_cost)
|
|
569
|
-
reportedCost += u.reported_cost;
|
|
570
|
-
const model = event.message.model || 'unknown';
|
|
571
|
-
if (!modelUsage[model])
|
|
572
|
-
modelUsage[model] = { calls: 0, tokens: 0 };
|
|
573
|
-
modelUsage[model].calls++;
|
|
574
|
-
modelUsage[model].tokens += (u.input_tokens || 0) + (u.output_tokens || 0);
|
|
575
|
-
// Check content for tool_use blocks
|
|
576
|
-
if (Array.isArray(event.message.content)) {
|
|
577
|
-
for (const block of event.message.content) {
|
|
578
|
-
if (block.type === 'tool_use' && typeof block.name === 'string') {
|
|
579
|
-
toolUsage[block.name] = (toolUsage[block.name] || 0) + 1;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
if (event.type === 'user')
|
|
585
|
-
messageCount++;
|
|
586
|
-
if (event.type === 'summary')
|
|
587
|
-
compactionEstimate++;
|
|
588
|
-
// Check for truncation in tool results
|
|
589
|
-
if (event.type === 'user' && Array.isArray(event.message?.content)) {
|
|
590
|
-
for (const block of event.message.content) {
|
|
591
|
-
if (block.type === 'tool_result' && typeof block.content === 'string') {
|
|
592
|
-
for (const pattern of jsonl_1.TRUNCATION_PATTERNS) {
|
|
593
|
-
if (pattern.regex.test(block.content)) {
|
|
594
|
-
truncationCount++;
|
|
595
|
-
break;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
catch {
|
|
603
|
-
// Skip malformed lines
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
catch {
|
|
608
|
-
// Skip unreadable files
|
|
609
|
-
}
|
|
610
|
-
return {
|
|
611
|
-
providerId: 'claude-code',
|
|
612
|
-
sessionId,
|
|
613
|
-
filePath: sessionPath,
|
|
614
|
-
label: this.extractSessionLabel(sessionPath),
|
|
615
|
-
startTime,
|
|
616
|
-
endTime,
|
|
617
|
-
messageCount,
|
|
618
|
-
tokens,
|
|
619
|
-
modelUsage,
|
|
620
|
-
toolUsage,
|
|
621
|
-
compactionEstimate,
|
|
622
|
-
truncationCount,
|
|
623
|
-
reportedCost,
|
|
624
|
-
};
|
|
536
|
+
// One reader pass through the shared aggregator: cache-inclusive per-model
|
|
537
|
+
// totals, cost with provenance, a tool success/failure split, and the label
|
|
538
|
+
// from the first user prompt in the events already read.
|
|
539
|
+
return (0, sessionStats_1.readSessionFileStats)(this, sessionPath);
|
|
625
540
|
}
|
|
626
541
|
readSessionContextSnapshot(sessionPath, options = {}) {
|
|
627
542
|
return (0, sessionContext_1.readSessionContextSnapshot)(this, sessionPath, options);
|
|
@@ -74,6 +74,8 @@ export declare class CodexProvider implements SessionProviderBase {
|
|
|
74
74
|
isSessionFile(filename: string): boolean;
|
|
75
75
|
getSessionId(sessionPath: string): string;
|
|
76
76
|
encodeWorkspacePath(workspacePath: string): string;
|
|
77
|
+
/** Thread title or first user message from the SQLite index; null without it. */
|
|
78
|
+
private extractSessionLabelFromDb;
|
|
77
79
|
extractSessionLabel(sessionPath: string): string | null;
|
|
78
80
|
extractSessionLabelsAsync(sessionPaths: readonly string[]): Promise<Map<string, string | null>>;
|
|
79
81
|
createReader(sessionPath: string): SessionReader;
|