@bitkyc08/opencodex 2.86.0 → 2.88.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 (400) hide show
  1. package/gui/dist/assets/App-CHC89EXQ.js +58 -0
  2. package/gui/dist/assets/App-wT3mXqFz.css +1 -0
  3. package/gui/dist/assets/{Tray-DyR9yBee.js → Tray-B5bC7AWL.js} +1 -1
  4. package/gui/dist/assets/index-B5bsvxor.js +94 -0
  5. package/gui/dist/assets/index-DPeB9HpV.css +1 -0
  6. package/gui/dist/assets/quota-summary-D8y2wTsB.js +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/package.json +1 -1
  9. package/src/adapters/anthropic/beta-allowlist.ts +9 -8
  10. package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
  11. package/src/adapters/anthropic/passthrough.ts +7 -23
  12. package/src/adapters/anthropic-progress.ts +84 -0
  13. package/src/adapters/anthropic-rejection-memo.ts +71 -0
  14. package/src/adapters/anthropic-replay.ts +135 -0
  15. package/src/adapters/anthropic-tool-catalog.ts +11 -0
  16. package/src/adapters/anthropic.ts +151 -33
  17. package/src/adapters/base.ts +2 -0
  18. package/src/adapters/claude-cli/adapter.ts +111 -23
  19. package/src/adapters/claude-cli/profiles.ts +2 -1
  20. package/src/adapters/claude-cli/stable-replay.ts +108 -0
  21. package/src/adapters/claude-cli/usage-admission.ts +230 -0
  22. package/src/adapters/coding-agent/protocol.ts +1 -1
  23. package/src/adapters/coding-agent/turn.ts +18 -2
  24. package/src/adapters/dsh-account.ts +97 -0
  25. package/src/adapters/google-progress-history.ts +53 -0
  26. package/src/adapters/google.ts +52 -9
  27. package/src/adapters/openai-chat/messages.ts +4 -3
  28. package/src/adapters/openai-chat/passthrough.ts +8 -2
  29. package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
  30. package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
  31. package/src/adapters/openai-responses/passthrough.ts +57 -125
  32. package/src/adapters/openai-responses/request-strips.ts +25 -3
  33. package/src/adapters/openai-responses/transport.ts +81 -0
  34. package/src/adapters/qoder/adapter.ts +4 -2
  35. package/src/adapters/registry.ts +5 -0
  36. package/src/adapters/zed.ts +26 -1
  37. package/src/advisor/activity.ts +55 -0
  38. package/src/advisor/budget.ts +62 -0
  39. package/src/advisor/consult.ts +4 -1
  40. package/src/advisor/context.ts +16 -4
  41. package/src/advisor/evidence-tool.ts +21 -0
  42. package/src/advisor/evidence.ts +117 -0
  43. package/src/advisor/runtime.ts +79 -31
  44. package/src/advisor/settings.ts +11 -2
  45. package/src/bridge/errors.ts +19 -1
  46. package/src/bridge/internal.ts +7 -1
  47. package/src/bridge/response-json.ts +18 -3
  48. package/src/bridge/sse.ts +59 -8
  49. package/src/bridge/terminal-refusal.ts +59 -0
  50. package/src/claude/desktop-3p-library.ts +32 -7
  51. package/src/claude/desktop-3p.ts +55 -13
  52. package/src/claude/desktop-first-party.ts +1 -1
  53. package/src/claude/desktop-picker-platform.ts +4 -0
  54. package/src/claude/desktop-picker.ts +15 -8
  55. package/src/claude/desktop-system-proxy.ts +50 -4
  56. package/src/claude/inbound-content-options.ts +77 -0
  57. package/src/claude/inbound.ts +33 -0
  58. package/src/claude/intercept/picker-ca-startup.ts +2 -1
  59. package/src/claude/intercept/picker-runtime.ts +6 -5
  60. package/src/claude/intercept/picker-trust-windows.ts +338 -0
  61. package/src/claude/intercept/picker-trust.ts +19 -0
  62. package/src/claude/intercept/port-policy.ts +30 -0
  63. package/src/claude/intercept/runtime.ts +97 -94
  64. package/src/claude/outbound.ts +46 -13
  65. package/src/cli/account-api.ts +1 -0
  66. package/src/cli/account-policy-dto.ts +6 -0
  67. package/src/cli/account-policy.ts +34 -5
  68. package/src/cli/account-preservation.ts +44 -0
  69. package/src/cli/account.ts +8 -2
  70. package/src/cli/advisor.ts +17 -3
  71. package/src/cli/capabilities-accounts.ts +20 -1
  72. package/src/cli/capabilities-agents-routing.ts +5 -2
  73. package/src/cli/capabilities-base.ts +38 -10
  74. package/src/cli/capabilities-observe-system.ts +63 -3
  75. package/src/cli/capabilities-provider-models.ts +11 -0
  76. package/src/cli/codex-cli-update.ts +151 -41
  77. package/src/cli/codex-provider.ts +44 -0
  78. package/src/cli/combo-input.ts +10 -1
  79. package/src/cli/combo-result.ts +1 -1
  80. package/src/cli/combo.ts +2 -1
  81. package/src/cli/cross-home-owner.ts +33 -16
  82. package/src/cli/dispatch.ts +25 -4
  83. package/src/cli/doctor.ts +6 -1
  84. package/src/cli/ensure-desktop-cold-start.ts +60 -7
  85. package/src/cli/help.ts +3 -2
  86. package/src/cli/index.ts +1 -1
  87. package/src/cli/integration-plan-dto.ts +1 -0
  88. package/src/cli/log-history.ts +172 -0
  89. package/src/cli/loopback-family.ts +31 -0
  90. package/src/cli/models-runtime-subcommands.ts +1 -0
  91. package/src/cli/models-runtime.ts +72 -8
  92. package/src/cli/observe-stream.ts +2 -0
  93. package/src/cli/observe.ts +16 -4
  94. package/src/cli/provider.ts +27 -5
  95. package/src/cli/registry.ts +28 -8
  96. package/src/cli/runtime-api.ts +5 -3
  97. package/src/cli/system-command.ts +40 -8
  98. package/src/cli/uninstall-client-state.ts +32 -0
  99. package/src/cli/usage-compare.ts +309 -0
  100. package/src/cli/usage-model-search.ts +4 -4
  101. package/src/cli/usage-report.ts +2 -2
  102. package/src/cli/v2.ts +1 -1
  103. package/src/client/machine-listener.ts +1 -3
  104. package/src/client/runtime.ts +1 -0
  105. package/src/clients/client-path.ts +51 -0
  106. package/src/clients/config-export/contracts.ts +2 -1
  107. package/src/clients/config-export.ts +18 -44
  108. package/src/clients/gentle-shell-path.ts +87 -0
  109. package/src/codex/account-auto-switch.ts +2 -0
  110. package/src/codex/account-identity.ts +29 -0
  111. package/src/codex/account-label.ts +1 -1
  112. package/src/codex/account-lifecycle.ts +21 -5
  113. package/src/codex/account-preservation.ts +28 -0
  114. package/src/codex/account-use-remaining.ts +23 -0
  115. package/src/codex/app-server-processes.ts +97 -7
  116. package/src/codex/app-server-restart-service.ts +55 -4
  117. package/src/codex/auth-api/account-list.ts +4 -0
  118. package/src/codex/auth-api/account-pause-group.ts +6 -50
  119. package/src/codex/auth-api/account-preservation.ts +57 -0
  120. package/src/codex/auth-api/routes.ts +8 -0
  121. package/src/codex/auth-api/use-remaining-route.ts +36 -0
  122. package/src/codex/auth-api.ts +0 -1
  123. package/src/codex/auth-context.ts +2 -2
  124. package/src/codex/catalog/auto-review.ts +20 -3
  125. package/src/codex/catalog/build-entries.ts +9 -1
  126. package/src/codex/catalog/combo-member.ts +14 -5
  127. package/src/codex/catalog/configured-tiers.ts +1 -1
  128. package/src/codex/catalog/gather-capture.ts +2 -0
  129. package/src/codex/catalog/metadata.ts +11 -9
  130. package/src/codex/catalog/model-hints.ts +21 -16
  131. package/src/codex/catalog/model-visibility.ts +3 -1
  132. package/src/codex/catalog/parsing.ts +30 -86
  133. package/src/codex/catalog/provider-models.ts +36 -34
  134. package/src/codex/catalog/routed-gather.ts +14 -13
  135. package/src/codex/cli-install-provenance.ts +105 -17
  136. package/src/codex/cli-update-plan.ts +545 -0
  137. package/src/codex/config-write-lock.ts +23 -2
  138. package/src/codex/desktop-app/picker-freshness.ts +96 -0
  139. package/src/codex/desktop-app-restart.ts +21 -0
  140. package/src/codex/desktop-compatibility/installed-build.ts +24 -6
  141. package/src/codex/desktop-compatibility/routing-preflight.ts +1 -1
  142. package/src/codex/desktop-compatibility/runtime.ts +12 -3
  143. package/src/codex/desktop-compatibility/windows-key-protection.ts +115 -9
  144. package/src/codex/features.ts +85 -45
  145. package/src/codex/inject/history-failure.ts +27 -0
  146. package/src/codex/inject/restore.ts +24 -2
  147. package/src/codex/inject/routing-classify.ts +4 -3
  148. package/src/codex/inject.ts +18 -27
  149. package/src/codex/main-account-hard-lock.ts +30 -1
  150. package/src/codex/native-profile-startup.ts +1 -1
  151. package/src/codex/ocx-compaction-history.ts +12 -10
  152. package/src/codex/paths.ts +86 -1
  153. package/src/codex/provider-routing.ts +174 -0
  154. package/src/codex/refresh.ts +2 -2
  155. package/src/codex/routing/health-store.ts +1 -1
  156. package/src/codex/routing/selection.ts +4 -3
  157. package/src/codex/routing/thread-affinity.ts +1 -1
  158. package/src/codex/signed-in-identity.ts +43 -0
  159. package/src/codex/subagent-model-fallback.ts +1 -1
  160. package/src/codex/sync.ts +6 -1
  161. package/src/codex/user-identity.ts +16 -5
  162. package/src/codex/websocket-activity.ts +161 -0
  163. package/src/codex/websocket-registry.ts +25 -1
  164. package/src/codex/windows-local-appdata.ts +84 -0
  165. package/src/combos/failover.ts +6 -1
  166. package/src/combos/index.ts +1 -0
  167. package/src/combos/resolve.ts +46 -10
  168. package/src/combos/types.ts +15 -0
  169. package/src/config/diagnostics.ts +33 -6
  170. package/src/config/live-reconcile.ts +38 -2
  171. package/src/config/load-degrade.ts +17 -0
  172. package/src/config/opencode-wire-upgrade.ts +54 -0
  173. package/src/config/opencode-zen-upgrade.ts +53 -0
  174. package/src/config/owner-registry.ts +22 -17
  175. package/src/config/provider-validation.ts +45 -2
  176. package/src/config/schema/config-schema.ts +22 -0
  177. package/src/config/schema/leaf-validators.ts +38 -9
  178. package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
  179. package/src/config/schema/native-reasoning-retention.ts +26 -0
  180. package/src/config.ts +2 -0
  181. package/src/generated/compatibility-version.json +657 -297
  182. package/src/grok/sync.ts +1 -1
  183. package/src/images/loop.ts +116 -27
  184. package/src/integrations/catalog-refresh.ts +1 -1
  185. package/src/integrations/mutation-plan.ts +1 -0
  186. package/src/integrations/registry.ts +8 -0
  187. package/src/lib/codex-restart-contract.ts +15 -0
  188. package/src/lib/desktop-upstream-tunnel.ts +18 -53
  189. package/src/lib/empty-tool-catalog.ts +62 -0
  190. package/src/lib/errors.ts +19 -3
  191. package/src/lib/gcp-adc.ts +96 -9
  192. package/src/lib/gcp-credential-input.ts +12 -0
  193. package/src/lib/lab-live-route-production.ts +5 -0
  194. package/src/lib/opaque-proxy-tunnel.ts +217 -0
  195. package/src/lib/redact.ts +2 -2
  196. package/src/lib/request-failure-model.ts +2 -0
  197. package/src/oauth/account-quota-rank.ts +69 -2
  198. package/src/oauth/anthropic-account-refusal.ts +20 -2
  199. package/src/oauth/anthropic-oauth-definitions.ts +3 -1
  200. package/src/oauth/anthropic-routing.ts +1 -21
  201. package/src/oauth/anthropic.ts +38 -7
  202. package/src/oauth/callback-server.ts +27 -1
  203. package/src/oauth/chatgpt-device.ts +1 -1
  204. package/src/oauth/chatgpt-shared.ts +83 -0
  205. package/src/oauth/chatgpt.ts +8 -72
  206. package/src/oauth/dsh.ts +203 -0
  207. package/src/oauth/generic-account-failover.ts +40 -11
  208. package/src/oauth/generic-session-affinity.ts +125 -0
  209. package/src/oauth/index.ts +184 -109
  210. package/src/oauth/local-token-detect.ts +21 -1
  211. package/src/oauth/login-cli-errors.ts +44 -0
  212. package/src/oauth/login-cli.ts +69 -7
  213. package/src/oauth/login-flow-state.ts +371 -23
  214. package/src/oauth/meta-muse-errors.ts +41 -0
  215. package/src/oauth/meta-muse-keychain.ts +52 -0
  216. package/src/oauth/meta-muse.ts +51 -84
  217. package/src/oauth/model-discovery-auth.ts +3 -0
  218. package/src/oauth/pool-settings-capability.ts +4 -2
  219. package/src/oauth/refresh-flight-retirement.ts +48 -0
  220. package/src/oauth/session-affinity-key.ts +23 -0
  221. package/src/oauth/store-anthropic-instance.ts +9 -2
  222. package/src/oauth/store.ts +12 -5
  223. package/src/protocols/encoders/adapter-events.ts +6 -5
  224. package/src/protocols/encoders/messages.ts +9 -6
  225. package/src/protocols/provider-summary.ts +2 -1
  226. package/src/providers/api-key-cooldowns.ts +49 -0
  227. package/src/providers/api-key-resolve.ts +11 -6
  228. package/src/providers/api-key-response-ownership.ts +57 -0
  229. package/src/providers/api-key-selection.ts +31 -6
  230. package/src/providers/api-keys.ts +214 -3
  231. package/src/providers/claude-cli-usage.ts +96 -0
  232. package/src/providers/dsh-account-destination.ts +31 -0
  233. package/src/providers/dsh-account-models.ts +41 -0
  234. package/src/providers/gcp-credential-cleanup.ts +59 -0
  235. package/src/providers/key-failover.ts +54 -50
  236. package/src/providers/key-store.ts +7 -2
  237. package/src/providers/model-rename-fields.ts +3 -0
  238. package/src/providers/model-rename-migration.ts +2 -2
  239. package/src/providers/openai-tiers-destination.ts +11 -2
  240. package/src/providers/openai-tiers.ts +5 -12
  241. package/src/providers/opencode-go-transport.ts +3 -1
  242. package/src/providers/opencode-zen-rate-limit.ts +7 -2
  243. package/src/providers/quota/account-cache.ts +6 -5
  244. package/src/providers/quota/account-row.ts +34 -0
  245. package/src/providers/quota/antigravity.ts +28 -7
  246. package/src/providers/quota/dsh-account.ts +70 -0
  247. package/src/providers/quota/vendor-probes-oauth.ts +1 -93
  248. package/src/providers/quota-types.ts +2 -0
  249. package/src/providers/quota.ts +14 -20
  250. package/src/providers/registry/entries-core.ts +37 -8
  251. package/src/providers/registry/types.ts +1 -1
  252. package/src/providers/request-pacing.ts +77 -19
  253. package/src/providers/routed-config.ts +339 -0
  254. package/src/providers/service-tier.ts +2 -1
  255. package/src/quota/window-mapping.ts +5 -2
  256. package/src/responses/anthropic-progress.ts +34 -0
  257. package/src/responses/assistant-replay.ts +35 -0
  258. package/src/responses/compaction-history-framing.ts +65 -0
  259. package/src/responses/compaction.ts +6 -1
  260. package/src/responses/incomplete-reason.ts +31 -0
  261. package/src/responses/parser.ts +50 -5
  262. package/src/responses/reasoning-envelope.ts +4 -0
  263. package/src/responses/reasoning-replay-cache.ts +74 -6
  264. package/src/responses/reasoning-retention.ts +173 -0
  265. package/src/responses/retained-compaction.ts +46 -0
  266. package/src/responses/schema.ts +23 -0
  267. package/src/router.ts +8 -321
  268. package/src/routing/analytics.ts +7 -15
  269. package/src/routing/health.ts +37 -22
  270. package/src/routing/history/indexer.ts +6 -5
  271. package/src/routing/history/ingest.ts +6 -2
  272. package/src/routing/profile.ts +1 -1
  273. package/src/server/admission-model-scope.ts +17 -0
  274. package/src/server/auth-cors.ts +11 -0
  275. package/src/server/chat-completions.ts +7 -1
  276. package/src/server/chat-native-reasoning.ts +123 -0
  277. package/src/server/chat-native-sse.ts +110 -7
  278. package/src/server/chat-native.ts +76 -17
  279. package/src/server/claude-messages.ts +56 -414
  280. package/src/server/effort-policy.ts +1 -1
  281. package/src/server/images.ts +15 -2
  282. package/src/server/index/live-sideband.ts +3 -2
  283. package/src/server/index/model-alias-id.ts +36 -0
  284. package/src/server/index/optional-listeners.ts +2 -0
  285. package/src/server/index/serve-options.ts +20 -6
  286. package/src/server/index/startup-warnings.ts +2 -0
  287. package/src/server/index/websocket-handler.ts +18 -4
  288. package/src/server/index.ts +8 -8
  289. package/src/server/inference/advisor-diagnostics.ts +31 -0
  290. package/src/server/lifecycle.ts +13 -1
  291. package/src/server/management/advisor-routes.ts +15 -4
  292. package/src/server/management/claude-desktop-picker-routes.ts +1 -1
  293. package/src/server/management/combo-routes.ts +176 -50
  294. package/src/server/management/companion-routes.ts +1 -1
  295. package/src/server/management/config-routes.ts +75 -4
  296. package/src/server/management/cursor-integration-routes.ts +1 -1
  297. package/src/server/management/model-routes.ts +11 -6
  298. package/src/server/management/model-rows.ts +14 -0
  299. package/src/server/management/native-integration-routes.ts +2 -7
  300. package/src/server/management/native-reasoning-retention-routes.ts +41 -0
  301. package/src/server/management/oauth-account-routes.ts +87 -14
  302. package/src/server/management/provider-gcp-credential-routes.ts +29 -0
  303. package/src/server/management/provider-key-pacing-routes.ts +31 -0
  304. package/src/server/management/provider-overwrite-carry.ts +7 -0
  305. package/src/server/management/provider-routes.ts +25 -30
  306. package/src/server/management/route-registry.ts +10 -1
  307. package/src/server/management-api.ts +3 -1
  308. package/src/server/messages-native-tool-guard.ts +185 -0
  309. package/src/server/messages-native.ts +117 -24
  310. package/src/server/messages-shared.ts +431 -0
  311. package/src/server/relay.ts +1 -1
  312. package/src/server/request-log-terminal-status.ts +1 -1
  313. package/src/server/request-log.ts +6 -1
  314. package/src/server/responses/account-change-state.ts +8 -2
  315. package/src/server/responses/adapter-continuation.ts +47 -19
  316. package/src/server/responses/adapter-delivery.ts +72 -12
  317. package/src/server/responses/adapter-dispatch.ts +46 -3
  318. package/src/server/responses/advisor-retention.ts +117 -0
  319. package/src/server/responses/advisor-slot.ts +73 -41
  320. package/src/server/responses/anthropic-thinking-recovery.ts +153 -0
  321. package/src/server/responses/codex-ws-wire.ts +15 -8
  322. package/src/server/responses/combo-stream-preflight.ts +3 -2
  323. package/src/server/responses/compact.ts +303 -125
  324. package/src/server/responses/compaction-recovery.ts +20 -10
  325. package/src/server/responses/compaction-retention.ts +61 -0
  326. package/src/server/responses/context-overflow.ts +11 -6
  327. package/src/server/responses/core-auth.ts +6 -0
  328. package/src/server/responses/core-codex-account.ts +11 -1
  329. package/src/server/responses/core-combo-failure.ts +2 -0
  330. package/src/server/responses/core-combo.ts +121 -36
  331. package/src/server/responses/core-errors.ts +3 -3
  332. package/src/server/responses/core-lifetime.ts +8 -4
  333. package/src/server/responses/core-opaque-recovery.ts +35 -0
  334. package/src/server/responses/core-options.ts +7 -0
  335. package/src/server/responses/core-pipeline.ts +141 -0
  336. package/src/server/responses/core-replay.ts +23 -3
  337. package/src/server/responses/core.ts +2 -115
  338. package/src/server/responses/fetch-helpers.ts +73 -19
  339. package/src/server/responses/main-hard-lock-routing.ts +109 -0
  340. package/src/server/responses/native-response-control.ts +4 -2
  341. package/src/server/responses/passthrough-delivery.ts +3 -1
  342. package/src/server/responses/passthrough-dispatch.ts +15 -13
  343. package/src/server/responses/passthrough-execution.ts +3 -2
  344. package/src/server/responses/request-prepare.ts +77 -12
  345. package/src/server/responses/request-sidecar-auth.ts +2 -2
  346. package/src/server/responses/request-transport.ts +104 -27
  347. package/src/server/responses/response-effects.ts +2 -0
  348. package/src/server/responses/response-tool-ownership.ts +21 -0
  349. package/src/server/responses/run-turn-execution.ts +96 -30
  350. package/src/server/responses/sidecar-execution.ts +63 -9
  351. package/src/server/responses/sidecar-send-budget.ts +2 -2
  352. package/src/server/responses/terminal-guard.ts +2 -16
  353. package/src/server/responses-undeclared-tool-guard.ts +1 -1
  354. package/src/server/ws-bridge.ts +2 -0
  355. package/src/service/auth-preflight.ts +71 -0
  356. package/src/service/cli.ts +4 -2
  357. package/src/service/definition.ts +97 -0
  358. package/src/service/guards.ts +1 -61
  359. package/src/service/health-sentinel-linux.ts +112 -0
  360. package/src/service/health-sentinel-main.ts +76 -57
  361. package/src/service/health.ts +5 -89
  362. package/src/service/launchd.ts +27 -7
  363. package/src/service/logging.ts +72 -9
  364. package/src/service/repair.ts +2 -1
  365. package/src/service/state.ts +7 -8
  366. package/src/service/systemd.ts +1 -1
  367. package/src/service/windows-guarded-manager.ts +2 -1
  368. package/src/service/windows-ops.ts +1 -1
  369. package/src/service/windows-scheduler.ts +2 -7
  370. package/src/service/windows-taskxml.ts +2 -2
  371. package/src/service/windows-wscript.ts +14 -0
  372. package/src/service.ts +4 -2
  373. package/src/sidecar/auth.ts +2 -0
  374. package/src/types/config.ts +64 -3
  375. package/src/types/opencode-go.ts +61 -0
  376. package/src/types/opencode-zen.ts +35 -0
  377. package/src/types/provider.ts +32 -6
  378. package/src/types/request.ts +31 -2
  379. package/src/types/wire.ts +31 -37
  380. package/src/types.ts +2 -0
  381. package/src/update/npm-invocation.mjs +12 -2
  382. package/src/usage/cost.ts +48 -12
  383. package/src/usage/expected-prices.ts +3 -0
  384. package/src/usage/ledger-retention.ts +2 -1
  385. package/src/usage/ledger-scanner.ts +6 -5
  386. package/src/usage/log.ts +17 -8
  387. package/src/usage/summary.ts +30 -11
  388. package/src/usage/telemetry-contract.ts +1 -0
  389. package/src/usage/user-cost-overlays.ts +14 -19
  390. package/src/usage/user-cost-validation.ts +38 -0
  391. package/src/vision/eligibility.ts +13 -0
  392. package/src/web-search/anthropic-history.ts +59 -0
  393. package/src/web-search/loop.ts +236 -73
  394. package/src/web-search/progress-stream.ts +15 -2
  395. package/src/web-search/run-turn-loop.ts +9 -1
  396. package/gui/dist/assets/App-BjlttVLy.js +0 -58
  397. package/gui/dist/assets/App-CSJvmjNs.css +0 -1
  398. package/gui/dist/assets/index-BB6uK6tU.css +0 -1
  399. package/gui/dist/assets/index-BMssP4k3.js +0 -94
  400. package/gui/dist/assets/quota-summary-D8M1bc_R.js +0 -1
