peachsim 0.1.1635 → 0.1.1640

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +5 -1
  2. package/cli/app-config.ts +14 -5
  3. package/cli/app-stubs.ts +62 -13
  4. package/cli/bridge-flow-runner.ts +2 -2
  5. package/cli/cloud-client.ts +60 -40
  6. package/cli/commands/doctor.ts +13 -5
  7. package/cli/commands/flow.ts +1 -1
  8. package/cli/commands/inspect/shared.ts +9 -4
  9. package/cli/commands/inspect.ts +65 -47
  10. package/cli/commands/preview.ts +1 -1
  11. package/cli/commands/record.ts +97 -47
  12. package/cli/commands/swift.ts +9 -3
  13. package/cli/commands/upload.ts +48 -42
  14. package/cli/drivers/playwright-sim-host.ts +65 -42
  15. package/cli/main.ts +1 -1
  16. package/cli/outbound-endpoints.ts +7 -5
  17. package/cli/pause-aware-timeout.ts +4 -0
  18. package/cli/ws-bridge.ts +19 -10
  19. package/detox/attempt-events.cjs +62 -5
  20. package/detox/attempt-events.d.cts +7 -0
  21. package/detox/expectations.ts +7 -3
  22. package/detox/index.ts +121 -47
  23. package/detox/motion-change.cjs +170 -21
  24. package/detox/motion-change.d.cts +32 -0
  25. package/detox/navigation-lifecycle.ts +35 -3
  26. package/dist-lib/agent-daemon-client.cjs +1 -1
  27. package/dist-lib/agent-events.cjs +1 -1
  28. package/dist-lib/attached-projects.cjs +1 -1
  29. package/dist-lib/auth/shared-session.cjs +1 -1
  30. package/dist-lib/backend-origin.cjs +8 -7
  31. package/dist-lib/beta.cjs +1 -1
  32. package/dist-lib/beta.mjs +1 -1
  33. package/dist-lib/bridge-constants.cjs +1 -1
  34. package/dist-lib/bridge-contract-input.cjs +1 -1
  35. package/dist-lib/bridge-contract-input.mjs +1 -1
  36. package/dist-lib/bridge-contract.cjs +1 -1
  37. package/dist-lib/bridge-contract.mjs +1 -1
  38. package/dist-lib/bundle-channel.cjs +4038 -1983
  39. package/dist-lib/capture-contract.cjs +1 -1
  40. package/dist-lib/capture-contract.mjs +1 -1
  41. package/dist-lib/cloud-contract.cjs +1 -1
  42. package/dist-lib/cloud-contract.mjs +1 -1
  43. package/dist-lib/cloud-test-args.cjs +1 -1
  44. package/dist-lib/cloud-test-args.mjs +1 -1
  45. package/dist-lib/cloud.cjs +1 -1
  46. package/dist-lib/cloud.mjs +1 -1
  47. package/dist-lib/config.cjs +1 -1
  48. package/dist-lib/config.mjs +1 -1
  49. package/dist-lib/detox/index.cjs +509 -86
  50. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  51. package/dist-lib/expo-swift-bundle.cjs +3551 -1574
  52. package/dist-lib/expo-swift-metadata.cjs +9 -7
  53. package/dist-lib/expo-swift-metadata.mjs +9 -7
  54. package/dist-lib/home-paths.cjs +1 -1
  55. package/dist-lib/host/bridge-host.cjs +43633 -2635
  56. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  57. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  58. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  59. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  60. package/dist-lib/host/websocket-proxy.cjs +1 -1
  61. package/dist-lib/index.cjs +2748 -128
  62. package/dist-lib/jump-to-source-babel.cjs +1 -1
  63. package/dist-lib/jump-to-source-native.cjs +1 -1
  64. package/dist-lib/kotlin-host.cjs +1 -1
  65. package/dist-lib/menu.cjs +1 -1
  66. package/dist-lib/menu.mjs +1 -1
  67. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  68. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  69. package/dist-lib/metro-production-bundle.cjs +1 -1
  70. package/dist-lib/metro-production-bundle.mjs +1 -1
  71. package/dist-lib/metro.cjs +2547 -83
  72. package/dist-lib/native-app-identity-project.cjs +237 -50
  73. package/dist-lib/native-app-identity-project.mjs +237 -50
  74. package/dist-lib/native-app-identity.cjs +29 -30
  75. package/dist-lib/native-app-identity.mjs +29 -30
  76. package/dist-lib/native-firebase-metadata.cjs +1 -1
  77. package/dist-lib/native-firebase-metadata.mjs +1 -1
  78. package/dist-lib/plist.cjs +1 -1
  79. package/dist-lib/plist.mjs +1 -1
  80. package/dist-lib/profiles.cjs +1 -1
  81. package/dist-lib/public-brand.cjs +1 -1
  82. package/dist-lib/react-native-host-modules.cjs +2 -2
  83. package/dist-lib/react-native-host-modules.mjs +2 -2
  84. package/dist-lib/scripts/dev-server-scanner.cjs +8 -6
  85. package/dist-lib/sdk.cjs +1 -1
  86. package/dist-lib/sdk.mjs +1 -1
  87. package/dist-lib/skills.cjs +65403 -22739
  88. package/dist-lib/swift-compile.cjs +93 -32
  89. package/dist-lib/swift-compile.mjs +93 -32
  90. package/dist-lib/swift-package.cjs +1 -1
  91. package/dist-lib/swift-package.mjs +1 -1
  92. package/dist-lib/swift-submit.cjs +7 -5
  93. package/dist-lib/swift-submit.mjs +7 -5
  94. package/dist-lib/swift-toolchain.cjs +316 -41
  95. package/dist-lib/swift.cjs +1 -1
  96. package/dist-lib/vite-swift.cjs +7335 -5432
  97. package/dist-lib/vite.cjs +2857 -12
  98. package/dist-lib/worklet-executable.cjs +14 -2
  99. package/dist-lib/worklet-executable.mjs +14 -2
  100. package/package.json +1 -1
  101. package/src/backend-origin.ts +13 -6
  102. package/src/expo-swift-host.ts +5 -2
  103. package/src/expoKotlinContract.ts +4 -7
  104. package/src/expoSwiftContract.ts +4 -6
  105. package/src/host/staged-host-files.ts +9 -0
  106. package/src/native-app-identity-project.ts +1 -4
  107. package/src/native-app-identity.ts +1 -4
  108. package/src/nativeAppIconContract.ts +1 -4
  109. package/src/output-lock-stdio.ts +36 -0
  110. package/src/react-native-bridge-modules.ts +21 -6
  111. package/src/react-native-host-modules.ts +4 -1
  112. package/src/settings-bundle.ts +1 -4
  113. package/src/swift-compile.ts +91 -33
  114. package/src/swift-distribution.lock.json +22 -12
  115. package/src/swift-distribution.ts +103 -4
  116. package/src/swift-host.ts +89 -26
  117. package/src/swift-icu.ts +16 -10
  118. package/src/swift-objc-compile.ts +355 -0
  119. package/src/swift-objc-sdk.ts +689 -18
  120. package/src/swift-objc-standin.ts +126 -14
  121. package/src/swift-package-manifest.ts +39 -1
  122. package/src/swift-packages.ts +35 -21
  123. package/src/swift-standin-emit.ts +40 -7
  124. package/src/swift-standins.ts +404 -138
  125. package/src/swift-submit.ts +3 -5
  126. package/src/swift-toolchain.ts +378 -46
  127. package/src/worker-system-chunks.ts +11 -12
  128. package/src/worklet-executable.ts +19 -1
  129. package/src/xcode-project.ts +270 -30
