peachsim 0.1.1465 → 0.1.1469

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 (80) hide show
  1. package/cli/bridge-flow-runner.ts +25 -17
  2. package/cli/cloud-client.ts +12 -19
  3. package/cli/commands/inspect/settling.ts +4 -1
  4. package/dist-lib/agent-daemon-client.cjs +1 -1
  5. package/dist-lib/agent-events.cjs +1 -1
  6. package/dist-lib/attached-projects.cjs +1 -1
  7. package/dist-lib/auth/shared-session.cjs +1 -1
  8. package/dist-lib/backend-origin.cjs +1 -1
  9. package/dist-lib/beta.cjs +1 -1
  10. package/dist-lib/beta.mjs +1 -1
  11. package/dist-lib/bridge-constants.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.cjs +1 -1
  13. package/dist-lib/bridge-contract-input.mjs +1 -1
  14. package/dist-lib/bridge-contract.cjs +1 -1
  15. package/dist-lib/bridge-contract.mjs +1 -1
  16. package/dist-lib/bundle-channel.cjs +2 -2
  17. package/dist-lib/capture-contract.cjs +1 -1
  18. package/dist-lib/capture-contract.mjs +1 -1
  19. package/dist-lib/cloud-contract.cjs +1 -1
  20. package/dist-lib/cloud-contract.mjs +1 -1
  21. package/dist-lib/cloud-test-args.cjs +1 -1
  22. package/dist-lib/cloud-test-args.mjs +1 -1
  23. package/dist-lib/cloud.cjs +1 -1
  24. package/dist-lib/cloud.mjs +1 -1
  25. package/dist-lib/config.cjs +1 -1
  26. package/dist-lib/config.mjs +1 -1
  27. package/dist-lib/detox/index.cjs +1 -1
  28. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  29. package/dist-lib/expo-swift-bundle.cjs +2 -2
  30. package/dist-lib/expo-swift-metadata.cjs +1 -1
  31. package/dist-lib/expo-swift-metadata.mjs +1 -1
  32. package/dist-lib/home-paths.cjs +1 -1
  33. package/dist-lib/host/bridge-host.cjs +69 -12
  34. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  36. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  37. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  38. package/dist-lib/host/websocket-proxy.cjs +1 -1
  39. package/dist-lib/index.cjs +5 -2
  40. package/dist-lib/jump-to-source-babel.cjs +1 -1
  41. package/dist-lib/jump-to-source-native.cjs +1 -1
  42. package/dist-lib/kotlin-host.cjs +1 -1
  43. package/dist-lib/menu.cjs +1 -1
  44. package/dist-lib/menu.mjs +1 -1
  45. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  46. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  47. package/dist-lib/metro-production-bundle.cjs +1 -1
  48. package/dist-lib/metro-production-bundle.mjs +1 -1
  49. package/dist-lib/metro.cjs +1 -1
  50. package/dist-lib/native-app-identity-project.cjs +1 -1
  51. package/dist-lib/native-app-identity-project.mjs +1 -1
  52. package/dist-lib/native-app-identity.cjs +1 -1
  53. package/dist-lib/native-app-identity.mjs +1 -1
  54. package/dist-lib/native-firebase-metadata.cjs +1 -1
  55. package/dist-lib/native-firebase-metadata.mjs +1 -1
  56. package/dist-lib/plist.cjs +1 -1
  57. package/dist-lib/plist.mjs +1 -1
  58. package/dist-lib/profiles.cjs +1 -1
  59. package/dist-lib/public-brand.cjs +1 -1
  60. package/dist-lib/react-native-host-modules.cjs +1 -1
  61. package/dist-lib/react-native-host-modules.mjs +1 -1
  62. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  63. package/dist-lib/sdk.cjs +5 -2
  64. package/dist-lib/sdk.mjs +5 -2
  65. package/dist-lib/skills.cjs +90 -23
  66. package/dist-lib/swift-compile.cjs +2 -2
  67. package/dist-lib/swift-compile.mjs +2 -2
  68. package/dist-lib/swift-package.cjs +1 -1
  69. package/dist-lib/swift-package.mjs +1 -1
  70. package/dist-lib/swift-submit.cjs +1 -1
  71. package/dist-lib/swift-submit.mjs +1 -1
  72. package/dist-lib/swift-toolchain.cjs +1 -1
  73. package/dist-lib/swift.cjs +1 -1
  74. package/dist-lib/vite-swift.cjs +2 -2
  75. package/dist-lib/vite.cjs +1 -1
  76. package/dist-lib/worklet-executable.cjs +1 -1
  77. package/dist-lib/worklet-executable.mjs +1 -1
  78. package/package.json +1 -1
  79. package/src/bundle-asset-resource.ts +8 -0
  80. package/src/swift-compile.ts +4 -0