@@ -35,7 +35,6 @@ import {
35
35
  import type { OcxConfig, OcxProviderConfig } from "../../types";
36
36
  import { modelInList } from "../../types";
37
37
  import { CODEX_REASONING_LEVELS, codexEffortRank, configuredReasoningEfforts, modelRecordValue, sanitizeCodexReasoningEfforts } from "../../reasoning-effort";
38
- import { isModelVisionSidecarConsumer } from "../../vision/eligibility";
39
38
  import { getModelMetadata, getModelMetadataCaseInsensitive, listModelMetadata, resolveMetadataProvider, type ModelMetadata } from "../../generated/model-metadata";
40
39
  import { enrichProviderFromRegistry, shouldCaseFoldMetadataModelId } from "../../providers/derive";
41
40
  import {
@@ -103,7 +102,7 @@ import type {
103
102
  CatalogTrustedOpenAiApiPolicySnapshot,
104
103
  } from "../convergence-types";
105
104
  import type { CatalogGatherProviderAuthOutcome, CatalogGatherProviderModelOutcome, GatherFlightCapture, ModelsAuthResolverFactory } from "./gather-capture";
106
- import { applyProviderConfigHints, configuredAutoCompactTokenLimit, configuredMaxInputTokens, configuredReasoningSummarySupport, modelInputModalities, routedMaxOutputTokens } from "./model-hints";
105
+ import { applyProviderConfigHints, configuredAutoCompactTokenLimit, configuredMaxInputTokens, configuredModelDisplayName, configuredReasoningSummarySupport, modelInputModalities, routedMaxOutputTokens, withVisionSidecarInput } from "./model-hints";
107
106
  import { resolveComboCatalogMember } from "./combo-member";
108
107
  import { captureGatherFlight, captureTrustedOpenAiApiPolicy, gatherFlightKey, keyedGatherBytesIdentity, withCanonicalOpenAiForwardAuthDefault } from "./gather-capture";
109
108
  import { fetchProviderModelsWithAuth, observedModelsAuthResolver, refreshingModelsAuthResolver } from "./provider-models";
@@ -330,6 +329,7 @@ async function gatherRoutedModelsUncached(
330
329
  const localProviderAuthOutcomes = capture.providerAuthOutcomes;
331
330
  const resolveAuth = capture.authResolver;
332
331
  const ttlMs = config.modelCacheTtlMs ?? DEFAULT_MODEL_CACHE_TTL_MS;
332
+ const visionSidecarEnabled = config.visionSidecar?.enabled !== false;
333
333
  // Persisted provider entries can predate newer registry fields (noVisionModels,
334
334
  // modelInputModalities, ...). The ROUTER merges registry seeds at request time
335
335
  // (routedProviderConfig), so the proxy behaves correctly — the catalog listing must see the
@@ -337,6 +337,8 @@ async function gatherRoutedModelsUncached(
337
337
  // vision-sidecar model advertised text-only, blocking image attachments app-side).
338
338
  // Enrich a CLONE: hydrated defaults must never leak into the persisted config.
339
339
  const activeProviders = capture.providers;
340
+ // Use admission-time provider clones for sidecar advertisement, custom rows and combo members.
341
+ const enrichedByName = new Map(activeProviders.map(provider => [provider.name, provider.provider]));
340
342
  const providerResults = await Promise.all(
341
343
  activeProviders.map(provider => fetchProviderModelsWithAuth(
342
344
  provider,
@@ -378,7 +380,9 @@ async function gatherRoutedModelsUncached(
378
380
  config,
379
381
  metadataModelIdCaseFoldByProvider,
380
382
  metadataConfigDirByProvider,
383
+ false,
381
384
  )
385
+ .map(model => withVisionSidecarInput(model, enrichedByName.get(model.provider), visionSidecarEnabled))
382
386
  // Drop image/video generation models (e.g. Grok image/video) by default. Cursor's static catalog
383
387
  // intentionally mirrors Cursor's public model table, including Gemini image preview, so the
384
388
  // exposure decision goes through shouldExposeRoutedModel (single choke point).
@@ -482,9 +486,6 @@ async function gatherRoutedModelsUncached(
482
486
  ...(custom.codexToolMode !== undefined ? { codexToolMode: custom.codexToolMode } : {}),
483
487
  });
484
488
  }
485
- // Enriched (registry-hydrated) provider clones — shared by combo member synthesis and
486
- // custom-model vision-sidecar inheritance so both see the same merged registry view.
487
- const enrichedByName = new Map(activeProviders.map(provider => [provider.name, provider.provider]));
488
489
  for (const id of listComboIds(config)) {
489
490
  const combo = getCombo(config, id);
490
491
  if (!combo) continue;
@@ -521,6 +522,7 @@ async function gatherRoutedModelsUncached(
521
522
  nativeAliasFallback,
522
523
  metadataModelIdCaseFoldByProvider.get(target.provider),
523
524
  metadataConfigDirByProvider.get(target.provider),
525
+ visionSidecarEnabled,
524
526
  ))
525
527
  .filter((member): member is CatalogModel => member !== undefined);
526
528
  const derived = deriveComboCatalogModel(id, combo, members);
@@ -714,7 +716,7 @@ async function gatherRoutedModelsUncached(
714
716
  const customContextHints = merged.contextWindow === undefined && effectiveProvider && canInferVendorContext(cm.provider, effectiveProvider)
715
717
  ? applyProviderConfigHints(cm.provider, effectiveProvider, { provider: cm.provider, id: cm.modelId },
716
718
  providerContextCap(config, cm.provider), metadataModelIdCaseFoldByProvider.get(cm.provider),
717
- undefined, metadataConfigDirByProvider.get(cm.provider))
719
+ undefined, metadataConfigDirByProvider.get(cm.provider), false)
718
720
  : undefined;
719
721
  const contextResolved: CatalogModel = customContextHints?.contextWindow !== undefined
720
722
  ? { ...merged, contextWindow: customContextHints.contextWindow,
@@ -762,13 +764,7 @@ async function gatherRoutedModelsUncached(
762
764
  : mergedWithHardBounds;
763
765
  const enrichedProvider = enrichedByName.get(cm.provider) ?? rawProvider;
764
766
  // Reuse the request-time consumer predicate so custom rows cannot drift from catalog hints.
765
- if (enrichedProvider && isModelVisionSidecarConsumer(enrichedProvider, mergedWithAutoCompact.id)) {
766
- const current = mergedWithAutoCompact.inputModalities ?? ["text"];
767
- if (!current.includes("image")) {
768
- return { ...mergedWithAutoCompact, inputModalities: [...current, "image"] };
769
- }
770
- }
771
- return mergedWithAutoCompact;
767
+ return withVisionSidecarInput(mergedWithAutoCompact, enrichedProvider, visionSidecarEnabled);
772
768
  });
773
769
  // Custom rows override discovered rows that encode to the same Codex-facing slug. A provider whose
774
770
  // captured discovery declares an order (preferFirst) keeps each replacement in the discovered row's
@@ -890,10 +886,12 @@ function augmentRoutedModelsWithCapturedOpenAiApiRows(
890
886
  undefined,
891
887
  metadataConfigDir,
892
888
  );
889
+ const displayName = configuredModelDisplayName(configured, id);
893
890
  return {
894
891
  provider: OPENAI_API_PROVIDER_ID,
895
892
  id,
896
893
  owned_by: OPENAI_API_PROVIDER_ID,
894
+ ...(displayName ? { displayName } : {}),
897
895
  ...(contextWindow ? { contextWindow } : {}),
898
896
  ...(maxInputTokens ? { maxInputTokens } : {}),
899
897
  ...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
@@ -948,6 +946,7 @@ export function augmentRoutedModelsWithMetadata(
948
946
  caps?: Pick<OcxConfig, "providerContextCaps">,
949
947
  metadataModelIdCaseFoldByProvider?: ReadonlyMap<string, boolean>,
950
948
  metadataConfigDirByProvider?: ReadonlyMap<string, string>,
949
+ includeVisionSidecar = true,
951
950
  ): CatalogModel[] {
952
951
  const out = [...models];
953
952
  const indexByKey = new Map(out.map((model, index) => [`${model.provider}/${model.id}`, index]));
@@ -977,6 +976,7 @@ export function augmentRoutedModelsWithMetadata(
977
976
  metadataModelIdCaseFoldByProvider?.get(provider),
978
977
  undefined,
979
978
  metadataConfigDirByProvider?.get(provider),
979
+ includeVisionSidecar,
980
980
  )
981
981
  : seeded;
982
982
  continue;
@@ -1001,6 +1001,7 @@ export function augmentRoutedModelsWithMetadata(
1001
1001
  metadataModelIdCaseFoldByProvider?.get(provider),
1002
1002
  undefined,
1003
1003
  metadataConfigDirByProvider?.get(provider),
1004
+ includeVisionSidecar,
1004
1005
  )
1005
1006
  : {}),
1006
1007
  });
@@ -18,6 +18,9 @@ import { isSpawnableCodexCandidate } from "./exec-invocation";
18
18
  import {
19
19
  codexRuntimeStatePath,
20
20
  parsePersistedCodexRuntime,
21
+ resolveCodexRuntime,
22
+ type ResolveCodexRuntimeDeps,
23
+ type ResolveCodexRuntimeResult,
21
24
  } from "./runtime";
22
25
  import {
23
26
  inspectCodexShimBackingForCommand,
@@ -46,12 +49,13 @@ export type CodexCliInstallReason =
46
49
  | "shim_state_unknown"
47
50
  | "shim_update_deferred"
48
51
  | "app_bundle"
49
- | "version_manager_owned"
50
- | "npm_global_unverified"
51
- | "selection_unattested"
52
- | "version_mismatch"
53
- | "unverified_standalone"
54
- | "inspection_failed";
52
+ | "version_manager_owned"
53
+ | "npm_global_unverified"
54
+ | "managed_npm_global"
55
+ | "selection_unattested"
56
+ | "version_mismatch"
57
+ | "unverified_standalone"
58
+ | "inspection_failed";
55
59
 
56
60
  export type CodexCliCandidateSource = "environment" | "persisted";
57
61
  export type CodexCliInstallEvidence =
@@ -82,6 +86,12 @@ export interface CodexCliInstallReport {
82
86
  readonly managed: boolean;
83
87
  readonly reason: CodexCliInstallReason;
84
88
  readonly location: string | null;
89
+ /**
90
+ * sha256 digest of the canonical package manifest root when one was observed,
91
+ * otherwise null. Digest-only so the public report still carries no path; plan
92
+ * identity binds this value so two different install roots cannot share a plan.
93
+ */
94
+ readonly installDigest: string | null;
85
95
  readonly packageVersion: string | null;
86
96
  readonly shim: Readonly<{
87
97
  status: "not-tracked" | "matched" | "unknown";
@@ -105,6 +115,19 @@ export interface CodexCliInstallProvenanceDeps {
105
115
  platform: NodeJS.Platform,
106
116
  configDir: string,
107
117
  ) => CodexShimBackingForCommand;
118
+ /**
119
+ * Caller assertion that `env.CODEX_CLI_PATH` is the runtime the launcher actually
120
+ * selected, not merely a configured name. Only a proof-bound caller may set this;
121
+ * a persisted selection and an arbitrary environment stay unattested.
122
+ */
123
+ readonly selectionAttested?: boolean;
124
+ /**
125
+ * The command the runtime resolver actually selected under the same evidence.
126
+ * Attestation additionally requires its canonical path to match the inspected
127
+ * candidate, so a snapshot candidate the resolver would have rejected cannot
128
+ * turn a different installation managed.
129
+ */
130
+ readonly selectedCommand?: string | null;
108
131
  }
109
132
 
110
133
  interface PackageManifestEvidence {
@@ -159,6 +182,7 @@ function unknownReport(
159
182
  managed: false,
160
183
  reason,
161
184
  location: extra.location ?? null,
185
+ installDigest: null,
162
186
  packageVersion: null,
163
187
  shim: Object.freeze({ status: "not-tracked", backingKind: null }),
164
188
  evidence: Object.freeze([]),
@@ -287,6 +311,38 @@ function resolveCandidateCommandPath(
287
311
  return null;
288
312
  }
289
313
 
314
+ /** Resolve selection under inspection's bounded, local-only filesystem policy. */
315
+ export function observeCodexCliSelectedCommand(
316
+ deps: CodexCliInstallProvenanceDeps,
317
+ resolve: (deps: ResolveCodexRuntimeDeps) => ResolveCodexRuntimeResult = resolveCodexRuntime,
318
+ ): string | null {
319
+ const platform = deps.platform ?? process.platform;
320
+ // Even the general resolver's existence checks can touch a remote Windows
321
+ // candidate. Deferred inspection must return before invoking it at all.
322
+ if (platform === "win32") return null;
323
+ const configDir = deps.configDir ?? getConfigDir();
324
+ if (!isSafeLocalInspectionPath(configDir, deps)) return null;
325
+ try {
326
+ return resolve({
327
+ platform,
328
+ env: deps.env,
329
+ configDir,
330
+ discoverAlternatives: false,
331
+ probeVersion: false,
332
+ // Runtime and shim state must use the same no-follow, nonblocking,
333
+ // size-bounded descriptor reads as provenance, including before selection.
334
+ readFileSync: path => {
335
+ const bytes = readBoundedFile(path, MAX_RUNTIME_STATE_BYTES, deps);
336
+ if (!bytes) throw new Error("inspection_state_unavailable");
337
+ return bytes.toString("utf8");
338
+ },
339
+ existsSync: path => resolveCandidateCommandPath(path, deps) !== null,
340
+ }).runtime.command ?? null;
341
+ } catch {
342
+ return null;
343
+ }
344
+ }
345
+
290
346
  function canonicalize(path: string, deps: CodexCliInstallProvenanceDeps): string | null {
291
347
  if (!isSafeLocalInspectionPath(path, deps)) return null;
292
348
  try {
@@ -630,15 +686,16 @@ export async function inspectCodexCliInstall(
630
686
  managed: false,
631
687
  reason: appBundle ? "app_bundle" : "version_manager_owned",
632
688
  location: publicExecutableLocation(lexicalCandidatePath, platform),
689
+ installDigest: null,
633
690
  packageVersion: null,
634
691
  shim: Object.freeze({ status: "unknown", backingKind: null }),
635
692
  evidence: Object.freeze([appBundle ? "app_bundle_path" : "version_manager_path"]),
636
693
  });
637
694
  }
638
- return unknownWindowsReport("windows_inspection_deferred", candidate, {
639
- location: publicExecutableLocation(lexicalCandidatePath, platform),
640
- });
641
- }
695
+ return unknownWindowsReport("windows_inspection_deferred", candidate, {
696
+ location: publicExecutableLocation(lexicalCandidatePath, platform),
697
+ });
698
+ }
642
699
  const configDir = deps.configDir ?? getConfigDir();
643
700
  if (!isSafeLocalInspectionPath(configDir, deps)) {
644
701
  return unknownReport("shim_state_unknown", candidate);
@@ -651,6 +708,23 @@ export async function inspectCodexCliInstall(
651
708
  if (!canonicalCandidatePath) {
652
709
  return unknownReport("candidate_path_unsafe", candidate);
653
710
  }
711
+ // Only a proof-bound caller may attest that the environment candidate is the
712
+ // runtime it actually selected, and only when the runtime resolver picked the
713
+ // same canonical path under the same evidence. A persisted selection records
714
+ // intent, not the resolved binary, and an arbitrary environment is ambient —
715
+ // neither can become managed here; a resolver that would choose a different
716
+ // executable cannot attest the snapshot's installation either.
717
+ const resolverPicked = deps.selectedCommand
718
+ ? canonicalize(
719
+ resolveCandidateCommandPath(deps.selectedCommand, deps) ?? deps.selectedCommand,
720
+ deps,
721
+ )
722
+ : null;
723
+ const selectionAttested =
724
+ deps.selectionAttested === true
725
+ && candidate.evidence === "environment"
726
+ && resolverPicked !== null
727
+ && samePath(resolverPicked, canonicalCandidatePath, platform);
654
728
  const inspectShim = deps.inspectShim ?? inspectCodexShimBackingForCommand;
655
729
  const shim = inspectShim(candidatePath, platform, configDir);
656
730
  if (shim.status === "unknown") {
@@ -658,6 +732,7 @@ export async function inspectCodexCliInstall(
658
732
  ...unknownReport("shim_state_unknown", candidate, {
659
733
  location: publicExecutableLocation(canonicalCandidatePath, platform),
660
734
  }),
735
+ selectionAttested,
661
736
  shim: shimReport(shim),
662
737
  });
663
738
  }
@@ -666,6 +741,7 @@ export async function inspectCodexCliInstall(
666
741
  ...unknownReport("shim_update_deferred", candidate, {
667
742
  location: publicExecutableLocation(canonicalCandidatePath, platform),
668
743
  }),
744
+ selectionAttested,
669
745
  provenance: "standalone-unverified",
670
746
  shim: shimReport(shim),
671
747
  evidence: Object.freeze(["canonical_path", "shim_backing"] as const),
@@ -685,7 +761,7 @@ export async function inspectCodexCliInstall(
685
761
  candidateAvailable: true,
686
762
  candidateVersion: candidate.version,
687
763
  candidateSource: candidate.evidence,
688
- selectionAttested: false,
764
+ selectionAttested,
689
765
  versionEvidence: Object.freeze({
690
766
  kind: candidate.version ? "advisory-runtime" as const : "unavailable" as const,
691
767
  }),
@@ -693,6 +769,7 @@ export async function inspectCodexCliInstall(
693
769
  managed: false,
694
770
  reason: "app_bundle",
695
771
  location,
772
+ installDigest: null,
696
773
  packageVersion: null,
697
774
  shim: shimReport(shim),
698
775
  evidence: Object.freeze(["canonical_path", "app_bundle_path"]),
@@ -706,7 +783,7 @@ export async function inspectCodexCliInstall(
706
783
  candidateAvailable: true,
707
784
  candidateVersion: candidate.version,
708
785
  candidateSource: candidate.evidence,
709
- selectionAttested: false,
786
+ selectionAttested,
710
787
  versionEvidence: Object.freeze({
711
788
  kind: candidate.version ? "advisory-runtime" as const : "unavailable" as const,
712
789
  }),
@@ -714,6 +791,7 @@ export async function inspectCodexCliInstall(
714
791
  managed: false,
715
792
  reason: "version_manager_owned",
716
793
  location,
794
+ installDigest: null,
717
795
  packageVersion: null,
718
796
  shim: shimReport(shim),
719
797
  evidence: Object.freeze(["canonical_path", "version_manager_path"]),
@@ -722,6 +800,7 @@ export async function inspectCodexCliInstall(
722
800
  if (/codex[.]opencodex-real(?:[.](?:cmd|bat|exe))?$/i.test(pathTools(platform).basename(candidatePath))) {
723
801
  return freezeReport({
724
802
  ...unknownReport("shim_state_unknown", candidate, { location }),
803
+ selectionAttested,
725
804
  shim: shimReport(shim),
726
805
  });
727
806
  }
@@ -745,22 +824,30 @@ export async function inspectCodexCliInstall(
745
824
  const versionMatches = candidate.version === null || candidate.version === manifest.version;
746
825
  const reason: CodexCliInstallReason = !global || !linked
747
826
  ? "npm_global_unverified"
748
- : !versionMatches ? "version_mismatch" : "selection_unattested";
827
+ : !versionMatches ? "version_mismatch"
828
+ : selectionAttested ? "managed_npm_global" : "selection_unattested";
749
829
  return freezeReport({
750
830
  schemaVersion: 1,
751
831
  candidateAvailable: true,
752
832
  candidateVersion: candidate.version,
753
833
  candidateSource: candidate.evidence,
754
- selectionAttested: false,
834
+ selectionAttested,
755
835
  versionEvidence: Object.freeze({
756
- kind: manifestOwned && candidate.version !== null && versionMatches
836
+ // The manifest is the on-disk record of what is installed. An absent advisory
837
+ // version (the launcher snapshot carries no version) cannot contradict it,
838
+ // while a reported one that disagrees already classified as version_mismatch.
839
+ kind: manifestOwned && versionMatches
757
840
  ? "package-manifest" as const
758
841
  : candidate.version !== null ? "advisory-runtime" as const : "unavailable" as const,
759
842
  }),
760
843
  provenance: manifestOwned ? "npm-global" : "standalone-unverified",
761
- managed: false,
844
+ managed: manifestOwned && versionMatches && selectionAttested,
762
845
  reason,
763
846
  location,
847
+ // Plan identity binds this digest, not the redacted display location: two
848
+ // package roots that resolve to the same "<path>/codex" string must still
849
+ // produce different plans.
850
+ installDigest: sha256("codex-cli-install-root-v1", normalizePath(manifest.root, platform)),
764
851
  packageVersion: manifest.version,
765
852
  shim: shimReport(shim),
766
853
  evidence: Object.freeze<CodexCliInstallEvidence[]>([
@@ -786,7 +873,7 @@ export async function inspectCodexCliInstall(
786
873
  candidateAvailable: true,
787
874
  candidateVersion: candidate.version,
788
875
  candidateSource: candidate.evidence,
789
- selectionAttested: false,
876
+ selectionAttested,
790
877
  versionEvidence: Object.freeze({
791
878
  kind: candidate.version ? "advisory-runtime" as const : "unavailable" as const,
792
879
  }),
@@ -794,6 +881,7 @@ export async function inspectCodexCliInstall(
794
881
  managed: false,
795
882
  reason: "unverified_standalone",
796
883
  location,
884
+ installDigest: null,
797
885
  packageVersion: null,
798
886
  shim: shimReport(shim),
799
887
  evidence: Object.freeze(["canonical_path"]),