rnxsim 0.1.312 → 0.1.314

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 (299) hide show
  1. package/LICENSE +11 -10
  2. package/README.md +5 -0
  3. package/cli/app-config.ts +65 -0
  4. package/cli/app-fonts.ts +408 -0
  5. package/cli/app-project.ts +231 -0
  6. package/cli/app-splash.ts +185 -0
  7. package/cli/app-state-reset.ts +24 -0
  8. package/cli/auth.ts +155 -0
  9. package/cli/bin.ts +594 -0
  10. package/cli/bridge-diagnostics.ts +226 -0
  11. package/cli/bridge-flow-runner.ts +2830 -0
  12. package/cli/browser-evals.ts +96 -0
  13. package/cli/commands/agent-wrapper.ts +986 -0
  14. package/cli/commands/agent.ts +423 -0
  15. package/cli/commands/app-fonts.ts +98 -0
  16. package/cli/commands/assert.ts +541 -0
  17. package/cli/commands/auth.ts +59 -0
  18. package/cli/commands/camera.ts +266 -0
  19. package/cli/commands/cleanup.ts +169 -0
  20. package/cli/commands/compat.ts +87 -0
  21. package/cli/commands/config.ts +32 -0
  22. package/cli/commands/control.ts +2142 -0
  23. package/cli/commands/cpu-profile.ts +269 -0
  24. package/cli/commands/daemon-mac-app.ts +169 -0
  25. package/cli/commands/daemon.ts +874 -0
  26. package/cli/commands/debug.ts +719 -0
  27. package/cli/commands/desktop.ts +39 -0
  28. package/cli/commands/detect.ts +197 -0
  29. package/cli/commands/detox.ts +385 -0
  30. package/cli/commands/device.ts +133 -0
  31. package/cli/commands/diagnose.ts +589 -0
  32. package/cli/commands/electron.ts +95 -0
  33. package/cli/commands/film.ts +379 -0
  34. package/cli/commands/flow.ts +1124 -0
  35. package/cli/commands/inspect/actions.ts +622 -0
  36. package/cli/commands/inspect/core.ts +2405 -0
  37. package/cli/commands/inspect/count.ts +17 -0
  38. package/cli/commands/inspect/describe.ts +192 -0
  39. package/cli/commands/inspect/env.ts +23 -0
  40. package/cli/commands/inspect/find.ts +171 -0
  41. package/cli/commands/inspect/get-layout.ts +39 -0
  42. package/cli/commands/inspect/keyboard.ts +52 -0
  43. package/cli/commands/inspect/list.ts +58 -0
  44. package/cli/commands/inspect/memory.ts +215 -0
  45. package/cli/commands/inspect/redaction.ts +39 -0
  46. package/cli/commands/inspect/resolve-target.ts +82 -0
  47. package/cli/commands/inspect/screens.ts +78 -0
  48. package/cli/commands/inspect/settle.ts +22 -0
  49. package/cli/commands/inspect/settling.ts +158 -0
  50. package/cli/commands/inspect/shared.ts +353 -0
  51. package/cli/commands/inspect/sleep.ts +14 -0
  52. package/cli/commands/inspect/tree.ts +32 -0
  53. package/cli/commands/inspect/url.ts +17 -0
  54. package/cli/commands/inspect/wait-event.ts +210 -0
  55. package/cli/commands/inspect/wait-idle.ts +24 -0
  56. package/cli/commands/inspect/wait-ready.ts +74 -0
  57. package/cli/commands/inspect/wait-selector.ts +54 -0
  58. package/cli/commands/inspect/wait.ts +31 -0
  59. package/cli/commands/inspect.ts +4519 -0
  60. package/cli/commands/install-desktop.ts +351 -0
  61. package/cli/commands/login.ts +331 -0
  62. package/cli/commands/logout.ts +31 -0
  63. package/cli/commands/maestro-generate.ts +361 -0
  64. package/cli/commands/maestro.ts +453 -0
  65. package/cli/commands/mode.ts +57 -0
  66. package/cli/commands/no-bridge-hint.ts +80 -0
  67. package/cli/commands/perf.ts +66 -0
  68. package/cli/commands/permissions.ts +203 -0
  69. package/cli/commands/profile.ts +108 -0
  70. package/cli/commands/react.ts +353 -0
  71. package/cli/commands/record.ts +1434 -0
  72. package/cli/commands/report-issue.ts +305 -0
  73. package/cli/commands/reset.ts +85 -0
  74. package/cli/commands/runtime.ts +351 -0
  75. package/cli/commands/screenshot-command.ts +106 -0
  76. package/cli/commands/screenshot-layers.ts +143 -0
  77. package/cli/commands/screenshot-mode.ts +37 -0
  78. package/cli/commands/screenshot.ts +488 -0
  79. package/cli/commands/screenshots-capture.ts +607 -0
  80. package/cli/commands/screenshots.ts +127 -0
  81. package/cli/commands/serve.ts +168 -0
  82. package/cli/commands/setup.ts +545 -0
  83. package/cli/commands/shell-boolean-mode.ts +81 -0
  84. package/cli/commands/skills.ts +467 -0
  85. package/cli/commands/slides.ts +361 -0
  86. package/cli/commands/state.ts +87 -0
  87. package/cli/commands/storage.ts +58 -0
  88. package/cli/commands/telemetry.ts +54 -0
  89. package/cli/commands/three-mode.ts +763 -0
  90. package/cli/commands/timeline.ts +122 -0
  91. package/cli/commands/upgrade.ts +208 -0
  92. package/cli/commands/upload.ts +1225 -0
  93. package/cli/commands/version.ts +54 -0
  94. package/cli/commands/what-happened.ts +327 -0
  95. package/cli/current-sim.ts +204 -0
  96. package/cli/desktop-companion.ts +300 -0
  97. package/cli/drivers/electron.ts +70 -0
  98. package/cli/drivers/index.ts +20 -0
  99. package/cli/drivers/playwright-provisioning.ts +180 -0
  100. package/cli/drivers/playwright.ts +698 -0
  101. package/cli/drivers/registry.ts +65 -0
  102. package/cli/drivers/types.ts +102 -0
  103. package/cli/flow-file.ts +142 -0
  104. package/cli/flow-live-status.ts +120 -0
  105. package/cli/flow-session.ts +187 -0
  106. package/cli/help.ts +80 -0
  107. package/cli/hidden-runtime-alias.ts +19 -0
  108. package/cli/hints.ts +216 -0
  109. package/cli/inspect-notice-state.ts +114 -0
  110. package/cli/maestro-js.ts +334 -0
  111. package/cli/open-url.ts +8 -0
  112. package/cli/parent-pid.ts +204 -0
  113. package/cli/parse-args.ts +211 -0
  114. package/cli/prompt.ts +51 -0
  115. package/cli/recording-access.ts +107 -0
  116. package/cli/registry.ts +1 -0
  117. package/cli/resolve-assets.ts +63 -0
  118. package/cli/run-registry.ts +226 -0
  119. package/cli/runtime-notes.ts +66 -0
  120. package/cli/runtime-summary.ts +25 -0
  121. package/cli/setup-repository.ts +187 -0
  122. package/cli/telemetry.ts +187 -0
  123. package/cli/ws-bridge.ts +798 -0
  124. package/dist-cli/bin.js +5 -5
  125. package/dist-cli/chunks/{agent-NXVDDCFG.js → agent-7YBDCYMA.js} +2 -2
  126. package/dist-cli/chunks/{agent-wrapper-DXJCFKL3.js → agent-wrapper-2GHFBHCR.js} +2 -2
  127. package/dist-cli/chunks/{app-fonts-W5AJZQJF.js → app-fonts-RSNVPQSU.js} +2 -2
  128. package/dist-cli/chunks/{assert-3LOJEUDT.js → assert-XCMX3XJX.js} +2 -2
  129. package/dist-cli/chunks/{auth-MFTYYPNX.js → auth-B442HRAX.js} +2 -2
  130. package/dist-cli/chunks/{beta-GT3NN67B.js → beta-XJ55JK3M.js} +2 -2
  131. package/dist-cli/chunks/camera-UGYSSLIK.js +33 -0
  132. package/dist-cli/chunks/{chunk-EUAVBTKU.js → chunk-277AEQZX.js} +2 -2
  133. package/dist-cli/chunks/{chunk-5OX7ANRA.js → chunk-2JNSK774.js} +2 -2
  134. package/dist-cli/chunks/{chunk-L24Z3CRS.js → chunk-32WOTSTR.js} +3 -3
  135. package/dist-cli/chunks/{chunk-BKNOLP3J.js → chunk-3S753SNQ.js} +2 -2
  136. package/dist-cli/chunks/{chunk-N6A3SXMR.js → chunk-46ZOLOYA.js} +2 -2
  137. package/dist-cli/chunks/{chunk-GZDHEONW.js → chunk-5L7ELDQL.js} +8 -9
  138. package/dist-cli/chunks/{chunk-YZRFF4YA.js → chunk-7OOPFSQS.js} +2 -2
  139. package/dist-cli/chunks/{chunk-TBMVBI26.js → chunk-7SV3RPRW.js} +2 -2
  140. package/dist-cli/chunks/{chunk-JG6S4RSH.js → chunk-7ZC35MOU.js} +1 -1
  141. package/dist-cli/chunks/chunk-AMG5E6CC.js +9 -0
  142. package/dist-cli/chunks/{chunk-MENV7VLD.js → chunk-APWNH3A4.js} +1 -1
  143. package/dist-cli/chunks/chunk-B57XUKY3.js +4 -0
  144. package/dist-cli/chunks/{chunk-3D57IBPC.js → chunk-C2NL26TD.js} +1 -1
  145. package/dist-cli/chunks/chunk-D2FNUWAB.js +15 -0
  146. package/dist-cli/chunks/{chunk-4BXCZHAU.js → chunk-E5T4XSJ3.js} +2 -2
  147. package/dist-cli/chunks/{chunk-FTC4M26Q.js → chunk-EAC34EQS.js} +1 -1
  148. package/dist-cli/chunks/{chunk-NPVGMH2N.js → chunk-EG32ML36.js} +2 -2
  149. package/dist-cli/chunks/{chunk-DM6KUAOZ.js → chunk-FXUAC6D5.js} +1 -1
  150. package/dist-cli/chunks/chunk-GQSL4USA.js +6 -0
  151. package/dist-cli/chunks/{chunk-U4PN6JOT.js → chunk-HAXW27SS.js} +2 -2
  152. package/dist-cli/chunks/{chunk-ZMZTHU7V.js → chunk-IZAHPAN6.js} +1 -1
  153. package/dist-cli/chunks/{chunk-SI3BUTQR.js → chunk-J62KM5TB.js} +2 -2
  154. package/dist-cli/chunks/{chunk-Y2FSZSO7.js → chunk-JEMCD5E4.js} +1 -1
  155. package/dist-cli/chunks/{chunk-T4FT6CM7.js → chunk-JZS3Q37N.js} +2 -2
  156. package/dist-cli/chunks/{chunk-2SA2VTGP.js → chunk-KR4JON7D.js} +1 -1
  157. package/dist-cli/chunks/chunk-KWCYKQIQ.js +4 -0
  158. package/dist-cli/chunks/{chunk-HG7ORJMT.js → chunk-MCWPL644.js} +2 -2
  159. package/dist-cli/chunks/chunk-MJYK3N2I.js +4 -0
  160. package/dist-cli/chunks/{chunk-YRV7HR3P.js → chunk-O6TRIZNS.js} +2 -2
  161. package/dist-cli/chunks/{chunk-WBT32R6N.js → chunk-P7XL2E73.js} +3 -3
  162. package/dist-cli/chunks/{chunk-MNGQ42QE.js → chunk-PFQTUKQ4.js} +62 -87
  163. package/dist-cli/chunks/{chunk-Q3RGLERJ.js → chunk-PG5RZCTN.js} +2 -2
  164. package/dist-cli/chunks/{chunk-OR3XTXEB.js → chunk-QGRI2Z4M.js} +2 -2
  165. package/dist-cli/chunks/chunk-QLXXE7GE.js +125 -0
  166. package/dist-cli/chunks/{chunk-KZW5WBGU.js → chunk-QOJJJWJE.js} +89 -133
  167. package/dist-cli/chunks/{chunk-BRIZOR4K.js → chunk-RWZY5427.js} +2 -2
  168. package/dist-cli/chunks/{chunk-TYE3WBSR.js → chunk-RZKU2K3J.js} +2 -2
  169. package/dist-cli/chunks/{chunk-7VWOSTD5.js → chunk-SBV4IK4H.js} +1 -1
  170. package/dist-cli/chunks/{chunk-FWYYCUAZ.js → chunk-SGMVFFMK.js} +1 -1
  171. package/dist-cli/chunks/{chunk-LDQ7HVCW.js → chunk-TAX4UT2N.js} +1 -1
  172. package/dist-cli/chunks/{chunk-G74YIEVS.js → chunk-TUOFAWXT.js} +1 -1
  173. package/dist-cli/chunks/{chunk-274UD5FD.js → chunk-UHZLOHGP.js} +1 -1
  174. package/dist-cli/chunks/{chunk-37I5AIS7.js → chunk-VC7V76U3.js} +1 -1
  175. package/dist-cli/chunks/{chunk-B7KMNHX7.js → chunk-VQVMLW4U.js} +1 -1
  176. package/dist-cli/chunks/{chunk-VZBLFMYC.js → chunk-VUKKYPZN.js} +2 -2
  177. package/dist-cli/chunks/{chunk-VUFRB347.js → chunk-WGGRJDRE.js} +1 -1
  178. package/dist-cli/chunks/chunk-X6H76EKP.js +15 -0
  179. package/dist-cli/chunks/chunk-XLZ5FNRT.js +27 -0
  180. package/dist-cli/chunks/{chunk-TCWQJILS.js → chunk-XULEACM4.js} +2 -2
  181. package/dist-cli/chunks/{chunk-XRGEEPJ5.js → chunk-YFSDM7AX.js} +4 -4
  182. package/dist-cli/chunks/chunk-YWI3UEVX.js +5 -0
  183. package/dist-cli/chunks/{chunk-TGQNQ6XT.js → chunk-ZBSJO4NB.js} +10 -9
  184. package/dist-cli/chunks/{cleanup-H3GWQB63.js → cleanup-EYLGCA6Z.js} +2 -2
  185. package/dist-cli/chunks/cli-version-LL2UGIHE.js +4 -0
  186. package/dist-cli/chunks/{compat-5WG2XJV7.js → compat-TLJYHB4E.js} +2 -2
  187. package/dist-cli/chunks/{config-ANMBVVLL.js → config-4JWUOEXK.js} +2 -2
  188. package/dist-cli/chunks/{control-NSGNQFJG.js → control-HPAOYF4N.js} +2 -2
  189. package/dist-cli/chunks/daemon-OYLASXLE.js +4 -0
  190. package/dist-cli/chunks/{debug-CHV2O2KF.js → debug-4BKXF6KI.js} +5 -5
  191. package/dist-cli/chunks/{desktop-FIPIK4CH.js → desktop-ZQ6ZD2S6.js} +3 -3
  192. package/dist-cli/chunks/{detox-CVUJP7K6.js → detox-WNPASSS3.js} +2 -2
  193. package/dist-cli/chunks/{device-6WCUM4W6.js → device-BXLXVG3V.js} +2 -2
  194. package/dist-cli/chunks/{diagnose-I6EMWEII.js → diagnose-3QX7W5RW.js} +2 -2
  195. package/dist-cli/chunks/{disk-cleanup-P27CYFTN.js → disk-cleanup-KSWKI7WB.js} +2 -2
  196. package/dist-cli/chunks/drivers-EPIEFF7P.js +4 -0
  197. package/dist-cli/chunks/{film-UOQFFYNF.js → film-GDMR33VO.js} +3 -3
  198. package/dist-cli/chunks/flow-NKMPBYCJ.js +4 -0
  199. package/dist-cli/chunks/help-OGCBHOKA.js +4 -0
  200. package/dist-cli/chunks/{hidden-runtime-alias-NJYFSJKZ.js → hidden-runtime-alias-S2GTDX3T.js} +2 -2
  201. package/dist-cli/chunks/home-paths-QRCDLTTV.js +4 -0
  202. package/dist-cli/chunks/inspect-FUYMOZPY.js +4 -0
  203. package/dist-cli/chunks/install-desktop-FR6YKW7Y.js +4 -0
  204. package/dist-cli/chunks/{login-BPFQENCX.js → login-IJAPUZHI.js} +4 -4
  205. package/dist-cli/chunks/{logout-5A45ZGY7.js → logout-QMXDFU2X.js} +2 -2
  206. package/dist-cli/chunks/{maestro-E4CSDMLM.js → maestro-ZXU3YCVX.js} +3 -3
  207. package/dist-cli/chunks/{maestro-generate-CKMOJQX2.js → maestro-generate-PYB5QY7K.js} +3 -3
  208. package/dist-cli/chunks/{mode-SZYNMIQF.js → mode-WGUCL5FZ.js} +2 -2
  209. package/dist-cli/chunks/{optional-demo-registry-FRH4SFVG.js → optional-demo-registry-WH2O6H36.js} +2 -2
  210. package/dist-cli/chunks/{perf-VXU2XJAX.js → perf-TOD3UFAH.js} +2 -2
  211. package/dist-cli/chunks/{permissions-IRIAOVND.js → permissions-I5BRJGTB.js} +2 -2
  212. package/dist-cli/chunks/{record-RY7FPLLH.js → record-ZYL2FYSK.js} +3 -3
  213. package/dist-cli/chunks/{report-issue-KNWXOE53.js → report-issue-TAI6DYZO.js} +2 -2
  214. package/dist-cli/chunks/reset-7YGYKQPQ.js +4 -0
  215. package/dist-cli/chunks/runtime-B4JO6QRI.js +4 -0
  216. package/dist-cli/chunks/{screenshot-command-QLALR6GY.js → screenshot-command-7ANLODZY.js} +7 -7
  217. package/dist-cli/chunks/{screenshot-layers-OQFMFVRL.js → screenshot-layers-A7FYXSVU.js} +3 -3
  218. package/dist-cli/chunks/{screenshots-capture-6TSRJFGB.js → screenshots-capture-WT2ZY6CB.js} +2 -2
  219. package/dist-cli/chunks/serve-TG5WKA4V.js +44 -0
  220. package/dist-cli/chunks/{setup-7V6UKX4U.js → setup-PCWLD22V.js} +2 -2
  221. package/dist-cli/chunks/{skills-QQBOSETH.js → skills-27ZHWCQS.js} +2 -2
  222. package/dist-cli/chunks/state-ZQVY46ZO.js +14 -0
  223. package/dist-cli/chunks/{storage-TAPMKK5O.js → storage-OYC57C4X.js} +6 -6
  224. package/dist-cli/chunks/store-32HSPZHI.js +4 -0
  225. package/dist-cli/chunks/telemetry-PBJR7XHR.js +4 -0
  226. package/dist-cli/chunks/{timeline-IAM564NA.js → timeline-RAJJFQT6.js} +2 -2
  227. package/dist-cli/chunks/{upgrade-CD55QXIX.js → upgrade-OEFNZRIP.js} +2 -2
  228. package/dist-cli/chunks/upload-LQJITLKK.js +4 -0
  229. package/dist-cli/chunks/version-NIXTY6PL.js +6 -0
  230. package/dist-cli/chunks/{web-6NW6YLPI.js → web-XBUTBVGR.js} +2 -2
  231. package/dist-cli/chunks/{what-happened-CZZDOOVG.js → what-happened-YNHRFUDX.js} +3 -3
  232. package/dist-lib/agent-daemon-client.cjs +1 -1
  233. package/dist-lib/agent-events.cjs +1 -1
  234. package/dist-lib/agent-identity.cjs +1 -1
  235. package/dist-lib/agent-sessions.cjs +1 -1
  236. package/dist-lib/attached-projects.cjs +1 -1
  237. package/dist-lib/auth/shared-session.cjs +1 -1
  238. package/dist-lib/backend-origin.cjs +1 -1
  239. package/dist-lib/beta.cjs +1 -1
  240. package/dist-lib/beta.mjs +1 -1
  241. package/dist-lib/bridge-constants.cjs +1 -1
  242. package/dist-lib/bridge-contract.cjs +20 -0
  243. package/dist-lib/cli-constants.cjs +1 -1
  244. package/dist-lib/config.cjs +1 -1
  245. package/dist-lib/detox/index.cjs +1 -1
  246. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  247. package/dist-lib/home-paths.cjs +67 -28
  248. package/dist-lib/host/bridge-host.cjs +140 -12
  249. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  250. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  251. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  252. package/dist-lib/host/websocket-proxy.cjs +1 -1
  253. package/dist-lib/index.cjs +2815 -40
  254. package/dist-lib/jump-to-source-babel.cjs +1 -1
  255. package/dist-lib/menu.cjs +1 -1
  256. package/dist-lib/menu.mjs +1 -1
  257. package/dist-lib/metro.cjs +1 -1
  258. package/dist-lib/profiles.cjs +1 -1
  259. package/dist-lib/public-brand.cjs +1 -1
  260. package/dist-lib/render-mode.cjs +1 -1
  261. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  262. package/dist-lib/sdk.cjs +2549 -2061
  263. package/dist-lib/sdk.mjs +2543 -2061
  264. package/dist-lib/skills.cjs +493 -282
  265. package/dist-lib/vite.cjs +1 -1
  266. package/package.json +8 -2
  267. package/src/bridge-constants.ts +3 -4
  268. package/src/bridge-contract.ts +251 -0
  269. package/src/connect.ts +83 -0
  270. package/src/disk-cleanup.ts +30 -0
  271. package/src/home-paths.ts +81 -38
  272. package/src/host/bridge-host.ts +134 -6
  273. package/src/index.ts +27 -1
  274. package/src/sdk.ts +8 -0
  275. package/src/sim-client.ts +660 -0
  276. package/dist-cli/chunks/camera-6EAK7CUL.js +0 -22
  277. package/dist-cli/chunks/chunk-33FKQH54.js +0 -5
  278. package/dist-cli/chunks/chunk-66NF2KNG.js +0 -9
  279. package/dist-cli/chunks/chunk-6UKJB2VC.js +0 -125
  280. package/dist-cli/chunks/chunk-7INBNA3U.js +0 -26
  281. package/dist-cli/chunks/chunk-AY47WKS5.js +0 -23
  282. package/dist-cli/chunks/chunk-HMDOLCKG.js +0 -15
  283. package/dist-cli/chunks/chunk-KR5BGMBZ.js +0 -4
  284. package/dist-cli/chunks/chunk-NLEMQ4PY.js +0 -6
  285. package/dist-cli/chunks/chunk-PEPUGJVI.js +0 -4
  286. package/dist-cli/chunks/cli-version-3QPAJ3LC.js +0 -4
  287. package/dist-cli/chunks/daemon-JHF4BJ3U.js +0 -4
  288. package/dist-cli/chunks/drivers-HQ6AKZT6.js +0 -4
  289. package/dist-cli/chunks/flow-N27MRRNL.js +0 -4
  290. package/dist-cli/chunks/help-SF6FEGEE.js +0 -4
  291. package/dist-cli/chunks/home-paths-XOV44JEF.js +0 -4
  292. package/dist-cli/chunks/inspect-CWFRFQTY.js +0 -4
  293. package/dist-cli/chunks/install-desktop-KLQDNXZQ.js +0 -4
  294. package/dist-cli/chunks/runtime-AR3GJTGK.js +0 -4
  295. package/dist-cli/chunks/serve-F54J2NQO.js +0 -44
  296. package/dist-cli/chunks/store-7NX3S43H.js +0 -4
  297. package/dist-cli/chunks/telemetry-E7BUK6RA.js +0 -4
  298. package/dist-cli/chunks/upload-GZ6LIMYM.js +0 -4
  299. package/dist-cli/chunks/version-3DYJ5AS3.js +0 -6
