@remodex/rmx 1.0.2

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 (588) hide show
  1. package/AGENTS_INSTALL.md +91 -0
  2. package/LICENSE +21 -0
  3. package/README.md +242 -0
  4. package/assets/architecture.png +0 -0
  5. package/assets/banner.png +0 -0
  6. package/assets/claude-code-models.gif +0 -0
  7. package/assets/codex-app-picker.png +0 -0
  8. package/bin/ocx.mjs +584 -0
  9. package/bin/package-main.mjs +9 -0
  10. package/gui/dist/assets/index-CZqebSPQ.css +1 -0
  11. package/gui/dist/assets/index-CkETtt7P.js +71 -0
  12. package/gui/dist/favicon.png +0 -0
  13. package/gui/dist/fonts/google-sans-cyrillic.woff2 +0 -0
  14. package/gui/dist/fonts/google-sans-latin.woff2 +0 -0
  15. package/gui/dist/icons.svg +24 -0
  16. package/gui/dist/index.html +25 -0
  17. package/gui/dist/logo.png +0 -0
  18. package/gui/dist/provider-icons/alibaba-color.svg +1 -0
  19. package/gui/dist/provider-icons/antigravity-color.svg +1 -0
  20. package/gui/dist/provider-icons/claude-color.svg +1 -0
  21. package/gui/dist/provider-icons/cline-color.svg +16 -0
  22. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
  23. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  24. package/gui/dist/provider-icons/copilot-color.svg +1 -0
  25. package/gui/dist/provider-icons/cursor-color.svg +2 -0
  26. package/gui/dist/provider-icons/deepseek-color.svg +1 -0
  27. package/gui/dist/provider-icons/discord.svg +1 -0
  28. package/gui/dist/provider-icons/firepass-color.svg +1 -0
  29. package/gui/dist/provider-icons/fireworks-color.svg +1 -0
  30. package/gui/dist/provider-icons/gemini-color.svg +1 -0
  31. package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
  32. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
  33. package/gui/dist/provider-icons/grok.svg +1 -0
  34. package/gui/dist/provider-icons/groq-color.svg +1 -0
  35. package/gui/dist/provider-icons/huggingface-color.svg +1 -0
  36. package/gui/dist/provider-icons/kimi-color.svg +1 -0
  37. package/gui/dist/provider-icons/kiro-color.svg +15 -0
  38. package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
  39. package/gui/dist/provider-icons/mistral-color.svg +1 -0
  40. package/gui/dist/provider-icons/moonshot-color.svg +1 -0
  41. package/gui/dist/provider-icons/nvidia-color.svg +1 -0
  42. package/gui/dist/provider-icons/ollama-color.svg +1 -0
  43. package/gui/dist/provider-icons/openai.svg +1 -0
  44. package/gui/dist/provider-icons/opencode.svg +2 -0
  45. package/gui/dist/provider-icons/openrouter-color.svg +1 -0
  46. package/gui/dist/provider-icons/pi.svg +21 -0
  47. package/gui/dist/provider-icons/qianfan-color.svg +1 -0
  48. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
  49. package/gui/dist/provider-icons/telegram.svg +1 -0
  50. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
  51. package/gui/dist/provider-icons/vllm-color.svg +1 -0
  52. package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
  53. package/package.json +118 -0
  54. package/src/AGENTS.md +28 -0
  55. package/src/adapters/anthropic-image-guard.ts +251 -0
  56. package/src/adapters/anthropic-image-normalize.ts +518 -0
  57. package/src/adapters/anthropic.ts +1205 -0
  58. package/src/adapters/azure.ts +36 -0
  59. package/src/adapters/base.ts +83 -0
  60. package/src/adapters/client-fingerprint.ts +59 -0
  61. package/src/adapters/command-code.ts +453 -0
  62. package/src/adapters/cursor/arg-codec.ts +38 -0
  63. package/src/adapters/cursor/arg-normalize.ts +104 -0
  64. package/src/adapters/cursor/cursor-errors.ts +165 -0
  65. package/src/adapters/cursor/discovery.ts +276 -0
  66. package/src/adapters/cursor/effort-map.ts +139 -0
  67. package/src/adapters/cursor/exec-policy.ts +88 -0
  68. package/src/adapters/cursor/framing.ts +250 -0
  69. package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
  70. package/src/adapters/cursor/kv-store.ts +52 -0
  71. package/src/adapters/cursor/live-models.ts +153 -0
  72. package/src/adapters/cursor/live-smoke-gate.ts +41 -0
  73. package/src/adapters/cursor/live-transport.ts +1235 -0
  74. package/src/adapters/cursor/mcp-config.ts +42 -0
  75. package/src/adapters/cursor/mcp-manager.ts +333 -0
  76. package/src/adapters/cursor/message-mapper.ts +49 -0
  77. package/src/adapters/cursor/native-exec-common.ts +59 -0
  78. package/src/adapters/cursor/native-exec-desktop.ts +184 -0
  79. package/src/adapters/cursor/native-exec-fs.ts +332 -0
  80. package/src/adapters/cursor/native-exec-mcp.ts +153 -0
  81. package/src/adapters/cursor/native-exec-network.ts +43 -0
  82. package/src/adapters/cursor/native-exec-shell.ts +548 -0
  83. package/src/adapters/cursor/native-exec-tools.ts +118 -0
  84. package/src/adapters/cursor/native-exec.ts +604 -0
  85. package/src/adapters/cursor/protobuf-events.ts +735 -0
  86. package/src/adapters/cursor/protobuf-request.ts +719 -0
  87. package/src/adapters/cursor/request-builder.ts +280 -0
  88. package/src/adapters/cursor/thread-continuity.ts +67 -0
  89. package/src/adapters/cursor/tool-definitions.ts +621 -0
  90. package/src/adapters/cursor/transport-retry.ts +132 -0
  91. package/src/adapters/cursor/transport.ts +57 -0
  92. package/src/adapters/cursor/types.ts +59 -0
  93. package/src/adapters/cursor.ts +196 -0
  94. package/src/adapters/google-antigravity-replay.ts +520 -0
  95. package/src/adapters/google-antigravity-wire.ts +140 -0
  96. package/src/adapters/google-errors.ts +85 -0
  97. package/src/adapters/google-http.ts +100 -0
  98. package/src/adapters/google-tool-schema.ts +173 -0
  99. package/src/adapters/google-truncation.ts +24 -0
  100. package/src/adapters/google-wire-compiler.ts +232 -0
  101. package/src/adapters/google.ts +859 -0
  102. package/src/adapters/identity.ts +77 -0
  103. package/src/adapters/image.ts +23 -0
  104. package/src/adapters/kiro-constants.ts +16 -0
  105. package/src/adapters/kiro-errors.ts +208 -0
  106. package/src/adapters/kiro-events.ts +197 -0
  107. package/src/adapters/kiro-images.ts +129 -0
  108. package/src/adapters/kiro-retry.ts +312 -0
  109. package/src/adapters/kiro-thinking.ts +104 -0
  110. package/src/adapters/kiro-tool-fallback.ts +36 -0
  111. package/src/adapters/kiro-tools.ts +224 -0
  112. package/src/adapters/kiro-truncation.ts +33 -0
  113. package/src/adapters/kiro-wire.ts +129 -0
  114. package/src/adapters/kiro.ts +1924 -0
  115. package/src/adapters/mimo-free.ts +263 -0
  116. package/src/adapters/openai-chat.ts +1265 -0
  117. package/src/adapters/openai-responses.ts +1309 -0
  118. package/src/adapters/run-turn-queue.ts +114 -0
  119. package/src/adapters/tool-catalog-nudge.ts +71 -0
  120. package/src/adapters/upstream-http-error.ts +48 -0
  121. package/src/android-remote/assets.ts +218 -0
  122. package/src/android-remote/attachments.ts +168 -0
  123. package/src/android-remote/auth.ts +237 -0
  124. package/src/android-remote/cloudflare-provisioning.ts +409 -0
  125. package/src/android-remote/cloudflare-secret.ts +106 -0
  126. package/src/android-remote/cloudflare-tunnel.ts +488 -0
  127. package/src/android-remote/cloudflared.ts +286 -0
  128. package/src/android-remote/codex-app-server.ts +565 -0
  129. package/src/android-remote/desktop-history-page.ts +936 -0
  130. package/src/android-remote/desktop-ipc.ts +3643 -0
  131. package/src/android-remote/desktop-ownership-store.ts +98 -0
  132. package/src/android-remote/desktop-project-registration.ts +129 -0
  133. package/src/android-remote/desktop-session-stream.ts +1110 -0
  134. package/src/android-remote/desktop-workspace-state.ts +443 -0
  135. package/src/android-remote/file-change-parser.ts +112 -0
  136. package/src/android-remote/gateway.ts +9108 -0
  137. package/src/android-remote/mutation-store.ts +299 -0
  138. package/src/android-remote/projection.ts +1780 -0
  139. package/src/android-remote/queued-turn-store.ts +248 -0
  140. package/src/android-remote/session-command-recovery.ts +1384 -0
  141. package/src/android-remote/store.ts +466 -0
  142. package/src/android-remote/thread-reconciliation.ts +133 -0
  143. package/src/android-remote/thread-source-paths.ts +307 -0
  144. package/src/android-remote/thread-stream.ts +546 -0
  145. package/src/android-remote/turn-activity.ts +235 -0
  146. package/src/android-remote/user-message-identity.ts +94 -0
  147. package/src/bridge.ts +1793 -0
  148. package/src/chat/inbound.ts +295 -0
  149. package/src/chat/outbound.ts +821 -0
  150. package/src/claude/agents-inject.ts +267 -0
  151. package/src/claude/alias.ts +149 -0
  152. package/src/claude/auth-detect.ts +229 -0
  153. package/src/claude/auth-mode-migration.ts +32 -0
  154. package/src/claude/auth-mode.ts +62 -0
  155. package/src/claude/context-windows.ts +189 -0
  156. package/src/claude/desktop-3p-guard.ts +35 -0
  157. package/src/claude/desktop-3p-paths.ts +84 -0
  158. package/src/claude/desktop-3p.ts +601 -0
  159. package/src/claude/desktop-health.ts +26 -0
  160. package/src/claude/desktop-profile.ts +263 -0
  161. package/src/claude/gateway-cache.ts +70 -0
  162. package/src/claude/inbound-debug.ts +163 -0
  163. package/src/claude/inbound.ts +519 -0
  164. package/src/claude/model-info.ts +154 -0
  165. package/src/claude/outbound.ts +898 -0
  166. package/src/cli/access.ts +108 -0
  167. package/src/cli/account-api.ts +296 -0
  168. package/src/cli/account-auth.ts +250 -0
  169. package/src/cli/account-catalog-refresh.ts +14 -0
  170. package/src/cli/account-extended.ts +476 -0
  171. package/src/cli/account-main.ts +317 -0
  172. package/src/cli/account.ts +297 -0
  173. package/src/cli/agent-driven.ts +70 -0
  174. package/src/cli/agent.ts +184 -0
  175. package/src/cli/catalog-prewarm.ts +27 -0
  176. package/src/cli/claude-desktop.ts +211 -0
  177. package/src/cli/claude.ts +302 -0
  178. package/src/cli/codex-shim-autorestore.ts +45 -0
  179. package/src/cli/codex-shim-readiness.ts +69 -0
  180. package/src/cli/combo.ts +124 -0
  181. package/src/cli/config-command.ts +183 -0
  182. package/src/cli/debug.ts +228 -0
  183. package/src/cli/desktop-first-run.ts +25 -0
  184. package/src/cli/doctor.ts +1022 -0
  185. package/src/cli/export-command.ts +201 -0
  186. package/src/cli/help.ts +370 -0
  187. package/src/cli/index.ts +1565 -0
  188. package/src/cli/init.ts +224 -0
  189. package/src/cli/integrations.ts +225 -0
  190. package/src/cli/interactive-confirm.ts +133 -0
  191. package/src/cli/internal-dispatch.ts +35 -0
  192. package/src/cli/launcher-context.ts +77 -0
  193. package/src/cli/models-runtime.ts +224 -0
  194. package/src/cli/models.ts +340 -0
  195. package/src/cli/observe.ts +170 -0
  196. package/src/cli/opencode.ts +587 -0
  197. package/src/cli/provider-runtime.ts +179 -0
  198. package/src/cli/provider.ts +476 -0
  199. package/src/cli/ready.ts +301 -0
  200. package/src/cli/route-policy.ts +92 -0
  201. package/src/cli/runtime-api.ts +328 -0
  202. package/src/cli/star-prompt.ts +211 -0
  203. package/src/cli/status-oauth.ts +78 -0
  204. package/src/cli/status.ts +321 -0
  205. package/src/cli/system-command.ts +196 -0
  206. package/src/cli/system-restart-client.ts +146 -0
  207. package/src/cli/tray-proxy.ts +205 -0
  208. package/src/cli/v2.ts +200 -0
  209. package/src/cli.ts +10 -0
  210. package/src/clients/config-export.ts +1109 -0
  211. package/src/codex/account-id.ts +34 -0
  212. package/src/codex/account-label.ts +34 -0
  213. package/src/codex/account-lifecycle.ts +172 -0
  214. package/src/codex/account-namespace-match.ts +63 -0
  215. package/src/codex/account-namespaces.ts +195 -0
  216. package/src/codex/account-pause.ts +20 -0
  217. package/src/codex/account-priority.ts +83 -0
  218. package/src/codex/account-runtime-state.ts +31 -0
  219. package/src/codex/account-store.ts +517 -0
  220. package/src/codex/account-usability.ts +40 -0
  221. package/src/codex/admission.ts +263 -0
  222. package/src/codex/app-server-processes.ts +799 -0
  223. package/src/codex/auth-api.ts +2098 -0
  224. package/src/codex/auth-collision.ts +107 -0
  225. package/src/codex/auth-context.ts +480 -0
  226. package/src/codex/autostart-health.ts +156 -0
  227. package/src/codex/catalog/account-models.ts +67 -0
  228. package/src/codex/catalog/aggregation.ts +471 -0
  229. package/src/codex/catalog/bundled.ts +533 -0
  230. package/src/codex/catalog/effort.ts +432 -0
  231. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  232. package/src/codex/catalog/kinds.ts +2 -0
  233. package/src/codex/catalog/metadata.ts +287 -0
  234. package/src/codex/catalog/native-models.ts +7 -0
  235. package/src/codex/catalog/parsing.ts +503 -0
  236. package/src/codex/catalog/provider-fetch.ts +2267 -0
  237. package/src/codex/catalog/sync.ts +1606 -0
  238. package/src/codex/catalog-admission.ts +197 -0
  239. package/src/codex/catalog-refresh-status.ts +87 -0
  240. package/src/codex/catalog-write-serialization.ts +242 -0
  241. package/src/codex/catalog.ts +15 -0
  242. package/src/codex/codex-write-lock.ts +384 -0
  243. package/src/codex/convergence-types.ts +593 -0
  244. package/src/codex/convergence.ts +580 -0
  245. package/src/codex/custom-model-catalog-migration.ts +176 -0
  246. package/src/codex/data/upstream-models.json +830 -0
  247. package/src/codex/desired-state.ts +230 -0
  248. package/src/codex/desktop-client-processes.ts +521 -0
  249. package/src/codex/exec-invocation.ts +22 -0
  250. package/src/codex/features.ts +1091 -0
  251. package/src/codex/generation.ts +202 -0
  252. package/src/codex/history-job.ts +347 -0
  253. package/src/codex/history-lock.ts +242 -0
  254. package/src/codex/history-migration-guardian.ts +115 -0
  255. package/src/codex/history-provider.ts +1075 -0
  256. package/src/codex/history-transition.ts +105 -0
  257. package/src/codex/history-worker.ts +204 -0
  258. package/src/codex/home.ts +206 -0
  259. package/src/codex/inject-coordination.ts +257 -0
  260. package/src/codex/inject.ts +1857 -0
  261. package/src/codex/injected-marker.ts +79 -0
  262. package/src/codex/integration-record.ts +266 -0
  263. package/src/codex/internal/catalog-writer.ts +203 -0
  264. package/src/codex/internal/history-writer.ts +105 -0
  265. package/src/codex/journal.ts +172 -0
  266. package/src/codex/main-account-cache.ts +56 -0
  267. package/src/codex/main-account.ts +40 -0
  268. package/src/codex/management-convergence.ts +114 -0
  269. package/src/codex/model-cache.ts +267 -0
  270. package/src/codex/native-main-admission.ts +47 -0
  271. package/src/codex/native-main-auth-temp.ts +187 -0
  272. package/src/codex/native-main-claim.ts +167 -0
  273. package/src/codex/native-main-lock-file.ts +162 -0
  274. package/src/codex/native-main-owner.ts +329 -0
  275. package/src/codex/native-profile-api.ts +247 -0
  276. package/src/codex/native-profile-manager.ts +1531 -0
  277. package/src/codex/native-profile-processes.ts +121 -0
  278. package/src/codex/native-profile-recovery.ts +99 -0
  279. package/src/codex/native-profile-stage-store.ts +387 -0
  280. package/src/codex/native-profile-startup.ts +348 -0
  281. package/src/codex/native-profile-store.ts +855 -0
  282. package/src/codex/native-profile-types.ts +120 -0
  283. package/src/codex/native-residue.ts +691 -0
  284. package/src/codex/paths.ts +78 -0
  285. package/src/codex/plugins-doctor.ts +242 -0
  286. package/src/codex/pool-rotation.ts +295 -0
  287. package/src/codex/project-config-warnings.ts +426 -0
  288. package/src/codex/prompt-journal.ts +311 -0
  289. package/src/codex/prompt-layers.ts +967 -0
  290. package/src/codex/prompt-lock.ts +143 -0
  291. package/src/codex/provider-adoption.ts +242 -0
  292. package/src/codex/quota-rejection.ts +224 -0
  293. package/src/codex/quota.ts +494 -0
  294. package/src/codex/refresh.ts +60 -0
  295. package/src/codex/routing.ts +1855 -0
  296. package/src/codex/runtime.ts +659 -0
  297. package/src/codex/shim.ts +1215 -0
  298. package/src/codex/subagent-defaults.ts +557 -0
  299. package/src/codex/subagent-model-fallback.ts +560 -0
  300. package/src/codex/sync.ts +238 -0
  301. package/src/codex/transition-state.ts +612 -0
  302. package/src/codex/upstream-host-health.ts +368 -0
  303. package/src/codex/user-identity.ts +374 -0
  304. package/src/codex/warmup.ts +192 -0
  305. package/src/codex/websocket-registry.ts +100 -0
  306. package/src/codex/write-coordination.ts +114 -0
  307. package/src/combos/failover.ts +140 -0
  308. package/src/combos/index.ts +44 -0
  309. package/src/combos/request.ts +64 -0
  310. package/src/combos/resolve.ts +232 -0
  311. package/src/combos/types.ts +392 -0
  312. package/src/config.ts +3270 -0
  313. package/src/generated/model-metadata.ts +144 -0
  314. package/src/github/star-state.ts +203 -0
  315. package/src/grok/inject.ts +540 -0
  316. package/src/grok/inspect.ts +45 -0
  317. package/src/grok/status.ts +127 -0
  318. package/src/grok/sync.ts +66 -0
  319. package/src/images/artifacts.ts +516 -0
  320. package/src/images/fulfill-video.ts +163 -0
  321. package/src/images/fulfill.ts +149 -0
  322. package/src/images/index.ts +4 -0
  323. package/src/images/loop.ts +922 -0
  324. package/src/images/plan.ts +133 -0
  325. package/src/images/synthetic-tool.ts +133 -0
  326. package/src/images/types.ts +41 -0
  327. package/src/images/xai-client.ts +141 -0
  328. package/src/images/xai-video-client.ts +163 -0
  329. package/src/index.ts +22 -0
  330. package/src/integrations/config-io.ts +151 -0
  331. package/src/integrations/journal.ts +315 -0
  332. package/src/integrations/merge.ts +135 -0
  333. package/src/integrations/native/ownership-preflight.ts +202 -0
  334. package/src/integrations/ownership.ts +111 -0
  335. package/src/integrations/registry.ts +108 -0
  336. package/src/integrations/serialize.ts +235 -0
  337. package/src/integrations/state.ts +290 -0
  338. package/src/integrations/store.ts +103 -0
  339. package/src/integrations/writer.ts +492 -0
  340. package/src/lib/abort.ts +146 -0
  341. package/src/lib/admin-secrets.ts +25 -0
  342. package/src/lib/admission.ts +83 -0
  343. package/src/lib/app-owned-memory-stores.ts +173 -0
  344. package/src/lib/app-owned-memory.ts +265 -0
  345. package/src/lib/bounded-body.ts +242 -0
  346. package/src/lib/bun-binary-validator.d.mts +3 -0
  347. package/src/lib/bun-binary-validator.mjs +18 -0
  348. package/src/lib/bun-runtime.ts +184 -0
  349. package/src/lib/bun-stream-caps.ts +127 -0
  350. package/src/lib/config-ownership.ts +438 -0
  351. package/src/lib/crash-guard.ts +344 -0
  352. package/src/lib/debug-log-buffer.ts +83 -0
  353. package/src/lib/debug-settings.ts +108 -0
  354. package/src/lib/debug.ts +31 -0
  355. package/src/lib/destination-policy.ts +316 -0
  356. package/src/lib/errors.ts +364 -0
  357. package/src/lib/eventstream-decoder.ts +253 -0
  358. package/src/lib/gcp-adc.ts +341 -0
  359. package/src/lib/injection-debug-log.ts +58 -0
  360. package/src/lib/local-management-attestation.ts +51 -0
  361. package/src/lib/open-url.ts +25 -0
  362. package/src/lib/pinned-http.ts +182 -0
  363. package/src/lib/privacy.ts +20 -0
  364. package/src/lib/process-control.ts +168 -0
  365. package/src/lib/provider-environment.ts +470 -0
  366. package/src/lib/provider-outbound.ts +203 -0
  367. package/src/lib/provider-url.ts +14 -0
  368. package/src/lib/proxy-env.ts +18 -0
  369. package/src/lib/redact.ts +510 -0
  370. package/src/lib/remodex-home.ts +616 -0
  371. package/src/lib/retry-after.ts +55 -0
  372. package/src/lib/service-secrets.ts +178 -0
  373. package/src/lib/shadow-call.ts +54 -0
  374. package/src/lib/sidecar-tracker.ts +52 -0
  375. package/src/lib/sse-decoder.ts +364 -0
  376. package/src/lib/state-store-registrations.ts +109 -0
  377. package/src/lib/state-store-sweeper.ts +184 -0
  378. package/src/lib/system-restart-contract.ts +73 -0
  379. package/src/lib/test-home-guard.ts +98 -0
  380. package/src/lib/token-estimate.ts +69 -0
  381. package/src/lib/translator-budget.ts +366 -0
  382. package/src/lib/upstream-reachability.ts +91 -0
  383. package/src/lib/upstream-retry.ts +508 -0
  384. package/src/lib/win-exec.ts +115 -0
  385. package/src/lib/win-paths.ts +68 -0
  386. package/src/lib/windows-elevation.ts +705 -0
  387. package/src/lib/windows-secret-acl.ts +817 -0
  388. package/src/lib/windows-user-principal.ts +283 -0
  389. package/src/lib/winsw.ts +402 -0
  390. package/src/model-sources.ts +73 -0
  391. package/src/oauth/anthropic-routing.ts +594 -0
  392. package/src/oauth/anthropic.ts +177 -0
  393. package/src/oauth/callback-server.ts +294 -0
  394. package/src/oauth/chatgpt.ts +150 -0
  395. package/src/oauth/command-code.ts +239 -0
  396. package/src/oauth/cursor.ts +231 -0
  397. package/src/oauth/github-copilot.ts +428 -0
  398. package/src/oauth/google-antigravity.ts +230 -0
  399. package/src/oauth/health.ts +443 -0
  400. package/src/oauth/index.ts +1280 -0
  401. package/src/oauth/key-providers.ts +128 -0
  402. package/src/oauth/kimi.ts +213 -0
  403. package/src/oauth/kiro-credentials.ts +726 -0
  404. package/src/oauth/kiro.ts +621 -0
  405. package/src/oauth/local-token-detect.ts +121 -0
  406. package/src/oauth/log.ts +48 -0
  407. package/src/oauth/login-cli.ts +163 -0
  408. package/src/oauth/pkce.ts +15 -0
  409. package/src/oauth/store.ts +655 -0
  410. package/src/oauth/token-guardian.ts +309 -0
  411. package/src/oauth/types.ts +62 -0
  412. package/src/oauth/xai.ts +241 -0
  413. package/src/providers/alibaba-region-backup.ts +75 -0
  414. package/src/providers/alibaba-region-migration.ts +156 -0
  415. package/src/providers/alibaba-region-startup.ts +36 -0
  416. package/src/providers/antigravity-models.ts +317 -0
  417. package/src/providers/api-keys.ts +140 -0
  418. package/src/providers/base-url-choices.ts +64 -0
  419. package/src/providers/codex-capacity.ts +288 -0
  420. package/src/providers/command-code-efforts.ts +85 -0
  421. package/src/providers/context-cap.ts +73 -0
  422. package/src/providers/derive.ts +451 -0
  423. package/src/providers/free-directory.ts +187 -0
  424. package/src/providers/github-copilot-transport.ts +56 -0
  425. package/src/providers/google-vertex-location.ts +14 -0
  426. package/src/providers/key-failover.ts +271 -0
  427. package/src/providers/kiro-models.ts +67 -0
  428. package/src/providers/label.ts +19 -0
  429. package/src/providers/model-discovery-limits.ts +16 -0
  430. package/src/providers/model-discovery.ts +361 -0
  431. package/src/providers/openai-sidecar.ts +235 -0
  432. package/src/providers/openai-tier-startup.ts +27 -0
  433. package/src/providers/openai-tiers.ts +301 -0
  434. package/src/providers/openai-virtual-models.ts +83 -0
  435. package/src/providers/openrouter-routing.ts +102 -0
  436. package/src/providers/provider-id-rewrite.ts +179 -0
  437. package/src/providers/quota.ts +1942 -0
  438. package/src/providers/reasoning-capabilities.ts +336 -0
  439. package/src/providers/registry.ts +2375 -0
  440. package/src/providers/slug-codec.ts +74 -0
  441. package/src/providers/xai-transport.ts +149 -0
  442. package/src/reasoning-effort.ts +243 -0
  443. package/src/responses/compaction.ts +124 -0
  444. package/src/responses/hosted-tool-policy.ts +9 -0
  445. package/src/responses/parser.ts +714 -0
  446. package/src/responses/reasoning-envelope.ts +60 -0
  447. package/src/responses/reasoning-replay-cache.ts +106 -0
  448. package/src/responses/schema.ts +159 -0
  449. package/src/responses/spill-store.ts +431 -0
  450. package/src/responses/state.ts +1039 -0
  451. package/src/responses/tool-groups.ts +19 -0
  452. package/src/router.ts +802 -0
  453. package/src/routing/analytics.ts +377 -0
  454. package/src/routing/capability.ts +205 -0
  455. package/src/routing/cost.ts +77 -0
  456. package/src/routing/evaluator.ts +444 -0
  457. package/src/routing/health.ts +401 -0
  458. package/src/routing/history/cursor.ts +43 -0
  459. package/src/routing/history/indexer.ts +605 -0
  460. package/src/routing/history/schema.ts +72 -0
  461. package/src/routing/profile-namespace.ts +15 -0
  462. package/src/routing/profile.ts +424 -0
  463. package/src/routing/quota.ts +145 -0
  464. package/src/routing/request-evidence.ts +45 -0
  465. package/src/routing/trace.ts +686 -0
  466. package/src/server/adapter-resolve.ts +83 -0
  467. package/src/server/auth-cors.ts +606 -0
  468. package/src/server/chat-completions.ts +379 -0
  469. package/src/server/claude-messages.ts +980 -0
  470. package/src/server/effort-policy.ts +251 -0
  471. package/src/server/github-copilot-responses-repair.ts +338 -0
  472. package/src/server/gui-static.ts +152 -0
  473. package/src/server/image-retry.ts +42 -0
  474. package/src/server/images.ts +485 -0
  475. package/src/server/index.ts +1633 -0
  476. package/src/server/lifecycle.ts +482 -0
  477. package/src/server/live.ts +609 -0
  478. package/src/server/management/agent-settings-routes.ts +1180 -0
  479. package/src/server/management/android-remote-routes.ts +390 -0
  480. package/src/server/management/api-access.ts +141 -0
  481. package/src/server/management/api-key-usage.ts +167 -0
  482. package/src/server/management/body.ts +35 -0
  483. package/src/server/management/combo-routes.ts +244 -0
  484. package/src/server/management/config-routes.ts +602 -0
  485. package/src/server/management/context.ts +88 -0
  486. package/src/server/management/integration-routes.ts +538 -0
  487. package/src/server/management/logs-usage-routes.ts +516 -0
  488. package/src/server/management/model-routes.ts +519 -0
  489. package/src/server/management/model-rows.ts +143 -0
  490. package/src/server/management/native-integration-routes.ts +781 -0
  491. package/src/server/management/oauth-account-routes.ts +573 -0
  492. package/src/server/management/provider-routes.ts +781 -0
  493. package/src/server/management/request-history-routes.ts +191 -0
  494. package/src/server/management/routing-analytics-routes.ts +74 -0
  495. package/src/server/management/routing-profile-routes.ts +384 -0
  496. package/src/server/management/shared.ts +277 -0
  497. package/src/server/management/sidebar-routes.ts +106 -0
  498. package/src/server/management/sync-response.ts +69 -0
  499. package/src/server/management/system-restart.ts +433 -0
  500. package/src/server/management/system-routes.ts +141 -0
  501. package/src/server/management/usage-summary-cache.ts +86 -0
  502. package/src/server/management-api.ts +269 -0
  503. package/src/server/management-auth.ts +353 -0
  504. package/src/server/memory-watchdog.ts +156 -0
  505. package/src/server/port-reclaim.ts +307 -0
  506. package/src/server/ports.ts +156 -0
  507. package/src/server/proxy-liveness.ts +326 -0
  508. package/src/server/proxy-stop.ts +92 -0
  509. package/src/server/readiness.ts +99 -0
  510. package/src/server/relay-eager.ts +353 -0
  511. package/src/server/relay.ts +1179 -0
  512. package/src/server/request-decompress.ts +132 -0
  513. package/src/server/request-log-conversation.ts +168 -0
  514. package/src/server/request-log.ts +1072 -0
  515. package/src/server/responses/collaboration.ts +409 -0
  516. package/src/server/responses/compact.ts +710 -0
  517. package/src/server/responses/core.ts +3561 -0
  518. package/src/server/responses/encrypted-payload.ts +308 -0
  519. package/src/server/responses/fetch-helpers.ts +171 -0
  520. package/src/server/responses/passthrough-error.ts +78 -0
  521. package/src/server/responses/policy-fallback.ts +152 -0
  522. package/src/server/responses/terminal-guard.ts +230 -0
  523. package/src/server/responses/upstream-error.ts +48 -0
  524. package/src/server/responses-image-gen-repair.ts +132 -0
  525. package/src/server/responses-item-id-repair.ts +272 -0
  526. package/src/server/responses-json-events.ts +52 -0
  527. package/src/server/responses-model-rewrite.ts +29 -0
  528. package/src/server/responses-snapshot-repair.ts +621 -0
  529. package/src/server/responses.ts +10 -0
  530. package/src/server/search.ts +181 -0
  531. package/src/server/sse-frame-buffer.ts +292 -0
  532. package/src/server/sse-payload-rewrite.ts +263 -0
  533. package/src/server/startup-action-control.ts +308 -0
  534. package/src/server/startup-health-cache.ts +119 -0
  535. package/src/server/system-env.ts +418 -0
  536. package/src/server/windows-tcp-drop.ts +184 -0
  537. package/src/server/windows-tray-control.ts +41 -0
  538. package/src/server/ws-bridge.ts +470 -0
  539. package/src/service-manager-probe.ts +824 -0
  540. package/src/service.ts +3011 -0
  541. package/src/stall-timeout.ts +20 -0
  542. package/src/storage/cleanup-job.ts +57 -0
  543. package/src/storage/cleanup.ts +3085 -0
  544. package/src/storage/policy-job.ts +457 -0
  545. package/src/storage/policy-scheduler.ts +40 -0
  546. package/src/storage/policy-worker.ts +59 -0
  547. package/src/storage/policy.ts +527 -0
  548. package/src/storage/restore-job.ts +299 -0
  549. package/src/storage/restore-worker.ts +58 -0
  550. package/src/storage/scanner.ts +238 -0
  551. package/src/storage/storage-mutation-coordinator.ts +139 -0
  552. package/src/storage/worker-lifecycle.ts +215 -0
  553. package/src/tray/assets/opencodex-tray-offline.ico +0 -0
  554. package/src/tray/assets/opencodex-tray-online.ico +0 -0
  555. package/src/tray/assets/opencodex-tray-warning.ico +0 -0
  556. package/src/tray/assets/opencodex-tray.png +0 -0
  557. package/src/tray/windows-tray.ps1 +364 -0
  558. package/src/tray/windows.ts +738 -0
  559. package/src/types.ts +1531 -0
  560. package/src/update/badge.ts +72 -0
  561. package/src/update/desktop-release.ts +1620 -0
  562. package/src/update/index.ts +402 -0
  563. package/src/update/job.ts +1906 -0
  564. package/src/update/notify.ts +261 -0
  565. package/src/update/npm-cache-preflight.d.mts +47 -0
  566. package/src/update/npm-cache-preflight.mjs +201 -0
  567. package/src/update/npm-invocation.d.mts +23 -0
  568. package/src/update/npm-invocation.mjs +94 -0
  569. package/src/update/tray-update-plan.d.mts +18 -0
  570. package/src/update/tray-update-plan.mjs +38 -0
  571. package/src/usage/cost.ts +0 -0
  572. package/src/usage/debug.ts +97 -0
  573. package/src/usage/expected-prices.ts +283 -0
  574. package/src/usage/log.ts +695 -0
  575. package/src/usage/summary.ts +585 -0
  576. package/src/usage/totals.ts +14 -0
  577. package/src/vision/anthropic-describe.ts +185 -0
  578. package/src/vision/describe.ts +127 -0
  579. package/src/vision/index.ts +558 -0
  580. package/src/vision/reasoning.ts +55 -0
  581. package/src/web-search/anthropic-executor.ts +189 -0
  582. package/src/web-search/executor.ts +105 -0
  583. package/src/web-search/format-result.ts +89 -0
  584. package/src/web-search/index.ts +196 -0
  585. package/src/web-search/loop.ts +791 -0
  586. package/src/web-search/parse.ts +235 -0
  587. package/src/web-search/progress-stream.ts +342 -0
  588. package/src/web-search/synthetic-tool.ts +47 -0
