peachsim 0.1.577 → 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
package/LICENSE CHANGED
@@ -3,7 +3,7 @@ Proprietary Software License
3
3
  Copyright (c) Tamagui LLC. All rights reserved.
4
4
 
5
5
  This package (peachsim) is proprietary software of Tamagui LLC, licensed under
6
- the rnx Software License Agreement: https://rnxsim.com/legal/license
6
+ the rnx Software License Agreement: https://peachsim.com/legal/license
7
7
 
8
8
  In summary (the agreement governs): personal, non-commercial use is free;
9
9
  commercial use requires an active Pro subscription after a single 30-day
package/README.md CHANGED
@@ -215,12 +215,12 @@ bridge always addresses the **shell worker**, never an undifferentiated sim.
215
215
  | standalone CLI delivery | Cached stable-version checks, bounded interactive notices, and verified atomic executable replacement. | `cli/cli-update.ts`, `cli/commands/upgrade.ts`, `cli/commands/version.ts`, `src/cli-version.ts` |
216
216
  | `peachsim/vite` + `peachsim/metro` (runtime serving) | Published bundler plugins. Both serve the installed engine runtime at `/__soot/` from `~/.peach/runtimes/<version>` so an app's own dev server can host the sim shell; the Vite plugin can opt into a named Electron window. | `src/vite-plugin-one.ts`, `src/metro-plugin.ts`, `src/runtime-assets.ts` |
217
217
  | `sootsim()` vite resolver plugin (internal) | The large RN-resolution / native-stub vite plugin: aliases `react-native` to the engine shim, native packages to `@sootsim/compat` stubs, applies worklets/babel transforms, and instantiates `SootSimBridgeHost` in its dev server. Distinct from the published `peachsim/vite` export. | `src/vite-plugin.ts`, `src/worklets-babel.ts`, `packages/peach-compat/src/stub-manifest.ts` |
218
- | skills registry | Peach agent skills (`rnx-setup`, `rnx-debug`, `rnx-test`, `rnx-visual`, and the generated `contrast` index) installable with `peach skill`. | `skills/*.md`, `src/skills/registry.ts`, `src/skills/types.ts` |
218
+ | skills registry | Peach agent skills (`peach-setup`, `peach-debug`, `peach-test`, `peach-visual`, and the generated `contrast` index) installable with `peach skill`. | `skills/*.md`, `src/skills/registry.ts`, `src/skills/types.ts` |
219
219
 
220
220
  ## Getting started
221
221
 
222
222
  ```sh
223
- curl -fsSL https://rnxsim.com/install.sh | sh
223
+ curl -fsSL https://peachsim.com/install.sh | sh
224
224
  peach # open ConnectRN and choose a running app in the simulator
225
225
  peach open /settings # dispatch a React Native deep link into that app
226
226
  ```
@@ -253,7 +253,9 @@ agent work because inspect, interaction, and test commands reuse one ready bridg
253
253
  and runtime. Enable it at any time with `peach daemon install`; it is never required
254
254
  in CI. The packaged Desktop app is optional and available through first-run
255
255
  onboarding or `peach desktop install`. A downloaded app starts its own bundled
256
- daemon on first launch, then offers **Install the Peach command** over the running
256
+ daemon on first launch. An installed runtime can open while the daemon checks
257
+ for updates; a first install waits for the runtime download to finish. The app
258
+ then offers **Install the Peach command** over the running
257
259
  simulator. That action installs `~/.local/bin/peach`, updates shell startup, and
258
260
  hands the daemon to launchd or systemd without reloading the window. Windows
259
261
  keeps the desktop-owned daemon because it has no daemon service yet. Native Electron windows created by `peach open` belong to that CLI
@@ -286,7 +288,7 @@ launchd / systemd services and removes their logs, launcher, and generated
286
288
  `.app` wrapper. `~/.peach/` survives, because runtimes, device profiles and their
287
289
  app storage, and live dev-bridge records belong to simulators the user may
288
290
  still be running. `peach daemon uninstall --purge` deletes `~/.peach/` as well.
289
- Neither form removes the optional `/Applications/rnx.app` desktop bundle or the
291
+ Neither form removes the optional `/Applications/peach.app` desktop bundle or the
290
292
  macOS preference plist. To inspect existing disk usage first, run `peach cleanup`;
291
293
  add `--apply` only after reviewing the preview.
292
294
 
@@ -358,7 +360,7 @@ peach debug diff before after
358
360
  peach maestro start # begin a Maestro draft
359
361
  peach maestro keep # persist the last action
360
362
  peach maestro end --output .maestro/login.yaml --validate
