peachsim 0.1.934 → 0.1.936

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 (79) hide show
  1. package/dist-lib/agent-daemon-client.cjs +1 -1
  2. package/dist-lib/agent-events.cjs +1 -1
  3. package/dist-lib/agent-identity.cjs +1 -1
  4. package/dist-lib/agent-sessions.cjs +1 -1
  5. package/dist-lib/attached-projects.cjs +1 -1
  6. package/dist-lib/auth/shared-session.cjs +1 -1
  7. package/dist-lib/backend-origin.cjs +1 -1
  8. package/dist-lib/beta.cjs +1 -1
  9. package/dist-lib/beta.mjs +1 -1
  10. package/dist-lib/bridge-constants.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.mjs +1 -1
  13. package/dist-lib/bridge-contract.cjs +1 -1
  14. package/dist-lib/bridge-contract.mjs +1 -1
  15. package/dist-lib/bundle-channel.cjs +22 -2
  16. package/dist-lib/capture-contract.cjs +1 -1
  17. package/dist-lib/capture-contract.mjs +1 -1
  18. package/dist-lib/cli-constants.cjs +1 -1
  19. package/dist-lib/cloud-contract.cjs +1 -1
  20. package/dist-lib/cloud-contract.mjs +1 -1
  21. package/dist-lib/cloud-test-args.cjs +1 -1
  22. package/dist-lib/cloud-test-args.mjs +1 -1
  23. package/dist-lib/cloud.cjs +1 -1
  24. package/dist-lib/cloud.mjs +1 -1
  25. package/dist-lib/config.cjs +1 -1
  26. package/dist-lib/detox/index.cjs +1 -1
  27. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  28. package/dist-lib/expo-swift-bundle.cjs +22 -2
  29. package/dist-lib/expo-swift-metadata.cjs +1 -1
  30. package/dist-lib/expo-swift-metadata.mjs +1 -1
  31. package/dist-lib/home-paths.cjs +1 -1
  32. package/dist-lib/host/bridge-host.cjs +22 -2
  33. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  34. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  36. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  37. package/dist-lib/host/websocket-proxy.cjs +1 -1
  38. package/dist-lib/index.cjs +1 -1
  39. package/dist-lib/jump-to-source-babel.cjs +1 -1
  40. package/dist-lib/jump-to-source-native.cjs +1 -1
  41. package/dist-lib/kotlin-host.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/native-app-identity.cjs +40 -3
  50. package/dist-lib/native-app-identity.mjs +36 -2
  51. package/dist-lib/native-firebase-metadata.cjs +1 -1
  52. package/dist-lib/native-firebase-metadata.mjs +1 -1
  53. package/dist-lib/plist.cjs +1 -1
  54. package/dist-lib/plist.mjs +1 -1
  55. package/dist-lib/profiles.cjs +1 -1
  56. package/dist-lib/public-brand.cjs +1 -1
  57. package/dist-lib/react-native-host-modules.cjs +1 -1
  58. package/dist-lib/react-native-host-modules.mjs +1 -1
  59. package/dist-lib/render-mode.cjs +1 -1
  60. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  61. package/dist-lib/sdk.cjs +1 -1
  62. package/dist-lib/sdk.mjs +1 -1
  63. package/dist-lib/skills.cjs +22 -2
  64. package/dist-lib/swift-compile.cjs +1 -1
  65. package/dist-lib/swift-compile.mjs +1 -1
  66. package/dist-lib/swift-package.cjs +1 -1
  67. package/dist-lib/swift-package.mjs +1 -1
  68. package/dist-lib/swift-submit.cjs +1 -1
  69. package/dist-lib/swift-submit.mjs +1 -1
  70. package/dist-lib/swift-toolchain.cjs +1 -1
  71. package/dist-lib/swift.cjs +1 -1
  72. package/dist-lib/vite-swift.cjs +22 -2
  73. package/dist-lib/vite.cjs +1 -1
  74. package/dist-lib/worklet-executable.cjs +1 -1
  75. package/dist-lib/worklet-executable.mjs +1 -1
  76. package/package.json +1 -1
  77. package/src/native-app-identity.ts +47 -5
  78. package/src/swift-host.ts +14 -1
  79. package/src/xcode-project.ts +24 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var REFUSED_PERFORM_STEP_TYPES = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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;
@@ -7296,6 +7296,21 @@ function workspaceReferences(workspace) {
7296
7296
  }
7297
7297
  return references;
