sidekick-shared 0.26.6 → 0.27.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 CHANGED
@@ -5,6 +5,36 @@ 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.27.1] - 2026-09-22
9
+
10
+ ### Fixed
11
+
12
+ - `collectPromptHistory()` returns a prompt again when its first answering call is written after the prompt was collected. Previously the cursor moved past the prompt and a resumed scan could never attach the answer's `model` / `usage`. Now, while a file's last emitted prompt is not final, the cursor keeps `pending: { ordinal, offset, emitted, state? }`: the byte offset of the prompt's line, a 16-hex digest of the model, usage, and status last returned, and (Codex) the parse state from just before that line. The next call replays from that offset, so the prompt's `provider`, `sessionId`, `ordinal`, `timestamp`, and `text` come from the log again and are never synthesized or renumbered, and returns it only if its metadata digest changed. No prompt or assistant text is stored in the cursor. A replay that would exceed `maxFileBytes` is dropped in favour of the committed offset, and that prompt is not revisited.
13
+ - First-answer attribution: Claude split records of the first call replace usage rather than adding it, a later assistant message id, a `tool_result`, or a non-null `stop_reason` closes the first call, later tool-loop calls never replace it, and `<synthetic>` records (API errors, interrupts) are ignored instead of contributing zero usage. Codex closes on the first `token_count` with `last_token_usage`; a `token_count` without usage (rate-limit only) does not. Missing usage stays `undefined`.
14
+ - Documentation: cursor keys are path-free, but values are not (Codex `state.cwd` / `gitBranch`), so the cursor is sensitive, local-only state; a file over `maxFileBytes` is skipped and calling again with the same bounds skips it again.
15
+
16
+ ### Added
17
+
18
+ - `PromptHistoryEntry.metadataStatus`: `pending` (no answering call yet), `provisional` (Claude call seen with `stop_reason: null`), or `final` (complete, or closed without an answer). A prompt closed by the next prompt without an answer is returned once more as `final`. New exported types `PromptHistoryMetadataStatus` and `PromptHistoryPendingPrompt`.
19
+
20
+ ### Changed
21
+
22
+ - `PromptHistoryCursor.version` is now `2` and sessions may carry `pending`. Version 1 cursors are accepted as input and upgraded; prompts they already returned without metadata cannot be recovered. Unknown versions are ignored (full rescan, same identities).
23
+
24
+ ## [0.27.0] - 2026-09-22
25
+
26
+ ### Added
27
+
28
+ - `collectPromptHistory(options)` (Node-only; exported from `sidekick-shared/node` and the package root, not `sidekick-shared/browser`) returns the prompts a person typed in Claude Code and Codex sessions whose recorded working directory lies inside `workspacePaths` (realpath-normalized; git worktree siblings are added unless `includeWorktrees: false`). Scope fails closed: each prompt's cwd (Claude: the line's `cwd`; Codex: `session_meta` / `turn_context`) must realpath-resolve to a root or inside one. Entries hold `provider`, `sessionId`, a stable per-session `ordinal` (every human prompt consumes one, in or out of scope), the log-line `timestamp` (lines without one are skipped and counted), full `text`, realpath `cwd`, `gitBranch`, and the `model` / `usage` of the first answering model call. Codex subagent sessions and forked sessions (whose replayed parent history cannot be separated) are skipped. `cursor` is JSON-serializable, keyed without paths, and records `size`, `mtimeMs`, `lastOrdinal`, and a byte `offset` per file; unchanged files are skipped, appended files resume after `lastOrdinal`, and rewritten (shrunk) files are rescanned. `bounds` (`maxSessions` 1000, `maxFileBytes` 16 MiB, `maxTotalBytes` 256 MiB, `deadlineMs` 30 000) and `signal` never throw: hits are listed in `boundsHit`, an interrupted file contributes no entries, and the cursor covers only fully processed files. `stats` reports sessions scanned, skipped unchanged, out of scope, non-interactive, and over the size limit, plus prompts dropped for missing timestamps or scope.
29
+ - `isHumanPrompt(message, provider)` and `humanPromptText(message, provider)` classify `CanonicalTranscriptMessage`s. Claude Code: user role, entrypoint in `HUMAN_CLAUDE_ENTRYPOINTS` (`cli`, `claude-desktop`, `sdk-cli`), not meta, sidechain, or compaction summary, `origin.kind` absent or `human`, `promptSource` not `system`, and not tool-result-only, local-command output or caveat, task notification, system reminder, or interrupt marker; slash commands come back as typed (`/review foo`). Codex: user role with injected `AGENTS.md`, `<environment_context>`, `<user_instructions>`, turn-aborted, skill, subagent-notification, and internal-context blocks and `<image>` wrappers dropped. `HUMAN_CODEX_SOURCES` (`cli`, `vscode`, `exec`) is the session-level Codex rule applied by `collectPromptHistory()`.
30
+ - `TranscriptSourceProvenance` gains optional `isCompactSummary`, `originKind`, and `promptSource`, and `SessionEventBase` gains `isCompactSummary`, `origin`, and `promptSource`, all preserved from Claude Code JSONL so `readSessionTranscript()` output can be classified without reparsing.
31
+
32
+ - GPT-6 Sol (`gpt-6-sol`: $2 input / $10 output / $0.20 cached input per 1M tokens) and GPT-6 Luna (`gpt-6-luna`: $0.10 / $0.50 / $0.01) pricing and 1.05M context-window entries.
33
+
34
+ ### Fixed
35
+
36
+ - Claude Opus 5.5 (`claude-opus-5-5` / `claude-opus-5.5`) is priced at $4 input / $20 output / $5 cache write / $0.20 cache read per 1M tokens with a 1M context window. It previously prefix-matched `claude-opus-5` ($5 / $25 / $0.50), and the LiteLLM catalog has no entry for it.
37
+
8
38
  ## [0.26.6] - 2026-09-16
9
39
 