@@ -55,6 +55,38 @@ export function evaluateMotionTransitions(
55
55
  passed: boolean
56
56
  }
57
57
 
58
+ export type MotionCycleOnset = { id: string; atMs: number }
59
+
60
+ export type MotionCyclePeriod = {
61
+ id: string
62
+ passed: boolean
63
+ referenceMs: number
64
+ sootsimMs: number
65
+ }
66
+
67
+ export function motionCycleOnsets(
68
+ event: Record<string, unknown>,
69
+ eventPath: string,
70
+ ): MotionCycleOnset[]
71
+
72
+ export function evaluateMotionPublication(
73
+ stages: readonly {
74
+ label: string
75
+ passedThreshold: boolean
76
+ oracleFromFirstPercent: number | null
77
+ oracleFromLastPercent: number | null
78
+ }[],
79
+ transitions: MotionTransitionSample[],
80
+ oracleTarget: string,
81
+ cycleOnsets: { reference: MotionCycleOnset[]; sootsim: MotionCycleOnset[] },
82
+ ): {
83
+ passed: boolean
84
+ cyclePeriods: MotionCyclePeriod[]
85
+ intermediateCount: number
86
+ intermediatePassed: number
87
+ movingPassed: number
88
+ }
89
+
58
90
  export type DiscreteFrameAsset = {
59
91
  fixturePath: string
60
92
  fixtureSha256: string
@@ -1,3 +1,4 @@
1
+ import { readPeachConfigFromSearchParams } from '../src/config'
1
2
  import { writeAttemptEvent } from './attempt-events.cjs'
2
3
  import type { Page, Request, Response } from 'playwright-core'
3
4
 
@@ -77,6 +78,18 @@ type PageDiagnostic =
77
78
  url: string
78
79
  }
