stim 1.24.0 → 1.26.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 (162) hide show
  1. package/README.md +1 -1
  2. package/dist/{acquire-artifact-CEs02U2o.mjs → acquire-artifact-DVsvSwf7.mjs} +1 -1
  3. package/dist/{act-Cyvm8xYc.mjs → act-C-BqJEpu.mjs} +158 -36
  4. package/dist/{activity-Dq3ZcdD8.mjs → activity-Lnb_EoRY.mjs} +4 -5
  5. package/dist/{agent-device-usage-output-CccomeE0.mjs → agent-device-usage-output-DbXy5tg8.mjs} +4 -4
  6. package/dist/{android-CX5IcRuf.mjs → android-B5P81yI-.mjs} +1 -1
  7. package/dist/{android-DcztblCT.mjs → android-CSbLRD53.mjs} +5 -5
  8. package/dist/{android-BZppyPe_.mjs → android-CiNQw3kq.mjs} +81 -52
  9. package/dist/{android-882m4hxX.mjs → android-DTAcRwBC.mjs} +81 -34
  10. package/dist/{android-cas-BtCOrNqb.mjs → android-cas-BTVhZ0Qs.mjs} +4 -4
  11. package/dist/{android-project-DVWyCbWU.d.mts → android-project-DUGMbq28.d.mts} +61 -3
  12. package/dist/api.d.mts +8 -5
  13. package/dist/api.mjs +27 -27
  14. package/dist/apk-signed-tail-B46U9hXc.mjs +142 -0
  15. package/dist/{artifact-BR5VNArK.mjs → artifact-BxREhAaV.mjs} +25 -19
  16. package/dist/{artifact-Bdt_n9Jc.mjs → artifact-CsAP6AGK.mjs} +36 -21
  17. package/dist/{attempt-DW-mQqM7.mjs → attempt-ClyJlZPT.mjs} +4 -2
  18. package/dist/{browser-web-ycg9qWB8.mjs → browser-web-rYPyqhTf.mjs} +11 -12
  19. package/dist/{budget-dPGuhNai.mjs → budget-k2mZGvvk.mjs} +242 -38
  20. package/dist/{build-CaF574eS.mjs → build-DPhApsjV.mjs} +28 -24
  21. package/dist/{build-cache-HFUQ9eLz.mjs → build-cache-DrXNCy3T.mjs} +123 -23
  22. package/dist/{build-plan-JsDUq4w1.mjs → build-plan-DrMMdayj.mjs} +5 -5
  23. package/dist/{cache-manifest-BPXRONJz.mjs → cache-manifest-BEZ9Bpl1.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{ccache-CCn1S6qG.mjs → ccache-Bx5TbxwG.mjs} +6 -6
  26. package/dist/{cli-xqAidP7O.mjs → cli-BBKFGOFl.mjs} +19 -19
  27. package/dist/cli.mjs +1 -1
  28. package/dist/{client-18-ZowoT.mjs → client-D9CaRks-.mjs} +55 -71
  29. package/dist/collector-run.mjs +4 -4
  30. package/dist/{command-output-DxC0k2rk.mjs → command-output-BF5AR2dL.mjs} +1 -1
  31. package/dist/{config-BZhXY15H.mjs → config-BktkY_zC.mjs} +321 -15
  32. package/dist/{launch-BVlyQw3T.mjs → dependencies-Dw6wfQdv.mjs} +259 -256
  33. package/dist/{dependency-state-C56ll9hY.mjs → dependency-state-DFB41vfr.mjs} +1 -1
  34. package/dist/{dev-client-w_fok0Ek.mjs → dev-client-DXR_tPVY.mjs} +2 -2
  35. package/dist/{device-BktRGdjS.mjs → device-BK-zwyd_.mjs} +64 -33
  36. package/dist/{device-4RUugw5X.mjs → device-BcYeHSFu.mjs} +14 -14
  37. package/dist/{device-capacity-Ic-kdmEV.mjs → device-capacity-DCSvUF0l.mjs} +10 -17
  38. package/dist/device-host-worker.mjs +11 -13
  39. package/dist/{device-ios-DzpSlZyd.mjs → device-ios-BLGfXQeK.mjs} +68 -25
  40. package/dist/{device-lease-run-DUtkbqBQ.mjs → device-lease-run-BmvIl7bI.mjs} +5 -5
  41. package/dist/{device-pool-CgBHk401.mjs → device-pool-Dluix4H3.mjs} +3 -3
  42. package/dist/{doctor-DZgpqR6J.mjs → doctor-Bhg1ii70.mjs} +14 -14
  43. package/dist/{doctor-BZ6oxNum.mjs → doctor-Cp-BhzTS.mjs} +1 -1
  44. package/dist/{doctor-C33AzVfR.mjs → doctor-OnwP94ne.mjs} +81 -26
  45. package/dist/{doctor-fingerprint-zlujA1Gs.mjs → doctor-fingerprint-D3a04Mhu.mjs} +8 -2
  46. package/dist/doctor-fingerprint.mjs +1 -1
  47. package/dist/{doctor-watchman-B453A231.mjs → doctor-watchman-BStK05nt.mjs} +4 -4
  48. package/dist/{eas-build-CxKUNHsb.mjs → eas-build-Dsj93iM9.mjs} +2 -2
  49. package/dist/{eas-fallback-LMxk9Kw0.mjs → eas-fallback-FwkeqqGi.mjs} +13 -12
  50. package/dist/{eas-session-ledger-Ck6YXPAO.mjs → eas-session-ledger-B5vygTiD.mjs} +5 -5
  51. package/dist/{error-diagnostics-BkKCZq4P.mjs → error-diagnostics-BOOm9Db7.mjs} +8 -8
  52. package/dist/{errors-ccaPc4ox.mjs → errors-DHm_U5gv.mjs} +2 -1
  53. package/dist/{gc-DDWEAj0w.mjs → gc-C_79zvz4.mjs} +2 -2
  54. package/dist/{gc-yVKpAOKM.mjs → gc-ldgr-hXU.mjs} +74 -43
  55. package/dist/{guide-Bggftwc5.mjs → guide-D7K0X6KG.mjs} +374 -78
  56. package/dist/{hosted-android-D4dweBof.mjs → hosted-android-Bk54ej6n.mjs} +3 -3
  57. package/dist/{hosted-client-BBTVe3X6.mjs → hosted-client-fHO8yqzc.mjs} +5 -5
  58. package/dist/{hosted-ios-Sn0djzg8.mjs → hosted-ios-D55QhYaD.mjs} +1 -1
  59. package/dist/{hosted-logs-CYIZ5ubJ.mjs → hosted-logs-BfbmDM4M.mjs} +17 -11
  60. package/dist/hosted-logs-sync-B0pvmOk-.mjs +195 -0
  61. package/dist/{hosted-macos-CXjsUNBR.mjs → hosted-macos-CPl0OZ9h.mjs} +5 -5
  62. package/dist/{hosted-native-Doxbfzem.mjs → hosted-native-CpDB3-PO.mjs} +6 -7
  63. package/dist/{idle-shutdown-BInjLKqm.mjs → idle-shutdown-FfxL1KdG.mjs} +22 -9
  64. package/dist/{ios-BItP6lkn.mjs → ios-B7-lToDu.mjs} +8 -8
  65. package/dist/{ios-CVUFFZ6C.mjs → ios-WxpDJ5T1.mjs} +129 -14
  66. package/dist/{ios-device-BI38NFFH.mjs → ios-device-CsyryvpT.mjs} +1 -1
  67. package/dist/{ios-B1FXRCMX.mjs → ios-ftxdQbJS.mjs} +84 -51
  68. package/dist/{ios-project-KYqeJURj.mjs → ios-project-Ty5pHl9O.mjs} +6 -6
  69. package/dist/{ios-state-DlElquYD.mjs → ios-state-Cw7-WQf2.mjs} +1 -1
  70. package/dist/{js-swap-BvrQvXHY.mjs → js-swap-BMhXYVDS.mjs} +4 -4
  71. package/dist/{launch-SfzGH_s9.mjs → launch-DOp8RjDz.mjs} +32 -27
  72. package/dist/{logs-DXE32kyb.mjs → logs-dQDki6Tt.mjs} +9 -173
  73. package/dist/{logs-ovlU7m7N.mjs → logs-s1dRIG1E.mjs} +85 -36
  74. package/dist/{macos-B3BveDrU.mjs → macos-B0VEV3Gf.mjs} +1 -1
  75. package/dist/{macos-CCfhb-jT.mjs → macos-DBBPNnIA.mjs} +18 -19
  76. package/dist/macos-run.mjs +1 -1
  77. package/dist/maintenance-run.mjs +28 -11
  78. package/dist/{metro-Bu8LBfzS.mjs → metro-CjC10t6E.mjs} +2 -2
  79. package/dist/{metro-gateway-DtsOy-0P.mjs → metro-gateway-B6_PgD0L.mjs} +2 -3
  80. package/dist/{named-ports-BWDuU5oQ.mjs → named-ports-BG0j1X4g.mjs} +2 -2
  81. package/dist/{native-android-96BBizbq.mjs → native-android-CL2NGiik.mjs} +17 -17
  82. package/dist/{native-gradle-artifact-inputs-BcLYBZil.mjs → native-gradle-artifact-inputs-btSUulme.mjs} +3 -3
  83. package/dist/{native-run-BmH7U8pr.mjs → native-run-BfIDFKLH.mjs} +2 -3
  84. package/dist/{native-runtime-DgtJkzIa.mjs → native-runtime-Dq3RBcON.mjs} +6 -7
  85. package/dist/{native-xcode-inputs-irplbQb0.mjs → native-xcode-inputs-BW7H8JGu.mjs} +2 -2
  86. package/dist/{native-xcode-ios-BY-6hh6M.mjs → native-xcode-ios-CBXJAxfC.mjs} +18 -18
  87. package/dist/offload-worker.d.mts +7 -2
  88. package/dist/offload-worker.mjs +34 -23
  89. package/dist/{ownership-DxlZGDcV.mjs → ownership-BjYvMNX_.mjs} +2 -2
  90. package/dist/{phone-reverses-BdsdesVF.mjs → phone-reverses-lmj6kcPm.mjs} +3 -3
  91. package/dist/{placement-log-DUvqqsB-.mjs → placement-log-DIFPQAXp.mjs} +1 -1
  92. package/dist/{plan-placement-4axc0Hs7.mjs → plan-placement-IiiSQhtz.mjs} +3 -3
  93. package/dist/{ports-D-E_OiAO.mjs → ports-C2_w1Z0Z.mjs} +3 -3
  94. package/dist/prebuild-gmouvmJZ.mjs +1247 -0
  95. package/dist/{project-Dz-hWkb-.mjs → project-BUu6Is4k.mjs} +15 -16
  96. package/dist/{react-native-android-DOinxgwB.mjs → react-native-android-Cgg99REN.mjs} +48 -33
  97. package/dist/{react-native-build-AuCu-aAP.mjs → react-native-build-oNwqF5Wb.mjs} +8 -8
  98. package/dist/{react-native-doctor-2ivJUmwZ.mjs → react-native-doctor-BhA3KUte.mjs} +49 -8
  99. package/dist/{react-native-ios-D5zTIuH8.mjs → react-native-ios-B-nf4rjN.mjs} +40 -25
  100. package/dist/{recordings-CdPwYwvs.mjs → recordings-BldzVKq0.mjs} +1 -1
  101. package/dist/{reload-Ck9RJeSq.mjs → reload-C9OduiNc.mjs} +1 -1
  102. package/dist/{reload-C1TTVesC.mjs → reload-CCR7KC_l.mjs} +14 -14
  103. package/dist/{remote-DEZ7AOVq.mjs → remote-C8S7FlPF.mjs} +16 -7
  104. package/dist/{result-DqBrb12U.mjs → result-7F5hEwQJ.mjs} +17 -17
  105. package/dist/{run-BIwoU44q.mjs → run-BqB0v3pt.mjs} +1 -1
  106. package/dist/{selection-BLtvaqxc.mjs → selection-BNPBZ6T5.mjs} +157 -44
  107. package/dist/{server-bare-Z1ToVLPn.mjs → server-bare-A75rDIdD.mjs} +55 -3
  108. package/dist/{server-command-C0pmjNdG.mjs → server-command-CssKFOD7.mjs} +4 -4
  109. package/dist/{server-expo-Tt_hLRpy.mjs → server-expo-eQfOdydb.mjs} +8 -6
  110. package/dist/server-expo-wvcj5tiZ.mjs +2 -0
  111. package/dist/{settings-RKwY33wv.mjs → settings-CosW5X-S.mjs} +59 -61
  112. package/dist/{settings-kkt0vP4w.mjs → settings-OaGQF-ri.mjs} +1 -1
  113. package/dist/{settings-write--gj6MACV.mjs → settings-write-QjYfSrjF.mjs} +5 -5
  114. package/dist/settings.schema.json +71 -6
  115. package/dist/{simslim-CdWKT3vA.mjs → simslim-Bax1qcxu.mjs} +22 -6
  116. package/dist/{slot-launch-A1BgotaM.mjs → slot-launch-CYCEhfBY.mjs} +6 -6
  117. package/dist/{stage-ERTMh88n.mjs → stage-jKQ7CP_B.mjs} +1 -1
  118. package/dist/{start-Bmg_qmHi.mjs → start-C_wefNKB.mjs} +1 -1
  119. package/dist/{start-BKGrEhzG.mjs → start-_BdJ32cZ.mjs} +9 -10
  120. package/dist/{state-B1ig0Kqy.mjs → state-C1i2nMOP.mjs} +2 -3
  121. package/dist/{state-BfAltYJP.mjs → state-C4OdpOTF.mjs} +1 -2
  122. package/dist/{stats-B-ckuiUg.mjs → stats-tEpEEH-u.mjs} +4 -4
  123. package/dist/{status-Pw-807f0.mjs → status-B9M7x4CZ.mjs} +1 -1
  124. package/dist/{status-Fect2w9R.mjs → status-CRXz-Gtj.mjs} +1 -1
  125. package/dist/{status-DfFp6a76.mjs → status-DQrqodLj.mjs} +22 -23
  126. package/dist/{status-watch-XC7F-AMf.mjs → status-watch-B5wDIH_o.mjs} +4 -4
  127. package/dist/status-worker.mjs +1 -1
  128. package/dist/{stim-desktop-DS0mzR8U.mjs → stim-desktop-6Dqp-gjX.mjs} +1 -1
  129. package/dist/{stop-BFu7X_Do.mjs → stop-CmdNhGlC.mjs} +2 -2
  130. package/dist/{stop-CL1kDHds.mjs → stop-DRqQVqDJ.mjs} +74 -53
  131. package/dist/{stop-DhclRwOO.mjs → stop-ySNQHXMG.mjs} +4 -5
  132. package/dist/supervisor-run.d.mts +1 -0
  133. package/dist/supervisor-run.mjs +15 -16
  134. package/dist/{support-B3tzVhKn.mjs → support-BGSCBoib.mjs} +4 -4
  135. package/dist/{support-B1W-hmC2.mjs → support-CVOCp0Ft.mjs} +15 -12
  136. package/dist/{swiftpm-artifact-inputs-BWYPj9Sn.mjs → swiftpm-artifact-inputs-CfUzt_0Z.mjs} +1 -1
  137. package/dist/{swiftpm-macos-BVCP5mO4.mjs → swiftpm-macos-x6HPpl_2.mjs} +10 -10
  138. package/dist/toolchain-DoavrvIA.mjs +2 -0
  139. package/dist/toolchain-J4J8MrAr.mjs +2107 -0
  140. package/dist/trigger-DzJu208Q.mjs +2 -0
  141. package/dist/{trigger-CBMe2YLH.mjs → trigger-KVaWWNyn.mjs} +1 -1
  142. package/dist/{warm-progress-ol0ZypEu.mjs → warm-progress-DvhTX_eu.mjs} +3 -4
  143. package/dist/web-BFLueSh-.mjs +2 -0
  144. package/dist/{web-BH7peScT.mjs → web-Bihbf7-u.mjs} +8 -9
  145. package/dist/web-run.mjs +4 -4
  146. package/dist/{workspace-state-CeBpIZgr.mjs → workspace-state-pUg3_RRA.mjs} +45 -7
  147. package/dist/{workspaces-CSV2Orf4.mjs → workspaces-g2lhdBXF.mjs} +17 -17
  148. package/dist/{worktree-Dw8kfacb.mjs → worktree-BKuklFh_.mjs} +34 -31
  149. package/dist/{worktree-DEDUzO_L.mjs → worktree-Bm4cb-nU.mjs} +1 -1
  150. package/package.json +8 -8
  151. package/shim/bundle-response.cjs +53 -1
  152. package/shim/bundle-response.d.cts +1 -1
  153. package/shim/expo-metro-config.cjs +23 -1
  154. package/dist/created-devices-D2Aca-xu.mjs +0 -52
  155. package/dist/paths-DQtTgsBf.mjs +0 -42
  156. package/dist/prebuild-DmVCf5xb.mjs +0 -501
  157. package/dist/server-expo-CEntXzRw.mjs +0 -2
  158. package/dist/toolchain-BjgKdoEf.mjs +0 -2
  159. package/dist/toolchain-D3bmRMia.mjs +0 -897
  160. package/dist/trigger-BLsHgAGR.mjs +0 -2
  161. package/dist/web-BdOFlTJr.mjs +0 -2
  162. package/dist/xcode-DHu41qQ4.mjs +0 -910
@@ -1,10 +1,10 @@
1
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";
2
+ import { P as formatBytes, _ as loadConfig$1 } from "./config-BktkY_zC.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
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";
5
+ import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-6Dqp-gjX.mjs";
6
+ import { Ct as forgetCreatedDeviceAsync, Et as recordCreatedDeviceAsync, dt as isStimOwnedSim } from "./android-DTAcRwBC.mjs";
7
+ import { n as signedTailFor } from "./apk-signed-tail-B46U9hXc.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";
@@ -14,6 +14,9 @@ import { IOS_SIMULATOR_APPS, isJsonObject, settingDefinition } from "@stim-cli/c
14
14
  const READ_CHUNK_BYTES = 1048576;
15
15
  const DEVICE_PATH_TIMEOUT_MS = 3e4;
16
16
  const DEVICE_HASH_TIMEOUT_MS = 12e4;
17
+ const APKSIGNER_TIMEOUT_MS = 12e4;
18
+ const PACKAGE_NAME = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)+$/;
19
+ const EMPTY_INPUT_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
17
20
  const SHA256_HEX = /^[0-9a-f]{64}$/;