7298
7298
  }
7299
+ function enclosingXcodeWorkspace(xcodeproj) {
7300
+ const project = import_node_fs13.default.realpathSync(xcodeproj);
7301
+ for (let dir = import_node_path14.default.dirname(project); ; dir = import_node_path14.default.dirname(dir)) {
7302
+ for (const name2 of import_node_fs13.default.readdirSync(dir)) {
7303
+ if (!name2.endsWith(".xcworkspace")) continue;
7304
+ const workspace = import_node_path14.default.join(dir, name2);
7305
+ if (!import_node_fs13.default.existsSync(import_node_path14.default.join(workspace, "contents.xcworkspacedata"))) continue;
7306
+ if (workspaceReferences(workspace).some(
7307
+ (reference) => import_node_fs13.default.existsSync(reference) && import_node_fs13.default.realpathSync(reference) === project
7308
+ ))
7309
+ return workspace;
7310
+ }
7311
+ if (import_node_fs13.default.existsSync(import_node_path14.default.join(dir, ".git")) || import_node_path14.default.dirname(dir) === dir) return null;
7312
+ }
7313
+ }
7299
7314
  function xcodeProjectFile(xcodeproj) {
7300
7315
  for (const name2 of ["project.pbxproj", "project.xcproj"]) {
7301
7316
  const file = import_node_path14.default.join(xcodeproj, name2);
@@ -8354,12 +8369,17 @@ async function missingModulesMessage(packagePath, missing) {
8354
8369
  })
8355
8370
  );
8356
8371
  const width = Math.max(...[...missing.keys()].map((name2) => name2.length));
8372
+ const opened = xcodeProjects.get(packagePath)?.xcodeproj;
8373
+ const workspace = opened?.endsWith(".xcodeproj") ? enclosingXcodeWorkspace(opened) : null;
8357
8374
  return [
8358
8375
  `Peach does not provide ${missing.size} module${missing.size === 1 ? "" : "s"} this app imports:`,
8359
8376
  ...[...missing].map(([name2, files2]) => {
8360
8377
  const gap = gaps.get(name2);
8361
8378
  return ` ${name2.padEnd(width)} ${files2.length} file${files2.length === 1 ? "" : "s"}${gap ? `, ${gap.source.includes("://") ? `package ${gap.source}` : gap.source.startsWith("/") ? `package ${import_node_path15.default.relative(packagePath, gap.source) || "."}` : gap.source} (${gap.reason})` : ""}`;
8362
- })
8379
+ }),
8380
+ ...workspace ? [
8381
+ `${import_node_path15.default.basename(opened)} is part of ${import_node_path15.default.relative(process.cwd(), workspace)}, which holds its local packages and Package.resolved pins; pass the workspace to build what Xcode builds there.`
8382
+ ] : []
8363
8383
  ].join("\n");
8364
8384
  }
8365
8385
  async function compileRemote(packagePath, snapshot, hosted) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/capture-contract.ts
4
4
  var RNX_SCREEN_CAPTURE_VERSION = 1;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-test-args.ts
4
4
  var CLOUD_TEST_ARGS_MAX_COUNT = 32;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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;
@@ -7151,6 +7151,21 @@ function workspaceReferences(workspace) {
7151
7151
  }
7152
7152
  return references;
7153
7153
  }
7154
+ function enclosingXcodeWorkspace(xcodeproj) {
7155
+ const project = import_node_fs13.default.realpathSync(xcodeproj);
7156
+ for (let dir = import_node_path14.default.dirname(project); ; dir = import_node_path14.default.dirname(dir)) {
7157
+ for (const name2 of import_node_fs13.default.readdirSync(dir)) {
7158
+ if (!name2.endsWith(".xcworkspace")) continue;
7159
+ const workspace = import_node_path14.default.join(dir, name2);
7160
+ if (!import_node_fs13.default.existsSync(import_node_path14.default.join(workspace, "contents.xcworkspacedata"))) continue;
7161
+ if (workspaceReferences(workspace).some(
7162
+ (reference) => import_node_fs13.default.existsSync(reference) && import_node_fs13.default.realpathSync(reference) === project
7163
+ ))
7164
+ return workspace;
7165
+ }
7166
+ if (import_node_fs13.default.existsSync(import_node_path14.default.join(dir, ".git")) || import_node_path14.default.dirname(dir) === dir) return null;
7167
+ }
7168
+ }
7154
7169
  var loaded = /* @__PURE__ */ new Map();
