@iislee/opencodex 2.11.0 → 2.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,175 @@
1
+ import { createAnthropicAdapter } from "./anthropic";
2
+ import { createAzureAdapter } from "./azure";
3
+ import type { ProviderAdapter } from "./base";
4
+ import { withClinePassDeepSeekV4ToolReplayCompatibility } from "./cline-pass-deepseek-v4-tool-replay";
5
+ import { createCommandCodeAdapter } from "./command-code";
6
+ import { createCursorAdapter } from "./cursor";
7
+ import { createGoogleAdapter } from "./google";
8
+ import { createKiroAdapter } from "./kiro";
9
+ import { createMimoFreeAdapter } from "./mimo-free";
10
+ import { createOpenAIChatAdapter } from "./openai-chat";
11
+ import { createResponsesPassthroughAdapter } from "./openai-responses";
12
+ import type { OcxProviderConfig } from "../types";
13
+ import { createAdapterTierMetadata } from "../providers/fastwire";
14
+
15
+ export type AdapterCacheRetention = "none" | "short" | "long";
16
+
17
+ export interface AdapterFactoryContext {
18
+ cacheRetention?: AdapterCacheRetention;
19
+ }
20
+
21
+ export type AdapterWire =
22
+ | "command-code"
23
+ | "openai-chat"
24
+ | "anthropic"
25
+ | "openai-responses"
26
+ | "google"
27
+ | "kiro"
28
+ | "cursor";
29
+
30
+ export type AdapterMutationContract =
31
+ | "codex-owned"
32
+ | "codex-owned-with-gated-native-fallback";
33
+
34
+ type AdapterFactory = (
35
+ provider: OcxProviderConfig,
36
+ context: AdapterFactoryContext,
37
+ ) => ProviderAdapter;
38
+
39
+ type DirectAdapterDefinition = {
40
+ wire: AdapterWire;
41
+ mutation: AdapterMutationContract;
42
+ create: AdapterFactory;
43
+ };
44
+
45
+ type InheritedAdapterDefinition = {
46
+ /** Semantic contract inheritance only. Runtime construction remains independent. */
47
+ contractParent: string;
48
+ create: AdapterFactory;
49
+ };
50
+
51
+ type AdapterDefinition = DirectAdapterDefinition | InheritedAdapterDefinition;
52
+
53
+ export const ADAPTER_REGISTRY = {
54
+ "command-code": {
55
+ wire: "command-code",
56
+ mutation: "codex-owned",
57
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createCommandCodeAdapter(provider),
58
+ },
59
+ "openai-chat": {
60
+ wire: "openai-chat",
61
+ mutation: "codex-owned",
62
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) =>
63
+ withClinePassDeepSeekV4ToolReplayCompatibility(createOpenAIChatAdapter(provider)),
64
+ },
65
+ anthropic: {
66
+ wire: "anthropic",
67
+ mutation: "codex-owned",
68
+ create: (provider: OcxProviderConfig, context: AdapterFactoryContext) =>
69
+ createAnthropicAdapter(provider, context.cacheRetention),
70
+ },
71
+ "openai-responses": {
72
+ wire: "openai-responses",
73
+ mutation: "codex-owned",
74
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) =>
75
+ createResponsesPassthroughAdapter(provider),
76
+ },
77
+ google: {
78
+ wire: "google",
79
+ mutation: "codex-owned",
80
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createGoogleAdapter(provider),
81
+ },
82
+ kiro: {
83
+ wire: "kiro",
84
+ mutation: "codex-owned",
85
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createKiroAdapter(provider),
86
+ },
87
+ azure: {
88
+ contractParent: "openai-responses",
89
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createAzureAdapter(provider),
90
+ },
91
+ "azure-openai": {
92
+ contractParent: "openai-responses",
93
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createAzureAdapter(provider),
94
+ },
95
+ cursor: {
96
+ wire: "cursor",
97
+ mutation: "codex-owned-with-gated-native-fallback",
98
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createCursorAdapter(provider),
99
+ },
100
+ "mimo-free": {
101
+ contractParent: "openai-chat",
102
+ create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createMimoFreeAdapter(provider),
103
+ },
104
+ } as const satisfies Record<string, AdapterDefinition>;
105
+
106
+ export type AdapterId = keyof typeof ADAPTER_REGISTRY;
107
+ export type RegisteredAdapterDefinition = typeof ADAPTER_REGISTRY[AdapterId];
108
+
109
+ export function adapterDefinitions(): Array<[AdapterId, RegisteredAdapterDefinition]> {
110
+ return Object.entries(ADAPTER_REGISTRY) as Array<[AdapterId, RegisteredAdapterDefinition]>;
111
+ }
112
+
113
+ export function getAdapterDefinition(adapterId: unknown): RegisteredAdapterDefinition | undefined {
114
+ if (typeof adapterId !== "string" || !Object.hasOwn(ADAPTER_REGISTRY, adapterId)) return undefined;
115
+ return ADAPTER_REGISTRY[adapterId as AdapterId];
116
+ }
117
+
118
+ export function effectiveAdapterContract(adapterId: string): Readonly<{
119
+ wire: AdapterWire;
120
+ mutation: AdapterMutationContract;
121
+ }> {
122
+ const visited = new Set<string>();
123
+ let current = adapterId;
124
+
125
+ while (true) {
126
+ if (visited.has(current)) {
127
+ throw new Error(`Adapter contract cycle detected at ${current}`);
128
+ }
129
+ visited.add(current);
130
+
131
+ const definition = getAdapterDefinition(current);
132
+ if (!definition) throw new Error(`Unknown adapter: ${current}`);
133
+ if ("wire" in definition) {
134
+ return { wire: definition.wire, mutation: definition.mutation };
135
+ }
136
+ current = definition.contractParent;
137
+ }
138
+ }
139
+
140
+ export function createRegisteredAdapter(
141
+ provider: OcxProviderConfig,
142
+ context: AdapterFactoryContext = {},
143
+ ): ProviderAdapter {
144
+ const definition = getAdapterDefinition(provider.adapter);
145
+ if (!definition) throw new Error(`Unknown adapter: ${provider.adapter}`);
146
+ const adapter = definition.create(provider, context);
147
+ const buildRequest = adapter.buildRequest.bind(adapter);
148
+ adapter.buildRequest = (parsed, incoming) => {
149
+ const attachTierMetadata = (request: Awaited<ReturnType<ProviderAdapter["buildRequest"]>>) => {
150
+ // OpenAI-family adapters report the exact emitted field themselves. Other adapters
151
+ // still report an exact absence at this serialization boundary, which makes a routed
152
+ // Fast downgrade observable without asking core to infer an outbound body shape.
153
+ request.tierLog ??= createAdapterTierMetadata(
154
+ parsed.options.tierObservation,
155
+ parsed.options.tierDecision,
156
+ null,
157
+ null,
158
+ );
159
+ return request;
160
+ };
161
+ const request = buildRequest(parsed, incoming);
162
+ return request instanceof Promise
163
+ ? request.then(attachTierMetadata)
164
+ : attachTierMetadata(request);
165
+ };
166
+ if (adapter.runTurn && !adapter.tierLogForRunTurn) {
167
+ adapter.tierLogForRunTurn = parsed => createAdapterTierMetadata(
168
+ parsed.options.tierObservation,
169
+ parsed.options.tierDecision,
170
+ null,
171
+ null,
172
+ );
173
+ }
174
+ return adapter;
175
+ }
@@ -0,0 +1,67 @@
1
+ // Codex multi-agent v2 stamps a Responses-only `encrypted: true` marker on
2
+ // collaboration tool schemas (openai/codex 5f4d06ef; issue #85). It is an
3
+ // annotation for the ChatGPT backend only, so translated provider schemas must
4
+ // drop it without removing properties or definitions literally named `encrypted`.
5
+ const ENCRYPTED_MARKER_NAME_BAG_KEYS = new Set([
6
+ "properties",
7
+ "patternProperties",
8
+ "$defs",
9
+ "definitions",
10
+ "dependencies",
11
+ "dependentSchemas",
12
+ "dependentRequired",
13
+ ]);
14
+ const ENCRYPTED_MARKER_LITERAL_VALUE_KEYS = new Set(["const", "default", "enum", "examples"]);
15
+
16
+ /**
17
+ * The schema is caller-supplied, so its nesting depth is attacker-influenced. Native recursion
18
+ * would turn a deep schema into a stack overflow that takes down the request path, so this walks
19
+ * an explicit stack instead: depth costs heap, which is bounded and recoverable.
20
+ */
21
+ export function stripResponsesOnlyEncryptedMarker(node: unknown, inNameBag = false): unknown {
22
+ type Assign = (value: unknown) => void;
23
+ interface Frame { node: unknown; inNameBag: boolean; assign: Assign }
24
+
25
+ let result: unknown;
26
+ const stack: Frame[] = [{ node, inNameBag, assign: value => { result = value; } }];
27
+
28
+ while (stack.length > 0) {
29
+ const frame = stack.pop()!;
30
+ const current = frame.node;
31
+
32
+ if (Array.isArray(current)) {
33
+ const out: unknown[] = new Array(current.length);
34
+ frame.assign(out);
35
+ // Array items are schemas in their own right, never a name bag.
36
+ for (let i = current.length - 1; i >= 0; i--) {
37
+ stack.push({ node: current[i], inNameBag: false, assign: value => { out[i] = value; } });
38
+ }
39
+ continue;
40
+ }
41
+ if (!current || typeof current !== "object") {
42
+ frame.assign(current);
43
+ continue;
44
+ }
45
+
46
+ // A schema name may be `__proto__`; a null-prototype record keeps it as data.
47
+ const out: Record<string, unknown> = Object.create(null) as Record<string, unknown>;
48
+ frame.assign(out);
49
+
50
+ for (const [key, value] of Object.entries(current as Record<string, unknown>)) {
51
+ if (frame.inNameBag) {
52
+ // Inside a name bag every key is a caller-chosen name, so `encrypted` here is data.
53
+ stack.push({ node: value, inNameBag: false, assign: v => { out[key] = v; } });
54
+ } else if (key !== "encrypted") {
55
+ if (ENCRYPTED_MARKER_LITERAL_VALUE_KEYS.has(key)) {
56
+ // Literal payloads are values, not schemas: an `encrypted` key inside them is data.
57
+ out[key] = value;
58
+ } else {
59
+ const childInNameBag = ENCRYPTED_MARKER_NAME_BAG_KEYS.has(key);
60
+ stack.push({ node: value, inNameBag: childInNameBag, assign: v => { out[key] = v; } });
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ return result;
67
+ }
@@ -0,0 +1,119 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ /**
4
+ * Anthropic rejects a `tool_use.id` longer than this. Collision disambiguation has to fit
5
+ * inside it too, which is why candidates are assembled from parts instead of sliced at the end.
6
+ */
7
+ export const MAX_TOOL_CALL_ID_LENGTH = 64;
8
+
9
+ /** Hex characters of the deterministic tail. Fixed width: it is a discriminator, not a payload. */
10
+ const TOOL_CALL_ID_HASH_WIDTH = 8;
11
+
12
+ const CONFORMING_TOOL_CALL_ID = /^[a-zA-Z0-9_-]+$/;
13
+
14
+ /** An id Anthropic accepts as-is: right character set AND within the length bound. */
15
+ export function isConformingToolCallId(rawId: string): boolean {
16
+ return rawId.length > 0
17
+ && rawId.length <= MAX_TOOL_CALL_ID_LENGTH
18
+ && CONFORMING_TOOL_CALL_ID.test(rawId);
19
+ }
20
+
21
+ /**
22
+ * The parts a rewritten id is built from: the sanitized prefix and a deterministic tail
23
+ * derived from the raw id. Kept separate so collision handling can truncate the prefix
24
+ * without destroying the discriminator.
25
+ */
26
+ function toolCallIdComponents(rawId: string | undefined): { cleaned: string; hash: string } | undefined {
27
+ const raw = rawId ?? "";
28
+ if (raw.length === 0) return undefined;
29
+ const cleaned = raw.replace(/[^a-zA-Z0-9_-]/g, "_");
30
+ const hash = createHash("sha256").update(raw).digest("hex").slice(0, TOOL_CALL_ID_HASH_WIDTH);
31
+ return { cleaned, hash };
32
+ }
33
+
34
+ /** Assemble `prefix_hash`, truncating only the prefix, leaving `reserve` characters spare. */
35
+ function fitToolCallId(cleaned: string, hash: string, reserve = 0): string {
36
+ const tail = `_${hash}`;
37
+ const room = MAX_TOOL_CALL_ID_LENGTH - reserve - tail.length;
38
+ return cleaned.slice(0, Math.max(1, room)) + tail;
39
+ }
40
+
41
+ /**
42
+ * Normalize a tool call id into the character set and length Anthropic accepts.
43
+ *
44
+ * This is the stateless view, kept for callers that only need the shape of one id. It is NOT
45
+ * injective on its own: `anthropicToolCallId("call:a")` returns something like `call_a_1f2e3d4c`,
46
+ * and a raw id that already equals that value is returned unchanged — two distinct sources, one
47
+ * wire id. Anything building a whole request must use {@link createToolCallIdAllocator}, which
48
+ * reserves the conforming ids first and resolves collisions.
49
+ *
50
+ * Returns `undefined` for an empty id. Callers must handle that rather than falling back to the
51
+ * raw value: restoring `""` puts an id on the wire that Anthropic rejects (#1767).
52
+ */
53
+ export function anthropicToolCallId(rawId: string | undefined): string | undefined {
54
+ const raw = rawId ?? "";
55
+ if (raw.length === 0) return undefined;
56
+ if (isConformingToolCallId(raw)) return raw;
57
+ const parts = toolCallIdComponents(raw);
58
+ if (!parts) return undefined;
59
+ return fitToolCallId(parts.cleaned, parts.hash);
60
+ }
61
+
62
+ export type ToolCallIdAllocator = {
63
+ /** Claim an already-conforming source id so no rewrite can be handed the same value. */
64
+ reserve(rawId: string | undefined): void;
65
+ /** Wire id for a raw id, stable within the request. `undefined` means "not representable". */
66
+ allocate(rawId: string | undefined): string | undefined;
67
+ /** Wire id previously allocated for this raw id, without creating one. */
68
+ lookup(rawId: string | undefined): string | undefined;
69
+ };
70
+
71
+ /**
72
+ * Request-scoped raw-id to wire-id mapping.
73
+ *
74
+ * Two properties the stateless transform cannot provide:
75
+ *
76
+ * - **Injective.** Reserve every already-conforming id first, then allocate rewrites around them,
77
+ * appending a numeric suffix when a candidate is taken. Two distinct raw ids never share a wire id,
78
+ * including the case where one raw id already looks like another's normalized form, and including
79
+ * an ordinary 32-bit hash collision.
80
+ * - **Stable.** A tool result asks for the same raw id its call used and gets the same wire id, so
81
+ * call/result pairing survives normalization.
82
+ */
83
+ export function createToolCallIdAllocator(): ToolCallIdAllocator {
84
+ const rawToWire = new Map<string, string>();
85
+ const occupied = new Set<string>();
86
+
87
+ return {
88
+ reserve(rawId) {
89
+ if (!rawId || rawToWire.has(rawId)) return;
90
+ if (!isConformingToolCallId(rawId)) return;
91
+ rawToWire.set(rawId, rawId);
92
+ occupied.add(rawId);
93
+ },
94
+ allocate(rawId) {
95
+ if (!rawId) return undefined;
96
+ const existing = rawToWire.get(rawId);
97
+ if (existing) return existing;
98
+ if (isConformingToolCallId(rawId) && !occupied.has(rawId)) {
99
+ rawToWire.set(rawId, rawId);
100
+ occupied.add(rawId);
101
+ return rawId;
102
+ }
103
+ const parts = toolCallIdComponents(rawId);
104
+ if (!parts) return undefined;
105
+ let candidate = fitToolCallId(parts.cleaned, parts.hash);
106
+ for (let n = 2; occupied.has(candidate); n++) {
107
+ const suffix = `_${n}`;
108
+ candidate = fitToolCallId(parts.cleaned, parts.hash, suffix.length) + suffix;
109
+ }
110
+ rawToWire.set(rawId, candidate);
111
+ occupied.add(candidate);
112
+ return candidate;
113
+ },
114
+ lookup(rawId) {
115
+ if (!rawId) return undefined;
116
+ return rawToWire.get(rawId);
117
+ },
118
+ };
119
+ }
@@ -1,30 +1,62 @@
1
1
  import {
2
- isAllowedToolChoice,
3
2
  namespacedToolName,
4
- toolAllowedByChoice,
5
- toolChoiceAliases,
3
+ toolChoiceToolPredicate,
6
4
  type OcxRequestOptions,
7
5
  type OcxTool,
8
6
  type OcxProviderConfig,
9
7
  } from "../types";
10
8
 
11
- const NEIGHBOR_AGENT_TOOL_NAMES = ["Read", "Grep", "Glob", "Bash", "LS", "apply_patch"] as const;
9
+ // Tool names that exist only in OTHER agent harnesses (Claude Code and friends). Naming one
10
+ // here tells a routed model not to call it unless this turn's catalog really lists it.
11
+ //
12
+ // `apply_patch` is deliberately absent: it is Codex's own first-class edit tool, not a
13
+ // neighbor's. Under Codex code mode it is reachable as a nested `tools.apply_patch(...)`
14
+ // helper declared inside the `exec` tool description rather than as a top-level wire tool,
15
+ // so a flat catalog check cannot see it and forbidding it pushed routed models into
16
+ // `python3` heredoc edits. The sibling list in `./cursor/tool-definitions.ts` never
17
+ // included it either.
18
+ const NEIGHBOR_AGENT_TOOL_NAMES = ["Read", "Grep", "Glob", "Bash", "LS"] as const;
19
+
20
+ /**
21
+ * The two halves of the code-mode shape, kept provider-neutral here.
22
+ *
23
+ * `./cursor/tool-definitions.ts` owns the Cursor-scoped versions of these
24
+ * (`isCursorCodeModeExecTool` / `isBareCodexShellBridgeTool`), but those additionally require
25
+ * the Cursor Responses namespace. This nudge is shared by Anthropic, Google, Kiro,
26
+ * OpenAI-chat and command-code, so it needs the same semantics without that provider gate.
27
+ */
28
+ const CODEX_UNIFIED_EXEC_TOOL_NAME = "exec";
29
+ const CODEX_SHELL_BRIDGE_TOOL_NAMES = ["exec_command", "shell_command"] as const;
30
+
31
+ function isCodexCodeModeExecTool(tool: Pick<OcxTool, "namespace" | "name" | "freeform">): boolean {
32
+ return !tool.namespace && tool.name === CODEX_UNIFIED_EXEC_TOOL_NAME && tool.freeform === true;
33
+ }
34
+
35
+ /**
36
+ * BARE means un-namespaced, and the word is load-bearing.
37
+ *
38
+ * An MCP server can advertise its own `exec_command` or `shell_command` — a docker, k8s or ssh
39
+ * server plausibly does — and those arrive namespaced (`mcp__docker__exec_command`). They are
40
+ * not Codex's shell bridge, so they must not cancel code mode: a genuine code-mode turn that
41
+ * merely happens to sit beside an MCP shell tool would lose its guidance and fall back to the
42
+ * generic sentence.
43
+ *
44
+ * The Cursor original this was ported from (`isBareCodexShellBridgeTool`) carries the same
45
+ * `!tool.namespace` requirement; dropping it here made the name assert a check the body did not
46
+ * perform.
47
+ */
48
+ function isBareShellBridgeTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
49
+ return !tool.namespace && (CODEX_SHELL_BRIDGE_TOOL_NAMES as readonly string[]).includes(tool.name);
50
+ }
12
51
 
13
52
  function quoteNames(names: readonly string[]): string {
14
- return names.map(name => `\`${name}\``).join(", ");
53
+ return names.map(name => "`" + name + "`").join(", ");
15
54
  }
16
55
 
17
56
  function uniqueNames(names: readonly string[]): string[] {
18
57
  return [...new Set(names.filter(name => name.trim().length > 0))];
19
58
  }
20
59
 
21
- function toolChoiceAllows(tool: Pick<OcxTool, "namespace" | "name">, toolChoice: OcxRequestOptions["toolChoice"] | undefined): boolean {
22
- if (!toolChoice || toolChoice === "auto" || toolChoice === "required") return true;
23
- if (toolChoice === "none") return false;
24
- if (isAllowedToolChoice(toolChoice)) return toolAllowedByChoice(tool, new Set(toolChoice.allowedTools));
25
- return toolChoiceAliases(tool).includes(toolChoice.name);
26
- }
27
-
28
60
  function isOpenAIOrChatGPTHost(hostname: string): boolean {
29
61
  return hostname === "openai.com"
30
62
  || hostname.endsWith(".openai.com")
@@ -40,19 +72,58 @@ export function shouldInjectNonOpenAIToolCatalogNudge(provider: Pick<OcxProvider
40
72
  }
41
73
  }
42
74
 
43
- export function buildNonOpenAIToolCatalogNudgeFromNames(wireNames: readonly string[] | undefined): string | undefined {
75
+ /**
76
+ * Codex code mode is a SEMANTIC property, not a name.
77
+ *
78
+ * The tool that carries it is a `freeform` `exec` whose body is JavaScript evaluated in a V8
79
+ * isolate, advertised alongside no bare shell bridge. A provider is free to advertise an
80
+ * ordinary structured tool called `exec` that runs a shell string — and a catalog can list
81
+ * `exec` next to `exec_command`/`shell_command`, which is the flat-bridge shape, not code mode.
82
+ *
83
+ * Classifying on the name alone would tell those turns that `exec` takes JavaScript and that
84
+ * shell is only reachable as a nested `tools.*` helper. Both are false there, and a model that
85
+ * believes them sends the wrong arguments or avoids a legitimate execution tool entirely.
86
+ *
87
+ * So callers that HAVE the tool objects decide with the semantic predicate and pass the verified
88
+ * wire name in; the name-only entry point cannot decide it and does not try.
89
+ */
90
+ function codeModeExecWireName(
91
+ advertised: ReadonlySet<string>,
92
+ verifiedName: string | undefined,
93
+ ): string | undefined {
94
+ if (!verifiedName) return undefined;
95
+ return advertised.has(verifiedName) ? verifiedName : undefined;
96
+ }
97
+
98
+ export function buildNonOpenAIToolCatalogNudgeFromNames(
99
+ wireNames: readonly string[] | undefined,
100
+ toWireName: (name: string) => string = name => name,
101
+ codeModeExecName?: string,
102
+ ): string | undefined {
44
103
  const names = uniqueNames(wireNames ?? []);
45
104
  if (names.length === 0) return undefined;
46
105
 
47
106
  const advertised = new Set(names);
48
- const unavailableNeighborNames = NEIGHBOR_AGENT_TOOL_NAMES.filter(name => !advertised.has(name));
107
+ // Compare in the catalog's own coordinate system. `advertised` holds WIRE names, so a
108
+ // provider that rewrites them (Claude OAuth `custom_`, Anthropic compat `cx_`) would never
109
+ // match a bare neighbor name and would forbid tools the turn actually advertises -- the
110
+ // catalog would list `custom_apply_patch` while the same sentence banned `apply_patch`.
111
+ const unavailableNeighborNames = NEIGHBOR_AGENT_TOOL_NAMES.filter(
112
+ name => !advertised.has(name) && !advertised.has(toWireName(name)),
113
+ );
114
+ const verifiedCodeModeExecName = codeModeExecWireName(advertised, codeModeExecName);
49
115
 
50
116
  return [
51
117
  "Tool contract: use the current tool catalog as ground truth.",
52
- `Valid tool names for this turn are exactly ${quoteNames(names)}.`,
118
+ "Valid tool names for this turn are exactly " + quoteNames(names) + ".",
119
+ "These listed names are the complete top-level tool-call surface for this turn.",
53
120
  "Call only listed names with their listed argument keys; do not invent, translate, or rename tools.",
121
+ "Names mentioned only in instructions, tool descriptions, argument descriptions, or nested helper APIs are not additional top-level tools.",
122
+ verifiedCodeModeExecName
123
+ ? "`" + verifiedCodeModeExecName + "` is Codex code mode: its body is JavaScript evaluated in a V8 isolate. Nested helpers are called INSIDE that body as `await tools.<name>(...)`, for example `await tools.exec_command({cmd: \"ls\"})` or `await tools.codex_app__list_threads({})`. Absence from the top-level catalog or from `" + verifiedCodeModeExecName + "`'s description is not absence: deferred helpers stay callable on `tools.<name>`. Discover them from the isolate global `ALL_TOOLS`, not `tools.ALL_TOOLS`. Do not skip an available nested helper because it is omitted from the listed top-level names."
124
+ : "If a listed tool exposes nested helpers such as a tools.* API, call the listed parent tool and use those helpers only inside that tool's input.",
54
125
  unavailableNeighborNames.length > 0
55
- ? `Do not use neighboring-agent tool names ${quoteNames(unavailableNeighborNames)} unless this turn's catalog lists those exact names.`
126
+ ? "Do not use neighboring-agent tool names " + quoteNames(unavailableNeighborNames) + " unless this turn's catalog lists those exact names."
56
127
  : undefined,
57
128
  "If you need shell, file search, file read, edit, or discovery behavior, choose the listed tool that provides that capability.",
58
129
  "Count a tool call only after its tool result returns; batch independent read-only calls when the runtime supports it.",
@@ -60,12 +131,24 @@ export function buildNonOpenAIToolCatalogNudgeFromNames(wireNames: readonly stri
60
131
  }
61
132
 
62
133
  export function buildNonOpenAIToolCatalogNudgeForTools(
63
- tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
134
+ tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
64
135
  toolChoice?: OcxRequestOptions["toolChoice"],
65
136
  toWireName: (tool: Pick<OcxTool, "namespace" | "name">) => string = tool => namespacedToolName(tool.namespace, tool.name),
66
137
  ): string | undefined {
67
- const visibleNames = tools
68
- ?.filter(tool => toolChoiceAllows(tool, toolChoice))
69
- .map(toWireName);
70
- return buildNonOpenAIToolCatalogNudgeFromNames(visibleNames);
138
+ const visible = tools?.filter(toolChoiceToolPredicate(toolChoice, tools));
139
+ const visibleNames = visible?.map(toWireName);
140
+ // Decide code mode from the tool OBJECTS, while the `freeform` flag still exists — reducing
141
+ // to wire names first throws away the only thing that distinguishes Codex's JavaScript
142
+ // `exec` from an ordinary structured tool that happens to share the name.
143
+ const codeModeExecTool = visible?.find(isCodexCodeModeExecTool);
144
+ const codeModeExecName = codeModeExecTool
145
+ && !visible?.some(isBareShellBridgeTool)
146
+ ? toWireName(codeModeExecTool)
147
+ : undefined;
148
+ // Neighbor names are bare and un-namespaced, so probe the same transform with a bare tool.
149
+ return buildNonOpenAIToolCatalogNudgeFromNames(
150
+ visibleNames,
151
+ name => toWireName({ name }),
152
+ codeModeExecName,
153
+ );
71
154
  }