stim 1.20.2 → 1.22.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 (231) hide show
  1. package/README.md +141 -8
  2. package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
  3. package/dist/act-DsuqEkiM.mjs +2801 -0
  4. package/dist/activity-CMLmzp7o.mjs +1397 -0
  5. package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
  6. package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
  7. package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
  8. package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
  9. package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
  10. package/dist/android-cas-compiler.mjs +2 -2
  11. package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
  12. package/dist/android-project-BCAAmMwz.mjs +12 -0
  13. package/dist/android-project-DVWyCbWU.d.mts +391 -0
  14. package/dist/api.d.mts +810 -64
  15. package/dist/api.mjs +782 -1
  16. package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
  17. package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
  18. package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
  19. package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
  20. package/dist/budget-Cvwn54qV.mjs +9285 -0
  21. package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
  22. package/dist/build-cache-Dv7RN200.mjs +602 -0
  23. package/dist/build-plan-DUC8Ka9y.mjs +248 -0
  24. package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
  25. package/dist/cache-manifest.mjs +1 -1
  26. package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
  27. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
  28. package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
  29. package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
  30. package/dist/cli.mjs +1 -1
  31. package/dist/client-OyRoEuSr.mjs +1577 -0
  32. package/dist/collector-run.d.mts +4 -40
  33. package/dist/collector-run.mjs +9 -8
  34. package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
  35. package/dist/config-DlrsduwG.mjs +955 -0
  36. package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
  37. package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
  38. package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
  39. package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
  40. package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
  41. package/dist/device-DklWZLqb.mjs +1068 -0
  42. package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
  43. package/dist/device-host-worker.mjs +76 -79
  44. package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
  45. package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
  46. package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
  47. package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
  48. package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
  49. package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
  50. package/dist/doctor-fingerprint.mjs +19 -0
  51. package/dist/doctor-thjWAV0z.mjs +2 -0
  52. package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
  53. package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
  54. package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
  55. package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
  56. package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
  57. package/dist/exec-DEoAhcze.mjs +858 -0
  58. package/dist/exec-DnYc4HGH.d.mts +78 -0
  59. package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
  60. package/dist/gc-DnNDQyaP.mjs +3 -0
  61. package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
  62. package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
  63. package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
  64. package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
  65. package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
  66. package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
  67. package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
  68. package/dist/idle-C4cZ757K.d.mts +24 -0
  69. package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
  70. package/dist/ios-CDvlmUs7.d.mts +24 -0
  71. package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
  72. package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
  73. package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
  74. package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
  75. package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
  76. package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
  77. package/dist/ios-signing-BtAffm0A.mjs +489 -0
  78. package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
  79. package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
  80. package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
  81. package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
  82. package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
  83. package/dist/logs-BfwwadsZ.mjs +479 -0
  84. package/dist/logs-jTS_lHSo.mjs +248 -0
  85. package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
  86. package/dist/macos-NfV2D7dO.mjs +694 -0
  87. package/dist/macos-run.mjs +1 -1
  88. package/dist/maintenance-run.mjs +123 -248
  89. package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
  90. package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
  91. package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
  92. package/dist/native-android-CqgnOgsT.mjs +645 -0
  93. package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
  94. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
  95. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  96. package/dist/native-run-NwUuxbkg.mjs +276 -0
  97. package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
  98. package/dist/native-source-Y0yLhFyQ.mjs +133 -0
  99. package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
  100. package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
  101. package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
  102. package/dist/offload-worker.d.mts +59 -41
  103. package/dist/offload-worker.mjs +478 -115
  104. package/dist/operation-exec-BW0em61G.mjs +171 -0
  105. package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
  106. package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
  107. package/dist/paths-BsJMoPP2.mjs +12 -0
  108. package/dist/paths-DQtTgsBf.mjs +42 -0
  109. package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
  110. package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
  111. package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
  112. package/dist/prebuild-D4JoEAEs.mjs +484 -0
  113. package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
  114. package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
  115. package/dist/pull-request-eODyIqZF.d.mts +124 -0
  116. package/dist/pull-requests.d.mts +2 -120
  117. package/dist/pull-requests.mjs +2 -2
  118. package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
  119. package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
  120. package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
  121. package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
  122. package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
  123. package/dist/registration-BcRgF6Ox.mjs +51 -0
  124. package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
  125. package/dist/reload-D7AVlb8N.mjs +2 -0
  126. package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
  127. package/dist/result-D2Ykz_iD.mjs +435 -0
  128. package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
  129. package/dist/selection-DSMbWEX2.mjs +620 -0
  130. package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
  131. package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
  132. package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
  133. package/dist/server-expo-D58c9L0M.mjs +2 -0
  134. package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
  135. package/dist/settings-DpR-1Wnn.mjs +114 -0
  136. package/dist/settings-write-CzD60rOD.mjs +360 -0
  137. package/dist/settings.schema.json +176 -16
  138. package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
  139. package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
  140. package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
  141. package/dist/stage-Bps5oius.mjs +200 -0
  142. package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
  143. package/dist/start-EojN4WFz.mjs +1364 -0
  144. package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
  145. package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
  146. package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
  147. package/dist/stats-report-BzaPrRm6.mjs +16 -0
  148. package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
  149. package/dist/status-EvrK72L2.mjs +2 -0
  150. package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
  151. package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
  152. package/dist/status-worker.d.mts +1 -0
  153. package/dist/status-worker.mjs +19 -0
  154. package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
  155. package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
  156. package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
  157. package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
  158. package/dist/supervisor-run.d.mts +8 -17
  159. package/dist/supervisor-run.mjs +56 -28
  160. package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
  161. package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
  162. package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
  163. package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
  164. package/dist/toolchain-BY8X8HXx.mjs +2 -0
  165. package/dist/toolchain-DpJMHq0n.mjs +876 -0
  166. package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
  167. package/dist/trigger-yb_nFzPF.mjs +2 -0
  168. package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
  169. package/dist/web-CZ07gd77.mjs +2 -0
  170. package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
  171. package/dist/web-run.mjs +13 -12
  172. package/dist/windows-report.d.mts +1 -0
  173. package/dist/windows-report.mjs +18 -0
  174. package/dist/windows-report.ps1 +43 -0
  175. package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
  176. package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
  177. package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
  178. package/dist/worktree-ZqZVjD9K.mjs +2 -0
  179. package/dist/xcode-BXn9-xYx.mjs +896 -0
  180. package/package.json +7 -5
  181. package/shim/android-audio/Main.java +24 -0
  182. package/shim/android-audio/README.md +17 -0
  183. package/shim/android-audio.jar +0 -0
  184. package/shim/android-optimizations.gradle +7 -5
  185. package/dist/activity-BSV745Kz.mjs +0 -629
  186. package/dist/api-qvOzWyfO.mjs +0 -154
  187. package/dist/api-run.mjs +0 -294
  188. package/dist/app-install-BIKtMfPq.mjs +0 -896
  189. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  190. package/dist/budget-f7516Zk0.mjs +0 -4106
  191. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  192. package/dist/cancellation-C_22VQTH.mjs +0 -24
  193. package/dist/client-qQAaXSUs.mjs +0 -1771
  194. package/dist/config-BYDxlMY3.mjs +0 -562
  195. package/dist/device-DuiPJQSn.mjs +0 -290
  196. package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
  197. package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
  198. package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
  199. package/dist/exec-DqKo9GKJ.mjs +0 -268
  200. package/dist/git-DDfFzkMm.mjs +0 -45
  201. package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
  202. package/dist/logs-BGrEUaEs.mjs +0 -383
  203. package/dist/macos-Ch5VJmcS.mjs +0 -584
  204. package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
  205. package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
  206. package/dist/native-android-D5qc3-_v.mjs +0 -226
  207. package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
  208. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  209. package/dist/plan-C4TjdPsR.mjs +0 -260
  210. package/dist/prebuild-DYbucPXy.mjs +0 -212
  211. package/dist/preview-78a9kR_-.mjs +0 -1011
  212. package/dist/react-native-build-CtCccJtb.mjs +0 -239
  213. package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
  214. package/dist/remote-cache-OyOyVIS3.mjs +0 -526
  215. package/dist/result-CaJg5Iat.mjs +0 -186
  216. package/dist/server-expo-Bigriskl.mjs +0 -2
  217. package/dist/settings-BORNaaCO.mjs +0 -402
  218. package/dist/settings-vk3mJGSm.d.mts +0 -13
  219. package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
  220. package/dist/stage-KNTQopqv.mjs +0 -157
  221. package/dist/start-BWqzODpb.mjs +0 -1116
  222. package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
  223. package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
  224. package/dist/tailnet-Dh-qiYzG.mjs +0 -265
  225. package/dist/toolchain-BFkAcstd.mjs +0 -2
  226. package/dist/toolchain-DxSsNssu.mjs +0 -1657
  227. package/dist/trigger-9_USgmxz.mjs +0 -2
  228. package/dist/web-Dq-i3wzJ.mjs +0 -2
  229. package/dist/worktree-DpLdCHga.mjs +0 -2
  230. package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
  231. package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
