stim 1.20.2 → 1.22.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 (231) hide show
  1. package/README.md +141 -8
  2. package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
  3. package/dist/act-DsuqEkiM.mjs +2801 -0
  4. package/dist/activity-CMLmzp7o.mjs +1397 -0
  5. package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
  6. package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
  7. package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
  8. package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
  9. package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
  10. package/dist/android-cas-compiler.mjs +2 -2
  11. package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
  12. package/dist/android-project-BCAAmMwz.mjs +12 -0
  13. package/dist/android-project-DVWyCbWU.d.mts +391 -0
  14. package/dist/api.d.mts +810 -64
  15. package/dist/api.mjs +782 -1
  16. package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
  17. package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
  18. package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
  19. package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
  20. package/dist/budget-Cvwn54qV.mjs +9285 -0
  21. package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
  22. package/dist/build-cache-Dv7RN200.mjs +602 -0
  23. package/dist/build-plan-DUC8Ka9y.mjs +248 -0
  24. package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
  25. package/dist/cache-manifest.mjs +1 -1
  26. package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
  27. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
  28. package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
  29. package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
  30. package/dist/cli.mjs +1 -1
  31. package/dist/client-OyRoEuSr.mjs +1577 -0
  32. package/dist/collector-run.d.mts +4 -40
  33. package/dist/collector-run.mjs +9 -8
  34. package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
  35. package/dist/config-DlrsduwG.mjs +955 -0
  36. package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
  37. package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
  38. package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
  39. package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
  40. package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
  41. package/dist/device-DklWZLqb.mjs +1068 -0
  42. package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
  43. package/dist/device-host-worker.mjs +76 -79
  44. package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
  45. package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
  46. package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
  47. package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
  48. package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
  49. package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
  50. package/dist/doctor-fingerprint.mjs +19 -0
  51. package/dist/doctor-thjWAV0z.mjs +2 -0
  52. package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
  53. package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
  54. package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
  55. package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
  56. package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
  57. package/dist/exec-DEoAhcze.mjs +858 -0
  58. package/dist/exec-DnYc4HGH.d.mts +78 -0
  59. package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
  60. package/dist/gc-DnNDQyaP.mjs +3 -0
  61. package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
  62. package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
  63. package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
  64. package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
  65. package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
  66. package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
  67. package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
  68. package/dist/idle-C4cZ757K.d.mts +24 -0
  69. package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
  70. package/dist/ios-CDvlmUs7.d.mts +24 -0
  71. package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
  72. package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
  73. package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
  74. package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
  75. package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
  76. package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
  77. package/dist/ios-signing-BtAffm0A.mjs +489 -0
  78. package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
  79. package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
  80. package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
  81. package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
  82. package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
  83. package/dist/logs-BfwwadsZ.mjs +479 -0
  84. package/dist/logs-jTS_lHSo.mjs +248 -0
  85. package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
  86. package/dist/macos-NfV2D7dO.mjs +694 -0
  87. package/dist/macos-run.mjs +1 -1
  88. package/dist/maintenance-run.mjs +123 -248
  89. package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
  90. package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
  91. package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
  92. package/dist/native-android-CqgnOgsT.mjs +645 -0
  93. package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
  94. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
  95. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  96. package/dist/native-run-NwUuxbkg.mjs +276 -0
  97. package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
  98. package/dist/native-source-Y0yLhFyQ.mjs +133 -0
  99. package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
  100. package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
  101. package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
  102. package/dist/offload-worker.d.mts +59 -41
  103. package/dist/offload-worker.mjs +478 -115
  104. package/dist/operation-exec-BW0em61G.mjs +171 -0
  105. package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
  106. package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
  107. package/dist/paths-BsJMoPP2.mjs +12 -0
  108. package/dist/paths-DQtTgsBf.mjs +42 -0
  109. package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
  110. package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
  111. package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
  112. package/dist/prebuild-D4JoEAEs.mjs +484 -0
  113. package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
  114. package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
  115. package/dist/pull-request-eODyIqZF.d.mts +124 -0
  116. package/dist/pull-requests.d.mts +2 -120
  117. package/dist/pull-requests.mjs +2 -2
  118. package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
  119. package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
  120. package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
  121. package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
  122. package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
  123. package/dist/registration-BcRgF6Ox.mjs +51 -0
  124. package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
  125. package/dist/reload-D7AVlb8N.mjs +2 -0
  126. package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
  127. package/dist/result-D2Ykz_iD.mjs +435 -0
  128. package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
  129. package/dist/selection-DSMbWEX2.mjs +620 -0
  130. package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
  131. package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
  132. package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
  133. package/dist/server-expo-D58c9L0M.mjs +2 -0
  134. package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
  135. package/dist/settings-DpR-1Wnn.mjs +114 -0
  136. package/dist/settings-write-CzD60rOD.mjs +360 -0
  137. package/dist/settings.schema.json +176 -16
  138. package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
  139. package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
  140. package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
  141. package/dist/stage-Bps5oius.mjs +200 -0
  142. package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
  143. package/dist/start-EojN4WFz.mjs +1364 -0
  144. package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
  145. package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
  146. package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
  147. package/dist/stats-report-BzaPrRm6.mjs +16 -0
  148. package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
  149. package/dist/status-EvrK72L2.mjs +2 -0
  150. package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
  151. package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
  152. package/dist/status-worker.d.mts +1 -0
  153. package/dist/status-worker.mjs +19 -0
  154. package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
  155. package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
  156. package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
  157. package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
  158. package/dist/supervisor-run.d.mts +8 -17
  159. package/dist/supervisor-run.mjs +56 -28
  160. package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
  161. package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
  162. package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
  163. package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
  164. package/dist/toolchain-BY8X8HXx.mjs +2 -0
  165. package/dist/toolchain-DpJMHq0n.mjs +876 -0
  166. package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
  167. package/dist/trigger-yb_nFzPF.mjs +2 -0
  168. package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
  169. package/dist/web-CZ07gd77.mjs +2 -0
  170. package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
  171. package/dist/web-run.mjs +13 -12
  172. package/dist/windows-report.d.mts +1 -0
  173. package/dist/windows-report.mjs +18 -0
  174. package/dist/windows-report.ps1 +43 -0
  175. package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
  176. package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
  177. package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
  178. package/dist/worktree-ZqZVjD9K.mjs +2 -0
  179. package/dist/xcode-BXn9-xYx.mjs +896 -0
  180. package/package.json +7 -5
  181. package/shim/android-audio/Main.java +24 -0
  182. package/shim/android-audio/README.md +17 -0
  183. package/shim/android-audio.jar +0 -0
  184. package/shim/android-optimizations.gradle +7 -5
  185. package/dist/activity-BSV745Kz.mjs +0 -629
  186. package/dist/api-qvOzWyfO.mjs +0 -154
  187. package/dist/api-run.mjs +0 -294
  188. package/dist/app-install-BIKtMfPq.mjs +0 -896
  189. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  190. package/dist/budget-f7516Zk0.mjs +0 -4106
  191. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  192. package/dist/cancellation-C_22VQTH.mjs +0 -24
  193. package/dist/client-qQAaXSUs.mjs +0 -1771
  194. package/dist/config-BYDxlMY3.mjs +0 -562
  195. package/dist/device-DuiPJQSn.mjs +0 -290
  196. package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
  197. package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
  198. package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
  199. package/dist/exec-DqKo9GKJ.mjs +0 -268
  200. package/dist/git-DDfFzkMm.mjs +0 -45
  201. package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
  202. package/dist/logs-BGrEUaEs.mjs +0 -383
  203. package/dist/macos-Ch5VJmcS.mjs +0 -584
  204. package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
  205. package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
  206. package/dist/native-android-D5qc3-_v.mjs +0 -226
  207. package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
  208. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  209. package/dist/plan-C4TjdPsR.mjs +0 -260
  210. package/dist/prebuild-DYbucPXy.mjs +0 -212
  211. package/dist/preview-78a9kR_-.mjs +0 -1011
  212. package/dist/react-native-build-CtCccJtb.mjs +0 -239
  213. package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
  214. package/dist/remote-cache-OyOyVIS3.mjs +0 -526
  215. package/dist/result-CaJg5Iat.mjs +0 -186
  216. package/dist/server-expo-Bigriskl.mjs +0 -2
  217. package/dist/settings-BORNaaCO.mjs +0 -402
  218. package/dist/settings-vk3mJGSm.d.mts +0 -13
  219. package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
  220. package/dist/stage-KNTQopqv.mjs +0 -157
  221. package/dist/start-BWqzODpb.mjs +0 -1116
  222. package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
  223. package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
  224. package/dist/tailnet-Dh-qiYzG.mjs +0 -265
  225. package/dist/toolchain-BFkAcstd.mjs +0 -2
  226. package/dist/toolchain-DxSsNssu.mjs +0 -1657
  227. package/dist/trigger-9_USgmxz.mjs +0 -2
  228. package/dist/web-Dq-i3wzJ.mjs +0 -2
  229. package/dist/worktree-DpLdCHga.mjs +0 -2
  230. package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
  231. package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
