stim 1.26.0 → 1.28.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 (172) hide show
  1. package/dist/{acquire-artifact-DVsvSwf7.mjs → acquire-artifact-CKByBnTD.mjs} +2 -2
  2. package/dist/{act-C-BqJEpu.mjs → act-8iswyfRa.mjs} +319 -126
  3. package/dist/{activity-Lnb_EoRY.mjs → activity-DRMg4_mD.mjs} +6 -6
  4. package/dist/{agent-device-usage-output-DbXy5tg8.mjs → agent-device-usage-output-tE90fDdo.mjs} +5 -5
  5. package/dist/{android-CiNQw3kq.mjs → android-CHmSU4B4.mjs} +101 -45
  6. package/dist/{android-DTAcRwBC.mjs → android-CsPs-7Mg.mjs} +23 -18
  7. package/dist/{android-B5P81yI-.mjs → android-D577ApKG.mjs} +37 -15
  8. package/dist/{android-CSbLRD53.mjs → android-YWCbmkVK.mjs} +5 -5
  9. package/dist/{android-cas-BTVhZ0Qs.mjs → android-cas-_aDifWW0.mjs} +4 -4
  10. package/dist/android-cas-compiler.mjs +1 -1
  11. package/dist/api.d.mts +14 -4
  12. package/dist/api.mjs +39 -29
  13. package/dist/{apk-signed-tail-B46U9hXc.mjs → apk-signed-tail-CQbwM0qO.mjs} +2 -2
  14. package/dist/{artifact-CsAP6AGK.mjs → artifact-DYtHjxsn.mjs} +19 -24
  15. package/dist/{artifact-BxREhAaV.mjs → artifact-bFkfD3vf.mjs} +18 -23
  16. package/dist/{artifact-platform-CMRc0M_r.mjs → artifact-platform-BO2Uvk_A.mjs} +1 -1
  17. package/dist/auto-placement-BVqs8AJi.mjs +350 -0
  18. package/dist/{browser-web-rYPyqhTf.mjs → browser-web-BUaLcafY.mjs} +16 -16
  19. package/dist/{build-DPhApsjV.mjs → build-cQURy_KW.mjs} +35 -31
  20. package/dist/{build-cache-DrXNCy3T.mjs → build-cache-CZULpXVl.mjs} +43 -21
  21. package/dist/{build-plan-DrMMdayj.mjs → build-plan-CxoYfxsc.mjs} +7 -6
  22. package/dist/{cache-manifest-BEZ9Bpl1.mjs → cache-manifest-DEjqGGat.mjs} +1 -1
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{budget-k2mZGvvk.mjs → ccache-Bm_A1xX9.mjs} +562 -1604
  25. package/dist/{cdp-BG3FJCCx.mjs → cdp-C3svvXiE.mjs} +1 -1
  26. package/dist/{chrome-BvV8ssI3.mjs → chrome-DyDWurWG.mjs} +1 -1
  27. package/dist/{cli-BBKFGOFl.mjs → cli-CpbaLDa7.mjs} +24 -23
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-D9CaRks-.mjs → client-YxCer6ab.mjs} +84 -65
  30. package/dist/collector-run.d.mts +10 -9
  31. package/dist/collector-run.mjs +42 -27
  32. package/dist/{command-output-BF5AR2dL.mjs → command-output-C8R1KIvi.mjs} +1 -1
  33. package/dist/{config-BktkY_zC.mjs → config-Cn94Jc0g.mjs} +23 -4
  34. package/dist/{dependencies-Dw6wfQdv.mjs → dependencies-DKeMzwXY.mjs} +108 -60
  35. package/dist/{dependency-state-DFB41vfr.mjs → dependency-state-CojA2o0t.mjs} +14 -7
  36. package/dist/{detached-entry-KmieOKgN.mjs → detached-entry-BPlSaCwC.mjs} +1 -1
  37. package/dist/{dev-client-DXR_tPVY.mjs → dev-client-D-BW5uiq.mjs} +2 -2
  38. package/dist/{device-BK-zwyd_.mjs → device-CgXfbcz5.mjs} +25 -24
  39. package/dist/{device-capacity-DCSvUF0l.mjs → device-capacity-Cd8lMSn3.mjs} +175 -22
  40. package/dist/{device-BcYeHSFu.mjs → device-eeK95Lir.mjs} +16 -16
  41. package/dist/device-host-worker.mjs +22 -20
  42. package/dist/{device-ios-BLGfXQeK.mjs → device-ios-Cc9ulihb.mjs} +251 -23
  43. package/dist/{device-lease-run-BmvIl7bI.mjs → device-lease-run-Mtzp4THX.mjs} +5 -5
  44. package/dist/{device-pool-Dluix4H3.mjs → device-pool-eRz6DtCg.mjs} +3 -3
  45. package/dist/{doctor-Bhg1ii70.mjs → doctor-Bz_ouYAW.mjs} +28 -16
  46. package/dist/{doctor-Cp-BhzTS.mjs → doctor-C2QyhejJ.mjs} +1 -1
  47. package/dist/{doctor-fingerprint-D3a04Mhu.mjs → doctor-fingerprint-o7ZI9YLn.mjs} +1 -1
  48. package/dist/doctor-fingerprint.mjs +1 -1
  49. package/dist/{doctor-watchman-BStK05nt.mjs → doctor-watchman-BTW82PDC.mjs} +5 -5
  50. package/dist/{doctor-OnwP94ne.mjs → doctor-xf7ht-5n.mjs} +76 -32
  51. package/dist/{eas-build-Dsj93iM9.mjs → eas-build-Dm6q68QY.mjs} +4 -4
  52. package/dist/eas-fallback-DajNpxf-.mjs +87 -0
  53. package/dist/{eas-session-ledger-B5vygTiD.mjs → eas-session-ledger-CBFo_Uo1.mjs} +37 -8
  54. package/dist/{error-diagnostics-BOOm9Db7.mjs → error-diagnostics-D1QfyJzQ.mjs} +51 -25
  55. package/dist/{exec-VFRpu1iA.mjs → exec-aULwtNly.mjs} +57 -6
  56. package/dist/{gc-ldgr-hXU.mjs → gc-DM5oMm-J.mjs} +161 -45
  57. package/dist/{gc-C_79zvz4.mjs → gc-PLFwb0k4.mjs} +2 -2
  58. package/dist/{guide-D7K0X6KG.mjs → guide-C4I46XAk.mjs} +674 -213
  59. package/dist/{hosted-android-Bk54ej6n.mjs → hosted-android-DlaKLbW0.mjs} +6 -7
  60. package/dist/{hosted-client-fHO8yqzc.mjs → hosted-client-DDRm9hPJ.mjs} +51 -20
  61. package/dist/{hosted-logs-BfbmDM4M.mjs → hosted-logs-bSebOKbz.mjs} +8 -8
  62. package/dist/{hosted-logs-sync-B0pvmOk-.mjs → hosted-logs-sync-B0c53W_c.mjs} +5 -5
  63. package/dist/{hosted-macos-CPl0OZ9h.mjs → hosted-macos-B7-8Pv4H.mjs} +6 -6
  64. package/dist/{hosted-native-CpDB3-PO.mjs → hosted-native-CDe33CSr.mjs} +22 -18
  65. package/dist/{idle-shutdown-FfxL1KdG.mjs → idle-shutdown-CQ0QwU9J.mjs} +7 -8
  66. package/dist/{ios-WxpDJ5T1.mjs → ios-B1DYuOjh.mjs} +27 -11
  67. package/dist/{ios-B7-lToDu.mjs → ios-B1HvafEG.mjs} +8 -8
  68. package/dist/{ios-ENC4sRPA.mjs → ios-CsRVik64.mjs} +7 -1
  69. package/dist/{ios-device-CsyryvpT.mjs → ios-device-B4elVFKi.mjs} +3 -3
  70. package/dist/{ios-device-B6HK951C.mjs → ios-device-CiBA-er9.mjs} +1 -1
  71. package/dist/{ios-project-Ty5pHl9O.mjs → ios-project-CR4mZ7CH.mjs} +22 -9
  72. package/dist/{ios-signing-4c_qXvQm.mjs → ios-signing-BJzvDPfU.mjs} +2 -2
  73. package/dist/{ios-state-Cw7-WQf2.mjs → ios-state-BPHqMDdZ.mjs} +1 -1
  74. package/dist/{ios-ftxdQbJS.mjs → ios-tg4tp3q1.mjs} +94 -37
  75. package/dist/{js-swap-BMhXYVDS.mjs → js-swap-CVpSW1fn.mjs} +8 -7
  76. package/dist/{launch-DOp8RjDz.mjs → launch-DoySmhjz.mjs} +42 -38
  77. package/dist/lightened-DFAJgfIk.mjs +171 -0
  78. package/dist/{logs-s1dRIG1E.mjs → logs-BGsW7iPe.mjs} +46 -21
  79. package/dist/{logs-dQDki6Tt.mjs → logs-DI5ILkYB.mjs} +7 -7
  80. package/dist/{macos-DBBPNnIA.mjs → macos-Bo9st9Di.mjs} +73 -38
  81. package/dist/{macos-B0VEV3Gf.mjs → macos-C12RMJQF.mjs} +1 -1
  82. package/dist/macos-run.mjs +1 -1
  83. package/dist/maintenance-run.mjs +7 -7
  84. package/dist/{metro-CjC10t6E.mjs → metro-BnhXV2Mj.mjs} +4 -4
  85. package/dist/{metro-gateway-B6_PgD0L.mjs → metro-request-DXyKjVDF.mjs} +26 -47
  86. package/dist/{named-ports-BG0j1X4g.mjs → named-ports-Phoi2POD.mjs} +3 -3
  87. package/dist/{native-android-CL2NGiik.mjs → native-android-vxgtLD7w.mjs} +17 -18
  88. package/dist/{native-gradle-artifact-inputs-btSUulme.mjs → native-gradle-artifact-inputs-BN96IVw8.mjs} +5 -5
  89. package/dist/{native-runtime-Dq3RBcON.mjs → native-runtime-DG4Rodzj.mjs} +9 -8
  90. package/dist/{native-source-D-4Dh4JU.mjs → native-source-D1AzWiuP.mjs} +1 -1
  91. package/dist/{native-xcode-inputs-BW7H8JGu.mjs → native-xcode-inputs-BKarCoKg.mjs} +3 -3
  92. package/dist/{native-xcode-ios-CBXJAxfC.mjs → native-xcode-ios-8A-efGa5.mjs} +17 -17
  93. package/dist/{ndjson-CgE_o3Dl.mjs → ndjson-Dy2W4vRa.mjs} +2 -2
  94. package/dist/offload-worker.mjs +23 -24
  95. package/dist/{operation-exec-CUZifp6Z.mjs → operation-exec-Dp4FuIGR.mjs} +1 -1
  96. package/dist/{ownership-BjYvMNX_.mjs → ownership-DJCq48IJ.mjs} +3 -3
  97. package/dist/{page-CzEA_-5_.mjs → page-CQJlcj3x.mjs} +2 -2
  98. package/dist/{phone-reverses-lmj6kcPm.mjs → phone-reverses-BzTa8g1F.mjs} +18 -4
  99. package/dist/{placement-log-DIFPQAXp.mjs → placement-log-Cvhta5ib.mjs} +3 -3
  100. package/dist/{plan-placement-IiiSQhtz.mjs → plan-placement-WkZdccuN.mjs} +36 -10
  101. package/dist/{ports-C2_w1Z0Z.mjs → ports-UV4mJgyC.mjs} +3 -3
  102. package/dist/{prebuild-gmouvmJZ.mjs → prebuild-k8d_tqOq.mjs} +16 -17
  103. package/dist/{project-BUu6Is4k.mjs → project-Sui52ywT.mjs} +17 -17
  104. package/dist/{pull-request-CbNlkFok.mjs → pull-request-BzLmzAIQ.mjs} +2 -2
  105. package/dist/pull-requests.mjs +1 -1
  106. package/dist/{react-native-android-Cgg99REN.mjs → react-native-android-DANlGGQf.mjs} +32 -26
  107. package/dist/{react-native-build-oNwqF5Wb.mjs → react-native-build-jUHnIfZ9.mjs} +9 -9
  108. package/dist/{react-native-doctor-BhA3KUte.mjs → react-native-doctor-DCWRjS7K.mjs} +6 -6
  109. package/dist/{react-native-ios-B-nf4rjN.mjs → react-native-ios-BwMsFMXi.mjs} +23 -17
  110. package/dist/{recordings-BldzVKq0.mjs → recordings-iy0mkm7b.mjs} +1 -1
  111. package/dist/{registration-CN6nlhcD.mjs → registration-BwCe64PH.mjs} +1 -1
  112. package/dist/{reload-C9OduiNc.mjs → reload-Bj7QyuDy.mjs} +1 -1
  113. package/dist/{reload-CCR7KC_l.mjs → reload-c_uEyc_X.mjs} +16 -16
  114. package/dist/{remote-C8S7FlPF.mjs → remote-DFlpAqdV.mjs} +23 -10
  115. package/dist/{result-7F5hEwQJ.mjs → result-BIcXREyC.mjs} +32 -21
  116. package/dist/{run-BqB0v3pt.mjs → run-y2HwyNvg.mjs} +3 -3
  117. package/dist/{selection-BNPBZ6T5.mjs → selection-CXgM_VK_.mjs} +37 -29
  118. package/dist/{server-bare-A75rDIdD.mjs → server-bare-2N4vSRZG.mjs} +2 -2
  119. package/dist/{server-command-CssKFOD7.mjs → server-command-qneHPcRI.mjs} +6 -6
  120. package/dist/{server-expo-eQfOdydb.mjs → server-expo-Ccm9zB0o.mjs} +4 -4
  121. package/dist/server-expo-WulkyAwT.mjs +2 -0
  122. package/dist/{settings-CosW5X-S.mjs → settings-CY5JZlNN.mjs} +375 -62
  123. package/dist/{settings-OaGQF-ri.mjs → settings-Cfd_Q6ys.mjs} +24 -3
  124. package/dist/settings-payload-DwQiEMCn.mjs +257 -0
  125. package/dist/settings-write-CJpjkeAd.mjs +185 -0
  126. package/dist/settings.schema.json +51 -33
  127. package/dist/{simslim-Bax1qcxu.mjs → simslim-DCQwzoPy.mjs} +2 -2
  128. package/dist/{slot-launch-CYCEhfBY.mjs → slot-launch-BpmanOnk.mjs} +6 -6
  129. package/dist/{stage-jKQ7CP_B.mjs → stage-CmugrSG5.mjs} +2 -2
  130. package/dist/{start-C_wefNKB.mjs → start-CHH3zgIU.mjs} +1 -1
  131. package/dist/{start-_BdJ32cZ.mjs → start-DYLk6GXn.mjs} +27 -22
  132. package/dist/{state-C1i2nMOP.mjs → state-B2QJbDwz.mjs} +4 -4
  133. package/dist/{state-C4OdpOTF.mjs → state-BXC1Lfxw.mjs} +2 -2
  134. package/dist/{stats-tEpEEH-u.mjs → stats-DxKqhcGp.mjs} +5 -5
  135. package/dist/{stats-report-n2U5plhk.mjs → stats-report-B86Cv7Uc.mjs} +1 -1
  136. package/dist/{status-CRXz-Gtj.mjs → status-7ULDEJ1e.mjs} +1 -1
  137. package/dist/{status-DQrqodLj.mjs → status-BHCkOZga.mjs} +51 -28
  138. package/dist/{status-B9M7x4CZ.mjs → status-D_Ljc89p.mjs} +1 -1
  139. package/dist/{status-watch-B5wDIH_o.mjs → status-watch-BmsPqYSU.mjs} +18 -7
  140. package/dist/status-worker.mjs +1 -1
  141. package/dist/{stim-desktop-6Dqp-gjX.mjs → stim-desktop-CbWo21kb.mjs} +2 -2
  142. package/dist/{stop-DRqQVqDJ.mjs → stop-D-dGE9gh.mjs} +21 -20
  143. package/dist/{stop-ySNQHXMG.mjs → stop-DQvE-P76.mjs} +10 -6
  144. package/dist/{stop-CmdNhGlC.mjs → stop-b2pouxAO.mjs} +2 -2
  145. package/dist/supervisor-run.mjs +237 -63
  146. package/dist/{support-BGSCBoib.mjs → support-04IhBUTT.mjs} +6 -6
  147. package/dist/{support-CVOCp0Ft.mjs → support-BtlJKjyQ.mjs} +12 -11
  148. package/dist/{swiftpm-artifact-inputs-CfUzt_0Z.mjs → swiftpm-artifact-inputs-Cj2UpmPN.mjs} +4 -4
  149. package/dist/{swiftpm-macos-x6HPpl_2.mjs → swiftpm-macos-BhF2stxY.mjs} +11 -12
  150. package/dist/{toolchain-J4J8MrAr.mjs → toolchain-mLA_km-b.mjs} +321 -15
  151. package/dist/{toolchain-DoavrvIA.mjs → toolchain-qktiV8xc.mjs} +1 -1
  152. package/dist/{trigger-KVaWWNyn.mjs → trigger-DMou-X7j.mjs} +2 -2
  153. package/dist/trigger-qp2ji5wE.mjs +2 -0
  154. package/dist/{warm-progress-DvhTX_eu.mjs → warm-progress-B0Vpuvpl.mjs} +731 -727
  155. package/dist/{web-Bihbf7-u.mjs → web-BYmK0TjL.mjs} +9 -9
  156. package/dist/web-CrVLVQZY.mjs +2 -0
  157. package/dist/web-run.mjs +9 -9
  158. package/dist/windows-report.mjs +1 -1
  159. package/dist/{workspace-state-pUg3_RRA.mjs → workspace-state-kIZrdlSg.mjs} +3 -3
  160. package/dist/{workspaces-g2lhdBXF.mjs → workspaces-CmOcceDN.mjs} +1879 -74
  161. package/dist/{worktree-BKuklFh_.mjs → worktree-2dk5edza.mjs} +933 -534
  162. package/dist/worktree-nliAoHxB.mjs +2 -0
  163. package/package.json +7 -7
  164. package/dist/ccache-Bx5TbxwG.mjs +0 -143
  165. package/dist/eas-fallback-FwkeqqGi.mjs +0 -381
  166. package/dist/hosted-ios-D55QhYaD.mjs +0 -15
  167. package/dist/native-run-BfIDFKLH.mjs +0 -275
  168. package/dist/server-expo-wvcj5tiZ.mjs +0 -2
  169. package/dist/settings-write-QjYfSrjF.mjs +0 -360
  170. package/dist/trigger-DzJu208Q.mjs +0 -2
  171. package/dist/web-BFLueSh-.mjs +0 -2
  172. package/dist/worktree-Bm4cb-nU.mjs +0 -2
