sidekick-shared 0.27.6 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +59 -18
- package/dist/browser.d.ts +13 -2
- package/dist/browser.js +30 -2
- package/dist/claudePaths.d.ts +11 -0
- package/dist/claudePaths.js +61 -0
- package/dist/claudeProfiles.d.ts +2 -9
- package/dist/claudeProfiles.js +10 -25
- package/dist/codexPaths.d.ts +22 -0
- package/dist/codexPaths.js +67 -0
- package/dist/codexProfiles.d.ts +1 -4
- package/dist/codexProfiles.js +5 -43
- package/dist/doctor.js +2 -2
- package/dist/esm/accountChangeSignal.js +15 -0
- package/dist/esm/accountChanges.js +152 -0
- package/dist/esm/accountHealth.js +288 -0
- package/dist/esm/accountLaunch.js +145 -0
- package/dist/esm/accountLease.js +60 -0
- package/dist/esm/accountManager.js +606 -0
- package/dist/esm/accountRegistry.js +214 -0
- package/dist/esm/accountStatus.js +51 -0
- package/dist/esm/accountSwitch.js +74 -0
- package/dist/esm/accountSync.js +156 -0
- package/dist/esm/accountSyncTypes.js +4 -0
- package/dist/esm/accounts.js +1291 -0
- package/dist/esm/aggregation/EventAggregator.js +2034 -0
- package/dist/esm/aggregation/FrequencyTracker.js +69 -0
- package/dist/esm/aggregation/HeatmapTracker.js +89 -0
- package/dist/esm/aggregation/PatternExtractor.js +168 -0
- package/dist/esm/aggregation/costProvenance.js +31 -0
- package/dist/esm/aggregation/snapshot.js +161 -0
- package/dist/esm/aggregation/types.js +5 -0
- package/dist/esm/analytics/codeImpact.js +18 -0
- package/dist/esm/analytics/compactionLedger.js +37 -0
- package/dist/esm/analytics/qualityScore.js +112 -0
- package/dist/esm/autoSwitch.js +185 -0
- package/dist/esm/browser.js +34 -0
- package/dist/esm/claudeCredentialDoctor.js +239 -0
- package/dist/esm/claudeCredentialLedger.js +91 -0
- package/dist/esm/claudeCredentials.js +111 -0
- package/dist/esm/claudeLiveGuard.js +43 -0
- package/dist/esm/claudePaths.js +22 -0
- package/dist/esm/claudeProfiles.js +142 -0
- package/dist/esm/claudeRefreshLock.js +106 -0
- package/dist/esm/codexAuth.js +101 -0
- package/dist/esm/codexCredentialDoctor.js +265 -0
- package/dist/esm/codexCredentialStore.js +164 -0
- package/dist/esm/codexKeepAlive.js +112 -0
- package/dist/esm/codexPaths.js +172 -0
- package/dist/esm/codexProfiles.js +1251 -0
- package/dist/esm/codexQuota.js +564 -0
- package/dist/esm/codexQuotaWatcher.js +363 -0
- package/dist/esm/context/composer.js +71 -0
- package/dist/esm/context/sessionContext.js +546 -0
- package/dist/esm/credentialIO.js +283 -0
- package/dist/esm/credentials.js +49 -0
- package/dist/esm/doctor.js +305 -0
- package/dist/esm/ensureDefaultAccounts.js +62 -0
- package/dist/esm/errorHistory.js +56 -0
- package/dist/esm/extractors/errorTaxonomy.js +43 -0
- package/dist/esm/extractors/gatherAssets.js +32 -0
- package/dist/esm/extractors/sessionAssets.js +176 -0
- package/dist/esm/extractors/sources/claudeAssets.js +158 -0
- package/dist/esm/extractors/sources/codexAssets.js +234 -0
- package/dist/esm/extractors/tokenUsage.js +41 -0
- package/dist/esm/extractors/toolCall.js +142 -0
- package/dist/esm/failingTools.js +65 -0
- package/dist/esm/fileHead.js +27 -0
- package/dist/esm/formatters/eventHighlighter.js +332 -0
- package/dist/esm/formatters/noiseClassifier.js +209 -0
- package/dist/esm/formatters/sessionDump.js +328 -0
- package/dist/esm/formatters/toolSummary.js +226 -0
- package/dist/esm/formatting.js +82 -0
- package/dist/esm/handoffUrl.js +23 -0
- package/dist/esm/historicalStore.js +305 -0
- package/dist/esm/humanPrompt.js +88 -0
- package/dist/esm/index.js +213 -0
- package/dist/esm/keepAlive.js +189 -0
- package/dist/esm/liveCredentialGuard.js +33 -0
- package/dist/esm/modelAliases.js +51 -0
- package/dist/esm/modelCatalog.js +139 -0
- package/dist/esm/modelContext.js +280 -0
- package/dist/esm/modelInfo.js +832 -0
- package/dist/esm/multiProviderQuotaService.js +450 -0
- package/dist/esm/node.js +46 -0
- package/dist/esm/observedContextWindows.js +165 -0
- package/dist/esm/observedSessionCollector.js +939 -0
- package/dist/esm/parsers/changelogParser.js +71 -0
- package/dist/esm/parsers/codexHistory.js +89 -0
- package/dist/esm/parsers/codexParser.js +906 -0
- package/dist/esm/parsers/debugLogParser.js +126 -0
- package/dist/esm/parsers/jsonl.js +66 -0
- package/dist/esm/parsers/mcpToolName.js +28 -0
- package/dist/esm/parsers/openCodeParser.js +625 -0
- package/dist/esm/parsers/planExtractor.js +335 -0
- package/dist/esm/parsers/sessionActivityDetector.js +246 -0
- package/dist/esm/parsers/sessionPathResolver.js +713 -0
- package/dist/esm/parsers/subagentScanner.js +360 -0
- package/dist/esm/parsers/subagentStatsCache.js +45 -0
- package/dist/esm/parsers/subagentTraceParser.js +325 -0
- package/dist/esm/paths.js +134 -0
- package/dist/esm/peakHours.js +194 -0
- package/dist/esm/phrases.js +1330 -0
- package/dist/esm/pricingCatalog.js +247 -0
- package/dist/esm/processDetection.js +200 -0
- package/dist/esm/projectMigration.js +59 -0
- package/dist/esm/promptHistory.js +1221 -0
- package/dist/esm/providerFailure.js +362 -0
- package/dist/esm/providerIds.js +6 -0
- package/dist/esm/providerQuota.js +1 -0
- package/dist/esm/providerServiceStatus.js +145 -0
- package/dist/esm/providerServiceStatusTypes.js +1 -0
- package/dist/esm/providerStatus.js +117 -0
- package/dist/esm/providers/claudeCode.js +575 -0
- package/dist/esm/providers/claudeListing.js +121 -0
- package/dist/esm/providers/codex.js +1034 -0
- package/dist/esm/providers/codexDatabase.js +297 -0
- package/dist/esm/providers/codexRollouts.js +215 -0
- package/dist/esm/providers/detect.js +185 -0
- package/dist/esm/providers/diagnostics.js +83 -0
- package/dist/esm/providers/directoryListingCache.js +206 -0
- package/dist/esm/providers/factory.js +54 -0
- package/dist/esm/providers/openCode.js +2008 -0
- package/dist/esm/providers/openCodeDatabase.js +419 -0
- package/dist/esm/providers/rolloutWalker.js +252 -0
- package/dist/esm/providers/types.js +12 -0
- package/dist/esm/quota.js +182 -0
- package/dist/esm/quotaHistory.js +364 -0
- package/dist/esm/quotaPoller.js +230 -0
- package/dist/esm/quotaPresentation.js +97 -0
- package/dist/esm/quotaResolver.js +231 -0
- package/dist/esm/quotaSnapshots.js +130 -0
- package/dist/esm/quotaThresholds.js +85 -0
- package/dist/esm/readers/decisions.js +24 -0
- package/dist/esm/readers/handoff.js +20 -0
- package/dist/esm/readers/helpers.js +27 -0
- package/dist/esm/readers/history.js +9 -0
- package/dist/esm/readers/notes.js +48 -0
- package/dist/esm/readers/plans.js +225 -0
- package/dist/esm/readers/tasks.js +19 -0
- package/dist/esm/report/htmlHelpers.js +280 -0
- package/dist/esm/report/htmlReportGenerator.js +704 -0
- package/dist/esm/report/index.js +7 -0
- package/dist/esm/report/logo.js +2 -0
- package/dist/esm/report/openBrowser.js +19 -0
- package/dist/esm/report/sessionReportInputs.js +33 -0
- package/dist/esm/report/transcriptParser.js +83 -0
- package/dist/esm/report/types.js +4 -0
- package/dist/esm/schemas/accountManager.js +204 -0
- package/dist/esm/schemas/accountStatus.js +25 -0
- package/dist/esm/schemas/assistantTurn.js +74 -0
- package/dist/esm/schemas/index.js +25 -0
- package/dist/esm/schemas/observedSessionV1.js +77 -0
- package/dist/esm/schemas/providerFailure.js +37 -0
- package/dist/esm/schemas/quota.js +132 -0
- package/dist/esm/schemas/quotaHistory.js +40 -0
- package/dist/esm/schemas/sessionEvent.js +216 -0
- package/dist/esm/schemas/stateFile.js +75 -0
- package/dist/esm/schemas/tokenEstimation.js +7 -0
- package/dist/esm/schemas/transcript.js +86 -0
- package/dist/esm/schemas/usageNormalization.js +38 -0
- package/dist/esm/search/advancedFilter.js +197 -0
- package/dist/esm/search/sessionSearch.js +66 -0
- package/dist/esm/sessionFingerprint.js +40 -0
- package/dist/esm/sessionMonitor.js +198 -0
- package/dist/esm/sessionPreviews.js +522 -0
- package/dist/esm/sessionPromptHistory.js +254 -0
- package/dist/esm/sessionPromptSignals.js +364 -0
- package/dist/esm/sessionStats.js +160 -0
- package/dist/esm/sessionTokenTotals.js +98 -0
- package/dist/esm/sessionTranscripts.js +49 -0
- package/dist/esm/stateFile.js +119 -0
- package/dist/esm/statusline/BurnRateCalculator.js +40 -0
- package/dist/esm/statusline/claudeStatuslinePayload.js +148 -0
- package/dist/esm/statusline/formatter.js +122 -0
- package/dist/esm/statusline/index.js +8 -0
- package/dist/esm/terminalSync.js +95 -0
- package/dist/esm/testing/credentialGuard.js +222 -0
- package/dist/esm/testing/index.js +12 -0
- package/dist/esm/testing/sessionLogFixtures.js +128 -0
- package/dist/esm/tokenEstimation.js +67 -0
- package/dist/esm/tokenSummary.js +113 -0
- package/dist/esm/toolCategory.js +82 -0
- package/dist/esm/transcript.js +257 -0
- package/dist/esm/turns/assistantTurn.js +373 -0
- package/dist/esm/types/codex.js +23 -0
- package/dist/esm/types/decisionLog.js +5 -0
- package/dist/esm/types/historicalData.js +47 -0
- package/dist/esm/types/knowledgeNote.js +15 -0
- package/dist/esm/types/observedSessionV1.js +257 -0
- package/dist/esm/types/opencode.js +12 -0
- package/dist/esm/types/plan.js +7 -0
- package/dist/esm/types/sessionEvent.js +10 -0
- package/dist/esm/types/taskPersistence.js +12 -0
- package/dist/esm/usage/billingBlocks.js +148 -0
- package/dist/esm/usage/claudeUsageDedupe.js +189 -0
- package/dist/esm/usage/importSessionHistory.js +84 -0
- package/dist/esm/usage/subagentUsage.js +18 -0
- package/dist/esm/usage/usageEvents.js +402 -0
- package/dist/esm/usage/usageReports.js +202 -0
- package/dist/esm/usageNormalization.js +95 -0
- package/dist/esm/watchers/eventBridge.js +219 -0
- package/dist/esm/watchers/factory.js +63 -0
- package/dist/esm/watchers/jsonlTail.js +289 -0
- package/dist/esm/watchers/jsonlWatcher.js +435 -0
- package/dist/esm/watchers/providerReaderWatcher.js +118 -0
- package/dist/esm/watchers/sqliteWatcher.js +285 -0
- package/dist/esm/watchers/types.js +4 -0
- package/dist/esm/workspaceRoots.js +56 -0
- package/dist/esm/writers/atomic.js +375 -0
- package/dist/esm/writers/decisions.js +51 -0
- package/dist/esm/writers/notes.js +46 -0
- package/dist/esm/writers/tasks.js +63 -0
- package/dist/esm/zaiQuota.js +323 -0
- package/dist/esm/zaiQuotaApi.js +271 -0
- package/dist/esm/zaiQuotaWatcher.js +265 -0
- package/dist/fileHead.d.ts +22 -0
- package/dist/fileHead.js +33 -0
- package/dist/index.d.ts +16 -7
- package/dist/index.js +49 -15
- package/dist/node.d.ts +13 -1
- package/dist/node.js +43 -2
- package/dist/parsers/codexHistory.js +2 -2
- package/dist/parsers/codexParser.d.ts +12 -0
- package/dist/parsers/codexParser.js +34 -12
- package/dist/parsers/debugLogParser.js +2 -2
- package/dist/parsers/sessionPathResolver.js +5 -4
- package/dist/promptHistory.d.ts +32 -0
- package/dist/promptHistory.js +115 -59
- package/dist/providerFailure.d.ts +12 -6
- package/dist/providerFailure.js +45 -0
- package/dist/providers/claudeCode.js +7 -99
- package/dist/providers/claudeListing.d.ts +22 -0
- package/dist/providers/claudeListing.js +158 -0
- package/dist/providers/codex.d.ts +3 -1
- package/dist/providers/codex.js +26 -227
- package/dist/providers/codexRollouts.d.ts +44 -0
- package/dist/providers/codexRollouts.js +261 -0
- package/dist/providers/detect.js +4 -4
- package/dist/readers/plans.js +3 -3
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +7 -2
- package/dist/schemas/providerFailure.d.ts +154 -0
- package/dist/schemas/providerFailure.js +40 -0
- package/dist/sessionPromptHistory.d.ts +12 -7
- package/dist/sessionPromptHistory.js +15 -3
- package/dist/sessionPromptSignals.d.ts +9 -0
- package/dist/sessionPromptSignals.js +13 -0
- package/dist/testing/credentialGuard.d.ts +23 -0
- package/dist/testing/credentialGuard.js +258 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +22 -0
- package/dist/testing/sessionLogFixtures.d.ts +28 -0
- package/dist/testing/sessionLogFixtures.js +169 -0
- package/dist/tokenEstimation.d.ts +2 -0
- package/dist/tokenEstimation.js +21 -11
- package/dist/toolCategory.d.ts +18 -0
- package/dist/toolCategory.js +86 -0
- package/dist/types/codex.d.ts +4 -0
- package/dist/usage/usageEvents.d.ts +16 -0
- package/dist/usage/usageEvents.js +53 -9
- package/dist/watchers/jsonlTail.d.ts +26 -1
- package/dist/watchers/jsonlTail.js +136 -28
- package/dist/watchers/jsonlWatcher.js +7 -0
- package/dist/watchers/providerReaderWatcher.js +1 -0
- package/dist/watchers/types.d.ts +6 -0
- package/dist/workspaceRoots.d.ts +23 -0
- package/dist/workspaceRoots.js +93 -0
- package/package.json +22 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ 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.28.1] - 2026-10-18
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **`installCredentialGuard()` keeps `promisify(execFile)` working.** The guard replaced `child_process.execFile` and `exec` without Node's `util.promisify.custom`, so `promisify(execFile)(...)` resolved to the bare stdout string and `const { stdout } = await promisify(execFile)(...)` read `undefined`. The guarded functions now carry a guarded `promisify.custom` that delegates to Node's own, so it resolves to `{ stdout, stderr }` again, rejects with an error carrying `stdout` / `stderr`, and keeps `.child`; a blocked binary on the promisified path is recorded and rejects.
|
|
13
|
+
|
|
14
|
+
## [0.28.0] - 2026-10-18
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Tree-shakable ES modules for bundlers.** Every exports subpath gains a `module` condition pointing at an ES-module build in `dist/esm/` (esbuild, Vite, Rollup, and webpack read it ahead of `import`/`require`). Node never reads `module` and keeps loading CommonJS, so a process cannot hold two copies of module state; `./dist/esm/*` is blocked from the `dist/*` wildcard. One helper from `/node` now bundles in hundreds of bytes instead of about 366 KB.
|
|
19
|
+
- **Narrow-entry exports.** `sidekick-shared/browser`: `CodexRolloutParser` (with `DEFAULT_MAX_TRACKED_TOOL_CALLS` and `CodexRolloutParserOptions`), the Codex tool-name helpers, the session-event and Codex rollout types (including `CompactionEvent` and `ContextAttribution`), `isAggregateCodexLimit()`, `isHumanPrompt()` / `humanPromptText()` and the human entrypoint lists, `renderHandoffUrlTemplate()`, the provider-failure identifier arrays, `ASCII_CHARS_PER_TOKEN`, and `classifyTool()`. `sidekick-shared/node`: `getLiveClaudeHome()`, `getDefaultClaudeHome()`, `isDefaultClaudeHome()`, `getClaudeProjectsDir()`, `getSystemCodexHome()`, `getCodexMonitoringHomes()`, `resolveSidekickCodexHome()`, `getCodexExecutionEnv()`, `getCodexSessionsDirs()`, `getConfigDir()` / `CONFIG_DIR_ENV_VAR`, `encodeClaudeWorkspacePath()` / `getClaudeSessionDirectory()`, `resolveWorkspaceRoots()`, `resolveWorktreeMainRepo()` / `discoverWorktreeSiblings()`, and `createJsonlTail()`.
|
|
20
|
+
- **`sidekick-shared/testing`.** `installCredentialGuard()` keeps a test process away from the real `security` / `claude` / `codex` binaries and the real Claude, Codex, and Sidekick homes (framework-free; Node 20.16+, or CommonJS on older Node; temp home removed on exit; `SIDEKICK_CONFIG_DIR` cleared), plus the Claude Code and Codex session-log builders. The internal vitest setup is now a thin shim over it.
|
|
21
|
+
- **Provider-failure schema.** `PROVIDER_FAILURE_CODES`, `PROVIDER_RECOVERY_ACTIONS`, `PROVIDER_CREDENTIAL_KINDS`, `PROVIDER_AUTHENTICATION_STATES`, `PROVIDER_AUTHENTICATION_SOURCES`, and `PROVIDER_FAILURE_EVIDENCE_SOURCES` define the existing union types, and `providerFailureDiagnosisSchema` (plus the evidence, authentication, and retry-after schemas) on `sidekick-shared/schemas` is built from them.
|
|
22
|
+
- **Prompt-history change reporting.** `collectPromptHistory()` results add `changed`, `progressed`, and `roots`; entries, whole sessions, `unread`, and `changed` carry an opaque `sessionKey`; `collectSessionPromptHistory()` accepts `sessionRefs` matched on (provider, sessionId) or one file; `isPromptHistorySessionSettled()` and `parsePromptHistoryCursor()` are exported.
|
|
23
|
+
- **Tool categories on signals.** `classifyTool(name, { mcpServer })` and `TOOL_CATEGORIES`; prompt-history signals that name a tool carry `toolCategory` and, for MCP calls, `mcpServer` (Codex's `invocation.server` / `server` was dropped before).
|
|
24
|
+
- **Multi-root usage.** `collectUsageEvents({ workspacePaths, includeWorktrees })` lists several roots in one call and counts each session file once; results add `roots`, and events add `filePath`.
|
|
25
|
+
- **Bounded JSONL tail.** `createJsonlTail()` gains `maxReadBytes` (1 MiB chunks), `maxLineBytes` (16 MiB, longer lines skipped and reported), each line's `{ offset, length }` as `onEvent`'s second argument, and `onReset({ reason, previousOffset })` for `truncated`, `rewritten` (first 4 KiB or the byte before the resume point changed), and `replaced` (another inode) files.
|
|
26
|
+
- `SessionWatcherCallbacks.onReset`: the JSONL and provider-reader watchers call it when the session file is truncated, rewritten, or replaced and its events are delivered again from the start.
|
|
27
|
+
- `getCodexSessionsDirs()`, `CODEX_SESSIONS_SUBDIR`, `CODEX_ARCHIVED_SESSIONS_SUBDIR`, and `CodexDbThread.archived` / `archived_at`.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **`CLAUDE_CONFIG_DIR`.** Claude session discovery, path resolution, provider detection, doctor, plans, and debug logs hard-coded `~/.claude`; they now use the live Claude home, as every credential and identity read already did.
|
|
32
|
+
- **Archived Codex rollouts.** Rollout lookup, listings, and watch roots include each home's `archived_sessions/`, and a prompt-history cursor entry follows a session whose file moved there (when the new file starts with the recorded head) instead of re-reading it as new. An `archived_sessions/` directory created after a watcher starts is picked up by its catch-up poll.
|
|
33
|
+
- `getCodexExecutionEnv(baseEnv)` keeps a non-blank `CODEX_HOME` from `baseEnv`.
|
|
34
|
+
- `CodexRolloutParser` bounds its emitted-tool, expanded-patch, and pending exec/MCP tables (`maxTrackedToolCalls`, default 4096).
|
|
35
|
+
- The session watcher resets its Claude usage de-duplication and Codex state when its tail starts over.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- `sidekick-shared/node` no longer reaches the account-switching modules: Codex home resolution moved to `codexPaths` (re-exported from `codexProfiles`), and prompt history lists files through standalone `listClaudeSessionFilesAsync()` / `listCodexSessionFilesAsync()` instead of constructing providers (`collectPromptHistory` bundles in 30 KB instead of 170 KB).
|
|
40
|
+
- `estimateTextTokens()` counts a leading ASCII run without regex tests (about 15× faster, identical results).
|
|
41
|
+
|
|
8
42
|
## [0.27.6] - 2026-09-26
|
|
9
43
|
|
|
10
44
|
### Fixed
|
package/README.md
CHANGED
|
@@ -9,6 +9,8 @@ Types, parsers, providers, readers, formatters, aggregation, search, reporting,
|
|
|
9
9
|
|
|
10
10
|
## Recent additions
|
|
11
11
|
|
|
12
|
+
- **0.28.1: credential guard keeps `promisify(execFile)`** — after `installCredentialGuard()`, `promisify(execFile)` and `promisify(exec)` resolve to `{ stdout, stderr }` again (0.28.0 dropped Node's `util.promisify.custom`, so they returned the bare stdout string), and the promisified calls are guarded too.
|
|
13
|
+
- **0.28.0: ES modules, narrow entries, and new readers** — a `module` export condition gives bundlers a tree-shakable ES-module build (Node keeps CommonJS); browser-safe parsers and helpers move onto `/browser` and the provider-home helpers onto `/node`; `sidekick-shared/testing` publishes the credential guard; `providerFailureDiagnosisSchema` joins `/schemas`; prompt history reports `changed` / `progressed` / `roots` and takes `sessionRefs`; signals carry `toolCategory` and `mcpServer`; `collectUsageEvents()` takes `workspacePaths`; `createJsonlTail()` is bounded and reports resets; and Claude sessions follow `CLAUDE_CONFIG_DIR` while Codex lookups include `archived_sessions/`.
|
|
12
14
|
- **0.27.6: one usable copy per login** — Claude Code and Codex rotate refresh tokens, so a second usable copy of a login invalidates the first ("Not logged in · Please run /login"). The live account now keeps no profile-home credential, only a private backup; `syncLiveAccountState()` demotes a leftover copy (installing it first when it is newer) and reports `demoted`, `repaired`, and `journal`. Live writes pass `decideLiveClaudeWrite()` or the Codex equivalent: a switch captures the outgoing login first even with `force`, holds Claude Code's refresh lock, is journaled so the next sync finishes or rolls it back, and keeps live MCP tokens. Claude Keychain writes use Claude Code's hex method and are read back (`ClaudeCredentialWriteError`), so blobs over about 4 KB are no longer truncated. New root APIs: `readClaudeCredentialStore()`, `inspectClaudeCredentialStores()` / `repairClaudeCredentialStores()`, `inspectCodexCredentialStores()` / `repairCodexCredentialStores()`, `readClaudeCredentialLedger()`, `readStoredCodexAccount()`, `syncCodexLiveStateAsync()`, `discardAccountLogin()`, `writeAccountLauncher()`, and non-persisting health inspection (`persist: false`). `writeActiveCredentials()` now requires a config directory; `writeLauncher()`, `applyActiveClaudeToLiveHome()`, and `resolveActiveClaudeHome()` are deprecated.
|
|
13
15
|
- **0.27.5: whole-session prompt history** — `collectSessionPromptHistory()` (root and Node) returns every human prompt of each matching Claude Code or Codex session, grouped by session and read from the start with the `collectPromptHistory()` scanners, so text, scope, model and usage, and ordinals are identical. Select with `sessionIds`, `since` (file mtime), or `limit`; each session carries `startedAt` / `lastActivityAt`, `cwds`, `gitBranches`, `models`, and `complete` / `truncated` / `droppedPrompts` / `excludedRecords`. `include.replies` adds the agent's last text for each prompt, and `include.signals` adds `interrupt`, `toolRejected`, `toolError`, `compaction`, `apiError`, and `rollback` signals. Sessions that `maxSessions`, `maxTotalBytes`, the deadline, or an abort cut off are listed in `unread` instead of being returned partially.
|
|
14
16
|
- **0.27.4: usage events from the Node entry** — `sidekick-shared/node` now exports `createSessionProviders()`, `SYNTHETIC_MODEL`, and the `ProviderId` / `SessionProviderBase` / `SessionProviderDiagnostic` / `CreateSessionProviders*` types, so `collectUsageEvents()` callers never import the package root (a CommonJS barrel that bundlers cannot tree-shake). `collectUsageEvents()` accepts an optional `signal` that stops the collection before listing and between sessions.
|
|
@@ -133,17 +135,36 @@ returns the platform default that both overrides bypass.
|
|
|
133
135
|
|
|
134
136
|
`sidekick-shared` ships three public entry points plus a few convenience subpaths. Pick the one that matches your runtime. As of 0.25.0 every documented subpath declares explicit `types` / `import` / `require` / `default` export conditions and resolves under Vite and TypeScript's legacy `moduleResolution: node` without consumer-side aliases.
|
|
135
137
|
|
|
136
|
-
| Path | Runtime | What it exposes
|
|
137
|
-
| ------------------------------ | -------------------------- |
|
|
138
|
-
| `sidekick-shared` | Node (CLI, extension host) | Full public API (readers, providers, parsers, pricing, …).
|
|
139
|
-
| `sidekick-shared/browser` | **Browser / webview** | Pure helpers: usage normalization/pricing, token estimation, transcript and assistant-turn projection, model/context math, `parseMcpToolName()`.
|
|
140
|
-
| `sidekick-shared/node` | Node only | LiteLLM pricing and context-window hydration, public provider service status (`fetchProviderServiceStatus()`), observed context-window persistence, recent-session/transcript reads, human prompt history (`collectPromptHistory()`, and whole sessions with `collectSessionPromptHistory()`), usage events from session logs (`collectUsageEvents()` with `createSessionProviders()` and `SYNTHETIC_MODEL`), session previews (`listSessionPreviews()` / `readSessionPreview()` plus the bounded-concurrency `listSessionPreviewsAsync()` / `readSessionPreviewAsync()`), Codex history/rollout lookup (`readCodexHistory()`, `findCodexRolloutFile()`),
|
|
141
|
-
| `sidekick-shared/phrases` | Any runtime | Phrase arrays + `getRandomPhrase()`.
|
|
142
|
-
| `sidekick-shared/modelContext` | Any runtime | Direct access to the context-window module.
|
|
143
|
-
| `sidekick-shared/modelInfo` | Any runtime | Direct access to model parsing and cost math.
|
|
144
|
-
| `sidekick-shared/formatting` | Any runtime | Direct access to pure token and duration display helpers.
|
|
145
|
-
| `sidekick-shared/schemas` | Any runtime | Pure Zod boundary schemas (session events, assistant turns, observed-session V1, quota, account status, account management, quota history, the `state.json` contract) — fs-free, no Node builtins.
|
|
146
|
-
| `sidekick-shared/statusline` | Node only | Cache-only statusline surface: account status + quota snapshot readers and writers, `formatStatusline()`, burn-rate estimates, quota freshness helpers, `parseClaudeStatuslinePayload()` / `quotaFromStatuslinePayload()`, and `readStateFile()` / `writeStateFile()`.
|
|
138
|
+
| Path | Runtime | What it exposes |
|
|
139
|
+
| ------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
140
|
+
| `sidekick-shared` | Node (CLI, extension host) | Full public API (readers, providers, parsers, pricing, …). |
|
|
141
|
+
| `sidekick-shared/browser` | **Browser / webview** | Pure helpers: usage normalization/pricing, token estimation, transcript and assistant-turn projection, model/context math, `parseMcpToolName()`, the `CodexRolloutParser` with the Codex rollout and session-event types, human-prompt detection (`isHumanPrompt()` / `humanPromptText()`), and `renderHandoffUrlTemplate()`. |
|
|
142
|
+
| `sidekick-shared/node` | Node only | LiteLLM pricing and context-window hydration, public provider service status (`fetchProviderServiceStatus()`), observed context-window persistence, recent-session/transcript reads, human prompt history (`collectPromptHistory()`, and whole sessions with `collectSessionPromptHistory()`), usage events from session logs (`collectUsageEvents()` with `createSessionProviders()` and `SYNTHETIC_MODEL`), session previews (`listSessionPreviews()` / `readSessionPreview()` plus the bounded-concurrency `listSessionPreviewsAsync()` / `readSessionPreviewAsync()`), Codex history/rollout lookup (`readCodexHistory()`, `findCodexRolloutFile()`), resilient observed-session collection (`fs` + providers), the provider homes the CLIs read (`getLiveClaudeHome()`, `getClaudeProjectsDir()`, `getSystemCodexHome()`, `getCodexMonitoringHomes()`, `getCodexExecutionEnv()`), Claude session-directory encoding (`encodeClaudeWorkspacePath()`, `getClaudeSessionDirectory()`), and the config root (`getConfigDir()`, `CONFIG_DIR_ENV_VAR`). |
|
|
143
|
+
| `sidekick-shared/phrases` | Any runtime | Phrase arrays + `getRandomPhrase()`. |
|
|
144
|
+
| `sidekick-shared/modelContext` | Any runtime | Direct access to the context-window module. |
|
|
145
|
+
| `sidekick-shared/modelInfo` | Any runtime | Direct access to model parsing and cost math. |
|
|
146
|
+
| `sidekick-shared/formatting` | Any runtime | Direct access to pure token and duration display helpers. |
|
|
147
|
+
| `sidekick-shared/schemas` | Any runtime | Pure Zod boundary schemas (session events, assistant turns, observed-session V1, quota, account status, account management, quota history, the `state.json` contract) — fs-free, no Node builtins. |
|
|
148
|
+
| `sidekick-shared/statusline` | Node only | Cache-only statusline surface: account status + quota snapshot readers and writers, `formatStatusline()`, burn-rate estimates, quota freshness helpers, `parseClaudeStatuslinePayload()` / `quotaFromStatuslinePayload()`, and `readStateFile()` / `writeStateFile()`. |
|
|
149
|
+
| `sidekick-shared/testing` | Node test runners | `installCredentialGuard()` keeps a test process away from the real `security` / `claude` / `codex` binaries and the real Claude, Codex, and Sidekick homes, and the Claude Code / Codex session-log builders (`createSessionLogFixtures()`, `writeJsonl()`, …). Framework-free. |
|
|
150
|
+
|
|
151
|
+
Since 0.28.0 every subpath also has a `module` condition pointing at an ES-module build in `dist/esm/`. Bundlers that read it (esbuild, Vite, Rollup, webpack) tree-shake unused exports, so importing one helper from `sidekick-shared/node` bundles a few hundred bytes instead of the whole entry. Node itself never reads `module` and keeps loading the CommonJS build for both `require` and `import`, so a process never holds two copies of module state.
|
|
152
|
+
|
|
153
|
+
Prefer these paths over `sidekick-shared/dist/*` deep imports. The `dist/*` wildcard still resolves for compatibility, but module files behind it can move between releases without notice.
|
|
154
|
+
|
|
155
|
+
### Test suites
|
|
156
|
+
|
|
157
|
+
`sidekick-shared/testing` is for test suites that run sidekick-shared code against session data. Install the guard once per test process, before anything reads a home or spawns a CLI, and check it after each test:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// vitest setupFiles entry (with `globals: true`)
|
|
161
|
+
import { installCredentialGuard } from 'sidekick-shared/testing';
|
|
162
|
+
|
|
163
|
+
const guard = installCredentialGuard();
|
|
164
|
+
afterEach(() => guard.assertNoViolations());
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The guard points `HOME` (and `USERPROFILE`, `APPDATA`, `LOCALAPPDATA`) at a temp directory it removes on exit, unsets `CLAUDE_CONFIG_DIR`, `CLAUDE_SECURESTORAGE_CONFIG_DIR`, `CODEX_HOME`, and `SIDEKICK_CONFIG_DIR`, and patches the real `child_process` and `fs` modules. Spawning `security`, `claude`, or `codex` throws (a promisified `execFile` or `exec` rejects instead, and otherwise keeps Node's `{ stdout, stderr }` result), writing under the real `~/.claude`, `~/.claude.json`, `~/.codex`, or `~/.config/sidekick` throws, and reads there are recorded. Production code often swallows errors, so `assertNoViolations()` reports what was recorded even when nothing threw. A `vi.mock('child_process')` factory replaces the module and bypasses the guard for that file.
|
|
147
168
|
|
|
148
169
|
### Browser / webview runtimes
|
|
149
170
|
|
|
@@ -345,11 +366,13 @@ const result = await collectPromptHistory({
|
|
|
345
366
|
});
|
|
346
367
|
|
|
347
368
|
for (const entry of result.entries) {
|
|
348
|
-
// { provider, sessionId, ordinal, timestamp, text, cwd, gitBranch?, model?, usage?, metadataStatus }
|
|
369
|
+
// { provider, sessionId, ordinal, timestamp, text, cwd, gitBranch?, model?, usage?, metadataStatus, sessionKey }
|
|
349
370
|
// Upsert by (provider, sessionId, ordinal): a prompt comes back when its answer metadata changes.
|
|
350
371
|
}
|
|
351
372
|
saveCursor(result.cursor); // sensitive local state; fully read unchanged files are skipped next time
|
|
352
373
|
if (result.hasMore) scheduleAnotherCall(); // a bound stopped the pass; the cursor resumes it
|
|
374
|
+
// result.changed: sessions whose cursor entry moved this call; result.progressed: anything new was read;
|
|
375
|
+
// result.roots: the realpaths scanned after worktree expansion
|
|
353
376
|
for (const exclusion of result.exclusions) console.warn('record left out', exclusion); // permanent
|
|
354
377
|
```
|
|
355
378
|
|
|
@@ -360,6 +383,8 @@ for (const exclusion of result.exclusions) console.warn('record left out', exclu
|
|
|
360
383
|
- **Late answers enrich the same prompt.** A prompt can be collected before its answer is written. `metadataStatus` is `pending` (no answering call yet), `provisional` (Claude call still being written, `stop_reason: null`), or `final`. While a file's last prompt is not final, the cursor keeps the byte offset and length of its line, its timestamp, and its answer state so far (first-answer message id, model, and usage, never prompt or answer text). The next call continues from where the file stopped, however far the answer is, and returns the prompt again with the same provider, sessionId, ordinal, timestamp, and text only when its model, usage, or status changed; the text comes from re-reading that one line. A prompt closed by the next prompt without an answer comes back once as `final` with no usage. Consumers should upsert by identity.
|
|
361
384
|
- **Large files are streamed and resumable.** Files are read in 1 MiB chunks and every pass stops after a complete line, so memory stays near one chunk plus one record whatever the file size. `maxFileBytes` is the most one file may read in one call: a file with more left keeps what it returned, records `backlog` in its cursor, is counted in `stats.filesOverSizeLimit`, and continues on the next call even if its size and mtime have not changed. `maxSessions`, `maxTotalBytes`, `maxEntries`, the deadline, and an abort stop the whole call the same way, and `cursor.next` makes the next call start with the file that was stopped, so a large or busy session cannot starve the others. The first file of a call always finishes its first record, so a record larger than the budget still moves forward. Bytes appended during a call and a half-written final line wait for the next call. `boundsHit` lists these resumable stops and `hasMore` says whether calling again would read more. No bound throws.
|
|
362
385
|
- **Permanent exclusions are reported.** A record over `maxRecordBytes` is skipped as it streams past without being buffered, even when it is still being written, and a complete line that is not JSON is skipped. Each is counted (`stats.recordsOverSizeLimit`, `stats.recordsMalformed`) and listed in `exclusions` with its byte offset. A prompt inside such a record is lost and does not consume an ordinal. A file that shrank or whose first 4 KiB changed is treated as rewritten: it is read again from the start with fresh ordinals and counted in `stats.sessionsRewritten`.
|
|
386
|
+
- **Change reporting.** `changed` lists the sessions (provider, sessionId, `sessionKey`) whose cursor entry this call added, advanced, moved, or dropped after a rewrite, so a consumer never has to diff cursor internals. `progressed` is false when nothing new was read, which tells a stalled `hasMore` loop apart from one that is moving. `sessionKey` is opaque and equal to the cursor key; it tells apart two files that carry the same session id. `isPromptHistorySessionSettled(cursor.sessions[key])` says whether a cursor entry is fully read with no prompt waiting for its answer, and `parsePromptHistoryCursor(stored)` validates a stored cursor (versions 1 to 3) and returns it as `version: 3` with malformed entries dropped, or `undefined`.
|
|
387
|
+
- **Moved files.** A session whose file is listed again under another path (Codex moves an archived thread's rollout to `archived_sessions/`) keeps its cursor entry and ordinals instead of being read again as a new session.
|
|
363
388
|
- **Cursor versions.** Output is `version: 3`. Cursors from 0.27.0 (`version: 1`) and 0.27.1 (`version: 2`) are accepted: each file is re-verified once, and a 0.27.1 pending prompt is replayed from its line in resumable passes, so it now settles even when its answer is far away. Files 0.27.1 skipped for size were never in its cursor and are read in full on the first call. Metadata that 0.27.1 already gave up on (a pending replay that exceeded `maxFileBytes`) was not saved and cannot be recovered, and a 0.27.0 cursor still cannot recover prompts it returned without metadata.
|
|
364
389
|
|
|
365
390
|
### Collect whole sessions of prompts
|
|
@@ -373,7 +398,8 @@ const result = await collectSessionPromptHistory({
|
|
|
373
398
|
workspacePaths: ['/Users/me/code/app'], // plus git worktree siblings
|
|
374
399
|
providers: ['claude-code', 'codex'], // default: both
|
|
375
400
|
since: new Date('2026-09-01'), // sessions whose file changed since then, returned whole
|
|
376
|
-
// sessionIds: ['…'], // or exact session ids
|
|
401
|
+
// sessionIds: ['…'], // or exact session ids (any provider)
|
|
402
|
+
// sessionRefs: result.changed, // or (provider, sessionId), pinned to one file by sessionKey
|
|
377
403
|
// limit: 20, // most recent sessions with prompts
|
|
378
404
|
include: { signals: true, replies: true }, // default: prompts only
|
|
379
405
|
bounds: {
|
|
@@ -385,18 +411,18 @@ const result = await collectSessionPromptHistory({
|
|
|
385
411
|
});
|
|
386
412
|
|
|
387
413
|
for (const session of result.sessions) {
|
|
388
|
-
// { provider, sessionId, startedAt, lastActivityAt, cwds, gitBranches, models,
|
|
414
|
+
// { provider, sessionId, sessionKey, startedAt, lastActivityAt, cwds, gitBranches, models,
|
|
389
415
|
// prompts: [{ ordinal, timestamp, text, cwd, gitBranch?, model?, usage?, metadataStatus, reply? }],
|
|
390
|
-
// signals?: [{ kind, timestamp, afterOrdinal, tool?, text?, textTruncated? }],
|
|
416
|
+
// signals?: [{ kind, timestamp, afterOrdinal, tool?, toolCategory?, mcpServer?, text?, textTruncated? }],
|
|
391
417
|
// complete, truncated, droppedPrompts, excludedRecords }
|
|
392
418
|
}
|
|
393
419
|
if (result.unread.length > 0) {
|
|
394
420
|
// A bound stopped the call, or a session changed while it was read:
|
|
395
|
-
// pass these back as `
|
|
421
|
+
// pass these back as `sessionRefs` to continue.
|
|
396
422
|
}
|
|
397
423
|
```
|
|
398
424
|
|
|
399
|
-
- **Whole sessions, no cursor.** Every call reads each session from its first line and never resumes one mid-file. `since` selects files by modification time and never drops older prompts from a returned session. A long-lived consumer can
|
|
425
|
+
- **Whole sessions, no cursor.** Every call reads each session from its first line and never resumes one mid-file. `since` selects files by modification time and never drops older prompts from a returned session. A long-lived consumer can keep a `collectPromptHistory()` cursor, then fetch the sessions in its result's `changed` whole with `sessionRefs: result.changed`. `sessionRefs` match on provider and id, or on one file when `sessionKey` is set; `sessionIds` match on id alone across providers.
|
|
400
426
|
- **Bounds.** `maxSessions`, `maxTotalBytes`, the deadline, and an abort stop the call. Any session they interrupt is listed in `unread` rather than returned partially, and `boundsHit` names the bound. A session that changed while it was being read is also listed in `unread`, with no `boundsHit` entry. A session longer than `maxSessionBytes` is returned with `truncated: true`, and `boundsHit` includes `maxSessionBytes`; keep `maxSessionBytes` at or below `maxTotalBytes`, or a session larger than `maxTotalBytes` is never read. A record over `maxRecordBytes` (default 16 MiB) is skipped and counted in `excludedRecords`.
|
|
401
427
|
- **Completeness.** `complete` is false when the session was truncated, when `droppedPrompts` > 0 (prompts out of scope or without a timestamp, visible as gaps in `ordinal`), or when `excludedRecords` > 0 (oversized or malformed records).
|
|
402
428
|
- **Replies** (`include.replies`): the agent's last text for the prompt's turn. For Claude Code this is the last assistant message with text before the next prompt, with split records joined. For Codex it is `task_complete.last_agent_message`, falling back to the last agent message.
|
|
@@ -404,6 +430,7 @@ if (result.unread.length > 0) {
|
|
|
404
430
|
- `interrupt`: Claude `[Request interrupted by user…]`, or Codex `turn_aborted`.
|
|
405
431
|
- `toolRejected`: Claude only. Carries the rejection reason the person typed, in full. A rejection without a reason and the interrupt Claude Code writes after it count as one signal.
|
|
406
432
|
- `toolError`: a failed tool call, with the tool name and the error text cut to 1024 characters (`textTruncated`).
|
|
433
|
+
- Signals that name a tool also carry `toolCategory` (`shell`, `file_read`, `file_edit`, `search`, `web`, `subagent`, `planning`, `mcp`, or `other`, from `classifyTool()`) and, for MCP calls, `mcpServer`. Claude Code names MCP tools `mcp__<server>__<tool>`; Codex names the bare tool and records the server separately, so `mcpServer` is the only way to tell a Codex MCP tool from a built-in one. `classifyTool(name, { mcpServer })` is exported from the root, `/browser`, and `/node`.
|
|
407
434
|
- `compaction`, `apiError` (including Codex usage-limit errors), and `rollback` (Codex `thread_rolled_back`).
|
|
408
435
|
- **Scope fails closed.** Sessions with no prompt inside the roots are omitted. Replies and signals that follow an out-of-scope prompt are dropped.
|
|
409
436
|
|
|
@@ -550,6 +577,15 @@ const priced = events.filter((event) => event.model !== SYNTHETIC_MODEL);
|
|
|
550
577
|
On abort the promise rejects with the signal's reason (an `AbortError` by
|
|
551
578
|
default); sessions read before the abort keep their cache entries.
|
|
552
579
|
|
|
580
|
+
To cover several workspaces in one call, pass `workspacePaths` instead of
|
|
581
|
+
`workspacePath`. Each root is realpath-resolved and, unless
|
|
582
|
+
`includeWorktrees: false`, expanded with its main checkout and git
|
|
583
|
+
worktrees (`resolveWorkspaceRoots()`, also on `sidekick-shared/node`). Each
|
|
584
|
+
root is listed, and a session file found under several overlapping roots
|
|
585
|
+
is read and counted once. The result's `roots` names what was listed, and
|
|
586
|
+
every event carries the `filePath` of its session. When no root resolves,
|
|
587
|
+
no session is read.
|
|
588
|
+
|
|
553
589
|
### Detect the active session provider
|
|
554
590
|
|
|
555
591
|
For a single-provider surface, auto-detect and construct just one:
|
|
@@ -591,6 +627,8 @@ console.log(`Found ${tasks.length} tasks`);
|
|
|
591
627
|
|
|
592
628
|
`diagnoseProviderFailure()` is a pure, synchronous helper exported from `sidekick-shared` and `sidekick-shared/browser`. The caller decides whether an SDK event is terminal: a Codex `ErrorItem`, including a reconnect notice, must not become terminal merely because its message can be classified.
|
|
593
629
|
|
|
630
|
+
The identifier lists behind the result types are exported alongside it as readonly arrays (`PROVIDER_FAILURE_CODES`, `PROVIDER_RECOVERY_ACTIONS`, `PROVIDER_CREDENTIAL_KINDS`, `PROVIDER_AUTHENTICATION_STATES`, `PROVIDER_AUTHENTICATION_SOURCES`, `PROVIDER_FAILURE_EVIDENCE_SOURCES`). To validate a diagnosis that crossed a process boundary, use `providerFailureDiagnosisSchema` from `sidekick-shared/schemas`; it is built from the same arrays, so it accepts every value a given release can return.
|
|
631
|
+
|
|
594
632
|
```typescript
|
|
595
633
|
import { diagnoseProviderFailure } from 'sidekick-shared/browser';
|
|
596
634
|
|
|
@@ -861,7 +899,8 @@ The boundary schemas — `sessionEventSchema` plus the quota, account-status, ac
|
|
|
861
899
|
Use `createJsonlTail()` when a consumer needs raw parsed events and owns its own aggregation lifecycle. `onBatchComplete` fires once after each drained byte chunk, which lets callers defer expensive UI or metrics updates until parsing for that chunk is complete.
|
|
862
900
|
|
|
863
901
|
```typescript
|
|
864
|
-
import { createJsonlTail
|
|
902
|
+
import { createJsonlTail } from 'sidekick-shared/node';
|
|
903
|
+
import { sessionEventSchema } from 'sidekick-shared/schemas';
|
|
865
904
|
|
|
866
905
|
const tail = createJsonlTail({
|
|
867
906
|
path: '/path/to/session.jsonl',
|
|
@@ -874,6 +913,8 @@ const tail = createJsonlTail({
|
|
|
874
913
|
tail.start();
|
|
875
914
|
```
|
|
876
915
|
|
|
916
|
+
A poll reads from the last position to the end of the file in chunks of `maxReadBytes` (default 1 MiB), so a cold start on a large file never allocates more than one chunk plus one line. `onEvent` receives each line's `{ offset, length }` as its second argument. A line longer than `maxLineBytes` (default 16 MiB) is skipped as it streams past, even while it is still being written, and reported to `onError`. The tail also checks that it is still reading the same content. When the path now names another file (`replaced`), the file shrank (`truncated`), or its first 4 KiB or the byte before the resume point changed (`rewritten`), it starts over from offset 0 and calls `onReset({ reason, previousOffset })` before the events from the start arrive. `createJsonlTail()` is also exported from `sidekick-shared/node`.
|
|
917
|
+
|
|
877
918
|
`SessionWatcherCallbacks.onBatchComplete` is also available through `createWatcher()`. Save aggregation state only after a complete event batch and only when the state includes the full history (a completed replay or a compatible restored checkpoint). Live-only state is incomplete and must not replace a full-history checkpoint. JSONL positions end at complete lines; Codex readers reconstruct parser context when seeking. OpenCode's SQLite timestamp cursor does not persist row-version deduplication, so the dashboards replay OpenCode history instead of restoring a snapshot.
|
|
878
919
|
|
|
879
920
|
### Search a workspace and diagnose its provider
|
package/dist/browser.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type { UsageProvider, UsageSemantics, UsageNormalizationProvenance, Provi
|
|
|
14
14
|
export { formatTokenBreakdown, summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_MAIN_THREAD_LABEL, TOKEN_SESSION_TOTAL_LABEL, TOKEN_SUBAGENTS_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
|
|
15
15
|
export type { TokenSummary, TokenTotalsLike } from './tokenSummary';
|
|
16
16
|
export { ClaudeUsageDeduper, SYNTHETIC_MODEL } from './usage/claudeUsageDedupe';
|
|
17
|
-
export { estimateTextTokens, estimateSerializedTokens } from './tokenEstimation';
|
|
17
|
+
export { ASCII_CHARS_PER_TOKEN, estimateTextTokens, estimateSerializedTokens, } from './tokenEstimation';
|
|
18
18
|
export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod, TokenEstimationConfidence, TokenEstimationOptions, TokenEstimate, } from './tokenEstimation';
|
|
19
19
|
export { projectSessionTranscript } from './transcript';
|
|
20
20
|
export type { TranscriptFidelity, TranscriptSourceProvenance, CanonicalTranscriptBlock, CanonicalTranscriptMessage, CanonicalToolCall, CanonicalTranscriptUsageTotals, CanonicalSessionTranscript, ProjectSessionTranscriptOptions, } from './transcript';
|
|
@@ -40,6 +40,17 @@ export { applySessionSummary, isFileImported, markFileImported, removeSessionSum
|
|
|
40
40
|
export type { ApplySessionSummaryOptions, SessionSummaryFromStatsOptions } from './historicalStore';
|
|
41
41
|
export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
|
|
42
42
|
export type { FailingToolTrend, FailingToolTrendRow, FailingToolWindow } from './failingTools';
|
|
43
|
-
export { diagnoseProviderFailure } from './providerFailure';
|
|
43
|
+
export { diagnoseProviderFailure, PROVIDER_AUTHENTICATION_SOURCES, PROVIDER_AUTHENTICATION_STATES, PROVIDER_CREDENTIAL_KINDS, PROVIDER_FAILURE_CODES, PROVIDER_FAILURE_EVIDENCE_SOURCES, PROVIDER_RECOVERY_ACTIONS, } from './providerFailure';
|
|
44
44
|
export type { ProviderCredentialKind, ProviderAuthenticationEvidence, ProviderFailureInput, ProviderFailureCode, ProviderRecoveryAction, ProviderRetryAfter, ProviderFailureEvidence, ProviderFailureDiagnosis, } from './providerFailure';
|
|
45
45
|
export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
|
|
46
|
+
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';
|
|
47
|
+
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';
|
|
48
|
+
export { isAggregateCodexLimit } from './types/codex';
|
|
49
|
+
export { CodexRolloutParser, DEFAULT_MAX_TRACKED_TOOL_CALLS, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
|
|
50
|
+
export type { CodexRolloutParserOptions } from './parsers/codexParser';
|
|
51
|
+
export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
|
|
52
|
+
export type { HumanPromptProvider } from './humanPrompt';
|
|
53
|
+
export { renderHandoffUrlTemplate } from './handoffUrl';
|
|
54
|
+
export type { HandoffUrlIdentifiers } from './handoffUrl';
|
|
55
|
+
export { classifyTool, TOOL_CATEGORIES } from './toolCategory';
|
|
56
|
+
export type { ClassifyToolOptions, ToolCategory } from './toolCategory';
|
package/dist/browser.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* For pricing hydration (LiteLLM catalog refresh), use `sidekick-shared/node`.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.formatCost = void 0;
|
|
12
|
+
exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.SESSION_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.MODEL_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.ASCII_CHARS_PER_TOKEN = exports.SYNTHETIC_MODEL = exports.ClaudeUsageDeduper = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_SUBAGENTS_LABEL = exports.TOKEN_SESSION_TOTAL_LABEL = exports.TOKEN_MAIN_THREAD_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.formatTokenBreakdown = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
|
|
13
|
+
exports.TOOL_CATEGORIES = exports.classifyTool = exports.renderHandoffUrlTemplate = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.resolveCodexCallUsage = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.DEFAULT_MAX_TRACKED_TOOL_CALLS = exports.CodexRolloutParser = exports.isAggregateCodexLimit = exports.PROVIDER_RECOVERY_ACTIONS = exports.PROVIDER_FAILURE_EVIDENCE_SOURCES = exports.PROVIDER_FAILURE_CODES = exports.PROVIDER_CREDENTIAL_KINDS = exports.PROVIDER_AUTHENTICATION_STATES = exports.PROVIDER_AUTHENTICATION_SOURCES = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.formatCost = exports.sortModelIds = void 0;
|
|
14
14
|
var modelContext_1 = require("./modelContext");
|
|
15
15
|
Object.defineProperty(exports, "getModelContextWindowSize", { enumerable: true, get: function () { return modelContext_1.getModelContextWindowSize; } });
|
|
16
16
|
Object.defineProperty(exports, "resolveModelContextWindow", { enumerable: true, get: function () { return modelContext_1.resolveModelContextWindow; } });
|
|
@@ -32,6 +32,7 @@ var claudeUsageDedupe_1 = require("./usage/claudeUsageDedupe");
|
|
|
32
32
|
Object.defineProperty(exports, "ClaudeUsageDeduper", { enumerable: true, get: function () { return claudeUsageDedupe_1.ClaudeUsageDeduper; } });
|
|
33
33
|
Object.defineProperty(exports, "SYNTHETIC_MODEL", { enumerable: true, get: function () { return claudeUsageDedupe_1.SYNTHETIC_MODEL; } });
|
|
34
34
|
var tokenEstimation_1 = require("./tokenEstimation");
|
|
35
|
+
Object.defineProperty(exports, "ASCII_CHARS_PER_TOKEN", { enumerable: true, get: function () { return tokenEstimation_1.ASCII_CHARS_PER_TOKEN; } });
|
|
35
36
|
Object.defineProperty(exports, "estimateTextTokens", { enumerable: true, get: function () { return tokenEstimation_1.estimateTextTokens; } });
|
|
36
37
|
Object.defineProperty(exports, "estimateSerializedTokens", { enumerable: true, get: function () { return tokenEstimation_1.estimateSerializedTokens; } });
|
|
37
38
|
var transcript_1 = require("./transcript");
|
|
@@ -101,3 +102,30 @@ Object.defineProperty(exports, "failingToolTrend", { enumerable: true, get: func
|
|
|
101
102
|
Object.defineProperty(exports, "mergeFailingToolWindows", { enumerable: true, get: function () { return failingTools_1.mergeFailingToolWindows; } });
|
|
102
103
|
var providerFailure_1 = require("./providerFailure");
|
|
103
104
|
Object.defineProperty(exports, "diagnoseProviderFailure", { enumerable: true, get: function () { return providerFailure_1.diagnoseProviderFailure; } });
|
|
105
|
+
Object.defineProperty(exports, "PROVIDER_AUTHENTICATION_SOURCES", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_AUTHENTICATION_SOURCES; } });
|
|
106
|
+
Object.defineProperty(exports, "PROVIDER_AUTHENTICATION_STATES", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_AUTHENTICATION_STATES; } });
|
|
107
|
+
Object.defineProperty(exports, "PROVIDER_CREDENTIAL_KINDS", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_CREDENTIAL_KINDS; } });
|
|
108
|
+
Object.defineProperty(exports, "PROVIDER_FAILURE_CODES", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_FAILURE_CODES; } });
|
|
109
|
+
Object.defineProperty(exports, "PROVIDER_FAILURE_EVIDENCE_SOURCES", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_FAILURE_EVIDENCE_SOURCES; } });
|
|
110
|
+
Object.defineProperty(exports, "PROVIDER_RECOVERY_ACTIONS", { enumerable: true, get: function () { return providerFailure_1.PROVIDER_RECOVERY_ACTIONS; } });
|
|
111
|
+
var codex_1 = require("./types/codex");
|
|
112
|
+
Object.defineProperty(exports, "isAggregateCodexLimit", { enumerable: true, get: function () { return codex_1.isAggregateCodexLimit; } });
|
|
113
|
+
// Codex rollout parsing (pure: no filesystem access)
|
|
114
|
+
var codexParser_1 = require("./parsers/codexParser");
|
|
115
|
+
Object.defineProperty(exports, "CodexRolloutParser", { enumerable: true, get: function () { return codexParser_1.CodexRolloutParser; } });
|
|
116
|
+
Object.defineProperty(exports, "DEFAULT_MAX_TRACKED_TOOL_CALLS", { enumerable: true, get: function () { return codexParser_1.DEFAULT_MAX_TRACKED_TOOL_CALLS; } });
|
|
117
|
+
Object.defineProperty(exports, "extractPatchFilePaths", { enumerable: true, get: function () { return codexParser_1.extractPatchFilePaths; } });
|
|
118
|
+
Object.defineProperty(exports, "normalizeCodexToolName", { enumerable: true, get: function () { return codexParser_1.normalizeCodexToolName; } });
|
|
119
|
+
Object.defineProperty(exports, "normalizeCodexToolInput", { enumerable: true, get: function () { return codexParser_1.normalizeCodexToolInput; } });
|
|
120
|
+
Object.defineProperty(exports, "resolveCodexCallUsage", { enumerable: true, get: function () { return codexParser_1.resolveCodexCallUsage; } });
|
|
121
|
+
var humanPrompt_1 = require("./humanPrompt");
|
|
122
|
+
Object.defineProperty(exports, "HUMAN_CLAUDE_ENTRYPOINTS", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CLAUDE_ENTRYPOINTS; } });
|
|
123
|
+
Object.defineProperty(exports, "HUMAN_CODEX_SOURCES", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CODEX_SOURCES; } });
|
|
124
|
+
Object.defineProperty(exports, "humanPromptText", { enumerable: true, get: function () { return humanPrompt_1.humanPromptText; } });
|
|
125
|
+
Object.defineProperty(exports, "isHumanPrompt", { enumerable: true, get: function () { return humanPrompt_1.isHumanPrompt; } });
|
|
126
|
+
var handoffUrl_1 = require("./handoffUrl");
|
|
127
|
+
Object.defineProperty(exports, "renderHandoffUrlTemplate", { enumerable: true, get: function () { return handoffUrl_1.renderHandoffUrlTemplate; } });
|
|
128
|
+
// Tool categories across providers
|
|
129
|
+
var toolCategory_1 = require("./toolCategory");
|
|
130
|
+
Object.defineProperty(exports, "classifyTool", { enumerable: true, get: function () { return toolCategory_1.classifyTool; } });
|
|
131
|
+
Object.defineProperty(exports, "TOOL_CATEGORIES", { enumerable: true, get: function () { return toolCategory_1.TOOL_CATEGORIES; } });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function getDefaultClaudeHome(): string;
|
|
2
|
+
/** True when this process runs against the default `~/.claude` home. */
|
|
3
|
+
export declare function isDefaultClaudeHome(): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* The home the `claude` CLI reads and writes for this process: `CLAUDE_CONFIG_DIR`
|
|
6
|
+
* when set, else `~/.claude`. Every "live" credential or identity read goes
|
|
7
|
+
* through this so sidekick follows the same home the CLI does.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getLiveClaudeHome(): string;
|
|
10
|
+
/** Where the `claude` CLI writes session transcripts for this process. */
|
|
11
|
+
export declare function getClaudeProjectsDir(): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getDefaultClaudeHome = getDefaultClaudeHome;
|
|
37
|
+
exports.isDefaultClaudeHome = isDefaultClaudeHome;
|
|
38
|
+
exports.getLiveClaudeHome = getLiveClaudeHome;
|
|
39
|
+
exports.getClaudeProjectsDir = getClaudeProjectsDir;
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
function getDefaultClaudeHome() {
|
|
43
|
+
return path.join(os.homedir(), '.claude');
|
|
44
|
+
}
|
|
45
|
+
/** True when this process runs against the default `~/.claude` home. */
|
|
46
|
+
function isDefaultClaudeHome() {
|
|
47
|
+
return !process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The home the `claude` CLI reads and writes for this process: `CLAUDE_CONFIG_DIR`
|
|
51
|
+
* when set, else `~/.claude`. Every "live" credential or identity read goes
|
|
52
|
+
* through this so sidekick follows the same home the CLI does.
|
|
53
|
+
*/
|
|
54
|
+
function getLiveClaudeHome() {
|
|
55
|
+
const explicit = process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
56
|
+
return explicit ? explicit : getDefaultClaudeHome();
|
|
57
|
+
}
|
|
58
|
+
/** Where the `claude` CLI writes session transcripts for this process. */
|
|
59
|
+
function getClaudeProjectsDir() {
|
|
60
|
+
return path.join(getLiveClaudeHome(), 'projects');
|
|
61
|
+
}
|
package/dist/claudeProfiles.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getDefaultClaudeHome, getLiveClaudeHome, isDefaultClaudeHome } from './claudePaths';
|
|
2
|
+
export { getDefaultClaudeHome, getLiveClaudeHome, isDefaultClaudeHome };
|
|
1
3
|
/**
|
|
2
4
|
* Claude Code honours this variable ahead of `CLAUDE_CONFIG_DIR` when it
|
|
3
5
|
* derives the keychain item name. Any `claude` child sidekick spawns must not
|
|
@@ -8,15 +10,6 @@ export interface ClaudeProfileIdentity {
|
|
|
8
10
|
email: string;
|
|
9
11
|
uuid: string;
|
|
10
12
|
}
|
|
11
|
-
export declare function getDefaultClaudeHome(): string;
|
|
12
|
-
/** True when this process runs against the default `~/.claude` home. */
|
|
13
|
-
export declare function isDefaultClaudeHome(): boolean;
|
|
14
|
-
/**
|
|
15
|
-
* The home the `claude` CLI reads and writes for this process: `CLAUDE_CONFIG_DIR`
|
|
16
|
-
* when set, else `~/.claude`. Every "live" credential or identity read goes
|
|
17
|
-
* through this so sidekick follows the same home the CLI does.
|
|
18
|
-
*/
|
|
19
|
-
export declare function getLiveClaudeHome(): string;
|
|
20
13
|
export declare function getClaudeProfilesDir(): string;
|
|
21
14
|
/**
|
|
22
15
|
* True when the live home is one of sidekick's own profile homes: a shell
|
package/dist/claudeProfiles.js
CHANGED
|
@@ -33,10 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = void 0;
|
|
37
|
-
exports.getDefaultClaudeHome = getDefaultClaudeHome;
|
|
38
|
-
exports.isDefaultClaudeHome = isDefaultClaudeHome;
|
|
39
|
-
exports.getLiveClaudeHome = getLiveClaudeHome;
|
|
36
|
+
exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = exports.isDefaultClaudeHome = exports.getLiveClaudeHome = exports.getDefaultClaudeHome = void 0;
|
|
40
37
|
exports.getClaudeProfilesDir = getClaudeProfilesDir;
|
|
41
38
|
exports.isLiveClaudeHomeSidekickProfile = isLiveClaudeHomeSidekickProfile;
|
|
42
39
|
exports.getClaudeProfileDir = getClaudeProfileDir;
|
|
@@ -58,6 +55,10 @@ const fs = __importStar(require("fs"));
|
|
|
58
55
|
const os = __importStar(require("os"));
|
|
59
56
|
const path = __importStar(require("path"));
|
|
60
57
|
const accountRegistry_1 = require("./accountRegistry");
|
|
58
|
+
const claudePaths_1 = require("./claudePaths");
|
|
59
|
+
Object.defineProperty(exports, "getDefaultClaudeHome", { enumerable: true, get: function () { return claudePaths_1.getDefaultClaudeHome; } });
|
|
60
|
+
Object.defineProperty(exports, "getLiveClaudeHome", { enumerable: true, get: function () { return claudePaths_1.getLiveClaudeHome; } });
|
|
61
|
+
Object.defineProperty(exports, "isDefaultClaudeHome", { enumerable: true, get: function () { return claudePaths_1.isDefaultClaudeHome; } });
|
|
61
62
|
const DEFAULT_CLAUDE_KEYCHAIN_SERVICE = 'Claude Code-credentials';
|
|
62
63
|
const KEYCHAIN_ACCOUNT_PATTERN = /^[a-zA-Z0-9._-]+$/;
|
|
63
64
|
const KEYCHAIN_FALLBACK_ACCOUNT = 'claude-code-user';
|
|
@@ -67,22 +68,6 @@ const KEYCHAIN_FALLBACK_ACCOUNT = 'claude-code-user';
|
|
|
67
68
|
* inherit it, or the login would land in an item nobody else reads.
|
|
68
69
|
*/
|
|
69
70
|
exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = 'CLAUDE_SECURESTORAGE_CONFIG_DIR';
|
|
70
|
-
function getDefaultClaudeHome() {
|
|
71
|
-
return path.join(os.homedir(), '.claude');
|
|
72
|
-
}
|
|
73
|
-
/** True when this process runs against the default `~/.claude` home. */
|
|
74
|
-
function isDefaultClaudeHome() {
|
|
75
|
-
return !process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* The home the `claude` CLI reads and writes for this process: `CLAUDE_CONFIG_DIR`
|
|
79
|
-
* when set, else `~/.claude`. Every "live" credential or identity read goes
|
|
80
|
-
* through this so sidekick follows the same home the CLI does.
|
|
81
|
-
*/
|
|
82
|
-
function getLiveClaudeHome() {
|
|
83
|
-
const explicit = process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
84
|
-
return explicit ? explicit : getDefaultClaudeHome();
|
|
85
|
-
}
|
|
86
71
|
function getClaudeProfilesDir() {
|
|
87
72
|
return path.join((0, accountRegistry_1.getAccountsDir)(), 'claude', 'profiles');
|
|
88
73
|
}
|
|
@@ -94,7 +79,7 @@ function getClaudeProfilesDir() {
|
|
|
94
79
|
* usable copy and re-point the active account at it.
|
|
95
80
|
*/
|
|
96
81
|
function isLiveClaudeHomeSidekickProfile() {
|
|
97
|
-
const liveHome = path.resolve(getLiveClaudeHome());
|
|
82
|
+
const liveHome = path.resolve((0, claudePaths_1.getLiveClaudeHome)());
|
|
98
83
|
const profilesDir = path.resolve(getClaudeProfilesDir());
|
|
99
84
|
return liveHome === profilesDir || liveHome.startsWith(profilesDir + path.sep);
|
|
100
85
|
}
|
|
@@ -129,7 +114,7 @@ function claudeKeychainSuffix(configDir) {
|
|
|
129
114
|
* `~/.claude` — so the no-argument form follows the process environment.
|
|
130
115
|
*/
|
|
131
116
|
function claudeKeychainService(configDir) {
|
|
132
|
-
const dir = configDir ?? (isDefaultClaudeHome() ? undefined : getLiveClaudeHome());
|
|
117
|
+
const dir = configDir ?? ((0, claudePaths_1.isDefaultClaudeHome)() ? undefined : (0, claudePaths_1.getLiveClaudeHome)());
|
|
133
118
|
return dir
|
|
134
119
|
? `${DEFAULT_CLAUDE_KEYCHAIN_SERVICE}-${claudeKeychainSuffix(dir)}`
|
|
135
120
|
: DEFAULT_CLAUDE_KEYCHAIN_SERVICE;
|
|
@@ -167,11 +152,11 @@ function readOauthAccount(configPath) {
|
|
|
167
152
|
* when it carries an identity, otherwise fall back to the legacy location for
|
|
168
153
|
* the default home only.
|
|
169
154
|
*/
|
|
170
|
-
function getClaudeConfigPath(home = getLiveClaudeHome()) {
|
|
155
|
+
function getClaudeConfigPath(home = (0, claudePaths_1.getLiveClaudeHome)()) {
|
|
171
156
|
const primary = path.join(home, '.claude.json');
|
|
172
157
|
if (readOauthAccount(primary))
|
|
173
158
|
return primary;
|
|
174
|
-
if (path.resolve(home) === path.resolve(getDefaultClaudeHome())) {
|
|
159
|
+
if (path.resolve(home) === path.resolve((0, claudePaths_1.getDefaultClaudeHome)())) {
|
|
175
160
|
return path.join(os.homedir(), '.claude.json');
|
|
176
161
|
}
|
|
177
162
|
return primary;
|
|
@@ -182,7 +167,7 @@ function identityFromOauthAccount(oauthAccount) {
|
|
|
182
167
|
return typeof email === 'string' && typeof uuid === 'string' ? { email, uuid } : null;
|
|
183
168
|
}
|
|
184
169
|
/** Identity of the account currently logged in to a Claude home (default: the live home). */
|
|
185
|
-
function readLiveClaudeIdentity(home = getLiveClaudeHome()) {
|
|
170
|
+
function readLiveClaudeIdentity(home = (0, claudePaths_1.getLiveClaudeHome)()) {
|
|
186
171
|
return identityFromOauthAccount(readOauthAccount(getClaudeConfigPath(home)));
|
|
187
172
|
}
|
|
188
173
|
function readClaudeProfileIdentity(home) {
|
package/dist/codexPaths.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ export declare function getDefaultSystemCodexHome(): string;
|
|
|
2
2
|
export declare function getExplicitCodexHome(): string | null;
|
|
3
3
|
/** The home the `codex` CLI reads for this process: `CODEX_HOME` or `~/.codex`. */
|
|
4
4
|
export declare function getSystemCodexHome(): string;
|
|
5
|
+
export declare function resolveSidekickCodexHome(): string;
|
|
6
|
+
/**
|
|
7
|
+
* The environment for spawning `codex`: `baseEnv` with `CODEX_HOME` set to the
|
|
8
|
+
* live home. A non-blank `CODEX_HOME` already in `baseEnv` is kept, so a caller
|
|
9
|
+
* that points one child at its own home does not have it overwritten.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getCodexExecutionEnv(baseEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
5
12
|
export declare function getCodexProfilesDir(): string;
|
|
6
13
|
export declare function getCodexProfileDir(profileId: string): string;
|
|
7
14
|
export declare function getCodexProfileHome(profileId: string): string;
|
|
@@ -25,3 +32,18 @@ export declare function getCodexLoginDir(id: string): string;
|
|
|
25
32
|
/** Legacy pending profiles remain readable until finalized or discarded. */
|
|
26
33
|
export declare function getCodexLoginHome(id: string): string;
|
|
27
34
|
export declare function getCodexLoginStatePath(id: string): string;
|
|
35
|
+
export declare function getCodexMonitoringHomes(): string[];
|
|
36
|
+
/** Where Codex writes live rollouts, below each home. */
|
|
37
|
+
export declare const CODEX_SESSIONS_SUBDIR = "sessions";
|
|
38
|
+
/** Where Codex moves a rollout when its thread is archived, below each home. */
|
|
39
|
+
export declare const CODEX_ARCHIVED_SESSIONS_SUBDIR = "archived_sessions";
|
|
40
|
+
export interface CodexSessionsDirsOptions {
|
|
41
|
+
/** Also list each home's `archived_sessions` directory when it exists (default true). */
|
|
42
|
+
includeArchived?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Every directory that may hold Codex rollouts: each home's `sessions`, then
|
|
46
|
+
* each home's `archived_sessions` that exists. Live directories come first so
|
|
47
|
+
* callers that pick one directory pick a live one.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getCodexSessionsDirs(homes?: string[], options?: CodexSessionsDirsOptions): string[];
|