@bitkyc08/opencodex 2.83.0 → 2.86.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 (405) hide show
  1. package/README.md +0 -4
  2. package/bin/ocx.mjs +61 -3
  3. package/gui/dist/assets/App-BjlttVLy.js +58 -0
  4. package/gui/dist/assets/Tray-DyR9yBee.js +1 -0
  5. package/gui/dist/assets/{index-BAbcj51J.css → index-BB6uK6tU.css} +1 -1
  6. package/gui/dist/assets/index-BMssP4k3.js +94 -0
  7. package/gui/dist/assets/quota-summary-D8M1bc_R.js +1 -0
  8. package/gui/dist/index.html +2 -2
  9. package/package.json +2 -3
  10. package/src/adapters/anthropic/beta-allowlist.ts +87 -8
  11. package/src/adapters/anthropic/client-identity.ts +1 -1
  12. package/src/adapters/anthropic/passthrough.ts +33 -4
  13. package/src/adapters/azure.ts +19 -1
  14. package/src/adapters/client-fingerprint.ts +24 -0
  15. package/src/adapters/coding-agent/protocol.ts +15 -8
  16. package/src/adapters/coding-agent/turn.ts +22 -9
  17. package/src/adapters/cursor/arg-codec.ts +17 -5
  18. package/src/adapters/cursor/catalog.ts +8 -0
  19. package/src/adapters/cursor/effort-map.ts +3 -0
  20. package/src/adapters/cursor/freeform-args.ts +75 -0
  21. package/src/adapters/cursor/protobuf-events.ts +36 -23
  22. package/src/adapters/google-antigravity-wire.ts +22 -1
  23. package/src/adapters/google.ts +2 -2
  24. package/src/adapters/ollama-native.ts +29 -1
  25. package/src/adapters/openai-chat/messages.ts +8 -4
  26. package/src/adapters/openai-chat/response-events.ts +59 -1
  27. package/src/adapters/openai-chat.ts +8 -5
  28. package/src/adapters/openai-responses/empty-assistant.ts +32 -0
  29. package/src/adapters/openai-responses/passthrough.ts +3 -0
  30. package/src/adapters/openai-responses/request-strips.ts +10 -2
  31. package/src/adapters/qoder/adapter.ts +56 -15
  32. package/src/advisor/consult.ts +220 -0
  33. package/src/advisor/context.ts +226 -0
  34. package/src/advisor/disclosure.ts +20 -0
  35. package/src/advisor/runtime.ts +305 -0
  36. package/src/advisor/settings.ts +135 -0
  37. package/src/advisor/state.ts +369 -0
  38. package/src/advisor/synthetic-tool.ts +33 -0
  39. package/src/bridge/errors.ts +24 -0
  40. package/src/bridge.ts +1 -1
  41. package/src/chat/inbound.ts +30 -6
  42. package/src/chat/outbound.ts +5 -0
  43. package/src/claude/context-windows.ts +54 -1
  44. package/src/claude/desktop-3p-library.ts +43 -3
  45. package/src/claude/desktop-3p.ts +22 -8
  46. package/src/claude/desktop-picker-profile.ts +11 -4
  47. package/src/claude/desktop-profile.ts +10 -1
  48. package/src/claude/desktop-remote-store-io.ts +5 -3
  49. package/src/claude/inbound.ts +121 -50
  50. package/src/claude/intercept/connect-proxy.ts +10 -3
  51. package/src/claude/intercept/local-ca.ts +8 -1
  52. package/src/claude/intercept/picker-ca-persistence.ts +3 -1
  53. package/src/claude/intercept/picker-listener.ts +49 -1
  54. package/src/claude/intercept/settings-no-proxy.ts +146 -0
  55. package/src/claude/intercept/settings.ts +101 -9
  56. package/src/claude/model-default-settings.ts +154 -0
  57. package/src/claude/model-info.ts +7 -7
  58. package/src/claude/outbound.ts +13 -6
  59. package/src/cli/account-api.ts +65 -0
  60. package/src/cli/account-auth.ts +26 -2
  61. package/src/cli/account.ts +41 -5
  62. package/src/cli/advisor.ts +151 -0
  63. package/src/cli/auxiliary-listener-preflight.ts +37 -0
  64. package/src/cli/capabilities-access-remote.ts +8 -0
  65. package/src/cli/capabilities-agents-routing.ts +18 -0
  66. package/src/cli/capabilities-base.ts +14 -2
  67. package/src/cli/catalog-command-result.ts +2 -1
  68. package/src/cli/chatgpt-command.ts +35 -14
  69. package/src/cli/claude.ts +60 -11
  70. package/src/cli/config-command.ts +8 -2
  71. package/src/cli/debug.ts +8 -0
  72. package/src/cli/dispatch.ts +21 -4
  73. package/src/cli/doctor.ts +9 -0
  74. package/src/cli/ensure-desktop-cold-start.ts +329 -0
  75. package/src/cli/export-command.ts +15 -2
  76. package/src/cli/help.ts +2 -1
  77. package/src/cli/hub-disable.ts +99 -0
  78. package/src/cli/hub.ts +4 -2
  79. package/src/cli/index.ts +26 -8
  80. package/src/cli/integration-plan-dto.ts +2 -0
  81. package/src/cli/link-child.ts +104 -0
  82. package/src/cli/link-enrollment.ts +96 -0
  83. package/src/cli/link.ts +39 -24
  84. package/src/cli/observe-stream.ts +6 -1
  85. package/src/cli/observe.ts +10 -2
  86. package/src/cli/provider.ts +12 -0
  87. package/src/cli/registry.ts +20 -7
  88. package/src/cli/restart-scope.ts +3 -1
  89. package/src/cli/runtime-api.ts +27 -2
  90. package/src/cli/status.ts +104 -20
  91. package/src/client/connect.ts +39 -4
  92. package/src/client/hub-client.ts +14 -7
  93. package/src/client/hub-state.ts +25 -14
  94. package/src/client/link-home.ts +248 -0
  95. package/src/client/link-management-relay.ts +61 -0
  96. package/src/client/link-relay.ts +6 -1
  97. package/src/client/link-status.ts +14 -0
  98. package/src/client/machine-api.ts +14 -7
  99. package/src/client/machine-listener.ts +29 -4
  100. package/src/clients/config-export/contracts.ts +1 -0
  101. package/src/clients/config-export/model-metadata.ts +3 -2
  102. package/src/clients/config-export/qoder.ts +93 -0
  103. package/src/clients/config-export.ts +59 -16
  104. package/src/clients/omo-role-models.ts +6 -3
  105. package/src/codex/agent-role-models.ts +26 -8
  106. package/src/codex/auth-api/account-list.ts +17 -2
  107. package/src/codex/auth-api/account-selection.ts +17 -7
  108. package/src/codex/auth-api/pool-mode-gate.ts +5 -2
  109. package/src/codex/auth-api/routes.ts +5 -1
  110. package/src/codex/auth-context.ts +79 -5
  111. package/src/codex/autostart-health.ts +7 -1
  112. package/src/codex/catalog/build-entries.ts +11 -2
  113. package/src/codex/catalog/bundled.ts +5 -1
  114. package/src/codex/catalog/configured-tiers.ts +50 -0
  115. package/src/codex/catalog/effort.ts +6 -3
  116. package/src/codex/catalog/metadata.ts +4 -2
  117. package/src/codex/catalog/model-hints.ts +21 -3
  118. package/src/codex/catalog/native-models.ts +16 -2
  119. package/src/codex/catalog/native-ultrafast.ts +106 -0
  120. package/src/codex/catalog/parsing.ts +5 -0
  121. package/src/codex/catalog/provider-models.ts +4 -0
  122. package/src/codex/catalog/retained-sync.ts +2 -0
  123. package/src/codex/catalog/routed-gather.ts +22 -4
  124. package/src/codex/catalog/vendor-context.ts +82 -0
  125. package/src/codex/config-write-lock.ts +40 -2
  126. package/src/codex/convergence.ts +2 -0
  127. package/src/codex/desktop-app/types.ts +2 -0
  128. package/src/codex/desktop-app/windows.ts +29 -16
  129. package/src/codex/desktop-app-restart.ts +4 -2
  130. package/src/codex/desktop-compatibility/certificate-service.ts +99 -0
  131. package/src/codex/desktop-compatibility/certificate-store.ts +193 -0
  132. package/src/codex/desktop-compatibility/connection-store.ts +87 -0
  133. package/src/codex/desktop-compatibility/installed-build.ts +55 -0
  134. package/src/codex/desktop-compatibility/json-body.ts +29 -0
  135. package/src/codex/desktop-compatibility/native-identity.ts +62 -0
  136. package/src/codex/desktop-compatibility/relay-listener.ts +93 -0
  137. package/src/codex/desktop-compatibility/routing-binding.ts +10 -0
  138. package/src/codex/desktop-compatibility/routing-preflight.ts +69 -0
  139. package/src/codex/desktop-compatibility/runtime-ownership.ts +28 -0
  140. package/src/codex/desktop-compatibility/runtime.ts +173 -0
  141. package/src/codex/desktop-compatibility/service.ts +30 -0
  142. package/src/codex/desktop-compatibility/startup-settings.ts +50 -0
  143. package/src/codex/desktop-compatibility/usage-activation.ts +86 -0
  144. package/src/codex/desktop-compatibility/usage-controlled-fetch.ts +59 -0
  145. package/src/codex/desktop-compatibility/usage-controller.ts +107 -0
  146. package/src/codex/desktop-compatibility/usage-policy.ts +59 -0
  147. package/src/codex/desktop-compatibility/usage-refresh.ts +33 -0
  148. package/src/codex/desktop-compatibility/usage-sse-controller.ts +86 -0
  149. package/src/codex/desktop-compatibility/windows-activation-source.ts +44 -0
  150. package/src/codex/desktop-compatibility/windows-certificate-trust.ts +81 -0
  151. package/src/codex/desktop-compatibility/windows-key-protection.ts +59 -0
  152. package/src/codex/desktop-compatibility/windows-package-command.ts +86 -0
  153. package/src/codex/desktop-compatibility/windows-package-launch.ts +28 -0
  154. package/src/codex/history-provider.ts +1 -1
  155. package/src/codex/inject/config-write-section.ts +4 -1
  156. package/src/codex/inject/remove.ts +18 -6
  157. package/src/codex/journal.ts +16 -1
  158. package/src/codex/main-account.ts +99 -15
  159. package/src/codex/native-main-refresh-mode.ts +217 -0
  160. package/src/codex/native-profile-startup.ts +4 -1
  161. package/src/codex/prompt-journal.ts +20 -2
  162. package/src/codex/prompt-layers/encoding.ts +49 -0
  163. package/src/codex/prompt-layers/import-source.ts +30 -0
  164. package/src/codex/prompt-layers/toml-edit.ts +269 -37
  165. package/src/codex/prompt-layers/toml-read.ts +52 -4
  166. package/src/codex/prompt-layers.ts +383 -20
  167. package/src/codex/prompt-lock-claim.ts +13 -3
  168. package/src/codex/prompt-lock-evidence.ts +3 -3
  169. package/src/codex/prompt-lock-owner.ts +14 -6
  170. package/src/codex/prompt-text-probe.ts +34 -5
  171. package/src/codex/quota.ts +13 -6
  172. package/src/codex/role-auto-assign.ts +2 -5
  173. package/src/codex/routing/active-account.ts +21 -0
  174. package/src/codex/routing/health-store.ts +1 -1
  175. package/src/codex/routing/pool-recovery.ts +79 -0
  176. package/src/codex/routing.ts +1 -1
  177. package/src/codex/runtime.ts +196 -8
  178. package/src/codex/shim-diagnostics.ts +6 -0
  179. package/src/codex/shim-overlay.ts +15 -6
  180. package/src/codex/shim.ts +1 -1
  181. package/src/combos/failover.ts +3 -0
  182. package/src/config/api-key-reconcile.ts +34 -0
  183. package/src/config/diagnostics.ts +18 -1
  184. package/src/config/feature-flags.ts +5 -0
  185. package/src/config/live-reconcile.ts +56 -29
  186. package/src/config/live-topology.ts +29 -0
  187. package/src/config/load-degrade.ts +8 -2
  188. package/src/config/paths.ts +13 -3
  189. package/src/config/salvage.ts +3 -1
  190. package/src/config/schema/config-schema.ts +19 -0
  191. package/src/config/schema/desktop-compatibility.ts +9 -0
  192. package/src/config/schema/leaf-validators.ts +1 -0
  193. package/src/generated/compatibility-version.json +713 -285
  194. package/src/generated/model-metadata.ts +1 -1
  195. package/src/grok/grpc-web.ts +23 -1
  196. package/src/grok/reset-coupon-ledger.ts +75 -5
  197. package/src/grok/reset-coupons.ts +4 -2
  198. package/src/integrations/catalog-refresh.ts +1 -1
  199. package/src/integrations/config-io.ts +20 -2
  200. package/src/integrations/journal.ts +15 -1
  201. package/src/integrations/mutation-plan.ts +14 -7
  202. package/src/integrations/registry.ts +52 -11
  203. package/src/integrations/state.ts +19 -7
  204. package/src/integrations/store.ts +3 -0
  205. package/src/integrations/target.ts +42 -5
  206. package/src/integrations/writer.ts +24 -7
  207. package/src/lib/advisor-activation.ts +16 -0
  208. package/src/lib/app-owned-memory-stores.ts +4 -0
  209. package/src/lib/app-owned-memory.ts +11 -0
  210. package/src/lib/background-work.ts +65 -0
  211. package/src/lib/bounded-file-read.ts +58 -0
  212. package/src/lib/bun-path-runtime.d.mts +10 -1
  213. package/src/lib/bun-path-runtime.mjs +62 -3
  214. package/src/lib/desktop-proxy-route.ts +30 -0
  215. package/src/lib/desktop-upstream-tunnel.ts +107 -0
  216. package/src/lib/errors.ts +7 -0
  217. package/src/lib/json-byte-size.ts +31 -0
  218. package/src/lib/local-internal-call-capability.ts +55 -0
  219. package/src/lib/optional-shutdown-hooks.ts +35 -0
  220. package/src/lib/outbound-credential-registry.ts +210 -0
  221. package/src/lib/package-tree-integrity.ts +2 -2
  222. package/src/lib/passive-read.ts +35 -0
  223. package/src/lib/shadow-call.ts +44 -5
  224. package/src/lib/socks5-fetch.ts +48 -71
  225. package/src/lib/socks5-handshake.ts +112 -0
  226. package/src/lib/translator-budget.ts +7 -1
  227. package/src/link/codex-settings.ts +155 -0
  228. package/src/link/management-routes.ts +89 -0
  229. package/src/link/remote-probe.ts +38 -0
  230. package/src/link/ssh-argv.ts +26 -5
  231. package/src/link/ssh-runner.ts +58 -27
  232. package/src/link/status-projection.ts +22 -4
  233. package/src/link/supervisor.ts +144 -49
  234. package/src/link/tunnel-state.ts +11 -4
  235. package/src/oauth/anthropic-continuity.ts +4 -3
  236. package/src/oauth/anthropic-identity.ts +13 -2
  237. package/src/oauth/anthropic-model-quota.ts +13 -1
  238. package/src/oauth/anthropic-routing.ts +230 -23
  239. package/src/oauth/anthropic.ts +18 -4
  240. package/src/oauth/generic-account-failover.ts +29 -5
  241. package/src/oauth/google-antigravity.ts +24 -7
  242. package/src/oauth/index.ts +28 -17
  243. package/src/oauth/kiro-account-identity.ts +106 -0
  244. package/src/oauth/kiro-device-login.ts +2 -1
  245. package/src/oauth/kiro.ts +55 -6
  246. package/src/oauth/plan.ts +29 -0
  247. package/src/oauth/store.ts +40 -3
  248. package/src/oauth/types.ts +2 -0
  249. package/src/plugins/loader.ts +11 -0
  250. package/src/protocols/codecs/chat-ir.ts +467 -0
  251. package/src/protocols/codecs/chat.ts +10 -1
  252. package/src/protocols/codecs/messages-ir.ts +500 -0
  253. package/src/protocols/features.ts +10 -2
  254. package/src/protocols/path.ts +11 -1
  255. package/src/protocols/plan-snapshot.ts +39 -16
  256. package/src/protocols/plan.ts +9 -1
  257. package/src/protocols/settings.ts +8 -0
  258. package/src/providers/anthropic-billing-ownership.ts +74 -0
  259. package/src/providers/anthropic-billing-recovery.ts +31 -0
  260. package/src/providers/anthropic-billing-refusal.ts +55 -0
  261. package/src/providers/anthropic-reset-admission.ts +62 -0
  262. package/src/providers/anthropic-reset-grant-ledger.ts +28 -6
  263. package/src/providers/antigravity-account-roster.ts +102 -0
  264. package/src/providers/antigravity-models.ts +85 -7
  265. package/src/providers/api-key-resolve.ts +17 -2
  266. package/src/providers/key-failover.ts +52 -5
  267. package/src/providers/model-rename-fields.ts +2 -0
  268. package/src/providers/model-rename-migration.ts +5 -3
  269. package/src/providers/model-rename-startup.ts +5 -3
  270. package/src/providers/quota/account-cache.ts +11 -0
  271. package/src/providers/quota/anthropic-account-quota.ts +4 -2
  272. package/src/providers/quota/report-cache.ts +14 -0
  273. package/src/providers/quota/vendor-probes-oauth.ts +3 -3
  274. package/src/providers/quota.ts +4 -1
  275. package/src/providers/registry/entries-core.ts +21 -20
  276. package/src/providers/registry/entries-extended.ts +19 -1
  277. package/src/providers/registry/model-seeds.ts +17 -0
  278. package/src/providers/request-pacing.ts +9 -0
  279. package/src/providers/stale-no-vision-seed-migration.ts +72 -0
  280. package/src/responses/compaction.ts +14 -0
  281. package/src/responses/parser.ts +37 -20
  282. package/src/responses/state.ts +32 -29
  283. package/src/routing/history/build-file.ts +92 -0
  284. package/src/routing/history/indexer.ts +248 -216
  285. package/src/routing/history/ingest.ts +238 -0
  286. package/src/routing/history/rebuild-job.ts +111 -0
  287. package/src/routing/history/rebuild-protocol.ts +15 -0
  288. package/src/routing/history/rebuild-worker.ts +34 -0
  289. package/src/server/admission-model-scope.ts +4 -1
  290. package/src/server/antigravity-direct-eligibility.ts +208 -0
  291. package/src/server/auth-cors.ts +46 -0
  292. package/src/server/chat-completions.ts +75 -9
  293. package/src/server/claude-messages.ts +110 -20
  294. package/src/server/configured-credentials.ts +194 -0
  295. package/src/server/index/desktop-compatibility-startup.ts +56 -0
  296. package/src/server/index/link-management.ts +58 -0
  297. package/src/server/index/optional-listeners.ts +5 -1
  298. package/src/server/index/serve-options.ts +15 -2
  299. package/src/server/index/startup-warnings.ts +9 -0
  300. package/src/server/index/websocket-handler.ts +9 -0
  301. package/src/server/index.ts +13 -10
  302. package/src/server/inference/client-encoder-delivery.ts +6 -5
  303. package/src/server/lifecycle.ts +2 -1
  304. package/src/server/login-shell-path.ts +146 -0
  305. package/src/server/management/advisor-routes.ts +191 -0
  306. package/src/server/management/agent-settings-routes.ts +50 -14
  307. package/src/server/management/anthropic-reset-grant-routes.ts +17 -1
  308. package/src/server/management/codex-agent-role-routes.ts +19 -6
  309. package/src/server/management/codex-prompt-routes.ts +136 -5
  310. package/src/server/management/codex-role-auto-assign.ts +1 -1
  311. package/src/server/management/companion-routes.ts +4 -0
  312. package/src/server/management/config-routes.ts +2 -2
  313. package/src/server/management/context.ts +4 -0
  314. package/src/server/management/desktop-compatibility-routes.ts +46 -0
  315. package/src/server/management/desktop-compatibility-runtime-routes.ts +46 -0
  316. package/src/server/management/desktop-compatibility-settings-routes.ts +27 -0
  317. package/src/server/management/grok-coupon-routes.ts +78 -27
  318. package/src/server/management/link-enrollment.ts +192 -0
  319. package/src/server/management/link-route-state.ts +185 -0
  320. package/src/server/management/link-routes.ts +82 -402
  321. package/src/server/management/model-routes.ts +2 -2
  322. package/src/server/management/model-rows.ts +3 -1
  323. package/src/server/management/protocol-settings-patch.ts +1 -0
  324. package/src/server/management/provider-overwrite-carry.ts +10 -0
  325. package/src/server/management/provider-routes.ts +1 -0
  326. package/src/server/management/route-registry.ts +16 -3
  327. package/src/server/management/shared.ts +3 -0
  328. package/src/server/management/sibling-guard.ts +1 -0
  329. package/src/server/management-api.ts +9 -1
  330. package/src/server/messages-antigravity-direct.ts +195 -0
  331. package/src/server/messages-native.ts +73 -43
  332. package/src/server/relay-eager.ts +2 -0
  333. package/src/server/request-log-filter.ts +6 -1
  334. package/src/server/request-log-terminal-status.ts +63 -6
  335. package/src/server/request-log.ts +7 -0
  336. package/src/server/responses/adapter-continuation.ts +35 -18
  337. package/src/server/responses/adapter-delivery.ts +24 -2
  338. package/src/server/responses/adapter-dispatch.ts +261 -81
  339. package/src/server/responses/advisor-plan-slot.ts +27 -0
  340. package/src/server/responses/advisor-slot.ts +336 -0
  341. package/src/server/responses/code-mode-collab-surface.ts +313 -0
  342. package/src/server/responses/codex-ws-exchange.ts +147 -6
  343. package/src/server/responses/codex-ws-wire.ts +203 -0
  344. package/src/server/responses/collaboration.ts +36 -7
  345. package/src/server/responses/compact.ts +126 -48
  346. package/src/server/responses/context-overflow.ts +13 -1
  347. package/src/server/responses/core-codex-account.ts +105 -1
  348. package/src/server/responses/core-combo-failure.ts +24 -1
  349. package/src/server/responses/core-combo.ts +28 -2
  350. package/src/server/responses/core-errors.ts +29 -1
  351. package/src/server/responses/core-lifetime.ts +2 -0
  352. package/src/server/responses/core-normalize.ts +11 -0
  353. package/src/server/responses/core-options.ts +48 -0
  354. package/src/server/responses/core-replay.ts +7 -4
  355. package/src/server/responses/core.ts +1 -1
  356. package/src/server/responses/deferred-collab-surface.ts +158 -0
  357. package/src/server/responses/deferred-send-reporter.ts +25 -0
  358. package/src/server/responses/fetch-helpers.ts +12 -1
  359. package/src/server/responses/passthrough-delivery.ts +20 -11
  360. package/src/server/responses/passthrough-dispatch.ts +29 -7
  361. package/src/server/responses/request-prepare.ts +74 -9
  362. package/src/server/responses/request-transport.ts +22 -8
  363. package/src/server/responses/run-turn-execution.ts +70 -8
  364. package/src/server/responses/sidecar-execution.ts +89 -5
  365. package/src/server/responses/terminal-guard.ts +2 -1
  366. package/src/server/responses/ws-upstream.ts +9 -1
  367. package/src/server/responses-undeclared-tool-guard.ts +30 -9
  368. package/src/server/startup-action-control.ts +38 -4
  369. package/src/server/startup-health-cache.ts +5 -0
  370. package/src/server/system-env-shell.ts +7 -2
  371. package/src/server/system-env.ts +11 -1
  372. package/src/service/cli.ts +5 -1
  373. package/src/service/desktop-startup.ts +161 -34
  374. package/src/service/desktop-supervision.d.mts +27 -1
  375. package/src/service/desktop-supervision.mjs +111 -5
  376. package/src/service/health-sentinel-launch.ts +176 -0
  377. package/src/service/health-sentinel-main.ts +466 -0
  378. package/src/service/health-sentinel-policy.ts +241 -0
  379. package/src/service/health-sentinel-probe.ts +71 -0
  380. package/src/service/health-sentinel-windows.ts +87 -0
  381. package/src/service/linux-linger.ts +20 -0
  382. package/src/service/logging.ts +72 -0
  383. package/src/tray/windows-tray.ps1 +43 -24
  384. package/src/types/config.ts +68 -6
  385. package/src/types/provider.ts +7 -0
  386. package/src/types/request.ts +15 -0
  387. package/src/types/tools.ts +2 -0
  388. package/src/update/async-check.ts +1 -1
  389. package/src/update/badge.ts +2 -2
  390. package/src/update/index.ts +88 -15
  391. package/src/update/job-supervised-restart.ts +107 -0
  392. package/src/update/job.ts +32 -32
  393. package/src/update/notify.ts +1 -1
  394. package/src/update/refresh-scheduler.ts +2 -2
  395. package/src/update/supervised-recovery.d.mts +27 -0
  396. package/src/update/supervised-recovery.mjs +157 -0
  397. package/src/usage/cache-diagnostic.ts +2 -0
  398. package/src/usage/expected-prices.ts +16 -0
  399. package/src/usage/log.ts +19 -1
  400. package/src/web-search/gemini-executor.ts +2 -2
  401. package/assets/sponsors/packycode.png +0 -0
  402. package/gui/dist/assets/App-Ba8uG696.js +0 -54
  403. package/gui/dist/assets/Tray-IImbNPRy.js +0 -1
  404. package/gui/dist/assets/index-BHRZdJuv.js +0 -94
  405. package/gui/dist/assets/quota-summary-DiJO6sYY.js +0 -1
