rnxsim 0.1.369 → 0.1.370

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 (253) hide show
  1. package/cli/auth.ts +2 -1
  2. package/cli/bin.ts +283 -273
  3. package/cli/commands/app-fonts.ts +3 -2
  4. package/cli/commands/assert.ts +8 -7
  5. package/cli/commands/auth.ts +2 -1
  6. package/cli/commands/box/checkout-plane.ts +45 -16
  7. package/cli/commands/config.ts +2 -1
  8. package/cli/commands/control.ts +37 -33
  9. package/cli/commands/daemon.ts +22 -21
  10. package/cli/commands/debug.ts +17 -15
  11. package/cli/commands/detox.ts +5 -4
  12. package/cli/commands/device.ts +6 -5
  13. package/cli/commands/electron.ts +6 -5
  14. package/cli/commands/flow.ts +12 -11
  15. package/cli/commands/inspect/find.ts +2 -1
  16. package/cli/commands/inspect/keyboard.ts +2 -1
  17. package/cli/commands/inspect/sleep.ts +2 -1
  18. package/cli/commands/inspect/wait-event.ts +4 -3
  19. package/cli/commands/inspect/wait-idle.ts +2 -1
  20. package/cli/commands/inspect/wait-ready.ts +3 -2
  21. package/cli/commands/inspect/wait-selector.ts +4 -3
  22. package/cli/commands/inspect/wait.ts +2 -1
  23. package/cli/commands/inspect.ts +82 -80
  24. package/cli/commands/install-desktop.ts +5 -4
  25. package/cli/commands/login.ts +3 -2
  26. package/cli/commands/mode.ts +2 -1
  27. package/cli/commands/record.ts +38 -37
  28. package/cli/commands/runtime.ts +9 -8
  29. package/cli/commands/screenshot-layers.ts +4 -3
  30. package/cli/commands/screenshot-mode.ts +2 -1
  31. package/cli/commands/screenshot.ts +8 -7
  32. package/cli/commands/screenshots-capture.ts +2 -1
  33. package/cli/commands/serve.ts +5 -4
  34. package/cli/commands/shell-boolean-mode.ts +2 -1
  35. package/cli/commands/skills.ts +11 -10
  36. package/cli/commands/telemetry.ts +2 -1
  37. package/cli/commands/three-mode.ts +2 -1
  38. package/cli/commands/timeline.ts +4 -3
  39. package/cli/commands/upload.ts +14 -13
  40. package/cli/commands/what-happened.ts +2 -1
  41. package/cli/recording-access.ts +6 -5
  42. package/cli/run-rnx.ts +140 -0
  43. package/dist-cli/bin.js +6 -6
  44. package/dist-cli/chunks/{agent-OUUFWDLF.js → agent-3R4424LW.js} +2 -2
  45. package/dist-cli/chunks/{agent-wrapper-7BE7DR4R.js → agent-wrapper-4PPWZWSY.js} +2 -2
  46. package/dist-cli/chunks/app-fonts-KYXB6CXQ.js +4 -0
  47. package/dist-cli/chunks/{assert-I3CMRNS7.js → assert-7EZOWGYQ.js} +11 -11
  48. package/dist-cli/chunks/auth-L7M36H6C.js +12 -0
  49. package/dist-cli/chunks/{beta-BHSKY4K4.js → beta-FKAF6YWJ.js} +2 -2
  50. package/dist-cli/chunks/{box-3CVWXVTT.js → box-5Y5VBMHV.js} +342 -342
  51. package/dist-cli/chunks/{camera-MNK73TYV.js → camera-XHF2RPFG.js} +2 -2
  52. package/dist-cli/chunks/{chunk-NPVEBXU3.js → chunk-2FOGXVOK.js} +2 -2
  53. package/dist-cli/chunks/{chunk-UDXQCEJU.js → chunk-3BG6UCQY.js} +2 -2
  54. package/dist-cli/chunks/{chunk-V7I4CTAX.js → chunk-3SOPYG7S.js} +2 -2
  55. package/dist-cli/chunks/{chunk-QE5MC4V3.js → chunk-3UXXYJVD.js} +1 -1
  56. package/dist-cli/chunks/{chunk-EKAEEWC2.js → chunk-5BR33NAZ.js} +1 -1
  57. package/dist-cli/chunks/{chunk-FGGESBWD.js → chunk-5RKRVS5A.js} +2 -2
  58. package/dist-cli/chunks/{chunk-MXWME7ET.js → chunk-64JAEJ6N.js} +1 -1
  59. package/dist-cli/chunks/{chunk-AKJYEX54.js → chunk-6A6L3VJR.js} +2 -2
  60. package/dist-cli/chunks/chunk-6GPS7U4X.js +74 -0
  61. package/dist-cli/chunks/{chunk-OROUEG22.js → chunk-6S5LJV2O.js} +2 -2
  62. package/dist-cli/chunks/{chunk-ZW6JXEVX.js → chunk-6W4HIWC7.js} +2 -2
  63. package/dist-cli/chunks/{chunk-6BMM6OCW.js → chunk-72S5FCBY.js} +2 -2
  64. package/dist-cli/chunks/{chunk-TBK5UXW2.js → chunk-7C7TJYZ3.js} +2 -2
  65. package/dist-cli/chunks/{chunk-D6MGELKZ.js → chunk-AALKIAUZ.js} +1 -1
  66. package/dist-cli/chunks/{chunk-WUR4FXWT.js → chunk-ARMXC3C3.js} +25 -25
  67. package/dist-cli/chunks/chunk-AVJBT5LF.js +4 -0
  68. package/dist-cli/chunks/chunk-BMIJZNKD.js +28 -0
  69. package/dist-cli/chunks/{chunk-N5KDDGV6.js → chunk-C7BA5CCM.js} +2 -2
  70. package/dist-cli/chunks/{chunk-F4OTMARL.js → chunk-CMVRTZ5G.js} +2 -2
  71. package/dist-cli/chunks/chunk-D24EOJ4C.js +24 -0
  72. package/dist-cli/chunks/{chunk-A56GQVNF.js → chunk-D2GZASRV.js} +1 -1
  73. package/dist-cli/chunks/{chunk-IYPMULI7.js → chunk-DHYTRCIP.js} +2 -2
  74. package/dist-cli/chunks/{chunk-X3PEDNLV.js → chunk-DMHSD6YJ.js} +2 -2
  75. package/dist-cli/chunks/{chunk-YPBDPVLR.js → chunk-DUXHYPBP.js} +2 -2
  76. package/dist-cli/chunks/{chunk-4SCVGBOX.js → chunk-DXV37CJN.js} +1 -1
  77. package/dist-cli/chunks/{chunk-H2GB2PLY.js → chunk-EOIBLKZO.js} +2 -2
  78. package/dist-cli/chunks/{chunk-UQJY6O72.js → chunk-EQ3OE2AV.js} +1 -1
  79. package/dist-cli/chunks/{chunk-3454VMHD.js → chunk-EWSWOWXK.js} +2 -2
  80. package/dist-cli/chunks/{chunk-FHRG772G.js → chunk-FA75F34Z.js} +1 -1
  81. package/dist-cli/chunks/{chunk-LU3AHE6T.js → chunk-FK4JSTZ3.js} +2 -2
  82. package/dist-cli/chunks/{chunk-AJJCYLBC.js → chunk-GJRLPJQL.js} +2 -2
  83. package/dist-cli/chunks/{chunk-WGE2P25F.js → chunk-GRO74J2X.js} +1 -1
  84. package/dist-cli/chunks/chunk-H5X5FJ63.js +99 -0
  85. package/dist-cli/chunks/chunk-HEKHLQ3B.js +497 -0
  86. package/dist-cli/chunks/chunk-HQQTS2CB.js +30 -0
  87. package/dist-cli/chunks/{chunk-DKSZZABN.js → chunk-I52NT6VG.js} +1 -1
  88. package/dist-cli/chunks/{chunk-A72MIIJI.js → chunk-IDLFVRPN.js} +1 -1
  89. package/dist-cli/chunks/{chunk-6F3WOWFC.js → chunk-JZLDHPB7.js} +2 -2
  90. package/dist-cli/chunks/{chunk-ZNNE5MAV.js → chunk-LIMWG54N.js} +1 -1
  91. package/dist-cli/chunks/{chunk-TTUZ5MCK.js → chunk-LUOHRBJG.js} +1 -1
  92. package/dist-cli/chunks/{chunk-B5NW4TT3.js → chunk-LXPHL6FO.js} +2 -2
  93. package/dist-cli/chunks/{chunk-TAC4CEIX.js → chunk-MDCY532E.js} +2 -2
  94. package/dist-cli/chunks/{chunk-45X3D6CI.js → chunk-NJMU5BN6.js} +1 -1
  95. package/dist-cli/chunks/{chunk-2APXX4RN.js → chunk-NR2V2ONN.js} +2 -2
  96. package/dist-cli/chunks/{chunk-JH5KE2OI.js → chunk-NTC46LSA.js} +2 -2
  97. package/dist-cli/chunks/{chunk-RV76U3EI.js → chunk-O6QLKSAM.js} +10 -10
  98. package/dist-cli/chunks/{chunk-ZEF57HQO.js → chunk-OJZHECGH.js} +1 -1
  99. package/dist-cli/chunks/chunk-OTFTMGAL.js +7 -0
  100. package/dist-cli/chunks/{chunk-RYGQ6LZN.js → chunk-PAUEZO6F.js} +2 -2
  101. package/dist-cli/chunks/{chunk-CCI3DZKE.js → chunk-PIZXOXBL.js} +2 -2
  102. package/dist-cli/chunks/{chunk-JLOOLA47.js → chunk-PNOENVMJ.js} +1 -1
  103. package/dist-cli/chunks/{chunk-YLNSLMQM.js → chunk-Q4MRJ6PO.js} +2 -2
  104. package/dist-cli/chunks/{chunk-5QFJFASW.js → chunk-RRX52O37.js} +1 -1
  105. package/dist-cli/chunks/{chunk-FBMNYSSW.js → chunk-U63T6LIQ.js} +1 -1
  106. package/dist-cli/chunks/{chunk-2PVVIPQS.js → chunk-UFVAAWGZ.js} +1 -1
  107. package/dist-cli/chunks/{chunk-CZ2HCNRK.js → chunk-VVQCZ42C.js} +1 -1
  108. package/dist-cli/chunks/{chunk-USHV3QFZ.js → chunk-WFQHT4QD.js} +2 -2
  109. package/dist-cli/chunks/{chunk-DCPDMF27.js → chunk-WPV4H5S4.js} +2 -2
  110. package/dist-cli/chunks/{chunk-SSBZA5VZ.js → chunk-X6WQ4YWE.js} +1 -1
  111. package/dist-cli/chunks/{chunk-VGJLCFSC.js → chunk-YIZGNT7A.js} +1 -1
  112. package/dist-cli/chunks/{chunk-JXARZBWS.js → chunk-Z2VBSNFI.js} +1 -1
  113. package/dist-cli/chunks/{chunk-4G4VCT2M.js → chunk-Z3DENGXW.js} +2 -2
  114. package/dist-cli/chunks/{cleanup-H4XFRMZV.js → cleanup-MXMMJ7JW.js} +2 -2
  115. package/dist-cli/chunks/cli-version-MLS55UTY.js +4 -0
  116. package/dist-cli/chunks/{compat-NKGYERLN.js → compat-E6KE5KDI.js} +2 -2
  117. package/dist-cli/chunks/config-QSLLVZDS.js +13 -0
  118. package/dist-cli/chunks/{connect-WWWAVVCF.js → connect-QE4VU6GB.js} +2 -2
  119. package/dist-cli/chunks/control-XD5F6K5T.js +4 -0
  120. package/dist-cli/chunks/daemon-UN5SE2JO.js +4 -0
  121. package/dist-cli/chunks/{debug-RO6GLDIM.js → debug-5FG3MBJS.js} +20 -20
  122. package/dist-cli/chunks/desktop-5EZX7NX5.js +31 -0
  123. package/dist-cli/chunks/detox-WJGQP5TM.js +52 -0
  124. package/dist-cli/chunks/device-D7LKCAMS.js +18 -0
  125. package/dist-cli/chunks/{diagnose-HDRTUPDO.js → diagnose-A3W6ZTGA.js} +2 -2
  126. package/dist-cli/chunks/{disk-cleanup-QP2NYN43.js → disk-cleanup-BDRHX5ZG.js} +2 -2
  127. package/dist-cli/chunks/{do-chain-6LP6SV5J.js → do-chain-RUJNRPPF.js} +2 -2
  128. package/dist-cli/chunks/drivers-3NJ5RL6X.js +4 -0
  129. package/dist-cli/chunks/{env-4XD5D2G6.js → env-U67SQVTV.js} +2 -2
  130. package/dist-cli/chunks/{film-I5SIXLS5.js → film-XC6UAQ3V.js} +3 -3
  131. package/dist-cli/chunks/flow-FHZZD3P6.js +4 -0
  132. package/dist-cli/chunks/help-BYYDUSXF.js +4 -0
  133. package/dist-cli/chunks/{hidden-runtime-alias-LJV2S4M2.js → hidden-runtime-alias-7S2TNZXG.js} +2 -2
  134. package/dist-cli/chunks/{home-paths-RFI2QRC3.js → home-paths-LMO5LB4F.js} +2 -2
  135. package/dist-cli/chunks/inspect-RQCTWDCC.js +4 -0
  136. package/dist-cli/chunks/install-desktop-GOWXCQUE.js +4 -0
  137. package/dist-cli/chunks/login-JIU42S4C.js +26 -0
  138. package/dist-cli/chunks/{logout-DKXZZ6HU.js → logout-JTAWQXZO.js} +2 -2
  139. package/dist-cli/chunks/{maestro-WKGVVWRA.js → maestro-TYBQYOGB.js} +3 -3
  140. package/dist-cli/chunks/{maestro-generate-KCK6RK2C.js → maestro-generate-YLAGWVKE.js} +3 -3
  141. package/dist-cli/chunks/mode-DV24ZRZ6.js +26 -0
  142. package/dist-cli/chunks/{optional-demo-registry-EUSKBIPP.js → optional-demo-registry-JZH66VIM.js} +2 -2
  143. package/dist-cli/chunks/{perf-IMZMA5MT.js → perf-LXXJ4EAX.js} +2 -2
  144. package/dist-cli/chunks/{permissions-SLWXTLH6.js → permissions-KAOVZUPW.js} +2 -2
  145. package/dist-cli/chunks/{platform-HQ735LAE.js → platform-KW35446W.js} +3 -3
  146. package/dist-cli/chunks/privacy-MIFE72CG.js +4 -0
  147. package/dist-cli/chunks/record-EK3ETFHZ.js +72 -0
  148. package/dist-cli/chunks/report-issue-NW5PCAZF.js +29 -0
  149. package/dist-cli/chunks/reset-RZ4O5AFJ.js +4 -0
  150. package/dist-cli/chunks/resolve-target-7R5BNYMM.js +4 -0
  151. package/dist-cli/chunks/runtime-MZHLSRS6.js +4 -0
  152. package/dist-cli/chunks/{screenshot-command-HAJB5FHK.js → screenshot-command-TQSPTFT2.js} +11 -11
  153. package/dist-cli/chunks/screenshot-layers-IZP3L3AQ.js +20 -0
  154. package/dist-cli/chunks/screenshots-capture-K7LJOVAE.js +42 -0
  155. package/dist-cli/chunks/{serve-TM46TKFW.js → serve-MMX4WXXG.js} +18 -18
  156. package/dist-cli/chunks/setup-YFP3KEQZ.js +4 -0
  157. package/dist-cli/chunks/{sim-client-LQUZSO45.js → sim-client-KLAYIFOC.js} +2 -2
  158. package/dist-cli/chunks/skills-N4D3POIS.js +50 -0
  159. package/dist-cli/chunks/{state-RUVM4Z4S.js → state-ES6TFQZF.js} +2 -2
  160. package/dist-cli/chunks/{storage-GQ33UTYN.js → storage-52DR5V2C.js} +2 -2
  161. package/dist-cli/chunks/store-HOL45WCI.js +4 -0
  162. package/dist-cli/chunks/telemetry-BV6OTYPF.js +4 -0
  163. package/dist-cli/chunks/timeline-NRVNB5JR.js +24 -0
  164. package/dist-cli/chunks/{upgrade-AZDZLUIT.js → upgrade-LNED5YQ2.js} +2 -2
  165. package/dist-cli/chunks/upload-RXKHFIBU.js +4 -0
  166. package/dist-cli/chunks/{version-N3ALB75G.js → version-VEF2DYGG.js} +2 -2
  167. package/dist-cli/chunks/{web-XPHFZATA.js → web-CGDE6S73.js} +2 -2
  168. package/dist-cli/chunks/welcome-FT2AMUWW.js +5 -0
  169. package/dist-cli/chunks/what-happened-FSIDWL32.js +25 -0
  170. package/dist-cli/chunks/{ws-bridge-RUXOYOU6.js → ws-bridge-QXFQLRE7.js} +2 -2
  171. package/dist-lib/agent-daemon-client.cjs +1 -1
  172. package/dist-lib/agent-events.cjs +1 -1
  173. package/dist-lib/agent-identity.cjs +1 -1
  174. package/dist-lib/agent-sessions.cjs +1 -1
  175. package/dist-lib/attached-projects.cjs +1 -1
  176. package/dist-lib/auth/shared-session.cjs +1 -1
  177. package/dist-lib/backend-origin.cjs +1 -1
  178. package/dist-lib/beta.cjs +1 -1
  179. package/dist-lib/beta.mjs +1 -1
  180. package/dist-lib/bridge-constants.cjs +1 -1
  181. package/dist-lib/bridge-contract-input.cjs +1 -1
  182. package/dist-lib/bridge-contract-input.mjs +1 -1
  183. package/dist-lib/bridge-contract.cjs +1 -1
  184. package/dist-lib/bridge-contract.mjs +1 -1
  185. package/dist-lib/cli-constants.cjs +1 -1
  186. package/dist-lib/config.cjs +1 -1
  187. package/dist-lib/detox/index.cjs +1 -1
  188. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  189. package/dist-lib/home-paths.cjs +1 -1
  190. package/dist-lib/host/bridge-host.cjs +1 -1
  191. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  192. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  193. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  194. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  195. package/dist-lib/host/websocket-proxy.cjs +1 -1
  196. package/dist-lib/index.cjs +1 -1
  197. package/dist-lib/jump-to-source-babel.cjs +1 -1
  198. package/dist-lib/menu.cjs +1 -1
  199. package/dist-lib/menu.mjs +1 -1
  200. package/dist-lib/metro-production-bundle.cjs +1 -1
  201. package/dist-lib/metro-production-bundle.mjs +1 -1
  202. package/dist-lib/metro.cjs +1 -1
  203. package/dist-lib/profiles.cjs +1 -1
  204. package/dist-lib/public-brand.cjs +1 -1
  205. package/dist-lib/react-native-host-modules.cjs +2 -1
  206. package/dist-lib/react-native-host-modules.mjs +2 -1
  207. package/dist-lib/render-mode.cjs +1 -1
  208. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  209. package/dist-lib/sdk.cjs +1 -1
  210. package/dist-lib/sdk.mjs +1 -1
  211. package/dist-lib/skills.cjs +79 -47
  212. package/dist-lib/vite.cjs +1 -1
  213. package/package.json +1 -1
  214. package/src/react-native-host-modules.ts +1 -0
  215. package/dist-cli/chunks/app-fonts-66V7TL26.js +0 -4
  216. package/dist-cli/chunks/auth-3FMWUVJH.js +0 -12
  217. package/dist-cli/chunks/chunk-3NLB5LCN.js +0 -28
  218. package/dist-cli/chunks/chunk-5RWUFIZW.js +0 -24
  219. package/dist-cli/chunks/chunk-COXCR6UU.js +0 -7
  220. package/dist-cli/chunks/chunk-ROISJKH3.js +0 -99
  221. package/dist-cli/chunks/chunk-SUHAD6N2.js +0 -30
  222. package/dist-cli/chunks/chunk-TIB3CTRX.js +0 -497
  223. package/dist-cli/chunks/chunk-YFZLDFZK.js +0 -74
  224. package/dist-cli/chunks/cli-version-MJWLDXBW.js +0 -4
  225. package/dist-cli/chunks/config-WK7467KI.js +0 -13
  226. package/dist-cli/chunks/control-ESI7IZNN.js +0 -4
  227. package/dist-cli/chunks/daemon-UCLO27YP.js +0 -4
  228. package/dist-cli/chunks/desktop-FF34Z5X4.js +0 -31
  229. package/dist-cli/chunks/detox-Q3CWY5UX.js +0 -52
  230. package/dist-cli/chunks/device-WN4ZWLES.js +0 -18
  231. package/dist-cli/chunks/drivers-OR2JPAXD.js +0 -4
  232. package/dist-cli/chunks/flow-4GWW5DYT.js +0 -4
  233. package/dist-cli/chunks/help-MIIWOT3C.js +0 -4
  234. package/dist-cli/chunks/inspect-3ZGNJENJ.js +0 -4
  235. package/dist-cli/chunks/install-desktop-BYOJVTLS.js +0 -4
  236. package/dist-cli/chunks/login-GNIFSAFE.js +0 -26
  237. package/dist-cli/chunks/mode-YVMX7OJY.js +0 -26
  238. package/dist-cli/chunks/privacy-EDC7PF7G.js +0 -4
  239. package/dist-cli/chunks/record-N4KTTVDI.js +0 -72
  240. package/dist-cli/chunks/report-issue-PP752HAD.js +0 -29
  241. package/dist-cli/chunks/reset-DRMKGVP4.js +0 -4
  242. package/dist-cli/chunks/resolve-target-7WWI32R3.js +0 -4
  243. package/dist-cli/chunks/runtime-EKJV2ZVI.js +0 -4
  244. package/dist-cli/chunks/screenshot-layers-GOCJVM2G.js +0 -20
  245. package/dist-cli/chunks/screenshots-capture-YYJLYA3V.js +0 -42
  246. package/dist-cli/chunks/setup-FVPVIYE4.js +0 -4
  247. package/dist-cli/chunks/skills-V5TE57FN.js +0 -50
  248. package/dist-cli/chunks/store-IKNBDDKM.js +0 -4
  249. package/dist-cli/chunks/telemetry-2ZVU6WLK.js +0 -4
  250. package/dist-cli/chunks/timeline-LP7DMJYT.js +0 -24
  251. package/dist-cli/chunks/upload-DFQK2Q7X.js +0 -4
  252. package/dist-cli/chunks/welcome-2NFYLWLJ.js +0 -5
  253. package/dist-cli/chunks/what-happened-EJ5PHKT7.js +0 -25
