sidekick-shared 0.24.3 → 0.24.5

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 (52) hide show
  1. package/CHANGELOG.md +436 -0
  2. package/LICENSE +21 -0
  3. package/README.md +172 -60
  4. package/dist/accountManager.d.ts +13 -0
  5. package/dist/accountManager.js +60 -32
  6. package/dist/accountRegistry.js +59 -41
  7. package/dist/accounts.js +40 -19
  8. package/dist/autoSwitch.d.ts +2 -1
  9. package/dist/autoSwitch.js +32 -7
  10. package/dist/browser.d.ts +2 -0
  11. package/dist/browser.js +3 -1
  12. package/dist/codexProfiles.d.ts +14 -0
  13. package/dist/codexProfiles.js +268 -116
  14. package/dist/context/sessionContext.js +2 -4
  15. package/dist/ensureDefaultAccounts.js +4 -4
  16. package/dist/index.d.ts +14 -7
  17. package/dist/index.js +33 -7
  18. package/dist/modelInfo.js +11 -2
  19. package/dist/node.d.ts +6 -0
  20. package/dist/node.js +8 -1
  21. package/dist/observedContextWindows.d.ts +20 -4
  22. package/dist/observedContextWindows.js +47 -7
  23. package/dist/parsers/codexHistory.d.ts +30 -0
  24. package/dist/parsers/codexHistory.js +118 -0
  25. package/dist/parsers/mcpToolName.d.ts +26 -0
  26. package/dist/parsers/mcpToolName.js +31 -0
  27. package/dist/parsers/sessionPathResolver.d.ts +11 -4
  28. package/dist/parsers/sessionPathResolver.js +11 -4
  29. package/dist/paths.d.ts +43 -4
  30. package/dist/paths.js +66 -6
  31. package/dist/peakHours.d.ts +16 -2
  32. package/dist/peakHours.js +18 -3
  33. package/dist/pricingCatalog.d.ts +7 -3
  34. package/dist/pricingCatalog.js +3 -2
  35. package/dist/providers/claudeCode.d.ts +2 -1
  36. package/dist/providers/claudeCode.js +18 -0
  37. package/dist/providers/codex.d.ts +22 -1
  38. package/dist/providers/codex.js +58 -0
  39. package/dist/providers/types.d.ts +5 -0
  40. package/dist/quotaHistory.d.ts +1 -1
  41. package/dist/quotaHistory.js +2 -2
  42. package/dist/quotaSnapshots.js +8 -77
  43. package/dist/sessionPreviews.d.ts +60 -0
  44. package/dist/sessionPreviews.js +234 -0
  45. package/dist/sessionTranscripts.js +10 -4
  46. package/dist/writers/atomic.d.ts +20 -0
  47. package/dist/writers/atomic.js +190 -19
  48. package/dist/zaiQuota.d.ts +87 -0
  49. package/dist/zaiQuota.js +49 -0
  50. package/dist/zaiQuotaWatcher.d.ts +7 -0
  51. package/dist/zaiQuotaWatcher.js +3 -0
  52. package/package.json +60 -2
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ export type { HistoricalDataStore, DailyData, HourlyData, MonthlyData, AllTimeSt
25
25
  export { HISTORICAL_DATA_SCHEMA_VERSION, HISTORICAL_SESSION_RETENTION_LIMIT, createEmptyTokenTotals, createEmptyDataStore, } from './types/historicalData';
26
26
  export type { PersistedPlan, PersistedPlanStep, PlanHistoryStore, PlanStepStatus, PlanStatus, PlanSource, PlanStepComplexity, } from './types/plan';
27
27
  export { PLAN_SCHEMA_VERSION, MAX_PLANS_PER_PROJECT } from './types/plan';
28
- export { getConfigDir, getProjectDataPath, getGlobalDataPath, encodeWorkspacePath, getProjectSlug, getProjectSlugRaw, resolveProjectIdentity, } from './paths';
28
+ export { CONFIG_DIR_ENV_VAR, getConfigDir, getConfigDirOverride, getDefaultConfigDir, setConfigDir, getProjectDataPath, getGlobalDataPath, encodeWorkspacePath, getProjectSlug, getProjectSlugRaw, resolveProjectIdentity, } from './paths';
29
29
  export type { ProjectIdentity } from './paths';
30
30
  export { migrateLegacyProjectStores } from './projectMigration';
31
31
  export { readTasks } from './readers/tasks';
@@ -38,7 +38,7 @@ export { readHistory } from './readers/history';
38
38
  export { readLatestHandoff } from './readers/handoff';
39
39
  export { readPlans, getLatestPlan, writePlans, getPlanAnalytics, readClaudeCodePlanFiles, } from './readers/plans';
40
40
  export type { ReadPlansOptions, PlanAnalytics } from './readers/plans';
41
- export { atomicWriteJson, atomicWriteJsonSync, updateJsonStoreAtomic } from './writers/atomic';
41
+ export { atomicWriteJson, atomicWriteJsonSync, atomicWriteFileSync, updateJsonStoreAtomic, updateJsonStoreAtomicSync, withFileLockSync, } from './writers/atomic';
42
42
  export { addTask, completeTask } from './writers/tasks';
43
43
  export { addDecision, decisionFingerprint } from './writers/decisions';
44
44
  export { addNote } from './writers/notes';
@@ -50,7 +50,8 @@ export type { ObservationProvenanceV1, ObservedAgentSessionV1, ObservedValueV1,
50
50
  export { detectProvider, getAllDetectedProviders } from './providers/detect';
51
51
  export { ClaudeCodeProvider } from './providers/claudeCode';
52
52
  export { OpenCodeProvider, getOpenCodeDataDir } from './providers/openCode';
53
- export { CodexProvider } from './providers/codex';
53
+ export { CodexProvider, findCodexRolloutFile } from './providers/codex';
54
+ export type { FindCodexRolloutFileOptions } from './providers/codex';
54
55
  export { JsonlParser, TRUNCATION_PATTERNS } from './parsers/jsonl';
55
56
  export type { RawSessionEvent, JsonlParserCallbacks, JsonlParserOptions } from './parsers/jsonl';
56
57
  export { normalizeToolName, normalizeToolInput, detectPlanModeFromText, convertOpenCodeMessage, parseDbMessageData, parseDbPartData, } from './parsers/openCodeParser';
@@ -61,6 +62,12 @@ export type { SessionActivityState, SessionActivityResult, } from './parsers/ses
61
62
  export { encodeWorkspacePath as encodeClaudeWorkspacePath, getSessionDirectory as getClaudeSessionDirectory, discoverSessionDirectory, findActiveSession as findActiveClaudeSession, findAllSessions as findAllClaudeSessions, findSessionsInDirectory, findSubdirectorySessionDirs, getMostRecentlyActiveSessionDir, decodeEncodedPath, getAllProjectFolders as getAllClaudeProjectFolders, resolveWorktreeMainRepo, discoverWorktreeSiblings, findAllSessionsWithWorktrees, } from './parsers/sessionPathResolver';
62
63
  export { scanSubagentTraces } from './parsers/subagentTraceParser';
63
64
  export type { SubagentTrace, SubagentTraceEvent } from './parsers/subagentTraceParser';
65
+ export { parseMcpToolName } from './parsers/mcpToolName';
66
+ export type { McpToolNameParts } from './parsers/mcpToolName';
67
+ export { readCodexHistory } from './parsers/codexHistory';
68
+ export type { CodexHistoryEntry, ReadCodexHistoryOptions } from './parsers/codexHistory';
69
+ export { listSessionPreviews, readSessionPreview } from './sessionPreviews';
70
+ export type { ListSessionPreviewsOptions, ReadSessionPreviewOptions, SessionPreview, } from './sessionPreviews';
64
71
  export { parseDebugLog, filterByLevel, collapseDuplicates, discoverDebugLogs, } from './parsers/debugLogParser';
65
72
  export type { DebugLogEntry, DebugLogFile, DebugLogLevel } from './parsers/debugLogParser';
66
73
  export { OpenCodeDatabase } from './providers/openCodeDatabase';
@@ -126,7 +133,7 @@ export { ensureDefaultAccounts } from './ensureDefaultAccounts';
126
133
  export type { EnsureDefaultAccountStatus, EnsureDefaultAccountsOptions, EnsureDefaultAccountsResult, } from './ensureDefaultAccounts';
127
134
  export { readAccountRegistry, writeAccountRegistry, readActiveClaudeAccount, addCurrentAccount, switchToAccount, resolveActiveClaudeHome, applyActiveClaudeToLiveHome, reconcileClaudeAuthState, removeAccount, listAccounts, getActiveAccount, resolveActiveClaudeAccount, isMultiAccountEnabled, } from './accounts';
128
135
  export type { AccountEntry, AccountRegistry, ActiveAccountInfo, AccountManagerResult, } from './accounts';
129
- export { beginAccountLogin, getAccountLoginStatus, finalizeAccountLogin, spawnAccountLogin, switchAccount, listAllAccounts, resolveClaudeLoginCommand, } from './accountManager';
136
+ export { beginAccountLogin, getAccountLoginStatus, getAccountLoginStatusAsync, finalizeAccountLogin, finalizeAccountLoginAsync, spawnAccountLogin, switchAccount, switchAccountAsync, listAllAccounts, resolveClaudeLoginCommand, } from './accountManager';
130
137
  export type { AccountLoginCommand, AccountLoginState, AccountLoginStatus, BeginAccountLoginResult, FinalizeAccountLoginOptions, ListAllAccountsResult, SpawnAccountLoginOptions, } from './accountManager';
131
138
  export { getAccountsDir, readSavedAccountRegistry, writeSavedAccountRegistry, listSavedAccountProfiles, getActiveSavedAccount, upsertSavedAccountProfile, setActiveSavedAccount, replaceSavedAccountProfiles, removeSavedAccountProfile, } from './accountRegistry';
132
139
  export type { AccountProviderId, AccountIdentityMetadata, ResolvedActiveAccount, SavedAccountProfile, SavedAccountRegistry, } from './accountRegistry';
@@ -134,7 +141,7 @@ export { getActiveAccountStatus } from './accountStatus';
134
141
  export type { ActiveAccountStatus, ActiveProviderAccountStatus } from './accountStatus';
135
142
  export { getClaudeProfilesDir, getClaudeProfileHome, claudeKeychainSuffix, claudeKeychainService, isClaudeProfileAuthenticated, readClaudeProfileIdentity, } from './claudeProfiles';
136
143
  export type { ClaudeProfileIdentity } from './claudeProfiles';
137
- export { getCodexProfilesDir, getCodexProfileHome, getCodexMonitoringHomes, getSystemCodexHome, listCodexAccounts, getActiveCodexAccount, resolveActiveCodexAccount, resolveSidekickCodexHome, getCodexExecutionEnv, prepareCodexAccount, finalizeCodexAccount, switchToCodexAccount, removeCodexAccount, } from './codexProfiles';
144
+ export { getCodexProfilesDir, getCodexProfileHome, getCodexMonitoringHomes, getSystemCodexHome, listCodexAccounts, getActiveCodexAccount, resolveActiveCodexAccount, resolveSidekickCodexHome, getCodexExecutionEnv, prepareCodexAccount, prepareCodexAccountAsync, finalizeCodexAccount, finalizeCodexAccountAsync, switchToCodexAccount, switchToCodexAccountAsync, removeCodexAccount, } from './codexProfiles';
138
145
  export type { CodexAccountManagerResult } from './codexProfiles';
139
146
  export { setTerminalActiveProfile, installShellHook, uninstallShellHook, isShellHookInstalled, writeLauncher, removeLauncher, } from './terminalSync';
140
147
  export { DEFAULT_AUTO_SWITCH_CONFIG, decideAutoSwitch, AutoSwitchController } from './autoSwitch';
@@ -188,5 +195,5 @@ export { fetchProviderStatus, fetchOpenAIStatus } from './providerStatus';
188
195
  export type { ProviderStatusState } from './providerStatus';
189
196
  export { formatHealthReport, getSessionDiagnostics, runDoctor } from './doctor';
190
197
  export type { DeprecatedSetting, DoctorOptions, HealthCheck, HealthCheckStatus, HealthReport, SessionDiagnostics, } from './doctor';
191
- export { createPeakHoursNotApplicableState, fetchPeakHoursStatus, isClaudeCodeSessionProvider, scopePeakHoursToSessionProvider, } from './peakHours';
192
- export type { PeakHoursState } from './peakHours';
198
+ export { createPeakHoursNotApplicableState, DEFAULT_PEAK_HOURS_TIMEOUT_MS, fetchPeakHoursStatus, isClaudeCodeSessionProvider, scopePeakHoursToSessionProvider, } from './peakHours';
199
+ export type { FetchPeakHoursOptions, PeakHoursState } from './peakHours';
package/dist/index.js CHANGED
@@ -3,13 +3,14 @@
3
3
  * Public API for sidekick-shared.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.addNote = exports.decisionFingerprint = exports.addDecision = exports.completeTask = exports.addTask = exports.updateJsonStoreAtomic = 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.getConfigDir = 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.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionTranscript = exports.listRecentSessions = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = void 0;
7
- 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.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.detectSessionActivity = 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.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.renderHandoffUrlTemplate = void 0;
8
- 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.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.formatTokenCount = exports.formatDurationMs = exports.createJsonlTail = exports.toFollowEvents = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.readSessionContextSnapshot = void 0;
9
- exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.getActiveAccountStatus = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLogin = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.formatCompactionLedger = exports.calculateCompactionLedger = exports.calculateCodeImpact = void 0;
10
- exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = 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.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.isShellHookInstalled = exports.uninstallShellHook = exports.installShellHook = exports.setTerminalActiveProfile = exports.removeCodexAccount = exports.switchToCodexAccount = exports.finalizeCodexAccount = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = void 0;
11
- 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.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = void 0;
12
- exports.scopePeakHoursToSessionProvider = exports.isClaudeCodeSessionProvider = exports.fetchPeakHoursStatus = exports.createPeakHoursNotApplicableState = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = 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 = void 0;
6
+ 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.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionTranscript = exports.listRecentSessions = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = void 0;
7
+ exports.readSessionPreview = exports.listSessionPreviews = exports.readCodexHistory = exports.parseMcpToolName = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.detectSessionActivity = 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.findCodexRolloutFile = exports.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = exports.addDecision = exports.completeTask = exports.addTask = exports.withFileLockSync = exports.updateJsonStoreAtomicSync = void 0;
8
+ 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.formatTokenCount = exports.formatDurationMs = exports.createJsonlTail = exports.toFollowEvents = 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 = void 0;
9
+ exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.resolveClaudeLoginCommand = exports.listAllAccounts = 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.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.formatCompactionLedger = exports.calculateCompactionLedger = 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.isSnapshotValid = void 0;
10
+ exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.isShellHookInstalled = exports.uninstallShellHook = exports.installShellHook = exports.setTerminalActiveProfile = 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.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.getActiveAccountStatus = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = void 0;
11
+ 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.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = 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 = void 0;
12
+ exports.formatHealthReport = 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 = exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = void 0;
13
+ exports.scopePeakHoursToSessionProvider = exports.isClaudeCodeSessionProvider = exports.fetchPeakHoursStatus = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = exports.createPeakHoursNotApplicableState = exports.runDoctor = exports.getSessionDiagnostics = void 0;
13
14
  var usageNormalization_1 = require("./usageNormalization");
14
15
  Object.defineProperty(exports, "normalizeProviderUsage", { enumerable: true, get: function () { return usageNormalization_1.normalizeProviderUsage; } });
15
16
  Object.defineProperty(exports, "extractNormalizedUsage", { enumerable: true, get: function () { return usageNormalization_1.extractNormalizedUsage; } });
@@ -47,7 +48,11 @@ Object.defineProperty(exports, "PLAN_SCHEMA_VERSION", { enumerable: true, get: f
47
48
  Object.defineProperty(exports, "MAX_PLANS_PER_PROJECT", { enumerable: true, get: function () { return plan_1.MAX_PLANS_PER_PROJECT; } });
48
49
  // Paths
49
50
  var paths_1 = require("./paths");
51
+ Object.defineProperty(exports, "CONFIG_DIR_ENV_VAR", { enumerable: true, get: function () { return paths_1.CONFIG_DIR_ENV_VAR; } });
50
52
  Object.defineProperty(exports, "getConfigDir", { enumerable: true, get: function () { return paths_1.getConfigDir; } });
53
+ Object.defineProperty(exports, "getConfigDirOverride", { enumerable: true, get: function () { return paths_1.getConfigDirOverride; } });
54
+ Object.defineProperty(exports, "getDefaultConfigDir", { enumerable: true, get: function () { return paths_1.getDefaultConfigDir; } });
55
+ Object.defineProperty(exports, "setConfigDir", { enumerable: true, get: function () { return paths_1.setConfigDir; } });
51
56
  Object.defineProperty(exports, "getProjectDataPath", { enumerable: true, get: function () { return paths_1.getProjectDataPath; } });
52
57
  Object.defineProperty(exports, "getGlobalDataPath", { enumerable: true, get: function () { return paths_1.getGlobalDataPath; } });
53
58
  Object.defineProperty(exports, "encodeWorkspacePath", { enumerable: true, get: function () { return paths_1.encodeWorkspacePath; } });
@@ -77,7 +82,10 @@ Object.defineProperty(exports, "readClaudeCodePlanFiles", { enumerable: true, ge
77
82
  var atomic_1 = require("./writers/atomic");
78
83
  Object.defineProperty(exports, "atomicWriteJson", { enumerable: true, get: function () { return atomic_1.atomicWriteJson; } });
79
84
  Object.defineProperty(exports, "atomicWriteJsonSync", { enumerable: true, get: function () { return atomic_1.atomicWriteJsonSync; } });
85
+ Object.defineProperty(exports, "atomicWriteFileSync", { enumerable: true, get: function () { return atomic_1.atomicWriteFileSync; } });
80
86
  Object.defineProperty(exports, "updateJsonStoreAtomic", { enumerable: true, get: function () { return atomic_1.updateJsonStoreAtomic; } });
87
+ Object.defineProperty(exports, "updateJsonStoreAtomicSync", { enumerable: true, get: function () { return atomic_1.updateJsonStoreAtomicSync; } });
88
+ Object.defineProperty(exports, "withFileLockSync", { enumerable: true, get: function () { return atomic_1.withFileLockSync; } });
81
89
  var tasks_2 = require("./writers/tasks");
82
90
  Object.defineProperty(exports, "addTask", { enumerable: true, get: function () { return tasks_2.addTask; } });
83
91
  Object.defineProperty(exports, "completeTask", { enumerable: true, get: function () { return tasks_2.completeTask; } });
@@ -101,6 +109,7 @@ Object.defineProperty(exports, "OpenCodeProvider", { enumerable: true, get: func
101
109
  Object.defineProperty(exports, "getOpenCodeDataDir", { enumerable: true, get: function () { return openCode_1.getOpenCodeDataDir; } });
102
110
  var codex_2 = require("./providers/codex");
103
111
  Object.defineProperty(exports, "CodexProvider", { enumerable: true, get: function () { return codex_2.CodexProvider; } });
112
+ Object.defineProperty(exports, "findCodexRolloutFile", { enumerable: true, get: function () { return codex_2.findCodexRolloutFile; } });
104
113
  // Parsers — JSONL
105
114
  var jsonl_1 = require("./parsers/jsonl");
106
115
  Object.defineProperty(exports, "JsonlParser", { enumerable: true, get: function () { return jsonl_1.JsonlParser; } });
@@ -144,6 +153,16 @@ Object.defineProperty(exports, "findAllSessionsWithWorktrees", { enumerable: tru
144
153
  // Parsers — Subagent traces
145
154
  var subagentTraceParser_1 = require("./parsers/subagentTraceParser");
146
155
  Object.defineProperty(exports, "scanSubagentTraces", { enumerable: true, get: function () { return subagentTraceParser_1.scanSubagentTraces; } });
156
+ // Parsers — MCP tool names
157
+ var mcpToolName_1 = require("./parsers/mcpToolName");
158
+ Object.defineProperty(exports, "parseMcpToolName", { enumerable: true, get: function () { return mcpToolName_1.parseMcpToolName; } });
159
+ // Parsers — Codex native history
160
+ var codexHistory_1 = require("./parsers/codexHistory");
161
+ Object.defineProperty(exports, "readCodexHistory", { enumerable: true, get: function () { return codexHistory_1.readCodexHistory; } });
162
+ // Session previews (bounded, stat-first)
163
+ var sessionPreviews_1 = require("./sessionPreviews");
164
+ Object.defineProperty(exports, "listSessionPreviews", { enumerable: true, get: function () { return sessionPreviews_1.listSessionPreviews; } });
165
+ Object.defineProperty(exports, "readSessionPreview", { enumerable: true, get: function () { return sessionPreviews_1.readSessionPreview; } });
147
166
  // Parsers — Debug log parsing
148
167
  var debugLogParser_1 = require("./parsers/debugLogParser");
149
168
  Object.defineProperty(exports, "parseDebugLog", { enumerable: true, get: function () { return debugLogParser_1.parseDebugLog; } });
@@ -283,9 +302,12 @@ Object.defineProperty(exports, "isMultiAccountEnabled", { enumerable: true, get:
283
302
  var accountManager_1 = require("./accountManager");
284
303
  Object.defineProperty(exports, "beginAccountLogin", { enumerable: true, get: function () { return accountManager_1.beginAccountLogin; } });
285
304
  Object.defineProperty(exports, "getAccountLoginStatus", { enumerable: true, get: function () { return accountManager_1.getAccountLoginStatus; } });
305
+ Object.defineProperty(exports, "getAccountLoginStatusAsync", { enumerable: true, get: function () { return accountManager_1.getAccountLoginStatusAsync; } });
286
306
  Object.defineProperty(exports, "finalizeAccountLogin", { enumerable: true, get: function () { return accountManager_1.finalizeAccountLogin; } });
307
+ Object.defineProperty(exports, "finalizeAccountLoginAsync", { enumerable: true, get: function () { return accountManager_1.finalizeAccountLoginAsync; } });
287
308
  Object.defineProperty(exports, "spawnAccountLogin", { enumerable: true, get: function () { return accountManager_1.spawnAccountLogin; } });
288
309
  Object.defineProperty(exports, "switchAccount", { enumerable: true, get: function () { return accountManager_1.switchAccount; } });
310
+ Object.defineProperty(exports, "switchAccountAsync", { enumerable: true, get: function () { return accountManager_1.switchAccountAsync; } });
289
311
  Object.defineProperty(exports, "listAllAccounts", { enumerable: true, get: function () { return accountManager_1.listAllAccounts; } });
290
312
  Object.defineProperty(exports, "resolveClaudeLoginCommand", { enumerable: true, get: function () { return accountManager_1.resolveClaudeLoginCommand; } });
291
313
  var accountRegistry_1 = require("./accountRegistry");
@@ -318,8 +340,11 @@ Object.defineProperty(exports, "resolveActiveCodexAccount", { enumerable: true,
318
340
  Object.defineProperty(exports, "resolveSidekickCodexHome", { enumerable: true, get: function () { return codexProfiles_1.resolveSidekickCodexHome; } });
319
341
  Object.defineProperty(exports, "getCodexExecutionEnv", { enumerable: true, get: function () { return codexProfiles_1.getCodexExecutionEnv; } });
320
342
  Object.defineProperty(exports, "prepareCodexAccount", { enumerable: true, get: function () { return codexProfiles_1.prepareCodexAccount; } });
343
+ Object.defineProperty(exports, "prepareCodexAccountAsync", { enumerable: true, get: function () { return codexProfiles_1.prepareCodexAccountAsync; } });
321
344
  Object.defineProperty(exports, "finalizeCodexAccount", { enumerable: true, get: function () { return codexProfiles_1.finalizeCodexAccount; } });
345
+ Object.defineProperty(exports, "finalizeCodexAccountAsync", { enumerable: true, get: function () { return codexProfiles_1.finalizeCodexAccountAsync; } });
322
346
  Object.defineProperty(exports, "switchToCodexAccount", { enumerable: true, get: function () { return codexProfiles_1.switchToCodexAccount; } });
347
+ Object.defineProperty(exports, "switchToCodexAccountAsync", { enumerable: true, get: function () { return codexProfiles_1.switchToCodexAccountAsync; } });
323
348
  Object.defineProperty(exports, "removeCodexAccount", { enumerable: true, get: function () { return codexProfiles_1.removeCodexAccount; } });
324
349
  var terminalSync_1 = require("./terminalSync");
325
350
  Object.defineProperty(exports, "setTerminalActiveProfile", { enumerable: true, get: function () { return terminalSync_1.setTerminalActiveProfile; } });
@@ -494,6 +519,7 @@ Object.defineProperty(exports, "runDoctor", { enumerable: true, get: function ()
494
519
  // Peak Hours (PromoClock — third-party)
495
520
  var peakHours_1 = require("./peakHours");
496
521
  Object.defineProperty(exports, "createPeakHoursNotApplicableState", { enumerable: true, get: function () { return peakHours_1.createPeakHoursNotApplicableState; } });
522
+ Object.defineProperty(exports, "DEFAULT_PEAK_HOURS_TIMEOUT_MS", { enumerable: true, get: function () { return peakHours_1.DEFAULT_PEAK_HOURS_TIMEOUT_MS; } });
497
523
  Object.defineProperty(exports, "fetchPeakHoursStatus", { enumerable: true, get: function () { return peakHours_1.fetchPeakHoursStatus; } });
498
524
  Object.defineProperty(exports, "isClaudeCodeSessionProvider", { enumerable: true, get: function () { return peakHours_1.isClaudeCodeSessionProvider; } });
499
525
  Object.defineProperty(exports, "scopePeakHoursToSessionProvider", { enumerable: true, get: function () { return peakHours_1.scopePeakHoursToSessionProvider; } });
package/dist/modelInfo.js CHANGED
@@ -432,7 +432,12 @@ function _clearPricingOverrides() {
432
432
  overrideSortedKeys = [];
433
433
  }
434
434
  // ── Model ID Parsing ──
435
- const CLAUDE_RE = /^claude-(haiku|sonnet|opus|fable)-([0-9.]+)/i;
435
+ // Anthropic writes the minor version with a hyphen in modern IDs
436
+ // (`claude-sonnet-4-6-20260321`) and a dot in older ones
437
+ // (`claude-sonnet-4.5-20241022`). Accept both, then normalize to a dot.
438
+ // The `{1,2}` bound plus the trailing `(?![0-9])` keep the 8-digit release
439
+ // date from being mistaken for a minor version in `claude-opus-4-20250514`.
440
+ const CLAUDE_RE = /^claude-(haiku|sonnet|opus|fable)-([0-9]+(?:[-.][0-9]{1,2})?)(?![0-9])/i;
436
441
  const LEGACY_CLAUDE_RE = /^claude-([0-9]+(?:[-.][0-9]+)?)-(haiku|sonnet|opus)(?:-|$)/i;
437
442
  const GPT_RE = /^gpt-([0-9][0-9.A-Za-z-]*)/i;
438
443
  const O_SERIES_RE = /^o([0-9]+)(-mini|-pro)?/i;
@@ -455,7 +460,11 @@ function parseModelId(modelId) {
455
460
  .toLowerCase();
456
461
  const claude = normalized.match(CLAUDE_RE);
457
462
  if (claude) {
458
- return { provider: 'anthropic', family: claude[1].toLowerCase(), version: claude[2] };
463
+ return {
464
+ provider: 'anthropic',
465
+ family: claude[1].toLowerCase(),
466
+ version: claude[2].replace('-', '.'),
467
+ };
459
468
  }
460
469
  const legacyClaude = normalized.match(LEGACY_CLAUDE_RE);
461
470
  if (legacyClaude) {
package/dist/node.d.ts CHANGED
@@ -11,5 +11,11 @@ export { loadObservedContextWindows, recordObservedContextWindow, getObservedCon
11
11
  export type { ObservedContextWindowOptions, ObservedContextWindowStore, } from './observedContextWindows';
12
12
  export { listRecentSessions, readSessionTranscript } from './sessionTranscripts';
13
13
  export type { ProviderSessionIndex, ListRecentSessionsOptions } from './sessionTranscripts';
14
+ export { findCodexRolloutFile } from './providers/codex';
15
+ export type { FindCodexRolloutFileOptions } from './providers/codex';
16
+ export { readCodexHistory } from './parsers/codexHistory';
17
+ export type { CodexHistoryEntry, ReadCodexHistoryOptions } from './parsers/codexHistory';
18
+ export { listSessionPreviews, readSessionPreview } from './sessionPreviews';
19
+ export type { ListSessionPreviewsOptions, ReadSessionPreviewOptions, SessionPreview, } from './sessionPreviews';
14
20
  export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, } from './observedSessionCollector';
15
21
  export type { ObservedSessionReference, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
package/dist/node.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * for browser bundles — use `sidekick-shared/browser` there.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
10
+ exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionPreview = exports.listSessionPreviews = exports.readCodexHistory = exports.findCodexRolloutFile = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
11
11
  var pricingCatalog_1 = require("./pricingCatalog");
12
12
  Object.defineProperty(exports, "hydratePricingCatalog", { enumerable: true, get: function () { return pricingCatalog_1.hydratePricingCatalog; } });
13
13
  Object.defineProperty(exports, "normalizeLiteLlmCatalog", { enumerable: true, get: function () { return pricingCatalog_1.normalizeLiteLlmCatalog; } });
@@ -20,6 +20,13 @@ Object.defineProperty(exports, "getObservedContextWindowPath", { enumerable: tru
20
20
  var sessionTranscripts_1 = require("./sessionTranscripts");
21
21
  Object.defineProperty(exports, "listRecentSessions", { enumerable: true, get: function () { return sessionTranscripts_1.listRecentSessions; } });
22
22
  Object.defineProperty(exports, "readSessionTranscript", { enumerable: true, get: function () { return sessionTranscripts_1.readSessionTranscript; } });
23
+ var codex_1 = require("./providers/codex");
24
+ Object.defineProperty(exports, "findCodexRolloutFile", { enumerable: true, get: function () { return codex_1.findCodexRolloutFile; } });
25
+ var codexHistory_1 = require("./parsers/codexHistory");
26
+ Object.defineProperty(exports, "readCodexHistory", { enumerable: true, get: function () { return codexHistory_1.readCodexHistory; } });
27
+ var sessionPreviews_1 = require("./sessionPreviews");
28
+ Object.defineProperty(exports, "listSessionPreviews", { enumerable: true, get: function () { return sessionPreviews_1.listSessionPreviews; } });
29
+ Object.defineProperty(exports, "readSessionPreview", { enumerable: true, get: function () { return sessionPreviews_1.readSessionPreview; } });
23
30
  var observedSessionCollector_1 = require("./observedSessionCollector");
24
31
  Object.defineProperty(exports, "ObservedSessionCollector", { enumerable: true, get: function () { return observedSessionCollector_1.ObservedSessionCollector; } });
25
32
  Object.defineProperty(exports, "observedSessionSourceFromProvider", { enumerable: true, get: function () { return observedSessionCollector_1.observedSessionSourceFromProvider; } });
@@ -14,6 +14,19 @@
14
14
  * Precedence, most-trusted first: runtime → observed (here) → LiteLLM catalog →
15
15
  * static table. See `modelContext.ts`.
16
16
  *
17
+ * ## Where the store lives — two seams, one story
18
+ *
19
+ * Reader ({@link loadObservedContextWindows}) and writer
20
+ * ({@link recordObservedContextWindow}) resolve the store path identically:
21
+ * explicit `cacheDir` option → `setConfigDir()` / `SIDEKICK_CONFIG_DIR` (via
22
+ * `getConfigDir()`) → platform default. The global config-dir override is the
23
+ * deployment-level seam external consumers use to relocate every Sidekick
24
+ * store at once; the per-call `cacheDir` is the isolation seam for tests and
25
+ * multi-tenant hosts. Providers deliberately do NOT thread `cacheDir` —
26
+ * `CodexProvider` records observations with default options, which follow the
27
+ * global override, so a default-options load always sees what a
28
+ * default-options record wrote.
29
+ *
17
30
  * @module observedContextWindows
18
31
  */
19
32
  export interface ObservedContextWindowOptions {
@@ -33,6 +46,8 @@ export interface ObservedContextWindowStore {
33
46
  }
34
47
  /** Resolve the on-disk store path. */
35
48
  export declare function getObservedContextWindowPath(cacheDir?: string): string;
49
+ /** Reset the per-store write dedupe. Test-only; not part of the public API. */
50
+ export declare function _clearObservedContextWindowWriteCache(): void;
36
51
  /**
37
52
  * Load persisted observations and apply them as context-window overrides.
38
53
  *
@@ -44,11 +59,12 @@ export declare function loadObservedContextWindows(options?: ObservedContextWind
44
59
  * Record a provider-reported context window for a model.
45
60
  *
46
61
  * Applies in memory immediately, then persists — but only when the value
47
- * actually changed. Codex reports a window on every `token_count` event, so an
48
- * unconditional write would mean disk I/O many times per session for a value
49
- * that almost never moves.
62
+ * actually changed *for that store*. Codex reports a window on every
63
+ * `token_count` event, so an unconditional write would mean disk I/O many times
64
+ * per session for a value that almost never moves.
50
65
  *
51
66
  * Always resolves — never throws. Persistence failures are logged and dropped;
52
- * the in-memory override still stands for this process.
67
+ * the in-memory override still stands for this process, and the next call
68
+ * retries the write.
53
69
  */
54
70
  export declare function recordObservedContextWindow(modelId: string, contextWindow: number, options?: ObservedContextWindowOptions): Promise<void>;
@@ -15,6 +15,19 @@
15
15
  * Precedence, most-trusted first: runtime → observed (here) → LiteLLM catalog →
16
16
  * static table. See `modelContext.ts`.
17
17
  *
18
+ * ## Where the store lives — two seams, one story
19
+ *
20
+ * Reader ({@link loadObservedContextWindows}) and writer
21
+ * ({@link recordObservedContextWindow}) resolve the store path identically:
22
+ * explicit `cacheDir` option → `setConfigDir()` / `SIDEKICK_CONFIG_DIR` (via
23
+ * `getConfigDir()`) → platform default. The global config-dir override is the
24
+ * deployment-level seam external consumers use to relocate every Sidekick
25
+ * store at once; the per-call `cacheDir` is the isolation seam for tests and
26
+ * multi-tenant hosts. Providers deliberately do NOT thread `cacheDir` —
27
+ * `CodexProvider` records observations with default options, which follow the
28
+ * global override, so a default-options load always sees what a
29
+ * default-options record wrote.
30
+ *
18
31
  * @module observedContextWindows
19
32
  */
20
33
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
@@ -52,6 +65,7 @@ var __importStar = (this && this.__importStar) || (function () {
52
65
  })();
53
66
  Object.defineProperty(exports, "__esModule", { value: true });
54
67
  exports.getObservedContextWindowPath = getObservedContextWindowPath;
68
+ exports._clearObservedContextWindowWriteCache = _clearObservedContextWindowWriteCache;
55
69
  exports.loadObservedContextWindows = loadObservedContextWindows;
56
70
  exports.recordObservedContextWindow = recordObservedContextWindow;
57
71
  const node_fs_1 = require("node:fs");
@@ -69,6 +83,21 @@ function getObservedContextWindowPath(cacheDir) {
69
83
  function emptyStore() {
70
84
  return { version: STORE_VERSION, models: {} };
71
85
  }
86
+ /**
87
+ * Last value successfully persisted, per resolved store path.
88
+ *
89
+ * The in-memory override table in `modelContext` is process-global by design —
90
+ * a lookup should answer the same way everywhere. That makes it unusable as the
91
+ * write dedupe: with two `cacheDir`s in one process (two temp dirs in a test
92
+ * suite, a multi-tenant host, a CLI and extension host sharing a process), the
93
+ * global would already hold the value from the first store and the second store
94
+ * would never be written at all.
95
+ */
96
+ const lastPersistedByStore = new Map();
97
+ /** Reset the per-store write dedupe. Test-only; not part of the public API. */
98
+ function _clearObservedContextWindowWriteCache() {
99
+ lastPersistedByStore.clear();
100
+ }
72
101
  /** Keep only well-formed entries; a hand-edited or partly-corrupt file shouldn't poison lookups. */
73
102
  function toOverrideMap(store) {
74
103
  const out = {};
@@ -110,12 +139,13 @@ async function loadObservedContextWindows(options = {}) {
110
139
  * Record a provider-reported context window for a model.
111
140
  *
112
141
  * Applies in memory immediately, then persists — but only when the value
113
- * actually changed. Codex reports a window on every `token_count` event, so an
114
- * unconditional write would mean disk I/O many times per session for a value
115
- * that almost never moves.
142
+ * actually changed *for that store*. Codex reports a window on every
143
+ * `token_count` event, so an unconditional write would mean disk I/O many times
144
+ * per session for a value that almost never moves.
116
145
  *
117
146
  * Always resolves — never throws. Persistence failures are logged and dropped;
118
- * the in-memory override still stands for this process.
147
+ * the in-memory override still stands for this process, and the next call
148
+ * retries the write.
119
149
  */
120
150
  async function recordObservedContextWindow(modelId, contextWindow, options = {}) {
121
151
  const normalizedId = modelId?.trim().toLowerCase();
@@ -124,10 +154,13 @@ async function recordObservedContextWindow(modelId, contextWindow, options = {})
124
154
  if (!Number.isFinite(contextWindow) || contextWindow <= 0)
125
155
  return;
126
156
  const current = (0, modelContext_1._getObservedContextWindows)();
127
- if (current[normalizedId] === contextWindow)
128
- return;
129
- (0, modelContext_1._setObservedContextWindows)({ ...current, [normalizedId]: contextWindow });
157
+ if (current[normalizedId] !== contextWindow) {
158
+ (0, modelContext_1._setObservedContextWindows)({ ...current, [normalizedId]: contextWindow });
159
+ }
130
160
  const storePath = getObservedContextWindowPath(options.cacheDir);
161
+ const persisted = lastPersistedByStore.get(storePath);
162
+ if (persisted?.get(normalizedId) === contextWindow)
163
+ return;
131
164
  try {
132
165
  // Lock-guarded read-modify-write: the CLI and the extension host can both
133
166
  // be observing sessions at once, and each should merge rather than clobber.
@@ -143,6 +176,13 @@ async function recordObservedContextWindow(modelId, contextWindow, options = {})
143
176
  },
144
177
  };
145
178
  });
179
+ // Recorded only on success, so a transient EACCES retries next time.
180
+ let store = lastPersistedByStore.get(storePath);
181
+ if (!store) {
182
+ store = new Map();
183
+ lastPersistedByStore.set(storePath, store);
184
+ }
185
+ store.set(normalizedId, contextWindow);
146
186
  }
147
187
  catch (err) {
148
188
  options.logger?.(`observedContextWindows: failed to persist ${storePath}: ${String(err)}`);
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Reader for Codex's append-only `~/.codex/history.jsonl` (Node-only).
3
+ *
4
+ * Each line is `{"session_id","ts","text"}` — one entry per user prompt. The
5
+ * file grows without bound, so this reader takes a bounded tail instead of the
6
+ * whole file, drops the leading partial line, and parses tolerantly. Pair an
7
+ * entry with {@link findCodexRolloutFile} (providers/codex) to jump from a
8
+ * history row to its full rollout transcript.
9
+ *
10
+ * @module codexHistory
11
+ */
12
+ export interface CodexHistoryEntry {
13
+ sessionId: string;
14
+ /** Timestamp exactly as Codex recorded it (numeric epoch value). */
15
+ ts: number;
16
+ text: string;
17
+ }
18
+ export interface ReadCodexHistoryOptions {
19
+ /** Codex home containing `history.jsonl` (default: `$CODEX_HOME` or `~/.codex`). */
20
+ codexHome?: string;
21
+ /** Maximum entries returned, newest first (default 100). */
22
+ limit?: number;
23
+ /** Bytes read from the end of the file (default 512 KiB). */
24
+ maxTailBytes?: number;
25
+ }
26
+ /**
27
+ * Returns the newest history entries, newest first. A missing or unreadable
28
+ * file yields `[]`; malformed lines are skipped. Never throws.
29
+ */
30
+ export declare function readCodexHistory(options?: ReadCodexHistoryOptions): CodexHistoryEntry[];
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * Reader for Codex's append-only `~/.codex/history.jsonl` (Node-only).
4
+ *
5
+ * Each line is `{"session_id","ts","text"}` — one entry per user prompt. The
6
+ * file grows without bound, so this reader takes a bounded tail instead of the
7
+ * whole file, drops the leading partial line, and parses tolerantly. Pair an
8
+ * entry with {@link findCodexRolloutFile} (providers/codex) to jump from a
9
+ * history row to its full rollout transcript.
10
+ *
11
+ * @module codexHistory
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.readCodexHistory = readCodexHistory;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const codexProfiles_1 = require("../codexProfiles");
51
+ const DEFAULT_LIMIT = 100;
52
+ const DEFAULT_TAIL_BYTES = 512 * 1024;
53
+ /**
54
+ * Returns the newest history entries, newest first. A missing or unreadable
55
+ * file yields `[]`; malformed lines are skipped. Never throws.
56
+ */
57
+ function readCodexHistory(options = {}) {
58
+ const limit = Math.max(0, options.limit ?? DEFAULT_LIMIT);
59
+ const maxTailBytes = Math.max(1, options.maxTailBytes ?? DEFAULT_TAIL_BYTES);
60
+ const historyPath = path.join(options.codexHome ?? (0, codexProfiles_1.getSystemCodexHome)(), 'history.jsonl');
61
+ let descriptor;
62
+ try {
63
+ descriptor = fs.openSync(historyPath, 'r');
64
+ }
65
+ catch {
66
+ return [];
67
+ }
68
+ try {
69
+ const size = fs.fstatSync(descriptor).size;
70
+ const readBytes = Math.min(size, maxTailBytes);
71
+ const buffer = Buffer.alloc(readBytes);
72
+ fs.readSync(descriptor, buffer, 0, readBytes, size - readBytes);
73
+ let content = buffer.toString('utf8');
74
+ if (readBytes < size) {
75
+ // The tail almost certainly starts mid-line; a multibyte character
76
+ // straddling the boundary decodes as replacement garbage inside that
77
+ // same partial line, so dropping through the first newline handles both.
78
+ const firstNewline = content.indexOf('\n');
79
+ content = firstNewline === -1 ? '' : content.slice(firstNewline + 1);
80
+ }
81
+ const entries = [];
82
+ for (const line of content.split('\n')) {
83
+ const trimmed = line.trim();
84
+ if (!trimmed)
85
+ continue;
86
+ let parsed;
87
+ try {
88
+ parsed = JSON.parse(trimmed);
89
+ }
90
+ catch {
91
+ continue;
92
+ }
93
+ if (typeof parsed.session_id !== 'string' ||
94
+ typeof parsed.ts !== 'number' ||
95
+ // JSON.parse('1e400') yields Infinity, which would later RangeError
96
+ // out of Date serialization in consumers.
97
+ !Number.isFinite(parsed.ts) ||
98
+ typeof parsed.text !== 'string') {
99
+ continue;
100
+ }
101
+ entries.push({ sessionId: parsed.session_id, ts: parsed.ts, text: parsed.text });
102
+ }
103
+ // The file is append-only, so on-disk order is oldest first.
104
+ entries.reverse();
105
+ return entries.slice(0, limit);
106
+ }
107
+ catch {
108
+ return [];
109
+ }
110
+ finally {
111
+ try {
112
+ fs.closeSync(descriptor);
113
+ }
114
+ catch {
115
+ // Already closed or invalid; nothing to release.
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Claude Code exposes MCP tools under composite identifiers of the form
3
+ * `mcp__<server>__<tool>`. Splitting them correctly is subtle enough that
4
+ * consumers keep re-implementing it by hand (usually with a plain
5
+ * `split('__')`, which mangles server names containing single underscores).
6
+ * This module is the canonical splitter. Browser-safe: no Node imports.
7
+ *
8
+ * @module mcpToolName
9
+ */
10
+ export interface McpToolNameParts {
11
+ serverName: string;
12
+ toolName: string;
13
+ }
14
+ /**
15
+ * Splits a Claude Code MCP tool identifier `mcp__<server>__<tool>` into parts.
16
+ *
17
+ * The server name ends at the first double underscore after the prefix, so
18
+ * single underscores stay inside it (`mcp__plugin_context7_context7__query-docs`
19
+ * → server `plugin_context7_context7`) and the tool keeps any further double
20
+ * underscores (`mcp__a__b__c` → tool `b__c`).
21
+ *
22
+ * Returns `null` for anything that is not a well-formed MCP tool id: a
23
+ * non-`mcp__` name, a missing or empty server or tool part, or a
24
+ * case-mismatched prefix. No trimming is applied.
25
+ */
26
+ export declare function parseMcpToolName(name: string): McpToolNameParts | null;