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,290 +0,0 @@
1
- import { B as deviceSlotKey, U as parseDeviceSlotOption, W as projectDeviceSlots, p as getProject } from "./config-BYDxlMY3.mjs";
2
- import { n as fileLeaseIo, o as parseLeaseDuration, p as takeLease, u as releaseWorkspaceLeases } from "./device-lease-BX1sJQ2E.mjs";
3
- import { r as clockTime } from "./command-output-BTy8hZ0F.mjs";
4
- import { r as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-_phNIJfs.mjs";
5
- import { E as getAvdNameForSerial, G as probeEmulatorSerial, N as memoizeEmulatorProbe, O as listAdbDevices, U as physicalDeviceModel, Y as resolvePhysicalDevice, c as androidPoolNoCandidatesRefusal, s as androidPoolCandidates } from "./android-Mz_Inn3w.mjs";
6
- import { l as parseDeviceWait, p as waitForDevice } from "./device-lease-run-Cw2M4z51.mjs";
7
- import { t as selectFromPool } from "./device-pool-Bf-pOhSw.mjs";
8
- import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, l as listIosDevices, o as iosPoolNoCandidatesRefusal } from "./ios-device-D7pi2Sca.mjs";
9
- import chalk from "chalk";
10
- //#region src/commands/device.ts
11
- const DEFAULT_FOR = "5m";
12
- const DEFAULT_DEPS = {
13
- findProjectRoot,
14
- getProject,
15
- avdNameOf: getAvdNameForSerial,
16
- listIosDevices,
17
- listAdbDevices,
18
- physicalDeviceModel,
19
- probeEmulatorSerial,
20
- takeLease,
21
- releaseLeases: releaseWorkspaceLeases,
22
- waitForDevice,
23
- selectFromPool,
24
- io: fileLeaseIo,
25
- now: () => Date.now(),
26
- sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
27
- out: (line) => console.log(line),
28
- note: (line) => console.error(line)
29
- };
30
- function grantLine(facts, durationText) {
31
- return `locked ${facts.deviceName ? `${facts.deviceName} (${facts.id})` : facts.id} for ${facts.holder} until ${clockTime(facts.expiresAt)} (${durationText}). Renew: stim device lock ${facts.platform}${facts.slot ? ` --slot ${facts.slot}` : ""} --for ${durationText}. Release: stim device unlock${facts.slot ? ` --slot ${facts.slot}` : ""}.`;
32
- }
33
- function releasedLine(lease) {
34
- return `unlocked ${lease.deviceName ? `${lease.deviceName} (${lease.id})` : lease.id} -- the ${lease.platform} lease ran until ${clockTime(lease.expiresAt)}.`;
35
- }
36
- function readPlatform(value) {
37
- return value === "ios" || value === "android" ? value : null;
38
- }
39
- function resolveDevice(platform, requested, d) {
40
- if (platform === "ios") {
41
- const resolved = resolveIosPhysicalDevice(requested, d.listIosDevices());
42
- if (!resolved.udid) return {
43
- code: "STIM_NO_DEVICE",
44
- message: resolved.error,
45
- remedy: resolved.remedy ?? null
46
- };
47
- return {
48
- id: resolved.udid,
49
- deviceName: resolved.name ?? resolved.udid
50
- };
51
- }
52
- const resolved = resolvePhysicalDevice(requested, d.listAdbDevices(), d.probeEmulatorSerial);
53
- if (!resolved.serial) return {
54
- code: "STIM_NO_DEVICE",
55
- message: resolved.error,
56
- remedy: resolved.remedy ?? null
57
- };
58
- return {
59
- id: resolved.serial,
60
- deviceName: d.physicalDeviceModel(resolved.serial) ?? resolved.serial
61
- };
62
- }
63
- function findOwnedVirtualDevice(project, platform, id, avdNameOf) {
64
- let running;
65
- for (const { slot, platforms } of projectDeviceSlots(project)) {
66
- if (platform === "ios") {
67
- const sim = platforms.ios;
68
- if (sim?.owned && sim.deviceUdid && sim.deviceUdid.toLowerCase() === id.toLowerCase()) return {
69
- id: sim.deviceUdid,
70
- deviceName: sim.deviceName ?? null,
71
- slot
72
- };
73
- continue;
74
- }
75
- const emulator = platforms.android;
76
- if (!emulator?.owned || !emulator.avdName || !/^emulator-\d+$/.test(id)) continue;
77
- running ??= { name: avdNameOf(id) };
78
- if (running.name === emulator.avdName) return {
79
- id,
80
- deviceName: emulator.deviceName ?? emulator.avdName,
81
- slot
82
- };
83
- }
84
- return null;
85
- }
86
- function isFailure(value) {
87
- return "code" in value;
88
- }
89
- async function poolDevice(platform, idLabel, waitSeconds, deadline, root, d, slot) {
90
- const isEmulator = memoizeEmulatorProbe(d.probeEmulatorSerial);
91
- const pooled = await d.selectFromPool({
92
- ...slot ? { slot } : {},
93
- root,
94
- platform,
95
- idLabel,
96
- list: () => platform === "ios" ? iosPoolCandidates(d.listIosDevices()).map((entry) => ({
97
- id: entry.udid,
98
- name: entry.name,
99
- fallback: isWirelessIosDevice(entry)
100
- })) : androidPoolCandidates(d.listAdbDevices(), isEmulator).map((entry) => ({ id: entry.serial })),
101
- noCandidates: () => {
102
- const resolved = platform === "ios" ? iosPoolNoCandidatesRefusal(d.listIosDevices()) : androidPoolNoCandidatesRefusal(d.listAdbDevices(), isEmulator);
103
- return {
104
- message: resolved.error,
105
- remedy: resolved.remedy
106
- };
107
- },
108
- waitSeconds,
109
- deadline,
110
- now: d.now,
111
- sleep: d.sleep,
112
- warn: (line) => d.note(chalk.yellow(line)),
113
- io: d.io
114
- });
115
- if (pooled.status === "refused") return {
116
- code: pooled.refusal.code,
117
- message: pooled.refusal.message,
118
- remedy: pooled.refusal.remedy,
119
- ...pooled.refusal.lease === null ? {} : { lease: pooled.refusal.lease }
120
- };
121
- const name = pooled.candidate.name ?? (platform === "ios" ? pooled.candidate.id : d.physicalDeviceModel(pooled.candidate.id));
122
- return {
123
- id: pooled.candidate.id,
124
- deviceName: name ?? pooled.candidate.id
125
- };
126
- }
127
- async function runLock(platformArg, idArg, opts = {}, overrides = {}) {
128
- const d = {
129
- ...DEFAULT_DEPS,
130
- ...overrides
131
- };
132
- const json = Boolean(opts.json);
133
- const report = (failure) => {
134
- d.note(chalk.red(`${failure.code}: ${failure.message}`));
135
- if (failure.remedy) d.note(chalk.dim(failure.remedy));
136
- if (json) d.out(JSON.stringify({
137
- code: failure.code,
138
- message: failure.message,
139
- remedy: failure.remedy,
140
- ...failure.lease === void 0 ? {} : { lease: failure.lease }
141
- }));
142
- return failure;
143
- };
144
- const platform = readPlatform(platformArg);
145
- if (!platform) return report({
146
- code: "STIM_BAD_ARG",
147
- message: `\`stim device lock\` takes ios or android, not ${JSON.stringify(platformArg)}.`,
148
- remedy: "Run `stim device lock ios` or `stim device lock android`."
149
- });
150
- const root = d.findProjectRoot(process.cwd());
151
- if (!root) return report(NO_PROJECT_REFUSAL);
152
- const durationText = String(opts.for ?? DEFAULT_FOR).trim();
153
- const duration = parseLeaseDuration(durationText);
154
- if ("error" in duration) return report({
155
- code: "STIM_BAD_ARG",
156
- message: duration.error,
157
- remedy: "Pass a whole number of seconds or minutes from 10s to 30m, e.g. --for 90s or --for 10m."
158
- });
159
- const wait = parseDeviceWait(opts.wait);
160
- if ("error" in wait) return report({
161
- code: "STIM_BAD_ARG",
162
- message: wait.error,
163
- remedy: "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a leased device at once."
164
- });
165
- const idLabel = platform === "ios" ? "udid" : "serial";
166
- const deadline = d.now() + wait.seconds * 1e3;
167
- const lastLine = { at: null };
168
- const owned = idArg ? findOwnedVirtualDevice(d.getProject(root), platform, idArg, d.avdNameOf) : null;
169
- if (owned && opts.slot && opts.slot !== owned.slot) return report({
170
- code: "STIM_BAD_ARG",
171
- message: `${owned.id} is this workspace's ${platform} device in slot ${owned.slot}, not ${opts.slot}.`,
172
- remedy: `Run \`stim device lock ${platform} ${owned.id}\` without --slot, or with --slot ${owned.slot}.`
173
- });
174
- const held = owned ? d.io.readHolder(root)[deviceSlotKey(platform, owned.slot)] : void 0;
175
- if (owned && held && held.id !== owned.id) return report({
176
- code: "STIM_DEVICE_BUSY",
177
- message: `This workspace already leases ${held.id} for ${platform} in slot ${owned.slot}, and a workspace holds one lease per platform and slot.`,
178
- remedy: `Release it with \`stim device unlock ${platform}${owned.slot === "default" ? "" : ` --slot ${owned.slot}`}\` once nothing depends on it, then lock ${owned.id}.`
179
- });
180
- const slot = owned ? owned.slot === "default" ? void 0 : owned.slot : opts.slot;
181
- const device = owned ? owned : idArg ? resolveDevice(platform, idArg, d) : await poolDevice(platform, idLabel, wait.seconds, deadline, root, d, opts.slot);
182
- if (isFailure(device)) return report(device);
183
- for (;;) {
184
- const outcome = await d.waitForDevice({
185
- ...slot ? { slot } : {},
186
- root,
187
- platform,
188
- id: device.id,
189
- idLabel,
190
- waitSeconds: wait.seconds,
191
- now: d.now,
192
- sleep: d.sleep,
193
- warn: (line) => d.note(chalk.yellow(line)),
194
- io: d.io,
195
- deadline,
196
- lastLine
197
- });
198
- if (outcome.status === "refused") return report({
199
- ...outcome.refusal,
200
- lease: outcome.refusal.lease
201
- });
202
- const taken = d.takeLease({
203
- ...slot ? { slot } : {},
204
- root,
205
- platform,
206
- id: device.id,
207
- deviceName: device.deviceName,
208
- kind: "declared",
209
- durationMs: duration.ms
210
- }, d.io);
211
- if (taken.status === "unreadable") return report({
212
- code: "STIM_DEVICE_BUSY",
213
- message: `The lease file at ${taken.path} does not parse, so Stim cannot tell who holds that device.`,
214
- remedy: `Read ${taken.path} and, once you know no run depends on it, delete it. \`stim gc\` reports it on every run.`,
215
- lease: {
216
- platform: null,
217
- id: null,
218
- deviceName: null,
219
- holder: null,
220
- expiresAt: null
221
- }
222
- });
223
- if (taken.status === "held") continue;
224
- const facts = {
225
- ...taken.lease.slot ? { slot: taken.lease.slot } : {},
226
- platform,
227
- id: taken.lease.id,
228
- deviceName: taken.lease.deviceName,
229
- holder: taken.lease.holder,
230
- kind: "declared",
231
- grantedAt: taken.lease.grantedAt,
232
- expiresAt: taken.lease.expiresAt,
233
- leaseSeconds: Math.round(duration.ms / 1e3)
234
- };
235
- if (json) d.out(JSON.stringify(facts));
236
- else d.out(chalk.green(grantLine(facts, durationText)));
237
- return facts;
238
- }
239
- }
240
- async function runUnlock(platformArg, opts = {}, overrides = {}) {
241
- const d = {
242
- ...DEFAULT_DEPS,
243
- ...overrides
244
- };
245
- const json = Boolean(opts.json);
246
- const report = (failure) => {
247
- d.note(chalk.red(`${failure.code}: ${failure.message}`));
248
- if (failure.remedy) d.note(chalk.dim(failure.remedy));
249
- if (json) d.out(JSON.stringify({
250
- code: failure.code,
251
- message: failure.message,
252
- remedy: failure.remedy
253
- }));
254
- return failure;
255
- };
256
- const platform = platformArg === void 0 ? null : readPlatform(platformArg);
257
- if (platformArg !== void 0 && !platform) return report({
258
- code: "STIM_BAD_ARG",
259
- message: `\`stim device unlock\` takes ios or android, not ${JSON.stringify(platformArg)}.`,
260
- remedy: "Run `stim device unlock` for every lease this workspace holds, or name one platform."
261
- });
262
- const root = d.findProjectRoot(process.cwd());
263
- if (!root) return report(NO_PROJECT_REFUSAL);
264
- const released = d.releaseLeases(root, {
265
- platform,
266
- ...opts.slot ? { slot: opts.slot } : {}
267
- }, d.io);
268
- if (released.length === 0) d.note(chalk.dim(`No ${platform ? `${platform} ` : ""}device lease to release for ${root}. \`stim status\` lists every lease on this machine.`));
269
- if (json) d.out(JSON.stringify(released.map((lease) => ({
270
- ...lease,
271
- holder: root
272
- }))));
273
- else for (const lease of released) d.out(chalk.green(releasedLine(lease)));
274
- return released;
275
- }
276
- function registerDevice(program, deps = {}) {
277
- const device = program.command("device").description("Lease a connected physical device to this workspace, and give it back");
278
- device.command("lock").argument("<platform>", "ios or android").argument("[id]", "the UDID or serial to lease, a connected device or this workspace's own simulator or emulator; without one, the first free connected device is used").description("Lease a connected physical device, or this workspace's own simulator or emulator, to this workspace for a declared time, so another workspace's `--device` run waits and agents see the device as driven. Nothing but this command and a `--device` run moves the expiry.").option("--for <duration>", `How long to hold it: a whole number of seconds or minutes from 10s to 30m (default ${DEFAULT_FOR})`).option("--wait <seconds>", "How long to wait for a device another workspace holds, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once)").option("--slot <name>", "Use this workspace device slot", parseDeviceSlotOption).option("--json", "print the lease as JSON on stdout").action(async (platform, id, opts) => {
279
- if ("code" in await runLock(platform, id, opts, deps)) process.exit(1);
280
- });
281
- device.command("unlock").argument("[platform]", "ios or android; without one, every lease this workspace holds is released").description("Release the device lease or leases this workspace holds. Releasing nothing is not an error.").option("--slot <name>", "Use this workspace device slot", parseDeviceSlotOption).option("--json", "print the released leases as JSON on stdout").action(async (platform, opts) => {
282
- const result = await runUnlock(platform, opts, deps);
283
- if (!Array.isArray(result)) process.exit(1);
284
- });
285
- }
286
- function deviceCommand(program) {
287
- registerDevice(program);
288
- }
289
- //#endregion
290
- export { deviceCommand as default, grantLine, registerDevice, releasedLine, runLock, runUnlock };