sidekick-shared 0.27.6 → 0.28.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 +28 -0
- package/README.md +58 -18
- package/dist/browser.d.ts +13 -2
- package/dist/browser.js +30 -2
- package/dist/claudePaths.d.ts +11 -0
- package/dist/claudePaths.js +61 -0
- package/dist/claudeProfiles.d.ts +2 -9
- package/dist/claudeProfiles.js +10 -25
- package/dist/codexPaths.d.ts +22 -0
- package/dist/codexPaths.js +67 -0
- package/dist/codexProfiles.d.ts +1 -4
- package/dist/codexProfiles.js +5 -43
- package/dist/doctor.js +2 -2
- package/dist/esm/accountChangeSignal.js +15 -0
- package/dist/esm/accountChanges.js +152 -0
- package/dist/esm/accountHealth.js +288 -0
- package/dist/esm/accountLaunch.js +145 -0
- package/dist/esm/accountLease.js +60 -0
- package/dist/esm/accountManager.js +606 -0
- package/dist/esm/accountRegistry.js +214 -0
- package/dist/esm/accountStatus.js +51 -0
- package/dist/esm/accountSwitch.js +74 -0
- package/dist/esm/accountSync.js +156 -0
- package/dist/esm/accountSyncTypes.js +4 -0
- package/dist/esm/accounts.js +1291 -0
- package/dist/esm/aggregation/EventAggregator.js +2034 -0
- package/dist/esm/aggregation/FrequencyTracker.js +69 -0
- package/dist/esm/aggregation/HeatmapTracker.js +89 -0
- package/dist/esm/aggregation/PatternExtractor.js +168 -0
- package/dist/esm/aggregation/costProvenance.js +31 -0
- package/dist/esm/aggregation/snapshot.js +161 -0
- package/dist/esm/aggregation/types.js +5 -0
- package/dist/esm/analytics/codeImpact.js +18 -0
- package/dist/esm/analytics/compactionLedger.js +37 -0
- package/dist/esm/analytics/qualityScore.js +112 -0
- package/dist/esm/autoSwitch.js +185 -0
- package/dist/esm/browser.js +34 -0
- package/dist/esm/claudeCredentialDoctor.js +239 -0
- package/dist/esm/claudeCredentialLedger.js +91 -0
- package/dist/esm/claudeCredentials.js +111 -0
- package/dist/esm/claudeLiveGuard.js +43 -0
- package/dist/esm/claudePaths.js +22 -0
- package/dist/esm/claudeProfiles.js +142 -0
- package/dist/esm/claudeRefreshLock.js +106 -0
- package/dist/esm/codexAuth.js +101 -0
- package/dist/esm/codexCredentialDoctor.js +265 -0
- package/dist/esm/codexCredentialStore.js +164 -0
- package/dist/esm/codexKeepAlive.js +112 -0
- package/dist/esm/codexPaths.js +172 -0
- package/dist/esm/codexProfiles.js +1251 -0
- package/dist/esm/codexQuota.js +564 -0
- package/dist/esm/codexQuotaWatcher.js +363 -0
- package/dist/esm/context/composer.js +71 -0
- package/dist/esm/context/sessionContext.js +546 -0
- package/dist/esm/credentialIO.js +283 -0
- package/dist/esm/credentials.js +49 -0
- package/dist/esm/doctor.js +305 -0
- package/dist/esm/ensureDefaultAccounts.js +62 -0
- package/dist/esm/errorHistory.js +56 -0
- package/dist/esm/extractors/errorTaxonomy.js +43 -0
- package/dist/esm/extractors/gatherAssets.js +32 -0
- package/dist/esm/extractors/sessionAssets.js +176 -0
- package/dist/esm/extractors/sources/claudeAssets.js +158 -0
- package/dist/esm/extractors/sources/codexAssets.js +234 -0
- package/dist/esm/extractors/tokenUsage.js +41 -0
- package/dist/esm/extractors/toolCall.js +142 -0
- package/dist/esm/failingTools.js +65 -0
- package/dist/esm/fileHead.js +27 -0
- package/dist/esm/formatters/eventHighlighter.js +332 -0
- package/dist/esm/formatters/noiseClassifier.js +209 -0
- package/dist/esm/formatters/sessionDump.js +328 -0
- package/dist/esm/formatters/toolSummary.js +226 -0
- package/dist/esm/formatting.js +82 -0
- package/dist/esm/handoffUrl.js +23 -0
- package/dist/esm/historicalStore.js +305 -0
- package/dist/esm/humanPrompt.js +88 -0
- package/dist/esm/index.js +213 -0
- package/dist/esm/keepAlive.js +189 -0
- package/dist/esm/liveCredentialGuard.js +33 -0
- package/dist/esm/modelAliases.js +51 -0
- package/dist/esm/modelCatalog.js +139 -0
- package/dist/esm/modelContext.js +280 -0
- package/dist/esm/modelInfo.js +832 -0
- package/dist/esm/multiProviderQuotaService.js +450 -0
- package/dist/esm/node.js +46 -0
- package/dist/esm/observedContextWindows.js +165 -0
- package/dist/esm/observedSessionCollector.js +939 -0
- package/dist/esm/parsers/changelogParser.js +71 -0
- package/dist/esm/parsers/codexHistory.js +89 -0
- package/dist/esm/parsers/codexParser.js +906 -0
- package/dist/esm/parsers/debugLogParser.js +126 -0
- package/dist/esm/parsers/jsonl.js +66 -0
- package/dist/esm/parsers/mcpToolName.js +28 -0
- package/dist/esm/parsers/openCodeParser.js +625 -0
- package/dist/esm/parsers/planExtractor.js +335 -0
- package/dist/esm/parsers/sessionActivityDetector.js +246 -0
- package/dist/esm/parsers/sessionPathResolver.js +713 -0
- package/dist/esm/parsers/subagentScanner.js +360 -0
- package/dist/esm/parsers/subagentStatsCache.js +45 -0
- package/dist/esm/parsers/subagentTraceParser.js +325 -0
- package/dist/esm/paths.js +134 -0
- package/dist/esm/peakHours.js +194 -0
- package/dist/esm/phrases.js +1330 -0
- package/dist/esm/pricingCatalog.js +247 -0
- package/dist/esm/processDetection.js +200 -0
- package/dist/esm/projectMigration.js +59 -0
- package/dist/esm/promptHistory.js +1221 -0
- package/dist/esm/providerFailure.js +362 -0
- package/dist/esm/providerIds.js +6 -0
- package/dist/esm/providerQuota.js +1 -0
- package/dist/esm/providerServiceStatus.js +145 -0
- package/dist/esm/providerServiceStatusTypes.js +1 -0
- package/dist/esm/providerStatus.js +117 -0
- package/dist/esm/providers/claudeCode.js +575 -0
- package/dist/esm/providers/claudeListing.js +121 -0
- package/dist/esm/providers/codex.js +1034 -0
- package/dist/esm/providers/codexDatabase.js +297 -0
- package/dist/esm/providers/codexRollouts.js +215 -0
- package/dist/esm/providers/detect.js +185 -0
- package/dist/esm/providers/diagnostics.js +83 -0
- package/dist/esm/providers/directoryListingCache.js +206 -0
- package/dist/esm/providers/factory.js +54 -0
- package/dist/esm/providers/openCode.js +2008 -0
- package/dist/esm/providers/openCodeDatabase.js +419 -0
- package/dist/esm/providers/rolloutWalker.js +252 -0
- package/dist/esm/providers/types.js +12 -0
- package/dist/esm/quota.js +182 -0
- package/dist/esm/quotaHistory.js +364 -0
- package/dist/esm/quotaPoller.js +230 -0
- package/dist/esm/quotaPresentation.js +97 -0
- package/dist/esm/quotaResolver.js +231 -0
- package/dist/esm/quotaSnapshots.js +130 -0
- package/dist/esm/quotaThresholds.js +85 -0
- package/dist/esm/readers/decisions.js +24 -0
- package/dist/esm/readers/handoff.js +20 -0
- package/dist/esm/readers/helpers.js +27 -0
- package/dist/esm/readers/history.js +9 -0
- package/dist/esm/readers/notes.js +48 -0
- package/dist/esm/readers/plans.js +225 -0
- package/dist/esm/readers/tasks.js +19 -0
- package/dist/esm/report/htmlHelpers.js +280 -0
- package/dist/esm/report/htmlReportGenerator.js +704 -0
- package/dist/esm/report/index.js +7 -0
- package/dist/esm/report/logo.js +2 -0
- package/dist/esm/report/openBrowser.js +19 -0
- package/dist/esm/report/sessionReportInputs.js +33 -0
- package/dist/esm/report/transcriptParser.js +83 -0
- package/dist/esm/report/types.js +4 -0
- package/dist/esm/schemas/accountManager.js +204 -0
- package/dist/esm/schemas/accountStatus.js +25 -0
- package/dist/esm/schemas/assistantTurn.js +74 -0
- package/dist/esm/schemas/index.js +25 -0
- package/dist/esm/schemas/observedSessionV1.js +77 -0
- package/dist/esm/schemas/providerFailure.js +37 -0
- package/dist/esm/schemas/quota.js +132 -0
- package/dist/esm/schemas/quotaHistory.js +40 -0
- package/dist/esm/schemas/sessionEvent.js +216 -0
- package/dist/esm/schemas/stateFile.js +75 -0
- package/dist/esm/schemas/tokenEstimation.js +7 -0
- package/dist/esm/schemas/transcript.js +86 -0
- package/dist/esm/schemas/usageNormalization.js +38 -0
- package/dist/esm/search/advancedFilter.js +197 -0
- package/dist/esm/search/sessionSearch.js +66 -0
- package/dist/esm/sessionFingerprint.js +40 -0
- package/dist/esm/sessionMonitor.js +198 -0
- package/dist/esm/sessionPreviews.js +522 -0
- package/dist/esm/sessionPromptHistory.js +254 -0
- package/dist/esm/sessionPromptSignals.js +364 -0
- package/dist/esm/sessionStats.js +160 -0
- package/dist/esm/sessionTokenTotals.js +98 -0
- package/dist/esm/sessionTranscripts.js +49 -0
- package/dist/esm/stateFile.js +119 -0
- package/dist/esm/statusline/BurnRateCalculator.js +40 -0
- package/dist/esm/statusline/claudeStatuslinePayload.js +148 -0
- package/dist/esm/statusline/formatter.js +122 -0
- package/dist/esm/statusline/index.js +8 -0
- package/dist/esm/terminalSync.js +95 -0
- package/dist/esm/testing/credentialGuard.js +197 -0
- package/dist/esm/testing/index.js +12 -0
- package/dist/esm/testing/sessionLogFixtures.js +128 -0
- package/dist/esm/tokenEstimation.js +67 -0
- package/dist/esm/tokenSummary.js +113 -0
- package/dist/esm/toolCategory.js +82 -0
- package/dist/esm/transcript.js +257 -0
- package/dist/esm/turns/assistantTurn.js +373 -0
- package/dist/esm/types/codex.js +23 -0
- package/dist/esm/types/decisionLog.js +5 -0
- package/dist/esm/types/historicalData.js +47 -0
- package/dist/esm/types/knowledgeNote.js +15 -0
- package/dist/esm/types/observedSessionV1.js +257 -0
- package/dist/esm/types/opencode.js +12 -0
- package/dist/esm/types/plan.js +7 -0
- package/dist/esm/types/sessionEvent.js +10 -0
- package/dist/esm/types/taskPersistence.js +12 -0
- package/dist/esm/usage/billingBlocks.js +148 -0
- package/dist/esm/usage/claudeUsageDedupe.js +189 -0
- package/dist/esm/usage/importSessionHistory.js +84 -0
- package/dist/esm/usage/subagentUsage.js +18 -0
- package/dist/esm/usage/usageEvents.js +402 -0
- package/dist/esm/usage/usageReports.js +202 -0
- package/dist/esm/usageNormalization.js +95 -0
- package/dist/esm/watchers/eventBridge.js +219 -0
- package/dist/esm/watchers/factory.js +63 -0
- package/dist/esm/watchers/jsonlTail.js +289 -0
- package/dist/esm/watchers/jsonlWatcher.js +435 -0
- package/dist/esm/watchers/providerReaderWatcher.js +118 -0
- package/dist/esm/watchers/sqliteWatcher.js +285 -0
- package/dist/esm/watchers/types.js +4 -0
- package/dist/esm/workspaceRoots.js +56 -0
- package/dist/esm/writers/atomic.js +375 -0
- package/dist/esm/writers/decisions.js +51 -0
- package/dist/esm/writers/notes.js +46 -0
- package/dist/esm/writers/tasks.js +63 -0
- package/dist/esm/zaiQuota.js +323 -0
- package/dist/esm/zaiQuotaApi.js +271 -0
- package/dist/esm/zaiQuotaWatcher.js +265 -0
- package/dist/fileHead.d.ts +22 -0
- package/dist/fileHead.js +33 -0
- package/dist/index.d.ts +16 -7
- package/dist/index.js +49 -15
- package/dist/node.d.ts +13 -1
- package/dist/node.js +43 -2
- package/dist/parsers/codexHistory.js +2 -2
- package/dist/parsers/codexParser.d.ts +12 -0
- package/dist/parsers/codexParser.js +34 -12
- package/dist/parsers/debugLogParser.js +2 -2
- package/dist/parsers/sessionPathResolver.js +5 -4
- package/dist/promptHistory.d.ts +32 -0
- package/dist/promptHistory.js +115 -59
- package/dist/providerFailure.d.ts +12 -6
- package/dist/providerFailure.js +45 -0
- package/dist/providers/claudeCode.js +7 -99
- package/dist/providers/claudeListing.d.ts +22 -0
- package/dist/providers/claudeListing.js +158 -0
- package/dist/providers/codex.d.ts +3 -1
- package/dist/providers/codex.js +26 -227
- package/dist/providers/codexRollouts.d.ts +44 -0
- package/dist/providers/codexRollouts.js +261 -0
- package/dist/providers/detect.js +4 -4
- package/dist/readers/plans.js +3 -3
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +7 -2
- package/dist/schemas/providerFailure.d.ts +154 -0
- package/dist/schemas/providerFailure.js +40 -0
- package/dist/sessionPromptHistory.d.ts +12 -7
- package/dist/sessionPromptHistory.js +15 -3
- package/dist/sessionPromptSignals.d.ts +9 -0
- package/dist/sessionPromptSignals.js +13 -0
- package/dist/testing/credentialGuard.d.ts +23 -0
- package/dist/testing/credentialGuard.js +233 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +22 -0
- package/dist/testing/sessionLogFixtures.d.ts +28 -0
- package/dist/testing/sessionLogFixtures.js +169 -0
- package/dist/tokenEstimation.d.ts +2 -0
- package/dist/tokenEstimation.js +21 -11
- package/dist/toolCategory.d.ts +18 -0
- package/dist/toolCategory.js +86 -0
- package/dist/types/codex.d.ts +4 -0
- package/dist/usage/usageEvents.d.ts +16 -0
- package/dist/usage/usageEvents.js +53 -9
- package/dist/watchers/jsonlTail.d.ts +26 -1
- package/dist/watchers/jsonlTail.js +136 -28
- package/dist/watchers/jsonlWatcher.js +7 -0
- package/dist/watchers/providerReaderWatcher.js +1 -0
- package/dist/watchers/types.d.ts +6 -0
- package/dist/workspaceRoots.d.ts +23 -0
- package/dist/workspaceRoots.js +93 -0
- package/package.json +22 -2
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure mutations of the `historical-data.json` store.
|
|
3
|
+
*
|
|
4
|
+
* Ported verbatim from the VS Code extension's HistoricalDataService so the
|
|
5
|
+
* CLI importer and the extension apply session summaries the same way:
|
|
6
|
+
* a session's previous contribution is subtracted before the new one is
|
|
7
|
+
* added (idempotent replacement), daily, hourly, monthly, and all-time
|
|
8
|
+
* buckets are updated together, and the per-session record list is capped
|
|
9
|
+
* at `HISTORICAL_SESSION_RETENTION_LIMIT`. Browser-safe: no Node imports.
|
|
10
|
+
*
|
|
11
|
+
* @module historicalStore
|
|
12
|
+
*/
|
|
13
|
+
import { formatLocalDateKey } from './formatting';
|
|
14
|
+
import { HISTORICAL_SESSION_RETENTION_LIMIT, createEmptyTokenTotals } from './types/historicalData';
|
|
15
|
+
function mergeModelUsage(existing, incoming) {
|
|
16
|
+
const map = new Map();
|
|
17
|
+
for (const record of existing)
|
|
18
|
+
map.set(record.model, { ...record });
|
|
19
|
+
for (const record of incoming) {
|
|
20
|
+
const current = map.get(record.model);
|
|
21
|
+
if (current) {
|
|
22
|
+
current.calls += record.calls;
|
|
23
|
+
current.tokens += record.tokens;
|
|
24
|
+
current.cost += record.cost;
|
|
25
|
+
// Unpriced taints: if either side was unpriced, the merged row is too.
|
|
26
|
+
// Legacy v1 records (priced === undefined) are assumed priced.
|
|
27
|
+
if (record.priced === false || current.priced === false)
|
|
28
|
+
current.priced = false;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
map.set(record.model, { ...record });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return Array.from(map.values());
|
|
35
|
+
}
|
|
36
|
+
function mergeToolUsage(existing, incoming) {
|
|
37
|
+
const map = new Map();
|
|
38
|
+
for (const record of existing)
|
|
39
|
+
map.set(record.tool, { ...record });
|
|
40
|
+
for (const record of incoming) {
|
|
41
|
+
const current = map.get(record.tool);
|
|
42
|
+
if (current) {
|
|
43
|
+
current.calls += record.calls;
|
|
44
|
+
current.successCount += record.successCount;
|
|
45
|
+
current.failureCount += record.failureCount;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
map.set(record.tool, { ...record });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return Array.from(map.values());
|
|
52
|
+
}
|
|
53
|
+
function subtractTokenTotals(target, contribution) {
|
|
54
|
+
target.inputTokens = Math.max(0, target.inputTokens - contribution.inputTokens);
|
|
55
|
+
target.outputTokens = Math.max(0, target.outputTokens - contribution.outputTokens);
|
|
56
|
+
target.cacheWriteTokens = Math.max(0, target.cacheWriteTokens - contribution.cacheWriteTokens);
|
|
57
|
+
target.cacheReadTokens = Math.max(0, target.cacheReadTokens - contribution.cacheReadTokens);
|
|
58
|
+
}
|
|
59
|
+
function subtractModelUsage(existing, outgoing) {
|
|
60
|
+
const map = new Map(existing.map((record) => [record.model, { ...record }]));
|
|
61
|
+
for (const record of outgoing) {
|
|
62
|
+
const current = map.get(record.model);
|
|
63
|
+
if (!current)
|
|
64
|
+
continue;
|
|
65
|
+
current.calls = Math.max(0, current.calls - record.calls);
|
|
66
|
+
current.tokens = Math.max(0, current.tokens - record.tokens);
|
|
67
|
+
current.cost = Math.max(0, current.cost - record.cost);
|
|
68
|
+
if (current.calls === 0 && current.tokens === 0)
|
|
69
|
+
map.delete(record.model);
|
|
70
|
+
}
|
|
71
|
+
return [...map.values()];
|
|
72
|
+
}
|
|
73
|
+
function subtractToolUsage(existing, outgoing) {
|
|
74
|
+
const map = new Map(existing.map((record) => [record.tool, { ...record }]));
|
|
75
|
+
for (const record of outgoing) {
|
|
76
|
+
const current = map.get(record.tool);
|
|
77
|
+
if (!current)
|
|
78
|
+
continue;
|
|
79
|
+
current.calls = Math.max(0, current.calls - record.calls);
|
|
80
|
+
current.successCount = Math.max(0, current.successCount - record.successCount);
|
|
81
|
+
current.failureCount = Math.max(0, current.failureCount - record.failureCount);
|
|
82
|
+
if (current.calls === 0)
|
|
83
|
+
map.delete(record.tool);
|
|
84
|
+
}
|
|
85
|
+
return [...map.values()];
|
|
86
|
+
}
|
|
87
|
+
function subtractSummary(bucket, summary, now) {
|
|
88
|
+
subtractTokenTotals(bucket.tokens, summary.tokens);
|
|
89
|
+
bucket.totalCost = Math.max(0, bucket.totalCost - summary.totalCost);
|
|
90
|
+
bucket.messageCount = Math.max(0, bucket.messageCount - summary.messageCount);
|
|
91
|
+
bucket.sessionCount = Math.max(0, bucket.sessionCount - 1);
|
|
92
|
+
bucket.modelUsage = subtractModelUsage(bucket.modelUsage, summary.modelUsage);
|
|
93
|
+
bucket.toolUsage = subtractToolUsage(bucket.toolUsage, summary.toolUsage);
|
|
94
|
+
bucket.updatedAt = now.toISOString();
|
|
95
|
+
}
|
|
96
|
+
function accumulateSummary(bucket, summary, now) {
|
|
97
|
+
bucket.tokens.inputTokens += summary.tokens.inputTokens;
|
|
98
|
+
bucket.tokens.outputTokens += summary.tokens.outputTokens;
|
|
99
|
+
bucket.tokens.cacheWriteTokens += summary.tokens.cacheWriteTokens;
|
|
100
|
+
bucket.tokens.cacheReadTokens += summary.tokens.cacheReadTokens;
|
|
101
|
+
bucket.totalCost += summary.totalCost;
|
|
102
|
+
bucket.messageCount += summary.messageCount;
|
|
103
|
+
bucket.sessionCount += 1;
|
|
104
|
+
bucket.modelUsage = mergeModelUsage(bucket.modelUsage, summary.modelUsage);
|
|
105
|
+
bucket.toolUsage = mergeToolUsage(bucket.toolUsage, summary.toolUsage);
|
|
106
|
+
bucket.updatedAt = now.toISOString();
|
|
107
|
+
}
|
|
108
|
+
function emptyDaily(date, now) {
|
|
109
|
+
return {
|
|
110
|
+
date,
|
|
111
|
+
tokens: createEmptyTokenTotals(),
|
|
112
|
+
totalCost: 0,
|
|
113
|
+
messageCount: 0,
|
|
114
|
+
sessionCount: 0,
|
|
115
|
+
modelUsage: [],
|
|
116
|
+
toolUsage: [],
|
|
117
|
+
updatedAt: now.toISOString(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function emptyMonthly(month, now) {
|
|
121
|
+
return {
|
|
122
|
+
month,
|
|
123
|
+
tokens: createEmptyTokenTotals(),
|
|
124
|
+
totalCost: 0,
|
|
125
|
+
messageCount: 0,
|
|
126
|
+
sessionCount: 0,
|
|
127
|
+
modelUsage: [],
|
|
128
|
+
toolUsage: [],
|
|
129
|
+
updatedAt: now.toISOString(),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function refreshAllTimeDateRange(store) {
|
|
133
|
+
const dates = Object.keys(store.daily).sort();
|
|
134
|
+
store.allTime.firstDate = dates[0] ?? '';
|
|
135
|
+
store.allTime.lastDate = dates[dates.length - 1] ?? '';
|
|
136
|
+
}
|
|
137
|
+
/** Subtract a previously saved session's contribution from every bucket. */
|
|
138
|
+
export function removeSessionSummary(store, record, now = new Date()) {
|
|
139
|
+
const summary = {
|
|
140
|
+
sessionId: record.sessionId,
|
|
141
|
+
startTime: record.startTime,
|
|
142
|
+
endTime: record.endTime,
|
|
143
|
+
tokens: { ...record.tokens },
|
|
144
|
+
totalCost: record.totalCost,
|
|
145
|
+
messageCount: record.messageCount,
|
|
146
|
+
modelUsage: record.modelUsage?.map((usage) => ({ ...usage })) ?? [],
|
|
147
|
+
toolUsage: record.toolUsage?.map((usage) => ({ ...usage })) ?? [],
|
|
148
|
+
unpricedModelIds: record.unpricedModelIds ? [...record.unpricedModelIds] : undefined,
|
|
149
|
+
};
|
|
150
|
+
const date = formatLocalDateKey(new Date(record.startTime));
|
|
151
|
+
const month = date.substring(0, 7);
|
|
152
|
+
const daily = store.daily[date];
|
|
153
|
+
if (daily) {
|
|
154
|
+
subtractSummary(daily, summary, now);
|
|
155
|
+
if (daily.sessionCount === 0)
|
|
156
|
+
delete store.daily[date];
|
|
157
|
+
}
|
|
158
|
+
const hourly = store.hourly?.[date];
|
|
159
|
+
if (hourly && store.hourly) {
|
|
160
|
+
const hour = new Date(record.startTime).getHours();
|
|
161
|
+
const bucket = hourly.find((entry) => entry.hour === hour);
|
|
162
|
+
if (bucket) {
|
|
163
|
+
subtractTokenTotals(bucket.tokens, summary.tokens);
|
|
164
|
+
bucket.totalCost = Math.max(0, bucket.totalCost - summary.totalCost);
|
|
165
|
+
bucket.messageCount = Math.max(0, bucket.messageCount - summary.messageCount);
|
|
166
|
+
bucket.sessionCount = Math.max(0, bucket.sessionCount - 1);
|
|
167
|
+
}
|
|
168
|
+
store.hourly[date] = hourly.filter((entry) => entry.sessionCount > 0);
|
|
169
|
+
if (store.hourly[date].length === 0)
|
|
170
|
+
delete store.hourly[date];
|
|
171
|
+
}
|
|
172
|
+
const monthly = store.monthly[month];
|
|
173
|
+
if (monthly) {
|
|
174
|
+
subtractSummary(monthly, summary, now);
|
|
175
|
+
if (monthly.sessionCount === 0)
|
|
176
|
+
delete store.monthly[month];
|
|
177
|
+
}
|
|
178
|
+
subtractSummary(store.allTime, summary, now);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Apply a completed session to the daily, hourly, monthly, and all-time
|
|
182
|
+
* buckets and the capped per-session list. Re-applying the same session id
|
|
183
|
+
* replaces its earlier contribution instead of double counting it.
|
|
184
|
+
*
|
|
185
|
+
* Returns the stored per-session record.
|
|
186
|
+
*/
|
|
187
|
+
export function applySessionSummary(store, summary, options = {}) {
|
|
188
|
+
const now = options.now ?? new Date();
|
|
189
|
+
const retentionLimit = options.retentionLimit ?? HISTORICAL_SESSION_RETENTION_LIMIT;
|
|
190
|
+
const date = formatLocalDateKey(new Date(summary.startTime));
|
|
191
|
+
const month = date.substring(0, 7);
|
|
192
|
+
store.sessions ??= [];
|
|
193
|
+
const previous = store.sessions.find((session) => session.sessionId === summary.sessionId);
|
|
194
|
+
if (previous)
|
|
195
|
+
removeSessionSummary(store, previous, now);
|
|
196
|
+
// Daily
|
|
197
|
+
store.daily[date] ??= emptyDaily(date, now);
|
|
198
|
+
accumulateSummary(store.daily[date], summary, now);
|
|
199
|
+
// Hourly (by the session's local start hour)
|
|
200
|
+
store.hourly ??= {};
|
|
201
|
+
store.hourly[date] ??= [];
|
|
202
|
+
const hour = new Date(summary.startTime).getHours();
|
|
203
|
+
let hourly = store.hourly[date].find((entry) => entry.hour === hour);
|
|
204
|
+
if (!hourly) {
|
|
205
|
+
hourly = {
|
|
206
|
+
hour,
|
|
207
|
+
tokens: createEmptyTokenTotals(),
|
|
208
|
+
totalCost: 0,
|
|
209
|
+
messageCount: 0,
|
|
210
|
+
sessionCount: 0,
|
|
211
|
+
};
|
|
212
|
+
store.hourly[date].push(hourly);
|
|
213
|
+
}
|
|
214
|
+
hourly.tokens.inputTokens += summary.tokens.inputTokens;
|
|
215
|
+
hourly.tokens.outputTokens += summary.tokens.outputTokens;
|
|
216
|
+
hourly.tokens.cacheWriteTokens += summary.tokens.cacheWriteTokens;
|
|
217
|
+
hourly.tokens.cacheReadTokens += summary.tokens.cacheReadTokens;
|
|
218
|
+
hourly.totalCost += summary.totalCost;
|
|
219
|
+
hourly.messageCount += summary.messageCount;
|
|
220
|
+
hourly.sessionCount += 1;
|
|
221
|
+
// Monthly
|
|
222
|
+
store.monthly[month] ??= emptyMonthly(month, now);
|
|
223
|
+
accumulateSummary(store.monthly[month], summary, now);
|
|
224
|
+
// All-time
|
|
225
|
+
accumulateSummary(store.allTime, summary, now);
|
|
226
|
+
if (!store.allTime.firstDate || date < store.allTime.firstDate)
|
|
227
|
+
store.allTime.firstDate = date;
|
|
228
|
+
if (!store.allTime.lastDate || date > store.allTime.lastDate)
|
|
229
|
+
store.allTime.lastDate = date;
|
|
230
|
+
const record = {
|
|
231
|
+
sessionId: summary.sessionId,
|
|
232
|
+
provider: summary.provider ?? 'unknown',
|
|
233
|
+
project: summary.project ?? 'unknown',
|
|
234
|
+
startTime: summary.startTime,
|
|
235
|
+
endTime: summary.endTime,
|
|
236
|
+
tokens: { ...summary.tokens },
|
|
237
|
+
totalCost: summary.totalCost,
|
|
238
|
+
messageCount: summary.messageCount,
|
|
239
|
+
modelUsage: summary.modelUsage.map((usage) => ({ ...usage })),
|
|
240
|
+
toolUsage: summary.toolUsage.map((usage) => ({ ...usage })),
|
|
241
|
+
unpricedModelIds: summary.unpricedModelIds ? [...summary.unpricedModelIds] : undefined,
|
|
242
|
+
qualityScore: summary.qualityScore ?? 0,
|
|
243
|
+
qualityFactors: summary.qualityFactors ?? [],
|
|
244
|
+
additions: summary.additions ?? 0,
|
|
245
|
+
deletions: summary.deletions ?? 0,
|
|
246
|
+
costPerChangedLine: summary.costPerChangedLine ?? null,
|
|
247
|
+
};
|
|
248
|
+
store.sessions = [
|
|
249
|
+
...store.sessions.filter((session) => session.sessionId !== summary.sessionId),
|
|
250
|
+
record,
|
|
251
|
+
].slice(-retentionLimit);
|
|
252
|
+
refreshAllTimeDateRange(store);
|
|
253
|
+
return record;
|
|
254
|
+
}
|
|
255
|
+
/** Whether a session file has already been folded into the store. */
|
|
256
|
+
export function isFileImported(store, filePath) {
|
|
257
|
+
return store.importedFiles?.includes(filePath) ?? false;
|
|
258
|
+
}
|
|
259
|
+
/** Record a session file as imported. Returns false when it was already listed. */
|
|
260
|
+
export function markFileImported(store, filePath, now = new Date()) {
|
|
261
|
+
store.importedFiles ??= [];
|
|
262
|
+
if (store.importedFiles.includes(filePath))
|
|
263
|
+
return false;
|
|
264
|
+
store.importedFiles.push(filePath);
|
|
265
|
+
store.lastImportTimestamp = now.toISOString();
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Build the summary the history store expects from unified session stats,
|
|
270
|
+
* so the CLI importer and the extension's first-activation import store the
|
|
271
|
+
* same per-model cost, tool success/failure split, and unpriced markers.
|
|
272
|
+
* Pending tool calls count as successes (stats only split out failures).
|
|
273
|
+
*/
|
|
274
|
+
export function sessionSummaryFromStats(stats, options = {}) {
|
|
275
|
+
const modelUsage = Object.entries(stats.modelUsage).map(([model, usage]) => ({
|
|
276
|
+
model,
|
|
277
|
+
calls: usage.calls,
|
|
278
|
+
tokens: usage.tokens,
|
|
279
|
+
cost: usage.costUsd,
|
|
280
|
+
priced: usage.priced,
|
|
281
|
+
}));
|
|
282
|
+
const unpricedModelIds = modelUsage.filter((m) => m.priced === false).map((m) => m.model);
|
|
283
|
+
const toolUsage = Object.entries(stats.toolUsage).map(([tool, calls]) => {
|
|
284
|
+
const failureCount = stats.toolFailures[tool] ?? 0;
|
|
285
|
+
return { tool, calls, successCount: Math.max(0, calls - failureCount), failureCount };
|
|
286
|
+
});
|
|
287
|
+
return {
|
|
288
|
+
sessionId: stats.sessionId,
|
|
289
|
+
startTime: stats.startTime,
|
|
290
|
+
endTime: stats.endTime || stats.startTime,
|
|
291
|
+
tokens: {
|
|
292
|
+
inputTokens: stats.tokens.input,
|
|
293
|
+
outputTokens: stats.tokens.output,
|
|
294
|
+
cacheWriteTokens: stats.tokens.cacheWrite,
|
|
295
|
+
cacheReadTokens: stats.tokens.cacheRead,
|
|
296
|
+
},
|
|
297
|
+
totalCost: stats.costUsd,
|
|
298
|
+
messageCount: stats.messageCount,
|
|
299
|
+
modelUsage,
|
|
300
|
+
toolUsage,
|
|
301
|
+
...(unpricedModelIds.length > 0 ? { unpricedModelIds } : {}),
|
|
302
|
+
provider: options.provider ?? stats.providerId,
|
|
303
|
+
project: options.project ?? 'unknown',
|
|
304
|
+
};
|
|
305
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One shared definition of "a prompt a person typed" for Claude Code and
|
|
3
|
+
* Codex transcripts. Pure: no filesystem access, so it can classify messages
|
|
4
|
+
* from `readSessionTranscript()` or from `collectPromptHistory()` alike.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Claude Code `entrypoint` values treated as a person at the keyboard:
|
|
8
|
+
* the interactive CLI, Claude Desktop's Code surface, and `claude -p`.
|
|
9
|
+
* `sdk-ts` / `sdk-py` (Agent SDK programs) are excluded.
|
|
10
|
+
*/
|
|
11
|
+
export const HUMAN_CLAUDE_ENTRYPOINTS = Object.freeze([
|
|
12
|
+
'cli',
|
|
13
|
+
'claude-desktop',
|
|
14
|
+
'sdk-cli',
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Codex `session_meta.source` values whose sessions carry typed prompts.
|
|
18
|
+
* Subagent sessions (`{ subagent: … }`) are excluded; they replay parent
|
|
19
|
+
* history. This is a session-level rule applied by `collectPromptHistory()`.
|
|
20
|
+
*/
|
|
21
|
+
export const HUMAN_CODEX_SOURCES = Object.freeze(['cli', 'vscode', 'exec']);
|
|
22
|
+
/** Claude user text that is harness output rather than something typed. */
|
|
23
|
+
const CLAUDE_INJECTED_PREFIX = /^(?:<(?:local-command-stdout|local-command-stderr|local-command-caveat|task-notification|system-reminder|bash-input|bash-stdout|bash-stderr|user-prompt-submit-hook)\b|\[Request interrupted\b|This session is being continued from a previous conversation)/;
|
|
24
|
+
const COMMAND_NAME = /<command-name>\s*([\s\S]*?)\s*<\/command-name>/;
|
|
25
|
+
const COMMAND_ARGS = /<command-args>\s*([\s\S]*?)\s*<\/command-args>/;
|
|
26
|
+
/** Codex user-role blocks injected by the harness (context, instructions, markers). */
|
|
27
|
+
const CODEX_INJECTED_PREFIX = /^(?:# AGENTS\.md instructions\b|<(?:environment_context|user_instructions|recommended_plugins|turn_aborted|skill|subagent_notification|codex_internal_context|user_shell_command|permissions instructions|collaboration_mode)\b)/;
|
|
28
|
+
/** Codex wraps attached images as `<image name=…>` / `</image>` text blocks. */
|
|
29
|
+
const CODEX_IMAGE_WRAPPER = /^<\/?image\b[^>]*>$/;
|
|
30
|
+
/** Whether a canonical transcript message is a prompt a person typed. */
|
|
31
|
+
export function isHumanPrompt(message, provider) {
|
|
32
|
+
return humanPromptText(message, provider) !== null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The visible text of a human prompt, or `null` when the message is not one.
|
|
36
|
+
* Claude slash commands are returned as typed (`/review foo`); Codex image
|
|
37
|
+
* wrappers and injected context blocks are dropped. Text is never truncated.
|
|
38
|
+
*/
|
|
39
|
+
export function humanPromptText(message, provider) {
|
|
40
|
+
if (message.role !== 'user')
|
|
41
|
+
return null;
|
|
42
|
+
if ((message.source.originalRole ?? 'user') !== 'user')
|
|
43
|
+
return null;
|
|
44
|
+
return provider === 'claude-code' ? claudePromptText(message) : codexPromptText(message);
|
|
45
|
+
}
|
|
46
|
+
function claudePromptText(message) {
|
|
47
|
+
const source = message.source;
|
|
48
|
+
if (!source.entrypoint || !HUMAN_CLAUDE_ENTRYPOINTS.includes(source.entrypoint))
|
|
49
|
+
return null;
|
|
50
|
+
if (source.isMeta === true || source.isSidechain === true)
|
|
51
|
+
return null;
|
|
52
|
+
if (source.isCompactSummary === true)
|
|
53
|
+
return null;
|
|
54
|
+
if (source.originKind !== undefined && source.originKind !== 'human')
|
|
55
|
+
return null;
|
|
56
|
+
if (source.promptSource === 'system')
|
|
57
|
+
return null;
|
|
58
|
+
const text = textBlocks(message).join('\n');
|
|
59
|
+
const trimmed = text.trim();
|
|
60
|
+
if (!trimmed)
|
|
61
|
+
return null;
|
|
62
|
+
if (CLAUDE_INJECTED_PREFIX.test(trimmed))
|
|
63
|
+
return null;
|
|
64
|
+
const command = trimmed.match(COMMAND_NAME);
|
|
65
|
+
if (command && /^<command-(?:name|message)>/.test(trimmed)) {
|
|
66
|
+
const name = command[1].trim();
|
|
67
|
+
if (!name)
|
|
68
|
+
return null;
|
|
69
|
+
const args = trimmed.match(COMMAND_ARGS)?.[1].trim() ?? '';
|
|
70
|
+
const visible = name.startsWith('/') ? name : `/${name}`;
|
|
71
|
+
return args ? `${visible} ${args}` : visible;
|
|
72
|
+
}
|
|
73
|
+
return text;
|
|
74
|
+
}
|
|
75
|
+
function codexPromptText(message) {
|
|
76
|
+
const typed = textBlocks(message).filter((text) => {
|
|
77
|
+
const trimmed = text.trim();
|
|
78
|
+
return (trimmed.length > 0 &&
|
|
79
|
+
!CODEX_INJECTED_PREFIX.test(trimmed) &&
|
|
80
|
+
!CODEX_IMAGE_WRAPPER.test(trimmed));
|
|
81
|
+
});
|
|
82
|
+
return typed.length > 0 ? typed.join('\n') : null;
|
|
83
|
+
}
|
|
84
|
+
function textBlocks(message) {
|
|
85
|
+
return message.content
|
|
86
|
+
.filter((block) => block.type === 'text' && typeof block.text === 'string')
|
|
87
|
+
.map((block) => block.text);
|
|
88
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API for sidekick-shared.
|
|
3
|
+
*/
|
|
4
|
+
export { normalizeProviderUsage, extractNormalizedUsage, calculateNormalizedUsageCost, } from './usageNormalization';
|
|
5
|
+
export { formatTokenBreakdown, summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_MAIN_THREAD_LABEL, TOKEN_SESSION_TOTAL_LABEL, TOKEN_SUBAGENTS_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
|
|
6
|
+
export { ASCII_CHARS_PER_TOKEN, estimateTextTokens, estimateSerializedTokens, } from './tokenEstimation';
|
|
7
|
+
export { projectSessionTranscript } from './transcript';
|
|
8
|
+
export { listRecentSessions, readSessionTranscript } from './sessionTranscripts';
|
|
9
|
+
export { collectPromptHistory, isPromptHistorySessionSettled, parsePromptHistoryCursor, } from './promptHistory';
|
|
10
|
+
export { collectSessionPromptHistory } from './sessionPromptHistory';
|
|
11
|
+
export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
|
|
12
|
+
export { computeSessionFileStats, firstUserPrompt, providerContextSizeFn, readSessionFileStats, } from './sessionStats';
|
|
13
|
+
export { readSessionReportInputs } from './report/sessionReportInputs';
|
|
14
|
+
export { fingerprintString, sessionFingerprintParts } from './sessionFingerprint';
|
|
15
|
+
export { STATE_FILE_NAME, STATE_FILE_SCHEMA_VERSION, billingBlockToStateFile, getStateFilePath, quotaToStateFile, readStateFile, writeStateFile, } from './stateFile';
|
|
16
|
+
export { BILLING_BLOCK_DURATION_MS, computeBillingBlocks, findActiveBillingBlock, } from './usage/billingBlocks';
|
|
17
|
+
export { MAX_USAGE_CACHE_FILES, USAGE_CACHE_VERSION, collectUsageEvents, getUsageCacheDir, pruneUsageCache, } from './usage/usageEvents';
|
|
18
|
+
export { applySessionSummary, isFileImported, markFileImported, removeSessionSummary, sessionSummaryFromStats, } from './historicalStore';
|
|
19
|
+
export { ACTIVE_SESSION_MTIME_THRESHOLD_MS, importSessionHistory, } from './usage/importSessionHistory';
|
|
20
|
+
export { bucketUsage, summarizeUsageRows, usageBucketKey, weekKey } from './usage/usageReports';
|
|
21
|
+
export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, fileFingerprintParts, } from './observedSessionCollector';
|
|
22
|
+
export { DirectoryListingCache, splitWatchedPath } from './providers/directoryListingCache';
|
|
23
|
+
export { isAggregateCodexLimit } from './types/codex';
|
|
24
|
+
export { TASK_PERSISTENCE_SCHEMA_VERSION, normalizeTaskStatus } from './types/taskPersistence';
|
|
25
|
+
export { DECISION_LOG_SCHEMA_VERSION } from './types/decisionLog';
|
|
26
|
+
export { KNOWLEDGE_NOTE_SCHEMA_VERSION, IMPORTANCE_DECAY_FACTORS, STALENESS_THRESHOLDS, } from './types/knowledgeNote';
|
|
27
|
+
export { HISTORICAL_DATA_SCHEMA_VERSION, HISTORICAL_SESSION_RETENTION_LIMIT, createEmptyTokenTotals, createEmptyDataStore, } from './types/historicalData';
|
|
28
|
+
export { PLAN_SCHEMA_VERSION, MAX_PLANS_PER_PROJECT } from './types/plan';
|
|
29
|
+
// Paths
|
|
30
|
+
export { CONFIG_DIR_ENV_VAR, getConfigDir, getConfigDirOverride, getDefaultConfigDir, setConfigDir, getProjectDataPath, getGlobalDataPath, encodeWorkspacePath, getProjectSlug, getProjectSlugRaw, resolveProjectIdentity, } from './paths';
|
|
31
|
+
export { migrateLegacyProjectStores } from './projectMigration';
|
|
32
|
+
// Readers
|
|
33
|
+
export { readTasks } from './readers/tasks';
|
|
34
|
+
export { readDecisions } from './readers/decisions';
|
|
35
|
+
export { readNotes } from './readers/notes';
|
|
36
|
+
export { readHistory } from './readers/history';
|
|
37
|
+
export { readLatestHandoff } from './readers/handoff';
|
|
38
|
+
export { readPlans, getLatestPlan, writePlans, getPlanAnalytics, readClaudeCodePlanFiles, } from './readers/plans';
|
|
39
|
+
// Atomic persistence writers
|
|
40
|
+
export { atomicWriteJson, atomicWriteJsonSync, atomicWriteFileSync, updateJsonStoreAtomic, updateJsonStoreAtomicSync, withFileLockSync, } from './writers/atomic';
|
|
41
|
+
export { addTask, completeTask } from './writers/tasks';
|
|
42
|
+
export { addDecision, decisionFingerprint } from './writers/decisions';
|
|
43
|
+
export { addNote } from './writers/notes';
|
|
44
|
+
export { renderHandoffUrlTemplate } from './handoffUrl';
|
|
45
|
+
export { SESSION_PROVIDER_IDS } from './providers/types';
|
|
46
|
+
export { createSessionProviders } from './providers/factory';
|
|
47
|
+
export { createProviderSessionAdapterV1, derivePendingUserRequestV1, getObservedActivityReason, } from './types/observedSessionV1';
|
|
48
|
+
export { _resetProviderDetectionCache, detectProvider, getAllDetectedProviders, } from './providers/detect';
|
|
49
|
+
export { ClaudeCodeProvider } from './providers/claudeCode';
|
|
50
|
+
export { OpenCodeProvider, getOpenCodeDataDir } from './providers/openCode';
|
|
51
|
+
export { CodexProvider, findCodexRolloutFile } from './providers/codex';
|
|
52
|
+
export { walkRolloutFiles, walkRolloutFilesAsync } from './providers/rolloutWalker';
|
|
53
|
+
// Parsers — JSONL
|
|
54
|
+
export { JsonlParser, TRUNCATION_PATTERNS } from './parsers/jsonl';
|
|
55
|
+
// Parsers — OpenCode
|
|
56
|
+
export { normalizeToolName, normalizeToolInput, detectPlanModeFromText, convertOpenCodeMessage, parseDbMessageData, parseDbPartData, } from './parsers/openCodeParser';
|
|
57
|
+
// Parsers — Codex
|
|
58
|
+
export { CodexRolloutParser, DEFAULT_MAX_TRACKED_TOOL_CALLS, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
|
|
59
|
+
// Parsers — Subagent scanning
|
|
60
|
+
export { scanSubagentDir, extractTaskInfo, readAgentMeta } from './parsers/subagentScanner';
|
|
61
|
+
// Usage — split-line dedupe, subagent tokens, session totals
|
|
62
|
+
export { ClaudeUsageDeduper, SYNTHETIC_MODEL, dedupedRawClaudeUsage, normalizeClaudeUsage, } from './usage/claudeUsageDedupe';
|
|
63
|
+
export { addUsageToSubagent } from './usage/subagentUsage';
|
|
64
|
+
export { collectSessionTokenTotals, combineSessionTokenTotals, readMainThreadTokenTotals, scanSessionSubagents, subagentTokenTotals, } from './sessionTokenTotals';
|
|
65
|
+
// Parsers — Session activity detection
|
|
66
|
+
export { classifySessionActivity, detectSessionActivity, refreshSessionActivityState, SESSION_ACTIVITY_GRACE_PERIOD_MS, SESSION_ACTIVITY_STALENESS_MS, } from './parsers/sessionActivityDetector';
|
|
67
|
+
// Parsers — Session path resolution (Claude Code)
|
|
68
|
+
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';
|
|
69
|
+
// Parsers — Subagent traces
|
|
70
|
+
export { scanSubagentTraces } from './parsers/subagentTraceParser';
|
|
71
|
+
// Parsers — MCP tool names
|
|
72
|
+
export { parseMcpToolName } from './parsers/mcpToolName';
|
|
73
|
+
// Parsers — Codex native history
|
|
74
|
+
export { readCodexHistory } from './parsers/codexHistory';
|
|
75
|
+
// Session previews (bounded, stat-first)
|
|
76
|
+
export { listSessionPreviews, listSessionPreviewsAsync, readSessionPreview, readSessionPreviewAsync, } from './sessionPreviews';
|
|
77
|
+
// Parsers — Debug log parsing
|
|
78
|
+
export { parseDebugLog, filterByLevel, collapseDuplicates, discoverDebugLogs, } from './parsers/debugLogParser';
|
|
79
|
+
// Database wrappers
|
|
80
|
+
export { OpenCodeDatabase } from './providers/openCodeDatabase';
|
|
81
|
+
export { CodexDatabase } from './providers/codexDatabase';
|
|
82
|
+
// Search
|
|
83
|
+
export { searchSessions } from './search/sessionSearch';
|
|
84
|
+
export { FilterEngine } from './search/advancedFilter';
|
|
85
|
+
// Context
|
|
86
|
+
export { composeContext } from './context/composer';
|
|
87
|
+
export { buildSessionContextSnapshot, calculateSessionContextPressure, createSessionContextProjector, readSessionContextSnapshot, } from './context/sessionContext';
|
|
88
|
+
// Assistant turn projection
|
|
89
|
+
export { assistantTurnEventsFromSessionEvents, extractTurnSubagents, isAssistantTurnSubagentTool, reasoningSummary, segmentAssistantTurn, } from './turns/assistantTurn';
|
|
90
|
+
// Plan Extraction
|
|
91
|
+
export { PlanExtractor, parsePlanMarkdown as parsePlanMarkdownShared, extractProposedPlan as extractProposedPlanShared, } from './parsers/planExtractor';
|
|
92
|
+
// Changelog Parsing
|
|
93
|
+
export { parseChangelog } from './parsers/changelogParser';
|
|
94
|
+
export { createWatcher, resolveSessionPath } from './watchers/factory';
|
|
95
|
+
export { toFollowEvents } from './watchers/eventBridge';
|
|
96
|
+
export { createJsonlTail, DEFAULT_JSONL_TAIL_MAX_LINE_BYTES, DEFAULT_JSONL_TAIL_READ_BYTES, } from './watchers/jsonlTail';
|
|
97
|
+
// Formatters
|
|
98
|
+
export { addLocalDays, formatDurationMs, formatLocalDateKey, formatTokenCount, parseLocalDateKey, } from './formatting';
|
|
99
|
+
export { formatToolSummary } from './formatters/toolSummary';
|
|
100
|
+
export { isHardNoise, isHardNoiseFollowEvent, getSoftNoiseReason, classifyMessage, classifyFollowEvent, shouldMergeWithPrevious, classifyNoise, } from './formatters/noiseClassifier';
|
|
101
|
+
export { formatSessionText, formatSessionMarkdown, formatSessionJson, } from './formatters/sessionDump';
|
|
102
|
+
export { highlight as highlightEvent, clearHighlightCache, HIGHLIGHT_CSS, } from './formatters/eventHighlighter';
|
|
103
|
+
// Phrases
|
|
104
|
+
export { ALL_PHRASES, PHRASE_CATEGORIES, getRandomPhrase } from './phrases';
|
|
105
|
+
// Aggregation
|
|
106
|
+
export { EventAggregator, parseTodoDependencies } from './aggregation/EventAggregator';
|
|
107
|
+
export { SessionMonitor } from './sessionMonitor';
|
|
108
|
+
export { saveSnapshot, loadSnapshot, deleteSnapshot, isSnapshotValid, pruneSnapshots, MAX_SNAPSHOT_FILES, getSnapshotPath, } from './aggregation/snapshot';
|
|
109
|
+
export { ERROR_HISTORY_SCHEMA_VERSION, MAX_ERROR_HISTORY_SESSIONS, appendErrorHistory, getTopFailingTools, readErrorHistory, } from './errorHistory';
|
|
110
|
+
// Aggregation — analytics engines
|
|
111
|
+
export { FrequencyTracker } from './aggregation/FrequencyTracker';
|
|
112
|
+
export { HeatmapTracker } from './aggregation/HeatmapTracker';
|
|
113
|
+
export { PatternExtractor } from './aggregation/PatternExtractor';
|
|
114
|
+
export { calculateQualityTrend, scoreSessionQuality } from './analytics/qualityScore';
|
|
115
|
+
export { calculateCodeImpact } from './analytics/codeImpact';
|
|
116
|
+
export { classifyCostProvenance, describeCostProvenance } from './aggregation/costProvenance';
|
|
117
|
+
export { calculateCompactionLedger, formatCompactionLedger } from './analytics/compactionLedger';
|
|
118
|
+
// Report — HTML session report generation
|
|
119
|
+
export { generateHtmlReport, parseTranscript, parseTranscriptFromEvents, openInBrowser, } from './report';
|
|
120
|
+
// Credential I/O (platform-aware: Keychain on macOS, file on Linux/Windows)
|
|
121
|
+
export { readActiveCredentials, readClaudeCredentialStore, writeActiveCredentials, deleteStoredCredentials, ClaudeCredentialWriteError, SIDEKICK_KEYCHAIN_COMMENT_PREFIX, } from './credentialIO';
|
|
122
|
+
export { decideLiveClaudeWrite } from './claudeLiveGuard';
|
|
123
|
+
export { readClaudeCredentialLedger, getClaudeCredentialLedgerPath, } from './claudeCredentialLedger';
|
|
124
|
+
export { inspectClaudeCredentialStores, repairClaudeCredentialStores, parseKeychainDump, } from './claudeCredentialDoctor';
|
|
125
|
+
// Credentials
|
|
126
|
+
export { readClaudeMaxCredentials, readClaudeMaxCredentialsRaw, readClaudeMaxAccessTokenSync, } from './credentials';
|
|
127
|
+
export { parseClaudeCredentialBlob, claudeCredentialFreshness, isNewerClaudeCredential, resolveClaudeRefreshExpiry, claudeRefreshFingerprint, claudeLoginOnly, mergeClaudeLoginIntoLive, CLAUDE_ACCESS_TOKEN_LIFETIME_MS, CLAUDE_REFRESH_TOKEN_LIFETIME_ESTIMATE_MS, } from './claudeCredentials';
|
|
128
|
+
export { parseAuthJson as parseCodexAuthJson, readAuthIdentityFromRaw as readCodexAuthIdentity, readLastRefresh as readCodexLastRefresh, readAccessTokenExpiry as readCodexAccessTokenExpiry, identitiesMatch as codexIdentitiesMatch, } from './codexAuth';
|
|
129
|
+
// Accounts
|
|
130
|
+
export { ensureDefaultAccounts } from './ensureDefaultAccounts';
|
|
131
|
+
export { readAccountRegistry, writeAccountRegistry, readActiveClaudeAccount, addCurrentAccount, switchToAccount, switchToAccountAsync, syncClaudeLiveState, cleanupAbandonedClaudeLogins, resolveActiveClaudeHome, applyActiveClaudeToLiveHome, reconcileClaudeAuthState, removeAccount, listAccounts, getActiveAccount, resolveActiveClaudeAccount, isMultiAccountEnabled, } from './accounts';
|
|
132
|
+
export { beginAccountLogin, getAccountLoginStatus, getAccountLoginStatusAsync, finalizeAccountLogin, finalizeAccountLoginAsync, spawnAccountLogin, switchAccount, switchAccountAsync, undoLastSwitch, getLastSwitch, listAllAccounts, resolveClaudeLoginCommand, discardAccountLogin, } from './accountManager';
|
|
133
|
+
export { readLastSwitch, getLastSwitchPath } from './accountSwitch';
|
|
134
|
+
export { syncLiveAccountState, syncLiveAccountStateSync, cleanupAbandonedLogins, } from './accountSync';
|
|
135
|
+
export { getAccountHealth, listAccountsWithHealth, readHealthSidecar, getHealthSidecarPath, } from './accountHealth';
|
|
136
|
+
export { getAccountLaunchEnv } from './accountLaunch';
|
|
137
|
+
export { refreshInactiveAccounts, keepAliveCommand } from './keepAlive';
|
|
138
|
+
export { findRunningProcesses, findRunningProcessesSync, detectRunningAccountConsumers, detectRunningAccountConsumersSync, describeAccountConsumer, ACCOUNT_CONSUMER_REACHABILITY, } from './processDetection';
|
|
139
|
+
export { getAccountsDir, readSavedAccountRegistry, writeSavedAccountRegistry, listSavedAccountProfiles, getActiveSavedAccount, upsertSavedAccountProfile, setActiveSavedAccount, replaceSavedAccountProfiles, removeSavedAccountProfile, } from './accountRegistry';
|
|
140
|
+
export { ACCOUNT_PROVIDER_IDS } from './accountRegistry';
|
|
141
|
+
export { getActiveAccountStatus } from './accountStatus';
|
|
142
|
+
export { onAccountsChanged } from './accountChanges';
|
|
143
|
+
export { getClaudeProfilesDir, getClaudeProfileHome, getClaudeConfigPath, claudeKeychainSuffix, claudeKeychainService, claudeKeychainAccountName, buildClaudeChildEnv, CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV, isClaudeProfileAuthenticated, readClaudeProfileIdentity, readLiveClaudeIdentity, } from './claudeProfiles';
|
|
144
|
+
export { getLiveClaudeHome, getDefaultClaudeHome, isDefaultClaudeHome, getClaudeProjectsDir, } from './claudePaths';
|
|
145
|
+
export { getCodexProfilesDir, getCodexProfileHome, getCodexMonitoringHomes, getSystemCodexHome, listCodexAccounts, getActiveCodexAccount, resolveActiveCodexAccount, resolveSidekickCodexHome, getCodexExecutionEnv, prepareCodexAccount, prepareCodexAccountAsync, finalizeCodexAccount, finalizeCodexAccountAsync, switchToCodexAccount, switchToCodexAccountAsync, removeCodexAccount, syncCodexLiveState, cleanupAbandonedCodexLogins, getCodexCredentialStoreMode, CODEX_KEYRING_FIX_HINT, } from './codexProfiles';
|
|
146
|
+
export { writeAccountLauncher, writeLauncher, removeLauncher } from './terminalSync';
|
|
147
|
+
export { DEFAULT_AUTO_SWITCH_CONFIG, decideAutoSwitch, AutoSwitchController } from './autoSwitch';
|
|
148
|
+
// Quota
|
|
149
|
+
export { FIVE_HOUR_WINDOW_MS, QUOTA_PROVIDER_IDS, SEVEN_DAY_WINDOW_MS, fetchQuota, projectQuotaWindow, withQuotaProjections, } from './quota';
|
|
150
|
+
export { describeQuotaFailure } from './quotaPresentation';
|
|
151
|
+
export { QuotaPoller } from './quotaPoller';
|
|
152
|
+
export { readQuotaSnapshot, writeQuotaSnapshot } from './quotaSnapshots';
|
|
153
|
+
export { resolveQuota } from './quotaResolver';
|
|
154
|
+
export { classifyQuotaFreshness, formatQuotaAge, QUOTA_AGING_MAX_AGE_MS, QUOTA_FRESH_MAX_AGE_MS, } from './quota';
|
|
155
|
+
export { DEFAULT_QUOTA_THRESHOLDS, describeQuotaThresholdAlert, evaluateQuotaThresholds, } from './quotaThresholds';
|
|
156
|
+
export { parseClaudeStatuslinePayload, quotaFromStatuslinePayload, } from './statusline/claudeStatuslinePayload';
|
|
157
|
+
export { appendQuotaHistorySample, readQuotaHistoryRange, readQuotaHistoryDailyBuckets, pruneQuotaHistory, getWorkspaceIdFromPath, } from './quotaHistory';
|
|
158
|
+
export { fetchCodexResetCreditsFromApi, fetchCodexQuotaFromApi, quotaFromCodexRateLimits, readLatestCodexQuotaFromRollouts, resolveCodexQuota, resolveCodexQuotaFromLocalSources, } from './codexQuota';
|
|
159
|
+
export { CodexQuotaWatcher } from './codexQuotaWatcher';
|
|
160
|
+
export { fetchZaiQuotaFromApi, quotaStateFromZaiQuotaLimitPayload, readZaiCredentials, resolveZaiQuota, } from './zaiQuotaApi';
|
|
161
|
+
export { MultiProviderQuotaService } from './multiProviderQuotaService';
|
|
162
|
+
export { RUNTIME_QUOTA_PROVIDER_IDS } from './providerQuota';
|
|
163
|
+
export { BurnRateCalculator, estimateTimeToQuota } from './statusline/BurnRateCalculator';
|
|
164
|
+
export { formatStatusline, selectStatuslineAccount } from './statusline/formatter';
|
|
165
|
+
// Model Context
|
|
166
|
+
export { getModelContextWindowSize, resolveModelContextWindow, DEFAULT_CONTEXT_WINDOW, } from './modelContext';
|
|
167
|
+
// Model Info & Pricing
|
|
168
|
+
export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, MODEL_PROVIDER_IDS, } from './modelInfo';
|
|
169
|
+
export { exportResolvedModelCatalog, importResolvedModelCatalog, registerModelAlias, resolveModelAlias, RESOLVED_MODEL_CATALOG_SCHEMA_VERSION, } from './modelCatalog';
|
|
170
|
+
// Pricing Catalog (LiteLLM hydration) — Node-only. Safe for extension host
|
|
171
|
+
// and CLI; do NOT import from browser bundles (webviews).
|
|
172
|
+
export { hydratePricingCatalog, normalizeLiteLlmCatalog, normalizeLiteLlmContextWindows, LITELLM_CATALOG_URL, } from './pricingCatalog';
|
|
173
|
+
// Observed context windows (provider-reported, persisted) — Node-only.
|
|
174
|
+
export { loadObservedContextWindows, recordObservedContextWindow, getObservedContextWindowPath, } from './observedContextWindows';
|
|
175
|
+
// Extractors — per-event token usage and tool call extraction
|
|
176
|
+
export { extractTokenUsage } from './extractors/tokenUsage';
|
|
177
|
+
// Extractors — actionable session assets. Node-only: safe for CLI and
|
|
178
|
+
// extension-host code, not for browser/webview bundles.
|
|
179
|
+
export { extractUrls, extractFilePaths, extractCommands } from './extractors/sessionAssets';
|
|
180
|
+
export { readClaudeAssets, claudeSessions } from './extractors/sources/claudeAssets';
|
|
181
|
+
export { readCodexAssets, codexSessions } from './extractors/sources/codexAssets';
|
|
182
|
+
export { gatherAssetsForCwd } from './extractors/gatherAssets';
|
|
183
|
+
export { categorizeError, extractErrorMessage } from './extractors/errorTaxonomy';
|
|
184
|
+
export { extractToolCall, extractToolCalls, ToolCallTracker } from './extractors/toolCall';
|
|
185
|
+
// Schemas — Zod runtime validation for session events
|
|
186
|
+
export { messageUsageSchema, sessionMessageSchema, sessionEventSchema, permissionModeSchema, extractSessionEvents, } from './schemas/sessionEvent';
|
|
187
|
+
// Schemas — Zod runtime validation for quota / provider quota / peak hours
|
|
188
|
+
export { quotaWindowSchema, quotaStateSchema, quotaFailureKindSchema, quotaProviderIdSchema, quotaSourceSchema, codexResetCreditSchema, codexResetCreditsSnapshotSchema, peakHoursStateSchema, quotaFailureDescriptorSchema, runtimeQuotaProviderSchema, providerQuotaStateSchema, claudeProviderQuotaStateSchema, codexProviderQuotaStateSchema, zaiProviderQuotaStateSchema, providerQuotaMapSchema, } from './schemas/quota';
|
|
189
|
+
// Schemas — Zod runtime validation for quota history
|
|
190
|
+
export { quotaHistoryRuntimeProviderSchema, quotaHistorySampleSchema, quotaHistoryDailyBucketSchema, } from './schemas/quotaHistory';
|
|
191
|
+
// Schemas — Zod runtime validation for provider-failure diagnoses
|
|
192
|
+
export { providerAuthenticationEvidenceSchema, providerFailureEvidenceSchema, providerRetryAfterSchema, providerFailureDiagnosisSchema, } from './schemas/providerFailure';
|
|
193
|
+
// Schemas — Zod runtime validation for account status
|
|
194
|
+
export { activeProviderAccountStatusSchema, activeAccountStatusSchema, } from './schemas/accountStatus';
|
|
195
|
+
export { accountProviderIdSchema, accountManagerResultSchema, beginAccountLoginResultSchema, accountLoginStatusSchema, accountEntrySchema, savedAccountProfileSchema, listAllAccountsResultSchema, } from './schemas/accountManager';
|
|
196
|
+
export { assistantTurnEventSchema, assistantTurnEventTypeSchema, assistantTurnNarrationStepSchema, assistantTurnProcessSchema, assistantTurnProcessStepSchema, assistantTurnProjectionSchema, assistantTurnReasoningTimelineItemSchema, assistantTurnSubagentSchema, assistantTurnSubagentStatusSchema, assistantTurnTimelineItemSchema, assistantTurnToolGroupStepSchema, assistantTurnToolRefSchema, } from './schemas/assistantTurn';
|
|
197
|
+
// Provider Status
|
|
198
|
+
export { fetchProviderStatus, fetchOpenAIStatus, toLegacyProviderStatus } from './providerStatus';
|
|
199
|
+
// Shared diagnostics / health report
|
|
200
|
+
export { formatHealthReport, getSessionDiagnostics, runDoctor } from './doctor';
|
|
201
|
+
// Peak Hours (PromoClock — third-party)
|
|
202
|
+
export { _resetPeakHoursCache, createPeakHoursNotApplicableState, DEFAULT_PEAK_HOURS_TIMEOUT_MS, fetchPeakHoursStatus, getScheduledPeakHoursState, isClaudeCodeSessionProvider, PEAK_HOURS_CACHE_MS, PEAK_HOURS_DESCRIPTION, scopePeakHoursToSessionProvider, } from './peakHours';
|
|
203
|
+
export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
|
|
204
|
+
export { diagnoseProviderFailure, PROVIDER_AUTHENTICATION_SOURCES, PROVIDER_AUTHENTICATION_STATES, PROVIDER_CREDENTIAL_KINDS, PROVIDER_FAILURE_CODES, PROVIDER_FAILURE_EVIDENCE_SOURCES, PROVIDER_RECOVERY_ACTIONS, } from './providerFailure';
|
|
205
|
+
export { fetchProviderServiceStatus } from './providerServiceStatus';
|
|
206
|
+
export { inspectCodexCredentialStores, repairCodexCredentialStores } from './codexCredentialDoctor';
|
|
207
|
+
export { readStoredCodexAccount, syncCodexLiveStateAsync } from './codexProfiles';
|
|
208
|
+
// Codex rollout directories (live and archived)
|
|
209
|
+
export { getCodexSessionsDirs, CODEX_SESSIONS_SUBDIR, CODEX_ARCHIVED_SESSIONS_SUBDIR, } from './codexPaths';
|
|
210
|
+
// Tool categories across providers
|
|
211
|
+
export { classifyTool, TOOL_CATEGORIES } from './toolCategory';
|
|
212
|
+
// Workspace roots (realpath plus git worktree expansion)
|
|
213
|
+
export { resolveWorkspaceRoots } from './workspaceRoots';
|