@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,223 @@
|
|
|
1
|
+
import { createPrivateKey, createPublicKey } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
closeSync,
|
|
4
|
+
constants as fsConstants,
|
|
5
|
+
fsyncSync,
|
|
6
|
+
openSync,
|
|
7
|
+
readdirSync,
|
|
8
|
+
rmSync,
|
|
9
|
+
unlinkSync,
|
|
10
|
+
} from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import {
|
|
13
|
+
ensureLabDirs,
|
|
14
|
+
labCommunityDir,
|
|
15
|
+
labExportDir,
|
|
16
|
+
labPublicOriginDir,
|
|
17
|
+
labPublicPublisherKeyPath,
|
|
18
|
+
} from "../paths";
|
|
19
|
+
import {
|
|
20
|
+
isCommunityRevocationFileName,
|
|
21
|
+
parseCommunityBundleFileName,
|
|
22
|
+
} from "./community-files";
|
|
23
|
+
import { readPrivateRegularFile } from "./file-safety";
|
|
24
|
+
import { publicEvidenceId } from "./ids";
|
|
25
|
+
import { withPublicEvidenceMutationLock } from "./mutation-lock";
|
|
26
|
+
import { clearLocalPublicOrigins } from "./origin";
|
|
27
|
+
import { recoverPublicOriginsForPurge } from "./origin-purge";
|
|
28
|
+
import { publicEvidencePurgeFaultForTests } from "./purge-test-fault";
|
|
29
|
+
import { readPublicEvidenceBundle } from "./storage";
|
|
30
|
+
import { parseStrictPublicJson } from "./strict-json";
|
|
31
|
+
import { PublicEvidenceValidationError } from "./validate";
|
|
32
|
+
|
|
33
|
+
const MAX_PRIVATE_KEY_BYTES = 8 * 1024;
|
|
34
|
+
const MAX_COMMUNITY_OBJECT_BYTES = 2 * 1024 * 1024;
|
|
35
|
+
const EXPORT_FILE_RE = /^([0-9a-f]{64})\.json$/;
|
|
36
|
+
|
|
37
|
+
function syncPurgeDirectory(dir: string, label: "export" | "community" | "origin"): void {
|
|
38
|
+
if (process.platform === "win32") return;
|
|
39
|
+
if (label === "export" && publicEvidencePurgeFaultForTests() === "export_directory_sync") {
|
|
40
|
+
throw new Error("synthetic public export directory sync failure");
|
|
41
|
+
}
|
|
42
|
+
let fd: number | null = null;
|
|
43
|
+
try {
|
|
44
|
+
fd = openSync(dir, fsConstants.O_RDONLY);
|
|
45
|
+
fsyncSync(fd);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
48
|
+
throw new Error(`public ${label} purge directory sync failed: ${detail}`);
|
|
49
|
+
} finally {
|
|
50
|
+
if (fd !== null) closeSync(fd);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Publisher provenance is useful only for classifying local community copies. A corrupt
|
|
56
|
+
* key must never block deletion of sensitive exports, so classification fails closed to
|
|
57
|
+
* "unknown publisher" while the purge continues.
|
|
58
|
+
*/
|
|
59
|
+
function readExistingPublisherKeyId(configDir?: string): string | null {
|
|
60
|
+
const path = labPublicPublisherKeyPath(configDir);
|
|
61
|
+
try {
|
|
62
|
+
const pem = readPrivateRegularFile(path, {
|
|
63
|
+
maxBytes: MAX_PRIVATE_KEY_BYTES,
|
|
64
|
+
errorCode: "public_publisher_key_unsafe",
|
|
65
|
+
errorMessage: "public publisher key is unsafe during purge",
|
|
66
|
+
requireMode600: true,
|
|
67
|
+
}).toString("utf8");
|
|
68
|
+
if (!pem.includes("BEGIN PRIVATE KEY")) return null;
|
|
69
|
+
const privateKey = createPrivateKey(pem);
|
|
70
|
+
if (privateKey.asymmetricKeyType !== "ed25519") return null;
|
|
71
|
+
const publicKey = createPublicKey(pem);
|
|
72
|
+
const publicKeyDer = publicKey.export({ type: "spki", format: "der" }).toString("base64");
|
|
73
|
+
return publicEvidenceId("publisher_key", { algorithm: "ed25519", publicKey: publicKeyDer });
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function publicIdentity(publisherKeyId: string, bundleId: string): string {
|
|
80
|
+
return `${publisherKeyId}:${bundleId}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Best-effort legacy classification only. Malformed exports are still deleted below. */
|
|
84
|
+
function localExportIdentities(configDir?: string): Set<string> {
|
|
85
|
+
const identities = new Set<string>();
|
|
86
|
+
for (const entry of readdirSync(labExportDir(configDir), { withFileTypes: true })) {
|
|
87
|
+
const match = EXPORT_FILE_RE.exec(entry.name);
|
|
88
|
+
if (!match) continue;
|
|
89
|
+
try {
|
|
90
|
+
const bundle = readPublicEvidenceBundle(match[1]!, configDir);
|
|
91
|
+
identities.add(publicIdentity(bundle.publisher.keyId, bundle.bundleId));
|
|
92
|
+
} catch {
|
|
93
|
+
// Durable origin markers are the primary provenance source. Never retain a
|
|
94
|
+
// malformed export merely because legacy recovery can no longer parse it.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return identities;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function purgeAllExports(configDir?: string): number {
|
|
101
|
+
if (publicEvidencePurgeFaultForTests() === "before_export_delete") {
|
|
102
|
+
throw new Error("synthetic public export purge failure");
|
|
103
|
+
}
|
|
104
|
+
let deleted = 0;
|
|
105
|
+
const exportDir = labExportDir(configDir);
|
|
106
|
+
for (const entry of readdirSync(exportDir, { withFileTypes: true })) {
|
|
107
|
+
rmSync(join(exportDir, entry.name), { recursive: entry.isDirectory(), force: true });
|
|
108
|
+
deleted += 1;
|
|
109
|
+
}
|
|
110
|
+
// A previous attempt may already have removed all names but failed its directory
|
|
111
|
+
// fsync. Re-sync even when this retry deletes zero entries before reporting success.
|
|
112
|
+
syncPurgeDirectory(exportDir, "export");
|
|
113
|
+
return deleted;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Provenance classification happens before this call. Purge removes only the exact
|
|
118
|
+
* community cache pathname, so a symlink or hardlink cannot redirect deletion to a peer.
|
|
119
|
+
*/
|
|
120
|
+
function unlinkLocalCommunityFile(path: string): boolean {
|
|
121
|
+
try {
|
|
122
|
+
unlinkSync(path);
|
|
123
|
+
return true;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function communityObjectPublisherKeyId(path: string): string | null {
|
|
131
|
+
try {
|
|
132
|
+
const raw = parseStrictPublicJson(
|
|
133
|
+
readPrivateRegularFile(path, {
|
|
134
|
+
maxBytes: MAX_COMMUNITY_OBJECT_BYTES,
|
|
135
|
+
errorCode: "community_unsafe_target",
|
|
136
|
+
errorMessage: "community object is unsafe during purge",
|
|
137
|
+
}),
|
|
138
|
+
"community object during purge",
|
|
139
|
+
);
|
|
140
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
141
|
+
const publisher = (raw as { publisher?: unknown }).publisher;
|
|
142
|
+
if (!publisher || typeof publisher !== "object" || Array.isArray(publisher)) return null;
|
|
143
|
+
const keyId = (publisher as { keyId?: unknown }).keyId;
|
|
144
|
+
return typeof keyId === "string" && /^[0-9a-f]{64}$/.test(keyId) ? keyId : null;
|
|
145
|
+
} catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function purgeLocalPublicEvidenceCopiesLocked(configDir?: string): {
|
|
151
|
+
deletedExports: number;
|
|
152
|
+
deletedCommunityBundles: number;
|
|
153
|
+
deletedCommunityRevocations: number;
|
|
154
|
+
} {
|
|
155
|
+
const exportedIdentities = localExportIdentities(configDir);
|
|
156
|
+
const originRecovery = recoverPublicOriginsForPurge(configDir);
|
|
157
|
+
const localPublisherKeyIds = new Set<string>();
|
|
158
|
+
for (const origin of originRecovery.identities) {
|
|
159
|
+
exportedIdentities.add(publicIdentity(origin.publisherKeyId, origin.bundleId));
|
|
160
|
+
localPublisherKeyIds.add(origin.publisherKeyId);
|
|
161
|
+
}
|
|
162
|
+
const currentPublisherKeyId = readExistingPublisherKeyId(configDir);
|
|
163
|
+
if (currentPublisherKeyId) localPublisherKeyIds.add(currentPublisherKeyId);
|
|
164
|
+
const communityDir = labCommunityDir(configDir);
|
|
165
|
+
|
|
166
|
+
// Sensitive local exports are the mandatory deletion target. Provenance is captured
|
|
167
|
+
// before this point, so cleanup remains possible even after the export bytes disappear.
|
|
168
|
+
const deletedExports = purgeAllExports(configDir);
|
|
169
|
+
|
|
170
|
+
let deletedCommunityBundles = 0;
|
|
171
|
+
let deletedCommunityRevocations = 0;
|
|
172
|
+
for (const entry of readdirSync(communityDir, { withFileTypes: true })) {
|
|
173
|
+
const bundleIdentity = parseCommunityBundleFileName(entry.name);
|
|
174
|
+
if (bundleIdentity) {
|
|
175
|
+
const { publisherKeyId, bundleId } = bundleIdentity;
|
|
176
|
+
const locallyOriginated = exportedIdentities.has(publicIdentity(publisherKeyId, bundleId))
|
|
177
|
+
|| localPublisherKeyIds.has(publisherKeyId);
|
|
178
|
+
if (locallyOriginated && unlinkLocalCommunityFile(join(communityDir, entry.name))) {
|
|
179
|
+
deletedCommunityBundles += 1;
|
|
180
|
+
}
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (isCommunityRevocationFileName(entry.name)) {
|
|
185
|
+
const path = join(communityDir, entry.name);
|
|
186
|
+
const publisherKeyId = communityObjectPublisherKeyId(path);
|
|
187
|
+
if (publisherKeyId && localPublisherKeyIds.has(publisherKeyId)
|
|
188
|
+
&& unlinkLocalCommunityFile(path)) {
|
|
189
|
+
deletedCommunityRevocations += 1;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// As with exports, a retry after a failed directory fsync may have no remaining
|
|
194
|
+
// names to unlink. Re-sync the directory unconditionally before success.
|
|
195
|
+
syncPurgeDirectory(communityDir, "community");
|
|
196
|
+
|
|
197
|
+
if (originRecovery.skipped > 0) {
|
|
198
|
+
// Preserve provenance markers for operator recovery. Sensitive exports are already
|
|
199
|
+
// durably gone, but unknown community copies cannot be reported as fully purged.
|
|
200
|
+
throw new PublicEvidenceValidationError(
|
|
201
|
+
"public_origin_incomplete",
|
|
202
|
+
`public origin classification incomplete: ${originRecovery.skipped} marker(s) could not be validated`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Markers are purge-owned public provenance only. Remove them last, then establish
|
|
207
|
+
// deletion durability before the caller may record an export purge tombstone.
|
|
208
|
+
clearLocalPublicOrigins(configDir);
|
|
209
|
+
syncPurgeDirectory(labPublicOriginDir(configDir), "origin");
|
|
210
|
+
return { deletedExports, deletedCommunityBundles, deletedCommunityRevocations };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function purgeLocalPublicEvidenceCopies(configDir?: string): {
|
|
214
|
+
deletedExports: number;
|
|
215
|
+
deletedCommunityBundles: number;
|
|
216
|
+
deletedCommunityRevocations: number;
|
|
217
|
+
} {
|
|
218
|
+
ensureLabDirs(configDir);
|
|
219
|
+
return withPublicEvidenceMutationLock(
|
|
220
|
+
configDir,
|
|
221
|
+
() => purgeLocalPublicEvidenceCopiesLocked(configDir),
|
|
222
|
+
);
|
|
223
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { publicEvidenceId } from "./ids";
|
|
2
|
+
import {
|
|
3
|
+
PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION,
|
|
4
|
+
type PublicAdapterFamily,
|
|
5
|
+
type PublicRouteRegistryEntryV1,
|
|
6
|
+
type PublicRouteRegistryManifestV1,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
// Repository-authoritative provider/model/adapter snapshot. The public manifest
|
|
10
|
+
// itself is independently content-addressed by manifestDigest below.
|
|
11
|
+
const PUBLIC_ROUTE_REGISTRY_SOURCE_COMMIT = "75a21417657ba5a3033198be0d8ae949de723d11";
|
|
12
|
+
|
|
13
|
+
const entries: PublicRouteRegistryEntryV1[] = [
|
|
14
|
+
{
|
|
15
|
+
providerId: "openai",
|
|
16
|
+
modelId: "gpt-5.6-sol",
|
|
17
|
+
adapterFamilies: ["openai-responses"],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const manifestWithoutDigest = {
|
|
22
|
+
schemaVersion: PUBLIC_ROUTE_REGISTRY_SCHEMA_VERSION,
|
|
23
|
+
registryVersion: "2026-08-13.v2",
|
|
24
|
+
sourceCommit: PUBLIC_ROUTE_REGISTRY_SOURCE_COMMIT,
|
|
25
|
+
entries,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const PUBLIC_ROUTE_REGISTRY_V1: PublicRouteRegistryManifestV1 = Object.freeze({
|
|
29
|
+
...manifestWithoutDigest,
|
|
30
|
+
entries: Object.freeze(entries.map((entry) => Object.freeze({
|
|
31
|
+
...entry,
|
|
32
|
+
adapterFamilies: Object.freeze([...entry.adapterFamilies]) as unknown as PublicAdapterFamily[],
|
|
33
|
+
}))) as unknown as PublicRouteRegistryEntryV1[],
|
|
34
|
+
manifestDigest: publicEvidenceId("route_registry", manifestWithoutDigest),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export function findPublicRouteRegistryEntry(
|
|
38
|
+
providerId: string,
|
|
39
|
+
modelId: string,
|
|
40
|
+
): PublicRouteRegistryEntryV1 | undefined {
|
|
41
|
+
return PUBLIC_ROUTE_REGISTRY_V1.entries.find(
|
|
42
|
+
(entry) => entry.providerId === providerId && entry.modelId === modelId,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { createPublicKey, verify as verifyBytes } from "node:crypto";
|
|
2
|
+
import { publicEvidenceId } from "./ids";
|
|
3
|
+
import {
|
|
4
|
+
loadExistingPublicPublisher,
|
|
5
|
+
signPublicPublisherDigest,
|
|
6
|
+
verifyPublicEvidenceBundle,
|
|
7
|
+
} from "./signature";
|
|
8
|
+
import {
|
|
9
|
+
PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION,
|
|
10
|
+
type PublicEvidenceBundleV1,
|
|
11
|
+
type PublicEvidenceRevocationV1,
|
|
12
|
+
type PublicPublisherV1,
|
|
13
|
+
type PublicRevocationReasonV1,
|
|
14
|
+
type PublicRevocationTargetV1,
|
|
15
|
+
type PublicRevocationVerificationResult,
|
|
16
|
+
} from "./types";
|
|
17
|
+
import { PublicEvidenceValidationError } from "./validate";
|
|
18
|
+
|
|
19
|
+
const REASONS = new Set<PublicRevocationReasonV1>([
|
|
20
|
+
"publisher_retracted",
|
|
21
|
+
"privacy_retraction",
|
|
22
|
+
"evidence_invalidated",
|
|
23
|
+
"superseded",
|
|
24
|
+
]);
|
|
25
|
+
const MAX_TARGETS = 256;
|
|
26
|
+
|
|
27
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
28
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function closedKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {
|
|
32
|
+
const allowed = new Set(keys);
|
|
33
|
+
return Object.keys(value).every((key) => allowed.has(key)) && keys.every((key) => key in value);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function validId(value: unknown): value is string {
|
|
37
|
+
return typeof value === "string" && /^[0-9a-f]{64}$/.test(value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function validDay(value: unknown): value is string {
|
|
41
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
|
|
42
|
+
const date = new Date(`${value}T00:00:00.000Z`);
|
|
43
|
+
return Number.isFinite(date.getTime()) && date.toISOString().slice(0, 10) === value;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function targetKey(target: PublicRevocationTargetV1): string {
|
|
47
|
+
return `${target.kind}:${target.id}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function compareCanonicalText(a: string, b: string): number {
|
|
51
|
+
if (a < b) return -1;
|
|
52
|
+
if (a > b) return 1;
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function canonicalTargets(targets: readonly PublicRevocationTargetV1[]): PublicRevocationTargetV1[] {
|
|
57
|
+
if (targets.length === 0 || targets.length > MAX_TARGETS) {
|
|
58
|
+
throw new PublicEvidenceValidationError("revocation_targets", "revocation must contain 1..256 targets");
|
|
59
|
+
}
|
|
60
|
+
const normalized = targets.map((target) => {
|
|
61
|
+
if ((target.kind !== "bundle" && target.kind !== "record") || !validId(target.id)) {
|
|
62
|
+
throw new PublicEvidenceValidationError("revocation_target", "invalid revocation target");
|
|
63
|
+
}
|
|
64
|
+
return { kind: target.kind, id: target.id } as PublicRevocationTargetV1;
|
|
65
|
+
}).sort((a, b) => compareCanonicalText(targetKey(a), targetKey(b)));
|
|
66
|
+
if (new Set(normalized.map(targetKey)).size !== normalized.length) {
|
|
67
|
+
throw new PublicEvidenceValidationError("revocation_target_duplicate", "revocation targets must be unique");
|
|
68
|
+
}
|
|
69
|
+
return normalized;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function samePublisher(a: PublicPublisherV1, b: PublicPublisherV1): boolean {
|
|
73
|
+
return a.algorithm === b.algorithm && a.keyId === b.keyId && a.publicKey === b.publicKey;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function validateTargetsAgainstBundle(targets: readonly PublicRevocationTargetV1[], bundle: PublicEvidenceBundleV1): boolean {
|
|
77
|
+
const records = new Set(bundle.records.map((record) => record.recordId));
|
|
78
|
+
return targets.every((target) => target.kind === "bundle" ? target.id === bundle.bundleId : records.has(target.id));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function revocationPayload(
|
|
82
|
+
issuedDayUtc: string,
|
|
83
|
+
publisher: PublicPublisherV1,
|
|
84
|
+
targets: PublicRevocationTargetV1[],
|
|
85
|
+
reason: PublicRevocationReasonV1,
|
|
86
|
+
): Record<string, unknown> {
|
|
87
|
+
return {
|
|
88
|
+
schemaVersion: PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION,
|
|
89
|
+
issuedDayUtc,
|
|
90
|
+
publisher,
|
|
91
|
+
targets,
|
|
92
|
+
reason,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function createPublicEvidenceRevocation(input: {
|
|
97
|
+
configDir?: string;
|
|
98
|
+
targetBundle: PublicEvidenceBundleV1;
|
|
99
|
+
issuedDayUtc: string;
|
|
100
|
+
targets: PublicRevocationTargetV1[];
|
|
101
|
+
reason: PublicRevocationReasonV1;
|
|
102
|
+
}): PublicEvidenceRevocationV1 {
|
|
103
|
+
// Validate the target and every caller-controlled field before touching publisher state.
|
|
104
|
+
if (verifyPublicEvidenceBundle(input.targetBundle).status !== "cryptographically_valid") {
|
|
105
|
+
throw new PublicEvidenceValidationError("revocation_target", "revocation target bundle is not cryptographically valid");
|
|
106
|
+
}
|
|
107
|
+
if (!validDay(input.issuedDayUtc)) {
|
|
108
|
+
throw new PublicEvidenceValidationError("revocation_day", "issuedDayUtc is invalid");
|
|
109
|
+
}
|
|
110
|
+
if (!REASONS.has(input.reason)) {
|
|
111
|
+
throw new PublicEvidenceValidationError("revocation_reason", "unsupported revocation reason");
|
|
112
|
+
}
|
|
113
|
+
const targets = canonicalTargets(input.targets);
|
|
114
|
+
if (!validateTargetsAgainstBundle(targets, input.targetBundle)) {
|
|
115
|
+
throw new PublicEvidenceValidationError("revocation_target", "revocation target is unknown to target bundle");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const handle = loadExistingPublicPublisher(input.configDir);
|
|
119
|
+
if (!handle || !samePublisher(handle.publisher, input.targetBundle.publisher)) {
|
|
120
|
+
throw new PublicEvidenceValidationError(
|
|
121
|
+
"revocation_publisher",
|
|
122
|
+
"revocation requires the existing publisher key that signed the target bundle",
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
const revocationId = publicEvidenceId(
|
|
126
|
+
"revocation",
|
|
127
|
+
revocationPayload(input.issuedDayUtc, handle.publisher, targets, input.reason),
|
|
128
|
+
);
|
|
129
|
+
const signature = signPublicPublisherDigest(handle, revocationId);
|
|
130
|
+
return Object.freeze({
|
|
131
|
+
schemaVersion: PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION,
|
|
132
|
+
revocationId,
|
|
133
|
+
issuedDayUtc: input.issuedDayUtc,
|
|
134
|
+
publisher: handle.publisher,
|
|
135
|
+
targets,
|
|
136
|
+
reason: input.reason,
|
|
137
|
+
signature: Object.freeze({ algorithm: "ed25519" as const, signedDigest: revocationId, signature }),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function verifyPublicEvidenceRevocation(
|
|
142
|
+
raw: unknown,
|
|
143
|
+
targetBundle: PublicEvidenceBundleV1,
|
|
144
|
+
): PublicRevocationVerificationResult {
|
|
145
|
+
try {
|
|
146
|
+
if (!isPlainObject(raw) || !closedKeys(raw, [
|
|
147
|
+
"schemaVersion", "revocationId", "issuedDayUtc", "publisher", "targets", "reason", "signature",
|
|
148
|
+
])) {
|
|
149
|
+
return { status: "schema_rejected", detail: "closed revocation schema mismatch" };
|
|
150
|
+
}
|
|
151
|
+
if (
|
|
152
|
+
raw.schemaVersion !== PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION
|
|
153
|
+
|| !validId(raw.revocationId)
|
|
154
|
+
|| !validDay(raw.issuedDayUtc)
|
|
155
|
+
|| !REASONS.has(raw.reason as PublicRevocationReasonV1)
|
|
156
|
+
) {
|
|
157
|
+
return { status: "schema_rejected", detail: "revocation version/id/day/reason invalid" };
|
|
158
|
+
}
|
|
159
|
+
if (
|
|
160
|
+
!isPlainObject(raw.publisher)
|
|
161
|
+
|| !closedKeys(raw.publisher, ["algorithm", "keyId", "publicKey"])
|
|
162
|
+
|| raw.publisher.algorithm !== "ed25519"
|
|
163
|
+
|| !validId(raw.publisher.keyId)
|
|
164
|
+
|| typeof raw.publisher.publicKey !== "string"
|
|
165
|
+
|| raw.publisher.publicKey.length > 1024
|
|
166
|
+
) {
|
|
167
|
+
return { status: "schema_rejected", detail: "revocation publisher invalid" };
|
|
168
|
+
}
|
|
169
|
+
const publicKeyBytes = Buffer.from(raw.publisher.publicKey, "base64");
|
|
170
|
+
if (publicKeyBytes.toString("base64") !== raw.publisher.publicKey) {
|
|
171
|
+
return { status: "schema_rejected", detail: "revocation publisher key is non-canonical" };
|
|
172
|
+
}
|
|
173
|
+
const publisher: PublicPublisherV1 = {
|
|
174
|
+
algorithm: "ed25519",
|
|
175
|
+
keyId: raw.publisher.keyId,
|
|
176
|
+
publicKey: raw.publisher.publicKey,
|
|
177
|
+
};
|
|
178
|
+
if (publicEvidenceId("publisher_key", { algorithm: "ed25519", publicKey: publisher.publicKey }) !== publisher.keyId) {
|
|
179
|
+
return { status: "schema_rejected", detail: "revocation publisher key id mismatch" };
|
|
180
|
+
}
|
|
181
|
+
if (!samePublisher(publisher, targetBundle.publisher)) {
|
|
182
|
+
return { status: "publisher_mismatch", detail: "revocation publisher does not match target bundle" };
|
|
183
|
+
}
|
|
184
|
+
if (!Array.isArray(raw.targets) || raw.targets.length === 0 || raw.targets.length > MAX_TARGETS) {
|
|
185
|
+
return { status: "schema_rejected", detail: "revocation targets invalid" };
|
|
186
|
+
}
|
|
187
|
+
const targets: PublicRevocationTargetV1[] = [];
|
|
188
|
+
for (const [index, value] of raw.targets.entries()) {
|
|
189
|
+
if (
|
|
190
|
+
!isPlainObject(value)
|
|
191
|
+
|| !closedKeys(value, ["kind", "id"])
|
|
192
|
+
|| (value.kind !== "bundle" && value.kind !== "record")
|
|
193
|
+
|| !validId(value.id)
|
|
194
|
+
) {
|
|
195
|
+
return { status: "schema_rejected", detail: `revocation target ${index} invalid` };
|
|
196
|
+
}
|
|
197
|
+
targets.push({ kind: value.kind, id: value.id });
|
|
198
|
+
}
|
|
199
|
+
const canonical = canonicalTargets(targets);
|
|
200
|
+
if (canonical.some((target, index) => target.kind !== targets[index]!.kind || target.id !== targets[index]!.id)) {
|
|
201
|
+
return { status: "schema_rejected", detail: "revocation targets must be sorted" };
|
|
202
|
+
}
|
|
203
|
+
if (!validateTargetsAgainstBundle(targets, targetBundle)) {
|
|
204
|
+
return { status: "unknown_target", detail: "revocation target not present in target bundle" };
|
|
205
|
+
}
|
|
206
|
+
if (
|
|
207
|
+
!isPlainObject(raw.signature)
|
|
208
|
+
|| !closedKeys(raw.signature, ["algorithm", "signedDigest", "signature"])
|
|
209
|
+
|| raw.signature.algorithm !== "ed25519"
|
|
210
|
+
|| raw.signature.signedDigest !== raw.revocationId
|
|
211
|
+
|| typeof raw.signature.signature !== "string"
|
|
212
|
+
) {
|
|
213
|
+
return { status: "schema_rejected", detail: "revocation signature schema invalid" };
|
|
214
|
+
}
|
|
215
|
+
const expected = publicEvidenceId(
|
|
216
|
+
"revocation",
|
|
217
|
+
revocationPayload(raw.issuedDayUtc, publisher, targets, raw.reason as PublicRevocationReasonV1),
|
|
218
|
+
);
|
|
219
|
+
if (expected !== raw.revocationId) {
|
|
220
|
+
return { status: "digest_invalid", detail: "revocation id does not match canonical bytes" };
|
|
221
|
+
}
|
|
222
|
+
const key = createPublicKey({ key: publicKeyBytes, type: "spki", format: "der" });
|
|
223
|
+
if (key.asymmetricKeyType !== "ed25519") {
|
|
224
|
+
return { status: "signature_invalid", detail: "revocation publisher key is not Ed25519" };
|
|
225
|
+
}
|
|
226
|
+
const signatureBytes = Buffer.from(raw.signature.signature, "base64");
|
|
227
|
+
if (signatureBytes.toString("base64") !== raw.signature.signature) {
|
|
228
|
+
return { status: "signature_invalid", detail: "revocation signature is non-canonical" };
|
|
229
|
+
}
|
|
230
|
+
if (!verifyBytes(null, Buffer.from(raw.revocationId, "hex"), key, signatureBytes)) {
|
|
231
|
+
return { status: "signature_invalid", detail: "revocation signature invalid" };
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
status: "cryptographically_valid",
|
|
235
|
+
revocation: {
|
|
236
|
+
schemaVersion: PUBLIC_EVIDENCE_REVOCATION_SCHEMA_VERSION,
|
|
237
|
+
revocationId: raw.revocationId,
|
|
238
|
+
issuedDayUtc: raw.issuedDayUtc,
|
|
239
|
+
publisher,
|
|
240
|
+
targets,
|
|
241
|
+
reason: raw.reason as PublicRevocationReasonV1,
|
|
242
|
+
signature: {
|
|
243
|
+
algorithm: "ed25519",
|
|
244
|
+
signedDigest: raw.revocationId,
|
|
245
|
+
signature: raw.signature.signature,
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
} catch (error) {
|
|
250
|
+
return { status: "schema_rejected", detail: error instanceof Error ? error.message : String(error) };
|
|
251
|
+
}
|
|
252
|
+
}
|