@@ -1,428 +0,0 @@
1
- import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
2
- import { s as isAppLaunchError } from "./command-output-BTy8hZ0F.mjs";
3
- import { s as readNdjsonGenerations } from "./ndjson-GOnbyvso.mjs";
4
- import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-B5veSDDQ.mjs";
5
- import { n as ANDROID_DISABLE_AUTO_LAUNCH_EXTRA, p as deviceShellArg, s as androidAppProcess } from "./app-install-BIKtMfPq.mjs";
6
- import { join } from "node:path";
7
- //#region src/engine/app-readiness.ts
8
- const APP_READINESS_TIMEOUT_MS = 3e4;
9
- function appReadinessSignal(record, platform) {
10
- if (record.src !== "device" || !platform || record.platform !== platform) return null;
11
- if (record.level !== "info" && record.level !== "debug") return null;
12
- if (typeof record.msg !== "string") return null;
13
- const text = record.msg.trim();
14
- const message = /^(?:'[^']*'|"[^"]*")$/.test(text) ? text.slice(1, -1) : text;
15
- return /^\[stim:readiness\] (pending|ready)$/.exec(message)?.[1] ?? null;
16
- }
17
- //#endregion
18
- //#region src/engine/launch-verify.ts
19
- const RELEASE_VERIFY_WAIT_MS = 3e3;
20
- async function verifyReleaseLaunch({ pid, waitMs = RELEASE_VERIFY_WAIT_MS, alive = isProcessAlive, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) }) {
21
- const startedAt = now();
22
- if (!pid) return {
23
- verified: false,
24
- reason: "no-pid",
25
- waitedMs: 0
26
- };
27
- await sleep(Math.max(0, waitMs));
28
- const waitedMs = now() - startedAt;
29
- return alive(pid) ? {
30
- verified: true,
31
- waitedMs
32
- } : {
33
- verified: false,
34
- reason: "exited",
35
- waitedMs
36
- };
37
- }
38
- async function verifyAndroidReleaseLaunch({ serial, packageName, waitMs = RELEASE_VERIFY_WAIT_MS, exec = null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) }) {
39
- const e = exec || getExecutor();
40
- const startedAt = now();
41
- await sleep(Math.max(0, waitMs));
42
- const running = androidAppProcess(serial, packageName, { exec: e });
43
- const waitedMs = now() - startedAt;
44
- if (running.state === "unknown") return {
45
- verified: false,
46
- reason: "probe-failed",
47
- waitedMs
48
- };
49
- return running.state === "running" ? {
50
- verified: true,
51
- waitedMs,
52
- pid: running.pid
53
- } : {
54
- verified: false,
55
- reason: "exited",
56
- waitedMs,
57
- pid: null
58
- };
59
- }
60
- function isProcessAlive(pid) {
61
- try {
62
- process.kill(pid, 0);
63
- return true;
64
- } catch (err) {
65
- return err?.code === "EPERM";
66
- }
67
- }
68
- const LAUNCH_UNVERIFIED = "unverified";
69
- const LAUNCH_BUNDLING = "bundling";
70
- const LAUNCH_FATAL = "fatal";
71
- const VERIFY_TIMEOUT_MS = 2e4;
72
- const STABILITY_WINDOW_MS = 3e3;
73
- const VERIFY_POLL_MS = 500;
74
- const BUNDLE_EVENTS = /* @__PURE__ */ new Set([
75
- "bundle_build_started",
76
- "bundle_build_done",
77
- "bundle_build_failed",
78
- "bundling_error",
79
- "transformer_error",
80
- "bundle_response_started",
81
- "bundle_response_finished",
82
- "bundle_response_failed"
83
- ]);
84
- function isBundleProof(record, since = 0, platform = null) {
85
- if (!record || typeof record !== "object") return false;
86
- const rec = record;
87
- const ts = Number(rec.ts);
88
- if (!Number.isFinite(ts) || ts < Number(since || 0)) return false;
89
- if (platform && recordPlatform(rec) !== platform) return false;
90
- if (typeof rec.event === "string" && BUNDLE_EVENTS.has(rec.event)) return true;
91
- if (rec.src === "metro" && typeof rec.msg === "string" && expoBundleLine(rec.msg)) return true;
92
- return false;
93
- }
94
- const BUNDLE_URL_PATH = /\.bundle\b|\/_expo\/|expo-development-client/i;
95
- function isBundleRequestProof(record, since = 0, port = null, platform = null) {
96
- if (!record || typeof record !== "object" || !port) return false;
97
- const rec = record;
98
- const ts = Number(rec.ts);
99
- if (!Number.isFinite(ts) || ts < Number(since || 0)) return false;
100
- if (typeof rec.msg !== "string") return false;
101
- if (rec.level === "error" || rec.level === "fatal") return false;
102
- const sourcePlatform = recordPlatform(rec);
103
- if (platform && sourcePlatform && sourcePlatform !== platform) return false;
104
- const digits = String(port).replace(/[^0-9]/g, "");
105
- if (!digits) return false;
106
- if (!new RegExp(`:${digits}\\b`).test(rec.msg)) return false;
107
- return BUNDLE_URL_PATH.test(rec.msg);
108
- }
109
- function expoBundleLine(msg) {
110
- return /\bBundl(?:ing|ed)\b/.test(msg);
111
- }
112
- function nativeLaunchFailure({ readCrashes, since, platform, processAlive, mode, waitedMs }) {
113
- if (!readCrashes) return null;
114
- const crashes = readCrashes().filter((record) => record.event === "native_crash" && after(record, since) && recordCouldBelongToPlatform(record, platform));
115
- return crashes.length ? {
116
- verified: false,
117
- fatal: true,
118
- errors: crashes,
119
- processAlive: processAlive?.() ?? null,
120
- mode,
121
- waitedMs
122
- } : null;
123
- }
124
- async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metroPort = null, platform = null, mode = null, requireBundleResponse, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, onActivity, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
125
- const delivered = (record) => deliveryOwner(record, {
126
- slot,
127
- appPid,
128
- platformShared
129
- }) === "this";
130
- const read = readRecords || (() => readMetroRecords(logsDir));
131
- const readDevice = readDeviceRecords || (() => readNdjson(logsDir, "device.ndjson"));
132
- const readClient = readClientRecords || (() => readNdjson(logsDir, "client.ndjson"));
133
- const startedAt = now();
134
- const bundleDeadline = startedAt + Math.max(0, timeoutMs);
135
- let proof = null;
136
- let activity = null;
137
- let stabilityDeadline = null;
138
- let pendingAt = null;
139
- let deliveryId = null;
140
- let runtimeLoadingAt = null;
141
- let runtimeStartedAt = null;
142
- let nextCrashCheck = startedAt + 1e3;
143
- let bundlingAt = null;
144
- let reported = null;
145
- const report = (name, at) => {
146
- if (name === reported) return;
147
- reported = name;
148
- onActivity?.(name, at);
149
- };
150
- while (true) {
151
- const metroRecords = read().filter((record) => after(record, since));
152
- const bundleRecords = metroRecords.filter((record) => (!requireBundleResponse || String(record.event).startsWith("bundle_response_")) && delivered(record));
153
- const deviceRecords = readDevice().filter((record) => after(record, since) && (slot === void 0 || (record.slot ?? "default") === slot));
154
- const clientRecords = readClient().filter((record) => after(record, since) && !platformShared);
155
- if (now() >= nextCrashCheck) {
156
- nextCrashCheck = now() + 2e3;
157
- const crash = nativeLaunchFailure({
158
- readCrashes: readNativeCrashes,
159
- since,
160
- platform,
161
- processAlive,
162
- mode,
163
- waitedMs: now() - startedAt
164
- });
165
- if (crash) return crash;
166
- }
167
- if (deliveryId === null) {
168
- const request = bundleRecords.find((record) => record.event === "bundle_response_started" && typeof record.requestId === "string" && isBundleProof(record, since, platform));
169
- if (request) {
170
- deliveryId = request.requestId;
171
- bundlingAt = request;
172
- proof = null;
173
- stabilityDeadline = null;
174
- }
175
- }
176
- for (const record of bundleRecords) {
177
- if (isBundleProof(record, since, platform)) activity = record;
178
- const completed = deliveryId === null ? isBundleReadyProof(record, since, platform) : record.event === "bundle_response_finished" && record.requestId === deliveryId && isBundleProof(record, since, platform);
179
- if (!proof && completed) {
180
- proof = record;
181
- stabilityDeadline = Number(record.ts) + Math.max(0, stabilityMs);
182
- }
183
- }
184
- const signals = deviceRecords.filter((record) => Number(record.ts) <= now()).toSorted((a, b) => Number(a.ts) - Number(b.ts));
185
- if (platform === "android" && runtimeLoadingAt === null) {
186
- const loading = signals.find((record) => record.src === "device" && record.platform === "android" && /^(?:unknown:)?BridgelessReact\(\d+\)$/.test(String(record.proc)) && /^ReactHost\{\d+\}\.getOrCreateReactInstanceTask\(\): Loading JS Bundle$/.test(String(record.msg)) && (stabilityDeadline === null || Number(record.ts) <= stabilityDeadline));
187
- if (loading) runtimeLoadingAt = Number(loading.ts);
188
- }
189
- if (runtimeLoadingAt !== null && runtimeStartedAt === null) {
190
- const executing = signals.find((record) => record.src === "device" && record.platform === "android" && Number(record.ts) >= runtimeLoadingAt && (/^ReactNativeJS\(\d+\)$/.test(String(record.proc)) || appReadinessSignal(record, platform) !== null));
191
- if (executing) runtimeStartedAt = Number(executing.ts);
192
- }
193
- const runtimeWaiting = runtimeLoadingAt !== null && runtimeStartedAt === null;
194
- const completedAt = proof ? Math.max(Number(proof.ts), runtimeStartedAt ?? 0) : null;
195
- if (completedAt !== null) stabilityDeadline = completedAt + Math.max(0, stabilityMs);
196
- const readinessDeadline = completedAt !== null ? completedAt + APP_READINESS_TIMEOUT_MS : bundleDeadline;
197
- if (pendingAt === null) {
198
- const pending = signals.find((record) => appReadinessSignal(record, platform) === "pending" && (runtimeWaiting || stabilityDeadline === null || Number(record.ts) <= stabilityDeadline));
199
- if (pending) {
200
- pendingAt = Number(pending.ts);
201
- onReadinessPending?.();
202
- }
203
- }
204
- report(...launchActivity(pendingAt, proof, bundlingAt));
205
- const ready = pendingAt !== null && signals.some((record) => Number(record.ts) >= pendingAt && Number(record.ts) <= readinessDeadline && appReadinessSignal(record, platform) === "ready");
206
- const bundleErrors = bundleRecords.filter((record) => isFatalLaunchError(record, platform) || deliveryId !== null && record.event === "bundle_response_failed" && record.requestId === deliveryId && isBundleProof(record, since, platform));
207
- if (bundleErrors.length) {
208
- const alive = processAlive ? processAlive() : null;
209
- const fatalRecord = bundleErrors[bundleErrors.length - 1];
210
- const fatalAt = Number(fatalRecord?.ts ?? since ?? 0);
211
- return {
212
- verified: false,
213
- fatal: true,
214
- errors: metroRecords.filter((record) => after(record, fatalAt) && recordCouldBelongToPlatform(record, platform) && isLaunchError(record, platform)),
215
- processAlive: alive,
216
- record: fatalRecord,
217
- mode,
218
- waitedMs: now() - startedAt,
219
- ...pendingAt !== null ? { readiness: "error" } : {}
220
- };
221
- }
222
- if (proof && stabilityDeadline !== null && (pendingAt !== null || now() >= stabilityDeadline)) {
223
- const errorSince = pendingAt === null ? Number(proof.ts ?? since ?? 0) : Number(since ?? 0);
224
- const errors = [
225
- ...metroRecords.filter((record) => after(record, errorSince) && recordCouldBelongToPlatform(record, platform)),
226
- ...deviceRecords.filter((record) => after(record, errorSince) && recordCouldBelongToPlatform(record, platform)),
227
- ...clientRecords.filter((record) => after(record, errorSince) && recordCouldBelongToPlatform(record, platform))
228
- ].filter((record) => isLaunchError(record, platform));
229
- const alive = processAlive ? processAlive() : null;
230
- const waitedMs = now() - startedAt;
231
- if (alive === false) return {
232
- verified: false,
233
- fatal: true,
234
- errors,
235
- processAlive: alive,
236
- record: proof,
237
- mode,
238
- waitedMs,
239
- ...pendingAt !== null ? { readiness: "error" } : {}
240
- };
241
- const actionableErrors = errors.filter((record) => !isIosConnectionRefusal(record, platform));
242
- const appErrors = actionableErrors.some(isAppLaunchError);
243
- if (!runtimeWaiting && pendingAt === null || appErrors || ready || now() >= readinessDeadline) return {
244
- verified: true,
245
- record: proof,
246
- errors: actionableErrors,
247
- processAlive: alive,
248
- mode,
249
- waitedMs,
250
- ...pendingAt !== null ? { readiness: appErrors ? "error" : ready ? "ready" : "timed-out" } : {}
251
- };
252
- }
253
- if ((!proof || runtimeWaiting) && now() >= bundleDeadline) return bundleTimeoutOutcome({
254
- requested: findBundleRequest(deviceRecords, since, metroPort, platform) ?? activity,
255
- unattributed: metroRecords.find((record) => record.event === "bundle_response_finished" && deliveryOwner(record, {
256
- slot,
257
- appPid,
258
- platformShared
259
- }) === "unknown" && isBundleProof(record, since, platform)) ?? null,
260
- processAlive,
261
- deviceRecords,
262
- platform,
263
- mode,
264
- waitedMs: now() - startedAt
265
- });
266
- await sleep(Math.min(pollMs, Math.max(0, (runtimeWaiting ? bundleDeadline : proof && pendingAt !== null ? readinessDeadline : stabilityDeadline ?? bundleDeadline) - now())));
267
- }
268
- }
269
- function launchActivity(pendingAt, proof, bundling) {
270
- if (pendingAt !== null) return ["waiting-ready", pendingAt];
271
- if (proof) return [null, Number(proof.ts)];
272
- return bundling ? ["bundling", Number(bundling.ts)] : [null, 0];
273
- }
274
- function deliveryOwner(record, { slot, appPid, platformShared }) {
275
- if (slot === void 0) return "this";
276
- if (typeof record.clientPid === "number" && appPid) return record.clientPid === appPid ? "this" : "other";
277
- return platformShared ? "unknown" : "this";
278
- }
279
- function bundleTimeoutOutcome({ requested, unattributed, processAlive, deviceRecords, platform, mode, waitedMs }) {
280
- if (processAlive?.() === false) return {
281
- verified: false,
282
- fatal: true,
283
- errors: deviceRecords.filter((record) => recordCouldBelongToPlatform(record, platform) && isLaunchError(record, platform) && !isIosConnectionRefusal(record, platform)),
284
- processAlive: false,
285
- mode,
286
- waitedMs
287
- };
288
- if (requested) return {
289
- verified: false,
290
- timedOut: true,
291
- requested: true,
292
- record: requested,
293
- mode,
294
- waitedMs
295
- };
296
- return unattributed ? {
297
- verified: false,
298
- timedOut: true,
299
- unattributed: true,
300
- record: unattributed,
301
- mode,
302
- waitedMs
303
- } : {
304
- verified: false,
305
- timedOut: true,
306
- mode,
307
- waitedMs
308
- };
309
- }
310
- function after(record, since) {
311
- const ts = Number(record.ts);
312
- return Number.isFinite(ts) && ts >= Number(since ?? 0);
313
- }
314
- function isLaunchError(record, platform) {
315
- return record.level === "error" || record.level === "fatal" || isFatalLaunchError(record, platform);
316
- }
317
- const TCP_REFUSAL = /^TCP Conn 0x[0-9a-f]+ Failed : error 0:61 \[61\]$/i;
318
- function isIosConnectionRefusal(record, platform) {
319
- return platform === "ios" && record.src === "device" && record.level === "error" && typeof record.msg === "string" && TCP_REFUSAL.test(record.msg);
320
- }
321
- function isFatalLaunchError(record, platform) {
322
- if (platform && recordPlatform(record) !== platform) return false;
323
- return record.event === "bundle_build_failed" || record.event === "bundling_error" || record.event === "transformer_error" || [
324
- "expo_stdout",
325
- "expo_stderr",
326
- "command_stdout",
327
- "command_stderr"
328
- ].includes(String(record.event)) && typeof record.msg === "string" && /\bBundling failed\b/.test(record.msg);
329
- }
330
- function isBundleReadyProof(record, since = 0, platform = null) {
331
- if (!isBundleProof(record, since, platform)) return false;
332
- const rec = record;
333
- if (rec.event === "bundle_build_done") return true;
334
- return rec.src === "metro" && typeof rec.msg === "string" && /\bBundled\b/.test(rec.msg);
335
- }
336
- function findBundleRequest(records, since, port, platform) {
337
- for (const record of records) if (isBundleRequestProof(record, since ?? 0, port, platform)) return record;
338
- return null;
339
- }
340
- function recordCouldBelongToPlatform(record, platform) {
341
- if (!platform) return true;
342
- const sourcePlatform = recordPlatform(record);
343
- return sourcePlatform === null || sourcePlatform === platform;
344
- }
345
- function recordPlatform(record) {
346
- if (record.platform === "ios" || record.platform === "android") return record.platform;
347
- if (typeof record.msg !== "string") return null;
348
- const match = record.msg.match(/\b(iOS|Android)\s+Bundl(?:ed|ing)\b/i);
349
- if (!match) return null;
350
- return match[1].toLowerCase() === "ios" ? "ios" : "android";
351
- }
352
- function readMetroRecords(logsDir) {
353
- return readNdjson(logsDir, "metro.ndjson");
354
- }
355
- function readCollectorRecords(logsDir) {
356
- return readNdjson(logsDir, "device.ndjson");
357
- }
358
- function readNdjson(logsDir, name) {
359
- return logsDir ? readNdjsonGenerations(join(logsDir, name)) : [];
360
- }
361
- function unattributedLaunchLines({ platform, metroPort, slot = "default", siblings }) {
362
- const others = siblings.length === 1 ? `Slot ${siblings[0]} also runs` : `Slots ${siblings.join(", ")} also run`;
363
- return [
364
- `UNVERIFIED: Metro delivered ${platform === "ios" ? "an iOS" : "an Android"} bundle on port ${metroPort}, but not provably to this device`,
365
- `${others} ${platform} on this workspace's Metro, and this bundle delivery could not be matched to this device.`,
366
- `Check this device directly: its screen through your device tool, or \`stim logs --slot ${slot} --source device\`. A slot stops counting as a sibling after \`stim stop --slot <name>\`.`
367
- ];
368
- }
369
- function unverifiedLaunchLines({ platform, metroPort, waitedMs = VERIFY_TIMEOUT_MS, bundleId = null, udid = null, serial = null, devClientUrl: url = null, mode = null, remote = false, physical = false, devClient = false, lanOrigin = null, metroOrigin = null, localNetworkPending = false, component = null }) {
370
- const seconds = Math.round(Number(waitedMs || 0) / 1e3);
371
- const localNetwork = localNetworkPending && platform === "ios" && physical;
372
- const lines = [`The app was started, but nothing fetched a bundle from this workspace's Metro (port ${metroPort}) within ${seconds}s.`];
373
- const origin = metroOrigin || `http://localhost:${metroPort}`;
374
- const picker = `If expo-dev-launcher's DEVELOPMENT SERVERS picker is showing, tap the entry for ${origin} -- NOT another workspace's, which would load a different project's bundle onto this device.`;
375
- let step = 0;
376
- const push = (text) => lines.push(` ${++step}. ${text}`);
377
- lines.push(localNetwork ? `THE PHONE'S LOCAL NETWORK PERMISSION IS NOT GRANTED: the LAN connections this launch made failed with NSURLErrorDomain -1009 and the path reason "unsatisfied (Local network prohibited)", which is what iOS returns while the "would like to find and connect to devices on your local network" prompt is unanswered OR was answered Don't Allow earlier -- the log reads the same either way. Nothing the app sends reaches ${lanOrigin || origin} until it is granted. Do this, in order:` : "The app is launched; what is unproven is that it is talking to THIS dev server. Do this, in order:");
378
- if (remote) {
379
- push(`Check that ${origin} is reachable FROM THE DEVICE's network, not just from this machine. That is the usual cause: a tunnel that stopped, or one this machine can reach and the device cannot.`);
380
- push("If an \"Open in <app>?\" alert or the expo-dev-launcher picker is showing on the remote device, confirm it with your device tool (`agent-device snapshot -i`, then `agent-device press`).");
381
- lines.push(`Then check \`stim logs --source metro\`${mode ? ` (${mode})` : ""} for a bundle request.`);
382
- return lines;
383
- }
384
- if (platform === "ios" && physical) {
385
- const target = lanOrigin || origin;
386
- const relaunch = `xcrun devicectl device process launch --device ${udid} --terminate-existing ` + (url ? `--payload-url '${url}' ` : "") + bundleId + (url ? ` -- ${DEV_MENU_LAUNCH_ARGS.join(" ")}` : "");
387
- if (localNetwork) {
388
- push(`See the prompt: agent-device alert get --platform ios --udid ${udid}. It reads the alert without opening anything, so it works while the app sits behind it.`);
389
- push(`Tap Allow: agent-device alert accept --platform ios --udid ${udid}. A second \`alert get\` then finds none.`);
390
- push("If the FIRST `alert get` already finds no alert, this permission was denied on an earlier run -- a Don't Allow persists across upgrade installs. Turn the app on by hand under Settings > Privacy & Security > Local Network; there is no API for that switch.");
391
- if (devClient) {
392
- push(`The app does NOT retry after the grant -- it stays on "Failed to load app ... The Internet connection appears to be offline." with a Reload button. Press it: agent-device snapshot -i --platform ios --udid ${udid}, then agent-device press 'label="Reload"' --platform ios --udid ${udid}. This launch carried -EXDevMenuShowsAtLaunch 0, so the Expo dev menu is not over the app; if the app was started another way and the menu is on screen, agent-device press 'label="Close"' --platform ios --udid ${udid} dismisses it.`);
393
- push(`Without agent-device, relaunching also recovers: ${relaunch}. It costs the device log -- it replaces the process the collector follows, so \`stim logs --source device\` stops for the rest of this run. Pressing Reload keeps the collector alive.`);
394
- push("By hand: tap Allow on the phone, then tap Reload on the app.");
395
- } else {
396
- push(`The app does NOT retry after the grant. A bare app is expected to show React Native's "Could not connect to development server" RedBox -- NOT VERIFIED ON HARDWARE, so read the screen rather than trusting that: agent-device snapshot -i --platform ios --udid ${udid}, then press its Reload button by the ref or label that snapshot reports.`);
397
- push(`Cleanest for a bare app: relaunch, which re-reads ip.txt: ${relaunch}. It costs the device log -- it replaces the process the collector follows, so \`stim logs --source device\` stops for the rest of this run.`);
398
- push("By hand: tap Allow on the phone, then tap Reload on the RedBox.");
399
- }
400
- lines.push("`agent-device metro reload` does NOT recover either screen: it only reaches an app already connected to Metro's websocket, and this app never connected.");
401
- lines.push(`Then check \`stim logs --source metro\`${mode ? ` (${mode})` : ""} for a bundle request.`);
402
- return lines;
403
- }
404
- push(`Tap Allow on the phone's "would like to find and connect to devices on your local network" prompt if it is showing, or turn the app on under Settings > Privacy & Security > Local Network. iOS gates every LAN connection behind that permission, it cannot be PRE-granted from this machine -- but once the prompt is up a device tool can accept it (agent-device alert get, then agent-device alert accept, both --platform ios --udid ${udid}) -- and until it is granted nothing the app sends reaches ${target}.`);
405
- push("Check the phone is on the same network as this Mac -- the same Wi-Fi SSID, not cellular, not a VPN -- and that the network does not isolate clients from each other.");
406
- push("Check macOS is not blocking inbound connections: System Settings > Network > Firewall, or `/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate`. The gate on this machine passes either way, because macOS routes a host connection to its own address over loopback.");
407
- push(`If this Mac has several network interfaces, ${target} may not be the one the phone shares: set ios.lanHost in .stim.json to the address it can reach.`);
408
- if (devClient) {
409
- push(picker);
410
- if (url && udid) push(`Retry the deep link: xcrun devicectl device process launch --device ${udid} --terminate-existing --payload-url '${url}' ${bundleId} -- ${DEV_MENU_LAUNCH_ARGS.join(" ")}`);
411
- } else lines.push("AND READ THIS: a Debug device build with no dev client carries the JS bundle baked in when the artifact was built, so an unreachable Metro is silent. The app on screen is not broken -- it is running THAT bundle, which on a cache hit is another workspace's JS, not this workspace's.");
412
- lines.push(`Then check \`stim logs --source metro\`${mode ? ` (${mode})` : ""} for a bundle request.`);
413
- return lines;
414
- }
415
- if (platform === "ios") {
416
- if (devClient) push(picker);
417
- if (url && udid) push(`Retry the deep link: xcrun simctl openurl ${udid} '${url}'`);
418
- else if (udid && bundleId) push(`Re-launch: xcrun simctl launch --terminate-running-process ${udid} ${bundleId}`);
419
- } else {
420
- if (url && serial) push(`Re-send the dev-client deep link -- this is the command that points the app at THIS workspace's Metro: adb -s ${serial} shell am start -a android.intent.action.VIEW -d ${deviceShellArg(deviceShellArg(url))} --ez ${ANDROID_DISABLE_AUTO_LAUNCH_EXTRA} true`);
421
- if (devClient) push(picker);
422
- if (serial && bundleId) push(`If the app is stuck, restart its process: ${component ? `adb -s ${serial} shell am force-stop ${bundleId} && adb -s ${serial} shell am start -n ${component}` : url ? `adb -s ${serial} shell am force-stop ${bundleId} && adb -s ${serial} shell am start -a android.intent.action.VIEW -d ${deviceShellArg(deviceShellArg(url))} --ez ${ANDROID_DISABLE_AUTO_LAUNCH_EXTRA} true` : `adb -s ${serial} shell am force-stop ${bundleId} && adb -s ${serial} shell monkey -p ${bundleId} 1`}`);
423
- }
424
- lines.push(`Then check \`stim logs --source metro\`${mode ? ` (${mode})` : ""} for a bundle request.`);
425
- return lines;
426
- }
427
- //#endregion
428
- export { VERIFY_TIMEOUT_MS as a, readMetroRecords as c, verifyAndroidReleaseLaunch as d, verifyLaunch as f, RELEASE_VERIFY_WAIT_MS as i, unattributedLaunchLines as l, APP_READINESS_TIMEOUT_MS as m, LAUNCH_FATAL as n, isBundleProof as o, verifyReleaseLaunch as p, LAUNCH_UNVERIFIED as r, readCollectorRecords as s, LAUNCH_BUNDLING as t, unverifiedLaunchLines as u };