@@ -1,9 +1,9 @@
1
- import { D as ownership_claim_exports, S as process_identity_exports, m as declareSpawnsOn, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-VFRpu1iA.mjs";
2
- import { M as withDirLock$1, N as withDirLockAsync$1, c as withWorkspaceStateLock, d as writeWorkspaceState, k as workspaceLogsDir$1, l as withWorkspaceStateLockAsync, n as clearWorkspaceStateKeys, r as readWorkspaceState$1 } from "./workspace-state-pUg3_RRA.mjs";
3
- import { U as parseDeviceSlotKey, V as deviceSlotKey, d as getConfigDir, q as validateDeviceSlot } from "./config-BktkY_zC.mjs";
4
- import { a as formatElapsed, i as formatDuration, m as shortHash } from "./command-output-BF5AR2dL.mjs";
5
- import { n as runOperationFileQuiet } from "./operation-exec-CUZifp6Z.mjs";
6
- import { S as resolveBuild } from "./build-cache-DrXNCy3T.mjs";
1
+ import { D as ownership_claim_exports, S as process_identity_exports, m as declareSpawnsOn, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-aULwtNly.mjs";
2
+ import { M as withDirLock$1, N as withDirLockAsync$1, c as withWorkspaceStateLock, d as writeWorkspaceState, k as workspaceLogsDir$1, l as withWorkspaceStateLockAsync, n as clearWorkspaceStateKeys, r as readWorkspaceState$1 } from "./workspace-state-kIZrdlSg.mjs";
3
+ import { U as parseDeviceSlotKey, V as deviceSlotKey, d as getConfigDir, q as validateDeviceSlot } from "./config-Cn94Jc0g.mjs";
4
+ import { a as formatElapsed, i as formatDuration, m as shortHash } from "./command-output-C8R1KIvi.mjs";
5
+ import { n as runOperationFileQuiet } from "./operation-exec-Dp4FuIGR.mjs";
6
+ import { C as resolveBuild } from "./build-cache-CZULpXVl.mjs";
7
7
  import { randomBytes } from "node:crypto";
8
8
  import { closeSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
9
9
  import { homedir } from "node:os";
@@ -1,8 +1,8 @@
1
- import { S as process_identity_exports } from "./exec-VFRpu1iA.mjs";
2
- import { P as formatBytes } from "./config-BktkY_zC.mjs";
3
- import { o as formatLongDuration } from "./command-output-BF5AR2dL.mjs";
4
- import { F as measureDu, I as writeUsageCache, P as canonical, c as listWorkspaceDirs } from "./workspaces-g2lhdBXF.mjs";
5
- import { c as parseAgentDeviceRecord, o as envDir, u as processMatches } from "./activity-Lnb_EoRY.mjs";
1
+ import { S as process_identity_exports } from "./exec-aULwtNly.mjs";
2
+ import { P as formatBytes } from "./config-Cn94Jc0g.mjs";
3
+ import { o as formatLongDuration } from "./command-output-C8R1KIvi.mjs";
4
+ import { bt as measureDu, u as listWorkspaceDirs, xt as writeUsageCache, yt as canonical } from "./workspaces-CmOcceDN.mjs";
5
+ import { c as parseAgentDeviceRecord, o as envDir, u as processMatches } from "./activity-DRMg4_mD.mjs";
6
6
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
7
7
  import { homedir } from "node:os";
8
8
  import { isAbsolute, join, relative, sep } from "node:path";
@@ -1,42 +1,43 @@
1
- import { D as ownership_claim_exports, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
- import { a as recordWorkspaceUseAsync, f as writeWorkspaceStateAsync, g as emulatorLogFile, k as workspaceLogsDir$1, r as readWorkspaceState$1 } from "./workspace-state-pUg3_RRA.mjs";
3
- import { B as deviceSlotFileKey, E as upsertProject, H as deviceSlotPlatforms, O as withConfigLockAsync$1, W as parseDeviceSlotOption, p as getProject, q as validateDeviceSlot, u as getConcurrencyLimits } from "./config-BktkY_zC.mjs";
4
- import { _ as stepTimer, f as refuseNoProject, g as stepClock, i as formatDuration, l as phaseLine } from "./command-output-BF5AR2dL.mjs";
5
- import { K as resolveCacheProviderConfig, M as metroPortSetting, P as metroWarmupUrlSetting, R as projectSettingsContextAsync, U as remoteEasFallbackSetting, X as resolveSettings, Y as resolveProjectSettingsAsync, a as SETTING_SHAPE_REMEDY, g as deviceReclaimIdleMinutesSetting, it as tunnelModeSetting, lt as detectProviders, z as publicUrlSetting } from "./settings-CosW5X-S.mjs";
6
- import { f as projectRegistry, i as findProjectRoot$1, l as projectShortcut, t as NO_PROJECT_REFUSAL, z as writeWorkspaceLaunchAsync } from "./project-BUu6Is4k.mjs";
7
- import { A as listAdbDevices, Dt as configuredAndroidEmulatorApp, I as listInstalledSystemImages, Y as physicalDeviceModel, Z as probeEmulatorSerial, a as androidDeviceAbi, ct as waitForBoot, nt as resolveOwnedAvdSerialAsync, rt as resolvePhysicalDevice } from "./android-DTAcRwBC.mjs";
8
- import { c as pidExists, d as resolveProjectMetro } from "./metro-CjC10t6E.mjs";
9
- import { r as createNdjsonWriter } from "./ndjson-CgE_o3Dl.mjs";
10
- import { An as launchAndroidApp, En as installAndroidApp, G as runFailureRecord, I as NO_BUILD_PROGRESS, J as thrownRunFailureRecord, K as startBuildProgress, Kt as ensureMetroReachable, Q as recordCapacityRefusal, Un as runProcessOperation, Ut as binOnPath, Vn as exitAfterFlush, X as readRunEstimates, Y as createRunRecorder, Yt as remoteAndroidDeps, Zt as resolveRemoteContext, dn as verifyLaunch, er as resolveEasCliBin, et as recordRunStats, hn as DEFAULT_METRO_PORT, jn as launchAndroidReleaseApp, mn as ADB_INSTALL_TIMEOUT_MS, nr as uploadRemote, q as tapBuildLog, qn as checkEasAuth, qt as ensureRemoteBootOwned, t as budgetGate, tr as resolveRemote, tt as statsProjectKey$1, un as verifyAndroidReleaseLaunch, ur as ownedSessionName } from "./budget-k2mZGvvk.mjs";
11
- import { d as runCancellationSignal, f as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-BfIDFKLH.mjs";
12
- import { L as acquireBuildSlot, z as releaseBuildSlot } from "./workspaces-g2lhdBXF.mjs";
13
- import { F as waitForBuild, M as acquireBuildLock, P as releaseBuildLock } from "./activity-Lnb_EoRY.mjs";
14
- import { w as storedAppId } from "./build-cache-DrXNCy3T.mjs";
15
- import { t as CCACHE_NOT_RUN } from "./ccache-Bx5TbxwG.mjs";
16
- import { S as setRemoteLogSink } from "./client-D9CaRks-.mjs";
17
- import { a as parseBuildMachineOption, l as resolveBuildPlacement } from "./selection-BNPBZ6T5.mjs";
18
- import { r as hostedMetroSettings } from "./metro-gateway-B6_PgD0L.mjs";
19
- import { a as writeHostedAndroidAsync, i as writeDevicePlacementAsync, t as readHostedAndroid } from "./ios-state-Cw7-WQf2.mjs";
20
- import { n as prepareHostedAndroid, t as placeHostedAndroid } from "./hosted-android-Bk54ej6n.mjs";
21
- import { n as verifyCollectorOwnership } from "./ownership-BjYvMNX_.mjs";
22
- import { c as startDevServer } from "./start-_BdJ32cZ.mjs";
23
- import { a as acquireRunLease, d as runLease, f as waitFlagConflict, o as leaseExpiryText, u as releaseLeaseOnAbort } from "./device-lease-run-BmvIl7bI.mjs";
24
- import { n as DeviceAdmissionRefusal, r as checkDeviceCapacity } from "./device-capacity-DCSvUF0l.mjs";
25
- import { a as resolveEasDevelopmentBuild, r as isEasBuildFailure } from "./eas-build-Dsj93iM9.mjs";
26
- import { t as followHostedLaunchLogs } from "./hosted-logs-sync-B0pvmOk-.mjs";
27
- import { f as settleFingerprintCheck } from "./prebuild-gmouvmJZ.mjs";
28
- import { n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-Dq3RBcON.mjs";
29
- import { n as devicePlacementRecord } from "./placement-log-DIFPQAXp.mjs";
30
- import { S as pooledAndroidDevice, a as PLATFORM, b as noDeviceDiagnostic, g as dumpApkManifest, h as displayPath, o as androidBuildOptions, p as apkPackage, r as NO_DEVICE, s as androidDevClientScheme } from "./support-BGSCBoib.mjs";
31
- import { t as acquireAndroidArtifact } from "./artifact-BxREhAaV.mjs";
32
- import { a as persistLastBuild, c as androidDeviceSelectorRefusal, i as logPostBuildFailure, n as finishAndroidUpload, o as persistThrownBuild, s as reportAndroidResult, u as resolveAndroidRunPlan } from "./result-7F5hEwQJ.mjs";
33
- import { n as automaticDevicePlacement, r as devicePlacementLine, t as checkEasFallback } from "./eas-fallback-FwkeqqGi.mjs";
34
- import { i as verifyAndroidMetroRun, r as finishAndroidRun } from "./launch-DOp8RjDz.mjs";
35
- import { a as AvdRecoveryError, i as AvdBootError, n as ensureBooted, o as warmMetro, r as ensureOwnedDevice, t as didSetUpDevice } from "./device-BK-zwyd_.mjs";
36
- import { t as selectFromPool } from "./device-pool-Dluix4H3.mjs";
1
+ import { D as ownership_claim_exports, t as getExecutor } from "./exec-aULwtNly.mjs";
2
+ import { a as recordWorkspaceUseAsync, f as writeWorkspaceStateAsync, g as emulatorLogFile, k as workspaceLogsDir$1, r as readWorkspaceState$1 } from "./workspace-state-kIZrdlSg.mjs";
3
+ import { B as deviceSlotFileKey, E as upsertProject, H as deviceSlotPlatforms, O as withConfigLockAsync$1, W as parseDeviceSlotOption, p as getProject, q as validateDeviceSlot, u as getConcurrencyLimits } from "./config-Cn94Jc0g.mjs";
4
+ import { _ as stepTimer, f as refuseNoProject, g as stepClock, i as formatDuration, l as phaseLine } from "./command-output-C8R1KIvi.mjs";
5
+ import { B as publicUrlSetting, F as metroWarmupUrlSetting, J as resolveCacheProviderConfig, N as metroPortSetting, Q as resolveSettings, W as remoteEasFallbackSetting, Z as resolveProjectSettingsAsync, a as SETTING_SHAPE_REMEDY, dt as detectProviders, g as deviceReclaimIdleMinutesSetting, ot as tunnelModeSetting, z as projectSettingsContextAsync } from "./settings-CY5JZlNN.mjs";
6
+ import { f as projectRegistry, i as findProjectRoot$1, l as projectShortcut, t as NO_PROJECT_REFUSAL, z as writeWorkspaceLaunchAsync } from "./project-Sui52ywT.mjs";
7
+ import { A as listAdbDevices, Dt as configuredAndroidEmulatorApp, I as listInstalledSystemImages, Y as physicalDeviceModel, Z as probeEmulatorSerial, a as androidDeviceAbi, ct as waitForBoot, nt as resolveOwnedAvdSerialAsync, rt as resolvePhysicalDevice } from "./android-CsPs-7Mg.mjs";
8
+ import { c as pidExists, d as resolveProjectMetro } from "./metro-BnhXV2Mj.mjs";
9
+ import { i as createNdjsonWriter } from "./ndjson-Dy2W4vRa.mjs";
10
+ import { An as checkEasAuth, At as ensureRemoteBootOwned, En as runProcessOperation, Et as binOnPath, Jt as verifyLaunch, Ln as resolveEasCliBin, Mt as remoteAndroidDeps, Pt as resolveRemoteContext, Qt as DEFAULT_METRO_PORT, Rn as resolveRemote, Zt as ADB_INSTALL_TIMEOUT_MS, c as budgetGate, kt as ensureMetroReachable, ln as installAndroidApp, mn as launchAndroidReleaseApp, pn as launchAndroidApp, qn as ownedSessionName, qt as verifyAndroidReleaseLaunch, t as CCACHE_NOT_RUN, wn as exitAfterFlush, zn as uploadRemote } from "./ccache-Bm_A1xX9.mjs";
11
+ import { $ as tapBuildLog, H as NO_BUILD_PROGRESS, Q as startBuildProgress, St as acquireBuildSlot, Tt as releaseBuildSlot, Z as runFailureRecord, ct as recordRunStats, et as thrownRunFailureRecord, it as readRunEstimates, lt as statsProjectKey$1, ot as recordCapacityRefusal, rt as createRunRecorder } from "./workspaces-CmOcceDN.mjs";
12
+ import { Q as cancelledFailure, at as runCancellation, ot as runCancellationSignal, st as withNativeBuildRun } from "./toolchain-mLA_km-b.mjs";
13
+ import { F as waitForBuild, M as acquireBuildLock, P as releaseBuildLock } from "./activity-DRMg4_mD.mjs";
14
+ import { T as storedAppId } from "./build-cache-CZULpXVl.mjs";
15
+ import { S as setRemoteLogSink } from "./client-YxCer6ab.mjs";
16
+ import { d as resolveBuildPlacement, s as parseBuildMachineOption } from "./selection-CXgM_VK_.mjs";
17
+ import { r as hostedMetroSettings } from "./metro-request-DXyKjVDF.mjs";
18
+ import { a as writeHostedAndroidAsync, i as writeDevicePlacementAsync, t as readHostedAndroid } from "./ios-state-BPHqMDdZ.mjs";
19
+ import { n as prepareHostedAndroid, t as placeHostedAndroid } from "./hosted-android-DlaKLbW0.mjs";
20
+ import { n as verifyCollectorOwnership } from "./ownership-DJCq48IJ.mjs";
21
+ import { i as restoreLightenedDependencies, n as printLightenedFailure } from "./lightened-DFAJgfIk.mjs";
22
+ import { c as startDevServer } from "./start-DYLk6GXn.mjs";
23
+ import { a as acquireRunLease, d as runLease, f as waitFlagConflict, o as leaseExpiryText, u as releaseLeaseOnAbort } from "./device-lease-run-Mtzp4THX.mjs";
24
+ import { n as DeviceAdmissionRefusal, r as checkDeviceCapacity } from "./device-capacity-Cd8lMSn3.mjs";
25
+ import { a as resolveEasDevelopmentBuild, r as isEasBuildFailure } from "./eas-build-Dm6q68QY.mjs";
26
+ import { t as followHostedLaunchLogs } from "./hosted-logs-sync-B0c53W_c.mjs";
27
+ import { f as settleFingerprintCheck } from "./prebuild-k8d_tqOq.mjs";
28
+ import { i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-DG4Rodzj.mjs";
29
+ import { n as devicePlacementRecord } from "./placement-log-Cvhta5ib.mjs";
30
+ import { S as pooledAndroidDevice, a as PLATFORM, b as noDeviceDiagnostic, g as dumpApkManifest, h as displayPath, o as androidBuildOptions, p as apkPackage, r as NO_DEVICE, s as androidDevClientScheme } from "./support-04IhBUTT.mjs";
31
+ import { t as acquireAndroidArtifact } from "./artifact-bFkfD3vf.mjs";
32
+ import { a as persistLastBuild, c as androidDeviceSelectorRefusal, i as logPostBuildFailure, n as finishAndroidUpload, o as persistThrownBuild, s as reportAndroidResult, u as resolveAndroidRunPlan } from "./result-BIcXREyC.mjs";
33
+ import { n as devicePlacementLine, t as automaticDevicePlacement } from "./auto-placement-BVqs8AJi.mjs";
34
+ import { i as verifyAndroidMetroRun, r as finishAndroidRun } from "./launch-DoySmhjz.mjs";
35
+ import { t as checkEasFallback } from "./eas-fallback-DajNpxf-.mjs";
36
+ import { a as AvdRecoveryError, i as AvdBootError, n as ensureBooted, o as warmMetro, r as ensureOwnedDevice, t as didSetUpDevice } from "./device-CgXfbcz5.mjs";
37
+ import { t as selectFromPool } from "./device-pool-eRz6DtCg.mjs";
37
38
  import { t as unsupportedPlan } from "./project-plan-BPwbLwQu.mjs";
38
- import { a as refusePlan, i as printPlan, n as planFlagRefusal } from "./build-plan-DrMMdayj.mjs";
39
- import { basename, join } from "node:path";
39
+ import { a as refusePlan, i as printPlan, n as planFlagRefusal } from "./build-plan-CxoYfxsc.mjs";
40
+ import { join } from "node:path";
40
41
  import { workspaceId } from "@stim-cli/core";
41
42
  import { hostedAndroidStatus, parseMachine } from "@stim-cli/core/state";
42
43
  import chalk from "chalk";
@@ -86,7 +87,7 @@ async function connectAndroidHosting({ root, slot, machine, release, appMode = r
86
87
  } };
87
88
  }
88
89
  }
89
- async function selectAndroidPlacement({ target: selected, automatic = automaticDevicePlacement, checkBudget = budgetGate, note, phase, log, fromFlag, noWait, buildMachine, localSelectors, eas, ...args }) {
90
+ async function selectAndroidPlacement({ target: selected, automatic = automaticDevicePlacement, checkBudget = budgetGate, note, phase, log, fromFlag, noWait, waitMs, signal, buildMachine, localSelectors, eas, ...args }) {
90
91
  const appMode = args.appMode ?? (args.release ? "release" : "development");
91
92
  const selectors = selected.kind === "hosted" ? {
92
93
  ...selected.systemImage ? { systemImage: selected.systemImage } : {},
@@ -119,15 +120,20 @@ async function selectAndroidPlacement({ target: selected, automatic = automaticD
119
120
  root: args.root,
120
121
  slot: args.slot,
121
122
  platform: "android",
123
+ ...selected.placement ? { placement: selected.placement } : {},
122
124
  ...appMode === "process" ? { appMode } : {},
123
125
  selectors,
124
126
  buildMachine,
125
127
  noWait,
128
+ ...waitMs === void 0 ? {} : { waitMs },
129
+ onWait: (line) => phase("placement:", line),
130
+ signal,
126
131
  ...eas ? { eas } : {}
127
132
  });
128
133
  phase("placement:", devicePlacementLine(placed.placement, placed.skipped));
129
134
  log?.(devicePlacementRecord({
130
135
  platform: "android",
136
+ selected: selected.placement,
131
137
  fromFlag,
132
138
  easFallback: Boolean(eas),
133
139
  placed
@@ -173,6 +179,11 @@ async function selectAndroidPlacement({ target: selected, automatic = automaticD
173
179
  devicePlacement: placed.placement
174
180
  };
175
181
  } catch (error) {
182
+ if (signal?.aborted) return { failure: {
183
+ code: "STIM_CANCELLED",
184
+ message: "The run was cancelled while it waited for a remote machine.",
185
+ remedy: "Run the command again when you want the app on a device."
186
+ } };
176
187
  return { failure: {
177
188
  code: error.code ?? "STIM_HOSTING_REFUSED",
178
189
  message: error.message,
@@ -182,11 +193,12 @@ async function selectAndroidPlacement({ target: selected, automatic = automaticD
182
193
  }
183
194
  //#endregion
184
195
  //#region src/commands/android/hosted.ts
185
- async function finishHostedAndroidRun({ target, artifact, root, slot = "default", release, appMode = release ? "release" : "development", isExpo, metroPort, logsDir, selectors, place, writePlacement, verifyLaunch: verify, followLogs, writeLaunch, readApkPackage, resolveDevClientScheme, now, started, startedAt, fail, phase, enterPhase, enterActivity, out, recordBuild, ...report }) {
196
+ async function finishHostedAndroidRun({ target, operation, artifact, root, slot = "default", release, appMode = release ? "release" : "development", isExpo, metroPort, logsDir, selectors, place, writePlacement, verifyLaunch: verify, followLogs, writeLaunch, readApkPackage, resolveDevClientScheme, now, started, startedAt, fail, phase, enterPhase, enterActivity, out, recordBuild, ...report }) {
186
197
  const packageName = artifact.androidPackage ?? await readApkPackage(artifact.apkPath);
187
198
  if (!artifact.apkPath || !packageName) return fail("STIM_INSTALL_FAILED", "The built APK has no package identity.");
188
199
  const devClientScheme = appMode === "development" && isExpo ? await resolveDevClientScheme(root, artifact.apkPath) ?? void 0 : void 0;
189
200
  const launchedAt = now();
201
+ let marked = false;
190
202
  try {
191
203
  const run = await place(target, {
192
204
  root,
@@ -199,7 +211,25 @@ async function finishHostedAndroidRun({ target, artifact, root, slot = "default"
199
211
  metroPort,
200
212
  selectors,
201
213
  ...appMode === "development" && isExpo ? { devClientScheme } : {},
202
- reserved: (placement) => writePlacement(root, slot, placement),
214
+ reserved: (placement) => {
215
+ if (placement.device && !marked) {
216
+ marked = true;
217
+ report.writer.write({
218
+ src: "build",
219
+ level: "info",
220
+ marker: true,
221
+ event: "launch_attempt",
222
+ ts: now(),
223
+ platform: "android",
224
+ appId: packageName,
225
+ deviceId: placement.session,
226
+ remote: true,
227
+ host: target.host.machine,
228
+ msg: `launching ${packageName} on ${target.host.machine}`
229
+ });
230
+ }
231
+ return writePlacement(root, slot, placement);
232
+ },
203
233
  note: out,
204
234
  enterPhase
205
235
  });
@@ -214,11 +244,13 @@ async function finishHostedAndroidRun({ target, artifact, root, slot = "default"
214
244
  }, slot);
215
245
  let launched = run.launched;
216
246
  let launchWarning;
247
+ let unattributed = false;
217
248
  if (appMode === "development") {
218
249
  const hostedLogs = followLogs(root, slot, "android", launchedAt);
219
250
  let verification;
220
251
  try {
221
252
  verification = await verifyAndroidMetroRun({
253
+ operation,
222
254
  root,
223
255
  slot,
224
256
  remoteDevice: false,
@@ -244,7 +276,17 @@ async function finishHostedAndroidRun({ target, artifact, root, slot = "default"
244
276
  if (verification.state === "fatal") return fail("STIM_LAUNCH_FAILED", "The app failed its launch readiness check.", `Read the launch error above or run \`stim logs --errors\`. The full timeline is in ${logsDir}.`, { lastBuildStatus: true });
245
277
  launched = verification.state === true ? true : verification.state === "bundling" ? "bundling" : "unverified";
246
278
  launchWarning = verification.warning;
279
+ unattributed = verification.unattributed ?? false;
247
280
  }
281
+ report.writer.write(launchOutcomeRecord({
282
+ launchState: launched,
283
+ release,
284
+ process: appMode === "process",
285
+ bundleId: packageName,
286
+ configuration: report.variant,
287
+ metroPort,
288
+ unattributed
289
+ }));
248
290
  if (launched === "unverified") out(`Launch on ${target.host.machine} is unverified; check the hosted app, then retry stim android --remote ${target.host.machine}.`);
249
291
  const host = hostedAndroidStatus(run.placement);
250
292
  report.record.deviceName = host.device?.name ?? null;
@@ -337,8 +379,8 @@ function androidCommand(program) {
337
379
  registerAndroid(program);
338
380
  }
339
381
  function registerAndroid(program) {
340
- program.command("android").description("Build (or install from the shared cache), install and launch this workspace's Android app on its owned emulator. React Native and Expo Debug runs start the dev server when it is not running.").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", parseDeviceSlotOption).option("--remote-build <value>", "Build on auto, local, or one named machine; a name refuses without fallback", parseBuildMachineOption).option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--plan", "Predict the next build without building, booting or installing: resolve the fingerprint, check the local then remote cache, and print the expected cache result and duration. Writes no Stim state.").option("--no-metro-check", "Skip the reserved-port Metro health check and do not start it (the app will load no bundle unless something else serves it)").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--variant <name>", "Gradle variant to assemble and install (e.g. productionDebug on a flavored project); overrides the android.variant setting. A variant ending in Release embeds the JS bundle and skips Metro entirely. Default: debug").option("--system-image <id>", "Android system image to create this workspace's owned AVD from, as the sdkmanager package id (e.g. \"system-images;android-36;google_apis;arm64-v8a\"). Overrides the android.systemImage setting for this invocation. An unknown id refuses with STIM_BAD_ARG and prints the installed images.").option("--device-profile <id>", "Hardware profile to create this workspace's owned AVD with, as an `avdmanager list device -c` id (e.g. \"pixel_fold\", \"pixel_tablet\"). Overrides the android.deviceProfile setting for this invocation. An unknown id refuses with STIM_BAD_ARG and prints the available ids.").option("--device [serial]", "Install and launch on a connected physical device instead of this workspace's owned emulator. With no serial, the first connected device this workspace can lease is used. Stim never creates, boots, or deletes a physical device.").option("--remote <target>", "Run on eas, proxy, or a named approved Mac from remote.machines; auto places on an approved Mac when this machine is full or busy; local runs here, whatever android.remote says", (value) => {
341
- if (!parseMachine(value)) throw new InvalidArgumentError("expected eas, proxy, auto, local, or a tailnet machine name");
382
+ program.command("android").description("Build (or install from the shared cache), install and launch this workspace's Android app on its owned emulator. React Native and Expo Debug runs start the dev server when it is not running.").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", parseDeviceSlotOption).option("--remote-build <value>", "Build on local, auto, remote (remote machines first), remote-only (never here), or one named machine; a name refuses without fallback", parseBuildMachineOption).option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--plan", "Predict the next build without building, booting or installing: resolve the fingerprint, check the local then remote cache, and print the expected cache result and duration. Writes no Stim state.").option("--no-metro-check", "Skip the reserved-port Metro health check and do not start it (the app will load no bundle unless something else serves it)").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--variant <name>", "Gradle variant to assemble and install (e.g. productionDebug on a flavored project); overrides the android.variant setting. A variant ending in Release embeds the JS bundle and skips Metro entirely. Default: debug").option("--system-image <id>", "Android system image to create this workspace's owned AVD from, as the sdkmanager package id (e.g. \"system-images;android-36;google_apis;arm64-v8a\"). Overrides the android.systemImage setting for this invocation. An unknown id refuses with STIM_BAD_ARG and prints the installed images.").option("--device-profile <id>", "Hardware profile to create this workspace's owned AVD with, as an `avdmanager list device -c` id (e.g. \"pixel_fold\", \"pixel_tablet\"). Overrides the android.deviceProfile setting for this invocation. An unknown id refuses with STIM_BAD_ARG and prints the available ids.").option("--device [serial]", "Install and launch on a connected physical device instead of this workspace's owned emulator. With no serial, the first connected device this workspace can lease is used. Stim never creates, boots, or deletes a physical device.").option("--remote <target>", "Run on eas, proxy, or a named approved Mac from remote.machines; auto places on an approved Mac when this machine is full or busy; remote tries remote.machines in order first and runs here only when none takes it; remote-only never runs here; local runs here, whatever android.remote says", (value) => {
383
+ if (!parseMachine(value)) throw new InvalidArgumentError("expected eas, proxy, local, auto, remote, remote-only, or a tailnet machine name");
342
384
  return value;
343
385
  }).option("--wait <seconds>", "How long to wait for another workspace to release the device it leases, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once). Without --device, wait for an owned-device slot (default 600 seconds; --no-wait refuses immediately).").option("--no-wait", "Install on a device another workspace leases instead of waiting: this run takes no lease and, when both workspaces build the same app id, the install terminates the holder's running app. Without --device, refuse a full device cap or existing slot queue immediately.").action(async (opts) => {
344
386
  if (opts.plan) return planAndroid(opts);
@@ -361,6 +403,14 @@ function runAndroidOperation(context, root, opts = {}) {
361
403
  platform: PLATFORM,
362
404
  slot: opts.slot ?? "default"
363
405
  }, async (claim) => {
406
+ const lightened = await restoreLightenedDependencies(root, context);
407
+ if (lightened) {
408
+ printLightenedFailure(context, lightened, Boolean(opts.json));
409
+ return {
410
+ ok: false,
411
+ error: lightened
412
+ };
413
+ }
364
414
  await recordWorkspaceUseAsync(root, /* @__PURE__ */ new Date(), context.env, context.cwd, context.signal);
365
415
  const progress = startBuildProgress({
366
416
  root,
@@ -628,6 +678,8 @@ async function runAndroid(options = {}) {
628
678
  status: "failed",
629
679
  errorCode: code,
630
680
  diagnostics: rawDiagnostics,
681
+ message,
682
+ remedy,
631
683
  out
632
684
  });
633
685
  logPostBuildFailure(artifactAcquired, writer, runFailureRecord({
@@ -733,9 +785,9 @@ async function runAndroid(options = {}) {
733
785
  automatic: plan.target.kind === "hosted" && plan.target.machine === "auto",
734
786
  signal: runCancellationSignal(context),
735
787
  waitMs: plan.deviceSlotWaitMs,
736
- displayName: basename(root),
737
788
  reclaimIdleMinutes: deviceReclaimIdleMinutesSetting(settings),
738
789
  waitingFor: (info) => progress.waitingFor(info, "device-slot"),
790
+ onBootStart: () => progress.bootStarted(),
739
791
  onWait: (ms) => {
740
792
  stats.addDeviceSlotWaitMs(ms);
741
793
  if (record.devicePlacement?.decision === "local" && ms > 0) record.devicePlacement.decision = "waited-locally";
@@ -754,6 +806,8 @@ async function runAndroid(options = {}) {
754
806
  appMode,
755
807
  metroCheck,
756
808
  noWait: plan.deviceSlotWaitMs === 0,
809
+ waitMs: plan.deviceSlotWaitMs,
810
+ signal: settingsSignal,
757
811
  buildMachine: options.buildMachine,
758
812
  read: options.readHostedAndroid,
759
813
  resolveSerial: resolveAvdSerial,
@@ -802,7 +856,7 @@ async function runAndroid(options = {}) {
802
856
  const remoteBackend = target.kind === "remote" ? target.backend : null;
803
857
  if (hostedTarget) {
804
858
  if (settings.androidEmulatorApp !== void 0) phase("device", "androidEmulatorApp is ignored on a hosting Mac; the emulator boots headless.");
805
- if (appMode === "development" && (publicUrlSetting(settings) || tunnelModeSetting(settings))) phase("metro", "metro.publicUrl and metro.tunnel are ignored on a hosting Mac; Metro uses the private tailnet bridge.");
859
+ if (appMode === "development" && (publicUrlSetting(settings) || tunnelModeSetting(settings))) phase("metro", "metro.publicUrl and metro.tunnel are ignored on a hosting Mac; Metro uses links this machine opens to the host.");
806
860
  }
807
861
  reclaimed = budget.reclaimed;
808
862
  if (budget.refusal) return fail(budget.refusal.code, budget.refusal.message, budget.refusal.remedy);
@@ -1068,6 +1122,7 @@ async function runAndroid(options = {}) {
1068
1122
  }
1069
1123
  record.avdName = device.avdName ?? null;
1070
1124
  record.deviceName = device.deviceName ?? device.avdName ?? null;
1125
+ record.deviceSerial = device.serial;
1071
1126
  record.systemImage = device.systemImage;
1072
1127
  record.deviceProfile = device.deviceProfile;
1073
1128
  let preparedArtifact;
@@ -1153,6 +1208,7 @@ async function runAndroid(options = {}) {
1153
1208
  artifactAcquired = true;
1154
1209
  if (runCancellation(context)) return fail("STIM_CANCELLED", "before install");
1155
1210
  if (hostedTarget) return finishHostedAndroidRun({
1211
+ operation: context,
1156
1212
  target: hostedTarget,
1157
1213
  artifact,
1158
1214
  root,
@@ -1,10 +1,10 @@
1
- import { D as ownership_claim_exports, S as process_identity_exports, l as WorkspaceProcessCleanupError, m as declareSpawnsOn, o as cancellableSleep, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-VFRpu1iA.mjs";
2
- import { M as withDirLock$1, N as withDirLockAsync$1 } from "./workspace-state-pUg3_RRA.mjs";
3
- import { C as saveConfig, D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, K as removeSlotDevice, O as withConfigLockAsync$1, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as assignSlotDevice } from "./config-BktkY_zC.mjs";
4
- import { n as runOperationFileQuiet, t as runOperationFile } from "./operation-exec-CUZifp6Z.mjs";
5
- import { c as androidDataPartitionSizeBytes } from "./settings-CosW5X-S.mjs";
6
- import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-6Dqp-gjX.mjs";
7
- import { c as pidExists, p as signalProcessTreeAsync } from "./metro-CjC10t6E.mjs";
1
+ import { D as ownership_claim_exports, S as process_identity_exports, l as WorkspaceProcessCleanupError, m as declareSpawnsOn, o as cancellableSleep, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-aULwtNly.mjs";
2
+ import { M as withDirLock$1, N as withDirLockAsync$1 } from "./workspace-state-kIZrdlSg.mjs";
3
+ import { C as saveConfig, D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, K as removeSlotDevice, O as withConfigLockAsync$1, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as assignSlotDevice } from "./config-Cn94Jc0g.mjs";
4
+ import { n as runOperationFileQuiet, t as runOperationFile } from "./operation-exec-Dp4FuIGR.mjs";
5
+ import { c as androidDataPartitionSizeBytes } from "./settings-CY5JZlNN.mjs";
6
+ import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-CbWo21kb.mjs";
7
+ import { c as pidExists, p as signalProcessTreeAsync } from "./metro-BnhXV2Mj.mjs";
8
8
  import { renameSync, rmSync, writeFileSync } from "node:fs";
9
9
  import { isDeepStrictEqual } from "node:util";
10
10
  import { join } from "node:path";
@@ -1421,16 +1421,25 @@ function listAvdEmulatorProcesses(avdName, platform) {
1421
1421
  ], { timeoutMs: 5e3 });
1422
1422
  return out === null ? null : parseAvdEmulatorProcesses(out, avdName);
1423
1423
  }
1424
+ const PROCESS_TABLE_READ_TIMEOUTS_MS = [5e3, 15e3];
1425
+ async function readProcessTableAsync(operation, args, options = {}) {
1426
+ for (const timeoutMs of PROCESS_TABLE_READ_TIMEOUTS_MS) {
1427
+ const out = await runOperationFileQuiet(operation, getExecutor(), "ps", args, {
1428
+ timeoutMs,
1429
+ killSignal: "SIGKILL",
1430
+ ...options
1431
+ });
1432
+ if (out !== null) return out;
1433
+ }
1434
+ return null;
1435
+ }
1424
1436
  async function listAvdEmulatorProcessesAsync(avdName, platform, operation) {
1425
1437
  if (platform === "win32") return [];
1426
- const out = await runOperationFileQuiet(operation, getExecutor(), "ps", [
1438
+ const out = await readProcessTableAsync(operation, [
1427
1439
  "-axww",
1428
1440
  "-o",
1429
1441
  "pid=,command="
1430
- ], {
1431
- timeoutMs: 5e3,
1432
- killSignal: "SIGKILL"
1433
- });
1442
+ ]);
1434
1443
  return out === null ? null : parseAvdEmulatorProcesses(out, avdName);
1435
1444
  }
1436
1445
  function scanAvdEmulatorProcesses(avdName, platform, listProcesses) {
@@ -1463,16 +1472,12 @@ async function assertOwnedAvdStoppedAsync(avdName, operation, resolveDirectory =
1463
1472
  if (processes === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
1464
1473
  const live = new Set(processes);
1465
1474
  if (processId !== null && pidExists(processId)) {
1466
- const stat = process.platform === "win32" ? null : await runOperationFileQuiet(operation, getExecutor(), "ps", [
1475
+ const stat = process.platform === "win32" ? null : await readProcessTableAsync(operation, [
1467
1476
  "-o",
1468
1477
  "stat=",
1469
1478
  "-p",
1470
1479
  String(processId)
1471
- ], {
1472
- timeoutMs: 5e3,
1473
- killSignal: "SIGKILL",
1474
- cwd: operation?.cwd
1475
- });
1480
+ ], { cwd: operation?.cwd });
1476
1481
  if (stat === null || !stat.trim().startsWith("Z")) live.add(processId);
1477
1482
  }
1478
1483
  if (live.size) throw new Error(`Owned AVD ${avdName} still has a live emulator process (${[...live].join(", ")}).`);
@@ -1,5 +1,5 @@
1
- import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
- import { u as androidToolCwd } from "./android-DTAcRwBC.mjs";
1
+ import { t as getExecutor } from "./exec-aULwtNly.mjs";
2
+ import { u as androidToolCwd } from "./android-CsPs-7Mg.mjs";
3
3
  //#region src/collector/android.ts
4
4
  const LEVEL_BY_LETTER = {
5
5
  V: "debug",
@@ -111,10 +111,19 @@ function logcatArgs(serial, pid) {
111
111
  "time,epoch"
112
112
  ];
113
113
  }
114
- function androidClockOffset(serial, { exec = getExecutor(), now = Date.now } = {}) {
114
+ function killOnAbort(signal) {
115
+ if (!signal) return {};
116
+ return { onSpawn(child) {
117
+ const kill = () => child.kill("SIGKILL");
118
+ signal.addEventListener("abort", kill, { once: true });
119
+ child.once("close", () => signal.removeEventListener("abort", kill));
120
+ if (signal.aborted) kill();
121
+ } };
122
+ }
123
+ async function androidClockOffset(serial, { exec = getExecutor(), now = Date.now, signal } = {}) {
115
124
  const before = now();
116
125
  try {
117
- const output = exec.runFile("adb", [
126
+ const output = (await exec.runFileAsync("adb", [
118
127
  "-s",
119
128
  serial,
120
129
  "shell",
@@ -122,8 +131,9 @@ function androidClockOffset(serial, { exec = getExecutor(), now = Date.now } = {
122
131
  "+%s%3N"
123
132
  ], {
124
133
  timeoutMs: 1e3,
125
- cwd: androidToolCwd()
126
- }).trim();
134
+ cwd: androidToolCwd(),
135
+ ...killOnAbort(signal)
136
+ })).trim();
127
137
  const after = now();
128
138
  if (!/^\d{13}$/.test(output) || after < before || after - before > 1e3) return null;
129
139
  return Math.round((before + after) / 2) - Number(output);
@@ -136,25 +146,31 @@ function parsePidof(text) {
136
146
  const pid = Number(first);
137
147
  return Number.isInteger(pid) && pid > 0 ? pid : null;
138
148
  }
139
- function resolveAppPid(serial, packageName, { exec = null } = {}) {
149
+ async function resolveAppPid(serial, packageName, { exec = null, signal } = {}) {
140
150
  const e = exec || getExecutor();
141
151
  try {
142
- return parsePidof(e.runFile("adb", [
152
+ return parsePidof(await e.runFileAsync("adb", [
143
153
  "-s",
144
154
  serial,
145
155
  "shell",
146
156
  "pidof",
147
157
  "-s",
148
158
  packageName
149
- ], { timeoutMs: 1e4 }));
159
+ ], {
160
+ timeoutMs: 1e4,
161
+ ...killOnAbort(signal)
162
+ }));
150
163
  } catch {
151
164
  return null;
152
165
  }
153
166
  }
154
- async function waitForAppPid({ serial, packageName, timeoutMs = 3e4, pollMs = 500, exec = null, now = Date.now, sleep = defaultSleep }) {
167
+ async function waitForAppPid({ serial, packageName, timeoutMs = 3e4, pollMs = 500, exec = null, signal, now = Date.now, sleep = defaultSleep }) {
155
168
  const deadline = now() + timeoutMs;
156
169
  for (;;) {
157
- const pid = resolveAppPid(serial, packageName, { exec });
170
+ const pid = await resolveAppPid(serial, packageName, {
171
+ exec,
172
+ signal
173
+ });
158
174
  if (pid) return {
159
175
  ok: true,
160
176
  pid
@@ -184,7 +200,7 @@ function pidWatchInterval() {
184
200
  const override = Number(process.env.STIM_PID_WATCH_MS);
185
201
  return Number.isFinite(override) && override > 0 ? override : PID_WATCH_MS;
186
202
  }
187
- function watchAppPid({ serial, packageName, pid, intervalMs = null, exec = null, onChange, resolve = resolveAppPid, setTimer = setTimeout, clearTimer = clearTimeout }) {
203
+ function watchAppPid({ serial, packageName, pid, intervalMs = null, exec = null, signal, onChange, resolve = resolveAppPid, setTimer = setTimeout, clearTimer = clearTimeout }) {
188
204
  const every = intervalMs ?? pidWatchInterval();
189
205
  let current = pid;
190
206
  let stopped = false;
@@ -194,7 +210,10 @@ function watchAppPid({ serial, packageName, pid, intervalMs = null, exec = null,
194
210
  if (stopped) return;
195
211
  let next = null;
196
212
  try {
197
- next = resolve(serial, packageName, { exec });
213
+ next = await resolve(serial, packageName, {
214
+ exec,
215
+ signal
216
+ });
198
217
  } catch {}
199
218
  if (next && next !== current) {
200
219
  current = next;
@@ -211,9 +230,12 @@ function watchAppPid({ serial, packageName, pid, intervalMs = null, exec = null,
211
230
  if (timer) clearTimer(timer);
212
231
  timer = null;
213
232
  },
214
- probe() {
233
+ async probe() {
215
234
  try {
216
- return resolve(serial, packageName, { exec });
235
+ return await resolve(serial, packageName, {
236
+ exec,
237
+ signal
238
+ });
217
239
  } catch {
218
240
  return null;
219
241
  }
@@ -1,6 +1,6 @@
1
- import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-BF5AR2dL.mjs";
2
- import { E as resolveVariant, T as resolveSystemImage, _ as findAapt, b as noDeviceDiagnostic, d as androidVariantSetting, f as apkDevClientFacts, g as dumpApkManifest, h as displayPath, i as NO_FINGERPRINT, p as apkPackage, r as NO_DEVICE, s as androidDevClientScheme, u as androidSystemImageSetting, x as parseXmltree, y as isReleaseVariant } from "./support-BGSCBoib.mjs";
3
- import { r as lastBuildRecord, t as androidFacts } from "./result-7F5hEwQJ.mjs";
4
- import { i as runAndroidOperation, n as registerAndroid, r as runAndroid, t as androidCommand } from "./android-CiNQw3kq.mjs";
5
- import { a as collectorLogFile, o as killPreviousCollector, s as startCollector } from "./launch-DOp8RjDz.mjs";
1
+ import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-C8R1KIvi.mjs";
2
+ import { E as resolveVariant, T as resolveSystemImage, _ as findAapt, b as noDeviceDiagnostic, d as androidVariantSetting, f as apkDevClientFacts, g as dumpApkManifest, h as displayPath, i as NO_FINGERPRINT, p as apkPackage, r as NO_DEVICE, s as androidDevClientScheme, u as androidSystemImageSetting, x as parseXmltree, y as isReleaseVariant } from "./support-04IhBUTT.mjs";
3
+ import { r as lastBuildRecord, t as androidFacts } from "./result-BIcXREyC.mjs";
4
+ import { i as runAndroidOperation, n as registerAndroid, r as runAndroid, t as androidCommand } from "./android-CHmSU4B4.mjs";
5
+ import { a as collectorLogFile, o as killPreviousCollector, s as startCollector } from "./launch-DoySmhjz.mjs";
6
6
  export { NO_DEVICE, NO_FINGERPRINT, androidDevClientScheme, androidFacts, androidSystemImageSetting, androidVariantSetting, apkDevClientFacts, apkPackage, collectorLogFile, androidCommand as default, displayPath, dumpApkManifest, findAapt, formatDuration, isReleaseVariant, killPreviousCollector, lastBuildRecord, noDeviceDiagnostic, parseXmltree, phaseLine, registerAndroid, resolveSystemImage, resolveVariant, runAndroid, runAndroidOperation, shortHash, startCollector };
@@ -1,7 +1,7 @@
1
- import { M as withDirLock$1, _ as ensureWorkspaceStorage } from "./workspace-state-pUg3_RRA.mjs";
2
- import { d as getConfigDir } from "./config-BktkY_zC.mjs";
3
- import { m as defaultAndroidLayout } from "./settings-CosW5X-S.mjs";
4
- import { r as register } from "./cache-manifest-BEZ9Bpl1.mjs";
1
+ import { M as withDirLock$1, _ as ensureWorkspaceStorage } from "./workspace-state-kIZrdlSg.mjs";
2
+ import { d as getConfigDir } from "./config-Cn94Jc0g.mjs";
3
+ import { m as defaultAndroidLayout } from "./settings-CY5JZlNN.mjs";
4
+ import { r as register } from "./cache-manifest-DEjqGGat.mjs";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  import { accessSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
7
7
  import { join } from "node:path";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
+ import { t as getExecutor } from "./exec-aULwtNly.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
5
5
  import { join } from "node:path";
package/dist/api.d.mts CHANGED
@@ -19,7 +19,7 @@ interface ReleasedLease {
19
19
  }
20
20
  //#endregion
21
21
  //#region src/commands/gc/results.d.ts
22
- type GcResultKind = "archive" | "device" | "parkedDevice" | "parkedHostedDevice" | "idleDevice" | "deviceRecord" | "workspaceOutputs" | "recording" | "workspaceDirectory" | "project" | "buildLock" | "buildSlot" | "deviceLease" | "easSession" | "worktree" | "cache" | "statusCache" | "tempLeftover" | "trash" | "watchmanRoot" | "watchman" | "gradleDaemon" | "gradleVersion" | "kotlinDaemon" | "devServer" | "workspaceLogs" | "ledgerEntry" | "easLedgerEntry";
22
+ type GcResultKind = "archive" | "device" | "parkedDevice" | "parkedHostedDevice" | "idleDevice" | "deviceRecord" | "workspaceOutputs" | "worktreeDependencies" | "recording" | "workspaceDirectory" | "project" | "buildLock" | "buildSlot" | "deviceLease" | "easSession" | "worktree" | "cache" | "statusCache" | "tempLeftover" | "trash" | "watchmanRoot" | "watchman" | "gradleDaemon" | "gradleVersion" | "kotlinDaemon" | "devServer" | "workspaceLogs" | "ledgerEntry" | "easLedgerEntry";
23
23
  type GcResultStatus = "done" | "kept" | "failed";
24
24
  interface GcResult {
25
25
  kind: GcResultKind;
@@ -259,8 +259,12 @@ interface DoctorReport {
259
259
  maintenance: ReturnType<typeof maintenanceStatus> & {
260
260
  logPath: string;
261
261
  };
262
- remoteMachines: BuildMachinesInspection["machines"];
263
- deviceHosts: Awaited<ReturnType<typeof inspectDeviceHostMachines>>["machines"];
262
+ remoteMachines: Array<BuildMachinesInspection["machines"][number] & {
263
+ priority?: number;
264
+ }>;
265
+ deviceHosts: Array<Awaited<ReturnType<typeof inspectDeviceHostMachines>>["machines"][number] & {
266
+ priority?: number;
267
+ }>;
264
268
  toolchain: ToolchainReport | null;
265
269
  findings: Finding[];
266
270
  }
@@ -432,7 +436,7 @@ interface GradleVersionSweep {
432
436
  }
433
437
  //#endregion
434
438
  //#region src/commands/gc/workspaces.d.ts
435
- type WorkspaceKeptCode = "unresolved" | "in-use" | "last-use-unknown" | "recently-used";
439
+ type WorkspaceKeptCode = "unresolved" | "locked" | "lock-unknown" | "in-use" | "last-use-unknown" | "recently-used";
436
440
  //#endregion
437
441
  //#region src/commands/gc/logs.d.ts
438
442
  type WorkspaceLogsKeptCode = "unresolved" | "in-use" | "collector";
@@ -684,6 +688,11 @@ interface GcJsonSections {
684
688
  reason: WorkspaceLogsKeptCode | null;
685
689
  detail: string | null;
686
690
  }[];
691
+ worktreeDependencies: {
692
+ path: string;
693
+ willDelete: boolean;
694
+ detail: string | null;
695
+ }[];
687
696
  recordings: {
688
697
  dir: string;
689
698
  projectRoot: string | null;
@@ -697,6 +706,7 @@ interface GcJsonSections {
697
706
  workspaceBuildOutputs: {
698
707
  dir: string;
699
708
  projectRoot: string | null;
709
+ inTreeDirs: string[];
700
710
  bytes: number | null;
701
711
  idleDays: number | null;
702
712
  willClear: boolean;