@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
@@ -0,0 +1,36 @@
1
+ import { fastRowBases } from "../fast-row";
2
+ import { previewRouteModel } from "../../router";
3
+ import type { OcxConfig } from "../../types";
4
+
5
+ /**
6
+ * Build the alias promoter for one model listing. The Fast-base inventory walks
7
+ * the configured catalog, so it is computed at most once per listing instead of
8
+ * once per aliased row.
9
+ */
10
+ export function modelAliasIdPromoter(config: OcxConfig) {
11
+ let isFastBase: ((id: string) => boolean) | undefined;
12
+ const fastBases = () => (isFastBase ??= fastRowBases(config));
13
+ return (provider: string, model: string, alias: string, fastEligible: boolean) =>
14
+ preferredModelAliasId(config, provider, model, alias, fastEligible, fastBases);
15
+ }
16
+
17
+ /** Promote only a short alias whose ordinary route is this exact upstream model. */
18
+ export function preferredModelAliasId(
19
+ config: OcxConfig, provider: string, model: string, alias: string, fastEligible: boolean,
20
+ fastBases: () => (id: string) => boolean = () => fastRowBases(config),
21
+ ): string | undefined {
22
+ if (config.preferModelAliasIds !== true) return undefined;
23
+ // Built-in bare aliases are not stable Fast bases. Preserve the qualified ID
24
+ // when promotion would publish a synthetic sibling that ingress cannot parse.
25
+ if (config.fastRows !== false && fastEligible && !fastBases()(alias)) return undefined;
26
+ try {
27
+ // Preview cannot consume a combo's round-robin selection state. A policy/combo,
28
+ // reserved native name or another provider's native id must keep its own meaning.
29
+ const route = previewRouteModel(config, alias);
30
+ return route.routeReason === "model-alias" && route.providerName === provider && route.modelId === model
31
+ ? alias : undefined;
32
+ } catch {
33
+ // An ambiguous alias stays available through the existing qualified public id.
34
+ return undefined;
35
+ }
36
+ }
@@ -21,6 +21,7 @@ export { LINK_INGRESS_HOSTNAME } from "./link-listener";
21
21
  import type { ServerIngress } from "./serve-options";
22
22
 
23
23
  export interface OptionalListenerStartContext<T> {
24
+ startProxy?: typeof import("../../claude/intercept/connect-proxy").startConnectProxy;
24
25
  config: OcxConfig;
25
26
  publicPort: number;
26
27
  requestedPort?: number;
@@ -106,6 +107,7 @@ export function createOptionalListenerSet<T>(linkDeps: LinkListenerDeps = {}): O
106
107
  }
107
108
  supervisorStop = () => supervisor.stop();
