@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,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `AdmissionSnapshot` producer.
|
|
3
|
+
*
|
|
4
|
+
* `AdmissionSnapshot` existed as a TYPE for the whole unit while nothing built
|
|
5
|
+
* one, which meant the write lock's API could only ever be exercised by a
|
|
6
|
+
* fabricated object — the reason WP11 was merged into WP12 rather than shipped
|
|
7
|
+
* as a mechanism with no consumer.
|
|
8
|
+
*
|
|
9
|
+
* What this is FOR: one decision uses one set of bytes. Everything the lock
|
|
10
|
+
* compares is captured here, once, before any artifact is created; the lock then
|
|
11
|
+
* re-reads it while holding N and refuses if the authority moved underneath.
|
|
12
|
+
* Passing the config around instead would let two reads of a changing file
|
|
13
|
+
* disagree inside one operation, which is the interruption hazard this unit
|
|
14
|
+
* exists to close.
|
|
15
|
+
*
|
|
16
|
+
* READS ONLY. Nothing here creates a directory, a database, or a marker: an
|
|
17
|
+
* admission that manufactures the state it is admitting cannot refuse.
|
|
18
|
+
*
|
|
19
|
+
* Design record: devlog/_fin/260804_codex_write_substrate/040_ownership_convergence.md.
|
|
20
|
+
*/
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
22
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
|
|
25
|
+
import { getConfigDir, observeConfigGeneration, readConfigAdmissionSnapshot } from "../config";
|
|
26
|
+
import { inspectNativeCodexOwnership } from "../integrations/native/ownership-preflight";
|
|
27
|
+
import type { AdmissionSnapshot } from "./convergence-types";
|
|
28
|
+
import { codexIntegrationEnabled } from "./desired-state";
|
|
29
|
+
import { externalCodexModelProvider } from "./inject";
|
|
30
|
+
import { JOURNAL_PATH } from "./journal";
|
|
31
|
+
import {
|
|
32
|
+
CODEX_MODELS_CACHE_PATH,
|
|
33
|
+
CODEX_PROFILE_PATH,
|
|
34
|
+
DEFAULT_CATALOG_PATH,
|
|
35
|
+
getCodexHome,
|
|
36
|
+
resolveCodexStateDbPath,
|
|
37
|
+
} from "./paths";
|
|
38
|
+
|
|
39
|
+
export type CodexAdmission =
|
|
40
|
+
| { readonly kind: "admitted"; readonly snapshot: AdmissionSnapshot }
|
|
41
|
+
| {
|
|
42
|
+
readonly kind: "refused";
|
|
43
|
+
readonly authority: "config" | "generation" | "service-home" | "external-provider";
|
|
44
|
+
readonly message: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Seams, not conveniences.
|
|
49
|
+
*
|
|
50
|
+
* The ownership probe shells out to the platform service manager, and a test
|
|
51
|
+
* that reached the real one would be asserting against whatever the developer's
|
|
52
|
+
* machine happens to have installed. Injecting it is also what lets a test
|
|
53
|
+
* observe the EXACT argv the production probe emits, which is the only way to
|
|
54
|
+
* hold down "this never starts or stops anything".
|
|
55
|
+
*/
|
|
56
|
+
export interface AdmissionDeps {
|
|
57
|
+
readonly inspectOwnership?: typeof inspectNativeCodexOwnership;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Hash of a file's exact bytes, or a stable marker for absence. */
|
|
61
|
+
function contentIdentity(path: string): string {
|
|
62
|
+
try {
|
|
63
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex").slice(0, 32);
|
|
64
|
+
} catch {
|
|
65
|
+
// Absence is EVIDENCE, not a hole. An absent journal and an unreadable one
|
|
66
|
+
// are different states and must not collapse to the same identity.
|
|
67
|
+
return existsSync(path) ? "unreadable" : "absent";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Capture everything one Codex write decision depends on.
|
|
73
|
+
*
|
|
74
|
+
* Refuses rather than guessing: a missing or malformed config, a coordinator
|
|
75
|
+
* that cannot report a generation, a service installed from another home, and an
|
|
76
|
+
* external `model_provider` each end the operation before it starts. The last
|
|
77
|
+
* two are separate authorities on purpose — "someone else's service owns this
|
|
78
|
+
* home" and "the user pointed Codex somewhere else" need different messages
|
|
79
|
+
* because they need different actions.
|
|
80
|
+
*/
|
|
81
|
+
export function admitCodexWrite(deps: AdmissionDeps = {}): CodexAdmission {
|
|
82
|
+
const persisted = readConfigAdmissionSnapshot();
|
|
83
|
+
const diagnostics = persisted.diagnostics;
|
|
84
|
+
if (diagnostics.source !== "file") {
|
|
85
|
+
return {
|
|
86
|
+
kind: "refused",
|
|
87
|
+
authority: "config",
|
|
88
|
+
message: diagnostics.source === "default"
|
|
89
|
+
? "No config file exists to admit a Codex write from."
|
|
90
|
+
: "The config file is malformed; refusing to write from it.",
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (persisted.kind !== "read") {
|
|
94
|
+
// Unreachable through the union today — `source: "file"` only comes from a
|
|
95
|
+
// successful read — but stated rather than assumed, because the day that
|
|
96
|
+
// stops being true this should refuse, not proceed with no digest.
|
|
97
|
+
return {
|
|
98
|
+
kind: "refused",
|
|
99
|
+
authority: "config",
|
|
100
|
+
message: "The config file could not be read as bytes; refusing to write from it.",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* OBSERVE, not read.
|
|
106
|
+
*
|
|
107
|
+
* `readConfigGeneration` opens the coordinator with `create: true`, so merely
|
|
108
|
+
* admitting would produce a `config-mutation.sqlite` in a home that had none —
|
|
109
|
+
* caught by the "creates nothing" test, which is what that test is for. Only a
|
|
110
|
+
* cooperating config WRITE may create and initialize the singleton.
|
|
111
|
+
*/
|
|
112
|
+
const observed = observeConfigGeneration();
|
|
113
|
+
if (observed.kind === "unavailable") {
|
|
114
|
+
return {
|
|
115
|
+
kind: "refused",
|
|
116
|
+
authority: "generation",
|
|
117
|
+
message: observed.reason === "busy"
|
|
118
|
+
? "The config coordinator is busy; the generation could not be read."
|
|
119
|
+
: "The config generation exists but could not be read; refusing to guess it.",
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const generation = observed.kind === "absent"
|
|
123
|
+
? { present: false, value: 0 }
|
|
124
|
+
: { present: true, value: observed.generation.value };
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Tri-state, and NOT `assertNativeTeardownOwned` — that one fails open, so a
|
|
128
|
+
* corrupt state file would arrive here as `owned`. Unattended writes refuse on
|
|
129
|
+
* both `foreign` and `unknown`: the first is someone else's home, the second
|
|
130
|
+
* is a question that could not be answered, and neither is permission.
|
|
131
|
+
*/
|
|
132
|
+
const ownership = (deps.inspectOwnership ?? inspectNativeCodexOwnership)();
|
|
133
|
+
if (ownership.ownership !== "owned") {
|
|
134
|
+
return {
|
|
135
|
+
kind: "refused",
|
|
136
|
+
authority: "service-home",
|
|
137
|
+
message: ownership.ownership === "foreign"
|
|
138
|
+
? `Refusing to write: ${ownership.reason}.`
|
|
139
|
+
: `Refusing to write because ownership could not be proven: ${ownership.reason}.`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const codexHome = getCodexHome();
|
|
144
|
+
const codexConfigPath = join(codexHome, "config.toml");
|
|
145
|
+
let external: string | null = null;
|
|
146
|
+
try {
|
|
147
|
+
// Resolved at call time, not at module load: CODEX_CONFIG_PATH is a const
|
|
148
|
+
// fixed when the module was first imported, so it does not follow a
|
|
149
|
+
// CODEX_HOME that changed afterwards.
|
|
150
|
+
external = externalCodexModelProvider(readFileSync(codexConfigPath, "utf-8"));
|
|
151
|
+
} catch {
|
|
152
|
+
// No Codex config yet is not an external owner; it is simply nothing to read.
|
|
153
|
+
external = null;
|
|
154
|
+
}
|
|
155
|
+
if (external) {
|
|
156
|
+
return {
|
|
157
|
+
kind: "refused",
|
|
158
|
+
authority: "external-provider",
|
|
159
|
+
message: `Codex config.toml is owned by an external model_provider (${external}).`,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const config = diagnostics.config;
|
|
164
|
+
const opencodexHome = getConfigDir();
|
|
165
|
+
const integrationRecord = join(opencodexHome, "integrations", "codex.json");
|
|
166
|
+
const historyDb = resolveCodexStateDbPath({ codexHome });
|
|
167
|
+
|
|
168
|
+
const canonicalTargets = {
|
|
169
|
+
codexHome,
|
|
170
|
+
opencodexHome,
|
|
171
|
+
config: codexConfigPath,
|
|
172
|
+
profile: CODEX_PROFILE_PATH,
|
|
173
|
+
catalog: DEFAULT_CATALOG_PATH,
|
|
174
|
+
cache: CODEX_MODELS_CACHE_PATH,
|
|
175
|
+
// The journal's own constant. Re-deriving it here is what made this field
|
|
176
|
+
// watch a path nothing writes.
|
|
177
|
+
journal: JOURNAL_PATH,
|
|
178
|
+
integrationRecord,
|
|
179
|
+
// Backups and rollouts are enumerated by their owners, not guessed here.
|
|
180
|
+
catalogBackups: [] as readonly string[],
|
|
181
|
+
historyDb,
|
|
182
|
+
historyManifest: `${historyDb}.ocx-backup.json`,
|
|
183
|
+
historyRollouts: [] as readonly string[],
|
|
184
|
+
} as const;
|
|
185
|
+
|
|
186
|
+
const snapshot: AdmissionSnapshot = {
|
|
187
|
+
config,
|
|
188
|
+
// The EXACT persisted bytes. Hashing the parsed object instead let a
|
|
189
|
+
// whitespace-only rewrite pass unnoticed, which is precisely the
|
|
190
|
+
// non-cooperating writer this comparison exists to catch.
|
|
191
|
+
configDigest: persisted.contentSha256,
|
|
192
|
+
intent: codexIntegrationEnabled(config) ? "on" : "off",
|
|
193
|
+
generation,
|
|
194
|
+
// Reached only when the projection above said `owned`; the other two states
|
|
195
|
+
// have already refused. This is the observed value, not a placeholder.
|
|
196
|
+
ownership: ownership.ownership,
|
|
197
|
+
externalProvider: null,
|
|
198
|
+
canonicalTargets,
|
|
199
|
+
journalIdentity: contentIdentity(JOURNAL_PATH),
|
|
200
|
+
provenanceIdentity: contentIdentity(integrationRecord),
|
|
201
|
+
authoritySnapshotId: "",
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
return { kind: "admitted", snapshot: { ...snapshot, authoritySnapshotId: hashAuthority(snapshot) } };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Collapse the generation to one authority token.
|
|
209
|
+
*
|
|
210
|
+
* An absent database and a present zero are the SAME authority — both mean no
|
|
211
|
+
* cooperating write has committed — and they must hash alike, because the lock
|
|
212
|
+
* compares this ID byte-for-byte. They cannot be observed alike: before the lock
|
|
213
|
+
* only absence is visible, and inside it only the present zero is, since the
|
|
214
|
+
* transaction that creates the row has not committed while a separate connection
|
|
215
|
+
* looks. Without this they would never match and every first write would refuse.
|
|
216
|
+
*
|
|
217
|
+
* Canonicalizing inside the hash rather than beside it, in a comparator: a
|
|
218
|
+
* comparator that treats one field specially has to be rewritten at every future
|
|
219
|
+
* comparison site, and the site that gets forgotten is the one that matters.
|
|
220
|
+
*/
|
|
221
|
+
function generationAuthority(generation: AdmissionSnapshot["generation"]): string {
|
|
222
|
+
const { present, value } = generation;
|
|
223
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
224
|
+
// NaN, Infinity, fractions, negatives and unsafe integers would otherwise
|
|
225
|
+
// all quietly become "gen:0" — the one value that means "safe to proceed".
|
|
226
|
+
throw new TypeError(`A config generation must be a non-negative safe integer, got ${String(value)}.`);
|
|
227
|
+
}
|
|
228
|
+
return present && value > 0 ? `gen:${value}` : "gen:0";
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Digest every authority field, in a fixed order.
|
|
233
|
+
*
|
|
234
|
+
* The lock compares THIS and nothing else, so a field left out of the hash is a
|
|
235
|
+
* field that can change under the lock without anyone noticing. Adding one to
|
|
236
|
+
* the snapshot means adding it here.
|
|
237
|
+
*/
|
|
238
|
+
export function hashAuthority(snapshot: AdmissionSnapshot): string {
|
|
239
|
+
return createHash("sha256")
|
|
240
|
+
.update(JSON.stringify([
|
|
241
|
+
snapshot.configDigest,
|
|
242
|
+
snapshot.intent,
|
|
243
|
+
generationAuthority(snapshot.generation),
|
|
244
|
+
snapshot.ownership,
|
|
245
|
+
snapshot.externalProvider,
|
|
246
|
+
snapshot.canonicalTargets,
|
|
247
|
+
snapshot.journalIdentity,
|
|
248
|
+
snapshot.provenanceIdentity,
|
|
249
|
+
]))
|
|
250
|
+
.digest("hex");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Test seam: prove the identity of a path the way admission does. */
|
|
254
|
+
export function admissionContentIdentityForTests(path: string): string {
|
|
255
|
+
return contentIdentity(path);
|
|
256
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in Codex affinity diagnostics for account-switch compatibility failures.
|
|
3
|
+
*
|
|
4
|
+
* The provider debug stream may compare values only within the current process. It never emits
|
|
5
|
+
* raw header values, credentials, account identifiers, or durable unsalted hashes.
|
|
6
|
+
*/
|
|
7
|
+
import { createHmac, randomBytes } from "node:crypto";
|
|
8
|
+
import { isDebugEnabled } from "../lib/debug-settings";
|
|
9
|
+
import { debugProviderDiagnostic } from "../lib/debug";
|
|
10
|
+
|
|
11
|
+
const MAX_TAGGED_VALUE_BYTES = 16 * 1024;
|
|
12
|
+
const RUN_KEY = randomBytes(32);
|
|
13
|
+
let nextSequence = 0;
|
|
14
|
+
|
|
15
|
+
const SAFE_AFFINITY_HEADERS = [
|
|
16
|
+
"openai-beta",
|
|
17
|
+
"originator",
|
|
18
|
+
"session_id",
|
|
19
|
+
"session-id",
|
|
20
|
+
"thread-id",
|
|
21
|
+
"x-client-request-id",
|
|
22
|
+
"x-codex-beta-features",
|
|
23
|
+
"x-codex-installation-id",
|
|
24
|
+
"x-codex-parent-thread-id",
|
|
25
|
+
"x-codex-turn-metadata",
|
|
26
|
+
"x-codex-turn-state",
|
|
27
|
+
"x-codex-window-id",
|
|
28
|
+
"x-openai-subagent",
|
|
29
|
+
"x-responsesapi-include-timing-metrics",
|
|
30
|
+
] as const;
|
|
31
|
+
|
|
32
|
+
const KNOWN_TURN_FIELDS = [
|
|
33
|
+
"forked_from_thread_id",
|
|
34
|
+
"parent_thread_id",
|
|
35
|
+
"request_kind",
|
|
36
|
+
"session_id",
|
|
37
|
+
"subagent_kind",
|
|
38
|
+
"thread_id",
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
type SizeBucket = "0" | "1-31" | "32-127" | "128-511" | "512-2047" | "2048-16384" | "oversized";
|
|
42
|
+
|
|
43
|
+
export interface CodexAffinityValueTag {
|
|
44
|
+
name: string;
|
|
45
|
+
size: SizeBucket;
|
|
46
|
+
tag?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface CodexAffinityJsonSummary {
|
|
50
|
+
shape: "absent" | "malformed" | "oversized" | "array" | "scalar" | "object";
|
|
51
|
+
knownFields?: Array<CodexAffinityValueTag & { kind: "string" | "number" | "boolean" | "null" | "array" | "object" }>;
|
|
52
|
+
unknownFieldCount?: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface CodexAffinityDiagnosticInput {
|
|
56
|
+
inboundHeaders: Headers;
|
|
57
|
+
outboundHeaders: HeadersInit;
|
|
58
|
+
authKind: "main" | "pool" | "main-pool";
|
|
59
|
+
accountMode: "direct" | "pool" | undefined;
|
|
60
|
+
fixedAccount: boolean;
|
|
61
|
+
credentialSubstituted: boolean;
|
|
62
|
+
accountGatedModel: boolean;
|
|
63
|
+
wireModelNormalized: boolean;
|
|
64
|
+
status: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function sizeBucket(bytes: number): SizeBucket {
|
|
68
|
+
if (bytes === 0) return "0";
|
|
69
|
+
if (bytes <= 31) return "1-31";
|
|
70
|
+
if (bytes <= 127) return "32-127";
|
|
71
|
+
if (bytes <= 511) return "128-511";
|
|
72
|
+
if (bytes <= 2047) return "512-2047";
|
|
73
|
+
if (bytes <= MAX_TAGGED_VALUE_BYTES) return "2048-16384";
|
|
74
|
+
return "oversized";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function valueTag(name: string, value: string): CodexAffinityValueTag {
|
|
78
|
+
const bytes = Buffer.byteLength(value, "utf8");
|
|
79
|
+
const size = sizeBucket(bytes);
|
|
80
|
+
if (size === "oversized") return { name, size };
|
|
81
|
+
const tag = createHmac("sha256", RUN_KEY)
|
|
82
|
+
.update(name)
|
|
83
|
+
.update("\0")
|
|
84
|
+
.update(value)
|
|
85
|
+
.digest("hex")
|
|
86
|
+
.slice(0, 12);
|
|
87
|
+
return { name, size, tag };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function headerTags(headers: Headers): CodexAffinityValueTag[] {
|
|
91
|
+
const rows: CodexAffinityValueTag[] = [];
|
|
92
|
+
for (const name of SAFE_AFFINITY_HEADERS) {
|
|
93
|
+
const value = headers.get(name);
|
|
94
|
+
if (value !== null) rows.push(valueTag(name, value));
|
|
95
|
+
}
|
|
96
|
+
return rows;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function jsonSummary(headers: Headers, name: "x-codex-turn-metadata" | "x-codex-turn-state"): CodexAffinityJsonSummary {
|
|
100
|
+
const raw = headers.get(name);
|
|
101
|
+
if (raw === null) return { shape: "absent" };
|
|
102
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_TAGGED_VALUE_BYTES) return { shape: "oversized" };
|
|
103
|
+
let parsed: unknown;
|
|
104
|
+
try {
|
|
105
|
+
parsed = JSON.parse(raw) as unknown;
|
|
106
|
+
} catch {
|
|
107
|
+
return { shape: "malformed" };
|
|
108
|
+
}
|
|
109
|
+
if (Array.isArray(parsed)) return { shape: "array" };
|
|
110
|
+
if (!parsed || typeof parsed !== "object") return { shape: "scalar" };
|
|
111
|
+
const record = parsed as Record<string, unknown>;
|
|
112
|
+
const knownFields: NonNullable<CodexAffinityJsonSummary["knownFields"]> = [];
|
|
113
|
+
for (const field of KNOWN_TURN_FIELDS) {
|
|
114
|
+
if (!Object.hasOwn(record, field)) continue;
|
|
115
|
+
const value = record[field];
|
|
116
|
+
if (value === null) {
|
|
117
|
+
knownFields.push({ name: field, kind: "null", size: "0" });
|
|
118
|
+
} else {
|
|
119
|
+
const scalarKind = typeof value;
|
|
120
|
+
if (scalarKind === "string" || scalarKind === "number" || scalarKind === "boolean") {
|
|
121
|
+
knownFields.push({ ...valueTag(`${name}.${field}`, String(value)), name: field, kind: scalarKind });
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
knownFields.push({ name: field, kind: Array.isArray(value) ? "array" : "object", size: "0" });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const known = new Set<string>(KNOWN_TURN_FIELDS);
|
|
128
|
+
const unknownFieldCount = Object.keys(record).filter(key => !known.has(key)).length;
|
|
129
|
+
return {
|
|
130
|
+
shape: "object",
|
|
131
|
+
...(knownFields.length > 0 ? { knownFields } : {}),
|
|
132
|
+
...(unknownFieldCount > 0 ? { unknownFieldCount } : {}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Emit one observation-only, privacy-bounded provider-debug record. */
|
|
137
|
+
export function captureCodexAffinityDiagnostic(input: CodexAffinityDiagnosticInput): void {
|
|
138
|
+
if (!isDebugEnabled()) return;
|
|
139
|
+
try {
|
|
140
|
+
const outbound = new Headers(input.outboundHeaders);
|
|
141
|
+
debugProviderDiagnostic("codex", "affinity", {
|
|
142
|
+
sequence: ++nextSequence,
|
|
143
|
+
authKind: input.authKind,
|
|
144
|
+
accountMode: input.accountMode ?? "unset",
|
|
145
|
+
fixedAccount: input.fixedAccount,
|
|
146
|
+
credentialSubstituted: input.credentialSubstituted,
|
|
147
|
+
accountGatedModel: input.accountGatedModel,
|
|
148
|
+
wireModelNormalized: input.wireModelNormalized,
|
|
149
|
+
status: input.status,
|
|
150
|
+
inbound: headerTags(input.inboundHeaders),
|
|
151
|
+
outbound: headerTags(outbound),
|
|
152
|
+
inboundTurnMetadata: jsonSummary(input.inboundHeaders, "x-codex-turn-metadata"),
|
|
153
|
+
outboundTurnMetadata: jsonSummary(outbound, "x-codex-turn-metadata"),
|
|
154
|
+
inboundTurnState: jsonSummary(input.inboundHeaders, "x-codex-turn-state"),
|
|
155
|
+
outboundTurnState: jsonSummary(outbound, "x-codex-turn-state"),
|
|
156
|
+
});
|
|
157
|
+
} catch {
|
|
158
|
+
// Diagnostics must never affect request handling.
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const CODEX_AFFINITY_DEBUG_SAFE_HEADERS = SAFE_AFFINITY_HEADERS;
|