@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.
Files changed (733) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +117 -22
  3. package/bin/ocx.mjs +245 -88
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-Be1sDpWw.css +1 -0
  6. package/gui/dist/assets/index-D4OKgUV4.js +114 -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 +21 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +475 -62
  44. package/src/adapters/base.ts +82 -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 +637 -0
  48. package/src/adapters/cursor/call-id.ts +44 -0
  49. package/src/adapters/cursor/catalog.ts +541 -0
  50. package/src/adapters/cursor/checkpoint-store.ts +308 -0
  51. package/src/adapters/cursor/cursor-errors.ts +144 -6
  52. package/src/adapters/cursor/discovery.ts +122 -14
  53. package/src/adapters/cursor/effort-map.ts +106 -4
  54. package/src/adapters/cursor/envelope-echo.ts +290 -0
  55. package/src/adapters/cursor/framing.ts +39 -0
  56. package/src/adapters/cursor/h2-pool.ts +123 -0
  57. package/src/adapters/cursor/http1-bidi.ts +361 -0
  58. package/src/adapters/cursor/images.ts +704 -0
  59. package/src/adapters/cursor/live-models.ts +180 -59
  60. package/src/adapters/cursor/live-transport.ts +623 -170
  61. package/src/adapters/cursor/message-mapper.ts +4 -1
  62. package/src/adapters/cursor/native-exec-common.ts +23 -2
  63. package/src/adapters/cursor/native-exec-desktop.ts +23 -0
  64. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  65. package/src/adapters/cursor/native-exec-network.ts +1 -1
  66. package/src/adapters/cursor/native-exec-shell.ts +5 -3
  67. package/src/adapters/cursor/native-exec.ts +121 -14
  68. package/src/adapters/cursor/protobuf-events.ts +829 -11
  69. package/src/adapters/cursor/protobuf-request.ts +447 -75
  70. package/src/adapters/cursor/request-builder.ts +271 -35
  71. package/src/adapters/cursor/tool-definitions.ts +252 -12
  72. package/src/adapters/cursor/tool-result-normalize.ts +115 -0
  73. package/src/adapters/cursor/transport.ts +22 -0
  74. package/src/adapters/cursor/types.ts +48 -1
  75. package/src/adapters/cursor.ts +336 -39
  76. package/src/adapters/exec-tool-result-normalize.ts +99 -0
  77. package/src/adapters/google-antigravity-replay.ts +713 -41
  78. package/src/adapters/google-antigravity-wire.ts +48 -10
  79. package/src/adapters/google-errors.ts +44 -12
  80. package/src/adapters/google-http.ts +38 -10
  81. package/src/adapters/google-tool-schema.ts +80 -15
  82. package/src/adapters/google-truncation.ts +11 -0
  83. package/src/adapters/google.ts +742 -86
  84. package/src/adapters/identity.ts +39 -6
  85. package/src/adapters/image.ts +1 -1
  86. package/src/adapters/kiro-constants.ts +27 -0
  87. package/src/adapters/kiro-errors.ts +11 -0
  88. package/src/adapters/kiro-events.ts +19 -1
  89. package/src/adapters/kiro-thinking.ts +18 -2
  90. package/src/adapters/kiro-tools.ts +65 -17
  91. package/src/adapters/kiro.ts +270 -73
  92. package/src/adapters/mimo-free.ts +17 -0
  93. package/src/adapters/openai-chat-url.ts +11 -0
  94. package/src/adapters/openai-chat.ts +1377 -344
  95. package/src/adapters/openai-responses-url.ts +16 -0
  96. package/src/adapters/openai-responses.ts +1164 -64
  97. package/src/adapters/registry.ts +175 -0
  98. package/src/adapters/responses-tool-schema.ts +67 -0
  99. package/src/adapters/run-turn-queue.ts +36 -1
  100. package/src/adapters/tool-call-id.ts +119 -0
  101. package/src/adapters/tool-catalog-nudge.ts +105 -21
  102. package/src/adapters/xai-tool-schema.ts +436 -0
  103. package/src/adapters/xai-web-search.ts +186 -0
  104. package/src/bridge.ts +512 -92
  105. package/src/chat/inbound.ts +57 -20
  106. package/src/chat/outbound.ts +97 -33
  107. package/src/claude/agents-inject.ts +40 -10
  108. package/src/claude/context-windows.ts +37 -14
  109. package/src/claude/desktop-3p.ts +243 -9
  110. package/src/claude/gateway-cache.ts +41 -4
  111. package/src/claude/inbound.ts +72 -3
  112. package/src/claude/model-info.ts +38 -15
  113. package/src/claude/outbound.ts +88 -21
  114. package/src/cli/access.ts +46 -3
  115. package/src/cli/account-api.ts +150 -19
  116. package/src/cli/account-auth.ts +33 -6
  117. package/src/cli/account-catalog-refresh.ts +14 -0
  118. package/src/cli/account-extended.ts +648 -28
  119. package/src/cli/account-main.ts +317 -0
  120. package/src/cli/account.ts +97 -19
  121. package/src/cli/agent.ts +53 -2
  122. package/src/cli/alias.ts +66 -0
  123. package/src/cli/capabilities-command.ts +94 -0
  124. package/src/cli/capabilities.ts +496 -0
  125. package/src/cli/claude-agent-startup-sync.ts +73 -0
  126. package/src/cli/claude-desktop.ts +60 -15
  127. package/src/cli/claude.ts +129 -35
  128. package/src/cli/codex-log-guard-doctor.ts +103 -0
  129. package/src/cli/codex-shim-autorestore.ts +2 -0
  130. package/src/cli/codex-shim-readiness.ts +76 -0
  131. package/src/cli/combo.ts +8 -0
  132. package/src/cli/config-command.ts +74 -10
  133. package/src/cli/dispatch.ts +821 -0
  134. package/src/cli/doctor.ts +440 -56
  135. package/src/cli/ensure-desired-integrations.ts +152 -0
  136. package/src/cli/export-command.ts +46 -20
  137. package/src/cli/help.ts +34 -274
  138. package/src/cli/index.ts +417 -528
  139. package/src/cli/init.ts +5 -17
  140. package/src/cli/inspect.ts +230 -0
  141. package/src/cli/integrations.ts +120 -2
  142. package/src/cli/lab.ts +607 -0
  143. package/src/cli/launcher-context.ts +77 -0
  144. package/src/cli/minimax.ts +497 -0
  145. package/src/cli/models-runtime.ts +130 -2
  146. package/src/cli/models.ts +118 -16
  147. package/src/cli/observe.ts +123 -11
  148. package/src/cli/opencode.ts +4 -2
  149. package/src/cli/provider-runtime.ts +34 -3
  150. package/src/cli/provider.ts +25 -3
  151. package/src/cli/ready.ts +301 -0
  152. package/src/cli/registry.ts +476 -0
  153. package/src/cli/root.ts +86 -0
  154. package/src/cli/route-policy.ts +92 -0
  155. package/src/cli/runtime-api.ts +57 -10
  156. package/src/cli/star-prompt.ts +71 -15
  157. package/src/cli/status.ts +51 -4
  158. package/src/cli/storage.ts +234 -0
  159. package/src/cli/system-command.ts +16 -0
  160. package/src/cli/system-restart-client.ts +146 -0
  161. package/src/cli/tray-proxy.ts +153 -6
  162. package/src/cli/usage-report.ts +184 -0
  163. package/src/cli/v2.ts +137 -18
  164. package/src/cli/version-skew.ts +46 -0
  165. package/src/cli.ts +1 -1
  166. package/src/clients/config-export.ts +1442 -23
  167. package/src/clients/effective-status.ts +30 -2
  168. package/src/clients/probes/cline.ts +81 -0
  169. package/src/codex/account-label.ts +35 -1
  170. package/src/codex/account-lifecycle.ts +130 -13
  171. package/src/codex/account-namespaces.ts +49 -3
  172. package/src/codex/account-pause.ts +2 -1
  173. package/src/codex/account-priority.ts +84 -0
  174. package/src/codex/account-store.ts +29 -2
  175. package/src/codex/account-usability.ts +25 -2
  176. package/src/codex/admission.ts +256 -0
  177. package/src/codex/affinity-debug.ts +162 -0
  178. package/src/codex/app-server-processes.ts +570 -107
  179. package/src/codex/app-server-restart-service.ts +232 -0
  180. package/src/codex/auth-api.ts +893 -246
  181. package/src/codex/auth-collision.ts +5 -3
  182. package/src/codex/auth-context.ts +348 -32
  183. package/src/codex/autostart-health.ts +24 -1
  184. package/src/codex/catalog/account-models.ts +67 -0
  185. package/src/codex/catalog/aggregation.ts +86 -10
  186. package/src/codex/catalog/bundled.ts +331 -33
  187. package/src/codex/catalog/effort.ts +138 -32
  188. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  189. package/src/codex/catalog/kinds.ts +2 -0
  190. package/src/codex/catalog/metadata.ts +555 -45
  191. package/src/codex/catalog/native-models.ts +75 -0
  192. package/src/codex/catalog/parsing.ts +269 -30
  193. package/src/codex/catalog/provider-fetch.ts +1626 -144
  194. package/src/codex/catalog/sync.ts +1576 -187
  195. package/src/codex/catalog-admission.ts +199 -0
  196. package/src/codex/catalog-refresh-status.ts +105 -0
  197. package/src/codex/catalog-write-serialization.ts +242 -0
  198. package/src/codex/catalog.ts +6 -3
  199. package/src/codex/codex-write-lock.ts +386 -0
  200. package/src/codex/convergence-types.ts +614 -0
  201. package/src/codex/convergence.ts +676 -0
  202. package/src/codex/coordinator-doctor.ts +332 -0
  203. package/src/codex/custom-model-catalog-migration.ts +176 -0
  204. package/src/codex/desired-state.ts +230 -0
  205. package/src/codex/desktop-app-restart.ts +355 -0
  206. package/src/codex/features.ts +636 -39
  207. package/src/codex/generation.ts +202 -0
  208. package/src/codex/history-job.ts +436 -0
  209. package/src/codex/history-lock.ts +242 -0
  210. package/src/codex/history-manifest.ts +112 -0
  211. package/src/codex/history-migration-guardian.ts +30 -24
  212. package/src/codex/history-provider.ts +1016 -235
  213. package/src/codex/history-transition.ts +105 -0
  214. package/src/codex/history-worker.ts +223 -0
  215. package/src/codex/inject-coordination.ts +373 -0
  216. package/src/codex/inject.ts +1114 -152
  217. package/src/codex/injected-marker.ts +37 -3
  218. package/src/codex/integration-record.ts +266 -0
  219. package/src/codex/internal/catalog-writer.ts +203 -0
  220. package/src/codex/internal/history-writer.ts +81 -0
  221. package/src/codex/journal.ts +66 -4
  222. package/src/codex/log-guard/inspect.ts +524 -0
  223. package/src/codex/log-guard/lock.ts +150 -0
  224. package/src/codex/log-guard/maintenance.ts +403 -0
  225. package/src/codex/log-guard/path-safety.ts +88 -0
  226. package/src/codex/log-guard/policy.ts +44 -0
  227. package/src/codex/log-guard/processes.ts +205 -0
  228. package/src/codex/log-guard/protection.ts +489 -0
  229. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  230. package/src/codex/main-account-cache.ts +24 -0
  231. package/src/codex/main-account.ts +29 -1
  232. package/src/codex/management-convergence.ts +167 -0
  233. package/src/codex/model-cache.ts +56 -10
  234. package/src/codex/model-entitlements.ts +360 -0
  235. package/src/codex/native-main-admission.ts +47 -0
  236. package/src/codex/native-main-auth-temp.ts +187 -0
  237. package/src/codex/native-main-claim.ts +178 -0
  238. package/src/codex/native-main-lock-file.ts +162 -0
  239. package/src/codex/native-main-owner.ts +329 -0
  240. package/src/codex/native-profile-api.ts +247 -0
  241. package/src/codex/native-profile-manager.ts +1531 -0
  242. package/src/codex/native-profile-processes.ts +121 -0
  243. package/src/codex/native-profile-recovery.ts +99 -0
  244. package/src/codex/native-profile-stage-store.ts +387 -0
  245. package/src/codex/native-profile-startup.ts +622 -0
  246. package/src/codex/native-profile-store.ts +855 -0
  247. package/src/codex/native-profile-types.ts +120 -0
  248. package/src/codex/native-residue.ts +675 -0
  249. package/src/codex/paths.ts +80 -1
  250. package/src/codex/plan-from-token.ts +140 -0
  251. package/src/codex/plan.ts +40 -0
  252. package/src/codex/plugins-doctor.ts +1 -1
  253. package/src/codex/pool-rotation.ts +74 -4
  254. package/src/codex/project-config-warnings.ts +20 -6
  255. package/src/codex/prompt-journal.ts +352 -0
  256. package/src/codex/prompt-layers.ts +1313 -0
  257. package/src/codex/prompt-lock.ts +143 -0
  258. package/src/codex/prompt-text-probe.ts +238 -0
  259. package/src/codex/quota-rejection.ts +298 -0
  260. package/src/codex/quota.ts +264 -21
  261. package/src/codex/refresh.ts +11 -2
  262. package/src/codex/reset-credit-recovery.ts +1044 -0
  263. package/src/codex/routing.ts +514 -94
  264. package/src/codex/runtime.ts +159 -38
  265. package/src/codex/shim.ts +1065 -31
  266. package/src/codex/subagent-model-fallback.ts +437 -43
  267. package/src/codex/sync.ts +191 -2
  268. package/src/codex/transition-state.ts +720 -0
  269. package/src/codex/upstream-host-health.ts +368 -0
  270. package/src/codex/user-identity.ts +557 -0
  271. package/src/codex/warmup.ts +187 -81
  272. package/src/codex/write-coordination.ts +114 -0
  273. package/src/combos/failover.ts +47 -0
  274. package/src/combos/index.ts +4 -0
  275. package/src/combos/request.ts +32 -0
  276. package/src/combos/types.ts +91 -9
  277. package/src/compatibility/index.ts +26 -0
  278. package/src/compatibility/manifest.ts +253 -0
  279. package/src/compatibility/openai-responses.ts +121 -0
  280. package/src/config/atomic-write.ts +219 -0
  281. package/src/config/paths.ts +40 -0
  282. package/src/config/process-state.ts +309 -0
  283. package/src/config/provider-name.ts +24 -0
  284. package/src/config/provider-validation.ts +177 -0
  285. package/src/config/rebase-provenance.ts +68 -0
  286. package/src/config.ts +1713 -709
  287. package/src/generated/compatibility-version.json +3324 -0
  288. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  289. package/src/grok/inject.ts +16 -5
  290. package/src/grok/inspect.ts +45 -0
  291. package/src/grok/sync.ts +2 -2
  292. package/src/images/loop.ts +157 -33
  293. package/src/images/plan.ts +24 -13
  294. package/src/integrations/config-io.ts +269 -0
  295. package/src/integrations/journal.ts +315 -0
  296. package/src/integrations/merge.ts +135 -0
  297. package/src/integrations/mutation-flight.ts +71 -0
  298. package/src/integrations/native/ownership-preflight.ts +202 -0
  299. package/src/integrations/omp-yaml-source.ts +358 -0
  300. package/src/integrations/owned-refresh.ts +74 -0
  301. package/src/integrations/ownership-policy.ts +160 -0
  302. package/src/integrations/ownership.ts +155 -0
  303. package/src/integrations/registry.ts +166 -0
  304. package/src/integrations/serialize.ts +314 -0
  305. package/src/integrations/state.ts +433 -0
  306. package/src/integrations/store.ts +103 -0
  307. package/src/integrations/writer-lock.ts +98 -0
  308. package/src/integrations/writer.ts +715 -0
  309. package/src/lab/artifacts/sanitize.ts +586 -0
  310. package/src/lab/artifacts/secure-fs.ts +475 -0
  311. package/src/lab/artifacts/store.ts +310 -0
  312. package/src/lab/automation/budgets.ts +78 -0
  313. package/src/lab/automation/config-persistence.ts +256 -0
  314. package/src/lab/automation/constants.ts +39 -0
  315. package/src/lab/automation/cooldown.ts +103 -0
  316. package/src/lab/automation/dispatch.ts +211 -0
  317. package/src/lab/automation/index.ts +13 -0
  318. package/src/lab/automation/orchestrator.ts +499 -0
  319. package/src/lab/automation/persistence.ts +512 -0
  320. package/src/lab/automation/planner.ts +371 -0
  321. package/src/lab/automation/policy.ts +136 -0
  322. package/src/lab/automation/queue.ts +191 -0
  323. package/src/lab/automation/recovery.ts +24 -0
  324. package/src/lab/automation/route-context.ts +21 -0
  325. package/src/lab/automation/run-key.ts +44 -0
  326. package/src/lab/automation/runs-query.ts +34 -0
  327. package/src/lab/automation/types.ts +160 -0
  328. package/src/lab/conformance/assertion.ts +325 -0
  329. package/src/lab/conformance/digest.ts +22 -0
  330. package/src/lab/conformance/executor.ts +741 -0
  331. package/src/lab/conformance/fixture-provider.ts +27 -0
  332. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  333. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  334. package/src/lab/conformance/harness-budget.ts +47 -0
  335. package/src/lab/conformance/index.ts +5 -0
  336. package/src/lab/conformance/jcs.ts +64 -0
  337. package/src/lab/conformance/json-pointer.ts +39 -0
  338. package/src/lab/conformance/manifest.ts +180 -0
  339. package/src/lab/conformance/mcp-stub.ts +179 -0
  340. package/src/lab/conformance/negative-controls.ts +164 -0
  341. package/src/lab/conformance/observation.ts +355 -0
  342. package/src/lab/conformance/runner.ts +68 -0
  343. package/src/lab/conformance/sse-normalize.ts +59 -0
  344. package/src/lab/conformance/suite-manifest.ts +78 -0
  345. package/src/lab/conformance/types.ts +214 -0
  346. package/src/lab/constants.ts +126 -0
  347. package/src/lab/digest.ts +64 -0
  348. package/src/lab/events/errors.ts +9 -0
  349. package/src/lab/events/limits.ts +117 -0
  350. package/src/lab/events/types.ts +229 -0
  351. package/src/lab/events/validate.ts +781 -0
  352. package/src/lab/fabric/constants.ts +40 -0
  353. package/src/lab/fabric/executor.ts +492 -0
  354. package/src/lab/fabric/index.ts +80 -0
  355. package/src/lab/fabric/manifest.ts +222 -0
  356. package/src/lab/fabric/observe.ts +489 -0
  357. package/src/lab/fabric/patch.ts +79 -0
  358. package/src/lab/fabric/producer-child.ts +139 -0
  359. package/src/lab/fabric/producer-isolate.ts +276 -0
  360. package/src/lab/fabric/producer-protocol.ts +61 -0
  361. package/src/lab/fabric/scratch.ts +439 -0
  362. package/src/lab/fabric/subject.ts +106 -0
  363. package/src/lab/fabric/types.ts +134 -0
  364. package/src/lab/fabric/verifier.ts +98 -0
  365. package/src/lab/index.ts +54 -0
  366. package/src/lab/ledger/artifact-refs.ts +127 -0
  367. package/src/lab/ledger/invalidation.ts +136 -0
  368. package/src/lab/ledger/purge.ts +310 -0
  369. package/src/lab/ledger/store.ts +532 -0
  370. package/src/lab/live/credential-lease.ts +53 -0
  371. package/src/lab/live/destination.ts +155 -0
  372. package/src/lab/live/executor.ts +336 -0
  373. package/src/lab/live/inert-tools.ts +56 -0
  374. package/src/lab/live/manifest.ts +85 -0
  375. package/src/lab/live/mcp-loopback.ts +57 -0
  376. package/src/lab/live/runner.ts +19 -0
  377. package/src/lab/live/sandbox.ts +61 -0
  378. package/src/lab/live/suite-manifest.ts +41 -0
  379. package/src/lab/live/transport.ts +118 -0
  380. package/src/lab/live/types.ts +197 -0
  381. package/src/lab/observe/from-conformance.ts +301 -0
  382. package/src/lab/observe/from-live.ts +117 -0
  383. package/src/lab/paths.ts +153 -0
  384. package/src/lab/projection/rebuild.ts +495 -0
  385. package/src/lab/projection/schema.ts +135 -0
  386. package/src/lab/projection/verdicts.ts +474 -0
  387. package/src/lab/projection/verification.ts +412 -0
  388. package/src/lab/public/bundle.ts +217 -0
  389. package/src/lab/public/community-authority.ts +175 -0
  390. package/src/lab/public/community-files.ts +29 -0
  391. package/src/lab/public/community.ts +479 -0
  392. package/src/lab/public/file-safety.ts +155 -0
  393. package/src/lab/public/ids.ts +26 -0
  394. package/src/lab/public/index.ts +16 -0
  395. package/src/lab/public/mutation-lock.ts +424 -0
  396. package/src/lab/public/operator.ts +353 -0
  397. package/src/lab/public/origin-purge.ts +79 -0
  398. package/src/lab/public/origin.ts +203 -0
  399. package/src/lab/public/privacy.ts +143 -0
  400. package/src/lab/public/private-file.ts +261 -0
  401. package/src/lab/public/project.ts +124 -0
  402. package/src/lab/public/purge-test-fault.ts +21 -0
  403. package/src/lab/public/purge.ts +223 -0
  404. package/src/lab/public/registry.ts +44 -0
  405. package/src/lab/public/revocation.ts +252 -0
  406. package/src/lab/public/signature.ts +243 -0
  407. package/src/lab/public/storage.ts +105 -0
  408. package/src/lab/public/strict-json.ts +206 -0
  409. package/src/lab/public/time.ts +26 -0
  410. package/src/lab/public/types.ts +172 -0
  411. package/src/lab/public/validate.ts +391 -0
  412. package/src/lab/query/catalog.ts +101 -0
  413. package/src/lab/query/connection.ts +107 -0
  414. package/src/lab/query/constants.ts +4 -0
  415. package/src/lab/query/cursor.ts +132 -0
  416. package/src/lab/query/dto-map.ts +277 -0
  417. package/src/lab/query/errors.ts +22 -0
  418. package/src/lab/query/freshness.ts +53 -0
  419. package/src/lab/query/index.ts +45 -0
  420. package/src/lab/query/latest-observation.ts +59 -0
  421. package/src/lab/query/passive-production.ts +159 -0
  422. package/src/lab/query/queries.ts +444 -0
  423. package/src/lab/query/types.ts +266 -0
  424. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  425. package/src/lab/subject/installation-salt.ts +112 -0
  426. package/src/lab/subject/protocol-subject.ts +80 -0
  427. package/src/lab/subject/route-subject.ts +74 -0
  428. package/src/lib/admin-secrets.ts +24 -0
  429. package/src/lib/app-owned-memory-stores.ts +22 -0
  430. package/src/lib/bounded-body.ts +167 -11
  431. package/src/lib/bun-runtime.ts +125 -12
  432. package/src/lib/bun-stream-caps.ts +13 -9
  433. package/src/lib/codex-restart-contract.ts +120 -0
  434. package/src/lib/config-ownership.ts +26 -2
  435. package/src/lib/destination-policy.ts +65 -1
  436. package/src/lib/errors.ts +80 -5
  437. package/src/lib/fabric-task-execution-authority.ts +7 -0
  438. package/src/lib/fabric-task-host.ts +29 -0
  439. package/src/lib/lab-activation.ts +223 -0
  440. package/src/lib/lab-live-execution-authority.ts +13 -0
  441. package/src/lib/lab-live-host.ts +30 -0
  442. package/src/lib/lab-live-pinned-sender.ts +56 -0
  443. package/src/lib/lab-live-route-production.ts +130 -0
  444. package/src/lib/lab-passive-linker-registration.ts +26 -0
  445. package/src/lib/local-management-attestation.ts +51 -0
  446. package/src/lib/local-management-capability.ts +100 -0
  447. package/src/lib/local-provider-reload-contract.ts +100 -0
  448. package/src/lib/optional-shutdown-hooks.ts +57 -0
  449. package/src/lib/package-tree-integrity.ts +101 -0
  450. package/src/lib/pinned-http.ts +145 -26
  451. package/src/lib/process-control.ts +6 -2
  452. package/src/lib/provider-outbound.ts +49 -9
  453. package/src/lib/redact.ts +419 -3
  454. package/src/lib/self-launch-argv.ts +15 -0
  455. package/src/lib/server-resource-ownership.ts +71 -0
  456. package/src/lib/service-secrets.ts +15 -0
  457. package/src/lib/shadow-call.ts +35 -4
  458. package/src/lib/sse-decoder.ts +41 -0
  459. package/src/lib/state-store-registrations.ts +10 -2
  460. package/src/lib/system-restart-contract.ts +73 -0
  461. package/src/lib/token-estimate.ts +19 -2
  462. package/src/lib/tool-argument-integers.ts +253 -0
  463. package/src/lib/translator-budget.ts +44 -0
  464. package/src/lib/upstream-http-version.ts +57 -0
  465. package/src/lib/upstream-reachability.ts +95 -0
  466. package/src/lib/upstream-retry.ts +156 -3
  467. package/src/lib/windows-atomic-replace.ts +155 -0
  468. package/src/lib/windows-elevation.ts +70 -2
  469. package/src/lib/windows-secret-acl.ts +409 -69
  470. package/src/lib/windows-service-wrappers.ts +72 -0
  471. package/src/lib/windows-text.ts +106 -0
  472. package/src/lib/windows-user-principal.ts +341 -0
  473. package/src/lib/winsw.ts +33 -5
  474. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  475. package/src/oauth/account-import/index.ts +15 -0
  476. package/src/oauth/account-import/parser.ts +83 -0
  477. package/src/oauth/account-import/registry.ts +18 -0
  478. package/src/oauth/account-import/service.ts +75 -0
  479. package/src/oauth/account-import/types.ts +91 -0
  480. package/src/oauth/anthropic.ts +12 -1
  481. package/src/oauth/callback-server.ts +30 -4
  482. package/src/oauth/chatgpt.ts +12 -1
  483. package/src/oauth/cline.ts +203 -0
  484. package/src/oauth/command-code.ts +239 -0
  485. package/src/oauth/cursor.ts +46 -5
  486. package/src/oauth/generic-account-failover.ts +231 -0
  487. package/src/oauth/google-antigravity.ts +35 -3
  488. package/src/oauth/health.ts +20 -12
  489. package/src/oauth/index.ts +462 -71
  490. package/src/oauth/key-providers.ts +25 -0
  491. package/src/oauth/kimi.ts +25 -3
  492. package/src/oauth/kiro.ts +95 -6
  493. package/src/oauth/local-token-detect.ts +13 -2
  494. package/src/oauth/log.ts +3 -1
  495. package/src/oauth/login-cli.ts +88 -28
  496. package/src/oauth/nous.ts +798 -0
  497. package/src/oauth/open-browser-choice.ts +26 -0
  498. package/src/oauth/store.ts +133 -26
  499. package/src/oauth/token-guardian.ts +9 -3
  500. package/src/oauth/types.ts +15 -0
  501. package/src/pi/models.ts +2 -2
  502. package/src/providers/alibaba-region-migration.ts +1 -1
  503. package/src/providers/antigravity-models.ts +521 -31
  504. package/src/providers/auto-compact-budget.ts +65 -0
  505. package/src/providers/base-url-choices.ts +10 -0
  506. package/src/providers/codex-capacity.ts +292 -0
  507. package/src/providers/command-code-efforts.ts +176 -0
  508. package/src/providers/context-cap.ts +26 -8
  509. package/src/providers/cursor-pool.ts +72 -0
  510. package/src/providers/default-aliases.ts +65 -0
  511. package/src/providers/derive.ts +281 -6
  512. package/src/providers/fastwire.ts +507 -0
  513. package/src/providers/free-directory.ts +10 -7
  514. package/src/providers/google-vertex-location.ts +14 -0
  515. package/src/providers/key-failover.ts +71 -3
  516. package/src/providers/label.ts +35 -2
  517. package/src/providers/model-discovery-limits.ts +16 -0
  518. package/src/providers/model-discovery.ts +115 -22
  519. package/src/providers/model-presets.ts +119 -0
  520. package/src/providers/model-rename-migration.ts +255 -0
  521. package/src/providers/model-rename-startup.ts +28 -0
  522. package/src/providers/new-model-policy.ts +146 -0
  523. package/src/providers/openai-sidecar.ts +72 -4
  524. package/src/providers/openai-tier-startup.ts +31 -2
  525. package/src/providers/openai-tiers.ts +119 -4
  526. package/src/providers/openai-virtual-models.ts +1 -0
  527. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  528. package/src/providers/provider-id-rewrite.ts +30 -0
  529. package/src/providers/quota.ts +1379 -40
  530. package/src/providers/registry.ts +1545 -112
  531. package/src/providers/request-pacing.ts +310 -0
  532. package/src/providers/service-tier.ts +277 -0
  533. package/src/providers/slug-codec.ts +94 -6
  534. package/src/providers/static-model-discovery.ts +86 -0
  535. package/src/providers/xai-responses-opt-in.ts +15 -0
  536. package/src/providers/xai-transport.ts +32 -4
  537. package/src/reasoning-effort.ts +68 -3
  538. package/src/responses/apply-patch-envelope.ts +63 -0
  539. package/src/responses/code-mode-helper-compat.ts +50 -0
  540. package/src/responses/compaction.ts +26 -1
  541. package/src/responses/custom-tool-compat.ts +384 -0
  542. package/src/responses/hosted-tool-policy.ts +9 -0
  543. package/src/responses/namespace-tool-compat.ts +435 -0
  544. package/src/responses/parser.ts +225 -38
  545. package/src/responses/provider-continuation.ts +98 -0
  546. package/src/responses/provider-opaque-metadata.ts +73 -0
  547. package/src/responses/reasoning-envelope.ts +9 -1
  548. package/src/responses/reasoning-replay-cache.ts +504 -0
  549. package/src/responses/schema.ts +12 -2
  550. package/src/responses/spill-store.ts +75 -10
  551. package/src/responses/state.ts +659 -31
  552. package/src/responses/thought-signature-replay.ts +364 -0
  553. package/src/responses/tool-search-compat.ts +301 -0
  554. package/src/responses/truncated-stop-reason.ts +60 -0
  555. package/src/responses/turn-termination.ts +107 -0
  556. package/src/router.ts +405 -31
  557. package/src/routing/analytics.ts +379 -0
  558. package/src/routing/capability.ts +244 -0
  559. package/src/routing/compatibility/assemble.ts +73 -0
  560. package/src/routing/compatibility/behavior.ts +278 -0
  561. package/src/routing/compatibility/catalog.ts +99 -0
  562. package/src/routing/compatibility/endpoint.ts +52 -0
  563. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  564. package/src/routing/compatibility/policy.ts +181 -0
  565. package/src/routing/compatibility/provider-slot.ts +56 -0
  566. package/src/routing/compatibility/reader.ts +110 -0
  567. package/src/routing/compatibility/subject.ts +191 -0
  568. package/src/routing/compatibility/types.ts +64 -0
  569. package/src/routing/compatibility/version.ts +104 -0
  570. package/src/routing/cost.ts +77 -0
  571. package/src/routing/evaluator.ts +495 -0
  572. package/src/routing/health.ts +412 -0
  573. package/src/routing/history/cursor.ts +43 -0
  574. package/src/routing/history/indexer.ts +605 -0
  575. package/src/routing/history/schema.ts +72 -0
  576. package/src/routing/profile-namespace.ts +15 -0
  577. package/src/routing/profile.ts +547 -0
  578. package/src/routing/quota.ts +155 -0
  579. package/src/routing/request-evidence.ts +45 -0
  580. package/src/routing/trace.ts +776 -0
  581. package/src/server/adapter-resolve.ts +2 -29
  582. package/src/server/auth-cors.ts +289 -48
  583. package/src/server/background-lifecycle.ts +182 -0
  584. package/src/server/chat-completions.ts +154 -72
  585. package/src/server/chat-native-sse.ts +331 -0
  586. package/src/server/chat-native.ts +445 -0
  587. package/src/server/claude-messages.ts +160 -44
  588. package/src/server/direct-local-http.ts +347 -0
  589. package/src/server/effort-policy.ts +18 -0
  590. package/src/server/github-copilot-responses-repair.ts +338 -0
  591. package/src/server/gui-static.ts +39 -10
  592. package/src/server/images.ts +94 -12
  593. package/src/server/index.ts +1021 -190
  594. package/src/server/lifecycle.ts +336 -14
  595. package/src/server/live.ts +136 -17
  596. package/src/server/local-management-read-client.ts +90 -0
  597. package/src/server/local-provider-reload-client.ts +137 -0
  598. package/src/server/management/agent-settings-routes.ts +433 -116
  599. package/src/server/management/api-key-usage.ts +31 -5
  600. package/src/server/management/body.ts +6 -0
  601. package/src/server/management/codex-prompt-routes.ts +570 -0
  602. package/src/server/management/combo-routes.ts +64 -25
  603. package/src/server/management/config-routes.ts +511 -51
  604. package/src/server/management/context.ts +89 -2
  605. package/src/server/management/integration-routes.ts +498 -0
  606. package/src/server/management/lab-automation-routes.ts +206 -0
  607. package/src/server/management/lab-routes.ts +563 -0
  608. package/src/server/management/logs-usage-routes.ts +127 -52
  609. package/src/server/management/model-routes.ts +461 -133
  610. package/src/server/management/model-rows.ts +167 -0
  611. package/src/server/management/native-integration-routes.ts +770 -0
  612. package/src/server/management/oauth-account-routes.ts +90 -8
  613. package/src/server/management/provider-capability-config.ts +48 -0
  614. package/src/server/management/provider-routes.ts +836 -159
  615. package/src/server/management/request-history-routes.ts +191 -0
  616. package/src/server/management/route-registry.ts +332 -0
  617. package/src/server/management/routing-analytics-routes.ts +74 -0
  618. package/src/server/management/routing-profile-routes.ts +380 -0
  619. package/src/server/management/shared.ts +27 -11
  620. package/src/server/management/sidebar-routes.ts +47 -31
  621. package/src/server/management/storage-log-guard-routes.ts +186 -0
  622. package/src/server/management/sync-response.ts +69 -0
  623. package/src/server/management/system-restart.ts +289 -33
  624. package/src/server/management/system-routes.ts +77 -0
  625. package/src/server/management/usage-summary-cache.ts +9 -1
  626. package/src/server/management/vision-sidecar-options.ts +167 -0
  627. package/src/server/management/web-search-sidecar-options.ts +120 -0
  628. package/src/server/management-api.ts +126 -23
  629. package/src/server/management-auth.ts +220 -5
  630. package/src/server/passive-route-linker.ts +66 -0
  631. package/src/server/port-reclaim.ts +1 -1
  632. package/src/server/ports.ts +41 -1
  633. package/src/server/proxy-liveness.ts +161 -10
  634. package/src/server/readiness.ts +99 -0
  635. package/src/server/relay-eager.ts +221 -54
  636. package/src/server/relay.ts +479 -87
  637. package/src/server/request-decompress.ts +113 -6
  638. package/src/server/request-log-conversation.ts +51 -0
  639. package/src/server/request-log.ts +298 -31
  640. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  641. package/src/server/responses/agent-task-recovery.ts +465 -0
  642. package/src/server/responses/codex-auth-error.ts +55 -0
  643. package/src/server/responses/collaboration.ts +239 -36
  644. package/src/server/responses/combo-stream-preflight.ts +178 -0
  645. package/src/server/responses/compact.ts +444 -72
  646. package/src/server/responses/core.ts +3579 -436
  647. package/src/server/responses/empty-completion-guard.ts +333 -0
  648. package/src/server/responses/encrypted-payload.ts +62 -39
  649. package/src/server/responses/fetch-helpers.ts +89 -99
  650. package/src/server/responses/input-admission.ts +187 -0
  651. package/src/server/responses/pacing-overload.ts +13 -0
  652. package/src/server/responses/passthrough-error.ts +33 -9
  653. package/src/server/responses/policy-fallback.ts +178 -0
  654. package/src/server/responses/responses-field-backfill.ts +343 -0
  655. package/src/server/responses/terminal-guard.ts +26 -5
  656. package/src/server/responses/upstream-error.ts +5 -0
  657. package/src/server/responses/ws-upstream.ts +381 -0
  658. package/src/server/responses-custom-tool-repair.ts +363 -0
  659. package/src/server/responses-item-id-repair.ts +54 -6
  660. package/src/server/responses-json-events.ts +90 -0
  661. package/src/server/responses-model-rewrite.ts +29 -0
  662. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  663. package/src/server/responses-snapshot-repair.ts +621 -0
  664. package/src/server/responses-terminal-repair.ts +363 -0
  665. package/src/server/responses-tool-search-repair.ts +267 -0
  666. package/src/server/responses-undeclared-tool-guard.ts +376 -0
  667. package/src/server/responses.ts +18 -2
  668. package/src/server/search.ts +78 -13
  669. package/src/server/sse-frame-buffer.ts +319 -0
  670. package/src/server/sse-payload-rewrite.ts +110 -22
  671. package/src/server/startup-action-control.ts +8 -1
  672. package/src/server/startup-health-cache.ts +19 -1
  673. package/src/server/system-env.ts +80 -9
  674. package/src/server/ws-bridge.ts +53 -40
  675. package/src/service-manager-probe.ts +892 -0
  676. package/src/service.ts +1153 -94
  677. package/src/sidecar/auth.ts +92 -0
  678. package/src/sidecar/candidates.ts +83 -0
  679. package/src/storage/cleanup.ts +2 -2
  680. package/src/storage/policy-job.ts +14 -4
  681. package/src/storage/policy.ts +88 -23
  682. package/src/storage/scanner.ts +1 -1
  683. package/src/storage/worker-lifecycle.ts +14 -14
  684. package/src/tray/windows-tray.ps1 +83 -9
  685. package/src/tray/windows.ts +43 -16
  686. package/src/types/accounts.ts +37 -0
  687. package/src/types/config.ts +911 -0
  688. package/src/types/provider.ts +614 -0
  689. package/src/types/request.ts +397 -0
  690. package/src/types/tools.ts +236 -0
  691. package/src/types/wire.ts +80 -0
  692. package/src/types.ts +107 -1237
  693. package/src/update/index.ts +37 -23
  694. package/src/update/job.ts +445 -68
  695. package/src/update/notify.ts +12 -6
  696. package/src/update/npm-cache-preflight.d.mts +47 -0
  697. package/src/update/npm-cache-preflight.mjs +201 -0
  698. package/src/update/transactional-install.d.mts +22 -0
  699. package/src/update/transactional-install.mjs +266 -0
  700. package/src/usage/cost.ts +0 -0
  701. package/src/usage/expected-prices.ts +287 -16
  702. package/src/usage/log.ts +666 -50
  703. package/src/usage/summary.ts +388 -17
  704. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  705. package/src/usage/user-cost-overlays.ts +314 -0
  706. package/src/vision/anthropic-describe.ts +10 -6
  707. package/src/vision/backends.ts +97 -0
  708. package/src/vision/describe.ts +27 -16
  709. package/src/vision/eligibility.ts +250 -0
  710. package/src/vision/index.ts +238 -24
  711. package/src/vision/reasoning.ts +55 -0
  712. package/src/vision/routed-describe.ts +175 -0
  713. package/src/vision/timeout-bounds.ts +9 -0
  714. package/src/web-search/anthropic-executor.ts +13 -7
  715. package/src/web-search/backends.ts +108 -0
  716. package/src/web-search/exa-executor.ts +119 -0
  717. package/src/web-search/executor.ts +21 -6
  718. package/src/web-search/gemini-executor.ts +141 -0
  719. package/src/web-search/index.ts +150 -15
  720. package/src/web-search/loop.ts +284 -54
  721. package/src/web-search/parse.ts +125 -30
  722. package/src/web-search/sources.ts +60 -0
  723. package/src/web-search/xai-executor.ts +219 -0
  724. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  725. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  726. package/gui/dist/provider-icons/antigravity.svg +0 -1
  727. package/gui/dist/provider-icons/claude.svg +0 -1
  728. package/gui/dist/provider-icons/copilot.svg +0 -1
  729. package/gui/dist/provider-icons/cursor.svg +0 -2
  730. package/gui/dist/provider-icons/gemini.svg +0 -1
  731. package/gui/dist/provider-icons/grok-color.svg +0 -1
  732. package/gui/dist/provider-icons/kiro.svg +0 -14
  733. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Production host integration for CL-03 trusted exact-route execution.