7155
7170
  function xcodeProjectFile(xcodeproj) {
7156
7171
  for (const name2 of ["project.pbxproj", "project.xcproj"]) {
@@ -8248,12 +8263,17 @@ async function missingModulesMessage(packagePath, missing) {
8248
8263
  })
8249
8264
  );
8250
8265
  const width = Math.max(...[...missing.keys()].map((name2) => name2.length));
8266
+ const opened = xcodeProjects.get(packagePath)?.xcodeproj;
8267
+ const workspace = opened?.endsWith(".xcodeproj") ? enclosingXcodeWorkspace(opened) : null;
8251
8268
  return [
8252
8269
  `Peach does not provide ${missing.size} module${missing.size === 1 ? "" : "s"} this app imports:`,
8253
8270
  ...[...missing].map(([name2, files2]) => {
8254
8271
  const gap = gaps.get(name2);
8255
8272
  return ` ${name2.padEnd(width)} ${files2.length} file${files2.length === 1 ? "" : "s"}${gap ? `, ${gap.source.includes("://") ? `package ${gap.source}` : gap.source.startsWith("/") ? `package ${import_node_path15.default.relative(packagePath, gap.source) || "."}` : gap.source} (${gap.reason})` : ""}`;
8256
- })
8273
+ }),
8274
+ ...workspace ? [
8275
+ `${import_node_path15.default.basename(opened)} is part of ${import_node_path15.default.relative(process.cwd(), workspace)}, which holds its local packages and Package.resolved pins; pass the workspace to build what Xcode builds there.`
8276
+ ] : []
8257
8277
  ].join("\n");
8258
8278
  }
8259
8279
  async function compileRemote(packagePath, snapshot, hosted) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/expoSwiftContract.ts
4
4
  function record(value) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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;
@@ -16400,6 +16400,21 @@ function workspaceReferences(workspace) {
16400
16400
  }
16401
16401
  return references;
16402
16402
  }
16403
+ function enclosingXcodeWorkspace(xcodeproj) {
16404
+ const project = import_node_fs18.default.realpathSync(xcodeproj);
16405
+ for (let dir = import_node_path19.default.dirname(project); ; dir = import_node_path19.default.dirname(dir)) {
16406
+ for (const name2 of import_node_fs18.default.readdirSync(dir)) {
16407
+ if (!name2.endsWith(".xcworkspace")) continue;
16408
+ const workspace = import_node_path19.default.join(dir, name2);
16409
+ if (!import_node_fs18.default.existsSync(import_node_path19.default.join(workspace, "contents.xcworkspacedata"))) continue;
16410
+ if (workspaceReferences(workspace).some(
16411
+ (reference) => import_node_fs18.default.existsSync(reference) && import_node_fs18.default.realpathSync(reference) === project
16412
+ ))
16413
+ return workspace;
16414
+ }
16415
+ if (import_node_fs18.default.existsSync(import_node_path19.default.join(dir, ".git")) || import_node_path19.default.dirname(dir) === dir) return null;
16416
+ }
16417
+ }
16403
16418
  var loaded = /* @__PURE__ */ new Map();
16404
16419
  function xcodeProjectFile(xcodeproj) {
16405
16420
  for (const name2 of ["project.pbxproj", "project.xcproj"]) {
@@ -17501,12 +17516,17 @@ async function missingModulesMessage(packagePath, missing) {
17501
17516
  })
17502
17517
  );
17503
17518
  const width = Math.max(...[...missing.keys()].map((name2) => name2.length));
17519
+ const opened = xcodeProjects.get(packagePath)?.xcodeproj;
17520
+ const workspace = opened?.endsWith(".xcodeproj") ? enclosingXcodeWorkspace(opened) : null;
17504
17521
  return [
17505
17522
  `Peach does not provide ${missing.size} module${missing.size === 1 ? "" : "s"} this app imports:`,
17506
17523
  ...[...missing].map(([name2, files2]) => {
17507
17524
  const gap = gaps.get(name2);
17508
17525
  return ` ${name2.padEnd(width)} ${files2.length} file${files2.length === 1 ? "" : "s"}${gap ? `, ${gap.source.includes("://") ? `package ${gap.source}` : gap.source.startsWith("/") ? `package ${import_node_path20.default.relative(packagePath, gap.source) || "."}` : gap.source} (${gap.reason})` : ""}`;
17509
- })
17526
+ }),
17527
+ ...workspace ? [
17528
+ `${import_node_path20.default.basename(opened)} is part of ${import_node_path20.default.relative(process.cwd(), workspace)}, which holds its local packages and Package.resolved pins; pass the workspace to build what Xcode builds there.`
17529
+ ] : []
17510
17530
  ].join("\n");
