rnxsim 0.1.368 → 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 (256) 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 +49 -16
  7. package/cli/commands/compat.ts +93 -4
  8. package/cli/commands/config.ts +2 -1
  9. package/cli/commands/control.ts +37 -33
  10. package/cli/commands/daemon.ts +22 -21
  11. package/cli/commands/debug.ts +17 -15
  12. package/cli/commands/detect.ts +11 -7
  13. package/cli/commands/detox.ts +5 -4
  14. package/cli/commands/device.ts +6 -5
  15. package/cli/commands/electron.ts +6 -5
  16. package/cli/commands/flow.ts +12 -11
  17. package/cli/commands/inspect/find.ts +2 -1
  18. package/cli/commands/inspect/keyboard.ts +2 -1
  19. package/cli/commands/inspect/sleep.ts +2 -1
  20. package/cli/commands/inspect/wait-event.ts +4 -3
  21. package/cli/commands/inspect/wait-idle.ts +2 -1
  22. package/cli/commands/inspect/wait-ready.ts +3 -2
  23. package/cli/commands/inspect/wait-selector.ts +4 -3
  24. package/cli/commands/inspect/wait.ts +2 -1
  25. package/cli/commands/inspect.ts +82 -80
  26. package/cli/commands/install-desktop.ts +5 -4
  27. package/cli/commands/login.ts +3 -2
  28. package/cli/commands/mode.ts +2 -1
  29. package/cli/commands/record.ts +38 -37
  30. package/cli/commands/runtime.ts +9 -8
  31. package/cli/commands/screenshot-layers.ts +4 -3
  32. package/cli/commands/screenshot-mode.ts +2 -1
  33. package/cli/commands/screenshot.ts +8 -7
  34. package/cli/commands/screenshots-capture.ts +2 -1
  35. package/cli/commands/serve.ts +5 -4
  36. package/cli/commands/shell-boolean-mode.ts +2 -1
  37. package/cli/commands/skills.ts +11 -10
  38. package/cli/commands/telemetry.ts +2 -1
  39. package/cli/commands/three-mode.ts +2 -1
  40. package/cli/commands/timeline.ts +4 -3
  41. package/cli/commands/upload.ts +14 -13
  42. package/cli/commands/what-happened.ts +2 -1
  43. package/cli/recording-access.ts +6 -5
  44. package/cli/run-rnx.ts +140 -0
  45. package/dist-cli/bin.js +6 -6
  46. package/dist-cli/chunks/{agent-GXCQMYV4.js → agent-3R4424LW.js} +2 -2
  47. package/dist-cli/chunks/{agent-wrapper-Y3PQAL6I.js → agent-wrapper-4PPWZWSY.js} +2 -2
  48. package/dist-cli/chunks/app-fonts-KYXB6CXQ.js +4 -0
  49. package/dist-cli/chunks/{assert-BSRQBRH7.js → assert-7EZOWGYQ.js} +11 -11
  50. package/dist-cli/chunks/auth-L7M36H6C.js +12 -0
  51. package/dist-cli/chunks/{beta-R4IZ5SWO.js → beta-FKAF6YWJ.js} +2 -2
  52. package/dist-cli/chunks/{box-2NQYYY3B.js → box-5Y5VBMHV.js} +62 -62
  53. package/dist-cli/chunks/{camera-ER66WWAX.js → camera-XHF2RPFG.js} +2 -2
  54. package/dist-cli/chunks/{chunk-UBH2BWCY.js → chunk-2FOGXVOK.js} +2 -2
  55. package/dist-cli/chunks/{chunk-7B22IPSC.js → chunk-3BG6UCQY.js} +2 -2
  56. package/dist-cli/chunks/{chunk-IXRVFQMT.js → chunk-3SOPYG7S.js} +2 -2
  57. package/dist-cli/chunks/{chunk-7V3S2DY2.js → chunk-3UXXYJVD.js} +1 -1
  58. package/dist-cli/chunks/{chunk-3MPFC3DS.js → chunk-5BR33NAZ.js} +1 -1
  59. package/dist-cli/chunks/{chunk-BWJOLJOK.js → chunk-5RKRVS5A.js} +2 -2
  60. package/dist-cli/chunks/{chunk-WVVAYLWZ.js → chunk-64JAEJ6N.js} +1 -1
  61. package/dist-cli/chunks/{chunk-GXHCJRKE.js → chunk-6A6L3VJR.js} +2 -2
  62. package/dist-cli/chunks/chunk-6GPS7U4X.js +74 -0
  63. package/dist-cli/chunks/{chunk-JHYXRORU.js → chunk-6S5LJV2O.js} +2 -2
  64. package/dist-cli/chunks/{chunk-TOE5O6JE.js → chunk-6W4HIWC7.js} +2 -2
  65. package/dist-cli/chunks/{chunk-ESVUVW3R.js → chunk-72S5FCBY.js} +2 -2
  66. package/dist-cli/chunks/{chunk-TC6DNQL6.js → chunk-7C7TJYZ3.js} +2 -2
  67. package/dist-cli/chunks/{chunk-M7COA4BE.js → chunk-AALKIAUZ.js} +1 -1
  68. package/dist-cli/chunks/{chunk-CKNNO6ZG.js → chunk-ARMXC3C3.js} +25 -25
  69. package/dist-cli/chunks/chunk-AVJBT5LF.js +4 -0
  70. package/dist-cli/chunks/chunk-BMIJZNKD.js +28 -0
  71. package/dist-cli/chunks/{chunk-FSPZY4AI.js → chunk-C7BA5CCM.js} +2 -2
  72. package/dist-cli/chunks/{chunk-EHA65UVJ.js → chunk-CMVRTZ5G.js} +2 -2
  73. package/dist-cli/chunks/chunk-D24EOJ4C.js +24 -0
  74. package/dist-cli/chunks/{chunk-3XMEIZEV.js → chunk-D2GZASRV.js} +1 -1
  75. package/dist-cli/chunks/{chunk-3S2J6IVC.js → chunk-DHYTRCIP.js} +2 -2
  76. package/dist-cli/chunks/{chunk-QMVBWZH2.js → chunk-DMHSD6YJ.js} +2 -2
  77. package/dist-cli/chunks/{chunk-NGWUGNPV.js → chunk-DUXHYPBP.js} +2 -2
  78. package/dist-cli/chunks/{chunk-4FLQYRGN.js → chunk-DXV37CJN.js} +1 -1
  79. package/dist-cli/chunks/{chunk-T2MGLXY5.js → chunk-EOIBLKZO.js} +2 -2
  80. package/dist-cli/chunks/{chunk-PNBQBBG5.js → chunk-EQ3OE2AV.js} +1 -1
  81. package/dist-cli/chunks/{chunk-WFAFAGMG.js → chunk-EWSWOWXK.js} +2 -2
  82. package/dist-cli/chunks/{chunk-HKQXGCQT.js → chunk-FA75F34Z.js} +1 -1
  83. package/dist-cli/chunks/{chunk-NERY6HGZ.js → chunk-FK4JSTZ3.js} +2 -2
  84. package/dist-cli/chunks/{chunk-NPSPWMBO.js → chunk-GJRLPJQL.js} +2 -2
  85. package/dist-cli/chunks/{chunk-TPIPKXJL.js → chunk-GRO74J2X.js} +1 -1
  86. package/dist-cli/chunks/chunk-H5X5FJ63.js +99 -0
  87. package/dist-cli/chunks/chunk-HEKHLQ3B.js +497 -0
  88. package/dist-cli/chunks/chunk-HQQTS2CB.js +30 -0
  89. package/dist-cli/chunks/{chunk-Q65KH25G.js → chunk-I52NT6VG.js} +1 -1
  90. package/dist-cli/chunks/{chunk-AUPJX4KI.js → chunk-IDLFVRPN.js} +1 -1
  91. package/dist-cli/chunks/{chunk-LAKWOJ5Y.js → chunk-JZLDHPB7.js} +2 -2
  92. package/dist-cli/chunks/{chunk-WJQB6AXZ.js → chunk-LIMWG54N.js} +1 -1
  93. package/dist-cli/chunks/{chunk-TE645QCO.js → chunk-LUOHRBJG.js} +1 -1
  94. package/dist-cli/chunks/{chunk-DJSPNOF6.js → chunk-LXPHL6FO.js} +2 -2
  95. package/dist-cli/chunks/{chunk-ECXDCED5.js → chunk-MDCY532E.js} +2 -2
  96. package/dist-cli/chunks/{chunk-4VA2ISWX.js → chunk-NJMU5BN6.js} +1 -1
  97. package/dist-cli/chunks/{chunk-RRALQ4WM.js → chunk-NR2V2ONN.js} +2 -2
  98. package/dist-cli/chunks/{chunk-SHMLYTNH.js → chunk-NTC46LSA.js} +2 -2
  99. package/dist-cli/chunks/{chunk-X5MXQB3L.js → chunk-O6QLKSAM.js} +10 -10
  100. package/dist-cli/chunks/{chunk-LPAOOJIW.js → chunk-OJZHECGH.js} +1 -1
  101. package/dist-cli/chunks/chunk-OTFTMGAL.js +7 -0
  102. package/dist-cli/chunks/{chunk-QKOY7UW5.js → chunk-PAUEZO6F.js} +2 -2
  103. package/dist-cli/chunks/{chunk-WXRDFUR7.js → chunk-PIZXOXBL.js} +2 -2
  104. package/dist-cli/chunks/{chunk-WF2CRNYF.js → chunk-PNOENVMJ.js} +1 -1
  105. package/dist-cli/chunks/{chunk-FDAFSRQE.js → chunk-Q4MRJ6PO.js} +2 -2
  106. package/dist-cli/chunks/{chunk-SSUPPM6K.js → chunk-RRX52O37.js} +1 -1
  107. package/dist-cli/chunks/{chunk-E6XYIIJK.js → chunk-U63T6LIQ.js} +1 -1
  108. package/dist-cli/chunks/{chunk-OZJMWTGA.js → chunk-UFVAAWGZ.js} +1 -1
  109. package/dist-cli/chunks/{chunk-GS5VUDCF.js → chunk-VVQCZ42C.js} +1 -1
  110. package/dist-cli/chunks/{chunk-MCO7V4VN.js → chunk-WFQHT4QD.js} +2 -2
  111. package/dist-cli/chunks/{chunk-JFGW75UL.js → chunk-WPV4H5S4.js} +2 -2
  112. package/dist-cli/chunks/{chunk-OXCDE3DD.js → chunk-X6WQ4YWE.js} +1 -1
  113. package/dist-cli/chunks/{chunk-FVODUDPS.js → chunk-YIZGNT7A.js} +1 -1
  114. package/dist-cli/chunks/{chunk-MGOAQHMO.js → chunk-Z2VBSNFI.js} +2 -2
  115. package/dist-cli/chunks/{chunk-GFWUIGGY.js → chunk-Z3DENGXW.js} +2 -2
  116. package/dist-cli/chunks/{cleanup-WHGLBAJ2.js → cleanup-MXMMJ7JW.js} +2 -2
  117. package/dist-cli/chunks/cli-version-MLS55UTY.js +4 -0
  118. package/dist-cli/chunks/compat-E6KE5KDI.js +23 -0
  119. package/dist-cli/chunks/config-QSLLVZDS.js +13 -0
  120. package/dist-cli/chunks/{connect-N4FV3DDV.js → connect-QE4VU6GB.js} +2 -2
  121. package/dist-cli/chunks/control-XD5F6K5T.js +4 -0
  122. package/dist-cli/chunks/daemon-UN5SE2JO.js +4 -0
  123. package/dist-cli/chunks/{debug-AHEK43AJ.js → debug-5FG3MBJS.js} +20 -20
  124. package/dist-cli/chunks/desktop-5EZX7NX5.js +31 -0
  125. package/dist-cli/chunks/detox-WJGQP5TM.js +52 -0
  126. package/dist-cli/chunks/device-D7LKCAMS.js +18 -0
  127. package/dist-cli/chunks/{diagnose-WDP3CVIX.js → diagnose-A3W6ZTGA.js} +2 -2
  128. package/dist-cli/chunks/{disk-cleanup-JRT5MKFW.js → disk-cleanup-BDRHX5ZG.js} +2 -2
  129. package/dist-cli/chunks/{do-chain-7FDMO56C.js → do-chain-RUJNRPPF.js} +2 -2
  130. package/dist-cli/chunks/drivers-3NJ5RL6X.js +4 -0
  131. package/dist-cli/chunks/{env-YIBOMB24.js → env-U67SQVTV.js} +2 -2
  132. package/dist-cli/chunks/{film-R3EQADMG.js → film-XC6UAQ3V.js} +3 -3
  133. package/dist-cli/chunks/flow-FHZZD3P6.js +4 -0
  134. package/dist-cli/chunks/help-BYYDUSXF.js +4 -0
  135. package/dist-cli/chunks/{hidden-runtime-alias-6M4UERRQ.js → hidden-runtime-alias-7S2TNZXG.js} +2 -2
  136. package/dist-cli/chunks/{home-paths-QJNOHZJO.js → home-paths-LMO5LB4F.js} +2 -2
  137. package/dist-cli/chunks/inspect-RQCTWDCC.js +4 -0
  138. package/dist-cli/chunks/install-desktop-GOWXCQUE.js +4 -0
  139. package/dist-cli/chunks/login-JIU42S4C.js +26 -0
  140. package/dist-cli/chunks/{logout-VNJX2IEW.js → logout-JTAWQXZO.js} +2 -2
  141. package/dist-cli/chunks/{maestro-SQS2OS2D.js → maestro-TYBQYOGB.js} +3 -3
  142. package/dist-cli/chunks/{maestro-generate-GWVPISG5.js → maestro-generate-YLAGWVKE.js} +3 -3
  143. package/dist-cli/chunks/mode-DV24ZRZ6.js +26 -0
  144. package/dist-cli/chunks/{optional-demo-registry-L3LRBQHG.js → optional-demo-registry-JZH66VIM.js} +2 -2
  145. package/dist-cli/chunks/{perf-XLPC4UKR.js → perf-LXXJ4EAX.js} +2 -2
  146. package/dist-cli/chunks/{permissions-QRHWVMDP.js → permissions-KAOVZUPW.js} +2 -2
  147. package/dist-cli/chunks/{platform-F47URZNB.js → platform-KW35446W.js} +3 -3
  148. package/dist-cli/chunks/privacy-MIFE72CG.js +4 -0
  149. package/dist-cli/chunks/record-EK3ETFHZ.js +72 -0
  150. package/dist-cli/chunks/report-issue-NW5PCAZF.js +29 -0
  151. package/dist-cli/chunks/reset-RZ4O5AFJ.js +4 -0
  152. package/dist-cli/chunks/resolve-target-7R5BNYMM.js +4 -0
  153. package/dist-cli/chunks/runtime-MZHLSRS6.js +4 -0
  154. package/dist-cli/chunks/{screenshot-command-RK7IJHVK.js → screenshot-command-TQSPTFT2.js} +11 -11
  155. package/dist-cli/chunks/screenshot-layers-IZP3L3AQ.js +20 -0
  156. package/dist-cli/chunks/screenshots-capture-K7LJOVAE.js +42 -0
  157. package/dist-cli/chunks/{serve-UBXNGLNP.js → serve-MMX4WXXG.js} +18 -18
  158. package/dist-cli/chunks/setup-YFP3KEQZ.js +4 -0
  159. package/dist-cli/chunks/{sim-client-VTKFEDJX.js → sim-client-KLAYIFOC.js} +2 -2
  160. package/dist-cli/chunks/skills-N4D3POIS.js +50 -0
  161. package/dist-cli/chunks/{state-273XJPUE.js → state-ES6TFQZF.js} +2 -2
  162. package/dist-cli/chunks/{storage-RTDFWIY7.js → storage-52DR5V2C.js} +2 -2
  163. package/dist-cli/chunks/store-HOL45WCI.js +4 -0
  164. package/dist-cli/chunks/telemetry-BV6OTYPF.js +4 -0
  165. package/dist-cli/chunks/timeline-NRVNB5JR.js +24 -0
  166. package/dist-cli/chunks/{upgrade-R74NVHKG.js → upgrade-LNED5YQ2.js} +2 -2
  167. package/dist-cli/chunks/upload-RXKHFIBU.js +4 -0
  168. package/dist-cli/chunks/{version-RTFCYQZ7.js → version-VEF2DYGG.js} +2 -2
  169. package/dist-cli/chunks/{web-35SSKBRU.js → web-CGDE6S73.js} +2 -2
  170. package/dist-cli/chunks/welcome-FT2AMUWW.js +5 -0
  171. package/dist-cli/chunks/what-happened-FSIDWL32.js +25 -0
  172. package/dist-cli/chunks/{ws-bridge-JXQUAWFA.js → ws-bridge-QXFQLRE7.js} +2 -2
  173. package/dist-lib/agent-daemon-client.cjs +1 -1
  174. package/dist-lib/agent-events.cjs +1 -1
  175. package/dist-lib/agent-identity.cjs +1 -1
  176. package/dist-lib/agent-sessions.cjs +1 -1
  177. package/dist-lib/attached-projects.cjs +1 -1
  178. package/dist-lib/auth/shared-session.cjs +1 -1
  179. package/dist-lib/backend-origin.cjs +1 -1
  180. package/dist-lib/beta.cjs +1 -1
  181. package/dist-lib/beta.mjs +1 -1
  182. package/dist-lib/bridge-constants.cjs +1 -1
  183. package/dist-lib/bridge-contract-input.cjs +1 -1
  184. package/dist-lib/bridge-contract-input.mjs +1 -1
  185. package/dist-lib/bridge-contract.cjs +1 -1
  186. package/dist-lib/bridge-contract.mjs +1 -1
  187. package/dist-lib/cli-constants.cjs +1 -1
  188. package/dist-lib/config.cjs +1 -1
  189. package/dist-lib/detox/index.cjs +1 -1
  190. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  191. package/dist-lib/home-paths.cjs +1 -1
  192. package/dist-lib/host/bridge-host.cjs +1 -1
  193. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  194. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  195. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  196. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  197. package/dist-lib/host/websocket-proxy.cjs +1 -1
  198. package/dist-lib/index.cjs +1 -1
  199. package/dist-lib/jump-to-source-babel.cjs +1 -1
  200. package/dist-lib/menu.cjs +1 -1
  201. package/dist-lib/menu.mjs +1 -1
  202. package/dist-lib/metro-production-bundle.cjs +1 -1
  203. package/dist-lib/metro-production-bundle.mjs +1 -1
  204. package/dist-lib/metro.cjs +1 -1
  205. package/dist-lib/profiles.cjs +1 -1
  206. package/dist-lib/public-brand.cjs +1 -1
  207. package/dist-lib/react-native-host-modules.cjs +2 -1
  208. package/dist-lib/react-native-host-modules.mjs +2 -1
  209. package/dist-lib/render-mode.cjs +1 -1
  210. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  211. package/dist-lib/sdk.cjs +1 -1
  212. package/dist-lib/sdk.mjs +1 -1
  213. package/dist-lib/skills.cjs +560 -48
  214. package/dist-lib/vite.cjs +1 -1
  215. package/package.json +1 -1
  216. package/src/react-native-host-modules.ts +1 -0
  217. package/dist-cli/chunks/app-fonts-MDD3W4VN.js +0 -4
  218. package/dist-cli/chunks/auth-SLPHDPCF.js +0 -12
  219. package/dist-cli/chunks/chunk-2YK5J2D2.js +0 -24
  220. package/dist-cli/chunks/chunk-42TLK75A.js +0 -497
  221. package/dist-cli/chunks/chunk-57LITN73.js +0 -7
  222. package/dist-cli/chunks/chunk-T4ZZ26A2.js +0 -28
  223. package/dist-cli/chunks/chunk-UXROQPIN.js +0 -30
  224. package/dist-cli/chunks/chunk-YSHJ3LMQ.js +0 -74
  225. package/dist-cli/chunks/chunk-YYPTSF6W.js +0 -99
  226. package/dist-cli/chunks/cli-version-DMXIXBIM.js +0 -4
  227. package/dist-cli/chunks/compat-MGBKGYGQ.js +0 -20
  228. package/dist-cli/chunks/config-TRDOMP4T.js +0 -13
  229. package/dist-cli/chunks/control-5GRBZVYK.js +0 -4
  230. package/dist-cli/chunks/daemon-MBT5E3ZC.js +0 -4
  231. package/dist-cli/chunks/desktop-LDRIXOVV.js +0 -31
  232. package/dist-cli/chunks/detox-6HAKYISO.js +0 -52
  233. package/dist-cli/chunks/device-QM3S7OVU.js +0 -18
  234. package/dist-cli/chunks/drivers-AJL2EVXH.js +0 -4
  235. package/dist-cli/chunks/flow-BDAA6BWL.js +0 -4
  236. package/dist-cli/chunks/help-5EJD6LJF.js +0 -4
  237. package/dist-cli/chunks/inspect-S3LR3R2A.js +0 -4
  238. package/dist-cli/chunks/install-desktop-GXE6K7BJ.js +0 -4
  239. package/dist-cli/chunks/login-ISWDW4WU.js +0 -26
  240. package/dist-cli/chunks/mode-3URDGBZB.js +0 -26
  241. package/dist-cli/chunks/privacy-BF23T67T.js +0 -4
  242. package/dist-cli/chunks/record-2DN3OUE5.js +0 -72
  243. package/dist-cli/chunks/report-issue-D3BQPSLU.js +0 -29
  244. package/dist-cli/chunks/reset-T5CNZ7D3.js +0 -4
  245. package/dist-cli/chunks/resolve-target-KAAS274S.js +0 -4
  246. package/dist-cli/chunks/runtime-AQJDBR3X.js +0 -4
  247. package/dist-cli/chunks/screenshot-layers-DP2QKSMN.js +0 -20
  248. package/dist-cli/chunks/screenshots-capture-MA7P3FUT.js +0 -42
  249. package/dist-cli/chunks/setup-GH7OW4GC.js +0 -4
  250. package/dist-cli/chunks/skills-HPK25R4B.js +0 -50
  251. package/dist-cli/chunks/store-DLKNNM4L.js +0 -4
  252. package/dist-cli/chunks/telemetry-7CWDXEOO.js +0 -4
  253. package/dist-cli/chunks/timeline-IF2PGK7C.js +0 -24
  254. package/dist-cli/chunks/upload-3JFFVCZ4.js +0 -4
  255. package/dist-cli/chunks/welcome-N5V352SE.js +0 -5
  256. package/dist-cli/chunks/what-happened-WXTP6EPR.js +0 -25