3
+ *
4
+ * Issues a host-recognized `TrustedLabRouteExecutor` that routes provider traffic
5
+ * through the CL-03 credential lease, pinned transport, and observation normalization
6
+ * pipeline. Secret material stays outside Lab modules.
7
+ *
8
+ * @internal host integration only
9
+ */
10
+ import { resolveEnvValue } from "../config";
11
+ import {
12
+ getValidAccessTokenSnapshot,
13
+ OAuthLoginRequiredError,
14
+ UnsupportedOAuthProviderError,
15
+ } from "../oauth";
16
+ import type { OcxConfig } from "../types";
17
+ import { createCredentialLease } from "../lab/live/credential-lease";
18
+ import {
19
+ liveUpstreamRequestPath,
20
+ normalizeLabLiveTransportObservation,
21
+ } from "../lab/live/executor";
22
+ import { createPinnedTransport } from "../lab/live/transport";
23
+ import { TransportError } from "../lab/live/transport";
24
+ import type { LabRouteContext } from "../lab/live/types";
25
+ import { createLabAuthorizedPinnedSender } from "./lab-live-pinned-sender";
26
+ import { createHostIssuedLabRouteExecutor } from "./lab-live-host";
27
+ import type { TrustedLabRouteExecutor } from "../lab/live/types";
28
+
29
+ const CREDENTIAL_HEADER = /(authorization|api[-_]?key|token|secret|credential|cookie)/i;
30
+
31
+ export interface ProductionLabRouteExecutorDeps {
32
+ configDir?: string;
33
+ loadConfig: () => OcxConfig;
34
+ }
35
+
36
+ async function buildLabProviderAuthHeaders(
37
+ routeContext: LabRouteContext,
38
+ config: OcxConfig,
39
+ ): Promise<Record<string, string>> {
40
+ const provider = config.providers?.[routeContext.providerId];
41
+ if (!provider || provider.disabled === true) {
42
+ throw new TransportError("auth_blocked", "provider unavailable");
43
+ }
44
+ if (provider.authMode === "forward") {
45
+ throw new TransportError("auth_blocked", "forward auth unsupported for lab probes");
46
+ }
47
+ if (provider.authMode === "local") {
48
+ throw new TransportError("auth_blocked", "local provider unsupported for lab probes");
49
+ }
50
+
51
+ const headers: Record<string, string> = {
52
+ Accept: "application/json",
53
+ "Content-Type": "application/json",
54
+ };
55
+
56
+ if (provider.authMode === "oauth") {
57
+ let protocol: string;
58
+ try {
59
+ protocol = new URL(routeContext.baseUrl).protocol;
60
+ } catch {
61
+ throw new TransportError("auth_blocked", "invalid OAuth provider destination");
62
+ }
63
+ if (protocol !== "https:") {
64
+ throw new TransportError("auth_blocked", "OAuth lab probes require HTTPS");
65
+ }
66
+ try {
67
+ const snapshot = await getValidAccessTokenSnapshot(routeContext.providerId);
68
+ headers.Authorization = `Bearer ${snapshot.accessToken}`;
69
+ } catch (error) {
70
+ if (error instanceof OAuthLoginRequiredError || error instanceof UnsupportedOAuthProviderError) {
71
+ throw new TransportError("auth_blocked", "oauth unavailable");
72
+ }
73
+ // Non-terminal refresh failures (network, lock contention, provider transient errors)
74
+ // are harness/infrastructure failures rather than evidence that credentials are invalid.
75
+ throw new TransportError("harness_failure", "oauth refresh unavailable");
76
+ }
77
+ } else {
78
+ const apiKey = resolveEnvValue(provider.apiKey)?.trim();
79
+ if (!apiKey) throw new TransportError("auth_blocked", "missing api key");
80
+ if (provider.adapter === "anthropic" && provider.apiKeyTransport === "x-api-key") {
81
+ headers["x-api-key"] = apiKey;
82
+ } else {
83
+ headers.Authorization = `Bearer ${apiKey}`;
84
+ }
85
+ }
86
+
87
+ if (provider.headers) {
88
+ for (const [name, value] of Object.entries(provider.headers)) {
89
+ if (CREDENTIAL_HEADER.test(name)) continue;
90
+ const resolved = resolveEnvValue(value);
91
+ headers[name] = typeof resolved === "string" ? resolved : value;
92
+ }
93
+ }
94
+
95
+ return headers;
96
+ }
97
+
98
+ /** Create the process-local trusted CL-03 route executor for Lab automation dispatch. */
99
+ export function createProductionLabRouteExecutor(
100
+ deps: ProductionLabRouteExecutorDeps,
101
+ ): TrustedLabRouteExecutor {
102
+ return createHostIssuedLabRouteExecutor(async (input) => {
103
+ if (!input.initiatingRequest) {
104
+ throw new TransportError("harness_failure", "live scenario missing initiating request");
105
+ }
106
+ const config = deps.loadConfig();
107
+ const lease = createCredentialLease({
108
+ destination: input.destination,
109
+ transportId: "lab-automation",
110
+ budget: input.limits.maxRequests,
111
+ });
112
+ const authHeaders = await buildLabProviderAuthHeaders(input.routeContext, config);
113
+ const sender = createLabAuthorizedPinnedSender(async () => authHeaders);
114
+ const transport = createPinnedTransport({
115
+ destination: input.destination,
116
+ lease,
117
+ sender,
118
+ limits: input.limits,
119
+ transportId: "lab-automation",
120
+ });
121
+ const path = liveUpstreamRequestPath(input.routeContext.upstreamProtocol);
122
+ const response = await transport.request({
123
+ method: "POST",
124
+ path,
125
+ body: input.initiatingRequest,
126
+ signal: input.signal,
127
+ });
128
+ return normalizeLabLiveTransportObservation(input.routeContext, response);
129
+ });
130
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Registers Compatibility Lab's passive route-subject linker into the core slot.
3
+ *
4
+ * Imported only from the Lab activation path, never from the request path. This module
5
+ * lives outside `src/lab/` for the same reason the other `src/lib/lab-*.ts` host
6
+ * integrations do: it is the seam between core and the subsystem, not the subsystem.
7
+ *
8
+ * @internal host integration only
9
+ */
10
+ import { setPassiveRouteLinker } from "../server/passive-route-linker";
11
+ import { resolveProductionRouteSubject } from "../routing/compatibility/subject";
12
+
13
+ /** Install the Lab linker. Returns a detach function. */
14
+ export function registerLabPassiveRouteLinker(configDir?: string): () => void {
15
+ return setPassiveRouteLinker((config, providerName, modelId, routed, inboundWire) => {
16
+ const subject = resolveProductionRouteSubject(
17
+ config,
18
+ providerName,
19
+ modelId,
20
+ routed,
21
+ inboundWire,
22
+ configDir,
23
+ );
24
+ return subject ? subject.subjectId : null;
25
+ });
26
+ }
@@ -0,0 +1,51 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
2
+
3
+ export const LOCAL_ATTESTATION_CHALLENGE_HEADER = "x-opencodex-attestation-challenge";
4
+ export const LOCAL_ATTESTATION_PROOF_HEADER = "x-opencodex-attestation-proof";
5
+
6
+ const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
7
+
8
+ export function isLocalAttestationSecret(value: unknown): value is string {
9
+ return typeof value === "string" && BASE64URL_256.test(value);
10
+ }
11
+
12
+ export function createLocalAttestationSecret(): string {
13
+ return randomBytes(32).toString("base64url");
14
+ }
15
+
16
+ export function createLocalAttestationChallenge(): string {
17
+ return randomBytes(32).toString("base64url");
18
+ }
19
+
20
+ function attestationPayload(challenge: string, pid: number, port: number): string | null {
21
+ if (!BASE64URL_256.test(challenge)) return null;
22
+ if (!Number.isSafeInteger(pid) || pid <= 0) return null;
23
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
24
+ return `opencodex-local-management-v1\n${challenge}\n${pid}\n${port}`;
25
+ }
26
+
27
+ export function createLocalAttestationProof(
28
+ secret: string,
29
+ challenge: string,
30
+ pid: number,
31
+ port: number,
32
+ ): string | null {
33
+ if (!isLocalAttestationSecret(secret)) return null;
34
+ const payload = attestationPayload(challenge, pid, port);
35
+ if (!payload) return null;
36
+ return createHmac("sha256", secret).update(payload).digest("base64url");
37
+ }
38
+
39
+ export function verifyLocalAttestationProof(
40
+ secret: string,
41
+ challenge: string,
42
+ pid: number,
43
+ port: number,
44
+ proof: string | null,
45
+ ): boolean {
46
+ const expected = createLocalAttestationProof(secret, challenge, pid, port);
47
+ if (!expected || !proof || !BASE64URL_256.test(proof)) return false;
48
+ const expectedBytes = Buffer.from(expected);
49
+ const actualBytes = Buffer.from(proof);
50
+ return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
51
+ }
@@ -0,0 +1,100 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { isLocalAttestationSecret } from "./local-management-attestation";
3
+
4
+ export const LOCAL_MANAGEMENT_EXPECTED_PID_HEADER = "x-opencodex-local-expected-pid";
5
+ export const LOCAL_MANAGEMENT_NONCE_HEADER = "x-opencodex-local-nonce";
6
+ export const LOCAL_MANAGEMENT_CAPABILITY_EXPIRES_AT_HEADER = "x-opencodex-local-expires-at";
7
+ export const LOCAL_MANAGEMENT_CAPABILITY_HEADER = "x-opencodex-local-capability";
8
+ export const LOCAL_MANAGEMENT_CAPABILITY_TTL_MS = 10_000;
9
+
10
+ export const LOCAL_MANAGEMENT_READ_PATHS = {
11
+ codexAccounts: "/api/codex-auth/accounts",
12
+ systemMemory: "/api/system/memory",
13
+ } as const;
14
+
15
+ export type LocalManagementReadPath =
16
+ typeof LOCAL_MANAGEMENT_READ_PATHS[keyof typeof LOCAL_MANAGEMENT_READ_PATHS];
17
+
18
+ const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
19
+ const LOCAL_READ_METHOD = "GET";
20
+
21
+ export type ExpectedLocalManagementPid =
22
+ | { kind: "absent" }
23
+ | { kind: "invalid" }
24
+ | { kind: "present"; pid: number };
25
+
26
+ export function parseExpectedLocalManagementPid(value: string | null): ExpectedLocalManagementPid {
27
+ if (value === null) return { kind: "absent" };
28
+ if (!/^[1-9]\d*$/.test(value)) return { kind: "invalid" };
29
+ const pid = Number(value);
30
+ return Number.isSafeInteger(pid) ? { kind: "present", pid } : { kind: "invalid" };
31
+ }
32
+
33
+ function isLocalManagementReadPath(path: string): path is LocalManagementReadPath {
34
+ return path === LOCAL_MANAGEMENT_READ_PATHS.codexAccounts
35
+ || path === LOCAL_MANAGEMENT_READ_PATHS.systemMemory;
36
+ }
37
+
38
+ function localReadCapabilityPayload(
39
+ nonce: string,
40
+ method: string,
41
+ path: string,
42
+ pid: number,
43
+ port: number,
44
+ expiresAt: number,
45
+ ): string | null {
46
+ if (!BASE64URL_256.test(nonce)) return null;
47
+ if (method !== LOCAL_READ_METHOD || !isLocalManagementReadPath(path)) return null;
48
+ if (!Number.isSafeInteger(pid) || pid <= 0) return null;
49
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
50
+ if (!Number.isSafeInteger(expiresAt) || expiresAt <= 0) return null;
51
+ return `opencodex-local-management-read-v1\n${nonce}\n${method}\n${path}\n${pid}\n${port}\n${expiresAt}`;
52
+ }
53
+
54
+ /** Process-scoped authorization for one allowlisted local management GET. */
55
+ export function createLocalManagementReadCapability(
56
+ secret: string,
57
+ nonce: string,
58
+ method: string,
59
+ path: string,
60
+ pid: number,
61
+ port: number,
62
+ expiresAt: number,
63
+ ): string | null {
64
+ if (!isLocalAttestationSecret(secret)) return null;
65
+ const payload = localReadCapabilityPayload(nonce, method, path, pid, port, expiresAt);
66
+ if (!payload) return null;
67
+ return createHmac("sha256", secret).update(payload).digest("base64url");
68
+ }
69
+
70
+ export function verifyLocalManagementReadCapability(
71
+ secret: string,
72
+ nonce: string | null,
73
+ method: string,
74
+ path: string,
75
+ pid: number,
76
+ port: number,
77
+ expiresAt: number,
78
+ capability: string | null,
79
+ now = Date.now(),
80
+ ): boolean {
81
+ if (!nonce || !capability || !BASE64URL_256.test(capability)) return false;
82
+ if (
83
+ !Number.isSafeInteger(now)
84
+ || expiresAt <= now
85
+ || expiresAt > now + LOCAL_MANAGEMENT_CAPABILITY_TTL_MS
86
+ ) return false;
87
+ const expected = createLocalManagementReadCapability(
88
+ secret,
89
+ nonce,
90
+ method,
91
+ path,
92
+ pid,
93
+ port,
94
+ expiresAt,
95
+ );
96
+ if (!expected) return false;
97
+ const expectedBytes = Buffer.from(expected);
98
+ const actualBytes = Buffer.from(capability);
99
+ return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
100
+ }
@@ -0,0 +1,100 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { isLocalAttestationSecret } from "./local-management-attestation";
3
+
4
+ export const LOCAL_PROVIDER_RELOAD_METHOD = "POST";
5
+ export const LOCAL_PROVIDER_RELOAD_PATH = "/api/providers/reload";
6
+ export const LOCAL_PROVIDER_RELOAD_CAPABILITY_VERSION = "v1";
7
+ export const LOCAL_PROVIDER_RELOAD_EXPECTED_PID_HEADER = "x-opencodex-provider-reload-expected-pid";
8
+ export const LOCAL_PROVIDER_RELOAD_NONCE_HEADER = "x-opencodex-provider-reload-nonce";
9
+ export const LOCAL_PROVIDER_RELOAD_EXPIRES_AT_HEADER = "x-opencodex-provider-reload-expires-at";
10
+ export const LOCAL_PROVIDER_RELOAD_NAME_HEADER = "x-opencodex-provider-reload-name";
11
+ export const LOCAL_PROVIDER_RELOAD_CAPABILITY_HEADER = "x-opencodex-provider-reload-capability";
12
+ export const LOCAL_PROVIDER_RELOAD_CAPABILITY_TTL_MS = 10_000;
13
+
14
+ const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
15
+ const PROVIDER_NAME = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62}[A-Za-z0-9])?$/;
16
+
17
+ export type ExpectedLocalProviderReloadPid =
18
+ | { kind: "absent" }
19
+ | { kind: "invalid" }
20
+ | { kind: "present"; pid: number };
21
+
22
+ export function parseExpectedLocalProviderReloadPid(value: string | null): ExpectedLocalProviderReloadPid {
23
+ if (value === null) return { kind: "absent" };
24
+ if (!/^[1-9]\d*$/.test(value)) return { kind: "invalid" };
25
+ const pid = Number(value);
26
+ return Number.isSafeInteger(pid) ? { kind: "present", pid } : { kind: "invalid" };
27
+ }
28
+
29
+ export function isLocalProviderReloadName(value: unknown): value is string {
30
+ return typeof value === "string" && PROVIDER_NAME.test(value);
31
+ }
32
+
33
+ function capabilityPayload(
34
+ nonce: string,
35
+ method: string,
36
+ path: string,
37
+ name: string,
38
+ pid: number,
39
+ port: number,
40
+ expiresAt: number,
41
+ ): string | null {
42
+ if (!BASE64URL_256.test(nonce)) return null;
43
+ if (method !== LOCAL_PROVIDER_RELOAD_METHOD || path !== LOCAL_PROVIDER_RELOAD_PATH) return null;
44
+ if (!isLocalProviderReloadName(name)) return null;
45
+ if (!Number.isSafeInteger(pid) || pid <= 0) return null;
46
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
47
+ if (!Number.isSafeInteger(expiresAt) || expiresAt <= 0) return null;
48
+ return `opencodex-local-provider-reload-v1\n${nonce}\n${method}\n${path}\n${name}\n${pid}\n${port}\n${expiresAt}`;
49
+ }
50
+
51
+ /** Process-scoped authorization to reload one named provider from protected disk state. */
52
+ export function createLocalProviderReloadCapability(
53
+ secret: string,
54
+ nonce: string,
55
+ method: string,
56
+ path: string,
57
+ name: string,
58
+ pid: number,
59
+ port: number,
60
+ expiresAt: number,
61
+ ): string | null {
62
+ if (!isLocalAttestationSecret(secret)) return null;
63
+ const payload = capabilityPayload(nonce, method, path, name, pid, port, expiresAt);
64
+ if (!payload) return null;
65
+ return createHmac("sha256", secret).update(payload).digest("base64url");
66
+ }
67
+
68
+ export function verifyLocalProviderReloadCapability(
69
+ secret: string,
70
+ nonce: string | null,
71
+ method: string,
72
+ path: string,
73
+ name: string | null,
74
+ pid: number,
75
+ port: number,
76
+ expiresAt: number,
77
+ capability: string | null,
78
+ now = Date.now(),
79
+ ): boolean {
80
+ if (!nonce || !name || !capability || !BASE64URL_256.test(capability)) return false;
81
+ if (
82
+ !Number.isSafeInteger(now)
83
+ || expiresAt <= now
84
+ || expiresAt > now + LOCAL_PROVIDER_RELOAD_CAPABILITY_TTL_MS
85
+ ) return false;
86
+ const expected = createLocalProviderReloadCapability(
87
+ secret,
88
+ nonce,
89
+ method,
90
+ path,
91
+ name,
92
+ pid,
93
+ port,
94
+ expiresAt,
95
+ );
96
+ if (!expected) return false;
97
+ const expectedBytes = Buffer.from(expected);
98
+ const actualBytes = Buffer.from(capability);
99
+ return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
100
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Core-owned registry for optional-subsystem shutdown work.
3
+ *
4
+ * The proxy core must not import an optional subsystem merely to be able to stop it.
5
+ * Compatibility Lab is the first case: `server/lifecycle.ts` imported
6
+ * `lab/automation/orchestrator` for two teardown calls, and that single edge closed an
7
+ * import cycle (`routing/compatibility/assemble` → `routing/quota` → `providers/quota` →
8
+ * `codex/auth-api` → `codex/native-main-admission` → `server/lifecycle` → Lab) that pulled
9
+ * ~69 `src/lab/` modules into the graph of every install, including installs with no
10
+ * routing profile at all.
11
+ *
12
+ * A subsystem registers its teardown when it activates. A process that never activates it
13
+ * registers nothing, so shutdown does no work and loads no module.
14
+ *
15
+ * Hooks are synchronous and best-effort by contract: `drainAndShutdown` runs under an
16
+ * absolute deadline, so a hook that throws must not prevent its siblings — or
17
+ * `server.stop` — from running.
18
+ *
19
+ * See devlog/_fin/260814_lab_core_decoupling/010_lifecycle_shutdown_registry.md
20
+ */
21
+
22
+ type ShutdownHook = () => void;
23
+
24
+ const hooks = new Map<string, ShutdownHook>();
25
+
26
+ /**
27
+ * Register (or replace) the teardown for one optional subsystem.
28
+ *
29
+ * Keyed so repeated activation of the same subsystem cannot accumulate duplicate hooks.
30
+ * Returns a detach function so an owner-scoped lease can release its registration.
31
+ */
32
+ export function registerOptionalShutdownHook(key: string, hook: ShutdownHook): () => void {
33
+ hooks.set(key, hook);
34
+ return () => {
35
+ // Only detach our own registration: a later activation may have replaced it.
36
+ if (hooks.get(key) === hook) hooks.delete(key);
37
+ };
38
+ }
39
+
40
+ /** Run every registered teardown. Never throws. */
41
+ export function runOptionalShutdownHooks(): void {
42
+ for (const [key, hook] of [...hooks]) {
43
+ try {
44
+ hook();
45
+ } catch (err) {
46
+ console.warn(
47
+ `[shutdown] optional subsystem "${key}" teardown failed:`,
48
+ err instanceof Error ? err.message : err,
49
+ );
50
+ }
51
+ }
52
+ }
53
+
54
+ /** Test-only reset so an isolated lifecycle test does not inherit registrations. */
55
+ export function resetOptionalShutdownHooksForTests(): void {
56
+ hooks.clear();
57
+ }
@@ -0,0 +1,101 @@
1
+ import { statSync } from "node:fs";
2
+
3
+ export interface PackageTreeObservation {
4
+ readonly device: bigint;
5
+ readonly inode: bigint;
6
+ readonly contentTimeNs: bigint;
7
+ readonly size: bigint;
8
+ }
9
+
10
+ export type PackageTreeIntegrityStatus =
11
+ | { readonly ok: true }
12
+ | { readonly ok: false; readonly reason: "package_tree_replaced" | "package_tree_unreadable" };
13
+
14
+ export interface PackageTreeIntegrityGuard {
15
+ status(): PackageTreeIntegrityStatus;
16
+ }
17
+
18
+ type ObservePackageTree = () => PackageTreeObservation | null;
19
+ type PackageTreeRuntimeInstall = "bun" | "npm" | "source";
20
+
21
+ const packageManifestUrl = new URL("../../package.json", import.meta.url);
22
+
23
+ function observePackageManifest(): PackageTreeObservation | null {
24
+ try {
25
+ const stat = statSync(packageManifestUrl, { bigint: true });
26
+ return {
27
+ device: stat.dev,
28
+ inode: stat.ino,
29
+ // mtimeNs, NOT ctimeNs. An inode-change time moves for METADATA writes that
30
+ // replace nothing: chmod, chown, touch, an editor normalizing permissions, a
31
+ // backup tool restoring modes. Each of those left device, inode and size
32
+ // identical, so the comparison below called the manifest "replaced" and every
33
+ // /v1/* request answered 503 until the process was restarted. Measured on
34
+ // macOS: chmod alone moved ctimeNs and left mtimeNs untouched.
35
+ //
36
+ // mtimeNs still catches every real replacement. An in-place rewrite of the
37
+ // same byte length moves mtimeNs while inode and size hold; an atomic
38
+ // install (write-then-rename, which is what a package manager does) changes
39
+ // the inode as well. Both were measured before this change was made.
40
+ contentTimeNs: stat.mtimeNs,
41
+ size: stat.size,
42
+ };
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+
48
+ function sameObservation(left: PackageTreeObservation, right: PackageTreeObservation): boolean {
49
+ return left.device === right.device
50
+ && left.inode === right.inode
51
+ && left.contentTimeNs === right.contentTimeNs
52
+ && left.size === right.size;
53
+ }
54
+
55
+ /**
56
+ * How long an `ok` observation is reused before the manifest is stat'd again.
57
+ *
58
+ * `status()` runs on `/healthz`, `/readyz` and every `/v1/*` request, so an unthrottled guard
59
+ * adds a filesystem syscall to the proxy's hot path to detect an event that happens at most
60
+ * once per install. A replaced tree is not time-critical either: the process is already
61
+ * serving broken imports, and one more second of that is not worse than a syscall per turn
62
+ * forever.
63
+ *
64
+ * A NEGATIVE result is never cached — once the tree looks wrong, every later request re-checks,
65
+ * so a repaired install recovers on its own instead of staying refused for a window.
66
+ */
67
+ const PACKAGE_TREE_RECHECK_MS = 1_000;
68
+
69
+ export function createPackageTreeIntegrityGuard(
70
+ observe: ObservePackageTree = observePackageManifest,
71
+ now: () => number = Date.now,
72
+ ): PackageTreeIntegrityGuard {
73
+ const boot = observe();
74
+ let lastOkAt: number | null = null;
75
+ return {
76
+ status(): PackageTreeIntegrityStatus {
77
+ const at = now();
78
+ if (lastOkAt !== null && at - lastOkAt < PACKAGE_TREE_RECHECK_MS) return { ok: true };
79
+ const current = observe();
80
+ if (boot === null || current === null) return { ok: false, reason: "package_tree_unreadable" };
81
+ if (!sameObservation(boot, current)) return { ok: false, reason: "package_tree_replaced" };
82
+ lastOkAt = at;
83
+ return { ok: true };
84
+ },
85
+ };
86
+ }
87
+
88
+ /**
89
+ * Installed packages fail closed when their manifest is replaced under a live process.
90
+ * A source checkout is different: editing package.json is ordinary development work, and
91
+ * Bun keeps serving the module snapshot already loaded by this process until the operator
92
+ * chooses to restart. Fencing every request there makes running dev directly impossible.
93
+ */
94
+ export function createRuntimePackageTreeIntegrityGuard(
95
+ installer: PackageTreeRuntimeInstall,
96
+ observe: ObservePackageTree = observePackageManifest,
97
+ now: () => number = Date.now,
98
+ ): PackageTreeIntegrityGuard {
99
+ if (installer === "source") return { status: () => ({ ok: true }) };
100
+ return createPackageTreeIntegrityGuard(observe, now);
101
+ }