@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
|
@@ -18,9 +18,21 @@ export const KEY_LOGIN_PROVIDERS: Record<string, KeyLoginProvider> = deriveKeyLo
|
|
|
18
18
|
* `noReasoningModels`, `defaultModel`) onto a provider config being created, for any field the
|
|
19
19
|
* caller didn't already supply. Lets the vision/reasoning classification actually reach the saved
|
|
20
20
|
* config (the GUI/API only send adapter/baseUrl/apiKey/defaultModel). No-op for unknown names.
|
|
21
|
+
*
|
|
22
|
+
* `modelSupportsReasoningSummaries` is deliberately excluded from what gets persisted. It is
|
|
23
|
+
* registry-only metadata resolved at runtime, and this function feeds a config that is about to
|
|
24
|
+
* be written to disk. Persisting today's registry defaults would freeze them as the user's own
|
|
25
|
+
* overrides: a later registry correction — say we learn a model's backend rejects summary
|
|
26
|
+
* delivery — would never reach anyone who created their provider before the correction, and they
|
|
27
|
+
* would keep getting upstream 400s with no way to know why. Catalog gathering enriches a
|
|
28
|
+
* detached runtime clone, so the defaults still apply where they matter.
|
|
21
29
|
*/
|
|
22
30
|
export function enrichProviderFromCatalog(name: string, prov: OcxProviderConfig): void {
|
|
31
|
+
const hadOwnSummaries = Object.hasOwn(prov, "modelSupportsReasoningSummaries");
|
|
32
|
+
const submittedSummaries = prov.modelSupportsReasoningSummaries;
|
|
23
33
|
enrichProviderFromRegistry(name, prov);
|
|
34
|
+
if (hadOwnSummaries) prov.modelSupportsReasoningSummaries = submittedSummaries;
|
|
35
|
+
else delete prov.modelSupportsReasoningSummaries;
|
|
24
36
|
}
|
|
25
37
|
|
|
26
38
|
export function isKeyLoginProvider(name: string): boolean {
|
|
@@ -52,6 +64,10 @@ export async function validateApiKey(
|
|
|
52
64
|
key: string,
|
|
53
65
|
): Promise<boolean | "unknown"> {
|
|
54
66
|
try {
|
|
67
|
+
// A public model catalog cannot prove that the supplied key is valid. Returning unknown keeps
|
|
68
|
+
// the best-effort login flow available without persisting a false-positive validation result.
|
|
69
|
+
if (provider.apiKeyValidation === "unknown") return "unknown";
|
|
70
|
+
|
|
55
71
|
if (provider.adapter === "anthropic") {
|
|
56
72
|
const base = provider.baseUrl.replace(/\/v1\/?$/, "");
|
|
57
73
|
const res = await fetch(`${base}/v1/messages`, {
|
package/src/oauth/kimi.ts
CHANGED
|
@@ -151,7 +151,21 @@ async function requestDeviceAuthorization(): Promise<{
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
function parseTokenPayload(payload: TokenResponse, refreshFallback?: string): OAuthCredentials {
|
|
154
|
-
|
|
154
|
+
// Number.isFinite is required here: typeof NaN === "number", so the type check
|
|
155
|
+
// alone would let a NaN expires_in through and produce a never-refreshing expiry.
|
|
156
|
+
// Negative durations would stamp an already-past expiry — also malformed.
|
|
157
|
+
// The computed timestamp itself must also stay finite: Number.MAX_VALUE passes
|
|
158
|
+
// Number.isFinite but overflows to Infinity once multiplied by 1000.
|
|
159
|
+
if (
|
|
160
|
+
!payload.access_token
|
|
161
|
+
|| typeof payload.expires_in !== "number"
|
|
162
|
+
|| !Number.isFinite(payload.expires_in)
|
|
163
|
+
|| payload.expires_in < 0
|
|
164
|
+
) {
|
|
165
|
+
throw new Error("Kimi token response missing required fields");
|
|
166
|
+
}
|
|
167
|
+
const expires = Date.now() + payload.expires_in * 1000 - OAUTH_EXPIRY_SKEW_MS;
|
|
168
|
+
if (!Number.isFinite(expires)) {
|
|
155
169
|
throw new Error("Kimi token response missing required fields");
|
|
156
170
|
}
|
|
157
171
|
const refresh = payload.refresh_token ?? refreshFallback;
|
|
@@ -160,7 +174,7 @@ function parseTokenPayload(payload: TokenResponse, refreshFallback?: string): OA
|
|
|
160
174
|
return {
|
|
161
175
|
access: payload.access_token,
|
|
162
176
|
refresh,
|
|
163
|
-
expires
|
|
177
|
+
expires,
|
|
164
178
|
...identity,
|
|
165
179
|
};
|
|
166
180
|
}
|
package/src/oauth/kiro.ts
CHANGED
|
@@ -172,13 +172,37 @@ async function defaultKiroCliRunner(args: string[], signal?: AbortSignal): Promi
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
/** Kiro profile ARN structure: arn:<partition>:codewhisperer:<region>:<account>:profile/<id> */
|
|
176
|
+
const KIRO_PROFILE_ARN_PATTERN = /^arn:[a-z0-9-]+:codewhisperer:[a-z0-9-]+:\d{12}:profile\/[A-Za-z0-9-]+$/;
|
|
177
|
+
const KIRO_PROFILE_ARN_MAX_LENGTH = 256;
|
|
178
|
+
|
|
179
|
+
function parseKiroProfileArn(value: unknown): string | undefined {
|
|
180
|
+
if (typeof value !== "string") return undefined;
|
|
181
|
+
const trimmed = value.trim();
|
|
182
|
+
if (trimmed.length === 0 || trimmed.length > KIRO_PROFILE_ARN_MAX_LENGTH) return undefined;
|
|
183
|
+
return KIRO_PROFILE_ARN_PATTERN.test(trimmed) ? trimmed : undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function profileArnFromWhoami(parsed: Record<string, unknown>): string | undefined {
|
|
187
|
+
// Only narrowly-named documented-ish shapes; never invent an ARN (#993).
|
|
188
|
+
return parseKiroProfileArn(parsed.profileArn)
|
|
189
|
+
?? parseKiroProfileArn(parsed.profile_arn)
|
|
190
|
+
?? (parsed.profile && typeof parsed.profile === "object" && !Array.isArray(parsed.profile)
|
|
191
|
+
? parseKiroProfileArn((parsed.profile as Record<string, unknown>).arn)
|
|
192
|
+
: undefined);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function readKiroCliIdentity(runner: KiroCliRunner, signal?: AbortSignal): Promise<{ email?: string; profileArn?: string }> {
|
|
176
196
|
try {
|
|
177
197
|
const result = await runner(["whoami", "--format", "json"], signal);
|
|
178
198
|
if (result.exitCode !== 0) return {};
|
|
179
|
-
const parsed = JSON.parse(result.stdout) as
|
|
199
|
+
const parsed = JSON.parse(result.stdout) as Record<string, unknown>;
|
|
180
200
|
const email = typeof parsed.email === "string" ? parsed.email.trim().toLowerCase() : "";
|
|
181
|
-
|
|
201
|
+
const profileArn = profileArnFromWhoami(parsed);
|
|
202
|
+
return {
|
|
203
|
+
...(email && email.length <= 320 ? { email } : {}),
|
|
204
|
+
...(profileArn ? { profileArn } : {}),
|
|
205
|
+
};
|
|
182
206
|
} catch {
|
|
183
207
|
return {};
|
|
184
208
|
}
|
|
@@ -251,14 +275,34 @@ async function oauthCredentialFromImported(
|
|
|
251
275
|
runner: KiroCliRunner,
|
|
252
276
|
signal?: AbortSignal,
|
|
253
277
|
): Promise<OAuthCredentials> {
|
|
254
|
-
|
|
255
|
-
|
|
278
|
+
let identity: { email?: string; profileArn?: string } = {};
|
|
279
|
+
if (imported.source === "sqlite") {
|
|
280
|
+
identity = await readKiroCliIdentity(runner, signal);
|
|
281
|
+
// Session-switch race (#993 review): another process may have switched the
|
|
282
|
+
// active Kiro CLI session between the SQLite read and whoami. Accept
|
|
283
|
+
// whoami's identity only when the session token STILL matches the import —
|
|
284
|
+
// refresh token, or access token when refresh is absent.
|
|
285
|
+
if (identity.profileArn !== undefined) {
|
|
286
|
+
const current = readKiroCliSqliteCredential();
|
|
287
|
+
const importedKey = imported.refresh || imported.access;
|
|
288
|
+
const currentKey = current ? current.refresh || current.access : "";
|
|
289
|
+
if (!current || currentKey !== importedKey) identity = {};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Builder ID imports often lack a profileArn in SQLite; whoami against the
|
|
293
|
+
// SAME active CLI session can supply it (#993). Imported stays authoritative.
|
|
294
|
+
const resolvedProfileArn = imported.profileArn ?? identity.profileArn;
|
|
295
|
+
const metadata: KiroOAuthMetadata | undefined = (() => {
|
|
296
|
+
const base = metadataFromImported(imported) ?? {};
|
|
297
|
+
if (resolvedProfileArn && !base.profileArn) base.profileArn = resolvedProfileArn;
|
|
298
|
+
return Object.keys(base).length > 0 ? base : undefined;
|
|
299
|
+
})();
|
|
256
300
|
return {
|
|
257
301
|
access: imported.access,
|
|
258
302
|
refresh: imported.refresh,
|
|
259
303
|
expires: imported.expires,
|
|
260
304
|
source: imported.source === "json" ? "credential-file" : "local-cli",
|
|
261
|
-
...(
|
|
305
|
+
...(resolvedProfileArn ? { accountId: resolvedProfileArn } : {}),
|
|
262
306
|
...(identity.email ? { email: identity.email } : {}),
|
|
263
307
|
...(metadata ? { kiro: metadata } : {}),
|
|
264
308
|
};
|
|
@@ -24,7 +24,10 @@ export function detectGrokCliToken(): OAuthCredentials | null {
|
|
|
24
24
|
|
|
25
25
|
const accessToken = entry.key as string;
|
|
26
26
|
const refreshToken = entry.refresh_token as string;
|
|
27
|
-
const
|
|
27
|
+
const parsedExpiresAt = entry.expires_at ? new Date(entry.expires_at as string).getTime() : 0;
|
|
28
|
+
// Guard against unparseable/NaN expiries: a non-finite value must never be treated as
|
|
29
|
+
// "valid forever". Unknown → 0, which forces the refresh-validation path downstream.
|
|
30
|
+
const expiresAt = Number.isFinite(parsedExpiresAt) ? parsedExpiresAt : 0;
|
|
28
31
|
|
|
29
32
|
return {
|
|
30
33
|
refresh: refreshToken,
|
|
@@ -55,6 +58,9 @@ export function shouldAdoptGrokGeneration(
|
|
|
55
58
|
now = Date.now(),
|
|
56
59
|
refreshSkewMs = 60_000,
|
|
57
60
|
): boolean {
|
|
61
|
+
// A non-finite disk expiry means we cannot reason about the generation: the credential is
|
|
62
|
+
// either garbage or unknown. Treat it as requiring refresh validation, never as an upgrade.
|
|
63
|
+
if (!Number.isFinite(disk.expires)) return false;
|
|
58
64
|
if (disk.expires <= now + refreshSkewMs) return false;
|
|
59
65
|
const bothExpiriesExist = stored.expires > 0 && disk.expires > 0;
|
|
60
66
|
if (bothExpiriesExist) return disk.expires >= stored.expires;
|
|
@@ -108,7 +114,10 @@ export function parseClaudeOauthPayload(raw: string): OAuthCredentials | null {
|
|
|
108
114
|
const data = JSON.parse(raw) as { claudeAiOauth?: { accessToken?: string; refreshToken?: string; expiresAt?: number } };
|
|
109
115
|
const o = data.claudeAiOauth;
|
|
110
116
|
if (!o?.accessToken || !o?.refreshToken) return null;
|
|
111
|
-
|
|
117
|
+
// Number.isFinite guard: a string/NaN expiresAt must not flow into downstream time
|
|
118
|
+
// comparisons as a "valid forever" value. Unknown → 0 (refresh-validation path).
|
|
119
|
+
const expires = typeof o.expiresAt === "number" && Number.isFinite(o.expiresAt) ? o.expiresAt : 0;
|
|
120
|
+
return { access: o.accessToken, refresh: o.refreshToken, expires, source: "local-cli" };
|
|
112
121
|
} catch {
|
|
113
122
|
return null;
|
|
114
123
|
}
|
package/src/oauth/log.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/oauth/log.ts
|
|
2
2
|
import { maskAccountId } from "../lib/privacy";
|
|
3
|
+
import { redactSecretString } from "../lib/redact";
|
|
3
4
|
|
|
4
5
|
/** Normalize camelCase / snake_case / kebab-case field names before secret checks. */
|
|
5
6
|
function normalizeFieldKey(key: string): string {
|
|
@@ -20,6 +21,7 @@ const FORBIDDEN_NORMALIZED = new Set([
|
|
|
20
21
|
"id_token",
|
|
21
22
|
"client_secret",
|
|
22
23
|
"oauth_code",
|
|
24
|
+
"code_verifier",
|
|
23
25
|
"clientsecret",
|
|
24
26
|
]);
|
|
25
27
|
|
|
@@ -44,5 +46,5 @@ export function logOAuthEvent(
|
|
|
44
46
|
if (value === undefined) continue;
|
|
45
47
|
parts.push(`${key}=${String(value)}`);
|
|
46
48
|
}
|
|
47
|
-
console.info(parts.join(" "));
|
|
49
|
+
console.info(redactSecretString(parts.join(" ")));
|
|
48
50
|
}
|
package/src/oauth/login-cli.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import * as readline from "node:readline";
|
|
2
2
|
import { openUrl } from "../lib/open-url";
|
|
3
3
|
import { loadConfig, saveConfig } from "../config";
|
|
4
|
-
import { findLiveProxy
|
|
4
|
+
import { findLiveProxy } from "../server/proxy-liveness";
|
|
5
|
+
import {
|
|
6
|
+
requestBoundLocalProviderReload,
|
|
7
|
+
type LocalProviderReloadResult,
|
|
8
|
+
} from "../server/local-provider-reload-client";
|
|
5
9
|
import { isPublicOAuthProvider, listOAuthProviders, runLogin } from "./index";
|
|
6
10
|
import { KEY_LOGIN_PROVIDERS, isKeyLoginProvider, validateApiKey, type KeyLoginProvider } from "./key-providers";
|
|
7
|
-
import type { OcxProviderConfig } from "../types";
|
|
11
|
+
import type { OcxConfig, OcxProviderConfig } from "../types";
|
|
8
12
|
import { configuredAdminToken } from "../lib/admin-secrets";
|
|
9
13
|
import { codexAccountNamespaceProviderCollisionError } from "../codex/account-namespace-match";
|
|
10
14
|
|
|
15
|
+
const LIVE_RELOAD_PROVIDERS = new Set<string>([
|
|
16
|
+
...listOAuthProviders(),
|
|
17
|
+
...Object.keys(KEY_LOGIN_PROVIDERS),
|
|
18
|
+
]);
|
|
19
|
+
|
|
11
20
|
export function runningProxyUpdateHeaders(): Headers {
|
|
12
21
|
const headers = new Headers({ "Content-Type": "application/json" });
|
|
13
22
|
const adminToken = configuredAdminToken();
|
|
@@ -15,34 +24,43 @@ export function runningProxyUpdateHeaders(): Headers {
|
|
|
15
24
|
return headers;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Ask the attested runtime to reload one already-persisted provider.
|
|
29
|
+
*
|
|
30
|
+
* Returns the outcome instead of swallowing it. A running proxy that predates
|
|
31
|
+
* attested reload — or one whose runtime record no longer matches — cannot adopt
|
|
32
|
+
* the new credential, and the caller has to say so: the credential is on disk, but
|
|
33
|
+
* the live process keeps routing with the old one until it restarts. Silently
|
|
34
|
+
* printing success there is how a login appears to work and then does not.
|
|
35
|
+
*/
|
|
36
|
+
export async function notifyRunningProxy(name: string): Promise<LocalProviderReloadResult | null> {
|
|
37
|
+
if (!LIVE_RELOAD_PROVIDERS.has(name)) return null;
|
|
22
38
|
const live = await findLiveProxy();
|
|
23
|
-
if (!live) return;
|
|
24
|
-
|
|
25
|
-
await fetch(`http://${probeHostname(live.hostname)}:${live.port}/api/providers`, {
|
|
26
|
-
method: "POST",
|
|
27
|
-
headers: runningProxyUpdateHeaders(),
|
|
28
|
-
body: JSON.stringify({ name, provider }),
|
|
29
|
-
});
|
|
30
|
-
} catch {
|
|
31
|
-
/* proxy unreachable; disk config loads on next start */
|
|
32
|
-
}
|
|
39
|
+
if (!live) return null;
|
|
40
|
+
return await requestBoundLocalProviderReload(live, name);
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
/**
|
|
36
44
|
* After `runLogin()` has persisted the merged provider (including preserved apiKey /
|
|
37
|
-
* apiKeyPool / authMode),
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
* apiKeyPool / authMode), ask the attested proxy to reload that exact on-disk entry.
|
|
46
|
+
*/
|
|
47
|
+
export async function notifyRunningProxyAfterOAuthLogin(name: string): Promise<LocalProviderReloadResult | null> {
|
|
48
|
+
if (!loadConfig().providers[name]) return null;
|
|
49
|
+
return await notifyRunningProxy(name);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A live proxy was found but could not adopt the credential. `null` means there was
|
|
54
|
+
* nothing to notify (no running proxy, or a provider that never reloads live), which
|
|
55
|
+
* is not a warning-worthy state.
|
|
41
56
|
*/
|
|
42
|
-
export
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
export function warnIfLiveReloadSkipped(result: LocalProviderReloadResult | null): void {
|
|
58
|
+
if (!result || result.kind === "reloaded") return;
|
|
59
|
+
console.warn(
|
|
60
|
+
`\n⚠️ A proxy is running but could not reload this provider (${result.reason}).`
|
|
61
|
+
+ `\n The credential is saved to disk; the running proxy keeps using the previous one.`
|
|
62
|
+
+ `\n Restart it to pick this up: ocx restart`,
|
|
63
|
+
);
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
export async function handleLogin(provider?: string): Promise<void> {
|
|
@@ -73,8 +91,9 @@ async function handleOAuthLogin(name: string): Promise<void> {
|
|
|
73
91
|
} finally {
|
|
74
92
|
rl.close();
|
|
75
93
|
}
|
|
76
|
-
await notifyRunningProxyAfterOAuthLogin(name);
|
|
94
|
+
const reload = await notifyRunningProxyAfterOAuthLogin(name);
|
|
77
95
|
console.log(`\n✅ Logged in to ${name}. Try: ocx sync`);
|
|
96
|
+
warnIfLiveReloadSkipped(reload);
|
|
78
97
|
}
|
|
79
98
|
|
|
80
99
|
export function providerConfigFromKeyLoginProvider(def: KeyLoginProvider, key: string, baseUrlOverride?: string): OcxProviderConfig {
|
|
@@ -102,10 +121,51 @@ export function providerConfigFromKeyLoginProvider(def: KeyLoginProvider, key: s
|
|
|
102
121
|
...(def.noPenaltyModels ? { noPenaltyModels: [...def.noPenaltyModels] } : {}),
|
|
103
122
|
...(def.autoToolChoiceOnlyModels ? { autoToolChoiceOnlyModels: [...def.autoToolChoiceOnlyModels] } : {}),
|
|
104
123
|
...(def.preserveReasoningContentModels ? { preserveReasoningContentModels: [...def.preserveReasoningContentModels] } : {}),
|
|
124
|
+
...(def.requiresReasoningPlaceholderModels ? { requiresReasoningPlaceholderModels: [...def.requiresReasoningPlaceholderModels] } : {}),
|
|
105
125
|
...(def.escapeBuiltinToolNames !== undefined ? { escapeBuiltinToolNames: def.escapeBuiltinToolNames } : {}),
|
|
106
126
|
};
|
|
107
127
|
}
|
|
108
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Merge a freshly built key-login provider row with a previously saved row,
|
|
131
|
+
* carrying operator-owned fields the key-provider preset cannot know about.
|
|
132
|
+
* Currently that is the user-configured modelCosts overlay: rotating the API
|
|
133
|
+
* key must not silently revert Logs/Usage estimates to catalog prices.
|
|
134
|
+
*/
|
|
135
|
+
export function mergeKeyLoginProviderRow(
|
|
136
|
+
provider: OcxProviderConfig,
|
|
137
|
+
existing: OcxProviderConfig | undefined,
|
|
138
|
+
): OcxProviderConfig {
|
|
139
|
+
return {
|
|
140
|
+
...provider,
|
|
141
|
+
...(existing?.modelCosts !== undefined ? { modelCosts: existing.modelCosts } : {}),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Commit a fresh key-login provider row: merge operator-owned fields from the
|
|
147
|
+
* existing row (currently the modelCosts overlay), persist the merged row, and
|
|
148
|
+
* push the SAME merged row to a running proxy so its live config cannot diverge
|
|
149
|
+
* from disk (e.g. by replacing the overlay with catalog prices until reload).
|
|
150
|
+
* Returns the merged row that was persisted and notified.
|
|
151
|
+
*/
|
|
152
|
+
export async function commitKeyLoginProvider(
|
|
153
|
+
config: OcxConfig,
|
|
154
|
+
name: string,
|
|
155
|
+
provider: OcxProviderConfig,
|
|
156
|
+
onLiveReload?: (result: LocalProviderReloadResult | null) => void,
|
|
157
|
+
): Promise<OcxProviderConfig> {
|
|
158
|
+
const mergedProvider = mergeKeyLoginProviderRow(provider, config.providers[name]);
|
|
159
|
+
config.providers[name] = mergedProvider;
|
|
160
|
+
saveConfig(config);
|
|
161
|
+
// Evaluate the reload BEFORE the optional call: `onLiveReload?.(await ...)` short-circuits
|
|
162
|
+
// the whole argument list when no callback is supplied, so the reload would never fire for
|
|
163
|
+
// callers that do not care about the outcome.
|
|
164
|
+
const reloadResult = await notifyRunningProxy(name);
|
|
165
|
+
onLiveReload?.(reloadResult);
|
|
166
|
+
return mergedProvider;
|
|
167
|
+
}
|
|
168
|
+
|
|
109
169
|
async function handleKeyLogin(name: string): Promise<void> {
|
|
110
170
|
const def = KEY_LOGIN_PROVIDERS[name];
|
|
111
171
|
const preflightConfig = loadConfig();
|
|
@@ -148,10 +208,10 @@ async function handleKeyLogin(name: string): Promise<void> {
|
|
|
148
208
|
console.error(`Error: ${commitCollision}.`);
|
|
149
209
|
process.exit(1);
|
|
150
210
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
await notifyRunningProxy(name, provider);
|
|
211
|
+
let reload: LocalProviderReloadResult | null = null;
|
|
212
|
+
await commitKeyLoginProvider(config, name, provider, result => { reload = result; });
|
|
154
213
|
console.log(`✅ ${def.label} added. Try: ocx sync`);
|
|
214
|
+
warnIfLiveReloadSkipped(reload);
|
|
155
215
|
}
|
|
156
216
|
|
|
157
217
|
function cloneRecordOfArrays(input: Record<string, string[]>): Record<string, string[]> {
|