sidekick-shared 0.26.1 → 0.26.3

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,33 @@ All notable changes to sidekick-shared will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.26.3] - 2026-09-09
9
+
10
+ ### Added
11
+
12
+ - `diagnoseProviderFailure()` and its pure types are available from the root and browser entry points. Results contain bounded diagnosis/recovery identifiers, evidence provenance, and optional HTTP/retry-after data without raw errors or credentials.
13
+ - `fetchProviderServiceStatus()` is available from the root and Node entry points, with pure result types also exported through browser. Stateless official-feed checks support cancellation and a ten-second deadline, preserve component/incident associations and independent timestamps, and distinguish observed, unavailable, and omitted incident evidence.
14
+ - `HealthReport.serviceStatus` and `DoctorOptions.fetchServiceStatuses` add explicit service evidence while retaining legacy status output and injection. `toLegacyProviderStatus()` supports compatibility projections.
15
+
16
+ ### Changed
17
+
18
+ - Doctor reports unavailable and partial public evidence explicitly. Existing `ErrorCategory`, quota guidance, and legacy status functions/types remain compatible; consumers needing availability semantics should adopt the new API.
19
+
20
+ ## [0.26.2] - 2026-09-06
21
+
22
+ ### Added
23
+
24
+ - `DoctorOptions.provider` selects the session provider to diagnose; `HealthReport.sessionProvider` records it.
25
+ - Optional watcher `onBatchComplete` callback for persisting state after all events in a read have been delivered.
26
+ - `SessionSearchOptions.projectPath` and `signal` for provider-aware workspace filtering and cancellation; legacy `projectSlug` remains supported.
27
+
28
+ ### Fixed
29
+
30
+ - JSONL watcher and provider reader checkpoints end at complete lines, retaining partial UTF-8 characters across reads and restarts. Codex restores parser context when seeking.
31
+ - Watcher failures retain polling fallback; OpenCode watchers share the canonical data-directory resolver.
32
+ - Session search enumerates through providers, includes database-only sessions, and deduplicates paths.
33
+ - Doctor checks the selected session provider, treats unrelated integrations as informational, and reads account status without changing account selection.
34
+
8
35
  ## [0.26.1] - 2026-09-05
9
36
 
10
37
  ### Fixed
package/README.md CHANGED
@@ -9,6 +9,7 @@ Types, parsers, providers, readers, formatters, aggregation, search, reporting,
9
9
 
10
10
  ## Recent additions
11
11
 
12
+ - **0.26.2: reliable monitoring and search** — complete-line JSONL cursors preserve Unicode and Codex parser context; watcher `onBatchComplete` signals a delivered batch. `searchSessions()` adds workspace-path filtering and cancellation, and Doctor accepts an explicit session provider.
12
13
  - **One token vocabulary and cost provenance (0.26.0)** — `summarizeTokens()` gives every surface the same `total` (input + output + cache writes + cache reads) and `context` (input + cache) figures; `AggregatedTokens.costUsd` carries `costProvenance` so reports can say whether a cost was provider-reported or estimated; `parseClaudeStatuslinePayload()` / `quotaFromStatuslinePayload()` turn Claude Code's status-line JSON into an official `statusline` quota source; `readQuotaSnapshot()` reports `ageMs` / `freshness` and keeps the sample's origin as `capturedSource`; `resolveQuota()` shares quota resolution across CLI, MCP, and dashboard startup, with default local-sample preferences and an API-first option used by one-shot Codex queries; `readSessionFileStats()` / `computeSessionFileStats()` give every provider one `readSessionStats()` over the shared aggregator, with `availability`, `costProvenance`, and `toolFailures` on `SessionFileStats`; `collectUsageEvents()` reads priced usage events from session logs with a per-session cache, `computeBillingBlocks()` groups them into five-hour billing blocks, and `bucketUsage()` turns them into day, week, month, or session rows; `applySessionSummary()` and `importSessionHistory()` let any host fold finished sessions into `historical-data.json` the way the extension does; observed sessions are read once per discovery, re-read only when their fingerprint changes, and classified from events by `classifySessionActivity()`; `readSessionReportInputs()` derives report metrics and transcript from one read; `writeStateFile()` / `readStateFile()` (also on the `statusline` subpath) maintain the public, versioned `state.json` for external tools, validated by `sidekickStateFileSchema`; `getScheduledPeakHoursState()` and `evaluateQuotaThresholds()` are shared by the CLI and extension dashboards.
13
14
  - **Host-safe APIs (0.25.0)** — `listSessionPreviewsAsync()` / `readSessionPreviewAsync()` read previews with bounded concurrency and cooperative yielding; `ObservedSessionCollector.subscribe()` and `SessionMonitor.subscribe()` replace host polling loops with debounced change batches; `createSessionProviders({ onDiagnostic })` constructs every usable provider with structured diagnostics instead of throwing; `findSessionById()` resolves one session without scanning; `exportResolvedModelCatalog()` / `importResolvedModelCatalog()` and `registerModelAlias()` transfer context/pricing resolutions across realms; `onAccountsChanged()` reports login/logout/switch events; provider constructors perform no environment I/O, and quota pollers stay dormant without an account.
14
15
  - **Native session-file helpers** — `encodeClaudeWorkspacePath()` / `getClaudeSessionDirectory()` locate Claude Code's `~/.claude/projects/` directories with the real on-disk encoding, `findCodexRolloutFile()` resolves a Codex session id to its rollout path, `readCodexHistory()` tail-reads `~/.codex/history.jsonl`, `listSessionPreviews()` / `readSessionPreview()` build a cheap stat-first recent-sessions index across providers, and `parseMcpToolName()` splits `mcp__<server>__<tool>` identifiers (browser-safe).