10
40
  ### Added
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.27.1: late prompt metadata** — `collectPromptHistory()` returns a prompt again, with the same provider, sessionId, ordinal, timestamp, and text, when its first answering call is written after an earlier collection, and entries gain `metadataStatus` (`pending` / `provisional` / `final`). The cursor becomes `version: 2`, keeps a replay offset and metadata digest for the one open prompt per file (no prompt text), and still accepts 0.27.0 cursors.
13
+ - **0.27.0: human prompt history** — `collectPromptHistory()` (Node-only) returns the prompts a person typed in Claude Code and Codex sessions under a set of workspace roots (plus git worktree siblings), with fail-closed cwd scoping, untruncated text, stable per-session ordinals, the answering model and usage, a JSON-serializable resume cursor, and bounds that stop cleanly and report themselves in `boundsHit`. `isHumanPrompt()` / `humanPromptText()` expose the same classification for any canonical transcript message, and transcript provenance now keeps Claude Code's `isCompactSummary`, `originKind`, and `promptSource`. Claude Opus 5.5 gets its own pricing and context entries.
12
14
  - **0.26.6: verified account switching** — `syncLiveAccountState()` reconciles the live Claude Code and Codex logins with saved profiles (registers unknown logins under their email, folds rotated tokens, merges duplicate Codex profiles, re-points the active pointer) and runs at startup, on account-change events, and as phase one of every switch; `getAccountHealth()` / `listAccountsWithHealth()` report secret-free `fresh | expiring | expired | unknown | missing` health; `switchAccount[Async]()` returns a `SwitchAccountResult` with verification, `runningConsumers`, `needsLogin`, and an `undoToken` for `undoLastSwitch()`; `detectRunningAccountConsumers()`, `getAccountLaunchEnv()`, `refreshInactiveAccounts()`, and `getCodexCredentialStoreMode()` are new. Claude logins run `claude auth login`, the Keychain suffix follows Claude Code 2.1.x, and the unused shell-hook helpers were removed.
13
15
  - **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.
14
16
  - **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`.
@@ -111,7 +113,7 @@ returns the platform default that both overrides bypass.
111
113
  | **Doctor** | Typed cross-provider health diagnostics — `runDoctor()` checks project identity, sessions, accounts, providers, and dependencies into a `HealthReport`; `formatHealthReport()` renders it and `getSessionDiagnostics()` retains the legacy Claude Code path probe; `runDoctor({ provider })` diagnoses the selected session provider |
112
114
  | **Schemas** | Zod schemas for runtime validation of data crossing process/IPC boundaries — JSONL session events (`sessionEventSchema`, `messageUsageSchema`, `sessionMessageSchema`), assistant turns, observed-session V1 records, quota, account status, account management, quota history, and the public `state.json` contract (`sidekickStateFileSchema`, exported only from `sidekick-shared/schemas`) — plus `extractSessionEvents()` to unwrap `progress`-wrapped events. Account and quota APIs guarantee results valid against the same-release schemas. Also published fs-free via the [`sidekick-shared/schemas`](#supported-import-paths) subpath |
113
115
  | **Extractors** | Pure functions for single-event processing: `extractTokenUsage()`, `extractToolCall()` (top-level `tool_use`), `extractToolCalls()` (assistant content blocks), plus Node-only session asset extraction (`gatherAssetsForCwd()`, `readClaudeAssets()`, `readCodexAssets()`) for URLs, file paths, commands, and plans |
114
- | **Model Info & Pricing** | Model family parsing (Anthropic / OpenAI / Google, including legacy `claude-3-opus-…` and `claude-3-5-sonnet-…` IDs), context-window lookup (including Fable 5 / Opus 4.8 / Opus 4.7 / Sonnet 4.7 1M and GPT-5.x variants), pricing tables with optional LiteLLM hydration, normalized non-double-counting cost (`calculateNormalizedUsageCost()`, fed by `normalizeProviderUsage()` / `extractNormalizedUsage()`), legacy cost helpers retained but deprecated (`calculateCost()`, `calculateCostWithProvenance()`), `mergeCostSources()`, display helpers (`shortModelName()`, `getModelDisplayInfo()`, `compareModelIds()`, `sortModelIds()`, `formatCost()`), and cross-realm catalog transfer — `exportResolvedModelCatalog()` / `importResolvedModelCatalog()` move resolved context windows and pricing (with provenance, prefix inheritance explicit) between Node and browser realms, and `registerModelAlias()` resolves short or host-specific names to canonical ids |
116
+ | **Model Info & Pricing** | Model family parsing (Anthropic / OpenAI / Google, including legacy `claude-3-opus-…` and `claude-3-5-sonnet-…` IDs), context-window lookup (including Fable 5.1 / Opus 5.5 / Opus 5 / Opus 4.8 / Opus 4.7 1M and GPT-5.x / GPT-6 variants), pricing tables with optional LiteLLM hydration, normalized non-double-counting cost (`calculateNormalizedUsageCost()`, fed by `normalizeProviderUsage()` / `extractNormalizedUsage()`), legacy cost helpers retained but deprecated (`calculateCost()`, `calculateCostWithProvenance()`), `mergeCostSources()`, display helpers (`shortModelName()`, `getModelDisplayInfo()`, `compareModelIds()`, `sortModelIds()`, `formatCost()`), and cross-realm catalog transfer — `exportResolvedModelCatalog()` / `importResolvedModelCatalog()` move resolved context windows and pricing (with provenance, prefix inheritance explicit) between Node and browser realms, and `registerModelAlias()` resolves short or host-specific names to canonical ids |
115
117
  | **Quota Polling** | `QuotaPoller` class with exponential backoff, active/idle intervals, and cached fallback. Stays dormant while no account exists and wakes through the account-change signal |
116
118
  | **Multi-Provider Quota** | `MultiProviderQuotaService` orchestrates Claude polling + peak-hours + account labels + Codex/z.ai quota updates behind one typed event stream. `CodexQuotaWatcher` watches the active Codex rollout for live rate limits with snapshot fallback; z.ai quota uses the API resolver with snapshot fallback. All three stay dormant without a matching account and wake on account changes |
117
119
  | **Accounts** | Multi-provider account registry (v2) with per-provider active account, save/switch/remove, v1 migration, `ensureDefaultAccounts()` for startup bootstrap (migrations, abandoned-login cleanup, then `syncLiveAccountState()`), `syncLiveAccountState()` to register live logins the registry has never seen under their email, fold rotated tokens into their profile, and merge duplicate Codex profiles, `getAccountHealth()` / `listAccountsWithHealth()` for secret-free `fresh`/`expiring`/`expired`/`unknown`/`missing` health with access/refresh expiry,`getActiveAccountStatus()` for a single-pass active-account read across providers,`onAccountsChanged()`for push-based login/logout/switch notification (process-local mutations, filesystem watches, and a catch-up poll), and live-first`resolveActiveClaudeAccount()`/`resolveActiveCodexAccount()` that report the currently logged-in account (self-healing the saved pointer) for display |
@@ -126,17 +128,17 @@ returns the platform default that both overrides bypass.
126
128
 
127
129
  `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.
