sidekick-shared 0.27.2 → 0.27.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +57 -14
  3. package/dist/aggregation/EventAggregator.d.ts +12 -2
  4. package/dist/aggregation/EventAggregator.js +49 -19
  5. package/dist/browser.d.ts +2 -1
  6. package/dist/browser.js +9 -2
  7. package/dist/extractors/tokenUsage.js +1 -0
  8. package/dist/formatters/sessionDump.d.ts +10 -2
  9. package/dist/formatters/sessionDump.js +45 -23
  10. package/dist/index.d.ts +7 -3
  11. package/dist/index.js +31 -10
  12. package/dist/node.d.ts +6 -1
  13. package/dist/node.js +12 -2
  14. package/dist/parsers/codexParser.d.ts +22 -2
  15. package/dist/parsers/codexParser.js +64 -5
  16. package/dist/parsers/subagentScanner.d.ts +9 -0
  17. package/dist/parsers/subagentScanner.js +45 -12
  18. package/dist/parsers/subagentStatsCache.d.ts +17 -0
  19. package/dist/parsers/subagentStatsCache.js +82 -0
  20. package/dist/parsers/subagentTraceParser.js +19 -10
  21. package/dist/providers/claudeCode.js +8 -41
  22. package/dist/providers/codex.js +28 -14
  23. package/dist/providers/codexDatabase.d.ts +16 -1
  24. package/dist/providers/codexDatabase.js +49 -1
  25. package/dist/providers/openCode.js +30 -4
  26. package/dist/report/htmlReportGenerator.js +33 -11
  27. package/dist/report/sessionReportInputs.d.ts +3 -1
  28. package/dist/report/sessionReportInputs.js +2 -0
  29. package/dist/report/types.d.ts +5 -0
  30. package/dist/schemas/sessionEvent.d.ts +30 -6
  31. package/dist/schemas/sessionEvent.js +7 -1
  32. package/dist/schemas/stateFile.d.ts +2 -0
  33. package/dist/schemas/stateFile.js +1 -0
  34. package/dist/sessionTokenTotals.d.ts +46 -0
  35. package/dist/sessionTokenTotals.js +138 -0
  36. package/dist/stateFile.d.ts +7 -0
  37. package/dist/tokenSummary.d.ts +27 -1
  38. package/dist/tokenSummary.js +50 -3
  39. package/dist/types/codex.d.ts +4 -0
  40. package/dist/types/sessionEvent.d.ts +22 -0
  41. package/dist/usage/claudeUsageDedupe.d.ts +53 -0
  42. package/dist/usage/claudeUsageDedupe.js +195 -0
  43. package/dist/usage/subagentUsage.d.ts +13 -0
  44. package/dist/usage/subagentUsage.js +21 -0
  45. package/dist/usage/usageEvents.d.ts +18 -2
  46. package/dist/usage/usageEvents.js +83 -8
  47. package/dist/watchers/eventBridge.js +5 -0
  48. package/dist/watchers/jsonlWatcher.d.ts +5 -0
  49. package/dist/watchers/jsonlWatcher.js +40 -5
  50. package/dist/watchers/types.d.ts +5 -0
  51. package/package.json +1 -1
@@ -18,12 +18,19 @@ exports.formatDuration = formatDuration;
18
18
  const costProvenance_1 = require("../aggregation/costProvenance");
19
19
  const formatting_1 = require("../formatting");
20
20
  const tokenSummary_1 = require("../tokenSummary");
21
+ const sessionTokenTotals_1 = require("../sessionTokenTotals");
22
+ /** Main thread (the aggregated transcript) plus the session's subagents. */
23
+ function sessionTokens(metrics, options) {
24
+ return (0, sessionTokenTotals_1.combineSessionTokenTotals)(metrics.tokens, options.subagents ?? []);
25
+ }
21
26
  // ── JSON output ──
22
27
  /**
23
- * Serialize aggregated metrics as pretty-printed JSON.
28
+ * Serialize aggregated metrics as pretty-printed JSON, plus a `tokenSummary`
29
+ * block in the shared vocabulary: `mainThread`, per-subagent summaries,
30
+ * `subagentTotal`, and `combined` (main thread plus subagents).
24
31
  */
