stim 1.23.1 → 1.25.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 (174) hide show
  1. package/README.md +3 -2
  2. package/dist/{acquire-artifact-BzYRDgaP.mjs → acquire-artifact-zA4S7RHE.mjs} +2 -2
  3. package/dist/{act-vxiMwdf5.mjs → act-BbHS3oV8.mjs} +41 -26
  4. package/dist/{activity-BpWUPgUm.mjs → activity-BpjwrQXU.mjs} +6 -6
  5. package/dist/{agent-device-usage-output-CUlLsbRt.mjs → agent-device-usage-output-Bnkerfod.mjs} +5 -5
  6. package/dist/{android-DtfRGLcc.mjs → android-BGwuK3Mc.mjs} +75 -50
  7. package/dist/{android-CLi6DSiS.mjs → android-CNZgRC-4.mjs} +5 -5
  8. package/dist/{android-C7sVmyI9.mjs → android-Cjcj8MCw.mjs} +140 -46
  9. package/dist/{android-cas-ngferVq2.mjs → android-cas-BVqh2Zep.mjs} +3 -3
  10. package/dist/android-cas-compiler.mjs +1 -1
  11. package/dist/{android-project-DVWyCbWU.d.mts → android-project-CTYaETc0.d.mts} +6 -2
  12. package/dist/{android-DR5lZ2Az.mjs → android-saBeB4lr.mjs} +13 -3
  13. package/dist/api.d.mts +22 -5
  14. package/dist/api.mjs +32 -31
  15. package/dist/{artifact-Xvgibgzq.mjs → artifact-Co8zixVx.mjs} +19 -17
  16. package/dist/{artifact-DBI3DALs.mjs → artifact-DN8JNwqS.mjs} +18 -17
  17. package/dist/{artifact-platform-CXcmX_j3.mjs → artifact-platform-CMRc0M_r.mjs} +3 -3
  18. package/dist/{browser-web-BJN9ZHxB.mjs → browser-web-CCgZsHmI.mjs} +16 -17
  19. package/dist/{budget-3ivAK99e.mjs → budget-HyShrIpL.mjs} +149 -47
  20. package/dist/{build-Dv9s8Fz-.mjs → build-CAiw8Ezm.mjs} +33 -29
  21. package/dist/{build-cache-Dv7RN200.mjs → build-cache-CKCzxzxA.mjs} +172 -21
  22. package/dist/{build-plan-BmbdHQbr.mjs → build-plan-zCuHGlA8.mjs} +8 -7
  23. package/dist/{cache-manifest-DSeQjt-Q.mjs → cache-manifest-BPXRONJz.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{ccache-CH2EWGPB.mjs → ccache-h1FKhZeg.mjs} +6 -6
  26. package/dist/{cdp-3fwICjzi.mjs → cdp-BG3FJCCx.mjs} +1 -1
  27. package/dist/{chrome-Bbw689-6.mjs → chrome-BvV8ssI3.mjs} +1 -1
  28. package/dist/{cli-BkK6Wr5i.mjs → cli-C4w607Pz.mjs} +20 -20
  29. package/dist/cli.mjs +1 -1
  30. package/dist/{client-B4MMzfo_.mjs → client-BQsmyp_-.mjs} +274 -39
  31. package/dist/collector-run.mjs +6 -6
  32. package/dist/{command-output-YKGWivpG.mjs → command-output-BBvS1H6v.mjs} +3 -2
  33. package/dist/{config-DlrsduwG.mjs → config-BZhXY15H.mjs} +3 -3
  34. package/dist/{created-devices-x9rN6bhs.mjs → created-devices-D2Aca-xu.mjs} +6 -2
  35. package/dist/{dependency-state-1I9KZT1Y.mjs → dependency-state-BwNCYG5Q.mjs} +2 -2
  36. package/dist/{detached-entry-BwNEtIrP.mjs → detached-entry-KmieOKgN.mjs} +1 -1
  37. package/dist/{dev-client-BFxiDpkf.mjs → dev-client-CHoXXZeg.mjs} +3 -3
  38. package/dist/{device-CiNYxqp6.mjs → device-B9FqTBYW.mjs} +81 -54
  39. package/dist/{device-B7ljwccX.mjs → device-F5-4z9ef.mjs} +16 -16
  40. package/dist/{device-capacity-DH0QsZYZ.mjs → device-capacity-ZYaRALv5.mjs} +20 -16
  41. package/dist/device-host-worker.mjs +17 -17
  42. package/dist/{device-ios-CbVDtDIy.mjs → device-ios-DkHBrmvH.mjs} +32 -50
  43. package/dist/{device-lease-run-DXPSwdbb.mjs → device-lease-run-ogEeJ62K.mjs} +6 -6
  44. package/dist/{device-pool-B4iOXIrD.mjs → device-pool-BIg8MU8l.mjs} +3 -3
  45. package/dist/{doctor-DRu-8ld6.mjs → doctor-A_Nr_fDe.mjs} +1 -1
  46. package/dist/{doctor-HUC1igzw.mjs → doctor-Bm8TVpGn.mjs} +37 -31
  47. package/dist/{doctor-fingerprint-DZLoYFVb.mjs → doctor-fingerprint-zlujA1Gs.mjs} +1 -1
  48. package/dist/doctor-fingerprint.mjs +1 -1
  49. package/dist/{doctor-C6t4Maue.mjs → doctor-k3P3PizH.mjs} +14 -14
  50. package/dist/{doctor-watchman-iGBpC6KM.mjs → doctor-watchman-BovI1y3-.mjs} +5 -5
  51. package/dist/{eas-build-DMWSSvxq.mjs → eas-build-CyDKNTBP.mjs} +4 -4
  52. package/dist/{eas-fallback-vKlrqxgE.mjs → eas-fallback-gaZi-dJL.mjs} +16 -15
  53. package/dist/{eas-session-ledger-BQF9Yyy9.mjs → eas-session-ledger-BMCA1gdO.mjs} +12 -8
  54. package/dist/{error-diagnostics-DYsjJIHz.mjs → error-diagnostics-B1Mj_-7h.mjs} +17 -42
  55. package/dist/{errors-ccaPc4ox.mjs → errors-DHm_U5gv.mjs} +2 -1
  56. package/dist/{exec-DEoAhcze.mjs → exec-VFRpu1iA.mjs} +116 -28
  57. package/dist/{gc-BW8E1uSC.mjs → gc-B9jcnmIk.mjs} +205 -28
  58. package/dist/{gc-dDE4QPVu.mjs → gc-eaz403W6.mjs} +2 -2
  59. package/dist/{guide-DYYEO3Wz.mjs → guide-DR0K0xW9.mjs} +328 -89
  60. package/dist/{hosted-android-xcfgCgSF.mjs → hosted-android-Bvb2-ZxD.mjs} +4 -4
  61. package/dist/{hosted-client-Bt-tndxV.mjs → hosted-client-rsRqysJc.mjs} +4 -4
  62. package/dist/{hosted-ios-y19jCYFF.mjs → hosted-ios-RtVcJH3u.mjs} +1 -1
  63. package/dist/{hosted-logs-DzJKzKlj.mjs → hosted-logs-CWKGYWNX.mjs} +11 -6
  64. package/dist/{hosted-macos-BJusKvqL.mjs → hosted-macos-d0pv9Tth.mjs} +7 -7
  65. package/dist/{hosted-native-BmQC6U_x.mjs → hosted-native-BxTizGU2.mjs} +58 -11
  66. package/dist/{idle-shutdown-CJmUOV5x.mjs → idle-shutdown-BIyfl0Zj.mjs} +10 -10
  67. package/dist/{ios-hcBpnEGk.mjs → ios-BQzvJlzw.mjs} +122 -17
  68. package/dist/{ios-CWjqfSm_.mjs → ios-BRVM8b0P.mjs} +81 -49
  69. package/dist/{ios-DTOYZGMJ.mjs → ios-Dvt97HgQ.mjs} +8 -8
  70. package/dist/{ios-xtlRHaeB.mjs → ios-ENC4sRPA.mjs} +1 -1
  71. package/dist/{ios-device-BXZ0c7Kb.mjs → ios-device-B6HK951C.mjs} +1 -1
  72. package/dist/{ios-device-DFGuwF4U.mjs → ios-device-CKSvk0bu.mjs} +3 -3
  73. package/dist/{ios-project-CSZYI1iu.mjs → ios-project-DCUDo06I.mjs} +5 -5
  74. package/dist/{ios-signing-BtAffm0A.mjs → ios-signing-4c_qXvQm.mjs} +2 -2
  75. package/dist/{ios-state-Dtw5K2aI.mjs → ios-state-CT9nV5SP.mjs} +15 -7
  76. package/dist/{js-swap-BSBHldmm.mjs → js-swap-Z9HbC4cj.mjs} +7 -6
  77. package/dist/{launch-D-zq8SHG.mjs → launch-D0lPvFFu.mjs} +49 -30
  78. package/dist/{launch-CP2wDCVd.mjs → launch-DscF1QfM.mjs} +52 -50
  79. package/dist/{logs-pNvA2hHK.mjs → logs-BsIRre8x.mjs} +16 -9
  80. package/dist/{logs-By5aw3g9.mjs → logs-Crs9y34Z.mjs} +8 -6
  81. package/dist/{macos-CPMahOC2.mjs → macos-CcUlJPMu.mjs} +1 -1
  82. package/dist/{macos-C67FZ2ft.mjs → macos-D477nfzH.mjs} +49 -42
  83. package/dist/macos-run.mjs +1 -1
  84. package/dist/maintenance-run.mjs +7 -7
  85. package/dist/{metro-DiXtA3Ty.mjs → metro-1pJgCX4U.mjs} +4 -4
  86. package/dist/{metro-gateway-CKZqKqx7.mjs → metro-gateway-Bp9gJQAN.mjs} +3 -4
  87. package/dist/{named-ports-DkEzOfzO.mjs → named-ports-BVbn8SvC.mjs} +3 -3
  88. package/dist/{native-android-_MWSs3PP.mjs → native-android-BvMizJn1.mjs} +17 -17
  89. package/dist/{native-gradle-artifact-inputs-DHFnmrVf.mjs → native-gradle-artifact-inputs-BJscK4vN.mjs} +5 -5
  90. package/dist/{native-run-Dv88i0aU.mjs → native-run-D5OJsGwA.mjs} +6 -6
  91. package/dist/{native-runtime-DBRfY_PN.mjs → native-runtime-B9w_Qyz3.mjs} +10 -9
  92. package/dist/{native-source-Y0yLhFyQ.mjs → native-source-D-4Dh4JU.mjs} +7 -4
  93. package/dist/{native-xcode-inputs-CqViUh3r.mjs → native-xcode-inputs-Cv4l-obn.mjs} +2 -2
  94. package/dist/{native-xcode-ios-vFgqL_yS.mjs → native-xcode-ios-DGrg90hE.mjs} +21 -20
  95. package/dist/offload-worker.d.mts +12 -4
  96. package/dist/offload-worker.mjs +78 -43
  97. package/dist/{operation-exec-BW0em61G.mjs → operation-exec-CUZifp6Z.mjs} +2 -25
  98. package/dist/{ownership-C5fo5Edb.mjs → ownership-jxxz-19m.mjs} +3 -3
  99. package/dist/{page-DBL2PiUU.mjs → page-CzEA_-5_.mjs} +2 -3
  100. package/dist/phone-reverses-CYb7RRAx.mjs +57 -0
  101. package/dist/{placement-log-BnGgJRRZ.mjs → placement-log-DjOXJRIH.mjs} +1 -1
  102. package/dist/{plan-placement-cr0fEU7b.mjs → plan-placement-BqKgKHCi.mjs} +3 -3
  103. package/dist/{ports-DpXjKkSV.mjs → ports-DtS1Amb0.mjs} +3 -3
  104. package/dist/{prebuild-BligW0QS.mjs → prebuild-JUaqOLpc.mjs} +14 -9
  105. package/dist/{project-DhCtQWWU.mjs → project-BiC68mIp.mjs} +21 -17
  106. package/dist/{pull-request-W1IuLXDt.mjs → pull-request-CbNlkFok.mjs} +2 -2
  107. package/dist/pull-requests.mjs +1 -1
  108. package/dist/{react-native-android-ZlhQfhvq.mjs → react-native-android-DRYqoJc4.mjs} +76 -32
  109. package/dist/{react-native-build-CelbTO_y.mjs → react-native-build-CwZB-agu.mjs} +23 -20
  110. package/dist/{react-native-doctor-LTIaP7lv.mjs → react-native-doctor-BCrytK7h.mjs} +10 -9
  111. package/dist/{react-native-ios-C5W0SA6f.mjs → react-native-ios-Cr1buNFo.mjs} +41 -24
  112. package/dist/{recordings-CQmfzAh7.mjs → recordings-BaoQ0t-J.mjs} +1 -1
  113. package/dist/{registration-BcRgF6Ox.mjs → registration-CN6nlhcD.mjs} +1 -1
  114. package/dist/{reload-QcwnYLYV.mjs → reload-Beftw2X3.mjs} +1 -1
  115. package/dist/{reload-COJWTbae.mjs → reload-FbSgMF8x.mjs} +144 -42
  116. package/dist/{remote-DR8qUERM.mjs → remote-BuZj6AyU.mjs} +16 -7
  117. package/dist/{result-utnBea7x.mjs → result-CR2vk2cj.mjs} +41 -18
  118. package/dist/{run-DidHghD1.mjs → run-BtzE09Dl.mjs} +2 -2
  119. package/dist/{selection-DSMbWEX2.mjs → selection-D5cxEl3t.mjs} +13 -7
  120. package/dist/{server-bare-CafzuyFB.mjs → server-bare-CH9X0RLn.mjs} +56 -4
  121. package/dist/{server-command-B9o92sLM.mjs → server-command-CaBbDNU2.mjs} +5 -5
  122. package/dist/server-expo-C16Zf2k7.mjs +2 -0
  123. package/dist/{server-expo-BXrWxNYh.mjs → server-expo-Ck8EIidM.mjs} +14 -9
  124. package/dist/{settings-C7O8A6ZI.mjs → settings-B5tCoq9N.mjs} +132 -39
  125. package/dist/{settings-PfJx8uK1.mjs → settings-DzH9mGQZ.mjs} +1 -1
  126. package/dist/{settings-write-Chuy7Cte.mjs → settings-write-n0zwfohx.mjs} +7 -7
  127. package/dist/settings.schema.json +51 -0
  128. package/dist/{simslim-BNckWpXi.mjs → simslim-BjxszUAb.mjs} +22 -7
  129. package/dist/{slot-launch-B7AuoWJv.mjs → slot-launch-QeuJMlnJ.mjs} +6 -6
  130. package/dist/{stage-C4u17aES.mjs → stage-D8xlRU2D.mjs} +2 -3
  131. package/dist/{start-BL_BsiWt.mjs → start-C1JLjkNw.mjs} +1 -1
  132. package/dist/{start-CU8mCPC7.mjs → start-YMpNwLhh.mjs} +75 -35
  133. package/dist/{state--smjFSTL.mjs → state-DMRNP7-4.mjs} +4 -4
  134. package/dist/{state-08I3hw3_.mjs → state-DPaM3u5K.mjs} +2 -2
  135. package/dist/{stats-CO6sK0Nh.mjs → stats-CP7STzZw.mjs} +5 -5
  136. package/dist/{stats-report-BzaPrRm6.mjs → stats-report-n2U5plhk.mjs} +1 -1
  137. package/dist/{status-_WPHzVft.mjs → status-CRLiJ-O_.mjs} +24 -24
  138. package/dist/{status-BRROykC8.mjs → status-Fect2w9R.mjs} +1 -1
  139. package/dist/{status-CrJutl6-.mjs → status-cNw6i0_t.mjs} +1 -1
  140. package/dist/{status-watch-BHFasOZN.mjs → status-watch-Bc2J4TZn.mjs} +5 -5
  141. package/dist/status-worker.mjs +1 -1
  142. package/dist/stim-clonefile.c +18 -0
  143. package/dist/{stim-desktop-D5OGpYZM.mjs → stim-desktop-DS0mzR8U.mjs} +2 -2
  144. package/dist/{stop-iuFHjUST.mjs → stop-Br7LKxBE.mjs} +2 -2
  145. package/dist/{stop-CR5689oB.mjs → stop-COP6PQqw.mjs} +5 -5
  146. package/dist/{stop-BJ06ipTZ.mjs → stop-Db9Kh-UA.mjs} +109 -56
  147. package/dist/supervisor-run.mjs +17 -17
  148. package/dist/{support-CbXPbUMJ.mjs → support-Cxj9CmII.mjs} +6 -6
  149. package/dist/{support-TWuQlHQo.mjs → support-qKcbgmI5.mjs} +14 -11
  150. package/dist/{swiftpm-artifact-inputs-DFcGsXDP.mjs → swiftpm-artifact-inputs-iY9fsmOc.mjs} +4 -4
  151. package/dist/{swiftpm-macos-DbwGCpZg.mjs → swiftpm-macos-Bp_sn9P4.mjs} +15 -14
  152. package/dist/{toolchain-XkA2PfJZ.mjs → toolchain-DB1aeqxO.mjs} +1 -1
  153. package/dist/{toolchain-B9hCFCQw.mjs → toolchain-VzLJzZ7O.mjs} +69 -37
  154. package/dist/trigger-BLsHgAGR.mjs +2 -0
  155. package/dist/{trigger-Cbyc41d_.mjs → trigger-CBMe2YLH.mjs} +2 -2
  156. package/dist/{warm-progress-CA3TgT3-.mjs → warm-progress-BV3ZPmcY.mjs} +6 -6
  157. package/dist/{web-DRF_oFXk.mjs → web-B4Yjyt1G.mjs} +12 -10
  158. package/dist/web-DS4UDWvf.mjs +2 -0
  159. package/dist/web-run.mjs +8 -9
  160. package/dist/windows-report.mjs +12 -1
  161. package/dist/windows-report.ps1 +1 -1
  162. package/dist/{workspace-state-U08dEzhG.mjs → workspace-state-CPSp3mav.mjs} +11 -4
  163. package/dist/{workspaces-e41xsjKr.mjs → workspaces-C9w4aeXF.mjs} +36 -32
  164. package/dist/{worktree-B4Nj3EGS.mjs → worktree-CclFIe1Z.mjs} +324 -99
  165. package/dist/{worktree-BEwxVwKF.mjs → worktree-Ct9Gk3KL.mjs} +1 -1
  166. package/dist/{xcode-Rq744mBF.mjs → xcode-CiIIDnuD.mjs} +42 -28
  167. package/package.json +7 -7
  168. package/shim/bundle-response.cjs +53 -1
  169. package/shim/bundle-response.d.cts +1 -1
  170. package/shim/expo-metro-config.cjs +23 -1
  171. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +0 -211
  172. package/dist/server-expo-Ddr8cG_c.mjs +0 -2
  173. package/dist/trigger-yb_nFzPF.mjs +0 -2
  174. package/dist/web-kDE9Myoy.mjs +0 -2
@@ -1,13 +1,12 @@
1
- import { i as withWorkspaceProcessLock, n as isTimeoutError, t as getExecutor, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
1
+ import { D as ownership_claim_exports, o as cancellableSleep, t as getExecutor, u as withWorkspaceProcessLock } from "./exec-VFRpu1iA.mjs";
2
2
  import { f as workspaceId$1 } from "./paths-DQtTgsBf.mjs";
3
- import { C as saveConfig, D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, a as clearDevice, d as getConfigDir, w as setDevice } from "./config-DlrsduwG.mjs";
4
- import { l as phaseLine } from "./command-output-YKGWivpG.mjs";
5
- import { u as cancellableSleep } from "./operation-exec-BW0em61G.mjs";
6
- import { T as iosSimSlimProfileSetting } from "./settings-C7O8A6ZI.mjs";
7
- import { j as teardownParkedIosSim } from "./workspaces-e41xsjKr.mjs";
8
- import { _t as parkedMaxSetting, bt as selectParked, ft as adoptParked, pt as dropParked, vt as readParked } from "./android-C7sVmyI9.mjs";
9
- 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, f as listAllIosSimsAsync, h as listIosRuntimesAsync, n as bootIosSim, p as listIosDeviceTypesAsync, u as iosSimulatorFailureAdvice, w as resetIosPrivacy, y as parseRuntimeVersion } from "./ios-hcBpnEGk.mjs";
10
- import { l as runtimeMismatch, m as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as deviceTypeMismatch } from "./device-capacity-DH0QsZYZ.mjs";
3
+ import { C as saveConfig, G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, a as clearDevice, d as getConfigDir, w as setDevice } from "./config-BZhXY15H.mjs";
4
+ import { l as phaseLine } from "./command-output-BBvS1H6v.mjs";
5
+ import { E as iosSimSlimProfileSetting, T as iosSimSlimDefaultSetting } from "./settings-B5tCoq9N.mjs";
6
+ import { mt as dropParked, pt as adoptParked, vt as parkedMaxSetting, xt as selectParked, yt as readParked } from "./android-Cjcj8MCw.mjs";
7
+ import { M as teardownParkedIosSim } from "./workspaces-C9w4aeXF.mjs";
8
+ import { A as waitForSpringBoard, C as resetIosKeychain, E as resolveOwnedIosSim, I as readHostMemoryPressure, N as hostMemoryPressureAdvice, R as reportMemoryCulprits, S as renameIosSim, T as resolveIosCreation, _ as ownedSimName, a as createOwnedIosSim, d as listAllIosSims, f as listAllIosSimsAsync, h as listIosRuntimesAsync, j as configuredIosSimulatorViewer, n as bootIosSim, p as listIosDeviceTypesAsync, u as iosSimulatorFailureAdvice, w as resetIosPrivacy, y as parseRuntimeVersion } from "./ios-BQzvJlzw.mjs";
9
+ import { l as runtimeMismatch, m as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as deviceTypeMismatch } from "./device-capacity-ZYaRALv5.mjs";
11
10
  import { ambientContext } from "@stim-cli/core";
12
11
  import { isJsonObject } from "@stim-cli/core/state";
13
12
  import chalk from "chalk";
@@ -24,8 +23,8 @@ function startIosBoot(udid, configure, label, out, simulatorApp, root, deviceSlo
24
23
  simulatorApp,
25
24
  env: ambientContext()?.env
26
25
  });