108
109
  claudeIntercept.start({
110
+ startProxy: ctx.startProxy,
109
111
  config: ctx.config,
110
112
  publicPort: ctx.publicPort,
111
113
  requestedPort: ctx.requestedPort,
@@ -1,4 +1,5 @@
1
1
  import type { Server, ServerWebSocket } from "bun";
2
+ import { modelAliasIdPromoter } from "./model-alias-id";
2
3
  import type { StartServerDeps } from "./startup-warnings";
3
4
  import { isLinkManagementPath } from "../../link/management-routes";
4
5
  import {
@@ -1252,6 +1253,7 @@ export function createServeOptions(ctx: ServeOptionsContext) {
1252
1253
  effortRowKnownIds,
1253
1254
  ));
1254
1255
  };
1256
+ const promoteAliasId = modelAliasIdPromoter(config);
1255
1257
  const routedRows = await Promise.all(uniqueCatalogModelsForRawPublicList(goOrdered)
1256
1258
  .filter(m => listAllows(m.provider, m.id))
1257
1259
  .map(async m => {
@@ -1269,8 +1271,11 @@ export function createServeOptions(ctx: ServeOptionsContext) {
1269
1271
  knownModelIdsForProvider(m.provider, provider, config),
1270
1272
  ).get(m.id)
1271
1273
  : undefined;
1274
+ const effectiveId = !isCombo && !fastModelId && effective
1275
+ ? promoteAliasId(m.provider, m.id, effective.alias, catalogRowFastEligible(m)) ?? publicId
1276
+ : publicId;
1272
1277
  const row = {
1273
- id: publicId,
1278
+ id: effectiveId,
1274
1279
  object: "model",
1275
1280
  created: 0,
1276
1281
  // This endpoint is an OpenAI-compatible inbound contract. Some clients use
@@ -1279,6 +1284,9 @@ export function createServeOptions(ctx: ServeOptionsContext) {
1279
1284
  owned_by: isCombo ? "openai" : (m.owned_by ?? m.provider),
1280
1285
  ...(isCombo ? { is_combo: true } : {}),
1281
1286
  ...(effective ? { alias_of: `${provider?.alias || m.provider}/${effective.alias}` } : {}),
1287
+ // When preferModelAliasIds promotes the alias to `id`, retain the original
1288
+ // provider/nativeId so clients that need the upstream identity can read it.
1289
+ ...(effectiveId !== publicId ? { native_id: publicId } : {}),
1282
1290
  ...grokEffortFields(m.reasoningEfforts ?? [], m.defaultReasoningEffort),
1283
1291
  ...modelCapabilityFields({
1284
1292
  reasoningEfforts: m.reasoningEfforts,
@@ -1610,11 +1618,17 @@ export function createServeOptions(ctx: ServeOptionsContext) {
1610
1618
  // Promote a caller `x-session-id` before admission, as Responses and Messages do (#6520):
1611
1619
  // the ChatGPT bridge forwards only canonical session headers, so the raw marker is lost.
1612
1620
  const sessionReq = withCallerSessionIdentity(req, admission);
1613
- return runAdmittedHttpTurn(sessionReq, policy, async turnAdmissionLease => withCors(
1614
- await handleChatCompletions(sessionReq, config, logCtx, { requestId, start, turnAdmissionLease, admission }),
1615
- req,
1616
- policy,
1617
- ), { requestId, start, logCtx });
1621
+ // Only expose an id when the handler or a logged refusal owns its history row.
1622
+ let ownsRequestLog = false;
1623
+ const response = await runAdmittedHttpTurn(sessionReq, policy, async turnAdmissionLease => {
1624
+ ownsRequestLog = true;
1625
+ return withCors(
1626
+ await handleChatCompletions(sessionReq, config, logCtx, { requestId, start, turnAdmissionLease, admission }),
1627
+ req,
1628
+ policy,
1629
+ );
1630
+ }, { requestId, start, logCtx, onLogged: () => { ownsRequestLog = true; } });
1631
+ return ownsRequestLog ? withRequestLogId(response, requestId) : response;
1618
1632
  }
1619
1633
 
1620
1634
  if (url.pathname === "/v1/audio/transcriptions" && req.method === "POST") {
@@ -149,6 +149,8 @@ export function withRequestLogId(response: Response, requestId: string): Respons
149
149
  }
150
150
 
151
151
  export interface StartServerDeps {
152
+ /** Test-only CONNECT binder; permits kernel-assigned ports without probe-and-release races. */
153
+ startClaudeInterceptProxy?: typeof import("../../claude/intercept/connect-proxy").startConnectProxy;
152
154
  /** Test-only seam; production always initializes its own management credential state. */
153
155
  managementAuthState?: ManagementAuthState;
154
156
  /** Test-only route dependencies, forwarded only after management admission succeeds. */
@@ -89,6 +89,7 @@ import {
89
89
  import type { ServeOptionsContext } from "./serve-options";
90
90
  import type { RequestMetricsRecorder } from "../request-metrics";
91
91
  import { resolveInboundBodyLimitBytes } from "../request-decompress";
92
+ import { responseToolOwnership } from "../responses/response-tool-ownership";
92
93
 
93
94
  /**
94
95
  * The WebSocket half of the Bun.serve options, split out of serve-options.ts to keep that file
@@ -184,6 +185,8 @@ export function createWebsocketHandler(
184
185
  }
185
186
  return;
186
187
  }
188
+ if (ws.data.responsesActivity?.closing) return;
189
+ ws.data.responsesActivity?.touch();
187
190
  const rawBytes = typeof raw === "string" ? Buffer.byteLength(raw) : raw.byteLength;
188
191
  if (rawBytes > MAX_WS_FRAME_BYTES) {
189
192
  sendJsonFrame(ws, buildWsErrorFrame(413, {
@@ -223,6 +226,7 @@ export function createWebsocketHandler(
223
226
  if (frame.type === "response.inject") {
224
227
  if (!ws.data.nativeControl?.inject) throw new NativeSteeringError("injection_not_supported", "Native injection is disabled or unavailable on this route.");
225
228
  ws.data.nativeControl.inject(frame);
229
+ ws.data.responsesActivity?.acceptResults(frame.input);
226
230
  return;
227
231
  }
228
232
  if (frame.type === "response.steer") {
@@ -230,7 +234,10 @@ export function createWebsocketHandler(
230
234
  ws.data.nativeControl.steer(frame);
231
235
  return;
232
236
  }
233
- if (ws.data.nativeControl?.continue(frame)) return;
237
+ if (ws.data.nativeControl?.continue(frame)) {
238
+ ws.data.responsesActivity?.acceptResults(frame.input);
239
+ return;
240
+ }
234
241
  } catch (error) {
235
242
  sendJsonFrame(ws, buildWsErrorFrame(400, {
236
243
  type: "invalid_request_error",
@@ -294,6 +301,7 @@ export function createWebsocketHandler(
294
301
  }
295
302
 
296
303
  // Only a genuinely admitted turn may receive steering or continuations.
304
+ const finishActivity = ws.data.responsesActivity?.beginTurn(frame.input);
297
305
  ws.data.nativeControl = nativeControl;
298
306
  const payload: Record<string, unknown> = { ...frame };
299
307
  delete payload.type;
@@ -346,11 +354,16 @@ export function createWebsocketHandler(
346
354
  terminalRecorder = recorder;
347
355
  },
348
356
  });
357
+ const observeLog = nativeControl?.relayActive
358
+ ? createNativeSteeringLogObserver(logCtx, () => recordFirstOutput(logCtx, start))
359
+ : (payload: string) => inspectResponseLogSsePayload(logCtx, payload);
360
+ const providerExecuted = responseToolOwnership(response);
349
361
  await sendResponseToWebSocket(ws, response, isCurrent, {
350
362
  untilEof: nativeControl?.relayActive === true,
351
- onSsePayload: nativeControl?.relayActive
352
- ? createNativeSteeringLogObserver(logCtx, () => recordFirstOutput(logCtx, start))
353
- : payload => inspectResponseLogSsePayload(logCtx, payload),
363
+ onSsePayload: payload => {
364
+ ws.data.responsesActivity?.observePayload(payload, providerExecuted);
365
+ observeLog(payload);
366
+ },
354
367
  onTerminal: status => {
355
368
  terminalRecorder?.(status, logCtx.terminalHttpStatus);
356
369
  finalizeLog(httpStatusForRequestLogTerminal(status, logCtx), {
@@ -392,6 +405,7 @@ export function createWebsocketHandler(
392
405
  /* socket already gone or send dropped */
393
406
  }
394
407
  } finally {
408
+ finishActivity?.();
395
409
  turnAdmissionLease.release();
396
410
  if (ws.data.nativeControl === nativeControl) ws.data.nativeControl = undefined;
397
411
  if (!logged && turnAbort.signal.aborted) finalizeLog(499);
@@ -267,17 +267,17 @@ function startServerWithSpendLedgerOwner(port: number | undefined, deps: StartSe
267
267
  startupOwnershipHomes = homes;
268
268
  startupOwnershipStatePaths = statePaths;
269
269
  } catch { /* inspection below stays unknown */ }
270
- const startupCacheOwnership = inspectStartupOwnership(
270
+ const startupCacheOwnership = shouldSyncCodexOnStart(config) ? inspectStartupOwnership(
271
271
  deps,
272
272
  startupOwnershipHomes,
273
273
  startupOwnershipStatePaths,
274
274
  startupWindowsTaskListingCache,
275
- );
275
+ ) : null;
276
276
  // Startup cache invalidation is best-effort and applies only when startup sync is enabled.
277
277
  // Check OFF before taking K: on Windows K resolves SID + LocalAppData through PowerShell,
278
278
  // and run 35093667426 exceeded healthy controls by 33.8 s against that 30 s child budget.
279
279
  // The permit callback still re-reads intent under K to close a concurrent disable race.
280
- if (shouldSyncCodexOnStart(config) && startupCacheOwnership.ownership === "owned" && startupOwnershipHomes !== null) {
280
+ if (startupCacheOwnership?.ownership === "owned" && startupOwnershipHomes !== null) {
281
281
  try {
282
282
  const startupCodexHome = startupOwnershipHomes.codexHome;
283
283
  // #1046: record whether this actually rewrote the cache. `handleStart` ORs this
@@ -549,12 +549,12 @@ function startServerWithSpendLedgerOwner(port: number | undefined, deps: StartSe
549
549
  // clients; no Codex request can use this lifecycle in that state.
550
550
  // Re-probe here instead of trusting the earlier cache decision: startup work
551
551
  // between the two sites must not widen the service-install race.
552
- const nativeOwnership = inspectStartupOwnership(
552
+ const nativeOwnership = shouldSyncCodexOnStart(config) ? inspectStartupOwnership(
553
553
  deps,
554
554
  startupOwnershipHomes,
555
555
  startupOwnershipStatePaths,
556
- );
557
- const preparedNativeMainLifecycle = nativeOwnership.ownership !== "foreign"
556
+ ) : null;
557
+ const preparedNativeMainLifecycle = nativeOwnership !== null && nativeOwnership.ownership !== "foreign"
558
558
  && startupOwnershipHomes !== null
559
559
  ? prepareNativeMainStartupLifecycle(
560
560
  deps.nativeMainStartup,
@@ -600,7 +600,7 @@ function startServerWithSpendLedgerOwner(port: number | undefined, deps: StartSe
600
600
  return retryPreparedNativeMainLifecycle.start();
601
601
  },
602
602
  };
603
- const nativeMainLifecycle: NativeMainStartupLifecycle = shouldSyncCodexOnStart(config)
603
+ const nativeMainLifecycle: NativeMainStartupLifecycle = nativeOwnership !== null
604
604
  ? nativeOwnership.ownership === "owned"
605
605
  ? preparedNativeMainLifecycle
606
606
  ? preparedNativeMainLifecycle.start()
@@ -738,7 +738,7 @@ function startServerWithSpendLedgerOwner(port: number | undefined, deps: StartSe
738
738
  throw new AuxiliaryListenerBindError("hub.managementIngress", managementIngressPort, "127.0.0.1", error);
739
739
  }
740
740
  }
741
- optionalListeners.start({ config, publicPort: server.port ?? listenPort, requestedPort: listenPort,
741
+ optionalListeners.start({ config, publicPort: server.port ?? listenPort, requestedPort: listenPort, startProxy: deps.startClaudeInterceptProxy,
742
742
  maxRequestBodySize: inboundBodyLimitBytes, dispatch: (req, requestServer) => serveOptions.fetch(req, requestServer) });
743
743
  } catch (error) {
744
744
  unregisterQuotaAutoRefresh?.();
@@ -0,0 +1,31 @@
1
+ import type { RequestLogContext } from "../request-log";
2
+ import { ADVISOR_INTERNAL_CAPABILITY_HEADER, isInternalCallCapability } from "../../lib/local-internal-call-capability";
3
+
4
+ export const ADVISOR_REASONING_HEADER = "x-opencodex-advisor-reasoning";
5
+ const EFFORTS = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"]);
6
+
7
+ /** Native Chat sends the finalized body directly instead of the translating adapter builder. */
8
+ export function observeAdvisorNativeReasoning(headers: Headers, log: RequestLogContext, body: string): void {
9
+ if (!isInternalCallCapability(headers.get(ADVISOR_INTERNAL_CAPABILITY_HEADER))) return;
10
+ delete log.effectiveEffort;
11
+ try {
12
+ const effort = JSON.parse(body)?.reasoning_effort;
13
+ if (typeof effort === "string" && EFFORTS.has(effort)) log.effectiveEffort = effort;
14
+ } catch { /* absence of evidence stays unreported */ }
15
+ }
16
+
17
+ /** Only the authenticated internal caller receives adapter-owned serialization evidence. */
18
+ export function attachAdvisorReasoning(response: Response, log: RequestLogContext): Response {
19
+ const headers = new Headers(response.headers);
20
+ headers.set(ADVISOR_REASONING_HEADER, JSON.stringify({
21
+ effectiveEffort: log.effectiveEffort && EFFORTS.has(log.effectiveEffort) ? log.effectiveEffort : null,
22
+ }));
23
+ return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
24
+ }
25
+
26
+ export function readAdvisorReasoning(headers: Headers): string | null {
27
+ try {
28
+ const value = JSON.parse(headers.get(ADVISOR_REASONING_HEADER) ?? "null")?.effectiveEffort;
29
+ return typeof value === "string" && EFFORTS.has(value) ? value : null;
30
+ } catch { return null; }
31
+ }
@@ -38,6 +38,7 @@ export interface ActiveTurnLease extends AdmissionLease {
38
38
  attach(lease: AdmissionLease): void;
39
39
  bindAbortSignal(signal: AbortSignal): () => void;
40
40
  bindAbortController(ac: AbortController): void;
41
+ unbindAbortController(ac: AbortController): void;
41
42
  beginCodexAccountSelection(): CodexAccountSelectionAdmission;
42
43
  isTransferred(): boolean;
43
44
  }
@@ -231,6 +232,17 @@ export function tryAdmitTurn(sessionLaneId?: string, clientSignal?: AbortSignal)
231
232
  activeTurns.set(ac, lease);
232
233
  lease.bindAbortSignal(ac.signal);
233
234
  },
235
+ unbindAbortController(ac) {
236
+ if (!controllers.delete(ac)) return;
237
+ if (activeTurns.get(ac) === lease) activeTurns.delete(ac);
238
+ const listener = abortListeners.get(ac.signal);
239
+ if (listener) {
240
+ ac.signal.removeEventListener("abort", listener);
241
+ abortListeners.delete(ac.signal);
242
+ }
243
+ // A completed child relay cannot retire its still-running parent turn.
244
+ if (controllers.size === 0) lease.release();
245
+ },
234
246
  beginCodexAccountSelection() {
235
247
  const mainProfileDraining = nativeMainDrainOwners.size > 0;
236
248
  let selectionActive = active && !mainProfileDraining;
@@ -327,7 +339,7 @@ export function unregisterTurn(ac: AbortController): void {
327
339
  turnReleaseMisses += 1;
328
340
  return;
329
341
  }
330
- lease.release();
342
+ lease.unbindAbortController(ac);
331
343
  }
332
344
  export function isDraining(): boolean { return shutdownDraining || temporaryDrainOwners.size > 0; }
333
345
  export function getActiveTurnCount(): number { return turnGate.metrics().active; }
@@ -20,10 +20,12 @@ import {
20
20
  isCurrentAdvisorContextSharingConsent,
21
21
  isValidAdvisorEffort,
22
22
  isValidAdvisorPolicy,
23
+ isValidAdvisorTaskLimit,
23
24
  resolveAdvisorSettings,
24
25
  type AdvisorEffort,
25
26
  type AdvisorPolicy,
26
27
  } from "../../advisor/settings";
28
+ import { advisorActivityStore } from "../../advisor/activity";
27
29
 
28
30
  const INVALID_BODY = Symbol("invalid-body");
29
31
 
@@ -33,6 +35,7 @@ interface AdvisorPatch {
33
35
  effort?: AdvisorEffort;
34
36
  policy?: AdvisorPolicy;
35
37
  timeoutMs?: number;
38
+ maxConsultationsPerTask?: number;
36
39
  /** "v1" records current consent. null removes it. Enabling does not imply this field. */
37
40
  contextSharingConsent?: typeof ADVISOR_CONTEXT_SHARING_CONSENT_VERSION | null;
38
41
  reset?: boolean;
@@ -40,7 +43,7 @@ interface AdvisorPatch {
40
43
 
41
44
  type ParsedPatch = { ok: true; patch: AdvisorPatch } | { ok: false; code: string; message: string };
42
45
 
43
- const PATCH_KEYS = new Set(["enabled", "model", "effort", "policy", "timeoutMs", "contextSharingConsent", "reset"]);
46
+ const PATCH_KEYS = new Set(["enabled", "model", "effort", "policy", "timeoutMs", "maxConsultationsPerTask", "contextSharingConsent", "reset"]);
44
47
 
45
48
  type Rec = Record<string, unknown>;
46
49
  function isRec(value: unknown): value is Rec {
@@ -50,9 +53,9 @@ function isRec(value: unknown): value is Rec {
50
53
  /** Strict: unknown keys and wrong types are refused; messages name the field, never the value. */
51
54
  export function parseAdvisorSettingsPatch(body: unknown): ParsedPatch {
52
55
  if (!isRec(body)) return { ok: false, code: "invalid_body", message: "body must be a JSON object" };
53
- if (Object.keys(body).length === 0) return { ok: false, code: "empty_body", message: "body must set at least one of enabled, model, effort, policy, timeoutMs, contextSharingConsent or reset" };
56
+ if (Object.keys(body).length === 0) return { ok: false, code: "empty_body", message: "body must set at least one supported advisor setting or reset" };
54
57
  for (const key of Object.keys(body)) {
55
- if (!PATCH_KEYS.has(key)) return { ok: false, code: "unknown_field", message: "body accepts only enabled, model, effort, policy, timeoutMs, contextSharingConsent and reset" };
58
+ if (!PATCH_KEYS.has(key)) return { ok: false, code: "unknown_field", message: "body accepts only enabled, model, effort, policy, timeoutMs, maxConsultationsPerTask, contextSharingConsent and reset" };
56
59
  }
57
60
  const patch: AdvisorPatch = {};
58
61
  if (body.reset !== undefined) {
@@ -86,7 +89,7 @@ export function parseAdvisorSettingsPatch(body: unknown): ParsedPatch {
86
89
  }
87
90
  if (body.policy !== undefined) {
88
91
  if (!isValidAdvisorPolicy(body.policy)) {
89
- return { ok: false, code: "invalid_policy", message: 'policy must be "manual" or "preflight"' };
92
+ return { ok: false, code: "invalid_policy", message: 'policy must be "manual", "preflight" or "adaptive"' };
90
93
  }
91
94
  patch.policy = body.policy;
92
95
  }
@@ -96,6 +99,10 @@ export function parseAdvisorSettingsPatch(body: unknown): ParsedPatch {
96
99
  }
97
100
  patch.timeoutMs = Math.floor(body.timeoutMs);
98
101
  }
102
+ if (body.maxConsultationsPerTask !== undefined) {
103
+ if (!isValidAdvisorTaskLimit(body.maxConsultationsPerTask)) return { ok: false, code: "invalid_task_limit", message: "maxConsultationsPerTask must be an integer between 1 and 3" };
104
+ patch.maxConsultationsPerTask = body.maxConsultationsPerTask;
105
+ }
99
106
  if (body.contextSharingConsent !== undefined) {
100
107
  if (body.contextSharingConsent === null) {
101
108
  patch.contextSharingConsent = null;
@@ -139,6 +146,7 @@ function applyPatchInMemory(config: ManagementContext["config"], patch: AdvisorP
139
146
  if (patch.effort !== undefined) current.effort = patch.effort;
140
147
  if (patch.policy !== undefined) current.policy = patch.policy;
141
148
  if (patch.timeoutMs !== undefined) current.timeoutMs = patch.timeoutMs;
149
+ if (patch.maxConsultationsPerTask !== undefined) current.maxConsultationsPerTask = patch.maxConsultationsPerTask;
142
150
  if (patch.contextSharingConsent === null) delete current.contextSharingConsent;
143
151
  else if (patch.contextSharingConsent !== undefined) current.contextSharingConsent = patch.contextSharingConsent;
144
152
  config.advisor = current as ManagementContext["config"]["advisor"];
@@ -152,6 +160,9 @@ function isConfigLockContention(error: unknown): boolean {
152
160
 
153
161
  export async function handleAdvisorRoutes(ctx: ManagementContext): Promise<Response | null> {
154
162
  const { url, req, config } = ctx;
163
+ if (url.pathname === "/api/advisor/activity" && req.method === "GET") {
164
+ return jsonResponse({ entries: advisorActivityStore(config).snapshot(), retention: "process", limit: 100 }, 200, req, config);
165
+ }
155
166
  if (url.pathname !== "/api/advisor/settings") return null;
156
167
 
157
168
  if (req.method === "GET") return jsonResponse(advisorInfo(config), 200, req, config);
@@ -44,7 +44,7 @@ export function pickerPreferenceOn(config: Pick<OcxConfig, "claudeCode">): boole
44
44
  }
45
45
 
46
46
  const PICKER_BODY_KEYS = new Set(["enabled", "persist", "trustedLocally", "callerAddedTrust"]);
47
- /** Enable outcomes that are progress, not refusal: on, waiting for a Desktop restart, or for the keychain step. */
47
+ /** Enable outcomes that are progress, not refusal: on, waiting for a Desktop restart, or for certificate trust. */
48
48
  const ENABLE_ACCEPTED = new Set(["active", "restart_required", "trust_pending"]);
49
49
 
50
50
  interface PickerRequestBody { enabled: boolean; persist: boolean; trustedLocally?: boolean; callerAddedTrust?: boolean }