@@ -17,6 +17,7 @@ import { rememberFlowCandidate } from '../flow-session'
17
17
  import { maybeHint } from '../hints'
18
18
  import { shouldPrintInspectNotice } from '../inspect-notice-state'
19
19
  import { TOP_LEVEL_RUNTIME_COMMANDS } from '../parse-args'
20
+ import { rethrowIfExit, rnxExit } from '../run-rnx'
20
21
  import {
21
22
  callInBridge,
22
23
  callInBridgeWrite,
@@ -829,12 +830,12 @@ async function requireVisualKeyboard(bridge: WsBridge, actionLabel: string) {
829
830
  console.error(
830
831
  ` ${actionLabel} requires a focused editable control. the iOS keyboard is visible, but no input owns focus.`,
831
832
  )
832
- process.exit(1)
833
+ rnxExit(1)
833
834
  }
834
835
  console.error(
835
836
  ` ${actionLabel} requires the iOS keyboard to be visible. focus an input first with rnx do tap-id/tap-text or rnx do type-into.`,
836
837
  )
837
- process.exit(1)
838
+ rnxExit(1)
838
839
  }
839
840
 
840
841
  async function runShellVisualCommand(
@@ -1132,7 +1133,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1132
1133
  const groupHelp = renderCliGroupHelp(invocationPrefix, docContext)
1133
1134
  if (groupHelp) {
1134
1135
  console.log(`${groupHelp}\n`)
1135
- process.exit(0)
1136
+ rnxExit(0)
1136
1137
  }
1137
1138
  }