17511
17531
  }
17512
17532
  async function compileRemote(packagePath, snapshot, hosted) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_NATIVE_USER_AGENT_HEADER = "x-sootsim-native-user-agent";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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/menu.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "Peach";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/is-record.ts
4
4
  function isRecord(value) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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;
@@ -22,20 +22,24 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  // src/native-app-identity.ts
23
23
  var native_app_identity_exports = {};
24
24
  __export(native_app_identity_exports, {
25
+ NATIVE_APP_IDENTITY_HEADER: () => NATIVE_APP_IDENTITY_HEADER,
25
26
  applyNativeAppIdentity: () => applyNativeAppIdentity,
26
27
  canExtractNativeAppIdentity: () => canExtractNativeAppIdentity,
27
28
  createNativeAppIdentityFooter: () => createNativeAppIdentityFooter,
29
+ createNativeAppIdentityHeader: () => createNativeAppIdentityHeader,
28
30
  detachNativeAppIdentityFooter: () => detachNativeAppIdentityFooter,
29
31
  extractNativeAppIdentityFromFiles: () => extractNativeAppIdentityFromFiles,
30
32
  getAppliedNativeAppIdentity: () => getAppliedNativeAppIdentity,
31
33
  insertNativeAppIdentityFooter: () => insertNativeAppIdentityFooter,
32
34
  isNativeAppIdentity: () => isNativeAppIdentity,
33
35
  readNativeAppIdentity: () => readNativeAppIdentity,
34
- readNativeAppIdentityFooter: () => readNativeAppIdentityFooter
36
+ readNativeAppIdentityFooter: () => readNativeAppIdentityFooter,
37
+ readNativeAppIdentityFromBundle: () => readNativeAppIdentityFromBundle
35
38
  });
36
39
  module.exports = __toCommonJS(native_app_identity_exports);
37
40
  var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
38
41
  var METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
42
+ var NATIVE_APP_IDENTITY_HEADER = "Peach-Native-App-Identity";
39
43
  function isRecord(value) {
40
44
  return typeof value === "object" && value !== null && !Array.isArray(value);
41
45
  }
@@ -82,6 +86,36 @@ function readNativeAppIdentity(value) {
82
86
  ...value.urlQuerySchemes === void 0 ? {} : { urlQuerySchemes: [...value.urlQuerySchemes] }
83
87
  };
84
88
  }
89
+ function createNativeAppIdentityHeader(identity) {
90
+ return encodeURIComponent(JSON.stringify(readNativeAppIdentity(identity)));
91
+ }
92
+ function equalIdentityValues(left, right) {
93
+ if (left === right) return true;
94
+ if (Array.isArray(left) && Array.isArray(right)) {
95
+ return left.length === right.length && left.every((value, index) => equalIdentityValues(value, right[index]));
96
+ }
97
+ if (!isRecord(left) || !isRecord(right)) return false;
98
+ const keys = Object.keys(left);
99
+ return keys.length === Object.keys(right).length && keys.every(
100
+ (key) => Object.hasOwn(right, key) && equalIdentityValues(left[key], right[key])
101
+ );
102
+ }
103
+ function readNativeAppIdentityFromBundle(source, header) {
104
+ const footer = readNativeAppIdentityFooter(source);
105
+ if (header === null) return readNativeAppIdentity(footer);
106
+ let value;
107
+ try {
108
+ value = JSON.parse(decodeURIComponent(header));
109
+ } catch {
110
+ throw new Error("native app identity response header is malformed");
111
+ }
112
+ const identity = readNativeAppIdentity(value);
113
+ if (!identity) throw new Error("native app identity response header is malformed");
114
+ if (footer && !equalIdentityValues(identity, readNativeAppIdentity(footer))) {
115
+ throw new Error("native app identity response header conflicts with bundle footer");
116
+ }
117
+ return identity;
118
+ }
85
119
  function applyNativeAppIdentity(identity) {
86
120
  const globals = globalThis;
87
121
  if (identity) globals.__sootsim_native_app_identity = identity;
@@ -324,14 +358,17 @@ function extractNativeAppIdentityFromFiles(files, platform, parseInfoPlist) {
324
358
  }
325
359
  // Annotate the CommonJS export names for ESM import in node:
326
360
  0 && (module.exports = {
361
+ NATIVE_APP_IDENTITY_HEADER,
327
362
  applyNativeAppIdentity,
328
363
  canExtractNativeAppIdentity,
329
364
  createNativeAppIdentityFooter,
365
+ createNativeAppIdentityHeader,
330
366
  detachNativeAppIdentityFooter,
331
367
  extractNativeAppIdentityFromFiles,
332
368
  getAppliedNativeAppIdentity,
333
369
  insertNativeAppIdentityFooter,
334
370
  isNativeAppIdentity,
335
371
  readNativeAppIdentity,
336
- readNativeAppIdentityFooter
372
+ readNativeAppIdentityFooter,
373
+ readNativeAppIdentityFromBundle
337
374
  });
@@ -1,8 +1,9 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/native-app-identity.ts
4
4
  var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
5
5
  var METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
6
+ var NATIVE_APP_IDENTITY_HEADER = "Peach-Native-App-Identity";
6
7
  function isRecord(value) {
7
8
  return typeof value === "object" && value !== null && !Array.isArray(value);
8
9
  }
@@ -49,6 +50,36 @@ function readNativeAppIdentity(value) {
49
50
  ...value.urlQuerySchemes === void 0 ? {} : { urlQuerySchemes: [...value.urlQuerySchemes] }
50
51
  };
51
52
  }
