rnxsim 0.1.335 → 0.1.337

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 (272) hide show
  1. package/README.md +104 -76
  2. package/cli/auth.ts +2 -2
  3. package/cli/bin.ts +7 -3
  4. package/cli/bridge-flow-runner.ts +2 -2
  5. package/cli/commands/agent-wrapper.ts +1 -1
  6. package/cli/commands/agent.ts +12 -12
  7. package/cli/commands/app-fonts.ts +1 -1
  8. package/cli/commands/assert.ts +7 -7
  9. package/cli/commands/auth.ts +4 -4
  10. package/cli/commands/camera.ts +13 -13
  11. package/cli/commands/cleanup.ts +6 -6
  12. package/cli/commands/compat.ts +4 -4
  13. package/cli/commands/config.ts +2 -2
  14. package/cli/commands/control.ts +37 -43
  15. package/cli/commands/cpu-profile.ts +2 -2
  16. package/cli/commands/daemon-mac-app.ts +2 -2
  17. package/cli/commands/daemon.ts +12 -12
  18. package/cli/commands/debug.ts +22 -22
  19. package/cli/commands/desktop.ts +3 -3
  20. package/cli/commands/detox.ts +17 -17
  21. package/cli/commands/device.ts +9 -9
  22. package/cli/commands/diagnose.ts +11 -11
  23. package/cli/commands/electron.ts +7 -7
  24. package/cli/commands/film.ts +6 -6
  25. package/cli/commands/inspect/core.ts +6 -7
  26. package/cli/commands/inspect/find.ts +2 -2
  27. package/cli/commands/inspect.ts +36 -36
  28. package/cli/commands/install-desktop.ts +8 -8
  29. package/cli/commands/login.ts +6 -6
  30. package/cli/commands/maestro-generate.ts +2 -2
  31. package/cli/commands/maestro.ts +23 -23
  32. package/cli/commands/mode.ts +4 -4
  33. package/cli/commands/no-bridge-hint.ts +9 -9
  34. package/cli/commands/perf.ts +11 -11
  35. package/cli/commands/permissions.ts +5 -5
  36. package/cli/commands/profile.ts +11 -11
  37. package/cli/commands/react.ts +15 -15
  38. package/cli/commands/record.ts +15 -15
  39. package/cli/commands/report-issue.ts +2 -2
  40. package/cli/commands/reset.ts +2 -2
  41. package/cli/commands/runtime.ts +18 -18
  42. package/cli/commands/screenshot-mode.ts +5 -5
  43. package/cli/commands/screenshot.ts +12 -12
  44. package/cli/commands/screenshots-capture.ts +7 -7
  45. package/cli/commands/screenshots.ts +6 -6
  46. package/cli/commands/serve.ts +6 -6
  47. package/cli/commands/setup.ts +13 -15
  48. package/cli/commands/skills.ts +14 -14
  49. package/cli/commands/slides.ts +19 -23
  50. package/cli/commands/state.ts +2 -2
  51. package/cli/commands/storage.ts +3 -3
  52. package/cli/commands/telemetry.ts +1 -1
  53. package/cli/commands/three-mode.ts +16 -16
  54. package/cli/commands/timeline.ts +4 -4
  55. package/cli/commands/upgrade.ts +1 -1
  56. package/cli/commands/upload.ts +11 -11
  57. package/cli/commands/version.ts +3 -5
  58. package/cli/commands/what-happened.ts +11 -11
  59. package/cli/drivers/electron.ts +3 -3
  60. package/cli/hints.ts +8 -8
  61. package/cli/recording-access.ts +1 -1
  62. package/cli/ws-bridge.ts +5 -5
  63. package/dist-cli/bin.js +5 -5
  64. package/dist-cli/chunks/{agent-XSJMAFVA.js → agent-QQ3RJNRY.js} +14 -14
  65. package/dist-cli/chunks/{agent-wrapper-NFLJ5K64.js → agent-wrapper-M6SQSMRY.js} +3 -3
  66. package/dist-cli/chunks/app-fonts-F6NDV3XC.js +4 -0
  67. package/dist-cli/chunks/{assert-ILAXIYB5.js → assert-5VB3KQNK.js} +12 -12
  68. package/dist-cli/chunks/auth-PFXODKFN.js +12 -0
  69. package/dist-cli/chunks/{beta-TDR6UKJU.js → beta-WUWYHT4F.js} +2 -2
  70. package/dist-cli/chunks/camera-V3MMTKP7.js +33 -0
  71. package/dist-cli/chunks/{chunk-INBPUR4T.js → chunk-2ANFH72P.js} +11 -11
  72. package/dist-cli/chunks/chunk-2GIA5T6B.js +74 -0
  73. package/dist-cli/chunks/{chunk-GP6QEBZA.js → chunk-4FRSEZ7Z.js} +1 -1
  74. package/dist-cli/chunks/{chunk-USGOQ3YJ.js → chunk-4GXBZHNA.js} +2 -2
  75. package/dist-cli/chunks/{chunk-R3CMECGC.js → chunk-4HESY5E7.js} +4 -4
  76. package/dist-cli/chunks/{chunk-WKT7YM5Q.js → chunk-4VJEXQGD.js} +1 -1
  77. package/dist-cli/chunks/{chunk-FE6ZHPKD.js → chunk-5LJNNHZH.js} +1 -1
  78. package/dist-cli/chunks/{chunk-I2HQB5NN.js → chunk-5QXGSTYI.js} +2 -2
  79. package/dist-cli/chunks/{chunk-FJSHIWAM.js → chunk-5SHAOQHJ.js} +2 -2
  80. package/dist-cli/chunks/{chunk-CGZWLSYD.js → chunk-5UPRBMIG.js} +1 -1
  81. package/dist-cli/chunks/{chunk-ZTM2MKNI.js → chunk-5ZEFRPCC.js} +1 -1
  82. package/dist-cli/chunks/{chunk-RTD3CPDQ.js → chunk-6ART4XVJ.js} +23 -23
  83. package/dist-cli/chunks/{chunk-MTD6IAEA.js → chunk-6CAUT2LH.js} +1 -1
  84. package/dist-cli/chunks/{chunk-ZYHCWCMM.js → chunk-7ATIH7OU.js} +1 -1
  85. package/dist-cli/chunks/{chunk-RVUGKXJD.js → chunk-7Q4QKHMA.js} +1 -1
  86. package/dist-cli/chunks/{chunk-MTNIDSOA.js → chunk-ABK2V2PR.js} +1 -1
  87. package/dist-cli/chunks/{chunk-TL4DNDDY.js → chunk-B53ILAHI.js} +2 -2
  88. package/dist-cli/chunks/{chunk-POC3QTA6.js → chunk-BSSVLFZR.js} +2 -2
  89. package/dist-cli/chunks/chunk-BVOBXTPN.js +30 -0
  90. package/dist-cli/chunks/{chunk-4KC35DMK.js → chunk-CPDEUWL5.js} +2 -2
  91. package/dist-cli/chunks/{chunk-HNQLZZJA.js → chunk-DINU267S.js} +2 -2
  92. package/dist-cli/chunks/{chunk-DCDKJ4NC.js → chunk-DQQ4CZVC.js} +2 -2
  93. package/dist-cli/chunks/{chunk-JWAY6DIH.js → chunk-EDWN2HOO.js} +18 -18
  94. package/dist-cli/chunks/{chunk-3CS4EUMG.js → chunk-EWVG4A3B.js} +2 -2
  95. package/dist-cli/chunks/{chunk-RTEJXUXN.js → chunk-F3NKCQHM.js} +6 -6
  96. package/dist-cli/chunks/{chunk-M7CBQ5I4.js → chunk-GEAGFYKP.js} +1 -1
  97. package/dist-cli/chunks/chunk-GGNH44PZ.js +5 -0
  98. package/dist-cli/chunks/{chunk-YSUIYK6B.js → chunk-HAHJJJUC.js} +2 -2
  99. package/dist-cli/chunks/chunk-HPJ5EKIZ.js +4 -0
  100. package/dist-cli/chunks/{chunk-IN2PZBQD.js → chunk-IBTHGFKE.js} +2 -2
  101. package/dist-cli/chunks/{chunk-ZZWO6Y7X.js → chunk-J6BYRRZQ.js} +2 -2
  102. package/dist-cli/chunks/{chunk-6Y3PVPTF.js → chunk-JK4OZ2TQ.js} +5 -5
  103. package/dist-cli/chunks/{chunk-PO3TOAED.js → chunk-KGQAO25M.js} +2 -2
  104. package/dist-cli/chunks/{chunk-J7XFINJG.js → chunk-L6UUIQE7.js} +2 -2
  105. package/dist-cli/chunks/{chunk-35XNGT5C.js → chunk-LXYLCETR.js} +1 -1
  106. package/dist-cli/chunks/{chunk-JWK5WD44.js → chunk-LZAL3DMP.js} +2 -2
  107. package/dist-cli/chunks/{chunk-3ZDOPKHE.js → chunk-M43UU7UG.js} +4 -4
  108. package/dist-cli/chunks/{chunk-ROPHZJ6P.js → chunk-M4LGUVBM.js} +2 -2
  109. package/dist-cli/chunks/{chunk-RELRA5VW.js → chunk-NCG6C5AH.js} +2 -2
  110. package/dist-cli/chunks/{chunk-42KDXJUD.js → chunk-NR5TSR2Y.js} +2 -2
  111. package/dist-cli/chunks/{chunk-R2UL5VFY.js → chunk-OCPWXT73.js} +3 -3
  112. package/dist-cli/chunks/{chunk-VV4MXLFR.js → chunk-ODKS6JUJ.js} +1 -1
  113. package/dist-cli/chunks/{chunk-F33DUJGG.js → chunk-R2WBREGQ.js} +1 -1
  114. package/dist-cli/chunks/chunk-RKY3ZNTA.js +5 -0
  115. package/dist-cli/chunks/{chunk-MGGRL2Z2.js → chunk-SW7BHOMO.js} +9 -9
  116. package/dist-cli/chunks/{chunk-GVKISFQ3.js → chunk-TJTLXG3R.js} +1 -1
  117. package/dist-cli/chunks/chunk-TNI4PW75.js +124 -0
  118. package/dist-cli/chunks/{chunk-CL3PREIE.js → chunk-UWEDNDND.js} +2 -2
  119. package/dist-cli/chunks/{chunk-IV36DY6M.js → chunk-WRID5SBV.js} +1 -1
  120. package/dist-cli/chunks/{chunk-42ALI64M.js → chunk-WUYI3XJ5.js} +2 -2
  121. package/dist-cli/chunks/{chunk-6VN5ULGQ.js → chunk-X7MHCEGG.js} +2 -2
  122. package/dist-cli/chunks/chunk-XIQFYLWD.js +15 -0
  123. package/dist-cli/chunks/{chunk-LCVUJCRJ.js → chunk-ZUK5ZQU7.js} +1 -1
  124. package/dist-cli/chunks/{cleanup-X6ZRPFDV.js → cleanup-6WBS3MUO.js} +10 -10
  125. package/dist-cli/chunks/cli-version-HUQCDGMA.js +4 -0
  126. package/dist-cli/chunks/{compat-VRXJ5J56.js → compat-2WOPKJYK.js} +9 -9
  127. package/dist-cli/chunks/{config-LHPPE4EP.js → config-FPD7WUYB.js} +5 -5
  128. package/dist-cli/chunks/{control-TVTNGSSF.js → control-B3XNER7I.js} +2 -2
  129. package/dist-cli/chunks/daemon-T4D4X2P5.js +4 -0
  130. package/dist-cli/chunks/{debug-EUHBBPGM.js → debug-LKV5CEAV.js} +17 -17
  131. package/dist-cli/chunks/desktop-EMDPOYQT.js +31 -0
  132. package/dist-cli/chunks/detox-4J4UTZE7.js +52 -0
  133. package/dist-cli/chunks/{device-PONITUZJ.js → device-PMZ7RPXQ.js} +11 -11
  134. package/dist-cli/chunks/{diagnose-2PN4K4L2.js → diagnose-MLEP727D.js} +12 -12
  135. package/dist-cli/chunks/{disk-cleanup-U2PQLOEW.js → disk-cleanup-CVEDIPEE.js} +2 -2
  136. package/dist-cli/chunks/drivers-NTUKJEL6.js +4 -0
  137. package/dist-cli/chunks/{film-XGZCFTQL.js → film-4RNECABF.js} +9 -9
  138. package/dist-cli/chunks/flow-5IOCAHVO.js +4 -0
  139. package/dist-cli/chunks/help-NUJUYEWP.js +4 -0
  140. package/dist-cli/chunks/{hidden-runtime-alias-I4MYF5CO.js → hidden-runtime-alias-YIF25W4F.js} +2 -2
  141. package/dist-cli/chunks/{home-paths-YRAPZ5LE.js → home-paths-WNJCCCCZ.js} +2 -2
  142. package/dist-cli/chunks/inspect-MFEIYUCN.js +4 -0
  143. package/dist-cli/chunks/install-desktop-NB65KI4D.js +4 -0
  144. package/dist-cli/chunks/{login-ZMAIAQ6F.js → login-VEHHGN42.js} +6 -6
  145. package/dist-cli/chunks/{logout-UQZ5JBJU.js → logout-VE7PNXL2.js} +2 -2
  146. package/dist-cli/chunks/{maestro-BQYKDUC4.js → maestro-ZXHTDEOI.js} +25 -25
  147. package/dist-cli/chunks/{maestro-generate-VQYMMQJ5.js → maestro-generate-TK33E2Z6.js} +3 -3
  148. package/dist-cli/chunks/mode-ZDKJ56NT.js +26 -0
  149. package/dist-cli/chunks/{optional-demo-registry-DUWHCLGD.js → optional-demo-registry-GBZ3WVDW.js} +2 -2
  150. package/dist-cli/chunks/{perf-7RAU7WRZ.js → perf-JXNZOUKW.js} +28 -28
  151. package/dist-cli/chunks/permissions-WQ62PW7Y.js +13 -0
  152. package/dist-cli/chunks/record-4S3ZMDIO.js +72 -0
  153. package/dist-cli/chunks/{report-issue-P376KFFU.js → report-issue-KKBADTWO.js} +4 -4
  154. package/dist-cli/chunks/reset-H5XIISJE.js +4 -0
  155. package/dist-cli/chunks/runtime-FK7EEMWA.js +4 -0
  156. package/dist-cli/chunks/{screenshot-command-NE7BKTQ2.js → screenshot-command-42U5MVQL.js} +34 -34
  157. package/dist-cli/chunks/{screenshot-layers-UE4R64PZ.js → screenshot-layers-4G42AHOX.js} +2 -2
  158. package/dist-cli/chunks/{screenshots-capture-ULXPLXMC.js → screenshots-capture-HMQ2OO3I.js} +11 -11
  159. package/dist-cli/chunks/{serve-P7BT4XHR.js → serve-S4V5EDW2.js} +16 -16
  160. package/dist-cli/chunks/setup-T43V7GA6.js +32 -0
  161. package/dist-cli/chunks/{skills-NTRYKJSF.js → skills-O426K26J.js} +16 -16
  162. package/dist-cli/chunks/{state-4D5YAM47.js → state-ZEEPDKJG.js} +5 -5
  163. package/dist-cli/chunks/storage-4GQLOFGG.js +37 -0
  164. package/dist-cli/chunks/store-RFMSNWLJ.js +4 -0
  165. package/dist-cli/chunks/telemetry-NFAAPSMN.js +4 -0
  166. package/dist-cli/chunks/{timeline-GZNFGD3Q.js → timeline-ONCYX7KW.js} +6 -6
  167. package/dist-cli/chunks/{upgrade-A46D6PEY.js → upgrade-A36T52AM.js} +2 -2
  168. package/dist-cli/chunks/upload-36O32DII.js +4 -0
  169. package/dist-cli/chunks/version-67HA253N.js +6 -0
  170. package/dist-cli/chunks/{web-H2IXO5SC.js → web-PWXQHQIE.js} +2 -2
  171. package/dist-cli/chunks/{what-happened-Z7UII5GH.js → what-happened-WNXE622R.js} +16 -16
  172. package/dist-lib/agent-daemon-client.cjs +5 -5
  173. package/dist-lib/agent-events.cjs +1 -1
  174. package/dist-lib/agent-identity.cjs +1 -1
  175. package/dist-lib/agent-sessions.cjs +4 -4
  176. package/dist-lib/attached-projects.cjs +1 -1
  177. package/dist-lib/auth/shared-session.cjs +1 -1
  178. package/dist-lib/backend-origin.cjs +1 -1
  179. package/dist-lib/beta.cjs +1 -1
  180. package/dist-lib/beta.mjs +1 -1
  181. package/dist-lib/bridge-constants.cjs +1 -1
  182. package/dist-lib/bridge-contract.cjs +1 -1
  183. package/dist-lib/cli-constants.cjs +1 -1
  184. package/dist-lib/config.cjs +1 -1
  185. package/dist-lib/detox/index.cjs +1 -1
  186. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  187. package/dist-lib/home-paths.cjs +1 -1
  188. package/dist-lib/host/bridge-host.cjs +7 -7
  189. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  190. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  191. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  192. package/dist-lib/host/websocket-proxy.cjs +1 -1
  193. package/dist-lib/index.cjs +248 -98
  194. package/dist-lib/jump-to-source-babel.cjs +1 -1
  195. package/dist-lib/menu.cjs +2 -2
  196. package/dist-lib/menu.mjs +2 -2
  197. package/dist-lib/metro-host-modules/react-dom.js +6 -0
  198. package/dist-lib/metro-host-modules/react-native-web.js +6 -0
  199. package/dist-lib/metro-host-modules/react-native.js +6 -0
  200. package/dist-lib/metro-host-modules/react.js +6 -0
  201. package/dist-lib/metro-host-modules/react__jsx-dev-runtime.js +6 -0
  202. package/dist-lib/metro-host-modules/react__jsx-runtime.js +6 -0
  203. package/dist-lib/metro-production-bundle.cjs +72 -0
  204. package/dist-lib/metro-production-bundle.mjs +44 -0
  205. package/dist-lib/metro.cjs +152 -8
  206. package/dist-lib/profiles.cjs +1 -1
  207. package/dist-lib/public-brand.cjs +2 -2
  208. package/dist-lib/react-native-host-modules.cjs +50 -0
  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 +6 -7
  212. package/dist-lib/sdk.mjs +6 -7
  213. package/dist-lib/skills.cjs +71 -77
  214. package/dist-lib/vite.cjs +104 -85
  215. package/package.json +15 -2
  216. package/scripts/preuninstall.cjs +1 -1
  217. package/skills/contrast/SKILL.md +67 -75
  218. package/skills/rnx-debug/SKILL.md +84 -84
  219. package/skills/rnx-perf/SKILL.md +8 -8
  220. package/skills/rnx-setup/SKILL.md +54 -54
  221. package/skills/rnx-test/SKILL.md +35 -35
  222. package/skills/rnx-visual/SKILL.md +18 -18
  223. package/src/agent-daemon-client.ts +2 -2
  224. package/src/agent-sessions.ts +2 -2
  225. package/src/connect.ts +6 -6
  226. package/src/disk-cleanup.ts +1 -1
  227. package/src/home-paths.ts +1 -1
  228. package/src/host/bridge-host.ts +6 -6
  229. package/src/index.ts +1 -1
  230. package/src/metro-host-modules/react-dom.js +6 -0
  231. package/src/metro-host-modules/react-native-web.js +6 -0
  232. package/src/metro-host-modules/react-native.js +6 -0
  233. package/src/metro-host-modules/react.js +6 -0
  234. package/src/metro-host-modules/react__jsx-dev-runtime.js +6 -0
  235. package/src/metro-host-modules/react__jsx-runtime.js +6 -0
  236. package/src/metro-plugin.ts +249 -10
  237. package/src/metro-production-bundle.ts +51 -0
  238. package/src/public-brand.ts +1 -1
  239. package/src/react-native-host-modules.ts +25 -0
  240. package/src/runtime-assets.ts +1 -1
  241. package/src/sim-client.ts +1 -1
  242. package/src/vite-plugin-one.ts +171 -145
  243. package/dist-cli/chunks/app-fonts-L3UXFYVE.js +0 -4
  244. package/dist-cli/chunks/auth-ISX2EUQL.js +0 -12
  245. package/dist-cli/chunks/camera-4SWTNJUA.js +0 -33
  246. package/dist-cli/chunks/chunk-BRHZEZKN.js +0 -124
  247. package/dist-cli/chunks/chunk-EJPYPJWP.js +0 -5
  248. package/dist-cli/chunks/chunk-KWCD5MOK.js +0 -15
  249. package/dist-cli/chunks/chunk-MJ7QGY7Z.js +0 -4
  250. package/dist-cli/chunks/chunk-RSA4XWHN.js +0 -5
  251. package/dist-cli/chunks/chunk-S3EIOAWZ.js +0 -74
  252. package/dist-cli/chunks/chunk-TYANJQLO.js +0 -30
  253. package/dist-cli/chunks/cli-version-NZUSWKZR.js +0 -4
  254. package/dist-cli/chunks/daemon-XUEC47EC.js +0 -4
  255. package/dist-cli/chunks/desktop-LLHMP4A3.js +0 -31
  256. package/dist-cli/chunks/detox-QLNWLXA4.js +0 -52
  257. package/dist-cli/chunks/drivers-7IU37M2E.js +0 -4
  258. package/dist-cli/chunks/flow-NZZLR4BN.js +0 -4
  259. package/dist-cli/chunks/help-D7URIJRD.js +0 -4
  260. package/dist-cli/chunks/inspect-TJYWKY56.js +0 -4
  261. package/dist-cli/chunks/install-desktop-LD3W5RS7.js +0 -4
  262. package/dist-cli/chunks/mode-ZQ6H7KWM.js +0 -26
  263. package/dist-cli/chunks/permissions-DRZ3HCFL.js +0 -13
  264. package/dist-cli/chunks/record-J5JAYW4Y.js +0 -72
  265. package/dist-cli/chunks/reset-KXYRDEFU.js +0 -4
  266. package/dist-cli/chunks/runtime-66CEPOG6.js +0 -4
  267. package/dist-cli/chunks/setup-QO5KZAX3.js +0 -32
  268. package/dist-cli/chunks/storage-X2K2MDPX.js +0 -37
  269. package/dist-cli/chunks/store-TUJPIRTT.js +0 -4
  270. package/dist-cli/chunks/telemetry-CF5DVEKI.js +0 -4
  271. package/dist-cli/chunks/upload-UIQJIBEZ.js +0 -4
  272. package/dist-cli/chunks/version-CMBB3FXL.js +0 -6
