stim 1.23.1 → 1.24.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 (169) hide show
  1. package/README.md +3 -2
  2. package/dist/{acquire-artifact-BzYRDgaP.mjs → acquire-artifact-CEs02U2o.mjs} +2 -2
  3. package/dist/{act-vxiMwdf5.mjs → act-Cyvm8xYc.mjs} +40 -25
  4. package/dist/{activity-BpWUPgUm.mjs → activity-Dq3ZcdD8.mjs} +6 -6
  5. package/dist/{agent-device-usage-output-CUlLsbRt.mjs → agent-device-usage-output-CccomeE0.mjs} +5 -5
  6. package/dist/{android-C7sVmyI9.mjs → android-882m4hxX.mjs} +140 -46
  7. package/dist/{android-DtfRGLcc.mjs → android-BZppyPe_.mjs} +66 -46
  8. package/dist/{android-DR5lZ2Az.mjs → android-CX5IcRuf.mjs} +13 -3
  9. package/dist/{android-CLi6DSiS.mjs → android-DcztblCT.mjs} +5 -5
  10. package/dist/{android-cas-ngferVq2.mjs → android-cas-BtCOrNqb.mjs} +3 -3
  11. package/dist/android-cas-compiler.mjs +1 -1
  12. package/dist/api.d.mts +21 -4
  13. package/dist/api.mjs +32 -31
  14. package/dist/{artifact-Xvgibgzq.mjs → artifact-BR5VNArK.mjs} +17 -16
  15. package/dist/{artifact-DBI3DALs.mjs → artifact-Bdt_n9Jc.mjs} +17 -16
  16. package/dist/{artifact-platform-CXcmX_j3.mjs → artifact-platform-CMRc0M_r.mjs} +3 -3
  17. package/dist/{browser-web-BJN9ZHxB.mjs → browser-web-ycg9qWB8.mjs} +16 -17
  18. package/dist/{budget-3ivAK99e.mjs → budget-dPGuhNai.mjs} +101 -40
  19. package/dist/{build-Dv9s8Fz-.mjs → build-CaF574eS.mjs} +31 -28
  20. package/dist/{build-cache-Dv7RN200.mjs → build-cache-HFUQ9eLz.mjs} +152 -19
  21. package/dist/{build-plan-BmbdHQbr.mjs → build-plan-JsDUq4w1.mjs} +8 -7
  22. package/dist/{cache-manifest-DSeQjt-Q.mjs → cache-manifest-BPXRONJz.mjs} +1 -1
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{ccache-CH2EWGPB.mjs → ccache-CCn1S6qG.mjs} +6 -6
  25. package/dist/{cdp-3fwICjzi.mjs → cdp-BG3FJCCx.mjs} +1 -1
  26. package/dist/{chrome-Bbw689-6.mjs → chrome-BvV8ssI3.mjs} +1 -1
  27. package/dist/{cli-BkK6Wr5i.mjs → cli-xqAidP7O.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-B4MMzfo_.mjs → client-18-ZowoT.mjs} +254 -28
  30. package/dist/collector-run.mjs +6 -6
  31. package/dist/{command-output-YKGWivpG.mjs → command-output-DxC0k2rk.mjs} +3 -2
  32. package/dist/{config-DlrsduwG.mjs → config-BZhXY15H.mjs} +3 -3
  33. package/dist/{created-devices-x9rN6bhs.mjs → created-devices-D2Aca-xu.mjs} +6 -2
  34. package/dist/{dependency-state-1I9KZT1Y.mjs → dependency-state-C56ll9hY.mjs} +2 -2
  35. package/dist/{detached-entry-BwNEtIrP.mjs → detached-entry-KmieOKgN.mjs} +1 -1
  36. package/dist/{dev-client-BFxiDpkf.mjs → dev-client-w_fok0Ek.mjs} +3 -3
  37. package/dist/{device-B7ljwccX.mjs → device-4RUugw5X.mjs} +16 -16
  38. package/dist/{device-CiNYxqp6.mjs → device-BktRGdjS.mjs} +40 -44
  39. package/dist/{device-capacity-DH0QsZYZ.mjs → device-capacity-Ic-kdmEV.mjs} +20 -16
  40. package/dist/device-host-worker.mjs +17 -17
  41. package/dist/{device-ios-CbVDtDIy.mjs → device-ios-DzpSlZyd.mjs} +23 -52
  42. package/dist/{device-lease-run-DXPSwdbb.mjs → device-lease-run-DUtkbqBQ.mjs} +5 -5
  43. package/dist/{device-pool-B4iOXIrD.mjs → device-pool-CgBHk401.mjs} +3 -3
  44. package/dist/{doctor-DRu-8ld6.mjs → doctor-BZ6oxNum.mjs} +1 -1
  45. package/dist/{doctor-HUC1igzw.mjs → doctor-C33AzVfR.mjs} +28 -28
  46. package/dist/{doctor-C6t4Maue.mjs → doctor-DZgpqR6J.mjs} +14 -14
  47. package/dist/{doctor-fingerprint-DZLoYFVb.mjs → doctor-fingerprint-zlujA1Gs.mjs} +1 -1
  48. package/dist/doctor-fingerprint.mjs +1 -1
  49. package/dist/{doctor-watchman-iGBpC6KM.mjs → doctor-watchman-B453A231.mjs} +5 -5
  50. package/dist/{eas-build-DMWSSvxq.mjs → eas-build-CxKUNHsb.mjs} +4 -4
  51. package/dist/{eas-fallback-vKlrqxgE.mjs → eas-fallback-LMxk9Kw0.mjs} +14 -14
  52. package/dist/{eas-session-ledger-BQF9Yyy9.mjs → eas-session-ledger-Ck6YXPAO.mjs} +12 -8
  53. package/dist/{error-diagnostics-DYsjJIHz.mjs → error-diagnostics-BkKCZq4P.mjs} +17 -42
  54. package/dist/{exec-DEoAhcze.mjs → exec-VFRpu1iA.mjs} +116 -28
  55. package/dist/{gc-dDE4QPVu.mjs → gc-DDWEAj0w.mjs} +2 -2
  56. package/dist/{gc-BW8E1uSC.mjs → gc-yVKpAOKM.mjs} +205 -28
  57. package/dist/{guide-DYYEO3Wz.mjs → guide-Bggftwc5.mjs} +222 -59
  58. package/dist/{hosted-android-xcfgCgSF.mjs → hosted-android-D4dweBof.mjs} +4 -4
  59. package/dist/{hosted-client-Bt-tndxV.mjs → hosted-client-BBTVe3X6.mjs} +4 -4
  60. package/dist/{hosted-ios-y19jCYFF.mjs → hosted-ios-Sn0djzg8.mjs} +1 -1
  61. package/dist/{hosted-logs-DzJKzKlj.mjs → hosted-logs-CYIZ5ubJ.mjs} +11 -6
  62. package/dist/{hosted-macos-BJusKvqL.mjs → hosted-macos-CXjsUNBR.mjs} +7 -7
  63. package/dist/{hosted-native-BmQC6U_x.mjs → hosted-native-Doxbfzem.mjs} +58 -11
  64. package/dist/{idle-shutdown-CJmUOV5x.mjs → idle-shutdown-BInjLKqm.mjs} +10 -10
  65. package/dist/{ios-CWjqfSm_.mjs → ios-B1FXRCMX.mjs} +71 -44
  66. package/dist/{ios-DTOYZGMJ.mjs → ios-BItP6lkn.mjs} +8 -8
  67. package/dist/{ios-hcBpnEGk.mjs → ios-CVUFFZ6C.mjs} +70 -13
  68. package/dist/{ios-xtlRHaeB.mjs → ios-ENC4sRPA.mjs} +1 -1
  69. package/dist/{ios-device-BXZ0c7Kb.mjs → ios-device-B6HK951C.mjs} +1 -1
  70. package/dist/{ios-device-DFGuwF4U.mjs → ios-device-BI38NFFH.mjs} +3 -3
  71. package/dist/{ios-project-CSZYI1iu.mjs → ios-project-KYqeJURj.mjs} +5 -5
  72. package/dist/{ios-signing-BtAffm0A.mjs → ios-signing-4c_qXvQm.mjs} +2 -2
  73. package/dist/{ios-state-Dtw5K2aI.mjs → ios-state-DlElquYD.mjs} +15 -7
  74. package/dist/{js-swap-BSBHldmm.mjs → js-swap-BvrQvXHY.mjs} +7 -6
  75. package/dist/{launch-CP2wDCVd.mjs → launch-BVlyQw3T.mjs} +51 -49
  76. package/dist/{launch-D-zq8SHG.mjs → launch-SfzGH_s9.mjs} +48 -29
  77. package/dist/{logs-pNvA2hHK.mjs → logs-DXE32kyb.mjs} +16 -9
  78. package/dist/{logs-By5aw3g9.mjs → logs-ovlU7m7N.mjs} +8 -6
  79. package/dist/{macos-CPMahOC2.mjs → macos-B3BveDrU.mjs} +1 -1
  80. package/dist/{macos-C67FZ2ft.mjs → macos-CCfhb-jT.mjs} +49 -42
  81. package/dist/macos-run.mjs +1 -1
  82. package/dist/maintenance-run.mjs +7 -7
  83. package/dist/{metro-DiXtA3Ty.mjs → metro-Bu8LBfzS.mjs} +4 -4
  84. package/dist/{metro-gateway-CKZqKqx7.mjs → metro-gateway-DtsOy-0P.mjs} +3 -4
  85. package/dist/{named-ports-DkEzOfzO.mjs → named-ports-BWDuU5oQ.mjs} +3 -3
  86. package/dist/{native-android-_MWSs3PP.mjs → native-android-96BBizbq.mjs} +17 -17
  87. package/dist/{native-gradle-artifact-inputs-DHFnmrVf.mjs → native-gradle-artifact-inputs-BcLYBZil.mjs} +5 -5
  88. package/dist/{native-run-Dv88i0aU.mjs → native-run-BmH7U8pr.mjs} +6 -6
  89. package/dist/{native-runtime-DBRfY_PN.mjs → native-runtime-DgtJkzIa.mjs} +10 -9
  90. package/dist/{native-source-Y0yLhFyQ.mjs → native-source-D-4Dh4JU.mjs} +7 -4
  91. package/dist/{native-xcode-inputs-CqViUh3r.mjs → native-xcode-inputs-irplbQb0.mjs} +2 -2
  92. package/dist/{native-xcode-ios-vFgqL_yS.mjs → native-xcode-ios-BY-6hh6M.mjs} +18 -18
  93. package/dist/offload-worker.d.mts +7 -2
  94. package/dist/offload-worker.mjs +75 -41
  95. package/dist/{operation-exec-BW0em61G.mjs → operation-exec-CUZifp6Z.mjs} +2 -25
  96. package/dist/{ownership-C5fo5Edb.mjs → ownership-DxlZGDcV.mjs} +3 -3
  97. package/dist/{page-DBL2PiUU.mjs → page-CzEA_-5_.mjs} +2 -3
  98. package/dist/phone-reverses-BdsdesVF.mjs +57 -0
  99. package/dist/{placement-log-BnGgJRRZ.mjs → placement-log-DUvqqsB-.mjs} +1 -1
  100. package/dist/{plan-placement-cr0fEU7b.mjs → plan-placement-4axc0Hs7.mjs} +3 -3
  101. package/dist/{ports-DpXjKkSV.mjs → ports-D-E_OiAO.mjs} +3 -3
  102. package/dist/{prebuild-BligW0QS.mjs → prebuild-DmVCf5xb.mjs} +14 -9
  103. package/dist/{project-DhCtQWWU.mjs → project-Dz-hWkb-.mjs} +21 -17
  104. package/dist/{pull-request-W1IuLXDt.mjs → pull-request-CbNlkFok.mjs} +2 -2
  105. package/dist/pull-requests.mjs +1 -1
  106. package/dist/{react-native-android-ZlhQfhvq.mjs → react-native-android-DOinxgwB.mjs} +75 -32
  107. package/dist/{react-native-build-CelbTO_y.mjs → react-native-build-AuCu-aAP.mjs} +22 -19
  108. package/dist/{react-native-doctor-LTIaP7lv.mjs → react-native-doctor-2ivJUmwZ.mjs} +10 -9
  109. package/dist/{react-native-ios-C5W0SA6f.mjs → react-native-ios-D5zTIuH8.mjs} +38 -22
  110. package/dist/{recordings-CQmfzAh7.mjs → recordings-CdPwYwvs.mjs} +1 -1
  111. package/dist/{registration-BcRgF6Ox.mjs → registration-CN6nlhcD.mjs} +1 -1
  112. package/dist/{reload-COJWTbae.mjs → reload-C1TTVesC.mjs} +144 -42
  113. package/dist/{reload-QcwnYLYV.mjs → reload-Ck9RJeSq.mjs} +1 -1
  114. package/dist/{remote-DR8qUERM.mjs → remote-DEZ7AOVq.mjs} +7 -7
  115. package/dist/{result-utnBea7x.mjs → result-DqBrb12U.mjs} +40 -17
  116. package/dist/{run-DidHghD1.mjs → run-BIwoU44q.mjs} +2 -2
  117. package/dist/{selection-DSMbWEX2.mjs → selection-BLtvaqxc.mjs} +11 -5
  118. package/dist/{server-bare-CafzuyFB.mjs → server-bare-Z1ToVLPn.mjs} +2 -2
  119. package/dist/{server-command-B9o92sLM.mjs → server-command-C0pmjNdG.mjs} +5 -5
  120. package/dist/server-expo-CEntXzRw.mjs +2 -0
  121. package/dist/{server-expo-BXrWxNYh.mjs → server-expo-Tt_hLRpy.mjs} +8 -5
  122. package/dist/{settings-C7O8A6ZI.mjs → settings-RKwY33wv.mjs} +114 -19
  123. package/dist/{settings-PfJx8uK1.mjs → settings-kkt0vP4w.mjs} +1 -1
  124. package/dist/{settings-write-Chuy7Cte.mjs → settings-write--gj6MACV.mjs} +7 -7
  125. package/dist/settings.schema.json +13 -0
  126. package/dist/{simslim-BNckWpXi.mjs → simslim-CdWKT3vA.mjs} +2 -2
  127. package/dist/{slot-launch-B7AuoWJv.mjs → slot-launch-A1BgotaM.mjs} +6 -6
  128. package/dist/{stage-C4u17aES.mjs → stage-ERTMh88n.mjs} +2 -3
  129. package/dist/{start-CU8mCPC7.mjs → start-BKGrEhzG.mjs} +75 -35
  130. package/dist/{start-BL_BsiWt.mjs → start-Bmg_qmHi.mjs} +1 -1
  131. package/dist/{state--smjFSTL.mjs → state-B1ig0Kqy.mjs} +4 -4
  132. package/dist/{state-08I3hw3_.mjs → state-BfAltYJP.mjs} +2 -2
  133. package/dist/{stats-CO6sK0Nh.mjs → stats-B-ckuiUg.mjs} +5 -5
  134. package/dist/{stats-report-BzaPrRm6.mjs → stats-report-n2U5plhk.mjs} +1 -1
  135. package/dist/{status-_WPHzVft.mjs → status-DfFp6a76.mjs} +24 -24
  136. package/dist/{status-BRROykC8.mjs → status-Fect2w9R.mjs} +1 -1
  137. package/dist/{status-CrJutl6-.mjs → status-Pw-807f0.mjs} +1 -1
  138. package/dist/{status-watch-BHFasOZN.mjs → status-watch-XC7F-AMf.mjs} +5 -5
  139. package/dist/status-worker.mjs +1 -1
  140. package/dist/stim-clonefile.c +18 -0
  141. package/dist/{stim-desktop-D5OGpYZM.mjs → stim-desktop-DS0mzR8U.mjs} +2 -2
  142. package/dist/{stop-iuFHjUST.mjs → stop-BFu7X_Do.mjs} +2 -2
  143. package/dist/{stop-BJ06ipTZ.mjs → stop-CL1kDHds.mjs} +55 -21
  144. package/dist/{stop-CR5689oB.mjs → stop-DhclRwOO.mjs} +5 -5
  145. package/dist/supervisor-run.mjs +16 -16
  146. package/dist/{support-TWuQlHQo.mjs → support-B1W-hmC2.mjs} +8 -8
  147. package/dist/{support-CbXPbUMJ.mjs → support-B3tzVhKn.mjs} +6 -6
  148. package/dist/{swiftpm-artifact-inputs-DFcGsXDP.mjs → swiftpm-artifact-inputs-BWYPj9Sn.mjs} +4 -4
  149. package/dist/{swiftpm-macos-DbwGCpZg.mjs → swiftpm-macos-BVCP5mO4.mjs} +14 -13
  150. package/dist/{toolchain-XkA2PfJZ.mjs → toolchain-BjgKdoEf.mjs} +1 -1
  151. package/dist/{toolchain-B9hCFCQw.mjs → toolchain-D3bmRMia.mjs} +57 -36
  152. package/dist/trigger-BLsHgAGR.mjs +2 -0
  153. package/dist/{trigger-Cbyc41d_.mjs → trigger-CBMe2YLH.mjs} +2 -2
  154. package/dist/{warm-progress-CA3TgT3-.mjs → warm-progress-ol0ZypEu.mjs} +6 -6
  155. package/dist/{web-DRF_oFXk.mjs → web-BH7peScT.mjs} +12 -10
  156. package/dist/web-BdOFlTJr.mjs +2 -0
  157. package/dist/web-run.mjs +8 -9
  158. package/dist/windows-report.mjs +12 -1
  159. package/dist/windows-report.ps1 +1 -1
  160. package/dist/{workspace-state-U08dEzhG.mjs → workspace-state-CeBpIZgr.mjs} +11 -4
  161. package/dist/{workspaces-e41xsjKr.mjs → workspaces-CSV2Orf4.mjs} +36 -32
  162. package/dist/{worktree-BEwxVwKF.mjs → worktree-DEDUzO_L.mjs} +1 -1
  163. package/dist/{worktree-B4Nj3EGS.mjs → worktree-Dw8kfacb.mjs} +324 -99
  164. package/dist/{xcode-Rq744mBF.mjs → xcode-DHu41qQ4.mjs} +41 -27
  165. package/package.json +7 -7
  166. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +0 -211
  167. package/dist/server-expo-Ddr8cG_c.mjs +0 -2
  168. package/dist/trigger-yb_nFzPF.mjs +0 -2
  169. package/dist/web-kDE9Myoy.mjs +0 -2
