@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
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production host integration for CL-03 trusted exact-route execution.
|
|
3
|
+
*
|
|
4
|
+
* Issues a host-recognized `TrustedLabRouteExecutor` that routes provider traffic
|
|
5
|
+
* through the CL-03 credential lease, pinned transport, and observation normalization
|
|
6
|
+
* pipeline. Secret material stays outside Lab modules.
|
|
7
|
+
*
|
|
8
|
+
* @internal host integration only
|
|
9
|
+
*/
|
|
10
|
+
import { resolveEnvValue } from "../config";
|
|
11
|
+
import {
|
|
12
|
+
getValidAccessTokenSnapshot,
|
|
13
|
+
OAuthLoginRequiredError,
|
|
14
|
+
UnsupportedOAuthProviderError,
|
|
15
|
+
} from "../oauth";
|
|
16
|
+
import type { OcxConfig } from "../types";
|
|
17
|
+
import { createCredentialLease } from "../lab/live/credential-lease";
|
|
18
|
+
import {
|
|
19
|
+
liveUpstreamRequestPath,
|
|
20
|
+
normalizeLabLiveTransportObservation,
|
|
21
|
+
} from "../lab/live/executor";
|
|
22
|
+
import { createPinnedTransport } from "../lab/live/transport";
|
|
23
|
+
import { TransportError } from "../lab/live/transport";
|
|
24
|
+
import type { LabRouteContext } from "../lab/live/types";
|
|
25
|
+
import { createLabAuthorizedPinnedSender } from "./lab-live-pinned-sender";
|
|
26
|
+
import { createHostIssuedLabRouteExecutor } from "./lab-live-host";
|
|
27
|
+
import type { TrustedLabRouteExecutor } from "../lab/live/types";
|
|
28
|
+
|
|
29
|
+
const CREDENTIAL_HEADER = /(authorization|api[-_]?key|token|secret|credential|cookie)/i;
|
|
30
|
+
|
|
31
|
+
export interface ProductionLabRouteExecutorDeps {
|
|
32
|
+
configDir?: string;
|
|
33
|
+
loadConfig: () => OcxConfig;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function buildLabProviderAuthHeaders(
|
|
37
|
+
routeContext: LabRouteContext,
|
|
38
|
+
config: OcxConfig,
|
|
39
|
+
): Promise<Record<string, string>> {
|
|
40
|
+
const provider = config.providers?.[routeContext.providerId];
|
|
41
|
+
if (!provider || provider.disabled === true) {
|
|
42
|
+
throw new TransportError("auth_blocked", "provider unavailable");
|
|
43
|
+
}
|
|
44
|
+
if (provider.authMode === "forward") {
|
|
45
|
+
throw new TransportError("auth_blocked", "forward auth unsupported for lab probes");
|
|
46
|
+
}
|
|
47
|
+
if (provider.authMode === "local") {
|
|
48
|
+
throw new TransportError("auth_blocked", "local provider unsupported for lab probes");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const headers: Record<string, string> = {
|
|
52
|
+
Accept: "application/json",
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (provider.authMode === "oauth") {
|
|
57
|
+
let protocol: string;
|
|
58
|
+
try {
|
|
59
|
+
protocol = new URL(routeContext.baseUrl).protocol;
|
|
60
|
+
} catch {
|
|
61
|
+
throw new TransportError("auth_blocked", "invalid OAuth provider destination");
|
|
62
|
+
}
|
|
63
|
+
if (protocol !== "https:") {
|
|
64
|
+
throw new TransportError("auth_blocked", "OAuth lab probes require HTTPS");
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const snapshot = await getValidAccessTokenSnapshot(routeContext.providerId);
|
|
68
|
+
headers.Authorization = `Bearer ${snapshot.accessToken}`;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (error instanceof OAuthLoginRequiredError || error instanceof UnsupportedOAuthProviderError) {
|
|
71
|
+
throw new TransportError("auth_blocked", "oauth unavailable");
|
|
72
|
+
}
|
|
73
|
+
// Non-terminal refresh failures (network, lock contention, provider transient errors)
|
|
74
|
+
// are harness/infrastructure failures rather than evidence that credentials are invalid.
|
|
75
|
+
throw new TransportError("harness_failure", "oauth refresh unavailable");
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
const apiKey = resolveEnvValue(provider.apiKey)?.trim();
|
|
79
|
+
if (!apiKey) throw new TransportError("auth_blocked", "missing api key");
|
|
80
|
+
if (provider.adapter === "anthropic" && provider.apiKeyTransport === "x-api-key") {
|
|
81
|
+
headers["x-api-key"] = apiKey;
|
|
82
|
+
} else {
|
|
83
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (provider.headers) {
|
|
88
|
+
for (const [name, value] of Object.entries(provider.headers)) {
|
|
89
|
+
if (CREDENTIAL_HEADER.test(name)) continue;
|
|
90
|
+
const resolved = resolveEnvValue(value);
|
|
91
|
+
headers[name] = typeof resolved === "string" ? resolved : value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return headers;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Create the process-local trusted CL-03 route executor for Lab automation dispatch. */
|
|
99
|
+
export function createProductionLabRouteExecutor(
|
|
100
|
+
deps: ProductionLabRouteExecutorDeps,
|
|
101
|
+
): TrustedLabRouteExecutor {
|
|
102
|
+
return createHostIssuedLabRouteExecutor(async (input) => {
|
|
103
|
+
if (!input.initiatingRequest) {
|
|
104
|
+
throw new TransportError("harness_failure", "live scenario missing initiating request");
|
|
105
|
+
}
|
|
106
|
+
const config = deps.loadConfig();
|
|
107
|
+
const lease = createCredentialLease({
|
|
108
|
+
destination: input.destination,
|
|
109
|
+
transportId: "lab-automation",
|
|
110
|
+
budget: input.limits.maxRequests,
|
|
111
|
+
});
|
|
112
|
+
const authHeaders = await buildLabProviderAuthHeaders(input.routeContext, config);
|
|
113
|
+
const sender = createLabAuthorizedPinnedSender(async () => authHeaders);
|
|
114
|
+
const transport = createPinnedTransport({
|
|
115
|
+
destination: input.destination,
|
|
116
|
+
lease,
|
|
117
|
+
sender,
|
|
118
|
+
limits: input.limits,
|
|
119
|
+
transportId: "lab-automation",
|
|
120
|
+
});
|
|
121
|
+
const path = liveUpstreamRequestPath(input.routeContext.upstreamProtocol);
|
|
122
|
+
const response = await transport.request({
|
|
123
|
+
method: "POST",
|
|
124
|
+
path,
|
|
125
|
+
body: input.initiatingRequest,
|
|
126
|
+
signal: input.signal,
|
|
127
|
+
});
|
|
128
|
+
return normalizeLabLiveTransportObservation(input.routeContext, response);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers Compatibility Lab's passive route-subject linker into the core slot.
|
|
3
|
+
*
|
|
4
|
+
* Imported only from the Lab activation path, never from the request path. This module
|
|
5
|
+
* lives outside `src/lab/` for the same reason the other `src/lib/lab-*.ts` host
|
|
6
|
+
* integrations do: it is the seam between core and the subsystem, not the subsystem.
|
|
7
|
+
*
|
|
8
|
+
* @internal host integration only
|
|
9
|
+
*/
|
|
10
|
+
import { setPassiveRouteLinker } from "../server/passive-route-linker";
|
|
11
|
+
import { resolveProductionRouteSubject } from "../routing/compatibility/subject";
|
|
12
|
+
|
|
13
|
+
/** Install the Lab linker. Returns a detach function. */
|
|
14
|
+
export function registerLabPassiveRouteLinker(configDir?: string): () => void {
|
|
15
|
+
return setPassiveRouteLinker((config, providerName, modelId, routed, inboundWire) => {
|
|
16
|
+
const subject = resolveProductionRouteSubject(
|
|
17
|
+
config,
|
|
18
|
+
providerName,
|
|
19
|
+
modelId,
|
|
20
|
+
routed,
|
|
21
|
+
inboundWire,
|
|
22
|
+
configDir,
|
|
23
|
+
);
|
|
24
|
+
return subject ? subject.subjectId : null;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
export const LOCAL_ATTESTATION_CHALLENGE_HEADER = "x-opencodex-attestation-challenge";
|
|
4
|
+
export const LOCAL_ATTESTATION_PROOF_HEADER = "x-opencodex-attestation-proof";
|
|
5
|
+
|
|
6
|
+
const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
|
|
7
|
+
|
|
8
|
+
export function isLocalAttestationSecret(value: unknown): value is string {
|
|
9
|
+
return typeof value === "string" && BASE64URL_256.test(value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createLocalAttestationSecret(): string {
|
|
13
|
+
return randomBytes(32).toString("base64url");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createLocalAttestationChallenge(): string {
|
|
17
|
+
return randomBytes(32).toString("base64url");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function attestationPayload(challenge: string, pid: number, port: number): string | null {
|
|
21
|
+
if (!BASE64URL_256.test(challenge)) return null;
|
|
22
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return null;
|
|
23
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
24
|
+
return `opencodex-local-management-v1\n${challenge}\n${pid}\n${port}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createLocalAttestationProof(
|
|
28
|
+
secret: string,
|
|
29
|
+
challenge: string,
|
|
30
|
+
pid: number,
|
|
31
|
+
port: number,
|
|
32
|
+
): string | null {
|
|
33
|
+
if (!isLocalAttestationSecret(secret)) return null;
|
|
34
|
+
const payload = attestationPayload(challenge, pid, port);
|
|
35
|
+
if (!payload) return null;
|
|
36
|
+
return createHmac("sha256", secret).update(payload).digest("base64url");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function verifyLocalAttestationProof(
|
|
40
|
+
secret: string,
|
|
41
|
+
challenge: string,
|
|
42
|
+
pid: number,
|
|
43
|
+
port: number,
|
|
44
|
+
proof: string | null,
|
|
45
|
+
): boolean {
|
|
46
|
+
const expected = createLocalAttestationProof(secret, challenge, pid, port);
|
|
47
|
+
if (!expected || !proof || !BASE64URL_256.test(proof)) return false;
|
|
48
|
+
const expectedBytes = Buffer.from(expected);
|
|
49
|
+
const actualBytes = Buffer.from(proof);
|
|
50
|
+
return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
|
|
51
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { isLocalAttestationSecret } from "./local-management-attestation";
|
|
3
|
+
|
|
4
|
+
export const LOCAL_MANAGEMENT_EXPECTED_PID_HEADER = "x-opencodex-local-expected-pid";
|
|
5
|
+
export const LOCAL_MANAGEMENT_NONCE_HEADER = "x-opencodex-local-nonce";
|
|
6
|
+
export const LOCAL_MANAGEMENT_CAPABILITY_EXPIRES_AT_HEADER = "x-opencodex-local-expires-at";
|
|
7
|
+
export const LOCAL_MANAGEMENT_CAPABILITY_HEADER = "x-opencodex-local-capability";
|
|
8
|
+
export const LOCAL_MANAGEMENT_CAPABILITY_TTL_MS = 10_000;
|
|
9
|
+
|
|
10
|
+
export const LOCAL_MANAGEMENT_READ_PATHS = {
|
|
11
|
+
codexAccounts: "/api/codex-auth/accounts",
|
|
12
|
+
systemMemory: "/api/system/memory",
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export type LocalManagementReadPath =
|
|
16
|
+
typeof LOCAL_MANAGEMENT_READ_PATHS[keyof typeof LOCAL_MANAGEMENT_READ_PATHS];
|
|
17
|
+
|
|
18
|
+
const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
|
|
19
|
+
const LOCAL_READ_METHOD = "GET";
|
|
20
|
+
|
|
21
|
+
export type ExpectedLocalManagementPid =
|
|
22
|
+
| { kind: "absent" }
|
|
23
|
+
| { kind: "invalid" }
|
|
24
|
+
| { kind: "present"; pid: number };
|
|
25
|
+
|
|
26
|
+
export function parseExpectedLocalManagementPid(value: string | null): ExpectedLocalManagementPid {
|
|
27
|
+
if (value === null) return { kind: "absent" };
|
|
28
|
+
if (!/^[1-9]\d*$/.test(value)) return { kind: "invalid" };
|
|
29
|
+
const pid = Number(value);
|
|
30
|
+
return Number.isSafeInteger(pid) ? { kind: "present", pid } : { kind: "invalid" };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isLocalManagementReadPath(path: string): path is LocalManagementReadPath {
|
|
34
|
+
return path === LOCAL_MANAGEMENT_READ_PATHS.codexAccounts
|
|
35
|
+
|| path === LOCAL_MANAGEMENT_READ_PATHS.systemMemory;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function localReadCapabilityPayload(
|
|
39
|
+
nonce: string,
|
|
40
|
+
method: string,
|
|
41
|
+
path: string,
|
|
42
|
+
pid: number,
|
|
43
|
+
port: number,
|
|
44
|
+
expiresAt: number,
|
|
45
|
+
): string | null {
|
|
46
|
+
if (!BASE64URL_256.test(nonce)) return null;
|
|
47
|
+
if (method !== LOCAL_READ_METHOD || !isLocalManagementReadPath(path)) return null;
|
|
48
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return null;
|
|
49
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
50
|
+
if (!Number.isSafeInteger(expiresAt) || expiresAt <= 0) return null;
|
|
51
|
+
return `opencodex-local-management-read-v1\n${nonce}\n${method}\n${path}\n${pid}\n${port}\n${expiresAt}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Process-scoped authorization for one allowlisted local management GET. */
|
|
55
|
+
export function createLocalManagementReadCapability(
|
|
56
|
+
secret: string,
|
|
57
|
+
nonce: string,
|
|
58
|
+
method: string,
|
|
59
|
+
path: string,
|
|
60
|
+
pid: number,
|
|
61
|
+
port: number,
|
|
62
|
+
expiresAt: number,
|
|
63
|
+
): string | null {
|
|
64
|
+
if (!isLocalAttestationSecret(secret)) return null;
|
|
65
|
+
const payload = localReadCapabilityPayload(nonce, method, path, pid, port, expiresAt);
|
|
66
|
+
if (!payload) return null;
|
|
67
|
+
return createHmac("sha256", secret).update(payload).digest("base64url");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function verifyLocalManagementReadCapability(
|
|
71
|
+
secret: string,
|
|
72
|
+
nonce: string | null,
|
|
73
|
+
method: string,
|
|
74
|
+
path: string,
|
|
75
|
+
pid: number,
|
|
76
|
+
port: number,
|
|
77
|
+
expiresAt: number,
|
|
78
|
+
capability: string | null,
|
|
79
|
+
now = Date.now(),
|
|
80
|
+
): boolean {
|
|
81
|
+
if (!nonce || !capability || !BASE64URL_256.test(capability)) return false;
|
|
82
|
+
if (
|
|
83
|
+
!Number.isSafeInteger(now)
|
|
84
|
+
|| expiresAt <= now
|
|
85
|
+
|| expiresAt > now + LOCAL_MANAGEMENT_CAPABILITY_TTL_MS
|
|
86
|
+
) return false;
|
|
87
|
+
const expected = createLocalManagementReadCapability(
|
|
88
|
+
secret,
|
|
89
|
+
nonce,
|
|
90
|
+
method,
|
|
91
|
+
path,
|
|
92
|
+
pid,
|
|
93
|
+
port,
|
|
94
|
+
expiresAt,
|
|
95
|
+
);
|
|
96
|
+
if (!expected) return false;
|
|
97
|
+
const expectedBytes = Buffer.from(expected);
|
|
98
|
+
const actualBytes = Buffer.from(capability);
|
|
99
|
+
return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
|
|
100
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { isLocalAttestationSecret } from "./local-management-attestation";
|
|
3
|
+
|
|
4
|
+
export const LOCAL_PROVIDER_RELOAD_METHOD = "POST";
|
|
5
|
+
export const LOCAL_PROVIDER_RELOAD_PATH = "/api/providers/reload";
|
|
6
|
+
export const LOCAL_PROVIDER_RELOAD_CAPABILITY_VERSION = "v1";
|
|
7
|
+
export const LOCAL_PROVIDER_RELOAD_EXPECTED_PID_HEADER = "x-opencodex-provider-reload-expected-pid";
|
|
8
|
+
export const LOCAL_PROVIDER_RELOAD_NONCE_HEADER = "x-opencodex-provider-reload-nonce";
|
|
9
|
+
export const LOCAL_PROVIDER_RELOAD_EXPIRES_AT_HEADER = "x-opencodex-provider-reload-expires-at";
|
|
10
|
+
export const LOCAL_PROVIDER_RELOAD_NAME_HEADER = "x-opencodex-provider-reload-name";
|
|
11
|
+
export const LOCAL_PROVIDER_RELOAD_CAPABILITY_HEADER = "x-opencodex-provider-reload-capability";
|
|
12
|
+
export const LOCAL_PROVIDER_RELOAD_CAPABILITY_TTL_MS = 10_000;
|
|
13
|
+
|
|
14
|
+
const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
|
|
15
|
+
const PROVIDER_NAME = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62}[A-Za-z0-9])?$/;
|
|
16
|
+
|
|
17
|
+
export type ExpectedLocalProviderReloadPid =
|
|
18
|
+
| { kind: "absent" }
|
|
19
|
+
| { kind: "invalid" }
|
|
20
|
+
| { kind: "present"; pid: number };
|
|
21
|
+
|
|
22
|
+
export function parseExpectedLocalProviderReloadPid(value: string | null): ExpectedLocalProviderReloadPid {
|
|
23
|
+
if (value === null) return { kind: "absent" };
|
|
24
|
+
if (!/^[1-9]\d*$/.test(value)) return { kind: "invalid" };
|
|
25
|
+
const pid = Number(value);
|
|
26
|
+
return Number.isSafeInteger(pid) ? { kind: "present", pid } : { kind: "invalid" };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isLocalProviderReloadName(value: unknown): value is string {
|
|
30
|
+
return typeof value === "string" && PROVIDER_NAME.test(value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function capabilityPayload(
|
|
34
|
+
nonce: string,
|
|
35
|
+
method: string,
|
|
36
|
+
path: string,
|
|
37
|
+
name: string,
|
|
38
|
+
pid: number,
|
|
39
|
+
port: number,
|
|
40
|
+
expiresAt: number,
|
|
41
|
+
): string | null {
|
|
42
|
+
if (!BASE64URL_256.test(nonce)) return null;
|
|
43
|
+
if (method !== LOCAL_PROVIDER_RELOAD_METHOD || path !== LOCAL_PROVIDER_RELOAD_PATH) return null;
|
|
44
|
+
if (!isLocalProviderReloadName(name)) return null;
|
|
45
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return null;
|
|
46
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
47
|
+
if (!Number.isSafeInteger(expiresAt) || expiresAt <= 0) return null;
|
|
48
|
+
return `opencodex-local-provider-reload-v1\n${nonce}\n${method}\n${path}\n${name}\n${pid}\n${port}\n${expiresAt}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Process-scoped authorization to reload one named provider from protected disk state. */
|
|
52
|
+
export function createLocalProviderReloadCapability(
|
|
53
|
+
secret: string,
|
|
54
|
+
nonce: string,
|
|
55
|
+
method: string,
|
|
56
|
+
path: string,
|
|
57
|
+
name: string,
|
|
58
|
+
pid: number,
|
|
59
|
+
port: number,
|
|
60
|
+
expiresAt: number,
|
|
61
|
+
): string | null {
|
|
62
|
+
if (!isLocalAttestationSecret(secret)) return null;
|
|
63
|
+
const payload = capabilityPayload(nonce, method, path, name, pid, port, expiresAt);
|
|
64
|
+
if (!payload) return null;
|
|
65
|
+
return createHmac("sha256", secret).update(payload).digest("base64url");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function verifyLocalProviderReloadCapability(
|
|
69
|
+
secret: string,
|
|
70
|
+
nonce: string | null,
|
|
71
|
+
method: string,
|
|
72
|
+
path: string,
|
|
73
|
+
name: string | null,
|
|
74
|
+
pid: number,
|
|
75
|
+
port: number,
|
|
76
|
+
expiresAt: number,
|
|
77
|
+
capability: string | null,
|
|
78
|
+
now = Date.now(),
|
|
79
|
+
): boolean {
|
|
80
|
+
if (!nonce || !name || !capability || !BASE64URL_256.test(capability)) return false;
|
|
81
|
+
if (
|
|
82
|
+
!Number.isSafeInteger(now)
|
|
83
|
+
|| expiresAt <= now
|
|
84
|
+
|| expiresAt > now + LOCAL_PROVIDER_RELOAD_CAPABILITY_TTL_MS
|
|
85
|
+
) return false;
|
|
86
|
+
const expected = createLocalProviderReloadCapability(
|
|
87
|
+
secret,
|
|
88
|
+
nonce,
|
|
89
|
+
method,
|
|
90
|
+
path,
|
|
91
|
+
name,
|
|
92
|
+
pid,
|
|
93
|
+
port,
|
|
94
|
+
expiresAt,
|
|
95
|
+
);
|
|
96
|
+
if (!expected) return false;
|
|
97
|
+
const expectedBytes = Buffer.from(expected);
|
|
98
|
+
const actualBytes = Buffer.from(capability);
|
|
99
|
+
return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
|
|
100
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core-owned registry for optional-subsystem shutdown work.
|
|
3
|
+
*
|
|
4
|
+
* The proxy core must not import an optional subsystem merely to be able to stop it.
|
|
5
|
+
* Compatibility Lab is the first case: `server/lifecycle.ts` imported
|
|
6
|
+
* `lab/automation/orchestrator` for two teardown calls, and that single edge closed an
|
|
7
|
+
* import cycle (`routing/compatibility/assemble` → `routing/quota` → `providers/quota` →
|
|
8
|
+
* `codex/auth-api` → `codex/native-main-admission` → `server/lifecycle` → Lab) that pulled
|
|
9
|
+
* ~69 `src/lab/` modules into the graph of every install, including installs with no
|
|
10
|
+
* routing profile at all.
|
|
11
|
+
*
|
|
12
|
+
* A subsystem registers its teardown when it activates. A process that never activates it
|
|
13
|
+
* registers nothing, so shutdown does no work and loads no module.
|
|
14
|
+
*
|
|
15
|
+
* Hooks are synchronous and best-effort by contract: `drainAndShutdown` runs under an
|
|
16
|
+
* absolute deadline, so a hook that throws must not prevent its siblings — or
|
|
17
|
+
* `server.stop` — from running.
|
|
18
|
+
*
|
|
19
|
+
* See devlog/_fin/260814_lab_core_decoupling/010_lifecycle_shutdown_registry.md
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
type ShutdownHook = () => void;
|
|
23
|
+
|
|
24
|
+
const hooks = new Map<string, ShutdownHook>();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Register (or replace) the teardown for one optional subsystem.
|
|
28
|
+
*
|
|
29
|
+
* Keyed so repeated activation of the same subsystem cannot accumulate duplicate hooks.
|
|
30
|
+
* Returns a detach function so an owner-scoped lease can release its registration.
|
|
31
|
+
*/
|
|
32
|
+
export function registerOptionalShutdownHook(key: string, hook: ShutdownHook): () => void {
|
|
33
|
+
hooks.set(key, hook);
|
|
34
|
+
return () => {
|
|
35
|
+
// Only detach our own registration: a later activation may have replaced it.
|
|
36
|
+
if (hooks.get(key) === hook) hooks.delete(key);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Run every registered teardown. Never throws. */
|
|
41
|
+
export function runOptionalShutdownHooks(): void {
|
|
42
|
+
for (const [key, hook] of [...hooks]) {
|
|
43
|
+
try {
|
|
44
|
+
hook();
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.warn(
|
|
47
|
+
`[shutdown] optional subsystem "${key}" teardown failed:`,
|
|
48
|
+
err instanceof Error ? err.message : err,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Test-only reset so an isolated lifecycle test does not inherit registrations. */
|
|
55
|
+
export function resetOptionalShutdownHooksForTests(): void {
|
|
56
|
+
hooks.clear();
|
|
57
|
+
}
|