rnxsim 0.1.366 → 0.1.367

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 (239) hide show
  1. package/README.md +14 -2
  2. package/cli/bin.ts +18 -0
  3. package/cli/bridge-flow-runner.ts +14 -151
  4. package/cli/commands/assert.ts +1 -1
  5. package/cli/commands/box/checkout-plane.ts +126 -0
  6. package/cli/commands/box/rnx-command.ts +68 -0
  7. package/cli/commands/box.ts +200 -0
  8. package/cli/commands/control.ts +12 -32
  9. package/cli/commands/do-chain.ts +412 -0
  10. package/cli/commands/flow.ts +0 -10
  11. package/cli/commands/inspect/core.ts +302 -725
  12. package/cli/commands/inspect/describe.ts +3 -76
  13. package/cli/commands/inspect/find.ts +3 -6
  14. package/cli/commands/inspect/get-layout.ts +14 -1
  15. package/cli/commands/inspect/resolve-target.ts +41 -47
  16. package/cli/commands/inspect/shared.ts +28 -123
  17. package/cli/commands/inspect/tree.ts +6 -15
  18. package/cli/commands/inspect/wait-ready.ts +2 -2
  19. package/cli/commands/inspect/wait-selector.ts +4 -8
  20. package/cli/commands/inspect.ts +23 -17
  21. package/cli/commands/install-desktop.ts +44 -7
  22. package/cli/commands/maestro-generate.ts +0 -2
  23. package/cli/commands/platform.ts +68 -0
  24. package/cli/commands/state.ts +5 -2
  25. package/cli/outbound-endpoints.ts +6 -1
  26. package/cli/parse-args.ts +13 -2
  27. package/cli/ws-bridge.ts +30 -2
  28. package/detox/index.ts +34 -17
  29. package/dist-cli/bin.js +5 -5
  30. package/dist-cli/chunks/{agent-SO6IOPRK.js → agent-EKKIAKP5.js} +2 -2
  31. package/dist-cli/chunks/{agent-wrapper-PMYCB2KO.js → agent-wrapper-MHLQUGA6.js} +2 -2
  32. package/dist-cli/chunks/{app-fonts-LULQGFY7.js → app-fonts-HN6ADRTQ.js} +2 -2
  33. package/dist-cli/chunks/{assert-WGNCD4ZU.js → assert-IMR6QCN6.js} +3 -3
  34. package/dist-cli/chunks/{auth-G7CCHH3M.js → auth-27LPMQNH.js} +2 -2
  35. package/dist-cli/chunks/{beta-N4LXL5TO.js → beta-6RXBB5AI.js} +2 -2
  36. package/dist-cli/chunks/box-DORLF3GP.js +1709 -0
  37. package/dist-cli/chunks/{camera-4JHCYBQS.js → camera-2G7JZ5DL.js} +2 -2
  38. package/dist-cli/chunks/{chunk-2UXU53MG.js → chunk-3QZJLNYY.js} +1 -1
  39. package/dist-cli/chunks/{chunk-YXXKSL6R.js → chunk-3VBVEDDA.js} +1 -1
  40. package/dist-cli/chunks/{chunk-ZJIS3CTW.js → chunk-4BWGLTKU.js} +2 -2
  41. package/dist-cli/chunks/chunk-4XSNO374.js +423 -0
  42. package/dist-cli/chunks/{chunk-RYIMSKDO.js → chunk-5DGMFUZG.js} +2 -2
  43. package/dist-cli/chunks/{chunk-M3BNCF7E.js → chunk-6DBS5EGX.js} +2 -2
  44. package/dist-cli/chunks/{chunk-ONORMKWX.js → chunk-6SO6I3D5.js} +2 -2
  45. package/dist-cli/chunks/chunk-75EFOPXE.js +32 -0
  46. package/dist-cli/chunks/{chunk-5NMCF5VF.js → chunk-A5AJFVOF.js} +1 -1
  47. package/dist-cli/chunks/{chunk-N3UC7HIX.js → chunk-AM2ODYAN.js} +1 -1
  48. package/dist-cli/chunks/{chunk-I6KIM6PN.js → chunk-AVOROGA3.js} +1 -1
  49. package/dist-cli/chunks/chunk-AXMMLO7D.js +130 -0
  50. package/dist-cli/chunks/{chunk-ORWP2E7R.js → chunk-BSEXEYNX.js} +2 -2
  51. package/dist-cli/chunks/{chunk-NQFJOCSF.js → chunk-CM6ZKZW7.js} +2 -2
  52. package/dist-cli/chunks/{chunk-ZMJ75EDG.js → chunk-DNVABCEC.js} +2 -2
  53. package/dist-cli/chunks/{chunk-2S7BKUP2.js → chunk-E33A4AIR.js} +2 -2
  54. package/dist-cli/chunks/{chunk-GXAB52K7.js → chunk-EFMOXYDD.js} +2 -2
  55. package/dist-cli/chunks/{chunk-TIAEYO6I.js → chunk-EV4P5UBP.js} +2 -2
  56. package/dist-cli/chunks/{chunk-JHXETDVC.js → chunk-G5IUIGGC.js} +1 -1
  57. package/dist-cli/chunks/chunk-GMLOCV3E.js +312 -0
  58. package/dist-cli/chunks/{chunk-ZLVRYXZ7.js → chunk-GRN2FHVW.js} +1 -1
  59. package/dist-cli/chunks/{chunk-A5FXX5PJ.js → chunk-HFFXPUEP.js} +1 -1
  60. package/dist-cli/chunks/chunk-HG6T4OOR.js +4 -0
  61. package/dist-cli/chunks/{chunk-OW5XHAA4.js → chunk-HNT2OXPZ.js} +1 -1
  62. package/dist-cli/chunks/chunk-IPEURNLI.js +24 -0
  63. package/dist-cli/chunks/chunk-IR44SFBA.js +5 -0
  64. package/dist-cli/chunks/chunk-JMSLXZFW.js +4 -0
  65. package/dist-cli/chunks/{chunk-EFR5DVNP.js → chunk-JPXQKLNH.js} +1 -1
  66. package/dist-cli/chunks/chunk-K3EC6JDE.js +4 -0
  67. package/dist-cli/chunks/{chunk-YGMEDJKJ.js → chunk-KHX65HAU.js} +2 -2
  68. package/dist-cli/chunks/{chunk-EQK5MJCU.js → chunk-LWOVKHRC.js} +2 -2
  69. package/dist-cli/chunks/{chunk-5OK3LCEJ.js → chunk-MQN5DWTI.js} +2 -2
  70. package/dist-cli/chunks/{chunk-TTASWLKM.js → chunk-N3BXQEUF.js} +1 -1
  71. package/dist-cli/chunks/{chunk-UCHW7ZHR.js → chunk-N5OSV26B.js} +2 -2
  72. package/dist-cli/chunks/chunk-PHNURIH3.js +4 -0
  73. package/dist-cli/chunks/{chunk-AFV32WZT.js → chunk-PP2KNVXP.js} +3 -3
  74. package/dist-cli/chunks/{chunk-XJU2QIRY.js → chunk-PROKNJVY.js} +2 -2
  75. package/dist-cli/chunks/chunk-QXLLY4IM.js +7 -0
  76. package/dist-cli/chunks/{chunk-HT6GFZOZ.js → chunk-RNQTOGM7.js} +1 -1
  77. package/dist-cli/chunks/{chunk-CN6XYYEA.js → chunk-RPNKKVBN.js} +27 -27
  78. package/dist-cli/chunks/{chunk-LN3RNW6X.js → chunk-RSNLI2NH.js} +2 -2
  79. package/dist-cli/chunks/{chunk-YCCCPFWT.js → chunk-RZGHV2WI.js} +2 -2
  80. package/dist-cli/chunks/chunk-SGGL3AFV.js +497 -0
  81. package/dist-cli/chunks/chunk-SH5ETJKG.js +4 -0
  82. package/dist-cli/chunks/{chunk-77ZHQJZR.js → chunk-T6J4YP56.js} +2 -2
  83. package/dist-cli/chunks/{chunk-MGDSJZ37.js → chunk-TWUE7WF5.js} +2 -2
  84. package/dist-cli/chunks/{chunk-SA6XVI55.js → chunk-U44VEQRN.js} +1 -1
  85. package/dist-cli/chunks/{chunk-IZKHOM37.js → chunk-URLVQHC3.js} +1 -1
  86. package/dist-cli/chunks/{chunk-GAJQSITE.js → chunk-VANZFTUE.js} +1 -1
  87. package/dist-cli/chunks/{chunk-EGAGZHO6.js → chunk-VB2YBH46.js} +1 -1
  88. package/dist-cli/chunks/{chunk-H23KWIKA.js → chunk-VFU2SJ7M.js} +2 -2
  89. package/dist-cli/chunks/{chunk-34IQM22N.js → chunk-VUBJ6FXU.js} +15 -15
  90. package/dist-cli/chunks/{chunk-NM2L2QV4.js → chunk-W5PATILQ.js} +2 -2
  91. package/dist-cli/chunks/chunk-WI5V4TYG.js +38 -0
  92. package/dist-cli/chunks/{chunk-6PL2CCGP.js → chunk-XTRHQAOV.js} +2 -2
  93. package/dist-cli/chunks/chunk-XWUTJLBM.js +27 -0
  94. package/dist-cli/chunks/{chunk-5DAIA77C.js → chunk-XYRUQQUR.js} +2 -2
  95. package/dist-cli/chunks/chunk-YBFB3RM7.js +4 -0
  96. package/dist-cli/chunks/chunk-YGQVQ2VG.js +4 -0
  97. package/dist-cli/chunks/{chunk-CTG7HBCA.js → chunk-YINACV32.js} +1 -1
  98. package/dist-cli/chunks/chunk-YV7ERO2V.js +5 -0
  99. package/dist-cli/chunks/{cleanup-KRIATKFH.js → cleanup-GVFHQ3KH.js} +2 -2
  100. package/dist-cli/chunks/cli-version-DPX5MA2M.js +4 -0
  101. package/dist-cli/chunks/{compat-6PTQ3QEA.js → compat-AYRTXYAM.js} +2 -2
  102. package/dist-cli/chunks/{config-ETGDUANO.js → config-K7LOOV62.js} +2 -2
  103. package/dist-cli/chunks/connect-H3CNY4IO.js +4 -0
  104. package/dist-cli/chunks/control-SMHZ2CF5.js +4 -0
  105. package/dist-cli/chunks/daemon-TEZUNI73.js +4 -0
  106. package/dist-cli/chunks/{debug-WIIB6ZKC.js → debug-ELGHG57T.js} +3 -3
  107. package/dist-cli/chunks/{desktop-TD7Q5LNB.js → desktop-4G7FK3MP.js} +3 -3
  108. package/dist-cli/chunks/{detox-7GNR33VM.js → detox-JKXGEJIZ.js} +2 -2
  109. package/dist-cli/chunks/{device-QOR3PGUF.js → device-IV3AR6KG.js} +2 -2
  110. package/dist-cli/chunks/{diagnose-RRCBLP6E.js → diagnose-3ERGF7EW.js} +2 -2
  111. package/dist-cli/chunks/{disk-cleanup-MJUGJPXT.js → disk-cleanup-ALFEVZ4B.js} +2 -2
  112. package/dist-cli/chunks/do-chain-K2B4OHM7.js +5 -0
  113. package/dist-cli/chunks/drivers-KJYXA3M3.js +4 -0
  114. package/dist-cli/chunks/env-2KF6IYZE.js +4 -0
  115. package/dist-cli/chunks/{film-D7Y64LID.js → film-UQXJFAD5.js} +3 -3
  116. package/dist-cli/chunks/flow-ASTUH56E.js +4 -0
  117. package/dist-cli/chunks/help-SNNYFELA.js +4 -0
  118. package/dist-cli/chunks/{hidden-runtime-alias-JGURVR2Z.js → hidden-runtime-alias-VJCWCFVO.js} +2 -2
  119. package/dist-cli/chunks/{home-paths-4ICFIGXO.js → home-paths-EGUZZ6J6.js} +2 -2
  120. package/dist-cli/chunks/inspect-XANAADQT.js +4 -0
  121. package/dist-cli/chunks/install-desktop-JKQA7UY6.js +4 -0
  122. package/dist-cli/chunks/{login-RU33QR2G.js → login-6KQGD7HK.js} +2 -2
  123. package/dist-cli/chunks/{logout-2IUG3Y5J.js → logout-2FCOVLBC.js} +2 -2
  124. package/dist-cli/chunks/{maestro-2MXTGG7I.js → maestro-HPSSEVJD.js} +3 -3
  125. package/dist-cli/chunks/{maestro-generate-2PYIFGLR.js → maestro-generate-KQQ6JHMR.js} +5 -5
  126. package/dist-cli/chunks/{mode-3DAPG3HF.js → mode-SH7KRZET.js} +2 -2
  127. package/dist-cli/chunks/{optional-demo-registry-BWSDJF2Z.js → optional-demo-registry-NAMCAVFX.js} +2 -2
  128. package/dist-cli/chunks/{perf-2TKPWB4N.js → perf-LWKAHXUL.js} +2 -2
  129. package/dist-cli/chunks/{permissions-5CSMHYNA.js → permissions-EZTKWTXV.js} +2 -2
  130. package/dist-cli/chunks/platform-KSOJIVN5.js +6 -0
  131. package/dist-cli/chunks/privacy-EJULWP7L.js +4 -0
  132. package/dist-cli/chunks/{record-I2HJCFP3.js → record-2IC7BAQN.js} +3 -3
  133. package/dist-cli/chunks/{report-issue-A4FZWBOC.js → report-issue-MMX6HOQO.js} +2 -2
  134. package/dist-cli/chunks/reset-PKFZA4NC.js +4 -0
  135. package/dist-cli/chunks/resolve-target-AFKU3BRE.js +4 -0
  136. package/dist-cli/chunks/runtime-XHWWPOIN.js +4 -0
  137. package/dist-cli/chunks/{screenshot-command-UFW5BFHP.js → screenshot-command-JYUXDVSA.js} +3 -3
  138. package/dist-cli/chunks/{screenshot-layers-5BIAL4YN.js → screenshot-layers-OGRY6AA3.js} +2 -2
  139. package/dist-cli/chunks/{screenshots-capture-EHYS3BV2.js → screenshots-capture-QHDN65XS.js} +2 -2
  140. package/dist-cli/chunks/{serve-O4FDM3AC.js → serve-W4BKAG4J.js} +3 -3
  141. package/dist-cli/chunks/setup-WJPMPSAC.js +4 -0
  142. package/dist-cli/chunks/sim-client-UOQGFBPO.js +4 -0
  143. package/dist-cli/chunks/{skills-ZK55SY32.js → skills-OPPXOD63.js} +2 -2
  144. package/dist-cli/chunks/state-TDAN7BOM.js +14 -0
  145. package/dist-cli/chunks/{storage-WP33ISEM.js → storage-CFB2YGLY.js} +2 -2
  146. package/dist-cli/chunks/store-4TEED4ZU.js +4 -0
  147. package/dist-cli/chunks/telemetry-S6N7CV6G.js +4 -0
  148. package/dist-cli/chunks/{timeline-DKGW5S4I.js → timeline-ASOOVP4C.js} +2 -2
  149. package/dist-cli/chunks/{upgrade-LL7G4B7G.js → upgrade-6MVJISHG.js} +2 -2
  150. package/dist-cli/chunks/upload-CBNIRFEW.js +4 -0
  151. package/dist-cli/chunks/{version-YLWR5G4F.js → version-5GS7CWRL.js} +2 -2
  152. package/dist-cli/chunks/{web-QELZ4CP6.js → web-QRRMYMV4.js} +2 -2
  153. package/dist-cli/chunks/welcome-33FXMAMB.js +5 -0
  154. package/dist-cli/chunks/{what-happened-MIOMZWM5.js → what-happened-GAZJGKXX.js} +2 -2
  155. package/dist-cli/chunks/ws-bridge-DIXUAPLQ.js +4 -0
  156. package/dist-lib/agent-daemon-client.cjs +1 -1
  157. package/dist-lib/agent-events.cjs +1 -1
  158. package/dist-lib/agent-identity.cjs +1 -1
  159. package/dist-lib/agent-sessions.cjs +1 -1
  160. package/dist-lib/attached-projects.cjs +1 -1
  161. package/dist-lib/auth/shared-session.cjs +1 -1
  162. package/dist-lib/backend-origin.cjs +1 -1
  163. package/dist-lib/beta.cjs +1 -1
  164. package/dist-lib/beta.mjs +1 -1
  165. package/dist-lib/bridge-constants.cjs +1 -1
  166. package/dist-lib/bridge-contract-input.cjs +336 -0
  167. package/dist-lib/bridge-contract-input.mjs +303 -0
  168. package/dist-lib/bridge-contract.cjs +29 -1
  169. package/dist-lib/bridge-contract.mjs +19 -0
  170. package/dist-lib/cli-constants.cjs +1 -1
  171. package/dist-lib/config.cjs +1 -1
  172. package/dist-lib/detox/index.cjs +32 -18
  173. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  174. package/dist-lib/home-paths.cjs +1 -1
  175. package/dist-lib/host/bridge-host.cjs +5 -1
  176. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  177. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  178. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  179. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  180. package/dist-lib/host/websocket-proxy.cjs +1 -1
  181. package/dist-lib/index.cjs +214 -594
  182. package/dist-lib/jump-to-source-babel.cjs +1 -1
  183. package/dist-lib/menu.cjs +1 -1
  184. package/dist-lib/menu.mjs +1 -1
  185. package/dist-lib/metro-production-bundle.cjs +1 -1
  186. package/dist-lib/metro-production-bundle.mjs +1 -1
  187. package/dist-lib/metro.cjs +1 -1
  188. package/dist-lib/profiles.cjs +1 -1
  189. package/dist-lib/public-brand.cjs +1 -1
  190. package/dist-lib/react-native-host-modules.cjs +1 -1
  191. package/dist-lib/react-native-host-modules.mjs +1 -1
  192. package/dist-lib/render-mode.cjs +1 -1
  193. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  194. package/dist-lib/sdk.cjs +273 -657
  195. package/dist-lib/sdk.mjs +271 -652
  196. package/dist-lib/skills.cjs +190 -287
  197. package/dist-lib/vite.cjs +1 -1
  198. package/package.json +9 -6
  199. package/skills/contrast/SKILL.md +3 -0
  200. package/skills/rnx-debug/SKILL.md +8 -0
  201. package/skills/rnx-test/SKILL.md +21 -0
  202. package/src/bridge-contract-input.ts +359 -0
  203. package/src/bridge-contract.ts +121 -1
  204. package/src/host/bridge-host.ts +7 -12
  205. package/src/index.ts +7 -0
  206. package/src/sim-client.ts +12 -3
  207. package/dist-cli/chunks/chunk-3X6IBUBX.js +0 -38
  208. package/dist-cli/chunks/chunk-7B37IZBN.js +0 -15
  209. package/dist-cli/chunks/chunk-DMPF2D24.js +0 -4
  210. package/dist-cli/chunks/chunk-DW37EVX5.js +0 -767
  211. package/dist-cli/chunks/chunk-DWFIH7CB.js +0 -32
  212. package/dist-cli/chunks/chunk-GUI3PDH2.js +0 -27
  213. package/dist-cli/chunks/chunk-KLF3K6ZZ.js +0 -4
  214. package/dist-cli/chunks/chunk-M5QCGLXR.js +0 -944
  215. package/dist-cli/chunks/chunk-M6SKQGAN.js +0 -5
  216. package/dist-cli/chunks/chunk-NAYLPOC5.js +0 -24
  217. package/dist-cli/chunks/chunk-VIND4SP3.js +0 -124
  218. package/dist-cli/chunks/chunk-XXNLYR64.js +0 -5
  219. package/dist-cli/chunks/chunk-ZFM24DOX.js +0 -4
  220. package/dist-cli/chunks/cli-version-SYGNHGFR.js +0 -4
  221. package/dist-cli/chunks/control-RBTNOLQM.js +0 -4
  222. package/dist-cli/chunks/daemon-N3SC5DK6.js +0 -4
  223. package/dist-cli/chunks/drivers-W6E3BZH4.js +0 -4
  224. package/dist-cli/chunks/flow-7QAE2V5Y.js +0 -4
  225. package/dist-cli/chunks/help-NLD6KWVG.js +0 -4
  226. package/dist-cli/chunks/inspect-C347BG52.js +0 -4
  227. package/dist-cli/chunks/install-desktop-YR6TWZYK.js +0 -4
  228. package/dist-cli/chunks/privacy-PWWC2BXO.js +0 -4
  229. package/dist-cli/chunks/reset-Y3PBPFYA.js +0 -4
  230. package/dist-cli/chunks/runtime-IC6NVVGA.js +0 -4
  231. package/dist-cli/chunks/setup-Y4QGSJBM.js +0 -4
  232. package/dist-cli/chunks/state-KFLAZNEY.js +0 -14
  233. package/dist-cli/chunks/store-VEE22CAY.js +0 -4
  234. package/dist-cli/chunks/telemetry-PZV4BISJ.js +0 -4
  235. package/dist-cli/chunks/upload-Y4C3YZDK.js +0 -4
  236. package/dist-cli/chunks/welcome-ZPKA5PZJ.js +0 -5
  237. package/dist-lib/mcp.cjs +0 -673
  238. package/dist-lib/mcp.mjs +0 -641
  239. package/src/mcp.ts +0 -791
