rnxsim 0.1.504 → 0.1.506

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 (61) hide show
  1. package/cli/bridge-flow-runner.ts +7 -2
  2. package/cli/commands/agent-wrapper.ts +7 -3
  3. package/cli/commands/detox.ts +19 -3
  4. package/cli/commands/flow.ts +1 -0
  5. package/cli/commands/inspect.ts +2 -2
  6. package/cli/commands/test.ts +4 -1
  7. package/cli/flow-live-status.ts +8 -2
  8. package/dist-lib/agent-daemon-client.cjs +1 -1
  9. package/dist-lib/agent-events.cjs +1 -1
  10. package/dist-lib/agent-identity.cjs +1 -1
  11. package/dist-lib/agent-sessions.cjs +1 -1
  12. package/dist-lib/attached-projects.cjs +1 -1
  13. package/dist-lib/auth/shared-session.cjs +1 -1
  14. package/dist-lib/backend-origin.cjs +1 -1
  15. package/dist-lib/beta.cjs +1 -1
  16. package/dist-lib/beta.mjs +1 -1
  17. package/dist-lib/bridge-constants.cjs +1 -1
  18. package/dist-lib/bridge-contract-input.cjs +1 -1
  19. package/dist-lib/bridge-contract-input.mjs +1 -1
  20. package/dist-lib/bridge-contract.cjs +1 -1
  21. package/dist-lib/bridge-contract.mjs +1 -1
  22. package/dist-lib/capture-contract.cjs +1 -1
  23. package/dist-lib/capture-contract.mjs +1 -1
  24. package/dist-lib/cli-constants.cjs +1 -1
  25. package/dist-lib/cloud-contract.cjs +1 -1
  26. package/dist-lib/cloud-contract.mjs +1 -1
  27. package/dist-lib/cloud.cjs +1 -1
  28. package/dist-lib/cloud.mjs +1 -1
  29. package/dist-lib/config.cjs +1 -1
  30. package/dist-lib/detox/index.cjs +1 -1
  31. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  32. package/dist-lib/home-paths.cjs +1 -1
  33. package/dist-lib/host/bridge-host.cjs +142 -56
  34. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  36. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  37. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  38. package/dist-lib/host/websocket-proxy.cjs +1 -1
  39. package/dist-lib/index.cjs +1 -1
  40. package/dist-lib/jump-to-source-babel.cjs +1 -1
  41. package/dist-lib/jump-to-source-native.cjs +1 -1
  42. package/dist-lib/menu.cjs +1 -1
  43. package/dist-lib/menu.mjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  45. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  46. package/dist-lib/metro-production-bundle.cjs +1 -1
  47. package/dist-lib/metro-production-bundle.mjs +1 -1
  48. package/dist-lib/metro.cjs +1 -1
  49. package/dist-lib/profiles.cjs +1 -1
  50. package/dist-lib/public-brand.cjs +1 -1
  51. package/dist-lib/react-native-host-modules.cjs +1 -1
  52. package/dist-lib/react-native-host-modules.mjs +1 -1
  53. package/dist-lib/render-mode.cjs +1 -1
  54. package/dist-lib/scripts/dev-server-scanner.cjs +36 -18
  55. package/dist-lib/sdk.cjs +1 -1
  56. package/dist-lib/sdk.mjs +1 -1
  57. package/dist-lib/skills.cjs +189 -67
  58. package/dist-lib/vite.cjs +1 -1
  59. package/package.json +1 -1
  60. package/scripts/dev-server-scanner.ts +37 -20
  61. package/src/screenshots/frame-compose.ts +71 -11
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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;
@@ -782,6 +782,9 @@ function modernButtons(action, volumeUp, volumeDown, power) {
782
782
  function uniformFrameInsets(value) {
783
783
  return { top: value, right: value, bottom: value, left: value };
784
784
  }
785
+ function cornerRadii(value) {
786
+ return { topLeft: value, topRight: value, bottomRight: value, bottomLeft: value };
787
+ }
785
788
  function iosDevice(spec) {
786
789
  return {
787
790
  ...spec,
@@ -803,8 +806,36 @@ function iosDevice(spec) {
803
806
  modelName: spec.name
804
807
  };
805
808
  }
806
- function getDevice(model) {
807
- return devices[model];
809
+ function resolveDevicePosture(model, posture) {
810
+ const supported = devices[model].supportedPostures;
811
+ return posture && supported?.includes(posture) ? posture : supported?.[0] ?? "closed";
812
+ }
813
+ function getDevice(model, posture) {
814
+ const device = devices[model];
815
+ if (!device.supportedPostures) return device;
816
+ const resolvedPosture = resolveDevicePosture(model, posture);
817
+ if (resolvedPosture === "closed") return device;
818
+ return {
819
+ ...device,
820
+ // inner display size from apple's ios 27 ui kit. corners and insets are
821
+ // measured from apple's 2d inner product art: every display corner fits a
822
+ // 53pt circle within 0.4px, and the silhouette sits 19.5pt outside the
823
+ // display on every edge as 16pt of black glass plus a 3.5pt rail.
824
+ width: 951,
825
+ height: 669,
826
+ statusBarHeight: 44,
827
+ cornerRadius: cornerRadii(53),
828
+ continuousCornerRadius: cornerRadii(53),
829
+ frameInsets: uniformFrameInsets(19.5),
830
+ housing: { rail: uniformFrameInsets(3.5), hingeBarrel: null },
831
+ cameraCutout: null,
832
+ physicalPPI: 430,
833
+ posture: "open",
834
+ // open inner display keeps horizontal bars in this slice; preserve the
835
+ // previous trailing status lane so open layouts do not pick up the closed
836
+ // 84pt Vertical Bar inset.
837
+ safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 72 }
838
+ };
808
839
  }
809
840
  function listDeviceModels() {
810
841
  return Object.keys(devices);
@@ -853,8 +884,8 @@ var init_devices = __esm({
853
884
  scale: 1,
854
885
  statusBarHeight: 0,
855
886
  homeIndicatorHeight: 0,
856
- cornerRadius: 0,
857
- continuousCornerRadius: 0,
887
+ cornerRadius: cornerRadii(0),
888
+ continuousCornerRadius: cornerRadii(0),
858
889
  frameInsets: uniformFrameInsets(16),
859
890
  dynamicIsland: null,
860
891
  safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 0 },
@@ -878,8 +909,8 @@ var init_devices = __esm({
878
909
  scale: 2,
879
910
  statusBarHeight: 20,
880
911
  homeIndicatorHeight: 0,
881
- cornerRadius: 0,
882
- continuousCornerRadius: 0,
912
+ cornerRadius: cornerRadii(0),
913
+ continuousCornerRadius: cornerRadii(0),
883
914
  // legacy home-button frame uses asymmetric LEGACY_*_BEZEL constants in the
884
915
  // shell (111pt forehead/chin, 29pt sides); uniform frameInsets are a sane
885
916
  // modern-path value and mirror the SE's ~28.7pt side bezel.
@@ -898,8 +929,8 @@ var init_devices = __esm({
898
929
  scale: 3,
899
930
  statusBarHeight: 47,
900
931
  homeIndicatorHeight: 34,
901
- cornerRadius: 46.2,
902
- continuousCornerRadius: 67.462,
932
+ cornerRadius: cornerRadii(46.2),
933
+ continuousCornerRadius: cornerRadii(67.462),
903
934
  frameInsets: uniformFrameInsets(19.5),
904
935
  dynamicIsland: null,
905
936
  safeAreaInsets: { top: 47, bottom: 34, left: 0, right: 0 },
@@ -920,8 +951,8 @@ var init_devices = __esm({
920
951
  scale: 3,
921
952
  statusBarHeight: 59,
922
953
  homeIndicatorHeight: 34,
923
- cornerRadius: 53.9,
924
- continuousCornerRadius: 73.402,
954
+ cornerRadius: cornerRadii(53.9),
955
+ continuousCornerRadius: cornerRadii(73.402),
925
956
  frameInsets: uniformFrameInsets(18.2),
926
957
  dynamicIsland: { width: 126, height: 37.3, top: 14.1 },
927
958
  safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
@@ -942,8 +973,8 @@ var init_devices = __esm({
942
973
  scale: 3,
943
974
  statusBarHeight: 59,
944
975
  homeIndicatorHeight: 34,
945
- cornerRadius: 53.9,
946
- continuousCornerRadius: 74.654,
976
+ cornerRadius: cornerRadii(53.9),
977
+ continuousCornerRadius: cornerRadii(74.654),
947
978
  frameInsets: uniformFrameInsets(17.3),
948
979
  dynamicIsland: { width: 126, height: 37.3, top: 11.4 },
949
980
  safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
@@ -964,8 +995,8 @@ var init_devices = __esm({
964
995
  scale: 3,
965
996
  statusBarHeight: 59,
966
997
  homeIndicatorHeight: 34,
967
- cornerRadius: 53.9,
968
- continuousCornerRadius: 73.402,
998
+ cornerRadius: cornerRadii(53.9),
999
+ continuousCornerRadius: cornerRadii(73.402),
969
1000
  frameInsets: uniformFrameInsets(15.3),
970
1001
  dynamicIsland: { width: 126, height: 38, top: 13.4 },
971
1002
  safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
@@ -986,8 +1017,8 @@ var init_devices = __esm({
986
1017
  scale: 3,
987
1018
  statusBarHeight: 59,
988
1019
  homeIndicatorHeight: 34,
989
- cornerRadius: 53.9,
990
- continuousCornerRadius: 74.654,
1020
+ cornerRadius: cornerRadii(53.9),
1021
+ continuousCornerRadius: cornerRadii(74.654),
991
1022
  frameInsets: uniformFrameInsets(15.3),
992
1023
  dynamicIsland: { width: 126, height: 38, top: 13.3 },
993
1024
  safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
@@ -1012,8 +1043,8 @@ var init_devices = __esm({
1012
1043
  // mask (extracted from the simdevicetype bundle PDF; see
1013
1044
  // packages/sootsim-engine/assets/device-frame-geometry). radius is a paint clip only — the
1014
1045
  // calibrated conformance-oracle layout fields below are unchanged.
1015
- cornerRadius: 53.9,
1016
- continuousCornerRadius: 73.402,
1046
+ cornerRadius: cornerRadii(53.9),
1047
+ continuousCornerRadius: cornerRadii(73.402),
1017
1048
  frameInsets: uniformFrameInsets(15.3),
1018
1049
  // island top kept at 11 (real 11.3) — this is the calibrated conformance /
1019
1050
  // proof oracle profile; the status-bar clock offsets are tuned against it.
@@ -1036,8 +1067,8 @@ var init_devices = __esm({
1036
1067
  scale: 3,
1037
1068
  statusBarHeight: 59,
1038
1069
  homeIndicatorHeight: 34,
1039
- cornerRadius: 53.9,
1040
- continuousCornerRadius: 74.654,
1070
+ cornerRadius: cornerRadii(53.9),
1071
+ continuousCornerRadius: cornerRadii(74.654),
1041
1072
  frameInsets: uniformFrameInsets(15.3),
1042
1073
  dynamicIsland: { width: 126, height: 37.3, top: 11.4 },
1043
1074
  safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
@@ -1060,8 +1091,8 @@ var init_devices = __esm({
1060
1091
  // app content at y=186px, i.e. 62 logical pt at 3x.
1061
1092
  statusBarHeight: 62,
1062
1093
  homeIndicatorHeight: 34,
1063
- cornerRadius: 61,
1064
- continuousCornerRadius: 84.661,
1094
+ cornerRadius: cornerRadii(61),
1095
+ continuousCornerRadius: cornerRadii(84.661),
1065
1096
  frameInsets: uniformFrameInsets(15.3),
1066
1097
  dynamicIsland: { width: 126, height: 38, top: 13.5 },
1067
1098
  safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
@@ -1085,8 +1116,8 @@ var init_devices = __esm({
1085
1116
  // remains at the 59pt profile.
1086
1117
  statusBarHeight: 62,
1087
1118
  homeIndicatorHeight: 34,
1088
- cornerRadius: 61.3,
1089
- continuousCornerRadius: 85.163,
1119
+ cornerRadius: cornerRadii(61.3),
1120
+ continuousCornerRadius: cornerRadii(85.163),
1090
1121
  frameInsets: uniformFrameInsets(15.4),
1091
1122
  dynamicIsland: { width: 126, height: 38, top: 14 },
1092
1123
  safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
@@ -1107,8 +1138,8 @@ var init_devices = __esm({
1107
1138
  scale: 3,
1108
1139
  statusBarHeight: 59,
1109
1140
  homeIndicatorHeight: 34,
1110
- cornerRadius: 61,
1111
- continuousCornerRadius: 84.661,
1141
+ cornerRadius: cornerRadii(61),
1142
+ continuousCornerRadius: cornerRadii(84.661),
1112
1143
  // display border 1.44mm plus the visible flat housing rail.
1113
1144
  frameInsets: uniformFrameInsets(15.3),
1114
1145
  dynamicIsland: { width: 126, height: 37.3, top: 14 },
@@ -1133,8 +1164,8 @@ var init_devices = __esm({
1133
1164
  scale: 3,
1134
1165
  statusBarHeight: 59,
1135
1166
  homeIndicatorHeight: 34,
1136
- cornerRadius: 64.6,
1137
- continuousCornerRadius: 88.313,
1167
+ cornerRadius: cornerRadii(64.6),
1168
+ continuousCornerRadius: cornerRadii(88.313),
1138
1169
  // WHICH QUANTITY THIS IS, because it has been flipped twice and each pass
1139
1170
  // read the other one as a bug: frameInsets is the VISIBLE FACE-ON frame —
1140
1171
  // the black display border plus however much housing rail you actually see
@@ -1170,8 +1201,8 @@ var init_devices = __esm({
1170
1201
  scale: 3,
1171
1202
  statusBarHeight: 59,
1172
1203
  homeIndicatorHeight: 34,
1173
- cornerRadius: 61,
1174
- continuousCornerRadius: 84.661,
1204
+ cornerRadius: cornerRadii(61),
1205
+ continuousCornerRadius: cornerRadii(84.661),
1175
1206
  // display border 1.44mm plus the visible flat housing rail.
1176
1207
  frameInsets: uniformFrameInsets(15.3),
1177
1208
  dynamicIsland: { width: 126, height: 38, top: 14 },
@@ -1195,8 +1226,8 @@ var init_devices = __esm({
1195
1226
  // iphone 16 pro max screens proof oracle.
1196
1227
  statusBarHeight: 62,
1197
1228
  homeIndicatorHeight: 34,
1198
- cornerRadius: 61.3,
1199
- continuousCornerRadius: 85.163,
1229
+ cornerRadius: cornerRadii(61.3),
1230
+ continuousCornerRadius: cornerRadii(85.163),
1200
1231
  // display border 1.36mm plus the visible flat housing rail.
1201
1232
  frameInsets: uniformFrameInsets(15.4),
1202
1233
  dynamicIsland: { width: 126, height: 38, top: 14 },
@@ -1211,6 +1242,47 @@ var init_devices = __esm({
1211
1242
  [292.2, 98.3]
1212
1243
  )
1213
1244
  }),
1245
+ "iphone-duo": {
1246
+ ...iosDevice({
1247
+ name: "iPhone Duo",
1248
+ width: 466,
1249
+ height: 678,
1250
+ scale: 3,
1251
+ statusBarHeight: 66,
1252
+ homeIndicatorHeight: 0,
1253
+ // hinge on the left. the hinge-side display corners measure 5pt in
1254
+ // apple's 2d outer product art; the free side keeps the 61pt pro curve.
1255
+ cornerRadius: { topLeft: 5, topRight: 61, bottomRight: 61, bottomLeft: 5 },
1256
+ continuousCornerRadius: {
1257
+ topLeft: 5,
1258
+ topRight: 61,
1259
+ bottomRight: 61,
1260
+ bottomLeft: 5
1261
+ },
1262
+ // display edge to silhouette. left is black glass 8.6 + rail 5.4 + hinge
1263
+ // barrel 14.1; right is black glass 8.7 + rail 7.7.
1264
+ frameInsets: { top: 19, right: 16.4, bottom: 16.3, left: 28.1 },
1265
+ housing: {
1266
+ rail: { top: 10.4, right: 7.7, bottom: 7.7, left: 19.5 },
1267
+ hingeBarrel: { width: 14.1, endInset: 6.4 }
1268
+ },
1269
+ dynamicIsland: null,
1270
+ // 84pt trailing Vertical Bar on the outer display (Apple iOS 27 UI kit).
1271
+ safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 84 },
1272
+ iosVersion: "27.1",
1273
+ keyboardHeight: 0,
1274
+ physicalPPI: 460,
1275
+ // official model extraction for button positions is outside this slice.
1276
+ hardwareButtons: modernButtons([0, 0], [0, 0], [0, 0], [0, 0]),
1277
+ posture: "closed",
1278
+ supportedPostures: ["closed", "open"]
1279
+ }),
1280
+ cameraCutout: {
1281
+ diameter: 37,
1282
+ top: 29,
1283
+ trailing: 29
1284
+ }
1285
+ },
1214
1286
  "pixel-8": {
1215
1287
  platform: "android",
1216
1288
  name: "Pixel 8",
@@ -1230,8 +1302,8 @@ var init_devices = __esm({
1230
1302
  left: 0,
1231
1303
  right: 0
1232
1304
  },
1233
- cornerRadius: 39,
1234
- continuousCornerRadius: 39,
1305
+ cornerRadius: cornerRadii(39),
1306
+ continuousCornerRadius: cornerRadii(39),
1235
1307
  // android studio's pixel 8 device art places the 1080x2400 display at
1236
1308
  // (49,55) in a 1187x2513 body. the right side button occupies the final
1237
1309
  // 8 physical pixels, so the body insets are 49/50/58/55 at 2.625x.
@@ -1278,8 +1350,8 @@ var init_devices = __esm({
1278
1350
  left: 0,
1279
1351
  right: 0
1280
1352
  },
1281
- cornerRadius: 39,
1282
- continuousCornerRadius: 39,
1353
+ cornerRadius: cornerRadii(39),
1354
+ continuousCornerRadius: cornerRadii(39),
1283
1355
  frameInsets: {
1284
1356
  top: 55 / 2.625,
1285
1357
  right: 50 / 2.625,
@@ -1318,8 +1390,8 @@ var init_devices = __esm({
1318
1390
  keyboardHeight: 308,
1319
1391
  navigationBarMode: "gesture",
1320
1392
  displayCutout: { top: 40, bottom: 0, left: 0, right: 0 },
1321
- cornerRadius: 41,
1322
- continuousCornerRadius: 41,
1393
+ cornerRadius: cornerRadii(41),
1394
+ continuousCornerRadius: cornerRadii(41),
1323
1395
  // Pixel 9 Pro XL body 162.8×76.6mm over a 70.2mm panel → ~1.8mm ≈ 12pt.
1324
1396
  frameInsets: uniformFrameInsets(12),
1325
1397
  dynamicIsland: null,
@@ -1354,8 +1426,8 @@ var init_devices = __esm({
1354
1426
  keyboardHeight: 308,
1355
1427
  navigationBarMode: "gesture",
1356
1428
  displayCutout: { top: 40, bottom: 0, left: 0, right: 0 },
1357
- cornerRadius: 40,
1358
- continuousCornerRadius: 40,
1429
+ cornerRadius: cornerRadii(40),
1430
+ continuousCornerRadius: cornerRadii(40),
1359
1431
  // the 72mm body surrounds a roughly 65.1mm-wide 6.3-inch panel, which
1360
1432
  // resolves to about 18 logical points of frame around the 1080px display.
1361
1433
  frameInsets: uniformFrameInsets(18),
@@ -1391,8 +1463,8 @@ var init_devices = __esm({
1391
1463
  keyboardHeight: 308,
1392
1464
  navigationBarMode: "gesture",
1393
1465
  displayCutout: { top: 36, bottom: 0, left: 0, right: 0 },
1394
- cornerRadius: 36,
1395
- continuousCornerRadius: 36,
1466
+ cornerRadius: cornerRadii(36),
1467
+ continuousCornerRadius: cornerRadii(36),
1396
1468
  // Galaxy S24 body 147.0×70.6mm over a 65.9mm panel → ~1.2mm ≈ 8pt (Samsung
1397
1469
  // flat-display bezels are noticeably thinner than Pixel's).
1398
1470
  frameInsets: uniformFrameInsets(8),
@@ -1429,8 +1501,8 @@ var init_devices = __esm({
1429
1501
  keyboardHeight: 308,
1430
1502
  navigationBarMode: "gesture",
1431
1503
  displayCutout: { top: 36, bottom: 0, left: 0, right: 0 },
1432
- cornerRadius: 24,
1433
- continuousCornerRadius: 24,
1504
+ cornerRadius: cornerRadii(24),
1505
+ continuousCornerRadius: cornerRadii(24),
1434
1506
  // Galaxy S24 Ultra body 162.3×79.0mm over a 72.4mm panel → ~1.5mm ≈ 9pt.
1435
1507
  frameInsets: uniformFrameInsets(9),
1436
1508
  dynamicIsland: null,
@@ -4919,20 +4991,34 @@ function applyManifest(result, manifestRes, buildIconProxyUrl) {
4919
4991
  if (launchUrl2 && !result.patched && !isDirectOneBundleUrl(result.bundleUrl)) {
4920
4992
  result.bundleUrl = withRuntimeConfig(result.port, launchUrl2, result.cwd);
4921
4993
  }
4922
- const rawIconUrl = client.iconUrl || client.ios?.iconUrl || client.icon || client.ios?.icon;
4923
- if (rawIconUrl) {
4924
- result.iconPath = rawIconUrl;
4925
- if (buildIconProxyUrl) {
4926
- if (rawIconUrl.startsWith("http")) {
4927
- result.iconUrl = buildIconProxyUrl(rawIconUrl);
4994
+ const localIcon = client.icon || client.ios?.icon;
4995
+ const remoteIcon = client.iconUrl || client.ios?.iconUrl;
4996
+ const rawIcon = localIcon || remoteIcon;
4997
+ if (rawIcon) {
4998
+ result.iconPath = rawIcon;
4999
+ let resolvedIconUrl;
5000
+ if (rawIcon.startsWith("http://") || rawIcon.startsWith("https://")) {
5001
+ let isLoopback = false;
5002
+ try {
5003
+ const parsed = new URL(rawIcon);
5004
+ isLoopback = isLoopbackHost(parsed.hostname);
5005
+ } catch {
5006
+ }
5007
+ if (buildIconProxyUrl) {
5008
+ if (isLoopback) {
5009
+ resolvedIconUrl = buildIconProxyUrl(rawIcon);
5010
+ }
4928
5011
  } else {
4929
- const cleanPath = rawIconUrl.replace(/^\.\//, "");
4930
- result.iconUrl = buildIconProxyUrl(
4931
- `${buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port)}/assets/${cleanPath}`
4932
- );
5012
+ resolvedIconUrl = rawIcon;
4933
5013
  }
4934
5014
  } else {
4935
- result.iconUrl = rawIconUrl.startsWith("http") ? rawIconUrl : `${buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port)}/assets/${rawIconUrl.replace(/^\.\//, "")}`;
5015
+ const cleanPath = rawIcon.replace(/^\.?\//, "");
5016
+ const assetPath = cleanPath.startsWith("assets/") ? `/${cleanPath}` : `/assets/${cleanPath}`;
5017
+ const localUrl = `${buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port)}${assetPath}`;
5018
+ resolvedIconUrl = buildIconProxyUrl ? buildIconProxyUrl(localUrl) : localUrl;
5019
+ }
5020
+ if (resolvedIconUrl) {
5021
+ result.iconUrl = resolvedIconUrl;
4936
5022
  }
4937
5023
  }
4938
5024
  } catch {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-fingerprint-registry.ts
4
4
  var RNX_METRO_FINGERPRINT_SCHEMA_VERSION = 2;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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;
@@ -842,32 +842,50 @@ function applyManifest(result, manifestRes, buildIconProxyUrl) {
842
842
  if (launchUrl && !result.patched && !isDirectOneBundleUrl(result.bundleUrl)) {
843
843
  result.bundleUrl = withRuntimeConfig(result.port, launchUrl, result.cwd);
844
844
  }
845
- const rawIconUrl = client.iconUrl || client.ios?.iconUrl || client.icon || client.ios?.icon;
846
- if (rawIconUrl) {
847
- result.iconPath = rawIconUrl;
848
- if (buildIconProxyUrl) {
849
- if (rawIconUrl.startsWith("http")) {
850
- result.iconUrl = buildIconProxyUrl(rawIconUrl);
845
+ const localIcon = client.icon || client.ios?.icon;
846
+ const remoteIcon = client.iconUrl || client.ios?.iconUrl;
847
+ const rawIcon = localIcon || remoteIcon;
848
+ if (rawIcon) {
849
+ result.iconPath = rawIcon;
850
+ let resolvedIconUrl;
851
+ if (rawIcon.startsWith("http://") || rawIcon.startsWith("https://")) {
852
+ let isLoopback = false;
853
+ try {
854
+ const parsed = new URL(rawIcon);
855
+ isLoopback = isLoopbackHost(parsed.hostname);
856
+ } catch {
857
+ }
858
+ if (buildIconProxyUrl) {
859
+ if (isLoopback) {
860
+ resolvedIconUrl = buildIconProxyUrl(rawIcon);
861
+ }
851
862
  } else {
852
- const cleanPath = rawIconUrl.replace(/^\.\//, "");
853
- result.iconUrl = buildIconProxyUrl(
854
- `${buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port)}/assets/${cleanPath}`
855
- );
863
+ resolvedIconUrl = rawIcon;
856
864
  }
857
865
  } else {
858
- result.iconUrl = rawIconUrl.startsWith("http") ? rawIconUrl : `${buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port)}/assets/${rawIconUrl.replace(/^\.\//, "")}`;
866
+ const cleanPath = rawIcon.replace(/^\.?\//, "");
867
+ const assetPath = cleanPath.startsWith("assets/") ? `/${cleanPath}` : `/assets/${cleanPath}`;
868
+ const localUrl = `${buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port)}${assetPath}`;
869
+ resolvedIconUrl = buildIconProxyUrl ? buildIconProxyUrl(localUrl) : localUrl;
870
+ }
871
+ if (resolvedIconUrl) {
872
+ result.iconUrl = resolvedIconUrl;
859
873
  }
860
874
  }
861
875
  } catch {
862
876
  }
863
877
  return result;
864
878
  }
865
- function __applyManifestForTests(result, manifestBody) {
866
- return applyManifest(result, {
867
- statusCode: 200,
868
- body: manifestBody,
869
- hostname: new URL(result.bundleUrl).hostname
870
- });
879
+ function __applyManifestForTests(result, manifestBody, buildIconProxyUrl) {
880
+ return applyManifest(
881
+ result,
882
+ {
883
+ statusCode: 200,
884
+ body: manifestBody,
885
+ hostname: new URL(result.bundleUrl).hostname
886
+ },
887
+ buildIconProxyUrl
888
+ );
871
889
  }
872
890
  var ENRICH_TIMEOUT_MS = 2e4;
873
891
  var enrichmentCache = /* @__PURE__ */ new Map();
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.504 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.506 | (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);