@@ -20,7 +20,7 @@ const USAGE = `Usage (experimental, macOS only):
20
20
 
21
21
  function run(command: string, args: string[]) {
22
22
  const result = spawnSync(command, args, { encoding: "utf8", timeout: 5000 });
23
- return { ok: result.status === 0, output: `${result.stdout ?? ""}${result.stderr ?? ""}`.trim() };
23
+ return { ok: result.status === 0, status: result.status, output: `${result.stdout ?? ""}${result.stderr ?? ""}`.trim() };
24
24
  }
25
25
 
26
26
  /**
@@ -42,11 +42,12 @@ function chatgptDesktopIssueInFile(): string | null {
42
42
  * desktop restart adapter does. "ChatGPT" is a display name another app can share, so quitting,
43
43
  * relaunching and the binary path all key on this verified bundle rather than on the name.
44
44
  */
45
- function discoverApp(): DesktopAppInstall | null {
45
+ function discoverApp(): DesktopAppInstall | null | undefined {
46
46
  try {
47
47
  return darwinDesktopAppAdapter.discover(darwinDefaultExec);
48
48
  } catch {
49
- return null;
49
+ // An inspection error is not evidence that the app is uninstalled.
50
+ return undefined;
50
51
  }
51
52
  }
52
53
 
@@ -55,14 +56,20 @@ function discoverApp(): DesktopAppInstall | null {
55
56
  * `-a` keeps ancestors in the match: when ocx runs inside a ChatGPT/Codex session the app is
56
57
  * one of this process's ancestors, and plain `pgrep -x` would report it as not running.
57
58
  */
58
- function appState(install: DesktopAppInstall, launcher: string): { running: boolean; shim: boolean } {
59
+ function appState(install: DesktopAppInstall, launcher: string): { running: boolean | null; shim: boolean | null } {
59
60
  const shell = join(install.root, "Contents", "MacOS", "ChatGPT");
60
61
  // Only this user's processes: another account's ChatGPT can neither be quit nor relaunched here.
61
62
  const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
62
63
  const pids = run("pgrep", [...(uid === undefined ? [] : ["-U", String(uid)]), "-a", "-x", "ChatGPT"]);
63
- if (!pids.ok) return { running: false, shim: false };
64
- for (const pid of pids.output.split(/\s+/).filter(value => /^\d+$/.test(value))) {
64
+ // pgrep exit 1 means no match; timeout, signal, or command errors are unknown.
65
+ if (!pids.ok) return pids.status === 1
66
+ ? { running: false, shim: false } : { running: null, shim: null };
67
+ const candidates = pids.output.split(/\s+/).filter(value => /^\d+$/.test(value));
68
+ if (candidates.length === 0) return { running: null, shim: null };
69
+ let unreadable = false;
70
+ for (const pid of candidates) {
65
71
  const command = run("ps", ["eww", "-o", "command=", "-p", pid]);
72
+ if (!command.ok || !command.output) unreadable = true;
66
73
  if (command.ok && (command.output === shell || command.output.startsWith(`${shell} `))) {
67
74
  const marker = `CODEX_CLI_PATH=${launcher}`;
68
75
  const start = command.output.indexOf(marker);
@@ -70,20 +77,24 @@ function appState(install: DesktopAppInstall, launcher: string): { running: bool
70
77
  && (start + marker.length === command.output.length || command.output[start + marker.length] === " ") };
71
78
  }
72
79
  }
73
- return { running: false, shim: false };
80
+ return unreadable ? { running: null, shim: null } : { running: false, shim: false };
74
81
  }
75
82
 
76
83
  /** Adapted from #5947: open ignores new launch settings until the previous app exits. */
77
84
  async function quitApp(install: DesktopAppInstall, launcher: string): Promise<boolean> {
78
- if (!appState(install, launcher).running) return true;
85
+ const initial = appState(install, launcher).running;
86
+ if (initial === false) return true;
87
+ if (initial === null) return false;
79
88
  for (let attempt = 0; attempt < 3; attempt++) {
80
89
  run("/usr/bin/osascript", ["-e", `quit app id "${install.id}"`]);
81
90
  for (let poll = 0; poll < 20; poll++) {
82
- if (!appState(install, launcher).running) return true;
91
+ const running = appState(install, launcher).running;
92
+ if (running === false) return true;
93
+ if (running === null) return false;
83
94
  await Bun.sleep(250);
84
95
  }
85
96
  }
86
- return !appState(install, launcher).running;
97
+ return appState(install, launcher).running === false;
87
98
  }
88
99
 
89
100
  export async function handleChatgptCommand(args: string[], platform: NodeJS.Platform = process.platform): Promise<number> {
@@ -105,16 +116,21 @@ export async function handleChatgptCommand(args: string[], platform: NodeJS.Plat
105
116
  const launcher = chatgptShimLauncherPath();
106
117
  const install = discoverApp();
107
118
  if (sub === "status") {
108
- const app = install ? appState(install, launcher) : { running: false, shim: false };
119
+ const app = install ? appState(install, launcher)
120
+ : install === undefined ? { running: null, shim: null } : { running: false, shim: false };
109
121
  const configIssue = config.chatgptDesktop?.appServerShim === true ? null : chatgptDesktopIssueInFile();
110
122
  const flag = config.chatgptDesktop?.appServerShim === true ? "on"
111
123
  : configIssue ? `off (config.json ${configIssue}; the whole chatgptDesktop block is ignored)` : "off";
112
124
  console.log(`app-server shim (experimental): ${flag}