@@ -0,0 +1,312 @@
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ function X(t,e){let n=["--max-ms","--maxMs","--maxms","--max_ms"];for(let r of n){let s=t.indexOf(r);if(s>=0&&t[s+1]){let o=Number(t[s+1]);if(Number.isFinite(o))return Math.max(100,o)}}return e}var P=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function _(t){return typeof t=="string"&&P.has(t)}async function A(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function G(t,e){if(!_(e))return!1;try{return await A(t)}catch{return!1}}async function V(t){let e=await t.send({type:"query",query:{kind:"count"}});return{nodes:b(e)?e.total:0}}async function Z(t,e=5){let n=await t.send({type:"query",query:{kind:"tree",depth:e}}),r=b(n)?n.nodes:[];return{depth:e,tree:r}}async function ee(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}function C(t){return t!==null&&typeof t=="object"&&[Reflect.get(t,"x"),Reflect.get(t,"y"),Reflect.get(t,"width"),Reflect.get(t,"height")].every(e=>typeof e=="number"?Number.isFinite(e):!1)}function I(t){return Array.isArray(t)?t.every(e=>{if(e===null||typeof e!="object"||!Number.isInteger(Reflect.get(e,"nodeId"))||typeof Reflect.get(e,"type")!="string"||!C(Reflect.get(e,"geometry")))return!1;for(let s of["testID","text","role","label"]){let o=Reflect.get(e,s);if(o!==void 0&&typeof o!="string")return!1}let n=Reflect.get(e,"pressable");if(n!==void 0&&n!==!0)return!1;let r=Reflect.get(e,"children");return r===void 0||I(r)}):!1}function b(t){let e=t!==null&&typeof t=="object"?Reflect.get(t,"total"):void 0;return t!==null&&typeof t=="object"&&typeof e=="number"&&Number.isInteger(e)&&e>=0&&I(Reflect.get(t,"nodes"))}function N(t){let e=t.replace(/[.+^$(){}|[\]\\]/g,"\\$&");return new RegExp(`^${e.replace(/\*/g,".*").replace(/\?/g,".")}$`,"i")}function F(t,e={}){let n=e.filter?.toLowerCase()??"",r=e.testIdLike?N(e.testIdLike):null,s=e.onlyGlob?N(e.onlyGlob):null,o=[],i=(a,y)=>{let p=[a.role,a.label,a.text,a.testID].filter(d=>typeof d=="string").join(" ");if((!n||p.toLowerCase().includes(n))&&(!r||r.test(a.testID??""))&&(!s||s.test(p))){let d=[a.role?`[${a.role}]`:a.pressable?"[tap]":`<${a.type}>`];if(a.text){let g=e.fullText||a.text.length<=50?a.text:`${a.text.slice(0,49).trimEnd()}\u2026`;d.push(JSON.stringify(g))}if(a.testID&&d.push(`#${a.testID}`),a.label&&a.label!==a.text&&d.push(`label=${JSON.stringify(a.label)}`),!e.hideXy){let g=a.geometry;d.push(`@(${Math.round(g.x)},${Math.round(g.y)}) ${Math.round(g.width)}x${Math.round(g.height)}`)}a.pressable&&d.push("(tap)"),o.push(`${" ".repeat(y+1)}${d.join(" ")}`)}for(let d of a.children??[])i(d,y+1)},u=t;if(e.subtreeRoot){let a=[...t],y;for(;a.length>0&&!y;){let p=a.shift();p&&(p.testID===e.subtreeRoot?y=p:a.push(...p.children??[]))}if(!y)return`__SUBTREE_NOT_FOUND__:${e.subtreeRoot}`;u=[y]}for(let a of u)i(a,0);return o.join(`
5
+ `)}async function te(t,e){let n=e.maxDepth??12,r=await t.send({type:"query",query:{kind:"tree",depth:n}});return b(r)?{tree:F(r.nodes,e),nodeCount:r.total}:{}}function W(t){let e=t.fontSize>=18||t.fontSize>=14&&(t.fontWeight??400)>=700?3:4.5,{normal:n,background:r}=t;if(n.width<=0||n.height<=0||n.width!==r.width||n.height!==r.height)return{ratio:null,required:e,reason:"capture dimensions do not match"};let s=Math.max(0,Math.floor(t.box.x)),o=Math.max(0,Math.floor(t.box.y)),i=Math.min(n.width,Math.ceil(t.box.x+t.box.w)),u=Math.min(n.height,Math.ceil(t.box.y+t.box.h));if(i<=s||u<=o)return{ratio:null,required:e,reason:"text is outside the captured frame"};let a=l=>{let c=l/255;return c<=.04045?c/12.92:Math.pow((c+.055)/1.055,2.4)},y=(l,c)=>{let m=.2126*a(l[0])+.7152*a(l[1])+.0722*a(l[2]),x=.2126*a(c[0])+.7152*a(c[1])+.0722*a(c[2]);return(Math.max(m,x)+.05)/(Math.min(m,x)+.05)},p=l=>`#${l.slice(0,3).map(c=>Math.round(c).toString(16).padStart(2,"0")).join("")}`,R=(i-s)*(u-o),d=Math.max(1,Math.floor(Math.sqrt(R/12e3))),g=(l,c)=>(c*n.width+l)*4,$=l=>Math.max(Math.abs(n.data[l]-r.data[l]),Math.abs(n.data[l+1]-r.data[l+1]),Math.abs(n.data[l+2]-r.data[l+2])),S=0,w=null,f=null;for(let l=o;l<u;l+=d)for(let c=s;c<i;c+=d){let m=g(c,l);if(r.data[m+3]<250)continue;let x=[r.data[m],r.data[m+1],r.data[m+2]];f??=x;let M=$(m);M<=S||(S=M,w=[n.data[m],n.data[m+1],n.data[m+2]])}let h=1/0,v=null,k=null,E=(l,c)=>{let m=y(l,c);m>=h||(h=m,v=l,k=c)};if(S>=2&&w)for(let l=o;l<u;l+=d)for(let c=s;c<i;c+=d){let m=g(c,l);r.data[m+3]<250||$(m)<2||E(w,[r.data[m],r.data[m+1],r.data[m+2]])}else f&&E(f,f);return!v||!k||!Number.isFinite(h)?{ratio:null,required:e,reason:"could not isolate opaque rendered text pixels"}:{ratio:Math.round(h*100)/100,required:e,foreground:p(v),background:p(k)}}function O(t={}){let e=t.styling===!0,n=t.filter?.trim().toLowerCase()??"";return`(async () => {
6
+ const t = window.__sootsimTest
7
+ if (!t || typeof t.listInspectable !== 'function') return []
8
+ const list = await t.listInspectable({})
9
+ if (!Array.isArray(list)) return []
10
+ const includeStyle = ${JSON.stringify(e)}
11
+ const scoreContrast = ${W.toString()}
12
+ // narrows by ELEMENT, not by style field: fewer rows, full detail on each.
13
+ const filter = ${JSON.stringify(n)}
14
+ const matchesFilter = (n, text) => {
15
+ if (!filter) return true
16
+ const fields = [text, n.testID || n.testId, n.accessibilityRole || n.role, n.type]
17
+ return fields.some((f) => typeof f === 'string' && f.toLowerCase().includes(filter))
18
+ }
19
+
20
+ const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0)
21
+ const round = (v) => Math.round(num(v))
22
+
23
+ // borderRadius can be authored as a string ("12px") or split per-corner;
24
+ // prefer the uniform borderRadius, else the largest corner radius present.
25
+ const radiusOf = (style) => {
26
+ if (!style) return 0
27
+ const keys = ['borderRadius','borderTopLeftRadius','borderTopRightRadius','borderBottomLeftRadius','borderBottomRightRadius']
28
+ let max = 0
29
+ for (const k of keys) {
30
+ const raw = style[k]
31
+ const n = typeof raw === 'number' ? raw : (typeof raw === 'string' ? parseFloat(raw) : NaN)
32
+ if (Number.isFinite(n)) max = Math.max(max, n)
33
+ }
34
+ return Math.round(max)
35
+ }
36
+ const fontSizeOf = (style) => {
37
+ if (!style) return 0
38
+ const raw = style.fontSize
39
+ const n = typeof raw === 'number' ? raw : (typeof raw === 'string' ? parseFloat(raw) : NaN)
40
+ return Number.isFinite(n) ? Math.round(n) : 0
41
+ }
42
+ // styling extractors \u2014 omit boring defaults so the agent only sees notable
43
+ // styling (low opacity, struck text, clipping, a real border/color).
44
+ const colorStr = (v) => {
45
+ if (v == null) return undefined
46
+ const s = String(v).split(' ').join('')
47
+ return s && s !== 'transparent' && s !== 'rgba(0,0,0,0)' ? s : undefined
48
+ }
49
+ const opacityOf = (style) => {
50
+ const o = style && style.opacity
51
+ const n = typeof o === 'number' ? o : (typeof o === 'string' ? parseFloat(o) : NaN)
52
+ return Number.isFinite(n) && n < 1 ? Math.round(n * 100) / 100 : undefined
53
+ }
54
+ const weightOf = (style) => {
55
+ const w = style && style.fontWeight
56
+ const n = w === 'bold' ? 700 : (typeof w === 'number' ? w : (typeof w === 'string' ? parseInt(w, 10) : NaN))
57
+ return Number.isFinite(n) && n >= 600 ? n : undefined
58
+ }
59
+ const decoOf = (style) => {
60
+ const d = style && (style.textDecorationLine || style.textDecoration)
61
+ return d && d !== 'none' && d !== 'normal' ? String(d).split(' ')[0] : undefined
62
+ }
63
+ const overflowOf = (style) => (style && style.overflow === 'hidden' ? 'hidden' : undefined)
64
+ const borderWOf = (style) => {
65
+ if (!style) return undefined
66
+ const keys = ['borderWidth','borderTopWidth','borderBottomWidth','borderLeftWidth','borderRightWidth']
67
+ let max = 0
68
+ for (const k of keys) {
69
+ const r = style[k]
70
+ const n = typeof r === 'number' ? r : (typeof r === 'string' ? parseFloat(r) : NaN)
71
+ if (Number.isFinite(n)) max = Math.max(max, n)
72
+ }
73
+ return max > 0 ? Math.round(max) : undefined
74
+ }
75
+ // only meaningful alongside a real border width, so it is resolved by the
76
+ // caller below rather than on its own.
77
+ const borderColorOf = (style) => {
78
+ if (!style) return undefined
79
+ const keys = ['borderColor','borderTopColor','borderBottomColor','borderLeftColor','borderRightColor']
80
+ for (const k of keys) {
81
+ const c = colorStr(style[k])
82
+ if (c) return c
83
+ }
84
+ return undefined
85
+ }
86
+
87
+ const isVisible = (n) => {
88
+ const layout = n && n.layout
89
+ if (!layout || layout.width <= 0 || layout.height <= 0) return false
90
+ const abs = (n && (n.absolute || n.absolutePosition)) || null
91
+ if (!abs) return true
92
+ const device = (n && n.device) || {}
93
+ const screenW = Number(device.width) || window.innerWidth || 0
94
+ const screenH = Number(device.height) || window.innerHeight || 0
95
+ if (!screenW || !screenH) return true
96
+ return abs.x + layout.width > 0 && abs.y + layout.height > 0 && abs.x < screenW && abs.y < screenH
97
+ }
98
+
99
+ const elements = list.filter(isVisible).filter((n) => {
100
+ const t = typeof n.text === 'string' && n.text.trim() ? n.text.trim() : undefined
101
+ return matchesFilter(n, t)
102
+ }).map((n) => {
103
+ const layout = n.layout || { x: 0, y: 0, width: 0, height: 0 }
104
+ const abs = n.absolute || n.absolutePosition || { x: layout.x, y: layout.y }
105
+ const text = typeof n.text === 'string' && n.text.trim() ? n.text.trim() : undefined
106
+ const base = {
107
+ ...(typeof n.nodeId === 'number'
108
+ ? {
109
+ nodeId: n.nodeId,
110
+ ancestorIds: Array.isArray(n.ancestors)
111
+ ? n.ancestors.map((ancestor) => ancestor && ancestor.nodeId).filter((id) => typeof id === 'number')
112
+ : [],
113
+ }
114
+ : {}),
115
+ testID: n.testID || n.testId || undefined,
116
+ role: n.accessibilityRole || n.role || undefined,
117
+ type: typeof n.type === 'string' ? n.type : 'node',
118
+ text,
119
+ box: { x: round(abs.x), y: round(abs.y), w: round(layout.width), h: round(layout.height) },
120
+ }
121
+ if (!includeStyle) return base
122
+ // computedStyle has the resolved values; style is the curated subset \u2014
123
+ // fall back across both so radius/fontSize survive either shape.
124
+ const style = Object.assign({}, n.style || {}, n.computedStyle || {})
125
+ const pad = (n.boxModel && n.boxModel.padding) || {}
126
+ const borderWidth = borderWOf(style)
127
+ return {
128
+ ...base,
129
+ borderRadius: radiusOf(style),
130
+ padding: { t: round(pad.top), r: round(pad.right), b: round(pad.bottom), l: round(pad.left) },
131
+ fontSize: text ? (fontSizeOf(style) || 14) : 0,
132
+ color: text ? colorStr(style.color) : undefined,
133
+ bg: colorStr(style.backgroundColor),
134
+ opacity: opacityOf(style),
135
+ fontWeight: weightOf(style),
136
+ textDecoration: decoOf(style),
137
+ overflow: overflowOf(style),
138
+ borderWidth,
139
+ borderColor: borderWidth ? borderColorOf(style) : undefined,
140
+ }
141
+ })
142
+ const textElements = elements.filter((element) => element.text && element.fontSize > 0)
143
+ if (!includeStyle || textElements.length === 0) return elements
144
+
145
+ const screenshot = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.screenshot
146
+ if (typeof screenshot !== 'function') {
147
+ throw new Error('styled native layout requires the rnx capture bridge')
148
+ }
149
+ const device = list.find((node) => node && node.device)?.device || {}
150
+ const width = Math.round(Number(device.width) || window.innerWidth || 0)
151
+ const height = Math.round(Number(device.height) || window.innerHeight || 0)
152
+ if (!width || !height) throw new Error('native layout has no capture dimensions')
153
+ const capture = async (suppressText) => {
154
+ const dataUrl = await screenshot({
155
+ format: 'png',
156
+ outputWidth: width,
157
+ outputHeight: height,
158
+ ...(suppressText ? { suppressText: true } : {}),
159
+ })
160
+ const image = await new Promise((resolve, reject) => {
161
+ const next = new Image()
162
+ next.onload = () => resolve(next)
163
+ next.onerror = () => reject(new Error('could not decode native layout pixels'))
164
+ next.src = dataUrl
165
+ })
166
+ const canvas = document.createElement('canvas')
167
+ canvas.width = image.naturalWidth
168
+ canvas.height = image.naturalHeight
169
+ const context = canvas.getContext('2d', { willReadFrequently: true })
170
+ if (!context) throw new Error('could not read native layout pixels')
171
+ context.drawImage(image, 0, 0)
172
+ return context.getImageData(0, 0, canvas.width, canvas.height)
173
+ }
174
+ const normal = await capture(false)
175
+ const background = await capture(true)
176
+ for (const element of textElements) {
177
+ element.contrast = scoreContrast({
178
+ normal,
179
+ background,
180
+ box: element.box,
181
+ fontSize: element.fontSize,
182
+ fontWeight: element.fontWeight,
183
+ })
184
+ }
185
+ return elements
186
+ })()`}var re=O();async function ne(t,e={}){if(!e.styling){let r=await t.send({type:"query",query:{kind:"find",selector:{visible:!0}}});if(!b(r))return[];let s=e.filter?.trim().toLowerCase()??"";return r.nodes.filter(o=>s?[o.text,o.testID,o.role,o.type].some(i=>typeof i=="string"&&i.toLowerCase().includes(s)):!0).map(o=>({nodeId:o.nodeId,...o.testID?{testID:o.testID}:{},...o.role?{role:o.role}:{},type:o.type,...o.text?{text:o.text}:{},box:{x:Math.round(o.geometry.x),y:Math.round(o.geometry.y),w:Math.round(o.geometry.width),h:Math.round(o.geometry.height)}}))}let n=await t.send({type:"evaluate",code:O(e)});return Array.isArray(n)?n:[]}function oe(t,e){return t.length===0?" no visible elements found":t.map(r=>{let o=[r.testID?`#${r.testID}`:r.selector?r.selector:r.role?`[${r.role}]`:`<${r.type}>`,`@(${r.box.x},${r.box.y})`,`${r.box.w}x${r.box.h}`];r.borderRadius!==void 0&&r.borderRadius>0&&o.push(`radius:${r.borderRadius}`);let i=r.padding;if(i&&(i.t||i.r||i.b||i.l)){let u=i.t===i.r&&i.r===i.b&&i.b===i.l;o.push(u?`pad:${i.t}`:`pad:${i.t},${i.r},${i.b},${i.l}`)}if(r.fontSize!==void 0&&r.fontSize>0&&o.push(`font:${r.fontSize}`),e?.styling){if(r.fontWeight&&o.push(`weight:${r.fontWeight}`),r.color&&o.push(`color:${r.color}`),r.bg&&o.push(`bg:${r.bg}`),r.contrast){let u=r.contrast.ratio==null?`?/${r.contrast.required}`:`${r.contrast.ratio}/${r.contrast.required}${r.contrast.ratio<r.contrast.required?" FAIL":""}`;o.push(`contrast:${u}`),r.contrast.background&&o.push(`on:${r.contrast.background}`)}r.opacity!=null&&o.push(`opacity:${r.opacity}`),r.textDecoration&&o.push(`deco:${r.textDecoration}`),r.overflow&&o.push(`overflow:${r.overflow}`),r.borderWidth&&o.push(r.borderColor?`border:${r.borderWidth}/${r.borderColor}`:`border:${r.borderWidth}`)}if(r.text){let u=r.text.length>40?`${r.text.slice(0,39)}\u2026`:r.text;o.push(`"${u}"`)}return` ${o.join(" ")}`}).join(`
187
+ `)}async function se(t){let e=await t.send({type:"query",query:{kind:"find",selector:{visible:!0}}});return b(e)?e.nodes.flatMap(n=>!n.role&&!n.label&&!n.text&&!n.pressable?[]:[{role:n.role??(n.pressable?"button":n.type==="text"?"statictext":"none"),label:n.label??n.text??null,hint:null,state:null,testID:n.testID??null,position:{x:Math.round(n.geometry.x),y:Math.round(n.geometry.y)},size:{w:Math.round(n.geometry.width),h:Math.round(n.geometry.height)}}]):[]}function B(t){return t.testId?{mode:"testid",selector:{testID:t.testId}}:t.role?{mode:"role",selector:{role:t.role}}:t.type?{mode:"type",selector:{type:t.type}}:t.pressable?{mode:"pressable",selector:{pressable:!0}}:t.interactive?{mode:"interactive-targets",selector:{pressable:!0}}:t.visible?{mode:"visible",selector:{visible:!0}}:t.text?{mode:"text",selector:{text:t.text}}:null}async function ie(t,e){let n=B(e);if(!n)return null;let r=await t.send({type:"query",query:{kind:"find",selector:n.selector}});if(!b(r))return{mode:n.mode,result:[]};let s=r.nodes.map(i=>({type:i.type,nodeId:i.nodeId,...i.testID?{testID:i.testID}:{},...i.text?{text:i.text}:{},...i.pressable?{pressable:!0}:{},...i.role?{accessibilityRole:i.role}:{},...i.label?{accessibilityLabel:i.label}:{},absolutePosition:{x:i.geometry.x,y:i.geometry.y},layout:{width:i.geometry.width,height:i.geometry.height}})),o=n.mode==="testid"||n.mode==="text"?s[0]??null:s;return{mode:n.mode,result:o}}function ae(t){return[...t].sort((e,n)=>T(n)-T(e))}function T(t){let e=0;t.testID&&(e+=100),typeof t.text=="string"&&t.text.trim().length>0&&(e+=60),typeof t.accessibilityLabel=="string"&&t.accessibilityLabel.trim().length>0&&(e+=30),t.accessibilityRole&&(e+=15);let n=t.layout?.width??0,r=t.layout?.height??0,s=n*r;return s>=400&&s<=6e4?e+=25:s>6e4&&(e-=20),(t.absolutePosition?.y??0)<0&&(e-=30),e}function le(t){if(t.testID)return`rnx do tap-id ${L(t.testID)}`;let e=typeof t.text=="string"?t.text.trim():"";if(e.length>0&&e.length<=80)return`rnx do tap-text ${L(e)}`;let n=Math.round(((t.absolutePosition?.x??0)+(t.layout?.width??0)/2)*10)/10,r=Math.round(((t.absolutePosition?.y??0)+(t.layout?.height??0)/2)*10)/10;return`rnx do tap ${n} ${r}`}function L(t){return/^[A-Za-z0-9_./@:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function ue(t){if(t.bridgeError)return`sim unreachable: ${t.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`rnx list\`, reopen with \`rnx open\`)`;let e=t.externalError?`guest app errored: ${t.externalError}`:t.loadingText?`still showing "${t.loadingText}"`:t.externalReady===!1?"guest app is still loading":t.flag!==!0&&t.targets>0?"native content is rendered but the ready signal has not settled":t.flag!==!0?"guest app has not emitted sootsim:externalAppReady":t.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";return!t.externalError&&t.suppressedEntryError?`${e} (suppressed entry error: ${t.suppressedEntryError})`:e}async function ce(t,e=2e4,n={}){let r=Date.now(),s;try{s=await t.send({type:"waitFor",waitForOptions:{condition:{type:"ready"},timeoutMs:e}},{timeoutMs:e+1e3})}catch(u){let a=u instanceof Error?u.message:String(u);if(a.startsWith("multiple sims are connected:")||a.startsWith("saved sim "))throw u;s={matched:!1,elapsedMs:Date.now()-r,polls:0,error:a}}let o=s.probe,i={ready:s.matched,elapsedMs:s.elapsedMs,nodes:o?.nodes??0,targets:o?.targets??0,liveFrameActive:o?.liveFrameActive??!1,liveFrameChannels:o?.liveFrameChannels??0,liveFramePublishes:o?.liveFramePublishes??0,flag:o?.flag,loadingText:o?.loadingText??"",externalReady:o?.externalReady??null,externalStatus:o?.externalStatus??"",externalError:o?.externalError??"",suppressedEntryError:o?.suppressedEntryError??"",errors:o?.errors??0,bridgeError:s.error??""};return!i.ready&&n.onProgress&&n.onProgress(i),i}async function me(t,e,n=5e3,r={}){let s=r.gone===!0,o=await t.send({type:"waitFor",waitForOptions:{condition:{type:s?"absent":"present",testID:e},timeoutMs:n}},{timeoutMs:n+1e3});if(o?.error)throw new Error(o.error);if(o?.node&&!I([o.node]))throw new Error("waitFor returned an invalid semantic node");return{found:o?.matched===!0,...o?.node?{node:o.node}:{},elapsed:o?.elapsedMs??n}}function D(t,e){return`(() => {
188
+ const out = []
189
+ const seen = new Set()
190
+ const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
191
+ const key = (ts, args) => Math.round((ts || 0) / 250) + '|' + (Array.isArray(args) ? args.map(norm).join(' ') : norm(args))
192
+ const push = (e) => {
193
+ if (!e) return
194
+ const ts = typeof e.timestamp === 'number' ? e.timestamp : (typeof e.ts === 'number' ? e.ts : 0)
195
+ const k = key(ts, e.args)
196
+ if (seen.has(k)) return
197
+ seen.add(k)
198
+ out.push({ timestamp: ts, args: Array.isArray(e.args) ? e.args : [e.args], stack: e.stack || undefined, source: e.source || undefined })
199
+ }
200
+ // page-realm ws-bridge buffer first (richest stacks for page-origin errors)
201
+ try { for (const e of (window.__sootsimConsole?.${t==="error"?"getErrors":"getWarnings"}(${e}) || [])) push(e) } catch {}
202
+ // engine observability store \u2014 the always-on render-worker / forwarded path
203
+ try {
204
+ const obs = window.__sootsimObservability
205
+ const snap = obs && obs.logs && typeof obs.logs.getSnapshot === 'function' ? obs.logs.getSnapshot() : []
206
+ for (const e of snap) if (e && e.level === ${JSON.stringify(t)}) push(e)
207
+ } catch {}
208
+ return out.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)).slice(-${e})
209
+ })()`}async function de(t,e=20){let n=await t.send({type:"evaluate",code:D("error",e)});return Array.isArray(n)?n:[]}async function pe(t,e=20){let n=await t.send({type:"evaluate",code:D("warn",e)});return Array.isArray(n)?n:[]}var ye=`(() => {
210
+ const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
211
+ const key = (lvl, ts, args) => lvl + '|' + Math.round((ts || 0) / 250) + '|' + (Array.isArray(args) ? args.map(norm).join(' ') : norm(args))
212
+ const seen = new Set()
213
+ let errors = 0
214
+ let warnings = 0
215
+ const add = (lvl, ts, args) => {
216
+ if (lvl !== 'error' && lvl !== 'warn') return
217
+ const k = key(lvl, ts, args)
218
+ if (seen.has(k)) return
219
+ seen.add(k)
220
+ if (lvl === 'error') errors++
221
+ else warnings++
222
+ }
223
+ try {
224
+ const c = window.__sootsimConsole
225
+ for (const e of (c?.getErrors?.(200) || [])) add('error', e?.timestamp ?? e?.ts, e?.args)
226
+ for (const e of (c?.getWarnings?.(200) || [])) add('warn', e?.timestamp ?? e?.ts, e?.args)
227
+ } catch {}
228
+ try {
229
+ const obs = window.__sootsimObservability
230
+ const snap = obs && obs.logs && typeof obs.logs.getSnapshot === 'function' ? obs.logs.getSnapshot() : []
231
+ for (const e of snap) if (e) add(e.level, e.ts, e.args)
232
+ } catch {}
233
+ return { errors, warnings, total: errors + warnings }
234
+ })()`;async function ge(t){await t.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); window.__sootsimObservability?.logs?.clear?.(); "cleared"'})}async function be(t,e={}){let n=e.limit??20,r=e.failed===!1?"getRequests":"getFailedRequests",s=await t.send({type:"call",path:`__sootsimTest.${r}`,args:[n]});return Array.isArray(s)?s:[]}async function fe(t){await t.send({type:"call",path:"__sootsimTest.clearRequests",args:[]})}async function he(t){let e=await t.send({type:"evaluate",code:`(() => {
235
+ const obs = window.__sootsimObservability;
236
+ if (!obs) return { ok: false };
237
+ return { ok: true, entries: obs.logs.getSnapshot() };
238
+ })()`});return!e||!e.ok?[]:e.entries??[]}async function xe(t){await t.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'})}function H(t,e){if(t.source===e.source||t.level!==e.level||Math.abs(t.ts-e.ts)>1e3||t.args.length!==e.args.length)return!1;let n=new Set([t.source,e.source]);return!n.has("sootsim-worker")||!n.has("render-worker")&&!n.has("forwarded-render-worker")?!1:t.args.every((r,s)=>r===e.args[s])}function Se(t,e={}){let n=[];for(let r of t)n.some(s=>H(s,r))||n.push(r);if(e.showInternal||(n=n.filter(r=>{let s=r.args[0];return!(typeof s=="string"&&s.startsWith("[rnx]"))})),e.level&&(n=n.filter(r=>e.level.has(r.level))),e.filter){let r=e.filter.toLowerCase();n=n.filter(s=>s.args.join(" ").toLowerCase().includes(r))}return n}async function we(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.summary",args:[e]})}async function j(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.recent",args:[e]})}async function ve(t){let e;try{e=(await j(t,{kinds:["alert","actionsheet"],limit:80})).events}catch{return[]}let n=new Map;for(let o of e)n.set(o.kind,o);let r=[],s=(o,i)=>{let u=n.get(o);if(!u||!u.data||typeof u.data!="object")return;let a=u.data;a.phase==="show"&&r.push({label:i,title:typeof a.title=="string"?a.title:null})};return s("alert","Alert"),s("actionsheet","ActionSheet"),r}async function ke(t,e,n){await t.send({type:"call",path:"SootSim.bridges.timeline.cursorAdvance",args:[e,n]})}async function Ie(t){return await t.send({type:"evaluate",code:`(() => {
239
+ const kb = window.__sootsimKeyboard
240
+ if (!kb || typeof kb.getLayout !== 'function') {
241
+ return { error: 'keyboard bridge getLayout() not available' }
242
+ }
243
+ return kb.getLayout()
244
+ })()`})??{error:"keyboard bridge returned no result"}}function z(t){let e=t instanceof Error?t.message:String(t);return e.includes("call target not found: SootSim.bridges.mainShell")||e.includes("test bridge unavailable before app-in-worker boot")}async function q(t,e=0){let n=Date.now()+Math.max(0,e);for(;;)try{return await t.send({type:"call",path:"SootSim.bridges.mainShell.getState",args:[]})}catch(r){if(!z(r)||Date.now()>=n)throw r;await new Promise(s=>setTimeout(s,50))}}async function Re(t){let e=await t.send({type:"evaluate",code:`(async () => {
245
+ const test = window.__sootsimTest
246
+ const kb = window.__sootsimKeyboard
247
+ const navSnap =
248
+ test && typeof test.getNavigationSnapshot === 'function'
249
+ ? await test.getNavigationSnapshot()
250
+ : null
251
+ const route =
252
+ test && typeof test.getRouteInfo === 'function'
253
+ ? await test.getRouteInfo()
254
+ : null
255
+ const keyboard =
256
+ kb && typeof kb.getLayout === 'function'
257
+ ? (() => {
258
+ const layout = kb.getLayout()
259
+ return layout ? {
260
+ visible: layout.visible,
261
+ mode: layout.mode,
262
+ spec: layout.spec
263
+ ? {
264
+ keyboardType: layout.spec.keyboardType,
265
+ returnKeyType: layout.spec.returnKeyType,
266
+ }
267
+ : null,
268
+ } : null
269
+ })()
270
+ : null
271
+ return { nav: navSnap, route, keyboard }
272
+ })()`});return{shell:await q(t,500).catch(()=>null),nav:e?.nav??null,route:e?.route??null,keyboard:e?.keyboard??null}}async function $e(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.status()"})}async function Ee(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.flags()"})}async function Me(t,e){return t.send({type:"evaluate",code:`window.__sootsimTest.debugFind(${JSON.stringify(e)})`})}async function Ne(t,e,n=50){let r=e&&e!=="all"?`window.__sootsimDebug.recent(${JSON.stringify(e)}, ${n})`:`window.__sootsimDebug.recent(undefined, ${n})`;return t.send({type:"evaluate",code:r})}async function Te(t,e,n){let r=n.length>0?n.map(s=>JSON.stringify(s)).join(", "):e==="disable"?"'all'":"";return t.send({type:"evaluate",code:`window.__sootsimDebug.${e}(${r})`})}async function Le(t){return await t.send({type:"evaluate",code:`(async () => {
273
+ const host = window.__sootsimRenderHost
274
+ const stats = host?.queryStats ? await host.queryStats() : null
275
+ const shellRaw = window.__sootsimShellMemory
276
+ ? await window.__sootsimShellMemory()
277
+ : null
278
+ const shell = shellRaw && !shellRaw.error ? shellRaw : null
279
+ // the compositor paints home + app:one + app:two, so every app-surface
280
+ // picture and raster image is counted here and nowhere else.
281
+ let compositor = null
282
+ try {
283
+ const cs = await window.__sootsimCompositor?.getStats?.(false, true)
284
+ compositor = cs?.memory ?? null
285
+ } catch {}
286
+ const normalize = (m) =>
287
+ m
288
+ ? {
289
+ nodesRegistered: m.nodesRegistered ?? null,
290
+ nodesDetached: m.nodesDetached ?? null,
291
+ detachedTypes: m.detachedTypes ?? null,
292
+ objects: m.objects ?? null,
293
+ activeNativeAnimations: m.activeNativeAnimations ?? null,
294
+ imageLoader: m.imageLoader ?? null,
295
+ workerHeap: m.workerHeap ?? null,
296
+ wasmHeapBytes: m.wasmHeapBytes ?? null,
297
+ }
298
+ : null
299
+ const hostMem = performance.memory
300
+ ? {
301
+ usedJSHeapSize: performance.memory.usedJSHeapSize,
302
+ totalJSHeapSize: performance.memory.totalJSHeapSize,
303
+ jsHeapSizeLimit: performance.memory.jsHeapSizeLimit,
304
+ }
305
+ : null
306
+ return {
307
+ tenant: normalize(stats?.memory),
308
+ shell: normalize(shell),
309
+ compositor: normalize(compositor),
310
+ hostHeap: hostMem,
311
+ }
312
+ })()`})??{tenant:null,shell:null,compositor:null,hostHeap:null}}function Oe(t){if(t.total===0)return"nothing recorded";let e=[],n=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],r=new Set;for(let s of n){let o=t.byKind[s];o&&(e.push(`${o} ${s}${o===1?"":"s"}`),r.add(s))}for(let[s,o]of Object.entries(t.byKind))!r.has(s)&&o&&e.push(`${o} ${s}${o===1?"":"s"}`);return e.join(" \xB7 ")}var De=new Set(["react-commit","layout","scroll"]);function K(t,e){if(e===null)return new Date(t).toLocaleTimeString();let n=(t-e)/1e3;return`${n>=0?"+":""}${n.toFixed(2)}s`}function Y(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"flow-step":return`${e.status??"?"} ${e.stepName??"step"}${e.durationMs?` ${e.durationMs}ms`:""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":case"console-log":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"layout":return`${e.kind??"?"} ${e.testID??e.type??""}${e.skipped?` skipped:${e.reason??"unknown"}`:""}`;case"react-commit":{let n=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${n?.displayName?` \xB7 ${n.displayName} ${n.durationMs??"?"}ms`:""}`}case"frame":return`${e.totalMs??"?"}ms${e.renderMs?` \xB7 render ${e.renderMs}ms`:""}${e.layoutMs?` \xB7 layout ${e.layoutMs}ms`:""}${e.copyMs?` \xB7 copy ${e.copyMs}ms`:""}`;case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}return""}function Pe(t,e){let n=K(t.t,e).padStart(8),r=t.context.padEnd(6),s=`[${t.kind}]`.padEnd(15),o=t.data,i=o&&typeof o=="object"?Y(t.kind,o):"";return` ${n} ${r} ${s} ${i}`}export{X as a,G as b,V as c,Z as d,ee as e,I as f,F as g,te as h,ne as i,oe as j,se as k,ie as l,ae as m,le as n,ue as o,ce as p,me as q,de as r,pe as s,ye as t,ge as u,be as v,fe as w,he as x,xe as y,Se as z,we as A,j as B,ve as C,ke as D,Ie as E,z as F,q as G,Re as H,$e as I,Ee as J,Me as K,Ne as L,Te as M,Le as N,Oe as O,De as P,Pe as Q};
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
4
  function a(){console.error(" no rnx desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" rnx desktop install"),console.error(""),console.error(" or install the recommended background service:"),console.error(" rnx daemon install"),console.error("")}function t(r){console.error(""),console.error(` no sim is connected to the rnx bridge on port ${r}.`),console.error(""),console.error(" start your app dev server, then open it in rnx:"),console.error(" npx expo start --localhost --port 8081"),console.error(" rnx open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" rnx describe")}async function d(r,n,s){let e=[];try{e=await r.listSims()}catch{}if(console.error(""),e.length===0){t(n);return}console.error(` no sim with id "${s}" is connected to the bridge on port ${n}.`),console.error(""),console.error(" connected sims:");for(let o of e){let i=[o.isPrimary?"primary":null,o.readyState,o.userVisible===!1?"hidden":o.userVisible===!0?"visible":null,o.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${o.id} (${i})`)}console.error(""),console.error(" pass a valid --sim id, or run `rnx list` to see all sessions.")}export{a,t as b,d as c};
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
4
  function t(_){return`(async () => {
@@ -0,0 +1,4 @@
1
+ /*! rnx v0.1.367 | (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 F,b as h,e as f,f as W,g as B}from"./chunk-4XSNO374.js";import{b as l}from"./chunk-K3EC6JDE.js";import{b as P}from"./chunk-SH5ETJKG.js";import{E as y,G as D,d as T,e as u,h as v,k as I,l as R,o as O,p as $,r as M,s as A,x as N,z as _}from"./chunk-GMLOCV3E.js";var o=class extends Error{constructor(e){super(e),this.name=new.target.name}},m=class extends o{},w=class extends o{status;constructor(e){super(`sim not ready: ${O(e)}`),this.status=e}},d=class extends o{outcome;constructor(e,t=null){super(e),this.outcome=t}},b=class extends o{},g=class extends o{result;constructor(e){let t=e.steps.find(n=>!n.ok),s=t?`${t.index} (${t.type})`:String(e.completed),r=t?.error??e.error;super(`perform failed at step ${s}${r?`: ${r}`:""}`),this.result=e}},x=class extends o{result;constructor(e){super(`reset (${e.strategy}) failed${e.error?`: ${e.error}`:""}`),this.result=e}};function U(i){return new Promise(e=>setTimeout(e,i))}function C(i){if(typeof i!="string"||!i.startsWith("data:image/png;base64,"))throw new o(`screenshot bridge returned a non-png payload: ${JSON.stringify(typeof i=="string"?i.slice(0,80):i)}`);let e=i.slice(22),t=atob(e),s=new Uint8Array(t.length);for(let r=0;r<t.length;r++)s[r]=t.charCodeAt(r);return{dataUrl:i,bytes:s}}var J=["bundle","demo","app","open","port","inspectOpen","appFonts","appSplash"];function K(i,e){let t=new URL(i);for(let a of J)t.searchParams.delete(a);let s=t.pathname.replace(/\/+$/,"")||"/",r=s==="/__soot"||s.startsWith("/__soot/")?"/__soot":"",n=String(e).trim();return/^\d+$/.test(n)?t.pathname=`${r}/rn/${n}`:(t.pathname=`${r}/rn`,t.searchParams.set("open",n)),t.toString()}function j(i){return typeof i=="object"&&"text"in i&&typeof i.text=="string"&&!("layout"in i)&&!("absolutePosition"in i)}var k=class{simId;bridge;closed=!1;constructor(e,t,s={}){this.bridge=e,this.simId=t}send(e,t){if(this.closed)return Promise.reject(new m("sim client is closed"));let s=e.simId===void 0?{...e,simId:this.simId}:e;return this.bridge.send(s,t)}listSims(){return this.bridge.listSims()}focusSim(e=this.simId){return this.bridge.focusSim(e)}closeSim(e=this.simId){return this.bridge.closeSim(e)}claim(e=this.simId,t){return this.bridge.claim(e,t)}close(){this.closed||(this.closed=!0,this.bridge.close())}async open(e,t={}){let r=(await this.listSims()).find(c=>c.id===this.simId);if(!r)throw new m(`sim ${this.simId} is no longer connected`);let n=r.url??r.origin;if(!n)throw new m(`sim ${this.simId} reported no URL to derive the shell from`);let a=K(n,e),p=new URL(a);await this.send({type:"evaluate",code:`window.location.href = ${JSON.stringify(a)}`});let L=Date.now()+(t.timeoutMs??3e4);for(;Date.now()<L;){await U(250);try{let{url:c}=await u(this),S=new URL(c);if(S.pathname===p.pathname&&S.searchParams.get("open")===p.searchParams.get("open"))return}catch{}}throw new m(`timed out waiting for sim ${this.simId} to load ${a}`)}openUrl(e){return P(this,e)}async waitReady(e={}){let t=await $(this,e.timeoutMs??2e4,{onProgress:e.onProgress});if(!t.ready)throw new w(t);return t}settle(e={}){return F({bridge:this,maxMs:e.maxMs??3e3,strict:e.strict})}async find(e){return(await this.findAll(e))[0]??null}async findAll(e){let t={testId:e.testId??null,role:e.role??null,type:e.type??null,text:e.text??null,pressable:e.pressable},s=await R(this,t);if(!s)throw new o("find() needs at least one of testId, text, role, type, or pressable");let{result:r}=s;return Array.isArray(r)?r:r?[r]:[]}async tree(e=5){let{tree:t}=await T(this,e);return Array.isArray(t)?t:[]}resolve(e){return this.send({type:"resolve",selector:e})}describe(e={}){return v(this,{describe:!0,verbose:e.verbose??!1,filter:e.filter??"",compact:!e.verbose,hideXy:!1,fullText:!0})}accessibilityTree(){return I(this)}async logs(e={}){return _(await N(this),e)}errors(e=20){return M(this,e)}warnings(e=20){return A(this,e)}keyboard(){return y(this)}shellState(e=0){return D(this,e)}async url(){let{url:e}=await u(this);return e}async screenshot(e={}){let t=await this.send({type:"screenshot",...e.layers?{layers:e.layers}:{},...e.crop?{crop:e.crop}:{}});return C(t)}async tap(e){if(typeof e=="string")return this.throwUnlessTapped(await B(this,e),e);if("testId"in e&&typeof e.testId=="string")return this.throwUnlessTapped(await f(this,e.testId),e.testId);if(j(e)){let{text:r,...n}=e;return this.throwUnlessTapped(await W(this,r,n),r)}if("testID"in e&&typeof e.testID=="string")return this.throwUnlessTapped(await f(this,e.testID),e.testID);let t=this.coordsForTapTarget(e),s=await this.send({type:"tap",x:t.x,y:t.y});if(!h(s))throw new d(`tap at ${t.x},${t.y} missed: ${JSON.stringify(s)}`)}async longPress(e,t={}){let s=await this.resolveCoords(e);if(!(await this.send({type:"longPress",x:s.x,y:s.y,durationMs:t.durationMs??600},{timeoutMs:(t.durationMs??600)+15e3}))?.ok)throw new d(`longPress at ${s.x},${s.y} missed`)}async type(e){await this.requireVisibleKeyboard("type"),await this.send({type:"keyboard",action:"type",text:e})}async press(e){await this.requireVisibleKeyboard("press"),await this.send({type:"keyboard",action:"press",text:e})}async dismissKeyboard(){await this.send({type:"keyboard",action:"dismiss"})}async perform(e,t){let s=[];for(let a of e){if(a.type!=="tapText"){s.push(a);continue}let p=await l(this,{mode:"text",value:a.text});if(!p)throw new d(`perform tapText: no node with text ${JSON.stringify(a.text)}`);s.push({type:"tap",x:p.x,y:p.y,target:{testID:p.testID??void 0,text:p.text??void 0,type:p.type??void 0}})}let r=t?.timeoutMs??3e4,n=await this.send({type:"perform",steps:s,...t?{performOptions:t}:{}},{timeoutMs:r+5e3});if(!n?.ok)throw new g(n);return n}state(e){return this.send({type:"state",...e?{stateOptions:e}:{}})}async reset(e){let t=await this.send({type:"reset",...e?{resetOptions:e}:{}},{timeoutMs:6e4});if(!t?.ok)throw new x(t);return t}throwUnlessTapped(e,t){if(!e.failure&&h(e.result))return;let s=e.failure==="not-found"?"no matching node":e.failure==="missed"?e.result?.reason??"press missed":e.payload?.ambiguous?`ambiguous: ${e.payload.total} matches`:e.result?.reason??e.payload?.error??"tap failed";throw new d(`tap ${JSON.stringify(t)} failed: ${s}`,e)}coordsForTapTarget(e){if(typeof e=="object"&&"x"in e&&"y"in e&&typeof e.x=="number"&&typeof e.y=="number")return{x:e.x,y:e.y};if(typeof e=="object"&&"absolutePosition"in e&&e.absolutePosition&&e.layout)return{x:e.absolutePosition.x+(e.layout.width??0)/2,y:e.absolutePosition.y+(e.layout.height??0)/2};throw new o("tap target needs coordinates, a testId, text, or a node from find()")}async resolveCoords(e){if(typeof e=="string"){let t=await l(this,{mode:"testid",value:e})??await l(this,{mode:"text",value:e});if(!t)throw new d(`no node matching ${JSON.stringify(e)}`);return t}if("testId"in e&&typeof e.testId=="string"){let t=await l(this,{mode:"testid",value:e.testId});if(!t)throw new d(`no node with testID ${JSON.stringify(e.testId)}`);return t}if("text"in e&&typeof e.text=="string"&&!("layout"in e)){let t=await l(this,{mode:"text",value:e.text});if(!t)throw new d(`no node with text ${JSON.stringify(e.text)}`);return t}return this.coordsForTapTarget(e)}async requireVisibleKeyboard(e){let t=Date.now()+1500;for(;;){let s=await y(this);if(!("error"in s)&&s.visible)return;if(Date.now()>=t)throw new b(`${e} requires the iOS keyboard to be visible \u2014 focus an input first (tap a TextInput)`);await U(150)}}};export{o as a,m as b,w as c,d,b as e,g as f,x as g,K as h,k as i};
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
4
  var c="sootsim-agent-prompt-v1";function r(n){return typeof n=="string"?n.trim():""}function m(n){let e=r(n.text);if(!e)return"";let t=r(n.displayText),s=r(n.inspectSummary),o=r(n.inspectTrace);return!!s||!!o||/[\r\n]/.test(e)||!!t&&t!==e?JSON.stringify({__sootsimAgentPrompt:c,text:e,displayText:t,inspectSummary:s,inspectTrace:o}):e}function u(n){let e=r(n);if(!e)return null;try{let t=JSON.parse(e);if(t.__sootsimAgentPrompt!==c)return{text:e};let s=r(typeof t.text=="string"?t.text:void 0);if(!s)return null;let o=r(typeof t.displayText=="string"?t.displayText:void 0),i=r(typeof t.inspectSummary=="string"?t.inspectSummary:void 0),p=r(typeof t.inspectTrace=="string"?t.inspectTrace:void 0);return{text:s,...o?{displayText:o}:{},...i?{inspectSummary:i}:{},...p?{inspectTrace:p}:{}}}catch{return{text:e}}}export{m as a,u as b};
@@ -0,0 +1,24 @@
1
+ /*! rnx v0.1.367 | (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 v}from"./chunk-AVOROGA3.js";import{a as P,b as y,c as $,d as k,e as x,h as E,i as O}from"./chunk-AM2ODYAN.js";import{spawn as M,spawnSync as p}from"child_process";import{chmodSync as I,copyFileSync as L,createWriteStream as C,existsSync as g,mkdirSync as D,rmSync as u,statSync as R,unlinkSync as B}from"fs";import{tmpdir as F}from"os";import{dirname as N,join as f,resolve as A}from"path";var b="https://contrast.dev/api/electron-release";function W(){let n=process.arch;if(process.platform==="darwin"){let t=n==="arm64"?"mac-arm64":"mac-x64",r=`sootsim-latest-${t}.dmg`;return{platform:t,filename:r,url:`${b}/${r}`,install:q}}if(process.platform==="linux"){let t=n==="arm64"?"linux-arm64":"linux-x64",r=`sootsim-latest-${t}.AppImage`;return{platform:t,filename:r,url:`${b}/${r}`,install:z}}if(process.platform==="win32"){let t="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:t,url:`${b}/${t}`,install:H}}return null}async function Y({url:n,dest:t,onProgress:r}){let s=await fetch(n,{redirect:"follow"});if(!s.ok)throw new Error(`${s.status} ${s.statusText} (${n})`);let o=s.headers.get("content-length"),a=o?Number(o):null;if(!s.body)throw new Error(`empty response body (${n})`);D(N(t),{recursive:!0});let l=C(t),d=s.body.getReader(),c=0;try{for(;;){let{done:e,value:i}=await d.read();if(e)break;l.write(Buffer.from(i)),c+=i.byteLength,r?.(c,a)}}finally{await new Promise((e,i)=>{l.end(m=>m?i(m):e())})}}function _(n,t){let r=(n/1048576).toFixed(1);if(!t)return` ${r} MB`;let s=Math.min(100,Math.round(n/t*100)),o=(t/(1024*1024)).toFixed(1),a=24,l=Math.round(s/100*a);return` ${P("\u2588".repeat(l))+$("\u2591".repeat(a-l))} ${s}% ${r} / ${o} MB`}async function q(n){let t=p("hdiutil",["attach","-nobrowse","-readonly",n],{encoding:"utf8"});if(t.status!==0)throw new Error(`hdiutil attach failed: ${t.stderr||t.stdout}`.trim());let r=t.stdout.trim().split(`
5
+ `),o=r[r.length-1].split(" ").pop()?.trim();if(!o||!g(o))throw new Error(`could not determine dmg mount point (output: ${t.stdout})`);let a=f(o,"rnx.app");if(!g(a))throw p("hdiutil",["detach","-force",o]),new Error(`rnx.app not found inside ${o}`);let l="/Applications",d=A(process.env.HOME||"","Applications"),c=l;try{let w=f(l,`.sootsim-write-probe-${process.pid}`);p("touch",[w]),g(w)?u(w,{force:!0}):c=d}catch{c=d}c===d&&D(c,{recursive:!0});let e=f(c,"rnx.app"),i=f(c,`.rnx-incoming-${process.pid}.app`);u(i,{recursive:!0,force:!0});let m=p("cp",["-R",a,i]);if(m.status!==0)throw p("hdiutil",["detach","-force",o]),u(i,{recursive:!0,force:!0}),new Error(`copy to ${c} failed: ${m.stderr?.toString()||""}`.trim());let S=p("hdiutil",["detach","-force",o]),h=f(c,`.rnx-previous-${process.pid}.app`);if(g(e)){let w=p("mv",[e,h]);if(w.status!==0)throw u(i,{recursive:!0,force:!0}),new Error(`could not replace ${e}: ${w.stderr?.toString()||""}`.trim())}let T=p("mv",[i,e]);if(T.status!==0)throw g(h)&&p("mv",[h,e]),u(i,{recursive:!0,force:!0}),new Error(`could not move into ${e}: ${T.stderr?.toString()||""}`.trim());return u(h,{recursive:!0,force:!0}),S.status!==0&&console.warn(` warning: failed to unmount ${o} (${S.stderr?.toString().trim()||"unknown error"})`),p("xattr",["-dr","com.apple.quarantine",e]),e}async function z(n){let t=A(process.env.HOME||"","Applications");D(t,{recursive:!0});let r=f(t,"rnx.AppImage");return g(r)&&u(r,{force:!0}),L(n,r),B(n),I(r,493),r}async function H(n){await new Promise((r,s)=>{let o=M("cmd",["/c","start",'""',"/wait",n],{stdio:"inherit"});o.once("error",s),o.once("exit",a=>{a===0?r():s(new Error(`installer exited with code ${a}`))})});let t=v();if(!t)throw new Error("the installer finished but the rnx application was not registered");return t.path}async function X(n){(n.includes("--help")||n.includes("-h"))&&(console.log(`
6
+ rnx desktop install
7
+
8
+ Download and install the optional rnx Desktop app.
9
+ The CLI works without it. Choose Desktop when you want a dedicated native window.
10
+
11
+ usage:
12
+ rnx desktop install [options]
13
+
14
+ options:
15
+ -y, --yes skip confirmation and install immediately
16
+ --force reinstall even if the companion is already present
17
+
18
+ examples:
19
+ rnx desktop install
20
+ rnx desktop install --yes
21
+ `),process.exit(0));let t=n.includes("--yes")||n.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,r=n.includes("--force"),s=v();if(s&&!r){console.log(` ${k("\u2713")} Desktop app is already installed at ${s.path}`),console.log(` ${$("Pass --force to reinstall.")}`);return}let o=W();if(o||(console.error(` ${x("\xD7")} No desktop build is available for ${process.platform}/${process.arch}.`),console.error(" Supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64"),process.exit(1)),console.log(` ${y("Desktop app")}`),console.log(` Platform ${o.platform}`),console.log(` Download ${o.url}`),console.log(),!t){if(!await O("Download and install now?",!0)){console.log(` ${$("Cancelled.")}`);return}console.log()}let a=f(F(),`sootsim-install-${Date.now()}`),l=f(a,o.filename),d=0;process.stdout.write(` Downloading ${o.filename}...
22
+ `);try{await Y({url:o.url,dest:l,onProgress:(e,i)=>{let m=Date.now();m-d<100&&e<(i??1/0)||(d=m,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${_(e,i)}`))}})}catch(e){u(a,{recursive:!0,force:!0});let i=e instanceof Error?e.message:String(e);console.error(`
23
+ ${x("\xD7")} Download failed: ${i}`),console.error(` The ${o.platform} desktop build may not be published yet, or your`),console.error(" network blocked the request. Check your connection and try again later."),console.error(" The CLI and daemon work without the desktop app. Run `rnx --help`."),process.exit(1)}process.stdout.isTTY&&process.stdout.write(`
24
+ `);let c=R(l).size;console.log(` ${k("\u2713")} Downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log();try{let e=await E("Installing the desktop app",()=>o.install(l));console.log(` Installed at ${e}`),u(a,{recursive:!0,force:!0})}catch(e){console.error(` ${x("\xD7")} Install failed: ${e instanceof Error?e.message:String(e)}`),process.platform==="darwin"?(p("open",[l]),console.error(` Opened ${o.filename} \u2014 drag rnx to Applications to finish.`)):console.error(` Keeping the download at ${l} for manual installation.`),process.exit(1)}console.log(),console.log(` ${y("Ready")}`),console.log(" rnx desktop Launch the desktop app"),console.log(" rnx open <target> Open a demo or bundle in it")}export{X as a};
@@ -0,0 +1,5 @@
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ function i(t,o,a,c){return{width:3,ringToggle:{side:"left",top:t[0],height:t[1]},volumeUp:{side:"left",top:o[0],height:o[1]},volumeDown:{side:"left",top:a[0],height:a[1]},lock:{side:"right",top:c[0],height:c[1]}}}var N={width:2.5,lock:{side:"right",top:188.7,height:68.1},ringToggle:{side:"left",top:113.2,height:36},volumeUp:{side:"left",top:188.2,height:68.1},volumeDown:{side:"left",top:269,height:68.1}},S={width:3,lock:{side:"right",top:671/2.625,height:163/2.625},ringToggle:{side:"left",top:-1e3,height:0},volumeUp:{side:"right",top:971/2.625,height:165/2.625},volumeDown:{side:"right",top:1136/2.625,height:166/2.625}},O={width:3,lock:{side:"right",top:248,height:72},ringToggle:{side:"left",top:-1e3,height:0},volumeUp:{side:"right",top:144,height:62},volumeDown:{side:"right",top:216,height:62}},s=24,d="17",u=37,R=1080/2.625,D=2400/2.625,p=132/2.625;function r(t){return{top:t,right:t,bottom:t,left:t}}function _(t){let o=(t.frameInsets.top+t.frameInsets.right+t.frameInsets.bottom+t.frameInsets.left)/4,a=Math.max(Math.abs(t.frameInsets.top-o),Math.abs(t.frameInsets.right-o),Math.abs(t.frameInsets.bottom-o),Math.abs(t.frameInsets.left-o));return{frameRadius:t.cornerRadius+o,frameRadiusApproximationError:a,screenRadius:t.cornerRadius}}function H(t){return{..._(t),frameHeight:t.frameInsets.top+t.height+t.frameInsets.bottom,frameWidth:t.frameInsets.left+t.width+t.frameInsets.right,screenBottomInset:t.frameInsets.bottom,screenLeft:t.frameInsets.left,screenRightInset:t.frameInsets.right,screenTop:t.frameInsets.top}}function n(t){return{...t,platform:"ios",navigationBarHeight:0,navigationBarMode:t.homeIndicatorHeight>0?"gesture":"none",displayCutout:{top:t.dynamicIsland?t.statusBarHeight:0,bottom:0,left:0,right:0},cameraCutout:null,osVersion:t.iosVersion,androidApiLevel:null,systemName:"iOS",manufacturer:"Apple",brand:"Apple",modelName:t.name}}var v={"canvas-workspace":n({name:"Canvas Workspace",width:1440,height:900,scale:1,statusBarHeight:0,homeIndicatorHeight:0,cornerRadius:0,continuousCornerRadius:0,frameInsets:r(16),dynamicIsland:null,safeAreaInsets:{top:0,bottom:0,left:0,right:0},iosVersion:"26.4",physicalPPI:110,hardwareButtons:i([185.8,41.7],[258.2,67.6],[344,67.6],[281.5,106.9]),experimental:!0}),"iphone-se":n({name:"iPhone SE",width:375,height:667,scale:2,statusBarHeight:20,homeIndicatorHeight:0,cornerRadius:0,continuousCornerRadius:0,frameInsets:r(28.7),dynamicIsland:null,safeAreaInsets:{top:20,bottom:0,left:0,right:0},iosVersion:"15.8",physicalPPI:326,hardwareButtons:N}),"iphone-14":n({name:"iPhone 14",width:390,height:844,scale:3,statusBarHeight:47,homeIndicatorHeight:34,cornerRadius:46.2,continuousCornerRadius:67.462,frameInsets:r(19.5),dynamicIsland:null,safeAreaInsets:{top:47,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:i([141.7,29.7],[205.9,69.6],[289.5,69.6],[228.9,114.5])}),"iphone-15":n({name:"iPhone 15",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:73.402,frameInsets:r(18.2),dynamicIsland:{width:126,height:37.3,top:14.1},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:i([171.7,32],[235.8,65.3],[320.5,65.3],[280.6,105.2])}),"iphone-15-plus":n({name:"iPhone 15 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:74.654,frameInsets:r(17.3),dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"17.6",physicalPPI:460,hardwareButtons:i([172.1,33],[236.1,66.6],[321.2,66.6],[281,106.8])}),"iphone-15-pro":n({name:"iPhone 15 Pro",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:73.402,frameInsets:r(15.3),dynamicIsland:{width:126,height:38,top:13.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:i([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-15-pro-max":n({name:"iPhone 15 Pro Max",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:74.654,frameInsets:r(15.3),dynamicIsland:{width:126,height:38,top:13.3},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"18.2",physicalPPI:460,hardwareButtons:i([173.3,32.2],[253.4,61.7],[343.3,61.7],[268.5,98.5])}),"iphone-16":n({name:"iPhone 16",width:393,height:852,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:73.402,frameInsets:r(15.3),dynamicIsland:{width:126,height:37.3,top:11},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-16-plus":n({name:"iPhone 16 Plus",width:430,height:932,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:53.9,continuousCornerRadius:74.654,frameInsets:r(15.3),dynamicIsland:{width:126,height:37.3,top:11.4},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([173.3,32.2],[253.4,61.7],[343.3,61.7],[268.5,98.5])}),"iphone-16-pro":n({name:"iPhone 16 Pro",width:402,height:874,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61,continuousCornerRadius:84.661,frameInsets:r(15.3),dynamicIsland:{width:126,height:38,top:13.5},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-16-pro-max":n({name:"iPhone 16 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61.3,continuousCornerRadius:85.163,frameInsets:r(15.4),dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"iphone-17":n({name:"iPhone 17",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:61,continuousCornerRadius:84.661,frameInsets:r(15.3),dynamicIsland:{width:126,height:37.3,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-17-air":n({name:"iPhone Air",width:420,height:912,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:64.6,continuousCornerRadius:88.313,frameInsets:r(10.7),dynamicIsland:{width:126,height:38,top:20},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"iphone-17-pro":n({name:"iPhone 17 Pro",width:402,height:874,scale:3,statusBarHeight:59,homeIndicatorHeight:34,cornerRadius:61,continuousCornerRadius:84.661,frameInsets:r(15.3),dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:59,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([159.1,31.5],[220.1,61.9],[299,61.9],[260.8,98.9])}),"iphone-17-pro-max":n({name:"iPhone 17 Pro Max",width:440,height:956,scale:3,statusBarHeight:62,homeIndicatorHeight:34,cornerRadius:61.3,continuousCornerRadius:85.163,frameInsets:r(15.4),dynamicIsland:{width:126,height:38,top:14},safeAreaInsets:{top:62,bottom:34,left:0,right:0},iosVersion:"26.4",physicalPPI:460,hardwareButtons:i([178.8,32.2],[266.8,61.8],[352.7,61.8],[292.2,98.3])}),"pixel-8":{platform:"android",name:"Pixel 8",width:R,height:D,scale:2.625,statusBarHeight:p,homeIndicatorHeight:0,navigationBarHeight:s,navigationBarMode:"gesture",displayCutout:{top:p,bottom:0,left:0,right:0},cornerRadius:39,continuousCornerRadius:39,frameInsets:{top:55/2.625,right:50/2.625,bottom:58/2.625,left:49/2.625},dynamicIsland:null,cameraCutout:{diameter:72.5/2.625},safeAreaInsets:{top:p,bottom:s,left:0,right:0},osVersion:d,iosVersion:"",androidApiLevel:u,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:S},"pixel-8-three-button":{platform:"android",name:"Pixel 8 (3-button)",width:R,height:D,scale:2.625,statusBarHeight:p,homeIndicatorHeight:0,navigationBarHeight:48,navigationBarMode:"three-button",displayCutout:{top:p,bottom:0,left:0,right:0},cornerRadius:39,continuousCornerRadius:39,frameInsets:{top:55/2.625,right:50/2.625,bottom:58/2.625,left:49/2.625},dynamicIsland:null,cameraCutout:{diameter:72.5/2.625},safeAreaInsets:{top:p,bottom:48,left:0,right:0},osVersion:d,iosVersion:"",androidApiLevel:u,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 8",physicalPPI:428,hardwareButtons:S},"pixel-9-pro-xl":{platform:"android",name:"Pixel 9 Pro XL",width:448,height:997,scale:3,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:s,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:41,continuousCornerRadius:41,frameInsets:r(12),dynamicIsland:null,cameraCutout:{diameter:24},safeAreaInsets:{top:40,bottom:s,left:0,right:0},osVersion:d,iosVersion:"",androidApiLevel:u,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 9 Pro XL",physicalPPI:486,hardwareButtons:S},"pixel-10":{platform:"android",name:"Pixel 10",width:360,height:808,scale:3,statusBarHeight:40,homeIndicatorHeight:0,navigationBarHeight:s,navigationBarMode:"gesture",displayCutout:{top:40,bottom:0,left:0,right:0},cornerRadius:40,continuousCornerRadius:40,frameInsets:r(18),dynamicIsland:null,cameraCutout:{diameter:26},safeAreaInsets:{top:40,bottom:s,left:0,right:0},osVersion:d,iosVersion:"",androidApiLevel:u,systemName:"Android",manufacturer:"Google",brand:"google",modelName:"Pixel 10",physicalPPI:422,hardwareButtons:S},"galaxy-s24":{platform:"android",name:"Galaxy S24",width:360,height:780,scale:3,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:s,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:36,continuousCornerRadius:36,frameInsets:r(8),dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:s,left:0,right:0},osVersion:d,iosVersion:"",androidApiLevel:u,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S921B",physicalPPI:416,hardwareButtons:O},"galaxy-s24-ultra":{platform:"android",name:"Galaxy S24 Ultra",width:384,height:832,scale:3.75,statusBarHeight:36,homeIndicatorHeight:0,navigationBarHeight:s,navigationBarMode:"gesture",displayCutout:{top:36,bottom:0,left:0,right:0},cornerRadius:24,continuousCornerRadius:24,frameInsets:r(9),dynamicIsland:null,cameraCutout:{diameter:18},safeAreaInsets:{top:36,bottom:s,left:0,right:0},osVersion:d,iosVersion:"",androidApiLevel:u,systemName:"Android",manufacturer:"Samsung",brand:"samsung",modelName:"SM-S928B",physicalPPI:505,hardwareButtons:O}},P="iphone-17-pro",j={ios:P,android:"pixel-10"};function L(t){return v[t]}function A(){return Object.keys(v)}function W(){return A().filter(t=>!v[t].experimental)}function K(t){return L(t).platform}var F="rnx",$=Object.freeze({name:F,packageName:"rnxsim",commandName:"rnx",domain:"rnxsim.com",origin:"https://rnxsim.com"});var k=["off","soft","full"];function B(t){return t==="off"||t==="soft"||t==="full"}var w={"iphone-6-9":{name:"iphone-6-9",label:'iPhone 6.7"',width:1284,height:2778,store:"apple"},"iphone-6-1":{name:"iphone-6-1",label:'iPhone 6.5"',width:1242,height:2688,store:"apple"},"android-phone":{name:"android-phone",label:"Google Play phone",width:1080,height:1920,store:"google"},"android-tablet-7":{name:"android-tablet-7",label:'Google Play 7" tablet',width:1200,height:1920,store:"google"},"android-tablet-10":{name:"android-tablet-10",label:'Google Play 10" tablet',width:1600,height:2560,store:"google"}},I={dark:{type:"gradient",direction:180,glow:"#4caeff",stops:[{offset:0,color:"#111827"},{offset:40,color:"#101725"},{offset:100,color:"#06080d"}]},cyan:{type:"gradient",direction:180,glow:"#25c3ec",stops:[{offset:0,color:"#1b465c"},{offset:32,color:"#122336"},{offset:100,color:"#05070b"}]},gold:{type:"gradient",direction:180,glow:"#ffc25a",stops:[{offset:0,color:"#3b2f1a"},{offset:34,color:"#18140d"},{offset:100,color:"#050505"}]},red:{type:"gradient",direction:180,glow:"#ff6178",stops:[{offset:0,color:"#3e1018"},{offset:35,color:"#17080c"},{offset:100,color:"#050405"}]}},Z={color:"#25c3ec",blur:120,spread:52,opacity:.34},Q="iphone-17-pro";var V=[{name:"white",value:"#ffffff"},{name:"gray-light",value:"#d1d5db"},{name:"gray",value:"#6b7280"},{name:"gray-dark",value:"#3b4350"},{name:"slate",value:"#2a3644"},{name:"black",value:"#000000"},{name:"cyan",value:"#25c3ec"},{name:"blue",value:"#3f7cff"},{name:"teal",value:"#1fc7b4"},{name:"green",value:"#42c95d"},{name:"lime",value:"#92d21b"},{name:"gold",value:"#f5c518"},{name:"orange",value:"#ff912e"},{name:"coral",value:"#ff6f5b"},{name:"red",value:"#ff4f6f"},{name:"berry",value:"#d054ff"},{name:"magenta",value:"#ff4eb8"}],M=Object.fromEntries(V.map(t=>[t.name,t.value]));function J(t){return M[t]??M.gray}function ee(t){return Object.prototype.hasOwnProperty.call(w,t)?w[t]:null}function z(t){return{type:t.type,color:t.color,direction:t.direction,glow:t.glow,stops:t.stops?.map(o=>({...o}))}}function te(t){return Object.prototype.hasOwnProperty.call(I,t)?z(I[t]):null}var G=[.823,.882,.941,1,1.118,1.235,1.353,1.786,2.143,2.643,3.143,3.571];function e(t,o){return Object.freeze({fontSize:t,lineHeight:o})}var re=Object.freeze({xs:Object.freeze({largeTitle:e(31,44.408775),title1:e(25,37.128102),title2:e(19,27.816685),title3:e(17,23.807109),headline:e(14,20.161577),body:e(14,20.161577),callout:e(13,18.942243),subheadline:e(12,16.720313),footnote:e(12,16.986979),caption1:e(11,15.564453),caption2:e(11,16.126953)}),s:Object.freeze({largeTitle:e(32,45.797256),title1:e(26,38.556756),title2:e(20,29.22433),title3:e(18,25.160469),headline:e(15,21.536754),body:e(15,21.536754),callout:e(14,20.326079),subheadline:e(13,18.213672),footnote:e(12,16.986979),caption1:e(11,15.564453),caption2:e(11,16.126953)}),m:Object.freeze({largeTitle:e(33,47.185737),title1:e(27,39.985409),title2:e(21,30.631975),title3:e(19,26.513828),headline:e(16,22.911932),body:e(16,22.911932),callout:e(15,21.709914),subheadline:e(14,19.557031),footnote:e(12,16.986979),caption1:e(11,15.564453),caption2:e(11,16.126953)}),l:Object.freeze({largeTitle:e(34,48.574219),title1:e(28,41.414063),title2:e(22,32.253906),title3:e(20,27.867187),headline:e(17,24.287109),body:e(17,24.287109),callout:e(16,23.09375),subheadline:e(15,20.900391),footnote:e(13,18.513672),caption1:e(12,17.320313),caption2:e(11,16.126953)}),xl:Object.freeze({largeTitle:e(36,51.351181),title1:e(30,44.271369),title2:e(24,35.069196),title3:e(22,30.733906),headline:e(19,27.037464),body:e(19,27.037464),callout:e(18,25.861421),subheadline:e(17,23.587109),footnote:e(15,21.233724),caption1:e(14,20.269531),caption2:e(13,19.667518)}),xxl:Object.freeze({largeTitle:e(38,54.323266),title1:e(32,47.128676),title2:e(26,37.884487),title3:e(24,33.440625),headline:e(21,29.78782),body:e(21,29.78782),callout:e(20,28.629092),subheadline:e(19,26.273828),footnote:e(17,23.953776),caption1:e(16,23.03125),caption2:e(15,22.515775)}),xxxl:Object.freeze({largeTitle:e(40,57.100229),title1:e(34,50.221278),title2:e(28,40.699777),title3:e(26,36.147344),headline:e(23,32.719993),body:e(23,32.719993),callout:e(22,31.58724),subheadline:e(21,28.960547),footnote:e(19,26.673828),caption1:e(18,25.792969),caption2:e(17,25.364032)}),ax1:Object.freeze({largeTitle:e(44,62.654154),title1:e(38,56.171186),title2:e(34,49.359933),title3:e(31,43.074141),headline:e(28,39.595881),body:e(28,39.595881),callout:e(26,37.122582),subheadline:e(25,34.483984),footnote:e(23,32.280599),caption1:e(22,31.316406),caption2:e(20,29.636418)}),ax2:Object.freeze({largeTitle:e(48,68.403201),title1:e(43,63.314453),title2:e(39,56.612444),title3:e(37,51.194297),headline:e(33,46.653587),body:e(33,46.653587),callout:e(32,45.616071),subheadline:e(30,41.200781),footnote:e(27,37.720703),caption1:e(26,37.027344),caption2:e(24,35.332933)}),ax3:Object.freeze({largeTitle:e(52,73.957127),title1:e(48,70.693015),title2:e(44,63.65067),title3:e(43,59.474453),headline:e(40,56.461648),body:e(40,56.461648),callout:e(38,54.109561),subheadline:e(36,49.410937),footnote:e(33,46.047526),caption1:e(32,45.5),caption2:e(29,42.684345)}),ax4:Object.freeze({largeTitle:e(56,79.706174),title1:e(53,77.600988),title2:e(50,72.310826),title3:e(49,67.754609),headline:e(47,65.360618),body:e(47,66.269709),callout:e(44,62.412574),subheadline:e(42,57.621094),footnote:e(38,53.014323),caption1:e(37,52.404297),caption2:e(34,50.035757)}),ax5:Object.freeze({largeTitle:e(60,85.260099),title1:e(58,85.214844),title2:e(56,80.970982),title3:e(55,76.034766),headline:e(53,74.520774),body:e(53,74.520774),callout:e(51,72.2899),subheadline:e(49,67.174609),footnote:e(44,61.174479),caption1:e(43,60.876953),caption2:e(40,58.811298)})});function E(t){return G.some(o=>Object.is(o,t))}var ce=["colorScheme","reduceMotion","boldText","fontSize","largerAccessibilitySizes"],l={deviceModel:{type:"enum",default:P,description:"device model to simulate",cliFlag:"device",cliFlagShort:"d",options:A(),group:"device"},orientation:{type:"enum",default:"portrait",description:"screen orientation",cliFlag:"orientation",options:["portrait","landscape"],group:"device"},colorScheme:{type:"enum",default:"auto",description:"color scheme (auto follows system preference)",cliFlag:"theme",cliFlagShort:"t",options:["light","dark","auto"],group:"appearance"},reduceMotion:{type:"boolean",default:!1,description:"reduce motion",group:"appearance"},boldText:{type:"boolean",default:!1,description:"bold text",group:"appearance"},fontSize:{type:"number",default:1,description:"font size multiplier (1.0 = default)",group:"appearance",validate:t=>t>=.5&&t<=4},largerAccessibilitySizes:{type:"boolean",default:!1,description:"show accessibility categories in the dynamic type size picker",group:"appearance"},networkCondition:{type:"enum",default:"wifi",description:"simulated network condition",cliFlag:"network",options:["wifi","lte","fast-3g","slow-3g","offline"],group:"network"},language:{type:"string",default:"en",description:"language code (ISO 639-1)",cliFlag:"language",group:"locale"},region:{type:"string",default:"US",description:"region code (ISO 3166-1)",cliFlag:"region",group:"locale"},renderDensity:{type:"number",default:0,description:"render density override in device pixels per point for high-resolution capture (0 = destination display capped at device native)",group:"simulator",validate:t=>t===0||t>=1&&t<=9},showTouches:{type:"boolean",default:!1,description:"show touch indicators",group:"simulator"},showFrame:{type:"boolean",default:!0,description:"show device frame",cliFlag:"frame",group:"simulator"},showMenuBar:{type:"boolean",default:!0,description:"keep the menu bar visible instead of revealing it at the top edge",group:"simulator"},showRail:{type:"boolean",default:!0,description:"keep the rail visible instead of revealing it on hover",group:"simulator"},solidWindow:{type:"boolean",default:!1,description:"desktop app: always use the solid, freely-resizable window instead of the device-shaped transparent one (3d mode uses it regardless)",group:"simulator"},ambientGlow:{type:"enum",default:"off",description:"bleed the app's own edge colors outward behind the device, like bias lighting behind a TV (off, soft, full)",options:k,cliFlag:"ambient-glow",group:"simulator"},screenshotMode:{type:"boolean",default:!1,description:"show screenshot composition mode in the browser shell",group:"simulator"},screenshotCanvasEditing:{type:"boolean",default:!1,description:"experimental figma-style slide editing: draggable copy block, drop-in image layers (owner review pending)",group:"simulator"},threeMode:{type:"boolean",default:!1,description:"show the experimental 3d device stage in the browser shell",group:"simulator"},threeRecordingEditor:{type:"boolean",default:!1,description:"dock the 3d recording editor in the 3d stage (toggled from its rail)",group:"simulator"},screenshotCanvas:{type:"enum",default:"iphone-6-9",description:"target app-store canvas preset for screenshot mode",options:Object.keys(w),group:"simulator"},screenshotBackground:{type:"enum",default:"dark",description:"background preset rendered inside the screenshot canvas",options:Object.keys(I),group:"simulator"},screenshotText:{type:"enum",default:"bold-top",description:"text layout preset for the screenshot canvas",options:["bold-top","editorial-left","minimal-bottom","none"],group:"simulator"},screenshotPose:{type:"enum",default:"straight",description:"device pose preset inside the screenshot canvas",options:["straight","tilted-left","tilted-right","cut-bottom","cut-top"],group:"simulator"},screenshotDynamicSize:{type:"boolean",default:!1,description:"let the screenshot canvas rect fit available space (off = pin to exact preset pixels)",group:"simulator"},showStatusBar:{type:"boolean",default:!0,description:"show status bar",group:"simulator"},showHomeIndicator:{type:"boolean",default:!0,description:"show home indicator",group:"simulator"},alwaysShowLiveWebViews:{type:"boolean",default:!1,description:"always render WebViews as live browser views",group:"simulator"},a11yMode:{type:"enum",default:"delayed",description:"accessibility tree sync mode (off, delayed=100ms, active=30ms)",options:["off","delayed","active"],group:"simulator"},a11yDepth:{type:"enum",default:"deep",description:"accessibility tree structure depth (shallow or deep)",options:["shallow","deep"],group:"simulator"},inspectMode:{type:"boolean",default:!1,description:"inspect mode",group:"simulator"},productAnalytics:{type:"boolean",default:!1,description:"send bounded product usage analytics",group:"privacy"},crashReports:{type:"boolean",default:!1,description:"send anonymous crash reports",group:"privacy"},agentProvider:{type:"enum",default:"codex",description:"ai agent used by the sootsim agent prompt bar",options:["codex","claude"],group:"agent"}},de={colorScheme:l.colorScheme.default,reduceMotion:l.reduceMotion.default,boldText:l.boldText.default,fontSize:l.fontSize.default,largerAccessibilitySizes:l.largerAccessibilitySizes.default};function U(){if(typeof window>"u")return{};let t={};try{let o=new URLSearchParams(window.location.search),a=o.get("device");a&&l.deviceModel.options?.includes(a)&&(t.deviceModel=a);let c=o.get("orientation");(c==="portrait"||c==="landscape")&&(t.orientation=c),o.get("ssMode")==="1"&&(t.screenshotMode=!0),o.get("filmStage")==="1"&&(t.threeMode=!0,a||(t.deviceModel="iphone-17-air"));let h=Number(o.get("renderDensity"));Number.isFinite(h)&&h>=1&&h<=9&&(t.renderDensity=h),o.get("ssEdit")==="1"&&(t.screenshotCanvasEditing=!0);let x=o.get("colorScheme")??o.get("theme");x&&l.colorScheme.options?.includes(x)&&(t.colorScheme=x);let m=o.get("reduceMotion");m==="1"||m==="true"?t.reduceMotion=!0:(m==="0"||m==="false")&&(t.reduceMotion=!1);let g=o.get("boldText");g==="1"||g==="true"?t.boldText=!0:(g==="0"||g==="false")&&(t.boldText=!1);let C=Number(o.get("fontSize"));Number.isFinite(C)&&E(C)&&(t.fontSize=C);let f=o.get("largerAccessibilitySizes");f==="1"||f==="true"?t.largerAccessibilitySizes=!0:(f==="0"||f==="false")&&(t.largerAccessibilitySizes=!1);let b=o.get("alwaysShowLiveWebViews");b==="1"||b==="true"?t.alwaysShowLiveWebViews=!0:(b==="0"||b==="false")&&(t.alwaysShowLiveWebViews=!1);let y=o.get("showFrame");y==="1"||y==="true"?t.showFrame=!0:(y==="0"||y==="false")&&(t.showFrame=!1);let T=o.get("ambientGlow");B(T)&&(t.ambientGlow=T)}catch{}return t}function ue(){let t={};for(let[o,a]of Object.entries(l))t[o]=a.default;return Object.assign(t,U()),t}export{H as a,v as b,j as c,L as d,W as e,K as f,Z as g,Q as h,J as i,ee as j,z as k,te as l,ce as m,l as n,de as o,U as p,ue as q};
5
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -0,0 +1,4 @@
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ import{d as P,m,n as S,o as R,p as _,q as v}from"./chunk-IR44SFBA.js";var k="sootsim:settings",d=["productAnalytics","crashReports","colorScheme","reduceMotion","boldText","fontSize","largerAccessibilitySizes","a11yMode","a11yDepth","screenshotCanvas","screenshotBackground","screenshotText","screenshotPose","screenshotDynamicSize","alwaysShowLiveWebViews","showFrame","showMenuBar","showRail","solidWindow","ambientGlow","agentProvider"];function p(){if(typeof window>"u")return null;let e=window.sootsimElectron;return e&&typeof e=="object"?e:null}function l(e){let t={};for(let n of d){if(!(n in e))continue;let o=e[n],i=S[n];i.validate&&!i.validate(o)||i.options&&!i.options.includes(o)||(t[n]=o)}return t}function K(e){let t={};for(let n of d)t[n]=e[n];return t}function M(){if(typeof localStorage>"u")return{};try{let e=localStorage.getItem(k);return e?l(JSON.parse(e)):{}}catch{return{}}}function T(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(k,JSON.stringify(e))}catch{}}function x(){let t=p()?.sharedConfig?.settings;return!t||typeof t!="object"?{}:l(t)}function A(e){let t=p();if(t?.writeSharedConfig)try{t.writeSharedConfig({settings:e})}catch{}}async function L(e){let t=p();return t?.writeSharedConfig?(await t.writeSharedConfig({settings:e}),!0):!1}function b(){if(typeof window>"u")return null;let e=window.__sootsimSharedConfig;return e&&typeof e=="object"?e:null}function O(){let e=b()?.settings;return!e||typeof e!="object"?{}:l(e)}function B(e){if(!b())return;let t={settings:e};try{if(globalThis.__sootsimBridgeRequest?.writeSharedConfig?.(t))return}catch{}if(!(typeof fetch>"u"))try{fetch("/__sootsim/shared-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}catch{}}async function F(e){if(!b()||typeof fetch>"u")return!1;let t=await fetch("/__sootsim/shared-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({settings:e}),keepalive:!0});if(!t.ok)throw new Error(`shared settings reset failed with HTTP ${t.status}`);return await t.text(),!0}function D(){let e=M(),t=O(),n=x();return{...e,...t,...n}}function V(e,t={}){let n=K(e);for(let o of d)t[o]!==void 0&&(n[o]=t[o]);T(n),A(n),B(n)}async function I(e,t={}){let n=K(e);for(let o of d)t[o]!==void 0&&(n[o]=t[o]);T(n),!await L(n)&&await F(n)}function j(e){if(typeof window>"u")return()=>{};let t=r=>{if(!(r.key!==k||r.newValue==null))try{e(l(JSON.parse(r.newValue)))}catch{}};window.addEventListener("storage",t);let n=p(),o;n?.onSharedConfigChanged&&(o=n.onSharedConfigChanged(r=>{let f=r?.settings;!f||typeof f!="object"||e(l(f))}));let a=globalThis.__sootsimBridgeRequest?.subscribeSharedConfig?.(r=>{let f=r?.settings;!f||typeof f!="object"||e(l(f))});return()=>{window.removeEventListener("storage",t),o?.(),a?.()}}var N=_(),q=v(),y=D(),c=new Set,g={};for(let e of d)N[e]!==void 0&&(c.add(e),y[e]!==void 0&&(g[e]=y[e]),delete y[e]);var s={...q,...y},w=[],u=null;function h(){for(let e of w)e()}function E(){h(),V(s,g)}function C(e,t){let n=S[e];return n.validate&&!n.validate(t)||n.options&&!n.options.includes(t)||s[e]===t?!1:(s={...s,[e]:t},e==="deviceModel"&&(u=null),!0)}j(e=>{let t={...s},n=!1;for(let[o,i]of Object.entries(e)){let a=o;if(c.has(a)){g[a]=i;continue}t[a]!==i&&(t[a]=i,n=!0)}n&&(s=t,u=null,h())});var z={get(e){return s[e]},set(e,t){C(e,t)&&E()},setRuntime(e,t){c.has(e)||(c.add(e),d.includes(e)&&(g[e]=s[e])),C(e,t)&&h()},isRuntimeControlled(e){return c.has(e)},getAll(){return s},apply(e){let t=!1,n={...s};for(let[o,i]of Object.entries(e)){if(i===void 0)continue;let a=o,r=S[a];r&&(r.validate&&!r.validate(i)||r.options&&!r.options.includes(i)||n[a]!==i&&(n[a]=i,t=!0))}t&&(s=n,u=null,E())},applyRuntime(e){let t=!1;for(let n of Object.keys(e)){let o=e[n];o!==void 0&&(c.has(n)||(c.add(n),d.includes(n)&&(g[n]=s[n])),C(n,o)&&(t=!0))}t&&h()},reset(){s=v(),u=null,E()},async resetDeviceContent(){let e=m.filter(n=>!c.has(n)).map(n=>[n,R[n]]),t=e.some(([n,o])=>s[n]!==o);s={...s,...Object.fromEntries(e)};for(let n of m)c.has(n)&&(g[n]=R[n]);t&&h(),await I(s,g)},subscribe(e){return w.push(e),()=>{w=w.filter(t=>t!==e)}},getDeviceSpec(){return u||(u=P(s.deviceModel)),u},getA11yMode(){return s.a11yMode},setA11yMode(e){this.set("a11yMode",e)},getInspectMode(){return s.inspectMode},setInspectMode(e){this.set("inspectMode",e)}};export{z as a};
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  import { createRequire as __sootsimCreateRequire } from 'node:module'
3
3
  var require = __sootsimCreateRequire(import.meta.url)
4
4
  var o=!0,e="public beta",t=e,n="we send anonymous error and dependency data while you use it";export{o as a,e as b,t as c,n as d};
@@ -0,0 +1,4 @@
1
+ /*! rnx v0.1.367 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import { createRequire as __sootsimCreateRequire } from 'node:module'
3
+ var require = __sootsimCreateRequire(import.meta.url)
4
+ import{f as c}from"./chunk-GMLOCV3E.js";function m(e,n){let t=e.indexOf("--testid");if(t>=0&&e[t+1])return{mode:"testid",value:e[t+1]};let i=e.indexOf("--test-id");if(i>=0&&e[i+1])return{mode:"testid",value:e[i+1]};let l=e.indexOf("--text");if(l>=0&&e[l+1])return{mode:"text",value:e[l+1]};let r=n?.[1];return r&&!r.startsWith("-")&&!Number.isFinite(Number(r))?{mode:"testid",value:r}:null}async function a(e,n){let t=await e.send({type:"resolve",selector:n.mode==="testid"?{testID:n.value}:{text:n.value}});if(t===null)return null;if(typeof t!="object")throw new Error("resolve returned an invalid result");let i=Reflect.get(t,"match"),l=Reflect.get(t,"target"),r=[i,l],o=Reflect.get(t,"point"),u=o!==null&&typeof o=="object"?Reflect.get(o,"x"):void 0,d=o!==null&&typeof o=="object"?Reflect.get(o,"y"):void 0;if(!c(r)||typeof u!="number"||!Number.isFinite(u)||typeof d!="number"||!Number.isFinite(d))throw new Error("resolve returned an invalid result");let s=r[0];if(!s)throw new Error("resolve returned an invalid result");return{x:u,y:d,testID:s.testID??null,text:s.text??(n.mode==="text"?n.value:s.label),type:s.type}}export{m as a,a as b};