@@ -1,13 +1,14 @@
1
- import { _ as loadConfig$1, d as getConfigDir, f as getConfigPath$1, h as getRepoSettings, m as getProjectSettings } from "./config-BYDxlMY3.mjs";
2
- import { n as isTimeoutError, t as getExecutor } from "./exec-DqKo9GKJ.mjs";
3
- import { r as gitQuiet, t as git } from "./git-DDfFzkMm.mjs";
1
+ import { n as isTimeoutError, r as WorkspaceProcessCleanupError, t as getExecutor } from "./exec-DEoAhcze.mjs";
2
+ import { _ as loadConfig$1, d as getConfigDir, f as getConfigPath$1, h as getRepoSettings, m as getProjectSettings } from "./config-DlrsduwG.mjs";
3
+ import { c as gitQuiet, f as throwIfCancelled, l as gitQuietAsync, o as git, r as childEnvironment, s as gitAsync } from "./operation-exec-BW0em61G.mjs";
4
4
  import { accessSync, chmodSync, constants, lstatSync, mkdirSync, mkdtempSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
5
6
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
- import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, normalize, relative as relative$1, resolve as resolve$1, sep as sep$1 } from "path";
7
+ import { ambientEnv, buildCacheRoot } from "@stim-cli/core";
7
8
  import { REMOTE_DEVICE_BACKENDS, SETTINGS, SETTING_GROUPS, TUNNEL_MODES, WEB_VIEWPORTS, acceptsShape, coerceSettingText, expectedShape, isLayeredSetting, settingDefinition, settingValueError } from "@stim-cli/core/state";
8
- import { chmodSync as chmodSync$1, existsSync as existsSync$1, lstatSync as lstatSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, statSync as statSync$1, utimesSync as utimesSync$1 } from "fs";
9
- import { buildCacheRoot } from "@stim-cli/core";
10
- import { tmpdir } from "node:os";
9
+ import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, normalize, relative as relative$1, resolve as resolve$1, sep as sep$1 } from "path";
10
+ import { existsSync as existsSync$1, lstatSync as lstatSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, statSync as statSync$1 } from "fs";
11
+ import { chmod, lstat, mkdir, readdir, rm, utimes } from "node:fs/promises";
11
12
  //#region src/temporary.ts