128
130
 
129
- | Path | Runtime | What it exposes |
130
- | ------------------------------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
131
- | `sidekick-shared` | Node (CLI, extension host) | Full public API (readers, providers, parsers, pricing, …). |
132
- | `sidekick-shared/browser` | **Browser / webview** | Pure helpers: usage normalization/pricing, token estimation, transcript and assistant-turn projection, model/context math, `parseMcpToolName()`. |
133
- | `sidekick-shared/node` | Node only | LiteLLM pricing and context-window hydration, public provider service status (`fetchProviderServiceStatus()`), observed context-window persistence, recent-session/transcript reads, session previews (`listSessionPreviews()` / `readSessionPreview()` plus the bounded-concurrency `listSessionPreviewsAsync()` / `readSessionPreviewAsync()`), Codex history/rollout lookup (`readCodexHistory()`, `findCodexRolloutFile()`), and resilient observed-session collection (`fs` + providers). |
134
- | `sidekick-shared/phrases` | Any runtime | Phrase arrays + `getRandomPhrase()`. |
135
- | `sidekick-shared/modelContext` | Any runtime | Direct access to the context-window module. |
136
- | `sidekick-shared/modelInfo` | Any runtime | Direct access to model parsing and cost math. |
137
- | `sidekick-shared/formatting` | Any runtime | Direct access to pure token and duration display helpers. |
138
- | `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. |
139
- | `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()`. |
131
+ | Path | Runtime | What it exposes |
132
+ | ------------------------------ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
133
+ | `sidekick-shared` | Node (CLI, extension host) | Full public API (readers, providers, parsers, pricing, …). |
134
+ | `sidekick-shared/browser` | **Browser / webview** | Pure helpers: usage normalization/pricing, token estimation, transcript and assistant-turn projection, model/context math, `parseMcpToolName()`. |
135
+ | `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()`), session previews (`listSessionPreviews()` / `readSessionPreview()` plus the bounded-concurrency `listSessionPreviewsAsync()` / `readSessionPreviewAsync()`), Codex history/rollout lookup (`readCodexHistory()`, `findCodexRolloutFile()`), and resilient observed-session collection (`fs` + providers). |
136
+ | `sidekick-shared/phrases` | Any runtime | Phrase arrays + `getRandomPhrase()`. |
137
+ | `sidekick-shared/modelContext` | Any runtime | Direct access to the context-window module. |
138
+ | `sidekick-shared/modelInfo` | Any runtime | Direct access to model parsing and cost math. |
139
+ | `sidekick-shared/formatting` | Any runtime | Direct access to pure token and duration display helpers. |
140
+ | `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. |
141
+ | `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()`. |
140
142
 
141
143
  ### Browser / webview runtimes
142
144
 