53
+ function createNativeAppIdentityHeader(identity) {
54
+ return encodeURIComponent(JSON.stringify(readNativeAppIdentity(identity)));
55
+ }
56
+ function equalIdentityValues(left, right) {
57
+ if (left === right) return true;
58
+ if (Array.isArray(left) && Array.isArray(right)) {
59
+ return left.length === right.length && left.every((value, index) => equalIdentityValues(value, right[index]));
60
+ }
61
+ if (!isRecord(left) || !isRecord(right)) return false;
62
+ const keys = Object.keys(left);
63
+ return keys.length === Object.keys(right).length && keys.every(
64
+ (key) => Object.hasOwn(right, key) && equalIdentityValues(left[key], right[key])
65
+ );
66
+ }
67
+ function readNativeAppIdentityFromBundle(source, header) {
68
+ const footer = readNativeAppIdentityFooter(source);
69
+ if (header === null) return readNativeAppIdentity(footer);
70
+ let value;
71
+ try {
72
+ value = JSON.parse(decodeURIComponent(header));
73
+ } catch {
74
+ throw new Error("native app identity response header is malformed");
75
+ }
76
+ const identity = readNativeAppIdentity(value);
77
+ if (!identity) throw new Error("native app identity response header is malformed");
78
+ if (footer && !equalIdentityValues(identity, readNativeAppIdentity(footer))) {
79
+ throw new Error("native app identity response header conflicts with bundle footer");
80
+ }
81
+ return identity;
82
+ }
52
83
  function applyNativeAppIdentity(identity) {
53
84
  const globals = globalThis;
54
85
  if (identity) globals.__sootsim_native_app_identity = identity;
@@ -290,14 +321,17 @@ function extractNativeAppIdentityFromFiles(files, platform, parseInfoPlist) {
290
321
  return canExtractNativeAppIdentity(platform) ? nativeAppIdentityFromIos(files, parseInfoPlist) : null;
291
322
  }
292
323
  export {
324
+ NATIVE_APP_IDENTITY_HEADER,
293
325
  applyNativeAppIdentity,
294
326
  canExtractNativeAppIdentity,
295
327
  createNativeAppIdentityFooter,
328
+ createNativeAppIdentityHeader,
296
329
  detachNativeAppIdentityFooter,
297
330
  extractNativeAppIdentityFromFiles,
298
331
  getAppliedNativeAppIdentity,
299
332
  insertNativeAppIdentityFooter,
300
333
  isNativeAppIdentity,
301
334
  readNativeAppIdentity,
302
- readNativeAppIdentityFooter
335
+ readNativeAppIdentityFooter,
336
+ readNativeAppIdentityFromBundle
303
337
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/native-firebase-metadata.ts
4
4
  var PREFIX = "globalThis.__peachNativeFirebaseConfig=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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;
@@ -36372,6 +36372,21 @@ function workspaceReferences(workspace) {
36372
36372
  }
36373
36373
  return references;
36374
36374
  }
36375
+ function enclosingXcodeWorkspace(xcodeproj) {
36376
+ const project = import_node_fs18.default.realpathSync(xcodeproj);
36377
+ for (let dir = import_node_path19.default.dirname(project); ; dir = import_node_path19.default.dirname(dir)) {
36378
+ for (const name2 of import_node_fs18.default.readdirSync(dir)) {
36379
+ if (!name2.endsWith(".xcworkspace")) continue;
36380
+ const workspace = import_node_path19.default.join(dir, name2);
36381
+ if (!import_node_fs18.default.existsSync(import_node_path19.default.join(workspace, "contents.xcworkspacedata"))) continue;
36382
+ if (workspaceReferences(workspace).some(
36383
+ (reference) => import_node_fs18.default.existsSync(reference) && import_node_fs18.default.realpathSync(reference) === project
36384
+ ))
36385
+ return workspace;
36386
+ }
36387
+ if (import_node_fs18.default.existsSync(import_node_path19.default.join(dir, ".git")) || import_node_path19.default.dirname(dir) === dir) return null;
36388
+ }
36389
+ }
36375
36390
  function xcodeProjectFile(xcodeproj) {
36376
36391
  for (const name2 of ["project.pbxproj", "project.xcproj"]) {
36377
36392
  const file = import_node_path19.default.join(xcodeproj, name2);
@@ -37436,12 +37451,17 @@ async function missingModulesMessage(packagePath, missing) {
37436
37451
  })
37437
37452
  );
37438
37453
  const width = Math.max(...[...missing.keys()].map((name2) => name2.length));
37454
+ const opened = xcodeProjects.get(packagePath)?.xcodeproj;
37455
+ const workspace = opened?.endsWith(".xcodeproj") ? enclosingXcodeWorkspace(opened) : null;
37439
37456
  return [
37440
37457
  `Peach does not provide ${missing.size} module${missing.size === 1 ? "" : "s"} this app imports:`,
37441
37458
  ...[...missing].map(([name2, files2]) => {
37442
37459
  const gap = gaps.get(name2);
37443
37460
  return ` ${name2.padEnd(width)} ${files2.length} file${files2.length === 1 ? "" : "s"}${gap ? `, ${gap.source.includes("://") ? `package ${gap.source}` : gap.source.startsWith("/") ? `package ${import_node_path20.default.relative(packagePath, gap.source) || "."}` : gap.source} (${gap.reason})` : ""}`;
37444
- })
37461
+ }),
37462
+ ...workspace ? [
37463
+ `${import_node_path20.default.basename(opened)} is part of ${import_node_path20.default.relative(process.cwd(), workspace)}, which holds its local packages and Package.resolved pins; pass the workspace to build what Xcode builds there.`
37464
+ ] : []
37445
37465
  ].join("\n");
