stim 1.28.0 → 1.30.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 (155) hide show
  1. package/dist/{acquire-artifact-CKByBnTD.mjs → acquire-artifact-CrZ4rEbI.mjs} +1 -1
  2. package/dist/{act-8iswyfRa.mjs → act-BaKjDWGw.mjs} +479 -29
  3. package/dist/{activity-DRMg4_mD.mjs → activity-BTaUf0tc.mjs} +6 -5
  4. package/dist/{agent-device-usage-output-tE90fDdo.mjs → agent-device-usage-output-DYBpO17K.mjs} +4 -4
  5. package/dist/{android-YWCbmkVK.mjs → android-BCYLwmH6.mjs} +5 -5
  6. package/dist/{android-D577ApKG.mjs → android-BEQUDpOg.mjs} +1 -1
  7. package/dist/{android-CHmSU4B4.mjs → android-BWqdDK6R.mjs} +44 -42
  8. package/dist/{android-CsPs-7Mg.mjs → android-DdKG6lyD.mjs} +44 -35
  9. package/dist/{android-cas-_aDifWW0.mjs → android-cas-BH6K12__.mjs} +4 -4
  10. package/dist/{android-project-DUGMbq28.d.mts → android-project-CCEQyYJK.d.mts} +6 -2
  11. package/dist/api.d.mts +7 -4
  12. package/dist/api.mjs +27 -27
  13. package/dist/{apk-signed-tail-CQbwM0qO.mjs → apk-signed-tail-B8kw4a8K.mjs} +2 -2
  14. package/dist/{artifact-DYtHjxsn.mjs → artifact-DTHXcmQ3.mjs} +12 -12
  15. package/dist/{artifact-bFkfD3vf.mjs → artifact-M6W2l-xh.mjs} +12 -12
  16. package/dist/{auto-placement-BVqs8AJi.mjs → auto-placement-CZaWDmcY.mjs} +10 -10
  17. package/dist/{browser-web-BUaLcafY.mjs → browser-web-JQ7lFej3.mjs} +12 -12
  18. package/dist/{build-cQURy_KW.mjs → build-C2ZWoCmg.mjs} +23 -23
  19. package/dist/{build-cache-CZULpXVl.mjs → build-cache-DlC3owap.mjs} +4 -4
  20. package/dist/{build-plan-CxoYfxsc.mjs → build-plan-J3iRR3gI.mjs} +6 -6
  21. package/dist/{cache-manifest-DEjqGGat.mjs → cache-manifest-evF_zJ9U.mjs} +1 -1
  22. package/dist/cache-manifest.mjs +1 -1
  23. package/dist/{ccache-Bm_A1xX9.mjs → ccache-B8gY50-h.mjs} +18 -18
  24. package/dist/{cli-CpbaLDa7.mjs → cli-xRPXJPtA.mjs} +19 -19
  25. package/dist/cli.mjs +1 -1
  26. package/dist/{client-YxCer6ab.mjs → client-DrHykA24.mjs} +5 -5
  27. package/dist/collector-run.mjs +5 -5
  28. package/dist/{command-output-C8R1KIvi.mjs → command-output-BBW8eWPL.mjs} +1 -1
  29. package/dist/{config-Cn94Jc0g.mjs → config-AbUjIBOQ.mjs} +121 -19
  30. package/dist/{dependencies-DKeMzwXY.mjs → dependencies-vUh9mp5z.mjs} +39 -38
  31. package/dist/{dependency-state-CojA2o0t.mjs → dependency-state-CPKAKCZ8.mjs} +1 -1
  32. package/dist/{dev-client-D-BW5uiq.mjs → dev-client-CASgAOu7.mjs} +2 -2
  33. package/dist/device-ChnO7bR9.mjs +761 -0
  34. package/dist/device-CsIdRXfm.mjs +175 -0
  35. package/dist/{device-CgXfbcz5.mjs → device-android-CcdQqQWg.mjs} +28 -195
  36. package/dist/{device-capacity-Cd8lMSn3.mjs → device-capacity-C5C_jOQd.mjs} +11 -11
  37. package/dist/device-host-worker.mjs +44 -35
  38. package/dist/{device-ios-Cc9ulihb.mjs → device-ios-DbmtPIiw.mjs} +28 -18
  39. package/dist/{device-lease-run-Mtzp4THX.mjs → device-lease-run-Do6zYA7y.mjs} +4 -4
  40. package/dist/{device-pool-eRz6DtCg.mjs → device-pool-CpoYiCGO.mjs} +3 -3
  41. package/dist/{device-eeK95Lir.mjs → device-provision-B5Ms94qY.mjs} +11 -302
  42. package/dist/{doctor-xf7ht-5n.mjs → doctor-CJSB5q-s.mjs} +20 -20
  43. package/dist/{doctor-Bz_ouYAW.mjs → doctor-CLE4AZEI.mjs} +20 -15
  44. package/dist/{doctor-C2QyhejJ.mjs → doctor-CpfbYh3Q.mjs} +1 -1
  45. package/dist/doctor-fingerprint.mjs +1 -1
  46. package/dist/{doctor-watchman-BTW82PDC.mjs → doctor-watchman-D1IyMle9.mjs} +4 -4
  47. package/dist/{eas-build-Dm6q68QY.mjs → eas-build-DIDOHw2P.mjs} +2 -2
  48. package/dist/{eas-fallback-DajNpxf-.mjs → eas-fallback-DVS9oBSc.mjs} +4 -4
  49. package/dist/{eas-session-ledger-CBFo_Uo1.mjs → eas-session-ledger-CW3l-inB.mjs} +5 -5
  50. package/dist/{error-diagnostics-D1QfyJzQ.mjs → error-diagnostics-XJ9eWdtq.mjs} +8 -8
  51. package/dist/{gc-PLFwb0k4.mjs → gc-BVIcxCxE.mjs} +2 -2
  52. package/dist/{gc-DM5oMm-J.mjs → gc-Co7PE36D.mjs} +80 -18
  53. package/dist/{guide-C4I46XAk.mjs → guide-DkepBgHT.mjs} +235 -34
  54. package/dist/{hosted-android-DlaKLbW0.mjs → hosted-android-Du7NxufJ.mjs} +3 -3
  55. package/dist/{hosted-client-DDRm9hPJ.mjs → hosted-client-Cect92SZ.mjs} +3 -3
  56. package/dist/{hosted-logs-bSebOKbz.mjs → hosted-logs-Opcjv1Lr.mjs} +17 -8
  57. package/dist/{hosted-logs-sync-B0c53W_c.mjs → hosted-logs-sync-wsI7N1Hv.mjs} +7 -11
  58. package/dist/{hosted-macos-B7-8Pv4H.mjs → hosted-macos-BP9Kucat.mjs} +5 -5
  59. package/dist/{hosted-native-CDe33CSr.mjs → hosted-native-DmdLSmvu.mjs} +9 -8
  60. package/dist/{idle-shutdown-CQ0QwU9J.mjs → idle-shutdown-BcMN_cLm.mjs} +7 -7
  61. package/dist/{ios-B1HvafEG.mjs → ios-BFkBHuRT.mjs} +8 -8
  62. package/dist/{ios-tg4tp3q1.mjs → ios-CG0IsLtt.mjs} +29 -29
  63. package/dist/{ios-B1DYuOjh.mjs → ios-CXnoVO_z.mjs} +4 -4
  64. package/dist/{ios-device-B4elVFKi.mjs → ios-device-ClSfuu-_.mjs} +1 -1
  65. package/dist/{ios-project-CR4mZ7CH.mjs → ios-project-BM9TbTE7.mjs} +7 -7
  66. package/dist/{ios-state-BPHqMDdZ.mjs → ios-state-Ce_dystM.mjs} +1 -1
  67. package/dist/{js-swap-CVpSW1fn.mjs → js-swap-9Rx-5Nqz.mjs} +4 -4
  68. package/dist/{launch-DoySmhjz.mjs → launch-DvJV1Mx4.mjs} +19 -19
  69. package/dist/{lightened-DFAJgfIk.mjs → lightened-23pqe7LS.mjs} +4 -4
  70. package/dist/{logs-BGsW7iPe.mjs → logs-DJgZlf2K.mjs} +9 -8
  71. package/dist/{logs-DI5ILkYB.mjs → logs-Pkeh3wZk.mjs} +7 -6
  72. package/dist/{macos-Bo9st9Di.mjs → macos-DPvPQadc.mjs} +20 -20
  73. package/dist/{macos-C12RMJQF.mjs → macos-Du07NsOB.mjs} +1 -1
  74. package/dist/macos-run.mjs +1 -1
  75. package/dist/maintenance-run.mjs +13 -9
  76. package/dist/{metro-BnhXV2Mj.mjs → metro-BMQHczcf.mjs} +2 -2
  77. package/dist/{metro-request-DXyKjVDF.mjs → metro-request-BtF7ox53.mjs} +1 -1
  78. package/dist/{named-ports-Phoi2POD.mjs → named-ports-DcktE2Pw.mjs} +2 -2
  79. package/dist/{native-android-vxgtLD7w.mjs → native-android-CBOM1_gB.mjs} +16 -16
  80. package/dist/{native-gradle-artifact-inputs-BN96IVw8.mjs → native-gradle-artifact-inputs-D_iAfPuS.mjs} +3 -3
  81. package/dist/{native-runtime-DG4Rodzj.mjs → native-runtime-D4cTwU0Z.mjs} +6 -6
  82. package/dist/{native-xcode-inputs-BKarCoKg.mjs → native-xcode-inputs-BF-ogSnG.mjs} +2 -2
  83. package/dist/{native-xcode-ios-8A-efGa5.mjs → native-xcode-ios-DwJBfMP6.mjs} +15 -15
  84. package/dist/{ndjson-Dy2W4vRa.mjs → ndjson-CrjIsGzw.mjs} +2 -2
  85. package/dist/offload-worker.d.mts +1 -1
  86. package/dist/offload-worker.mjs +22 -22
  87. package/dist/{ownership-DJCq48IJ.mjs → ownership-Dtz9G5Gl.mjs} +2 -2
  88. package/dist/{phone-reverses-BzTa8g1F.mjs → phone-reverses-CvhhkGMH.mjs} +4 -4
  89. package/dist/{placement-log-Cvhta5ib.mjs → placement-log-CRR_TE1r.mjs} +1 -1
  90. package/dist/{plan-placement-WkZdccuN.mjs → plan-placement-CdLc-pTb.mjs} +6 -6
  91. package/dist/{ports-UV4mJgyC.mjs → ports-g4N_cfyg.mjs} +3 -3
  92. package/dist/{prebuild-k8d_tqOq.mjs → prebuild-DBJMhwSS.mjs} +9 -9
  93. package/dist/{project-Sui52ywT.mjs → project-DPQjnpcI.mjs} +15 -15
  94. package/dist/{react-native-android-DANlGGQf.mjs → react-native-android-idMWOwkX.mjs} +24 -24
  95. package/dist/{react-native-build-jUHnIfZ9.mjs → react-native-build-BSoh4HkH.mjs} +7 -7
  96. package/dist/{react-native-doctor-DCWRjS7K.mjs → react-native-doctor-CYibY8-4.mjs} +9 -8
  97. package/dist/{react-native-ios-BwMsFMXi.mjs → react-native-ios-13KIIOOy.mjs} +16 -15
  98. package/dist/{recordings-iy0mkm7b.mjs → recordings-CHMaF73C.mjs} +1 -1
  99. package/dist/{reload-Bj7QyuDy.mjs → reload-B9DZOjcV.mjs} +1 -1
  100. package/dist/{reload-c_uEyc_X.mjs → reload-BUQI3dSu.mjs} +14 -14
  101. package/dist/{remote-DFlpAqdV.mjs → remote-C-RGHhAP.mjs} +8 -8
  102. package/dist/{result-BIcXREyC.mjs → result-W4HCum4A.mjs} +16 -16
  103. package/dist/{run-y2HwyNvg.mjs → run-BQAmrohh.mjs} +2 -2
  104. package/dist/{selection-CXgM_VK_.mjs → selection-PCMT97XD.mjs} +105 -62
  105. package/dist/{server-bare-2N4vSRZG.mjs → server-bare-CEQdB_F4.mjs} +37 -1
  106. package/dist/{server-command-qneHPcRI.mjs → server-command-oqi3TDy7.mjs} +5 -5
  107. package/dist/server-expo-BUFAq2In.mjs +2 -0
  108. package/dist/{server-expo-Ccm9zB0o.mjs → server-expo-C1K07shx.mjs} +8 -5
  109. package/dist/{settings-Cfd_Q6ys.mjs → settings-CKlMOmhj.mjs} +2 -2
  110. package/dist/{settings-CY5JZlNN.mjs → settings-D776ygML.mjs} +1 -1
  111. package/dist/{settings-Djl-mpjX.mjs → settings-D9LtQaUw.mjs} +2 -1
  112. package/dist/{settings-payload-DwQiEMCn.mjs → settings-payload-CE-NZ6Lq.mjs} +4 -4
  113. package/dist/{settings-write-CJpjkeAd.mjs → settings-write-D7Xwa_-M.mjs} +5 -5
  114. package/dist/settings.schema.json +58 -9
  115. package/dist/{simslim-DCQwzoPy.mjs → simslim-CbpHERcv.mjs} +1 -1
  116. package/dist/{slot-launch-BpmanOnk.mjs → slot-launch-CeIK1iUI.mjs} +6 -6
  117. package/dist/{stage-CmugrSG5.mjs → stage-Blqe6bWb.mjs} +1 -1
  118. package/dist/{start-DYLk6GXn.mjs → start-B7J5a9nS.mjs} +11 -11
  119. package/dist/{start-CHH3zgIU.mjs → start-CvP2pJjc.mjs} +1 -1
  120. package/dist/{state-BXC1Lfxw.mjs → state-C2AUjjhg.mjs} +1 -1
  121. package/dist/{state-B2QJbDwz.mjs → state-D5ZxwCGJ.mjs} +2 -2
  122. package/dist/{stats-DxKqhcGp.mjs → stats-Uo7l8OAk.mjs} +4 -4
  123. package/dist/{status-7ULDEJ1e.mjs → status-CK7ZoEhV.mjs} +2 -2
  124. package/dist/{status-D_Ljc89p.mjs → status-CqJI1TgG.mjs} +1 -1
  125. package/dist/{status-BHCkOZga.mjs → status-_rWXFSO7.mjs} +24 -24
  126. package/dist/{status-watch-BmsPqYSU.mjs → status-watch-CnSyXUmj.mjs} +4 -4
  127. package/dist/status-worker.mjs +1 -1
  128. package/dist/{stim-desktop-CbWo21kb.mjs → stim-desktop-CYXLFpFS.mjs} +1 -1
  129. package/dist/{stop-b2pouxAO.mjs → stop-Bogo9oO2.mjs} +2 -2
  130. package/dist/{stop-DQvE-P76.mjs → stop-CMVfaA-6.mjs} +4 -4
  131. package/dist/{stop-D-dGE9gh.mjs → stop-CnF9ixYe.mjs} +20 -19
  132. package/dist/supervisor-run.d.mts +1 -0
  133. package/dist/supervisor-run.mjs +23 -19
  134. package/dist/{support-04IhBUTT.mjs → support-BGqpYMV8.mjs} +15 -11
  135. package/dist/{support-BtlJKjyQ.mjs → support-DUevTPur.mjs} +9 -9
  136. package/dist/{swiftpm-artifact-inputs-Cj2UpmPN.mjs → swiftpm-artifact-inputs-BcJk6-3u.mjs} +1 -1
  137. package/dist/{swiftpm-macos-BhF2stxY.mjs → swiftpm-macos-DBrmoocG.mjs} +8 -8
  138. package/dist/toolchain-Cw9VVHOY.mjs +2 -0
  139. package/dist/{toolchain-mLA_km-b.mjs → toolchain-DLdoyxIt.mjs} +19 -11
  140. package/dist/{trigger-DMou-X7j.mjs → trigger-CfnOfpDd.mjs} +1 -1
  141. package/dist/trigger-DBZ-GBrl.mjs +2 -0
  142. package/dist/{warm-progress-B0Vpuvpl.mjs → warm-progress-DQ2wQZKp.mjs} +3 -3
  143. package/dist/web-CI_qCRPw.mjs +2 -0
  144. package/dist/{web-BYmK0TjL.mjs → web-g9U7L1sR.mjs} +8 -8
  145. package/dist/web-run.mjs +5 -5
  146. package/dist/{workspace-state-kIZrdlSg.mjs → workspace-state-DGwkPXwq.mjs} +2 -2
  147. package/dist/{workspaces-CmOcceDN.mjs → workspaces-7_RWoi6c.mjs} +11 -11
  148. package/dist/{worktree-nliAoHxB.mjs → worktree-DEet9H3p.mjs} +1 -1
  149. package/dist/{worktree-2dk5edza.mjs → worktree-qKJ3x07S.mjs} +25 -25
  150. package/package.json +7 -7
  151. package/shim/bundle-response.cjs +37 -0
  152. package/dist/server-expo-WulkyAwT.mjs +0 -2
  153. package/dist/toolchain-qktiV8xc.mjs +0 -2
  154. package/dist/trigger-qp2ji5wE.mjs +0 -2
  155. package/dist/web-CrVLVQZY.mjs +0 -2
