rnxsim 0.1.364 → 0.1.366

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 (184) hide show
  1. package/README.md +2 -0
  2. package/cli/bridge-flow-runner.ts +2 -2
  3. package/cli/commands/control.ts +3 -44
  4. package/cli/commands/detox.ts +18 -1
  5. package/cli/commands/flow.ts +2 -1
  6. package/detox/index.ts +3 -1
  7. package/dist-cli/bin.js +5 -5
  8. package/dist-cli/chunks/{agent-TPAN64UJ.js → agent-SO6IOPRK.js} +2 -2
  9. package/dist-cli/chunks/{agent-wrapper-GFB3KBNY.js → agent-wrapper-PMYCB2KO.js} +2 -2
  10. package/dist-cli/chunks/{app-fonts-DF5BO6AK.js → app-fonts-LULQGFY7.js} +2 -2
  11. package/dist-cli/chunks/{assert-VVKTC5YX.js → assert-WGNCD4ZU.js} +2 -2
  12. package/dist-cli/chunks/{auth-C7SRVIIX.js → auth-G7CCHH3M.js} +2 -2
  13. package/dist-cli/chunks/{beta-SZVR5QH2.js → beta-N4LXL5TO.js} +2 -2
  14. package/dist-cli/chunks/{camera-XKUQHX54.js → camera-4JHCYBQS.js} +2 -2
  15. package/dist-cli/chunks/{chunk-6TFSPDDE.js → chunk-2S7BKUP2.js} +2 -2
  16. package/dist-cli/chunks/{chunk-6OZZCDOK.js → chunk-2UXU53MG.js} +1 -1
  17. package/dist-cli/chunks/{chunk-GISQDTW6.js → chunk-34IQM22N.js} +2 -2
  18. package/dist-cli/chunks/{chunk-4OK2SZTF.js → chunk-3X6IBUBX.js} +2 -2
  19. package/dist-cli/chunks/{chunk-KXGBOYTB.js → chunk-5DAIA77C.js} +2 -2
  20. package/dist-cli/chunks/{chunk-6EALLMLO.js → chunk-5NMCF5VF.js} +1 -1
  21. package/dist-cli/chunks/{chunk-CDGPG6JU.js → chunk-5OK3LCEJ.js} +2 -2
  22. package/dist-cli/chunks/{chunk-CAP2EQ4P.js → chunk-6PL2CCGP.js} +2 -2
  23. package/dist-cli/chunks/{chunk-WKH7T3YK.js → chunk-77ZHQJZR.js} +2 -2
  24. package/dist-cli/chunks/chunk-7B37IZBN.js +15 -0
  25. package/dist-cli/chunks/{chunk-QECOXZY3.js → chunk-A5FXX5PJ.js} +1 -1
  26. package/dist-cli/chunks/{chunk-DSD2TMUC.js → chunk-AFV32WZT.js} +3 -3
  27. package/dist-cli/chunks/{chunk-VDEE37CY.js → chunk-CN6XYYEA.js} +12 -12
  28. package/dist-cli/chunks/{chunk-WK3QQTWE.js → chunk-CTG7HBCA.js} +1 -1
  29. package/dist-cli/chunks/{chunk-XXFZMO4I.js → chunk-DMPF2D24.js} +2 -2
  30. package/dist-cli/chunks/{chunk-SWIEVEPN.js → chunk-DW37EVX5.js} +1 -1
  31. package/dist-cli/chunks/{chunk-2UM2IFEM.js → chunk-DWFIH7CB.js} +2 -2
  32. package/dist-cli/chunks/{chunk-7RZI733Y.js → chunk-EFR5DVNP.js} +1 -1
  33. package/dist-cli/chunks/{chunk-LWOIQBVX.js → chunk-EGAGZHO6.js} +1 -1
  34. package/dist-cli/chunks/{chunk-AUHE5LTY.js → chunk-EQK5MJCU.js} +2 -2
  35. package/dist-cli/chunks/{chunk-T2U4BLWM.js → chunk-GAJQSITE.js} +1 -1
  36. package/dist-cli/chunks/{chunk-MPWM3TBY.js → chunk-GUI3PDH2.js} +2 -2
  37. package/dist-cli/chunks/{chunk-5OZJUMUS.js → chunk-GXAB52K7.js} +2 -2
  38. package/dist-cli/chunks/{chunk-3LSNLOZR.js → chunk-H23KWIKA.js} +2 -2
  39. package/dist-cli/chunks/{chunk-GJKVFQCF.js → chunk-HT6GFZOZ.js} +1 -1
  40. package/dist-cli/chunks/{chunk-475BITXX.js → chunk-I6KIM6PN.js} +1 -1
  41. package/dist-cli/chunks/{chunk-PSUX2SIK.js → chunk-IZKHOM37.js} +1 -1
  42. package/dist-cli/chunks/{chunk-GCMVAY4M.js → chunk-JHXETDVC.js} +1 -1
  43. package/dist-cli/chunks/{chunk-MUKHA5UF.js → chunk-KLF3K6ZZ.js} +1 -1
  44. package/dist-cli/chunks/{chunk-6CQSKBKG.js → chunk-LN3RNW6X.js} +2 -2
  45. package/dist-cli/chunks/{chunk-26XF67QW.js → chunk-M3BNCF7E.js} +2 -2
  46. package/dist-cli/chunks/{chunk-XXP4GLLC.js → chunk-M5QCGLXR.js} +3 -3
  47. package/dist-cli/chunks/{chunk-OXXWSZKI.js → chunk-M6SKQGAN.js} +2 -2
  48. package/dist-cli/chunks/{chunk-5GO3JI65.js → chunk-MGDSJZ37.js} +2 -2
  49. package/dist-cli/chunks/{chunk-JF6NYOSI.js → chunk-N3UC7HIX.js} +1 -1
  50. package/dist-cli/chunks/{chunk-GYC6VTQV.js → chunk-NAYLPOC5.js} +2 -2
  51. package/dist-cli/chunks/{chunk-BRU5PPUO.js → chunk-NM2L2QV4.js} +2 -2
  52. package/dist-cli/chunks/{chunk-6TAFS3GK.js → chunk-NQFJOCSF.js} +2 -2
  53. package/dist-cli/chunks/{chunk-QSGQVEGD.js → chunk-ONORMKWX.js} +2 -2
  54. package/dist-cli/chunks/{chunk-ONGTUKC3.js → chunk-ORWP2E7R.js} +2 -2
  55. package/dist-cli/chunks/{chunk-PG2B65PZ.js → chunk-OW5XHAA4.js} +1 -1
  56. package/dist-cli/chunks/{chunk-GXMNFFJJ.js → chunk-RYIMSKDO.js} +2 -2
  57. package/dist-cli/chunks/{chunk-2TL6BZCH.js → chunk-SA6XVI55.js} +1 -1
  58. package/dist-cli/chunks/{chunk-QWRQ7RY6.js → chunk-TIAEYO6I.js} +2 -2
  59. package/dist-cli/chunks/{chunk-FKAZFE5Z.js → chunk-TTASWLKM.js} +1 -1
  60. package/dist-cli/chunks/{chunk-X3N2H4A3.js → chunk-UCHW7ZHR.js} +2 -2
  61. package/dist-cli/chunks/{chunk-UDZI7GEV.js → chunk-VIND4SP3.js} +1 -1
  62. package/dist-cli/chunks/{chunk-ZOQAPVNV.js → chunk-XJU2QIRY.js} +2 -2
  63. package/dist-cli/chunks/{chunk-EP5FYRBT.js → chunk-XXNLYR64.js} +3 -3
  64. package/dist-cli/chunks/{chunk-PTOGXUOE.js → chunk-YCCCPFWT.js} +2 -2
  65. package/dist-cli/chunks/chunk-YGMEDJKJ.js +4 -0
  66. package/dist-cli/chunks/{chunk-S7OIWXIZ.js → chunk-YXXKSL6R.js} +1 -1
  67. package/dist-cli/chunks/{chunk-V7CAEDZT.js → chunk-ZFM24DOX.js} +2 -2
  68. package/dist-cli/chunks/{chunk-YJTZ77E4.js → chunk-ZJIS3CTW.js} +2 -2
  69. package/dist-cli/chunks/{chunk-IX2ZY3FI.js → chunk-ZLVRYXZ7.js} +1 -1
  70. package/dist-cli/chunks/{chunk-ZUKAXCGG.js → chunk-ZMJ75EDG.js} +2 -2
  71. package/dist-cli/chunks/{cleanup-KSK43W4F.js → cleanup-KRIATKFH.js} +2 -2
  72. package/dist-cli/chunks/cli-version-SYGNHGFR.js +4 -0
  73. package/dist-cli/chunks/{compat-ETLIMR6U.js → compat-6PTQ3QEA.js} +2 -2
  74. package/dist-cli/chunks/{config-GZKHF2OQ.js → config-ETGDUANO.js} +2 -2
  75. package/dist-cli/chunks/control-RBTNOLQM.js +4 -0
  76. package/dist-cli/chunks/daemon-N3SC5DK6.js +4 -0
  77. package/dist-cli/chunks/{debug-TCZOR7EX.js → debug-WIIB6ZKC.js} +3 -3
  78. package/dist-cli/chunks/{desktop-SXNUOCYY.js → desktop-TD7Q5LNB.js} +3 -3
  79. package/dist-cli/chunks/detox-7GNR33VM.js +52 -0
  80. package/dist-cli/chunks/{device-W7U63QOH.js → device-QOR3PGUF.js} +2 -2
  81. package/dist-cli/chunks/{diagnose-TNZKUJHP.js → diagnose-RRCBLP6E.js} +2 -2
  82. package/dist-cli/chunks/{disk-cleanup-3YIXIS5V.js → disk-cleanup-MJUGJPXT.js} +2 -2
  83. package/dist-cli/chunks/drivers-W6E3BZH4.js +4 -0
  84. package/dist-cli/chunks/{film-E4DAHL3T.js → film-D7Y64LID.js} +3 -3
  85. package/dist-cli/chunks/flow-7QAE2V5Y.js +4 -0
  86. package/dist-cli/chunks/help-NLD6KWVG.js +4 -0
  87. package/dist-cli/chunks/{hidden-runtime-alias-JGC3RNJM.js → hidden-runtime-alias-JGURVR2Z.js} +2 -2
  88. package/dist-cli/chunks/{home-paths-RMAJUXID.js → home-paths-4ICFIGXO.js} +2 -2
  89. package/dist-cli/chunks/inspect-C347BG52.js +4 -0
  90. package/dist-cli/chunks/install-desktop-YR6TWZYK.js +4 -0
  91. package/dist-cli/chunks/{login-AVAHLXIO.js → login-RU33QR2G.js} +2 -2
  92. package/dist-cli/chunks/{logout-FHY54N66.js → logout-2IUG3Y5J.js} +2 -2
  93. package/dist-cli/chunks/{maestro-4FOX653X.js → maestro-2MXTGG7I.js} +3 -3
  94. package/dist-cli/chunks/{maestro-generate-A5VA2C2L.js → maestro-generate-2PYIFGLR.js} +3 -3
  95. package/dist-cli/chunks/{mode-EEMUPUUN.js → mode-3DAPG3HF.js} +2 -2
  96. package/dist-cli/chunks/{optional-demo-registry-OOJVFEEM.js → optional-demo-registry-BWSDJF2Z.js} +2 -2
  97. package/dist-cli/chunks/{perf-KC3DWW2K.js → perf-2TKPWB4N.js} +2 -2
  98. package/dist-cli/chunks/{permissions-NYLB3HTV.js → permissions-5CSMHYNA.js} +2 -2
  99. package/dist-cli/chunks/privacy-PWWC2BXO.js +4 -0
  100. package/dist-cli/chunks/{record-W4VGQFZO.js → record-I2HJCFP3.js} +3 -3
  101. package/dist-cli/chunks/{report-issue-OV4TEQA4.js → report-issue-A4FZWBOC.js} +2 -2
  102. package/dist-cli/chunks/reset-Y3PBPFYA.js +4 -0
  103. package/dist-cli/chunks/runtime-IC6NVVGA.js +4 -0
  104. package/dist-cli/chunks/{screenshot-command-E5UQAWDL.js → screenshot-command-UFW5BFHP.js} +3 -3
  105. package/dist-cli/chunks/{screenshot-layers-FKOOWRTR.js → screenshot-layers-5BIAL4YN.js} +2 -2
  106. package/dist-cli/chunks/{screenshots-capture-75RRIMXV.js → screenshots-capture-EHYS3BV2.js} +2 -2
  107. package/dist-cli/chunks/{serve-FSKXPWZS.js → serve-O4FDM3AC.js} +2 -2
  108. package/dist-cli/chunks/setup-Y4QGSJBM.js +4 -0
  109. package/dist-cli/chunks/{skills-6KOGOICV.js → skills-ZK55SY32.js} +2 -2
  110. package/dist-cli/chunks/{state-MFXITPJO.js → state-KFLAZNEY.js} +2 -2
  111. package/dist-cli/chunks/{storage-Y6WMFSON.js → storage-WP33ISEM.js} +2 -2
  112. package/dist-cli/chunks/store-VEE22CAY.js +4 -0
  113. package/dist-cli/chunks/telemetry-PZV4BISJ.js +4 -0
  114. package/dist-cli/chunks/{timeline-ULQSPSUI.js → timeline-DKGW5S4I.js} +2 -2
  115. package/dist-cli/chunks/{upgrade-TXKMF6QG.js → upgrade-LL7G4B7G.js} +2 -2
  116. package/dist-cli/chunks/upload-Y4C3YZDK.js +4 -0
  117. package/dist-cli/chunks/{version-ELQDHWMV.js → version-YLWR5G4F.js} +2 -2
  118. package/dist-cli/chunks/{web-QDYHKVEF.js → web-QELZ4CP6.js} +2 -2
  119. package/dist-cli/chunks/welcome-ZPKA5PZJ.js +5 -0
  120. package/dist-cli/chunks/{what-happened-64IQA6AX.js → what-happened-MIOMZWM5.js} +2 -2
  121. package/dist-lib/agent-daemon-client.cjs +1 -1
  122. package/dist-lib/agent-events.cjs +1 -1
  123. package/dist-lib/agent-identity.cjs +1 -1
  124. package/dist-lib/agent-sessions.cjs +1 -1
  125. package/dist-lib/attached-projects.cjs +1 -1
  126. package/dist-lib/auth/shared-session.cjs +1 -1
  127. package/dist-lib/backend-origin.cjs +1 -1
  128. package/dist-lib/beta.cjs +1 -1
  129. package/dist-lib/beta.mjs +1 -1
  130. package/dist-lib/bridge-constants.cjs +1 -1
  131. package/dist-lib/bridge-contract.cjs +1 -1
  132. package/dist-lib/cli-constants.cjs +1 -1
  133. package/dist-lib/config.cjs +1 -1
  134. package/dist-lib/detox/index.cjs +4 -2
  135. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  136. package/dist-lib/home-paths.cjs +1 -1
  137. package/dist-lib/host/bridge-host.cjs +1 -1
  138. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  139. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  140. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  141. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  142. package/dist-lib/host/websocket-proxy.cjs +1 -1
  143. package/dist-lib/index.cjs +31 -1
  144. package/dist-lib/jump-to-source-babel.cjs +1 -1
  145. package/dist-lib/mcp.cjs +673 -0
  146. package/dist-lib/mcp.mjs +641 -0
  147. package/dist-lib/menu.cjs +1 -1
  148. package/dist-lib/menu.mjs +1 -1
  149. package/dist-lib/metro-production-bundle.cjs +1 -1
  150. package/dist-lib/metro-production-bundle.mjs +1 -1
  151. package/dist-lib/metro.cjs +1 -1
  152. package/dist-lib/profiles.cjs +1 -1
  153. package/dist-lib/public-brand.cjs +1 -1
  154. package/dist-lib/react-native-host-modules.cjs +1 -1
  155. package/dist-lib/react-native-host-modules.mjs +1 -1
  156. package/dist-lib/render-mode.cjs +1 -1
  157. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  158. package/dist-lib/sdk.cjs +31 -1
  159. package/dist-lib/sdk.mjs +31 -1
  160. package/dist-lib/skills.cjs +67 -53
  161. package/dist-lib/vite.cjs +1 -1
  162. package/package.json +7 -1
  163. package/src/app-url.ts +40 -0
  164. package/src/mcp.ts +791 -0
  165. package/src/sim-client.ts +12 -6
  166. package/dist-cli/chunks/chunk-2FLTYH6I.js +0 -15
  167. package/dist-cli/chunks/chunk-HFHQUP6D.js +0 -4
  168. package/dist-cli/chunks/cli-version-VMIKRJJR.js +0 -4
  169. package/dist-cli/chunks/control-GEI7BBKL.js +0 -4
  170. package/dist-cli/chunks/daemon-F4J2GDYQ.js +0 -4
  171. package/dist-cli/chunks/detox-3IE75WQS.js +0 -52
  172. package/dist-cli/chunks/drivers-EW637BG3.js +0 -4
  173. package/dist-cli/chunks/flow-FX5GS2R4.js +0 -4
  174. package/dist-cli/chunks/help-2GRNPHE6.js +0 -4
  175. package/dist-cli/chunks/inspect-G24KNRYH.js +0 -4
  176. package/dist-cli/chunks/install-desktop-FHESQL4S.js +0 -4
  177. package/dist-cli/chunks/privacy-FHOKJ2N7.js +0 -4
  178. package/dist-cli/chunks/reset-MUWZMMPE.js +0 -4
  179. package/dist-cli/chunks/runtime-TK4FTIEZ.js +0 -4
  180. package/dist-cli/chunks/setup-LAKKCS57.js +0 -4
  181. package/dist-cli/chunks/store-56XZIZGX.js +0 -4
  182. package/dist-cli/chunks/telemetry-OXQ57PD4.js +0 -4
  183. package/dist-cli/chunks/upload-S3BWN6EM.js +0 -4
  184. package/dist-cli/chunks/welcome-ZT56CZ2Z.js +0 -5
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/react-native-host-modules.ts
4
4
  var REACT_NATIVE_PASSTHROUGH_SPECIFIERS = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -2315,6 +2315,32 @@ async function resolveTargetCoords(bridge, target) {
2315
2315
  return result ?? null;
2316
2316
  }