361
- peach detox # run Detox/Jest suites against rnx
363
+ peach detox # run Detox/Jest suites against Peach
362
364
  ```
363
365
 
364
366
  See the full command reference via `peach --help` or at
@@ -485,8 +487,8 @@ peach debug snapshot before
485
487
  # reproduce the transition
486
488
  peach debug snapshot after
487
489
  peach debug diff before after
488
- peach screenshot --with-frame --output /tmp/rnx-framed.png
489
- peach record --duration 5 --output /tmp/rnx-anim.mp4
490
+ peach screenshot --with-frame --output /tmp/peach-framed.png
491
+ peach record --duration 5 --output /tmp/peach-anim.mp4
490
492
  ```
491
493
 
492
494
  `peach screenshot --with-frame` composes the real Peach shell device chrome
@@ -557,12 +559,12 @@ frame for quick art-direction passes.
557
559
  `<skill-name>/SKILL.md` layout used by Codex and Claude Code. The bundled
558
560
  skills cover setup, debugging/perf/accessibility, testing, visual review, and
559
561
  the generated `contrast` command index. The published CLI registry and generated
560
- website docs both come from `packages/rnx-skills/`:
562
+ website docs both come from `packages/peach-skills/`:
561
563
 
562
564
  - `packages/peachsim/skills/contrast/SKILL.md` is generated from that registry
563
565
  - `src/features/site/docs/rnx/cli/*` is generated output, not hand-edited
564
566
 
565
- When command docs or examples drift, update `packages/rnx-skills/` and run:
567
+ When command docs or examples drift, update `packages/peach-skills/` and run:
566
568
 
