peachsim 0.1.1469 → 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 (82) hide show
  1. package/cli/drivers/playwright-sim-host.ts +7 -2
  2. package/cli/drivers/playwright.ts +6 -6
  3. package/dist-lib/agent-daemon-client.cjs +1 -1
  4. package/dist-lib/agent-events.cjs +1 -1
  5. package/dist-lib/attached-projects.cjs +1 -1
  6. package/dist-lib/auth/shared-session.cjs +1 -1
  7. package/dist-lib/backend-origin.cjs +1 -1
  8. package/dist-lib/beta.cjs +1 -1
  9. package/dist-lib/beta.mjs +1 -1
  10. package/dist-lib/bridge-constants.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.mjs +1 -1
  13. package/dist-lib/bridge-contract.cjs +1 -1
  14. package/dist-lib/bridge-contract.mjs +1 -1
  15. package/dist-lib/bundle-channel.cjs +13 -2
  16. package/dist-lib/capture-contract.cjs +1 -1
  17. package/dist-lib/capture-contract.mjs +1 -1
  18. package/dist-lib/cloud-contract.cjs +1 -1
  19. package/dist-lib/cloud-contract.mjs +1 -1
  20. package/dist-lib/cloud-test-args.cjs +1 -1
  21. package/dist-lib/cloud-test-args.mjs +1 -1
  22. package/dist-lib/cloud.cjs +1 -1
  23. package/dist-lib/cloud.mjs +1 -1
  24. package/dist-lib/config.cjs +1 -1
  25. package/dist-lib/config.mjs +1 -1
  26. package/dist-lib/detox/index.cjs +46 -40
  27. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  28. package/dist-lib/expo-swift-bundle.cjs +7 -2
  29. package/dist-lib/expo-swift-metadata.cjs +1 -1
  30. package/dist-lib/expo-swift-metadata.mjs +1 -1
  31. package/dist-lib/home-paths.cjs +1 -1
  32. package/dist-lib/host/bridge-host.cjs +134 -37
  33. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  34. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  36. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  37. package/dist-lib/host/websocket-proxy.cjs +1 -1
  38. package/dist-lib/index.cjs +1 -1
  39. package/dist-lib/jump-to-source-babel.cjs +1 -1
  40. package/dist-lib/jump-to-source-native.cjs +1 -1
  41. package/dist-lib/kotlin-host.cjs +1 -1
  42. package/dist-lib/menu.cjs +1 -1
  43. package/dist-lib/menu.mjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  45. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  46. package/dist-lib/metro-production-bundle.cjs +1 -1
  47. package/dist-lib/metro-production-bundle.mjs +1 -1
  48. package/dist-lib/metro.cjs +1 -1
  49. package/dist-lib/native-app-identity-project.cjs +1 -1
  50. package/dist-lib/native-app-identity-project.mjs +1 -1
  51. package/dist-lib/native-app-identity.cjs +1 -1
  52. package/dist-lib/native-app-identity.mjs +1 -1
  53. package/dist-lib/native-firebase-metadata.cjs +1 -1
  54. package/dist-lib/native-firebase-metadata.mjs +1 -1
  55. package/dist-lib/plist.cjs +1 -1
  56. package/dist-lib/plist.mjs +1 -1
  57. package/dist-lib/profiles.cjs +1 -1
  58. package/dist-lib/public-brand.cjs +1 -1
  59. package/dist-lib/react-native-host-modules.cjs +1 -1
  60. package/dist-lib/react-native-host-modules.mjs +1 -1
  61. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  62. package/dist-lib/sdk.cjs +1 -1
  63. package/dist-lib/sdk.mjs +1 -1
  64. package/dist-lib/skills.cjs +141 -93
  65. package/dist-lib/swift-compile.cjs +7 -2
  66. package/dist-lib/swift-compile.mjs +7 -2
  67. package/dist-lib/swift-package.cjs +1 -1
  68. package/dist-lib/swift-package.mjs +1 -1
  69. package/dist-lib/swift-submit.cjs +1 -1
  70. package/dist-lib/swift-submit.mjs +1 -1
  71. package/dist-lib/swift-toolchain.cjs +1 -1
  72. package/dist-lib/swift.cjs +1 -1
  73. package/dist-lib/vite-swift.cjs +7 -2
  74. package/dist-lib/vite.cjs +1 -1
  75. package/dist-lib/worklet-executable.cjs +1 -1
  76. package/dist-lib/worklet-executable.mjs +1 -1
  77. package/package.json +1 -1
  78. package/src/admitted-mac-build.ts +12 -0
  79. package/src/bridge-constants.ts +5 -3
  80. package/src/host/bridge-host.ts +34 -6
  81. package/src/swift-compile.ts +5 -4
  82. package/src/worker-system-chunks.ts +10 -9
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (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;
@@ -36,30 +36,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
 
38
38
  // ../../scripts/lib/chromium-admission.ts
39
- async function acquireChromiumAdmission(deps) {
40
- const { fs: fs38, os: os14, path: path42, childProcess: childProcess2, label } = deps;
39
+ function readChromiumQueue(deps, verified3, own) {
40
+ const { fs: fs38, os: os15, path: path42, childProcess: childProcess3 } = deps;
41
41
  const dir = path42.join(
42
- process.platform === "win32" ? os14.tmpdir() : "/tmp",
42
+ process.platform === "win32" ? os15.tmpdir() : "/tmp",
43
43
  "chromium-admission"
44
44
  );
45
45
  fs38.mkdirSync(dir, { recursive: true });
46
- const limit = Math.max(2, Math.floor(os14.availableParallelism() / 3));
47
- const startedAt = Math.round(Date.now() / 1e3 - process.uptime());
48
- const name2 = `${process.pid}-${startedAt}-${Math.random().toString(36).slice(2, 10)}`;
49
- const ticket = path42.join(dir, name2);
50
- fs38.closeSync(fs38.openSync(ticket, "wx"));
51
- let released = false;
52
- const release = () => {
53
- if (released) return;
54
- released = true;
55
- process.removeListener("exit", release);
56
- try {
57
- fs38.unlinkSync(ticket);
58
- } catch {
59
- }
60
- };
61
- process.on("exit", release);
62
- const verified3 = /* @__PURE__ */ new Map();
46
+ const limit = Math.max(2, Math.floor(os15.availableParallelism() / 3));
63
47
  const live = (entry) => {
64
48
  const match = /^(\d+)-(\d+)-/.exec(entry);
65
49
  if (!match) return false;
@@ -74,7 +58,7 @@ async function acquireChromiumAdmission(deps) {
74
58
  let same = pid === process.pid;
75
59
  if (!same) {
76
60
  try {
77
- const started = childProcess2.execFileSync("ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf8" }).trim();
61
+ const started = childProcess3.execFileSync("ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf8" }).trim();
78
62
  same = Math.abs(Date.parse(started) / 1e3 - Number(match[2])) <= 2;
79
63
  } catch {
80
64
  same = false;
@@ -83,29 +67,50 @@ async function acquireChromiumAdmission(deps) {
83
67
  verified3.set(entry, same);
84
68
  return same;
85
69
  };
86
- let waited = false;
87
- while (true) {
88
- const tickets = [];
89
- for (const entry of fs38.readdirSync(dir)) {
90
- if (entry !== name2 && !live(entry)) {
91
- try {
92
- fs38.unlinkSync(path42.join(dir, entry));
93
- } catch {
94
- }
95
- continue;
96
- }
70
+ const tickets = [];
71
+ for (const entry of fs38.readdirSync(dir)) {
72
+ if (entry !== own && !live(entry)) {
97
73
  try {
98
- tickets.push({
99
- entry,
100
- created: fs38.statSync(path42.join(dir, entry), { bigint: true }).ctimeNs
101
- });
74
+ fs38.unlinkSync(path42.join(dir, entry));
102
75
  } catch {
103
76
  }
77
+ continue;
104
78
  }
105
- tickets.sort(
106
- (a, b) => a.created === b.created ? a.entry < b.entry ? -1 : 1 : a.created < b.created ? -1 : 1
107
- );
108
- const rank = tickets.findIndex((t) => t.entry === name2);
79
+ try {
80
+ tickets.push({
81
+ entry,
82
+ created: fs38.statSync(path42.join(dir, entry), { bigint: true }).ctimeNs
83
+ });
84
+ } catch {
85
+ }
86
+ }
87
+ tickets.sort(
88
+ (a, b) => a.created === b.created ? a.entry < b.entry ? -1 : 1 : a.created < b.created ? -1 : 1
89
+ );
90
+ return { dir, limit, tickets: tickets.map((t) => t.entry) };
91
+ }
92
+ async function acquireChromiumAdmission(deps) {
93
+ const { fs: fs38, path: path42, label, readQueue } = deps;
94
+ const verified3 = /* @__PURE__ */ new Map();
95
+ const startedAt = Math.round(Date.now() / 1e3 - process.uptime());
96
+ const name2 = `${process.pid}-${startedAt}-${Math.random().toString(36).slice(2, 10)}`;
97
+ const ticket = path42.join(readQueue(deps, verified3, name2).dir, name2);
98
+ fs38.closeSync(fs38.openSync(ticket, "wx"));
99
+ let released = false;
100
+ const release = () => {
101
+ if (released) return;
102
+ released = true;
103
+ process.removeListener("exit", release);
104
+ try {
105
+ fs38.unlinkSync(ticket);
106
+ } catch {
107
+ }
108
+ };
109
+ process.on("exit", release);
110
+ let waited = false;
111
+ while (true) {
112
+ const { limit, tickets } = readQueue(deps, verified3, name2);
113
+ const rank = tickets.indexOf(name2);
109
114
  if (rank < 0) {
110
115
  fs38.closeSync(fs38.openSync(ticket, "wx"));
111
116
  continue;
@@ -116,7 +121,7 @@ async function acquireChromiumAdmission(deps) {
116
121
  return release;
117
122
  }
118
123
  if (!waited) {
119
- const holders = tickets.slice(0, limit).map((t) => t.entry.split("-")[0]);
124
+ const holders = tickets.slice(0, limit).map((t) => t.split("-")[0]);
120
125
  process.stderr.write(
121
126
  `[chromium-admission] ${label}: ${limit} chromium launches already run on this machine (pids ${holders.join(" ")}), queued ${rank - limit + 1}
122
127
  `
@@ -420,7 +425,8 @@ async function launchReapedScoped(launch2, readIdentity2 = processIdentity) {
420
425
  os,
421
426
  path,
422
427
  childProcess,
423
- label: process.argv.slice(1, 3).join(" ")
428
+ label: process.argv.slice(1, 3).join(" "),
429
+ readQueue: readChromiumQueue
424
430
  });
425
431
  let browser;
426
432
  try {
@@ -1067,7 +1073,6 @@ var init_light_native_package_names = __esm({
1067
1073
  "@react-native-karte/in-app-messaging",
1068
1074
  "@react-native-karte/notification",
1069
1075
  "@react-native-seoul/kakao-login",
1070
- "@react-native-vector-icons/get-image",
1071
1076
  "@react-native-zohosalesiq/mobilisten",
1072
1077
  "@react-native-zohosalesiq/mobilisten-core",
1073
1078
  "@reclaimprotocol/inapp-rn-sdk",
@@ -29861,6 +29866,16 @@ var init_internal_child = __esm({
29861
29866
  }
29862
29867
  });
29863
29868
 
29869
+ // src/admitted-mac-build.ts
29870
+ function admittedMacBuilderSlot(env = process.env) {
29871
+ return env.CONTRAST_REMOTE_BUILD === "mac" && env.REMOTE_MAC_SLOT_HELD === "1" && env.CONTRAST_HEAVY_ADMITTED === "1";
29872
+ }
29873
+ var init_admitted_mac_build = __esm({
29874
+ "src/admitted-mac-build.ts"() {
29875
+ "use strict";
29876
+ }
29877
+ });
29878
+
29864
29879
  // src/swift-distribution-contract.ts
29865
29880
  function swiftDistributionHost(platform, arch) {
29866
29881
  const host2 = `${platform}-${arch}`;
@@ -32104,7 +32119,7 @@ function compileSwiftProjectUnit(input, options) {
32104
32119
  };
32105
32120
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
32106
32121
  return serialize(root, async () => {
32107
- 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)) {
32122
+ if (process.platform === "darwin" && process.env.TM_SESSION && !admittedMacBuilderSlot() && process.env.CI !== "true" && moduleRoot === import_node_path10.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
32108
32123
  const requestRoot = (0, import_node_fs10.mkdtempSync)(import_node_path10.default.join(root, ".builder-request-"));
32109
32124
  const output = import_node_path10.default.join(requestRoot, "output");
32110
32125
  const request = import_node_path10.default.join(requestRoot, "request.json");
@@ -32234,6 +32249,7 @@ var init_swift_compile = __esm({
32234
32249
  import_node_os4 = __toESM(require("node:os"), 1);
32235
32250
  import_node_path10 = __toESM(require("node:path"), 1);
32236
32251
  import_node_util2 = require("node:util");
32252
+ init_admitted_mac_build();
32237
32253
  init_swift_distribution_contract();
32238
32254
  init_swift_icu();
32239
32255
  init_swift_package();
@@ -45278,6 +45294,7 @@ function quotedEnd(text3, start, end) {
45278
45294
  return end;
45279
45295
  }
45280
45296
  function decodeSingleQuoted(contents) {
45297
+ if (!contents.includes("\\")) return contents;
45281
45298
  let value = "";
45282
45299
  for (let cursor = 0; cursor < contents.length; cursor++) {
45283
45300
  const character = contents[cursor];
@@ -45697,6 +45714,15 @@ async function sha256HexBytes(bytes) {
45697
45714
  return hex;
45698
45715
  }
45699
45716
  async function assertSelfContainedMetroArtifactAssets(bundle) {
45717
+ return visitVerifiedMetroArtifactAssets(
45718
+ bundle,
45719
+ () => {
45720
+ },
45721
+ () => {
45722
+ }
45723
+ );
45724
+ }
45725
+ async function visitVerifiedMetroArtifactAssets(bundle, acceptVariant, acceptSite) {
45700
45726
  const seen = /* @__PURE__ */ new Set();
45701
45727
  const manifestLines = [];
45702
45728
  let descriptorsCount = 0;
@@ -45707,7 +45733,10 @@ async function assertSelfContainedMetroArtifactAssets(bundle) {
45707
45733
  for (const site of iterateAssetDescriptorSites(bundle)) {
45708
45734
  const descriptor = site.descriptor;
45709
45735
  const key2 = assetDescriptorKey(descriptor);
45710
- if (seen.has(key2)) continue;
45736
+ if (seen.has(key2)) {
45737
+ acceptSite(site);
45738
+ continue;
45739
+ }
45711
45740
  seen.add(key2);
45712
45741
  descriptorsCount++;
45713
45742
  const label = `${descriptor.httpServerLocation}/${descriptor.name}.${descriptor.type}`;
@@ -45742,11 +45771,13 @@ async function assertSelfContainedMetroArtifactAssets(bundle) {
45742
45771
  `peach ios --remote bundle is not self-contained: ${label} scale ${descriptor.scales[index]} bytes do not match their content hash`
45743
45772
  );
45744
45773
  }
45774
+ acceptVariant(descriptor, index, decoded);
45745
45775
  variants++;
45746
45776
  bytes += decoded.byteLength;
45747
45777
  descriptorBytes += decoded.byteLength;
45748
45778
  }
45749
45779
  sizes.push({ asset: label, bytes: descriptorBytes });
45780
+ acceptSite(site);
45750
45781
  }
45751
45782
  } catch (error) {
45752
45783
  if (error instanceof Error && error.message.startsWith("peach ios --remote bundle is not self-contained:")) {
@@ -45768,52 +45799,48 @@ async function assertSelfContainedMetroArtifactAssets(bundle) {
45768
45799
  };
45769
45800
  }
45770
45801
  async function separateMetroArtifactAssets(bundle) {
45771
- const assets2 = await assertSelfContainedMetroArtifactAssets(bundle);
45772
- const sites = scanAssetDescriptorSites(bundle);
45773
45802
  const resources = /* @__PURE__ */ new Map();
45774
45803
  const entries = /* @__PURE__ */ new Map();
45775
- for (const site of sites) {
45776
- const descriptor = site.descriptor;
45777
- const key2 = assetDescriptorKey(descriptor);
45778
- if (entries.has(key2)) continue;
45779
- const contentType = metroAssetContentType(descriptor.type);
45780
- const prefix = `data:${contentType};base64,`;
45781
- const fileUris = [];
45782
- const fileHashes = [];
45783
- for (let index = 0; index < descriptor.scales.length; index++) {
45784
- const dataUri = descriptor.fileUris?.[index];
45804
+ const pieces = [];
45805
+ let cursor = 0;
45806
+ const assets2 = await visitVerifiedMetroArtifactAssets(
45807
+ bundle,
45808
+ (descriptor, index, bytes) => {
45809
+ const key2 = assetDescriptorKey(descriptor);
45810
+ let entry = entries.get(key2);
45811
+ if (!entry) {
45812
+ entry = { fileUris: [], fileHashes: [], scales: descriptor.scales };
45813
+ entries.set(key2, entry);
45814
+ }
45785
45815
  const sha256 = descriptor.fileHashes?.[index];
45786
- if (!dataUri || !sha256) throw new Error("verified Metro asset is incomplete");
45787
45816
  const scale = descriptor.scales[index];
45788
- if (scale === void 0) throw new Error("verified Metro asset scale is missing");
45817
+ if (!sha256 || scale === void 0) {
45818
+ throw new Error("verified Metro asset variant is incomplete");
45819
+ }
45789
45820
  const filename = metroAssetScaleFilename(descriptor.name, descriptor.type, scale);
45790
45821
  const uri = `${PEACH_BUNDLE_ASSET_PREFIX}${sha256}/${encodeURIComponent(filename)}`;
45791
45822
  if (!resources.has(uri)) {
45792
- const bytes = decodeBase64ToBytes(dataUri.slice(prefix.length));
45793
45823
  resources.set(uri, {
45794
45824
  uri,
45795
45825
  sha256,
45796
- contentType,
45826
+ contentType: metroAssetContentType(descriptor.type),
45797
45827
  bytes,
45798
45828
  byteLength: bytes.byteLength
45799
45829
  });
45800
45830
  }
45801
- fileUris.push(uri);
45802
- fileHashes.push(sha256);
45831
+ entry.fileUris.push(uri);
45832
+ entry.fileHashes.push(sha256);
45833
+ },
45834
+ (site) => {
45835
+ const entry = entries.get(assetDescriptorKey(site.descriptor));
45836
+ if (!entry) throw new Error("verified Metro asset descriptor is missing");
45837
+ pieces.push(
45838
+ bundle.slice(cursor, site.start),
45839
+ rewriteDescriptorObject(bundle, site, entry)
45840
+ );
45841
+ cursor = site.end;
45803
45842
  }
45804
- entries.set(key2, { fileUris, fileHashes, scales: descriptor.scales });
45805
- }
45806
- const pieces = [];
45807
- let cursor = 0;
45808
- for (const site of sites) {
45809
- const entry = entries.get(assetDescriptorKey(site.descriptor));
45810
- if (!entry) throw new Error("verified Metro asset descriptor is missing");
45811
- pieces.push(
45812
- bundle.slice(cursor, site.start),
45813
- rewriteDescriptorObject(bundle, site, entry)
45814
- );
45815
- cursor = site.end;
45816
- }
45843
+ );
45817
45844
  pieces.push(bundle.slice(cursor));
45818
45845
  return { code: pieces.join(""), assets: assets2, resources: [...resources.values()] };
45819
45846
  }
@@ -48649,15 +48676,17 @@ function unrefTimer(timer) {
48649
48676
  timer.unref();
48650
48677
  }
48651
48678
  }
48652
- var import_child_process3, import_fs2, import_http4, import_path2, import_ws, SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, CAMERA_FIXTURE_ROUTE, CAMERA_FIXTURE_NAME_RE, SootSimBridgeHost;
48679
+ var import_child_process3, import_fs2, import_http4, import_os, import_path2, import_ws, SOOTSIM_CROSS_ORIGIN_EMBEDDER_POLICY, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, CAMERA_FIXTURE_ROUTE, CAMERA_FIXTURE_NAME_RE, SootSimBridgeHost;
48653
48680
  var init_bridge_host = __esm({
48654
48681
  "src/host/bridge-host.ts"() {
48655
48682
  "use strict";
48656
- import_child_process3 = require("child_process");
48683
+ import_child_process3 = __toESM(require("child_process"), 1);
48657
48684
  import_fs2 = __toESM(require("fs"), 1);
48658
48685
  import_http4 = require("http");
48686
+ import_os = __toESM(require("os"), 1);
48659
48687
  import_path2 = __toESM(require("path"), 1);
48660
48688
  import_ws = require("ws");
48689
+ init_chromium_admission();
48661
48690
  init_dev_server_scanner();
48662
48691
  init_automatic_update_policy();
48663
48692
  init_backend_origin();
@@ -50074,6 +50103,7 @@ var init_bridge_host = __esm({
50074
50103
  }
50075
50104
  reapIdleSims(now = Date.now()) {
50076
50105
  const attachedSimIds = new Set(this.cliSimBySocket.values());
50106
+ let reclaimable = null;
50077
50107
  for (const sim of this.sims.values()) {
50078
50108
  if (attachedSimIds.has(sim.id)) continue;
50079
50109
  const automation = this.isAutomationSim(sim);
@@ -50082,9 +50112,27 @@ var init_bridge_host = __esm({
50082
50112
  continue;
50083
50113
  }
50084
50114
  const idleMs = now - Math.max(sim.lastActiveAt, sim.connectedAt);
50085
- const ttl = automation ? AUTOMATION_SIM_IDLE_REAP_TTL_MS : _SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS;
50086
- if (idleMs >= ttl) this.closeSimSocketFromHost(sim.ws);
50115
+ if (automation) {
50116
+ if (idleMs >= AUTOMATION_SIM_IDLE_REAP_TTL_MS && idleMs > (reclaimable?.idleMs ?? 0))
50117
+ reclaimable = { ws: sim.ws, idleMs };
50118
+ continue;
50119
+ }
50120
+ if (idleMs >= _SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS)
50121
+ this.closeSimSocketFromHost(sim.ws);
50087
50122
  }
50123
+ if (reclaimable && this.chromiumLaunchWaiting())
50124
+ this.closeSimSocketFromHost(reclaimable.ws);
50125
+ }
50126
+ chromiumQueueVerified = /* @__PURE__ */ new Map();
50127
+ chromiumLaunchWaiting() {
50128
+ const queue2 = readChromiumQueue(
50129
+ { fs: import_fs2.default, os: import_os.default, path: import_path2.default, childProcess: import_child_process3.default },
50130
+ this.chromiumQueueVerified
50131
+ );
50132
+ const live = new Set(queue2.tickets);
50133
+ for (const entry of this.chromiumQueueVerified.keys())
50134
+ if (!live.has(entry)) this.chromiumQueueVerified.delete(entry);
50135
+ return queue2.tickets.length > queue2.limit;
50088
50136
  }
50089
50137
  // ping every connected ws; if the previous round's ping went unanswered,
50090
50138
  // terminate the socket so 'close' fires and the sim cleanup path
@@ -50980,7 +51028,7 @@ function getCurrentSimPath() {
50980
51028
  return (0, import_path3.resolve)(envPath);
50981
51029
  }
50982
51030
  const key2 = getCliIdentityKey();
50983
- return (0, import_path3.join)((0, import_os.tmpdir)(), `peach-current-sim-${key2}.json`);
51031
+ return (0, import_path3.join)((0, import_os2.tmpdir)(), `peach-current-sim-${key2}.json`);
50984
51032
  }
50985
51033
  function legacyCloudCredentialDirectory(filepath) {
50986
51034
  return (0, import_path3.join)((0, import_path3.dirname)(filepath), `${(0, import_path3.basename)(filepath)}.credentials`);
@@ -51032,12 +51080,12 @@ function saveCurrentSimId(simId) {
51032
51080
  function clearCurrentSimId() {
51033
51081
  (0, import_fs4.rmSync)(getCurrentSimPath(), { force: true });
51034
51082
  }
51035
- var import_fs4, import_os, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, LEGACY_CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE, INIT_COMM_RE, readCurrentSim;
51083
+ var import_fs4, import_os2, import_path3, CURRENT_SIM_VERSION, CURRENT_SIM_PATH_ENV, LEGACY_CURRENT_SIM_PATH_ENV, IDENTITY_ENV_VARS, IMMORTAL_HOST_COMM_RE, INIT_COMM_RE, readCurrentSim;
51036
51084
  var init_current_sim = __esm({
51037
51085
  "cli/current-sim.ts"() {
51038
51086
  "use strict";
51039
51087
  import_fs4 = require("fs");
51040
- import_os = require("os");
51088
+ import_os2 = require("os");
51041
51089
  import_path3 = require("path");
51042
51090
  init_parent_pid();
51043
51091
  init_secure_file();
@@ -55615,7 +55663,7 @@ function resolveUserDataDir(opts) {
55615
55663
  return playwrightProfileUserDataDir(ensureProfile(opts.profileId).id);
55616
55664
  }
55617
55665
  if (opts.ephemeralProfile) {
55618
- return (0, import_fs7.mkdtempSync)((0, import_path6.join)((0, import_os2.tmpdir)(), "peach-playwright-profile-"));
55666
+ return (0, import_fs7.mkdtempSync)((0, import_path6.join)((0, import_os3.tmpdir)(), "peach-playwright-profile-"));
55619
55667
  }
55620
55668
  return "";
55621
55669
  }
@@ -55706,7 +55754,7 @@ async function launch(opts) {
55706
55754
  }
55707
55755
  }
55708
55756
  const cdpPort = opts.cdpPort ?? (hostCommand ? await freePort() : void 0);
55709
- const errLog = (0, import_path6.join)((0, import_os2.tmpdir)(), playwrightHostLogName(Date.now(), process.pid));
55757
+ const errLog = (0, import_path6.join)((0, import_os3.tmpdir)(), playwrightHostLogName(Date.now(), process.pid));
55710
55758
  const connectAckFile = `${errLog}.connected`;
55711
55759
  const completionFile = `${errLog}.completed`;
55712
55760
  const errFd = (0, import_fs7.openSync)(errLog, "a");
@@ -55748,7 +55796,7 @@ async function launch(opts) {
55748
55796
  child.unref();
55749
55797
  const ownerComm = getProcessComm(ownerPid);
55750
55798
  const idleMinutes = AUTOMATION_SIM_IDLE_REAP_TTL_MS / 6e4;
55751
- const ownerNote = ` \u2014 browser closes after ${idleMinutes} min with no peach command or input, or when pid ${ownerPid}${ownerComm ? ` (${ownerComm})` : ""} exits`;
55799
+ const ownerNote = ` \u2014 browser closes when pid ${ownerPid}${ownerComm ? ` (${ownerComm})` : ""} exits, or after ${idleMinutes} min with no peach command or input if another browser launch is waiting for its slot`;
55752
55800
  return {
55753
55801
  launched: true,
55754
55802
  message: `playwright chrome launched \u2192 ${targetUrl.href}${ownerNote}`,
@@ -55769,14 +55817,14 @@ async function launch(opts) {
55769
55817
  (0, import_fs7.closeSync)(errFd);
55770
55818
  }
55771
55819
  }
55772
- var import_child_process6, import_fs7, import_net2, import_os2, import_path6, playwrightDriver;
55820
+ var import_child_process6, import_fs7, import_net2, import_os3, import_path6, playwrightDriver;
55773
55821
  var init_playwright = __esm({
55774
55822
  "cli/drivers/playwright.ts"() {
55775
55823
  "use strict";
55776
55824
  import_child_process6 = require("child_process");
55777
55825
  import_fs7 = require("fs");
55778
55826
  import_net2 = require("net");
55779
- import_os2 = require("os");
55827
+ import_os3 = require("os");
55780
55828
  import_path6 = require("path");
55781
55829
  init_bridge_constants();
55782
55830
  init_desktop_host_delivery();
@@ -56154,12 +56202,12 @@ function skillsDir() {
56154
56202
  return skillsDirPath;
56155
56203
  }
56156
56204
  function targetFromHome(envName, fallbackDir) {
56157
- const home = process.env[envName] || path38.join(os12.homedir(), fallbackDir);
56205
+ const home = process.env[envName] || path38.join(os13.homedir(), fallbackDir);
56158
56206
  return path38.join(home, "skills");
56159
56207
  }
56160
56208
  function codexTargets() {
56161
56209
  const homes = /* @__PURE__ */ new Map();
56162
- const userHome = process.env.HOME || os12.homedir();
56210
+ const userHome = process.env.HOME || os13.homedir();
56163
56211
  const primaryCodexHome = process.env.CODEX_HOME || path38.join(userHome, ".codex");
56164
56212
  homes.set(path38.resolve(primaryCodexHome), "codex");
56165
56213
  const tmCodexHomes = process.env.TM_CODEX_HOMES;
@@ -56312,13 +56360,13 @@ function listSkills() {
56312
56360
  }
56313
56361
  return skills.sort((a, b) => a.name.localeCompare(b.name));
56314
56362
  }
56315
- var import_child_process7, fs33, os12, path38, import_url3, import_meta3, skillsDirPath;
56363
+ var import_child_process7, fs33, os13, path38, import_url3, import_meta3, skillsDirPath;
56316
56364
  var init_skills = __esm({
56317
56365
  "cli/commands/skills.ts"() {
56318
56366
  "use strict";
56319
56367
  import_child_process7 = require("child_process");
56320
56368
  fs33 = __toESM(require("fs"), 1);
56321
- os12 = __toESM(require("os"), 1);
56369
+ os13 = __toESM(require("os"), 1);
56322
56370
  path38 = __toESM(require("path"), 1);
56323
56371
  import_url3 = require("url");
56324
56372
  init_cli_version();
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (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;
@@ -73,6 +73,11 @@ var import_node_os = __toESM(require("node:os"), 1);
73
73
  var import_node_path2 = __toESM(require("node:path"), 1);
74
74
  var import_node_util2 = require("node:util");
75
75
 
76
+ // src/admitted-mac-build.ts
77
+ function admittedMacBuilderSlot(env = process.env) {
78
+ return env.CONTRAST_REMOTE_BUILD === "mac" && env.REMOTE_MAC_SLOT_HELD === "1" && env.CONTRAST_HEAVY_ADMITTED === "1";
79
+ }
80
+
76
81
  // src/is-record.ts
77
82
  function isRecord(value) {
78
83
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2343,7 +2348,7 @@ function compileSwiftProjectUnit(input, options) {
2343
2348
  };
2344
2349
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
2345
2350
  return serialize(root, async () => {
2346
- 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)) {
2351
+ 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)) {
2347
2352
  const requestRoot = (0, import_node_fs2.mkdtempSync)(import_node_path2.default.join(root, ".builder-request-"));
2348
2353
  const output = import_node_path2.default.join(requestRoot, "output");
2349
2354
  const request = import_node_path2.default.join(requestRoot, "request.json");
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1477 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
4
  import { execFile as execFile2, execFileSync } from "node:child_process";
@@ -19,6 +19,11 @@ import os from "node:os";
19
19
  import path2 from "node:path";
20
20
  import { promisify as promisify2 } from "node:util";
21
21
 
22
+ // src/admitted-mac-build.ts
23
+ function admittedMacBuilderSlot(env = process.env) {
24
+ return env.CONTRAST_REMOTE_BUILD === "mac" && env.REMOTE_MAC_SLOT_HELD === "1" && env.CONTRAST_HEAVY_ADMITTED === "1";
25
+ }
26
+
22
27
  // src/is-record.ts
23
28
  function isRecord(value) {
24
29
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2289,7 +2294,7 @@ function compileSwiftProjectUnit(input, options) {
2289
2294
  };
2290
2295
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
2291
2296
  return serialize(root, async () => {
2292
- if (process.platform === "darwin" && process.env.TM_SESSION && !process.env.CONTRAST_REMOTE_BUILD && process.env.CI !== "true" && moduleRoot === path2.resolve(import.meta.dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
2297
+ if (process.platform === "darwin" && process.env.TM_SESSION && !admittedMacBuilderSlot() && process.env.CI !== "true" && moduleRoot === path2.resolve(import.meta.dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
2293
2298
  const requestRoot = mkdtempSync(path2.join(root, ".builder-request-"));
2294
2299
  const output = path2.join(requestRoot, "output");
2295
2300
  const request = path2.join(requestRoot, "request.json");
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (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.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1477 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/swift-package.ts
4
4
  function isSwiftManifestFile(file) {
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (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.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1477 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/swiftContract.ts
4
4
  function isSwiftResourcePath(value) {
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (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.1469 | (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.1469 | (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.CONTRAST_REMOTE_BUILD && 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.1469 | (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.1469 | (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.1469 | (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.1469",
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