@@ -3,11 +3,13 @@
3
3
  // bound to that directory across an active-runtime update.
4
4
  //
5
5
  // usage in vite.config.ts:
6
- // import { sootsimPlugin } from 'sootsim/vite'
7
- // export default { plugins: [one(), sootsimPlugin()] }
6
+ // import { rnxPlugin } from 'rnxsim/vite'
7
+ // export default { plugins: [one(), rnxPlugin()] }
8
8
 
9
+ import { spawn } from 'child_process'
9
10
  import fs from 'fs'
10
11
  import path from 'path'
12
+ import { fileURLToPath } from 'url'
11
13
  import { DEFAULT_SOOTSIM_BRIDGE_PORT } from './bridge-constants'
12
14
  import { isDaemonLockfileFresh, readDaemonLockfile } from './home-paths'
13
15
  import {
@@ -19,172 +21,196 @@ import {
19
21
  } from './runtime-assets'
20
22
  import type { Plugin } from 'vite'
21
23
 
22
- export interface SootSimPluginOptions {
24
+ export interface RnxPluginOptions {
23
25
  // custom bundle URL (default: auto-detect from One's metro)
24
26
  bundleUrl?: string
25
27
  // path prefix (default: '/__soot')
26
28
  prefix?: string
27
29
  // disable sootsim
28
30
  enabled?: boolean
31
+ // launch the sootsim simulator loading this server's bundle once the dev
32
+ // server is listening. skipped when CI or SOOTSIM_NO_OPEN is set.
33
+ open?: boolean
29
34
  }
30
35
 
31
- export function sootsimPlugin(options: SootSimPluginOptions = {}): Plugin[] {
32
- if (options.enabled === false) return []
33
-
36
+ export function rnxPlugin(options: RnxPluginOptions = {}): Plugin {
34
37
  const prefix = options.prefix || '/__soot'
35
38
 
36
- return [
37
- {
38
- name: 'sootsim-one',
39
-
40
- configureServer(server) {
41
- const bundleUrl =
42
- options.bundleUrl ||
43
- '/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false'
44
-
45
- // build the shell HTML, injecting the bundle URL (so main.tsx loads this
46
- // app's bundle) AND window.__sootsimBridgePort. the bridge-port injection
47
- // mirrors the dev-stack bridge-host: without it the engine's
48
- // resolveBridgePort() falls back to a location-derived guess that mis-maps
49
- // a non-Contrast app port (the mobile template's :4400 -> 9068) and the sim
50
- // can't reach the bridge. resolved per-request from the daemon lockfile
51
- // (the CLI's `open` writes/uses it before the shell loads) so the engine
52
- // targets the SAME bridge the CLI does; default port otherwise.
53
- const buildShellHtml = (runtimeRoot: string): string => {
54
- const html = fs.readFileSync(path.join(runtimeRoot, 'index.html'), 'utf8')
55
- const lock = readDaemonLockfile()
56
- const bridgePort =
57
- lock && isDaemonLockfileFresh(lock) && lock.bridgePort > 0
58
- ? lock.bridgePort
59
- : DEFAULT_SOOTSIM_BRIDGE_PORT
60
- // inject the bridge port + a default bundle (only when the URL has none,
61
- // so the CLI's resolved bundle wins), and PRESERVE the existing query.
62
- // preserving the query is essential: `sootsim open` stamps the open URL
63
- // with `inspectOpen=<token>` and matches the registered sim by that
64
- // token (waitForSimMatch). the old code forced `?bundle=` only and
65
- // stripped inspectOpen, so the sim registered but never matched and
66
- // `open` timed out after 60s.
67
- const inject =
68
- `<script>(function(){var u=new URL(location.href);` +
69
- `if(!u.searchParams.has('bundle'))u.searchParams.set('bundle',${JSON.stringify(bundleUrl)});` +
70
- `window.__sootsimBridgePort=${bridgePort};` +
71
- `history.replaceState(null,'','${prefix}/'+u.search)})()</script>`
72
- return html.replace('</head>', inject + '</head>')
73
- }
74
-
75
- // mirror Set-Cookie into a readable header for sootsim's fetch wrapper
76
- server.middlewares.use((req, res, next) => {
77
- const origWriteHead = res.writeHead.bind(res)
78
- res.writeHead = function (statusCode: number, ...args: unknown[]) {
79
- const setCookie = res.getHeader('set-cookie')
80
- if (setCookie) {
81
- const value = Array.isArray(setCookie)
82
- ? setCookie.join(', ')
83
- : String(setCookie)
84
- res.setHeader('x-sootsim-set-cookie', value)
85
- res.setHeader('access-control-expose-headers', 'x-sootsim-set-cookie')
86
- }
87
- return (origWriteHead as (...args: unknown[]) => typeof res)(
88
- statusCode,
89
- ...args,
90
- )
91
- } as typeof res.writeHead
92
- next()
93
- })
94
-
95
- // serve a minimal /__server-scan describing THIS vite dev server, so a
96
- // sootsim shell loaded from <port>/__soot can resolve this app's native
97
- // bundle. dev-bundle-resolution's resolvePortViaServerScan fetches
98
- // `/__server-scan` RELATIVE to the shell origin; when the shell is loaded
99
- // from this target origin, that hits here. without it the request SPA-
100
- // falls-back to 404 and the bundle never resolves (sootsim open hangs).
101
- // we describe only this server (the shell drives THIS app) — no localhost-
102
- // wide scan, so the published plugin pulls in no shell-only scanner
103
- // internals. shape matches DiscoveredServer enough for the resolver.
104
- server.middlewares.use((req, res, next) => {
105
- if ((req.url || '').split('?')[0] !== '/__server-scan') return next()
106
- const scanPort = server.config.server.port || 8081
107
- const absoluteBundleUrl = bundleUrl.startsWith('http')
108
- ? bundleUrl
109
- : `http://localhost:${scanPort}${bundleUrl}`
110
- res.setHeader('content-type', 'application/json')
111
- res.end(
112
- JSON.stringify([
113
- {
114
- port: scanPort,
115
- framework: 'one',
116
- bundleUrl: absoluteBundleUrl,
117
- lastSeen: Date.now(),
118
- },
119
- ]),
39
+ return {
40
+ name: 'sootsim-one',
41
+
42
+ configureServer(server) {
43
+ if (options.enabled === false) return
44
+ const bundleUrl =
45
+ options.bundleUrl ||
46
+ '/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false'
47
+
48
+ // build the shell HTML, injecting the bundle URL (so main.tsx loads this
49
+ // app's bundle) AND window.__sootsimBridgePort. the bridge-port injection
50
+ // mirrors the dev-stack bridge-host: without it the engine's
51
+ // resolveBridgePort() falls back to a location-derived guess that mis-maps
52
+ // a non-Contrast app port (the mobile template's :4400 -> 9068) and the sim
53
+ // can't reach the bridge. resolved per-request from the daemon lockfile
54
+ // (the CLI's `open` writes/uses it before the shell loads) so the engine
55
+ // targets the SAME bridge the CLI does; default port otherwise.
56
+ const buildShellHtml = (runtimeRoot: string): string => {
57
+ const html = fs.readFileSync(path.join(runtimeRoot, 'index.html'), 'utf8')
58
+ const lock = readDaemonLockfile()
59
+ const bridgePort =
60
+ lock && isDaemonLockfileFresh(lock) && lock.bridgePort > 0
61
+ ? lock.bridgePort
62
+ : DEFAULT_SOOTSIM_BRIDGE_PORT
63
+ // inject the bridge port + a default bundle (only when the URL has none,
64
+ // so the CLI's resolved bundle wins), and PRESERVE the existing query.
65
+ // preserving the query is essential: `sootsim open` stamps the open URL
66
+ // with `inspectOpen=<token>` and matches the registered sim by that
67
+ // token (waitForSimMatch). the old code forced `?bundle=` only and
68
+ // stripped inspectOpen, so the sim registered but never matched and
69
+ // `open` timed out after 60s.
70
+ const inject =
71
+ `<script>(function(){var u=new URL(location.href);` +
72
+ `if(!u.searchParams.has('bundle'))u.searchParams.set('bundle',${JSON.stringify(bundleUrl)});` +
73
+ `window.__sootsimBridgePort=${bridgePort};` +
74
+ `history.replaceState(null,'','${prefix}/'+u.search)})()</script>`
75
+ return html.replace('</head>', inject + '</head>')
76
+ }
77
+
78
+ // mirror Set-Cookie into a readable header for sootsim's fetch wrapper
79
+ server.middlewares.use((req, res, next) => {
80
+ const origWriteHead = res.writeHead.bind(res)
81
+ res.writeHead = function (statusCode: number, ...args: unknown[]) {
82
+ const setCookie = res.getHeader('set-cookie')
83
+ if (setCookie) {
84
+ const value = Array.isArray(setCookie)
85
+ ? setCookie.join(', ')
86
+ : String(setCookie)
87
+ res.setHeader('x-sootsim-set-cookie', value)
88
+ res.setHeader('access-control-expose-headers', 'x-sootsim-set-cookie')
89
+ }
90
+ return (origWriteHead as (...args: unknown[]) => typeof res)(
91
+ statusCode,
92
+ ...args,
120
93
  )
121
- })
94
+ } as typeof res.writeHead
95
+ next()
96
+ })
97
+
98
+ // serve a minimal /__server-scan describing THIS vite dev server, so a
99
+ // sootsim shell loaded from <port>/__soot can resolve this app's native
100
+ // bundle. dev-bundle-resolution's resolvePortViaServerScan fetches
101
+ // `/__server-scan` RELATIVE to the shell origin; when the shell is loaded
102
+ // from this target origin, that hits here. without it the request SPA-
103
+ // falls-back to 404 and the bundle never resolves (sootsim open hangs).
104
+ // we describe only this server (the shell drives THIS app) — no localhost-
105
+ // wide scan, so the published plugin pulls in no shell-only scanner
106
+ // internals. shape matches DiscoveredServer enough for the resolver.
107
+ server.middlewares.use((req, res, next) => {
108
+ if ((req.url || '').split('?')[0] !== '/__server-scan') return next()
109
+ const scanPort = server.config.server.port || 8081
110
+ const absoluteBundleUrl = bundleUrl.startsWith('http')
111
+ ? bundleUrl
112
+ : `http://localhost:${scanPort}${bundleUrl}`
113
+ res.setHeader('content-type', 'application/json')
114
+ res.end(
115
+ JSON.stringify([
116
+ {
117
+ port: scanPort,
118
+ framework: 'one',
119
+ bundleUrl: absoluteBundleUrl,
120
+ lastSeen: Date.now(),
121
+ },
122
+ ]),
123
+ )
124
+ })
125
+
126
+ server.middlewares.use((req, res, next) => {
127
+ const url = req.url || ''
128
+ const pathname = url.split('?')[0]
129
+ const runtimeRoot = resolveRuntimeRootForRequestHost(req.headers.host)
130
+
131
+ if (!runtimeRoot) {
132
+ if (
133
+ pathname === prefix ||
134
+ pathname === prefix + '/' ||
135
+ pathname.startsWith(prefix + '/')
136
+ ) {
137
+ res.statusCode = 500
138
+ res.end(SOOTSIM_RUNTIME_MISSING_MESSAGE)
139
+ return
140
+ }
141
+ next()
142
+ return
143
+ }
122
144
 
123
- server.middlewares.use((req, res, next) => {
124
- const url = req.url || ''
125
- const pathname = url.split('?')[0]
126
- const runtimeRoot = resolveRuntimeRootForRequestHost(req.headers.host)
127
-
128
- if (!runtimeRoot) {
129
- if (
130
- pathname === prefix ||
131
- pathname === prefix + '/' ||
132
- pathname.startsWith(prefix + '/')
133
- ) {
134
- res.statusCode = 500
135
- res.end(SOOTSIM_RUNTIME_MISSING_MESSAGE)
136
- return
137
- }
138
- next()
145
+ // root-relative runtime assets emitted by the shell and engine vite
146
+ // builds. only intercept when the asset exists in the active runtime.
147
+ if (isRootRuntimeAssetPath(pathname)) {
148
+ const fullPath = resolveRuntimeFilePath(runtimeRoot, pathname)
149
+ if (fullPath) {
150
+ serveRuntimeFile(req, res, fullPath)
139
151
  return
140
152
  }
153
+ }
154
+
155
+ // serve the sootsim HTML shell — inject bundle URL + bridge port
156
+ if (pathname === prefix || pathname === prefix + '/') {
157
+ res.setHeader('content-type', 'text/html')
158
+ res.end(buildShellHtml(runtimeRoot))
159
+ return
160
+ }
141
161
 
142
- // root-relative runtime assets emitted by the shell and engine vite
143
- // builds. only intercept when the asset exists in the active runtime.
144
- if (isRootRuntimeAssetPath(pathname)) {
145
- const fullPath = resolveRuntimeFilePath(runtimeRoot, pathname)
146
- if (fullPath) {
147
- serveRuntimeFile(req, res, fullPath)
148
- return
149
- }
162
+ // serve runtime files under /__soot/*.
163
+ if (pathname.startsWith(prefix + '/')) {
164
+ const fullPath = resolveRuntimeFilePath(
165
+ runtimeRoot,
166
+ pathname.slice(prefix.length),
167
+ )
168
+ if (fullPath) {
169
+ serveRuntimeFile(req, res, fullPath)
170
+ return
150
171
  }
151
172
 
152
- // serve the sootsim HTML shell inject bundle URL + bridge port
153
- if (pathname === prefix || pathname === prefix + '/') {
173
+ // extensionless in-shell routes should still load the shell.
174
+ const ext = path.extname(pathname)
175
+ if (!ext) {
154
176
  res.setHeader('content-type', 'text/html')
155
177
  res.end(buildShellHtml(runtimeRoot))
156
178
  return
157
179
  }
180
+ }
158
181
 
159
- // serve runtime files under /__soot/*.
160
- if (pathname.startsWith(prefix + '/')) {
161
- const fullPath = resolveRuntimeFilePath(
162
- runtimeRoot,
163
- pathname.slice(prefix.length),
164
- )
165
- if (fullPath) {
166
- serveRuntimeFile(req, res, fullPath)
167
- return
168
- }
169
-
170
- // extensionless in-shell routes should still load the shell.
171
- const ext = path.extname(pathname)
172
- if (!ext) {
173
- res.setHeader('content-type', 'text/html')
174
- res.end(buildShellHtml(runtimeRoot))
175
- return
176
- }
177
- }
178
-
179
- next()
182
+ next()
183
+ })
184
+
185
+ const port = server.config.server.port || 8081
186
+ const sootsimUrl = `http://localhost:${port}${prefix}/`
187
+ console.log(`[rnx] serving at ${sootsimUrl}`)
188
+
189
+ if (options.open && !process.env.CI && !process.env.SOOTSIM_NO_OPEN) {
190
+ server.httpServer?.once('listening', () => {
191
+ // this package's own cli (package.json bin: dist-cli/bin.js),
192
+ // resolved from this file so it works from both the workspace
193
+ // source export and the published dist-lib build.
194
+ const packageRoot = path.resolve(
195
+ path.dirname(fileURLToPath(import.meta.url)),
196
+ '..',
197
+ )
198
+ const binPath = path.join(packageRoot, 'dist-cli', 'bin.js')
199
+ const openPort = server.config.server.port || port
200
+ console.log(`[rnx] opening simulator for :${openPort}`)
201
+ // invoke the cli script through the current node binary rather
202
+ // than the bin shim so the same spawn works on windows, macos,
203
+ // and linux without a shell.
204
+ spawn(process.execPath, [binPath, 'open', String(openPort)], {
205
+ detached: true,
206
+ stdio: 'ignore',
207
+ windowsHide: true,
208
+ }).unref()
180
209
  })
181
-
182
- const port = server.config.server.port || 8081
183
- const sootsimUrl = `http://localhost:${port}${prefix}/`
184
- console.log(`[rnx] serving at ${sootsimUrl}`)
185
- },
210
+ }
186
211
  },
187
- ]
212
+ }
188
213
  }
189
214
 
190
- export default sootsimPlugin
215
+ export const sootsimPlugin = rnxPlugin
216
+ export default rnxPlugin
@@ -1,4 +0,0 @@
1
- /*! rnx v0.1.335 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import { createRequire as __sootsimCreateRequire } from 'node:module'
3
- var require = __sootsimCreateRequire(import.meta.url)
4
- import{k as p}from"./chunk-6VN5ULGQ.js";import"./chunk-35XNGT5C.js";import"./chunk-ZYHCWCMM.js";import"./chunk-MTNIDSOA.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let i=t.find(r=>r.startsWith(`--${e}=`));return i?i.slice(e.length+3):void 0}async function x(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),i=f(t,"manifest");if((!o||!i)&&(console.error(" usage: rnxsim app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let r=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of r){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(i))try{let n=JSON.parse(y(i,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(i,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await x(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
@@ -1,12 +0,0 @@
1
- /*! rnx v0.1.335 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import { createRequire as __sootsimCreateRequire } from 'node:module'
3
- var require = __sootsimCreateRequire(import.meta.url)
4
- import{a as s}from"./chunk-FJSHIWAM.js";import{d as i}from"./chunk-ZZWO6Y7X.js";import"./chunk-GP6QEBZA.js";import"./chunk-MTNIDSOA.js";function t(){console.log(`
5
- rnxsim auth \u2014 inspect CLI auth
6
-
7
- usage:
8
- rnxsim auth
9
-
10
- API keys are read from RNX_API_KEY, or SOOTSIM_API_KEY if that is unset.
11
- Use \`rnxsim login\` to sign in and \`rnxsim logout\` to clear the desktop session.
12
- `)}async function r(){let o=s();if(!o)return console.log(" not signed in"),console.log(" set RNX_API_KEY=sk_rnx_... or run `rnxsim login`"),1;if(o.kind==="api-key")return console.log(` api key ${o.secret.slice(0,14)}...`),console.log(` source: ${o.envName} env var`),0;if(o.kind==="github")return console.log(` github token (${o.source})`),console.log(` repo: ${o.repoId}`),0;let e=await i(o.origin),n=e?.user;return console.log(` ${n?.email||n?.name||n?.id||"signed in"}`),console.log(` origin: ${e?.origin??o.origin}`),e?.updatedAt&&console.log(` updated: ${e.updatedAt}`),0}async function c(o){if(o.includes("--help")||o.includes("-h")){t();return}let e=o.find(n=>!n.startsWith("-"));if(!e||e==="status"){process.exitCode=await r();return}console.error(` unknown auth command: ${e}`),t(),process.exit(1)}export{c as runAuth};
@@ -1,33 +0,0 @@
1
- /*! rnx v0.1.335 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import { createRequire as __sootsimCreateRequire } from 'node:module'
3
- var require = __sootsimCreateRequire(import.meta.url)
4
- import{m as O}from"./chunk-ROPHZJ6P.js";import"./chunk-3ZDOPKHE.js";import{q as E,s as F,u as N}from"./chunk-RTEJXUXN.js";import"./chunk-GVKISFQ3.js";import{r as S}from"./chunk-GP6QEBZA.js";import"./chunk-MTNIDSOA.js";import{createHash as I,randomUUID as q}from"node:crypto";import{createReadStream as D}from"node:fs";import l from"node:fs/promises";import f from"node:path";var T="/__camera-fixtures/",J=new Set([".m4v",".mov",".mp4",".webm"]);function _(){console.log(`
5
- rnxsim camera \u2014 control the simulator camera source
6
-
7
- usage:
8
- rnxsim camera play <file> [--loop] [--rate <number>]
9
- rnxsim camera stop
10
- rnxsim camera status [--json]
11
- rnxsim do scan <text> [--format <web-format>]
12
-
13
- subcommands:
14
- play <file> replace the active camera source with a local video fixture
15
- stop clear fixture mode and restore the live camera source
16
- status report live, fixture, or idle source state
17
- scan <text> inject a synthetic barcode result into an active scan session
18
-
19
- options:
20
- --loop loop fixture playback
21
- --rate <n> fixture playback rate (default: 1)
22
- --format <f> synthetic BarcodeDetector format (default: qr_code)
23
- --json print status/result as JSON
24
- --sim <id> target a specific sim
25
- --port <p> WS bridge port (default: 7668)
26
-
27
- examples:
28
- rnxsim camera play ./fixtures/qr.mp4 --loop
29
- rnxsim camera play ./fixtures/document.webm --rate 2
30
- rnxsim camera status
31
- rnxsim camera stop
32
- rnxsim do scan "https://example.com" --format qr_code
33
- `)}function U(e){if(!e||typeof e!="object")return!1;let i=Reflect.get(e,"ok"),t=Reflect.get(e,"source");return typeof i=="boolean"&&(t==="live"||t==="fixture"||t==="idle")}async function b(e,i){let t=await e.send({type:"camera",camera:i});if(!U(t))throw new Error("camera bridge returned an invalid result");return t}function $(e,i){if(i){console.log(JSON.stringify(e));return}e.source==="fixture"?console.log(` camera source: fixture (${e.url??"unknown url"}, ${e.loop?"looping":"once"}, ${e.rate??1}x)`):e.source==="live"?console.log(" camera source: live"):e.url?console.log(` camera source: idle (fixture queued: ${e.url}, ${e.loop?"looping":"once"}, ${e.rate??1}x)`):console.log(" camera source: idle"),!e.ok&&e.error&&console.error(` camera failed: ${e.error}`)}async function M(e,i={}){let t=E(e,{port:i.port,stripBooleanFlags:["--help","-h","--json","--loop"],stripValueFlags:["--format","--rate"]}),p=t.positional,n=p[0];if(!n||n==="help"||e.includes("--help")||e.includes("-h"))return _(),n?0:1;let c=F(t),d=e.includes("--json");try{if(n==="scan"){let r=p[1];if(!r)return console.error(" usage: rnxsim do scan <text>"),1;let a=e.indexOf("--format"),s=a>=0?e[a+1]:"qr_code";return s?await N(c,`globalThis.__sootsimCameraInjectScan?.(${JSON.stringify(r)}, ${JSON.stringify(s)}) ?? false`)?(console.log(` injected ${s} scan: ${r}`),0):(console.error(" no active barcode scan session. open a scanning <CameraView> first"),1):(console.error(" --format requires a value"),1)}if(n==="status"){let r=await b(c,{action:"status"});return $(r,d),r.ok?0:1}if(n==="stop"){let r=await b(c,{action:"stop"});return $(r,d),r.ok?0:1}if(n==="play"){let r=p[1];if(!r)return console.error(" usage: rnxsim camera play <file> [--loop] [--rate <number>]"),1;let a=f.resolve(r),s=f.extname(a).toLowerCase();if(!J.has(s))return console.error(` unsupported camera fixture extension ${s||"(none)"}. use mp4, webm, mov, or m4v`),1;let u;try{u=await l.stat(a)}catch{return console.error(` camera fixture not found: ${a}`),1}if(!u.isFile()||u.size===0)return console.error(` camera fixture must be a non-empty file: ${a}`),1;let v=e.indexOf("--rate"),C=v>=0?e[v+1]:void 0,x=C===void 0?1:Number(C);if(!Number.isFinite(x)||x<=0)return console.error(" --rate must be a positive finite number"),1;let g=S();await l.mkdir(g,{recursive:!0});let j=I("sha256");await new Promise((o,m)=>{let h=D(a);h.on("data",P=>j.update(P)),h.once("error",m),h.once("end",o)});let w=`${j.digest("hex")}${s}`,y=f.join(g,w),k=!1;try{if(!(await l.lstat(y)).isFile())throw new Error(`camera fixture cache entry is not a file: ${y}`);k=!0}catch(o){if(!o||typeof o!="object"||Reflect.get(o,"code")!=="ENOENT")throw o}if(!k){let o=f.join(g,`.${w}.${process.pid}-${q()}.tmp`);await l.copyFile(a,o);try{await l.link(o,y)}catch(m){if(!m||typeof m!="object"||Reflect.get(m,"code")!=="EEXIST")throw m}finally{await l.unlink(o).catch(()=>{})}}let B=`http://127.0.0.1:${t.wsPort}${T}${w}`,R=await b(c,{action:"play",url:B,loop:e.includes("--loop"),rate:x});return $(R,d),R.ok?0:1}return console.error(` unknown camera subcommand: ${n}`),_(),1}catch(r){return console.error(` camera failed: ${r instanceof Error?r.message:r}`),await O(c),1}finally{c.close()}}export{M as runCamera};