peachsim 0.1.527 → 0.1.570

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 (158) hide show
  1. package/README.md +26 -26
  2. package/cli/app-fonts.ts +1 -1
  3. package/cli/app-splash.ts +1 -1
  4. package/cli/bin.ts +1 -1
  5. package/cli/bridge-diagnostics.ts +1 -1
  6. package/cli/bridge-flow-runner.ts +57 -5
  7. package/cli/cloud-client.ts +273 -6
  8. package/cli/cloud-dispatch.ts +22 -2
  9. package/cli/cloud-session.ts +60 -4
  10. package/cli/cloud-test-tunnel.ts +354 -0
  11. package/cli/commands/box/bundle-plane.ts +2 -2
  12. package/cli/commands/box/checkout-plane.ts +1 -1
  13. package/cli/commands/box/rnx-command.ts +2 -2
  14. package/cli/commands/box/search-command.ts +2 -2
  15. package/cli/commands/box.ts +8 -8
  16. package/cli/commands/compat.ts +1 -1
  17. package/cli/commands/control.ts +22 -3
  18. package/cli/commands/detox.ts +1 -1
  19. package/cli/commands/device.ts +1 -1
  20. package/cli/commands/diagnose.ts +1 -1
  21. package/cli/commands/film.ts +1 -1
  22. package/cli/commands/flow.ts +60 -3
  23. package/cli/commands/inspect/actions.ts +1 -1
  24. package/cli/commands/inspect/core.ts +6 -7
  25. package/cli/commands/inspect/find.ts +2 -1
  26. package/cli/commands/inspect/resolve-target.ts +5 -3
  27. package/cli/commands/inspect/shared.ts +1 -1
  28. package/cli/commands/inspect/wait-event.ts +1 -1
  29. package/cli/commands/inspect/wait-selector.ts +15 -4
  30. package/cli/commands/inspect.ts +19 -14
  31. package/cli/commands/maestro.ts +464 -43
  32. package/cli/commands/permissions.ts +1 -1
  33. package/cli/commands/platform.ts +205 -8
  34. package/cli/commands/preview.ts +2 -2
  35. package/cli/commands/record.ts +2 -2
  36. package/cli/commands/report-issue.ts +2 -2
  37. package/cli/commands/screenshot-layers.ts +1 -1
  38. package/cli/commands/screenshot.ts +1 -1
  39. package/cli/commands/setup.ts +2 -2
  40. package/cli/commands/test.ts +440 -115
  41. package/cli/commands/three-mode.ts +1 -1
  42. package/cli/commands/upload.ts +5 -5
  43. package/cli/commands/what-happened.ts +1 -1
  44. package/cli/desktop-companion.ts +3 -3
  45. package/cli/drivers/playwright-sim-host.ts +2 -2
  46. package/cli/flow-file.ts +7 -0
  47. package/cli/flow-live-status.ts +65 -8
  48. package/cli/help-core.ts +3 -3
  49. package/cli/hidden-runtime-alias.ts +1 -1
  50. package/cli/maestro-report.ts +178 -0
  51. package/cli/main.ts +1 -1
  52. package/cli/outbound-endpoints.ts +185 -136
  53. package/cli/parse-args.ts +1 -1
  54. package/cli/registry.ts +1 -1
  55. package/cli/resolve-assets.ts +1 -1
  56. package/cli/run-registry.ts +8 -0
  57. package/cli/send-to-box.ts +4 -4
  58. package/cli/ws-bridge.ts +3 -5
  59. package/detox/expectations.ts +1 -1
  60. package/detox/gestures.ts +2 -2
  61. package/detox/index.ts +71 -29
  62. package/detox/jest-preset.cjs +3 -3
  63. package/detox/jest-setup-after-env.cjs +1 -1
  64. package/dist-lib/agent-daemon-client.cjs +2 -2
  65. package/dist-lib/agent-events.cjs +1 -1
  66. package/dist-lib/agent-identity.cjs +1 -1
  67. package/dist-lib/agent-sessions.cjs +2 -2
  68. package/dist-lib/attached-projects.cjs +2 -2
  69. package/dist-lib/auth/shared-session.cjs +1 -1
  70. package/dist-lib/backend-origin.cjs +1 -1
  71. package/dist-lib/beta.cjs +1 -1
  72. package/dist-lib/beta.mjs +1 -1
  73. package/dist-lib/bridge-constants.cjs +1 -1
  74. package/dist-lib/bridge-contract-input.cjs +1 -1
  75. package/dist-lib/bridge-contract-input.mjs +1 -1
  76. package/dist-lib/bridge-contract.cjs +1 -1
  77. package/dist-lib/bridge-contract.mjs +1 -1
  78. package/dist-lib/capture-contract.cjs +94 -3
  79. package/dist-lib/capture-contract.mjs +93 -3
  80. package/dist-lib/cli-constants.cjs +1 -1
  81. package/dist-lib/cloud-contract.cjs +1 -1
  82. package/dist-lib/cloud-contract.mjs +1 -1
  83. package/dist-lib/cloud.cjs +2 -2
  84. package/dist-lib/cloud.mjs +2 -2
  85. package/dist-lib/config.cjs +1 -1
  86. package/dist-lib/detox/index.cjs +106 -25
  87. package/dist-lib/detox/jest-preset.cjs +3 -3
  88. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  89. package/dist-lib/home-paths.cjs +1 -1
  90. package/dist-lib/host/bridge-host.cjs +137 -61
  91. package/dist-lib/host/fetch-proxy-handler.cjs +28 -2
  92. package/dist-lib/host/fetch-proxy-overrides.cjs +33 -3
  93. package/dist-lib/host/fetch-proxy-overrides.mjs +30 -2
  94. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  95. package/dist-lib/host/websocket-proxy.cjs +1 -1
  96. package/dist-lib/index.cjs +209 -16
  97. package/dist-lib/jump-to-source-babel.cjs +1 -1
  98. package/dist-lib/jump-to-source-native.cjs +1 -1
  99. package/dist-lib/menu.cjs +2 -2
  100. package/dist-lib/menu.mjs +2 -2
  101. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  102. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  103. package/dist-lib/metro-production-bundle.cjs +3 -3
  104. package/dist-lib/metro-production-bundle.mjs +3 -3
  105. package/dist-lib/metro.cjs +8 -8
  106. package/dist-lib/profiles.cjs +1 -1
  107. package/dist-lib/public-brand.cjs +2 -2
  108. package/dist-lib/react-native-host-modules.cjs +1 -1
  109. package/dist-lib/react-native-host-modules.mjs +1 -1
  110. package/dist-lib/render-mode.cjs +1 -1
  111. package/dist-lib/scripts/dev-server-scanner.cjs +31 -15
  112. package/dist-lib/sdk.cjs +3 -2
  113. package/dist-lib/sdk.mjs +3 -2
  114. package/dist-lib/skills.cjs +362 -163
  115. package/dist-lib/swift-submit.cjs +1 -1
  116. package/dist-lib/swift-submit.mjs +1 -1
  117. package/dist-lib/swift.cjs +583 -16
  118. package/dist-lib/vite.cjs +29 -14
  119. package/package.json +9 -9
  120. package/scripts/dev-server-scanner.ts +41 -14
  121. package/scripts/optional-demo-registry.ts +3 -3
  122. package/skills/contrast/SKILL.md +9 -9
  123. package/skills/rnx-debug/SKILL.md +14 -4
  124. package/skills/rnx-perf/SKILL.md +5 -5
  125. package/skills/rnx-setup/SKILL.md +11 -11
  126. package/skills/rnx-test/SKILL.md +11 -11
  127. package/skills/rnx-visual/SKILL.md +6 -6
  128. package/src/agent-sessions.ts +3 -3
  129. package/src/attached-projects.ts +1 -1
  130. package/src/bridge-contract-input.ts +1 -1
  131. package/src/bridge-contract.ts +23 -5
  132. package/src/capture-contract.ts +145 -3
  133. package/src/config.ts +2 -2
  134. package/src/connect.ts +2 -2
  135. package/src/home-paths.ts +3 -3
  136. package/src/host/bridge-host.ts +2 -2
  137. package/src/host/fetch-proxy-handler.ts +4 -3
  138. package/src/host/fetch-proxy-overrides.ts +41 -0
  139. package/src/host/plane-host.ts +2 -2
  140. package/src/index.ts +3 -0
  141. package/src/metro-plugin.ts +4 -4
  142. package/src/metro-production-bundle.ts +2 -2
  143. package/src/native-seam-manifest.ts +6 -6
  144. package/src/public-brand.ts +1 -1
  145. package/src/rolldown-plugin-swift.ts +8 -5
  146. package/src/runtime-assets.ts +8 -6
  147. package/src/screenshots/frame-compose.ts +24 -56
  148. package/src/screenshots/org-deck.ts +1 -1
  149. package/src/screenshots/registry.ts +4 -4
  150. package/src/screenshots/schema.ts +1 -1
  151. package/src/sdk.ts +2 -2
  152. package/src/settings-bundle.ts +1 -1
  153. package/src/sim-client.ts +2 -4
  154. package/src/skills/builtin/compat-check.ts +1 -1
  155. package/src/vite-plugin-one.ts +1 -1
  156. package/src/vite-plugin-swift.ts +11 -6
  157. package/src/vite-plugin.ts +30 -17
  158. package/src/worklets-babel.ts +2 -2
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.527 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.570 | (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;
@@ -114,7 +114,7 @@ var init_optional_demo_registry = __esm({
114
114
  import_node_fs = require("node:fs");
115
115
  import_node_path2 = require("node:path");
116
116
  import_node_url = require("node:url");
117
- REGISTRY_REPO_PATH = "packages/sootsim/scripts/demo-app-registry.ts";
117
+ REGISTRY_REPO_PATH = "packages/peachsim/scripts/demo-app-registry.ts";
118
118
  MAX_ANCESTOR_STEPS = 8;
119
119
  cached = null;
120
120
  }
@@ -128,7 +128,7 @@ var init_public_brand = __esm({
128
128
  name = "rnx";
129
129
  rnxPublicBrand = Object.freeze({
130
130
  name,
131
- packageName: "rnxsim",
131
+ packageName: "peachsim",
132
132
  commandName: "rnx",
133
133
  domain: "rnxsim.com",
134
134
  origin: "https://rnxsim.com"
@@ -721,7 +721,7 @@ var init_auth = __esm({
721
721
  }
722
722
  });
723
723
 
724
- // ../sootsim-engine/src/preview/storage-snapshot-contract.ts
724
+ // ../peach-engine/src/preview/storage-snapshot-contract.ts
725
725
  function isRecord3(value) {
726
726
  return !!value && typeof value === "object" && !Array.isArray(value);
727
727
  }
@@ -768,12 +768,12 @@ function isStorageSnapshot(value) {
768
768
  return isRecord3(value) && Array.isArray(value.entries) && value.entries.every(isStorageSnapshotEntry) && (value.secureStore == null || Array.isArray(value.secureStore) && value.secureStore.every(isSecureStoreSnapshotEntry)) && (value.indexedDB == null || Array.isArray(value.indexedDB) && value.indexedDB.every(isIndexedDBSnapshot)) && (value.route == null || isPreviewRouteSnapshot(value.route));
769
769
  }
770
770
  var init_storage_snapshot_contract = __esm({
771
- "../sootsim-engine/src/preview/storage-snapshot-contract.ts"() {
771
+ "../peach-engine/src/preview/storage-snapshot-contract.ts"() {
772
772
  "use strict";
773
773
  }
774
774
  });
775
775
 
776
- // ../sootsim-engine/src/tenant-runtime-environment.ts
776
+ // ../peach-engine/src/tenant-runtime-environment.ts
777
777
  function readBrowserLocation() {
778
778
  try {
779
779
  return typeof location === "undefined" ? null : location;
@@ -783,25 +783,25 @@ function readBrowserLocation() {
783
783
  }
784
784
  var nativeRuntimeLocation;
785
785
  var init_tenant_runtime_environment = __esm({
786
- "../sootsim-engine/src/tenant-runtime-environment.ts"() {
786
+ "../peach-engine/src/tenant-runtime-environment.ts"() {
787
787
  "use strict";
788
788
  nativeRuntimeLocation = readBrowserLocation();
789
789
  }
790
790
  });
791
791
 
792
- // ../sootsim-engine/src/development-mode.ts
792
+ // ../peach-engine/src/development-mode.ts
793
793
  var bridgeConstants, DEFAULT_SOOTSIM_BRIDGE_PORT2, DAEMON_RUNTIME_PORT_MAX;
794
794
  var init_development_mode = __esm({
795
- "../sootsim-engine/src/development-mode.ts"() {
795
+ "../peach-engine/src/development-mode.ts"() {
796
796
  "use strict";
797
- bridgeConstants = __toESM(require("rnxsim/bridge-constants"), 1);
797
+ bridgeConstants = __toESM(require("peachsim/bridge-constants"), 1);
798
798
  init_tenant_runtime_environment();
799
799
  ({ DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = bridgeConstants);
800
800
  DAEMON_RUNTIME_PORT_MAX = DEFAULT_SOOTSIM_BRIDGE_PORT2 + 10;
801
801
  }
802
802
  });
803
803
 
804
- // ../sootsim-engine/src/settings/devices.ts
804
+ // ../peach-engine/src/settings/devices.ts
805
805
  function modernButtons(action, volumeUp, volumeDown, power) {
806
806
  return {
807
807
  width: 3,
@@ -850,23 +850,27 @@ function getDevice(model, posture) {
850
850
  return {
851
851
  ...device,
852
852
  // inner display size from apple's ios 27 ui kit. corners and insets are
853
- // measured from apple's 2d inner product art: every display corner fits a
854
- // 53pt circle within 0.4px, and the silhouette sits 19.5pt outside the
855
- // display on every edge as 16pt of black glass plus a 3.5pt rail.
853
+ // measured from apple's 2d inner product art at 3x: every display corner
854
+ // fits a 53pt circle within 0.4px, the silhouette sits 20.67pt outside the
855
+ // display on every edge as 16.33pt of black glass plus a 4.33pt rail, and
856
+ // the body itself curves at 75pt. the barrel is hidden when open.
856
857
  width: 951,
857
858
  height: 669,
858
859
  statusBarHeight: 44,
859
860
  cornerRadius: cornerRadii(53),
860
861
  continuousCornerRadius: cornerRadii(53),
861
- frameInsets: uniformFrameInsets(19.5),
862
- housing: { rail: uniformFrameInsets(3.5), hingeBarrel: null },
862
+ frameInsets: uniformFrameInsets(20.6667),
863
+ frameCornerRadius: cornerRadii(75),
864
+ housing: { rail: uniformFrameInsets(4.3333), hingeBarrel: null },
863
865
  cameraCutout: null,
864
866
  physicalPPI: 430,
865
867
  posture: "open",
866
- // open inner display keeps horizontal bars in this slice; preserve the
867
- // previous trailing status lane so open layouts do not pick up the closed
868
- // 84pt Vertical Bar inset.
869
- safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 72 }
868
+ // open inner display in landscape carries the same trailing column as
869
+ // the closed outer display, so it takes the same 84pt inset: a ~50pt
870
+ // control at a ~23pt inset needs 73pt, and anything narrower would shift
871
+ // controls horizontally on unfold, defeating the continuous experience
872
+ // Apple states as the reason for the design.
873
+ safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 84 }
870
874
  };
871
875
  }
872
876
  function listDeviceModels() {
@@ -877,9 +881,9 @@ function getRuntimePlatform(model) {
877
881
  }
878
882
  var import_menu, LEGACY_HARDWARE_BUTTONS, PIXEL_HARDWARE_BUTTONS, GALAXY_HARDWARE_BUTTONS, ANDROID_GESTURE_NAV_BAR_HEIGHT, ANDROID_OS_VERSION, ANDROID_API_LEVEL, PIXEL_8_WIDTH, PIXEL_8_HEIGHT, PIXEL_8_STATUS_BAR_HEIGHT, devices, DEFAULT_DEVICE, DEFAULT_DEVICE_BY_PLATFORM;
879
883
  var init_devices = __esm({
880
- "../sootsim-engine/src/settings/devices.ts"() {
884
+ "../peach-engine/src/settings/devices.ts"() {
881
885
  "use strict";
882
- import_menu = require("rnxsim/menu");
886
+ import_menu = require("peachsim/menu");
883
887
  init_development_mode();
884
888
  LEGACY_HARDWARE_BUTTONS = {
885
889
  width: 2.5,
@@ -912,6 +916,7 @@ var init_devices = __esm({
912
916
  PIXEL_8_STATUS_BAR_HEIGHT = 132 / 2.625;
913
917
  devices = {
914
918
  "canvas-workspace": iosDevice({
919
+ model: "canvas-workspace",
915
920
  name: "Canvas Workspace",
916
921
  width: 1440,
917
922
  height: 900,
@@ -937,6 +942,7 @@ var init_devices = __esm({
937
942
  experimental: true
938
943
  }),
939
944
  "iphone-se": iosDevice({
945
+ model: "iphone-se",
940
946
  name: "iPhone SE",
941
947
  width: 375,
942
948
  height: 667,
@@ -957,6 +963,7 @@ var init_devices = __esm({
957
963
  hardwareButtons: LEGACY_HARDWARE_BUTTONS
958
964
  }),
959
965
  "iphone-14": iosDevice({
966
+ model: "iphone-14",
960
967
  name: "iPhone 14",
961
968
  width: 390,
962
969
  height: 844,
@@ -979,6 +986,7 @@ var init_devices = __esm({
979
986
  )
980
987
  }),
981
988
  "iphone-15": iosDevice({
989
+ model: "iphone-15",
982
990
  name: "iPhone 15",
983
991
  width: 393,
984
992
  height: 852,
@@ -1001,6 +1009,7 @@ var init_devices = __esm({
1001
1009
  )
1002
1010
  }),
1003
1011
  "iphone-15-plus": iosDevice({
1012
+ model: "iphone-15-plus",
1004
1013
  name: "iPhone 15 Plus",
1005
1014
  width: 430,
1006
1015
  height: 932,
@@ -1023,6 +1032,7 @@ var init_devices = __esm({
1023
1032
  )
1024
1033
  }),
1025
1034
  "iphone-15-pro": iosDevice({
1035
+ model: "iphone-15-pro",
1026
1036
  name: "iPhone 15 Pro",
1027
1037
  width: 393,
1028
1038
  height: 852,
@@ -1045,6 +1055,7 @@ var init_devices = __esm({
1045
1055
  )
1046
1056
  }),
1047
1057
  "iphone-15-pro-max": iosDevice({
1058
+ model: "iphone-15-pro-max",
1048
1059
  name: "iPhone 15 Pro Max",
1049
1060
  width: 430,
1050
1061
  height: 932,
@@ -1067,6 +1078,7 @@ var init_devices = __esm({
1067
1078
  )
1068
1079
  }),
1069
1080
  "iphone-16": iosDevice({
1081
+ model: "iphone-16",
1070
1082
  name: "iPhone 16",
1071
1083
  width: 393,
1072
1084
  height: 852,
@@ -1075,7 +1087,7 @@ var init_devices = __esm({
1075
1087
  homeIndicatorHeight: 34,
1076
1088
  // 2026-07-10: cornerRadius corrected 58 → 53.9 to Apple's own framebuffer
1077
1089
  // mask (extracted from the simdevicetype bundle PDF; see
1078
- // packages/sootsim-engine/assets/device-frame-geometry). radius is a paint clip only — the
1090
+ // packages/peach-engine/assets/device-frame-geometry). radius is a paint clip only — the
1079
1091
  // calibrated conformance-oracle layout fields below are unchanged.
1080
1092
  cornerRadius: cornerRadii(53.9),
1081
1093
  continuousCornerRadius: cornerRadii(73.402),
@@ -1095,6 +1107,7 @@ var init_devices = __esm({
1095
1107
  )
1096
1108
  }),
1097
1109
  "iphone-16-plus": iosDevice({
1110
+ model: "iphone-16-plus",
1098
1111
  name: "iPhone 16 Plus",
1099
1112
  width: 430,
1100
1113
  height: 932,
@@ -1117,6 +1130,7 @@ var init_devices = __esm({
1117
1130
  )
1118
1131
  }),
1119
1132
  "iphone-16-pro": iosDevice({
1133
+ model: "iphone-16-pro",
1120
1134
  name: "iPhone 16 Pro",
1121
1135
  width: 402,
1122
1136
  height: 874,
@@ -1141,6 +1155,7 @@ var init_devices = __esm({
1141
1155
  )
1142
1156
  }),
1143
1157
  "iphone-16-pro-max": iosDevice({
1158
+ model: "iphone-16-pro-max",
1144
1159
  name: "iPhone 16 Pro Max",
1145
1160
  width: 440,
1146
1161
  height: 956,
@@ -1166,6 +1181,7 @@ var init_devices = __esm({
1166
1181
  )
1167
1182
  }),
1168
1183
  "iphone-17": iosDevice({
1184
+ model: "iphone-17",
1169
1185
  name: "iPhone 17",
1170
1186
  width: 402,
1171
1187
  height: 874,
@@ -1189,6 +1205,7 @@ var init_devices = __esm({
1189
1205
  )
1190
1206
  }),
1191
1207
  "iphone-17-air": iosDevice({
1208
+ model: "iphone-17-air",
1192
1209
  // apple markets this as "iphone air" (not "iphone 17 air"). the real air
1193
1210
  // is 420x912 with thin bezels and a lower-sitting island. it is not the
1194
1211
  // 430x932 Plus body it used to be cloned from.
@@ -1229,6 +1246,7 @@ var init_devices = __esm({
1229
1246
  )
1230
1247
  }),
1231
1248
  "iphone-17-pro": iosDevice({
1249
+ model: "iphone-17-pro",
1232
1250
  name: "iPhone 17 Pro",
1233
1251
  width: 402,
1234
1252
  height: 874,
@@ -1256,6 +1274,7 @@ var init_devices = __esm({
1256
1274
  )
1257
1275
  }),
1258
1276
  "iphone-17-pro-max": iosDevice({
1277
+ model: "iphone-17-pro-max",
1259
1278
  name: "iPhone 17 Pro Max",
1260
1279
  width: 440,
1261
1280
  height: 956,
@@ -1285,6 +1304,7 @@ var init_devices = __esm({
1285
1304
  // measurements are still settling (nate, 2026-09-15).
1286
1305
  developmentOnly: true,
1287
1306
  ...iosDevice({
1307
+ model: "iphone-duo",
1288
1308
  name: "iPhone Duo",
1289
1309
  width: 466,
1290
1310
  height: 678,
@@ -1300,12 +1320,21 @@ var init_devices = __esm({
1300
1320
  bottomRight: 61,
1301
1321
  bottomLeft: 5
1302
1322
  },
1303
- // display edge to silhouette. left is black glass 8.6 + rail 5.4 + hinge
1304
- // barrel 14.1; right is black glass 8.7 + rail 7.7.
1305
- frameInsets: { top: 19, right: 16.4, bottom: 16.3, left: 28.1 },
1323
+ // display edge to silhouette, measured off apple's 2d outer product art
1324
+ // at 3x. the barrel is not part of the body: it protrudes 11.67pt past
1325
+ // the left silhouette, so the full outer width is frame + protrusion.
1326
+ frameInsets: { top: 16.3333, right: 16.3333, bottom: 16, left: 14 },
1327
+ // the spine is a flat cut, so its corners are tiny; the free side keeps
1328
+ // the 75pt body curve the pro bodies use.
1329
+ frameCornerRadius: {
1330
+ topLeft: 4.3333,
1331
+ topRight: 75,
1332
+ bottomRight: 75,
1333
+ bottomLeft: 3.3333
1334
+ },
1306
1335
  housing: {
1307
- rail: { top: 10.4, right: 7.7, bottom: 7.7, left: 19.5 },
1308
- hingeBarrel: { width: 14.1, endInset: 6.4 }
1336
+ rail: { top: 7.5, right: 8, bottom: 7.3333, left: 5.3333 },
1337
+ hingeBarrel: { width: 16.6667, endInset: 7.3333, protrusion: 11.6667 }
1309
1338
  },
1310
1339
  dynamicIsland: null,
1311
1340
  // 84pt trailing Vertical Bar on the outer display (Apple iOS 27 UI kit).
@@ -1325,6 +1354,7 @@ var init_devices = __esm({
1325
1354
  }
1326
1355
  },
1327
1356
  "pixel-8": {
1357
+ model: "pixel-8",
1328
1358
  platform: "android",
1329
1359
  name: "Pixel 8",
1330
1360
  width: PIXEL_8_WIDTH,
@@ -1373,6 +1403,7 @@ var init_devices = __esm({
1373
1403
  hardwareButtons: PIXEL_HARDWARE_BUTTONS
1374
1404
  },
1375
1405
  "pixel-8-three-button": {
1406
+ model: "pixel-8-three-button",
1376
1407
  platform: "android",
1377
1408
  name: "Pixel 8 (3-button)",
1378
1409
  width: PIXEL_8_WIDTH,
@@ -1418,6 +1449,7 @@ var init_devices = __esm({
1418
1449
  hardwareButtons: PIXEL_HARDWARE_BUTTONS
1419
1450
  },
1420
1451
  "pixel-9-pro-xl": {
1452
+ model: "pixel-9-pro-xl",
1421
1453
  platform: "android",
1422
1454
  name: "Pixel 9 Pro XL",
1423
1455
  width: 448,
@@ -1454,6 +1486,7 @@ var init_devices = __esm({
1454
1486
  hardwareButtons: PIXEL_HARDWARE_BUTTONS
1455
1487
  },
1456
1488
  "pixel-10": {
1489
+ model: "pixel-10",
1457
1490
  platform: "android",
1458
1491
  name: "Pixel 10",
1459
1492
  width: 360,
@@ -1491,6 +1524,7 @@ var init_devices = __esm({
1491
1524
  hardwareButtons: PIXEL_HARDWARE_BUTTONS
1492
1525
  },
1493
1526
  "galaxy-s24": {
1527
+ model: "galaxy-s24",
1494
1528
  platform: "android",
1495
1529
  name: "Galaxy S24",
1496
1530
  width: 360,
@@ -1528,6 +1562,7 @@ var init_devices = __esm({
1528
1562
  hardwareButtons: GALAXY_HARDWARE_BUTTONS
1529
1563
  },
1530
1564
  "galaxy-s24-ultra": {
1565
+ model: "galaxy-s24-ultra",
1531
1566
  platform: "android",
1532
1567
  name: "Galaxy S24 Ultra",
1533
1568
  width: 384,
@@ -1576,7 +1611,7 @@ var init_devices = __esm({
1576
1611
  // src/metro-production-bundle.ts
1577
1612
  function toRNXProductionBundleUrl(bundleUrl) {
1578
1613
  const relative2 = bundleUrl.startsWith("/");
1579
- const url = new URL(bundleUrl, "http://rnxsim.local");
1614
+ const url = new URL(bundleUrl, "http://peachsim.local");
1580
1615
  url.searchParams.set("dev", "false");
1581
1616
  url.searchParams.set("hot", "false");
1582
1617
  url.searchParams.set("minify", "true");
@@ -2571,7 +2606,7 @@ var import_metro_production_bundle, import_terser, MODULE_PATHS_REQUIRED, SOURCE
2571
2606
  var init_metroCloudArtifact = __esm({
2572
2607
  "../contrast-bundler/src/metroCloudArtifact.ts"() {
2573
2608
  "use strict";
2574
- import_metro_production_bundle = require("rnxsim/metro-production-bundle");
2609
+ import_metro_production_bundle = require("peachsim/metro-production-bundle");
2575
2610
  import_terser = require("terser");
2576
2611
  init_metroAssetArtifact();
2577
2612
  init_metroDebugSourceMap();
@@ -2586,7 +2621,7 @@ var init_metroCloudArtifact = __esm({
2586
2621
  }
2587
2622
  });
2588
2623
 
2589
- // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
2624
+ // ../peach-engine/src/metro-fingerprint-registry-client.ts
2590
2625
  function pointerUrl(options) {
2591
2626
  return options.pointerUrl ?? new URL(import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_POINTER_PATH, DEFAULT_REGISTRY_ORIGIN).toString();
2592
2627
  }
@@ -2751,19 +2786,19 @@ async function loadMetroFingerprintRegistry(options = {}) {
2751
2786
  }
2752
2787
  var import_metro_fingerprint_registry, REGISTRY_CACHE_NAME, DEFAULT_REGISTRY_ORIGIN, memoryReceipts;
2753
2788
  var init_metro_fingerprint_registry_client = __esm({
2754
- "../sootsim-engine/src/metro-fingerprint-registry-client.ts"() {
2789
+ "../peach-engine/src/metro-fingerprint-registry-client.ts"() {
2755
2790
  "use strict";
2756
- import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
2791
+ import_metro_fingerprint_registry = require("peachsim/metro-fingerprint-registry");
2757
2792
  REGISTRY_CACHE_NAME = "rnx-metro-fingerprints-v1";
2758
2793
  DEFAULT_REGISTRY_ORIGIN = "https://contrast.dev";
2759
2794
  memoryReceipts = /* @__PURE__ */ new Map();
2760
2795
  }
2761
2796
  });
2762
2797
 
2763
- // ../compat/src/stub-manifest.ts
2798
+ // ../peach-compat/src/stub-manifest.ts
2764
2799
  var COMPAT_REACT_NATIVE_DEEP_STUBS;
2765
2800
  var init_stub_manifest = __esm({
2766
- "../compat/src/stub-manifest.ts"() {
2801
+ "../peach-compat/src/stub-manifest.ts"() {
2767
2802
  "use strict";
2768
2803
  COMPAT_REACT_NATIVE_DEEP_STUBS = {
2769
2804
  usePressability: {
@@ -2921,17 +2956,17 @@ var init_stub_manifest = __esm({
2921
2956
  }
2922
2957
  });
2923
2958
 
2924
- // ../sootsim-engine/src/metro-asset-path.ts
2959
+ // ../peach-engine/src/metro-asset-path.ts
2925
2960
  function isMetroAssetRegistryModulePath(modulePath) {
2926
- return modulePath.includes("polyfill:assets-registry") || modulePath.includes("@react-native/assets-registry/registry") || modulePath.includes("assets-registry/registry") || modulePath.includes("react-native/src/asset-registry");
2961
+ return modulePath.includes("polyfill:assets-registry") || modulePath.includes("@react-native/assets-registry/registry") || modulePath.includes("assets-registry/registry") || modulePath.includes("react-native/asset-registry") || modulePath.includes("react-native/src/asset-registry");
2927
2962
  }
2928
2963
  var init_metro_asset_path = __esm({
2929
- "../sootsim-engine/src/metro-asset-path.ts"() {
2964
+ "../peach-engine/src/metro-asset-path.ts"() {
2930
2965
  "use strict";
2931
2966
  }
2932
2967
  });
2933
2968
 
2934
- // ../sootsim-engine/src/stub-pattern-matcher.ts
2969
+ // ../peach-engine/src/stub-pattern-matcher.ts
2935
2970
  function matchesModuleEntry(modulePath, pattern) {
2936
2971
  if (!modulePath || !pattern) return false;
2937
2972
  if (modulePath === pattern) return true;
@@ -2959,12 +2994,12 @@ function isReactNativeWorkletsGeneratedWorkletModule(modulePath) {
2959
2994
  return subpath?.startsWith(".worklets/") === true;
2960
2995
  }
2961
2996
  var init_stub_pattern_matcher = __esm({
2962
- "../sootsim-engine/src/stub-pattern-matcher.ts"() {
2997
+ "../peach-engine/src/stub-pattern-matcher.ts"() {
2963
2998
  "use strict";
2964
2999
  }
2965
3000
  });
2966
3001
 
2967
- // ../sootsim-engine/src/metro-fingerprint.ts
3002
+ // ../peach-engine/src/metro-fingerprint.ts
2968
3003
  function compareStrings(left, right) {
2969
3004
  return left < right ? -1 : left > right ? 1 : 0;
2970
3005
  }
@@ -3528,11 +3563,11 @@ async function inferMetroModuleIdentity(args) {
3528
3563
  }
3529
3564
  var import_metro_production_bundle2, import_react_native_host_modules, IDENTIFIER, MAX_CANDIDATE_EMBEDDINGS, MIN_DUPLICATE_ROOT_EXACT_FACTORIES, REQUIRED_INTERCEPT_PACKAGES;
3530
3565
  var init_metro_fingerprint = __esm({
3531
- "../sootsim-engine/src/metro-fingerprint.ts"() {
3566
+ "../peach-engine/src/metro-fingerprint.ts"() {
3532
3567
  "use strict";
3533
3568
  init_stub_manifest();
3534
- import_metro_production_bundle2 = require("rnxsim/metro-production-bundle");
3535
- import_react_native_host_modules = require("rnxsim/react-native-host-modules");
3569
+ import_metro_production_bundle2 = require("peachsim/metro-production-bundle");
3570
+ import_react_native_host_modules = require("peachsim/react-native-host-modules");
3536
3571
  init_metro_asset_path();
3537
3572
  init_stub_pattern_matcher();
3538
3573
  IDENTIFIER = "[A-Za-z_$][A-Za-z0-9_$]*";
@@ -5087,7 +5122,7 @@ async function resolveLocalIconPath(hostname, port, rawIcon) {
5087
5122
  const res = await httpGet(hostname, port, candidate, "HEAD", ENRICH_TIMEOUT_MS);
5088
5123
  if (res?.statusCode === 200) {
5089
5124
  localIconPathCache.set(port, candidate);
5090
- portCache.delete(port);
5125
+ invalidatePortCache(port);
5091
5126
  return;
5092
5127
  }
5093
5128
  }
@@ -5209,7 +5244,7 @@ async function fetchManifestEnrichment(result, buildIconProxyUrl) {
5209
5244
  iconPath: parsed.iconPath,
5210
5245
  bundleId: parsed.bundleId
5211
5246
  });
5212
- portCache.delete(result.port);
5247
+ invalidatePortCache(result.port);
5213
5248
  }
5214
5249
  var knownNonPatched = /* @__PURE__ */ new Set();
5215
5250
  var knownNonExpo = /* @__PURE__ */ new Set();
@@ -5249,16 +5284,19 @@ async function probePort(port, buildIconProxyUrl, listeningProcess) {
5249
5284
  const framework = launchUrl2.includes(
5250
5285
  "/one/metro-entry.bundle"
5251
5286
  ) ? "one" : "expo";
5252
- return applyManifest(
5253
- {
5254
- port,
5255
- framework,
5256
- bundleUrl: withRuntimeConfig(port, launchUrl2, owner.cwd),
5257
- hmrUrl: `${buildLoopbackProbeBaseUrl("ws:", probeHostname, port)}/hot`,
5258
- lastSeen: Date.now(),
5259
- ...owner
5260
- },
5261
- manifestRes,
5287
+ return enrichWithManifest(
5288
+ applyManifest(
5289
+ {
5290
+ port,
5291
+ framework,
5292
+ bundleUrl: withRuntimeConfig(port, launchUrl2, owner.cwd),
5293
+ hmrUrl: `${buildLoopbackProbeBaseUrl("ws:", probeHostname, port)}/hot`,
5294
+ lastSeen: Date.now(),
5295
+ ...owner
5296
+ },
5297
+ manifestRes,
5298
+ buildIconProxyUrl
5299
+ ),
5262
5300
  buildIconProxyUrl
5263
5301
  );
5264
5302
  }
@@ -5336,6 +5374,11 @@ function isSootSimSelfServer(server) {
5336
5374
  return false;
5337
5375
  }
5338
5376
  var portCache = /* @__PURE__ */ new Map();
5377
+ var portCacheInvalidatedAt = /* @__PURE__ */ new Map();
5378
+ function invalidatePortCache(port) {
5379
+ portCache.delete(port);
5380
+ portCacheInvalidatedAt.set(port, Date.now());
5381
+ }
5339
5382
  var NEGATIVE_CACHE_TTL_MS = 3e4;
5340
5383
  var WEAK_RESULT_CACHE_TTL_MS = 1500;
5341
5384
  function isWeakCachedResult(result) {
@@ -5390,6 +5433,9 @@ async function scanDevServers(opts = {}) {
5390
5433
  for (const p of [...localIconPathCache.keys()]) {
5391
5434
  if (!currentPorts.has(p)) localIconPathCache.delete(p);
5392
5435
  }
5436
+ for (const p of [...portCacheInvalidatedAt.keys()]) {
5437
+ if (!currentPorts.has(p)) portCacheInvalidatedAt.delete(p);
5438
+ }
5393
5439
  const results = [];
5394
5440
  const toProbe = [];
5395
5441
  for (const { port, pid } of processes) {
@@ -5408,12 +5454,16 @@ async function scanDevServers(opts = {}) {
5408
5454
  toProbe.push({ port, pid });
5409
5455
  }
5410
5456
  if (toProbe.length > 0) {
5457
+ const scanStartedAt = Date.now();
5411
5458
  const probed = await Promise.all(
5412
5459
  toProbe.map((p) => probePort(p.port, opts.buildIconProxyUrl, p))
5413
5460
  );
5414
5461
  probed.forEach((result, i) => {
5415
5462
  const { port, pid } = toProbe[i];
5416
- if (pid !== 0) portCache.set(port, { pid, result, cachedAt: Date.now() });
5463
+ const invalidatedAt = portCacheInvalidatedAt.get(port) ?? 0;
5464
+ if (pid !== 0 && invalidatedAt < scanStartedAt) {
5465
+ portCache.set(port, { pid, result, cachedAt: Date.now() });
5466
+ }
5417
5467
  if (result) results.push(result);
5418
5468
  });
5419
5469
  }
@@ -5905,7 +5955,7 @@ function findMonorepoRoot() {
5905
5955
  if (_monorepoRootCache !== void 0) return _monorepoRootCache;
5906
5956
  let dir = import_path.default.dirname((0, import_url.fileURLToPath)(__sootsim_import_meta_url));
5907
5957
  for (let i = 0; i < 12 && dir !== import_path.default.dirname(dir); i++) {
5908
- if (import_fs.default.existsSync(import_path.default.join(dir, "packages/sootsim-engine/package.json")) && import_fs.default.existsSync(import_path.default.join(dir, "public/sootsim"))) {
5958
+ if (import_fs.default.existsSync(import_path.default.join(dir, "packages/peach-engine/package.json")) && import_fs.default.existsSync(import_path.default.join(dir, "public/sootsim"))) {
5909
5959
  _monorepoRootCache = dir;
5910
5960
  return dir;
5911
5961
  }
@@ -5919,7 +5969,7 @@ function resolveDevCheckoutRuntimeRoot() {
5919
5969
  const root = findMonorepoRoot();
5920
5970
  if (!root) return null;
5921
5971
  const devBuild = import_path.default.join(root, "public/sootsim");
5922
- if (import_fs.default.existsSync(import_path.default.join(devBuild, "index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine/index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.js"))) {
5972
+ if (import_fs.default.existsSync(import_path.default.join(devBuild, "index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine/index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.js")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.prod.js"))) {
5923
5973
  return devBuild;
5924
5974
  }
5925
5975
  return null;
@@ -7398,6 +7448,32 @@ function headerOverridesFor(hostname) {
7398
7448
  }
7399
7449
  return void 0;
7400
7450
  }
7451
+ var PUBLIC_RPC_TENANT = "rnx-public-rpc";
7452
+ var QUICKNODE_HOST_SUFFIX = ".quiknode.pro";
7453
+ var PUBLIC_RPC_BY_QUICKNODE_CHAIN = {
7454
+ "": "https://ethereum-rpc.publicnode.com",
7455
+ "arbitrum-mainnet": "https://arbitrum-one-rpc.publicnode.com",
7456
+ "avalanche-mainnet": "https://avalanche-c-chain-rpc.publicnode.com",
7457
+ "base-mainnet": "https://base-rpc.publicnode.com",
7458
+ "blast-mainnet": "https://blast-rpc.publicnode.com",
7459
+ bsc: "https://bsc-rpc.publicnode.com",
7460
+ "celo-mainnet": "https://celo-rpc.publicnode.com",
7461
+ matic: "https://polygon-bor-rpc.publicnode.com",
7462
+ optimism: "https://optimism-rpc.publicnode.com",
7463
+ "soneium-mainnet": "https://soneium-rpc.publicnode.com",
7464
+ "unichain-mainnet": "https://unichain-rpc.publicnode.com"
7465
+ };
7466
+ function resolveFetchProxyTargetUrl(requested) {
7467
+ const host = requested.hostname.toLowerCase();
7468
+ if (!host.endsWith(QUICKNODE_HOST_SUFFIX)) return requested;
7469
+ const tenant = host.slice(0, -QUICKNODE_HOST_SUFFIX.length);
7470
+ if (tenant !== PUBLIC_RPC_TENANT && !tenant.startsWith(`${PUBLIC_RPC_TENANT}.`)) {
7471
+ return requested;
7472
+ }
7473
+ const chain = tenant === PUBLIC_RPC_TENANT ? "" : tenant.slice(PUBLIC_RPC_TENANT.length + 1);
7474
+ const replacement = PUBLIC_RPC_BY_QUICKNODE_CHAIN[chain];
7475
+ return replacement ? new URL(replacement) : requested;
7476
+ }
7401
7477
  function getFetchProxyTargetHeaders(targetUrl) {
7402
7478
  const hostOverrides = headerOverridesFor(targetUrl.hostname);
7403
7479
  return {
@@ -7518,7 +7594,7 @@ async function handleFetchProxyRequest(req, res) {
7518
7594
  }
7519
7595
  let upstreamUrl;
7520
7596
  try {
7521
- upstreamUrl = new URL(targetUrl);
7597
+ upstreamUrl = resolveFetchProxyTargetUrl(new URL(targetUrl));
7522
7598
  } catch {
7523
7599
  applyFetchProxyCors(res);
7524
7600
  res.writeHead(400, { "Content-Type": "text/plain" });
@@ -7781,7 +7857,7 @@ async function openUrl(url, options = {}) {
7781
7857
  var import_node_fs12 = __toESM(require("node:fs"), 1);
7782
7858
  var import_node_path12 = __toESM(require("node:path"), 1);
7783
7859
 
7784
- // ../rnx-box/src/planeProtocol.ts
7860
+ // ../peach-box/src/planeProtocol.ts
7785
7861
  var PLANE_FLAG_READ_ONLY = 1;
7786
7862
  var PLANE_FLAG_BINARY = 2;
7787
7863
  function encodeBase64(bytes) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.527 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.570 | (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;
@@ -78,6 +78,32 @@ function headerOverridesFor(hostname) {
78
78
  }
79
79
  return void 0;
80
80
  }
81
+ var PUBLIC_RPC_TENANT = "rnx-public-rpc";
82
+ var QUICKNODE_HOST_SUFFIX = ".quiknode.pro";
83
+ var PUBLIC_RPC_BY_QUICKNODE_CHAIN = {
84
+ "": "https://ethereum-rpc.publicnode.com",
85
+ "arbitrum-mainnet": "https://arbitrum-one-rpc.publicnode.com",
86
+ "avalanche-mainnet": "https://avalanche-c-chain-rpc.publicnode.com",
87
+ "base-mainnet": "https://base-rpc.publicnode.com",
88
+ "blast-mainnet": "https://blast-rpc.publicnode.com",
89
+ bsc: "https://bsc-rpc.publicnode.com",
90
+ "celo-mainnet": "https://celo-rpc.publicnode.com",
91
+ matic: "https://polygon-bor-rpc.publicnode.com",
92
+ optimism: "https://optimism-rpc.publicnode.com",
93
+ "soneium-mainnet": "https://soneium-rpc.publicnode.com",
94
+ "unichain-mainnet": "https://unichain-rpc.publicnode.com"
95
+ };
96
+ function resolveFetchProxyTargetUrl(requested) {
97
+ const host = requested.hostname.toLowerCase();
98
+ if (!host.endsWith(QUICKNODE_HOST_SUFFIX)) return requested;
99
+ const tenant = host.slice(0, -QUICKNODE_HOST_SUFFIX.length);
100
+ if (tenant !== PUBLIC_RPC_TENANT && !tenant.startsWith(`${PUBLIC_RPC_TENANT}.`)) {
101
+ return requested;
102
+ }
103
+ const chain = tenant === PUBLIC_RPC_TENANT ? "" : tenant.slice(PUBLIC_RPC_TENANT.length + 1);
104
+ const replacement = PUBLIC_RPC_BY_QUICKNODE_CHAIN[chain];
105
+ return replacement ? new URL(replacement) : requested;
106
+ }
81
107
  function getFetchProxyTargetHeaders(targetUrl) {
82
108
  const hostOverrides = headerOverridesFor(targetUrl.hostname);
83
109
  return {
@@ -201,7 +227,7 @@ async function handleFetchProxyRequest(req, res) {
201
227
  }
202
228
  let upstreamUrl;
203
229
  try {
204
- upstreamUrl = new URL(targetUrl);
230
+ upstreamUrl = resolveFetchProxyTargetUrl(new URL(targetUrl));
205
231
  } catch {
206
232
  applyFetchProxyCors(res);
207
233
  res.writeHead(400, { "Content-Type": "text/plain" });