25
- function formatSessionJson(metrics) {
26
- return JSON.stringify(metrics, null, 2) + '\n';
32
+ function formatSessionJson(metrics, options = {}) {
33
+ return (JSON.stringify({ ...metrics, tokenSummary: sessionTokens(metrics, options) }, null, 2) + '\n');
27
34
  }
28
35
  // ── Text output ──
29
36
  /**
@@ -40,13 +47,13 @@ function formatSessionText(metrics, options = {}) {
40
47
  lines.push(hr);
41
48
  lines.push('');
42
49
  // Token summary
43
- lines.push(formatTokenSummary(metrics));
50
+ lines.push(...formatTokenSummary(metrics, sessionTokens(metrics, options)));
44
51
  lines.push('');
45
52
  // Model stats
46
53
  if (metrics.modelStats.length > 0) {
47
54
  lines.push('Models:');
48
55
  for (const m of metrics.modelStats) {
49
- lines.push(` ${m.model}: ${m.calls} calls, ${fmtTokens(m.tokens)} tokens, ${fmtCost(m.cost)}`);
56
+ lines.push(` ${m.model}: ${m.calls} calls, ${fmtTokens(m.tokens)} total incl. cache, ${fmtCost(m.cost)}`);
50
57
  }
51
58
  lines.push('');
52
59
  }
@@ -70,7 +77,7 @@ function formatSessionText(metrics, options = {}) {
70
77
  parts.push(`${metrics.compactionCount} compaction(s)`);
71
78
  if (metrics.truncationCount > 0)
72
79
  parts.push(`${metrics.truncationCount} truncation(s)`);
73
- lines.push(`Context: ${parts.join(', ')}`);
80
+ lines.push(`Context management: ${parts.join(', ')}`);
74
81
  lines.push('');
75
82
  }
76
83
  // Timeline
@@ -130,7 +137,18 @@ function formatSessionMarkdown(metrics, options = {}) {
130
137
  lines.push(`| Output | ${fmtTokens(metrics.tokens.outputTokens)} |`);
131
138
  lines.push(`| Cache write | ${fmtTokens(metrics.tokens.cacheWriteTokens)} |`);
132
139
  lines.push(`| Cache read | ${fmtTokens(metrics.tokens.cacheReadTokens)} |`);
133
- lines.push(`| ${tokenSummary_1.TOKEN_TOTAL_LABEL} | ${fmtTokens((0, tokenSummary_1.summarizeTokens)(metrics.tokens).total)} |`);
140
+ const tokens = sessionTokens(metrics, options);
141
+ if (tokens.mainThread.billedOutsideBuckets > 0) {
142
+ lines.push(`| Reasoning (billed separately) | ${fmtTokens(tokens.mainThread.billedOutsideBuckets)} |`);
143
+ }
144
+ if (tokens.subagents.length > 0) {
145
+ lines.push(`| ${tokenSummary_1.TOKEN_MAIN_THREAD_LABEL} — ${tokenSummary_1.TOKEN_TOTAL_LABEL} | ${fmtTokens(tokens.mainThread.total)} |`);
146
+ lines.push(`| ${tokenSummary_1.TOKEN_SUBAGENTS_LABEL} (${tokens.subagents.length}) — ${tokenSummary_1.TOKEN_TOTAL_LABEL} | ${fmtTokens(tokens.subagentTotal.total)} |`);
147
+ lines.push(`| **${tokenSummary_1.TOKEN_SESSION_TOTAL_LABEL}** | **${fmtTokens(tokens.combined.total)}** |`);
148
+ }
149
+ else {
150
+ lines.push(`| ${tokenSummary_1.TOKEN_TOTAL_LABEL} | ${fmtTokens(tokens.mainThread.total)} |`);
151
+ }
134
152
  if (metrics.tokens.costUsd > 0) {
135
153
  lines.push(`| Cost | ${fmtCost(metrics.tokens.costUsd)} (${(0, costProvenance_1.describeCostProvenance)(metrics.tokens)}) |`);
136
154
  }
@@ -142,7 +160,7 @@ function formatSessionMarkdown(metrics, options = {}) {
142
160
  if (metrics.modelStats.length > 0) {
143
161
  lines.push('## Models');
144
162
  lines.push('');
145
- lines.push(`| Model | Calls | Tokens | Cost |`);
163
+ lines.push(`| Model | Calls | ${tokenSummary_1.TOKEN_TOTAL_LABEL} | Cost |`);
146
164
  lines.push(`|-------|-------|--------|------|`);
147
165
  for (const m of metrics.modelStats) {
148
166
  lines.push(`| ${m.model} | ${m.calls} | ${fmtTokens(m.tokens)} | ${fmtCost(m.cost)} |`);
@@ -190,6 +208,16 @@ function formatSessionMarkdown(metrics, options = {}) {
190
208
  }
191
209
  lines.push('');
192
210
  }
211
+ if (tokens.subagents.length > 0) {
212
+ lines.push('## Subagent Tokens');
213
+ lines.push('');
214
+ lines.push(`| Agent | Type | Description | ${tokenSummary_1.TOKEN_TOTAL_LABEL} |`);
215
+ lines.push(`|-------|------|-------------|--------|`);
216
+ for (const agent of tokens.subagents) {
217
+ lines.push(`| ${agent.agentId} | ${agent.agentType ?? '-'} | ${agent.description ?? '-'} | ${fmtTokens(agent.summary.total)} |`);
218
+ }
219
+ lines.push('');
220
+ }
193
221
  // Timeline
194
222
  lines.push('## Timeline');
195
223
  lines.push('');
@@ -225,23 +253,17 @@ function formatHeader(metrics) {
225
253
  parts.push(`${metrics.eventCount} events`);
226
254
  return parts.join(' | ');
227
255
  }
228
- function formatTokenSummary(metrics) {
256
+ function formatTokenSummary(metrics, tokens) {
229
257
  const t = metrics.tokens;
230
- const total = (0, tokenSummary_1.summarizeTokens)(t).total;
231
- const parts = [
232
- `Tokens: ${fmtTokens(total)} total incl. cache`,
233
- `(${fmtTokens(t.inputTokens)} in`,
234
- `${fmtTokens(t.outputTokens)} out`,
235
- ];
236
- if (t.cacheReadTokens > 0)
237
- parts.push(`${fmtTokens(t.cacheReadTokens)} cache-read`);
238
- if (t.cacheWriteTokens > 0)
239
- parts.push(`${fmtTokens(t.cacheWriteTokens)} cache-write`);
240
- const line = parts.join(', ');
241
- if (t.costUsd > 0) {
242
- return `${line}) Cost: ${fmtCost(t.costUsd)} (${(0, costProvenance_1.describeCostProvenance)(t)})`;
258
+ let first = `Tokens: ${(0, tokenSummary_1.formatTokenBreakdown)(tokens.mainThread, fmtTokens)}`;
259
+ if (t.costUsd > 0)
260
+ first += ` Cost: ${fmtCost(t.costUsd)} (${(0, costProvenance_1.describeCostProvenance)(t)})`;
261
+ const lines = [first];
262
+ if (tokens.subagents.length > 0) {
263
+ lines.push(`${tokenSummary_1.TOKEN_SUBAGENTS_LABEL} (${tokens.subagents.length}): ${(0, tokenSummary_1.formatTokenBreakdown)(tokens.subagentTotal, fmtTokens)}`);
264
+ lines.push(`${tokenSummary_1.TOKEN_SESSION_TOTAL_LABEL}: ${fmtTokens(tokens.combined.total)}`);
243
265
  }
244
- return line + ')';
266
+ return lines;
245
267
  }
246
268
  /** @internal Exported for tests. */
247
269
  function fmtTokens(n) {
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
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';
6
+ export { formatTokenBreakdown, summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_MAIN_THREAD_LABEL, TOKEN_SESSION_TOTAL_LABEL, TOKEN_SUBAGENTS_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
7
7
  export type { TokenSummary, TokenTotalsLike } from './tokenSummary';
8
8
  export { estimateTextTokens, estimateSerializedTokens } from './tokenEstimation';
9
9
  export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod, TokenEstimationConfidence, TokenEstimationOptions, TokenEstimate, } from './tokenEstimation';
@@ -85,8 +85,12 @@ export type { FindCodexRolloutFileOptions } from './providers/codex';
85
85
  export { JsonlParser, TRUNCATION_PATTERNS } from './parsers/jsonl';
86
86
  export type { RawSessionEvent, JsonlParserCallbacks, JsonlParserOptions } from './parsers/jsonl';
87
87
  export { normalizeToolName, normalizeToolInput, detectPlanModeFromText, convertOpenCodeMessage, parseDbMessageData, parseDbPartData, } from './parsers/openCodeParser';
88
- export { CodexRolloutParser, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, } from './parsers/codexParser';
89
- export { scanSubagentDir, extractTaskInfo } from './parsers/subagentScanner';
88
+ export { CodexRolloutParser, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
89
+ export { scanSubagentDir, extractTaskInfo, readAgentMeta } from './parsers/subagentScanner';
90
+ export { ClaudeUsageDeduper, SYNTHETIC_MODEL, dedupedRawClaudeUsage, normalizeClaudeUsage, } from './usage/claudeUsageDedupe';
91
+ export { addUsageToSubagent } from './usage/subagentUsage';
92
+ export { collectSessionTokenTotals, combineSessionTokenTotals, readMainThreadTokenTotals, scanSessionSubagents, subagentTokenTotals, } from './sessionTokenTotals';
93
+ export type { SessionTokenTotals, SubagentTokenSummary } from './sessionTokenTotals';
90
94
  export { classifySessionActivity, detectSessionActivity, refreshSessionActivityState, SESSION_ACTIVITY_GRACE_PERIOD_MS, SESSION_ACTIVITY_STALENESS_MS, } from './parsers/sessionActivityDetector';
91
95
  export type { ClassifySessionActivityOptions, SessionActivityState, SessionActivityResult, } from './parsers/sessionActivityDetector';
92
96
  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';
package/dist/index.js CHANGED
@@ -3,24 +3,29 @@
3
3
  * Public API for sidekick-shared.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.collectPromptHistory = exports.readSessionTranscript = exports.listRecentSessions = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = void 0;
7
- exports.addDecision = exports.completeTask = exports.addTask = exports.withFileLockSync = exports.updateJsonStoreAtomicSync = exports.updateJsonStoreAtomic = exports.atomicWriteFileSync = exports.atomicWriteJsonSync = exports.atomicWriteJson = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.migrateLegacyProjectStores = exports.resolveProjectIdentity = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.setConfigDir = exports.getDefaultConfigDir = exports.getConfigDirOverride = exports.getConfigDir = exports.CONFIG_DIR_ENV_VAR = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyDataStore = exports.createEmptyTokenTotals = exports.HISTORICAL_SESSION_RETENTION_LIMIT = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = exports.isAggregateCodexLimit = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = void 0;
8
- exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionFilesWithStats = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.SESSION_ACTIVITY_STALENESS_MS = exports.SESSION_ACTIVITY_GRACE_PERIOD_MS = exports.refreshSessionActivityState = exports.detectSessionActivity = exports.classifySessionActivity = exports.extractTaskInfo = exports.scanSubagentDir = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports._resetProviderDetectionCache = exports.getObservedActivityReason = exports.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.createSessionProviders = exports.SESSION_PROVIDER_IDS = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = void 0;
9
- exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.createJsonlTail = exports.toFollowEvents = exports.resolveSessionPath = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.readSessionContextSnapshot = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = exports.parseMcpToolName = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = void 0;
10
- exports.readCodexLastRefresh = exports.readCodexAuthIdentity = exports.parseCodexAuthJson = exports.CLAUDE_REFRESH_TOKEN_LIFETIME_ESTIMATE_MS = exports.CLAUDE_ACCESS_TOKEN_LIFETIME_MS = exports.resolveClaudeRefreshExpiry = exports.isNewerClaudeCredential = exports.claudeCredentialFreshness = exports.parseClaudeCredentialBlob = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentialsRaw = exports.readClaudeMaxCredentials = exports.deleteStoredCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.formatCompactionLedger = exports.calculateCompactionLedger = exports.describeCostProvenance = exports.classifyCostProvenance = exports.calculateCodeImpact = exports.scoreSessionQuality = exports.calculateQualityTrend = exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.readErrorHistory = exports.getTopFailingTools = exports.appendErrorHistory = exports.MAX_ERROR_HISTORY_SESSIONS = exports.ERROR_HISTORY_SCHEMA_VERSION = exports.getSnapshotPath = exports.MAX_SNAPSHOT_FILES = exports.pruneSnapshots = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.SessionMonitor = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.PHRASE_CATEGORIES = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = void 0;
11
- exports.getAccountsDir = exports.ACCOUNT_CONSUMER_REACHABILITY = exports.describeAccountConsumer = exports.detectRunningAccountConsumersSync = exports.detectRunningAccountConsumers = exports.findRunningProcessesSync = exports.findRunningProcesses = exports.keepAliveCommand = exports.refreshInactiveAccounts = exports.getAccountLaunchEnv = exports.getHealthSidecarPath = exports.readHealthSidecar = exports.listAccountsWithHealth = exports.getAccountHealth = exports.cleanupAbandonedLogins = exports.syncLiveAccountStateSync = exports.syncLiveAccountState = exports.getLastSwitchPath = exports.readLastSwitch = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.getLastSwitch = exports.undoLastSwitch = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = exports.finalizeAccountLogin = exports.getAccountLoginStatusAsync = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.cleanupAbandonedClaudeLogins = exports.syncClaudeLiveState = exports.switchToAccountAsync = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.codexIdentitiesMatch = exports.readCodexAccessTokenExpiry = void 0;
12
- exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.CODEX_KEYRING_FIX_HINT = exports.getCodexCredentialStoreMode = exports.cleanupAbandonedCodexLogins = exports.syncCodexLiveState = exports.removeCodexAccount = exports.switchToCodexAccountAsync = exports.switchToCodexAccount = exports.finalizeCodexAccountAsync = exports.finalizeCodexAccount = exports.prepareCodexAccountAsync = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readLiveClaudeIdentity = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = exports.buildClaudeChildEnv = exports.claudeKeychainAccountName = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeConfigPath = exports.getDefaultClaudeHome = exports.getLiveClaudeHome = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.onAccountsChanged = exports.getActiveAccountStatus = exports.ACCOUNT_PROVIDER_IDS = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = void 0;
13
- exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.MultiProviderQuotaService = exports.resolveZaiQuota = exports.readZaiCredentials = exports.quotaStateFromZaiQuotaLimitPayload = exports.fetchZaiQuotaFromApi = exports.CodexQuotaWatcher = exports.resolveCodexQuotaFromLocalSources = exports.resolveCodexQuota = exports.readLatestCodexQuotaFromRollouts = exports.quotaFromCodexRateLimits = exports.fetchCodexQuotaFromApi = exports.fetchCodexResetCreditsFromApi = exports.getWorkspaceIdFromPath = exports.pruneQuotaHistory = exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.quotaFromStatuslinePayload = exports.parseClaudeStatuslinePayload = exports.evaluateQuotaThresholds = exports.describeQuotaThresholdAlert = exports.DEFAULT_QUOTA_THRESHOLDS = exports.QUOTA_FRESH_MAX_AGE_MS = exports.QUOTA_AGING_MAX_AGE_MS = exports.formatQuotaAge = exports.classifyQuotaFreshness = exports.resolveQuota = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.QUOTA_PROVIDER_IDS = void 0;
14
- exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = exports.extractErrorMessage = exports.categorizeError = exports.gatherAssetsForCwd = exports.codexSessions = exports.readCodexAssets = exports.claudeSessions = exports.readClaudeAssets = exports.extractCommands = exports.extractFilePaths = exports.extractUrls = exports.extractTokenUsage = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.MODEL_PROVIDER_IDS = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = void 0;
15
- exports.fetchProviderServiceStatus = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.scopePeakHoursToSessionProvider = exports.PEAK_HOURS_DESCRIPTION = exports.PEAK_HOURS_CACHE_MS = exports.isClaudeCodeSessionProvider = exports.getScheduledPeakHoursState = exports.fetchPeakHoursStatus = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = exports.createPeakHoursNotApplicableState = exports._resetPeakHoursCache = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.toLegacyProviderStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = void 0;
6
+ exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.collectPromptHistory = exports.readSessionTranscript = exports.listRecentSessions = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_SUBAGENTS_LABEL = exports.TOKEN_SESSION_TOTAL_LABEL = exports.TOKEN_MAIN_THREAD_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.formatTokenBreakdown = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = void 0;
7
+ exports.updateJsonStoreAtomicSync = exports.updateJsonStoreAtomic = exports.atomicWriteFileSync = exports.atomicWriteJsonSync = exports.atomicWriteJson = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.migrateLegacyProjectStores = exports.resolveProjectIdentity = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.setConfigDir = exports.getDefaultConfigDir = exports.getConfigDirOverride = exports.getConfigDir = exports.CONFIG_DIR_ENV_VAR = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyDataStore = exports.createEmptyTokenTotals = exports.HISTORICAL_SESSION_RETENTION_LIMIT = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = exports.isAggregateCodexLimit = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = void 0;
8
+ exports.detectSessionActivity = exports.classifySessionActivity = exports.subagentTokenTotals = exports.scanSessionSubagents = exports.readMainThreadTokenTotals = exports.combineSessionTokenTotals = exports.collectSessionTokenTotals = exports.addUsageToSubagent = exports.normalizeClaudeUsage = exports.dedupedRawClaudeUsage = exports.SYNTHETIC_MODEL = exports.ClaudeUsageDeduper = exports.readAgentMeta = exports.extractTaskInfo = exports.scanSubagentDir = exports.resolveCodexCallUsage = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports._resetProviderDetectionCache = exports.getObservedActivityReason = exports.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.createSessionProviders = exports.SESSION_PROVIDER_IDS = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = exports.addDecision = exports.completeTask = exports.addTask = exports.withFileLockSync = void 0;
9
+ exports.createJsonlTail = exports.toFollowEvents = exports.resolveSessionPath = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.readSessionContextSnapshot = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = exports.parseMcpToolName = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionFilesWithStats = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.SESSION_ACTIVITY_STALENESS_MS = exports.SESSION_ACTIVITY_GRACE_PERIOD_MS = exports.refreshSessionActivityState = void 0;
10
+ exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.formatCompactionLedger = exports.calculateCompactionLedger = exports.describeCostProvenance = exports.classifyCostProvenance = exports.calculateCodeImpact = exports.scoreSessionQuality = exports.calculateQualityTrend = exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.readErrorHistory = exports.getTopFailingTools = exports.appendErrorHistory = exports.MAX_ERROR_HISTORY_SESSIONS = exports.ERROR_HISTORY_SCHEMA_VERSION = exports.getSnapshotPath = exports.MAX_SNAPSHOT_FILES = exports.pruneSnapshots = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.SessionMonitor = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.PHRASE_CATEGORIES = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = void 0;
11
+ exports.syncLiveAccountState = exports.getLastSwitchPath = exports.readLastSwitch = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.getLastSwitch = exports.undoLastSwitch = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = exports.finalizeAccountLogin = exports.getAccountLoginStatusAsync = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.cleanupAbandonedClaudeLogins = exports.syncClaudeLiveState = exports.switchToAccountAsync = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.codexIdentitiesMatch = exports.readCodexAccessTokenExpiry = exports.readCodexLastRefresh = exports.readCodexAuthIdentity = exports.parseCodexAuthJson = exports.CLAUDE_REFRESH_TOKEN_LIFETIME_ESTIMATE_MS = exports.CLAUDE_ACCESS_TOKEN_LIFETIME_MS = exports.resolveClaudeRefreshExpiry = exports.isNewerClaudeCredential = exports.claudeCredentialFreshness = exports.parseClaudeCredentialBlob = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentialsRaw = exports.readClaudeMaxCredentials = exports.deleteStoredCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = void 0;
12
+ exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readLiveClaudeIdentity = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = exports.buildClaudeChildEnv = exports.claudeKeychainAccountName = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeConfigPath = exports.getDefaultClaudeHome = exports.getLiveClaudeHome = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.onAccountsChanged = exports.getActiveAccountStatus = exports.ACCOUNT_PROVIDER_IDS = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.ACCOUNT_CONSUMER_REACHABILITY = exports.describeAccountConsumer = exports.detectRunningAccountConsumersSync = exports.detectRunningAccountConsumers = exports.findRunningProcessesSync = exports.findRunningProcesses = exports.keepAliveCommand = exports.refreshInactiveAccounts = exports.getAccountLaunchEnv = exports.getHealthSidecarPath = exports.readHealthSidecar = exports.listAccountsWithHealth = exports.getAccountHealth = exports.cleanupAbandonedLogins = exports.syncLiveAccountStateSync = void 0;
13
+ exports.readZaiCredentials = exports.quotaStateFromZaiQuotaLimitPayload = exports.fetchZaiQuotaFromApi = exports.CodexQuotaWatcher = exports.resolveCodexQuotaFromLocalSources = exports.resolveCodexQuota = exports.readLatestCodexQuotaFromRollouts = exports.quotaFromCodexRateLimits = exports.fetchCodexQuotaFromApi = exports.fetchCodexResetCreditsFromApi = exports.getWorkspaceIdFromPath = exports.pruneQuotaHistory = exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.quotaFromStatuslinePayload = exports.parseClaudeStatuslinePayload = exports.evaluateQuotaThresholds = exports.describeQuotaThresholdAlert = exports.DEFAULT_QUOTA_THRESHOLDS = exports.QUOTA_FRESH_MAX_AGE_MS = exports.QUOTA_AGING_MAX_AGE_MS = exports.formatQuotaAge = exports.classifyQuotaFreshness = exports.resolveQuota = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.QUOTA_PROVIDER_IDS = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.CODEX_KEYRING_FIX_HINT = exports.getCodexCredentialStoreMode = exports.cleanupAbandonedCodexLogins = exports.syncCodexLiveState = exports.removeCodexAccount = exports.switchToCodexAccountAsync = exports.switchToCodexAccount = exports.finalizeCodexAccountAsync = exports.finalizeCodexAccount = exports.prepareCodexAccountAsync = void 0;
14
+ exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = exports.extractErrorMessage = exports.categorizeError = exports.gatherAssetsForCwd = exports.codexSessions = exports.readCodexAssets = exports.claudeSessions = exports.readClaudeAssets = exports.extractCommands = exports.extractFilePaths = exports.extractUrls = exports.extractTokenUsage = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.MODEL_PROVIDER_IDS = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.MultiProviderQuotaService = exports.resolveZaiQuota = void 0;
15
+ exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.toLegacyProviderStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = void 0;
16
+ exports.fetchProviderServiceStatus = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.scopePeakHoursToSessionProvider = exports.PEAK_HOURS_DESCRIPTION = exports.PEAK_HOURS_CACHE_MS = exports.isClaudeCodeSessionProvider = exports.getScheduledPeakHoursState = exports.fetchPeakHoursStatus = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = exports.createPeakHoursNotApplicableState = exports._resetPeakHoursCache = void 0;
16
17
  var usageNormalization_1 = require("./usageNormalization");
17
18
  Object.defineProperty(exports, "normalizeProviderUsage", { enumerable: true, get: function () { return usageNormalization_1.normalizeProviderUsage; } });
18
19
  Object.defineProperty(exports, "extractNormalizedUsage", { enumerable: true, get: function () { return usageNormalization_1.extractNormalizedUsage; } });
19
20
  Object.defineProperty(exports, "calculateNormalizedUsageCost", { enumerable: true, get: function () { return usageNormalization_1.calculateNormalizedUsageCost; } });
20
21
  var tokenSummary_1 = require("./tokenSummary");
22
+ Object.defineProperty(exports, "formatTokenBreakdown", { enumerable: true, get: function () { return tokenSummary_1.formatTokenBreakdown; } });
21
23
  Object.defineProperty(exports, "summarizeTokens", { enumerable: true, get: function () { return tokenSummary_1.summarizeTokens; } });
22
24
  Object.defineProperty(exports, "sumTokenTotals", { enumerable: true, get: function () { return tokenSummary_1.sumTokenTotals; } });
23
25
  Object.defineProperty(exports, "TOKEN_CONTEXT_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_CONTEXT_LABEL; } });
26
+ Object.defineProperty(exports, "TOKEN_MAIN_THREAD_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_MAIN_THREAD_LABEL; } });
27
+ Object.defineProperty(exports, "TOKEN_SESSION_TOTAL_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_SESSION_TOTAL_LABEL; } });
28
+ Object.defineProperty(exports, "TOKEN_SUBAGENTS_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_SUBAGENTS_LABEL; } });
24
29
  Object.defineProperty(exports, "TOKEN_TOTAL_LABEL", { enumerable: true, get: function () { return tokenSummary_1.TOKEN_TOTAL_LABEL; } });
25
30
  var tokenEstimation_1 = require("./tokenEstimation");
26
31
  Object.defineProperty(exports, "estimateTextTokens", { enumerable: true, get: function () { return tokenEstimation_1.estimateTextTokens; } });
@@ -197,10 +202,26 @@ Object.defineProperty(exports, "CodexRolloutParser", { enumerable: true, get: fu
197
202
  Object.defineProperty(exports, "extractPatchFilePaths", { enumerable: true, get: function () { return codexParser_1.extractPatchFilePaths; } });
198
203
  Object.defineProperty(exports, "normalizeCodexToolName", { enumerable: true, get: function () { return codexParser_1.normalizeCodexToolName; } });
199
204
  Object.defineProperty(exports, "normalizeCodexToolInput", { enumerable: true, get: function () { return codexParser_1.normalizeCodexToolInput; } });
205
+ Object.defineProperty(exports, "resolveCodexCallUsage", { enumerable: true, get: function () { return codexParser_1.resolveCodexCallUsage; } });
200
206
  // Parsers — Subagent scanning
201
207
  var subagentScanner_1 = require("./parsers/subagentScanner");
202
208
  Object.defineProperty(exports, "scanSubagentDir", { enumerable: true, get: function () { return subagentScanner_1.scanSubagentDir; } });
203
209
  Object.defineProperty(exports, "extractTaskInfo", { enumerable: true, get: function () { return subagentScanner_1.extractTaskInfo; } });
210
+ Object.defineProperty(exports, "readAgentMeta", { enumerable: true, get: function () { return subagentScanner_1.readAgentMeta; } });
211
+ // Usage — split-line dedupe, subagent tokens, session totals
212
+ var claudeUsageDedupe_1 = require("./usage/claudeUsageDedupe");
213
+ Object.defineProperty(exports, "ClaudeUsageDeduper", { enumerable: true, get: function () { return claudeUsageDedupe_1.ClaudeUsageDeduper; } });
214
+ Object.defineProperty(exports, "SYNTHETIC_MODEL", { enumerable: true, get: function () { return claudeUsageDedupe_1.SYNTHETIC_MODEL; } });
215
+ Object.defineProperty(exports, "dedupedRawClaudeUsage", { enumerable: true, get: function () { return claudeUsageDedupe_1.dedupedRawClaudeUsage; } });
216
+ Object.defineProperty(exports, "normalizeClaudeUsage", { enumerable: true, get: function () { return claudeUsageDedupe_1.normalizeClaudeUsage; } });
217
+ var subagentUsage_1 = require("./usage/subagentUsage");
218
+ Object.defineProperty(exports, "addUsageToSubagent", { enumerable: true, get: function () { return subagentUsage_1.addUsageToSubagent; } });
219
+ var sessionTokenTotals_1 = require("./sessionTokenTotals");
220
+ Object.defineProperty(exports, "collectSessionTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.collectSessionTokenTotals; } });
221
+ Object.defineProperty(exports, "combineSessionTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.combineSessionTokenTotals; } });
222
+ Object.defineProperty(exports, "readMainThreadTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.readMainThreadTokenTotals; } });
223
+ Object.defineProperty(exports, "scanSessionSubagents", { enumerable: true, get: function () { return sessionTokenTotals_1.scanSessionSubagents; } });
224
+ Object.defineProperty(exports, "subagentTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.subagentTokenTotals; } });
204
225
  // Parsers — Session activity detection
205
226
  var sessionActivityDetector_1 = require("./parsers/sessionActivityDetector");
206
227
  Object.defineProperty(exports, "classifySessionActivity", { enumerable: true, get: function () { return sessionActivityDetector_1.classifySessionActivity; } });
package/dist/node.d.ts CHANGED
@@ -25,6 +25,8 @@ export { BILLING_BLOCK_DURATION_MS, computeBillingBlocks, findActiveBillingBlock
25
25
  export type { BillingBlock, BillingBlockInput, BillingBlockModelUsage, BillingBlockTokens, ComputeBillingBlocksOptions, } from './usage/billingBlocks';
26
26
  export { MAX_USAGE_CACHE_FILES, USAGE_CACHE_VERSION, collectUsageEvents, getUsageCacheDir, pruneUsageCache, } from './usage/usageEvents';
27
27
  export type { CollectUsageEventsOptions, CollectUsageEventsResult, UsageEventRecord, UsageSessionRecord, } from './usage/usageEvents';
28
+ export { collectSessionTokenTotals, combineSessionTokenTotals, readMainThreadTokenTotals, scanSessionSubagents, subagentTokenTotals, } from './sessionTokenTotals';
29
+ export type { SessionTokenTotals, SubagentTokenSummary } from './sessionTokenTotals';
28
30
  export { applySessionSummary, isFileImported, markFileImported, removeSessionSummary, sessionSummaryFromStats, } from './historicalStore';
29
31
  export type { ApplySessionSummaryOptions, SessionSummaryFromStatsOptions } from './historicalStore';
30
32
  export { ACTIVE_SESSION_MTIME_THRESHOLD_MS, importSessionHistory, } from './usage/importSessionHistory';
@@ -44,6 +46,9 @@ export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFinger
44
46
  export type { KnownObservedSessionFingerprint, ObservedSessionChange, ObservedSessionChangeBatch, ObservedSessionChangeType, ObservedSessionReference, ObservedSessionFingerprintParts, ObservedSessionSourceSubscribeOptions, ObservedSessionSubscribeOptions, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnosticPhase, ObservedSessionDiagnosticSeverity, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, ObservedSessionCollectOptions, ObservedSessionDiscoverOptions, ObservedSessionDiscoveryStats, ObservedSessionDiscoveryTrigger, ObservedSessionSourceSignal, ObservedSessionSourceListener, ObservedSessionResolution, } from './observedSessionCollector';
45
47
  export { DirectoryListingCache, splitWatchedPath } from './providers/directoryListingCache';
46
48
  export type { CachedDirectoryListing, CachedFileStat, DirectoryListingCacheOptions, DirectoryListingCounters, ListDirectoryOptions, } from './providers/directoryListingCache';
47
- export type { ListSessionFilesOptions, SessionEnumerationCounters, WatchedSessionFile, } from './providers/types';
49
+ export type { ListSessionFilesOptions, ProviderId, SessionEnumerationCounters, SessionProviderBase, SessionProviderDiagnostic, WatchedSessionFile, } from './providers/types';
50
+ export { createSessionProviders } from './providers/factory';
51
+ export type { CreateSessionProvidersOptions, CreateSessionProvidersResult, } from './providers/factory';
52
+ export { SYNTHETIC_MODEL } from './usage/claudeUsageDedupe';
48
53
  export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
49
54
  export { fetchProviderServiceStatus } from './providerServiceStatus';
package/dist/node.js CHANGED
@@ -7,8 +7,8 @@
7
7
  * for browser bundles — use `sidekick-shared/browser` there.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.collectPromptHistory = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
11
- exports.fetchProviderServiceStatus = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = void 0;
10
+ exports.summarizeUsageRows = exports.bucketUsage = exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.subagentTokenTotals = exports.scanSessionSubagents = exports.readMainThreadTokenTotals = exports.combineSessionTokenTotals = exports.collectSessionTokenTotals = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.collectPromptHistory = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
11
+ exports.fetchProviderServiceStatus = exports.SYNTHETIC_MODEL = exports.createSessionProviders = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.weekKey = exports.usageBucketKey = void 0;
12
12
  var pricingCatalog_1 = require("./pricingCatalog");
13
13
  Object.defineProperty(exports, "hydratePricingCatalog", { enumerable: true, get: function () { return pricingCatalog_1.hydratePricingCatalog; } });
14
14
  Object.defineProperty(exports, "normalizeLiteLlmCatalog", { enumerable: true, get: function () { return pricingCatalog_1.normalizeLiteLlmCatalog; } });
@@ -56,6 +56,12 @@ Object.defineProperty(exports, "USAGE_CACHE_VERSION", { enumerable: true, get: f
56
56
  Object.defineProperty(exports, "collectUsageEvents", { enumerable: true, get: function () { return usageEvents_1.collectUsageEvents; } });
57
57
  Object.defineProperty(exports, "getUsageCacheDir", { enumerable: true, get: function () { return usageEvents_1.getUsageCacheDir; } });
58
58
  Object.defineProperty(exports, "pruneUsageCache", { enumerable: true, get: function () { return usageEvents_1.pruneUsageCache; } });
59
+ var sessionTokenTotals_1 = require("./sessionTokenTotals");
60
+ Object.defineProperty(exports, "collectSessionTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.collectSessionTokenTotals; } });
61
+ Object.defineProperty(exports, "combineSessionTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.combineSessionTokenTotals; } });
62
+ Object.defineProperty(exports, "readMainThreadTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.readMainThreadTokenTotals; } });
63
+ Object.defineProperty(exports, "scanSessionSubagents", { enumerable: true, get: function () { return sessionTokenTotals_1.scanSessionSubagents; } });
64
+ Object.defineProperty(exports, "subagentTokenTotals", { enumerable: true, get: function () { return sessionTokenTotals_1.subagentTokenTotals; } });
59
65
  var historicalStore_1 = require("./historicalStore");
60
66
  Object.defineProperty(exports, "applySessionSummary", { enumerable: true, get: function () { return historicalStore_1.applySessionSummary; } });
61
67
  Object.defineProperty(exports, "isFileImported", { enumerable: true, get: function () { return historicalStore_1.isFileImported; } });
@@ -90,5 +96,9 @@ Object.defineProperty(exports, "fileFingerprintParts", { enumerable: true, get:
90
96
  var directoryListingCache_1 = require("./providers/directoryListingCache");
91
97
  Object.defineProperty(exports, "DirectoryListingCache", { enumerable: true, get: function () { return directoryListingCache_1.DirectoryListingCache; } });
92
98
  Object.defineProperty(exports, "splitWatchedPath", { enumerable: true, get: function () { return directoryListingCache_1.splitWatchedPath; } });
99
+ var factory_1 = require("./providers/factory");
100
+ Object.defineProperty(exports, "createSessionProviders", { enumerable: true, get: function () { return factory_1.createSessionProviders; } });
101
+ var claudeUsageDedupe_1 = require("./usage/claudeUsageDedupe");
102
+ Object.defineProperty(exports, "SYNTHETIC_MODEL", { enumerable: true, get: function () { return claudeUsageDedupe_1.SYNTHETIC_MODEL; } });
93
103
  var providerServiceStatus_1 = require("./providerServiceStatus");
94
104
  Object.defineProperty(exports, "fetchProviderServiceStatus", { enumerable: true, get: function () { return providerServiceStatus_1.fetchProviderServiceStatus; } });
@@ -4,7 +4,8 @@
4
4
  * Unlike OpenCode's stateless converter, this is stateful because:
5
5
  * - exec_command_begin/end and mcp_tool_call_begin/end need pairing by call_id
6
6
  * - turn_context sets the current model for subsequent events
7
- * - token_count provides cumulative usage that needs delta computation
7
+ * - token_count repeats its cumulative total on duplicate events, so each
8
+ * call is counted only when `total_token_usage` changes
8
9
  *
9
10
  * Moved from sidekick-vscode to sidekick-shared for reuse across packages.
10
11
  *
@@ -12,6 +13,23 @@
12
13
  */
13
14
  import type { SessionEvent } from '../types/sessionEvent';
14
15
  import type { CodexRolloutLine, CodexSessionMeta, CodexTokenUsage, CodexRateLimits } from '../types/codex';
16
+ /**
17
+ * Resolve the usage of the single call a Codex `token_count` event reports.
18
+ *
19
+ * Codex emits `token_count` repeatedly — rate-limit refreshes and resumes
20
+ * resend the same `info` — so summing `last_token_usage` per event counts
21
+ * those calls again. `total_token_usage` is cumulative, which makes an
22
+ * unchanged total the reliable duplicate signal. When `last_token_usage` is
23
+ * missing, the call is the growth of the cumulative total (never the total
24
+ * itself). A total that drops means the counter restarted; re-baseline on it.
25
+ */
26
+ export declare function resolveCodexCallUsage(info: {
27
+ last_token_usage?: CodexTokenUsage | null;
28
+ total_token_usage?: CodexTokenUsage | null;
29
+ } | null | undefined, previousTotal: CodexTokenUsage | null): {
30
+ usage: CodexTokenUsage | null;
31
+ total: CodexTokenUsage | null;
32
+ };
15
33
  /**
16
34
  * Codex-specific tool name normalization.
17
35
  * Extends the shared normalizeToolName with Codex-specific mappings.
@@ -33,7 +51,7 @@ export declare function extractPatchFilePaths(input: string): string[];
33
51
  * - Session metadata (from session_meta)
34
52
  * - Current model (from turn_context)
35
53
  * - Pending exec commands and MCP tool calls (begin/end pairing)
36
- * - Previous token counts (for delta computation)
54
+ * - Previous cumulative token total (to skip duplicate token_count events)
37
55
  */
38
56
  export declare class CodexRolloutParser {
39
57
  private sessionMeta;
@@ -41,6 +59,8 @@ export declare class CodexRolloutParser {
41
59
  private pendingExecCommands;
42
60
  private pendingMcpToolCalls;
43
61
  private lastTokenUsage;
62
+ /** Cumulative `total_token_usage` from the previous token_count event. */
63
+ private prevTotalUsage;
44
64
  private modelContextWindow;
45
65
  private lastRateLimits;
46
66
  private hasAggregateRateLimits;
@@ -5,7 +5,8 @@
5
5
  * Unlike OpenCode's stateless converter, this is stateful because:
6
6
  * - exec_command_begin/end and mcp_tool_call_begin/end need pairing by call_id
7
7
  * - turn_context sets the current model for subsequent events
8
- * - token_count provides cumulative usage that needs delta computation
8
+ * - token_count repeats its cumulative total on duplicate events, so each
9
+ * call is counted only when `total_token_usage` changes
9
10
  *
10
11
  * Moved from sidekick-vscode to sidekick-shared for reuse across packages.
11
12
  *
@@ -13,6 +14,7 @@
13
14
  */
14
15
  Object.defineProperty(exports, "__esModule", { value: true });
15
16
  exports.CodexRolloutParser = void 0;
17
+ exports.resolveCodexCallUsage = resolveCodexCallUsage;
16
18
  exports.normalizeCodexToolName = normalizeCodexToolName;
17
19
  exports.normalizeCodexToolInput = normalizeCodexToolInput;
18
20
  exports.extractPatchFilePaths = extractPatchFilePaths;
@@ -50,6 +52,58 @@ function normalizeRateLimits(rateLimits) {
50
52
  : undefined,
51
53
  };
52
54
  }
55
+ const CODEX_USAGE_FIELDS = [
56
+ 'input_tokens',
57
+ 'cached_input_tokens',
58
+ 'output_tokens',
59
+ 'reasoning_output_tokens',
60
+ 'total_tokens',
61
+ ];
62
+ function usageField(usage, field) {
63
+ const value = usage[field];
64
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0;
65
+ }
66
+ function codexTotalOf(usage) {
67
+ return (usageField(usage, 'total_tokens') ||
68
+ usageField(usage, 'input_tokens') + usageField(usage, 'output_tokens'));
69
+ }
70
+ /**
71
+ * Resolve the usage of the single call a Codex `token_count` event reports.
72
+ *
73
+ * Codex emits `token_count` repeatedly — rate-limit refreshes and resumes
74
+ * resend the same `info` — so summing `last_token_usage` per event counts
75
+ * those calls again. `total_token_usage` is cumulative, which makes an
76
+ * unchanged total the reliable duplicate signal. When `last_token_usage` is
77
+ * missing, the call is the growth of the cumulative total (never the total
78
+ * itself). A total that drops means the counter restarted; re-baseline on it.
79
+ */
80
+ function resolveCodexCallUsage(info, previousTotal) {
81
+ if (!info)
82
+ return { usage: null, total: previousTotal };
83
+ const last = info.last_token_usage ?? null;
84
+ const total = info.total_token_usage ?? null;
85
+ if (total && previousTotal) {
86
+ const unchanged = CODEX_USAGE_FIELDS.every((field) => usageField(total, field) === usageField(previousTotal, field));
87
+ if (unchanged)
88
+ return { usage: null, total };
89
+ if (codexTotalOf(total) < codexTotalOf(previousTotal)) {
90
+ return { usage: last ?? total, total };
91
+ }
92
+ }
93
+ if (last)
94
+ return { usage: last, total: total ?? previousTotal };
95
+ if (!total)
96
+ return { usage: null, total: previousTotal };
97
+ const delta = {};
98
+ let any = false;
99
+ for (const field of CODEX_USAGE_FIELDS) {
100
+ const value = Math.max(0, usageField(total, field) - (previousTotal ? usageField(previousTotal, field) : 0));
101
+ delta[field] = value;
102
+ if (value > 0)
103
+ any = true;
104
+ }
105
+ return { usage: any ? delta : null, total };
106
+ }
53
107
  /**
54
108
  * Codex-specific tool name normalization.
55
109
  * Extends the shared normalizeToolName with Codex-specific mappings.
@@ -129,7 +183,7 @@ function extractPatchFilePaths(input) {
129
183
  * - Session metadata (from session_meta)
130
184
  * - Current model (from turn_context)
131
185
  * - Pending exec commands and MCP tool calls (begin/end pairing)
132
- * - Previous token counts (for delta computation)
186
+ * - Previous cumulative token total (to skip duplicate token_count events)
133
187
  */
134
188
  class CodexRolloutParser {
135
189
  sessionMeta = null;
@@ -137,6 +191,8 @@ class CodexRolloutParser {
137
191
  pendingExecCommands = new Map();
138
192
  pendingMcpToolCalls = new Map();
139
193
  lastTokenUsage = null;
194
+ /** Cumulative `total_token_usage` from the previous token_count event. */
195
+ prevTotalUsage = null;
140
196
  modelContextWindow = null;
141
197
  lastRateLimits = null;
142
198
  hasAggregateRateLimits = false;
@@ -189,6 +245,7 @@ class CodexRolloutParser {
189
245
  this.pendingExecCommands.clear();
190
246
  this.pendingMcpToolCalls.clear();
191
247
  this.lastTokenUsage = null;
248
+ this.prevTotalUsage = null;
192
249
  this.modelContextWindow = null;
193
250
  this.lastRateLimits = null;
194
251
  this.hasAggregateRateLimits = false;
@@ -526,9 +583,11 @@ class CodexRolloutParser {
526
583
  this.lastRateLimits = e.rate_limits;
527
584
  }
528
585
  }
529
- // Usage data is nested under info.last_token_usage (info can be null)
530
- const usage = e.info?.last_token_usage || e.info?.total_token_usage;
531
- return this.handleTokenCount(timestamp, usage ?? null, e.rate_limits);
586
+ // Usage data is nested under info (info can be null). Codex repeats an
587
+ // unchanged cumulative total on duplicate events; count each call once.
588
+ const resolved = resolveCodexCallUsage(e.info, this.prevTotalUsage);
589
+ this.prevTotalUsage = resolved.total;
590
+ return this.handleTokenCount(timestamp, resolved.usage, e.rate_limits);
532
591
  }
533
592
  // agent_message and user_message are suppressed — they duplicate
534
593
  // response_item/message events which carry richer metadata (id, content parts, role).
@@ -8,6 +8,15 @@
8
8
  * @module parsers/subagentScanner
9
9
  */
10
10
  import type { SubagentStats, TaskState } from '../types/sessionEvent';
11
+ /**
12
+ * Reads `agent-<id>.meta.json` (written by Claude Code next to the transcript)
13
+ * for the spawn's agent type and description. Missing or malformed files
14
+ * yield an empty object.
15
+ */
16
+ export declare function readAgentMeta(agentFilePath: string): {
17
+ agentType?: string;
18
+ description?: string;
19
+ };
11
20
  /**
12
21
  * Scans subagent directory for agent JSONL files and extracts tool calls.
13
22
  *