1138
1139
 
@@ -1140,7 +1141,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1140
1141
  const shellHelp = renderCliCommandHelp('shell', docContext)
1141
1142
  if (shellHelp) {
1142
1143
  console.log(`${shellHelp}\n`)
1143
- process.exit(0)
1144
+ rnxExit(0)
1144
1145
  }
1145
1146
  }
1146
1147
 
@@ -1150,7 +1151,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1150
1151
  .filter((s): s is string => s != null)
1151
1152
  .join('\n\n')
1152
1153
  console.log(`${groupSections}\n`)
1153
- process.exit(0)
1154
+ rnxExit(0)
1154
1155
  }
1155
1156
 
1156
1157
  const wsPort = parsed.wsPort
@@ -1593,7 +1594,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1593
1594
  (args.includes('--verbose') || args.includes('-v')) && !args.includes('--json')
1594
1595
  if (invocationPrefix === 'do' && subcommand === 'shell') {
1595
1596
  console.error(' `rnx do shell` was removed. use `rnx shell ...` instead.')
1596
- process.exit(1)
1597
+ rnxExit(1)
1597
1598
  }
1598
1599
  if (writeCommands.has(subcommand)) {
1599
1600
  await checkSimHealth(bridge)
@@ -1804,7 +1805,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1804
1805
  console.error(
1805
1806
  ' samples an averaged color from the canvas. coords are logical rnx units.',
1806
1807
  )
1807
- process.exit(1)
1808
+ rnxExit(1)
1808
1809
  }