79
80
 
81
+ // developer config belongs in the browser, never in persisted diagnostics.
82
+ const developerToken = readPeachConfigFromSearchParams(
83
+ new URL(process.env.PEACH_URL || 'http://localhost').searchParams,
84
+ )?.mapKit?.token
85
+
86
+ function redactDiagnosticText(text: string): string {
87
+ const withoutConfig = text.replace(/([?&]peachConfig=)[^&\s"'<>]+/g, '$1[redacted]')
88
+ return developerToken
89
+ ? withoutConfig.replaceAll(developerToken, '[redacted]')
90
+ : withoutConfig
91
+ }
92
+
80
93
  const DIAGNOSTIC_LIMIT = 40
81
94
  const pageDiagnostics = new WeakMap<Page, PageDiagnostic[]>()
82
95
  const activeNavigations = new WeakMap<Page, ActiveNavigation>()
@@ -95,6 +108,21 @@ function persistDiagnostic(diagnostic: PageDiagnostic) {
95
108
  // prints this buffer, so a guest error writes the console tail that led to it
96
109
  // into events.jsonl. passing runs emit no guest error and write nothing.
97
110
  function recordPageDiagnostic(page: Page, diagnostic: PageDiagnostic, persist = false) {
111
+ if ('url' in diagnostic) diagnostic.url = redactDiagnosticText(diagnostic.url)
112
+ if ('navigationUrl' in diagnostic)
113
+ diagnostic.navigationUrl = redactDiagnosticText(diagnostic.navigationUrl)
114
+ if ('message' in diagnostic)
115
+ diagnostic.message = redactDiagnosticText(diagnostic.message)
116
+ if ('errorText' in diagnostic && diagnostic.errorText)
117
+ diagnostic.errorText = redactDiagnosticText(diagnostic.errorText)
118
+ if ('pageState' in diagnostic && diagnostic.pageState) {
119
+ if ('url' in diagnostic.pageState)
120
+ diagnostic.pageState.url = redactDiagnosticText(diagnostic.pageState.url)
121
+ if ('evaluateError' in diagnostic.pageState)
122
+ diagnostic.pageState.evaluateError = redactDiagnosticText(
123
+ diagnostic.pageState.evaluateError,
124
+ )
125
+ }
98
126
  const entries = pageDiagnostics.get(page)
99
127
  if (!entries) return
100
128
  entries.push(diagnostic)
@@ -229,7 +257,7 @@ async function readSootsimPageState(
229
257
  page: Page,
230
258
  ): Promise<SootsimPageState | { evaluateError: string }> {
231
259
  try {
232
- return await page.evaluate(() => {
260
+ const state = await page.evaluate(() => {
233
261
  const bootMarks = Reflect.get(window, '__sootsimBootMarks')
234
262
  return {
235
263
  bodyText: document.body?.innerText?.slice(0, 500) ?? '',
@@ -248,6 +276,8 @@ async function readSootsimPageState(
248
276
  url: window.location.href,
249
277
  }
250
278
  })
279
+ state.url = redactDiagnosticText(state.url)
280
+ return state
251
281
  } catch (error) {
252
282
  return {
253
283
  evaluateError: error instanceof Error ? error.message : String(error),
@@ -277,7 +307,9 @@ export async function describeSootsimBridgeFailure(
277
307
  `cause: ${cause instanceof Error ? cause.message : String(cause)}`,
278
308
  `page: ${JSON.stringify(state)}`,
279
309
  `recent page diagnostics:\n${JSON.stringify(getSootsimNavigationDiagnostics(page))}`,
280
- ].join('\n'),
310
+ ]
311
+ .map(redactDiagnosticText)
312
+ .join('\n'),
281
313
  )
282
314
  }
283
315
 
@@ -289,7 +321,7 @@ export async function navigateSootsimPage(
289
321
  attachPageDiagnostics(page)
290
322
  const navigation = {
291
323
  ...identity,
292
- navigationUrl: url,
324
+ navigationUrl: redactDiagnosticText(url),
293
325
  navigationId: ++nextNavigationIdentity,
294
326
  }
295
327
  activeNavigations.set(page, navigation)
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -24,6 +24,7 @@ var backend_origin_exports = {};
24
24
  __export(backend_origin_exports, {
25
25
  DEFAULT_CONTRAST_BACKEND_ORIGIN: () => DEFAULT_CONTRAST_BACKEND_ORIGIN,
26
26
  LOOPBACK_PROBE_HOSTNAMES: () => LOOPBACK_PROBE_HOSTNAMES,
27
+ PEACHSIM_NATIVE_HOST: () => PEACHSIM_NATIVE_HOST,
27
28
  buildBrowserAssetProxyUrl: () => buildBrowserAssetProxyUrl,
28
29
  buildLoopbackProbeBaseUrl: () => buildLoopbackProbeBaseUrl,
29
30
  isBrowserAssetProxyUrl: () => isBrowserAssetProxyUrl,
@@ -88,9 +89,10 @@ function isBrowserAssetProxyUrl(value) {
88
89
  return false;
89
90
  }
90
91
  }
92
+ var PEACHSIM_NATIVE_HOST = "native.peachsim.com";
91
93
  function isContrastBackendHost(hostname) {
92
94
  const normalized = normalizeHostname(hostname);
93
- return isLoopbackHost(normalized) || normalized === "contrast.dev" || normalized.endsWith(".contrast.dev");
95
+ return isLoopbackHost(normalized) || normalized === "contrast.dev" || normalized.endsWith(".contrast.dev") || normalized === PEACHSIM_NATIVE_HOST;
94
96
  }
95
97
  function isContrastBackendOrigin(origin) {
96
98
  try {
@@ -99,14 +101,12 @@ function isContrastBackendOrigin(origin) {
99
101
  return false;
100
102
  }
101
103
  }
102
- function resolveContrastBackendOrigin(currentOrigin) {
103
- const origin = currentOrigin?.trim();
104
+ function resolveContrastBackendOrigin(currentOrigin, search) {
105
+ const origin = new URLSearchParams(search ?? "").get("backend")?.trim() || currentOrigin?.trim();
104
106
  if (!origin) return DEFAULT_CONTRAST_BACKEND_ORIGIN;
105
107
  try {
106
108
  const parsed = new URL(origin);
107
- if (isLoopbackHost(parsed.hostname) || isContrastBackendHost(parsed.hostname)) {
108
- return parsed.origin;
109
- }
109
+ if (isContrastBackendHost(parsed.hostname)) return parsed.origin;
110
110
  } catch {
111
111
  }
112
112
  return DEFAULT_CONTRAST_BACKEND_ORIGIN;
@@ -115,6 +115,7 @@ function resolveContrastBackendOrigin(currentOrigin) {
115
115
  0 && (module.exports = {
116
116
  DEFAULT_CONTRAST_BACKEND_ORIGIN,
117
117
  LOOPBACK_PROBE_HOSTNAMES,
118
+ PEACHSIM_NATIVE_HOST,
118
119
  buildBrowserAssetProxyUrl,
119
120
  buildLoopbackProbeBaseUrl,
120
121
  isBrowserAssetProxyUrl,
package/dist-lib/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1635 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1640 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var REFUSED_PERFORM_STEP_TYPES = [