codex-multi-auth 2.17.0 → 2.17.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/.codex-plugin/plugin.json +9 -9
- package/LICENSE +21 -21
- package/README.md +142 -484
- package/assets/codex-multi-auth-icon.svg +39 -39
- package/assets/readme-hero.svg +31 -31
- package/config/README.md +31 -31
- package/config/codex-legacy.json +1221 -1221
- package/config/codex-modern.json +423 -423
- package/config/minimal-codex.json +15 -15
- package/dist/index.d.ts +0 -1
- package/dist/lib/account-policy.d.ts +18 -2
- package/dist/lib/account-policy.js +97 -40
- package/dist/lib/accounts/rate-limits.d.ts +0 -1
- package/dist/lib/accounts.d.ts +1 -8
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +7 -19
- package/dist/lib/api-route-store.d.ts +0 -1
- package/dist/lib/audit.d.ts +0 -1
- package/dist/lib/audit.js +43 -12
- package/dist/lib/auth/account-access.d.ts +0 -1
- package/dist/lib/auth/account-access.js +5 -1
- package/dist/lib/auth/auth.d.ts +4 -3
- package/dist/lib/auth/auth.js +220 -28
- package/dist/lib/auth/browser.d.ts +0 -1
- package/dist/lib/auth/callback-guidance.d.ts +0 -1
- package/dist/lib/auth/device-auth.d.ts +0 -1
- package/dist/lib/auth/index.d.ts +0 -1
- package/dist/lib/auth/org-override.d.ts +0 -1
- package/dist/lib/auth/server.d.ts +1 -2
- package/dist/lib/auth/server.js +100 -53
- package/dist/lib/auth/token-utils.d.ts +0 -1
- package/dist/lib/auth-rate-limit.d.ts +0 -1
- package/dist/lib/budget-guard.d.ts +16 -2
- package/dist/lib/budget-guard.js +123 -43
- package/dist/lib/capability-policy.d.ts +0 -1
- package/dist/lib/circuit-breaker.d.ts +20 -1
- package/dist/lib/circuit-breaker.js +24 -5
- package/dist/lib/cli.d.ts +0 -1
- package/dist/lib/codex-cli/index.d.ts +0 -1
- package/dist/lib/codex-cli/observability.d.ts +0 -1
- package/dist/lib/codex-cli/state.d.ts +0 -1
- package/dist/lib/codex-cli/sync.d.ts +0 -1
- package/dist/lib/codex-cli/writer.d.ts +0 -1
- package/dist/lib/codex-manager/account-credentials.d.ts +0 -1
- package/dist/lib/codex-manager/account-manager-commands.d.ts +0 -1
- package/dist/lib/codex-manager/account-pool-write.d.ts +0 -1
- package/dist/lib/codex-manager/active-account-sync.d.ts +6 -0
- package/dist/lib/codex-manager/active-account-sync.js +336 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts +0 -1
- package/dist/lib/codex-manager/backend-category-entry.d.ts +0 -1
- package/dist/lib/codex-manager/backend-category-helpers.d.ts +0 -1
- package/dist/lib/codex-manager/backend-category-prompt.d.ts +0 -1
- package/dist/lib/codex-manager/backend-settings-controller.d.ts +0 -1
- package/dist/lib/codex-manager/backend-settings-entry.d.ts +0 -1
- package/dist/lib/codex-manager/backend-settings-helpers.d.ts +0 -1
- package/dist/lib/codex-manager/backend-settings-prompt.d.ts +0 -1
- package/dist/lib/codex-manager/backend-settings-schema.d.ts +0 -1
- package/dist/lib/codex-manager/behavior-settings-panel.d.ts +0 -1
- package/dist/lib/codex-manager/commands/account.d.ts +8 -3
- package/dist/lib/codex-manager/commands/account.js +46 -34
- package/dist/lib/codex-manager/commands/best.d.ts +0 -1
- package/dist/lib/codex-manager/commands/bridge.d.ts +0 -1
- package/dist/lib/codex-manager/commands/budget.d.ts +8 -3
- package/dist/lib/codex-manager/commands/budget.js +6 -4
- package/dist/lib/codex-manager/commands/check.d.ts +0 -1
- package/dist/lib/codex-manager/commands/config-explain.d.ts +0 -1
- package/dist/lib/codex-manager/commands/debug-bundle.d.ts +0 -1
- package/dist/lib/codex-manager/commands/forecast.d.ts +1 -2
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +2 -2
- package/dist/lib/codex-manager/commands/history.d.ts +0 -1
- package/dist/lib/codex-manager/commands/init-config.d.ts +0 -1
- package/dist/lib/codex-manager/commands/integrations.d.ts +0 -1
- package/dist/lib/codex-manager/commands/limits.d.ts +0 -1
- package/dist/lib/codex-manager/commands/models.d.ts +0 -1
- package/dist/lib/codex-manager/commands/monitor.d.ts +0 -1
- package/dist/lib/codex-manager/commands/report.d.ts +0 -1
- package/dist/lib/codex-manager/commands/resets.d.ts +0 -1
- package/dist/lib/codex-manager/commands/resets.js +9 -1
- package/dist/lib/codex-manager/commands/rotation.d.ts +0 -1
- package/dist/lib/codex-manager/commands/status.d.ts +0 -1
- package/dist/lib/codex-manager/commands/switch.d.ts +0 -1
- package/dist/lib/codex-manager/commands/uninstall.d.ts +0 -1
- package/dist/lib/codex-manager/commands/unpin.d.ts +0 -1
- package/dist/lib/codex-manager/commands/usage.d.ts +0 -1
- package/dist/lib/codex-manager/commands/verify.d.ts +0 -1
- package/dist/lib/codex-manager/commands/why-selected.d.ts +0 -1
- package/dist/lib/codex-manager/commands/workspace.d.ts +0 -1
- package/dist/lib/codex-manager/dashboard-display-panel.d.ts +0 -1
- package/dist/lib/codex-manager/dashboard-formatters.d.ts +0 -1
- package/dist/lib/codex-manager/dashboard-settings-controller.d.ts +0 -1
- package/dist/lib/codex-manager/dashboard-settings-data.d.ts +0 -1
- package/dist/lib/codex-manager/dashboard-settings-entry.d.ts +0 -1
- package/dist/lib/codex-manager/experimental-settings-entry.d.ts +0 -1
- package/dist/lib/codex-manager/experimental-settings-prompt.d.ts +0 -1
- package/dist/lib/codex-manager/experimental-settings-schema.d.ts +0 -1
- package/dist/lib/codex-manager/experimental-sync-target-entry.d.ts +0 -1
- package/dist/lib/codex-manager/experimental-sync-target.d.ts +0 -1
- package/dist/lib/codex-manager/forecast-report-shared.d.ts +0 -1
- package/dist/lib/codex-manager/formatters/account-formatters.d.ts +0 -1
- package/dist/lib/codex-manager/formatters/index.d.ts +0 -1
- package/dist/lib/codex-manager/formatters/model-formatters.d.ts +0 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts +0 -1
- package/dist/lib/codex-manager/formatters/text-style.d.ts +0 -1
- package/dist/lib/codex-manager/health-check.d.ts +0 -1
- package/dist/lib/codex-manager/health-check.js +1 -1
- package/dist/lib/codex-manager/help.d.ts +0 -1
- package/dist/lib/codex-manager/login-action-panel.d.ts +0 -1
- package/dist/lib/codex-manager/login-flow.d.ts +0 -1
- package/dist/lib/codex-manager/login-menu-actions.d.ts +0 -1
- package/dist/lib/codex-manager/login-menu-data.d.ts +0 -1
- package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-menu-data.js +7 -3
- package/dist/lib/codex-manager/login-oauth.d.ts +0 -1
- package/dist/lib/codex-manager/login-workspace-choice.d.ts +0 -1
- package/dist/lib/codex-manager/manual-callback.d.ts +0 -1
- package/dist/lib/codex-manager/persist-selected-account.d.ts +0 -1
- package/dist/lib/codex-manager/quota-cache-helpers.d.ts +7 -2
- package/dist/lib/codex-manager/quota-cache-helpers.d.ts.map +1 -1
- package/dist/lib/codex-manager/quota-cache-helpers.js +34 -19
- package/dist/lib/codex-manager/rate-limit-markers.d.ts +0 -1
- package/dist/lib/codex-manager/repair-commands.d.ts +0 -1
- package/dist/lib/codex-manager/repair-commands.js +1 -1
- package/dist/lib/codex-manager/settings-hub/backend.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub/dashboard.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub/experimental.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub/index.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub/shared.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub-entry.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub-menu.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub-prompt.d.ts +0 -1
- package/dist/lib/codex-manager/settings-hub.d.ts +0 -1
- package/dist/lib/codex-manager/settings-panels.d.ts +0 -1
- package/dist/lib/codex-manager/settings-persist-utils.d.ts +0 -1
- package/dist/lib/codex-manager/settings-preview.d.ts +0 -1
- package/dist/lib/codex-manager/settings-write-queue.d.ts +0 -1
- package/dist/lib/codex-manager/statusline-settings-panel.d.ts +0 -1
- package/dist/lib/codex-manager/theme-settings-panel.d.ts +0 -1
- package/dist/lib/codex-manager/unified-settings-controller.d.ts +0 -1
- package/dist/lib/codex-manager/unified-settings-entry.d.ts +0 -1
- package/dist/lib/codex-manager.d.ts +1 -2
- package/dist/lib/codex-manager.js +5 -95
- package/dist/lib/concurrency.d.ts +0 -1
- package/dist/lib/config-schema.d.ts +0 -1
- package/dist/lib/config.d.ts +0 -1
- package/dist/lib/config.js +46 -241
- package/dist/lib/constants.d.ts +0 -1
- package/dist/lib/context-budget/model-context-windows.d.ts +0 -1
- package/dist/lib/context-budget-guard.d.ts +0 -1
- package/dist/lib/context-budget-response.d.ts +0 -1
- package/dist/lib/context-budget-response.js +8 -8
- package/dist/lib/context-overflow.d.ts +0 -1
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/dashboard-settings.d.ts +0 -1
- package/dist/lib/entitlement-cache.d.ts +0 -1
- package/dist/lib/env-parsing.d.ts +13 -1
- package/dist/lib/env-parsing.js +21 -0
- package/dist/lib/errors.d.ts +0 -1
- package/dist/lib/forecast.d.ts +0 -1
- package/dist/lib/fs-retry.d.ts +0 -1
- package/dist/lib/health.d.ts +0 -1
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/integration-generators.d.ts +0 -1
- package/dist/lib/live-account-sync.d.ts +0 -1
- package/dist/lib/local-bridge.d.ts +0 -1
- package/dist/lib/local-bridge.js +4 -1
- package/dist/lib/local-client-tokens.d.ts +0 -1
- package/dist/lib/local-client-tokens.js +125 -30
- package/dist/lib/logger.d.ts +0 -1
- package/dist/lib/logger.js +11 -1
- package/dist/lib/model-capability-matrix.d.ts +0 -1
- package/dist/lib/model-route-policy.d.ts +1 -2
- package/dist/lib/named-backup-export.d.ts +0 -1
- package/dist/lib/oauth-success.html +125 -125
- package/dist/lib/oc-chatgpt-import-adapter.d.ts +0 -1
- package/dist/lib/oc-chatgpt-orchestrator.d.ts +0 -1
- package/dist/lib/oc-chatgpt-target-detection.d.ts +0 -1
- package/dist/lib/parallel-probe.d.ts +0 -1
- package/dist/lib/policy/runtime-policy-cache.d.ts +80 -0
- package/dist/lib/policy/runtime-policy-cache.js +310 -0
- package/dist/lib/policy/runtime-policy.d.ts +1 -2
- package/dist/lib/policy/runtime-policy.js +46 -19
- package/dist/lib/preemptive-quota-scheduler.d.ts +0 -1
- package/dist/lib/proactive-refresh.d.ts +0 -1
- package/dist/lib/prompts/codex-host-bridge.d.ts +0 -1
- package/dist/lib/prompts/codex-host-bridge.js +138 -138
- package/dist/lib/prompts/codex.d.ts +0 -1
- package/dist/lib/prompts/codex.js +79 -79
- package/dist/lib/prompts/fetch-utils.d.ts +0 -1
- package/dist/lib/prompts/host-codex-prompt.d.ts +0 -1
- package/dist/lib/quota-cache.d.ts +7 -4
- package/dist/lib/quota-cache.d.ts.map +1 -1
- package/dist/lib/quota-cache.js +117 -61
- package/dist/lib/quota-probe.d.ts +0 -1
- package/dist/lib/quota-probe.js +5 -2
- package/dist/lib/quota-readiness.d.ts +7 -3
- package/dist/lib/quota-readiness.d.ts.map +1 -1
- package/dist/lib/quota-readiness.js +25 -4
- package/dist/lib/recovery/constants.d.ts +0 -1
- package/dist/lib/recovery/storage.d.ts +0 -1
- package/dist/lib/recovery/types.d.ts +0 -1
- package/dist/lib/recovery.d.ts +0 -1
- package/dist/lib/redaction.d.ts +0 -1
- package/dist/lib/refresh-guardian.d.ts +0 -1
- package/dist/lib/refresh-lease.d.ts +0 -1
- package/dist/lib/refresh-queue.d.ts +0 -1
- package/dist/lib/request/client-cancellation.d.ts +0 -1
- package/dist/lib/request/error-classification.d.ts +0 -1
- package/dist/lib/request/failover-config.d.ts +0 -1
- package/dist/lib/request/failure-policy.d.ts +0 -1
- package/dist/lib/request/fetch-helpers.d.ts +0 -1
- package/dist/lib/request/headers.d.ts +0 -1
- package/dist/lib/request/helpers/input-utils.d.ts +0 -1
- package/dist/lib/request/helpers/input-utils.js +88 -34
- package/dist/lib/request/helpers/model-map.d.ts +0 -1
- package/dist/lib/request/helpers/tool-utils.d.ts +0 -1
- package/dist/lib/request/helpers/tool-utils.js +421 -4
- package/dist/lib/request/index.d.ts +0 -1
- package/dist/lib/request/rate-limit-backoff.d.ts +0 -1
- package/dist/lib/request/rate-limit-decision.d.ts +0 -1
- package/dist/lib/request/request-attempt-budget.d.ts +0 -1
- package/dist/lib/request/request-init.d.ts +0 -1
- package/dist/lib/request/request-resilience.d.ts +0 -1
- package/dist/lib/request/request-transformer.d.ts +0 -1
- package/dist/lib/request/request-transformer.js +50 -25
- package/dist/lib/request/response-compaction.d.ts +0 -1
- package/dist/lib/request/response-handler.d.ts +0 -1
- package/dist/lib/request/response-metadata.d.ts +0 -1
- package/dist/lib/request/response-outcome.d.ts +0 -1
- package/dist/lib/request/stream-failover-runtime.d.ts +0 -1
- package/dist/lib/request/stream-failover.d.ts +0 -1
- package/dist/lib/request/stream-failover.js +28 -4
- package/dist/lib/request/token-refresh.d.ts +0 -1
- package/dist/lib/request/url-rewriting.d.ts +0 -1
- package/dist/lib/request/wait-utils.d.ts +0 -1
- package/dist/lib/rotation.d.ts +0 -1
- package/dist/lib/routing-mutex.d.ts +0 -1
- package/dist/lib/routing-profiles.d.ts +16 -2
- package/dist/lib/routing-profiles.js +119 -44
- package/dist/lib/runtime/account-check-helpers.d.ts +0 -1
- package/dist/lib/runtime/account-check-types.d.ts +0 -1
- package/dist/lib/runtime/account-check.d.ts +0 -1
- package/dist/lib/runtime/account-manager-cache-entry.d.ts +0 -1
- package/dist/lib/runtime/account-manager-cache.d.ts +0 -1
- package/dist/lib/runtime/account-model-catalog.d.ts +1 -2
- package/dist/lib/runtime/account-pool.d.ts +0 -1
- package/dist/lib/runtime/account-reset-credits.d.ts +0 -1
- package/dist/lib/runtime/account-reset-credits.js +8 -2
- package/dist/lib/runtime/account-scope.d.ts +0 -1
- package/dist/lib/runtime/account-select-event.d.ts +0 -1
- package/dist/lib/runtime/account-selection.d.ts +0 -1
- package/dist/lib/runtime/account-state.d.ts +0 -1
- package/dist/lib/runtime/account-status.d.ts +0 -1
- package/dist/lib/runtime/account-storage-scope-entry.d.ts +0 -1
- package/dist/lib/runtime/api-model-capabilities.d.ts +0 -1
- package/dist/lib/runtime/api-model-runtime.d.ts +0 -1
- package/dist/lib/runtime/app-bind.d.ts +0 -1
- package/dist/lib/runtime/app-bind.d.ts.map +1 -1
- package/dist/lib/runtime/app-bind.js +10 -2
- package/dist/lib/runtime/app-helper-selection.d.ts +0 -1
- package/dist/lib/runtime/auth-facade.d.ts +0 -1
- package/dist/lib/runtime/automatic-account-checks.d.ts +5 -2
- package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -1
- package/dist/lib/runtime/automatic-account-checks.js +29 -2
- package/dist/lib/runtime/automatic-subscription-checks.d.ts +1 -2
- package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -1
- package/dist/lib/runtime/automatic-subscription-checks.js +13 -16
- package/dist/lib/runtime/browser-oauth-flow.d.ts +0 -1
- package/dist/lib/runtime/capability-boost.d.ts +0 -1
- package/dist/lib/runtime/catalog-capabilities.d.ts +0 -1
- package/dist/lib/runtime/config-toml.d.ts +0 -1
- package/dist/lib/runtime/context-budget-settings.d.ts +0 -1
- package/dist/lib/runtime/event-handler.d.ts +0 -1
- package/dist/lib/runtime/first-run.d.ts +0 -1
- package/dist/lib/runtime/flagged-verify-types.d.ts +0 -1
- package/dist/lib/runtime/hydrate-emails.d.ts +0 -1
- package/dist/lib/runtime/inference-activity.d.ts +0 -1
- package/dist/lib/runtime/live-sync-entry.d.ts +0 -1
- package/dist/lib/runtime/live-sync.d.ts +0 -1
- package/dist/lib/runtime/loader-setup.d.ts +0 -1
- package/dist/lib/runtime/login-menu-accounts.d.ts +0 -1
- package/dist/lib/runtime/manual-oauth-flow.d.ts +0 -1
- package/dist/lib/runtime/model-discovery-status.d.ts +2 -3
- package/dist/lib/runtime/native-account-storage.d.ts +0 -1
- package/dist/lib/runtime/native-account-sync.d.ts +0 -1
- package/dist/lib/runtime/native-binding-lock.d.ts +0 -1
- package/dist/lib/runtime/native-client-auth.d.ts +0 -1
- package/dist/lib/runtime/native-provider-config.d.ts +0 -1
- package/dist/lib/runtime/native-rate-limits.d.ts +2 -1
- package/dist/lib/runtime/native-rate-limits.js +23 -6
- package/dist/lib/runtime/preemptive-quota.d.ts +0 -1
- package/dist/lib/runtime/quota-headers.d.ts +0 -1
- package/dist/lib/runtime/quota-probe.d.ts +0 -1
- package/dist/lib/runtime/quota-settings.d.ts +0 -1
- package/dist/lib/runtime/refresh-guardian-entry.d.ts +0 -1
- package/dist/lib/runtime/refresh-guardian.d.ts +0 -1
- package/dist/lib/runtime/request-init.d.ts +0 -1
- package/dist/lib/runtime/reset-credit-routing.d.ts +0 -1
- package/dist/lib/runtime/reset-credits.d.ts +0 -1
- package/dist/lib/runtime/response-output-history.d.ts +0 -1
- package/dist/lib/runtime/responses-websocket.d.ts +0 -1
- package/dist/lib/runtime/resume-picker.d.ts +0 -1
- package/dist/lib/runtime/rotation-account-selection.d.ts +0 -1
- package/dist/lib/runtime/rotation-proxy-state.d.ts +0 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +0 -1
- package/dist/lib/runtime/rotation-storage-meta.d.ts +0 -1
- package/dist/lib/runtime/rotation-token-refresh.d.ts +0 -1
- package/dist/lib/runtime/runtime-capability-failures.d.ts +0 -1
- package/dist/lib/runtime/runtime-current-account.d.ts +0 -1
- package/dist/lib/runtime/runtime-observability.d.ts +0 -1
- package/dist/lib/runtime/runtime-services.d.ts +0 -1
- package/dist/lib/runtime/session-affinity-entry.d.ts +0 -1
- package/dist/lib/runtime/session-recovery.d.ts +0 -1
- package/dist/lib/runtime/status-marker.d.ts +0 -1
- package/dist/lib/runtime/storage-scope.d.ts +0 -1
- package/dist/lib/runtime/subscription-first-use.d.ts +0 -1
- package/dist/lib/runtime/subscription-quota-event.d.ts +0 -1
- package/dist/lib/runtime/subscription-quota-order.d.ts +0 -1
- package/dist/lib/runtime/toast.d.ts +0 -1
- package/dist/lib/runtime/ui-runtime-entry.d.ts +0 -1
- package/dist/lib/runtime/ui-runtime.d.ts +0 -1
- package/dist/lib/runtime/verify-flagged.d.ts +0 -1
- package/dist/lib/runtime/workspace-model-scopes.d.ts +0 -1
- package/dist/lib/runtime-constants.d.ts +0 -1
- package/dist/lib/runtime-paths.d.ts +0 -1
- package/dist/lib/runtime-rotation-proxy.d.ts +1 -1
- package/dist/lib/runtime-rotation-proxy.js +136 -3
- package/dist/lib/schemas.d.ts +35 -13
- package/dist/lib/schemas.js +19 -2
- package/dist/lib/session-affinity.d.ts +0 -1
- package/dist/lib/shutdown.d.ts +0 -1
- package/dist/lib/storage/account-clear-entry.d.ts +0 -1
- package/dist/lib/storage/account-clear.d.ts +0 -1
- package/dist/lib/storage/account-match-utils.d.ts +0 -1
- package/dist/lib/storage/account-persistence.d.ts +0 -1
- package/dist/lib/storage/account-port.d.ts +0 -1
- package/dist/lib/storage/account-save-entry.d.ts +0 -1
- package/dist/lib/storage/account-save.d.ts +9 -2
- package/dist/lib/storage/account-save.js +4 -1
- package/dist/lib/storage/account-snapshot.d.ts +0 -1
- package/dist/lib/storage/backup-metadata-builder.d.ts +0 -1
- package/dist/lib/storage/backup-metadata.d.ts +0 -1
- package/dist/lib/storage/backup-paths.d.ts +0 -1
- package/dist/lib/storage/backup-restore.d.ts +0 -1
- package/dist/lib/storage/cache-artifacts.d.ts +0 -1
- package/dist/lib/storage/credential-sidecars.d.ts +0 -1
- package/dist/lib/storage/error-hints.d.ts +0 -1
- package/dist/lib/storage/file-lock.d.ts +0 -1
- package/dist/lib/storage/file-lock.js +33 -1
- package/dist/lib/storage/file-paths.d.ts +0 -1
- package/dist/lib/storage/fixture-guards.d.ts +0 -1
- package/dist/lib/storage/flagged-entry.d.ts +0 -1
- package/dist/lib/storage/flagged-load-entry.d.ts +0 -1
- package/dist/lib/storage/flagged-save-entry.d.ts +0 -1
- package/dist/lib/storage/flagged-storage-file.d.ts +0 -1
- package/dist/lib/storage/flagged-storage-io.d.ts +0 -1
- package/dist/lib/storage/flagged-storage.d.ts +0 -1
- package/dist/lib/storage/gitignore.d.ts +0 -1
- package/dist/lib/storage/hash.d.ts +0 -1
- package/dist/lib/storage/health.d.ts +0 -1
- package/dist/lib/storage/identity.d.ts +0 -1
- package/dist/lib/storage/import-export.d.ts +0 -1
- package/dist/lib/storage/json-store-lock.d.ts +105 -0
- package/dist/lib/storage/json-store-lock.js +259 -0
- package/dist/lib/storage/metadata-section.d.ts +0 -1
- package/dist/lib/storage/migrations.d.ts +0 -1
- package/dist/lib/storage/migrations.js +31 -18
- package/dist/lib/storage/named-backup-entry.d.ts +0 -1
- package/dist/lib/storage/named-backups-entry.d.ts +0 -1
- package/dist/lib/storage/named-backups.d.ts +0 -1
- package/dist/lib/storage/path-state.d.ts +0 -1
- package/dist/lib/storage/paths.d.ts +0 -1
- package/dist/lib/storage/pending-auth.d.ts +10 -3
- package/dist/lib/storage/pending-auth.d.ts.map +1 -1
- package/dist/lib/storage/pending-auth.js +33 -9
- package/dist/lib/storage/project-migration.d.ts +0 -1
- package/dist/lib/storage/public-types.d.ts +0 -1
- package/dist/lib/storage/record-identity.d.ts +15 -0
- package/dist/lib/storage/record-identity.d.ts.map +1 -0
- package/dist/lib/storage/record-identity.js +16 -0
- package/dist/lib/storage/record-utils.d.ts +0 -1
- package/dist/lib/storage/restore-assessment.d.ts +0 -1
- package/dist/lib/storage/restore-backup-entry.d.ts +0 -1
- package/dist/lib/storage/restore-metadata.d.ts +0 -1
- package/dist/lib/storage/save-retry.d.ts +0 -1
- package/dist/lib/storage/snapshot-inspectors.d.ts +0 -1
- package/dist/lib/storage/snapshot-merge.d.ts +0 -1
- package/dist/lib/storage/storage-parser.d.ts +2 -1
- package/dist/lib/storage/storage-parser.js +10 -2
- package/dist/lib/storage/transactions.d.ts +0 -1
- package/dist/lib/storage.d.ts +15 -2
- package/dist/lib/storage.js +612 -25
- package/dist/lib/synthetic-response.d.ts +0 -1
- package/dist/lib/table-formatter.d.ts +0 -1
- package/dist/lib/temp-path.d.ts +0 -1
- package/dist/lib/tools/hashline-tools.d.ts +0 -1
- package/dist/lib/types.d.ts +0 -1
- package/dist/lib/ui/ansi.d.ts +0 -1
- package/dist/lib/ui/auth-menu-builder.d.ts +0 -1
- package/dist/lib/ui/auth-menu.d.ts +0 -1
- package/dist/lib/ui/check-progress.d.ts +0 -1
- package/dist/lib/ui/confirm.d.ts +0 -1
- package/dist/lib/ui/display-width.d.ts +0 -1
- package/dist/lib/ui/format.d.ts +0 -1
- package/dist/lib/ui/index.d.ts +0 -1
- package/dist/lib/ui/runtime.d.ts +0 -1
- package/dist/lib/ui/select.d.ts +0 -1
- package/dist/lib/ui/theme.d.ts +0 -1
- package/dist/lib/ui/ui-copy.d.ts +0 -1
- package/dist/lib/unified-settings.d.ts +13 -11
- package/dist/lib/unified-settings.js +22 -14
- package/dist/lib/update-notice.d.ts +0 -1
- package/dist/lib/usage/index.d.ts +0 -1
- package/dist/lib/usage/ledger.d.ts +0 -1
- package/dist/lib/usage/pricing.d.ts +0 -1
- package/dist/lib/usage/redaction.d.ts +0 -1
- package/dist/lib/usage/stream-usage-deferral.d.ts +0 -1
- package/dist/lib/usage/types.d.ts +0 -1
- package/dist/lib/usage/usage-extraction.d.ts +0 -1
- package/dist/lib/utils.d.ts +21 -1
- package/dist/lib/utils.js +31 -0
- package/dist/lib/wsl.d.ts +0 -1
- package/node_modules/@codex-ai/plugin/dist/index.d.ts +2 -2
- package/node_modules/@codex-ai/plugin/dist/index.js +2 -2
- package/node_modules/@codex-ai/plugin/dist/tool.d.ts +42 -42
- package/node_modules/@codex-ai/plugin/dist/tool.js +29 -29
- package/node_modules/@codex-ai/plugin/package.json +9 -9
- package/node_modules/@codex-ai/sdk/dist/index.d.ts +4 -4
- package/node_modules/@codex-ai/sdk/dist/index.js +2 -2
- package/node_modules/@codex-ai/sdk/package.json +8 -8
- package/package.json +206 -200
- package/scripts/codex-app-launcher.js +653 -653
- package/scripts/codex-app-router.js +373 -373
- package/scripts/codex-bin-resolver.js +332 -313
- package/scripts/codex-multi-auth.js +65 -59
- package/scripts/codex-routing.js +62 -62
- package/scripts/codex.js +6923 -6642
- package/scripts/install-codex-auth-utils.js +213 -213
- package/scripts/mcodex.js +367 -367
- package/scripts/postinstall.js +114 -114
- package/scripts/preuninstall.js +265 -265
- package/skills/codex-auth-setup/SKILL.md +73 -0
- package/vendor/codex-ai-plugin/dist/index.d.ts +2 -2
- package/vendor/codex-ai-plugin/dist/index.js +2 -2
- package/vendor/codex-ai-plugin/dist/tool.d.ts +42 -42
- package/vendor/codex-ai-plugin/dist/tool.js +29 -29
- package/vendor/codex-ai-plugin/package.json +9 -9
- package/vendor/codex-ai-sdk/dist/index.d.ts +4 -4
- package/vendor/codex-ai-sdk/dist/index.js +2 -2
- package/vendor/codex-ai-sdk/package.json +8 -8
|
@@ -22,4 +22,3 @@ export interface StatuslineSettingsPanelDeps {
|
|
|
22
22
|
}
|
|
23
23
|
export declare function promptStatuslineSettingsPanel(initial: DashboardDisplaySettings, deps: StatuslineSettingsPanelDeps): Promise<DashboardDisplaySettings | null>;
|
|
24
24
|
export {};
|
|
25
|
-
//# sourceMappingURL=statusline-settings-panel.d.ts.map
|
|
@@ -10,4 +10,3 @@ export interface ThemeSettingsPanelDeps {
|
|
|
10
10
|
UI_COPY: typeof UI_COPY;
|
|
11
11
|
}
|
|
12
12
|
export declare function promptThemeSettingsPanel(initial: DashboardDisplaySettings, deps: ThemeSettingsPanelDeps): Promise<DashboardDisplaySettings | null>;
|
|
13
|
-
//# sourceMappingURL=theme-settings-panel.d.ts.map
|
|
@@ -24,4 +24,3 @@ export type UnifiedSettingsControllerDeps = {
|
|
|
24
24
|
THEME_PANEL_KEYS: readonly (keyof DashboardDisplaySettings)[];
|
|
25
25
|
};
|
|
26
26
|
export declare function configureUnifiedSettingsController(initialSettings: DashboardDisplaySettings | undefined, deps: UnifiedSettingsControllerDeps): Promise<DashboardDisplaySettings>;
|
|
27
|
-
//# sourceMappingURL=unified-settings-controller.d.ts.map
|
|
@@ -3,4 +3,3 @@ import type { UnifiedSettingsControllerDeps } from "./unified-settings-controlle
|
|
|
3
3
|
export declare function configureUnifiedSettingsEntry(initialSettings: DashboardDisplaySettings | undefined, deps: {
|
|
4
4
|
configureUnifiedSettingsController: (initialSettings: DashboardDisplaySettings | undefined, deps: UnifiedSettingsControllerDeps) => Promise<DashboardDisplaySettings>;
|
|
5
5
|
} & UnifiedSettingsControllerDeps): Promise<DashboardDisplaySettings>;
|
|
6
|
-
//# sourceMappingURL=unified-settings-entry.d.ts.map
|
|
@@ -2,8 +2,7 @@ import { selectHybridAccountTraced } from "./rotation.js";
|
|
|
2
2
|
import { formatBackupSavedAt, styleAccountDetailText } from "./codex-manager/formatters/index.js";
|
|
3
3
|
import { type AccountStorageV3 } from "./storage.js";
|
|
4
4
|
export { formatBackupSavedAt, styleAccountDetailText };
|
|
5
|
-
export
|
|
5
|
+
export { autoSyncActiveAccountToCodex } from "./codex-manager/active-account-sync.js";
|
|
6
6
|
/** @internal Exposed for diagnostics regression tests; not part of the CLI API. */
|
|
7
7
|
export declare function buildSelectAccountTraced(): (storage: AccountStorageV3) => Promise<ReturnType<typeof selectHybridAccountTraced>>;
|
|
8
8
|
export declare function runCodexMultiAuthCli(rawArgs: string[]): Promise<number>;
|
|
9
|
-
//# sourceMappingURL=codex-manager.d.ts.map
|
|
@@ -5,7 +5,6 @@ import { loadInferenceRequestTimes } from "./runtime/inference-activity.js";
|
|
|
5
5
|
import { loadModelInventory, refreshAndPrintModelInventory } from "./runtime/model-discovery-status.js";
|
|
6
6
|
import { AUTH_INVALIDATION_MARKER, AccountManager, extractAccountEmail, extractAccountId, formatAccountLabel, formatWaitTime, sanitizeEmail, } from "./accounts.js";
|
|
7
7
|
import { reboundUnauthorizedAccountIdentity, refreshCodexCliMirror, } from "./auth/account-access.js";
|
|
8
|
-
import { codexCliAccountIdFor } from "./auth/token-utils.js";
|
|
9
8
|
import { loadCodexCliState } from "./codex-cli/state.js";
|
|
10
9
|
import { setCodexCliActiveSelection } from "./codex-cli/writer.js";
|
|
11
10
|
import { parseBestArgs, printBestUsage, runBestCommand, } from "./codex-manager/commands/best.js";
|
|
@@ -60,7 +59,7 @@ import { loadQuotaCache, saveQuotaCache } from "./quota-cache.js";
|
|
|
60
59
|
import { readAppRuntimeHelperAccountSignal } from "./runtime/runtime-current-account.js";
|
|
61
60
|
import { fetchCodexQuotaSnapshot, formatQuotaSnapshotLine, } from "./quota-probe.js";
|
|
62
61
|
import { queuedRefresh } from "./refresh-queue.js";
|
|
63
|
-
import { clearAccounts,
|
|
62
|
+
import { clearAccounts, inspectStorageHealth, getLastAccountsSaveTimestamp, getStoragePath, loadAccounts, loadFlaggedAccounts, saveAccounts, setStoragePath, } from "./storage.js";
|
|
64
63
|
// Formatter implementations moved to lib/codex-manager/formatters/ (audit
|
|
65
64
|
// roadmap §4.1.1 phase 1). Re-exported here so existing consumers importing
|
|
66
65
|
// from lib/codex-manager.js keep working unchanged.
|
|
@@ -196,99 +195,10 @@ async function runBest(args) {
|
|
|
196
195
|
setCodexCliActiveSelection,
|
|
197
196
|
});
|
|
198
197
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
const activeIndex = resolveActiveIndex(storage, "codex");
|
|
206
|
-
if (activeIndex < 0 || activeIndex >= storage.accounts.length) {
|
|
207
|
-
return false;
|
|
208
|
-
}
|
|
209
|
-
const account = storage.accounts[activeIndex];
|
|
210
|
-
if (!account) {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
const accountMatch = {
|
|
214
|
-
accountId: account.accountId,
|
|
215
|
-
email: account.email,
|
|
216
|
-
refreshToken: account.refreshToken,
|
|
217
|
-
};
|
|
218
|
-
const now = Date.now();
|
|
219
|
-
let syncAccessToken = account.accessToken;
|
|
220
|
-
let syncRefreshToken = account.refreshToken;
|
|
221
|
-
let syncExpiresAt = account.expiresAt;
|
|
222
|
-
let syncIdToken;
|
|
223
|
-
let syncEmail = account.email;
|
|
224
|
-
let changed = false;
|
|
225
|
-
let nextStoredAccount = null;
|
|
226
|
-
if (!hasUsableAccessToken(account, now)) {
|
|
227
|
-
const refreshResult = await queuedRefresh(account.refreshToken);
|
|
228
|
-
if (refreshResult.type !== "success") {
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
nextStoredAccount = structuredClone(account);
|
|
232
|
-
const tokenAccountId = extractAccountId(refreshResult.access);
|
|
233
|
-
const nextEmail = sanitizeEmail(extractAccountEmail(refreshResult.access, refreshResult.idToken));
|
|
234
|
-
if (nextStoredAccount.refreshToken !== refreshResult.refresh) {
|
|
235
|
-
nextStoredAccount.refreshToken = refreshResult.refresh;
|
|
236
|
-
changed = true;
|
|
237
|
-
}
|
|
238
|
-
if (nextStoredAccount.accessToken !== refreshResult.access) {
|
|
239
|
-
nextStoredAccount.accessToken = refreshResult.access;
|
|
240
|
-
changed = true;
|
|
241
|
-
}
|
|
242
|
-
if (nextStoredAccount.expiresAt !== refreshResult.expires) {
|
|
243
|
-
nextStoredAccount.expiresAt = refreshResult.expires;
|
|
244
|
-
changed = true;
|
|
245
|
-
}
|
|
246
|
-
if (nextEmail && nextEmail !== nextStoredAccount.email) {
|
|
247
|
-
nextStoredAccount.email = nextEmail;
|
|
248
|
-
changed = true;
|
|
249
|
-
}
|
|
250
|
-
if (applyTokenAccountIdentity(nextStoredAccount, tokenAccountId)) {
|
|
251
|
-
changed = true;
|
|
252
|
-
}
|
|
253
|
-
syncAccessToken = refreshResult.access;
|
|
254
|
-
syncRefreshToken = refreshResult.refresh;
|
|
255
|
-
syncExpiresAt = refreshResult.expires;
|
|
256
|
-
syncIdToken = refreshResult.idToken;
|
|
257
|
-
syncEmail = nextStoredAccount.email;
|
|
258
|
-
}
|
|
259
|
-
if (changed && nextStoredAccount) {
|
|
260
|
-
let persisted = false;
|
|
261
|
-
await withAccountStorageTransaction(async (loadedStorage, persist) => {
|
|
262
|
-
if (!loadedStorage) {
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
const nextStorage = structuredClone(loadedStorage);
|
|
266
|
-
const targetIndex = findMatchingAccountIndex(nextStorage.accounts, accountMatch, {
|
|
267
|
-
allowUniqueAccountIdFallbackWithoutEmail: true,
|
|
268
|
-
}) ??
|
|
269
|
-
findMatchingAccountIndex(nextStorage.accounts, nextStoredAccount, {
|
|
270
|
-
allowUniqueAccountIdFallbackWithoutEmail: true,
|
|
271
|
-
});
|
|
272
|
-
if (targetIndex === undefined) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
nextStorage.accounts[targetIndex] = structuredClone(nextStoredAccount);
|
|
276
|
-
await persist(nextStorage);
|
|
277
|
-
persisted = true;
|
|
278
|
-
});
|
|
279
|
-
if (!persisted) {
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
return setCodexCliActiveSelection({
|
|
284
|
-
accountId: codexCliAccountIdFor(nextStoredAccount ?? account, syncAccessToken, syncIdToken),
|
|
285
|
-
email: syncEmail,
|
|
286
|
-
accessToken: syncAccessToken,
|
|
287
|
-
refreshToken: syncRefreshToken,
|
|
288
|
-
expiresAt: syncExpiresAt,
|
|
289
|
-
...(syncIdToken ? { idToken: syncIdToken } : {}),
|
|
290
|
-
});
|
|
291
|
-
}
|
|
198
|
+
// Moved to lib/codex-manager/active-account-sync.ts so the wrapper's forwarded
|
|
199
|
+
// path can import the sync without the whole manager/dispatch graph. Re-exported
|
|
200
|
+
// here to keep the codex-manager.js surface (and its tests) unchanged.
|
|
201
|
+
export { autoSyncActiveAccountToCodex } from "./codex-manager/active-account-sync.js";
|
|
292
202
|
/** @internal Exposed for diagnostics regression tests; not part of the CLI API. */
|
|
293
203
|
export function buildSelectAccountTraced() {
|
|
294
204
|
return async (storage) => {
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
/** Bounded independent work, refilling free slots immediately and preserving result order. */
|
|
2
2
|
export declare function mapWithConcurrency<T, R>(items: readonly T[], limit: number, worker: (item: T, index: number) => Promise<R>): Promise<R[]>;
|
|
3
|
-
//# sourceMappingURL=concurrency.d.ts.map
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -385,4 +385,3 @@ export declare function getRoutingMutexMode(pluginConfig: PluginConfig): "enable
|
|
|
385
385
|
export declare function getSchedulingStrategy(pluginConfig: PluginConfig): "hybrid" | "sequential";
|
|
386
386
|
export declare function getPluginConfigExplainReport(): ConfigExplainReport;
|
|
387
387
|
export {};
|
|
388
|
-
//# sourceMappingURL=config.d.ts.map
|
package/dist/lib/config.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { existsSync, promises as fs, readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
2
|
+
import { join } from "node:path";
|
|
4
3
|
import { parseBooleanEnv } from "./env-parsing.js";
|
|
5
4
|
import { stripModelEffortSuffix } from "./constants.js";
|
|
6
5
|
import { withRetry, withRetrySync } from "./fs-retry.js";
|
|
@@ -8,8 +7,8 @@ import { logWarn } from "./logger.js";
|
|
|
8
7
|
import { StorageError } from "./errors.js";
|
|
9
8
|
import { getCodexHomeDir, getCodexMultiAuthDir, getLegacyCodexDir, } from "./runtime-paths.js";
|
|
10
9
|
import { getValidationErrors, PluginConfigSchema } from "./schemas.js";
|
|
10
|
+
import { getJsonStoreFileMtimeMs, withJsonStoreCasRetry, withJsonStoreFileLock, withJsonStoreWriteQueue, writeJsonStoreFileAtomicWithRetry, } from "./storage/json-store-lock.js";
|
|
11
11
|
import { getUnifiedSettingsPath, loadUnifiedPluginConfigSync, saveUnifiedPluginConfig, } from "./unified-settings.js";
|
|
12
|
-
import { tempPathFor } from "./temp-path.js";
|
|
13
12
|
const CONFIG_DIR = getCodexMultiAuthDir();
|
|
14
13
|
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
15
14
|
const CODEX_HOME_DIR = getCodexHomeDir();
|
|
@@ -23,8 +22,6 @@ const TUI_COLOR_PROFILES = new Set(["truecolor", "ansi16", "ansi256"]);
|
|
|
23
22
|
const TUI_GLYPH_MODES = new Set(["ascii", "unicode", "auto"]);
|
|
24
23
|
const UNSUPPORTED_CODEX_POLICIES = new Set(["strict", "fallback"]);
|
|
25
24
|
const emittedConfigWarnings = new Set();
|
|
26
|
-
const configSaveQueues = new Map();
|
|
27
|
-
const RETRYABLE_FS_CODES = new Set(["EBUSY", "EPERM"]);
|
|
28
25
|
const RETRYABLE_CONFIG_READ_CODES = new Set(["EBUSY", "EPERM", "EAGAIN"]);
|
|
29
26
|
/**
|
|
30
27
|
* Synchronous readFileSync with bounded retry on transient FS-lock codes.
|
|
@@ -330,212 +327,14 @@ function stripUtf8Bom(content) {
|
|
|
330
327
|
function isRecord(value) {
|
|
331
328
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
332
329
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
// same backoff, 5 attempts). ENOENT still returns null immediately. On
|
|
342
|
-
// exhaustion the last failure surfaces so the caller treats it as a real
|
|
343
|
-
// save error rather than a phantom missing file.
|
|
344
|
-
return withRetry(async () => {
|
|
345
|
-
try {
|
|
346
|
-
return (await fs.stat(filePath)).mtimeMs;
|
|
347
|
-
}
|
|
348
|
-
catch (error) {
|
|
349
|
-
if (error?.code === "ENOENT") {
|
|
350
|
-
return null;
|
|
351
|
-
}
|
|
352
|
-
throw error;
|
|
353
|
-
}
|
|
354
|
-
}, {
|
|
355
|
-
maxAttempts: 5,
|
|
356
|
-
backoffMs: (attempt) => 10 * 2 ** (attempt - 1),
|
|
357
|
-
retryableCodes: RETRYABLE_CONFIG_READ_CODES,
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
async function writeJsonFileAtomicWithRetry(filePath, payload, options) {
|
|
361
|
-
const tempPath = tempPathFor(filePath);
|
|
362
|
-
await fs.mkdir(dirname(filePath), { recursive: true });
|
|
363
|
-
await fs.writeFile(tempPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
364
|
-
let renamed = false;
|
|
365
|
-
try {
|
|
366
|
-
// Compare-and-swap guard: if a concurrent writer changed the target file
|
|
367
|
-
// since the caller read it (mtime mismatch), abort with ESTALE so the
|
|
368
|
-
// caller can re-read and merge instead of clobbering the other write.
|
|
369
|
-
if (options && "expectedMtimeMs" in options) {
|
|
370
|
-
const currentMtimeMs = await getConfigFileMtimeMs(filePath);
|
|
371
|
-
if (currentMtimeMs !== options.expectedMtimeMs) {
|
|
372
|
-
const staleError = new Error(`Config at ${filePath} changed on disk during save; retrying with latest state.`);
|
|
373
|
-
staleError.code = "ESTALE";
|
|
374
|
-
throw staleError;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
await withRetry(() => fs.rename(tempPath, filePath), {
|
|
378
|
-
maxAttempts: 5,
|
|
379
|
-
backoffMs: (attempt) => 10 * 2 ** (attempt - 1),
|
|
380
|
-
retryableCodes: RETRYABLE_FS_CODES,
|
|
381
|
-
});
|
|
382
|
-
renamed = true;
|
|
383
|
-
}
|
|
384
|
-
finally {
|
|
385
|
-
if (!renamed) {
|
|
386
|
-
try {
|
|
387
|
-
await fs.unlink(tempPath);
|
|
388
|
-
}
|
|
389
|
-
catch {
|
|
390
|
-
// Best-effort temp cleanup.
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
async function withConfigSaveLock(path, task) {
|
|
396
|
-
const previous = configSaveQueues.get(path) ?? Promise.resolve();
|
|
397
|
-
const queued = previous.catch(() => { }).then(task);
|
|
398
|
-
configSaveQueues.set(path, queued);
|
|
399
|
-
try {
|
|
400
|
-
await queued;
|
|
401
|
-
}
|
|
402
|
-
finally {
|
|
403
|
-
if (configSaveQueues.get(path) === queued) {
|
|
404
|
-
configSaveQueues.delete(path);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
// Cross-process config-save lock. withConfigSaveLock only serializes saves
|
|
409
|
-
// within THIS process (a per-path promise queue); it does nothing against a
|
|
410
|
-
// second process. The mtime CAS in writeJsonFileAtomicWithRetry narrows but does
|
|
411
|
-
// not close the read→check→merge→rename TOCTOU window (another process can still
|
|
412
|
-
// land a write between the CAS stat and the rename). This file lock provides the
|
|
413
|
-
// cross-process mutual exclusion that closes that window. It deliberately mirrors
|
|
414
|
-
// RefreshLeaseCoordinator (lib/refresh-lease.ts): exclusive `wx` lockfile create,
|
|
415
|
-
// JSON payload carrying pid + expiry, stale-takeover via expiry/mtime, and a
|
|
416
|
-
// best-effort retrying release in a finally. The mtime CAS stays as a second-line
|
|
417
|
-
// guard for any non-participating writer.
|
|
418
|
-
const CONFIG_LOCK_TTL_MS = 10_000;
|
|
419
|
-
const CONFIG_LOCK_WAIT_TIMEOUT_MS = 10_000;
|
|
420
|
-
const CONFIG_LOCK_POLL_MS = 50;
|
|
421
|
-
async function unlinkConfigLockWithRetry(lockPath) {
|
|
422
|
-
try {
|
|
423
|
-
await withRetry(() => fs.unlink(lockPath), {
|
|
424
|
-
maxAttempts: 5,
|
|
425
|
-
backoffMs: (attempt) => 10 * 2 ** (attempt - 1),
|
|
426
|
-
retryableCodes: RETRYABLE_FS_CODES,
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
catch {
|
|
430
|
-
// ENOENT (already released) or best-effort release failure: a leftover
|
|
431
|
-
// lockfile is recovered as stale by the next acquirer via its
|
|
432
|
-
// expiry/mtime, so never fail the save over this.
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
// Owner-safe release: only unlink the lockfile if it still carries OUR owner
|
|
436
|
-
// token. If a slow save was deemed stale and a second process stole the lock,
|
|
437
|
-
// the lockfile now holds the new owner's token — deleting it would reopen
|
|
438
|
-
// concurrent saves, so we leave it alone.
|
|
439
|
-
async function releaseConfigLockIfOwner(lockPath, owner) {
|
|
440
|
-
try {
|
|
441
|
-
const content = await fs.readFile(lockPath, "utf-8");
|
|
442
|
-
const parsed = JSON.parse(stripUtf8Bom(content));
|
|
443
|
-
if (parsed?.owner && parsed.owner !== owner) {
|
|
444
|
-
// Lock was taken over by another holder; do not delete their lock.
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
catch (error) {
|
|
449
|
-
const code = error?.code;
|
|
450
|
-
if (code === "ENOENT")
|
|
451
|
-
return;
|
|
452
|
-
// Unreadable/malformed: fall through and attempt our best-effort unlink.
|
|
453
|
-
}
|
|
454
|
-
await unlinkConfigLockWithRetry(lockPath);
|
|
455
|
-
}
|
|
456
|
-
async function isConfigLockStale(lockPath) {
|
|
457
|
-
try {
|
|
458
|
-
const content = await fs.readFile(lockPath, "utf-8");
|
|
459
|
-
const parsed = JSON.parse(stripUtf8Bom(content));
|
|
460
|
-
if (typeof parsed?.expiresAt === "number" &&
|
|
461
|
-
Number.isFinite(parsed.expiresAt)) {
|
|
462
|
-
return parsed.expiresAt <= Date.now();
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
catch (error) {
|
|
466
|
-
const code = error?.code;
|
|
467
|
-
if (code === "ENOENT")
|
|
468
|
-
return true;
|
|
469
|
-
// Unreadable/malformed payload: fall through to the mtime heuristic.
|
|
470
|
-
}
|
|
471
|
-
try {
|
|
472
|
-
const stat = await fs.stat(lockPath);
|
|
473
|
-
return Date.now() - stat.mtimeMs > CONFIG_LOCK_TTL_MS;
|
|
474
|
-
}
|
|
475
|
-
catch (error) {
|
|
476
|
-
const code = error?.code;
|
|
477
|
-
if (code === "ENOENT")
|
|
478
|
-
return true;
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
async function withConfigFileLock(targetPath, task) {
|
|
483
|
-
const lockPath = `${targetPath}.lock`;
|
|
484
|
-
const owner = randomUUID();
|
|
485
|
-
await fs.mkdir(dirname(lockPath), { recursive: true });
|
|
486
|
-
const deadline = Date.now() + CONFIG_LOCK_WAIT_TIMEOUT_MS;
|
|
487
|
-
let acquired = false;
|
|
488
|
-
while (!acquired) {
|
|
489
|
-
try {
|
|
490
|
-
const now = Date.now();
|
|
491
|
-
const payload = {
|
|
492
|
-
pid: process.pid,
|
|
493
|
-
owner,
|
|
494
|
-
acquiredAt: now,
|
|
495
|
-
expiresAt: now + CONFIG_LOCK_TTL_MS,
|
|
496
|
-
};
|
|
497
|
-
const handle = await fs.open(lockPath, "wx", 0o600);
|
|
498
|
-
try {
|
|
499
|
-
await handle.writeFile(`${JSON.stringify(payload)}\n`, "utf8");
|
|
500
|
-
}
|
|
501
|
-
finally {
|
|
502
|
-
await handle.close();
|
|
503
|
-
}
|
|
504
|
-
acquired = true;
|
|
505
|
-
}
|
|
506
|
-
catch (error) {
|
|
507
|
-
const code = error?.code;
|
|
508
|
-
if (code !== "EEXIST") {
|
|
509
|
-
// A transient FS lock on the lockfile itself: retry until the deadline,
|
|
510
|
-
// matching the bounded backoff used elsewhere on the Windows save path.
|
|
511
|
-
if (typeof code === "string" &&
|
|
512
|
-
RETRYABLE_FS_CODES.has(code) &&
|
|
513
|
-
Date.now() < deadline) {
|
|
514
|
-
await sleep(CONFIG_LOCK_POLL_MS);
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
throw error;
|
|
518
|
-
}
|
|
519
|
-
// Lock is held. Take it over if the holder expired/crashed; otherwise wait.
|
|
520
|
-
if (await isConfigLockStale(lockPath)) {
|
|
521
|
-
await unlinkConfigLockWithRetry(lockPath);
|
|
522
|
-
continue;
|
|
523
|
-
}
|
|
524
|
-
if (Date.now() >= deadline) {
|
|
525
|
-
const timeoutError = new Error(`Timed out acquiring config save lock at ${lockPath}.`);
|
|
526
|
-
timeoutError.code = "ELOCKTIMEOUT";
|
|
527
|
-
throw timeoutError;
|
|
528
|
-
}
|
|
529
|
-
await sleep(CONFIG_LOCK_POLL_MS);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
try {
|
|
533
|
-
return await task();
|
|
534
|
-
}
|
|
535
|
-
finally {
|
|
536
|
-
await releaseConfigLockIfOwner(lockPath, owner);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
330
|
+
// Cross-process save safety lives in lib/storage/json-store-lock.ts:
|
|
331
|
+
// withJsonStoreWriteQueue (per-path in-process queue), withJsonStoreFileLock
|
|
332
|
+
// (candidate-directory lock + dead-owner recovery), and the mtime CAS
|
|
333
|
+
// trio (getJsonStoreFileMtimeMs / writeJsonStoreFileAtomicWithRetry /
|
|
334
|
+
// withJsonStoreCasRetry). The file lock provides the cross-process mutual
|
|
335
|
+
// exclusion that closes the read→check→merge→rename TOCTOU window against
|
|
336
|
+
// OTHER processes; the mtime CAS stays on as a second-line guard for any
|
|
337
|
+
// non-participating writer.
|
|
539
338
|
/**
|
|
540
339
|
* Read and parse a JSON configuration file and return its top-level object when present and valid.
|
|
541
340
|
*
|
|
@@ -718,19 +517,19 @@ export async function savePluginConfig(configPatch) {
|
|
|
718
517
|
}
|
|
719
518
|
const envPath = (process.env.CODEX_MULTI_AUTH_CONFIG_PATH ?? "").trim();
|
|
720
519
|
if (envPath.length > 0) {
|
|
721
|
-
await
|
|
520
|
+
await withJsonStoreWriteQueue(envPath, async () => {
|
|
722
521
|
// In-process queue (above) is the cheap fast path; the cross-process file
|
|
723
522
|
// lock (below) closes the read→merge→rename TOCTOU window against OTHER
|
|
724
523
|
// processes. Acquire the file lock for the full critical section, then run
|
|
725
524
|
// the same mtime CAS retry as a second-line guard for any non-participating
|
|
726
525
|
// writer. Mirrors the unified-settings save path (writeSettingsRecordAsync
|
|
727
526
|
// CAS).
|
|
728
|
-
await
|
|
527
|
+
await withJsonStoreFileLock(envPath, async () => {
|
|
729
528
|
// CAS retry: ESTALE means the file's mtime moved between our stat and
|
|
730
529
|
// the write, so each attempt re-stats, re-reads, and re-merges against
|
|
731
530
|
// the latest on-disk state before writing again.
|
|
732
|
-
await
|
|
733
|
-
const expectedMtimeMs = await
|
|
531
|
+
await withJsonStoreCasRetry(async () => {
|
|
532
|
+
const expectedMtimeMs = await getJsonStoreFileMtimeMs(envPath);
|
|
734
533
|
const envConfigState = await readConfigRecordForSave(envPath);
|
|
735
534
|
if (envConfigState.status === "unreadable") {
|
|
736
535
|
throw unreadableConfigSaveError(envPath, envConfigState.errorMessage);
|
|
@@ -742,39 +541,45 @@ export async function savePluginConfig(configPatch) {
|
|
|
742
541
|
...(existingConfig ?? {}),
|
|
743
542
|
...sanitizedPatch,
|
|
744
543
|
};
|
|
745
|
-
await
|
|
544
|
+
await writeJsonStoreFileAtomicWithRetry(envPath, merged, {
|
|
746
545
|
expectedMtimeMs,
|
|
747
546
|
});
|
|
748
|
-
}
|
|
547
|
+
});
|
|
749
548
|
});
|
|
750
549
|
});
|
|
751
550
|
return;
|
|
752
551
|
}
|
|
753
552
|
const unifiedPath = getUnifiedSettingsPath();
|
|
754
|
-
await
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
553
|
+
await withJsonStoreWriteQueue(unifiedPath, async () => {
|
|
554
|
+
// Hold the same cross-process lockfile for the read→merge portion, not
|
|
555
|
+
// just the write: saveUnifiedPluginConfig re-acquires both primitives
|
|
556
|
+
// re-entrantly inside this critical section, so the merged pluginConfig
|
|
557
|
+
// cannot interleave with another process's write to the same file.
|
|
558
|
+
await withJsonStoreFileLock(unifiedPath, async () => {
|
|
559
|
+
const unifiedConfigState = await readConfigRecordForSave(unifiedPath);
|
|
560
|
+
if (unifiedConfigState.status === "unreadable") {
|
|
561
|
+
throw unreadableConfigSaveError(unifiedPath, unifiedConfigState.errorMessage);
|
|
562
|
+
}
|
|
563
|
+
const unifiedConfigRecord = unifiedConfigState.status === "ok"
|
|
564
|
+
? unifiedConfigState.record.pluginConfig
|
|
565
|
+
: loadUnifiedPluginConfigSync();
|
|
566
|
+
const unifiedConfig = sanitizeStoredPluginConfigRecord(unifiedConfigRecord);
|
|
567
|
+
const legacyPath = unifiedConfig === null ? resolvePluginConfigPath() : null;
|
|
568
|
+
const legacyConfigState = legacyPath
|
|
569
|
+
? await readConfigRecordForSave(legacyPath)
|
|
570
|
+
: null;
|
|
571
|
+
if (legacyConfigState?.status === "unreadable") {
|
|
572
|
+
throw unreadableConfigSaveError(legacyPath, legacyConfigState.errorMessage);
|
|
573
|
+
}
|
|
574
|
+
const legacyConfig = legacyConfigState?.status === "ok"
|
|
575
|
+
? sanitizeStoredPluginConfigRecord(legacyConfigState.record)
|
|
576
|
+
: null;
|
|
577
|
+
const merged = {
|
|
578
|
+
...(unifiedConfig ?? legacyConfig ?? {}),
|
|
579
|
+
...sanitizedPatch,
|
|
580
|
+
};
|
|
581
|
+
await saveUnifiedPluginConfig(merged);
|
|
582
|
+
});
|
|
778
583
|
});
|
|
779
584
|
}
|
|
780
585
|
function parseNumberEnv(value) {
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -22,4 +22,3 @@ export interface EffectiveContextWindow {
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function getEffectiveContextWindow(model: string | null | undefined, overrides: Record<string, number> | undefined): EffectiveContextWindow | null;
|
|
24
24
|
export declare function listEstimatedModelContextWindows(): Record<string, number>;
|
|
25
|
-
//# sourceMappingURL=model-context-windows.d.ts.map
|
|
@@ -22,4 +22,3 @@ export declare function createContextBudgetPauseResponse(advisory: Extract<Conte
|
|
|
22
22
|
export declare function buildContextBudgetHeaders(advisory: Extract<ContextBudgetAdvisory, {
|
|
23
23
|
level: "soft" | "hard";
|
|
24
24
|
}>): Record<string, string>;
|
|
25
|
-
//# sourceMappingURL=context-budget-response.d.ts.map
|
|
@@ -17,14 +17,14 @@ function buildPauseMessage(advisory) {
|
|
|
17
17
|
const windowNote = advisory.windowSource === "override"
|
|
18
18
|
? "your configured window size"
|
|
19
19
|
: "an estimated window size (unverified — set `contextBudgetGuardModelWindowOverrides` if you know the real limit)";
|
|
20
|
-
return `[Plugin Notice] Context budget guard paused this session at ${formatPercent(advisory.percent)}% of ${windowNote} for \`${advisory.model}\`, before hitting the model's actual limit.
|
|
21
|
-
|
|
22
|
-
Please use one of these commands to reduce context size:
|
|
23
|
-
|
|
24
|
-
• **/compact** - Compress conversation history (recommended)
|
|
25
|
-
• **/clear** - Start fresh with empty context
|
|
26
|
-
• **/undo** - Remove recent messages
|
|
27
|
-
|
|
20
|
+
return `[Plugin Notice] Context budget guard paused this session at ${formatPercent(advisory.percent)}% of ${windowNote} for \`${advisory.model}\`, before hitting the model's actual limit.
|
|
21
|
+
|
|
22
|
+
Please use one of these commands to reduce context size:
|
|
23
|
+
|
|
24
|
+
• **/compact** - Compress conversation history (recommended)
|
|
25
|
+
• **/clear** - Start fresh with empty context
|
|
26
|
+
• **/undo** - Remove recent messages
|
|
27
|
+
|
|
28
28
|
Then retry your request. This pause clears itself automatically once your context usage drops back below the threshold.`;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
@@ -33,16 +33,16 @@ export function isContextOverflowError(status, bodyText) {
|
|
|
33
33
|
/**
|
|
34
34
|
* The message shown to users when context overflow occurs
|
|
35
35
|
*/
|
|
36
|
-
const CONTEXT_OVERFLOW_MESSAGE = `[Plugin Notice] Context is too long for this model.
|
|
37
|
-
|
|
38
|
-
Please use one of these commands to reduce context size:
|
|
39
|
-
|
|
40
|
-
• **/compact** - Compress conversation history (recommended)
|
|
41
|
-
• **/clear** - Start fresh with empty context
|
|
42
|
-
• **/undo** - Remove recent messages
|
|
43
|
-
|
|
44
|
-
Then retry your request.
|
|
45
|
-
|
|
36
|
+
const CONTEXT_OVERFLOW_MESSAGE = `[Plugin Notice] Context is too long for this model.
|
|
37
|
+
|
|
38
|
+
Please use one of these commands to reduce context size:
|
|
39
|
+
|
|
40
|
+
• **/compact** - Compress conversation history (recommended)
|
|
41
|
+
• **/clear** - Start fresh with empty context
|
|
42
|
+
• **/undo** - Remove recent messages
|
|
43
|
+
|
|
44
|
+
Then retry your request.
|
|
45
|
+
|
|
46
46
|
Alternatively, you can switch to a model with a larger context window.`;
|
|
47
47
|
/**
|
|
48
48
|
* Creates a synthetic SSE response for context overflow errors.
|