peachsim 0.1.872 → 0.1.875

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 (82) hide show
  1. package/cli/commands/inspect.ts +3 -2
  2. package/cli/commands/swift.ts +39 -12
  3. package/dist-lib/agent-daemon-client.cjs +1 -1
  4. package/dist-lib/agent-events.cjs +1 -1
  5. package/dist-lib/agent-identity.cjs +1 -1
  6. package/dist-lib/agent-sessions.cjs +1 -1
  7. package/dist-lib/attached-projects.cjs +1 -1
  8. package/dist-lib/auth/shared-session.cjs +1 -1
  9. package/dist-lib/backend-origin.cjs +1 -1
  10. package/dist-lib/beta.cjs +1 -1
  11. package/dist-lib/beta.mjs +1 -1
  12. package/dist-lib/bridge-constants.cjs +1 -1
  13. package/dist-lib/bridge-contract-input.cjs +1 -1
  14. package/dist-lib/bridge-contract-input.mjs +1 -1
  15. package/dist-lib/bridge-contract.cjs +1 -1
  16. package/dist-lib/bridge-contract.mjs +1 -1
  17. package/dist-lib/bundle-channel.cjs +2 -1
  18. package/dist-lib/capture-contract.cjs +1 -1
  19. package/dist-lib/capture-contract.mjs +1 -1
  20. package/dist-lib/cli-constants.cjs +1 -1
  21. package/dist-lib/cloud-contract.cjs +1 -1
  22. package/dist-lib/cloud-contract.mjs +1 -1
  23. package/dist-lib/cloud-test-args.cjs +1 -1
  24. package/dist-lib/cloud-test-args.mjs +1 -1
  25. package/dist-lib/cloud.cjs +1 -1
  26. package/dist-lib/cloud.mjs +1 -1
  27. package/dist-lib/config.cjs +1 -1
  28. package/dist-lib/detox/index.cjs +1 -1
  29. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  30. package/dist-lib/expo-swift-bundle.cjs +2 -1
  31. package/dist-lib/expo-swift-metadata.cjs +1 -1
  32. package/dist-lib/expo-swift-metadata.mjs +1 -1
  33. package/dist-lib/home-paths.cjs +1 -1
  34. package/dist-lib/host/bridge-host.cjs +40 -6
  35. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  36. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  37. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  38. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  39. package/dist-lib/host/websocket-proxy.cjs +1 -1
  40. package/dist-lib/index.cjs +2 -1
  41. package/dist-lib/jump-to-source-babel.cjs +1 -1
  42. package/dist-lib/jump-to-source-native.cjs +1 -1
  43. package/dist-lib/kotlin-host.cjs +1 -1
  44. package/dist-lib/menu.cjs +1 -1
  45. package/dist-lib/menu.mjs +1 -1
  46. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  47. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  48. package/dist-lib/metro-production-bundle.cjs +1 -1
  49. package/dist-lib/metro-production-bundle.mjs +1 -1
  50. package/dist-lib/metro.cjs +2 -1
  51. package/dist-lib/native-app-identity.cjs +1 -1
  52. package/dist-lib/native-app-identity.mjs +1 -1
  53. package/dist-lib/native-firebase-metadata.cjs +1 -1
  54. package/dist-lib/native-firebase-metadata.mjs +1 -1
  55. package/dist-lib/plist.cjs +1 -1
  56. package/dist-lib/plist.mjs +1 -1
  57. package/dist-lib/profiles.cjs +1 -1
  58. package/dist-lib/public-brand.cjs +1 -1
  59. package/dist-lib/react-native-host-modules.cjs +1 -1
  60. package/dist-lib/react-native-host-modules.mjs +1 -1
  61. package/dist-lib/render-mode.cjs +1 -1
  62. package/dist-lib/scripts/dev-server-scanner.cjs +39 -6
  63. package/dist-lib/sdk.cjs +1 -1
  64. package/dist-lib/sdk.mjs +1 -1
  65. package/dist-lib/skills.cjs +47 -6
  66. package/dist-lib/swift-compile.cjs +1 -1
  67. package/dist-lib/swift-compile.mjs +1 -1
  68. package/dist-lib/swift-package.cjs +1 -1
  69. package/dist-lib/swift-package.mjs +1 -1
  70. package/dist-lib/swift-submit.cjs +1 -1
  71. package/dist-lib/swift-submit.mjs +1 -1
  72. package/dist-lib/swift-toolchain.cjs +1 -1
  73. package/dist-lib/swift.cjs +1 -1
  74. package/dist-lib/vite-swift.cjs +2 -1
  75. package/dist-lib/vite.cjs +1 -1
  76. package/dist-lib/worklet-executable.cjs +1 -1
  77. package/dist-lib/worklet-executable.mjs +1 -1
  78. package/package.json +1 -1
  79. package/scripts/dev-server-scanner.ts +38 -19
  80. package/src/swift-host.ts +65 -0
  81. package/src/swiftDiscoveryContract.ts +32 -0
  82. package/src/xcode-project.ts +2 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/plist.ts