37446
37466
  }
37447
37467
  async function compileRemote(packagePath, snapshot, hosted) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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;
@@ -7144,6 +7144,21 @@ function workspaceReferences(workspace) {
7144
7144
  }
7145
7145
  return references;
7146
7146
  }
7147
+ function enclosingXcodeWorkspace(xcodeproj) {
7148
+ const project = import_node_fs13.default.realpathSync(xcodeproj);
7149
+ for (let dir = import_node_path14.default.dirname(project); ; dir = import_node_path14.default.dirname(dir)) {
7150
+ for (const name2 of import_node_fs13.default.readdirSync(dir)) {
7151
+ if (!name2.endsWith(".xcworkspace")) continue;
7152
+ const workspace = import_node_path14.default.join(dir, name2);
7153
+ if (!import_node_fs13.default.existsSync(import_node_path14.default.join(workspace, "contents.xcworkspacedata"))) continue;
7154
+ if (workspaceReferences(workspace).some(
7155
+ (reference) => import_node_fs13.default.existsSync(reference) && import_node_fs13.default.realpathSync(reference) === project
7156
+ ))
7157
+ return workspace;
7158
+ }
7159
+ if (import_node_fs13.default.existsSync(import_node_path14.default.join(dir, ".git")) || import_node_path14.default.dirname(dir) === dir) return null;
7160
+ }
7161
+ }
7147
7162
  var loaded = /* @__PURE__ */ new Map();
7148
7163
  function xcodeProjectFile(xcodeproj) {
7149
7164
  for (const name2 of ["project.pbxproj", "project.xcproj"]) {
@@ -8256,12 +8271,17 @@ async function missingModulesMessage(packagePath, missing) {
8256
8271
  })
8257
8272
  );
