peachsim 0.1.1635 → 0.1.1640

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 (129) hide show
  1. package/README.md +5 -1
  2. package/cli/app-config.ts +14 -5
  3. package/cli/app-stubs.ts +62 -13
  4. package/cli/bridge-flow-runner.ts +2 -2
  5. package/cli/cloud-client.ts +60 -40
  6. package/cli/commands/doctor.ts +13 -5
  7. package/cli/commands/flow.ts +1 -1
  8. package/cli/commands/inspect/shared.ts +9 -4
  9. package/cli/commands/inspect.ts +65 -47
  10. package/cli/commands/preview.ts +1 -1
  11. package/cli/commands/record.ts +97 -47
  12. package/cli/commands/swift.ts +9 -3
  13. package/cli/commands/upload.ts +48 -42
  14. package/cli/drivers/playwright-sim-host.ts +65 -42
  15. package/cli/main.ts +1 -1
  16. package/cli/outbound-endpoints.ts +7 -5
  17. package/cli/pause-aware-timeout.ts +4 -0
  18. package/cli/ws-bridge.ts +19 -10
  19. package/detox/attempt-events.cjs +62 -5
  20. package/detox/attempt-events.d.cts +7 -0
  21. package/detox/expectations.ts +7 -3
  22. package/detox/index.ts +121 -47
  23. package/detox/motion-change.cjs +170 -21
  24. package/detox/motion-change.d.cts +32 -0
  25. package/detox/navigation-lifecycle.ts +35 -3
  26. package/dist-lib/agent-daemon-client.cjs +1 -1
  27. package/dist-lib/agent-events.cjs +1 -1
  28. package/dist-lib/attached-projects.cjs +1 -1
  29. package/dist-lib/auth/shared-session.cjs +1 -1
  30. package/dist-lib/backend-origin.cjs +8 -7
  31. package/dist-lib/beta.cjs +1 -1
  32. package/dist-lib/beta.mjs +1 -1
  33. package/dist-lib/bridge-constants.cjs +1 -1
  34. package/dist-lib/bridge-contract-input.cjs +1 -1
  35. package/dist-lib/bridge-contract-input.mjs +1 -1
  36. package/dist-lib/bridge-contract.cjs +1 -1
  37. package/dist-lib/bridge-contract.mjs +1 -1
  38. package/dist-lib/bundle-channel.cjs +4038 -1983
  39. package/dist-lib/capture-contract.cjs +1 -1
  40. package/dist-lib/capture-contract.mjs +1 -1
  41. package/dist-lib/cloud-contract.cjs +1 -1
  42. package/dist-lib/cloud-contract.mjs +1 -1
  43. package/dist-lib/cloud-test-args.cjs +1 -1
  44. package/dist-lib/cloud-test-args.mjs +1 -1
  45. package/dist-lib/cloud.cjs +1 -1
  46. package/dist-lib/cloud.mjs +1 -1
  47. package/dist-lib/config.cjs +1 -1
  48. package/dist-lib/config.mjs +1 -1
  49. package/dist-lib/detox/index.cjs +509 -86
  50. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  51. package/dist-lib/expo-swift-bundle.cjs +3551 -1574
  52. package/dist-lib/expo-swift-metadata.cjs +9 -7
  53. package/dist-lib/expo-swift-metadata.mjs +9 -7
  54. package/dist-lib/home-paths.cjs +1 -1
  55. package/dist-lib/host/bridge-host.cjs +43633 -2635
  56. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  57. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  58. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  59. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  60. package/dist-lib/host/websocket-proxy.cjs +1 -1
  61. package/dist-lib/index.cjs +2748 -128
  62. package/dist-lib/jump-to-source-babel.cjs +1 -1
  63. package/dist-lib/jump-to-source-native.cjs +1 -1
  64. package/dist-lib/kotlin-host.cjs +1 -1
  65. package/dist-lib/menu.cjs +1 -1
  66. package/dist-lib/menu.mjs +1 -1
  67. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  68. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  69. package/dist-lib/metro-production-bundle.cjs +1 -1
  70. package/dist-lib/metro-production-bundle.mjs +1 -1
  71. package/dist-lib/metro.cjs +2547 -83
  72. package/dist-lib/native-app-identity-project.cjs +237 -50
  73. package/dist-lib/native-app-identity-project.mjs +237 -50
  74. package/dist-lib/native-app-identity.cjs +29 -30
  75. package/dist-lib/native-app-identity.mjs +29 -30
  76. package/dist-lib/native-firebase-metadata.cjs +1 -1
  77. package/dist-lib/native-firebase-metadata.mjs +1 -1
  78. package/dist-lib/plist.cjs +1 -1
  79. package/dist-lib/plist.mjs +1 -1
  80. package/dist-lib/profiles.cjs +1 -1
  81. package/dist-lib/public-brand.cjs +1 -1
  82. package/dist-lib/react-native-host-modules.cjs +2 -2
  83. package/dist-lib/react-native-host-modules.mjs +2 -2
  84. package/dist-lib/scripts/dev-server-scanner.cjs +8 -6
  85. package/dist-lib/sdk.cjs +1 -1
  86. package/dist-lib/sdk.mjs +1 -1
  87. package/dist-lib/skills.cjs +65403 -22739
  88. package/dist-lib/swift-compile.cjs +93 -32
  89. package/dist-lib/swift-compile.mjs +93 -32
  90. package/dist-lib/swift-package.cjs +1 -1
  91. package/dist-lib/swift-package.mjs +1 -1
  92. package/dist-lib/swift-submit.cjs +7 -5
  93. package/dist-lib/swift-submit.mjs +7 -5
  94. package/dist-lib/swift-toolchain.cjs +316 -41
  95. package/dist-lib/swift.cjs +1 -1
  96. package/dist-lib/vite-swift.cjs +7335 -5432
  97. package/dist-lib/vite.cjs +2857 -12
  98. package/dist-lib/worklet-executable.cjs +14 -2
  99. package/dist-lib/worklet-executable.mjs +14 -2
  100. package/package.json +1 -1
  101. package/src/backend-origin.ts +13 -6
  102. package/src/expo-swift-host.ts +5 -2
  103. package/src/expoKotlinContract.ts +4 -7
  104. package/src/expoSwiftContract.ts +4 -6
  105. package/src/host/staged-host-files.ts +9 -0
  106. package/src/native-app-identity-project.ts +1 -4
  107. package/src/native-app-identity.ts +1 -4
  108. package/src/nativeAppIconContract.ts +1 -4
  109. package/src/output-lock-stdio.ts +36 -0
  110. package/src/react-native-bridge-modules.ts +21 -6
  111. package/src/react-native-host-modules.ts +4 -1
  112. package/src/settings-bundle.ts +1 -4
  113. package/src/swift-compile.ts +91 -33
  114. package/src/swift-distribution.lock.json +22 -12
  115. package/src/swift-distribution.ts +103 -4
  116. package/src/swift-host.ts +89 -26
  117. package/src/swift-icu.ts +16 -10
  118. package/src/swift-objc-compile.ts +355 -0
  119. package/src/swift-objc-sdk.ts +689 -18
  120. package/src/swift-objc-standin.ts +126 -14
  121. package/src/swift-package-manifest.ts +39 -1
  122. package/src/swift-packages.ts +35 -21
  123. package/src/swift-standin-emit.ts +40 -7
  124. package/src/swift-standins.ts +404 -138
  125. package/src/swift-submit.ts +3 -5
  126. package/src/swift-toolchain.ts +378 -46
  127. package/src/worker-system-chunks.ts +11 -12
  128. package/src/worklet-executable.ts +19 -1
  129. package/src/xcode-project.ts +270 -30
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (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;
@@ -34,11 +34,16 @@ var swift_toolchain_exports = {};
34
34
  __export(swift_toolchain_exports, {
35
35
  SWIFT_HOST_COMPILER_ID: () => SWIFT_HOST_COMPILER_ID,
36
36
  SWIFT_HOST_COMPILER_RELEASE: () => SWIFT_HOST_COMPILER_RELEASE,
37
+ confineSwiftScratch: () => confineSwiftScratch,
38
+ installSwiftWasmSdk: () => installSwiftWasmSdk,
37
39
  swiftCompiler: () => swiftCompiler,
40
+ swiftCompilerInstallSteps: () => swiftCompilerInstallSteps,
38
41
  swiftCompilerRelease: () => swiftCompilerRelease,
42
+ swiftEnvironment: () => swiftEnvironment,
39
43
  swiftFileChecksum: () => swiftFileChecksum,
40
44
  swiftHostCompilerArchive: () => swiftHostCompilerArchive,
41
45
  swiftInstallSteps: () => swiftInstallSteps,
46
+ swiftSdkInstallStep: () => swiftSdkInstallStep,
42
47
  swiftSdkOptions: () => swiftSdkOptions,
43
48
  swiftToolchain: () => swiftToolchain,
44
49
  swiftToolchainBin: () => swiftToolchainBin,
@@ -51,24 +56,25 @@ var import_node_crypto = require("node:crypto");
51
56
  var import_node_fs = __toESM(require("node:fs"), 1);
52
57
  var import_node_os = __toESM(require("node:os"), 1);
53
58
  var import_node_path = __toESM(require("node:path"), 1);
59
+ var import_node_url = require("node:url");
54
60
  function swiftSdkOptions() {
55
61
  const directory = process.env.PEACH_SWIFT_SDKS_PATH;
56
62
  return directory ? ["--swift-sdks-path", import_node_path.default.resolve(directory)] : [];
57
63
  }
58
- var SWIFT_HOST_COMPILER_RELEASE = "swift-6.4.0-RELEASE-custom-91504a66b3f012ac";
59
- var SWIFT_HOST_COMPILER_ID = "91504a66b3f012ac";
64
+ var SWIFT_HOST_COMPILER_RELEASE = "swift-6.4.0-RELEASE-custom-0d775d32d7c74eae";
65
+ var SWIFT_HOST_COMPILER_ID = "0d775d32d7c74eae";
60
66
  var compilerArchives = {
61
67
  "darwin-arm64": {
62
- checksum: "5d0ecbafd88c896beac74fd74c9d5fb20f973e0f58abbc1d2f27d5af0cbc4e59",
63
- manifest: "827130a60b782ed413c9df41410afe7baf32dcb132b945a70ac0ff4c0594c690"
68
+ checksum: "957e85486f92327ee5cf8d3c5bb9336d17ab80145c87645c637c49130a50477a",
69
+ manifest: "c63e2f81694e8d8ad046d10c71d0638dbae4e5a36601294ed670988d1cb5b6f1"
64
70
  },
65
71
  "linux-x64": {
66
- checksum: "9d8491107efa347ccadf5f6974e80b2cff2b33cd8c34317dab777c5542512b3e",
67
- manifest: "6221c024fa86b2201dcada23d9e13f6a11d7450cf22164a9708703f992de129f"
72
+ checksum: "6302230fb126b79c9af5fc2bc0208a936bb573c343da7ae949c5c1687e761cd2",
73
+ manifest: "31b507a6a8648a2266a187b9fed092e29a63cae99d57c5defdf2e82a7cbbc113"
68
74
  },
69
75
  "linux-arm64": {
70
- checksum: "14f5c7b39b1e36a1d9ce426a875676182fdb5247763a7e99cb72f74957bc0d9a",
71
- manifest: "57ff31b79f9b3d9a6c0fd51c73271cdd88088522c0fc6d7a28ade03d68008b68"
76
+ checksum: "9b40d39ea5ba82fd9a417868f0a449f5e98e37cf83acaac9cedd3a8b8d91a218",
77
+ manifest: "fe07a29d4f4374cad47b29de70e90aa2e3b7664e08c8b53d304585e65637da24"
72
78
  }
73
79
  };
74
80
  function swiftHostCompilerArchive(release, host = `${process.platform}-${process.arch}`) {
@@ -102,15 +108,83 @@ function swiftToolchainBin(release) {
102
108
  return import_node_path.default.join(process.env.CONTRAST_SWIFT_TOOLCHAINS, release, "usr/bin");
103
109
  }
104
110
  const image = import_node_path.default.join("/opt/swift", release, "usr/bin");
105
- if (release.includes("-custom-") || import_node_fs.default.existsSync(import_node_path.default.join(image, "swift")))
106
- return image;
111
+ if (import_node_fs.default.existsSync(import_node_path.default.join(image, "swift"))) return image;
112
+ if (release.includes("-custom-"))
113
+ return import_node_path.default.join(peachHome(), "swift", "toolchains", release, "usr/bin");
107
114
  return (process.env.PATH ?? "").split(import_node_path.default.delimiter).find((dir) => dir && import_node_fs.default.existsSync(import_node_path.default.join(dir, "swift"))) ?? image;
108
115
  }
109
- var verified = /* @__PURE__ */ new Map();
116
+ function peachHome() {
117
+ const override = process.env.PEACH_HOME;
118
+ return override ? import_node_path.default.resolve(override) : import_node_path.default.join(import_node_os.default.homedir(), ".peach");
119
+ }
120
+ var scratch;
121
+ var swiftHome;
122
+ function confineSwiftScratch(root) {
123
+ if (scratch) return;
124
+ import_node_fs.default.mkdirSync(root, { recursive: true });
125
+ for (const name of import_node_fs.default.readdirSync(root)) {
126
+ const pid = Number(name);
127
+ if (Number.isInteger(pid) && pid > 0 && !processRuns(pid))
128
+ import_node_fs.default.rmSync(import_node_path.default.join(root, name), { recursive: true, force: true });
129
+ }
130
+ const dir = import_node_path.default.join(root, String(process.pid));
131
+ import_node_fs.default.mkdirSync(dir, { recursive: true });
132
+ scratch = dir;
133
+ if (process.platform === "linux") {
134
+ swiftHome = import_node_path.default.join(root, "home");
135
+ import_node_fs.default.mkdirSync(swiftHome, { recursive: true });
136
+ }
137
+ const seeded = import_node_path.default.join(import_node_os.default.homedir(), ".swiftpm");
138
+ const dirAbsentBefore = lstatIfKnown(seeded) === null;
139
+ const absentBefore = swiftpmSeeds.filter(
140
+ (name) => lstatIfKnown(import_node_path.default.join(seeded, name)) === null
141
+ );
142
+ process.once("exit", () => {
143
+ import_node_fs.default.rmSync(dir, { recursive: true, force: true });
144
+ for (const name of absentBefore) removeSwiftpmSeed(import_node_path.default.join(seeded, name), name);
145
+ if (dirAbsentBefore && lstatIfKnown(seeded)?.isDirectory())
146
+ try {
147
+ import_node_fs.default.rmdirSync(seeded);
148
+ } catch {
149
+ }
150
+ });
151
+ }
152
+ var swiftpmSeeds = ["cache", "configuration", "security"];
153
+ function lstatIfKnown(entry) {
154
+ try {
155
+ return import_node_fs.default.lstatSync(entry);
156
+ } catch (error) {
157
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
158
+ return void 0;
159
+ }
160
+ }
161
+ function removeSwiftpmSeed(entry, name) {
162
+ const stat = lstatIfKnown(entry);
163
+ if (!stat) return;
164
+ try {
165
+ if (name === "cache") {
166
+ if (stat.isSymbolicLink() && import_node_fs.default.readlinkSync(entry).endsWith("/.cache/org.swift.swiftpm"))
167
+ import_node_fs.default.unlinkSync(entry);
168
+ } else if (stat.isDirectory()) {
169
+ import_node_fs.default.rmdirSync(entry);
170
+ }
171
+ } catch {
172
+ }
173
+ }
174
+ function processRuns(pid) {
175
+ try {
176
+ process.kill(pid, 0);
177
+ return true;
178
+ } catch (error) {
179
+ return error instanceof Error && "code" in error && error.code === "EPERM";
180
+ }
181
+ }
182
+ function swiftEnvironment(base = process.env) {
183
+ if (!scratch) return base;
184
+ return swiftHome ? { ...base, TMPDIR: scratch, HOME: swiftHome } : { ...base, TMPDIR: scratch };
185
+ }
110
186
  function swiftToolchain(release, sdk) {
111
- const key = JSON.stringify([release, sdk.wasmSdkId, swiftSdkOptions()]);
112
- const cached = verified.get(key);
113
- if (cached) return cached;
187
+ validateSwiftSdkIdentity(sdk);
114
188
  let bin;
115
189
  try {
116
190
  bin = swiftCompiler(release);
@@ -124,17 +198,187 @@ ${swiftInstallSteps(release, sdk)}`
124
198
  const swift = import_node_path.default.join(bin, "swift");
125
199
  const sdks = (0, import_node_child_process.execFileSync)(swift, ["sdk", "list", ...swiftSdkOptions()], {
126
200
  encoding: "utf8",
201
+ env: swiftEnvironment(),
127
202
  stdio: ["ignore", "pipe", "pipe"]
128
203
  });
129
204
  if (!sdks.split("\n").some((line) => line.trim() === sdk.wasmSdkId)) {
130
205
  throw new Error(
131
206
  `peach compiles Swift with the ${sdk.wasmSdkId} SDK, which ${swift} does not have.
132
- ${swiftInstallSteps(release, sdk)}`
207
+ ${swiftSdkInstallStep(release, sdk)}`
133
208
  );
134
209
  }
135
- verified.set(key, bin);
210
+ try {
211
+ verifySwiftSdk(swift, sdk);
212
+ } catch (error) {
213
+ const reason = error instanceof Error ? error.message : String(error);
214
+ throw new Error(`${reason}
215
+ ${swiftSdkInstallStep(release, sdk)}`);
216
+ }
136
217
  return bin;
137
218
  }
219
+ function validateSwiftSdkIdentity(sdk) {
220
+ if (!/^[a-zA-Z0-9._-]+$/.test(sdk.wasmSdkId) || !/^[a-f0-9]{64}$/.test(sdk.wasmSdkChecksum))
221
+ throw new Error("invalid Swift SDK identity or checksum");
222
+ }
223
+ function swiftSdkBundle(swift, id, options) {
224
+ const configuration = (0, import_node_child_process.execFileSync)(
225
+ swift,
226
+ ["sdk", "configure", ...options, "--show-configuration", id, "wasm32-unknown-wasip1"],
227
+ { encoding: "utf8", env: swiftEnvironment(), stdio: ["ignore", "pipe", "pipe"] }
228
+ );
229
+ const sysroot = /^sdkRootPath: (.+)$/m.exec(configuration)?.[1]?.trim();
230
+ if (!sysroot || !import_node_path.default.isAbsolute(sysroot))
231
+ throw new Error(`Swift SDK ${id} reports no absolute sdkRootPath`);
232
+ let bundle = sysroot;
233
+ while (!bundle.endsWith(".artifactbundle")) {
234
+ const parent = import_node_path.default.dirname(bundle);
235
+ if (parent === bundle)
236
+ throw new Error(`Swift SDK ${id} is outside an artifact bundle`);
237
+ bundle = parent;
238
+ }
239
+ return import_node_fs.default.realpathSync(bundle);
240
+ }
241
+ var sdkFileHashes = /* @__PURE__ */ new Map();
242
+ function swiftSdkPayloadChecksum(bundle) {
243
+ const hash = (0, import_node_crypto.createHash)("sha256");
244
+ function visit(relative) {
245
+ const file = import_node_path.default.join(bundle, relative);
246
+ const stat = import_node_fs.default.lstatSync(file, { bigint: true });
247
+ if (stat.isSymbolicLink()) {
248
+ const resolved = import_node_path.default.relative(bundle, import_node_fs.default.realpathSync(file));
249
+ if (resolved === ".." || resolved.startsWith(`..${import_node_path.default.sep}`) || import_node_path.default.isAbsolute(resolved))
250
+ throw new Error(`Swift SDK symlink escapes its bundle: ${relative}`);
251
+ hash.update(JSON.stringify([relative, "link", import_node_fs.default.readlinkSync(file)]) + "\n");
252
+ } else if (stat.isDirectory()) {
253
+ hash.update(JSON.stringify([relative, "directory"]) + "\n");
254
+ for (const name of import_node_fs.default.readdirSync(file).sort()) visit(import_node_path.default.join(relative, name));
255
+ } else if (stat.isFile()) {
256
+ const stamp = [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
257
+ let cached = sdkFileHashes.get(file);
258
+ if (cached?.stamp !== stamp) {
259
+ cached = { stamp, checksum: swiftFileChecksum(file) };
260
+ sdkFileHashes.set(file, cached);
261
+ }
262
+ hash.update(
263
+ JSON.stringify([relative, "file", Number(stat.mode & 0o111n), cached.checksum]) + "\n"
264
+ );
265
+ } else throw new Error(`unsupported Swift SDK payload entry: ${relative}`);
266
+ }
267
+ visit("");
268
+ return hash.digest("hex");
269
+ }
270
+ function swiftSdkVerificationFile(bundle, sdk) {
271
+ return import_node_path.default.join(
272
+ import_node_path.default.dirname(bundle),
273
+ ".peach-sdk-checksums",
274
+ `${sdk.wasmSdkId}-${sdk.wasmSdkChecksum}.json`
275
+ );
276
+ }
277
+ function verifySwiftSdk(swift, sdk) {
278
+ const bundle = swiftSdkBundle(swift, sdk.wasmSdkId, swiftSdkOptions());
279
+ const file = swiftSdkVerificationFile(bundle, sdk);
280
+ if (!import_node_fs.default.existsSync(file))
281
+ throw new Error(
282
+ `Swift SDK ${sdk.wasmSdkId} has no verified archive binding for ${sdk.wasmSdkChecksum}. Hydrate it with installSwiftWasmSdk before compiling.`
283
+ );
284
+ const receipt = JSON.parse(import_node_fs.default.readFileSync(file, "utf8"));
285
+ if (!receipt || typeof receipt !== "object" || !("wasmSdkId" in receipt) || receipt.wasmSdkId !== sdk.wasmSdkId || !("wasmSdkChecksum" in receipt) || receipt.wasmSdkChecksum !== sdk.wasmSdkChecksum || !("payloadChecksum" in receipt) || receipt.payloadChecksum !== swiftSdkPayloadChecksum(bundle))
286
+ throw new Error(
287
+ `Swift SDK ${sdk.wasmSdkId} installed payload differs from its verified archive ${sdk.wasmSdkChecksum}`
288
+ );
289
+ }
290
+ function installSwiftSdkArchive(swift, sdk, archive) {
291
+ validateSwiftSdkIdentity(sdk);
292
+ const staging = import_node_fs.default.realpathSync(
293
+ import_node_fs.default.mkdtempSync(import_node_path.default.join(scratch ?? import_node_os.default.tmpdir(), "peach-sdk-verification-"))
294
+ );
295
+ try {
296
+ if (swiftFileChecksum(archive) !== sdk.wasmSdkChecksum)
297
+ throw new Error("declared Swift SDK archive checksum mismatch");
298
+ const store = import_node_path.default.join(staging, "sdks");
299
+ import_node_fs.default.mkdirSync(store);
300
+ (0, import_node_child_process.execFileSync)(
301
+ swift,
302
+ [
303
+ "sdk",
304
+ "install",
305
+ archive,
306
+ "--checksum",
307
+ sdk.wasmSdkChecksum,
308
+ "--swift-sdks-path",
309
+ store
310
+ ],
311
+ { env: swiftEnvironment(), stdio: "inherit" }
312
+ );
313
+ const stagedBundle = swiftSdkBundle(swift, sdk.wasmSdkId, [
314
+ "--swift-sdks-path",
315
+ store
316
+ ]);
317
+ const expected = swiftSdkPayloadChecksum(stagedBundle);
318
+ const directory = process.env.PEACH_SWIFT_SDKS_PATH;
319
+ const locks = directory ? import_node_path.default.join(import_node_path.default.resolve(directory), ".peach-locks") : import_node_path.default.join(import_node_os.default.homedir(), ".swiftpm", "builder-locks");
320
+ import_node_fs.default.mkdirSync(locks, { recursive: true });
321
+ (0, import_node_child_process.execFileSync)(
322
+ "perl",
323
+ [
324
+ "-e",
325
+ 'use Fcntl qw(:flock); my ($lock, $id, $bundle, $swift, @options) = @ARGV; open(my $fd, ">>", $lock) or die $!; flock($fd, LOCK_EX) or die $!; open(my $list, "-|", $swift, "sdk", "list", @options) or die $!; my $found = 0; while (<$list>) { s/^\\s+|\\s+$//g; $found = 1 if $_ eq $id; } close($list) or die "swift sdk list failed"; unless ($found) { system($swift, "sdk", "install", $bundle, @options); exit(($? & 127) ? 128 + ($? & 127) : $? >> 8); }',
326
+ import_node_path.default.join(locks, "wasm-sdk.lock"),
327
+ sdk.wasmSdkId,
328
+ stagedBundle,
329
+ swift,
330
+ ...swiftSdkOptions()
331
+ ],
332
+ { env: swiftEnvironment(), stdio: "inherit" }
333
+ );
334
+ const bundle = swiftSdkBundle(swift, sdk.wasmSdkId, swiftSdkOptions());
335
+ if (swiftSdkPayloadChecksum(bundle) !== expected)
336
+ throw new Error(
337
+ `Swift SDK ${sdk.wasmSdkId} already exists with different payload bytes; select a separate --swift-sdks-path. No installed SDK was replaced.`
338
+ );
339
+ const file = swiftSdkVerificationFile(bundle, sdk);
340
+ import_node_fs.default.mkdirSync(import_node_path.default.dirname(file), { recursive: true });
341
+ const temporary = `${file}.${process.pid}.tmp`;
342
+ try {
343
+ import_node_fs.default.writeFileSync(
344
+ temporary,
345
+ JSON.stringify({
346
+ wasmSdkId: sdk.wasmSdkId,
347
+ wasmSdkChecksum: sdk.wasmSdkChecksum,
348
+ payloadChecksum: expected
349
+ }) + "\n"
350
+ );
351
+ import_node_fs.default.renameSync(temporary, file);
352
+ } finally {
353
+ import_node_fs.default.rmSync(temporary, { force: true });
354
+ }
355
+ } finally {
356
+ import_node_fs.default.rmSync(staging, { recursive: true, force: true });
357
+ for (const file of sdkFileHashes.keys())
358
+ if (file.startsWith(staging + import_node_path.default.sep)) sdkFileHashes.delete(file);
359
+ }
360
+ }
361
+ function installSwiftWasmSdk(release, sdk) {
362
+ validateSwiftSdkIdentity(sdk);
363
+ try {
364
+ swiftToolchain(release, sdk);
365
+ return;
366
+ } catch {
367
+ }
368
+ const swift = import_node_path.default.join(swiftCompiler(release), "swift");
369
+ const staging = import_node_fs.default.mkdtempSync(import_node_path.default.join(scratch ?? import_node_os.default.tmpdir(), "builder-swift-sdk-"));
370
+ const archive = import_node_path.default.join(staging, "sdk.artifactbundle.tar.gz");
371
+ try {
372
+ if (sdk.wasmSdkUrl.startsWith("file:"))
373
+ import_node_fs.default.copyFileSync((0, import_node_url.fileURLToPath)(sdk.wasmSdkUrl), archive);
374
+ else
375
+ (0, import_node_child_process.execFileSync)("curl", ["-fsSL", sdk.wasmSdkUrl, "-o", archive], { stdio: "inherit" });
376
+ installSwiftSdkArchive(swift, sdk, archive);
377
+ swiftToolchain(release, sdk);
378
+ } finally {
379
+ import_node_fs.default.rmSync(staging, { recursive: true, force: true });
380
+ }
381
+ }
138
382
  function swiftFileChecksum(file) {
139
383
  const hash = (0, import_node_crypto.createHash)("sha256");
140
384
  const fd = import_node_fs.default.openSync(file, "r");
@@ -160,7 +404,7 @@ function verifySwiftHostCompiler(release, root) {
160
404
  throw new Error(`Swift compiler identity mismatch at ${root}`);
161
405
  }
162
406
  const files = Object.entries(manifest.files);
163
- if (files.length !== 15) throw new Error("incomplete Swift compiler manifest");
407
+ if (files.length !== 16) throw new Error("incomplete Swift compiler manifest");
164
408
  for (const [relative, checksum] of files) {
165
409
  if (relative.startsWith("/") || relative.split("/").includes("..") || typeof checksum !== "string" || swiftFileChecksum(import_node_path.default.join(root, relative)) !== checksum) {
166
410
  throw new Error(`Swift compiler binary mismatch: ${relative}`);
@@ -176,6 +420,7 @@ function swiftCompiler(release) {
176
420
  verifySwiftHostCompiler(release, import_node_path.default.resolve(bin, "../.."));
177
421
  const version = (0, import_node_child_process.execFileSync)(import_node_path.default.join(bin, "swift"), ["--version"], {
178
422
  encoding: "utf8",
423
+ env: swiftEnvironment(),
179
424
  stdio: ["ignore", "pipe", "pipe"]
180
425
  });
181
426
  if (!version.includes(`(${swiftCompilerRelease(release)})`))
@@ -183,50 +428,80 @@ function swiftCompiler(release) {
183
428
  verifiedCompilers.set(release, bin);
184
429
  return bin;
185
430
  }
431
+ function swiftSdkInstallStep(release, wasmSdk) {
432
+ return `install the pinned SDK:
433
+ ${swiftSdkInstallCommand(release, wasmSdk)}`;
434
+ }
435
+ function swiftSdkInstallCommand(release, wasmSdk) {
436
+ const { wasmSdkId, wasmSdkUrl, wasmSdkChecksum } = wasmSdk;
437
+ const program = `import { installSwiftWasmSdk } from "peachsim/swift-toolchain"; installSwiftWasmSdk(${JSON.stringify(release)}, ${JSON.stringify({ wasmSdkId, wasmSdkUrl, wasmSdkChecksum })})`;
438
+ const directory = process.env.PEACH_SWIFT_SDKS_PATH;
439
+ const environment = directory ? `PEACH_SWIFT_SDKS_PATH='${import_node_path.default.resolve(directory).replaceAll("'", "'\\''")}' ` : "";
440
+ return `${environment}node --input-type=module -e '${program.replaceAll("'", "'\\''")}'`;
441
+ }
186
442
  function swiftInstallSteps(release, wasmSdk) {
187
- const sdkOptions = swiftSdkOptions().map((arg) => ` '${arg.replaceAll("'", "'\\''")}'`).join("");
443
+ const { note, commands } = swiftCompilerInstall(release);
444
+ return [
445
+ `install the pinned compiler and SDK${note}:`,
446
+ ...[...commands, swiftSdkInstallCommand(release, wasmSdk)].map((line) => ` ${line}`)
447
+ ].join("\n");
448
+ }
449
+ function swiftCompilerInstallSteps(release) {
450
+ const { note, commands } = swiftCompilerInstall(release);
451
+ return [
452
+ `install the pinned compiler${note}:`,
453
+ ...commands.map((line) => ` ${line}`)
454
+ ].join("\n");
455
+ }
456
+ function swiftCompilerInstall(release) {
188
457
  if (release.includes("-custom-")) {
189
458
  const archive = swiftHostCompilerArchive(release);
190
459
  const directory = import_node_path.default.resolve(swiftToolchainBin(release), "../..");
191
- return [
192
- "install the pinned compiler and SDK:",
193
- ` curl -fsSL ${archive.url} -o compiler.tar.gz`,
194
- ` echo '${archive.checksum} compiler.tar.gz' | shasum -a 256 -c -`,
195
- ` mkdir -p '${directory}'`,
196
- ` tar -xzf compiler.tar.gz --strip-components=1 -C '${directory}'`,
197
- ` '${directory}/usr/bin/swift' sdk install ${wasmSdk.wasmSdkUrl} --checksum ${wasmSdk.wasmSdkChecksum}${sdkOptions}`
198
- ].join("\n");
460
+ return {
461
+ note: "",
462
+ commands: [
463
+ `curl -fsSL ${archive.url} -o compiler.tar.gz`,
464
+ `echo '${archive.checksum} compiler.tar.gz' | shasum -a 256 -c -`,
465
+ `mkdir -p '${directory}'`,
466
+ `tar -xzf compiler.tar.gz --strip-components=1 -C '${directory}'`
467
+ ]
468
+ };
199
469
  }
200
470
  const version = release.replace(/^swift-/, "").toLowerCase();
201
471
  const downloads = `https://download.swift.org/swift-${version}`;
202
- const sdk = `swift sdk install ${wasmSdk.wasmSdkUrl} --checksum ${wasmSdk.wasmSdkChecksum}${sdkOptions}`;
203
472
  if (process.platform === "darwin") {
204
- const swift = `~/Library/Developer/Toolchains/${release}.xctoolchain/usr/bin/swift`;
205
- return [
206
- "install it:",
207
- ` curl -fsSLO ${downloads}/xcode/${release}/${release}-osx.pkg`,
208
- ` installer -pkg ${release}-osx.pkg -target CurrentUserHomeDirectory`,
209
- ` ${swift} ${sdk.replace(/^swift /, "")}`
210
- ].join("\n");
473
+ return {
474
+ note: "",
475
+ commands: [
476
+ `curl -fsSLO ${downloads}/xcode/${release}/${release}-osx.pkg`,
477
+ `installer -pkg ${release}-osx.pkg -target CurrentUserHomeDirectory`
478
+ ]
479
+ };
211
480
  }
212
481
  const platform = `debian12${process.arch === "arm64" ? "-aarch64" : ""}`;
213
482
  const name = `${release}-${platform}`;
214
- return [
215
- "install it (Debian 12 shown; other distributions: https://www.swift.org/install/linux/):",
216
- ` curl -fsSL ${downloads}/${platform}/${release}/${name}.tar.gz | tar -xz -C /opt`,
217
- ` export PATH=/opt/${name}/usr/bin:$PATH`,
218
- ` ${sdk}`
219
- ].join("\n");
483
+ return {
484
+ note: " (Debian 12 shown; other distributions: https://www.swift.org/install/linux/)",
485
+ commands: [
486
+ `curl -fsSL ${downloads}/${platform}/${release}/${name}.tar.gz | tar -xz -C /opt`,
487
+ `export PATH=/opt/${name}/usr/bin:$PATH`
488
+ ]
489
+ };
220
490
  }
221
491
  // Annotate the CommonJS export names for ESM import in node:
222
492
  0 && (module.exports = {
223
493
  SWIFT_HOST_COMPILER_ID,
224
494
  SWIFT_HOST_COMPILER_RELEASE,
495
+ confineSwiftScratch,
496
+ installSwiftWasmSdk,
225
497
  swiftCompiler,
498
+ swiftCompilerInstallSteps,
226
499
  swiftCompilerRelease,
500
+ swiftEnvironment,
227
501
  swiftFileChecksum,
228
502
  swiftHostCompilerArchive,
229
503
  swiftInstallSteps,
504
+ swiftSdkInstallStep,
230
505
  swiftSdkOptions,
231
506
  swiftToolchain,
232
507
  swiftToolchainBin,
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (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;