@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,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-state-first proxy liveness with identity checking.
|
|
3
|
+
*
|
|
4
|
+
* Historically `ensure`/`start` probed only `config.port` and accepted ANY 2xx /healthz:
|
|
5
|
+
* a proxy that started on a fallback port was invisible (duplicate starts, Codex synced
|
|
6
|
+
* back to a dead port), and a foreign app answering 200 on the configured port counted
|
|
7
|
+
* as "our proxy". Liveness now (1) prefers the pid + runtime-port record and (2) requires
|
|
8
|
+
* the /healthz body to identify as opencodex.
|
|
9
|
+
*
|
|
10
|
+
* Lives outside cli.ts (which dispatches argv at module top level) so tests can import it.
|
|
11
|
+
*/
|
|
12
|
+
import { loadConfig, readAlivePid, readRuntimePort, verifyPidIdentity } from "../config";
|
|
13
|
+
import { directLocalHttpFetch } from "./direct-local-http";
|
|
14
|
+
|
|
15
|
+
export interface HealthzIdentity {
|
|
16
|
+
service?: unknown;
|
|
17
|
+
status?: unknown;
|
|
18
|
+
version?: unknown;
|
|
19
|
+
uptime?: unknown;
|
|
20
|
+
pid?: unknown;
|
|
21
|
+
port?: unknown;
|
|
22
|
+
restartCapability?: unknown;
|
|
23
|
+
providerReloadCapability?: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface LivenessIo {
|
|
27
|
+
fetchFn?: typeof fetch;
|
|
28
|
+
readPidFn?: () => number | null;
|
|
29
|
+
/**
|
|
30
|
+
* Full identity check of the passed candidate pid; must return the SAME pid or null.
|
|
31
|
+
* Destructive callers only ever receive pids that passed this gate.
|
|
32
|
+
*/
|
|
33
|
+
verifyPidFn?: (candidatePid: number) => number | null;
|
|
34
|
+
readRuntimeFn?: (pid?: number) => { pid?: number; port: number; hostname?: string } | null;
|
|
35
|
+
configFn?: () => { port?: number; hostname?: string };
|
|
36
|
+
timeoutMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* How many times to retry a probe that failed with a transport error (timeout /
|
|
39
|
+
* connection refused). Definitive answers (non-OK HTTP, foreign /healthz body, pid
|
|
40
|
+
* mismatch) do not retry. Default 1 = no retry. Stop paths should pass 2–3 (#764).
|
|
41
|
+
*/
|
|
42
|
+
attempts?: number;
|
|
43
|
+
sleepFn?: (ms: number) => Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Absolute wall-clock deadline for discovery. When set, each probe attempt aborts
|
|
46
|
+
* once the remaining budget cannot cover another fetch — so multi-candidate
|
|
47
|
+
* `findLiveProxy` under `SERVICE_STOP_LIVENESS` cannot overrun the stop-path
|
|
48
|
+
* verification window (#764 / CodeRabbit).
|
|
49
|
+
*/
|
|
50
|
+
deadlineAt?: number;
|
|
51
|
+
nowFn?: () => number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Default per-probe fetch ceiling shared by liveness and readiness probes. */
|
|
55
|
+
export const DEFAULT_PROBE_TIMEOUT_MS = 750;
|
|
56
|
+
|
|
57
|
+
/** Default probe options for service stop / orphan cleanup — a just-bound proxy can miss a single 750ms probe. */
|
|
58
|
+
export const SERVICE_STOP_LIVENESS: Pick<LivenessIo, "timeoutMs" | "attempts"> = {
|
|
59
|
+
timeoutMs: 1500,
|
|
60
|
+
attempts: 3,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export interface LiveProxy {
|
|
64
|
+
pid: number | null;
|
|
65
|
+
port: number;
|
|
66
|
+
/** Raw bind hostname the probe succeeded against; compose URLs via `probeHostname`. */
|
|
67
|
+
hostname?: string;
|
|
68
|
+
/** Whether the successful probe used runtime-port metadata or the configured listen port. */
|
|
69
|
+
source: "runtime" | "config";
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Host to probe for a given bind hostname: wildcards answer on IPv4 loopback, and raw
|
|
74
|
+
* IPv6 addresses must be bracketed or the composed URL is invalid.
|
|
75
|
+
*/
|
|
76
|
+
export function probeHostname(hostname: string | undefined): string {
|
|
77
|
+
const trimmed = (hostname ?? "").trim();
|
|
78
|
+
if (!trimmed || trimmed === "0.0.0.0" || trimmed === "::" || trimmed === "[::]") return "127.0.0.1";
|
|
79
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) return trimmed;
|
|
80
|
+
return trimmed.includes(":") ? `[${trimmed}]` : trimmed;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* True when a /healthz body identifies an opencodex proxy. Accepts the explicit
|
|
85
|
+
* `service: "opencodex"` marker, plus the legacy `{status, version, uptime}` trio so a
|
|
86
|
+
* still-running pre-identity proxy (e.g. right after `ocx update`) is not mistaken for a
|
|
87
|
+
* foreign server and shadow-started over.
|
|
88
|
+
*/
|
|
89
|
+
export function isOpencodexHealthz(body: HealthzIdentity | null): boolean {
|
|
90
|
+
if (!body) return false;
|
|
91
|
+
if (body.service === "opencodex") return true;
|
|
92
|
+
if (body.service !== undefined) return false;
|
|
93
|
+
return body.status === "ok" && typeof body.version === "string" && typeof body.uptime === "number";
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Identity-checked /healthz probe; null when unreachable, non-OK, or not our proxy. */
|
|
97
|
+
export async function proxyIdentityAt(
|
|
98
|
+
port: number,
|
|
99
|
+
opts: { hostname?: string; expectedPid?: number } = {},
|
|
100
|
+
io: LivenessIo = {},
|
|
101
|
+
): Promise<{ pid: number | null } | null> {
|
|
102
|
+
const fetchFn = io.fetchFn ?? directLocalHttpFetch;
|
|
103
|
+
const sleepFn = io.sleepFn ?? ((ms: number) => new Promise<void>(r => setTimeout(r, ms)));
|
|
104
|
+
const nowFn = io.nowFn ?? Date.now;
|
|
105
|
+
const baseTimeoutMs = io.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
|
106
|
+
const requestedAttempts = Math.trunc(io.attempts ?? 1);
|
|
107
|
+
const attempts = Number.isNaN(requestedAttempts)
|
|
108
|
+
? 1
|
|
109
|
+
: Math.max(1, Math.min(requestedAttempts, 5));
|
|
110
|
+
|
|
111
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
112
|
+
const remainingMs = io.deadlineAt === undefined ? baseTimeoutMs : io.deadlineAt - nowFn();
|
|
113
|
+
if (remainingMs <= 0) return null;
|
|
114
|
+
const timeoutMs = Math.min(baseTimeoutMs, remainingMs);
|
|
115
|
+
try {
|
|
116
|
+
const res = await fetchFn(`http://${probeHostname(opts.hostname)}:${port}/healthz`, {
|
|
117
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
118
|
+
});
|
|
119
|
+
if (!res.ok) return null;
|
|
120
|
+
const body = (await res.json().catch(() => null)) as HealthzIdentity | null;
|
|
121
|
+
if (!isOpencodexHealthz(body)) return null;
|
|
122
|
+
const pid = typeof body?.pid === "number" ? body.pid : null;
|
|
123
|
+
if (opts.expectedPid !== undefined && pid !== null && pid !== opts.expectedPid) return null;
|
|
124
|
+
return { pid };
|
|
125
|
+
} catch {
|
|
126
|
+
// Transport failure (timeout / refused) — retry while budget remains; a proxy that
|
|
127
|
+
// has only just begun listening can miss a single short probe (#764).
|
|
128
|
+
if (attempt >= attempts) return null;
|
|
129
|
+
if (io.deadlineAt !== undefined && io.deadlineAt - nowFn() <= 0) return null;
|
|
130
|
+
await sleepFn(100);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Locate the live proxy: pid file → runtime-port record → identity probe. Falls back to
|
|
138
|
+
* the configured port ONLY when no runtime record answers, so a fallback-port proxy is
|
|
139
|
+
* found and a foreign listener on the configured port is rejected.
|
|
140
|
+
*/
|
|
141
|
+
export async function findLiveProxy(io: LivenessIo = {}): Promise<LiveProxy | null> {
|
|
142
|
+
// Prefer the cheap alive-pid check: the Windows cmdline probe (WMIC/PowerShell) is too
|
|
143
|
+
// expensive for waitForProxy's 150ms poll loop, and /healthz identity is the real trust gate.
|
|
144
|
+
const readPidFn = io.readPidFn ?? readAlivePid;
|
|
145
|
+
const verifyPidFn = io.verifyPidFn ?? verifyPidIdentity;
|
|
146
|
+
const readRuntimeFn = io.readRuntimeFn ?? readRuntimePort;
|
|
147
|
+
const configFn = io.configFn ?? loadConfig;
|
|
148
|
+
const nowFn = io.nowFn ?? Date.now;
|
|
149
|
+
const deadlineAt = io.deadlineAt;
|
|
150
|
+
const probeIo: LivenessIo = io;
|
|
151
|
+
const budgetExhausted = (): boolean =>
|
|
152
|
+
deadlineAt !== undefined && nowFn() >= deadlineAt;
|
|
153
|
+
|
|
154
|
+
// The cheap pid is discovery-only. Before it can appear in a returned (killable) result
|
|
155
|
+
// it must pass the full identity check AND the verifier must echo the exact candidate —
|
|
156
|
+
// a pidfile rewrite between discovery and verification can never swap in another process.
|
|
157
|
+
const killablePid = (candidate: number | null): number | null => {
|
|
158
|
+
if (candidate === null) return null;
|
|
159
|
+
const verified = verifyPidFn(candidate);
|
|
160
|
+
return verified === candidate ? verified : null;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const verifiedReportedPid = (reported: number | null): number | null => {
|
|
164
|
+
if (reported === null) return null;
|
|
165
|
+
if (!Number.isSafeInteger(reported) || reported <= 0) return null;
|
|
166
|
+
const verified = verifyPidFn(reported);
|
|
167
|
+
return verified === reported ? verified : null;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const pid = readPidFn();
|
|
171
|
+
let probedPort: number | null = null;
|
|
172
|
+
if (pid) {
|
|
173
|
+
const runtime = readRuntimeFn(pid);
|
|
174
|
+
if (runtime?.port) {
|
|
175
|
+
if (budgetExhausted()) return null;
|
|
176
|
+
probedPort = runtime.port;
|
|
177
|
+
const identity = await proxyIdentityAt(runtime.port, { hostname: runtime.hostname, expectedPid: pid }, probeIo);
|
|
178
|
+
if (identity) {
|
|
179
|
+
// healthz confirmed the pid itself → trusted; a pidless legacy body did not,
|
|
180
|
+
// so the cheap pid must pass full identity verification before it is returned.
|
|
181
|
+
const trusted = identity.pid === pid ? pid : killablePid(pid);
|
|
182
|
+
return { pid: trusted, port: runtime.port, hostname: runtime.hostname, source: "runtime" };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Orphan recovery: the pid file can be lost/corrupt while the proxy is alive (crash of a
|
|
188
|
+
// sibling command, manual deletion). The runtime record still says where it listens —
|
|
189
|
+
// identity-probe it so ensure/update/stop see the live proxy instead of shadowing it.
|
|
190
|
+
const record = readRuntimeFn();
|
|
191
|
+
if (record?.port && record.port !== probedPort) {
|
|
192
|
+
if (budgetExhausted()) return null;
|
|
193
|
+
const expectedPid = typeof record.pid === "number" ? record.pid : undefined;
|
|
194
|
+
const identity = await proxyIdentityAt(record.port, { hostname: record.hostname, expectedPid }, probeIo);
|
|
195
|
+
// Only the healthz-reported pid is authoritative here. The record's pid may be stale
|
|
196
|
+
// (its process dead, the port reused by a pidless legacy proxy) — synthesizing it
|
|
197
|
+
// would hand destructive callers (stopProxy → kill fallback) a reusable pid.
|
|
198
|
+
if (identity) {
|
|
199
|
+
return { pid: verifiedReportedPid(identity.pid), port: record.port, hostname: record.hostname, source: "runtime" };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const config = configFn();
|
|
204
|
+
const port = config.port ?? 10100;
|
|
205
|
+
if (budgetExhausted()) return null;
|
|
206
|
+
const identity = await proxyIdentityAt(port, { hostname: config.hostname }, probeIo);
|
|
207
|
+
if (identity) {
|
|
208
|
+
return {
|
|
209
|
+
pid: verifiedReportedPid(identity.pid) ?? killablePid(pid),
|
|
210
|
+
port,
|
|
211
|
+
hostname: config.hostname,
|
|
212
|
+
source: "config",
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
219
|
+
// Readiness (/readyz) strict probe.
|
|
220
|
+
//
|
|
221
|
+
// Liveness (/healthz) confirms the process answers; readiness confirms the
|
|
222
|
+
// post-startup Codex sync has settled. A readiness probe is identity-checked the
|
|
223
|
+
// same way liveness is, AND additionally enforces the full /readyz contract so
|
|
224
|
+
// an adversarial or malformed body can never count as ready:
|
|
225
|
+
//
|
|
226
|
+
// - HTTP 200 is required for status="ready"; HTTP 503 is required for pending
|
|
227
|
+
// or failed. Any other HTTP/body-status pairing is an invalid contract.
|
|
228
|
+
// - body.service must be exactly "opencodex".
|
|
229
|
+
// - body.version must be a non-empty string.
|
|
230
|
+
// - body.uptime must be a finite nonnegative number.
|
|
231
|
+
// - body.pid must be a positive integer; when `expectedPid` is supplied it must
|
|
232
|
+
// match exactly.
|
|
233
|
+
// - body.port must be an integer in 1..65535 and equal the probed port.
|
|
234
|
+
// - body.status must be exactly one of pending|ready|failed.
|
|
235
|
+
//
|
|
236
|
+
// Any unreachable, foreign, legacy, malformed, mismatched, or self-inconsistent
|
|
237
|
+
// response returns `null` so callers can never treat an invalid identity/contract
|
|
238
|
+
// as ready.
|
|
239
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
240
|
+
|
|
241
|
+
interface ReadyzBody {
|
|
242
|
+
service?: unknown;
|
|
243
|
+
version?: unknown;
|
|
244
|
+
uptime?: unknown;
|
|
245
|
+
pid?: unknown;
|
|
246
|
+
port?: unknown;
|
|
247
|
+
status?: unknown;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface ReadinessProbeResult {
|
|
251
|
+
/** True ONLY for a valid 200 + status="ready" body with a matching pid. */
|
|
252
|
+
ready: boolean;
|
|
253
|
+
/** Fixed sanitized status. A foreign/unreadable body yields a `null` RESULT, never a `null` status. */
|
|
254
|
+
status: "ready" | "pending" | "failed";
|
|
255
|
+
/** Positive integer pid from a valid body. */
|
|
256
|
+
pid: number;
|
|
257
|
+
/** Integer port from a valid body. */
|
|
258
|
+
port: number;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface ReadinessProbeIo {
|
|
262
|
+
fetchFn?: typeof fetch;
|
|
263
|
+
timeoutMs?: number;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const READYZ_STATUS_VALUES = new Set<"ready" | "pending" | "failed">(["ready", "pending", "failed"]);
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Validate a parsed /readyz body against the strict contract. Returns the
|
|
270
|
+
* sanitized probe result, or `null` when the body is foreign, legacy,
|
|
271
|
+
* malformed, or fails the pid/port checks. Pure (no I/O) so it is fully
|
|
272
|
+
* deterministic and unit-testable.
|
|
273
|
+
*/
|
|
274
|
+
export function validateReadyzBody(
|
|
275
|
+
body: unknown,
|
|
276
|
+
port: number,
|
|
277
|
+
opts: { expectedPid?: number } = {},
|
|
278
|
+
): ReadinessProbeResult | null {
|
|
279
|
+
if (!body || typeof body !== "object") return null;
|
|
280
|
+
const b = body as ReadyzBody;
|
|
281
|
+
if (b.service !== "opencodex") return null;
|
|
282
|
+
if (typeof b.version !== "string" || b.version.length === 0) return null;
|
|
283
|
+
if (typeof b.uptime !== "number" || !Number.isFinite(b.uptime) || b.uptime < 0) return null;
|
|
284
|
+
if (typeof b.pid !== "number" || !Number.isInteger(b.pid) || b.pid <= 0) return null;
|
|
285
|
+
if (
|
|
286
|
+
typeof b.port !== "number"
|
|
287
|
+
|| !Number.isInteger(b.port)
|
|
288
|
+
|| b.port < 1
|
|
289
|
+
|| b.port > 65535
|
|
290
|
+
|| b.port !== port
|
|
291
|
+
) return null;
|
|
292
|
+
if (typeof b.status !== "string" || !READYZ_STATUS_VALUES.has(b.status as "ready" | "pending" | "failed")) return null;
|
|
293
|
+
const status = b.status as "ready" | "pending" | "failed";
|
|
294
|
+
if (opts.expectedPid !== undefined && b.pid !== opts.expectedPid) return null;
|
|
295
|
+
return { ready: status === "ready", status, pid: b.pid, port: b.port };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Identity- and contract-checked /readyz probe. Returns `null` when the
|
|
300
|
+
* endpoint is unreachable or the body fails the strict contract (foreign 200,
|
|
301
|
+
* legacy health-only body, non-JSON, missing/malformed/mismatched fields,
|
|
302
|
+
* wrong port/pid, or an HTTP/body-status inconsistency). Returns
|
|
303
|
+
* `{ready:false, ...}` when the body is ours but pending or failed. Returns
|
|
304
|
+
* `{ready:true, ...}` ONLY for a valid 200 body with `status:"ready"` and (when
|
|
305
|
+
* requested) a matching pid.
|
|
306
|
+
*/
|
|
307
|
+
export async function probeReadiness(
|
|
308
|
+
port: number,
|
|
309
|
+
opts: { hostname?: string; expectedPid?: number } = {},
|
|
310
|
+
io: ReadinessProbeIo = {},
|
|
311
|
+
): Promise<ReadinessProbeResult | null> {
|
|
312
|
+
const fetchFn = io.fetchFn ?? directLocalHttpFetch;
|
|
313
|
+
try {
|
|
314
|
+
const res = await fetchFn(`http://${probeHostname(opts.hostname)}:${port}/readyz`, {
|
|
315
|
+
signal: AbortSignal.timeout(io.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS),
|
|
316
|
+
});
|
|
317
|
+
// Parse even on 503: /readyz returns JSON with a sanitized status while pending.
|
|
318
|
+
const body = (await res.json().catch(() => null)) as unknown;
|
|
319
|
+
const parsed = validateReadyzBody(body, port, opts);
|
|
320
|
+
if (!parsed) return null;
|
|
321
|
+
// HTTP/body-status consistency: ready requires 200; pending/failed require 503.
|
|
322
|
+
if (parsed.status === "ready" && res.status !== 200) return null;
|
|
323
|
+
if (parsed.status !== "ready" && res.status !== 503) return null;
|
|
324
|
+
return parsed;
|
|
325
|
+
} catch {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-server readiness gate for the opencodex proxy.
|
|
3
|
+
*
|
|
4
|
+
* `GET /healthz` answers "is the process alive and serving HTTP?" the instant the
|
|
5
|
+
* listener binds. Readiness is stricter: the proxy is "ready" only after the
|
|
6
|
+
* post-startup Codex catalog/config sync (`syncModelsToCodex`) has settled with
|
|
7
|
+
* `ok=true` and no catalog-sync warning. Until then the process is live (Codex can
|
|
8
|
+
* open a socket) but not ready (a request would race the sync or hit a stale
|
|
9
|
+
* catalog), so clients should back off.
|
|
10
|
+
*
|
|
11
|
+
* Design contract (per P1 review):
|
|
12
|
+
* - NO module-global mutable state. Each `startServer` invocation gets its own
|
|
13
|
+
* private gate via `createReadinessGate()`, captured by that listener's
|
|
14
|
+
* closure. Starting/failing a second server in the same process can never
|
|
15
|
+
* reset or mutate the first server's gate.
|
|
16
|
+
* - Only the fixed sanitized status enum `pending | ready | failed` is stored
|
|
17
|
+
* and exposed. There is no `changedAt`, no free-form failure reason, no sync
|
|
18
|
+
* message, no warning text, no catalog path, no provider output, and no
|
|
19
|
+
* account data — those are private diagnostic data and are never exposed by
|
|
20
|
+
* `/readyz`.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Sanitized readiness state. Exactly these three values, nothing else. */
|
|
24
|
+
export type ReadinessStatus = "pending" | "ready" | "failed";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Private per-server readiness controller. The status starts at `pending` and
|
|
28
|
+
* transitions at most once (to `ready` or `failed`) when the post-startup sync
|
|
29
|
+
* settles. The gate is owned by the listener closure that requested it.
|
|
30
|
+
*/
|
|
31
|
+
export interface ReadinessGate {
|
|
32
|
+
/** Current sanitized status. */
|
|
33
|
+
getStatus(): ReadinessStatus;
|
|
34
|
+
/** Mark the proxy ready (post-startup sync settled cleanly). */
|
|
35
|
+
markReady(): void;
|
|
36
|
+
/** Mark the proxy failed. No reason is stored or exposed. */
|
|
37
|
+
markFailed(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Create a fresh private gate for one `startServer` invocation. The returned
|
|
42
|
+
* gate is the only way to read or mutate this server's readiness.
|
|
43
|
+
*/
|
|
44
|
+
export function createReadinessGate(): ReadinessGate {
|
|
45
|
+
let status: ReadinessStatus = "pending";
|
|
46
|
+
return {
|
|
47
|
+
getStatus: () => status,
|
|
48
|
+
markReady: () => {
|
|
49
|
+
if (status === "pending") status = "ready";
|
|
50
|
+
},
|
|
51
|
+
markFailed: () => {
|
|
52
|
+
if (status === "pending") status = "failed";
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Minimal shape of the post-startup sync outcome the gate cares about. */
|
|
58
|
+
export interface SyncOutcomeLike {
|
|
59
|
+
ok?: boolean;
|
|
60
|
+
warning?: string;
|
|
61
|
+
/** #1046: whether the sync actually rewrote the on-disk catalog/cache. */
|
|
62
|
+
catalogWritten?: boolean;
|
|
63
|
+
cacheSynced?: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Drive the gate from the post-startup sync. Awaits `syncFn`; the gate goes to
|
|
68
|
+
* `ready` ONLY on `ok=true` with no nonempty warning. A throw, `null`, `ok=false`,
|
|
69
|
+
* or a nonempty warning transitions to `failed`. Used directly by `handleStart`
|
|
70
|
+
* so the startup transition is unit-testable without spawning the proxy. Returns
|
|
71
|
+
* the raw sync outcome so a caller that also needs the #1046 write flags (did the
|
|
72
|
+
* sync actually write the catalog/cache?) can keep them without a second call.
|
|
73
|
+
*/
|
|
74
|
+
export async function runStartupReadinessSync(
|
|
75
|
+
gate: ReadinessGate,
|
|
76
|
+
syncFn: () => Promise<SyncOutcomeLike | null>,
|
|
77
|
+
): Promise<SyncOutcomeLike | null> {
|
|
78
|
+
let result: SyncOutcomeLike | null;
|
|
79
|
+
try {
|
|
80
|
+
result = await syncFn();
|
|
81
|
+
} catch {
|
|
82
|
+
gate.markFailed();
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
if (result === null) {
|
|
86
|
+
gate.markFailed();
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
if (result.ok !== true) {
|
|
90
|
+
gate.markFailed();
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
if (result.warning !== undefined && result.warning !== "") {
|
|
94
|
+
gate.markFailed();
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
gate.markReady();
|
|
98
|
+
return result;
|
|
99
|
+
}
|