stim 1.23.1 → 1.24.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 (169) hide show
  1. package/README.md +3 -2
  2. package/dist/{acquire-artifact-BzYRDgaP.mjs → acquire-artifact-CEs02U2o.mjs} +2 -2
  3. package/dist/{act-vxiMwdf5.mjs → act-Cyvm8xYc.mjs} +40 -25
  4. package/dist/{activity-BpWUPgUm.mjs → activity-Dq3ZcdD8.mjs} +6 -6
  5. package/dist/{agent-device-usage-output-CUlLsbRt.mjs → agent-device-usage-output-CccomeE0.mjs} +5 -5
  6. package/dist/{android-C7sVmyI9.mjs → android-882m4hxX.mjs} +140 -46
  7. package/dist/{android-DtfRGLcc.mjs → android-BZppyPe_.mjs} +66 -46
  8. package/dist/{android-DR5lZ2Az.mjs → android-CX5IcRuf.mjs} +13 -3
  9. package/dist/{android-CLi6DSiS.mjs → android-DcztblCT.mjs} +5 -5
  10. package/dist/{android-cas-ngferVq2.mjs → android-cas-BtCOrNqb.mjs} +3 -3
  11. package/dist/android-cas-compiler.mjs +1 -1
  12. package/dist/api.d.mts +21 -4
  13. package/dist/api.mjs +32 -31
  14. package/dist/{artifact-Xvgibgzq.mjs → artifact-BR5VNArK.mjs} +17 -16
  15. package/dist/{artifact-DBI3DALs.mjs → artifact-Bdt_n9Jc.mjs} +17 -16
  16. package/dist/{artifact-platform-CXcmX_j3.mjs → artifact-platform-CMRc0M_r.mjs} +3 -3
  17. package/dist/{browser-web-BJN9ZHxB.mjs → browser-web-ycg9qWB8.mjs} +16 -17
  18. package/dist/{budget-3ivAK99e.mjs → budget-dPGuhNai.mjs} +101 -40
  19. package/dist/{build-Dv9s8Fz-.mjs → build-CaF574eS.mjs} +31 -28
  20. package/dist/{build-cache-Dv7RN200.mjs → build-cache-HFUQ9eLz.mjs} +152 -19
  21. package/dist/{build-plan-BmbdHQbr.mjs → build-plan-JsDUq4w1.mjs} +8 -7
  22. package/dist/{cache-manifest-DSeQjt-Q.mjs → cache-manifest-BPXRONJz.mjs} +1 -1
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{ccache-CH2EWGPB.mjs → ccache-CCn1S6qG.mjs} +6 -6
  25. package/dist/{cdp-3fwICjzi.mjs → cdp-BG3FJCCx.mjs} +1 -1
  26. package/dist/{chrome-Bbw689-6.mjs → chrome-BvV8ssI3.mjs} +1 -1
  27. package/dist/{cli-BkK6Wr5i.mjs → cli-xqAidP7O.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-B4MMzfo_.mjs → client-18-ZowoT.mjs} +254 -28
  30. package/dist/collector-run.mjs +6 -6
  31. package/dist/{command-output-YKGWivpG.mjs → command-output-DxC0k2rk.mjs} +3 -2
  32. package/dist/{config-DlrsduwG.mjs → config-BZhXY15H.mjs} +3 -3
  33. package/dist/{created-devices-x9rN6bhs.mjs → created-devices-D2Aca-xu.mjs} +6 -2
  34. package/dist/{dependency-state-1I9KZT1Y.mjs → dependency-state-C56ll9hY.mjs} +2 -2
  35. package/dist/{detached-entry-BwNEtIrP.mjs → detached-entry-KmieOKgN.mjs} +1 -1
  36. package/dist/{dev-client-BFxiDpkf.mjs → dev-client-w_fok0Ek.mjs} +3 -3
  37. package/dist/{device-B7ljwccX.mjs → device-4RUugw5X.mjs} +16 -16
  38. package/dist/{device-CiNYxqp6.mjs → device-BktRGdjS.mjs} +40 -44
  39. package/dist/{device-capacity-DH0QsZYZ.mjs → device-capacity-Ic-kdmEV.mjs} +20 -16
  40. package/dist/device-host-worker.mjs +17 -17
  41. package/dist/{device-ios-CbVDtDIy.mjs → device-ios-DzpSlZyd.mjs} +23 -52
  42. package/dist/{device-lease-run-DXPSwdbb.mjs → device-lease-run-DUtkbqBQ.mjs} +5 -5
  43. package/dist/{device-pool-B4iOXIrD.mjs → device-pool-CgBHk401.mjs} +3 -3
  44. package/dist/{doctor-DRu-8ld6.mjs → doctor-BZ6oxNum.mjs} +1 -1
  45. package/dist/{doctor-HUC1igzw.mjs → doctor-C33AzVfR.mjs} +28 -28
  46. package/dist/{doctor-C6t4Maue.mjs → doctor-DZgpqR6J.mjs} +14 -14
  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-watchman-iGBpC6KM.mjs → doctor-watchman-B453A231.mjs} +5 -5
  50. package/dist/{eas-build-DMWSSvxq.mjs → eas-build-CxKUNHsb.mjs} +4 -4
  51. package/dist/{eas-fallback-vKlrqxgE.mjs → eas-fallback-LMxk9Kw0.mjs} +14 -14
  52. package/dist/{eas-session-ledger-BQF9Yyy9.mjs → eas-session-ledger-Ck6YXPAO.mjs} +12 -8
  53. package/dist/{error-diagnostics-DYsjJIHz.mjs → error-diagnostics-BkKCZq4P.mjs} +17 -42
  54. package/dist/{exec-DEoAhcze.mjs → exec-VFRpu1iA.mjs} +116 -28
  55. package/dist/{gc-dDE4QPVu.mjs → gc-DDWEAj0w.mjs} +2 -2
  56. package/dist/{gc-BW8E1uSC.mjs → gc-yVKpAOKM.mjs} +205 -28
  57. package/dist/{guide-DYYEO3Wz.mjs → guide-Bggftwc5.mjs} +222 -59
  58. package/dist/{hosted-android-xcfgCgSF.mjs → hosted-android-D4dweBof.mjs} +4 -4
  59. package/dist/{hosted-client-Bt-tndxV.mjs → hosted-client-BBTVe3X6.mjs} +4 -4
  60. package/dist/{hosted-ios-y19jCYFF.mjs → hosted-ios-Sn0djzg8.mjs} +1 -1
  61. package/dist/{hosted-logs-DzJKzKlj.mjs → hosted-logs-CYIZ5ubJ.mjs} +11 -6
  62. package/dist/{hosted-macos-BJusKvqL.mjs → hosted-macos-CXjsUNBR.mjs} +7 -7
  63. package/dist/{hosted-native-BmQC6U_x.mjs → hosted-native-Doxbfzem.mjs} +58 -11
  64. package/dist/{idle-shutdown-CJmUOV5x.mjs → idle-shutdown-BInjLKqm.mjs} +10 -10
  65. package/dist/{ios-CWjqfSm_.mjs → ios-B1FXRCMX.mjs} +71 -44
  66. package/dist/{ios-DTOYZGMJ.mjs → ios-BItP6lkn.mjs} +8 -8
  67. package/dist/{ios-hcBpnEGk.mjs → ios-CVUFFZ6C.mjs} +70 -13
  68. package/dist/{ios-xtlRHaeB.mjs → ios-ENC4sRPA.mjs} +1 -1
  69. package/dist/{ios-device-BXZ0c7Kb.mjs → ios-device-B6HK951C.mjs} +1 -1
  70. package/dist/{ios-device-DFGuwF4U.mjs → ios-device-BI38NFFH.mjs} +3 -3
  71. package/dist/{ios-project-CSZYI1iu.mjs → ios-project-KYqeJURj.mjs} +5 -5
  72. package/dist/{ios-signing-BtAffm0A.mjs → ios-signing-4c_qXvQm.mjs} +2 -2
  73. package/dist/{ios-state-Dtw5K2aI.mjs → ios-state-DlElquYD.mjs} +15 -7
  74. package/dist/{js-swap-BSBHldmm.mjs → js-swap-BvrQvXHY.mjs} +7 -6
  75. package/dist/{launch-CP2wDCVd.mjs → launch-BVlyQw3T.mjs} +51 -49
  76. package/dist/{launch-D-zq8SHG.mjs → launch-SfzGH_s9.mjs} +48 -29
  77. package/dist/{logs-pNvA2hHK.mjs → logs-DXE32kyb.mjs} +16 -9
  78. package/dist/{logs-By5aw3g9.mjs → logs-ovlU7m7N.mjs} +8 -6
  79. package/dist/{macos-CPMahOC2.mjs → macos-B3BveDrU.mjs} +1 -1
  80. package/dist/{macos-C67FZ2ft.mjs → macos-CCfhb-jT.mjs} +49 -42
  81. package/dist/macos-run.mjs +1 -1
  82. package/dist/maintenance-run.mjs +7 -7
  83. package/dist/{metro-DiXtA3Ty.mjs → metro-Bu8LBfzS.mjs} +4 -4
  84. package/dist/{metro-gateway-CKZqKqx7.mjs → metro-gateway-DtsOy-0P.mjs} +3 -4
  85. package/dist/{named-ports-DkEzOfzO.mjs → named-ports-BWDuU5oQ.mjs} +3 -3
  86. package/dist/{native-android-_MWSs3PP.mjs → native-android-96BBizbq.mjs} +17 -17
  87. package/dist/{native-gradle-artifact-inputs-DHFnmrVf.mjs → native-gradle-artifact-inputs-BcLYBZil.mjs} +5 -5
  88. package/dist/{native-run-Dv88i0aU.mjs → native-run-BmH7U8pr.mjs} +6 -6
  89. package/dist/{native-runtime-DBRfY_PN.mjs → native-runtime-DgtJkzIa.mjs} +10 -9
  90. package/dist/{native-source-Y0yLhFyQ.mjs → native-source-D-4Dh4JU.mjs} +7 -4
  91. package/dist/{native-xcode-inputs-CqViUh3r.mjs → native-xcode-inputs-irplbQb0.mjs} +2 -2
  92. package/dist/{native-xcode-ios-vFgqL_yS.mjs → native-xcode-ios-BY-6hh6M.mjs} +18 -18
  93. package/dist/offload-worker.d.mts +7 -2
  94. package/dist/offload-worker.mjs +75 -41
  95. package/dist/{operation-exec-BW0em61G.mjs → operation-exec-CUZifp6Z.mjs} +2 -25
  96. package/dist/{ownership-C5fo5Edb.mjs → ownership-DxlZGDcV.mjs} +3 -3
  97. package/dist/{page-DBL2PiUU.mjs → page-CzEA_-5_.mjs} +2 -3
  98. package/dist/phone-reverses-BdsdesVF.mjs +57 -0
  99. package/dist/{placement-log-BnGgJRRZ.mjs → placement-log-DUvqqsB-.mjs} +1 -1
  100. package/dist/{plan-placement-cr0fEU7b.mjs → plan-placement-4axc0Hs7.mjs} +3 -3
  101. package/dist/{ports-DpXjKkSV.mjs → ports-D-E_OiAO.mjs} +3 -3
  102. package/dist/{prebuild-BligW0QS.mjs → prebuild-DmVCf5xb.mjs} +14 -9
  103. package/dist/{project-DhCtQWWU.mjs → project-Dz-hWkb-.mjs} +21 -17
  104. package/dist/{pull-request-W1IuLXDt.mjs → pull-request-CbNlkFok.mjs} +2 -2
  105. package/dist/pull-requests.mjs +1 -1
  106. package/dist/{react-native-android-ZlhQfhvq.mjs → react-native-android-DOinxgwB.mjs} +75 -32
  107. package/dist/{react-native-build-CelbTO_y.mjs → react-native-build-AuCu-aAP.mjs} +22 -19
  108. package/dist/{react-native-doctor-LTIaP7lv.mjs → react-native-doctor-2ivJUmwZ.mjs} +10 -9
  109. package/dist/{react-native-ios-C5W0SA6f.mjs → react-native-ios-D5zTIuH8.mjs} +38 -22
  110. package/dist/{recordings-CQmfzAh7.mjs → recordings-CdPwYwvs.mjs} +1 -1
  111. package/dist/{registration-BcRgF6Ox.mjs → registration-CN6nlhcD.mjs} +1 -1
  112. package/dist/{reload-COJWTbae.mjs → reload-C1TTVesC.mjs} +144 -42
  113. package/dist/{reload-QcwnYLYV.mjs → reload-Ck9RJeSq.mjs} +1 -1
  114. package/dist/{remote-DR8qUERM.mjs → remote-DEZ7AOVq.mjs} +7 -7
  115. package/dist/{result-utnBea7x.mjs → result-DqBrb12U.mjs} +40 -17
  116. package/dist/{run-DidHghD1.mjs → run-BIwoU44q.mjs} +2 -2
  117. package/dist/{selection-DSMbWEX2.mjs → selection-BLtvaqxc.mjs} +11 -5
  118. package/dist/{server-bare-CafzuyFB.mjs → server-bare-Z1ToVLPn.mjs} +2 -2
  119. package/dist/{server-command-B9o92sLM.mjs → server-command-C0pmjNdG.mjs} +5 -5
  120. package/dist/server-expo-CEntXzRw.mjs +2 -0
  121. package/dist/{server-expo-BXrWxNYh.mjs → server-expo-Tt_hLRpy.mjs} +8 -5
  122. package/dist/{settings-C7O8A6ZI.mjs → settings-RKwY33wv.mjs} +114 -19
  123. package/dist/{settings-PfJx8uK1.mjs → settings-kkt0vP4w.mjs} +1 -1
  124. package/dist/{settings-write-Chuy7Cte.mjs → settings-write--gj6MACV.mjs} +7 -7
  125. package/dist/settings.schema.json +13 -0
  126. package/dist/{simslim-BNckWpXi.mjs → simslim-CdWKT3vA.mjs} +2 -2
  127. package/dist/{slot-launch-B7AuoWJv.mjs → slot-launch-A1BgotaM.mjs} +6 -6
  128. package/dist/{stage-C4u17aES.mjs → stage-ERTMh88n.mjs} +2 -3
  129. package/dist/{start-CU8mCPC7.mjs → start-BKGrEhzG.mjs} +75 -35
  130. package/dist/{start-BL_BsiWt.mjs → start-Bmg_qmHi.mjs} +1 -1
  131. package/dist/{state--smjFSTL.mjs → state-B1ig0Kqy.mjs} +4 -4
  132. package/dist/{state-08I3hw3_.mjs → state-BfAltYJP.mjs} +2 -2
  133. package/dist/{stats-CO6sK0Nh.mjs → stats-B-ckuiUg.mjs} +5 -5
  134. package/dist/{stats-report-BzaPrRm6.mjs → stats-report-n2U5plhk.mjs} +1 -1
  135. package/dist/{status-_WPHzVft.mjs → status-DfFp6a76.mjs} +24 -24
  136. package/dist/{status-BRROykC8.mjs → status-Fect2w9R.mjs} +1 -1
  137. package/dist/{status-CrJutl6-.mjs → status-Pw-807f0.mjs} +1 -1
  138. package/dist/{status-watch-BHFasOZN.mjs → status-watch-XC7F-AMf.mjs} +5 -5
  139. package/dist/status-worker.mjs +1 -1
  140. package/dist/stim-clonefile.c +18 -0
  141. package/dist/{stim-desktop-D5OGpYZM.mjs → stim-desktop-DS0mzR8U.mjs} +2 -2
  142. package/dist/{stop-iuFHjUST.mjs → stop-BFu7X_Do.mjs} +2 -2
  143. package/dist/{stop-BJ06ipTZ.mjs → stop-CL1kDHds.mjs} +55 -21
  144. package/dist/{stop-CR5689oB.mjs → stop-DhclRwOO.mjs} +5 -5
  145. package/dist/supervisor-run.mjs +16 -16
  146. package/dist/{support-TWuQlHQo.mjs → support-B1W-hmC2.mjs} +8 -8
  147. package/dist/{support-CbXPbUMJ.mjs → support-B3tzVhKn.mjs} +6 -6
  148. package/dist/{swiftpm-artifact-inputs-DFcGsXDP.mjs → swiftpm-artifact-inputs-BWYPj9Sn.mjs} +4 -4
  149. package/dist/{swiftpm-macos-DbwGCpZg.mjs → swiftpm-macos-BVCP5mO4.mjs} +14 -13
  150. package/dist/{toolchain-XkA2PfJZ.mjs → toolchain-BjgKdoEf.mjs} +1 -1
  151. package/dist/{toolchain-B9hCFCQw.mjs → toolchain-D3bmRMia.mjs} +57 -36
  152. package/dist/trigger-BLsHgAGR.mjs +2 -0
  153. package/dist/{trigger-Cbyc41d_.mjs → trigger-CBMe2YLH.mjs} +2 -2
  154. package/dist/{warm-progress-CA3TgT3-.mjs → warm-progress-ol0ZypEu.mjs} +6 -6
  155. package/dist/{web-DRF_oFXk.mjs → web-BH7peScT.mjs} +12 -10
  156. package/dist/web-BdOFlTJr.mjs +2 -0
  157. package/dist/web-run.mjs +8 -9
  158. package/dist/windows-report.mjs +12 -1
  159. package/dist/windows-report.ps1 +1 -1
  160. package/dist/{workspace-state-U08dEzhG.mjs → workspace-state-CeBpIZgr.mjs} +11 -4
  161. package/dist/{workspaces-e41xsjKr.mjs → workspaces-CSV2Orf4.mjs} +36 -32
  162. package/dist/{worktree-BEwxVwKF.mjs → worktree-DEDUzO_L.mjs} +1 -1
  163. package/dist/{worktree-B4Nj3EGS.mjs → worktree-Dw8kfacb.mjs} +324 -99
  164. package/dist/{xcode-Rq744mBF.mjs → xcode-DHu41qQ4.mjs} +41 -27
  165. package/package.json +7 -7
  166. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +0 -211
  167. package/dist/server-expo-Ddr8cG_c.mjs +0 -2
  168. package/dist/trigger-yb_nFzPF.mjs +0 -2
  169. package/dist/web-kDE9Myoy.mjs +0 -2
