@yansigit/opencodex 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/LICENSE +21 -0
- package/README.md +303 -0
- package/assets/architecture.png +0 -0
- package/assets/banner.png +0 -0
- package/assets/claude-code-models.gif +0 -0
- package/assets/codex-app-picker.png +0 -0
- package/bin/ocx.mjs +587 -0
- package/bin/package-main.mjs +9 -0
- package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
- package/gui/dist/assets/index-CGoDO3uO.css +1 -0
- package/gui/dist/favicon.png +0 -0
- package/gui/dist/icons.svg +24 -0
- package/gui/dist/index.html +25 -0
- package/gui/dist/logo.png +0 -0
- package/gui/dist/provider-icons/alibaba-color.svg +1 -0
- package/gui/dist/provider-icons/antigravity-color.svg +1 -0
- package/gui/dist/provider-icons/claude-color.svg +1 -0
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -0
- package/gui/dist/provider-icons/cursor-color.svg +2 -0
- package/gui/dist/provider-icons/deepseek-color.svg +1 -0
- package/gui/dist/provider-icons/discord.svg +1 -0
- package/gui/dist/provider-icons/firepass-color.svg +1 -0
- package/gui/dist/provider-icons/fireworks-color.svg +1 -0
- package/gui/dist/provider-icons/gemini-color.svg +1 -0
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
- package/gui/dist/provider-icons/grok.svg +1 -0
- package/gui/dist/provider-icons/groq-color.svg +1 -0
- package/gui/dist/provider-icons/huggingface-color.svg +1 -0
- package/gui/dist/provider-icons/kimi-color.svg +1 -0
- package/gui/dist/provider-icons/kiro-color.svg +15 -0
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
- package/gui/dist/provider-icons/mistral-color.svg +1 -0
- package/gui/dist/provider-icons/moonshot-color.svg +1 -0
- package/gui/dist/provider-icons/nvidia-color.svg +1 -0
- package/gui/dist/provider-icons/ollama-color.svg +1 -0
- package/gui/dist/provider-icons/openai.svg +1 -0
- package/gui/dist/provider-icons/opencode.svg +2 -0
- package/gui/dist/provider-icons/openrouter-color.svg +1 -0
- package/gui/dist/provider-icons/pi.svg +21 -0
- package/gui/dist/provider-icons/qianfan-color.svg +1 -0
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
- package/gui/dist/provider-icons/telegram.svg +1 -0
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/vllm-color.svg +1 -0
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
- package/package.json +108 -0
- package/src/AGENTS.md +28 -0
- package/src/adapters/anthropic-image-guard.ts +251 -0
- package/src/adapters/anthropic-image-normalize.ts +518 -0
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +1327 -0
- package/src/adapters/azure.ts +36 -0
- package/src/adapters/base.ts +121 -0
- package/src/adapters/client-fingerprint.ts +65 -0
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/arg-codec.ts +38 -0
- package/src/adapters/cursor/arg-normalize.ts +104 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +288 -0
- package/src/adapters/cursor/discovery.ts +333 -0
- package/src/adapters/cursor/effort-map.ts +151 -0
- package/src/adapters/cursor/exec-policy.ts +88 -0
- package/src/adapters/cursor/framing.ts +250 -0
- package/src/adapters/cursor/gen/agent_pb.ts +15274 -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/kv-store.ts +52 -0
- package/src/adapters/cursor/live-models.ts +269 -0
- package/src/adapters/cursor/live-smoke-gate.ts +41 -0
- package/src/adapters/cursor/live-transport.ts +1653 -0
- package/src/adapters/cursor/mcp-config.ts +42 -0
- package/src/adapters/cursor/mcp-manager.ts +333 -0
- package/src/adapters/cursor/message-mapper.ts +49 -0
- package/src/adapters/cursor/native-exec-common.ts +76 -0
- package/src/adapters/cursor/native-exec-desktop.ts +184 -0
- package/src/adapters/cursor/native-exec-fs.ts +332 -0
- package/src/adapters/cursor/native-exec-mcp.ts +153 -0
- package/src/adapters/cursor/native-exec-network.ts +43 -0
- package/src/adapters/cursor/native-exec-shell.ts +547 -0
- package/src/adapters/cursor/native-exec-tools.ts +118 -0
- package/src/adapters/cursor/native-exec.ts +663 -0
- package/src/adapters/cursor/protobuf-events.ts +1381 -0
- package/src/adapters/cursor/protobuf-request.ts +1032 -0
- package/src/adapters/cursor/request-builder.ts +461 -0
- package/src/adapters/cursor/thread-continuity.ts +67 -0
- package/src/adapters/cursor/tool-definitions.ts +735 -0
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport-retry.ts +132 -0
- package/src/adapters/cursor/transport.ts +79 -0
- package/src/adapters/cursor/types.ts +79 -0
- package/src/adapters/cursor.ts +322 -0
- package/src/adapters/google-antigravity-hosts.ts +48 -0
- package/src/adapters/google-antigravity-replay.ts +827 -0
- package/src/adapters/google-antigravity-tools.ts +105 -0
- package/src/adapters/google-antigravity-wire.ts +141 -0
- package/src/adapters/google-errors.ts +92 -0
- package/src/adapters/google-http.ts +460 -0
- package/src/adapters/google-tool-schema.ts +238 -0
- package/src/adapters/google-truncation.ts +24 -0
- package/src/adapters/google-wire-compiler.ts +232 -0
- package/src/adapters/google.ts +1377 -0
- package/src/adapters/identity.ts +77 -0
- package/src/adapters/image.ts +23 -0
- package/src/adapters/kiro-constants.ts +16 -0
- package/src/adapters/kiro-errors.ts +208 -0
- package/src/adapters/kiro-events.ts +197 -0
- package/src/adapters/kiro-images.ts +129 -0
- package/src/adapters/kiro-retry.ts +312 -0
- package/src/adapters/kiro-thinking.ts +112 -0
- package/src/adapters/kiro-tool-fallback.ts +36 -0
- package/src/adapters/kiro-tools.ts +224 -0
- package/src/adapters/kiro-truncation.ts +33 -0
- package/src/adapters/kiro-wire.ts +129 -0
- package/src/adapters/kiro.ts +1936 -0
- package/src/adapters/mimo-free.ts +280 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1980 -0
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1911 -0
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +114 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +154 -0
- package/src/adapters/upstream-http-error.ts +48 -0
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +1986 -0
- package/src/chat/inbound.ts +319 -0
- package/src/chat/outbound.ts +821 -0
- package/src/claude/agents-inject.ts +266 -0
- package/src/claude/alias.ts +149 -0
- package/src/claude/auth-detect.ts +229 -0
- package/src/claude/auth-mode-migration.ts +32 -0
- package/src/claude/auth-mode.ts +62 -0
- package/src/claude/context-windows.ts +205 -0
- package/src/claude/desktop-3p-guard.ts +35 -0
- package/src/claude/desktop-3p-paths.ts +84 -0
- package/src/claude/desktop-3p.ts +615 -0
- package/src/claude/desktop-health.ts +26 -0
- package/src/claude/desktop-profile.ts +263 -0
- package/src/claude/gateway-cache.ts +107 -0
- package/src/claude/inbound-debug.ts +163 -0
- package/src/claude/inbound.ts +578 -0
- package/src/claude/model-info.ts +174 -0
- package/src/claude/outbound.ts +926 -0
- package/src/cli/access.ts +108 -0
- package/src/cli/account-api.ts +302 -0
- package/src/cli/account-auth.ts +250 -0
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +737 -0
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +299 -0
- package/src/cli/agent-driven.ts +70 -0
- package/src/cli/agent.ts +290 -0
- package/src/cli/catalog-prewarm.ts +27 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +213 -0
- package/src/cli/claude.ts +355 -0
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +47 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +127 -0
- package/src/cli/config-command.ts +209 -0
- package/src/cli/debug.ts +228 -0
- package/src/cli/dispatch.ts +585 -0
- package/src/cli/doctor.ts +1202 -0
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +213 -0
- package/src/cli/help.ts +101 -0
- package/src/cli/index.ts +973 -0
- package/src/cli/init.ts +211 -0
- package/src/cli/integrations.ts +260 -0
- package/src/cli/interactive-confirm.ts +133 -0
- 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 +245 -0
- package/src/cli/models.ts +422 -0
- package/src/cli/observe.ts +206 -0
- package/src/cli/opencode.ts +588 -0
- package/src/cli/provider-replit.ts +232 -0
- package/src/cli/provider-runtime.ts +179 -0
- package/src/cli/provider.ts +492 -0
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +422 -0
- package/src/cli/replit-gateway-key-input.ts +138 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +328 -0
- package/src/cli/star-prompt.ts +211 -0
- package/src/cli/status-oauth.ts +78 -0
- package/src/cli/status.ts +328 -0
- package/src/cli/system-command.ts +112 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +199 -0
- package/src/cli/v2.ts +268 -0
- package/src/cli.ts +10 -0
- package/src/clients/config-export.ts +1704 -0
- package/src/codex/account-id.ts +34 -0
- package/src/codex/account-label.ts +47 -0
- package/src/codex/account-lifecycle.ts +172 -0
- package/src/codex/account-namespace-match.ts +63 -0
- package/src/codex/account-namespaces.ts +195 -0
- package/src/codex/account-pause.ts +20 -0
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-runtime-state.ts +31 -0
- package/src/codex/account-store.ts +544 -0
- package/src/codex/account-usability.ts +43 -0
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/agent-roles-sync.ts +225 -0
- package/src/codex/agent-roles.ts +238 -0
- package/src/codex/app-server-processes.ts +1143 -0
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +2147 -0
- package/src/codex/auth-collision.ts +109 -0
- package/src/codex/auth-context.ts +665 -0
- package/src/codex/autostart-health.ts +156 -0
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +436 -0
- package/src/codex/catalog/bundled.ts +549 -0
- package/src/codex/catalog/effort.ts +446 -0
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +664 -0
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +650 -0
- package/src/codex/catalog/provider-fetch.ts +2064 -0
- package/src/codex/catalog/sync.ts +1883 -0
- 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 +14 -0
- 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/data/upstream-models.json +830 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/exec-invocation.ts +22 -0
- package/src/codex/features.ts +1566 -0
- 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 +108 -0
- package/src/codex/history-provider.ts +979 -0
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/home.ts +206 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1733 -0
- package/src/codex/injected-marker.ts +106 -0
- 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 +225 -0
- 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 +56 -0
- package/src/codex/main-account.ts +68 -0
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +273 -0
- 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 +144 -0
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +242 -0
- package/src/codex/pool-rotation.ts +295 -0
- package/src/codex/project-config-warnings.ts +425 -0
- 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 +573 -0
- package/src/codex/refresh.ts +62 -0
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +1888 -0
- package/src/codex/runtime.ts +659 -0
- package/src/codex/shim.ts +2170 -0
- package/src/codex/subagent-defaults.ts +550 -0
- package/src/codex/subagent-model-fallback.ts +784 -0
- package/src/codex/sync.ts +319 -0
- 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 +298 -0
- package/src/codex/websocket-registry.ts +100 -0
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +160 -0
- package/src/combos/index.ts +45 -0
- package/src/combos/request.ts +94 -0
- package/src/combos/resolve.ts +232 -0
- package/src/combos/types.ts +398 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +4041 -0
- package/src/fork/register.ts +3 -0
- package/src/generated/compatibility-version.json +3116 -0
- package/src/generated/model-metadata.ts +106 -0
- package/src/github/star-state.ts +203 -0
- package/src/grok/inject.ts +530 -0
- package/src/grok/inspect.ts +45 -0
- package/src/grok/status.ts +121 -0
- package/src/grok/sync.ts +66 -0
- package/src/images/artifacts.ts +516 -0
- package/src/images/fulfill-video.ts +163 -0
- package/src/images/fulfill.ts +149 -0
- package/src/images/index.ts +4 -0
- package/src/images/loop.ts +955 -0
- package/src/images/plan.ts +143 -0
- package/src/images/synthetic-tool.ts +133 -0
- package/src/images/types.ts +41 -0
- package/src/images/xai-client.ts +141 -0
- package/src/images/xai-video-client.ts +163 -0
- package/src/index.ts +22 -0
- 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/abort.ts +146 -0
- package/src/lib/admin-secrets.ts +25 -0
- package/src/lib/admission.ts +83 -0
- package/src/lib/app-owned-memory-stores.ts +195 -0
- package/src/lib/app-owned-memory.ts +265 -0
- package/src/lib/bounded-body.ts +346 -0
- package/src/lib/bun-binary-validator.d.mts +3 -0
- package/src/lib/bun-binary-validator.mjs +18 -0
- package/src/lib/bun-runtime.ts +184 -0
- package/src/lib/bun-stream-caps.ts +130 -0
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +364 -0
- package/src/lib/crash-guard.ts +344 -0
- package/src/lib/debug-log-buffer.ts +83 -0
- package/src/lib/debug-settings.ts +108 -0
- package/src/lib/debug.ts +31 -0
- package/src/lib/destination-policy.ts +380 -0
- package/src/lib/errors.ts +406 -0
- package/src/lib/eventstream-decoder.ts +253 -0
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/gcp-adc.ts +341 -0
- package/src/lib/injection-debug-log.ts +58 -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/open-url.ts +25 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +270 -0
- package/src/lib/privacy.ts +20 -0
- package/src/lib/process-control.ts +168 -0
- package/src/lib/provider-outbound.ts +210 -0
- package/src/lib/provider-url.ts +14 -0
- package/src/lib/proxy-env.ts +18 -0
- package/src/lib/redact.ts +521 -0
- package/src/lib/retry-after.ts +55 -0
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +25 -0
- package/src/lib/shadow-call.ts +61 -0
- package/src/lib/sidecar-tracker.ts +52 -0
- package/src/lib/sse-decoder.ts +364 -0
- package/src/lib/state-store-registrations.ts +119 -0
- package/src/lib/state-store-sweeper.ts +184 -0
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/test-home-guard.ts +90 -0
- package/src/lib/token-estimate.ts +86 -0
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +400 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +392 -0
- package/src/lib/win-exec.ts +115 -0
- package/src/lib/win-paths.ts +68 -0
- package/src/lib/windows-atomic-replace.ts +156 -0
- package/src/lib/windows-elevation.ts +773 -0
- package/src/lib/windows-secret-acl.ts +854 -0
- 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 +403 -0
- 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-routing.ts +594 -0
- package/src/oauth/anthropic.ts +188 -0
- package/src/oauth/antigravity-routing.ts +151 -0
- package/src/oauth/callback-server.ts +300 -0
- package/src/oauth/chatgpt.ts +161 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +252 -0
- package/src/oauth/github-copilot.ts +428 -0
- package/src/oauth/google-antigravity.ts +262 -0
- package/src/oauth/health.ts +407 -0
- package/src/oauth/index.ts +1504 -0
- package/src/oauth/key-providers.ts +124 -0
- package/src/oauth/kimi.ts +227 -0
- package/src/oauth/kiro-credentials.ts +726 -0
- package/src/oauth/kiro.ts +621 -0
- package/src/oauth/local-token-detect.ts +130 -0
- package/src/oauth/log.ts +50 -0
- package/src/oauth/login-cli.ts +223 -0
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/pkce.ts +15 -0
- package/src/oauth/store.ts +728 -0
- package/src/oauth/token-guardian.ts +309 -0
- package/src/oauth/types.ts +62 -0
- package/src/oauth/xai.ts +241 -0
- package/src/providers/alibaba-region-backup.ts +75 -0
- package/src/providers/alibaba-region-migration.ts +156 -0
- package/src/providers/alibaba-region-startup.ts +36 -0
- package/src/providers/antigravity-models.ts +695 -0
- package/src/providers/antigravity-quota.ts +216 -0
- package/src/providers/api-keys.ts +140 -0
- package/src/providers/base-url-choices.ts +74 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +82 -0
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +586 -0
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +187 -0
- package/src/providers/github-copilot-transport.ts +56 -0
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +271 -0
- package/src/providers/kiro-models.ts +67 -0
- package/src/providers/label.ts +19 -0
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +449 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +243 -0
- package/src/providers/openai-tier-startup.ts +56 -0
- package/src/providers/openai-tiers.ts +423 -0
- package/src/providers/openai-virtual-models.ts +83 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/openrouter-routing.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +185 -0
- package/src/providers/quota.ts +2345 -0
- package/src/providers/registry.ts +2918 -0
- package/src/providers/replit/constants.ts +27 -0
- package/src/providers/replit/derive.ts +85 -0
- package/src/providers/replit/headers.ts +28 -0
- package/src/providers/replit/origin.ts +55 -0
- package/src/providers/replit/pair-install-response.ts +72 -0
- package/src/providers/replit/probe.ts +199 -0
- package/src/providers/replit/setup.ts +350 -0
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +103 -0
- 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 +148 -0
- package/src/reasoning-effort.ts +183 -0
- package/src/responses/compaction.ts +142 -0
- 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 +838 -0
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +60 -0
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +165 -0
- package/src/responses/spill-store.ts +459 -0
- package/src/responses/state.ts +1433 -0
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-groups.ts +19 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +761 -0
- 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 +53 -0
- package/src/server/auth-cors.ts +751 -0
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +442 -0
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +1030 -0
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +190 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +152 -0
- package/src/server/image-retry.ts +42 -0
- package/src/server/images.ts +568 -0
- package/src/server/index.ts +1813 -0
- package/src/server/lifecycle.ts +498 -0
- package/src/server/live.ts +717 -0
- 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 +1433 -0
- package/src/server/management/api-access.ts +141 -0
- package/src/server/management/api-key-usage.ts +193 -0
- package/src/server/management/body.ts +41 -0
- package/src/server/management/combo-routes.ts +263 -0
- package/src/server/management/config-routes.ts +835 -0
- package/src/server/management/context.ts +113 -0
- 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 +586 -0
- package/src/server/management/model-routes.ts +560 -0
- 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 +637 -0
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +1033 -0
- package/src/server/management/replit-provider-routes.ts +86 -0
- 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 +385 -0
- package/src/server/management/shared.ts +286 -0
- package/src/server/management/sidebar-routes.ts +106 -0
- 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 +435 -0
- package/src/server/management/system-routes.ts +194 -0
- package/src/server/management/usage-summary-cache.ts +94 -0
- 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 +314 -0
- package/src/server/management-auth.ts +482 -0
- package/src/server/memory-watchdog.ts +156 -0
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +307 -0
- package/src/server/ports.ts +156 -0
- package/src/server/proxy-liveness.ts +328 -0
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +353 -0
- package/src/server/relay.ts +1209 -0
- package/src/server/request-decompress.ts +239 -0
- package/src/server/request-log-conversation.ts +168 -0
- package/src/server/request-log.ts +1259 -0
- 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 +551 -0
- package/src/server/responses/compact.ts +771 -0
- package/src/server/responses/core.ts +5389 -0
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +331 -0
- package/src/server/responses/fetch-helpers.ts +232 -0
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +78 -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 +251 -0
- package/src/server/responses/upstream-error.ts +53 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-image-gen-repair.ts +132 -0
- package/src/server/responses-item-id-repair.ts +272 -0
- 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 +25 -0
- package/src/server/search.ts +201 -0
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +263 -0
- package/src/server/startup-action-control.ts +315 -0
- package/src/server/startup-health-cache.ts +131 -0
- package/src/server/system-env.ts +484 -0
- package/src/server/windows-tcp-drop.ts +184 -0
- package/src/server/windows-tray-control.ts +41 -0
- package/src/server/ws-bridge.ts +472 -0
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +3575 -0
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/stall-timeout.ts +20 -0
- package/src/storage/cleanup-job.ts +57 -0
- package/src/storage/cleanup.ts +3085 -0
- package/src/storage/policy-job.ts +457 -0
- package/src/storage/policy-scheduler.ts +40 -0
- package/src/storage/policy-worker.ts +59 -0
- package/src/storage/policy.ts +527 -0
- package/src/storage/restore-job.ts +299 -0
- package/src/storage/restore-worker.ts +58 -0
- package/src/storage/scanner.ts +238 -0
- package/src/storage/storage-mutation-coordinator.ts +139 -0
- package/src/storage/worker-lifecycle.ts +215 -0
- package/src/tray/assets/opencodex-tray-offline.ico +0 -0
- package/src/tray/assets/opencodex-tray-online.ico +0 -0
- package/src/tray/assets/opencodex-tray-warning.ico +0 -0
- package/src/tray/assets/opencodex-tray.png +0 -0
- package/src/tray/windows-tray.ps1 +364 -0
- package/src/tray/windows.ts +757 -0
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +876 -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 +106 -0
- package/src/update/badge.ts +72 -0
- package/src/update/index.ts +415 -0
- package/src/update/job.ts +1887 -0
- package/src/update/notify.ts +263 -0
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/npm-invocation.d.mts +23 -0
- package/src/update/npm-invocation.mjs +94 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/update/tray-update-plan.d.mts +18 -0
- package/src/update/tray-update-plan.mjs +38 -0
- package/src/usage/cost.ts +625 -0
- package/src/usage/debug.ts +97 -0
- package/src/usage/expected-prices.ts +416 -0
- package/src/usage/log.ts +1223 -0
- package/src/usage/summary.ts +753 -0
- package/src/usage/totals.ts +14 -0
- 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 +189 -0
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +131 -0
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +681 -0
- 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 +195 -0
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +113 -0
- package/src/web-search/format-result.ts +89 -0
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +331 -0
- package/src/web-search/loop.ts +896 -0
- package/src/web-search/parse.ts +315 -0
- package/src/web-search/progress-stream.ts +342 -0
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/synthetic-tool.ts +47 -0
- package/src/web-search/xai-executor.ts +219 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the transition a history job belongs to.
|
|
3
|
+
*
|
|
4
|
+
* `updateCodexHistoryTransition` had no production caller, so every completed or
|
|
5
|
+
* skipped job left the coordinator row permanently `pending` — a transition was
|
|
6
|
+
* published and never resolved. This is that caller.
|
|
7
|
+
*
|
|
8
|
+
* The classification is `020_history_isolation.md:564-572`, applied rather than
|
|
9
|
+
* reinvented. The two unions do not line up one-to-one, so each outcome is
|
|
10
|
+
* mapped by hand: a cast across them would compile on the words they share and
|
|
11
|
+
* lie about the rest.
|
|
12
|
+
*/
|
|
13
|
+
import type { CodexHistoryJobOutcome } from "./history-job";
|
|
14
|
+
import type { CodexHistoryState, CodexTransitionVersion } from "./convergence-types";
|
|
15
|
+
import { updateCodexHistoryTransition } from "./transition-state";
|
|
16
|
+
|
|
17
|
+
/** The retry budget for a contended terminal CAS. Bounded; never unbounded. */
|
|
18
|
+
const TERMINAL_RETRY_ATTEMPTS = 3;
|
|
19
|
+
const TERMINAL_RETRY_DELAY_MS = 250;
|
|
20
|
+
|
|
21
|
+
function sleep(ms: number): void {
|
|
22
|
+
// The caller path here is synchronous after the awaited job, so a spin is the
|
|
23
|
+
// honest tool — awaiting would be, and this is short.
|
|
24
|
+
const until = Date.now() + ms;
|
|
25
|
+
while (Date.now() < until) { /* bounded */ }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function classify(outcome: CodexHistoryJobOutcome, txId: string | null): CodexHistoryState {
|
|
29
|
+
switch (outcome.kind) {
|
|
30
|
+
case "converged":
|
|
31
|
+
return {
|
|
32
|
+
status: "converged",
|
|
33
|
+
attempts: 1,
|
|
34
|
+
nextRetryAt: null,
|
|
35
|
+
txId,
|
|
36
|
+
// A zero is durable only when the worker proved the exact DB/manifest
|
|
37
|
+
// state while H was held. Without proof, keep the counts unknown. Keep
|
|
38
|
+
// `??`: `||` would discard a verified zero.
|
|
39
|
+
pendingRows: outcome.proof?.pendingRows ?? null,
|
|
40
|
+
backupEntries: outcome.proof?.backupEntries ?? null,
|
|
41
|
+
};
|
|
42
|
+
case "skipped":
|
|
43
|
+
// The user opting out is a completed decision, not a failure — converged
|
|
44
|
+
// with no reason. Marking it blocked would retry what they asked not to do.
|
|
45
|
+
return { status: "converged", attempts: 0, nextRetryAt: null, txId, pendingRows: null, backupEntries: null };
|
|
46
|
+
case "blocked":
|
|
47
|
+
return {
|
|
48
|
+
status: outcome.reason === "busy" ? "pending" : "blocked",
|
|
49
|
+
reason: outcome.reason === "busy" ? "db-busy"
|
|
50
|
+
: outcome.reason === "database" ? "unreadable"
|
|
51
|
+
: "permission",
|
|
52
|
+
attempts: 1,
|
|
53
|
+
// A busy unit retries; the others do not reschedule themselves.
|
|
54
|
+
nextRetryAt: outcome.reason === "busy"
|
|
55
|
+
? new Date(Date.now() + TERMINAL_RETRY_DELAY_MS * 10).toISOString()
|
|
56
|
+
: null,
|
|
57
|
+
txId,
|
|
58
|
+
pendingRows: null,
|
|
59
|
+
backupEntries: null,
|
|
60
|
+
};
|
|
61
|
+
case "failed":
|
|
62
|
+
return {
|
|
63
|
+
status: "unknown",
|
|
64
|
+
reason: outcome.reason === "timeout" ? "timeout"
|
|
65
|
+
: outcome.reason === "worker-died" ? "worker-died"
|
|
66
|
+
: "record-write-failed",
|
|
67
|
+
attempts: 1,
|
|
68
|
+
nextRetryAt: null,
|
|
69
|
+
txId,
|
|
70
|
+
pendingRows: null,
|
|
71
|
+
backupEntries: null,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Publish the terminal state of a history job against the transition it belongs
|
|
78
|
+
* to. A `conflict` means a newer transition won and is deliberately left alone.
|
|
79
|
+
* A `busy` terminal CAS retries a bounded number of times; when that exhausts,
|
|
80
|
+
* the previously persisted `pending` schedule is left intact — the same update
|
|
81
|
+
* needs the lock that was busy, so it cannot record its own failure
|
|
82
|
+
* (`005_contract.md:277`), and the retry being out of attempts is itself a
|
|
83
|
+
* terminal observation.
|
|
84
|
+
*/
|
|
85
|
+
export function resolveCodexHistoryTransition(
|
|
86
|
+
receipt: CodexTransitionVersion,
|
|
87
|
+
outcome: CodexHistoryJobOutcome,
|
|
88
|
+
): void {
|
|
89
|
+
const state = classify(outcome, receipt.currentTxId);
|
|
90
|
+
for (let attempt = 0; attempt < TERMINAL_RETRY_ATTEMPTS; attempt += 1) {
|
|
91
|
+
const result = updateCodexHistoryTransition(receipt, state);
|
|
92
|
+
if (result.kind === "updated") return;
|
|
93
|
+
if (result.kind === "conflict") {
|
|
94
|
+
// A newer transition already owns the row. Overwriting it would be the
|
|
95
|
+
// overtaken job overwriting the winner.
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (result.reason === "busy") {
|
|
99
|
+
if (attempt + 1 < TERMINAL_RETRY_ATTEMPTS) sleep(TERMINAL_RETRY_DELAY_MS * (attempt + 1));
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
// database / unsafe-path: retried CAS will not help.
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker-thread entry for the Codex history unit.
|
|
3
|
+
*
|
|
4
|
+
* Everything mutable about history happens here, behind H: the SQLite rows, the
|
|
5
|
+
* backup manifest, and every rollout patch. Those three do not share a
|
|
6
|
+
* transaction — sync writes the manifest before its database transaction, and
|
|
7
|
+
* restore writes rollouts, then the database, then the manifest
|
|
8
|
+
* (`src/codex/history-provider.ts:606-648,656-698`) — so a busy timeout only
|
|
9
|
+
* ever serialized a third of a state transition. Holding H across the whole unit
|
|
10
|
+
* is what stops an opposite-direction process overtaking through the other two.
|
|
11
|
+
*
|
|
12
|
+
* The message is deliberately thin, and it does NOT carry a direction. A caller
|
|
13
|
+
* saying which way history should move is exactly what the durable operation
|
|
14
|
+
* exists to prevent: `syncResumeHistory: false` means leave history alone, apply
|
|
15
|
+
* targets opencodex only in legacy mode, and legacy recovery is a different
|
|
16
|
+
* operation from generic restore. So the Worker is told which JOB to run and
|
|
17
|
+
* reads the operation from the coordinator row itself.
|
|
18
|
+
*
|
|
19
|
+
* Homes are carried explicitly because a Worker is a separate process: it does
|
|
20
|
+
* not inherit the module-load `CODEX_HOME` that `history-provider.ts` resolves
|
|
21
|
+
* at import time, so a request that leaned on those constants would silently
|
|
22
|
+
* address the wrong home.
|
|
23
|
+
*
|
|
24
|
+
* Design record: devlog/_fin/260804_codex_write_substrate/020_history_isolation.md.
|
|
25
|
+
*/
|
|
26
|
+
import { withHistoryWriteSerialization } from "./history-lock";
|
|
27
|
+
import { loadConfig } from "../config";
|
|
28
|
+
import { shouldSyncCodexOnStart } from "./desired-state";
|
|
29
|
+
import {
|
|
30
|
+
writeHistoryProviderTransition,
|
|
31
|
+
writeLegacyOpenaiHistoryRecovery,
|
|
32
|
+
type HistoryWriteTarget,
|
|
33
|
+
} from "./internal/history-writer";
|
|
34
|
+
import {
|
|
35
|
+
snapshotCodexHistoryNoop,
|
|
36
|
+
type CodexHistoryFailureReason,
|
|
37
|
+
type CodexHistoryVerifiedNoopProof,
|
|
38
|
+
} from "./history-provider";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The durable operation, mirrored into the request for diagnostics only.
|
|
42
|
+
*
|
|
43
|
+
* The Worker validates this against what it reads and refuses a mismatch rather
|
|
44
|
+
* than trusting it — a tampered copy must not be able to turn a restore into an
|
|
45
|
+
* apply. Structured-clone safe by construction: a closed set of string literals.
|
|
46
|
+
*/
|
|
47
|
+
export type CodexHistoryWorkerOperation =
|
|
48
|
+
| "skip"
|
|
49
|
+
| "apply-opencodex"
|
|
50
|
+
| "migrate-openai"
|
|
51
|
+
| "restore-openai"
|
|
52
|
+
| "recover-legacy-openai";
|
|
53
|
+
|
|
54
|
+
export interface HistoryWorkerRunMessage {
|
|
55
|
+
readonly type: "run";
|
|
56
|
+
readonly requestId: string;
|
|
57
|
+
/** Opaque durable job identity; the Worker refuses work that is not current. */
|
|
58
|
+
readonly jobId: string;
|
|
59
|
+
readonly operation: CodexHistoryWorkerOperation;
|
|
60
|
+
readonly canonicalCodexHome: string;
|
|
61
|
+
readonly canonicalStateDbPath: string;
|
|
62
|
+
readonly canonicalBackupPath: string;
|
|
63
|
+
/** When set, prove this transition's desired direction while H is held. */
|
|
64
|
+
readonly expectedDesiredEnabled?: boolean;
|
|
65
|
+
/** Env snapshot: a Worker may not observe parent mutations on every platform. */
|
|
66
|
+
readonly env?: { readonly CODEX_HOME?: string; readonly OPENCODEX_HOME?: string };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type HistoryWorkerResult =
|
|
70
|
+
| { readonly type: "done"; readonly requestId: string; readonly jobId: string;
|
|
71
|
+
readonly outcome: "converged" | "skipped";
|
|
72
|
+
readonly rows: number; readonly files: number;
|
|
73
|
+
readonly proof?: CodexHistoryVerifiedNoopProof }
|
|
74
|
+
| { readonly type: "blocked"; readonly requestId: string; readonly jobId: string;
|
|
75
|
+
readonly reason: "busy" | "database" | "unsafe-path" | "desired_disabled" | "desired_enabled" }
|
|
76
|
+
| { readonly type: "error"; readonly requestId: string; readonly jobId: string;
|
|
77
|
+
readonly message: string; readonly reason?: CodexHistoryFailureReason };
|
|
78
|
+
|
|
79
|
+
const OPERATIONS: ReadonlySet<string> = new Set<CodexHistoryWorkerOperation>([
|
|
80
|
+
"skip",
|
|
81
|
+
"apply-opencodex",
|
|
82
|
+
"migrate-openai",
|
|
83
|
+
"restore-openai",
|
|
84
|
+
"recover-legacy-openai",
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Validate the message before it can reach a writer.
|
|
89
|
+
*
|
|
90
|
+
* A malformed message is dropped rather than coerced. Every field is required
|
|
91
|
+
* and non-empty: an absent path would otherwise fall back to a module-load
|
|
92
|
+
* constant that points at the wrong home in this process.
|
|
93
|
+
*/
|
|
94
|
+
export function isHistoryWorkerRunMessage(data: unknown): data is HistoryWorkerRunMessage {
|
|
95
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) return false;
|
|
96
|
+
const message = data as Record<string, unknown>;
|
|
97
|
+
const nonEmpty = (value: unknown): value is string =>
|
|
98
|
+
typeof value === "string" && value.trim().length > 0;
|
|
99
|
+
return message.type === "run"
|
|
100
|
+
&& nonEmpty(message.requestId)
|
|
101
|
+
&& nonEmpty(message.jobId)
|
|
102
|
+
&& typeof message.operation === "string"
|
|
103
|
+
&& OPERATIONS.has(message.operation)
|
|
104
|
+
&& nonEmpty(message.canonicalCodexHome)
|
|
105
|
+
&& nonEmpty(message.canonicalStateDbPath)
|
|
106
|
+
&& nonEmpty(message.canonicalBackupPath)
|
|
107
|
+
&& (message.expectedDesiredEnabled === undefined || typeof message.expectedDesiredEnabled === "boolean");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Run one history operation under H.
|
|
112
|
+
*
|
|
113
|
+
* Exported so the unit can be exercised in-process; the Worker entry below is a
|
|
114
|
+
* thin adapter over it. `skip` is a real outcome rather than an absence: opting
|
|
115
|
+
* out of history resume must be recorded, not inferred from nothing happening.
|
|
116
|
+
*/
|
|
117
|
+
export function runHistoryUnitUnderLock(
|
|
118
|
+
message: HistoryWorkerRunMessage,
|
|
119
|
+
): HistoryWorkerResult {
|
|
120
|
+
const { requestId, jobId, operation } = message;
|
|
121
|
+
const target: HistoryWriteTarget = {
|
|
122
|
+
canonicalStateDbPath: message.canonicalStateDbPath,
|
|
123
|
+
canonicalBackupPath: message.canonicalBackupPath,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
if (operation === "skip") {
|
|
127
|
+
return { type: "done", requestId, jobId, outcome: "skipped", rows: 0, files: 0 };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const acquired = withHistoryWriteSerialization(
|
|
131
|
+
message.canonicalCodexHome,
|
|
132
|
+
message.canonicalStateDbPath,
|
|
133
|
+
permit => {
|
|
134
|
+
if (message.expectedDesiredEnabled !== undefined
|
|
135
|
+
&& shouldSyncCodexOnStart(loadConfig()) !== message.expectedDesiredEnabled) {
|
|
136
|
+
return { desiredStateChanged: true as const };
|
|
137
|
+
}
|
|
138
|
+
if (operation === "recover-legacy-openai") {
|
|
139
|
+
return writeLegacyOpenaiHistoryRecovery(permit, target);
|
|
140
|
+
}
|
|
141
|
+
if (operation === "migrate-openai") {
|
|
142
|
+
const proof = snapshotCodexHistoryNoop(message.canonicalStateDbPath, message.canonicalBackupPath);
|
|
143
|
+
if (proof.kind === "verified-noop") return { verifiedNoop: proof } as const;
|
|
144
|
+
}
|
|
145
|
+
// apply-opencodex routes history to opencodex; migrate/restore return it to
|
|
146
|
+
// native. The provider is derived from the operation, never from a caller.
|
|
147
|
+
const provider = operation === "apply-opencodex" ? "opencodex" : "openai";
|
|
148
|
+
return writeHistoryProviderTransition(permit, target, provider);
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
if (acquired.kind !== "completed") {
|
|
153
|
+
return { type: "blocked", requestId, jobId, reason: acquired.reason };
|
|
154
|
+
}
|
|
155
|
+
const result = acquired.value;
|
|
156
|
+
if ("desiredStateChanged" in result) {
|
|
157
|
+
return {
|
|
158
|
+
type: "blocked",
|
|
159
|
+
requestId,
|
|
160
|
+
jobId,
|
|
161
|
+
reason: message.expectedDesiredEnabled ? "desired_disabled" : "desired_enabled",
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if ("verifiedNoop" in result) {
|
|
165
|
+
return {
|
|
166
|
+
type: "done",
|
|
167
|
+
requestId,
|
|
168
|
+
jobId,
|
|
169
|
+
outcome: "converged",
|
|
170
|
+
rows: 0,
|
|
171
|
+
files: 0,
|
|
172
|
+
proof: result.verifiedNoop,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (result.failed === true) {
|
|
176
|
+
return {
|
|
177
|
+
type: "error",
|
|
178
|
+
requestId,
|
|
179
|
+
jobId,
|
|
180
|
+
message: "history_transition_failed",
|
|
181
|
+
...(result.failureReason ? { reason: result.failureReason } : {}),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
type: "done",
|
|
186
|
+
requestId,
|
|
187
|
+
jobId,
|
|
188
|
+
outcome: "converged",
|
|
189
|
+
rows: result.rows,
|
|
190
|
+
files: result.files,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
declare const self: Worker;
|
|
195
|
+
|
|
196
|
+
// Guarded so the module can be imported directly by tests without a Worker host.
|
|
197
|
+
if (typeof self !== "undefined" && typeof (self as { onmessage?: unknown }) === "object") {
|
|
198
|
+
self.onmessage = (event: MessageEvent<unknown>) => {
|
|
199
|
+
if (!isHistoryWorkerRunMessage(event.data)) return;
|
|
200
|
+
const message = event.data;
|
|
201
|
+
try {
|
|
202
|
+
if (message.env?.CODEX_HOME) process.env.CODEX_HOME = message.env.CODEX_HOME;
|
|
203
|
+
if (message.env?.OPENCODEX_HOME) process.env.OPENCODEX_HOME = message.env.OPENCODEX_HOME;
|
|
204
|
+
self.postMessage(runHistoryUnitUnderLock(message));
|
|
205
|
+
} catch (error) {
|
|
206
|
+
self.postMessage({
|
|
207
|
+
type: "error",
|
|
208
|
+
requestId: message.requestId,
|
|
209
|
+
jobId: message.jobId,
|
|
210
|
+
message: error instanceof Error ? error.message : "history_worker_failed",
|
|
211
|
+
} satisfies HistoryWorkerResult);
|
|
212
|
+
} finally {
|
|
213
|
+
// Close from inside the Worker so the thread begins exiting before the
|
|
214
|
+
// parent's terminate() races isolate realm reclaim on Windows.
|
|
215
|
+
try {
|
|
216
|
+
(self as unknown as { close?: () => void }).close?.();
|
|
217
|
+
} catch { /* already closing */ }
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, posix, resolve, win32 } from "node:path";
|
|
4
|
+
import { expandUserPath } from "../config";
|
|
5
|
+
import { redactUserPath } from "../lib/redact";
|
|
6
|
+
|
|
7
|
+
export type CodexHomeDeps = {
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
platform?: NodeJS.Platform | string;
|
|
10
|
+
release?: string;
|
|
11
|
+
procVersion?: string | null;
|
|
12
|
+
homedir?: () => string;
|
|
13
|
+
usersRoot?: string;
|
|
14
|
+
/** Raw /etc/wsl.conf content override (tests); null means "no file". */
|
|
15
|
+
wslConf?: string | null;
|
|
16
|
+
existsSync?: (path: string) => boolean;
|
|
17
|
+
readdirSync?: (path: string) => string[];
|
|
18
|
+
statSync?: typeof statSync;
|
|
19
|
+
realpathSync?: (path: string) => string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function windowsUserProfileToWslPath(value: string | undefined, automountRoot = DEFAULT_WSL_AUTOMOUNT_ROOT): string | null {
|
|
23
|
+
if (!value) return null;
|
|
24
|
+
const normalized = value.replaceAll("\\", "/");
|
|
25
|
+
const match = normalized.match(/^([A-Za-z]):\/Users\/([^/]+)$/);
|
|
26
|
+
if (!match) return null;
|
|
27
|
+
const root = normalizeAutomountRoot(automountRoot);
|
|
28
|
+
return `${root === "/" ? "" : root}/${match[1]!.toLowerCase()}/Users/${match[2]}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const DEFAULT_WSL_AUTOMOUNT_ROOT = "/mnt";
|
|
32
|
+
|
|
33
|
+
function normalizeAutomountRoot(value: string): string {
|
|
34
|
+
const trimmed = value.replace(/\/+$/, "");
|
|
35
|
+
return trimmed === "" ? "/" : trimmed;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function readWslConf(): string | null {
|
|
39
|
+
try {
|
|
40
|
+
return readFileSync("/etc/wsl.conf", "utf8");
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Windows drive mount root inside WSL: `[automount] root` from /etc/wsl.conf,
|
|
48
|
+
* default `/mnt` (https://learn.microsoft.com/en-us/windows/wsl/wsl-config).
|
|
49
|
+
* Returns a path without a trailing slash (or `/` itself).
|
|
50
|
+
*/
|
|
51
|
+
export function wslAutomountRoot(deps: CodexHomeDeps = {}): string {
|
|
52
|
+
const content = deps.wslConf !== undefined ? deps.wslConf : readWslConf();
|
|
53
|
+
if (!content) return DEFAULT_WSL_AUTOMOUNT_ROOT;
|
|
54
|
+
let section = "";
|
|
55
|
+
for (const rawLine of content.split("\n")) {
|
|
56
|
+
const line = rawLine.replace(/[#;].*$/, "").trim();
|
|
57
|
+
if (!line) continue;
|
|
58
|
+
const sect = line.match(/^\[(.+)\]$/);
|
|
59
|
+
if (sect) {
|
|
60
|
+
section = sect[1]!.trim().toLowerCase();
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (section !== "automount") continue;
|
|
64
|
+
const kv = line.match(/^root\s*=\s*(.+)$/i);
|
|
65
|
+
if (kv) {
|
|
66
|
+
const value = kv[1]!.trim().replace(/^["']|["']$/g, "");
|
|
67
|
+
if (!value.startsWith("/")) return DEFAULT_WSL_AUTOMOUNT_ROOT;
|
|
68
|
+
return normalizeAutomountRoot(value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return DEFAULT_WSL_AUTOMOUNT_ROOT;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function readProcVersion(): string | null {
|
|
75
|
+
try {
|
|
76
|
+
return readFileSync("/proc/version", "utf8");
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function isWslRuntime(deps: CodexHomeDeps = {}): boolean {
|
|
83
|
+
if ((deps.platform ?? process.platform) !== "linux") return false;
|
|
84
|
+
const env = deps.env ?? process.env;
|
|
85
|
+
if (env.WSL_DISTRO_NAME || env.WSL_INTEROP) return true;
|
|
86
|
+
const version = `${deps.release ?? ""}\n${deps.procVersion ?? readProcVersion() ?? ""}`;
|
|
87
|
+
return /microsoft|wsl/i.test(version);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** All Windows-profile `.codex` homes (with config.toml) visible from WSL, resolved real paths. */
|
|
91
|
+
export function listWslWindowsCodexHomes(deps: CodexHomeDeps = {}): string[] {
|
|
92
|
+
if (!isWslRuntime(deps)) return [];
|
|
93
|
+
const exists = deps.existsSync ?? existsSync;
|
|
94
|
+
const stat = deps.statSync ?? statSync;
|
|
95
|
+
const readdir = deps.readdirSync ?? readdirSync;
|
|
96
|
+
const realpath = deps.realpathSync ?? realpathSync.native;
|
|
97
|
+
const automountRoot = wslAutomountRoot(deps);
|
|
98
|
+
// WSL mount paths are POSIX by definition; keep separators stable on any host.
|
|
99
|
+
const usersRoot = deps.usersRoot ?? posix.join(automountRoot, "c", "Users");
|
|
100
|
+
if (!exists(usersRoot)) return [];
|
|
101
|
+
|
|
102
|
+
const candidates = [];
|
|
103
|
+
try {
|
|
104
|
+
for (const user of readdir(usersRoot)) {
|
|
105
|
+
if (user === "Default" || user === "Default User" || user === "Public" || user === "All Users") continue;
|
|
106
|
+
const home = posix.join(usersRoot, user, ".codex");
|
|
107
|
+
const config = posix.join(home, "config.toml");
|
|
108
|
+
if (!exists(config)) continue;
|
|
109
|
+
try {
|
|
110
|
+
if (stat(home).isDirectory()) candidates.push(realpath(home));
|
|
111
|
+
} catch {
|
|
112
|
+
// Ignore unreadable Windows profiles.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
return candidates;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function findWslWindowsCodexHome(deps: CodexHomeDeps = {}): string | null {
|
|
122
|
+
const env = deps.env ?? process.env;
|
|
123
|
+
const candidates = listWslWindowsCodexHomes(deps);
|
|
124
|
+
if (candidates.length === 0) return null;
|
|
125
|
+
|
|
126
|
+
const explicitProfile = windowsUserProfileToWslPath(env.USERPROFILE, wslAutomountRoot(deps));
|
|
127
|
+
if (explicitProfile) {
|
|
128
|
+
const explicitHome = posix.join(explicitProfile, ".codex");
|
|
129
|
+
const match = candidates.find(candidate => candidate === explicitHome || candidate.endsWith(`/${explicitProfile.split("/").pop()}/.codex`));
|
|
130
|
+
if (match) return match;
|
|
131
|
+
}
|
|
132
|
+
return candidates.length === 1 ? candidates[0]! : null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function defaultCodexHome(deps: CodexHomeDeps = {}): string {
|
|
136
|
+
const home = (deps.homedir ?? homedir)();
|
|
137
|
+
const defaultHome = join(home, ".codex");
|
|
138
|
+
const exists = deps.existsSync ?? existsSync;
|
|
139
|
+
const detected = !exists(join(defaultHome, "config.toml")) ? findWslWindowsCodexHome(deps) : null;
|
|
140
|
+
return detected ?? defaultHome;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function resolveCodexHomeDir(deps: CodexHomeDeps = {}): string {
|
|
144
|
+
const raw = (deps.env ?? process.env).CODEX_HOME?.trim();
|
|
145
|
+
if (raw) return resolve(expandUserPath(raw));
|
|
146
|
+
return defaultCodexHome(deps);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export type OrcaCodexHomeDiagnostic = {
|
|
150
|
+
applicable: boolean;
|
|
151
|
+
mismatch: boolean;
|
|
152
|
+
effectiveCodexHome: string;
|
|
153
|
+
appCodexHome: string;
|
|
154
|
+
orcaCodexHome: string | null;
|
|
155
|
+
warning: string | null;
|
|
156
|
+
action: string | null;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
type OrcaCodexHomeDeps = CodexHomeDeps & {
|
|
160
|
+
effectiveCodexHome?: string;
|
|
161
|
+
appCodexHome?: string;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
function normalizedWindowsPath(path: string): string {
|
|
165
|
+
return path.trim().replaceAll("/", "\\").replace(/\\+$/, "").toLowerCase();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* High-confidence Orca/ChatGPT dual-home diagnosis. Explicit CODEX_HOME remains
|
|
170
|
+
* authoritative; this only explains when an Orca-owned shell targets a home the
|
|
171
|
+
* Windows ChatGPT/Codex app does not read.
|
|
172
|
+
*/
|
|
173
|
+
export function collectOrcaCodexHomeDiagnostic(deps: OrcaCodexHomeDeps = {}): OrcaCodexHomeDiagnostic {
|
|
174
|
+
const platform = deps.platform ?? process.platform;
|
|
175
|
+
const env = deps.env ?? process.env;
|
|
176
|
+
const effectiveCodexHome = deps.effectiveCodexHome ?? resolveCodexHomeDir(deps);
|
|
177
|
+
const appCodexHome = deps.appCodexHome
|
|
178
|
+
?? (platform === "win32" ? win32.join((deps.homedir ?? homedir)(), ".codex") : join((deps.homedir ?? homedir)(), ".codex"));
|
|
179
|
+
const explicitHome = env.CODEX_HOME?.trim() ?? "";
|
|
180
|
+
const orcaCodexHome = env.ORCA_CODEX_HOME?.trim() || null;
|
|
181
|
+
const normalizedEffective = normalizedWindowsPath(effectiveCodexHome);
|
|
182
|
+
const normalizedOrca = orcaCodexHome ? normalizedWindowsPath(orcaCodexHome) : "";
|
|
183
|
+
const normalizedApp = normalizedWindowsPath(appCodexHome);
|
|
184
|
+
const applicable = platform === "win32"
|
|
185
|
+
&& !!explicitHome
|
|
186
|
+
&& !!orcaCodexHome
|
|
187
|
+
&& normalizedEffective === normalizedOrca
|
|
188
|
+
&& /(?:^|\\)orca\\codex-runtime-home\\home$/i.test(normalizedOrca);
|
|
189
|
+
const mismatch = applicable && normalizedEffective !== normalizedApp;
|
|
190
|
+
const displayEffective = redactUserPath(effectiveCodexHome);
|
|
191
|
+
const displayApp = redactUserPath(appCodexHome);
|
|
192
|
+
const displayOrca = orcaCodexHome ? redactUserPath(orcaCodexHome) : null;
|
|
193
|
+
return {
|
|
194
|
+
applicable,
|
|
195
|
+
mismatch,
|
|
196
|
+
effectiveCodexHome: displayEffective,
|
|
197
|
+
appCodexHome: displayApp,
|
|
198
|
+
orcaCodexHome: displayOrca,
|
|
199
|
+
warning: mismatch
|
|
200
|
+
? `CODEX_HOME targets Orca's runtime home (${displayEffective}), while the Windows ChatGPT/Codex app uses ${displayApp}; OpenCodex injection will not reach that app.`
|
|
201
|
+
: null,
|
|
202
|
+
action: mismatch
|
|
203
|
+
? "If a service was installed from Orca, run 'ocx service uninstall' in that original Orca shell first. Then in Command Prompt run set \"ORCA_CODEX_HOME=\" and set \"CODEX_HOME=%USERPROFILE%\\.codex\"; or in PowerShell run Remove-Item Env:ORCA_CODEX_HOME -ErrorAction SilentlyContinue; $env:CODEX_HOME = Join-Path $env:USERPROFILE '.codex'. Rerun the command, then reinstall with 'ocx service install'."
|
|
204
|
+
: null,
|
|
205
|
+
};
|
|
206
|
+
}
|