@@ -104,7 +105,7 @@ returns the platform default that both overrides bypass.
104
105
  | **Credentials** | Claude Max OAuth credential reading from `~/.claude/.credentials.json` |
105
106
  | **Quota** | Claude Max subscription quota fetching (5-hour and 7-day windows), Codex rate-limit extraction from event streams (plus Codex reset credits via `fetchCodexResetCreditsFromApi()`, attached to quota state by `fetchCodexQuotaFromApi()`), and authoritative z.ai Coding Plan quota fetching via `resolveZaiQuota()` / `fetchZaiQuotaFromApi()` (reads z.ai's `api/monitor/usage/quota/limit` endpoint with cached-snapshot fallback). The observed-traffic z.ai estimator was removed from the package root exports in 0.23.0 and every remaining export of it is `@deprecated` — `resolveZaiQuota()` is the single supported z.ai quota API |
106
107
  | **Provider Status** | API health checking via status.claude.com and status.openai.com (indicator, components, incidents) |
107
- | **Doctor** | Typed cross-provider health diagnostics — `runDoctor()` checks project identity, sessions, accounts, providers, and dependencies into a `HealthReport`; `formatHealthReport()` renders it and `getSessionDiagnostics()` exposes the per-provider session probe |
108
+ | **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 |
108
109
  | **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`) — 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 |
109
110
  | **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 |
110
111
  | **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 |
@@ -448,20 +449,83 @@ const tasks = await readTasks(project, { status: 'pending' });
448
449
  console.log(`Found ${tasks.length} tasks`);
449
450
  ```
450
451
 
451
- ### Check provider status
452
+ ### Diagnose terminal provider failures
453
+
454
+ `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.
452
455
 
453
456
  ```typescript
454
- import { fetchProviderStatus } from 'sidekick-shared';
457
+ import { diagnoseProviderFailure } from 'sidekick-shared/browser';
455
458
 
456
- const status = await fetchProviderStatus();
457
- if (status.indicator !== 'none') {
458
- console.log(`Claude API: ${status.description}`);
459
- for (const c of status.affectedComponents) {
460
- console.log(` ${c.name}: ${c.status}`);
461
- }
459
+ function diagnoseTerminalError(error: unknown) {
460
+ return diagnoseProviderFailure({
461
+ provider: 'codex', // AccountProviderId: 'claude-code' | 'codex'
462
+ credentialKind: 'oauth', // 'oauth' | 'api-key' | 'unknown'
463
+ error,
464
+ authentication: {
465
+ credentialKind: 'oauth',
466
+ state: 'authenticated',
467
+ source: 'local-check',
468
+ checkedAt: '2026-09-09T12:00:00.000Z',
469
+ },
470
+ });
471
+ }
472
+ ```
473
+
474
+ Authentication evidence is optional. Its states are `authenticated`, `missing`, `signed-out`, `expired`, `rejected`, and `unknown`; sources are `local-check` and `provider-response`. The caller owns the observation's freshness and relevance. File presence alone does not establish authenticated request success.
475
+
476
+ The result contains `provider`, caller-supplied `credentialKind`, `diagnosis`, `recovery`, and `evidence`. Evidence records a bounded rule and its source (`structured-error`, `http-status`, `message`, or `authentication-check`); authentication-check evidence includes `checkedAt`. Valid supplied authentication evidence is preserved separately. Optional `httpStatus` and `retryAfter` retain request information; retry-after is `{ kind: 'delay', delayMs }` or `{ kind: 'date', at }`, without a clock-dependent conversion.
477
+
478
+ | Diagnosis | Recovery identifier |
479
+ | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
480
+ | `missing_credentials` | `sign_in`, `update_credentials`, or `check_authentication`, according to credential kind |
481
+ | `oauth_reauthentication_required` | `sign_in` |
482
+ | `api_credentials_rejected` | `update_credentials` |
483
+ | `authentication_rejected` (credential kind unknown) | `check_authentication` |
484
+ | `invalid_provider_session` | `start_new_session` |
485
+ | `service_unavailable`, `timeout`, `rate_limited`, `overloaded` | `retry_later` |
486
+ | `connection_failed` | `check_connection` |
487
+ | `execution_policy_denied` | `review_execution_policy` |
488
+ | `runtime_unavailable` | `repair_runtime` |
489
+ | `context_overflow` | `reduce_context` |
490
+ | `unknown` | `inspect_error` |
491
+
492
+ Recognized structured request codes take precedence over HTTP status, followed by narrow message patterns. A bare 401 establishes credential rejection, with recovery chosen from the credential kind; a bare 403 does not distinguish authentication from execution policy and remains unknown. Explicit credential rejection from the request overrides a successful local OAuth check. OAuth observations never validate API keys. Thread/conversation failures, 5xx responses, DNS failures, and connection resets do not establish rejected account credentials. The reported `Reconnecting... 2/5 (unexpected status 503 Service Unavailable: upstream connect error or disconnect/reset before headers. reset reason: connection termination)` is classified as `service_unavailable`, with message provenance and HTTP 503, if the caller supplies it as a terminal error.
493
+
494
+ The projection contains no raw errors, stacks, credentials, or request URLs. Product wording belongs to consumers. The helper performs no I/O, credential reads, SDK calls, stream control, retries, or UI actions. Existing transcript/tool `ErrorCategory` and quota-specific guidance contracts remain unchanged.
495
+
496
+ ### Check public provider service status
497
+
498
+ ```typescript
499
+ import { fetchProviderServiceStatus } from 'sidekick-shared/node';
500
+ import type { ProviderServiceStatus } from 'sidekick-shared/browser';
501
+
502
+ const controller = new AbortController();
503
+ const status: ProviderServiceStatus = await fetchProviderServiceStatus('codex', {
504
+ signal: controller.signal,
505
+ });
506
+
507
+ if (status.availability === 'unavailable') {
508
+ console.log('Public status unavailable', status.reason, status.checkedAt);
509
+ } else {
510
+ console.log(status.severity, status.checkedAt, status.providerUpdatedAt);
511
+ // null means the feed omitted incident evidence; [] explicitly reports none unresolved.
512
+ console.log(status.incidents === null ? 'Incident information unavailable' : status.incidents);
462
513
  }
463
514
  ```
464
515
 
516
+ The fetcher is exported from root and Node, with pure result types also exported from browser. It requests the official [Claude summary](https://status.claude.com/api/v2/summary.json) or [OpenAI summary](https://status.openai.com/api/v2/summary.json) without credentials. Every call has a ten-second deadline covering headers and body consumption, supports caller cancellation, and performs one request with no retries or cache.
517
+
518
+ - `observed` results contain provider, source URL, check timestamp, reported severity/description, provider page update timestamp, all reported components, and unresolved incidents. Supported severity values are `none`, `minor`, `major`, `critical`, and `maintenance`.
519
+ - Components retain IDs, names, and reported states. Incidents retain IDs, titles, status, impact, HTTP(S) links, provider update timestamps, and component IDs. Unknown associations are `null`; unmatched IDs are preserved. Resolved and postmortem incidents are excluded.
520
+ - Omitted incident data is represented as `incidents: null`, preserving a partial observation without claiming zero incidents. Missing provider timestamps and links remain `null`; the check timestamp never substitutes for a provider update.
521
+ - `unavailable` results contain no severity. Reasons are `http_error`, `network_error`, `timeout`, `cancelled`, or `invalid_response`, with optional HTTP status and no raw error text. Malformed supplied fields are rejected rather than defaulted to operational.
522
+
523
+ Request failure, authentication, CLI readiness, and public service status are separate observations. Public incidents supplement a diagnosis but do not prove a failed request's cause. An operational public page does not prove that the user's connection works. Preserve component associations to avoid attributing unrelated vendor incidents to Claude Code or Codex; unknown component mappings and custom provider endpoints remain uncorrelated. The result's `provider` identifies the selected public feed, not a verified request-backend mapping.
524
+
525
+ Consumers own caching, stale-evidence presentation, polling, and request coalescing. Neither API initiates sign-in, modifies credentials, switches providers, requests a model response, or replays a turn.
526
+
527
+ `fetchProviderStatus()`, `fetchOpenAIStatus()`, and `ProviderStatusState` remain compatible. Their historical fallback combines `indicator: 'none'` with `Status unavailable`; migrate to the new API for reliable availability semantics. `toLegacyProviderStatus()` is a lossy compatibility projection for older output contracts, not an availability check. Doctor includes optional `serviceStatus` evidence alongside legacy `providerStatus`; its new `fetchServiceStatuses` injection takes precedence over legacy `fetchStatuses`, which remains supported without additional network requests.
528
+
465
529
  ### Check Claude peak-hours state
466
530
 
467
531
  ```typescript
@@ -670,6 +734,26 @@ const tail = createJsonlTail({
670
734
  tail.start();
671
735
  ```
672
736
 
737
+ `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.
738
+
739
+ ### Search a workspace and diagnose its provider
740
+
741
+ ```typescript
742
+ import { CodexProvider, searchSessions, runDoctor } from 'sidekick-shared';
743
+
744
+ const provider = new CodexProvider();
745
+ const controller = new AbortController();
746
+ const matches = await searchSessions(provider, 'authentication', {
747
+ projectPath: '/path/to/project',
748
+ signal: controller.signal,
749
+ maxResults: 20,
750
+ });
751
+ const report = await runDoctor({ cwd: '/path/to/project', provider: 'codex' });
752
+ console.log(matches, report.sessionProvider, report.checks);
753
+ ```
754
+
755
+ `projectPath` resolves the workspace canonically and takes precedence over the legacy `projectSlug`. Cancellation is checked between session reads; it does not interrupt an in-progress synchronous provider read. `HealthReport.sessionProvider` is optional for compatibility. `getSessionDiagnostics()` remains a Claude Code path diagnostic; use `runDoctor()` for provider-aware checks.
756
+
673
757
  ### Poll quota with backoff
674
758
 
675
759
  ```typescript
package/dist/browser.d.ts CHANGED
@@ -39,3 +39,6 @@ export { applySessionSummary, isFileImported, markFileImported, removeSessionSum
39
39
  export type { ApplySessionSummaryOptions, SessionSummaryFromStatsOptions } from './historicalStore';
40
40
  export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
41
41
  export type { FailingToolTrend, FailingToolTrendRow, FailingToolWindow } from './failingTools';
42
+ export { diagnoseProviderFailure } from './providerFailure';
43
+ export type { ProviderCredentialKind, ProviderAuthenticationEvidence, ProviderFailureInput, ProviderFailureCode, ProviderRecoveryAction, ProviderRetryAfter, ProviderFailureEvidence, ProviderFailureDiagnosis, } from './providerFailure';
44
+ export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
package/dist/browser.js CHANGED
@@ -10,7 +10,7 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.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.TOKEN_TOTAL_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
13
- 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 = void 0;
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 = 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; } });
@@ -92,3 +92,5 @@ var failingTools_1 = require("./failingTools");
92
92
  Object.defineProperty(exports, "FAILING_TOOL_TREND_ARROWS", { enumerable: true, get: function () { return failingTools_1.FAILING_TOOL_TREND_ARROWS; } });
93
93
  Object.defineProperty(exports, "failingToolTrend", { enumerable: true, get: function () { return failingTools_1.failingToolTrend; } });
94
94
  Object.defineProperty(exports, "mergeFailingToolWindows", { enumerable: true, get: function () { return failingTools_1.mergeFailingToolWindows; } });
95
+ var providerFailure_1 = require("./providerFailure");
96
+ Object.defineProperty(exports, "diagnoseProviderFailure", { enumerable: true, get: function () { return providerFailure_1.diagnoseProviderFailure; } });
package/dist/doctor.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { type ActiveAccountStatus } from './accountStatus';
2
2
  import { type ProjectIdentity } from './paths';
3
3
  import { type ProviderStatusState } from './providerStatus';
4
+ import type { ProviderServiceStatus } from './providerServiceStatusTypes';
5
+ import type { ProviderId } from './providers/types';
4
6
  import { type OpenCodeDbRuntimeStatus } from './providers/openCodeDatabase';
5
7
  export type HealthCheckStatus = 'ok' | 'warning' | 'error' | 'info';
6
8
  export interface HealthCheck {
@@ -38,12 +40,25 @@ export interface HealthReport {
38
40
  claude: ProviderStatusState;
39
41
  openai: ProviderStatusState;
40
42
  };
43
+ serviceStatus?: {
44
+ claude: ProviderServiceStatus;
45
+ openai: ProviderServiceStatus;
46
+ };
47
+ /** Legacy Claude Code path diagnostics, retained for compatibility. */
41
48
  sessions: SessionDiagnostics;
49
+ sessionProvider?: ProviderId;
42
50
  }
43
51
  export interface DoctorOptions {
44
52
  cwd?: string;
53
+ /** Session provider to diagnose; defaults to auto-detection. */
54
+ provider?: ProviderId | 'auto';
45
55
  deprecatedSettings?: DeprecatedSetting[];
46
56
  openCodeStatus?: OpenCodeDbRuntimeStatus;
57
+ fetchServiceStatuses?: () => Promise<{
58
+ claude: ProviderServiceStatus;
59
+ openai: ProviderServiceStatus;
60
+ }>;
61
+ /** Legacy injection; does not establish service evidence availability. */
47
62
  fetchStatuses?: () => Promise<{
48
63
  claude: ProviderStatusState;
49
64
  openai: ProviderStatusState;
package/dist/doctor.js CHANGED
@@ -43,7 +43,10 @@ const accountStatus_1 = require("./accountStatus");
43
43
  const paths_1 = require("./paths");
44
44
  const sessionPathResolver_1 = require("./parsers/sessionPathResolver");
45
45
  const providerStatus_1 = require("./providerStatus");
46
+ const providerServiceStatus_1 = require("./providerServiceStatus");
46
47
  const openCode_1 = require("./providers/openCode");
48
+ const factory_1 = require("./providers/factory");
49
+ const detect_1 = require("./providers/detect");
47
50
  const openCodeDatabase_1 = require("./providers/openCodeDatabase");
48
51
  /** Collects the Claude Code path-resolution detail used by both host surfaces. */
49
52
  function getSessionDiagnostics(workspacePath) {
@@ -100,21 +103,95 @@ function statusUnavailable() {
100
103
  updatedAt: new Date().toISOString(),
101
104
  };
102
105
  }
106
+ async function checkSessionProvider(providerId, workspacePath) {
107
+ const { providers } = (0, factory_1.createSessionProviders)({ providerIds: [providerId] });
108
+ const provider = providers[0];
109
+ const title = `Session discovery (${provider?.displayName ?? providerId})`;
110
+ try {
111
+ if (!provider)
112
+ throw new Error(`${providerId} could not be initialized.`);
113
+ const sessions = provider.listSessionFilesAsync
114
+ ? await provider.listSessionFilesAsync(workspacePath)
115
+ : provider.findAllSessions(workspacePath);
116
+ if (sessions.length > 0) {
117
+ return {
118
+ id: 'session_discovery',
119
+ status: 'ok',
120
+ title,
121
+ message: `Found ${sessions.length} ${provider.displayName} session${sessions.length === 1 ? '' : 's'} for ${workspacePath}.`,
122
+ };
123
+ }
124
+ const operation = provider.getLastOperationStatus?.();
125
+ const runtime = provider.getRuntimeStatus?.();
126
+ const issue = operation && !operation.usable
127
+ ? operation.runtimeStatus
128
+ : runtime && !runtime.available
129
+ ? runtime
130
+ : undefined;
131
+ return {
132
+ id: 'session_discovery',
133
+ status: 'warning',
134
+ title,
135
+ message: issue?.message ?? `No ${provider.displayName} sessions found for ${workspacePath}.`,
136
+ repair: issue?.kind === 'sqlite_missing'
137
+ ? 'Install sqlite3 and ensure it is on PATH, then rerun sidekick doctor.'
138
+ : `Start ${provider.displayName} in this project, or inspect ${provider.getSessionDirectory(workspacePath)}.`,
139
+ };
140
+ }
141
+ catch (error) {
142
+ return {
143
+ id: 'session_discovery',
144
+ status: 'warning',
145
+ title,
146
+ message: error instanceof Error ? error.message : String(error),
147
+ repair: `Check ${providerId} session storage permissions and rerun sidekick doctor.`,
148
+ };
149
+ }
150
+ finally {
151
+ for (const candidate of providers)
152
+ candidate.dispose();
153
+ }
154
+ }
103
155
  async function runDoctor(options = {}) {
104
156
  const project = (0, paths_1.resolveProjectIdentity)(options.cwd);
105
157
  const sessions = getSessionDiagnostics(project.cwd);
106
- const accounts = (0, accountStatus_1.getActiveAccountStatus)();
158
+ const accounts = (0, accountStatus_1.getActiveAccountStatus)(undefined, { selfHeal: false });
159
+ const sessionProvider = options.provider && options.provider !== 'auto' ? options.provider : (0, detect_1.detectProvider)();
107
160
  let openCode = options.openCodeStatus;
108
161
  if (!openCode) {
109
162
  const database = new openCodeDatabase_1.OpenCodeDatabase((0, openCode_1.getOpenCodeDataDir)());
110
163
  database.open();
111
164
  openCode = database.getRuntimeStatus();
165
+ database.close();
112
166
  }
113
- const providerStatus = await (options.fetchStatuses ??
114
- (async () => {
115
- const [claude, openai] = await Promise.all([(0, providerStatus_1.fetchProviderStatus)(), (0, providerStatus_1.fetchOpenAIStatus)()]);
116
- return { claude, openai };
117
- }))().catch(() => ({ claude: statusUnavailable(), openai: statusUnavailable() }));
167
+ const serviceStatus = options.fetchServiceStatuses || !options.fetchStatuses
168
+ ? await (options.fetchServiceStatuses ??
169
+ (async () => {
170
+ const [claude, openai] = await Promise.all([
171
+ (0, providerServiceStatus_1.fetchProviderServiceStatus)('claude-code'),
172
+ (0, providerServiceStatus_1.fetchProviderServiceStatus)('codex'),
173
+ ]);
174
+ return { claude, openai };
175
+ }))().catch(() => {
176
+ const unavailable = (provider) => ({
177
+ availability: 'unavailable',
178
+ provider,
179
+ checkedAt: new Date().toISOString(),
180
+ sourceUrl: `https://status.${provider === 'codex' ? 'openai' : 'claude'}.com/api/v2/summary.json`,
181
+ reason: 'network_error',
182
+ });
183
+ return { claude: unavailable('claude-code'), openai: unavailable('codex') };
184
+ })
185
+ : undefined;
186
+ const providerStatus = serviceStatus
187
+ ? {
188
+ claude: (0, providerStatus_1.toLegacyProviderStatus)(serviceStatus.claude),
189
+ openai: (0, providerStatus_1.toLegacyProviderStatus)(serviceStatus.openai),
190
+ }
191
+ : await options.fetchStatuses().catch(() => ({
192
+ claude: statusUnavailable(),
193
+ openai: statusUnavailable(),
194
+ }));
118
195
  const checks = [];
