@iislee/opencodex 2.11.0 → 2.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. 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
+ }