@@ -20,6 +20,7 @@
20
20
 
21
21
  import { DEFAULT_SOOTSIM_BRIDGE_PORT } from '../../src/bridge-constants'
22
22
  import { printBridgeFailureDiagnostics } from '../bridge-diagnostics'
23
+ import { rethrowIfExit, rnxExit } from '../run-rnx'
23
24
  import {
24
25
  createBridgeFromParsed,
25
26
  evalInBridge,
@@ -399,7 +400,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
399
400
 
400
401
  if (!subcommand || args.includes('--help') || args.includes('-h')) {
401
402
  printHelp()
402
- process.exit(0)
403
+ rnxExit(0)
403
404
  }
404
405
 
405
406
  const wsPort = parsed.wsPort
@@ -438,7 +439,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
438
439
  console.error(
439
440
  ` usage: rnx debug enable <channel[,channel,...]>\n known: ${KNOWN_CHANNELS.join(', ')}`,
440
441
  )
441
- process.exit(1)
442
+ rnxExit(1)
442
443
  }
443
444
  const active = await setDebugChannels(bridge, 'enable', channels)
444
445
  console.log(fmt({ active }, pretty))
@@ -456,7 +457,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
456
457
  const channel = rest[0]
457
458
  if (!channel) {
458
459
  console.error(' usage: rnx debug toggle <channel>')
459
- process.exit(1)
460
+ rnxExit(1)
460
461
  }