@@ -1,10 +1,11 @@
1
- import { t as getExecutor } from "./exec-DEoAhcze.mjs";
1
+ import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  import { d as workspaceDir, m as workspaceLogsDir$1 } from "./paths-DQtTgsBf.mjs";
3
- import { B as deviceSlotFileKey, et as parseMachine$1, q as validateDeviceSlot } from "./config-DlrsduwG.mjs";
4
- import { l as phaseLine } from "./command-output-YKGWivpG.mjs";
5
- import { n as macosDir } from "./state-08I3hw3_.mjs";
3
+ import { B as deviceSlotFileKey, et as parseMachine$1, q as validateDeviceSlot } from "./config-BZhXY15H.mjs";
4
+ import { l as phaseLine } from "./command-output-DxC0k2rk.mjs";
5
+ import { n as macosDir } from "./state-BfAltYJP.mjs";
6
+ import { n as androidLogGroups, r as isAndroidCrashText } from "./android-CX5IcRuf.mjs";
6
7
  import { r as createNdjsonWriter } from "./ndjson-CgE_o3Dl.mjs";
7
- import { c as call } from "./hosted-client-Bt-tndxV.mjs";
8
+ import { c as call } from "./hosted-client-BBTVe3X6.mjs";
8
9
  import { mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
9
10
  import { dirname, join } from "node:path";
10
11
  import { LOG_ROTATE_BYTES, ambientWrite, withDirLockAsync } from "@stim-cli/core";
@@ -150,6 +151,9 @@ function readCursor(root, session, target) {
150
151
  } catch {}
151
152
  }
