@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
@@ -22,12 +22,26 @@
22
22
  * dashboard drain-and-restart confirm UX — never request bodies or IDs.
23
23
  */
24
24
  import { selectEagerPath } from "../../lib/bun-stream-caps";
25
+ import { reportedBunRuntimeSource } from "../../lib/bun-runtime";
25
26
  import { getActiveTurnCount, isDraining } from "../lifecycle";
26
27
  import { getActiveMemoryWatchdog, observedMemoryCounter } from "../memory-watchdog";
27
28
  import { responseStateMetrics } from "../../responses/state";
28
29
  import { appOwnedBytesSnapshot } from "../../lib/app-owned-memory";
30
+ import { readWindowsReplaceRetryCounters } from "../../lib/windows-atomic-replace";
31
+ import {
32
+ SYSTEM_RESTART_EXPECTED_PID_HEADER,
33
+ parseExpectedSystemRestartPid,
34
+ } from "../../lib/system-restart-contract";
35
+ import {
36
+ CODEX_APP_SERVER_STATE_PATH,
37
+ CODEX_RESTART_PATH,
38
+ } from "../../lib/codex-restart-contract";
29
39
  import { jsonResponse } from "../auth-cors";
30
40
  import { getInspectionCounters } from "../relay";
41
+ import type {
42
+ performCodexRestart,
43
+ readCodexAppServerState,
44
+ } from "../../codex/app-server-restart-service";
31
45
  import type { ManagementContext } from "./context";
32
46
  import { acceptSystemRestart } from "./system-restart";
33
47
 
@@ -78,6 +92,9 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
78
92
  pid: process.pid,
79
93
  bunVersion: Bun.version,
80
94
  bunRevision: Bun.revision,
95
+ // Recorded at launch, not resolved now: absent means "this service predates the
96
+ // marker", which callers must report as unknown rather than guess.
97
+ bunRuntimeSource: reportedBunRuntimeSource(),
81
98
  platform: process.platform,
82
99
  uptimeSeconds: process.uptime(),
83
100
  rss: usage.rss,
@@ -99,7 +116,37 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
99
116
  });
100
117
  }
101
118
 
119
+ /**
120
+ * Windows atomic-replace retry counters.
121
+ *
122
+ * A sibling route rather than a field on /api/system/memory: that payload is
123
+ * memory-shaped, and appending unrelated filesystem counters to it makes both
124
+ * harder to consume.
125
+ *
126
+ * Keys are `publisher:CODE` where publisher is a closed union
127
+ * (ReplacePublisher) and never a path — a path could carry a username. The
128
+ * type is what enforces that; a text scan cannot see a runtime value.
129
+ */
130
+ if (url.pathname === "/api/system/windows-replace-retries" && req.method === "GET") {
131
+ return jsonResponse({ counters: readWindowsReplaceRetryCounters() });
132
+ }
102
133
  if (url.pathname === "/api/system/restart" && req.method === "POST") {
134
+ const expectedPid = parseExpectedSystemRestartPid(
135
+ req.headers.get(SYSTEM_RESTART_EXPECTED_PID_HEADER),
136
+ );
137
+ if (expectedPid.kind === "invalid") {
138
+ return jsonResponse({
139
+ success: false,
140
+ error: "Invalid restart target identity.",
141
+ }, 400, req, config);
142
+ }
143
+ if (expectedPid.kind === "present" && expectedPid.pid !== process.pid) {
144
+ return jsonResponse({
145
+ success: false,
146
+ error: "Restart target identity changed.",
147
+ }, 409, req, config);
148
+ }
149
+
103
150
  // Longer informed drain than /api/stop; does not tear down Codex/Grok injection.
104
151
  const result = acceptSystemRestart();
105
152
  return jsonResponse({
@@ -113,5 +160,35 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
113
160
  }, 202, req, config);
114
161
  }
115
162
 