@@ -716,14 +716,14 @@ export interface MaestroStep {
716
716
  stopApp?: boolean | string | { appId?: string }
717
717
  clearState?: boolean | { appId?: string }
718
718
  clearKeychain?: boolean
719
- copyTextFrom?: string | { id?: string; text?: string }
719
+ copyTextFrom?: string | FlowTargetSelector
720
720
  evalScript?: string
721
721
  openLink?: string | { link: string; autoVerify?: boolean; browser?: boolean }
722
722
  // maestro `when:` conditional runs the step only if the predicate holds.
723
723
  // supports `visible` / `notVisible` with the same matcher shape used elsewhere.
724
724
  when?: {
725
- visible?: string | { id?: string; text?: string }
726
- notVisible?: string | { id?: string; text?: string }
725
+ visible?: string | FlowTargetSelector
726
+ notVisible?: string | FlowTargetSelector
727
727
  platform?: string
728
728
  true?: string | boolean
729
729
  }
@@ -1310,7 +1310,10 @@ export class SootSimBridgeFlowRunner {
1310
1310
  // engine's XCTest accessibility projection — one bridge evaluate, then the
1311
1311
  // same Orchestra.buildFilter semantics the render resolver implements, over
1312
1312
  // PeachAccessibilityNode instead of the visible semantic tree.
1313
- private async findElementAccessibilityTree(opts: FlowTargetSelector) {
1313
+ private async resolveAccessibilityElement(
1314
+ opts: FlowTargetSelector,
1315
+ command: string,
1316
+ ): Promise<PeachAccessibilityNode | null> {
1314
1317
  const tree = await this.evaluate(`(async () => {
1315
1318
  const test = window.__sootsimTest
1316
1319
  if (!test || typeof test.captureAccessibilityTree !== 'function') throw new Error('engine accessibility snapshot is unavailable')
@@ -1320,10 +1323,15 @@ export class SootSimBridgeFlowRunner {
1320
1323
  throw new Error('engine returned an invalid accessibility snapshot')
1321
1324
  if (tree.length === 0) return null
1322
1325
  if (tree.some((node) => node.platform !== 'ios'))
1323
- throw new Error(
1324
- 'containsChild, containsDescendants and focused require the iOS accessibility hierarchy',
1325
- )
1326
- const node = resolveAccessibilitySelector(tree, opts)
1326
+ throw new Error(`${command} requires the iOS accessibility hierarchy`)
1327
+ return resolveAccessibilitySelector(tree, opts)
1328
+ }
1329
+
1330
+ private async findElementAccessibilityTree(opts: FlowTargetSelector) {
1331
+ const node = await this.resolveAccessibilityElement(
1332
+ opts,
1333
+ 'containsChild, containsDescendants and focused',
1334
+ )
1327
1335
  if (!node) return null
1328
1336
  const frame = node.frame
1329
1337
  return {
@@ -1865,7 +1873,7 @@ export class SootSimBridgeFlowRunner {
1865
1873
  // assert a button that no finger could reach. visibleFrame already carries
1866
1874
  // the clipped, occlusion-subtracted rect, and tap-target refuses a covered
1867
1875
  // node on the same basis, so assertions and taps now agree.
1868
- private async isElementVisible(opts: { id?: string; text?: string }) {
1876
+ private async isElementVisible(opts: FlowTargetSelector) {
1869
1877
  const element = await this.findElement(opts)
1870
1878
  if (!element) return false
1871
1879
  const frame = element.visibleFrame
@@ -2894,17 +2902,17 @@ export class SootSimBridgeFlowRunner {
2894
2902
 
2895
2903
  // maestro copyTextFrom: find an element and capture its text for use in
2896
2904
  // later steps via ${maestro.copiedText} (upstream form) or the legacy
2897
- // ${maestroCopiedText}. the matcher shape matches tapOn.
2898
- async copyTextFrom(target: string | { id?: string; text?: string }) {
2899
- const opts = typeof target === 'string' ? { id: target } : target
2900
- const node = await this.findElement(opts)
2905
+ // ${maestroCopiedText}. the string form is a text selector, as in tapOn.
2906
+ // the copied text is Orchestra.resolveText over the XCTest attributes:
2907
+ // text (the value), then hintText (the placeholder), then the label.
2908
+ async copyTextFrom(target: string | FlowTargetSelector) {
2909
+ const opts = typeof target === 'string' ? { text: target } : target
2910
+ assertSupportedSelector(opts)
2911
+ const node = await this.resolveAccessibilityElement(opts, 'copyTextFrom')
2901
2912
  if (!node) {
2902
2913
  throw new Error(`copyTextFrom: element not found: ${JSON.stringify(opts)}`)
2903
2914
  }
2904
- const captured =
2905
- (node as { text?: string | null }).text ??
2906
- (node as { testID?: string | null }).testID ??
2907
- ''
2915
+ const captured = node.value || node.placeholder || node.label || ''
2908
2916
  this.js.setCopiedText(captured)
2909
2917
  this.js.putEnv('maestroCopiedText', captured)
2910
2918
  console.log(`[flow] copied text: ${JSON.stringify(captured)}`)
@@ -17,7 +17,7 @@ import {
17
17
  metroAssetScaleFilename,
18
18
  metroIosAssetDestRelatives,
19
19
  resolveMetroIosAssetDestFiles,
20
- type MetroArtifactAssetSize,
20
+ separateMetroArtifactAssets,
21
21
  type MetroAssetDescriptor,
22
22
  } from '../../contrast-bundler/src/metroAssetArtifact.ts'
23
23
  import {
@@ -647,18 +647,6 @@ function searchMetroAssetDest(
647
647
  return { dest: winner.dest, searched, truncated, unconfirmed: best === 0 }
648
648
  }
649
649
 
650
- function largestEmbeddedAssets(
651
- sizes: readonly MetroArtifactAssetSize[],
652
- count: number,
653
- ): string {
654
- if (sizes.length === 0) return ''
655
- const largest = sizes
656
- .slice(0, count)
657
- .map((entry) => `${entry.asset} ${entry.bytes} bytes`)
658
- .join(', ')
659
- return ` Largest embedded assets: ${largest}.`
660
- }
661
-
662
650
  async function inferCloudModuleIdentity(
663
651
  source: string,
664
652
  ): Promise<RNXMetroModuleIdentityMetadata> {
@@ -893,9 +881,15 @@ async function produceArtifact(
893
881
  })
894
882
  const bytes = Buffer.from(artifact.code, 'utf8')
895
883
  const assets = artifact.receipt.assets
896
- if (bytes.length > maxBytes) {
884
+ // previews keep their self-contained artifact. nano loads only the executable;
885
+ // its verified asset bytes live beside the upload in R2.
886
+ const executableBytes =
887
+ command === PREVIEW_COMMAND
888
+ ? bytes.length
889
+ : Buffer.byteLength((await separateMetroArtifactAssets(artifact.code)).code, 'utf8')
890
+ if (executableBytes > maxBytes) {
897
891
  throw new Error(
898
- `${REMOTE_COMMAND} artifact is ${bytes.length} bytes and exceeds the ${maxBytes}-byte limit. Embedded assets weigh ${assets.bytes} bytes on disk, and base64 embedding costs about a third on top of that, so the practical asset budget is roughly ${Math.round((maxBytes * 0.75) / 1e6)} MB.${largestEmbeddedAssets(assets.sizes, 10)}`,
892
+ `${command} executable is ${executableBytes} bytes and exceeds the ${maxBytes}-byte limit. The ${assets.bytes} asset bytes are stored outside guest code.`,
899
893
  )
900
894
  }
901
895
  const warnings: string[] = []
@@ -909,11 +903,10 @@ async function produceArtifact(
909
903
  `${command} embedded a placeholder image for ${prepared.substituted.length} asset(s) no scale of which is in ${prepared.search.searched.join(', ') || 'any asset dest directory'}: ${prepared.substituted.join(', ')}. Rebuild with \`react-native bundle --assets-dest\` to ship the real images.`,
910
904
  )
911
905
  }
912
- // an artifact this close to the ceiling is one asset away from being refused,
913
- // and the producer knows which assets it would be.
914
- if (bytes.length >= Math.floor(maxBytes * 0.8)) {
906
+ // warn on executable headroom; external assets do not consume this ceiling.
907
+ if (executableBytes >= Math.floor(maxBytes * 0.8)) {
915
908
  warnings.push(
916
- `${command} artifact is ${bytes.length} bytes, ${Math.round((bytes.length / maxBytes) * 100)}% of the ${maxBytes}-byte limit.${largestEmbeddedAssets(assets.sizes, 5)}`,
909
+ `${command} executable is ${executableBytes} bytes, ${Math.round((executableBytes / maxBytes) * 100)}% of the ${maxBytes}-byte limit.`,
917
910
  )
918
911
  }
919
912
  return {
@@ -357,6 +357,7 @@ export async function waitForSootsimIdle({
357
357
  return true
358
358
  }
359
359
  while (Date.now() < deadline) {
360
+ const pollStarted = Date.now()
360
361
  const snapshot = await readSnapshot()
361
362
  if (snapshot.runtimeUnsupported) return snapshot.runtimeUnsupported
362
363
  polls++
@@ -429,7 +430,9 @@ export async function waitForSootsimIdle({
429
430
  lastRequestTotal = snapshot.requestTotal
430
431
  lastAppCommits = snapshot.appCommits
431
432
  lastNodeCount = snapshot.nodeCount
432
- await sleep(pollMs)
433
+ // reply latency belongs inside the poll interval; the stillness window
434
+ // above remains measured from completed observations.
435
+ await sleep(Math.max(0, pollMs - (Date.now() - pollStarted)))
433
436
  }
434
437
  const last = await readSnapshot()
435
438
  if (last.runtimeUnsupported) return last.runtimeUnsupported
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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;
@@ -2329,7 +2329,7 @@ function compileSwiftProjectUnit(input, options) {
2329
2329
  };
2330
2330
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
2331
2331
  return serialize(root, async () => {
2332
- if (process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
2332
+ if (process.platform === "darwin" && process.env.TM_SESSION && !process.env.CONTRAST_REMOTE_BUILD && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
2333
2333
  const requestRoot = (0, import_node_fs2.mkdtempSync)(import_node_path2.default.join(root, ".builder-request-"));
2334
2334
  const output = import_node_path2.default.join(requestRoot, "output");
2335
2335
  const request = import_node_path2.default.join(requestRoot, "request.json");
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 40761776;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/config.ts
4
4
  import { isValidRuntimeVersion } from "@contrast/runtime-delivery/version";
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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;
@@ -3745,7 +3745,7 @@ function compileSwiftProjectUnit(input, options) {
3745
3745
  };
3746
3746
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
3747
3747
  return serialize(root, async () => {
3748
- if (process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3748
+ if (process.platform === "darwin" && process.env.TM_SESSION && !process.env.CONTRAST_REMOTE_BUILD && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3749
3749
  const requestRoot = (0, import_node_fs2.mkdtempSync)(import_node_path2.default.join(root, ".builder-request-"));
3750
3750
  const output = import_node_path2.default.join(requestRoot, "output");
3751
3751
  const request = import_node_path2.default.join(requestRoot, "request.json");
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/bundleGlobalFooter.ts
4
4
  function readBundleGlobalFooter(source, name) {
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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;
@@ -4556,6 +4556,15 @@ var init_metro_production_bundle = __esm({
4556
4556
  }
4557
4557
  });
4558
4558
 
4559
+ // src/bundle-asset-resource.ts
4560
+ var PEACH_BUNDLE_ASSET_PREFIX;
4561
+ var init_bundle_asset_resource = __esm({
4562
+ "src/bundle-asset-resource.ts"() {
4563
+ "use strict";
4564
+ PEACH_BUNDLE_ASSET_PREFIX = "peach-asset://";
4565
+ }
4566
+ });
4567
+
4559
4568
  // ../contrast-bundler/src/metroAssetArtifact.ts
4560
4569
  function isEmbeddedAssetDescriptor(descriptor) {
4561
4570
  return descriptor.fileUris?.length === descriptor.scales.length && descriptor.fileHashes?.length === descriptor.scales.length;
@@ -5097,6 +5106,56 @@ async function assertSelfContainedMetroArtifactAssets(bundle) {
5097
5106
  sizes: sortedAssetSizes(sizes)
5098
5107
  };
5099
5108
  }
5109
+ async function separateMetroArtifactAssets(bundle) {
5110
+ const assets2 = await assertSelfContainedMetroArtifactAssets(bundle);
5111
+ const sites = scanAssetDescriptorSites(bundle);
5112
+ const resources = /* @__PURE__ */ new Map();
5113
+ const entries = /* @__PURE__ */ new Map();
5114
+ for (const site of sites) {
5115
+ const descriptor = site.descriptor;
5116
+ const key2 = assetDescriptorKey(descriptor);
5117
+ if (entries.has(key2)) continue;
5118
+ const contentType = metroAssetContentType(descriptor.type);
5119
+ const prefix = `data:${contentType};base64,`;
5120
+ const fileUris = [];
5121
+ const fileHashes = [];
5122
+ for (let index = 0; index < descriptor.scales.length; index++) {
5123
+ const dataUri = descriptor.fileUris?.[index];
5124
+ const sha256 = descriptor.fileHashes?.[index];
5125
+ if (!dataUri || !sha256) throw new Error("verified Metro asset is incomplete");
5126
+ const scale = descriptor.scales[index];
5127
+ if (scale === void 0) throw new Error("verified Metro asset scale is missing");
5128
+ const filename = metroAssetScaleFilename(descriptor.name, descriptor.type, scale);
5129
+ const uri = `${PEACH_BUNDLE_ASSET_PREFIX}${sha256}/${encodeURIComponent(filename)}`;
5130
+ if (!resources.has(uri)) {
5131
+ const bytes = decodeBase64ToBytes(dataUri.slice(prefix.length));
5132
+ resources.set(uri, {
5133
+ uri,
5134
+ sha256,
5135
+ contentType,
5136
+ bytes,
5137
+ byteLength: bytes.byteLength
5138
+ });
5139
+ }
5140
+ fileUris.push(uri);
5141
+ fileHashes.push(sha256);
5142
+ }
5143
+ entries.set(key2, { fileUris, fileHashes, scales: descriptor.scales });
5144
+ }
5145
+ const pieces = [];
5146
+ let cursor = 0;
5147
+ for (const site of sites) {
5148
+ const entry = entries.get(assetDescriptorKey(site.descriptor));
5149
+ if (!entry) throw new Error("verified Metro asset descriptor is missing");
5150
+ pieces.push(
5151
+ bundle.slice(cursor, site.start),
5152
+ rewriteDescriptorObject(bundle, site, entry)
5153
+ );
5154
+ cursor = site.end;
5155
+ }
5156
+ pieces.push(bundle.slice(cursor));
5157
+ return { code: pieces.join(""), assets: assets2, resources: [...resources.values()] };
5158
+ }
5100
5159
  function metroAssetScaleFilename(name2, type, scale) {
5101
5160
  const suffix = scale === 1 ? "" : `@${scale}x`;
5102
5161
  return `${name2}${suffix}.${type}`;
@@ -5291,6 +5350,7 @@ var EXPRESSION_KEYWORDS, PLACEHOLDER_JPEG, METRO_ASSET_PLACEHOLDERS;
5291
5350
  var init_metroAssetArtifact = __esm({
5292
5351
  "../contrast-bundler/src/metroAssetArtifact.ts"() {
5293
5352
  "use strict";
5353
+ init_bundle_asset_resource();
5294
5354
  EXPRESSION_KEYWORDS = /* @__PURE__ */ new Set([
5295
5355
  "await",
5296
5356
  "case",
@@ -10069,11 +10129,6 @@ function searchMetroAssetDest(bundlePath, descriptors, assetsDirectory) {
10069
10129
  }
10070
10130
  return { dest: winner.dest, searched, truncated, unconfirmed: best === 0 };
10071
10131
  }
10072
- function largestEmbeddedAssets(sizes, count) {
10073
- if (sizes.length === 0) return "";
10074
- const largest = sizes.slice(0, count).map((entry) => `${entry.asset} ${entry.bytes} bytes`).join(", ");
10075
- return ` Largest embedded assets: ${largest}.`;
10076
- }
10077
10132
  async function inferCloudModuleIdentity(source) {
10078
10133
  let receipt;
10079
10134
  try {
@@ -10193,9 +10248,10 @@ async function produceArtifact(bundlePath, maxBytes, command, assetPolicy, asset
10193
10248
  });
10194
10249
  const bytes = Buffer.from(artifact.code, "utf8");
10195
10250
  const assets2 = artifact.receipt.assets;
10196
- if (bytes.length > maxBytes) {
10251
+ const executableBytes = command === PREVIEW_COMMAND ? bytes.length : Buffer.byteLength((await separateMetroArtifactAssets(artifact.code)).code, "utf8");
10252
+ if (executableBytes > maxBytes) {
10197
10253
  throw new Error(
10198
- `${REMOTE_COMMAND} artifact is ${bytes.length} bytes and exceeds the ${maxBytes}-byte limit. Embedded assets weigh ${assets2.bytes} bytes on disk, and base64 embedding costs about a third on top of that, so the practical asset budget is roughly ${Math.round(maxBytes * 0.75 / 1e6)} MB.${largestEmbeddedAssets(assets2.sizes, 10)}`
10254
+ `${command} executable is ${executableBytes} bytes and exceeds the ${maxBytes}-byte limit. The ${assets2.bytes} asset bytes are stored outside guest code.`
10199
10255
  );
10200
10256
  }
10201
10257
  const warnings = [];
@@ -10209,9 +10265,9 @@ async function produceArtifact(bundlePath, maxBytes, command, assetPolicy, asset
10209
10265
  `${command} embedded a placeholder image for ${prepared.substituted.length} asset(s) no scale of which is in ${prepared.search.searched.join(", ") || "any asset dest directory"}: ${prepared.substituted.join(", ")}. Rebuild with \`react-native bundle --assets-dest\` to ship the real images.`
10210
10266
  );
10211
10267
  }
10212
- if (bytes.length >= Math.floor(maxBytes * 0.8)) {
10268
+ if (executableBytes >= Math.floor(maxBytes * 0.8)) {
10213
10269
  warnings.push(
10214
- `${command} artifact is ${bytes.length} bytes, ${Math.round(bytes.length / maxBytes * 100)}% of the ${maxBytes}-byte limit.${largestEmbeddedAssets(assets2.sizes, 5)}`
10270
+ `${command} executable is ${executableBytes} bytes, ${Math.round(executableBytes / maxBytes * 100)}% of the ${maxBytes}-byte limit.`
10215
10271
  );
10216
10272
  }
10217
10273
  return {
@@ -10321,7 +10377,7 @@ async function createCloudBox(options) {
10321
10377
  warnings: artifact.warnings
10322
10378
  };
10323
10379
  }
10324
- var import_node_crypto15, import_node_fs33, import_node_path34, import_node_vm, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, REMOTE_COMMAND, MAX_ASSET_DEST_FILES, ACCOUNT_CHOICE_REFUSALS, PROJECT_ONLY_DIRECTORIES, MAX_PLACEMENT_COMBINATIONS;
10380
+ var import_node_crypto15, import_node_fs33, import_node_path34, import_node_vm, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, REMOTE_COMMAND, PREVIEW_COMMAND, MAX_ASSET_DEST_FILES, ACCOUNT_CHOICE_REFUSALS, PROJECT_ONLY_DIRECTORIES, MAX_PLACEMENT_COMBINATIONS;
10325
10381
  var init_cloud_client = __esm({
10326
10382
  "cli/cloud-client.ts"() {
10327
10383
  "use strict";
@@ -10346,6 +10402,7 @@ var init_cloud_client = __esm({
10346
10402
  DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
10347
10403
  MAX_RNX_CLOUD_BUNDLE_BYTES = RNX_CLOUD_MAX_ARTIFACT_BYTES;
10348
10404
  REMOTE_COMMAND = "peach remote";
10405
+ PREVIEW_COMMAND = "peach preview";
10349
10406
  MAX_ASSET_DEST_FILES = 25e3;
10350
10407
  ACCOUNT_CHOICE_REFUSALS = /* @__PURE__ */ new Set([
10351
10408
  "accountId is required",
@@ -14730,7 +14787,7 @@ function compileSwiftProjectUnit(input, options) {
14730
14787
  };
14731
14788
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
14732
14789
  return serialize(root, async () => {
14733
- if (process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && moduleRoot === import_node_path10.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
14790
+ if (process.platform === "darwin" && process.env.TM_SESSION && !process.env.CONTRAST_REMOTE_BUILD && process.env.CI !== "true" && moduleRoot === import_node_path10.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
14734
14791
  const requestRoot = (0, import_node_fs10.mkdtempSync)(import_node_path10.default.join(root, ".builder-request-"));
14735
14792
  const output = import_node_path10.default.join(requestRoot, "output");
14736
14793
  const request = import_node_path10.default.join(requestRoot, "request.json");
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_NATIVE_USER_AGENT_HEADER = "x-sootsim-native-user-agent";
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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;
@@ -7232,6 +7232,7 @@ async function waitForSootsimIdle({
7232
7232
  return true
7233
7233
  }
7234
7234
  while (Date.now() < deadline) {
7235
+ const pollStarted = Date.now()
7235
7236
  const snapshot = await readSnapshot()
7236
7237
  if (snapshot.runtimeUnsupported) return snapshot.runtimeUnsupported
7237
7238
  polls++
@@ -7304,7 +7305,9 @@ async function waitForSootsimIdle({
7304
7305
  lastRequestTotal = snapshot.requestTotal
7305
7306
  lastAppCommits = snapshot.appCommits
7306
7307
  lastNodeCount = snapshot.nodeCount
7307
- await sleep(pollMs)
7308
+ // reply latency belongs inside the poll interval; the stillness window
7309
+ // above remains measured from completed observations.
7310
+ await sleep(Math.max(0, pollMs - (Date.now() - pollStarted)))
7308
7311
  }
7309
7312
  const last = await readSnapshot()
7310
7313
  if (last.runtimeUnsupported) return last.runtimeUnsupported
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1469 | (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;