27
- await muteBootedSimulator(udid, out);
28
26
  await configure();
27
+ await muteBootedSimulator(udid, out);
29
28
  }, {
30
29
  ...deviceSlotWait,
31
30
  root,
@@ -37,36 +36,12 @@ function startIosBoot(udid, configure, label, out, simulatorApp, root, deviceSlo
37
36
  done
38
37
  };
39
38
  }
40
- const SPRINGBOARD_STARTUP_TIMEOUT_MS = 3e4;
41
- const SPRINGBOARD_STARTUP_POLL_MS = 250;
42
- async function waitForSpringBoard(udid) {
43
- const deadline = Date.now() + SPRINGBOARD_STARTUP_TIMEOUT_MS;
44
- for (;;) {
45
- let output = null;
46
- try {
47
- output = await getExecutor().runFileAsync("xcrun", [
48
- "simctl",
49
- "spawn",
50
- udid,
51
- "notifyutil",
52
- "-g",
53
- "com.apple.springboard.finishedstartup"
54
- ], { timeoutMs: 1e4 });
55
- } catch (error) {
56
- if (!isTimeoutError(error)) throw error;
57
- }
58
- if (output !== null) {
59
- const state = /^com\.apple\.springboard\.finishedstartup (\d+)$/m.exec(output);
60
- if (!state) throw new Error(`Could not read SpringBoard's startup state: ${output.trim() || "no output"}.`);
61
- if (Number(state[1]) > 0) return;
62
- }
63
- if (Date.now() >= deadline) throw new Error(`SpringBoard did not finish starting within ${SPRINGBOARD_STARTUP_TIMEOUT_MS / 1e3}s.`);
64
- await cancellableSleep(SPRINGBOARD_STARTUP_POLL_MS);
65
- }
66
- }
39
+ const SPRINGBOARD_MUTE_WAIT_MS = 6e4;
67
40
  async function muteBootedSimulator(udid, out) {
68
41
  try {
69
- await waitForSpringBoard(udid);
42
+ const springBoard = await waitForSpringBoard(udid, Date.now() + SPRINGBOARD_MUTE_WAIT_MS);
43
+ if (springBoard.state === "unreadable") throw new Error(springBoard.reason);
44
+ if (springBoard.state === "timed-out") throw new Error(`SpringBoard did not finish starting within ${SPRINGBOARD_MUTE_WAIT_MS / 1e3}s.`);
70
45
  const response = JSON.parse(await getExecutor().runFileAsync("xcrun", [
71
46
  "devicectl",
72
47
  "device",
@@ -90,9 +65,11 @@ var IosDeviceMismatchError = class extends Error {
90
65
  };
91
66
  async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, label, settings, flags, note, out, reconcileIosSimulator, simSnapshot }) {
92
67
  const pressure = readHostMemoryPressure();
93
- const memoryAdvice = hostMemoryPressureAdvice(pressure, memoryCulpritsUnder(pressure));
68
+ const memoryAdvice = hostMemoryPressureAdvice(pressure);
94
69
  if (memoryAdvice) out(chalk.yellow(phaseLine("memory", memoryAdvice)));
70
+ reportMemoryCulprits(pressure, (named) => out(chalk.yellow(phaseLine("memory", named))));
95
71
  const simslimProfile = iosSimSlimProfileSetting(settings, settingsRoot);
72
+ const simslimDefault = iosSimSlimDefaultSetting(settings);
96
73
  if (record?.deviceUdid) {
97
74
  if (record.owned) {
98
75
  const listed = simSnapshot ? simSnapshot.read() : listAllIosSims({ includeUnavailable: true });
@@ -101,10 +78,10 @@ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, l
101
78
  else if (resolved.missing) {} else {
102
79
  const sim = resolved.sim;
103
80
  const wantedType = flags.deviceType || settings?.ios?.deviceType;
104
- const deviceTypes = await listIosDeviceTypesAsync();
81
+ const deviceTypes = await listIosDeviceTypesAsync({ snapshot: simSnapshot });
105
82
  const mismatch = deviceTypeMismatch(sim.deviceTypeIdentifier, wantedType, deviceTypes);
106
83
  if (mismatch) throw new IosDeviceMismatchError(`${mismatch}. Stim will not silently boot a different model.`);
107
- const versionMismatch = flags.runtimeFlag ? runtimeMismatch(sim.runtime, flags.runtimeFlag, await listIosRuntimesAsync()) : null;
84
+ const versionMismatch = flags.runtimeFlag ? runtimeMismatch(sim.runtime, flags.runtimeFlag, await listIosRuntimesAsync({ snapshot: simSnapshot })) : null;
108
85
  if (versionMismatch) throw new IosDeviceMismatchError(`${versionMismatch}. Stim will not silently boot a different iOS version.`);
109
86
  const model = {
110
87
  model: deviceTypes.find((d) => d.identifier === sim.deviceTypeIdentifier)?.name ?? null,
@@ -128,6 +105,7 @@ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, l
128
105
  projectPath,
129
106
  slot,
130
107
  profile: simslimProfile,
108
+ slimByDefault: simslimDefault,
131
109
  out,
132
110
  reconcileIosSimulator
133
111
  });
@@ -183,6 +161,7 @@ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, l
183
161
  projectPath,
184
162
  slot,
185
163
  profile: simslimProfile,
164
+ slimByDefault: simslimDefault,
186
165
  out,
187
166
  reconcileIosSimulator
188
167
  });
@@ -200,11 +179,11 @@ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, l
200
179
  runtime: choice.runtime
201
180
  }, projectPath, void 0, await listAllIosSimsAsync({ includeUnavailable: true }));
202
181
  const result = await createOwnedIosSim(label, { suffix }, choice);
203
- setDevice(projectPath, "ios", {
182
+ await withConfigLockAsync$1(() => setDevice(projectPath, "ios", {
204
183
  deviceUdid: result.udid,
205
184
  owned: true,
206
185
  deviceName: result.name
207
- }, slot);
186
+ }, slot));
208
187
  return result;
209
188
  });
