@iislee/opencodex 2.11.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* H — the cross-process history serialization primitive.
|
|
3
|
+
*
|
|
4
|
+
* Today a native apply or restore performs SQLite rows, the backup manifest and
|
|
5
|
+
* every rollout file on the caller thread, and the manifest and rollout writes
|
|
6
|
+
* sit OUTSIDE the provider's SQLite transaction
|
|
7
|
+
* (`src/codex/history-provider.ts:606-648,656-698`). A SQLite busy timeout
|
|
8
|
+
* therefore serializes one third of a state transition and explains one stall.
|
|
9
|
+
* H is held across the whole unit — DB, manifest and rollouts together — so an
|
|
10
|
+
* opposite-direction process cannot overtake through the unguarded files.
|
|
11
|
+
*
|
|
12
|
+
* Two ways H differs from K, both forced by review:
|
|
13
|
+
*
|
|
14
|
+
* `H -> N` is a real edge, not a violation. The Worker reads the coordinator row
|
|
15
|
+
* and writes its terminal state while holding H, and both take BEGIN IMMEDIATE
|
|
16
|
+
* on N. That is why H must be its own database: sharing N's would make the
|
|
17
|
+
* Worker contend with itself. `N -> H`, `K -> H` and `C -> H` are forbidden, and
|
|
18
|
+
* the resulting `H -> N -> K -> C` order was checked acyclic in review round 3.
|
|
19
|
+
*
|
|
20
|
+
* H is keyed by the canonical state database as well as the canonical home,
|
|
21
|
+
* because one CODEX_HOME can name a different `state_5.sqlite` and those are not
|
|
22
|
+
* the same exclusion (`src/codex/user-identity.ts`).
|
|
23
|
+
*
|
|
24
|
+
* The permit is a runtime registration, not a type. An opaque TypeScript brand
|
|
25
|
+
* proves a permit-bearing call path exists; it cannot prove the callback still
|
|
26
|
+
* holds the lock, and a permit leaked past its callback type-checks perfectly.
|
|
27
|
+
* So every history mutator asks this module at runtime whether the permit it was
|
|
28
|
+
* handed is still live for the state database it is about to write.
|
|
29
|
+
*
|
|
30
|
+
* Design record: devlog/_fin/260804_codex_write_substrate/005_contract.md §6.
|
|
31
|
+
*/
|
|
32
|
+
import { chmodSync, lstatSync, realpathSync } from "node:fs";
|
|
33
|
+
|
|
34
|
+
import { Database } from "bun:sqlite";
|
|
35
|
+
|
|
36
|
+
import {
|
|
37
|
+
CodexUserIdentityRefusal,
|
|
38
|
+
resolveCodexHistorySerializationDatabasePath,
|
|
39
|
+
resolveEffectiveUserIdentity,
|
|
40
|
+
samePathIdentity,
|
|
41
|
+
} from "./user-identity";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Authorization to perform history mutations inside ONE H acquisition.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately carries no usable field. Holding this object is necessary and
|
|
47
|
+
* never sufficient: `assertHistoryWritePermit` decides, by looking the object up
|
|
48
|
+
* in a registry only this module can write. A forged cast, a prototype copy or a
|
|
49
|
+
* symbol clone produces a value of this type that every writer refuses.
|
|
50
|
+
*/
|
|
51
|
+
export interface HistoryWritePermit {
|
|
52
|
+
readonly [historyWritePermitBrand]: true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
declare const historyWritePermitBrand: unique symbol;
|
|
56
|
+
|
|
57
|
+
export type HistorySerializationOutcome<T> =
|
|
58
|
+
| { kind: "completed"; value: T }
|
|
59
|
+
| { kind: "unavailable"; reason: "busy" | "database" | "unsafe-path" };
|
|
60
|
+
|
|
61
|
+
export class HistoryWritePermitRefusal extends Error {
|
|
62
|
+
readonly code = "CODEX_HISTORY_WRITE_PERMIT_REFUSED";
|
|
63
|
+
|
|
64
|
+
constructor(message: string) {
|
|
65
|
+
super(message);
|
|
66
|
+
this.name = "HistoryWritePermitRefusal";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface PermitRegistration {
|
|
71
|
+
readonly canonicalStateDbPath: string;
|
|
72
|
+
readonly transactionId: string;
|
|
73
|
+
live: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Registrations are marked dead, never deleted.
|
|
78
|
+
*
|
|
79
|
+
* Deleting would make a leaked permit indistinguishable from a forged one, and
|
|
80
|
+
* those are different bugs: "used after its acquisition released" points at a
|
|
81
|
+
* caller that kept a permit past its callback, while "never minted here" points
|
|
82
|
+
* at a cast or a clone. Both are refused; only the diagnosis differs. The map is
|
|
83
|
+
* weak, so a dead entry costs nothing once the permit is unreachable.
|
|
84
|
+
*/
|
|
85
|
+
const activePermits = new WeakMap<object, PermitRegistration>();
|
|
86
|
+
let acquisitionCounter = 0;
|
|
87
|
+
|
|
88
|
+
function isBusy(error: unknown): boolean {
|
|
89
|
+
const code = error && typeof error === "object" && "code" in error
|
|
90
|
+
? String((error as { code?: unknown }).code)
|
|
91
|
+
: "";
|
|
92
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
93
|
+
return code === "SQLITE_BUSY" || code === "SQLITE_LOCKED"
|
|
94
|
+
|| /database (?:is|table is) locked/i.test(message);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Refuse unless this exact permit is live for this exact state database.
|
|
99
|
+
*
|
|
100
|
+
* Every history mutator calls this BEFORE touching the database, the manifest or
|
|
101
|
+
* a rollout file. The state database is named by the caller rather than derived,
|
|
102
|
+
* because a rollout path can point anywhere the manifest recorded.
|
|
103
|
+
*/
|
|
104
|
+
export function assertHistoryWritePermit(
|
|
105
|
+
permit: HistoryWritePermit,
|
|
106
|
+
canonicalStateDbPath: string,
|
|
107
|
+
): void {
|
|
108
|
+
const registration = activePermits.get(permit as unknown as object);
|
|
109
|
+
if (!registration) {
|
|
110
|
+
throw new HistoryWritePermitRefusal(
|
|
111
|
+
"The history write permit was not minted by the serialization owner.",
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (!registration.live) {
|
|
115
|
+
throw new HistoryWritePermitRefusal(
|
|
116
|
+
"The history write permit belongs to a released acquisition.",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (registration.canonicalStateDbPath !== canonicalStateDbPath) {
|
|
120
|
+
throw new HistoryWritePermitRefusal(
|
|
121
|
+
"The history write permit authorizes a different Codex state database.",
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Acquire H for one canonical state database and run `work` while it is held.
|
|
128
|
+
*
|
|
129
|
+
* The callback may enter N — that is the `H -> N` edge the Worker needs to read
|
|
130
|
+
* the coordinator row and publish its terminal state. It must never re-enter H.
|
|
131
|
+
*
|
|
132
|
+
* `busy_timeout = 0` with `BEGIN IMMEDIATE` makes contention fail fast and
|
|
133
|
+
* typed. Blocking here would hold the acquisition across an unbounded wait,
|
|
134
|
+
* which is the stall this phase exists to remove.
|
|
135
|
+
*/
|
|
136
|
+
export function withHistoryWriteSerialization<T>(
|
|
137
|
+
canonicalCodexHome: string,
|
|
138
|
+
canonicalStateDbPath: string,
|
|
139
|
+
work: (permit: HistoryWritePermit) => T,
|
|
140
|
+
): HistorySerializationOutcome<T> {
|
|
141
|
+
let databasePath: string;
|
|
142
|
+
try {
|
|
143
|
+
databasePath = resolveCodexHistorySerializationDatabasePath(
|
|
144
|
+
resolveEffectiveUserIdentity(),
|
|
145
|
+
canonicalCodexHome,
|
|
146
|
+
canonicalStateDbPath,
|
|
147
|
+
);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
if (error instanceof CodexUserIdentityRefusal) {
|
|
150
|
+
return { kind: "unavailable", reason: "unsafe-path" };
|
|
151
|
+
}
|
|
152
|
+
return { kind: "unavailable", reason: "database" };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let database: Database | undefined;
|
|
156
|
+
let transactionOpen = false;
|
|
157
|
+
let registration: PermitRegistration | undefined;
|
|
158
|
+
let permit: HistoryWritePermit | undefined;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
let databaseWasAbsent = false;
|
|
162
|
+
try {
|
|
163
|
+
const before = lstatSync(databasePath);
|
|
164
|
+
if (before.isSymbolicLink() || !before.isFile()) {
|
|
165
|
+
return { kind: "unavailable", reason: "unsafe-path" };
|
|
166
|
+
}
|
|
167
|
+
if (process.platform !== "win32") {
|
|
168
|
+
const uid = process.getuid?.();
|
|
169
|
+
if (uid === undefined || before.uid !== uid || (before.mode & 0o777) !== 0o600) {
|
|
170
|
+
return { kind: "unavailable", reason: "unsafe-path" };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
} catch (cause) {
|
|
174
|
+
const code = cause && typeof cause === "object" && "code" in cause
|
|
175
|
+
? String((cause as { code?: unknown }).code)
|
|
176
|
+
: "";
|
|
177
|
+
if (code !== "ENOENT") throw cause;
|
|
178
|
+
databaseWasAbsent = true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
database = new Database(databasePath, { create: true });
|
|
182
|
+
if (databaseWasAbsent) {
|
|
183
|
+
try { chmodSync(databasePath, 0o600); } catch { /* Windows applies ACLs in WP11. */ }
|
|
184
|
+
}
|
|
185
|
+
const opened = lstatSync(databasePath);
|
|
186
|
+
if (opened.isSymbolicLink() || !opened.isFile()
|
|
187
|
+
|| !samePathIdentity(realpathSync.native(databasePath), databasePath)) {
|
|
188
|
+
return { kind: "unavailable", reason: "unsafe-path" };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
database.exec("PRAGMA busy_timeout = 0; BEGIN IMMEDIATE");
|
|
192
|
+
transactionOpen = true;
|
|
193
|
+
|
|
194
|
+
acquisitionCounter += 1;
|
|
195
|
+
registration = {
|
|
196
|
+
canonicalStateDbPath,
|
|
197
|
+
transactionId: `${process.pid}:${acquisitionCounter}`,
|
|
198
|
+
live: true,
|
|
199
|
+
};
|
|
200
|
+
// A bare object: nothing about it is guessable or reconstructable, because
|
|
201
|
+
// the authority lives in the registry entry rather than in the value.
|
|
202
|
+
permit = {} as HistoryWritePermit;
|
|
203
|
+
activePermits.set(permit as unknown as object, registration);
|
|
204
|
+
|
|
205
|
+
let value: T;
|
|
206
|
+
try {
|
|
207
|
+
value = work(permit);
|
|
208
|
+
} finally {
|
|
209
|
+
// Revoke BEFORE releasing the transaction, so a mutator racing the release
|
|
210
|
+
// can never find a live permit without a live lock. This runs on the
|
|
211
|
+
// throwing path too, which is what a `finally`-less version gets wrong.
|
|
212
|
+
registration.live = false;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
database.exec("COMMIT");
|
|
216
|
+
transactionOpen = false;
|
|
217
|
+
return { kind: "completed", value };
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (transactionOpen) {
|
|
220
|
+
try { database?.exec("ROLLBACK"); } catch { /* close releases the transaction */ }
|
|
221
|
+
transactionOpen = false;
|
|
222
|
+
}
|
|
223
|
+
if (registration?.live) {
|
|
224
|
+
registration.live = false;
|
|
225
|
+
}
|
|
226
|
+
if (error instanceof CodexUserIdentityRefusal) {
|
|
227
|
+
return { kind: "unavailable", reason: "unsafe-path" };
|
|
228
|
+
}
|
|
229
|
+
if (isBusy(error)) return { kind: "unavailable", reason: "busy" };
|
|
230
|
+
// A callback failure is the caller's error, not a lock outcome: H acquired
|
|
231
|
+
// fine. Reporting it as `unavailable` would tell the caller to retry
|
|
232
|
+
// something that fails identically.
|
|
233
|
+
throw error;
|
|
234
|
+
} finally {
|
|
235
|
+
try { database?.close(); } catch { /* acquisition already finished */ }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Test-only: prove a leaked permit is dead without reaching into the registry. */
|
|
240
|
+
export function isHistoryWritePermitLive(permit: HistoryWritePermit): boolean {
|
|
241
|
+
return activePermits.get(permit as unknown as object)?.live === true;
|
|
242
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
/** Sources whose native OpenAI provenance can be restored exactly. */
|
|
5
|
+
export const CODEX_HISTORY_RESUMABLE_SOURCES = ["cli", "vscode"] as const;
|
|
6
|
+
|
|
7
|
+
export interface CodexHistoryBackupEntry {
|
|
8
|
+
id: string;
|
|
9
|
+
rolloutPath: string;
|
|
10
|
+
modelProvider: string;
|
|
11
|
+
source: string;
|
|
12
|
+
hasUserEvent: 0 | 1;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CodexHistoryBackupManifest {
|
|
16
|
+
version: 1;
|
|
17
|
+
stateDbPath: string;
|
|
18
|
+
entries: Record<string, CodexHistoryBackupEntry>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type CodexHistoryManifestValidation =
|
|
22
|
+
| { readonly ok: true; readonly manifest: CodexHistoryBackupManifest }
|
|
23
|
+
| { readonly ok: false; readonly reason: "foreign-database" }
|
|
24
|
+
| {
|
|
25
|
+
readonly ok: false;
|
|
26
|
+
readonly reason: "schema";
|
|
27
|
+
readonly scope: "manifest" | "entry-shape" | "entry-provenance";
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function codexHistoryPathIdentity(path: string): string {
|
|
31
|
+
const canonical = resolve(path);
|
|
32
|
+
return process.platform === "win32" ? canonical.toLowerCase() : canonical;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Canonical identity used by both backup naming and manifest ownership checks.
|
|
37
|
+
* Windows paths are case-insensitive for this contract; other platforms keep
|
|
38
|
+
* the resolved path's case.
|
|
39
|
+
*/
|
|
40
|
+
export function codexHistoryStateDbIdentity(path: string): string {
|
|
41
|
+
return codexHistoryPathIdentity(path);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Stable, non-secret file-name component for one state database. */
|
|
45
|
+
export function codexHistoryBackupId(stateDbPath: string): string {
|
|
46
|
+
return createHash("sha256")
|
|
47
|
+
.update(codexHistoryStateDbIdentity(stateDbPath))
|
|
48
|
+
.digest("hex")
|
|
49
|
+
.slice(0, 16);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Platform-aware identity comparison shared by database and rollout checks. */
|
|
53
|
+
export function sameCodexHistoryPath(left: string, right: string): boolean {
|
|
54
|
+
return codexHistoryPathIdentity(left) === codexHistoryPathIdentity(right);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
58
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function hasAllowedProvenance(entry: Record<string, unknown>): boolean {
|
|
62
|
+
return (entry.modelProvider === "openai"
|
|
63
|
+
&& CODEX_HISTORY_RESUMABLE_SOURCES.includes(
|
|
64
|
+
entry.source as (typeof CODEX_HISTORY_RESUMABLE_SOURCES)[number],
|
|
65
|
+
))
|
|
66
|
+
|| (entry.modelProvider === "opencodex" && entry.source === "exec");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Validate only the versioned data contract and database ownership identity.
|
|
71
|
+
* Filesystem type checks, reads, fingerprints, rollout inspection, SQLite, and
|
|
72
|
+
* mutation deliberately remain with the callers.
|
|
73
|
+
*/
|
|
74
|
+
export function validateCodexHistoryBackupManifest(
|
|
75
|
+
raw: unknown,
|
|
76
|
+
expectedStateDbPath: string,
|
|
77
|
+
): CodexHistoryManifestValidation {
|
|
78
|
+
if (!isRecord(raw)
|
|
79
|
+
|| raw.version !== 1
|
|
80
|
+
|| typeof raw.stateDbPath !== "string"
|
|
81
|
+
|| !raw.stateDbPath.trim()
|
|
82
|
+
|| !isAbsolute(raw.stateDbPath)
|
|
83
|
+
|| !isRecord(raw.entries)) {
|
|
84
|
+
return { ok: false, reason: "schema", scope: "manifest" };
|
|
85
|
+
}
|
|
86
|
+
if (!sameCodexHistoryPath(raw.stateDbPath, expectedStateDbPath)) {
|
|
87
|
+
return { ok: false, reason: "foreign-database" };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (const [id, value] of Object.entries(raw.entries)) {
|
|
91
|
+
if (!isRecord(value)) {
|
|
92
|
+
return { ok: false, reason: "schema", scope: "entry-shape" };
|
|
93
|
+
}
|
|
94
|
+
if (!id
|
|
95
|
+
|| value.id !== id
|
|
96
|
+
|| typeof value.rolloutPath !== "string"
|
|
97
|
+
|| !value.rolloutPath.trim()
|
|
98
|
+
|| !isAbsolute(value.rolloutPath)
|
|
99
|
+
|| typeof value.modelProvider !== "string"
|
|
100
|
+
|| !value.modelProvider.trim()
|
|
101
|
+
|| typeof value.source !== "string"
|
|
102
|
+
|| !value.source.trim()
|
|
103
|
+
|| typeof value.hasUserEvent !== "number"
|
|
104
|
+
|| !Number.isSafeInteger(value.hasUserEvent)
|
|
105
|
+
|| (value.hasUserEvent !== 0 && value.hasUserEvent !== 1)
|
|
106
|
+
|| !hasAllowedProvenance(value)) {
|
|
107
|
+
return { ok: false, reason: "schema", scope: "entry-provenance" };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { ok: true, manifest: raw as unknown as CodexHistoryBackupManifest };
|
|
112
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { migrateHistoryToOpenai } from "./history-provider";
|
|
2
|
+
import { resolveCodexHistoryJobTarget, runCodexHistoryJob } from "./history-job";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* Daemon-side retry for the one-time Design-B history
|
|
5
|
+
* Daemon-side retry for the one-time Design-B history metadata restoration.
|
|
5
6
|
*
|
|
6
7
|
* Most upgrades run `ocx start` while the Codex app still holds `state_5.sqlite`,
|
|
7
|
-
* so the inject-time
|
|
8
|
-
*
|
|
8
|
+
* so the inject-time restore can fail on the FIRST start while manifest-backed original
|
|
9
|
+
* metadata is still pending. Instead
|
|
9
10
|
* of asking the user to close the app and rerun start, this guardian keeps retrying
|
|
10
11
|
* in the background until the migration lands.
|
|
11
12
|
*
|
|
@@ -22,8 +23,8 @@ export interface HistoryMigrationGuardianHandle {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export interface HistoryMigrationGuardianDeps {
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
migrateFn?: () => ReturnType<typeof migrateHistoryToOpenai>
|
|
27
|
+
| Promise<ReturnType<typeof migrateHistoryToOpenai>>;
|
|
27
28
|
log?: Pick<Console, "log">;
|
|
28
29
|
tickMs?: number;
|
|
29
30
|
maxTicks?: number;
|
|
@@ -41,8 +42,18 @@ function defaultSchedule(fn: () => void, ms: number): { cancel(): void } {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
export function startHistoryMigrationGuardian(deps: HistoryMigrationGuardianDeps = {}): HistoryMigrationGuardianHandle {
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
// The default migration goes through the history job, so the guardian's timer
|
|
46
|
+
// thread never performs the transition itself. A background repair that races
|
|
47
|
+
// an apply or a restore is exactly what H exists to order.
|
|
48
|
+
const migrateFn = deps.migrateFn ?? (async () => {
|
|
49
|
+
const outcome = await runCodexHistoryJob({
|
|
50
|
+
...resolveCodexHistoryJobTarget(),
|
|
51
|
+
operation: "migrate-openai",
|
|
52
|
+
});
|
|
53
|
+
return outcome.kind === "converged"
|
|
54
|
+
? { rows: outcome.rows, files: outcome.files, verifiedNoop: outcome.proof?.kind === "verified-noop" }
|
|
55
|
+
: { rows: 0, files: 0, failed: true as const };
|
|
56
|
+
});
|
|
46
57
|
const log = deps.log ?? console;
|
|
47
58
|
const tickMs = deps.tickMs ?? DEFAULT_TICK_MS;
|
|
48
59
|
const maxTicks = deps.maxTicks ?? DEFAULT_MAX_TICKS;
|
|
@@ -56,27 +67,22 @@ export function startHistoryMigrationGuardian(deps: HistoryMigrationGuardianDeps
|
|
|
56
67
|
pending = (deps.scheduleFn ?? defaultSchedule)(tick, tickMs);
|
|
57
68
|
};
|
|
58
69
|
|
|
59
|
-
const tick = () => {
|
|
70
|
+
const tick = async () => {
|
|
60
71
|
if (stopped) return;
|
|
61
72
|
ticks++;
|
|
62
73
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
// Locked probe or pending work: attempt one migration pass.
|
|
69
|
-
const result = migrateFn();
|
|
74
|
+
// The worker re-derives state under H on every pass; no pre-lock probe is
|
|
75
|
+
// allowed to stop or suppress this attempt.
|
|
76
|
+
const result = await migrateFn();
|
|
70
77
|
if (!result.failed) {
|
|
71
|
-
const moved = result.rows + (result.ejectedRows ?? 0);
|
|
78
|
+
const moved = result.rows + ((result as { ejectedRows?: number }).ejectedRows ?? 0);
|
|
72
79
|
if (moved > 0) {
|
|
73
|
-
log.log(`🩹 history-migration: ${moved}
|
|
80
|
+
log.log(`🩹 history-migration: restored original provider metadata for ${moved} manifest-backed thread(s).`);
|
|
74
81
|
}
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (moved > 0 || (!after.failed && after.pendingRows === 0 && after.backupEntries === 0)) {
|
|
82
|
+
// Zero mutations are authoritative only when the worker verified the
|
|
83
|
+
// exact DB/manifest state while H was held.
|
|
84
|
+
const verifiedNoop = (result as { verifiedNoop?: boolean }).verifiedNoop === true;
|
|
85
|
+
if (moved > 0 || verifiedNoop) {
|
|
80
86
|
stopped = true;
|
|
81
87
|
return;
|
|
82
88
|
}
|
|
@@ -86,7 +92,7 @@ export function startHistoryMigrationGuardian(deps: HistoryMigrationGuardianDeps
|
|
|
86
92
|
}
|
|
87
93
|
if (ticks >= maxTicks) {
|
|
88
94
|
stopped = true;
|
|
89
|
-
log.log("⚠️ history-migration:
|
|
95
|
+
log.log("⚠️ history-migration: Could not verify that backed-up provider metadata was restored; the history database may be busy, unavailable, or not yet ready. Run 'ocx sync' (or check 'ocx doctor').");
|
|
90
96
|
return;
|
|
91
97
|
}
|
|
92
98
|
schedule();
|