peachsim 0.1.645 → 0.1.647

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 (69) hide show
  1. package/cli/commands/control.ts +20 -1
  2. package/cli/desktop-companion.ts +48 -8
  3. package/cli/drivers/electron.ts +1 -3
  4. package/dist-lib/agent-daemon-client.cjs +1 -1
  5. package/dist-lib/agent-events.cjs +1 -1
  6. package/dist-lib/agent-identity.cjs +1 -1
  7. package/dist-lib/agent-sessions.cjs +1 -1
  8. package/dist-lib/attached-projects.cjs +1 -1
  9. package/dist-lib/auth/shared-session.cjs +1 -1
  10. package/dist-lib/backend-origin.cjs +1 -1
  11. package/dist-lib/beta.cjs +1 -1
  12. package/dist-lib/beta.mjs +1 -1
  13. package/dist-lib/bridge-constants.cjs +1 -1
  14. package/dist-lib/bridge-contract-input.cjs +1 -1
  15. package/dist-lib/bridge-contract-input.mjs +1 -1
  16. package/dist-lib/bridge-contract.cjs +1 -1
  17. package/dist-lib/bridge-contract.mjs +1 -1
  18. package/dist-lib/capture-contract.cjs +1 -1
  19. package/dist-lib/capture-contract.mjs +1 -1
  20. package/dist-lib/cli-constants.cjs +1 -1
  21. package/dist-lib/cloud-contract.cjs +1 -1
  22. package/dist-lib/cloud-contract.mjs +1 -1
  23. package/dist-lib/cloud-test-args.cjs +1 -1
  24. package/dist-lib/cloud-test-args.mjs +1 -1
  25. package/dist-lib/cloud.cjs +1 -1
  26. package/dist-lib/cloud.mjs +1 -1
  27. package/dist-lib/config.cjs +1 -1
  28. package/dist-lib/detox/index.cjs +1 -1
  29. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  30. package/dist-lib/home-paths.cjs +1 -1
  31. package/dist-lib/host/bridge-host.cjs +1 -1
  32. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  33. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  34. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  35. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  36. package/dist-lib/host/websocket-proxy.cjs +1 -1
  37. package/dist-lib/index.cjs +1 -1
  38. package/dist-lib/jump-to-source-babel.cjs +1 -1
  39. package/dist-lib/jump-to-source-native.cjs +1 -1
  40. package/dist-lib/kotlin-host.cjs +1 -1
  41. package/dist-lib/menu.cjs +1 -1
  42. package/dist-lib/menu.mjs +1 -1
  43. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  45. package/dist-lib/metro-production-bundle.cjs +1 -1
  46. package/dist-lib/metro-production-bundle.mjs +1 -1
  47. package/dist-lib/metro.cjs +1 -1
  48. package/dist-lib/native-app-identity.cjs +1 -1
  49. package/dist-lib/native-app-identity.mjs +1 -1
  50. package/dist-lib/profiles.cjs +1 -1
  51. package/dist-lib/public-brand.cjs +1 -1
  52. package/dist-lib/react-native-host-modules.cjs +1 -1
  53. package/dist-lib/react-native-host-modules.mjs +1 -1
  54. package/dist-lib/render-mode.cjs +1 -1
  55. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  56. package/dist-lib/sdk.cjs +1 -1
  57. package/dist-lib/sdk.mjs +1 -1
  58. package/dist-lib/skills.cjs +37 -10
  59. package/dist-lib/swift-compile.cjs +15 -3
  60. package/dist-lib/swift-compile.mjs +15 -3
  61. package/dist-lib/swift-package.cjs +1 -1
  62. package/dist-lib/swift-package.mjs +1 -1
  63. package/dist-lib/swift-submit.cjs +1 -1
  64. package/dist-lib/swift-submit.mjs +1 -1
  65. package/dist-lib/swift.cjs +1 -1
  66. package/dist-lib/vite-swift.cjs +15 -3
  67. package/dist-lib/vite.cjs +1 -1
  68. package/package.json +1 -1
  69. package/src/swift-compile.ts +31 -7
