peachsim 0.1.578 → 0.1.579

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 (178) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +11 -9
  3. package/cli/app-catalog.ts +77 -0
  4. package/cli/app-fonts.ts +4 -20
  5. package/cli/app-splash.ts +2 -18
  6. package/cli/bridge-flow-runner.ts +505 -139
  7. package/cli/cloud-client.ts +1 -4
  8. package/cli/cloud-session.ts +1 -4
  9. package/cli/cloud-test-result-files.ts +3 -0
  10. package/cli/cloud-test-tunnel.ts +2 -5
  11. package/cli/command-registry.ts +2 -0
  12. package/cli/commands/agent.ts +149 -23
  13. package/cli/commands/assert.ts +1 -4
  14. package/cli/commands/box/peach-command.ts +62 -0
  15. package/cli/commands/box/plane-share.ts +0 -70
  16. package/cli/commands/box/rnx-command.ts +1 -60
  17. package/cli/commands/box/search-command.ts +14 -0
  18. package/cli/commands/box.ts +2 -2
  19. package/cli/commands/control.ts +121 -27
  20. package/cli/commands/cpu-profile.ts +23 -10
  21. package/cli/commands/daemon.ts +1 -9
  22. package/cli/commands/detox.ts +26 -18
  23. package/cli/commands/device.ts +129 -1
  24. package/cli/commands/film.ts +25 -16
  25. package/cli/commands/flow.ts +9 -2
  26. package/cli/commands/inspect/actions.ts +75 -1
  27. package/cli/commands/inspect/core.ts +81 -2
  28. package/cli/commands/inspect/describe.ts +2 -6
  29. package/cli/commands/inspect/env.ts +1 -1
  30. package/cli/commands/inspect/settling.ts +20 -3
  31. package/cli/commands/inspect/shared.ts +1 -4
  32. package/cli/commands/inspect/sleep.ts +1 -1
  33. package/cli/commands/inspect.ts +16 -49
  34. package/cli/commands/install-desktop.ts +8 -6
  35. package/cli/commands/login.ts +3 -5
  36. package/cli/commands/maestro-generate.ts +1 -4
  37. package/cli/commands/maestro.ts +38 -21
  38. package/cli/commands/no-bridge-hint.ts +0 -14
  39. package/cli/commands/permissions.ts +2 -2
  40. package/cli/commands/platform.ts +13 -6
  41. package/cli/commands/screenshot.ts +6 -1
  42. package/cli/commands/skills.ts +1 -1
  43. package/cli/commands/test.ts +6 -2
  44. package/cli/commands/three-mode.ts +162 -19
  45. package/cli/commands/upload.ts +3 -18
  46. package/cli/current-sim.ts +0 -1
  47. package/cli/desktop-companion.ts +40 -8
  48. package/cli/drivers/playwright-provisioning.ts +1 -4
  49. package/cli/flow-export.ts +1 -8
  50. package/cli/flow-session.ts +0 -4
  51. package/cli/hints.ts +1 -16
  52. package/cli/inspect-notice-state.ts +0 -4
  53. package/cli/main.ts +2 -4
  54. package/cli/outbound-endpoints.ts +1 -24
  55. package/cli/parse-args.ts +1 -2
  56. package/cli/rnx-in-process.ts +3 -1
  57. package/cli/run-rnx-core.ts +4 -2
  58. package/cli/run-rnx.ts +18 -10
  59. package/cli/send-to-box.ts +1 -4
  60. package/cli/telemetry.ts +1 -1
  61. package/cli/ws-bridge.ts +1 -5
  62. package/detox/gestures.ts +20 -6
  63. package/detox/index.ts +379 -123
  64. package/detox/navigation-lifecycle.ts +22 -13
  65. package/dist-lib/agent-daemon-client.cjs +21 -15
  66. package/dist-lib/agent-events.cjs +1 -1
  67. package/dist-lib/agent-identity.cjs +3 -17
  68. package/dist-lib/agent-sessions.cjs +5 -4
  69. package/dist-lib/attached-projects.cjs +1 -77
  70. package/dist-lib/auth/shared-session.cjs +1 -1
  71. package/dist-lib/backend-origin.cjs +11 -1
  72. package/dist-lib/beta.cjs +1 -1
  73. package/dist-lib/beta.mjs +1 -1
  74. package/dist-lib/bridge-constants.cjs +1 -1
  75. package/dist-lib/bridge-contract-input.cjs +7 -5
  76. package/dist-lib/bridge-contract-input.mjs +7 -5
  77. package/dist-lib/bridge-contract.cjs +1 -1
  78. package/dist-lib/bridge-contract.mjs +1 -1
  79. package/dist-lib/capture-contract.cjs +30 -7
  80. package/dist-lib/capture-contract.mjs +30 -7
  81. package/dist-lib/cli-constants.cjs +1 -1
  82. package/dist-lib/cloud-contract.cjs +1 -1
  83. package/dist-lib/cloud-contract.mjs +1 -1
  84. package/dist-lib/cloud-test-args.cjs +1 -1
  85. package/dist-lib/cloud-test-args.mjs +1 -1
  86. package/dist-lib/cloud.cjs +17 -11
  87. package/dist-lib/cloud.mjs +17 -11
  88. package/dist-lib/config.cjs +1 -1
  89. package/dist-lib/detox/index.cjs +321 -122
  90. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  91. package/dist-lib/home-paths.cjs +1 -1
  92. package/dist-lib/host/bridge-host.cjs +427 -212
  93. package/dist-lib/host/fetch-proxy-handler.cjs +5 -28
  94. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  95. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  96. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  97. package/dist-lib/host/websocket-proxy.cjs +1 -1
  98. package/dist-lib/index.cjs +315 -58
  99. package/dist-lib/jump-to-source-babel.cjs +1 -1
  100. package/dist-lib/jump-to-source-native.cjs +1 -1
  101. package/dist-lib/menu.cjs +67 -31
  102. package/dist-lib/menu.mjs +64 -28
  103. package/dist-lib/metro-fingerprint-registry.cjs +8 -4
  104. package/dist-lib/metro-fingerprint-registry.mjs +6 -4
  105. package/dist-lib/metro-production-bundle.cjs +2 -2
  106. package/dist-lib/metro-production-bundle.mjs +2 -2
  107. package/dist-lib/metro.cjs +8 -4
  108. package/dist-lib/profiles.cjs +1 -1
  109. package/dist-lib/public-brand.cjs +7 -4
  110. package/dist-lib/react-native-host-modules.cjs +1 -1
  111. package/dist-lib/react-native-host-modules.mjs +1 -1
  112. package/dist-lib/render-mode.cjs +3 -13
  113. package/dist-lib/scripts/dev-server-scanner.cjs +5 -17
  114. package/dist-lib/sdk.cjs +129 -10
  115. package/dist-lib/sdk.mjs +127 -10
  116. package/dist-lib/skills.cjs +1635 -1121
  117. package/dist-lib/swift-compile.cjs +277 -70
  118. package/dist-lib/swift-compile.mjs +275 -70
  119. package/dist-lib/swift-package.cjs +17 -5
  120. package/dist-lib/swift-package.mjs +15 -4
  121. package/dist-lib/swift-submit.cjs +32 -8
  122. package/dist-lib/swift-submit.mjs +29 -7
  123. package/dist-lib/swift.cjs +30912 -577
  124. package/dist-lib/vite-kotlin.cjs +356 -0
  125. package/dist-lib/vite-swift.cjs +1743 -0
  126. package/dist-lib/vite.cjs +208 -1039
  127. package/kotlin/README.md +18 -0
  128. package/kotlin/Sources/androidx/annotation/Keep.kt +4 -0
  129. package/kotlin/Sources/dev/onejs/one/OneNativeSourceDispatch.kt +7 -0
  130. package/kotlin/Sources/dev/onejs/one/source/OneModule.kt +4 -0
  131. package/kotlin/Sources/org/json/JSON.kt +244 -0
  132. package/kotlin/toolchain.json +19 -0
  133. package/package.json +14 -2
  134. package/scripts/dev-server-scanner.ts +0 -18
  135. package/scripts/optional-demo-registry.ts +0 -17
  136. package/skills/contrast/SKILL.md +2 -2
  137. package/skills/peach-setup/SKILL.md +16 -0
  138. package/src/agent-daemon-client.ts +36 -22
  139. package/src/agent-identity.ts +0 -15
  140. package/src/agent-prompt.ts +12 -0
  141. package/src/attached-projects.ts +0 -72
  142. package/src/backend-origin.ts +10 -0
  143. package/src/bridge-contract-input.ts +2 -5
  144. package/src/bridge-contract.ts +2 -0
  145. package/src/capture-contract.ts +53 -11
  146. package/src/cloud.ts +4 -9
  147. package/src/dev-server-open.ts +0 -99
  148. package/src/home-paths.ts +2 -3
  149. package/src/host/agent-host.ts +82 -36
  150. package/src/host/bridge-host.ts +5 -11
  151. package/src/host/fetch-proxy-handler.ts +19 -43
  152. package/src/is-record.ts +4 -0
  153. package/src/menu.ts +82 -37
  154. package/src/metro-fingerprint-registry.ts +1 -4
  155. package/src/metro-production-bundle.ts +1 -1
  156. package/src/plist.ts +1 -4
  157. package/src/public-brand.ts +5 -3
  158. package/src/render-mode.ts +0 -12
  159. package/src/runtime-assets.ts +9 -2
  160. package/src/screenshots/compose.ts +7 -1
  161. package/src/screenshots/frame-compose.ts +21 -10
  162. package/src/screenshots/schema.ts +1 -4
  163. package/src/sim-client.ts +2 -4
  164. package/src/skills/builtin/maestro-test.ts +1 -4
  165. package/src/sleep.ts +4 -0
  166. package/src/swift-compile.ts +209 -47
  167. package/src/swift-icu.ts +140 -0
  168. package/src/swift-package.ts +26 -2
  169. package/src/swift-submit.ts +84 -4
  170. package/src/swift.ts +2 -0
  171. package/src/vite-plugin-kotlin.ts +376 -0
  172. package/src/vite-plugin-one.ts +224 -36
  173. package/src/vite-plugin-swift.ts +382 -96
  174. package/src/vite-plugin.ts +121 -134
  175. package/src/vite.d.ts +10 -0
  176. package/cli/resolve-assets.ts +0 -63
  177. package/src/rolldown-plugin-swift.ts +0 -244
  178. package/src/team-machine-prompt.ts +0 -73
