@iislee/opencodex 2.11.0 → 2.31.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/AGENTS_INSTALL.md +109 -0
- package/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
-
import type { CodexAccount } from "../types";
|
|
2
|
+
import type { CodexAccount, OcxConfig } from "../types";
|
|
3
|
+
import type { CodexAuthContext } from "./auth-context";
|
|
4
|
+
import { MAIN_CODEX_ACCOUNT_ID } from "./main-account";
|
|
3
5
|
|
|
4
6
|
export const CODEX_ACCOUNT_LOG_LABEL_RE = /^p[a-f0-9]{6}$/;
|
|
5
7
|
|
|
@@ -22,6 +24,17 @@ export function codexAccountLogLabel(account: CodexAccount): string {
|
|
|
22
24
|
: fallbackCodexAccountLogLabel(account.id);
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
/** Effective durable label for a resolved Codex Pool account. */
|
|
28
|
+
export function codexAuthContextLogLabel(
|
|
29
|
+
authCtx: CodexAuthContext,
|
|
30
|
+
config: Pick<OcxConfig, "codexAccounts">,
|
|
31
|
+
): "main" | `p${string}` | undefined {
|
|
32
|
+
if (authCtx.kind !== "pool" && authCtx.kind !== "main-pool") return undefined;
|
|
33
|
+
if (authCtx.accountId === MAIN_CODEX_ACCOUNT_ID) return "main";
|
|
34
|
+
const account = (config.codexAccounts ?? []).find(candidate => candidate.id === authCtx.accountId);
|
|
35
|
+
return account ? codexAccountLogLabel(account) as `p${string}` : undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
export function withCodexAccountLogLabel(
|
|
26
39
|
account: Omit<CodexAccount, "logLabel"> & Partial<Pick<CodexAccount, "logLabel">>,
|
|
27
40
|
existingAccounts: readonly CodexAccount[],
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import {
|
|
3
|
+
atomicWriteFile,
|
|
4
|
+
getConfigPath,
|
|
5
|
+
saveConfigPreservingClaudeCode,
|
|
6
|
+
withConfigMutationLockSync,
|
|
7
|
+
} from "../config";
|
|
1
8
|
import { removeCodexAccountCredential } from "./account-store";
|
|
2
9
|
import { clearAccountNeedsReauth } from "./account-runtime-state";
|
|
3
10
|
import { getMainChatgptAccountId } from "./auth-collision";
|
|
@@ -5,18 +12,43 @@ import { MAIN_CODEX_ACCOUNT_ID, setMainAccountPlan } from "./main-account";
|
|
|
5
12
|
import { clearAccountQuota } from "./quota";
|
|
6
13
|
import { clearCodexUpstreamHealthForAccount, clearThreadAccountMapForAccount } from "./routing";
|
|
7
14
|
import { invalidateCodexWebSocketsForAccount } from "./websocket-registry";
|
|
8
|
-
import { clearMainAccountInfoCache } from "./main-account-cache";
|
|
15
|
+
import { clearMainAccountCredentialPresence, clearMainAccountInfoCache } from "./main-account-cache";
|
|
9
16
|
import { forgetCodexAccountPause } from "./account-pause";
|
|
17
|
+
import { clearCodexAccountPin, forgetCodexAccountPriority } from "./account-priority";
|
|
18
|
+
import { codexAccountNamespaceEntries, codexAccountPickerEnabled } from "./account-namespaces";
|
|
10
19
|
import type { OcxConfig } from "../types";
|
|
11
20
|
|
|
12
21
|
let observedMainChatgptAccountId: string | undefined;
|
|
13
22
|
|
|
23
|
+
export class CodexAccountDeleteCleanupError extends Error {
|
|
24
|
+
constructor() {
|
|
25
|
+
super("Account deletion was saved, but local credential cleanup did not complete. Retry removal.");
|
|
26
|
+
this.name = "CodexAccountDeleteCleanupError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class CodexAccountDeleteRollbackError extends Error {
|
|
31
|
+
constructor() {
|
|
32
|
+
super("Account deletion failed and the previous config could not be restored. Restart before retrying.");
|
|
33
|
+
this.name = "CodexAccountDeleteRollbackError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
14
37
|
export function purgeCodexAccountRuntimeState(accountId: string): void {
|
|
15
38
|
clearAccountNeedsReauth(accountId);
|
|
16
39
|
clearAccountQuota(accountId);
|
|
17
40
|
clearThreadAccountMapForAccount(accountId);
|
|
18
41
|
clearCodexUpstreamHealthForAccount(accountId);
|
|
19
|
-
if (accountId === MAIN_CODEX_ACCOUNT_ID)
|
|
42
|
+
if (accountId === MAIN_CODEX_ACCOUNT_ID) {
|
|
43
|
+
clearMainAccountInfoCache();
|
|
44
|
+
clearMainAccountCredentialPresence();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function purgeMainCodexAccountRuntimeState(): void {
|
|
49
|
+
purgeCodexAccountRuntimeState(MAIN_CODEX_ACCOUNT_ID);
|
|
50
|
+
setMainAccountPlan(null);
|
|
51
|
+
invalidateCodexWebSocketsForAccount(MAIN_CODEX_ACCOUNT_ID);
|
|
20
52
|
}
|
|
21
53
|
|
|
22
54
|
/**
|
|
@@ -34,22 +66,107 @@ export function reconcileMainCodexAccountRuntimeState(): boolean {
|
|
|
34
66
|
observedMainChatgptAccountId = currentAccountId;
|
|
35
67
|
if (previousAccountId === undefined || previousAccountId === currentAccountId) return false;
|
|
36
68
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
69
|
+
purgeMainCodexAccountRuntimeState();
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Apply a transaction-confirmed physical native-login change without waiting for
|
|
75
|
+
* a later auth.json observation. The caller owns credential commit/rollback.
|
|
76
|
+
*/
|
|
77
|
+
export function applyConfirmedMainCodexAccountTransition(
|
|
78
|
+
fromAccountId: string,
|
|
79
|
+
toAccountId: string,
|
|
80
|
+
): boolean {
|
|
81
|
+
if (!fromAccountId || !toAccountId || fromAccountId === toAccountId) {
|
|
82
|
+
if (toAccountId) observedMainChatgptAccountId = toAccountId;
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
observedMainChatgptAccountId = toAccountId;
|
|
86
|
+
purgeMainCodexAccountRuntimeState();
|
|
40
87
|
return true;
|
|
41
88
|
}
|
|
42
89
|
|
|
43
90
|
export function resetMainCodexAccountIdentityTrackingForTests(): void {
|
|
44
91
|
observedMainChatgptAccountId = undefined;
|
|
92
|
+
clearMainAccountCredentialPresence();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function restoreRuntimeConfig(target: OcxConfig, snapshot: OcxConfig): void {
|
|
96
|
+
for (const key of Object.keys(target) as Array<keyof OcxConfig>) delete target[key];
|
|
97
|
+
Object.assign(target, snapshot);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function restorePersistedConfig(configPath: string, previousBytes: string): void {
|
|
101
|
+
try {
|
|
102
|
+
if (readFileSync(configPath, "utf8") === previousBytes) return;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
105
|
+
}
|
|
106
|
+
atomicWriteFile(configPath, previousBytes);
|
|
45
107
|
}
|
|
46
108
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Delete a stored account while retaining its selector binding.
|
|
111
|
+
*
|
|
112
|
+
* When the runtime config is backed by an existing config.json, commit the config deletion before
|
|
113
|
+
* credentials or runtime state are destroyed. Transient callers intentionally skip durable config
|
|
114
|
+
* persistence because they have no durable account row to protect. The whole sequence shares the
|
|
115
|
+
* config mutation coordinator so a cooperating writer cannot re-add a persisted account between
|
|
116
|
+
* the durable config commit and credential cleanup.
|
|
117
|
+
*
|
|
118
|
+
* Returns true when a picker-visible row disappeared and the catalog must converge.
|
|
119
|
+
*/
|
|
120
|
+
export function deleteCodexAccount(runtimeConfig: OcxConfig, accountId: string): boolean {
|
|
121
|
+
let cleanupFailed = false;
|
|
122
|
+
const pickerVisibilityChanged = withConfigMutationLockSync(() => {
|
|
123
|
+
const previousConfig = structuredClone(runtimeConfig);
|
|
124
|
+
const configPath = getConfigPath();
|
|
125
|
+
const hasPersistedConfig = existsSync(configPath);
|
|
126
|
+
const previousPersistedConfig = hasPersistedConfig ? readFileSync(configPath, "utf8") : undefined;
|
|
127
|
+
const hadStoredAccount = (runtimeConfig.codexAccounts ?? [])
|
|
128
|
+
.some(account => !account.isMain && account.id === accountId);
|
|
129
|
+
const hadVisiblePickerBinding = hadStoredAccount
|
|
130
|
+
&& codexAccountPickerEnabled(runtimeConfig)
|
|
131
|
+
&& codexAccountNamespaceEntries(runtimeConfig)
|
|
132
|
+
.some(([, boundAccountId]) => boundAccountId === accountId);
|
|
133
|
+
|
|
134
|
+
runtimeConfig.codexAccounts = (runtimeConfig.codexAccounts ?? [])
|
|
135
|
+
.filter(account => account.isMain || account.id !== accountId);
|
|
136
|
+
forgetCodexAccountPause(runtimeConfig, accountId);
|
|
137
|
+
forgetCodexAccountPriority(runtimeConfig, accountId);
|
|
138
|
+
clearCodexAccountPin(runtimeConfig, accountId);
|
|
139
|
+
if (runtimeConfig.activeCodexAccountId === accountId) runtimeConfig.activeCodexAccountId = undefined;
|
|
140
|
+
|
|
141
|
+
if (previousPersistedConfig !== undefined) {
|
|
142
|
+
try {
|
|
143
|
+
// Persist first for durable configs. Destructive cleanup below must never run for a
|
|
144
|
+
// deletion that failed to commit. Transient configs intentionally skip this write.
|
|
145
|
+
saveConfigPreservingClaudeCode(runtimeConfig);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
restoreRuntimeConfig(runtimeConfig, previousConfig);
|
|
148
|
+
try {
|
|
149
|
+
restorePersistedConfig(configPath, previousPersistedConfig);
|
|
150
|
+
} catch {
|
|
151
|
+
throw new CodexAccountDeleteRollbackError();
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
removeCodexAccountCredential(accountId);
|
|
159
|
+
purgeCodexAccountRuntimeState(accountId);
|
|
160
|
+
invalidateCodexWebSocketsForAccount(accountId);
|
|
161
|
+
} catch {
|
|
162
|
+
// Do not throw through the mutation coordinator after config.json committed: that would roll
|
|
163
|
+
// back only the SQLite generation transaction, not the already-atomic file replacement.
|
|
164
|
+
cleanupFailed = true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return hadVisiblePickerBinding;
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (cleanupFailed) throw new CodexAccountDeleteCleanupError();
|
|
171
|
+
return pickerVisibilityChanged;
|
|
55
172
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { CodexAccount, OcxConfig } from "../types";
|
|
2
2
|
import { COMBO_NAMESPACE } from "../combos/types";
|
|
3
3
|
import { OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
|
|
4
|
+
import {
|
|
5
|
+
POLICY_NAMESPACE,
|
|
6
|
+
routingProfileAliasNamespacePrefixes,
|
|
7
|
+
} from "../routing/profile-namespace";
|
|
4
8
|
import {
|
|
5
9
|
CODEX_ACCOUNT_LOG_LABEL_RE,
|
|
6
10
|
createCodexAccountLogLabel,
|
|
@@ -21,6 +25,7 @@ const RESERVED_NAMESPACE_KEYS = new Set([
|
|
|
21
25
|
"constructor",
|
|
22
26
|
COMBO_NAMESPACE,
|
|
23
27
|
OPENAI_CODEX_PROVIDER_ID,
|
|
28
|
+
POLICY_NAMESPACE,
|
|
24
29
|
].map(codexProviderNamespaceKey));
|
|
25
30
|
const PUBLIC_ACCOUNT_SELECTOR_MAX_ATTEMPTS = 16;
|
|
26
31
|
|
|
@@ -68,17 +73,21 @@ function claimNamespace(requested: string, used: Set<string>): string {
|
|
|
68
73
|
return namespace;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
/** Collect every public namespace that a generated account selector must not claim. */
|
|
77
|
+
function occupiedNamespaces(
|
|
78
|
+
config: Pick<OcxConfig, "combos" | "providers" | "routingProfiles">,
|
|
79
|
+
): Set<string> {
|
|
72
80
|
return new Set([
|
|
73
81
|
...Object.keys(config.providers).map(codexProviderNamespaceKey),
|
|
74
82
|
...comboAliasNamespaces(config),
|
|
83
|
+
...routingProfileAliasNamespacePrefixes(config),
|
|
75
84
|
...RESERVED_NAMESPACE_KEYS,
|
|
76
85
|
]);
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
/** Build an initial account-selector map without deriving public selectors from aliases or ids. */
|
|
80
89
|
export function defaultCodexAccountNamespaces(
|
|
81
|
-
config: Pick<OcxConfig, "codexAccounts" | "combos" | "providers">,
|
|
90
|
+
config: Pick<OcxConfig, "codexAccounts" | "combos" | "providers" | "routingProfiles">,
|
|
82
91
|
): Record<string, string> {
|
|
83
92
|
const namespaces: Record<string, string> = {};
|
|
84
93
|
const used = occupiedNamespaces(config);
|
|
@@ -99,13 +108,39 @@ export function defaultCodexAccountNamespaces(
|
|
|
99
108
|
return namespaces;
|
|
100
109
|
}
|
|
101
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Initialize generated selectors only for an explicit opt-in with no existing bindings.
|
|
113
|
+
* A true result means the map was replaced and the caller must persist the updated config.
|
|
114
|
+
*/
|
|
115
|
+
export function initializeDefaultCodexAccountNamespaces(
|
|
116
|
+
config: Pick<
|
|
117
|
+
OcxConfig,
|
|
118
|
+
| "codexAccountPickerEnabled"
|
|
119
|
+
| "codexAccountNamespaces"
|
|
120
|
+
| "codexAccounts"
|
|
121
|
+
| "combos"
|
|
122
|
+
| "providers"
|
|
123
|
+
| "routingProfiles"
|
|
124
|
+
>,
|
|
125
|
+
): boolean {
|
|
126
|
+
if (config.codexAccountPickerEnabled !== true
|
|
127
|
+
|| Object.keys(config.codexAccountNamespaces ?? {}).length > 0) return false;
|
|
128
|
+
|
|
129
|
+
const namespaces = defaultCodexAccountNamespaces(config);
|
|
130
|
+
config.codexAccountNamespaces = namespaces;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
102
134
|
/**
|
|
103
135
|
* Add one account to a generated map without renaming or replacing explicit existing entries.
|
|
104
136
|
* The account-creation layer must reject a new id that already equals an existing selector key.
|
|
105
137
|
* A true result means the map was mutated in place; callers must persist the updated config.
|
|
106
138
|
*/
|
|
107
139
|
export function appendDefaultCodexAccountNamespace(
|
|
108
|
-
config: Pick<
|
|
140
|
+
config: Pick<
|
|
141
|
+
OcxConfig,
|
|
142
|
+
"codexAccountNamespaces" | "codexAccounts" | "combos" | "providers" | "routingProfiles"
|
|
143
|
+
>,
|
|
109
144
|
account: Pick<CodexAccount, "id" | "isMain" | "logLabel">,
|
|
110
145
|
): boolean {
|
|
111
146
|
const namespaces = config.codexAccountNamespaces;
|
|
@@ -147,3 +182,14 @@ export function codexAccountNamespaceEntries(
|
|
|
147
182
|
return Object.entries(config.codexAccountNamespaces ?? {})
|
|
148
183
|
.map(([namespace, accountId]) => [namespace, normalizeCodexAccountNamespaceTarget(accountId)]);
|
|
149
184
|
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Whether generated account-qualified rows are enabled for catalog discovery.
|
|
188
|
+
* A non-empty hand-written map predating the explicit override remains enabled.
|
|
189
|
+
*/
|
|
190
|
+
export function codexAccountPickerEnabled(
|
|
191
|
+
config: Pick<OcxConfig, "codexAccountNamespaces" | "codexAccountPickerEnabled">,
|
|
192
|
+
): boolean {
|
|
193
|
+
return (config.codexAccountPickerEnabled === undefined || config.codexAccountPickerEnabled === true)
|
|
194
|
+
&& Object.keys(config.codexAccountNamespaces ?? {}).length > 0;
|
|
195
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { isValidCodexAccountId, MAIN_CODEX_ACCOUNT_ID } from "./account-id";
|
|
2
|
+
import { DEFAULT_ACCOUNT_PRIORITY, normalizeAccountPriority } from "./pool-rotation";
|
|
3
|
+
import type { OcxConfig } from "../types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Which ids may carry a selection order: any pool account, plus the synthetic
|
|
7
|
+
* `__main__` Desktop login. Owned here rather than by the config schema because
|
|
8
|
+
* every writer needs it — the schema rejects a bad key on load, but the management
|
|
9
|
+
* API has to reject one before `setCodexAccountPriority` persists it as an own
|
|
10
|
+
* property that the schema would then reject, degrading the whole map.
|
|
11
|
+
*/
|
|
12
|
+
export function isCodexAccountPriorityKey(key: unknown): key is string {
|
|
13
|
+
return key === MAIN_CODEX_ACCOUNT_ID || isValidCodexAccountId(key);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Persisted selection order for one account: higher numbers are used earlier.
|
|
18
|
+
* Stored as a config sidecar rather than a `codexAccounts` row field because the
|
|
19
|
+
* Codex Desktop login (`__main__`) has no row and must be orderable too.
|
|
20
|
+
*/
|
|
21
|
+
export function getCodexAccountPriority(config: OcxConfig, accountId: string): number {
|
|
22
|
+
return codexAccountPriorityLookup(config)(accountId);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Write one account's selection order. The default is stored as absence, so a
|
|
27
|
+
* pool that was never ordered keeps no map at all and routing takes its fast path.
|
|
28
|
+
* Entries are rebuilt through `Object.fromEntries` so a reserved key such as
|
|
29
|
+
* `__proto__` becomes an own data property instead of invoking a prototype setter.
|
|
30
|
+
*/
|
|
31
|
+
export function setCodexAccountPriority(config: OcxConfig, accountId: string, priority: number): void {
|
|
32
|
+
const entries = new Map(Object.entries(config.codexAccountPriorities ?? {}));
|
|
33
|
+
if (priority === DEFAULT_ACCOUNT_PRIORITY) entries.delete(accountId);
|
|
34
|
+
else entries.set(accountId, priority);
|
|
35
|
+
|
|
36
|
+
if (entries.size > 0) config.codexAccountPriorities = Object.fromEntries(entries);
|
|
37
|
+
else delete config.codexAccountPriorities;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function forgetCodexAccountPriority(config: OcxConfig, accountId: string): void {
|
|
41
|
+
setCodexAccountPriority(config, accountId, DEFAULT_ACCOUNT_PRIORITY);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Stable lookup for one selection pass. Routing calls this once per pick and
|
|
46
|
+
* hands the closure to `selectPriorityTier`, so a pool without stored order pays
|
|
47
|
+
* a single map read rather than one per candidate.
|
|
48
|
+
*/
|
|
49
|
+
export function codexAccountPriorityLookup(config: OcxConfig): (accountId: string) => number {
|
|
50
|
+
const priorities = config.codexAccountPriorities;
|
|
51
|
+
if (!priorities) return () => DEFAULT_ACCOUNT_PRIORITY;
|
|
52
|
+
return accountId => (
|
|
53
|
+
Object.hasOwn(priorities, accountId)
|
|
54
|
+
? normalizeAccountPriority(priorities[accountId])
|
|
55
|
+
: DEFAULT_ACCOUNT_PRIORITY
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The account an operator most recently selected by hand. While pinned, priority
|
|
61
|
+
* never preempts upward: the pin is a tier *ceiling* for round-robin/fill-first --
|
|
62
|
+
* `selectPriorityTier` skips every tier above the pinned account's, so higher-ordered
|
|
63
|
+
* accounts are suppressed rather than the pinned one being guaranteed -- and a veto in
|
|
64
|
+
* the quota path, until the account crosses the auto-switch threshold.
|
|
65
|
+
*/
|
|
66
|
+
export function pinnedCodexAccountId(config: OcxConfig): string | undefined {
|
|
67
|
+
return config.activeCodexAccountPinned;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function isCodexAccountPinned(config: OcxConfig, accountId: string): boolean {
|
|
71
|
+
return config.activeCodexAccountPinned === accountId;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function setCodexAccountPin(config: OcxConfig, accountId: string): void {
|
|
75
|
+
config.activeCodexAccountPinned = accountId;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Release the pin. With `accountId` given, only when it is the pinned account. */
|
|
79
|
+
export function clearCodexAccountPin(config: OcxConfig, accountId?: string): void {
|
|
80
|
+
if (accountId === undefined || config.activeCodexAccountPinned === accountId) {
|
|
81
|
+
delete config.activeCodexAccountPinned;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -386,6 +386,19 @@ function findFreshCredentialForGrant(
|
|
|
386
386
|
return null;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
+
async function notePlanFromRefreshedAccessToken(
|
|
390
|
+
id: string,
|
|
391
|
+
accessToken: string,
|
|
392
|
+
generation: number,
|
|
393
|
+
): Promise<void> {
|
|
394
|
+
try {
|
|
395
|
+
const { noteCodexAccountAccessToken } = await import("./plan-from-token");
|
|
396
|
+
noteCodexAccountAccessToken(id, accessToken, generation);
|
|
397
|
+
} catch {
|
|
398
|
+
// Derived plan metadata must not fail credential refresh.
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
389
402
|
export async function getValidCodexToken(id: string): Promise<CodexTokenResult> {
|
|
390
403
|
const record = readCodexAccountRecord(id);
|
|
391
404
|
const cred = record?.deletedAt == null ? record?.credential : undefined;
|
|
@@ -415,10 +428,12 @@ export async function getValidCodexToken(id: string): Promise<CodexTokenResult>
|
|
|
415
428
|
if (!saveCodexAccountCredentialIfGeneration(id, current.generation, refreshed.credential)) {
|
|
416
429
|
throw new CodexCredentialGenerationConflictError();
|
|
417
430
|
}
|
|
431
|
+
const generation = current.generation + 1;
|
|
432
|
+
await notePlanFromRefreshedAccessToken(id, refreshed.credential.accessToken, generation);
|
|
418
433
|
return {
|
|
419
434
|
accessToken: refreshed.credential.accessToken,
|
|
420
435
|
chatgptAccountId: refreshed.credential.chatgptAccountId,
|
|
421
|
-
generation
|
|
436
|
+
generation,
|
|
422
437
|
};
|
|
423
438
|
}
|
|
424
439
|
return getValidCodexToken(id);
|
|
@@ -491,11 +506,22 @@ export async function getValidCodexToken(id: string): Promise<CodexTokenResult>
|
|
|
491
506
|
throw new TokenRefreshError(reason, `Codex token refresh failed (${reason}); reauthenticate the account.`);
|
|
492
507
|
}
|
|
493
508
|
const data = (await res.json()) as { access_token: string; refresh_token?: string; expires_in: number };
|
|
509
|
+
// Guard against a missing/non-finite/negative expires_in (malformed upstream
|
|
510
|
+
// response): a NaN expiry would never compare as expired, and a negative
|
|
511
|
+
// duration would stamp an already-past expiry — both block refresh semantics.
|
|
512
|
+
const expiresIn =
|
|
513
|
+
typeof data.expires_in === "number" && Number.isFinite(data.expires_in) && data.expires_in >= 0
|
|
514
|
+
? data.expires_in
|
|
515
|
+
: 3600;
|
|
516
|
+
// The computed timestamp itself must stay finite: Number.MAX_VALUE passes
|
|
517
|
+
// Number.isFinite but overflows to Infinity once multiplied by 1000.
|
|
518
|
+
const expiresAt = Date.now() + expiresIn * 1000;
|
|
519
|
+
const safeExpiresAt = Number.isFinite(expiresAt) ? expiresAt : Date.now() + 3600 * 1000;
|
|
494
520
|
|
|
495
521
|
const updated: CodexAccountCredentials = {
|
|
496
522
|
accessToken: data.access_token,
|
|
497
523
|
refreshToken: data.refresh_token ?? lockedCred.refreshToken,
|
|
498
|
-
expiresAt:
|
|
524
|
+
expiresAt: safeExpiresAt,
|
|
499
525
|
chatgptAccountId: lockedCred.chatgptAccountId,
|
|
500
526
|
};
|
|
501
527
|
if (!saveCodexAccountCredentialIfGeneration(id, startGeneration, updated)) {
|
|
@@ -509,6 +535,7 @@ export async function getValidCodexToken(id: string): Promise<CodexTokenResult>
|
|
|
509
535
|
flight = { promise: refreshPromise, startedAt: Date.now(), abort };
|
|
510
536
|
refreshLocks.set(refreshGrantFingerprint, flight);
|
|
511
537
|
const result = await refreshPromise;
|
|
538
|
+
await notePlanFromRefreshedAccessToken(id, result.accessToken, result.generation);
|
|
512
539
|
return {
|
|
513
540
|
accessToken: result.accessToken,
|
|
514
541
|
chatgptAccountId: result.chatgptAccountId,
|
|
@@ -3,14 +3,37 @@ import { isAccountNeedsReauth } from "./account-runtime-state";
|
|
|
3
3
|
import { MAIN_CODEX_ACCOUNT_ID, isMainAccountTokenLive } from "./main-account";
|
|
4
4
|
import { hasLegacyMainCodexPoolAccount, isSelectableCodexPoolAccount } from "./account-id";
|
|
5
5
|
import type { OcxConfig } from "../types";
|
|
6
|
+
import { isNativeMainTrafficBlocked } from "./native-profile-startup";
|
|
6
7
|
|
|
7
|
-
export
|
|
8
|
+
export interface CodexAccountUsabilityOptions {
|
|
9
|
+
/** Route using cached runtime state only; the caller must reject selected main before auth. */
|
|
10
|
+
nativeMainSelectionOnly?: boolean;
|
|
11
|
+
/** Test seam for proving whether routing attempted a physical native-token read. */
|
|
12
|
+
isMainAccountTokenLive?: typeof isMainAccountTokenLive;
|
|
13
|
+
/** Confirmed account ids for an account-gated model; omitted for ordinary native models. */
|
|
14
|
+
modelEligibleAccountIds?: ReadonlySet<string>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function isCodexAccountUsable(
|
|
18
|
+
config: OcxConfig,
|
|
19
|
+
accountId: string,
|
|
20
|
+
options: CodexAccountUsabilityOptions = {},
|
|
21
|
+
): boolean {
|
|
22
|
+
if (options.modelEligibleAccountIds && !options.modelEligibleAccountIds.has(accountId)) return false;
|
|
8
23
|
if (accountId === MAIN_CODEX_ACCOUNT_ID) {
|
|
24
|
+
// Startup recovery owns the physical auth/vault boundary. Never parse or select
|
|
25
|
+
// native __main__ while an encrypted switch journal is pending or inconclusive.
|
|
26
|
+
if (!options.nativeMainSelectionOnly && isNativeMainTrafficBlocked()) return false;
|
|
9
27
|
// A legacy pool row with the sentinel makes an active `__main__` ambiguous.
|
|
10
28
|
// Fail closed until the authenticated compatibility-delete path removes it.
|
|
11
29
|
if (hasLegacyMainCodexPoolAccount(config.codexAccounts)) return false;
|
|
30
|
+
if (isAccountNeedsReauth(accountId)) return false;
|
|
31
|
+
// A selection-only caller owns the recovery/drain fence and will reject main
|
|
32
|
+
// before reservation or token materialization. Treat cached main as a routing
|
|
33
|
+
// candidate without touching the credential file so affinity is not rebound.
|
|
34
|
+
if (options.nativeMainSelectionOnly) return true;
|
|
12
35
|
// Main account: credential is the read-only ~/.codex/auth.json token (Option A).
|
|
13
|
-
return isMainAccountTokenLive
|
|
36
|
+
return (options.isMainAccountTokenLive ?? isMainAccountTokenLive)();
|
|
14
37
|
}
|
|
15
38
|
const exists = (config.codexAccounts ?? [])
|
|
16
39
|
.some(account => isSelectableCodexPoolAccount(account) && account.id === accountId);
|