stim 1.19.0 → 1.20.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 (172) hide show
  1. package/README.md +20 -3
  2. package/dist/{activity-BSw0x84R.mjs → activity-BrGh9EAI.mjs} +3 -3
  3. package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-DVyv_hWj.mjs} +7 -7
  4. package/dist/android-0vv-OruW.mjs +6 -0
  5. package/dist/android-Brx6EKvJ.mjs +1258 -0
  6. package/dist/{android-BdQC6zs1.mjs → android-BsYNR81W.mjs} +103 -45
  7. package/dist/{android-DE5g_5gv.mjs → android-CK3fpEyZ.mjs} +2 -2
  8. package/dist/{android-cas-C87geAg-.mjs → android-cas-DCAuXryb.mjs} +9 -5
  9. package/dist/android-cas-compiler.mjs +1 -1
  10. package/dist/api-run.mjs +159 -8
  11. package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
  12. package/dist/api.d.mts +98 -4
  13. package/dist/api.mjs +1 -1
  14. package/dist/{app-install-CFI4ptUL.mjs → app-install-0LgaQRT7.mjs} +9 -8
  15. package/dist/artifact-CnC0mfov.mjs +807 -0
  16. package/dist/artifact-DClXJNWx.mjs +772 -0
  17. package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
  18. package/dist/{browser-web-CDhqQxhv.mjs → browser-web-CzBmhmgs.mjs} +19 -19
  19. package/dist/{budget-Dz-kyXLv.mjs → budget-BONq9vXY.mjs} +3101 -3062
  20. package/dist/build-BixRI6sB.mjs +462 -0
  21. package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
  22. package/dist/build-plan-CP0tckNU.mjs +553 -0
  23. package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{manifest-CX0d1IkZ.mjs → ccache-CjHQ5F8g.mjs} +13 -19
  26. package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
  27. package/dist/{cli-C9Zvgbdc.mjs → cli-B2R8wH1F.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-CuUo8Nvg.mjs → client-BLy1Pw2V.mjs} +89 -307
  30. package/dist/collector-run.d.mts +4 -0
  31. package/dist/collector-run.mjs +7 -7
  32. package/dist/{command-output-Bt8ygHE7.mjs → command-output-BjPN99ZB.mjs} +2 -2
  33. package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
  34. package/dist/{created-devices-D0s26Hx5.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
  35. package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
  36. package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
  37. package/dist/{dev-client-CDY_zAmD.mjs → dev-client-ClATaJoH.mjs} +2 -2
  38. package/dist/{device-BHw0WlHl.mjs → device-B7lsC0K1.mjs} +8 -8
  39. package/dist/device-DVCwAFlX.mjs +727 -0
  40. package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-Ca_ke1LE.mjs} +13 -14
  41. package/dist/device-host-worker.mjs +38 -18
  42. package/dist/device-ios-CRUqPxKw.mjs +413 -0
  43. package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-DHOBXGgS.mjs} +135 -22
  44. package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
  45. package/dist/{device-pool-CP4rAsHx.mjs → device-pool-L2-5GxMy.mjs} +3 -3
  46. package/dist/{device-remote-B5GiUifk.mjs → device-remote-Bmg42063.mjs} +17 -68
  47. package/dist/doctor-C2MSuMMg.mjs +515 -0
  48. package/dist/{doctor-PRJH94v6.mjs → doctor-DPAqhVCK.mjs} +333 -744
  49. package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-CB4NnVZm.mjs} +13 -12
  50. package/dist/{simslim-D9LkJxIO.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
  51. package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
  52. package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
  53. package/dist/errors-DzkMYh8Q.mjs +205 -0
  54. package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
  55. package/dist/{gc-CyHMcKcn.mjs → gc-PWp34zGb.mjs} +21 -20
  56. package/dist/{device-ios-B2ruohE-.mjs → gradle-C2OEKCCI.mjs} +21 -650
  57. package/dist/{guide-dRaQJJk9.mjs → guide-Dai9lphv.mjs} +504 -117
  58. package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
  59. package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client-Io01s5By.mjs} +9 -3
  60. package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
  61. package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
  62. package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
  63. package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-BdAQi21M.mjs} +17 -14
  64. package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
  65. package/dist/{ios-DYUr9LGc.mjs → ios-BZ9dg2Fr.mjs} +8 -7
  66. package/dist/{ios-BWbHFZVz.mjs → ios-CXLIUxXJ.mjs} +180 -24
  67. package/dist/ios-CZuv6gRv.mjs +1112 -0
  68. package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
  69. package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
  70. package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BreZOpM0.mjs} +3 -3
  71. package/dist/ios-project-B9drt_aY.mjs +197 -0
  72. package/dist/{ios-state-By0XuLTQ.mjs → ios-state-CjrL2qv-.mjs} +1 -1
  73. package/dist/js-swap-C8icNYIY.mjs +432 -0
  74. package/dist/launch-DxH0THLP.mjs +745 -0
  75. package/dist/{react-native-ios-CSpIxexZ.mjs → launch-YrbqaIFj.mjs} +59 -612
  76. package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
  77. package/dist/{logs-Bao1HOMy.mjs → logs-DHaRNfg7.mjs} +11 -11
  78. package/dist/macos-C0iljhsN.mjs +2 -0
  79. package/dist/{macos-ciyBdTY5.mjs → macos-V_3Ui7g4.mjs} +42 -50
  80. package/dist/macos-run.mjs +1 -1
  81. package/dist/maintenance-run.mjs +13 -10
  82. package/dist/{metro-DI2AjPF_.mjs → metro-D_j9sN-B.mjs} +18 -5
  83. package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
  84. package/dist/miss-reason-BPAzZS0r.mjs +238 -0
  85. package/dist/{named-ports-B4iWH4E-.mjs → named-ports-C2lvoPsb.mjs} +3 -3
  86. package/dist/native-android-lHzaew7r.mjs +226 -0
  87. package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
  88. package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-BRmWL7ru.mjs} +9 -8
  89. package/dist/native-xcode-inputs-eutS19jU.mjs +307 -0
  90. package/dist/native-xcode-ios-DP3cHLwu.mjs +434 -0
  91. package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
  92. package/dist/offload-worker.d.mts +41 -7
  93. package/dist/offload-worker.mjs +409 -74
  94. package/dist/{ownership-EB0ySdGK.mjs → ownership-DXzMMSx6.mjs} +2 -2
  95. package/dist/{placement-log-Dxe34rJm.mjs → placement-log-reFbjqEr.mjs} +1 -1
  96. package/dist/plan-BDk2AeY_.mjs +260 -0
  97. package/dist/plan-placement-D_YYlE6N.mjs +73 -0
  98. package/dist/{ports-ByPc0_97.mjs → ports-jzvAJXXL.mjs} +3 -3
  99. package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-Bw44QxVh.mjs} +4 -4
  100. package/dist/{preview-BbSottmO.mjs → preview-BaBJ72Al.mjs} +50 -32
  101. package/dist/project-B8_duAzW.mjs +1067 -0
  102. package/dist/project-plan-BPwbLwQu.mjs +10 -0
  103. package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
  104. package/dist/pull-requests.mjs +1 -1
  105. package/dist/react-native-android-chm1DMlA.mjs +921 -0
  106. package/dist/react-native-build-oAw6gQeW.mjs +239 -0
  107. package/dist/react-native-doctor-DYXoh-6I.mjs +78 -0
  108. package/dist/react-native-ios-SCTK_CT5.mjs +595 -0
  109. package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
  110. package/dist/{reload-rAPdqeRR.mjs → reload-D34GkY78.mjs} +17 -13
  111. package/dist/remote-BU9UyhCJ.mjs +192 -0
  112. package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
  113. package/dist/result-BDoRk1k3.mjs +186 -0
  114. package/dist/{run-lAkle1-c.mjs → run-qvff78hv.mjs} +3 -3
  115. package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
  116. package/dist/server-command-7XIKlWtO.mjs +69 -0
  117. package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CsYu2aKL.mjs} +107 -82
  118. package/dist/server-expo-DV43vep4.mjs +2 -0
  119. package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
  120. package/dist/{settings-2am7TSxp.mjs → settings-CT3E71-i.mjs} +6 -6
  121. package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
  122. package/dist/settings.schema.json +84 -0
  123. package/dist/simslim-ChMfe8rg.mjs +149 -0
  124. package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-B9hn96wd.mjs} +6 -6
  125. package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
  126. package/dist/start-CbQCSnXQ.mjs +2 -0
  127. package/dist/{start-DtxthMfI.mjs → start-CdvcTaXr.mjs} +97 -68
  128. package/dist/{state-Tp4uImDS.mjs → state-Boo0IMJq.mjs} +1 -1
  129. package/dist/{state-D2KtnALG.mjs → state-DI84A-uu.mjs} +29 -10
  130. package/dist/{stats-8EJ5ivFT.mjs → stats-BIIDrjA8.mjs} +5 -5
  131. package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
  132. package/dist/{status-BOyp0CUl.mjs → status-DARMkc9q.mjs} +81 -293
  133. package/dist/status-watch-DvmI3SmN.mjs +296 -0
  134. package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
  135. package/dist/{stop-DRipAg-e.mjs → stop-CCZS-C9m.mjs} +2 -2
  136. package/dist/{stop-D0UIpZuh.mjs → stop-WQPQHLuy.mjs} +5 -5
  137. package/dist/{stop-zDlknFoz.mjs → stop-iNemHsJC.mjs} +21 -20
  138. package/dist/supervisor-run.d.mts +7 -2
  139. package/dist/supervisor-run.mjs +32 -20
  140. package/dist/{support-DsNaFg6D.mjs → support-CnE_SIjt.mjs} +17 -7
  141. package/dist/{support-CNqYkV0y.mjs → support-DCco5fut.mjs} +61 -8
  142. package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-afeNUExW.mjs} +5 -5
  143. package/dist/tailnet-CoJUb2tB.mjs +265 -0
  144. package/dist/toolchain-BIupIro1.mjs +2 -0
  145. package/dist/{toolchain-C3xSoyUl.mjs → toolchain-DqyDXs30.mjs} +206 -53
  146. package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
  147. package/dist/trigger-SHLOWJ4O.mjs +2 -0
  148. package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-C3ASD6z5.mjs} +6 -6
  149. package/dist/{watchman-BL1IdOtq.mjs → watchman-CQl51YZu.mjs} +6 -6
  150. package/dist/{web-DbbrPUn0.mjs → web-B3eldHFH.mjs} +9 -13
  151. package/dist/web-BLXpOe6b.mjs +2 -0
  152. package/dist/web-run.mjs +10 -10
  153. package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
  154. package/dist/{workspaces-Djb2gfi9.mjs → workspaces-D2xSHBDY.mjs} +1260 -1258
  155. package/dist/{worktree-BL4M1rhB.mjs → worktree-BxDqaTev.mjs} +84 -48
  156. package/dist/worktree-q7_OZNY0.mjs +2 -0
  157. package/package.json +8 -6
  158. package/shim/native-android.gradle +101 -0
  159. package/dist/android-BXc6BmEi.mjs +0 -3732
  160. package/dist/android-BvV1gGdN.mjs +0 -4
  161. package/dist/ios-ITYno9rO.mjs +0 -2241
  162. package/dist/macos-nIOATJmR.mjs +0 -2
  163. package/dist/metro-store-BAHFcJm6.mjs +0 -106
  164. package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
  165. package/dist/plan-placement-BVY59qa8.mjs +0 -290
  166. package/dist/project-B5eQ1USs.mjs +0 -612
  167. package/dist/react-native-ios-BMh2i25I.mjs +0 -2
  168. package/dist/server-expo-DGsdUGX2.mjs +0 -2
  169. package/dist/start-D8NbxNBb.mjs +0 -2
  170. package/dist/trigger-CoalsMTV.mjs +0 -2
  171. package/dist/web-DFpFeZu5.mjs +0 -2
  172. package/dist/worktree-DV-A0LNL.mjs +0 -2
