peachsim 0.1.1641 → 0.1.1644

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 (96) hide show
  1. package/cli/app-bundle-resources.ts +57 -0
  2. package/cli/commands/control.ts +12 -0
  3. package/cli/drivers/playwright.ts +39 -0
  4. package/cli/outbound-endpoints.ts +4 -2
  5. package/detox/motion-change.cjs +7 -5
  6. package/detox/motion-change.d.cts +1 -0
  7. package/detox/motion-leg-starts.cjs +20 -0
  8. package/detox/motion-leg-starts.d.cts +8 -0
  9. package/dist-lib/agent-daemon-client.cjs +1 -1
  10. package/dist-lib/agent-events.cjs +1 -1
  11. package/dist-lib/attached-projects.cjs +1 -1
  12. package/dist-lib/auth/shared-session.cjs +1 -1
  13. package/dist-lib/backend-origin.cjs +3 -3
  14. package/dist-lib/beta.cjs +1 -1
  15. package/dist-lib/beta.mjs +1 -1
  16. package/dist-lib/bridge-constants.cjs +1 -1
  17. package/dist-lib/bridge-contract-input.cjs +1 -1
  18. package/dist-lib/bridge-contract-input.mjs +1 -1
  19. package/dist-lib/bridge-contract.cjs +1 -1
  20. package/dist-lib/bridge-contract.mjs +1 -1
  21. package/dist-lib/bundle-channel.cjs +719 -572
  22. package/dist-lib/capture-contract.cjs +1 -1
  23. package/dist-lib/capture-contract.mjs +1 -1
  24. package/dist-lib/cloud-contract.cjs +1 -1
  25. package/dist-lib/cloud-contract.mjs +1 -1
  26. package/dist-lib/cloud-test-args.cjs +1 -1
  27. package/dist-lib/cloud-test-args.mjs +1 -1
  28. package/dist-lib/cloud.cjs +1 -1
  29. package/dist-lib/cloud.mjs +1 -1
  30. package/dist-lib/config.cjs +1 -1
  31. package/dist-lib/config.mjs +1 -1
  32. package/dist-lib/detox/index.cjs +7 -6
  33. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  34. package/dist-lib/expo-swift-bundle.cjs +656 -509
  35. package/dist-lib/expo-swift-metadata.cjs +1 -1
  36. package/dist-lib/expo-swift-metadata.mjs +1 -1
  37. package/dist-lib/home-paths.cjs +1 -1
  38. package/dist-lib/host/bridge-host.cjs +811 -658
  39. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  40. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  41. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  42. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  43. package/dist-lib/host/websocket-proxy.cjs +1 -1
  44. package/dist-lib/index.cjs +89 -41
  45. package/dist-lib/jump-to-source-babel.cjs +1 -1
  46. package/dist-lib/jump-to-source-native.cjs +1 -1
  47. package/dist-lib/kotlin-host.cjs +1 -1
  48. package/dist-lib/menu.cjs +14 -6
  49. package/dist-lib/menu.mjs +14 -6
  50. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  51. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  52. package/dist-lib/metro-production-bundle.cjs +1 -1
  53. package/dist-lib/metro-production-bundle.mjs +1 -1
  54. package/dist-lib/metro.cjs +88 -41
  55. package/dist-lib/native-app-identity-project.cjs +90 -41
  56. package/dist-lib/native-app-identity-project.mjs +89 -41
  57. package/dist-lib/native-app-identity.cjs +1 -1
  58. package/dist-lib/native-app-identity.mjs +1 -1
  59. package/dist-lib/native-firebase-metadata.cjs +1 -1
  60. package/dist-lib/native-firebase-metadata.mjs +1 -1
  61. package/dist-lib/plist.cjs +1 -1
  62. package/dist-lib/plist.mjs +1 -1
  63. package/dist-lib/profiles.cjs +1 -1
  64. package/dist-lib/public-brand.cjs +1 -1
  65. package/dist-lib/react-native-host-modules.cjs +1 -1
  66. package/dist-lib/react-native-host-modules.mjs +1 -1
  67. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  68. package/dist-lib/sdk.cjs +2 -1
  69. package/dist-lib/sdk.mjs +2 -1
  70. package/dist-lib/skills.cjs +1716 -1366
  71. package/dist-lib/swift-compile.cjs +297 -215
  72. package/dist-lib/swift-compile.mjs +315 -227
  73. package/dist-lib/swift-package.cjs +1 -1
  74. package/dist-lib/swift-package.mjs +1 -1
  75. package/dist-lib/swift-submit.cjs +1 -1
  76. package/dist-lib/swift-submit.mjs +1 -1
  77. package/dist-lib/swift-toolchain.cjs +1 -1
  78. package/dist-lib/swift.cjs +1 -1
  79. package/dist-lib/vite-swift.cjs +620 -473
  80. package/dist-lib/vite.cjs +1 -1
  81. package/dist-lib/worklet-executable.cjs +1 -1
  82. package/dist-lib/worklet-executable.mjs +1 -1
  83. package/package.json +1 -1
  84. package/src/appBundleResourcesContract.ts +51 -0
  85. package/src/backend-origin.ts +3 -1
  86. package/src/host/bridge-host.ts +17 -11
  87. package/src/host/staged-host-files.ts +28 -4
  88. package/src/launchMetadataContract.ts +1 -0
  89. package/src/menu.ts +12 -4
  90. package/src/native-app-identity-project.ts +47 -38
  91. package/src/runtime-delivery.ts +6 -7
  92. package/src/swift-compile.ts +18 -7
  93. package/src/swift-compiler-digest.ts +5 -3
  94. package/src/swift-objc-compile.ts +34 -4
  95. package/src/swift-root-lock.ts +241 -92
  96. package/src/xcode-project.ts +67 -4
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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;
@@ -1387,6 +1387,7 @@ var require_lib = __commonJS({
1387
1387
  var native_app_identity_project_exports = {};
1388
1388
  __export(native_app_identity_project_exports, {
1389
1389
  NativeAppTargetSelectionError: () => NativeAppTargetSelectionError,
1390
+ readIosAppTarget: () => readIosAppTarget,
1390
1391
  readNativeAppIdentityFromProject: () => readNativeAppIdentityFromProject,
1391
1392
  readNativeAppIdentityFromSources: () => readNativeAppIdentityFromSources,
1392
1393
  readNativeAppIdentityFromXcodeTarget: () => readNativeAppIdentityFromXcodeTarget
@@ -2886,6 +2887,9 @@ function targetSettings(ref, configuration, builtins, options = {}) {
2886
2887
  return applyOperator(get("PRODUCT_NAME"), "c99extidentifier");
2887
2888
  case "EXECUTABLE_NAME":
2888
2889
  return get("PRODUCT_NAME");
2890
+ // the native default of CoreBuildSystem.xcspec
2891
+ case "EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES":
2892
+ return "*.nib *.lproj *.framework *.gch *.xcode* *.xcassets *.icon (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj";
2889
2893
  case "AppIdentifierPrefix":
2890
2894
  case "TeamIdentifierPrefix": {
2891
2895
  const team = get("DEVELOPMENT_TEAM");
@@ -2908,6 +2912,45 @@ function settingList(value) {
2908
2912
  items2.push((quoted ?? plain).replace(/\\(.)/g, "$1"));
2909
2913
  return items2;
2910
2914
  }
2915
+ function expandSearchPath(directory, rules) {
2916
+ if (import_node_path2.default.basename(directory) !== "**") return [directory];
2917
+ const expanded = [];
2918
+ const seen = /* @__PURE__ */ new Set();
2919
+ const queue = [import_node_path2.default.dirname(directory)];
2920
+ for (let at = 0; at < queue.length; at++) {
2921
+ const current = queue[at];
2922
+ let real;
2923
+ try {
2924
+ real = import_node_fs.default.realpathSync(current);
2925
+ } catch {
2926
+ continue;
2927
+ }
2928
+ if (!import_node_fs.default.statSync(real).isDirectory() || seen.has(real)) continue;
2929
+ seen.add(real);
2930
+ expanded.push(current);
2931
+ for (const entry of import_node_fs.default.readdirSync(real, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
2932
+ if (entry.isSymbolicLink() ? !rules.followLinks : !entry.isDirectory()) continue;
2933
+ if (rules.excluded.some((pattern) => pattern.test(entry.name)) && !rules.included.some((pattern) => pattern.test(entry.name)))
2934
+ continue;
2935
+ queue.push(import_node_path2.default.join(current, entry.name));
2936
+ }
2937
+ }
2938
+ return expanded;
2939
+ }
2940
+ function recursiveSearchRules(settings) {
2941
+ const glob = (pattern) => new RegExp(
2942
+ `^${pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replaceAll("*", ".*").replaceAll("?", ".")}$`
2943
+ );
2944
+ return {
2945
+ excluded: settingList(settings("EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES")).map(
2946
+ glob
2947
+ ),
2948
+ included: settingList(settings("INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES")).map(
2949
+ glob
2950
+ ),
2951
+ followLinks: settings("RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS") !== "NO"
2952
+ };
2953
+ }
2911
2954
  function compilationConditions(settings) {
2912
2955
  const flags = settingList(settings("OTHER_SWIFT_FLAGS"));
2913
2956
  const defined = flags.flatMap(
@@ -3270,6 +3313,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3270
3313
  for (const file of read) xcconfigs.add(file);
3271
3314
  const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
3272
3315
  const members = targetMembers(ref, settings2, options, keys, xcconfigs);
3316
+ const searchRules = recursiveSearchRules(settings2);
3273
3317
  const implementations = members.allSources.filter(
3274
3318
  (file) => /\.(c|cc|cpp|cxx|m|mm)$/.test(file)
3275
3319
  );
@@ -3312,10 +3356,10 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
3312
3356
  headerSearchPaths: [
3313
3357
  ...settingList(settings2("HEADER_SEARCH_PATHS")),
3314
3358
  ...settingList(settings2("USER_HEADER_SEARCH_PATHS"))
3315
- ].map(absolute),
3316
- frameworkSearchPaths: settingList(settings2("FRAMEWORK_SEARCH_PATHS")).map(
3317
- absolute
3318
- ),
3359
+ ].flatMap((raw) => expandSearchPath(absolute(raw), searchRules)),
3360
+ frameworkSearchPaths: settingList(
3361
+ settings2("FRAMEWORK_SEARCH_PATHS")
3362
+ ).flatMap((raw) => expandSearchPath(absolute(raw), searchRules)),
3319
3363
  flags: [
3320
3364
  ...settings2("CLANG_ENABLE_OBJC_ARC") === "YES" ? ["-fobjc-arc"] : [],
3321
3365
  ...settings2("CLANG_ENABLE_OBJC_WEAK") === "YES" ? ["-fobjc-weak"] : [],
@@ -3688,42 +3732,8 @@ function readAndroidNativeAppIdentity(projectRoot, androidMergedManifest) {
3688
3732
  );
3689
3733
  }
3690
3734
  function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
3691
- const iosRoot = import_node_path3.default.join(projectRoot, "ios");
3692
- if (!import_node_fs2.default.existsSync(iosRoot)) return null;
3693
- const projects = import_node_fs2.default.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
3694
- if (projects.length === 0) return null;
3695
- if (projects.length > 1 && !iosTarget) {
3696
- throw new NativeAppTargetSelectionError(
3697
- `native app identity requires a selected Xcode project; set withPeach's iosTarget to an app target in one of: ${projects.map((entry) => entry.name).join(", ")}`
3698
- );
3699
- }
3700
- let project = projects[0];
3701
- if (iosTarget && projects.length > 1) {
3702
- const matches = projects.filter(
3703
- (entry) => listXcodeAppTargets(import_node_path3.default.join(iosRoot, entry.name), {
3704
- requireSources: false
3705
- }).includes(iosTarget)
3706
- );
3707
- if (matches.length === 0) {
3708
- throw new Error(`native app identity has no application target ${iosTarget}`);
3709
- }
3710
- if (matches.length > 1) {
3711
- throw new Error(
3712
- `native app identity target ${iosTarget} is ambiguous across ${matches.map((entry) => entry.name).join(", ")}`
3713
- );
3714
- }
3715
- project = matches[0];
3716
- }
3717
- const xcodeproj = import_node_path3.default.join(iosRoot, project.name);
3718
- const appTargets = listXcodeAppTargets(xcodeproj, { requireSources: false });
3719
- if (!iosTarget && appTargets.length > 1) {
3720
- throw new NativeAppTargetSelectionError(
3721
- `native app identity requires a selected app target; set withPeach's iosTarget to one of: ${appTargets.join(", ")}`
3722
- );
3723
- }
3724
- const app = readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
3725
- requireSources: false
3726
- });
3735
+ const app = readIosAppTarget(projectRoot, iosTarget);
3736
+ if (!app) return null;
3727
3737
  const identity = readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist);
3728
3738
  const projectManifestPath = import_node_path3.default.join(projectRoot, "package.json");
3729
3739
  const projectRequire = (0, import_node_module.createRequire)(projectManifestPath);
@@ -3776,9 +3786,48 @@ function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
3776
3786
  }
3777
3787
  return { ...identity, reanimatedStaticFeatureFlags: flags };
3778
3788
  }
3789
+ function readIosAppTarget(projectRoot, iosTarget) {
3790
+ const iosRoot = import_node_path3.default.join(projectRoot, "ios");
3791
+ if (!import_node_fs2.default.existsSync(iosRoot)) return null;
3792
+ const projects = import_node_fs2.default.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
3793
+ if (projects.length === 0) return null;
3794
+ if (projects.length > 1 && !iosTarget) {
3795
+ throw new NativeAppTargetSelectionError(
3796
+ `native app identity requires a selected Xcode project; set withPeach's iosTarget to an app target in one of: ${projects.map((entry) => entry.name).join(", ")}`
3797
+ );
3798
+ }
3799
+ let project = projects[0];
3800
+ if (iosTarget && projects.length > 1) {
3801
+ const matches = projects.filter(
3802
+ (entry) => listXcodeAppTargets(import_node_path3.default.join(iosRoot, entry.name), {
3803
+ requireSources: false
3804
+ }).includes(iosTarget)
3805
+ );
3806
+ if (matches.length === 0) {
3807
+ throw new Error(`native app identity has no application target ${iosTarget}`);
3808
+ }
3809
+ if (matches.length > 1) {
3810
+ throw new Error(
3811
+ `native app identity target ${iosTarget} is ambiguous across ${matches.map((entry) => entry.name).join(", ")}`
3812
+ );
3813
+ }
3814
+ project = matches[0];
3815
+ }
3816
+ const xcodeproj = import_node_path3.default.join(iosRoot, project.name);
3817
+ const appTargets = listXcodeAppTargets(xcodeproj, { requireSources: false });
3818
+ if (!iosTarget && appTargets.length > 1) {
3819
+ throw new NativeAppTargetSelectionError(
3820
+ `native app identity requires a selected app target; set withPeach's iosTarget to one of: ${appTargets.join(", ")}`
3821
+ );
3822
+ }
3823
+ return readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
3824
+ requireSources: false
3825
+ });
3826
+ }
3779
3827
  // Annotate the CommonJS export names for ESM import in node:
3780
3828
  0 && (module.exports = {
3781
3829
  NativeAppTargetSelectionError,
3830
+ readIosAppTarget,
3782
3831
  readNativeAppIdentityFromProject,
3783
3832
  readNativeAppIdentityFromSources,
3784
3833
  readNativeAppIdentityFromXcodeTarget
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/native-app-identity-project.ts
4
4
  import fs2 from "node:fs";
@@ -1495,6 +1495,9 @@ function targetSettings(ref, configuration, builtins, options = {}) {
1495
1495
  return applyOperator(get("PRODUCT_NAME"), "c99extidentifier");
1496
1496
  case "EXECUTABLE_NAME":
1497
1497
  return get("PRODUCT_NAME");
1498
+ // the native default of CoreBuildSystem.xcspec
1499
+ case "EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES":
1500
+ return "*.nib *.lproj *.framework *.gch *.xcode* *.xcassets *.icon (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj";
1498
1501
  case "AppIdentifierPrefix":
1499
1502
  case "TeamIdentifierPrefix": {
1500
1503
  const team = get("DEVELOPMENT_TEAM");
@@ -1517,6 +1520,45 @@ function settingList(value) {
1517
1520
  items2.push((quoted ?? plain).replace(/\\(.)/g, "$1"));
1518
1521
  return items2;
1519
1522
  }
1523
+ function expandSearchPath(directory, rules) {
1524
+ if (path2.basename(directory) !== "**") return [directory];
1525
+ const expanded = [];
1526
+ const seen = /* @__PURE__ */ new Set();
1527
+ const queue = [path2.dirname(directory)];
1528
+ for (let at = 0; at < queue.length; at++) {
1529
+ const current = queue[at];
1530
+ let real;
1531
+ try {
1532
+ real = fs.realpathSync(current);
1533
+ } catch {
1534
+ continue;
1535
+ }
1536
+ if (!fs.statSync(real).isDirectory() || seen.has(real)) continue;
1537
+ seen.add(real);
1538
+ expanded.push(current);
1539
+ for (const entry of fs.readdirSync(real, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1540
+ if (entry.isSymbolicLink() ? !rules.followLinks : !entry.isDirectory()) continue;
1541
+ if (rules.excluded.some((pattern) => pattern.test(entry.name)) && !rules.included.some((pattern) => pattern.test(entry.name)))
1542
+ continue;
1543
+ queue.push(path2.join(current, entry.name));
1544
+ }
1545
+ }
1546
+ return expanded;
1547
+ }
1548
+ function recursiveSearchRules(settings) {
1549
+ const glob = (pattern) => new RegExp(
1550
+ `^${pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replaceAll("*", ".*").replaceAll("?", ".")}$`
1551
+ );
1552
+ return {
1553
+ excluded: settingList(settings("EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES")).map(
1554
+ glob
1555
+ ),
1556
+ included: settingList(settings("INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES")).map(
1557
+ glob
1558
+ ),
1559
+ followLinks: settings("RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS") !== "NO"
1560
+ };
1561
+ }
1520
1562
  function compilationConditions(settings) {
1521
1563
  const flags = settingList(settings("OTHER_SWIFT_FLAGS"));
1522
1564
  const defined = flags.flatMap(
@@ -1879,6 +1921,7 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
1879
1921
  for (const file of read) xcconfigs.add(file);
1880
1922
  const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
1881
1923
  const members = targetMembers(ref, settings2, options, keys, xcconfigs);
1924
+ const searchRules = recursiveSearchRules(settings2);
1882
1925
  const implementations = members.allSources.filter(
1883
1926
  (file) => /\.(c|cc|cpp|cxx|m|mm)$/.test(file)
1884
1927
  );
@@ -1921,10 +1964,10 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
1921
1964
  headerSearchPaths: [
1922
1965
  ...settingList(settings2("HEADER_SEARCH_PATHS")),
1923
1966
  ...settingList(settings2("USER_HEADER_SEARCH_PATHS"))
1924
- ].map(absolute),
1925
- frameworkSearchPaths: settingList(settings2("FRAMEWORK_SEARCH_PATHS")).map(
1926
- absolute
1927
- ),
1967
+ ].flatMap((raw) => expandSearchPath(absolute(raw), searchRules)),
1968
+ frameworkSearchPaths: settingList(
1969
+ settings2("FRAMEWORK_SEARCH_PATHS")
1970
+ ).flatMap((raw) => expandSearchPath(absolute(raw), searchRules)),
1928
1971
  flags: [
1929
1972
  ...settings2("CLANG_ENABLE_OBJC_ARC") === "YES" ? ["-fobjc-arc"] : [],
1930
1973
  ...settings2("CLANG_ENABLE_OBJC_WEAK") === "YES" ? ["-fobjc-weak"] : [],
@@ -2297,42 +2340,8 @@ function readAndroidNativeAppIdentity(projectRoot, androidMergedManifest) {
2297
2340
  );
2298
2341
  }
2299
2342
  function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
2300
- const iosRoot = path3.join(projectRoot, "ios");
2301
- if (!fs2.existsSync(iosRoot)) return null;
2302
- const projects = fs2.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
2303
- if (projects.length === 0) return null;
2304
- if (projects.length > 1 && !iosTarget) {
2305
- throw new NativeAppTargetSelectionError(
2306
- `native app identity requires a selected Xcode project; set withPeach's iosTarget to an app target in one of: ${projects.map((entry) => entry.name).join(", ")}`
2307
- );
2308
- }
2309
- let project = projects[0];
2310
- if (iosTarget && projects.length > 1) {
2311
- const matches = projects.filter(
2312
- (entry) => listXcodeAppTargets(path3.join(iosRoot, entry.name), {
2313
- requireSources: false
2314
- }).includes(iosTarget)
2315
- );
2316
- if (matches.length === 0) {
2317
- throw new Error(`native app identity has no application target ${iosTarget}`);
2318
- }
2319
- if (matches.length > 1) {
2320
- throw new Error(
2321
- `native app identity target ${iosTarget} is ambiguous across ${matches.map((entry) => entry.name).join(", ")}`
2322
- );
2323
- }
2324
- project = matches[0];
2325
- }
2326
- const xcodeproj = path3.join(iosRoot, project.name);
2327
- const appTargets = listXcodeAppTargets(xcodeproj, { requireSources: false });
2328
- if (!iosTarget && appTargets.length > 1) {
2329
- throw new NativeAppTargetSelectionError(
2330
- `native app identity requires a selected app target; set withPeach's iosTarget to one of: ${appTargets.join(", ")}`
2331
- );
2332
- }
2333
- const app = readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
2334
- requireSources: false
2335
- });
2343
+ const app = readIosAppTarget(projectRoot, iosTarget);
2344
+ if (!app) return null;
2336
2345
  const identity = readNativeAppIdentityFromXcodeTarget(app, parseInfoPlist);
2337
2346
  const projectManifestPath = path3.join(projectRoot, "package.json");
2338
2347
  const projectRequire = createRequire(projectManifestPath);
@@ -2385,8 +2394,47 @@ function readIosNativeAppIdentity(projectRoot, parseInfoPlist, iosTarget) {
2385
2394
  }
2386
2395
  return { ...identity, reanimatedStaticFeatureFlags: flags };
2387
2396
  }
2397
+ function readIosAppTarget(projectRoot, iosTarget) {
2398
+ const iosRoot = path3.join(projectRoot, "ios");
2399
+ if (!fs2.existsSync(iosRoot)) return null;
2400
+ const projects = fs2.readdirSync(iosRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.endsWith(".xcodeproj"));
2401
+ if (projects.length === 0) return null;
2402
+ if (projects.length > 1 && !iosTarget) {
2403
+ throw new NativeAppTargetSelectionError(
2404
+ `native app identity requires a selected Xcode project; set withPeach's iosTarget to an app target in one of: ${projects.map((entry) => entry.name).join(", ")}`
2405
+ );
2406
+ }
2407
+ let project = projects[0];
2408
+ if (iosTarget && projects.length > 1) {
2409
+ const matches = projects.filter(
2410
+ (entry) => listXcodeAppTargets(path3.join(iosRoot, entry.name), {
2411
+ requireSources: false
2412
+ }).includes(iosTarget)
2413
+ );
2414
+ if (matches.length === 0) {
2415
+ throw new Error(`native app identity has no application target ${iosTarget}`);
2416
+ }
2417
+ if (matches.length > 1) {
2418
+ throw new Error(
2419
+ `native app identity target ${iosTarget} is ambiguous across ${matches.map((entry) => entry.name).join(", ")}`
2420
+ );
2421
+ }
2422
+ project = matches[0];
2423
+ }
2424
+ const xcodeproj = path3.join(iosRoot, project.name);
2425
+ const appTargets = listXcodeAppTargets(xcodeproj, { requireSources: false });
2426
+ if (!iosTarget && appTargets.length > 1) {
2427
+ throw new NativeAppTargetSelectionError(
2428
+ `native app identity requires a selected app target; set withPeach's iosTarget to one of: ${appTargets.join(", ")}`
2429
+ );
2430
+ }
2431
+ return readXcodeAppTarget(xcodeproj, iosTarget ?? appTargets[0], "Release", {
2432
+ requireSources: false
2433
+ });
2434
+ }
2388
2435
  export {
2389
2436
  NativeAppTargetSelectionError,
2437
+ readIosAppTarget,
2390
2438
  readNativeAppIdentityFromProject,
2391
2439
  readNativeAppIdentityFromSources,
2392
2440
  readNativeAppIdentityFromXcodeTarget
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/android-string-value.ts
4
4
  function compileAndroidStringValue(text, where) {
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/bundleGlobalFooter.ts
4
4
  function findBundleFooter(source, prefix) {
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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;
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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;
@@ -2694,6 +2694,7 @@ var LAUNCH_METADATA_KEYS = [
2694
2694
  "appFonts",
2695
2695
  "appSplash",
2696
2696
  "appCatalog",
2697
+ "appBundleResources",
2697
2698
  "nativeAppIdentity",
2698
2699
  "nativeFirebase",
2699
2700
  "appManifest",
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1641 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1644 | (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);
@@ -2589,6 +2589,7 @@ var LAUNCH_METADATA_KEYS = [
2589
2589
  "appFonts",
2590
2590
  "appSplash",
2591
2591
  "appCatalog",
2592
+ "appBundleResources",
2592
2593
  "nativeAppIdentity",
2593
2594
  "nativeFirebase",
2594
2595
  "appManifest",