codex-multi-auth 2.17.3 → 2.19.0
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/.codex-plugin/plugin.json +1 -1
- package/README.md +10 -4
- package/config/README.md +1 -1
- package/config/codex-legacy.json +12 -212
- package/config/codex-modern.json +4 -80
- package/config/minimal-codex.json +1 -1
- package/dist/lib/account-policy.d.ts +3 -1
- package/dist/lib/account-policy.js +21 -5
- package/dist/lib/codex-manager/commands/history.js +3 -1
- package/dist/lib/codex-manager/commands/status.js +8 -3
- package/dist/lib/codex-manager/formatters/subscription-status.d.ts +16 -0
- package/dist/lib/codex-manager/formatters/subscription-status.js +69 -0
- package/dist/lib/codex-manager/health-check.js +17 -12
- package/dist/lib/codex-manager/quota-cache-helpers.js +8 -4
- package/dist/lib/context-budget/model-context-windows.d.ts +1 -1
- package/dist/lib/context-budget/model-context-windows.js +10 -13
- package/dist/lib/model-route-policy.d.ts +1 -1
- package/dist/lib/oc-chatgpt-target-detection.d.ts +3 -2
- package/dist/lib/oc-chatgpt-target-detection.js +40 -13
- package/dist/lib/quota-cache.d.ts +6 -0
- package/dist/lib/quota-cache.js +33 -16
- package/dist/lib/quota-probe.d.ts +3 -0
- package/dist/lib/quota-probe.js +5 -4
- package/dist/lib/quota-readiness.d.ts +1 -1
- package/dist/lib/quota-readiness.js +6 -2
- package/dist/lib/request/error-classification.js +41 -52
- package/dist/lib/request/fetch-helpers.js +1 -1
- package/dist/lib/request/helpers/model-map.d.ts +2 -2
- package/dist/lib/request/helpers/model-map.js +120 -78
- package/dist/lib/request/request-transformer.d.ts +1 -1
- package/dist/lib/request/request-transformer.js +1 -1
- package/dist/lib/runtime/account-model-catalog.d.ts +1 -1
- package/dist/lib/runtime/model-discovery-status.d.ts +2 -2
- package/dist/lib/runtime/subscription-first-use.js +1 -1
- package/dist/lib/ui/ui-copy.d.ts +1 -1
- package/dist/lib/ui/ui-copy.js +1 -1
- package/dist/lib/usage/pricing.d.ts +1 -1
- package/dist/lib/usage/pricing.js +41 -16
- package/package.json +2 -2
- package/scripts/codex.js +167 -85
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/account-policy.d.ts.map +0 -1
- package/dist/lib/accounts/rate-limits.d.ts.map +0 -1
- package/dist/lib/accounts.d.ts.map +0 -1
- package/dist/lib/api-route-store.d.ts.map +0 -1
- package/dist/lib/audit.d.ts.map +0 -1
- package/dist/lib/auth/account-access.d.ts.map +0 -1
- package/dist/lib/auth/auth.d.ts.map +0 -1
- package/dist/lib/auth/browser.d.ts.map +0 -1
- package/dist/lib/auth/callback-guidance.d.ts.map +0 -1
- package/dist/lib/auth/device-auth.d.ts.map +0 -1
- package/dist/lib/auth/index.d.ts.map +0 -1
- package/dist/lib/auth/org-override.d.ts.map +0 -1
- package/dist/lib/auth/server.d.ts.map +0 -1
- package/dist/lib/auth/token-utils.d.ts.map +0 -1
- package/dist/lib/auth-rate-limit.d.ts.map +0 -1
- package/dist/lib/budget-guard.d.ts.map +0 -1
- package/dist/lib/capability-policy.d.ts.map +0 -1
- package/dist/lib/circuit-breaker.d.ts.map +0 -1
- package/dist/lib/cli.d.ts.map +0 -1
- package/dist/lib/codex-cli/index.d.ts.map +0 -1
- package/dist/lib/codex-cli/observability.d.ts.map +0 -1
- package/dist/lib/codex-cli/state.d.ts.map +0 -1
- package/dist/lib/codex-cli/sync.d.ts.map +0 -1
- package/dist/lib/codex-cli/writer.d.ts.map +0 -1
- package/dist/lib/codex-manager/account-credentials.d.ts.map +0 -1
- package/dist/lib/codex-manager/account-manager-commands.d.ts.map +0 -1
- package/dist/lib/codex-manager/account-pool-write.d.ts.map +0 -1
- package/dist/lib/codex-manager/api-login-menu.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-category-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-category-helpers.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-category-prompt.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-settings-controller.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-settings-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-settings-helpers.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-settings-prompt.d.ts.map +0 -1
- package/dist/lib/codex-manager/backend-settings-schema.d.ts.map +0 -1
- package/dist/lib/codex-manager/behavior-settings-panel.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/account.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/best.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/bridge.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/budget.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/check.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/config-explain.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/debug-bundle.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/history.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/init-config.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/integrations.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/limits.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/models.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/monitor.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/report.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/resets.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/status.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/switch.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/uninstall.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/unpin.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/usage.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/verify.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/why-selected.d.ts.map +0 -1
- package/dist/lib/codex-manager/commands/workspace.d.ts.map +0 -1
- package/dist/lib/codex-manager/dashboard-display-panel.d.ts.map +0 -1
- package/dist/lib/codex-manager/dashboard-formatters.d.ts.map +0 -1
- package/dist/lib/codex-manager/dashboard-settings-controller.d.ts.map +0 -1
- package/dist/lib/codex-manager/dashboard-settings-data.d.ts.map +0 -1
- package/dist/lib/codex-manager/dashboard-settings-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager/experimental-settings-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager/experimental-settings-prompt.d.ts.map +0 -1
- package/dist/lib/codex-manager/experimental-settings-schema.d.ts.map +0 -1
- package/dist/lib/codex-manager/experimental-sync-target-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager/experimental-sync-target.d.ts.map +0 -1
- package/dist/lib/codex-manager/forecast-report-shared.d.ts.map +0 -1
- package/dist/lib/codex-manager/formatters/account-formatters.d.ts.map +0 -1
- package/dist/lib/codex-manager/formatters/index.d.ts.map +0 -1
- package/dist/lib/codex-manager/formatters/model-formatters.d.ts.map +0 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +0 -1
- package/dist/lib/codex-manager/formatters/text-style.d.ts.map +0 -1
- package/dist/lib/codex-manager/health-check.d.ts.map +0 -1
- package/dist/lib/codex-manager/help.d.ts.map +0 -1
- package/dist/lib/codex-manager/login-action-panel.d.ts.map +0 -1
- package/dist/lib/codex-manager/login-flow.d.ts.map +0 -1
- package/dist/lib/codex-manager/login-menu-actions.d.ts.map +0 -1
- package/dist/lib/codex-manager/login-menu-data.d.ts.map +0 -1
- package/dist/lib/codex-manager/login-oauth.d.ts.map +0 -1
- package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +0 -1
- package/dist/lib/codex-manager/manual-callback.d.ts.map +0 -1
- package/dist/lib/codex-manager/persist-selected-account.d.ts.map +0 -1
- package/dist/lib/codex-manager/quota-cache-helpers.d.ts.map +0 -1
- package/dist/lib/codex-manager/rate-limit-markers.d.ts.map +0 -1
- package/dist/lib/codex-manager/repair-commands.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub/backend.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub/dashboard.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub/experimental.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub/index.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub/shared.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub-menu.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub-prompt.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-hub.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-panels.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-persist-utils.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-preview.d.ts.map +0 -1
- package/dist/lib/codex-manager/settings-write-queue.d.ts.map +0 -1
- package/dist/lib/codex-manager/statusline-settings-panel.d.ts.map +0 -1
- package/dist/lib/codex-manager/theme-settings-panel.d.ts.map +0 -1
- package/dist/lib/codex-manager/unified-settings-controller.d.ts.map +0 -1
- package/dist/lib/codex-manager/unified-settings-entry.d.ts.map +0 -1
- package/dist/lib/codex-manager.d.ts.map +0 -1
- package/dist/lib/concurrency.d.ts.map +0 -1
- package/dist/lib/config-schema.d.ts.map +0 -1
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/constants.d.ts.map +0 -1
- package/dist/lib/context-budget/model-context-windows.d.ts.map +0 -1
- package/dist/lib/context-budget-guard.d.ts.map +0 -1
- package/dist/lib/context-budget-response.d.ts.map +0 -1
- package/dist/lib/context-overflow.d.ts.map +0 -1
- package/dist/lib/dashboard-settings.d.ts.map +0 -1
- package/dist/lib/entitlement-cache.d.ts.map +0 -1
- package/dist/lib/env-parsing.d.ts.map +0 -1
- package/dist/lib/errors.d.ts.map +0 -1
- package/dist/lib/forecast.d.ts.map +0 -1
- package/dist/lib/fs-retry.d.ts.map +0 -1
- package/dist/lib/health.d.ts.map +0 -1
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/integration-generators.d.ts.map +0 -1
- package/dist/lib/live-account-sync.d.ts.map +0 -1
- package/dist/lib/local-bridge.d.ts.map +0 -1
- package/dist/lib/local-client-tokens.d.ts.map +0 -1
- package/dist/lib/logger.d.ts.map +0 -1
- package/dist/lib/model-capability-matrix.d.ts.map +0 -1
- package/dist/lib/model-route-policy.d.ts.map +0 -1
- package/dist/lib/named-backup-export.d.ts.map +0 -1
- package/dist/lib/oc-chatgpt-import-adapter.d.ts.map +0 -1
- package/dist/lib/oc-chatgpt-orchestrator.d.ts.map +0 -1
- package/dist/lib/oc-chatgpt-target-detection.d.ts.map +0 -1
- package/dist/lib/parallel-probe.d.ts.map +0 -1
- package/dist/lib/policy/runtime-policy.d.ts.map +0 -1
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +0 -1
- package/dist/lib/proactive-refresh.d.ts.map +0 -1
- package/dist/lib/prompts/codex-host-bridge.d.ts.map +0 -1
- package/dist/lib/prompts/codex.d.ts.map +0 -1
- package/dist/lib/prompts/fetch-utils.d.ts.map +0 -1
- package/dist/lib/prompts/host-codex-prompt.d.ts.map +0 -1
- package/dist/lib/quota-cache.d.ts.map +0 -1
- package/dist/lib/quota-probe.d.ts.map +0 -1
- package/dist/lib/quota-readiness.d.ts.map +0 -1
- package/dist/lib/recovery/constants.d.ts.map +0 -1
- package/dist/lib/recovery/storage.d.ts.map +0 -1
- package/dist/lib/recovery/types.d.ts.map +0 -1
- package/dist/lib/recovery.d.ts.map +0 -1
- package/dist/lib/redaction.d.ts.map +0 -1
- package/dist/lib/refresh-guardian.d.ts.map +0 -1
- package/dist/lib/refresh-lease.d.ts.map +0 -1
- package/dist/lib/refresh-queue.d.ts.map +0 -1
- package/dist/lib/request/client-cancellation.d.ts.map +0 -1
- package/dist/lib/request/error-classification.d.ts.map +0 -1
- package/dist/lib/request/failover-config.d.ts.map +0 -1
- package/dist/lib/request/failure-policy.d.ts.map +0 -1
- package/dist/lib/request/fetch-helpers.d.ts.map +0 -1
- package/dist/lib/request/headers.d.ts.map +0 -1
- package/dist/lib/request/helpers/input-utils.d.ts.map +0 -1
- package/dist/lib/request/helpers/model-map.d.ts.map +0 -1
- package/dist/lib/request/helpers/tool-utils.d.ts.map +0 -1
- package/dist/lib/request/index.d.ts.map +0 -1
- package/dist/lib/request/rate-limit-backoff.d.ts.map +0 -1
- package/dist/lib/request/rate-limit-decision.d.ts.map +0 -1
- package/dist/lib/request/request-attempt-budget.d.ts.map +0 -1
- package/dist/lib/request/request-init.d.ts.map +0 -1
- package/dist/lib/request/request-resilience.d.ts.map +0 -1
- package/dist/lib/request/request-transformer.d.ts.map +0 -1
- package/dist/lib/request/response-compaction.d.ts.map +0 -1
- package/dist/lib/request/response-handler.d.ts.map +0 -1
- package/dist/lib/request/response-metadata.d.ts.map +0 -1
- package/dist/lib/request/response-outcome.d.ts.map +0 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +0 -1
- package/dist/lib/request/stream-failover.d.ts.map +0 -1
- package/dist/lib/request/token-refresh.d.ts.map +0 -1
- package/dist/lib/request/url-rewriting.d.ts.map +0 -1
- package/dist/lib/request/wait-utils.d.ts.map +0 -1
- package/dist/lib/rotation.d.ts.map +0 -1
- package/dist/lib/routing-mutex.d.ts.map +0 -1
- package/dist/lib/routing-profiles.d.ts.map +0 -1
- package/dist/lib/runtime/account-check-helpers.d.ts.map +0 -1
- package/dist/lib/runtime/account-check-types.d.ts.map +0 -1
- package/dist/lib/runtime/account-check.d.ts.map +0 -1
- package/dist/lib/runtime/account-manager-cache-entry.d.ts.map +0 -1
- package/dist/lib/runtime/account-manager-cache.d.ts.map +0 -1
- package/dist/lib/runtime/account-model-catalog.d.ts.map +0 -1
- package/dist/lib/runtime/account-pool.d.ts.map +0 -1
- package/dist/lib/runtime/account-reset-credits.d.ts.map +0 -1
- package/dist/lib/runtime/account-scope.d.ts.map +0 -1
- package/dist/lib/runtime/account-select-event.d.ts.map +0 -1
- package/dist/lib/runtime/account-selection.d.ts.map +0 -1
- package/dist/lib/runtime/account-state.d.ts.map +0 -1
- package/dist/lib/runtime/account-status.d.ts.map +0 -1
- package/dist/lib/runtime/account-storage-scope-entry.d.ts.map +0 -1
- package/dist/lib/runtime/api-model-capabilities.d.ts.map +0 -1
- package/dist/lib/runtime/api-model-runtime.d.ts.map +0 -1
- package/dist/lib/runtime/app-bind.d.ts.map +0 -1
- package/dist/lib/runtime/app-helper-selection.d.ts.map +0 -1
- package/dist/lib/runtime/auth-facade.d.ts.map +0 -1
- package/dist/lib/runtime/automatic-account-checks.d.ts.map +0 -1
- package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +0 -1
- package/dist/lib/runtime/browser-oauth-flow.d.ts.map +0 -1
- package/dist/lib/runtime/capability-boost.d.ts.map +0 -1
- package/dist/lib/runtime/catalog-capabilities.d.ts.map +0 -1
- package/dist/lib/runtime/config-toml.d.ts.map +0 -1
- package/dist/lib/runtime/context-budget-settings.d.ts.map +0 -1
- package/dist/lib/runtime/event-handler.d.ts.map +0 -1
- package/dist/lib/runtime/first-run.d.ts.map +0 -1
- package/dist/lib/runtime/flagged-verify-types.d.ts.map +0 -1
- package/dist/lib/runtime/hydrate-emails.d.ts.map +0 -1
- package/dist/lib/runtime/inference-activity.d.ts.map +0 -1
- package/dist/lib/runtime/live-sync-entry.d.ts.map +0 -1
- package/dist/lib/runtime/live-sync.d.ts.map +0 -1
- package/dist/lib/runtime/loader-setup.d.ts.map +0 -1
- package/dist/lib/runtime/login-menu-accounts.d.ts.map +0 -1
- package/dist/lib/runtime/manual-oauth-flow.d.ts.map +0 -1
- package/dist/lib/runtime/model-discovery-status.d.ts.map +0 -1
- package/dist/lib/runtime/native-account-storage.d.ts.map +0 -1
- package/dist/lib/runtime/native-account-sync.d.ts.map +0 -1
- package/dist/lib/runtime/native-binding-lock.d.ts.map +0 -1
- package/dist/lib/runtime/native-client-auth.d.ts.map +0 -1
- package/dist/lib/runtime/native-provider-config.d.ts.map +0 -1
- package/dist/lib/runtime/native-rate-limits.d.ts.map +0 -1
- package/dist/lib/runtime/preemptive-quota.d.ts.map +0 -1
- package/dist/lib/runtime/quota-headers.d.ts.map +0 -1
- package/dist/lib/runtime/quota-probe.d.ts.map +0 -1
- package/dist/lib/runtime/quota-settings.d.ts.map +0 -1
- package/dist/lib/runtime/refresh-guardian-entry.d.ts.map +0 -1
- package/dist/lib/runtime/refresh-guardian.d.ts.map +0 -1
- package/dist/lib/runtime/request-init.d.ts.map +0 -1
- package/dist/lib/runtime/reset-credit-routing.d.ts.map +0 -1
- package/dist/lib/runtime/reset-credits.d.ts.map +0 -1
- package/dist/lib/runtime/response-output-history.d.ts.map +0 -1
- package/dist/lib/runtime/responses-websocket.d.ts.map +0 -1
- package/dist/lib/runtime/resume-picker.d.ts.map +0 -1
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +0 -1
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +0 -1
- package/dist/lib/runtime/rotation-server-types.d.ts.map +0 -1
- package/dist/lib/runtime/rotation-storage-meta.d.ts.map +0 -1
- package/dist/lib/runtime/rotation-token-refresh.d.ts.map +0 -1
- package/dist/lib/runtime/runtime-capability-failures.d.ts.map +0 -1
- package/dist/lib/runtime/runtime-current-account.d.ts.map +0 -1
- package/dist/lib/runtime/runtime-observability.d.ts.map +0 -1
- package/dist/lib/runtime/runtime-services.d.ts.map +0 -1
- package/dist/lib/runtime/session-affinity-entry.d.ts.map +0 -1
- package/dist/lib/runtime/session-recovery.d.ts.map +0 -1
- package/dist/lib/runtime/status-marker.d.ts.map +0 -1
- package/dist/lib/runtime/storage-scope.d.ts.map +0 -1
- package/dist/lib/runtime/subscription-first-use.d.ts.map +0 -1
- package/dist/lib/runtime/subscription-quota-event.d.ts.map +0 -1
- package/dist/lib/runtime/subscription-quota-order.d.ts.map +0 -1
- package/dist/lib/runtime/toast.d.ts.map +0 -1
- package/dist/lib/runtime/ui-runtime-entry.d.ts.map +0 -1
- package/dist/lib/runtime/ui-runtime.d.ts.map +0 -1
- package/dist/lib/runtime/verify-flagged.d.ts.map +0 -1
- package/dist/lib/runtime/workspace-model-scopes.d.ts.map +0 -1
- package/dist/lib/runtime-constants.d.ts.map +0 -1
- package/dist/lib/runtime-paths.d.ts.map +0 -1
- package/dist/lib/runtime-rotation-proxy.d.ts.map +0 -1
- package/dist/lib/schemas.d.ts.map +0 -1
- package/dist/lib/session-affinity.d.ts.map +0 -1
- package/dist/lib/shutdown.d.ts.map +0 -1
- package/dist/lib/storage/account-clear-entry.d.ts.map +0 -1
- package/dist/lib/storage/account-clear.d.ts.map +0 -1
- package/dist/lib/storage/account-match-utils.d.ts.map +0 -1
- package/dist/lib/storage/account-persistence.d.ts.map +0 -1
- package/dist/lib/storage/account-port.d.ts.map +0 -1
- package/dist/lib/storage/account-save-entry.d.ts.map +0 -1
- package/dist/lib/storage/account-save.d.ts.map +0 -1
- package/dist/lib/storage/account-snapshot.d.ts.map +0 -1
- package/dist/lib/storage/backup-metadata-builder.d.ts.map +0 -1
- package/dist/lib/storage/backup-metadata.d.ts.map +0 -1
- package/dist/lib/storage/backup-paths.d.ts.map +0 -1
- package/dist/lib/storage/backup-restore.d.ts.map +0 -1
- package/dist/lib/storage/cache-artifacts.d.ts.map +0 -1
- package/dist/lib/storage/credential-sidecars.d.ts.map +0 -1
- package/dist/lib/storage/error-hints.d.ts.map +0 -1
- package/dist/lib/storage/file-lock.d.ts.map +0 -1
- package/dist/lib/storage/file-paths.d.ts.map +0 -1
- package/dist/lib/storage/fixture-guards.d.ts.map +0 -1
- package/dist/lib/storage/flagged-entry.d.ts.map +0 -1
- package/dist/lib/storage/flagged-load-entry.d.ts.map +0 -1
- package/dist/lib/storage/flagged-save-entry.d.ts.map +0 -1
- package/dist/lib/storage/flagged-storage-file.d.ts.map +0 -1
- package/dist/lib/storage/flagged-storage-io.d.ts.map +0 -1
- package/dist/lib/storage/flagged-storage.d.ts.map +0 -1
- package/dist/lib/storage/gitignore.d.ts.map +0 -1
- package/dist/lib/storage/hash.d.ts.map +0 -1
- package/dist/lib/storage/health.d.ts.map +0 -1
- package/dist/lib/storage/identity.d.ts.map +0 -1
- package/dist/lib/storage/import-export.d.ts.map +0 -1
- package/dist/lib/storage/metadata-section.d.ts.map +0 -1
- package/dist/lib/storage/migrations.d.ts.map +0 -1
- package/dist/lib/storage/named-backup-entry.d.ts.map +0 -1
- package/dist/lib/storage/named-backups-entry.d.ts.map +0 -1
- package/dist/lib/storage/named-backups.d.ts.map +0 -1
- package/dist/lib/storage/path-state.d.ts.map +0 -1
- package/dist/lib/storage/paths.d.ts.map +0 -1
- package/dist/lib/storage/pending-auth.d.ts.map +0 -1
- package/dist/lib/storage/project-migration.d.ts.map +0 -1
- package/dist/lib/storage/public-types.d.ts.map +0 -1
- package/dist/lib/storage/record-identity.d.ts.map +0 -1
- package/dist/lib/storage/record-utils.d.ts.map +0 -1
- package/dist/lib/storage/restore-assessment.d.ts.map +0 -1
- package/dist/lib/storage/restore-backup-entry.d.ts.map +0 -1
- package/dist/lib/storage/restore-metadata.d.ts.map +0 -1
- package/dist/lib/storage/save-retry.d.ts.map +0 -1
- package/dist/lib/storage/snapshot-inspectors.d.ts.map +0 -1
- package/dist/lib/storage/snapshot-merge.d.ts.map +0 -1
- package/dist/lib/storage/storage-parser.d.ts.map +0 -1
- package/dist/lib/storage/transactions.d.ts.map +0 -1
- package/dist/lib/storage.d.ts.map +0 -1
- package/dist/lib/synthetic-response.d.ts.map +0 -1
- package/dist/lib/table-formatter.d.ts.map +0 -1
- package/dist/lib/temp-path.d.ts.map +0 -1
- package/dist/lib/tools/hashline-tools.d.ts.map +0 -1
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/ui/ansi.d.ts.map +0 -1
- package/dist/lib/ui/auth-menu-builder.d.ts.map +0 -1
- package/dist/lib/ui/auth-menu.d.ts.map +0 -1
- package/dist/lib/ui/check-progress.d.ts.map +0 -1
- package/dist/lib/ui/confirm.d.ts.map +0 -1
- package/dist/lib/ui/display-width.d.ts.map +0 -1
- package/dist/lib/ui/format.d.ts.map +0 -1
- package/dist/lib/ui/index.d.ts.map +0 -1
- package/dist/lib/ui/runtime.d.ts.map +0 -1
- package/dist/lib/ui/select.d.ts.map +0 -1
- package/dist/lib/ui/theme.d.ts.map +0 -1
- package/dist/lib/ui/ui-copy.d.ts.map +0 -1
- package/dist/lib/unified-settings.d.ts.map +0 -1
- package/dist/lib/update-notice.d.ts.map +0 -1
- package/dist/lib/usage/index.d.ts.map +0 -1
- package/dist/lib/usage/ledger.d.ts.map +0 -1
- package/dist/lib/usage/pricing.d.ts.map +0 -1
- package/dist/lib/usage/redaction.d.ts.map +0 -1
- package/dist/lib/usage/stream-usage-deferral.d.ts.map +0 -1
- package/dist/lib/usage/types.d.ts.map +0 -1
- package/dist/lib/usage/usage-extraction.d.ts.map +0 -1
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/wsl.d.ts.map +0 -1
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { subscriptionStatus, formatSubscriptionStatus } from "./formatters/subscription-status.js";
|
|
2
|
+
import { getAccountPolicyKey, loadAccountPolicyStore } from "../account-policy.js";
|
|
3
|
+
import { automaticCheckWorkspaceId } from "../runtime/automatic-account-checks.js";
|
|
1
4
|
import { refreshAndPrintResetCredits } from "../runtime/account-reset-credits.js";
|
|
2
5
|
import { mapWithConcurrency } from "../concurrency.js";
|
|
3
6
|
import { withCheckProgress } from "../ui/check-progress.js";
|
|
@@ -16,7 +19,7 @@ import { loadAccounts, saveAccounts, setStoragePath } from "../storage.js";
|
|
|
16
19
|
import { applyTokenAccountIdentity, hasLikelyInvalidRefreshToken, hasUsableAccessToken, } from "./account-credentials.js";
|
|
17
20
|
import { saveAccountsWithRetry } from "./forecast-report-shared.js";
|
|
18
21
|
import { formatModelInspection, formatQuotaSnapshotForDashboard, formatResultSummary, inspectRequestedModel, normalizeFailureDetail, styleAccountDetailText, stylePromptText, } from "./formatters/index.js";
|
|
19
|
-
import { cloneQuotaCacheData, DEFAULT_LIVE_PROBE_MODEL, pruneUnsafeQuotaEmailCacheEntry,
|
|
22
|
+
import { cloneQuotaCacheData, DEFAULT_LIVE_PROBE_MODEL, pruneUnsafeQuotaEmailCacheEntry, updateQuotaCacheForWorkspace, } from "./quota-cache-helpers.js";
|
|
20
23
|
function appendAuthInvalidationMarker(account, detail) {
|
|
21
24
|
return typeof account.authInvalidatedAt === "number" &&
|
|
22
25
|
Number.isFinite(account.authInvalidatedAt)
|
|
@@ -44,6 +47,8 @@ export async function runHealthCheck(options = {}) {
|
|
|
44
47
|
let quotaEmailFallbackState = liveProbe && quotaCache
|
|
45
48
|
? buildQuotaEmailFallbackState(storage.accounts)
|
|
46
49
|
: null;
|
|
50
|
+
const policies = await loadAccountPolicyStore({ strict: true }).catch(() => null);
|
|
51
|
+
const subscriptionLine = (account, snapshot) => formatSubscriptionStatus(subscriptionStatus(account, { ...snapshot, updatedAt: snapshot.observedAt ?? Date.now() }, policies ? policies.accounts[getAccountPolicyKey(account)] ?? {} : undefined, Date.now()));
|
|
47
52
|
let changed = false;
|
|
48
53
|
let ok = 0;
|
|
49
54
|
let failed = 0;
|
|
@@ -62,7 +67,7 @@ export async function runHealthCheck(options = {}) {
|
|
|
62
67
|
const quickProbes = new Map();
|
|
63
68
|
if (liveProbe && !forceRefresh) {
|
|
64
69
|
const candidates = storage.accounts.flatMap((account, index) => {
|
|
65
|
-
const accountId =
|
|
70
|
+
const accountId = automaticCheckWorkspaceId(account);
|
|
66
71
|
return hasUsableAccessToken(account, now) && account.accessToken && accountId
|
|
67
72
|
? [{ index, accountId, accessToken: account.accessToken }] : [];
|
|
68
73
|
});
|
|
@@ -104,14 +109,14 @@ export async function runHealthCheck(options = {}) {
|
|
|
104
109
|
if (liveProbe) {
|
|
105
110
|
const currentAccessToken = account.accessToken;
|
|
106
111
|
const probeAccountId = currentAccessToken
|
|
107
|
-
? (account
|
|
112
|
+
? automaticCheckWorkspaceId(account)
|
|
108
113
|
: undefined;
|
|
109
114
|
if (!probeAccountId || !currentAccessToken) {
|
|
110
115
|
warnings += 1;
|
|
111
116
|
signedInOnly += 1;
|
|
112
117
|
healthTone = "warning";
|
|
113
118
|
healthDetail =
|
|
114
|
-
"signed in (live check skipped: missing account ID)";
|
|
119
|
+
"signed in (live check skipped: missing account ID or unavailable selected workspace)";
|
|
115
120
|
}
|
|
116
121
|
else {
|
|
117
122
|
try {
|
|
@@ -124,10 +129,10 @@ export async function runHealthCheck(options = {}) {
|
|
|
124
129
|
model: modelInspection.normalized,
|
|
125
130
|
}), console.log);
|
|
126
131
|
if (workingQuotaCache) {
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
updateQuotaCacheForWorkspace(workingQuotaCache, account, probeAccountId, snapshot, storage.accounts);
|
|
133
|
+
quotaCacheChanged = true;
|
|
129
134
|
}
|
|
130
|
-
healthDetail = formatQuotaSnapshotForDashboard(snapshot, display);
|
|
135
|
+
healthDetail = formatQuotaSnapshotForDashboard(snapshot, display) + " | " + subscriptionLine(account, snapshot);
|
|
131
136
|
if (snapshot.primingFailure) {
|
|
132
137
|
healthTone = "warning";
|
|
133
138
|
warnings += 1;
|
|
@@ -210,13 +215,13 @@ export async function runHealthCheck(options = {}) {
|
|
|
210
215
|
let healthyMessage = "working now";
|
|
211
216
|
let healthyTone = "success";
|
|
212
217
|
if (liveProbe) {
|
|
213
|
-
const probeAccountId = account
|
|
218
|
+
const probeAccountId = automaticCheckWorkspaceId(account);
|
|
214
219
|
if (!probeAccountId) {
|
|
215
220
|
warnings += 1;
|
|
216
221
|
signedInOnly += 1;
|
|
217
222
|
healthyTone = "warning";
|
|
218
223
|
healthyMessage =
|
|
219
|
-
"signed in (live check skipped: missing account ID)";
|
|
224
|
+
"signed in (live check skipped: missing account ID or unavailable selected workspace)";
|
|
220
225
|
}
|
|
221
226
|
else {
|
|
222
227
|
try {
|
|
@@ -226,10 +231,10 @@ export async function runHealthCheck(options = {}) {
|
|
|
226
231
|
model: modelInspection.normalized,
|
|
227
232
|
}), console.log);
|
|
228
233
|
if (workingQuotaCache) {
|
|
229
|
-
|
|
230
|
-
|
|
234
|
+
updateQuotaCacheForWorkspace(workingQuotaCache, account, probeAccountId, snapshot, storage.accounts);
|
|
235
|
+
quotaCacheChanged = true;
|
|
231
236
|
}
|
|
232
|
-
healthyMessage = formatQuotaSnapshotForDashboard(snapshot, display);
|
|
237
|
+
healthyMessage = formatQuotaSnapshotForDashboard(snapshot, display) + " | " + subscriptionLine(account, snapshot);
|
|
233
238
|
if (snapshot.primingFailure) {
|
|
234
239
|
healthyTone = "warning";
|
|
235
240
|
warnings += 1;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { buildQuotaEmailFallbackState, findQuotaCacheEntryForAccount, quotaWorkspaceKey, hasSafeQuotaEmailFallback, hasUniqueQuotaAccountId, normalizeQuotaAccountId, normalizeQuotaEmail, } from "../quota-readiness.js";
|
|
2
|
+
import { mergeQuotaCacheEntry, } from "../quota-cache.js";
|
|
2
3
|
import { DEFAULT_MODEL, DEFAULT_PROBE_MODEL, } from "../request/helpers/model-map.js";
|
|
3
4
|
import { getRateLimitResetTimeForFamily } from "../runtime/account-status.js";
|
|
4
5
|
/**
|
|
@@ -41,7 +42,10 @@ export function getPersistedQuotaViewForAccount(cache, account, accounts, now, e
|
|
|
41
42
|
/** Retain only quota fields from a probe, never its credentials or response body. */
|
|
42
43
|
function quotaEntryFromSnapshot(snapshot) {
|
|
43
44
|
return {
|
|
44
|
-
|
|
45
|
+
...(snapshot.primingCompleted ? { primingCompleted: true } : {}),
|
|
46
|
+
...(snapshot.primingFailure ? { primingFailure: snapshot.primingFailure } : {}),
|
|
47
|
+
...(snapshot.primingCompleted || snapshot.primingFailure ? { primingObservedAt: snapshot.primingObservedAt ?? Date.now() } : {}),
|
|
48
|
+
updatedAt: snapshot.observedAt ?? Date.now(),
|
|
45
49
|
status: snapshot.status,
|
|
46
50
|
model: snapshot.model,
|
|
47
51
|
planType: snapshot.planType,
|
|
@@ -64,14 +68,14 @@ export function updateQuotaCacheForAccount(cache, account, snapshot, accounts, e
|
|
|
64
68
|
const accountId = normalizeQuotaAccountId(account.accountId);
|
|
65
69
|
const hasUniqueAccountId = accountId !== null && hasUniqueQuotaAccountId(accounts, account);
|
|
66
70
|
if (hasUniqueAccountId) {
|
|
67
|
-
cache.byAccountId[accountId] = nextEntry;
|
|
71
|
+
cache.byAccountId[accountId] = mergeQuotaCacheEntry(cache.byAccountId[accountId], nextEntry);
|
|
68
72
|
changed = true;
|
|
69
73
|
}
|
|
70
74
|
const email = normalizeQuotaEmail(account.email);
|
|
71
75
|
if (email &&
|
|
72
76
|
hasSafeQuotaEmailFallback(emailFallbackState, account) &&
|
|
73
77
|
!hasUniqueAccountId) {
|
|
74
|
-
cache.byEmail[email] = nextEntry;
|
|
78
|
+
cache.byEmail[email] = mergeQuotaCacheEntry(cache.byEmail[email], nextEntry);
|
|
75
79
|
changed = true;
|
|
76
80
|
}
|
|
77
81
|
else if (email && cache.byEmail[email]) {
|
|
@@ -86,7 +90,7 @@ export function updateQuotaCacheForWorkspace(cache, account, workspaceId, snapsh
|
|
|
86
90
|
if (!key)
|
|
87
91
|
return;
|
|
88
92
|
cache.byWorkspace ??= {};
|
|
89
|
-
cache.byWorkspace[key] = quotaEntryFromSnapshot(snapshot);
|
|
93
|
+
cache.byWorkspace[key] = mergeQuotaCacheEntry(cache.byWorkspace[key], quotaEntryFromSnapshot(snapshot));
|
|
90
94
|
if (workspaceId === normalizeQuotaAccountId(account.accountId)) {
|
|
91
95
|
updateQuotaCacheForAccount(cache, account, snapshot, accounts);
|
|
92
96
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* behavior (see the v2.5.0 release notes) closely enough to launch that no
|
|
7
7
|
* estimate here has been reviewed for it yet.
|
|
8
8
|
*/
|
|
9
|
-
export declare const UNESTIMATED_ROUTABLE_MODELS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-6-astra", "gpt-6-
|
|
9
|
+
export declare const UNESTIMATED_ROUTABLE_MODELS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-6.1-sol", "gpt-daybreak-blue-latest", "gpt-daybreak-red-latest"];
|
|
10
10
|
export interface EffectiveContextWindow {
|
|
11
11
|
tokens: number;
|
|
12
12
|
source: "override" | "estimate";
|
|
@@ -23,14 +23,11 @@ import { getNormalizedModel } from "../request/helpers/model-map.js";
|
|
|
23
23
|
* it to UNESTIMATED_ROUTABLE_MODELS instead.
|
|
24
24
|
*/
|
|
25
25
|
//
|
|
26
|
-
// Retired models (`gpt-5.1` through `gpt-5.
|
|
27
|
-
// models) are deliberately absent. Their ids now route to a
|
|
28
|
-
// estimating the window from the retired name would
|
|
29
|
-
// a model it no longer runs on.
|
|
30
|
-
const ESTIMATED_MODEL_CONTEXT_WINDOWS = {
|
|
31
|
-
"gpt-5.5": 260_000,
|
|
32
|
-
"gpt-5.5-pro": 260_000,
|
|
33
|
-
};
|
|
26
|
+
// Retired models (`gpt-5.1` through `gpt-5.5-pro`, `gpt-5-mini`/`nano`, the
|
|
27
|
+
// codex models) are deliberately absent. Their ids now route to a
|
|
28
|
+
// replacement, and estimating the window from the retired name would
|
|
29
|
+
// evaluate a request against a model it no longer runs on.
|
|
30
|
+
const ESTIMATED_MODEL_CONTEXT_WINDOWS = {};
|
|
34
31
|
/**
|
|
35
32
|
* Routable models this guard consciously does not estimate a window for.
|
|
36
33
|
* `getEffectiveContextWindow` returns `null` for these absent an override,
|
|
@@ -52,11 +49,11 @@ export const UNESTIMATED_ROUTABLE_MODELS = [
|
|
|
52
49
|
// measured ceiling for this transport, so it stays unestimated too. Set
|
|
53
50
|
// `contextBudgetGuardModelWindowOverrides` once you know your real ceiling.
|
|
54
51
|
"gpt-6-astra",
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
// catalog as Astra, so the same reasoning keeps them unestimated.
|
|
52
|
+
// Sol, Luna and 6.1 Sol carry the same 272K Codex / 872K max split in the
|
|
53
|
+
// upstream catalog as Astra, so the same reasoning keeps them unestimated.
|
|
58
54
|
"gpt-6-sol",
|
|
59
55
|
"gpt-6-luna",
|
|
56
|
+
"gpt-6.1-sol",
|
|
60
57
|
"gpt-daybreak-blue-latest",
|
|
61
58
|
"gpt-daybreak-red-latest",
|
|
62
59
|
];
|
|
@@ -79,8 +76,8 @@ function normalizeModelName(model) {
|
|
|
79
76
|
* the way they type the model still wins, then the catalog's canonical id for
|
|
80
77
|
* it. `getNormalizedModel` is deliberately the exact/alias-only resolver —
|
|
81
78
|
* `resolveNormalizedModel` falls back to `DEFAULT_MODEL` for anything it does
|
|
82
|
-
* not recognize, which would hand an unknown model
|
|
83
|
-
* evaluate a real session against a fabricated number.
|
|
79
|
+
* not recognize, which would hand an unknown model the default model's
|
|
80
|
+
* window and evaluate a real session against a fabricated number.
|
|
84
81
|
*/
|
|
85
82
|
function windowLookupCandidates(model) {
|
|
86
83
|
const raw = normalizeModelName(model);
|
|
@@ -44,7 +44,7 @@ export declare function modelEntitlements(model: RouteModel): {
|
|
|
44
44
|
reasoningLevels: string[];
|
|
45
45
|
accessPrograms: string[];
|
|
46
46
|
probes?: {
|
|
47
|
-
[k: string]: "
|
|
47
|
+
[k: string]: "unsupported" | "verified" | "unverified" | "downgraded";
|
|
48
48
|
} | undefined;
|
|
49
49
|
checkedAt?: number | undefined;
|
|
50
50
|
model: string;
|
|
@@ -35,7 +35,8 @@ export type OcChatgptTargetDetectionResult = OcChatgptTargetFound | OcChatgptTar
|
|
|
35
35
|
/**
|
|
36
36
|
* Detects the oc-chatgpt multi-auth storage target by evaluating explicit, canonical, and per-project candidate roots.
|
|
37
37
|
*
|
|
38
|
-
* Examines an explicit override (
|
|
38
|
+
* Examines an explicit override (OC_CODEX_MULTI_AUTH_DIR, the legacy OC_CHATGPT_MULTI_AUTH_DIR alias, or
|
|
39
|
+
* options.explicitRoot), the canonical user store (~/.opencode),
|
|
39
40
|
* and a per-project storage location (derived from options.projectRoot or the current working directory). For each candidate
|
|
40
41
|
* it checks for account artifacts and storage signals and returns a single resolved target, an ambiguity listing multiple
|
|
41
42
|
* matching candidates, or a "none" result with the attempted candidates. This function performs synchronous filesystem checks
|
|
@@ -45,7 +46,7 @@ export type OcChatgptTargetDetectionResult = OcChatgptTargetFound | OcChatgptTar
|
|
|
45
46
|
*
|
|
46
47
|
* @param options - Optional overrides:
|
|
47
48
|
* - explicitRoot: absolute path to force as the candidate root (use `null` to explicitly disable); if omitted the
|
|
48
|
-
*
|
|
49
|
+
* OC_CODEX_MULTI_AUTH_DIR environment variable is considered, then the legacy OC_CHATGPT_MULTI_AUTH_DIR alias.
|
|
49
50
|
* - projectRoot: explicit project root to derive per-project storage; if omitted the current working directory is used to
|
|
50
51
|
* discover the project root.
|
|
51
52
|
* @returns An OcChatgptTargetDetectionResult describing either a resolved `target` (with `descriptor` and a `resolution`
|
|
@@ -2,7 +2,14 @@ import { existsSync, readdirSync } from "node:fs";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join, normalize, relative, resolve, sep, win32 } from "node:path";
|
|
4
4
|
import { findProjectRoot, getProjectStorageKey, resolveProjectStorageIdentityRoot, } from "./storage/paths.js";
|
|
5
|
-
|
|
5
|
+
// The sibling plugin renamed its account file from `openai-codex-accounts.json`
|
|
6
|
+
// (oc-chatgpt-multi-auth era) to `oc-codex-multi-auth-accounts.json`; both are
|
|
7
|
+
// detected, preferring the current name when a root holds both.
|
|
8
|
+
const ACCOUNT_FILE_NAMES = [
|
|
9
|
+
"oc-codex-multi-auth-accounts.json",
|
|
10
|
+
"openai-codex-accounts.json",
|
|
11
|
+
];
|
|
12
|
+
const ACCOUNT_FILE_NAME = ACCOUNT_FILE_NAMES[0];
|
|
6
13
|
const BACKUPS_DIR_NAME = "backups";
|
|
7
14
|
const PROJECTS_DIR_NAME = "projects";
|
|
8
15
|
const CANONICAL_HOME_BASENAME = ".opencode";
|
|
@@ -107,17 +114,32 @@ function deduplicatePaths(paths) {
|
|
|
107
114
|
}
|
|
108
115
|
return result;
|
|
109
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns the path of the primary account file under `root`, preferring the
|
|
119
|
+
* current `oc-codex-multi-auth-accounts.json` name over the legacy
|
|
120
|
+
* `openai-codex-accounts.json` name when both exist, or `null` when neither
|
|
121
|
+
* file (nor its `.wal` sidecar) is present.
|
|
122
|
+
*/
|
|
123
|
+
function findPrimaryAccountPath(root) {
|
|
124
|
+
for (const name of ACCOUNT_FILE_NAMES) {
|
|
125
|
+
const accountPath = join(root, name);
|
|
126
|
+
if (existsSync(accountPath) || existsSync(`${accountPath}.wal`)) {
|
|
127
|
+
return accountPath;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
110
132
|
/**
|
|
111
133
|
* Detects whether an account file or rotated account artifacts exist under the specified storage root.
|
|
112
134
|
*
|
|
113
|
-
* Scans for
|
|
135
|
+
* Scans for an account file under either known name (`oc-codex-multi-auth-accounts.json` or the legacy `openai-codex-accounts.json`) and its WAL variant, rotated/archived files matching either account filename pattern (excluding `.tmp`, `.wal`, and names containing `.rotate.`), and the backups directory. The probe is tolerant of unreadable directories (errors are ignored) and does not read file contents. Callers should be aware of concurrent filesystem changes — a `false` result does not guarantee no artifact will appear shortly after. On Windows, filesystem matching should be considered case-insensitive by callers. This check does not expose or parse any token contents.
|
|
114
136
|
*
|
|
115
137
|
* @param root - Filesystem path of the storage root to probe
|
|
138
|
+
* @param primaryAccountPath - Result of `findPrimaryAccountPath(root)`, so callers resolve the descriptor path once
|
|
116
139
|
* @returns `true` if any account file or rotated account artifact exists under `root` or its backups directory, `false` otherwise.
|
|
117
140
|
*/
|
|
118
|
-
function hasAccountArtifacts(root) {
|
|
119
|
-
|
|
120
|
-
if (existsSync(accountPath) || existsSync(`${accountPath}.wal`)) {
|
|
141
|
+
function hasAccountArtifacts(root, primaryAccountPath) {
|
|
142
|
+
if (primaryAccountPath !== null) {
|
|
121
143
|
return true;
|
|
122
144
|
}
|
|
123
145
|
const hasRotated = (dir) => {
|
|
@@ -126,7 +148,7 @@ function hasAccountArtifacts(root) {
|
|
|
126
148
|
for (const entry of entries) {
|
|
127
149
|
if (!entry.isFile())
|
|
128
150
|
continue;
|
|
129
|
-
if (!entry.name.startsWith(`${
|
|
151
|
+
if (!ACCOUNT_FILE_NAMES.some((name) => entry.name.startsWith(`${name}.`)))
|
|
130
152
|
continue;
|
|
131
153
|
if (entry.name.endsWith(".tmp"))
|
|
132
154
|
continue;
|
|
@@ -146,7 +168,7 @@ function hasAccountArtifacts(root) {
|
|
|
146
168
|
return true;
|
|
147
169
|
}
|
|
148
170
|
const backupsDir = join(root, BACKUPS_DIR_NAME);
|
|
149
|
-
if (existsSync(join(backupsDir,
|
|
171
|
+
if (ACCOUNT_FILE_NAMES.some((name) => existsSync(join(backupsDir, name)))) {
|
|
150
172
|
return true;
|
|
151
173
|
}
|
|
152
174
|
if (hasRotated(backupsDir)) {
|
|
@@ -191,7 +213,8 @@ function inferScopeFromRoot(root, canonicalRoot) {
|
|
|
191
213
|
/**
|
|
192
214
|
* Detects the oc-chatgpt multi-auth storage target by evaluating explicit, canonical, and per-project candidate roots.
|
|
193
215
|
*
|
|
194
|
-
* Examines an explicit override (
|
|
216
|
+
* Examines an explicit override (OC_CODEX_MULTI_AUTH_DIR, the legacy OC_CHATGPT_MULTI_AUTH_DIR alias, or
|
|
217
|
+
* options.explicitRoot), the canonical user store (~/.opencode),
|
|
195
218
|
* and a per-project storage location (derived from options.projectRoot or the current working directory). For each candidate
|
|
196
219
|
* it checks for account artifacts and storage signals and returns a single resolved target, an ambiguity listing multiple
|
|
197
220
|
* matching candidates, or a "none" result with the attempted candidates. This function performs synchronous filesystem checks
|
|
@@ -201,14 +224,17 @@ function inferScopeFromRoot(root, canonicalRoot) {
|
|
|
201
224
|
*
|
|
202
225
|
* @param options - Optional overrides:
|
|
203
226
|
* - explicitRoot: absolute path to force as the candidate root (use `null` to explicitly disable); if omitted the
|
|
204
|
-
*
|
|
227
|
+
* OC_CODEX_MULTI_AUTH_DIR environment variable is considered, then the legacy OC_CHATGPT_MULTI_AUTH_DIR alias.
|
|
205
228
|
* - projectRoot: explicit project root to derive per-project storage; if omitted the current working directory is used to
|
|
206
229
|
* discover the project root.
|
|
207
230
|
* @returns An OcChatgptTargetDetectionResult describing either a resolved `target` (with `descriptor` and a `resolution`
|
|
208
231
|
* of `"accounts"` or `"signals"`), an `ambiguous` outcome listing conflicting candidates, or `none` with the tried candidates.
|
|
209
232
|
*/
|
|
210
233
|
export function detectOcChatgptMultiAuthTarget(options) {
|
|
211
|
-
const explicitFromEnv = (
|
|
234
|
+
const explicitFromEnv = (firstNonEmpty([
|
|
235
|
+
process.env.OC_CODEX_MULTI_AUTH_DIR,
|
|
236
|
+
process.env.OC_CHATGPT_MULTI_AUTH_DIR,
|
|
237
|
+
]) ?? "").trim();
|
|
212
238
|
const hasExplicitRootOption = options !== undefined && "explicitRoot" in options;
|
|
213
239
|
const explicitRoot = (hasExplicitRootOption ? (options.explicitRoot ?? "") : explicitFromEnv).trim();
|
|
214
240
|
const userHome = getResolvedUserHomeDir();
|
|
@@ -233,9 +259,10 @@ export function detectOcChatgptMultiAuthTarget(options) {
|
|
|
233
259
|
: inferredScope === "project"
|
|
234
260
|
? "project"
|
|
235
261
|
: "default-global";
|
|
236
|
-
const
|
|
262
|
+
const primaryAccountPath = findPrimaryAccountPath(root);
|
|
263
|
+
const accountPath = primaryAccountPath ?? join(root, ACCOUNT_FILE_NAME);
|
|
237
264
|
const backupRoot = join(root, BACKUPS_DIR_NAME);
|
|
238
|
-
const hasAccountArtifactsFlag = hasAccountArtifacts(root);
|
|
265
|
+
const hasAccountArtifactsFlag = hasAccountArtifacts(root, primaryAccountPath);
|
|
239
266
|
return {
|
|
240
267
|
scope: inferredScope,
|
|
241
268
|
source,
|
|
@@ -314,7 +341,7 @@ export function detectOcChatgptMultiAuthTarget(options) {
|
|
|
314
341
|
}
|
|
315
342
|
return {
|
|
316
343
|
kind: "none",
|
|
317
|
-
reason: "No oc-chatgpt-multi-auth target root found; create ~/.opencode or supply OC_CHATGPT_MULTI_AUTH_DIR.",
|
|
344
|
+
reason: "No oc-chatgpt-multi-auth target root found; create ~/.opencode or supply OC_CODEX_MULTI_AUTH_DIR (legacy OC_CHATGPT_MULTI_AUTH_DIR is still accepted).",
|
|
318
345
|
tried: candidates.map(({ scope, source, root, accountPath, backupRoot }) => ({
|
|
319
346
|
scope,
|
|
320
347
|
source,
|
|
@@ -4,6 +4,10 @@ export interface QuotaCacheWindow {
|
|
|
4
4
|
resetAtMs?: number;
|
|
5
5
|
}
|
|
6
6
|
export interface QuotaCacheEntry {
|
|
7
|
+
primingCompleted?: boolean;
|
|
8
|
+
/** Completion/failure time, independent of the quota header observation. */
|
|
9
|
+
primingObservedAt?: number;
|
|
10
|
+
primingFailure?: "timed out" | "stream ended early" | "upstream failed" | "response too large" | "network error";
|
|
7
11
|
updatedAt: number;
|
|
8
12
|
status: number;
|
|
9
13
|
model: string;
|
|
@@ -47,6 +51,8 @@ export declare function getQuotaCachePath(): string;
|
|
|
47
51
|
* will be empty if the on-disk file is absent, malformed, or could not be read.
|
|
48
52
|
*/
|
|
49
53
|
export declare function loadQuotaCache(): Promise<QuotaCacheData>;
|
|
54
|
+
/** Merge quota and priming evidence independently; subsequent quota retires old outcomes. */
|
|
55
|
+
export declare function mergeQuotaCacheEntry(latest: QuotaCacheEntry | undefined, update: QuotaCacheEntry): QuotaCacheEntry;
|
|
50
56
|
/**
|
|
51
57
|
* Persist the quota cache to the on-disk JSON file used by the multi-auth runtime.
|
|
52
58
|
*
|
package/dist/lib/quota-cache.js
CHANGED
|
@@ -58,6 +58,9 @@ function normalizeEntry(value) {
|
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
return {
|
|
61
|
+
...(value.primingCompleted === true ? { primingCompleted: true } : {}),
|
|
62
|
+
...(typeof value.primingFailure === "string" && ["timed out", "stream ended early", "upstream failed", "response too large", "network error"].includes(value.primingFailure) ? { primingFailure: value.primingFailure } : {}),
|
|
63
|
+
...(normalizeNumber(value.primingObservedAt) !== undefined ? { primingObservedAt: normalizeNumber(value.primingObservedAt) } : {}),
|
|
61
64
|
updatedAt,
|
|
62
65
|
status,
|
|
63
66
|
model: model.trim(),
|
|
@@ -158,6 +161,32 @@ async function readQuotaCache() {
|
|
|
158
161
|
...(parsed.byWorkspace ? { byWorkspace: normalizeEntryMap(parsed.byWorkspace) } : {}),
|
|
159
162
|
};
|
|
160
163
|
}
|
|
164
|
+
/** Merge quota and priming evidence independently; subsequent quota retires old outcomes. */
|
|
165
|
+
export function mergeQuotaCacheEntry(latest, update) {
|
|
166
|
+
if (!latest)
|
|
167
|
+
return update;
|
|
168
|
+
const quota = update.updatedAt >= latest.updatedAt ? update : latest;
|
|
169
|
+
const outcomeTime = (entry) => entry.primingCompleted || entry.primingFailure
|
|
170
|
+
? entry.primingObservedAt ?? entry.updatedAt : -Infinity;
|
|
171
|
+
// A timeout does not undo a completion from an overlapping attempt.
|
|
172
|
+
// Only completions at/after the newest quota observation remain relevant.
|
|
173
|
+
const completion = [update, latest].filter(entry => entry.primingCompleted && outcomeTime(entry) >= quota.updatedAt)
|
|
174
|
+
.sort((a, b) => outcomeTime(b) - outcomeTime(a))[0];
|
|
175
|
+
const evidence = completion ?? (outcomeTime(update) >= outcomeTime(latest) ? update : latest);
|
|
176
|
+
const result = { ...quota };
|
|
177
|
+
delete result.primingCompleted;
|
|
178
|
+
delete result.primingFailure;
|
|
179
|
+
delete result.primingObservedAt;
|
|
180
|
+
if (outcomeTime(evidence) >= quota.updatedAt) {
|
|
181
|
+
if (evidence.primingCompleted)
|
|
182
|
+
result.primingCompleted = true;
|
|
183
|
+
else if (evidence.primingFailure)
|
|
184
|
+
result.primingFailure = evidence.primingFailure;
|
|
185
|
+
if (evidence.primingObservedAt !== undefined)
|
|
186
|
+
result.primingObservedAt = evidence.primingObservedAt;
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
161
190
|
/** Reapply this run's changed entries, preserving unrelated or newer concurrent observations. */
|
|
162
191
|
function mergeQuotaChanges(current, proposed, baseline) {
|
|
163
192
|
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
@@ -168,24 +197,12 @@ function mergeQuotaChanges(current, proposed, baseline) {
|
|
|
168
197
|
continue;
|
|
169
198
|
const latest = current[namespace]?.[key], update = next[key];
|
|
170
199
|
if (update) {
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
current[namespace][key] = update;
|
|
174
|
-
}
|
|
175
|
-
else if (same(latest, before[key])) {
|
|
176
|
-
// The on-disk entry is still exactly the one this caller's
|
|
177
|
-
// baseline saw, so nothing concurrent touched this key:
|
|
178
|
-
// `update` is a deliberate write whose lower stamp can only
|
|
179
|
-
// come from a backward clock jump on this writer. Re-stamp
|
|
180
|
-
// it just ahead instead of silently losing it. A raced key
|
|
181
|
-
// (`!same`) falls through and keeps the on-disk entry: its
|
|
182
|
-
// higher stamp marks a newer observation, and bumping an
|
|
183
|
-
// older one past it would let stale quota data overwrite
|
|
184
|
-
// fresher data.
|
|
200
|
+
if (latest && update.updatedAt < latest.updatedAt && same(latest, before[key])) {
|
|
201
|
+
// Preserve the existing backward-clock handling for an unraced write.
|
|
185
202
|
update.updatedAt = latest.updatedAt + 1;
|
|
186
|
-
current[namespace] ??= {};
|
|
187
|
-
current[namespace][key] = update;
|
|
188
203
|
}
|
|
204
|
+
current[namespace] ??= {};
|
|
205
|
+
current[namespace][key] = mergeQuotaCacheEntry(latest, update);
|
|
189
206
|
}
|
|
190
207
|
else if (same(latest, before[key])) {
|
|
191
208
|
delete current[namespace]?.[key];
|
|
@@ -26,7 +26,10 @@ export interface CodexQuotaWindow {
|
|
|
26
26
|
resetAtMs?: number;
|
|
27
27
|
}
|
|
28
28
|
export interface CodexQuotaSnapshot {
|
|
29
|
+
/** Time quota headers were observed, before consuming the response stream. */
|
|
30
|
+
observedAt?: number;
|
|
29
31
|
primingCompleted?: boolean;
|
|
32
|
+
primingObservedAt?: number;
|
|
30
33
|
primingFailure?: FirstUseProbeError["reason"];
|
|
31
34
|
status: number;
|
|
32
35
|
planType?: string;
|
package/dist/lib/quota-probe.js
CHANGED
|
@@ -382,15 +382,16 @@ export async function fetchCodexQuotaSnapshot(options) {
|
|
|
382
382
|
}
|
|
383
383
|
const snapshotBase = parseQuotaSnapshotBase(response.headers, response.status);
|
|
384
384
|
if (snapshotBase) {
|
|
385
|
-
|
|
385
|
+
const observedAt = Date.now();
|
|
386
|
+
if (options.primeUnusedSubscription && needsSubscriptionFirstUse(snapshotBase, observedAt)) {
|
|
386
387
|
try {
|
|
387
388
|
await finishSubscriptionFirstUse(response, timeoutMs);
|
|
388
|
-
return { ...snapshotBase, model, primingCompleted: true };
|
|
389
|
+
return { ...snapshotBase, observedAt, model, primingObservedAt: Date.now(), primingCompleted: true };
|
|
389
390
|
}
|
|
390
391
|
catch (error) {
|
|
391
392
|
// Keep valid quota data without retrying an accepted inference.
|
|
392
393
|
if (error instanceof FirstUseProbeError)
|
|
393
|
-
return { ...snapshotBase, model, primingFailure: error.reason };
|
|
394
|
+
return { ...snapshotBase, observedAt, model, primingObservedAt: Date.now(), primingFailure: error.reason };
|
|
394
395
|
throw error;
|
|
395
396
|
}
|
|
396
397
|
}
|
|
@@ -400,7 +401,7 @@ export async function fetchCodexQuotaSnapshot(options) {
|
|
|
400
401
|
catch {
|
|
401
402
|
// Best effort cancellation.
|
|
402
403
|
}
|
|
403
|
-
return { ...snapshotBase, model };
|
|
404
|
+
return { ...snapshotBase, observedAt, model };
|
|
404
405
|
}
|
|
405
406
|
if (!response.ok) {
|
|
406
407
|
const bodyText = await response.text().catch(() => "");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { QuotaCacheData, QuotaCacheEntry } from "./quota-cache.js";
|
|
2
2
|
import type { AccountMetadataV3 } from "./storage.js";
|
|
3
|
-
export type QuotaCacheAccountRef = Pick<AccountMetadataV3, "accountId" | "email" | "recordId" | "workspaces" | "currentWorkspaceIndex"> & Partial<Pick<AccountMetadataV3, "refreshToken" | "addedAt">>;
|
|
3
|
+
export type QuotaCacheAccountRef = Pick<AccountMetadataV3, "accountId" | "email" | "recordId" | "workspaces" | "currentWorkspaceIndex"> & Partial<Pick<AccountMetadataV3, "refreshToken" | "addedAt" | "accessToken">>;
|
|
4
4
|
export declare function normalizeQuotaAccountId(value: string | undefined): string | null;
|
|
5
5
|
export declare function normalizeQuotaEmail(value: string | undefined): string | null;
|
|
6
6
|
export declare function hasUniqueQuotaAccountId(accounts: readonly QuotaCacheAccountRef[], account: QuotaCacheAccountRef): boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractAccountId } from "./auth/token-utils.js";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { resolveAccountRecordId } from "./storage/record-identity.js";
|
|
3
4
|
export function normalizeQuotaAccountId(value) {
|
|
@@ -101,7 +102,7 @@ export function quotaWorkspaceKey(account, workspaceId) {
|
|
|
101
102
|
export function quotaWorkspaceId(account) {
|
|
102
103
|
return account.workspaces?.length
|
|
103
104
|
? account.workspaces[account.currentWorkspaceIndex ?? 0]?.id.trim()
|
|
104
|
-
: account.accountId?.trim();
|
|
105
|
+
: account.accountId?.trim() || extractAccountId(account.accessToken);
|
|
105
106
|
}
|
|
106
107
|
/** Read exact-workspace quota, using legacy binding entries only for that binding. */
|
|
107
108
|
export function findQuotaCacheEntryForAccount(cache, account, accounts, emailFallbackState = buildQuotaEmailFallbackState(accounts), workspaceId = quotaWorkspaceId(account)) {
|
|
@@ -110,7 +111,10 @@ export function findQuotaCacheEntryForAccount(cache, account, accounts, emailFal
|
|
|
110
111
|
const key = workspaceId && quotaWorkspaceKey(account, workspaceId);
|
|
111
112
|
const scoped = key ? cache.byWorkspace?.[key] : undefined;
|
|
112
113
|
// Legacy entries describe only the stored binding, never a sibling workspace.
|
|
113
|
-
|
|
114
|
+
// A workspaces-bearing account whose selection does not resolve (invalid index
|
|
115
|
+
// or blank id) has no valid binding at all — never fall back to legacy keys.
|
|
116
|
+
if (normalizeQuotaAccountId(workspaceId) !== normalizeQuotaAccountId(account.accountId) ||
|
|
117
|
+
(account.workspaces?.length && !normalizeQuotaAccountId(workspaceId)))
|
|
114
118
|
return scoped ?? null;
|
|
115
119
|
const accountId = normalizeQuotaAccountId(account.accountId);
|
|
116
120
|
const newer = (legacy) => scoped && (!legacy || scoped.updatedAt >= legacy.updatedAt) ? scoped : legacy ?? null;
|