@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
package/bin/ocx.mjs ADDED
@@ -0,0 +1,584 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Remodex npm bin launcher (legacy package/command aliases remain supported).
4
+ *
5
+ * The package source is TypeScript that runs on the Bun runtime. To let
6
+ * `npm install -g @remodex/rmx` work without a separately-installed Bun,
7
+ * we bundle the runtime via the `bun` npm dependency and exec it from this
8
+ * Node shim. (Dev still runs `bun run src/cli/index.ts` directly via the shebang on
9
+ * src/cli/index.ts — only the published npm `bin` routes through here.)
10
+ */
11
+ import { spawn, spawnSync } from "node:child_process";
12
+ import { randomBytes } from "node:crypto";
13
+ import { createRequire } from "node:module";
14
+ import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
15
+ import { homedir } from "node:os";
16
+ import { dirname, join, resolve } from "node:path";
17
+ import { fileURLToPath } from "node:url";
18
+ import { isRealBunBinary } from "../src/lib/bun-binary-validator.mjs";
19
+ import { npmInvocation } from "../src/update/npm-invocation.mjs";
20
+ import {
21
+ npmCachePreflightFailureMessage,
22
+ runNpmCachePreflight,
23
+ } from "../src/update/npm-cache-preflight.mjs";
24
+ import { handoffWindowsTrayForUpdate, planWindowsTrayUpdate } from "../src/update/tray-update-plan.mjs";
25
+
26
+ const PKG = "@remodex/rmx";
27
+ const require = createRequire(import.meta.url);
28
+ const here = dirname(fileURLToPath(import.meta.url));
29
+ const cliPath = join(here, "..", "src", "cli", "index.ts");
30
+ const NODE_LAUNCH_CONTEXT_ENV = "OCX_NODE_LAUNCH_CONTEXT";
31
+ const NODE_LAUNCH_PROOF_PREFIX = "--ocx-internal-launch-proof=";
32
+
33
+ function isNodeModulesInstall() {
34
+ return here.split(/[\\/]/).includes("node_modules");
35
+ }
36
+
37
+ function isBunGlobalInstall() {
38
+ return /[\\/]\.bun[\\/]/.test(here);
39
+ }
40
+
41
+ function currentPackageVersion() {
42
+ try {
43
+ return JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8")).version ?? "?";
44
+ } catch {
45
+ return "?";
46
+ }
47
+ }
48
+
49
+ function updateTag(currentVersion) {
50
+ // Allowlist the tag: the value is argv-controlled and (on Windows) flows into a
51
+ // shell-joined spawnSync — never forward arbitrary strings.
52
+ const tagIndex = process.argv.indexOf("--tag");
53
+ const explicit = tagIndex !== -1 ? process.argv[tagIndex + 1] : undefined;
54
+ if (explicit === "preview" || explicit === "latest") return explicit;
55
+ return String(currentVersion).includes("-preview.") ? "preview" : "latest";
56
+ }
57
+
58
+ function expandUserPath(raw) {
59
+ // Mirror src/config.ts expandUserPath — the Bun proxy expands `~`, so this launcher's
60
+ // pid/state gates must resolve the same directory or they silently check the wrong path.
61
+ if (raw === "~") return homedir();
62
+ if (raw.startsWith("~/") || raw.startsWith("~\\")) return join(homedir(), raw.slice(2));
63
+ return raw;
64
+ }
65
+
66
+ function configDir() {
67
+ const raw = process.env.OPENCODEX_HOME?.trim();
68
+ if (raw) return resolve(expandUserPath(raw));
69
+
70
+ // The full Bun runtime performs the atomic legacy-directory migration. The
71
+ // Node shim runs first, though, and its update/tray gates must inspect the
72
+ // same old state while that migration is pending (for example when Windows
73
+ // still has a file open). Keep this probe intentionally conservative.
74
+ const canonical = resolve(join(homedir(), ".remodex"));
75
+ if (isRealDirectory(canonical)) return canonical;
76
+ const legacy = resolve(join(homedir(), ".opencodex"));
77
+ if (hasLegacyRemodexEvidence(legacy)) return legacy;
78
+ return canonical;
79
+ }
80
+
81
+ function isRealDirectory(path) {
82
+ try {
83
+ const stat = lstatSync(path);
84
+ return stat.isDirectory() && !stat.isSymbolicLink();
85
+ } catch {
86
+ return false;
87
+ }
88
+ }
89
+
90
+ function hasLegacyRemodexEvidence(path) {
91
+ if (!isRealDirectory(path)) return false;
92
+ let names;
93
+ try {
94
+ names = readdirSync(path);
95
+ } catch {
96
+ return false;
97
+ }
98
+ const known = new Set([
99
+ ".opencodex-owner.json",
100
+ ".opencodex-uninstall.json",
101
+ "admin-api-token",
102
+ "android-remote.json",
103
+ "catalog-backup.json",
104
+ "codex-runtime.json",
105
+ "codex-shim.json",
106
+ "desktop-runtime.log",
107
+ "desktop-update.json",
108
+ "ocx.pid",
109
+ "responses-state.json",
110
+ "runtime-port.json",
111
+ "service-api-token",
112
+ "service-provider-env.json",
113
+ "service-state.json",
114
+ "service.log",
115
+ "tray-state.json",
116
+ "usage.jsonl",
117
+ "update-job.json",
118
+ "winsw",
119
+ ]);
120
+ if (names.some(name => known.has(name))) return true;
121
+ if (!names.includes("config.json")) return false;
122
+ try {
123
+ const value = JSON.parse(readFileSync(join(path, "config.json"), "utf8"));
124
+ return value && typeof value === "object" && !Array.isArray(value)
125
+ && ["providers", "defaultProvider", "clientIntegrations", "claudeCode", "grok"]
126
+ .some(key => Object.prototype.hasOwnProperty.call(value, key));
127
+ } catch {
128
+ return false;
129
+ }
130
+ }
131
+
132
+ function shouldRepairCodexShim() {
133
+ return existsSync(join(configDir(), "codex-shim.json"));
134
+ }
135
+
136
+ function historyRestoreIncomplete() {
137
+ // Mirror src/update/index.ts historyRestoreIncomplete — a codex-history-backup-*.json surviving
138
+ // a stop means the native-history restore was skipped (locked state DB).
139
+ try {
140
+ return readdirSync(configDir()).some(
141
+ name => name.startsWith("codex-history-backup-") && name.endsWith(".json"),
142
+ );
143
+ } catch {
144
+ return false;
145
+ }
146
+ }
147
+
148
+ function repairCodexShimIfNeeded() {
149
+ if (!shouldRepairCodexShim()) return;
150
+ const launcher = fileURLToPath(import.meta.url);
151
+ const res = spawnSync(process.execPath, [launcher, "codex-shim", "install"], {
152
+ stdio: "inherit",
153
+ windowsHide: true,
154
+ });
155
+ if (res.status !== 0) {
156
+ console.warn(`Remodex: Codex shim repair failed (${res.status ?? "unknown exit"}). Try: rmx codex-shim install`);
157
+ }
158
+ }
159
+
160
+ function trayInstallState() {
161
+ const statePath = join(configDir(), "tray-state.json");
162
+ if (!existsSync(statePath)) return { installed: false, running: false };
163
+ let running = false;
164
+ try {
165
+ const heartbeat = JSON.parse(readFileSync(join(configDir(), "tray-heartbeat.json"), "utf8"));
166
+ if (Number.isSafeInteger(heartbeat.pid) && Date.now() - Number(heartbeat.timestamp) < 15_000) {
167
+ process.kill(heartbeat.pid, 0);
168
+ running = true;
169
+ }
170
+ } catch { /* installed but not running */ }
171
+ return { installed: true, running };
172
+ }
173
+
174
+ function runTrayLifecycle(launcher, action) {
175
+ return spawnSync(process.execPath, [launcher, "tray", action], {
176
+ stdio: "inherit",
177
+ windowsHide: true,
178
+ });
179
+ }
180
+
181
+ function runNpmSelfUpdate() {
182
+ const current = currentPackageVersion();
183
+ const tag = updateTag(current);
184
+ const latestInvocation = npmInvocation(["view", `${PKG}@${tag}`, "version"]);
185
+ const installInvocation = npmInvocation(["install", "-g", `${PKG}@${tag}`]);
186
+ if (!latestInvocation || !installInvocation) {
187
+ console.error("Remodex: could not resolve npm from a trusted absolute PATH entry; aborting before stopping the proxy.");
188
+ process.exit(1);
189
+ }
190
+ const latestResult = spawnSync(latestInvocation.file, latestInvocation.args, {
191
+ encoding: "utf8",
192
+ timeout: 12000,
193
+ windowsHide: true,
194
+ ...latestInvocation.options,
195
+ });
196
+ const latest = latestResult.status === 0 ? latestResult.stdout.trim() : "";
197
+
198
+ console.log(`Remodex v${current} (installed via npm, tag ${tag})`);
199
+ if (latest && latest === current) {
200
+ console.log(`Already on the latest ${tag} version (v${latest}).`);
201
+ process.exit(0);
202
+ }
203
+
204
+ const cachePreflight = runNpmCachePreflight();
205
+ if (!cachePreflight.ok) {
206
+ console.error(`Remodex: ${npmCachePreflightFailureMessage(cachePreflight.reason)}. Aborting before stopping the proxy.`);
207
+ process.exit(1);
208
+ }
209
+
210
+ // Remember whether a background service manages the proxy BEFORE stopping — `rmx stop`
211
+ // unloads it, so a successful update must refresh and restart it afterwards.
212
+ const serviceStatePath = join(configDir(), "service-state.json");
213
+ const serviceWasInstalled = existsSync(serviceStatePath);
214
+ const trayBeforeUpdate = planWindowsTrayUpdate(
215
+ process.platform === "win32" ? trayInstallState() : { installed: false, running: false },
216
+ );
217
+ /**
218
+ * Refresh the existing service without re-registering it. `service repair` discovers
219
+ * the installed backend itself and, on Windows scheduler installs, rewrites the wrapper
220
+ * assets and restarts the existing task without `schtasks /create` — the elevation a
221
+ * non-admin `rmx update` does not have.
222
+ */
223
+ function serviceRefreshArgs() {
224
+ return [launcher, "service", "repair"];
225
+ }
226
+ /** Register from scratch, preserving the recorded backend. Only for a genuinely absent service. */
227
+ function serviceInstallArgs() {
228
+ try {
229
+ const state = JSON.parse(readFileSync(serviceStatePath, "utf8"));
230
+ if (state.backend === "native") return [launcher, "service", "install", "--native"];
231
+ } catch { /* missing or corrupt — fall through to default */ }
232
+ return [launcher, "service", "install"];
233
+ }
234
+ /**
235
+ * Structured "is a service actually registered?" answer.
236
+ *
237
+ * This file is plain Node ESM and cannot import `diagnoseService()` from the
238
+ * TypeScript runtime, so it asks the freshly-installed launcher — which runs that
239
+ * diagnostic under Bun — and reads `startup.serviceInstalled`.
240
+ *
241
+ * Returns `null` when the probe itself could not answer, which callers must treat as
242
+ * "unknown" rather than "absent": failing closed here means NOT re-registering.
243
+ */
244
+ function readServiceInstalledFromStatus(launcherPath) {
245
+ try {
246
+ const st = spawnSync(process.execPath, [launcherPath, "status", "--json"], {
247
+ encoding: "utf8",
248
+ timeout: 20_000,
249
+ windowsHide: true,
250
+ });
251
+ if (st.status !== 0 || typeof st.stdout !== "string" || !st.stdout.trim()) return null;
252
+ const installed = JSON.parse(st.stdout)?.startup?.serviceInstalled;
253
+ return typeof installed === "boolean" ? installed : null;
254
+ } catch {
255
+ return null;
256
+ }
257
+ }
258
+
259
+ // Capture listen target before stop clears runtime-port.json (mirrors GUI/CLI update worker).
260
+ // Do not treat a live runtime port of 10100 as "missing" — track whether the read succeeded.
261
+ let bakePort = 10100;
262
+ let sawRuntimePort = false;
263
+ try {
264
+ const rt = JSON.parse(readFileSync(join(configDir(), "runtime-port.json"), "utf8"));
265
+ if (Number.isFinite(rt?.port) && rt.port > 0 && rt.port <= 65535) {
266
+ // Only trust runtime when its pid still looks alive (stale crash leftovers fall back to config).
267
+ const rtPid = Number(rt?.pid);
268
+ let runtimeLive = false;
269
+ if (Number.isSafeInteger(rtPid) && rtPid > 0) {
270
+ try {
271
+ process.kill(rtPid, 0);
272
+ runtimeLive = true;
273
+ } catch (e) {
274
+ if (e && typeof e === "object" && "code" in e && e.code === "EPERM") runtimeLive = true;
275
+ }
276
+ }
277
+ if (runtimeLive) {
278
+ bakePort = Math.trunc(rt.port);
279
+ sawRuntimePort = true;
280
+ }
281
+ }
282
+ } catch { /* fall through to config */ }
283
+ if (!sawRuntimePort) {
284
+ try {
285
+ const cfg = JSON.parse(readFileSync(join(configDir(), "config.json"), "utf8"));
286
+ if (Number.isFinite(cfg?.port) && cfg.port > 0 && cfg.port <= 65535) bakePort = Math.trunc(cfg.port);
287
+ } catch { /* keep default */ }
288
+ }
289
+
290
+ // Never replace package files under a live proxy — stop it first (full `rmx stop`
291
+ // semantics: graceful drain, service stop, native Codex restore). Gate on the service
292
+ // and the runtime-port record too: a service-managed or orphaned proxy can be live
293
+ // while ocx.pid is stale/missing.
294
+ const launcher = fileURLToPath(import.meta.url);
295
+ if (trayBeforeUpdate.stopBeforeReplacement) {
296
+ console.log("⏹ Handing off the Windows tray before updating...");
297
+ try {
298
+ handoffWindowsTrayForUpdate(trayBeforeUpdate, {
299
+ stop: () => {
300
+ const stopped = runTrayLifecycle(launcher, "stop");
301
+ return { exitStatus: stopped.status, running: trayInstallState().running };
302
+ },
303
+ start: () => runTrayLifecycle(launcher, "start"),
304
+ });
305
+ } catch {
306
+ console.error("Remodex: could not stop the Windows tray; aborting before package replacement.");
307
+ process.exit(1);
308
+ }
309
+ }
310
+ const hasRuntimeState =
311
+ existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
312
+ if (serviceWasInstalled || hasRuntimeState) {
313
+ console.log("⏹ Stopping the running proxy before updating...");
314
+ const stopRes = spawnSync(process.execPath, [launcher, "stop"], { stdio: "inherit", windowsHide: true });
315
+ const stillHasRuntimeState =
316
+ existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
317
+ if (stopRes.status !== 0 || stillHasRuntimeState) {
318
+ if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
319
+ console.error("Remodex: could not stop the running proxy; aborting the update. Run 'rmx stop' and retry.");
320
+ process.exit(1);
321
+ }
322
+ if (historyRestoreIncomplete()) {
323
+ console.warn(
324
+ "Remodex: WARNING — Codex resume history was NOT restored (history DB locked; Codex app/IDE open?).\n" +
325
+ " Routed threads stay hidden in the native Codex app until restored.\n" +
326
+ " After the update: close the Codex app, then run 'rmx stop' once to restore.",
327
+ );
328
+ }
329
+ }
330
+
331
+ console.log(`Updating${latest ? ` to v${latest}` : ""}...\n$ npm install -g ${PKG}@${tag}`);
332
+ const res = spawnSync(installInvocation.file, installInvocation.args, {
333
+ stdio: "inherit",
334
+ timeout: 180000,
335
+ windowsHide: true,
336
+ ...installInvocation.options,
337
+ });
338
+ if (res.status === 0) {
339
+ console.log(`\nUpdated${latest ? ` to v${latest}` : ""}.`);
340
+ repairCodexShimIfNeeded();
341
+ if (trayBeforeUpdate.refreshAfterReplacement) {
342
+ const tray = spawnSync(process.execPath, [launcher, ...trayBeforeUpdate.installArgs], {
343
+ stdio: "inherit",
344
+ windowsHide: true,
345
+ });
346
+ if (tray.status !== 0) {
347
+ console.warn("Remodex: Windows tray refresh failed. Run: rmx tray install");
348
+ if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
349
+ }
350
+ }
351
+ // The stop above unloaded any managed service; refresh via the freshly-installed
352
+ // launcher so the new files write the baked paths and the service restarts.
353
+ if (serviceWasInstalled) {
354
+ console.log("Refreshing the background service with the updated files...");
355
+ const prevBake = process.env.OCX_BAKE_PORT;
356
+ process.env.OCX_BAKE_PORT = String(bakePort);
357
+ try {
358
+ let svc = spawnSync(process.execPath, serviceRefreshArgs(), { stdio: "inherit", windowsHide: true });
359
+ // `serviceWasInstalled` is inferred from service-state.json alone, which can be
360
+ // STALE — present while the registration is gone. Repair refuses that case by
361
+ // design, and its thrown Error is indistinguishable from any other failure at
362
+ // this layer (plain Error, inherited stdio, generic exit status). So ask for
363
+ // structured state instead of parsing the failure: install only when the
364
+ // diagnostic says the service is genuinely absent. Installing after ANY repair
365
+ // failure would resurrect the elevation prompt this change exists to avoid, and
366
+ // could re-register a service the user just uninstalled.
367
+ if (svc.status !== 0 && readServiceInstalledFromStatus(launcher) === false) {
368
+ console.log("No registered service found — installing it instead.");
369
+ svc = spawnSync(process.execPath, serviceInstallArgs(), { stdio: "inherit", windowsHide: true });
370
+ }
371
+ let needDirectStart = svc.status !== 0;
372
+ if (!needDirectStart) {
373
+ // Exit 0 can still leave stale/missing assets that never bring the proxy
374
+ // back — match the GUI/CLI fallthrough so /healthz is not left dead.
375
+ try {
376
+ const st = spawnSync(process.execPath, [launcher, "status", "--json"], {
377
+ encoding: "utf8",
378
+ timeout: 20_000,
379
+ windowsHide: true,
380
+ });
381
+ if (st.status === 0 && typeof st.stdout === "string" && st.stdout.trim()) {
382
+ const parsed = JSON.parse(st.stdout);
383
+ const proxyUp = parsed?.proxy?.running === true || parsed?.proxy?.health?.ok === true;
384
+ const viable = parsed?.startup?.serviceViable === true;
385
+ if (!proxyUp && !viable) needDirectStart = true;
386
+ } else {
387
+ // status failed or empty — fail closed to direct start (match CLI).
388
+ needDirectStart = true;
389
+ }
390
+ } catch {
391
+ needDirectStart = true;
392
+ }
393
+ }
394
+ if (needDirectStart) {
395
+ // A repair needs no elevation, but it can still fail — or exit 0 while leaving
396
+ // a non-viable manager. Fall back to a direct detached proxy start so the
397
+ // update never leaves the user without a running proxy.
398
+ console.warn(
399
+ svc.status === 0
400
+ ? "Remodex: service refresh left a non-viable manager — starting the proxy directly instead."
401
+ : "Remodex: service refresh failed — starting the proxy directly instead.",
402
+ );
403
+ console.warn(" Run 'rmx service repair' to see why the background service could not restart.");
404
+ const env = { ...process.env };
405
+ delete env.OCX_SERVICE;
406
+ const child = spawn(process.execPath, [launcher, "start", "--port", String(bakePort)], {
407
+ detached: true,
408
+ stdio: "ignore",
409
+ windowsHide: true,
410
+ env,
411
+ });
412
+ child.unref();
413
+ console.log(`Proxy starting on port ${bakePort}.`);
414
+ }
415
+ } finally {
416
+ if (prevBake === undefined) delete process.env.OCX_BAKE_PORT;
417
+ else process.env.OCX_BAKE_PORT = prevBake;
418
+ }
419
+ } else {
420
+ console.log("Restart the proxy: rmx start");
421
+ }
422
+ process.exit(0);
423
+ }
424
+ if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
425
+ console.error(`\nUpdate failed (npm exit ${res.status ?? "?"}). Try manually: npm install -g ${PKG}@${tag}`);
426
+ process.exit(1);
427
+ }
428
+
429
+ function bunBinDir() {
430
+ // Resolve the `bun` dependency's directory without hardcoding the platform
431
+ // package — npm's os/cpu/libc resolution already picked the right @oven/bun-*.
432
+ return dirname(require.resolve("bun/package.json"));
433
+ }
434
+
435
+ const BUN_OVERRIDE_ENV = "OPENCODEX_BUN_PATH";
436
+ // Mirrors BUN_RUNTIME_SOURCE_ENV in src/lib/bun-runtime.ts. This launcher is plain
437
+ // Node and runs before any TypeScript is loaded, so the name is repeated rather than
438
+ // imported; tests/ocx-launcher-source.test.ts pins the two together.
439
+ const BUN_RUNTIME_SOURCE_ENV = "OCX_BUN_RUNTIME_SOURCE";
440
+ const BUN_RUNTIME_PATH_ENV = "OCX_BUN_RUNTIME_PATH";
441
+
442
+ function findBunBinary(bunDir) {
443
+ // The npm `bun` package ships the binary as bin/bun.exe on every platform;
444
+ // probe bin/bun too for forward compatibility.
445
+ for (const name of ["bun.exe", "bun"]) {
446
+ const p = join(bunDir, "bin", name);
447
+ if (isRealBunBinary(p)) return p;
448
+ }
449
+ return null;
450
+ }
451
+
452
+ function fail(msg) {
453
+ console.error(
454
+ `Remodex: ${msg}\n` +
455
+ "The bundled Bun runtime could not be prepared. This usually means the\n" +
456
+ "install skipped lifecycle scripts (e.g. npm blocked bun's postinstall\n" +
457
+ "under allowScripts) or optional dependencies. Reinstall with:\n" +
458
+ " npm install -g --allow-scripts=bun @remodex/rmx\n" +
459
+ "(use sudo if the original install used sudo; without --ignore-scripts\n" +
460
+ "and without --omit=optional / optional=false)"
461
+ );
462
+ process.exit(1);
463
+ }
464
+
465
+ function resolveBun() {
466
+ // Keep direct npm-launcher starts aligned with durable service/shim installs:
467
+ // a valid explicit runtime must win even when the bundled dependency exists.
468
+ const override = process.env[BUN_OVERRIDE_ENV]?.trim();
469
+ if (override) {
470
+ const overridePath = resolve(override);
471
+ if (isRealBunBinary(overridePath)) return { path: overridePath, source: "override" };
472
+ console.error(
473
+ `Remodex: ${BUN_OVERRIDE_ENV} is missing, unreadable, or not a complete Bun binary; falling back to the bundled runtime.`,
474
+ );
475
+ }
476
+
477
+ let bunDir;
478
+ try {
479
+ bunDir = bunBinDir();
480
+ } catch {
481
+ fail("the `bun` dependency is not installed.");
482
+ }
483
+
484
+ let bin = findBunBinary(bunDir);
485
+ if (bin) return { path: bin, source: "bundled" };
486
+
487
+ // Lazy fallback: --ignore-scripts (or a failed postinstall) leaves the
488
+ // ~450-byte placeholder stub. Run the bun package's own installer once.
489
+ const installJs = join(bunDir, "install.js");
490
+ if (existsSync(installJs)) {
491
+ const r = spawnSync(process.execPath, [installJs], { stdio: "inherit" });
492
+ if (r.status === 0) bin = findBunBinary(bunDir);
493
+ }
494
+ if (!bin) fail("Bun binary missing after install attempt.");
495
+ return { path: bin, source: "bundled" };
496
+ }
497
+
498
+ // `rmx update --help` prints usage and exits WITHOUT side effects. The npm launcher
499
+ // intercepts `update` before the Bun CLI starts, so the help short-circuit must live
500
+ // here too — otherwise --help runs the real self-update, stops the proxy, and drops
501
+ // in-flight routed streams (issue #168).
502
+ const updateHelpRequested = process.argv[2] === "update" &&
503
+ process.argv.slice(3).some(a => a === "--help" || a === "-h" || a === "help");
504
+ if (updateHelpRequested) {
505
+ console.log("Usage: rmx update [--tag latest|preview]\n\nUpdate Remodex. Preview installs stay on the preview tag unless overridden.\nCompatibility aliases: remodex, opencodex, ocx.");
506
+ process.exit(0);
507
+ }
508
+
509
+ if (process.argv[2] === "update" && isNodeModulesInstall() && !isBunGlobalInstall()) {
510
+ runNpmSelfUpdate();
511
+ }
512
+
513
+ const bunRuntime = resolveBun();
514
+ const bun = bunRuntime.path;
515
+
516
+ // Run the Bun child asynchronously and FORWARD termination signals to it, then wait
517
+ // for its graceful shutdown before this launcher exits. The previous blocking
518
+ // spawnSync() could not run JS signal handlers and did not forward signals, so a
519
+ // signal delivered only to this launcher (Codex app, IDE terminal, service wrapper,
520
+ // or `kill -INT <launcherPid>`) killed the launcher and ORPHANED the Bun proxy —
521
+ // port left bound, pid/runtime-port files left behind, Codex config not restored.
522
+ //
523
+ // Provenance seam for issue #701: THIS launcher runs under Node, which does not
524
+ // auto-load a project `.env`/`.env.local`; the Bun child does, before any opencodex
525
+ // code evaluates. So this is the last point that can still tell a real shell export
526
+ // from a working-directory dotenv value, and we record which Anthropic credential or
527
+ // destination slots already existed. The context is paired with a random proof carried
528
+ // in argv, which project dotenv cannot modify during an ordinary `rmx` invocation.
529
+ // `src/cli/claude.ts` treats anything present in the Bun child but missing from this
530
+ // list as ambient project pollution rather than user auth or destination,
531
+ // which stopped a project dotenv from silently moving a claude.ai subscriber onto API
532
+ // billing and prevents it from redirecting the subscriber's OAuth bearer.
533
+ // Disabling Bun's dotenv wholesale with --no-env-file is NOT an option: config
534
+ // interpolation and provider settings legitimately read the project environment.
535
+ const preBunAnthropicSlots = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL"]
536
+ .filter(name => typeof process.env[name] === "string" && process.env[name] !== "");
537
+ const launchProof = randomBytes(32).toString("base64url");
538
+ const launchContext = JSON.stringify({
539
+ version: 1,
540
+ proof: launchProof,
541
+ anthropicEnvSlots: preBunAnthropicSlots,
542
+ });
543
+ const child = spawn(bun, [cliPath, `${NODE_LAUNCH_PROOF_PREFIX}${launchProof}`, ...process.argv.slice(2)], {
544
+ stdio: "inherit",
545
+ env: {
546
+ ...process.env,
547
+ [NODE_LAUNCH_CONTEXT_ENV]: launchContext,
548
+ [BUN_RUNTIME_SOURCE_ENV]: bunRuntime.source,
549
+ [BUN_RUNTIME_PATH_ENV]: bunRuntime.path,
550
+ },
551
+ });
552
+
553
+ // Windows has no real POSIX signals (no SIGHUP); forwarding is best-effort there.
554
+ const FORWARDED = process.platform === "win32" ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
555
+ const handlers = FORWARDED.map(sig => {
556
+ const handler = () => {
557
+ try {
558
+ child.kill(sig);
559
+ } catch {
560
+ /* child already exited */
561
+ }
562
+ };
563
+ process.on(sig, handler);
564
+ return [sig, handler];
565
+ });
566
+ const clearHandlers = () => {
567
+ for (const [sig, handler] of handlers) process.removeListener(sig, handler);
568
+ };
569
+
570
+ child.on("error", err => {
571
+ clearHandlers();
572
+ console.error(`Remodex: failed to launch Bun runtime: ${err.message}`);
573
+ process.exit(1);
574
+ });
575
+
576
+ child.on("exit", (code, signal) => {
577
+ clearHandlers();
578
+ // Mirror the child's terminating signal/exit code so this launcher's status matches.
579
+ if (signal) {
580
+ process.kill(process.pid, signal);
581
+ return;
582
+ }
583
+ process.exit(code ?? 1);
584
+ });
@@ -0,0 +1,9 @@
1
+ export const packageName = "@remodex/rmx";
2
+ export const cliCommand = "rmx";
3
+
4
+ export async function loadBunApi() {
5
+ if (typeof Bun === "undefined") {
6
+ throw new Error("The Remodex programmatic API requires the Bun runtime. Use `rmx` (aliases: remodex, opencodex, ocx) for the CLI entrypoint.");
7
+ }
8
+ return import("../src/index.ts");
9
+ }