113
125
  launcher: ${existsSync(launcher) ? "present" : "absent"}
114
- app: ${install ? (app.running ? "running" : "not running") : "not installed"}
115
- CODEX_CLI_PATH launcher: ${app.shim ? "yes" : "no"}`);
126
+ app: ${install === undefined ? "unknown (app discovery failed)" : install ? (app.running === null ? "unknown (process inspection failed)" : app.running ? "running" : "not running") : "not installed"}
127
+ CODEX_CLI_PATH launcher: ${app.shim === null ? "unknown" : app.shim ? "yes" : "no"}`);
116
128
  return 0;
117
129
  }
130
+ if (install === undefined) {
131
+ console.error("ChatGPT app discovery failed; no launcher was changed and no app was opened. Retry after resolving discovery.");
132
+ return 1;
133
+ }
118
134
  if (!install) {
119
135
  if (sub === "restore") rmSync(launcher, { force: true });
120
136
  console.error("ChatGPT (com.openai.codex) was not found; install or open it once, then retry.");
@@ -143,9 +159,14 @@ CODEX_CLI_PATH launcher: ${app.shim ? "yes" : "no"}`);
143
159
  console.error(`Refusing to ${sub === "launch" ? "launch the shim" : "restore ChatGPT"}: ${untrusted}.`);
144
160
  return 1;
145
161
  }
162
+ // Preflight before changing the launcher. quitApp rechecks at the action boundary.
163
+ if (appState(install, launcher).running === null) {
164
+ console.error("ChatGPT process inspection failed; no launcher was changed and no app was opened. Retry after resolving inspection.");
165
+ return 1;
166
+ }
146
167
  if (binary) writeChatgptShimLauncher(undefined, binary);
147
168
  if (!(await quitApp(install, launcher))) {
148
- console.error("ChatGPT did not quit; quit it manually and retry.");
169
+ console.error("ChatGPT exit could not be confirmed; no new app was opened. Check the running app and retry.");
149
170
  return 1;
150
171
  }
151
172
  // Remove an inherited override too: restore must launch without CODEX_CLI_PATH.
package/src/cli/claude.ts CHANGED
@@ -12,7 +12,7 @@ import { spawn } from "node:child_process";
12
12
  import { loadConfig } from "../config";
13
13
  import { injectClaudeAgentDefs } from "../claude/agents-inject";
14
14
  import { CLAUDE_ALIAS_PREFIX_CURRENT, CLAUDE_ALIAS_PREFIX_CURRENT_V2, CLAUDE_ALIAS_PREFIX_V1, CLAUDE_ALIAS_PREFIX_V2 } from "../claude/alias";
15
- import { claudeToolSearchEnv, effectiveModelEnv, resolveAutoContext } from "../claude/context-windows";
15
+ import { claudeTierDisplayName, claudeToolSearchEnv, effectiveModelEnv, isClaudeTierLabelSlot, resolveAutoContext } from "../claude/context-windows";
16
16
  import { claudeConfigDir, fetchGatewayModels, writeGatewayModelCache } from "../claude/gateway-cache";
17
17
  import { commandInvocation } from "../lib/win-exec";
18
18
  import { isProxyAdmissionSecret } from "../server/auth-cors";
@@ -32,7 +32,8 @@ import { DEFAULT_CATALOG_PATH } from "../codex/paths";
32
32
  import { readFileSync } from "node:fs";
33
33
  import { join } from "node:path";
34
34
  import { aliasForNative, aliasForRoute, legacyAliasForNative, legacyAliasForRoute } from "../claude/alias";
35
- import { desktop3pAlias } from "../claude/desktop-3p";
35
+ import { desktop3pAlias, isRealDesktop3pModelId, resolveDesktop3pAlias } from "../claude/desktop-3p";
36
+ import { desktopProfileWireAlias, legacyDesktopProfileWireAlias } from "../claude/desktop-profile";
36
37
  import { inspectDesktopFirstParty } from "../claude/desktop-first-party";
37
38
  import { isClaudeInterceptProxyUrl, type ClaudeInterceptSettingsState } from "../claude/intercept/settings";
38
39
  import { withoutSiblingMarker } from "../codex/sibling-start";
@@ -211,10 +212,12 @@ export function buildClaudeEnv(
211
212
  // real cost to a documented entry point, and the escape hatch is the launcher: run
212
213
  // through `ocx` (the published bin) and genuine shell exports are preserved by proof.
213
214
  deleteUntrustedAnthropicSlots(env, deps);
214
- const setDefault = (name: string, value: string | undefined) => {
215
- if (value === undefined || value.length === 0) return;
216
- if (env[name] !== undefined && env[name] !== "") return; // user wins
215
+ /** Returns whether the value was written; a value the user already has wins. */
216
+ const setDefault = (name: string, value: string | undefined): boolean => {
217
+ if (value === undefined || value.length === 0) return false;
218
+ if (env[name] !== undefined && env[name] !== "") return false; // user wins
217
219
  env[name] = value;
220
+ return true;
218
221
  };
219
222
  if (config.claudeCode?.subagentModelForce !== undefined) {
220
223
  const forced = resolveSubagentForceModel(config, contextWindows, deps.forceAvailableSelectors !== undefined ? { selectors: deps.forceAvailableSelectors } : { entries: deps.forceAvailable ?? [] });
@@ -415,7 +418,9 @@ export function buildClaudeEnv(
415
418
  // with automatic [1m] context-variant marking when the slot's target model has an
416
419
  // authoritative >=1M window (Claude Code then accounts 1M, compaction preserved).
417
420
  for (const [name, value] of Object.entries(effectiveModelEnv(config.claudeCode, contextWindows, auto))) {
418
- setDefault(name, value);
421
+ // A tier slot this launch wrote gets its picker label too (#6926). A slot the user exported
422
+ // stays unlabelled, and a `<slot>_NAME` the user exported wins.
423
+ if (setDefault(name, value) && isClaudeTierLabelSlot(name)) setDefault(`${name}_NAME`, claudeTierDisplayName(value));
419
424
  }
420
425
  return env;
421
426
  }
@@ -614,11 +619,47 @@ const MODEL_ENV_SLOT_NAMES = [
614
619
  "ANTHROPIC_SMALL_FAST_MODEL",
615
620
  ] as const;
616
621
 
617
- const DESKTOP_3P_ALIAS = /^claude-opus-4(?:-8)?-[a-z][0-9a-z]{2}$/;
622
+ const DESKTOP_3P_ALIAS = /^claude-(?:opus-4(?:-8)?-[a-z][0-9a-z]{2}|(?:opus-4-8|fable-5)-p[0-9a-z]{3})(?:--fast)?$/;
623
+
624
+ export function nativeClaudeModelIds(config: OcxConfig): string[] {
625
+ const assignments = config.claudeCode?.desktopProfile?.assignments ?? {};
626
+ const routes = Object.keys(assignments);
627
+ const realProfileIds = new Set(routes.filter(route => route.startsWith("anthropic/claude-"))
628
+ .map(route => route.slice("anthropic/".length)));
629
+ // A native CLI starts without the server registry. Persisted profile bindings still
630
+ // identify proxy selectors, even when an old provider declaration has the same spelling.
631
+ const proxyProfileIds = new Set(routes.filter(route => !route.startsWith("anthropic/claude-"))
632
+ .flatMap(route => {
633
+ const alias = assignments[route]!.alias;
634
+ const slash = route.indexOf("/");
635
+ return [alias, desktopProfileWireAlias(alias), legacyDesktopProfileWireAlias(alias),
636
+ desktop3pAlias(route.slice(0, slash), route.slice(slash + 1))];
637
+ }));
638
+ // The configured default is a genuine declaration too: the catalog seeds it for static
639
+ // providers, so it must be recognized here even without a server registry.
640
+ const anthropic = config.providers.anthropic;
641
+ const declaredIds = [
642
+ ...(anthropic?.defaultModel ? [anthropic.defaultModel] : []),
643
+ ...(anthropic?.models ?? []), ...(anthropic?.selectedModels ?? []), ...(anthropic?.retainModels ?? []),
644
+ ];
645
+ return [...new Set([
646
+ ...realProfileIds,
647
+ ...declaredIds
648
+ .filter(id => {
649
+ const base = id.endsWith("--fast") ? id.slice(0, -"--fast".length) : id;
650
+ return id.startsWith("claude-") && (realProfileIds.has(id)
651
+ || (!proxyProfileIds.has(id) && !proxyProfileIds.has(base)));
652
+ }),
653
+ ])];
654
+ }
618
655
 
619
- export function isProxyOnlyModelId(value: string, providerNames: readonly string[] = []): boolean {
656
+ export function isProxyOnlyModelId(value: string, providerNames: readonly string[] = [], realAnthropicIds: readonly string[] = []): boolean {
620
657
  const id = value.trim().replace(/\[1m\]$/, "");
621
658
  if (!id) return false;
659
+ if (isRealDesktop3pModelId(id)) return false;
660
+ const base = id.endsWith("--fast") ? id.slice(0, -"--fast".length) : id;
661
+ if (resolveDesktop3pAlias(id) || resolveDesktop3pAlias(base)) return true;
662
+ if (realAnthropicIds.includes(id)) return false;
622
663
  const aliasPrefixes = [CLAUDE_ALIAS_PREFIX_CURRENT, CLAUDE_ALIAS_PREFIX_CURRENT_V2, CLAUDE_ALIAS_PREFIX_V1, CLAUDE_ALIAS_PREFIX_V2];
623
664
  if (aliasPrefixes.some(prefix => id.startsWith(prefix)) || DESKTOP_3P_ALIAS.test(id)) {
624
665
  return true;
@@ -680,9 +721,15 @@ export function buildNativeClaudeEnv(
680
721
  // otherwise settings.env can replace the destination while retaining the credential.
681
722
  if (hasOwnedAdmission) delete env.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST;
682
723
  const providerNames = Object.keys(config.providers);
724
+ const realAnthropicIds = nativeClaudeModelIds(config);
683
725
  for (const name of MODEL_ENV_SLOT_NAMES) {
684
726
  const value = env[name];
685
- if (value && isProxyOnlyModelId(value, providerNames)) delete env[name];
727
+ if (!value || !isProxyOnlyModelId(value, providerNames, realAnthropicIds)) continue;
728
+ delete env[name];
729
+ // The label opencodex paired with this slot names a proxy route the native session cannot use.
730
+ const labelName = `${name}_NAME`;
731
+ const label = claudeTierDisplayName(value);
732
+ if (isClaudeTierLabelSlot(name) && label !== undefined && env[labelName] === label) delete env[labelName];
686
733
  }
687
734
  if (deps.allowRootSkipPermissions === true && !env.IS_SANDBOX) env.IS_SANDBOX = "1";
688
735
  return env;
@@ -693,11 +740,12 @@ export function nativeModelOverride(
693
740
  configuredModel: string | undefined,
694
741
  args: readonly string[],
695
742
  providerNames: readonly string[] = [],
743
+ realAnthropicIds: readonly string[] = [],
696
744
  ): { flag?: string[]; warning?: string } {
697
- if (!pickedModel || !isProxyOnlyModelId(pickedModel, providerNames)) return {};
745
+ if (!pickedModel || !isProxyOnlyModelId(pickedModel, providerNames, realAnthropicIds)) return {};
698
746
  if (args.some(arg => arg === "--model" || arg.startsWith("--model="))) return {};
699
747
  const fallback = configuredModel?.trim();
700
- if (fallback && !isProxyOnlyModelId(fallback, providerNames)) {
748
+ if (fallback && !isProxyOnlyModelId(fallback, providerNames, realAnthropicIds)) {
701
749
  return {
702
750
  flag: ["--model", fallback],
703
751
  warning: `ℹ️ The saved model (${pickedModel}) requires the proxy. This native session will use ${fallback}.`,
@@ -858,6 +906,7 @@ async function launchNativeClaude(config: OcxConfig, args: string[], notice: str
858
906
  config.claudeCode?.model,
859
907
  args,
860
908
  providerNames,
909
+ nativeClaudeModelIds(config),
861
910
  );
862
911
  if (override.warning) console.error(override.warning);
863
912
  const allowRootSkipPermissions = shouldAllowRootSkipPermissions(args);
@@ -60,11 +60,14 @@ export function remoteHubConfigNote(
60
60
  // alone describes a machine that cannot read its hub, and `ocx status` is still the command
61
61
  // that has the facts — so the note points there in every case, connected or not.
62
62
  const connected = connection.state === "connected" && connection.token === "owned";
63
+ const link = config.client.transport === "link";
63
64
  const note = connection.state !== "connected"
64
65
  ? `this machine is configured as a client but its connection is ${connection.state}${connection.reason ? ` (${connection.reason})` : ""}; run ocx connect status`
65
66
  : connection.token !== "owned"
66
- ? `this machine is configured as a client but its hub data-plane token is ${connection.token}; run ocx connect status`
67
- : "provider credentials and model availability live on the hub; run ocx status";
67
+ ? `this machine is configured as a client but its ${link ? "Remote Link key" : "hub data-plane token"} is ${connection.token}; run ocx connect status`
68
+ : link
69
+ ? "this machine is a Remote Link Child: provider credentials, model availability and the Codex settings OpenCodex writes come from its Home; the settings in this file are local and inactive while linked; run ocx status"
70
+ : "provider credentials and model availability live on the hub; run ocx status";
68
71
  return { connected, origin: config.client.serverUrl, note };
69
72
  }
70
73
 
@@ -235,6 +238,7 @@ export async function handleConfigCommand(argv: string[]): Promise<number> {
235
238
  const path = args.shift();
236
239
  if (!path) throw new CliUsageError("config path is required", USAGE);
237
240
  rejectArgs(args, USAGE);
241
+ await (await import("./link-child")).printLinkChildLocalNotice("The values");
238
242
  const diagnostics = readConfigDiagnostics();
239
243
  if (diagnostics.source === "fallback" || diagnostics.error) {
240
244
  console.error(`Warning: Config at ${getConfigPath()} is invalid or unreadable; defaults are being shown for invalid settings. Run: ocx config validate. Inspect: ocx config show --source.`);
@@ -246,6 +250,7 @@ export async function handleConfigCommand(argv: string[]): Promise<number> {
246
250
  return;
247
251
  }
248
252
  if (action === "set" || action === "unset") {
253
+ await (await import("./link-child")).printLinkChildLocalWriteNotice();
249
254
  const path = args.shift();
250
255
  const raw = action === "set" ? args.shift() : undefined;
251
256
  if (!path || (action === "set" && raw === undefined)) throw new CliUsageError(action === "unset" ? "config path is required" : "config path and value are required", USAGE);
@@ -316,6 +321,7 @@ export async function handleConfigCommand(argv: string[]): Promise<number> {
316
321
  return;
317
322
  }
318
323
  if (action === "import") {
324
+ await (await import("./link-child")).printLinkChildLocalWriteNotice();
319
325
  const path = args.shift();
320
326
  const yes = takeFlag(args, "--yes");
321
327
  if (!path) throw new CliUsageError("import path is required", USAGE);
package/src/cli/debug.ts CHANGED
@@ -10,6 +10,14 @@ async function requireLiveProxy() {
10
10
  console.error("Proxy is not running. Start it with: ocx start");
11
11
  process.exit(1);
12
12
  }
13
+ if (live.role === "client") {
14
+ // Debug capture is the serving proxy's; a connected client has no management API (#6957).
15
+ const { readLinkChildContext, linkChildRefusal } = await import("./link-child");
16
+ const link = readLinkChildContext();
17
+ console.error(link ? linkChildRefusal(link, "ocx debug")
18
+ : "This listener runs in the client role and has no management API. Run this command on its serving hub. No request was sent.");
19
+ process.exit(1);
20
+ }
13
21
  return live;
14
22
  }
15
23
 
@@ -31,7 +31,7 @@ import { restoreNativeCodexAsync, type CodexNativeRestoreResult } from "../codex
31
31
  import { stripGrokConfig } from "../grok/inject";
32
32
  import { handleRestartScopeAfterWrite, readRestartScope, type RestartScope } from "./restart-scope";
33
33
  import { normalizeUpdateChannel, runGuiUpdateWorker } from "../update/job";
34
- import { isJsonOption, takeFlag, terminalSafeError } from "./runtime-api";
34
+ import { isJsonOption, takeFlag, terminalSafeError, terminalSafeText } from "./runtime-api";
35
35
  import { printStopSummary, type StopOutcome } from "./stop-report";
36
36
  import { parseStopApproval, type StopApproval } from "./stop-approval";
37
37
  import type { ResolveArgs } from "./resolve";
@@ -407,9 +407,22 @@ const commandRunners: Record<string, CommandRunner> = {
407
407
  try {
408
408
  const { syncConnectedClient } = await import("../client/connect");
409
409
  const result = await syncConnectedClient({ restartCodex });
410
+ const link = clientState.value.transport === "link";
410
411
  console.log(result.stale
411
- ? "Hub unavailable; retained and applied the last-known-good remote catalog (stale)."
412
- : "Remote hub catalog synchronized.");
412
+ ? `${link ? "Home" : "Hub"} unavailable; retained and applied the last-known-good remote catalog (stale).`
413
+ : link ? "Remote Link Home catalog synchronized." : "Remote hub catalog synchronized.");
414
+ if (result.homeSettings) {
415
+ const { describeHomeCodexSettings } = await import("../link/codex-settings");
416
+ const settings = result.homeSettings;
417
+ if (settings.source === "local") {
418
+ console.log(`Codex settings: kept this machine's local values (${terminalSafeText(settings.reason)}).`);
419
+ } else {
420
+ console.log(settings.source === "home"
421
+ ? `Codex settings applied from Home ${terminalSafeText(settings.document.home.name)}:`
422
+ : `Codex settings applied from the last recorded Home read (${terminalSafeText(settings.reason)}):`);
423
+ for (const line of describeHomeCodexSettings(settings.document.settings)) console.log(` ${terminalSafeText(line)}`);
424
+ }
425
+ }
413
426
  await handleConnectedSyncCatalogWrite(result, restartScope);