2317
2317
 
2318
+ // src/app-url.ts
2319
+ var APP_URL_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:/;
2320
+ function normalizeAppUrlTarget(target) {
2321
+ const trimmed = target.trim();
2322
+ if (!trimmed) {
2323
+ throw new Error("expected <url-or-route>");
2324
+ }
2325
+ if (APP_URL_SCHEME_RE.test(trimmed) || trimmed.startsWith("/")) {
2326
+ return trimmed;
2327
+ }
2328
+ return `/${trimmed}`;
2329
+ }
2330
+ async function openAppUrl(bridge, target) {
2331
+ const normalized = normalizeAppUrlTarget(target);
2332
+ const result = await bridge.send({
2333
+ type: "call",
2334
+ path: "SootSim.bridges.test.openDeepLink",
2335
+ args: [normalized]
2336
+ });
2337
+ if (result !== null && typeof result === "object" && Reflect.get(result, "ok") === false) {
2338
+ const error = Reflect.get(result, "error");
2339
+ throw new Error(typeof error === "string" ? error : "deep-link dispatch failed");
2340
+ }
2341
+ return normalized;
2342
+ }
2343
+
2318
2344
  // src/sim-client.ts
2319
2345
  var SimClientError = class extends Error {
2320
2346
  constructor(message) {
@@ -2475,6 +2501,10 @@ var SimClient = class {
2475
2501
  `timed out waiting for sim ${this.simId} to load ${nextUrl}`
2476
2502
  );
2477
2503
  }
2504
+ /** dispatch a route or app URL through React Native Linking in this guest. */
2505
+ openUrl(target) {
2506
+ return openAppUrl(this, target);
2507
+ }
2478
2508
  /**
2479
2509
  * block until the guest app has mounted and painted real content.
2480
2510
  * throws SimReadyTimeoutError (with the last probe status) on timeout.
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -2217,6 +2217,32 @@ async function resolveTargetCoords(bridge, target) {
2217
2217
  return result ?? null;
2218
2218
  }
2219
2219
 
2220
+ // src/app-url.ts
2221
+ var APP_URL_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:/;
2222
+ function normalizeAppUrlTarget(target) {
2223
+ const trimmed = target.trim();
2224
+ if (!trimmed) {
2225
+ throw new Error("expected <url-or-route>");
2226
+ }
2227
+ if (APP_URL_SCHEME_RE.test(trimmed) || trimmed.startsWith("/")) {
2228
+ return trimmed;
2229
+ }
2230
+ return `/${trimmed}`;
2231
+ }
2232
+ async function openAppUrl(bridge, target) {
2233
+ const normalized = normalizeAppUrlTarget(target);
2234
+ const result = await bridge.send({
2235
+ type: "call",
2236
+ path: "SootSim.bridges.test.openDeepLink",
2237
+ args: [normalized]
2238
+ });
2239
+ if (result !== null && typeof result === "object" && Reflect.get(result, "ok") === false) {
2240
+ const error = Reflect.get(result, "error");
2241
+ throw new Error(typeof error === "string" ? error : "deep-link dispatch failed");
2242
+ }
2243
+ return normalized;
2244
+ }
2245
+
2220
2246
  // src/sim-client.ts
2221
2247
  var SimClientError = class extends Error {
2222
2248
  constructor(message) {
@@ -2377,6 +2403,10 @@ var SimClient = class {
2377
2403
  `timed out waiting for sim ${this.simId} to load ${nextUrl}`
2378
2404
  );
2379
2405
  }
2406
+ /** dispatch a route or app URL through React Native Linking in this guest. */
2407
+ openUrl(target) {
2408
+ return openAppUrl(this, target);
2409
+ }
2380
2410
  /**
2381
2411
  * block until the guest app has mounted and painted real content.
2382
2412
  * throws SimReadyTimeoutError (with the last probe status) on timeout.
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1180,6 +1180,16 @@ var init_react_native_root_export_coverage = __esm({
1180
1180
  }
1181
1181
  });
1182
1182
 
1183
+ // ../compat/src/generated/react-native-webview-coverage.ts
1184
+ var REACT_NATIVE_WEBVIEW_WILL_IT_WORK_COVERAGE, REACT_NATIVE_WEBVIEW_STRICT_COVERAGE;
1185
+ var init_react_native_webview_coverage = __esm({
1186
+ "../compat/src/generated/react-native-webview-coverage.ts"() {
1187
+ "use strict";
1188
+ REACT_NATIVE_WEBVIEW_WILL_IT_WORK_COVERAGE = 0.74;
1189
+ REACT_NATIVE_WEBVIEW_STRICT_COVERAGE = 0.223;
1190
+ }
1191
+ });
1192
+
1183
1193
  // ../compat/src/unsupported-packages.ts
1184
1194
  function getUnsupportedNativePackage(name2) {
1185
1195
  const entry = UNSUPPORTED_NATIVE_PACKAGES[name2];
@@ -1220,6 +1230,7 @@ var init_registry = __esm({
1220
1230
  "use strict";
1221
1231
  init_capability_inventory_coverage();
1222
1232
  init_react_native_root_export_coverage();
1233
+ init_react_native_webview_coverage();
1223
1234
  init_unsupported_packages();
1224
1235
  COMPAT_CATEGORIES = [
1225
1236
  "All",
@@ -1371,10 +1382,11 @@ var init_registry = __esm({
1371
1382
  versions: [
1372
1383
  {
1373
1384
  range: ">=11.0.0",
1374
- coverage: 0.55,
1375
- note: "native-seam only: the published package runs unchanged and routes RNCWebView through the tenant-to-shell hosted iframe surface. chromium can load cross-origin source.uri pages under the shell COEP through a credentialless frame; same-origin URI and source.html keep normal cookie and persistent-storage semantics. the iframe keeps loading while parked behind a canvas placeholder and becomes interactive when promoted live. paired native and SootSim runtime conformance covers local-page onOpenWindow target delivery.",
1376
- working: "source.uri/source.html, Chromium cross-origin URI loading under the shell COEP, same-origin URI cookies, source.html persistent localStorage, document-start ReactNativeWebView bootstrap and injectedJavaScriptBeforeContentLoaded/injectedJavaScript on source.html and percent-encoded data: URI pages, strict ReactNativeWebView.postMessage bridge envelope, onMessage synthetic event with navigation fields, onOpenWindow target delivery for source.html and percent-encoded data: URI pages, onLoad/Start/End, onNavigationStateChange, ref.reload/stopLoading/injectJavaScript/postMessage, renderLoading, javaScriptEnabled sandbox, layout, inherited clipping and visibility, parked/live presentation",
1377
- missing: "Safari/WebKit cross-origin URI pages without COEP-compatible response headers remain permanently loading because WebKit ignores iframe credentialless; Chromium credentialless cross-origin URI frames send no credentials, including cookies set by their own origin, and use ephemeral storage; iframe pixels in canvas screenshots; script injection, ReactNativeWebView bootstrap, and onOpenWindow for remote pages, which get no bridge at all because a browser cannot script a cross-origin frame; the re-encoded data: URI a page reports as its own location.href, so onMessage carries the re-encoded url while onLoad and onNavigationStateChange carry the original where iOS reports one identical url for all three; cross-origin ref.goBack/goForward and truthful canGoBack/canGoForward values; failed HTTP/refused navigation callbacks (onError/onHttpError and renderError); onShouldStartLoadWithRequest, allowsBackForwardNavigationGestures, userAgent, dataDetectorTypes, cacheEnabled, incognito, scalesPageToFit, originWhitelist enforcement"
1385
+ coverage: REACT_NATIVE_WEBVIEW_WILL_IT_WORK_COVERAGE,
1386
+ strictCoverage: REACT_NATIVE_WEBVIEW_STRICT_COVERAGE,
1387
+ note: "native-seam only: the published package runs unchanged and routes RNCWebView through the tenant-to-shell hosted iframe surface. coverage is generated from app-source use in six pinned applications; equal-surface strict coverage includes the shared, iOS, and Android public prop and ref surface. paired native and SootSim runtime conformance covers local HTML, base URL, URI loading, load and navigation callbacks, both injection phases, two-way messaging, imperative URI reload and injection, content scrolling, parent translation, and onOpenWindow target delivery.",
1388
+ working: "source.uri/source.html/source.baseUrl, Chromium cross-origin URI loading under the shell COEP, same-origin URI cookies, source.html persistent localStorage, document-start ReactNativeWebView bootstrap and injectedJavaScriptBeforeContentLoaded/injectedJavaScript on source.html, strict ReactNativeWebView.postMessage bridge envelope in both directions, onMessage synthetic event with navigation fields, onOpenWindow target delivery for source.html, successful onLoad/Start/End and onNavigationStateChange, ref.reload on URI pages, ref.injectJavaScript/postMessage, internal content scrolling, renderLoading, javaScriptEnabled sandbox, layout, inherited clipping and visibility, parked/live presentation",
1389
+ missing: "Safari/WebKit cross-origin URI pages without COEP-compatible response headers remain permanently loading because WebKit ignores iframe credentialless; Chromium credentialless cross-origin URI frames send no credentials, including cookies set by their own origin, and use ephemeral storage; iframe pixels in canvas screenshots; script injection, ReactNativeWebView bootstrap, and onOpenWindow for remote pages, which get no bridge at all because a browser cannot script a cross-origin frame; cross-origin ref.goBack/goForward/stopLoading and truthful canGoBack/canGoForward values; failed HTTP/refused navigation callbacks (onError/onHttpError and renderError); onShouldStartLoadWithRequest, allowsBackForwardNavigationGestures, userAgent, dataDetectorTypes, cacheEnabled, incognito, scalesPageToFit, originWhitelist enforcement"
1378
1390
  }
1379
1391
  ]
1380
1392
  },
@@ -21171,6 +21183,45 @@ var init_ws_bridge = __esm({
21171
21183
  }
21172
21184
  });
21173
21185
 
21186
+ // src/app-url.ts
21187
+ function normalizeAppUrlTarget(target) {
21188
+ const trimmed = target.trim();
21189
+ if (!trimmed) {
21190
+ throw new Error("expected <url-or-route>");
21191
+ }
21192
+ if (APP_URL_SCHEME_RE.test(trimmed) || trimmed.startsWith("/")) {
21193
+ return trimmed;
21194
+ }
21195
+ return `/${trimmed}`;
21196
+ }
21197
+ function isAppDeepLinkTarget(target) {
21198
+ const trimmed = target.trim();
21199
+ if (!trimmed) return false;
21200
+ if (trimmed.startsWith("/")) return true;
21201
+ if (!APP_URL_SCHEME_RE.test(trimmed)) return false;
21202
+ return !/^https?:\/\//i.test(trimmed);
21203
+ }
21204
+ async function openAppUrl(bridge, target) {
21205
+ const normalized = normalizeAppUrlTarget(target);
21206
+ const result = await bridge.send({
21207
+ type: "call",
21208
+ path: "SootSim.bridges.test.openDeepLink",
21209
+ args: [normalized]
21210
+ });
21211
+ if (result !== null && typeof result === "object" && Reflect.get(result, "ok") === false) {
21212
+ const error = Reflect.get(result, "error");
21213
+ throw new Error(typeof error === "string" ? error : "deep-link dispatch failed");
21214
+ }
21215
+ return normalized;
21216
+ }
21217
+ var APP_URL_SCHEME_RE;
21218
+ var init_app_url = __esm({
21219
+ "src/app-url.ts"() {
21220
+ "use strict";
21221
+ APP_URL_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:/;
21222
+ }
21223
+ });
21224
+
21174
21225
  // src/dev-bundle-resolution.ts
21175
21226
  function buildUnresolvedTargetError(targetLabel) {
21176
21227
  return new Error(
@@ -24002,7 +24053,6 @@ __export(control_exports, {
24002
24053
  buildShellUrl: () => buildShellUrl,
24003
24054
  closeSimsBulk: () => closeSimsBulk,
24004
24055
  ensureBridgeForOpen: () => ensureBridgeForOpen,
24005
- normalizeDeepLinkTarget: () => normalizeDeepLinkTarget,
24006
24056
  planBulkCloseTargets: () => planBulkCloseTargets,
24007
24057
  playwrightHostPidForSim: () => playwrightHostPidForSim,
24008
24058
  printConnectedSims: () => printConnectedSims,
@@ -24063,26 +24113,6 @@ function resolveDriverHeadless(args, driverId) {
24063
24113
  function normalizeKnownTarget(target) {
24064
24114
  return target.trim();
24065
24115
  }
24066
- function normalizeDeepLinkTarget(target) {
24067
- const trimmed = target.trim();
24068
- if (!trimmed) {
24069
- throw new Error("expected <url-or-route>");
24070
- }
24071
- if (DEEP_LINK_SCHEME_RE.test(trimmed) || trimmed.startsWith("/")) {
24072
- return trimmed;
24073
- }
24074
- return `/${trimmed}`;
24075
- }
24076
- function isObjectRecord(value) {
24077
- return value !== null && typeof value === "object";
24078
- }
24079
- function shouldOpenAsDeepLink(target) {
24080
- const trimmed = target.trim();
24081
- if (!trimmed) return false;
24082
- if (trimmed.startsWith("/")) return true;
24083
- if (!DEEP_LINK_SCHEME_RE.test(trimmed)) return false;
24084
- return !/^https?:\/\//i.test(trimmed);
24085
- }
24086
24116
  async function ensureBridgeForOpen(preferredPort, explicitPort = false) {
24087
24117
  const lock = readDaemonLockfile();
24088
24118
  assertExplicitBridgeLock(preferredPort, explicitPort, lock);
@@ -24932,26 +24962,10 @@ async function runLinkCommand(args, opts = {}) {
24932
24962
  console.error(" examples: rnx open /settings | rnx open myapp://settings");
24933
24963
  process.exit(1);
24934
24964
  }
24935
- let target;
24936
- try {
24937
- target = normalizeDeepLinkTarget(parsed.positional[0] ?? "");
24938
- } catch (err) {
24939
- console.error(` rnx open: ${err instanceof Error ? err.message : String(err)}`);
24940
- process.exit(1);
24941
- }
24942
24965
  const bridge = createBridgeFromParsed(parsed);
24943
24966
  const simHint = parsed.simId ? ` --sim ${parsed.simId}` : "";
24944
24967
  try {
24945
- const result = await bridge.send({
24946
- type: "call",
24947
- path: "SootSim.bridges.test.openDeepLink",
24948
- args: [target]
24949
- });
24950
- if (isObjectRecord(result) && result.ok === false) {
24951
- throw new Error(
24952
- typeof result.error === "string" ? result.error : "deep-link dispatch failed"
24953
- );
24954
- }
24968
+ const target = await openAppUrl(bridge, parsed.positional[0] ?? "");
24955
24969
  console.log(` opened deep link: ${target}`);
24956
24970
  } catch (err) {
24957
24971
  console.error(` link failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -25014,7 +25028,7 @@ async function runOpenCommand(args, opts = {}) {
25014
25028
  process.exit(1);
25015
25029
  }
25016
25030
  const target = parsed.positional[0] || "";
25017
- if (shouldOpenAsDeepLink(target)) {
25031
+ if (isAppDeepLinkTarget(target)) {
25018
25032
  if (openInNewSim) {
25019
25033
  console.error(
25020
25034
  " rnx open: deep links target the current app; remove --new, --profile, or --ephemeral"
@@ -25551,7 +25565,7 @@ async function runCloseCommand(args, opts = {}) {
25551
25565
  bridge.close();
25552
25566
  }
25553
25567
  }
25554
- var import_node_child_process6, import_node_fs13, import_node_os3, import_node_path16, import_settings, import_ws5, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS, DEEP_LINK_SCHEME_RE;
25568
+ var import_node_child_process6, import_node_fs13, import_node_os3, import_node_path16, import_settings, import_ws5, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS;
25555
25569
  var init_control = __esm({
25556
25570
  "cli/commands/control.ts"() {
25557
25571
  "use strict";
@@ -25562,6 +25576,7 @@ var init_control = __esm({
25562
25576
  import_settings = require("sootsim-engine/settings");
25563
25577
  import_ws5 = require("ws");
25564
25578
  init_dev_server_scanner();
25579
+ init_app_url();
25565
25580
  init_backend_origin();
25566
25581
  init_bridge_constants();
25567
25582
  init_config();
@@ -25598,7 +25613,6 @@ var init_control = __esm({
25598
25613
  photos: "/app/photos",
25599
25614
  camera: "/app/camera"
25600
25615
  };
25601
- DEEP_LINK_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:/;
25602
25616
  }
25603
25617
  });
25604
25618
 
@@ -26702,16 +26716,16 @@ __export(bridge_flow_runner_exports, {
26702
26716
  function sleep3(ms) {
26703
26717
  return new Promise((resolve7) => setTimeout(resolve7, ms));
26704
26718
  }
26705
- function isObjectRecord2(value) {
26719
+ function isObjectRecord(value) {
26706
26720
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
26707
26721
  }
26708
26722
  function readStringKey(value, key) {
26709
- if (!isObjectRecord2(value)) return null;
26723
+ if (!isObjectRecord(value)) return null;
26710
26724
  const raw = value[key];
26711
26725
  return typeof raw === "string" && raw.length > 0 ? raw : null;
26712
26726
  }
26713
26727
  function readBooleanKey(value, key) {
26714
- if (!isObjectRecord2(value)) return false;
26728
+ if (!isObjectRecord(value)) return false;
26715
26729
  return value[key] === true;
26716
26730
  }
26717
26731
  function readRecentShellAppId(state) {
@@ -28016,8 +28030,8 @@ var init_bridge_flow_runner = __esm({
28016
28030
  await this.refreshSimId();
28017
28031
  let hasLaunchArguments = false;
28018
28032
  let launchArguments;
28019
- if (isObjectRecord2(opts) && Object.prototype.hasOwnProperty.call(opts, "arguments")) {
28020
- if (!isObjectRecord2(opts.arguments)) {
28033
+ if (isObjectRecord(opts) && Object.prototype.hasOwnProperty.call(opts, "arguments")) {
28034
+ if (!isObjectRecord(opts.arguments)) {
28021
28035
  throw new Error("launchApp.arguments must be a JSON object");
28022
28036
  }
28023
28037
  hasLaunchArguments = true;
@@ -28069,7 +28083,7 @@ var init_bridge_flow_runner = __esm({
28069
28083
  await this.waitForTree(12e4);
28070
28084
  if (this.opts.onAfterLaunch) {
28071
28085
  try {
28072
- await this.opts.onAfterLaunch();
28086
+ await this.opts.onAfterLaunch(this.opts.simId);
28073
28087
  } catch (err) {
28074
28088
  console.warn(
28075
28089
  ` warn: onAfterLaunch hook threw: ${err instanceof Error ? err.message : err}`
@@ -28102,7 +28116,7 @@ var init_bridge_flow_runner = __esm({
28102
28116
  }
28103
28117
  resolveShellLaunchAppId(opts, state) {
28104
28118
  if (typeof opts === "string" && opts.length > 0) return opts;
28105
- if (isObjectRecord2(opts)) {
28119
+ if (isObjectRecord(opts)) {
28106
28120
  const explicit = readStringKey(opts, "appId") || readStringKey(opts, "id");
28107
28121
  if (explicit) return explicit;
28108
28122
  }
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.364 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.366 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rnxsim",
3
- "version": "0.1.364",
3
+ "version": "0.1.366",
4
4
  "description": "rnx CLI, Vite and Metro plugins, and agent skills for driving React Native apps in the browser.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -71,6 +71,12 @@
71
71
  "import": "./dist-lib/sdk.mjs",
72
72
  "default": "./dist-lib/sdk.cjs"
73
73
  },
74
+ "./mcp": {
75
+ "types": "./src/mcp.ts",
76
+ "source": "./src/mcp.ts",
77
+ "import": "./dist-lib/mcp.mjs",
78
+ "default": "./dist-lib/mcp.cjs"
79
+ },
74
80
  "./beta": {
75
81
  "source": "./src/beta.ts",
76
82
  "import": "./dist-lib/beta.mjs",
package/src/app-url.ts ADDED
@@ -0,0 +1,40 @@
1
+ import type { InspectBridge } from '../cli/commands/inspect/core'
2
+
3
+ const APP_URL_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:/
4
+
5
+ export function normalizeAppUrlTarget(target: string): string {
6
+ const trimmed = target.trim()
7
+ if (!trimmed) {
8
+ throw new Error('expected <url-or-route>')
9
+ }
10
+ if (APP_URL_SCHEME_RE.test(trimmed) || trimmed.startsWith('/')) {
11
+ return trimmed
12
+ }
13
+ return `/${trimmed}`
14
+ }
15
+
16
+ export function isAppDeepLinkTarget(target: string): boolean {
17
+ const trimmed = target.trim()
18
+ if (!trimmed) return false
19
+ if (trimmed.startsWith('/')) return true
20
+ if (!APP_URL_SCHEME_RE.test(trimmed)) return false
21
+ return !/^https?:\/\//i.test(trimmed)
22
+ }
23
+
24
+ export async function openAppUrl(bridge: InspectBridge, target: string): Promise<string> {
25
+ const normalized = normalizeAppUrlTarget(target)
26
+ const result: unknown = await bridge.send({
27
+ type: 'call',
28
+ path: 'SootSim.bridges.test.openDeepLink',
29
+ args: [normalized],
30
+ })
31
+ if (
32
+ result !== null &&
33
+ typeof result === 'object' &&
34
+ Reflect.get(result, 'ok') === false
35
+ ) {
36
+ const error = Reflect.get(result, 'error')
37
+ throw new Error(typeof error === 'string' ? error : 'deep-link dispatch failed')
38
+ }
39
+ return normalized
40
+ }