8258
8273
  const width = Math.max(...[...missing.keys()].map((name2) => name2.length));
8274
+ const opened = xcodeProjects.get(packagePath)?.xcodeproj;
8275
+ const workspace = opened?.endsWith(".xcodeproj") ? enclosingXcodeWorkspace(opened) : null;
8259
8276
  return [
8260
8277
  `Peach does not provide ${missing.size} module${missing.size === 1 ? "" : "s"} this app imports:`,
8261
8278
  ...[...missing].map(([name2, files2]) => {
8262
8279
  const gap = gaps.get(name2);
8263
8280
  return ` ${name2.padEnd(width)} ${files2.length} file${files2.length === 1 ? "" : "s"}${gap ? `, ${gap.source.includes("://") ? `package ${gap.source}` : gap.source.startsWith("/") ? `package ${import_node_path15.default.relative(packagePath, gap.source) || "."}` : gap.source} (${gap.reason})` : ""}`;
8264
- })
8281
+ }),
8282
+ ...workspace ? [
8283
+ `${import_node_path15.default.basename(opened)} is part of ${import_node_path15.default.relative(process.cwd(), workspace)}, which holds its local packages and Package.resolved pins; pass the workspace to build what Xcode builds there.`
8284
+ ] : []
8265
8285
  ].join("\n");
8266
8286
  }
8267
8287
  async function compileRemote(packagePath, snapshot, hosted) {
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.936 | (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.934",
3
+ "version": "0.1.936",
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",
@@ -3,11 +3,9 @@
3
3
  // against the Xcode Release build settings, or `android/app/build.gradle`), so
4
4
  // a simulator tenant reports the same identity the native Release build does.
5
5
  //
6
- // the values travel in a footer a bundle builder appends to the artifact — the
7
- // same transport shape the Metro module identity footer already uses — and the
8
- // tenant boot reads it from the bundle text before the guest evaluates, then
9
- // stores it on the tenant realm for the native app-information seams. a bundle
10
- // with no native identity footer leaves every seam exactly where it was.
6
+ // the values travel in a bundle footer or a response header bound to unchanged
7
+ // artifact bytes. tenant boot validates both before evaluation and clears the
8
+ // realm store when neither carries identity.
11
9
 
12
10
  export type NativeAppIdentityPlatform = 'ios' | 'android'
13
11
 
@@ -32,6 +30,7 @@ export type NativeAppIdentityFiles = Record<string, string>
32
30
  const NATIVE_APP_IDENTITY_PREFIX = 'globalThis.__sootsimNativeAppIdentity='
33
31
  const METRO_MODULE_PATHS_PREFIX = 'globalThis.__sootsimModulePaths='
34
32
  const APPLIED_NATIVE_APP_IDENTITY_KEY = '__sootsim_native_app_identity'
33
+ export const NATIVE_APP_IDENTITY_HEADER = 'Peach-Native-App-Identity'
35
34
 
36
35
  interface NativeAppIdentityGlobals {
37
36
  __sootsim_native_app_identity?: NativeAppIdentity | null
@@ -99,6 +98,49 @@ export function readNativeAppIdentity(value: unknown): NativeAppIdentity | null
99
98
  }
100
99
  }
101
100
 
101
+ // response metadata carries binary configuration without changing guest bytes.
102
+ export function createNativeAppIdentityHeader(identity: NativeAppIdentity): string {
103
+ return encodeURIComponent(JSON.stringify(readNativeAppIdentity(identity)))
104
+ }
105
+
106
+ function equalIdentityValues(left: unknown, right: unknown): boolean {
107
+ if (left === right) return true
108
+ if (Array.isArray(left) && Array.isArray(right)) {
109
+ return (
110
+ left.length === right.length &&
111
+ left.every((value, index) => equalIdentityValues(value, right[index]))
112
+ )
113
+ }
114
+ if (!isRecord(left) || !isRecord(right)) return false
115
+ const keys = Object.keys(left)
116
+ return (
117
+ keys.length === Object.keys(right).length &&
118
+ keys.every(
119
+ (key) => Object.hasOwn(right, key) && equalIdentityValues(left[key], right[key]),
120
+ )
121
+ )
122
+ }
123
+
124
+ export function readNativeAppIdentityFromBundle(
125
+ source: string,
126
+ header: string | null,
127
+ ): NativeAppIdentity | null {
128
+ const footer = readNativeAppIdentityFooter(source)
129
+ if (header === null) return readNativeAppIdentity(footer)
130
+ let value: unknown
131
+ try {
132
+ value = JSON.parse(decodeURIComponent(header))
133
+ } catch {
134
+ throw new Error('native app identity response header is malformed')
135
+ }
136
+ const identity = readNativeAppIdentity(value)
137
+ if (!identity) throw new Error('native app identity response header is malformed')
138
+ if (footer && !equalIdentityValues(identity, readNativeAppIdentity(footer))) {
139
+ throw new Error('native app identity response header conflicts with bundle footer')
140
+ }
141
+ return identity
142
+ }
143
+
102
144
  // the one realm store every seam reads. set by the tenant boot before the
103
145
  // guest evaluates, cleared on a boot without an identity so a previous app's
104
146
  // identity can never leak into the next load.
package/src/swift-host.ts CHANGED
@@ -54,7 +54,11 @@ import {
54
54
  type SwiftImageUpload,
55
55
  type SwiftNativeModules,
56
56
  } from './swift-submit'
57
- import { readXcodeAppTarget, type XcodeAppTarget } from './xcode-project'
57
+ import {
58
+ enclosingXcodeWorkspace,
59
+ readXcodeAppTarget,
60
+ type XcodeAppTarget,
61
+ } from './xcode-project'
58
62
  import type { SwiftEntryModuleArgs } from '../../sootsim-swift/src/entryModule'
59
63
  import type {
60
64
  AppCatalogColor,
@@ -1097,12 +1101,21 @@ async function missingModulesMessage(
1097
1101
  }),
1098
1102
  )