567
569
  ```sh
568
570
  bun run generate:sootsim-docs
@@ -0,0 +1,77 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import { enumerateBundleColors } from '../../sootsim-swift/src/bundleAssets'
4
+ import type { AppCatalog } from 'peach-engine/engine/app-catalog-wire'
5
+
6
+ // the xcode build setting actool turns into the built Info.plist's
7
+ // NSAccentColorName when the source plist does not name one itself
8
+ const ACCENT_BUILD_SETTING =
9
+ /ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "?([^";]+)"?;/
10
+ const PLIST_ACCENT = /<key>NSAccentColorName<\/key>\s*<string>([^<]+)<\/string>/
11
+
12
+ function listDir(dir: string): fs.Dirent[] {
13
+ try {
14
+ return fs.readdirSync(dir, { withFileTypes: true })
15
+ } catch {
16
+ return []
17
+ }
18
+ }
19
+
20
+ function readText(file: string): string | null {
21
+ try {
22
+ return fs.readFileSync(file, 'utf8')
23
+ } catch {
24
+ return null
25
+ }
26
+ }
27
+
28
+ function catalogFiles(dir: string, found: string[]) {
29
+ for (const entry of listDir(dir)) {
30
+ const full = path.join(dir, entry.name)
31
+ if (entry.isDirectory()) catalogFiles(full, found)
32
+ else if (entry.name === 'Contents.json') found.push(full)
33
+ }
34
+ }
35
+
36
+ // the app's asset-catalog colors and its declared accent, read off the ios
37
+ // project a prebuild or a bare app keeps on disk: the app target is the
38
+ // folder holding the AppDelegate, the catalogs are its .xcassets, and the
39
+ // accent is what its Info.plist or project build settings name. null when
40
+ // the app has no ios project on disk or declares neither.
41
+ export function discoverAppCatalog(appDir: string): AppCatalog | null {
42
+ const iosDir = path.join(appDir, 'ios')
43
+ const target = listDir(iosDir).find(
44
+ (entry) =>
45
+ entry.isDirectory() &&
46
+ entry.name !== 'Pods' &&
47
+ listDir(path.join(iosDir, entry.name)).some((file) =>
48
+ /^AppDelegate\.(swift|mm|m)$/.test(file.name),
49
+ ),
50
+ )
51
+ if (!target) return null
52
+ const targetDir = path.join(iosDir, target.name)
53
+ const files: string[] = []
54
+ for (const entry of listDir(targetDir)) {
55
+ if (entry.isDirectory() && entry.name.endsWith('.xcassets'))
56
+ catalogFiles(path.join(targetDir, entry.name), files)
57
+ }
58
+ const relative = files.map((file) =>
59
+ path.relative(targetDir, file).split(path.sep).join(path.posix.sep),
60
+ )
61
+ const colors = enumerateBundleColors(relative, (candidate) =>
62
+ candidate.endsWith('Contents.json')
63
+ ? readText(path.join(targetDir, candidate))
64
+ : null,
65
+ )
66
+ const pbxproj = listDir(iosDir).find((entry) => entry.name.endsWith('.xcodeproj'))
67
+ const accentName =
68
+ readText(path.join(targetDir, 'Info.plist'))?.match(PLIST_ACCENT)?.[1] ??
69
+ (pbxproj
70
+ ? readText(path.join(iosDir, pbxproj.name, 'project.pbxproj'))?.match(
71
+ ACCENT_BUILD_SETTING,
72
+ )?.[1]
73
+ : undefined) ??
74
+ null
75
+ if (accentName === null && Object.keys(colors).length === 0) return null
76
+ return { colors, accentName }
77
+ }
package/cli/app-fonts.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  type ConfigPluginFontSpec,
9
9
  } from 'peach-engine/engine/config-plugin-fonts'
10
10
  import { resolveListeningPid, resolveProcessCwd } from '../scripts/dev-server-scanner'
11
+ import { loopbackOriginOf } from '../src/backend-origin'
11
12
  import { parsePlistSource } from '../src/plist.ts'
12
13
  import { resolveAppProject } from './app-project'
13
14
 
@@ -19,29 +20,12 @@ export type DiscoveredAppFontSpec = ConfigPluginFontSpec
19
20
 
20
21
  type ExpoConfigGetter = (dir: string, opts: Record<string, unknown>) => { exp?: unknown }
21
22
 
22
- function localOriginOf(value: string): string | null {
23
- try {
24
- const url = new URL(value)
25
- const host = url.hostname.replace(/^\[|\]$/g, '').toLowerCase()
26
- if (
27
- host === 'localhost' ||
28
- host.endsWith('.localhost') ||
29
- host === '0.0.0.0' ||
30
- host === '::1' ||
31
- /^127(?:\.\d{1,3}){3}$/.test(host)
32
- ) {
33
- return url.origin
34
- }
35
- } catch {}
36
- return null
37
- }
38
-
39
23
  export function discoverNativeLinkedAppFonts(opts: {
40
24
  bundleUrl: string
41
25
  projectDir: string
42
26
  platform?: string
43
27
  }): DiscoveredAppFontSpec[] {
44
- const metroOrigin = localOriginOf(opts.bundleUrl)
28
+ const metroOrigin = loopbackOriginOf(opts.bundleUrl)
45
29
  if (!metroOrigin) return []
46
30
 
47
31
  const project = resolveAppProject(opts.projectDir)
@@ -262,7 +246,7 @@ export function discoverNativeLinkedAppFonts(opts: {
262
246
  // server origin carrying `extra.expoClient._internal.projectRoot` — the absolute
263
247
  // dir of the app being served. the local `peach open <port>` path runs from the
264
248
  // CLI's cwd, which almost never owns the bundle being opened (e.g.
265
- // `peach open 8081` run from ~/soot against a 3pc metro), so scanning cwd for
249
+ // `peach open 8081` run from ~/contrast against a 3pc metro), so scanning cwd for
266
250
  // font declarations finds nothing.
267
251
  //
268
252
  // a bare react-native packager serves no such manifest, so the same resolver
@@ -272,7 +256,7 @@ export async function resolveMetroProjectRoot(
272
256
  bundleUrl: string,
273
257
  opts?: { timeoutMs?: number },
274
258
  ): Promise<string | null> {
275
- const origin = localOriginOf(bundleUrl)
259
+ const origin = loopbackOriginOf(bundleUrl)
276
260
  if (!origin) return null
277
261
  const controller = new AbortController()
278
262
  const timer = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1500)
package/cli/app-splash.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  configPluginSplashFromExpoConfig,
7
7
  type ConfigPluginSplashSpec,
8
8
  } from 'peach-engine/engine/config-plugin-splash'
9
+ import { loopbackOriginOf } from '../src/backend-origin'
9
10
  import { resolveAppProject } from './app-project'
10
11
 
11
12
  const require = createRequire(import.meta.url)
@@ -16,23 +17,6 @@ export type DiscoveredAppSplashSpec = ConfigPluginSplashSpec
16
17
 
17
18
  type ExpoConfigGetter = (dir: string, opts: Record<string, unknown>) => { exp?: unknown }
18
19
 
19
- function localOriginOf(value: string): string | null {
20
- try {
21
- const url = new URL(value)
22
- const host = url.hostname.replace(/^\[|\]$/g, '').toLowerCase()
23
- if (
24
- host === 'localhost' ||
25
- host.endsWith('.localhost') ||
26
- host === '0.0.0.0' ||
27
- host === '::1' ||
28
- /^127(?:\.\d{1,3}){3}$/.test(host)
29
- ) {
30
- return url.origin
31
- }
32
- } catch {}
33
- return null
34
- }
35
-
36
20
  // discover the app's configured splash by evaluating its expo config on the
37
21
  // filesystem (mirrors discoverNativeLinkedAppFonts exactly). returns null when
38
22
  // no splash is configured, no app config is found, or the bundle isn't local.
@@ -41,7 +25,7 @@ export function discoverConfigPluginAppSplash(opts: {
41
25
  projectDir: string
42
26
  platform?: string
43
27
  }): DiscoveredAppSplashSpec | null {
44
- const metroOrigin = localOriginOf(opts.bundleUrl)
28
+ const metroOrigin = loopbackOriginOf(opts.bundleUrl)
45
29
  if (!metroOrigin) return null
46
30
 
47
31
  const project = resolveAppProject(opts.projectDir)