12
13
  function existingPath(path) {
13
14
  const missing = [];
@@ -41,7 +42,7 @@ function inside(parent, path) {
41
42
  function temporaryRoot(near) {
42
43
  const reference = existingPath(near);
43
44
  const insideReference = (path) => inside(reference.resolved, path);
44
- const override = process.env.STIM_TMPDIR ?? loadConfig$1()?.tempDir;
45
+ const override = ambientEnv().STIM_TMPDIR ?? loadConfig$1()?.tempDir;
45
46
  if (override !== void 0) {
46
47
  if (typeof override !== "string" || !isAbsolute(override)) throw new Error("STIM_TMPDIR / tempDir must be an absolute directory path.");
47
48
  const { existing, resolved } = existingPath(override);
@@ -88,13 +89,31 @@ function removeTemporaryEntry(path) {
88
89
  force: true
89
90
  });
90
91
  }
92
+ async function removeTemporaryEntryAsync(path, signal) {
93
+ signal?.throwIfAborted();
94
+ const info = await lstat(path).catch((error) => {
95
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
96
+ throw error;
97
+ });
98
+ if (info?.isDirectory()) {
99
+ await chmod(path, info.mode | 448);
100
+ for (const entry of await readdir(path, { withFileTypes: true })) if (entry.isDirectory()) await removeTemporaryEntryAsync(join(path, entry.name), signal);
101
+ }
102
+ signal?.throwIfAborted();
103
+ await rm(path, {
104
+ recursive: true,
105
+ force: true
106
+ });
107
+ signal?.throwIfAborted();
108
+ }
91
109
  //#endregion
92
110
  //#region src/workspace/worktree.ts
93
111
  const CARRY_SKIP_BASENAMES = /* @__PURE__ */ new Set([
94
112
  ".DerivedData",
95
113
  ".DS_Store",
96
114
  ".idea",
97
- ".jj"
115
+ ".jj",
116
+ ".pnpm-store"
98
117
  ]);
99
118
  function isCarrySkipped(rel) {
100
119
  return /(^|\/)android\/build\/generated\/autolinking(\/|$)/.test(rel) || String(rel).split("/").some((seg) => CARRY_SKIP_BASENAMES.has(seg));
@@ -102,6 +121,24 @@ function isCarrySkipped(rel) {
102
121
  function nativePath(path) {
103
122
  return sep$1 === "/" ? path : path.replaceAll("/", sep$1);
104
123
  }
124
+ async function gitReadAsync(dir, args, { removal, env, signal, declareFor, untrimmed }) {
125
+ signal ??= getExecutor().reportSignal?.();
126
+ try {
127
+ return await gitAsync(dir, args, {
128
+ ...env ? childEnvironment(env) : {},
129
+ signal,
130
+ ...removal ? { timeoutMs: REMOVAL_CHECK_TIMEOUT_MS } : {},
131
+ killSignal: "SIGKILL",
132
+ declareFor,
133
+ untrimmed
134
+ });
135
+ } catch (error) {
136
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
137
+ signal?.throwIfAborted();
138
+ if (removal && isTimeoutError(error)) throw error;
139
+ return null;
140
+ }
141
+ }
105
142
  function gitRead(dir, args, { removal }) {
106
143
  return removal ? removalCheck(dir, args) : gitQuiet(dir, args);
107
144
  }
@@ -113,48 +150,82 @@ function gitCommonDir(cwd, opts = {}) {
113
150
  ], opts);
114
151
  return out ? nativePath(out.trim()) : null;
115
152
  }
153
+ async function gitCommonDirAsync(cwd, options = {}) {
154
+ const out = await gitReadAsync(cwd, [
155
+ "rev-parse",
156
+ "--path-format=absolute",
157
+ "--git-common-dir"
158
+ ], options);
159
+ return out ? nativePath(out.trim()) : null;
160
+ }
116
161
  function repoRoot(cwd) {
117
162
  const out = gitQuiet(cwd, ["rev-parse", "--show-toplevel"]);
118
163
  return out ? nativePath(out.trim()) : null;
119
164
  }
165
+ async function repoRootAsync(cwd, options = {}) {
166
+ const out = await gitReadAsync(cwd, ["rev-parse", "--show-toplevel"], options);
167
+ return out ? nativePath(out.trim()) : null;
168
+ }
169
+ function upstreamState(name, counts) {
170
+ const [ahead = NaN, behind = NaN] = counts.trim().split(/\s+/).map(Number);
171
+ if (!name || !Number.isInteger(ahead) || !Number.isInteger(behind)) return null;
172
+ return {
173
+ name,
174
+ ahead,
175
+ behind
176
+ };
177
+ }
120
178
  function locallyKnownUpstream(projectRoot) {
121
179
  try {
122
- const name = git(projectRoot, [
180
+ return upstreamState(git(projectRoot, [
123
181
  "rev-parse",
124
182
  "--abbrev-ref",
125
183
  "--symbolic-full-name",
126
184
  "@{upstream}"
127
- ], { timeoutMs: 5e3 });
128
- const counts = git(projectRoot, [
185
+ ], { timeoutMs: 5e3 }), git(projectRoot, [
129
186
  "rev-list",
130
187
  "--left-right",
131
188
  "--count",
132
189
  "HEAD...@{upstream}"
133
- ], { timeoutMs: 5e3 }).trim().split(/\s+/).map(Number);
134
- const ahead = counts[0] ?? NaN;
135
- const behind = counts[1] ?? NaN;
136
- if (!name || !Number.isInteger(ahead) || !Number.isInteger(behind)) return null;
137
- return {
138
- name,
139
- ahead,
140
- behind
141
- };
190
+ ], { timeoutMs: 5e3 }));
142
191
  } catch {
143
192
  return null;
144
193
  }
145
194
  }
146
- function warmWorktreePaths(cwd) {
147
- const currentRoot = repoRoot(cwd);
195
+ async function locallyKnownUpstreamAsync(projectRoot) {
196
+ try {
197
+ return upstreamState(await gitAsync(projectRoot, [
198
+ "rev-parse",
199
+ "--abbrev-ref",
200
+ "--symbolic-full-name",
201
+ "@{upstream}"
202
+ ], { timeoutMs: 5e3 }), await gitAsync(projectRoot, [
203
+ "rev-list",
204
+ "--left-right",
205
+ "--count",
206
+ "HEAD...@{upstream}"
207
+ ], { timeoutMs: 5e3 }));
208
+ } catch {
209
+ return null;
210
+ }
211
+ }
212
+ async function warmWorktreePaths(cwd, operation) {
213
+ const options = {
214
+ env: operation?.env,
215
+ signal: operation?.signal,
216
+ declareFor: operation
217
+ };
218
+ const currentRoot = await repoRootAsync(cwd, options);
148
219
  if (!currentRoot) throw new Error("Not a git repository.");
149
220
  const target = realpathSync$1(currentRoot);
150
- const source = resolveSourceCheckout(target);
221
+ const source = await resolveSourceCheckoutAsync(target, options);
151
222
  if ("refusal" in source) throw new Error(source.refusal);
152
- if (!source.entries.find((entry) => canonicalPath(entry.path) === target)) throw new Error("Could not identify the linked worktree and its source checkout.");
223
+ if (!source.entries.some((entry) => canonicalPath(entry.path) === target)) throw new Error("Could not identify the linked worktree and its source checkout.");
153
224
  const root = realpathSync$1(source.path);
154
225
  if (root === target) throw new Error("Run stim worktree warm from a linked worktree, not the source checkout.");
155
- const sourceRoot = repoRoot(root);
156
- const sourceCommon = gitCommonDir(root);
157
- const targetCommon = gitCommonDir(target);
226
+ const sourceRoot = await repoRootAsync(root, options);
227
+ const sourceCommon = await gitCommonDirAsync(root, options);
228
+ const targetCommon = await gitCommonDirAsync(target, options);
158
229
  if (!sourceRoot || realpathSync$1(sourceRoot) !== root || !sourceCommon || !targetCommon || realpathSync$1(sourceCommon) !== realpathSync$1(targetCommon)) throw new Error("Could not verify that the source checkout belongs to this linked worktree.");
159
230
  return {
160
231
  root,
@@ -184,16 +255,19 @@ function canonicalPath(path) {
184
255
  return resolve$1(path);
185
256
  }
186
257
  }
187
- function nestedWorktreePaths(root) {
188
- const source = canonicalPath(root);
189
- const paths = /* @__PURE__ */ new Set();
190
- const out = gitQuiet(root, [
258
+ async function nestedWorktreePaths(root, options = {}) {
259
+ const out = await gitReadAsync(root, [
191
260
  "worktree",
192
261
  "list",
193
262
  "--porcelain"
194
- ]);
263
+ ], options);
195
264
  if (out === null) throw new Error("Could not list Git worktrees. Refusing to carry ignored files.");
196
- for (const entry of parseWorktrees(out)) {
265
+ return relativeWorktreePaths(root, parseWorktrees(out));
266
+ }
267
+ function relativeWorktreePaths(root, entries) {
268
+ const source = canonicalPath(root);
269
+ const paths = /* @__PURE__ */ new Set();
270
+ for (const entry of entries) {
197
271
  const rel = relative$1(source, canonicalPath(entry.path));
198
272
  if (!rel || rel === ".." || rel.startsWith(`..${sep$1}`) || isAbsolute$1(rel)) continue;
199
273
  paths.add(rel.split(sep$1).join("/"));
@@ -204,13 +278,15 @@ function overlapsNestedWorktree(rel, nestedPaths) {
204
278
  const path = String(rel).replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/$/, "");
205
279
  return nestedPaths.some((nested) => path === nested || path.startsWith(`${nested}/`) || nested.startsWith(`${path}/`));
206
280
  }
207
- function listTrackedPaths(dir) {
208
- const out = gitQuiet(dir, ["ls-files", "-z"]);
281
+ async function listTrackedPaths(dir, options = {}) {
282
+ const out = await gitReadAsync(dir, ["ls-files", "-z"], {
283
+ ...options,
284
+ untrimmed: true
285
+ });
209
286
  if (out === null) return null;
210
287
  return out.split("\0").filter(Boolean);
211
288
  }
212
- function trackedGuard(dir) {
213
- const paths = listTrackedPaths(dir);
289
+ function trackedPathsGuard(paths) {
214
290
  if (paths === null) return {
215
291
  known: false,
216
292
  covers: () => false
@@ -227,8 +303,8 @@ function trackedGuard(dir) {
227
303
  }
228
304
  };
229
305
  }
230
- function listGitignoredEntries(root) {
231
- const out = git(root, [
306
+ async function listGitignoredEntries(root, options = {}) {
307
+ return (await gitAsync(root, [
232
308
  "ls-files",
233
309
  "--others",
234
310
  "--ignored",
@@ -236,13 +312,17 @@ function listGitignoredEntries(root) {
236
312
  "--directory",
237
313
  "--no-empty-directory",
238
314
  "-z"
239
- ], { timeoutMs: "unbounded" });
240
- if (!out) return [];
241
- return out.split("\0").filter(Boolean).map((e) => e.endsWith("/") ? e.slice(0, -1) : e);
242
- }
243
- function listCarryableIgnoredEntries(root, patterns) {
244
- const nested = nestedWorktreePaths(root);
245
- return listGitignoredEntries(root).filter((rel) => !isCarrySkipped(rel) && !overlapsNestedWorktree(rel, nested) && !matchesInclude(rel, patterns));
315
+ ], {
316
+ ...options.env ? childEnvironment(options.env) : {},
317
+ signal: options.signal,
318
+ declareFor: options.declareFor,
319
+ timeoutMs: "unbounded",
320
+ untrimmed: true
321
+ })).split("\0").filter(Boolean).map((entry) => entry.endsWith("/") ? entry.slice(0, -1) : entry);
322
+ }
323
+ async function listCarryableIgnoredEntries(root, patterns, options = {}) {
324
+ const nested = await nestedWorktreePaths(root, options);
325
+ return (await listGitignoredEntries(root, options)).filter((rel) => !isCarrySkipped(rel) && !overlapsNestedWorktree(rel, nested) && !matchesInclude(rel, patterns));
246
326
  }
247
327
  function missingDestinationReason(target, rel) {
248
328
  const parts = rel.split("/");
@@ -254,35 +334,54 @@ function missingDestinationReason(target, rel) {
254
334
  }
255
335
  return lstatSync$1(join$1(target, rel), { throwIfNoEntry: false }) ? "exists" : null;
256
336
  }
257
- function removeCopiedExclusions(path, rel) {
258
- const entries = readdirSync$1(path, { withFileTypes: true });
337
+ async function removeCopiedExclusionsAsync(path, rel, signal) {
338
+ signal.throwIfAborted();
339
+ const entries = await readdir(path, { withFileTypes: true });
259
340
  const excluded = entries.filter((entry) => isCarrySkipped(`${rel}/${entry.name}`));
260
- if (excluded.length > 0) {
261
- const stat = lstatSync$1(path);
262
- chmodSync$1(path, stat.mode | 448);
341
+ if (excluded.length) {
342
+ const stat = await lstat(path);
343
+ await chmod(path, stat.mode | 448);
263
344
  try {
264
- for (const entry of excluded) removeTemporaryEntry(join$1(path, entry.name));
345
+ for (const entry of excluded) {
346
+ signal.throwIfAborted();
347
+ await removeTemporaryEntryAsync(join$1(path, entry.name), signal);
348
+ }
265
349
  } finally {
266
- utimesSync$1(path, stat.atime, stat.mtime);
267
- chmodSync$1(path, stat.mode);
350
+ await utimes(path, stat.atime, stat.mtime);
351
+ await chmod(path, stat.mode);
268
352
  }
269
353
  }
270
354
  for (const entry of entries) {
271
355
  const child = `${rel}/${entry.name}`;
272
- if (entry.isDirectory() && !isCarrySkipped(child)) removeCopiedExclusions(join$1(path, entry.name), child);
356
+ if (entry.isDirectory() && !isCarrySkipped(child)) await removeCopiedExclusionsAsync(join$1(path, entry.name), child, signal);
273
357
  }
274
358
  }
275
- function cloneIgnoredEntries({ root, target, patterns }) {
359
+ async function cloneIgnoredEntries({ root, target, patterns, operation }) {
360
+ const options = {
361
+ ...childEnvironment(operation.env),
362
+ signal: operation.signal,
363
+ declareFor: operation,
364
+ timeoutMs: "unbounded",
365
+ untrimmed: true
366
+ };
367
+ const reads = {
368
+ env: operation.env,
369
+ signal: operation.signal,
370
+ declareFor: operation
371
+ };
372
+ const guard = trackedPathsGuard(await listTrackedPaths(target, reads));
373
+ if (!guard.known) throw new Error("Could not list the destination's tracked files.");
374
+ const nested = await nestedWorktreePaths(target, reads);
375
+ const entries = await listCarryableIgnoredEntries(root, patterns, reads);
276
376
  const copied = [];
277
377
  const skipped = [];
278
378
  const failed = [];
279
379
  let cloned = true;
280
- const guard = trackedGuard(target);
281
- if (!guard.known) throw new Error("Could not list the destination's tracked files.");
282
- const nested = nestedWorktreePaths(target);
283
- for (const rel of listCarryableIgnoredEntries(root, patterns)) {
380
+ for (const rel of entries) {
381
+ operation.signal.throwIfAborted();
284
382
  const from = join$1(root, rel);
285
383
  const to = join$1(target, rel);
384
+ let copying = false;
286
385
  try {
287
386
  const reason = guard.covers(rel) ? "tracked" : overlapsNestedWorktree(rel, nested) ? "nested worktree" : missingDestinationReason(target, rel);
288
387
  if (reason) {
@@ -292,28 +391,34 @@ function cloneIgnoredEntries({ root, target, patterns }) {
292
391
  });
293
392
  continue;
294
393
  }
295
- mkdirSync$1(dirname$1(to), { recursive: true });
394
+ await mkdir(dirname$1(to), { recursive: true });
395
+ copying = true;
296
396
  try {
297
- getExecutor().runFile("cp", [
397
+ await getExecutor().runFileAsync("cp", [
298
398
  "-Rc",
299
399
  from,
300
400
  to
301
- ], { timeoutMs: "unbounded" });
302
- } catch {
303
- removeTemporaryEntry(to);
304
- getExecutor().runFile("cp", [
401
+ ], options);
402
+ } catch (cause) {
403
+ if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
404
+ operation.signal.throwIfAborted();
405
+ await removeTemporaryEntryAsync(to);
406
+ await getExecutor().runFileAsync("cp", [
305
407
  "-R",
306
408
  from,
307
409
  to
308
- ], { timeoutMs: "unbounded" });
410
+ ], options);
309
411
  cloned = false;
310
412
  }
311
- if (lstatSync$1(to).isDirectory()) removeCopiedExclusions(to, rel);
413
+ if ((await lstat(to)).isDirectory()) await removeCopiedExclusionsAsync(to, rel, operation.signal);
312
414
  copied.push(rel);
313
- } catch (e) {
415
+ } catch (cause) {
416
+ if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
417
+ if (copying) await removeTemporaryEntryAsync(to);
418
+ operation.signal.throwIfAborted();
314
419
  failed.push({
315
420
  file: rel,
316
- error: String(e?.message || e)
421
+ error: String(cause?.message || cause)
317
422
  });
318
423
  }
319
424
  }
@@ -452,8 +557,8 @@ const FINGERPRINT_INPUT_FILES = [
452
557
  "app.config.mjs",
453
558
  "package.json"
454
559
  ];
455
- function dirtyFingerprintFiles(root) {
456
- const out = gitQuiet(root, [
560
+ async function dirtyFingerprintFiles(root) {
561
+ const out = await gitQuietAsync(root, [
457
562
  "status",
458
563
  "--porcelain",
459
564
  "--",
@@ -475,86 +580,113 @@ function removalCheck(dir, args) {
475
580
  return null;
476
581
  }
477
582
  }
478
- function hasUncommittedWork(dir) {
479
- const out = removalCheck(dir, ["status", "--porcelain"]);
583
+ function removalCheckAsync(dir, args, options = {}) {
584
+ return gitReadAsync(dir, args, {
585
+ ...options,
586
+ removal: true
587
+ });
588
+ }
589
+ async function hasUncommittedWorkAsync(dir, options = {}) {
590
+ const out = await removalCheckAsync(dir, ["status", "--porcelain"], options);
480
591
  if (out === null) return null;
481
592
  return out.trim().length > 0;
482
593
  }
483
594
  /** The porcelain status lines, or null when git cannot answer; throws when git times out. */
484
- function dirtyPaths(dir, { limit = 10 } = {}) {
485
- const out = removalCheck(dir, ["status", "--porcelain"]);
595
+ async function dirtyPathsAsync(dir, { limit = 10 } = {}, options = {}) {
596
+ const out = await removalCheckAsync(dir, ["status", "--porcelain"], options);
486
597
  if (out === null) return null;
487
- return out.split("\n").map((l) => normalizePorcelainLine(l.trimEnd())).filter(Boolean).slice(0, limit);
598
+ return out.split("\n").map((line) => normalizePorcelainLine(line.trimEnd())).filter(Boolean).slice(0, limit);
488
599
  }
489
600
  function normalizePorcelainLine(line) {
490
601
  if (line === "" || line[2] === " ") return line;
491
602
  return ` ${line}`;
492
603
  }
493
- function restoreFile(dir, file) {
494
- return gitQuiet(dir, [
495
- "checkout",
496
- "--",
497
- file
498
- ], { write: true }) !== null;
499
- }
500
604
  function isPodInstallChurn(paths) {
501
605
  if (!paths || paths.length === 0) return false;
502
606
  return paths.every((line) => /(?:^|\/)(?:Podfile\.lock|project\.pbxproj)$/.test(line.slice(3).trim()));
503
607
  }
504
608
  const SAFE_BRANCH_NAME = /^[A-Za-z0-9@._/-]+$/;
505
- function unpushedCommits(dir) {
506
- const branch = removalCheck(dir, [
609
+ async function unpushedCommitsAsync(dir, options = {}) {
610
+ const branch = await removalCheckAsync(dir, [
507
611
  "symbolic-ref",
508
612
  "--quiet",
509
613
  "--short",
510
614
  "HEAD"
511
- ]);
615
+ ], options);
512
616
  const own = branch === null ? "" : branch.trim();
513
617
  const protection = own && SAFE_BRANCH_NAME.test(own) ? [
514
618
  "--remotes",
515
619
  `--exclude=${own}`,
516
620
  "--branches"
517
621
  ] : ["--remotes"];
518
- if (!own && removalCheck(dir, [
622
+ if (!own && await removalCheckAsync(dir, [
519
623
  "rev-parse",
520
624
  "--abbrev-ref",
521
625
  "HEAD"
522
- ]) === "HEAD") protection.push("--branches");
523
- const out = removalCheck(dir, [
626
+ ], options) === "HEAD") protection.push("--branches");
627
+ const out = await removalCheckAsync(dir, [
524
628
  "log",
525
629
  "--oneline",
526
630
  "HEAD",
527
631
  "--not",
528
632
  ...protection
529
- ]);
633
+ ], options);
530
634
  if (out === null) return null;
531
- return out.split("\n").map((l) => l.trim()).filter(Boolean);
532
- }
533
- function hasRemote(dir) {
534
- const out = gitQuiet(dir, ["remote"]);
535
- return Boolean(out && out.trim().length > 0);
635
+ return out.split("\n").map((line) => line.trim()).filter(Boolean);
536
636
  }
537
- function branchExists(cwd, branch, opts = {}) {
637
+ function resolveFullRef(cwd, ref, opts = {}) {
538
638
  const out = gitRead(cwd, [
539
639
  "rev-parse",
540
640
  "--verify",
541
641
  "--quiet",
542
- `refs/heads/${branch}`
642
+ "--end-of-options",
643
+ `${ref}^{commit}`
543
644
  ], opts);
544
- return Boolean(out);
645
+ return out && out.trim() ? out.trim() : null;
545
646
  }
546
- function resolveFullRef(cwd, ref, opts = {}) {
547
- const out = gitRead(cwd, [
647
+ async function resolveFullRefAsync(cwd, ref, options = {}) {
648
+ const out = await gitReadAsync(cwd, [
548
649
  "rev-parse",
549
650
  "--verify",
550
651
  "--quiet",
551
652
  "--end-of-options",
552
653
  `${ref}^{commit}`
553
- ], opts);
654
+ ], options);
554
655
  return out && out.trim() ? out.trim() : null;
555
656
  }
556
- function removeWorktree(path, { from, force = false, platform = process.platform }) {
557
- const args = [
657
+ async function hasRemoteAsync(dir, options = {}) {
658
+ const out = await gitReadAsync(dir, ["remote"], options);
659
+ return Boolean(out && out.trim().length > 0);
660
+ }
661
+ async function branchExistsAsync(cwd, branch, options = {}) {
662
+ return Boolean(await gitReadAsync(cwd, [
663
+ "rev-parse",
664
+ "--verify",
665
+ "--quiet",
666
+ `refs/heads/${branch}`
667
+ ], options));
668
+ }
669
+ async function restoreFileAsync(dir, file, options = {}) {
670
+ try {
671
+ await gitAsync(dir, [
672
+ "checkout",
673
+ "--",
674
+ file
675
+ ], {
676
+ ...options.env ? childEnvironment(options.env) : {},
677
+ signal: options.signal,
678
+ declareFor: options.declareFor,
679
+ write: true
680
+ });
681
+ return true;
682
+ } catch (error) {
683
+ if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
684
+ options.signal?.throwIfAborted();
685
+ return false;
686
+ }
687
+ }
688
+ function worktreeRemoveArgs(path, force, platform) {
689
+ return [
558
690
  ...platform === "win32" ? ["-c", "core.longpaths=true"] : [],
559
691
  "worktree",
560
692
  "remove",
@@ -562,19 +694,32 @@ function removeWorktree(path, { from, force = false, platform = process.platform
562
694
  "--",
563
695
  path
564
696
  ];
565
- git(from, args, {
697
+ }
698
+ async function removeWorktreeAsync(path, { from, force = false, platform = process.platform, env, signal, declareFor }) {
699
+ await gitAsync(from, worktreeRemoveArgs(path, force, platform), {
700
+ ...env ? childEnvironment(env) : {},
701
+ signal,
702
+ declareFor,
566
703
  write: true,
567
704
  timeoutMs: "unbounded"
568
705
  });
569
706
  }
570
- function deleteBranch(cwd, branch, expectedSha) {
707
+ function branchDeleteArgs(branch, expectedSha) {
571
708
  if (!SAFE_BRANCH_NAME.test(branch) || branch.startsWith("-")) throw new Error(`Refusing branch ${JSON.stringify(branch)}: it is not a safe local branch name.`);
572
- git(cwd, [
709
+ return [
573
710
  "update-ref",
574
711
  "-d",
575
712
  `refs/heads/${branch}`,
576
713
  expectedSha
577
- ], { write: true });
714
+ ];
715
+ }
716
+ async function deleteBranchAsync(cwd, branch, expectedSha, options = {}) {
717
+ await gitAsync(cwd, branchDeleteArgs(branch, expectedSha), {
718
+ ...options.env ? childEnvironment(options.env) : {},
719
+ signal: options.signal,
720
+ declareFor: options.declareFor,
721
+ write: true
722
+ });
578
723
  }
579
724
  function parseWorktrees(out) {
580
725
  const entries = [];
@@ -590,18 +735,18 @@ function parseWorktrees(out) {
590
735
  return entries;
591
736
  }
592
737
  /** Null when git cannot list the index, so the answer is unknown; throws when git times out. */
593
- function hasPopulatedSubmodules(worktree) {
594
- const modules = removalCheck(worktree, [
738
+ async function hasPopulatedSubmodulesAsync(worktree, options = {}) {
739
+ const modules = await removalCheckAsync(worktree, [
595
740
  "rev-parse",
596
741
  "--git-path",
597
742
  "modules"
598
- ]);
743
+ ], options);
599
744
  if (modules && existsSync$1(resolve$1(worktree, nativePath(modules)))) return true;
600
- const staged = removalCheck(worktree, [
745
+ const staged = await removalCheckAsync(worktree, [
601
746
  "ls-files",
602
747
  "--stage",
603
748
  "-z"
604
- ]);
749
+ ], options);
605
750
  if (staged === null) return null;
606
751
  return staged.split("\0").some((line) => line.startsWith("160000 ") && existsSync$1(join$1(worktree, line.slice(line.indexOf(" ") + 1), ".git")));
607
752
  }
@@ -613,6 +758,14 @@ function listWorktrees(cwd, opts = {}) {
613
758
  ], opts);
614
759
  return out ? parseWorktrees(out) : [];
615
760
  }
761
+ async function listWorktreesAsync(cwd, options = {}) {
762
+ const out = await gitReadAsync(cwd, [
763
+ "worktree",
764
+ "list",
765
+ "--porcelain"
766
+ ], options);
767
+ return out ? parseWorktrees(out) : [];
768
+ }
616
769
  function branchOf(head) {
617
770
  return head.startsWith("ref: refs/heads/") ? head.slice(16) : void 0;
618
771
  }
@@ -699,11 +852,17 @@ function sourceCheckoutOf(entries) {
699
852
  const first = entries[0];
700
853
  return selectSourceCheckout(entries, first?.bare ? bareHeadBranch(first.path) : null);
701
854
  }
702
- function resolveSourceCheckout(cwd) {
703
- const entries = listWorktrees(cwd);
855
+ async function resolveSourceCheckoutAsync(cwd, options = {}) {
856
+ const entries = await listWorktreesAsync(cwd, options);
857
+ const first = entries[0];
858
+ const head = first?.bare ? (await gitReadAsync(first.path, [
859
+ "symbolic-ref",
860
+ "--quiet",
861
+ "HEAD"
862
+ ], options))?.trim() : null;
704
863
  return {
705
864
  entries,
706
- ...sourceCheckoutOf(entries)
865
+ ...selectSourceCheckout(entries, head?.startsWith("refs/heads/") ? head.slice(11) : null)
707
866
  };
708
867
  }
709
868
  //#endregion
@@ -1286,6 +1445,37 @@ function resolveProjectSettings(root) {
1286
1445
  settings: resolveSettings(context)
1287
1446
  };
1288
1447
  }
1448
+ /** Resolves repository paths asynchronously; declared probes run sequentially and cancellation rejects. */
1449
+ async function projectSettingsContextAsync(root, git = {
1450
+ gitCommonDir: gitCommonDirAsync,
1451
+ repoRoot: repoRootAsync
1452
+ }, { env = process.env, signal, declareFor } = {}) {
1453
+ throwIfCancelled(signal, "settings resolution");
1454
+ const options = {
1455
+ env,
1456
+ signal,
1457
+ declareFor
1458
+ };
1459
+ const common = Promise.resolve(git.gitCommonDir(root, options));
1460
+ const repo = declareFor ? common.then(() => git.repoRoot(root, options)) : git.repoRoot(root, options);
1461
+ const [commonResult, repoResult] = await Promise.allSettled([common, repo]);
1462
+ for (const result of [commonResult, repoResult]) if (result.status === "rejected" && (result.reason instanceof WorkspaceProcessCleanupError || result.reason instanceof Error && "reportCleanup" in result.reason)) throw result.reason;
1463
+ throwIfCancelled(signal, "settings resolution");
1464
+ if (commonResult.status === "rejected") throw commonResult.reason;
1465
+ if (repoResult.status === "rejected") throw repoResult.reason;
1466
+ return {
1467
+ projectPath: root,
1468
+ gitCommonDir: commonResult.value,
1469
+ repoRoot: repoResult.value
1470
+ };
1471
+ }
1472
+ async function resolveProjectSettingsAsync(root, options) {
1473
+ const context = await projectSettingsContextAsync(root, void 0, options);
1474
+ return {
1475
+ context,
1476
+ settings: resolveSettings(context)
1477
+ };
1478
+ }
1289
1479
  const METRO_COMMAND_PORT = "{port}";
1290
1480
  function metroCommandSetting(settings) {
1291
1481
  const value = settingValueAt(settings, "metro.command");
@@ -1348,7 +1538,7 @@ function cacheProviderSettingError(settings) {
1348
1538
  if ("options" in block && !isPlainObject(block.options)) return `Invalid cache.options setting ${JSON.stringify(block.options)}. Expected an object.`;
1349
1539
  return null;
1350
1540
  }
1351
- /** The remote target `remote` names, or null for `local`, which runs on this Mac whatever a lower layer sets. */
1541
+ /** The remote target `remote` names, or null for `local`, which runs on this machine whatever a lower layer sets. */
1352
1542
  function parseIosRemote(remote) {
1353
1543
  const selected = remote.trim();
1354
1544
  const reserved = selected.toLowerCase();
@@ -1459,4 +1649,4 @@ function webSettings(settings) {
1459
1649
  };
1460
1650
  }
1461
1651
  //#endregion
1462
- export { settingValueAt as $, metroIdleStopMinutesSetting as A, restoreFile as At, remoteAndroidSetting as B, iosSigningIdentitySha1Setting as C, locallyKnownUpstream as Ct, mergeSettingsLayers as D, repoRoot as Dt, maintenanceKeepSetting as E, removeWorktree as Et, parseIosRemote as F, makeTemporaryDirectory as Ft, resolveIosProjectDir as G, remoteIosSetting as H, projectSettingsContext as I, removeTemporaryEntry as It, runnableMetroCommand as J, resolveProjectSettings as K, publicUrlSetting as L, temporaryRoot as Lt, metroTunnelSettingError as M, unpushedCommits as Mt, metroWarmupUrlSetting as N, warmWorktreePaths as Nt, metroCommandSetting as O, resolveFullRef as Ot, ngrokUrlSetting as P, filesystemDevice as Pt, settingShapeErrors as Q, readCommittedSettings as R, iosSigningIdentitySettingError as S, listWorktrees as St, iosSimSlimProfileSetting as T, readWorktreeExclude as Tt, resolveAndroidLayout as U, remoteEasFallbackSetting as V, resolveCacheProviderConfig as W, settingOrigin as X, settingFile as Y, settingOriginScope as Z, iosLanHostSetting as _, hasPopulatedSubmodules as _t, SETTING_SHAPE_REMEDY as a, PUBLIC_METRO_ENV as at, iosProjectDirSettingError as b, isPodInstallChurn as bt, androidDataPartitionSizeBytes as c, resolveTailscaleBinary as ct, androidLayoutSetting as d, deleteBranch as dt, settingsLayers as et, androidLayoutSettingError as f, depsOutOfSync as ft, deviceReclaimIdleMinutesSetting as g, gitCommonDirOnDisk as gt, deviceIdleShutdownMinutesSetting as h, gitCommonDir as ht, SETTINGS_WITH_RESOLVE_TIME_FALLBACK as i, workspaceHiddenSetting as it, metroPortSetting as j, sourceCheckoutOf as jt, metroCommandSettingError as k, resolveSourceCheckout as kt, androidDataPartitionSizeGbSetting as l, branchExists as lt, defaultAndroidLayout as m, dirtyPaths as mt, METRO_COMMAND_PORT as n, unknownSettingKeys as nt, androidAvdConfigSetting as o, detectProviders as ot, cacheProviderSettingError as p, dirtyFingerprintFiles as pt, resolveSettings as q, PATH_SETTINGS as r, webSettings as rt, androidAvdConfigSettingError as s, planMetroReach as st, ANDROID_AVD_CONFIG_HELP as t, tunnelModeSetting as tt, androidDataPartitionSizeGbSettingError as u, cloneIgnoredEntries as ut, iosLanHostSettingError as v, hasRemote as vt, iosSigningIdentitySha1SettingError as w, podsOutOfSync as wt, iosSigningIdentitySetting as x, linkedWorktreesOnDisk as xt, iosProjectDirSetting as y, hasUncommittedWork as yt, realpathInside as z };
1652
+ export { settingOriginScope as $, metroIdleStopMinutesSetting as A, readWorktreeExclude as At, realpathInside as B, warmWorktreePaths as Bt, iosSigningIdentitySha1Setting as C, isPodInstallChurn as Ct, mergeSettingsLayers as D, locallyKnownUpstream as Dt, maintenanceKeepSetting as E, listWorktreesAsync as Et, parseIosRemote as F, resolveFullRefAsync as Ft, resolveCacheProviderConfig as G, temporaryRoot as Gt, remoteEasFallbackSetting as H, makeTemporaryDirectory as Ht, projectSettingsContext as I, resolveSourceCheckoutAsync as It, resolveProjectSettingsAsync as J, resolveIosProjectDir as K, projectSettingsContextAsync as L, restoreFileAsync as Lt, metroTunnelSettingError as M, repoRoot as Mt, metroWarmupUrlSetting as N, repoRootAsync as Nt, metroCommandSetting as O, locallyKnownUpstreamAsync as Ot, ngrokUrlSetting as P, resolveFullRef as Pt, settingOrigin as Q, publicUrlSetting as R, sourceCheckoutOf as Rt, iosSigningIdentitySettingError as S, hasUncommittedWorkAsync as St, iosSimSlimProfileSetting as T, listWorktrees as Tt, remoteIosSetting as U, removeTemporaryEntry as Ut, remoteAndroidSetting as V, filesystemDevice as Vt, resolveAndroidLayout as W, removeTemporaryEntryAsync as Wt, runnableMetroCommand as X, resolveSettings as Y, settingFile as Z, iosLanHostSetting as _, gitCommonDir as _t, SETTING_SHAPE_REMEDY as a, webSettings as at, iosProjectDirSettingError as b, hasPopulatedSubmodulesAsync as bt, androidDataPartitionSizeBytes as c, detectProviders as ct, androidLayoutSetting as d, branchExistsAsync as dt, settingShapeErrors as et, androidLayoutSettingError as f, cloneIgnoredEntries as ft, deviceReclaimIdleMinutesSetting as g, dirtyPathsAsync as gt, deviceIdleShutdownMinutesSetting as h, dirtyFingerprintFiles as ht, SETTINGS_WITH_RESOLVE_TIME_FALLBACK as i, unknownSettingKeys as it, metroPortSetting as j, removeWorktreeAsync as jt, metroCommandSettingError as k, podsOutOfSync as kt, androidDataPartitionSizeGbSetting as l, planMetroReach as lt, defaultAndroidLayout as m, depsOutOfSync as mt, METRO_COMMAND_PORT as n, settingsLayers as nt, androidAvdConfigSetting as o, workspaceHiddenSetting as ot, cacheProviderSettingError as p, deleteBranchAsync as pt, resolveProjectSettings as q, PATH_SETTINGS as r, tunnelModeSetting as rt, androidAvdConfigSettingError as s, PUBLIC_METRO_ENV as st, ANDROID_AVD_CONFIG_HELP as t, settingValueAt as tt, androidDataPartitionSizeGbSettingError as u, resolveTailscaleBinary as ut, iosLanHostSettingError as v, gitCommonDirAsync as vt, iosSigningIdentitySha1SettingError as w, linkedWorktreesOnDisk as wt, iosSigningIdentitySetting as x, hasRemoteAsync as xt, iosProjectDirSetting as y, gitCommonDirOnDisk as yt, readCommittedSettings as z, unpushedCommitsAsync as zt };