@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,179 @@
1
+ import {
2
+ CliUsageError,
3
+ csv,
4
+ printData,
5
+ rejectArgs,
6
+ runCliAction,
7
+ runtimeRequest,
8
+ summaryLines,
9
+ takeBooleanOption,
10
+ takeFlag,
11
+ takeOption,
12
+ type RuntimeApiDeps,
13
+ } from "./runtime-api";
14
+
15
+ const USAGE = `Usage:
16
+ rmx provider edit <name> [--adapter <id>] [--base-url <url>] [--default-model <id|->]
17
+ [--auth-mode <key|forward|oauth|local|->] [--note <text|->]
18
+ [--api-key-transport <x-api-key|bearer|->]
19
+ [--headers <json>] [--enabled <on|off>] [--live-models <on|off>]
20
+ [--allow-private-network <on|off>] [--json]
21
+ rmx provider test <name> [--json]
22
+ rmx provider quota [--refresh] [--json]
23
+ rmx provider presets [--json]
24
+ rmx provider account-mode <pool|direct> [--json]
25
+ rmx provider selected <name> [--set <model,model...>] [--clear] [--json]`;
26
+
27
+ function cleared(value: string | undefined): string | undefined {
28
+ return value === "-" ? "" : value;
29
+ }
30
+
31
+ async function edit(argv: string[], deps: RuntimeApiDeps): Promise<void> {
32
+ const args = [...argv];
33
+ const name = args.shift()?.trim();
34
+ if (!name) throw new CliUsageError("provider name is required", USAGE);
35
+ const wantsJson = takeFlag(args, "--json");
36
+ const patch: Record<string, unknown> = {};
37
+ const adapter = takeOption(args, "--adapter");
38
+ const baseUrl = takeOption(args, "--base-url");
39
+ const defaultModel = cleared(takeOption(args, "--default-model"));
40
+ const authMode = cleared(takeOption(args, "--auth-mode"));
41
+ const note = cleared(takeOption(args, "--note"));
42
+ const apiKeyTransport = cleared(takeOption(args, "--api-key-transport"));
43
+ const headers = takeOption(args, "--headers");
44
+ const enabled = takeBooleanOption(args, "--enabled");
45
+ const liveModels = takeBooleanOption(args, "--live-models");
46
+ const allowPrivateNetwork = takeBooleanOption(args, "--allow-private-network");
47
+ rejectArgs(args, USAGE);
48
+ if (adapter !== undefined) patch.adapter = adapter;
49
+ if (baseUrl !== undefined) patch.baseUrl = baseUrl;
50
+ if (defaultModel !== undefined) patch.defaultModel = defaultModel;
51
+ if (authMode !== undefined) patch.authMode = authMode;
52
+ if (note !== undefined) patch.note = note;
53
+ if (apiKeyTransport !== undefined) patch.apiKeyTransport = apiKeyTransport;
54
+ if (headers !== undefined) {
55
+ if (headers === "-") {
56
+ patch.headers = null;
57
+ } else {
58
+ let parsed: unknown;
59
+ try { parsed = JSON.parse(headers); } catch { throw new CliUsageError("--headers must be valid JSON"); }
60
+ if (parsed === null) {
61
+ patch.headers = null;
62
+ } else if (typeof parsed !== "object" || Array.isArray(parsed)) {
63
+ throw new CliUsageError("--headers must be a JSON object like {\"X-Custom\":\"value\"}");
64
+ } else {
65
+ patch.headers = parsed;
66
+ }
67
+ }
68
+ }
69
+ if (enabled !== undefined) patch.disabled = !enabled;
70
+ if (liveModels !== undefined) patch.liveModels = liveModels;
71
+ if (allowPrivateNetwork !== undefined) patch.allowPrivateNetwork = allowPrivateNetwork;
72
+ if (Object.keys(patch).length === 0) throw new CliUsageError("at least one edit option is required", USAGE);
73
+ const result = await runtimeRequest(`/api/providers?name=${encodeURIComponent(name)}`, {
74
+ method: "PATCH",
75
+ body: JSON.stringify(patch),
76
+ }, deps);
77
+ printData(result, wantsJson, [`Updated provider ${name}.`]);
78
+ }
79
+
80
+ async function testProvider(argv: string[], deps: RuntimeApiDeps): Promise<void> {
81
+ const args = [...argv];
82
+ const name = args.shift()?.trim();
83
+ const wantsJson = takeFlag(args, "--json");
84
+ if (!name) throw new CliUsageError("provider name is required", USAGE);
85
+ rejectArgs(args, USAGE);
86
+ const result = await runtimeRequest<Record<string, unknown>>(`/api/providers/test?name=${encodeURIComponent(name)}`, {
87
+ method: "POST",
88
+ }, deps);
89
+ if (result.applicable === false) {
90
+ printData(result, wantsJson, [
91
+ `${name}: not applicable`,
92
+ "Static catalog; no live model-discovery endpoint to test.",
93
+ ]);
94
+ return;
95
+ }
96
+ const ok = result.ok === true;
97
+ printData(result, wantsJson, [
98
+ `${name}: ${ok ? "connected" : "failed"}`,
99
+ String(result.message ?? result.error ?? "No detail"),
100
+ `Latency: ${String(result.latencyMs ?? "?")} ms`,
101
+ ]);
102
+ if (!ok) process.exitCode = 1;
103
+ }
104
+
105
+ async function quota(argv: string[], deps: RuntimeApiDeps): Promise<void> {
106
+ const args = [...argv];
107
+ const wantsJson = takeFlag(args, "--json");
108
+ const refresh = takeFlag(args, "--refresh");
109
+ rejectArgs(args, USAGE);
110
+ const result = await runtimeRequest(`/api/provider-quotas${refresh ? "?refresh=1" : ""}`, {}, deps);
111
+ printData(result, wantsJson, summaryLines(result));
112
+ }
113
+
114
+ async function presets(argv: string[], deps: RuntimeApiDeps): Promise<void> {
115
+ const args = [...argv];
116
+ const wantsJson = takeFlag(args, "--json");
117
+ rejectArgs(args, USAGE);
118
+ const result = await runtimeRequest<{ providers?: unknown[] } | unknown[]>("/api/provider-presets", {}, deps);
119
+ const rows = Array.isArray(result) ? result : result.providers ?? [];
120
+ printData(result, wantsJson, rows.map(row => {
121
+ const record = row as Record<string, unknown>;
122
+ return `${String(record.id ?? record.name ?? "?")} ${String(record.label ?? record.adapter ?? "")}`.trimEnd();
123
+ }));
124
+ }
125
+
126
+ async function accountMode(argv: string[], deps: RuntimeApiDeps): Promise<void> {
127
+ const args = [...argv];
128
+ const mode = args.shift();
129
+ const wantsJson = takeFlag(args, "--json");
130
+ if (mode !== "pool" && mode !== "direct") throw new CliUsageError("mode must be pool or direct", USAGE);
131
+ rejectArgs(args, USAGE);
132
+ const result = await runtimeRequest("/api/providers?name=openai", {
133
+ method: "PATCH",
134
+ body: JSON.stringify({ codexAccountMode: mode }),
135
+ }, deps);
136
+ printData(result, wantsJson, [`OpenAI Codex account mode: ${mode}`]);
137
+ }
138
+
139
+ async function selected(argv: string[], deps: RuntimeApiDeps): Promise<void> {
140
+ const args = [...argv];
141
+ const name = args.shift()?.trim();
142
+ const wantsJson = takeFlag(args, "--json");
143
+ const set = csv(takeOption(args, "--set"));
144
+ const clear = takeFlag(args, "--clear");
145
+ if (!name) throw new CliUsageError("provider name is required", USAGE);
146
+ if (set !== undefined && clear) throw new CliUsageError("--set and --clear cannot be combined", USAGE);
147
+ rejectArgs(args, USAGE);
148
+ if (set === undefined && !clear) {
149
+ const result = await runtimeRequest<Record<string, unknown>>("/api/selected-models", {}, deps);
150
+ const selectedMap = (result.selected ?? {}) as Record<string, string[]>;
151
+ const availableMap = (result.available ?? {}) as Record<string, string[]>;
152
+ printData({ provider: name, selected: selectedMap[name] ?? [], available: availableMap[name] ?? [] }, wantsJson,
153
+ [`Selected models for ${name}: ${(selectedMap[name] ?? []).join(", ") || "all"}`]);
154
+ return;
155
+ }
156
+ const models = clear ? [] : (set ?? []);
157
+ const result = await runtimeRequest("/api/selected-models", {
158
+ method: "PUT",
159
+ body: JSON.stringify({ provider: name, models }),
160
+ }, deps);
161
+ printData(result, wantsJson, [`${name}: ${models.length ? models.join(", ") : "all models"}`]);
162
+ }
163
+
164
+ export async function handleProviderRuntimeCommand(sub: string, argv: string[], deps: RuntimeApiDeps = {}): Promise<number | null> {
165
+ const handlers: Record<string, (args: string[], deps: RuntimeApiDeps) => Promise<void>> = {
166
+ edit,
167
+ update: edit,
168
+ test: testProvider,
169
+ quota,
170
+ presets,
171
+ "account-mode": accountMode,
172
+ selected,
173
+ };
174
+ const handler = handlers[sub];
175
+ if (!handler) return null;
176
+ return runCliAction(() => handler(argv, deps));
177
+ }
178
+
179
+ export const PROVIDER_RUNTIME_USAGE = USAGE;
@@ -0,0 +1,476 @@
1
+ /**
2
+ * `rmx provider` subcommand — non-interactive provider management.
3
+ *
4
+ * Subcommands:
5
+ * list List configured and available registry providers
6
+ * add <name> Add a provider from the registry or with custom flags
7
+ * remove <name> Remove a configured provider
8
+ * show <name> Show provider config details (secrets masked)
9
+ * set-default <name> Change the default provider
10
+ */
11
+ import { apiKeyTransportConfigError, hasOwnProvider, isValidProviderName, loadConfig, saveConfig } from "../config";
12
+ import { hasHelpFlag } from "./help";
13
+ import { getProviderRegistryEntry, PROVIDER_REGISTRY } from "../providers/registry";
14
+ import { providerConfigSeed } from "../providers/derive";
15
+ import { dropProviderCustomModels } from "../providers/provider-id-rewrite";
16
+ import type { OcxProviderConfig } from "../types";
17
+ import { findLiveProxy } from "../server/proxy-liveness";
18
+ import { syncModelsToCodex } from "../codex/sync";
19
+ import { codexAccountNamespaceProviderCollisionError } from "../codex/account-namespace-match";
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Arg helpers
23
+ // ---------------------------------------------------------------------------
24
+
25
+ function consumeFlag(args: string[], flag: string): boolean {
26
+ const idx = args.indexOf(flag);
27
+ if (idx === -1) return false;
28
+ args.splice(idx, 1);
29
+ return true;
30
+ }
31
+
32
+ function consumeFlagValue(args: string[], flag: string): string | undefined {
33
+ const idx = args.indexOf(flag);
34
+ if (idx === -1 || idx + 1 >= args.length) return undefined;
35
+ const value = args[idx + 1];
36
+ args.splice(idx, 2);
37
+ return value;
38
+ }
39
+
40
+ /** Reject any leftover args (unknown flags or trailing values). */
41
+ function rejectUnknownArgs(args: string[], usage: string): void {
42
+ if (args.length === 0) return;
43
+ const unknown = args.filter(a => a.startsWith("-"));
44
+ if (unknown.length > 0) {
45
+ console.error(`Unknown flag(s): ${unknown.join(", ")}`);
46
+ } else {
47
+ console.error(`Unexpected argument(s): ${args.join(", ")}`);
48
+ }
49
+ console.error(usage);
50
+ process.exit(1);
51
+ }
52
+
53
+ function maskSecret(value: string): string {
54
+ if (value.length <= 8) return "****";
55
+ return `${value.slice(0, 4)}****${value.slice(-4)}`;
56
+ }
57
+
58
+ // ---------------------------------------------------------------------------
59
+ // Validation helper (F1 fix: validate before saveConfig)
60
+ // ---------------------------------------------------------------------------
61
+
62
+ function validateAndSave(config: ReturnType<typeof loadConfig>): void {
63
+ if (!config.providers || Object.keys(config.providers).length === 0) {
64
+ console.error("Error: config would have no providers. Aborting.");
65
+ process.exit(1);
66
+ }
67
+ if (!hasOwnProvider(config.providers, config.defaultProvider)) {
68
+ console.error(`Error: defaultProvider "${config.defaultProvider}" does not exist in providers. Aborting.`);
69
+ process.exit(1);
70
+ }
71
+ saveConfig(config);
72
+ }
73
+
74
+ // ---------------------------------------------------------------------------
75
+ // provider list
76
+ // ---------------------------------------------------------------------------
77
+
78
+ function handleList(args: string[]): void {
79
+ const wantsJson = consumeFlag(args, "--json");
80
+ rejectUnknownArgs(args, "Usage: rmx provider list [--json]");
81
+
82
+ const config = loadConfig();
83
+ const configured = Object.keys(config.providers);
84
+
85
+ if (wantsJson) {
86
+ const entries = configured.map(name => {
87
+ const prov = config.providers[name];
88
+ const registryEntry = getProviderRegistryEntry(name);
89
+ return {
90
+ name,
91
+ adapter: prov.adapter,
92
+ baseUrl: prov.baseUrl,
93
+ authMode: prov.authMode ?? "key",
94
+ defaultModel: prov.defaultModel ?? null,
95
+ isDefault: name === config.defaultProvider,
96
+ source: registryEntry ? "registry" : "custom",
97
+ models: prov.models ?? [],
98
+ };
99
+ });
100
+ console.log(JSON.stringify({ configured: entries, registryCount: PROVIDER_REGISTRY.length }, null, 2));
101
+ return;
102
+ }
103
+
104
+ console.log("Configured providers:\n");
105
+ for (const name of configured) {
106
+ const prov = config.providers[name];
107
+ const isDefault = name === config.defaultProvider ? " (default)" : "";
108
+ const registryEntry = getProviderRegistryEntry(name);
109
+ const source = registryEntry ? "" : " [custom]";
110
+ const model = prov.defaultModel ? ` model=${prov.defaultModel}` : "";
111
+ console.log(` ${name}${isDefault}${source} adapter=${prov.adapter}${model}`);
112
+ }
113
+
114
+ const available = PROVIDER_REGISTRY.filter(e => !configured.includes(e.id));
115
+ if (available.length > 0) {
116
+ console.log(`\nAvailable from registry (${available.length}):\n`);
117
+ for (const entry of available) {
118
+ const auth = entry.authKind === "forward" ? "chatgpt-login" : entry.authKind;
119
+ console.log(` ${entry.id.padEnd(24)} ${entry.label} (${auth})`);
120
+ }
121
+ console.log(`\nAdd with: rmx provider add <name> [--api-key <key>]`);
122
+ }
123
+ }
124
+
125
+ // ---------------------------------------------------------------------------
126
+ // provider add
127
+ // ---------------------------------------------------------------------------
128
+
129
+ const ADD_USAGE = "Usage: rmx provider add <name> [--adapter <adapter>] [--base-url <url>] [--api-key <key>] [--api-key-transport <x-api-key|bearer>] [--default-model <model>] [--allow-private-network] [--set-default] [--force] [--json] [--sync]";
130
+
131
+ async function handleAdd(args: string[]): Promise<void> {
132
+ const name = args[0];
133
+ if (!name || name.startsWith("-")) {
134
+ console.error(ADD_USAGE);
135
+ process.exit(1);
136
+ }
137
+
138
+ if (!isValidProviderName(name)) {
139
+ console.error(`Invalid provider name: "${name}". Use letters, numbers, dots, underscores, or hyphens.`);
140
+ process.exit(1);
141
+ }
142
+
143
+ const restArgs = args.slice(1);
144
+ const force = consumeFlag(restArgs, "--force");
145
+ const setDefault = consumeFlag(restArgs, "--set-default");
146
+ const wantsJson = consumeFlag(restArgs, "--json");
147
+ const wantsSync = consumeFlag(restArgs, "--sync");
148
+ const allowPrivateNetwork = consumeFlag(restArgs, "--allow-private-network");
149
+ const apiKey = consumeFlagValue(restArgs, "--api-key");
150
+ const apiKeyTransport = consumeFlagValue(restArgs, "--api-key-transport");
151
+ const adapter = consumeFlagValue(restArgs, "--adapter");
152
+ const baseUrl = consumeFlagValue(restArgs, "--base-url");
153
+ const defaultModel = consumeFlagValue(restArgs, "--default-model");
154
+ rejectUnknownArgs(restArgs, ADD_USAGE);
155
+
156
+ const config = loadConfig();
157
+
158
+ const namespaceCollision = codexAccountNamespaceProviderCollisionError(config.codexAccountNamespaces, name);
159
+ if (namespaceCollision) {
160
+ console.error(`Error: ${namespaceCollision}.`);
161
+ process.exit(1);
162
+ }
163
+
164
+ if (hasOwnProvider(config.providers, name) && !force) {
165
+ console.error(`Provider "${name}" already exists. Use --force to overwrite.`);
166
+ process.exit(1);
167
+ }
168
+
169
+ let provConfig: OcxProviderConfig;
170
+ const registryEntry = getProviderRegistryEntry(name);
171
+
172
+ if (registryEntry) {
173
+ provConfig = providerConfigSeed(registryEntry);
174
+ if (apiKey) {
175
+ if (registryEntry.authKind === "forward") {
176
+ console.warn(`Warning: provider "${name}" uses ChatGPT login (forward auth); --api-key is ignored.`);
177
+ } else if (registryEntry.authKind === "oauth") {
178
+ console.warn(`Warning: provider "${name}" uses OAuth auth; --api-key is ignored. Run: rmx login ${name}`);
179
+ } else {
180
+ provConfig.apiKey = apiKey;
181
+ }
182
+ }
183
+ if (defaultModel) provConfig.defaultModel = defaultModel;
184
+ if (adapter) provConfig.adapter = adapter;
185
+ if (baseUrl) provConfig.baseUrl = baseUrl;
186
+ } else {
187
+ if (!adapter || !baseUrl) {
188
+ console.error(`Provider "${name}" is not in the registry. --adapter and --base-url are required.`);
189
+ console.error("Usage: rmx provider add <name> --adapter <adapter> --base-url <url> [--api-key <key>]");
190
+ process.exit(1);
191
+ }
192
+ provConfig = {
193
+ adapter,
194
+ baseUrl,
195
+ ...(apiKey ? { apiKey } : {}),
196
+ ...(defaultModel ? { defaultModel } : {}),
197
+ };
198
+ }
199
+
200
+ if (apiKeyTransport !== undefined) {
201
+ if (apiKeyTransport !== "x-api-key" && apiKeyTransport !== "bearer") {
202
+ console.error('Error: --api-key-transport must be "x-api-key" or "bearer".');
203
+ process.exit(1);
204
+ }
205
+ const transportError = apiKeyTransportConfigError({ ...provConfig, apiKeyTransport });
206
+ if (transportError) {
207
+ console.error(`Error: ${transportError}.`);
208
+ process.exit(1);
209
+ }
210
+ provConfig.apiKeyTransport = apiKeyTransport;
211
+ }
212
+
213
+ config.providers[name] = provConfig;
214
+ if (allowPrivateNetwork) provConfig.allowPrivateNetwork = true;
215
+ if (setDefault) config.defaultProvider = name;
216
+
217
+ validateAndSave(config);
218
+
219
+ if (wantsJson) {
220
+ console.log(JSON.stringify({
221
+ action: "added",
222
+ provider: name,
223
+ adapter: provConfig.adapter,
224
+ baseUrl: provConfig.baseUrl,
225
+ defaultModel: provConfig.defaultModel ?? null,
226
+ isDefault: config.defaultProvider === name,
227
+ source: registryEntry ? "registry" : "custom",
228
+ needsSync: true,
229
+ }, null, 2));
230
+ return;
231
+ }
232
+
233
+ let codexSyncSkipped = false;
234
+ if (wantsSync) {
235
+ const live = await findLiveProxy();
236
+ if (live) {
237
+ const synced = await syncModelsToCodex(live.port).catch(e => {
238
+ console.error(`Warning: sync failed: ${e instanceof Error ? e.message : String(e)}`);
239
+ return null;
240
+ });
241
+ if (synced?.status === "skipped") {
242
+ codexSyncSkipped = true;
243
+ console.log("Provider saved; Codex integration is OFF, so Codex sync was skipped.");
244
+ }
245
+ }
246
+ }
247
+
248
+ const registryLabel = registryEntry ? ` (${registryEntry.label})` : "";
249
+ console.log(`✅ Provider "${name}"${registryLabel} added.`);
250
+ if (setDefault) console.log(` Set as default provider.`);
251
+ if (registryEntry?.authKind === "oauth") {
252
+ console.log(` Authenticate with: rmx login ${name}`);
253
+ }
254
+ if (registryEntry?.authKind === "key" && !apiKey) {
255
+ const envKey = `${name.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
256
+ console.log(` Set API key with: rmx provider add ${name} --api-key <key> --force`);
257
+ console.log(` Or set env var: ${envKey}`);
258
+ }
259
+ if (wantsSync && !codexSyncSkipped) {
260
+ console.log(` Models synced to Codex.`);
261
+ } else {
262
+ console.log(` Apply to Codex: rmx sync`);
263
+ }
264
+ }
265
+
266
+ // ---------------------------------------------------------------------------
267
+ // provider remove
268
+ // ---------------------------------------------------------------------------
269
+
270
+ function handleRemove(args: string[]): void {
271
+ const restArgs = [...args];
272
+ const wantsJson = consumeFlag(restArgs, "--json");
273
+ const name = restArgs[0];
274
+ if (!name || name.startsWith("-")) {
275
+ console.error("Usage: rmx provider remove <name> [--json]");
276
+ process.exit(1);
277
+ }
278
+ rejectUnknownArgs(restArgs.slice(1), "Usage: rmx provider remove <name> [--json]");
279
+
280
+ const config = loadConfig();
281
+ if (!hasOwnProvider(config.providers, name)) {
282
+ console.error(`Provider "${name}" is not configured.`);
283
+ process.exit(1);
284
+ }
285
+
286
+ if (name === config.defaultProvider) {
287
+ console.error(`Cannot remove "${name}" — it is the default provider. Change the default first: rmx provider set-default <other>`);
288
+ process.exit(1);
289
+ }
290
+
291
+ if (Object.keys(config.providers).length <= 1) {
292
+ console.error("Cannot remove the last provider.");
293
+ process.exit(1);
294
+ }
295
+
296
+ const dependentCombos = Object.entries(config.combos ?? {})
297
+ .filter(([, combo]) => combo.targets.some(target => target.provider === name))
298
+ .map(([id]) => id)
299
+ .sort();
300
+ if (dependentCombos.length > 0) {
301
+ console.error(`Cannot remove "${name}" — combo(s) depend on it: ${dependentCombos.join(", ")}`);
302
+ process.exit(1);
303
+ }
304
+
305
+ delete config.providers[name];
306
+ const droppedCustomModels = dropProviderCustomModels(config, name);
307
+ validateAndSave(config);
308
+
309
+
310
+ if (wantsJson) {
311
+ console.log(JSON.stringify({
312
+ action: "removed",
313
+ provider: name,
314
+ remainingProviders: Object.keys(config.providers),
315
+ defaultProvider: config.defaultProvider,
316
+ needsSync: true,
317
+ ...(droppedCustomModels > 0 ? { droppedCustomModels } : {}),
318
+ }, null, 2));
319
+ return;
320
+ }
321
+
322
+ console.log(`✅ Provider "${name}" removed.`);
323
+ if (droppedCustomModels > 0) {
324
+ const plural = droppedCustomModels === 1 ? "model" : "models";
325
+ console.log(` Also removed ${droppedCustomModels} custom ${plural} that belonged to it.`);
326
+ }
327
+ }
328
+
329
+ // ---------------------------------------------------------------------------
330
+ // provider show
331
+ // ---------------------------------------------------------------------------
332
+
333
+ function handleShow(args: string[]): void {
334
+ const restArgs = [...args];
335
+ const wantsJson = consumeFlag(restArgs, "--json");
336
+ const name = restArgs[0];
337
+ if (!name || name.startsWith("-")) {
338
+ console.error("Usage: rmx provider show <name> [--json]");
339
+ process.exit(1);
340
+ }
341
+ rejectUnknownArgs(restArgs.slice(1), "Usage: rmx provider show <name> [--json]");
342
+
343
+ const config = loadConfig();
344
+ if (!hasOwnProvider(config.providers, name)) {
345
+ console.error(`Provider "${name}" is not configured.`);
346
+ process.exit(1);
347
+ }
348
+
349
+ const prov = config.providers[name];
350
+ const display = {
351
+ ...prov,
352
+ ...(prov.apiKey ? { apiKey: maskSecret(prov.apiKey) } : {}),
353
+ ...(prov.apiKeyPool ? { apiKeyPool: prov.apiKeyPool.map(e => ({ ...e, key: maskSecret(e.key) })) } : {}),
354
+ };
355
+
356
+ if (wantsJson) {
357
+ console.log(JSON.stringify({ name, isDefault: name === config.defaultProvider, ...display }, null, 2));
358
+ return;
359
+ }
360
+
361
+ console.log(`Provider: ${name}${name === config.defaultProvider ? " (default)" : ""}`);
362
+ console.log(` adapter: ${display.adapter}`);
363
+ console.log(` baseUrl: ${display.baseUrl}`);
364
+ if (display.authMode) console.log(` authMode: ${display.authMode}`);
365
+ if (display.apiKey) console.log(` apiKey: ${display.apiKey}`);
366
+ if (display.defaultModel) console.log(` defaultModel: ${display.defaultModel}`);
367
+ if (display.models?.length) console.log(` models: ${display.models.join(", ")}`);
368
+ }
369
+
370
+ // ---------------------------------------------------------------------------
371
+ // provider set-default
372
+ // ---------------------------------------------------------------------------
373
+
374
+ function handleSetDefault(args: string[]): void {
375
+ const restArgs = [...args];
376
+ const wantsJson = consumeFlag(restArgs, "--json");
377
+ const name = restArgs[0];
378
+ if (!name || name.startsWith("-")) {
379
+ console.error("Usage: rmx provider set-default <name> [--json]");
380
+ process.exit(1);
381
+ }
382
+ rejectUnknownArgs(restArgs.slice(1), "Usage: rmx provider set-default <name> [--json]");
383
+
384
+ const config = loadConfig();
385
+ if (!hasOwnProvider(config.providers, name)) {
386
+ console.error(`Provider "${name}" is not configured. Add it first: rmx provider add ${name}`);
387
+ process.exit(1);
388
+ }
389
+
390
+ if (config.defaultProvider === name) {
391
+ if (wantsJson) {
392
+ console.log(JSON.stringify({ action: "noop", provider: name, defaultProvider: name, needsSync: false }, null, 2));
393
+ } else {
394
+ console.log(`"${name}" is already the default provider.`);
395
+ }
396
+ return;
397
+ }
398
+
399
+ config.defaultProvider = name;
400
+ validateAndSave(config);
401
+
402
+
403
+ if (wantsJson) {
404
+ console.log(JSON.stringify({ action: "set-default", provider: name, defaultProvider: name, needsSync: true }, null, 2));
405
+ return;
406
+ }
407
+
408
+ console.log(`✅ Default provider set to "${name}".`);
409
+ }
410
+
411
+ // ---------------------------------------------------------------------------
412
+ // Router (F2 fix: handle help flags internally, like service/codex-shim)
413
+ // ---------------------------------------------------------------------------
414
+
415
+ const PROVIDER_USAGE = `Usage: rmx provider <subcommand>
416
+
417
+ Subcommands:
418
+ list List configured and available providers
419
+ add <name> Add a provider (registry or custom)
420
+ edit <name> Edit live provider fields
421
+ test <name> Test the provider's upstream model endpoint
422
+ remove <name> Remove a configured provider
423
+ show <name> Show provider config details
424
+ set-default <name> Change the default provider
425
+ selected <name> Show or set the provider model allowlist
426
+ quota Show provider quota reports
427
+ presets List GUI provider presets
428
+ account-mode <mode> Set OpenAI Codex pool/direct mode
429
+
430
+ Examples:
431
+ rmx provider list
432
+ rmx provider add anthropic --api-key sk-ant-...
433
+ rmx provider add my-ollama --adapter openai-chat --base-url http://localhost:11434/v1
434
+ rmx provider show anthropic --json
435
+ rmx provider set-default anthropic
436
+ rmx provider remove my-ollama`;
437
+
438
+ export async function handleProviderCommand(args: string[]): Promise<void> {
439
+ const sub = args[0];
440
+
441
+ if (!sub || sub === "help" || hasHelpFlag(args)) {
442
+ console.log(PROVIDER_USAGE);
443
+ process.exit(0);
444
+ }
445
+
446
+ const subArgs = args.slice(1);
447
+
448
+ switch (sub) {
449
+ case "list":
450
+ handleList(subArgs);
451
+ break;
452
+ case "add":
453
+ await handleAdd(subArgs);
454
+ break;
455
+ case "remove":
456
+ handleRemove(subArgs);
457
+ break;
458
+ case "show":
459
+ handleShow(subArgs);
460
+ break;
461
+ case "set-default":
462
+ handleSetDefault(subArgs);
463
+ break;
464
+ default: {
465
+ const { handleProviderRuntimeCommand } = await import("./provider-runtime");
466
+ const code = await handleProviderRuntimeCommand(sub, subArgs);
467
+ if (code !== null) {
468
+ process.exitCode = code;
469
+ break;
470
+ }
471
+ console.error(`Unknown provider subcommand: ${sub}`);
472
+ console.error(PROVIDER_USAGE);
473
+ process.exit(1);
474
+ }
475
+ }
476
+ }