1809
1810
  const result = await bridge.send({
1810
1811
  type: 'evaluate',
@@ -1837,7 +1838,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1837
1838
  if (!matcher) {
1838
1839
  console.error(inspectUsage('node', '<matcher>'))
1839
1840
  console.error(' resolves testID, id, then text — dumps full node info as JSON')
1840
- process.exit(1)
1841
+ rnxExit(1)
1841
1842
  }
1842
1843
  // resolve in order: testID → id → text. first hit wins, includes the
1843
1844
  // resolved transform and a parent chain so agents can skip the usual
@@ -1940,11 +1941,11 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1940
1941
  if (target.mode === 'testid') {
1941
1942
  maybeHint('wait-selector-for-missing-testid', target.value)
1942
1943
  }
1943
- process.exit(1)
1944
+ rnxExit(1)
1944
1945
  }
1945
1946
  if (!isTapSuccess(outcome.result)) {
1946
1947
  printTapFailure(`${target.mode} "${target.value}"`, outcome)
1947
- process.exit(1)
1948
+ rnxExit(1)
1948
1949
  }
1949
1950
  const candidate = buildTapCandidateFromResult(
1950
1951
  payload.cx,
@@ -1970,7 +1971,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1970
1971
  console.error(
1971
1972
  inspectUsage('tap', '<testid> | <x> <y> | --testid <id> | --text <t>'),
1972
1973
  )
1973
- process.exit(1)
1974
+ rnxExit(1)
1974
1975
  }
1975
1976
  const result = await tapCoordinates(bridge, x, y)
1976
1977
  const candidate = buildTapCandidateFromResult(x, y, result)
@@ -2000,7 +2001,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2000
2001
  !Number.isFinite(stepMs)
2001
2002
  ) {
2002
2003
  console.error(inspectUsage(subcommand, '<x1> <y1> <x2> <y2> [steps] [stepMs]'))
2003
- process.exit(1)
2004
+ rnxExit(1)
2004
2005
  }