@@ -1,47 +1,49 @@
1
- import { c as declareSpawnsOn, f as stopDeclaringSpawnsOn, g as process_identity_exports, m as operationState, n as isTimeoutError, r as WorkspaceProcessCleanupError, t as getExecutor, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
1
+ import { D as ownership_claim_exports, S as process_identity_exports, b as operationState, l as WorkspaceProcessCleanupError, m as declareSpawnsOn, n as isTimeoutError, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-VFRpu1iA.mjs";
2
2
  import { d as workspaceDir, l as workspaceAgentDeviceDir } from "./paths-DQtTgsBf.mjs";
3
- import { E as upsertProject, G as projectDeviceSlots, L as measuredDirectorySizeAsync, S as removeProject, _ as loadConfig$1, a as clearDevice, d as getConfigDir, g as isPathPrefix, j as acquireAvdClaim, p as getProject } from "./config-DlrsduwG.mjs";
4
- import { a as formatElapsed, h as shortUdid, i as formatDuration, l as phaseLine, p as releasedLeaseFact, u as plural } from "./command-output-YKGWivpG.mjs";
5
- import { c as gitQuiet, o as git, r as childEnvironment, s as gitAsync, t as runOperationFile } from "./operation-exec-BW0em61G.mjs";
6
- import { i as recordWorkspaceUse, r as readWorkspaceState$1 } from "./workspace-state-U08dEzhG.mjs";
7
- import { At as readWorktreeExclude, Bt as warmWorktreePaths, Ct as isPodInstallChurn, Dt as locallyKnownUpstream, Et as listWorktreesAsync, Ft as resolveFullRefAsync, K as resolveIosProjectDir, Lt as restoreFileAsync, Pt as resolveFullRef, Rt as sourceCheckoutOf, St as hasUncommittedWorkAsync, Y as resolveSettings, a as SETTING_SHAPE_REMEDY, bt as hasPopulatedSubmodulesAsync, dt as branchExistsAsync, et as settingShapeErrors, ft as cloneIgnoredEntries, gt as dirtyPathsAsync, it as unknownSettingKeys, jt as removeWorktreeAsync, kt as podsOutOfSync, mt as depsOutOfSync, pt as deleteBranchAsync, q as resolveProjectSettings, vt as gitCommonDirAsync, xt as hasRemoteAsync, yt as gitCommonDirOnDisk, z as readCommittedSettings, zt as unpushedCommitsAsync } from "./settings-C7O8A6ZI.mjs";
8
- import { F as readRemoteSessionId, M as readMetroTunnel, O as clearManagedMetroTunnel, P as readRemoteSession, T as MODE_COMMAND, i as findProjectRoot$1, k as clearRemoteSession, o as isMobileProject } from "./project-DhCtQWWU.mjs";
9
- import { t as macosAppPresent } from "./state-08I3hw3_.mjs";
10
- import { c as pidExists, d as resolveProjectMetro, p as signalProcessTreeAsync, r as killMetroTreeAsync } from "./metro-DiXtA3Ty.mjs";
11
- import { o as readWebRecord } from "./state--smjFSTL.mjs";
12
- import { In as runProcessOperation, S as withdrawDevServerStopRequest, b as requestDevServerStop, br as discoverCaches, c as readVolumeSpace, l as readVolumeSpaceAsync, nt as planCacheEmptying, o as machineNumber, qn as resolveEasCliBin, u as resolveBudget, zt as endRecordedSession } from "./budget-3ivAK99e.mjs";
3
+ import { E as upsertProject, G as projectDeviceSlots, L as measuredDirectorySizeAsync, O as withConfigLockAsync$1, S as removeProject, _ as loadConfig$1, a as clearDevice, d as getConfigDir, g as isPathPrefix, j as acquireAvdClaim, p as getProject } from "./config-BZhXY15H.mjs";
4
+ import { a as formatElapsed, h as shortUdid, i as formatDuration, l as phaseLine, p as releasedLeaseFact, u as plural } from "./command-output-DxC0k2rk.mjs";
5
+ import { c as gitQuiet, o as git, r as childEnvironment, s as gitAsync, t as runOperationFile } from "./operation-exec-CUZifp6Z.mjs";
6
+ import { a as recordWorkspaceUseAsync, l as withWorkspaceStateLockAsync, r as readWorkspaceState$1 } from "./workspace-state-CeBpIZgr.mjs";
7
+ import { At as readWorktreeExclude, Bt as warmWorktreePaths, Ct as isPodInstallChurn, Dt as locallyKnownUpstream, Et as listWorktreesAsync, Ft as resolveFullRefAsync, K as resolveIosProjectDir, Lt as restoreFileAsync, Pt as resolveFullRef, Rt as sourceCheckoutOf, St as hasUncommittedWorkAsync, Vt as filesystemDevice, Wt as removeTemporaryEntryAsync, Y as resolveSettings, a as SETTING_SHAPE_REMEDY, bt as hasPopulatedSubmodulesAsync, dt as branchExistsAsync, et as settingShapeErrors, ft as cloneIgnoredEntries, gt as dirtyPathsAsync, it as unknownSettingKeys, jt as removeWorktreeAsync, kt as podsOutOfSync, mt as depsOutOfSync, pt as deleteBranchAsync, q as resolveProjectSettings, vt as gitCommonDirAsync, xt as hasRemoteAsync, yt as gitCommonDirOnDisk, z as readCommittedSettings, zt as unpushedCommitsAsync } from "./settings-RKwY33wv.mjs";
8
+ import { F as readRemoteSessionId, M as readMetroTunnel, O as clearManagedMetroTunnel, P as readRemoteSession, T as MODE_COMMAND, i as findProjectRoot$1, k as clearRemoteSession, o as isMobileProject } from "./project-Dz-hWkb-.mjs";
9
+ import { t as macosAppPresent } from "./state-BfAltYJP.mjs";
10
+ import { a as workspaceLinkLine, o as workspaceLinks } from "./stim-desktop-DS0mzR8U.mjs";
11
+ import { ft as POOL_SETTING_REMEDY, vt as parkedMaxSetting } from "./android-882m4hxX.mjs";
12
+ import { c as pidExists, d as resolveProjectMetro, p as signalProcessTreeAsync, r as killMetroTreeAsync } from "./metro-Bu8LBfzS.mjs";
13
+ import { o as readWebRecord } from "./state-B1ig0Kqy.mjs";
14
+ import { Rn as runProcessOperation, S as withdrawDevServerStopRequest, Sr as discoverCaches, Vt as endRecordedSession, Yn as resolveEasCliBin, b as requestDevServerStop, c as readVolumeSpace, it as planCacheEmptying, l as readVolumeSpaceAsync, o as machineNumber, u as resolveBudget } from "./budget-dPGuhNai.mjs";
13
15
  import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
14
- import { p as cacheUser } from "./native-run-Dv88i0aU.mjs";
15
- import { D as teardownOwnedAvd, O as teardownOwnedBrowser, S as withManagedTunnelRemovalLock, _ as stopTunnel, a as collectWorkspaceOutputs, b as withManagedRemoteWorktreeRemovalLock, d as emptyWorkspaceDir, f as withIdleWorkspace, h as resolveSupervisorTarget, k as teardownOwnedIosSim } from "./workspaces-e41xsjKr.mjs";
16
- import { D as releaseWorkspaceLeases, t as agentDeviceDaemon } from "./activity-BpWUPgUm.mjs";
17
- import { _t as parkedMaxSetting, dt as POOL_SETTING_REMEDY } from "./android-C7sVmyI9.mjs";
18
- import { F as readHostMemoryPressureAsync, P as readHostMemoryPressure } from "./ios-hcBpnEGk.mjs";
19
- import { a as workspaceLinkLine, o as workspaceLinks } from "./stim-desktop-D5OGpYZM.mjs";
20
- import { t as clearNamedPorts } from "./named-ports-DkEzOfzO.mjs";
21
- import { r as HEARTBEAT_INTERVAL_MS, x as podInstallCommand } from "./xcode-Rq744mBF.mjs";
16
+ import { p as cacheUser } from "./native-run-BmH7U8pr.mjs";
17
+ import { A as teardownOwnedIosSim, C as withManagedTunnelRemovalLock, O as teardownOwnedAvd, a as collectWorkspaceOutputs, f as emptyWorkspaceDir, g as resolveSupervisorTarget, k as teardownOwnedBrowser, p as withIdleWorkspace, v as stopTunnel, x as withManagedRemoteWorktreeRemovalLock } from "./workspaces-CSV2Orf4.mjs";
18
+ import { D as releaseWorkspaceLeases, t as agentDeviceDaemon } from "./activity-Dq3ZcdD8.mjs";
19
+ import { F as readHostMemoryPressure, I as readHostMemoryPressureAsync } from "./ios-CVUFFZ6C.mjs";
20
+ import { t as clearNamedPorts } from "./named-ports-BWDuU5oQ.mjs";
21
+ import { r as HEARTBEAT_INTERVAL_MS, x as podInstallCommand } from "./xcode-DHu41qQ4.mjs";
22
22
  import { t as resolveMaintenanceSettings } from "./settings-Djl-mpjX.mjs";
23
- import { _ as runCaptured, h as readPodState, m as podsAreStale, p as DEPS_ERROR, v as runPodInstall } from "./toolchain-B9hCFCQw.mjs";
24
- import { i as stopHostedAndroid } from "./hosted-android-xcfgCgSF.mjs";
25
- import { r as stopHostedIos } from "./hosted-ios-y19jCYFF.mjs";
26
- import { n as stopMacosApp } from "./stop-CR5689oB.mjs";
27
- import { n as verifyCollectorOwnership } from "./ownership-C5fo5Edb.mjs";
28
- import { a as discoverXcodeProject } from "./react-native-build-CelbTO_y.mjs";
29
- import { n as hasInstalledDependencies, r as installedNpmTreeIsValid, t as dependencyState } from "./dependency-state-1I9KZT1Y.mjs";
30
- import { a as forgetStatusMeasures, p as mergeStateAsync, t as startWarmProgress } from "./warm-progress-CA3TgT3-.mjs";
31
- import { o as pullRequestLookupAsync, r as endedPullRequest } from "./pull-request-W1IuLXDt.mjs";
32
- import { r as workspaceRecordingEnabled } from "./recordings-CQmfzAh7.mjs";
23
+ import { _ as runCaptured, h as readPodState, m as podsAreStale, p as DEPS_ERROR, v as runPodInstall } from "./toolchain-D3bmRMia.mjs";
24
+ import { i as stopHostedAndroid } from "./hosted-android-D4dweBof.mjs";
25
+ import { r as stopHostedIos } from "./hosted-ios-Sn0djzg8.mjs";
26
+ import { n as stopMacosApp } from "./stop-DhclRwOO.mjs";
27
+ import { n as verifyCollectorOwnership } from "./ownership-DxlZGDcV.mjs";
28
+ import { n as removePhoneReverses } from "./phone-reverses-BdsdesVF.mjs";
29
+ import { a as discoverXcodeProject } from "./react-native-build-AuCu-aAP.mjs";
30
+ import { n as hasInstalledDependencies, r as installedNpmTreeIsValid, t as dependencyState } from "./dependency-state-C56ll9hY.mjs";
31
+ import { a as forgetStatusMeasures, p as mergeStateAsync, t as startWarmProgress } from "./warm-progress-ol0ZypEu.mjs";
32
+ import { o as pullRequestLookupAsync, r as endedPullRequest } from "./pull-request-CbNlkFok.mjs";
33
+ import { r as workspaceRecordingEnabled } from "./recordings-CdPwYwvs.mjs";
33
34
  import { claimRemoveCommand, clearFreeClaimSet, readClaimSet, releaseClaim, tryAcquireClaim } from "@stim-cli/core/ownership-claim";
34
35
  import { createHash, randomUUID } from "node:crypto";
35
36
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
36
37
  import { cpus, freemem, homedir, loadavg, totalmem } from "node:os";
37
38
  import { basename, dirname, join, relative } from "node:path";
38
39
  import { buildCacheRoot, configDir, metroCacheRoot, unitLines, unitWords, withDirLockTransaction, workspaceName } from "@stim-cli/core";
39
- import { LAST_BUILD_KEYS, archiveDir, archiveEnabled, archiveLock, archiveRoot, archivedUsage, buildWorkerRoot, countErrorEntries, endedAgentSessionOf, isJsonObject, listRecordedDevicesAsync, loadConfig, queryLogs, readArchivesAsync, readBuildHistory, readJsonObject, readLastBuilds, readMacosRecord, readPullRequestCache, readWorkspaceState, recordingEnabled, sharedCcache, sharedCompilationCache, sortByTs } from "@stim-cli/core/state";
40
+ import { LAST_BUILD_KEYS, archiveDir, archiveEnabled, archiveLock, archiveRoot, archivedUsage, buildWorkerRoot, countErrorEntries, endedAgentSessionOf, isJsonObject, listRecordedDevicesAsync, loadConfig, queryLogs, readArchivesAsync, readBuildHistory, readJsonObject, readLastBuilds, readMacosRecord, readPullRequestCache, readWorkspaceState, recordingEnabled, sharedCcache, sharedCompilationCache, sortByTs, trashRoot } from "@stim-cli/core/state";
40
41
  import { basename as basename$1, dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, relative as relative$1, resolve as resolve$1 } from "path";
41
42
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
43
+ import { captureProcessIdentity } from "@stim-cli/core/process-identity";
42
44
  import chalk from "chalk";
43
45
  import { existsSync as existsSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, readlinkSync as readlinkSync$1, realpathSync as realpathSync$1, renameSync as renameSync$1, rmSync as rmSync$1, symlinkSync as symlinkSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "fs";
44
- import { chmod, lstat, mkdir, readdir, rename, rm, stat, utimes, writeFile } from "node:fs/promises";
46
+ import { chmod, lstat, mkdir, mkdtemp, readdir, rename, rm, rmdir, stat, utimes, writeFile } from "node:fs/promises";
45
47
  import { createHash as createHash$1 } from "crypto";
46
48
  //#region src/maintenance/pressure.ts
47
49
  /**
@@ -291,7 +293,7 @@ function findPath(dir, text, bytes) {
291
293
  if (entry.isDirectory()) {
292
294
  const found = findPath(path, text, bytes);
293
295
  if (found) return found;
294
- } else if (entry.isFile() && bytes(readFileSync$1(path).toString("latin1"))) return path;
296
+ } else if (entry.isFile() && bytes(readFileSync$1(path))) return path;
295
297
  }
296
298
  return null;
297
299
  }
@@ -319,7 +321,9 @@ function relocatePods({ podsDir, podfileLockPath, sourceRoot, targetRoot, canRel
319
321
  const manifest = readFileSync$1(manifestPath, "utf-8");
320
322
  const pattern = pathPattern(sourceRoot);
321
323
  const textNamesSource = sourceNamer(sourceRoot, targetRoot, "utf-8");
322
- const bytesNameSource = sourceNamer(sourceRoot, targetRoot, "latin1");
324
+ const latin1NamesSource = sourceNamer(sourceRoot, targetRoot, "latin1");
325
+ const sourceBytes = Buffer.from(sourceRoot, "utf-8");
326
+ const bytesNameSource = (buffer) => buffer.includes(sourceBytes) && latin1NamesSource(buffer.toString("latin1"));
323
327
  let pods = [];
324
328
  if (normalize$1(podfileLock) === normalize$1(manifest)) {
325
329
  let names;
@@ -357,7 +361,7 @@ function relocatePods({ podsDir, podfileLockPath, sourceRoot, targetRoot, canRel
357
361
  if (!existsSync$1(dir)) continue;
358
362
  walkTextFiles(dir, (file) => {
359
363
  const buffer = readFileSync$1(file);
360
- if (buffer.includes(0)) return;
364
+ if (!buffer.includes(sourceBytes) || buffer.includes(0)) return;
361
365
  const text = buffer.toString("utf-8");
362
366
  if (!pattern.test(text)) return;
363
367
  writeFileSync$1(file, relocatePath(text, sourceRoot, targetRoot));
@@ -994,7 +998,7 @@ async function reclaimRemoteSession(root, { stopSession = defaultStopSession, op
994
998
  reason: `${result.reason} The session is stopped. Re-run cleanup to reconcile its retained ownership claim.`
995
999
  }
996
1000
  };
997
- clearRemoteSession(root, sessionId);
1001
+ await withWorkspaceStateLockAsync(root, () => clearRemoteSession(root, sessionId));
998
1002
  return {
999
1003
  stopped: sessionId,
1000
1004
  failed: null
@@ -1045,7 +1049,7 @@ async function reclaimMetroTunnel(root, { stopMetroTunnel = defaultStopMetroTunn
1045
1049
  reason: `${result.reason ?? "stop failed"} The process identity could not be verified or the stop could not be confirmed. The ownership record is kept. Inspect the process and retry \`stim worktree remove\`.`
1046
1050
  }
1047
1051
  };
1048
- if (!clearManagedMetroTunnel(root, record)) return {
1052
+ if (!await withWorkspaceStateLockAsync(root, () => clearManagedMetroTunnel(root, record))) return {
1049
1053
  stopped: null,
1050
1054
  failed: {
1051
1055
  platform: "ios",
@@ -1112,7 +1116,7 @@ async function reclaimOwnedDevices(project, projectPath, { park = false, operati
1112
1116
  parkedDevices.push(r.parked);
1113
1117
  evictedDevices.push(...r.evicted ?? []);
1114
1118
  } else if (r.status === "torn-down") deletedDevices.push(r.label);
1115
- if (!r.parked && (r.status === "torn-down" || r.status === "missing")) clearDevice(projectPath, "ios", slot, udid);
1119
+ if (!r.parked && (r.status === "torn-down" || r.status === "missing")) await withConfigLockAsync$1(() => clearDevice(projectPath, "ios", slot, udid));
1116
1120
  if (r.status === "skipped") skippedDevices.push({
1117
1121
  platform: "ios",
1118
1122
  name: label,
@@ -1152,7 +1156,10 @@ async function reclaimOwnedDevices(project, projectPath, { park = false, operati
1152
1156
  });
1153
1157
  if (r.parkFallback) poolNotes.push(`could not park ${android.avdName}: ${r.parkFallback} -- deleted it instead`);
1154
1158
  for (const failure of r.evictionFailures ?? []) poolNotes.push(failure);
1155
- if (!r.parked && (r.status === "torn-down" || r.status === "missing")) clearDevice(projectPath, "android", slot, android.avdName);
1159
+ if (!r.parked && (r.status === "torn-down" || r.status === "missing")) {
1160
+ const avdName = android.avdName;
1161
+ await withConfigLockAsync$1(() => clearDevice(projectPath, "android", slot, avdName));
1162
+ }
1156
1163
  if (r.parked) {
1157
1164
  parkedDevices.push(r.parked);
1158
1165
  evictedDevices.push(...r.evicted ?? []);
@@ -1265,6 +1272,7 @@ async function reclaimIdleProject(path, workspaceExisted, { archive, deleteOwned
1265
1272
  verifyAvdClaims(project, operation);
1266
1273
  const dereferenced = describeDereferenced(project);
1267
1274
  const initialState = readWorkspaceState$1(path);
1275
+ await removePhoneReverses(path, { operation });
1268
1276
  let killedPid = null;
1269
1277
  let skippedMetro = null;
1270
1278
  let supervisorHeld = false;
@@ -1279,9 +1287,10 @@ async function reclaimIdleProject(path, workspaceExisted, { archive, deleteOwned
1279
1287
  };
1280
1288
  const orphanIdentity = supervisor.status === "stale" && typeof orphanServer.processToken === "string" ? (0, process_identity_exports.inspectProcessIdentity)(orphanServer) : null;
1281
1289
  if (supervisor.status === "ours") {
1282
- requestDevServerStop(path, supervisor.processToken, stopRequester);
1290
+ const processToken = supervisor.processToken;
1291
+ await withWorkspaceStateLockAsync(path, () => requestDevServerStop(path, processToken, stopRequester)).catch(() => {});
1283
1292
  const signalled = await killMetroTreeAsync(supervisor.pid, supervisor.processToken, operation);
1284
- if (!signalled) withdrawDevServerStopRequest(path, supervisor.processToken);
1293
+ if (!signalled) await withWorkspaceStateLockAsync(path, () => withdrawDevServerStopRequest(path, processToken)).catch(() => {});
1285
1294
  if (signalled && await (0, process_identity_exports.waitForProcessExit)(supervisor, 1e4, signal)) killedPid = supervisor.pid;
1286
1295
  else {
1287
1296
  skippedMetro = `could not confirm supervisor pid ${supervisor.pid} exited`;
@@ -1424,7 +1433,7 @@ async function reclaimIdleProject(path, workspaceExisted, { archive, deleteOwned
1424
1433
  }
1425
1434
  const keptEntry = supervisorHeld || failedDevices.length > 0 || failedWorkspaceDirs.length > 0;
1426
1435
  signal?.throwIfAborted();
1427
- if (project && !keptEntry && !preserveProjectRecord) removeProject(path);
1436
+ if (project && !keptEntry && !preserveProjectRecord) await withConfigLockAsync$1(() => removeProject(path));
1428
1437
  return {
1429
1438
  path,
1430
1439
  dereferenced,
@@ -2265,6 +2274,205 @@ async function refreshMainCheckout({ root, appDir, settings, iosProject, emit, s
2265
2274
  return podsRunning;
2266
2275
  }
2267
2276
  //#endregion
2277
+ //#region src/workspace/worktree-trash.ts
2278
+ const TRASH_MANIFEST = "trash.json";
2279
+ const TRASH_ENTRY_PREFIX = "remove-";
2280
+ const TRASH_ENTRIES = "entries";
2281
+ const TRASH_CLAIMS = "claims";
2282
+ const LIST_TIMEOUT_MS = 3e4;
2283
+ const DELETE_NICENESS = "10";
2284
+ function rethrowCancellation(error, signal) {
2285
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
2286
+ signal?.throwIfAborted();
2287
+ }
2288
+ async function isPlainDirectory(path) {
2289
+ const stat = await lstat(path).catch(() => null);
2290
+ return Boolean(stat?.isDirectory());
2291
+ }
2292
+ async function ignoredDirectories(worktree, options) {
2293
+ const out = await gitAsync(worktree, [
2294
+ "ls-files",
2295
+ "--others",
2296
+ "--ignored",
2297
+ "--exclude-standard",
2298
+ "--directory",
2299
+ "--no-empty-directory",
2300
+ "-z"
2301
+ ], {
2302
+ ...options.env ? childEnvironment(options.env) : {},
2303
+ signal: options.signal,
2304
+ declareFor: options.declareFor,
2305
+ timeoutMs: LIST_TIMEOUT_MS,
2306
+ untrimmed: true
2307
+ });
2308
+ const found = [];
2309
+ for (const entry of out.split("\0")) {
2310
+ if (!entry.endsWith("/")) continue;
2311
+ const rel = entry.slice(0, -1);
2312
+ const parts = rel.split("/");
2313
+ let plain = true;
2314
+ for (let depth = 1; depth <= parts.length && plain; depth++) plain = await isPlainDirectory(join(worktree, ...parts.slice(0, depth)));
2315
+ if (plain) found.push(rel);
2316
+ }
2317
+ return found;
2318
+ }
2319
+ /**
2320
+ * Moves the worktree's ignored directories, which `git worktree remove` would delete, into a new entry under
2321
+ * `$STIM_HOME/trash` held by an exclusive ownership claim. Null, with nothing moved, when the trash is on another
2322
+ * filesystem, the platform is Windows, git cannot list the entries, or the claim cannot be taken. A directory that
2323
+ * does not rename stays in the worktree for git to delete.
2324
+ */
2325
+ async function moveIgnoredTreesToTrash(worktree, options = {}) {
2326
+ if ((options.platform ?? process.platform) === "win32") return null;
2327
+ let listed;
2328
+ try {
2329
+ listed = await ignoredDirectories(worktree, options);
2330
+ } catch (error) {
2331
+ rethrowCancellation(error, options.signal);
2332
+ return null;
2333
+ }
2334
+ if (!listed.length) return null;
2335
+ const root = trashRoot();
2336
+ let dir = null;
2337
+ let claim = null;
2338
+ const entries = listed.map((from, index) => ({
2339
+ from,
2340
+ to: String(index)
2341
+ }));
2342
+ try {
2343
+ await mkdir(root, { recursive: true });
2344
+ if (filesystemDevice(root) !== filesystemDevice(worktree)) return null;
2345
+ dir = await mkdtemp(join(root, TRASH_ENTRY_PREFIX));
2346
+ claim = (0, ownership_claim_exports.tryAcquireClaim)({
2347
+ root: join(dir, "claims"),
2348
+ mode: "exclusive",
2349
+ label: "worktree trash"
2350
+ }).acquired ?? null;
2351
+ if (!claim) throw new Error("the trash entry claim was not acquired");
2352
+ const manifest = {
2353
+ worktree,
2354
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
2355
+ };
2356
+ await writeFile(join(dir, TRASH_MANIFEST), `${JSON.stringify(manifest)}\n`);
2357
+ await mkdir(join(dir, TRASH_ENTRIES));
2358
+ } catch (error) {
2359
+ if (claim) (0, ownership_claim_exports.releaseClaim)(claim);
2360
+ if (dir) await rm(dir, {
2361
+ recursive: true,
2362
+ force: true
2363
+ }).catch(() => {});
2364
+ rethrowCancellation(error, options.signal);
2365
+ return null;
2366
+ }
2367
+ const moved = [];
2368
+ for (const entry of entries) try {
2369
+ await rename(join(worktree, entry.from), join(dir, TRASH_ENTRIES, entry.to));
2370
+ moved.push(entry);
2371
+ } catch {}
2372
+ const trash = {
2373
+ dir,
2374
+ worktree,
2375
+ moved,
2376
+ claim
2377
+ };
2378
+ if (moved.length) return trash;
2379
+ await discardTrash(trash);
2380
+ return null;
2381
+ }
2382
+ async function discardTrash(trash) {
2383
+ await rmdir(join(trash.dir, TRASH_ENTRIES)).catch(() => {});
2384
+ await rm(join(trash.dir, TRASH_MANIFEST), { force: true }).catch(() => {});
2385
+ (0, ownership_claim_exports.releaseClaim)(trash.claim);
2386
+ await rmdir(trash.dir).catch(() => {});
2387
+ }
2388
+ /** Moves every tree back into the worktree. Returns the relative paths that stay in the trash for gc. */
2389
+ async function restoreTrashedTrees(trash) {
2390
+ const kept = [];
2391
+ for (const entry of trash.moved.toReversed()) {
2392
+ const target = join(trash.worktree, entry.from);
2393
+ try {
2394
+ if (await lstat(target).catch(() => null) || !await isPlainDirectory(dirname(target))) {
2395
+ kept.push(entry.from);
2396
+ continue;
2397
+ }
2398
+ await rename(join(trash.dir, TRASH_ENTRIES, entry.to), target);
2399
+ } catch {
2400
+ kept.push(entry.from);
2401
+ }
2402
+ }
2403
+ if (kept.length) (0, ownership_claim_exports.releaseClaim)(trash.claim);
2404
+ else await discardTrash(trash);
2405
+ return kept;
2406
+ }
2407
+ /** Deletes one trash entry: `rm -rf` for the bulk, then a walk that also clears read-only directories. */
2408
+ async function deleteTrashEntry(dir, operation) {
2409
+ if (process.platform !== "win32") try {
2410
+ await runOperationFile(operation, getExecutor(), "rm", [
2411
+ "-rf",
2412
+ "--",
2413
+ join(dir, TRASH_ENTRIES)
2414
+ ], {
2415
+ timeoutMs: "unbounded",
2416
+ signal: operation?.signal,
2417
+ cwd: dirname(dir)
2418
+ });
2419
+ } catch (error) {
2420
+ rethrowCancellation(error, operation?.signal);
2421
+ }
2422
+ await removeTemporaryEntryAsync(dir, operation?.signal);
2423
+ }
2424
+ function deleteInBackground(trash) {
2425
+ try {
2426
+ (0, ownership_claim_exports.markClaimChildPending)(trash.claim);
2427
+ const child = getExecutor().spawn("nice", [
2428
+ "-n",
2429
+ DELETE_NICENESS,
2430
+ "rm",
2431
+ "-rf",
2432
+ "--",
2433
+ join(trash.dir, TRASH_ENTRIES),
2434
+ trash.dir
2435
+ ], {
2436
+ cwd: dirname(trash.dir),
2437
+ detached: true,
2438
+ stdio: "ignore"
2439
+ });
2440
+ child.on?.("error", () => {});
2441
+ child.unref?.();
2442
+ const captured = child.pid === void 0 ? null : captureProcessIdentity(child.pid);
2443
+ if (!captured?.ok || child.pid === void 0) throw new Error("the trash deletion process was not recorded");
2444
+ (0, ownership_claim_exports.setClaimChild)(trash.claim, {
2445
+ pid: child.pid,
2446
+ processToken: captured.token
2447
+ });
2448
+ return true;
2449
+ } catch {
2450
+ try {
2451
+ (0, ownership_claim_exports.clearClaimChild)(trash.claim);
2452
+ } catch {}
2453
+ (0, ownership_claim_exports.releaseClaim)(trash.claim);
2454
+ return false;
2455
+ }
2456
+ }
2457
+ /**
2458
+ * Deletes the trash entry once git removed the worktree. A CLI command starts a detached, low-priority `rm` recorded
2459
+ * as the claim's child, so gc reports the entry as in use until `rm` exits. Inside a bounded report, such as the
2460
+ * programmatic API, every child is stopped when the report settles, so the entry is deleted before returning.
2461
+ * `left` means the entry waits for gc with its claim released.
2462
+ */
2463
+ async function disposeTrash(trash, operation) {
2464
+ if (!getExecutor().reportSignal?.()) return deleteInBackground(trash) ? "background" : "left";
2465
+ try {
2466
+ await deleteTrashEntry(trash.dir, operation);
2467
+ return "deleted";
2468
+ } catch (error) {
2469
+ rethrowCancellation(error, operation?.signal);
2470
+ return "left";
2471
+ } finally {
2472
+ (0, ownership_claim_exports.releaseClaim)(trash.claim);
2473
+ }
2474
+ }
2475
+ //#endregion
2268
2476
  //#region src/commands/worktree.ts
2269
2477
  function dependencyInstallCommand(target, dir = ".") {
2270
2478
  const installRoot = resolve$1(target, dir);
@@ -2310,7 +2518,7 @@ function reportCarriedStateHealth(root, target, copied, out) {
2310
2518
  }
2311
2519
  for (const p of podsOutOfSync(target, copied)) {
2312
2520
  const where = p.dir === "." ? "Podfile.lock" : `${p.dir}/Podfile.lock`;
2313
- const pod = podInstallCommand(p.dir === "." ? target : resolve$1(target, p.dir, ".."));
2521
+ const pod = podInstallCommand(p.dir === "." ? target : resolve$1(target, p.dir, ".."), resolve$1(target, p.dir));
2314
2522
  out(chalk.yellow(phaseLine("carry", p.reason === "missing" ? `carried ${p.dir === "." ? "Pods" : `${p.dir}/Pods`} but there is no ${where}. Run \`${pod}\` before building.` : `carried ${p.dir === "." ? "Pods" : `${p.dir}/Pods`} does not match the ${where} on disk here. Pods are gitignored and cloned; Podfile.lock is tracked, so the two can disagree. Run \`${pod}\` before building, or xcodebuild fails with "sandbox is not in sync" only after every pod has compiled.`)));
2315
2523
  }
2316
2524
  }
@@ -2345,9 +2553,11 @@ function warmedWorkspace(root, target, cwd) {
2345
2553
  }
2346
2554
  return apps.size === 1 ? [...apps][0] : app;
2347
2555
  }
2348
- function registerWarmedWorkspace(workspace, out) {
2556
+ async function registerWarmedWorkspace(workspace, out) {
2349
2557
  try {
2350
- if (!getProject(workspace)) upsertProject(workspace, {});
2558
+ await withConfigLockAsync$1(() => {
2559
+ if (!getProject(workspace)) upsertProject(workspace, {});
2560
+ });
2351
2561
  } catch (error) {
2352
2562
  out(chalk.yellow(`Could not register ${workspace} for status: ${error?.message || String(error)}`));
2353
2563
  }
@@ -2393,11 +2603,11 @@ async function warmWorktreeTarget(opts) {
2393
2603
  ...workspace ? [workspace] : []
2394
2604
  ]);
2395
2605
  for (const key of scope) opts.beforeWarm?.(nativeCanonicalPath(key));
2396
- if (app) recordWorkspaceUse(app, /* @__PURE__ */ new Date(), operation.env, opts.cwd);
2397
- if (workspace && workspace !== app) recordWorkspaceUse(workspace, /* @__PURE__ */ new Date(), operation.env, opts.cwd);
2606
+ if (app) await recordWorkspaceUseAsync(app, /* @__PURE__ */ new Date(), operation.env, opts.cwd, operation.signal);
2607
+ if (workspace && workspace !== app) await recordWorkspaceUseAsync(workspace, /* @__PURE__ */ new Date(), operation.env, opts.cwd, operation.signal);
2398
2608
  if (!workspace) out(chalk.dim(phaseLine("project", "no single app to register here; run warm from the app directory to list it in status while it warms")));
2399
2609
  else {
2400
- registerWarmedWorkspace(workspace, out);
2610
+ await registerWarmedWorkspace(workspace, out);
2401
2611
  progress = startWarmProgress(workspace, opts.refresh ? "refresh" : "copy", { note: (line) => out(chalk.yellow(line)) });
2402
2612
  }
2403
2613
  const readSettings = () => {
@@ -3021,7 +3231,7 @@ async function removeOrRefuse(target, opts, onRemoved, output) {
3021
3231
  }
3022
3232
  opts.beforeRemove?.(removalPath(mainRoot));
3023
3233
  if (!await branchExistsAsync(mainRoot, branch, options)) {
3024
- removeProject(path);
3234
+ await withConfigLockAsync$1(() => removeProject(path));
3025
3235
  output.error(chalk.dim(phaseLine("branch", `${branch} is already absent; cleared its pending cleanup record`)));
3026
3236
  return;
3027
3237
  }
@@ -3041,7 +3251,7 @@ async function removeOrRefuse(target, opts, onRemoved, output) {
3041
3251
  }
3042
3252
  try {
3043
3253
  await deleteBranchAsync(mainRoot, branch, pending.worktreePendingBranchSha, options);
3044
- removeProject(path);
3254
+ await withConfigLockAsync$1(() => removeProject(path));
3045
3255
  output.error(chalk.dim(phaseLine("branch", `deleted ${branch}; cleared its pending cleanup record`)));
3046
3256
  } catch (error) {
3047
3257
  if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
@@ -3192,6 +3402,11 @@ async function removeOrRefuse(target, opts, onRemoved, output) {
3192
3402
  await restorePodChurn(path, current.podChurn, output, opts.operation);
3193
3403
  options.signal?.throwIfAborted();
3194
3404
  deleteWatchmanCookies(path, current.cookies);
3405
+ const trash = await moveIgnoredTreesToTrash(path, {
3406
+ env: options.env,
3407
+ signal: options.signal,
3408
+ declareFor: opts.operation
3409
+ });
3195
3410
  try {
3196
3411
  await removeWorktreeAsync(path, {
3197
3412
  from: source.path,
@@ -3201,6 +3416,8 @@ async function removeOrRefuse(target, opts, onRemoved, output) {
3201
3416
  declareFor: opts.operation
3202
3417
  });
3203
3418
  } catch (error) {
3419
+ const unrestored = trash ? await restoreTrashedTrees(trash) : [];
3420
+ if (trash && unrestored.length) output.error(chalk.yellow(`Could not move ${unrestored.join(", ")} back into ${path}; ${unrestored.length === 1 ? "it stays" : "they stay"} in ${trash.dir}, which stim gc keeps while ${path} exists.`));
3204
3421
  if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
3205
3422
  const message = String(error?.message || error);
3206
3423
  output.error(chalk.red(`git worktree remove failed: ${message}`));
@@ -3211,56 +3428,64 @@ async function removeOrRefuse(target, opts, onRemoved, output) {
3211
3428
  return;
3212
3429
  }
3213
3430
  onRemoved();
3214
- forgetStatusMeasures(path, result.reclaimedKeys);
3215
- const finish = () => {
3216
- printRemovalCleanup(result, false, output);
3217
- output.error(chalk.dim(phaseLine("removed", path)));
3218
- };
3219
- if (deleteOwnedBranch && branch) {
3220
- if (!approvedBranchSha) {
3221
- output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (Stim could not record its commit before removal)`)));
3222
- output.fail();
3223
- finish();
3224
- return;
3225
- }
3226
- upsertProject(path, {
3227
- worktreeRemovalComplete: true,
3228
- worktreePendingBranchSha: approvedBranchSha
3229
- });
3230
- let checkedOutAt;
3231
- try {
3232
- checkedOutAt = (await listWorktreesAsync(branchDeleteCwd, options)).find((candidate) => candidate.branch === branch && resolve$1(candidate.path) !== resolve$1(path))?.path;
3233
- } catch (error) {
3234
- if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
3235
- opts.operation?.signal.throwIfAborted();
3236
- if (!isTimeoutError(error)) throw error;
3237
- output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (git did not list the worktrees in time to check it)`)));
3238
- output.error(chalk.dim(` Retry: stim worktree remove ${path}`));
3239
- output.fail();
3240
- finish();
3241
- return;
3242
- }
3243
- if (checkedOutAt) {
3244
- output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (it is checked out at ${checkedOutAt})`)));
3245
- output.error(chalk.dim(` Switch that worktree to another branch, then retry: stim worktree remove ${path}`));
3246
- output.fail();
3247
- finish();
3248
- return;
3249
- }
3250
- try {
3251
- await deleteBranchAsync(branchDeleteCwd, branch, approvedBranchSha, options);
3252
- output.error(chalk.dim(phaseLine("branch", `deleted ${branch}`)));
3253
- } catch (error) {
3254
- if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
3255
- output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (${String(error?.message || error)})`)));
3256
- output.error(chalk.dim(` Retry with: git -C ${branchDeleteCwd} branch -D -- ${branch}`));
3257
- output.fail();
3258
- finish();
3259
- return;
3431
+ try {
3432
+ forgetStatusMeasures(path, result.reclaimedKeys);
3433
+ const finish = () => {
3434
+ printRemovalCleanup(result, false, output);
3435
+ output.error(chalk.dim(phaseLine("removed", path)));
3436
+ };
3437
+ if (deleteOwnedBranch && branch) {
3438
+ if (!approvedBranchSha) {
3439
+ output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (Stim could not record its commit before removal)`)));
3440
+ output.fail();
3441
+ finish();
3442
+ return;
3443
+ }
3444
+ await withConfigLockAsync$1(() => upsertProject(path, {
3445
+ worktreeRemovalComplete: true,
3446
+ worktreePendingBranchSha: approvedBranchSha
3447
+ }));
3448
+ let checkedOutAt;
3449
+ try {
3450
+ checkedOutAt = (await listWorktreesAsync(branchDeleteCwd, options)).find((candidate) => candidate.branch === branch && resolve$1(candidate.path) !== resolve$1(path))?.path;
3451
+ } catch (error) {
3452
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
3453
+ opts.operation?.signal.throwIfAborted();
3454
+ if (!isTimeoutError(error)) throw error;
3455
+ output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (git did not list the worktrees in time to check it)`)));
3456
+ output.error(chalk.dim(` Retry: stim worktree remove ${path}`));
3457
+ output.fail();
3458
+ finish();
3459
+ return;
3460
+ }
3461
+ if (checkedOutAt) {
3462
+ output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (it is checked out at ${checkedOutAt})`)));
3463
+ output.error(chalk.dim(` Switch that worktree to another branch, then retry: stim worktree remove ${path}`));
3464
+ output.fail();
3465
+ finish();
3466
+ return;
3467
+ }
3468
+ try {
3469
+ await deleteBranchAsync(branchDeleteCwd, branch, approvedBranchSha, options);
3470
+ output.error(chalk.dim(phaseLine("branch", `deleted ${branch}`)));
3471
+ } catch (error) {
3472
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
3473
+ output.error(chalk.yellow(phaseLine("branch", `kept ${branch} (${String(error?.message || error)})`)));
3474
+ output.error(chalk.dim(` Retry with: git -C ${branchDeleteCwd} branch -D -- ${branch}`));
3475
+ output.fail();
3476
+ finish();
3477
+ return;
3478
+ }
3479
+ } else if (branch && retainedBranchReason) output.error(chalk.dim(phaseLine("branch", `kept ${branch} (${retainedBranchReason})`)));
3480
+ await withConfigLockAsync$1(() => removeProject(path));
3481
+ finish();
3482
+ } finally {
3483
+ if (trash) {
3484
+ const moved = plural(trash.moved.length, "ignored directory", "ignored directories");
3485
+ const disposed = await disposeTrash(trash, opts.operation);
3486
+ output.error(chalk.dim(phaseLine("trash", disposed === "background" ? `deleting ${moved} in the background from ${trash.dir}` : disposed === "deleted" ? `deleted ${moved}` : `left ${moved} in ${trash.dir}; stim gc --delete deletes them`)));
3260
3487
  }
3261
- } else if (branch && retainedBranchReason) output.error(chalk.dim(phaseLine("branch", `kept ${branch} (${retainedBranchReason})`)));
3262
- removeProject(path);
3263
- finish();
3488
+ }
3264
3489
  }, opts.operation, opts.beforeRemove), {
3265
3490
  signal: opts.operation?.signal,
3266
3491
  declareSpawnsFor: opts.operation
@@ -3277,4 +3502,4 @@ function worktreeCommand(program) {
3277
3502
  registerRemove(worktree);
3278
3503
  }
3279
3504
  //#endregion
3280
- export { levelFloors as A, measureDisk as C, measureSizes as D, measurePressureAsync as E, lowestFree as M, protectWindowMs as N, sizeScanDeferred as O, cacheBlocked as S, measurePressure as T, worktreeCommand as _, matchWorktreeEntry as a, deleteSelectedArchives as b, reclaimKeys as c, removalBlockers as d, removalPath as f, warmedWorkspace as g, warmWorktreeTarget as h, excludeWatchmanCookies as i, levelStillShort as j, diskPressureLevel as k, registerRemove as l, removeWorktreeTarget as m, dependencyInstallCommand as n, nestedWorktrees as o, removalRemedy as p, excludePodChurn as r, porcelainPath as s, customIosDirs as t, registerWarm as u, describeDereferenced as v, measureDiskAsync as w, sweepArchiveStaging as x, reclaimProject as y };
3505
+ export { measurePressureAsync as A, reclaimProject as C, measureDisk as D, cacheBlocked as E, levelStillShort as F, lowestFree as I, protectWindowMs as L, sizeScanDeferred as M, diskPressureLevel as N, measureDiskAsync as O, levelFloors as P, describeDereferenced as S, sweepArchiveStaging as T, worktreeCommand as _, matchWorktreeEntry as a, TRASH_MANIFEST as b, reclaimKeys as c, removalBlockers as d, removalPath as f, warmedWorkspace as g, warmWorktreeTarget as h, excludeWatchmanCookies as i, measureSizes as j, measurePressure as k, registerRemove as l, removeWorktreeTarget as m, dependencyInstallCommand as n, nestedWorktrees as o, removalRemedy as p, excludePodChurn as r, porcelainPath as s, customIosDirs as t, registerWarm as u, TRASH_CLAIMS as v, deleteSelectedArchives as w, deleteTrashEntry as x, TRASH_ENTRY_PREFIX as y };