@@ -0,0 +1,305 @@
1
+ // sootsim report-issue — submit an explicitly approved compatibility report.
2
+
3
+ import { existsSync, readFileSync } from 'node:fs'
4
+ import { resolve } from 'node:path'
5
+ import { getCliVersion } from '../../src/cli-version'
6
+ import { readActiveRuntime } from '../../src/home-paths'
7
+ import { authHeaderValue, resolveCliAuth } from '../auth'
8
+ import { confirm } from '../prompt'
9
+ import type { ScanResult } from '@sootsim/compat/web'
10
+
11
+ const DEFAULT_REPORT_ORIGIN = 'https://contrast.dev'
12
+ const MAX_DESCRIPTION_LENGTH = 8_000
13
+
14
+ type PackageManifest = {
15
+ name?: string
16
+ dependencies?: Record<string, string>
17
+ devDependencies?: Record<string, string>
18
+ }
19
+
20
+ type ReportIssueOptions = {
21
+ appDir: string
22
+ description: string
23
+ dryRun: boolean
24
+ yes: boolean
25
+ }
26
+
27
+ export type ReportIssuePayload = {
28
+ note: string
29
+ timestamp: string
30
+ sootsim_version: string | null
31
+ cli_version: string
32
+ bundle: {
33
+ activeApp: { appName: string } | null
34
+ reportSource: 'cli'
35
+ runtimeVersion: string | null
36
+ cliVersion: string
37
+ platform: NodeJS.Platform
38
+ arch: string
39
+ compatibility: ScanResult | null
40
+ }
41
+ }
42
+
43
+ export type ReportIssueDependencies = {
44
+ request: (url: string, init: RequestInit) => Promise<Response>
45
+ confirmSubmission: (message: string, defaultYes: boolean) => Promise<boolean>
46
+ isInteractive: boolean
47
+ now: () => Date
48
+ stdout: (message: string) => void
49
+ stderr: (message: string) => void
50
+ }
51
+
52
+ function defaultDependencies(): ReportIssueDependencies {
53
+ return {
54
+ request: (url, init) => fetch(url, init),
55
+ confirmSubmission: confirm,
56
+ isInteractive: process.stdin.isTTY === true,
57
+ now: () => new Date(),
58
+ stdout: (message) => process.stdout.write(message),
59
+ stderr: (message) => process.stderr.write(message),
60
+ }
61
+ }
62
+
63
+ function getFlagValue(args: string[], flag: string): string | null {
64
+ const index = args.indexOf(flag)
65
+ if (index === -1) return null
66
+ const value = args[index + 1]
67
+ if (!value || value.startsWith('-')) {
68
+ throw new Error(`${flag} requires a value`)
69
+ }
70
+ return value
71
+ }
72
+
73
+ export function parseReportIssueOptions(
74
+ args: string[],
75
+ cwd = process.cwd(),
76
+ ): ReportIssueOptions {
77
+ const app = getFlagValue(args, '--app')
78
+ const consumed = new Set<number>()
79
+ const appIndex = args.indexOf('--app')
80
+ if (appIndex !== -1) {
81
+ consumed.add(appIndex)
82
+ consumed.add(appIndex + 1)
83
+ }
84
+
85
+ const descriptionParts: string[] = []
86
+ for (let index = 0; index < args.length; index += 1) {
87
+ if (consumed.has(index)) continue
88
+ const arg = args[index]
89
+ if (arg === '--yes' || arg === '-y' || arg === '--dry-run') continue
90
+ if (arg.startsWith('-')) throw new Error(`unknown flag: ${arg}`)
91
+ descriptionParts.push(arg)
92
+ }
93
+
94
+ const description = descriptionParts.join(' ').trim()
95
+ if (!description) {
96
+ throw new Error('describe the missing or broken compatibility behavior')
97
+ }
98
+ if (description.length > MAX_DESCRIPTION_LENGTH) {
99
+ throw new Error(
100
+ `description is too long (maximum ${MAX_DESCRIPTION_LENGTH} characters)`,
101
+ )
102
+ }
103
+
104
+ return {
105
+ appDir: resolve(cwd, app ?? '.'),
106
+ description,
107
+ dryRun: args.includes('--dry-run'),
108
+ yes: args.includes('--yes') || args.includes('-y'),
109
+ }
110
+ }
111
+
112
+ function readStringRecord(value: unknown): Record<string, string> | undefined {
113
+ if (!value || typeof value !== 'object') return undefined
114
+ const output: Record<string, string> = {}
115
+ for (const key of Object.keys(value)) {
116
+ const next = Object.getOwnPropertyDescriptor(value, key)?.value
117
+ if (typeof next === 'string') output[key] = next
118
+ }
119
+ return output
120
+ }
121
+
122
+ function readManifest(appDir: string): PackageManifest | null {
123
+ const path = resolve(appDir, 'package.json')
124
+ if (!existsSync(path)) return null
125
+
126
+ let parsed: unknown
127
+ try {
128
+ parsed = JSON.parse(readFileSync(path, 'utf8'))
129
+ } catch {
130
+ throw new Error(`could not parse ${path}`)
131
+ }
132
+ if (!parsed || typeof parsed !== 'object') {
133
+ throw new Error(`${path} must contain a JSON object`)
134
+ }
135
+
136
+ const name = Object.getOwnPropertyDescriptor(parsed, 'name')?.value
137
+ const dependencies = Object.getOwnPropertyDescriptor(parsed, 'dependencies')?.value
138
+ const devDependencies = Object.getOwnPropertyDescriptor(
139
+ parsed,
140
+ 'devDependencies',
141
+ )?.value
142
+ const dependencyRecord = readStringRecord(dependencies)
143
+ const devDependencyRecord = readStringRecord(devDependencies)
144
+ return {
145
+ ...(typeof name === 'string' ? { name } : {}),
146
+ ...(dependencyRecord ? { dependencies: dependencyRecord } : {}),
147
+ ...(devDependencyRecord ? { devDependencies: devDependencyRecord } : {}),
148
+ }
149
+ }
150
+
151
+ export async function createReportIssuePayload(
152
+ options: Pick<ReportIssueOptions, 'appDir' | 'description'>,
153
+ now = new Date(),
154
+ ): Promise<ReportIssuePayload> {
155
+ const manifest = readManifest(options.appDir)
156
+ const compatibility = manifest
157
+ ? (await import('@sootsim/compat/web')).scanDeps(manifest)
158
+ : null
159
+ const cliVersion = getCliVersion()
160
+ const runtimeVersion = readActiveRuntime()
161
+
162
+ return {
163
+ note: options.description,
164
+ timestamp: now.toISOString(),
165
+ sootsim_version: runtimeVersion,
166
+ cli_version: cliVersion,
167
+ bundle: {
168
+ activeApp:
169
+ compatibility && compatibility.projectName !== 'unknown'
170
+ ? { appName: compatibility.projectName }
171
+ : null,
172
+ reportSource: 'cli',
173
+ runtimeVersion,
174
+ cliVersion,
175
+ platform: process.platform,
176
+ arch: process.arch,
177
+ compatibility,
178
+ },
179
+ }
180
+ }
181
+
182
+ function reportEndpoint(): { url: string; authorization: string | null } {
183
+ const auth = resolveCliAuth()
184
+ const origin =
185
+ auth?.kind === 'session' ? auth.origin.replace(/\/+$/, '') : DEFAULT_REPORT_ORIGIN
186
+ const authorization = auth && auth.kind !== 'github' ? authHeaderValue(auth) : null
187
+ return {
188
+ url: `${origin}/api/sootsim/report-issue`,
189
+ authorization,
190
+ }
191
+ }
192
+
193
+ function compatibilitySummary(scan: ScanResult | null): string {
194
+ if (!scan) return 'no package.json found; no compatibility scan attached'
195
+ const attention = scan.packages.filter(
196
+ (item) => item.status !== 'full' && item.status !== 'not-relevant',
197
+ ).length
198
+ return `${scan.packages.length} React Native ecosystem packages, ${attention} needing attention`
199
+ }
200
+
201
+ function readResponseId(value: unknown): string | null {
202
+ if (!value || typeof value !== 'object') return null
203
+ const id = Object.getOwnPropertyDescriptor(value, 'id')?.value
204
+ return typeof id === 'string' && id ? id : null
205
+ }
206
+
207
+ export async function runReportIssue(
208
+ args: string[],
209
+ dependencies: ReportIssueDependencies = defaultDependencies(),
210
+ ): Promise<number> {
211
+ let options: ReportIssueOptions
212
+ try {
213
+ options = parseReportIssueOptions(args)
214
+ } catch (error) {
215
+ dependencies.stderr(
216
+ ` ${error instanceof Error ? error.message : String(error)}\n` +
217
+ ` usage: rnxsim report-issue [--app <dir>] [--dry-run] [--yes] "<description>"\n`,
218
+ )
219
+ return 1
220
+ }
221
+
222
+ if (!existsSync(options.appDir)) {
223
+ dependencies.stderr(` directory not found: ${options.appDir}\n`)
224
+ return 1
225
+ }
226
+
227
+ let payload: ReportIssuePayload
228
+ try {
229
+ payload = await createReportIssuePayload(options, dependencies.now())
230
+ } catch (error) {
231
+ dependencies.stderr(
232
+ ` could not prepare the issue report: ${
233
+ error instanceof Error ? error.message : String(error)
234
+ }\n`,
235
+ )
236
+ return 1
237
+ }
238
+
239
+ dependencies.stdout(
240
+ `\n rnxsim issue report preview\n\n` +
241
+ ` description: ${payload.note}\n` +
242
+ ` compatibility: ${compatibilitySummary(payload.bundle.compatibility)}\n` +
243
+ ` environment: CLI ${payload.bundle.cliVersion}, runtime ${
244
+ payload.bundle.runtimeVersion ?? 'not installed'
245
+ }, ${payload.bundle.platform}/${payload.bundle.arch}\n\n` +
246
+ ` Includes only the description, compatibility scan, and the version/platform details above.\n` +
247
+ ` It does not include source files, environment variables, terminal output, logs, screenshots, or app data.\n`,
248
+ )
249
+
250
+ if (options.dryRun) {
251
+ dependencies.stdout(`\n dry run: nothing was sent.\n`)
252
+ return 0
253
+ }
254
+
255
+ if (!options.yes) {
256
+ if (!dependencies.isInteractive) {
257
+ dependencies.stderr(
258
+ `\n not sent: ask the user for explicit approval, then rerun with --yes.\n`,
259
+ )
260
+ return 2
261
+ }
262
+ const approved = await dependencies.confirmSubmission(
263
+ 'send this compatibility report to the rnx team?',
264
+ false,
265
+ )
266
+ if (!approved) {
267
+ dependencies.stdout(`\n not sent.\n`)
268
+ return 2
269
+ }
270
+ }
271
+
272
+ const endpoint = reportEndpoint()
273
+ const headers: Record<string, string> = { 'content-type': 'application/json' }
274
+ if (endpoint.authorization) headers.authorization = endpoint.authorization
275
+
276
+ let response: Response
277
+ try {
278
+ response = await dependencies.request(endpoint.url, {
279
+ method: 'POST',
280
+ headers,
281
+ body: JSON.stringify(payload),
282
+ signal: AbortSignal.timeout(15_000),
283
+ })
284
+ } catch (error) {
285
+ dependencies.stderr(
286
+ ` report failed: ${error instanceof Error ? error.message : String(error)}\n`,
287
+ )
288
+ return 1
289
+ }
290
+
291
+ if (!response.ok) {
292
+ const detail = (await response.text().catch(() => '')).slice(0, 240)
293
+ dependencies.stderr(
294
+ ` report failed: ${response.status} ${response.statusText}${
295
+ detail ? ` — ${detail}` : ''
296
+ }\n`,
297
+ )
298
+ return 1
299
+ }
300
+
301
+ const parsed: unknown = await response.json().catch(() => null)
302
+ const id = readResponseId(parsed)
303
+ dependencies.stdout(id ? `\n sent. Report id: ${id}\n` : `\n sent. Thank you.\n`)
304
+ return 0
305
+ }
@@ -0,0 +1,85 @@
1
+ import { printBridgeFailureDiagnostics } from '../bridge-diagnostics'
2
+ import { createBridgeFromParsed, parseBridgeCliArgs } from '../ws-bridge'
3
+ import type { ResetResult } from '../../src/bridge-contract'
4
+
5
+ function isResetResult(value: unknown): value is ResetResult {
6
+ if (!value || typeof value !== 'object') return false
7
+ const strategy = Reflect.get(value, 'strategy')
8
+ return (
9
+ typeof Reflect.get(value, 'ok') === 'boolean' &&
10
+ (strategy === 'data' || strategy === 'full') &&
11
+ Array.isArray(Reflect.get(value, 'cleared')) &&
12
+ typeof Reflect.get(value, 'relaunched') === 'boolean'
13
+ )
14
+ }
15
+
16
+ function printHelp(): void {
17
+ console.log(`
18
+ rnxsim reset - clear the current guest app and relaunch it
19
+
20
+ usage:
21
+ rnxsim reset [--full] [--json] [--sim <id>]
22
+
23
+ options:
24
+ --full also clear keychain, user defaults, and permissions
25
+ --json print the structured reset result
26
+ --sim <id> target a specific sim
27
+ --port <p> WS bridge port
28
+ `)
29
+ }
30
+
31
+ export async function runReset(
32
+ args: string[],
33
+ opts: { port?: number } = {},
34
+ ): Promise<number> {
35
+ if (args.includes('--help') || args.includes('-h')) {
36
+ printHelp()
37
+ return 0
38
+ }
39
+
40
+ const parsed = parseBridgeCliArgs(args, {
41
+ port: opts.port,
42
+ stripBooleanFlags: ['--full', '--json'],
43
+ })
44
+ if (parsed.positional.length > 0) {
45
+ console.error(` unexpected reset argument: ${parsed.positional[0]}`)
46
+ return 1
47
+ }
48
+
49
+ const bridge = createBridgeFromParsed(parsed)
50
+ try {
51
+ const value: unknown = await bridge.send({
52
+ type: 'reset',
53
+ resetOptions: { strategy: args.includes('--full') ? 'full' : 'data' },
54
+ })
55
+ if (!isResetResult(value)) {
56
+ throw new Error('reset bridge returned an invalid result')
57
+ }
58
+
59
+ if (args.includes('--json')) {
60
+ console.log(JSON.stringify(value))
61
+ } else {
62
+ console.log(` ${value.strategy} reset ${value.ok ? 'complete' : 'failed'}`)
63
+ console.log(
64
+ value.cleared.length > 0
65
+ ? ` cleared: ${value.cleared.join(', ')}`
66
+ : ' cleared: none',
67
+ )
68
+ for (const skipped of value.skipped ?? []) {
69
+ console.log(` skipped ${skipped.store}: ${skipped.reason}`)
70
+ }
71
+ console.log(` app: ${value.relaunched ? 'relaunched' : 'not relaunched'}`)
72
+ console.log(
73
+ ` worker: ${value.workerReloaded ? 'restarted' : 'preserved in place'}`,
74
+ )
75
+ if (value.error) console.error(` error: ${value.error}`)
76
+ }
77
+ return value.ok ? 0 : 1
78
+ } catch (error) {
79
+ console.error(` reset failed: ${error instanceof Error ? error.message : error}`)
80
+ await printBridgeFailureDiagnostics(bridge)
81
+ return 1
82
+ } finally {
83
+ bridge.close()
84
+ }
85
+ }