@iislee/opencodex 2.11.0 → 2.35.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 +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -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 +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -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 +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- 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 +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- 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 +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- 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 +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- 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 +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- 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 +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- 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 +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- 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 +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -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 +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- 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 +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -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/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -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 +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -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 +360 -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 +622 -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 +675 -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 +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -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 +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -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 +157 -33
- package/src/images/plan.ts +24 -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-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -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/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- 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 +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- 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/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- 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/service-secrets.ts +15 -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 +253 -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 +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -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/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- 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/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -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 +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -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 +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -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 +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -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 +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -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 +155 -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 +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- 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 +1021 -190
- package/src/server/lifecycle.ts +336 -14
- 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 +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -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 +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -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 +289 -33
- 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 +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- 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/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -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 +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -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 +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -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 +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- 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 +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- 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 +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- 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 +27 -16
- 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 +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- 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
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { isAbsolute } from "node:path";
|
|
2
|
+
import { codexExecInvocation } from "../codex/exec-invocation";
|
|
3
|
+
import { resolveAndPersistCodexRuntime, type ResolveCodexRuntimeDeps } from "../codex/runtime";
|
|
4
|
+
import type { ResolveDeps, SpawnInvocation } from "../lib/win-exec";
|
|
5
|
+
import {
|
|
6
|
+
apiError,
|
|
7
|
+
apiJson,
|
|
8
|
+
proxyUnreachable,
|
|
9
|
+
resolveBaseUrl,
|
|
10
|
+
type AccountDeps,
|
|
11
|
+
type NativeMainLoginChild,
|
|
12
|
+
type StageLeaseClock,
|
|
13
|
+
} from "./account-api";
|
|
14
|
+
|
|
15
|
+
const USAGE = `Usage:
|
|
16
|
+
ocx account main doctor [--json]
|
|
17
|
+
ocx account main list [--json]
|
|
18
|
+
ocx account main register <label> [--json]
|
|
19
|
+
ocx account main add <label>
|
|
20
|
+
ocx account main switch <profile-id-or-label> --yes [--json]
|
|
21
|
+
ocx account main recover [--rollback --yes] [--json]
|
|
22
|
+
|
|
23
|
+
Native main login profiles change the physical Codex App/CLI login in the effective CODEX_HOME.
|
|
24
|
+
They are independent from the OpenCodex Pool selected by 'ocx account use openai'.`;
|
|
25
|
+
|
|
26
|
+
const STAGE_LEASE_SAFETY_MARGIN_MS = 30_000;
|
|
27
|
+
|
|
28
|
+
const systemStageLeaseClock: StageLeaseClock = {
|
|
29
|
+
now: Date.now,
|
|
30
|
+
setTimeout: (callback, ms) => setTimeout(callback, ms),
|
|
31
|
+
clearTimeout: timer => clearTimeout(timer),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
interface PublicProfile {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
identityHint: string;
|
|
38
|
+
state: "active" | "inactive";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type NativeMainCodexLoginInvocationDeps =
|
|
42
|
+
& ResolveDeps
|
|
43
|
+
& Pick<ResolveCodexRuntimeDeps, "existsSync" | "execFileSync" | "configDir" | "readFileSync">;
|
|
44
|
+
|
|
45
|
+
function flag(args: string[], name: string): boolean {
|
|
46
|
+
const index = args.indexOf(name);
|
|
47
|
+
if (index < 0) return false;
|
|
48
|
+
args.splice(index, 1);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function reject(args: string[]): number {
|
|
53
|
+
if (args.length > 0) console.error(`Unexpected argument(s): ${args.join(", ")}`);
|
|
54
|
+
console.error(USAGE);
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function effectiveCodexHome(result: Record<string, unknown>): string {
|
|
59
|
+
return typeof result.effectiveCodexHome === "string" && result.effectiveCodexHome.length > 0
|
|
60
|
+
? result.effectiveCodexHome
|
|
61
|
+
: "the effective CODEX_HOME";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function printProfiles(profiles: PublicProfile[]): void {
|
|
65
|
+
if (profiles.length === 0) { console.log("No native main login profiles registered."); return; }
|
|
66
|
+
const rows = profiles.map(profile => [profile.state === "active" ? "*" : " ", profile.label, profile.id, profile.identityHint]);
|
|
67
|
+
const header = ["", "LABEL", "PROFILE ID", "IDENTITY"];
|
|
68
|
+
const widths = header.map((value, index) => Math.max(value.length, ...rows.map(row => row[index]!.length)));
|
|
69
|
+
const line = (columns: string[]) => columns.map((value, index) => value.padEnd(widths[index]!)).join(" ").trimEnd();
|
|
70
|
+
console.log([line(header), ...rows.map(line)].join("\n"));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function nativeMainCodexLoginInvocation(
|
|
74
|
+
platform: NodeJS.Platform = process.platform,
|
|
75
|
+
deps: NativeMainCodexLoginInvocationDeps = {},
|
|
76
|
+
): SpawnInvocation {
|
|
77
|
+
const command = resolveAndPersistCodexRuntime({
|
|
78
|
+
env: deps.env ?? process.env,
|
|
79
|
+
platform,
|
|
80
|
+
existsSync: deps.existsSync,
|
|
81
|
+
execFileSync: deps.execFileSync,
|
|
82
|
+
configDir: deps.configDir,
|
|
83
|
+
readFileSync: deps.readFileSync,
|
|
84
|
+
discoverAlternatives: false,
|
|
85
|
+
}).runtime.command || "codex";
|
|
86
|
+
return codexExecInvocation(command, ["login"], platform, deps);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function spawnOfficialCodexLogin(codexHome: string): NativeMainLoginChild {
|
|
90
|
+
const invocation = nativeMainCodexLoginInvocation();
|
|
91
|
+
const child = Bun.spawn([invocation.file, ...invocation.args], {
|
|
92
|
+
env: { ...process.env, CODEX_HOME: codexHome },
|
|
93
|
+
stdin: "inherit",
|
|
94
|
+
stdout: "inherit",
|
|
95
|
+
stderr: "inherit",
|
|
96
|
+
...(invocation.options.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
|
|
97
|
+
});
|
|
98
|
+
return child;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function abortableDelay(ms: number, signal: AbortSignal, clock: StageLeaseClock): Promise<void> {
|
|
102
|
+
if (signal.aborted) return Promise.resolve();
|
|
103
|
+
return new Promise(resolve => {
|
|
104
|
+
const timer = clock.setTimeout(done, ms);
|
|
105
|
+
signal.addEventListener("abort", done, { once: true });
|
|
106
|
+
function done(): void {
|
|
107
|
+
clock.clearTimeout(timer);
|
|
108
|
+
signal.removeEventListener("abort", done);
|
|
109
|
+
resolve();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function maintainStageLease(
|
|
115
|
+
deps: AccountDeps,
|
|
116
|
+
baseUrl: string,
|
|
117
|
+
stageId: string,
|
|
118
|
+
writerToken: string,
|
|
119
|
+
initialLeaseExpiresAt: number,
|
|
120
|
+
heartbeatIntervalMs: number,
|
|
121
|
+
child: NativeMainLoginChild,
|
|
122
|
+
signal: AbortSignal,
|
|
123
|
+
clock: StageLeaseClock,
|
|
124
|
+
): Promise<{ lost: boolean }> {
|
|
125
|
+
let leaseExpiresAt = initialLeaseExpiresAt;
|
|
126
|
+
for (;;) {
|
|
127
|
+
if (signal.aborted) return { lost: false };
|
|
128
|
+
const deadlineAt = leaseExpiresAt - STAGE_LEASE_SAFETY_MARGIN_MS;
|
|
129
|
+
if (clock.now() >= deadlineAt) {
|
|
130
|
+
try { child.kill(); } catch { /* child exit below is authoritative */ }
|
|
131
|
+
return { lost: true };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const heartbeatAbort = new AbortController();
|
|
135
|
+
const deadlineReached = Symbol("heartbeat-deadline");
|
|
136
|
+
const parentCancelled = Symbol("heartbeat-parent-cancelled");
|
|
137
|
+
let resolveInterruption!: (result: typeof deadlineReached | typeof parentCancelled) => void;
|
|
138
|
+
const interruption = new Promise<typeof deadlineReached | typeof parentCancelled>(resolve => {
|
|
139
|
+
resolveInterruption = resolve;
|
|
140
|
+
});
|
|
141
|
+
const cancelHeartbeat = () => {
|
|
142
|
+
heartbeatAbort.abort();
|
|
143
|
+
resolveInterruption(parentCancelled);
|
|
144
|
+
};
|
|
145
|
+
signal.addEventListener("abort", cancelHeartbeat, { once: true });
|
|
146
|
+
const deadlineTimer = clock.setTimeout(() => {
|
|
147
|
+
heartbeatAbort.abort();
|
|
148
|
+
resolveInterruption(deadlineReached);
|
|
149
|
+
}, Math.max(0, deadlineAt - clock.now()));
|
|
150
|
+
const heartbeatRequest = apiJson(
|
|
151
|
+
deps,
|
|
152
|
+
baseUrl,
|
|
153
|
+
"POST",
|
|
154
|
+
"/api/native-main-profiles/stage/heartbeat",
|
|
155
|
+
{ stageId, writerToken },
|
|
156
|
+
{ signal: heartbeatAbort.signal },
|
|
157
|
+
);
|
|
158
|
+
const heartbeat = await Promise.race([heartbeatRequest, interruption]);
|
|
159
|
+
clock.clearTimeout(deadlineTimer);
|
|
160
|
+
signal.removeEventListener("abort", cancelHeartbeat);
|
|
161
|
+
if (signal.aborted) return { lost: false };
|
|
162
|
+
if (heartbeat === parentCancelled) return { lost: false };
|
|
163
|
+
if (heartbeat === deadlineReached) {
|
|
164
|
+
try { child.kill(); } catch { /* child exit below is authoritative */ }
|
|
165
|
+
return { lost: true };
|
|
166
|
+
}
|
|
167
|
+
if (heartbeat.status === 200 && typeof heartbeat.json.leaseExpiresAt === "number") {
|
|
168
|
+
leaseExpiresAt = heartbeat.json.leaseExpiresAt;
|
|
169
|
+
await abortableDelay(Math.min(heartbeatIntervalMs, Math.max(0, leaseExpiresAt - STAGE_LEASE_SAFETY_MARGIN_MS - clock.now())), signal, clock);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (heartbeat.status === 0 && clock.now() < leaseExpiresAt - STAGE_LEASE_SAFETY_MARGIN_MS) {
|
|
173
|
+
await abortableDelay(Math.min(5_000, heartbeatIntervalMs, leaseExpiresAt - STAGE_LEASE_SAFETY_MARGIN_MS - clock.now()), signal, clock);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
try { child.kill(); } catch { /* child exit below is authoritative */ }
|
|
177
|
+
return { lost: true };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export async function cmdNativeMainAccount(args: string[], deps: AccountDeps): Promise<number> {
|
|
182
|
+
const sub = args.shift();
|
|
183
|
+
const wantsJson = flag(args, "--json");
|
|
184
|
+
const confirmed = flag(args, "--yes");
|
|
185
|
+
const rollback = flag(args, "--rollback");
|
|
186
|
+
const baseUrl = await resolveBaseUrl(deps);
|
|
187
|
+
if (!baseUrl) return proxyUnreachable();
|
|
188
|
+
|
|
189
|
+
if (sub === "doctor" || sub === "list") {
|
|
190
|
+
if (args.length > 0 || confirmed || rollback) return reject(args);
|
|
191
|
+
const path = sub === "doctor" ? "/api/native-main-profiles/doctor" : "/api/native-main-profiles";
|
|
192
|
+
const result = await apiJson(deps, baseUrl, "GET", path);
|
|
193
|
+
if (result.status === 0) return proxyUnreachable(result.transportError);
|
|
194
|
+
if (result.status !== 200) return apiError(result.json, `failed to ${sub} native profiles`, result.status);
|
|
195
|
+
if (wantsJson || sub === "doctor") console.log(JSON.stringify(result.json, null, 2));
|
|
196
|
+
else printProfiles(Array.isArray(result.json.profiles) ? result.json.profiles as PublicProfile[] : []);
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (sub === "register") {
|
|
201
|
+
const label = args.shift();
|
|
202
|
+
if (!label || args.length > 0 || confirmed || rollback) return reject(args);
|
|
203
|
+
const result = await apiJson(deps, baseUrl, "POST", "/api/native-main-profiles/register", { label });
|
|
204
|
+
if (result.status === 0) return proxyUnreachable(result.transportError);
|
|
205
|
+
if (result.status !== 200) return apiError(result.json, "failed to register the current native login", result.status);
|
|
206
|
+
if (wantsJson) console.log(JSON.stringify(result.json, null, 2));
|
|
207
|
+
else console.log(`Registered '${label}' for ${effectiveCodexHome(result.json)}.`);
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (sub === "add") {
|
|
212
|
+
const label = args.shift();
|
|
213
|
+
if (!label || args.length > 0 || wantsJson || confirmed || rollback) return reject(args);
|
|
214
|
+
const stage = await apiJson(deps, baseUrl, "POST", "/api/native-main-profiles/stage", {});
|
|
215
|
+
if (stage.status === 0) return proxyUnreachable(stage.transportError);
|
|
216
|
+
if (stage.status !== 200) return apiError(stage.json, "failed to prepare native login staging", stage.status);
|
|
217
|
+
const stageId = typeof stage.json.stageId === "string" ? stage.json.stageId : "";
|
|
218
|
+
const writerToken = typeof stage.json.writerToken === "string" ? stage.json.writerToken : "";
|
|
219
|
+
const stagingHome = typeof stage.json.stagingCodexHome === "string" ? stage.json.stagingCodexHome : "";
|
|
220
|
+
const leaseExpiresAt = typeof stage.json.leaseExpiresAt === "number" ? stage.json.leaseExpiresAt : 0;
|
|
221
|
+
const heartbeatIntervalMs = typeof stage.json.heartbeatIntervalMs === "number"
|
|
222
|
+
? Math.min(5 * 60_000, Math.max(deps.stageHeartbeatIntervalMinMs ?? 5_000, stage.json.heartbeatIntervalMs))
|
|
223
|
+
: 60_000;
|
|
224
|
+
const stageLeaseClock = deps.stageLeaseClock ?? systemStageLeaseClock;
|
|
225
|
+
const stagedEffectiveHome = effectiveCodexHome(stage.json);
|
|
226
|
+
let exitCode = 1;
|
|
227
|
+
let finished = false;
|
|
228
|
+
let leaseLost = false;
|
|
229
|
+
try {
|
|
230
|
+
if (!stageId || !writerToken || !isAbsolute(stagingHome) || leaseExpiresAt <= stageLeaseClock.now()) {
|
|
231
|
+
throw new Error("The proxy returned an invalid staging session.");
|
|
232
|
+
}
|
|
233
|
+
console.error(`Effective CODEX_HOME: ${stagedEffectiveHome}`);
|
|
234
|
+
console.error(`Starting official Codex login in restricted staging home: ${stagingHome}`);
|
|
235
|
+
const child = deps.spawnCodexLoginImpl
|
|
236
|
+
? deps.spawnCodexLoginImpl(stagingHome)
|
|
237
|
+
: deps.runCodexLoginImpl
|
|
238
|
+
? { exited: deps.runCodexLoginImpl(stagingHome), kill: () => {} }
|
|
239
|
+
: spawnOfficialCodexLogin(stagingHome);
|
|
240
|
+
const heartbeatAbort = new AbortController();
|
|
241
|
+
const heartbeat = maintainStageLease(
|
|
242
|
+
deps,
|
|
243
|
+
baseUrl,
|
|
244
|
+
stageId,
|
|
245
|
+
writerToken,
|
|
246
|
+
leaseExpiresAt,
|
|
247
|
+
heartbeatIntervalMs,
|
|
248
|
+
child,
|
|
249
|
+
heartbeatAbort.signal,
|
|
250
|
+
stageLeaseClock,
|
|
251
|
+
);
|
|
252
|
+
try {
|
|
253
|
+
exitCode = await child.exited;
|
|
254
|
+
} finally {
|
|
255
|
+
heartbeatAbort.abort();
|
|
256
|
+
leaseLost = (await heartbeat).lost;
|
|
257
|
+
}
|
|
258
|
+
if (leaseLost) throw new Error("The native-login staging lease was lost before login completed.");
|
|
259
|
+
if (exitCode !== 0) throw new Error("Official Codex login did not complete successfully.");
|
|
260
|
+
const finish = await apiJson(deps, baseUrl, "POST", "/api/native-main-profiles/stage/finish", { stageId, writerToken, label });
|
|
261
|
+
if (finish.status === 0) return proxyUnreachable(finish.transportError);
|
|
262
|
+
if (finish.status !== 200) return apiError(finish.json, "failed to encrypt the staged native login", finish.status);
|
|
263
|
+
finished = true;
|
|
264
|
+
console.log(`Added encrypted native profile '${label}' for ${effectiveCodexHome(finish.json)}.`);
|
|
265
|
+
return 0;
|
|
266
|
+
} catch (error) {
|
|
267
|
+
console.error(`Error: ${error instanceof Error ? error.message : "Official Codex login failed."}`);
|
|
268
|
+
return exitCode === 0 ? 1 : exitCode;
|
|
269
|
+
} finally {
|
|
270
|
+
if (stageId && !finished) {
|
|
271
|
+
const cleanup = await apiJson(deps, baseUrl, "POST", "/api/native-main-profiles/stage/cancel", { stageId, writerToken });
|
|
272
|
+
if (cleanup.status !== 200 || cleanup.json.plaintextMayRemain === true) {
|
|
273
|
+
console.error("Error: the proxy could not confirm native-login staging cleanup; run account main doctor.");
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (sub === "switch") {
|
|
280
|
+
const target = args.shift();
|
|
281
|
+
if (!target || args.length > 0 || rollback || !confirmed) {
|
|
282
|
+
if (!confirmed) console.error("Close Codex App/CLI, then pass --yes to confirm it is stopped.");
|
|
283
|
+
return reject(args);
|
|
284
|
+
}
|
|
285
|
+
const result = await apiJson(deps, baseUrl, "POST", "/api/native-main-profiles/switch", { target, confirmedStopped: true });
|
|
286
|
+
if (result.status === 0) return proxyUnreachable(result.transportError);
|
|
287
|
+
if (result.status !== 200) return apiError(result.json, "failed to switch the native login", result.status);
|
|
288
|
+
if (wantsJson) console.log(JSON.stringify(result.json, null, 2));
|
|
289
|
+
else {
|
|
290
|
+
const profile = result.json.activeProfile as PublicProfile | undefined;
|
|
291
|
+
console.log(`Native Codex login for ${effectiveCodexHome(result.json)} is now '${profile?.label ?? target}'. Restart Codex App/CLI before continuing.`);
|
|
292
|
+
}
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (sub === "recover") {
|
|
297
|
+
if (args.length > 0 || (rollback && !confirmed)) {
|
|
298
|
+
if (rollback && !confirmed) console.error("--rollback changes the native login and requires --yes.");
|
|
299
|
+
return reject(args);
|
|
300
|
+
}
|
|
301
|
+
const result = await apiJson(deps, baseUrl, "POST", "/api/native-main-profiles/recover", rollback
|
|
302
|
+
? { rollback: true, confirmedStopped: true }
|
|
303
|
+
: { rollback: false });
|
|
304
|
+
if (result.status === 0) return proxyUnreachable(result.transportError);
|
|
305
|
+
if (result.status !== 200) return apiError(result.json, "failed to recover the native-profile transaction", result.status);
|
|
306
|
+
if (wantsJson) console.log(JSON.stringify(result.json, null, 2));
|
|
307
|
+
else {
|
|
308
|
+
const home = effectiveCodexHome(result.json);
|
|
309
|
+
console.log(result.json.recovered === true
|
|
310
|
+
? `Recovery completed for ${home}: ${String(result.json.action ?? "converged")}.`
|
|
311
|
+
: `No recovery journal is pending for ${home}.`);
|
|
312
|
+
}
|
|
313
|
+
return 0;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return reject(args);
|
|
317
|
+
}
|
package/src/cli/account.ts
CHANGED
|
@@ -2,7 +2,20 @@
|
|
|
2
2
|
import { loadConfig } from "../config";
|
|
3
3
|
import { providerCodexAccountMode } from "../providers/registry";
|
|
4
4
|
import type { OcxConfig } from "../types";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
cmdAddKey,
|
|
7
|
+
cmdAlias,
|
|
8
|
+
cmdAutoSwitch,
|
|
9
|
+
cmdClearCooldown,
|
|
10
|
+
cmdImport,
|
|
11
|
+
cmdPause,
|
|
12
|
+
cmdPauseExhausted,
|
|
13
|
+
cmdPriority,
|
|
14
|
+
cmdRefresh,
|
|
15
|
+
cmdRemove,
|
|
16
|
+
cmdSticky,
|
|
17
|
+
cmdStrategy,
|
|
18
|
+
} from "./account-extended";
|
|
6
19
|
import { apiError, apiJson, classifyAccount, fetchRows, proxyUnreachable, resolveBaseUrl, type AccountDeps, type AccountRow, type AccountType, type ApiResult }
|
|
7
20
|
from "./account-api";
|
|
8
21
|
|
|
@@ -16,19 +29,27 @@ const MAIN_CODEX_ID = "__main__";
|
|
|
16
29
|
const REPLACEMENT_STYLE_OAUTH = new Set(["kiro"]);
|
|
17
30
|
|
|
18
31
|
const ACCOUNT_USAGE = `Usage:
|
|
19
|
-
ocx account list [provider] [--json] [--all]
|
|
32
|
+
ocx account list [provider] [--json] [--all] [--quota [--refresh]]
|
|
20
33
|
ocx account current <provider> [--json]
|
|
21
34
|
ocx account use <provider> <account-or-key-id|main> [--json]
|
|
22
35
|
ocx account refresh <provider> [--json]
|
|
23
36
|
ocx account auto-switch <provider> <on|off|status|threshold <0-100>> [--json]
|
|
24
37
|
ocx account alias <provider> <account-or-key-id> <display-name|-> [--json]
|
|
38
|
+
ocx account priority <provider> <account-id|main> [<-100..100|first|earlier|normal|later|last|reset>] [--json]
|
|
39
|
+
ocx account pause <provider> <account-id|main> [--json]
|
|
40
|
+
ocx account resume <provider> <account-id|main> [--json]
|
|
41
|
+
ocx account pause-exhausted <provider> [--json]
|
|
42
|
+
ocx account strategy <provider> [<quota|round-robin|fill-first>] [--json]
|
|
43
|
+
ocx account sticky <provider> [<1-100>] [--json]
|
|
25
44
|
ocx account remove <provider> <account-or-key-id|main> --yes [--json]
|
|
26
45
|
ocx account clear-cooldown <provider> <account-id|main> [--json]
|
|
27
46
|
ocx account add-key <provider> [--label <label>] [--json]
|
|
47
|
+
ocx account import <provider> --format <format> (--file <path>|--stdin) [--json]
|
|
28
48
|
ocx account login <provider> [--id <account-id>] [--reauth] [--code -] [--no-wait] [--json]
|
|
29
49
|
ocx account code <provider> [--flow <flow-id>] [--json] (reads the code from stdin)
|
|
30
50
|
ocx account cancel <provider> [--flow <flow-id>] [--json]
|
|
31
51
|
ocx account reset-credits <account-id|main> [--consume --yes] [--json]
|
|
52
|
+
ocx account main <doctor|list|register|add|switch|recover> ...
|
|
32
53
|
|
|
33
54
|
List and switch provider accounts and API-key pools (masked output only).
|
|
34
55
|
'main' selects the Codex App login for the openai account pool.`;
|
|
@@ -61,16 +82,53 @@ function displayId(id: string): string {
|
|
|
61
82
|
|
|
62
83
|
function statusText(row: AccountRow): string {
|
|
63
84
|
const parts: string[] = [];
|
|
85
|
+
// `paused` leads, and does NOT replace `selected`. A paused-but-selected account is the
|
|
86
|
+
// state an operator most needs named -- requests route to it while the pool believes it is
|
|
87
|
+
// held out -- so printing only one of the two would hide exactly the confusing case (#2703).
|
|
88
|
+
if (row.paused) parts.push("paused");
|
|
64
89
|
if (row.active) parts.push(row.type === "codex" ? "selected" : "active");
|
|
65
90
|
if (row.needsReauth) parts.push("needs-reauth");
|
|
66
91
|
return parts.join(" ");
|
|
67
92
|
}
|
|
68
93
|
|
|
69
|
-
|
|
70
|
-
|
|
94
|
+
/** Signed so the sort direction reads off the column; "-" where ordering does not apply. */
|
|
95
|
+
function priorityText(row: AccountRow): string {
|
|
96
|
+
if (row.priority === undefined) return "-";
|
|
97
|
+
return row.priority > 0 ? `+${row.priority}` : String(row.priority);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Compact per-account quota for the opt-in QUOTA column: the two windows an operator actually
|
|
102
|
+
* decides on before a long session. The full breakdown stays in `--json`.
|
|
103
|
+
*/
|
|
104
|
+
function quotaText(row: AccountRow): string {
|
|
105
|
+
if ((row as { quotaUnavailable?: boolean }).quotaUnavailable) return "unavailable";
|
|
106
|
+
const quota = row.quota;
|
|
107
|
+
if (!quota) return "-";
|
|
108
|
+
const parts: string[] = [];
|
|
109
|
+
// Two spellings reach this DTO: the per-account provider probe reports `fiveHourPercent`,
|
|
110
|
+
// while the Codex pool reports the same idea as `shortPercent`.
|
|
111
|
+
const short = quota.fiveHourPercent ?? quota.shortPercent;
|
|
112
|
+
if (typeof short === "number") parts.push(`5h ${short}%`);
|
|
113
|
+
if (typeof quota.weeklyPercent === "number") parts.push(`wk ${quota.weeklyPercent}%`);
|
|
114
|
+
return parts.length > 0 ? parts.join(" ") : "-";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function formatAccountTable(rows: AccountRow[], withQuota = false): string {
|
|
118
|
+
const header = ["PROVIDER", "TYPE", "ID", "PLAN/LABEL", "PRIORITY", "STATUS"];
|
|
119
|
+
if (withQuota) header.push("QUOTA");
|
|
71
120
|
const data = rows.map(r => {
|
|
72
121
|
const keyLabel = r.masked && r.label !== r.masked ? `${r.masked} (${r.label})` : r.masked;
|
|
73
|
-
|
|
122
|
+
const cols = [
|
|
123
|
+
r.provider,
|
|
124
|
+
r.type,
|
|
125
|
+
displayId(r.id),
|
|
126
|
+
r.type === "api-key" ? keyLabel ?? "-" : r.label ?? "-",
|
|
127
|
+
priorityText(r),
|
|
128
|
+
statusText(r),
|
|
129
|
+
];
|
|
130
|
+
if (withQuota) cols.push(quotaText(r));
|
|
131
|
+
return cols;
|
|
74
132
|
});
|
|
75
133
|
const widths = header.map((h, i) => Math.max(h.length, ...data.map(d => d[i]!.length)));
|
|
76
134
|
const line = (cols: string[]) => cols.map((c, i) => c.padEnd(widths[i]!)).join(" ").trimEnd();
|
|
@@ -80,6 +138,10 @@ export function formatAccountTable(rows: AccountRow[]): string {
|
|
|
80
138
|
async function cmdList(rest: string[], deps: AccountDeps): Promise<number> {
|
|
81
139
|
const wantsJson = consumeFlag(rest, "--json");
|
|
82
140
|
const showAll = consumeFlag(rest, "--all");
|
|
141
|
+
// Opt-in: the server probes the upstream once per stored credential, so the default listing
|
|
142
|
+
// stays a cheap local read (#2566). --refresh bypasses the server-side TTL.
|
|
143
|
+
const wantsQuota = consumeFlag(rest, "--quota");
|
|
144
|
+
const refreshQuota = consumeFlag(rest, "--refresh");
|
|
83
145
|
const name = rest.shift();
|
|
84
146
|
const leftover = leftoverArgsError(rest);
|
|
85
147
|
if (leftover) {
|
|
@@ -110,8 +172,8 @@ async function cmdList(rest: string[], deps: AccountDeps): Promise<number> {
|
|
|
110
172
|
};
|
|
111
173
|
push("openai", "codex");
|
|
112
174
|
const providersRes = await apiJson(deps, baseUrl, "GET", "/api/oauth/providers");
|
|
113
|
-
if (providersRes.status === 0) return proxyUnreachable();
|
|
114
|
-
if (providersRes.status !== 200) return apiError(providersRes.json, "failed to list OAuth providers");
|
|
175
|
+
if (providersRes.status === 0) return proxyUnreachable(providersRes.transportError);
|
|
176
|
+
if (providersRes.status !== 200) return apiError(providersRes.json, "failed to list OAuth providers", providersRes.status);
|
|
115
177
|
if (Array.isArray(providersRes.json.providers)) {
|
|
116
178
|
for (const p of providersRes.json.providers) {
|
|
117
179
|
if (typeof p === "string") push(p, "live-oauth-list");
|
|
@@ -123,10 +185,11 @@ async function cmdList(rest: string[], deps: AccountDeps): Promise<number> {
|
|
|
123
185
|
const rows: AccountRow[] = [];
|
|
124
186
|
const notes: string[] = [];
|
|
125
187
|
for (const t of targets) {
|
|
126
|
-
const r = await fetchRows(deps, baseUrl, t.name, t.type);
|
|
127
|
-
if (r.networkDown) return proxyUnreachable();
|
|
188
|
+
const r = await fetchRows(deps, baseUrl, t.name, t.type, wantsQuota ? { refresh: refreshQuota } : undefined);
|
|
189
|
+
if (r.networkDown) return proxyUnreachable(r.transportError);
|
|
128
190
|
if (r.errorJson) {
|
|
129
|
-
if (name) return apiError(r.errorJson, `failed to list ${t.name}
|
|
191
|
+
if (name) return apiError(r.errorJson, `failed to list ${t.name}`, r.status);
|
|
192
|
+
|
|
130
193
|
const errorText = typeof r.errorJson.error === "string" ? r.errorJson.error : "";
|
|
131
194
|
const skipUnknownKey = t.type === "api-key"
|
|
132
195
|
&& r.status === 404
|
|
@@ -136,7 +199,7 @@ async function cmdList(rest: string[], deps: AccountDeps): Promise<number> {
|
|
|
136
199
|
&& r.status === 400
|
|
137
200
|
&& errorText.includes("unknown oauth provider");
|
|
138
201
|
if (skipUnknownKey || skipConfigOAuth) continue;
|
|
139
|
-
return apiError(r.errorJson, `failed to list ${t.name}
|
|
202
|
+
return apiError(r.errorJson, `failed to list ${t.name}`, r.status);
|
|
140
203
|
}
|
|
141
204
|
if (r.rows.length === 0) {
|
|
142
205
|
if (showAll) notes.push(`${t.name}: no stored accounts or keys`);
|
|
@@ -158,7 +221,7 @@ async function cmdList(rest: string[], deps: AccountDeps): Promise<number> {
|
|
|
158
221
|
console.log(JSON.stringify({ accounts: rows, notes }, null, 2));
|
|
159
222
|
return 0;
|
|
160
223
|
}
|
|
161
|
-
if (rows.length > 0) console.log(formatAccountTable(rows));
|
|
224
|
+
if (rows.length > 0) console.log(formatAccountTable(rows, wantsQuota));
|
|
162
225
|
for (const n of notes) console.log(n);
|
|
163
226
|
if (rows.length === 0 && notes.length === 0) console.log("No stored accounts or keys.");
|
|
164
227
|
return 0;
|
|
@@ -182,8 +245,8 @@ async function cmdCurrent(rest: string[], deps: AccountDeps): Promise<number> {
|
|
|
182
245
|
const baseUrl = await resolveBaseUrl(deps);
|
|
183
246
|
if (!baseUrl) return proxyUnreachable();
|
|
184
247
|
const r = await fetchRows(deps, baseUrl, name, c.type);
|
|
185
|
-
if (r.networkDown) return proxyUnreachable();
|
|
186
|
-
if (r.errorJson) return apiError(r.errorJson, `failed to read ${name}
|
|
248
|
+
if (r.networkDown) return proxyUnreachable(r.transportError);
|
|
249
|
+
if (r.errorJson) return apiError(r.errorJson, `failed to read ${name}`, r.status);
|
|
187
250
|
|
|
188
251
|
const activeRow = r.rows.find(row => row.active) ?? null;
|
|
189
252
|
if (wantsJson) {
|
|
@@ -237,15 +300,17 @@ async function cmdUse(rest: string[], deps: AccountDeps): Promise<number> {
|
|
|
237
300
|
activeId = id;
|
|
238
301
|
res = await apiJson(deps, baseUrl, "PUT", "/api/providers/keys/active", { name, id });
|
|
239
302
|
}
|
|
240
|
-
if (res.status === 0) return proxyUnreachable();
|
|
241
|
-
if (res.status !== 200) return apiError(res.json, `failed to switch ${name}
|
|
303
|
+
if (res.status === 0) return proxyUnreachable(res.transportError);
|
|
304
|
+
if (res.status !== 200) return apiError(res.json, `failed to switch ${name}`, res.status);
|
|
242
305
|
|
|
243
306
|
if (wantsJson) console.log(JSON.stringify({ ok: true, provider: name, type: c.type, activeId }, null, 2));
|
|
244
307
|
else console.log(`${name}: active ${c.type === "api-key" ? "key" : "account"} is now ${displayId(activeId)}`);
|
|
245
308
|
if (c.type === "codex") {
|
|
246
|
-
console.error("
|
|
247
|
-
|
|
248
|
-
|
|
309
|
+
console.error("Takes effect immediately; running threads move on their next request, and in-flight requests keep the account they captured.");
|
|
310
|
+
const active = await apiJson(deps, baseUrl, "GET", "/api/codex-auth/active");
|
|
311
|
+
if (active.status === 200 && typeof active.json.autoSwitchThreshold === "number" && active.json.autoSwitchThreshold > 0) {
|
|
312
|
+
console.error(`Note: auto-switch (threshold ${active.json.autoSwitchThreshold}%) may override this pin.`);
|
|
313
|
+
}
|
|
249
314
|
}
|
|
250
315
|
return 0;
|
|
251
316
|
}
|
|
@@ -259,9 +324,22 @@ export async function cmdAccount(args: string[], deps: AccountDeps = {}): Promis
|
|
|
259
324
|
if (sub === "refresh") return await cmdRefresh(rest, deps);
|
|
260
325
|
if (sub === "auto-switch") return await cmdAutoSwitch(rest, deps);
|
|
261
326
|
if (sub === "alias" || sub === "rename") return await cmdAlias(rest, deps);
|
|
327
|
+
if (sub === "priority") return await cmdPriority(rest, deps);
|
|
328
|
+
// #2702: the server routes existed and only the CLI caller was missing, so these were
|
|
329
|
+
// dashboard-only capabilities.
|
|
330
|
+
if (sub === "pause") return await cmdPause(rest, deps, true);
|
|
331
|
+
if (sub === "resume") return await cmdPause(rest, deps, false);
|
|
332
|
+
if (sub === "pause-exhausted") return await cmdPauseExhausted(rest, deps);
|
|
333
|
+
if (sub === "strategy") return await cmdStrategy(rest, deps);
|
|
334
|
+
if (sub === "sticky") return await cmdSticky(rest, deps);
|
|
262
335
|
if (sub === "remove") return await cmdRemove(rest, deps);
|
|
263
336
|
if (sub === "clear-cooldown") return await cmdClearCooldown(rest, deps);
|
|
264
337
|
if (sub === "add-key") return await cmdAddKey(rest, deps);
|
|
338
|
+
if (sub === "import") return await cmdImport(rest, deps);
|
|
339
|
+
if (sub === "main") {
|
|
340
|
+
const { cmdNativeMainAccount } = await import("./account-main");
|
|
341
|
+
return await cmdNativeMainAccount(rest, deps);
|
|
342
|
+
}
|
|
265
343
|
if (["login", "reauth", "code", "cancel", "reset-credits"].includes(sub ?? "")) {
|
|
266
344
|
const { handleAccountAuthCommand } = await import("./account-auth");
|
|
267
345
|
return await handleAccountAuthCommand(sub!, rest, deps) ?? 1;
|
package/src/cli/agent.ts
CHANGED
|
@@ -13,6 +13,13 @@ import {
|
|
|
13
13
|
type RuntimeApiDeps,
|
|
14
14
|
} from "./runtime-api";
|
|
15
15
|
|
|
16
|
+
interface WebSearchModelOption {
|
|
17
|
+
value: string;
|
|
18
|
+
model: string;
|
|
19
|
+
backend: "openai" | "anthropic";
|
|
20
|
+
authSlot?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
const USAGE = `Usage:
|
|
17
24
|
ocx agent [status] [--json]
|
|
18
25
|
ocx agent injection <status|set> [--model <id|->] [--effort <level|->]
|
|
@@ -20,8 +27,10 @@ const USAGE = `Usage:
|
|
|
20
27
|
ocx agent effort <status|set> [--main <level|->] [--subagent <level|->] [--json]
|
|
21
28
|
ocx agent subagents <status|set|clear> [model,model...] [--json]
|
|
22
29
|
ocx agent fallback <status|set|clear> [model,model...] [--poll-ms <5000-600000>] [--json]
|
|
23
|
-
ocx agent sidecar <status|web|vision> [--
|
|
24
|
-
[--
|
|
30
|
+
ocx agent sidecar <status|web|vision> [--list] [--model <id|->]
|
|
31
|
+
[--backend web:<openai|anthropic|xai|gemini|exa|-> vision:<openai|anthropic|routed|->]
|
|
32
|
+
[--reasoning <level>] [--max-descriptions <n>] [--json]
|
|
33
|
+
ocx agent request-user-input [on|off] [--json]`;
|
|
25
34
|
|
|
26
35
|
function clearable(value: string | undefined): string | null | undefined {
|
|
27
36
|
return value === "-" ? null : value;
|
|
@@ -152,6 +161,29 @@ async function sidecar(argv: string[], deps: RuntimeApiDeps): Promise<void> {
|
|
|
152
161
|
return;
|
|
153
162
|
}
|
|
154
163
|
if (section !== "web" && section !== "vision") throw new CliUsageError("sidecar must be web, vision, or status", USAGE);
|
|
164
|
+
// --list must be consumed BEFORE rejectArgs sees it. It prints the server's
|
|
165
|
+
// candidate set — the exact list the GUI picker shows (#2188): the server
|
|
166
|
+
// computes it once and every surface consumes it, so the CLI cannot drift.
|
|
167
|
+
const wantsList = takeFlag(args, "--list");
|
|
168
|
+
if (wantsList) {
|
|
169
|
+
rejectArgs(args, USAGE);
|
|
170
|
+
const settings = await runtimeRequest("/api/sidecar-settings", {}, deps) as {
|
|
171
|
+
webSearchModels?: WebSearchModelOption[];
|
|
172
|
+
visionModels?: Array<{ value: string; backend?: string; baseline?: boolean }>;
|
|
173
|
+
};
|
|
174
|
+
if (section === "web") {
|
|
175
|
+
const options = settings.webSearchModels ?? [];
|
|
176
|
+
printData(options, wantsJson, options.length === 0
|
|
177
|
+
? ["no runnable web-search sidecar models (log in to ChatGPT or Anthropic)"]
|
|
178
|
+
: options.map(option => `${option.value} [${option.backend}]${option.authSlot ? " (auth slot)" : ""}`));
|
|
179
|
+
} else {
|
|
180
|
+
const options = settings.visionModels ?? [];
|
|
181
|
+
printData(options, wantsJson, options.length === 0
|
|
182
|
+
? ["no eligible vision describers"]
|
|
183
|
+
: options.map(option => `${option.value}${option.backend ? ` [${option.backend}]` : ""}${option.baseline ? " (baseline)" : ""}`));
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
155
187
|
const model = takeOption(args, "--model");
|
|
156
188
|
const backend = takeOption(args, "--backend");
|
|
157
189
|
const reasoning = takeOption(args, "--reasoning");
|
|
@@ -163,6 +195,19 @@ async function sidecar(argv: string[], deps: RuntimeApiDeps): Promise<void> {
|
|
|
163
195
|
if (reasoning !== undefined) settings.reasoning = reasoning;
|
|
164
196
|
if (maxDescriptionsPerTurn !== undefined) settings.maxDescriptionsPerTurn = maxDescriptionsPerTurn;
|
|
165
197
|
if (Object.keys(settings).length === 0) throw new CliUsageError("at least one sidecar option is required", USAGE);
|
|
198
|
+
if (section === "web" && model !== undefined && model !== "-") {
|
|
199
|
+
const offered = await runtimeRequest("/api/sidecar-settings", {}, deps) as {
|
|
200
|
+
webSearchModels?: WebSearchModelOption[];
|
|
201
|
+
};
|
|
202
|
+
const requestedBackend = backend === "-" ? "openai" : backend;
|
|
203
|
+
const option = offered.webSearchModels?.find(candidate =>
|
|
204
|
+
(candidate.value === model || candidate.model === model)
|
|
205
|
+
&& (requestedBackend === undefined || candidate.backend === requestedBackend));
|
|
206
|
+
if (option) {
|
|
207
|
+
settings.model = option.model;
|
|
208
|
+
if (backend !== "-") settings.backend = option.backend;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
166
211
|
const body = section === "web" ? { webSearch: settings } : { vision: settings };
|
|
167
212
|
const result = await runtimeRequest("/api/sidecar-settings", { method: "PUT", body: JSON.stringify(body) }, deps);
|
|
168
213
|
printData(result, wantsJson, [`${section} sidecar settings updated.`]);
|
|
@@ -177,6 +222,12 @@ export async function handleAgentCommand(argv: string[], deps: RuntimeApiDeps =
|
|
|
177
222
|
else if (sub === "subagents" || sub === "roster") await subagents(rest, deps);
|
|
178
223
|
else if (sub === "fallback") await fallback(rest, deps);
|
|
179
224
|
else if (sub === "sidecar") await sidecar(rest, deps);
|
|
225
|
+
// Lives here rather than as a top-level verb because it is an agent-behavior feature flag:
|
|
226
|
+
// it controls whether default mode may ask the operator a question mid-task.
|
|
227
|
+
else if (sub === "request-user-input") {
|
|
228
|
+
const { requestUserInputAction } = await import("./inspect");
|
|
229
|
+
await requestUserInputAction(rest, deps);
|
|
230
|
+
}
|
|
180
231
|
else throw new CliUsageError(`unknown agent command ${sub}`, USAGE);
|
|
181
232
|
});
|
|
182
233
|
}
|