2005
2006
  const result = await performSingleStep(bridge, {
2006
2007
  type: 'drag',
@@ -2061,7 +2062,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2061
2062
  "<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]",
2062
2063
  ),
2063
2064
  )
2064
- process.exit(1)
2065
+ rnxExit(1)
2065
2066
  }
2066
2067
  const result = await performSingleStep(bridge, {
2067
2068
  type: 'pinch',
@@ -2098,7 +2099,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2098
2099
  const query = positional[1]
2099
2100
  if (!query) {
2100
2101
  console.error(inspectUsage('tap-text', '<text>'))
2101
- process.exit(1)
2102
+ rnxExit(1)
2102
2103
  }
2103
2104
 
2104
2105
  const findFlagValue = (name: string): string | null => {
@@ -2111,7 +2112,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2111
2112
  const nthIndex = nthArg !== null ? Number(nthArg) : null
2112
2113
  if (nthIndex !== null && !Number.isFinite(nthIndex)) {
2113
2114
  console.error(` --nth/--index requires an integer, got: ${nthArg}`)
2114
- process.exit(1)
2115
+ rnxExit(1)
2115
2116
  }
2116
2117
  const within = findFlagValue('--within')
2117
2118
  const roleFlag = findFlagValue('--role')
@@ -2129,7 +2130,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2129
2130
  ] as const) {
2130
2131
  if (val !== null && !Number.isFinite(Number(val))) {
2131
2132
  console.error(` ${flag} requires a number, got: ${val}`)
2132
- process.exit(1)
2133
+ rnxExit(1)
2133
2134
  }
2134
2135
  }
2135
2136
  const nearIdx = args.indexOf('--near')
@@ -2139,7 +2140,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2139
2140
  const ny = Number(args[nearIdx + 2])
2140
2141
  if (!Number.isFinite(nx) || !Number.isFinite(ny)) {
2141
2142
  console.error(' --near requires two numbers: --near <x> <y>')
2142
- process.exit(1)
2143
+ rnxExit(1)
2143
2144
  }
2144
2145
  near = { x: nx, y: ny }
2145
2146
  }
@@ -2164,7 +2165,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2164
2165
 
2165
2166
  if (payload?.error === 'bridge-not-ready') {
2166
2167
  console.error(' rnx test bridge not ready')
2167
- process.exit(1)
2168
+ rnxExit(1)
2168
2169
  }
2169
2170
 
2170
2171
  if (payload?.ambiguous) {
@@ -2213,23 +2214,23 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2213
2214
  console.error(
2214
2215
  ' --first keep the old pick-first-silently behavior',
2215
2216
  )
2216
- process.exit(2)
2217
+ rnxExit(2)
2217
2218
  }
2218
2219
 
2219
2220
  if (payload?.nthOutOfRange) {
2220
2221
  console.error(
2221
2222
  ` not found: nth ${payload.nth} of ${payload.total} match${payload.total === 1 ? '' : 'es'} for "${query}"`,
2222
2223
  )
2223
- process.exit(1)
2224
+ rnxExit(1)
2224
2225
  }
2225
2226
 
2226
2227
  if (!payload || typeof payload.cx !== 'number') {
2227
2228
  console.error(` not found: ${query}`)
2228
- process.exit(1)
2229
+ rnxExit(1)
2229
2230
  }
2230
2231
  if (!isTapSuccess(outcome.result)) {
2231
2232
  printTapFailure(`text "${query}"`, outcome)
2232
- process.exit(1)
2233
+ rnxExit(1)
2233
2234
  }
2234
2235
  const candidate = buildTapCandidateFromNode(
2235
2236
  query,
@@ -2289,7 +2290,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2289
2290
  const query = positional[1]
2290
2291
  if (!query) {
2291
2292
  console.error(inspectUsage('tap-best', '<query>'))
2292
- process.exit(1)
2293
+ rnxExit(1)
2293
2294
  }
2294
2295
  const outcome = await tapBest(bridge, query, { agent: isAgentEnv() })
2295
2296
  const payload = outcome.payload as
@@ -2312,22 +2313,22 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2312
2313
  console.error(
2313
2314
  ` tap-best: no testID or visible text matched "${query}". try \`rnx find --interactive-targets\` to list candidates.`,
2314
2315
  )
2315
- process.exit(1)
2316
+ rnxExit(1)
2316
2317
  }
2317
2318
  if ('error' in payload) {
2318
2319
  console.error(` ${payload.error}`)
2319
- process.exit(1)
2320
+ rnxExit(1)
2320
2321
  }
2321
2322
  if (payload.strategy === 'none') {
2322
2323
  console.error(
2323
2324
  ` tap-best: no testID or visible text matched "${query}". try \`rnx find --interactive-targets\` to list candidates.`,
2324
2325
  )
2325
- process.exit(1)
2326
+ rnxExit(1)
2326
2327
  }
2327
2328
  const node = payload.node
2328
2329
  if (!isTapSuccess(outcome.result)) {
2329
2330
  printTapFailure(`best "${query}"`, outcome)
2330
- process.exit(1)
2331
+ rnxExit(1)
2331
2332
  }
2332
2333
  const candidate = buildTapCandidateFromNode(
2333
2334
  query,
@@ -2367,7 +2368,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2367
2368
  const query = positional[1]
2368
2369
  if (!query) {
2369
2370
  console.error(inspectUsage('tap-id', '<id>'))
2370
- process.exit(1)
2371
+ rnxExit(1)
2371
2372
  }
2372
2373
 
2373
2374
  const outcome = await tapById(bridge, query, { agent: isAgentEnv() })
@@ -2378,11 +2379,11 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2378
2379
  // nearby testIDs in the live tree so the agent can pick the
2379
2380
  // intended one without dumping the whole tree first.
2380
2381
  await printSimilarTestIds(bridge, query)
2381
- process.exit(1)
2382
+ rnxExit(1)
2382
2383
  }
2383
2384
  if (!isTapSuccess(outcome.result)) {
2384
2385
  printTapFailure(`id "${query}"`, outcome)
2385
- process.exit(1)
2386
+ rnxExit(1)
2386
2387
  }
