@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,146 @@
|
|
|
1
|
+
import { readRuntimePort } from "../config/process-state";
|
|
2
|
+
import {
|
|
3
|
+
LOCAL_ATTESTATION_CHALLENGE_HEADER,
|
|
4
|
+
LOCAL_ATTESTATION_PROOF_HEADER,
|
|
5
|
+
createLocalAttestationChallenge,
|
|
6
|
+
verifyLocalAttestationProof,
|
|
7
|
+
} from "../lib/local-management-attestation";
|
|
8
|
+
import {
|
|
9
|
+
SYSTEM_RESTART_CAPABILITY_HEADER,
|
|
10
|
+
SYSTEM_RESTART_CAPABILITY_VERSION,
|
|
11
|
+
SYSTEM_RESTART_EXPECTED_PID_HEADER,
|
|
12
|
+
SYSTEM_RESTART_METHOD,
|
|
13
|
+
SYSTEM_RESTART_NONCE_HEADER,
|
|
14
|
+
SYSTEM_RESTART_PATH,
|
|
15
|
+
createSystemRestartCapability,
|
|
16
|
+
} from "../lib/system-restart-contract";
|
|
17
|
+
import {
|
|
18
|
+
findLiveProxy,
|
|
19
|
+
isOpencodexHealthz,
|
|
20
|
+
probeHostname,
|
|
21
|
+
type HealthzIdentity,
|
|
22
|
+
type LiveProxy,
|
|
23
|
+
} from "../server/proxy-liveness";
|
|
24
|
+
import type { ProxyRestartRequestOutcome } from "./tray-proxy";
|
|
25
|
+
|
|
26
|
+
export const SYSTEM_RESTART_REQUEST_TIMEOUT_MS = 5_000;
|
|
27
|
+
export const SYSTEM_RESTART_ATTESTATION_TIMEOUT_MS = 4_000;
|
|
28
|
+
|
|
29
|
+
export interface BoundSystemRestartDeps {
|
|
30
|
+
fetchImpl?: typeof fetch;
|
|
31
|
+
readRuntime?: typeof readRuntimePort;
|
|
32
|
+
findLive?: typeof findLiveProxy;
|
|
33
|
+
createChallenge?: () => string;
|
|
34
|
+
now?: () => number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function rejected(code: string): ProxyRestartRequestOutcome {
|
|
38
|
+
return { accepted: false, uncertain: false, error: new Error(code) };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function uncertain(code: string): ProxyRestartRequestOutcome {
|
|
42
|
+
return { accepted: false, uncertain: true, error: new Error(code) };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function remaining(deadlineAt: number, now: () => number, cap: number): number {
|
|
46
|
+
return Math.max(0, Math.min(cap, deadlineAt - now()));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function sameRestartTarget(expected: LiveProxy, observed: LiveProxy | null): boolean {
|
|
50
|
+
return expected.pid !== null
|
|
51
|
+
&& observed?.source === "runtime"
|
|
52
|
+
&& observed.pid === expected.pid
|
|
53
|
+
&& observed.port === expected.port;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Send one restart request to the exact runtime proxy observed by the caller.
|
|
58
|
+
*
|
|
59
|
+
* No reusable admin credential is sent. After the listener proves possession of
|
|
60
|
+
* its per-process runtime secret, the client derives a capability bound to this
|
|
61
|
+
* method, path, PID, and port. The expected PID is repeated so a replacement that
|
|
62
|
+
* wins the port between proof and POST rejects the request.
|
|
63
|
+
*/
|
|
64
|
+
export async function requestBoundSystemRestart(
|
|
65
|
+
target: LiveProxy,
|
|
66
|
+
deadlineAt: number,
|
|
67
|
+
deps: BoundSystemRestartDeps = {},
|
|
68
|
+
): Promise<ProxyRestartRequestOutcome> {
|
|
69
|
+
if (target.source !== "runtime" || target.pid === null) return rejected("restart_target_unattested");
|
|
70
|
+
|
|
71
|
+
const now = deps.now ?? Date.now;
|
|
72
|
+
const readRuntime = deps.readRuntime ?? readRuntimePort;
|
|
73
|
+
const runtime = readRuntime(target.pid);
|
|
74
|
+
if (!runtime?.attestationSecret || runtime.pid !== target.pid || runtime.port !== target.port) {
|
|
75
|
+
return rejected("restart_target_runtime_mismatch");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const attestationBudget = remaining(deadlineAt, now, SYSTEM_RESTART_ATTESTATION_TIMEOUT_MS);
|
|
79
|
+
if (attestationBudget <= 0) return rejected("restart_deadline_expired");
|
|
80
|
+
|
|
81
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
82
|
+
const challenge = (deps.createChallenge ?? createLocalAttestationChallenge)();
|
|
83
|
+
const baseUrl = `http://${probeHostname(target.hostname)}:${target.port}`;
|
|
84
|
+
let proofResponse: Response;
|
|
85
|
+
try {
|
|
86
|
+
proofResponse = await fetchImpl(`${baseUrl}/healthz`, {
|
|
87
|
+
headers: { [LOCAL_ATTESTATION_CHALLENGE_HEADER]: challenge },
|
|
88
|
+
signal: AbortSignal.timeout(attestationBudget),
|
|
89
|
+
});
|
|
90
|
+
} catch {
|
|
91
|
+
return rejected("restart_attestation_unreachable");
|
|
92
|
+
}
|
|
93
|
+
const body = await proofResponse.json().catch(() => null) as HealthzIdentity | null;
|
|
94
|
+
const proof = proofResponse.headers.get(LOCAL_ATTESTATION_PROOF_HEADER);
|
|
95
|
+
if (
|
|
96
|
+
!proofResponse.ok
|
|
97
|
+
|| !isOpencodexHealthz(body)
|
|
98
|
+
|| body?.pid !== target.pid
|
|
99
|
+
|| !verifyLocalAttestationProof(runtime.attestationSecret, challenge, target.pid, target.port, proof)
|
|
100
|
+
) {
|
|
101
|
+
return rejected("restart_attestation_failed");
|
|
102
|
+
}
|
|
103
|
+
if (body.restartCapability !== SYSTEM_RESTART_CAPABILITY_VERSION) {
|
|
104
|
+
// A pre-update proxy accepts only the reusable management credential and cannot
|
|
105
|
+
// bind the operation to the attested PID. Refuse before POST rather than weakening
|
|
106
|
+
// the exact-process contract or replaying a stop/start transaction.
|
|
107
|
+
return rejected("restart_capability_unsupported");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let observed: LiveProxy | null;
|
|
111
|
+
try {
|
|
112
|
+
observed = await (deps.findLive ?? findLiveProxy)({ deadlineAt, nowFn: now });
|
|
113
|
+
} catch {
|
|
114
|
+
return rejected("restart_target_recheck_failed");
|
|
115
|
+
}
|
|
116
|
+
if (!sameRestartTarget(target, observed)) return rejected("restart_target_changed");
|
|
117
|
+
|
|
118
|
+
const capability = createSystemRestartCapability(
|
|
119
|
+
runtime.attestationSecret,
|
|
120
|
+
challenge,
|
|
121
|
+
SYSTEM_RESTART_METHOD,
|
|
122
|
+
SYSTEM_RESTART_PATH,
|
|
123
|
+
target.pid,
|
|
124
|
+
target.port,
|
|
125
|
+
);
|
|
126
|
+
if (!capability) return rejected("restart_capability_unavailable");
|
|
127
|
+
|
|
128
|
+
const requestBudget = remaining(deadlineAt, now, SYSTEM_RESTART_REQUEST_TIMEOUT_MS);
|
|
129
|
+
if (requestBudget <= 0) return rejected("restart_deadline_expired");
|
|
130
|
+
try {
|
|
131
|
+
const response = await fetchImpl(`${baseUrl}${SYSTEM_RESTART_PATH}`, {
|
|
132
|
+
method: SYSTEM_RESTART_METHOD,
|
|
133
|
+
headers: {
|
|
134
|
+
[SYSTEM_RESTART_EXPECTED_PID_HEADER]: String(target.pid),
|
|
135
|
+
[SYSTEM_RESTART_NONCE_HEADER]: challenge,
|
|
136
|
+
[SYSTEM_RESTART_CAPABILITY_HEADER]: capability,
|
|
137
|
+
},
|
|
138
|
+
signal: AbortSignal.timeout(requestBudget),
|
|
139
|
+
});
|
|
140
|
+
return response.ok ? { accepted: true } : rejected(`restart_request_http_${response.status}`);
|
|
141
|
+
} catch {
|
|
142
|
+
// The server may have accepted the restart before the response connection failed.
|
|
143
|
+
// The coordinator observes the original PID for replacement instead of replaying.
|
|
144
|
+
return uncertain("restart_request_outcome_unknown");
|
|
145
|
+
}
|
|
146
|
+
}
|
package/src/cli/tray-proxy.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface TrayProxyServiceState {
|
|
|
8
8
|
|
|
9
9
|
export interface TrayProxyStartIo {
|
|
10
10
|
findLive: () => Promise<TrayProxyLive | null>;
|
|
11
|
+
/** Normal Start is idempotent; restart fallback refuses a target that reappeared. */
|
|
12
|
+
existingIsSuccess?: boolean;
|
|
11
13
|
diagnoseService: () => TrayProxyServiceState;
|
|
12
14
|
startService: () => void | Promise<void>;
|
|
13
15
|
startDirect: () => void | Promise<void>;
|
|
@@ -16,10 +18,101 @@ export interface TrayProxyStartIo {
|
|
|
16
18
|
error: (message: string) => void;
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
export interface ProxyRestartLive {
|
|
22
|
+
pid: number | null;
|
|
23
|
+
port: number;
|
|
24
|
+
hostname?: string;
|
|
25
|
+
source: "runtime" | "config";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ProxyRestartRequestOutcome =
|
|
29
|
+
| { accepted: true }
|
|
30
|
+
| { accepted: false; uncertain: boolean; error?: unknown };
|
|
31
|
+
|
|
32
|
+
export type ProxyRestartResult =
|
|
33
|
+
| { ok: true; mode: "started" }
|
|
34
|
+
| { ok: true; mode: "skipped" }
|
|
35
|
+
| { ok: true; mode: "restarted"; live: ProxyRestartLive }
|
|
36
|
+
| { ok: false; phase: "start" | "identity" | "request" | "replacement"; error?: unknown };
|
|
37
|
+
|
|
38
|
+
export type ProxyRestartDiscovery =
|
|
39
|
+
| { status: "live"; live: ProxyRestartLive }
|
|
40
|
+
| { status: "absent" }
|
|
41
|
+
| { status: "uncertain"; error?: unknown };
|
|
42
|
+
|
|
43
|
+
export interface ProxyRestartDiscoveryIo {
|
|
44
|
+
findLive: () => Promise<ProxyRestartLive | null>;
|
|
45
|
+
waitBetweenChecks?: () => Promise<void>;
|
|
46
|
+
expired?: () => boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ProxyRestartIo {
|
|
50
|
+
findLive: () => Promise<ProxyRestartDiscovery>;
|
|
51
|
+
startWhenStopped: () => boolean | "skipped" | Promise<boolean | "skipped">;
|
|
52
|
+
requestInPlaceRestart: (
|
|
53
|
+
previous: ProxyRestartLive,
|
|
54
|
+
) => ProxyRestartRequestOutcome | Promise<ProxyRestartRequestOutcome>;
|
|
55
|
+
waitForReplacement: (previous: ProxyRestartLive) => Promise<ProxyRestartLive | null>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Confirm absence twice before restart is allowed to select a start-only path.
|
|
60
|
+
* A live target appearing during confirmation is uncertainty, not success: the
|
|
61
|
+
* caller must not claim it restarted a process it never asked to restart.
|
|
62
|
+
*/
|
|
63
|
+
export async function discoverStableProxyForRestart(
|
|
64
|
+
io: ProxyRestartDiscoveryIo,
|
|
65
|
+
): Promise<ProxyRestartDiscovery> {
|
|
66
|
+
let first: ProxyRestartLive | null;
|
|
67
|
+
try {
|
|
68
|
+
first = await io.findLive();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return { status: "uncertain", error };
|
|
71
|
+
}
|
|
72
|
+
if (first) return { status: "live", live: first };
|
|
73
|
+
if (io.expired?.()) {
|
|
74
|
+
return { status: "uncertain", error: new Error("restart_discovery_deadline_expired") };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await (io.waitBetweenChecks ?? (() => Bun.sleep(100)))();
|
|
78
|
+
let second: ProxyRestartLive | null;
|
|
79
|
+
try {
|
|
80
|
+
second = await io.findLive();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return { status: "uncertain", error };
|
|
83
|
+
}
|
|
84
|
+
if (second) {
|
|
85
|
+
return {
|
|
86
|
+
status: "uncertain",
|
|
87
|
+
error: new Error("restart_target_appeared_during_absence_confirmation"),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (io.expired?.()) {
|
|
91
|
+
return { status: "uncertain", error: new Error("restart_discovery_deadline_expired") };
|
|
92
|
+
}
|
|
93
|
+
return { status: "absent" };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function isProxyReplacement(
|
|
97
|
+
previous: ProxyRestartLive,
|
|
98
|
+
candidate: ProxyRestartLive | null,
|
|
99
|
+
): candidate is ProxyRestartLive & { pid: number } {
|
|
100
|
+
return previous.pid !== null
|
|
101
|
+
&& candidate?.pid !== null
|
|
102
|
+
&& candidate?.pid !== undefined
|
|
103
|
+
&& candidate.source === "runtime"
|
|
104
|
+
&& candidate.port === previous.port
|
|
105
|
+
&& candidate.pid !== previous.pid;
|
|
106
|
+
}
|
|
107
|
+
|
|
19
108
|
/** Side-effect coordinator for the tray's fixed proxy-start action. */
|
|
20
109
|
export async function runTrayProxyStart(io: TrayProxyStartIo): Promise<boolean> {
|
|
21
110
|
const live = await io.findLive();
|
|
22
111
|
if (live) {
|
|
112
|
+
if (io.existingIsSuccess === false) {
|
|
113
|
+
io.error("Proxy appeared while restart was confirming absence; no start was attempted.");
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
23
116
|
io.info(`Proxy already running on port ${live.port}.`);
|
|
24
117
|
return true;
|
|
25
118
|
}
|
|
@@ -43,10 +136,64 @@ export async function runTrayProxyStart(io: TrayProxyStartIo): Promise<boolean>
|
|
|
43
136
|
return true;
|
|
44
137
|
}
|
|
45
138
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Shared restart transaction for both `ocx restart` and the Windows tray.
|
|
141
|
+
*
|
|
142
|
+
* A live proxy restarts itself through POST /api/system/restart. That lifecycle owns
|
|
143
|
+
* drain, supervisor handoff, exact replacement identity, and managed-routing
|
|
144
|
+
* preservation. Re-implementing restart as `stop` + `start` here races a late service
|
|
145
|
+
* child and lets ordinary /api/stop restore native routing between the two halves.
|
|
146
|
+
* When no proxy is live there is nothing to recycle, so restart degrades to the
|
|
147
|
+
* caller's normal start path.
|
|
148
|
+
*/
|
|
149
|
+
export async function runProxyRestart(io: ProxyRestartIo): Promise<ProxyRestartResult> {
|
|
150
|
+
let discovery: ProxyRestartDiscovery;
|
|
151
|
+
try {
|
|
152
|
+
discovery = await io.findLive();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return { ok: false, phase: "request", error };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (discovery.status === "uncertain") {
|
|
158
|
+
return { ok: false, phase: "request", error: discovery.error };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (discovery.status === "absent") {
|
|
162
|
+
try {
|
|
163
|
+
const started = await io.startWhenStopped();
|
|
164
|
+
if (started === "skipped") return { ok: true, mode: "skipped" };
|
|
165
|
+
return started ? { ok: true, mode: "started" } : { ok: false, phase: "start" };
|
|
166
|
+
} catch (error) {
|
|
167
|
+
return { ok: false, phase: "start", error };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const previous = discovery.live;
|
|
172
|
+
|
|
173
|
+
if (previous.pid === null || previous.source !== "runtime") {
|
|
174
|
+
return { ok: false, phase: "identity" };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let request: ProxyRestartRequestOutcome;
|
|
178
|
+
try {
|
|
179
|
+
request = await io.requestInPlaceRestart(previous);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
// The request may have reached the proxy before the response connection failed.
|
|
182
|
+
// Keep observing the original identity; never replay or fall back to stop/start.
|
|
183
|
+
request = { accepted: false, uncertain: true, error };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!request.accepted && !request.uncertain) {
|
|
187
|
+
return { ok: false, phase: "request", error: request.error };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
const replacement = await io.waitForReplacement(previous);
|
|
192
|
+
if (replacement) return { ok: true, mode: "restarted", live: replacement };
|
|
193
|
+
return request.accepted
|
|
194
|
+
? { ok: false, phase: "replacement" }
|
|
195
|
+
: { ok: false, phase: "request", error: request.error };
|
|
196
|
+
} catch (error) {
|
|
197
|
+
return { ok: false, phase: "replacement", error };
|
|
198
|
+
}
|
|
52
199
|
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human rendering for `ocx usage`.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of `observe.ts` and away from the shared `summaryLines()` helper on
|
|
5
|
+
* purpose. `summaryLines()` is a generic depth-1 flattener shared with
|
|
6
|
+
* storage/memory/debug/claude-inbound/injection; it renders any array as
|
|
7
|
+
* "N item(s)", which is why every per-model and per-provider cost the server
|
|
8
|
+
* computes used to vanish before reaching the terminal. Deepening it would
|
|
9
|
+
* change five unrelated commands.
|
|
10
|
+
*
|
|
11
|
+
* Formatting follows the existing CLI house style: dynamic `padEnd` columns
|
|
12
|
+
* (as in `formatAccountTable`), plain text, no ANSI colour.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
interface CostRow {
|
|
16
|
+
provider: string;
|
|
17
|
+
model?: string;
|
|
18
|
+
requests: number;
|
|
19
|
+
totalTokens: number;
|
|
20
|
+
estimatedCostUsd?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface UsageReportInput {
|
|
24
|
+
range?: string;
|
|
25
|
+
surface?: string;
|
|
26
|
+
since?: number | null;
|
|
27
|
+
summary?: {
|
|
28
|
+
requests?: number;
|
|
29
|
+
totalTokens?: number;
|
|
30
|
+
inputTokens?: number;
|
|
31
|
+
outputTokens?: number;
|
|
32
|
+
cachedInputTokens?: number;
|
|
33
|
+
estimatedCostUsd?: number;
|
|
34
|
+
unpricedRequests?: number;
|
|
35
|
+
unmeteredRequests?: number;
|
|
36
|
+
};
|
|
37
|
+
models?: CostRow[];
|
|
38
|
+
providers?: CostRow[];
|
|
39
|
+
days?: { date: string; requests: number; totalTokens: number; estimatedCostUsd?: number }[];
|
|
40
|
+
filter?: { provider: string | null; model: string | null; matched: boolean; comboOverlap: boolean };
|
|
41
|
+
/**
|
|
42
|
+
* Per-account totals the API already returns and the CLI discarded (#2700).
|
|
43
|
+
*
|
|
44
|
+
* Withheld by the server -- sent as `[]` -- whenever a provider or model filter is active,
|
|
45
|
+
* because account rows are not provider-partitioned in a way the projection could honestly
|
|
46
|
+
* re-derive (summary.ts, reasoned around :865-872). An empty array therefore means two very
|
|
47
|
+
* different things, and the renderer must say which.
|
|
48
|
+
*/
|
|
49
|
+
accounts?: {
|
|
50
|
+
accountLogLabel: string;
|
|
51
|
+
ambiguous?: boolean;
|
|
52
|
+
requests: number;
|
|
53
|
+
totalTokens: number;
|
|
54
|
+
estimatedCostUsd?: number;
|
|
55
|
+
}[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const MAX_MODEL_ROWS = 10;
|
|
59
|
+
|
|
60
|
+
function terminalText(value: string): string {
|
|
61
|
+
return value.replace(/[\x00-\x1f\x7f-\x9f]/g, character => {
|
|
62
|
+
const code = character.charCodeAt(0);
|
|
63
|
+
return code <= 0x7f
|
|
64
|
+
? `\\x${code.toString(16).padStart(2, "0")}`
|
|
65
|
+
: `\\u${code.toString(16).padStart(4, "0")}`;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function count(value: number | undefined): string {
|
|
70
|
+
return (value ?? 0).toLocaleString("en-US");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Matches the dashboard's `~$` with four fraction digits. Estimates below a
|
|
75
|
+
* hundredth of a cent still read as a number rather than collapsing to $0.00,
|
|
76
|
+
* which matters when a single request is being inspected.
|
|
77
|
+
*/
|
|
78
|
+
function usd(value: number | undefined): string {
|
|
79
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "—";
|
|
80
|
+
return `~$${value.toFixed(4)}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function table(header: string[], rows: string[][]): string[] {
|
|
84
|
+
if (rows.length === 0) return [];
|
|
85
|
+
header = header.map(terminalText);
|
|
86
|
+
rows = rows.map(row => row.map(terminalText));
|
|
87
|
+
const widths = header.map((h, i) => Math.max(h.length, ...rows.map(r => (r[i] ?? "").length)));
|
|
88
|
+
const line = (cols: string[]): string => cols.map((c, i) => (c ?? "").padEnd(widths[i]!)).join(" ").trimEnd();
|
|
89
|
+
return [line(header), ...rows.map(line)];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function describeScope(data: UsageReportInput): string {
|
|
93
|
+
const parts = [`Usage — ${data.range ?? "?"}`];
|
|
94
|
+
if (data.surface && data.surface !== "all") parts.push(`surface=${data.surface}`);
|
|
95
|
+
if (data.filter?.provider) parts.push(`provider=${data.filter.provider}`);
|
|
96
|
+
if (data.filter?.model) parts.push(`model=${data.filter.model}`);
|
|
97
|
+
return terminalText(parts.join(", "));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function formatUsageReport(data: UsageReportInput): string[] {
|
|
101
|
+
const summary = data.summary ?? {};
|
|
102
|
+
const lines: string[] = [describeScope(data), ""];
|
|
103
|
+
|
|
104
|
+
if (data.filter && !data.filter.matched) {
|
|
105
|
+
const what = [data.filter.provider && `provider "${data.filter.provider}"`, data.filter.model && `model "${data.filter.model}"`]
|
|
106
|
+
.filter(Boolean).join(" and ");
|
|
107
|
+
lines.push(`No usage recorded for ${terminalText(what)} in this range.`);
|
|
108
|
+
lines.push("Check the spelling against `ocx usage --json`, or widen --range.");
|
|
109
|
+
return lines;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const tokenSplit = [
|
|
113
|
+
summary.inputTokens !== undefined ? `in ${count(summary.inputTokens)}` : null,
|
|
114
|
+
summary.outputTokens !== undefined ? `out ${count(summary.outputTokens)}` : null,
|
|
115
|
+
summary.cachedInputTokens ? `cached ${count(summary.cachedInputTokens)}` : null,
|
|
116
|
+
].filter(Boolean).join(" / ");
|
|
117
|
+
|
|
118
|
+
lines.push(`Requests ${count(summary.requests)}`);
|
|
119
|
+
lines.push(`Tokens ${count(summary.totalTokens)}${tokenSplit ? ` (${tokenSplit})` : ""}`);
|
|
120
|
+
lines.push(`Est. cost ${usd(summary.estimatedCostUsd)} API list-price equivalent (this range)`);
|
|
121
|
+
|
|
122
|
+
const unpriced = summary.unpricedRequests ?? 0;
|
|
123
|
+
const unmetered = summary.unmeteredRequests ?? 0;
|
|
124
|
+
if (unpriced > 0 || unmetered > 0) {
|
|
125
|
+
// Spelled out because a $0 total is ambiguous otherwise: it can mean "no
|
|
126
|
+
// spend" or "no price row matched", and those are very different answers.
|
|
127
|
+
lines.push(` ${count(unpriced)} unpriced, ${count(unmetered)} unmetered excluded from ~$`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const providers = (data.providers ?? []).filter(row => row.requests > 0);
|
|
131
|
+
if (providers.length > 0) {
|
|
132
|
+
lines.push("");
|
|
133
|
+
lines.push(...table(
|
|
134
|
+
["PROVIDER", "REQUESTS", "TOKENS", "EST. COST"],
|
|
135
|
+
providers.map(row => [row.provider, count(row.requests), count(row.totalTokens), usd(row.estimatedCostUsd)]),
|
|
136
|
+
));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Per-account spend (#2700). The two empty cases are distinguished deliberately: printing an
|
|
140
|
+
// empty table under a filter would repeat the silently-wrong-output defect this unit removes,
|
|
141
|
+
// because "what did this provider cost me per account" is the most natural way to ask and the
|
|
142
|
+
// server cannot answer it honestly.
|
|
143
|
+
const accountFilterActive = Boolean(data.filter?.provider || data.filter?.model);
|
|
144
|
+
const accounts = (data.accounts ?? []).filter(row => row.requests > 0);
|
|
145
|
+
if (accountFilterActive) {
|
|
146
|
+
lines.push("");
|
|
147
|
+
lines.push("ACCOUNT: not reported under a provider or model filter; run without filters for per-account totals.");
|
|
148
|
+
} else if (accounts.length > 0) {
|
|
149
|
+
lines.push("");
|
|
150
|
+
lines.push(...table(
|
|
151
|
+
["ACCOUNT", "REQUESTS", "TOKENS", "EST. COST"],
|
|
152
|
+
accounts.map(row => [
|
|
153
|
+
// An ambiguous row aggregates several accounts, so reading it as one account draws the
|
|
154
|
+
// wrong conclusion. Mark it rather than presenting it as a single identity.
|
|
155
|
+
row.ambiguous ? `${terminalText(row.accountLogLabel)} (ambiguous)` : terminalText(row.accountLogLabel),
|
|
156
|
+
count(row.requests),
|
|
157
|
+
count(row.totalTokens),
|
|
158
|
+
usd(row.estimatedCostUsd),
|
|
159
|
+
]),
|
|
160
|
+
));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const models = (data.models ?? []).filter(row => row.requests > 0);
|
|
164
|
+
if (models.length > 0) {
|
|
165
|
+
lines.push("");
|
|
166
|
+
const shown = models.slice(0, MAX_MODEL_ROWS);
|
|
167
|
+
lines.push(...table(
|
|
168
|
+
["MODEL", "PROVIDER", "REQUESTS", "TOKENS", "EST. COST"],
|
|
169
|
+
shown.map(row => [row.model ?? "-", row.provider, count(row.requests), count(row.totalTokens), usd(row.estimatedCostUsd)]),
|
|
170
|
+
));
|
|
171
|
+
if (models.length > shown.length) {
|
|
172
|
+
lines.push(`... ${models.length - shown.length} more (use --json)`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (data.filter?.comboOverlap) {
|
|
177
|
+
lines.push("");
|
|
178
|
+
lines.push("Some requests ran as combos, so per-model request counts can overlap. Cost does not.");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
lines.push("");
|
|
182
|
+
lines.push("Not a billing receipt. Subscription usage or provider credits may apply instead.");
|
|
183
|
+
return lines;
|
|
184
|
+
}
|