119
196
  checks.push(project.hasLegacyMismatch
120
197
  ? {
@@ -130,20 +207,7 @@ async function runDoctor(options = {}) {
130
207
  title: 'Project identity',
131
208
  message: `Canonical slug: ${project.canonicalSlug}`,
132
209
  });
133
- checks.push(sessions.discoveredSessionDir
134
- ? {
135
- id: 'session_discovery',
136
- status: 'ok',
137
- title: 'Session discovery',
138
- message: `Found Claude Code sessions at ${sessions.discoveredSessionDir}.`,
139
- }
140
- : {
141
- id: 'session_discovery',
142
- status: 'warning',
143
- title: 'Session discovery',
144
- message: `No Claude Code session directory found for ${project.cwd}.`,
145
- repair: `Start Claude Code in this project, or inspect ${sessions.expectedSessionDir}.`,
146
- });
210
+ checks.push(await checkSessionProvider(sessionProvider, project.resolvedCwd));
147
211
  const openCodeCheck = openCode.available
148
212
  ? {
149
213
  id: 'opencode_sqlite',
@@ -167,33 +231,66 @@ async function runDoctor(options = {}) {
167
231
  ? 'Install sqlite3 and ensure the sqlite3 executable is on PATH, then rerun sidekick doctor.'
168
232
  : 'Make sqlite3 executable and verify the OpenCode database is readable.',
169
233
  };
234
+ if (sessionProvider !== 'opencode' && openCodeCheck.status === 'warning') {
235
+ openCodeCheck.status = 'info';
236
+ openCodeCheck.message += ' This does not affect the selected session provider.';
237
+ }
170
238
  checks.push(openCodeCheck);
171
239
  checks.push({
172
240
  id: 'accounts',
173
- status: accounts.ok ? 'ok' : 'warning',
241
+ status: accounts.ok ? 'ok' : 'info',
174
242
  title: 'Accounts and credentials',
175
243
  message: accounts.ok
176
244
  ? `Detected ${[accounts.claude.present && 'Claude', accounts.codex.present && 'Codex'].filter(Boolean).join(' and ')} credentials.`
177
245
  : (accounts.error ?? 'No Claude or Codex credentials were detected.'),
178
246
  ...(!accounts.ok
179
- ? { repair: 'Sign in with claude or codex, then rerun sidekick doctor.' }
247
+ ? {
248
+ repair: 'Sign in with claude or codex to refresh account quota. Existing sessions can be monitored without saved credentials.',
249
+ }
180
250
  : {}),
181
251
  });
182
- const unavailableProviders = Object.entries(providerStatus)
183
- .filter(([, status]) => status.description === 'Status unavailable')
184
- .map(([name]) => name);
185
- const degradedProviders = Object.entries(providerStatus)
186
- .filter(([, status]) => status.indicator !== 'none')
187
- .map(([name]) => name);
252
+ const unavailableProviders = serviceStatus
253
+ ? Object.entries(serviceStatus)
254
+ .filter(([, status]) => status.availability === 'unavailable')
255
+ .map(([name]) => name)
256
+ : Object.entries(providerStatus)
257
+ .filter(([, status]) => status.description === 'Status unavailable')
258
+ .map(([name]) => name);
259
+ const degradedProviders = serviceStatus
260
+ ? Object.entries(serviceStatus)
261
+ .filter(([, status]) => status.availability === 'observed' && status.severity !== 'none')
262
+ .map(([name]) => name)
263
+ : Object.entries(providerStatus)
264
+ .filter(([, status]) => status.indicator !== 'none')
265
+ .map(([name]) => name);
266
+ const partialProviders = serviceStatus
267
+ ? Object.entries(serviceStatus)
268
+ .filter(([, status]) => status.availability === 'observed' && status.incidents === null)
269
+ .map(([name]) => name)
270
+ : [];
271
+ const observations = [
272
+ ...(degradedProviders.length
273
+ ? [`Public vendor degradation reported for: ${degradedProviders.join(', ')}.`]
274
+ : []),
275
+ ...(unavailableProviders.length
276
+ ? [`Status pages unavailable for: ${unavailableProviders.join(', ')}.`]
277
+ : []),
278
+ ...(partialProviders.length
279
+ ? [`Incident information unavailable for: ${partialProviders.join(', ')}.`]
280
+ : []),
281
+ ];
188
282
  checks.push({
189
283
  id: 'provider_api',
190
- status: degradedProviders.length > 0 ? 'warning' : unavailableProviders.length > 0 ? 'info' : 'ok',
191
- title: 'Provider API status',
192
- message: degradedProviders.length > 0
193
- ? `Provider incidents reported for: ${degradedProviders.join(', ')}.`
194
- : unavailableProviders.length > 0
195
- ? `Status pages unavailable for: ${unavailableProviders.join(', ')}.`
196
- : 'Claude and OpenAI status pages report normal operation.',
284
+ status: degradedProviders.includes(sessionProvider === 'codex' ? 'openai' : sessionProvider === 'claude-code' ? 'claude' : '')
285
+ ? 'warning'
286
+ : observations.length
287
+ ? 'info'
288
+ : 'ok',
289
+ title: 'Public provider service status',
290
+ message: (observations.length
291
+ ? observations.join(' ')
292
+ : 'Claude and OpenAI status pages report normal operation.') +
293
+ ' Public status does not establish request connectivity or authentication.',
197
294
  });
198
295
  const deprecatedSettings = options.deprecatedSettings ?? [];
199
296
  checks.push({
@@ -225,7 +322,9 @@ async function runDoctor(options = {}) {
225
322
  accounts,
226
323
  openCode,
227
324
  providerStatus,
325
+ ...(serviceStatus ? { serviceStatus } : {}),
228
326
  sessions,
327
+ sessionProvider,
229
328
  };
230
329
  }
231
330
  function formatHealthReport(report) {
package/dist/index.d.ts CHANGED
@@ -97,7 +97,7 @@ export type { DebugLogEntry, DebugLogFile, DebugLogLevel } from './parsers/debug
97
97
  export { OpenCodeDatabase } from './providers/openCodeDatabase';
98
98
  export { CodexDatabase } from './providers/codexDatabase';
99
99
  export { searchSessions } from './search/sessionSearch';
100
- export type { SearchResult } from './search/sessionSearch';
100
+ export type { SearchResult, SessionSearchOptions } from './search/sessionSearch';
101
101
  export { FilterEngine } from './search/advancedFilter';
102
102
  export type { FilterMode, FilterState, HighlightFormat as FilterHighlightFormat, } from './search/advancedFilter';
103
103
  export { composeContext } from './context/composer';
@@ -233,7 +233,7 @@ export { quotaHistoryRuntimeProviderSchema, quotaHistorySampleSchema, quotaHisto
233
233
  export { activeProviderAccountStatusSchema, activeAccountStatusSchema, } from './schemas/accountStatus';
234
234
  export { accountProviderIdSchema, accountManagerResultSchema, beginAccountLoginResultSchema, accountLoginStatusSchema, accountEntrySchema, savedAccountProfileSchema, listAllAccountsResultSchema, } from './schemas/accountManager';
235
235
  export { assistantTurnEventSchema, assistantTurnEventTypeSchema, assistantTurnNarrationStepSchema, assistantTurnProcessSchema, assistantTurnProcessStepSchema, assistantTurnProjectionSchema, assistantTurnReasoningTimelineItemSchema, assistantTurnSubagentSchema, assistantTurnSubagentStatusSchema, assistantTurnTimelineItemSchema, assistantTurnToolGroupStepSchema, assistantTurnToolRefSchema, } from './schemas/assistantTurn';
236
- export { fetchProviderStatus, fetchOpenAIStatus } from './providerStatus';
236
+ export { fetchProviderStatus, fetchOpenAIStatus, toLegacyProviderStatus } from './providerStatus';
237
237
  export type { ProviderStatusState } from './providerStatus';
238
238
  export { formatHealthReport, getSessionDiagnostics, runDoctor } from './doctor';
239
239
  export type { DeprecatedSetting, DoctorOptions, HealthCheck, HealthCheckStatus, HealthReport, SessionDiagnostics, } from './doctor';
@@ -241,3 +241,7 @@ export { _resetPeakHoursCache, createPeakHoursNotApplicableState, DEFAULT_PEAK_H
241
241
  export type { FetchPeakHoursOptions, PeakHoursState } from './peakHours';
242
242
  export { FAILING_TOOL_TREND_ARROWS, failingToolTrend, mergeFailingToolWindows, } from './failingTools';
243
243
  export type { FailingToolTrend, FailingToolTrendRow, FailingToolWindow } from './failingTools';
244
+ export { diagnoseProviderFailure } from './providerFailure';
245
+ export type { ProviderCredentialKind, ProviderAuthenticationEvidence, ProviderFailureInput, ProviderFailureCode, ProviderRecoveryAction, ProviderRetryAfter, ProviderFailureEvidence, ProviderFailureDiagnosis, } from './providerFailure';
246
+ export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
247
+ export { fetchProviderServiceStatus } from './providerServiceStatus';
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ exports.finalizeAccountLogin = exports.getAccountLoginStatusAsync = exports.getA
11
11
  exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.isShellHookInstalled = exports.uninstallShellHook = exports.installShellHook = exports.setTerminalActiveProfile = exports.removeCodexAccount = exports.switchToCodexAccountAsync = exports.switchToCodexAccount = exports.finalizeCodexAccountAsync = exports.finalizeCodexAccount = exports.prepareCodexAccountAsync = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.onAccountsChanged = exports.getActiveAccountStatus = exports.ACCOUNT_PROVIDER_IDS = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.switchAccountAsync = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLoginAsync = void 0;
12
12
  exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = exports.selectStatuslineAccount = exports.formatStatusline = exports.estimateTimeToQuota = exports.BurnRateCalculator = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.MultiProviderQuotaService = exports.resolveZaiQuota = exports.readZaiCredentials = exports.quotaStateFromZaiQuotaLimitPayload = exports.fetchZaiQuotaFromApi = exports.CodexQuotaWatcher = exports.resolveCodexQuotaFromLocalSources = exports.resolveCodexQuota = exports.readLatestCodexQuotaFromRollouts = exports.quotaFromCodexRateLimits = exports.fetchCodexQuotaFromApi = exports.fetchCodexResetCreditsFromApi = exports.getWorkspaceIdFromPath = exports.pruneQuotaHistory = exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.quotaFromStatuslinePayload = exports.parseClaudeStatuslinePayload = exports.evaluateQuotaThresholds = exports.describeQuotaThresholdAlert = exports.DEFAULT_QUOTA_THRESHOLDS = exports.QUOTA_FRESH_MAX_AGE_MS = exports.QUOTA_AGING_MAX_AGE_MS = exports.formatQuotaAge = exports.classifyQuotaFreshness = exports.resolveQuota = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.QUOTA_PROVIDER_IDS = void 0;
13
13
  exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.ToolCallTracker = exports.extractToolCalls = exports.extractToolCall = exports.extractErrorMessage = exports.categorizeError = exports.gatherAssetsForCwd = exports.codexSessions = exports.readCodexAssets = exports.claudeSessions = exports.readClaudeAssets = exports.extractCommands = exports.extractFilePaths = exports.extractUrls = exports.extractTokenUsage = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.MODEL_PROVIDER_IDS = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = void 0;
14
- exports.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.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;
14
+ exports.fetchProviderServiceStatus = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.scopePeakHoursToSessionProvider = exports.PEAK_HOURS_DESCRIPTION = exports.PEAK_HOURS_CACHE_MS = exports.isClaudeCodeSessionProvider = exports.getScheduledPeakHoursState = exports.fetchPeakHoursStatus = exports.DEFAULT_PEAK_HOURS_TIMEOUT_MS = exports.createPeakHoursNotApplicableState = exports._resetPeakHoursCache = exports.runDoctor = exports.getSessionDiagnostics = exports.formatHealthReport = exports.toLegacyProviderStatus = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = void 0;
15
15
  var usageNormalization_1 = require("./usageNormalization");
16
16
  Object.defineProperty(exports, "normalizeProviderUsage", { enumerable: true, get: function () { return usageNormalization_1.normalizeProviderUsage; } });
17
17
  Object.defineProperty(exports, "extractNormalizedUsage", { enumerable: true, get: function () { return usageNormalization_1.extractNormalizedUsage; } });
@@ -615,6 +615,7 @@ Object.defineProperty(exports, "assistantTurnToolRefSchema", { enumerable: true,
615
615
  var providerStatus_1 = require("./providerStatus");
616
616
  Object.defineProperty(exports, "fetchProviderStatus", { enumerable: true, get: function () { return providerStatus_1.fetchProviderStatus; } });
617
617
  Object.defineProperty(exports, "fetchOpenAIStatus", { enumerable: true, get: function () { return providerStatus_1.fetchOpenAIStatus; } });
618
+ Object.defineProperty(exports, "toLegacyProviderStatus", { enumerable: true, get: function () { return providerStatus_1.toLegacyProviderStatus; } });
618
619
  // Shared diagnostics / health report
619
620
  var doctor_1 = require("./doctor");
620
621
  Object.defineProperty(exports, "formatHealthReport", { enumerable: true, get: function () { return doctor_1.formatHealthReport; } });
@@ -635,3 +636,7 @@ var failingTools_1 = require("./failingTools");
635
636
  Object.defineProperty(exports, "FAILING_TOOL_TREND_ARROWS", { enumerable: true, get: function () { return failingTools_1.FAILING_TOOL_TREND_ARROWS; } });
636
637
  Object.defineProperty(exports, "failingToolTrend", { enumerable: true, get: function () { return failingTools_1.failingToolTrend; } });
637
638
  Object.defineProperty(exports, "mergeFailingToolWindows", { enumerable: true, get: function () { return failingTools_1.mergeFailingToolWindows; } });
639
+ var providerFailure_1 = require("./providerFailure");
640
+ Object.defineProperty(exports, "diagnoseProviderFailure", { enumerable: true, get: function () { return providerFailure_1.diagnoseProviderFailure; } });
641
+ var providerServiceStatus_1 = require("./providerServiceStatus");
642
+ Object.defineProperty(exports, "fetchProviderServiceStatus", { enumerable: true, get: function () { return providerServiceStatus_1.fetchProviderServiceStatus; } });
package/dist/node.d.ts CHANGED
@@ -38,3 +38,5 @@ export { listSessionPreviews, listSessionPreviewsAsync, readSessionPreview, read
38
38
  export type { AsyncSessionPreviewOptions, ListSessionPreviewsAsyncOptions, ListSessionPreviewsOptions, ReadSessionPreviewAsyncOptions, ReadSessionPreviewOptions, SessionPreview, SessionPreviewListResult, SessionPreviewReadResult, } from './sessionPreviews';
39
39
  export { ObservedSessionCollector, observedSessionSourceFromProvider, fileFingerprint, fileFingerprintParts, } from './observedSessionCollector';
40
40
  export type { KnownObservedSessionFingerprint, ObservedSessionChange, ObservedSessionChangeBatch, ObservedSessionChangeType, ObservedSessionReference, ObservedSessionFingerprintParts, ObservedSessionSourceSubscribeOptions, ObservedSessionSubscribeOptions, ObservedSessionCollectionSource, ProviderObservedSessionCollectionSource, ObservedSessionDiagnosticKind, ObservedSessionDiagnosticPhase, ObservedSessionDiagnosticSeverity, ObservedSessionDiagnostic, ObservedSessionCollection, ObservedSessionCollectorOptions, } from './observedSessionCollector';
41
+ export type { ProviderServiceSeverity, ProviderServiceComponent, ProviderServiceIncident, ProviderServiceStatusFailureReason, ObservedProviderServiceStatus, UnavailableProviderServiceStatus, ProviderServiceStatus, FetchProviderServiceStatusOptions, } from './providerServiceStatusTypes';
42
+ export { fetchProviderServiceStatus } from './providerServiceStatus';
package/dist/node.js CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.readSessionPreviewAsync = exports.readSessionPreview = exports.listSessionPreviewsAsync = exports.listSessionPreviews = exports.readCodexHistory = exports.walkRolloutFilesAsync = exports.walkRolloutFiles = exports.findCodexRolloutFile = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.importSessionHistory = exports.ACTIVE_SESSION_MTIME_THRESHOLD_MS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.pruneUsageCache = exports.getUsageCacheDir = exports.collectUsageEvents = exports.USAGE_CACHE_VERSION = exports.MAX_USAGE_CACHE_FILES = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.writeStateFile = exports.readStateFile = exports.quotaToStateFile = exports.getStateFilePath = exports.billingBlockToStateFile = exports.STATE_FILE_SCHEMA_VERSION = exports.STATE_FILE_NAME = exports.sessionFingerprintParts = exports.fingerprintString = exports.readSessionReportInputs = exports.readSessionFileStats = exports.providerContextSizeFn = exports.firstUserPrompt = exports.computeSessionFileStats = exports.readSessionTranscript = exports.listRecentSessions = exports.getObservedContextWindowPath = exports.recordObservedContextWindow = exports.loadObservedContextWindows = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmContextWindows = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = void 0;
11
- exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = void 0;
11
+ exports.fetchProviderServiceStatus = exports.fileFingerprintParts = exports.fileFingerprint = exports.observedSessionSourceFromProvider = exports.ObservedSessionCollector = void 0;
12
12
  var pricingCatalog_1 = require("./pricingCatalog");
13
13
  Object.defineProperty(exports, "hydratePricingCatalog", { enumerable: true, get: function () { return pricingCatalog_1.hydratePricingCatalog; } });
14
14
  Object.defineProperty(exports, "normalizeLiteLlmCatalog", { enumerable: true, get: function () { return pricingCatalog_1.normalizeLiteLlmCatalog; } });
@@ -80,3 +80,5 @@ Object.defineProperty(exports, "ObservedSessionCollector", { enumerable: true, g
80
80
  Object.defineProperty(exports, "observedSessionSourceFromProvider", { enumerable: true, get: function () { return observedSessionCollector_1.observedSessionSourceFromProvider; } });
81
81
  Object.defineProperty(exports, "fileFingerprint", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprint; } });
82
82
  Object.defineProperty(exports, "fileFingerprintParts", { enumerable: true, get: function () { return observedSessionCollector_1.fileFingerprintParts; } });
83
+ var providerServiceStatus_1 = require("./providerServiceStatus");
84
+ Object.defineProperty(exports, "fetchProviderServiceStatus", { enumerable: true, get: function () { return providerServiceStatus_1.fetchProviderServiceStatus; } });