rnxsim 0.1.381 → 0.1.382

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 (138) hide show
  1. package/README.md +19 -6
  2. package/cli/app-fonts.ts +1 -1
  3. package/cli/bin.ts +118 -26
  4. package/cli/bridge-diagnostics.ts +1 -1
  5. package/cli/bridge-flow-runner.ts +9 -9
  6. package/cli/browser-evals.ts +3 -3
  7. package/cli/cli-update.ts +261 -0
  8. package/cli/cloud-client.ts +407 -0
  9. package/cli/cloud-dispatch.ts +165 -0
  10. package/cli/cloud-session.ts +156 -0
  11. package/cli/command-contract.ts +2 -2
  12. package/cli/command-registry.ts +9 -0
  13. package/cli/commands/agent-wrapper.ts +4 -4
  14. package/cli/commands/agent.ts +3 -3
  15. package/cli/commands/box/checkout-plane.ts +16 -8
  16. package/cli/commands/box/rnx-command.ts +2 -2
  17. package/cli/commands/box/search-command.ts +2 -2
  18. package/cli/commands/box.ts +123 -70
  19. package/cli/commands/config.ts +3 -2
  20. package/cli/commands/control.ts +6 -6
  21. package/cli/commands/cpu-profile.ts +2 -2
  22. package/cli/commands/daemon.ts +7 -7
  23. package/cli/commands/debug.ts +2 -2
  24. package/cli/commands/detox.ts +7 -7
  25. package/cli/commands/diagnose.ts +1 -1
  26. package/cli/commands/electron.ts +1 -1
  27. package/cli/commands/film.ts +1 -1
  28. package/cli/commands/flow.ts +4 -4
  29. package/cli/commands/inspect/core.ts +58 -7
  30. package/cli/commands/inspect/env.ts +5 -3
  31. package/cli/commands/inspect/shared.ts +2 -1
  32. package/cli/commands/inspect/wait-event.ts +1 -1
  33. package/cli/commands/inspect/wait-ready.ts +15 -5
  34. package/cli/commands/inspect.ts +31 -9
  35. package/cli/commands/install-desktop.ts +2 -2
  36. package/cli/commands/maestro.ts +3 -3
  37. package/cli/commands/permissions.ts +1 -1
  38. package/cli/commands/platform.ts +91 -0
  39. package/cli/commands/record.ts +3 -3
  40. package/cli/commands/report-issue.ts +1 -1
  41. package/cli/commands/runtime.ts +1 -1
  42. package/cli/commands/screenshot-mode.ts +1 -1
  43. package/cli/commands/screenshot.ts +25 -0
  44. package/cli/commands/serve.ts +1 -1
  45. package/cli/commands/skills.ts +1 -1
  46. package/cli/commands/timeline.ts +1 -1
  47. package/cli/commands/upgrade.ts +8 -34
  48. package/cli/commands/upload.ts +3 -3
  49. package/cli/commands/version.ts +14 -3
  50. package/cli/commands/what-happened.ts +2 -2
  51. package/cli/current-sim.ts +43 -30
  52. package/cli/desktop-companion.ts +1 -1
  53. package/cli/drivers/electron.ts +1 -1
  54. package/cli/drivers/playwright.ts +3 -3
  55. package/cli/drivers/types.ts +4 -4
  56. package/cli/flow-file.ts +3 -3
  57. package/cli/help-core.ts +18 -11
  58. package/cli/hidden-runtime-alias.ts +1 -1
  59. package/cli/hints.ts +2 -2
  60. package/cli/maestro-js.ts +2 -2
  61. package/cli/outbound-endpoints.ts +40 -6
  62. package/cli/parse-args.ts +1 -1
  63. package/cli/registry.ts +1 -1
  64. package/cli/resolve-assets.ts +2 -2
  65. package/cli/secure-file.ts +31 -0
  66. package/cli/shell-init.ts +98 -0
  67. package/cli/ws-bridge.ts +18 -8
  68. package/detox/expectations.ts +1 -1
  69. package/detox/gestures.ts +3 -3
  70. package/detox/index.ts +3 -3
  71. package/dist-lib/agent-daemon-client.cjs +1 -1
  72. package/dist-lib/agent-events.cjs +1 -1
  73. package/dist-lib/agent-identity.cjs +1 -1
  74. package/dist-lib/agent-sessions.cjs +1 -1
  75. package/dist-lib/attached-projects.cjs +1 -1
  76. package/dist-lib/auth/shared-session.cjs +1 -1
  77. package/dist-lib/backend-origin.cjs +1 -1
  78. package/dist-lib/beta.cjs +1 -1
  79. package/dist-lib/beta.mjs +1 -1
  80. package/dist-lib/bridge-constants.cjs +1 -1
  81. package/dist-lib/bridge-contract-input.cjs +15 -8
  82. package/dist-lib/bridge-contract-input.mjs +15 -8
  83. package/dist-lib/bridge-contract.cjs +1 -1
  84. package/dist-lib/bridge-contract.mjs +1 -1
  85. package/dist-lib/capture-contract.cjs +107 -0
  86. package/dist-lib/capture-contract.mjs +80 -0
  87. package/dist-lib/cli-constants.cjs +1 -1
  88. package/dist-lib/cloud-contract.cjs +32 -0
  89. package/dist-lib/cloud-contract.mjs +7 -0
  90. package/dist-lib/config.cjs +1 -1
  91. package/dist-lib/detox/index.cjs +4 -4
  92. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  93. package/dist-lib/home-paths.cjs +9 -1
  94. package/dist-lib/host/bridge-host.cjs +15 -10
  95. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  96. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  97. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  98. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  99. package/dist-lib/host/websocket-proxy.cjs +1 -1
  100. package/dist-lib/index.cjs +248 -73
  101. package/dist-lib/jump-to-source-babel.cjs +1 -1
  102. package/dist-lib/menu.cjs +1 -1
  103. package/dist-lib/menu.mjs +1 -1
  104. package/dist-lib/metro-production-bundle.cjs +1 -1
  105. package/dist-lib/metro-production-bundle.mjs +1 -1
  106. package/dist-lib/metro.cjs +1 -1
  107. package/dist-lib/profiles.cjs +1 -1
  108. package/dist-lib/public-brand.cjs +1 -1
  109. package/dist-lib/react-native-host-modules.cjs +1 -1
  110. package/dist-lib/react-native-host-modules.mjs +1 -1
  111. package/dist-lib/render-mode.cjs +1 -1
  112. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  113. package/dist-lib/sdk.cjs +44 -6
  114. package/dist-lib/sdk.mjs +44 -6
  115. package/dist-lib/skills.cjs +435 -155
  116. package/dist-lib/vite.cjs +1 -1
  117. package/package.json +20 -4
  118. package/scripts/dev-server-scanner.ts +3 -3
  119. package/skills/contrast/SKILL.md +1 -1
  120. package/skills/rnx-perf/SKILL.md +68 -52
  121. package/src/app-url.ts +2 -3
  122. package/src/bridge-contract-input.ts +17 -6
  123. package/src/bridge-contract.ts +25 -4
  124. package/src/capture-contract.ts +423 -0
  125. package/src/cloud-contract.ts +15 -0
  126. package/src/home-paths.ts +9 -3
  127. package/src/host/agent-host.ts +1 -1
  128. package/src/host/bridge-host.ts +13 -11
  129. package/src/host/plane-host.ts +2 -2
  130. package/src/index.ts +21 -0
  131. package/src/native-dev-bundle-url.ts +2 -2
  132. package/src/screenshots/orchestrate.ts +1 -1
  133. package/src/screenshots/org-deck.ts +1 -1
  134. package/src/settings-bundle.ts +1 -1
  135. package/src/sim-client.ts +4 -0
  136. package/src/vite-plugin-one.ts +2 -2
  137. package/src/vite-plugin.ts +1 -1
  138. package/cli/commands/box/cloud-box.ts +0 -294
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (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;
@@ -8,8 +8,8 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
8
8
  var __getProtoOf = Object.getPrototypeOf;
9
9
  var __hasOwnProp = Object.prototype.hasOwnProperty;
10
10
  var __export = (target, all) => {
11
- for (var name in all)
12
- __defProp(target, name, { get: all[name], enumerable: true });
11
+ for (var name2 in all)
12
+ __defProp(target, name2, { get: all[name2], enumerable: true });
13
13
  };
14
14
  var __copyProps = (to, from, except, desc) => {
15
15
  if (from && typeof from === "object" || typeof from === "function") {
@@ -35,6 +35,7 @@ __export(src_exports, {
35
35
  DEFAULT_SOOTSIM_BRIDGE_PORT: () => DEFAULT_SOOTSIM_BRIDGE_PORT,
36
36
  DEFAULT_SOOTSIM_BRIDGE_URL: () => DEFAULT_SOOTSIM_BRIDGE_URL,
37
37
  DEFAULT_SOOTSIM_SHELL_URL: () => DEFAULT_SOOTSIM_SHELL_URL,
38
+ RNX_SCREEN_CAPTURE_VERSION: () => RNX_SCREEN_CAPTURE_VERSION,
38
39
  SimClient: () => SimClient,
39
40
  SimClientError: () => SimClientError,
40
41
  SimConnectError: () => SimConnectError,
@@ -44,6 +45,8 @@ __export(src_exports, {
44
45
  SimResetError: () => SimResetError,
45
46
  SimTapError: () => SimTapError,
46
47
  connect: () => connect,
48
+ isRnxCaptureRegionAtlas: () => isRnxCaptureRegionAtlas,
49
+ isRnxScreenCapture: () => isRnxScreenCapture,
47
50
  jumpToSourceBabelPlugin: () => sootsimJumpToSourceBabelPlugin,
48
51
  metroPlugin: () => metro_plugin_default,
49
52
  rnxPlugin: () => rnxPlugin
@@ -208,8 +211,32 @@ function tryBuildDarwinCommFfi() {
208
211
  }
209
212
  }
210
213
 
214
+ // cli/secure-file.ts
215
+ var import_node_crypto = require("node:crypto");
216
+ var import_node_fs = require("node:fs");
217
+ var import_node_path = require("node:path");
218
+ function writeSecureJsonAtomic(filepath, value) {
219
+ (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(filepath), { recursive: true });
220
+ const temporary = `${filepath}.tmp-${process.pid}-${(0, import_node_crypto.randomUUID)()}`;
221
+ let descriptor = null;
222
+ try {
223
+ descriptor = (0, import_node_fs.openSync)(temporary, "wx", 384);
224
+ (0, import_node_fs.fchmodSync)(descriptor, 384);
225
+ (0, import_node_fs.writeFileSync)(descriptor, `${JSON.stringify(value, null, 2)}
226
+ `);
227
+ (0, import_node_fs.fsyncSync)(descriptor);
228
+ (0, import_node_fs.closeSync)(descriptor);
229
+ descriptor = null;
230
+ (0, import_node_fs.renameSync)(temporary, filepath);
231
+ } catch (error) {
232
+ if (descriptor !== null) (0, import_node_fs.closeSync)(descriptor);
233
+ (0, import_node_fs.rmSync)(temporary, { force: true });
234
+ throw error;
235
+ }
236
+ }
237
+
211
238
  // cli/current-sim.ts
212
- var CURRENT_SIM_VERSION = 1;
239
+ var CURRENT_SIM_VERSION = 2;
213
240
  var CURRENT_SIM_PATH_ENV = "SOOTSIM_CLI_CURRENT_SIM_PATH";
214
241
  var IDENTITY_ENV_VARS = [
215
242
  "RNX_CLI_IDENTITY",
@@ -260,10 +287,10 @@ function findTopAncestor(start, maxDepth = 20) {
260
287
  return pid;
261
288
  }
262
289
  function getCliIdentity() {
263
- for (const name of IDENTITY_ENV_VARS) {
264
- const value = process.env[name];
290
+ for (const name2 of IDENTITY_ENV_VARS) {
291
+ const value = process.env[name2];
265
292
  if (value && value.trim()) {
266
- return { key: `${name}:${value.trim()}`, source: name, stable: true };
293
+ return { key: `${name2}:${value.trim()}`, source: name2, stable: true };
267
294
  }
268
295
  }
269
296
  const topPid = findTopAncestor(process.ppid);
@@ -282,35 +309,50 @@ function getCurrentSimPath() {
282
309
  const key = getCliIdentityKey();
283
310
  return (0, import_path.join)((0, import_os.tmpdir)(), `rnx-current-sim-${key}.json`);
284
311
  }
285
- function readCurrentSim() {
312
+ function legacyCloudCredentialDirectory(filepath) {
313
+ return (0, import_path.join)((0, import_path.dirname)(filepath), `${(0, import_path.basename)(filepath)}.credentials`);
314
+ }
315
+ function readCurrentTarget() {
286
316
  const filepath = getCurrentSimPath();
317
+ (0, import_fs2.rmSync)(legacyCloudCredentialDirectory(filepath), { recursive: true, force: true });
287
318
  if (!(0, import_fs2.existsSync)(filepath)) return null;
288
319
  try {
289
320
  const parsed = JSON.parse((0, import_fs2.readFileSync)(filepath, "utf8"));
290
- if (parsed.version !== CURRENT_SIM_VERSION || typeof parsed.simId !== "string" || !parsed.simId.trim() || typeof parsed.updatedAt !== "string") {
321
+ if (parsed === null || typeof parsed !== "object") {
291
322
  (0, import_fs2.rmSync)(filepath, { force: true });
292
323
  return null;
293
324
  }
294
- return {
325
+ const version = Reflect.get(parsed, "version");
326
+ const plane = Reflect.get(parsed, "plane");
327
+ const simId = Reflect.get(parsed, "simId");
328
+ const updatedAt = Reflect.get(parsed, "updatedAt");
329
+ if (version !== 1 && version !== CURRENT_SIM_VERSION || version === CURRENT_SIM_VERSION && plane !== "local" || typeof simId !== "string" || !simId.trim() || typeof updatedAt !== "string") {
330
+ (0, import_fs2.rmSync)(filepath, { force: true });
331
+ return null;
332
+ }
333
+ const target = {
295
334
  version: CURRENT_SIM_VERSION,
296
- simId: parsed.simId.trim(),
297
- updatedAt: parsed.updatedAt
335
+ plane: "local",
336
+ simId: simId.trim(),
337
+ updatedAt
298
338
  };
339
+ if (version === 1) writeSecureJsonAtomic(filepath, target);
340
+ return target;
299
341
  } catch {
300
342
  (0, import_fs2.rmSync)(filepath, { force: true });
301
343
  return null;
302
344
  }
303
345
  }
304
346
  function readCurrentSimId() {
305
- return readCurrentSim()?.simId || null;
347
+ return readCurrentTarget()?.simId ?? null;
306
348
  }
307
349
  function clearCurrentSimId() {
308
350
  (0, import_fs2.rmSync)(getCurrentSimPath(), { force: true });
309
351
  }
310
352
 
311
353
  // cli/ws-bridge.ts
312
- var import_node_fs2 = __toESM(require("node:fs"), 1);
313
- var import_node_path2 = __toESM(require("node:path"), 1);
354
+ var import_node_fs3 = __toESM(require("node:fs"), 1);
355
+ var import_node_path3 = __toESM(require("node:path"), 1);
314
356
  var import_ws = require("ws");
315
357
 
316
358
  // src/bridge-constants.ts
@@ -340,9 +382,9 @@ function resolveSootsimBridgePort(input = {}) {
340
382
  var DEFAULT_SOOTSIM_SHELL_URL = "http://localhost:5173/";
341
383
 
342
384
  // src/home-paths.ts
343
- var import_node_fs = __toESM(require("node:fs"), 1);
385
+ var import_node_fs2 = __toESM(require("node:fs"), 1);
344
386
  var import_node_os = require("node:os");
345
- var import_node_path = __toESM(require("node:path"), 1);
387
+ var import_node_path2 = __toESM(require("node:path"), 1);
346
388
  var RNX_HOME_ENV = "RNX_HOME";
347
389
  var ACTIVE_RUNTIME_FILE = "active";
348
390
  var DAEMON_LOCKFILE = "daemon.json";
@@ -350,27 +392,27 @@ var DEV_BRIDGES_DIR = "dev-bridges";
350
392
  var DAEMON_HEARTBEAT_STALE_MS = 3e4;
351
393
  function rnxHomeDir() {
352
394
  const override = process.env[RNX_HOME_ENV];
353
- if (override && override.length > 0) return import_node_path.default.resolve(override);
354
- return import_node_path.default.join((0, import_node_os.homedir)(), ".rnx");
395
+ if (override && override.length > 0) return import_node_path2.default.resolve(override);
396
+ return import_node_path2.default.join((0, import_node_os.homedir)(), ".rnx");
355
397
  }
356
398
  function runtimesDir() {
357
- return import_node_path.default.join(rnxHomeDir(), "runtimes");
399
+ return import_node_path2.default.join(rnxHomeDir(), "runtimes");
358
400
  }
359
401
  function runtimeDir(version) {
360
- return import_node_path.default.join(runtimesDir(), version);
402
+ return import_node_path2.default.join(runtimesDir(), version);
361
403
  }
362
404
  function activeRuntimeFile() {
363
- return import_node_path.default.join(runtimesDir(), ACTIVE_RUNTIME_FILE);
405
+ return import_node_path2.default.join(runtimesDir(), ACTIVE_RUNTIME_FILE);
364
406
  }
365
407
  function daemonLockfilePath() {
366
- return import_node_path.default.join(rnxHomeDir(), DAEMON_LOCKFILE);
408
+ return import_node_path2.default.join(rnxHomeDir(), DAEMON_LOCKFILE);
367
409
  }
368
410
  function devBridgesDir() {
369
- return import_node_path.default.join(rnxHomeDir(), DEV_BRIDGES_DIR);
411
+ return import_node_path2.default.join(rnxHomeDir(), DEV_BRIDGES_DIR);
370
412
  }
371
413
  function readActiveRuntime() {
372
414
  try {
373
- const value = import_node_fs.default.readFileSync(activeRuntimeFile(), "utf8").trim();
415
+ const value = import_node_fs2.default.readFileSync(activeRuntimeFile(), "utf8").trim();
374
416
  return value.length > 0 ? value : null;
375
417
  } catch {
376
418
  return null;
@@ -379,10 +421,10 @@ function readActiveRuntime() {
379
421
  var DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
380
422
  function readDaemonLockfile() {
381
423
  try {
382
- const fd = import_node_fs.default.openSync(daemonLockfilePath(), "r");
424
+ const fd = import_node_fs2.default.openSync(daemonLockfilePath(), "r");
383
425
  try {
384
426
  const buf = Buffer.alloc(DAEMON_LOCKFILE_MAX_BYTES);
385
- const bytesRead = import_node_fs.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
427
+ const bytesRead = import_node_fs2.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
386
428
  const raw = buf.subarray(0, bytesRead).toString("utf8");
387
429
  const parsed = JSON.parse(raw);
388
430
  if (parsed && parsed.schema === 1 && typeof parsed.pid === "number" && typeof parsed.bridgePort === "number" && typeof parsed.runtimePort === "number" && typeof parsed.startedAt === "number" && typeof parsed.heartbeatAt === "number" && (parsed.servedRuntimes === void 0 || Array.isArray(parsed.servedRuntimes) && parsed.servedRuntimes.every((version) => typeof version === "string"))) {
@@ -390,7 +432,7 @@ function readDaemonLockfile() {
390
432
  }
391
433
  return null;
392
434
  } finally {
393
- import_node_fs.default.closeSync(fd);
435
+ import_node_fs2.default.closeSync(fd);
394
436
  }
395
437
  } catch {
396
438
  return null;
@@ -410,7 +452,7 @@ function parseDevBridgeLockfile(raw) {
410
452
  function readDevBridgeLockfiles() {
411
453
  let entries;
412
454
  try {
413
- entries = import_node_fs.default.readdirSync(devBridgesDir(), { withFileTypes: true });
455
+ entries = import_node_fs2.default.readdirSync(devBridgesDir(), { withFileTypes: true });
414
456
  } catch {
415
457
  return [];
416
458
  }
@@ -418,11 +460,11 @@ function readDevBridgeLockfiles() {
418
460
  for (const entry of entries) {
419
461
  if (!entry.isFile() || !/^\d+\.json$/.test(entry.name)) continue;
420
462
  try {
421
- const filePath = import_node_path.default.join(devBridgesDir(), entry.name);
422
- const fd = import_node_fs.default.openSync(filePath, "r");
463
+ const filePath = import_node_path2.default.join(devBridgesDir(), entry.name);
464
+ const fd = import_node_fs2.default.openSync(filePath, "r");
423
465
  try {
424
466
  const buf = Buffer.alloc(DAEMON_LOCKFILE_MAX_BYTES);
425
- const bytesRead = import_node_fs.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
467
+ const bytesRead = import_node_fs2.default.readSync(fd, buf, 0, DAEMON_LOCKFILE_MAX_BYTES, 0);
426
468
  const lockfile = parseDevBridgeLockfile(
427
469
  buf.subarray(0, bytesRead).toString("utf8")
428
470
  );
@@ -430,7 +472,7 @@ function readDevBridgeLockfiles() {
430
472
  lockfiles.push(lockfile);
431
473
  }
432
474
  } finally {
433
- import_node_fs.default.closeSync(fd);
475
+ import_node_fs2.default.closeSync(fd);
434
476
  }
435
477
  } catch {
436
478
  }
@@ -458,6 +500,37 @@ function isDevBridgeLockfileFresh(lock, now = Date.now()) {
458
500
  }
459
501
  }
460
502
 
503
+ // src/cloud-contract.ts
504
+ var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
505
+
506
+ // src/public-brand.ts
507
+ var name = "rnx";
508
+ var rnxPublicBrand = Object.freeze({
509
+ name,
510
+ packageName: "rnxsim",
511
+ commandName: "rnx",
512
+ domain: "rnxsim.com",
513
+ origin: "https://rnxsim.com"
514
+ });
515
+
516
+ // src/backend-origin.ts
517
+ function normalizeHostname(hostname) {
518
+ return hostname.replace(/^\[|\]$/g, "").toLowerCase();
519
+ }
520
+ function isLoopbackHost(hostname) {
521
+ const normalized = normalizeHostname(hostname);
522
+ return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "0.0.0.0" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized);
523
+ }
524
+
525
+ // cli/cloud-session.ts
526
+ var MAX_ENCODED_SESSION_BYTES = 32 * 1024;
527
+ var RNX_SHELL_UPDATE_PREFIX = "__RNX_SHELL_UPDATE_V1__";
528
+ var RNX_SHELL_UPDATE_SET_PREFIX = `${RNX_SHELL_UPDATE_PREFIX}set:`;
529
+ var RNX_SHELL_UPDATE_UNSET = `${RNX_SHELL_UPDATE_PREFIX}unset`;
530
+
531
+ // cli/cloud-client.ts
532
+ var DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
533
+
461
534
  // cli/ws-bridge.ts
462
535
  function bridgeWsUrl(wsPort) {
463
536
  return `ws://localhost:${wsPort}`;
@@ -467,17 +540,17 @@ function liveDevBridgeLockfiles() {
467
540
  return readDevBridgeLockfiles().filter((lockfile) => isDevBridgeLockfileFresh(lockfile));
468
541
  }
469
542
  function checkoutRoot(cwd) {
470
- let current = import_node_path2.default.resolve(cwd);
543
+ let current = import_node_path3.default.resolve(cwd);
471
544
  while (true) {
472
- if (import_node_fs2.default.existsSync(import_node_path2.default.join(current, ".git"))) return current;
473
- const parent = import_node_path2.default.dirname(current);
545
+ if (import_node_fs3.default.existsSync(import_node_path3.default.join(current, ".git"))) return current;
546
+ const parent = import_node_path3.default.dirname(current);
474
547
  if (parent === current) return null;
475
548
  current = parent;
476
549
  }
477
550
  }
478
551
  function pathContains(parent, child) {
479
- const relative = import_node_path2.default.relative(parent, child);
480
- return relative === "" || relative !== ".." && !relative.startsWith(`..${import_node_path2.default.sep}`) && !import_node_path2.default.isAbsolute(relative);
552
+ const relative = import_node_path3.default.relative(parent, child);
553
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${import_node_path3.default.sep}`) && !import_node_path3.default.isAbsolute(relative);
481
554
  }
482
555
  function resolveDefaultDevBridgeLockfile() {
483
556
  const lockfiles = liveDevBridgeLockfiles();
@@ -638,6 +711,7 @@ function createBridge(wsPort, opts = {}) {
638
711
  }
639
712
  });
640
713
  return {
714
+ plane: "local",
641
715
  async send(cmd, callOpts) {
642
716
  const effectiveTimeoutMs = callOpts?.timeoutMs ?? commandTimeoutMs;
643
717
  const sendOnce = async (defaultSimId) => {
@@ -1917,6 +1991,39 @@ async function inspectWarnings(bridge, limit = 20) {
1917
1991
  return Array.isArray(result) ? result : [];
1918
1992
  }
1919
1993
  async function inspectLogs(bridge) {
1994
+ if (bridge.plane === "cloud") {
1995
+ const state = await bridge.send({
1996
+ type: "state",
1997
+ stateOptions: {
1998
+ screenshot: false,
1999
+ tree: false,
2000
+ route: false,
2001
+ errors: false,
2002
+ logs: true,
2003
+ logLimit: 100
2004
+ }
2005
+ });
2006
+ const recentLogs = state && typeof state === "object" && Array.isArray(Reflect.get(state, "recentLogs")) ? Reflect.get(state, "recentLogs") : [];
2007
+ return recentLogs.flatMap((entry, index) => {
2008
+ if (!entry || typeof entry !== "object") return [];
2009
+ const text = Reflect.get(entry, "text");
2010
+ const rawLevel = Reflect.get(entry, "level");
2011
+ if (typeof text !== "string") return [];
2012
+ const level = rawLevel === "log" || rawLevel === "info" || rawLevel === "warn" || rawLevel === "error" || rawLevel === "debug" ? rawLevel : "error";
2013
+ const at = Reflect.get(entry, "at");
2014
+ const ts = typeof at === "number" && Number.isFinite(at) ? at : 0;
2015
+ return [
2016
+ {
2017
+ id: `cloud-${ts}-${index}`,
2018
+ source: "rnx-cloud",
2019
+ level,
2020
+ ts,
2021
+ args: [text],
2022
+ stack: null
2023
+ }
2024
+ ];
2025
+ });
2026
+ }
1920
2027
  const res = await bridge.send({
1921
2028
  type: "evaluate",
1922
2029
  code: `(() => {
@@ -1951,7 +2058,7 @@ function filterLogEntries(entries, opts = {}) {
1951
2058
  if (!opts.showInternal) {
1952
2059
  out = out.filter((e) => {
1953
2060
  const first = e.args[0];
1954
- return !(typeof first === "string" && first.startsWith("[rnx]"));
2061
+ return !(typeof first === "string" && /^\[(?:rnx|sootsim)(?:\s[^\]]*)?\]/.test(first));
1955
2062
  });
1956
2063
  }
1957
2064
  if (opts.level) out = out.filter((e) => opts.level.has(e.level));
@@ -2037,9 +2144,8 @@ function normalizeAppUrlTarget(target) {
2037
2144
  async function openAppUrl(bridge, target) {
2038
2145
  const normalized = normalizeAppUrlTarget(target);
2039
2146
  const result = await bridge.send({
2040
- type: "call",
2041
- path: "SootSim.bridges.test.openDeepLink",
2042
- args: [normalized]
2147
+ type: "openUrl",
2148
+ url: normalized
2043
2149
  });
2044
2150
  if (result !== null && typeof result === "object" && Reflect.get(result, "ok") === false) {
2045
2151
  const error = Reflect.get(result, "error");
@@ -2212,6 +2318,9 @@ var SimClient = class {
2212
2318
  openUrl(target) {
2213
2319
  return openAppUrl(this, target);
2214
2320
  }
2321
+ async setAppearance(appearance) {
2322
+ await this.send({ type: "setAppearance", appearance });
2323
+ }
2215
2324
  /**
2216
2325
  * block until the guest app has mounted and painted real content.
2217
2326
  * throws SimReadyTimeoutError (with the last probe status) on timeout.
@@ -2535,17 +2644,91 @@ async function connect(options = {}) {
2535
2644
  return new SimClient(bridge, picked.id, { commandTimeoutMs });
2536
2645
  }
2537
2646
 
2647
+ // src/capture-contract.ts
2648
+ var RNX_SCREEN_CAPTURE_VERSION = 1;
2649
+ function captureRecord(value) {
2650
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2651
+ }
2652
+ function captureInteger(value) {
2653
+ return typeof value === "number" && Number.isSafeInteger(value);
2654
+ }
2655
+ function captureNumber(value) {
2656
+ return typeof value === "number" && Number.isFinite(value);
2657
+ }
2658
+ function captureNullableString(value) {
2659
+ return value === null || typeof value === "string";
2660
+ }
2661
+ function captureRect(value) {
2662
+ return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y) && captureNumber(value.width) && captureNumber(value.height);
2663
+ }
2664
+ function captureOptionalString(value) {
2665
+ return value === void 0 || typeof value === "string";
2666
+ }
2667
+ function captureOptionalNullableString(value) {
2668
+ return value === void 0 || captureNullableString(value);
2669
+ }
2670
+ function captureFontRegistration(value) {
2671
+ return captureRecord(value) && typeof value.family === "string" && value.family.length > 0 && captureOptionalString(value.url) && captureOptionalString(value.sourceLabel) && captureOptionalNullableString(value.parsedFamily) && captureOptionalNullableString(value.parsedPostScript) && captureOptionalNullableString(value.fullName);
2672
+ }
2673
+ function capturePoint(value) {
2674
+ return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y);
2675
+ }
2676
+ function captureNode(value) {
2677
+ if (!captureRecord(value) || !captureInteger(value.nodeId) || !(value.parentNodeId === null || captureInteger(value.parentNodeId)) || !Array.isArray(value.childNodeIds) || !value.childNodeIds.every(captureInteger) || !captureInteger(value.paintIndex) || typeof value.type !== "string" || !captureNullableString(value.id) || !captureNullableString(value.testID) || !captureNullableString(value.text) || !captureInteger(value.childCount) || !captureRecord(value.accessibility) || !captureRecord(value.interaction) || !captureRecord(value.layout) || !captureRecord(value.style) || !captureRecord(value.source) || !captureRecord(value.props) || !captureRecord(value.inspection)) {
2678
+ return false;
2679
+ }
2680
+ const accessibility = value.accessibility;
2681
+ if (typeof accessibility.accessible !== "boolean" || !captureNullableString(accessibility.label) || !captureNullableString(accessibility.role) || !captureNullableString(accessibility.hint) || !(accessibility.liveRegion === null || accessibility.liveRegion === "none" || accessibility.liveRegion === "polite" || accessibility.liveRegion === "assertive") || !(accessibility.state === null || captureRecord(accessibility.state)) || !(accessibility.value === null || captureRecord(accessibility.value))) {
2682
+ return false;
2683
+ }
2684
+ const interaction = value.interaction;
2685
+ if (typeof interaction.pressed !== "boolean" || typeof interaction.pressable !== "boolean" || typeof interaction.textInput !== "boolean" || !(interaction.textSelection === null || captureRecord(interaction.textSelection)) || typeof interaction.secureTextEntry !== "boolean" || !captureNullableString(interaction.placeholder) || !capturePoint(interaction.scrollOffset) || !(interaction.zoomScale === null || captureNumber(interaction.zoomScale)) || typeof interaction.nativePinchEnabled !== "boolean" || !(interaction.contentOffsetProp === null || captureRecord(interaction.contentOffsetProp)) || !(interaction.strokeDashoffsetProp === null || captureNumber(interaction.strokeDashoffsetProp))) {
2686
+ return false;
2687
+ }
2688
+ const layout = value.layout;
2689
+ if (!captureRect(layout.local) || !(layout.frame === null || captureRect(layout.frame)) || !capturePoint(layout.absolutePosition) || !(layout.visibleFrame === null || captureRect(layout.visibleFrame))) {
2690
+ return false;
2691
+ }
2692
+ const style = value.style;
2693
+ return captureRecord(style.resolved) && captureRecord(style.authored) && captureRecord(style.computed) && captureRecord(style.tokenBindings) && (value.textLines === void 0 || Array.isArray(value.textLines));
2694
+ }
2695
+ function isRnxScreenCapture(value) {
2696
+ if (!captureRecord(value) || value.contractVersion !== RNX_SCREEN_CAPTURE_VERSION || !captureInteger(value.capturedAt) || !captureRecord(value.tree) || !(value.fonts === void 0 || Array.isArray(value.fonts) && value.fonts.length <= 200 && value.fonts.every(captureFontRegistration)) || !(value.visual === void 0 || captureRecord(value.visual))) {
2697
+ return false;
2698
+ }
2699
+ const tree = value.tree;
2700
+ const visual = value.visual;
2701
+ return captureRecord(tree.viewport) && captureInteger(tree.viewport.width) && tree.viewport.width > 0 && captureInteger(tree.viewport.height) && tree.viewport.height > 0 && captureInteger(tree.rootNodeId) && Array.isArray(tree.nodes) && tree.nodes.every(captureNode) && (visual === void 0 || visual.kind === "png" && (visual.producer === "headless-cpu-app-surface" || visual.producer === "browser-compositor-app-surface") && typeof visual.dataUri === "string" && visual.dataUri.startsWith("data:image/png;base64,") && captureInteger(visual.pixelWidth) && visual.pixelWidth > 0 && captureInteger(visual.pixelHeight) && visual.pixelHeight > 0);
2702
+ }
2703
+ function isRnxCaptureRegionAtlas(value) {
2704
+ if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
2705
+ return false;
2706
+ }
2707
+ const scale = value.pixelWidth / value.width;
2708
+ if (!Number.isInteger(scale) || scale < 1 || scale > 4 || Math.abs(value.height * scale - value.pixelHeight) > 1e-6) {
2709
+ return false;
2710
+ }
2711
+ const keys = /* @__PURE__ */ new Set();
2712
+ for (const region of value.regions) {
2713
+ if (!captureRecord(region) || typeof region.key !== "string" || region.key.length === 0 || keys.has(region.key) || !captureInteger(region.nodeId) || region.nodeId <= 0 || !captureRect(region.frame) || region.frame.width <= 0 || region.frame.height <= 0 || !captureRect(region.source) || region.source.x < 0 || region.source.y < 0 || region.source.width !== region.frame.width || region.source.height !== region.frame.height || region.source.x + region.source.width > value.width || region.source.y + region.source.height > value.height) {
2714
+ return false;
2715
+ }
2716
+ keys.add(region.key);
2717
+ }
2718
+ return true;
2719
+ }
2720
+
2538
2721
  // src/vite-plugin-one.ts
2539
2722
  var import_fs4 = __toESM(require("fs"), 1);
2540
- var import_node_crypto2 = require("node:crypto");
2723
+ var import_node_crypto3 = require("node:crypto");
2541
2724
  var import_path3 = __toESM(require("path"), 1);
2542
2725
 
2543
2726
  // src/dev-server-open.ts
2544
2727
  var import_node_child_process = require("node:child_process");
2545
- var import_node_crypto = require("node:crypto");
2546
- var import_node_fs3 = __toESM(require("node:fs"), 1);
2728
+ var import_node_crypto2 = require("node:crypto");
2729
+ var import_node_fs4 = __toESM(require("node:fs"), 1);
2547
2730
  var import_node_http = __toESM(require("node:http"), 1);
2548
- var import_node_path3 = __toESM(require("node:path"), 1);
2731
+ var import_node_path4 = __toESM(require("node:path"), 1);
2549
2732
  var import_node_url = require("node:url");
2550
2733
  var scheduledMetroOpens = /* @__PURE__ */ new Set();
2551
2734
  function resolveRnxDesktopAppName(open, projectRoot) {
@@ -2555,8 +2738,8 @@ function resolveRnxDesktopAppName(open, projectRoot) {
2555
2738
  if (!appName) throw new Error("rnx: open.appName must not be empty");
2556
2739
  return appName;
2557
2740
  }
2558
- const packageJsonPath = import_node_path3.default.join(projectRoot, "package.json");
2559
- const packageJson = JSON.parse(import_node_fs3.default.readFileSync(packageJsonPath, "utf8"));
2741
+ const packageJsonPath = import_node_path4.default.join(projectRoot, "package.json");
2742
+ const packageJson = JSON.parse(import_node_fs4.default.readFileSync(packageJsonPath, "utf8"));
2560
2743
  const packageName = packageJson && typeof packageJson === "object" ? Reflect.get(packageJson, "name") : void 0;
2561
2744
  if (typeof packageName !== "string" || !packageName.trim()) {
2562
2745
  throw new Error(`rnx: ${packageJsonPath} must declare a package name`);
@@ -2570,7 +2753,7 @@ function tagRnxBundleForPlugin(bundleUrl, replacementOrigin, replacementToken, p
2570
2753
  url.searchParams.set("rnxAppName", appName);
2571
2754
  url.searchParams.set(
2572
2755
  "rnxProjectId",
2573
- (0, import_node_crypto.createHash)("sha256").update(import_node_fs3.default.realpathSync(projectRoot)).digest("hex").slice(0, 32)
2756
+ (0, import_node_crypto2.createHash)("sha256").update(import_node_fs4.default.realpathSync(projectRoot)).digest("hex").slice(0, 32)
2574
2757
  );
2575
2758
  }
2576
2759
  url.searchParams.set("rnxReplacementOrigin", replacementOrigin);
@@ -2605,8 +2788,8 @@ function observeRnxDesktopLaunch(child, appName) {
2605
2788
  });
2606
2789
  }
2607
2790
  function launchRnxDesktop(bundleUrl, appName) {
2608
- const packageRoot = import_node_path3.default.resolve(import_node_path3.default.dirname((0, import_node_url.fileURLToPath)(__sootsim_import_meta_url)), "..");
2609
- const binPath = import_node_path3.default.join(packageRoot, "dist-cli", "bin.js");
2791
+ const packageRoot = import_node_path4.default.resolve(import_node_path4.default.dirname((0, import_node_url.fileURLToPath)(__sootsim_import_meta_url)), "..");
2792
+ const binPath = import_node_path4.default.join(packageRoot, "dist-cli", "bin.js");
2610
2793
  console.log(`[rnx] opening ${appName} in the desktop simulator`);
2611
2794
  const child = (0, import_node_child_process.spawn)(
2612
2795
  process.execPath,
@@ -2696,22 +2879,11 @@ function openRnxDesktopWhenMetroIsReady({
2696
2879
 
2697
2880
  // src/host/replacement-module-handler.ts
2698
2881
  var import_promises = __toESM(require("node:fs/promises"), 1);
2699
- var import_node_path4 = __toESM(require("node:path"), 1);
2882
+ var import_node_path5 = __toESM(require("node:path"), 1);
2700
2883
  var import_esbuild = require("esbuild");
2701
-
2702
- // src/backend-origin.ts
2703
- function normalizeHostname(hostname) {
2704
- return hostname.replace(/^\[|\]$/g, "").toLowerCase();
2705
- }
2706
- function isLoopbackHost(hostname) {
2707
- const normalized = normalizeHostname(hostname);
2708
- return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "0.0.0.0" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized);
2709
- }
2710
-
2711
- // src/host/replacement-module-handler.ts
2712
2884
  var REPLACEMENT_MODULE_ROUTE = "/__sootsim-replacement-module";
2713
2885
  function getReplacementLoader(filePath) {
2714
- const ext = import_node_path4.default.extname(filePath).toLowerCase();
2886
+ const ext = import_node_path5.default.extname(filePath).toLowerCase();
2715
2887
  switch (ext) {
2716
2888
  case ".js":
2717
2889
  return "js";
@@ -2793,7 +2965,7 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
2793
2965
  res.end("replacement files must be .js, .jsx, .ts, or .tsx");
2794
2966
  return true;
2795
2967
  }
2796
- if (!import_node_path4.default.isAbsolute(targetPath)) {
2968
+ if (!import_node_path5.default.isAbsolute(targetPath)) {
2797
2969
  res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
2798
2970
  res.end("replacement file path must be absolute");
2799
2971
  return true;
@@ -2801,10 +2973,10 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
2801
2973
  const runtimePackages = new Set(url.searchParams.getAll("runtimePackage"));
2802
2974
  let resolvedProjectRoot;
2803
2975
  if (options.projectRoot) {
2804
- const lexicalProjectRoot = import_node_path4.default.resolve(options.projectRoot);
2976
+ const lexicalProjectRoot = import_node_path5.default.resolve(options.projectRoot);
2805
2977
  resolvedProjectRoot = await import_promises.default.realpath(options.projectRoot);
2806
- const lexicalTarget = import_node_path4.default.relative(lexicalProjectRoot, targetPath);
2807
- if (lexicalTarget.startsWith("..") || import_node_path4.default.isAbsolute(lexicalTarget)) {
2978
+ const lexicalTarget = import_node_path5.default.relative(lexicalProjectRoot, targetPath);
2979
+ if (lexicalTarget.startsWith("..") || import_node_path5.default.isAbsolute(lexicalTarget)) {
2808
2980
  res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
2809
2981
  res.end("replacement file must be inside the project root");
2810
2982
  return true;
@@ -2820,8 +2992,8 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
2820
2992
  return true;
2821
2993
  }
2822
2994
  if (resolvedProjectRoot) {
2823
- const relativeTarget = import_node_path4.default.relative(resolvedProjectRoot, resolvedTargetPath);
2824
- if (relativeTarget.startsWith("..") || import_node_path4.default.isAbsolute(relativeTarget)) {
2995
+ const relativeTarget = import_node_path5.default.relative(resolvedProjectRoot, resolvedTargetPath);
2996
+ if (relativeTarget.startsWith("..") || import_node_path5.default.isAbsolute(relativeTarget)) {
2825
2997
  res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
2826
2998
  res.end("replacement file must be inside the project root");
2827
2999
  return true;
@@ -3062,7 +3234,7 @@ function rnxPlugin(options = {}) {
3062
3234
  if (options.enabled === false) return;
3063
3235
  const bundleUrl = options.bundleUrl || "/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false";
3064
3236
  const appName = resolveRnxDesktopAppName(options.open, server.config.root);
3065
- const replacementToken = (0, import_node_crypto2.randomUUID)();
3237
+ const replacementToken = (0, import_node_crypto3.randomUUID)();
3066
3238
  const configuredPort = server.config.server.port || 8081;
3067
3239
  const listeningPort = () => {
3068
3240
  const address = server.httpServer?.address();
@@ -3187,7 +3359,7 @@ function rnxPlugin(options = {}) {
3187
3359
  // src/metro-plugin.ts
3188
3360
  var import_fs5 = __toESM(require("fs"), 1);
3189
3361
  var import_module2 = require("module");
3190
- var import_node_crypto3 = require("node:crypto");
3362
+ var import_node_crypto4 = require("node:crypto");
3191
3363
  var import_path4 = __toESM(require("path"), 1);
3192
3364
 
3193
3365
  // src/metro-production-bundle.ts
@@ -3284,7 +3456,7 @@ function withRNX(config, options = {}) {
3284
3456
  const configuredBundleUrl = options.bundleUrl || "/index.bundle?platform=ios&dev=true&hot=true&minify=false";
3285
3457
  const cfgServer = config.server;
3286
3458
  const port = resolveMetroPort(cfgServer);
3287
- const metroServerId = (0, import_node_crypto3.randomUUID)();
3459
+ const metroServerId = (0, import_node_crypto4.randomUUID)();
3288
3460
  const bundleUrl = tagRnxBundleForPlugin(
3289
3461
  configuredBundleUrl,
3290
3462
  `http://localhost:${port}`,
@@ -3522,6 +3694,7 @@ function sootsimJumpToSourceBabelPlugin(api, options = {}) {
3522
3694
  DEFAULT_SOOTSIM_BRIDGE_PORT,
3523
3695
  DEFAULT_SOOTSIM_BRIDGE_URL,
3524
3696
  DEFAULT_SOOTSIM_SHELL_URL,
3697
+ RNX_SCREEN_CAPTURE_VERSION,
3525
3698
  SimClient,
3526
3699
  SimClientError,
3527
3700
  SimConnectError,
@@ -3531,6 +3704,8 @@ function sootsimJumpToSourceBabelPlugin(api, options = {}) {
3531
3704
  SimResetError,
3532
3705
  SimTapError,
3533
3706
  connect,
3707
+ isRnxCaptureRegionAtlas,
3708
+ isRnxScreenCapture,
3534
3709
  jumpToSourceBabelPlugin,
3535
3710
  metroPlugin,
3536
3711
  rnxPlugin
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (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;
package/dist-lib/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (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;
package/dist-lib/menu.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "rnx";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (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.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION = "rnxsim";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.382 | (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;