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/README.md
CHANGED
|
@@ -44,13 +44,34 @@ Stim builds or restores the app, installs it, launches it, and checks launch
|
|
|
44
44
|
readiness. Plain output streams progress and reports the complete result. Use
|
|
45
45
|
`--json` when a script needs structured data.
|
|
46
46
|
|
|
47
|
+
For native Xcode simulator builds, declared repeatable SwiftPM macOS builds,
|
|
48
|
+
and React Native/Expo iOS Simulator or Android development builds, a local and configured-provider miss can
|
|
49
|
+
reuse an exact completed artifact from an enabled paired build worker. Reuse
|
|
50
|
+
checks the full source, toolchain, SDK, architecture and target cache key and
|
|
51
|
+
verifies the downloaded archive. It needs no compilation slot. An explicit
|
|
52
|
+
local build and remote build mode off skip peer lookup. React Native archives
|
|
53
|
+
match the native fingerprint, build choices and compatible toolchain verified
|
|
54
|
+
around compilation; they remain reusable after the worker changes checkouts.
|
|
55
|
+
Release and physical device builds keep their existing cache paths. See `stim guide settings` for placement.
|
|
56
|
+
SwiftPM peer reuse requires `macos.artifactInputs` and a capable worker. Its
|
|
57
|
+
receipt verifies actual worker source and rechecks worker-private files,
|
|
58
|
+
environment and Swift/Xcode/SDK identity. Private values are not transferred;
|
|
59
|
+
worker identities are separate from local cache keys. Compiler overrides
|
|
60
|
+
(`SWIFT_EXEC` and `SWIFT_EXEC_MANIFEST`) are resolved and versioned separately.
|
|
61
|
+
Overrides and custom toolchain launchers
|
|
62
|
+
require the worker checkout to revalidate their selection. See `stim guide macos`.
|
|
63
|
+
|
|
47
64
|
## Native Android build workers
|
|
48
65
|
|
|
49
66
|
Native Gradle apps can use an approved build worker after declaring that
|
|
50
67
|
Git-visible source and exact additional ignored files are sufficient. See
|
|
51
|
-
`stim guide lifecycle native-android` for `android.offloadInputs`, generated
|
|
52
|
-
|
|
53
|
-
|
|
68
|
+
`stim guide lifecycle native-android` for `android.offloadInputs`, generated output ownership,
|
|
69
|
+
and supported input boundaries. Workers remain uncached. Local builds can opt
|
|
70
|
+
into APK caching through a separate complete `android.artifactInputs` declaration.
|
|
71
|
+
A configured cache provider with a `files` capability can share the verified APK
|
|
72
|
+
and its receipt between machines. Private input files and environment values
|
|
73
|
+
stay local; the declaration never authorizes their transfer. Gradle
|
|
74
|
+
keeps its own incremental and task caches in both cases.
|
|
54
75
|
|
|
55
76
|
## Programmatic API
|
|
56
77
|
|
|
@@ -80,26 +101,138 @@ already running server. `run` builds, installs and launches.
|
|
|
80
101
|
`build({ platform: 'ios' })` returns a retained simulator app without starting
|
|
81
102
|
a device or runtime; Android returns an APK and macOS returns an app bundle.
|
|
82
103
|
Build-only preserves existing sessions and uses the same cache and build locks.
|
|
104
|
+
Successful builds include `result.facts.links.workspace`, an HTTPS workspace link
|
|
105
|
+
agents can share with an already-paired phone or Desktop, including when the
|
|
106
|
+
build machine has no Desktop app installed.
|
|
83
107
|
Each result is a separate copy kept in the workspace until `stim worktree remove`.
|
|
84
108
|
Run results preserve the CLI's launch evidence, including `'bundling'` and
|
|
85
109
|
`'unverified'` results.
|
|
86
110
|
|
|
87
|
-
|
|
88
|
-
|
|
111
|
+
`reload({ platform?: 'ios' | 'android' | 'web', signal? })` requests a JavaScript
|
|
112
|
+
reload in a live app or reloads the owned Chrome page, returning the flat
|
|
113
|
+
`stim reload --json` facts. Select a platform when more than one is live.
|
|
114
|
+
Dispatch does not prove completion; verify the expected UI and inspect logs.
|
|
115
|
+
A Metro broadcast can reach other connected clients. Reload uses a 60 second
|
|
116
|
+
execution budget and 35 second cleanup budget, with the report timeout and
|
|
117
|
+
cleanup refusals described below. Cancellation stops pending work but cannot
|
|
118
|
+
retract a request already sent. Reload never retries automatically.
|
|
119
|
+
|
|
120
|
+
`warmWorktree({ signal?, beforeWarm? })` copies missing ignored state from the
|
|
121
|
+
source checkout into the client's linked worktree in process, returning
|
|
122
|
+
`{ exitCode: 0 | 1 }`. It preserves existing entries and tracked files, shares
|
|
123
|
+
the source's read claim, and takes an exclusive claim on the target while copying.
|
|
124
|
+
`beforeWarm(workspace)` admits each canonical workspace in the resolved warming
|
|
125
|
+
scope before registration or copying; throwing refuses warming. Progress uses
|
|
126
|
+
`onProgress`. Cancellation drains the copy child before removing its partial
|
|
127
|
+
entry or releasing claims. Unverifiable cleanup retains the claims and reports
|
|
128
|
+
`STIM_CLAIM_UNAVAILABLE` with recovery paths. Warming has a 90 minute execution
|
|
129
|
+
budget and a 35 second cleanup budget. Source refresh remains available through
|
|
130
|
+
`stim worktree warm --refresh`; this API does not refresh or install dependencies.
|
|
131
|
+
|
|
132
|
+
`removeWorktree({ target?, force?, signal? })` uses the CLI's removal checks and
|
|
133
|
+
cleanup in process. The target defaults to `projectRoot`; relative paths resolve
|
|
134
|
+
against it. It returns `{ removed, exitCode }` without changing `process.exitCode`.
|
|
135
|
+
Source checkout environment cleanup can succeed with `removed: false` and
|
|
136
|
+
`exitCode: 0`; a linked worktree deleted before a branch-cleanup failure returns
|
|
137
|
+
`removed: true` and `exitCode: 1`. `force` means CLI `--force`, including discarding
|
|
138
|
+
unsaved work. It uses the 60 second execution and 35 second cleanup budgets below.
|
|
139
|
+
Cancellation stops pending actions and drains owned cleanup; completed deletions
|
|
140
|
+
remain applied.
|
|
141
|
+
|
|
142
|
+
`setSetting(key, text, { scope?, signal? })` and `unsetSetting(key, { scope?, signal? })`
|
|
143
|
+
share the CLI's validation and return its JSON write result, including masked
|
|
144
|
+
sensitive values. Values use CLI text syntax, including JSON for arrays and
|
|
145
|
+
objects. Config lock waits and device-pool probes are asynchronous. Cancellation
|
|
146
|
+
prevents a pending write; a committed write finishes its recording cleanup
|
|
147
|
+
before settling. Recording changes serialize through cleanup within the home.
|
|
148
|
+
|
|
149
|
+
Native lifecycle operations run in the importing process. Custom Expo
|
|
150
|
+
`buildCacheProvider` modules are not supported. Use EAS or a Stim cache provider.
|
|
151
|
+
|
|
152
|
+
`settings()` and `stats()`
|
|
153
|
+
read the `stim settings --json` and `stim stats --json` payloads. All
|
|
154
|
+
use the client's own home and leave the caller's cwd, environment,
|
|
155
|
+
output, signal handlers and exit listeners as they were. The API and CLI call
|
|
89
156
|
the same native lifecycle operations. Progress is silent unless `onProgress`
|
|
90
157
|
is provided; its `message` is an output chunk. Operations accept `signal`.
|
|
91
|
-
Cancellation
|
|
158
|
+
Cancellation drains the operation's owned work, and does not replace `stop()`.
|
|
92
159
|
Call cleanup with a fresh signal after cancellation or partial failure.
|
|
160
|
+
Cancelling `stop()` while it waits for another native operation ends that wait.
|
|
161
|
+
Once teardown starts, it finishes cleanup before rejecting with `STIM_CANCELLED`;
|
|
162
|
+
its config, workspace-state, and lease lock waits are asynchronous.
|
|
163
|
+
|
|
164
|
+
`plan({ platform: 'ios' | 'android' | 'macos', signal? })` predicts the next
|
|
165
|
+
configured native build, as the CLI's `--plan --json` reports it, without building
|
|
166
|
+
or launching. iOS and Android also accept `slot`; build and device selectors
|
|
167
|
+
come from the project's settings. Plans use the report execution and cleanup
|
|
168
|
+
budgets below. Fingerprinting uses the existing cancellable report helper;
|
|
169
|
+
native probes and cache downloads finish cleanup before the report settles.
|
|
170
|
+
Cache providers must settle after cancellation. If cleanup cannot finish within
|
|
171
|
+
35 seconds, the plan refuses with `STIM_CLAIM_UNAVAILABLE` and retains the download
|
|
172
|
+
directory; it does not delete files a broken provider may still be writing.
|
|
173
|
+
|
|
174
|
+
`doctor({ platform?, record? })` and `gc({ cache?, olderThan?, worktrees? })` read their CLI
|
|
175
|
+
JSON reports with a 60 second execution budget and optional `signal`. Doctor
|
|
176
|
+
never repairs; its `stim.runningPath` is null. By default it does not record a
|
|
177
|
+
check. Pass `record: true` to register the supported iOS/Android project and record
|
|
178
|
+
its checked platforms after the report and owned cleanup succeed. Recording waits
|
|
179
|
+
asynchronously for the config lock, honors `signal`, and rejects unavailable state.
|
|
180
|
+
GC never
|
|
181
|
+
deletes or shuts down idle devices. Reads can refresh their own usage caches
|
|
182
|
+
and existing pending remote approvals. An explicit `home` or `STIM_HOME` keeps
|
|
183
|
+
the CLI's scoped-home restrictions. Expiry rejects with `STIM_REPORT_TIMEOUT`
|
|
184
|
+
after owned cleanup; a caller abort rejects with
|
|
185
|
+
`STIM_CANCELLED`. Throwing from report progress also cancels the read.
|
|
186
|
+
If child identity cannot be verified after a one-second retry budget, cleanup
|
|
187
|
+
refuses with `STIM_CLAIM_UNAVAILABLE` instead of a cancellation or timeout
|
|
188
|
+
error. Child cleanup errors name the launcher PID; unverifiable processes and descendants
|
|
189
|
+
are left untouched. On POSIX, a launcher that exited before identity capture can only
|
|
190
|
+
finish successfully once its process group is proven gone.
|
|
191
|
+
After a termination request, cleanup waits at most one second for a child to
|
|
192
|
+
close. Overall cleanup has a 35 second budget, including temporary-worktree
|
|
193
|
+
removal; unfinished cleanup returns `STIM_CLAIM_UNAVAILABLE` and leaves
|
|
194
|
+
unresolved resources in place. Credential refresh waits asynchronously and
|
|
195
|
+
checks cancellation before writing.
|
|
196
|
+
On Windows, report probes require the built-in Windows PowerShell for process-tree containment.
|
|
93
197
|
|
|
94
198
|
`home` and `buildCache` accept absolute paths. Omit them to use normal Stim
|
|
95
199
|
settings. A cache used by concurrent writers needs the same coordinating Stim
|
|
96
200
|
home; do not point independent homes at a concurrently writable artifact cache.
|
|
201
|
+
`start({ remote?, resetCache?, waitSeconds?, signal?, beforeStart? })` starts or
|
|
202
|
+
reuses the managed dev server and returns flat start facts.
|
|
203
|
+
The optional admission callback receives the resolved app before startup effects.
|
|
204
|
+
Cancellation accounts for newly spawned processes before returning; a verified
|
|
205
|
+
supervisor handed off to its workspace can remain running. Unconfirmed cleanup
|
|
206
|
+
reports `STIM_CLAIM_UNAVAILABLE` with the retained ownership claims' recovery remedy.
|
|
207
|
+
|
|
97
208
|
Ownership checks and cache locks remain active. `stop()` acts on this workspace,
|
|
98
209
|
including resources from earlier runs, so use a dedicated workspace in CI.
|
|
99
210
|
|
|
100
211
|
Stim failures are `StimError` instances with `code`, `message`, `remedy`, and
|
|
101
|
-
`details`. An exception thrown by `onProgress`
|
|
102
|
-
propagated unchanged
|
|
212
|
+
`details`. An exception thrown by `onProgress` stops further progress and is
|
|
213
|
+
propagated unchanged: `start()`, `build()` or `run()` is cancelled, and
|
|
214
|
+
`stop()` or read finishes its work first.
|
|
215
|
+
`logs({ tail, sources, minLevel, slot, since, grep, errorsOnly })` reads the same
|
|
216
|
+
merged records as `stim logs --json`, including crash capture and agent actions.
|
|
217
|
+
Pass `tail` to bound the returned records. `followLogs(options, onRecord)` emits
|
|
218
|
+
that backfill and new records, then returns a stop function; aborting its signal
|
|
219
|
+
also stops it. An optional third callback receives initial records instead of
|
|
220
|
+
`onRecord`; its promise is awaited before the next batch. With that callback and
|
|
221
|
+
no `tail`, timeline batches hold at most 500 records. Agent attribution still
|
|
222
|
+
retains its matching records during backfill. These reads run in process and yield between log chunks.
|
|
223
|
+
Local follow uses filesystem hints with a ten-second repair scan. While a
|
|
224
|
+
directory watch is unavailable, it retries and scans every 500 ms; Expo error
|
|
225
|
+
context uses a timer only while pending. Local agent actions use filesystem
|
|
226
|
+
notifications for state and claim changes, with the same repair timing. Active hosted log
|
|
227
|
+
queries retain their pull cadence.
|
|
228
|
+
Attachment schedules one 500 ms recovery scan. A moved directory on Windows can
|
|
229
|
+
require the ten-second repair scan.
|
|
230
|
+
Hosted targets join and leave the follow stream from local state notifications;
|
|
231
|
+
missed notifications are reconciled about every 10 seconds. Active hosts still
|
|
232
|
+
serve bounded log queries.
|
|
233
|
+
Tail selection bounds matching timeline and agent records; agent attribution
|
|
234
|
+
still reads each retained session generation to establish device ownership.
|
|
235
|
+
|
|
103
236
|
`diagnostics()` returns the workspace log directory and up to 200 local records,
|
|
104
237
|
even if no run has succeeded. It does not fetch remote logs or capture new crashes.
|
|
105
238
|
See [the API reference](https://stim.appandflow.com/docs/programmatic-api) or
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { r as WorkspaceProcessCleanupError } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { I as waitForSharedBuild } from "./activity-CMLmzp7o.mjs";
|
|
3
|
+
import { rmSync } from "node:fs";
|
|
4
|
+
//#region src/engine/artifact-lifecycle.ts
|
|
5
|
+
async function runArtifactLifecycle(phases) {
|
|
6
|
+
try {
|
|
7
|
+
const resolved = await phases.resolve();
|
|
8
|
+
if (resolved.kind === "ready") return resolved.artifact;
|
|
9
|
+
const cached = resolved.kind === "cached" ? resolved.artifact : await phases.claim?.() ?? null;
|
|
10
|
+
if (cached !== null) {
|
|
11
|
+
const reused = await phases.reuse(cached);
|
|
12
|
+
if (reused !== null) return reused;
|
|
13
|
+
}
|
|
14
|
+
const { build } = phases;
|
|
15
|
+
const placement = await build.placement?.select() ?? null;
|
|
16
|
+
if (placement === null) await build.admit();
|
|
17
|
+
const preparation = await build.prepare();
|
|
18
|
+
const late = await build.revalidate(preparation);
|
|
19
|
+
if (late !== null) return late.ready;
|
|
20
|
+
if (build.placement && placement !== null) {
|
|
21
|
+
const offloaded = await build.placement.acquire(placement, preparation);
|
|
22
|
+
if (offloaded !== null) return offloaded.ready;
|
|
23
|
+
await build.admit();
|
|
24
|
+
}
|
|
25
|
+
const artifact = await build.compile(placement, preparation);
|
|
26
|
+
if (await build.validate(preparation) === "cacheable") await build.store(artifact);
|
|
27
|
+
return build.finish ? await build.finish(artifact) : artifact;
|
|
28
|
+
} finally {
|
|
29
|
+
phases.release();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/engine/cleanup-scope.ts
|
|
34
|
+
function drain(pending, report) {
|
|
35
|
+
const kept = [];
|
|
36
|
+
for (const cleanup of pending.toReversed()) try {
|
|
37
|
+
cleanup();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
kept.unshift(cleanup);
|
|
40
|
+
report(error);
|
|
41
|
+
}
|
|
42
|
+
return kept;
|
|
43
|
+
}
|
|
44
|
+
function createCleanupScope(report) {
|
|
45
|
+
let pending = [];
|
|
46
|
+
return {
|
|
47
|
+
defer: (cleanup) => {
|
|
48
|
+
pending.push(cleanup);
|
|
49
|
+
return () => {
|
|
50
|
+
pending = pending.filter((entry) => entry !== cleanup);
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
transfer: () => {
|
|
54
|
+
let handed = pending;
|
|
55
|
+
pending = [];
|
|
56
|
+
return () => {
|
|
57
|
+
handed = drain(handed, report);
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
release: () => {
|
|
61
|
+
pending = drain(pending, report);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/engine/acquire-artifact.ts
|
|
67
|
+
function unresolvedCleanup(error) {
|
|
68
|
+
return error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error;
|
|
69
|
+
}
|
|
70
|
+
/** Waits for upload readers; unresolved child cleanup refuses deletion of their temporary inputs. */
|
|
71
|
+
async function settleArtifactUploads(...uploads) {
|
|
72
|
+
const unresolved = (await Promise.allSettled(uploads)).find((result) => result.status === "rejected" && unresolvedCleanup(result.reason));
|
|
73
|
+
if (unresolved?.status === "rejected") throw unresolved.reason;
|
|
74
|
+
}
|
|
75
|
+
async function acquireArtifact(adapter, { root, logFile, deps }) {
|
|
76
|
+
const owned = createCleanupScope((error) => adapter.temporaryReleaseFailed(error));
|
|
77
|
+
let closeOffload = null;
|
|
78
|
+
let buildLock = null;
|
|
79
|
+
let buildSlot = null;
|
|
80
|
+
const releaseLock = () => {
|
|
81
|
+
if (!buildLock) return;
|
|
82
|
+
const held = buildLock;
|
|
83
|
+
buildLock = null;
|
|
84
|
+
try {
|
|
85
|
+
deps.releaseBuildLock(held);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
adapter.releaseFailed(`the build lock at ${held.path}`, error);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const releaseSlot = () => {
|
|
91
|
+
if (!buildSlot) return;
|
|
92
|
+
const held = buildSlot;
|
|
93
|
+
buildSlot = null;
|
|
94
|
+
try {
|
|
95
|
+
deps.releaseBuildSlot(held);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
adapter.releaseFailed("the build slot", error);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const run = {
|
|
101
|
+
own: (directory) => owned.defer(() => rmSync(directory, {
|
|
102
|
+
recursive: true,
|
|
103
|
+
force: true
|
|
104
|
+
})),
|
|
105
|
+
openOffload: (close) => {
|
|
106
|
+
closeOffload = close;
|
|
107
|
+
},
|
|
108
|
+
claimSharedBuild: async (options) => {
|
|
109
|
+
const shared = await waitForSharedBuild({
|
|
110
|
+
...options,
|
|
111
|
+
platform: adapter.platform,
|
|
112
|
+
root,
|
|
113
|
+
logFile,
|
|
114
|
+
command: adapter.command,
|
|
115
|
+
acquire: deps.acquireBuildLock,
|
|
116
|
+
wait: deps.waitForBuild,
|
|
117
|
+
now: deps.now
|
|
118
|
+
});
|
|
119
|
+
if (!shared.refusal) buildLock = shared.lock;
|
|
120
|
+
return shared;
|
|
121
|
+
},
|
|
122
|
+
takeBuildSlot: async (options) => {
|
|
123
|
+
buildSlot = await deps.acquireBuildSlot({
|
|
124
|
+
...options,
|
|
125
|
+
root,
|
|
126
|
+
logFile
|
|
127
|
+
});
|
|
128
|
+
return buildSlot;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
try {
|
|
132
|
+
return {
|
|
133
|
+
ok: true,
|
|
134
|
+
artifact: await runArtifactLifecycle({
|
|
135
|
+
...adapter.lifecycle(run),
|
|
136
|
+
release: () => {
|
|
137
|
+
const close = closeOffload;
|
|
138
|
+
closeOffload = null;
|
|
139
|
+
try {
|
|
140
|
+
close?.();
|
|
141
|
+
} finally {
|
|
142
|
+
releaseLock();
|
|
143
|
+
releaseSlot();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}),
|
|
147
|
+
release: owned.transfer()
|
|
148
|
+
};
|
|
149
|
+
} catch (error) {
|
|
150
|
+
try {
|
|
151
|
+
await adapter.settleFailed?.();
|
|
152
|
+
} catch (cleanupError) {
|
|
153
|
+
if (unresolvedCleanup(cleanupError)) owned.transfer();
|
|
154
|
+
throw cleanupError;
|
|
155
|
+
}
|
|
156
|
+
if (unresolvedCleanup(error)) {
|
|
157
|
+
owned.transfer();
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
const failure = adapter.refuse(error);
|
|
161
|
+
if (failure === null) throw error;
|
|
162
|
+
return {
|
|
163
|
+
ok: false,
|
|
164
|
+
failure
|
|
165
|
+
};
|
|
166
|
+
} finally {
|
|
167
|
+
owned.release();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { settleArtifactUploads as n, acquireArtifact as t };
|