163
+ if (
164
+ (url.pathname === CODEX_APP_SERVER_STATE_PATH && req.method === "GET")
165
+ || (url.pathname === CODEX_RESTART_PATH && req.method === "POST")
166
+ ) {
167
+ // Resolved inside the path check, not at the top of this function: every
168
+ // /api/system/* request runs through here, and an unconditional import would
169
+ // pull the platform process-enumeration helpers into requests that never
170
+ // touch them.
171
+ // An explicit branch rather than `??`: the seam is an optional property, and
172
+ // narrowing through a nullish default keeps its `undefined` in the union.
173
+ let service: {
174
+ readState: typeof readCodexAppServerState;
175
+ performRestart: typeof performCodexRestart;
176
+ };
177
+ const injected = ctx.deps.codexRestartService;
178
+ if (injected) {
179
+ service = injected;
180
+ } else {
181
+ const module = await import("../../codex/app-server-restart-service");
182
+ service = {
183
+ readState: module.readCodexAppServerState,
184
+ performRestart: module.performCodexRestart,
185
+ };
186
+ }
187
+ if (req.method === "GET") {
188
+ return jsonResponse(service.readState(), 200, req, config);
189
+ }
190
+ return jsonResponse(await service.performRestart(), 200, req, config);
191
+ }
192
+
116
193
  return null;
117
194
  }
@@ -8,9 +8,17 @@ export type CachedUsageSummary = UsageSummary & {
8
8
  entriesDropped: number;
9
9
  };
10
10
 
