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.
- package/README.md +141 -8
- package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
- package/dist/act-DsuqEkiM.mjs +2801 -0
- package/dist/activity-CMLmzp7o.mjs +1397 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
- package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
- package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
- package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
- package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/android-project-DVWyCbWU.d.mts +391 -0
- package/dist/api.d.mts +810 -64
- package/dist/api.mjs +782 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
- package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
- package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
- package/dist/budget-Cvwn54qV.mjs +9285 -0
- package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
- package/dist/build-cache-Dv7RN200.mjs +602 -0
- package/dist/build-plan-DUC8Ka9y.mjs +248 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-OyRoEuSr.mjs +1577 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
- package/dist/config-DlrsduwG.mjs +955 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
- package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
- package/dist/device-DklWZLqb.mjs +1068 -0
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
- package/dist/device-host-worker.mjs +76 -79
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
- package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
- package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
- package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/doctor-thjWAV0z.mjs +2 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
- package/dist/exec-DEoAhcze.mjs +858 -0
- package/dist/exec-DnYc4HGH.d.mts +78 -0
- package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
- package/dist/gc-DnNDQyaP.mjs +3 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
- package/dist/idle-C4cZ757K.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
- package/dist/ios-CDvlmUs7.d.mts +24 -0
- package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
- package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
- package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
- package/dist/ios-signing-BtAffm0A.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
- package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
- package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
- package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
- package/dist/logs-BfwwadsZ.mjs +479 -0
- package/dist/logs-jTS_lHSo.mjs +248 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
- package/dist/macos-NfV2D7dO.mjs +694 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +123 -248
- package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
- package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
- package/dist/native-android-CqgnOgsT.mjs +645 -0
- package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
- package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-NwUuxbkg.mjs +276 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
- package/dist/native-source-Y0yLhFyQ.mjs +133 -0
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +59 -41
- package/dist/offload-worker.mjs +478 -115
- package/dist/operation-exec-BW0em61G.mjs +171 -0
- package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
- package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
- package/dist/prebuild-D4JoEAEs.mjs +484 -0
- package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
- package/dist/pull-request-eODyIqZF.d.mts +124 -0
- package/dist/pull-requests.d.mts +2 -120
- package/dist/pull-requests.mjs +2 -2
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
- package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
- package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
- package/dist/registration-BcRgF6Ox.mjs +51 -0
- package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
- package/dist/reload-D7AVlb8N.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
- package/dist/result-D2Ykz_iD.mjs +435 -0
- package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
- package/dist/selection-DSMbWEX2.mjs +620 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
- package/dist/server-expo-D58c9L0M.mjs +2 -0
- package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
- package/dist/settings-DpR-1Wnn.mjs +114 -0
- package/dist/settings-write-CzD60rOD.mjs +360 -0
- package/dist/settings.schema.json +176 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-Bps5oius.mjs +200 -0
- package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
- package/dist/start-EojN4WFz.mjs +1364 -0
- package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
- package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
- package/dist/stats-report-BzaPrRm6.mjs +16 -0
- package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
- package/dist/status-EvrK72L2.mjs +2 -0
- package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
- package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
- package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +56 -28
- package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
- package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
- package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
- package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
- package/dist/toolchain-BY8X8HXx.mjs +2 -0
- package/dist/toolchain-DpJMHq0n.mjs +876 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
- package/dist/trigger-yb_nFzPF.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
- package/dist/web-CZ07gd77.mjs +2 -0
- package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
- package/dist/web-run.mjs +13 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
- package/dist/worktree-ZqZVjD9K.mjs +2 -0
- package/dist/xcode-BXn9-xYx.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-audio/Main.java +24 -0
- package/shim/android-audio/README.md +17 -0
- package/shim/android-audio.jar +0 -0
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/macos-Ch5VJmcS.mjs +0 -584
- package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/settings-vk3mJGSm.d.mts +0 -13
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/start-BWqzODpb.mjs +0 -1116
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { c as pidExists } from "./metro-DiXtA3Ty.mjs";
|
|
3
|
+
import { n as easMachineStateRoot } from "./eas-session-ledger-DlY_serQ.mjs";
|
|
4
|
+
import { d as androidToolPath } from "./android-C7sVmyI9.mjs";
|
|
5
|
+
import { b as parseSimctlList } from "./ios-hcBpnEGk.mjs";
|
|
6
|
+
import { existsSync, readdirSync, statSync, watch } from "node:fs";
|
|
7
|
+
import { basename, dirname, join } from "node:path";
|
|
7
8
|
//#region src/status-watch.ts
|
|
8
9
|
const WATCH_FALLBACK_MS = 3e4;
|
|
9
|
-
const WATCH_LIGHT_INTERVAL_MS =
|
|
10
|
-
const
|
|
10
|
+
const WATCH_LIGHT_INTERVAL_MS = 1e3;
|
|
11
|
+
const WATCH_TABLES_INTERVAL_MS = 5e3;
|
|
12
|
+
const WATCH_MACHINE_INTERVAL_MS = 15e3;
|
|
13
|
+
const WATCH_PROCESS_INTERVAL_MS = 2e3;
|
|
14
|
+
const WATCH_SIMCTL_INTERVAL_MS = 3e4;
|
|
11
15
|
const ADB_RESTART_MIN_MS = 1e3;
|
|
12
16
|
const ADB_RESTART_MAX_MS = 6e4;
|
|
13
17
|
const SIMCTL_TIMEOUT_MS = 1e4;
|
|
@@ -86,6 +90,16 @@ function statusChange(dir, name) {
|
|
|
86
90
|
default: return "full";
|
|
87
91
|
}
|
|
88
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Whether a change to `name`, relative to a repository's git common directory, can change a worktree's git summary:
|
|
95
|
+
* its HEAD, index or a ref, in the main worktree or a linked one. Objects, logs and lock files cannot on their own.
|
|
96
|
+
*/
|
|
97
|
+
function gitChange(name) {
|
|
98
|
+
if (name === null) return true;
|
|
99
|
+
const path = name.replaceAll("\\", "/");
|
|
100
|
+
if (path.endsWith(".lock")) return false;
|
|
101
|
+
return /^(HEAD|index|packed-refs|FETCH_HEAD)$/.test(path) || path.startsWith("refs/") || /^worktrees\/[^/]+(\/(HEAD|index))?$/.test(path) || path === "worktrees";
|
|
102
|
+
}
|
|
89
103
|
/** A stable summary of every simulator's state, or null when the listing is unreadable. */
|
|
90
104
|
function simulatorSignature(simctlJson) {
|
|
91
105
|
try {
|
|
@@ -94,12 +108,18 @@ function simulatorSignature(simctlJson) {
|
|
|
94
108
|
return null;
|
|
95
109
|
}
|
|
96
110
|
}
|
|
111
|
+
const SIMULATOR_DIR = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;
|
|
97
112
|
/**
|
|
98
113
|
* Calls `onChange` when anything `stim status` reports may have changed:
|
|
99
|
-
* `$STIM_HOME` files,
|
|
100
|
-
*
|
|
114
|
+
* `$STIM_HOME` files, git HEADs, indexes and refs of the watched repositories,
|
|
115
|
+
* exits of the watched processes, adb device arrivals and departures, and
|
|
116
|
+
* simulator state. Process liveness is polled with a signal 0 that spawns
|
|
117
|
+
* nothing. simctl has no push API reachable from Node, so a simulator change is
|
|
118
|
+
* a write CoreSimulator makes in `deviceSet`: to `device_set.plist`, a device
|
|
119
|
+
* directory, or a device's `device.plist`, which carries its state. A slow
|
|
120
|
+
* simctl poll covers events FSEvents drops and a device set that cannot be watched.
|
|
101
121
|
*/
|
|
102
|
-
function watchStatusSources({ home, onChange, platform = process.platform, simctlIntervalMs = WATCH_SIMCTL_INTERVAL_MS }) {
|
|
122
|
+
function watchStatusSources({ home, deviceSet, onChange, platform = process.platform, simctlIntervalMs = WATCH_SIMCTL_INTERVAL_MS }) {
|
|
103
123
|
let stopped = false;
|
|
104
124
|
const watchers = /* @__PURE__ */ new Map();
|
|
105
125
|
const desiredDirs = () => {
|
|
@@ -111,6 +131,7 @@ function watchStatusSources({ home, onChange, platform = process.platform, simct
|
|
|
111
131
|
[join(home, "device-locks"), "leases"],
|
|
112
132
|
[easMachineStateRoot(), "eas"]
|
|
113
133
|
]);
|
|
134
|
+
if (platform === "darwin") return dirs;
|
|
114
135
|
let names = [];
|
|
115
136
|
try {
|
|
116
137
|
names = readdirSync(join(home, "workspaces"));
|
|
@@ -132,11 +153,26 @@ function watchStatusSources({ home, onChange, platform = process.platform, simct
|
|
|
132
153
|
for (const [dir, kind] of desired) {
|
|
133
154
|
if (watchers.has(dir)) continue;
|
|
134
155
|
try {
|
|
135
|
-
const
|
|
136
|
-
|
|
156
|
+
const recursive = platform === "darwin" && kind === "workspaces";
|
|
157
|
+
const watcher = watch(dir, { recursive }, (_event, name) => {
|
|
158
|
+
let source = kind;
|
|
159
|
+
let filename = name === null ? null : String(name);
|
|
160
|
+
if (recursive && filename !== null) {
|
|
161
|
+
const [, entry, child, ...nested] = filename.split("/");
|
|
162
|
+
if (entry !== void 0) {
|
|
163
|
+
if (entry === "logs" && child !== void 0 && nested.length === 0) {
|
|
164
|
+
source = "logs";
|
|
165
|
+
filename = child;
|
|
166
|
+
} else if (child === void 0) {
|
|
167
|
+
source = "workspace";
|
|
168
|
+
filename = entry;
|
|
169
|
+
} else return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const change = statusChange(source, filename);
|
|
137
173
|
if (!change) return;
|
|
138
|
-
if (
|
|
139
|
-
|
|
174
|
+
if (source === "home" || source === "workspaces" || source === "workspace") {
|
|
175
|
+
listingVersion++;
|
|
140
176
|
reconcile();
|
|
141
177
|
}
|
|
142
178
|
onChange(change);
|
|
@@ -149,16 +185,114 @@ function watchStatusSources({ home, onChange, platform = process.platform, simct
|
|
|
149
185
|
} catch {}
|
|
150
186
|
}
|
|
151
187
|
};
|
|
188
|
+
const repositories = /* @__PURE__ */ new Map();
|
|
189
|
+
const watchRepositories = (commonDirs) => {
|
|
190
|
+
if (stopped) return;
|
|
191
|
+
const wanted = new Set(commonDirs);
|
|
192
|
+
for (const [dir, watcher] of repositories) {
|
|
193
|
+
if (wanted.has(dir)) continue;
|
|
194
|
+
watcher.close();
|
|
195
|
+
repositories.delete(dir);
|
|
196
|
+
}
|
|
197
|
+
for (const dir of wanted) {
|
|
198
|
+
if (repositories.has(dir)) continue;
|
|
199
|
+
try {
|
|
200
|
+
const watcher = watch(dir, { recursive: true }, (_event, name) => {
|
|
201
|
+
if (gitChange(name === null ? null : String(name))) onChange("full");
|
|
202
|
+
});
|
|
203
|
+
watcher.on("error", () => {
|
|
204
|
+
watcher.close();
|
|
205
|
+
repositories.delete(dir);
|
|
206
|
+
});
|
|
207
|
+
repositories.set(dir, watcher);
|
|
208
|
+
} catch {}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
let processes = [];
|
|
212
|
+
const processTimer = setInterval(() => {
|
|
213
|
+
if (processes.some((pid) => !pidExists(pid))) {
|
|
214
|
+
processes = [];
|
|
215
|
+
onChange("full");
|
|
216
|
+
}
|
|
217
|
+
}, WATCH_PROCESS_INTERVAL_MS);
|
|
218
|
+
processTimer.unref();
|
|
152
219
|
const adb = trackAdbDevices(() => onChange("full"));
|
|
153
220
|
let simctl = null;
|
|
154
221
|
let listing = null;
|
|
155
|
-
let
|
|
222
|
+
let listingVersion = 0;
|
|
156
223
|
let simTimer = null;
|
|
157
|
-
|
|
224
|
+
const deviceWatchers = /* @__PURE__ */ new Map();
|
|
225
|
+
if (platform === "darwin" && deviceSet) {
|
|
226
|
+
const changed = () => {
|
|
227
|
+
listingVersion++;
|
|
228
|
+
check();
|
|
229
|
+
onChange("full");
|
|
230
|
+
};
|
|
231
|
+
const watchDir = (dir, listener) => {
|
|
232
|
+
try {
|
|
233
|
+
const ino = statSync(dir, { bigint: true }).ino;
|
|
234
|
+
const current = deviceWatchers.get(dir);
|
|
235
|
+
if (current?.ino === ino) return;
|
|
236
|
+
current?.watcher.close();
|
|
237
|
+
deviceWatchers.delete(dir);
|
|
238
|
+
const watcher = watch(dir, (_event, name) => {
|
|
239
|
+
if (!stopped && deviceWatchers.get(dir)?.watcher === watcher) listener(name === null ? null : String(name));
|
|
240
|
+
});
|
|
241
|
+
watcher.on("error", () => {
|
|
242
|
+
if (deviceWatchers.get(dir)?.watcher !== watcher) return;
|
|
243
|
+
watcher.close();
|
|
244
|
+
deviceWatchers.delete(dir);
|
|
245
|
+
});
|
|
246
|
+
deviceWatchers.set(dir, {
|
|
247
|
+
watcher,
|
|
248
|
+
ino
|
|
249
|
+
});
|
|
250
|
+
} catch {}
|
|
251
|
+
};
|
|
252
|
+
const watchDeviceSet = () => {
|
|
253
|
+
if (stopped) return;
|
|
254
|
+
let names = null;
|
|
255
|
+
try {
|
|
256
|
+
names = readdirSync(deviceSet);
|
|
257
|
+
} catch {}
|
|
258
|
+
const wanted = /* @__PURE__ */ new Set();
|
|
259
|
+
if (names) {
|
|
260
|
+
wanted.add(deviceSet);
|
|
261
|
+
for (const name of names) {
|
|
262
|
+
if (!SIMULATOR_DIR.test(name)) continue;
|
|
263
|
+
const dir = join(deviceSet, name);
|
|
264
|
+
const plist = join(dir, "device.plist");
|
|
265
|
+
wanted.add(existsSync(plist) ? plist : dir);
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
let dir = dirname(deviceSet);
|
|
269
|
+
while (dirname(dir) !== dir && !isDirectory(dir)) dir = dirname(dir);
|
|
270
|
+
wanted.add(dir);
|
|
271
|
+
}
|
|
272
|
+
for (const [dir, { watcher }] of deviceWatchers) {
|
|
273
|
+
if (wanted.has(dir)) continue;
|
|
274
|
+
watcher.close();
|
|
275
|
+
deviceWatchers.delete(dir);
|
|
276
|
+
}
|
|
277
|
+
for (const dir of wanted) if (dir === deviceSet) watchDir(dir, () => {
|
|
278
|
+
watchDeviceSet();
|
|
279
|
+
changed();
|
|
280
|
+
});
|
|
281
|
+
else if (basename(dir) === "device.plist") watchDir(dir, changed);
|
|
282
|
+
else if (dirname(dir) === deviceSet) watchDir(dir, (name) => {
|
|
283
|
+
if (name === null || name === "device.plist") changed();
|
|
284
|
+
});
|
|
285
|
+
else watchDir(dir, () => {
|
|
286
|
+
watchDeviceSet();
|
|
287
|
+
if (deviceWatchers.has(deviceSet)) changed();
|
|
288
|
+
});
|
|
289
|
+
};
|
|
158
290
|
let last = null;
|
|
159
291
|
const check = () => {
|
|
292
|
+
watchDeviceSet();
|
|
160
293
|
if (simctl || stopped) return;
|
|
161
294
|
const startedAt = Date.now();
|
|
295
|
+
const version = listingVersion;
|
|
162
296
|
let out = "";
|
|
163
297
|
const child = getExecutor().spawn("xcrun", [
|
|
164
298
|
"simctl",
|
|
@@ -176,18 +310,23 @@ function watchStatusSources({ home, onChange, platform = process.platform, simct
|
|
|
176
310
|
});
|
|
177
311
|
simctl = child;
|
|
178
312
|
child.stdout?.on("data", (chunk) => out += chunk.toString());
|
|
179
|
-
child.on("error", () => {
|
|
180
|
-
simctl = null;
|
|
181
|
-
});
|
|
313
|
+
child.on("error", () => {});
|
|
182
314
|
child.on("close", () => {
|
|
183
315
|
simctl = null;
|
|
316
|
+
if (stopped) return;
|
|
317
|
+
if (version !== listingVersion) {
|
|
318
|
+
check();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
184
321
|
const signature = simulatorSignature(out);
|
|
185
|
-
if (signature === null
|
|
322
|
+
if (signature === null) return;
|
|
323
|
+
const wasStale = listing?.version !== version;
|
|
186
324
|
listing = {
|
|
187
325
|
at: startedAt,
|
|
326
|
+
version,
|
|
188
327
|
json: out
|
|
189
328
|
};
|
|
190
|
-
if (last !== null && signature !== last) onChange("full");
|
|
329
|
+
if (last !== null && (signature !== last || wasStale)) onChange("full");
|
|
191
330
|
last = signature;
|
|
192
331
|
});
|
|
193
332
|
};
|
|
@@ -197,12 +336,21 @@ function watchStatusSources({ home, onChange, platform = process.platform, simct
|
|
|
197
336
|
reconcile();
|
|
198
337
|
return {
|
|
199
338
|
reconcile,
|
|
200
|
-
|
|
339
|
+
watchRepositories,
|
|
340
|
+
watchProcesses(pids) {
|
|
341
|
+
processes = [...new Set(pids)];
|
|
342
|
+
},
|
|
343
|
+
simulatorListing: () => listing && listing.version === listingVersion && Date.now() - listing.at <= 2 * simctlIntervalMs ? listing.json : null,
|
|
201
344
|
stop() {
|
|
202
345
|
stopped = true;
|
|
203
346
|
for (const watcher of watchers.values()) watcher.close();
|
|
204
347
|
watchers.clear();
|
|
348
|
+
for (const watcher of repositories.values()) watcher.close();
|
|
349
|
+
repositories.clear();
|
|
350
|
+
clearInterval(processTimer);
|
|
205
351
|
if (simTimer) clearInterval(simTimer);
|
|
352
|
+
for (const { watcher } of deviceWatchers.values()) watcher.close();
|
|
353
|
+
deviceWatchers.clear();
|
|
206
354
|
simctl?.kill("SIGKILL");
|
|
207
355
|
adb.stop();
|
|
208
356
|
}
|
|
@@ -249,6 +397,13 @@ function trackAdbDevices(onChange) {
|
|
|
249
397
|
child?.kill("SIGTERM");
|
|
250
398
|
} };
|
|
251
399
|
}
|
|
400
|
+
function isDirectory(path) {
|
|
401
|
+
try {
|
|
402
|
+
return statSync(path).isDirectory();
|
|
403
|
+
} catch {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
252
407
|
function ownerKey(owner) {
|
|
253
408
|
return JSON.stringify([
|
|
254
409
|
owner.kind,
|
|
@@ -265,7 +420,7 @@ function ownerSteady(before, after) {
|
|
|
265
420
|
/**
|
|
266
421
|
* The payload `status --watch --json` prints. A usage figure keeps its value from the `previous` printed payload until it moves by a step: an owner's `cpuPercent`
|
|
267
422
|
* and `memoryMb`, an environment's `memoryMb` and `capacity.committedMb`. An owner's row is kept whole, `residentMb`
|
|
268
|
-
* and `processes` included, until one of its two figures moves, so a
|
|
423
|
+
* and `processes` included, until one of its two figures moves, so a machine whose processes only jitter prints no new line.
|
|
269
424
|
*/
|
|
270
425
|
function watchPayload(previous, next) {
|
|
271
426
|
const payload = { ...next };
|
|
@@ -292,5 +447,47 @@ function watchPayload(previous, next) {
|
|
|
292
447
|
if (capacity.overCapacity === next.capacity.overCapacity && capacity.liveCount === next.capacity.liveCount && capacity.totalMemoryMb === next.capacity.totalMemoryMb && Math.abs(next.capacity.committedMb - capacity.committedMb) < 16) payload.capacity = capacity;
|
|
293
448
|
return payload;
|
|
294
449
|
}
|
|
450
|
+
const holdPullRequest = (worktree) => worktree.pullRequest ? {
|
|
451
|
+
...worktree,
|
|
452
|
+
pullRequest: {
|
|
453
|
+
...worktree.pullRequest,
|
|
454
|
+
checkedAt: ""
|
|
455
|
+
}
|
|
456
|
+
} : worktree;
|
|
457
|
+
/**
|
|
458
|
+
* The string `status --watch --json` compares to decide whether a line is new. It is the payload with the bookkeeping
|
|
459
|
+
* timestamps masked: each `pullRequest.checkedAt`, `maintenance.lastChecks`, `maintenance.lastPass.startedAt` and
|
|
460
|
+
* `durationMs`, and `maintenance.running.startedAt`. A change in only those fields prints no line; any printed line
|
|
461
|
+
* carries the current values.
|
|
462
|
+
*/
|
|
463
|
+
function watchChangeKey(payload) {
|
|
464
|
+
const { maintenance } = payload;
|
|
465
|
+
return JSON.stringify({
|
|
466
|
+
...payload,
|
|
467
|
+
environments: payload.environments.map((env) => env.worktree ? {
|
|
468
|
+
...env,
|
|
469
|
+
worktree: holdPullRequest(env.worktree)
|
|
470
|
+
} : env),
|
|
471
|
+
unprovisionedWorktrees: payload.unprovisionedWorktrees.map(holdPullRequest),
|
|
472
|
+
maintenance: maintenance && {
|
|
473
|
+
...maintenance,
|
|
474
|
+
lastChecks: {
|
|
475
|
+
pressure: null,
|
|
476
|
+
size: null,
|
|
477
|
+
worktree: null,
|
|
478
|
+
sweep: null
|
|
479
|
+
},
|
|
480
|
+
lastPass: maintenance.lastPass && {
|
|
481
|
+
...maintenance.lastPass,
|
|
482
|
+
startedAt: 0,
|
|
483
|
+
durationMs: 0
|
|
484
|
+
},
|
|
485
|
+
running: maintenance.running && {
|
|
486
|
+
...maintenance.running,
|
|
487
|
+
startedAt: ""
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
}
|
|
295
492
|
//#endregion
|
|
296
|
-
export {
|
|
493
|
+
export { createRefreshScheduler as a, watchStatusSources as c, WATCH_TABLES_INTERVAL_MS as i, WATCH_LIGHT_INTERVAL_MS as n, watchChangeKey as o, WATCH_MACHINE_INTERVAL_MS as r, watchPayload as s, WATCH_FALLBACK_MS as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { n as runStatusWatch } from "./status-WBDajew2.mjs";
|
|
2
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
3
|
+
//#region src/status-worker.ts
|
|
4
|
+
const STOP_EXIT_MS = 500;
|
|
5
|
+
const cwd = workerData?.cwd;
|
|
6
|
+
const watch = runStatusWatch({
|
|
7
|
+
json: true,
|
|
8
|
+
...typeof cwd === "string" ? { cwd } : {},
|
|
9
|
+
emit: (line) => parentPort?.postMessage({ line }),
|
|
10
|
+
failed: (message) => parentPort?.postMessage({ failed: message })
|
|
11
|
+
});
|
|
12
|
+
parentPort?.on("message", (message) => {
|
|
13
|
+
if (message !== "stop") return;
|
|
14
|
+
watch.stop();
|
|
15
|
+
parentPort?.close();
|
|
16
|
+
setTimeout(() => process.exit(0), STOP_EXIT_MS);
|
|
17
|
+
});
|
|
18
|
+
//#endregion
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { t as getExecutor } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { C as saveConfig, c as ensureConfig } from "./config-DlrsduwG.mjs";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { workspaceId } from "@stim-cli/core";
|
|
5
|
+
import { readHomeIdentity, withConfigLockAsync } from "@stim-cli/core/state";
|
|
6
|
+
import { realpath } from "node:fs/promises";
|
|
7
|
+
import { sharedWorkspaceURL } from "@stim-cli/core/workspace-link";
|
|
8
|
+
//#region src/workspace/home-identity.ts
|
|
9
|
+
function ensureHomeIdentity(signal) {
|
|
10
|
+
return withConfigLockAsync(() => {
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
const config = ensureConfig();
|
|
13
|
+
const existing = readHomeIdentity(config);
|
|
14
|
+
if (existing) return existing;
|
|
15
|
+
const id = randomUUID();
|
|
16
|
+
config.homeId = id;
|
|
17
|
+
saveConfig(config);
|
|
18
|
+
return id;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/devices/stim-desktop.ts
|
|
23
|
+
const LAUNCH_SERVICES_LOOKUP = `ObjC.import('AppKit'); const url = $.NSWorkspace.sharedWorkspace.URLForApplicationWithBundleIdentifier('dev.stim.desktop'); url.isNil() ? '' : url.path.js`;
|
|
24
|
+
const SCHEME_HANDLER_LOOKUP = `ObjC.import('AppKit'); const url = $.NSWorkspace.sharedWorkspace.URLForApplicationToOpenURL($.NSURL.URLWithString('stim-desktop://workspace')); url.isNil() ? '' : url.path.js`;
|
|
25
|
+
const STIM_DESKTOP_INSTALLED = "Stim Desktop installed";
|
|
26
|
+
/**
|
|
27
|
+
* macOS `open` passes its environment to an app it launches, so Stim Desktop
|
|
28
|
+
* started by a command run under a scoped `STIM_HOME` would serve that home.
|
|
29
|
+
*/
|
|
30
|
+
const STIM_DESKTOP_OPEN_OPTIONS = {
|
|
31
|
+
timeoutMs: 5e3,
|
|
32
|
+
killSignal: "SIGKILL",
|
|
33
|
+
omitEnv: ["STIM_HOME"]
|
|
34
|
+
};
|
|
35
|
+
/** Stim Desktop sets `STIM_DESKTOP_APP` to its bundle path for every command it runs; a non-empty value means Desktop is installed. */
|
|
36
|
+
function stimDesktopInstalled(platform = process.platform, env = process.env) {
|
|
37
|
+
if (platform !== "darwin") return false;
|
|
38
|
+
if (env.STIM_DESKTOP_APP) return true;
|
|
39
|
+
return launchServicesFinds(LAUNCH_SERVICES_LOOKUP);
|
|
40
|
+
}
|
|
41
|
+
/** `stimDesktopInstalled` without blocking the event loop. */
|
|
42
|
+
async function stimDesktopInstalledAsync(platform = process.platform, env = process.env, onSpawn) {
|
|
43
|
+
if (platform !== "darwin") return false;
|
|
44
|
+
if (env.STIM_DESKTOP_APP) return true;
|
|
45
|
+
const found = await getExecutor().runFileAsync("osascript", [
|
|
46
|
+
"-l",
|
|
47
|
+
"JavaScript",
|
|
48
|
+
"-e",
|
|
49
|
+
LAUNCH_SERVICES_LOOKUP
|
|
50
|
+
], {
|
|
51
|
+
timeoutMs: 5e3,
|
|
52
|
+
killSignal: "SIGKILL",
|
|
53
|
+
onSpawn
|
|
54
|
+
}).catch(() => "");
|
|
55
|
+
return Boolean(found);
|
|
56
|
+
}
|
|
57
|
+
function launchServicesFinds(script) {
|
|
58
|
+
return Boolean(getExecutor().runFileQuiet("osascript", [
|
|
59
|
+
"-l",
|
|
60
|
+
"JavaScript",
|
|
61
|
+
"-e",
|
|
62
|
+
script
|
|
63
|
+
], {
|
|
64
|
+
timeoutMs: 5e3,
|
|
65
|
+
killSignal: "SIGKILL"
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
async function stimDesktopHandlesLinks(platform = process.platform, env = process.env) {
|
|
69
|
+
if (platform !== "darwin") return false;
|
|
70
|
+
if (env.STIM_DESKTOP_APP) return true;
|
|
71
|
+
return Boolean(await getExecutor().runFileAsync("osascript", [
|
|
72
|
+
"-l",
|
|
73
|
+
"JavaScript",
|
|
74
|
+
"-e",
|
|
75
|
+
SCHEME_HANDLER_LOOKUP
|
|
76
|
+
], {
|
|
77
|
+
timeoutMs: 5e3,
|
|
78
|
+
killSignal: "SIGKILL"
|
|
79
|
+
}).catch(() => ""));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The links that open this workspace for a human, or undefined when no app on this Mac handles
|
|
83
|
+
* `stim-desktop://`. `target` names the device Stim Desktop focuses when the user opens the workspace.
|
|
84
|
+
*/
|
|
85
|
+
async function workspaceLinks(root, target, handlesLinks = stimDesktopHandlesLinks) {
|
|
86
|
+
if (!await handlesLinks()) return void 0;
|
|
87
|
+
return { desktop: await workspaceShareURL(root, target) };
|
|
88
|
+
}
|
|
89
|
+
/** A share URL for the canonical workspace in this Stim home, usable by its already-paired phone or Desktop. */
|
|
90
|
+
async function workspaceShareURL(root, target, signal) {
|
|
91
|
+
const canonical = await realpath(root);
|
|
92
|
+
return sharedWorkspaceURL({
|
|
93
|
+
machine: await ensureHomeIdentity(signal),
|
|
94
|
+
workspace: workspaceId(canonical),
|
|
95
|
+
...target
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function workspaceLinkLine(links) {
|
|
99
|
+
return `Open in Stim: ${links.desktop}`;
|
|
100
|
+
}
|
|
101
|
+
function settingDefault(setting, desktopInstalled = stimDesktopInstalled) {
|
|
102
|
+
if (setting.desktopDefault !== void 0 && desktopInstalled()) return {
|
|
103
|
+
value: setting.desktopDefault,
|
|
104
|
+
reason: STIM_DESKTOP_INSTALLED
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
value: setting.default,
|
|
108
|
+
reason: null
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { workspaceLinkLine as a, ensureHomeIdentity as c, stimDesktopInstalledAsync as i, settingDefault as n, workspaceLinks as o, stimDesktopInstalled as r, workspaceShareURL as s, STIM_DESKTOP_OPEN_OPTIONS as t };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as resolveCollectorTargets, c as stopWorkspaceNow, i as readSupervisorState, n as clearSupervisorState, o as runStop, r as readCollectorState, s as stopCommand, t as clearCollectorState } from "./stop-
|
|
1
|
+
import { h as resolveSupervisorTarget } from "./workspaces-CpANmBlq.mjs";
|
|
2
|
+
import { a as resolveCollectorTargets, c as stopWorkspaceNow, i as readSupervisorState, n as clearSupervisorState, o as runStop, r as readCollectorState, s as stopCommand, t as clearCollectorState } from "./stop-Mv6W9FAk.mjs";
|
|
3
3
|
export { clearCollectorState, clearSupervisorState, stopCommand as default, readCollectorState, readSupervisorState, resolveCollectorTargets, resolveSupervisorTarget, runStop, stopWorkspaceNow };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
6
|
-
import { n as stopHostedMacos } from "./hosted-macos-
|
|
1
|
+
import { g as process_identity_exports, i as withWorkspaceProcessLock, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
|
|
3
|
+
import { d as writeWorkspaceState, l as withWorkspaceStateLockAsync } from "./workspace-state-U08dEzhG.mjs";
|
|
4
|
+
import { a as macosRuntimeClaim, o as requiredMacosRecord } from "./state-08I3hw3_.mjs";
|
|
5
|
+
import { C as runningBundleInstancesAsync } from "./workspaces-CpANmBlq.mjs";
|
|
6
|
+
import { n as stopHostedMacos } from "./hosted-macos-_awYSpfv.mjs";
|
|
7
7
|
import { readMacosRecord } from "@stim-cli/core/state";
|
|
8
8
|
//#region src/macos/stop.ts
|
|
9
9
|
const APP_EXIT_MS = 5e3;
|
|
@@ -15,57 +15,67 @@ function signal(pid, name) {
|
|
|
15
15
|
if (error.code !== "ESRCH") throw error;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
async function stopProcesses(records, waitMs = APP_EXIT_MS) {
|
|
18
|
+
async function stopProcesses(records, waitMs = APP_EXIT_MS, operation) {
|
|
19
19
|
let live = [...new Map(records.map((record) => [record.pid, record])).values()];
|
|
20
20
|
for (const name of ["SIGTERM", "SIGKILL"]) {
|
|
21
|
+
operation?.signal.throwIfAborted();
|
|
21
22
|
live = live.filter((record) => {
|
|
22
23
|
const identity = (0, process_identity_exports.inspectProcessIdentity)(record);
|
|
23
24
|
if (identity === "gone" || identity === "different") return false;
|
|
24
25
|
if (identity !== "same") throw Object.assign(/* @__PURE__ */ new Error(`Cannot verify macOS owner pid ${record.pid}; no signal was sent.`), { code: "STIM_MACOS_OWNER_UNVERIFIED" });
|
|
25
26
|
return true;
|
|
26
27
|
});
|
|
27
|
-
for (const record of live)
|
|
28
|
-
|
|
28
|
+
for (const record of live) {
|
|
29
|
+
operation?.signal.throwIfAborted();
|
|
30
|
+
signal(record.pid, name);
|
|
31
|
+
}
|
|
32
|
+
const exited = await Promise.all(live.map((record) => (0, process_identity_exports.waitForProcessExit)(record, waitMs, operation?.signal)));
|
|
29
33
|
live = live.filter((_, index) => !exited[index]);
|
|
30
34
|
if (!live.length) return;
|
|
31
35
|
}
|
|
32
36
|
throw new Error(`Owned macOS process ${live.map((record) => record.pid).join(", ")} did not exit.`);
|
|
33
37
|
}
|
|
34
38
|
/** Stops every running copy of the workspace's owned app bundle, including copies LaunchServices started. */
|
|
35
|
-
async function stopBundleInstances(root) {
|
|
36
|
-
const instances =
|
|
37
|
-
await stopProcesses(instances);
|
|
39
|
+
async function stopBundleInstances(root, operation) {
|
|
40
|
+
const instances = await runningBundleInstancesAsync(root, operation);
|
|
41
|
+
await stopProcesses(instances, void 0, operation);
|
|
38
42
|
return instances.length > 0;
|
|
39
43
|
}
|
|
40
|
-
async function stopMacosAppHeld(root) {
|
|
44
|
+
async function stopMacosAppHeld(root, operation) {
|
|
45
|
+
operation?.signal.throwIfAborted();
|
|
41
46
|
const record = requiredMacosRecord(root);
|
|
42
|
-
if (record?.supervisor) await stopProcesses([record.supervisor], SUPERVISOR_EXIT_MS);
|
|
47
|
+
if (record?.supervisor) await stopProcesses([record.supervisor], SUPERVISOR_EXIT_MS, operation);
|
|
43
48
|
const app = readMacosRecord(root)?.app ?? record?.app;
|
|
44
|
-
if (app) await stopProcesses([app]);
|
|
45
|
-
const instances =
|
|
46
|
-
await stopProcesses(instances);
|
|
49
|
+
if (app) await stopProcesses([app], void 0, operation);
|
|
50
|
+
const instances = await runningBundleInstancesAsync(root, operation);
|
|
51
|
+
await stopProcesses(instances, void 0, operation);
|
|
52
|
+
operation?.signal.throwIfAborted();
|
|
47
53
|
if (!record) return instances.length > 0;
|
|
48
54
|
const claims = (0, ownership_claim_exports.readClaimSet)(macosRuntimeClaim(root));
|
|
49
55
|
if (claims.unresolved.length || claims.live.length) throw Object.assign(/* @__PURE__ */ new Error("The macOS runtime claim cannot be released; inspect its recorded owner before cleanup."), { code: "STIM_MACOS_OWNER_UNVERIFIED" });
|
|
50
56
|
return true;
|
|
51
57
|
}
|
|
52
58
|
/** Stops the workspace's app here, or its session on the hosting Mac, which must confirm the session stopped. */
|
|
53
|
-
function stopMacosApp(root) {
|
|
59
|
+
function stopMacosApp(root, operation) {
|
|
54
60
|
const stop = async () => {
|
|
61
|
+
operation?.signal.throwIfAborted();
|
|
55
62
|
const record = requiredMacosRecord(root);
|
|
56
|
-
if (!record?.host) return stopMacosAppHeld(root);
|
|
57
|
-
await stopHostedMacos(root, record.host);
|
|
63
|
+
if (!record?.host) return stopMacosAppHeld(root, operation);
|
|
64
|
+
await stopHostedMacos(root, record.host, operation?.signal);
|
|
65
|
+
operation?.signal.throwIfAborted();
|
|
58
66
|
const { host: _host, hostLaunched: _launched, ...stopped } = record;
|
|
59
|
-
writeWorkspaceState(root, { macos: {
|
|
67
|
+
await withWorkspaceStateLockAsync(root, () => writeWorkspaceState(root, { macos: {
|
|
60
68
|
...stopped,
|
|
61
69
|
supervisor: void 0
|
|
62
|
-
} });
|
|
70
|
+
} }), operation?.signal);
|
|
63
71
|
return true;
|
|
64
72
|
};
|
|
65
73
|
return withWorkspaceProcessLock(workspaceDir(root), "macos-launch", stop, {
|
|
66
74
|
external: true,
|
|
67
75
|
waitMs: 0,
|
|
68
|
-
ownerPurpose: "stop macOS app"
|
|
76
|
+
ownerPurpose: "stop macOS app",
|
|
77
|
+
signal: operation?.signal,
|
|
78
|
+
declareSpawnsFor: operation
|
|
69
79
|
});
|
|
70
80
|
}
|
|
71
81
|
//#endregion
|