stim 1.27.0 → 1.29.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 (154) hide show
  1. package/dist/{acquire-artifact-BKN2Yuhg.mjs → acquire-artifact-C2DKfenN.mjs} +1 -1
  2. package/dist/{act-ROviTF_t.mjs → act-CrTcskiE.mjs} +502 -34
  3. package/dist/{activity-Cd-ysFes.mjs → activity-BR5oHSO5.mjs} +6 -5
  4. package/dist/{agent-device-usage-output-C5nCKWp9.mjs → agent-device-usage-output-W0x4SoC7.mjs} +4 -4
  5. package/dist/{android-DriNoAVy.mjs → android-BHKgeOuq.mjs} +5 -5
  6. package/dist/{android--HBgpvpW.mjs → android-BPmCmyAy.mjs} +5 -5
  7. package/dist/{android-Deb9X3_Y.mjs → android-CLU_MMnb.mjs} +1 -1
  8. package/dist/{android-cas-D5e6ecUg.mjs → android-cas-BH6K12__.mjs} +4 -4
  9. package/dist/{android-Cd6w7_qw.mjs → android-l616dRP1.mjs} +42 -39
  10. package/dist/{android-project-DUGMbq28.d.mts → android-project-CCEQyYJK.d.mts} +6 -2
  11. package/dist/api.d.mts +8 -5
  12. package/dist/api.mjs +27 -27
  13. package/dist/{apk-signed-tail-BHQHx3Rm.mjs → apk-signed-tail-B-wKoF_8.mjs} +2 -2
  14. package/dist/{artifact-0AGJYB9O.mjs → artifact-DHuFYfhD.mjs} +12 -12
  15. package/dist/{artifact-faemIZv5.mjs → artifact-Dm9ScLrh.mjs} +12 -12
  16. package/dist/{auto-placement-z-H5pJza.mjs → auto-placement-C8sJsyMN.mjs} +8 -8
  17. package/dist/{browser-web-slD8AvLp.mjs → browser-web-_tQTbQUs.mjs} +12 -12
  18. package/dist/{build-hS0QyFlQ.mjs → build-DtCU9Kim.mjs} +23 -23
  19. package/dist/{build-cache-gBJ-WKzA.mjs → build-cache-BGwTsIEa.mjs} +4 -4
  20. package/dist/{build-plan-CBqYbzYM.mjs → build-plan-CWyjMPKo.mjs} +6 -6
  21. package/dist/{cache-manifest-DEjqGGat.mjs → cache-manifest-evF_zJ9U.mjs} +1 -1
  22. package/dist/cache-manifest.mjs +1 -1
  23. package/dist/{ccache-BWTze1Ls.mjs → ccache-DsDkdP72.mjs} +19 -18
  24. package/dist/{cli-ftXDLto1.mjs → cli-3fjOg-Oc.mjs} +19 -19
  25. package/dist/cli.mjs +1 -1
  26. package/dist/{client-xsdxrhWA.mjs → client-BTUH8TF1.mjs} +41 -8
  27. package/dist/collector-run.mjs +5 -5
  28. package/dist/{command-output-Dj-WT4BP.mjs → command-output-DjCsmzLZ.mjs} +1 -1
  29. package/dist/{config-Cn94Jc0g.mjs → config-AbUjIBOQ.mjs} +121 -19
  30. package/dist/{dependencies-BGokZ-Ng.mjs → dependencies-CHNqX6Pr.mjs} +38 -38
  31. package/dist/{dependency-state-C3OtgG94.mjs → dependency-state-CPKAKCZ8.mjs} +1 -1
  32. package/dist/{dev-client-BMca82xo.mjs → dev-client-CROrxj1x.mjs} +2 -2
  33. package/dist/{device-tM41-TUq.mjs → device-Bmm5qjM-.mjs} +14 -14
  34. package/dist/device-BvpasThQ.mjs +297 -0
  35. package/dist/{device-capacity-6LP7QsaA.mjs → device-capacity-B2ChA-bz.mjs} +86 -18
  36. package/dist/device-host-worker.mjs +15 -13
  37. package/dist/{device-ios-534c14fz.mjs → device-ios-CYzivd31.mjs} +9 -9
  38. package/dist/{device-lease-run-DwsGfjUN.mjs → device-lease-run-qRq_2W2V.mjs} +4 -4
  39. package/dist/{device-pool-BnQqvs6o.mjs → device-pool-CrmiE4_x.mjs} +3 -3
  40. package/dist/{device-BJm0irrq.mjs → device-provision-CK2XiEp1.mjs} +11 -302
  41. package/dist/{doctor-Dbx1ZpD2.mjs → doctor-BO_kaFWX.mjs} +1 -1
  42. package/dist/{doctor-DyqE9n1J.mjs → doctor-Cp4-HN1f.mjs} +20 -15
  43. package/dist/{doctor-F-3VUUyN.mjs → doctor-Dr3C1iXV.mjs} +19 -19
  44. package/dist/doctor-fingerprint.mjs +1 -1
  45. package/dist/{doctor-watchman-CxDbyrrt.mjs → doctor-watchman-CJr2aXXv.mjs} +4 -4
  46. package/dist/{eas-build-CjNSWmjo.mjs → eas-build-D-9HmGZS.mjs} +2 -2
  47. package/dist/{eas-fallback-9fqb46kW.mjs → eas-fallback-Cemt2GVL.mjs} +4 -4
  48. package/dist/{eas-session-ledger-DrP4OuuM.mjs → eas-session-ledger-B0KLZx5m.mjs} +36 -7
  49. package/dist/{error-diagnostics-snej9k4j.mjs → error-diagnostics-CV_1RoEH.mjs} +8 -8
  50. package/dist/{gc-CGZ1Yg88.mjs → gc-CKHqL4aS.mjs} +81 -18
  51. package/dist/{gc-BRwAY3qT.mjs → gc-DjXwQXHK.mjs} +2 -2
  52. package/dist/{guide-_rfEh_zM.mjs → guide-CeRlWVsS.mjs} +230 -62
  53. package/dist/{hosted-android-BMKzUNnY.mjs → hosted-android-DI_vvv7U.mjs} +5 -6
  54. package/dist/{hosted-client-D7Pk_Oo1.mjs → hosted-client-CgoxdU9j.mjs} +44 -17
  55. package/dist/{hosted-logs-B1gqQuva.mjs → hosted-logs-C-4INmkn.mjs} +17 -8
  56. package/dist/{hosted-logs-sync-Dg3qrZmV.mjs → hosted-logs-sync-Bf5s02fi.mjs} +5 -5
  57. package/dist/{hosted-macos-B9w4H8hc.mjs → hosted-macos-Doh85YUM.mjs} +5 -5
  58. package/dist/{hosted-native-CdgaiuyP.mjs → hosted-native-DvZENAL-.mjs} +11 -8
  59. package/dist/{idle-shutdown-Cbvo5KEh.mjs → idle-shutdown-BM37gMfU.mjs} +7 -7
  60. package/dist/{ios-Bk4mWbtS.mjs → ios-CNDH6fNF.mjs} +8 -8
  61. package/dist/{ios-E26qSpkb.mjs → ios-CoMCWfub.mjs} +4 -4
  62. package/dist/{ios-B5HlVMhQ.mjs → ios-UM_dManb.mjs} +31 -29
  63. package/dist/{ios-device-C_QkIf1Z.mjs → ios-device-L1-pota_.mjs} +1 -1
  64. package/dist/{ios-project-D8Jcy_br.mjs → ios-project-DJYptOCh.mjs} +7 -7
  65. package/dist/{ios-state-BZ03NFgF.mjs → ios-state-Ce_dystM.mjs} +1 -1
  66. package/dist/{js-swap-Dg2a945i.mjs → js-swap-BthE4kZC.mjs} +4 -4
  67. package/dist/{launch-CRyBeNsA.mjs → launch-D798aSm8.mjs} +19 -19
  68. package/dist/{lightened-BCsdAGj_.mjs → lightened-vSxkstg6.mjs} +4 -4
  69. package/dist/{logs-aJQb-RDg.mjs → logs-BND8MiBq.mjs} +9 -8
  70. package/dist/{logs-CC_-ZzEE.mjs → logs-CilPftm3.mjs} +5 -5
  71. package/dist/{macos-BGmTpnv9.mjs → macos-BOQrKYeJ.mjs} +1 -1
  72. package/dist/{macos-DlCBhMw5.mjs → macos-CxUi9xcE.mjs} +20 -20
  73. package/dist/macos-run.mjs +1 -1
  74. package/dist/maintenance-run.mjs +13 -9
  75. package/dist/{metro-CvyD-xwe.mjs → metro-BMQHczcf.mjs} +2 -2
  76. package/dist/{metro-gateway-BnHdqMO_.mjs → metro-request-BtF7ox53.mjs} +25 -46
  77. package/dist/{named-ports-BCyMWA6b.mjs → named-ports-DcktE2Pw.mjs} +2 -2
  78. package/dist/{native-android-DlpxCyOP.mjs → native-android-BkhrCjdX.mjs} +16 -16
  79. package/dist/{native-gradle-artifact-inputs-C13qT7R_.mjs → native-gradle-artifact-inputs-Cw4P6Gyr.mjs} +3 -3
  80. package/dist/{native-runtime-DqaIBO5w.mjs → native-runtime-DyH2gkXK.mjs} +6 -6
  81. package/dist/{native-xcode-inputs-B1W8SrxB.mjs → native-xcode-inputs-DV8jr3kJ.mjs} +2 -2
  82. package/dist/{native-xcode-ios-QPP0Rm68.mjs → native-xcode-ios-DdpPG2iT.mjs} +15 -15
  83. package/dist/{ndjson-Dy2W4vRa.mjs → ndjson-CrjIsGzw.mjs} +2 -2
  84. package/dist/offload-worker.d.mts +1 -1
  85. package/dist/offload-worker.mjs +22 -22
  86. package/dist/{ownership-Bx-0cku-.mjs → ownership-Dtz9G5Gl.mjs} +2 -2
  87. package/dist/{phone-reverses-C9yAaKEv.mjs → phone-reverses-DZRad8HT.mjs} +4 -4
  88. package/dist/{placement-log-BXUbiZM6.mjs → placement-log-CoN6xrjY.mjs} +1 -1
  89. package/dist/{plan-placement-UxnQjv5Z.mjs → plan-placement-7sHuqR-r.mjs} +6 -6
  90. package/dist/{ports-uUrghqWN.mjs → ports-VQSAPZhl.mjs} +3 -3
  91. package/dist/{prebuild-BDpToDgR.mjs → prebuild-Bqp0LFGN.mjs} +9 -9
  92. package/dist/{project-DYj-HVx6.mjs → project-D1n0K4yg.mjs} +15 -15
  93. package/dist/{react-native-android-DDBccgJw.mjs → react-native-android-FQ-yX3Mv.mjs} +22 -22
  94. package/dist/{react-native-build-DaK2IFyP.mjs → react-native-build-D58bIqV9.mjs} +7 -7
  95. package/dist/{react-native-doctor-B-Mw6DcR.mjs → react-native-doctor-AkUH2aca.mjs} +5 -5
  96. package/dist/{react-native-ios-DjYwUF9U.mjs → react-native-ios-Dmsv8j7T.mjs} +14 -14
  97. package/dist/{recordings-C20iUZfp.mjs → recordings-CHMaF73C.mjs} +1 -1
  98. package/dist/{reload-fUdkH2_p.mjs → reload-BV0nD-k9.mjs} +14 -14
  99. package/dist/{reload-DJBeF_rC.mjs → reload-CDKEzzaf.mjs} +1 -1
  100. package/dist/{remote-y6n99WMW.mjs → remote-C8xyslUa.mjs} +9 -9
  101. package/dist/{result-CTqBw2Te.mjs → result-9fqcJ90W.mjs} +16 -16
  102. package/dist/{run-DaCeNKRm.mjs → run-BQAmrohh.mjs} +2 -2
  103. package/dist/{selection-Bs8phwhN.mjs → selection-D1ZDzHFX.mjs} +105 -62
  104. package/dist/{server-bare-BOh-iZEj.mjs → server-bare-CEQdB_F4.mjs} +37 -1
  105. package/dist/{server-command-8CuA51Cv.mjs → server-command-RlS-Kl4a.mjs} +5 -5
  106. package/dist/server-expo-BVV9qy31.mjs +2 -0
  107. package/dist/{server-expo-ABQs2XFA.mjs → server-expo-bB1VV2k-.mjs} +8 -5
  108. package/dist/{settings-CMHhQNwI.mjs → settings-BcVCcAT5.mjs} +2 -2
  109. package/dist/{settings-BDVI8Ivc.mjs → settings-D776ygML.mjs} +47 -3
  110. package/dist/{settings-Djl-mpjX.mjs → settings-D9LtQaUw.mjs} +2 -1
  111. package/dist/{settings-payload-cm60Zhib.mjs → settings-payload-_aatELz2.mjs} +4 -4
  112. package/dist/{settings-write-BdNRLlBn.mjs → settings-write-CkTVGQ4O.mjs} +5 -5
  113. package/dist/settings.schema.json +58 -9
  114. package/dist/{simslim-DCQwzoPy.mjs → simslim-CbpHERcv.mjs} +1 -1
  115. package/dist/{slot-launch-0l7RqSpr.mjs → slot-launch-Dbgfh8gc.mjs} +6 -6
  116. package/dist/{stage-F4cAfJGi.mjs → stage-BuHuRj1y.mjs} +1 -1
  117. package/dist/{start-DcqnF9p8.mjs → start-Cr-c3Xhq.mjs} +1 -1
  118. package/dist/{start-DrPwER_2.mjs → start-Dlv4XXTP.mjs} +11 -11
  119. package/dist/{state-CZxLyetD.mjs → state-C2AUjjhg.mjs} +1 -1
  120. package/dist/{state-BX1y5syV.mjs → state-D5ZxwCGJ.mjs} +2 -2
  121. package/dist/{stats-GxuCbles.mjs → stats-D5c-uIBp.mjs} +4 -4
  122. package/dist/{status-7ULDEJ1e.mjs → status-CK7ZoEhV.mjs} +2 -2
  123. package/dist/{status-BfnK9pUd.mjs → status-D6PBK6_-.mjs} +49 -26
  124. package/dist/{status-Bj7ZYvvc.mjs → status-DbQv--Yb.mjs} +1 -1
  125. package/dist/{status-watch-BfabQn03.mjs → status-watch-okrpea4i.mjs} +17 -6
  126. package/dist/status-worker.mjs +1 -1
  127. package/dist/{stim-desktop-CbWo21kb.mjs → stim-desktop-CYXLFpFS.mjs} +1 -1
  128. package/dist/{stop-x1Yu3He4.mjs → stop-CHtAiv79.mjs} +2 -2
  129. package/dist/{stop-D-EAr25B.mjs → stop-p9uSKuGE.mjs} +20 -19
  130. package/dist/{stop-CH79S3IZ.mjs → stop-uRQ-zYcl.mjs} +9 -5
  131. package/dist/supervisor-run.d.mts +1 -0
  132. package/dist/supervisor-run.mjs +243 -65
  133. package/dist/{support-Be0UeVZU.mjs → support-BMpQIug0.mjs} +11 -10
  134. package/dist/{support-CNg_YsOk.mjs → support-PFyTkrnr.mjs} +4 -4
  135. package/dist/{swiftpm-artifact-inputs-uPqYvGBv.mjs → swiftpm-artifact-inputs-Cddq6jN2.mjs} +1 -1
  136. package/dist/{swiftpm-macos-Ch4YjY_A.mjs → swiftpm-macos-BSj9iZlI.mjs} +8 -8
  137. package/dist/{toolchain-JYAOquPg.mjs → toolchain-B-mzR9Rh.mjs} +1 -1
  138. package/dist/{toolchain-CbCG6C5Z.mjs → toolchain-CLGnEUgT.mjs} +4 -4
  139. package/dist/{trigger-DMou-X7j.mjs → trigger-CfnOfpDd.mjs} +1 -1
  140. package/dist/trigger-DBZ-GBrl.mjs +2 -0
  141. package/dist/{warm-progress-C0RsbngN.mjs → warm-progress--KkkBBaq.mjs} +3 -3
  142. package/dist/web-BxSo493O.mjs +2 -0
  143. package/dist/web-run.mjs +5 -5
  144. package/dist/{web-Cq_AQ4DK.mjs → web-xlVssjQf.mjs} +8 -8
  145. package/dist/{workspace-state-BjqdjnJR.mjs → workspace-state-DGwkPXwq.mjs} +2 -2
  146. package/dist/{workspaces-DFbj07jp.mjs → workspaces-CvSYD_78.mjs} +106 -26
  147. package/dist/{worktree-COAJ3-OD.mjs → worktree-CaQBf6kh.mjs} +26 -47
  148. package/dist/worktree-DTOIohFe.mjs +2 -0
  149. package/package.json +7 -7
  150. package/shim/bundle-response.cjs +37 -0
  151. package/dist/server-expo-Ba_Y21vB.mjs +0 -2
  152. package/dist/trigger-qp2ji5wE.mjs +0 -2
  153. package/dist/web-Je6abcpz.mjs +0 -2
  154. package/dist/worktree-JGUd_53L.mjs +0 -2