4
4
  import plist from "plist";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (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.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -933,6 +933,22 @@ function __resetAppSettingsBundleCacheForTests() {
933
933
  settingsBundleCache.clear();
934
934
  }
935
935
 
936
+ // src/swiftDiscoveryContract.ts
937
+ var SWIFT_DISCOVERY_PATH = "/__peach/swift-host";
938
+ var SWIFT_GUEST_PATH = "/__peach/swift-guest.js";
939
+ var SWIFT_ICON_PATH = "/__peach/swift-icon";
940
+ function parseSwiftHostDiscovery(value) {
941
+ if (!value || typeof value !== "object") return null;
942
+ if (!("framework" in value) || value.framework !== "swift" || !("projectName" in value) || typeof value.projectName !== "string" || !("status" in value) || value.status !== "compiling" && value.status !== "ready" && value.status !== "error")
943
+ return null;
944
+ return {
945
+ framework: value.framework,
946
+ projectName: value.projectName,
947
+ status: value.status,
948
+ ..."iconPath" in value && value.iconPath === SWIFT_ICON_PATH ? { iconPath: SWIFT_ICON_PATH } : {}
949
+ };
950
+ }
951
+
936
952
  // scripts/optional-demo-registry.ts
937
953
  var import_node_fs = require("node:fs");
938
954
  var import_node_path2 = require("node:path");
@@ -1151,7 +1167,7 @@ async function listListeners() {
1151
1167
  let timedOut = false;
1152
1168
  try {
1153
1169
  const { stdout } = await execGuarded(
1154
- `lsof -a -c node -c bun -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun)'`,
1170
+ `lsof -a -c node -c bun -c peach -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun|peach)'`,
1155
1171
  LISTING_TIMEOUT_MS
1156
1172
  );
1157
1173
  const seen = /* @__PURE__ */ new Map();
@@ -1173,7 +1189,7 @@ async function listListeners() {
1173
1189
  }
1174
1190
  try {
1175
1191
  const { stdout } = await execGuarded(
1176
- `ss -tlnp 2>/dev/null | grep -E '"(node|bun)"'`,
1192
+ `ss -tlnp 2>/dev/null | grep -E '"(node|bun|peach)"'`,
1177
1193
  LISTING_TIMEOUT_MS
1178
1194
  );
1179
1195
  const seen = /* @__PURE__ */ new Map();
@@ -1466,14 +1482,30 @@ async function probePort(port, buildIconProxyUrl, listeningProcess) {
1466
1482
  ...ownerCwd ? { cwd: ownerCwd } : {}
1467
1483
  };
1468
1484
  const onePath = `/node_modules/one/metro-entry.bundle?platform=ios&dev=true`;
1469
- const [sootsimRes, statusRes, manifestRes, expoRes] = await Promise.all([
1485
+ const [sootsimRes, statusRes, manifestRes, expoRes, swiftRes] = await Promise.all([
1470
1486
  knownNonPatched.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/__soot/"),
1471
1487
  httpGet(probeHostname, port, "/status"),
1472
1488
  knownOne.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/", "GET", MANIFEST_TIMEOUT_MS, {
1473
1489
  "expo-platform": "ios"
1474
1490
  }),
1475
- knownNonExpo.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/_expo/status")
1491
+ knownNonExpo.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/_expo/status"),
1492
+ httpGet(probeHostname, port, SWIFT_DISCOVERY_PATH)
1476
1493
  ]);
1494
+ const swift = swiftRes?.statusCode === 200 ? parseSwiftHostDiscovery(safeParseManifest(swiftRes.body)) : null;
1495
+ if (swift) {
1496
+ const base = buildLoopbackProbeBaseUrl("http:", probeHostname, port);
1497
+ const iconUrl = swift.iconPath ? `${base}${swift.iconPath}` : void 0;
1498
+ return {
1499
+ port,
1500
+ framework: "swift",
1501
+ projectName: swift.projectName,
1502
+ status: swift.status,
1503
+ bundleUrl: `${base}${SWIFT_GUEST_PATH}`,
1504
+ iconUrl: iconUrl && buildIconProxyUrl ? buildIconProxyUrl(iconUrl) : iconUrl,
1505
+ lastSeen: Date.now(),
1506
+ ...owner
1507
+ };
1508
+ }
1477
1509
  if (expoRes && expoRes.statusCode === 200) {
1478
1510
  knownNonExpo.delete(port);
1479
1511
  } else if (!knownNonExpo.has(port)) {
@@ -1589,7 +1621,8 @@ var NEGATIVE_CACHE_TTL_MS = 3e4;
1589
1621
  var WEAK_RESULT_CACHE_TTL_MS = 1500;
1590
1622
  function isWeakCachedResult(result) {
1591
1623
  if (!result) return true;
1592
- if (result.framework === "metro" || result.framework === "unknown") return true;
1624
+ if (result.framework === "metro" || result.framework === "unknown" || result.framework === "swift")
1625
+ return true;
1593
1626
  return false;
1594
1627
  }
1595
1628
  function hasCurrentRuntimeConfig(result) {
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } 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.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (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);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -27448,6 +27448,28 @@ var init_settings_bundle = __esm({
27448
27448
  }
27449
27449
  });
27450
27450
 
27451
+ // src/swiftDiscoveryContract.ts
27452
+ function parseSwiftHostDiscovery(value) {
27453
+ if (!value || typeof value !== "object") return null;
27454
+ if (!("framework" in value) || value.framework !== "swift" || !("projectName" in value) || typeof value.projectName !== "string" || !("status" in value) || value.status !== "compiling" && value.status !== "ready" && value.status !== "error")
27455
+ return null;
27456
+ return {
27457
+ framework: value.framework,
27458
+ projectName: value.projectName,
27459
+ status: value.status,
27460
+ ..."iconPath" in value && value.iconPath === SWIFT_ICON_PATH ? { iconPath: SWIFT_ICON_PATH } : {}
27461
+ };
27462
+ }
27463
+ var SWIFT_DISCOVERY_PATH, SWIFT_GUEST_PATH, SWIFT_ICON_PATH;
27464
+ var init_swiftDiscoveryContract = __esm({
27465
+ "src/swiftDiscoveryContract.ts"() {
27466
+ "use strict";
27467
+ SWIFT_DISCOVERY_PATH = "/__peach/swift-host";
27468
+ SWIFT_GUEST_PATH = "/__peach/swift-guest.js";
27469
+ SWIFT_ICON_PATH = "/__peach/swift-icon";
27470
+ }
27471
+ });
27472
+
27451
27473
  // scripts/optional-demo-registry.ts
27452
27474
  var optional_demo_registry_exports = {};
27453
27475
  __export(optional_demo_registry_exports, {
@@ -27649,7 +27671,7 @@ async function listListeners() {
27649
27671
  let timedOut = false;
27650
27672
  try {
27651
27673
  const { stdout } = await execGuarded(
27652
- `lsof -a -c node -c bun -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun)'`,
27674
+ `lsof -a -c node -c bun -c peach -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun|peach)'`,
27653
27675
  LISTING_TIMEOUT_MS
27654
27676
  );
27655
27677
  const seen = /* @__PURE__ */ new Map();
@@ -27671,7 +27693,7 @@ async function listListeners() {
27671
27693
  }
27672
27694
  try {
27673
27695
  const { stdout } = await execGuarded(
27674
- `ss -tlnp 2>/dev/null | grep -E '"(node|bun)"'`,
27696
+ `ss -tlnp 2>/dev/null | grep -E '"(node|bun|peach)"'`,
27675
27697
  LISTING_TIMEOUT_MS
27676
27698
  );
27677
27699
  const seen = /* @__PURE__ */ new Map();
@@ -27951,14 +27973,30 @@ async function probePort(port, buildIconProxyUrl, listeningProcess) {
27951
27973
  ...ownerCwd ? { cwd: ownerCwd } : {}
27952
27974
  };
27953
27975
  const onePath = `/node_modules/one/metro-entry.bundle?platform=ios&dev=true`;
27954
- const [sootsimRes, statusRes, manifestRes, expoRes] = await Promise.all([
27976
+ const [sootsimRes, statusRes, manifestRes, expoRes, swiftRes] = await Promise.all([
27955
27977
  knownNonPatched.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/__soot/"),
27956
27978
  httpGet(probeHostname, port, "/status"),
27957
27979
  knownOne.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/", "GET", MANIFEST_TIMEOUT_MS, {
27958
27980
  "expo-platform": "ios"
27959
27981
  }),
27960
- knownNonExpo.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/_expo/status")
27982
+ knownNonExpo.has(port) ? Promise.resolve(null) : httpGet(probeHostname, port, "/_expo/status"),
27983
+ httpGet(probeHostname, port, SWIFT_DISCOVERY_PATH)
27961
27984
  ]);
27985
+ const swift = swiftRes?.statusCode === 200 ? parseSwiftHostDiscovery(safeParseManifest(swiftRes.body)) : null;
27986
+ if (swift) {
27987
+ const base = buildLoopbackProbeBaseUrl("http:", probeHostname, port);
27988
+ const iconUrl = swift.iconPath ? `${base}${swift.iconPath}` : void 0;
27989
+ return {
27990
+ port,
27991
+ framework: "swift",
27992
+ projectName: swift.projectName,
27993
+ status: swift.status,
27994
+ bundleUrl: `${base}${SWIFT_GUEST_PATH}`,
27995
+ iconUrl: iconUrl && buildIconProxyUrl ? buildIconProxyUrl(iconUrl) : iconUrl,
27996
+ lastSeen: Date.now(),
27997
+ ...owner
27998
+ };
27999
+ }
27962
28000
  if (expoRes && expoRes.statusCode === 200) {
27963
28001
  knownNonExpo.delete(port);
27964
28002
  } else if (!knownNonExpo.has(port)) {
@@ -28070,7 +28108,8 @@ function invalidatePortCache(port) {
28070
28108
  }
28071
28109
  function isWeakCachedResult(result) {
28072
28110
  if (!result) return true;
28073
- if (result.framework === "metro" || result.framework === "unknown") return true;
28111
+ if (result.framework === "metro" || result.framework === "unknown" || result.framework === "swift")
28112
+ return true;
28074
28113
  return false;
28075
28114
  }
28076
28115
  function hasCurrentRuntimeConfig(result) {
@@ -28198,6 +28237,7 @@ var init_dev_server_scanner = __esm({
28198
28237
  init_native_dev_bundle_url();
28199
28238
  init_one_widget_discovery();
28200
28239
  init_settings_bundle();
28240
+ init_swiftDiscoveryContract();
28201
28241
  init_optional_demo_registry();
28202
28242
  TIMEOUT_MS = 250;
28203
28243
  MANIFEST_TIMEOUT_MS = 1500;
@@ -36649,6 +36689,7 @@ function readXcodeAppTarget(input, targetName) {
36649
36689
  ].map((dir) => import_node_fs18.default.realpathSync(dir))
36650
36690
  ),
36651
36691
  projectFiles: [...new Set(used.map((project) => project.projectFile))].sort(),
36692
+ appIconName: settings("ASSETCATALOG_COMPILER_APPICON_NAME"),
36652
36693
  infoPlist: import_plist3.default.build(info),
36653
36694
  infoPlistFile,
36654
36695
  frameworks,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
4
  import { execFile as execFile2, execFileSync } from "node:child_process";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-package.ts
4
4
  function isSwiftManifestFile(file) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-submit.ts
4
4
  var SWIFT_COMPILE_PATH = "/api/swift-compile";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -7610,6 +7610,7 @@ function readXcodeAppTarget(input, targetName) {
7610
7610
  ].map((dir) => import_node_fs13.default.realpathSync(dir))
7611
7611
  ),
7612
7612
  projectFiles: [...new Set(used.map((project) => project.projectFile))].sort(),
7613
+ appIconName: settings("ASSETCATALOG_COMPILER_APPICON_NAME"),
7613
7614
  infoPlist: import_plist.default.build(info),
7614
7615
  infoPlistFile,
7615
7616
  frameworks,
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.872 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.875 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/worklet-executable.ts
4
4
  import { parse } from "acorn";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peachsim",
3
- "version": "0.1.872",
3
+ "version": "0.1.875",
4
4
  "description": "Vite and Metro plugins, testing drivers, and SDK exports for peach.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -1,19 +1,7 @@
1
+ // shared loopback discovery for node, bun and standalone peach hosts.
2
+ // probes swift signatures and RN bundlers; results are cached by port and pid.
1
3
  import { spawn } from 'child_process'
2
4
  import { readlink } from 'fs/promises'
3
- // shared dev-server scanner used by both the electron main process
4
- // (`src-electron/main.ts`) and the vite plugin (`vite.config.ts`). discovers
5
- // running dev servers on localhost by listing every node/bun process that's
6
- // listening, then probes each port for known bundler signatures.
7
- //
8
- // precedence during probing:
9
- // 1. one/vxrn (node_modules/one/metro-entry.bundle reachable)
10
- // 2. metro/expo (packager-status:running + /_expo/status)
11
- // 3. expo manifest (JSON manifest at /)
12
- // 4. sootsim-patched (/__soot/ middleware present) → /__soot/bundle.js
13
- //
14
- // scans are cached per (port, pid). repeat scans with no process changes issue
15
- // no signature probes; widget metadata is refreshed from the owning One server
16
- // on every scan. before signature HTTP, a TCP gate skips unreachable ports.
17
5
  import http from 'http'
18
6
  import net from 'net'
19
7
  import { realpathSync } from 'node:fs'
@@ -35,6 +23,11 @@ import {
35
23
  __resetAppSettingsBundleCacheForTests,
36
24
  readAppSettingsBundle,
37
25
  } from '../src/settings-bundle.ts'
26
+ import {
27
+ SWIFT_DISCOVERY_PATH,
28
+ SWIFT_GUEST_PATH,
29
+ parseSwiftHostDiscovery,
30
+ } from '../src/swiftDiscoveryContract'
38
31
  import { loadOptionalDemoApps, optionalDemoAppsSync } from './optional-demo-registry.ts'
39
32
  import type { ConfiguredOneWidget } from '../src/oneWidgetContract'
40
33
  import type { AppSettingsSpecifier } from '@peach/globals'
@@ -103,7 +96,8 @@ function execGuarded(
103
96
 
104
97
  export interface DiscoveredServer {
105
98
  port: number
106
- framework: 'metro' | 'expo' | 'vxrn' | 'one' | 'unknown'
99
+ framework: 'metro' | 'expo' | 'vxrn' | 'one' | 'swift' | 'unknown'
100
+ status?: 'compiling' | 'ready' | 'error'
107
101
  projectName?: string
108
102
  bundleUrl: string
109
103
  hmrUrl?: string
@@ -390,7 +384,7 @@ async function listListeners(): Promise<ListeningProcessScan> {
390
384
  // lsof most of a builder's filesystem calls.
391
385
  try {
392
386
  const { stdout } = await execGuarded(
393
- `lsof -a -c node -c bun -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun)'`,
387
+ `lsof -a -c node -c bun -c peach -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E '^(node|bun|peach)'`,
394
388
  LISTING_TIMEOUT_MS,
395
389
  )
396
390
  const seen = new Map<number, number>()
@@ -415,7 +409,7 @@ async function listListeners(): Promise<ListeningProcessScan> {
415
409
  // ss layout: State Recv-Q Send-Q Local-Address:Port Peer-Addr:Port users:(("node",pid=1234,fd=5))
416
410
  try {
417
411
  const { stdout } = await execGuarded(
418
- `ss -tlnp 2>/dev/null | grep -E '"(node|bun)"'`,
412
+ `ss -tlnp 2>/dev/null | grep -E '"(node|bun|peach)"'`,
419
413
  LISTING_TIMEOUT_MS,
420
414
  )
421
415
  const seen = new Map<number, number>()
@@ -911,7 +905,7 @@ export async function probePort(
911
905
  const onePath = `/node_modules/one/metro-entry.bundle?platform=ios&dev=true`
912
906
 
913
907
  // wave 1 — safe parallel probes. none of these mutate metro state.
914
- const [sootsimRes, statusRes, manifestRes, expoRes] = await Promise.all([
908
+ const [sootsimRes, statusRes, manifestRes, expoRes, swiftRes] = await Promise.all([
915
909
  knownNonPatched.has(port)
916
910
  ? Promise.resolve(null)
917
911
  : httpGet(probeHostname, port, '/__soot/'),
@@ -924,8 +918,28 @@ export async function probePort(
924
918
  knownNonExpo.has(port)
925
919
  ? Promise.resolve(null)
926
920
  : httpGet(probeHostname, port, '/_expo/status'),
921
+ httpGet(probeHostname, port, SWIFT_DISCOVERY_PATH),
927
922
  ])
928
923
 
924
+ const swift =
925
+ swiftRes?.statusCode === 200
926
+ ? parseSwiftHostDiscovery(safeParseManifest(swiftRes.body))
927
+ : null
928
+ if (swift) {
929
+ const base = buildLoopbackProbeBaseUrl('http:', probeHostname, port)
930
+ const iconUrl = swift.iconPath ? `${base}${swift.iconPath}` : undefined
931
+ return {
932
+ port,
933
+ framework: 'swift',
934
+ projectName: swift.projectName,
935
+ status: swift.status,
936
+ bundleUrl: `${base}${SWIFT_GUEST_PATH}`,
937
+ iconUrl: iconUrl && buildIconProxyUrl ? buildIconProxyUrl(iconUrl) : iconUrl,
938
+ lastSeen: Date.now(),
939
+ ...owner,
940
+ }
941
+ }
942
+
929
943
  // remember negative /_expo/status responses so we don't keep probing this
930
944
  // endpoint on ports that clearly aren't expo packagers (one/vxrn, vite,
931
945
  // random node processes). a 200 flips the port out of the non-expo set.
@@ -1170,7 +1184,12 @@ const WEAK_RESULT_CACHE_TTL_MS = 1_500
1170
1184
 
1171
1185
  function isWeakCachedResult(result: DiscoveredServer | null): boolean {
1172
1186
  if (!result) return true
1173
- if (result.framework === 'metro' || result.framework === 'unknown') return true
1187
+ if (
1188
+ result.framework === 'metro' ||
1189
+ result.framework === 'unknown' ||
1190
+ result.framework === 'swift'
1191
+ )
1192
+ return true
1174
1193
  return false
1175
1194
  }
1176
1195
 
package/src/swift-host.ts CHANGED
@@ -479,6 +479,71 @@ function resourceCandidateFiles(root: string): string[] {
479
479
  )
480
480
  }
481
481
 
482
+ // discovery reads only the app target's catalog, before the first compile.
483
+ export function swiftProjectAppInfo(packagePath: string): {
484
+ name: string
485
+ icon: { bytes: Buffer; contentType: string } | null
486
+ } {
487
+ const registered = xcodeProjects.get(packagePath)
488
+ const app = registered
489
+ ? readXcodeAppTarget(registered.xcodeproj, registered.target)
490
+ : null
491
+ const files = app?.resources ?? resourceCandidateFiles(packagePath)
492
+ const catalogs = files.filter(
493
+ (file) =>
494
+ file.endsWith('.appiconset/Contents.json') &&
495
+ (!app?.appIconName ||
496
+ path.basename(path.dirname(file)) === `${app.appIconName}.appiconset`),
497
+ )
498
+ let icon: { bytes: Buffer; contentType: string } | null = null
499
+ for (const contents of catalogs) {
500
+ const value: unknown = JSON.parse(fs.readFileSync(contents, 'utf8'))
501
+ if (
502
+ !value ||
503
+ typeof value !== 'object' ||
504
+ !('images' in value) ||
505
+ !Array.isArray(value.images)
506
+ )
507
+ continue
508
+ const images: { filename: string; pixels: number }[] = []
509
+ const entries: readonly unknown[] = value.images
510
+ for (const image of entries) {
511
+ if (
512
+ !image ||
513
+ typeof image !== 'object' ||
514
+ !('filename' in image) ||
515
+ typeof image.filename !== 'string' ||
516
+ path.basename(image.filename) !== image.filename ||
517
+ !/\.(png|jpe?g|webp)$/i.test(image.filename)
518
+ )
519
+ continue
520
+ if (
521
+ 'idiom' in image &&
522
+ (typeof image.idiom !== 'string' ||
523
+ !['iphone', 'ios-marketing', 'universal'].includes(image.idiom))
524
+ )
525
+ continue
526
+ if ('appearances' in image) continue
527
+ const size =
528
+ 'size' in image && typeof image.size === 'string' ? parseFloat(image.size) : 0
529
+ const scale =
530
+ 'scale' in image && typeof image.scale === 'string' ? parseFloat(image.scale) : 1
531
+ images.push({ filename: image.filename, pixels: size * scale })
532
+ }
533
+ const picked = images.sort((a, b) => b.pixels - a.pixels)[0]
534
+ if (!picked) continue
535
+ const file = path.join(path.dirname(contents), picked.filename)
536
+ if (!files.includes(file)) continue
537
+ icon = {
538
+ bytes: fs.readFileSync(file),
539
+ contentType:
540
+ RESOURCE_CONTENT_TYPES[path.extname(file).toLowerCase()] ?? 'image/png',
541
+ }
542
+ break
543
+ }
544
+ return { name: app?.name ?? path.basename(packagePath), icon }
545
+ }
546
+
482
547
  // the hosted compile service caps what a project sends it; a local compile
483
548
  // reads the author's own files, so nothing caps them there.
484
549
  const HOSTED_LIMITS = {
@@ -0,0 +1,32 @@
1
+ // the foreground swift host's signature, shared by its server and scanner.
2
+ export const SWIFT_DISCOVERY_PATH = '/__peach/swift-host'
3
+ export const SWIFT_GUEST_PATH = '/__peach/swift-guest.js'
4
+ export const SWIFT_ICON_PATH = '/__peach/swift-icon'
5
+
6
+ export interface SwiftHostDiscovery {
7
+ framework: 'swift'
8
+ projectName: string
9
+ status: 'compiling' | 'ready' | 'error'
10
+ iconPath?: typeof SWIFT_ICON_PATH
11
+ }
12
+
13
+ export function parseSwiftHostDiscovery(value: unknown): SwiftHostDiscovery | null {
14
+ if (!value || typeof value !== 'object') return null
15
+ if (
16
+ !('framework' in value) ||
17
+ value.framework !== 'swift' ||
18
+ !('projectName' in value) ||
19
+ typeof value.projectName !== 'string' ||
20
+ !('status' in value) ||
21
+ (value.status !== 'compiling' && value.status !== 'ready' && value.status !== 'error')
22
+ )
23
+ return null
24
+ return {
25
+ framework: value.framework,
26
+ projectName: value.projectName,
27
+ status: value.status,
28
+ ...('iconPath' in value && value.iconPath === SWIFT_ICON_PATH
29
+ ? { iconPath: SWIFT_ICON_PATH }
30
+ : {}),
31
+ }
32
+ }
@@ -141,6 +141,7 @@ export interface XcodeAppTarget extends XcodeModuleTarget {
141
141
  /** the target's processed launch plist, including generated build settings. */
142
142
  infoPlist: string
143
143
  infoPlistFile: string | null
144
+ appIconName: string
144
145
  /** the target's compiled sources in every language, swift or not. */
145
146
  allSources: string[]
146
147
  /**
@@ -966,6 +967,7 @@ export function readXcodeAppTarget(input: string, targetName?: string): XcodeApp
966
967
  ].map((dir) => fs.realpathSync(dir)),
967
968
  ),
968
969
  projectFiles: [...new Set(used.map((project) => project.projectFile))].sort(),
970
+ appIconName: settings('ASSETCATALOG_COMPILER_APPICON_NAME'),
969
971
  infoPlist: plist.build(info),
970
972
  infoPlistFile,
971
973
  frameworks,