@iislee/opencodex 2.11.0 → 2.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. package/src/cli/internal-dispatch.ts +0 -20
package/src/cli/models.ts CHANGED
@@ -5,15 +5,72 @@ import { randomUUID } from "node:crypto";
5
5
  import { createInterface } from "node:readline/promises";
6
6
  import { syncModelsToCodex } from "../codex/sync";
7
7
  import { hasOwnProvider, isValidProviderName, loadConfig, saveConfig } from "../config";
8
- import { routedSlug } from "../providers/slug-codec";
8
+ import { canonicalizeReasoningEfforts, isDeclaredReasoningEffort, modelRecordValue } from "../reasoning-effort";
9
+ import { encodedModelIdCollides, routedSlug, slugEquals } from "../providers/slug-codec";
10
+ import { knownModelIdsForProvider } from "../router";
9
11
  import { findLiveProxy } from "../server/proxy-liveness";
10
- import type { OcxConfig, OcxCustomModel } from "../types";
12
+ import { modelInList, type OcxConfig, type OcxCustomModel } from "../types";
11
13
 
12
- const ADD_USAGE = "Usage: ocx models add <provider> <modelId> [--display-name <name>] [--context-window <tokens>] [--modalities text,image,audio]";
14
+ const ADD_USAGE = "Usage: ocx models add <provider> <modelId> [--display-name <name>] [--context-window <tokens>] [--modalities text,image,audio] [--reasoning-efforts <none,minimal,low,medium,high,xhigh,max,ultra>] [--default-reasoning-effort <level>]";
13
15
  const REMOVE_USAGE = "Usage: ocx models remove <customId|provider/modelId> [--yes]";
14
16
  const LIST_CUSTOM_USAGE = "Usage: ocx models list-custom [--json]";
15
17
  const ALLOWED_MODALITIES = new Set(["text", "image", "audio"]);
16
18
 
