stim 1.28.0 → 1.30.0

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 (155) hide show
  1. package/dist/{acquire-artifact-CKByBnTD.mjs → acquire-artifact-CrZ4rEbI.mjs} +1 -1
  2. package/dist/{act-8iswyfRa.mjs → act-BaKjDWGw.mjs} +479 -29
  3. package/dist/{activity-DRMg4_mD.mjs → activity-BTaUf0tc.mjs} +6 -5
  4. package/dist/{agent-device-usage-output-tE90fDdo.mjs → agent-device-usage-output-DYBpO17K.mjs} +4 -4
  5. package/dist/{android-YWCbmkVK.mjs → android-BCYLwmH6.mjs} +5 -5
  6. package/dist/{android-D577ApKG.mjs → android-BEQUDpOg.mjs} +1 -1
  7. package/dist/{android-CHmSU4B4.mjs → android-BWqdDK6R.mjs} +44 -42
  8. package/dist/{android-CsPs-7Mg.mjs → android-DdKG6lyD.mjs} +44 -35
  9. package/dist/{android-cas-_aDifWW0.mjs → android-cas-BH6K12__.mjs} +4 -4
  10. package/dist/{android-project-DUGMbq28.d.mts → android-project-CCEQyYJK.d.mts} +6 -2
  11. package/dist/api.d.mts +7 -4
  12. package/dist/api.mjs +27 -27
  13. package/dist/{apk-signed-tail-CQbwM0qO.mjs → apk-signed-tail-B8kw4a8K.mjs} +2 -2
  14. package/dist/{artifact-DYtHjxsn.mjs → artifact-DTHXcmQ3.mjs} +12 -12
  15. package/dist/{artifact-bFkfD3vf.mjs → artifact-M6W2l-xh.mjs} +12 -12
  16. package/dist/{auto-placement-BVqs8AJi.mjs → auto-placement-CZaWDmcY.mjs} +10 -10
  17. package/dist/{browser-web-BUaLcafY.mjs → browser-web-JQ7lFej3.mjs} +12 -12
  18. package/dist/{build-cQURy_KW.mjs → build-C2ZWoCmg.mjs} +23 -23
  19. package/dist/{build-cache-CZULpXVl.mjs → build-cache-DlC3owap.mjs} +4 -4
  20. package/dist/{build-plan-CxoYfxsc.mjs → build-plan-J3iRR3gI.mjs} +6 -6
  21. package/dist/{cache-manifest-DEjqGGat.mjs → cache-manifest-evF_zJ9U.mjs} +1 -1
  22. package/dist/cache-manifest.mjs +1 -1
  23. package/dist/{ccache-Bm_A1xX9.mjs → ccache-B8gY50-h.mjs} +18 -18
  24. package/dist/{cli-CpbaLDa7.mjs → cli-xRPXJPtA.mjs} +19 -19
  25. package/dist/cli.mjs +1 -1
  26. package/dist/{client-YxCer6ab.mjs → client-DrHykA24.mjs} +5 -5
  27. package/dist/collector-run.mjs +5 -5
  28. package/dist/{command-output-C8R1KIvi.mjs → command-output-BBW8eWPL.mjs} +1 -1
  29. package/dist/{config-Cn94Jc0g.mjs → config-AbUjIBOQ.mjs} +121 -19
  30. package/dist/{dependencies-DKeMzwXY.mjs → dependencies-vUh9mp5z.mjs} +39 -38
  31. package/dist/{dependency-state-CojA2o0t.mjs → dependency-state-CPKAKCZ8.mjs} +1 -1
  32. package/dist/{dev-client-D-BW5uiq.mjs → dev-client-CASgAOu7.mjs} +2 -2
  33. package/dist/device-ChnO7bR9.mjs +761 -0
  34. package/dist/device-CsIdRXfm.mjs +175 -0
  35. package/dist/{device-CgXfbcz5.mjs → device-android-CcdQqQWg.mjs} +28 -195
  36. package/dist/{device-capacity-Cd8lMSn3.mjs → device-capacity-C5C_jOQd.mjs} +11 -11
  37. package/dist/device-host-worker.mjs +44 -35
  38. package/dist/{device-ios-Cc9ulihb.mjs → device-ios-DbmtPIiw.mjs} +28 -18
  39. package/dist/{device-lease-run-Mtzp4THX.mjs → device-lease-run-Do6zYA7y.mjs} +4 -4
  40. package/dist/{device-pool-eRz6DtCg.mjs → device-pool-CpoYiCGO.mjs} +3 -3
  41. package/dist/{device-eeK95Lir.mjs → device-provision-B5Ms94qY.mjs} +11 -302
  42. package/dist/{doctor-xf7ht-5n.mjs → doctor-CJSB5q-s.mjs} +20 -20
  43. package/dist/{doctor-Bz_ouYAW.mjs → doctor-CLE4AZEI.mjs} +20 -15
  44. package/dist/{doctor-C2QyhejJ.mjs → doctor-CpfbYh3Q.mjs} +1 -1
  45. package/dist/doctor-fingerprint.mjs +1 -1
  46. package/dist/{doctor-watchman-BTW82PDC.mjs → doctor-watchman-D1IyMle9.mjs} +4 -4
  47. package/dist/{eas-build-Dm6q68QY.mjs → eas-build-DIDOHw2P.mjs} +2 -2
  48. package/dist/{eas-fallback-DajNpxf-.mjs → eas-fallback-DVS9oBSc.mjs} +4 -4
  49. package/dist/{eas-session-ledger-CBFo_Uo1.mjs → eas-session-ledger-CW3l-inB.mjs} +5 -5
  50. package/dist/{error-diagnostics-D1QfyJzQ.mjs → error-diagnostics-XJ9eWdtq.mjs} +8 -8
  51. package/dist/{gc-PLFwb0k4.mjs → gc-BVIcxCxE.mjs} +2 -2
  52. package/dist/{gc-DM5oMm-J.mjs → gc-Co7PE36D.mjs} +80 -18
  53. package/dist/{guide-C4I46XAk.mjs → guide-DkepBgHT.mjs} +235 -34
  54. package/dist/{hosted-android-DlaKLbW0.mjs → hosted-android-Du7NxufJ.mjs} +3 -3
  55. package/dist/{hosted-client-DDRm9hPJ.mjs → hosted-client-Cect92SZ.mjs} +3 -3
  56. package/dist/{hosted-logs-bSebOKbz.mjs → hosted-logs-Opcjv1Lr.mjs} +17 -8
  57. package/dist/{hosted-logs-sync-B0c53W_c.mjs → hosted-logs-sync-wsI7N1Hv.mjs} +7 -11
  58. package/dist/{hosted-macos-B7-8Pv4H.mjs → hosted-macos-BP9Kucat.mjs} +5 -5
  59. package/dist/{hosted-native-CDe33CSr.mjs → hosted-native-DmdLSmvu.mjs} +9 -8
  60. package/dist/{idle-shutdown-CQ0QwU9J.mjs → idle-shutdown-BcMN_cLm.mjs} +7 -7
  61. package/dist/{ios-B1HvafEG.mjs → ios-BFkBHuRT.mjs} +8 -8
  62. package/dist/{ios-tg4tp3q1.mjs → ios-CG0IsLtt.mjs} +29 -29
  63. package/dist/{ios-B1DYuOjh.mjs → ios-CXnoVO_z.mjs} +4 -4
  64. package/dist/{ios-device-B4elVFKi.mjs → ios-device-ClSfuu-_.mjs} +1 -1
  65. package/dist/{ios-project-CR4mZ7CH.mjs → ios-project-BM9TbTE7.mjs} +7 -7
  66. package/dist/{ios-state-BPHqMDdZ.mjs → ios-state-Ce_dystM.mjs} +1 -1
  67. package/dist/{js-swap-CVpSW1fn.mjs → js-swap-9Rx-5Nqz.mjs} +4 -4
  68. package/dist/{launch-DoySmhjz.mjs → launch-DvJV1Mx4.mjs} +19 -19
  69. package/dist/{lightened-DFAJgfIk.mjs → lightened-23pqe7LS.mjs} +4 -4
  70. package/dist/{logs-BGsW7iPe.mjs → logs-DJgZlf2K.mjs} +9 -8
  71. package/dist/{logs-DI5ILkYB.mjs → logs-Pkeh3wZk.mjs} +7 -6
  72. package/dist/{macos-Bo9st9Di.mjs → macos-DPvPQadc.mjs} +20 -20
  73. package/dist/{macos-C12RMJQF.mjs → macos-Du07NsOB.mjs} +1 -1
  74. package/dist/macos-run.mjs +1 -1
  75. package/dist/maintenance-run.mjs +13 -9
  76. package/dist/{metro-BnhXV2Mj.mjs → metro-BMQHczcf.mjs} +2 -2
  77. package/dist/{metro-request-DXyKjVDF.mjs → metro-request-BtF7ox53.mjs} +1 -1
  78. package/dist/{named-ports-Phoi2POD.mjs → named-ports-DcktE2Pw.mjs} +2 -2
  79. package/dist/{native-android-vxgtLD7w.mjs → native-android-CBOM1_gB.mjs} +16 -16
  80. package/dist/{native-gradle-artifact-inputs-BN96IVw8.mjs → native-gradle-artifact-inputs-D_iAfPuS.mjs} +3 -3
  81. package/dist/{native-runtime-DG4Rodzj.mjs → native-runtime-D4cTwU0Z.mjs} +6 -6
  82. package/dist/{native-xcode-inputs-BKarCoKg.mjs → native-xcode-inputs-BF-ogSnG.mjs} +2 -2
  83. package/dist/{native-xcode-ios-8A-efGa5.mjs → native-xcode-ios-DwJBfMP6.mjs} +15 -15
  84. package/dist/{ndjson-Dy2W4vRa.mjs → ndjson-CrjIsGzw.mjs} +2 -2
  85. package/dist/offload-worker.d.mts +1 -1
  86. package/dist/offload-worker.mjs +22 -22
  87. package/dist/{ownership-DJCq48IJ.mjs → ownership-Dtz9G5Gl.mjs} +2 -2
  88. package/dist/{phone-reverses-BzTa8g1F.mjs → phone-reverses-CvhhkGMH.mjs} +4 -4
  89. package/dist/{placement-log-Cvhta5ib.mjs → placement-log-CRR_TE1r.mjs} +1 -1
  90. package/dist/{plan-placement-WkZdccuN.mjs → plan-placement-CdLc-pTb.mjs} +6 -6
  91. package/dist/{ports-UV4mJgyC.mjs → ports-g4N_cfyg.mjs} +3 -3
  92. package/dist/{prebuild-k8d_tqOq.mjs → prebuild-DBJMhwSS.mjs} +9 -9
  93. package/dist/{project-Sui52ywT.mjs → project-DPQjnpcI.mjs} +15 -15
  94. package/dist/{react-native-android-DANlGGQf.mjs → react-native-android-idMWOwkX.mjs} +24 -24
  95. package/dist/{react-native-build-jUHnIfZ9.mjs → react-native-build-BSoh4HkH.mjs} +7 -7
  96. package/dist/{react-native-doctor-DCWRjS7K.mjs → react-native-doctor-CYibY8-4.mjs} +9 -8
  97. package/dist/{react-native-ios-BwMsFMXi.mjs → react-native-ios-13KIIOOy.mjs} +16 -15
  98. package/dist/{recordings-iy0mkm7b.mjs → recordings-CHMaF73C.mjs} +1 -1
  99. package/dist/{reload-Bj7QyuDy.mjs → reload-B9DZOjcV.mjs} +1 -1
  100. package/dist/{reload-c_uEyc_X.mjs → reload-BUQI3dSu.mjs} +14 -14
  101. package/dist/{remote-DFlpAqdV.mjs → remote-C-RGHhAP.mjs} +8 -8
  102. package/dist/{result-BIcXREyC.mjs → result-W4HCum4A.mjs} +16 -16
  103. package/dist/{run-y2HwyNvg.mjs → run-BQAmrohh.mjs} +2 -2
  104. package/dist/{selection-CXgM_VK_.mjs → selection-PCMT97XD.mjs} +105 -62
  105. package/dist/{server-bare-2N4vSRZG.mjs → server-bare-CEQdB_F4.mjs} +37 -1
  106. package/dist/{server-command-qneHPcRI.mjs → server-command-oqi3TDy7.mjs} +5 -5
  107. package/dist/server-expo-BUFAq2In.mjs +2 -0
  108. package/dist/{server-expo-Ccm9zB0o.mjs → server-expo-C1K07shx.mjs} +8 -5
  109. package/dist/{settings-Cfd_Q6ys.mjs → settings-CKlMOmhj.mjs} +2 -2
  110. package/dist/{settings-CY5JZlNN.mjs → settings-D776ygML.mjs} +1 -1
  111. package/dist/{settings-Djl-mpjX.mjs → settings-D9LtQaUw.mjs} +2 -1
  112. package/dist/{settings-payload-DwQiEMCn.mjs → settings-payload-CE-NZ6Lq.mjs} +4 -4
  113. package/dist/{settings-write-CJpjkeAd.mjs → settings-write-D7Xwa_-M.mjs} +5 -5
  114. package/dist/settings.schema.json +58 -9
  115. package/dist/{simslim-DCQwzoPy.mjs → simslim-CbpHERcv.mjs} +1 -1
  116. package/dist/{slot-launch-BpmanOnk.mjs → slot-launch-CeIK1iUI.mjs} +6 -6
  117. package/dist/{stage-CmugrSG5.mjs → stage-Blqe6bWb.mjs} +1 -1
  118. package/dist/{start-DYLk6GXn.mjs → start-B7J5a9nS.mjs} +11 -11
  119. package/dist/{start-CHH3zgIU.mjs → start-CvP2pJjc.mjs} +1 -1
  120. package/dist/{state-BXC1Lfxw.mjs → state-C2AUjjhg.mjs} +1 -1
  121. package/dist/{state-B2QJbDwz.mjs → state-D5ZxwCGJ.mjs} +2 -2
  122. package/dist/{stats-DxKqhcGp.mjs → stats-Uo7l8OAk.mjs} +4 -4
  123. package/dist/{status-7ULDEJ1e.mjs → status-CK7ZoEhV.mjs} +2 -2
  124. package/dist/{status-D_Ljc89p.mjs → status-CqJI1TgG.mjs} +1 -1
  125. package/dist/{status-BHCkOZga.mjs → status-_rWXFSO7.mjs} +24 -24
  126. package/dist/{status-watch-BmsPqYSU.mjs → status-watch-CnSyXUmj.mjs} +4 -4
  127. package/dist/status-worker.mjs +1 -1
  128. package/dist/{stim-desktop-CbWo21kb.mjs → stim-desktop-CYXLFpFS.mjs} +1 -1
  129. package/dist/{stop-b2pouxAO.mjs → stop-Bogo9oO2.mjs} +2 -2
  130. package/dist/{stop-DQvE-P76.mjs → stop-CMVfaA-6.mjs} +4 -4
  131. package/dist/{stop-D-dGE9gh.mjs → stop-CnF9ixYe.mjs} +20 -19
  132. package/dist/supervisor-run.d.mts +1 -0
  133. package/dist/supervisor-run.mjs +23 -19
  134. package/dist/{support-04IhBUTT.mjs → support-BGqpYMV8.mjs} +15 -11
  135. package/dist/{support-BtlJKjyQ.mjs → support-DUevTPur.mjs} +9 -9
  136. package/dist/{swiftpm-artifact-inputs-Cj2UpmPN.mjs → swiftpm-artifact-inputs-BcJk6-3u.mjs} +1 -1
  137. package/dist/{swiftpm-macos-BhF2stxY.mjs → swiftpm-macos-DBrmoocG.mjs} +8 -8
  138. package/dist/toolchain-Cw9VVHOY.mjs +2 -0
  139. package/dist/{toolchain-mLA_km-b.mjs → toolchain-DLdoyxIt.mjs} +19 -11
  140. package/dist/{trigger-DMou-X7j.mjs → trigger-CfnOfpDd.mjs} +1 -1
  141. package/dist/trigger-DBZ-GBrl.mjs +2 -0
  142. package/dist/{warm-progress-B0Vpuvpl.mjs → warm-progress-DQ2wQZKp.mjs} +3 -3
  143. package/dist/web-CI_qCRPw.mjs +2 -0
  144. package/dist/{web-BYmK0TjL.mjs → web-g9U7L1sR.mjs} +8 -8
  145. package/dist/web-run.mjs +5 -5
  146. package/dist/{workspace-state-kIZrdlSg.mjs → workspace-state-DGwkPXwq.mjs} +2 -2
  147. package/dist/{workspaces-CmOcceDN.mjs → workspaces-7_RWoi6c.mjs} +11 -11
  148. package/dist/{worktree-nliAoHxB.mjs → worktree-DEet9H3p.mjs} +1 -1
  149. package/dist/{worktree-2dk5edza.mjs → worktree-qKJ3x07S.mjs} +25 -25
  150. package/package.json +7 -7
  151. package/shim/bundle-response.cjs +37 -0
  152. package/dist/server-expo-WulkyAwT.mjs +0 -2
  153. package/dist/toolchain-qktiV8xc.mjs +0 -2
  154. package/dist/trigger-qp2ji5wE.mjs +0 -2
  155. package/dist/web-CrVLVQZY.mjs +0 -2
