peachsim 0.1.1465 → 0.1.1477

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 (86) 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/cli/drivers/playwright-sim-host.ts +7 -2
  5. package/cli/drivers/playwright.ts +6 -6
  6. package/dist-lib/agent-daemon-client.cjs +1 -1
  7. package/dist-lib/agent-events.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/bundle-channel.cjs +13 -2
  19. package/dist-lib/capture-contract.cjs +1 -1
  20. package/dist-lib/capture-contract.mjs +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/config.mjs +1 -1
  29. package/dist-lib/detox/index.cjs +46 -40
  30. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  31. package/dist-lib/expo-swift-bundle.cjs +7 -2
  32. package/dist-lib/expo-swift-metadata.cjs +1 -1
  33. package/dist-lib/expo-swift-metadata.mjs +1 -1
  34. package/dist-lib/home-paths.cjs +1 -1
  35. package/dist-lib/host/bridge-host.cjs +170 -16
  36. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  37. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  38. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  39. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  40. package/dist-lib/host/websocket-proxy.cjs +1 -1
  41. package/dist-lib/index.cjs +5 -2
  42. package/dist-lib/jump-to-source-babel.cjs +1 -1
  43. package/dist-lib/jump-to-source-native.cjs +1 -1
  44. package/dist-lib/kotlin-host.cjs +1 -1
  45. package/dist-lib/menu.cjs +1 -1
  46. package/dist-lib/menu.mjs +1 -1
  47. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  48. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  49. package/dist-lib/metro-production-bundle.cjs +1 -1
  50. package/dist-lib/metro-production-bundle.mjs +1 -1
  51. package/dist-lib/metro.cjs +1 -1
  52. package/dist-lib/native-app-identity-project.cjs +1 -1
  53. package/dist-lib/native-app-identity-project.mjs +1 -1
  54. package/dist-lib/native-app-identity.cjs +1 -1
  55. package/dist-lib/native-app-identity.mjs +1 -1
  56. package/dist-lib/native-firebase-metadata.cjs +1 -1
  57. package/dist-lib/native-firebase-metadata.mjs +1 -1
  58. package/dist-lib/plist.cjs +1 -1
  59. package/dist-lib/plist.mjs +1 -1
  60. package/dist-lib/profiles.cjs +1 -1
  61. package/dist-lib/public-brand.cjs +1 -1
  62. package/dist-lib/react-native-host-modules.cjs +1 -1
  63. package/dist-lib/react-native-host-modules.mjs +1 -1
  64. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  65. package/dist-lib/sdk.cjs +5 -2
  66. package/dist-lib/sdk.mjs +5 -2
  67. package/dist-lib/skills.cjs +198 -83
  68. package/dist-lib/swift-compile.cjs +7 -2
  69. package/dist-lib/swift-compile.mjs +7 -2
  70. package/dist-lib/swift-package.cjs +1 -1
  71. package/dist-lib/swift-package.mjs +1 -1
  72. package/dist-lib/swift-submit.cjs +1 -1
  73. package/dist-lib/swift-submit.mjs +1 -1
  74. package/dist-lib/swift-toolchain.cjs +1 -1
  75. package/dist-lib/swift.cjs +1 -1
  76. package/dist-lib/vite-swift.cjs +7 -2
  77. package/dist-lib/vite.cjs +1 -1
  78. package/dist-lib/worklet-executable.cjs +1 -1
  79. package/dist-lib/worklet-executable.mjs +1 -1
  80. package/package.json +1 -1
  81. package/src/admitted-mac-build.ts +12 -0
  82. package/src/bridge-constants.ts +5 -3
  83. package/src/bundle-asset-resource.ts +8 -0
  84. package/src/host/bridge-host.ts +34 -6
  85. package/src/swift-compile.ts +5 -0
  86. package/src/worker-system-chunks.ts +10 -9
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1477 | (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.1477 | (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.1477 | (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;
@@ -1782,6 +1782,11 @@ var import_node_os = __toESM(require("node:os"), 1);
1782
1782
  var import_node_path2 = __toESM(require("node:path"), 1);
1783
1783
  var import_node_util2 = require("node:util");
1784
1784
 
1785
+ // src/admitted-mac-build.ts
1786
+ function admittedMacBuilderSlot(env = process.env) {
1787
+ return env.CONTRAST_REMOTE_BUILD === "mac" && env.REMOTE_MAC_SLOT_HELD === "1" && env.CONTRAST_HEAVY_ADMITTED === "1";
1788
+ }
1789
+
1785
1790
  // src/is-record.ts
1786
1791
  function isRecord(value) {
1787
1792
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -4038,7 +4043,7 @@ function compileSwiftProjectUnit(input, options) {
4038
4043
  };
4039
4044
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
4040
4045
  return serialize(root, async () => {
4041
- 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)) {
4046
+ if (process.platform === "darwin" && process.env.TM_SESSION && !admittedMacBuilderSlot() && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
4042
4047
  const requestRoot = (0, import_node_fs2.mkdtempSync)(import_node_path2.default.join(root, ".builder-request-"));
4043
4048
  const output = import_node_path2.default.join(requestRoot, "output");
4044
4049
  const request = import_node_path2.default.join(requestRoot, "request.json");
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1465 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1477 | (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.1477 | (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.1477 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/worklet-executable.ts
4
4
  import { parse } from "acorn";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peachsim",
3
- "version": "0.1.1465",
3
+ "version": "0.1.1477",
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",
@@ -0,0 +1,12 @@
1
+ // true only inside a mac builder slot that already passed resource admission.
2
+ // any other CONTRAST_REMOTE_BUILD value, including "linux" and "0", is an
3
+ // inherited marker and is not a reason to compile on this host.
4
+ export function admittedMacBuilderSlot(
5
+ env: { readonly [key: string]: string | undefined } = process.env,
6
+ ): boolean {
7
+ return (
8
+ env.CONTRAST_REMOTE_BUILD === 'mac' &&
9
+ env.REMOTE_MAC_SLOT_HELD === '1' &&
10
+ env.CONTRAST_HEAVY_ADMITTED === '1'
11
+ )
12
+ }
@@ -186,7 +186,9 @@ export const SOOTSIM_BRIDGE_SIM_CLOSE_REASON = 'sootsim close'
186
186
  // and an idle one still renders at full rate (the host disables background
187
187
  // throttling so captures see real motion). a cli attached, which covers a long
188
188
  // in-flight command such as a recording, a command within this window, or a
189
- // person's input on the page within it proves one is in use. past it the
190
- // bridge reaper closes the sim socket with the code above, the page asks its
191
- // host to close, and the host exits with its chrome tree.
189
+ // person's input on the page within it proves one is in use. past it the sim
190
+ // stays open while its owning session lives, but the bridge reaper may reclaim
191
+ // it for a chromium launch queued behind the machine's cap: it closes the sim
192
+ // socket with the code above, the page asks its host to close, and the host
193
+ // exits with its chrome tree.
192
194
  export const AUTOMATION_SIM_IDLE_REAP_TTL_MS = 5 * 60_000
@@ -0,0 +1,8 @@
1
+ export const PEACH_BUNDLE_ASSET_PREFIX = 'peach-asset://'
2
+
3
+ export interface PeachBundleAssetReference {
4
+ uri: string
5
+ sha256: string
6
+ contentType: string
7
+ byteLength: number
8
+ }
@@ -1,8 +1,10 @@
1
- import { spawn } from 'child_process'
1
+ import childProcess, { spawn } from 'child_process'
2
2
  import fs from 'fs'
3
3
  import { createServer, type IncomingMessage, type ServerResponse } from 'http'
4
+ import os from 'os'
4
5
  import path from 'path'
5
6
  import { WebSocket, WebSocketServer } from 'ws'
7
+ import { readChromiumQueue } from '../../../../scripts/lib/chromium-admission.ts'
6
8
  import {
7
9
  scanDevServers,
8
10
  type DiscoveredServer,
@@ -2038,6 +2040,7 @@ export class SootSimBridgeHost {
2038
2040
 
2039
2041
  private reapIdleSims(now = Date.now()) {
2040
2042
  const attachedSimIds = new Set(this.cliSimBySocket.values())
2043
+ let reclaimable: { ws: WebSocket; idleMs: number } | null = null
2041
2044
  for (const sim of this.sims.values()) {
2042
2045
  if (attachedSimIds.has(sim.id)) continue
2043
2046
  const automation = this.isAutomationSim(sim)
@@ -2053,13 +2056,38 @@ export class SootSimBridgeHost {
2053
2056
  // never-CLI-driven sims have lastActiveAt 0 — fall back to connectedAt
2054
2057
  // so a freshly opened, not-yet-primary tab isn't reaped on the spot.
2055
2058
  const idleMs = now - Math.max(sim.lastActiveAt, sim.connectedAt)
2056
- const ttl = automation
2057
- ? AUTOMATION_SIM_IDLE_REAP_TTL_MS
2058
- : SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS
2059
+ if (automation) {
2060
+ if (
2061
+ idleMs >= AUTOMATION_SIM_IDLE_REAP_TTL_MS &&
2062
+ idleMs > (reclaimable?.idleMs ?? 0)
2063
+ )
2064
+ reclaimable = { ws: sim.ws, idleMs }
2065
+ continue
2066
+ }
2059
2067
  // terminal close → client closes the window, does not reconnect; the
2060
2068
  // 'close' handler runs rememberDisconnectedSim → this.sims.delete.
2061
- if (idleMs >= ttl) this.closeSimSocketFromHost(sim.ws)
2062
- }
2069
+ if (idleMs >= SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS)
2070
+ this.closeSimSocketFromHost(sim.ws)
2071
+ }
2072
+ // an automation sim lives as long as the session that opened it, as a
2073
+ // simulator stays booted between commands; its host closes chrome when that
2074
+ // session exits. an idle one gives up its chromium slot only while another
2075
+ // launch on this machine waits for one, the longest idle first.
2076
+ if (reclaimable && this.chromiumLaunchWaiting())
2077
+ this.closeSimSocketFromHost(reclaimable.ws)
2078
+ }
2079
+
2080
+ private chromiumQueueVerified = new Map<string, boolean>()
2081
+
2082
+ private chromiumLaunchWaiting(): boolean {
2083
+ const queue = readChromiumQueue(
2084
+ { fs, os, path, childProcess },
2085
+ this.chromiumQueueVerified,
2086
+ )
2087
+ const live = new Set(queue.tickets)
2088
+ for (const entry of this.chromiumQueueVerified.keys())
2089
+ if (!live.has(entry)) this.chromiumQueueVerified.delete(entry)
2090
+ return queue.tickets.length > queue.limit
2063
2091
  }
2064
2092
 
2065
2093
  // ping every connected ws; if the previous round's ping went unanswered,
@@ -15,6 +15,7 @@ import {
15
15
  import os from 'node:os'
16
16
  import path from 'node:path'
17
17
  import { promisify } from 'node:util'
18
+ import { admittedMacBuilderSlot } from './admitted-mac-build'
18
19
  import {
19
20
  parseSwiftDistributionManifest,
20
21
  SWIFT_DISTRIBUTION_MANIFEST,
@@ -2690,9 +2691,13 @@ export function compileSwiftProjectUnit(
2690
2691
  }
2691
2692
  const hash = swiftArtifactHash(input, options.release, moduleRoot)
2692
2693
  return serialize(root, async () => {
2694
+ // an admitted mac slot already holds the build lock and the pinned
2695
+ // toolchain, so it compiles here. a bare CONTRAST_REMOTE_BUILD value is
2696
+ // only an inherited marker and still dispatches through admission.
2693
2697
  if (
2694
2698
  process.platform === 'darwin' &&
2695
2699
  process.env.TM_SESSION &&
2700
+ !admittedMacBuilderSlot() &&
2696
2701
  process.env.CI !== 'true' &&
2697
2702
  moduleRoot === path.resolve(import.meta.dirname, '../../sootsim-swift') &&
2698
2703
  !swiftDistributionAt(moduleRoot)
@@ -6,22 +6,23 @@ import { isRecord } from './is-record'
6
6
 
7
7
  const require = createRequire(import.meta.url)
8
8
  const systemRuntime = fs.readFileSync(require.resolve('systemjs/dist/s.min.js'), 'utf8')
9
- const minifierModule = require.resolve('terser')
9
+ const minifierModule = require.resolve('rolldown/utils')
10
10
  type MinifiedWorkerChunk = { code: string; map: string }
11
11
  const minifierWorker = `
12
12
  const { parentPort, workerData } = require('node:worker_threads');
13
- const { minify } = require(workerData.module);
13
+ const minifier = import(workerData.module);
14
14
  parentPort.on('message', async ({ code, map, keepNames, measurement }) => {
15
15
  try {
16
- const result = await minify(code, {
16
+ const { minifySync } = await minifier;
17
+ const result = minifySync('peach-worker-chunk.js', code, {
17
18
  module: true,
18
- compress: measurement ? false : { passes: 2 },
19
- mangle: !measurement,
20
- keep_fnames: keepNames,
21
- keep_classnames: keepNames,
22
- sourceMap: { content: map },
19
+ compress: measurement ? false : { keepNames: { function: keepNames, class: keepNames } },
20
+ mangle: measurement ? false : { keepNames },
21
+ sourcemap: true,
22
+ inputMap: JSON.parse(map),
23
23
  });
24
- parentPort.postMessage({ code: result.code, map: result.map });
24
+ if (result.errors.length) throw new Error(result.errors.map(error => error.message).join('; '));
25
+ parentPort.postMessage({ code: result.code, map: result.map && JSON.stringify(result.map) });
25
26
  } catch (error) {
26
27
  parentPort.postMessage({ error: error instanceof Error ? error.message : String(error) });
27
28
  }