stim 1.20.1 → 1.20.2

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 (157) hide show
  1. package/README.md +6 -3
  2. package/dist/{activity-BaMpUQ4-.mjs → activity-BSV745Kz.mjs} +4 -4
  3. package/dist/{agent-device-usage-output-VPaOgGaF.mjs → agent-device-usage-output-Dzgv6lgR.mjs} +5 -6
  4. package/dist/{android-CLbBJ2ve.mjs → android-DCKZrNvV.mjs} +37 -38
  5. package/dist/{android-eXfIjKJr.mjs → android-Dlzxshgp.mjs} +5 -5
  6. package/dist/{android-CZh6ElG5.mjs → android-HqP1_vB_.mjs} +3 -3
  7. package/dist/{android-DE8-JfGW.mjs → android-Mz_Inn3w.mjs} +10 -10
  8. package/dist/{android-cas-BFpS84v2.mjs → android-cas-Bl-cLJBk.mjs} +4 -4
  9. package/dist/android-cas-compiler.mjs +1 -1
  10. package/dist/{api-zuX3ynYN.mjs → api-qvOzWyfO.mjs} +1 -1
  11. package/dist/api-run.mjs +19 -21
  12. package/dist/api.mjs +1 -1
  13. package/dist/{app-install-Cg9YJy3x.mjs → app-install-BIKtMfPq.mjs} +71 -48
  14. package/dist/{artifact-DXk_Fle_.mjs → artifact-D3czlUvT.mjs} +13 -13
  15. package/dist/{artifact-Ctb2jpw6.mjs → artifact-HSwkIWEQ.mjs} +12 -12
  16. package/dist/{browser-web-xQWC2RWl.mjs → browser-web-CA-F1GQo.mjs} +18 -18
  17. package/dist/{budget-RFbwFpG5.mjs → budget-f7516Zk0.mjs} +23 -26
  18. package/dist/{build-COBA1tBc.mjs → build-DYDbfkk5.mjs} +28 -33
  19. package/dist/{build-plan-CRjAA6Qi.mjs → build-plan-B7SZsc2N.mjs} +17 -17
  20. package/dist/{cache-manifest-qA3dT2x2.mjs → cache-manifest-XH-fvDUj.mjs} +10 -5
  21. package/dist/cache-manifest.mjs +1 -1
  22. package/dist/cancellation-C_22VQTH.mjs +24 -0
  23. package/dist/{ccache-CtbqWxIC.mjs → ccache-zdKiYQ3E.mjs} +7 -7
  24. package/dist/{chrome-Dp2lMLBe.mjs → chrome-BnzZMqsR.mjs} +1 -1
  25. package/dist/{cli-sGqlPu1n.mjs → cli-CLP3diBm.mjs} +20 -20
  26. package/dist/cli.mjs +1 -1
  27. package/dist/{client-zqjFd79D.mjs → client-qQAaXSUs.mjs} +21 -29
  28. package/dist/collector-run.d.mts +7 -6
  29. package/dist/collector-run.mjs +6 -7
  30. package/dist/{command-output-CPDq_90S.mjs → command-output-BTy8hZ0F.mjs} +1 -1
  31. package/dist/{config-D0LhTY3S.mjs → config-BYDxlMY3.mjs} +43 -5
  32. package/dist/{created-devices-CXBMtoj5.mjs → created-devices-Dzd5C2LF.mjs} +2 -2
  33. package/dist/{dependency-state-B2m8eqsS.mjs → dependency-state-DG0p31-y.mjs} +2 -2
  34. package/dist/{detached-entry-BXq4fIl-.mjs → detached-entry-B9C_zeQC.mjs} +1 -1
  35. package/dist/{dev-client-BqYjMIaC.mjs → dev-client-DAWVIGBu.mjs} +2 -2
  36. package/dist/{device-D4DqjSZZ.mjs → device-BECOiufl.mjs} +13 -14
  37. package/dist/{device-BgNj-qVj.mjs → device-DuiPJQSn.mjs} +8 -8
  38. package/dist/{device-capacity-DrwHwR97.mjs → device-capacity-CBUAcRyQ.mjs} +10 -11
  39. package/dist/device-host-worker.mjs +16 -17
  40. package/dist/{device-ios-DE8KJd3b.mjs → device-ios-COSi6oS1.mjs} +12 -15
  41. package/dist/{device-lease-C309csaB.mjs → device-lease-BX1sJQ2E.mjs} +12 -16
  42. package/dist/{device-lease-run-Baelt3nc.mjs → device-lease-run-Cw2M4z51.mjs} +4 -4
  43. package/dist/{device-pool-DtK9S6AD.mjs → device-pool-Bf-pOhSw.mjs} +3 -3
  44. package/dist/{device-remote-DjsNw8DD.mjs → device-remote-xRT0Vmo9.mjs} +14 -14
  45. package/dist/{doctor-DiP9HsIP.mjs → doctor-CB8oZKCk.mjs} +13 -13
  46. package/dist/{doctor-Dunu3Nv1.mjs → doctor-kfMBnUw6.mjs} +78 -69
  47. package/dist/{doctor-watchman-XJzT8tK-.mjs → doctor-watchman-BRyV2adA.mjs} +7 -9
  48. package/dist/{eas-build-0gadvrca.mjs → eas-build-JyfqyHfC.mjs} +5 -5
  49. package/dist/{eas-session-ledger-DJDeL4Uq.mjs → eas-session-ledger-Cm0Gwq2F.mjs} +6 -4
  50. package/dist/{error-diagnostics-BhQtoLrZ.mjs → error-diagnostics-BR677IDM.mjs} +10 -10
  51. package/dist/{exec-B81Qodjn.mjs → exec-DqKo9GKJ.mjs} +22 -8
  52. package/dist/{gc-D5cz5G0k.mjs → gc-qWOMdnER.mjs} +74 -23
  53. package/dist/git-DDfFzkMm.mjs +45 -0
  54. package/dist/{gradle-CZZo1TSA.mjs → gradle-DSrXb6lG.mjs} +6 -6
  55. package/dist/{guide-DakjcoUt.mjs → guide-G9cAbVAc.mjs} +56 -18
  56. package/dist/{hosted-android-C-D8Dj0_.mjs → hosted-android-C3MHGld1.mjs} +3 -3
  57. package/dist/{hosted-client--hNFgixu.mjs → hosted-client-ZEKpS9vw.mjs} +19 -11
  58. package/dist/{hosted-ios-Chx9XQyI.mjs → hosted-ios-l-o3iM9J.mjs} +1 -1
  59. package/dist/{hosted-logs-Bkz0Hxzh.mjs → hosted-logs-EzQM7-3Z.mjs} +7 -7
  60. package/dist/{hosted-macos-ckTjN-0V.mjs → hosted-macos-BACVAVqE.mjs} +10 -8
  61. package/dist/{hosted-native-3KXZ5-qn.mjs → hosted-native-A4s1QPXe.mjs} +13 -11
  62. package/dist/{idle-shutdown-DhAUyf5s.mjs → idle-shutdown-DtxhPTKe.mjs} +7 -7
  63. package/dist/{ios-BDBN-xpf.mjs → ios-BwVCF7oA.mjs} +8 -8
  64. package/dist/{ios-CQ8bHQXB.mjs → ios-Ce7bc7br.mjs} +29 -29
  65. package/dist/{ios-o896T9PE.mjs → ios-RkW4pnQf.mjs} +6 -6
  66. package/dist/{ios-device-B1B14xND.mjs → ios-device-B5veSDDQ.mjs} +1 -1
  67. package/dist/{ios-device-BWHKGaJq.mjs → ios-device-D7pi2Sca.mjs} +14 -14
  68. package/dist/{ios-VGvNdsv2.mjs → ios-nOLJGVdy.mjs} +1 -1
  69. package/dist/{ios-project-BeOXKPt2.mjs → ios-project-K9hY_Jab.mjs} +8 -8
  70. package/dist/{ios-state-BsXMwo5y.mjs → ios-state-CBLe1xYw.mjs} +1 -1
  71. package/dist/{js-swap-Z_mSuRrx.mjs → js-swap-Bb3nsS07.mjs} +13 -13
  72. package/dist/{launch-BootbMk4.mjs → launch-C3qJ6Agb.mjs} +46 -45
  73. package/dist/{launch-V1zqiOYn.mjs → launch-F4sOqAhB.mjs} +21 -21
  74. package/dist/{launch-verify-Dl78EVgR.mjs → launch-verify-B6Q8hZP-.mjs} +11 -11
  75. package/dist/{logs-Bh4eqCCc.mjs → logs-BGrEUaEs.mjs} +10 -11
  76. package/dist/{macos-D7irBW3A.mjs → macos-Ch5VJmcS.mjs} +40 -24
  77. package/dist/macos-D7uDvO-z.mjs +2 -0
  78. package/dist/macos-run.mjs +1 -1
  79. package/dist/maintenance-run.mjs +7 -7
  80. package/dist/{metro-_ZIE3Axg.mjs → metro-DnCEjCxs.mjs} +8 -9
  81. package/dist/{metro-gateway-BzlQZQmU.mjs → metro-gateway-CX9Xlkq2.mjs} +3 -3
  82. package/dist/{miss-reason-SuTptY-I.mjs → miss-reason-mKzZ4VvN.mjs} +3 -3
  83. package/dist/{named-ports-O1TIl7tx.mjs → named-ports-4WopRPg-.mjs} +4 -5
  84. package/dist/{native-android-D94RlJ-X.mjs → native-android-D5qc3-_v.mjs} +10 -10
  85. package/dist/{native-gradle-inputs-BQnIdAlL.mjs → native-gradle-inputs-BsLRrl7u.mjs} +3 -10
  86. package/dist/{native-runtime-D024BAvm.mjs → native-runtime-k8dTIrbK.mjs} +7 -8
  87. package/dist/{native-xcode-inputs-UElfGs59.mjs → native-xcode-inputs-CykopJdM.mjs} +7 -8
  88. package/dist/{native-xcode-ios-CjS-nDVY.mjs → native-xcode-ios-Bbf30Gm0.mjs} +15 -15
  89. package/dist/offload-worker.mjs +34 -38
  90. package/dist/{ownership-BrjepDiv.mjs → ownership-DCtw_2IA.mjs} +3 -3
  91. package/dist/{page-Bv9s2KwY.mjs → page-DRHy329N.mjs} +1 -1
  92. package/dist/{placement-log-BItXET1x.mjs → placement-log-MOfPVgaM.mjs} +1 -1
  93. package/dist/{plan-Jwu_vr-F.mjs → plan-C4TjdPsR.mjs} +10 -10
  94. package/dist/{plan-placement-B466UYMU.mjs → plan-placement-V0TdzYXp.mjs} +3 -3
  95. package/dist/{ports-BFRL6JTj.mjs → ports-DdSUicVo.mjs} +3 -3
  96. package/dist/{prebuild-DB_zLOLc.mjs → prebuild-DYbucPXy.mjs} +7 -8
  97. package/dist/{preview-BRLFRhTz.mjs → preview-78a9kR_-.mjs} +31 -24
  98. package/dist/{project-DX8fXyw_.mjs → project-_phNIJfs.mjs} +15 -16
  99. package/dist/{pull-request-vOhLNmIb.mjs → pull-request-CQ8sPbZa.mjs} +5 -18
  100. package/dist/pull-requests.mjs +1 -1
  101. package/dist/{react-native-android-CuXM3QS8.mjs → react-native-android-CM1XRDwv.mjs} +34 -30
  102. package/dist/{react-native-build-JUF31S8U.mjs → react-native-build-CtCccJtb.mjs} +6 -6
  103. package/dist/{react-native-doctor-BQHqiXaQ.mjs → react-native-doctor-CfRnFfjs.mjs} +5 -5
  104. package/dist/{react-native-ios-DtVO4qf2.mjs → react-native-ios-Dhq_eiYQ.mjs} +14 -14
  105. package/dist/{recordings-Bk-VivUV.mjs → recordings-D0d5aQt0.mjs} +1 -1
  106. package/dist/{reload-D9V7D8gP.mjs → reload-C8JhxjSh.mjs} +17 -17
  107. package/dist/{remote-CZiTijxG.mjs → remote-BiR6aYjy.mjs} +7 -7
  108. package/dist/{remote-cache-fxcl5C-L.mjs → remote-cache-OyOyVIS3.mjs} +4 -4
  109. package/dist/{result-BrfgXtdO.mjs → result-CaJg5Iat.mjs} +8 -8
  110. package/dist/{run-ClC8UVB5.mjs → run-BtPgpKks.mjs} +3 -3
  111. package/dist/{server-bare-dWjAarki.mjs → server-bare-R2m_gsH8.mjs} +3 -3
  112. package/dist/{server-command-DnJYLnr4.mjs → server-command-CTtCkmcQ.mjs} +5 -5
  113. package/dist/server-expo-Bigriskl.mjs +2 -0
  114. package/dist/{server-expo-CUuzP9Mp.mjs → server-expo-DsguMGUF.mjs} +5 -10
  115. package/dist/{settings-Bbztm4oV.mjs → settings-B717odTD.mjs} +74 -115
  116. package/dist/{settings-BuKMOANA.mjs → settings-BORNaaCO.mjs} +5 -5
  117. package/dist/{simslim-ChMfe8rg.mjs → simslim-CCr3rE-A.mjs} +2 -3
  118. package/dist/{slot-launch-CeCRr6MK.mjs → slot-launch-DPt0m9Nd.mjs} +6 -6
  119. package/dist/{spawn-claims-Kqiifsk2.mjs → spawn-claims-DVS5RkMS.mjs} +1 -1
  120. package/dist/{stage-BNKKdDNc.mjs → stage-KNTQopqv.mjs} +9 -9
  121. package/dist/{start-CRkG-mZ7.mjs → start-BWqzODpb.mjs} +19 -20
  122. package/dist/{start-mh6bS27z.mjs → start-TXeMmmO2.mjs} +1 -1
  123. package/dist/{state-BUpAmt2r.mjs → state-CG_OFoaA.mjs} +2 -2
  124. package/dist/{state-lqxdOH_g.mjs → state-D1Icyjlu.mjs} +5 -5
  125. package/dist/{stats-CaB1MxMi.mjs → stats-BoY5sEPU.mjs} +5 -5
  126. package/dist/{status-BDGHwkCs.mjs → status-BTA7kKiQ.mjs} +1 -1
  127. package/dist/{status-C7vzkInu.mjs → status-WgFbkRzj.mjs} +30 -47
  128. package/dist/{status-watch-ZaVqRdtW.mjs → status-watch-C23ILtf9.mjs} +4 -4
  129. package/dist/{stim-desktop-8GQX2OV8.mjs → stim-desktop-BzBN2Em2.mjs} +1 -1
  130. package/dist/{stop-BO80KJoT.mjs → stop-BNmBMi1F.mjs} +18 -19
  131. package/dist/{stop-Cftw_sXJ.mjs → stop-DPEhunlw.mjs} +6 -6
  132. package/dist/{stop-BU7JaFCg.mjs → stop-DR6VoDIk.mjs} +2 -2
  133. package/dist/supervisor-run.mjs +16 -17
  134. package/dist/{support-Co0wk8Cv.mjs → support-CwjbFs9H.mjs} +9 -9
  135. package/dist/{support-Ca6PZbpr.mjs → support-DMTqj3Hm.mjs} +6 -6
  136. package/dist/{swiftpm-macos-siFSkmCO.mjs → swiftpm-macos-DRNVJWlb.mjs} +9 -9
  137. package/dist/{tailnet-D7-tE_ug.mjs → tailnet-Dh-qiYzG.mjs} +5 -5
  138. package/dist/toolchain-BFkAcstd.mjs +2 -0
  139. package/dist/{toolchain-SqehyPLw.mjs → toolchain-DxSsNssu.mjs} +10 -10
  140. package/dist/trigger-9_USgmxz.mjs +2 -0
  141. package/dist/{trigger-C0MWBi8O.mjs → trigger-CigAYjeL.mjs} +2 -2
  142. package/dist/{warm-progress-5FAXkXIg.mjs → warm-progress-BuY-Fvfn.mjs} +43 -61
  143. package/dist/{watchman-CqmaGcIb.mjs → watchman-CPQFZLXY.mjs} +6 -6
  144. package/dist/{web-BTjzE8mc.mjs → web-BDBMxDpx.mjs} +9 -9
  145. package/dist/web-Dq-i3wzJ.mjs +2 -0
  146. package/dist/web-run.mjs +14 -14
  147. package/dist/{workspace-state-CvgTFe-h.mjs → workspace-state-DJt_MMvf.mjs} +13 -3
  148. package/dist/{workspaces-C4kqIOlx.mjs → workspaces-C36s2jb9.mjs} +15 -16
  149. package/dist/{worktree-DtRsh6go.mjs → worktree-CgvJYJ-Q.mjs} +94 -87
  150. package/dist/{worktree-Cgnm6vZt.mjs → worktree-DpLdCHga.mjs} +1 -1
  151. package/package.json +5 -5
  152. package/dist/macos-kivF8qKz.mjs +0 -2
  153. package/dist/process-identity-Biv3arCO.mjs +0 -40
  154. package/dist/server-expo-Dvkd7JcF.mjs +0 -2
  155. package/dist/toolchain-B12psPA2.mjs +0 -2
  156. package/dist/trigger-SHLOWJ4O.mjs +0 -2
  157. package/dist/web-CHN5gh34.mjs +0 -2