461
462
  const result = await call(
462
463
  bridge,
@@ -516,7 +517,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
516
517
  const b = rest[1]
517
518
  if (!a || !b) {
518
519
  console.error(' usage: rnx debug diff <labelA> <labelB>')
519
- process.exit(1)
520
+ rnxExit(1)
520
521
  }
521
522
  // Maps don't serialize — project added/removed/changed arrays only
522
523
  const code = `(() => {
@@ -557,7 +558,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
557
558
  ' zero draws means either nothing on screen is an image, or the audit\n' +
558
559
  ' is not attached to the surface that paints.',
559
560
  )
560
- process.exit(2)
561
+ rnxExit(2)
561
562
  }
562
563
  const under = report.rows.filter(
563
564
  (row) => row.shortfall !== null && row.shortfall < minimum,
@@ -567,7 +568,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
567
568
  } else {
568
569
  printImageAudit(report, args.includes('--all') ? report.rows : under, minimum)
569
570
  }
570
- if (under.length > 0) process.exit(1)
571
+ if (under.length > 0) rnxExit(1)
571
572
  break
572
573
  }
573
574
 
@@ -578,7 +579,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
578
579
  console.log(fmt(result, pretty))
579
580
  } else {
580
581
  console.error(' usage: rnx debug find <sheets|portals|boundaries>')
581
- process.exit(1)
582
+ rnxExit(1)
582
583
  }
583
584
  break
584
585
  }
@@ -596,7 +597,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
596
597
  console.error(
597
598
  ' usage: rnx debug trace anim <on|off|status|clear|<id>> [id|limit]',
598
599
  )
599
- process.exit(1)
600
+ rnxExit(1)
600
601
  }
601
602
  if (sub === 'on') {
602
603
  const raw = rest[2] ?? 'all'
@@ -604,7 +605,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
604
605
  const target: number | 'all' = raw === 'all' ? 'all' : Number(raw)
605
606
  if (target !== 'all' && !Number.isFinite(target)) {
606
607
  console.error(` invalid target: ${raw}`)
607
- process.exit(1)
608
+ rnxExit(1)
608
609
  }
609
610
  await callTestBridge(bridge, 'enableAnimationTrace', target, limit)
610
611
  const listed = await callTestBridge(bridge, 'listAnimationTraces')
@@ -616,7 +617,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
616
617
  const target: number | 'all' = raw === 'all' ? 'all' : Number(raw)
617
618
  if (target !== 'all' && !Number.isFinite(target)) {
618
619
  console.error(` invalid target: ${raw}`)
619
- process.exit(1)
620
+ rnxExit(1)
620
621
  }
621
622
  await callTestBridge(bridge, 'disableAnimationTrace', target)
622
623
  console.log(fmt({ disabled: target }, pretty))
@@ -633,7 +634,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
633
634
  const id = Number(sub)
634
635
  if (!Number.isFinite(id)) {
635
636
  console.error(` invalid id: ${sub}`)
636
- process.exit(1)
637
+ rnxExit(1)
637
638
  }
638
639
  const limit = rest[2] ? Number(rest[2]) : undefined
639
640
  const samples = await callTestBridge(bridge, 'getAnimationTrace', id, limit)
@@ -642,7 +643,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
642
643
  }
643
644
  if (traceTarget !== 'shell') {
644
645
  console.error(' usage: rnx debug trace <shell|anim> [args]')
645
- process.exit(1)
646
+ rnxExit(1)
646
647
  }
647
648
  if (!traceCommand || /^[0-9]+$/.test(traceCommand)) {
648
649
  const recentLimit = traceCommand ? Number(traceCommand) : 50
@@ -674,7 +675,7 @@ export async function runDebug(args: string[], opts: DebugOptions) {
674
675
  console.error(
675
676
  ' usage: rnx debug trace shell [on [limit]|off|status|clear|recentLimit]',
676
677
  )
677
- process.exit(1)
678
+ rnxExit(1)
678
679
  }
679
680
 
680
681
  case 'record': {
@@ -702,16 +703,17 @@ export async function runDebug(args: string[], opts: DebugOptions) {
702
703
  default:
703
704
  console.error(` unknown subcommand: ${sub}`)
704
705
  printHelp()
705
- process.exit(1)
706
+ rnxExit(1)
706
707
  }
707
708
  } catch (err: any) {
709
+ rethrowIfExit(err)
708
710
  console.error(` debug failed: ${err.message}`)
709
711
  await printBridgeFailureDiagnostics(bridge, {
710
712
  errorsCommand: `rnx get errors 5${simHint}`,
711
713
  warningsCommand: `rnx get warnings 5${simHint}`,
712
714
  requestsCommand: `rnx get requests 5${simHint}`,
713
715
  })
714
- process.exit(1)
716
+ rnxExit(1)
715
717
  } finally {
716
718
  bridge.close()
717
719
  }
@@ -18,6 +18,7 @@ import { dirname, resolve, join, relative } from 'path'
18
18
  import { rnxPublicBrand } from '../../src/public-brand'
19
19
  import { resolveCliAuth } from '../auth'
20
20
  import { registerRun, shouldRegisterRun } from '../run-registry'
21
+ import { rnxExit } from '../run-rnx'
21
22
  import { discoverSootsimUrl } from './flow'
22
23
  import { resolveDefaultUploadOrigin } from './upload'
23
24
 
@@ -57,7 +58,7 @@ expected port. disable with --no-launch if you're managing the shell yourself.
57
58
  export async function runDetox(args: string[], opts: RunDetoxOpts = {}): Promise<void> {
58
59
  if (args.includes('--help') || args.includes('-h')) {
59
60
  console.log(HELP)
60
- process.exit(0)
61
+ rnxExit(0)
61
62
  }
62
63
 
63
64
  if (args[0] === 'init') {
@@ -125,7 +126,7 @@ export async function runDetox(args: string[], opts: RunDetoxOpts = {}): Promise
125
126
  ` error: no detox tests found. expected one of: ${detoxDirs.join(', ')}\n` +
126
127
  ` run 'rnx detox init' to scaffold a starter suite.`,
127
128
  )
128
- process.exit(1)
129
+ rnxExit(1)
129
130
  }
130
131
 
131
132
  // auto-launch: make sure a sootsim shell is reachable before running jest.
@@ -278,7 +279,7 @@ export async function runDetox(args: string[], opts: RunDetoxOpts = {}): Promise
278
279
  })
279
280
  if (run) console.log(` run: ${run.id}`)
280
281
  }
281
- process.exit(code)
282
+ rnxExit(code)
282
283
  }
283
284
 
284
285
  type JestRunSummary = {
@@ -410,5 +411,5 @@ describe('example', () => {
410
411
  console.log(`\n next:`)
411
412
  console.log(` rnx detox # run the sample`)
412
413
  console.log(` rnx detox --watch`)
413
- process.exit(0)
414
+ rnxExit(0)
414
415
  }