1099
1103
  const width = Math.max(...[...missing.keys()].map((name) => name.length))
1104
+ const opened = xcodeProjects.get(packagePath)?.xcodeproj
1105
+ const workspace = opened?.endsWith('.xcodeproj')
1106
+ ? enclosingXcodeWorkspace(opened)
1107
+ : null
1100
1108
  return [
1101
1109
  `Peach does not provide ${missing.size} module${missing.size === 1 ? '' : 's'} this app imports:`,
1102
1110
  ...[...missing].map(([name, files]) => {
1103
1111
  const gap = gaps.get(name)
1104
1112
  return ` ${name.padEnd(width)} ${files.length} file${files.length === 1 ? '' : 's'}${gap ? `, ${gap.source.includes('://') ? `package ${gap.source}` : gap.source.startsWith('/') ? `package ${path.relative(packagePath, gap.source) || '.'}` : gap.source} (${gap.reason})` : ''}`
1105
1113
  }),
1114
+ ...(workspace
1115
+ ? [
1116
+ `${path.basename(opened!)} is part of ${path.relative(process.cwd(), workspace)}, which holds its local packages and Package.resolved pins; pass the workspace to build what Xcode builds there.`,
1117
+ ]
1118
+ : []),
1106
1119
  ].join('\n')
1107
1120
  }
1108
1121
 
@@ -313,6 +313,30 @@ function workspaceReferences(workspace: string): string[] {
313
313
  return references
314
314
  }
315
315
 
316
+ /**
317
+ * the workspace in an ancestor directory that lists `xcodeproj`, up to the
318
+ * repository root: opened alone, the project misses the local packages and
319
+ * Package.resolved pins that workspace holds.
320
+ */
321
+ export function enclosingXcodeWorkspace(xcodeproj: string): string | null {
322
+ const project = fs.realpathSync(xcodeproj)
323
+ for (let dir = path.dirname(project); ; dir = path.dirname(dir)) {
324
+ for (const name of fs.readdirSync(dir)) {
325
+ if (!name.endsWith('.xcworkspace')) continue
326
+ const workspace = path.join(dir, name)
327
+ if (!fs.existsSync(path.join(workspace, 'contents.xcworkspacedata'))) continue
328
+ if (
329
+ workspaceReferences(workspace).some(
330
+ (reference) =>
331
+ fs.existsSync(reference) && fs.realpathSync(reference) === project,
332
+ )
333
+ )
334
+ return workspace
335
+ }
336
+ if (fs.existsSync(path.join(dir, '.git')) || path.dirname(dir) === dir) return null
337
+ }
338
+ }
339
+
316
340
  /**
317
341
  * the workspace or project a path names: the bundle itself, or in a
318
342
  * directory its one workspace, else its one project, as xcode opens it.