414
427
  // `process.exitCode` rather than a literal 0, for the same reason every other
415
428
  // runner does it (tests/cli/cli-transport-honesty.test.ts): the catalog-write helper
@@ -471,7 +484,7 @@ const commandRunners: Record<string, CommandRunner> = {
471
484
  },
472
485
  config,
473
486
  port: live.port,
474
- }, ["mcode", "pi", "raycast", "omo", "cline", "commandcode", "droid", "opencode", "kilo"]));
487
+ }, ["mcode", "pi", "raycast", "omo", "cline", "commandcode", "droid", "opencode", "kilo", "qoder"]));
475
488
  } catch (error) {
476
489
  console.warn(`Client integrations were not refreshed: ${error instanceof Error ? error.message : String(error)}`);
477
490
  }
@@ -821,6 +834,10 @@ const commandRunners: Record<string, CommandRunner> = {
821
834
  const { handleComboCommand } = await import("./combo");
822
835
  return await handleComboCommand(deps.args.slice(1));
823
836
  },
837
+ advisor: async deps => {
838
+ const { handleAdvisorCommand } = await import("./advisor");
839
+ return await handleAdvisorCommand(deps.args.slice(1));
840
+ },
824
841
  companion: async deps => {
825
842
  const { handleCompanionCommand } = await import("./companion");
826
843
  return await handleCompanionCommand(deps.args.slice(1), { findLiveProxy: deps.findLiveProxy });
package/src/cli/doctor.ts CHANGED
@@ -1428,6 +1428,15 @@ export async function runDoctor(args: string[] = []): Promise<void> {
1428
1428
  }
1429
1429
  }
1430
1430
 
1431
+ // #2999: which process refreshes the native main login in CODEX_HOME.
1432
+ console.log("\nNative main refresh");
1433
+ {
1434
+ const { loadConfig } = await import("../config");
1435
+ const { formatNativeMainRefreshDoctorLines, resolveNativeMainRefreshMode } = await import("../codex/native-main-refresh-mode");
1436
+ const resolution = await resolveNativeMainRefreshMode(loadConfig());
1437
+ for (const line of formatNativeMainRefreshDoctorLines(resolution)) console.log(line);
1438
+ }
1439
+
1431
1440
  // Mirrors `ocx status` through the same comparison rather than a second implementation:
1432
1441
  // two diagnostics disagreeing about whether an install is stale is worse than one (#2701).
1433
1442
  // No extra probe -- findLiveProxy already carried the version back.