@@ -4,6 +4,7 @@ import {
4
4
  listSelectableDeviceModels,
5
5
  type DeviceModel,
6
6
  } from 'sootsim-engine/settings'
7
+ import { rnxExit } from '../run-rnx'
7
8
  import {
8
9
  callInBridge,
9
10
  createBridgeFromParsed,
@@ -74,7 +75,7 @@ async function readCurrentDevice(
74
75
  export async function runDeviceCommand(args: string[], opts: DeviceCommandOptions) {
75
76
  if (args.includes('--help') || args.includes('-h')) {
76
77
  usage()
77
- process.exit(0)
78
+ rnxExit(0)
78
79
  }
79
80
 
80
81
  const subcommand = args[0]
@@ -83,7 +84,7 @@ export async function runDeviceCommand(args: string[], opts: DeviceCommandOption
83
84
  const current = await readCurrentDevice(parsed)
84
85
  if (!current) {
85
86
  console.error(' error: could not read current device from the target sim')
86
- process.exit(1)
87
+ rnxExit(1)
87
88
  }
88
89
  console.log(
89
90
  ` ${current.model} ${current.width}x${current.height} pt ${current.width * current.scale}x${current.height * current.scale} px ${current.name}`,
@@ -101,12 +102,12 @@ export async function runDeviceCommand(args: string[], opts: DeviceCommandOption
101
102
  const model = args[1]
102
103
  if (!model) {
103
104
  console.error(' error: device set expects a model')
104
- process.exit(1)
105
+ rnxExit(1)
105
106
  }
106
107
  if (!(model in devices)) {
107
108
  console.error(` error: unknown device "${model}"`)
108
109
  console.error(' run `rnx device list` to see valid models')
109
- process.exit(1)
110
+ rnxExit(1)
110
111
  }
111
112
  const parsed = parseBridgeCliArgs(args, { port: opts.port })
112
113
  const bridge = createBridgeFromParsed(parsed)
@@ -129,5 +130,5 @@ export async function runDeviceCommand(args: string[], opts: DeviceCommandOption
129
130
 
130
131
  usage()
131
132
  console.error(` unknown subcommand: ${subcommand}`)
132
- process.exit(1)
133
+ rnxExit(1)
133
134
  }
@@ -7,6 +7,7 @@ import { ensureProfile } from '../../src/profiles'
7
7
  import { findDesktopCompanion } from '../desktop-companion'
8
8
  import { electronDriver } from '../drivers'
9
9
  import { confirm } from '../prompt'
10
+ import { rnxExit } from '../run-rnx'
10
11
  import { buildShellUrl } from './control'
11
12
  import { printMissingCompanionHint } from './no-bridge-hint'
12
13
 
@@ -22,7 +23,7 @@ function parseInlinePort(args: string[]): number | undefined {
22
23
  const port = raw ? Number(raw) : Number.NaN
23
24
  if (!Number.isInteger(port) || port <= 0) {
24
25
  console.error(` invalid --port value: ${raw || '(missing)'}`)
25
- process.exit(1)
26
+ rnxExit(1)
26
27
  }
27
28
  return port
28
29
  }
@@ -53,14 +54,14 @@ examples:
53
54
  rnx desktop --port 5173
54
55
  rnx desktop --profile qa
55
56
  `)
56
- process.exit(0)
57
+ rnxExit(0)
57
58
  }
58
59
 
59
60
  const profileArg = args.find((_, i) => args[i - 1] === '--profile')
60
61
  const ephemeralProfile = args.includes('--ephemeral')
61
62
  if (profileArg && ephemeralProfile) {
62
63
  console.error(' rnx desktop: --profile cannot be combined with --ephemeral')
63
- process.exit(1)
64
+ rnxExit(1)
64
65
  }
65
66
  const profileId = profileArg ? ensureProfile(profileArg).id : undefined
66
67
  let install = findDesktopCompanion()
@@ -76,7 +77,7 @@ examples:
76
77
  await runInstallDesktop(['--yes'])
77
78
  install = findDesktopCompanion()
78
79
  }
79
- if (!install) process.exit(1)
80
+ if (!install) rnxExit(1)
80
81
  }
81
82
  console.log(` launching ${install.path}`)
82
83
 
@@ -89,7 +90,7 @@ examples:
89
90
  })
90
91
  if (!result.launched) {
91
92
  console.error(` ${result.message}`)
92
- process.exit(1)
93
+ rnxExit(1)
93
94
  }
94
95
  console.log(` ${result.message}`)
95
96
  }
@@ -23,6 +23,7 @@ import {
23
23
  keepFlowCandidate,
24
24
  startFlowSession,
25
25
  } from '../flow-session'
26
+ import { rnxExit } from '../run-rnx'
26
27
  import { createBridge, createBridgeFromParsed, parseBridgeCliArgs } from '../ws-bridge'
27
28
  import {
28
29
  buildShellUrl,
@@ -176,13 +177,13 @@ flow extension:
176
177
  path: marketing/hero
177
178
  withFrame: true
178
179
  `)
179
- process.exit(0)
180
+ rnxExit(0)
180
181
  }
181
182
 
182
183
  const flowPath = args[0]
183
184
  if (!fs.existsSync(flowPath)) {
184
185
  console.error(` error: ${flowPath} not found`)
185
- process.exit(1)
186
+ rnxExit(1)
186
187
  }
187
188
 
188
189
  const getFlag = (name: string) => args.find((_, i) => args[i - 1] === name)
@@ -240,7 +241,7 @@ flow extension:
240
241
  : ''
241
242
  if (previewBillingKind && previewBillingKind !== 'test_run') {
242
243
  console.error(` error: invalid --billing-kind: ${previewBillingKind}`)
243
- process.exit(1)
244
+ rnxExit(1)
244
245
  }
245
246
  const replaceArgs = args.flatMap((arg, index) =>
246
247
  args[index - 1] === '--replace' ? ['--replace', arg] : [],
@@ -271,7 +272,7 @@ flow extension:
271
272
  const { frontmatter, steps } = parseFlowFile(flowContent)
272
273
  if (steps.length === 0) {
273
274
  console.error(' error: flow file must contain a YAML array of steps')
274
- process.exit(1)
275
+ rnxExit(1)
275
276
  }
276
277
  const targetDevice = deviceOverride || frontmatter.device || ''
277
278
  const targetTheme = frontmatter.theme || ''
@@ -323,7 +324,7 @@ flow extension:
323
324
  console.error(
324
325
  ' error: desktop companion not found. install or build it first with `bun run build:electron`',
325
326
  )
326
- process.exit(1)
327
+ rnxExit(1)
327
328
  }
328
329
 
329
330
  const mode = wantElectron ? 'desktop companion' : 'bridge'
@@ -371,7 +372,7 @@ flow extension:
371
372
  const discovered = await discoverSootsimUrl()
372
373
  if (!discovered) {
373
374
  console.error(' error: no current sim and no sootsim target found')
374
- process.exit(1)
375
+ rnxExit(1)
375
376
  }
376
377
  openTarget = discovered
377
378
  }
@@ -934,7 +935,7 @@ async function runFlowSession(args: string[]) {
934
935
  const result = keepFlowCandidate()
935
936
  if (!result.active) {
936
937
  console.error(' no active flow draft — run `sootsim maestro start` first')
937
- process.exit(1)
938
+ rnxExit(1)
938
939
  }
939
940
  if (!result.kept) {
940
941
  console.log(' no pending action to keep')
@@ -963,7 +964,7 @@ async function runFlowSession(args: string[]) {
963
964
  )
964
965
  if (!result.active) {
965
966
  console.error(' no active flow draft — run `sootsim maestro start` first')
966
- process.exit(1)
967
+ rnxExit(1)
967
968
  }
968
969
  if (!result.valid) {
969
970
  console.error(' flow draft is not valid:')
@@ -971,7 +972,7 @@ async function runFlowSession(args: string[]) {
971
972
  console.error(
972
973
  ' draft preserved — keep at least one real interaction or run `sootsim maestro start` to reset',
973
974
  )
974
- process.exit(1)
975
+ rnxExit(1)
975
976
  }
976
977
 
977
978
  if (validate) {
@@ -1016,13 +1017,13 @@ async function runFlowSession(args: string[]) {
1016
1017
  const flowPath = args[1]
1017
1018
  if (!flowPath || flowPath.startsWith('-')) {
1018
1019
  console.error(' usage: sootsim maestro validate <path>')
1019
- process.exit(1)
1020
+ rnxExit(1)
1020
1021
  }
1021
1022
  const issues = validateFlowFile(flowPath)
1022
1023
  if (issues.length > 0) {
1023
1024
  console.error(` x ${flowPath} failed validation:`)
1024
1025
  for (const issue of issues) console.error(` - ${issue}`)
1025
- process.exit(1)
1026
+ rnxExit(1)
1026
1027
  }
1027
1028
  console.log(` + ${flowPath} looks valid`)
1028
1029
  return
@@ -1,4 +1,5 @@
1
1
  import { maybeHint } from '../../hints'
2
+ import { rnxExit } from '../../run-rnx'
2
3
  import { inspectFind, inspectNodeCount, rankInteractive, tapCommandForNode } from './core'
3
4
  import { printJson, wantsJson } from './shared'
4
5
  import type { WsBridge } from '../../ws-bridge'
@@ -56,7 +57,7 @@ export async function runFindSubcommand(opts: {
56
57
  '<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets',
57
58
  ),
58
59
  )
59
- process.exit(1)
60
+ rnxExit(1)
60
61
  }
61
62
  const { mode, result } = found
62
63
  const jsonOut = wantsJson(args)
@@ -5,6 +5,7 @@
5
5
  // id (if any). reads from `__sootsimKeyboard.getLayout()`, which is
6
6
  // populated by shell-worker `keyboard.layout` broadcasts.
7
7
 
8
+ import { rnxExit } from '../../run-rnx'
8
9
  import { inspectKeyboard } from './core'
9
10
  import type { WsBridge } from '../../ws-bridge'
10
11
 
@@ -16,7 +17,7 @@ export async function runKeyboardSubcommand(
16
17
 
17
18
  if ('error' in result) {
18
19
  console.error(result.error)
19
- process.exit(1)
20
+ rnxExit(1)
20
21
  }
21
22
 
22
23
  if (opts.json) {
@@ -1,3 +1,4 @@
1
+ import { rnxExit } from '../../run-rnx'
1
2
  import { sleep } from './shared'
2
3
 
3
4
  export async function runSleepSubcommand(opts: {
@@ -7,7 +8,7 @@ export async function runSleepSubcommand(opts: {
7
8
  const seconds = opts.positional[1] ? Number(opts.positional[1]) : 0.5
8
9
  if (!Number.isFinite(seconds) || seconds < 0) {
9
10
  console.error(opts.inspectUsage('sleep', '[seconds]'))
10
- process.exit(1)
11
+ rnxExit(1)
11
12
  }
12
13
  await sleep(seconds * 1000)
13
14
  console.log(` slept ${seconds}s`)
@@ -20,6 +20,7 @@
20
20
  // human-paced UI events we care about and stays compatible with the
21
21
  // existing query surface.
22
22
 
23
+ import { rnxExit } from '../../run-rnx'
23
24
  import type { WsBridge } from '../../ws-bridge'
24
25
  import type {
25
26
  SootSimTimelineEvent,
@@ -120,7 +121,7 @@ export async function runWaitEventSubcommand(opts: WaitEventOptions): Promise<vo
120
121
  '<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]',
121
122
  ),
122
123
  )
123
- process.exit(1)
124
+ rnxExit(1)
124
125
  }
125
126
  if (!KNOWN_KINDS.has(kind)) {
126
127
  console.error(
@@ -171,7 +172,7 @@ export async function runWaitEventSubcommand(opts: WaitEventOptions): Promise<vo
171
172
  console.error(
172
173
  ` could not query timeline: ${result && 'error' in result ? result.error : 'unknown'}`,
173
174
  )
174
- process.exit(1)
175
+ rnxExit(1)
175
176
  }
176
177
  const evts = result.result.events ?? []
177
178
  for (const ev of evts) {
@@ -206,5 +207,5 @@ export async function runWaitEventSubcommand(opts: WaitEventOptions): Promise<vo
206
207
  ` ⚠ wait event ${kind} timed out after ${elapsed}ms${filter ? ` (filter: ${filter})` : ''}${equals ? ` (equals: ${equals})` : ''}`,
207
208
  )
208
209
  }
209
- process.exit(1)
210
+ rnxExit(1)
210
211
  }
@@ -1,3 +1,4 @@
1
+ import { rnxExit } from '../../run-rnx'
1
2
  import { resolveMaxMsFlag } from './core'
2
3
  import { waitForSootsimIdle } from './settling'
3
4
  import type { WsBridge } from '../../ws-bridge'
@@ -19,6 +20,6 @@ export async function runWaitIdleSubcommand(opts: {
19
20
  console.log(` idle in ${elapsed}ms`)
20
21
  } else {
21
22
  console.error(` ⚠ wait idle timed out after ${elapsed}ms (may still be animating)`)
22
- process.exit(1)
23
+ rnxExit(1)
23
24
  }
24
25
  }
@@ -1,3 +1,4 @@
1
+ import { rnxExit } from '../../run-rnx'
1
2
  import { inspectWaitReady, resolveMaxMsFlag, waitReadyReason } from './core'
2
3
  import { waitForSootsimIdle } from './settling'
3
4
  import type { WsBridge } from '../../ws-bridge'
@@ -51,7 +52,7 @@ export async function runWaitReadySubcommand(opts: {
51
52
  console.error(
52
53
  ` ⚠ wait ready timed out after ${elapsedMs + idle.elapsed}ms — app mounted but did not settle (nodes: ${nodes}, targets: ${targets})`,
53
54
  )
54
- process.exit(1)
55
+ rnxExit(1)
55
56
  }
56
57
  console.log(
57
58
  ` ready in ${elapsedMs + idle.elapsed}ms: ${nodes} nodes, ${targets} targets${liveFrameActive ? `, ${liveFrameChannels} live surfaces` : ''}`,
@@ -70,5 +71,5 @@ export async function runWaitReadySubcommand(opts: {
70
71
  console.error(
71
72
  ` ⚠ wait ready timed out after ${elapsedMs}ms — ${reason} (nodes: ${nodes}, targets: ${targets}, live surfaces: ${liveFrameActive ? liveFrameChannels : 0}, errors: ${errors})`,
72
73
  )
73
- process.exit(1)
74
+ rnxExit(1)
74
75
  }
@@ -1,3 +1,4 @@
1
+ import { rnxExit } from '../../run-rnx'
1
2
  import { inspectWaitSelector } from './core'
2
3
  import type { WsBridge } from '../../ws-bridge'
3
4
 
@@ -14,7 +15,7 @@ export async function runWaitSelectorSubcommand(opts: {
14
15
  const testId = positional[1]
15
16
  if (!testId) {
16
17
  console.error(inspectUsage('selector', '<testid> [--max-ms 5000] [--gone]'))
17
- process.exit(1)
18
+ rnxExit(1)
18
19
  }
19
20
  const maxMsIdx = args.indexOf('--max-ms')
20
21
  const timeoutMs =
@@ -32,7 +33,7 @@ export async function runWaitSelectorSubcommand(opts: {
32
33
  console.error(
33
34
  ` ⚠ wait selector #${testId} --gone timed out after ${elapsed ?? timeoutMs}ms (still present)`,
34
35
  )
35
- process.exit(1)
36
+ rnxExit(1)
36
37
  }
37
38
  return
38
39
  }
@@ -45,6 +46,6 @@ export async function runWaitSelectorSubcommand(opts: {
45
46
  console.error(
46
47
  ` ⚠ wait selector #${testId} timed out after ${elapsed ?? timeoutMs}ms`,
47
48
  )
48
- process.exit(1)
49
+ rnxExit(1)
49
50
  }
50
51
  }
@@ -1,4 +1,5 @@
1
1
  import { rememberFlowCandidate } from '../../flow-session'
2
+ import { rnxExit } from '../../run-rnx'
2
3
  import { waitForSimReady } from './shared'
3
4
 
4
5
  export async function runWaitSubcommand(opts: {
@@ -19,7 +20,7 @@ export async function runWaitSubcommand(opts: {
19
20
  })
20
21
  if (!ready) {
21
22
  console.error(` timed out waiting for sim reconnect`)
22
- process.exit(1)
23
+ rnxExit(1)
23
24
  }
24
25
  ready.bridge.close()
25
26
  rememberFlowCandidate({