19
+ /**
20
+ * Parse and validate the reasoning flags shared by `ocx models add` (offline path).
21
+ * "-" means "inherit" and omits the field entirely; "" means an explicit empty ladder
22
+ * ("no reasoning" override, the same state the dashboard stores for the toggle-off
23
+ * checkbox set). Malformed CSV like `low,,high` or `,,` is rejected instead of being
24
+ * silently normalized. Values are canonicalized into Codex ladder order so the stored
25
+ * config matches what the API stores.
26
+ */
27
+ export function parseReasoningArgs(
28
+ reasoningEffortsValue: string | undefined,
29
+ defaultEffortValue: string | undefined,
30
+ ): { reasoningEfforts?: string[]; defaultReasoningEffort?: string; error?: string } {
31
+ if (reasoningEffortsValue === undefined && defaultEffortValue === undefined) return {};
32
+ let reasoningEfforts: string[] | undefined;
33
+ if (reasoningEffortsValue !== undefined) {
34
+ const trimmed = reasoningEffortsValue.trim();
35
+ if (trimmed === "-") {
36
+ reasoningEfforts = undefined;
37
+ } else if (trimmed === "") {
38
+ // Explicit no-reasoning override, exactly like the API's [] / the dashboard's
39
+ // uncheck-all state.
40
+ reasoningEfforts = [];
41
+ } else {
42
+ const parts = trimmed.split(",").map(value => value.trim());
43
+ if (parts.some(part => part === "")) {
44
+ return { error: "--reasoning-efforts must be comma-separated values from none, minimal, low, medium, high, xhigh, max, ultra (\"\" for no reasoning, \"-\" to inherit)" };
45
+ }
46
+ const invalid = parts.filter(value => !isDeclaredReasoningEffort(value));
47
+ if (invalid.length > 0) {
48
+ return { error: `unsupported reasoning effort: ${invalid.join(", ")} (allowed: none, minimal, low, medium, high, xhigh, max, ultra)` };
49
+ }
50
+ reasoningEfforts = canonicalizeReasoningEfforts(parts);
51
+ }
52
+ }
53
+ let defaultReasoningEffort: string | undefined;
54
+ if (defaultEffortValue !== undefined) {
55
+ const trimmed = defaultEffortValue.trim();
56
+ if (trimmed === "-") {
57
+ defaultReasoningEffort = undefined;
58
+ } else {
59
+ if (!isDeclaredReasoningEffort(trimmed)) {
60
+ return { error: `unsupported reasoning effort: ${trimmed} (allowed: none, minimal, low, medium, high, xhigh, max, ultra)` };
61
+ }
62
+ if (!reasoningEfforts || reasoningEfforts.length === 0) {
63
+ return { error: "--default-reasoning-effort requires --reasoning-efforts" };
64
+ }
65
+ if (!reasoningEfforts.includes(trimmed)) {
66
+ return { error: `--default-reasoning-effort "${trimmed}" is not in the declared reasoning efforts` };
67
+ }
68
+ defaultReasoningEffort = trimmed;
69
+ }
70
+ }
71
+ return { reasoningEfforts, defaultReasoningEffort };
72
+ }
73
+
17
74
  interface ModelEntry {
18
75
  provider: string;
19
76
  model: string;
@@ -41,15 +98,22 @@ function collectModels(config: OcxConfig, providerFilter?: string): ModelEntry[]
41
98
  if (seen.has(model)) return;
42
99
  seen.add(model);
43
100
 
44
- const noVision = prov.noVisionModels?.includes(model);
45
- const modalities = inputModalities[model] ?? (noVision ? ["text"] : null);
46
- const efforts = reasoningEfforts[model] ?? prov.reasoningEfforts ?? null;
101
+ // Resolve exactly as the runtime does, or this command reports capabilities the
102
+ // proxy will not honour: `isModelTextOnly` matches noVisionModels with modelInList
103
+ // and reads modelInputModalities with modelRecordValue, so a `gpt-oss` entry covers
104
+ // `gpt-oss:120b`. A bare lookup reported that model as unclassified on every field.
105
+ // noVisionModels is checked first because `isModelTextOnly` returns true on that
106
+ // match before it ever reads modelInputModalities: a `gpt-oss` noVision entry beats
107
+ // an exact `gpt-oss:120b` entry that lists "image", and the proxy rejects the image.
108
+ const noVision = modelInList(prov.noVisionModels, model);
109
+ const modalities = noVision ? ["text"] : (modelRecordValue(inputModalities, model) ?? null);
110
+ const efforts = modelRecordValue(reasoningEfforts, model) ?? prov.reasoningEfforts ?? null;
47
111
 
48
112
  entries.push({
49
113
  provider: provName,
50
114
  model,
51
115
  isDefault,
52
- contextWindow: contextWindows[model] ?? globalContext,
116
+ contextWindow: modelRecordValue(contextWindows, model) ?? globalContext,
53
117
  inputModalities: modalities,
54
118
  reasoningEfforts: efforts,
55
119
  });
@@ -102,9 +166,13 @@ function rejectUnexpectedArgs(args: string[], usage: string): void {
102
166
  async function syncCustomModelsIfLive(): Promise<void> {
103
167
  const live = await findLiveProxy();
104
168
  if (!live) return;
105
- await syncModelsToCodex(live.port).catch(error => {
169
+ const synced = await syncModelsToCodex(live.port).catch(error => {
106
170
  console.error(`Warning: custom model saved, but catalog sync failed: ${error instanceof Error ? error.message : String(error)}`);
171
+ return null;
107
172
  });
173
+ if (synced?.status === "skipped") {
174
+ console.log("Custom model saved; Codex integration is OFF, so its catalog was not changed.");
175
+ }
108
176
  }
109
177
 
110
178
  async function handleCustomAdd(args: string[]): Promise<void> {
@@ -114,11 +182,12 @@ async function handleCustomAdd(args: string[]): Promise<void> {
114
182
  const displayNameValue = consumeFlagValue(rest, "--display-name");
115
183
  const contextWindowValue = consumeFlagValue(rest, "--context-window");
116
184
  const modalitiesValue = consumeFlagValue(rest, "--modalities");
185
+ const reasoningEffortsValue = consumeFlagValue(rest, "--reasoning-efforts");
186
+ const defaultEffortValue = consumeFlagValue(rest, "--default-reasoning-effort");
117
187
  rejectUnexpectedArgs(rest, ADD_USAGE);
118
188
 
119
189
  if (!provider || !modelId) fail("provider and modelId are required", ADD_USAGE);
120
190
  if (!isValidProviderName(provider)) fail(`invalid provider name "${provider}"`);
121
- if (modelId.includes("/")) fail("modelId must not contain /");
122
191
 
123
192
  const config = loadConfig();
124
193
  if (!hasOwnProvider(config.providers, provider)) {
@@ -146,11 +215,18 @@ async function handleCustomAdd(args: string[]): Promise<void> {
146
215
  inputModalities = [...new Set(inputModalities)];
147
216
  }
148
217
 
218
+ const parsed = parseReasoningArgs(reasoningEffortsValue, defaultEffortValue);
219
+ if (parsed.error) fail(parsed.error);
220
+
149
221
  const existing = config.customModels ?? [];
150
222
  const slug = routedSlug(provider, modelId);
151
223
  if (existing.some(model => routedSlug(model.provider, model.modelId) === slug)) {
152
224
  fail(`custom model "${slug}" already exists`);
153
225
  }
226
+ const known = knownModelIdsForProvider(provider, config.providers[provider], config);
227
+ if (encodedModelIdCollides(modelId, known)) {
228
+ fail(`custom model "${slug}" is ambiguous; it encodes to an existing model id`);
229
+ }
154
230
 
155
231
  const entry: OcxCustomModel = {
156
232
  id: randomUUID(),
@@ -159,6 +235,8 @@ async function handleCustomAdd(args: string[]): Promise<void> {
159
235
  ...(displayName ? { displayName } : {}),
160
236
  ...(contextWindow ? { contextWindow } : {}),
161
237
  ...(inputModalities ? { inputModalities } : {}),
238
+ ...(parsed.reasoningEfforts ? { reasoningEfforts: parsed.reasoningEfforts } : {}),
239
+ ...(parsed.defaultReasoningEffort ? { defaultReasoningEffort: parsed.defaultReasoningEffort } : {}),
162
240
  addedAt: new Date().toISOString(),
163
241
  };
164
242
  config.customModels = [...existing, entry];
@@ -189,10 +267,16 @@ async function handleCustomRemove(args: string[]): Promise<void> {
189
267
 
190
268
  const config = loadConfig();
191
269
  const existing = config.customModels ?? [];
192
- const index = target.includes("/")
193
- ? existing.findIndex(model => routedSlug(model.provider, model.modelId) === target)
194
- : existing.findIndex(model => model.id === target);
195
- if (index === -1) fail(`custom model "${target}" not found`);
270
+ const matchingIndexes = existing.flatMap((model, index) => (
271
+ target.includes("/")
272
+ ? slugEquals(target, model.provider, model.modelId)
273
+ : model.id === target
274
+ ) ? [index] : []);
275
+ if (matchingIndexes.length === 0) fail(`custom model "${target}" not found`);
276
+ if (matchingIndexes.length > 1) {
277
+ fail(`custom model selector "${target}" is ambiguous; use the custom model id`);
278
+ }
279
+ const index = matchingIndexes[0]!;
196
280
 
197
281
  const model = existing[index];
198
282
  if (!confirmed && !(await confirmCustomRemoval(model))) {
@@ -214,12 +298,14 @@ function customModelCells(model: OcxCustomModel): string[] {
214
298
  model.displayName ?? "-",
215
299
  model.contextWindow ? `${Math.round(model.contextWindow / 1000)}k` : "-",
216
300
  model.inputModalities?.join(",") ?? "-",
301
+ model.reasoningEfforts?.join(",") ?? "-",
302
+ model.defaultReasoningEffort ?? "-",
217
303
  ];
218
304
  }
219
305
 
220
306
  function printCustomModelGroup(provider: string, models: OcxCustomModel[]): void {
221
307
  const rows = models.map(customModelCells);
222
- const headers = ["ID", "MODEL", "DISPLAY NAME", "CONTEXT", "MODALITIES"];
308
+ const headers = ["ID", "MODEL", "DISPLAY NAME", "CONTEXT", "MODALITIES", "EFFORTS", "DEFAULT EFFORT"];
223
309
  const widths = headers.map((header, column) => Math.max(header.length, ...rows.map(row => row[column].length)));
224
310
  const line = (cells: string[]) => cells.map((cell, column) => cell.padEnd(widths[column])).join(" ");
225
311
  console.log(`${provider}:`);
@@ -14,8 +14,11 @@ import {
14
14
  const USAGE = `Usage:
15
15
  ocx observe logs [--provider <name>] [--model <id>] [--status <code>]
16
16
  [--limit <n>] [--follow] [--json|--jsonl]
17
+ ocx logs explain <request-id> [--json]
18
+ ocx logs rebuild-index
19
+ ocx logs index-status
17
20
  ocx observe usage [--range <7d|30d|all>] [--surface <all|codex|claude|grok>] [--json]
18
- ocx observe storage [--json]
21
+ ocx observe storage [codex-logs [status|protect|unprotect|repair|compact] [--mode <compat|quiet>]] [--json]
19
22
  ocx observe memory [--json]
20
23
  ocx observe debug [--json]
21
24
  ocx observe claude-inbound [--limit <n>] [--json]
@@ -79,6 +82,50 @@ async function logs(argv: string[], deps: RuntimeApiDeps): Promise<void> {
79
82
  } while (true);
80
83
  }
81
84
 
85
+ async function explain(argv: string[], deps: RuntimeApiDeps): Promise<void> {
86
+ const args = [...argv];
87
+ const requestId = args.shift();
88
+ const wantsJson = takeFlag(args, "--json");
89
+ if (!requestId) throw new CliUsageError("request id is required", USAGE);
90
+ rejectArgs(args, USAGE);
91
+ const encoded = encodeURIComponent(requestId);
92
+ const result = await runtimeRequest(`/api/request-history/${encoded}/route-decision`, {}, deps);
93
+ printData(result, wantsJson, wantsJson ? undefined : [JSON.stringify(result, null, 2)]);
94
+ }
95
+
96
+ async function rebuildIndex(argv: string[], deps: RuntimeApiDeps): Promise<void> {
97
+ const args = [...argv];
98
+ const wantsJson = takeFlag(args, "--json");
99
+ rejectArgs(args, USAGE);
100
+ const { rebuildRequestHistoryIndex } = await import("../routing/history/indexer");
101
+ const meta = await rebuildRequestHistoryIndex();
102
+ if (wantsJson) printData(meta, true);
103
+ else {
104
+ console.log(`Request-history index rebuilt (${meta.dbPath})`);
105
+ console.log(` schema version: ${meta.schemaVersion}`);
106
+ console.log(` indexed rows: ${meta.indexedRows}`);
107
+ console.log(` source size: ${meta.sourceSize} bytes`);
108
+ console.log(` last error: ${meta.lastError ?? "none"}`);
109
+ }
110
+ }
111
+
112
+ async function indexStatus(argv: string[], deps: RuntimeApiDeps): Promise<void> {
113
+ const args = [...argv];
114
+ const wantsJson = takeFlag(args, "--json");
115
+ rejectArgs(args, USAGE);
116
+ const { requestHistoryIndexStatus } = await import("../routing/history/indexer");
117
+ const meta = await requestHistoryIndexStatus();
118
+ if (wantsJson) printData(meta, true);
119
+ else {
120
+ console.log(`Request-history index (${meta.dbPath})`);
121
+ console.log(` schema version: ${meta.schemaVersion}`);
122
+ console.log(` indexed rows: ${meta.indexedRows}`);
123
+ console.log(` source size: ${meta.sourceSize} bytes`);
124
+ console.log(` indexed offset: ${meta.indexedOffset} bytes`);
125
+ console.log(` last error: ${meta.lastError ?? "none"}`);
126
+ }
127
+ }
128
+
82
129
  async function usage(argv: string[], deps: RuntimeApiDeps): Promise<void> {
83
130
  const args = [...argv];
84
131
  const wantsJson = takeFlag(args, "--json");
@@ -100,12 +147,54 @@ async function simple(path: string, argv: string[], deps: RuntimeApiDeps): Promi
100
147
  printData(result, wantsJson, summaryLines(result));
101
148
  }
102
149
 
150
+ async function storage(argv: string[], deps: RuntimeApiDeps): Promise<void> {
151
+ if (argv[0] !== "codex-logs") {
152
+ await simple("/api/storage", argv, deps);
153
+ return;
154
+ }
155
+
156
+ const args = argv.slice(1);
157
+ const action = args[0] && !args[0].startsWith("-") ? args.shift()! : "status";
158
+ const wantsJson = takeFlag(args, "--json");
159
+ const mode = takeOption(args, "--mode");
160
+ rejectArgs(args, USAGE);
161
+
162
+ let result: unknown;
163
+ if (action === "status") {
164
+ if (mode !== undefined) throw new CliUsageError("--mode is only valid with codex-logs protect", USAGE);
165
+ result = await runtimeRequest("/api/storage/codex-logs", {}, deps);
166
+ } else if (action === "protect") {
167
+ const requestedMode = mode ?? "compat";
168
+ if (requestedMode !== "compat" && requestedMode !== "quiet") {
169
+ throw new CliUsageError("--mode must be compat or quiet", USAGE);
170
+ }
171
+ result = await runtimeRequest("/api/storage/codex-logs/protect", {
172
+ method: "POST",
173
+ headers: { "content-type": "application/json" },
174
+ body: JSON.stringify({ mode: requestedMode }),
175
+ }, deps);
176
+ } else if (action === "unprotect" || action === "repair" || action === "compact") {
177
+ if (mode !== undefined) throw new CliUsageError("--mode is only valid with codex-logs protect", USAGE);
178
+ result = await runtimeRequest(`/api/storage/codex-logs/${action}`, { method: "POST" }, deps);
179
+ } else {
180
+ throw new CliUsageError(`unknown codex-logs action ${action}`, USAGE);
181
+ }
182
+
183
+ printData(result, wantsJson, summaryLines(result));
184
+ }
185
+
103
186
  export async function handleObserveCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
104
187
  return runCliAction(async () => {
105
188
  const [sub = "logs", ...rest] = argv;
106
- if (sub === "logs") await logs(rest, deps);
189
+ if (sub === "logs") {
190
+ const action = rest[0];
191
+ if (action === "explain") await explain(rest.slice(1), deps);
192
+ else if (action === "rebuild-index") await rebuildIndex(rest.slice(1), deps);
193
+ else if (action === "index-status") await indexStatus(rest.slice(1), deps);
194
+ else await logs(rest, deps);
195
+ }
107
196
  else if (sub === "usage") await usage(rest, deps);
108
- else if (sub === "storage") await simple("/api/storage", rest, deps);
197
+ else if (sub === "storage") await storage(rest, deps);
109
198
  else if (sub === "memory") await simple("/api/system/memory", rest, deps);
110
199
  else if (sub === "debug") await simple("/api/debug", rest, deps);
111
200
  else if (sub === "claude-inbound") await simple("/api/claude/inbound-debug", rest, deps);
@@ -40,6 +40,8 @@ import { loadServiceTokenFromFile, serviceApiTokenFilePath } from "../lib/servic
40
40
  import { providerCodexAccountMode } from "../providers/registry";
41
41
  import { findLiveProxy, probeHostname, type LiveProxy } from "../server/proxy-liveness";
42
42
  import type { OcxConfig } from "../types";
43
+ import { withProcessRuntimeProvenance } from "../lib/bun-runtime";
44
+ import { selfLaunchArgv } from "../lib/self-launch-argv";
43
45
 
44
46
  /**
45
47
  * The provider-block serializer, its constants, and the config-path helpers now live in
@@ -493,11 +495,11 @@ async function ensureProxyForOpencode(config: OcxConfig): Promise<LiveProxy | nu
493
495
  if (live) return live;
494
496
  const cfgPort = config.port;
495
497
  const pinPort = typeof cfgPort === "number" && cfgPort > 0 ? cfgPort : 10100;
496
- const child = spawn(process.execPath, [process.argv[1], "start", "--port", String(pinPort)], {
498
+ const child = spawn(process.execPath, selfLaunchArgv(["start", "--port", String(pinPort)]), {
497
499
  detached: true,
498
500
  stdio: "ignore",
499
501
  windowsHide: true,
500
- env: opencodeProxyStartEnv(process.env) as NodeJS.ProcessEnv,
502
+ env: withProcessRuntimeProvenance(opencodeProxyStartEnv(process.env) as NodeJS.ProcessEnv),
501
503
  });
502
504
  // Without a listener an 'error' (bad argv[1], EMFILE, AV denial) throws synchronously
503
505
  // and kills this process; the health poll below already reports the failure properly.
@@ -16,7 +16,8 @@ const USAGE = `Usage:
16
16
  ocx provider edit <name> [--adapter <id>] [--base-url <url>] [--default-model <id|->]
17
17
  [--auth-mode <key|forward|oauth|local|->] [--note <text|->]
18
18
  [--api-key-transport <x-api-key|bearer|->]
19
- [--enabled <on|off>] [--live-models <on|off>] [--allow-private-network <on|off>] [--json]
19
+ [--headers <json>] [--enabled <on|off>] [--live-models <on|off>]
20
+ [--allow-private-network <on|off>] [--json]
20
21
  ocx provider test <name> [--json]
21
22
  ocx provider quota [--refresh] [--json]
22
23
  ocx provider presets [--json]
@@ -39,6 +40,7 @@ async function edit(argv: string[], deps: RuntimeApiDeps): Promise<void> {
39
40
  const authMode = cleared(takeOption(args, "--auth-mode"));
40
41
  const note = cleared(takeOption(args, "--note"));
41
42
  const apiKeyTransport = cleared(takeOption(args, "--api-key-transport"));
43
+ const headers = takeOption(args, "--headers");
42
44
  const enabled = takeBooleanOption(args, "--enabled");
43
45
  const liveModels = takeBooleanOption(args, "--live-models");
44
46
  const allowPrivateNetwork = takeBooleanOption(args, "--allow-private-network");
@@ -49,6 +51,21 @@ async function edit(argv: string[], deps: RuntimeApiDeps): Promise<void> {
49
51
  if (authMode !== undefined) patch.authMode = authMode;
50
52
  if (note !== undefined) patch.note = note;
51
53
  if (apiKeyTransport !== undefined) patch.apiKeyTransport = apiKeyTransport;
54
+ if (headers !== undefined) {
55
+ if (headers === "-") {
56
+ patch.headers = null;
57
+ } else {
58
+ let parsed: unknown;
59
+ try { parsed = JSON.parse(headers); } catch { throw new CliUsageError("--headers must be valid JSON"); }
60
+ if (parsed === null) {
61
+ patch.headers = null;
62
+ } else if (typeof parsed !== "object" || Array.isArray(parsed)) {
63
+ throw new CliUsageError("--headers must be a JSON object like {\"X-Custom\":\"value\"}");
64
+ } else {
65
+ patch.headers = parsed;
66
+ }
67
+ }
68
+ }
52
69
  if (enabled !== undefined) patch.disabled = !enabled;
53
70
  if (liveModels !== undefined) patch.liveModels = liveModels;
54
71
  if (allowPrivateNetwork !== undefined) patch.allowPrivateNetwork = allowPrivateNetwork;
@@ -8,10 +8,11 @@
8
8
  * show <name> Show provider config details (secrets masked)
9
9
  * set-default <name> Change the default provider
10
10
  */
11
- import { apiKeyTransportConfigError, hasOwnProvider, isValidProviderName, loadConfig, saveConfig } from "../config";
11
+ import { apiKeyTransportConfigError, hasOwnProvider, isValidProviderName, loadConfig, sanitizeModelCostsForDisplay, saveConfig } from "../config";
12
12
  import { hasHelpFlag } from "./help";
13
13
  import { getProviderRegistryEntry, PROVIDER_REGISTRY } from "../providers/registry";
14
14
  import { providerConfigSeed } from "../providers/derive";
15
+ import { dropProviderCustomModels } from "../providers/provider-id-rewrite";
15
16
  import type { OcxProviderConfig } from "../types";
16
17
  import { findLiveProxy } from "../server/proxy-liveness";
17
18
  import { syncModelsToCodex } from "../codex/sync";
@@ -209,7 +210,14 @@ async function handleAdd(args: string[]): Promise<void> {
209
210
  provConfig.apiKeyTransport = apiKeyTransport;
210
211
  }
211
212
 
213
+ const existingProvider = config.providers[name];
212
214
  config.providers[name] = provConfig;
215
+ // A --force overwrite rotates the key/endpoint but must not drop a
216
+ // user-configured price overlay (same rule as the /api/providers path and
217
+ // the login paths); there is no explicit clear/replace flag yet.
218
+ if (existingProvider?.modelCosts !== undefined && provConfig.modelCosts === undefined) {
219
+ provConfig.modelCosts = existingProvider.modelCosts;
220
+ }
213
221
  if (allowPrivateNetwork) provConfig.allowPrivateNetwork = true;
214
222
  if (setDefault) config.defaultProvider = name;
215
223
 
@@ -229,12 +237,18 @@ async function handleAdd(args: string[]): Promise<void> {
229
237
  return;
230
238
  }
231
239
 
240
+ let codexSyncSkipped = false;
232
241
  if (wantsSync) {
233
242
  const live = await findLiveProxy();
234
243
  if (live) {
235
- await syncModelsToCodex(live.port).catch(e => {
244
+ const synced = await syncModelsToCodex(live.port).catch(e => {
236
245
  console.error(`Warning: sync failed: ${e instanceof Error ? e.message : String(e)}`);
246
+ return null;
237
247
  });
248
+ if (synced?.status === "skipped") {
249
+ codexSyncSkipped = true;
250
+ console.log("Provider saved; Codex integration is OFF, so Codex sync was skipped.");
251
+ }
238
252
  }
239
253
  }
240
254
 
@@ -249,7 +263,7 @@ async function handleAdd(args: string[]): Promise<void> {
249
263
  console.log(` Set API key with: ocx provider add ${name} --api-key <key> --force`);
250
264
  console.log(` Or set env var: ${envKey}`);
251
265
  }
252
- if (wantsSync) {
266
+ if (wantsSync && !codexSyncSkipped) {
253
267
  console.log(` Models synced to Codex.`);
254
268
  } else {
255
269
  console.log(` Apply to Codex: ocx sync`);
@@ -296,6 +310,7 @@ function handleRemove(args: string[]): void {
296
310
  }
297
311
 
298
312
  delete config.providers[name];
313
+ const droppedCustomModels = dropProviderCustomModels(config, name);
299
314
  validateAndSave(config);
300
315
 
301
316
 
@@ -306,11 +321,16 @@ function handleRemove(args: string[]): void {
306
321
  remainingProviders: Object.keys(config.providers),
307
322
  defaultProvider: config.defaultProvider,
308
323
  needsSync: true,
324
+ ...(droppedCustomModels > 0 ? { droppedCustomModels } : {}),
309
325
  }, null, 2));
310
326
  return;
311
327
  }
312
328
 
313
329
  console.log(`✅ Provider "${name}" removed.`);
330
+ if (droppedCustomModels > 0) {
331
+ const plural = droppedCustomModels === 1 ? "model" : "models";
332
+ console.log(` Also removed ${droppedCustomModels} custom ${plural} that belonged to it.`);
333
+ }
314
334
  }
315
335
 
316
336
  // ---------------------------------------------------------------------------
@@ -336,6 +356,7 @@ function handleShow(args: string[]): void {
336
356
  const prov = config.providers[name];
337
357
  const display = {
338
358
  ...prov,
359
+ ...(prov.modelCosts !== undefined ? { modelCosts: sanitizeModelCostsForDisplay(prov.modelCosts) } : {}),
339
360
  ...(prov.apiKey ? { apiKey: maskSecret(prov.apiKey) } : {}),
340
361
  ...(prov.apiKeyPool ? { apiKeyPool: prov.apiKeyPool.map(e => ({ ...e, key: maskSecret(e.key) })) } : {}),
341
362
  };