@iislee/opencodex 2.11.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { isCyberPolicyCode, isCyberPolicyMessage } from "../lib/errors";
|
|
2
|
+
|
|
3
|
+
export const MAX_CLIENT_SSE_FRAME_BYTES = 4 * 1024 * 1024;
|
|
4
|
+
|
|
5
|
+
const LF_LF = Uint8Array.of(10, 10);
|
|
6
|
+
const LF_CR_LF = Uint8Array.of(10, 13, 10);
|
|
7
|
+
const CR_LF_LF = Uint8Array.of(13, 10, 10);
|
|
8
|
+
const CR_LF_CR_LF = Uint8Array.of(13, 10, 13, 10);
|
|
9
|
+
|
|
10
|
+
export class SseFrameTooLargeError extends Error {
|
|
11
|
+
readonly maxBytes: number;
|
|
12
|
+
|
|
13
|
+
constructor(maxBytes: number) {
|
|
14
|
+
super(`upstream SSE frame exceeded ${maxBytes} bytes`);
|
|
15
|
+
this.name = "SseFrameTooLargeError";
|
|
16
|
+
this.maxBytes = maxBytes;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class SseFrameCountLimitError extends Error {
|
|
21
|
+
readonly maxFrames: number;
|
|
22
|
+
|
|
23
|
+
constructor(maxFrames: number) {
|
|
24
|
+
super(`upstream SSE chunk exceeded ${maxFrames} frame limit`);
|
|
25
|
+
this.name = "SseFrameCountLimitError";
|
|
26
|
+
this.maxFrames = maxFrames;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type BoundedSseFrame = {
|
|
31
|
+
block: Uint8Array;
|
|
32
|
+
delimiter: Uint8Array;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Classify the bytes at `index` as an SSE block delimiter.
|
|
37
|
+
*
|
|
38
|
+
* Returns the delimiter length in bytes, `0` when `index` does not start a
|
|
39
|
+
* delimiter, and `undefined` when more bytes are required to decide.
|
|
40
|
+
*/
|
|
41
|
+
function delimiterLengthAt(
|
|
42
|
+
index: number,
|
|
43
|
+
length: number,
|
|
44
|
+
byteAt: (index: number) => number,
|
|
45
|
+
): number | undefined {
|
|
46
|
+
const first = byteAt(index);
|
|
47
|
+
if (first === 10) {
|
|
48
|
+
if (index + 1 >= length) return undefined;
|
|
49
|
+
const second = byteAt(index + 1);
|
|
50
|
+
if (second === 10) return 2;
|
|
51
|
+
if (second !== 13) return 0;
|
|
52
|
+
if (index + 2 >= length) return undefined;
|
|
53
|
+
return byteAt(index + 2) === 10 ? 3 : 0;
|
|
54
|
+
}
|
|
55
|
+
if (first !== 13) return 0;
|
|
56
|
+
if (index + 1 >= length) return undefined;
|
|
57
|
+
if (byteAt(index + 1) !== 10) return 0;
|
|
58
|
+
if (index + 2 >= length) return undefined;
|
|
59
|
+
const third = byteAt(index + 2);
|
|
60
|
+
if (third === 10) return 3;
|
|
61
|
+
if (third !== 13) return 0;
|
|
62
|
+
if (index + 3 >= length) return undefined;
|
|
63
|
+
return byteAt(index + 3) === 10 ? 4 : 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function delimiterBytesAt(
|
|
67
|
+
index: number,
|
|
68
|
+
delimiterLength: number,
|
|
69
|
+
byteAt: (index: number) => number,
|
|
70
|
+
): Uint8Array {
|
|
71
|
+
if (delimiterLength === 2) return LF_LF;
|
|
72
|
+
if (delimiterLength === 4) return CR_LF_CR_LF;
|
|
73
|
+
return byteAt(index) === 10 ? LF_CR_LF : CR_LF_LF;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function copyRange(
|
|
77
|
+
start: number,
|
|
78
|
+
end: number,
|
|
79
|
+
tailLength: number,
|
|
80
|
+
previousTail: Uint8Array,
|
|
81
|
+
chunk: Uint8Array,
|
|
82
|
+
): Uint8Array {
|
|
83
|
+
const out = new Uint8Array(end - start);
|
|
84
|
+
for (let index = start; index < end; index += 1) {
|
|
85
|
+
out[index - start] = index < tailLength
|
|
86
|
+
? previousTail[index]!
|
|
87
|
+
: chunk[index - tailLength]!;
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* True when a complete SSE block already commits a Responses terminal event.
|
|
94
|
+
*
|
|
95
|
+
* Framing errors in bytes *after* such a block must not retroactively turn an
|
|
96
|
+
* already-completed/failed/incomplete model turn into a transport failure. This
|
|
97
|
+
* helper is used only on the exceptional path, so decoding/JSON parsing has no
|
|
98
|
+
* cost on ordinary framing.
|
|
99
|
+
*/
|
|
100
|
+
function isResponsesTerminalFrame(block: Uint8Array): boolean {
|
|
101
|
+
const data: string[] = [];
|
|
102
|
+
for (const line of new TextDecoder().decode(block).split(/\r?\n/)) {
|
|
103
|
+
if (!line.startsWith("data:")) continue;
|
|
104
|
+
const value = line.slice(5);
|
|
105
|
+
data.push(value.startsWith(" ") ? value.slice(1) : value);
|
|
106
|
+
}
|
|
107
|
+
if (data.length === 0) return false;
|
|
108
|
+
const payload = data.join("\n");
|
|
109
|
+
if (payload === "[DONE]") return false;
|
|
110
|
+
try {
|
|
111
|
+
const parsed = JSON.parse(payload) as {
|
|
112
|
+
type?: unknown;
|
|
113
|
+
code?: unknown;
|
|
114
|
+
message?: unknown;
|
|
115
|
+
error?: unknown;
|
|
116
|
+
last_error?: unknown;
|
|
117
|
+
response?: { error?: unknown; incomplete_details?: unknown };
|
|
118
|
+
};
|
|
119
|
+
if (parsed.type === "response.completed"
|
|
120
|
+
|| parsed.type === "response.failed"
|
|
121
|
+
|| parsed.type === "response.incomplete") return true;
|
|
122
|
+
if (parsed.type !== "error") return false;
|
|
123
|
+
// A top-level error is terminal for this boundary only when it carries the
|
|
124
|
+
// same high-confidence cyber-policy evidence used by relay.ts. Ordinary
|
|
125
|
+
// upstream errors remain transport failures and still become a bounded 502.
|
|
126
|
+
const candidates = [
|
|
127
|
+
parsed,
|
|
128
|
+
parsed.error,
|
|
129
|
+
parsed.last_error,
|
|
130
|
+
parsed.response?.error,
|
|
131
|
+
parsed.response?.incomplete_details,
|
|
132
|
+
];
|
|
133
|
+
for (const candidate of candidates) {
|
|
134
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
135
|
+
const record = candidate as { code?: unknown; message?: unknown };
|
|
136
|
+
if (isCyberPolicyCode(typeof record.code === "string" ? record.code : undefined)) return true;
|
|
137
|
+
if (typeof record.message === "string" && isCyberPolicyMessage(record.message)) return true;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
} catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Byte-bounded SSE block framer for client-facing protocol paths.
|
|
147
|
+
*
|
|
148
|
+
* The delimiter scanner works on raw bytes, so fragmented UTF-8 cannot change
|
|
149
|
+
* accounting and a hostile upstream cannot grow an unterminated JS string
|
|
150
|
+
* without limit. Candidate bytes live in one geometrically grown buffer rather
|
|
151
|
+
* than one allocation per upstream chunk, bounding both bytes and object count.
|
|
152
|
+
* Complete blocks are returned without their delimiter; the exact delimiter
|
|
153
|
+
* bytes are returned separately so callers can relay bytes unchanged.
|
|
154
|
+
*/
|
|
155
|
+
export class BoundedSseFrameBuffer {
|
|
156
|
+
private readonly maxFrameBytes: number;
|
|
157
|
+
private readonly maxFramesPerFeed: number;
|
|
158
|
+
private delimiterTail: Uint8Array = new Uint8Array(0);
|
|
159
|
+
private candidate: Uint8Array = new Uint8Array(0);
|
|
160
|
+
private candidateBytes = 0;
|
|
161
|
+
private disposed = false;
|
|
162
|
+
|
|
163
|
+
constructor(maxFrameBytes = MAX_CLIENT_SSE_FRAME_BYTES) {
|
|
164
|
+
if (!Number.isSafeInteger(maxFrameBytes) || maxFrameBytes <= 0) {
|
|
165
|
+
throw new RangeError("maxFrameBytes must be a positive safe integer");
|
|
166
|
+
}
|
|
167
|
+
this.maxFrameBytes = maxFrameBytes;
|
|
168
|
+
// Delimiter-only input otherwise creates an object-amplification path that
|
|
169
|
+
// is independent of candidate bytes. Keep frame count proportional to the
|
|
170
|
+
// configured byte budget while leaving ample room for real Responses events.
|
|
171
|
+
this.maxFramesPerFeed = Math.max(1, Math.ceil(maxFrameBytes / 1024));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private clear(): void {
|
|
175
|
+
this.delimiterTail = new Uint8Array(0);
|
|
176
|
+
this.candidate = new Uint8Array(0);
|
|
177
|
+
this.candidateBytes = 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private ensureCapacity(requiredBytes: number): void {
|
|
181
|
+
if (this.candidate.byteLength >= requiredBytes) return;
|
|
182
|
+
if (requiredBytes > this.maxFrameBytes) {
|
|
183
|
+
throw new SseFrameTooLargeError(this.maxFrameBytes);
|
|
184
|
+
}
|
|
185
|
+
let capacity = this.candidate.byteLength === 0
|
|
186
|
+
? Math.min(this.maxFrameBytes, Math.max(requiredBytes, 4096))
|
|
187
|
+
: this.candidate.byteLength;
|
|
188
|
+
while (capacity < requiredBytes) {
|
|
189
|
+
capacity = Math.min(this.maxFrameBytes, Math.max(requiredBytes, capacity * 2));
|
|
190
|
+
}
|
|
191
|
+
const grown = new Uint8Array(capacity);
|
|
192
|
+
if (this.candidateBytes > 0) {
|
|
193
|
+
grown.set(this.candidate.subarray(0, this.candidateBytes));
|
|
194
|
+
}
|
|
195
|
+
this.candidate = grown;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private retain(slice: Uint8Array): void {
|
|
199
|
+
if (slice.byteLength === 0) return;
|
|
200
|
+
const nextBytes = this.candidateBytes + slice.byteLength;
|
|
201
|
+
if (nextBytes > this.maxFrameBytes) {
|
|
202
|
+
this.clear();
|
|
203
|
+
this.disposed = true;
|
|
204
|
+
throw new SseFrameTooLargeError(this.maxFrameBytes);
|
|
205
|
+
}
|
|
206
|
+
this.ensureCapacity(nextBytes);
|
|
207
|
+
this.candidate.set(slice, this.candidateBytes);
|
|
208
|
+
this.candidateBytes = nextBytes;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private takeCandidate(): Uint8Array {
|
|
212
|
+
if (this.candidateBytes === 0) return new Uint8Array(0);
|
|
213
|
+
const block = this.candidate.slice(0, this.candidateBytes);
|
|
214
|
+
// Release the working allocation after each complete frame. This avoids
|
|
215
|
+
// retaining a rare multi-MiB frame allocation for the rest of a long-lived
|
|
216
|
+
// stream; normal small-frame allocation remains bounded by feed's frame cap.
|
|
217
|
+
this.candidate = new Uint8Array(0);
|
|
218
|
+
this.candidateBytes = 0;
|
|
219
|
+
return block;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
feed(chunk: Uint8Array): BoundedSseFrame[] {
|
|
223
|
+
if (this.disposed) return [];
|
|
224
|
+
if (chunk.byteLength === 0) return [];
|
|
225
|
+
|
|
226
|
+
const frames: BoundedSseFrame[] = [];
|
|
227
|
+
const previousTail = this.delimiterTail;
|
|
228
|
+
this.delimiterTail = new Uint8Array(0);
|
|
229
|
+
const tailLength = previousTail.byteLength;
|
|
230
|
+
const totalLength = tailLength + chunk.byteLength;
|
|
231
|
+
const byteAt = (index: number): number => index < tailLength
|
|
232
|
+
? previousTail[index]!
|
|
233
|
+
: chunk[index - tailLength]!;
|
|
234
|
+
const retainRange = (start: number, end: number): void => {
|
|
235
|
+
if (end <= start) return;
|
|
236
|
+
if (start < tailLength) {
|
|
237
|
+
this.retain(previousTail.subarray(start, Math.min(end, tailLength)));
|
|
238
|
+
}
|
|
239
|
+
if (end > tailLength) {
|
|
240
|
+
this.retain(chunk.subarray(Math.max(0, start - tailLength), end - tailLength));
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
let index = 0;
|
|
246
|
+
let retainedThrough = 0;
|
|
247
|
+
while (index < totalLength) {
|
|
248
|
+
const delimiterLength = delimiterLengthAt(index, totalLength, byteAt);
|
|
249
|
+
if (delimiterLength === undefined) break;
|
|
250
|
+
if (delimiterLength > 0) {
|
|
251
|
+
if (frames.length >= this.maxFramesPerFeed) {
|
|
252
|
+
this.clear();
|
|
253
|
+
this.disposed = true;
|
|
254
|
+
throw new SseFrameCountLimitError(this.maxFramesPerFeed);
|
|
255
|
+
}
|
|
256
|
+
retainRange(retainedThrough, index);
|
|
257
|
+
const block = this.takeCandidate();
|
|
258
|
+
const delimiter = delimiterBytesAt(index, delimiterLength, byteAt);
|
|
259
|
+
frames.push({ block, delimiter });
|
|
260
|
+
index += delimiterLength;
|
|
261
|
+
retainedThrough = index;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
index += 1;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
retainRange(retainedThrough, index);
|
|
268
|
+
if (index < totalLength) {
|
|
269
|
+
this.delimiterTail = copyRange(index, totalLength, tailLength, previousTail, chunk);
|
|
270
|
+
}
|
|
271
|
+
return frames;
|
|
272
|
+
} catch (err) {
|
|
273
|
+
const framingError = err instanceof SseFrameTooLargeError
|
|
274
|
+
|| err instanceof SseFrameCountLimitError;
|
|
275
|
+
if (framingError && frames.some(frame => isResponsesTerminalFrame(frame.block))) {
|
|
276
|
+
// A terminal frame is the Responses protocol boundary. Ignore malformed
|
|
277
|
+
// or oversized bytes that occur later in the same upstream chunk rather
|
|
278
|
+
// than retroactively replacing the committed terminal with a 502.
|
|
279
|
+
this.clear();
|
|
280
|
+
this.disposed = true;
|
|
281
|
+
return frames;
|
|
282
|
+
}
|
|
283
|
+
throw err;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** Return the final unterminated block bytes and release all retained state. */
|
|
288
|
+
finish(): Uint8Array {
|
|
289
|
+
if (this.disposed) return new Uint8Array(0);
|
|
290
|
+
try {
|
|
291
|
+
this.retain(this.delimiterTail);
|
|
292
|
+
this.delimiterTail = new Uint8Array(0);
|
|
293
|
+
return this.takeCandidate();
|
|
294
|
+
} finally {
|
|
295
|
+
this.clear();
|
|
296
|
+
this.disposed = true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
dispose(): void {
|
|
301
|
+
if (this.disposed) return;
|
|
302
|
+
this.clear();
|
|
303
|
+
this.disposed = true;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export function joinSseFrameBytes(parts: readonly Uint8Array[]): Uint8Array {
|
|
308
|
+
let byteLength = 0;
|
|
309
|
+
for (const part of parts) byteLength += part.byteLength;
|
|
310
|
+
if (byteLength === 0) return new Uint8Array(0);
|
|
311
|
+
if (parts.length === 1 && parts[0]!.byteLength === byteLength) return parts[0]!;
|
|
312
|
+
const joined = new Uint8Array(byteLength);
|
|
313
|
+
let offset = 0;
|
|
314
|
+
for (const part of parts) {
|
|
315
|
+
joined.set(part, offset);
|
|
316
|
+
offset += part.byteLength;
|
|
317
|
+
}
|
|
318
|
+
return joined;
|
|
319
|
+
}
|
|
@@ -9,6 +9,56 @@ import type { TranslatorBudget } from "../lib/translator-budget";
|
|
|
9
9
|
|
|
10
10
|
export type SsePayloadRewrite = (payload: string) => string;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Block-level SSE rewrite: maps one complete SSE event block (without its
|
|
14
|
+
* blank-line delimiter) to zero or more replacement blocks. This is the
|
|
15
|
+
* contract lifecycle repair needs: injecting missing canonical events
|
|
16
|
+
* (#893) is impossible in the one-payload-in/one-payload-out model.
|
|
17
|
+
*
|
|
18
|
+
* `dispose` releases any retained state (budget-charged collectors) when the
|
|
19
|
+
* relay tears down — terminal, EOF, cancel, or error. Relays call it exactly
|
|
20
|
+
* once per teardown path.
|
|
21
|
+
*/
|
|
22
|
+
export type SseBlockRewrite = ((block: string) => readonly string[]) & {
|
|
23
|
+
dispose?: () => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Adapt a payload rewrite to the block contract (replace only on change). */
|
|
27
|
+
export function payloadRewriteAsBlockRewrite(rewrite: SsePayloadRewrite): SseBlockRewrite {
|
|
28
|
+
return (block) => {
|
|
29
|
+
const payload = sseDataPayload(block);
|
|
30
|
+
if (payload === null) return [block];
|
|
31
|
+
const rewritten = rewrite(payload);
|
|
32
|
+
return rewritten !== payload ? [replaceSseDataPayload(block, rewritten)] : [block];
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Chain block rewrites: every block stage N emits feeds stage N+1. */
|
|
37
|
+
export function composeSseBlockRewrites(...rewrites: SseBlockRewrite[]): SseBlockRewrite {
|
|
38
|
+
const active = rewrites.filter(Boolean);
|
|
39
|
+
if (active.length === 0) return Object.assign((block: string) => [block], {});
|
|
40
|
+
const composed: SseBlockRewrite = (block: string) => {
|
|
41
|
+
let blocks: readonly string[] = [block];
|
|
42
|
+
for (const rewrite of active) {
|
|
43
|
+
const next: string[] = [];
|
|
44
|
+
for (const current of blocks) next.push(...rewrite(current));
|
|
45
|
+
blocks = next;
|
|
46
|
+
}
|
|
47
|
+
return blocks;
|
|
48
|
+
};
|
|
49
|
+
// Child disposal is part of the contract: one idempotent disposer for the
|
|
50
|
+
// whole chain, so relay teardown never leaks a nested collector.
|
|
51
|
+
let disposed = false;
|
|
52
|
+
composed.dispose = () => {
|
|
53
|
+
if (disposed) return;
|
|
54
|
+
disposed = true;
|
|
55
|
+
for (const rewrite of active) {
|
|
56
|
+
try { rewrite.dispose?.(); } catch { /* teardown must not throw */ }
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return composed;
|
|
60
|
+
}
|
|
61
|
+
|
|
12
62
|
/** Split one complete SSE event block while retaining its original blank-line delimiter. */
|
|
13
63
|
export function nextSseBlock(buffer: string): { block: string; delimiter: string; rest: string } | null {
|
|
14
64
|
const match = buffer.match(/\r?\n\r?\n/);
|
|
@@ -69,12 +119,34 @@ export function relaySseWithPayloadRewrite(
|
|
|
69
119
|
body: ReadableStream<Uint8Array>,
|
|
70
120
|
rewrite: SsePayloadRewrite,
|
|
71
121
|
translatorBudget: TranslatorBudget,
|
|
122
|
+
): ReadableStream<Uint8Array> {
|
|
123
|
+
return relaySseWithBlockRewrite(body, payloadRewriteAsBlockRewrite(rewrite), translatorBudget);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Relay an SSE body through a single JS pull wrapper, applying a block-level
|
|
128
|
+
* rewrite that may emit zero or more blocks per upstream event (lifecycle
|
|
129
|
+
* event injection, #893). The original stream's delimiter style is preserved
|
|
130
|
+
* for every emitted block.
|
|
131
|
+
*/
|
|
132
|
+
export function relaySseWithBlockRewrite(
|
|
133
|
+
body: ReadableStream<Uint8Array>,
|
|
134
|
+
rewrite: SseBlockRewrite,
|
|
135
|
+
translatorBudget: TranslatorBudget,
|
|
72
136
|
): ReadableStream<Uint8Array> {
|
|
73
137
|
const reader = body.getReader();
|
|
74
138
|
const decoder = new TextDecoder();
|
|
75
139
|
const encoder = new TextEncoder();
|
|
76
140
|
let buffer = "";
|
|
77
141
|
let bufferBytes = 0;
|
|
142
|
+
// Relays have several independent teardown paths; disposal is exactly once.
|
|
143
|
+
let disposed = false;
|
|
144
|
+
let cancelled = false;
|
|
145
|
+
const disposeRewrite = (): void => {
|
|
146
|
+
if (disposed) return;
|
|
147
|
+
disposed = true;
|
|
148
|
+
try { rewrite.dispose?.(); } catch { /* teardown must not throw */ }
|
|
149
|
+
};
|
|
78
150
|
|
|
79
151
|
const appendBuffer = (fragment: string): void => {
|
|
80
152
|
if (!fragment) return;
|
|
@@ -126,49 +198,65 @@ export function relaySseWithPayloadRewrite(
|
|
|
126
198
|
const emitProcessedBlocks = (
|
|
127
199
|
controller: ReadableStreamDefaultController<Uint8Array>,
|
|
128
200
|
flushFinal = false,
|
|
129
|
-
):
|
|
201
|
+
): number => {
|
|
202
|
+
let emitted = 0;
|
|
130
203
|
let next: { block: string; delimiter: string; rest: string } | null;
|
|
131
204
|
while ((next = nextSseBlock(buffer))) {
|
|
132
205
|
replaceBuffer(next.rest);
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
: next.block;
|
|
138
|
-
enqueueText(controller, block + next.delimiter);
|
|
206
|
+
for (const outBlock of rewrite(next.block)) {
|
|
207
|
+
enqueueText(controller, outBlock + next.delimiter);
|
|
208
|
+
emitted += 1;
|
|
209
|
+
}
|
|
139
210
|
}
|
|
140
211
|
if (flushFinal && buffer.length > 0) {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
212
|
+
const tailBlocks = rewrite(buffer);
|
|
213
|
+
// A trailing fragment has no delimiter of its own; multiple emitted
|
|
214
|
+
// blocks must still be framed as separate events (#893 review).
|
|
215
|
+
const tailDelimiter = buffer.includes("\r\n") ? "\r\n\r\n" : "\n\n";
|
|
216
|
+
for (let i = 0; i < tailBlocks.length; i++) {
|
|
217
|
+
enqueueText(controller, tailBlocks[i]! + (i < tailBlocks.length - 1 ? tailDelimiter : ""));
|
|
218
|
+
emitted += 1;
|
|
219
|
+
}
|
|
147
220
|
releaseBuffer();
|
|
148
221
|
}
|
|
222
|
+
return emitted;
|
|
149
223
|
};
|
|
150
224
|
|
|
151
225
|
return new ReadableStream<Uint8Array>({
|
|
152
226
|
async pull(controller) {
|
|
153
227
|
try {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
228
|
+
// A network chunk is not an SSE-event boundary. Bun may not issue a
|
|
229
|
+
// second pull after a fulfilled pull enqueues nothing, so keep reading
|
|
230
|
+
// until at least one complete rewritten block is available or EOF is
|
|
231
|
+
// reached. This also handles block rewrites that intentionally drop an
|
|
232
|
+
// event without parking the client stream.
|
|
233
|
+
for (;;) {
|
|
234
|
+
const { done, value } = await reader.read();
|
|
235
|
+
// A cancel raced this pending read: never feed the rewriter again
|
|
236
|
+
// after its disposal (#893 review).
|
|
237
|
+
if (cancelled) return;
|
|
238
|
+
if (done) {
|
|
239
|
+
appendBuffer(decoder.decode());
|
|
240
|
+
emitProcessedBlocks(controller, true);
|
|
241
|
+
releaseBuffer();
|
|
242
|
+
disposeRewrite();
|
|
243
|
+
controller.close();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
appendBuffer(decoder.decode(value, { stream: true }));
|
|
247
|
+
if (emitProcessedBlocks(controller) > 0) return;
|
|
161
248
|
}
|
|
162
|
-
appendBuffer(decoder.decode(value, { stream: true }));
|
|
163
|
-
emitProcessedBlocks(controller);
|
|
164
249
|
} catch (error) {
|
|
165
250
|
releaseBuffer();
|
|
251
|
+
disposeRewrite();
|
|
166
252
|
try { await reader.cancel(error); } catch { /* already closed */ }
|
|
167
253
|
controller.error(error);
|
|
168
254
|
}
|
|
169
255
|
},
|
|
170
256
|
cancel(reason) {
|
|
257
|
+
cancelled = true;
|
|
171
258
|
releaseBuffer();
|
|
259
|
+
disposeRewrite();
|
|
172
260
|
reader.cancel(reason).catch(() => {});
|
|
173
261
|
},
|
|
174
262
|
});
|
|
@@ -164,10 +164,17 @@ function runCliInstall(
|
|
|
164
164
|
const cli = join(import.meta.dir, "..", "cli", "index.ts");
|
|
165
165
|
const argv = [cli, ...startupInstallArgv(action, options)];
|
|
166
166
|
return new Promise((resolve, reject) => {
|
|
167
|
+
const timeout = process.platform === "win32" && action === "install-service"
|
|
168
|
+
? 0
|
|
169
|
+
: 60_000;
|
|
167
170
|
execFile(bun, argv, {
|
|
168
171
|
encoding: "utf8",
|
|
169
172
|
env: process.env,
|
|
170
|
-
|
|
173
|
+
// A fresh Windows scheduler install now owns its UAC prompt inside this CLI
|
|
174
|
+
// transaction. Killing only the CLI at 60s can orphan its elevated schtasks child,
|
|
175
|
+
// which may register the task after the Dashboard has reported failure. Keep the
|
|
176
|
+
// async request/attempt lock alive until Windows returns approval or cancellation.
|
|
177
|
+
timeout,
|
|
171
178
|
windowsHide: true,
|
|
172
179
|
maxBuffer: 256 * 1024,
|
|
173
180
|
}, (error, stdout, stderr) => {
|
|
@@ -10,6 +10,7 @@ import { truncateRetainedUtf8 } from "../lib/admission";
|
|
|
10
10
|
|
|
11
11
|
const CACHE_TTL_MS = 30_000;
|
|
12
12
|
const PROBE_TIMEOUT_MS = 5_000;
|
|
13
|
+
const INITIAL_PROBE_WAIT_MS = 5_500;
|
|
13
14
|
const MAX_DIAGNOSTIC_VALUE_BYTES = 8 * 1024;
|
|
14
15
|
let cached: { timestamp: number; value: StartupHealth } | null = null;
|
|
15
16
|
let inflight: Promise<StartupHealth> | null = null;
|
|
@@ -23,9 +24,14 @@ export function markStartupHealthDiagnosticStale(value: StartupHealth): StartupH
|
|
|
23
24
|
rebootSafe: false,
|
|
24
25
|
protection: "none",
|
|
25
26
|
diagnosticStale: true,
|
|
27
|
+
// Mirror deriveStartupHealth's choice: an already-registered service is refreshed in
|
|
28
|
+
// place. Hardcoding installService here silently undid that for every stale-cache
|
|
29
|
+
// read, which is the path the dashboard hits while a probe is revalidating.
|
|
26
30
|
recommendedCommand: value.routingKind === "custom-local" || value.routingKind === "unknown"
|
|
27
31
|
? value.commands.restoreNative
|
|
28
|
-
: value.
|
|
32
|
+
: value.serviceInstalled && !value.serviceConflict
|
|
33
|
+
? value.commands.repairService
|
|
34
|
+
: value.commands.installService,
|
|
29
35
|
};
|
|
30
36
|
}
|
|
31
37
|
|
|
@@ -72,6 +78,7 @@ function runProbe(config: Pick<OcxConfig, "codexAutoStart">): Promise<StartupHea
|
|
|
72
78
|
: truncateRetainedUtf8(parsed.recommendedCommand, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
73
79
|
commands: {
|
|
74
80
|
installService: truncateRetainedUtf8(parsed.commands.installService, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
81
|
+
repairService: truncateRetainedUtf8(parsed.commands.repairService, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
75
82
|
installShim: truncateRetainedUtf8(parsed.commands.installShim, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
76
83
|
restoreNative: truncateRetainedUtf8(parsed.commands.restoreNative, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
77
84
|
},
|
|
@@ -103,6 +110,17 @@ function refreshInBackground(config: Pick<OcxConfig, "codexAutoStart">): void {
|
|
|
103
110
|
export async function getCachedStartupHealth(config: Pick<OcxConfig, "codexAutoStart">): Promise<StartupHealth> {
|
|
104
111
|
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) return cached.value;
|
|
105
112
|
refreshInBackground(config);
|
|
113
|
+
// An expired or empty read is an explicit protection check. Wait for the
|
|
114
|
+
// isolated probe instead of presenting a synthetic failure while that probe
|
|
115
|
+
// is still running. The probe remains child-process isolated and hard-capped
|
|
116
|
+
// at 5s; stale state is returned only if that bounded probe cannot settle.
|
|
117
|
+
if (inflight) {
|
|
118
|
+
const settled = await Promise.race([
|
|
119
|
+
inflight,
|
|
120
|
+
new Promise<null>(resolve => setTimeout(() => resolve(null), INITIAL_PROBE_WAIT_MS)),
|
|
121
|
+
]);
|
|
122
|
+
if (settled) return settled;
|
|
123
|
+
}
|
|
106
124
|
return cached ? markStartupHealthDiagnosticStale(cached.value) : conservativeFallback(config);
|
|
107
125
|
}
|
|
108
126
|
|