152
153
  const sameCursor = (a, b) => JSON.stringify(Object.entries(a ?? {}).toSorted()) === JSON.stringify(Object.entries(b ?? {}).toSorted());
154
+ function androidCrashRecords(records) {
155
+ return new Set(androidLogGroups(records).filter((group) => isAndroidCrashText(group.map((record) => record.msg ?? "").join("\n"))).flat());
156
+ }
153
157
  async function commitPage(root, session, before, records, cursor, target) {
154
158
  if (!records.length && sameCursor(before, cursor)) return;
155
159
  const directory = logsStateDir(root, target);
@@ -158,12 +162,13 @@ async function commitPage(root, session, before, records, cursor, target) {
158
162
  if (records.length) {
159
163
  const writer = createNdjsonWriter(hostLogFile(root, target), { maxBytes: LOG_ROTATE_BYTES });
160
164
  try {
165
+ const crashes = target.platform === "android" ? androidCrashRecords(records) : /* @__PURE__ */ new Set();
161
166
  for (const record of records) writer.write(target.platform !== "macos" ? {
162
167
  ...record,
163
168
  src: "device",
164
169
  platform: target.platform,
165
170
  slot: target.slot,
166
- event: "hosted_native_log"
171
+ event: crashes.has(record) ? "native_crash" : "hosted_native_log"
167
172
  } : record);
168
173
  } finally {
169
174
  writer.close();
@@ -1,9 +1,9 @@
1
- import { a as removeAgentAccess, i as agentAccess, r as closeAgentConnection, t as pullHostedMacosLogs } from "./hosted-logs-DzJKzKlj.mjs";
2
- import { l as phaseLine } from "./command-output-YKGWivpG.mjs";
3
- import { u as cancellableSleep } from "./operation-exec-BW0em61G.mjs";
4
- import { n as macosDir } from "./state-08I3hw3_.mjs";
5
- import { d as runCancellationSignal } from "./native-run-Dv88i0aU.mjs";
6
- import { _ as unknownSession, a as SESSION_TIMEOUT_MS, c as call, d as hostedSession, g as stoppedSession, h as sha256, i as RESERVE_TIMEOUT_MS, l as connectHost, m as settle, o as attach, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as upload } from "./hosted-client-Bt-tndxV.mjs";
1
+ import { o as cancellableSleep } from "./exec-VFRpu1iA.mjs";
2
+ import { a as removeAgentAccess, i as agentAccess, r as closeAgentConnection, t as pullHostedMacosLogs } from "./hosted-logs-CYIZ5ubJ.mjs";
3
+ import { l as phaseLine } from "./command-output-DxC0k2rk.mjs";
4
+ import { n as macosDir } from "./state-BfAltYJP.mjs";
5
+ import { d as runCancellationSignal } from "./native-run-BmH7U8pr.mjs";
6
+ import { _ as unknownSession, a as SESSION_TIMEOUT_MS, c as call, d as hostedSession, g as stoppedSession, h as sha256, i as RESERVE_TIMEOUT_MS, l as connectHost, m as settle, o as attach, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as upload } from "./hosted-client-BBTVe3X6.mjs";
7
7
  import { randomUUID } from "node:crypto";
8
8
  import { join } from "node:path";
9
9
  import { ambientContext, ambientWrite } from "@stim-cli/core";
@@ -51,7 +51,7 @@ async function placeHostedMacos(host, { root, bundle, bundleId, handoff, argumen
51
51
  setting: "hosting.agentDriver"
52
52
  }
53
53
  };
54
- reserved(placement);
54
+ await reserved(placement);
55
55
  session = await settle(host, session, ["preparing"], PREPARE_TIMEOUT_MS, "macos", runCancellationSignal(ambientContext()));
56
56
  if (session.state === "unknown") throw unknownSession(host, session);
57
57
  if (session.state === "stopped") throw stoppedSession(host, session);
@@ -1,11 +1,11 @@
1
+ import { o as cancellableSleep } from "./exec-VFRpu1iA.mjs";
1
2
  import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
2
- import { a as removeAgentAccess, i as agentAccess, n as pullHostedNativeLogs, r as closeAgentConnection } from "./hosted-logs-DzJKzKlj.mjs";
3
- import { u as cancellableSleep } from "./operation-exec-BW0em61G.mjs";
4
- import { l as withWorkspaceStateLockAsync, r as readWorkspaceState$1 } from "./workspace-state-U08dEzhG.mjs";
5
- import { d as runCancellationSignal } from "./native-run-Dv88i0aU.mjs";
6
- import { _ as unknownSession, a as SESSION_TIMEOUT_MS, c as call, d as hostedSession, g as stoppedSession, h as sha256, i as RESERVE_TIMEOUT_MS, l as connectHost, m as settle, n as OFFER_TIMEOUT_MS, o as attach, p as requireHostedAppMode, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as upload } from "./hosted-client-Bt-tndxV.mjs";
7
- import { a as requireHostedMetro, i as requestHostedMetro, n as closeHostedMetro } from "./metro-gateway-CKZqKqx7.mjs";
8
- import { s as writeHostedNative } from "./ios-state-Dtw5K2aI.mjs";
3
+ import { a as removeAgentAccess, i as agentAccess, n as pullHostedNativeLogs, r as closeAgentConnection } from "./hosted-logs-CYIZ5ubJ.mjs";
4
+ import { l as withWorkspaceStateLockAsync, r as readWorkspaceState$1 } from "./workspace-state-CeBpIZgr.mjs";
5
+ import { d as runCancellationSignal } from "./native-run-BmH7U8pr.mjs";
6
+ import { _ as unknownSession, a as SESSION_TIMEOUT_MS, c as call, d as hostedSession, g as stoppedSession, h as sha256, i as RESERVE_TIMEOUT_MS, l as connectHost, m as settle, n as OFFER_TIMEOUT_MS, o as attach, p as requireHostedAppMode, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as upload } from "./hosted-client-BBTVe3X6.mjs";
7
+ import { a as requireHostedMetro, i as requestHostedMetro, n as closeHostedMetro } from "./metro-gateway-DtsOy-0P.mjs";
8
+ import { s as writeHostedNative } from "./ios-state-DlElquYD.mjs";
9
9
  import { randomUUID } from "node:crypto";
10
10
  import { readFileSync } from "node:fs";
11
11
  import { join } from "node:path";
@@ -81,6 +81,50 @@ async function reserveHostedNative(host, target, params, platform) {
81
81
  throw Object.assign(/* @__PURE__ */ new Error(`${error instanceof Error ? error.message : String(error)} Retry stim ${platform} --remote auto; the build already targets ${host.machine}'s architecture.`), { remedy: `Retry stim ${platform} --remote auto.` });
82
82
  }
83
83
  }
84
+ const HOST_PORT_WINDOW = 64;
85
+ const devClientPortRemedy = (machine) => `Run stim stop, then stim ios --remote ${machine} without stim start, so Stim starts Metro on a port free on both Macs. If metro.port or STIM_METRO_PORT pins the port, pin one free on both Macs instead.`;
86
+ const devClientPortBusy = (machine, port) => ({
87
+ code: "STIM_HOSTING_REFUSED",
88
+ message: `${machine}: Port ${port} is in use on ${machine}, and an Expo dev client loads its bundle from this workspace's Metro port.`,
89
+ remedy: devClientPortRemedy(machine)
90
+ });
91
+ /**
92
+ * Answers whether a port is free for an Expo dev-client bridge on `machine`, asking the host for a window of ports at
93
+ * a time. A host without `hosted-metro-ports`, or one that cannot answer, counts every port as free; the bridge's own
94
+ * bind check still refuses an occupied one.
95
+ */
96
+ function hostedMetroPortProbe(machine, note) {
97
+ let window = null;
98
+ let unknown = false;
99
+ return async (port) => {
100
+ if (unknown) return true;
101
+ if (!window || port < window.from || port >= window.from + HOST_PORT_WINDOW) {
102
+ const ports = Array.from({ length: Math.min(HOST_PORT_WINDOW, 65536 - port) }, (_, index) => port + index);
103
+ let host;
104
+ try {
105
+ host = await connectHost(machine, void 0, false, runCancellationSignal(ambientContext()));
106
+ if (!host.connection.supports("hosted-metro-ports")) {
107
+ unknown = true;
108
+ return true;
109
+ }
110
+ const { busy } = await call(host, "device-host.metro.ports", { ports });
111
+ if (!Array.isArray(busy) || busy.some((each) => !Number.isInteger(each))) throw new Error(`${machine} answered device-host.metro.ports without its busy ports.`);
112
+ window = {
113
+ from: port,
114
+ busy: new Set(busy)
115
+ };
116
+ } catch (error) {
117
+ runCancellationSignal(ambientContext())?.throwIfAborted();
118
+ unknown = true;
119
+ note(`Could not check which Metro ports are free on ${machine} (${error instanceof Error ? error.message : String(error)}); choosing one free here`);
120
+ return true;
121
+ } finally {
122
+ host?.connection.close();
123
+ }
124
+ }
125
+ return !window.busy.has(port);
126
+ };
127
+ }
84
128
  async function placeHostedNative(target, { root, slot, bundle, handoff, bundleId, selectors, release, mode = release ? "release" : "development", devClientScheme, reserved, note, enterPhase = () => {}, metro = requestHostedMetro, metroPort, platform = "ios" }) {
85
129
  let host = target.host;
86
130
  try {
@@ -112,7 +156,7 @@ async function placeHostedNative(target, { root, slot, bundle, handoff, bundleId
112
156
  setting: "hosting.agentDriver"
113
157
  }
114
158
  };
115
- reserved(placement);
159
+ await reserved(placement);
116
160
  session = await settle(host, session, ["preparing"], PREPARE_TIMEOUT_MS, platform, runCancellationSignal(ambientContext()));
117
161
  if (session.state === "stopped") throw stoppedSession(host, session);
118
162
  if (session.state !== "ready") throw unknownSession(host, session);
@@ -122,13 +166,16 @@ async function placeHostedNative(target, { root, slot, bundle, handoff, bundleId
122
166
  ...placement,
123
167
  device
124
168
  };
125
- reserved(placement);
169
+ await reserved(placement);
126
170
  if (mode === "development") {
127
171
  const gateway = await metro(root, session.id, host.credential);
128
172
  await call(host, "device-host.metro.open", {
129
173
  session: session.id,
130
174
  ...gateway,
131
- ...platform === "android" ? { clientMetroPort: metroPort } : {}
175
+ ...platform === "android" || devClientScheme ? { clientMetroPort: metroPort } : {}
176
+ }).catch((error) => {
177
+ if (platform === "ios" && devClientScheme && error.code === "device-busy") throw Object.assign(error, { remedy: devClientPortRemedy(host.machine) });
178
+ throw error;
132
179
  });
133
180
  } else {
134
181
  await call(host, "device-host.metro.close", { session: session.id });
@@ -283,4 +330,4 @@ async function stopHostedNative(root, slot, signal, platform = "ios") {
283
330
  if (failures.length) throw new Error(failures.join("\n"));
284
331
  }
285
332
  //#endregion
286
- export { prepareHostedNative as n, stopHostedNative as r, placeHostedNative as t };
333
+ export { stopHostedNative as a, prepareHostedNative as i, hostedMetroPortProbe as n, placeHostedNative as r, devClientPortBusy as t };
@@ -1,11 +1,11 @@
1
- import { V as deviceSlotKey, _ as loadConfig$1 } from "./config-DlrsduwG.mjs";
2
- import { o as formatLongDuration } from "./command-output-YKGWivpG.mjs";
3
- import { o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-U08dEzhG.mjs";
4
- import { A as workspaceBuildInProgress, T as collectOwnedDeviceActivity } from "./budget-3ivAK99e.mjs";
1
+ import { V as deviceSlotKey, _ as loadConfig$1 } from "./config-BZhXY15H.mjs";
2
+ import { o as formatLongDuration } from "./command-output-DxC0k2rk.mjs";
3
+ import { r as readWorkspaceState$1, s as updateWorkspaceStateAsync } from "./workspace-state-CeBpIZgr.mjs";
4
+ import { A as workspaceBuildInProgress, T as collectOwnedDeviceActivity } from "./budget-dPGuhNai.mjs";
5
5
  import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
6
- import { D as teardownOwnedAvd, k as teardownOwnedIosSim } from "./workspaces-e41xsjKr.mjs";
7
- import { _ as workspaceDeviceLastUseAt } from "./activity-BpWUPgUm.mjs";
8
- import { d as listAllIosSims } from "./ios-hcBpnEGk.mjs";
6
+ import { A as teardownOwnedIosSim, O as teardownOwnedAvd } from "./workspaces-CSV2Orf4.mjs";
7
+ import { _ as workspaceDeviceLastUseAt } from "./activity-Dq3ZcdD8.mjs";
8
+ import { d as listAllIosSims } from "./ios-CVUFFZ6C.mjs";
9
9
  import { DEVICE_IDLE_SHUTDOWN_KEY, DEVICE_RECLAIM_REASON, readDeviceIdleShutdowns } from "@stim-cli/core/state";
10
10
  //#region src/devices/idle-shutdown.ts
11
11
  const SIM_LIST_TIMEOUT_MS = 1e4;
@@ -82,7 +82,7 @@ async function shutDownIdleDevices(root, idleMs, log, now = Date.now(), { only,
82
82
  shutDown++;
83
83
  const idleMinutes = Math.floor(idleForMs / MINUTE_MS);
84
84
  try {
85
- updateWorkspaceState(root, (state) => ({
85
+ await updateWorkspaceStateAsync(root, (state) => ({
86
86
  ...state,
87
87
  [DEVICE_IDLE_SHUTDOWN_KEY]: {
88
88
  ...readDeviceIdleShutdowns(state),
@@ -114,10 +114,10 @@ async function shutDownIdleDevices(root, idleMs, log, now = Date.now(), { only,
114
114
  return shutDown;
115
115
  }
116
116
  /** Forgets the slot's idle shutdown once a run boots its device again. */
117
- function clearDeviceIdleShutdown(root, platform, slot = "default") {
117
+ async function clearDeviceIdleShutdown(root, platform, slot = "default") {
118
118
  const key = deviceSlotKey(platform, slot);
119
119
  if (!(key in readDeviceIdleShutdowns(readWorkspaceState$1(root)))) return;
120
- updateWorkspaceState(root, (state) => {
120
+ await updateWorkspaceStateAsync(root, (state) => {
121
121
  const { [key]: _cleared, ...rest } = readDeviceIdleShutdowns(state);
122
122
  const { [DEVICE_IDLE_SHUTDOWN_KEY]: _all, ...others } = state;
123
123
  return Object.keys(rest).length ? {
@@ -1,33 +1,34 @@
1
1
  import { m as workspaceLogsDir$1 } from "./paths-DQtTgsBf.mjs";
2
- import { B as deviceSlotFileKey, W as parseDeviceSlotOption, q as validateDeviceSlot } from "./config-DlrsduwG.mjs";
3
- import { _ as stepTimer, g as stepClock, i as formatDuration, l as phaseLine } from "./command-output-YKGWivpG.mjs";
4
- import { i as recordWorkspaceUse } from "./workspace-state-U08dEzhG.mjs";
5
- import { C as iosSigningIdentitySha1Setting, L as projectSettingsContextAsync, N as metroWarmupUrlSetting, R as publicUrlSetting, S as iosSigningIdentitySettingError, _ as iosLanHostSetting, a as SETTING_SHAPE_REMEDY, g as deviceReclaimIdleMinutesSetting, j as metroPortSetting, rt as tunnelModeSetting, v as iosLanHostSettingError, w as iosSigningIdentitySha1SettingError, x as iosSigningIdentitySetting } from "./settings-C7O8A6ZI.mjs";
6
- import { L as workspaceDevServerMode, t as NO_PROJECT_REFUSAL } from "./project-DhCtQWWU.mjs";
7
- import { H as tapBuildLog, In as runProcessOperation, Lt as binOnPath, M as NO_BUILD_PROGRESS, Pn as exitAfterFlush, U as createRunRecorder, V as startBuildProgress, Y as statsProjectKey$1, cn as DEFAULT_METRO_PORT, rr as ownedSessionName } from "./budget-3ivAK99e.mjs";
8
- import { d as runCancellationSignal, f as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-Dv88i0aU.mjs";
9
- import { _t as parkedMaxSetting, dt as POOL_SETTING_REMEDY } from "./android-C7sVmyI9.mjs";
10
- import { i as createIosSimSnapshot } from "./ios-hcBpnEGk.mjs";
2
+ import { B as deviceSlotFileKey, W as parseDeviceSlotOption, q as validateDeviceSlot } from "./config-BZhXY15H.mjs";
3
+ import { _ as stepTimer, g as stepClock, i as formatDuration, l as phaseLine } from "./command-output-DxC0k2rk.mjs";
4
+ import { a as recordWorkspaceUseAsync } from "./workspace-state-CeBpIZgr.mjs";
5
+ import { C as iosSigningIdentitySha1Setting, L as projectSettingsContextAsync, N as metroWarmupUrlSetting, R as publicUrlSetting, S as iosSigningIdentitySettingError, _ as iosLanHostSetting, a as SETTING_SHAPE_REMEDY, g as deviceReclaimIdleMinutesSetting, j as metroPortSetting, rt as tunnelModeSetting, v as iosLanHostSettingError, w as iosSigningIdentitySha1SettingError, x as iosSigningIdentitySetting } from "./settings-RKwY33wv.mjs";
6
+ import { L as workspaceDevServerMode, t as NO_PROJECT_REFUSAL } from "./project-Dz-hWkb-.mjs";
7
+ import { ft as POOL_SETTING_REMEDY, vt as parkedMaxSetting } from "./android-882m4hxX.mjs";
8
+ import { G as createRunRecorder, H as startBuildProgress, In as exitAfterFlush, M as NO_BUILD_PROGRESS, Rn as runProcessOperation, U as tapBuildLog, V as runFailureRecord, W as thrownRunFailureRecord, Z as statsProjectKey$1, ar as ownedSessionName, un as DEFAULT_METRO_PORT, zt as binOnPath } from "./budget-dPGuhNai.mjs";
9
+ import { d as runCancellationSignal, f as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-BmH7U8pr.mjs";
10
+ import { i as createIosSimSnapshot } from "./ios-CVUFFZ6C.mjs";
11
11
  import { d as optimizationBuildProfile, l as artifactCachePolicy } from "./errors-ccaPc4ox.mjs";
12
- import { t as COMPILATION_CACHE_NOT_RUN } from "./xcode-Rq744mBF.mjs";
13
- import { d as simulatorRuntime, h as setRemoteLogSink } from "./client-B4MMzfo_.mjs";
14
- import { i as parseBuildMachineOption } from "./selection-DSMbWEX2.mjs";
15
- import { r as hostedMetroSettings } from "./metro-gateway-CKZqKqx7.mjs";
16
- import { i as writeDevicePlacement } from "./ios-state-Dtw5K2aI.mjs";
17
- import { r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-B7AuoWJv.mjs";
18
- import { f as waitFlagConflict, o as leaseExpiryText } from "./device-lease-run-DXPSwdbb.mjs";
19
- import { _ as resolveIosWait, a as deviceModelRefusal, b as resolveSimulatorAppFlag, c as iosProjectPathError, d as ownedSimFailure, g as resolveIosBuildSetup, h as resolveDeviceType, i as deviceLabel, m as resolveConfiguration, n as buildLogFile, r as createIosDeviceWaitRun, u as isReleaseConfiguration, v as resolveRuntime, x as simulatorBuildArch, y as resolveSchemeSelection } from "./support-TWuQlHQo.mjs";
20
- import { r as isEasBuildFailure } from "./eas-build-DMWSSvxq.mjs";
21
- import { r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-DBRfY_PN.mjs";
22
- import "./dev-client-BFxiDpkf.mjs";
23
- import { t as didSetUpDevice } from "./device-CiNYxqp6.mjs";
12
+ import { t as COMPILATION_CACHE_NOT_RUN } from "./xcode-DHu41qQ4.mjs";
13
+ import { S as setRemoteLogSink, d as simulatorRuntime } from "./client-18-ZowoT.mjs";
14
+ import { a as parseBuildMachineOption } from "./selection-BLtvaqxc.mjs";
15
+ import { r as hostedMetroSettings } from "./metro-gateway-DtsOy-0P.mjs";
16
+ import { i as writeDevicePlacementAsync } from "./ios-state-DlElquYD.mjs";
17
+ import { t as devClientPortBusy } from "./hosted-native-Doxbfzem.mjs";
18
+ import { r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-A1BgotaM.mjs";
19
+ import { f as waitFlagConflict, o as leaseExpiryText } from "./device-lease-run-DUtkbqBQ.mjs";
20
+ import { _ as resolveIosWait, a as deviceModelRefusal, b as resolveSimulatorAppFlag, c as iosProjectPathError, d as ownedSimFailure, g as resolveIosBuildSetup, h as resolveDeviceType, i as deviceLabel, m as resolveConfiguration, n as buildLogFile, r as createIosDeviceWaitRun, u as isReleaseConfiguration, v as resolveRuntime, x as simulatorBuildArch, y as resolveSchemeSelection } from "./support-B1W-hmC2.mjs";
21
+ import { r as isEasBuildFailure } from "./eas-build-CxKUNHsb.mjs";
22
+ import { r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-DgtJkzIa.mjs";
23
+ import "./dev-client-w_fok0Ek.mjs";
24
+ import { t as didSetUpDevice } from "./device-BktRGdjS.mjs";
24
25
  import { t as unsupportedPlan } from "./project-plan-BPwbLwQu.mjs";
25
- import { a as refusePlan, i as printPlan, n as planFlagRefusal } from "./build-plan-BmbdHQbr.mjs";
26
- import { a as lastBuildRecord, o as reportIosResult, s as writeLastBuild } from "./ios-project-CSZYI1iu.mjs";
27
- import { t as acquireIosArtifact } from "./artifact-DBI3DALs.mjs";
28
- import { a as hostedIosSelectors, i as hostedIosMetroNote, n as connectIosTarget, o as iosPlacementBudget, r as deviceRemoteConflict, s as selectIosPlacement, t as connectIosBackend } from "./remote-DR8qUERM.mjs";
29
- import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, o as iosPoolNoCandidatesRefusal, r as iosDeviceBounds } from "./ios-device-DFGuwF4U.mjs";
30
- import { i as DEFAULT_DEPS, l as lanOriginUrlFor, s as chooseLanAddress, t as finishIosRun } from "./launch-CP2wDCVd.mjs";
26
+ import { a as refusePlan, i as printPlan, n as planFlagRefusal } from "./build-plan-JsDUq4w1.mjs";
27
+ import { a as lastBuildRecord, o as reportIosResult, s as writeLastBuild } from "./ios-project-KYqeJURj.mjs";
28
+ import { t as acquireIosArtifact } from "./artifact-Bdt_n9Jc.mjs";
29
+ import { a as hostedIosSelectors, i as hostedIosMetroNote, n as connectIosTarget, o as iosPlacementBudget, r as deviceRemoteConflict, s as selectIosPlacement, t as connectIosBackend } from "./remote-DEZ7AOVq.mjs";
30
+ import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, o as iosPoolNoCandidatesRefusal, r as iosDeviceBounds } from "./ios-device-BI38NFFH.mjs";
31
+ import { i as DEFAULT_DEPS, l as lanOriginUrlFor, s as chooseLanAddress, t as finishIosRun } from "./launch-BVlyQw3T.mjs";
31
32
  import { basename, join } from "node:path";
32
33
  import { workspaceId } from "@stim-cli/core";
33
34
  import { hostedIosStatus, parseMachine } from "@stim-cli/core/state";
@@ -53,6 +54,7 @@ async function finishHostedIosRun({ target, d, artifact, root, slot, release, ap
53
54
  release,
54
55
  mode: appMode,
55
56
  ...appMode === "development" && isExpo ? { devClientScheme: d.devClientScheme(root, artifact.path) ?? void 0 } : {},
57
+ metroPort,
56
58
  reserved: (placement) => d.writeHostedIos(root, slot, placement),
57
59
  note,
58
60
  enterPhase
@@ -64,8 +66,8 @@ async function finishHostedIosRun({ target, d, artifact, root, slot, release, ap
64
66
  remedy: error instanceof Error && "remedy" in error && typeof error.remedy === "string" ? error.remedy : `Retry stim ios --remote ${target.host.machine}, or run stim stop to reconcile any recorded placement.`
65
67
  });
66
68
  }
67
- d.writeHostedIos(root, slot, run.placement);
68
- d.writeWorkspaceLaunch(root, "ios", {
69
+ await d.writeHostedIos(root, slot, run.placement);
70
+ await d.writeWorkspaceLaunch(root, "ios", {
69
71
  appId: bundleId,
70
72
  deviceId: run.placement.session,
71
73
  metroPort,
@@ -207,7 +209,7 @@ function runIosOperation(context, root, opts = {}, deps = {}, onFailure = () =>
207
209
  platform: "ios",
208
210
  slot: opts.slot ?? "default"
209
211
  }, async (claim) => {
210
- recordWorkspaceUse(root, /* @__PURE__ */ new Date(), context.env, context.cwd);
212
+ await recordWorkspaceUseAsync(root, /* @__PURE__ */ new Date(), context.env, context.cwd, context.signal);
211
213
  const progress = startBuildProgress({
212
214
  root,
213
215
  platform: "ios",
@@ -407,6 +409,17 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
407
409
  let buildMachine = "auto";
408
410
  let devicePlacement;
409
411
  let builtConfiguration = null;
412
+ let acquiredBuild = null;
413
+ const recordFailedBuild = (build, errorCode) => writeLastBuild(root, lastBuildRecord({
414
+ devicePlacement,
415
+ buildMachine,
416
+ ...build,
417
+ configuration: builtConfiguration,
418
+ startedAt,
419
+ status: "failed",
420
+ errorCode,
421
+ durationMs: elapsed()
422
+ }));
410
423
  const fail = ({ retainedClaimRoots, code, message, remedy = null, lines = [], logPath = null, build = null, lease, setup = false }) => {
411
424
  ({code, message, remedy, lines} = cancelledFailure(context, "ios", {
412
425
  code,
@@ -422,15 +435,12 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
422
435
  for (const line of lines) note(chalk.dim(phaseLine("", line)));
423
436
  if (remedy) note(chalk.dim(phaseLine("remedy", remedy)));
424
437
  if (logPath) note(chalk.dim(phaseLine("log", logPath)));
425
- if (build) writeLastBuild(root, lastBuildRecord({
426
- devicePlacement,
427
- buildMachine,
428
- ...build,
429
- configuration: builtConfiguration,
430
- startedAt,
431
- status: "failed",
432
- errorCode: code,
433
- durationMs: elapsed()
438
+ const failedBuild = build ?? acquiredBuild;
439
+ if (failedBuild) recordFailedBuild(failedBuild, code);
440
+ if (acquiredBuild) logWriter().write(runFailureRecord({
441
+ code,
442
+ message,
443
+ phase: progress.phase()
434
444
  }));
435
445
  note(chalk.red(phaseLine("failed", code)));
436
446
  if (!setup) recordRun({
@@ -595,7 +605,7 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
595
605
  });
596
606
  if (targetRefusal) return fail(targetRefusal);
597
607
  devicePlacement = remoteSelection.devicePlacement;
598
- writeDevicePlacement(root, slot, "ios", devicePlacement);
608
+ await writeDevicePlacementAsync(root, slot, "ios", devicePlacement);
599
609
  const { machine: hostedMachine, backend: remoteBackend } = remoteSelection;
600
610
  const viewer = resolveSimulatorAppFlag(opts.simulatorApp, physical, hostedMachine ?? remoteBackend, Boolean(remoteSelection.auto));
601
611
  if ("refusal" in viewer) return fail(viewer.refusal);
@@ -800,6 +810,11 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
800
810
  }
801
811
  async function prepareMetro() {
802
812
  if (metroCheck) {
813
+ const hostedPorts = hostedTarget && isExpo && d.hasDevClient(root) ? {
814
+ machine: hostedTarget.host.machine,
815
+ free: d.hostedMetroPortProbe(hostedTarget.host.machine, note),
816
+ busy: (port) => devClientPortBusy(hostedTarget.host.machine, port)
817
+ } : void 0;
803
818
  const gate = await ensureDevServer({
804
819
  env: context.env,
805
820
  root,
@@ -807,6 +822,7 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
807
822
  settings: hostedMetroSettings(settings, Boolean(hostedTarget)),
808
823
  settingsContext,
809
824
  remote: Boolean(remoteDevice),
825
+ hostedPorts,
810
826
  note,
811
827
  resolve: d.resolveProjectMetro,
812
828
  start: d.startDevServer,
@@ -825,6 +841,10 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
825
841
  };
826
842
  metroPort = gate.port;
827
843
  devServer = gate.devServer;
844
+ if (hostedPorts && !await hostedPorts.free(gate.port)) return {
845
+ ok: false,
846
+ error: devClientPortBusy(hostedPorts.machine, gate.port)
847
+ };
828
848
  } else {
829
849
  const pin = metroPortSetting(settings, context.env);
830
850
  if (pin.error) return {
@@ -917,10 +937,12 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
917
937
  code: "STIM_CANCELLED",
918
938
  message: "while finishing the run"
919
939
  });
920
- if (cancelled) return fail({
921
- ...cancelled,
922
- build: artifact?.failureFields
923
- });
940
+ if (cancelled) return fail(cancelled);
941
+ if (acquiredBuild) {
942
+ const { code } = error;
943
+ recordFailedBuild(acquiredBuild, typeof code === "string" ? code : void 0);
944
+ logWriter().write(thrownRunFailureRecord(error, progress.phase()));
945
+ }
924
946
  recordRun({
925
947
  failed: true,
926
948
  durationMs: elapsed()
@@ -1034,6 +1056,11 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
1034
1056
  return fail(acquiredArtifact.failure);
1035
1057
  }
1036
1058
  artifact = acquiredArtifact.artifact;
1059
+ acquiredBuild = {
1060
+ ...artifact.failureFields,
1061
+ appPath: artifact.path,
1062
+ bundleId: artifact.bundleId
1063
+ };
1037
1064
  compilationCache = artifact.cache.compilation;
1038
1065
  if (hostedTarget) return await finishHostedIosRun({
1039
1066
  output: context.output,
@@ -1,9 +1,9 @@
1
- import { h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-YKGWivpG.mjs";
2
- import { jn as schemesFromInfoPlist, kn as pickDevClientScheme } from "./budget-3ivAK99e.mjs";
3
- import { f as podAction, h as resolveDeviceType, i as deviceLabel, m as resolveConfiguration, n as buildLogFile, s as iosConfigurationSetting, t as appNameFromPath, u as isReleaseConfiguration, v as resolveRuntime } from "./support-TWuQlHQo.mjs";
4
- import { n as ensureWorkspaceStorageSafely } from "./native-runtime-DBRfY_PN.mjs";
5
- import { t as devClientScheme } from "./dev-client-BFxiDpkf.mjs";
6
- import { a as lastBuildRecord, i as iosFacts, n as cacheDescription, s as writeLastBuild } from "./ios-project-CSZYI1iu.mjs";
7
- import { n as registerIos, r as runIosOperation, t as iosCommand } from "./ios-CWjqfSm_.mjs";
8
- import { a as collectorEntry, o as replaceCollector } from "./launch-CP2wDCVd.mjs";
1
+ import { h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-DxC0k2rk.mjs";
2
+ import { Nn as schemesFromInfoPlist, jn as pickDevClientScheme } from "./budget-dPGuhNai.mjs";
3
+ import { f as podAction, h as resolveDeviceType, i as deviceLabel, m as resolveConfiguration, n as buildLogFile, s as iosConfigurationSetting, t as appNameFromPath, u as isReleaseConfiguration, v as resolveRuntime } from "./support-B1W-hmC2.mjs";
4
+ import { n as ensureWorkspaceStorageSafely } from "./native-runtime-DgtJkzIa.mjs";
5
+ import { t as devClientScheme } from "./dev-client-w_fok0Ek.mjs";
6
+ import { a as lastBuildRecord, i as iosFacts, n as cacheDescription, s as writeLastBuild } from "./ios-project-KYqeJURj.mjs";
7
+ import { n as registerIos, r as runIosOperation, t as iosCommand } from "./ios-B1FXRCMX.mjs";
8
+ import { a as collectorEntry, o as replaceCollector } from "./launch-BVlyQw3T.mjs";
9
9
  export { appNameFromPath, buildLogFile, cacheDescription, collectorEntry, iosCommand as default, devClientScheme, deviceLabel, ensureWorkspaceStorageSafely, formatDuration, iosConfigurationSetting, iosFacts, isReleaseConfiguration, lastBuildRecord, phaseLine, pickDevClientScheme, podAction, registerIos, replaceCollector, resolveConfiguration, resolveDeviceType, resolveRuntime, runIosOperation, schemesFromInfoPlist, shortHash, shortUdid, writeLastBuild };
@@ -1,10 +1,10 @@
1
- import { r as WorkspaceProcessCleanupError, t as getExecutor } from "./exec-DEoAhcze.mjs";
2
- import { P as formatBytes, _ as loadConfig$1 } from "./config-DlrsduwG.mjs";
1
+ import { l as WorkspaceProcessCleanupError, n as isTimeoutError, o as cancellableSleep, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
+ import { P as formatBytes, _ as loadConfig$1 } from "./config-BZhXY15H.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
- import { n as runOperationFileQuiet, t as runOperationFile } from "./operation-exec-BW0em61G.mjs";
5
- import { i as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-x9rN6bhs.mjs";
6
- import { ut as isStimOwnedSim } from "./android-C7sVmyI9.mjs";
7
- import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-D5OGpYZM.mjs";
4
+ import { n as runOperationFileQuiet, t as runOperationFile } from "./operation-exec-CUZifp6Z.mjs";
5
+ import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-DS0mzR8U.mjs";
6
+ import { dt as isStimOwnedSim } from "./android-882m4hxX.mjs";
7
+ import { a as recordCreatedDeviceAsync, n as forgetCreatedDeviceAsync } from "./created-devices-D2Aca-xu.mjs";
8
8
  import { createHash } from "node:crypto";
9
9
  import { closeSync, existsSync, lstatSync, mkdtempSync, openSync, readSync, readdirSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { tmpdir, totalmem } from "node:os";
@@ -332,6 +332,25 @@ async function readHostMemoryPressureAsync(exec = getExecutor(), platform = proc
332
332
  function memoryCulpritsUnder(pressure, exec = getExecutor()) {
333
333
  return pressure === "warning" || pressure === "critical" ? readMemoryCulprits(exec) : null;
334
334
  }
335
+ const CULPRIT_REUSE_MS = 3e4;
336
+ const recentCulprits = /* @__PURE__ */ new WeakMap();
337
+ function memoryCulpritsUnderAsync(pressure, exec = getExecutor()) {
338
+ if (pressure !== "warning" && pressure !== "critical") return Promise.resolve(null);
339
+ const recent = recentCulprits.get(exec);
340
+ if (recent && Date.now() - recent.at < CULPRIT_REUSE_MS) return recent.read;
341
+ const read = readMemoryCulpritsAsync(exec);
342
+ recentCulprits.set(exec, {
343
+ at: Date.now(),
344
+ read
345
+ });
346
+ return read;
347
+ }
348
+ function reportMemoryCulprits(pressure, emit, exec = getExecutor()) {
349
+ (async () => {
350
+ const named = memoryCulpritAdvice(await memoryCulpritsUnderAsync(pressure, exec));
351
+ if (named) emit(named);
352
+ })().catch(() => {});
353
+ }
335
354
  function hostMemoryPressureAdvice(pressure, culprits = null) {
336
355
  if (pressure === null || pressure === "normal") return null;
337
356
  const named = memoryCulpritAdvice(culprits);
@@ -486,9 +505,41 @@ const IOS_BOOT_TIMEOUT_MS = 6e5;
486
505
  const BOOTSTATUS_ATTEMPT_MS = 24e4;
487
506
  const BOOTSTATUS_ATTEMPT_FLOOR_MS = 1e3;
488
507
  const BOOT_STATE_LIST_TIMEOUT_MS = 3e4;
489
- function iosSimulatorFailureAdvice(exec = getExecutor()) {
508
+ const SPRINGBOARD_QUERY_TIMEOUT_MS = 1e4;
509
+ const SPRINGBOARD_POLL_MS = 250;
510
+ async function waitForSpringBoard(udid, deadline) {
511
+ for (;;) {
512
+ let output = null;
513
+ try {
514
+ output = await getExecutor().runFileAsync("xcrun", [
515
+ "simctl",
516
+ "spawn",
517
+ udid,
518
+ "notifyutil",
519
+ "-g",
520
+ "com.apple.springboard.finishedstartup"
521
+ ], { timeoutMs: Math.max(BOOTSTATUS_ATTEMPT_FLOOR_MS, Math.min(SPRINGBOARD_QUERY_TIMEOUT_MS, deadline - Date.now())) });
522
+ } catch (error) {
523
+ if (!isTimeoutError(error)) return {
524
+ state: "unreadable",
525
+ reason: error?.message || String(error)
526
+ };
527
+ }
528
+ if (output !== null) {
529
+ const state = /^com\.apple\.springboard\.finishedstartup (\d+)$/m.exec(output);
530
+ if (!state) return {
531
+ state: "unreadable",
532
+ reason: `Could not read SpringBoard's startup state: ${output.trim() || "no output"}.`
533
+ };
534
+ if (Number(state[1]) > 0) return { state: "started" };
535
+ }
536
+ if (Date.now() >= deadline) return { state: "timed-out" };
537
+ await cancellableSleep(SPRINGBOARD_POLL_MS);
538
+ }
539
+ }
540
+ async function iosSimulatorFailureAdvice(exec = getExecutor()) {
490
541
  const pressure = readHostMemoryPressure(exec);
491
- return hostMemoryPressureAdvice(pressure, memoryCulpritsUnder(pressure, exec)) ?? "The simulator may be unresponsive. Check Activity Monitor for memory pressure and free host memory before retrying.";
542
+ return hostMemoryPressureAdvice(pressure, await memoryCulpritsUnderAsync(pressure, exec)) ?? "The simulator may be unresponsive. Check Activity Monitor for memory pressure and free host memory before retrying.";
492
543
  }
493
544
  function bootstatusTimeout(command) {
494
545
  const e = /* @__PURE__ */ new Error(`${command} timed out`);
@@ -551,6 +602,7 @@ async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = B
551
602
  let sampledAt = started;
552
603
  let longestGapMs = 0;
553
604
  let phase = "requesting boot";
605
+ let springBoardUnreadable = null;
554
606
  const ranks = {
555
607
  normal: 0,
556
608
  warning: 1,
@@ -614,13 +666,18 @@ async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = B
614
666
  if (state !== "Booting" && state !== "Booted" && state !== void 0) throw new Error(`Simulator ${udid} reports "${state ?? "missing"}" after ${waited}s of boot wait.`);
615
667
  if (deadline - Date.now() <= 0) throw new Error(`Simulator ${udid} did not finish booting within ${Math.round(timeoutMs / 1e3)}s.`);
616
668
  }
669
+ phase = "waiting for SpringBoard";
670
+ const springBoard = await waitForSpringBoard(udid, deadline);
671
+ if (springBoard.state === "timed-out") throw new Error(`Simulator ${udid} did not finish booting within ${Math.round(timeoutMs / 1e3)}s.`);
672
+ if (springBoard.state === "unreadable") springBoardUnreadable = springBoard.reason;
617
673
  } catch (error) {
618
- const named = memoryCulpritAdvice(memoryCulpritsUnder(sample(), exec));
674
+ const named = memoryCulpritAdvice(await memoryCulpritsUnderAsync(sample(), exec));
619
675
  throw new Error(`${error?.message || error} Last boot output: ${phase}. Highest observed memory pressure: ${worst ?? "unknown"}; unavailable samples: ${unknown}.${coverage()}${named ? ` ${named}` : ""} ${recovery} These observations do not establish an OOM crash.`, { cause: error });
620
676
  } finally {
621
677
  clearInterval(monitor);
622
678
  }
623
679
  if (openViewer) await viewer.open(udid);
680
+ return { springBoardUnreadable };
624
681
  }
625
682
  async function shutdownIosSim(udid, operation) {
626
683
  if (!operation) {
@@ -772,7 +829,7 @@ async function createOwnedIosSim(label, { deviceType, runtime, suffix = "" } = {
772
829
  timeoutMs: SIMCTL_CREATE_TIMEOUT_MS,
773
830
  killSignal: "SIGKILL"
774
831
  })).trim();
775
- recordCreatedDevice("ios", udid);
832
+ await recordCreatedDeviceAsync("ios", udid);
776
833
  return {
777
834
  udid,
778
835
  name,
@@ -944,7 +1001,7 @@ async function deleteIosSim(udid, operation) {
944
1001
  ...SIMCTL_OPTIONS,
945
1002
  cwd: operation?.cwd
946
1003
  });
947
- forgetCreatedDevice("ios", udid);
1004
+ await forgetCreatedDeviceAsync("ios", udid);
948
1005
  }
949
1006
  const PARKED_DELETE_TIMEOUT_MS = 3e4;
950
1007
  async function deleteParkedIosSim(udid, operation) {
@@ -964,7 +1021,7 @@ async function deleteParkedIosSim(udid, operation) {
964
1021
  timeoutMs: PARKED_DELETE_TIMEOUT_MS,
965
1022
  cwd: operation?.cwd
966
1023
  });
967
- forgetCreatedDevice("ios", udid);
1024
+ await forgetCreatedDeviceAsync("ios", udid);
968
1025
  }
969
1026
  const LIST_RUNTIMES_ARGS = [
970
1027
  "simctl",
@@ -996,4 +1053,4 @@ function parseIosRuntimes(out) {
996
1053
  }] : []);
997
1054
  }
998
1055
  //#endregion
999
- export { configuredIosSimulatorViewer as A, deviceHoldsBundle as B, resetIosKeychain as C, sanitizeDeviceLabel as D, resolveOwnedIosSim as E, readHostMemoryPressureAsync as F, memoryCulpritAdvice as I, memoryCulpritFindings as L, hostMemoryPressureAdvice as M, memoryCulpritsUnder as N, shutdownIosSim as O, readHostMemoryPressure as P, readMemoryCulpritsAsync as R, renameIosSim as S, resolveIosCreation as T, ownedSimName as _, createOwnedIosSim as a, parseSimctlList as b, eraseIosSim as c, listAllIosSims as d, listAllIosSimsAsync as f, listUserApps as g, listIosRuntimesAsync as h, createIosSimSnapshot as i, parseIosSimulatorApp as j, uninstallIosApp as k, iosRuntimeMatches as l, listIosRuntimes as m, bootIosSim as n, deleteIosSim as o, listIosDeviceTypesAsync as p, clearIosAppData as r, deleteParkedIosSim as s, IOS_BOOT_TIMEOUT_MS as t, iosSimulatorFailureAdvice as u, parkedSimName as v, resetIosPrivacy as w, pickDefaultIosCreation as x, parseRuntimeVersion as y, deviceHoldsApk as z };
1056
+ export { configuredIosSimulatorViewer as A, readMemoryCulpritsAsync as B, resetIosKeychain as C, sanitizeDeviceLabel as D, resolveOwnedIosSim as E, readHostMemoryPressure as F, deviceHoldsBundle as H, readHostMemoryPressureAsync as I, reportMemoryCulprits as L, hostMemoryPressureAdvice as M, memoryCulpritsUnder as N, shutdownIosSim as O, memoryCulpritsUnderAsync as P, memoryCulpritAdvice as R, renameIosSim as S, resolveIosCreation as T, deviceHoldsApk as V, ownedSimName as _, createOwnedIosSim as a, parseSimctlList as b, eraseIosSim as c, listAllIosSims as d, listAllIosSimsAsync as f, listUserApps as g, listIosRuntimesAsync as h, createIosSimSnapshot as i, parseIosSimulatorApp as j, uninstallIosApp as k, iosRuntimeMatches as l, listIosRuntimes as m, bootIosSim as n, deleteIosSim as o, listIosDeviceTypesAsync as p, clearIosAppData as r, deleteParkedIosSim as s, IOS_BOOT_TIMEOUT_MS as t, iosSimulatorFailureAdvice as u, parkedSimName as v, resetIosPrivacy as w, pickDefaultIosCreation as x, parseRuntimeVersion as y, memoryCulpritFindings as z };
@@ -1,4 +1,4 @@
1
- import { t as getExecutor } from "./exec-DEoAhcze.mjs";
1
+ import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  //#region src/collector/ios.ts
3
3
  const MESSAGE_TYPE_LEVEL = {
4
4
  Debug: "debug",
@@ -1,4 +1,4 @@
1
- import { t as getExecutor } from "./exec-DEoAhcze.mjs";
1
+ import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  //#region src/collector/ios-device.ts
3
3
  const CONSOLE_ENV = { OS_ACTIVITY_DT_MODE: "enable" };
4
4
  const DEV_MENU_LAUNCH_ARGS = [
@@ -1,6 +1,6 @@
1
- import { t as getExecutor } from "./exec-DEoAhcze.mjs";
2
- import { ln as INSTALL_ERROR, pn as appProcessFromPid } from "./budget-3ivAK99e.mjs";
3
- import { n as TOOL_ERROR_PREFIX } from "./ios-device-BXZ0c7Kb.mjs";
1
+ import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
+ import { dn as INSTALL_ERROR, hn as appProcessFromPid } from "./budget-dPGuhNai.mjs";
3
+ import { n as TOOL_ERROR_PREFIX } from "./ios-device-B6HK951C.mjs";
4
4
  import { mkdtempSync, readFileSync, rmSync } from "node:fs";
5
5
  import { tmpdir } from "node:os";
6
6
  import { join } from "node:path";
@@ -1,9 +1,9 @@
1
1
  import { l as workspaceAgentDeviceDir } from "./paths-DQtTgsBf.mjs";
2
- import { i as formatDuration, l as phaseLine } from "./command-output-YKGWivpG.mjs";
3
- import { B as recordFinishedBuild, Hn as isEasAuthFailureText, Rn as UPLOAD_TIMEOUT_MS, Vn as easAuthNote, zn as cacheLevel } from "./budget-3ivAK99e.mjs";
4
- import { a as workspaceLinkLine } from "./stim-desktop-D5OGpYZM.mjs";
5
- import { o as compilationCacheActivityLine, t as COMPILATION_CACHE_NOT_RUN } from "./xcode-Rq744mBF.mjs";
6
- import { i as deviceLabel } from "./support-TWuQlHQo.mjs";
2
+ import { i as formatDuration, l as phaseLine } from "./command-output-DxC0k2rk.mjs";
3
+ import { a as workspaceLinkLine } from "./stim-desktop-DS0mzR8U.mjs";
4
+ import { B as recordFinishedBuild, Bn as UPLOAD_TIMEOUT_MS, Un as easAuthNote, Vn as cacheLevel, Wn as isEasAuthFailureText } from "./budget-dPGuhNai.mjs";
5
+ import { o as compilationCacheActivityLine, t as COMPILATION_CACHE_NOT_RUN } from "./xcode-DHu41qQ4.mjs";
6
+ import { i as deviceLabel } from "./support-B1W-hmC2.mjs";
7
7
  import { buildDiagnostics } from "@stim-cli/core/state";
8
8
  import chalk from "chalk";
9
9
  //#region src/commands/ios/result.ts