2387
2388
  const candidate = buildTapCandidateFromNode(
2388
2389
  query,
@@ -2426,7 +2427,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2426
2427
  const text = positional.slice(2).join(' ')
2427
2428
  if (!targetId || !text) {
2428
2429
  console.error(inspectUsage('type-into', '<id> <text>'))
2429
- process.exit(1)
2430
+ rnxExit(1)
2430
2431
  }
2431
2432
  // step 1: find the element
2432
2433
  const tiArg = JSON.stringify(targetId)
@@ -2451,7 +2452,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2451
2452
  })
2452
2453
  if (!tiPayload || typeof tiPayload.cx !== 'number') {
2453
2454
  console.error(` not found: ${targetId}`)
2454
- process.exit(1)
2455
+ rnxExit(1)
2455
2456
  }
2456
2457
  if (!tiPayload.isTextInput) {
2457
2458
  console.error(` warning: ${targetId} is not a text input (isTextInput: false)`)
@@ -2475,7 +2476,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2475
2476
  })
2476
2477
  if (!keyboardState.visible) {
2477
2478
  console.error(` keyboard did not open after tapping ${targetId}`)
2478
- process.exit(1)
2479
+ rnxExit(1)
2479
2480
  }
2480
2481
  // step 2.5: confirm the tap actually focused the requested input.
2481
2482
  // the keyboard being visible is necessary but not sufficient — a
@@ -2495,7 +2496,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2495
2496
  focusCheck.testID ?? focusCheck.id ?? null,