@@ -1,15 +1,15 @@
1
1
  import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { a as formatElapsed, l as phaseLine } from "./command-output-Bt8ygHE7.mjs";
3
- import { H as projectDeviceSlots, _ as loadConfig$1, d as getConfigDir, u as getConcurrencyLimits, z as deviceSlotPlatforms } from "./config-DC5jEtd1.mjs";
4
- import { x as workspaceLogsDir$1 } from "./workspace-state-CR9X86xJ.mjs";
5
- import { E as projectDeviceReclaimIdleMinutes } from "./settings-CxgngUZk.mjs";
6
- import { H as recordCapacityWait, V as recordCapacityRefusal } from "./budget-Dz-kyXLv.mjs";
7
- import { L as canonicalPath, f as withIdleWorkspace } from "./workspaces-Djb2gfi9.mjs";
8
- import { O as listAdbDevices } from "./android-BdQC6zs1.mjs";
9
- import { d as listAllIosSims, l as iosRuntimeMatches, v as parseRuntimeVersion } from "./ios-BWbHFZVz.mjs";
10
- import { a as withWorkspaceProcessLock, o as workspaceProcessLockError } from "./named-ports-B4iWH4E-.mjs";
11
- import { r as createNdjsonWriter } from "./ndjson-LGZAMsqa.mjs";
12
- import { n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-DYiMBn34.mjs";
2
+ import { H as projectDeviceSlots, _ as loadConfig$1, d as getConfigDir, u as getConcurrencyLimits, z as deviceSlotPlatforms } from "./config-D0LhTY3S.mjs";
3
+ import { g as deviceReclaimIdleMinutesSetting } from "./settings-Bbztm4oV.mjs";
4
+ import { w as workspaceLogsDir$1 } from "./workspace-state-CSIFuuDa.mjs";
5
+ import { a as formatElapsed, l as phaseLine } from "./command-output-BjPN99ZB.mjs";
6
+ import { O as listAdbDevices } from "./android-BsYNR81W.mjs";
7
+ import { T as canonicalPath, f as withIdleWorkspace } from "./workspaces-D2xSHBDY.mjs";
8
+ import { Nt as recordCapacityRefusal, Pt as recordCapacityWait } from "./budget-BONq9vXY.mjs";
9
+ import { a as withWorkspaceProcessLock, o as workspaceProcessLockError } from "./named-ports-C2lvoPsb.mjs";
10
+ import { r as createNdjsonWriter } from "./ndjson-GOnbyvso.mjs";
11
+ import { d as listAllIosSims, l as iosRuntimeMatches, y as parseRuntimeVersion } from "./ios-CXLIUxXJ.mjs";
12
+ import { n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-DdMqoSUB.mjs";
13
13
  import { realpathSync } from "node:fs";
14
14
  import { basename, join } from "node:path";
15
15
  import { DEVICE_RECLAIM_REASON, automaticMachineEnabled } from "@stim-cli/core/state";
@@ -373,7 +373,7 @@ async function admissionTransaction(action, lockWaitMs, out, signal) {
373
373
  }
374
374
  }
375
375
  /** Boots an owned device under the Stim home's cap, reserving capacity before releasing admission. */
376
- async function withDeviceBootAdmission(device, boot, { root, max = getConcurrencyLimits().maxDevices, sources = {}, lockWaitMs = ADMISSION_LOCK_WAIT_MS, out = () => {}, waitMs = DEFAULT_DEVICE_SLOT_WAIT_MS, noWait = false, automatic = false, displayName = basename(root), now = Date.now, signal, sleep = (ms) => setTimeout(ms, void 0, { signal }), waitingFor = () => {}, onWait = () => {} }) {
376
+ async function withDeviceBootAdmission(device, boot, { root, max = getConcurrencyLimits().maxDevices, sources = {}, lockWaitMs = ADMISSION_LOCK_WAIT_MS, out = () => {}, waitMs = DEFAULT_DEVICE_SLOT_WAIT_MS, noWait = false, automatic = false, displayName = basename(root), reclaimIdleMinutes = deviceReclaimIdleMinutesSetting({}), now = Date.now, signal, sleep = (ms) => setTimeout(ms, void 0, { signal }), waitingFor = () => {}, onWait = () => {} }) {
377
377
  const requireMembership = () => {
378
378
  if (automatic && !automaticMachineEnabled("device", "local")) throw new DeviceAdmissionRefusal({
379
379
  code: "STIM_HOSTING_REFUSED",
@@ -488,8 +488,7 @@ async function withDeviceBootAdmission(device, boot, { root, max = getConcurrenc
488
488
  if (result.reclaim && now() - lastReclaim >= 15e3) {
489
489
  lastReclaim = now();
490
490
  try {
491
- const minutes = projectDeviceReclaimIdleMinutes(canonicalPath(root));
492
- if (minutes > 0) reclaimed += await reclaimIdleDevice(root, minutes * 6e4, out, now, skippedReclaims);
491
+ if (reclaimIdleMinutes > 0) reclaimed += await reclaimIdleDevice(root, reclaimIdleMinutes * 6e4, out, now, skippedReclaims);
493
492
  } catch (error) {
494
493
  out(phaseLine("device", `could not reclaim an idle device: ${error?.message || error}`));
495
494
  }
@@ -1,26 +1,26 @@
1
1
  import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
3
3
  import { t as spawnEntry } from "./spawn-entry-Dcb7sDUz.mjs";
4
- import { D as withConfigLock$1, _ as loadConfig$1, c as ensureConfig } from "./config-DC5jEtd1.mjs";
5
- import { c as writeWorkspaceState, u as ensureWorkspaceStorage } from "./workspace-state-CR9X86xJ.mjs";
6
- import { D as teardownOwnedAvd, k as teardownOwnedIosSim } from "./workspaces-Djb2gfi9.mjs";
7
- import { t as forgetCreatedDevice } from "./created-devices-D0s26Hx5.mjs";
8
- import { A as listAvds, B as ownedAvdSystemImage, D as hostSystemImageArch, E as getAvdNameForSerial, J as resolveOwnedAvdSerial, O as listAdbDevices, R as ownedAvdName, W as pickDefaultSystemImage, _ as avdStorageRoots, a as androidDeviceAbi, b as createOwnedAvd, d as androidToolPath, f as assertOwnedAvdStopped, h as avdPathExists, j as listInstalledSystemImages, k as listAvdDeviceProfiles, q as resetAdoptedAvd, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, v as bootAndroidEmulator } from "./android-BdQC6zs1.mjs";
9
- import { C as resetIosPrivacy, M as readHostMemoryPressure, O as uninstallIosApp, S as resetIosKeychain, a as createOwnedIosSim, d as listAllIosSims, h as listUserApps, n as bootIosSim, w as resolveIosCreation } from "./ios-BWbHFZVz.mjs";
10
- import { i as macosProcess, o as requiredMacosRecord } from "./state-Tp4uImDS.mjs";
11
- import { r as createNdjsonWriter } from "./ndjson-LGZAMsqa.mjs";
12
- import { i as countLiveOwnedDevices } from "./device-capacity-BoN1jQkO.mjs";
13
- import { C as reverseMetroPorts, _ as installIosApp, b as launchAndroidReleaseApp, h as installAndroidApp, s as androidAppProcess, v as iosAppProcess, w as writeDebugHttpHost, x as launchIosApp, y as launchAndroidApp } from "./app-install-CFI4ptUL.mjs";
14
- import { h as findAapt } from "./support-DsNaFg6D.mjs";
15
- import { n as parseLogcatLine, r as parsePidof, t as androidClockOffset } from "./android-DE5g_5gv.mjs";
16
- import { r as stopMacosAppHeld } from "./stop-D0UIpZuh.mjs";
17
- import { n as parseLogStreamLine } from "./ios-DCrkgXEM.mjs";
4
+ import { D as withConfigLock$1, _ as loadConfig$1, c as ensureConfig } from "./config-D0LhTY3S.mjs";
5
+ import { c as writeWorkspaceState, p as ensureWorkspaceStorage } from "./workspace-state-CSIFuuDa.mjs";
6
+ import { A as listAvds, B as ownedAvdSystemImage, D as hostSystemImageArch, E as getAvdNameForSerial, J as resolveOwnedAvdSerial, O as listAdbDevices, R as ownedAvdName, W as pickDefaultSystemImage, _ as avdStorageRoots, a as androidDeviceAbi, b as createOwnedAvd, d as androidToolPath, f as assertOwnedAvdStopped, h as avdPathExists, j as listInstalledSystemImages, k as listAvdDeviceProfiles, q as resetAdoptedAvd, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, v as bootAndroidEmulator } from "./android-BsYNR81W.mjs";
7
+ import { t as forgetCreatedDevice } from "./created-devices-HU_DAb_Q.mjs";
8
+ import { b as teardownOwnedIosSim, v as teardownOwnedAvd } from "./workspaces-D2xSHBDY.mjs";
9
+ import { r as createNdjsonWriter } from "./ndjson-GOnbyvso.mjs";
10
+ import { C as resetIosKeychain, P as readHostMemoryPressure, T as resolveIosCreation, a as createOwnedIosSim, d as listAllIosSims, g as listUserApps, k as uninstallIosApp, n as bootIosSim, w as resetIosPrivacy } from "./ios-CXLIUxXJ.mjs";
11
+ import { i as macosProcess, o as requiredMacosRecord } from "./state-Boo0IMJq.mjs";
12
+ import { C as reverseMetroPorts, _ as installIosApp, b as launchAndroidReleaseApp, h as installAndroidApp, s as androidAppProcess, v as iosAppProcess, w as writeDebugHttpHost, x as launchIosApp, y as launchAndroidApp } from "./app-install-0LgaQRT7.mjs";
13
+ import { i as countLiveOwnedDevices } from "./device-capacity-Ca_ke1LE.mjs";
14
+ import { _ as findAapt } from "./support-CnE_SIjt.mjs";
15
+ import { n as parseLogcatLine, r as parsePidof, t as androidClockOffset } from "./android-CK3fpEyZ.mjs";
16
+ import { r as stopMacosAppHeld } from "./stop-WQPQHLuy.mjs";
17
+ import { n as parseLogStreamLine } from "./ios-VGvNdsv2.mjs";
18
18
  import { chmodSync, closeSync, copyFileSync, createReadStream, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statfsSync, symlinkSync, writeFileSync } from "node:fs";
19
19
  import { dirname, isAbsolute, join, posix, relative, sep } from "node:path";
20
20
  import { assertHostedDeviceLedger, hostedAppArea, hostedAppAttempt, hostedAppBlobs, hostedConsolePort, hostedMacosAppSlot, hostedMacosBundleId, hostedNativeLogsDir, isJsonObject, parseHostedOfferRequest, readHostedApp, readHostedAppMetadata, readHostedDevice, readHostedNativeLogsCheckpoint, readMacosRecord, readNdjsonGenerations } from "@stim-cli/core/state";
21
- import { availableParallelism, freemem, homedir, loadavg } from "node:os";
22
21
  import { LOG_ROTATE_BYTES, configDir, withDirLock } from "@stim-cli/core";
23
22
  import { createHash, randomUUID } from "node:crypto";
23
+ import { availableParallelism, freemem, homedir, loadavg } from "node:os";
24
24
  //#region src/device-host/android-app.ts
25
25
  async function digest$1(path) {
26
26
  const hash = createHash("sha256");
@@ -747,7 +747,17 @@ async function runHostedAndroidDevice(mode, request, app) {
747
747
  openViewer: false,
748
748
  logFile: join(home, "emulator.log")
749
749
  });
750
- if (!(await waitForBoot(selected.serial, 24e4, { commandTimeoutMs: 5e3 })).ok || getAvdNameForSerial(selected.serial) !== avdName || androidDeviceAbi(selected.serial) !== selected.architecture) throw new Error("Hosted Android boot could not be verified for its exact owned AVD.");
750
+ const boot = await waitForBoot(selected.serial, 24e4, { commandTimeoutMs: 5e3 });
751
+ if (!boot.ok) {
752
+ const { sysBoot, devBoot, bootAnim, packageManager } = boot.diagnostic ?? {};
753
+ throw new Error(`Hosted Android boot could not be verified for its exact owned AVD. Diagnostic: ${JSON.stringify({
754
+ sysBoot,
755
+ devBoot,
756
+ bootAnim,
757
+ packageManager
758
+ })}`);
759
+ }
760
+ if (getAvdNameForSerial(selected.serial) !== avdName || androidDeviceAbi(selected.serial) !== selected.architecture) throw new Error("Hosted Android boot could not be verified for its exact owned AVD.");
751
761
  return {
752
762
  state: "ready",
753
763
  device: selected
@@ -798,7 +808,17 @@ async function runHostedAndroidDevice(mode, request, app) {
798
808
  openViewer: false,
799
809
  logFile: join(home, "emulator.log")
800
810
  });
801
- if (!(await waitForBoot(device.serial, 24e4, { commandTimeoutMs: 5e3 })).ok || getAvdNameForSerial(device.serial) !== device.avdName || androidDeviceAbi(device.serial) !== device.architecture) throw new Error("Hosted Android boot could not be verified for its exact owned AVD.");
811
+ const boot = await waitForBoot(device.serial, 24e4, { commandTimeoutMs: 5e3 });
812
+ if (!boot.ok) {
813
+ const { sysBoot, devBoot, bootAnim, packageManager } = boot.diagnostic ?? {};
814
+ throw new Error(`Hosted Android boot could not be verified for its exact owned AVD. Diagnostic: ${JSON.stringify({
815
+ sysBoot,
816
+ devBoot,
817
+ bootAnim,
818
+ packageManager
819
+ })}`);
820
+ }
821
+ if (getAvdNameForSerial(device.serial) !== device.avdName || androidDeviceAbi(device.serial) !== device.architecture) throw new Error("Hosted Android boot could not be verified for its exact owned AVD.");
802
822
  await resetAdoptedAvd(device.avdName, device.serial, "");
803
823
  removeHostedAppData(home, { keepBlobs: true });
804
824
  return {
@@ -0,0 +1,413 @@
1
+ import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
2
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
3
+ import { C as saveConfig, D as withConfigLock, H as projectDeviceSlots, _ as loadConfig, a as clearDevice, d as getConfigDir, w as setDevice, z as deviceSlotPlatforms } from "./config-D0LhTY3S.mjs";
4
+ import { T as iosSimSlimProfileSetting } from "./settings-Bbztm4oV.mjs";
5
+ import { S as workspaceId } from "./workspace-state-CSIFuuDa.mjs";
6
+ import { l as phaseLine } from "./command-output-BjPN99ZB.mjs";
7
+ import { dt as parkedMaxSetting, ft as readParked, mt as selectParked, ot as adoptParked, st as dropParked } from "./android-BsYNR81W.mjs";
8
+ import { S as teardownParkedIosSim } from "./workspaces-D2xSHBDY.mjs";
9
+ import { a as withWorkspaceProcessLock } from "./named-ports-C2lvoPsb.mjs";
10
+ import { A as configuredIosSimulatorViewer, C as resetIosKeychain, E as resolveOwnedIosSim, M as hostMemoryPressureAdvice, N as memoryCulpritsUnder, P as readHostMemoryPressure, S as renameIosSim, T as resolveIosCreation, _ as ownedSimName, a as createOwnedIosSim, d as listAllIosSims, m as listIosRuntimes, n as bootIosSim, p as listIosDeviceTypes, u as iosSimulatorFailureAdvice, w as resetIosPrivacy, y as parseRuntimeVersion } from "./ios-CXLIUxXJ.mjs";
11
+ import { a as deviceTypeMismatch, c as runtimeMismatch, n as DeviceAdmissionRefusal, p as withDeviceBootAdmission } from "./device-capacity-Ca_ke1LE.mjs";
12
+ import chalk from "chalk";
13
+ //#region src/engine/device-ios.ts
14
+ function startIosBoot(udid, configure, label, out, simulatorApp, root, deviceSlotWait) {
15
+ const done = withDeviceBootAdmission({
16
+ platform: "ios",
17
+ key: udid
18
+ }, async () => {
19
+ out(chalk.dim(phaseLine("device", `booting ${label} (${udid})`)));
20
+ await bootIosSim(udid, {
21
+ label,
22
+ out,
23
+ simulatorApp
24
+ });
25
+ await configure();
26
+ }, {
27
+ ...deviceSlotWait,
28
+ root,
29
+ out
30
+ });
31
+ done.catch(() => {});
32
+ return {
33
+ udid,
34
+ done
35
+ };
36
+ }
37
+ var IosDeviceMismatchError = class extends Error {
38
+ remedy = "Run `stim worktree remove` (or `stim gc --delete`) to reap the current sim, then `stim ios` again to create the requested one, or pass `--slot <name>` to create it beside the current one.";
39
+ };
40
+ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, label, settings, flags, note, out, reconcileIosSimulator, simSnapshot }) {
41
+ const pressure = readHostMemoryPressure();
42
+ const memoryAdvice = hostMemoryPressureAdvice(pressure, memoryCulpritsUnder(pressure));
43
+ if (memoryAdvice) out(chalk.yellow(phaseLine("memory", memoryAdvice)));
44
+ const simslimProfile = iosSimSlimProfileSetting(settings, settingsRoot);
45
+ if (record?.deviceUdid) {
46
+ if (record.owned) {
47
+ const listed = simSnapshot ? simSnapshot.read() : listAllIosSims({ includeUnavailable: true });
48
+ const resolved = resolveOwnedIosSim(record.deviceUdid, listed);
49
+ if (resolved.notOwned) note(chalk.yellow(`Note: recorded sim is now named "${resolved.notOwned}", not Stim-owned -- creating a fresh owned sim instead of booting it.`));
50
+ else if (resolved.missing) {} else {
51
+ const sim = resolved.sim;
52
+ const wantedType = flags.deviceType || settings?.ios?.deviceType;
53
+ const deviceTypes = listIosDeviceTypes();
54
+ const mismatch = deviceTypeMismatch(sim.deviceTypeIdentifier, wantedType, deviceTypes);
55
+ if (mismatch) throw new IosDeviceMismatchError(`${mismatch}. Stim will not silently boot a different model.`);
56
+ const versionMismatch = flags.runtimeFlag ? runtimeMismatch(sim.runtime, flags.runtimeFlag, listIosRuntimes()) : null;
57
+ if (versionMismatch) throw new IosDeviceMismatchError(`${versionMismatch}. Stim will not silently boot a different iOS version.`);
58
+ const model = {
59
+ model: deviceTypes.find((d) => d.identifier === sim.deviceTypeIdentifier)?.name ?? null,
60
+ runtime: parseRuntimeVersion(sim.runtime)
61
+ };
62
+ const name = ownedIosName(sim, label, model, projectPath, listed) === sim.name ? sim.name : await withIosDeviceNameLock(() => renameToOwnedName(sim, label, model, projectPath));
63
+ const updated = {
64
+ deviceUdid: sim.udid,
65
+ owned: true,
66
+ deviceName: name,
67
+ ...record.simslimManaged ? { simslimManaged: true } : {},
68
+ ...record.adopted ? { adopted: true } : {},
69
+ ...record.adoptionPending ? { adoptionPending: true } : {},
70
+ ...record.parkedCacheKey ? { parkedCacheKey: record.parkedCacheKey } : {},
71
+ ...record.schemeApprovals ? { schemeApprovals: record.schemeApprovals } : {}
72
+ };
73
+ const configure = async () => {
74
+ if (record.adoptionPending) resetAdoptedSim(sim.udid, out);
75
+ return configureOwnedIosSim({
76
+ record: updated,
77
+ projectPath,
78
+ slot,
79
+ profile: simslimProfile,
80
+ out,
81
+ reconcileIosSimulator
82
+ });
83
+ };
84
+ const facts = {
85
+ deviceType: model.model,
86
+ runtime: model.runtime
87
+ };
88
+ if (sim.state !== "Booted") return {
89
+ ...updated,
90
+ booting: startIosBoot(sim.udid, configure, name, out, flags.simulatorApp, projectPath, flags.deviceSlotWait),
91
+ ...facts
92
+ };
93
+ return {
94
+ ...await configure(),
95
+ ...facts,
96
+ booted: sim.udid
97
+ };
98
+ }
99
+ } else {
100
+ const sim = listAllIosSims().find((s) => s.udid === record.deviceUdid);
101
+ if (sim) {
102
+ if (sim.state !== "Booted") {
103
+ note(chalk.yellow(`Note: assigned sim ${sim.name} (${sim.udid}) is shut down and is not owned by Stim, so it will not be booted automatically.`));
104
+ note(chalk.dim("Boot it yourself, or run `stim gc --delete` to clear the assignment so Stim can create an owned sim."));
105
+ }
106
+ return record;
107
+ }
108
+ }
109
+ withConfigLock(() => {
110
+ const current = deviceSlotPlatforms(loadConfig()?.projects?.[projectPath], slot)?.ios;
111
+ if (!current) return;
112
+ if (current.deviceUdid !== record.deviceUdid || current.owned !== record.owned) throw new Error("The simulator assignment changed during recovery. Run `stim ios` again.");
113
+ clearDevice(projectPath, "ios", slot);
114
+ });
115
+ }
116
+ const choice = resolveIosCreation({
117
+ deviceType: flags.deviceType || settings.ios?.deviceType,
118
+ runtime: flags.runtime || settings.ios?.runtime
119
+ });
120
+ const adopted = parkedMaxSetting("ios").max > 0 ? await withIosDeviceNameLock(() => takeParkedIosSim({
121
+ projectPath,
122
+ slot,
123
+ label,
124
+ choice,
125
+ out
126
+ })) : null;
127
+ if (adopted) {
128
+ const booting = startIosBoot(adopted.deviceUdid, async () => {
129
+ resetAdoptedSim(adopted.deviceUdid, out);
130
+ await configureOwnedIosSim({
131
+ record: adopted,
132
+ projectPath,
133
+ slot,
134
+ profile: simslimProfile,
135
+ out,
136
+ reconcileIosSimulator
137
+ });
138
+ }, adopted.deviceName, out, flags.simulatorApp, projectPath, flags.deviceSlotWait);
139
+ return {
140
+ ...adopted,
141
+ booting,
142
+ deviceType: choice.deviceType,
143
+ runtime: choice.runtime
144
+ };
145
+ }
146
+ const created = await withIosDeviceNameLock(() => {
147
+ const suffix = ownedIosNameSuffix(label, {
148
+ model: choice.deviceType,
149
+ runtime: choice.runtime
150
+ }, projectPath);
151
+ const result = createOwnedIosSim(label, { suffix }, choice);
152
+ setDevice(projectPath, "ios", {
153
+ deviceUdid: result.udid,
154
+ owned: true,
155
+ deviceName: result.name
156
+ }, slot);
157
+ return result;
158
+ });
159
+ const newRecord = {
160
+ deviceUdid: created.udid,
161
+ owned: true,
162
+ deviceName: created.name
163
+ };
164
+ const booting = startIosBoot(created.udid, () => configureOwnedIosSim({
165
+ record: newRecord,
166
+ projectPath,
167
+ slot,
168
+ profile: simslimProfile,
169
+ out,
170
+ reconcileIosSimulator
171
+ }), created.name, out, flags.simulatorApp, projectPath, flags.deviceSlotWait);
172
+ return {
173
+ ...newRecord,
174
+ created: true,
175
+ booting,
176
+ deviceType: created.deviceType,
177
+ runtime: created.runtime
178
+ };
179
+ }
180
+ function withIosDeviceNameLock(fn) {
181
+ return withWorkspaceProcessLock(getConfigDir(), "ios-device-names", async () => fn(), { external: true });
182
+ }
183
+ function ownedIosNameSuffix(label, model, projectPath, udid, listed = listAllIosSims({ includeUnavailable: true })) {
184
+ const names = new Set(listed.filter((sim) => sim.udid !== udid).map((sim) => sim.name));
185
+ for (const project of Object.values(loadConfig()?.projects ?? {})) for (const { platforms } of projectDeviceSlots(project)) {
186
+ const record = platforms.ios;
187
+ if (record?.deviceUdid !== udid && record?.deviceName) names.add(record.deviceName);
188
+ }
189
+ for (const parked of readParked("ios")) if (parked.udid !== udid) names.add(parked.name);
190
+ let suffix = "";
191
+ for (let attempt = 0; names.has(ownedSimName(label, model, suffix)); attempt++) suffix = ` ${workspaceId(projectPath)}${attempt ? `-${attempt}` : ""}`;
192
+ return suffix;
193
+ }
194
+ function ownedIosName(sim, label, model, projectPath, listed) {
195
+ return ownedSimName(label, model, ownedIosNameSuffix(label, model, projectPath, sim.udid, listed));
196
+ }
197
+ function renameToOwnedName(sim, label, model, projectPath) {
198
+ const wanted = ownedIosName(sim, label, model, projectPath);
199
+ if (sim.name === wanted) return wanted;
200
+ try {
201
+ renameIosSim(sim.udid, wanted);
202
+ return wanted;
203
+ } catch {
204
+ return sim.name;
205
+ }
206
+ }
207
+ function resetAdoptedSim(udid, out) {
208
+ out(chalk.dim(phaseLine("device", `resetting privacy grants and the keychain on ${udid}`)));
209
+ resetIosPrivacy(udid);
210
+ resetIosKeychain(udid);
211
+ }
212
+ function takeParkedIosSim({ projectPath, slot, label, choice, out }) {
213
+ const candidates = selectParked(readParked("ios"), {
214
+ deviceTypeIdentifier: choice.deviceTypeId,
215
+ runtimeIdentifier: choice.runtimeId
216
+ });
217
+ if (candidates.length === 0) return null;
218
+ const listed = new Map(listAllIosSims({ includeUnavailable: true }).map((sim) => [sim.udid, sim]));
219
+ for (const parked of candidates) {
220
+ const sim = listed.get(parked.udid);
221
+ if (!sim || !sim.available) {
222
+ const result = sim ? teardownParkedIosSim(parked.udid, { label: parked.name }) : null;
223
+ if (sim ? result?.status === "torn-down" : dropParked("ios", parked.udid)) out(chalk.dim(phaseLine("device", `deleted parked ${parked.name} (${parked.udid}): ${sim ? "unavailable" : "gone"}`)));
224
+ else if (result?.status === "failed") out(chalk.yellow(phaseLine("device", `could not delete unavailable parked ${parked.name} (${parked.udid}): ${result.reason}`)));
225
+ continue;
226
+ }
227
+ if (!sim.name.startsWith("stim-")) {
228
+ out(chalk.yellow(phaseLine("device", `kept parked record for ${parked.udid}: simulator is now named ${JSON.stringify(sim.name)} and is not Stim-owned`)));
229
+ continue;
230
+ }
231
+ const model = {
232
+ model: choice.deviceType,
233
+ runtime: choice.runtime
234
+ };
235
+ const name = ownedSimName(label, model, ownedIosNameSuffix(label, model, projectPath, parked.udid));
236
+ const device = {
237
+ deviceUdid: parked.udid,
238
+ owned: true,
239
+ deviceName: name,
240
+ adopted: true,
241
+ adoptionPending: true,
242
+ ...parked.simslimManaged ? { simslimManaged: true } : {},
243
+ ...parked.cacheKey ? { parkedCacheKey: parked.cacheKey } : {}
244
+ };
245
+ const adopted = adoptParked({
246
+ platform: "ios",
247
+ projectPath,
248
+ slot,
249
+ udid: parked.udid,
250
+ device
251
+ });
252
+ if (!adopted) continue;
253
+ try {
254
+ renameIosSim(parked.udid, name);
255
+ } catch {}
256
+ return adopted.schemeApprovals && adopted.schemeApprovals.length > 0 ? {
257
+ ...device,
258
+ schemeApprovals: adopted.schemeApprovals
259
+ } : device;
260
+ }
261
+ return null;
262
+ }
263
+ function clearIosAdoptionPending(projectPath, slot = "default") {
264
+ withConfigLock(() => {
265
+ const cfg = loadConfig();
266
+ const ios = deviceSlotPlatforms(cfg?.projects?.[projectPath], slot)?.ios;
267
+ if (!cfg || !ios?.adoptionPending) return;
268
+ delete ios.adopted;
269
+ delete ios.adoptionPending;
270
+ delete ios.parkedCacheKey;
271
+ saveConfig(cfg);
272
+ });
273
+ }
274
+ async function configureOwnedIosSim({ record, projectPath, slot, profile, out, reconcileIosSimulator }) {
275
+ if (profile) out(chalk.dim(phaseLine("device", `applying the SimSlim profile to ${record.deviceUdid}`)));
276
+ else if (record.simslimManaged) out(chalk.dim(phaseLine("device", `restoring stock simulator services on ${record.deviceUdid}`)));
277
+ const previouslyManaged = Boolean(record.simslimManaged);
278
+ if (profile && !record.simslimManaged) {
279
+ const pending = {
280
+ ...record,
281
+ simslimManaged: true
282
+ };
283
+ setDevice(projectPath, "ios", pending, slot);
284
+ record = pending;
285
+ }
286
+ const result = await reconcileIosSimulator({
287
+ udid: record.deviceUdid,
288
+ profile,
289
+ previouslyManaged,
290
+ out
291
+ });
292
+ const updated = { ...record };
293
+ if (result.managed) updated.simslimManaged = true;
294
+ else delete updated.simslimManaged;
295
+ setDevice(projectPath, "ios", updated, slot);
296
+ return updated;
297
+ }
298
+ async function ensureIosBooted({ device, projectPath, deviceSlotWait, simulatorApp, timeoutMs, pollMs, out }) {
299
+ const udid = device?.deviceUdid;
300
+ if (!udid) return {
301
+ failed: true,
302
+ reason: "No iOS simulator is recorded for this project."
303
+ };
304
+ const ready = () => {
305
+ try {
306
+ getExecutor().runFile("xcrun", [
307
+ "simctl",
308
+ "spawn",
309
+ udid,
310
+ "launchctl",
311
+ "list"
312
+ ], { timeoutMs: 3e4 });
313
+ return {
314
+ ok: true,
315
+ udid
316
+ };
317
+ } catch (error) {
318
+ return {
319
+ failed: true,
320
+ reason: `Simulator ${udid} failed its process-spawn readiness check: ${error?.message || error}. ${iosSimulatorFailureAdvice()}`
321
+ };
322
+ }
323
+ };
324
+ const booting = device?.booting;
325
+ if (booting?.udid === udid) {
326
+ try {
327
+ await booting.done;
328
+ } catch (e) {
329
+ return bootFailure(udid, e);
330
+ }
331
+ return ready();
332
+ }
333
+ const readiness = device?.booted === udid ? ready() : null;
334
+ if (readiness?.ok) {
335
+ if (simulatorApp !== void 0) configuredIosSimulatorViewer(simulatorApp).open(udid);
336
+ return readiness;
337
+ }
338
+ let resolved;
339
+ try {
340
+ resolved = resolveOwnedIosSim(udid);
341
+ } catch (e) {
342
+ return {
343
+ failed: true,
344
+ reason: `Could not list simulators: ${e?.message || e}`
345
+ };
346
+ }
347
+ if (resolved.missing) return {
348
+ failed: true,
349
+ reason: `Simulator ${udid} no longer exists. Run \`stim ios\` again to create a fresh owned sim.`
350
+ };
351
+ if (resolved.notOwned) return {
352
+ failed: true,
353
+ reason: `Simulator ${udid} is now named "${resolved.notOwned}" and is not Stim-owned; refusing to boot it.`
354
+ };
355
+ const sim = resolved.sim;
356
+ if (sim.state === "Booted") {
357
+ const result = readiness ?? ready();
358
+ if (result.ok && simulatorApp !== void 0) configuredIosSimulatorViewer(simulatorApp).open(udid);
359
+ return result;
360
+ }
361
+ const bootDeadline = Date.now() + timeoutMs;
362
+ try {
363
+ await withDeviceBootAdmission({
364
+ platform: "ios",
365
+ key: udid
366
+ }, () => {
367
+ out(chalk.dim(phaseLine("device", `booting ${sim.name} (${udid})`)));
368
+ return bootIosSim(udid, {
369
+ timeoutMs,
370
+ label: sim.name,
371
+ out,
372
+ simulatorApp
373
+ });
374
+ }, {
375
+ ...deviceSlotWait,
376
+ root: projectPath,
377
+ out
378
+ });
379
+ } catch (e) {
380
+ return bootFailure(udid, e);
381
+ }
382
+ const deadline = Math.max(bootDeadline, Date.now() + 2 * pollMs);
383
+ while (Date.now() < deadline) {
384
+ await sleep(pollMs);
385
+ let state = null;
386
+ try {
387
+ state = listAllIosSims({ timeoutMs: 3e4 }).find((s) => s.udid === udid)?.state ?? null;
388
+ } catch {}
389
+ if (state === "Booted") return ready();
390
+ }
391
+ return {
392
+ failed: true,
393
+ reason: `Simulator ${udid} did not reach the Booted state within ${Math.round(timeoutMs / 1e3)}s.`
394
+ };
395
+ }
396
+ function bootFailure(udid, error) {
397
+ const refusal = error instanceof DeviceAdmissionRefusal ? error : (0, ownership_claim_exports.claimFailure)(error, "stim ios");
398
+ if (refusal) return {
399
+ failed: true,
400
+ code: refusal.code,
401
+ reason: refusal.message,
402
+ remedy: refusal.remedy
403
+ };
404
+ return {
405
+ failed: true,
406
+ reason: `Could not boot simulator ${udid}: ${error?.message || error}`
407
+ };
408
+ }
409
+ function sleep(ms) {
410
+ return new Promise((r) => setTimeout(r, ms));
411
+ }
412
+ //#endregion
413
+ export { ensureOwnedIosDevice as i, clearIosAdoptionPending as n, ensureIosBooted as r, IosDeviceMismatchError as t };