@@ -0,0 +1,175 @@
1
+ import { H as deviceSlotPlatforms } from "./config-AbUjIBOQ.mjs";
2
+ import { s as ownedDeviceLabel } from "./project-DPQjnpcI.mjs";
3
+ import { b as configureNewOwnedAvd } from "./android-DdKG6lyD.mjs";
4
+ import { c as pidExists } from "./metro-BMQHczcf.mjs";
5
+ import { pt as teardownOwnedAvd } from "./workspaces-7_RWoi6c.mjs";
6
+ import { h as tailLines } from "./activity-BTaUf0tc.mjs";
7
+ import "./ios-CXnoVO_z.mjs";
8
+ import { t as clearDeviceIdleShutdown } from "./idle-shutdown-BcMN_cLm.mjs";
9
+ import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-DbmtPIiw.mjs";
10
+ import { t as reconcileSimSlim } from "./simslim-CbpHERcv.mjs";
11
+ import { n as ensureAndroidBooted, r as ensureOwnedAndroidDevice, t as ANDROID_BOOT_TIMEOUT_MS } from "./device-android-CcdQqQWg.mjs";
12
+ import { existsSync } from "node:fs";
13
+ import { dirname, join, resolve, sep } from "node:path";
14
+ import { rotatedLogPath } from "@stim-cli/core";
15
+ import { acceptsShape, settingDefinition } from "@stim-cli/core/state";
16
+ import { request } from "node:http";
17
+ //#region src/engine/metro-warmup.ts
18
+ const WARMUP_TIMEOUT_MS = 6e4;
19
+ async function requestLocal(url, platform, prefetch) {
20
+ return new Promise((resolve) => {
21
+ const req = request(url, { headers: {
22
+ accept: "application/json",
23
+ "expo-platform": platform,
24
+ "x-stim-metro-warmup": "1"
25
+ } });
26
+ const timer = setTimeout(() => req.destroy(), WARMUP_TIMEOUT_MS);
27
+ timer.unref();
28
+ req.on("socket", (socket) => socket.unref());
29
+ req.on("error", () => resolve(null));
30
+ req.on("close", () => {
31
+ clearTimeout(timer);
32
+ resolve(null);
33
+ });
34
+ req.on("response", (res) => {
35
+ let body = "";
36
+ res.setEncoding("utf8");
37
+ res.on("data", (chunk) => {
38
+ if (!prefetch) body += chunk;
39
+ });
40
+ res.on("error", () => resolve(null));
41
+ res.on("end", () => resolve(res.statusCode === 200 ? body : null));
42
+ });
43
+ req.end();
44
+ });
45
+ }
46
+ const ENTRY_EXTENSIONS = [
47
+ "",
48
+ ".js",
49
+ ".jsx",
50
+ ".ts",
51
+ ".tsx"
52
+ ];
53
+ function entryExists(bundlePath, root) {
54
+ const entry = decodeURIComponent(bundlePath.replace(/\.bundle\/*$/, ""));
55
+ if (entry.startsWith("/.expo/")) return true;
56
+ for (let dir = resolve(root);; dir = dirname(dir)) {
57
+ const file = resolve(dir, `.${entry}`);
58
+ if (file.startsWith(dir + sep) && ENTRY_EXTENSIONS.some((ext) => existsSync(file + ext))) return true;
59
+ if (dirname(dir) === dir) return false;
60
+ }
61
+ }
62
+ function recordedBundleUrl(logsDir, root, platform) {
63
+ const setting = settingDefinition(`metro.warmupUrl.${platform}`);
64
+ if (!logsDir || !root || !setting) return null;
65
+ const log = join(logsDir, "metro.ndjson");
66
+ for (const file of [log, rotatedLogPath(log)]) for (const line of (tailLines(file) ?? []).toReversed()) try {
67
+ const record = JSON.parse(line);
68
+ if (record?.event === "bundle_response_started" && record.platform === platform && acceptsShape(setting, record.url) && entryExists(new URL(record.url, "http://localhost").pathname, root)) return record.url;
69
+ } catch {}
70
+ return null;
71
+ }
72
+ async function warmMetro({ port, platform, isExpo, appId, bundleUrl, logsDir, root }) {
73
+ try {
74
+ const origin = `http://127.0.0.1:${port}`;
75
+ if (await requestLocal(new URL("/_stim/metro-warmup", origin), platform, false) !== "ready") return;
76
+ const url = new URL("/index.bundle", origin);
77
+ url.search = new URLSearchParams({
78
+ platform,
79
+ dev: "true",
80
+ lazy: "true",
81
+ minify: "false",
82
+ ...platform === "ios" ? { inlineSourceMap: "false" } : {},
83
+ modulesOnly: "false",
84
+ runModule: "true",
85
+ excludeSource: "true",
86
+ sourcePaths: "url-server",
87
+ ...appId ? { app: appId } : {}
88
+ }).toString();
89
+ bundleUrl ||= recordedBundleUrl(logsDir, root, platform);
90
+ if (!bundleUrl && isExpo) {
91
+ const body = await requestLocal(new URL(origin), platform, false);
92
+ if (body === null) return;
93
+ const manifest = JSON.parse(body);
94
+ bundleUrl = manifest.launchAsset?.url ?? manifest.bundleUrl;
95
+ if (typeof bundleUrl !== "string") return;
96
+ }
97
+ if (bundleUrl) {
98
+ const bundle = new URL(bundleUrl, origin);
99
+ url.pathname = bundle.pathname;
100
+ url.search = bundle.search;
101
+ }
102
+ await requestLocal(url, platform, true);
103
+ } catch {}
104
+ }
105
+ //#endregion
106
+ //#region src/engine/device.ts
107
+ /**
108
+ * Whether `ensureOwnedDevice` created, adopted or started booting the device, rather than finding it booted.
109
+ * Undefined for a remote device, which those functions do not describe.
110
+ */
111
+ function didSetUpDevice(device, remote) {
112
+ return remote ? void 0 : Boolean(device.setup || device.booting);
113
+ }
114
+ async function ensureOwnedDevice({ platform, project, projectPath, slot, settingsRoot = projectPath, label = ownedDeviceLabel(projectPath), settings, flags = {}, note = () => {}, out = () => {}, logFile = null, alive = pidExists, configureAvd = configureNewOwnedAvd, teardownAvd = teardownOwnedAvd, reconcileIosSimulator = reconcileSimSlim, simSnapshot }) {
115
+ await clearDeviceIdleShutdown(projectPath, platform, slot);
116
+ if (slot && slot !== "default") label = `${label}-${slot}`;
117
+ const record = deviceSlotPlatforms(project, slot)?.[platform] ?? null;
118
+ if (platform === "ios") return ensureOwnedIosDevice({
119
+ record,
120
+ projectPath,
121
+ slot,
122
+ settingsRoot,
123
+ label,
124
+ settings,
125
+ flags,
126
+ note,
127
+ out,
128
+ reconcileIosSimulator,
129
+ simSnapshot
130
+ });
131
+ return ensureOwnedAndroidDevice({
132
+ record,
133
+ projectPath,
134
+ slot,
135
+ settingsRoot,
136
+ label,
137
+ settings,
138
+ flags,
139
+ note,
140
+ out,
141
+ logFile,
142
+ alive,
143
+ configureAvd,
144
+ teardownAvd
145
+ });
146
+ }
147
+ const BOOT_POLL_MS = 500;
148
+ async function ensureBooted({ platform, device, simulatorApp, timeoutMs, pollMs = BOOT_POLL_MS, out = () => {}, logFile = null, alive = pidExists, projectPath, slot, deviceSlotWait }) {
149
+ if (platform === "ios") return ensureIosBooted({
150
+ device,
151
+ projectPath,
152
+ slot,
153
+ deviceSlotWait,
154
+ simulatorApp,
155
+ timeoutMs: timeoutMs ?? 6e5,
156
+ pollMs,
157
+ out
158
+ });
159
+ if (platform === "android") return ensureAndroidBooted({
160
+ device,
161
+ deviceSlotWait,
162
+ projectPath,
163
+ slot,
164
+ timeoutMs: timeoutMs ?? ANDROID_BOOT_TIMEOUT_MS,
165
+ out,
166
+ logFile,
167
+ alive
168
+ });
169
+ return {
170
+ failed: true,
171
+ reason: `Unknown platform "${platform}".`
172
+ };
173
+ }
174
+ //#endregion
175
+ export { warmMetro as i, ensureBooted as n, ensureOwnedDevice as r, didSetUpDevice as t };
@@ -1,117 +1,19 @@
1
1
  import { D as ownership_claim_exports, t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, j as acquireAvdClaim, t as allConsolePortsAndSerials, w as setDevice } from "./config-Cn94Jc0g.mjs";
3
- import { l as phaseLine } from "./command-output-C8R1KIvi.mjs";
4
- import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting } from "./settings-CY5JZlNN.mjs";
5
- import { s as ownedDeviceLabel } from "./project-Sui52ywT.mjs";
6
- import { B as ownedAvdDeviceProfile, F as listAvdsAsync, H as ownedAvdMatchesConfiguration, I as listInstalledSystemImages, K as ownedAvdSystemImage, O as getAvdNameForSerialAsync, U as ownedAvdName, X as pickDefaultSystemImage, _ as avdPoolConfiguration, b as configureNewOwnedAvd, ct as waitForBoot, gt as isLegacyDeletionClaim, j as listAdbDevicesAsync, n as OWNED_AVD_CONFIG_DEFAULTS, nt as resolveOwnedAvdSerialAsync, p as assertOwnedAvdStoppedAsync, pt as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, vt as parkedMaxSetting, x as createOwnedAvd, y as bootAndroidEmulator, yt as readParked, z as nextConsolePort } from "./android-CsPs-7Mg.mjs";
7
- import { c as pidExists } from "./metro-BnhXV2Mj.mjs";
8
- import { gt as teardownParkedAvd, pt as teardownOwnedAvd } from "./workspaces-CmOcceDN.mjs";
9
- import { h as tailLines } from "./activity-DRMg4_mD.mjs";
10
- import { B as reportMemoryCulprits, L as memoryCulpritsUnderAsync, R as readHostMemoryPressure, V as memoryCulpritAdvice, f as listAllIosSimsAsync } from "./ios-B1DYuOjh.mjs";
11
- import { g as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as countLiveOwnedDevicesFrom } from "./device-capacity-Cd8lMSn3.mjs";
12
- import { t as clearDeviceIdleShutdown } from "./idle-shutdown-CQ0QwU9J.mjs";
13
- import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-Cc9ulihb.mjs";
14
- import { t as reconcileSimSlim } from "./simslim-DCQwzoPy.mjs";
2
+ import { D as withConfigLock, G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync, _ as loadConfig, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, j as acquireAvdClaim, t as allConsolePortsAndSerials, w as setDevice } from "./config-AbUjIBOQ.mjs";
3
+ import { l as phaseLine } from "./command-output-BBW8eWPL.mjs";
4
+ import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting } from "./settings-D776ygML.mjs";
5
+ import { B as ownedAvdDeviceProfile, H as ownedAvdMatchesConfiguration, I as listAvdsAsync, K as ownedAvdSystemImage, L as listInstalledSystemImages, M as listAdbDevicesAsync, U as ownedAvdName, X as pickDefaultSystemImage, _ as avdPoolConfiguration, ct as waitForBoot, gt as isLegacyDeletionClaim, k as getAvdNameForSerialAsync, n as OWNED_AVD_CONFIG_DEFAULTS, nt as resolveOwnedAvdSerialAsync, p as assertOwnedAvdStoppedAsync, pt as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, vt as parkedMaxSetting, x as createOwnedAvd, y as bootAndroidEmulator, yt as readParked, z as nextConsolePort } from "./android-DdKG6lyD.mjs";
6
+ import { c as pidExists } from "./metro-BMQHczcf.mjs";
7
+ import { gt as teardownParkedAvd, pt as teardownOwnedAvd } from "./workspaces-7_RWoi6c.mjs";
8
+ import { B as reportMemoryCulprits, L as memoryCulpritsUnderAsync, R as readHostMemoryPressure, V as memoryCulpritAdvice, f as listAllIosSimsAsync } from "./ios-CXnoVO_z.mjs";
9
+ import { g as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as countLiveOwnedDevicesFrom } from "./device-capacity-C5C_jOQd.mjs";
15
10
  import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
16
11
  import { randomUUID } from "node:crypto";
17
12
  import { existsSync } from "node:fs";
18
13
  import { isDeepStrictEqual } from "node:util";
19
- import { dirname, join, resolve, sep } from "node:path";
20
- import { rotatedLogPath } from "@stim-cli/core";
21
- import { acceptsShape, settingDefinition } from "@stim-cli/core/state";
22
14
  import { fileURLToPath } from "node:url";
23
15
  import { captureProcessIdentity } from "@stim-cli/core/process-identity";
24
16
  import chalk from "chalk";
25
- import { request } from "node:http";
26
- //#region src/engine/metro-warmup.ts
27
- const WARMUP_TIMEOUT_MS = 6e4;
28
- async function requestLocal(url, platform, prefetch) {
29
- return new Promise((resolve) => {
30
- const req = request(url, { headers: {
31
- accept: "application/json",
32
- "expo-platform": platform,
33
- "x-stim-metro-warmup": "1"
34
- } });
35
- const timer = setTimeout(() => req.destroy(), WARMUP_TIMEOUT_MS);
36
- timer.unref();
37
- req.on("socket", (socket) => socket.unref());
38
- req.on("error", () => resolve(null));
39
- req.on("close", () => {
40
- clearTimeout(timer);
41
- resolve(null);
42
- });
43
- req.on("response", (res) => {
44
- let body = "";
45
- res.setEncoding("utf8");
46
- res.on("data", (chunk) => {
47
- if (!prefetch) body += chunk;
48
- });
49
- res.on("error", () => resolve(null));
50
- res.on("end", () => resolve(res.statusCode === 200 ? body : null));
51
- });
52
- req.end();
53
- });
54
- }
55
- const ENTRY_EXTENSIONS = [
56
- "",
57
- ".js",
58
- ".jsx",
59
- ".ts",
60
- ".tsx"
61
- ];
62
- function entryExists(bundlePath, root) {
63
- const entry = decodeURIComponent(bundlePath.replace(/\.bundle\/*$/, ""));
64
- if (entry.startsWith("/.expo/")) return true;
65
- for (let dir = resolve(root);; dir = dirname(dir)) {
66
- const file = resolve(dir, `.${entry}`);
67
- if (file.startsWith(dir + sep) && ENTRY_EXTENSIONS.some((ext) => existsSync(file + ext))) return true;
68
- if (dirname(dir) === dir) return false;
69
- }
70
- }
71
- function recordedBundleUrl(logsDir, root, platform) {
72
- const setting = settingDefinition(`metro.warmupUrl.${platform}`);
73
- if (!logsDir || !root || !setting) return null;
74
- const log = join(logsDir, "metro.ndjson");
75
- for (const file of [log, rotatedLogPath(log)]) for (const line of (tailLines(file) ?? []).toReversed()) try {
76
- const record = JSON.parse(line);
77
- if (record?.event === "bundle_response_started" && record.platform === platform && acceptsShape(setting, record.url) && entryExists(new URL(record.url, "http://localhost").pathname, root)) return record.url;
78
- } catch {}
79
- return null;
80
- }
81
- async function warmMetro({ port, platform, isExpo, appId, bundleUrl, logsDir, root }) {
82
- try {
83
- const origin = `http://127.0.0.1:${port}`;
84
- if (await requestLocal(new URL("/_stim/metro-warmup", origin), platform, false) !== "ready") return;
85
- const url = new URL("/index.bundle", origin);
86
- url.search = new URLSearchParams({
87
- platform,
88
- dev: "true",
89
- lazy: "true",
90
- minify: "false",
91
- ...platform === "ios" ? { inlineSourceMap: "false" } : {},
92
- modulesOnly: "false",
93
- runModule: "true",
94
- excludeSource: "true",
95
- sourcePaths: "url-server",
96
- ...appId ? { app: appId } : {}
97
- }).toString();
98
- bundleUrl ||= recordedBundleUrl(logsDir, root, platform);
99
- if (!bundleUrl && isExpo) {
100
- const body = await requestLocal(new URL(origin), platform, false);
101
- if (body === null) return;
102
- const manifest = JSON.parse(body);
103
- bundleUrl = manifest.launchAsset?.url ?? manifest.bundleUrl;
104
- if (typeof bundleUrl !== "string") return;
105
- }
106
- if (bundleUrl) {
107
- const bundle = new URL(bundleUrl, origin);
108
- url.pathname = bundle.pathname;
109
- url.search = bundle.search;
110
- }
111
- await requestLocal(url, platform, true);
112
- } catch {}
113
- }
114
- //#endregion
115
17
  //#region src/engine/android-avd-setup.ts
116
18
  var AvdBootError = class extends Error {
117
19
  remedy;
@@ -122,12 +24,12 @@ var AvdBootError = class extends Error {
122
24
  };
123
25
  var AvdRecoveryError = class extends AvdBootError {};
124
26
  function findOtherOwner(avdName, projectPath, selectedSlot = "default") {
125
- for (const [path, project] of Object.entries(loadConfig$1()?.projects ?? {})) if (projectDeviceSlots(project).some(({ slot, platforms }) => (path !== projectPath || slot !== selectedSlot) && platforms.android?.avdName?.toLowerCase() === avdName.toLowerCase())) return path;
27
+ for (const [path, project] of Object.entries(loadConfig()?.projects ?? {})) if (projectDeviceSlots(project).some(({ slot, platforms }) => (path !== projectPath || slot !== selectedSlot) && platforms.android?.avdName?.toLowerCase() === avdName.toLowerCase())) return path;
126
28
  return null;
127
29
  }
128
30
  async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, systemImage, deviceProfile, configuration, configure, teardown = teardownOwnedAvd }) {
129
- const { claim, reservation, previous, avdName } = await withConfigLockAsync$1(() => {
130
- const previous = deviceSlotPlatforms(loadConfig$1()?.projects?.[projectPath], slot)?.android;
31
+ const { claim, reservation, previous, avdName } = await withConfigLockAsync(() => {
32
+ const previous = deviceSlotPlatforms(loadConfig()?.projects?.[projectPath], slot)?.android;
131
33
  if (previous?.avdName && previous.avdName !== previousAvdName) throw new Error(`Another Stim run assigned AVD ${previous.avdName} to this workspace. Retry to use it.`);
132
34
  if (readParked("android").some((entry) => entry.name === ownedAvdName(label)) || findOtherOwner(ownedAvdName(label), projectPath, slot)) label = `${label}-${randomUUID().slice(0, 8)}`;
133
35
  const avdName = ownedAvdName(label);
@@ -152,7 +54,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
152
54
  throw error;
153
55
  }
154
56
  });
155
- const currentRecord = () => deviceSlotPlatforms(loadConfig$1()?.projects?.[projectPath], slot)?.android;
57
+ const currentRecord = () => deviceSlotPlatforms(loadConfig()?.projects?.[projectPath], slot)?.android;
156
58
  const assertReservation = () => {
157
59
  if (readParked("android").some((entry) => entry.name === avdName)) throw new Error(`AVD ${avdName} was parked by another Stim run. Retry to adopt it safely.`);
158
60
  const owner = findOtherOwner(avdName, projectPath, slot);
@@ -199,7 +101,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
199
101
  if (!message.includes("already exists")) throw error;
200
102
  try {
201
103
  if (!(await listAvdsAsync()).includes(avdName)) throw new AvdRecoveryError(`AVD ${avdName} already exists on disk but is not listed by the emulator. ${message}`, "Run `npx stim gc` to inspect orphaned owned AVDs, then `npx stim gc --delete` to reclaim those safe to delete. Retry `stim android` after cleanup; keep any AVD that GC cannot verify.", error);
202
- await withConfigLockAsync$1(assertReservation);
104
+ await withConfigLockAsync(assertReservation);
203
105
  const resolved = await resolveOwnedAvdSerialAsync(avdName);
204
106
  if (resolved.missing || resolved.notOwned) throw new Error(`AVD ${avdName} could not be verified for recovery. Retry after checking its registration.`, { cause: error });
205
107
  if (!resolved.serial) await assertOwnedAvdStoppedAsync(avdName);
@@ -214,7 +116,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
214
116
  } : {}
215
117
  };
216
118
  } catch (recoveryError) {
217
- await withConfigLockAsync$1(() => {
119
+ await withConfigLockAsync(() => {
218
120
  if (!isDeepStrictEqual(currentRecord(), reservation)) return;
219
121
  if (previous) setDevice(projectPath, "android", previous, slot);
220
122
  else clearDevice(projectPath, "android", slot, avdName);
@@ -228,7 +130,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
228
130
  } catch (error) {
229
131
  configurationFailure = { error };
230
132
  }
231
- if (!configurationFailure) await withConfigLockAsync$1(() => {
133
+ if (!configurationFailure) await withConfigLockAsync(() => {
232
134
  assertReservation();
233
135
  setDevice(projectPath, "android", {
234
136
  avdName,
@@ -258,7 +160,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
258
160
  slot,
259
161
  expectedRecord: reservation
260
162
  },
261
- onRemoved: () => withConfigLockAsync$1(() => clearDevice(projectPath, "android", slot, avdName))
163
+ onRemoved: () => withConfigLockAsync(() => clearDevice(projectPath, "android", slot, avdName))
262
164
  });
263
165
  const orphan = cleanup.status === "failed" || cleanup.status === "skipped" ? ` The owned AVD remains tracked for cleanup (${cleanup.reason || cleanup.status}); fix the cause, then retry or run \`stim gc --delete\`.` : "";
264
166
  throw new Error(`Created owned AVD ${avdName}, but could not configure its AVD settings: ${String(error?.message || error)}${orphan}`, { cause: error });
@@ -286,7 +188,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
286
188
  slot,
287
189
  expectedRecord: record
288
190
  },
289
- onRemoved: () => withConfigLockAsync$1(() => clearDevice(projectPath, "android", slot, avdName))
191
+ onRemoved: () => withConfigLockAsync(() => clearDevice(projectPath, "android", slot, avdName))
290
192
  });
291
193
  if (cleanup.status === "failed" || cleanup.status === "skipped") throw new AvdRecoveryError(`Owned AVD ${record.avdName} has incomplete setup and could not be deleted (${cleanup.reason || cleanup.status}). Fix the cause, then retry; Stim kept the device record for cleanup.`, "Wait for any active AVD operation to finish. If the refusal names an unresolved claim, inspect its creator and native processes before removing only that claim. Retry `stim android` to reconcile the incomplete device.");
292
194
  record = null;
@@ -304,7 +206,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
304
206
  slot,
305
207
  expectedRecord: record
306
208
  },
307
- onRemoved: () => withConfigLockAsync$1(() => clearDevice(projectPath, "android", slot, avdName))
209
+ onRemoved: () => withConfigLockAsync(() => clearDevice(projectPath, "android", slot, avdName))
308
210
  });
309
211
  if (cleanup.status === "failed" || cleanup.status === "skipped") throw new AvdRecoveryError(`Owned AVD ${avdName} never finished a boot, but could not be deleted to create one on ${requestedImage} (${cleanup.reason || cleanup.status}). Stim kept the device record.`, "Fix the cause, then retry, or pass `--slot <name>` to create the requested emulator beside it.");
310
212
  out(phaseLine("device", `deleted ${avdName}, which never finished a boot, to create one on ${requestedImage}`));
@@ -329,7 +231,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
329
231
  owned: true,
330
232
  deviceName: record.deviceName ?? record.avdName
331
233
  };
332
- await withConfigLockAsync$1(() => setDevice(projectPath, "android", updated, slot));
234
+ await withConfigLockAsync(() => setDevice(projectPath, "android", updated, slot));
333
235
  return {
334
236
  ...updated,
335
237
  systemImage: ownedAvdSystemImage(record.avdName),
@@ -469,7 +371,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
469
371
  deviceProfile: created.deviceProfile
470
372
  };
471
373
  }
472
- function claimAndroidConsolePort({ projectPath, slot, avdName, deviceName, livePorts = [], metadata }, { lock = withConfigLock$1, recordedPorts = () => allConsolePortsAndSerials().androidConsolePorts, record = setDevice } = {}) {
374
+ function claimAndroidConsolePort({ projectPath, slot, avdName, deviceName, livePorts = [], metadata }, { lock = withConfigLock, recordedPorts = () => allConsolePortsAndSerials().androidConsolePorts, record = setDevice } = {}) {
473
375
  return lock(() => {
474
376
  const consolePort = nextConsolePort([...recordedPorts(), ...livePorts]);
475
377
  const claim = {
@@ -495,7 +397,7 @@ async function bootOwnedAvdOnFreshPort({ avdName, deviceSlotWait, metadata, proj
495
397
  key: avdName
496
398
  }, async () => {
497
399
  const livePorts = await liveAndroidConsolePorts();
498
- const claim = await withConfigLockAsync$1(() => claimAndroidConsolePort({
400
+ const claim = await withConfigLockAsync(() => claimAndroidConsolePort({
499
401
  projectPath,
500
402
  slot,
501
403
  avdName,
@@ -518,7 +420,7 @@ async function bootOwnedAvdOnFreshPort({ avdName, deviceSlotWait, metadata, proj
518
420
  if (result.failed) throw new AvdBootError(result.reason, result.remedy);
519
421
  const running = await getAvdNameForSerialAsync(serial);
520
422
  if (running && running !== avdName) throw new Error(`${serial} is running AVD ${running}, not this workspace's owned AVD ${avdName}; refusing to use it.`);
521
- await withConfigLockAsync$1(() => clearAndroidBootPending(projectPath, avdName, slot));
423
+ await withConfigLockAsync(() => clearAndroidBootPending(projectPath, avdName, slot));
522
424
  await muteBootedEmulator(serial, avdName, out);
523
425
  const { bootPending: _booted, ...booted } = claim;
524
426
  return {
@@ -527,7 +429,7 @@ async function bootOwnedAvdOnFreshPort({ avdName, deviceSlotWait, metadata, proj
527
429
  setup: true
528
430
  };
529
431
  } catch (error) {
530
- await withConfigLockAsync$1(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
432
+ await withConfigLockAsync(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
531
433
  throw error;
532
434
  }
533
435
  }, {
@@ -670,7 +572,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
670
572
  };
671
573
  const avdName = device.avdName;
672
574
  const booted = async (result) => {
673
- if (!result.failed) await withConfigLockAsync$1(() => clearAndroidBootPending(projectPath, avdName, slot));
575
+ if (!result.failed) await withConfigLockAsync(() => clearAndroidBootPending(projectPath, avdName, slot));
674
576
  return result;
675
577
  };
676
578
  if (resolved.serial) return booted(await waitForAndroidBoot({
@@ -686,7 +588,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
686
588
  }));
687
589
  const boot = async () => {
688
590
  const livePorts = await liveAndroidConsolePorts();
689
- const claim = await withConfigLockAsync$1(() => claimAndroidConsolePort({
591
+ const claim = await withConfigLockAsync(() => claimAndroidConsolePort({
690
592
  projectPath,
691
593
  slot,
692
594
  avdName,
@@ -701,7 +603,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
701
603
  try {
702
604
  pid = await bootAndroidEmulator(avdName, claim.consolePort, { logFile });
703
605
  } catch (e) {
704
- await withConfigLockAsync$1(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
606
+ await withConfigLockAsync(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
705
607
  return {
706
608
  failed: true,
707
609
  reason: `Could not start emulator for AVD ${avdName}: ${e?.message || e}`
@@ -714,7 +616,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
714
616
  alive,
715
617
  out
716
618
  });
717
- if (result.failed) await withConfigLockAsync$1(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
619
+ if (result.failed) await withConfigLockAsync(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
718
620
  else await muteBootedEmulator(serial, avdName, out);
719
621
  return booted(result);
720
622
  };
@@ -739,73 +641,4 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
739
641
  }
740
642
  }
741
643
  //#endregion
742
- //#region src/engine/device.ts
743
- /**
744
- * Whether `ensureOwnedDevice` created, adopted or started booting the device, rather than finding it booted.
745
- * Undefined for a remote device, which those functions do not describe.
746
- */
747
- function didSetUpDevice(device, remote) {
748
- return remote ? void 0 : Boolean(device.setup || device.booting);
749
- }
750
- async function ensureOwnedDevice({ platform, project, projectPath, slot, settingsRoot = projectPath, label = ownedDeviceLabel(projectPath), settings, flags = {}, note = () => {}, out = () => {}, logFile = null, alive = pidExists, configureAvd = configureNewOwnedAvd, teardownAvd = teardownOwnedAvd, reconcileIosSimulator = reconcileSimSlim, simSnapshot }) {
751
- await clearDeviceIdleShutdown(projectPath, platform, slot);
752
- if (slot && slot !== "default") label = `${label}-${slot}`;
753
- const record = deviceSlotPlatforms(project, slot)?.[platform] ?? null;
754
- if (platform === "ios") return ensureOwnedIosDevice({
755
- record,
756
- projectPath,
757
- slot,
758
- settingsRoot,
759
- label,
760
- settings,
761
- flags,
762
- note,
763
- out,
764
- reconcileIosSimulator,
765
- simSnapshot
766
- });
767
- return ensureOwnedAndroidDevice({
768
- record,
769
- projectPath,
770
- slot,
771
- settingsRoot,
772
- label,
773
- settings,
774
- flags,
775
- note,
776
- out,
777
- logFile,
778
- alive,
779
- configureAvd,
780
- teardownAvd
781
- });
782
- }
783
- const BOOT_POLL_MS = 500;
784
- async function ensureBooted({ platform, device, simulatorApp, timeoutMs, pollMs = BOOT_POLL_MS, out = () => {}, logFile = null, alive = pidExists, projectPath, slot, deviceSlotWait }) {
785
- if (platform === "ios") return ensureIosBooted({
786
- device,
787
- projectPath,
788
- slot,
789
- deviceSlotWait,
790
- simulatorApp,
791
- timeoutMs: timeoutMs ?? 6e5,
792
- pollMs,
793
- out
794
- });
795
- if (platform === "android") return ensureAndroidBooted({
796
- device,
797
- deviceSlotWait,
798
- projectPath,
799
- slot,
800
- timeoutMs: timeoutMs ?? ANDROID_BOOT_TIMEOUT_MS,
801
- out,
802
- logFile,
803
- alive
804
- });
805
- return {
806
- failed: true,
807
- reason: `Unknown platform "${platform}".`
808
- };
809
- }
810
- //#endregion
811
- export { AvdRecoveryError as a, AvdBootError as i, ensureBooted as n, warmMetro as o, ensureOwnedDevice as r, didSetUpDevice as t };
644
+ export { AvdBootError as a, muteBootedEmulator as i, ensureAndroidBooted as n, AvdRecoveryError as o, ensureOwnedAndroidDevice as r, ANDROID_BOOT_TIMEOUT_MS as t };
@@ -1,12 +1,12 @@
1
1
  import { D as ownership_claim_exports, d as workspaceProcessLockError, u as withWorkspaceProcessLock } from "./exec-aULwtNly.mjs";
2
- import { G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, d as getConfigDir, u as getConcurrencyLimits } from "./config-Cn94Jc0g.mjs";
3
- import { a as formatElapsed, l as phaseLine } from "./command-output-C8R1KIvi.mjs";
4
- import { g as deviceReclaimIdleMinutesSetting } from "./settings-CY5JZlNN.mjs";
5
- import { A as listAdbDevices, j as listAdbDevicesAsync } from "./android-CsPs-7Mg.mjs";
6
- import { ot as recordCapacityRefusal, st as recordCapacityWait, v as withIdleWorkspace } from "./workspaces-CmOcceDN.mjs";
2
+ import { G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, d as getConfigDir, u as getConcurrencyLimits } from "./config-AbUjIBOQ.mjs";
3
+ import { a as formatElapsed, l as phaseLine } from "./command-output-BBW8eWPL.mjs";
4
+ import { g as deviceReclaimIdleMinutesSetting } from "./settings-D776ygML.mjs";
5
+ import { M as listAdbDevicesAsync, j as listAdbDevices } from "./android-DdKG6lyD.mjs";
6
+ import { ot as recordCapacityRefusal, st as recordCapacityWait, v as withIdleWorkspace } from "./workspaces-7_RWoi6c.mjs";
7
7
  import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
8
- import { d as listAllIosSims, f as listAllIosSimsAsync, l as iosRuntimeMatches, y as parseRuntimeVersion } from "./ios-B1DYuOjh.mjs";
9
- import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-CQ0QwU9J.mjs";
8
+ import { d as listAllIosSims, f as listAllIosSimsAsync, l as iosRuntimeMatches, y as parseRuntimeVersion } from "./ios-CXnoVO_z.mjs";
9
+ import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-BcMN_cLm.mjs";
10
10
  import { realpathSync } from "node:fs";
11
11
  import { basename, join } from "node:path";
12
12
  import { workspaceId } from "@stim-cli/core";
@@ -331,11 +331,11 @@ function deviceCapacityRefusal({ platform, project, slot = "default", max, sims
331
331
  * The early `concurrency.maxDevices` check, before Metro starts or a device is created. It is advisory, so an
332
332
  * unknown count passes: `withDeviceBootAdmission` makes the binding decision when the boot starts.
333
333
  */
334
- function checkDeviceCapacity({ platform, project, slot = "default", max, ...sources } = {}) {
334
+ async function checkDeviceCapacity({ platform, project, slot = "default", max, ...sources } = {}) {
335
335
  if (!max || max <= 0) return null;
336
336
  let inventory;
337
337
  try {
338
- inventory = readInventory(sources);
338
+ inventory = await readInventoryAsync(sources);
339
339
  } catch (error) {
340
340
  if ((0, ownership_claim_exports.isClaimRefusal)(error)) return null;
341
341
  throw error;
@@ -349,9 +349,9 @@ function checkDeviceCapacity({ platform, project, slot = "default", max, ...sour
349
349
  ...inventory
350
350
  });
351
351
  }
352
- function peekDeviceSlots({ platform, project, slot = "default", max = getConcurrencyLimits().maxDevices, sources = {} }) {
352
+ async function peekDeviceSlots({ platform, project, slot = "default", max = getConcurrencyLimits().maxDevices, sources = {} }) {
353
353
  try {
354
- const inventory = readInventory(sources);
354
+ const inventory = await readInventoryAsync(sources);
355
355
  if ("code" in inventory) return {
356
356
  count: null,
357
357
  max,