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
package/dist/api.mjs
CHANGED
|
@@ -1,2 +1,783 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { m as operationState, r as WorkspaceProcessCleanupError, v as runReport, x as ownership_claim_exports, y as trackReportResource } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { d as workspaceDir, m as workspaceLogsDir$1, n as ensureWorkspaceStorage, r as ensureWorkspaceStorageAsync } from "./paths-DQtTgsBf.mjs";
|
|
3
|
+
import { E as upsertProject, p as getProject, q as validateDeviceSlot, y as refuseRelativeStimPaths } from "./config-DlrsduwG.mjs";
|
|
4
|
+
import { l as phaseLine } from "./command-output-gwpm28fu.mjs";
|
|
5
|
+
import { d as cancelledError, f as throwIfCancelled } from "./operation-exec-BW0em61G.mjs";
|
|
6
|
+
import { a as recordWorkspaceUseAsync, i as recordWorkspaceUse } from "./workspace-state-U08dEzhG.mjs";
|
|
7
|
+
import { J as resolveProjectSettingsAsync, Nt as repoRootAsync, a as SETTING_SHAPE_REMEDY, et as settingShapeErrors, it as unknownSettingKeys, p as cacheProviderSettingError } from "./settings-C7O8A6ZI.mjs";
|
|
8
|
+
import { c as projectProblem, f as projectRegistry, i as findProjectRoot$1, r as findCommandWorkspaceAsync, t as NO_PROJECT_REFUSAL } from "./project-wM_XFTvE.mjs";
|
|
9
|
+
import { n as macosDir } from "./state-08I3hw3_.mjs";
|
|
10
|
+
import { r as createNdjsonWriter } from "./ndjson-CgE_o3Dl.mjs";
|
|
11
|
+
import { B as recordFinishedBuild, H as tapBuildLog, V as startBuildProgress } from "./budget-Cvwn54qV.mjs";
|
|
12
|
+
import { d as runCancellationSignal, f as withNativeBuildRun } from "./native-run-NwUuxbkg.mjs";
|
|
13
|
+
import { c as ensureHomeIdentity, s as workspaceShareURL } from "./stim-desktop-D5OGpYZM.mjs";
|
|
14
|
+
import { s as resolveBuildPlacement } from "./selection-DSMbWEX2.mjs";
|
|
15
|
+
import { c as stopWorkspaceNow } from "./stop-Mv6W9FAk.mjs";
|
|
16
|
+
import { r as runReload } from "./reload-BzkYabB-.mjs";
|
|
17
|
+
import { c as startDevServer } from "./start-EojN4WFz.mjs";
|
|
18
|
+
import { s as recordDoctorCheck } from "./doctor-watchman-N2wDotwQ.mjs";
|
|
19
|
+
import { a as readDoctorReport } from "./doctor-D5_EzwfA.mjs";
|
|
20
|
+
import { h as warmWorktreeTarget, m as removeWorktreeTarget } from "./worktree-CHecZ4Oq.mjs";
|
|
21
|
+
import { i as readGcReport, n as executeGc, o as withGcMaintenanceClaim } from "./gc-CXxN-4SE.mjs";
|
|
22
|
+
import { r as readWorkspaceLogs, t as followWorkspaceLogs } from "./logs-BfwwadsZ.mjs";
|
|
23
|
+
import { t as readProjectStats } from "./stats-report-BzaPrRm6.mjs";
|
|
24
|
+
import { n as buildAndroidOperation, t as buildIosOperation } from "./build-CabC3G23.mjs";
|
|
25
|
+
import { a as readAndroidBuildPlan, i as runAndroidOperation } from "./android-ByRMUoiJ.mjs";
|
|
26
|
+
import { i as readIosBuildPlan, r as runIosOperation } from "./ios-pm4nL6By.mjs";
|
|
27
|
+
import { a as buildMacosBundle, i as planMacos, n as runMacos } from "./macos-NfV2D7dO.mjs";
|
|
28
|
+
import { t as runWeb } from "./web-DKx6yoFA.mjs";
|
|
29
|
+
import { i as SettingsRefusal, o as readSettingsContext, s as readSettingsPayload, t as mutateSetting } from "./settings-write-CzD60rOD.mjs";
|
|
30
|
+
import { randomBytes } from "node:crypto";
|
|
31
|
+
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
|
|
32
|
+
import { stripVTControlCharacters } from "node:util";
|
|
33
|
+
import { homedir } from "node:os";
|
|
34
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
35
|
+
import { withAmbientContext } from "@stim-cli/core";
|
|
36
|
+
import { RUN_ID_ENV, findProjectRoot, openLogDir, validRunId } from "@stim-cli/core/state";
|
|
37
|
+
import { decodeSecret } from "@stim-cli/core/noise-session";
|
|
38
|
+
//#region src/commands/macos-build.ts
|
|
39
|
+
async function buildMacosOperation(context, root, options) {
|
|
40
|
+
const note = (line) => context.output("stderr", `${line}\n`);
|
|
41
|
+
if (process.platform !== "darwin") throw new Error("Building a macOS app requires a Mac with Swift installed.");
|
|
42
|
+
root = realpathSync(root);
|
|
43
|
+
const selected = projectRegistry.selectMacos(root);
|
|
44
|
+
if ("problem" in selected) throw Object.assign(new Error(selected.problem.message), {
|
|
45
|
+
code: "STIM_NO_PROJECT",
|
|
46
|
+
remedy: selected.problem.remedy
|
|
47
|
+
});
|
|
48
|
+
const { settings } = await resolveProjectSettingsAsync(root, {
|
|
49
|
+
env: context.env,
|
|
50
|
+
signal: runCancellationSignal(context) ?? context.signal
|
|
51
|
+
});
|
|
52
|
+
const [shape] = settingShapeErrors(settings);
|
|
53
|
+
if (shape) throw Object.assign(/* @__PURE__ */ new Error(`${shape} ${SETTING_SHAPE_REMEDY}`), { code: "STIM_BAD_ARG" });
|
|
54
|
+
const placement = resolveBuildPlacement(options.remoteBuild);
|
|
55
|
+
if (placement.failure) throw Object.assign(new Error(placement.failure.message), placement.failure);
|
|
56
|
+
const recipe = await (await selected.load()).prepare(context, settings);
|
|
57
|
+
ensureWorkspaceStorage(root);
|
|
58
|
+
return withNativeBuildRun(context, root, {
|
|
59
|
+
command: "build",
|
|
60
|
+
platform: "macos"
|
|
61
|
+
}, async (claim) => {
|
|
62
|
+
if (!getProject(root)) upsertProject(root, {});
|
|
63
|
+
recordWorkspaceUse(root, /* @__PURE__ */ new Date(), context.env, context.cwd);
|
|
64
|
+
const started = Date.now();
|
|
65
|
+
const progress = startBuildProgress({
|
|
66
|
+
root,
|
|
67
|
+
platform: "macos",
|
|
68
|
+
slot: "default",
|
|
69
|
+
claim,
|
|
70
|
+
note
|
|
71
|
+
});
|
|
72
|
+
const logs = workspaceLogsDir$1(root);
|
|
73
|
+
const writer = tapBuildLog(createNdjsonWriter(join(logs, "build-artifact-macos.ndjson"), { truncate: true }), progress);
|
|
74
|
+
const build = {
|
|
75
|
+
state: "running",
|
|
76
|
+
startedAt: new Date(started).toISOString(),
|
|
77
|
+
buildMachine: placement.selected
|
|
78
|
+
};
|
|
79
|
+
let directory;
|
|
80
|
+
let succeeded = false;
|
|
81
|
+
try {
|
|
82
|
+
const artifacts = join(workspaceDir(root), "artifacts");
|
|
83
|
+
mkdirSync(artifacts, { recursive: true });
|
|
84
|
+
directory = mkdtempSync(join(artifacts, "macos-"));
|
|
85
|
+
const bundle = join(directory, `${recipe.product}.app`);
|
|
86
|
+
await buildMacosBundle({
|
|
87
|
+
context,
|
|
88
|
+
root,
|
|
89
|
+
recipe,
|
|
90
|
+
bundle,
|
|
91
|
+
bundleId: recipe.bundleId,
|
|
92
|
+
scratch: join(macosDir(root), "build"),
|
|
93
|
+
writer,
|
|
94
|
+
note,
|
|
95
|
+
progress,
|
|
96
|
+
record: build,
|
|
97
|
+
buildMachine: placement.selected
|
|
98
|
+
});
|
|
99
|
+
throwIfCancelled(runCancellationSignal(context), "macOS build");
|
|
100
|
+
const executable = realpathSync(join(bundle, "Contents", "MacOS", recipe.product));
|
|
101
|
+
const links = { workspace: await workspaceShareURL(root, { platform: "macos" }, runCancellationSignal(context) ?? context.signal) };
|
|
102
|
+
throwIfCancelled(runCancellationSignal(context), "macOS build");
|
|
103
|
+
build.state = "ok";
|
|
104
|
+
succeeded = true;
|
|
105
|
+
return {
|
|
106
|
+
product: recipe.product,
|
|
107
|
+
bundle,
|
|
108
|
+
bundleId: recipe.bundleId,
|
|
109
|
+
executable,
|
|
110
|
+
build,
|
|
111
|
+
logs: { dir: logs },
|
|
112
|
+
links
|
|
113
|
+
};
|
|
114
|
+
} catch (error) {
|
|
115
|
+
const failure = runCancellationSignal(context)?.aborted ? cancelledError("macOS build", error) : error;
|
|
116
|
+
build.state = "failed";
|
|
117
|
+
build.error = failure instanceof Error ? failure.message : String(failure);
|
|
118
|
+
build.errorCode = failure.code;
|
|
119
|
+
throw failure;
|
|
120
|
+
} finally {
|
|
121
|
+
build.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
122
|
+
build.durationMs = Date.now() - started;
|
|
123
|
+
try {
|
|
124
|
+
recordFinishedBuild(root, {
|
|
125
|
+
platform: "macos",
|
|
126
|
+
status: build.state,
|
|
127
|
+
configuration: "Debug",
|
|
128
|
+
fingerprint: build.fingerprint ?? null,
|
|
129
|
+
cacheKey: build.cacheKey ?? null,
|
|
130
|
+
cacheHit: build.cacheHit ? build.cacheSource === "provider" ? "remote" : "local" : false,
|
|
131
|
+
cacheSkipped: !build.cacheKey,
|
|
132
|
+
durationMs: build.durationMs,
|
|
133
|
+
startedAt: build.startedAt,
|
|
134
|
+
errorCode: build.errorCode,
|
|
135
|
+
buildMachine: build.buildMachine,
|
|
136
|
+
builtOn: build.builtOn,
|
|
137
|
+
offloadedTo: build.offloadedTo,
|
|
138
|
+
offloadFallback: build.offloadFallback,
|
|
139
|
+
compileSteps: progress.steps()
|
|
140
|
+
}, { artifactOnly: true });
|
|
141
|
+
} catch (error) {
|
|
142
|
+
note(phaseLine("state", `could not record the build: ${error?.message || error}`));
|
|
143
|
+
} finally {
|
|
144
|
+
if (!succeeded && directory) rmSync(directory, {
|
|
145
|
+
recursive: true,
|
|
146
|
+
force: true
|
|
147
|
+
});
|
|
148
|
+
writer.close();
|
|
149
|
+
progress.clear();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}, { write: note });
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/api.ts
|
|
156
|
+
const version = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
157
|
+
var StimError = class extends Error {
|
|
158
|
+
code;
|
|
159
|
+
remedy;
|
|
160
|
+
details;
|
|
161
|
+
constructor({ code, message, remedy = null, details }, options) {
|
|
162
|
+
super(message, options);
|
|
163
|
+
this.name = "StimError";
|
|
164
|
+
this.code = code;
|
|
165
|
+
this.remedy = remedy;
|
|
166
|
+
this.details = details;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Creates a client without starting processes or changing the caller's cwd, environment, or signal handlers.
|
|
171
|
+
* The Stim home is fixed when the client is created: `home`, else STIM_HOME from `env`, else the default home.
|
|
172
|
+
* Operations run in the calling process against the client's home and project, so clients for different
|
|
173
|
+
* homes can share a process.
|
|
174
|
+
* Resources remain workspace-owned until stop() is called.
|
|
175
|
+
*/
|
|
176
|
+
function createStim(options) {
|
|
177
|
+
let projectRoot;
|
|
178
|
+
try {
|
|
179
|
+
projectRoot = realpathSync(options.projectRoot);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
throw new StimError({
|
|
182
|
+
code: "STIM_NO_PROJECT",
|
|
183
|
+
message: `Could not resolve projectRoot ${options.projectRoot}: ${error instanceof Error ? error.message : String(error)}`,
|
|
184
|
+
remedy: "Pass the path to an existing, readable app directory."
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
for (const [name, path] of [["home", options.home], ["buildCache", options.buildCache]]) if (path !== void 0 && !isAbsolute(path)) throw new StimError({
|
|
188
|
+
code: "STIM_BAD_ARG",
|
|
189
|
+
message: `${name} must be an absolute path.`
|
|
190
|
+
});
|
|
191
|
+
const base = options.env ?? process.env;
|
|
192
|
+
const home = options.home ?? (base.STIM_HOME || join(base.HOME || base.USERPROFILE || homedir(), ".stim"));
|
|
193
|
+
const clientContext = {
|
|
194
|
+
...options,
|
|
195
|
+
projectRoot,
|
|
196
|
+
env: {
|
|
197
|
+
...base,
|
|
198
|
+
...options.home === void 0 ? {} : { STIM_HOME: options.home },
|
|
199
|
+
...options.buildCache === void 0 ? {} : { STIM_BUILD_CACHE: options.buildCache },
|
|
200
|
+
FORCE_COLOR: "0"
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const begin = (signal, cancelOnProgress = false) => {
|
|
204
|
+
const controller = cancelOnProgress ? new AbortController() : void 0;
|
|
205
|
+
const abort = () => controller?.abort();
|
|
206
|
+
if (controller) {
|
|
207
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
208
|
+
if (signal?.aborted) abort();
|
|
209
|
+
}
|
|
210
|
+
const callback = {};
|
|
211
|
+
const output = (stream, message) => {
|
|
212
|
+
if ("error" in callback) return;
|
|
213
|
+
try {
|
|
214
|
+
options.onProgress?.({
|
|
215
|
+
stream,
|
|
216
|
+
message: stripVTControlCharacters(message)
|
|
217
|
+
});
|
|
218
|
+
} catch (error) {
|
|
219
|
+
callback.error = error;
|
|
220
|
+
controller?.abort();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const operation = operationContext(clientContext, home, output, controller?.signal ?? signal);
|
|
224
|
+
if (controller) operationState(operation).abortOperation = abort;
|
|
225
|
+
return {
|
|
226
|
+
context: operation,
|
|
227
|
+
callback,
|
|
228
|
+
dispose: () => signal?.removeEventListener("abort", abort)
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
const beginReport = (signal) => {
|
|
232
|
+
const operation = begin(signal, true);
|
|
233
|
+
operation.context.env.STIM_HOME = clientContext.env.STIM_HOME;
|
|
234
|
+
for (const name of [
|
|
235
|
+
"AGENT_DEVICE_STATE_DIR",
|
|
236
|
+
"AGENT_DEVICE_CLAIMS_DIR",
|
|
237
|
+
"AGENT_DEVICE_IOS_RUNNER_LEASE_DIR"
|
|
238
|
+
]) {
|
|
239
|
+
const directory = operation.context.env[name]?.trim();
|
|
240
|
+
if (directory) operation.context.env[name] = resolve(operation.context.cwd, directory);
|
|
241
|
+
}
|
|
242
|
+
return operation;
|
|
243
|
+
};
|
|
244
|
+
const report = async (signal, work, timeoutMs) => {
|
|
245
|
+
const operation = beginReport(signal);
|
|
246
|
+
try {
|
|
247
|
+
return await read(operation, (context) => runReport(context, (request) => withAmbientContext(request, () => work(request)), timeoutMs));
|
|
248
|
+
} finally {
|
|
249
|
+
operation.dispose();
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
return {
|
|
253
|
+
projectRoot,
|
|
254
|
+
start: ({ signal, ...request } = {}) => {
|
|
255
|
+
const operation = begin(signal, true);
|
|
256
|
+
operation.context.env.STIM_HOME = clientContext.env.STIM_HOME;
|
|
257
|
+
return lifecycle(operation, (context) => start(context, request));
|
|
258
|
+
},
|
|
259
|
+
identity: ({ signal } = {}) => read(begin(signal), (operation) => ensureHomeIdentity(operation.signal)),
|
|
260
|
+
doctor: async ({ signal, platform, record } = {}) => {
|
|
261
|
+
if (platform !== void 0 && platform !== "ios" && platform !== "android") return Promise.reject(new StimError({
|
|
262
|
+
code: "STIM_BAD_ARG",
|
|
263
|
+
message: "platform must be ios or android."
|
|
264
|
+
}));
|
|
265
|
+
const result = await report(signal, (context) => readDoctorReport(context, platform, version));
|
|
266
|
+
if (record !== true) return result;
|
|
267
|
+
return read(begin(signal), async (context) => {
|
|
268
|
+
await recordDoctorCheck(result.project, platform, version, context.signal);
|
|
269
|
+
return result;
|
|
270
|
+
});
|
|
271
|
+
},
|
|
272
|
+
requestMachineAccess: async ({ signal, ticket } = {}) => {
|
|
273
|
+
if (ticket !== void 0 && (typeof ticket !== "string" || !decodeSecret(ticket.trim()))) throw new StimError({
|
|
274
|
+
code: "STIM_BAD_ARG",
|
|
275
|
+
message: "The setup ticket must encode 32 random bytes."
|
|
276
|
+
});
|
|
277
|
+
const result = await report(signal, (context) => {
|
|
278
|
+
context.env.STIM_ACCESS_TICKET = ticket?.trim();
|
|
279
|
+
return readDoctorReport(context, "ios", version, true);
|
|
280
|
+
}, 12e4);
|
|
281
|
+
return read(begin(signal), async (context) => {
|
|
282
|
+
await recordDoctorCheck(result.project, "ios", version, context.signal);
|
|
283
|
+
return result;
|
|
284
|
+
});
|
|
285
|
+
},
|
|
286
|
+
plan: ({ signal, ...request }) => report(signal, (context) => {
|
|
287
|
+
const task = Promise.resolve().then(async () => {
|
|
288
|
+
if (request.platform === "macos") try {
|
|
289
|
+
return await planMacos(context, findProjectRoot$1(context.projectRoot) ?? context.projectRoot);
|
|
290
|
+
} catch (cause) {
|
|
291
|
+
if (cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
292
|
+
context.signal.throwIfAborted();
|
|
293
|
+
const code = cause instanceof Error && "code" in cause && typeof cause.code === "string" ? cause.code : "STIM_BAD_ARG";
|
|
294
|
+
const remedy = cause instanceof Error && "remedy" in cause && typeof cause.remedy === "string" ? cause.remedy : "Check the macOS project settings in stim guide macos.";
|
|
295
|
+
throw new StimError({
|
|
296
|
+
code,
|
|
297
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
298
|
+
remedy
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (request.platform !== "ios" && request.platform !== "android") throw new StimError({
|
|
302
|
+
code: "STIM_BAD_ARG",
|
|
303
|
+
message: "platform must be ios, android or macos."
|
|
304
|
+
});
|
|
305
|
+
const selectors = { slot: validateDeviceSlot(request.slot) };
|
|
306
|
+
const result = request.platform === "ios" ? await readIosBuildPlan(context, selectors) : await readAndroidBuildPlan(context, selectors);
|
|
307
|
+
context.signal.throwIfAborted();
|
|
308
|
+
if ("platform" in result) return result;
|
|
309
|
+
throw new StimError({
|
|
310
|
+
...result.refusal,
|
|
311
|
+
details: { lines: result.lines }
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
trackReportResource(context, task.then(() => void 0, (cause) => {
|
|
315
|
+
if (cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
316
|
+
}), () => {});
|
|
317
|
+
return task;
|
|
318
|
+
}),
|
|
319
|
+
gc: ({ signal, olderThan, cache, worktrees } = {}) => {
|
|
320
|
+
if (olderThan !== void 0 && !Number.isSafeInteger(olderThan)) return Promise.reject(new StimError({
|
|
321
|
+
code: "STIM_BAD_ARG",
|
|
322
|
+
message: "olderThan must be a whole number of days."
|
|
323
|
+
}));
|
|
324
|
+
return report(signal, async (context) => {
|
|
325
|
+
const result = await readGcReport({
|
|
326
|
+
olderThan,
|
|
327
|
+
cache,
|
|
328
|
+
worktrees
|
|
329
|
+
}, {
|
|
330
|
+
operation: context,
|
|
331
|
+
easLedgerRoot: join(context.env.HOME || context.env.USERPROFILE || homedir(), ".stim", "machine", "eas")
|
|
332
|
+
});
|
|
333
|
+
if ("code" in result) throw new StimError(result);
|
|
334
|
+
return result;
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
collectGarbage: ({ signal, olderThan, cache, worktrees, delete: deleting, idleMs } = {}) => {
|
|
338
|
+
const invalid = olderThan !== void 0 && !Number.isSafeInteger(olderThan) ? "olderThan must be a whole number of days." : cache !== void 0 && (typeof cache !== "string" || !cache.trim()) ? "cache must name a cache." : worktrees !== void 0 && typeof worktrees !== "boolean" ? "worktrees must be a boolean." : deleting !== void 0 && typeof deleting !== "boolean" ? "delete must be a boolean." : idleMs !== void 0 && (!Number.isSafeInteger(idleMs) || idleMs <= 0) ? "idleMs must be a positive whole number of milliseconds." : null;
|
|
339
|
+
if (invalid) return Promise.reject(new StimError({
|
|
340
|
+
code: "STIM_BAD_ARG",
|
|
341
|
+
message: invalid
|
|
342
|
+
}));
|
|
343
|
+
const operation = beginReport(signal);
|
|
344
|
+
const request = {
|
|
345
|
+
olderThan,
|
|
346
|
+
cache,
|
|
347
|
+
worktrees,
|
|
348
|
+
delete: deleting,
|
|
349
|
+
idle: idleMs,
|
|
350
|
+
json: true
|
|
351
|
+
};
|
|
352
|
+
return lifecycle(operation, (context) => withGcMaintenanceClaim(request, (claim) => runReport(context, (bounded) => withAmbientContext(bounded, () => {
|
|
353
|
+
const task = executeGc(request, {
|
|
354
|
+
operation: bounded,
|
|
355
|
+
easLedgerRoot: join(bounded.env.HOME || bounded.env.USERPROFILE || homedir(), ".stim", "machine", "eas")
|
|
356
|
+
}, (_stream, line) => bounded.output("stderr", `${line}\n`), claim).then(({ payload, exitCode }) => {
|
|
357
|
+
if ("code" in payload) throw new StimError(payload);
|
|
358
|
+
return {
|
|
359
|
+
report: payload,
|
|
360
|
+
exitCode
|
|
361
|
+
};
|
|
362
|
+
});
|
|
363
|
+
trackReportResource(bounded, task.then(() => void 0, (cause) => {
|
|
364
|
+
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
365
|
+
}), () => {});
|
|
366
|
+
return task;
|
|
367
|
+
}))).catch((cause) => {
|
|
368
|
+
if (cause instanceof WorkspaceProcessCleanupError) throw cause;
|
|
369
|
+
const failure = (0, ownership_claim_exports.claimFailure)(cause, null);
|
|
370
|
+
if (failure) throw new StimError(failure);
|
|
371
|
+
throw cause;
|
|
372
|
+
}));
|
|
373
|
+
},
|
|
374
|
+
warmWorktree: ({ signal, beforeWarm } = {}) => lifecycle(beginReport(signal), (context) => runReport(context, (bounded) => withAmbientContext(bounded, () => {
|
|
375
|
+
const task = warmWorktreeTarget({
|
|
376
|
+
cwd: bounded.cwd,
|
|
377
|
+
operation: bounded,
|
|
378
|
+
beforeWarm
|
|
379
|
+
});
|
|
380
|
+
trackReportResource(bounded, task.then(() => void 0, (cause) => {
|
|
381
|
+
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
382
|
+
}), () => {});
|
|
383
|
+
return task;
|
|
384
|
+
}), 54e5)),
|
|
385
|
+
removeWorktree: ({ signal, target, force, beforeRemove } = {}) => {
|
|
386
|
+
const invalid = target !== void 0 && (typeof target !== "string" || target.length === 0) ? "target must be a nonempty path." : force !== void 0 && typeof force !== "boolean" ? "force must be a boolean." : null;
|
|
387
|
+
if (invalid) return Promise.reject(new StimError({
|
|
388
|
+
code: "STIM_BAD_ARG",
|
|
389
|
+
message: invalid
|
|
390
|
+
}));
|
|
391
|
+
return lifecycle(beginReport(signal), (context) => runReport(context, (bounded) => withAmbientContext(bounded, () => {
|
|
392
|
+
let exitCode = 0;
|
|
393
|
+
const task = removeWorktreeTarget(resolve(bounded.cwd, target ?? "."), {
|
|
394
|
+
force,
|
|
395
|
+
beforeRemove,
|
|
396
|
+
operation: bounded,
|
|
397
|
+
output: {
|
|
398
|
+
error: (line) => bounded.output("stderr", `${line}\n`),
|
|
399
|
+
fail: () => {
|
|
400
|
+
exitCode = 1;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}).then((removed) => ({
|
|
404
|
+
removed,
|
|
405
|
+
exitCode
|
|
406
|
+
}));
|
|
407
|
+
trackReportResource(bounded, task.then(() => void 0, (cause) => {
|
|
408
|
+
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
|
|
409
|
+
}), () => {});
|
|
410
|
+
return task;
|
|
411
|
+
})));
|
|
412
|
+
},
|
|
413
|
+
settings: ({ signal } = {}) => read(begin(signal), async (operation) => readSettingsPayload(await readSettingsContext(operation.projectRoot, {
|
|
414
|
+
...operation.env,
|
|
415
|
+
STIM_HOME: clientContext.env.STIM_HOME
|
|
416
|
+
}, note(operation), operation.signal), operation.signal)),
|
|
417
|
+
setSetting: (key, value, { signal, scope, beforeWrite } = {}) => read(begin(signal), (operation) => mutateSetting({
|
|
418
|
+
action: "set",
|
|
419
|
+
key,
|
|
420
|
+
value,
|
|
421
|
+
scope
|
|
422
|
+
}, {
|
|
423
|
+
cwd: operation.projectRoot,
|
|
424
|
+
env: {
|
|
425
|
+
...operation.env,
|
|
426
|
+
STIM_HOME: clientContext.env.STIM_HOME
|
|
427
|
+
},
|
|
428
|
+
note: note(operation),
|
|
429
|
+
signal: operation.signal,
|
|
430
|
+
beforeWrite
|
|
431
|
+
})),
|
|
432
|
+
unsetSetting: (key, { signal, scope, beforeWrite } = {}) => read(begin(signal), (operation) => mutateSetting({
|
|
433
|
+
action: "unset",
|
|
434
|
+
key,
|
|
435
|
+
scope
|
|
436
|
+
}, {
|
|
437
|
+
cwd: operation.projectRoot,
|
|
438
|
+
env: {
|
|
439
|
+
...operation.env,
|
|
440
|
+
STIM_HOME: clientContext.env.STIM_HOME
|
|
441
|
+
},
|
|
442
|
+
note: note(operation),
|
|
443
|
+
signal: operation.signal,
|
|
444
|
+
beforeWrite
|
|
445
|
+
})),
|
|
446
|
+
stats: ({ signal } = {}) => read(begin(signal), async (operation) => (await readProjectStats(findProjectRoot(operation.projectRoot), operation.env, operation.signal)).report),
|
|
447
|
+
logs: ({ signal, ...request } = {}) => read(begin(signal), (operation) => readWorkspaceLogs(operation, request)),
|
|
448
|
+
followLogs: ({ signal, ...request }, onRecord, onBackfill) => {
|
|
449
|
+
const operation = begin(signal);
|
|
450
|
+
return read(operation, async (readContext) => {
|
|
451
|
+
const stop = await followWorkspaceLogs(readContext, request, onRecord, onBackfill);
|
|
452
|
+
if ("error" in operation.callback) stop();
|
|
453
|
+
return stop;
|
|
454
|
+
});
|
|
455
|
+
},
|
|
456
|
+
build: (({ signal, ...request }) => lifecycle(begin(signal, true), (operation) => build(operation, request))),
|
|
457
|
+
run: (({ signal, ...request }) => lifecycle(begin(signal, true), (operation) => run(operation, request))),
|
|
458
|
+
stop: ({ signal, ...request } = {}) => read(begin(signal), async (operation) => {
|
|
459
|
+
const root = findProjectRoot$1(operation.projectRoot) ?? operation.projectRoot;
|
|
460
|
+
request.beforeStop?.(root);
|
|
461
|
+
const logs = workspaceLogsDir$1(root);
|
|
462
|
+
let result;
|
|
463
|
+
try {
|
|
464
|
+
result = await stopWorkspaceNow({
|
|
465
|
+
root,
|
|
466
|
+
slot: request.slot,
|
|
467
|
+
report: note(operation),
|
|
468
|
+
operation
|
|
469
|
+
});
|
|
470
|
+
} catch (error) {
|
|
471
|
+
if (operation.signal.aborted) throw error;
|
|
472
|
+
const failure = error;
|
|
473
|
+
throw new StimError({
|
|
474
|
+
code: failure.code ?? "STIM_RUN_FAILED",
|
|
475
|
+
message: error instanceof Error ? error.message : String(error),
|
|
476
|
+
remedy: failure.remedy ?? null,
|
|
477
|
+
details: {
|
|
478
|
+
logs,
|
|
479
|
+
cause: failure.details
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
if ("refusal" in result) throw new StimError({
|
|
484
|
+
...result.refusal,
|
|
485
|
+
details: {
|
|
486
|
+
logs,
|
|
487
|
+
cause: result.remote
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
return result;
|
|
491
|
+
}),
|
|
492
|
+
reload: async ({ signal, ...request } = {}) => {
|
|
493
|
+
const requestOperation = begin(signal, true);
|
|
494
|
+
try {
|
|
495
|
+
return await read(requestOperation, (context) => runReport(context, (operation) => withAmbientContext(operation, () => {
|
|
496
|
+
const result = reload(operation, request);
|
|
497
|
+
trackReportResource(operation, result.then(() => void 0, () => void 0), () => {});
|
|
498
|
+
return result;
|
|
499
|
+
})));
|
|
500
|
+
} finally {
|
|
501
|
+
requestOperation.dispose();
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
diagnostics({ signal, ...request } = {}) {
|
|
505
|
+
if (request.tail !== void 0 && (!Number.isSafeInteger(request.tail) || request.tail < 0)) return Promise.reject(new StimError({
|
|
506
|
+
code: "STIM_BAD_ARG",
|
|
507
|
+
message: "tail must be a non-negative integer."
|
|
508
|
+
}));
|
|
509
|
+
return read(begin(signal), async (operation) => {
|
|
510
|
+
const directory = workspaceLogsDir$1(operation.projectRoot);
|
|
511
|
+
if (request.tail === 0) return {
|
|
512
|
+
directory,
|
|
513
|
+
records: []
|
|
514
|
+
};
|
|
515
|
+
const view = await openLogDir(directory, { signal: operation.signal });
|
|
516
|
+
try {
|
|
517
|
+
return {
|
|
518
|
+
directory,
|
|
519
|
+
records: await view.query({
|
|
520
|
+
tail: request.tail ?? 200,
|
|
521
|
+
errorsOnly: request.errors ?? false
|
|
522
|
+
})
|
|
523
|
+
};
|
|
524
|
+
} finally {
|
|
525
|
+
await view.close();
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
function operationContext(client, home, output, signal) {
|
|
532
|
+
const runId = validRunId(client.env[RUN_ID_ENV]) ?? randomBytes(6).toString("hex");
|
|
533
|
+
return {
|
|
534
|
+
home,
|
|
535
|
+
buildCache: client.buildCache ?? null,
|
|
536
|
+
projectRoot: client.projectRoot,
|
|
537
|
+
cwd: client.projectRoot,
|
|
538
|
+
runId,
|
|
539
|
+
env: {
|
|
540
|
+
...client.env,
|
|
541
|
+
STIM_HOME: home,
|
|
542
|
+
[RUN_ID_ENV]: runId
|
|
543
|
+
},
|
|
544
|
+
signal: signal ?? new AbortController().signal,
|
|
545
|
+
output
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
async function read({ context, callback }, operation) {
|
|
549
|
+
const { signal } = context;
|
|
550
|
+
if (signal.aborted) throw cancelled();
|
|
551
|
+
let result;
|
|
552
|
+
try {
|
|
553
|
+
refuseRelativeStimPaths(context.env);
|
|
554
|
+
result = await withAmbientContext(context, () => operation(context));
|
|
555
|
+
} catch (error) {
|
|
556
|
+
const cleanupUnresolved = error instanceof Error && ("reportCleanup" in error || "code" in error && error.code === "STIM_CLAIM_UNAVAILABLE");
|
|
557
|
+
if ("error" in callback && !cleanupUnresolved) throw callback.error;
|
|
558
|
+
if (signal.aborted && !cleanupUnresolved) throw cancelled();
|
|
559
|
+
if (error instanceof StimError) throw error;
|
|
560
|
+
if (error instanceof Error && "code" in error && typeof error.code === "string" && error.code.startsWith("STIM_")) {
|
|
561
|
+
const remedy = error instanceof SettingsRefusal ? error.remedy : cleanupUnresolved && "remedy" in error && typeof error.remedy === "string" ? error.remedy : null;
|
|
562
|
+
throw new StimError({
|
|
563
|
+
code: error.code,
|
|
564
|
+
message: error.message,
|
|
565
|
+
remedy
|
|
566
|
+
}, cleanupUnresolved ? { cause: error } : void 0);
|
|
567
|
+
}
|
|
568
|
+
throw error;
|
|
569
|
+
}
|
|
570
|
+
if ("error" in callback) throw callback.error;
|
|
571
|
+
if (signal.aborted) throw cancelled();
|
|
572
|
+
return result;
|
|
573
|
+
}
|
|
574
|
+
function note(operation) {
|
|
575
|
+
return (line) => operation.output("stderr", `${line}\n`);
|
|
576
|
+
}
|
|
577
|
+
function cancelled() {
|
|
578
|
+
return new StimError({
|
|
579
|
+
code: "STIM_CANCELLED",
|
|
580
|
+
message: "The Stim operation was cancelled."
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
async function lifecycle(operation, work) {
|
|
584
|
+
try {
|
|
585
|
+
return await read(operation, async (context) => {
|
|
586
|
+
const logs = workspaceLogsDir$1(context.projectRoot);
|
|
587
|
+
try {
|
|
588
|
+
return await work(context);
|
|
589
|
+
} catch (error) {
|
|
590
|
+
const failure = error;
|
|
591
|
+
throw new StimError({
|
|
592
|
+
code: failure?.code ?? "STIM_RUN_FAILED",
|
|
593
|
+
message: error instanceof Error ? error.message : String(error),
|
|
594
|
+
remedy: failure?.remedy ?? null,
|
|
595
|
+
details: {
|
|
596
|
+
logs,
|
|
597
|
+
cause: error instanceof WorkspaceProcessCleanupError ? { retainedClaimRoots: [...new Set(error.claims.map((claim) => claim.root))] } : failure?.details
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
} finally {
|
|
603
|
+
operation.dispose();
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
async function start(context, options) {
|
|
607
|
+
if (options.waitSeconds !== void 0 && (!Number.isSafeInteger(options.waitSeconds) || options.waitSeconds <= 0)) throw new StimError({
|
|
608
|
+
code: "STIM_BAD_ARG",
|
|
609
|
+
message: "waitSeconds must be a positive whole number."
|
|
610
|
+
});
|
|
611
|
+
const root = findProjectRoot$1(context.projectRoot);
|
|
612
|
+
if (!root) throw new StimError(NO_PROJECT_REFUSAL);
|
|
613
|
+
const problem = projectProblem(root, "dev-server");
|
|
614
|
+
if (problem) throw new StimError({
|
|
615
|
+
code: "STIM_NO_PROJECT",
|
|
616
|
+
...problem
|
|
617
|
+
});
|
|
618
|
+
options.beforeStart?.(root);
|
|
619
|
+
context.signal.throwIfAborted();
|
|
620
|
+
return withAmbientContext({
|
|
621
|
+
...context,
|
|
622
|
+
projectRoot: root
|
|
623
|
+
}, async () => {
|
|
624
|
+
const { context: settingsContext, settings } = await resolveProjectSettingsAsync(root, {
|
|
625
|
+
env: context.env,
|
|
626
|
+
signal: context.signal
|
|
627
|
+
});
|
|
628
|
+
const shapeErrors = settingShapeErrors(settings);
|
|
629
|
+
if (shapeErrors.length) throw new StimError({
|
|
630
|
+
code: "STIM_BAD_ARG",
|
|
631
|
+
message: shapeErrors.join("\n"),
|
|
632
|
+
remedy: SETTING_SHAPE_REMEDY
|
|
633
|
+
});
|
|
634
|
+
for (const key of unknownSettingKeys(settings)) note(context)(`Warning: setting "${key}" is not read by Stim and will be ignored.`);
|
|
635
|
+
const cacheError = cacheProviderSettingError(settings);
|
|
636
|
+
if (cacheError) note(context)(`Warning: ${cacheError} No cache provider is used.`);
|
|
637
|
+
await ensureWorkspaceStorageAsync(root, context.signal);
|
|
638
|
+
await recordWorkspaceUseAsync(root, /* @__PURE__ */ new Date(), context.env, context.cwd, context.signal);
|
|
639
|
+
const result = await startDevServer({
|
|
640
|
+
root,
|
|
641
|
+
settings,
|
|
642
|
+
settingsContext,
|
|
643
|
+
waitSeconds: options.waitSeconds,
|
|
644
|
+
remote: options.remote,
|
|
645
|
+
resetCache: options.resetCache,
|
|
646
|
+
out: (line) => context.output("stdout", `${line}\n`),
|
|
647
|
+
note: note(context)
|
|
648
|
+
});
|
|
649
|
+
if (!result.ok) {
|
|
650
|
+
for (const line of result.lines) note(context)(line);
|
|
651
|
+
throw new StimError({
|
|
652
|
+
...result.error,
|
|
653
|
+
details: {
|
|
654
|
+
lines: result.lines,
|
|
655
|
+
reclaimed: result.reclaimed,
|
|
656
|
+
...result.retainedClaimRoots ? { retainedClaimRoots: result.retainedClaimRoots } : {}
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
return result.facts;
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
async function reload(context, options) {
|
|
664
|
+
if (options.platform !== void 0 && ![
|
|
665
|
+
"ios",
|
|
666
|
+
"android",
|
|
667
|
+
"web"
|
|
668
|
+
].includes(options.platform)) throw new StimError({
|
|
669
|
+
code: "STIM_BAD_ARG",
|
|
670
|
+
message: "platform must be ios, android or web."
|
|
671
|
+
});
|
|
672
|
+
const root = await findCommandWorkspaceAsync(context.projectRoot, (cwd) => repoRootAsync(cwd, {
|
|
673
|
+
env: context.env,
|
|
674
|
+
signal: context.signal
|
|
675
|
+
}), note(context));
|
|
676
|
+
context.signal.throwIfAborted();
|
|
677
|
+
if (!root) throw new StimError({
|
|
678
|
+
code: "STIM_NO_PROJECT",
|
|
679
|
+
message: `No Stim environment is registered for ${context.projectRoot}.`,
|
|
680
|
+
remedy: "Run stim start first."
|
|
681
|
+
});
|
|
682
|
+
options.beforeReload?.(root);
|
|
683
|
+
context.signal.throwIfAborted();
|
|
684
|
+
await recordWorkspaceUseAsync(root, /* @__PURE__ */ new Date(), context.env, context.projectRoot, context.signal);
|
|
685
|
+
const result = await runReload({
|
|
686
|
+
root,
|
|
687
|
+
platform: options.platform,
|
|
688
|
+
signal: context.signal
|
|
689
|
+
});
|
|
690
|
+
if (!result.ok) throw new StimError(result.error);
|
|
691
|
+
return result.facts;
|
|
692
|
+
}
|
|
693
|
+
async function build(context, options) {
|
|
694
|
+
const root = context.projectRoot;
|
|
695
|
+
switch (options.platform) {
|
|
696
|
+
case "ios": return {
|
|
697
|
+
platform: "ios",
|
|
698
|
+
facts: await buildIosOperation(context, root, options)
|
|
699
|
+
};
|
|
700
|
+
case "android": return {
|
|
701
|
+
platform: "android",
|
|
702
|
+
facts: await buildAndroidOperation(context, root, options)
|
|
703
|
+
};
|
|
704
|
+
case "macos": return {
|
|
705
|
+
platform: "macos",
|
|
706
|
+
facts: await buildMacosOperation(context, root, options)
|
|
707
|
+
};
|
|
708
|
+
default: throw new StimError({
|
|
709
|
+
code: "STIM_BAD_ARG",
|
|
710
|
+
message: "Unknown Stim build platform."
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
async function run(context, options) {
|
|
715
|
+
const root = context.projectRoot;
|
|
716
|
+
switch (options.platform) {
|
|
717
|
+
case "ios": {
|
|
718
|
+
let error;
|
|
719
|
+
const result = await runIosOperation(context, root, options, {}, (failure) => {
|
|
720
|
+
error = failure;
|
|
721
|
+
});
|
|
722
|
+
if (!result) throw new StimError({
|
|
723
|
+
code: error?.code ?? "STIM_RUN_FAILED",
|
|
724
|
+
message: error?.message ?? "The iOS run failed.",
|
|
725
|
+
remedy: error?.remedy,
|
|
726
|
+
details: error
|
|
727
|
+
});
|
|
728
|
+
return {
|
|
729
|
+
platform: "ios",
|
|
730
|
+
facts: result.facts
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
case "android": {
|
|
734
|
+
const result = await runAndroidOperation(context, root, options);
|
|
735
|
+
if (!result.ok || !result.facts) throw new StimError({
|
|
736
|
+
code: result.error?.code ?? "STIM_RUN_FAILED",
|
|
737
|
+
message: result.error?.message ?? "The Android run failed.",
|
|
738
|
+
remedy: result.error?.remedy,
|
|
739
|
+
details: result.error
|
|
740
|
+
});
|
|
741
|
+
return {
|
|
742
|
+
platform: "android",
|
|
743
|
+
facts: result.facts
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
case "macos": {
|
|
747
|
+
const record = await runMacos(context, root, note(context), options.remote, options.remoteBuild);
|
|
748
|
+
return {
|
|
749
|
+
platform: "macos",
|
|
750
|
+
facts: {
|
|
751
|
+
product: record.product,
|
|
752
|
+
bundle: record.bundle,
|
|
753
|
+
bundleId: record.bundleId,
|
|
754
|
+
executable: record.executable,
|
|
755
|
+
pid: record.app?.pid ?? null,
|
|
756
|
+
launched: record.hostLaunched ?? record.app !== void 0,
|
|
757
|
+
build: record.build,
|
|
758
|
+
logs: { dir: workspaceLogsDir$1(root) }
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
case "web": {
|
|
763
|
+
const result = await runWeb({
|
|
764
|
+
root,
|
|
765
|
+
headed: options.headed ?? false,
|
|
766
|
+
note: note(context),
|
|
767
|
+
context
|
|
768
|
+
});
|
|
769
|
+
if (!result.ok) throw new StimError(result.error);
|
|
770
|
+
if (result.remedy) note(context)(result.remedy);
|
|
771
|
+
return {
|
|
772
|
+
platform: "web",
|
|
773
|
+
facts: result.facts
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
default: throw new StimError({
|
|
777
|
+
code: "STIM_BAD_ARG",
|
|
778
|
+
message: "Unknown Stim platform."
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
//#endregion
|
|
2
783
|
export { StimError, createStim };
|