2496
2497
  )}. did the tap land on an outer Pressable wrapper?`,
2497
2498
  )
2498
- process.exit(1)
2499
+ rnxExit(1)
2499
2500
  }
2500
2501
  }
2501
2502
  // step 3: type through the visible keyboard so key pop animations render
@@ -2544,7 +2545,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2544
2545
  const text = positional.slice(1).join(' ')
2545
2546
  if (!text) {
2546
2547
  console.error(inspectUsage('type', '<text>'))
2547
- process.exit(1)
2548
+ rnxExit(1)
2548
2549
  }
2549
2550
  const keyboardState = await requireVisualKeyboard(bridge, 'type')
2550
2551
  await bridge.send({ type: 'keyboard', action: 'type', text })
@@ -2568,7 +2569,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2568
2569
  const name = positional[1]
2569
2570
  if (!name) {
2570
2571
  console.error(inspectUsage('key', '<name>'))
2571
- process.exit(1)
2572
+ rnxExit(1)
2572
2573
  }
2573
2574
  await requireVisualKeyboard(bridge, 'key')
2574
2575
  await bridge.send({ type: 'keyboard', action: 'press', text: name })
@@ -2581,7 +2582,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2581
2582
  const keys = positional.slice(1)
2582
2583
  if (keys.length === 0) {
2583
2584
  console.error(inspectUsage('key-sequence', '<key> [<key> ...]'))
2584
- process.exit(1)
2585
+ rnxExit(1)
2585
2586
  }
2586
2587
  await requireVisualKeyboard(bridge, 'key-sequence')
2587
2588
  for (const key of keys) {
@@ -2600,7 +2601,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2600
2601
  const codes = positional.slice(1)
2601
2602
  if (codes.length === 0) {
2602
2603
  console.error(inspectUsage('keycode', '<code> [<code> ...]'))
2603
- process.exit(1)
2604
+ rnxExit(1)
2604
2605
  }
2605
2606
  const keys = codes.map((code) => ({ code, key: keyCodeToVisualKey(code) }))
2606
2607
  const unsupported = keys.filter((entry) => !entry.key)
@@ -2608,7 +2609,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2608
2609
  console.error(
2609
2610
  ` unsupported keycode(s): ${unsupported.map((entry) => entry.code).join(', ')}`,
2610
2611
  )
2611
- process.exit(1)
2612
+ rnxExit(1)
2612
2613
  }
2613
2614
  await requireVisualKeyboard(bridge, 'keycode')
2614
2615
  for (const entry of keys) {
@@ -2627,7 +2628,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2627
2628
  const ch = positional[1]
2628
2629
  if (!ch) {
2629
2630
  console.error(inspectUsage('dispatch', '<char>'))
2630
- process.exit(1)
2631
+ rnxExit(1)
2631
2632
  }
2632
2633
  await bridge.send({ type: 'keyboard', action: 'dispatchKey', text: ch })
2633
2634
  await recordInspectAction(
@@ -2661,7 +2662,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2661
2662
  if (target.mode === 'testid') {
2662
2663
  maybeHint('wait-selector-for-missing-testid', target.value)
2663
2664
  }
2664
- process.exit(1)
2665
+ rnxExit(1)
2665
2666
  }
2666
2667
  x = resolved.x
2667
2668
  y = resolved.y
@@ -2671,7 +2672,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2671
2672
  console.error(
2672
2673
  inspectUsage('double-tap', '<testid> | <x> <y> [gapMs] | --testid <id>'),
2673
2674
  )
2674
- process.exit(1)
2675
+ rnxExit(1)
2675
2676
  }
2676
2677
  const waitMs = Math.max(0, Math.round(gapMs))
2677
2678
  const single = await performSingleStep(bridge, {
@@ -2708,7 +2709,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2708
2709
  if (target.mode === 'testid') {
2709
2710
  maybeHint('wait-selector-for-missing-testid', target.value)
2710
2711
  }
2711
- process.exit(1)
2712
+ rnxExit(1)
2712
2713
  }
2713
2714
  x = resolved.x
2714
2715
  y = resolved.y
@@ -2724,7 +2725,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2724
2725
  console.error(
2725
2726
  inspectUsage('long-press', '<testid> | <x> <y> [durationMs] | --testid <id>'),
2726
2727
  )
2727
- process.exit(1)
2728
+ rnxExit(1)
2728
2729
  }
2729
2730
  const roundedDurationMs = Math.max(0, Math.round(durationMs))
2730
2731
  const result = await bridge.send({
@@ -2764,13 +2765,13 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2764
2765
  console.error(
2765
2766
  inspectUsage('touch', '<down|move|up|cancel> <x> <y> [pointerId]'),
2766
2767
  )
2767
- process.exit(1)
2768
+ rnxExit(1)
2768
2769
  }
2769
2770
  if (phase !== 'cancel' && (!Number.isFinite(x) || !Number.isFinite(y))) {
2770
2771
  console.error(
2771
2772
  inspectUsage('touch', '<down|move|up|cancel> <x> <y> [pointerId]'),
2772
2773
  )
2773
- process.exit(1)
2774
+ rnxExit(1)
2774
2775
  }
2775
2776
  // the engine's perform executor emits the matching agent-cursor
2776
2777
  // action (tap for down, move for move) natively.
@@ -2808,12 +2809,12 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2808
2809
  if (!preset || !Number.isFinite(durationMs)) {
2809
2810
  console.error(inspectUsage('gesture', '<preset> [durationMs]'))
2810
2811
  console.error(` presets: ${GESTURE_PRESETS.join(', ')}`)
2811
- process.exit(1)
2812
+ rnxExit(1)
2812
2813
  }
2813
2814
  if (!(GESTURE_PRESETS as readonly string[]).includes(preset)) {
2814
2815
  console.error(` unknown gesture preset: ${preset}`)
2815
2816
  console.error(` presets: ${GESTURE_PRESETS.join(', ')}`)
2816
- process.exit(1)
2817
+ rnxExit(1)
2817
2818
  }
2818
2819
  const frame = await bridge.send({
2819
2820
  type: 'evaluate',
@@ -2930,7 +2931,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2930
2931
  '<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>',
2931
2932
  ),
2932
2933
  )
2933
- process.exit(1)
2934
+ rnxExit(1)
2934
2935
  }
2935
2936
  // look up node position first so agent cursor can animate there
2936
2937
  const scrollNode = await bridge.send({
@@ -3105,7 +3106,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3105
3106
  const id = positional[2]
3106
3107
  if (!id) {
3107
3108
  console.error(` usage: ${inspectCommand('state')} node <id>`)
3108
- process.exit(1)
3109
+ rnxExit(1)
3109
3110
  }
3110
3111
  result =
3111
3112
  (await callTestBridge(bridge, 'findByTestId', id)) ||
@@ -3116,7 +3117,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3116
3117
  const id = positional[2]
3117
3118
  if (!id) {
3118
3119
  console.error(` usage: ${inspectCommand('state')} scroll <id>`)
3119
- process.exit(1)
3120
+ rnxExit(1)
3120
3121
  }
3121
3122
  result = await callTestBridge(bridge, 'getScrollState', id)
3122
3123
  break
@@ -3126,7 +3127,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3126
3127
  const y = Number(positional[3])
3127
3128
  if (!Number.isFinite(x) || !Number.isFinite(y)) {
3128
3129
  console.error(` usage: ${inspectCommand('state')} scroll-hit <x> <y>`)
3129
- process.exit(1)
3130
+ rnxExit(1)
3130
3131
  }
3131
3132
  result = await callTestBridge(bridge, 'getScrollStateAt', x, y)
3132
3133
  break
@@ -3136,7 +3137,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3136
3137
  const y = Number(positional[3])
3137
3138
  if (!Number.isFinite(x) || !Number.isFinite(y)) {
3138
3139
  console.error(` usage: ${inspectCommand('state')} hit <x> <y>`)
3139
- process.exit(1)
3140
+ rnxExit(1)
3140
3141
  }
3141
3142
  result = await callTestBridge(bridge, 'debugHitAt', x, y)
3142
3143
  break
@@ -3146,7 +3147,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3146
3147
  const y = Number(positional[3])
3147
3148
  if (!Number.isFinite(x) || !Number.isFinite(y)) {
3148
3149
  console.error(` usage: ${inspectCommand('state')} gesture <x> <y>`)
3149
- process.exit(1)
3150
+ rnxExit(1)
3150
3151
  }
3151
3152
  result = await callTestBridge(bridge, 'debugGestureAt', x, y)
3152
3153
  break
@@ -3191,7 +3192,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3191
3192
  break
3192
3193
  default:
3193
3194
  console.error(` unknown state subcommand: ${stateCmd}`)
3194
- process.exit(1)
3195
+ rnxExit(1)
3195
3196
  }
3196
3197
  console.log(JSON.stringify(result, null, 2))
3197
3198
  break
@@ -3247,7 +3248,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3247
3248
  : '<home|switcher> [settleMs]',
3248
3249
  ),
3249
3250
  )
3250
- process.exit(1)
3251
+ rnxExit(1)
3251
3252
  }
3252
3253
 
3253
3254
  let ok = false
@@ -3260,7 +3261,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3260
3261
  console.error(
3261
3262
  inspectUsage('shell', 'launch <appId> [settleMs] [--clear-state]'),
3262
3263
  )
3263
- process.exit(1)
3264
+ rnxExit(1)
3264
3265
  }
3265
3266
  if (clearState) {
3266
3267
  await bridge.send({
@@ -3325,7 +3326,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3325
3326
  const appId = positional[2]
3326
3327
  if (!appId) {
3327
3328
  console.error(inspectUsage('shell', 'open-card <appId> [settleMs]'))
3328
- process.exit(1)
3329
+ rnxExit(1)
3329
3330
  }
3330
3331
  ok = !!(await callShellCommandWhenReady(
3331
3332
  bridge,
@@ -3358,7 +3359,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3358
3359
  const mode = positional[2]
3359
3360
  if (!mode || !['light', 'dark', 'auto', 'toggle'].includes(mode)) {
3360
3361
  console.error(inspectUsage('shell', 'appearance <light|dark|auto|toggle>'))
3361
- process.exit(1)
3362
+ rnxExit(1)
3362
3363
  }
3363
3364
  const result = await runShellVisualCommand(bridge, 'appearance', mode)
3364
3365
  ok = !!result?.ok
@@ -3376,7 +3377,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3376
3377
  state = { [shellCmd]: result }
3377
3378
  } else {
3378
3379
  console.error(` unknown shell subcommand: ${shellCmd}`)
3379
- process.exit(1)
3380
+ rnxExit(1)
3380
3381
  }
3381
3382
  console.log(JSON.stringify({ ok, settled, state }, null, 2))
3382
3383
  break
@@ -3620,7 +3621,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3620
3621
  ` ${inspectCommand('js')} SootSim.bridges.keyboard.type("hello")`,
3621
3622
  )
3622
3623
  console.error(` ${inspectCommand('js')} SootSim.state.root.children.length`)
3623
- process.exit(1)
3624
+ rnxExit(1)
3624
3625
  }
3625
3626
  // --tenant: evaluate inside the TENANT worker's global scope (guest
3626
3627
  // bundle, metro module table, compat stubs) via the test bridge's
@@ -3741,7 +3742,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3741
3742
  case 'perf': {
3742
3743
  if (invocationPrefix === 'debug' && !opts.internalPerfCommand) {
3743
3744
  console.error(' `rnx debug perf` was removed. use `rnx perf shell ...`.')
3744
- process.exit(1)
3745
+ rnxExit(1)
3745
3746
  }
3746
3747
  const perfCmd = positional[1]
3747
3748
  if (opts.internalPerfCommand === 'scroll') {
@@ -3772,7 +3773,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3772
3773
  const parsedLimit = limitValue === undefined ? 6000 : Number(limitValue)
3773
3774
  if (!Number.isFinite(parsedLimit) || parsedLimit < 120) {
3774
3775
  console.error(' error: --limit must be a number of at least 120')
3775
- process.exit(1)
3776
+ rnxExit(1)
3776
3777
  }
3777
3778
  const result = await bridge.send({
3778
3779
  type: 'evaluate',
@@ -3785,7 +3786,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3785
3786
  })
3786
3787
  if (result?.error) {
3787
3788
  console.error(` error: ${result.error}`)
3788
- process.exit(1)
3789
+ rnxExit(1)
3789
3790
  }
3790
3791
  console.log(
3791
3792
  ` scroll profiling started: perform consecutive swipes, then run '${inspectCommand('perf')} stop'`,
@@ -3803,7 +3804,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3803
3804
  })
3804
3805
  if (result?.error) {
3805
3806
  console.error(` error: ${result.error}`)
3806
- process.exit(1)
3807
+ rnxExit(1)
3807
3808
  }
3808
3809
  const trace: SootSimScrollPerformanceTrace = result
3809
3810
  if (wantsJson(effectiveArgs)) {
@@ -3844,7 +3845,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3844
3845
  break
3845
3846
  }
3846
3847
  console.error(` unknown scroll perf command: ${perfCmd}`)
3847
- process.exit(1)
3848
+ rnxExit(1)
3848
3849
  }
3849
3850
  if (!perfCmd || perfCmd === '--help' || perfCmd === '-h') {
3850
3851
  console.log(`
