@bitkyc08/opencodex 2.84.0 → 2.87.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/README.md +0 -4
- package/bin/ocx.mjs +61 -3
- package/gui/dist/assets/App-ZfYbLHkB.js +58 -0
- package/gui/dist/assets/App-wT3mXqFz.css +1 -0
- package/gui/dist/assets/{Tray-C9TGtwad.js → Tray-DCd-A1az.js} +1 -1
- package/gui/dist/assets/index-CfYDMj34.js +94 -0
- package/gui/dist/assets/index-DPeB9HpV.css +1 -0
- package/gui/dist/assets/quota-summary-ChvmKGOk.js +1 -0
- package/gui/dist/index.html +2 -2
- package/package.json +1 -2
- package/src/adapters/anthropic/beta-allowlist.ts +91 -11
- package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
- package/src/adapters/anthropic/client-identity.ts +1 -1
- package/src/adapters/anthropic/passthrough.ts +16 -3
- package/src/adapters/anthropic-progress.ts +84 -0
- package/src/adapters/anthropic.ts +108 -21
- package/src/adapters/azure.ts +19 -1
- package/src/adapters/base.ts +2 -0
- package/src/adapters/claude-cli/adapter.ts +111 -23
- package/src/adapters/claude-cli/profiles.ts +2 -1
- package/src/adapters/claude-cli/stable-replay.ts +108 -0
- package/src/adapters/claude-cli/usage-admission.ts +230 -0
- package/src/adapters/client-fingerprint.ts +24 -0
- package/src/adapters/coding-agent/protocol.ts +1 -1
- package/src/adapters/coding-agent/turn.ts +40 -11
- package/src/adapters/cursor/arg-codec.ts +17 -5
- package/src/adapters/cursor/catalog.ts +8 -0
- package/src/adapters/cursor/effort-map.ts +3 -0
- package/src/adapters/cursor/freeform-args.ts +75 -0
- package/src/adapters/cursor/protobuf-events.ts +36 -23
- package/src/adapters/dsh-account.ts +97 -0
- package/src/adapters/google-antigravity-wire.ts +22 -1
- package/src/adapters/google.ts +37 -10
- package/src/adapters/openai-chat/messages.ts +4 -3
- package/src/adapters/openai-chat/passthrough.ts +8 -2
- package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
- package/src/adapters/openai-chat/response-events.ts +59 -1
- package/src/adapters/openai-chat.ts +8 -5
- package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
- package/src/adapters/openai-responses/passthrough.ts +57 -125
- package/src/adapters/openai-responses/request-strips.ts +25 -3
- package/src/adapters/openai-responses/transport.ts +81 -0
- package/src/adapters/qoder/adapter.ts +44 -3
- package/src/adapters/registry.ts +5 -0
- package/src/adapters/zed.ts +26 -1
- package/src/advisor/activity.ts +55 -0
- package/src/advisor/budget.ts +62 -0
- package/src/advisor/consult.ts +223 -0
- package/src/advisor/context.ts +238 -0
- package/src/advisor/disclosure.ts +20 -0
- package/src/advisor/evidence-tool.ts +21 -0
- package/src/advisor/evidence.ts +117 -0
- package/src/advisor/runtime.ts +353 -0
- package/src/advisor/settings.ts +144 -0
- package/src/advisor/state.ts +369 -0
- package/src/advisor/synthetic-tool.ts +33 -0
- package/src/bridge/errors.ts +24 -1
- package/src/bridge/internal.ts +3 -1
- package/src/bridge/response-json.ts +18 -3
- package/src/bridge/sse.ts +58 -8
- package/src/bridge/terminal-refusal.ts +59 -0
- package/src/chat/inbound.ts +30 -6
- package/src/chat/outbound.ts +5 -0
- package/src/claude/desktop-3p-library.ts +72 -7
- package/src/claude/desktop-3p.ts +75 -19
- package/src/claude/desktop-first-party.ts +1 -1
- package/src/claude/desktop-picker-platform.ts +4 -0
- package/src/claude/desktop-picker-profile.ts +11 -4
- package/src/claude/desktop-picker.ts +15 -8
- package/src/claude/desktop-profile.ts +10 -1
- package/src/claude/desktop-remote-store-io.ts +5 -3
- package/src/claude/desktop-system-proxy.ts +50 -4
- package/src/claude/inbound-content-options.ts +11 -0
- package/src/claude/inbound.ts +154 -50
- package/src/claude/intercept/local-ca.ts +8 -1
- package/src/claude/intercept/picker-ca-startup.ts +2 -1
- package/src/claude/intercept/picker-runtime.ts +6 -5
- package/src/claude/intercept/picker-trust-windows.ts +338 -0
- package/src/claude/intercept/picker-trust.ts +19 -0
- package/src/claude/intercept/port-policy.ts +30 -0
- package/src/claude/intercept/runtime.ts +97 -94
- package/src/claude/model-default-settings.ts +154 -0
- package/src/claude/model-info.ts +7 -7
- package/src/claude/outbound.ts +51 -19
- package/src/cli/account-api.ts +1 -0
- package/src/cli/account-policy-dto.ts +6 -0
- package/src/cli/account-policy.ts +34 -5
- package/src/cli/account-preservation.ts +44 -0
- package/src/cli/account.ts +8 -2
- package/src/cli/advisor.ts +165 -0
- package/src/cli/auxiliary-listener-preflight.ts +37 -0
- package/src/cli/capabilities-accounts.ts +20 -1
- package/src/cli/capabilities-agents-routing.ts +23 -2
- package/src/cli/capabilities-base.ts +39 -11
- package/src/cli/capabilities-observe-system.ts +63 -3
- package/src/cli/capabilities-provider-models.ts +11 -0
- package/src/cli/chatgpt-command.ts +35 -14
- package/src/cli/claude.ts +46 -6
- package/src/cli/codex-cli-update.ts +151 -41
- package/src/cli/codex-provider.ts +44 -0
- package/src/cli/combo-input.ts +10 -1
- package/src/cli/combo-result.ts +1 -1
- package/src/cli/combo.ts +2 -1
- package/src/cli/cross-home-owner.ts +17 -14
- package/src/cli/dispatch.ts +30 -5
- package/src/cli/doctor.ts +15 -1
- package/src/cli/ensure-desktop-cold-start.ts +382 -0
- package/src/cli/export-command.ts +1 -1
- package/src/cli/help.ts +4 -2
- package/src/cli/index.ts +14 -5
- package/src/cli/integration-plan-dto.ts +3 -0
- package/src/cli/log-history.ts +172 -0
- package/src/cli/models-runtime-subcommands.ts +1 -0
- package/src/cli/models-runtime.ts +72 -8
- package/src/cli/observe-stream.ts +2 -0
- package/src/cli/observe.ts +16 -4
- package/src/cli/provider.ts +27 -5
- package/src/cli/registry.ts +41 -9
- package/src/cli/restart-scope.ts +3 -1
- package/src/cli/runtime-api.ts +5 -3
- package/src/cli/system-command.ts +40 -8
- package/src/cli/uninstall-client-state.ts +32 -0
- package/src/cli/usage-compare.ts +309 -0
- package/src/cli/usage-model-search.ts +4 -4
- package/src/cli/usage-report.ts +2 -2
- package/src/cli/v2.ts +1 -1
- package/src/client/machine-listener.ts +1 -3
- package/src/client/runtime.ts +1 -0
- package/src/clients/client-path.ts +51 -0
- package/src/clients/config-export/contracts.ts +3 -1
- package/src/clients/config-export/model-metadata.ts +3 -2
- package/src/clients/config-export/qoder.ts +93 -0
- package/src/clients/config-export.ts +35 -48
- package/src/clients/gentle-shell-path.ts +87 -0
- package/src/codex/account-auto-switch.ts +2 -0
- package/src/codex/account-identity.ts +29 -0
- package/src/codex/account-label.ts +1 -1
- package/src/codex/account-lifecycle.ts +21 -5
- package/src/codex/account-preservation.ts +28 -0
- package/src/codex/account-use-remaining.ts +23 -0
- package/src/codex/app-server-processes.ts +97 -7
- package/src/codex/app-server-restart-service.ts +55 -4
- package/src/codex/auth-api/account-list.ts +4 -0
- package/src/codex/auth-api/account-pause-group.ts +6 -50
- package/src/codex/auth-api/account-preservation.ts +57 -0
- package/src/codex/auth-api/pool-mode-gate.ts +5 -2
- package/src/codex/auth-api/routes.ts +8 -0
- package/src/codex/auth-api/use-remaining-route.ts +36 -0
- package/src/codex/auth-api.ts +0 -1
- package/src/codex/auth-context.ts +81 -7
- package/src/codex/autostart-health.ts +4 -0
- package/src/codex/catalog/auto-review.ts +20 -3
- package/src/codex/catalog/build-entries.ts +19 -2
- package/src/codex/catalog/combo-member.ts +14 -5
- package/src/codex/catalog/configured-tiers.ts +50 -0
- package/src/codex/catalog/effort.ts +4 -1
- package/src/codex/catalog/gather-capture.ts +2 -0
- package/src/codex/catalog/metadata.ts +11 -9
- package/src/codex/catalog/model-hints.ts +42 -19
- package/src/codex/catalog/model-visibility.ts +3 -1
- package/src/codex/catalog/native-ultrafast.ts +106 -0
- package/src/codex/catalog/parsing.ts +35 -86
- package/src/codex/catalog/provider-models.ts +40 -34
- package/src/codex/catalog/retained-sync.ts +2 -0
- package/src/codex/catalog/routed-gather.ts +33 -16
- package/src/codex/catalog/vendor-context.ts +82 -0
- package/src/codex/cli-install-provenance.ts +105 -17
- package/src/codex/cli-update-plan.ts +545 -0
- package/src/codex/config-write-lock.ts +63 -4
- package/src/codex/convergence.ts +2 -0
- package/src/codex/desktop-app/picker-freshness.ts +96 -0
- package/src/codex/desktop-app/types.ts +2 -0
- package/src/codex/desktop-app/windows.ts +29 -16
- package/src/codex/desktop-app-restart.ts +25 -2
- package/src/codex/desktop-compatibility/certificate-service.ts +99 -0
- package/src/codex/desktop-compatibility/certificate-store.ts +193 -0
- package/src/codex/desktop-compatibility/connection-store.ts +87 -0
- package/src/codex/desktop-compatibility/installed-build.ts +73 -0
- package/src/codex/desktop-compatibility/json-body.ts +29 -0
- package/src/codex/desktop-compatibility/native-identity.ts +62 -0
- package/src/codex/desktop-compatibility/relay-listener.ts +93 -0
- package/src/codex/desktop-compatibility/routing-binding.ts +10 -0
- package/src/codex/desktop-compatibility/routing-preflight.ts +69 -0
- package/src/codex/desktop-compatibility/runtime-ownership.ts +28 -0
- package/src/codex/desktop-compatibility/runtime.ts +182 -0
- package/src/codex/desktop-compatibility/service.ts +30 -0
- package/src/codex/desktop-compatibility/startup-settings.ts +50 -0
- package/src/codex/desktop-compatibility/usage-activation.ts +86 -0
- package/src/codex/desktop-compatibility/usage-controlled-fetch.ts +59 -0
- package/src/codex/desktop-compatibility/usage-controller.ts +107 -0
- package/src/codex/desktop-compatibility/usage-policy.ts +59 -0
- package/src/codex/desktop-compatibility/usage-refresh.ts +33 -0
- package/src/codex/desktop-compatibility/usage-sse-controller.ts +86 -0
- package/src/codex/desktop-compatibility/windows-activation-source.ts +44 -0
- package/src/codex/desktop-compatibility/windows-certificate-trust.ts +81 -0
- package/src/codex/desktop-compatibility/windows-key-protection.ts +165 -0
- package/src/codex/desktop-compatibility/windows-package-command.ts +86 -0
- package/src/codex/desktop-compatibility/windows-package-launch.ts +28 -0
- package/src/codex/features.ts +85 -45
- package/src/codex/history-provider.ts +1 -1
- package/src/codex/inject/config-write-section.ts +4 -1
- package/src/codex/inject/history-failure.ts +27 -0
- package/src/codex/inject/remove.ts +18 -6
- package/src/codex/inject/restore.ts +24 -2
- package/src/codex/inject/routing-classify.ts +4 -3
- package/src/codex/inject.ts +18 -27
- package/src/codex/journal.ts +16 -1
- package/src/codex/main-account-hard-lock.ts +30 -1
- package/src/codex/main-account.ts +99 -15
- package/src/codex/native-main-refresh-mode.ts +217 -0
- package/src/codex/native-profile-startup.ts +1 -1
- package/src/codex/ocx-compaction-history.ts +12 -10
- package/src/codex/paths.ts +86 -1
- package/src/codex/provider-routing.ts +174 -0
- package/src/codex/refresh.ts +2 -2
- package/src/codex/routing/health-store.ts +2 -2
- package/src/codex/routing/pool-recovery.ts +79 -0
- package/src/codex/routing/selection.ts +4 -3
- package/src/codex/routing/thread-affinity.ts +1 -1
- package/src/codex/shim-diagnostics.ts +6 -0
- package/src/codex/shim-overlay.ts +7 -2
- package/src/codex/signed-in-identity.ts +43 -0
- package/src/codex/subagent-model-fallback.ts +1 -1
- package/src/codex/sync.ts +6 -1
- package/src/codex/user-identity.ts +16 -5
- package/src/codex/windows-local-appdata.ts +84 -0
- package/src/combos/failover.ts +6 -1
- package/src/combos/index.ts +1 -0
- package/src/combos/resolve.ts +46 -10
- package/src/combos/types.ts +15 -0
- package/src/config/diagnostics.ts +35 -7
- package/src/config/live-reconcile.ts +51 -2
- package/src/config/load-degrade.ts +23 -1
- package/src/config/opencode-wire-upgrade.ts +54 -0
- package/src/config/opencode-zen-upgrade.ts +52 -0
- package/src/config/owner-registry.ts +22 -17
- package/src/config/paths.ts +10 -3
- package/src/config/provider-validation.ts +45 -2
- package/src/config/schema/config-schema.ts +39 -0
- package/src/config/schema/desktop-compatibility.ts +9 -0
- package/src/config/schema/leaf-validators.ts +39 -9
- package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
- package/src/config/schema/native-reasoning-retention.ts +26 -0
- package/src/config.ts +2 -0
- package/src/generated/compatibility-version.json +962 -350
- package/src/generated/model-metadata.ts +1 -1
- package/src/grok/sync.ts +1 -1
- package/src/images/loop.ts +46 -8
- package/src/integrations/catalog-refresh.ts +1 -1
- package/src/integrations/config-io.ts +20 -2
- package/src/integrations/journal.ts +15 -1
- package/src/integrations/mutation-plan.ts +2 -0
- package/src/integrations/registry.ts +15 -0
- package/src/integrations/store.ts +3 -0
- package/src/integrations/writer.ts +10 -1
- package/src/lib/advisor-activation.ts +16 -0
- package/src/lib/background-work.ts +65 -0
- package/src/lib/bounded-file-read.ts +58 -0
- package/src/lib/bun-path-runtime.d.mts +10 -1
- package/src/lib/bun-path-runtime.mjs +62 -3
- package/src/lib/codex-restart-contract.ts +15 -0
- package/src/lib/desktop-proxy-route.ts +30 -0
- package/src/lib/desktop-upstream-tunnel.ts +72 -0
- package/src/lib/empty-tool-catalog.ts +62 -0
- package/src/lib/errors.ts +26 -3
- package/src/lib/gcp-adc.ts +96 -9
- package/src/lib/gcp-credential-input.ts +12 -0
- package/src/lib/lab-live-route-production.ts +5 -0
- package/src/lib/local-internal-call-capability.ts +55 -0
- package/src/lib/opaque-proxy-tunnel.ts +217 -0
- package/src/lib/package-tree-integrity.ts +2 -2
- package/src/lib/redact.ts +2 -2
- package/src/lib/socks5-fetch.ts +48 -71
- package/src/lib/socks5-handshake.ts +112 -0
- package/src/lib/translator-budget.ts +7 -1
- package/src/oauth/account-quota-rank.ts +69 -2
- package/src/oauth/anthropic-account-refusal.ts +20 -2
- package/src/oauth/anthropic-oauth-definitions.ts +3 -1
- package/src/oauth/anthropic-routing.ts +1 -21
- package/src/oauth/anthropic.ts +38 -7
- package/src/oauth/callback-server.ts +27 -1
- package/src/oauth/chatgpt-device.ts +1 -1
- package/src/oauth/chatgpt-shared.ts +83 -0
- package/src/oauth/chatgpt.ts +8 -72
- package/src/oauth/dsh.ts +203 -0
- package/src/oauth/generic-account-failover.ts +62 -12
- package/src/oauth/generic-session-affinity.ts +125 -0
- package/src/oauth/index.ts +188 -111
- package/src/oauth/kiro-device-login.ts +2 -1
- package/src/oauth/kiro.ts +7 -1
- package/src/oauth/local-token-detect.ts +21 -1
- package/src/oauth/login-cli-errors.ts +44 -0
- package/src/oauth/login-cli.ts +69 -7
- package/src/oauth/login-flow-state.ts +371 -23
- package/src/oauth/meta-muse-errors.ts +41 -0
- package/src/oauth/meta-muse-keychain.ts +52 -0
- package/src/oauth/meta-muse.ts +51 -84
- package/src/oauth/model-discovery-auth.ts +3 -0
- package/src/oauth/pool-settings-capability.ts +4 -2
- package/src/oauth/refresh-flight-retirement.ts +48 -0
- package/src/oauth/session-affinity-key.ts +23 -0
- package/src/oauth/store-anthropic-instance.ts +9 -2
- package/src/oauth/store.ts +12 -5
- package/src/protocols/codecs/chat-ir.ts +467 -0
- package/src/protocols/codecs/chat.ts +10 -1
- package/src/protocols/codecs/messages-ir.ts +500 -0
- package/src/protocols/encoders/adapter-events.ts +5 -4
- package/src/protocols/encoders/messages.ts +9 -6
- package/src/protocols/features.ts +10 -2
- package/src/protocols/path.ts +11 -1
- package/src/protocols/plan-snapshot.ts +39 -16
- package/src/protocols/plan.ts +9 -1
- package/src/protocols/provider-summary.ts +2 -1
- package/src/protocols/settings.ts +8 -0
- package/src/providers/antigravity-account-roster.ts +102 -0
- package/src/providers/antigravity-models.ts +85 -7
- package/src/providers/api-key-cooldowns.ts +49 -0
- package/src/providers/api-key-resolve.ts +11 -6
- package/src/providers/api-key-response-ownership.ts +57 -0
- package/src/providers/api-key-selection.ts +31 -6
- package/src/providers/api-keys.ts +214 -3
- package/src/providers/claude-cli-usage.ts +96 -0
- package/src/providers/dsh-account-destination.ts +31 -0
- package/src/providers/dsh-account-models.ts +41 -0
- package/src/providers/gcp-credential-cleanup.ts +59 -0
- package/src/providers/key-failover.ts +54 -50
- package/src/providers/key-store.ts +7 -2
- package/src/providers/model-rename-fields.ts +5 -0
- package/src/providers/model-rename-migration.ts +7 -5
- package/src/providers/openai-tiers-destination.ts +11 -2
- package/src/providers/openai-tiers.ts +5 -12
- package/src/providers/opencode-go-transport.ts +3 -1
- package/src/providers/quota/account-cache.ts +6 -5
- package/src/providers/quota/account-row.ts +34 -0
- package/src/providers/quota/antigravity.ts +28 -7
- package/src/providers/quota/dsh-account.ts +70 -0
- package/src/providers/quota/vendor-probes-oauth.ts +1 -93
- package/src/providers/quota-types.ts +2 -0
- package/src/providers/quota.ts +14 -20
- package/src/providers/registry/entries-core.ts +44 -14
- package/src/providers/registry/entries-extended.ts +19 -0
- package/src/providers/registry/types.ts +1 -1
- package/src/providers/request-pacing.ts +77 -19
- package/src/providers/routed-config.ts +339 -0
- package/src/providers/service-tier.ts +2 -1
- package/src/quota/window-mapping.ts +5 -2
- package/src/responses/anthropic-progress.ts +34 -0
- package/src/responses/assistant-replay.ts +35 -0
- package/src/responses/compaction-history-framing.ts +65 -0
- package/src/responses/compaction.ts +6 -1
- package/src/responses/incomplete-reason.ts +31 -0
- package/src/responses/parser.ts +78 -22
- package/src/responses/reasoning-envelope.ts +4 -0
- package/src/responses/reasoning-replay-cache.ts +24 -2
- package/src/responses/reasoning-retention.ts +173 -0
- package/src/responses/retained-compaction.ts +46 -0
- package/src/responses/schema.ts +23 -0
- package/src/responses/state.ts +32 -29
- package/src/router.ts +8 -321
- package/src/routing/health.ts +37 -22
- package/src/routing/history/build-file.ts +92 -0
- package/src/routing/history/indexer.ts +254 -221
- package/src/routing/history/ingest.ts +242 -0
- package/src/routing/history/rebuild-job.ts +111 -0
- package/src/routing/history/rebuild-protocol.ts +15 -0
- package/src/routing/history/rebuild-worker.ts +34 -0
- package/src/routing/profile.ts +1 -1
- package/src/server/admission-model-scope.ts +21 -1
- package/src/server/antigravity-direct-eligibility.ts +208 -0
- package/src/server/auth-cors.ts +15 -0
- package/src/server/chat-completions.ts +82 -10
- package/src/server/chat-native-reasoning.ts +123 -0
- package/src/server/chat-native-sse.ts +110 -7
- package/src/server/chat-native.ts +76 -17
- package/src/server/claude-messages.ts +164 -433
- package/src/server/effort-policy.ts +1 -1
- package/src/server/images.ts +15 -2
- package/src/server/index/desktop-compatibility-startup.ts +56 -0
- package/src/server/index/model-alias-id.ts +36 -0
- package/src/server/index/optional-listeners.ts +2 -0
- package/src/server/index/serve-options.ts +11 -3
- package/src/server/index/startup-warnings.ts +11 -0
- package/src/server/index/websocket-handler.ts +9 -0
- package/src/server/index.ts +14 -11
- package/src/server/inference/advisor-diagnostics.ts +31 -0
- package/src/server/inference/client-encoder-delivery.ts +6 -5
- package/src/server/login-shell-path.ts +146 -0
- package/src/server/management/advisor-routes.ts +202 -0
- package/src/server/management/agent-settings-routes.ts +22 -4
- package/src/server/management/claude-desktop-picker-routes.ts +1 -1
- package/src/server/management/combo-routes.ts +176 -50
- package/src/server/management/companion-routes.ts +4 -0
- package/src/server/management/config-routes.ts +77 -6
- package/src/server/management/context.ts +4 -0
- package/src/server/management/cursor-integration-routes.ts +1 -1
- package/src/server/management/desktop-compatibility-routes.ts +46 -0
- package/src/server/management/desktop-compatibility-runtime-routes.ts +46 -0
- package/src/server/management/desktop-compatibility-settings-routes.ts +27 -0
- package/src/server/management/model-routes.ts +13 -8
- package/src/server/management/model-rows.ts +14 -0
- package/src/server/management/native-integration-routes.ts +2 -7
- package/src/server/management/native-reasoning-retention-routes.ts +41 -0
- package/src/server/management/oauth-account-routes.ts +87 -14
- package/src/server/management/protocol-settings-patch.ts +1 -0
- package/src/server/management/provider-gcp-credential-routes.ts +29 -0
- package/src/server/management/provider-key-pacing-routes.ts +31 -0
- package/src/server/management/provider-overwrite-carry.ts +7 -0
- package/src/server/management/provider-routes.ts +25 -30
- package/src/server/management/route-registry.ts +21 -1
- package/src/server/management/sibling-guard.ts +1 -0
- package/src/server/management-api.ts +9 -1
- package/src/server/messages-antigravity-direct.ts +195 -0
- package/src/server/messages-native-tool-guard.ts +185 -0
- package/src/server/messages-native.ts +106 -22
- package/src/server/messages-shared.ts +431 -0
- package/src/server/relay.ts +1 -1
- package/src/server/request-log-terminal-status.ts +1 -1
- package/src/server/request-log.ts +13 -1
- package/src/server/responses/account-change-state.ts +8 -2
- package/src/server/responses/adapter-continuation.ts +48 -19
- package/src/server/responses/adapter-delivery.ts +43 -8
- package/src/server/responses/adapter-dispatch.ts +48 -4
- package/src/server/responses/advisor-plan-slot.ts +27 -0
- package/src/server/responses/advisor-retention.ts +117 -0
- package/src/server/responses/advisor-slot.ts +368 -0
- package/src/server/responses/code-mode-collab-surface.ts +116 -8
- package/src/server/responses/codex-ws-wire.ts +15 -8
- package/src/server/responses/compact.ts +303 -125
- package/src/server/responses/compaction-recovery.ts +18 -10
- package/src/server/responses/compaction-retention.ts +61 -0
- package/src/server/responses/context-overflow.ts +11 -6
- package/src/server/responses/core-auth.ts +6 -0
- package/src/server/responses/core-codex-account.ts +11 -1
- package/src/server/responses/core-combo-failure.ts +12 -1
- package/src/server/responses/core-combo.ts +141 -36
- package/src/server/responses/core-errors.ts +3 -3
- package/src/server/responses/core-lifetime.ts +7 -2
- package/src/server/responses/core-normalize.ts +11 -0
- package/src/server/responses/core-opaque-recovery.ts +35 -0
- package/src/server/responses/core-options.ts +51 -0
- package/src/server/responses/core-pipeline.ts +141 -0
- package/src/server/responses/core-replay.ts +25 -6
- package/src/server/responses/core.ts +3 -116
- package/src/server/responses/fetch-helpers.ts +73 -19
- package/src/server/responses/main-hard-lock-routing.ts +109 -0
- package/src/server/responses/native-response-control.ts +4 -2
- package/src/server/responses/passthrough-delivery.ts +19 -11
- package/src/server/responses/passthrough-dispatch.ts +29 -16
- package/src/server/responses/request-prepare.ts +144 -17
- package/src/server/responses/request-sidecar-auth.ts +2 -2
- package/src/server/responses/request-transport.ts +120 -27
- package/src/server/responses/response-effects.ts +1 -0
- package/src/server/responses/run-turn-execution.ts +166 -38
- package/src/server/responses/sidecar-execution.ts +98 -5
- package/src/server/responses/terminal-guard.ts +4 -17
- package/src/server/responses-undeclared-tool-guard.ts +30 -9
- package/src/server/startup-action-control.ts +16 -2
- package/src/server/startup-health-cache.ts +1 -0
- package/src/service/auth-preflight.ts +71 -0
- package/src/service/cli.ts +4 -2
- package/src/service/definition.ts +97 -0
- package/src/service/desktop-startup.ts +14 -0
- package/src/service/guards.ts +1 -61
- package/src/service/health-sentinel-linux.ts +112 -0
- package/src/service/health-sentinel-main.ts +99 -61
- package/src/service/health-sentinel-probe.ts +24 -7
- package/src/service/health.ts +5 -89
- package/src/service/launchd.ts +27 -7
- package/src/service/logging.ts +135 -0
- package/src/service/repair.ts +2 -1
- package/src/service/state.ts +7 -8
- package/src/service/systemd.ts +1 -1
- package/src/service/windows-guarded-manager.ts +2 -1
- package/src/service/windows-ops.ts +1 -1
- package/src/service/windows-scheduler.ts +2 -7
- package/src/service/windows-taskxml.ts +2 -2
- package/src/service/windows-wscript.ts +14 -0
- package/src/service.ts +4 -2
- package/src/sidecar/auth.ts +2 -0
- package/src/tray/windows-tray.ps1 +43 -24
- package/src/types/config.ts +124 -6
- package/src/types/opencode-go.ts +61 -0
- package/src/types/opencode-zen.ts +29 -0
- package/src/types/provider.ts +39 -6
- package/src/types/request.ts +38 -2
- package/src/types/tools.ts +2 -0
- package/src/types/wire.ts +29 -37
- package/src/types.ts +1 -0
- package/src/update/async-check.ts +1 -1
- package/src/update/badge.ts +2 -2
- package/src/update/index.ts +88 -15
- package/src/update/job-supervised-restart.ts +107 -0
- package/src/update/job.ts +32 -32
- package/src/update/notify.ts +1 -1
- package/src/update/npm-invocation.mjs +12 -2
- package/src/update/refresh-scheduler.ts +2 -2
- package/src/update/supervised-recovery.d.mts +27 -0
- package/src/update/supervised-recovery.mjs +157 -0
- package/src/usage/cache-diagnostic.ts +2 -0
- package/src/usage/cost.ts +48 -12
- package/src/usage/expected-prices.ts +15 -0
- package/src/usage/ledger-retention.ts +2 -1
- package/src/usage/ledger-scanner.ts +6 -5
- package/src/usage/log.ts +17 -8
- package/src/usage/summary.ts +22 -9
- package/src/usage/user-cost-overlays.ts +14 -19
- package/src/usage/user-cost-validation.ts +38 -0
- package/src/vision/eligibility.ts +13 -0
- package/src/web-search/gemini-executor.ts +2 -2
- package/src/web-search/loop.ts +55 -5
- package/src/web-search/progress-stream.ts +4 -1
- package/src/web-search/run-turn-loop.ts +9 -1
- package/assets/sponsors/packycode.png +0 -0
- package/gui/dist/assets/App-CSJvmjNs.css +0 -1
- package/gui/dist/assets/App-CZtqiGcw.js +0 -56
- package/gui/dist/assets/index-BB6uK6tU.css +0 -1
- package/gui/dist/assets/index-CTm4l-HQ.js +0 -94
- package/gui/dist/assets/quota-summary-BbEeRfPY.js +0 -1
|
@@ -23,12 +23,17 @@ import {
|
|
|
23
23
|
import {
|
|
24
24
|
clearLoginState,
|
|
25
25
|
getLoginStatus,
|
|
26
|
+
isCodeLoginFlow,
|
|
26
27
|
isPublicOAuthProvider,
|
|
27
28
|
listOAuthProviders,
|
|
29
|
+
loginFlowAccountId,
|
|
28
30
|
OAUTH_PROVIDERS,
|
|
29
31
|
publicOAuthAuthenticationErrorMessage,
|
|
30
32
|
startLoginFlow,
|
|
33
|
+
submitLoginCode,
|
|
31
34
|
submitManualLoginCode,
|
|
35
|
+
supportsCodeLoginMode,
|
|
36
|
+
waitForLoginSettled,
|
|
32
37
|
} from "../../oauth";
|
|
33
38
|
import { OAuthMutationBusyError, removeCredential } from "../../oauth/store";
|
|
34
39
|
import { cancelKiroDeviceLogin, kiroDeviceConfigBaseline, startKiroDeviceLogin, statusKiroDeviceLogin, type KiroDeviceMethod } from "../../oauth/kiro-device-login";
|
|
@@ -253,9 +258,17 @@ export async function handleOauthAccountRoutes(ctx: ManagementContext): Promise<
|
|
|
253
258
|
// the provider's loopback callback server (inside this process) captures the redirect in the
|
|
254
259
|
// background, then the credential is persisted. The GUI opens the URL and polls /api/oauth/status.
|
|
255
260
|
if (url.pathname === "/api/oauth/login" && req.method === "POST") {
|
|
256
|
-
const body = await readManagementJsonBodyOr(req, {}) as { provider?: string; addAccount?: boolean; accountId?: string; reauth?: boolean; openBrowser?: unknown; method?: unknown };
|
|
261
|
+
const body = await readManagementJsonBodyOr(req, {}) as { provider?: string; addAccount?: boolean; accountId?: string; reauth?: boolean; openBrowser?: unknown; method?: unknown; mode?: unknown };
|
|
257
262
|
const provider = (body.provider ?? "").trim().toLowerCase();
|
|
258
263
|
if (!isPublicOAuthProvider(provider)) return jsonResponse({ error: "unknown oauth provider" }, 400);
|
|
264
|
+
// Omitted mode is the localhost-callback flow this route has always run.
|
|
265
|
+
if (body.mode !== undefined && body.mode !== "callback" && body.mode !== "code") {
|
|
266
|
+
return jsonResponse({ error: "mode must be \"callback\" or \"code\"" }, 400);
|
|
267
|
+
}
|
|
268
|
+
const codeMode = body.mode === "code";
|
|
269
|
+
if (codeMode && !supportsCodeLoginMode(provider)) {
|
|
270
|
+
return jsonResponse({ error: "code_mode_unsupported" }, 400);
|
|
271
|
+
}
|
|
259
272
|
// Muse may import a local Keychain credential or start a device grant; add-account
|
|
260
273
|
// and reauth skip the import. All management login paths require the dashboard
|
|
261
274
|
// principal before credential acquisition. A raw token proves administration,
|
|
@@ -292,10 +305,15 @@ export async function handleOauthAccountRoutes(ctx: ManagementContext): Promise<
|
|
|
292
305
|
// request may already have mutated live config and yielded before its save.
|
|
293
306
|
const persistedBaseline = readConfigDiagnostics().config;
|
|
294
307
|
// addAccount / reauth forces a fresh browser identity (skips local-CLI token import).
|
|
295
|
-
|
|
308
|
+
// Only code mode gets a flow id: it is what a later paste is pinned to. The callback
|
|
309
|
+
// flow's lifecycle argument stays exactly as it was.
|
|
310
|
+
const flowId = codeMode ? randomUUID() : undefined;
|
|
311
|
+
const { url: authUrl, instructions, deviceCode, expiresAt } = await startLoginFlow(provider, {
|
|
296
312
|
forceLogin: body.addAccount === true || reauth,
|
|
297
313
|
...(accountId ? { reauthAccountId: accountId } : {}),
|
|
314
|
+
...(codeMode ? { codeMode: true } : {}),
|
|
298
315
|
}, {
|
|
316
|
+
...(flowId ? { flowId } : {}),
|
|
299
317
|
// startLoginFlow returns the authorization URL before background persistence completes.
|
|
300
318
|
// Three-way reconcile settled disk changes so a failed login cannot leave a provider
|
|
301
319
|
// live-only and an in-flight management mutation cannot be erased before it saves.
|
|
@@ -322,7 +340,13 @@ export async function handleOauthAccountRoutes(ctx: ManagementContext): Promise<
|
|
|
322
340
|
const { openUrl } = await import("../../lib/open-url");
|
|
323
341
|
browserLaunch = (await openUrl(authUrl)).status === "started" ? "started" : "failed";
|
|
324
342
|
}
|
|
325
|
-
return jsonResponse({
|
|
343
|
+
return jsonResponse({
|
|
344
|
+
url: authUrl,
|
|
345
|
+
instructions,
|
|
346
|
+
deviceCode,
|
|
347
|
+
browserLaunch,
|
|
348
|
+
...(codeMode ? { mode: "code", flowId, expiresAt } : {}),
|
|
349
|
+
});
|
|
326
350
|
} catch (err) {
|
|
327
351
|
if (err instanceof OAuthMutationBusyError) throw err;
|
|
328
352
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -347,25 +371,69 @@ export async function handleOauthAccountRoutes(ctx: ManagementContext): Promise<
|
|
|
347
371
|
return result ? jsonResponse(result) : jsonResponse({ error: "unknown login flow" }, 404);
|
|
348
372
|
}
|
|
349
373
|
const { cancelLoginFlow } = await import("../../oauth");
|
|
350
|
-
|
|
374
|
+
// Without a flow id this cancels the provider's newest in-flight login, which is what the
|
|
375
|
+
// single-user GUI has always meant by "Cancel". A host running concurrent code logins for
|
|
376
|
+
// several users passes the flowId it was given at /api/oauth/login.
|
|
377
|
+
const cancelled = cancelLoginFlow(provider, typeof body.flowId === "string" ? body.flowId : undefined);
|
|
351
378
|
return jsonResponse({ ok: true, cancelled });
|
|
352
379
|
}
|
|
353
380
|
|
|
354
381
|
// Manual fallback for browser OAuth: paste the final redirect URL (or authorization code)
|
|
355
382
|
// when the browser cannot reach the loopback callback (remote/SSH/blocked localhost).
|
|
383
|
+
//
|
|
384
|
+
// A code-display flow (started with mode:"code", or identified by its flowId) gets the
|
|
385
|
+
// richer contract instead: the paste is answered with the OUTCOME of the token exchange,
|
|
386
|
+
// not merely with "accepted". A hosted caller has one paste box and no second channel, so
|
|
387
|
+
// "accepted" is indistinguishable from "worked" to the person typing.
|
|
356
388
|
if (url.pathname === "/api/oauth/login/code" && req.method === "POST") {
|
|
357
|
-
const body = await readManagementJsonBodyOr(req, {}) as { provider?: string; input?: string; code?: string };
|
|
389
|
+
const body = await readManagementJsonBodyOr(req, {}) as { provider?: string; input?: string; code?: string; flowId?: unknown };
|
|
358
390
|
const provider = (body.provider ?? "").trim().toLowerCase();
|
|
359
391
|
if (!isPublicOAuthProvider(provider)) return jsonResponse({ error: "unknown oauth provider" }, 400);
|
|
360
392
|
const consentRequired = metaMuseConsentRequired(provider, principal);
|
|
361
393
|
if (consentRequired) return consentRequired;
|
|
394
|
+
const flowId = typeof body.flowId === "string" ? body.flowId : undefined;
|
|
395
|
+
const maskEmails = emailMaskingEnabled(config);
|
|
396
|
+
// Only a code flow of THIS provider gets the outcome-waiting contract; that flow is single-use,
|
|
397
|
+
// so at most one request ever waits on it. A flow id naming anything else (a callback flow,
|
|
398
|
+
// another provider's flow, nothing) has no code login to complete.
|
|
399
|
+
const codeFlow = isCodeLoginFlow(provider, flowId);
|
|
400
|
+
if (flowId !== undefined && !codeFlow) return jsonResponse({ ok: false, error: "no_pending_login" }, 409);
|
|
362
401
|
const input = typeof body.input === "string" ? body.input : typeof body.code === "string" ? body.code : "";
|
|
363
402
|
// Authorization responses are measured in hundreds of bytes; never accept the
|
|
364
403
|
// generic management-body allowance here.
|
|
365
|
-
if (input.length > 4096)
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
404
|
+
if (input.length > 4096) {
|
|
405
|
+
return codeFlow
|
|
406
|
+
? jsonResponse({ ok: false, error: "malformed_input" }, 400)
|
|
407
|
+
: jsonResponse({ error: "input too long" }, 400);
|
|
408
|
+
}
|
|
409
|
+
if (!codeFlow) {
|
|
410
|
+
const result = submitManualLoginCode(provider, input);
|
|
411
|
+
if (!result.ok) return jsonResponse({ error: result.error }, 409);
|
|
412
|
+
return jsonResponse({ ok: true });
|
|
413
|
+
}
|
|
414
|
+
const submitted = submitLoginCode(provider, input, flowId);
|
|
415
|
+
// Rejected before any token request: the flow stays alive so the user can paste again.
|
|
416
|
+
if (!submitted.ok) {
|
|
417
|
+
return jsonResponse({ ok: false, error: submitted.code }, submitted.code === "no_pending_login" ? 409 : 400);
|
|
418
|
+
}
|
|
419
|
+
// The exchange itself times out at 30s inside the provider client; this only has to
|
|
420
|
+
// outlast it so a hung socket surfaces as an answer rather than as a hung request.
|
|
421
|
+
// Pinned to the flow this paste actually landed in: with several code logins in flight for
|
|
422
|
+
// one provider, "the newest flow" by the time this resolves may be somebody else's.
|
|
423
|
+
const settled = await waitForLoginSettled(provider, 60_000, submitted.flowId);
|
|
424
|
+
const status = getLoginStatus(provider, maskEmails, submitted.flowId);
|
|
425
|
+
if (!settled) return jsonResponse({ ok: false, error: "provider_unreachable" }, 400);
|
|
426
|
+
if (status.error) {
|
|
427
|
+
const failure = status.errorCode ?? "invalid_or_expired_code";
|
|
428
|
+
return jsonResponse({ ok: false, error: failure }, failure === "no_pending_login" ? 409 : 400);
|
|
429
|
+
}
|
|
430
|
+
// A flow dropped while waiting (logout, clear) never completed, whatever the store now holds.
|
|
431
|
+
if (status.status !== "complete") return jsonResponse({ ok: false, error: "no_pending_login" }, 409);
|
|
432
|
+
// The account THIS flow wrote, which need not be the active one (reauth of an inactive account,
|
|
433
|
+
// or a concurrent login that finished later).
|
|
434
|
+
const savedId = loginFlowAccountId(provider, submitted.flowId);
|
|
435
|
+
const account = savedId === undefined ? undefined : status.accounts?.find(entry => entry.id === savedId);
|
|
436
|
+
return jsonResponse({ ok: true, ...(account ? { account: { id: account.id, email: account.email } } : {}) });
|
|
369
437
|
}
|
|
370
438
|
|
|
371
439
|
if (url.pathname === "/api/oauth/status" && req.method === "GET") {
|
|
@@ -597,10 +665,15 @@ export async function handleOauthAccountRoutes(ctx: ManagementContext): Promise<
|
|
|
597
665
|
// sticky limit is refused identically whichever pool is addressed.
|
|
598
666
|
let strategy: string | undefined;
|
|
599
667
|
if (fields.strategy !== undefined) {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
668
|
+
// reset-first is a Codex and generic strategy. The Anthropic runtime implements only
|
|
669
|
+
// quota, round-robin and fill-first, so that kind keeps refusing it rather than storing
|
|
670
|
+
// a strategy it would silently ignore.
|
|
671
|
+
const parsed = kind === "codex" ? parseCodexAccountPoolStrategy(fields.strategy)
|
|
672
|
+
: kind === "generic" ? parseGenericPoolStrategy(fields.strategy, provider)
|
|
673
|
+
: parseAccountPoolStrategy(fields.strategy);
|
|
674
|
+
if (parsed === null) return jsonResponse({ error: kind === "anthropic"
|
|
675
|
+
? "strategy must be one of: quota, round-robin, fill-first"
|
|
676
|
+
: `strategy must be one of: quota, round-robin, fill-first, reset-first${kind === "generic" && provider === "kiro" ? ", least-loaded" : ""}` }, 400);
|
|
604
677
|
strategy = parsed;
|
|
605
678
|
}
|
|
606
679
|
let stickyLimit: number | undefined;
|
|
@@ -754,7 +827,7 @@ export async function handleOauthAccountRoutes(ctx: ManagementContext): Promise<
|
|
|
754
827
|
if (body.strategy === null) delete next.strategy;
|
|
755
828
|
else {
|
|
756
829
|
const parsed = parseGenericPoolStrategy(body.strategy, provider);
|
|
757
|
-
if (parsed === null) return jsonResponse({ error: `strategy must be one of: quota, round-robin, fill-first${provider === "kiro" ? ", least-loaded" : ""}` }, 400);
|
|
830
|
+
if (parsed === null) return jsonResponse({ error: `strategy must be one of: quota, round-robin, fill-first, reset-first${provider === "kiro" ? ", least-loaded" : ""}` }, 400);
|
|
758
831
|
next.strategy = parsed;
|
|
759
832
|
}
|
|
760
833
|
}
|
|
@@ -31,6 +31,7 @@ export const PROTOCOL_ROLLOUT_KEYS = [
|
|
|
31
31
|
"managedMessagesNative",
|
|
32
32
|
"managedMessagesNativeOAuth",
|
|
33
33
|
"directEncoders",
|
|
34
|
+
"antigravityDirect",
|
|
34
35
|
"shadowPlan",
|
|
35
36
|
] as const satisfies readonly (keyof ProtocolRolloutSettings)[];
|
|
36
37
|
const ROLLOUT_KEYS = new Set<string>(PROTOCOL_ROLLOUT_KEYS);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { providerCredentialInputError } from "../../providers/api-keys";
|
|
2
|
+
import { commitProviderGcpCredentialRemoval } from "../../providers/gcp-credential-cleanup";
|
|
3
|
+
import { dropProviderCustomModels } from "../../providers/provider-id-rewrite";
|
|
4
|
+
import { forgetProviderContextCap } from "../../providers/context-cap";
|
|
5
|
+
import type { OcxConfig } from "../../types";
|
|
6
|
+
import { jsonResponse } from "../auth-cors";
|
|
7
|
+
|
|
8
|
+
/** Generic provider writes refuse credential JSON before any config mutation. */
|
|
9
|
+
export function providerGcpCredentialInputResponse(provider: { apiKey?: unknown; apiKeyPool?: unknown }): Response | null {
|
|
10
|
+
const error = providerCredentialInputError(provider);
|
|
11
|
+
return error ? jsonResponse({ error }, 400) : null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Keep marker capture, provider removal and persistence in one synchronous locked operation. */
|
|
15
|
+
export function removeProviderWithGcpCredentials(
|
|
16
|
+
config: OcxConfig,
|
|
17
|
+
name: string,
|
|
18
|
+
fallbackDefault: string | undefined,
|
|
19
|
+
save: (config: OcxConfig) => void,
|
|
20
|
+
): number {
|
|
21
|
+
return commitProviderGcpCredentialRemoval(config, name, () => {
|
|
22
|
+
if (fallbackDefault) config.defaultProvider = fallbackDefault;
|
|
23
|
+
delete config.providers[name];
|
|
24
|
+
const dropped = dropProviderCustomModels(config, name);
|
|
25
|
+
forgetProviderContextCap(config, name);
|
|
26
|
+
save(config);
|
|
27
|
+
return dropped;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { hasOwnProvider, isValidProviderName } from "../../config";
|
|
2
|
+
import { getKeyCooldownUntil } from "../../providers/key-failover";
|
|
3
|
+
import { providerRequestPacingStatus } from "../../providers/request-pacing";
|
|
4
|
+
import type { OcxProviderConfig } from "../../types";
|
|
5
|
+
import { jsonResponse } from "../auth-cors";
|
|
6
|
+
import type { ManagementContext } from "./context";
|
|
7
|
+
|
|
8
|
+
/** Read-only provider/key pacing diagnostics; configuration writes stay in the provider PATCH owner. */
|
|
9
|
+
export function handleProviderKeyPacingRoutes(
|
|
10
|
+
{ req, url, config }: Pick<ManagementContext, "req" | "url" | "config">,
|
|
11
|
+
): Response | null {
|
|
12
|
+
if (url.pathname !== "/api/provider-request-pacing" || req.method !== "GET") return null;
|
|
13
|
+
const statusFor = (name: string, provider: OcxProviderConfig) => {
|
|
14
|
+
const status = providerRequestPacingStatus(name, provider);
|
|
15
|
+
if (status.keys) status.keys = status.keys.map(row => ({ ...row, cooldownUntil: getKeyCooldownUntil(name, row.id) }));
|
|
16
|
+
return status;
|
|
17
|
+
};
|
|
18
|
+
const name = url.searchParams.get("name")?.trim();
|
|
19
|
+
if (name) {
|
|
20
|
+
if (!isValidProviderName(name) || !hasOwnProvider(config.providers, name)) {
|
|
21
|
+
return jsonResponse({ error: "unknown provider" }, 404);
|
|
22
|
+
}
|
|
23
|
+
return jsonResponse(statusFor(name, config.providers[name]!));
|
|
24
|
+
}
|
|
25
|
+
return jsonResponse(Object.fromEntries(
|
|
26
|
+
Object.entries(config.providers).map(([providerName, provider]) => [
|
|
27
|
+
providerName,
|
|
28
|
+
statusFor(providerName, provider),
|
|
29
|
+
]),
|
|
30
|
+
));
|
|
31
|
+
}
|
|
@@ -214,6 +214,13 @@ export function applyProviderCompatPatchFields(
|
|
|
214
214
|
else return { error: "preserveResponsesReasoningContent must be a boolean" };
|
|
215
215
|
touched = true;
|
|
216
216
|
}
|
|
217
|
+
if (Object.hasOwn(rawBody, "inferContextWindow")) {
|
|
218
|
+
const value = rawBody.inferContextWindow;
|
|
219
|
+
if (value === null) delete next.inferContextWindow;
|
|
220
|
+
else if (typeof value === "boolean") next.inferContextWindow = value;
|
|
221
|
+
else return { error: "inferContextWindow must be a boolean or null" };
|
|
222
|
+
touched = true;
|
|
223
|
+
}
|
|
217
224
|
if (Object.hasOwn(rawBody, "reasoningWireFormat")) {
|
|
218
225
|
const value = rawBody.reasoningWireFormat;
|
|
219
226
|
if (value === null) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { contextTierRecordConfigError, modelCapabilitiesConfigError, mergeModelCapabilities } from "../../config/provider-validation";
|
|
2
2
|
import { DECLARABLE_HOSTED_TOOL_TYPES } from "../../responses/hosted-tool-policy";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { cleanupRemovedGcpCredentials, providerGcpCredentialMarkers, snapshotProviderGcpCredentialMarkers } from "../../providers/gcp-credential-cleanup";
|
|
5
|
+
import { providerGcpCredentialInputResponse, removeProviderWithGcpCredentials } from "./provider-gcp-credential-routes";
|
|
4
6
|
import { readFileSync } from "node:fs";
|
|
5
7
|
import { isDeepStrictEqual } from "node:util";
|
|
6
8
|
import type { CatalogModel } from "../../codex/catalog";
|
|
@@ -78,7 +80,7 @@ import { cachedProviderQuotaIsExhausted } from "../../combos/resolve";
|
|
|
78
80
|
import { probeJevDecisionProvider } from "../../combos/jev";
|
|
79
81
|
import { comboDependsOnProviderRoute } from "./decision-model-validation";
|
|
80
82
|
import { clearKeyCooldowns, forgetApiKeyRotationCursor } from "../../providers/key-failover";
|
|
81
|
-
import {
|
|
83
|
+
import { handleProviderKeyPacingRoutes } from "./provider-key-pacing-routes";
|
|
82
84
|
import { CODEX_FORWARD_BASE_URL, isCanonicalOpenAiForwardProvider } from "../../providers/openai-tiers";
|
|
83
85
|
import { codexAccountNamespaceProviderCollisionError } from "../../codex/account-namespace-match";
|
|
84
86
|
import { clearThreadAccountMap } from "../../codex/routing";
|
|
@@ -853,7 +855,7 @@ function providerRoutingQuota(config: OcxConfig, name: string, now: number): Pro
|
|
|
853
855
|
|
|
854
856
|
// Removing search/MCP windows may leave only a timestamp. That is not inference evidence.
|
|
855
857
|
const percentages = [quota.fiveHourPercent, quota.weeklyPercent, quota.monthlyPercent,
|
|
856
|
-
...(quota.customWindows ?? []).map(window => window.percent)];
|
|
858
|
+
...(quota.customWindows ?? []).filter(window => window.modelId === undefined).map(window => window.percent)];
|
|
857
859
|
const hasPercentage = percentages.some(value => typeof value === "number" && Number.isFinite(value) && value >= 0);
|
|
858
860
|
const credits = quota.creditsUsd;
|
|
859
861
|
const hasCredits = credits !== undefined && Number.isFinite(credits.percent)
|
|
@@ -864,7 +866,7 @@ function providerRoutingQuota(config: OcxConfig, name: string, now: number): Pro
|
|
|
864
866
|
let validUntil = quota.updatedAt + PROVIDER_QUOTA_MAX_AGE_MS;
|
|
865
867
|
if (state === "exhausted") {
|
|
866
868
|
const resets = [quota.fiveHourResetAt, quota.weeklyResetAt, quota.monthlyResetAt,
|
|
867
|
-
...(quota.customWindows ?? []).map(window => window.resetAt)]
|
|
869
|
+
...(quota.customWindows ?? []).filter(window => window.modelId === undefined).map(window => window.resetAt)]
|
|
868
870
|
.filter((reset): reset is number => typeof reset === "number" && Number.isFinite(reset)
|
|
869
871
|
&& reset > now && reset < validUntil)
|
|
870
872
|
.sort((left, right) => left - right);
|
|
@@ -895,21 +897,8 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
895
897
|
});
|
|
896
898
|
}
|
|
897
899
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
if (name) {
|
|
901
|
-
if (!isValidProviderName(name) || !hasOwnProvider(config.providers, name)) {
|
|
902
|
-
return jsonResponse({ error: "unknown provider" }, 404);
|
|
903
|
-
}
|
|
904
|
-
return jsonResponse(providerRequestPacingStatus(name, config.providers[name]!));
|
|
905
|
-
}
|
|
906
|
-
return jsonResponse(Object.fromEntries(
|
|
907
|
-
Object.entries(config.providers).map(([providerName, provider]) => [
|
|
908
|
-
providerName,
|
|
909
|
-
providerRequestPacingStatus(providerName, provider),
|
|
910
|
-
]),
|
|
911
|
-
));
|
|
912
|
-
}
|
|
900
|
+
const keyPacingResponse = handleProviderKeyPacingRoutes(ctx);
|
|
901
|
+
if (keyPacingResponse) return keyPacingResponse;
|
|
913
902
|
|
|
914
903
|
if (url.pathname === "/api/providers" && req.method === "GET") {
|
|
915
904
|
return jsonResponse(Object.entries(config.providers).map(([name, p]) => ({
|
|
@@ -922,6 +911,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
922
911
|
requestPacing: p.requestPacing,
|
|
923
912
|
models: p.models ?? [],
|
|
924
913
|
contextWindow: p.contextWindow,
|
|
914
|
+
inferContextWindow: p.inferContextWindow,
|
|
925
915
|
modelContextWindows: p.modelContextWindows,
|
|
926
916
|
modelContextTiers: p.modelContextTiers,
|
|
927
917
|
modelCapabilities: p.modelCapabilities,
|
|
@@ -1073,6 +1063,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1073
1063
|
if (resolvedError) return jsonResponse({ error: resolvedError, code: "invalid_provider_destination" }, 400);
|
|
1074
1064
|
}
|
|
1075
1065
|
|
|
1066
|
+
let removedCredentials: string[] = [];
|
|
1076
1067
|
const outcome = mutatePersistedConfig<ProviderEditorMutationValue>(persisted => {
|
|
1077
1068
|
if (!isDeepStrictEqual(providerEditorConfigDTO(persisted), baselineResult.value)) {
|
|
1078
1069
|
return {
|
|
@@ -1095,6 +1086,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1095
1086
|
initializeProviderModelSelection(name, provider, undefined, candidate.config);
|
|
1096
1087
|
}
|
|
1097
1088
|
}
|
|
1089
|
+
removedCredentials = Object.values(persisted.providers).flatMap(providerGcpCredentialMarkers);
|
|
1098
1090
|
persisted.defaultProvider = candidate.config.defaultProvider;
|
|
1099
1091
|
persisted.providers = structuredClone(candidate.config.providers);
|
|
1100
1092
|
persisted.disabledModels = candidate.config.disabledModels;
|
|
@@ -1120,6 +1112,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1120
1112
|
return jsonResponse({ error: outcome.value.error, code: outcome.value.code }, outcome.value.status);
|
|
1121
1113
|
}
|
|
1122
1114
|
|
|
1115
|
+
cleanupRemovedGcpCredentials(removedCredentials);
|
|
1123
1116
|
adoptProviderEditorCandidate(config, outcome.value.config);
|
|
1124
1117
|
reconcileLiveStateStores();
|
|
1125
1118
|
refreshConfigDerivedRegistries(outcome.value.config);
|
|
@@ -1137,16 +1130,15 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1137
1130
|
return jsonResponse({ success: true, catalogRefresh });
|
|
1138
1131
|
}
|
|
1139
1132
|
|
|
1140
|
-
//
|
|
1141
|
-
// persists — existing providers' real keys are never round-tripped (unlike PUT /api/config,
|
|
1142
|
-
// which would re-save the masked keys from GET). Live routing picks it up immediately.
|
|
1133
|
+
// Provider POST merges directly; existing secrets never round-trip through masked DTOs.
|
|
1143
1134
|
if (url.pathname === "/api/providers" && req.method === "POST") {
|
|
1144
1135
|
let body: { name?: unknown; provider?: unknown; setDefault?: boolean };
|
|
1145
1136
|
try { body = await readManagementJsonBody(req); } catch (error) { rethrowManagementBodyTooLarge(error); return jsonResponse({ error: "invalid JSON body" }, 400); }
|
|
1146
1137
|
const name = typeof body.name === "string" ? body.name.trim() : "";
|
|
1147
1138
|
if (!isPlainRecord(body.provider)) return jsonResponse({ error: "provider must be a plain object" }, 400);
|
|
1148
|
-
|
|
1149
|
-
|
|
1139
|
+
const credentialResponse = providerGcpCredentialInputResponse(body.provider);
|
|
1140
|
+
if (credentialResponse) return credentialResponse;
|
|
1141
|
+
// Reject canonical-row clears before normalization hides their ownership.
|
|
1150
1142
|
if (name === "openai" && (Object.hasOwn(body.provider, "autoReviewModel") || Object.hasOwn(body.provider, "autoReviewModelOverrides"))) {
|
|
1151
1143
|
return jsonResponse({ error: "provider openai must not include autoReviewModel or autoReviewModelOverrides" }, 400);
|
|
1152
1144
|
}
|
|
@@ -1357,7 +1349,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1357
1349
|
const candidate = stripRegistryOnlyStaticHeaders(name, prov);
|
|
1358
1350
|
const previous = Object.getOwnPropertyDescriptor(config.providers, name);
|
|
1359
1351
|
const rollback = pinsOwned ? captureConfigTopLevelRollback(config, ["defaultProvider", "modelDiscovery", "disabledModels"]) : undefined;
|
|
1360
|
-
let validationError: string | undefined;
|
|
1352
|
+
let validationError: string | undefined, removedCredentials: string[] = [];
|
|
1361
1353
|
withConfigMutationLockSync(() => {
|
|
1362
1354
|
validationError = anthropicInstancePublicationError(name, candidate, config.providers[name]);
|
|
1363
1355
|
if (validationError) return;
|
|
@@ -1365,6 +1357,12 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1365
1357
|
if (submittedModelContextTiers && liveTiers) candidate.modelContextTiers = Object.assign(Object.create(null), liveTiers, candidate.modelContextTiers ?? {});
|
|
1366
1358
|
else if (!submittedModelContextTiers && liveTiers) candidate.modelContextTiers = { ...liveTiers };
|
|
1367
1359
|
else if (!submittedModelContextTiers) delete candidate.modelContextTiers;
|
|
1360
|
+
// Full forms omit the opt-in; preserve the latest value, including a concurrent clear.
|
|
1361
|
+
if (!Object.hasOwn(rawProvider, "inferContextWindow")) {
|
|
1362
|
+
const liveInference = config.providers[name]?.inferContextWindow;
|
|
1363
|
+
if (liveInference === undefined) delete candidate.inferContextWindow;
|
|
1364
|
+
else candidate.inferContextWindow = liveInference;
|
|
1365
|
+
}
|
|
1368
1366
|
const draft = { ...(registrationDraft ?? config), providers: { ...config.providers, [name]: candidate }, ...(body.setDefault === true ? { defaultProvider: name } : {}) };
|
|
1369
1367
|
const validation = validateConfigCandidate(draft); if (!validation.ok) { validationError = validation.error; return; }
|
|
1370
1368
|
try {
|
|
@@ -1375,6 +1373,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1375
1373
|
});
|
|
1376
1374
|
}
|
|
1377
1375
|
}
|
|
1376
|
+
removedCredentials = snapshotProviderGcpCredentialMarkers(name, config.providers[name]);
|
|
1378
1377
|
config.providers[name] = candidate;
|
|
1379
1378
|
if (body.setDefault === true) config.defaultProvider = name;
|
|
1380
1379
|
(deps.saveConfigPreservingClaudeCode ?? save)(config);
|
|
@@ -1388,6 +1387,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1388
1387
|
}
|
|
1389
1388
|
});
|
|
1390
1389
|
if (validationError !== undefined) return jsonResponse({ error: validationError }, 400);
|
|
1390
|
+
cleanupRemovedGcpCredentials(removedCredentials);
|
|
1391
1391
|
reconcileLiveStateStores();
|
|
1392
1392
|
if (prov.apiKey && prov.apiKeyPool) {
|
|
1393
1393
|
const { addProviderApiKey } = await import("../../providers/api-keys");
|
|
@@ -1848,12 +1848,7 @@ export async function handleProviderRoutes(ctx: ManagementContext): Promise<Resp
|
|
|
1848
1848
|
const { saveConfigPreservingClaudeCode: save } = await import("../../config");
|
|
1849
1849
|
// Deleting still succeeds; the response names the shadow-call target left without a provider.
|
|
1850
1850
|
const shadowDependency = shadowInterceptProviderDependency(config, name);
|
|
1851
|
-
|
|
1852
|
-
delete config.providers[name];
|
|
1853
|
-
const { dropProviderCustomModels } = await import("../../providers/provider-id-rewrite");
|
|
1854
|
-
const droppedCustomModels = dropProviderCustomModels(config, name);
|
|
1855
|
-
forgetProviderContextCap(config, name);
|
|
1856
|
-
save(config);
|
|
1851
|
+
const droppedCustomModels = removeProviderWithGcpCredentials(config, name, fallbackDefault, save);
|
|
1857
1852
|
await replaceProviderAccountSet(name, null);
|
|
1858
1853
|
reconcileLiveStateStores();
|
|
1859
1854
|
const { clearModelCache: clearCache } = await import("../../codex/model-cache");
|
|
@@ -97,8 +97,12 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
97
97
|
// server/management-api
|
|
98
98
|
{ method: "POST", path: "/api/stop", module: "server/management-api", mutates: true },
|
|
99
99
|
// codex/auth-api
|
|
100
|
+
{ method: "GET", path: "/api/codex-auth/preserve-signed-in", module: "codex/auth-api/routes", mutates: false },
|
|
101
|
+
{ method: "PUT", path: "/api/codex-auth/preserve-signed-in", module: "codex/auth-api/routes", mutates: true },
|
|
100
102
|
{ method: "DELETE", path: "/api/codex-auth/accounts", module: "codex/auth-api/routes", mutates: true },
|
|
101
103
|
{ method: "GET", path: "/api/codex-auth/accounts", module: "codex/auth-api/routes", mutates: false },
|
|
104
|
+
{ method: "GET", path: "/api/codex-auth/accounts/use-remaining", module: "codex/auth-api/routes", mutates: false },
|
|
105
|
+
{ method: "PUT", path: "/api/codex-auth/accounts/use-remaining", module: "codex/auth-api/routes", mutates: true },
|
|
102
106
|
{ method: "GET", path: "/api/codex-auth/active", module: "codex/auth-api/routes", mutates: false },
|
|
103
107
|
{ method: "GET", path: "/api/codex-auth/login-status", module: "codex/auth-api/routes", mutates: false },
|
|
104
108
|
{ method: "GET", path: "/api/codex-auth/quota", module: "codex/auth-api/routes", mutates: false },
|
|
@@ -139,6 +143,8 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
139
143
|
{ method: "POST", path: "/api/native-main-profiles/switch", module: "codex/native-profile-api", mutates: true },
|
|
140
144
|
// server/management/agent-settings-routes
|
|
141
145
|
{ method: "GET", path: "/api/claude-code", module: "server/management/agent-settings-routes", mutates: false },
|
|
146
|
+
{ method: "GET", path: "/api/claude-code/model-defaults", module: "server/management/agent-settings-routes", mutates: false, exempt: { reason: "interactive-preview", why: "Preview half of the GUI-only Claude Code tier-default apply; the fingerprint it returns is the only input POST accepts, and no terminal confirmation workflow exists yet." } },
|
|
147
|
+
{ method: "POST", path: "/api/claude-code/model-defaults", module: "server/management/agent-settings-routes", mutates: true, exempt: { reason: "interactive-preview", why: "Apply half of the GUI-only Claude Code tier-default preview; it writes the shared Claude settings only for a fingerprint the dashboard preview produced." } },
|
|
142
148
|
{ method: "GET", path: "/api/claude-desktop", module: "server/management/agent-settings-routes", mutates: false },
|
|
143
149
|
{ method: "GET", path: "/api/claude-desktop/status", module: "server/management/agent-settings-routes", mutates: false },
|
|
144
150
|
{ method: "GET", path: "/api/codex-auth/features/default-mode-request-user-input", module: "server/management/agent-settings-routes", mutates: false },
|
|
@@ -163,6 +169,12 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
163
169
|
// server/management/claude-desktop-picker-routes
|
|
164
170
|
{ method: "GET", path: "/api/claude-desktop/picker", module: "server/management/claude-desktop-picker-routes", mutates: false },
|
|
165
171
|
{ method: "PUT", path: "/api/claude-desktop/picker", module: "server/management/claude-desktop-picker-routes", mutates: true },
|
|
172
|
+
{ method: "GET", path: "/api/codex/desktop-compatibility/certificate", module: "server/management/desktop-compatibility-routes", mutates: false, mechanism: "path-constant", exempt: { reason: "deferred-verb", owner: "codex-desktop-compatibility", ownerDoc: "structure/clients/codex-desktop.md", why: "Certificate status is available over authenticated HTTP while the desktop compatibility runtime/CLI status contract is integrated." } },
|
|
173
|
+
{ method: "POST", path: "/api/codex/desktop-compatibility/certificate", module: "server/management/desktop-compatibility-routes", mutates: true, mechanism: "path-constant", exempt: { reason: "session-only", why: "Certificate setup requires a confirmed local dashboard session; raw admin tokens cannot enroll or remove OS trust." } },
|
|
174
|
+
{ method: "GET", path: "/api/codex/desktop-compatibility/runtime", module: "server/management/desktop-compatibility-runtime-routes", mutates: false, mechanism: "path-constant", exempt: { reason: "deferred-verb", owner: "codex-desktop-compatibility", ownerDoc: "structure/clients/codex-desktop.md", why: "Experimental runtime status is authenticated HTTP while the native compatibility UI and CLI contract are integrated." } },
|
|
175
|
+
{ method: "POST", path: "/api/codex/desktop-compatibility/runtime", module: "server/management/desktop-compatibility-runtime-routes", mutates: true, mechanism: "path-constant", exempt: { reason: "session-only", why: "Native app launch and account-wide UI trial require explicit local dashboard confirmation." } },
|
|
176
|
+
{ method: "GET", path: "/api/codex/desktop-compatibility/settings", module: "server/management/desktop-compatibility-settings-routes", mutates: false, mechanism: "path-constant", exempt: { reason: "deferred-verb", owner: "codex-desktop-compatibility", ownerDoc: "structure/clients/codex-desktop.md", why: "The persisted startup preference is currently owned by the local desktop compatibility panel." } },
|
|
177
|
+
{ method: "POST", path: "/api/codex/desktop-compatibility/settings", module: "server/management/desktop-compatibility-settings-routes", mutates: true, mechanism: "path-constant", exempt: { reason: "session-only", why: "Saved native observation intent requires an explicit local GUI action and fresh field revision." } },
|
|
166
178
|
{ method: "PUT", path: "/api/codex-auth/features/default-mode-request-user-input", module: "server/management/agent-settings-routes", mutates: true },
|
|
167
179
|
{ method: "PUT", path: "/api/effort-caps", module: "server/management/agent-settings-routes", mutates: true },
|
|
168
180
|
{ method: "PUT", path: "/api/grok/selection", module: "server/management/agent-settings-routes", mutates: true },
|
|
@@ -209,8 +221,11 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
209
221
|
{ method: "POST", path: "/api/combos/decision-test", module: "server/management/decision-routes", mutates: true },
|
|
210
222
|
// server/management/config-routes
|
|
211
223
|
{ method: "GET", path: "/api/config", module: "server/management/config-routes", mutates: false },
|
|
224
|
+
{ method: "GET", path: "/api/auto-review-settings", module: "server/management/config-routes", mutates: false },
|
|
212
225
|
{ method: "GET", path: "/api/diagnostics/project-config", module: "server/management/config-routes", mutates: false },
|
|
213
226
|
{ method: "GET", path: "/api/settings", module: "server/management/config-routes", mutates: false },
|
|
227
|
+
{ method: "GET", path: "/api/native-reasoning-retention", module: "server/management/native-reasoning-retention-routes", mutates: false, exempt: { reason: "local-transport", why: "The CLI reads the same nativeReasoningRetention policy through ocx config get; no separate HTTP-specific settings verb is required." } },
|
|
228
|
+
{ method: "PUT", path: "/api/native-reasoning-retention", module: "server/management/native-reasoning-retention-routes", mutates: true, exempt: { reason: "deferred-verb", why: "A dedicated live CLI verb for this policy is deferred to native-reasoning-retention-live-cli; ocx config set/unset currently edits the same block on disk without live convergence.", owner: "native-reasoning-retention-live-cli", ownerDoc: "structure/transports/native-reasoning-retention.md" } },
|
|
214
229
|
{ method: "GET", path: "/api/shadow-call-settings", module: "server/management/config-routes", mutates: false },
|
|
215
230
|
{ method: "GET", path: "/api/sidecar-settings", module: "server/management/config-routes", mutates: false },
|
|
216
231
|
{ method: "GET", path: "/api/startup-health", module: "server/management/config-routes", mutates: false },
|
|
@@ -223,6 +238,7 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
223
238
|
{ method: "POST", path: "/api/windows-tray", module: "server/management/config-routes", mutates: true },
|
|
224
239
|
{ method: "PUT", path: "/api/config", module: "server/management/config-routes", mutates: true, exempt: { reason: "disabled", why: "Returns 405 by design; provider changes go through POST /api/providers." } },
|
|
225
240
|
{ method: "PUT", path: "/api/settings", module: "server/management/config-routes", mutates: true },
|
|
241
|
+
{ method: "PUT", path: "/api/auto-review-settings", module: "server/management/config-routes", mutates: true },
|
|
226
242
|
{ method: "PUT", path: "/api/shadow-call-settings", module: "server/management/config-routes", mutates: true },
|
|
227
243
|
{ method: "PUT", path: "/api/sidecar-settings", module: "server/management/config-routes", mutates: true },
|
|
228
244
|
// server/management/integration-routes
|
|
@@ -267,6 +283,10 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
267
283
|
{ method: "GET", path: "/api/usage", module: "server/management/logs-usage-routes", mutates: false },
|
|
268
284
|
// server/management/usage-timeline-routes
|
|
269
285
|
{ method: "GET", path: "/api/usage/timeline", module: "server/management/usage-timeline-routes", mutates: false },
|
|
286
|
+
// server/management/advisor-routes
|
|
287
|
+
{ method: "GET", path: "/api/advisor/settings", module: "server/management/advisor-routes", mutates: false },
|
|
288
|
+
{ method: "GET", path: "/api/advisor/activity", module: "server/management/advisor-routes", mutates: false },
|
|
289
|
+
{ method: "PUT", path: "/api/advisor/settings", module: "server/management/advisor-routes", mutates: true },
|
|
270
290
|
// server/management/companion-routes
|
|
271
291
|
{ method: "POST", path: "/api/companion/open-in-browser", module: "server/management/companion-routes", mutates: true, exempt: { reason: "browser-navigation", why: "Opens the companion's current view in the system browser under normal management admission; the CLI reads the underlying settings and usage directly." } },
|
|
272
292
|
{ method: "GET", path: "/api/companion/settings", module: "server/management/companion-routes", mutates: false },
|
|
@@ -349,7 +369,7 @@ export const MANAGEMENT_ROUTES: readonly ManagementRoute[] = [
|
|
|
349
369
|
{ method: "GET", path: "/api/provider-context-caps", module: "server/management/provider-routes", mutates: false },
|
|
350
370
|
{ method: "GET", path: "/api/provider-presets", module: "server/management/provider-routes", mutates: false },
|
|
351
371
|
{ method: "GET", path: "/api/provider-quotas", module: "server/management/provider-routes", mutates: false },
|
|
352
|
-
{ method: "GET", path: "/api/provider-request-pacing", module: "server/management/provider-routes", mutates: false },
|
|
372
|
+
{ method: "GET", path: "/api/provider-request-pacing", module: "server/management/provider-key-pacing-routes", mutates: false },
|
|
353
373
|
{ method: "GET", path: "/api/providers", module: "server/management/provider-routes", mutates: false },
|
|
354
374
|
{ method: "PATCH", path: "/api/providers", module: "server/management/provider-routes", mutates: true },
|
|
355
375
|
{ method: "POST", path: "/api/providers", module: "server/management/provider-routes", mutates: true },
|
|
@@ -30,6 +30,7 @@ export const SIBLING_REFUSED_MANAGEMENT_PATHS: readonly { readonly path: string;
|
|
|
30
30
|
{ path: "/api/client-integrations", children: true },
|
|
31
31
|
{ path: "/api/native-integrations", children: true },
|
|
32
32
|
{ path: "/api/claude-desktop", children: true },
|
|
33
|
+
{ path: "/api/codex/desktop-compatibility", children: true },
|
|
33
34
|
{ path: "/api/claude-code", children: false },
|
|
34
35
|
{ path: "/api/grok/apply", children: false },
|
|
35
36
|
{ path: "/api/grok/selection", children: false },
|
|
@@ -59,6 +59,7 @@ import { applySystemEnvToggle } from "./system-env";
|
|
|
59
59
|
|
|
60
60
|
import type { ManagementApiDeps } from "./management/context";
|
|
61
61
|
import { handleConfigRoutes } from "./management/config-routes";
|
|
62
|
+
import { handleNativeReasoningRetentionRoutes } from "./management/native-reasoning-retention-routes";
|
|
62
63
|
import { handleLogsUsageRoutes } from "./management/logs-usage-routes";
|
|
63
64
|
import { handleStorageLogGuardRoutes } from "./management/storage-log-guard-routes";
|
|
64
65
|
import { handleRequestHistoryRoutes } from "./management/request-history-routes";
|
|
@@ -79,6 +80,9 @@ import { handleCodexPromptRoutes } from "./management/codex-prompt-routes";
|
|
|
79
80
|
import { handleIntegrationRoutes } from "./management/integration-routes";
|
|
80
81
|
import { handleNativeIntegrationRoutes } from "./management/native-integration-routes";
|
|
81
82
|
import { handleClaudeDesktopPickerRoutes } from "./management/claude-desktop-picker-routes";
|
|
83
|
+
import { handleDesktopCompatibilityRoutes } from "./management/desktop-compatibility-routes";
|
|
84
|
+
import { handleDesktopCompatibilityRuntimeRoutes } from "./management/desktop-compatibility-runtime-routes";
|
|
85
|
+
import { handleDesktopCompatibilitySettingsRoutes } from "./management/desktop-compatibility-settings-routes";
|
|
82
86
|
import { handleCursorIntegrationRoutes } from "./management/cursor-integration-routes";
|
|
83
87
|
import type { ManagementContext } from "./management/context";
|
|
84
88
|
import type { ManagementPrincipal, ManagementSessionControl } from "./management-auth";
|
|
@@ -341,6 +345,7 @@ export async function handleManagementAPI(
|
|
|
341
345
|
?? (await handleLinkRoutesOnDemand(ctx))
|
|
342
346
|
?? (await handleRemoteWorkspaceRoutesOnDemand(ctx))
|
|
343
347
|
?? (await handleConfigRoutes(ctx))
|
|
348
|
+
?? (await handleNativeReasoningRetentionRoutes(ctx))
|
|
344
349
|
?? (await handleStorageLogGuardRoutes(ctx))
|
|
345
350
|
?? (await handleLogsUsageRoutes(ctx))
|
|
346
351
|
?? (await handleRequestHistoryRoutes(ctx))
|
|
@@ -360,6 +365,9 @@ export async function handleManagementAPI(
|
|
|
360
365
|
?? (await handleNativeIntegrationRoutes(ctx))
|
|
361
366
|
?? (await handleCursorIntegrationRoutes(ctx))
|
|
362
367
|
?? (await handleClaudeDesktopPickerRoutes(ctx))
|
|
368
|
+
?? (await handleDesktopCompatibilityRoutes(ctx))
|
|
369
|
+
?? (await handleDesktopCompatibilityRuntimeRoutes(ctx))
|
|
370
|
+
?? (await handleDesktopCompatibilitySettingsRoutes(ctx))
|
|
363
371
|
?? (await handleAgentSettingsRoutes(ctx))
|
|
364
372
|
?? (await handleCodexPromptRoutes(ctx))
|
|
365
373
|
?? (await handleOauthAccountRoutes(ctx))
|
|
@@ -513,7 +521,7 @@ export async function handleManagementAPI(
|
|
|
513
521
|
const { handleMainDeviceReauthAPI } = await import("../codex/main-device-reauth-api");
|
|
514
522
|
return handleMainDeviceReauthAPI(req, url, config);
|
|
515
523
|
}
|
|
516
|
-
const { handleCodexAuthAPI } = await import("../codex/auth-api");
|
|
524
|
+
const { handleCodexAuthAPI } = await import("../codex/auth-api/routes");
|
|
517
525
|
const { ConfigMutationLockError } = await import("../config");
|
|
518
526
|
const { CodexCredentialRefreshLockTimeoutError } = await import("../codex/account-store");
|
|
519
527
|
try {
|