@@ -867,6 +867,10 @@ export interface BuildShellUrlOptions {
867
867
  // after the app path lands inside the bundle param and never reaches the
868
868
  // shell. non-foldable devices resolve it to closed at boot.
869
869
  posture?: string
870
+ // interface orientation (portrait|landscape) stamped as ?orientation=,
871
+ // which the shell reads at boot over the device's default: an open duo
872
+ // boots landscape unless this asks for it upright.
873
+ orientation?: string
870
874
  // portrayed os version (major.minor) stamped as ?osVersion=, which the
871
875
  // shell pins at boot over the device profile's own version. an oracle on a
872
876
  // newer os than the profile compares only when the sim runs that os era.
@@ -924,6 +928,7 @@ export async function buildShellUrl(
924
928
  !opts.device &&
925
929
  !opts.proof &&
926
930
  !opts.posture &&
931
+ !opts.orientation &&
927
932
  !opts.osVersion &&
928
933
  !opts.env?.length &&
929
934
  !opts.dotEnv
@@ -933,6 +938,7 @@ export async function buildShellUrl(
933
938
  if (opts.dotEnv) url.searchParams.set('dotEnv', JSON.stringify(opts.dotEnv))
934
939
  if (opts.device) url.searchParams.set('device', opts.device)
935
940
  if (opts.posture) url.searchParams.set('posture', opts.posture)
941
+ if (opts.orientation) url.searchParams.set('orientation', opts.orientation)
936
942
  if (opts.osVersion) url.searchParams.set('osVersion', opts.osVersion)
937
943
  if (opts.proof) url.searchParams.set('proof', '1')
938
944
  for (const entry of opts.env ?? []) url.searchParams.append('env', entry)
@@ -1483,6 +1489,7 @@ export async function runOpenCommand(
1483
1489
  '--cdp-port',
1484
1490
  '--device',
1485
1491
  '--posture',
1492
+ '--orientation',
1486
1493
  '--os-version',
1487
1494
  '--viewport',
1488
1495
  '--env',
@@ -1679,6 +1686,17 @@ export async function runOpenCommand(
1679
1686
  console.error(` peach open: --posture must be open or closed, got "${postureArg}"`)
1680
1687
  rnxExit(1)
1681
1688
  }
1689
+ const orientationFlag = args.find((_, i) => args[i - 1] === '--orientation')
1690
+ const orientationArg =
1691
+ orientationFlag === 'portrait' || orientationFlag === 'landscape'
1692
+ ? orientationFlag
1693
+ : undefined
1694
+ if (orientationFlag && !orientationArg) {
1695
+ console.error(
1696
+ ` peach open: --orientation must be portrait or landscape, got "${orientationFlag}"`,
1697
+ )
1698
+ rnxExit(1)
1699
+ }
1682
1700
  // the window fits the box the browser stage fits the device into, which for
1683
1701
  // a foldable spans both postures, so the device draws at its natural size in
1684
1702
  // the posture it opens in instead of shrinking into a window sized for one.
@@ -1686,7 +1704,7 @@ export async function runOpenCommand(
1686
1704
  ? resolveDeviceFitBox(
1687
1705
  deviceArg as DeviceModel,
1688
1706
  false,
1689
- undefined,
1707
+ orientationArg,
1690
1708
  postureArg === 'open' ? 'open' : 'closed',
1691
1709
  )
1692
1710
  : undefined
@@ -1762,6 +1780,7 @@ export async function runOpenCommand(
1762
1780
  hot: hotMode,
1763
1781
  device: deviceArg,
1764
1782
  posture: postureArg,
1783
+ orientation: orientationArg,
1765
1784
  osVersion: osVersionArg,
1766
1785
  resolvedBundle,
1767
1786
  project,
@@ -24,7 +24,13 @@ const PEACH_BUNDLE_ID = 'dev.peachsim.simulator'
24
24
  export interface DesktopCompanionInstall {
25
25
  path: string
26
26
  platform: NodeJS.Platform
27
- kind: 'mac-app' | 'linux-appimage' | 'linux-binary' | 'win-exe' | 'dev-electron'
27
+ kind:
28
+ | 'native-mac-app'
29
+ | 'mac-app'
30
+ | 'linux-appimage'
31
+ | 'linux-binary'
32
+ | 'win-exe'
33
+ | 'dev-electron'
28
34
  // present for dev-electron: the sootsim-engine dir that electron treats
29
35
  // as the app root (its package.json "main" points at dist-electron/main.cjs).
30
36
  engineDir?: string
@@ -32,7 +38,13 @@ export interface DesktopCompanionInstall {
32
38
 
33
39
  export interface DesktopCompanionLaunchResult {
34
40
  launched: boolean
35
- via?: 'mac-app' | 'linux-appimage' | 'linux-binary' | 'win-exe' | 'dev-electron'
41
+ via?:
42
+ | 'native-mac-app'
43
+ | 'mac-app'
44
+ | 'linux-appimage'
45
+ | 'linux-binary'
46
+ | 'win-exe'
47
+ | 'dev-electron'
36
48
  target?: string
37
49
  }
38
50
 
@@ -218,6 +230,17 @@ function findWindowsInstall(): DesktopCompanionInstall | null {
218
230
  }
219
231
 
220
232
  export function findDesktopCompanion(): DesktopCompanionInstall | null {
233
+ const explicitApp = process.env.PEACH_DESKTOP_APP
234
+ if (explicitApp) {
235
+ if (process.platform !== 'darwin' || !explicitApp.endsWith('.app')) {
236
+ throw new Error('PEACH_DESKTOP_APP must name a Mac .app bundle')
237
+ }
238
+ const appPath = resolve(explicitApp)
239
+ if (!existsSync(join(appPath, 'Contents/MacOS/PeachDesktop'))) {
240
+ throw new Error(`native desktop executable missing in ${appPath}`)
241
+ }
242
+ return { path: appPath, platform: 'darwin', kind: 'native-mac-app' }
243
+ }
221
244
  const dev = findDevElectron()
222
245
  if (dev) return dev
223
246
  if (isInRepoCheckout()) {
@@ -300,14 +323,20 @@ export async function launchDesktopCompanion(
300
323
  if (opts.ephemeralProfile) extraArgs.push('--ephemeral-profile')
301
324
  if (opts.ownerPid && opts.ownerPid > 1) extraArgs.push(`--owner-pid=${opts.ownerPid}`)
302
325
 
303
- if (install.kind === 'mac-app') {
326
+ if (install.kind === 'mac-app' || install.kind === 'native-mac-app') {
304
327
  // `open -a` splits app args before and after `--args`. anything after
305
328
  // --args is forwarded to electron's process.argv.
329
+ const nativeApp = install.kind === 'native-mac-app'
306
330
  const openArgs: string[] = ['-g', '-a', install.path]
307
- if (url) openArgs.push(buildMacLaunchUrl(url, opts))
331
+ if (url) openArgs.push(buildMacLaunchUrl(url, opts, nativeApp))
332
+ else if (
333
+ nativeApp &&
334
+ (opts.profileId || opts.ephemeralProfile || opts.ownerPid || opts.device)
335
+ )
336
+ openArgs.push(buildMacLaunchUrl(undefined, opts, true))
308
337
  if (extraArgs.length > 0) openArgs.push('--args', ...extraArgs)
309
338
  await spawnDetached('open', openArgs)
310
- return { launched: true, via: 'mac-app', target: install.path }
339
+ return { launched: true, via: install.kind, target: install.path }
311
340
  }
312
341
 
313
342
  if (install.kind === 'dev-electron') {
@@ -334,10 +363,21 @@ export async function launchDesktopCompanion(
334
363
  }
335
364
  }
336
365
 
337
- function buildMacLaunchUrl(url: string, opts: LaunchCompanionOptions): string {
338
- if (!opts.profileId && !opts.ephemeralProfile && !opts.ownerPid) return url
366
+ function buildMacLaunchUrl(
367
+ url: string | undefined,
368
+ opts: LaunchCompanionOptions,
369
+ nativeApp = false,
370
+ ): string {
371
+ if (
372
+ !opts.profileId &&
373
+ !opts.ephemeralProfile &&
374
+ !opts.ownerPid &&
375
+ (!nativeApp || !opts.device)
376
+ )
377
+ return url || ''
339
378
  const deepLink = new URL('peach://dev')
340
- deepLink.searchParams.set('url', url)
379
+ if (url) deepLink.searchParams.set('url', url)
380
+ if (nativeApp && opts.device) deepLink.searchParams.set('device', opts.device)
341
381
  if (opts.profileId) deepLink.searchParams.set('profile', opts.profileId)
342
382
  if (opts.ephemeralProfile) deepLink.searchParams.set('ephemeral', '1')
343
383
  if (opts.ownerPid && opts.ownerPid > 1) {
@@ -46,9 +46,7 @@ async function launch(opts: DriverLaunchOptions): Promise<DriverLaunchResult> {
46
46
  }
47
47
  return {
48
48
  launched: true,
49
- message: opts.url
50
- ? `electron launched via ${result.via} → ${opts.url}`
51
- : `electron launched via ${result.via}`,
49
+ message: `${install.kind === 'native-mac-app' ? 'native desktop' : 'electron'} launched via ${result.via}${opts.url ? ` → ${opts.url}` : ''}`,
52
50
  target: result.target,
53
51
  attachUrl: opts.url,
54
52
  }
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
package/dist-lib/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
package/dist-lib/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
package/dist-lib/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
package/dist-lib/menu.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -34145,6 +34145,17 @@ function findWindowsInstall() {
34145
34145
  return null;
34146
34146
  }
34147
34147
  function findDesktopCompanion() {
34148
+ const explicitApp = process.env.PEACH_DESKTOP_APP;
34149
+ if (explicitApp) {
34150
+ if (process.platform !== "darwin" || !explicitApp.endsWith(".app")) {
34151
+ throw new Error("PEACH_DESKTOP_APP must name a Mac .app bundle");
34152
+ }
34153
+ const appPath = (0, import_path5.resolve)(explicitApp);
34154
+ if (!(0, import_fs6.existsSync)((0, import_path5.join)(appPath, "Contents/MacOS/PeachDesktop"))) {
34155
+ throw new Error(`native desktop executable missing in ${appPath}`);
34156
+ }
34157
+ return { path: appPath, platform: "darwin", kind: "native-mac-app" };
34158
+ }
34148
34159
  const dev = findDevElectron();
34149
34160
  if (dev) return dev;
34150
34161
  if (isInRepoCheckout()) {
@@ -34186,12 +34197,15 @@ async function launchDesktopCompanion(url, install = findDesktopCompanion(), opt
34186
34197
  if (opts.profileId) extraArgs.push(`--profile=${opts.profileId}`);
34187
34198
  if (opts.ephemeralProfile) extraArgs.push("--ephemeral-profile");
34188
34199
  if (opts.ownerPid && opts.ownerPid > 1) extraArgs.push(`--owner-pid=${opts.ownerPid}`);
34189
- if (install.kind === "mac-app") {
34200
+ if (install.kind === "mac-app" || install.kind === "native-mac-app") {
34201
+ const nativeApp = install.kind === "native-mac-app";
34190
34202
  const openArgs = ["-g", "-a", install.path];
34191
- if (url) openArgs.push(buildMacLaunchUrl(url, opts));
34203
+ if (url) openArgs.push(buildMacLaunchUrl(url, opts, nativeApp));
34204
+ else if (nativeApp && (opts.profileId || opts.ephemeralProfile || opts.ownerPid || opts.device))
34205
+ openArgs.push(buildMacLaunchUrl(void 0, opts, true));
34192
34206
  if (extraArgs.length > 0) openArgs.push("--args", ...extraArgs);
34193
34207
  await spawnDetached("open", openArgs);
34194
- return { launched: true, via: "mac-app", target: install.path };
34208
+ return { launched: true, via: install.kind, target: install.path };
34195
34209
  }
34196
34210
  if (install.kind === "dev-electron") {
34197
34211
  const args = ["--no-sandbox", install.engineDir || getSootsimRoot()];
@@ -34210,10 +34224,12 @@ async function launchDesktopCompanion(url, install = findDesktopCompanion(), opt
34210
34224
  target: install.path
34211
34225
  };
34212
34226
  }
34213
- function buildMacLaunchUrl(url, opts) {
34214
- if (!opts.profileId && !opts.ephemeralProfile && !opts.ownerPid) return url;
34227
+ function buildMacLaunchUrl(url, opts, nativeApp = false) {
34228
+ if (!opts.profileId && !opts.ephemeralProfile && !opts.ownerPid && (!nativeApp || !opts.device))
34229
+ return url || "";
34215
34230
  const deepLink = new URL("peach://dev");
34216
- deepLink.searchParams.set("url", url);
34231
+ if (url) deepLink.searchParams.set("url", url);
34232
+ if (nativeApp && opts.device) deepLink.searchParams.set("device", opts.device);
34217
34233
  if (opts.profileId) deepLink.searchParams.set("profile", opts.profileId);
34218
34234
  if (opts.ephemeralProfile) deepLink.searchParams.set("ephemeral", "1");
34219
34235
  if (opts.ownerPid && opts.ownerPid > 1) {
@@ -34269,7 +34285,7 @@ async function launch(opts) {
34269
34285
  }
34270
34286
  return {
34271
34287
  launched: true,
34272
- message: opts.url ? `electron launched via ${result.via} \u2192 ${opts.url}` : `electron launched via ${result.via}`,
34288
+ message: `${install.kind === "native-mac-app" ? "native desktop" : "electron"} launched via ${result.via}${opts.url ? ` \u2192 ${opts.url}` : ""}`,
34273
34289
  target: result.target,
34274
34290
  attachUrl: opts.url
34275
34291
  };
@@ -35802,12 +35818,13 @@ async function buildShellUrl(target, baseUrl = resolveDefaultShellBaseUrl(), opt
35802
35818
  ),
35803
35819
  project
35804
35820
  );
35805
- if (!opts.device && !opts.proof && !opts.posture && !opts.osVersion && !opts.env?.length && !opts.dotEnv)
35821
+ if (!opts.device && !opts.proof && !opts.posture && !opts.orientation && !opts.osVersion && !opts.env?.length && !opts.dotEnv)
35806
35822
  return stamped;
35807
35823
  const url = new URL(stamped);
35808
35824
  if (opts.dotEnv) url.searchParams.set("dotEnv", JSON.stringify(opts.dotEnv));
35809
35825
  if (opts.device) url.searchParams.set("device", opts.device);
35810
35826
  if (opts.posture) url.searchParams.set("posture", opts.posture);
35827
+ if (opts.orientation) url.searchParams.set("orientation", opts.orientation);
35811
35828
  if (opts.osVersion) url.searchParams.set("osVersion", opts.osVersion);
35812
35829
  if (opts.proof) url.searchParams.set("proof", "1");
35813
35830
  for (const entry of opts.env ?? []) url.searchParams.append("env", entry);
@@ -36223,6 +36240,7 @@ async function runOpenCommand(args, opts = {}) {
36223
36240
  "--cdp-port",
36224
36241
  "--device",
36225
36242
  "--posture",
36243
+ "--orientation",
36226
36244
  "--os-version",
36227
36245
  "--viewport",
36228
36246
  "--env"
@@ -36363,10 +36381,18 @@ async function runOpenCommand(args, opts = {}) {
36363
36381
  console.error(` peach open: --posture must be open or closed, got "${postureArg}"`);
36364
36382
  rnxExit(1);
36365
36383
  }
36384
+ const orientationFlag = args.find((_, i) => args[i - 1] === "--orientation");
36385
+ const orientationArg = orientationFlag === "portrait" || orientationFlag === "landscape" ? orientationFlag : void 0;
36386
+ if (orientationFlag && !orientationArg) {
36387
+ console.error(
36388
+ ` peach open: --orientation must be portrait or landscape, got "${orientationFlag}"`
36389
+ );
36390
+ rnxExit(1);
36391
+ }
36366
36392
  const deviceFitBox = deviceArg ? (0, import_devices2.resolveDeviceFitBox)(
36367
36393
  deviceArg,
36368
36394
  false,
36369
- void 0,
36395
+ orientationArg,
36370
36396
  postureArg === "open" ? "open" : "closed"
36371
36397
  ) : void 0;
36372
36398
  const osVersionArg = args.find((_, i) => args[i - 1] === "--os-version");
@@ -36419,6 +36445,7 @@ async function runOpenCommand(args, opts = {}) {
36419
36445
  hot: hotMode,
36420
36446
  device: deviceArg,
36421
36447
  posture: postureArg,
36448
+ orientation: orientationArg,
36422
36449
  osVersion: osVersionArg,
36423
36450
  resolvedBundle,
36424
36451
  project,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -330,7 +330,7 @@ var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
330
330
  var MULTI_MANIFEST_VERSION = 6;
331
331
  function swiftArtifactHash(input, release, moduleRoot) {
332
332
  const hash = (0, import_node_crypto2.createHash)("sha256");
333
- hash.update(`swift-compile/v5
333
+ hash.update(`swift-compile/v6
334
334
  ${release}
335
335
  `);
336
336
  if (input.oneModule) hash.update("one-module\n");
@@ -434,6 +434,7 @@ var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
434
434
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
435
435
  var OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/;
436
436
  var SELECTOR = /^#selector\b/;
437
+ var DELEGATE_CLASS = /^class\s+[A-Za-z_]\w*\s*(?:<[^>{]*>)?\s*:[^{]*\b(?:UIApplicationDelegate|UISceneDelegate|UIWindowSceneDelegate)\b[^{]*\{/;
437
438
  function swiftSourceAsIOS(source) {
438
439
  const { lineStarts, tokens } = swiftCodeScan(source);
439
440
  let offset = 0;
@@ -446,7 +447,15 @@ function swiftSourceAsIOS(source) {
446
447
  let out = "";
447
448
  let copied = 0;
448
449
  for (const at of tokens) {
449
- const rest = conditioned.slice(at, at + 200);
450
+ const rest = conditioned.slice(at, at + 400);
451
+ if (rest.startsWith("class")) {
452
+ const modifiers = conditioned.slice(conditioned.lastIndexOf("\n", at - 1) + 1, at);
453
+ if (DELEGATE_CLASS.test(rest) && !/\b(?:final|open)\b/.test(modifiers)) {
454
+ out += `${conditioned.slice(copied, at)}final `;
455
+ copied = at;
456
+ }
457
+ continue;
458
+ }
450
459
  const selector = SELECTOR.exec(rest);
451
460
  const match = selector ?? OBJC_ATTRIBUTE.exec(rest);
452
461
  if (!match) continue;
@@ -539,6 +548,9 @@ function swiftCodeScan(source) {
539
548
  if (top.parens === 0 && stack.length > 1) stack.pop();
540
549
  else top.parens--;
541
550
  i++;
551
+ } else if (source.startsWith("class", i) && !/[\w$]/.test(source[i - 1] ?? "") && !/[\w$]/.test(source[i + 5] ?? "")) {
552
+ tokens.push(i);
553
+ i += 5;
542
554
  } else {
543
555
  if (char === "@") tokens.push(i);
544
556
  i++;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
4
  import { execFile as execFile2 } from "node:child_process";
@@ -295,7 +295,7 @@ var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
295
295
  var MULTI_MANIFEST_VERSION = 6;
296
296
  function swiftArtifactHash(input, release, moduleRoot) {
297
297
  const hash = createHash2("sha256");
298
- hash.update(`swift-compile/v5
298
+ hash.update(`swift-compile/v6
299
299
  ${release}
300
300
  `);
301
301
  if (input.oneModule) hash.update("one-module\n");
@@ -399,6 +399,7 @@ var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
399
399
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
400
400
  var OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/;
401
401
  var SELECTOR = /^#selector\b/;
402
+ var DELEGATE_CLASS = /^class\s+[A-Za-z_]\w*\s*(?:<[^>{]*>)?\s*:[^{]*\b(?:UIApplicationDelegate|UISceneDelegate|UIWindowSceneDelegate)\b[^{]*\{/;
402
403
  function swiftSourceAsIOS(source) {
403
404
  const { lineStarts, tokens } = swiftCodeScan(source);
404
405
  let offset = 0;
@@ -411,7 +412,15 @@ function swiftSourceAsIOS(source) {
411
412
  let out = "";
412
413
  let copied = 0;
413
414
  for (const at of tokens) {
414
- const rest = conditioned.slice(at, at + 200);
415
+ const rest = conditioned.slice(at, at + 400);
416
+ if (rest.startsWith("class")) {
417
+ const modifiers = conditioned.slice(conditioned.lastIndexOf("\n", at - 1) + 1, at);
418
+ if (DELEGATE_CLASS.test(rest) && !/\b(?:final|open)\b/.test(modifiers)) {
419
+ out += `${conditioned.slice(copied, at)}final `;
420
+ copied = at;
421
+ }
422
+ continue;
423
+ }
415
424
  const selector = SELECTOR.exec(rest);
416
425
  const match = selector ?? OBJC_ATTRIBUTE.exec(rest);
417
426
  if (!match) continue;
@@ -504,6 +513,9 @@ function swiftCodeScan(source) {
504
513
  if (top.parens === 0 && stack.length > 1) stack.pop();
505
514
  else top.parens--;
506
515
  i++;
516
+ } else if (source.startsWith("class", i) && !/[\w$]/.test(source[i - 1] ?? "") && !/[\w$]/.test(source[i + 5] ?? "")) {
517
+ tokens.push(i);
518
+ i += 5;
507
519
  } else {
508
520
  if (char === "@") tokens.push(i);
509
521
  i++;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
@@ -830,7 +830,7 @@ var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
830
830
  var MULTI_MANIFEST_VERSION = 6;
831
831
  function swiftArtifactHash(input, release, moduleRoot) {
832
832
  const hash = (0, import_node_crypto2.createHash)("sha256");
833
- hash.update(`swift-compile/v5
833
+ hash.update(`swift-compile/v6
834
834
  ${release}
835
835
  `);
836
836
  if (input.oneModule) hash.update("one-module\n");
@@ -934,6 +934,7 @@ var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
934
934
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
935
935
  var OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/;
936
936
  var SELECTOR = /^#selector\b/;
937
+ var DELEGATE_CLASS = /^class\s+[A-Za-z_]\w*\s*(?:<[^>{]*>)?\s*:[^{]*\b(?:UIApplicationDelegate|UISceneDelegate|UIWindowSceneDelegate)\b[^{]*\{/;
937
938
  function swiftSourceAsIOS(source) {
938
939
  const { lineStarts, tokens } = swiftCodeScan(source);
939
940
  let offset = 0;
@@ -946,7 +947,15 @@ function swiftSourceAsIOS(source) {
946
947
  let out = "";
947
948
  let copied = 0;
948
949
  for (const at of tokens) {
949
- const rest = conditioned.slice(at, at + 200);
950
+ const rest = conditioned.slice(at, at + 400);
951
+ if (rest.startsWith("class")) {
952
+ const modifiers = conditioned.slice(conditioned.lastIndexOf("\n", at - 1) + 1, at);
953
+ if (DELEGATE_CLASS.test(rest) && !/\b(?:final|open)\b/.test(modifiers)) {
954
+ out += `${conditioned.slice(copied, at)}final `;
955
+ copied = at;
956
+ }
957
+ continue;
958
+ }
950
959
  const selector = SELECTOR.exec(rest);
951
960
  const match = selector ?? OBJC_ATTRIBUTE.exec(rest);
952
961
  if (!match) continue;
@@ -1039,6 +1048,9 @@ function swiftCodeScan(source) {
1039
1048
  if (top.parens === 0 && stack.length > 1) stack.pop();
1040
1049
  else top.parens--;
1041
1050
  i++;
1051
+ } else if (source.startsWith("class", i) && !/[\w$]/.test(source[i - 1] ?? "") && !/[\w$]/.test(source[i + 5] ?? "")) {
1052
+ tokens.push(i);
1053
+ i += 5;
1042
1054
  } else {
1043
1055
  if (char === "@") tokens.push(i);
1044
1056
  i++;
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.645 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.647 | (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 __create = Object.create;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peachsim",
3
- "version": "0.1.645",
3
+ "version": "0.1.647",
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",
@@ -229,9 +229,10 @@ export function swiftArtifactHash(
229
229
  moduleRoot: string,
230
230
  ): string {
231
231
  const hash = createHash('sha256')
232
- // v5: a target declaring resources gets SwiftPM's Bundle.module accessor
233
- // (v4: sources compile through swiftSourceAsIOS)
234
- hash.update(`swift-compile/v5\n${release}\n`)
232
+ // v6: app and scene delegate classes compile final
233
+ // (v5: a target declaring resources gets SwiftPM's Bundle.module accessor;
234
+ // v4: sources compile through swiftSourceAsIOS)
235
+ hash.update(`swift-compile/v6\n${release}\n`)
235
236
  if (input.oneModule) hash.update('one-module\n')
236
237
  hash.update(linkedModuleDigest(moduleRoot))
237
238
  for (const file of Object.keys(input.files).sort()) {
@@ -361,11 +362,19 @@ function syncSwiftTree(base: string, files: Map<string, string>): void {
361
362
  // `@objcMembers` `@ObjCMembers`, `@IBAction` `@ObjC` padded, and `#selector(`
362
363
  // `#Selector(`: the module's macros that expose a method to selector dispatch
363
364
  // (plans/peach/uikit-shell.md, gate B). all keep their width except an
364
- // explicit `@objc(name:)`, whose name becomes a string argument.
365
+ // explicit `@objc(name:)`, whose name becomes a string argument, and a
366
+ // delegate class that becomes final (below).
365
367
  const DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/
366
368
  const OS_IOS = /\bos\(\s*iOS\s*\)/g
367
369
  const OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/
368
370
  const SELECTOR = /^#selector\b/
371
+ // uikit makes app and scene delegates from their class through the objc
372
+ // runtime; here their protocols require init(), which a non-final class
373
+ // meets only with a required one. a class declaring one of them that is
374
+ // neither final nor open becomes final, and subclassing it fails to
375
+ // compile naming itself.
376
+ const DELEGATE_CLASS =
377
+ /^class\s+[A-Za-z_]\w*\s*(?:<[^>{]*>)?\s*:[^{]*\b(?:UIApplicationDelegate|UISceneDelegate|UIWindowSceneDelegate)\b[^{]*\{/
369
378
  export function swiftSourceAsIOS(source: string): string {
370
379
  const { lineStarts, tokens } = swiftCodeScan(source)
371
380
  let offset = 0
@@ -382,7 +391,15 @@ export function swiftSourceAsIOS(source: string): string {
382
391
  let out = ''
383
392
  let copied = 0
384
393
  for (const at of tokens) {
385
- const rest = conditioned.slice(at, at + 200)
394
+ const rest = conditioned.slice(at, at + 400)
395
+ if (rest.startsWith('class')) {
396
+ const modifiers = conditioned.slice(conditioned.lastIndexOf('\n', at - 1) + 1, at)
397
+ if (DELEGATE_CLASS.test(rest) && !/\b(?:final|open)\b/.test(modifiers)) {
398
+ out += `${conditioned.slice(copied, at)}final `
399
+ copied = at
400
+ }
401
+ continue
402
+ }
386
403
  const selector = SELECTOR.exec(rest)
387
404
  const match = selector ?? OBJC_ATTRIBUTE.exec(rest)
388
405
  if (!match) continue
@@ -398,8 +415,8 @@ export function swiftSourceAsIOS(source: string): string {
398
415
  return out + conditioned.slice(copied)
399
416
  }
400
417
 
401
- // the offsets of the lines that begin in code, and of every `@` and `#` that
402
- // stands in code (an interpolation's code included), from a scan of Swift's
418
+ // the offsets of the lines that begin in code, and of every `@`, `#` and
419
+ // `class` keyword that stands in code (an interpolation's code included), from a scan of Swift's
403
420
  // lexical contexts: nested block comments, line comments, string literals (single and
404
421
  // multiline, raw with any number of #, interpolations holding code and
405
422
  // strings of their own) and #/ /# regex literals. a bare /regex/ literal
@@ -487,6 +504,13 @@ function swiftCodeScan(source: string): { lineStarts: Set<number>; tokens: numbe
487
504
  if (top.parens === 0 && stack.length > 1) stack.pop()
488
505
  else top.parens--
489
506
  i++
507
+ } else if (
508
+ source.startsWith('class', i) &&
509
+ !/[\w$]/.test(source[i - 1] ?? '') &&
510
+ !/[\w$]/.test(source[i + 5] ?? '')
511
+ ) {
512
+ tokens.push(i)
513
+ i += 5
490
514
  } else {
491
515
  if (char === '@') tokens.push(i)
492
516
  i++