@@ -283,18 +285,53 @@ const transcript = readSessionTranscript(provider, recent.sessionPath, {
283
285
 
284
286
  The same API works with `ClaudeCodeProvider` and `OpenCodeProvider`. It covers provider sessions discoverable by those readers. Remote Claude SDK-only history and Codex history entries whose rollout file has disappeared are not synthesized.
285
287
 
286
- Canonical transcript messages retain provider-origin facts on `message.source`, including the original role, entrypoint, meta/sidechain flags, and source identifiers. Transcript-level `cwd` and `gitBranch` use the latest non-empty value reported by the provider. Consumers can therefore distinguish a human Claude Code CLI prompt without reparsing JSONL:
288
+ Canonical transcript messages retain provider-origin facts on `message.source`, including the original role, entrypoint, meta/sidechain flags, and source identifiers. Transcript-level `cwd` and `gitBranch` use the latest non-empty value reported by the provider. Claude Code messages also carry `isCompactSummary`, `originKind` (`origin.kind`), and `promptSource`. Consumers can therefore pick out the prompts a person typed without reparsing JSONL, using the same rule `collectPromptHistory()` applies:
287
289
 
288
290
  ```typescript
289
- const humanCliPrompts = transcript.messages.filter(
290
- (message) =>
291
- message.source.originalRole === 'user' &&
292
- message.source.entrypoint === 'cli' &&
293
- message.source.isMeta !== true &&
294
- message.source.isSidechain !== true,
295
- );
291
+ import { isHumanPrompt, humanPromptText } from 'sidekick-shared/node';
292
+
293
+ const humanPrompts = transcript.messages
294
+ .filter((message) => isHumanPrompt(message, 'claude-code')) // or 'codex'
295
+ .map((message) => humanPromptText(message, 'claude-code')); // `/review foo` for slash commands
296
296
  ```
297
297
 
298
+ A Claude Code message is a human prompt when it has the user role, an entrypoint in `HUMAN_CLAUDE_ENTRYPOINTS` (`cli`, `claude-desktop`, `sdk-cli` — Agent SDK programs report `sdk-ts` / `sdk-py` and are excluded), is not meta, sidechain, or a compaction summary, has no non-human `origin.kind` (task notifications, coordinator messages, auto-continuations) or `promptSource: 'system'`, and is not tool-result-only, local-command output or caveat, bash-mode input or output, a hook or task notification, a system reminder, a continued-session summary, or an interrupt marker. A Codex message is one when it has the user role and some text is left after injected `AGENTS.md`, `<environment_context>`, `<user_instructions>`, permissions and collaboration-mode, recommended-plugin, user-shell-command, turn-aborted, skill, subagent-notification, and internal-context blocks and `<image>` wrappers are dropped. Codex session source is a session-level rule: `collectPromptHistory()` reads only sessions whose `session_meta.source` is in `HUMAN_CODEX_SOURCES` (`cli`, `vscode`, `exec`) and skips subagent and forked sessions.
299
+
300
+ ### Collect human prompt history for workspace roots
301
+
302
+ ```typescript
303
+ import { collectPromptHistory, type PromptHistoryCursor } from 'sidekick-shared/node';
304
+
305
+ let cursor: PromptHistoryCursor | undefined = loadCursor(); // your own JSON store
306
+ const result = await collectPromptHistory({
307
+ workspacePaths: ['/Users/me/code/app'], // realpath-normalized; worktree siblings added
308
+ providers: ['claude-code', 'codex'], // default: both
309
+ since: new Date('2026-09-01'),
310
+ cursor,
311
+ bounds: {
312
+ maxSessions: 1000,
313
+ maxFileBytes: 16 << 20,
314
+ maxTotalBytes: 256 << 20,
315
+ deadlineMs: 30_000,
316
+ },
317
+ signal: AbortSignal.timeout(60_000),
318
+ });
319
+
320
+ for (const entry of result.entries) {
321
+ // { provider, sessionId, ordinal, timestamp, text, cwd, gitBranch?, model?, usage?, metadataStatus }
322
+ // Upsert by (provider, sessionId, ordinal): a prompt comes back when its answer metadata changes.
323
+ }
324
+ saveCursor(result.cursor); // sensitive local state; unchanged files are skipped next time
325
+ if (result.boundsHit.length > 0) console.warn('partial pass', result.boundsHit, result.stats);
326
+ ```
327
+
328
+ - **Scope fails closed.** A prompt is returned only when its recorded working directory (the Claude line's `cwd`; the Codex `session_meta` / `turn_context` cwd) realpath-resolves to a root or somewhere inside one. Missing or unresolvable cwds are excluded and counted in `stats.promptsOutOfScope`; Codex scope never comes from the rollout's location. `cwd` is the only path in entries. Cursor keys hold no paths, but cursor values can (Codex resume state keeps the session's cwd and branch), so store the cursor as sensitive, local-only state.
329
+ - **Parse-only.** No redaction and no network I/O; text is untruncated.
330
+ - **Ordinals are stable.** Every human prompt in a file consumes one ordinal, even when it is out of scope, older than `since`, or lacks a timestamp (such lines are skipped and counted, never given a synthesized time). Entries are ordered by provider, session, then ordinal.
331
+ - **Model and usage** come from the first model call that answered the prompt (Claude: the first non-synthetic assistant message, with split records of that call replacing rather than adding usage; Codex: the first `token_count` with the model from `turn_context`). Later tool-loop calls never replace it. `inputTokens` is uncached input, and missing usage stays `undefined`, never zero.
332
+ - **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 of its line and a digest of what was returned (never prompt or answer text); the next call replays from that line and returns the prompt again, with the same provider, sessionId, ordinal, timestamp, and text, only when its model, usage, or status changed. A prompt closed by the next prompt without an answer comes back once as `final` with no usage. Consumers should upsert by identity. Cursors from 0.27.0 (`version: 1`) are accepted but cannot recover prompts they already returned without metadata.
333
+ - **Bounds never throw.** Hitting `maxSessions`, `maxTotalBytes`, the deadline, or an abort stops the pass. An interrupted file contributes no entries, and the cursor covers only fully processed files, so the next call picks up where this one stopped. A file over `maxFileBytes` is different: it is skipped and counted in `stats.filesOverSizeLimit`, and calling again with the same bounds skips it again, so raise the bound to make progress on it. When only the replay of a pending prompt would exceed `maxFileBytes`, the replay is dropped and the file continues from its committed offset; that prompt is not revisited.
334
+
298
335
  For an already-open incremental Codex rollout, keep one `CodexRolloutParser` per stream and pass each parsed `SessionEvent[]` batch to `projectSessionTranscript()` (or append the events to an existing projection). This preserves parser state for paired tool calls, model context, and cumulative token deltas; consumers should not convert raw `response_item` rows themselves.
299
336
 
300
337
  ### Locate provider-native session files
@@ -0,0 +1,27 @@
1
+ /**
2
+ * One shared definition of "a prompt a person typed" for Claude Code and
3
+ * Codex transcripts. Pure: no filesystem access, so it can classify messages
4
+ * from `readSessionTranscript()` or from `collectPromptHistory()` alike.
5
+ */
6
+ import type { CanonicalTranscriptMessage } from './transcript';
7
+ export type HumanPromptProvider = 'claude-code' | 'codex';
8
+ /**
9
+ * Claude Code `entrypoint` values treated as a person at the keyboard:
10
+ * the interactive CLI, Claude Desktop's Code surface, and `claude -p`.
11
+ * `sdk-ts` / `sdk-py` (Agent SDK programs) are excluded.
12
+ */
13
+ export declare const HUMAN_CLAUDE_ENTRYPOINTS: readonly string[];
14
+ /**
15
+ * Codex `session_meta.source` values whose sessions carry typed prompts.
16
+ * Subagent sessions (`{ subagent: … }`) are excluded; they replay parent
17
+ * history. This is a session-level rule applied by `collectPromptHistory()`.
18
+ */
19
+ export declare const HUMAN_CODEX_SOURCES: readonly string[];
20
+ /** Whether a canonical transcript message is a prompt a person typed. */
21
+ export declare function isHumanPrompt(message: CanonicalTranscriptMessage, provider: HumanPromptProvider): boolean;
22
+ /**
23
+ * The visible text of a human prompt, or `null` when the message is not one.
24
+ * Claude slash commands are returned as typed (`/review foo`); Codex image
25
+ * wrappers and injected context blocks are dropped. Text is never truncated.
26
+ */
27
+ export declare function humanPromptText(message: CanonicalTranscriptMessage, provider: HumanPromptProvider): string | null;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * One shared definition of "a prompt a person typed" for Claude Code and
4
+ * Codex transcripts. Pure: no filesystem access, so it can classify messages
5
+ * from `readSessionTranscript()` or from `collectPromptHistory()` alike.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = void 0;
9
+ exports.isHumanPrompt = isHumanPrompt;
10
+ exports.humanPromptText = humanPromptText;
11
+ /**
12
+ * Claude Code `entrypoint` values treated as a person at the keyboard:
13
+ * the interactive CLI, Claude Desktop's Code surface, and `claude -p`.
14
+ * `sdk-ts` / `sdk-py` (Agent SDK programs) are excluded.
15
+ */
16
+ exports.HUMAN_CLAUDE_ENTRYPOINTS = Object.freeze([
17
+ 'cli',
18
+ 'claude-desktop',
19
+ 'sdk-cli',
20
+ ]);
21
+ /**
22
+ * Codex `session_meta.source` values whose sessions carry typed prompts.
23
+ * Subagent sessions (`{ subagent: … }`) are excluded; they replay parent
24
+ * history. This is a session-level rule applied by `collectPromptHistory()`.
25
+ */
26
+ exports.HUMAN_CODEX_SOURCES = Object.freeze(['cli', 'vscode', 'exec']);
27
+ /** Claude user text that is harness output rather than something typed. */
28
+ const CLAUDE_INJECTED_PREFIX = /^(?:<(?:local-command-stdout|local-command-stderr|local-command-caveat|task-notification|system-reminder|bash-input|bash-stdout|bash-stderr|user-prompt-submit-hook)\b|\[Request interrupted\b|This session is being continued from a previous conversation)/;
29
+ const COMMAND_NAME = /<command-name>\s*([\s\S]*?)\s*<\/command-name>/;
30
+ const COMMAND_ARGS = /<command-args>\s*([\s\S]*?)\s*<\/command-args>/;
31
+ /** Codex user-role blocks injected by the harness (context, instructions, markers). */
32
+ const CODEX_INJECTED_PREFIX = /^(?:# AGENTS\.md instructions\b|<(?:environment_context|user_instructions|recommended_plugins|turn_aborted|skill|subagent_notification|codex_internal_context|user_shell_command|permissions instructions|collaboration_mode)\b)/;
33
+ /** Codex wraps attached images as `<image name=…>` / `</image>` text blocks. */
34
+ const CODEX_IMAGE_WRAPPER = /^<\/?image\b[^>]*>$/;
35
+ /** Whether a canonical transcript message is a prompt a person typed. */
36
+ function isHumanPrompt(message, provider) {
37
+ return humanPromptText(message, provider) !== null;
38
+ }
39
+ /**
40
+ * The visible text of a human prompt, or `null` when the message is not one.
41
+ * Claude slash commands are returned as typed (`/review foo`); Codex image
42
+ * wrappers and injected context blocks are dropped. Text is never truncated.
43
+ */
44
+ function humanPromptText(message, provider) {
45
+ if (message.role !== 'user')
46
+ return null;
47
+ if ((message.source.originalRole ?? 'user') !== 'user')
48
+ return null;
49
+ return provider === 'claude-code' ? claudePromptText(message) : codexPromptText(message);
50
+ }
51
+ function claudePromptText(message) {
52
+ const source = message.source;
53
+ if (!source.entrypoint || !exports.HUMAN_CLAUDE_ENTRYPOINTS.includes(source.entrypoint))
54
+ return null;
55
+ if (source.isMeta === true || source.isSidechain === true)
56
+ return null;
57
+ if (source.isCompactSummary === true)
58
+ return null;
59
+ if (source.originKind !== undefined && source.originKind !== 'human')
60
+ return null;
61
+ if (source.promptSource === 'system')
62
+ return null;
63
+ const text = textBlocks(message).join('\n');
64
+ const trimmed = text.trim();
65
+ if (!trimmed)
66
+ return null;
67
+ if (CLAUDE_INJECTED_PREFIX.test(trimmed))
68
+ return null;
69
+ const command = trimmed.match(COMMAND_NAME);
70
+ if (command && /^<command-(?:name|message)>/.test(trimmed)) {
71
+ const name = command[1].trim();
72
+ if (!name)
73
+ return null;
74
+ const args = trimmed.match(COMMAND_ARGS)?.[1].trim() ?? '';
75
+ const visible = name.startsWith('/') ? name : `/${name}`;
76
+ return args ? `${visible} ${args}` : visible;
77
+ }
78
+ return text;
79
+ }
80
+ function codexPromptText(message) {
81
+ const typed = textBlocks(message).filter((text) => {
82
+ const trimmed = text.trim();
83
+ return (trimmed.length > 0 &&
84
+ !CODEX_INJECTED_PREFIX.test(trimmed) &&
85
+ !CODEX_IMAGE_WRAPPER.test(trimmed));
86
+ });
87
+ return typed.length > 0 ? typed.join('\n') : null;
88
+ }
89
+ function textBlocks(message) {
90
+ return message.content
91
+ .filter((block) => block.type === 'text' && typeof block.text === 'string')
92
+ .map((block) => block.text);
93
+ }
package/dist/index.d.ts CHANGED
@@ -10,6 +10,10 @@ export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod
10
10
  export { projectSessionTranscript } from './transcript';
11
11
  export type { TranscriptFidelity, TranscriptSourceProvenance, CanonicalTranscriptBlock, CanonicalTranscriptMessage, CanonicalToolCall, CanonicalTranscriptUsageTotals, CanonicalSessionTranscript, ProjectSessionTranscriptOptions, } from './transcript';
12
12
  export { listRecentSessions, readSessionTranscript } from './sessionTranscripts';
13
+ export { collectPromptHistory } from './promptHistory';
14
+ export type { CollectPromptHistoryOptions, PromptHistoryBound, PromptHistoryBounds, PromptHistoryCursor, PromptHistoryCursorSession, PromptHistoryEntry, PromptHistoryMetadataStatus, PromptHistoryPendingPrompt, PromptHistoryProvider, PromptHistoryResult, PromptHistoryResumeState, PromptHistoryStats, PromptHistoryUsage, } from './promptHistory';
15
+ export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
16
+ export type { HumanPromptProvider } from './humanPrompt';
13
17
  export { computeSessionFileStats, firstUserPrompt, providerContextSizeFn, readSessionFileStats, } from './sessionStats';
14
18
  export { readSessionReportInputs } from './report/sessionReportInputs';
15
19
  export type { SessionReportInputs } from './report/sessionReportInputs';
package/dist/index.js CHANGED
@@ -3,16 +3,16 @@
3
3
  * Public API for sidekick-shared.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
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.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.codexIdentitiesMatch = exports.readCodexAccessTokenExpiry = exports.readCodexLastRefresh = exports.readCodexAuthIdentity = exports.parseCodexAuthJson = exports.CLAUDE_REFRESH_TOKEN_LIFETIME_ESTIMATE_MS = exports.CLAUDE_ACCESS_TOKEN_LIFETIME_MS = exports.resolveClaudeRefreshExpiry = exports.isNewerClaudeCredential = exports.claudeCredentialFreshness = exports.parseClaudeCredentialBlob = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentialsRaw = exports.readClaudeMaxCredentials = exports.deleteStoredCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = 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.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.ACCOUNT_CONSUMER_REACHABILITY = exports.describeAccountConsumer = exports.detectRunningAccountConsumersSync = exports.detectRunningAccountConsumers = exports.findRunningProcessesSync = exports.findRunningProcesses = exports.keepAliveCommand = exports.refreshInactiveAccounts = exports.getAccountLaunchEnv = exports.getHealthSidecarPath = exports.readHealthSidecar = exports.listAccountsWithHealth = exports.getAccountHealth = exports.cleanupAbandonedLogins = exports.syncLiveAccountStateSync = exports.syncLiveAccountState = exports.getLastSwitchPath = exports.readLastSwitch = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.getLastSwitch = exports.undoLastSwitch = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = exports.finalizeAccountLogin = exports.getAccountLoginStatusAsync = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.cleanupAbandonedClaudeLogins = exports.syncClaudeLiveState = exports.switchToAccountAsync = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = void 0;
12
- exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.QUOTA_PROVIDER_IDS = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.CODEX_KEYRING_FIX_HINT = exports.getCodexCredentialStoreMode = exports.cleanupAbandonedCodexLogins = exports.syncCodexLiveState = exports.removeCodexAccount = exports.switchToCodexAccountAsync = exports.switchToCodexAccount = exports.finalizeCodexAccountAsync = exports.finalizeCodexAccount = exports.prepareCodexAccountAsync = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readLiveClaudeIdentity = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = exports.buildClaudeChildEnv = exports.claudeKeychainAccountName = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeConfigPath = exports.getDefaultClaudeHome = exports.getLiveClaudeHome = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.onAccountsChanged = exports.getActiveAccountStatus = exports.ACCOUNT_PROVIDER_IDS = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = void 0;
13
- exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.MultiProviderQuotaService = exports.resolveZaiQuota = 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 = void 0;
14
- exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = 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 = void 0;
15
- exports.fetchProviderServiceStatus = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.scopePeakHoursToSessionProvider = exports.PEAK_HOURS_DESCRIPTION = exports.PEAK_HOURS_CACHE_MS = exports.isClaudeCodeSessionProvider = exports.getScheduledPeakHoursState = exports.fetchPeakHoursStatus = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = exports.createPeakHoursNotApplicableState = exports._resetPeakHoursCache = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.toLegacyProviderStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = void 0;
6
+ exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.collectPromptHistory = exports.readSessionTranscript = exports.listRecentSessions = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = void 0;
7
+ exports.addDecision = exports.completeTask = exports.addTask = exports.withFileLockSync = exports.updateJsonStoreAtomicSync = exports.updateJsonStoreAtomic = exports.atomicWriteFileSync = exports.atomicWriteJsonSync = exports.atomicWriteJson = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.migrateLegacyProjectStores = exports.resolveProjectIdentity = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.setConfigDir = exports.getDefaultConfigDir = exports.getConfigDirOverride = exports.getConfigDir = exports.CONFIG_DIR_ENV_VAR = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyDataStore = exports.createEmptyTokenTotals = exports.HISTORICAL_SESSION_RETENTION_LIMIT = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = exports.isAggregateCodexLimit = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = void 0;
8
+ exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionFilesWithStats = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.SESSION_ACTIVITY_STALENESS_MS = exports.SESSION_ACTIVITY_GRACE_PERIOD_MS = exports.refreshSessionActivityState = exports.detectSessionActivity = exports.classifySessionActivity = exports.extractTaskInfo = exports.scanSubagentDir = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports._resetProviderDetectionCache = exports.getObservedActivityReason = exports.derivePendingUserRequestV1 = exports.createProviderSessionAdapterV1 = exports.createSessionProviders = exports.SESSION_PROVIDER_IDS = exports.renderHandoffUrlTemplate = exports.addNote = exports.decisionFingerprint = void 0;
9
+ exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.createJsonlTail = exports.toFollowEvents = exports.resolveSessionPath = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.readSessionContextSnapshot = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = exports.parseMcpToolName = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = void 0;
10
+ exports.readCodexLastRefresh = exports.readCodexAuthIdentity = exports.parseCodexAuthJson = exports.CLAUDE_REFRESH_TOKEN_LIFETIME_ESTIMATE_MS = exports.CLAUDE_ACCESS_TOKEN_LIFETIME_MS = exports.resolveClaudeRefreshExpiry = exports.isNewerClaudeCredential = exports.claudeCredentialFreshness = exports.parseClaudeCredentialBlob = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentialsRaw = exports.readClaudeMaxCredentials = exports.deleteStoredCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.formatCompactionLedger = exports.calculateCompactionLedger = exports.describeCostProvenance = exports.classifyCostProvenance = exports.calculateCodeImpact = exports.scoreSessionQuality = exports.calculateQualityTrend = exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.readErrorHistory = exports.getTopFailingTools = exports.appendErrorHistory = exports.MAX_ERROR_HISTORY_SESSIONS = exports.ERROR_HISTORY_SCHEMA_VERSION = exports.getSnapshotPath = exports.MAX_SNAPSHOT_FILES = exports.pruneSnapshots = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.SessionMonitor = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.PHRASE_CATEGORIES = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = void 0;
11
+ exports.getAccountsDir = exports.ACCOUNT_CONSUMER_REACHABILITY = exports.describeAccountConsumer = exports.detectRunningAccountConsumersSync = exports.detectRunningAccountConsumers = exports.findRunningProcessesSync = exports.findRunningProcesses = exports.keepAliveCommand = exports.refreshInactiveAccounts = exports.getAccountLaunchEnv = exports.getHealthSidecarPath = exports.readHealthSidecar = exports.listAccountsWithHealth = exports.getAccountHealth = exports.cleanupAbandonedLogins = exports.syncLiveAccountStateSync = exports.syncLiveAccountState = exports.getLastSwitchPath = exports.readLastSwitch = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.getLastSwitch = exports.undoLastSwitch = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = exports.finalizeAccountLogin = exports.getAccountLoginStatusAsync = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.cleanupAbandonedClaudeLogins = exports.syncClaudeLiveState = exports.switchToAccountAsync = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.codexIdentitiesMatch = exports.readCodexAccessTokenExpiry = void 0;
12
+ exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.CODEX_KEYRING_FIX_HINT = exports.getCodexCredentialStoreMode = exports.cleanupAbandonedCodexLogins = exports.syncCodexLiveState = exports.removeCodexAccount = exports.switchToCodexAccountAsync = exports.switchToCodexAccount = exports.finalizeCodexAccountAsync = exports.finalizeCodexAccount = exports.prepareCodexAccountAsync = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readLiveClaudeIdentity = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.CLAUDE_SECURESTORAGE_CONFIG_DIR_ENV = exports.buildClaudeChildEnv = exports.claudeKeychainAccountName = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeConfigPath = exports.getDefaultClaudeHome = exports.getLiveClaudeHome = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.onAccountsChanged = exports.getActiveAccountStatus = exports.ACCOUNT_PROVIDER_IDS = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = void 0;
13
+ exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.MultiProviderQuotaService = exports.resolveZaiQuota = exports.readZaiCredentials = exports.quotaStateFromZaiQuotaLimitPayload = exports.fetchZaiQuotaFromApi = exports.CodexQuotaWatcher = exports.resolveCodexQuotaFromLocalSources = exports.resolveCodexQuota = exports.readLatestCodexQuotaFromRollouts = exports.quotaFromCodexRateLimits = exports.fetchCodexQuotaFromApi = exports.fetchCodexResetCreditsFromApi = exports.getWorkspaceIdFromPath = exports.pruneQuotaHistory = exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.quotaFromStatuslinePayload = exports.parseClaudeStatuslinePayload = exports.evaluateQuotaThresholds = exports.describeQuotaThresholdAlert = exports.DEFAULT_QUOTA_THRESHOLDS = exports.QUOTA_FRESH_MAX_AGE_MS = exports.QUOTA_AGING_MAX_AGE_MS = exports.formatQuotaAge = exports.classifyQuotaFreshness = exports.resolveQuota = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.QUOTA_PROVIDER_IDS = void 0;
14
+ exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = exports.extractErrorMessage = exports.categorizeError = exports.gatherAssetsForCwd = exports.codexSessions = exports.readCodexAssets = exports.claudeSessions = exports.readClaudeAssets = exports.extractCommands = exports.extractFilePaths = exports.extractUrls = exports.extractTokenUsage = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.MODEL_PROVIDER_IDS = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = void 0;
15
+ exports.fetchProviderServiceStatus = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.scopePeakHoursToSessionProvider = exports.PEAK_HOURS_DESCRIPTION = exports.PEAK_HOURS_CACHE_MS = exports.isClaudeCodeSessionProvider = exports.getScheduledPeakHoursState = exports.fetchPeakHoursStatus = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = exports.createPeakHoursNotApplicableState = exports._resetPeakHoursCache = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.toLegacyProviderStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = void 0;
16
16
  var usageNormalization_1 = require("./usageNormalization");
17
17
  Object.defineProperty(exports, "normalizeProviderUsage", { enumerable: true, get: function () { return usageNormalization_1.normalizeProviderUsage; } });
18
18
  Object.defineProperty(exports, "extractNormalizedUsage", { enumerable: true, get: function () { return usageNormalization_1.extractNormalizedUsage; } });
@@ -30,6 +30,13 @@ Object.defineProperty(exports, "projectSessionTranscript", { enumerable: true, g
30
30
  var sessionTranscripts_1 = require("./sessionTranscripts");
31
31
  Object.defineProperty(exports, "listRecentSessions", { enumerable: true, get: function () { return sessionTranscripts_1.listRecentSessions; } });
32
32
  Object.defineProperty(exports, "readSessionTranscript", { enumerable: true, get: function () { return sessionTranscripts_1.readSessionTranscript; } });
33
+ var promptHistory_1 = require("./promptHistory");
34
+ Object.defineProperty(exports, "collectPromptHistory", { enumerable: true, get: function () { return promptHistory_1.collectPromptHistory; } });
35
+ var humanPrompt_1 = require("./humanPrompt");
36
+ Object.defineProperty(exports, "HUMAN_CLAUDE_ENTRYPOINTS", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CLAUDE_ENTRYPOINTS; } });
37
+ Object.defineProperty(exports, "HUMAN_CODEX_SOURCES", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CODEX_SOURCES; } });
38
+ Object.defineProperty(exports, "humanPromptText", { enumerable: true, get: function () { return humanPrompt_1.humanPromptText; } });
39
+ Object.defineProperty(exports, "isHumanPrompt", { enumerable: true, get: function () { return humanPrompt_1.isHumanPrompt; } });
33
40
  var sessionStats_1 = require("./sessionStats");
34
41
  Object.defineProperty(exports, "computeSessionFileStats", { enumerable: true, get: function () { return sessionStats_1.computeSessionFileStats; } });
35
42
  Object.defineProperty(exports, "firstUserPrompt", { enumerable: true, get: function () { return sessionStats_1.firstUserPrompt; } });
@@ -48,6 +48,8 @@ const MODEL_CONTEXT_SIZES = {
48
48
  'claude-fable-5-1': 1_000_000,
49
49
  'claude-fable-5.1': 1_000_000,
50
50
  'claude-fable-5': 1_000_000,
51
+ 'claude-opus-5-5': 1_000_000,
52
+ 'claude-opus-5.5': 1_000_000,
51
53
  'claude-opus-5': 1_000_000,
52
54
  'claude-opus-4-8': 1_000_000,
53
55
  'claude-opus-4-7': 1_000_000,
@@ -75,6 +77,8 @@ const MODEL_CONTEXT_SIZES = {
75
77
  // window per account tier via token_count; that value wins through the
76
78
  // observed-override layer.
77
79
  'gpt-6-astra': 1_050_000,
80
+ 'gpt-6-sol': 1_050_000,
81
+ 'gpt-6-luna': 1_050_000,
78
82
  'gpt-5.6-sol': 1_050_000,
79
83
  'gpt-5.6-terra': 1_050_000,
80
84
  'gpt-5.6-luna': 1_050_000,
package/dist/modelInfo.js CHANGED
@@ -52,7 +52,7 @@ Object.defineProperty(exports, "MODEL_PROVIDER_IDS", { enumerable: true, get: fu
52
52
  * Sources:
53
53
  * - Anthropic: https://platform.claude.com/docs/en/about-claude/pricing
54
54
  * - OpenAI: https://developers.openai.com/api/docs/models
55
- * Current Anthropic and GPT-5.6/6 rates verified: 2026-09-05.
55
+ * Current Anthropic and GPT-5.6/6 rates verified: 2026-09-22.
56
56
  * Runtime LiteLLM hydration refreshes this offline baseline.
57
57
  *
58
58
  * Anthropic keys appear in both dashed (`claude-opus-4-8`, the real model-ID
@@ -136,6 +136,19 @@ const PRICING_TABLE = {
136
136
  cacheWriteCostPerMillion: 3.75,
137
137
  cacheReadCostPerMillion: 0.3,
138
138
  },
139
+ // Opus 5.5 undercuts Opus 5; without its own keys it would prefix-match 'claude-opus-5'.
140
+ 'claude-opus-5-5': {
141
+ inputCostPerMillion: 4.0,
142
+ outputCostPerMillion: 20.0,
143
+ cacheWriteCostPerMillion: 5.0,
144
+ cacheReadCostPerMillion: 0.2,
145
+ },
146
+ 'claude-opus-5.5': {
147
+ inputCostPerMillion: 4.0,
148
+ outputCostPerMillion: 20.0,
149
+ cacheWriteCostPerMillion: 5.0,
150
+ cacheReadCostPerMillion: 0.2,
151
+ },
139
152
  'claude-opus-5': {
140
153
  inputCostPerMillion: 5.0,
141
154
  outputCostPerMillion: 25.0,
@@ -259,6 +272,18 @@ const PRICING_TABLE = {
259
272
  cacheWriteCostPerMillion: 12.5,
260
273
  cacheReadCostPerMillion: 1.0,
261
274
  },
275
+ 'gpt-6-sol': {
276
+ inputCostPerMillion: 2.0,
277
+ outputCostPerMillion: 10.0,
278
+ cacheWriteCostPerMillion: 2.5,
279
+ cacheReadCostPerMillion: 0.2,
280
+ },
281
+ 'gpt-6-luna': {
282
+ inputCostPerMillion: 0.1,
283
+ outputCostPerMillion: 0.5,
284
+ cacheWriteCostPerMillion: 0.125,
285
+ cacheReadCostPerMillion: 0.01,
286
+ },
262
287
  'gpt-5.6-sol': {
263
288
  inputCostPerMillion: 4.0,
264
289
  outputCostPerMillion: 20.0,
package/dist/node.d.ts CHANGED
@@ -10,6 +10,10 @@ export type { HydrateOptions, HydrateResult } from './pricingCatalog';
10
10
  export { loadObservedContextWindows, recordObservedContextWindow, getObservedContextWindowPath, } from './observedContextWindows';
11
11
  export type { ObservedContextWindowOptions, ObservedContextWindowStore, } from './observedContextWindows';
12
12
  export { listRecentSessions, readSessionTranscript } from './sessionTranscripts';
13
+ export { collectPromptHistory } from './promptHistory';
14
+ export type { CollectPromptHistoryOptions, PromptHistoryBound, PromptHistoryBounds, PromptHistoryCursor, PromptHistoryCursorSession, PromptHistoryEntry, PromptHistoryMetadataStatus, PromptHistoryPendingPrompt, PromptHistoryProvider, PromptHistoryResult, PromptHistoryResumeState, PromptHistoryStats, PromptHistoryUsage, } from './promptHistory';
15
+ export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
16
+ export type { HumanPromptProvider } from './humanPrompt';
13
17
  export { computeSessionFileStats, firstUserPrompt, providerContextSizeFn, readSessionFileStats, } from './sessionStats';
14
18
  export { readSessionReportInputs } from './report/sessionReportInputs';
15
19
  export type { SessionReportInputs } from './report/sessionReportInputs';
package/dist/node.js CHANGED
@@ -7,8 +7,8 @@
7
7
  * for browser bundles — use `sidekick-shared/browser` there.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.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.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = void 0;
10
+ exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.collectPromptHistory = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
11
+ exports.fetchProviderServiceStatus = exports.splitWatchedPath = exports.DirectoryListingCache = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = void 0;
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; } });
@@ -21,6 +21,13 @@ Object.defineProperty(exports, "getObservedContextWindowPath", { enumerable: tru
21
21
  var sessionTranscripts_1 = require("./sessionTranscripts");
22
22
  Object.defineProperty(exports, "listRecentSessions", { enumerable: true, get: function () { return sessionTranscripts_1.listRecentSessions; } });
23
23
  Object.defineProperty(exports, "readSessionTranscript", { enumerable: true, get: function () { return sessionTranscripts_1.readSessionTranscript; } });
24
+ var promptHistory_1 = require("./promptHistory");
25
+ Object.defineProperty(exports, "collectPromptHistory", { enumerable: true, get: function () { return promptHistory_1.collectPromptHistory; } });
26
+ var humanPrompt_1 = require("./humanPrompt");
27
+ Object.defineProperty(exports, "HUMAN_CLAUDE_ENTRYPOINTS", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CLAUDE_ENTRYPOINTS; } });
28
+ Object.defineProperty(exports, "HUMAN_CODEX_SOURCES", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CODEX_SOURCES; } });
29
+ Object.defineProperty(exports, "humanPromptText", { enumerable: true, get: function () { return humanPrompt_1.humanPromptText; } });
30
+ Object.defineProperty(exports, "isHumanPrompt", { enumerable: true, get: function () { return humanPrompt_1.isHumanPrompt; } });
24
31
  var sessionStats_1 = require("./sessionStats");
25
32
  Object.defineProperty(exports, "computeSessionFileStats", { enumerable: true, get: function () { return sessionStats_1.computeSessionFileStats; } });
26
33
  Object.defineProperty(exports, "firstUserPrompt", { enumerable: true, get: function () { return sessionStats_1.firstUserPrompt; } });