@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
@@ -9,10 +9,11 @@ import { buildModelsRequest, resolveModelsAuthToken } from "../../oauth";
9
9
  import type { OcxConfig, OcxProviderConfig } from "../../types";
10
10
  import { modelInList } from "../../types";
11
11
  import { CODEX_REASONING_LEVELS, codexEffortRank, configuredReasoningEfforts, modelRecordValue, sanitizeCodexReasoningEfforts } from "../../reasoning-effort";
12
- import { getJawcodeModelMetadata, getJawcodeModelMetadataCaseInsensitive, listJawcodeModelMetadata, resolveJawcodeProvider } from "../../generated/jawcode-model-metadata";
12
+ import { getModelMetadata, getModelMetadataCaseInsensitive, listModelMetadata, resolveMetadataProvider } from "../../generated/model-metadata";
13
13
  import { enrichProviderFromRegistry, shouldCaseFoldMetadataModelId } from "../../providers/derive";
14
14
  import { getProviderRegistryEntry } from "../../providers/registry";
15
- import { applyProviderContextCap, providerContextCap } from "../../providers/context-cap";
15
+ import { applyProviderContextCap, providerContextCap, resolveUnknownRoutedContextWindow } from "../../providers/context-cap";
16
+ import { clampAutoCompactTokenLimit } from "../../providers/auto-compact-budget";
16
17
  import { routedSlug, slugEquals, slugsEquivalent } from "../../providers/slug-codec";
17
18
  import { CODEX_GPT5_IDENTITY_LINE } from "../../adapters/identity";
18
19
  import { filterCursorConfiguredModelsByLiveDiscovery } from "../../adapters/cursor/discovery";
@@ -31,11 +32,12 @@ import { redactSecretString, redactUserPath } from "../../lib/redact";
31
32
  import upstreamModelsSnapshot from "../data/upstream-models.json";
32
33
 
33
34
 
34
- import { readCatalog, readCodexCatalogPath } from "./parsing";
35
+ import { generatedModelMetadata, readCatalog, readCodexCatalogPath } from "./parsing";
35
36
  import type { CatalogModel, RawEntry } from "./parsing";
36
37
  import { UPSTREAM_NATIVE_ENTRIES } from "./metadata";
38
+ import { nativeOpenAiCapabilitySourceSlug } from "./native-models";
37
39
  import { loadBundledCodexCatalog } from "./bundled";
38
- import type { BundledCatalogDeps } from "./bundled";
40
+ import type { BundledCatalogDeps, ReadonlyRawCatalog } from "./bundled";
39
41
  import { deriveEntry } from "./sync";