@@ -1,44 +1,44 @@
1
1
  import { o as cancellableSleep, t as getExecutor, x as withDrainingCancellation } from "./exec-aULwtNly.mjs";
2
- import { f as writeWorkspaceStateAsync, k as workspaceLogsDir, r as readWorkspaceState } from "./workspace-state-BjqdjnJR.mjs";
3
- import { B as deviceSlotFileKey, E as upsertProject, O as withConfigLockAsync, V as deviceSlotKey, p as getProject, u as getConcurrencyLimits, v as recordIosSchemeApprovals } from "./config-Cn94Jc0g.mjs";
4
- import { _ as stepTimer, c as launchErrorReport, i as formatDuration, l as phaseLine, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-Dj-WT4BP.mjs";
5
- import { $t as makeTemporaryDirectory, J as resolveCacheProviderConfig, Lt as repoRootAsync, Q as resolveSettings, at as settingsLayers, dt as detectProviders, en as removeTemporaryEntry, nt as settingOriginScope, xt as gitCommonDirAsync } from "./settings-BDVI8Ivc.mjs";
6
- import { L as workspaceDevServerMode, f as projectRegistry, i as findProjectRoot, v as detectIsExpo, z as writeWorkspaceLaunchAsync } from "./project-DYj-HVx6.mjs";
7
- import { o as workspaceLinks } from "./stim-desktop-CbWo21kb.mjs";
8
- import { c as pidExists, d as resolveProjectMetro, f as signalProcessTree } from "./metro-CvyD-xwe.mjs";
9
- import { i as createNdjsonWriter } from "./ndjson-Dy2W4vRa.mjs";
10
- import { An as checkEasAuth, At as ensureRemoteBootOwned, Bt as RELEASE_VERIFY_WAIT_MS, Cn as gateMetroOrigin, Dt as bundleEntryPoint, Gt as unattributedLaunchLines, Ht as isBundleProof, It as LAUNCH_BUNDLING, Jt as verifyLaunch, Kt as unverifiedLaunchLines, Ln as resolveEasCliBin, Lt as LAUNCH_FATAL, Nn as loadProjectProvider, Nt as remoteIosDeps, Pt as resolveRemoteContext, Rn as resolveRemote, Rt as LAUNCH_UNVERIFIED, Sn as readRemoteSimulatorArch, Ut as readCollectorRecords, Wt as readMetroRecords, Yt as verifyReleaseLaunch, an as devClientUrl, c as budgetGate, dn as installIosApp, en as IOS_DEV_MENU_OFF_DEFAULTS_PLIST, fn as iosAppProcess, gn as restartedAppNote, hn as launchIosApp, in as clearOtherUserApps, kt as ensureMetroReachable, zn as uploadRemote } from "./ccache-BWTze1Ls.mjs";
11
- import { at as recordRunStats, rt as recordCapacityRefusal, tt as readRunEstimates, xt as releaseBuildSlot, yt as acquireBuildSlot } from "./workspaces-DFbj07jp.mjs";
12
- import { B as readBundleExecutable, H as resolveScheme, O as runPodInstall, T as readPodState, V as readBundleId, w as podsAreStale } from "./toolchain-CbCG6C5Z.mjs";
13
- import { F as waitForBuild, M as acquireBuildLock, P as releaseBuildLock } from "./activity-Cd-ysFes.mjs";
14
- import { A as untrackedNativeFiles, C as resolveBuild, c as evictBuild, m as fingerprintProject, w as storeBuild } from "./build-cache-gBJ-WKzA.mjs";
15
- import { d as listAllIosSims, h as listIosRuntimesAsync, r as clearIosAppData } from "./ios-E26qSpkb.mjs";
16
- import { n as readHostedIos, o as writeHostedIosAsync } from "./ios-state-BZ03NFgF.mjs";
17
- import { n as hostedMetroPortProbe } from "./hosted-native-CdgaiuyP.mjs";
18
- import { i as prepareHostedIos, r as placeHostedIos } from "./phone-reverses-C9yAaKEv.mjs";
19
- import { n as verifyCollectorOwnership } from "./ownership-Bx-0cku-.mjs";
20
- import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-0l7RqSpr.mjs";
21
- import { a as discoverXcodeProject, r as buildIos } from "./react-native-build-DaK2IFyP.mjs";
22
- import { c as startDevServer, g as detectBundleId } from "./start-DrPwER_2.mjs";
2
+ import { f as writeWorkspaceStateAsync, k as workspaceLogsDir, r as readWorkspaceState } from "./workspace-state-DGwkPXwq.mjs";
3
+ import { B as deviceSlotFileKey, E as upsertProject, O as withConfigLockAsync, V as deviceSlotKey, p as getProject, u as getConcurrencyLimits, v as recordIosSchemeApprovals } from "./config-AbUjIBOQ.mjs";
4
+ import { _ as stepTimer, c as launchErrorReport, i as formatDuration, l as phaseLine, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-DjCsmzLZ.mjs";
5
+ import { J as resolveCacheProviderConfig, Q as resolveSettings, St as gitCommonDirAsync, Vt as repoRootAsync, an as makeTemporaryDirectory, at as settingsLayers, dt as detectProviders, nt as settingOriginScope, on as removeTemporaryEntry } from "./settings-D776ygML.mjs";
6
+ import { L as workspaceDevServerMode, f as projectRegistry, i as findProjectRoot, v as detectIsExpo, z as writeWorkspaceLaunchAsync } from "./project-D1n0K4yg.mjs";
7
+ import { o as workspaceLinks } from "./stim-desktop-CYXLFpFS.mjs";
8
+ import { c as pidExists, d as resolveProjectMetro, f as signalProcessTree } from "./metro-BMQHczcf.mjs";
9
+ import { i as createNdjsonWriter } from "./ndjson-CrjIsGzw.mjs";
10
+ import { An as checkEasAuth, At as ensureRemoteBootOwned, Bt as RELEASE_VERIFY_WAIT_MS, Cn as gateMetroOrigin, Dt as bundleEntryPoint, Gt as unattributedLaunchLines, Ht as isBundleProof, It as LAUNCH_BUNDLING, Jt as verifyLaunch, Kt as unverifiedLaunchLines, Ln as resolveEasCliBin, Lt as LAUNCH_FATAL, Nn as loadProjectProvider, Nt as remoteIosDeps, Pt as resolveRemoteContext, Rn as resolveRemote, Rt as LAUNCH_UNVERIFIED, Sn as readRemoteSimulatorArch, Ut as readCollectorRecords, Wt as readMetroRecords, Yt as verifyReleaseLaunch, an as devClientUrl, c as budgetGate, dn as installIosApp, en as IOS_DEV_MENU_OFF_DEFAULTS_PLIST, fn as iosAppProcess, gn as restartedAppNote, hn as launchIosApp, in as clearOtherUserApps, kt as ensureMetroReachable, zn as uploadRemote } from "./ccache-DsDkdP72.mjs";
11
+ import { St as acquireBuildSlot, Tt as releaseBuildSlot, ct as recordRunStats, it as readRunEstimates, ot as recordCapacityRefusal } from "./workspaces-CvSYD_78.mjs";
12
+ import { B as readBundleExecutable, H as resolveScheme, O as runPodInstall, T as readPodState, V as readBundleId, w as podsAreStale } from "./toolchain-CLGnEUgT.mjs";
13
+ import { F as waitForBuild, M as acquireBuildLock, P as releaseBuildLock } from "./activity-BR5oHSO5.mjs";
14
+ import { A as untrackedNativeFiles, C as resolveBuild, c as evictBuild, m as fingerprintProject, w as storeBuild } from "./build-cache-BGwTsIEa.mjs";
15
+ import { d as listAllIosSims, h as listIosRuntimesAsync, r as clearIosAppData } from "./ios-CoMCWfub.mjs";
16
+ import { n as readHostedIos, o as writeHostedIosAsync } from "./ios-state-Ce_dystM.mjs";
17
+ import { n as hostedMetroPortProbe } from "./hosted-native-DvZENAL-.mjs";
18
+ import { i as prepareHostedIos, r as placeHostedIos } from "./phone-reverses-DZRad8HT.mjs";
19
+ import { n as verifyCollectorOwnership } from "./ownership-Dtz9G5Gl.mjs";
20
+ import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-Dbgfh8gc.mjs";
21
+ import { a as discoverXcodeProject, r as buildIos } from "./react-native-build-D58bIqV9.mjs";
22
+ import { c as startDevServer, g as detectBundleId } from "./start-Dlv4XXTP.mjs";
23
23
  import { t as spawnEntry } from "./spawn-entry-jw19m8Nl.mjs";
24
- import { a as acquireRunLease, c as lostRefusal, d as runLease, s as lostLine, t as DEBUG_VERIFY_STEP_MS, u as releaseLeaseOnAbort } from "./device-lease-run-DwsGfjUN.mjs";
25
- import { r as checkDeviceCapacity } from "./device-capacity-6LP7QsaA.mjs";
26
- import { n as clearIosAdoptionPending } from "./device-ios-534c14fz.mjs";
27
- import { i as deviceLabel, o as deviceShortName, t as appNameFromPath } from "./support-Be0UeVZU.mjs";
24
+ import { a as acquireRunLease, c as lostRefusal, d as runLease, s as lostLine, t as DEBUG_VERIFY_STEP_MS, u as releaseLeaseOnAbort } from "./device-lease-run-qRq_2W2V.mjs";
25
+ import { r as checkDeviceCapacity } from "./device-capacity-B2ChA-bz.mjs";
26
+ import { n as clearIosAdoptionPending } from "./device-ios-CYzivd31.mjs";
27
+ import { i as deviceLabel, o as deviceShortName, t as appNameFromPath } from "./support-BMpQIug0.mjs";
28
28
  import { a as sealAppForDevice, r as gateProfileForDevice } from "./ios-signing-BJzvDPfU.mjs";
29
- import { a as resolveEasDevelopmentBuild } from "./eas-build-CjNSWmjo.mjs";
30
- import { a as captureNativeCrashes, c as simulatorConsolePaths, i as bundleBindFailure, n as IOS_CRASH_REPORT_RETRY, s as printNativeCrashReport, t as errorDiagnostics } from "./error-diagnostics-snej9k4j.mjs";
31
- import { t as followHostedLaunchLogs } from "./hosted-logs-sync-Dg3qrZmV.mjs";
32
- import { a as runPrebuild, d as memoizedFingerprint, n as planPrebuildAsync } from "./prebuild-BDpToDgR.mjs";
33
- import { i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely } from "./native-runtime-DqaIBO5w.mjs";
34
- import { n as devClientTakesDevMenuParams, r as hasDevClient, t as devClientScheme } from "./dev-client-BMca82xo.mjs";
35
- import { t as automaticDevicePlacement } from "./auto-placement-z-H5pJza.mjs";
36
- import { t as checkEasFallback } from "./eas-fallback-9fqb46kW.mjs";
37
- import { n as ensureBooted, o as warmMetro, r as ensureOwnedDevice } from "./device-tM41-TUq.mjs";
38
- import { t as selectFromPool } from "./device-pool-BnQqvs6o.mjs";
39
- import { s as reportIosResult } from "./ios-project-D8Jcy_br.mjs";
40
- import { c as isWirelessIosDevice, i as iosDeviceProcess, l as listIosDevices, n as installIosDeviceApp, p as verifyIosDeviceReleaseLaunch, r as iosDeviceBounds, t as awaitIosDeviceLaunch, u as localNetworkPending } from "./ios-device-C_QkIf1Z.mjs";
41
- import { i as swapJsBundle } from "./js-swap-Dg2a945i.mjs";
29
+ import { a as resolveEasDevelopmentBuild } from "./eas-build-D-9HmGZS.mjs";
30
+ import { c as isWirelessIosDevice, i as iosDeviceProcess, l as listIosDevices, n as installIosDeviceApp, p as verifyIosDeviceReleaseLaunch, r as iosDeviceBounds, t as awaitIosDeviceLaunch, u as localNetworkPending } from "./ios-device-L1-pota_.mjs";
31
+ import { a as captureNativeCrashes, c as simulatorConsolePaths, i as bundleBindFailure, n as IOS_CRASH_REPORT_RETRY, s as printNativeCrashReport, t as errorDiagnostics } from "./error-diagnostics-CV_1RoEH.mjs";
32
+ import { t as followHostedLaunchLogs } from "./hosted-logs-sync-Bf5s02fi.mjs";
33
+ import { a as runPrebuild, d as memoizedFingerprint, n as planPrebuildAsync } from "./prebuild-Bqp0LFGN.mjs";
34
+ import { i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely } from "./native-runtime-DyH2gkXK.mjs";
35
+ import { n as devClientTakesDevMenuParams, r as hasDevClient, t as devClientScheme } from "./dev-client-CROrxj1x.mjs";
36
+ import { t as automaticDevicePlacement } from "./auto-placement-C8sJsyMN.mjs";
37
+ import { t as checkEasFallback } from "./eas-fallback-Cemt2GVL.mjs";
38
+ import { n as ensureBooted, o as warmMetro, r as ensureOwnedDevice } from "./device-Bmm5qjM-.mjs";
39
+ import { t as selectFromPool } from "./device-pool-CrmiE4_x.mjs";
40
+ import { s as reportIosResult } from "./ios-project-DJYptOCh.mjs";
41
+ import { i as swapJsBundle } from "./js-swap-BthE4kZC.mjs";
42
42
  import { mkdirSync, openSync, writeFileSync } from "node:fs";
43
43
  import { networkInterfaces } from "node:os";
44
44
  import { basename, join } from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { It as repoRoot } from "./settings-BDVI8Ivc.mjs";
2
+ import { Bt as repoRoot } from "./settings-D776ygML.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import { existsSync } from "node:fs";
5
5
  import { dirname, join, relative } from "node:path";
@@ -1,5 +1,5 @@
1
- import { C as resolvePackageJson, b as isPackageResolvable } from "./project-DYj-HVx6.mjs";
2
- import { bn as readBundleSchemes, yn as pickDevClientScheme } from "./ccache-BWTze1Ls.mjs";
1
+ import { C as resolvePackageJson, b as isPackageResolvable } from "./project-D1n0K4yg.mjs";
2
+ import { bn as readBundleSchemes, yn as pickDevClientScheme } from "./ccache-DsDkdP72.mjs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { isJsonObject, readJsonObject } from "@stim-cli/core/state";
5
5
  //#region src/commands/dev-client.ts
@@ -1,17 +1,17 @@
1
1
  import { D as ownership_claim_exports, t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, j as acquireAvdClaim, t as allConsolePortsAndSerials, w as setDevice } from "./config-Cn94Jc0g.mjs";
3
- import { l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
4
- import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting } from "./settings-BDVI8Ivc.mjs";
5
- import { s as ownedDeviceLabel } from "./project-DYj-HVx6.mjs";
6
- import { B as ownedAvdDeviceProfile, F as listAvdsAsync, H as ownedAvdMatchesConfiguration, I as listInstalledSystemImages, K as ownedAvdSystemImage, O as getAvdNameForSerialAsync, U as ownedAvdName, X as pickDefaultSystemImage, _ as avdPoolConfiguration, b as configureNewOwnedAvd, ct as waitForBoot, gt as isLegacyDeletionClaim, j as listAdbDevicesAsync, n as OWNED_AVD_CONFIG_DEFAULTS, nt as resolveOwnedAvdSerialAsync, p as assertOwnedAvdStoppedAsync, pt as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, vt as parkedMaxSetting, x as createOwnedAvd, y as bootAndroidEmulator, yt as readParked, z as nextConsolePort } from "./android-DriNoAVy.mjs";
7
- import { c as pidExists } from "./metro-CvyD-xwe.mjs";
8
- import { pt as teardownParkedAvd, ut as teardownOwnedAvd } from "./workspaces-DFbj07jp.mjs";
9
- import { h as tailLines } from "./activity-Cd-ysFes.mjs";
10
- import { B as reportMemoryCulprits, L as memoryCulpritsUnderAsync, R as readHostMemoryPressure, V as memoryCulpritAdvice, f as listAllIosSimsAsync } from "./ios-E26qSpkb.mjs";
11
- import { h as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as countLiveOwnedDevicesFrom } from "./device-capacity-6LP7QsaA.mjs";
12
- import { t as clearDeviceIdleShutdown } from "./idle-shutdown-Cbvo5KEh.mjs";
13
- import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-534c14fz.mjs";
14
- import { t as reconcileSimSlim } from "./simslim-DCQwzoPy.mjs";
2
+ import { D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, j as acquireAvdClaim, t as allConsolePortsAndSerials, w as setDevice } from "./config-AbUjIBOQ.mjs";
3
+ import { l as phaseLine } from "./command-output-DjCsmzLZ.mjs";
4
+ import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting } from "./settings-D776ygML.mjs";
5
+ import { s as ownedDeviceLabel } from "./project-D1n0K4yg.mjs";
6
+ import { B as ownedAvdDeviceProfile, F as listAvdsAsync, H as ownedAvdMatchesConfiguration, I as listInstalledSystemImages, K as ownedAvdSystemImage, O as getAvdNameForSerialAsync, U as ownedAvdName, X as pickDefaultSystemImage, _ as avdPoolConfiguration, b as configureNewOwnedAvd, ct as waitForBoot, gt as isLegacyDeletionClaim, j as listAdbDevicesAsync, n as OWNED_AVD_CONFIG_DEFAULTS, nt as resolveOwnedAvdSerialAsync, p as assertOwnedAvdStoppedAsync, pt as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, vt as parkedMaxSetting, x as createOwnedAvd, y as bootAndroidEmulator, yt as readParked, z as nextConsolePort } from "./android-BHKgeOuq.mjs";
7
+ import { c as pidExists } from "./metro-BMQHczcf.mjs";
8
+ import { gt as teardownParkedAvd, pt as teardownOwnedAvd } from "./workspaces-CvSYD_78.mjs";
9
+ import { h as tailLines } from "./activity-BR5oHSO5.mjs";
10
+ import { B as reportMemoryCulprits, L as memoryCulpritsUnderAsync, R as readHostMemoryPressure, V as memoryCulpritAdvice, f as listAllIosSimsAsync } from "./ios-CoMCWfub.mjs";
11
+ import { g as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as countLiveOwnedDevicesFrom } from "./device-capacity-B2ChA-bz.mjs";
12
+ import { t as clearDeviceIdleShutdown } from "./idle-shutdown-BM37gMfU.mjs";
13
+ import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-CYzivd31.mjs";
14
+ import { t as reconcileSimSlim } from "./simslim-CbpHERcv.mjs";
15
15
  import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
16
16
  import { randomUUID } from "node:crypto";
17
17
  import { existsSync } from "node:fs";
@@ -19,10 +19,10 @@ import { isDeepStrictEqual } from "node:util";
19
19
  import { dirname, join, resolve, sep } from "node:path";
20
20
  import { rotatedLogPath } from "@stim-cli/core";
21
21
  import { acceptsShape, settingDefinition } from "@stim-cli/core/state";
22
+ import { request } from "node:http";
22
23
  import { fileURLToPath } from "node:url";
23
24
  import { captureProcessIdentity } from "@stim-cli/core/process-identity";
24
25
  import chalk from "chalk";
25
- import { request } from "node:http";
26
26
  //#region src/engine/metro-warmup.ts
27
27
  const WARMUP_TIMEOUT_MS = 6e4;
28
28
  async function requestLocal(url, platform, prefetch) {
@@ -0,0 +1,297 @@
1
+ import { G as projectDeviceSlots, V as deviceSlotKey, W as parseDeviceSlotOption, p as getProject } from "./config-AbUjIBOQ.mjs";
2
+ import { r as clockTime } from "./command-output-DjCsmzLZ.mjs";
3
+ import { i as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-D1n0K4yg.mjs";
4
+ import { A as listAdbDevices, O as getAvdNameForSerialAsync, R as memoizeEmulatorProbe, Y as physicalDeviceModel, Z as probeEmulatorSerial, c as androidPoolNoCandidatesRefusal, rt as resolvePhysicalDevice, s as androidPoolCandidates } from "./android-BHKgeOuq.mjs";
5
+ import { En as runProcessOperation } from "./ccache-DsDkdP72.mjs";
6
+ import { C as parseLeaseDuration, D as releaseWorkspaceLeases, j as takeLease, y as fileLeaseIo } from "./activity-BR5oHSO5.mjs";
7
+ import { l as parseDeviceWait, p as waitForDevice } from "./device-lease-run-qRq_2W2V.mjs";
8
+ import { n as runProvision } from "./device-provision-CK2XiEp1.mjs";
9
+ import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, l as listIosDevices, o as iosPoolNoCandidatesRefusal } from "./ios-device-L1-pota_.mjs";
10
+ import { t as selectFromPool } from "./device-pool-CrmiE4_x.mjs";
11
+ import chalk from "chalk";
12
+ //#region src/commands/device.ts
13
+ const DEFAULT_FOR = "5m";
14
+ const DEFAULT_DEPS = {
15
+ findProjectRoot,
16
+ getProject,
17
+ avdNameOf: getAvdNameForSerialAsync,
18
+ listIosDevices,
19
+ listAdbDevices,
20
+ physicalDeviceModel,
21
+ probeEmulatorSerial,
22
+ takeLease,
23
+ releaseLeases: releaseWorkspaceLeases,
24
+ waitForDevice,
25
+ selectFromPool,
26
+ io: fileLeaseIo,
27
+ now: () => Date.now(),
28
+ sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
29
+ out: (line) => console.log(line),
30
+ note: (line) => console.error(line)
31
+ };
32
+ function grantLine(facts, durationText) {
33
+ 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}` : ""}.`;
34
+ }
35
+ function releasedLine(lease) {
36
+ return `unlocked ${lease.deviceName ? `${lease.deviceName} (${lease.id})` : lease.id} -- the ${lease.platform} lease ran until ${clockTime(lease.expiresAt)}.`;
37
+ }
38
+ function readPlatform(value) {
39
+ return value === "ios" || value === "android" ? value : null;
40
+ }
41
+ async function resolveDevice(platform, requested, d) {
42
+ if (platform === "ios") {
43
+ const resolved = resolveIosPhysicalDevice(requested, await d.listIosDevices());
44
+ if (!resolved.udid) return {
45
+ code: "STIM_NO_DEVICE",
46
+ message: resolved.error,
47
+ remedy: resolved.remedy ?? null
48
+ };
49
+ return {
50
+ id: resolved.udid,
51
+ deviceName: resolved.name ?? resolved.udid
52
+ };
53
+ }
54
+ const resolved = resolvePhysicalDevice(requested, d.listAdbDevices(), d.probeEmulatorSerial);
55
+ if (!resolved.serial) return {
56
+ code: "STIM_NO_DEVICE",
57
+ message: resolved.error,
58
+ remedy: resolved.remedy ?? null
59
+ };
60
+ return {
61
+ id: resolved.serial,
62
+ deviceName: d.physicalDeviceModel(resolved.serial) ?? resolved.serial
63
+ };
64
+ }
65
+ async function findOwnedVirtualDevice(project, platform, id, avdNameOf) {
66
+ let running;
67
+ for (const { slot, platforms } of projectDeviceSlots(project)) {
68
+ if (platform === "ios") {
69
+ const sim = platforms.ios;
70
+ if (sim?.owned && sim.deviceUdid && sim.deviceUdid.toLowerCase() === id.toLowerCase()) return {
71
+ id: sim.deviceUdid,
72
+ deviceName: sim.deviceName ?? null,
73
+ slot
74
+ };
75
+ continue;
76
+ }
77
+ const emulator = platforms.android;
78
+ if (!emulator?.owned || !emulator.avdName || !/^emulator-\d+$/.test(id)) continue;
79
+ running ??= { name: await avdNameOf(id) };
80
+ if (running.name === emulator.avdName) return {
81
+ id,
82
+ deviceName: emulator.deviceName ?? emulator.avdName,
83
+ slot
84
+ };
85
+ }
86
+ return null;
87
+ }
88
+ function isFailure(value) {
89
+ return "code" in value;
90
+ }
91
+ async function poolDevice(platform, idLabel, waitSeconds, deadline, root, d, slot) {
92
+ const isEmulator = memoizeEmulatorProbe(d.probeEmulatorSerial);
93
+ const pooled = await d.selectFromPool({
94
+ ...slot ? { slot } : {},
95
+ root,
96
+ platform,
97
+ idLabel,
98
+ list: async () => platform === "ios" ? iosPoolCandidates(await d.listIosDevices()).map((entry) => ({
99
+ id: entry.udid,
100
+ name: entry.name,
101
+ fallback: isWirelessIosDevice(entry)
102
+ })) : androidPoolCandidates(d.listAdbDevices(), isEmulator).map((entry) => ({ id: entry.serial })),
103
+ noCandidates: async () => {
104
+ const resolved = platform === "ios" ? iosPoolNoCandidatesRefusal(await d.listIosDevices()) : androidPoolNoCandidatesRefusal(d.listAdbDevices(), isEmulator);
105
+ return {
106
+ message: resolved.error,
107
+ remedy: resolved.remedy
108
+ };
109
+ },
110
+ waitSeconds,
111
+ deadline,
112
+ now: d.now,
113
+ sleep: d.sleep,
114
+ warn: (line) => d.note(chalk.yellow(line)),
115
+ io: d.io
116
+ });
117
+ if (pooled.status === "refused") return {
118
+ code: pooled.refusal.code,
119
+ message: pooled.refusal.message,
120
+ remedy: pooled.refusal.remedy,
121
+ ...pooled.refusal.lease === null ? {} : { lease: pooled.refusal.lease }
122
+ };
123
+ const name = pooled.candidate.name ?? (platform === "ios" ? pooled.candidate.id : d.physicalDeviceModel(pooled.candidate.id));
124
+ return {
125
+ id: pooled.candidate.id,
126
+ deviceName: name ?? pooled.candidate.id
127
+ };
128
+ }
129
+ async function runLock(platformArg, idArg, opts = {}, overrides = {}) {
130
+ const d = {
131
+ ...DEFAULT_DEPS,
132
+ ...overrides
133
+ };
134
+ const json = Boolean(opts.json);
135
+ const report = (failure) => {
136
+ d.note(chalk.red(`${failure.code}: ${failure.message}`));
137
+ if (failure.remedy) d.note(chalk.dim(failure.remedy));
138
+ if (json) d.out(JSON.stringify({
139
+ code: failure.code,
140
+ message: failure.message,
141
+ remedy: failure.remedy,
142
+ ...failure.lease === void 0 ? {} : { lease: failure.lease }
143
+ }));
144
+ return failure;
145
+ };
146
+ const platform = readPlatform(platformArg);
147
+ if (!platform) return report({
148
+ code: "STIM_BAD_ARG",
149
+ message: `\`stim device lock\` takes ios or android, not ${JSON.stringify(platformArg)}.`,
150
+ remedy: "Run `stim device lock ios` or `stim device lock android`."
151
+ });
152
+ const root = d.findProjectRoot(process.cwd());
153
+ if (!root) return report(NO_PROJECT_REFUSAL);
154
+ const durationText = String(opts.for ?? DEFAULT_FOR).trim();
155
+ const duration = parseLeaseDuration(durationText);
156
+ if ("error" in duration) return report({
157
+ code: "STIM_BAD_ARG",
158
+ message: duration.error,
159
+ remedy: "Pass a whole number of seconds or minutes from 10s to 30m, e.g. --for 90s or --for 10m."
160
+ });
161
+ const wait = parseDeviceWait(opts.wait);
162
+ if ("error" in wait) return report({
163
+ code: "STIM_BAD_ARG",
164
+ message: wait.error,
165
+ remedy: "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a leased device at once."
166
+ });
167
+ const idLabel = platform === "ios" ? "udid" : "serial";
168
+ const deadline = d.now() + wait.seconds * 1e3;
169
+ const lastLine = { at: null };
170
+ const owned = idArg ? await findOwnedVirtualDevice(d.getProject(root), platform, idArg, d.avdNameOf) : null;
171
+ if (owned && opts.slot && opts.slot !== owned.slot) return report({
172
+ code: "STIM_BAD_ARG",
173
+ message: `${owned.id} is this workspace's ${platform} device in slot ${owned.slot}, not ${opts.slot}.`,
174
+ remedy: `Run \`stim device lock ${platform} ${owned.id}\` without --slot, or with --slot ${owned.slot}.`
175
+ });
176
+ const held = owned ? d.io.readHolder(root)[deviceSlotKey(platform, owned.slot)] : void 0;
177
+ if (owned && held && held.id !== owned.id) return report({
178
+ code: "STIM_DEVICE_BUSY",
179
+ message: `This workspace already leases ${held.id} for ${platform} in slot ${owned.slot}, and a workspace holds one lease per platform and slot.`,
180
+ remedy: `Release it with \`stim device unlock ${platform}${owned.slot === "default" ? "" : ` --slot ${owned.slot}`}\` once nothing depends on it, then lock ${owned.id}.`
181
+ });
182
+ const slot = owned ? owned.slot === "default" ? void 0 : owned.slot : opts.slot;
183
+ const device = owned ? owned : idArg ? await resolveDevice(platform, idArg, d) : await poolDevice(platform, idLabel, wait.seconds, deadline, root, d, opts.slot);
184
+ if (isFailure(device)) return report(device);
185
+ for (;;) {
186
+ const outcome = await d.waitForDevice({
187
+ ...slot ? { slot } : {},
188
+ root,
189
+ platform,
190
+ id: device.id,
191
+ idLabel,
192
+ waitSeconds: wait.seconds,
193
+ now: d.now,
194
+ sleep: d.sleep,
195
+ warn: (line) => d.note(chalk.yellow(line)),
196
+ io: d.io,
197
+ deadline,
198
+ lastLine
199
+ });
200
+ if (outcome.status === "refused") return report({
201
+ ...outcome.refusal,
202
+ lease: outcome.refusal.lease
203
+ });
204
+ const taken = d.takeLease({
205
+ ...slot ? { slot } : {},
206
+ root,
207
+ platform,
208
+ id: device.id,
209
+ deviceName: device.deviceName,
210
+ kind: "declared",
211
+ durationMs: duration.ms
212
+ }, d.io);
213
+ if (taken.status === "unreadable") return report({
214
+ code: "STIM_DEVICE_BUSY",
215
+ message: `The lease file at ${taken.path} does not parse, so Stim cannot tell who holds that device.`,
216
+ remedy: `Read ${taken.path} and, once you know no run depends on it, delete it. \`stim gc\` reports it on every run.`,
217
+ lease: {
218
+ platform: null,
219
+ id: null,
220
+ deviceName: null,
221
+ holder: null,
222
+ expiresAt: null
223
+ }
224
+ });
225
+ if (taken.status === "held") continue;
226
+ const facts = {
227
+ ...taken.lease.slot ? { slot: taken.lease.slot } : {},
228
+ platform,
229
+ id: taken.lease.id,
230
+ deviceName: taken.lease.deviceName,
231
+ holder: taken.lease.holder,
232
+ kind: "declared",
233
+ grantedAt: taken.lease.grantedAt,
234
+ expiresAt: taken.lease.expiresAt,
235
+ leaseSeconds: Math.round(duration.ms / 1e3)
236
+ };
237
+ if (json) d.out(JSON.stringify(facts));
238
+ else d.out(chalk.green(grantLine(facts, durationText)));
239
+ return facts;
240
+ }
241
+ }
242
+ async function runUnlock(platformArg, opts = {}, overrides = {}) {
243
+ const d = {
244
+ ...DEFAULT_DEPS,
245
+ ...overrides
246
+ };
247
+ const json = Boolean(opts.json);
248
+ const report = (failure) => {
249
+ d.note(chalk.red(`${failure.code}: ${failure.message}`));
250
+ if (failure.remedy) d.note(chalk.dim(failure.remedy));
251
+ if (json) d.out(JSON.stringify({
252
+ code: failure.code,
253
+ message: failure.message,
254
+ remedy: failure.remedy
255
+ }));
256
+ return failure;
257
+ };
258
+ const platform = platformArg === void 0 ? null : readPlatform(platformArg);
259
+ if (platformArg !== void 0 && !platform) return report({
260
+ code: "STIM_BAD_ARG",
261
+ message: `\`stim device unlock\` takes ios or android, not ${JSON.stringify(platformArg)}.`,
262
+ remedy: "Run `stim device unlock` for every lease this workspace holds, or name one platform."
263
+ });
264
+ const root = d.findProjectRoot(process.cwd());
265
+ if (!root) return report(NO_PROJECT_REFUSAL);
266
+ const released = d.releaseLeases(root, {
267
+ platform,
268
+ ...opts.slot ? { slot: opts.slot } : {}
269
+ }, d.io);
270
+ 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.`));
271
+ if (json) d.out(JSON.stringify(released.map((lease) => ({
272
+ ...lease,
273
+ holder: root
274
+ }))));
275
+ else for (const lease of released) d.out(chalk.green(releasedLine(lease)));
276
+ return released;
277
+ }
278
+ function registerDevice(program, deps = {}) {
279
+ const device = program.command("device").description("Lease a connected physical device to this workspace, give it back, or provision iOS signing for it");
280
+ 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) => {
281
+ if ("code" in await runLock(platform, id, opts, deps)) process.exit(1);
282
+ });
283
+ 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) => {
284
+ const result = await runUnlock(platform, opts, deps);
285
+ if (!Array.isArray(result)) process.exit(1);
286
+ });
287
+ device.command("provision").argument("<platform>", "ios").argument("[udid]", "the connected iPhone or iPad to provision for; required when more than one is connected").description("Register a connected iPhone with the project's Apple Developer team and create or refresh its iOS App Development profile, through xcodebuild -allowProvisioningUpdates. It lists the account changes and asks first; no build ever does this.").option("--scheme <name>", "Xcode scheme whose signed targets to provision (default: ios.scheme, then detected)").option("--configuration <name>", "build configuration to provision (default: ios.configuration, then Debug)").option("--yes", "confirm the listed Apple Developer account changes without a prompt").option("--json", "print the plan and result, or the refusal, as JSON on stdout").action(async (platform, udid, opts) => {
288
+ const root = findProjectRoot(process.cwd()) ?? process.cwd();
289
+ const { value: result, interrupted } = await runProcessOperation(root, (operation) => runProvision(platform, udid, opts, { operation }));
290
+ if ("code" in result) process.exit(interrupted ?? 1);
291
+ });
292
+ }
293
+ function deviceCommand(program) {
294
+ registerDevice(program);
295
+ }
296
+ //#endregion
297
+ export { deviceCommand as default, grantLine, registerDevice, releasedLine, runLock, runUnlock };
@@ -1,12 +1,12 @@
1
1
  import { D as ownership_claim_exports, d as workspaceProcessLockError, u as withWorkspaceProcessLock } from "./exec-aULwtNly.mjs";
2
- import { G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, d as getConfigDir, u as getConcurrencyLimits } from "./config-Cn94Jc0g.mjs";
3
- import { a as formatElapsed, l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
4
- import { g as deviceReclaimIdleMinutesSetting } from "./settings-BDVI8Ivc.mjs";
5
- import { A as listAdbDevices, j as listAdbDevicesAsync } from "./android-DriNoAVy.mjs";
6
- import { _ as withIdleWorkspace, it as recordCapacityWait, rt as recordCapacityRefusal } from "./workspaces-DFbj07jp.mjs";
2
+ import { G as projectDeviceSlots, H as deviceSlotPlatforms, O as withConfigLockAsync$1, _ as loadConfig$1, d as getConfigDir, u as getConcurrencyLimits } from "./config-AbUjIBOQ.mjs";
3
+ import { a as formatElapsed, l as phaseLine } from "./command-output-DjCsmzLZ.mjs";
4
+ import { g as deviceReclaimIdleMinutesSetting } from "./settings-D776ygML.mjs";
5
+ import { A as listAdbDevices, j as listAdbDevicesAsync } from "./android-BHKgeOuq.mjs";
6
+ import { ot as recordCapacityRefusal, st as recordCapacityWait, v as withIdleWorkspace } from "./workspaces-CvSYD_78.mjs";
7
7
  import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
8
- import { d as listAllIosSims, f as listAllIosSimsAsync, l as iosRuntimeMatches, y as parseRuntimeVersion } from "./ios-E26qSpkb.mjs";
9
- import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-Cbvo5KEh.mjs";
8
+ import { d as listAllIosSims, f as listAllIosSimsAsync, l as iosRuntimeMatches, y as parseRuntimeVersion } from "./ios-CoMCWfub.mjs";
9
+ import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-BM37gMfU.mjs";
10
10
  import { realpathSync } from "node:fs";
11
11
  import { basename, join } from "node:path";
12
12
  import { workspaceId } from "@stim-cli/core";
@@ -385,8 +385,15 @@ const DEFAULT_DEVICE_SLOT_WAIT_MS = 6e5;
385
385
  function deviceSlotWaitingLine({ count, max, holders, elapsedMs, queue }) {
386
386
  return `${"device".padEnd(11)} waiting for a device slot (${count}/${max} in use${holders.length ? `: ${holders.join(", ")}` : ""}), ${formatElapsed(elapsedMs)} elapsed -- stim guide lifecycle concurrency${queue ? `; ${queue}` : ""}`;
387
387
  }
388
- function deviceHolders(inventory, keys) {
389
- const names = /* @__PURE__ */ new Map();
388
+ function unrecordedHolder(label) {
389
+ return {
390
+ label,
391
+ workspace: null,
392
+ slot: null
393
+ };
394
+ }
395
+ function slotHolders(inventory, keys) {
396
+ const owners = /* @__PURE__ */ new Map();
390
397
  const projects = Object.entries(inventory.config?.projects ?? {});
391
398
  const labels = workspaceLabels(projects.map(([root, project]) => ({
392
399
  root,
@@ -394,20 +401,77 @@ function deviceHolders(inventory, keys) {
394
401
  })));
395
402
  for (const [root, project] of projects) {
396
403
  const label = labels.get(root) ?? basename(root);
397
- for (const { platforms } of projectDeviceSlots(project)) {
398
- if (platforms.ios?.deviceUdid) names.set(deviceKey("ios", platforms.ios.deviceUdid), label);
399
- if (platforms.android?.avdName) names.set(deviceKey("android", platforms.android.avdName), label);
404
+ for (const { slot, platforms } of projectDeviceSlots(project)) {
405
+ if (platforms.ios?.deviceUdid) owners.set(deviceKey("ios", platforms.ios.deviceUdid), {
406
+ label,
407
+ workspace: root,
408
+ slot
409
+ });
410
+ if (platforms.android?.avdName) owners.set(deviceKey("android", platforms.android.avdName), {
411
+ label,
412
+ workspace: root,
413
+ slot
414
+ });
400
415
  }
401
416
  }
402
417
  for (const sim of inventory.sims) {
403
418
  const key = deviceKey("ios", sim.udid);
404
- if (!names.has(key)) names.set(key, sim.name);
419
+ if (!owners.has(key)) owners.set(key, unrecordedHolder(sim.name));
405
420
  }
421
+ const booting = /* @__PURE__ */ new Set();
406
422
  for (const device of inventory.booting) {
407
423
  const key = deviceKey(device.platform, device.key);
408
- if (!names.has(key)) names.set(key, device.displayName ?? device.key);
424
+ booting.add(key);
425
+ if (!owners.has(key)) owners.set(key, unrecordedHolder(device.displayName ?? device.key));
426
+ }
427
+ return [...keys].map((key) => {
428
+ const { label, workspace, slot } = owners.get(key) ?? unrecordedHolder(key.slice(key.indexOf(":") + 1));
429
+ const platform = key.startsWith("android:") ? "android" : "ios";
430
+ return booting.has(key) ? {
431
+ platform,
432
+ label,
433
+ workspace,
434
+ slot,
435
+ booting: true
436
+ } : {
437
+ platform,
438
+ label,
439
+ workspace,
440
+ slot
441
+ };
442
+ }).toSorted((a, b) => a.label.localeCompare(b.label) || a.platform.localeCompare(b.platform));
443
+ }
444
+ function deviceHolders(inventory, keys) {
445
+ return [...new Set(slotHolders(inventory, keys).map((holder) => holder.label))].toSorted();
446
+ }
447
+ /**
448
+ * `concurrency.maxDevices` usage for status: the owned devices the cap counts and who holds each. `sims` is the
449
+ * listing status already read; an unknown count reports why instead of failing.
450
+ */
451
+ async function deviceSlotUsage(max, sources = {}) {
452
+ try {
453
+ const inventory = await readInventoryAsync(sources);
454
+ if ("code" in inventory) return {
455
+ max,
456
+ inUse: null,
457
+ unknown: inventory.message,
458
+ holders: []
459
+ };
460
+ const keys = inventoryKeys(inventory);
461
+ return {
462
+ max,
463
+ inUse: keys.size,
464
+ holders: slotHolders(inventory, keys)
465
+ };
466
+ } catch (error) {
467
+ if ((0, ownership_claim_exports.isClaimRefusal)(error)) return {
468
+ max,
469
+ inUse: null,
470
+ unknown: error.message,
471
+ holders: []
472
+ };
473
+ throw error;
409
474
  }
410
- return [...new Set([...keys].map((key) => names.get(key) ?? key.slice(key.indexOf(":") + 1)))].toSorted();
411
475
  }
412
476
  function liveWaiters() {
413
477
  const root = join(getConfigDir(), "device-waits");
@@ -479,7 +543,7 @@ async function admissionTransaction(action, lockWaitMs, out, signal) {
479
543
  }
480
544
  }
481
545
  /** Boots an owned device under the Stim home's cap, reserving capacity before releasing admission. */
482
- async function withDeviceBootAdmission(device, boot, { root, max = getConcurrencyLimits().maxDevices, sources = {}, lockWaitMs = ADMISSION_LOCK_WAIT_MS, out = () => {}, waitMs = DEFAULT_DEVICE_SLOT_WAIT_MS, noWait = false, automatic = false, displayName = workspaceDisplayLabel(root, loadConfig$1()), reclaimIdleMinutes = deviceReclaimIdleMinutesSetting({}), now = Date.now, signal, sleep = (ms) => setTimeout(ms, void 0, { signal }), waitingFor = () => {}, onWait = () => {} }) {
546
+ async function withDeviceBootAdmission(device, boot, { root, max = getConcurrencyLimits().maxDevices, sources = {}, lockWaitMs = ADMISSION_LOCK_WAIT_MS, out = () => {}, waitMs = DEFAULT_DEVICE_SLOT_WAIT_MS, noWait = false, automatic = false, displayName = workspaceDisplayLabel(root, loadConfig$1()), reclaimIdleMinutes = deviceReclaimIdleMinutesSetting({}), now = Date.now, signal, sleep = (ms) => setTimeout(ms, void 0, { signal }), waitingFor = () => {}, onWait = () => {}, onBootStart = () => {} }) {
483
547
  const requireMembership = () => {
484
548
  if (automatic && !automaticMachineEnabled("device", "local")) throw new DeviceAdmissionRefusal({
485
549
  code: "STIM_HOSTING_REFUSED",
@@ -489,7 +553,10 @@ async function withDeviceBootAdmission(device, boot, { root, max = getConcurrenc
489
553
  };
490
554
  signal?.throwIfAborted();
491
555
  requireMembership();
492
- if (!max || max <= 0) return boot();
556
+ if (!max || max <= 0) {
557
+ onBootStart();
558
+ return boot();
559
+ }
493
560
  const workspace = workspaceId(root);
494
561
  device = {
495
562
  ...device,
@@ -628,6 +695,7 @@ async function withDeviceBootAdmission(device, boot, { root, max = getConcurrenc
628
695
  }
629
696
  }
630
697
  requireMembership();
698
+ onBootStart();
631
699
  return await boot();
632
700
  } finally {
633
701
  (0, ownership_claim_exports.releaseClaim)(marker);
@@ -697,4 +765,4 @@ function unknownAndroidDeviceProfileRefusal(requested, profiles) {
697
765
  };
698
766
  }
699
767
  //#endregion
700
- export { countLiveOwnedDevicesAsync as a, layerNote as c, unknownAndroidDeviceProfileRefusal as d, unknownAndroidSystemImageRefusal as f, withDeviceBootAdmission as h, countLiveOwnedDevices as i, peekDeviceSlots as l, unknownIosRuntimeRefusal as m, DeviceAdmissionRefusal as n, countLiveOwnedDevicesFrom as o, unknownIosDeviceTypeRefusal as p, checkDeviceCapacity as r, deviceTypeMismatch as s, DEFAULT_DEVICE_SLOT_WAIT_MS as t, runtimeMismatch as u };
768
+ export { countLiveOwnedDevicesAsync as a, deviceTypeMismatch as c, runtimeMismatch as d, unknownAndroidDeviceProfileRefusal as f, withDeviceBootAdmission as g, unknownIosRuntimeRefusal as h, countLiveOwnedDevices as i, layerNote as l, unknownIosDeviceTypeRefusal as m, DeviceAdmissionRefusal as n, countLiveOwnedDevicesFrom as o, unknownAndroidSystemImageRefusal as p, checkDeviceCapacity as r, deviceSlotUsage as s, DEFAULT_DEVICE_SLOT_WAIT_MS as t, peekDeviceSlots as u };