18
21
  function parseInstalledApkPath(text) {
19
22
  if (typeof text !== "string") return null;
@@ -31,6 +34,30 @@ function parseDeviceSha256(text) {
31
34
  const first = text.trim().split(/\s+/)[0] ?? "";
32
35
  return SHA256_HEX.test(first) ? first : null;
33
36
  }
37
+ function deviceTailProbeScript(packageName, tailBytes) {
38
+ return `for p in $(pm path ${packageName} | sed -n "s/^package://p"); do echo "path $p"; stat -c "size %s" "$p"; tail -c ${tailBytes} "$p" | sha256sum; done`;
39
+ }
40
+ const TAIL_PROBE = /^path \/.*\nsize (\d+)\n(\S+) {2}-$/gm;
41
+ function parseDeviceTailProbe(text) {
42
+ if (typeof text !== "string") return null;
43
+ const lines = text.split("\n").map((line) => line.trim()).filter(Boolean);
44
+ if (lines.length === 0) return { installs: 0 };
45
+ const probes = [];
46
+ for (const [, size, digest] of lines.join("\n").matchAll(TAIL_PROBE)) {
47
+ const tailSha256 = parseDeviceSha256(digest);
48
+ if (!size || !tailSha256 || tailSha256 === EMPTY_INPUT_SHA256) return null;
49
+ probes.push({
50
+ size: Number(size),
51
+ tailSha256
52
+ });
53
+ }
54
+ if (probes.length * 3 !== lines.length) return null;
55
+ const [only, ...others] = probes;
56
+ return only && others.length === 0 ? {
57
+ installs: 1,
58
+ ...only
59
+ } : { installs: "split" };
60
+ }
34
61
  function parseAppContainerPath(text) {
35
62
  if (typeof text !== "string") return null;
36
63
  const lines = text.split("\n").map((line) => line.trim()).filter(Boolean);
@@ -90,8 +117,32 @@ function hashBundle(dir) {
90
117
  };
91
118
  return walk(dir, "") ? digest.digest("hex") : null;
92
119
  }
120
+ async function deviceHoldsSignedTail({ serial, packageName }, tail, e) {
121
+ let probe;
122
+ try {
123
+ probe = parseDeviceTailProbe(await e.runFileAsync("adb", [
124
+ "-s",
125
+ serial,
126
+ "shell",
127
+ deviceTailProbeScript(packageName, tail.size - tail.tailOffset)
128
+ ], { timeoutMs: DEVICE_PATH_TIMEOUT_MS }));
129
+ } catch {
130
+ return false;
131
+ }
132
+ if (!probe) return null;
133
+ if (probe.installs !== 1) return false;
134
+ return probe.size === tail.size && probe.tailSha256 === tail.tailSha256;
135
+ }
93
136
  async function deviceHoldsApk({ serial, packageName, apkPath }, { exec = null } = {}) {
94
137
  const e = exec || getExecutor();
138
+ const tail = PACKAGE_NAME.test(packageName) ? await signedTailFor(apkPath, (file, args) => e.runFileAsync(file, args, { timeoutMs: APKSIGNER_TIMEOUT_MS })) : null;
139
+ if (tail) {
140
+ const held = await deviceHoldsSignedTail({
141
+ serial,
142
+ packageName
143
+ }, tail, e);
144
+ if (held !== null) return held;
145
+ }
95
146
  let path;
96
147
  try {
97
148
  path = parseInstalledApkPath(await e.runFileAsync("adb", [
@@ -457,6 +508,11 @@ const SIMCTL_LIST_ARGS = [
457
508
  "devices",
458
509
  "--json"
459
510
  ];
511
+ const SIMCTL_LIST_ALL_ARGS = [
512
+ "simctl",
513
+ "list",
514
+ "--json"
515
+ ];
460
516
  function listAllIosSims({ timeoutMs = 3e4, includeUnavailable = false } = {}) {
461
517
  return parseSimctlList(getExecutor().runFile("xcrun", SIMCTL_LIST_ARGS, {
462
518
  timeoutMs,
@@ -465,21 +521,47 @@ function listAllIosSims({ timeoutMs = 3e4, includeUnavailable = false } = {}) {
465
521
  }
466
522
  function createIosSimSnapshot() {
467
523
  let cached = null;
524
+ let listing = null;
525
+ const start = (options) => {
526
+ if (listing) return listing;
527
+ const entry = cached ??= {};
528
+ const run = listIosSimulatorAsync(options);
529
+ const pending = run.then((all) => entry.value ??= all.sims);
530
+ listing = run;
531
+ entry.pending = pending;
532
+ const forget = () => {
533
+ if (listing === run) listing = null;
534
+ if (entry.pending === pending) entry.pending = void 0;
535
+ };
536
+ run.catch(forget);
537
+ pending.catch(forget);
538
+ return run;
539
+ };
468
540
  return {
469
541
  read() {
470
542
  const entry = cached ??= {};
471
543
  entry.value ??= listAllIosSims({ includeUnavailable: true });
472
544
  return entry.value;
473
545
  },
474
- async readAsync() {
546
+ async readAsync(options) {
475
547
  const entry = cached ??= {};
476
548
  if (entry.value) return entry.value;
477
- entry.pending ??= listAllIosSimsAsync({ includeUnavailable: true }).then((value) => entry.value = value).catch((error) => {
549
+ if (!entry.pending && !listing) start(options);
550
+ entry.pending ??= listAllIosSimsAsync({
551
+ includeUnavailable: true,
552
+ ...options
553
+ }).then((value) => entry.value = value).catch((error) => {
478
554
  entry.pending = void 0;
479
555
  throw error;
480
556
  });
481
557
  return entry.pending;
482
558
  },
559
+ async runtimes(options) {
560
+ return (await start(options)).runtimes;
561
+ },
562
+ async deviceTypes(options) {
563
+ return (await start(options)).deviceTypes;
564
+ },
483
565
  invalidate() {
484
566
  cached = null;
485
567
  }
@@ -493,6 +575,22 @@ async function listAllIosSimsAsync({ timeoutMs = 3e4, includeUnavailable = false
493
575
  cwd: operation?.cwd
494
576
  }), { includeUnavailable });
495
577
  }
578
+ /** The simulators, runtimes and device types out of one unfiltered `simctl list --json`. */
579
+ function parseSimctlListing(jsonOutput) {
580
+ return {
581
+ sims: parseSimctlList(jsonOutput, { includeUnavailable: true }),
582
+ runtimes: parseIosRuntimes(jsonOutput),
583
+ deviceTypes: parseIosDeviceTypes(jsonOutput)
584
+ };
585
+ }
586
+ async function listIosSimulatorAsync({ signal, operation } = {}) {
587
+ return parseSimctlListing(await runOperationFile(operation, getExecutor(), "xcrun", SIMCTL_LIST_ALL_ARGS, {
588
+ timeoutMs: 3e4,
589
+ killSignal: "SIGKILL",
590
+ signal,
591
+ cwd: operation?.cwd
592
+ }));
593
+ }
496
594
  function parseRuntimeVersion(runtimeId) {
497
595
  const m = runtimeId.match(/iOS-(\d+)(?:-(\d+))?$/);
498
596
  if (!m) return runtimeId;
@@ -507,6 +605,22 @@ const BOOTSTATUS_ATTEMPT_FLOOR_MS = 1e3;
507
605
  const BOOT_STATE_LIST_TIMEOUT_MS = 3e4;
508
606
  const SPRINGBOARD_QUERY_TIMEOUT_MS = 1e4;
509
607
  const SPRINGBOARD_POLL_MS = 250;
608
+ async function readSpringBoardPid(udid) {
609
+ try {
610
+ const output = await getExecutor().runFileAsync("xcrun", [
611
+ "simctl",
612
+ "spawn",
613
+ udid,
614
+ "notifyutil",
615
+ "-g",
616
+ "com.apple.springboard.finishedstartup"
617
+ ], { timeoutMs: SPRINGBOARD_QUERY_TIMEOUT_MS });
618
+ const pid = Number(/^com\.apple\.springboard\.finishedstartup (\d+)$/m.exec(output)?.[1] ?? 0);
619
+ return pid > 0 ? pid : null;
620
+ } catch {
621
+ return null;
622
+ }
623
+ }
510
624
  async function waitForSpringBoard(udid, deadline) {
511
625
  for (;;) {
512
626
  let output = null;
@@ -602,7 +716,6 @@ async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = B
602
716
  let sampledAt = started;
603
717
  let longestGapMs = 0;
604
718
  let phase = "requesting boot";
605
- let springBoardUnreadable = null;
606
719
  const ranks = {
607
720
  normal: 0,
608
721
  warning: 1,
@@ -667,9 +780,7 @@ async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = B
667
780
  if (deadline - Date.now() <= 0) throw new Error(`Simulator ${udid} did not finish booting within ${Math.round(timeoutMs / 1e3)}s.`);
668
781
  }
669
782
  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;
783
+ if ((await waitForSpringBoard(udid, deadline)).state === "timed-out") throw new Error(`Simulator ${udid} did not finish booting within ${Math.round(timeoutMs / 1e3)}s.`);
673
784
  } catch (error) {
674
785
  const named = memoryCulpritAdvice(await memoryCulpritsUnderAsync(sample(), exec));
675
786
  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 });
@@ -677,7 +788,6 @@ async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = B
677
788
  clearInterval(monitor);
678
789
  }
679
790
  if (openViewer) await viewer.open(udid);
680
- return { springBoardUnreadable };
681
791
  }
682
792
  async function shutdownIosSim(udid, operation) {
683
793
  if (!operation) {
@@ -712,7 +822,11 @@ const LIST_DEVICE_TYPES_OPTIONS = {
712
822
  timeoutMs: 3e4,
713
823
  killSignal: "SIGKILL"
714
824
  };
715
- async function listIosDeviceTypesAsync({ signal, operation } = {}) {
825
+ async function listIosDeviceTypesAsync({ signal, operation, snapshot } = {}) {
826
+ if (snapshot?.deviceTypes) return snapshot.deviceTypes({
827
+ signal,
828
+ operation
829
+ });
716
830
  return parseIosDeviceTypes(await runOperationFile(operation, getExecutor(), "xcrun", LIST_DEVICE_TYPES_ARGS, {
717
831
  ...LIST_DEVICE_TYPES_OPTIONS,
718
832
  signal,
@@ -1036,7 +1150,8 @@ const LIST_RUNTIMES_OPTIONS = {
1036
1150
  function listIosRuntimes() {
1037
1151
  return parseIosRuntimes(getExecutor().runFile("xcrun", LIST_RUNTIMES_ARGS, LIST_RUNTIMES_OPTIONS));
1038
1152
  }
1039
- async function listIosRuntimesAsync({ signal } = {}) {
1153
+ async function listIosRuntimesAsync({ signal, snapshot } = {}) {
1154
+ if (snapshot?.runtimes) return snapshot.runtimes({ signal });
1040
1155
  return parseIosRuntimes(await getExecutor().runFileAsync("xcrun", LIST_RUNTIMES_ARGS, {
1041
1156
  ...LIST_RUNTIMES_OPTIONS,
1042
1157
  signal
@@ -1053,4 +1168,4 @@ function parseIosRuntimes(out) {
1053
1168
  }] : []);
1054
1169
  }
1055
1170
  //#endregion
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 };
1171
+ export { uninstallIosApp as A, memoryCulpritAdvice as B, renameIosSim as C, resolveOwnedIosSim as D, resolveIosCreation as E, memoryCulpritsUnder as F, readMemoryCulpritsAsync as H, memoryCulpritsUnderAsync as I, readHostMemoryPressure as L, configuredIosSimulatorViewer as M, parseIosSimulatorApp as N, sanitizeDeviceLabel as O, hostMemoryPressureAdvice as P, readHostMemoryPressureAsync as R, readSpringBoardPid as S, resetIosPrivacy as T, deviceHoldsApk as U, memoryCulpritFindings as V, deviceHoldsBundle as W, 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, waitForSpringBoard as j, shutdownIosSim 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, resetIosKeychain as w, pickDefaultIosCreation as x, parseRuntimeVersion as y, reportMemoryCulprits as z };
@@ -1,5 +1,5 @@
1
1
  import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
- import { dn as INSTALL_ERROR, hn as appProcessFromPid } from "./budget-dPGuhNai.mjs";
2
+ import { bn as appProcessFromPid, gn as INSTALL_ERROR } from "./budget-k2mZGvvk.mjs";
3
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";
@@ -1,46 +1,45 @@
1
- import { m as workspaceLogsDir$1 } from "./paths-DQtTgsBf.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
- import { d as optimizationBuildProfile, l as artifactCachePolicy } from "./errors-ccaPc4ox.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";
1
+ import { a as recordWorkspaceUseAsync, k as workspaceLogsDir$1 } from "./workspace-state-pUg3_RRA.mjs";
2
+ import { B as deviceSlotFileKey, W as parseDeviceSlotOption, q as validateDeviceSlot } from "./config-BktkY_zC.mjs";
3
+ import { _ as stepTimer, g as stepClock, i as formatDuration, l as phaseLine } from "./command-output-BF5AR2dL.mjs";
4
+ import { C as iosSigningIdentitySha1Setting, M as metroPortSetting, P as metroWarmupUrlSetting, R as projectSettingsContextAsync, S as iosSigningIdentitySettingError, _ as iosLanHostSetting, a as SETTING_SHAPE_REMEDY, g as deviceReclaimIdleMinutesSetting, it as tunnelModeSetting, v as iosLanHostSettingError, w as iosSigningIdentitySha1SettingError, x as iosSigningIdentitySetting, z as publicUrlSetting } from "./settings-CosW5X-S.mjs";
5
+ import { t as NO_PROJECT_REFUSAL } from "./project-BUu6Is4k.mjs";
6
+ import { ft as POOL_SETTING_REMEDY, vt as parkedMaxSetting } from "./android-DTAcRwBC.mjs";
7
+ import { G as runFailureRecord, I as NO_BUILD_PROGRESS, J as thrownRunFailureRecord, K as startBuildProgress, Un as runProcessOperation, Ut as binOnPath, Vn as exitAfterFlush, Y as createRunRecorder, hn as DEFAULT_METRO_PORT, q as tapBuildLog, tt as statsProjectKey$1, ur as ownedSessionName } from "./budget-k2mZGvvk.mjs";
8
+ import { d as runCancellationSignal, f as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-BfIDFKLH.mjs";
9
+ import { i as createIosSimSnapshot } from "./ios-WxpDJ5T1.mjs";
10
+ import { d as optimizationBuildProfile, l as artifactCachePolicy } from "./errors-DHm_U5gv.mjs";
11
+ import { k as COMPILATION_CACHE_NOT_RUN } from "./toolchain-J4J8MrAr.mjs";
12
+ import { S as setRemoteLogSink, d as simulatorRuntime } from "./client-D9CaRks-.mjs";
13
+ import { a as parseBuildMachineOption } from "./selection-BNPBZ6T5.mjs";
14
+ import { r as hostedMetroSettings } from "./metro-gateway-B6_PgD0L.mjs";
15
+ import { i as writeDevicePlacementAsync } from "./ios-state-Cw7-WQf2.mjs";
16
+ import { t as devClientPortBusy } from "./hosted-native-CpDB3-PO.mjs";
17
+ import { f as waitFlagConflict, o as leaseExpiryText } from "./device-lease-run-BmvIl7bI.mjs";
18
+ 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-CVOCp0Ft.mjs";
19
+ import { r as isEasBuildFailure } from "./eas-build-Dsj93iM9.mjs";
20
+ import { r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-Dq3RBcON.mjs";
21
+ import "./dev-client-DXR_tPVY.mjs";
22
+ import { t as didSetUpDevice } from "./device-BK-zwyd_.mjs";
25
23
  import { t as unsupportedPlan } from "./project-plan-BPwbLwQu.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";
24
+ import { a as refusePlan, i as printPlan, n as planFlagRefusal } from "./build-plan-DrMMdayj.mjs";
25
+ import { a as lastBuildRecord, o as reportIosResult, s as writeLastBuild } from "./ios-project-Ty5pHl9O.mjs";
26
+ import { t as acquireIosArtifact } from "./artifact-CsAP6AGK.mjs";
27
+ import { a as hostedIosSelectors, i as hostedIosMetroNote, n as connectIosTarget, o as iosPlacementBudget, r as deviceRemoteConflict, s as selectIosPlacement, t as connectIosBackend } from "./remote-C8S7FlPF.mjs";
28
+ import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, o as iosPoolNoCandidatesRefusal, r as iosDeviceBounds } from "./ios-device-CsyryvpT.mjs";
29
+ import { i as lanOriginUrlFor, l as verifyIosMetroRun, n as chooseLanAddress, o as finishIosRun, t as DEFAULT_DEPS } from "./dependencies-Dw6wfQdv.mjs";
32
30
  import { basename, join } from "node:path";
33
31
  import { workspaceId } from "@stim-cli/core";
34
32
  import { hostedIosStatus, parseMachine } from "@stim-cli/core/state";
35
33
  import chalk from "chalk";
36
34
  import { InvalidArgumentError } from "commander";
37
35
  //#region src/commands/ios/hosted.ts
38
- async function finishHostedIosRun({ target, d, artifact, root, slot, release, appMode, isExpo, metroCheck, metroPort, logsDir, fail, note, enterPhase, selectors, projectBundleId, ...report }) {
36
+ async function finishHostedIosRun({ target, d, artifact, root, slot, release, appMode, isExpo, metroCheck, metroPort, logsDir, fail, note, phase, enterPhase, enterActivity, selectors, projectBundleId, ...report }) {
39
37
  const bundleId = artifact.bundleId ?? (await d.readBundleId(artifact.path) || await projectBundleId());
40
38
  if (!bundleId) return fail({
41
39
  code: "STIM_INSTALL_FAILED",
42
40
  message: "The built app has no bundle identifier."
43
41
  });
42
+ const devClientScheme = appMode === "development" && isExpo ? d.devClientScheme(root, artifact.path) ?? void 0 : void 0;
44
43
  const launchedAt = d.now();
45
44
  let run;
46
45
  try {
@@ -53,7 +52,7 @@ async function finishHostedIosRun({ target, d, artifact, root, slot, release, ap
53
52
  selectors,
54
53
  release,
55
54
  mode: appMode,
56
- ...appMode === "development" && isExpo ? { devClientScheme: d.devClientScheme(root, artifact.path) ?? void 0 } : {},
55
+ ...appMode === "development" && isExpo ? { devClientScheme } : {},
57
56
  metroPort,
58
57
  reserved: (placement) => d.writeHostedIos(root, slot, placement),
59
58
  note,
@@ -76,23 +75,48 @@ async function finishHostedIosRun({ target, d, artifact, root, slot, release, ap
76
75
  launchedAt: new Date(launchedAt).toISOString()
77
76
  }, slot);
78
77
  let launched = run.launched;
79
- if (appMode === "development" && metroCheck) {
80
- const evidence = await d.verifyLaunch({
81
- requireBundleResponse: true,
82
- platform: "ios",
83
- logsDir,
84
- since: launchedAt,
85
- metroPort,
86
- mode: workspaceDevServerMode(root, isExpo),
87
- slot: launchSlotScope(root, slot),
88
- platformShared: (await siblingPlatformSlots(root, "ios", slot)).length > 0
89
- });
90
- if (evidence.fatal) return fail({
78
+ let launchWarning;
79
+ if (appMode === "development") {
80
+ const hostedLogs = d.followHostedLaunchLogs(root, slot, "ios", launchedAt);
81
+ let verification;
82
+ try {
83
+ verification = await verifyIosMetroRun({
84
+ root,
85
+ slot,
86
+ appPath: artifact.path,
87
+ d,
88
+ launched: {},
89
+ configuration: report.configuration,
90
+ phase,
91
+ note,
92
+ metroCheck,
93
+ logsDir,
94
+ launchedAt,
95
+ metroPort,
96
+ isExpo,
97
+ bundleId,
98
+ udid: run.placement.device?.udid ?? "",
99
+ scheme: devClientScheme,
100
+ physical: false,
101
+ appName: null,
102
+ lanAddress: null,
103
+ lanOrigin: null,
104
+ remoteDevice: true,
105
+ metroOrigin: null,
106
+ enterActivity,
107
+ hostedLogs
108
+ });
109
+ } finally {
110
+ hostedLogs.stop();
111
+ }
112
+ if (verification.state === "fatal") return fail({
91
113
  code: "STIM_LAUNCH_FAILED",
92
- message: "Metro could not deliver the hosted app bundle.",
93
- remedy: "Run stim logs --errors and fix the bundle error."
114
+ message: "The app failed its launch readiness check.",
115
+ remedy: `Read the launch error above or run \`stim logs --errors\`. The full timeline is in ${logsDir}.`,
116
+ logPath: logsDir
94
117
  });
95
- launched = evidence.verified ? true : evidence.requested ? "bundling" : "unverified";
118
+ launched = verification.state === true ? true : verification.state === "bundling" ? "bundling" : "unverified";
119
+ launchWarning = verification.warning;
96
120
  }
97
121
  if (launched === "unverified") note(`Launch on ${target.host.machine} is unverified; check the hosted app, then retry stim ios --remote ${target.host.machine}.`);
98
122
  const cache = artifact.cache;
@@ -126,6 +150,7 @@ async function finishHostedIosRun({ target, d, artifact, root, slot, release, ap
126
150
  useBuildCache: cache.readEnabled,
127
151
  waitedForBuild: cache.waitedForBuild,
128
152
  launchState: launched,
153
+ launchWarning,
129
154
  providerName: cache.providerName,
130
155
  buildMachine: cache.buildMachine,
131
156
  builtOn: cache.builtOn,
@@ -564,6 +589,7 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
564
589
  easProfile: opts.easProfile
565
590
  });
566
591
  if (capabilityRefusal) return fail(capabilityRefusal);
592
+ const simSnapshot = createIosSimSnapshot();
567
593
  const remoteSelection = await selectIosPlacement({
568
594
  root,
569
595
  env: context.env,
@@ -590,8 +616,10 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
590
616
  deviceTypeOrigin: d.settingOriginScope(d.settingsLayers(settingsContext), "ios.deviceType"),
591
617
  runtimeOrigin: d.settingOriginScope(d.settingsLayers(settingsContext), "ios.runtime"),
592
618
  listRuntimes: d.listIosRuntimes,
593
- signal: context.signal
619
+ signal: context.signal,
620
+ snapshot: simSnapshot
594
621
  }),
622
+ simSnapshot,
595
623
  noWait: deviceSlotWaitMs === 0,
596
624
  note,
597
625
  phase,
@@ -623,7 +651,8 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
623
651
  remoteBackend,
624
652
  hosted: Boolean(hostedMachine),
625
653
  listRuntimes: d.listIosRuntimes,
626
- signal: context.signal
654
+ signal: context.signal,
655
+ snapshot: simSnapshot
627
656
  });
628
657
  if (modelRefusal) return fail(modelRefusal);
629
658
  const selectors = hostedIosSelectors(deviceType, runtime);
@@ -631,7 +660,6 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
631
660
  if ("failure" in connected) return fail(connected.failure);
632
661
  const hostedTarget = connected.target;
633
662
  try {
634
- const simSnapshot = createIosSimSnapshot();
635
663
  const budget = await iosPlacementBudget(d, root, note, Boolean(hostedTarget), remoteSelection.budget, simSnapshot, context.env);
636
664
  reclaimed = budget.reclaimed;
637
665
  if (budget.refusal) return fail(budget.refusal);
@@ -890,7 +918,9 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
890
918
  platform: "ios",
891
919
  isExpo,
892
920
  appId: proj?.bundleId,
893
- bundleUrl: metroWarmupUrlSetting(settings, "ios")
921
+ bundleUrl: metroWarmupUrlSetting(settings, "ios"),
922
+ logsDir,
923
+ root
894
924
  });
895
925
  return {
896
926
  ok: true,
@@ -1088,7 +1118,9 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
1088
1118
  devServer,
1089
1119
  fail,
1090
1120
  note,
1121
+ phase,
1091
1122
  enterPhase: progress.step,
1123
+ enterActivity: progress.activity,
1092
1124
  selectors
1093
1125
  });
1094
1126
  if (!localBoot) {
@@ -1180,6 +1212,7 @@ async function runIos(context, projectRoot, opts = {}, overrides = {}, progress
1180
1212
  } catch (error) {
1181
1213
  return reportRunFailure(error);
1182
1214
  } finally {
1215
+ artifact?.cancelFingerprintCheck();
1183
1216
  await artifact?.release();
1184
1217
  }
1185
1218
  } finally {
@@ -1,9 +1,9 @@
1
- import { l as workspaceAgentDeviceDir } from "./paths-DQtTgsBf.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";
1
+ import { w as workspaceAgentDeviceDir } from "./workspace-state-pUg3_RRA.mjs";
2
+ import { i as formatDuration, l as phaseLine } from "./command-output-BF5AR2dL.mjs";
3
+ import { a as workspaceLinkLine } from "./stim-desktop-6Dqp-gjX.mjs";
4
+ import { Gn as UPLOAD_TIMEOUT_MS, Jn as easAuthNote, Kn as cacheLevel, W as recordFinishedBuild, Yn as isEasAuthFailureText } from "./budget-k2mZGvvk.mjs";
5
+ import { P as compilationCacheActivityLine, k as COMPILATION_CACHE_NOT_RUN } from "./toolchain-J4J8MrAr.mjs";
6
+ import { i as deviceLabel } from "./support-CVOCp0Ft.mjs";
7
7
  import { buildDiagnostics } from "@stim-cli/core/state";
8
8
  import chalk from "chalk";
9
9
  //#region src/commands/ios/result.ts
@@ -1,4 +1,4 @@
1
- import { l as withWorkspaceStateLockAsync, o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-CeBpIZgr.mjs";
1
+ import { l as withWorkspaceStateLockAsync, o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-pUg3_RRA.mjs";
2
2
  import { HOSTED_METRO_REQUESTS_KEY, hostedMetroRequests, hostedNativeRecords, isJsonObject, parseHostedNativePlacement, unreadableHostedNative } from "@stim-cli/core/state";
3
3
  //#region src/device-host/ios-state.ts
4
4
  function readHostedNative(root, platform, slot) {
@@ -1,10 +1,10 @@
1
1
  import { _ as spawnDeclared, b as operationState, c as throwIfCancelled, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
2
  import { r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
3
3
  import { a as killOnAbort, t as runOperationFile } from "./operation-exec-CUZifp6Z.mjs";
4
- import { Ht as makeTemporaryDirectory, Ut as removeTemporaryEntry } from "./settings-RKwY33wv.mjs";
5
- import { Qn as bundleInvocation } from "./budget-dPGuhNai.mjs";
6
- import { s as expoTelemetryEnv, t as cleanLine } from "./server-expo-Tt_hLRpy.mjs";
7
- import { _ as tailLines, h as startBuildHeartbeat, r as HEARTBEAT_INTERVAL_MS } from "./xcode-DHu41qQ4.mjs";
4
+ import { Ut as makeTemporaryDirectory, Wt as removeTemporaryEntry } from "./settings-CosW5X-S.mjs";
5
+ import { rr as bundleInvocation } from "./budget-k2mZGvvk.mjs";
6
+ import { s as expoTelemetryEnv, t as cleanLine } from "./server-expo-eQfOdydb.mjs";
7
+ import { G as tailLines, U as startBuildHeartbeat, j as HEARTBEAT_INTERVAL_MS } from "./toolchain-J4J8MrAr.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { basename, join } from "node:path";