@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
package/bin/ocx.mjs
ADDED
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* opencodex npm bin launcher.
|
|
4
|
+
*
|
|
5
|
+
* The package source is TypeScript that runs on the Bun runtime. To let
|
|
6
|
+
* `npm install -g @yansigit/opencodex` work without a separately-installed Bun,
|
|
7
|
+
* we bundle the runtime via the `bun` npm dependency and exec it from this
|
|
8
|
+
* Node shim. (Dev still runs `bun run src/cli/index.ts` directly via the shebang on
|
|
9
|
+
* src/cli/index.ts — only the published npm `bin` routes through here.)
|
|
10
|
+
*/
|
|
11
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
12
|
+
import { randomBytes } from "node:crypto";
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
15
|
+
import { homedir } from "node:os";
|
|
16
|
+
import { dirname, join, resolve } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { isRealBunBinary } from "../src/lib/bun-binary-validator.mjs";
|
|
19
|
+
import { npmInvocation } from "../src/update/npm-invocation.mjs";
|
|
20
|
+
import {
|
|
21
|
+
npmCachePreflightFailureMessage,
|
|
22
|
+
runNpmCachePreflight,
|
|
23
|
+
} from "../src/update/npm-cache-preflight.mjs";
|
|
24
|
+
import { handoffWindowsTrayForUpdate, planWindowsTrayUpdate } from "../src/update/tray-update-plan.mjs";
|
|
25
|
+
import { bootRestoreProbe, transactionalNpmUpdate } from "../src/update/transactional-install.mjs";
|
|
26
|
+
|
|
27
|
+
const require = createRequire(import.meta.url);
|
|
28
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
29
|
+
function readPublishedPackageName() {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8"));
|
|
32
|
+
return typeof parsed.name === "string" && parsed.name ? parsed.name : "@yansigit/opencodex";
|
|
33
|
+
} catch {
|
|
34
|
+
return "@yansigit/opencodex";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const PKG = readPublishedPackageName();
|
|
38
|
+
const cliPath = join(here, "..", "src", "cli", "index.ts");
|
|
39
|
+
const NODE_LAUNCH_CONTEXT_ENV = "OCX_NODE_LAUNCH_CONTEXT";
|
|
40
|
+
const NODE_LAUNCH_PROOF_PREFIX = "--ocx-internal-launch-proof=";
|
|
41
|
+
|
|
42
|
+
function isNodeModulesInstall() {
|
|
43
|
+
return here.split(/[\\/]/).includes("node_modules");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isBunGlobalInstall() {
|
|
47
|
+
return /[\\/]\.bun[\\/]/.test(here);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function currentPackageVersion() {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8")).version ?? "?";
|
|
53
|
+
} catch {
|
|
54
|
+
return "?";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function updateTag(currentVersion) {
|
|
59
|
+
// Allowlist the tag: the value is argv-controlled and (on Windows) flows into a
|
|
60
|
+
// shell-joined spawnSync — never forward arbitrary strings.
|
|
61
|
+
const tagIndex = process.argv.indexOf("--tag");
|
|
62
|
+
const explicit = tagIndex !== -1 ? process.argv[tagIndex + 1] : undefined;
|
|
63
|
+
if (explicit === "preview" || explicit === "latest") return explicit;
|
|
64
|
+
return String(currentVersion).includes("-preview.") ? "preview" : "latest";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function expandUserPath(raw) {
|
|
68
|
+
// Mirror src/config.ts expandUserPath — the Bun proxy expands `~`, so this launcher's
|
|
69
|
+
// pid/state gates must resolve the same directory or they silently check the wrong path.
|
|
70
|
+
if (raw === "~") return homedir();
|
|
71
|
+
if (raw.startsWith("~/") || raw.startsWith("~\\")) return join(homedir(), raw.slice(2));
|
|
72
|
+
return raw;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function configDir() {
|
|
76
|
+
const raw = process.env.OPENCODEX_HOME?.trim();
|
|
77
|
+
return resolve(raw ? expandUserPath(raw) : join(homedir(), ".opencodex"));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function shouldRepairCodexShim() {
|
|
81
|
+
return existsSync(join(configDir(), "codex-shim.json"));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function historyRestoreIncomplete() {
|
|
85
|
+
// Mirror src/update/index.ts historyRestoreIncomplete — a codex-history-backup-*.json surviving
|
|
86
|
+
// a stop means the native-history restore was skipped (locked state DB).
|
|
87
|
+
try {
|
|
88
|
+
return readdirSync(configDir()).some(
|
|
89
|
+
name => name.startsWith("codex-history-backup-") && name.endsWith(".json"),
|
|
90
|
+
);
|
|
91
|
+
} catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function repairCodexShimIfNeeded() {
|
|
97
|
+
if (!shouldRepairCodexShim()) return;
|
|
98
|
+
const launcher = fileURLToPath(import.meta.url);
|
|
99
|
+
const res = spawnSync(process.execPath, [launcher, "codex-shim", "install"], {
|
|
100
|
+
stdio: "inherit",
|
|
101
|
+
windowsHide: true,
|
|
102
|
+
});
|
|
103
|
+
if (res.status !== 0) {
|
|
104
|
+
console.warn(`opencodex: Codex shim repair failed (${res.status ?? "unknown exit"}). Try: ocx codex-shim install`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function trayInstallState() {
|
|
109
|
+
const statePath = join(configDir(), "tray-state.json");
|
|
110
|
+
if (!existsSync(statePath)) return { installed: false, running: false };
|
|
111
|
+
let running = false;
|
|
112
|
+
try {
|
|
113
|
+
const heartbeat = JSON.parse(readFileSync(join(configDir(), "tray-heartbeat.json"), "utf8"));
|
|
114
|
+
if (Number.isSafeInteger(heartbeat.pid) && Date.now() - Number(heartbeat.timestamp) < 15_000) {
|
|
115
|
+
process.kill(heartbeat.pid, 0);
|
|
116
|
+
running = true;
|
|
117
|
+
}
|
|
118
|
+
} catch { /* installed but not running */ }
|
|
119
|
+
return { installed: true, running };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function runTrayLifecycle(launcher, action) {
|
|
123
|
+
return spawnSync(process.execPath, [launcher, "tray", action], {
|
|
124
|
+
stdio: "inherit",
|
|
125
|
+
windowsHide: true,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function runNpmSelfUpdate() {
|
|
130
|
+
const current = currentPackageVersion();
|
|
131
|
+
const tag = updateTag(current);
|
|
132
|
+
const latestInvocation = npmInvocation(["view", `${PKG}@${tag}`, "version"]);
|
|
133
|
+
const installInvocation = npmInvocation(["install", "-g", `${PKG}@${tag}`]);
|
|
134
|
+
if (!latestInvocation || !installInvocation) {
|
|
135
|
+
console.error("opencodex: could not resolve npm from a trusted absolute PATH entry; aborting before stopping the proxy.");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
const latestResult = spawnSync(latestInvocation.file, latestInvocation.args, {
|
|
139
|
+
encoding: "utf8",
|
|
140
|
+
timeout: 12000,
|
|
141
|
+
windowsHide: true,
|
|
142
|
+
...latestInvocation.options,
|
|
143
|
+
});
|
|
144
|
+
const latest = latestResult.status === 0 ? latestResult.stdout.trim() : "";
|
|
145
|
+
|
|
146
|
+
console.log(`opencodex v${current} (installed via npm, tag ${tag})`);
|
|
147
|
+
if (latest && latest === current) {
|
|
148
|
+
console.log(`Already on the latest ${tag} version (v${latest}).`);
|
|
149
|
+
process.exit(0);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const cachePreflight = runNpmCachePreflight();
|
|
153
|
+
if (!cachePreflight.ok) {
|
|
154
|
+
console.error(`opencodex: ${npmCachePreflightFailureMessage(cachePreflight.reason)}. Aborting before stopping the proxy.`);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Remember whether a background service manages the proxy BEFORE stopping — `ocx stop`
|
|
159
|
+
// unloads it, so a successful update must refresh and restart it afterwards.
|
|
160
|
+
const serviceStatePath = join(configDir(), "service-state.json");
|
|
161
|
+
const serviceWasInstalled = existsSync(serviceStatePath);
|
|
162
|
+
const trayBeforeUpdate = planWindowsTrayUpdate(
|
|
163
|
+
process.platform === "win32" ? trayInstallState() : { installed: false, running: false },
|
|
164
|
+
);
|
|
165
|
+
/**
|
|
166
|
+
* Refresh the existing service without re-registering it. `service repair` discovers
|
|
167
|
+
* the installed backend itself and, on Windows scheduler installs, rewrites the wrapper
|
|
168
|
+
* assets and restarts the existing task without `schtasks /create` — the elevation a
|
|
169
|
+
* non-admin `ocx update` does not have.
|
|
170
|
+
*/
|
|
171
|
+
function serviceRefreshArgs() {
|
|
172
|
+
return [launcher, "service", "repair"];
|
|
173
|
+
}
|
|
174
|
+
/** Register from scratch, preserving the recorded backend. Only for a genuinely absent service. */
|
|
175
|
+
function serviceInstallArgs() {
|
|
176
|
+
try {
|
|
177
|
+
const state = JSON.parse(readFileSync(serviceStatePath, "utf8"));
|
|
178
|
+
if (state.backend === "native") return [launcher, "service", "install", "--native"];
|
|
179
|
+
} catch { /* missing or corrupt — fall through to default */ }
|
|
180
|
+
return [launcher, "service", "install"];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Structured "is a service actually registered?" answer.
|
|
184
|
+
*
|
|
185
|
+
* This file is plain Node ESM and cannot import `diagnoseService()` from the
|
|
186
|
+
* TypeScript runtime, so it asks the freshly-installed launcher — which runs that
|
|
187
|
+
* diagnostic under Bun — and reads `startup.serviceInstalled`.
|
|
188
|
+
*
|
|
189
|
+
* Returns `null` when the probe itself could not answer, which callers must treat as
|
|
190
|
+
* "unknown" rather than "absent": failing closed here means NOT re-registering.
|
|
191
|
+
*/
|
|
192
|
+
function readServiceInstalledFromStatus(launcherPath) {
|
|
193
|
+
try {
|
|
194
|
+
const st = spawnSync(process.execPath, [launcherPath, "status", "--json"], {
|
|
195
|
+
encoding: "utf8",
|
|
196
|
+
timeout: 20_000,
|
|
197
|
+
windowsHide: true,
|
|
198
|
+
});
|
|
199
|
+
if (st.status !== 0 || typeof st.stdout !== "string" || !st.stdout.trim()) return null;
|
|
200
|
+
const installed = JSON.parse(st.stdout)?.startup?.serviceInstalled;
|
|
201
|
+
return typeof installed === "boolean" ? installed : null;
|
|
202
|
+
} catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Capture listen target before stop clears runtime-port.json (mirrors GUI/CLI update worker).
|
|
208
|
+
// Do not treat a live runtime port of 10100 as "missing" — track whether the read succeeded.
|
|
209
|
+
let bakePort = 10100;
|
|
210
|
+
let sawRuntimePort = false;
|
|
211
|
+
try {
|
|
212
|
+
const rt = JSON.parse(readFileSync(join(configDir(), "runtime-port.json"), "utf8"));
|
|
213
|
+
if (Number.isFinite(rt?.port) && rt.port > 0 && rt.port <= 65535) {
|
|
214
|
+
// Only trust runtime when its pid still looks alive (stale crash leftovers fall back to config).
|
|
215
|
+
const rtPid = Number(rt?.pid);
|
|
216
|
+
let runtimeLive = false;
|
|
217
|
+
if (Number.isSafeInteger(rtPid) && rtPid > 0) {
|
|
218
|
+
try {
|
|
219
|
+
process.kill(rtPid, 0);
|
|
220
|
+
runtimeLive = true;
|
|
221
|
+
} catch (e) {
|
|
222
|
+
if (e && typeof e === "object" && "code" in e && e.code === "EPERM") runtimeLive = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (runtimeLive) {
|
|
226
|
+
bakePort = Math.trunc(rt.port);
|
|
227
|
+
sawRuntimePort = true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} catch { /* fall through to config */ }
|
|
231
|
+
if (!sawRuntimePort) {
|
|
232
|
+
try {
|
|
233
|
+
const cfg = JSON.parse(readFileSync(join(configDir(), "config.json"), "utf8"));
|
|
234
|
+
if (Number.isFinite(cfg?.port) && cfg.port > 0 && cfg.port <= 65535) bakePort = Math.trunc(cfg.port);
|
|
235
|
+
} catch { /* keep default */ }
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Never replace package files under a live proxy — stop it first (full `ocx stop`
|
|
239
|
+
// semantics: graceful drain, service stop, native Codex restore). Gate on the service
|
|
240
|
+
// and the runtime-port record too: a service-managed or orphaned proxy can be live
|
|
241
|
+
// while ocx.pid is stale/missing.
|
|
242
|
+
const launcher = fileURLToPath(import.meta.url);
|
|
243
|
+
if (trayBeforeUpdate.stopBeforeReplacement) {
|
|
244
|
+
console.log("⏹ Handing off the Windows tray before updating...");
|
|
245
|
+
try {
|
|
246
|
+
handoffWindowsTrayForUpdate(trayBeforeUpdate, {
|
|
247
|
+
stop: () => {
|
|
248
|
+
const stopped = runTrayLifecycle(launcher, "stop");
|
|
249
|
+
return { exitStatus: stopped.status, running: trayInstallState().running };
|
|
250
|
+
},
|
|
251
|
+
start: () => runTrayLifecycle(launcher, "start"),
|
|
252
|
+
});
|
|
253
|
+
} catch {
|
|
254
|
+
console.error("opencodex: could not stop the Windows tray; aborting before package replacement.");
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const hasRuntimeState =
|
|
259
|
+
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
|
|
260
|
+
if (serviceWasInstalled || hasRuntimeState) {
|
|
261
|
+
console.log("⏹ Stopping the running proxy before updating...");
|
|
262
|
+
const stopRes = spawnSync(process.execPath, [launcher, "stop"], { stdio: "inherit", windowsHide: true });
|
|
263
|
+
const stillHasRuntimeState =
|
|
264
|
+
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
|
|
265
|
+
if (stopRes.status !== 0 || stillHasRuntimeState) {
|
|
266
|
+
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
|
|
267
|
+
console.error("opencodex: could not stop the running proxy; aborting the update. Run 'ocx stop' and retry.");
|
|
268
|
+
process.exit(1);
|
|
269
|
+
}
|
|
270
|
+
if (historyRestoreIncomplete()) {
|
|
271
|
+
console.warn(
|
|
272
|
+
"opencodex: WARNING — Codex resume history was NOT restored (history DB locked; Codex app/IDE open?).\n" +
|
|
273
|
+
" Routed threads stay hidden in the native Codex app until restored.\n" +
|
|
274
|
+
" After the update: close the Codex app, then run 'ocx stop' once to restore.",
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// #1942/#1849: stage -> verify -> swap -> rollback instead of installing straight
|
|
280
|
+
// into the live tree. A failure at any point leaves either the old or the new tree
|
|
281
|
+
// complete — never a file-less skeleton. Falls back to the legacy in-place install
|
|
282
|
+
// only when the transactional module cannot run at all.
|
|
283
|
+
const packageDir = resolve(here, "..");
|
|
284
|
+
console.log(`Updating${latest ? ` to v${latest}` : ""} (transactional)...`);
|
|
285
|
+
let res;
|
|
286
|
+
try {
|
|
287
|
+
const tx = transactionalNpmUpdate({
|
|
288
|
+
packageDir,
|
|
289
|
+
pkgName: PKG,
|
|
290
|
+
targetVersion: latest || undefined,
|
|
291
|
+
tag,
|
|
292
|
+
runNpm: (args) => {
|
|
293
|
+
const invocation = npmInvocation(args);
|
|
294
|
+
if (!invocation) return { status: 1 };
|
|
295
|
+
return spawnSync(invocation.file, invocation.args, {
|
|
296
|
+
stdio: "inherit",
|
|
297
|
+
timeout: 180000,
|
|
298
|
+
windowsHide: true,
|
|
299
|
+
...invocation.options,
|
|
300
|
+
});
|
|
301
|
+
},
|
|
302
|
+
log: (line) => console.log(line),
|
|
303
|
+
});
|
|
304
|
+
if (tx.ok) {
|
|
305
|
+
res = { status: 0 };
|
|
306
|
+
} else if (tx.phase === "stage" || tx.phase === "verify") {
|
|
307
|
+
// Live tree untouched: report and stop. Nothing to roll back.
|
|
308
|
+
console.error(`opencodex: update aborted before touching the live install (${tx.phase}): ${tx.error}`);
|
|
309
|
+
res = { status: 1 };
|
|
310
|
+
} else {
|
|
311
|
+
console.error(`opencodex: update failed (${tx.phase}): ${tx.error}${tx.rolledBack ? " — previous version restored." : ""}`);
|
|
312
|
+
res = { status: 1 };
|
|
313
|
+
}
|
|
314
|
+
} catch (error) {
|
|
315
|
+
// An unexpected throw means we cannot prove the live tree is untouched, so the
|
|
316
|
+
// legacy in-place install (which deletes live first) is exactly the wrong rescue —
|
|
317
|
+
// it recreates the #1849 destruction path. Report and stop; the boot probe and the
|
|
318
|
+
// recovery marker cover the swap-window states.
|
|
319
|
+
console.error(`opencodex: transactional update failed unexpectedly (${error?.message ?? error}). ` +
|
|
320
|
+
"The live install was not knowingly modified; run 'ocx update' again or reinstall with npm install -g.");
|
|
321
|
+
res = { status: 1 };
|
|
322
|
+
}
|
|
323
|
+
if (res.status === 0) {
|
|
324
|
+
console.log(`\nUpdated${latest ? ` to v${latest}` : ""}.`);
|
|
325
|
+
repairCodexShimIfNeeded();
|
|
326
|
+
if (trayBeforeUpdate.refreshAfterReplacement) {
|
|
327
|
+
const tray = spawnSync(process.execPath, [launcher, ...trayBeforeUpdate.installArgs], {
|
|
328
|
+
stdio: "inherit",
|
|
329
|
+
windowsHide: true,
|
|
330
|
+
});
|
|
331
|
+
if (tray.status !== 0) {
|
|
332
|
+
console.warn("opencodex: Windows tray refresh failed. Run: ocx tray install");
|
|
333
|
+
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// The stop above unloaded any managed service; refresh via the freshly-installed
|
|
337
|
+
// launcher so the new files write the baked paths and the service restarts.
|
|
338
|
+
if (serviceWasInstalled) {
|
|
339
|
+
console.log("Refreshing the background service with the updated files...");
|
|
340
|
+
const prevBake = process.env.OCX_BAKE_PORT;
|
|
341
|
+
process.env.OCX_BAKE_PORT = String(bakePort);
|
|
342
|
+
try {
|
|
343
|
+
let svc = spawnSync(process.execPath, serviceRefreshArgs(), { stdio: "inherit", windowsHide: true });
|
|
344
|
+
// `serviceWasInstalled` is inferred from service-state.json alone, which can be
|
|
345
|
+
// STALE — present while the registration is gone. Repair refuses that case by
|
|
346
|
+
// design, and its thrown Error is indistinguishable from any other failure at
|
|
347
|
+
// this layer (plain Error, inherited stdio, generic exit status). So ask for
|
|
348
|
+
// structured state instead of parsing the failure: install only when the
|
|
349
|
+
// diagnostic says the service is genuinely absent. Installing after ANY repair
|
|
350
|
+
// failure would resurrect the elevation prompt this change exists to avoid, and
|
|
351
|
+
// could re-register a service the user just uninstalled.
|
|
352
|
+
if (svc.status !== 0 && readServiceInstalledFromStatus(launcher) === false) {
|
|
353
|
+
console.log("No registered service found — installing it instead.");
|
|
354
|
+
svc = spawnSync(process.execPath, serviceInstallArgs(), { stdio: "inherit", windowsHide: true });
|
|
355
|
+
}
|
|
356
|
+
let needDirectStart = svc.status !== 0;
|
|
357
|
+
if (!needDirectStart) {
|
|
358
|
+
// Exit 0 can still leave stale/missing assets that never bring the proxy
|
|
359
|
+
// back — match the GUI/CLI fallthrough so /healthz is not left dead.
|
|
360
|
+
try {
|
|
361
|
+
const st = spawnSync(process.execPath, [launcher, "status", "--json"], {
|
|
362
|
+
encoding: "utf8",
|
|
363
|
+
timeout: 20_000,
|
|
364
|
+
windowsHide: true,
|
|
365
|
+
});
|
|
366
|
+
if (st.status === 0 && typeof st.stdout === "string" && st.stdout.trim()) {
|
|
367
|
+
const parsed = JSON.parse(st.stdout);
|
|
368
|
+
const proxyUp = parsed?.proxy?.running === true || parsed?.proxy?.health?.ok === true;
|
|
369
|
+
const viable = parsed?.startup?.serviceViable === true;
|
|
370
|
+
if (!proxyUp && !viable) needDirectStart = true;
|
|
371
|
+
} else {
|
|
372
|
+
// status failed or empty — fail closed to direct start (match CLI).
|
|
373
|
+
needDirectStart = true;
|
|
374
|
+
}
|
|
375
|
+
} catch {
|
|
376
|
+
needDirectStart = true;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (needDirectStart) {
|
|
380
|
+
// A repair needs no elevation, but it can still fail — or exit 0 while leaving
|
|
381
|
+
// a non-viable manager. Fall back to a direct detached proxy start so the
|
|
382
|
+
// update never leaves the user without a running proxy.
|
|
383
|
+
console.warn(
|
|
384
|
+
svc.status === 0
|
|
385
|
+
? "opencodex: service refresh left a non-viable manager — starting the proxy directly instead."
|
|
386
|
+
: "opencodex: service refresh failed — starting the proxy directly instead.",
|
|
387
|
+
);
|
|
388
|
+
console.warn(" Run 'ocx service repair' to see why the background service could not restart.");
|
|
389
|
+
const env = { ...process.env };
|
|
390
|
+
delete env.OCX_SERVICE;
|
|
391
|
+
const child = spawn(process.execPath, [launcher, "start", "--port", String(bakePort)], {
|
|
392
|
+
detached: true,
|
|
393
|
+
stdio: "ignore",
|
|
394
|
+
windowsHide: true,
|
|
395
|
+
env,
|
|
396
|
+
});
|
|
397
|
+
child.unref();
|
|
398
|
+
console.log(`Proxy starting on port ${bakePort}.`);
|
|
399
|
+
}
|
|
400
|
+
} finally {
|
|
401
|
+
if (prevBake === undefined) delete process.env.OCX_BAKE_PORT;
|
|
402
|
+
else process.env.OCX_BAKE_PORT = prevBake;
|
|
403
|
+
}
|
|
404
|
+
} else {
|
|
405
|
+
console.log("Restart the proxy: ocx start");
|
|
406
|
+
}
|
|
407
|
+
process.exit(0);
|
|
408
|
+
}
|
|
409
|
+
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
|
|
410
|
+
console.error(`\nUpdate failed (npm exit ${res.status ?? "?"}). Try manually: npm install -g ${PKG}@${tag}`);
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function bunBinDir() {
|
|
415
|
+
// Resolve the `bun` dependency's directory without hardcoding the platform
|
|
416
|
+
// package — npm's os/cpu/libc resolution already picked the right @oven/bun-*.
|
|
417
|
+
return dirname(require.resolve("bun/package.json"));
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const BUN_OVERRIDE_ENV = "OPENCODEX_BUN_PATH";
|
|
421
|
+
// Mirrors BUN_RUNTIME_SOURCE_ENV in src/lib/bun-runtime.ts. This launcher is plain
|
|
422
|
+
// Node and runs before any TypeScript is loaded, so the name is repeated rather than
|
|
423
|
+
// imported; tests/ocx-launcher-source.test.ts pins the two together.
|
|
424
|
+
const BUN_RUNTIME_SOURCE_ENV = "OCX_BUN_RUNTIME_SOURCE";
|
|
425
|
+
const BUN_RUNTIME_PATH_ENV = "OCX_BUN_RUNTIME_PATH";
|
|
426
|
+
|
|
427
|
+
function findBunBinary(bunDir) {
|
|
428
|
+
// The npm `bun` package ships the binary as bin/bun.exe on every platform;
|
|
429
|
+
// probe bin/bun too for forward compatibility.
|
|
430
|
+
for (const name of ["bun.exe", "bun"]) {
|
|
431
|
+
const p = join(bunDir, "bin", name);
|
|
432
|
+
if (isRealBunBinary(p)) return p;
|
|
433
|
+
}
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function fail(msg) {
|
|
438
|
+
console.error(
|
|
439
|
+
`opencodex: ${msg}\n` +
|
|
440
|
+
"The bundled Bun runtime could not be prepared. This usually means the\n" +
|
|
441
|
+
"install skipped lifecycle scripts (e.g. npm blocked bun's postinstall\n" +
|
|
442
|
+
"under allowScripts) or optional dependencies. Reinstall with:\n" +
|
|
443
|
+
` npm install -g --allow-scripts=bun ${PKG}\n` +
|
|
444
|
+
"(use sudo if the original install used sudo; without --ignore-scripts\n" +
|
|
445
|
+
"and without --omit=optional / optional=false)"
|
|
446
|
+
);
|
|
447
|
+
process.exit(1);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function resolveBun() {
|
|
451
|
+
// Keep direct npm-launcher starts aligned with durable service/shim installs:
|
|
452
|
+
// a valid explicit runtime must win even when the bundled dependency exists.
|
|
453
|
+
const override = process.env[BUN_OVERRIDE_ENV]?.trim();
|
|
454
|
+
if (override) {
|
|
455
|
+
const overridePath = resolve(override);
|
|
456
|
+
if (isRealBunBinary(overridePath)) return { path: overridePath, source: "override" };
|
|
457
|
+
console.error(
|
|
458
|
+
`opencodex: ${BUN_OVERRIDE_ENV} is missing, unreadable, or not a complete Bun binary; falling back to the bundled runtime.`,
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
let bunDir;
|
|
463
|
+
try {
|
|
464
|
+
bunDir = bunBinDir();
|
|
465
|
+
} catch {
|
|
466
|
+
fail("the `bun` dependency is not installed.");
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
let bin = findBunBinary(bunDir);
|
|
470
|
+
if (bin) return { path: bin, source: "bundled" };
|
|
471
|
+
|
|
472
|
+
// Lazy fallback: --ignore-scripts (or a failed postinstall) leaves the
|
|
473
|
+
// ~450-byte placeholder stub. Run the bun package's own installer once.
|
|
474
|
+
const installJs = join(bunDir, "install.js");
|
|
475
|
+
if (existsSync(installJs)) {
|
|
476
|
+
const r = spawnSync(process.execPath, [installJs], { stdio: "inherit" });
|
|
477
|
+
if (r.status === 0) bin = findBunBinary(bunDir);
|
|
478
|
+
}
|
|
479
|
+
if (!bin) fail("Bun binary missing after install attempt.");
|
|
480
|
+
return { path: bin, source: "bundled" };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// `ocx update --help` prints usage and exits WITHOUT side effects. The npm launcher
|
|
484
|
+
// intercepts `update` before the Bun CLI starts, so the help short-circuit must live
|
|
485
|
+
// here too — otherwise --help runs the real self-update, stops the proxy, and drops
|
|
486
|
+
// in-flight routed streams (issue #168).
|
|
487
|
+
const updateHelpRequested = process.argv[2] === "update" &&
|
|
488
|
+
process.argv.slice(3).some(a => a === "--help" || a === "-h" || a === "help");
|
|
489
|
+
if (updateHelpRequested) {
|
|
490
|
+
console.log("Usage: ocx update [--tag latest|preview]\n\nUpdate opencodex. Preview installs stay on the preview tag unless overridden.");
|
|
491
|
+
process.exit(0);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (process.argv[2] === "update" && isNodeModulesInstall() && !isBunGlobalInstall()) {
|
|
495
|
+
runNpmSelfUpdate();
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// #1849 boot probe: a prior update that lost power (or double-faulted) mid-swap leaves a
|
|
499
|
+
// backup sibling and a broken live tree. Restore before anything tries to run from the
|
|
500
|
+
// broken tree; reap stale backups once the live tree verifies healthy.
|
|
501
|
+
if (isNodeModulesInstall() && !isBunGlobalInstall()) {
|
|
502
|
+
try {
|
|
503
|
+
const probe = bootRestoreProbe(resolve(here, ".."));
|
|
504
|
+
if (probe.action === "restored") {
|
|
505
|
+
console.warn(`opencodex: previous update left a broken install — restored the backup from ${probe.from}.`);
|
|
506
|
+
} else if (probe.action === "failed") {
|
|
507
|
+
console.warn(`opencodex: a backup from a failed update exists but could not be restored automatically: ${probe.error}`);
|
|
508
|
+
}
|
|
509
|
+
} catch { /* the probe must never block launch */ }
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const bunRuntime = resolveBun();
|
|
513
|
+
const bun = bunRuntime.path;
|
|
514
|
+
|
|
515
|
+
// Run the Bun child asynchronously and FORWARD termination signals to it, then wait
|
|
516
|
+
// for its graceful shutdown before this launcher exits. The previous blocking
|
|
517
|
+
// spawnSync() could not run JS signal handlers and did not forward signals, so a
|
|
518
|
+
// signal delivered only to this launcher (Codex app, IDE terminal, service wrapper,
|
|
519
|
+
// or `kill -INT <launcherPid>`) killed the launcher and ORPHANED the Bun proxy —
|
|
520
|
+
// port left bound, pid/runtime-port files left behind, Codex config not restored.
|
|
521
|
+
//
|
|
522
|
+
// Provenance seam for issue #701: THIS launcher runs under Node, which does not
|
|
523
|
+
// auto-load a project `.env`/`.env.local`; the Bun child does, before any opencodex
|
|
524
|
+
// code evaluates. So this is the last point that can still tell a real shell export
|
|
525
|
+
// from a working-directory dotenv value, and we record which Anthropic credential or
|
|
526
|
+
// destination slots already existed. The context is paired with a random proof carried
|
|
527
|
+
// in argv, which project dotenv cannot modify during an ordinary `ocx` invocation.
|
|
528
|
+
// `src/cli/claude.ts` treats anything present in the Bun child but missing from this
|
|
529
|
+
// list as ambient project pollution rather than user auth or destination,
|
|
530
|
+
// which stopped a project dotenv from silently moving a claude.ai subscriber onto API
|
|
531
|
+
// billing and prevents it from redirecting the subscriber's OAuth bearer.
|
|
532
|
+
// Disabling Bun's dotenv wholesale with --no-env-file is NOT an option: config
|
|
533
|
+
// interpolation and provider settings legitimately read the project environment.
|
|
534
|
+
const preBunAnthropicSlots = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL"]
|
|
535
|
+
.filter(name => typeof process.env[name] === "string" && process.env[name] !== "");
|
|
536
|
+
const launchProof = randomBytes(32).toString("base64url");
|
|
537
|
+
const launchContext = JSON.stringify({
|
|
538
|
+
version: 1,
|
|
539
|
+
proof: launchProof,
|
|
540
|
+
anthropicEnvSlots: preBunAnthropicSlots,
|
|
541
|
+
});
|
|
542
|
+
const child = spawn(bun, [cliPath, `${NODE_LAUNCH_PROOF_PREFIX}${launchProof}`, ...process.argv.slice(2)], {
|
|
543
|
+
stdio: "inherit",
|
|
544
|
+
// A headless Windows parent (Task Scheduler, dashboard restart, shortcut) has no
|
|
545
|
+
// console to inherit. Without this flag Windows allocates a visible console for
|
|
546
|
+
// the long-running Bun child, and closing that window kills the proxy (#1236).
|
|
547
|
+
windowsHide: true,
|
|
548
|
+
env: {
|
|
549
|
+
...process.env,
|
|
550
|
+
[NODE_LAUNCH_CONTEXT_ENV]: launchContext,
|
|
551
|
+
[BUN_RUNTIME_SOURCE_ENV]: bunRuntime.source,
|
|
552
|
+
[BUN_RUNTIME_PATH_ENV]: bunRuntime.path,
|
|
553
|
+
},
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// Windows has no real POSIX signals (no SIGHUP); forwarding is best-effort there.
|
|
557
|
+
const FORWARDED = process.platform === "win32" ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
558
|
+
const handlers = FORWARDED.map(sig => {
|
|
559
|
+
const handler = () => {
|
|
560
|
+
try {
|
|
561
|
+
child.kill(sig);
|
|
562
|
+
} catch {
|
|
563
|
+
/* child already exited */
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
process.on(sig, handler);
|
|
567
|
+
return [sig, handler];
|
|
568
|
+
});
|
|
569
|
+
const clearHandlers = () => {
|
|
570
|
+
for (const [sig, handler] of handlers) process.removeListener(sig, handler);
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
child.on("error", err => {
|
|
574
|
+
clearHandlers();
|
|
575
|
+
console.error(`opencodex: failed to launch Bun runtime: ${err.message}`);
|
|
576
|
+
process.exit(1);
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
child.on("exit", (code, signal) => {
|
|
580
|
+
clearHandlers();
|
|
581
|
+
// Mirror the child's terminating signal/exit code so this launcher's status matches.
|
|
582
|
+
if (signal) {
|
|
583
|
+
process.kill(process.pid, signal);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
process.exit(code ?? 1);
|
|
587
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const packageName = "@yansigit/opencodex";
|
|
2
|
+
export const cliCommand = "ocx";
|
|
3
|
+
|
|
4
|
+
export async function loadBunApi() {
|
|
5
|
+
if (typeof Bun === "undefined") {
|
|
6
|
+
throw new Error("The opencodex programmatic API requires the Bun runtime. Use `ocx` for the CLI entrypoint.");
|
|
7
|
+
}
|
|
8
|
+
return import("../src/index.ts");
|
|
9
|
+
}
|