11
- interface UsageSummaryCacheEntry {
11
+ export interface UsageSummaryCacheEntry {
12
12
  revisionKey: string;
13
+ /** path/dev/ino/birthtime only; appends keep this stable. */
14
+ identityKey: string;
15
+ maxReadBytes: number;
16
+ /** userCostOverlayVersion() when the summary was computed; overlay edits invalidate the entry. */
17
+ overlayVersion: number;
13
18
  expiresAt: number;
19
+ /** Generation freshness: ignore size/mtime until this instant. */
20
+ freshUntil: number;
21
+ lastSeenSize: number;
14
22
  summary: CachedUsageSummary;
15
23
  revisionReadAt: number;
16
24
  sizeBytes: number;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * The one place that decides which models the management API offers as vision
3
+ * describers, and which it refuses to persist.
4
+ *
5
+ * Two routes write a vision sidecar model — `PUT /api/sidecar-settings` and the
6
+ * `visionSidecar` override in `PUT /api/claude-code`. They share this module so
7
+ * the policy cannot drift: a gate on one route and a stale copy on the other is
8
+ * the same as no gate at all.
9
+ */
10
+ import type { OcxConfig } from "../../types";
11
+ import { findAnthropicVisionProvider, type AnthropicVisionProvider } from "../../vision";
12
+ import { VISION_BACKENDS } from "../../vision/backends";
13
+ import {
14
+ modelAcceptsImageInput,
15
+ visionEligibleModelOptions,
16
+ type VisionCandidateModel,
17
+ type VisionModelOption,
18
+ type VisionSidecarBackend,
19
+ } from "../../vision/eligibility";
20
+ import { pickerVisibleSidecarCandidates } from "../../sidecar/candidates";
21
+ import { resolveSidecarAuth } from "../../sidecar/auth";
22
+
23
+ /**
24
+ * Backends whose executor could actually run (#2188 roadmap 170): openai
25
+ * forward, anthropic OAuth, xai OAuth, Antigravity OAuth — resolved by the
26
+ * VISION_BACKENDS descriptor table so this module and the options path cannot
27
+ * drift on what "active" means.
28
+ *
29
+ * `anthropicSidecar` is REQUIRED rather than defaulted. `findAnthropicVisionProvider`
30
+ * reads the OAuth account store from disk, and a default argument made every helper
31
+ * in this chain re-resolve it whenever a caller passed an explicit `undefined` —
32
+ * which is exactly the no-executor case. Passing it in keeps one read per request.
33
+ * The descriptor table re-derives the anthropic flag from the shared auth
34
+ * module; asserting the caller's resolution stays consistent with it is the
35
+ * job of the shared module, not this file.
36
+ */
37
+ export function enabledVisionBackends(
38
+ config: OcxConfig,
39
+ anthropicSidecar: AnthropicVisionProvider | undefined,
40
+ ): VisionSidecarBackend[] {
41
+ const auth = resolveSidecarAuth(config);
42
+ // Preserve the caller's resolution for the anthropic side: the descriptor
43
+ // reads the shared auth module, but a caller that already resolved "no
44
+ // executor" must not see anthropic options it cannot dispatch. The filter
45
+ // applies to the ACTIVE set only — the fresh-install fallback below stays
46
+ // both universal sides, exactly the pre-widening behavior (test 6 pins it).
47
+ const active = VISION_BACKENDS
48
+ .filter(descriptor => descriptor.isActive(auth, config))
49
+ .map(descriptor => descriptor.backend)
50
+ .filter(backend => backend !== "anthropic" || anthropicSidecar !== undefined);
51
+ // "routed" is active by construction, so the fresh-install fallback keys on
52
+ // the UNIVERSAL sides: when neither resolves, both are offered so the picker
53
+ // stays populated (permissive-unknown rule; test 6 pins it).
54
+ if (!active.includes("openai") && !active.includes("anthropic")) {
55
+ return ["openai", "anthropic", ...active];
56
+ }
57
+ return active;
58
+ }
59
+
60
+ /**
61
+ * Visible catalog rows in the shape the eligibility predicate consumes.
62
+ * Sourced from the unified picker set (#2188): picker-visible rows ∪ auth
63
+ * slots, UNFILTERED. Rule 2 (− provably text-only) belongs to the OPTIONS
64
+ * path only (visionEligibleModelOptions already applies it). The PUT gate
65
+ * consumes this list as EVIDENCE: a picker row proving an id text-only is
66
+ * exactly what visionDescriberIsProvablyBlind needs to reject that id, so
67
+ * pre-filtering here would deaden the gate (review F1: reject → allow flip).
68
+ */
69
+ export async function visionCandidateRows(config: OcxConfig): Promise<VisionCandidateModel[]> {
70
+ const auth = resolveSidecarAuth(config);
71
+ const all = await pickerVisibleSidecarCandidates(config, auth);
72
+ return all.map(candidate => ({
73
+ provider: candidate.provider,
74
+ id: candidate.id,
75
+ ...(candidate.inputModalities ? { inputModalities: candidate.inputModalities } : {}),
76
+ ...(candidate.native ? { native: true } : {}),
77
+ }));
78
+ }
79
+
80
+ export function visionModelOptionsFrom(
81
+ config: OcxConfig,
82
+ candidates: readonly VisionCandidateModel[],
83
+ anthropicSidecar: AnthropicVisionProvider | undefined,
84
+ ): VisionModelOption[] {
85
+ return visionEligibleModelOptions(
86
+ config,
87
+ candidates,
88
+ enabledVisionBackends(config, anthropicSidecar),
89
+ anthropicSidecar?.providerName,
90
+ );
91
+ }
92
+
93
+ /** Convenience for read paths that have no candidate list in hand yet. */
94
+ export async function visionModelOptionsFor(
95
+ config: OcxConfig,
96
+ anthropicSidecar: AnthropicVisionProvider | undefined,
97
+ ): Promise<VisionModelOption[]> {
98
+ return visionModelOptionsFrom(config, await visionCandidateRows(config), anthropicSidecar);
99
+ }
100
+
101
+ /**
102
+ * Can we PROVE the requested describer is blind?
103
+ *
104
+ * Only a positive `false` rejects. An id no source knows stays allowed, because
105
+ * the runtime never required catalog membership and an operator may be ahead of
106
+ * our tables.
107
+ *
108
+ * When no catalog row matches, the caller's `backend` is only a HINT, never the
109
+ * authority. Trusting it let a client launder a known-blind OpenAI model past the
110
+ * gate by claiming `backend: "anthropic"`, since the id is absent from the
111
+ * Anthropic table and absence reads as "unknown".
112
+ *
113
+ * A NAMESPACED id ("provider/model", the routed-backend option shape) names
114
+ * its provider outright, so that provider's config row and metadata family
115
+ * are probed directly. A BARE id probes ALL configured provider families and
116
+ * any positive text-only verdict wins (roadmap 170: a bare `grok-4` is
117
+ * provably text-only in the xai vendor table and must not slip through a
118
+ * two-family probe). That is safe precisely because the vendor tables share
119
+ * no bare model id (collision scan in roadmap 160: openai 48, anthropic 26,
120
+ * xai 32, google 43, zero overlaps), so they can never disagree about one.
121
+ */
122
+ export function visionDescriberIsProvablyBlind(
123
+ config: OcxConfig,
124
+ requested: string,
125
+ candidates: readonly VisionCandidateModel[],
126
+ backendHint: VisionSidecarBackend | undefined,
127
+ ): boolean {
128
+ // Catalog rows can carry operator-authored modalities. A positive claim from one
129
+ // must not hide another row or canonical metadata that proves this id is blind.
130
+ if (candidates.some(candidate => candidate.id === requested
131
+ && modelAcceptsImageInput(config, candidate) === false)) return true;
132
+
133
+ // Namespaced routed id: the provider is named, probe it directly (config
134
+ // row enrichment + its metadata family both flow through the predicate).
135
+ const sep = requested.indexOf("/");
136
+ if (sep > 0) {
137
+ const provider = requested.slice(0, sep);
138
+ const id = requested.slice(sep + 1);
139
+ if (modelAcceptsImageInput(config, { provider, id }) === false) return true;
140
+ // A namespaced candidate row (value shape) may also carry the proof.
141
+ return candidates.some(candidate => candidate.provider === provider && candidate.id === id
142
+ && modelAcceptsImageInput(config, candidate) === false);
143
+ }
144
+
145
+ // Bare id: probe the base vendor families plus every configured provider —
146
+ // a positive text-only verdict from any source wins.
147
+ const families = new Set(["openai", "anthropic", "xai", "google-antigravity", ...Object.keys(config.providers ?? {})]);
148
+ const ordered = backendHint === "anthropic"
149
+ ? ["anthropic", ...[...families].filter(family => family !== "anthropic")]
150
+ : ["openai", ...[...families].filter(family => family !== "openai")];
151
+ return ordered.some(provider => modelAcceptsImageInput(config, { provider, id: requested }) === false);
152
+ }
153
+
154
+ /** The 400 body both routes return, so the two errors cannot diverge either. */
155
+ export function visionDescriberRejection(
156
+ field: "vision.model" | "visionSidecar.model",
157
+ requested: string,
158
+ config: OcxConfig,
159
+ candidates: readonly VisionCandidateModel[],
160
+ ): { error: string; allowed: string[] } {
161
+ return {
162
+ error: `${field} "${requested}" cannot describe images: it has no image input support, or it is a model the vision sidecar describes FOR.`,
163
+ // The rejection path is not hot, so it resolves the executor itself rather than
164
+ // making every 400 caller thread one through.
165
+ allowed: visionModelOptionsFrom(config, candidates, findAnthropicVisionProvider(config)).map(option => option.value),
166
+ };
167
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * The one place that decides which models the management API offers as the
3
+ * web-search sidecar, and which it refuses to persist (#2188).
4
+ *
5
+ * Two routes write `webSearchSidecar.model` — `PUT /api/sidecar-settings`
6
+ * and the `webSearchSidecar` override in `PUT /api/claude-code`. They share
7
+ * this module for the same reason the vision routes share
8
+ * vision-sidecar-options.ts: a gate on one route and a stale copy on the
9
+ * other is the same as no gate at all. `ocx config set` raw JSON writes
10
+ * bypass management gates by design (operator escape hatch, same as vision).
11
+ *
12
+ * Unlike vision's provably-blind gate (reject only on positive proof), the
13
+ * web-search gate is MEMBERSHIP: the executor set is closed and known, so an
14
+ * id outside (candidates ∪ auth slots) can never run and is refused.
15
+ */
16
+ import type { OcxConfig } from "../../types";
17
+ import { AUTH_SLOT_MODELS, resolveSidecarAuth } from "../../sidecar/auth";
18
+ import { pickerVisibleSidecarCandidates, type SidecarCandidate } from "../../sidecar/candidates";
19
+ import { WEB_SEARCH_BACKENDS, webSearchSidecarCandidates } from "../../web-search/backends";
20
+ import type { WebSearchBackendId } from "../../web-search/index";
21
+
22
+ // The full configured union. Rows only ever materialize for backends whose
23
+ // executor admits the candidate, so inert arms (gemini/exa without config)
24
+ // simply never produce rows.
25
+ export type WebSearchBackend = WebSearchBackendId;
26
+
27
+ export interface WebSearchCandidateRow extends SidecarCandidate {
28
+ /** Executor backend that admitted this exact candidate row. */
29
+ backend: WebSearchBackend;
30
+ }
31
+
32
+ export interface WebSearchModelOption {
33
+ value: string;
34
+ label: string;
35
+ /** Exact runnable pair represented by this picker row. */
36
+ backend: WebSearchBackend;
37
+ model: string;
38
+ /** True when the row is an auth-slot entitlement rather than a picker row. */
39
+ authSlot?: boolean;
40
+ }
41
+
42
+ /** The candidate rows the web-search executors can actually run right now. */
43
+ export async function webSearchCandidateRows(config: OcxConfig): Promise<WebSearchCandidateRow[]> {
44
+ const auth = resolveSidecarAuth(config);
45
+ const all = await pickerVisibleSidecarCandidates(config, auth);
46
+ return webSearchSidecarCandidates(config, auth, all).flatMap(candidate => {
47
+ const descriptor = WEB_SEARCH_BACKENDS.find(entry =>
48
+ entry.isActive(auth, config) && entry.eligibleModel(candidate, auth));
49
+ return descriptor ? [{ ...candidate, backend: descriptor.backend }] : [];
50
+ });
51
+ }
52
+
53
+ /**
54
+ * The GUI/CLI option list. The persisted model is display-grandfathered so an
55
+ * operator can SEE a now-illegal setting in the picker (parity with the vision
56
+ * GET); new writes of such an id are still rejected by the gate below.
57
+ */
58
+ export function webSearchModelOptionsFrom(
59
+ config: Pick<OcxConfig, "webSearchSidecar">,
60
+ candidates: readonly WebSearchCandidateRow[],
61
+ ): WebSearchModelOption[] {
62
+ const byValue = new Map<string, WebSearchModelOption>();
63
+ for (const candidate of candidates) {
64
+ if (byValue.has(candidate.id)) continue;
65
+ byValue.set(candidate.id, {
66
+ value: candidate.id,
67
+ label: candidate.id,
68
+ backend: candidate.backend,
69
+ model: candidate.id,
70
+ ...(candidate.authSlot ? { authSlot: true } : {}),
71
+ });
72
+ }
73
+ const persisted = config.webSearchSidecar?.model;
74
+ if (persisted && !byValue.has(persisted)) {
75
+ byValue.set(persisted, {
76
+ value: persisted,
77
+ label: persisted,
78
+ backend: config.webSearchSidecar?.backend ?? "openai",
79
+ model: persisted,
80
+ });
81
+ }
82
+ return [...byValue.values()].sort((a, b) => a.value.localeCompare(b.value));
83
+ }
84
+
85
+ /**
86
+ * Membership gate: reject when the id is neither a runnable candidate nor an
87
+ * auth-slot model. Auth slots pass even when the matching login is currently
88
+ * absent — the slot is a legal setting whose executor simply is not live yet,
89
+ * and refusing it would make settings order-dependent on login state.
90
+ */
91
+ export function webSearchModelIsRejected(
92
+ backend: WebSearchBackend,
93
+ requested: string,
94
+ candidates: readonly WebSearchCandidateRow[],
95
+ ): boolean {
96
+ if (requested === AUTH_SLOT_MODELS.codex) return backend !== "openai";
97
+ if (requested === AUTH_SLOT_MODELS.anthropic) return backend !== "anthropic";
98
+ return !candidates.some(candidate => candidate.backend === backend && candidate.id === requested);
99
+ }
100
+
101
+ /** Uniform 400 payload naming the filter, mirroring visionDescriberRejection's shape. */
102
+ export function webSearchModelRejection(
103
+ field: string,
104
+ backend: WebSearchBackend,
105
+ requested: string,
106
+ candidates: readonly WebSearchCandidateRow[],
107
+ ): { error: string; allowedModels: string[] } {
108
+ const allowed = new Set(candidates
109
+ .filter(candidate => candidate.backend === backend)
110
+ .map(candidate => candidate.id));
111
+ // Preserve the response contract: allowedModels lists both always-configurable
112
+ // auth-slot ids even though the pair gate below binds each to its own backend.
113
+ allowed.add(AUTH_SLOT_MODELS.codex);
114
+ allowed.add(AUTH_SLOT_MODELS.anthropic);
115
+ return {
116
+ error: `${field}: backend/model pair "${backend}/${requested}" is not a web-search sidecar candidate — ` +
117
+ "the model must be picker-visible and runnable by that executor-backed backend (or its auth-slot model)",
118
+ allowedModels: [...allowed].sort(),
119
+ };
120
+ }
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { readFileSync } from "node:fs";
3
3
  import type { CatalogModel } from "../codex/catalog";
4
- import { catalogModelSlug, invalidateCodexModelsCache, nativeModelRows, uniqueCatalogModelsForPublicList } from "../codex/catalog";
4
+ import { catalogModelSlug, invalidateCodexModelsCache, nativeContextLimits, nativeModelRows, uniqueCatalogModelsForPublicList } from "../codex/catalog";
5
5
  import {
6
6
  DEFAULT_SUBAGENT_MODELS,
7
7
  codexAutoStartEnabled,
@@ -28,7 +28,7 @@ import { deriveProviderPresets } from "../providers/derive";
28
28
  import { providerCodexAccountMode } from "../providers/registry";
29
29
  import { routedSlug, slugEquals } from "../providers/slug-codec";
30
30
  import { clearProviderQuotaCache, fetchProviderQuotaReports } from "../providers/quota";
31
- import { isCanonicalOpenAiForwardProvider } from "../providers/openai-tiers";
31
+ import { isCanonicalOpenAiForwardProvider, OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
32
32
  import { clearThreadAccountMap } from "../codex/routing";
33
33
  import { primeCodexPoolQuotas } from "../codex/auth-api";
34
34
  import { DEFAULT_PROVIDER_CONTEXT_CAP, globalContextCapValue, providerContextCap, providerContextCaps, setAllProviderContextCaps, setGlobalContextCapValue, setProviderContextCap } from "../providers/context-cap";
@@ -59,6 +59,9 @@ import { applySystemEnvToggle } from "./system-env";
59
59
  import type { ManagementApiDeps } from "./management/context";
60
60
  import { handleConfigRoutes } from "./management/config-routes";
61
61
  import { handleLogsUsageRoutes } from "./management/logs-usage-routes";
62
+ import { handleStorageLogGuardRoutes } from "./management/storage-log-guard-routes";
63
+ import { handleRequestHistoryRoutes } from "./management/request-history-routes";
64
+ import { handleRoutingAnalyticsRoutes } from "./management/routing-analytics-routes";
62
65
  import { handleProviderRoutes } from "./management/provider-routes";
63
66
  import { handleModelRoutes } from "./management/model-routes";
64
67
  import { handleAgentSettingsRoutes } from "./management/agent-settings-routes";
@@ -68,10 +71,16 @@ import { handleComboRoutes } from "./management/combo-routes";
68
71
  import { handleSystemRoutes } from "./management/system-routes";
69
72
  import { handleCloudSyncRoutes } from "./management/cloud-sync-routes";
70
73
  import { handleSidebarRoutes } from "./management/sidebar-routes";
74
+ import { handleCodexPromptRoutes } from "./management/codex-prompt-routes";
75
+ import { handleIntegrationRoutes } from "./management/integration-routes";
76
+ import { handleNativeIntegrationRoutes } from "./management/native-integration-routes";
71
77
  import type { ManagementContext } from "./management/context";
78
+ import type { ManagementPrincipal } from "./management-auth";
72
79
  export type { ManagementApiDeps } from "./management/context";
73
80
  import { fetchAllModels } from "./management/shared";
74
81
  import { CatalogGatherBusyError } from "../codex/catalog/provider-fetch";
82
+ import type { CatalogDisposition, ConvergeCodex } from "../codex/convergence-types";
83
+ import { normalizeCatalogDisposition } from "../codex/catalog-refresh-status";
75
84
  import { managementBodyTooLargeResponse } from "./management/body";
76
85
 
77
86
  // installed npm version instead of a stale hardcode.
@@ -83,7 +92,53 @@ export const VERSION = (() => {
83
92
  }
84
93
  })();
85
94
 
86
- export async function handleManagementAPI(req: Request, url: URL, config: OcxConfig, deps: ManagementApiDeps = {}): Promise<Response | null> {
95
+ const managementConvergenceBindings = new WeakMap<object, Readonly<{
96
+ factory: (config: Readonly<OcxConfig>) => ConvergeCodex;
97
+ converge: ConvergeCodex;
98
+ }>>();
99
+
100
+ /**
101
+ * Namespace match for management route prefixes: exact hit or a child path, never a
102
+ * prefix collision (`/api/labfoo` must not match `/api/lab`).
103
+ */
104
+ function pathInManagementNamespace(pathname: string, prefix: string): boolean {
105
+ return pathname === prefix || pathname.startsWith(`${prefix}/`);
106
+ }
107
+
108
+ /**
109
+ * Routing-profile and Compatibility Lab handlers statically import the Lab module graph,
110
+ * so mounting them eagerly would pull ~70 `src/lab/` modules into every management
111
+ * request -- including installs that never opted into Lab. Loading them per namespace
112
+ * keeps `management-api.ts` on the same footing as the three protected core files.
113
+ *
114
+ * Cherry-picked from @Wibias's PR #1676, which solved this before the boundary work
115
+ * reached it. See devlog/_fin/260814_lab_core_decoupling/.
116
+ */
117
+ async function handleRoutingProfileRoutesOnDemand(ctx: ManagementContext): Promise<Response | null> {
118
+ if (!pathInManagementNamespace(ctx.url.pathname, "/api/routing-profiles")) return null;
119
+ const { handleRoutingProfileRoutes } = await import("./management/routing-profile-routes");
120
+ return handleRoutingProfileRoutes(ctx);
121
+ }
122
+
123
+ async function handleLabRoutesOnDemand(ctx: ManagementContext): Promise<Response | null> {
124
+ if (!pathInManagementNamespace(ctx.url.pathname, "/api/lab")) return null;
125
+ // Automation is checked first so its narrower namespace keeps its own handler, matching
126
+ // the eager chain's ordering.
127
+ if (pathInManagementNamespace(ctx.url.pathname, "/api/lab/automation")) {
128
+ const { handleLabAutomationRoutes } = await import("./management/lab-automation-routes");
129
+ return handleLabAutomationRoutes(ctx);
130
+ }
131
+ const { handleLabRoutes } = await import("./management/lab-routes");
132
+ return handleLabRoutes(ctx);
133
+ }
134
+
135
+ export async function handleManagementAPI(
136
+ req: Request,
137
+ url: URL,
138
+ config: OcxConfig,
139
+ deps: ManagementApiDeps = {},
140
+ principal?: ManagementPrincipal,
141
+ ): Promise<Response | null> {
87
142
  if (!isAllowedManagementOrigin(req, config)) {
88
143
  return jsonResponse({ error: "cross-origin request blocked" }, 403, req, config);
89
144
  }
@@ -95,13 +150,48 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
95
150
  return jsonResponse({ error: "request body too large" }, 413, req, config);
96
151
  }
97
152
  }
98
- async function refreshCodexCatalogBestEffort(): Promise<void> {
99
- if (deps.refreshCodexCatalog) return deps.refreshCodexCatalog();
153
+ async function convergeCodexCatalog(): Promise<CatalogDisposition> {
154
+ let convergenceInvoked = false;
155
+ let managementConvergeCodex: ConvergeCodex | undefined;
100
156
  try {
101
- const { refreshCodexModelCatalog } = await import("../codex/refresh");
102
- await refreshCodexModelCatalog(config);
103
- } catch {
104
- /* catalog absent */
157
+ if (!managementConvergeCodex) {
158
+ const factory = deps.createManagementConvergeCodex
159
+ ?? (await import("../codex/management-convergence")).createManagementConvergeCodex;
160
+ if (typeof factory !== "function") throw new TypeError("Catalog convergence factory is unavailable.");
161
+ let binding = managementConvergenceBindings.get(config);
162
+ if (!binding || binding.factory !== factory) {
163
+ const created = factory(config);
164
+ if (typeof created !== "function") throw new TypeError("Catalog convergence factory returned no function.");
165
+ binding = { factory, converge: created };
166
+ managementConvergenceBindings.set(config, binding);
167
+ }
168
+ managementConvergeCodex = binding.converge;
169
+ }
170
+ const { createCatalogConvergeRequest } = await import("../codex/catalog-admission");
171
+ convergenceInvoked = true;
172
+ const outcome = await managementConvergeCodex(createCatalogConvergeRequest({ deadlineMs: 1_000 }));
173
+ const catalogRefresh = outcome?.kind === "catalog-only"
174
+ ? normalizeCatalogDisposition(outcome.catalogRefresh)
175
+ : null;
176
+ if (!catalogRefresh) {
177
+ throw new TypeError("Catalog convergence returned an invalid outcome.");
178
+ }
179
+ return catalogRefresh;
180
+ } catch (error) {
181
+ // #1784: this used to manufacture `reason: "disk"` for every escaping error, so a
182
+ // programming fault and a full filesystem were indistinguishable and both reported
183
+ // non-retryable. Classify honestly and keep the cause allowlisted.
184
+ const invalidRequest = error instanceof TypeError
185
+ || error instanceof RangeError
186
+ || error instanceof SyntaxError;
187
+ return {
188
+ status: "failed",
189
+ reason: invalidRequest ? "request-invalid" : "internal",
190
+ phase: convergenceInvoked ? "commit" : "gather",
191
+ retryable: false,
192
+ partialWrite: convergenceInvoked,
193
+ cause: { kind: invalidRequest ? "invalid-request" : "unknown" },
194
+ };
105
195
  }
106
196
  }
107
197
 
@@ -118,7 +208,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
118
208
  import("../claude/context-windows"),
119
209
  import("../codex/catalog"),
120
210
  ]);
121
- injectClaudeAgentDefs(config, buildClaudeContextWindows([...visibleNativeSlugs(config)], models));
211
+ injectClaudeAgentDefs(config, buildClaudeContextWindows([...visibleNativeSlugs(config)], models, nativeContextLimits(config)));
122
212
  } catch {
123
213
  // Keep routes available through a provider-discovery blip. A later
124
214
  // launch-time sync restores any context markers missing from this pass.
@@ -126,19 +216,27 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
126
216
  }
127
217
  } catch { /* best-effort */ }
128
218
  }
129
- const ctx: ManagementContext = { req, url, config, deps, refreshCodexCatalogBestEffort, syncClaudeAgentDefsBestEffort };
219
+ const ctx: ManagementContext = { req, url, config, deps, principal, convergeCodexCatalog, syncClaudeAgentDefsBestEffort };
130
220
  let routed: Response | null;
131
221
  try {
132
222
  routed = (await handleConfigRoutes(ctx))
133
- ?? (await handleLogsUsageRoutes(ctx))
134
- ?? (await handleProviderRoutes(ctx))
135
- ?? (await handleModelRoutes(ctx))
136
- ?? (await handleAgentSettingsRoutes(ctx))
137
- ?? (await handleClientsRoutes(ctx))
138
- ?? (await handleOauthAccountRoutes(ctx))
139
- ?? (await handleComboRoutes(ctx))
140
- ?? (await handleSystemRoutes(ctx))
141
- ?? (await handleCloudSyncRoutes(ctx))
223
+ ?? (await handleStorageLogGuardRoutes(ctx))
224
+ ?? (await handleLogsUsageRoutes(ctx))
225
+ ?? (await handleRequestHistoryRoutes(ctx))
226
+ ?? (await handleRoutingAnalyticsRoutes(ctx))
227
+ ?? (await handleRoutingProfileRoutesOnDemand(ctx))
228
+ ?? (await handleProviderRoutes(ctx))
229
+ ?? (await handleModelRoutes(ctx))
230
+ ?? (await handleIntegrationRoutes(ctx))
231
+ ?? (await handleNativeIntegrationRoutes(ctx))
232
+ ?? (await handleAgentSettingsRoutes(ctx))
233
+ ?? (await handleCodexPromptRoutes(ctx))
234
+ ?? (await handleClientsRoutes(ctx))
235
+ ?? (await handleOauthAccountRoutes(ctx))
236
+ ?? (await handleComboRoutes(ctx))
237
+ ?? (await handleSystemRoutes(ctx))
238
+ ?? (await handleCloudSyncRoutes(ctx))
239
+ ?? (await handleLabRoutesOnDemand(ctx))
142
240
  ?? (await handleSidebarRoutes(ctx));
143
241
  } catch (error) {
144
242
  const tooLarge = managementBodyTooLargeResponse(error, req, config);
@@ -158,7 +256,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
158
256
  if (routed) return routed;
159
257
 
160
258
  if (url.pathname === "/api/stop" && req.method === "POST") {
161
- const { restoreNativeCodex } = await import("../codex/inject");
259
+ const { restoreNativeCodexAsync } = await import("../codex/inject");
162
260
  const { stopServiceIfInstalled, isServiceOwnershipError } = await import("../service");
163
261
  try {
164
262
  stopServiceIfInstalled();
@@ -171,7 +269,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
171
269
  }
172
270
  throw err;
173
271
  }
174
- const restore = restoreNativeCodex();
272
+ const restore = await restoreNativeCodexAsync();
175
273
  // Both managed configs come down together on an explicit teardown. The daemon's own
176
274
  // syncCleanup skips this when OCX_SERVICE is set (so a crash/respawn keeps the fence),
177
275
  // which is exactly why an intentional stop has to do it here.
@@ -187,12 +285,17 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
187
285
  : { success: false, message: `Proxy stopping, but native Codex restore failed: ${restore.message}. Run \`ocx restore\`.${grokNote}` });
188
286
  }
189
287
 
288
+ if (url.pathname.startsWith("/api/native-main-profiles")) {
289
+ const { handleNativeProfileAPI } = await import("../codex/native-profile-api");
290
+ return handleNativeProfileAPI(req, url, config, deps.nativeProfileApi);
291
+ }
292
+
190
293
  if (url.pathname.startsWith("/api/codex-auth/")) {
191
294
  const { handleCodexAuthAPI } = await import("../codex/auth-api");
192
295
  const { ConfigMutationLockError } = await import("../config");
193
296
  const { CodexCredentialRefreshLockTimeoutError } = await import("../codex/account-store");
194
297
  try {
195
- return await handleCodexAuthAPI(req, url, config);
298
+ return await handleCodexAuthAPI(req, url, config, convergeCodexCatalog);
196
299
  } catch (error) {
197
300
  // Credential writers remap ConfigMutationLockError to CodexCredentialRefreshLockTimeoutError;
198
301
  // treat both as the same retryable busy response.