@@ -1,20 +1,118 @@
1
- /*! rnx v0.1.578 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.579 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
- import { execFile } from "node:child_process";
5
- import { createHash } from "node:crypto";
4
+ import { execFile as execFile2 } from "node:child_process";
5
+ import { createHash as createHash2 } from "node:crypto";
6
6
  import {
7
7
  existsSync,
8
8
  mkdirSync,
9
- readFileSync,
9
+ readFileSync as readFileSync2,
10
10
  readdirSync,
11
11
  realpathSync,
12
12
  rmSync,
13
13
  statSync,
14
14
  writeFileSync
15
15
  } from "node:fs";
16
+ import os from "node:os";
17
+ import path2 from "node:path";
18
+ import { promisify as promisify2 } from "node:util";
19
+
20
+ // src/swift-icu.ts
21
+ import { execFile } from "node:child_process";
22
+ import { createHash } from "node:crypto";
23
+ import { readFileSync } from "node:fs";
16
24
  import path from "node:path";
17
25
  import { promisify } from "node:util";
26
+ import { gzip } from "node:zlib";
27
+ var run = promisify(execFile);
28
+ var deflate = promisify(gzip);
29
+ var ARCHIVE = "wasi/lib_FoundationICU.a";
30
+ var MEMBER = "icu_packaged_data.cpp.obj";
31
+ var raw = /* @__PURE__ */ new Map();
32
+ var assets = /* @__PURE__ */ new Map();
33
+ function memo(cache, key, load2) {
34
+ let pending = cache.get(key);
35
+ if (!pending) {
36
+ pending = load2();
37
+ pending.catch(() => cache.delete(key));
38
+ cache.set(key, pending);
39
+ }
40
+ return pending;
41
+ }
42
+ function swiftIcuData(toolchainBin, release) {
43
+ return memo(raw, `${toolchainBin}\0${release}`, () => load(toolchainBin, release));
44
+ }
45
+ function swiftIcuAsset(toolchainBin, release) {
46
+ return memo(assets, `${toolchainBin}\0${release}`, async () => {
47
+ const zipped = await deflate(await swiftIcuData(toolchainBin, release));
48
+ return { sha256: createHash("sha256").update(zipped).digest("hex"), gzip: zipped };
49
+ });
50
+ }
51
+ async function load(toolchainBin, release) {
52
+ const { stdout } = await run(path.join(toolchainBin, "swift"), [
53
+ "sdk",
54
+ "configure",
55
+ "--show-configuration",
56
+ `${release}_wasm`,
57
+ "wasm32-unknown-wasip1"
58
+ ]);
59
+ const resources = /^swiftStaticResourcesPath: (.+)$/m.exec(stdout)?.[1]?.trim();
60
+ if (!resources) throw new Error(`swift-icu: ${release}_wasm names no static resources`);
61
+ return Buffer.from(
62
+ icuSegment(archiveMember(readFileSync(path.join(resources, ARCHIVE)), MEMBER))
63
+ );
64
+ }
65
+ function archiveMember(archive, name) {
66
+ if (archive.toString("latin1", 0, 8) !== "!<arch>\n")
67
+ throw new Error("swift-icu: not an ar archive");
68
+ let names = "";
69
+ for (let at = 8; at + 60 <= archive.length; ) {
70
+ const raw2 = archive.toString("latin1", at, at + 16).trimEnd();
71
+ const size = Number(archive.toString("latin1", at + 48, at + 58).trim());
72
+ const body = archive.subarray(at + 60, at + 60 + size);
73
+ if (raw2 === "//") names = body.toString("latin1");
74
+ const member = /^\/\d+$/.test(raw2) ? names.slice(Number(raw2.slice(1)), names.indexOf("/\n", Number(raw2.slice(1)))) : raw2.replace(/\/$/, "");
75
+ if (member === name) return body;
76
+ at += 60 + size + size % 2;
77
+ }
78
+ throw new Error(`swift-icu: ${name} is not in the sdk's icu archive`);
79
+ }
80
+ function icuSegment(object) {
81
+ let at = 8;
82
+ const leb = () => {
83
+ let result = 0;
84
+ let shift = 0;
85
+ let byte;
86
+ do {
87
+ byte = object[at++];
88
+ result += (byte & 127) * 2 ** shift;
89
+ shift += 7;
90
+ } while (byte & 128);
91
+ return result;
92
+ };
93
+ const found = [];
94
+ while (at < object.length) {
95
+ const id = object[at++];
96
+ const size = leb();
97
+ const end = at + size;
98
+ if (id === 11) {
99
+ for (let count = leb(); count > 0; count--) {
100
+ if (leb() !== 0) throw new Error("swift-icu: unexpected data segment kind");
101
+ at++;
102
+ leb();
103
+ at++;
104
+ const length = leb();
105
+ const bytes = object.subarray(at, at + length);
106
+ if (bytes[2] === 218 && bytes[3] === 39) found.push(bytes);
107
+ at += length;
108
+ }
109
+ }
110
+ at = end;
111
+ }
112
+ if (found.length !== 1)
113
+ throw new Error(`swift-icu: expected one icu data segment, found ${found.length}`);
114
+ return found[0];
115
+ }
18
116
 