210
189
  const newRecord = {
@@ -217,6 +196,7 @@ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, l
217
196
  projectPath,
218
197
  slot,
219
198
  profile: simslimProfile,
199
+ slimByDefault: simslimDefault,
220
200
  out,
221
201
  reconcileIosSimulator
222
202
  }), created.name, out, flags.simulatorApp, projectPath, flags.deviceSlotWait);
@@ -293,7 +273,7 @@ async function takeParkedIosSim({ projectPath, slot, label, choice, out }) {
293
273
  ...parked.simslimManaged ? { simslimManaged: true } : {},
294
274
  ...parked.cacheKey ? { parkedCacheKey: parked.cacheKey } : {}
295
275
  };
296
- const adopted = adoptParked({
276
+ const adopted = await adoptParked({
297
277
  platform: "ios",
298
278
  projectPath,
299
279
  slot,
@@ -312,7 +292,7 @@ async function takeParkedIosSim({ projectPath, slot, label, choice, out }) {
312
292
  return null;
313
293
  }
314
294
  function clearIosAdoptionPending(projectPath, slot = "default") {
315
- withConfigLock$1(() => {
295
+ return withConfigLockAsync$1(() => {
316
296
  const cfg = loadConfig$1();
317
297
  const ios = deviceSlotPlatforms(cfg?.projects?.[projectPath], slot)?.ios;
318
298
  if (!cfg || !ios?.adoptionPending) return;
@@ -322,29 +302,31 @@ function clearIosAdoptionPending(projectPath, slot = "default") {
322
302
  saveConfig(cfg);
323
303
  });
324
304
  }
325
- async function configureOwnedIosSim({ record, projectPath, slot, profile, out, reconcileIosSimulator }) {
305
+ async function configureOwnedIosSim({ record, projectPath, slot, profile, slimByDefault, out, reconcileIosSimulator }) {
326
306
  if (profile) out(chalk.dim(phaseLine("device", `applying the SimSlim profile to ${record.deviceUdid}`)));
307
+ else if (slimByDefault) out(chalk.dim(phaseLine("device", `applying SimSlim's default services to ${record.deviceUdid}`)));
327
308
  else if (record.simslimManaged) out(chalk.dim(phaseLine("device", `restoring stock simulator services on ${record.deviceUdid}`)));
328
309
  const previouslyManaged = Boolean(record.simslimManaged);
329
- if (profile && !record.simslimManaged) {
310
+ if ((profile || slimByDefault) && !record.simslimManaged) {
330
311
  const pending = {
331
312
  ...record,
332
313
  simslimManaged: true
333
314
  };
334
- setDevice(projectPath, "ios", pending, slot);
315
+ await withConfigLockAsync$1(() => setDevice(projectPath, "ios", pending, slot));
335
316
  record = pending;
336
317
  }
337
318
  const result = await reconcileIosSimulator({
338
319
  context: ambientContext(),
339
320
  udid: record.deviceUdid,
340
321
  profile,
322
+ slimByDefault,
341
323
  previouslyManaged,
342
324
  out
343
325
  });
344
326
  const updated = { ...record };
345
327
  if (result.managed) updated.simslimManaged = true;
346
328
  else delete updated.simslimManaged;
347
- setDevice(projectPath, "ios", updated, slot);
329
+ await withConfigLockAsync$1(() => setDevice(projectPath, "ios", updated, slot));
348
330
  return updated;
349
331
  }
350
332
  async function ensureIosBooted({ device, projectPath, deviceSlotWait, simulatorApp, timeoutMs, pollMs, out }) {
@@ -369,7 +351,7 @@ async function ensureIosBooted({ device, projectPath, deviceSlotWait, simulatorA
369
351
  } catch (error) {
370
352
  return {
371
353
  failed: true,
372
- reason: `Simulator ${udid} failed its process-spawn readiness check: ${error?.message || error}. ${iosSimulatorFailureAdvice()}`
354
+ reason: `Simulator ${udid} failed its process-spawn readiness check: ${error?.message || error}. ${await iosSimulatorFailureAdvice()}`
373
355
  };
374
356
  }
375
357
  };
@@ -1,11 +1,11 @@
1
- import { m as operationState } from "./exec-DEoAhcze.mjs";
2
- import { V as deviceSlotKey } from "./config-DlrsduwG.mjs";
3
- import { a as formatElapsed, r as clockTime } from "./command-output-YKGWivpG.mjs";
4
- import { Zt as VERIFY_TIMEOUT_MS, on as APP_READINESS_TIMEOUT_MS } from "./budget-3ivAK99e.mjs";
5
- import { E as releaseRunLease, S as parseLease, T as raiseLease, b as leaseIsExpired, j as takeLease, v as deviceLeasePath, y as fileLeaseIo } from "./activity-BpWUPgUm.mjs";
1
+ import { b as operationState } from "./exec-VFRpu1iA.mjs";
2
+ import { V as deviceSlotKey } from "./config-BZhXY15H.mjs";
3
+ import { a as formatElapsed, r as clockTime } from "./command-output-BBvS1H6v.mjs";
4
+ import { Qt as MANIFEST_VERIFY_TIMEOUT_MS, ln as APP_READINESS_TIMEOUT_MS } from "./budget-HyShrIpL.mjs";
5
+ import { E as releaseRunLease, S as parseLease, T as raiseLease, b as leaseIsExpired, j as takeLease, v as deviceLeasePath, y as fileLeaseIo } from "./activity-BpjwrQXU.mjs";
6
6
  //#region src/engine/device-lease-run.ts
7
7
  const LEASE_STEP_FLOOR_MS = 6e4;
8
- const DEBUG_VERIFY_STEP_MS = VERIFY_TIMEOUT_MS + APP_READINESS_TIMEOUT_MS;
8
+ const DEBUG_VERIFY_STEP_MS = MANIFEST_VERIFY_TIMEOUT_MS + APP_READINESS_TIMEOUT_MS;
9
9
  const DEVICE_WAIT_POLL_MS = 2e3;
10
10
  const DEVICE_WAIT_LINE_MS = 3e4;
11
11
  const DEVICE_BUSY = "STIM_DEVICE_BUSY";
@@ -1,6 +1,6 @@
1
- import { V as deviceSlotKey } from "./config-DlrsduwG.mjs";
2
- import { A as selectPoolDevice, S as parseLease, b as leaseIsExpired, v as deviceLeasePath, y as fileLeaseIo } from "./activity-BpWUPgUm.mjs";
3
- import { i as DEVICE_WAIT_POLL_MS, n as DEVICE_BUSY, o as leaseExpiryText } from "./device-lease-run-DXPSwdbb.mjs";
1
+ import { V as deviceSlotKey } from "./config-BZhXY15H.mjs";
2
+ import { A as selectPoolDevice, S as parseLease, b as leaseIsExpired, v as deviceLeasePath, y as fileLeaseIo } from "./activity-BpjwrQXU.mjs";
3
+ import { i as DEVICE_WAIT_POLL_MS, n as DEVICE_BUSY, o as leaseExpiryText } from "./device-lease-run-ogEeJ62K.mjs";
4
4
  //#region src/engine/device-pool.ts
5
5
  function heldPoolId(root, platform, now, io = fileLeaseIo, slot = "default") {
6
6
  const record = io.readHolder(root)[deviceSlotKey(platform, slot)];
@@ -1,2 +1,2 @@
1
- import { a as readDoctorReport, i as parseDoctorPlatform, n as doctorCommand, o as shadowedStimFinding, r as doctorSuccessLines, s as toolchainReport, t as applySandboxFix } from "./doctor-C6t4Maue.mjs";
1
+ import { a as readDoctorReport, i as parseDoctorPlatform, n as doctorCommand, o as shadowedStimFinding, r as doctorSuccessLines, s as toolchainReport, t as applySandboxFix } from "./doctor-k3P3PizH.mjs";
2
2
  export { applySandboxFix, doctorCommand as default, doctorSuccessLines, parseDoctorPlatform, readDoctorReport, shadowedStimFinding, toolchainReport };
@@ -1,29 +1,29 @@
1
- import { _ as reportSignal, t as getExecutor, y as trackReportResource } from "./exec-DEoAhcze.mjs";
1
+ import { C as reportSignal, T as trackReportResource, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  import { i as sharedBuildCache, u as workspaceDerivedData } from "./paths-DQtTgsBf.mjs";
3
- import { _ as loadConfig$1, nt as realIo, s as configCorruptRepair, u as getConcurrencyLimits } from "./config-DlrsduwG.mjs";
4
- import { d as quotedPath, u as plural } from "./command-output-YKGWivpG.mjs";
5
- import { l as gitQuietAsync, o as git } from "./operation-exec-BW0em61G.mjs";
6
- import { r as readWorkspaceState$1 } from "./workspace-state-U08dEzhG.mjs";
7
- import { D as mergeSettingsLayers, Et as listWorktreesAsync, Gt as temporaryRoot, Ht as makeTemporaryDirectory, I as projectSettingsContext, It as resolveSourceCheckoutAsync, K as resolveIosProjectDir, Mt as repoRoot, Nt as repoRootAsync, Ot as locallyKnownUpstreamAsync, Q as settingOrigin, T as iosSimSlimProfileSetting, U as remoteIosSetting, V as remoteAndroidSetting, Vt as filesystemDevice, W as resolveAndroidLayout, Y as resolveSettings, a as SETTING_SHAPE_REMEDY, at as webSettings, et as settingShapeErrors, ht as dirtyFingerprintFiles, i as SETTINGS_WITH_RESOLVE_TIME_FALLBACK, it as unknownSettingKeys, m as defaultAndroidLayout, nt as settingsLayers, r as PATH_SETTINGS, tt as settingValueAt, vt as gitCommonDirAsync } from "./settings-C7O8A6ZI.mjs";
8
- import { C as resolvePackageJson, _ as appProjectProblem, b as isPackageResolvable, v as detectIsExpo } from "./project-DhCtQWWU.mjs";
9
- import { Bn as checkEasAuth$1, Gn as providerFromConfig, Ht as readInstalledEasCliVersionAsync, Wn as ownerFromConfig, er as MIN_EAS_CLI_SIMULATOR_VERSION, nr as easCliUpgradeRemedy, qn as resolveEasCliBin, tr as easCliSupport } from "./budget-3ivAK99e.mjs";
10
- import { L as listBuildSlots } from "./workspaces-e41xsjKr.mjs";
11
- import { N as listBuildLocks } from "./activity-BpWUPgUm.mjs";
12
- import { a as diffFingerprintSources, l as fingerprintProject } from "./build-cache-Dv7RN200.mjs";
13
- import { _t as parkedMaxSetting, dt as POOL_SETTING_REMEDY, k as hostSystemImageArch, o as androidHome } from "./android-C7sVmyI9.mjs";
14
- import { F as readHostMemoryPressureAsync, M as hostMemoryPressureAdvice } from "./ios-hcBpnEGk.mjs";
15
- import { p as resolveOptimizations, u as compilerCacheFallbackMessage } from "./errors-ccaPc4ox.mjs";
16
- import { i as projectCmakeLauncher } from "./ccache-CH2EWGPB.mjs";
17
- import { x as podInstallCommand } from "./xcode-Rq744mBF.mjs";
18
- import { h as androidPathRoomRemedy, i as ccacheEnabled, l as androidSdkRefusal, m as androidPathRoomMessage, p as androidPathRoom, t as apkOutputsDir } from "./react-native-build-CelbTO_y.mjs";
19
- import { a as countLiveOwnedDevicesAsync, i as countLiveOwnedDevices } from "./device-capacity-DH0QsZYZ.mjs";
20
- import { t as readDoctorFingerprint } from "./doctor-fingerprint-DZLoYFVb.mjs";
21
- import { i as probeSigningIdentities } from "./ios-signing-BtAffm0A.mjs";
22
- import { a as findChrome, t as CHROME_INSTALL_REMEDY } from "./chrome-Bbw689-6.mjs";
23
- import { i as installedNpmTreeIsValidAsync, n as hasInstalledDependencies, t as dependencyState } from "./dependency-state-1I9KZT1Y.mjs";
24
- import { n as simslimIsOnPath } from "./simslim-BNckWpXi.mjs";
25
- import { t as MIN_EAS_CLI_BUILD_DOWNLOAD_VERSION } from "./eas-build-DMWSSvxq.mjs";
26
- import { r as resolveAndroidCompilerCache, t as readAndroidCasToolchain } from "./android-cas-ngferVq2.mjs";
3
+ import { _ as loadConfig$1, nt as realIo, s as configCorruptRepair, u as getConcurrencyLimits } from "./config-BZhXY15H.mjs";
4
+ import { d as quotedPath, u as plural } from "./command-output-BBvS1H6v.mjs";
5
+ import { l as gitQuietAsync, o as git } from "./operation-exec-CUZifp6Z.mjs";
6
+ import { r as readWorkspaceState$1 } from "./workspace-state-CPSp3mav.mjs";
7
+ import { $ as settingOrigin, Dt as listWorktreesAsync, E as iosSimSlimProfileSetting, G as resolveAndroidLayout, H as remoteAndroidSetting, Ht as filesystemDevice, Kt as temporaryRoot, L as projectSettingsContext, Lt as resolveSourceCheckoutAsync, Nt as repoRoot, O as mergeSettingsLayers, Pt as repoRootAsync, T as iosSimSlimDefaultSetting, Ut as makeTemporaryDirectory, W as remoteIosSetting, X as resolveSettings, a as SETTING_SHAPE_REMEDY, at as unknownSettingKeys, gt as dirtyFingerprintFiles, i as SETTINGS_WITH_RESOLVE_TIME_FALLBACK, kt as locallyKnownUpstreamAsync, m as defaultAndroidLayout, nt as settingValueAt, ot as webSettings, q as resolveIosProjectDir, r as PATH_SETTINGS, rt as settingsLayers, tt as settingShapeErrors, yt as gitCommonDirAsync } from "./settings-B5tCoq9N.mjs";
8
+ import { C as resolvePackageJson, _ as appProjectProblem, b as isPackageResolvable, v as detectIsExpo } from "./project-BiC68mIp.mjs";
9
+ import { ft as POOL_SETTING_REMEDY, k as hostSystemImageArch, o as androidHome, vt as parkedMaxSetting } from "./android-Cjcj8MCw.mjs";
10
+ import { Jn as providerFromConfig, Un as checkEasAuth$1, Wt as readInstalledEasCliVersionAsync, Xn as resolveEasCliBin, ar as easCliUpgradeRemedy, ir as easCliSupport, qn as ownerFromConfig, rr as MIN_EAS_CLI_SIMULATOR_VERSION } from "./budget-HyShrIpL.mjs";
11
+ import { R as listBuildSlots } from "./workspaces-C9w4aeXF.mjs";
12
+ import { N as listBuildLocks } from "./activity-BpjwrQXU.mjs";
13
+ import { d as fingerprintProject, o as diffFingerprintSources } from "./build-cache-CKCzxzxA.mjs";
14
+ import { L as readHostMemoryPressureAsync, N as hostMemoryPressureAdvice } from "./ios-BQzvJlzw.mjs";
15
+ import { p as resolveOptimizations, u as compilerCacheFallbackMessage } from "./errors-DHm_U5gv.mjs";
16
+ import { i as projectCmakeLauncher } from "./ccache-h1FKhZeg.mjs";
17
+ import { x as podInstallCommand } from "./xcode-CiIIDnuD.mjs";
18
+ import { g as androidPathRoomRemedy, i as ccacheEnabled, l as androidSdkRefusal, m as androidPathRoomMessage, p as androidPathRoom, t as apkOutputsDir } from "./react-native-build-CwZB-agu.mjs";
19
+ import { a as countLiveOwnedDevicesAsync, i as countLiveOwnedDevices } from "./device-capacity-ZYaRALv5.mjs";
20
+ import { t as readDoctorFingerprint } from "./doctor-fingerprint-zlujA1Gs.mjs";
21
+ import { i as probeSigningIdentities } from "./ios-signing-4c_qXvQm.mjs";
22
+ import { a as findChrome, t as CHROME_INSTALL_REMEDY } from "./chrome-BvV8ssI3.mjs";
23
+ import { i as installedNpmTreeIsValidAsync, n as hasInstalledDependencies, t as dependencyState } from "./dependency-state-BwNCYG5Q.mjs";
24
+ import { n as simslimIsOnPath } from "./simslim-BjxszUAb.mjs";
25
+ import { t as MIN_EAS_CLI_BUILD_DOWNLOAD_VERSION } from "./eas-build-CyDKNTBP.mjs";
26
+ import { r as resolveAndroidCompilerCache, t as readAndroidCasToolchain } from "./android-cas-BVqh2Zep.mjs";
27
27
  import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, rmSync } from "node:fs";
28
28
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
29
29
  import { LAST_BUILD_KEYS, isJsonObject, readBuildHistory, readJsonObject, readStats, settingDefinition } from "@stim-cli/core/state";
@@ -509,12 +509,12 @@ async function checkMainCheckout(projectRoot, { npmTreeValid, brokenPods = void
509
509
  podsState = "stale";
510
510
  }
511
511
  if (podsState) {
512
- const podCommand = `cd ${quotedPath(iosRoot)} && ${podInstallCommand(mainRoot)}`;
512
+ const podCommand = `cd ${quotedPath(iosRoot)} && ${podInstallCommand(mainRoot, iosRoot)}`;
513
513
  findings.push(finding("cost", `The source checkout CocoaPods state is ${podsState}`, `ios/Pods cannot be reused safely because its Manifest.lock ${podsState === "missing" ? "is absent" : "does not match ios/Podfile.lock"}.`, `Run \`${podCommand}\` before creating native worktrees, or let \`stim worktree warm --refresh\` run it from a linked worktree.`));
514
514
  }
515
515
  const broken = brokenPods === void 0 && existsSync$1(podsRoot) ? await brokenPodLinks(podsRoot) : brokenPods || [];
516
516
  if (broken.length) {
517
- const podCommand = `cd ${quotedPath(iosRoot)} && ${podInstallCommand(mainRoot, "--clean-install")}`;
517
+ const podCommand = `cd ${quotedPath(iosRoot)} && ${podInstallCommand(mainRoot, iosRoot, "--clean-install")}`;
518
518
  findings.push(finding("cost", "The source checkout CocoaPods state has broken links", `${broken.length} symlink${broken.length === 1 ? "" : "s"} under ios/Pods point to missing files. Worktrees copy these broken links and can fail during compilation. First: ${broken[0]}.`, `Run \`${podCommand}\` before creating native worktrees.`));
519
519
  }
520
520
  }
@@ -706,8 +706,12 @@ async function projectEasBuildDownloadFinding(projectRoot, remoteBackends, looku
706
706
  readEasCliVersion: () => version
707
707
  });
708
708
  }
709
- function checkSimSlim({ configured = false, profileError = null, onPath = false } = {}) {
709
+ function checkSimSlim({ configured = false, slimByDefault = false, profileError = null, onPath = false } = {}) {
710
710
  if (profileError) return finding("cost", "The SimSlim profile is invalid", profileError, "Set ios.simslimProfile to a readable JSON profile inside the repository.");
711
+ if (!configured && slimByDefault) {
712
+ if (onPath) return null;
713
+ return finding("cost", "ios.simslim is on, but SimSlim is not installed", "`stim ios` boots owned simulators without SimSlim until the `simslim` command is installed.", "brew install mobai-app/tap/simslim");
714
+ }
711
715
  if (!configured) return finding("note", "SimSlim is recommended for parallel iOS simulator work", "A reviewed profile can reduce background simulator services and memory use. It is optional: disabling services can affect tests that depend on them, and installing the binary alone does not apply a profile.", "Run `stim guide lifecycle simslim` to install SimSlim and configure ios.simslimProfile. Stim does not enable a profile through doctor --fix.");
712
716
  if (onPath) return null;
713
717
  return finding("cost", "A SimSlim profile is configured, but SimSlim is not installed", "`stim ios` needs the `simslim` command to apply the profile to its owned simulator.", "brew install mobai-app/tap/simslim");
@@ -780,10 +784,12 @@ async function runDoctor(projectRoot, options = {}, inspectors = []) {
780
784
  } catch (error) {
781
785
  simslimProfileError = String(error?.message || error);
782
786
  }
787
+ const simslimByDefault = localIos && iosSimSlimDefaultSetting(projectSettings);
783
788
  const simslimFinding = !localIos || !simslimProfile && !simslimProfileError && remoteIosSetting(projectSettings) ? null : checkSimSlim({
784
789
  configured: Boolean(simslimProfile),
790
+ slimByDefault: simslimByDefault,
785
791
  profileError: simslimProfileError,
786
- onPath: simslimProfile ? lookupSimSlim ? lookupSimSlim() : simslimIsOnPath() : false
792
+ onPath: simslimProfile || simslimByDefault ? lookupSimSlim ? lookupSimSlim() : simslimIsOnPath() : false
787
793
  });
788
794
  const memoryAdvice = localIos && !remoteIosSetting(projectSettings) ? hostMemoryPressureAdvice(await memoryPressure()) : null;
789
795
  const shared = [
@@ -904,7 +910,7 @@ function checkAndroidPathRoom(projectRoot, platform, host, hostArch = process.ar
904
910
  if (!room) return null;
905
911
  return {
906
912
  code: "android-path-room",
907
- ...finding("cost", "The project path leaves no room for Android native object paths", `${androidPathRoomMessage(room)} \`stim android\` refuses to build here with STIM_PATH_TOO_LONG, because Gradle would fail deep inside ninja instead.`, androidPathRoomRemedy(room))
913
+ ...finding("cost", "The project path leaves no room for Android native object paths", `${androidPathRoomMessage(room)} \`stim android\` refuses to run an emulator here with STIM_PATH_TOO_LONG, before it prepares the device, because Gradle would fail deep inside ninja instead.`, androidPathRoomRemedy(room))
908
914
  };
909
915
  }
910
916
  function hasAndroidProject(layout) {
@@ -965,7 +971,7 @@ function countActiveBuilds() {
965
971
  function checkFingerprintParity({ projectHash, worktreeHash, changed = [], dirtyFiles = [] } = {}) {
966
972
  if (!projectHash || !worktreeHash || projectHash === worktreeHash) return null;
967
973
  const names = changed.slice(0, 3).join(", ");
968
- return finding("note", "This checkout does not fingerprint like a fresh worktree of HEAD", `A clean detached worktree of HEAD computes a different @expo/fingerprint hash than this checkout, so worktrees will MISS the cache entries this checkout fills (and vice versa) until the two agree.${changed.length ? ` The differing source${changed.length === 1 ? "" : "s"}: ${names}${changed.length > 3 ? ` (and ${changed.length - 3} more)` : ""}.` : ""} ${dirtyFiles.length ? `The likely cause is uncommitted changes to tracked fingerprint inputs -- git reports ${dirtyFiles.slice(0, 3).join(", ")}${dirtyFiles.length > 3 ? ` (and ${dirtyFiles.length - 3} more)` : ""} dirty in this checkout.` : "The likely cause is uncommitted changes to tracked fingerprint inputs (this check compared against a clean worktree of HEAD)."} (To measure this, doctor ran a real fingerprint twice and briefly created a temporary git worktree -- .git/worktrees metadata was touched and cleaned up.)`, "Commit the dirty fingerprint inputs, or list the build-irrelevant ones in .fingerprintignore (same syntax as .gitignore, at the project root; Stim already ignores android/local.properties and android/.idea). Only the ones that genuinely cannot change the native build belong there -- generated reports, local env files, a lockfile whose checksums embed absolute machine paths. Never ignore a real native input (a Podfile, a gradle file, the app config) to force a hit: that trades a slow build for a wrong one.");
974
+ return finding("note", "This checkout does not fingerprint like a fresh worktree of HEAD", `A clean detached worktree of HEAD computes a different @expo/fingerprint hash than this checkout, so worktrees will MISS the cache entries this checkout fills (and vice versa) until the two agree.${changed.length ? ` The differing source${changed.length === 1 ? "" : "s"}: ${names}${changed.length > 3 ? ` (and ${changed.length - 3} more)` : ""}.` : ""} ${dirtyFiles.length ? `The likely cause is uncommitted changes to tracked fingerprint inputs -- git reports ${dirtyFiles.slice(0, 3).join(", ")}${dirtyFiles.length > 3 ? ` (and ${dirtyFiles.length - 3} more)` : ""} dirty in this checkout.` : "The likely cause is uncommitted changes to tracked fingerprint inputs (this check compared against a clean worktree of HEAD)."} (To measure this, doctor ran a real fingerprint twice and briefly created a temporary git worktree -- .git/worktrees metadata was touched and cleaned up.)`, "Commit the dirty fingerprint inputs, or list the build-irrelevant ones in .fingerprintignore (same syntax as .gitignore, at the project root; Stim already ignores android/local.properties, android/.idea, *.xcodeproj/xcuserdata, and ios/main.jsbundle and ios/assets while a .gitignore pattern matches them). Only the ones that genuinely cannot change the native build belong there -- generated reports, local env files, a lockfile whose checksums embed absolute machine paths. Never ignore a real native input (a Podfile, a gradle file, the app config) to force a hit: that trades a slow build for a wrong one.");
969
975
  }
970
976
  function fingerprintConfigSkipped(root) {
971
977
  const file = ["fingerprint.config.js", "fingerprint.config.cjs"].find((name) => existsSync$1(join$1(root, name)));
@@ -1,4 +1,4 @@
1
- import { t as getExecutor } from "./exec-DEoAhcze.mjs";
1
+ import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  //#region src/doctor-fingerprint.ts
4
4
  async function readDoctorFingerprint(operation, request) {
@@ -1,4 +1,4 @@
1
- import { l as fingerprintProject } from "./build-cache-Dv7RN200.mjs";
1
+ import { d as fingerprintProject } from "./build-cache-CKCzxzxA.mjs";
2
2
  import * as fingerprint from "@expo/fingerprint";
3
3
  //#region bin/doctor-fingerprint.ts
4
4
  let input = "";
@@ -1,17 +1,17 @@
1
- import { Y as doctorIo, _ as loadConfig$1, p as getProject } from "./config-DlrsduwG.mjs";
2
- import { f as refuseNoProject, l as phaseLine } from "./command-output-YKGWivpG.mjs";
3
- import { L as projectSettingsContextAsync, Mt as repoRoot } from "./settings-C7O8A6ZI.mjs";
4
- import { f as projectRegistry, t as NO_PROJECT_REFUSAL } from "./project-DhCtQWWU.mjs";
5
- import { c as inspectStimVersions, s as compareStimVersions } from "./eas-session-ledger-BQF9Yyy9.mjs";
6
- import { a as inspectBudget, cr as inspectWatchmanMemory, fr as memorySweepIsScoped, n as budgetLine } from "./budget-3ivAK99e.mjs";
7
- import { L as memoryCulpritFindings, R as readMemoryCulpritsAsync, f as listAllIosSimsAsync, h as listIosRuntimesAsync, l as iosRuntimeMatches, x as pickDefaultIosCreation } from "./ios-hcBpnEGk.mjs";
8
- import { c as detectXcodeMajorAsync } from "./xcode-Rq744mBF.mjs";
9
- import { s as offloadCheck } from "./client-B4MMzfo_.mjs";
10
- import { c as inspectBuildMachines, f as inspectDeviceHostMachines } from "./selection-DSMbWEX2.mjs";
11
- import { r as maintenanceStatus, t as maintenanceLine } from "./status-BRROykC8.mjs";
12
- import { a as writeIgnoreDirs, c as recordDoctorRun, i as watchedCheckouts, n as inspectNestedWorktrees, r as nestedWorktreeFinding } from "./doctor-watchman-iGBpC6KM.mjs";
13
- import { c as checkWorktreeStorageLayout, l as readMachineSettings, o as runDoctor } from "./doctor-HUC1igzw.mjs";
14
- import { h as resolveDeviceType, v as resolveRuntime } from "./support-TWuQlHQo.mjs";
1
+ import { Y as doctorIo, _ as loadConfig$1, p as getProject } from "./config-BZhXY15H.mjs";
2
+ import { f as refuseNoProject, l as phaseLine } from "./command-output-BBvS1H6v.mjs";
3
+ import { Nt as repoRoot, R as projectSettingsContextAsync } from "./settings-B5tCoq9N.mjs";
4
+ import { f as projectRegistry, t as NO_PROJECT_REFUSAL } from "./project-BiC68mIp.mjs";
5
+ import { c as inspectStimVersions, s as compareStimVersions } from "./eas-session-ledger-BMCA1gdO.mjs";
6
+ import { a as inspectBudget, dr as inspectWatchmanMemory, hr as memorySweepIsScoped, n as budgetLine } from "./budget-HyShrIpL.mjs";
7
+ import { B as memoryCulpritFindings, V as readMemoryCulpritsAsync, f as listAllIosSimsAsync, h as listIosRuntimesAsync, l as iosRuntimeMatches, x as pickDefaultIosCreation } from "./ios-BQzvJlzw.mjs";
8
+ import { c as detectXcodeMajorAsync } from "./xcode-CiIIDnuD.mjs";
9
+ import { s as offloadCheck } from "./client-BQsmyp_-.mjs";
10
+ import { l as inspectBuildMachines, p as inspectDeviceHostMachines } from "./selection-D5cxEl3t.mjs";
11
+ import { r as maintenanceStatus, t as maintenanceLine } from "./status-Fect2w9R.mjs";
12
+ import { a as writeIgnoreDirs, c as recordDoctorRun, i as watchedCheckouts, n as inspectNestedWorktrees, r as nestedWorktreeFinding } from "./doctor-watchman-BovI1y3-.mjs";
13
+ import { c as checkWorktreeStorageLayout, l as readMachineSettings, o as runDoctor } from "./doctor-Bm8TVpGn.mjs";
14
+ import { h as resolveDeviceType, v as resolveRuntime } from "./support-qKcbgmI5.mjs";
15
15
  import { isJsonObject, maintenanceNdjsonFile, readHostedAppMetadata, readHostedSessions } from "@stim-cli/core/state";
16
16
  import { dirname, join, sep } from "path";
17
17
  import chalk from "chalk";
@@ -1,8 +1,8 @@
1
- import { E as upsertProject, O as withConfigLockAsync$1, d as getConfigDir, p as getProject } from "./config-DlrsduwG.mjs";
2
- import { l as gitQuietAsync } from "./operation-exec-BW0em61G.mjs";
3
- import { Et as listWorktreesAsync, Nt as repoRootAsync } from "./settings-C7O8A6ZI.mjs";
4
- import { f as projectRegistry } from "./project-DhCtQWWU.mjs";
5
- import { d as parseWatchRoots, m as runWatchman, s as compareStimVersions } from "./eas-session-ledger-BQF9Yyy9.mjs";
1
+ import { E as upsertProject, O as withConfigLockAsync$1, d as getConfigDir, p as getProject } from "./config-BZhXY15H.mjs";
2
+ import { l as gitQuietAsync } from "./operation-exec-CUZifp6Z.mjs";
3
+ import { Dt as listWorktreesAsync, Pt as repoRootAsync } from "./settings-B5tCoq9N.mjs";
4
+ import { f as projectRegistry } from "./project-BiC68mIp.mjs";
5
+ import { d as parseWatchRoots, m as runWatchman, s as compareStimVersions } from "./eas-session-ledger-BMCA1gdO.mjs";
6
6
  import { mkdirSync, readFileSync, realpathSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
7
7
  import { dirname, isAbsolute, join, relative, sep } from "node:path";
8
8
  import { isJsonObject } from "@stim-cli/core/state";
@@ -1,7 +1,7 @@
1
- import { t as getExecutor, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
2
- import { a as killOnAbort, f as throwIfCancelled, r as childEnvironment } from "./operation-exec-BW0em61G.mjs";
3
- import { Zn as remoteCliInvocation, nr as easCliUpgradeRemedy, qn as resolveEasCliBin, tr as easCliSupport } from "./budget-3ivAK99e.mjs";
4
- import { M as acquireBuildLock, P as releaseBuildLock } from "./activity-BpWUPgUm.mjs";
1
+ import { D as ownership_claim_exports, c as throwIfCancelled, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
+ import { a as killOnAbort, r as childEnvironment } from "./operation-exec-CUZifp6Z.mjs";
3
+ import { Xn as resolveEasCliBin, ar as easCliUpgradeRemedy, er as remoteCliInvocation, ir as easCliSupport } from "./budget-HyShrIpL.mjs";
4
+ import { M as acquireBuildLock, P as releaseBuildLock } from "./activity-BpjwrQXU.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  import { existsSync, realpathSync, statSync } from "node:fs";
7
7
  //#region src/engine/eas-build.ts
@@ -1,15 +1,15 @@
1
- import { t as getExecutor } from "./exec-DEoAhcze.mjs";
2
- import { _ as loadConfig$1, p as getProject } from "./config-DlrsduwG.mjs";
3
- import { f as throwIfCancelled, r as childEnvironment } from "./operation-exec-BW0em61G.mjs";
4
- import { ct as detectProviders, lt as planMetroReach } from "./settings-C7O8A6ZI.mjs";
5
- import { M as readMetroTunnel, P as readRemoteSession } from "./project-DhCtQWWU.mjs";
6
- import { $n as MIN_EAS_CLI_DEVICE_VERSION, Hn as isEasAuthFailureText, Ht as readInstalledEasCliVersionAsync, Qn as remoteCommand, er as MIN_EAS_CLI_SIMULATOR_VERSION, qn as resolveEasCliBin, s as peekBudget, tr as easCliSupport } from "./budget-3ivAK99e.mjs";
7
- import { F as readHostMemoryPressureAsync } from "./ios-hcBpnEGk.mjs";
8
- import { d as hostingMachines, o as resolveBuildMachine, r as namedBuildMachine } from "./selection-DSMbWEX2.mjs";
9
- import { c as call, l as connectHost, p as requireHostedAppMode } from "./hosted-client-Bt-tndxV.mjs";
10
- import { r as readHostedNative, s as writeHostedNative } from "./ios-state-Dtw5K2aI.mjs";
11
- import { n as prepareHostedNative } from "./hosted-native-BmQC6U_x.mjs";
12
- import { c as peekDeviceSlots } from "./device-capacity-DH0QsZYZ.mjs";
1
+ import { c as throwIfCancelled, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
+ import { _ as loadConfig$1, p as getProject } from "./config-BZhXY15H.mjs";
3
+ import { r as childEnvironment } from "./operation-exec-CUZifp6Z.mjs";
4
+ import { lt as detectProviders, ut as planMetroReach } from "./settings-B5tCoq9N.mjs";
5
+ import { M as readMetroTunnel, P as readRemoteSession } from "./project-BiC68mIp.mjs";
6
+ import { Gn as isEasAuthFailureText, Wt as readInstalledEasCliVersionAsync, Xn as resolveEasCliBin, ir as easCliSupport, nr as MIN_EAS_CLI_DEVICE_VERSION, rr as MIN_EAS_CLI_SIMULATOR_VERSION, s as peekBudget, tr as remoteCommand } from "./budget-HyShrIpL.mjs";
7
+ import { L as readHostMemoryPressureAsync } from "./ios-BQzvJlzw.mjs";
8
+ import { f as hostingMachines, i as namedBuildMachine, s as resolveBuildMachine } from "./selection-D5cxEl3t.mjs";
9
+ import { c as call, l as connectHost, p as requireHostedAppMode } from "./hosted-client-rsRqysJc.mjs";
10
+ import { c as writeHostedNativeAsync, r as readHostedNative } from "./ios-state-CT9nV5SP.mjs";
11
+ import { i as prepareHostedNative } from "./hosted-native-BxTizGU2.mjs";
12
+ import { c as peekDeviceSlots } from "./device-capacity-ZYaRALv5.mjs";
13
13
  import { ambientEnv } from "@stim-cli/core";
14
14
  import { automaticMachineEnabled, isJsonObject, machineCapacity, parseHostedChoice, parseHostedNativeOffer } from "@stim-cli/core/state";
15
15
  //#region src/device-host/placement.ts
@@ -219,10 +219,11 @@ function viaEas(code, reason, skipped) {
219
219
  skipped
220
220
  };
221
221
  }
222
- async function automaticDevicePlacement({ root, slot, platform, selectors, appMode, buildMachine, noWait, eas, signal }, { machines = () => hostingMachines(void 0, signal), read = readHostedNative, write = writeHostedNative, resume = prepareHostedNative, peek = () => peekDeviceSlots({
222
+ async function automaticDevicePlacement({ root, slot, platform, selectors, appMode, buildMachine, noWait, eas, signal, localSims }, { machines = () => hostingMachines(void 0, signal), read = readHostedNative, write = writeHostedNativeAsync, resume = prepareHostedNative, peek = () => peekDeviceSlots({
223
223
  platform,
224
224
  project: getProject(root),
225
- slot
225
+ slot,
226
+ ...localSims ? { sources: { sims: localSims } } : {}
226
227
  }), capacity = machineCapacity, memory = () => readHostMemoryPressureAsync(void 0, void 0, signal), probe = probeHost, budget = (projectRoot) => peekBudget(projectRoot, {}, ambientEnv(), signal) } = {}) {
227
228
  const recorded = read(root, platform, slot)[slot];
228
229
  if (recorded) {
@@ -238,7 +239,7 @@ async function automaticDevicePlacement({ root, slot, platform, selectors, appMo
238
239
  skipped: [],
239
240
  sticky: true
240
241
  };
241
- write(root, slot, null, platform);
242
+ await write(root, slot, null, platform);
242
243
  }
243
244
  const devices = peek();
244
245
  if (devices.localLive) return {
@@ -1,9 +1,9 @@
1
- import { _ as reportSignal, t as getExecutor } from "./exec-DEoAhcze.mjs";
1
+ import { C as reportSignal, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  import { l as workspaceAgentDeviceDir, v as withDirLock$1, y as withDirLockAsync$1 } from "./paths-DQtTgsBf.mjs";
3
- import { G as projectDeviceSlots, V as deviceSlotKey } from "./config-DlrsduwG.mjs";
4
- import { a as formatElapsed, o as formatLongDuration, r as clockTime, u as plural } from "./command-output-YKGWivpG.mjs";
5
- import { n as isInsideProject } from "./metro-DiXtA3Ty.mjs";
6
- import { r as cdpEndpoint } from "./state--smjFSTL.mjs";
3
+ import { G as projectDeviceSlots, V as deviceSlotKey } from "./config-BZhXY15H.mjs";
4
+ import { a as formatElapsed, o as formatLongDuration, r as clockTime, u as plural } from "./command-output-BBvS1H6v.mjs";
5
+ import { n as isInsideProject } from "./metro-1pJgCX4U.mjs";
6
+ import { r as cdpEndpoint } from "./state-DMRNP7-4.mjs";
7
7
  import { accessSync, constants, existsSync, mkdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
8
8
  import { delimiter, dirname, join, resolve } from "node:path";
9
9
  import { workspaceId } from "@stim-cli/core";
@@ -681,11 +681,11 @@ function writeLedger(root, ledger) {
681
681
  throw error;
682
682
  }
683
683
  }
684
- function recordEasSessionClaim(claim, root = easMachineStateRoot()) {
684
+ function easSessionClaimWrite(claim, root) {
685
685
  assertEasMachineRootWritable(root);
686
686
  const normalized = validEasSessionClaim(claim.sessionId, claim);
687
687
  if (!normalized) throw new Error(`Invalid EAS session claim for ${claim.sessionId}.`);
688
- withDirLock$1(easSessionLedgerLock(root), () => {
688
+ return () => {
689
689
  const current = readEasSessionLedger(root);
690
690
  if (!current.safe) throw new Error(current.notice ?? "EAS ownership ledger is unreadable.");
691
691
  current.claims.set(normalized.sessionId, normalized);
@@ -693,7 +693,11 @@ function recordEasSessionClaim(claim, root = easMachineStateRoot()) {
693
693
  version: 1,
694
694
  claims: Object.fromEntries(current.claims)
695
695
  });
696
- }, { ensureParent: () => mkdirSync(dirname(easSessionLedgerLock(root)), { recursive: true }) });
696
+ };
697
+ }
698
+ /** Records the claim after waiting for the ledger lock without blocking the event loop. */
699
+ async function recordEasSessionClaim(claim, root = easMachineStateRoot()) {
700
+ await withDirLockAsync$1(easSessionLedgerLock(root), easSessionClaimWrite(claim, root), { ensureParent: () => mkdirSync(dirname(easSessionLedgerLock(root)), { recursive: true }) });
697
701
  }
698
702
  function removeEasSessionClaim(sessionId, root = easMachineStateRoot(), when = () => true) {
699
703
  const file = easSessionLedgerFile(root);