@@ -1,24 +1,23 @@
1
- import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { t as getExecutor } from "./exec-B81Qodjn.mjs";
3
- import { A as directorySize, D as withConfigLock$1, F as volumeRootFor, H as projectDeviceSlots, M as isOnMountedVolume, N as listMountedVolumes, S as removeProject, _ as loadConfig$1, j as formatBytes, k as acquireAvdClaim } from "./config-D0LhTY3S.mjs";
4
- import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-C309csaB.mjs";
5
- import { D as withDirLock$1, E as workspaceStateFile, s as workspaceLastUsed, x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
6
- import { h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-CPDq_90S.mjs";
7
- import { _ as detectIsExpo, r as findProjectRoot } from "./project-DX8fXyw_.mjs";
8
- import { A as listAvds, H as parseAvdSystemImage, I as ownedAvdDirectory, M as listOrphanedAvdDirectories, V as parseAvdDeviceProfile, _ as avdStorageRoots, at as POOL_SETTING_REMEDY, d as androidToolPath, dt as parkedMaxSetting, ft as readParked, it as isStimOwnedSim, j as listInstalledSystemImages, m as avdNameAbsent, o as androidHome, p as avdIniPaths, rt as isStimOwnedAvd } from "./android-DE8-JfGW.mjs";
9
- import { n as readCreatedDevices$1, t as forgetCreatedDevice } from "./created-devices-CXBMtoj5.mjs";
10
- import { C as recordGcResult, I as listBuildSlots, T as canonicalPath, a as collectWorkspaceOutputs, c as listWorkspaceDirs, f as withIdleWorkspace, i as collectOrphanedWorkspaces, l as rootPresence, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as workspaceInUse, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as sizeText, w as takeGcResults } from "./workspaces-C4kqIOlx.mjs";
11
- import { $ as memoryWorkPending, A as findStaleProjectDevices, B as previewScopedEmptying, C as deleteProjectDevices, D as eraseParkedDevices, E as deviceSweepIsScoped, F as includesParkedDevices, H as selectsBeyondCaches, I as includesRecordings, L as includesWorkspaceOutputs, M as withAndroidAvdSizes, N as emptyCaches, O as findOrphanedDevices, P as includesArchives, Q as memorySweepIsScoped, R as isWorkspacesScope, S as deleteParkedSims, T as describeUnverifiableDevices, U as trimCaches, V as selectCaches, W as parseArchiveSelector, X as memoryLines, Y as memoryCacheKind, Z as memoryScope, _ as DEVICE_LIST_TIMEOUT_MS, at as discoverCaches, b as collectParkedSims, d as collectIdleDevices, et as reclaimMemory, h as shutDownIdleDevices, j as unverifiedDeviceCommand, k as findStaleDeviceRecords, m as parseIdleDuration, nt as phase, p as idleDeviceLines, q as collectMemoryReport, st as sizeCaches, tt as scopedMemoryReport, v as collectDeviceLeases, w as describeParkedSims, x as deleteParkedAvds, y as collectParkedAvds, z as planCacheEmptying } from "./budget-RFbwFpG5.mjs";
12
- import { f as resolveEasCliBin } from "./remote-cache-fxcl5C-L.mjs";
13
- import { d as listAllIosSims } from "./ios-o896T9PE.mjs";
14
- import { C as parseSessionListPage, T as verifyStoppedSession, _ as findOrphanedOwnedSessions, b as isDefinitiveMissingSessionError, d as withRemoteSessionLock, f as withEasProjectLock, v as getSessionArgs, w as stopSessionArgs, x as listOwnedSessionsArgs, y as inspectSessionForTeardown } from "./device-remote-DjsNw8DD.mjs";
15
- import { a as removeEasSessionClaim, n as easMachineStateRoot$1, r as readEasSessionLedger$1 } from "./eas-session-ledger-DJDeL4Uq.mjs";
16
- import { r as readCollectors } from "./ownership-BrjepDiv.mjs";
17
- import { c as removeWorktrees, l as worktreePullRequestNote, n as previewMaintenance, s as collectWorktreeSweep, u as worktreeRemovalReason } from "./preview-BRLFRhTz.mjs";
18
- import { _ as reclaimProject, g as describeDereferenced, v as deleteSelectedArchives, y as sweepArchiveStaging } from "./worktree-DtRsh6go.mjs";
19
- import { i as getSwiftpmCacheUsage, n as swiftpmCacheLines, r as getAgentDeviceUsage, t as agentDeviceLines } from "./agent-device-usage-output-VPaOgGaF.mjs";
1
+ import { A as acquireAvdClaim, D as withConfigLock$1, F as listMountedVolumes, L as volumeRootFor, M as directorySize, N as formatBytes, P as isOnMountedVolume, S as removeProject, W as projectDeviceSlots, _ as loadConfig$1, j as ownership_claim_exports, k as process_identity_exports } from "./config-BYDxlMY3.mjs";
2
+ import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
3
+ import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-BX1sJQ2E.mjs";
4
+ import { D as withDirLock$1, E as workspaceStateFile, s as workspaceLastUsed, x as workspaceDir } from "./workspace-state-DJt_MMvf.mjs";
5
+ import { h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-BTy8hZ0F.mjs";
6
+ import { _ as detectIsExpo, r as findProjectRoot } from "./project-_phNIJfs.mjs";
7
+ import { A as listAvds, H as parseAvdSystemImage, I as ownedAvdDirectory, M as listOrphanedAvdDirectories, V as parseAvdDeviceProfile, _ as avdStorageRoots, at as POOL_SETTING_REMEDY, d as androidToolPath, dt as parkedMaxSetting, ft as readParked, it as isStimOwnedSim, j as listInstalledSystemImages, m as avdNameAbsent, o as androidHome, p as avdIniPaths, rt as isStimOwnedAvd } from "./android-Mz_Inn3w.mjs";
8
+ import { n as readCreatedDevices$1, t as forgetCreatedDevice } from "./created-devices-Dzd5C2LF.mjs";
9
+ import { C as recordGcResult, I as listBuildSlots, T as canonicalPath, a as collectWorkspaceOutputs, c as listWorkspaceDirs, f as withIdleWorkspace, i as collectOrphanedWorkspaces, l as rootPresence, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as workspaceInUse, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as sizeText, w as takeGcResults } from "./workspaces-C36s2jb9.mjs";
10
+ import { $ as memoryWorkPending, A as findStaleProjectDevices, B as previewScopedEmptying, C as deleteProjectDevices, D as eraseParkedDevices, E as deviceSweepIsScoped, F as includesParkedDevices, H as selectsBeyondCaches, I as includesRecordings, L as includesWorkspaceOutputs, M as withAndroidAvdSizes, N as emptyCaches, O as findOrphanedDevices, P as includesArchives, Q as memorySweepIsScoped, R as isWorkspacesScope, S as deleteParkedSims, T as describeUnverifiableDevices, U as trimCaches, V as selectCaches, W as parseArchiveSelector, X as memoryLines, Y as memoryCacheKind, Z as memoryScope, _ as DEVICE_LIST_TIMEOUT_MS, at as discoverCaches, b as collectParkedSims, d as collectIdleDevices, et as reclaimMemory, h as shutDownIdleDevices, j as unverifiedDeviceCommand, k as findStaleDeviceRecords, m as parseIdleDuration, nt as phase, p as idleDeviceLines, q as collectMemoryReport, st as sizeCaches, tt as scopedMemoryReport, v as collectDeviceLeases, w as describeParkedSims, x as deleteParkedAvds, y as collectParkedAvds, z as planCacheEmptying } from "./budget-f7516Zk0.mjs";
11
+ import { f as resolveEasCliBin } from "./remote-cache-OyOyVIS3.mjs";
12
+ import { d as listAllIosSims } from "./ios-RkW4pnQf.mjs";
13
+ import { C as parseSessionListPage, T as verifyStoppedSession, _ as findOrphanedOwnedSessions, b as isDefinitiveMissingSessionError, d as withRemoteSessionLock, f as withEasProjectLock, v as getSessionArgs, w as stopSessionArgs, x as listOwnedSessionsArgs, y as inspectSessionForTeardown } from "./device-remote-xRT0Vmo9.mjs";
14
+ import { a as removeEasSessionClaim, n as easMachineStateRoot$1, r as readEasSessionLedger$1 } from "./eas-session-ledger-Cm0Gwq2F.mjs";
15
+ import { r as readCollectors } from "./ownership-DCtw_2IA.mjs";
16
+ import { c as removeWorktrees, l as worktreePullRequestNote, n as previewMaintenance, s as collectWorktreeSweep, u as worktreeRemovalReason } from "./preview-78a9kR_-.mjs";
17
+ import { _ as reclaimProject, g as describeDereferenced, v as deleteSelectedArchives, y as sweepArchiveStaging } from "./worktree-CgvJYJ-Q.mjs";
18
+ import { i as getSwiftpmCacheUsage, n as swiftpmCacheLines, r as getAgentDeviceUsage, t as agentDeviceLines } from "./agent-device-usage-output-Dzgv6lgR.mjs";
20
19
  import { existsSync, lstatSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
21
- import { basename, dirname, join } from "node:path";
20
+ import { basename, dirname, isAbsolute, join } from "node:path";
22
21
  import { basename as basename$1, dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1 } from "path";
23
22
  import { assertHostedDeviceLedger, deviceHostArea, deviceHostRoot, hostedDeviceId, isJsonObject, listRecordedDevices, listStatusCacheEntries, maintenanceRunClaims, parseHostedPlatformDevice, readArchives, readHostedDevice, readHostedDeviceLedger, readHostedSessions, recordedBytes } from "@stim-cli/core/state";
24
23
  import { fileURLToPath } from "node:url";
@@ -529,6 +528,40 @@ async function deleteEasSessions(easSessionSweep, deps) {
529
528
  return deleteFailures;
530
529
  }
531
530
  //#endregion
531
+ //#region src/commands/gc/eas-ledger.ts
532
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
533
+ /**
534
+ * An entry is dropped only when its id cannot be an EAS session id and its workspace root is provably gone:
535
+ * absolute, missing, and on a mounted volume, the same proof gc uses for dead project entries.
536
+ */
537
+ function isStaleEasLedgerEntry(claim, mountedVolumes, exists = existsSync) {
538
+ if (UUID.test(claim.sessionId)) return false;
539
+ const root = claim.workspaceRoot;
540
+ if (!isAbsolute(root) || exists(root)) return false;
541
+ return isOnMountedVolume(root, mountedVolumes);
542
+ }
543
+ function findStaleEasLedgerEntries(mountedVolumes, deps = {}) {
544
+ const ledger = readEasSessionLedger$1(deps.easLedgerRoot ?? easMachineStateRoot$1());
545
+ if (!ledger.safe) return [];
546
+ return [...ledger.claims.values()].filter((claim) => isStaleEasLedgerEntry(claim, mountedVolumes)).map(({ sessionId, workspaceRoot }) => ({
547
+ id: sessionId,
548
+ workspaceRoot
549
+ }));
550
+ }
551
+ function forgetStaleEasLedgerEntries(entries, mountedVolumes, deps = {}) {
552
+ let failures = 0;
553
+ const root = deps.easLedgerRoot ?? easMachineStateRoot$1();
554
+ const remove = deps.removeEasSessionClaim ?? removeEasSessionClaim;
555
+ for (const entry of entries) try {
556
+ if (remove(entry.id, root, (claim) => isStaleEasLedgerEntry(claim, mountedVolumes))) console.log(chalk.green(`Forgot the EAS ledger entry ${entry.id} (invalid id, ${entry.workspaceRoot} is gone)`));
557
+ else console.log(chalk.dim(`Kept the EAS ledger entry ${entry.id}: it changed since the report.`));
558
+ } catch (error) {
559
+ failures++;
560
+ console.log(chalk.red(`Could not forget the EAS ledger entry ${entry.id}: ${describeError(error)}`));
561
+ }
562
+ return failures;
563
+ }
564
+ //#endregion
532
565
  //#region src/commands/gc/status-caches.ts
533
566
  const KINDS = ["disk-usage", "pull-request"];
534
567
  const KEPT_REASON = {
@@ -809,7 +842,15 @@ function maintenanceReportLines(maintenance) {
809
842
  }
810
843
  return lines;
811
844
  }
812
- function formatGcReport({ maintenance, archives, skipped = [], deadProjects = [], orphanedPorts, invalidProjects = [], orphanedWorkspaces = [], parkedSims = [], parkedAvds = [], parkedHostedDevices, orphanedDevices = [], unverifiedDevices = [], staleDevices = [], staleDeviceRecords = [], staleLedgerEntries = [], staleStatusCaches = [], buildLocks = {
845
+ function staleEasLedgerLines(entries = []) {
846
+ if (!entries.length) return [];
847
+ return [
848
+ `Stale EAS ledger entries (${entries.length}) - the id is not a valid EAS session id and the workspace is gone:`,
849
+ ...entries.map((entry) => ` ${entry.id} (workspace ${entry.workspaceRoot})`),
850
+ " --delete forgets the LEDGER ENTRY only; no EAS session is contacted."
851
+ ];
852
+ }
853
+ function formatGcReport({ maintenance, archives, skipped = [], deadProjects = [], orphanedPorts, invalidProjects = [], orphanedWorkspaces = [], parkedSims = [], parkedAvds = [], parkedHostedDevices, orphanedDevices = [], unverifiedDevices = [], staleDevices = [], staleDeviceRecords = [], staleLedgerEntries = [], staleEasLedgerEntries, staleStatusCaches = [], buildLocks = {
813
854
  stale: [],
814
855
  live: [],
815
856
  unresolved: []
@@ -828,6 +869,7 @@ function formatGcReport({ maintenance, archives, skipped = [], deadProjects = []
828
869
  }, agentDeviceUsage = null, swiftpmCacheUsage, caches = [], workspaceOutputs = null, workspaceLogs = [], recordings = [], worktreeSweep = null, memory, cacheScope = null, olderThan = null }, { now = Date.now() } = {}) {
829
870
  const lines = archiveLines(archives);
830
871
  const parkedHostedLines = formatParkedHostedDeviceReport(parkedHostedDevices, now);
872
+ const easLedgerLines = staleEasLedgerLines(staleEasLedgerEntries);
831
873
  const staleLocks = buildLocks?.stale ?? [];
832
874
  const liveLocks = buildLocks?.live ?? [];
833
875
  const staleSlots = buildSlots?.stale ?? [];
@@ -844,6 +886,7 @@ function formatGcReport({ maintenance, archives, skipped = [], deadProjects = []
844
886
  staleDevices,
845
887
  staleDeviceRecords,
846
888
  staleLedgerEntries,
889
+ easLedgerLines,
847
890
  staleStatusCaches,
848
891
  staleLocks,
849
892
  staleSlots,
@@ -901,6 +944,7 @@ function formatGcReport({ maintenance, archives, skipped = [], deadProjects = []
901
944
  for (const entry of staleLedgerEntries) lines.push(` ${entry.kind} ${entry.id} is not on this machine`);
902
945
  lines.push(" --delete forgets the LEDGER ENTRY only; there is no device left to touch.");
903
946
  }
947
+ lines.push(...easLedgerLines);
904
948
  lines.push(...statusCacheLines(staleStatusCaches));
905
949
  if (easSessionSweep.orphaned.length) {
906
950
  lines.push(`Orphaned EAS sessions (${easSessionSweep.orphaned.length}) - current EAS project only:`);
@@ -1083,7 +1127,7 @@ function jsonPullRequest(lookup) {
1083
1127
  containsHead: pr.containsHead
1084
1128
  } : null;
1085
1129
  }
1086
- function gcReportSections({ archives, skipped = [], deadProjects = [], orphanedPorts = [], invalidProjects = [], orphanedWorkspaces = [], worktreeSweep = null, parkedSims = [], parkedAvds = [], parkedHostedDevices = [], orphanedDevices = [], unverifiedDevices = [], staleDevices = [], staleDeviceRecords = [], staleLedgerEntries = [], staleStatusCaches = [], buildLocks = {
1130
+ function gcReportSections({ archives, skipped = [], deadProjects = [], orphanedPorts = [], invalidProjects = [], orphanedWorkspaces = [], worktreeSweep = null, parkedSims = [], parkedAvds = [], parkedHostedDevices = [], orphanedDevices = [], unverifiedDevices = [], staleDevices = [], staleDeviceRecords = [], staleLedgerEntries = [], staleEasLedgerEntries = [], staleStatusCaches = [], buildLocks = {
1087
1131
  stale: [],
1088
1132
  live: [],
1089
1133
  unresolved: []
@@ -1180,6 +1224,10 @@ function gcReportSections({ archives, skipped = [], deadProjects = [], orphanedP
1180
1224
  kind,
1181
1225
  id
1182
1226
  })),
1227
+ staleEasLedgerEntries: staleEasLedgerEntries.map(({ id, workspaceRoot }) => ({
1228
+ id,
1229
+ workspaceRoot
1230
+ })),
1183
1231
  staleStatusCaches: staleStatusCaches.map(({ kind, path, file, bytes }) => ({
1184
1232
  kind,
1185
1233
  path,
@@ -2103,6 +2151,7 @@ async function collectGcReport({ olderThan = null, cache = null, worktrees = fal
2103
2151
  staleDevices: [],
2104
2152
  staleDeviceRecords: [],
2105
2153
  staleLedgerEntries: [],
2154
+ staleEasLedgerEntries: [],
2106
2155
  staleStatusCaches: [],
2107
2156
  buildLocks: {
2108
2157
  stale: [],
@@ -2304,6 +2353,7 @@ async function collectGcReport({ olderThan = null, cache = null, worktrees = fal
2304
2353
  staleDevices,
2305
2354
  staleDeviceRecords,
2306
2355
  staleLedgerEntries,
2356
+ staleEasLedgerEntries: findStaleEasLedgerEntries(mountedVolumes, deps),
2307
2357
  staleStatusCaches: statusCaches.stale,
2308
2358
  buildLocks: {
2309
2359
  stale: locks.filter((l) => !l.alive && !l.unresolved),
@@ -2588,7 +2638,7 @@ async function runGcCore(opts, deps) {
2588
2638
  const all = report.all;
2589
2639
  for (const line of formatGcReport(report)) console.log(line);
2590
2640
  const { deadProjects, invalidProjects, orphanedDevices, staleDevices, staleDeviceRecords, buildLocks, buildSlots, deviceLeases, easSessionSweep, caches } = report;
2591
- const actionable = archiveWorkPending(report.archives, deadProjects.length + invalidProjects.length > 0 || report.orphanedWorkspaces.length > 0 || Boolean(report.workspaceOutputs?.workspaces.some((entry) => entry.willClear)) || report.workspaceLogs.some((entry) => entry.willTrim) || report.recordings.some((entry) => entry.willDelete && !entry.withWorkspace) || Boolean(report.worktreeSweep?.worktrees.some((entry) => !entry.skipped)) || report.parkedSims.length > 0 || report.parkedAvds.length + report.parkedHostedDevices.filter((device) => device.listed !== false).length > 0 || orphanedDevices.length > 0 || staleDevices.length > 0 || staleDeviceRecords.length > 0 || report.staleLedgerEntries.length > 0 || report.staleStatusCaches.length > 0 || buildLocks.stale.length > 0 || buildSlots.stale.length > 0 || deviceLeases.expired.length > 0 || easSessionSweep.orphaned.length > 0 || (olderThan !== null || all) && caches.length > 0 || memoryWorkPending(cache, report.memory));
2641
+ const actionable = archiveWorkPending(report.archives, deadProjects.length + invalidProjects.length > 0 || report.orphanedWorkspaces.length > 0 || Boolean(report.workspaceOutputs?.workspaces.some((entry) => entry.willClear)) || report.workspaceLogs.some((entry) => entry.willTrim) || report.recordings.some((entry) => entry.willDelete && !entry.withWorkspace) || Boolean(report.worktreeSweep?.worktrees.some((entry) => !entry.skipped)) || report.parkedSims.length > 0 || report.parkedAvds.length + report.parkedHostedDevices.filter((device) => device.listed !== false).length > 0 || orphanedDevices.length > 0 || staleDevices.length > 0 || staleDeviceRecords.length > 0 || report.staleLedgerEntries.length + report.staleEasLedgerEntries.length > 0 || report.staleStatusCaches.length > 0 || buildLocks.stale.length > 0 || buildSlots.stale.length > 0 || deviceLeases.expired.length > 0 || easSessionSweep.orphaned.length > 0 || (olderThan !== null || all) && caches.length > 0 || memoryWorkPending(cache, report.memory));
2592
2642
  const idle = opts.idle ?? null;
2593
2643
  const idleFailures = idle === null ? 0 : shutDownIdleDevices(report.idleDevices, idle, () => collectIdleDevices(loadConfig$1(), listAllIosSims({ timeoutMs: DEVICE_LIST_TIMEOUT_MS }), report.deadProjects)).failures;
2594
2644
  if (idleFailures) process.exitCode = 1;
@@ -2628,6 +2678,7 @@ async function runGcCore(opts, deps) {
2628
2678
  deleteFailures += await deleteOrphanedWorkspaces(report.orphanedWorkspaces);
2629
2679
  deleteFailures += deleteProjectDevices(orphanedDevices, staleDevices, staleDeviceRecords);
2630
2680
  deleteFailures += forgetStaleLedgerEntries(report.staleLedgerEntries);
2681
+ deleteFailures += forgetStaleEasLedgerEntries(report.staleEasLedgerEntries, listMountedVolumes(), deps);
2631
2682
  deleteFailures += pruneStatusCaches(report);
2632
2683
  for (const lock of buildLocks.stale) {
2633
2684
  const cleared = (0, ownership_claim_exports.clearFreeClaimSet)({
@@ -0,0 +1,45 @@
1
+ import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
2
+ //#region src/workspace/git.ts
3
+ const GIT_TIMEOUT_MS = 1e4;
4
+ const GIT_CONCURRENCY = 6;
5
+ function gitCall(cwd, args, { write, timeoutMs = GIT_TIMEOUT_MS, ...opts }) {
6
+ return {
7
+ args: [
8
+ ...write ? [] : ["--no-optional-locks"],
9
+ "-C",
10
+ cwd,
11
+ ...args
12
+ ],
13
+ opts: {
14
+ ...opts,
15
+ timeoutMs
16
+ }
17
+ };
18
+ }
19
+ /** Runs git in `cwd`, bounded by `timeoutMs` (10 s by default); throws like `runFile`. */
20
+ function git(cwd, args, opts = {}) {
21
+ const call = gitCall(cwd, args, opts);
22
+ return getExecutor().runFile("git", call.args, call.opts);
23
+ }
24
+ /** `git`, returning null instead of throwing. */
25
+ function gitQuiet(cwd, args, opts = {}) {
26
+ const call = gitCall(cwd, args, opts);
27
+ return getExecutor().runFileQuiet("git", call.args, call.opts);
28
+ }
29
+ const queue = [];
30
+ let running = 0;
31
+ /** `git` without blocking the event loop, at most six at a time; the budget starts when the call leaves the queue. */
32
+ async function gitAsync(cwd, args, opts = {}) {
33
+ if (running < GIT_CONCURRENCY) running++;
34
+ else await new Promise((proceed) => queue.push(proceed));
35
+ try {
36
+ const call = gitCall(cwd, args, opts);
37
+ return await getExecutor().runFileAsync("git", call.args, call.opts);
38
+ } finally {
39
+ const next = queue.shift();
40
+ if (next) next();
41
+ else running--;
42
+ }
43
+ }
44
+ //#endregion
45
+ export { gitAsync as n, gitQuiet as r, git as t };
@@ -1,10 +1,10 @@
1
- import { t as getExecutor } from "./exec-B81Qodjn.mjs";
1
+ import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
2
2
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
3
- import { l as phaseLine } from "./command-output-CPDq_90S.mjs";
4
- import { o as androidHome } from "./android-DE8-JfGW.mjs";
5
- import { a as spawnDeclared } from "./spawn-claims-Kqiifsk2.mjs";
6
- import { a as readCcacheActivity, n as CCACHE_UNAVAILABLE } from "./ccache-CtbqWxIC.mjs";
7
- import { M as startBuildHeartbeat, y as HEARTBEAT_INTERVAL_MS } from "./toolchain-SqehyPLw.mjs";
3
+ import { l as phaseLine } from "./command-output-BTy8hZ0F.mjs";
4
+ import { o as androidHome } from "./android-Mz_Inn3w.mjs";
5
+ import { a as spawnDeclared } from "./spawn-claims-DVS5RkMS.mjs";
6
+ import { a as readCcacheActivity, n as CCACHE_UNAVAILABLE } from "./ccache-zdKiYQ3E.mjs";
7
+ import { M as startBuildHeartbeat, y as HEARTBEAT_INTERVAL_MS } from "./toolchain-DxSsNssu.mjs";
8
8
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
9
9
  import { dirname, isAbsolute, join, relative, sep } from "node:path";
10
10
  import { fileURLToPath } from "node:url";
@@ -1,8 +1,8 @@
1
- import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-Bbztm4oV.mjs";
2
- import { r as findProjectRoot } from "./project-DX8fXyw_.mjs";
3
- import { s as RECENT_LAUNCH_MS } from "./watchman-CqmaGcIb.mjs";
4
- import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-XJzT8tK-.mjs";
5
- import "./status-watch-ZaVqRdtW.mjs";
1
+ import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-B717odTD.mjs";
2
+ import { r as findProjectRoot } from "./project-_phNIJfs.mjs";
3
+ import { s as RECENT_LAUNCH_MS } from "./watchman-CPQFZLXY.mjs";
4
+ import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-BRyV2adA.mjs";
5
+ import "./status-watch-C23ILtf9.mjs";
6
6
  import { SETTINGS, SETTINGS_SCHEMA_URL, TUTORIAL_VERSION } from "@stim-cli/core/state";
7
7
  import chalk from "chalk";
8
8
  //#region src/guide/agent.ts
@@ -1360,6 +1360,11 @@ RULES
1360
1360
  root, and browser profile paths whose
1361
1361
  directory is gone; --delete forgets the
1362
1362
  ledger entry only
1363
+ staleEasLedgerEntries { id, workspaceRoot } entries of the machine
1364
+ EAS session ledger whose id is not a UUID and
1365
+ whose absolute workspace root is missing on a
1366
+ mounted volume; --delete forgets the entry
1367
+ only and contacts no EAS session
1363
1368
  staleStatusCaches { kind: "disk-usage" | "pull-request", path,
1364
1369
  file, bytes } entries of $STIM_HOME/disk-usage
1365
1370
  and pull-requests whose path is gone from a
@@ -1506,6 +1511,8 @@ RULES
1506
1511
  absent until it has run.
1507
1512
  recording { enabled }: whether stim-server may record the workspace's
1508
1513
  device screens for replay, from recording.enabled
1514
+ hidden true when workspace.hidden is set; absent otherwise. The next
1515
+ command that uses the workspace clears it.
1509
1516
 
1510
1517
  Each environment also carries stage, where the workspace is as Stim
1511
1518
  Desktop and the phone app show it: { kind, since, platform, closedApps }.
@@ -6274,11 +6281,12 @@ A RUNNING APP IS RESTARTED, LIKE XCODE'S RUN
6274
6281
  A stop that fails refuses the launch rather than reusing the old process.
6275
6282
  When a simulator's process list cannot be read, Stim launches with
6276
6283
  \`simctl launch --terminate-running-process\`, which replaces any running
6277
- copy. When an emulator's cannot be read, Stim launches without stopping
6278
- anything and verification reports what it observes. An iPhone run
6279
- (\`ios --device\`) needs no extra step: its collector launches with
6280
- devicectl's \`--terminate-existing\`. Remote targets launch through
6281
- \`agent-device open --relaunch\`.
6284
+ copy. When an Android device's cannot be read, Stim launches with
6285
+ \`am start -S\`, which force-stops the app first; an app without a
6286
+ launcher activity gets a best-effort \`am force-stop\` before \`monkey\`.
6287
+ Neither claims a restart. An iPhone run (\`ios --device\`) needs no extra
6288
+ step: its collector launches with devicectl's \`--terminate-existing\`.
6289
+ Remote targets launch through \`agent-device open --relaunch\`.
6282
6290
 
6283
6291
  RUNTIME STATE AND BUILD INPUTS
6284
6292
  Runtime state is stored outside the project tree under
@@ -8076,6 +8084,14 @@ THE MIRROR IMAGE: A STALE DEVICE RECORD
8076
8084
  runs still counts as this home's; run \`gc\` after deleting a Stim AVD by
8077
8085
  hand.
8078
8086
 
8087
+ The machine EAS session ledger (~/.stim/machine/eas/sessions.json) can hold
8088
+ entries that no EAS session ever had, such as ids written by a test
8089
+ fixture. \`gc\` reports an entry under "Stale EAS ledger entries" only when
8090
+ its id is not a UUID AND its workspace root is an absolute path that is
8091
+ missing on a mounted volume. A valid id, an existing root, or a root on an
8092
+ unmounted volume keeps the entry. \`gc --delete\` re-checks each entry and
8093
+ removes it under the ledger lock; it never contacts EAS.
8094
+
8079
8095
  THE ONE CASE GC WILL NOT REAP
8080
8096
  If the config is gone entirely (deleted ~/.stim, or a throwaway
8081
8097
  STIM_HOME), gc cannot tell your stale devices from another config's LIVE
@@ -9163,8 +9179,10 @@ The same \`remote.machines\` list names the Macs that may build for this one:
9163
9179
  node in $STIM_HOME/build-machines.json. A person approves the request on that
9164
9180
  Mac with \`stim-server devices grant <id> --build\`; doctor prints the id.
9165
9181
  A person can instead run \`stim-server setup\` on the worker with a node,
9166
- ticket and expiry, under the approval rule above. Build never includes read
9167
- or control.
9182
+ ticket and expiry, under the approval rule above. A build grant is full access
9183
+ to the account stim-server runs as: project code runs there unsandboxed, so it
9184
+ can grant itself read and control. Revoking it does not undo what that code
9185
+ already did. Grant it only to Macs you trust.
9168
9186
  Stim connects to a named Mac only while its name still belongs to the pinned
9169
9187
  node and never sends the token to another node. \`doctor\` reports each
9170
9188
  remote Mac's build pairing state and, for an approved one, asks it for one build
@@ -9366,6 +9384,19 @@ them within seconds, as soon as \`stim status\` shows recording.enabled false
9366
9384
  for them. Turning it back on records from then on. See \`guide cleanup\` for
9367
9385
  how recordings are removed otherwise.
9368
9386
 
9387
+ HIDE A WORKSPACE IN THE APPS
9388
+ \`workspace.hidden\` is a boolean, false by default, set only at workspace
9389
+ scope, so it needs no --scope. Run it from the workspace:
9390
+
9391
+ stim settings set workspace.hidden true
9392
+ stim settings unset workspace.hidden
9393
+
9394
+ \`stim status --json\` then reports hidden: true on that environment, and
9395
+ clients that read it list the workspace under Hidden. The next start, ios,
9396
+ android, web, macos, reload or worktree warm in the workspace clears it, so
9397
+ a workspace in use is never hidden. \`worktree remove\` drops it with the
9398
+ workspace.
9399
+
9369
9400
  STIM NEEDS NO PROJECT CHANGES TO RUN
9370
9401
  Nothing above is required to use Stim. The performance caches that used to
9371
9402
  be setup steps are supplied by Stim on the command lines it composes itself:
@@ -9592,7 +9623,11 @@ FileStore shards across 256 directories, a build cache is keyed
9592
9623
  platform instead of one entry. Pass prune: 'atomic' for a cache whose index
9593
9624
  references its own data (an LLVM CAS): it is then left alone by --older-than
9594
9625
  and emptied whole only by 'gc --delete --cache all'.
9595
- Registration is idempotent and keyed on the directory.`
9626
+ Registration is idempotent and keyed on the directory.
9627
+ dir must be absolute (a leading ~ is expanded) and dedicated to the cache.
9628
+ register throws for a path that is or contains the home directory, the system
9629
+ temporary directory, the Stim config directory or a filesystem root, and gc
9630
+ never prunes or empties such a directory.`
9596
9631
  };
9597
9632
  //#endregion
9598
9633
  //#region src/guide/web.ts
@@ -9955,8 +9990,11 @@ attempt falls back here. Placement and failure reasons are in build logs.
9955
9990
 
9956
9991
  AGENT ACTIONS
9957
9992
 
9958
- Launch through stim macos first. Use its isolated bundleId from the JSON
9959
- launch record or status --json:
9993
+ Launch through stim macos first. Use its isolated bundleId from the JSON launch
9994
+ record or status --json. stim macos waits, for up to 20 seconds, until macOS
9995
+ LaunchServices lists the app, so agent-device open attaches to it instead of
9996
+ starting a second copy. If it is still unlisted, stim macos warns and returns;
9997
+ wait before opening. A --remote launch skips the wait:
9960
9998
 
9961
9999
  agent-device open <bundleId> --platform macos --surface app --foreground
9962
10000
  agent-device click <ref> --settle
@@ -10262,7 +10300,7 @@ const TUTORIAL_ASKS = {
10262
10300
  build: "Make the title purple in the Stim tutorial app and check it on the simulator.",
10263
10301
  parallel: "While that builds, make the Tap me button green in a new worktree and check it on the simulator.",
10264
10302
  finish: "I'm done with these experiments in {base} and don't need the changes. Stop the apps and remove the worktrees {worktrees}, and keep the clone. Follow stim guide tutorial finish.",
10265
- delete: "Remove the Stim tutorial: remove its worktrees and the clone at {base} with stim worktree remove, then delete {base}. Follow stim guide tutorial delete.",
10303
+ delete: "Remove the test app: run stim worktree remove on {base}, then delete the folder. Follow stim guide tutorial delete.",
10266
10304
  share: `Open a pull request to ${TUTORIAL_REPO} with my title color change, with before and after screenshots from the simulator. See stim guide tutorial share.`,
10267
10305
  retry: "The first iOS build of the tutorial app in {tour} failed. Find out why and run it on iOS again."
10268
10306
  };
@@ -10371,8 +10409,8 @@ ${screenshots}
10371
10409
 
10372
10410
  Check each change on the device with agent-device in that same session, after
10373
10411
  the after screenshot, so Stim Desktop records your actions and the user can
10374
- replay them: tap tap-button, toggle dark-accent-switch, type a name in
10375
- name-input, then take a screenshot (agent-device screenshot
10412
+ replay them: tap tap-button, toggle dark-accent-switch, pick a size
10413
+ (size-s, size-m or size-l), then take a screenshot (agent-device screenshot
10376
10414
  .expo/screenshots/checked.png) and confirm the change. Refs expire after each
10377
10415
  action: run agent-device snapshot -i before every action and use the ref it
10378
10416
  reports for that testID. When agentDevice.installed is false in stim status
@@ -1,6 +1,6 @@
1
- import { o as call, s as connectHost } from "./hosted-client--hNFgixu.mjs";
2
- import { i as requestHostedMetro } from "./metro-gateway-BzlQZQmU.mjs";
3
- import { n as prepareHostedNative, r as stopHostedNative, t as placeHostedNative } from "./hosted-native-3KXZ5-qn.mjs";
1
+ import { c as connectHost, s as call } from "./hosted-client-ZEKpS9vw.mjs";
2
+ import { i as requestHostedMetro } from "./metro-gateway-CX9Xlkq2.mjs";
3
+ import { n as prepareHostedNative, r as stopHostedNative, t as placeHostedNative } from "./hosted-native-A4s1QPXe.mjs";
4
4
  //#region src/device-host/hosted-android.ts
5
5
  async function prepareHostedAndroid(machine, selectors, recorded, mode) {
6
6
  return await prepareHostedNative(machine, selectors, recorded, "android", false, mode);
@@ -1,16 +1,19 @@
1
- import { c as pinnedEndpoint$1 } from "./tailnet-D7-tE_ug.mjs";
2
- import { t as BuildConnection, x as configuredMachines } from "./client-zqjFd79D.mjs";
1
+ import { c as pinnedEndpoint$1 } from "./tailnet-Dh-qiYzG.mjs";
2
+ import { r as throwIfCancelled, t as cancellableSleep } from "./cancellation-C_22VQTH.mjs";
3
+ import { t as BuildConnection, x as configuredMachines } from "./client-qQAaXSUs.mjs";
3
4
  import { lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
4
5
  import { join } from "node:path";
5
- import { HOSTED_APP_CHUNK_BYTES, hostedMacosAppSlot, isJsonObject, readDeviceHostMachines } from "@stim-cli/core/state";
6
+ import { DEVICE_HOST_LIMITS, HOSTED_APP_CHUNK_BYTES, hostedMacosAppSlot, hostedWorkerSettleMs, isJsonObject, readDeviceHostMachines } from "@stim-cli/core/state";
6
7
  import { createHash } from "node:crypto";
7
8
  //#region src/device-host/hosted-client.ts
8
9
  const CONNECT_TIMEOUT_MS = 1e4;
9
- /** Covers 90s stop + 15s final logs + three 10s worker group-settle bounds, with 45s for polling and transport. */
10
- const SESSION_TIMEOUT_MS = 18e4;
11
- const PREPARE_TIMEOUT_MS = 355e3;
12
- const INSTALL_TIMEOUT_MS = 3e5;
13
- const sleep = (ms) => new Promise((done) => setTimeout(done, ms));
10
+ const HOSTED_POLL_MARGIN_MS = 45e3;
11
+ const HOSTED_REQUEST_MARGIN_MS = 5e3;
12
+ const workerBoundMs = (deadlineMs) => deadlineMs + hostedWorkerSettleMs();
13
+ const SESSION_TIMEOUT_MS = hostedWorkerSettleMs() + workerBoundMs(DEVICE_HOST_LIMITS.logsMs) + workerBoundMs(DEVICE_HOST_LIMITS.stopMs) + HOSTED_POLL_MARGIN_MS;
14
+ const PREPARE_TIMEOUT_MS = workerBoundMs(DEVICE_HOST_LIMITS.prepareMs) + HOSTED_POLL_MARGIN_MS;
15
+ const INSTALL_TIMEOUT_MS = workerBoundMs(DEVICE_HOST_LIMITS.prepareMs) + HOSTED_POLL_MARGIN_MS;
16
+ const OFFER_TIMEOUT_MS = workerBoundMs(DEVICE_HOST_LIMITS.offerMs) + HOSTED_REQUEST_MARGIN_MS;
14
17
  const sha256 = (content) => createHash("sha256").update(content).digest("hex");
15
18
  function credentialRefusal(message, remedy = "Run stim doctor.") {
16
19
  return Object.assign(new Error(message), {
@@ -128,11 +131,16 @@ async function probeSession(placement, timeoutMs) {
128
131
  host?.connection.close();
129
132
  }
130
133
  }
131
- async function settle(host, session, passing, timeoutMs, platform = "macos") {
134
+ async function settle(host, session, passing, timeoutMs, platform = "macos", signal) {
132
135
  const deadline = Date.now() + timeoutMs;
136
+ const what = `wait for hosted session ${session.id}`;
133
137
  while (passing.includes(session.state)) {
138
+ throwIfCancelled(signal, what);
134
139
  if (Date.now() > deadline) throw new Error(`The hosted session ${session.id} on ${host.machine} stayed ${session.state}.`);
135
- await sleep(500);
140
+ await cancellableSleep(500, {
141
+ signal,
142
+ what
143
+ });
136
144
  session = await attach(host, session.id, void 0, platform);
137
145
  }
138
146
  return session;
@@ -199,4 +207,4 @@ async function upload(host, ids, missing, content) {
199
207
  }
200
208
  }
201
209
  //#endregion
202
- export { bundleManifest as a, heldNoLonger as c, requireHostedAppMode as d, settle as f, upload as g, unknownSession as h, attach as i, hostedSession as l, sleep as m, PREPARE_TIMEOUT_MS as n, call as o, sha256 as p, SESSION_TIMEOUT_MS as r, connectHost as s, INSTALL_TIMEOUT_MS as t, probeHostedSession as u };
210
+ export { attach as a, connectHost as c, probeHostedSession as d, requireHostedAppMode as f, upload as g, unknownSession as h, SESSION_TIMEOUT_MS as i, heldNoLonger as l, sha256 as m, OFFER_TIMEOUT_MS as n, bundleManifest as o, settle as p, PREPARE_TIMEOUT_MS as r, call as s, INSTALL_TIMEOUT_MS as t, hostedSession as u };
@@ -1,4 +1,4 @@
1
- import { n as prepareHostedNative, r as stopHostedNative, t as placeHostedNative } from "./hosted-native-3KXZ5-qn.mjs";
1
+ import { n as prepareHostedNative, r as stopHostedNative, t as placeHostedNative } from "./hosted-native-A4s1QPXe.mjs";
2
2
  //#region src/device-host/hosted-ios.ts
3
3
  async function prepareHostedIos(machine, selectors, recorded, mode) {
4
4
  return await prepareHostedNative(machine, selectors, recorded, "ios", false, mode);
@@ -1,11 +1,11 @@
1
- import { t as getExecutor } from "./exec-B81Qodjn.mjs";
2
- import { L as deviceSlotFileKey, W as validateDeviceSlot } from "./config-D0LhTY3S.mjs";
3
- import { w as workspaceLogsDir$1, x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
4
- import { l as phaseLine } from "./command-output-CPDq_90S.mjs";
5
- import { o as parseMachine$1 } from "./tailnet-D7-tE_ug.mjs";
1
+ import { K as validateDeviceSlot, z as deviceSlotFileKey } from "./config-BYDxlMY3.mjs";
2
+ import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
3
+ import { w as workspaceLogsDir$1, x as workspaceDir } from "./workspace-state-DJt_MMvf.mjs";
4
+ import { l as phaseLine } from "./command-output-BTy8hZ0F.mjs";
5
+ import { o as parseMachine$1 } from "./tailnet-Dh-qiYzG.mjs";
6
6
  import { r as createNdjsonWriter } from "./ndjson-GOnbyvso.mjs";
7
- import { n as macosDir } from "./state-BUpAmt2r.mjs";
8
- import { o as call } from "./hosted-client--hNFgixu.mjs";
7
+ import { n as macosDir } from "./state-CG_OFoaA.mjs";
8
+ import { s as call } from "./hosted-client-ZEKpS9vw.mjs";
9
9
  import { mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { dirname, join } from "node:path";
11
11
  import { isJsonObject, parseHostedAgentGrant, parseHostedLogsCursor } from "@stim-cli/core/state";
@@ -1,7 +1,9 @@
1
- import { l as phaseLine } from "./command-output-CPDq_90S.mjs";
2
- import { n as macosDir } from "./state-BUpAmt2r.mjs";
3
- import { a as bundleManifest, c as heldNoLonger, f as settle, g as upload, h as unknownSession, i as attach, l as hostedSession, m as sleep, n as PREPARE_TIMEOUT_MS, o as call, p as sha256, r as SESSION_TIMEOUT_MS, s as connectHost, t as INSTALL_TIMEOUT_MS } from "./hosted-client--hNFgixu.mjs";
4
- import { i as agentAccess, r as closeAgentConnection, t as pullHostedMacosLogs } from "./hosted-logs-Bkz0Hxzh.mjs";
1
+ import { l as phaseLine } from "./command-output-BTy8hZ0F.mjs";
2
+ import { x as runCancellationSignal } from "./tailnet-Dh-qiYzG.mjs";
3
+ import { t as cancellableSleep } from "./cancellation-C_22VQTH.mjs";
4
+ import { n as macosDir } from "./state-CG_OFoaA.mjs";
5
+ import { a as attach, c as connectHost, g as upload, h as unknownSession, i as SESSION_TIMEOUT_MS, l as heldNoLonger, m as sha256, o as bundleManifest, p as settle, r as PREPARE_TIMEOUT_MS, s as call, t as INSTALL_TIMEOUT_MS, u as hostedSession } from "./hosted-client-ZEKpS9vw.mjs";
6
+ import { i as agentAccess, r as closeAgentConnection, t as pullHostedMacosLogs } from "./hosted-logs-EzQM7-3Z.mjs";
5
7
  import { rmSync } from "node:fs";
6
8
  import { join } from "node:path";
7
9
  import { hostedMacosBundleId, parseHostedMacosDevice, validHostedAppArguments } from "@stim-cli/core/state";
@@ -18,8 +20,8 @@ async function placeHostedMacos(host, { root, bundle, bundleId, handoff, argumen
18
20
  let session = null;
19
21
  if (recorded) {
20
22
  try {
21
- session = await settle(host, await attach(host, recorded.session), ["preparing"], PREPARE_TIMEOUT_MS);
22
- session = await settle(host, session, ["stopping"], SESSION_TIMEOUT_MS);
23
+ session = await settle(host, await attach(host, recorded.session), ["preparing"], PREPARE_TIMEOUT_MS, "macos", runCancellationSignal());
24
+ session = await settle(host, session, ["stopping"], SESSION_TIMEOUT_MS, "macos", runCancellationSignal());
23
25
  } catch (error) {
24
26
  if (!heldNoLonger(error)) throw error;
25
27
  }
@@ -50,7 +52,7 @@ async function placeHostedMacos(host, { root, bundle, bundleId, handoff, argumen
50
52
  }
51
53
  };
52
54
  reserved(placement);
53
- session = await settle(host, session, ["preparing"], PREPARE_TIMEOUT_MS);
55
+ session = await settle(host, session, ["preparing"], PREPARE_TIMEOUT_MS, "macos", runCancellationSignal());
54
56
  if (session.state === "unknown") throw unknownSession(host, session);
55
57
  if (session.state !== "ready") throw new Error(`The hosted session ${session.id} on ${host.machine} is ${session.state}.`);
56
58
  const device = parseHostedMacosDevice(session.device);
@@ -97,7 +99,7 @@ async function placeHostedMacos(host, { root, bundle, bundleId, handoff, argumen
97
99
  while (delivery.state !== "installed") {
98
100
  if (delivery.state === "unknown") throw new Error(`${host.machine} could not install or launch the app${typeof delivery.notice === "string" ? `: ${delivery.notice}` : ""}.`);
99
101
  if (Date.now() > deadline) throw new Error(`${host.machine} did not finish installing the app.`);
100
- await sleep(500);
102
+ await cancellableSleep(500);
101
103
  delivery = await call(host, "device-host.app.attach", ids);
102
104
  }
103
105
  const appliedArguments = validHostedAppArguments(delivery.arguments) ? delivery.arguments : [];
@@ -1,8 +1,10 @@
1
- import { r as readWorkspaceState$1, x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
2
- import { a as bundleManifest, c as heldNoLonger, d as requireHostedAppMode, f as settle, g as upload, h as unknownSession, i as attach, l as hostedSession, m as sleep, n as PREPARE_TIMEOUT_MS, o as call, p as sha256, r as SESSION_TIMEOUT_MS, s as connectHost, t as INSTALL_TIMEOUT_MS } from "./hosted-client--hNFgixu.mjs";
3
- import { i as agentAccess, n as pullHostedNativeLogs, r as closeAgentConnection } from "./hosted-logs-Bkz0Hxzh.mjs";
4
- import { a as requireHostedMetro, i as requestHostedMetro, n as closeHostedMetro } from "./metro-gateway-BzlQZQmU.mjs";
5
- import { s as writeHostedNative } from "./ios-state-BsXMwo5y.mjs";
1
+ import { r as readWorkspaceState$1, x as workspaceDir } from "./workspace-state-DJt_MMvf.mjs";
2
+ import { x as runCancellationSignal } from "./tailnet-Dh-qiYzG.mjs";
3
+ import { t as cancellableSleep } from "./cancellation-C_22VQTH.mjs";
4
+ import { a as attach, c as connectHost, f as requireHostedAppMode, g as upload, h as unknownSession, i as SESSION_TIMEOUT_MS, l as heldNoLonger, m as sha256, n as OFFER_TIMEOUT_MS, o as bundleManifest, p as settle, r as PREPARE_TIMEOUT_MS, s as call, t as INSTALL_TIMEOUT_MS, u as hostedSession } from "./hosted-client-ZEKpS9vw.mjs";
5
+ import { i as agentAccess, n as pullHostedNativeLogs, r as closeAgentConnection } from "./hosted-logs-EzQM7-3Z.mjs";
6
+ import { a as requireHostedMetro, i as requestHostedMetro, n as closeHostedMetro } from "./metro-gateway-CX9Xlkq2.mjs";
7
+ import { s as writeHostedNative } from "./ios-state-CBLe1xYw.mjs";
6
8
  import { readFileSync, rmSync } from "node:fs";
7
9
  import { join } from "node:path";
8
10
  import { hostedNativeRecords, isJsonObject, parseHostedAndroidDevice, parseHostedChoice, parseHostedDevice, parseHostedNativeOffer, parseHostedNativePlacement, requireAutomaticMachine, unreadableHostedNative } from "@stim-cli/core/state";
@@ -24,8 +26,8 @@ async function prepareHostedNative(machine, selectors, recorded, platform = "ios
24
26
  if (recorded) {
25
27
  let session = null;
26
28
  try {
27
- session = await settle(host, await attach(host, recorded.session, void 0, platform), ["preparing"], PREPARE_TIMEOUT_MS, platform);
28
- session = await settle(host, session, ["stopping"], SESSION_TIMEOUT_MS, platform);
29
+ session = await settle(host, await attach(host, recorded.session, void 0, platform), ["preparing"], PREPARE_TIMEOUT_MS, platform, runCancellationSignal());
30
+ session = await settle(host, session, ["stopping"], SESSION_TIMEOUT_MS, platform, runCancellationSignal());
29
31
  } catch (error) {
30
32
  if (!heldNoLonger(error)) throw error;
31
33
  }
@@ -49,7 +51,7 @@ async function prepareHostedNative(machine, selectors, recorded, platform = "ios
49
51
  const offer = await call(host, "device-host.offer", {
50
52
  platform,
51
53
  ...selectors
52
- }, 45e3);
54
+ }, OFFER_TIMEOUT_MS);
53
55
  const parsedOffer = parseHostedNativeOffer(offer);
54
56
  const choice = platform === "ios" ? offer.platform === "ios" ? parseHostedChoice(offer.choice) : null : parsedOffer?.platform === "android" ? parsedOffer.choice : null;
55
57
  if (typeof offer.declined === "string") throw new Error(offer.declined);
@@ -109,7 +111,7 @@ async function placeHostedNative(target, { root, slot, bundle, handoff, bundleId
109
111
  }
110
112
  };
111
113
  reserved(placement);
112
- session = await settle(host, session, ["preparing"], PREPARE_TIMEOUT_MS, platform);
114
+ session = await settle(host, session, ["preparing"], PREPARE_TIMEOUT_MS, platform, runCancellationSignal());
113
115
  if (session.state !== "ready") throw unknownSession(host, session);
114
116
  const device = platform === "ios" ? parseHostedDevice(session.device) : parseHostedAndroidDevice(session.device);
115
117
  if (!device || device.architecture !== target.choice.architecture || "avdName" in device && "systemImage" in target.choice && (device.systemImage !== target.choice.systemImage || device.deviceProfile !== target.choice.deviceProfile)) throw new Error(platform === "ios" ? "The reserved simulator does not match the offered architecture." : "The reserved emulator does not match the offered architecture or selectors.");
@@ -182,7 +184,7 @@ async function placeHostedNative(target, { root, slot, bundle, handoff, bundleId
182
184
  break;
183
185
  } catch (offerError) {
184
186
  if (!String(offerError).includes("native operation in progress") || Date.now() >= fallbackDeadline) throw offerError;
185
- await sleep(Math.min(500, Math.max(0, fallbackDeadline - Date.now())));
187
+ await cancellableSleep(Math.min(500, Math.max(0, fallbackDeadline - Date.now())));
186
188
  }
187
189
  }
188
190
  }
@@ -194,7 +196,7 @@ async function placeHostedNative(target, { root, slot, bundle, handoff, bundleId
194
196
  while (delivery.state !== "installed") {
195
197
  if (delivery.state === "unknown") throw new Error(typeof delivery.notice === "string" ? delivery.notice : "App installation or launch is unknown.");
196
198
  if (Date.now() > deadline) throw new Error("App installation did not finish.");
197
- await sleep(500);
199
+ await cancellableSleep(500);
198
200
  delivery = await call(host, "device-host.app.attach", ids);
199
201
  }
200
202
  if (typeof delivery.notice === "string") note(delivery.notice);