@@ -0,0 +1,184 @@
1
+ import {
2
+ CliUsageError,
3
+ csv,
4
+ printData,
5
+ rejectArgs,
6
+ runCliAction,
7
+ runtimeRequest,
8
+ summaryLines,
9
+ takeBooleanOption,
10
+ takeFlag,
11
+ takeIntegerOption,
12
+ takeOption,
13
+ type RuntimeApiDeps,
14
+ } from "./runtime-api";
15
+
16
+ const USAGE = `Usage:
17
+ rmx agent [status] [--json]
18
+ rmx agent injection <status|set> [--model <id|->] [--effort <level|->]
19
+ [--prompt <text|->] [--guidance <on|off>] [--json]
20
+ rmx agent effort <status|set> [--main <level|->] [--subagent <level|->] [--json]
21
+ rmx agent subagents <status|set|clear> [model,model...] [--json]
22
+ rmx agent fallback <status|set|clear> [model,model...] [--poll-ms <5000-600000>] [--json]
23
+ rmx agent sidecar <status|web|vision> [--model <id|->] [--backend <openai|anthropic|->]
24
+ [--reasoning <level>] [--max-descriptions <n>] [--json]`;
25
+
26
+ function clearable(value: string | undefined): string | null | undefined {
27
+ return value === "-" ? null : value;
28
+ }
29
+
30
+ async function status(argv: string[], deps: RuntimeApiDeps): Promise<void> {
31
+ const args = [...argv];
32
+ const wantsJson = takeFlag(args, "--json");
33
+ rejectArgs(args, USAGE);
34
+ const [v2, injection, caps, subagents, fallback, sidecars] = await Promise.all([
35
+ runtimeRequest("/api/v2", {}, deps),
36
+ runtimeRequest("/api/injection-model", {}, deps),
37
+ runtimeRequest("/api/effort-caps", {}, deps),
38
+ runtimeRequest("/api/subagent-models", {}, deps),
39
+ runtimeRequest("/api/subagent-model-fallback", {}, deps),
40
+ runtimeRequest("/api/sidecar-settings", {}, deps),
41
+ ]);
42
+ const result = { v2, injection, caps, subagents, fallback, sidecars };
43
+ printData(result, wantsJson, summaryLines(result));
44
+ }
45
+
46
+ async function injection(argv: string[], deps: RuntimeApiDeps): Promise<void> {
47
+ const args = [...argv];
48
+ const action = (args.shift() ?? "status").toLowerCase();
49
+ const wantsJson = takeFlag(args, "--json");
50
+ if (action === "status") {
51
+ rejectArgs(args, USAGE);
52
+ const result = await runtimeRequest("/api/injection-model", {}, deps);
53
+ printData(result, wantsJson, summaryLines(result));
54
+ return;
55
+ }
56
+ if (action !== "set") throw new CliUsageError(`unknown injection action ${action}`, USAGE);
57
+ const model = clearable(takeOption(args, "--model"));
58
+ const effort = clearable(takeOption(args, "--effort"));
59
+ const prompt = clearable(takeOption(args, "--prompt"));
60
+ const guidance = takeBooleanOption(args, "--guidance");
61
+ rejectArgs(args, USAGE);
62
+ const body: Record<string, unknown> = {};
63
+ if (model !== undefined) body.model = model;
64
+ if (effort !== undefined) body.effort = effort;
65
+ if (prompt !== undefined) body.prompt = prompt;
66
+ if (guidance !== undefined) body.multiAgentGuidanceEnabled = guidance;
67
+ if (Object.keys(body).length === 0) throw new CliUsageError("at least one injection option is required", USAGE);
68
+ const result = await runtimeRequest("/api/injection-model", { method: "PUT", body: JSON.stringify(body) }, deps);
69
+ printData(result, wantsJson, ["Agent injection settings updated."]);
70
+ }
71
+
72
+ async function effort(argv: string[], deps: RuntimeApiDeps): Promise<void> {
73
+ const args = [...argv];
74
+ const action = (args.shift() ?? "status").toLowerCase();
75
+ const wantsJson = takeFlag(args, "--json");
76
+ if (action === "status") {
77
+ rejectArgs(args, USAGE);
78
+ const result = await runtimeRequest("/api/effort-caps", {}, deps);
79
+ printData(result, wantsJson, summaryLines(result));
80
+ return;
81
+ }
82
+ if (action !== "set") throw new CliUsageError(`unknown effort action ${action}`, USAGE);
83
+ const main = clearable(takeOption(args, "--main"));
84
+ const subagent = clearable(takeOption(args, "--subagent"));
85
+ rejectArgs(args, USAGE);
86
+ const body: Record<string, unknown> = {};
87
+ if (main !== undefined) body.effortCap = main;
88
+ if (subagent !== undefined) body.subagentEffortCap = subagent;
89
+ if (Object.keys(body).length === 0) throw new CliUsageError("--main and/or --subagent is required", USAGE);
90
+ const result = await runtimeRequest("/api/effort-caps", { method: "PUT", body: JSON.stringify(body) }, deps);
91
+ printData(result, wantsJson, ["Agent effort caps updated."]);
92
+ }
93
+
94
+ async function subagents(argv: string[], deps: RuntimeApiDeps): Promise<void> {
95
+ const args = [...argv];
96
+ const action = (args.shift() ?? "status").toLowerCase();
97
+ const wantsJson = takeFlag(args, "--json");
98
+ if (action === "status") {
99
+ rejectArgs(args, USAGE);
100
+ const result = await runtimeRequest("/api/subagent-models", {}, deps);
101
+ printData(result, wantsJson, summaryLines(result));
102
+ return;
103
+ }
104
+ let models: string[];
105
+ if (action === "clear") models = [];
106
+ else if (action === "set") {
107
+ const raw = args.shift();
108
+ if (!raw) throw new CliUsageError("comma-separated subagent models are required", USAGE);
109
+ models = csv(raw) ?? [];
110
+ } else throw new CliUsageError(`unknown subagents action ${action}`, USAGE);
111
+ rejectArgs(args, USAGE);
112
+ if (models.length > 5) throw new CliUsageError("at most 5 subagent models are allowed", USAGE);
113
+ const result = await runtimeRequest("/api/subagent-models", { method: "PUT", body: JSON.stringify({ models }) }, deps);
114
+ printData(result, wantsJson, [`Subagent roster: ${models.join(", ") || "cleared"}`]);
115
+ }
116
+
117
+ async function fallback(argv: string[], deps: RuntimeApiDeps): Promise<void> {
118
+ const args = [...argv];
119
+ const action = (args.shift() ?? "status").toLowerCase();
120
+ const wantsJson = takeFlag(args, "--json");
121
+ if (action === "status") {
122
+ rejectArgs(args, USAGE);
123
+ const result = await runtimeRequest("/api/subagent-model-fallback", {}, deps);
124
+ printData(result, wantsJson, summaryLines(result));
125
+ return;
126
+ }
127
+ const body: Record<string, unknown> = {};
128
+ if (action === "clear") body.models = [];
129
+ else if (action === "set") {
130
+ const raw = args[0] && !args[0].startsWith("--") ? args.shift() : undefined;
131
+ if (raw) body.models = csv(raw) ?? [];
132
+ } else throw new CliUsageError(`unknown fallback action ${action}`, USAGE);
133
+ const pollMs = takeIntegerOption(args, "--poll-ms", { min: 5_000 });
134
+ if (pollMs !== undefined) {
135
+ if (pollMs > 600_000) throw new CliUsageError("--poll-ms must be <= 600000", USAGE);
136
+ body.pollMs = pollMs;
137
+ }
138
+ rejectArgs(args, USAGE);
139
+ if (Object.keys(body).length === 0) throw new CliUsageError("models and/or --poll-ms is required", USAGE);
140
+ const result = await runtimeRequest("/api/subagent-model-fallback", { method: "PUT", body: JSON.stringify(body) }, deps);
141
+ printData(result, wantsJson, ["Subagent fallback settings updated."]);
142
+ }
143
+
144
+ async function sidecar(argv: string[], deps: RuntimeApiDeps): Promise<void> {
145
+ const args = [...argv];
146
+ const section = (args.shift() ?? "status").toLowerCase();
147
+ const wantsJson = takeFlag(args, "--json");
148
+ if (section === "status") {
149
+ rejectArgs(args, USAGE);
150
+ const result = await runtimeRequest("/api/sidecar-settings", {}, deps);
151
+ printData(result, wantsJson, summaryLines(result));
152
+ return;
153
+ }
154
+ if (section !== "web" && section !== "vision") throw new CliUsageError("sidecar must be web, vision, or status", USAGE);
155
+ const model = takeOption(args, "--model");
156
+ const backend = takeOption(args, "--backend");
157
+ const reasoning = takeOption(args, "--reasoning");
158
+ const maxDescriptionsPerTurn = takeIntegerOption(args, "--max-descriptions", { min: 1 });
159
+ rejectArgs(args, USAGE);
160
+ const settings: Record<string, unknown> = {};
161
+ if (model !== undefined) settings.model = model === "-" ? "" : model;
162
+ if (backend !== undefined) settings.backend = backend === "-" ? null : backend;
163
+ if (reasoning !== undefined) settings.reasoning = reasoning;
164
+ if (maxDescriptionsPerTurn !== undefined) settings.maxDescriptionsPerTurn = maxDescriptionsPerTurn;
165
+ if (Object.keys(settings).length === 0) throw new CliUsageError("at least one sidecar option is required", USAGE);
166
+ const body = section === "web" ? { webSearch: settings } : { vision: settings };
167
+ const result = await runtimeRequest("/api/sidecar-settings", { method: "PUT", body: JSON.stringify(body) }, deps);
168
+ printData(result, wantsJson, [`${section} sidecar settings updated.`]);
169
+ }
170
+
171
+ export async function handleAgentCommand(argv: string[], deps: RuntimeApiDeps = {}): Promise<number> {
172
+ return runCliAction(async () => {
173
+ const [sub = "status", ...rest] = argv;
174
+ if (sub === "status") await status(rest, deps);
175
+ else if (sub === "injection" || sub === "guidance") await injection(rest, deps);
176
+ else if (sub === "effort") await effort(rest, deps);
177
+ else if (sub === "subagents" || sub === "roster") await subagents(rest, deps);
178
+ else if (sub === "fallback") await fallback(rest, deps);
179
+ else if (sub === "sidecar") await sidecar(rest, deps);
180
+ else throw new CliUsageError(`unknown agent command ${sub}`, USAGE);
181
+ });
182
+ }
183
+
184
+ export const AGENT_USAGE = USAGE;
@@ -0,0 +1,27 @@
1
+ import type { OcxConfig } from "../types";
2
+
3
+ type GatherRoutedModels = (config: OcxConfig) => Promise<unknown>;
4
+
5
+ export type CatalogPrewarmDeps = {
6
+ loadConfig?: () => OcxConfig;
7
+ importCatalog?: () => Promise<{ gatherRoutedModels: GatherRoutedModels }>;
8
+ };
9
+
10
+ /**
11
+ * After the listen port is bound, kick off live provider discovery so the first
12
+ * GUI /v1/models and syncModelsToCodex share one gather flight instead of racing
13
+ * duplicate upstream /models fetches.
14
+ */
15
+ export function scheduleCatalogPrewarm(deps: CatalogPrewarmDeps = {}): void {
16
+ void Promise.resolve()
17
+ .then(async () => {
18
+ const load = deps.loadConfig ?? (await import("../config")).loadConfig;
19
+ const { gatherRoutedModels } = await (deps.importCatalog?.() ?? import("../codex/catalog"));
20
+ return gatherRoutedModels(load());
21
+ })
22
+ .catch(error => {
23
+ if (error && typeof error === "object" && (error as { code?: unknown }).code === "catalog_busy") {
24
+ console.warn("[catalog] startup discovery skipped: catalog gather is busy");
25
+ }
26
+ });
27
+ }
@@ -0,0 +1,211 @@
1
+ import { readFileSync, writeFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { loadConfig, saveConfigPreservingClaudeCode } from "../config";
4
+ import { setIntegrationEnabled } from "../codex/desired-state";
5
+ import {
6
+ DESKTOP_FAMILIES,
7
+ moveDesktopRoute,
8
+ parseDesktopProfile,
9
+ setDesktopFamilyDefault,
10
+ type DesktopFamily,
11
+ type DesktopProfile,
12
+ } from "../claude/desktop-profile";
13
+ import { writeDesktop3pConfig, type Desktop3pConfigMode, parseDesktop3pModeArgs } from "../claude/desktop-3p";
14
+ import { filterCatalogVisibleModels, desktopVisibleNativeSlugs } from "../codex/catalog";
15
+ import { buildClaudeDesktopState, fetchAllModels } from "../server/management-api";
16
+ import { findLiveProxy } from "../server/proxy-liveness";
17
+ import { runtimeRequest } from "./runtime-api";
18
+
19
+ function isFamily(value: string | undefined): value is DesktopFamily {
20
+ return !!value && (DESKTOP_FAMILIES as readonly string[]).includes(value);
21
+ }
22
+
23
+ function printDesktopHelp(): void {
24
+ console.log(`Usage:
25
+ rmx claude desktop [apply] [--static|--hybrid|--discovery-only]
26
+ rmx claude desktop show [--json]
27
+ rmx claude desktop move <provider/model> <opus|fable|sonnet|haiku> [--default]
28
+ rmx claude desktop default <family> <provider/model|none>
29
+ rmx claude desktop export <path|->
30
+ rmx claude desktop import <path> [--apply]`);
31
+ }
32
+
33
+ export interface ApplyProfileDeps {
34
+ findLiveProxyImpl?: typeof findLiveProxy;
35
+ postApplyImpl?: (
36
+ mode: Desktop3pConfigMode,
37
+ profile: DesktopProfile,
38
+ ) => Promise<{ ok?: boolean; path?: string; error?: string }>;
39
+ }
40
+
41
+ export async function applyProfile(
42
+ profile: DesktopProfile,
43
+ mode: Desktop3pConfigMode,
44
+ deps: ApplyProfileDeps = {},
45
+ ): Promise<{ ok: boolean; path: string; reason?: string; warning?: string }> {
46
+ // Explicit apply is an enable action. Persist intent before any Desktop write
47
+ // so a process crash cannot leave a gateway profile that startup immediately removes.
48
+ const desired = setIntegrationEnabled("claude-desktop", true);
49
+ if (!desired.ok) return { ok: false, path: "", reason: desired.message };
50
+ const config = loadConfig();
51
+ const state = await buildClaudeDesktopState(config, profile);
52
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: state.profile };
53
+ saveConfigPreservingClaudeCode(config);
54
+ const live = await (deps.findLiveProxyImpl ?? findLiveProxy)();
55
+ if (live) {
56
+ // #859: the Desktop alias reverse-map is process-local. Applying through the
57
+ // serving process installs the map there; a local-only write leaves the
58
+ // daemon unable to decode aliases, and the provider rejects them (400).
59
+ const post = deps.postApplyImpl ?? (async (m: Desktop3pConfigMode, p: DesktopProfile) =>
60
+ runtimeRequest<{ ok?: boolean; path?: string; error?: string; saved?: boolean; warning?: string }>(
61
+ "/api/claude-desktop/apply",
62
+ // The daemon's config may be older than what we just saved, so the
63
+ // profile travels with the request instead of being re-read there.
64
+ { method: "POST", body: JSON.stringify({ mode: m, profile: p }) },
65
+ ));
66
+ try {
67
+ const applied = await post(mode, state.profile);
68
+ if (applied.ok === false) return { ok: false, path: applied.path ?? "", reason: applied.error ?? "daemon apply failed" };
69
+ // Partial success: Desktop was written but the applied marker was not
70
+ // persisted. Pass the degradation up instead of reporting a clean apply.
71
+ const partial = (applied as { saved?: boolean; warning?: string }).saved === false;
72
+ return {
73
+ ok: true,
74
+ path: applied.path ?? "",
75
+ ...(partial ? { warning: (applied as { warning?: string }).warning ?? "applied marker was not saved" } : {}),
76
+ };
77
+ } catch (error) {
78
+ return { ok: false, path: "", reason: error instanceof Error ? error.message : String(error) };
79
+ }
80
+ }
81
+ const allModels = await fetchAllModels(config);
82
+ // The toggle can persist OFF while fetchAllModels was awaiting (same race the
83
+ // management writers fence). Re-read persisted intent immediately before the
84
+ // writer; a lost race is a discriminated skip, not a write.
85
+ const { claudeDesktopIntegrationEnabledNow } = await import("../codex/desired-state");
86
+ if (!claudeDesktopIntegrationEnabledNow()) {
87
+ return { ok: false, path: "", reason: "desired_state_changed" };
88
+ }
89
+ const routed = filterCatalogVisibleModels(allModels, config).map(model => ({
90
+ provider: model.provider,
91
+ id: model.id,
92
+ contextWindow: model.contextWindow,
93
+ }));
94
+ const result = writeDesktop3pConfig(
95
+ config.port ?? 10100,
96
+ [...desktopVisibleNativeSlugs(config)],
97
+ routed,
98
+ config.apiKeys?.[0]?.key,
99
+ mode,
100
+ state.profile,
101
+ );
102
+ return { ok: result.written, path: result.path, reason: result.reason };
103
+ }
104
+
105
+ export async function handleClaudeDesktopCommand(argv: string[], deps: ApplyProfileDeps = {}): Promise<number> {
106
+ const command = argv[0];
107
+ if (command === "help" || command === "--help" || command === "-h") {
108
+ printDesktopHelp();
109
+ return 0;
110
+ }
111
+
112
+ // Legacy mode flags remain apply aliases and are parsed before subcommands.
113
+ const legacyFlags = argv.filter(arg => ["--static", "--hybrid", "--discovery-only"].includes(arg));
114
+ const applyInvocation = argv.length === 0 || command === "apply" || legacyFlags.length > 0;
115
+ if (applyInvocation) {
116
+ const nonMode = argv.filter(arg => !["apply", "--static", "--hybrid", "--discovery-only"].includes(arg));
117
+ if (nonMode.length > 0) {
118
+ console.error(`알 수 없는 인자: ${nonMode.join(" ")}`);
119
+ return 1;
120
+ }
121
+ const parsedMode = parseDesktop3pModeArgs(legacyFlags);
122
+ if ("error" in parsedMode) { console.error(parsedMode.error); return 1; }
123
+ try {
124
+ const config = loadConfig();
125
+ const state = await buildClaudeDesktopState(config);
126
+ const result = await applyProfile(state.profile, parsedMode.mode, deps);
127
+ if (!result.ok) {
128
+ console.error(`설정 적용 실패: ${result.reason ?? "unknown error"}`);
129
+ console.error("프로필은 저장되었지만 Claude Desktop 설정 파일에는 반영되지 않았습니다. 프록시 상태를 확인한 뒤 다시 적용해 주세요.");
130
+ return 1;
131
+ }
132
+ console.log(`Claude Desktop 설정을 적용했습니다: ${result.path}`);
133
+ // The write landed; only the bookkeeping marker did not. Saying nothing
134
+ // would leave the saved-vs-applied display wrong with no explanation.
135
+ if (result.warning) console.warn(`⚠️ ${result.warning}`);
136
+ console.log("Claude Desktop을 완전히 종료한 뒤 다시 열어 주세요.");
137
+ return 0;
138
+ } catch (error) {
139
+ console.error(error instanceof Error ? error.message : String(error));
140
+ return 1;
141
+ }
142
+ }
143
+
144
+ try {
145
+ const config = loadConfig();
146
+ const state = await buildClaudeDesktopState(config);
147
+ if (command === "show") {
148
+ if (argv.length > 2 || (argv[1] && argv[1] !== "--json")) throw new Error("Usage: rmx claude desktop show [--json]");
149
+ if (argv[1] === "--json") console.log(JSON.stringify(state));
150
+ else {
151
+ for (const family of DESKTOP_FAMILIES) {
152
+ console.log(`${family.toUpperCase()}${state.profile.defaults[family] ? ` (default: ${state.profile.defaults[family]})` : ""}`);
153
+ for (const model of state.models.filter(item => item.assignment.family === family)) {
154
+ console.log(` ${model.available ? "•" : "○"} ${model.route} -> ${model.assignment.alias}${model.available ? "" : " (unavailable)"}`);
155
+ }
156
+ }
157
+ }
158
+ return 0;
159
+ }
160
+ if (command === "move") {
161
+ const [, route, familyRaw, ...flags] = argv;
162
+ if (!route || !isFamily(familyRaw) || flags.some(flag => flag !== "--default")) throw new Error("Usage: rmx claude desktop move <route> <family> [--default]");
163
+ if (!state.models.some(model => model.route === route && model.available)) throw new Error(`현재 사용할 수 없는 모델입니다: ${route}`);
164
+ const profile = moveDesktopRoute(state.profile, route, familyRaw, flags.includes("--default"));
165
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: profile };
166
+ saveConfigPreservingClaudeCode(config);
167
+ console.log(`${route} 모델을 ${familyRaw} 그룹으로 옮겼습니다.`);
168
+ return 0;
169
+ }
170
+ if (command === "default") {
171
+ const [, familyRaw, routeRaw] = argv;
172
+ if (!isFamily(familyRaw) || !routeRaw || argv.length !== 3) throw new Error("Usage: rmx claude desktop default <family> <route|none>");
173
+ const route = routeRaw === "none" ? null : routeRaw;
174
+ if (route && !state.models.some(model => model.route === route && model.available)) throw new Error(`현재 사용할 수 없는 모델입니다: ${route}`);
175
+ const profile = setDesktopFamilyDefault(state.profile, familyRaw, route);
176
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: profile };
177
+ saveConfigPreservingClaudeCode(config);
178
+ console.log(`${familyRaw} 기본 모델을 ${route ?? "없음"}으로 지정했습니다.`);
179
+ return 0;
180
+ }
181
+ if (command === "export") {
182
+ const target = argv[1];
183
+ if (!target || argv.length !== 2) throw new Error("Usage: rmx claude desktop export <path|->");
184
+ const json = JSON.stringify(state.profile, null, 2) + "\n";
185
+ if (target === "-") process.stdout.write(json);
186
+ else writeFileSync(resolve(target), json, { encoding: "utf8", mode: 0o600 });
187
+ return 0;
188
+ }
189
+ if (command === "import") {
190
+ const source = argv[1];
191
+ const flags = argv.slice(2);
192
+ if (!source || flags.some(flag => flag !== "--apply")) throw new Error("Usage: rmx claude desktop import <path> [--apply]");
193
+ const profile = parseDesktopProfile(JSON.parse(readFileSync(resolve(source), "utf8")));
194
+ const reconciled = (await buildClaudeDesktopState(config, profile)).profile;
195
+ config.claudeCode = { ...(config.claudeCode ?? {}), desktopProfile: reconciled };
196
+ saveConfigPreservingClaudeCode(config);
197
+ if (flags.includes("--apply")) {
198
+ const result = await applyProfile(reconciled, "static", deps);
199
+ if (!result.ok) { console.error(`프로필은 저장했지만 Desktop 적용에 실패했습니다: ${result.reason ?? "unknown error"}`); return 1; }
200
+ if (result.warning) console.warn(`⚠️ ${result.warning}`);
201
+ }
202
+ console.log("Claude Desktop 프로필을 가져왔습니다.");
203
+ return 0;
204
+ }
205
+ printDesktopHelp();
206
+ return 1;
207
+ } catch (error) {
208
+ console.error(error instanceof Error ? error.message : String(error));
209
+ return 1;
210
+ }
211
+ }