sidekick-shared 0.26.4 → 0.26.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to sidekick-shared will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.26.5] - 2026-09-15
9
+
10
+ ### Added
11
+
12
+ - `ObservedSessionCollector` accepts `discover({ limit, since })` and `collect({ limit, since })` bounds, a `minReconcileGapMs` option, and parse-cache bounds `maxCacheEntries` (default 20,000) and `maxCacheBytes` (default 128 MiB).
13
+ - `DirectoryListingCache` and `splitWatchedPath()` are exported from the root and Node entry points with their option and counter types. Session providers may implement `statWatchedSessionFile()`; `ListSessionFilesOptions`, `WatchedSessionFile`, and `SessionEnumerationCounters` describe bounded enumeration and per-file stat results.
14
+ - `provider-discovery-completed` is a new info-severity `ObservedSessionDiagnostic` emitted after every discovery pass with `trigger`, `durationMs`, `referenceCount`, `directoriesListed`, `directoriesStatted`, `filesStatted`, and `partial`.
15
+
16
+ ### Changed
17
+
18
+ - `ObservedSessionCollector.subscribe()` reconciles each recursive-watch event with one stat through `statWatchedSessionFile()` and runs a full `discover()` only for unknown paths, catch-up polls, and the initial pass, at most once per `minReconcileGapMs` (2 s ceiling, scaled down to four times the last walk's duration for cheap sources). Claude Code and Codex enumerate through a per-instance directory-listing cache, so a full pass costs one stat per unchanged directory. The parse cache is bounded and evicts the least recently observed entries.
19
+ - Hosts that treat every `onDiagnostic` call as a problem should branch on `severity`: the new diagnostic is `info` and emitted per pass. Consumers that switch exhaustively over `ObservedSessionDiagnosticKind` must handle the new member.
20
+
21
+ ### Fixed
22
+
23
+ - A reconcile pass that joins a full walk started earlier by a concurrent `collect()` compares scoped watch results against the walk's start, so a change observed while the walk ran is no longer reported back as the walk's older fingerprint.
24
+
8
25
  ## [0.26.4] - 2026-09-09
9
26
 
10
27
  ### Fixed
package/README.md CHANGED
@@ -9,6 +9,7 @@ Types, parsers, providers, readers, formatters, aggregation, search, reporting,
9
9
 
10
10
  ## Recent additions
11
11
 
12
+ - **0.26.5: event-scoped collection** — `ObservedSessionCollector.subscribe()` reconciles each watch event with one `statWatchedSessionFile()` stat and runs a full `discover()` only for unknown paths, catch-up polls, and the initial pass, gated by `minReconcileGapMs`; `discover({ limit, since })` / `collect({ limit, since })` bound a pass, `maxCacheEntries` / `maxCacheBytes` bound the parse cache, `DirectoryListingCache` makes a full pass one stat per unchanged directory, and the info-severity `provider-discovery-completed` diagnostic reports what each pass cost.
12
13
  - **0.26.3–0.26.4: provider failure diagnosis and service status** — `diagnoseProviderFailure()` (root and browser) classifies caller-designated terminal errors into bounded diagnosis and recovery identifiers with evidence provenance; `fetchProviderServiceStatus()` (root and Node) returns explicit observed/unavailable public status with component and incident associations. 0.26.4 recognizes expired-login and re-authentication messages, gives explicit refresh-token rejection precedence over conversation-expiry wording, and classifies `denied by policy` as `execution_policy_denied`.
13
14
  - **0.26.2: reliable monitoring and search** — complete-line JSONL cursors preserve Unicode and Codex parser context; watcher `onBatchComplete` signals a delivered batch. `searchSessions()` adds workspace-path filtering and cancellation, and Doctor accepts an explicit session provider.
14
15
  - **One token vocabulary and cost provenance (0.26.0)** — `summarizeTokens()` gives every surface the same `total` (input + output + cache writes + cache reads) and `context` (input + cache) figures; `AggregatedTokens.costUsd` carries `costProvenance` so reports can say whether a cost was provider-reported or estimated; `parseClaudeStatuslinePayload()` / `quotaFromStatuslinePayload()` turn Claude Code's status-line JSON into an official `statusline` quota source; `readQuotaSnapshot()` reports `ageMs` / `freshness` and keeps the sample's origin as `capturedSource`; `resolveQuota()` shares quota resolution across CLI, MCP, and dashboard startup, with default local-sample preferences and an API-first option used by one-shot Codex queries; `readSessionFileStats()` / `computeSessionFileStats()` give every provider one `readSessionStats()` over the shared aggregator, with `availability`, `costProvenance`, and `toolFailures` on `SessionFileStats`; `collectUsageEvents()` reads priced usage events from session logs with a per-session cache, `computeBillingBlocks()` groups them into five-hour billing blocks, and `bucketUsage()` turns them into day, week, month, or session rows; `applySessionSummary()` and `importSessionHistory()` let any host fold finished sessions into `historical-data.json` the way the extension does; observed sessions are read once per discovery, re-read only when their fingerprint changes, and classified from events by `classifySessionActivity()`; `readSessionReportInputs()` derives report metrics and transcript from one read; `writeStateFile()` / `readStateFile()` (also on the `statusline` subpath) maintain the public, versioned `state.json` for external tools, validated by `sidekickStateFileSchema`; `getScheduledPeakHoursState()` and `evaluateQuotaThresholds()` are shared by the CLI and extension dashboards.
@@ -91,7 +92,7 @@ returns the platform default that both overrides bypass.
91
92
  | **Paths** | Config directory resolution, project data paths, workspace encoding |
92
93
  | **Readers** | Read tasks, decisions, notes, history, handoff, and plans from `~/.config/sidekick/` |
93
94
  | **Writers** | Atomic persistence writers — `atomicWriteJson()` / `updateJsonStoreAtomic()` and their synchronous twins `atomicWriteJsonSync()` / `atomicWriteFileSync()` / `updateJsonStoreAtomicSync()` / `withFileLockSync()` (same cross-process lock file, progress-based timeouts, abandoned-lock reclaim), plus lock-coordinated capture helpers `addTask()`, `completeTask()`, `addDecision()`, `addNote()` that merge into the shared stores without clobbering concurrent writers |
94
- | **Providers** | Session provider abstraction with Claude Code, OpenCode, and Codex implementations; auto-detection via filesystem. As of 0.25.0 constructors perform no environment I/O — build them all with `createSessionProviders({ onDiagnostic })`, which reports unavailable providers as structured diagnostics instead of failing; `findSessionById()` resolves one session through provider-native indexes; stable provider-id const arrays (`SESSION_PROVIDER_IDS`, `ACCOUNT_PROVIDER_IDS`, `QUOTA_PROVIDER_IDS`, `MODEL_PROVIDER_IDS`) accompany the derived unions |
95
+ | **Providers** | Session provider abstraction with Claude Code, OpenCode, and Codex implementations; auto-detection via filesystem. As of 0.25.0 constructors perform no environment I/O — build them all with `createSessionProviders({ onDiagnostic })`, which reports unavailable providers as structured diagnostics instead of failing; `findSessionById()` resolves one session through provider-native indexes; stable provider-id const arrays (`SESSION_PROVIDER_IDS`, `ACCOUNT_PROVIDER_IDS`, `QUOTA_PROVIDER_IDS`, `MODEL_PROVIDER_IDS`) accompany the derived unions. As of 0.26.5 Claude Code and Codex enumerate through a per-instance `DirectoryListingCache` (one stat per unchanged directory) and implement `statWatchedSessionFile()` so a watch event resolves with one stat; `splitWatchedPath()` and the `ListSessionFilesOptions` / `WatchedSessionFile` / `SessionEnumerationCounters` types are exported alongside |
95
96
  | **Observed Sessions (V1)** | Versioned provider-neutral observation contracts — `createProviderSessionAdapterV1()` / `derivePendingUserRequestV1()` with `ObservedAgentSessionV1`, `ProviderCapabilitiesV1`, `PendingUserRequestV1`, `SessionEvidenceRefV1`, and provenance/confidence wrapper types (Zod schemas in `sidekick-shared/schemas`) |
96
97
  | **Parsers** | JSONL event parsing, OpenCode/Codex format normalization, subagent scanning, session path resolution, debug log parsing |
97
98
  | **Watchers** | Live session file watching with event bridging, plus `createJsonlTail()` for raw incremental JSONL consumers |
@@ -370,7 +371,9 @@ Discovery and reads are isolated, retries use bounded 30-second-to-5-minute expo
370
371
 
371
372
  As of 0.25.0, parses are cached by fingerprint — a second `collect()` over unchanged files performs no content reads (cache hits refresh `observedAt` and activity state; `contentObservedAt` reports how old the cached usage/model data actually is, and `cacheHit` marks them). Observations expose structured `fingerprintParts: { sizeBytes, mtimeMs }` alongside the opaque fingerprint string, and diagnostics carry `severity` and `phase` in addition to their existing `kind`.
372
373
 
373
- Instead of a host polling loop, subscribe to debounced change batches. Each change carries the previous and current fingerprints; filesystem watching is combined with a catch-up poll for filesystems that drop events:
374
+ As of 0.26.5, the parse cache is bounded (`maxCacheEntries`, default 20,000; `maxCacheBytes`, default 128 MiB — keep both above your session count) and a pass can be bounded with `discover({ limit, since })` / `collect({ limit, since })`. Every discovery emits an info-severity `provider-discovery-completed` diagnostic with `trigger`, `durationMs`, `referenceCount`, and the `directoriesListed` / `directoriesStatted` / `filesStatted` counters, so a host can see what each pass cost; hosts that surface every diagnostic should branch on `severity`.
375
+
376
+ Instead of a host polling loop, subscribe to debounced change batches. Each change carries the previous and current fingerprints. A recursive-watch event is reconciled with one stat when the provider implements `statWatchedSessionFile()`; a full `discover()` runs only for unknown paths, the catch-up poll (for filesystems that drop events), and the initial pass, at most once per `minReconcileGapMs` (2 s ceiling, scaled down to four times the last walk's duration for cheap sources):
374
377
 
375
378
  ```typescript
376
379
  const subscription = collector.subscribe(
package/dist/index.d.ts CHANGED
@@ -29,7 +29,9 @@ export { bucketUsage, summarizeUsageRows, usageBucketKey, weekKey } from './usag
29
29
  export type { BucketUsageOptions, UsageBucketRow, UsageGranularity, UsageGroupDimension, UsageTotals, } from './usage/usageReports';
30
30
  export type { ProviderSessionIndex, ListRecentSessionsOptions } from './sessionTranscripts';
31
31
  export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, fileFingerprintParts, } from './observedSessionCollector';
32
- export type { KnownObservedSessionFingerprint, ObservedSessionChange, ObservedSessionChangeBatch, ObservedSessionChangeType, ObservedSessionReference, ObservedSessionFingerprintParts, ObservedSessionSourceSubscribeOptions, ObservedSessionSubscribeOptions, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnosticPhase, ObservedSessionDiagnosticSeverity, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
32
+ 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';
33
+ export { DirectoryListingCache, splitWatchedPath } from './providers/directoryListingCache';
34
+ export type { CachedDirectoryListing, CachedFileStat, DirectoryListingCacheOptions, DirectoryListingCounters, ListDirectoryOptions, } from './providers/directoryListingCache';
33
35
  export type { SessionEvent, ClaudeSessionEvent, MessageUsage, SessionMessage, SessionEventBase, MessageSessionEvent, UserSessionEvent, AssistantSessionEvent, SummarySessionEvent, SystemSessionEvent, ToolUseSessionEvent, ToolResultSessionEvent, TokenUsage, ToolCall, ToolAnalytics, TimelineEvent, PendingToolCall, TaskStatus as SessionTaskStatus, TrackedTask, TaskState, SubagentStats, PendingUserRequest, ResponseLatency, LatencyStats, PlanStep, PlanState, SessionStats, CompactionEvent, TruncationEvent, ContextAttribution, TurnAttribution, ContextSizePoint, PermissionMode, PermissionModeChange, } from './types/sessionEvent';
34
36
  export type { OpenCodeSession, OpenCodeMessage, OpenCodePart, OpenCodeTextPart, OpenCodeReasoningPart, OpenCodeToolInvocationPart, OpenCodeCompactionPart, OpenCodeDbToolPart, OpenCodeStepStartPart, OpenCodeStepFinishPart, OpenCodePatchPart, OpenCodeSubtaskPart, OpenCodeAgentPart, OpenCodeFilePart, OpenCodeRetryPart, OpenCodeSnapshotPart, OpenCodeProject, DbProject as OpenCodeDbProject, DbSession as OpenCodeDbSession, DbMessage as OpenCodeDbMessage, DbPart as OpenCodeDbPart, } from './types/opencode';
35
37
  export type { CodexRolloutLine, CodexSessionMeta, CodexResponseItem, CodexMessageItem, CodexContentPart, CodexReasoningItem, CodexFunctionCallItem, CodexFunctionCallOutputItem, CodexLocalShellCallItem, CodexWebSearchCallItem, CodexCustomToolCallItem, CodexCustomToolCallOutputItem, CodexCompacted, CodexTurnContext, CodexEventMsg, CodexEvent, CodexTurnStartedEvent, CodexTurnCompleteEvent, CodexTaskStartedEvent, CodexTaskCompleteEvent, CodexTurnAbortedEvent, CodexTokenCountEvent, CodexTokenUsage, CodexRateLimits, CodexAgentMessageEvent, CodexAgentReasoningEvent, CodexUserMessageEvent, CodexExecCommandBeginEvent, CodexExecCommandEndEvent, CodexMcpToolCallBeginEvent, CodexMcpToolCallEndEvent, CodexErrorEvent, CodexContextCompactedEvent, CodexPatchAppliedEvent, CodexBackgroundEvent, CodexGenericEvent, CodexDbThread, CodexReasoningSummary, } from './types/codex';
@@ -63,7 +65,7 @@ export { addDecision, decisionFingerprint } from './writers/decisions';
63
65
  export { addNote } from './writers/notes';
64
66
  export { renderHandoffUrlTemplate } from './handoffUrl';
65
67
  export type { HandoffUrlIdentifiers } from './handoffUrl';
66
- export type { ProviderId, SessionProvider, SessionProviderBase, SessionFileStats, SessionFileStatsAvailability, SessionFileInfo, SearchHit, ProjectFolderInfo, SessionReader, SessionProviderOptions, ProviderOperationStatus, SessionProviderDiagnostic, SessionProviderDiagnosticKind, SessionProviderDiagnosticPhase, SessionProviderDiagnosticSeverity, ProviderRuntimeStatus, } from './providers/types';
68
+ export type { ProviderId, SessionProvider, SessionProviderBase, SessionEnumerationCounters, ListSessionFilesOptions, WatchedSessionFile, SessionFileStats, SessionFileStatsAvailability, SessionFileInfo, SearchHit, ProjectFolderInfo, SessionReader, SessionProviderOptions, ProviderOperationStatus, SessionProviderDiagnostic, SessionProviderDiagnosticKind, SessionProviderDiagnosticPhase, SessionProviderDiagnosticSeverity, ProviderRuntimeStatus, } from './providers/types';
67
69
  export { SESSION_PROVIDER_IDS } from './providers/types';
68
70
  export { createSessionProviders } from './providers/factory';
69
71
  export type { CreateSessionProvidersOptions, CreateSessionProvidersResult, } from './providers/factory';
package/dist/index.js CHANGED
@@ -3,15 +3,15 @@
3
3
  * Public API for sidekick-shared.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isAggregateCodexLimit = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = 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.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.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.createSessionProviders = exports.SESSION_PROVIDER_IDS = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = 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 = void 0;
8
- 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 = 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 = void 0;
9
- 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 = 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 = void 0;
10
- 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.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 = void 0;
11
- 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.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.resolveClaudeLoginCommand = exports.listAllAccounts = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = void 0;
12
- 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;
13
- 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;
14
- 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.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = 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.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.createSessionProviders = exports.SESSION_PROVIDER_IDS = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = 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 = void 0;
8
+ 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 = 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 = void 0;
9
+ 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 = 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 = void 0;
10
+ 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.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 = void 0;
11
+ 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.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.resolveClaudeLoginCommand = exports.listAllAccounts = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = exports.finalizeAccountLogin = exports.getAccountLoginStatusAsync = void 0;
12
+ 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 = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = void 0;
13
+ 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 = exports.calculateCostWithPricing = exports.calculateCost = void 0;
14
+ 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 = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = void 0;
15
15
  var usageNormalization_1 = require("./usageNormalization");
16
16
  Object.defineProperty(exports, "normalizeProviderUsage", { enumerable: true, get: function () { return usageNormalization_1.normalizeProviderUsage; } });
17
17
  Object.defineProperty(exports, "extractNormalizedUsage", { enumerable: true, get: function () { return usageNormalization_1.extractNormalizedUsage; } });
@@ -76,6 +76,9 @@ Object.defineProperty(exports, "ObservedSessionCollector", { enumerable: true, g
76
76
  Object.defineProperty(exports, "observedSessionSourceFromProvider", { enumerable: true, get: function () { return observedSessionCollector_1.observedSessionSourceFromProvider; } });
77
77
  Object.defineProperty(exports, "fileFingerprint", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprint; } });
78
78
  Object.defineProperty(exports, "fileFingerprintParts", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprintParts; } });
79
+ var directoryListingCache_1 = require("./providers/directoryListingCache");
80
+ Object.defineProperty(exports, "DirectoryListingCache", { enumerable: true, get: function () { return directoryListingCache_1.DirectoryListingCache; } });
81
+ Object.defineProperty(exports, "splitWatchedPath", { enumerable: true, get: function () { return directoryListingCache_1.splitWatchedPath; } });
79
82
  var codex_1 = require("./types/codex");
80
83
  Object.defineProperty(exports, "isAggregateCodexLimit", { enumerable: true, get: function () { return codex_1.isAggregateCodexLimit; } });
81
84
  var taskPersistence_1 = require("./types/taskPersistence");
package/dist/node.d.ts CHANGED
@@ -37,6 +37,9 @@ export type { CodexHistoryEntry, ReadCodexHistoryOptions } from './parsers/codex
37
37
  export { listSessionPreviews, listSessionPreviewsAsync, readSessionPreview, readSessionPreviewAsync, } from './sessionPreviews';
38
38
  export type { AsyncSessionPreviewOptions, ListSessionPreviewsAsyncOptions, ListSessionPreviewsOptions, ReadSessionPreviewAsyncOptions, ReadSessionPreviewOptions, SessionPreview, SessionPreviewListResult, SessionPreviewReadResult, } from './sessionPreviews';
39
39
  export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, fileFingerprintParts, } from './observedSessionCollector';
40
- export type { KnownObservedSessionFingerprint, ObservedSessionChange, ObservedSessionChangeBatch, ObservedSessionChangeType, ObservedSessionReference, ObservedSessionFingerprintParts, ObservedSessionSourceSubscribeOptions, ObservedSessionSubscribeOptions, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnosticPhase, ObservedSessionDiagnosticSeverity, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
40
+ 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';
41
+ export { DirectoryListingCache, splitWatchedPath } from './providers/directoryListingCache';
42
+ export type { CachedDirectoryListing, CachedFileStat, DirectoryListingCacheOptions, DirectoryListingCounters, ListDirectoryOptions, } from './providers/directoryListingCache';
43
+ export type { ListSessionFilesOptions, SessionEnumerationCounters, WatchedSessionFile, } from './providers/types';
41
44
  export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
42
45
  export { fetchProviderServiceStatus } from './providerServiceStatus';
package/dist/node.js CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = 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.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.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = void 0;
11
+ exports.fetchProviderServiceStatus = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = 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; } });
@@ -80,5 +80,8 @@ Object.defineProperty(exports, "ObservedSessionCollector", { enumerable: true, g
80
80
  Object.defineProperty(exports, "observedSessionSourceFromProvider", { enumerable: true, get: function () { return observedSessionCollector_1.observedSessionSourceFromProvider; } });
81
81
  Object.defineProperty(exports, "fileFingerprint", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprint; } });
82
82
  Object.defineProperty(exports, "fileFingerprintParts", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprintParts; } });
83
+ var directoryListingCache_1 = require("./providers/directoryListingCache");
84
+ Object.defineProperty(exports, "DirectoryListingCache", { enumerable: true, get: function () { return directoryListingCache_1.DirectoryListingCache; } });
85
+ Object.defineProperty(exports, "splitWatchedPath", { enumerable: true, get: function () { return directoryListingCache_1.splitWatchedPath; } });
83
86
  var providerServiceStatus_1 = require("./providerServiceStatus");
84
87
  Object.defineProperty(exports, "fetchProviderServiceStatus", { enumerable: true, get: function () { return providerServiceStatus_1.fetchProviderServiceStatus; } });
@@ -12,27 +12,79 @@ export interface ObservedSessionReference {
12
12
  /** Structured fingerprint for consumers that previously parsed fingerprintHint. */
13
13
  fingerprintParts?: ObservedSessionFingerprintParts;
14
14
  }
15
+ /** Payload-free counters a source may fill while discovering. */
16
+ export interface ObservedSessionDiscoveryStats {
17
+ directoriesListed?: number;
18
+ directoriesStatted?: number;
19
+ filesStatted?: number;
20
+ }
21
+ /** Optional bounds for `discover()`. Sources that ignore them still satisfy the contract. */
22
+ export interface ObservedSessionDiscoverOptions {
23
+ /** Return at most this many references, newest first. */
24
+ limit?: number;
25
+ /** Only references modified at or after this epoch-ms. */
26
+ since?: number;
27
+ /** Out-param: fields the source leaves undefined are omitted from diagnostics. */
28
+ stats?: ObservedSessionDiscoveryStats;
29
+ }
30
+ /**
31
+ * What a source's `subscribe()` listener receives. A recursive `fs.watch`
32
+ * supplies a root-relative `filename` that lets the collector reconcile one
33
+ * session instead of rediscovering the provider.
34
+ */
35
+ export interface ObservedSessionSourceSignal {
36
+ trigger?: 'event' | 'poll';
37
+ /** Watch root the event was observed under. */
38
+ root?: string;
39
+ /** Root-relative path from `fs.watch`; null or undefined when unknown. */
40
+ filename?: string | null;
41
+ eventType?: string;
42
+ }
43
+ /**
44
+ * A string arrives when a source hands the listener straight to `fs.watch`
45
+ * (the event type); the collector treats anything but a signal object as
46
+ * "unknown" and falls back to full discovery.
47
+ */
48
+ export type ObservedSessionSourceListener = (signal?: ObservedSessionSourceSignal | string) => void;
49
+ /** How a source classifies one watch signal, resolved with at most one stat. */
50
+ export type ObservedSessionResolution = {
51
+ status: 'ignored';
52
+ } | {
53
+ status: 'unknown';
54
+ } | {
55
+ status: 'missing';
56
+ sessionId: string;
57
+ } | {
58
+ status: 'present';
59
+ reference: ObservedSessionReference;
60
+ };
15
61
  export interface ObservedSessionSourceSubscribeOptions {
16
62
  pollIntervalMs?: number;
17
63
  }
18
64
  export interface ObservedSessionCollectionSource<T = unknown> {
19
65
  providerId: string;
20
- discover(): Promise<ObservedSessionReference[]> | ObservedSessionReference[];
66
+ discover(options?: ObservedSessionDiscoverOptions): Promise<ObservedSessionReference[]> | ObservedSessionReference[];
21
67
  read(reference: ObservedSessionReference): Promise<T> | T;
22
68
  refreshCached?(reference: ObservedSessionReference, value: T, observedAt: string): Promise<T> | T;
23
69
  /** Low-level invalidation signal; the collector performs fingerprint reconciliation. */
24
- subscribe?(listener: () => void, options?: ObservedSessionSourceSubscribeOptions): {
70
+ subscribe?(listener: ObservedSessionSourceListener, options?: ObservedSessionSourceSubscribeOptions): {
25
71
  dispose(): void;
26
72
  };
73
+ /**
74
+ * Map one watch signal to one session. Absent, or when the signal has no
75
+ * filename, the collector falls back to full discovery.
76
+ */
77
+ resolveReference?(signal: ObservedSessionSourceSignal): Promise<ObservedSessionResolution> | ObservedSessionResolution;
27
78
  dispose?(): void;
28
79
  }
29
80
  export interface ProviderObservedSessionCollectionSource extends ObservedSessionCollectionSource<ObservedAgentSessionV1> {
30
81
  capabilities: ProviderCapabilitiesV1;
31
82
  }
32
- export type ObservedSessionDiagnosticKind = 'provider-discovery-failed' | 'session-read-failed' | 'provider-recovered' | 'session-recovered';
83
+ export type ObservedSessionDiagnosticKind = 'provider-discovery-failed' | 'provider-discovery-completed' | 'session-read-failed' | 'provider-recovered' | 'session-recovered';
33
84
  export type ObservedSessionDiagnosticSeverity = 'info' | 'warning' | 'error';
34
85
  export type ObservedSessionDiagnosticPhase = 'discover' | 'read' | 'recover';
35
- /** Content-safe diagnostics: identifiers and retry metadata only. */
86
+ export type ObservedSessionDiscoveryTrigger = 'event' | 'poll' | 'initial' | 'collect';
87
+ /** Content-safe diagnostics: identifiers, retry metadata, and discovery cost only. */
36
88
  export interface ObservedSessionDiagnostic {
37
89
  kind: ObservedSessionDiagnosticKind;
38
90
  severity: ObservedSessionDiagnosticSeverity;
@@ -41,6 +93,15 @@ export interface ObservedSessionDiagnostic {
41
93
  sessionId?: string;
42
94
  attempt?: number;
43
95
  retryAt?: number;
96
+ /** `provider-discovery-completed` only: what started the discovery. */
97
+ trigger?: ObservedSessionDiscoveryTrigger;
98
+ durationMs?: number;
99
+ referenceCount?: number;
100
+ directoriesListed?: number;
101
+ directoriesStatted?: number;
102
+ filesStatted?: number;
103
+ /** True when `limit` or `since` bounded the discovery. */
104
+ partial?: boolean;
44
105
  }
45
106
  export interface ObservedSessionCollection<T = unknown> {
46
107
  providerId: string;
@@ -66,6 +127,23 @@ export interface ObservedSessionCollectorOptions<T = unknown> {
66
127
  yieldBetweenReads?: () => Promise<void> | void;
67
128
  onObservation?: (observation: ObservedSessionCollection<T>) => void;
68
129
  onDiagnostic?: (diagnostic: ObservedSessionDiagnostic) => void;
130
+ /**
131
+ * Ceiling on the wait between two full discoveries of one provider
132
+ * (default 2 s). The wait actually applied is the smaller of this and four
133
+ * times the previous discovery's duration, so cheap sources stay prompt.
134
+ */
135
+ minReconcileGapMs?: number;
136
+ /** Parse-cache bound by entry count (default 20 000), least-recently-observed first. */
137
+ maxCacheEntries?: number;
138
+ /** Parse-cache bound by approximate bytes (default 128 MiB). */
139
+ maxCacheBytes?: number;
140
+ /** Size estimate per cached value; defaults to the JSON length, computed once per parse. */
141
+ approximateValueBytes?: (value: T) => number;
142
+ }
143
+ /** Bounds for one `collect()`; a bounded pass never evicts sessions outside it. */
144
+ export interface ObservedSessionCollectOptions {
145
+ limit?: number;
146
+ since?: number;
69
147
  }
70
148
  export type ObservedSessionChangeType = 'added' | 'changed' | 'removed';
71
149
  export interface ObservedSessionChange {
@@ -90,6 +168,8 @@ export interface KnownObservedSessionFingerprint {
90
168
  export interface ObservedSessionSubscribeOptions {
91
169
  debounceMs?: number;
92
170
  pollIntervalMs?: number;
171
+ /** Overrides the collector's `minReconcileGapMs` for this subscription. */
172
+ minReconcileGapMs?: number;
93
173
  knownFingerprints?: readonly KnownObservedSessionFingerprint[];
94
174
  }
95
175
  /**
@@ -101,16 +181,33 @@ export declare class ObservedSessionCollector<T = unknown> {
101
181
  private readonly failures;
102
182
  private readonly cache;
103
183
  private readonly subscriptions;
184
+ /** Latest complete reference set per provider, kept current by scoped reconciles. */
185
+ private readonly lastDiscovery;
186
+ /** One full discovery per provider at a time; concurrent callers share it. */
187
+ private readonly inflightDiscovery;
188
+ private readonly fullPassState;
189
+ /** Scoped results newer than an in-flight walk, so the walk cannot undo them. */
190
+ private readonly scopedReferences;
191
+ private generation;
192
+ private passId;
104
193
  private readonly initialBackoffMs;
105
194
  private readonly maxBackoffMs;
106
195
  private readonly clock;
107
196
  private readonly maxConcurrentReads;
197
+ private readonly minReconcileGapMs;
108
198
  private readonly yieldBetweenReads;
109
199
  constructor(options: ObservedSessionCollectorOptions<T>);
110
- collect(): Promise<ObservedSessionCollection<T>[]>;
200
+ collect(options?: ObservedSessionCollectOptions): Promise<ObservedSessionCollection<T>[]>;
201
+ /** Number of parsed sessions currently cached. */
202
+ get cacheSize(): number;
111
203
  /**
112
204
  * Subscribe to debounced provider changes. The listener receives fingerprints
113
205
  * only; call collect() to consume changed sessions through the parse cache.
206
+ *
207
+ * A signal that names a file is reconciled with one stat. Signals without a
208
+ * filename, catch-up polls, and the initial pass run a full discovery, at
209
+ * most once per gap per provider; bursts inside the debounce window join a
210
+ * single trailing pass.
114
211
  */
115
212
  subscribe(listener: (batch: ObservedSessionChangeBatch) => void, options?: ObservedSessionSubscribeOptions): {
116
213
  dispose(): void;
@@ -121,6 +218,21 @@ export declare class ObservedSessionCollector<T = unknown> {
121
218
  private collectSession;
122
219
  private makeObservation;
123
220
  private emitObservation;
221
+ /**
222
+ * Runs `discover()` once per provider at a time. Unbounded discoveries are
223
+ * shared with concurrent callers and update the gap bookkeeping; every
224
+ * discovery emits one payload-free cost diagnostic.
225
+ */
226
+ private runDiscovery;
227
+ /**
228
+ * Starts (or joins) a discovery and reports the generation it started at,
229
+ * so a reconcile that joins a walk begun earlier by `collect()` compares
230
+ * scoped results against the walk's start rather than its own entry.
231
+ */
232
+ private startDiscovery;
233
+ private effectiveGapMs;
234
+ /** Reconcile one watch signal against `known` with at most one stat. */
235
+ private reconcileSignal;
124
236
  private reconcileSource;
125
237
  private fingerprint;
126
238
  private evictMissing;