19
117
  // src/swift-package.ts
20
118
  function swiftManifestTargets(manifest) {
@@ -25,7 +123,8 @@ function swiftManifestTargets(manifest) {
25
123
  while ((match = pattern.exec(code)) !== null) {
26
124
  const executable = match[1] === "executableTarget";
27
125
  let depth = 1;
28
- let i = pattern.lastIndex;
126
+ const start = pattern.lastIndex;
127
+ let i = start;
29
128
  let inString = false;
30
129
  let escaped = false;
31
130
  let flat = "";
@@ -54,26 +153,67 @@ function swiftManifestTargets(manifest) {
54
153
  if (!name) continue;
55
154
  const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
56
155
  const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
57
- targets.push({ name, path: targetPath, executable });
156
+ const call = code.slice(start, i);
157
+ const languageMode = Number(
158
+ /\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
159
+ );
160
+ const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
161
+ targets.push({ name, path: targetPath, executable, languageMode, mainActorIsolation });
58
162
  }
59
163
  return targets;
60
164
  }
165
+ function swiftPackagePartition(manifest) {
166
+ const targets = swiftManifestTargets(manifest);
167
+ return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
168
+ }
61
169
 
62
170
  // src/swift-compile.ts
63
- var run = promisify(execFile);
171
+ var run2 = promisify2(execFile2);
64
172
  var WASM_TRIPLE = "wasm32-unknown-wasip1";
173
+ var cores = os.availableParallelism();
174
+ var BUILD_ENV = { ...process.env, BINARYEN_CORES: String(Math.min(4, cores)) };
175
+ var BUILD_JOBS = String(Math.max(1, Math.floor(cores / 2)));
65
176
  function swiftModuleInputFiles(root) {
66
- const files = ["Package.swift", "scripts/contrast-app-Package.swift"];
177
+ const files = [
178
+ "Package.swift",
179
+ "scripts/contrast-app-Package.swift",
180
+ "toolchain.json"
181
+ ];
67
182
  const walk = (dir) => {
68
- for (const entry of readdirSync(path.join(root, dir), { withFileTypes: true })) {
183
+ for (const entry of readdirSync(path2.join(root, dir), { withFileTypes: true })) {
69
184
  const relative = `${dir}/${entry.name}`;
70
185
  if (entry.isDirectory()) walk(relative);
71
- else if (entry.name.endsWith(".swift")) files.push(relative);
186
+ else if (/\.(swift|c|h)$/.test(entry.name)) files.push(relative);
72
187
  }
73
188
  };
74
189
  walk("Sources");
75
190
  return files.sort();
76
191
  }
192
+ async function ensureMacroPlugins(moduleRoot, toolchainBin) {
193
+ const dir = path2.join(moduleRoot, ".build/host/RnxPreviewMacros");
194
+ const ext = process.platform === "darwin" ? "dylib" : "so";
195
+ const plugins = [
196
+ {
197
+ library: path2.join(dir, `libRnxPreviewMacros.${ext}`),
198
+ source: path2.join(moduleRoot, "Sources/RnxPreviewMacros/PreviewMacro.swift")
199
+ },
200
+ {
201
+ library: path2.join(dir, `libFoundationMacros.${ext}`),
202
+ source: path2.join(moduleRoot, "Sources/FoundationMacros/PredicateMacro.swift")
203
+ }
204
+ ];
205
+ const stale = plugins.some(
206
+ ({ library, source }) => !existsSync(library) || statSync(source).mtimeMs > statSync(library).mtimeMs
207
+ );
208
+ if (stale) {
209
+ await run2("sh", [
210
+ path2.join(moduleRoot, "scripts/build-preview-plugin.sh"),
211
+ toolchainBin,
212
+ plugins[0].library
213
+ ]);
214
+ }
215
+ return plugins.map(({ library }) => library);
216
+ }
77
217
  var linkedModuleDigests = /* @__PURE__ */ new Map();
78
218
  function clearLinkedModuleDigests(root) {
79
219
  if (root === void 0) linkedModuleDigests.clear();
@@ -81,9 +221,9 @@ function clearLinkedModuleDigests(root) {
81
221
  }
82
222
  function linkedModuleDigest(root) {
83
223
  const files = swiftModuleInputFiles(root);
84
- const stampHash = createHash("sha256");
224
+ const stampHash = createHash2("sha256");
85
225
  for (const file of files) {
86
- const stat = statSync(path.join(root, file), { bigint: true });
226
+ const stat = statSync(path2.join(root, file), { bigint: true });
87
227
  stampHash.update(file);
88
228
  stampHash.update(
89
229
  `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}
@@ -93,11 +233,11 @@ function linkedModuleDigest(root) {
93
233
  const stamp = stampHash.digest("hex");
94
234
  const cached = linkedModuleDigests.get(root);
95
235
  if (cached?.stamp === stamp) return cached.digest;
96
- const hash = createHash("sha256");
236
+ const hash = createHash2("sha256");
97
237
  for (const file of files) {
98
- hash.update(createHash("sha256").update(file).digest());
238
+ hash.update(createHash2("sha256").update(file).digest());
99
239
  hash.update(
100
- createHash("sha256").update(readFileSync(path.join(root, file))).digest()
240
+ createHash2("sha256").update(readFileSync2(path2.join(root, file))).digest()
101
241
  );
102
242
  }
103
243
  const digest = hash.digest();
@@ -106,7 +246,22 @@ function linkedModuleDigest(root) {
106
246
  }
107
247
  function compileTargets(input) {
108
248
  const manifest = input.files["Package.swift"];
109
- return manifest === void 0 ? [] : swiftManifestTargets(manifest);
249
+ return manifest === void 0 ? [] : swiftPackagePartition(manifest);
250
+ }
251
+ function withNativeSourceGlue(input, glue) {
252
+ const targets = compileTargets(input);
253
+ if (targets.length > 1) {
254
+ throw new Error("swift native modules need one SwiftPM target");
255
+ }
256
+ const targetPath = targets[0]?.path === "." ? "" : targets[0]?.path ?? "";
257
+ return {
258
+ ...input,
259
+ files: {
260
+ ...input.files,
261
+ [path2.posix.join(targetPath, "OneNativeSource.generated.swift")]: glue
262
+ },
263
+ oneModule: true
264
+ };
110
265
  }
111
266
  function swiftSiblingDependencies(files, targets) {
112
267
  const names = new Set(targets.map((target) => target.name));
@@ -116,7 +271,9 @@ function swiftSiblingDependencies(files, targets) {
116
271
  const deps = /* @__PURE__ */ new Set();
117
272
  for (const [file, contents] of Object.entries(files)) {
118
273
  if (file === "Package.swift" || !file.startsWith(prefix)) continue;
119
- for (const match of contents.matchAll(/^\s*import\s+([A-Za-z_][A-Za-z0-9_]*)/gm)) {
274
+ for (const match of contents.matchAll(
275
+ /^\s*(?:@\w+(?:\([^)]*\))?\s+)*import\s+(?:(?:typealias|struct|class|enum|protocol|let|var|func)\s+)?([A-Za-z_][A-Za-z0-9_]*)/gm
276
+ )) {
120
277
  if (names.has(match[1]) && match[1] !== target.name) deps.add(match[1]);
121
278
  }
122
279
  }
@@ -124,29 +281,32 @@ function swiftSiblingDependencies(files, targets) {
124
281
  }
125
282
  return siblings;
126
283
  }
127
- var MULTI_MANIFEST_VERSION = 1;
284
+ var ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")';
285
+ var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"';
286
+ var MULTI_MANIFEST_VERSION = 5;
128
287
  function swiftArtifactHash(input, release, moduleRoot) {
129
- const hash = createHash("sha256");
288
+ const hash = createHash2("sha256");
130
289
  hash.update(`swift-compile/v1
131
290
  ${release}
132
291
  `);
292
+ if (input.oneModule) hash.update("one-module\n");
133
293
  hash.update(linkedModuleDigest(moduleRoot));
134
294
  for (const file of Object.keys(input.files).sort()) {
135
- hash.update(createHash("sha256").update(file).digest());
136
- hash.update(createHash("sha256").update(input.files[file]).digest());
295
+ hash.update(createHash2("sha256").update(file).digest());
296
+ hash.update(createHash2("sha256").update(input.files[file]).digest());
137
297
  }
138
298
  for (const base of Object.keys(input.resources ?? {}).sort()) {
139
- hash.update(createHash("sha256").update(base).digest());
299
+ hash.update(createHash2("sha256").update(base).digest());
140
300
  hash.update(
141
- createHash("sha256").update(input.resources?.[base] ?? "").digest()
301
+ createHash2("sha256").update(input.resources?.[base] ?? "").digest()
142
302
  );
143
303
  }
144
304
  for (const name of Object.keys(input.images ?? {}).sort()) {
145
305
  const image = input.images?.[name];
146
306
  if (!image) continue;
147
- hash.update(createHash("sha256").update(name).digest());
148
- hash.update(createHash("sha256").update(image.file).digest());
149
- hash.update(createHash("sha256").update(image.data).digest());
307
+ hash.update(createHash2("sha256").update(name).digest());
308
+ hash.update(createHash2("sha256").update(image.file).digest());
309
+ hash.update(createHash2("sha256").update(image.data).digest());
150
310
  }
151
311
  const targets = compileTargets(input);
152
312
  if (targets.length > 0) {
@@ -164,13 +324,15 @@ ${release}
164
324
  return hash.digest("hex");
165
325
  }
166
326
  function emitSwiftPackageManifest(args) {
167
- const { targets, siblings, moduleRoot } = args;
327
+ const { targets, siblings, moduleRoot, oneModule } = args;
168
328
  const executable = targets.find((target) => target.executable);
169
329
  if (!executable) throw new Error("swift-compile: no executable target to emit");
170
- const swiftSettings = 'swiftSettings: [.swiftLanguageMode(.v5), .unsafeFlags(["-Osize"])]';
171
330
  const stanza = (target) => {
331
+ const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
332
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
172
333
  const deps = [
173
334
  '.product(name: "SwiftUI", package: "sootsim-swift")',
335
+ ...oneModule ? [ONE_PRODUCT] : [],
174
336
  ...(siblings.get(target.name) ?? []).map((sibling) => `"${sibling}"`)
175
337
  ].join(", ");
176
338
  const kind = target.executable ? ".executableTarget" : ".target";
@@ -192,7 +354,7 @@ function emitSwiftPackageManifest(args) {
192
354
  ].join("\n");
193
355
  };
194
356
  return [
195
- "// swift-tools-version: 6.0",
357
+ "// swift-tools-version: 6.2",
196
358
  "import PackageDescription",
197
359
  "",
198
360
  "// generated by swift-compile from the project package partition.",
@@ -207,42 +369,63 @@ function emitSwiftPackageManifest(args) {
207
369
  ""
208
370
  ].join("\n");
209
371
  }
372
+ function syncSwiftTree(base, files) {
373
+ mkdirSync(base, { recursive: true });
374
+ const walk = (dir) => {
375
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
376
+ const full = path2.join(dir, entry.name);
377
+ if (dir === base && entry.name === ".build") continue;
378
+ if (entry.isDirectory()) walk(full);
379
+ else if (!files.has(full)) rmSync(full, { force: true });
380
+ }
381
+ };
382
+ walk(base);
383
+ for (const [full, contents] of files) {
384
+ if (existsSync(full) && readFileSync2(full, "utf8") === contents) continue;
385
+ mkdirSync(path2.dirname(full), { recursive: true });
386
+ writeFileSync(full, contents, "utf8");
387
+ }
388
+ }
210
389
  function writeSwiftProject(layout, input, moduleRoot) {
211
390
  const targets = compileTargets(input);
391
+ const files = /* @__PURE__ */ new Map();
212
392
  if (targets.length === 0) {
213
- rmSync(layout.sources, { recursive: true, force: true });
214
393
  for (const [file, contents] of Object.entries(input.files)) {
215
- const target = path.join(layout.sources, file);
216
- mkdirSync(path.dirname(target), { recursive: true });
217
- writeFileSync(target, contents, "utf8");
394
+ if (file === "Package.swift") continue;
395
+ files.set(path2.join(layout.sources, file), contents);
218
396
  }
219
- const manifest = readFileSync(
220
- path.join(moduleRoot, "scripts/contrast-app-Package.swift"),
397
+ let manifest = readFileSync2(
398
+ path2.join(moduleRoot, "scripts/contrast-app-Package.swift"),
221
399
  "utf8"
222
400
  ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
223
- writeFileSync(path.join(layout.root, "Package.swift"), manifest, "utf8");
224
- return;
225
- }
226
- mkdirSync(layout.root, { recursive: true });
227
- for (const child of readdirSync(layout.root)) {
228
- if (child === ".build") continue;
229
- rmSync(path.join(layout.root, child), { recursive: true, force: true });
230
- }
231
- for (const [file, contents] of Object.entries(input.files)) {
232
- if (file === "Package.swift") continue;
233
- const target = path.join(layout.root, file);
234
- mkdirSync(path.dirname(target), { recursive: true });
235
- writeFileSync(target, contents, "utf8");
401
+ if (input.oneModule) {
402
+ const product = '.product(name: "CoreLocation", package: "sootsim-swift"),';
403
+ const flags = '"-Osize"';
404
+ if (!manifest.includes(product) || !manifest.includes(flags)) {
405
+ throw new Error(
406
+ "scripts/contrast-app-Package.swift lost the lines the One module links at"
407
+ );
408
+ }
409
+ manifest = manifest.replace(product, `${product}
410
+ ${ONE_PRODUCT},`).replace(flags, `${flags}${ONE_IMPLICIT_FLAGS}`);
411
+ }
412
+ files.set(path2.join(layout.root, "Package.swift"), manifest);
413
+ } else {
414
+ for (const [file, contents] of Object.entries(input.files)) {
415
+ if (file === "Package.swift") continue;
416
+ files.set(path2.join(layout.root, file), contents);
417
+ }
418
+ files.set(
419
+ path2.join(layout.root, "Package.swift"),
420
+ emitSwiftPackageManifest({
421
+ targets,
422
+ siblings: swiftSiblingDependencies(input.files, targets),
423
+ moduleRoot,
424
+ oneModule: input.oneModule
425
+ })
426
+ );
236
427
  }
237
- writeFileSync(
238
- path.join(layout.root, "Package.swift"),
239
- emitSwiftPackageManifest({
240
- targets,
241
- siblings: swiftSiblingDependencies(input.files, targets),
242
- moduleRoot
243
- }),
244
- "utf8"
245
- );
428
+ syncSwiftTree(layout.root, files);
246
429
  }
247
430
  function streamText(value) {
248
431
  if (typeof value === "string") return value.trim();
@@ -260,18 +443,24 @@ function outputOf(error) {
260
443
  return error instanceof Error ? error.message : String(error);
261
444
  }
262
445
  function builtArtifact(layout) {
263
- const binDir = path.join(layout.root, ".build", WASM_TRIPLE, "release");
264
- const artifacts = existsSync(binDir) ? readdirSync(binDir).filter((name) => name.endsWith(".wasm")).sort() : [];
265
- if (artifacts.length !== 1) {
446
+ const binDir = path2.join(layout.root, ".build", WASM_TRIPLE, "release");
447
+ const manifest = readFileSync2(path2.join(layout.root, "Package.swift"), "utf8");
448
+ const executable = swiftManifestTargets(manifest).find((target) => target.executable);
449
+ if (executable === void 0) {
450
+ throw new Error("swift-compile: the written manifest names no executable target");
451
+ }
452
+ const file = path2.join(binDir, `${executable.name}.wasm`);
453
+ if (!existsSync(file)) {
454
+ const found = existsSync(binDir) ? readdirSync(binDir).filter((name) => name.endsWith(".wasm")).sort() : [];
266
455
  throw new Error(
267
- `swift-compile: the build produced ${artifacts.length} wasm artifacts; exactly one executable is the app`
456
+ `swift-compile: the build produced no ${executable.name}.wasm (found: ${found.join(", ") || "none"})`
268
457
  );
269
458
  }
270
- return path.join(binDir, artifacts[0]);
459
+ return file;
271
460
  }
272
461
  function projectDiagnostic(output, layout) {
273
462
  const base = layout.multi ? layout.root : layout.sources;
274
- const prefix = `${base}${path.sep}`;
463
+ const prefix = `${base}${path2.sep}`;
275
464
  return output.split("\n").map((line) => line.startsWith(prefix) ? line.slice(prefix.length) : line).join("\n").trim();
276
465
  }
277
466
  var ROOT_LOCKS = Symbol.for("peachsim.swiftCompile.rootLocks");
@@ -290,26 +479,30 @@ function serialize(root, work) {
290
479
  function compileSwiftProjectUnit(input, options) {
291
480
  mkdirSync(options.buildRoot, { recursive: true });
292
481
  const root = realpathSync(options.buildRoot);
293
- const moduleRoot = path.resolve(options.moduleRoot);
482
+ const moduleRoot = path2.resolve(options.moduleRoot);
294
483
  const layout = {
295
484
  root,
296
- sources: path.join(root, "Sources", "App"),
485
+ sources: path2.join(root, "Sources", "App"),
297
486
  multi: compileTargets(input).length > 0
298
487
  };
299
488
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
300
489
  return serialize(root, async () => {
301
490
  writeSwiftProject(layout, input, moduleRoot);
302
- const swift = path.join(options.toolchainBin, "swift");
491
+ const swift = path2.join(options.toolchainBin, "swift");
303
492
  if (!existsSync(swift)) {
304
493
  throw new Error(
305
494
  `swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`
306
495
  );
307
496
  }
497
+ const macroPlugins = await ensureMacroPlugins(moduleRoot, options.toolchainBin);
498
+ const icu = swiftIcuAsset(options.toolchainBin, options.release);
308
499
  try {
309
- await run(
500
+ await run2(
310
501
  swift,
311
502
  [
312
503
  "build",
504
+ "-j",
505
+ BUILD_JOBS,
313
506
  "--package-path",
314
507
  root,
315
508
  "--swift-sdk",
@@ -317,14 +510,24 @@ function compileSwiftProjectUnit(input, options) {
317
510
  "-c",
318
511
  "release",
319
512
  "-Xswiftc",
320
- "-Osize"
513
+ "-Osize",
514
+ ...macroPlugins.flatMap((plugin) => [
515
+ "-Xswiftc",
516
+ "-load-plugin-library",
517
+ "-Xswiftc",
518
+ plugin
519
+ ])
321
520
  ],
322
- { maxBuffer: 64 * 1024 * 1024, timeout: options.timeoutMs }
521
+ { env: BUILD_ENV, maxBuffer: 64 * 1024 * 1024, timeout: options.timeoutMs }
323
522
  );
324
523
  } catch (error) {
325
524
  throw new Error(projectDiagnostic(outputOf(error), layout), { cause: error });
326
525
  }
327
- return { hash, bytes: readFileSync(builtArtifact(layout)) };
526
+ return {
527
+ hash,
528
+ bytes: readFileSync2(builtArtifact(layout)),
529
+ icu: await icu
530
+ };
328
531
  });
329
532
  }
330
533
  export {
@@ -334,6 +537,8 @@ export {
334
537
  compileTargets,
335
538
  emitSwiftPackageManifest,
336
539
  swiftArtifactHash,
540
+ swiftIcuAsset,
337
541
  swiftModuleInputFiles,
542
+ withNativeSourceGlue,
338
543
  writeSwiftProject
339
544
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.578 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.579 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -23,7 +23,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
23
23
  var swift_package_exports = {};
24
24
  __export(swift_package_exports, {
25
25
  isSwiftManifestFile: () => isSwiftManifestFile,
26
- swiftManifestTargets: () => swiftManifestTargets
26
+ swiftManifestTargets: () => swiftManifestTargets,
27
+ swiftPackagePartition: () => swiftPackagePartition
27
28
  });
28
29
  module.exports = __toCommonJS(swift_package_exports);
29
30
  function isSwiftManifestFile(file) {
@@ -38,7 +39,8 @@ function swiftManifestTargets(manifest) {
38
39
  while ((match = pattern.exec(code)) !== null) {
39
40
  const executable = match[1] === "executableTarget";
40
41
  let depth = 1;
41
- let i = pattern.lastIndex;
42
+ const start = pattern.lastIndex;
43
+ let i = start;
42
44
  let inString = false;
43
45
  let escaped = false;
44
46
  let flat = "";
@@ -67,12 +69,22 @@ function swiftManifestTargets(manifest) {
67
69
  if (!name) continue;
68
70
  const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
69
71
  const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
70
- targets.push({ name, path: targetPath, executable });
72
+ const call = code.slice(start, i);
73
+ const languageMode = Number(
74
+ /\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
75
+ );
76
+ const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
77
+ targets.push({ name, path: targetPath, executable, languageMode, mainActorIsolation });
71
78
  }
72
79
  return targets;
73
80
  }
81
+ function swiftPackagePartition(manifest) {
82
+ const targets = swiftManifestTargets(manifest);
83
+ return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
84
+ }
74
85
  // Annotate the CommonJS export names for ESM import in node:
75
86
  0 && (module.exports = {
76
87
  isSwiftManifestFile,
77
- swiftManifestTargets
88
+ swiftManifestTargets,
89
+ swiftPackagePartition
78
90
  });
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.578 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.579 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-package.ts
4
4
  function isSwiftManifestFile(file) {
@@ -13,7 +13,8 @@ function swiftManifestTargets(manifest) {
13
13
  while ((match = pattern.exec(code)) !== null) {
14
14
  const executable = match[1] === "executableTarget";
15
15
  let depth = 1;
16
- let i = pattern.lastIndex;
16
+ const start = pattern.lastIndex;
17
+ let i = start;
17
18
  let inString = false;
18
19
  let escaped = false;
19
20
  let flat = "";
@@ -42,11 +43,21 @@ function swiftManifestTargets(manifest) {
42
43
  if (!name) continue;
43
44
  const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
44
45
  const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
45
- targets.push({ name, path: targetPath, executable });
46
+ const call = code.slice(start, i);
47
+ const languageMode = Number(
48
+ /\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
49
+ );
50
+ const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
51
+ targets.push({ name, path: targetPath, executable, languageMode, mainActorIsolation });
46
52
  }
47
53
  return targets;
48
54
  }
55
+ function swiftPackagePartition(manifest) {
56
+ const targets = swiftManifestTargets(manifest);
57
+ return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
58
+ }
49
59
  export {
50
60
  isSwiftManifestFile,
51
- swiftManifestTargets
61
+ swiftManifestTargets,
62
+ swiftPackagePartition
52
63
  };