@@ -3885,7 +3886,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3885
3886
  })
3886
3887
  if (result?.error) {
3887
3888
  console.error(` error: ${result.error}`)
3888
- process.exit(1)
3889
+ rnxExit(1)
3889
3890
  }
3890
3891
  console.log(
3891
3892
  ` shell profiling started — interact with the app, then run '${inspectCommand('perf')} stop'`,
@@ -3910,7 +3911,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3910
3911
  ' (shell worker did not answer within 5s — is a sim loaded?)',
3911
3912
  )
3912
3913
  }
3913
- process.exit(1)
3914
+ rnxExit(1)
3914
3915
  }
3915
3916
  if (wantsJson(effectiveArgs)) {
3916
3917
  printJson(result)
@@ -3966,7 +3967,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3966
3967
  })
3967
3968
  if (result?.error) {
3968
3969
  console.error(` error: ${result.error}`)
3969
- process.exit(1)
3970
+ rnxExit(1)
3970
3971
  }
3971
3972
  if (wantsJson(effectiveArgs)) {
3972
3973
  printJson(result)
@@ -3999,7 +4000,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3999
4000
  ` use 'perf start' / 'perf stop' (worst frames are in the stop report).`,
4000
4001
  )
4001
4002
  }
4002
- process.exit(1)
4003
+ rnxExit(1)
4003
4004
  }
4004
4005
  break
4005
4006
  }
@@ -4104,12 +4105,12 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4104
4105
  const raw = positional[1]
4105
4106
  if (!raw || raw === '--help' || raw === '-h') {
4106
4107
  console.error(` usage: ${inspectCommand('animation')} <id>`)
4107
- process.exit(1)
4108
+ rnxExit(1)
4108
4109
  }
4109
4110
  const id = Number(raw)
4110
4111
  if (!Number.isFinite(id)) {
4111
4112
  console.error(` invalid id: ${raw}`)
4112
- process.exit(1)
4113
+ rnxExit(1)
4113
4114
  }
4114
4115
  const result = await callTestBridge(bridge, 'getAnimation', id)
4115
4116
  console.log(JSON.stringify(result, null, 2))
@@ -4120,12 +4121,12 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4120
4121
  const raw = positional[1]
4121
4122
  if (!raw || raw === '--help' || raw === '-h') {
4122
4123
  console.error(` usage: ${inspectCommand('stop-animation')} <id|all>`)
4123
- process.exit(1)
4124
+ rnxExit(1)
4124
4125
  }
4125
4126
  const target: number | 'all' = raw === 'all' ? 'all' : Number(raw)
4126
4127
  if (target !== 'all' && !Number.isFinite(target)) {
4127
4128
  console.error(` invalid id: ${raw}`)
4128
- process.exit(1)
4129
+ rnxExit(1)
4129
4130
  }
4130
4131
  const count = await callTestBridge<number>(bridge, 'stopAnimation', target)
4131
4132
  console.log(` stopped ${count ?? 0} animation(s)`)
@@ -4228,7 +4229,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4228
4229
  const id = positional[2]
4229
4230
  if (!id) {
4230
4231
  console.error(' usage: rnx network get <id>')
4231
- process.exit(1)
4232
+ rnxExit(1)
4232
4233
  }
4233
4234
  const entry = (await bridge.send({
4234
4235
  type: 'evaluate',
@@ -4240,7 +4241,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4240
4241
  })) as NetworkEntryPayload | null
4241
4242
  if (!entry) {
4242
4243
  console.error(` no entry with id ${id}`)
4243
- process.exit(1)
4244
+ rnxExit(1)
4244
4245
  }
4245
4246
  if (jsonOut) {
4246
4247
  console.log(JSON.stringify(entry, null, 2))
@@ -4259,7 +4260,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4259
4260
  ` invalid limit: ${sub} — \`network\` takes a numeric count (e.g. ${inspectCommand('network')} 100).\n` +
4260
4261
  ` to target a specific sim, use \`--sim ${sub}\` instead.`,
4261
4262
  )
4262
- process.exit(1)
4263
+ rnxExit(1)
4263
4264
  }
4264
4265
 
4265
4266
  const fetchEntries = async () => {
@@ -4428,7 +4429,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4428
4429
  ` invalid limit: ${sub} — \`logs\` takes a numeric count (e.g. ${inspectCommand('logs')} 100).\n` +
4429
4430
  ` to target a specific sim, use \`--sim ${sub}\` instead.`,
4430
4431
  )
4431
- process.exit(1)
4432
+ rnxExit(1)
4432
4433
  }
4433
4434
 
4434
4435
  const fetchEntries = () => inspectLogs(bridge)
@@ -4486,7 +4487,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4486
4487
 
4487
4488
  default:
4488
4489
  console.error(` unknown subcommand: ${subcommand}`)
4489
- process.exit(1)
4490
+ rnxExit(1)
4490
4491
  }
4491
4492
 
4492
4493
  // auto-settle after any write command so the next CLI call doesn't see
@@ -4529,6 +4530,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4529
4530
  }
4530
4531
  }
4531
4532
  } catch (err: any) {
4533
+ rethrowIfExit(err)
4532
4534
  const message = err instanceof Error ? err.message : String(err)
4533
4535
  console.error(` ${subcommand ?? 'rnx'} failed: ${message}`)
4534
4536
  const unknownSim = /^no sim connected with id ([^;]+)(?:; connected sims: .+)?$/.exec(
@@ -4589,7 +4591,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
4589
4591
  // ignore secondary request summary errors while already failing the command
4590
4592
  }
4591
4593
  }
4592
- process.exit(1)
4594
+ rnxExit(1)
4593
4595
  } finally {
4594
4596
  bridge.close()
4595
4597
  }