40
42
  import {
41
43
  formatClampLogLines,
@@ -116,18 +118,34 @@ export function applyCatalogModelMetadata(entry: RawEntry, model?: CatalogModel)
116
118
  if (model.provider === COMBO_NAMESPACE) entry.owned_by = model.owned_by ?? COMBO_NAMESPACE;
117
119
  // displayName is DISPLAY-ONLY: it relabels the picker row but never touches the routing
118
120
  // slug, alias, or provider. deriveEntry already stamped the slug as display_name; a
119
- // configured displayName overrides just the label. The `/` separator is rejected at every
120
- // input boundary (CLI `ocx models add`, management API), so the catalog trusts its source.
121
- // Combos carry no displayName, and natives never reach here (no CatalogModel), so genuine
122
- // upstream marketing names and combo alias labels are preserved untouched.
121
+ // configured displayName overrides just the label. Custom-model inputs reject `/`; combos
122
+ // validate their bounded display label independently. Natives never reach here (no CatalogModel),
123
+ // so genuine upstream marketing names are preserved untouched.
123
124
  const displayName = typeof model.displayName === "string" ? model.displayName.trim() : "";
124
125
  if (displayName) entry.display_name = displayName;
125
- if (typeof model.contextWindow === "number" && model.contextWindow > 0) {
126
- entry.context_window = model.contextWindow;
127
- entry.max_context_window = model.contextWindow;
128
- entry.auto_compact_token_limit = Math.min(
129
- Math.floor(model.contextWindow * 0.9),
130
- model.maxInputTokens ?? Number.POSITIVE_INFINITY,
126
+ const resolvedContext = typeof model.contextWindow === "number" && model.contextWindow > 0
127
+ ? model.contextWindow
128
+ : (model.contextCap !== undefined ? resolveUnknownRoutedContextWindow(model.contextCap) : undefined);
129
+ if (typeof resolvedContext === "number" && resolvedContext > 0) {
130
+ entry.context_window = resolvedContext;
131
+ entry.max_context_window = resolvedContext;
132
+ entry.auto_compact_token_limit = clampAutoCompactTokenLimit(
133
+ resolvedContext,
134
+ model.maxInputTokens,
135
+ model.autoCompactTokenLimit,
136
+ );
137
+ } else if (
138
+ typeof entry.context_window === "number"
139
+ && entry.context_window > 0
140
+ && typeof model.maxInputTokens === "number"
141
+ && model.maxInputTokens > 0
142
+ ) {
143
+ // A conservative routed fallback is not evidence for applying the optional soft policy,
144
+ // but a measured/configured input ceiling is still a hard bound. Compact before that
145
+ // ceiling even when the provider supplied no authoritative context window.
146
+ entry.auto_compact_token_limit = clampAutoCompactTokenLimit(
147
+ entry.context_window,
148
+ model.maxInputTokens,
131
149
  );
132
150
  }
133
151
  if (Array.isArray(model.inputModalities) && model.inputModalities.length > 0) {
@@ -139,6 +157,63 @@ export function applyCatalogModelMetadata(entry: RawEntry, model?: CatalogModel)
139
157
  if (typeof model.supportsReasoningSummaries === "boolean") {
140
158
  entry.supports_reasoning_summaries = model.supportsReasoningSummaries;
141
159
  }
160
+ if (model.supportsServiceTier === true) {
161
+ entry.default_service_tier = null;
162
+ entry.service_tiers = [{
163
+ id: "priority",
164
+ name: "Fast",
165
+ description: model.fastTierDescription ?? "1.5x speed, increased usage",
166
+ }];
167
+ entry.additional_speed_tiers = ["fast"];
168
+ }
169
+ stampCapabilityProvenance(entry, model);
170
+ }
171
+
172
+ /**
173
+ * Record which capability values a real source actually asserted (#1796).
174
+ *
175
+ * `ensureStrictCatalogFields` fills `context_window` and `input_modalities` with
176
+ * compatibility defaults so Codex's strict parser accepts the file, which means
177
+ * an entry ALWAYS carries both and their presence proves nothing. Routing has to
178
+ * tell "the provider said text-only" apart from "nobody said anything", so it
179
+ * reads this block and never the entry itself ("unknown is not zero",
180
+ * src/routing/capability.ts).
181
+ *
182
+ * Two real sources exist and both are consulted here, in the same precedence the
183
+ * writers use (`applyCatalogMetadata` runs first, the model's own fields
184
+ * overwrite it): the `CatalogModel` and the generated jawcode metadata table.
185
+ * Reading only the model would silently drop every provider whose capabilities
186
+ * live in that table.
187
+ */
188
+ function stampCapabilityProvenance(entry: RawEntry, model: CatalogModel): void {
189
+ // Virtual combo rows are synthesized from last-resort defaults (a generic 128k
190
+ // context and a `["text"]` modality), so their values are placeholders rather
191
+ // than assertions. Stamping them would reintroduce the exact false-evidence
192
+ // defect this block exists to prevent.
193
+ if (model.provider === COMBO_NAMESPACE) return;
194
+
195
+ const meta = generatedModelMetadata(model.provider, model.id);
196
+ const metaContext = typeof meta?.contextWindow === "number" && meta.contextWindow > 0
197
+ // The generated context is capped before it reaches the entry, so provenance
198
+ // must apply the same cap or routing would advertise a window the cap refused.
199
+ ? applyProviderContextCap(meta.contextWindow, model.contextCap) ?? meta.contextWindow
200
+ : undefined;
201
+ const contextWindow = typeof model.contextWindow === "number" && model.contextWindow > 0
202
+ ? model.contextWindow
203
+ : metaContext;
204
+ const inputModalities = Array.isArray(model.inputModalities) && model.inputModalities.length > 0
205
+ ? model.inputModalities
206
+ : (Array.isArray(meta?.input) && meta.input.length > 0 ? meta.input : undefined);
207
+
208
+ entry.opencodex_capability_provenance = {
209
+ provider: model.provider,
210
+ model_id: model.id,
211
+ ...(contextWindow !== undefined ? { context_window: contextWindow } : {}),
212
+ ...(inputModalities !== undefined ? { input_modalities: [...inputModalities] } : {}),
213
+ ...(Array.isArray(model.capabilities) && model.capabilities.length > 0
214
+ ? { capabilities: [...model.capabilities] }
215
+ : {}),
216
+ };
142
217
  }
143
218
 
144
219
  export function applyReasoningLevels(
@@ -153,8 +228,9 @@ export function applyReasoningLevels(
153
228
  // (no ultra->max client conversion) and codex-rs validates it by catalog membership,
154
229
  // so a missing max rung hard-fails spawn_agent effort overrides. The wire stays honest:
155
230
  // routed adapters clamp via clampToSupportedCodexEffort and natives via
156
- // nativeEffortClamp (max -> the model's real top rung).
157
- if (!preserveExact && efforts.length > 0) {
231
+ // nativeEffortClamp (max -> the model's real top rung). A `none`-only ladder is NOT
232
+ // reasoning-capable, so it must not grow synthetic top rungs.
233
+ if (!preserveExact && efforts.length > 0 && efforts.some(effort => effort !== "none" && effort !== "minimal")) {
158
234
  const additions: string[] = [];
159
235
  if (!efforts.includes("max")) additions.push("max");
160
236
  if (!efforts.includes("ultra")) additions.push("ultra");
@@ -177,11 +253,13 @@ export function applyReasoningLevels(
177
253
  }
178
254
  entry.default_reasoning_level = defaultOverride && efforts.includes(defaultOverride)
179
255
  ? defaultOverride
180
- : efforts.includes("medium") ? "medium" : efforts.includes("high") ? "high" : efforts[0];
256
+ : efforts.includes("medium") ? "medium" : efforts.includes("high") ? "high"
257
+ // Sentinels never become the implicit default when real rungs are declared.
258
+ : efforts.find(effort => effort !== "none" && effort !== "minimal") ?? efforts[0];
181
259
  }
182
260
 
183
261
  export function isGpt56NativeSlug(slug: string): boolean {
184
- return !slug.includes("/") && slug.startsWith("gpt-5.6-");
262
+ return !slug.includes("/") && nativeOpenAiCapabilitySourceSlug(slug).startsWith("gpt-5.6-");
185
263
  }
186
264
 
187
265
  export function ensureGpt56ReasoningLevels(entry: RawEntry): void {
@@ -214,11 +292,13 @@ export function ensureUltraReasoningLevel(entry: RawEntry): void {
214
292
  entry.supported_reasoning_levels = levels;
215
293
  }
216
294
 
217
- export function codexSupportedReasoningEfforts(deps: BundledCatalogDeps = {}): Set<string> | null {
218
- const bundled = loadBundledCodexCatalog(deps);
219
- if (!bundled) return null;
295
+ /** Derive the installed Codex effort vocabulary from caller-observed bundled catalog bytes. */
296
+ export function supportedCodexReasoningEffortsFromObservedCatalog(
297
+ catalog: ReadonlyRawCatalog | null,
298
+ ): ReadonlySet<string> | null {
299
+ if (!catalog) return null;
220
300
  const efforts = new Set<string>();
221
- for (const model of bundled.models ?? []) {
301
+ for (const model of catalog.models ?? []) {
222
302
  if (typeof model.slug !== "string" || model.slug.includes("/")) continue;
223
303
  const levels = Array.isArray(model.supported_reasoning_levels) ? model.supported_reasoning_levels : [];
224
304
  for (const level of levels) {
@@ -230,6 +310,10 @@ export function codexSupportedReasoningEfforts(deps: BundledCatalogDeps = {}): S
230
310
  return efforts.size > 0 ? efforts : null;
231
311
  }
232
312
 
313
+ export function codexSupportedReasoningEfforts(deps: BundledCatalogDeps = {}): ReadonlySet<string> | null {
314
+ return supportedCodexReasoningEffortsFromObservedCatalog(loadBundledCodexCatalog(deps));
315
+ }
316
+
233
317
  export function clampedDefaultEffort(original: string, surviving: readonly string[]): string {
234
318
  if (surviving.length === 0) return "medium";
235
319
  const ranked = [...surviving]
@@ -240,7 +324,10 @@ export function clampedDefaultEffort(original: string, surviving: readonly strin
240
324
  return (atOrBelow.at(-1) ?? ranked[0]!).effort;
241
325
  }
242
326
 
243
- export function clampEntryToCodexSupportedEfforts(entry: RawEntry, supported: Set<string> | null): void {
327
+ export function clampEntryToCodexSupportedEfforts(
328
+ entry: RawEntry,
329
+ supported: ReadonlySet<string> | null,
330
+ ): void {
244
331
  if (!supported) return;
245
332
  const levels = Array.isArray(entry.supported_reasoning_levels)
246
333
  ? entry.supported_reasoning_levels as Array<{ effort?: string }>
@@ -263,12 +350,17 @@ export function clampEntryToCodexSupportedEfforts(entry: RawEntry, supported: Se
263
350
  }
264
351
  }
265
352
 
266
- export function clampCatalogModelsToCodexSupport(models: RawEntry[], deps: BundledCatalogDeps = {}): RawEntry[] {
267
- const supported = codexSupportedReasoningEfforts(deps);
268
- if (!supported) {
269
- if (!deps.commandCandidates) persistEffortClamp(null, { configDir: deps.configDir });
270
- return models;
271
- }
353
+ export interface ObservedCatalogEffortClamp {
354
+ readonly removedEfforts: readonly string[];
355
+ readonly affectedModels: readonly string[];
356
+ }
357
+
358
+ /** Apply an already-observed runtime ladder without probing, logging, or writing diagnostics. */
359
+ export function clampCatalogModelsToObservedCodexSupport(
360
+ models: RawEntry[],
361
+ supported: ReadonlySet<string> | null,
362
+ ): ObservedCatalogEffortClamp {
363
+ if (!supported) return { removedEfforts: [], affectedModels: [] };
272
364
 
273
365
  const removed = new Set<string>();
274
366
  const affected: string[] = [];
@@ -301,6 +393,20 @@ export function clampCatalogModelsToCodexSupport(models: RawEntry[], deps: Bundl
301
393
  }
302
394
  }
303
395
 
396
+ return {
397
+ removedEfforts: [...removed].sort(),
398
+ affectedModels: affected,
399
+ };
400
+ }
401
+
402
+ export function clampCatalogModelsToCodexSupport(models: RawEntry[], deps: BundledCatalogDeps = {}): RawEntry[] {
403
+ const supported = codexSupportedReasoningEfforts(deps);
404
+ if (!supported) {
405
+ if (!deps.commandCandidates) persistEffortClamp(null, { configDir: deps.configDir });
406
+ return models;
407
+ }
408
+ const clamp = clampCatalogModelsToObservedCodexSupport(models, supported);
409
+
304
410
  let runtimePath = "codex";
305
411
  let runtimeVersion: string | null = null;
306
412
  if (!deps.commandCandidates) {
@@ -337,12 +443,12 @@ export function clampCatalogModelsToCodexSupport(models: RawEntry[], deps: Bundl
337
443
  }
338
444
  }
339
445
 
340
- if (removed.size > 0) {
446
+ if (clamp.removedEfforts.length > 0) {
341
447
  const diagnostic: EffortClampDiagnostic = {
342
448
  runtimePath,
343
449
  runtimeVersion,
344
- removedEfforts: [...removed].sort(),
345
- affectedModels: affected,
450
+ removedEfforts: [...clamp.removedEfforts],
451
+ affectedModels: [...clamp.affectedModels],
346
452
  };
347
453
  for (const line of formatClampLogLines(diagnostic)) console.warn(line);
348
454
  if (!deps.commandCandidates) persistEffortClamp(diagnostic, { configDir: deps.configDir });
@@ -0,0 +1,302 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync, realpathSync, statSync } from "node:fs";
3
+ import { basename, dirname, resolve } from "node:path";
4
+
5
+ import { expandUserPath } from "../../config";
6
+ import type {
7
+ CatalogConditionalSourceObservations,
8
+ CatalogConditionalSourceRole,
9
+ CatalogFilesystemIdentity,
10
+ CatalogHomeSelectionObservation,
11
+ CatalogRequiredSourceObservations,
12
+ CatalogRequiredSourceRole,
13
+ CatalogSourceEvidence,
14
+ CatalogSourceObservation,
15
+ CatalogSourceRole,
16
+ } from "../convergence-types";
17
+ import { defaultCodexHome } from "../home";
18
+
19
+ export type CatalogGatherReadableSourceRole =
20
+ | "active-catalog-merge"
21
+ | "hashed-backup-fallback"
22
+ | "legacy-backup-fallback"
23
+ | "models-cache-fallback"
24
+ | "runtime-selection";
25
+
26
+ /** The minimal observe-only source interface consumed by bundled catalog selection. */
27
+ export interface CatalogGatherEvidenceSession {
28
+ readSource(role: CatalogGatherReadableSourceRole): Uint8Array | null;
29
+ }
30
+
31
+ /** The exact observe-only auth input consumed by provider discovery. */
32
+ export interface CatalogGatherProviderAuthEvidence {
33
+ readonly authStoreBuffer: Uint8Array | null;
34
+ }
35
+
36
+ export type CatalogFilesystemEvidenceSession = CatalogGatherEvidenceSession
37
+ & CatalogGatherProviderAuthEvidence;
38
+
39
+ const CONDITIONAL_SOURCE_ROLES = [
40
+ "bundled-catalog-template",
41
+ "active-catalog-merge",
42
+ "hashed-backup-fallback",
43
+ "legacy-backup-fallback",
44
+ "models-cache-fallback",
45
+ "native-catalog-selection",
46
+ "runtime-selection",
47
+ "provider-auth-selection",
48
+ ] as const satisfies readonly CatalogConditionalSourceRole[];
49
+
50
+ interface MutableSessionState {
51
+ homeSelection: CatalogHomeSelectionObservation | null;
52
+ readonly sourcePaths: Map<CatalogSourceRole, string>;
53
+ requiredTargetSelection: CatalogSourceObservation<CatalogRequiredSourceRole> | null;
54
+ readonly conditional: Record<CatalogConditionalSourceRole, CatalogSourceObservation[]>;
55
+ sealed: boolean;
56
+ }
57
+
58
+ const sessionStates = new WeakMap<object, MutableSessionState>();
59
+
60
+ function filesystemIdentity(
61
+ entry: Readonly<{ dev: bigint; ino: bigint }>,
62
+ ): CatalogFilesystemIdentity {
63
+ return Object.freeze({ volume: String(entry.dev), fileId: String(entry.ino) });
64
+ }
65
+
66
+ function sessionState(session: CatalogFilesystemEvidenceSession): MutableSessionState {
67
+ const state = sessionStates.get(session);
68
+ if (!state) {
69
+ throw new TypeError("Catalog filesystem evidence session was not created by its owner.");
70
+ }
71
+ return state;
72
+ }
73
+
74
+ function assertOpen(state: MutableSessionState): void {
75
+ if (state.sealed) throw new Error("Catalog filesystem evidence session is already sealed.");
76
+ }
77
+
78
+ function observedHomeSelection(): CatalogHomeSelectionObservation {
79
+ const environmentSelector = process.env.CODEX_HOME?.trim();
80
+ const selector = environmentSelector
81
+ ? { kind: "environment" as const, raw: environmentSelector }
82
+ : { kind: "default" as const, raw: defaultCodexHome() };
83
+ const selectedPath = selector.kind === "environment"
84
+ ? resolve(expandUserPath(selector.raw))
85
+ : resolve(selector.raw);
86
+ const canonicalCodexHome = realpathSync.native(selectedPath);
87
+ const root = statSync(canonicalCodexHome, { bigint: true });
88
+ if (!root.isDirectory()) {
89
+ throw new Error(`Codex home is not a directory: ${selectedPath}`);
90
+ }
91
+ return Object.freeze({
92
+ selector: Object.freeze(selector),
93
+ canonicalCodexHome,
94
+ rootIdentity: filesystemIdentity(root),
95
+ });
96
+ }
97
+
98
+ /** Capture and freeze the selector/root authority before any derived path is admitted. */
99
+ export function captureAndSealCatalogHomeSelection(
100
+ session: CatalogFilesystemEvidenceSession,
101
+ ): CatalogHomeSelectionObservation {
102
+ const state = sessionState(session);
103
+ assertOpen(state);
104
+ if (state.homeSelection) return state.homeSelection;
105
+ state.homeSelection = observedHomeSelection();
106
+ return state.homeSelection;
107
+ }
108
+
109
+ /** Bind the next consultation for a closed role without exposing the evidence arrays. */
110
+ export function acceptCatalogGatherSourcePath(
111
+ session: CatalogFilesystemEvidenceSession,
112
+ role: CatalogSourceRole,
113
+ logicalPath: string,
114
+ ): void {
115
+ const state = sessionState(session);
116
+ assertOpen(state);
117
+ if (!state.homeSelection) {
118
+ throw new Error("Catalog home selection must be sealed before accepting a derived path.");
119
+ }
120
+ state.sourcePaths.set(role, resolve(logicalPath));
121
+ }
122
+
123
+ function isMissing(error: unknown): boolean {
124
+ return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
125
+ }
126
+
127
+ function observeSource<R extends CatalogSourceRole>(
128
+ role: R,
129
+ logicalPath: string,
130
+ ): Readonly<{ bytes: Uint8Array | null; observation: CatalogSourceObservation<R> }> {
131
+ const canonicalParent = realpathSync.native(dirname(logicalPath));
132
+ const parent = statSync(canonicalParent, { bigint: true });
133
+ if (!parent.isDirectory()) {
134
+ throw new Error(`Catalog source parent is not a directory: ${dirname(logicalPath)}`);
135
+ }
136
+ const parentIdentity = Object.freeze({
137
+ canonicalPath: canonicalParent,
138
+ ...filesystemIdentity(parent),
139
+ });
140
+
141
+ let bytes: Uint8Array;
142
+ try {
143
+ bytes = Uint8Array.from(readFileSync(logicalPath));
144
+ } catch (error) {
145
+ if (!isMissing(error)) throw error;
146
+ return Object.freeze({
147
+ bytes: null,
148
+ observation: Object.freeze({
149
+ state: "absent" as const,
150
+ role,
151
+ logicalPath,
152
+ canonicalPath: resolve(canonicalParent, basename(logicalPath)),
153
+ parentIdentity,
154
+ fileIdentity: null,
155
+ }),
156
+ });
157
+ }
158
+
159
+ const canonicalPath = realpathSync.native(logicalPath);
160
+ const file = statSync(canonicalPath, { bigint: true });
161
+ if (!file.isFile()) throw new Error(`Catalog source is not a regular file: ${logicalPath}`);
162
+ return Object.freeze({
163
+ bytes,
164
+ observation: Object.freeze({
165
+ state: "present" as const,
166
+ role,
167
+ logicalPath,
168
+ canonicalPath,
169
+ parentIdentity,
170
+ fileIdentity: filesystemIdentity(file),
171
+ sha256: createHash("sha256").update(bytes).digest("hex"),
172
+ }),
173
+ });
174
+ }
175
+
176
+ /** Read once, record PRESENT/ABSENT first, then return the exact hashed buffer. */
177
+ export function readCatalogGatherSource<R extends CatalogSourceRole>(
178
+ session: CatalogFilesystemEvidenceSession,
179
+ role: R,
180
+ ): Uint8Array | null {
181
+ const state = sessionState(session);
182
+ assertOpen(state);
183
+ const logicalPath = state.sourcePaths.get(role);
184
+ if (!logicalPath) throw new Error(`No catalog source path was accepted for role ${role}.`);
185
+ if (role === "catalog-target-selection" && state.requiredTargetSelection) {
186
+ throw new Error(`Required catalog source role ${role} was already observed.`);
187
+ }
188
+
189
+ const observed = observeSource(role, logicalPath);
190
+ if (role === "catalog-target-selection") {
191
+ state.requiredTargetSelection = observed.observation as CatalogSourceObservation<"catalog-target-selection">;
192
+ } else {
193
+ state.conditional[role as CatalogConditionalSourceRole].push(observed.observation);
194
+ }
195
+ return observed.bytes;
196
+ }
197
+
198
+ function optionalFileIdentity(path: string): Readonly<{ device: string; inode: string }> | null {
199
+ try {
200
+ const entry = statSync(path, { bigint: true });
201
+ return { device: String(entry.dev), inode: String(entry.ino) };
202
+ } catch (error) {
203
+ if (isMissing(error)) return null;
204
+ throw error;
205
+ }
206
+ }
207
+
208
+ /** Probe a candidate write target without allowing filesystem mutation. */
209
+ export function captureCatalogGatherTargetIdentity(
210
+ session: CatalogFilesystemEvidenceSession,
211
+ path: string,
212
+ ): string {
213
+ const state = sessionState(session);
214
+ assertOpen(state);
215
+ if (!state.homeSelection) {
216
+ throw new Error("Catalog home selection must be sealed before accepting a derived path.");
217
+ }
218
+ const textualPath = resolve(path);
219
+ const canonicalParent = realpathSync.native(dirname(textualPath));
220
+ const parent = statSync(canonicalParent, { bigint: true });
221
+ return JSON.stringify({
222
+ path: textualPath,
223
+ canonicalParent,
224
+ parentIdentity: { device: String(parent.dev), inode: String(parent.ino) },
225
+ fileIdentity: optionalFileIdentity(textualPath),
226
+ });
227
+ }
228
+
229
+ function cloneObservation<R extends CatalogSourceRole>(
230
+ observation: CatalogSourceObservation<R>,
231
+ ): CatalogSourceObservation<R> {
232
+ if (observation.state === "absent") {
233
+ return Object.freeze({
234
+ ...observation,
235
+ parentIdentity: Object.freeze({ ...observation.parentIdentity }),
236
+ fileIdentity: null,
237
+ });
238
+ }
239
+ return Object.freeze({
240
+ ...observation,
241
+ parentIdentity: Object.freeze({ ...observation.parentIdentity }),
242
+ fileIdentity: Object.freeze({ ...observation.fileIdentity }),
243
+ });
244
+ }
245
+
246
+ /** Seal one complete owner-created session into detached, recursively frozen evidence. */
247
+ export function sealCatalogGatherEvidenceSession(
248
+ session: CatalogFilesystemEvidenceSession,
249
+ ): CatalogSourceEvidence {
250
+ const state = sessionState(session);
251
+ assertOpen(state);
252
+ if (!state.homeSelection) throw new Error("Catalog home selection is required before sealing.");
253
+ const targetSelection = state.requiredTargetSelection;
254
+ if (!targetSelection) {
255
+ throw new Error("Required catalog source role catalog-target-selection was not observed.");
256
+ }
257
+ for (const role of CONDITIONAL_SOURCE_ROLES) {
258
+ if (!Object.hasOwn(state.conditional, role)) {
259
+ throw new Error(`Conditional catalog source role ${role} is missing.`);
260
+ }
261
+ }
262
+
263
+ const conditional = Object.fromEntries(CONDITIONAL_SOURCE_ROLES.map(role => [
264
+ role,
265
+ Object.freeze(state.conditional[role].map(observation => cloneObservation(observation))),
266
+ ])) as unknown as CatalogConditionalSourceObservations;
267
+ const required = Object.freeze({
268
+ "catalog-target-selection": cloneObservation(targetSelection),
269
+ }) as CatalogRequiredSourceObservations;
270
+ const evidence = Object.freeze({
271
+ homeSelection: Object.freeze({
272
+ ...state.homeSelection,
273
+ selector: Object.freeze({ ...state.homeSelection.selector }),
274
+ rootIdentity: Object.freeze({ ...state.homeSelection.rootIdentity }),
275
+ }),
276
+ required,
277
+ conditional: Object.freeze(conditional),
278
+ });
279
+ state.sealed = true;
280
+ return evidence;
281
+ }
282
+
283
+ /** Create an opaque session; all mutable evidence state remains module-private. */
284
+ export function createCatalogGatherEvidenceSession(): CatalogFilesystemEvidenceSession {
285
+ let session: CatalogFilesystemEvidenceSession;
286
+ session = Object.freeze({
287
+ readSource: (role: CatalogGatherReadableSourceRole) => readCatalogGatherSource(session, role),
288
+ get authStoreBuffer(): Uint8Array | null {
289
+ return readCatalogGatherSource(session, "provider-auth-selection");
290
+ },
291
+ });
292
+ sessionStates.set(session, {
293
+ homeSelection: null,
294
+ sourcePaths: new Map(),
295
+ requiredTargetSelection: null,
296
+ conditional: Object.fromEntries(
297
+ CONDITIONAL_SOURCE_ROLES.map(role => [role, [] as CatalogSourceObservation[]]),
298
+ ) as unknown as MutableSessionState["conditional"],
299
+ sealed: false,
300
+ });
301
+ return session;
302
+ }
@@ -0,0 +1,2 @@
1
+ /** Stable ownership marker for a routed combo that deliberately owns a bare native slug. */
2
+ export const CODEX_NATIVE_ALIAS_CATALOG_KIND = "combo-native-alias-v1";