@@ -1,23 +1,24 @@
1
1
  import { D as ownership_claim_exports, S as process_identity_exports, c as throwIfCancelled, l as WorkspaceProcessCleanupError, m as declareSpawnsOn, t as getExecutor, v as stopDeclaringSpawnsOn, x as withDrainingCancellation } from "./exec-aULwtNly.mjs";
2
- import { E as workspaceDir, u as workspaceLastUsed } from "./workspace-state-kIZrdlSg.mjs";
3
- import { F as isOnMountedVolume, G as projectDeviceSlots, I as listMountedVolumes, L as measuredDirectorySizeAsync, N as directorySizeAsync, O as withConfigLockAsync$1, P as formatBytes, R as volumeRootFor, S as removeProject, _ as loadConfig$1, d as getConfigDir, j as acquireAvdClaim } from "./config-Cn94Jc0g.mjs";
4
- import { d as quotedPath$1, h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-C8R1KIvi.mjs";
2
+ import { E as workspaceDir, u as workspaceLastUsed } from "./workspace-state-DGwkPXwq.mjs";
3
+ import { F as isOnMountedVolume, G as projectDeviceSlots, I as listMountedVolumes, L as measuredDirectorySizeAsync, N as directorySizeAsync, O as withConfigLockAsync$1, P as formatBytes, R as volumeRootFor, S as removeProject, _ as loadConfig$1, d as getConfigDir, j as acquireAvdClaim } from "./config-AbUjIBOQ.mjs";
4
+ import { d as quotedPath$1, h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-BBW8eWPL.mjs";
5
5
  import { t as runOperationFile } from "./operation-exec-Dp4FuIGR.mjs";
6
- import { $t as TRASH_MANIFEST, Ft as matchWorktreeEntry, Wt as resolveSourceCheckoutAsync, Zt as TRASH_CLAIMS, en as deleteTrashEntry, jt as listWorktreesAsync } from "./settings-CY5JZlNN.mjs";
7
- import { i as findProjectRoot$1, v as detectIsExpo } from "./project-Sui52ywT.mjs";
8
- import { Ct as forgetCreatedDeviceAsync, F as listAvdsAsync, L as listOrphanedAvdDirectories, V as ownedAvdDirectory, ft as POOL_SETTING_REMEDY, h as avdNameAbsent, vt as parkedMaxSetting, wt as readCreatedDevices$1 } from "./android-CsPs-7Mg.mjs";
9
- import { $ as gradleVersionLines, $n as memoryCacheKind, B as includesArchives, Ct as describeError, En as runProcessOperation, F as gcOptionsOf, Ft as withEasProjectLock, G as planCacheEmptying, H as includesRecordings, J as selectsBeyondCaches, Jn as parseArchiveSelector, K as previewScopedEmptying, L as openGcLog, Q as deleteGradleVersions, St as deleteEasSessions, U as includesWorkspaceOutputs, V as includesParkedDevices, W as isWorkspacesScope, X as collectGradleVersions, Y as trimCaches, Zn as collectMemoryReport, _t as findStaleDeviceRecords, ar as scopedMemoryReport, at as DEVICE_LIST_TIMEOUT_MS, bt as withAndroidAvdSizes, ct as collectParkedSims, dt as deleteProjectDevices, er as memoryLines, et as gradleVersionsPending, fr as sizeCaches, gt as findOrphanedDevices, ht as eraseParkedDevices, ir as reclaimMemory, it as collectInventory, lt as deleteParkedAvds, mt as deviceSweepIsScoped, nr as memorySweepIsScoped, ot as collectDeviceLeases, pt as describeUnverifiableDevices, q as selectCaches, rr as memoryWorkPending, rt as getMachineCacheReport, sr as phase, st as collectParkedAvds, tr as memoryScope, tt as includesGradleVersions, ur as discoverCaches, ut as deleteParkedSims, vt as findStaleProjectDevices, wt as withRemoteSessionGcLocks, xt as collectEasSessionSweep, yt as unverifiedDeviceCommand, z as emptyCaches } from "./ccache-Bm_A1xX9.mjs";
10
- import { n as easMachineStateRoot$1, o as removeEasSessionClaimAsync, r as readEasSessionLedger$1 } from "./eas-session-ledger-CBFo_Uo1.mjs";
11
- import { At as mapLimited, Dt as createGcResults, Et as GC_OUTPUT, I as idleDeviceLines, M as collectIdleDevices, Mt as sizeConcurrency, N as collectIdleDevicesAsync, R as parseIdleDuration, a as collectOrphanedWorkspaces, b as workspaceInUseAsync, c as isInsideWorkspaces, f as rootPresence, g as ARTIFACT_DIRS, i as clearWorkspaceOutputs, jt as readConcurrency, kt as eachLimited, n as REBUILD_COST, o as collectWorkspaceOutputs, p as sizeText, r as WORKSPACE_OUTPUT_DIRS, s as deleteOrphanedWorkspaces, t as LIGHTEN_AFTER_MS, u as listWorkspaceDirs, v as withIdleWorkspace, wt as listBuildSlots, z as shutDownIdleDevices } from "./workspaces-CmOcceDN.mjs";
6
+ import { $t as TRASH_MANIFEST, Ft as matchWorktreeEntry, Wt as resolveSourceCheckoutAsync, Zt as TRASH_CLAIMS, en as deleteTrashEntry, jt as listWorktreesAsync } from "./settings-D776ygML.mjs";
7
+ import { i as findProjectRoot$1, v as detectIsExpo } from "./project-DPQjnpcI.mjs";
8
+ import { Ct as forgetCreatedDeviceAsync, I as listAvdsAsync, R as listOrphanedAvdDirectories, V as ownedAvdDirectory, ft as POOL_SETTING_REMEDY, h as avdNameAbsent, vt as parkedMaxSetting, wt as readCreatedDevices$1 } from "./android-DdKG6lyD.mjs";
9
+ import { $ as gradleVersionLines, $n as memoryCacheKind, B as includesArchives, Ct as describeError, En as runProcessOperation, F as gcOptionsOf, Ft as withEasProjectLock, G as planCacheEmptying, H as includesRecordings, J as selectsBeyondCaches, Jn as parseArchiveSelector, K as previewScopedEmptying, L as openGcLog, Q as deleteGradleVersions, St as deleteEasSessions, U as includesWorkspaceOutputs, V as includesParkedDevices, W as isWorkspacesScope, X as collectGradleVersions, Y as trimCaches, Zn as collectMemoryReport, _t as findStaleDeviceRecords, ar as scopedMemoryReport, at as DEVICE_LIST_TIMEOUT_MS, bt as withAndroidAvdSizes, ct as collectParkedSims, dt as deleteProjectDevices, er as memoryLines, et as gradleVersionsPending, fr as sizeCaches, gt as findOrphanedDevices, ht as eraseParkedDevices, ir as reclaimMemory, it as collectInventory, lt as deleteParkedAvds, mt as deviceSweepIsScoped, nr as memorySweepIsScoped, ot as collectDeviceLeases, pt as describeUnverifiableDevices, q as selectCaches, rr as memoryWorkPending, rt as getMachineCacheReport, sr as phase, st as collectParkedAvds, tr as memoryScope, tt as includesGradleVersions, ur as discoverCaches, ut as deleteParkedSims, vt as findStaleProjectDevices, wt as withRemoteSessionGcLocks, xt as collectEasSessionSweep, yt as unverifiedDeviceCommand, z as emptyCaches } from "./ccache-B8gY50-h.mjs";
10
+ import { n as easMachineStateRoot$1, o as removeEasSessionClaimAsync, r as readEasSessionLedger$1 } from "./eas-session-ledger-CW3l-inB.mjs";
11
+ import { At as mapLimited, Dt as createGcResults, Et as GC_OUTPUT, I as idleDeviceLines, M as collectIdleDevices, Mt as sizeConcurrency, N as collectIdleDevicesAsync, R as parseIdleDuration, a as collectOrphanedWorkspaces, b as workspaceInUseAsync, c as isInsideWorkspaces, f as rootPresence, g as ARTIFACT_DIRS, i as clearWorkspaceOutputs, jt as readConcurrency, kt as eachLimited, n as REBUILD_COST, o as collectWorkspaceOutputs, p as sizeText, r as WORKSPACE_OUTPUT_DIRS, s as deleteOrphanedWorkspaces, t as LIGHTEN_AFTER_MS, u as listWorkspaceDirs, v as withIdleWorkspace, wt as listBuildSlots, z as shutDownIdleDevices } from "./workspaces-7_RWoi6c.mjs";
12
12
  import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
13
- import { N as listBuildLocks, k as removeExpiredLease } from "./activity-DRMg4_mD.mjs";
14
- import { d as listAllIosSims, f as listAllIosSimsAsync } from "./ios-B1DYuOjh.mjs";
15
- import { r as readCollectors } from "./ownership-DJCq48IJ.mjs";
16
- import { A as deleteSelectedArchives, O as describeDereferenced, j as sweepArchiveStaging, k as reclaimProject } from "./worktree-2dk5edza.mjs";
17
- import { p as writeCacheFile } from "./warm-progress-B0Vpuvpl.mjs";
18
- import { a as restoreProblem, o as workspaceKeys } from "./lightened-DFAJgfIk.mjs";
19
- import { C as worktreeRemovalReason, S as worktreePullRequestNote, _ as ownedDeviceUsage, a as previewMaintenance, b as collectWorktreeSweep, c as deleteTempLeftovers, d as appRoots, f as artifactWorktrees, h as finishedWorkspaces, l as tempLeftoverLines, m as collectArtifactsAsync, o as triggeringRoot, p as clearArtifact, s as collectTempLeftovers, t as deleteIdleWorkspaceDevices, u as tempLeftoverSection, v as maintenancePinned, x as removeWorktrees, y as candidateRootsAsync } from "./act-8iswyfRa.mjs";
20
- import { i as getSwiftpmCacheUsage, n as swiftpmCacheLines, r as getAgentDeviceUsage, t as agentDeviceLines } from "./agent-device-usage-output-tE90fDdo.mjs";
13
+ import { N as listBuildLocks, k as removeExpiredLease } from "./activity-BTaUf0tc.mjs";
14
+ import { d as listAllIosSims, f as listAllIosSimsAsync } from "./ios-CXnoVO_z.mjs";
15
+ import { t as resolveMaintenanceSettings } from "./settings-D9LtQaUw.mjs";
16
+ import { r as readCollectors } from "./ownership-Dtz9G5Gl.mjs";
17
+ import { A as deleteSelectedArchives, O as describeDereferenced, j as sweepArchiveStaging, k as reclaimProject } from "./worktree-qKJ3x07S.mjs";
18
+ import { p as writeCacheFile } from "./warm-progress-DQ2wQZKp.mjs";
19
+ import { a as restoreProblem, o as workspaceKeys } from "./lightened-23pqe7LS.mjs";
20
+ import { C as candidateRootsAsync, D as worktreeRemovalReason, E as worktreePullRequestNote, S as maintenancePinned, T as removeWorktrees, _ as finishedWorkspaces, a as previewMaintenance, b as cachedDeviceActivity, c as deleteTempLeftovers, d as appRoots, f as artifactWorktrees, g as stopIdleWorkspace, h as planIdleStop, l as tempLeftoverLines, m as collectArtifactsAsync, o as triggeringRoot, p as clearArtifact, s as collectTempLeftovers, t as deleteIdleWorkspaceDevices, u as tempLeftoverSection, w as collectWorktreeSweep, x as cachedDeviceActivityAsync, y as ownedDeviceUsage } from "./act-BaKjDWGw.mjs";
21
+ import { i as getSwiftpmCacheUsage, n as swiftpmCacheLines, r as getAgentDeviceUsage, t as agentDeviceLines } from "./agent-device-usage-output-DYBpO17K.mjs";
21
22
  import { claimRemoveCommand, isClaimRefusal, isClaimUnavailable, readClaimSet, releaseClaim, tryAcquireClaim } from "@stim-cli/core/ownership-claim";
22
23
  import { existsSync, lstatSync, readFileSync, readdirSync, statSync } from "node:fs";
23
24
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -2192,6 +2193,65 @@ async function deleteParkedHostedDevices(devices, { listAvds: list, operation }
2192
2193
  return failures;
2193
2194
  }
2194
2195
  //#endregion
2196
+ //#region src/commands/gc/idle-workspaces.ts
2197
+ /**
2198
+ * Stops each workspace idle past its maintenance.idleStopHours, as automatic maintenance does, unless
2199
+ * maintenance.mode is off, so the dry run's maintenance plan lists every stop; returns failures.
2200
+ */
2201
+ async function stopIdleWorkspaces(output, operation) {
2202
+ const env = operation?.env ?? process.env;
2203
+ if (resolveMaintenanceSettings(void 0, env).mode === "off") return 0;
2204
+ const devices = () => {
2205
+ const now = Date.now();
2206
+ return operation ? cachedDeviceActivityAsync(now, env, operation.signal, operation) : cachedDeviceActivity(now);
2207
+ };
2208
+ const protectedRoot = triggeringRoot(operation);
2209
+ let plan;
2210
+ try {
2211
+ plan = await planIdleStop({
2212
+ protectedRoot,
2213
+ now: Date.now(),
2214
+ env,
2215
+ devices: devices(),
2216
+ operation
2217
+ });
2218
+ } catch (error) {
2219
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
2220
+ operation?.signal.throwIfAborted();
2221
+ output.log(chalk.red(`Could not plan idle workspace stops: ${error instanceof Error ? error.message : String(error)}`));
2222
+ return 1;
2223
+ }
2224
+ let failures = 0;
2225
+ for (const action of plan.actions) {
2226
+ operation?.signal.throwIfAborted();
2227
+ let outcome;
2228
+ try {
2229
+ outcome = await stopIdleWorkspace(action, {
2230
+ protectedRoot,
2231
+ devices,
2232
+ operation,
2233
+ by: "stim gc --delete"
2234
+ });
2235
+ } catch (error) {
2236
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
2237
+ operation?.signal.throwIfAborted();
2238
+ outcome = {
2239
+ status: "failed",
2240
+ bytes: 0,
2241
+ detail: error instanceof Error ? error.message : String(error)
2242
+ };
2243
+ }
2244
+ output.record("devServer", outcome.status, action.target, { detail: outcome.status === "done" ? action.reason : outcome.detail });
2245
+ if (outcome.status === "done") output.log(chalk.green(`Stopped the idle workspace ${action.target}: ${action.reason}`));
2246
+ else if (outcome.status === "kept") output.log(chalk.dim(`Kept the workspace ${action.target}: ${outcome.detail}`));
2247
+ else {
2248
+ failures++;
2249
+ output.log(chalk.red(`Could not stop the idle workspace ${action.target}: ${outcome.detail}`));
2250
+ }
2251
+ }
2252
+ return failures;
2253
+ }
2254
+ //#endregion
2195
2255
  //#region src/commands/gc.ts
2196
2256
  function readGcReport(options = {}, deps = {}) {
2197
2257
  return sweep({
@@ -3009,6 +3069,8 @@ async function runGcCore(opts, deps, execution, reportOnly = false) {
3009
3069
  }
3010
3070
  let deleteFailures = idleFailures;
3011
3071
  throwIfCancelled(signal, "GC");
3072
+ if (cache === null) deleteFailures += await stopIdleWorkspaces(output, deps.operation);
3073
+ throwIfCancelled(signal, "GC");
3012
3074
  deleteFailures += await deleteArchives(report.archives, output, signal);
3013
3075
  throwIfCancelled(signal, "GC");
3014
3076
  deleteFailures += report.workspaceOutputs ? (await clearWorkspaceOutputs(report.workspaceOutputs, {
@@ -3143,7 +3205,7 @@ async function runGcCore(opts, deps, execution, reportOnly = false) {
3143
3205
  return payload(deleteFailures);
3144
3206
  }
3145
3207
  function gcCommand(program) {
3146
- program.command("gc").description("Report what Stim has left behind: dead project entries, orphaned workspace directories, clean Stim-managed linked worktrees whose branch is merged or whose pull request was merged or closed, orphaned owned devices and EAS sessions, records of devices that no longer exist, build locks whose builder is gone, expired physical-device leases, the shared build caches, the build outputs and logs of each workspace, the memory of watchman and of the Gradle and Kotlin daemons, and recognized leftovers in TMPDIR. Reports by default; pass --delete to act.").option("--worktrees", "also remove clean, idle Stim-managed linked worktrees, not only merged ones: with --delete run `stim worktree remove` (never --force) on each; idle means unused for --older-than days, 7 without it").option("--delete", "actually prune the reported entries, reap the reported devices, lighten every workspace that is not building and ran no ios, android or macos command in the last 15 minutes by clearing its build outputs, a running dev server or booted device included, and trim its Metro, client and device logs to their newest 8 MiB").option("--older-than <days>", "also reap owned devices whose workspace has not been used this long, trim shared cache entries nothing has used in that time and device recordings made before it, and clear workspace build outputs only for workspaces idle this long and parked devices only once parked this long", (v) => {
3208
+ program.command("gc").description("Report what Stim has left behind: dead project entries, orphaned workspace directories, clean Stim-managed linked worktrees whose branch is merged or whose pull request was merged or closed, orphaned owned devices and EAS sessions, records of devices that no longer exist, build locks whose builder is gone, expired physical-device leases, the shared build caches, the build outputs and logs of each workspace, the memory of watchman and of the Gradle and Kotlin daemons, and recognized leftovers in TMPDIR. Reports by default; pass --delete to act.").option("--worktrees", "also remove clean, idle Stim-managed linked worktrees, not only merged ones: with --delete run `stim worktree remove` (never --force) on each; idle means unused for --older-than days, 7 without it").option("--delete", "actually prune the reported entries, reap the reported devices, lighten every workspace that is not building and ran no ios, android or macos command in the last 15 minutes by clearing its build outputs, a running dev server or booted device included, trim its Metro, client and device logs to their newest 8 MiB, and, unless maintenance.mode is off, stop each workspace idle past maintenance.idleStopHours as stim stop does").option("--older-than <days>", "also reap owned devices whose workspace has not been used this long, trim shared cache entries nothing has used in that time and device recordings made before it, and clear workspace build outputs only for workspaces idle this long and parked devices only once parked this long", (v) => {
3147
3209
  const n = parseInt(v, 10);
3148
3210
  if (!Number.isFinite(n) || String(n) !== String(v).trim()) throw new InvalidArgumentError("must be a whole number of days, e.g. --older-than 30");
3149
3211
  return n;
@@ -1,8 +1,8 @@
1
- import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-CY5JZlNN.mjs";
2
- import { i as findProjectRoot$1 } from "./project-Sui52ywT.mjs";
3
- import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-CBFo_Uo1.mjs";
4
- import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-BTW82PDC.mjs";
5
- import "./status-watch-BmsPqYSU.mjs";
1
+ import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-D776ygML.mjs";
2
+ import { i as findProjectRoot$1 } from "./project-DPQjnpcI.mjs";
3
+ import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-CW3l-inB.mjs";
4
+ import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-D1IyMle9.mjs";
5
+ import "./status-watch-CnSyXUmj.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
@@ -288,6 +288,12 @@ activity prevent reclaim. The supervisor's own idle shutdown default is 30m.
288
288
  Read the holder names in progress and build.waitingFor in status; do not start
289
289
  replacement runs while one is queued. See \`stim guide lifecycle concurrency\`.
290
290
 
291
+ After maintenance.idleStopHours (default 6) with no Stim command, native run,
292
+ Metro bundle or HMR request, agent-device command or live view, automatic
293
+ maintenance stops the workspace as stim stop does. Device and app logs do not
294
+ count. After a long pause, run stim ios or android again before driving the
295
+ app; see \`stim guide cleanup\`.
296
+
291
297
  Treat a refusal as an ownership or state mismatch: read its code and remedy.
292
298
  Never reach for --force first.
293
299
  Stim leaves externally started Metro servers alone. Stop them with their original
@@ -412,6 +418,7 @@ FULL TOPIC LIST
412
418
  stim guide lifecycle budget # disk and memory budgets, automatic reclaim
413
419
  stim guide lifecycle options # every flag, Android variants, --device-type, --system-image, --device-profile
414
420
  stim guide lifecycle devices # ios --device and android --device on a physical phone
421
+ stim guide lifecycle tools # device location|permission|push|network on the owned simulator or emulator
415
422
  stim guide lifecycle release # Release configurations and ...Release variants
416
423
  stim guide api # typed run, stop, diagnostics and cancellation from the main package
417
424
  stim guide facts # the --json payloads
@@ -697,7 +704,7 @@ Do not point independent Stim homes at a concurrently writable shared cache.
697
704
  //#endregion
698
705
  //#region src/guide/facts.ts
699
706
  const facts = {
700
- summary: "The --json payloads: `start`, `ios`, `android`, `web`, `ios|android --plan`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
707
+ summary: "The --json payloads: `start`, `ios`, `android`, `web`, `ios|android --plan`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `device location|permission|push|network`, `gc`, and the error contract",
701
708
  preamble: () => `SLOTS
702
709
  Named ios/android runs add slot to their JSON facts. Default-run fields remain
703
710
  compatible. status adds a slots array per environment with each named slot's
@@ -707,7 +714,7 @@ Named collector, lease-holder, and launch keys use platform:slot internally.
707
714
  FACTS CONTRACT
708
715
 
709
716
  \`start\`, \`ios\`, \`android\`, \`web\`, \`reload\`, \`stop\`, \`status\`, \`stats\`, \`doctor\`,
710
- \`gc\`, and \`device lock\`/\`device unlock\` each print exactly ONE line of JSON on
717
+ \`gc\`, \`device lock\`/\`device unlock\`, and \`device location|permission|push|network\` each print exactly ONE line of JSON on
711
718
  stdout for \`--json\`. Every other line goes to stderr, so it is always safe
712
719
  to pipe. \`logs --json\` is the one exception: it is NDJSON, one record per
713
720
  line by design (see \`guide logs\`), not this single-payload contract.
@@ -1236,9 +1243,10 @@ leased until <time>" for each one.`,
1236
1243
  null when off; plan lists what the next start, ios or
1237
1244
  android would reclaim, in the \`reclaimed\` shape without
1238
1245
  freedMb, and is empty while under budget
1239
- deviceHosts one { machine, state, dnsName?, deviceId?, requestedAt?, expiresAt?,
1240
- host? } per remote.machines entry. state is "approved",
1241
- "pending", "not-asked", "revoked", "lapsed", "key-changed", "outdated",
1246
+ deviceHosts one { machine, state, dnsName?, fingerprint?, deviceId?, requestedAt?,
1247
+ expiresAt?, host? } per remote.machines entry. state is "approved",
1248
+ "pending", "not-asked", "revoked", "lapsed", "key-changed",
1249
+ "key-unconfirmed", "outdated",
1242
1250
  "not-on-tailnet", "tailscale-off", "unreachable", "invalid",
1243
1251
  "credentials-unavailable" or "busy". Setup tickets stay private.
1244
1252
  Only --fix asks for access or forgets removed names. A
@@ -1254,7 +1262,12 @@ leased until <time>" for each one.`,
1254
1262
  expires, absent for a Stim Desktop ticket; "lapsed" is a
1255
1263
  pending request whose expiry passed. --fix asks again.
1256
1264
  "key-changed" means the worker did not prove the
1257
- stim-server key pinned at approval. "outdated" means its
1265
+ stim-server key pinned at approval. "key-unconfirmed" is a
1266
+ local: machine that approved this one but whose key no
1267
+ person confirmed, so nothing pinned it; fingerprint is the
1268
+ key's fingerprint to compare with the one stim-server setup
1269
+ printed there, and only stim doctor --fix in a terminal asks.
1270
+ A local: entry has no dnsName. "outdated" means its
1258
1271
  stim-server speaks protocol 1; the finding names the
1259
1272
  stim-server service update command to run there.
1260
1273
  toolchain { entries, projectNode } on macOS, else null. entries is one { name, value,
@@ -1267,11 +1280,12 @@ leased until <time>" for each one.`,
1267
1280
  pins Node (bin, version and match are null when no install
1268
1281
  fits the pin; match is "exact", or "major" for the newest
1269
1282
  install of the pinned major not older than the pin), else null
1270
- remoteMachines one { machine, state, diagnosis?, dnsName?, deviceId?, requestedAt?,
1271
- expiresAt?, offloadable?, reasons?, problems?, capacity?, host? } per
1283
+ remoteMachines one { machine, state, diagnosis?, dnsName?, fingerprint?, deviceId?,
1284
+ requestedAt?, expiresAt?, offloadable?, reasons?, problems?, capacity?, host? } per
1272
1285
  remote.machines entry, for its build approval; state is "approved", "pending", "not-asked",
1273
1286
  "revoked" (revoked or denied), "lapsed" (the request lapsed
1274
- before approval), "key-changed", "outdated",
1287
+ before approval), "key-changed", "key-unconfirmed" (as in
1288
+ deviceHosts), "outdated",
1275
1289
  "not-on-tailnet", "tailscale-off", "unreachable" or
1276
1290
  "invalid". diagnosis is { layer, code, title, message, remedy }
1277
1291
  for the first layer that stopped this machine, present for
@@ -1286,6 +1300,11 @@ leased until <time>" for each one.`,
1286
1300
  nothing behind the route), server-not-ready (503: running but
1287
1301
  not serving; its message gives the cause the server reports),
1288
1302
  server-no-answer (silent route while tailscale ping reaches the Mac), server-outdated and connect-failed (none of the above).
1303
+ A local: machine never reads Tailscale and reports
1304
+ lan-not-listening (nothing accepts connections on its
1305
+ stim-server port), lan-no-answer (no reply: the network, or
1306
+ the macOS firewall on that machine), server-not-ready or
1307
+ connect-failed.
1289
1308
  Tailscale's own "offline" flag lags a reachable peer, so an
1290
1309
  answer from the machine outranks it. host has the same shape and presence rule as in
1291
1310
  deviceHosts, as do expiresAt (a pending request's lapse
@@ -2041,7 +2060,7 @@ RULES
2041
2060
  Each booted simulator and detected emulator in environments (and in
2042
2061
  slots) carries activity; a shut-down or physical device has none:
2043
2062
 
2044
- activity { state, driver?, lastActivityAt?, recent?, basis }
2063
+ activity { state, driver?, lastActivityAt?, recent?, basis, unknown? }
2045
2064
 
2046
2065
  state "driven" a live claim or driver holds the device now
2047
2066
  "active" no driver, but activity in the last 10 minutes
@@ -2064,6 +2083,8 @@ RULES
2064
2083
  workspace-use, supervisor-start, page-log or viewer, each
2065
2084
  rounded down to the minute. viewer is now while a
2066
2085
  stim-server client streams the device's frames
2086
+ unknown for "driven" only: the checks that could not be read, in
2087
+ basis's vocabulary; absent when every check was read
2067
2088
  basis the evidence behind state, strongest first:
2068
2089
  agent-device-claim, agent-device-lease agent-device state,
2069
2090
  read only; live only when every recorded process is alive
@@ -2445,8 +2466,8 @@ RULES
2445
2466
  minutes. It caches them in $STIM_HOME/agent-sessions.json, which one-shot
2446
2467
  status reads and ignores once it is 2 minutes old. Both sources are other
2447
2468
  tools' internal files; a missing or changed one only drops its sessions.
2448
- \`start\`, \`ios\`, \`android\`, \`web\`, \`reload\` and \`worktree warm\`
2449
- also record the CLAUDE_CODE_SESSION_ID or CODEX_THREAD_ID of the shell
2469
+ \`start\`, \`ios\`, \`android\`, \`web\`, \`reload\`, \`logs\` and
2470
+ \`worktree warm\` also record the CLAUDE_CODE_SESSION_ID or CODEX_THREAD_ID of the shell
2450
2471
  that ran them, so that session is listed for 30 minutes after the command
2451
2472
  even when status cannot see it, and for as long as it runs.
2452
2473
 
@@ -2990,8 +3011,8 @@ WHAT THE SUPERVISOR IS
2990
3011
  (default 60; 0 never stops) with no bundle request, no client log record
2991
3012
  (in-app console logs; for Expo or metro.command, any stdout line of the
2992
3013
  dev server) and no Stim
2993
- command in the workspace (start, ios, android, reload, worktree warm). It
2994
- checks once a minute. It keeps running while a bundle response is in
3014
+ command in the workspace (start, ios, android, reload, logs, worktree
3015
+ warm). It checks once a minute. It keeps running while a bundle response is in
2995
3016
  flight, while a build in the workspace is in progress, while a stim ios,
2996
3017
  android or stop run holds the workspace's native-run lock, while the
2997
3018
  workspace holds an unexpired device lease (\`stim device lock\` or a
@@ -3024,8 +3045,9 @@ WHAT THE SUPERVISOR IS
3024
3045
  own stops show only in the log).
3025
3046
  requested a Stim command stopped it and says which: stim stop,
3026
3047
  stim worktree remove, stim gc --delete, stim start
3027
- --reset-cache, or budget reclaim (with the workspace whose
3028
- ios, android or start run reclaimed it)
3048
+ --reset-cache, budget reclaim (with the workspace whose
3049
+ ios, android or start run reclaimed it), or automatic
3050
+ maintenance with its idle reason (guide cleanup, IDLE STOP)
3029
3051
  signal a SIGTERM or SIGINT with no Stim stop request recorded,
3030
3052
  so it likely came from outside Stim (level warn)
3031
3053
  server-exited the dev server exited on its own (level error). Expo CLI
@@ -3627,7 +3649,9 @@ WHAT WRITES WHAT
3627
3649
  and, on Expo, one per dev-client manifest
3628
3650
  request (manifest_request_started, _finished,
3629
3651
  _failed: debug level, with platform and requestId;
3630
- launch verification reads them as progress)
3652
+ launch verification reads them as progress), and
3653
+ an hmr_update debug record, at most once a minute,
3654
+ when Metro pushes a Fast Refresh change to the app
3631
3655
  client.ndjson in-app console logs and redboxes -- BARE PROJECTS ONLY.
3632
3656
  In expo-child and command-child mode everything the
3633
3657
  dev server prints lands in metro.ndjson with raw: true,
@@ -4620,7 +4644,11 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
4620
4644
  then until SpringBoard has finished starting, which \`simctl launch\` needs.
4621
4645
  Booted alone does not end that wait. The failure names the udid and the wait.
4622
4646
  After boot, a process-spawn probe must finish within 30 seconds before
4623
- installation. If it fails, the refusal includes observed host memory pressure
4647
+ installation. A probe that times out while the simulator still reports Booted
4648
+ is retried for about three minutes, since a loaded host can leave a booted
4649
+ simulator unresponsive for a while; a timeout on a simulator that no longer
4650
+ reports Booted, and any other probe failure, refuse at once. If it
4651
+ fails, the refusal includes observed host memory pressure
4624
4652
  when available. Free memory before retrying under pressure; see
4625
4653
  \`stim guide lifecycle simslim\`. Booted alone does not prove readiness.
4626
4654
  The same probe lists the simulator's launchd jobs and requires a running
@@ -4692,6 +4720,35 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
4692
4720
  no token left in its \`state.json\` (its workspace directory was recreated).
4693
4721
  The remedy for that last one is \`stim device unlock\`, which releases by
4694
4722
  holder rather than by token.`
4723
+ },
4724
+ STIM_DEVICE_TOOL_TARGET: {
4725
+ summary: "a device tool found no owned, running simulator or emulator in that slot to act on",
4726
+ body: () => `STIM_DEVICE_TOOL_TARGET
4727
+ \`stim device location|permission|push|network\` act only on this workspace's
4728
+ own local simulator or emulator in the slot. The message says which check
4729
+ failed: the slot's device is hosted on another Mac, the workspace runs an
4730
+ EAS Simulator session, the slot has no owned device (a physical device
4731
+ reached with \`--device\` is never one), the recorded simulator is gone or not
4732
+ owned by this Stim home, or it is not booted or running. Permission and push
4733
+ also refuse when no app is recorded for the device. Run the platform command
4734
+ the remedy names (\`stim ios\` or \`stim android\`, with \`--slot\` for a named
4735
+ slot) and retry. No tool runs before this refusal.`
4736
+ },
4737
+ STIM_DEVICE_TOOL_UNSUPPORTED: {
4738
+ summary: "that device tool has no equivalent on that platform",
4739
+ body: () => `STIM_DEVICE_TOOL_UNSUPPORTED
4740
+ The platform lacks the action: Android cannot clear a simulated location
4741
+ (\`adb emu geo fix\` only sets one), iOS has no network switch, and Android
4742
+ has no simulated push. The remedy names the nearest thing.`
4743
+ },
4744
+ STIM_DEVICE_TOOL_FAILED: {
4745
+ summary: "simctl or adb failed, or the device did not report the change afterwards",
4746
+ body: () => `STIM_DEVICE_TOOL_FAILED
4747
+ The tool call exited non-zero or timed out, with its output in the message, or
4748
+ the read-back after an Android permission or network change did not show the
4749
+ requested state. For a permission, the app must declare the permission in its
4750
+ manifest; when it declares none of the service's permissions the call refuses
4751
+ with this code. Check the device with \`stim status\` and retry.`
4695
4752
  },
4696
4753
  STIM_DEVICE_WIRELESS_FAILED: {
4697
4754
  summary: "an iPhone paired over Wi-Fi timed out or dropped during install or launch; use the cable",
@@ -5711,8 +5768,11 @@ SpringBoard is back; an already slim simulator is not touched. Turn sound on
5711
5768
  for one device with Sound (iOS) or Media sound (Android) in its Stim Desktop
5712
5769
  options; the choice lasts until that device next boots. Android 14 and older images have no shell command that can
5713
5770
  set media volume, so startup warns, as it does whenever a mute is not
5714
- confirmed. Host volume, Android alarm and ringtone volumes, hosted devices and
5715
- physical devices are unchanged.
5771
+ confirmed. A hosted simulator or emulator on a named Mac is muted the same way
5772
+ after the host boots or adopts it (best effort; a failed mute is not reported
5773
+ to the client), and Stim Desktop's Sound options do not reach
5774
+ it. Host volume, Android alarm and ringtone volumes and physical devices are
5775
+ unchanged.
5716
5776
 
5717
5777
  Repeat step 3 whenever a NATIVE input changes. A JS-only edit needs nothing --
5718
5778
  that is what Fast Refresh over the running dev server is for. \`stim reload\` is
@@ -7904,7 +7964,7 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
7904
7964
 
7905
7965
  Warm registers the app it prepares, so \`stim status\` lists the workspace
7906
7966
  with phase "warming" while it runs and "ready" once it succeeds, until the
7907
- first start, ios, android, web or reload there or for 2 hours
7967
+ first start, ios, android, web, reload or logs there or for 2 hours
7908
7968
  (\`guide facts status\`). In a monorepo worktree root, that app is the one
7909
7969
  the source checkout has registered.
7910
7970
 
@@ -8430,6 +8490,60 @@ THE POOL: WHICH DEVICE AN ID-LESS \`--device\` PICKS
8430
8490
  The chosen device is on the phase line and in \`--json\` (\`udid\` or
8431
8491
  \`serial\`, plus \`deviceName\`), so an agent can hand the same id to its
8432
8492
  device tool.`
8493
+ },
8494
+ tools: {
8495
+ summary: "device location, permission, push and network: change the owned simulator or emulator and read it back",
8496
+ body: () => ` \`stim device location|permission|push|network\` change the workspace's own
8497
+ simulator or emulator. Each takes the platform first, like \`device lock\`,
8498
+ and \`--slot <name>\` and \`--json\`:
8499
+
8500
+ stim device location <ios|android> --set <lat,lng> # --set 45.5,-73.6
8501
+ stim device location ios --clear
8502
+ stim device permission <ios|android> <grant|revoke|reset> <service>
8503
+ stim device push ios --payload '<json with an "aps" key>'
8504
+ stim device network android <on|off>
8505
+
8506
+ THE TARGET is the slot's owned, booted simulator or emulator, resolved the
8507
+ way \`reload\` resolves it: the project record says \`owned\`, the ledger
8508
+ agrees, and the serial belongs to the recorded AVD. A hosted device, an EAS
8509
+ Simulator session, a physical device (\`--device\`), a device Stim does not
8510
+ own, and a device that is not running refuse with STIM_DEVICE_TOOL_TARGET and
8511
+ run no tool. An action the platform lacks (Android \`--clear\`, iOS network,
8512
+ Android push) refuses with STIM_DEVICE_TOOL_UNSUPPORTED. A tool call that
8513
+ fails, or a device that disagrees with the change afterwards, is
8514
+ STIM_DEVICE_TOOL_FAILED. A bad value is STIM_BAD_ARG.
8515
+
8516
+ \`--set\` takes latitude and longitude as ONE value so a negative latitude is
8517
+ not read as a flag. Android's \`adb emu geo fix\` takes longitude first; Stim
8518
+ swaps them. The emulator has no way to clear a location.
8519
+
8520
+ \`permission\` acts on the app of the slot's last launch, else the project's
8521
+ bundle id or Android package. iOS services are simctl's own: all, calendar,
8522
+ contacts, contacts-limited, location, location-always, media-library,
8523
+ microphone, motion, photos, photos-add, reminders, siri. iOS notifications
8524
+ and camera are not simctl services. Android services are calendar, camera,
8525
+ contacts, location, microphone, motion, notifications, photos; one service is
8526
+ one or two \`pm\` permissions. A permission the app did not declare is
8527
+ listed in \`skipped\` and the call succeeds when the app declares at least one;
8528
+ an app that declares none is STIM_DEVICE_TOOL_FAILED.
8529
+ \`push\` needs the app to hold notification permission on the simulator, which
8530
+ \`simctl privacy\` cannot grant: without it simctl answers "Source is not
8531
+ authorized" and the call is STIM_DEVICE_TOOL_FAILED; open the app and accept
8532
+ its prompt.
8533
+ Android \`reset\` revokes the permission and clears its user-set flags so
8534
+ the app asks again. A grant needs one of the
8535
+ service's permissions to read back granted; a revoke or reset needs all of
8536
+ them not granted, and a reset also no USER_SET or USER_FIXED flag. Changing a
8537
+ permission can terminate the running app on both platforms.
8538
+
8539
+ \`--json\` prints ONE line: { platform, slot, deviceId, deviceName, tool,
8540
+ action, ..., readBack }. \`readBack\` is read from the device after the change:
8541
+ Android permissions are { permissions: [{ name, granted }] } from
8542
+ \`dumpsys package\`, and Android network is { wifi, data } from \`settings get
8543
+ global wifi_on|mobile_data\`. \`readBack\` is null where the platform has no
8544
+ read: iOS location, permission and push, and Android location. Then the exit
8545
+ status of simctl or adb is the only confirmation; Stim never echoes the
8546
+ request as a read-back.`
8433
8547
  },
8434
8548
  release: {
8435
8549
  summary: "Release configurations and ...Release variants: Metro skipped, process-proven launch, the JS swap",
@@ -8689,6 +8803,52 @@ supervisor's idle rules and records (guide lifecycle budget). While the level is
8689
8803
  check also names abnormally large processes (guide lifecycle simslim) in
8690
8804
  status's maintenance block and the maintenance log.
8691
8805
 
8806
+ IDLE STOP: the idle check, and gc --delete unless maintenance.mode is off (its
8807
+ dry run lists them in the maintenance plan), stop a workspace whose dev server
8808
+ runs or whose owned simulator or emulator is booted once it has had no real
8809
+ activity for maintenance.idleStopHours (default 6; 0 never; machine or project
8810
+ layers; STIM_MAINTENANCE_IDLE_STOP_HOURS overrides; fractions work). Six hours
8811
+ outlasts a lunch break, a meeting or an agent's pause between tasks, and still
8812
+ frees the memory overnight. Real activity is the newest of: a Stim command in
8813
+ the workspace (start, ios, android, macos, web, reload, logs, worktree warm),
8814
+ the end of its last native build, the start, progress or end of a Metro
8815
+ bundle or manifest request, or an HMR update, in metro.ndjson, an agent-device command in the workspace's
8816
+ agent-device sessions, and an open stim-server live view of its device.
8817
+ Device and system log lines, in-app console logs, dev server output,
8818
+ collector writes and maintenance's own records never count, and an app that
8819
+ only stays connected does not either. The stop is stim stop's: the dev
8820
+ server stops, the owned devices shut down through centralized teardown
8821
+ (never deleted), and the port is released; device leases stay. A build, a
8822
+ held native-run or metro-start lock, a build lock or slot, a running macOS
8823
+ app, a hosted or remote session, an unexpired device lease, a managed tunnel
8824
+ or remote lock, a running owned Chrome, a device driver other than
8825
+ agent-device, a live agent-device claim with no session activity to judge,
8826
+ device activity, an emulator list or an emulator's AVD name that cannot be read keeps
8827
+ the workspace;
8828
+ the check decides again under the native-run and metro-start locks. Each stop
8829
+ is a maintenance_action line naming the idle time (gc --delete records itself
8830
+ as the requester), each workspace kept past the window a maintenance_skip line
8831
+ with the reason. The port is released, so status shows the workspace idle as
8832
+ after stim stop, and the supervisor_stopped line in metro.ndjson names
8833
+ automatic maintenance and the idle time as the requester. The next start, ios or android starts it
8834
+ again. An owned emulator the activity check missed keeps the workspace while
8835
+ adb lists it, and so does any emulator adb lists without an AVD name, such as
8836
+ a stale offline entry that adb kill-server clears. A dev server that may still run after its supervisor
8837
+ exited is kept until stim stop ends it. So is a dev server whose requests Stim
8838
+ does not record: an Expo project before SDK 54, which cannot load Stim's Metro config
8839
+ adapter, or a dev server an older Stim started, until stim stop and stim start
8840
+ restart it. Unlike the other actions, it can stop the workspace whose dev server
8841
+ supervisor or status --watch timer started the pass; a pass a command starts,
8842
+ gc --delete included, never stops the command's own workspace.
8843
+ A dev server run through metro.command is kept: Stim sees none of its
8844
+ bundle or HMR requests. A Metro log that cannot be read, or that rotated
8845
+ within the window, and agent-device sessions, a state.json or a stim-server
8846
+ viewer record that cannot be read or verified keep the workspace too. A STIM_HOME-scoped home never
8847
+ idle-stops, because its devices are machine-wide. maintenance.keep does not keep a workspace from idle
8848
+ stop, which deletes nothing; set maintenance.idleStopHours 0 at workspace
8849
+ scope instead.
8850
+ stim settings set maintenance.idleStopHours 1 --scope machine
8851
+
8692
8852
  In on mode a pass runs, cheapest to rebuild first:
8693
8853
  1. orphaned workspace directories whose project is gone, and registered
8694
8854
  caches whose directory no longer exists
@@ -8733,7 +8893,8 @@ live build lock, or in a Metro store with a running or unverifiable dev
8733
8893
  server. Anything the pass cannot verify is kept. A device is deleted only when
8734
8894
  its workspace is idle: no dev server, native run, build, lease, managed lock,
8735
8895
  driven or busy device, and no recorded use within the window. Below disk
8736
- pressure level 3 a pass never stops a dev server or watchman; removing a
8896
+ pressure level 3 a pass stops a dev server only by IDLE STOP above and never
8897
+ stops watchman; removing a
8737
8898
  finished worktree or orphaned directory does tear down that workspace's own
8738
8899
  dev server, owned devices and Chrome profile, as gc --delete does. ccache evicts by itself under
8739
8900
  caches.ccacheMaxGb.
@@ -9792,8 +9953,8 @@ WORKSPACE BUILD OUTPUTS
9792
9953
  1 keeps its own rules. A running, building, unverified or hosted macOS app
9793
9954
  keeps its workspace untouched.
9794
9955
  stim gc --delete --cache workspaces --older-than 7
9795
- Last use is the newest of the lastUsedAt that start, ios, android, reload
9796
- and worktree warm record in state.json, lastBuild.startedAt,
9956
+ Last use is the newest of the lastUsedAt that start, ios, android, reload,
9957
+ logs and worktree warm record in state.json, lastBuild.startedAt,
9797
9958
  supervisor.startedAt and the mtimes under logs/, so a dev server that keeps
9798
9959
  logging keeps its workspace in use.
9799
9960
  A workspace with none of those was last used when its workspace.json was
@@ -10060,7 +10221,7 @@ KEYS STIM READS
10060
10221
  restores stock services when Stim applied the profile. Absolute paths, root or
10061
10222
  symlink escapes, and missing files are refused before
10062
10223
  simulator creation. Remote and unowned simulators are
10063
- never changed.
10224
+ never slimmed.
10064
10225
  ios.signingIdentity e.g. "Apple Development: Jane (TEAMID5678)" -- the
10065
10226
  keychain identity to re-seal a \`--device\` build with,
10066
10227
  overriding the one Stim derives from the artifact's own
@@ -10529,6 +10690,8 @@ floors below; report measures and plans and deletes nothing; off disables it.
10529
10690
  STIM_HOME and CI make the mode off unless STIM_MAINTENANCE is set.
10530
10691
  maintenance.keep is a project setting: pin a workspace so a pass never clears
10531
10692
  its build outputs or removes its worktree.
10693
+ maintenance.idleStopHours takes machine or project layers, so one workspace can
10694
+ stop sooner, later or never.
10532
10695
  See \`guide cleanup\` for checks, plans and log paths.
10533
10696
 
10534
10697
  ${SETTINGS.filter((setting) => setting.key.startsWith("maintenance.") || /^caches\..*MaxGb$/.test(setting.key)).map((setting) => ` ${setting.key} ${setting.env ?? "project setting"} ${setting.default === void 0 ? "unset" : `default ${setting.default}`}
@@ -10697,6 +10860,38 @@ machine a \`priority\` in its JSON:
10697
10860
  A host reports its own load limit in its device offer; a stim-server older than
10698
10861
  that does not, and this machine's \`server.maxLoadPerCore\` stands in for it.
10699
10862
 
10863
+ REMOTE MACHINES ON THE LOCAL NETWORK
10864
+ A machine on the same local network, without Tailscale, is named
10865
+ \`local:<host>\`: its private IPv4 address or host name, with an optional
10866
+ stim-server port (default 7787). On the worker, a person first chooses where
10867
+ stim-server listens with the machine setting \`server.lanAddresses\`, a list of
10868
+ network interface names or private IPv4 addresses. It defaults to [], which
10869
+ listens on no local network address; wildcard, loopback, public and IPv6
10870
+ addresses are refused, and the running server applies a change within seconds.
10871
+ An interface name follows the interface onto whatever private network it
10872
+ joins, so name the address on a machine that moves between networks, and an
10873
+ interface only on a worker that stays put. Then the person runs the setup
10874
+ command \`stim doctor --fix\` prints here:
10875
+
10876
+ stim settings set server.lanAddresses '["10.0.0.92"]' # on the worker
10877
+ stim settings set remote.machines '["local:10.0.0.92"]' # on this machine
10878
+ stim doctor --fix
10879
+
10880
+ Every connection runs Stim's Noise handshake, so plain WebSocket carries it
10881
+ without TLS, and the address never identifies anyone. Nothing on a local network
10882
+ vouches for the worker's key, so \`stim-server setup\` prints the worker's server
10883
+ key fingerprint and \`stim doctor --fix\`, run by a person in a terminal, shows
10884
+ the fingerprint the worker answered with and pins the key only after they
10885
+ confirm it matches. Until then the entry reports key-unconfirmed and is not
10886
+ used. Agents never answer that question. The printed setup command carries the
10887
+ ticket, which is a credential: whoever spends it first, after setup stores it,
10888
+ gets the approval, and on a local network that takes only the ticket and a
10889
+ route to the worker, not tailnet membership. Agents show it only to the user.
10890
+ Offloaded builds and hosted Debug and
10891
+ Release runs work there; agent control of hosted apps needs a tailnet machine.
10892
+ \`stim-server pair\` puts \`ws://<address>:<port>\` in the phone pairing code
10893
+ when Tailscale is not running and \`server.lanAddresses\` is set.
10894
+
10700
10895
  Automatic membership is separate from approval. In Desktop Settings > Remote
10701
10896
  Machines, use Builds enabled and Simulators enabled for this machine or a
10702
10897
  configured remote. The equivalent machine settings list the excluded members;
@@ -10827,6 +11022,13 @@ answer, an incompatible Stim build, CPU, Xcode, simulator SDK or CocoaPods, no
10827
11022
  Bundler for an app whose Gemfile.lock pins CocoaPods, no iPhone simulator on
10828
11023
  the runtime \`stim ios\` builds for here, low disk, or busy. With Package.swift
10829
11024
  and no platform selection on a Mac, it also checks the macOS Xcode and SDK.
11025
+ A client with no Xcode and no simulator SDK, such as Linux or Windows, has no
11026
+ Xcode to match: the Mac's own Xcode, simulator SDK and CocoaPods are the
11027
+ build's toolchain, the client leaves pod install to it, and \`stim ios --remote
11028
+ <mac> --remote-build <mac>\` runs the app on that Mac's hosted simulator. If
11029
+ that pod install changes Podfile.lock or the Xcode project, the build fails
11030
+ with fingerprint-mismatch; run pod install once on a Mac and commit the
11031
+ result. A client with an Xcode still needs the same one.
10830
11032
  Two machines build for each other when their Stim releases share a build
10831
11033
  compatibility version, which changes only when what a worker builds, how it
10832
11034
  builds, or the build messages change; their Stim builds can differ. A
@@ -11135,7 +11337,7 @@ scope, so it needs no --scope. Run it from the workspace:
11135
11337
 
11136
11338
  \`stim status --json\` then reports hidden: true on that environment, and
11137
11339
  clients that read it list the workspace under Hidden. The next start, ios,
11138
- android, web, macos, reload or worktree warm in the workspace clears it, so
11340
+ android, web, macos, reload, logs or worktree warm in the workspace clears it, so
11139
11341
  a workspace in use is never hidden. \`worktree remove\` drops it with the
11140
11342
  workspace.
11141
11343
 
@@ -12082,11 +12284,10 @@ script such as mini-desktop.sh use these instead:
12082
12284
  quit stim stop (verified stop; the host frees the slot
12083
12285
  and removes the app's defaults)
12084
12286
  clean stim worktree remove
12085
- 3 concurrent slots concurrency.maxDevices on the host; one bundle id
12287
+ 3 concurrent slots concurrency.maxDevices on the host, counted apart
12288
+ from simulators and emulators; one bundle id
12086
12289
  slot per session
12087
12290
 
12088
- The host's own owned devices count toward concurrency.maxDevices.
12089
-
12090
12291
  The agent-device rows work once the host's agent field names agent-device.
12091
12292
 
12092
12293
  On macOS 27, agent-device screenshot of a hosted app can return an image of the
@@ -1,7 +1,7 @@
1
1
  import { c as throwIfCancelled } from "./exec-aULwtNly.mjs";
2
- import { c as call, l as connectHost } from "./hosted-client-DDRm9hPJ.mjs";
3
- import { i as requestHostedMetro } from "./metro-request-DXyKjVDF.mjs";
4
- import { a as stopHostedNative, i as prepareHostedNative, r as placeHostedNative } from "./hosted-native-CDe33CSr.mjs";
2
+ import { c as call, l as connectHost } from "./hosted-client-Cect92SZ.mjs";
3
+ import { i as requestHostedMetro } from "./metro-request-BtF7ox53.mjs";
4
+ import { a as stopHostedNative, i as prepareHostedNative, r as placeHostedNative } from "./hosted-native-DmdLSmvu.mjs";
5
5
  //#region src/device-host/hosted-android.ts
6
6
  async function prepareHostedAndroid(machine, selectors, recorded, mode) {
7
7
  return await prepareHostedNative(machine, selectors, recorded, "android", false, mode);
@@ -1,7 +1,7 @@
1
1
  import { c as throwIfCancelled, o as cancellableSleep } from "./exec-aULwtNly.mjs";
2
- import { Y as diagnoseConnectFailure, ot as resolveEndpoint } from "./config-Cn94Jc0g.mjs";
3
- import { t as BuildConnection } from "./client-YxCer6ab.mjs";
4
- import { g as configuredMachines } from "./selection-CXgM_VK_.mjs";
2
+ import { Y as diagnoseConnectFailure, st as resolveEndpoint } from "./config-AbUjIBOQ.mjs";
3
+ import { t as BuildConnection } from "./client-DrHykA24.mjs";
4
+ import { g as configuredMachines } from "./selection-PCMT97XD.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  import { lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
7
7
  import { join } from "node:path";