@iislee/opencodex 2.11.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -17,45 +17,123 @@
|
|
|
17
17
|
* - If detached spawn fails (sync throw or pre-start `error`): exit(1) without
|
|
18
18
|
* markRecycling — after drain the listen socket is already closed, so a latch
|
|
19
19
|
* reset cannot recover serving. Clear inherited `OCX_SERVICE` so exit cleanup
|
|
20
|
-
* can restore Codex/Grok fences
|
|
21
|
-
*
|
|
20
|
+
* can restore Codex/Grok fences when a stale service marker has no viable
|
|
21
|
+
* supervisor. Log only a stable errno code — never the raw message
|
|
22
22
|
* (paths in ENOENT often include the OS username).
|
|
23
23
|
*/
|
|
24
24
|
import { spawn } from "node:child_process";
|
|
25
25
|
import {
|
|
26
|
+
beginShutdownDrain,
|
|
26
27
|
drainAndShutdown,
|
|
27
28
|
getActiveTurnCount,
|
|
28
29
|
getServerListenPort,
|
|
29
30
|
isDraining,
|
|
31
|
+
isShutdownDraining,
|
|
30
32
|
markRecyclingForExit,
|
|
31
|
-
|
|
33
|
+
stopServerListener,
|
|
32
34
|
} from "../lifecycle";
|
|
33
35
|
import { isServiceViable } from "../../service";
|
|
34
36
|
import { readRuntimePort } from "../../config";
|
|
37
|
+
import { withProcessRuntimeProvenance } from "../../lib/bun-runtime";
|
|
38
|
+
import { selfLaunchArgv } from "../../lib/self-launch-argv";
|
|
39
|
+
import {
|
|
40
|
+
MEMORY_DRAIN_RESTART_MS,
|
|
41
|
+
REPLACEMENT_READY_TIMEOUT_MS,
|
|
42
|
+
} from "../../lib/system-restart-contract";
|
|
43
|
+
import { findLiveProxy } from "../proxy-liveness";
|
|
44
|
+
|
|
45
|
+
export { MEMORY_DRAIN_RESTART_MS, REPLACEMENT_READY_TIMEOUT_MS } from "../../lib/system-restart-contract";
|
|
46
|
+
export const DEADLINE_LISTENER_STOP_TIMEOUT_MS = 5_000;
|
|
47
|
+
const REPLACEMENT_READY_POLL_MS = 150;
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
export interface ReplacementReadinessIo {
|
|
50
|
+
findLive?: typeof findLiveProxy;
|
|
51
|
+
now?: () => number;
|
|
52
|
+
sleep?: (ms: number) => Promise<void>;
|
|
53
|
+
}
|
|
38
54
|
|
|
39
55
|
export interface SystemRestartIo {
|
|
40
56
|
drainAndShutdown?: typeof drainAndShutdown;
|
|
41
57
|
/** True when a background service can actually respawn this process after exit(1). */
|
|
42
58
|
isServiceViable?: () => boolean;
|
|
43
59
|
isSupervisedServiceChild?: () => boolean;
|
|
44
|
-
/**
|
|
45
|
-
spawnStart?: (port?: number) => void | Promise<void>;
|
|
60
|
+
/** Ordinary start; deadline handoff may defer health until parent exit releases OS locks. */
|
|
61
|
+
spawnStart?: (port?: number, waitForHealthBeforeParentExit?: boolean) => void | Promise<void>;
|
|
62
|
+
/** Idempotent listener close; must settle before an ordinary start is spawned. */
|
|
63
|
+
stopListener?: () => void | Promise<void>;
|
|
46
64
|
markRecycling?: () => void;
|
|
47
65
|
exitProcess?: (code: number) => void;
|
|
48
66
|
schedule?: (fn: () => void | Promise<void>, ms: number) => void;
|
|
67
|
+
scheduleDeadline?: (fn: () => void, ms: number) => () => void;
|
|
49
68
|
isDraining?: () => boolean;
|
|
69
|
+
isShutdownDraining?: () => boolean;
|
|
70
|
+
beginShutdownDrain?: () => boolean;
|
|
50
71
|
setDraining?: (value: boolean) => void;
|
|
51
72
|
getActiveTurnCount?: () => number;
|
|
52
73
|
listenPort?: () => number | undefined;
|
|
74
|
+
now?: () => number;
|
|
53
75
|
}
|
|
54
76
|
|
|
55
77
|
let restartIo: SystemRestartIo = {};
|
|
56
78
|
/** Prevents double-scheduling in the 200ms window before drainAndShutdown sets draining. */
|
|
57
79
|
let restartAccepted = false;
|
|
58
80
|
|
|
81
|
+
type RestartDrainOutcome = "completed" | "rejected" | "deadline";
|
|
82
|
+
type BoundedSettlementOutcome = "completed" | "rejected" | "deadline";
|
|
83
|
+
|
|
84
|
+
function waitForRestartDrain(
|
|
85
|
+
drainPromise: Promise<void>,
|
|
86
|
+
deadlineMs: number,
|
|
87
|
+
now: () => number,
|
|
88
|
+
scheduleDeadline: NonNullable<SystemRestartIo["scheduleDeadline"]>,
|
|
89
|
+
): Promise<RestartDrainOutcome> {
|
|
90
|
+
const remainingMs = Math.max(0, deadlineMs - now());
|
|
91
|
+
if (remainingMs === 0) {
|
|
92
|
+
// Observe any late rejection even though orchestration is already terminal.
|
|
93
|
+
void drainPromise.catch(() => {});
|
|
94
|
+
return Promise.resolve("deadline");
|
|
95
|
+
}
|
|
96
|
+
return new Promise<RestartDrainOutcome>((resolve) => {
|
|
97
|
+
let settled = false;
|
|
98
|
+
let cancelDeadline: (() => void) | undefined;
|
|
99
|
+
const finish = (outcome: RestartDrainOutcome) => {
|
|
100
|
+
if (settled) return;
|
|
101
|
+
settled = true;
|
|
102
|
+
cancelDeadline?.();
|
|
103
|
+
resolve(outcome);
|
|
104
|
+
};
|
|
105
|
+
cancelDeadline = scheduleDeadline(() => finish("deadline"), remainingMs);
|
|
106
|
+
if (settled) cancelDeadline();
|
|
107
|
+
void drainPromise.then(
|
|
108
|
+
() => finish("completed"),
|
|
109
|
+
() => finish("rejected"),
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function waitForBoundedSettlement(
|
|
115
|
+
promise: Promise<void>,
|
|
116
|
+
timeoutMs: number,
|
|
117
|
+
scheduleDeadline: NonNullable<SystemRestartIo["scheduleDeadline"]>,
|
|
118
|
+
): Promise<BoundedSettlementOutcome> {
|
|
119
|
+
return new Promise<BoundedSettlementOutcome>((resolve) => {
|
|
120
|
+
let settled = false;
|
|
121
|
+
let cancelDeadline: (() => void) | undefined;
|
|
122
|
+
const finish = (outcome: BoundedSettlementOutcome) => {
|
|
123
|
+
if (settled) return;
|
|
124
|
+
settled = true;
|
|
125
|
+
cancelDeadline?.();
|
|
126
|
+
resolve(outcome);
|
|
127
|
+
};
|
|
128
|
+
cancelDeadline = scheduleDeadline(() => finish("deadline"), timeoutMs);
|
|
129
|
+
if (settled) cancelDeadline();
|
|
130
|
+
void promise.then(
|
|
131
|
+
() => finish("completed"),
|
|
132
|
+
() => finish("rejected"),
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
59
137
|
/** Test seam — reset between tests. */
|
|
60
138
|
export function setSystemRestartIoForTests(io: SystemRestartIo = {}): void {
|
|
61
139
|
restartIo = io;
|
|
@@ -86,42 +164,180 @@ function spawnFailureCode(err: unknown): string {
|
|
|
86
164
|
return "spawn_failed";
|
|
87
165
|
}
|
|
88
166
|
|
|
89
|
-
function
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
167
|
+
function handoffError(code: string): NodeJS.ErrnoException {
|
|
168
|
+
const error = new Error(code) as NodeJS.ErrnoException;
|
|
169
|
+
error.code = code;
|
|
170
|
+
return error;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function waitForReplacementReady(
|
|
174
|
+
expectedPid: number | undefined,
|
|
175
|
+
parentPid: number,
|
|
176
|
+
expectedPort: number | undefined,
|
|
177
|
+
io: ReplacementReadinessIo = {},
|
|
178
|
+
): Promise<boolean> {
|
|
179
|
+
const findLive = io.findLive ?? findLiveProxy;
|
|
180
|
+
const now = io.now ?? Date.now;
|
|
181
|
+
const sleep = io.sleep ?? Bun.sleep;
|
|
182
|
+
const deadline = now() + REPLACEMENT_READY_TIMEOUT_MS;
|
|
183
|
+
while (now() < deadline) {
|
|
184
|
+
try {
|
|
185
|
+
const live = await findLive({
|
|
186
|
+
deadlineAt: deadline,
|
|
187
|
+
nowFn: now,
|
|
188
|
+
sleepFn: sleep,
|
|
189
|
+
});
|
|
190
|
+
// A probe that began within budget can still return after it. Never accept
|
|
191
|
+
// delayed health as proof once the shared absolute handoff budget expired.
|
|
192
|
+
if (now() >= deadline) return false;
|
|
193
|
+
if (
|
|
194
|
+
live
|
|
195
|
+
&& live.pid !== null
|
|
196
|
+
&& live.pid !== parentPid
|
|
197
|
+
&& (expectedPid === undefined || live.pid === expectedPid)
|
|
198
|
+
&& (expectedPort === undefined || live.port === expectedPort)
|
|
199
|
+
) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
} catch {
|
|
203
|
+
// A not-yet-bound replacement is indistinguishable from a transient
|
|
204
|
+
// liveness failure here; keep polling inside the one bounded window.
|
|
205
|
+
}
|
|
206
|
+
const remainingMs = deadline - now();
|
|
207
|
+
if (remainingMs <= 0) break;
|
|
208
|
+
await sleep(Math.min(REPLACEMENT_READY_POLL_MS, remainingMs));
|
|
93
209
|
}
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function spawnDetachedStart(
|
|
214
|
+
port?: number,
|
|
215
|
+
waitForHealthBeforeParentExit = true,
|
|
216
|
+
): Promise<void> {
|
|
217
|
+
const args = ["start"];
|
|
218
|
+
const expectedPort = typeof port === "number" && Number.isFinite(port) && port > 0 && port <= 65535
|
|
219
|
+
? Math.trunc(port)
|
|
220
|
+
: undefined;
|
|
221
|
+
if (expectedPort !== undefined) {
|
|
222
|
+
args.push("--port", String(expectedPort));
|
|
223
|
+
}
|
|
224
|
+
const launchArgs = selfLaunchArgv(args);
|
|
94
225
|
return new Promise<void>((resolve, reject) => {
|
|
95
226
|
let child: ReturnType<typeof spawn>;
|
|
96
227
|
try {
|
|
97
|
-
|
|
228
|
+
const env: NodeJS.ProcessEnv = { ...process.env };
|
|
229
|
+
delete env.OCX_SERVICE;
|
|
230
|
+
child = spawn(process.execPath, launchArgs, {
|
|
98
231
|
detached: true,
|
|
99
232
|
stdio: "ignore",
|
|
100
233
|
windowsHide: true,
|
|
101
|
-
env:
|
|
234
|
+
env: withProcessRuntimeProvenance(env),
|
|
102
235
|
});
|
|
103
236
|
} catch (err) {
|
|
104
237
|
reject(err);
|
|
105
238
|
return;
|
|
106
239
|
}
|
|
107
240
|
let settled = false;
|
|
108
|
-
const
|
|
241
|
+
const cleanup = () => {
|
|
242
|
+
child.off("error", onError);
|
|
243
|
+
child.off("exit", onExit);
|
|
244
|
+
child.off("spawn", onSpawn);
|
|
245
|
+
};
|
|
246
|
+
const finish = (error?: unknown) => {
|
|
109
247
|
if (settled) return;
|
|
110
248
|
settled = true;
|
|
111
|
-
|
|
249
|
+
cleanup();
|
|
250
|
+
if (error !== undefined) {
|
|
251
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
252
|
+
try { child.kill(); } catch { /* best-effort failed-start cleanup */ }
|
|
253
|
+
}
|
|
254
|
+
try { child.unref(); } catch { /* best-effort */ }
|
|
255
|
+
reject(error);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
child.unref();
|
|
259
|
+
resolve();
|
|
112
260
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
child.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
261
|
+
const onError = (err: Error) => { finish(err); };
|
|
262
|
+
const onExit = () => { finish(handoffError("child_exit")); };
|
|
263
|
+
const onSpawn = () => {
|
|
264
|
+
if (!waitForHealthBeforeParentExit) {
|
|
265
|
+
// A deadline may have been caused by native-main ownership cleanup.
|
|
266
|
+
// Let the ordinary child survive parent exit, which releases those OS locks.
|
|
267
|
+
finish();
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
void waitForReplacementReady(child.pid, process.pid, expectedPort).then(
|
|
271
|
+
ready => {
|
|
272
|
+
if (!ready) {
|
|
273
|
+
console.warn(
|
|
274
|
+
"Drain-and-restart replacement is still alive after the readiness window; allowing it to continue after parent exit",
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
// Never kill a live ordinary start at its valid reclaim boundary. Parent
|
|
278
|
+
// exit is the final resource release the child may still be waiting for.
|
|
279
|
+
finish();
|
|
280
|
+
},
|
|
281
|
+
err => finish(err),
|
|
282
|
+
);
|
|
283
|
+
};
|
|
284
|
+
child.once("error", onError);
|
|
285
|
+
child.once("exit", onExit);
|
|
286
|
+
child.once("spawn", onSpawn);
|
|
122
287
|
});
|
|
123
288
|
}
|
|
124
289
|
|
|
290
|
+
async function completeDeferredParentExitHandoff(
|
|
291
|
+
io: SystemRestartIo,
|
|
292
|
+
exitProcess: (code: number) => void,
|
|
293
|
+
port: number | undefined,
|
|
294
|
+
phase: "deadline" | "listener-stop fallback",
|
|
295
|
+
): Promise<void> {
|
|
296
|
+
try {
|
|
297
|
+
await (io.spawnStart ?? spawnDetachedStart)(port, false);
|
|
298
|
+
} catch (err) {
|
|
299
|
+
console.warn(
|
|
300
|
+
`Drain-and-restart ${phase} spawn failed (${spawnFailureCode(err)}); exiting without replacement`,
|
|
301
|
+
);
|
|
302
|
+
delete process.env.OCX_SERVICE;
|
|
303
|
+
exitProcess(1);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
(io.markRecycling ?? markRecyclingForExit)();
|
|
307
|
+
exitProcess(0);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async function completeDeadlineRestartHandoff(
|
|
311
|
+
io: SystemRestartIo,
|
|
312
|
+
exitProcess: (code: number) => void,
|
|
313
|
+
port: number | undefined,
|
|
314
|
+
scheduleDeadline: NonNullable<SystemRestartIo["scheduleDeadline"]>,
|
|
315
|
+
): Promise<void> {
|
|
316
|
+
const supervised = (io.isSupervisedServiceChild ?? (() => isSupervisedServiceChild(io)))();
|
|
317
|
+
if (supervised) {
|
|
318
|
+
// Failure-only supervisors ignore exit(0); intentional non-zero triggers respawn.
|
|
319
|
+
exitProcess(1);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const stopPromise = Promise.resolve().then(
|
|
324
|
+
() => (io.stopListener ?? (() => stopServerListener()))(),
|
|
325
|
+
);
|
|
326
|
+
const stopOutcome = await waitForBoundedSettlement(
|
|
327
|
+
stopPromise,
|
|
328
|
+
DEADLINE_LISTENER_STOP_TIMEOUT_MS,
|
|
329
|
+
scheduleDeadline,
|
|
330
|
+
);
|
|
331
|
+
if (stopOutcome === "rejected") {
|
|
332
|
+
console.warn("Drain-and-restart deadline listener stop failed; continuing parent-exit handoff");
|
|
333
|
+
} else if (stopOutcome === "deadline") {
|
|
334
|
+
console.warn("Drain-and-restart deadline listener stop timed out; continuing parent-exit handoff");
|
|
335
|
+
}
|
|
336
|
+
// The ordinary child must survive parent exit: a failed/pending socket close
|
|
337
|
+
// or overdue cleanup is completed by process teardown, without a hidden mode.
|
|
338
|
+
await completeDeferredParentExitHandoff(io, exitProcess, port, "deadline");
|
|
339
|
+
}
|
|
340
|
+
|
|
125
341
|
/**
|
|
126
342
|
* Accept a drain-and-restart request. Returns immediately; the drain +
|
|
127
343
|
* respawn runs on a short timer so the HTTP response can flush first.
|
|
@@ -133,34 +349,74 @@ export function acceptSystemRestart(io: SystemRestartIo = restartIo): {
|
|
|
133
349
|
activeTurnCount: number;
|
|
134
350
|
drainTimeoutMs: number;
|
|
135
351
|
} {
|
|
136
|
-
const
|
|
352
|
+
const shutdownActive = io.isShutdownDraining
|
|
353
|
+
?? io.isDraining
|
|
354
|
+
?? isShutdownDraining;
|
|
355
|
+
const alreadyDraining = restartAccepted || shutdownActive();
|
|
137
356
|
const activeTurnCount = (io.getActiveTurnCount ?? getActiveTurnCount)();
|
|
138
357
|
const schedule = io.schedule ?? ((fn, ms) => { setTimeout(() => { void fn(); }, ms); });
|
|
139
358
|
|
|
140
359
|
if (!alreadyDraining) {
|
|
141
360
|
restartAccepted = true;
|
|
361
|
+
const now = io.now ?? Date.now;
|
|
362
|
+
const restartDeadlineMs = now() + MEMORY_DRAIN_RESTART_MS;
|
|
142
363
|
// Reject new data-plane traffic immediately (503), before the 200ms response-flush delay.
|
|
143
|
-
(io.
|
|
364
|
+
if (io.beginShutdownDrain) io.beginShutdownDrain();
|
|
365
|
+
else if (io.setDraining) io.setDraining(true);
|
|
366
|
+
else beginShutdownDrain();
|
|
144
367
|
schedule(async () => {
|
|
368
|
+
// Preserve the live binding before drainAndShutdown (or its deadline race)
|
|
369
|
+
// closes the listener and makes both the server ref and runtime metadata stale.
|
|
370
|
+
const restartPort = (io.listenPort ?? resolveListenPort)();
|
|
145
371
|
const drain = io.drainAndShutdown ?? drainAndShutdown;
|
|
146
|
-
|
|
372
|
+
const remainingMs = Math.max(0, restartDeadlineMs - now());
|
|
373
|
+
const drainPromise = Promise.resolve().then(() => drain(undefined, remainingMs));
|
|
374
|
+
const scheduleDeadline = io.scheduleDeadline ?? ((fn, ms) => {
|
|
375
|
+
const timer = setTimeout(fn, ms);
|
|
376
|
+
return () => clearTimeout(timer);
|
|
377
|
+
});
|
|
378
|
+
const drainOutcome = await waitForRestartDrain(drainPromise, restartDeadlineMs, now, scheduleDeadline);
|
|
379
|
+
const exitProcess = io.exitProcess ?? ((code: number) => { process.exit(code); });
|
|
380
|
+
if (drainOutcome === "deadline") {
|
|
381
|
+
console.warn("Drain-and-restart deadline expired; forcing terminal restart handoff");
|
|
382
|
+
await completeDeadlineRestartHandoff(io, exitProcess, restartPort, scheduleDeadline);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (drainOutcome === "rejected") {
|
|
386
|
+
// drainAndShutdown stops the listener in finally. Even if ancillary cleanup
|
|
387
|
+
// rejects, an accepted restart must still reach replacement or terminal exit.
|
|
388
|
+
console.warn("Drain-and-restart cleanup failed; continuing terminal restart handoff");
|
|
389
|
+
}
|
|
147
390
|
const supervised = (io.isSupervisedServiceChild ?? (() => isSupervisedServiceChild(io)))();
|
|
148
391
|
if (supervised) {
|
|
149
392
|
// Failure-only supervisors ignore exit(0); intentional non-zero triggers respawn.
|
|
150
393
|
(io.exitProcess ?? ((code: number) => { process.exit(code); }))(1);
|
|
151
394
|
return;
|
|
152
395
|
}
|
|
153
|
-
const port = (io.listenPort ?? resolveListenPort)();
|
|
154
|
-
const exitProcess = io.exitProcess ?? ((code: number) => { process.exit(code); });
|
|
155
396
|
try {
|
|
156
|
-
await (io.
|
|
397
|
+
await (io.stopListener ?? (() => stopServerListener()))();
|
|
398
|
+
} catch {
|
|
399
|
+
console.warn("Drain-and-restart listener stop failed; continuing parent-exit handoff");
|
|
400
|
+
await completeDeferredParentExitHandoff(
|
|
401
|
+
io,
|
|
402
|
+
exitProcess,
|
|
403
|
+
restartPort,
|
|
404
|
+
"listener-stop fallback",
|
|
405
|
+
);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
try {
|
|
409
|
+
// A rejected drain has uncertain cleanup ownership, so it uses the same
|
|
410
|
+
// parent-exit handoff as a deadline. Only a fully completed drain waits
|
|
411
|
+
// for replacement health in the old process.
|
|
412
|
+
await (io.spawnStart ?? spawnDetachedStart)(restartPort, drainOutcome === "completed");
|
|
157
413
|
} catch (err) {
|
|
158
414
|
console.warn(
|
|
159
415
|
`⚠️ Drain-and-restart spawn failed (${spawnFailureCode(err)}); exiting without replacement`,
|
|
160
416
|
);
|
|
161
417
|
// Listen socket is already stopped; do not markRecycling — no child to inherit fences.
|
|
162
|
-
//
|
|
163
|
-
//
|
|
418
|
+
// No replacement inherited the routing. Clear a stale service marker so
|
|
419
|
+
// this unsupervised parent restores clients after the failed handoff.
|
|
164
420
|
delete process.env.OCX_SERVICE;
|
|
165
421
|
exitProcess(1);
|
|
166
422
|
return;
|
|
@@ -22,12 +22,26 @@
|
|
|
22
22
|
* dashboard drain-and-restart confirm UX — never request bodies or IDs.
|
|
23
23
|
*/
|
|
24
24
|
import { selectEagerPath } from "../../lib/bun-stream-caps";
|
|
25
|
+
import { reportedBunRuntimeSource } from "../../lib/bun-runtime";
|
|
25
26
|
import { getActiveTurnCount, isDraining } from "../lifecycle";
|
|
26
27
|
import { getActiveMemoryWatchdog, observedMemoryCounter } from "../memory-watchdog";
|
|
27
28
|
import { responseStateMetrics } from "../../responses/state";
|
|
28
29
|
import { appOwnedBytesSnapshot } from "../../lib/app-owned-memory";
|
|
30
|
+
import { readWindowsReplaceRetryCounters } from "../../lib/windows-atomic-replace";
|
|
31
|
+
import {
|
|
32
|
+
SYSTEM_RESTART_EXPECTED_PID_HEADER,
|
|
33
|
+
parseExpectedSystemRestartPid,
|
|
34
|
+
} from "../../lib/system-restart-contract";
|
|
35
|
+
import {
|
|
36
|
+
CODEX_APP_SERVER_STATE_PATH,
|
|
37
|
+
CODEX_RESTART_PATH,
|
|
38
|
+
} from "../../lib/codex-restart-contract";
|
|
29
39
|
import { jsonResponse } from "../auth-cors";
|
|
30
40
|
import { getInspectionCounters } from "../relay";
|
|
41
|
+
import type {
|
|
42
|
+
performCodexRestart,
|
|
43
|
+
readCodexAppServerState,
|
|
44
|
+
} from "../../codex/app-server-restart-service";
|
|
31
45
|
import type { ManagementContext } from "./context";
|
|
32
46
|
import { acceptSystemRestart } from "./system-restart";
|
|
33
47
|
|
|
@@ -78,6 +92,9 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
|
|
|
78
92
|
pid: process.pid,
|
|
79
93
|
bunVersion: Bun.version,
|
|
80
94
|
bunRevision: Bun.revision,
|
|
95
|
+
// Recorded at launch, not resolved now: absent means "this service predates the
|
|
96
|
+
// marker", which callers must report as unknown rather than guess.
|
|
97
|
+
bunRuntimeSource: reportedBunRuntimeSource(),
|
|
81
98
|
platform: process.platform,
|
|
82
99
|
uptimeSeconds: process.uptime(),
|
|
83
100
|
rss: usage.rss,
|
|
@@ -99,7 +116,37 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
|
|
|
99
116
|
});
|
|
100
117
|
}
|
|
101
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Windows atomic-replace retry counters.
|
|
121
|
+
*
|
|
122
|
+
* A sibling route rather than a field on /api/system/memory: that payload is
|
|
123
|
+
* memory-shaped, and appending unrelated filesystem counters to it makes both
|
|
124
|
+
* harder to consume.
|
|
125
|
+
*
|
|
126
|
+
* Keys are `publisher:CODE` where publisher is a closed union
|
|
127
|
+
* (ReplacePublisher) and never a path — a path could carry a username. The
|
|
128
|
+
* type is what enforces that; a text scan cannot see a runtime value.
|
|
129
|
+
*/
|
|
130
|
+
if (url.pathname === "/api/system/windows-replace-retries" && req.method === "GET") {
|
|
131
|
+
return jsonResponse({ counters: readWindowsReplaceRetryCounters() });
|
|
132
|
+
}
|
|
102
133
|
if (url.pathname === "/api/system/restart" && req.method === "POST") {
|
|
134
|
+
const expectedPid = parseExpectedSystemRestartPid(
|
|
135
|
+
req.headers.get(SYSTEM_RESTART_EXPECTED_PID_HEADER),
|
|
136
|
+
);
|
|
137
|
+
if (expectedPid.kind === "invalid") {
|
|
138
|
+
return jsonResponse({
|
|
139
|
+
success: false,
|
|
140
|
+
error: "Invalid restart target identity.",
|
|
141
|
+
}, 400, req, config);
|
|
142
|
+
}
|
|
143
|
+
if (expectedPid.kind === "present" && expectedPid.pid !== process.pid) {
|
|
144
|
+
return jsonResponse({
|
|
145
|
+
success: false,
|
|
146
|
+
error: "Restart target identity changed.",
|
|
147
|
+
}, 409, req, config);
|
|
148
|
+
}
|
|
149
|
+
|
|
103
150
|
// Longer informed drain than /api/stop; does not tear down Codex/Grok injection.
|
|
104
151
|
const result = acceptSystemRestart();
|
|
105
152
|
return jsonResponse({
|
|
@@ -113,5 +160,35 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
|
|
|
113
160
|
}, 202, req, config);
|
|
114
161
|
}
|
|
115
162
|
|
|
163
|
+
if (
|
|
164
|
+
(url.pathname === CODEX_APP_SERVER_STATE_PATH && req.method === "GET")
|
|
165
|
+
|| (url.pathname === CODEX_RESTART_PATH && req.method === "POST")
|
|
166
|
+
) {
|
|
167
|
+
// Resolved inside the path check, not at the top of this function: every
|
|
168
|
+
// /api/system/* request runs through here, and an unconditional import would
|
|
169
|
+
// pull the platform process-enumeration helpers into requests that never
|
|
170
|
+
// touch them.
|
|
171
|
+
// An explicit branch rather than `??`: the seam is an optional property, and
|
|
172
|
+
// narrowing through a nullish default keeps its `undefined` in the union.
|
|
173
|
+
let service: {
|
|
174
|
+
readState: typeof readCodexAppServerState;
|
|
175
|
+
performRestart: typeof performCodexRestart;
|
|
176
|
+
};
|
|
177
|
+
const injected = ctx.deps.codexRestartService;
|
|
178
|
+
if (injected) {
|
|
179
|
+
service = injected;
|
|
180
|
+
} else {
|
|
181
|
+
const module = await import("../../codex/app-server-restart-service");
|
|
182
|
+
service = {
|
|
183
|
+
readState: module.readCodexAppServerState,
|
|
184
|
+
performRestart: module.performCodexRestart,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (req.method === "GET") {
|
|
188
|
+
return jsonResponse(service.readState(), 200, req, config);
|
|
189
|
+
}
|
|
190
|
+
return jsonResponse(await service.performRestart(), 200, req, config);
|
|
191
|
+
}
|
|
192
|
+
|
|
116
193
|
return null;
|
|
117
194
|
}
|
|
@@ -8,9 +8,17 @@ export type CachedUsageSummary = UsageSummary & {
|
|
|
8
8
|
entriesDropped: number;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
interface UsageSummaryCacheEntry {
|
|
11
|
+
export interface UsageSummaryCacheEntry {
|
|
12
12
|
revisionKey: string;
|
|
13
|
+
/** path/dev/ino/birthtime only; appends keep this stable. */
|
|
14
|
+
identityKey: string;
|
|
15
|
+
maxReadBytes: number;
|
|
16
|
+
/** userCostOverlayVersion() when the summary was computed; overlay edits invalidate the entry. */
|
|
17
|
+
overlayVersion: number;
|
|
13
18
|
expiresAt: number;
|
|
19
|
+
/** Generation freshness: ignore size/mtime until this instant. */
|
|
20
|
+
freshUntil: number;
|
|
21
|
+
lastSeenSize: number;
|
|
14
22
|
summary: CachedUsageSummary;
|
|
15
23
|
revisionReadAt: number;
|
|
16
24
|
sizeBytes: number;
|