@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
package/src/codex/paths.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { realpathSync, statSync } from "node:fs";
|
|
1
|
+
import { readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join, resolve } from "node:path";
|
|
3
3
|
import { expandUserPath } from "../config";
|
|
4
4
|
import { defaultCodexHome } from "./home";
|
|
@@ -34,6 +34,85 @@ export function getCodexHome(): string {
|
|
|
34
34
|
return resolveCodexHome();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
export interface CodexSqliteHomeDeps {
|
|
38
|
+
env?: NodeJS.ProcessEnv;
|
|
39
|
+
cwd?: () => string;
|
|
40
|
+
codexHome?: string;
|
|
41
|
+
readConfig?: (path: string) => string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type RootTomlStringState =
|
|
45
|
+
| { kind: "absent" }
|
|
46
|
+
| { kind: "value"; value: string }
|
|
47
|
+
| { kind: "invalid" };
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parse the authoritative SQLite setting without changing the tolerant helper
|
|
51
|
+
* used by injection/catalog readers. History ownership must distinguish a
|
|
52
|
+
* missing key from a present value that Codex cannot interpret as a path.
|
|
53
|
+
*/
|
|
54
|
+
function readAuthoritativeRootTomlString(content: string, key: string): RootTomlStringState {
|
|
55
|
+
let parsed: unknown;
|
|
56
|
+
try {
|
|
57
|
+
parsed = Bun.TOML.parse(content);
|
|
58
|
+
} catch {
|
|
59
|
+
return { kind: "invalid" };
|
|
60
|
+
}
|
|
61
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return { kind: "invalid" };
|
|
62
|
+
const root = parsed as Record<string, unknown>;
|
|
63
|
+
if (!Object.prototype.hasOwnProperty.call(root, key)) return { kind: "absent" };
|
|
64
|
+
const value = root[key];
|
|
65
|
+
if (typeof value !== "string" || value.trim() === "") return { kind: "invalid" };
|
|
66
|
+
return { kind: "value", value: value.trim() };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resolve Codex's SQLite state root at call time.
|
|
71
|
+
*
|
|
72
|
+
* Codex permits SQLite-backed state to live outside CODEX_HOME, especially for
|
|
73
|
+
* Windows Desktop sessions whose app-server runs in WSL. Keep the precedence
|
|
74
|
+
* identical to Codex: root config, then environment, then the effective home.
|
|
75
|
+
*/
|
|
76
|
+
export function resolveCodexSqliteHome(deps: CodexSqliteHomeDeps = {}): string {
|
|
77
|
+
const codexHome = deps.codexHome ?? getCodexHome();
|
|
78
|
+
const readConfig = deps.readConfig ?? (path => readFileSync(path, "utf8"));
|
|
79
|
+
const configPath = join(codexHome, "config.toml");
|
|
80
|
+
let configured: RootTomlStringState = { kind: "absent" };
|
|
81
|
+
try {
|
|
82
|
+
configured = readAuthoritativeRootTomlString(readConfig(configPath), "sqlite_home");
|
|
83
|
+
} catch (cause) {
|
|
84
|
+
if ((cause as NodeJS.ErrnoException | undefined)?.code !== "ENOENT") {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Codex config could not be read while resolving sqlite_home: ${configPath}`,
|
|
87
|
+
{ cause },
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
// A genuinely absent config cannot contain the authoritative root override,
|
|
91
|
+
// so only ENOENT may continue to the documented environment/home fallback.
|
|
92
|
+
}
|
|
93
|
+
if (configured.kind === "invalid") {
|
|
94
|
+
throw new Error(`Codex config has an invalid sqlite_home setting: ${configPath}`);
|
|
95
|
+
}
|
|
96
|
+
const raw = configured.kind === "value"
|
|
97
|
+
? configured.value
|
|
98
|
+
: (deps.env ?? process.env).CODEX_SQLITE_HOME?.trim() || "";
|
|
99
|
+
if (!raw) return codexHome;
|
|
100
|
+
const expanded = expandUserPath(raw);
|
|
101
|
+
return isAbsolute(expanded)
|
|
102
|
+
? resolve(expanded)
|
|
103
|
+
: resolve((deps.cwd ?? process.cwd)(), expanded);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Active Codex thread-state database, derived from the call-time SQLite root. */
|
|
107
|
+
export function resolveCodexStateDbPath(deps: CodexSqliteHomeDeps = {}): string {
|
|
108
|
+
return join(resolveCodexSqliteHome(deps), "state_5.sqlite");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Active Codex diagnostic-log database, derived from the call-time SQLite root. */
|
|
112
|
+
export function resolveCodexLogsDbPath(deps: CodexSqliteHomeDeps = {}): string {
|
|
113
|
+
return join(resolveCodexSqliteHome(deps), "logs_2.sqlite");
|
|
114
|
+
}
|
|
115
|
+
|
|
37
116
|
export function tomlString(value: string): string {
|
|
38
117
|
return JSON.stringify(value);
|
|
39
118
|
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConfigMutationLockError,
|
|
3
|
+
loadConfig,
|
|
4
|
+
mutatePersistedConfig,
|
|
5
|
+
} from "../config";
|
|
6
|
+
import type { CodexAccount, OcxConfig } from "../types";
|
|
7
|
+
import { isSelectableCodexPoolAccount, isValidCodexAccountId } from "./account-id";
|
|
8
|
+
import {
|
|
9
|
+
getCodexAccountCredential,
|
|
10
|
+
isCodexAccountGenerationLive,
|
|
11
|
+
readCodexAccountRecord,
|
|
12
|
+
} from "./account-store";
|
|
13
|
+
import { extractChatgptPlanType, codexPlanValue } from "./plan";
|
|
14
|
+
|
|
15
|
+
interface FreshPoolPlanUpdate {
|
|
16
|
+
accountId: string;
|
|
17
|
+
plan: string;
|
|
18
|
+
credentialGeneration: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function configuredPoolAccount(config: OcxConfig, accountId: string): CodexAccount | null {
|
|
22
|
+
if (!isValidCodexAccountId(accountId)) return null;
|
|
23
|
+
return (config.codexAccounts ?? [])
|
|
24
|
+
.find(account => account.id === accountId && isSelectableCodexPoolAccount(account)) ?? null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function jwtPlanFromPoolCredential(accountId: string): string | undefined {
|
|
28
|
+
const cred = getCodexAccountCredential(accountId);
|
|
29
|
+
return cred ? extractChatgptPlanType(undefined, cred.accessToken) : undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* WHAM-wins gate (release-audit fix). A JWT-derived plan may be persisted only when no
|
|
34
|
+
* WHAM-sourced plan exists for the CURRENT credential generation. A token refresh bumps the
|
|
35
|
+
* generation, and the refreshed JWT is then genuinely newer information than the previous
|
|
36
|
+
* generation's WHAM read, so it may write again until WHAM re-observes. Records without
|
|
37
|
+
* provenance (legacy) stay writable so the original #1989 recovery still works.
|
|
38
|
+
*/
|
|
39
|
+
function jwtMayWritePlan(account: CodexAccount, generation: number): boolean {
|
|
40
|
+
if (account.planSource !== "wham") return true;
|
|
41
|
+
const whamGeneration = account.planCredentialGeneration;
|
|
42
|
+
return whamGeneration !== undefined && generation > whamGeneration;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function collectJwtPoolPlanUpdates(runtimeConfig: OcxConfig): FreshPoolPlanUpdate[] {
|
|
46
|
+
const updates: FreshPoolPlanUpdate[] = [];
|
|
47
|
+
for (const account of (runtimeConfig.codexAccounts ?? []).filter(isSelectableCodexPoolAccount)) {
|
|
48
|
+
const jwtPlan = jwtPlanFromPoolCredential(account.id);
|
|
49
|
+
if (!jwtPlan || codexPlanValue(account.plan) === jwtPlan) continue;
|
|
50
|
+
const generation = readCodexAccountRecord(account.id)?.generation;
|
|
51
|
+
if (generation === undefined) continue;
|
|
52
|
+
if (!jwtMayWritePlan(account, generation)) continue;
|
|
53
|
+
updates.push({ accountId: account.id, plan: jwtPlan, credentialGeneration: generation });
|
|
54
|
+
}
|
|
55
|
+
return updates;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const appliedJwtPlans = new Map<string, string>();
|
|
59
|
+
|
|
60
|
+
function persistJwtPlanUpdates(runtimeConfig: OcxConfig, updates: FreshPoolPlanUpdate[]): void {
|
|
61
|
+
if (updates.length === 0) return;
|
|
62
|
+
let outcome: ReturnType<typeof mutatePersistedConfig<FreshPoolPlanUpdate[]>>;
|
|
63
|
+
try {
|
|
64
|
+
outcome = mutatePersistedConfig(persistedConfig => {
|
|
65
|
+
const accepted: FreshPoolPlanUpdate[] = [];
|
|
66
|
+
let changed = false;
|
|
67
|
+
for (const update of updates) {
|
|
68
|
+
if (!isCodexAccountGenerationLive(update.accountId, update.credentialGeneration)) continue;
|
|
69
|
+
const liveAccount = configuredPoolAccount(runtimeConfig, update.accountId);
|
|
70
|
+
const persistedAccount = configuredPoolAccount(persistedConfig, update.accountId);
|
|
71
|
+
if (!liveAccount || !persistedAccount) continue;
|
|
72
|
+
// Re-check against the PERSISTED row: another process may have landed a WHAM
|
|
73
|
+
// observation between collect and this mutation.
|
|
74
|
+
if (!jwtMayWritePlan(persistedAccount, update.credentialGeneration)) continue;
|
|
75
|
+
accepted.push(update);
|
|
76
|
+
if (persistedAccount.plan !== update.plan) {
|
|
77
|
+
persistedAccount.plan = update.plan;
|
|
78
|
+
changed = true;
|
|
79
|
+
}
|
|
80
|
+
if (persistedAccount.planSource !== "jwt" || persistedAccount.planCredentialGeneration !== update.credentialGeneration) {
|
|
81
|
+
persistedAccount.planSource = "jwt";
|
|
82
|
+
persistedAccount.planCredentialGeneration = update.credentialGeneration;
|
|
83
|
+
changed = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { changed, value: accepted };
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error instanceof ConfigMutationLockError) return;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
if (outcome.status === "unavailable") return;
|
|
93
|
+
for (const update of outcome.value) {
|
|
94
|
+
if (!isCodexAccountGenerationLive(update.accountId, update.credentialGeneration)) continue;
|
|
95
|
+
const liveAccount = configuredPoolAccount(runtimeConfig, update.accountId);
|
|
96
|
+
if (liveAccount) {
|
|
97
|
+
liveAccount.plan = update.plan;
|
|
98
|
+
liveAccount.planSource = "jwt";
|
|
99
|
+
liveAccount.planCredentialGeneration = update.credentialGeneration;
|
|
100
|
+
appliedJwtPlans.set(update.accountId, update.plan);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Persist JWT `chatgpt_plan_type` onto `codexAccounts[].plan` when it contradicts the stored
|
|
107
|
+
* label. Generation-gated, same fail-closed lock policy as the WHAM plan patch. Does not
|
|
108
|
+
* overwrite a plan that already matches the token.
|
|
109
|
+
*/
|
|
110
|
+
export function reconcileCodexPlansFromTokens(runtimeConfig: OcxConfig = loadConfig()): void {
|
|
111
|
+
persistJwtPlanUpdates(runtimeConfig, collectJwtPoolPlanUpdates(runtimeConfig));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function resetJwtPlanNotesForTests(): void {
|
|
115
|
+
appliedJwtPlans.clear();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Apply one account's live token claim without blocking the credential read path. */
|
|
119
|
+
export function noteCodexAccountAccessToken(
|
|
120
|
+
accountId: string,
|
|
121
|
+
accessToken: string,
|
|
122
|
+
credentialGeneration: number,
|
|
123
|
+
): void {
|
|
124
|
+
const jwtPlan = extractChatgptPlanType(undefined, accessToken);
|
|
125
|
+
if (!jwtPlan) return;
|
|
126
|
+
if (appliedJwtPlans.get(accountId) === jwtPlan) return;
|
|
127
|
+
try {
|
|
128
|
+
const runtimeConfig = loadConfig();
|
|
129
|
+
const live = configuredPoolAccount(runtimeConfig, accountId);
|
|
130
|
+
if (!live || codexPlanValue(live.plan) === jwtPlan) {
|
|
131
|
+
appliedJwtPlans.set(accountId, jwtPlan);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (!jwtMayWritePlan(live, credentialGeneration)) return;
|
|
135
|
+
persistJwtPlanUpdates(runtimeConfig, [{ accountId, plan: jwtPlan, credentialGeneration }]);
|
|
136
|
+
if (codexPlanValue(live.plan) === jwtPlan) appliedJwtPlans.set(accountId, jwtPlan);
|
|
137
|
+
} catch {
|
|
138
|
+
appliedJwtPlans.delete(accountId);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { decodeJwtPayload } from "../oauth/chatgpt";
|
|
2
|
+
|
|
3
|
+
/** Preserve user/provider plan labels only when they are usable strings. */
|
|
4
|
+
export function codexPlanValue(value: unknown): string | undefined {
|
|
5
|
+
if (typeof value !== "string") return undefined;
|
|
6
|
+
return value.trim() ? value : undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Case-insensitive key used by quota, capacity, and collision policy. */
|
|
10
|
+
export function codexPlanKey(value: unknown): string | undefined {
|
|
11
|
+
return codexPlanValue(value)?.trim().toLowerCase();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function isThirtyDayOnlyCodexPlan(value: unknown): boolean {
|
|
15
|
+
const key = codexPlanKey(value);
|
|
16
|
+
return key === "go" || key === "free";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* ChatGPT plan label from a live access/id token (`chatgpt_plan_type`).
|
|
21
|
+
* Used when WHAM has not run yet so a stale stored `free` cannot outrank the token (#1989).
|
|
22
|
+
*/
|
|
23
|
+
export function extractChatgptPlanType(idToken?: string, accessToken?: string): string | undefined {
|
|
24
|
+
for (const token of [idToken, accessToken]) {
|
|
25
|
+
if (!token) continue;
|
|
26
|
+
const payload = decodeJwtPayload(token);
|
|
27
|
+
if (!payload) continue;
|
|
28
|
+
if (typeof payload.chatgpt_plan_type === "string") {
|
|
29
|
+
const plan = codexPlanValue(payload.chatgpt_plan_type);
|
|
30
|
+
if (plan) return plan;
|
|
31
|
+
}
|
|
32
|
+
const ns = payload["https://api.openai.com/auth"];
|
|
33
|
+
if (ns && typeof ns === "object") {
|
|
34
|
+
const nested = (ns as Record<string, unknown>).chatgpt_plan_type;
|
|
35
|
+
const plan = codexPlanValue(nested);
|
|
36
|
+
if (plan) return plan;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
@@ -59,7 +59,7 @@ function readMarketplaceTable(configText: string, name: string): Record<string,
|
|
|
59
59
|
for (let i = start; i < lines.length; i++) {
|
|
60
60
|
const line = lines[i] ?? "";
|
|
61
61
|
if (/^\s*\[/.test(line)) break; // next table starts; stop
|
|
62
|
-
const m = line.match(/^\s*([A-Za-z0-9_-]+)\s*=\s*("(?:\\.|[^"])*"|'[^']*'|[
|
|
62
|
+
const m = line.match(/^\s*([A-Za-z0-9_-]+)\s*=\s*("(?:\\.|[^"\\])*"|'[^']*'|(?!["'])[^\s#]+)\s*(?:#.*)?$/);
|
|
63
63
|
if (!m) continue;
|
|
64
64
|
table[m[1]] = unquoteTomlValue(m[2].trim());
|
|
65
65
|
}
|
|
@@ -19,6 +19,11 @@ const MAX_STICKY_LIMIT = 100;
|
|
|
19
19
|
const DEFAULT_STRATEGY: OcxAccountPoolRotationStrategy = "quota";
|
|
20
20
|
const VALID_STRATEGIES = new Set<OcxAccountPoolRotationStrategy>(["quota", "round-robin", "fill-first"]);
|
|
21
21
|
|
|
22
|
+
/** Selection order for an account with no stored preference: one flat tier. */
|
|
23
|
+
export const DEFAULT_ACCOUNT_PRIORITY = 0;
|
|
24
|
+
export const MIN_ACCOUNT_PRIORITY = -100;
|
|
25
|
+
export const MAX_ACCOUNT_PRIORITY = 100;
|
|
26
|
+
|
|
22
27
|
/** Strict parse for management APIs — returns null instead of defaulting. */
|
|
23
28
|
export function parseAccountPoolStrategy(raw: unknown): OcxAccountPoolRotationStrategy | null {
|
|
24
29
|
if (typeof raw === "string" && VALID_STRATEGIES.has(raw as OcxAccountPoolRotationStrategy)) {
|
|
@@ -43,6 +48,71 @@ export function normalizeAccountPoolStickyLimit(raw: unknown): number {
|
|
|
43
48
|
return parseAccountPoolStickyLimit(raw) ?? DEFAULT_STICKY_LIMIT;
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
/** Strict parse for management APIs — returns null instead of defaulting. */
|
|
52
|
+
export function parseAccountPriority(raw: unknown): number | null {
|
|
53
|
+
if (
|
|
54
|
+
typeof raw === "number"
|
|
55
|
+
&& Number.isInteger(raw)
|
|
56
|
+
&& raw >= MIN_ACCOUNT_PRIORITY
|
|
57
|
+
&& raw <= MAX_ACCOUNT_PRIORITY
|
|
58
|
+
) {
|
|
59
|
+
return raw;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function normalizeAccountPriority(raw: unknown): number {
|
|
65
|
+
return parseAccountPriority(raw) ?? DEFAULT_ACCOUNT_PRIORITY;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Narrow an already-eligible account list to the highest selection-order tier that
|
|
70
|
+
* still has usable quota. Priority is an *ordering* boundary layered on top of
|
|
71
|
+
* eligibility: it never admits an account the caller already filtered out, and it
|
|
72
|
+
* never keeps the pool on a tier whose every member is drained.
|
|
73
|
+
*
|
|
74
|
+
* Contract (each clause is load-bearing for "no behavior change when unconfigured"):
|
|
75
|
+
* - one distinct priority across `ids` (the unconfigured case) returns `ids` unchanged,
|
|
76
|
+
* so today's pick sequence is preserved byte for byte;
|
|
77
|
+
* - input order is preserved inside the returned tier, which keeps the `__main__`
|
|
78
|
+
* head-of-list bias and the first-index tie-break used by SWRR/lowest-usage;
|
|
79
|
+
* - every tier drained returns `ids` unchanged, reproducing today's
|
|
80
|
+
* stay-put-until-429 behavior rather than inventing a pick;
|
|
81
|
+
* - a `pinnedId` that is present *and* has headroom lowers the ceiling to its own
|
|
82
|
+
* tier, which is what makes a manual "use this now" survive round-robin and
|
|
83
|
+
* fill-first without any mutable selection state. A drained or absent pin is
|
|
84
|
+
* ignored, so the pin expires on its own once the account crosses the threshold.
|
|
85
|
+
*/
|
|
86
|
+
export function selectPriorityTier(
|
|
87
|
+
ids: readonly string[],
|
|
88
|
+
priorityOf: (id: string) => number,
|
|
89
|
+
hasHeadroom: (id: string) => boolean,
|
|
90
|
+
pinnedId?: string,
|
|
91
|
+
): readonly string[] {
|
|
92
|
+
// Readonly out as well as in: the no-change cases return the caller's own array, so a
|
|
93
|
+
// mutating caller would corrupt its input in exactly the cases that must not change.
|
|
94
|
+
const list = ids;
|
|
95
|
+
if (list.length <= 1) return list;
|
|
96
|
+
|
|
97
|
+
const priorities = list.map(priorityOf);
|
|
98
|
+
const firstPriority = priorities[0]!;
|
|
99
|
+
if (priorities.every(priority => priority === firstPriority)) return list;
|
|
100
|
+
|
|
101
|
+
let ceiling = Number.POSITIVE_INFINITY;
|
|
102
|
+
if (pinnedId !== undefined) {
|
|
103
|
+
const pinnedIndex = list.indexOf(pinnedId);
|
|
104
|
+
if (pinnedIndex >= 0 && hasHeadroom(pinnedId)) ceiling = priorities[pinnedIndex]!;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const tiers = [...new Set(priorities)].sort((a, b) => b - a);
|
|
108
|
+
for (const tier of tiers) {
|
|
109
|
+
if (tier > ceiling) continue;
|
|
110
|
+
const members = list.filter((_, index) => priorities[index] === tier);
|
|
111
|
+
if (members.some(hasHeadroom)) return members;
|
|
112
|
+
}
|
|
113
|
+
return list;
|
|
114
|
+
}
|
|
115
|
+
|
|
46
116
|
function getOrCreateState(poolKey: string): SelectionState {
|
|
47
117
|
let state = selectionState.get(poolKey);
|
|
48
118
|
if (!state) {
|
|
@@ -60,7 +130,7 @@ function cloneSelectionState(state: SelectionState): SelectionState {
|
|
|
60
130
|
};
|
|
61
131
|
}
|
|
62
132
|
|
|
63
|
-
function smoothWeightedIndex(ids: string[], state: SelectionState): number {
|
|
133
|
+
function smoothWeightedIndex(ids: readonly string[], state: SelectionState): number {
|
|
64
134
|
let best = -1;
|
|
65
135
|
let bestScore = Number.NEGATIVE_INFINITY;
|
|
66
136
|
let total = 0;
|
|
@@ -87,7 +157,7 @@ function smoothWeightedIndex(ids: string[], state: SelectionState): number {
|
|
|
87
157
|
* either the live map entry or a scratch/clone for dry-run peek.
|
|
88
158
|
*/
|
|
89
159
|
function pickRoundRobinFromState(
|
|
90
|
-
eligibleIds: string[],
|
|
160
|
+
eligibleIds: readonly string[],
|
|
91
161
|
stickyLimit: number,
|
|
92
162
|
state: SelectionState,
|
|
93
163
|
commitSticky: boolean,
|
|
@@ -118,7 +188,7 @@ function pickRoundRobinFromState(
|
|
|
118
188
|
|
|
119
189
|
export function pickRoundRobinAccount(
|
|
120
190
|
poolKey: string,
|
|
121
|
-
eligibleIds: string[],
|
|
191
|
+
eligibleIds: readonly string[],
|
|
122
192
|
stickyLimit: number,
|
|
123
193
|
): string | null {
|
|
124
194
|
return pickRoundRobinFromState(eligibleIds, stickyLimit, getOrCreateState(poolKey), true);
|
|
@@ -130,7 +200,7 @@ export function pickRoundRobinAccount(
|
|
|
130
200
|
*/
|
|
131
201
|
export function peekRoundRobinAccount(
|
|
132
202
|
poolKey: string,
|
|
133
|
-
eligibleIds: string[],
|
|
203
|
+
eligibleIds: readonly string[],
|
|
134
204
|
stickyLimit: number,
|
|
135
205
|
): string | null {
|
|
136
206
|
const live = selectionState.get(poolKey);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
2
2
|
import path, { dirname, join, resolve } from "node:path";
|
|
3
3
|
import { expandUserPath } from "../config";
|
|
4
4
|
import { defaultCodexHome } from "./home";
|
|
@@ -70,7 +70,7 @@ export function parseTomlDocument(content: string): TomlDocument {
|
|
|
70
70
|
current = section;
|
|
71
71
|
continue;
|
|
72
72
|
}
|
|
73
|
-
const kv = line.match(/^\s*([A-Za-z0-9_.-]+)\s*=\s*("(?:\\.|[^"])*"|'[^']*'|[^\s#]+)\s*(?:#.*)?$/);
|
|
73
|
+
const kv = line.match(/^\s*([A-Za-z0-9_.-]+)\s*=\s*("(?:\\.|[^"\\])*"|'[^']*'|[^\s#]+)\s*(?:#.*)?$/);
|
|
74
74
|
if (kv) current[kv[1]!] = parseTomlString(kv[2]!);
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -252,9 +252,23 @@ export function discoverProjectCodexConfigPaths(options: {
|
|
|
252
252
|
} = {}): string[] {
|
|
253
253
|
const found = new Set<string>();
|
|
254
254
|
const codexConfigPath = options.codexConfigPath ?? resolveCodexConfigPath();
|
|
255
|
+
// A parent walk can reach the user's home and rediscover this global file as
|
|
256
|
+
// `$HOME/.codex/config.toml`; compare real paths so symlink aliases are excluded too.
|
|
257
|
+
const normalizeExistingPath = (candidate: string): string | null => {
|
|
258
|
+
if (!existsSync(candidate)) return null;
|
|
259
|
+
let canonical: string;
|
|
260
|
+
try {
|
|
261
|
+
canonical = realpathSync.native(candidate);
|
|
262
|
+
} catch {
|
|
263
|
+
canonical = resolve(candidate);
|
|
264
|
+
}
|
|
265
|
+
return process.platform === "win32" ? canonical.toLowerCase() : canonical;
|
|
266
|
+
};
|
|
267
|
+
const globalConfigIdentity = normalizeExistingPath(codexConfigPath);
|
|
255
268
|
const addIfExists = (projectRoot: string) => {
|
|
256
|
-
const
|
|
257
|
-
|
|
269
|
+
const candidate = join(resolve(projectRoot), ".codex", "config.toml");
|
|
270
|
+
const candidateIdentity = normalizeExistingPath(candidate);
|
|
271
|
+
if (candidateIdentity && candidateIdentity !== globalConfigIdentity) found.add(candidate);
|
|
258
272
|
};
|
|
259
273
|
|
|
260
274
|
let cwd = resolve(options.cwd ?? process.cwd());
|
|
@@ -339,7 +353,7 @@ export function summarizeProjectCodexIssue(warning: ProjectCodexConfigWarning):
|
|
|
339
353
|
|
|
340
354
|
function humanizeProviderDetail(detail: string): string {
|
|
341
355
|
if (detail === "opencode_go") return "OpenCode Go";
|
|
342
|
-
if (
|
|
356
|
+
if (/^opencode(?:$|[-_.:/])/.test(detail)) return "OpenCode";
|
|
343
357
|
if (detail === "opencodex") return "OpenCodex";
|
|
344
358
|
return detail;
|
|
345
359
|
}
|
|
@@ -408,4 +422,4 @@ export function printProjectCodexConfigWarnings(
|
|
|
408
422
|
}
|
|
409
423
|
}
|
|
410
424
|
return warnings;
|
|
411
|
-
}
|
|
425
|
+
}
|