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,8 +1,8 @@
|
|
|
1
|
-
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-
|
|
5
|
-
import "./status-watch-
|
|
1
|
+
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-C7O8A6ZI.mjs";
|
|
2
|
+
import { i as findProjectRoot$1 } from "./project-wM_XFTvE.mjs";
|
|
3
|
+
import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-DlY_serQ.mjs";
|
|
4
|
+
import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-N2wDotwQ.mjs";
|
|
5
|
+
import "./status-watch-Bg_u-pwR.mjs";
|
|
6
6
|
import { SETTINGS, SETTINGS_SCHEMA_URL, TUTORIAL_VERSION } from "@stim-cli/core/state";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
//#region src/guide/agent.ts
|
|
@@ -117,7 +117,7 @@ other apps or other workspaces' devices.
|
|
|
117
117
|
stim ios # or: stim android, or: stim web
|
|
118
118
|
|
|
119
119
|
When Stim Desktop is installed, worktree warm, start, ios, android and web
|
|
120
|
-
print "Open in Stim
|
|
120
|
+
print "Open in Stim: <link>" on stderr (links.desktop in JSON). The
|
|
121
121
|
first time one prints it in a workspace, tell the user once: "You can watch
|
|
122
122
|
this workspace in Stim Desktop: <link>". Do not repeat it after later
|
|
123
123
|
commands. When no command prints it, do not mention Stim Desktop.
|
|
@@ -146,9 +146,9 @@ lifecycle builds.
|
|
|
146
146
|
Agents never set STIM_ACCESS_TICKET, run stim-server setup, edit remote.*,
|
|
147
147
|
server.* or hosting.* for the user, or approve requests. Read stim guide settings for
|
|
148
148
|
Desktop access tickets and person-owned approval.
|
|
149
|
-
Read stim guide settings to select a remote
|
|
149
|
+
Read stim guide settings to select a remote machine. Keep a requested named
|
|
150
150
|
placement when recovering STIM_OFFLOAD_REFUSED: report its reason and remedy.
|
|
151
|
-
When the user mentions slow builds, a busy
|
|
151
|
+
When the user mentions slow builds, a busy machine or wanting updates away from the desk, tell them about Stim Desktop > Settings > Remote Machines > Add or Phones > Pair a Phone; see stim guide settings.
|
|
152
152
|
|
|
153
153
|
Read stim guide lifecycle concurrency when a build waits on another workspace
|
|
154
154
|
or a build call times out. A native build can outlive a shell timeout; if the
|
|
@@ -260,6 +260,12 @@ holds it across runs; stim device unlock gives it back. Never delete another
|
|
|
260
260
|
workspace's lease file under ~/.stim/device-locks; gc --delete removes expired
|
|
261
261
|
ones.
|
|
262
262
|
|
|
263
|
+
stim device provision ios [udid] registers a phone with the project's Apple
|
|
264
|
+
Developer team and creates or refreshes its Development profile. It changes
|
|
265
|
+
the team's developer account, so never run it, and never pass it --yes,
|
|
266
|
+
without the user's explicit go-ahead for that step. When ios --device fails
|
|
267
|
+
on signing, report the remedy and ask the user.
|
|
268
|
+
|
|
263
269
|
stop and worktree remove release this workspace's leases. On a physical
|
|
264
270
|
iPhone, stop also closes the app by ending its log collector; it does not
|
|
265
271
|
shut down the phone or uninstall the app.
|
|
@@ -412,7 +418,7 @@ FULL TOPIC LIST
|
|
|
412
418
|
//#endregion
|
|
413
419
|
//#region src/guide/api.ts
|
|
414
420
|
var api_default = {
|
|
415
|
-
summary: "Typed lifecycle API: createStim, build, run, stop, diagnostics, and cancellation",
|
|
421
|
+
summary: "Typed lifecycle API: createStim, build, run, reload, stop, warmWorktree, removeWorktree, diagnostics, doctor, GC, settings, stats, logs, and cancellation",
|
|
416
422
|
body: () => `PROGRAMMATIC API
|
|
417
423
|
|
|
418
424
|
Install stim as a project dependency: npm install --save-dev stim.
|
|
@@ -430,18 +436,156 @@ Import { createStim, StimError } from 'stim'. Node 22.12 or later is required.
|
|
|
430
436
|
}
|
|
431
437
|
}
|
|
432
438
|
|
|
433
|
-
createStim takes projectRoot, optional absolute home and buildCache paths,
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
439
|
+
createStim takes projectRoot, optional absolute home and buildCache paths, an
|
|
440
|
+
env object (default process.env) that Stim reads its settings overrides from
|
|
441
|
+
and passes to its child processes, and onProgress({ stream, message }). message is an
|
|
442
|
+
output chunk. Without onProgress, operations write nothing to the caller's
|
|
443
|
+
stdout or stderr. The home is fixed when the client is created: home, else
|
|
444
|
+
STIM_HOME from env, else the default home. All operations run in the calling
|
|
445
|
+
process against the client's home and project and call the same lifecycle
|
|
446
|
+
operations as the CLI. None parses CLI arguments or changes the caller's
|
|
447
|
+
cwd/environment.
|
|
448
|
+
Custom Expo buildCacheProvider modules are not supported. Use EAS or a Stim
|
|
449
|
+
cache provider.
|
|
450
|
+
|
|
451
|
+
settings() returns the stim settings --json payload: every setting with its
|
|
452
|
+
effective value, origin and per-layer values. An invalid environment override
|
|
453
|
+
rejects with StimError STIM_BAD_ARG and its remedy. stats() returns the
|
|
454
|
+
stim stats --json payload with the last recorded agent-device and SwiftPM cache
|
|
455
|
+
usage instead of measuring them again.
|
|
456
|
+
|
|
457
|
+
setSetting(key, text, { scope?, signal?, beforeWrite? }) and
|
|
458
|
+
unsetSetting(key, { scope?, signal?, beforeWrite? }) share CLI validation and
|
|
459
|
+
return its masked JSON write result. beforeWrite(workspace) runs once after
|
|
460
|
+
resolving the target and before mutation or recording-lock waits; throwing
|
|
461
|
+
refuses the write. Server adapters use it to admit that exact workspace.
|
|
462
|
+
Later registry changes do not redirect the write or its returned setting.
|
|
463
|
+
Pending writes cancel. After commit, recording deletion finishes before the
|
|
464
|
+
promise settles, including when cancellation arrives during cleanup.
|
|
465
|
+
|
|
466
|
+
plan({ platform, slot?, signal? }) returns the configured ios/android/macos next-build
|
|
467
|
+
report, matching --plan --json, without building, launching or taking a device.
|
|
468
|
+
slot applies to ios/android. A predicted build refusal stays in the report;
|
|
469
|
+
a failure to produce a report rejects with StimError. Fingerprinting uses the
|
|
470
|
+
existing cancellable report helper. Native probes and cache downloads drain
|
|
471
|
+
before the report settles. Plans use the report budgets below. Providers must settle on abort;
|
|
472
|
+
cleanup exceeding 35 seconds refuses with STIM_CLAIM_UNAVAILABLE and retains
|
|
473
|
+
the download directory rather than deleting files a provider may still write.
|
|
474
|
+
|
|
475
|
+
doctor({ platform? }) and gc({ cache?, olderThan?, worktrees? }) read reports in
|
|
476
|
+
process with a 60 second execution budget. They accept signal and attempt
|
|
477
|
+
owned cleanup before rejecting. Deadline expiry rejects with
|
|
478
|
+
STIM_REPORT_TIMEOUT; a caller abort rejects with STIM_CANCELLED. A thrown
|
|
479
|
+
onProgress callback cancels the report and is propagated unchanged.
|
|
480
|
+
If child identity cannot be verified after a one-second retry budget, cleanup
|
|
481
|
+
refuses with STIM_CLAIM_UNAVAILABLE instead of cancellation or timeout. The
|
|
482
|
+
child cleanup error names the launcher PID; unverifiable processes and descendants are left
|
|
483
|
+
untouched. On POSIX, a launcher that exited before identity capture can only finish
|
|
484
|
+
successfully once its process group is proven gone.
|
|
485
|
+
After a termination request, cleanup waits at most one second for a child to
|
|
486
|
+
close. Overall cleanup has a 35 second budget, including temporary-worktree
|
|
487
|
+
removal; unfinished cleanup returns STIM_CLAIM_UNAVAILABLE and leaves unresolved
|
|
488
|
+
resources in place. Credential refresh waits asynchronously and checks
|
|
489
|
+
cancellation before writing.
|
|
490
|
+
On Windows, report probes require the built-in Windows PowerShell for process-tree containment.
|
|
491
|
+
|
|
492
|
+
requestMachineAccess({ ticket?, signal? }) requests build and device-host access
|
|
493
|
+
from configured remote machines without granting capabilities or repairing project
|
|
494
|
+
state. It returns the iOS doctor report and records the completed project check
|
|
495
|
+
after owned cleanup. A supplied ticket encodes 32 random bytes; omitting it
|
|
496
|
+
generates or reuses a pending ticket instead of inheriting the process environment.
|
|
497
|
+
A person approves each capability on the worker. Execution has a 120 second
|
|
498
|
+
budget and cleanup uses the report's 35 second budget. Desktop requests access
|
|
499
|
+
only through its matching-home bundled server's private desktop-machine-access
|
|
500
|
+
subscription; cancellation waits for cleanup and reconnect never repeats it.
|
|
501
|
+
|
|
502
|
+
warmWorktree({ signal?, beforeWarm? }) copies missing ignored state from the source
|
|
503
|
+
checkout into the client's linked worktree in process. It returns { exitCode },
|
|
504
|
+
0 or 1, without changing process.exitCode. Existing entries and tracked paths
|
|
505
|
+
remain untouched. Copies share a source read claim and hold an exclusive target
|
|
506
|
+
claim. beforeWarm(workspace) admits each canonical workspace in the resolved
|
|
507
|
+
warming scope before registration or copying; throwing refuses warming.
|
|
508
|
+
Progress uses onProgress. Cancellation drains the copy child before removing
|
|
509
|
+
its partial entry or releasing claims. Unknown cleanup retains those claims
|
|
510
|
+
and returns STIM_CLAIM_UNAVAILABLE with exact recovery paths. The execution
|
|
511
|
+
budget is 90 minutes; cleanup still has the 35 second budget above. The API
|
|
512
|
+
does not refresh the source or install dependencies; use CLI worktree warm
|
|
513
|
+
--refresh for that.
|
|
514
|
+
|
|
515
|
+
removeWorktree({ target?, force?, signal?, beforeRemove? }) runs the CLI's worktree removal
|
|
516
|
+
safety checks and cleanup in process. target defaults to projectRoot; relative
|
|
517
|
+
paths resolve against it. It returns { removed, exitCode } without changing
|
|
518
|
+
process.exitCode. removed is true once a linked Git worktree is deleted, even
|
|
519
|
+
if later branch cleanup fails. Source checkout environment cleanup can succeed
|
|
520
|
+
with removed: false and exitCode: 0. force has the same destructive meaning as
|
|
521
|
+
CLI --force. Cancellation stops pending work and waits for owned cleanup;
|
|
522
|
+
completed actions remain applied. It uses the report budgets above.
|
|
523
|
+
beforeRemove(workspace) runs for every canonical workspace in the resolved
|
|
524
|
+
cleanup scope before effects, including registered descendants and pending
|
|
525
|
+
branch cleanup. Throwing refuses the operation.
|
|
526
|
+
|
|
527
|
+
gc() stays read-only. collectGarbage({ cache?, olderThan?, worktrees?, delete?,
|
|
528
|
+
idleMs?, signal? }) runs the same GC selections and actions as the CLI, including
|
|
529
|
+
an unscoped sweep. It returns { report, exitCode }; exitCode is 0 or 1 and does
|
|
530
|
+
not change process.exitCode. delete: true enables deletion. idleMs reclaims
|
|
531
|
+
owned devices idle for that many milliseconds, including without delete.
|
|
532
|
+
The existing CLI rules for cache selection, workspace safety and scoped homes apply.
|
|
533
|
+
|
|
534
|
+
A deletion or idle sweep takes this home's exclusive maintenance claim;
|
|
535
|
+
concurrent maintenance rejects with STIM_CLAIM_REFUSED and names the held claim.
|
|
536
|
+
Execution and cleanup use the report budgets above. Cancellation stops pending
|
|
537
|
+
lock waits and further actions; completed actions remain applied. An archive
|
|
538
|
+
whose history has started moving finishes publication before cancellation.
|
|
539
|
+
Unresolved owned cleanup rejects with STIM_CLAIM_UNAVAILABLE and retains its
|
|
540
|
+
actual ownership claims for recovery. Progress uses onProgress; GC does not
|
|
541
|
+
replace the caller's console methods.
|
|
542
|
+
|
|
543
|
+
doctor returns the doctor --json findings and metadata, with runningPath null
|
|
544
|
+
because the caller imports the library rather than executing a Stim CLI. It
|
|
545
|
+
never repairs the project. By default it does not record a check; record: true
|
|
546
|
+
registers a supported iOS/Android project and records the checked platforms only
|
|
547
|
+
after the report and owned cleanup succeed. Recording waits asynchronously for
|
|
548
|
+
the config lock, honors signal, and rejects unavailable state. Existing remote approval
|
|
549
|
+
checks can refresh their own pending credential records. gc returns the GC
|
|
550
|
+
JSON dry-run report; it never deletes or shuts down idle devices. Report reads
|
|
551
|
+
can refresh their own measured-usage caches. Supplying home or STIM_HOME retains
|
|
552
|
+
the CLI's scoped-home restrictions on machine-global resources.
|
|
553
|
+
|
|
554
|
+
logs({ tail, sources, minLevel, slot, since, grep, errorsOnly }) returns the raw
|
|
555
|
+
stim logs --json records, including native crash capture, agent actions and Expo
|
|
556
|
+
error context. It runs in process, with asynchronous chunked reads and bounded
|
|
557
|
+
record selection when tail is supplied. A new file generation gets a compact
|
|
558
|
+
metadata index; later queries reuse it and index only appended bytes.
|
|
559
|
+
Matching agent actions are also selected within tail; attribution still scans
|
|
560
|
+
each retained session generation to establish device ownership.
|
|
561
|
+
followLogs(options, onRecord) emits the requested backfill followed by new records
|
|
562
|
+
and returns a stop function. AbortSignal also stops the subscription.
|
|
563
|
+
An optional third callback, onBackfill(records), receives initial records instead
|
|
564
|
+
of onRecord. Its promise is awaited before reading another batch; with that
|
|
565
|
+
callback and no tail, the timeline is selected in batches of at most 500.
|
|
566
|
+
Appends still go to onRecord.
|
|
567
|
+
Agent attribution still retains its matching records during this initial read.
|
|
568
|
+
Local appends use filesystem hints with a ten-second repair scan; while a
|
|
569
|
+
directory watch is unavailable, attachment and reads retry every 500 ms.
|
|
570
|
+
Attachment also schedules one 500 ms recovery scan for watch startup.
|
|
571
|
+
Expo context uses a settle timer only while an error is pending. The separate
|
|
572
|
+
agent-action cursor and active hosted log queries keep their current sampling.
|
|
438
573
|
|
|
439
574
|
run takes platform plus its options:
|
|
440
|
-
ios: configuration, scheme, deviceType, runtime
|
|
575
|
+
ios: configuration, scheme, deviceType, runtime, simulatorApp
|
|
441
576
|
android: variant, systemImage, deviceProfile
|
|
442
|
-
macos: remoteBuild
|
|
577
|
+
macos: remoteBuild, remote
|
|
443
578
|
web: headed (default false)
|
|
444
|
-
iOS and Android also accept slot, metroCheck, buildCache,
|
|
579
|
+
iOS and Android also accept slot, metroCheck, buildCache, remoteBuild, remote,
|
|
580
|
+
device, wait and easProfile. device: true auto-selects a physical device; a
|
|
581
|
+
string pins its UDID or serial. wait takes seconds as a string, such as '30'.
|
|
582
|
+
wait: false refuses a full owned-device slot immediately; on a physical device
|
|
583
|
+
it bypasses another workspace's lease and can replace its running app, as CLI
|
|
584
|
+
--no-wait does. easProfile downloads an existing compatible development build;
|
|
585
|
+
it never starts an EAS build. iOS simulatorApp selects the simulator viewer.
|
|
586
|
+
remote selects the launch host using the CLI's existing placement and approval
|
|
587
|
+
rules; remoteBuild independently selects where compilation runs. macOS requires
|
|
588
|
+
a named hosting Mac; auto, eas and proxy are not supported there.
|
|
445
589
|
All methods accept signal. run builds, installs and launches.
|
|
446
590
|
Web requires a running server, just like stim web.
|
|
447
591
|
|
|
@@ -449,6 +593,12 @@ build produces an artifact without acquiring a device, starting a runtime, or
|
|
|
449
593
|
stopping an existing session. Its result is inferred from platform:
|
|
450
594
|
const result = await stim.build({ platform: 'ios' });
|
|
451
595
|
console.log(result.facts.appPath);
|
|
596
|
+
console.log(result.facts.links.workspace);
|
|
597
|
+
|
|
598
|
+
Successful builds include facts.links.workspace, an HTTPS link to this workspace
|
|
599
|
+
on this Stim home. Agents can share it with an already-paired phone or Desktop,
|
|
600
|
+
including when Desktop is not installed on the build machine. Opening it only
|
|
601
|
+
navigates; it does not install or launch the built app.
|
|
452
602
|
|
|
453
603
|
Build options:
|
|
454
604
|
ios: scheme, configuration, arch (arm64, x86_64, all), buildCache, remoteBuild
|
|
@@ -464,22 +614,64 @@ writes its own build-artifact-<platform>.ndjson. No distribution archive or web
|
|
|
464
614
|
pipeline is inferred. Use @stim-cli/ci's buildCI to export a portable artifact and
|
|
465
615
|
diagnostics for your CI provider.
|
|
466
616
|
|
|
617
|
+
Unresolved native Metro cleanup keeps error.details.cause.retainedClaimRoots and
|
|
618
|
+
STIM_CLAIM_UNAVAILABLE even after cancellation. Web cancellation stops pending
|
|
619
|
+
browser-lock and verification waits. A new browser launch is accounted for and
|
|
620
|
+
stopped before cancellation finishes, or refuses with retained ownership when
|
|
621
|
+
cleanup cannot be confirmed.
|
|
622
|
+
|
|
467
623
|
run returns { platform, facts }. iOS facts include udid; Android includes
|
|
468
624
|
serial; both include bundleId, appPath, metroPort, cacheHit and launched.
|
|
469
625
|
macOS facts include bundle, bundleId, executable, pid, build and launched.
|
|
626
|
+
A hosted macOS result has a null local pid and preserves true or 'unverified'
|
|
627
|
+
from the host's launch evidence.
|
|
470
628
|
Web facts contain the owned browser's existing launch and page facts.
|
|
471
629
|
Do not interpret 'bundling' or 'unverified' as proven application readiness.
|
|
472
630
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
631
|
+
start({ remote?, resetCache?, waitSeconds?, signal?, beforeStart? }) starts or
|
|
632
|
+
reuses the managed dev server, using the same settings and ownership rules as
|
|
633
|
+
stim start. remote requests the configured public URL or tunnel. resetCache
|
|
634
|
+
restarts the server with a cleared transform cache. waitSeconds is a positive
|
|
635
|
+
whole number, defaulting to 60. The flat result is port, supervisorPid, mode,
|
|
636
|
+
logsDir, agentDevice and alreadyRunning.
|
|
637
|
+
beforeStart(workspace) runs once with the resolved app before usage recording
|
|
638
|
+
or effects; throwing refuses startup. Cancellation stops pending probes and lock
|
|
639
|
+
waits, then accounts for new children before returning. A verified supervisor
|
|
640
|
+
handed off to the workspace may remain running. Unconfirmed cleanup refuses with
|
|
641
|
+
STIM_CLAIM_UNAVAILABLE, taking precedence over cancellation or callback failure;
|
|
642
|
+
follow its remedy before retrying. Startup never retries automatically.
|
|
643
|
+
|
|
644
|
+
reload({ platform?, signal?, beforeReload? }) requests a JavaScript reload in
|
|
645
|
+
the live iOS/Android app or reloads the owned Chrome page. It returns the flat
|
|
646
|
+
stim reload --json facts: platform, deviceId, deviceName, appId, metroPort,
|
|
647
|
+
strategy, targets and reverseRestored. Choose ios, android or web when more
|
|
648
|
+
than one platform is live. A request does not prove completion; verify the UI
|
|
649
|
+
and inspect logs. A Metro broadcast can reach other connected clients.
|
|
650
|
+
beforeReload(workspace) runs once after resolving the workspace and before
|
|
651
|
+
usage recording or dispatch; throwing refuses the action. Reload uses the
|
|
652
|
+
60 second execution and 35 second cleanup budgets described above, including
|
|
653
|
+
STIM_REPORT_TIMEOUT and STIM_CLAIM_UNAVAILABLE. Cancellation stops pending
|
|
654
|
+
probes and dispatch, but cannot retract a reload already sent. It never retries.
|
|
655
|
+
|
|
656
|
+
stop({ slot?, beforeStop? }) returns { ok, outcomes, summary }. It acts on the
|
|
657
|
+
workspace, including resources from earlier runs. Use a dedicated workspace in CI.
|
|
658
|
+
beforeStop(workspace) runs once with the resolved workspace before teardown;
|
|
659
|
+
throwing refuses the operation.
|
|
660
|
+
From a child directory, start and stop resolve the enclosing supported app.
|
|
661
|
+
Cancellation drains the operation's owned work, a read kills its child
|
|
662
|
+
processes, and both reject with STIM_CANCELLED. Cancelling stop while it waits
|
|
663
|
+
for another native operation ends that wait. Once teardown starts, stop finishes
|
|
664
|
+
cleanup before rejecting with STIM_CANCELLED. Its config, workspace-state, and lease lock waits are asynchronous.
|
|
665
|
+
Stop with a fresh signal
|
|
476
666
|
after cancellation or partial failure. Always inspect cleanup.ok.
|
|
477
667
|
|
|
478
668
|
diagnostics({ tail: 200, errors: false }) returns { directory, records } from
|
|
479
669
|
the local timeline, even before a successful run. tail: 0 returns paths only.
|
|
480
670
|
It does not fetch remote logs or capture new crashes. Stim failures reject with
|
|
481
671
|
StimError carrying code, message, remedy and details (including the log path).
|
|
482
|
-
An exception thrown by onProgress
|
|
672
|
+
An exception thrown by onProgress stops further progress and propagates
|
|
673
|
+
unchanged: build or run is cancelled, and stop or a read
|
|
674
|
+
finishes its work first.
|
|
483
675
|
|
|
484
676
|
Normal ownership, device creation, cache locks and coordination remain active.
|
|
485
677
|
All concurrent artifact-cache writers must share the same coordinating home.
|
|
@@ -667,10 +859,10 @@ leased until <time>" for each one.`,
|
|
|
667
859
|
agentDevice { stateDir }: absolute workspace agent-device state path;
|
|
668
860
|
set AGENT_DEVICE_STATE_DIR to it (see guide logs)
|
|
669
861
|
alreadyRunning true when nothing needed starting
|
|
670
|
-
links { desktop }:
|
|
671
|
-
|
|
672
|
-
no app on this
|
|
673
|
-
prints it on stderr as "Open in Stim
|
|
862
|
+
links { desktop }: an HTTPS link containing this Stim home and
|
|
863
|
+
workspace IDs, opened by Desktop here or an already-paired phone. Absent when
|
|
864
|
+
no app on this machine opens stim-desktop links. Plain output
|
|
865
|
+
prints it on stderr as "Open in Stim: <link>"; so
|
|
674
866
|
does worktree warm, which has no JSON payload
|
|
675
867
|
|
|
676
868
|
stim macos --json
|
|
@@ -733,7 +925,7 @@ leased until <time>" for each one.`,
|
|
|
733
925
|
configuration is part of it: -release-sim vs
|
|
734
926
|
-debug-sim-arm64). A single-architecture simulator build
|
|
735
927
|
ends in its architecture (-arm64 or -x86-64): a local Debug
|
|
736
|
-
build compiles this
|
|
928
|
+
build compiles this machine's, a --remote build the remote
|
|
737
929
|
host's. A local non-Debug simulator build compiles every
|
|
738
930
|
architecture the project lists and has no suffix
|
|
739
931
|
With --eas-profile, fingerprint is computed by EAS CLI using the selected
|
|
@@ -756,7 +948,7 @@ leased until <time>" for each one.`,
|
|
|
756
948
|
looked up", which is a different fact from "nothing was found"
|
|
757
949
|
buildMachine selected auto, local or machine name, including cache hits
|
|
758
950
|
builtOn here or machine name when a build ran; absent otherwise
|
|
759
|
-
offloadedTo only on an app a remote
|
|
951
|
+
offloadedTo only on an app a remote machine compiled: its
|
|
760
952
|
remote.machines entry (see \`guide settings\`). cacheHit is
|
|
761
953
|
false for it. The Android payload carries it too
|
|
762
954
|
offloadFallback only on an app compiled here after the run considered
|
|
@@ -909,7 +1101,7 @@ leased until <time>" for each one.`,
|
|
|
909
1101
|
sets its own CMake compiler launcher, or a Gradle run whose
|
|
910
1102
|
native work was all up to date. None of the three is an
|
|
911
1103
|
error, and this field is separate from cacheHit. On an
|
|
912
|
-
offloaded APK it is the remote
|
|
1104
|
+
offloaded APK it is the remote machine's ccache
|
|
913
1105
|
logs the workspace log directory
|
|
914
1106
|
agentDevice { stateDir }: absolute workspace agent-device state path
|
|
915
1107
|
durationMs wall time for the whole run
|
|
@@ -1010,21 +1202,39 @@ leased until <time>" for each one.`,
|
|
|
1010
1202
|
freedMb, and is empty while under budget
|
|
1011
1203
|
deviceHosts one { machine, state, dnsName?, deviceId?, requestedAt?, expiresAt?,
|
|
1012
1204
|
host? } per remote.machines entry. state is "approved",
|
|
1013
|
-
"pending", "not-asked", "revoked", "lapsed", "
|
|
1014
|
-
"tailscale-off", "unreachable", "invalid",
|
|
1015
|
-
"credentials-unavailable" or "busy".
|
|
1016
|
-
Only --fix asks for access or forgets removed names.
|
|
1017
|
-
|
|
1205
|
+
"pending", "not-asked", "revoked", "lapsed", "key-changed", "outdated",
|
|
1206
|
+
"not-on-tailnet", "tailscale-off", "unreachable", "invalid",
|
|
1207
|
+
"credentials-unavailable" or "busy". Setup tickets stay private.
|
|
1208
|
+
Only --fix asks for access or forgets removed names. A
|
|
1209
|
+
peer that Tailscale reports as running an OS other than
|
|
1210
|
+
macOS is never asked or contacted and reports
|
|
1211
|
+
"not-asked" with no finding, even with a saved approval,
|
|
1212
|
+
since it can never host.
|
|
1213
|
+
A remote machine approved for device hosting does not imply
|
|
1018
1214
|
build approval; see \`guide settings\`.
|
|
1019
1215
|
host is { name, screenRecording, accessibility }, present
|
|
1020
1216
|
only for approved machines whose worker reports it.
|
|
1021
|
-
expiresAt is when a pending request
|
|
1022
|
-
|
|
1217
|
+
expiresAt is when a pending request's setup ticket
|
|
1218
|
+
expires, absent for a Stim Desktop ticket; "lapsed" is a
|
|
1219
|
+
pending request whose expiry passed. --fix asks again.
|
|
1220
|
+
"key-changed" means the worker did not prove the
|
|
1221
|
+
stim-server key pinned at approval. "outdated" means its
|
|
1222
|
+
stim-server speaks protocol 1; the finding names the
|
|
1223
|
+
stim-server service update command to run there.
|
|
1224
|
+
toolchain { entries, projectNode } on macOS, else null. entries is one { name, value,
|
|
1225
|
+
source, from? } for node, ANDROID_HOME, JAVA_HOME, stim,
|
|
1226
|
+
brew and adb: source "environment" when this process's
|
|
1227
|
+
environment provides it, "discovered" when stim-server's
|
|
1228
|
+
toolchain discovery would find it (from says where), or
|
|
1229
|
+
"missing". projectNode is { pin, spec, bin, version } when
|
|
1230
|
+
.nvmrc, .node-version, .tool-versions or package.json volta
|
|
1231
|
+
pins Node (bin and version are null when no install
|
|
1232
|
+
satisfies the pin), else null
|
|
1023
1233
|
remoteMachines one { machine, state, dnsName?, deviceId?, requestedAt?,
|
|
1024
1234
|
expiresAt?, offloadable?, reasons?, problems?, capacity?, host? } per
|
|
1025
1235
|
remote.machines entry, for its build approval; state is "approved", "pending", "not-asked",
|
|
1026
1236
|
"revoked" (revoked or denied), "lapsed" (the request lapsed
|
|
1027
|
-
before approval), "
|
|
1237
|
+
before approval), "key-changed", "outdated",
|
|
1028
1238
|
"not-on-tailnet", "tailscale-off", "unreachable" or
|
|
1029
1239
|
"invalid". host has the same shape and presence rule as in
|
|
1030
1240
|
deviceHosts, as do expiresAt (a pending request's lapse
|
|
@@ -1033,13 +1243,15 @@ leased until <time>" for each one.`,
|
|
|
1033
1243
|
simulator unless --platform android, Android emulator when
|
|
1034
1244
|
--platform android or the app has android/ or uses Expo,
|
|
1035
1245
|
plus macOS SwiftPM when Package.swift exists and no platform
|
|
1036
|
-
is selected on a Mac
|
|
1246
|
+
is selected on a Mac; a platform the machine cannot build at
|
|
1247
|
+
all, such as iOS on Linux, is left out while it can build
|
|
1248
|
+
another), and reasons, each reason it would not,
|
|
1037
1249
|
prefixed "iOS: ", "Android: " or "macOS: " when only one platform
|
|
1038
1250
|
has it, with a finding
|
|
1039
1251
|
per reason (code build-machine-<reason>: unreachable,
|
|
1040
1252
|
checkout, stim-build, arch, xcode, simulator-sdk, macos-sdk,
|
|
1041
1253
|
cocoapods, bundler, runtime, jdk, android-sdk, ndk,
|
|
1042
|
-
build-tools, compile-sdk, disk or
|
|
1254
|
+
build-tools, compile-sdk, disk, busy or platform). problems lists the same
|
|
1043
1255
|
reasons as { code, reason } with that code. capacity
|
|
1044
1256
|
is the machine's offer: { running, max, diskFreeBytes,
|
|
1045
1257
|
minDiskFreeBytes, cpus?, loadPerCore?, builds?, maxBuilds?,
|
|
@@ -1050,7 +1262,7 @@ leased until <time>" for each one.`,
|
|
|
1050
1262
|
memory-culprit is a costs-time finding naming a process
|
|
1051
1263
|
with an abnormally large footprint and, when it is safe to
|
|
1052
1264
|
restart, the command
|
|
1053
|
-
offload-candidate is a note after 3+ successful local cold builds in 7 days average over 3 min, with no remote.machines and an online tailnet Mac; open Stim Desktop Settings > Remote
|
|
1265
|
+
offload-candidate is a note after 3+ successful local cold builds in 7 days average over 3 min, with no remote.machines and an online tailnet Mac; open Stim Desktop Settings > Remote Machines > Add
|
|
1054
1266
|
|
|
1055
1267
|
ON FAILURE
|
|
1056
1268
|
\`start\`, \`ios\`, \`android\` and \`web\` all print the error contract instead,
|
|
@@ -1067,8 +1279,8 @@ ON FAILURE
|
|
|
1067
1279
|
|
|
1068
1280
|
An \`ios\` or \`android\` run that \`stim stop\` or Ctrl-C interrupted
|
|
1069
1281
|
reports STIM_CANCELLED and exits 130. A
|
|
1070
|
-
run that exits on the interrupt at once (a second
|
|
1071
|
-
|
|
1282
|
+
run that exits on the interrupt at once (a second Ctrl-C, or Ctrl-C with no
|
|
1283
|
+
build tool or SimSlim to stop) exits 130 with no payload.
|
|
1072
1284
|
|
|
1073
1285
|
\`stop --json\` prints { root, ok, supervisor, collectors, metro, device,
|
|
1074
1286
|
port, metroTunnel, releasedLeases, macos? }. macos is { status: stopped | failed,
|
|
@@ -1267,7 +1479,9 @@ RULES
|
|
|
1267
1479
|
deviceRecord,
|
|
1268
1480
|
workspaceOutputs, recording, workspaceDirectory, project,
|
|
1269
1481
|
buildLock, buildSlot, deviceLease, easSession, worktree,
|
|
1270
|
-
cache
|
|
1482
|
+
cache, gradleVersion, tempLeftover (one "done" labelled
|
|
1483
|
+
with the TMPDIR it cleared, plus a "kept" or "failed" per
|
|
1484
|
+
entry gc checked again or could not delete).
|
|
1271
1485
|
label is a device, path or cache name; id is the UDID,
|
|
1272
1486
|
AVD name or path behind it, or null. Under --cache
|
|
1273
1487
|
parked, a "done" parkedDevice was erased and stays
|
|
@@ -1316,7 +1530,7 @@ RULES
|
|
|
1316
1530
|
whole workspace directory
|
|
1317
1531
|
linkedWorktrees { path, idleDays, mergedInto, pullRequest,
|
|
1318
1532
|
pullRequestUnknown, willRemove, reason,
|
|
1319
|
-
detail, eligibleAt } mergedInto is the
|
|
1533
|
+
detail, eligibleAt, buildState } mergedInto is the
|
|
1320
1534
|
default branch HEAD is merged into
|
|
1321
1535
|
("origin/main"), or null. pullRequest is the
|
|
1322
1536
|
branch's pull request { number, state:
|
|
@@ -1327,8 +1541,33 @@ RULES
|
|
|
1327
1541
|
origin/main", "PR #12 closed", "idle 9d") or
|
|
1328
1542
|
kept. eligibleAt is the ISO time a
|
|
1329
1543
|
recent-activity worktree becomes removable,
|
|
1330
|
-
else null.
|
|
1331
|
-
|
|
1544
|
+
else null. buildState is { bytes, dirs:
|
|
1545
|
+
{ path, bytes } } for the in-tree build and
|
|
1546
|
+
dependency directories automatic maintenance
|
|
1547
|
+
clears (ios/build, android/app/build,
|
|
1548
|
+
android/build, android/.gradle, .build,
|
|
1549
|
+
node_modules, ios/Pods, at the root, a
|
|
1550
|
+
project root, or apps/* and packages/* for
|
|
1551
|
+
build directories) and a root .pnpm-store,
|
|
1552
|
+
paths relative to the worktree, largest
|
|
1553
|
+
first; du counts APFS clones in full. A bytes
|
|
1554
|
+
is null when du could not measure it within
|
|
1555
|
+
10 seconds; sizes are cached for up to an
|
|
1556
|
+
hour while no entry of the directory was
|
|
1557
|
+
added or removed. null
|
|
1558
|
+
for a root outside git. Without --worktrees,
|
|
1559
|
+
the source checkout and roots outside git
|
|
1560
|
+
are left out
|
|
1561
|
+
unlistedWorktreeDirectories
|
|
1562
|
+
{ path, repository, bytes, remedy } a
|
|
1563
|
+
directory directly under a repository's
|
|
1564
|
+
.worktrees/ that \`git worktree list\` does
|
|
1565
|
+
not show and that has no .git, or a .git file
|
|
1566
|
+
whose gitdir is gone; a worktree of another
|
|
1567
|
+
repository is left out. bytes is null when du
|
|
1568
|
+
fails. Report-only, never deleted: it may
|
|
1569
|
+
hold work. remedy is the rm -rf command to
|
|
1570
|
+
run after checking it
|
|
1332
1571
|
parkedSimulators { udid, name, model, runtime, parkedAt, app,
|
|
1333
1572
|
bytes, listed } app is the bundle id recorded
|
|
1334
1573
|
at park, else null; with --older-than, only
|
|
@@ -1351,6 +1590,20 @@ RULES
|
|
|
1351
1590
|
for AVD data with no registration)
|
|
1352
1591
|
staleDevices { kind, id, name, project, slot, idleDays,
|
|
1353
1592
|
bytes } only with --older-than
|
|
1593
|
+
finishedDevices { kind, id, name, project, slot, bytes, reason }
|
|
1594
|
+
owned devices of a workspace whose linked
|
|
1595
|
+
worktree gc keeps although its branch is
|
|
1596
|
+
merged or its pull request ended; --delete
|
|
1597
|
+
deletes them unless the workspace is in use,
|
|
1598
|
+
leased, driven, locked, pinned by
|
|
1599
|
+
maintenance.keep or used within
|
|
1600
|
+
gc.worktreeGraceMinutes
|
|
1601
|
+
ownedDeviceDisk { kind, count, bytes, unmeasured } disk of the
|
|
1602
|
+
owned simulators and emulators of registered
|
|
1603
|
+
workspaces, per platform; unmeasured counts the
|
|
1604
|
+
ones whose size could not be read; parked
|
|
1605
|
+
devices are under parkedSimulators and
|
|
1606
|
+
parkedEmulators
|
|
1354
1607
|
staleDeviceRecords { kind, id, project, slot } --delete clears
|
|
1355
1608
|
the record only
|
|
1356
1609
|
staleLedgerEntries { kind: "ios" | "android" | "web", id }
|
|
@@ -1412,6 +1665,51 @@ RULES
|
|
|
1412
1665
|
null with any --cache scope
|
|
1413
1666
|
swiftpmCache <SwiftpmCacheUsage|null> report-only, never deleted;
|
|
1414
1667
|
null with any --cache scope
|
|
1668
|
+
gradleVersions { home, olderThanDays, blocked, gradleRunning,
|
|
1669
|
+
gradleRunningPids, versions: [{ version, dirs,
|
|
1670
|
+
bytes, lastModifiedAt, willDelete, reason,
|
|
1671
|
+
detail }], leftovers } | null; only with
|
|
1672
|
+
--cache gradle-versions. blocked is null or
|
|
1673
|
+
{ reason, detail } with machine-global,
|
|
1674
|
+
no-registry, unsafe-layout, listing-failed,
|
|
1675
|
+
unreadable-project, gradle-running or
|
|
1676
|
+
processes-unknown; gradleRunning is the
|
|
1677
|
+
gradle-running detail or null and
|
|
1678
|
+
gradleRunningPids the pids behind it; a
|
|
1679
|
+
version's reason is null, one of those,
|
|
1680
|
+
not-a-directory, walk-failed, too-many-entries
|
|
1681
|
+
or recently-modified. leftovers lists
|
|
1682
|
+
.stim-delete-* directories --delete finishes
|
|
1683
|
+
removing
|
|
1684
|
+
machineCaches { measuredAt, complete, notices, gradle, simRuntimes,
|
|
1685
|
+
deviceSupport, runnerBuilds } | null
|
|
1686
|
+
report-only, never deleted; null with any
|
|
1687
|
+
--cache scope. gradle: { home, unusedVersions:
|
|
1688
|
+
[{ version, bytes, dirs, remedy }],
|
|
1689
|
+
usedVersions: [{ version, projects }],
|
|
1690
|
+
unreadableProjects, modules }. simRuntimes:
|
|
1691
|
+
{ checked, runtimes: [{ identifier,
|
|
1692
|
+
runtimeIdentifier, version, build, bytes,
|
|
1693
|
+
deletable, lastUsedAt, devices, remedy }] }.
|
|
1694
|
+
deviceSupport: { entries: [{ dir, bytes }],
|
|
1695
|
+
remedy }. runnerBuilds: { agentDeviceVersion,
|
|
1696
|
+
xcodeBuildVersion, groups: [{ packageVersion,
|
|
1697
|
+
xcodeBuildVersion, current, entries, inUse,
|
|
1698
|
+
bytes, oldestUseAt }], remedy }. Sizes and
|
|
1699
|
+
versions come from
|
|
1700
|
+
$STIM_HOME/machine-cache-usage.json, at most
|
|
1701
|
+
10 minutes old
|
|
1702
|
+
tempLeftovers { root, groups: [{ kind, count, bytes,
|
|
1703
|
+
deleteCount, deleteBytes, kept: [{ reason,
|
|
1704
|
+
count }], remedy }] } | null recognized
|
|
1705
|
+
entries directly in TMPDIR (root, resolved).
|
|
1706
|
+
kind is stim (stim-claim-*, stim-host-*,
|
|
1707
|
+
stim-fakehome-*, stim-hosted-macos-*,
|
|
1708
|
+
stim-server-*, stim-ws-* directories), xctrace
|
|
1709
|
+
(instruments*.ktrace) or jest (Jest's
|
|
1710
|
+
jest_<uid in base 36> cache, never deleted). deleteCount
|
|
1711
|
+
is what --delete removes. null with STIM_HOME
|
|
1712
|
+
set or any --cache scope
|
|
1415
1713
|
caches { name, dir, source, bytes, note, willEmpty,
|
|
1416
1714
|
emptySkipped, scopedEmpty } alive, not
|
|
1417
1715
|
garbage; willEmpty marks the ones --delete
|
|
@@ -1454,7 +1752,8 @@ RULES
|
|
|
1454
1752
|
stim-server
|
|
1455
1753
|
linkedWorktrees not-a-worktree | bare-repository |
|
|
1456
1754
|
source-checkout-unknown | source-checkout |
|
|
1457
|
-
locked |
|
|
1755
|
+
locked | nested-worktree | in-use |
|
|
1756
|
+
status-unreadable | dirty |
|
|
1458
1757
|
unpushed-unchecked | unpushed | submodules |
|
|
1459
1758
|
not-merged | merge-unknown | last-use-unknown |
|
|
1460
1759
|
recently-used | activity-unknown |
|
|
@@ -1798,7 +2097,7 @@ RULES
|
|
|
1798
2097
|
device: its boot, adoption cleanup, or a physical
|
|
1799
2098
|
device's lease and connection check. A boot that
|
|
1800
2099
|
finishes during the build adds no device time. For a
|
|
1801
|
-
device hosted on another
|
|
2100
|
+
device hosted on another machine, device covers reserving
|
|
1802
2101
|
and preparing it there, install covers delivering the
|
|
1803
2102
|
app, and launch starts when the host launches it. An
|
|
1804
2103
|
--eas-profile run has no cache lookup, so its outcome
|
|
@@ -1940,7 +2239,7 @@ RULES
|
|
|
1940
2239
|
lookup, and create no lastBuild record or failed-run stats.
|
|
1941
2240
|
buildMachine selected auto, local or configured machine entry; always on new build records
|
|
1942
2241
|
builtOn here or machine name; absent when no build ran (cache/refusal)
|
|
1943
|
-
offloadedTo only on a run a remote
|
|
2242
|
+
offloadedTo only on a run a remote machine compiled: its name
|
|
1944
2243
|
offloadFallback
|
|
1945
2244
|
only on a run that considered offloading and built here: one
|
|
1946
2245
|
reason per machine when none took the build, or why the
|
|
@@ -2180,7 +2479,7 @@ RULES
|
|
|
2180
2479
|
baseline. rekeyedBy is empty.
|
|
2181
2480
|
placement with ios.remote or android.remote set to auto or a Mac,
|
|
2182
2481
|
where the plan assumes the device runs: "on <machine>" or
|
|
2183
|
-
"this
|
|
2482
|
+
"this machine; auto may use <machines>"; absent otherwise
|
|
2184
2483
|
refusal { code, message, remedy } when the run would refuse:
|
|
2185
2484
|
STIM_PREBUILD_FAILED for a tracked native dir the fingerprint
|
|
2186
2485
|
leaves out, STIM_EAS_BUILD_MISSING for an EAS miss
|
|
@@ -2212,7 +2511,7 @@ RULES
|
|
|
2212
2511
|
A bucket carries runs, failed, hits, misses, coldRuns, coldRunMs, hitRuns,
|
|
2213
2512
|
hitRunMs, timeSavedMs, firstRunAt and lastRunAt, plus lastColdBuildMs and
|
|
2214
2513
|
lastPodsMs once the project has compiled or installed pods, and
|
|
2215
|
-
offloadedRuns, offloadedRunMs and lastOffloadHost once a remote
|
|
2514
|
+
offloadedRuns, offloadedRunMs and lastOffloadHost once a remote machine
|
|
2216
2515
|
compiled one. An offloaded run is a miss but not a cold run, so the cold
|
|
2217
2516
|
average, time saved and build estimates stay local. Milliseconds are
|
|
2218
2517
|
integers.
|
|
@@ -2332,10 +2631,10 @@ BUILD PLACEMENT (\`offload\`)
|
|
|
2332
2631
|
decision, reason, machine?, buildMs?, slotWaitMs?, deviceSlotWaitMs?, localEstimateMs?, failed? }.
|
|
2333
2632
|
slotWaitMs and deviceSlotWaitMs are whole milliseconds waiting for build
|
|
2334
2633
|
and owned-device slots respectively, present only when positive.
|
|
2335
|
-
decision is "here", "offloaded", or "fell-back" (it tried a remote
|
|
2634
|
+
decision is "here", "offloaded", or "fell-back" (it tried a remote machine
|
|
2336
2635
|
and built here). reason is why: the run's \`placement:\` reason, such as
|
|
2337
2636
|
"load 0.6/core, 1 of 3 build slots busy here" (auto keeps the build here
|
|
2338
|
-
while this
|
|
2637
|
+
while this machine has room) or "remote.buildMode is off" (which prints no line),
|
|
2339
2638
|
or for a fallback the cause, prefixed by the machine it concerns, such as
|
|
2340
2639
|
"mini: no less loaded (load 1.2/core there, 0.6/core here)". buildMs is the compile here, or the offloaded build's
|
|
2341
2640
|
total (offer, sync, build and fetch); localEstimateMs is this project's
|
|
@@ -2344,7 +2643,7 @@ BUILD PLACEMENT (\`offload\`)
|
|
|
2344
2643
|
placements lists them newest first: the last 100 from the last 7 days.
|
|
2345
2644
|
Per machine, \`total\` keeps { offloaded, offloadedMs, savedMs, fallbacks,
|
|
2346
2645
|
lastOffloadAt?, lastFallbackAt? } for good and \`today\` counts { offloaded,
|
|
2347
|
-
offloadedMs, savedMs, fallbacks } from the placements on this
|
|
2646
|
+
offloadedMs, savedMs, fallbacks } from the placements on this machine's local
|
|
2348
2647
|
calendar day. savedMs sums localEstimateMs minus buildMs over offloaded
|
|
2349
2648
|
builds that had an estimate, so it is an ESTIMATE and is negative when the
|
|
2350
2649
|
machine was slower. \`offload.today\` counts the day's placements by
|
|
@@ -2382,7 +2681,7 @@ comes from \`start --remote\`, eas/proxy in \`ios.remote\`, or \`android.remote\
|
|
|
2382
2681
|
HOSTED IOS METRO
|
|
2383
2682
|
ios --remote <machine> keeps Metro local and needs no start --remote.
|
|
2384
2683
|
The supervisor watches private gateway requests in workspace state, binds
|
|
2385
|
-
only this
|
|
2684
|
+
only this machine's Tailscale address and accepts only the pinned hosting peer
|
|
2386
2685
|
with a per-session secret. The host's bridge is loopback-only. Port and secret
|
|
2387
2686
|
stay in 0600 workspace state and never appear in status, JSON or logs.
|
|
2388
2687
|
metro.tunnel and metro.publicUrl are ignored. Supervisor restart recreates
|
|
@@ -2522,6 +2821,12 @@ WHAT THE SUPERVISOR IS
|
|
|
2522
2821
|
launches stay UNVERIFIED: read \`stim logs --source metro\`
|
|
2523
2822
|
for the bundle lines.
|
|
2524
2823
|
|
|
2824
|
+
expo-child and command-child put the Node the app pins (.nvmrc,
|
|
2825
|
+
.node-version, .tool-versions nodejs, or package.json volta.node) first
|
|
2826
|
+
on PATH when an nvm, fnm, Volta, asdf or mise install satisfies the pin
|
|
2827
|
+
and the node already on PATH does not; the metro log then records a
|
|
2828
|
+
project_node event naming it. bare-inproc runs on the supervisor's Node.
|
|
2829
|
+
|
|
2525
2830
|
In expo-child mode, remote intent plus metro.tunnel "expo" makes \`start\` pass
|
|
2526
2831
|
\`--tunnel\` and EXPO_UNSTABLE_TUNNEL_V2=1 (the legacy ws-tunnel path is
|
|
2527
2832
|
locked to port 8081, which every reserved port but the first collides with)
|
|
@@ -2829,6 +3134,18 @@ FLAGS
|
|
|
2829
3134
|
mode only, on stderr. With --errors, an Expo error record
|
|
2830
3135
|
also carries context (see THE RECORD).
|
|
2831
3136
|
|
|
3137
|
+
Local follow uses filesystem change hints with a ten-second repair scan for
|
|
3138
|
+
missed events or a replaced directory. Until a directory watch is available,
|
|
3139
|
+
it retries and scans every 500 ms, with one recovery scan 500 ms after attachment.
|
|
3140
|
+
On Windows a moved log directory can require the ten-second repair scan.
|
|
3141
|
+
Expo context settling uses a timer only
|
|
3142
|
+
while an error is pending; otherwise idle files are not repeatedly scanned.
|
|
3143
|
+
Local agent actions also follow their state and claim directories, coalescing file
|
|
3144
|
+
changes instead of re-reading every 500 ms while idle.
|
|
3145
|
+
While following, hosted targets join and leave from local state notifications.
|
|
3146
|
+
Missed notifications are reconciled about every 10 seconds. Active hosts still
|
|
3147
|
+
serve bounded log queries.
|
|
3148
|
+
|
|
2832
3149
|
--ERRORS, PRECISELY
|
|
2833
3150
|
Level error or fatal, from metro, client and build, plus device records with
|
|
2834
3151
|
event native_crash (app/device/time-correlated OS reports or fatal app console output)
|
|
@@ -2916,7 +3233,7 @@ FLAGS
|
|
|
2916
3233
|
responses, do not cut the stack short. Human output joins the lines to the
|
|
2917
3234
|
message. --json leaves msg as captured and adds them to the error record as
|
|
2918
3235
|
a context array of strings; each record is still one line. --follow holds an
|
|
2919
|
-
Expo error until a
|
|
3236
|
+
Expo error until a 500 ms settle check adds no more of its lines, so
|
|
2920
3237
|
it can print up to about a second after Expo does. Non-follow human output
|
|
2921
3238
|
also shows bare React Native symbolication as separate context, because
|
|
2922
3239
|
Metro does not provide an error correlation identifier. Context never
|
|
@@ -2965,16 +3282,16 @@ failures before a later launch marker are hidden. Machine passes are reported in
|
|
|
2965
3282
|
status and maintenance/maintenance.ndjson; this command reads workspace logs.
|
|
2966
3283
|
|
|
2967
3284
|
REMOTE REQUEST RECORDS
|
|
2968
|
-
A request to another
|
|
3285
|
+
A request to another machine that fails is a warn record with src: build in the
|
|
2969
3286
|
run's build log: remote_connect_failed { host, capability, ms, timeoutMs, msg,
|
|
2970
|
-
code } (could not connect or say hello, e.g. "no reply in time" when the
|
|
3287
|
+
code } (could not connect or say hello, e.g. "no reply in time" when the machine
|
|
2971
3288
|
did not answer hello) and remote_request_failed { method, ms, code, msg }.
|
|
2972
3289
|
Timings of requests that succeed are debug records (below).
|
|
2973
3290
|
stim-server writes to its service log (~/Library/Logs/Stim/<label>.log), with
|
|
2974
3291
|
no tokens or tickets: "request failed method=<m> client=<device id> run=<runId>
|
|
2975
3292
|
ms=<n> error=<code>" for an error reply (once a minute per client, method and
|
|
2976
3293
|
code) and "host_connect ... error=<reason_with_underscores>" when its connection to a hosting
|
|
2977
|
-
|
|
3294
|
+
machine fails. With debug.logs on or STIM_DEBUG=1 for the server it logs every
|
|
2978
3295
|
request instead: "debug request method=<m> client=<id> run=<runId> ms=<n>
|
|
2979
3296
|
slow=true error=<code> whois=<ms> probe=<ms>" (slow means 1000 ms or more;
|
|
2980
3297
|
whois and probe are the hello's Tailscale identity lookup and its wait for
|
|
@@ -2991,14 +3308,14 @@ stim logs does not show them. Read them with jq:
|
|
|
2991
3308
|
jq -c 'select(.event=="exec" and .ms>1000)' ~/.stim/logs/debug/cli.ndjson
|
|
2992
3309
|
Events: run_start, run_end { exit, ms }, exec { program, ms, ok, exit? }, and
|
|
2993
3310
|
remote_connect and remote_request { ms, ok, code? } for requests to another
|
|
2994
|
-
|
|
3311
|
+
machine. They carry no arguments, tokens or tickets.
|
|
2995
3312
|
|
|
2996
3313
|
Placement records use src: placement and sit in the run's build log
|
|
2997
3314
|
(build-*.ndjson), so a new run replaces the previous run's. A run writes one
|
|
2998
|
-
record per decision it makes (a build that compiles and has a remote
|
|
3315
|
+
record per decision it makes (a build that compiles and has a remote machine to
|
|
2999
3316
|
consider, or ios/android --remote auto), with event build_placement,
|
|
3000
3317
|
device_placement or placement_fallback. A cache hit, a project with no paired
|
|
3001
|
-
remote
|
|
3318
|
+
remote machine and a named --remote target write none:
|
|
3002
3319
|
stim logs --source placement
|
|
3003
3320
|
stim logs --source placement --json
|
|
3004
3321
|
Fields: kind (build or device), platform, settings [{ key, value, from }] with
|
|
@@ -3006,7 +3323,7 @@ from flag, env, setting or default (remote.build and remote.buildMode for a
|
|
|
3006
3323
|
build, ios.remote or android.remote, plus remote.easFallback when it is on, for
|
|
3007
3324
|
a device), candidates [{ machine, code,
|
|
3008
3325
|
msg, detail? }], choice { machine, code, msg } with machine local when the run
|
|
3009
|
-
stays on this
|
|
3326
|
+
stays on this machine, and fallback { code, msg, machine? } when a remote machine that
|
|
3010
3327
|
was meant to take the run did not (level warn). The msg is the same text the
|
|
3011
3328
|
placement: and build: phase lines print.
|
|
3012
3329
|
Candidate codes: accepted, unreachable, busy, disk, load, version-mismatch
|
|
@@ -3204,6 +3521,13 @@ WHAT WRITES WHAT
|
|
|
3204
3521
|
};
|
|
3205
3522
|
//#endregion
|
|
3206
3523
|
//#region src/guide/errors.ts
|
|
3524
|
+
const PROVISION_CONTEXT = `\`stim device provision ios [udid]\` is the one Stim command that changes an Apple
|
|
3525
|
+
Developer account: it registers the phone with the project's team and creates
|
|
3526
|
+
or refreshes the iOS App Development profile (and, when the keychain holds
|
|
3527
|
+
none, an Apple Development certificate) by running xcodebuild with
|
|
3528
|
+
-allowProvisioningUpdates -allowProvisioningDeviceRegistration. No build, and
|
|
3529
|
+
no \`ios --device\` run, ever does this. Agents run it only when the user
|
|
3530
|
+
explicitly asks for this step.`;
|
|
3207
3531
|
const errors = {
|
|
3208
3532
|
summary: "Every refusal Stim can print: an index of codes, and one section for each",
|
|
3209
3533
|
sectionHint: "<CODE>",
|
|
@@ -3215,10 +3539,11 @@ Branch on the code, never on the message.`,
|
|
|
3215
3539
|
STIM_HOSTING_REFUSED: {
|
|
3216
3540
|
summary: "a hosting Mac refused or could not confirm its native session; no fallback after reservation",
|
|
3217
3541
|
body: () => `STIM_HOSTING_REFUSED
|
|
3218
|
-
The message names the hosting Mac and its reason: unreachable
|
|
3219
|
-
|
|
3542
|
+
The message names the hosting Mac and its reason: unreachable, a changed
|
|
3543
|
+
server key, a stim-server too old to speak protocol 2 (stim doctor names
|
|
3544
|
+
the update command), no installed simulator or emulator choice, no capacity, elevated or unknown
|
|
3220
3545
|
memory pressure, or an unresolved reservation or delivery. Stim boots nothing
|
|
3221
|
-
locally and never tries another
|
|
3546
|
+
locally and never tries another machine after choosing a named host or creating a
|
|
3222
3547
|
hosted session. Auto skips declined offers before building, then uses the
|
|
3223
3548
|
local queue if none admits. A reserve refusal after an accepted offer fails
|
|
3224
3549
|
with this code and asks to retry; it does not re-place the built architecture.
|
|
@@ -3236,7 +3561,7 @@ Branch on the code, never on the message.`,
|
|
|
3236
3561
|
on the host to enable handoff and native logs (hello features hosted-ios-data
|
|
3237
3562
|
for iOS and hosted-android-data for Android).
|
|
3238
3563
|
A name outside remote.machines is STIM_BAD_ARG. Missing or pending hosting
|
|
3239
|
-
approval keeps the doctor --fix and stim-server
|
|
3564
|
+
approval keeps the doctor --fix and stim-server setup remedies.`
|
|
3240
3565
|
},
|
|
3241
3566
|
STIM_EAS_BUILD_MISSING: {
|
|
3242
3567
|
summary: "no completed EAS development build matches; build only with session authorization",
|
|
@@ -3340,7 +3665,7 @@ Branch on the code, never on the message.`,
|
|
|
3340
3665
|
the source checkout, then warm again.`
|
|
3341
3666
|
},
|
|
3342
3667
|
STIM_BUILD_FAILED: {
|
|
3343
|
-
summary: "xcodebuild or gradle failed; the Android missing-SDK and APK refusals
|
|
3668
|
+
summary: "xcodebuild or gradle failed; the Android missing-SDK and APK refusals",
|
|
3344
3669
|
body: () => `STIM_BUILD_FAILED
|
|
3345
3670
|
xcodebuild or gradle failed. The EXTRACTED diagnostics are printed (capped),
|
|
3346
3671
|
not the transcript. Read the log path on the next line for the rest.
|
|
@@ -3367,17 +3692,40 @@ Branch on the code, never on the message.`,
|
|
|
3367
3692
|
reports UP-TO-DATE and repackages nothing. Stim installs it. Gradle owns task
|
|
3368
3693
|
freshness and the fingerprint owns cache freshness; Stim does not second-guess
|
|
3369
3694
|
either from the file's mtime.
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3695
|
+
A damaged compilation-cache object stays STIM_BUILD_FAILED when Stim did
|
|
3696
|
+
not give the build its shared cache; STIM_COMPILATION_CACHE_CORRUPT lists
|
|
3697
|
+
the messages and the gc remedy.`
|
|
3698
|
+
},
|
|
3699
|
+
STIM_COMPILATION_CACHE_CORRUPT: {
|
|
3700
|
+
summary: "an iOS build failed on a damaged shared compilation cache; Stim emptied it, rerun the command",
|
|
3701
|
+
body: () => `STIM_COMPILATION_CACHE_CORRUPT (ios)
|
|
3702
|
+
The build used the shared compilation cache ($STIM_HOME/compilation-cache)
|
|
3703
|
+
and the compiler reported a damaged object in it. A cache write that a full
|
|
3704
|
+
disk or a killed build cut short leaves such an object, and every later build
|
|
3705
|
+
that reaches it fails the same way. Stim matches only the compiler's own
|
|
3706
|
+
corruption errors in the transcript:
|
|
3707
|
+
LLVM ERROR: OnDiskCAS: corrupt internal reference
|
|
3708
|
+
error: CAS operation failed: ...
|
|
3376
3709
|
error: CAS-based dependency scan failed: not a IncludeTreeRoot node kind
|
|
3377
|
-
|
|
3378
|
-
object
|
|
3379
|
-
|
|
3380
|
-
|
|
3710
|
+
Xcode reports them per source file, so the failing targets are whichever
|
|
3711
|
+
reach the object first -- often pods you did not touch -- and they change
|
|
3712
|
+
between runs.
|
|
3713
|
+
Stim empties the whole cache at once, the way
|
|
3714
|
+
\`gc --delete --cache "compilation cache"\` does, and fails the build. It
|
|
3715
|
+
does not retry. RUN THE SAME COMMAND AGAIN: that build starts with an empty
|
|
3716
|
+
cache, so it is a cold one. The emptying is recorded in the maintenance log.
|
|
3717
|
+
Every iOS build that compiles with the cache holds a shared claim on it,
|
|
3718
|
+
<cache>.claims beside the cache directory, while xcodebuild runs. Stim
|
|
3719
|
+
empties the cache only under that set's exclusive claim, here, in gc and in
|
|
3720
|
+
maintenance. When another build holds it or its claim is unresolved, Stim
|
|
3721
|
+
leaves the cache alone, because that build may be using it, and the message
|
|
3722
|
+
says so. Once nothing else is building, run
|
|
3723
|
+
\`gc --delete --cache "compilation cache"\`, then run the command again.
|
|
3724
|
+
A build on a build worker gets the same handling on the worker, which
|
|
3725
|
+
empties its own cache for that client. With --remote-build <machine> the
|
|
3726
|
+
build fails with this code and the worker's message; otherwise it falls
|
|
3727
|
+
back to building here, and the fallback line names this code. Xcode builds
|
|
3728
|
+
run outside Stim take no claim, so a cache they share is not guarded.`
|
|
3381
3729
|
},
|
|
3382
3730
|
STIM_PATH_TOO_LONG: {
|
|
3383
3731
|
summary: "Windows only: the project root leaves no room for the NDK object paths ninja must open",
|
|
@@ -3387,12 +3735,17 @@ Branch on the code, never on the message.`,
|
|
|
3387
3735
|
after their mangled absolute source path, so each carries the project root
|
|
3388
3736
|
twice unless CMake shortens it, and CMake only shortens a name that then
|
|
3389
3737
|
fits the object path limit Stim's Gradle shim sets. The message names the
|
|
3390
|
-
longest known object
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3738
|
+
longest known object for the ABI being built and the longest root it
|
|
3739
|
+
leaves room for. A project with react-native-gesture-handler 3, whose
|
|
3740
|
+
shared shadow nodes have the longest known object path, fits a root of at
|
|
3741
|
+
most 24 characters for an x86_64 Debug build and 21 for arm64-v8a; other
|
|
3742
|
+
projects fit 51 and 48. Refused BEFORE Gradle
|
|
3743
|
+
runs -- a cache hit still installs -- because the build would otherwise
|
|
3744
|
+
fail deep inside ninja ("mkdir ... No such file or directory" or
|
|
3745
|
+
"Filename longer than 260 characters"). Move or clone the project under a
|
|
3746
|
+
short real path such as C:\\src\\<name> and run Stim there. A subst drive
|
|
3747
|
+
does not help: Node's realpath and Expo autolinking resolve it back to the
|
|
3748
|
+
long path, and Gradle then sees two roots.
|
|
3396
3749
|
A custom Gradle buildStagingDirectory can be shorter than the default; this
|
|
3397
3750
|
preflight does not inspect that configured path and may refuse it too.
|
|
3398
3751
|
\`doctor --platform android\` reports the same root as a finding for the
|
|
@@ -3534,7 +3887,7 @@ Branch on the code, never on the message.`,
|
|
|
3534
3887
|
works. See stim guide macos.`
|
|
3535
3888
|
},
|
|
3536
3889
|
STIM_OFFLOAD_REFUSED: {
|
|
3537
|
-
summary: "the selected remote
|
|
3890
|
+
summary: "the selected remote machine or automatic build pool cannot build this app",
|
|
3538
3891
|
body: () => `STIM_OFFLOAD_REFUSED
|
|
3539
3892
|
|
|
3540
3893
|
Automatic placement also refuses when local is excluded in remote.buildPoolDisabled
|
|
@@ -3544,20 +3897,20 @@ builds are not interrupted and a cache hit needs no compiler.
|
|
|
3544
3897
|
|
|
3545
3898
|
A named --remote-build selection is strict. The message names the machine
|
|
3546
3899
|
and why it cannot take or finish the build: not configured or paired, approval
|
|
3547
|
-
pending or denied, unreachable
|
|
3900
|
+
pending or denied, unreachable, changed pinned server key, a stim-server
|
|
3901
|
+
too old to speak protocol 2, incompatible
|
|
3548
3902
|
toolchain/runtime/CPU, low disk, busy, sync/build failure, artifact failure,
|
|
3549
3903
|
or a checkout that changed while it built. Unsupported build kinds also refuse.
|
|
3550
3904
|
No local xcodebuild, Gradle or SwiftPM compile or alternate machine follows a
|
|
3551
|
-
refusal. Prebuild and pod install still run on this
|
|
3905
|
+
refusal. Prebuild and pod install still run on this machine before a named offload.
|
|
3552
3906
|
Unlisted or unpaired names refuse at setup before consulting the cache, without
|
|
3553
3907
|
a build record or failed-run stats. A listed paired name with a cache hit needs
|
|
3554
3908
|
no build and does not contact the selected machine.
|
|
3555
3909
|
|
|
3556
3910
|
Run stim doctor --fix to ask for build access if not paired. Check
|
|
3557
|
-
stim settings get remote.machines. A person on the worker
|
|
3558
|
-
stim-server
|
|
3559
|
-
|
|
3560
|
-
(guide settings). Agents never run setup or approve requests.
|
|
3911
|
+
stim settings get remote.machines. A person on the worker approves this machine
|
|
3912
|
+
by running the stim-server setup command doctor --fix printed, with its ticket
|
|
3913
|
+
and expiry (guide settings). Agents never run setup or approve requests.
|
|
3561
3914
|
Rerun with --remote-build auto for normal placement and local fallback, or
|
|
3562
3915
|
--remote-build local to keep the build here.
|
|
3563
3916
|
`
|
|
@@ -3565,12 +3918,14 @@ Rerun with --remote-build auto for normal placement and local fallback, or
|
|
|
3565
3918
|
STIM_WORKTREE_SERVICE: {
|
|
3566
3919
|
summary: "worktree remove refuses a folder a stim-server service runs from",
|
|
3567
3920
|
body: () => `STIM_WORKTREE_SERVICE
|
|
3568
|
-
A
|
|
3569
|
-
StimService marker in
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3921
|
+
A service that \`stim-server service install\` wrote runs a program from
|
|
3922
|
+
inside this worktree: on macOS a LaunchAgent with a StimService marker in
|
|
3923
|
+
~/Library/LaunchAgents/<label>.plist, on Linux a systemd user unit with an
|
|
3924
|
+
[X-Stim] Managed=true section in ~/.config/systemd/user/<label>.service
|
|
3925
|
+
(default label dev.stim.server). Removing the folder would delete the
|
|
3926
|
+
running server's code. The refusal also covers a service that is installed
|
|
3927
|
+
but stopped, because launchd or systemd starts it again, and a marked file
|
|
3928
|
+
Stim could not read. \`--force\` does not
|
|
3574
3929
|
override it, and gc leaves the worktree in place.
|
|
3575
3930
|
Reinstall the service from another build (stim-server service install --label
|
|
3576
3931
|
<label> from a checkout that stays), or remove it with stim-server service
|
|
@@ -3671,10 +4026,11 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
3671
4026
|
The built or cached .app has no embedded.mobileprovision, or
|
|
3672
4027
|
\`openssl smime\` could not decode the one it has. The first means the build
|
|
3673
4028
|
produced an unsigned app -- almost always a simulator-sliced artifact.
|
|
3674
|
-
Set a team
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
4029
|
+
Set a team for the target's configuration in Xcode > Signing &
|
|
4030
|
+
Capabilities, then run \`stim device provision ios [udid]\` (see
|
|
4031
|
+
STIM_PROVISION_UNCONFIRMED) or BUILD ONCE FROM XCODE to install the profile.
|
|
4032
|
+
No build does that step: registering a device or minting a profile changes
|
|
4033
|
+
your Apple Developer account, so builds never pass
|
|
3678
4034
|
-allowProvisioningUpdates.`
|
|
3679
4035
|
},
|
|
3680
4036
|
STIM_PROFILE_MISMATCH: {
|
|
@@ -3692,8 +4048,10 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
3692
4048
|
refuses rather than guessing. Local device runs need a development
|
|
3693
4049
|
profile;
|
|
3694
4050
|
- it is a development or ad hoc profile whose device list does not name
|
|
3695
|
-
this UDID.
|
|
3696
|
-
|
|
4051
|
+
this UDID. Run \`stim device provision ios <udid>\`, which registers
|
|
4052
|
+
the UDID and refreshes the Development profile after asking, or
|
|
4053
|
+
register it at developer.apple.com, regenerate the profile, and build
|
|
4054
|
+
once from Xcode.
|
|
3697
4055
|
With --eas-profile, follow the EAS device:create and build commands in the
|
|
3698
4056
|
refusal instead. Registration, signing changes and cloud builds need session
|
|
3699
4057
|
authorization. See stim guide lifecycle eas.`
|
|
@@ -3727,6 +4085,44 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
3727
4085
|
and confirm exactly one identity matches the name. The cache entry itself is
|
|
3728
4086
|
never modified -- the failure is on a temporary copy, and the run builds
|
|
3729
4087
|
fresh.`
|
|
4088
|
+
},
|
|
4089
|
+
STIM_PROVISION_UNCONFIRMED: {
|
|
4090
|
+
summary: "device provision ios listed its account changes and nobody confirmed them; nothing changed",
|
|
4091
|
+
separator: "--- iOS PROVISIONING CODES (`stim device provision ios`, and only there) ---",
|
|
4092
|
+
context: PROVISION_CONTEXT,
|
|
4093
|
+
body: () => `STIM_PROVISION_UNCONFIRMED
|
|
4094
|
+
The command printed what it would change -- the team, the phone, each bundle
|
|
4095
|
+
id whose Development profile it would create or refresh, and whether it uses
|
|
4096
|
+
the Xcode account or an App Store Connect API key -- and nobody confirmed:
|
|
4097
|
+
the terminal prompt was answered with anything but y, or there was no
|
|
4098
|
+
terminal (or --json) and no --yes. Nothing changed. \`--json\` adds the plan.
|
|
4099
|
+
Confirm in a terminal, or pass --yes once the account owner agreed. Agents
|
|
4100
|
+
never add --yes on their own.`
|
|
4101
|
+
},
|
|
4102
|
+
STIM_PROVISION_FAILED: {
|
|
4103
|
+
summary: "device provision ios could not provision: no account or key, team not accessible, or project signing",
|
|
4104
|
+
context: PROVISION_CONTEXT,
|
|
4105
|
+
body: () => `STIM_PROVISION_FAILED
|
|
4106
|
+
Before xcodebuild runs: the app has no Xcode project, xcodebuild cannot
|
|
4107
|
+
report the scheme's build settings, a signed target names no development
|
|
4108
|
+
team or uses manual signing (xcodebuild creates profiles only for automatic
|
|
4109
|
+
signing), the temporary DerivedData cannot be created, or a native app uses
|
|
4110
|
+
Swift packages that Stim has not resolved yet (no workspace-state.json in
|
|
4111
|
+
its package directory): run \`stim ios\` or \`stim ios --device <udid>\` once
|
|
4112
|
+
to resolve them, then provision. Packages resolved for an older
|
|
4113
|
+
Package.resolved fail inside xcodebuild, whose error is quoted. The remedy
|
|
4114
|
+
names the Xcode or app-config change. From xcodebuild: "No Accounts" means Xcode has no Apple
|
|
4115
|
+
ID signed in and no App Store Connect key is set -- sign in under Xcode >
|
|
4116
|
+
Settings > Accounts, or set ios.appStoreConnectKeyPath,
|
|
4117
|
+
ios.appStoreConnectKeyId and ios.appStoreConnectIssuerId (stim guide
|
|
4118
|
+
settings); "No Account for Team" means that account or key cannot reach the
|
|
4119
|
+
project's team; a 401 means Apple rejected the key. Any other xcodebuild
|
|
4120
|
+
error is quoted, with the key path replaced. An interrupt or the 15-minute
|
|
4121
|
+
timeout also ends here. Once xcodebuild has run, the refusal still lists
|
|
4122
|
+
any profile it installed and any new keychain identity (\`--json\`:
|
|
4123
|
+
\`changes\`), because Apple may already have registered the phone; running
|
|
4124
|
+
the command again is safe. A phone that is not paired or has Developer Mode
|
|
4125
|
+
off refuses earlier, with STIM_NO_DEVICE.`
|
|
3730
4126
|
},
|
|
3731
4127
|
STIM_NO_LAN_ADDRESS: {
|
|
3732
4128
|
summary: "the Mac has no non-internal IPv4 interface; a tunnel cannot help a phone",
|
|
@@ -4324,7 +4720,8 @@ captured" (in metro.ndjson, bare RN)
|
|
|
4324
4720
|
a changed pin while this workspace's dev server runs or its supervisor
|
|
4325
4721
|
cannot be verified,
|
|
4326
4722
|
\`--device\` with an empty
|
|
4327
|
-
serial or UDID, \`--device\` together with \`--remote
|
|
4723
|
+
serial or UDID, \`--device\` together with \`--remote\` other than
|
|
4724
|
+
\`local\`, \`ios --runtime\`
|
|
4328
4725
|
on an eas/proxy run (\`--remote\` or ios.remote; that backend picks the
|
|
4329
4726
|
iOS version), \`ios --device-type\` on the proxy backend or with an
|
|
4330
4727
|
eas-cli older than 22.2.0 on the eas backend, \`android --system-image\` or
|
|
@@ -4392,20 +4789,34 @@ captured" (in metro.ndjson, bare RN)
|
|
|
4392
4789
|
\`workspace removal\` -- both are \`stim worktree remove\`). Let it finish,
|
|
4393
4790
|
then run the command again. \`start --remote\` reports this same case as
|
|
4394
4791
|
STIM_WORKTREE_REMOVAL_IN_PROGRESS instead.`
|
|
4792
|
+
},
|
|
4793
|
+
STIM_REPORT_TIMEOUT: {
|
|
4794
|
+
summary: "An in-process report or lifecycle operation exceeded its execution budget",
|
|
4795
|
+
body: () => `STIM_REPORT_TIMEOUT
|
|
4796
|
+
|
|
4797
|
+
An API operation exceeded its execution budget: 90 minutes for warmWorktree(),
|
|
4798
|
+
60 seconds for doctor(), gc(), collectGarbage(), reload(), plan() and removeWorktree().
|
|
4799
|
+
Stim attempts only that operation's cleanup before rejecting, with a 35 second
|
|
4800
|
+
cleanup budget. Unfinished cleanup returns STIM_CLAIM_UNAVAILABLE instead.
|
|
4801
|
+
Other clients are unaffected. Retry after the machine is less busy, or narrow
|
|
4802
|
+
the report with doctor({ platform }) or gc({ cache }). doctor() and gc() remain
|
|
4803
|
+
read-only. collectGarbage() can mutate resources; completed actions remain applied.
|
|
4804
|
+
Inspect what remains with gc() before retrying a mutation.
|
|
4805
|
+
`
|
|
4395
4806
|
},
|
|
4396
4807
|
STIM_CANCELLED: {
|
|
4397
4808
|
summary: "an ios or android run was interrupted by `stim stop` or Ctrl-C before it finished",
|
|
4398
4809
|
body: () => `STIM_CANCELLED (ios, android; exit 130)
|
|
4399
4810
|
"The ios run was cancelled by \`stim stop\` (pid <n>) before it finished."
|
|
4400
|
-
The run
|
|
4401
|
-
|
|
4811
|
+
The run was interrupted: by \`stim stop\`, which cancels a build it leaves
|
|
4812
|
+
with nothing to deploy to, or by Ctrl-C. It forwarded the interrupt
|
|
4402
4813
|
to the build tool it was running (xcodebuild, Gradle, pod install, expo
|
|
4403
4814
|
prebuild) and failed through its own cleanup; the next line names the step it
|
|
4404
4815
|
stopped at. An interrupted build stores no artifact, so the next run looks
|
|
4405
4816
|
up the cache as usual. Stopped between build tools, a run that \`stop\`
|
|
4406
4817
|
cancelled starts no further build tool and stops before it installs. A
|
|
4407
|
-
second
|
|
4408
|
-
|
|
4818
|
+
second Ctrl-C exits at once, and so does a Ctrl-C with no build tool or
|
|
4819
|
+
SimSlim to stop; those exits print no payload. Run the same command again when you want the
|
|
4409
4820
|
app on a device.`
|
|
4410
4821
|
},
|
|
4411
4822
|
STIM_STOP_BLOCKED: {
|
|
@@ -4416,6 +4827,10 @@ captured" (in metro.ndjson, bare RN)
|
|
|
4416
4827
|
- "... did not exit within 60s of SIGINT": the run was interrupted but is
|
|
4417
4828
|
still running. Wait for it, or end it with the \`kill <pid>\` the remedy
|
|
4418
4829
|
prints, then run \`stim stop\` again.
|
|
4830
|
+
- "... did not exit within 60s of the stop request": the run is inside a
|
|
4831
|
+
process that embeds Stim, such as stim-server, and runs other work too.
|
|
4832
|
+
Stop does not signal that process. Wait for the run, or cancel it from
|
|
4833
|
+
the client that started it, then run \`stim stop\` again.
|
|
4419
4834
|
- "... pid <n> is no longer that run; the build tool it started (pid <m>)
|
|
4420
4835
|
still holds the claim": the run itself died and its build tool keeps the
|
|
4421
4836
|
claim. Stim signals only a claim owner whose recorded identity it can
|
|
@@ -4773,14 +5188,6 @@ not on any remote" (worktree remove)
|
|
|
4773
5188
|
Expo build-cache provider would each use a different store. Set the named
|
|
4774
5189
|
variable to an absolute path, or unset it to use the default. Metro and the
|
|
4775
5190
|
cache provider, which cannot refuse, ignore a relative value with a warning.`
|
|
4776
|
-
},
|
|
4777
|
-
STIM_WORKER_FAILED: {
|
|
4778
|
-
summary: "a programmatic API worker exited without returning an operation result",
|
|
4779
|
-
body: () => `STIM_WORKER_FAILED (programmatic API)
|
|
4780
|
-
The worker process ended without a structured result. StimError.details
|
|
4781
|
-
includes its final stderr output. Inspect that output and call diagnostics()
|
|
4782
|
-
for existing workspace logs, then stop() with a fresh signal to clean up
|
|
4783
|
-
any resources created before the failure. See stim guide api.`
|
|
4784
5191
|
},
|
|
4785
5192
|
STIM_RUN_FAILED: {
|
|
4786
5193
|
summary: "a programmatic operation failed without a more specific Stim code",
|
|
@@ -4915,6 +5322,16 @@ with eas or proxy starts it the way \`stim start --remote\` does. A named
|
|
|
4915
5322
|
hosting Mac keeps Metro local through a private bridge; see hosted-ios. Step 2 remains useful to warm
|
|
4916
5323
|
Metro while other work happens.
|
|
4917
5324
|
|
|
5325
|
+
Each time Stim boots an owned local simulator or emulator, it mutes it: iOS
|
|
5326
|
+
simulators to volume zero through Xcode's devicectl, and Android 15 and later
|
|
5327
|
+
emulators to media volume zero. A device that is already running keeps its
|
|
5328
|
+
volume. Turn sound on for one device with Sound (iOS) or Media sound
|
|
5329
|
+
(Android) in its Stim Desktop options; the choice lasts until that device next
|
|
5330
|
+
boots. Android 14 and older images have no shell command that can set media
|
|
5331
|
+
volume, so startup warns, as it does whenever a mute is not confirmed. Host
|
|
5332
|
+
volume, Android alarm and ringtone volumes, hosted devices and physical
|
|
5333
|
+
devices are unchanged.
|
|
5334
|
+
|
|
4918
5335
|
Repeat step 3 whenever a NATIVE input changes. A JS-only edit needs nothing --
|
|
4919
5336
|
that is what Fast Refresh over the running dev server is for. \`stim reload\` is
|
|
4920
5337
|
not part of the normal workflow. It is the explicit recovery path when Fast
|
|
@@ -5036,9 +5453,10 @@ STOP DURING A BUILD
|
|
|
5036
5453
|
lock waiting for \`stim ios\` (pid 41233, running for 12m04s) in this workspace to finish
|
|
5037
5454
|
\`stop\` does not wait out a build it leaves with nothing to deploy to: a
|
|
5038
5455
|
plain \`stop\`, \`stop --slot <name>\` for the slot the build targets, or
|
|
5039
|
-
for the workspace's only device. It
|
|
5040
|
-
|
|
5041
|
-
|
|
5456
|
+
for the workspace's only device. It asks that run to stop through the
|
|
5457
|
+
workspace state and, when the run is a CLI process, also sends it SIGINT,
|
|
5458
|
+
only after proving the run's recorded process identity. It waits up to 60
|
|
5459
|
+
seconds for the run to exit. The run stops its build tool, stores nothing from the
|
|
5042
5460
|
interrupted build, and exits 130 with STIM_CANCELLED. A run that does not
|
|
5043
5461
|
exit in time, or whose build tool outlived it, is refused with
|
|
5044
5462
|
STIM_STOP_BLOCKED naming its pid and claim. \`stop --slot <name>\` while the
|
|
@@ -5068,11 +5486,20 @@ WAITING FOR A CHANGE
|
|
|
5068
5486
|
changes, never two identical ones in a row. In a watch line, a usage
|
|
5069
5487
|
figure repeats its value in the previous line until it moves by a step: an owner's cpuPercent 5 points, an
|
|
5070
5488
|
owner's or environment's memoryMb and capacity.committedMb 16 MB. An owner's row
|
|
5071
|
-
changes as a whole, so its residentMb and processes update with it.
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5489
|
+
changes as a whole, so its residentMb and processes update with it. A change
|
|
5490
|
+
in only a bookkeeping timestamp prints no line: each pullRequest.checkedAt,
|
|
5491
|
+
maintenance.lastChecks, maintenance.lastPass.startedAt and durationMs, and
|
|
5492
|
+
maintenance.running.startedAt. A line that prints carries their current
|
|
5493
|
+
values. It reacts to Stim state files,
|
|
5494
|
+
the EAS session ledger, git HEAD, index and ref changes in the worktrees'
|
|
5495
|
+
repositories, the exit of a recorded supervisor, Metro, build, browser or
|
|
5496
|
+
macOS app process (checked every 2 seconds), adb device arrivals and
|
|
5497
|
+
departures, and simulator boots, shutdowns, creations and deletions (from
|
|
5498
|
+
CoreSimulator's device set and metadata files, with a simctl check every 30 seconds), and
|
|
5499
|
+
recomputes every 30 seconds as a fallback. A log append updates the log-derived facts
|
|
5500
|
+
within about a second; device activity follows at most every 5 seconds. The
|
|
5501
|
+
first line does not wait for git: worktree git summaries can be null in it,
|
|
5502
|
+
and the next line carries them. Ctrl+C, SIGTERM or closing its stdout ends it
|
|
5076
5503
|
with exit 0. On Linux, so does the exit of the process that started it
|
|
5077
5504
|
when its stdout is a pipe. It notices within a few seconds even when
|
|
5078
5505
|
nothing changes, except a closed stdout pipe on Linux whose starter is
|
|
@@ -5121,7 +5548,7 @@ C-family header graphs, Swift package graphs and unresolved external input
|
|
|
5121
5548
|
paths or compiler overrides. The miss reason explains the exclusion. --plan
|
|
5122
5549
|
refuses such a prediction; omit --plan to prepare and build the app.
|
|
5123
5550
|
|
|
5124
|
-
A compatible approved
|
|
5551
|
+
A compatible approved remote Mac can compile a native Xcode app with
|
|
5125
5552
|
--remote-build auto or --remote-build <name>. Both peers must support
|
|
5126
5553
|
native-xcode-build. This first worker path requires a verified artifact identity
|
|
5127
5554
|
and all inputs contained in the repository and visible to git. Ignored or
|
|
@@ -5168,8 +5595,34 @@ density/split APK sets and EAS/proxy targets are unsupported. Set
|
|
|
5168
5595
|
org.gradle.configureondemand=false; configuration cache remains supported.
|
|
5169
5596
|
Stim verifies the existing APK signature; it does not sign it.
|
|
5170
5597
|
|
|
5171
|
-
|
|
5172
|
-
|
|
5598
|
+
Local APK caching requires project-scoped \`android.artifactInputs\`:
|
|
5599
|
+
\`{"complete":true,"ignored":[],"outputs":["build","app/build"],"localFiles":["../signing/release.keystore"],"environment":["SIGNING_PASSWORD"]}\`.
|
|
5600
|
+
complete promises a repeatable build from Git-visible source, declared ignored
|
|
5601
|
+
files, exact local files and named environment values, with pinned dependencies
|
|
5602
|
+
and unmodified pinned toolchains. Declare custom signing, JVM user.home, alternate
|
|
5603
|
+
toolchain and external configuration inputs; arbitrary Gradle reads cannot be
|
|
5604
|
+
inferred. Local files may be absolute or project-relative; absence is hashed.
|
|
5605
|
+
Default debug keystores, JDK release, SDK version metadata, Gradle user properties
|
|
5606
|
+
and init scripts also contribute. SDK directory paths alone do not change the
|
|
5607
|
+
key; other local.properties contents do. Keys must be plain and unescaped, and
|
|
5608
|
+
values must fit on one line; Java Properties escapes in sdk.dir values are supported.
|
|
5609
|
+
Unsupported syntax disables artifact caching. The AGP SDK must match ANDROID_HOME.
|
|
5610
|
+
Inputs are checked again after compilation; a change prevents publication.
|
|
5611
|
+
Cached APK bytes, package, signing certificate and target ABI are verified.
|
|
5612
|
+
A configured provider with a files capability shares the completed APK and
|
|
5613
|
+
verification receipt. Stim checks the local cache first, verifies downloaded
|
|
5614
|
+
bytes, then fills the local cache. Invalid shared entries are cache misses;
|
|
5615
|
+
providers without files are skipped. Private input contents are neither logged
|
|
5616
|
+
nor transferred. This contract grants no build-worker transfer access.
|
|
5617
|
+
Without it, native builds remain uncached and Gradle retains its incremental and
|
|
5618
|
+
task caches. optimizations.buildCache=false disables artifact reads and writes.
|
|
5619
|
+
--no-build-cache skips reads and shared-build waits, but stores the fresh build.
|
|
5620
|
+
Native Android --plan verifies the same key and cached APK without running Gradle;
|
|
5621
|
+
unresolved ABI (including legacy unowned emulator assignments), missing declarations,
|
|
5622
|
+
hosted placement and CAS setup refuse it.
|
|
5623
|
+
|
|
5624
|
+
|
|
5625
|
+
Build workers require a project-scoped \`android.offloadInputs\` declaration:
|
|
5173
5626
|
\`{"complete":true,"ignored":["app/src/main/assets/generated.json"],"outputs":["build","app/build"]}\`.
|
|
5174
5627
|
Use \`stim android --remote-build <approved-mac>\` after reviewing this declaration.
|
|
5175
5628
|
Paths are exact repository-relative paths. complete affirms that Git-visible
|
|
@@ -5179,8 +5632,17 @@ homes. External inputs, directory links, submodules and custom local.properties
|
|
|
5179
5632
|
refuse; an SDK-only local.properties stays local. Only declared directories
|
|
5180
5633
|
reported by AGP and previously produced by this worker remain warm, along with
|
|
5181
5634
|
worker project .gradle/.kotlin state. Undeclared bytes are removed. Gradle owns
|
|
5182
|
-
incremental, task-cache and configuration-cache reuse
|
|
5183
|
-
|
|
5635
|
+
incremental, task-cache and configuration-cache reuse. A transferred
|
|
5636
|
+
android.artifactInputs declaration also lets the worker reuse verified APKs under
|
|
5637
|
+
its own complete inputs: worker toolchain, signing files and environment values,
|
|
5638
|
+
not the caller's. The returned fingerprint remains null; transfer digests never
|
|
5639
|
+
become reusable APK cache keys. Workers with native-gradle-peer-cache can offer a
|
|
5640
|
+
completed APK for declared source and resolved variant, ABI and build options,
|
|
5641
|
+
rechecking current private inputs against the saved receipt at offer and fetch.
|
|
5642
|
+
A hit skips source upload and compilation even while that worker is busy or
|
|
5643
|
+
this machine has room. A miss follows normal placement; older Gradle workers
|
|
5644
|
+
still build normally. Off mode, explicit local builds and disabled remote cache
|
|
5645
|
+
reads skip peer lookup. Hosts without native-gradle-build refuse before upload.
|
|
5184
5646
|
|
|
5185
5647
|
outputs must list every build directory of this build's projects that the build
|
|
5186
5648
|
creates: the root build directory and each module's, library modules included.
|
|
@@ -5190,7 +5652,7 @@ Included builds (includeBuild, such as a build-logic plugin build) and
|
|
|
5190
5652
|
externalNativeBuild staging (.cxx) are not reported by AGP and cannot be
|
|
5191
5653
|
declared, so a remote build that creates them fails and Stim builds locally.
|
|
5192
5654
|
|
|
5193
|
-
Native Android \`--plan\`
|
|
5655
|
+
Native Android \`--plan\` requires a complete artifact input declaration and does not execute Gradle; \`doctor\` reports native
|
|
5194
5656
|
prerequisites. \`reload\` refuses because the app has no Metro runtime. Re-run
|
|
5195
5657
|
\`stim android\` after an edit and use \`stim stop\` for scoped cleanup.`
|
|
5196
5658
|
},
|
|
@@ -5252,12 +5714,13 @@ A person on the host approves device-host access, separately from build, read
|
|
|
5252
5714
|
and control. The setup in hosted-ios also serves Android. android.remote sets
|
|
5253
5715
|
a workspace default. eas and proxy remain backends. --remote auto or
|
|
5254
5716
|
android.remote = auto places automatically; see hosted-ios for the shared
|
|
5255
|
-
policy. No flag or setting runs on this
|
|
5717
|
+
policy. No flag or setting runs on this machine.
|
|
5256
5718
|
|
|
5257
5719
|
A named Mac is strict: refusal, unreachable, declined or failed preparation
|
|
5258
|
-
returns STIM_HOSTING_REFUSED without fallback. --device
|
|
5259
|
-
machine, a running local owned emulator in
|
|
5260
|
-
hosted Metro development apps refuse
|
|
5720
|
+
returns STIM_HOSTING_REFUSED without fallback. --device with --remote
|
|
5721
|
+
<machine>, a different recorded machine, a running local owned emulator in
|
|
5722
|
+
the slot, and --no-metro-check for hosted Metro development apps refuse
|
|
5723
|
+
STIM_BAD_ARG. Run stim stop before switching placement.
|
|
5261
5724
|
Unreadable android.host blocks only its slot; restore its recorded machine and
|
|
5262
5725
|
session from the host before stopping that slot.
|
|
5263
5726
|
|
|
@@ -5273,7 +5736,7 @@ bridge; the host reverses the client's Metro port into that bridge on its exact
|
|
|
5273
5736
|
ledger-owned serial and sets debug_http_host to localhost:<clientMetroPort>.
|
|
5274
5737
|
Each run and stim reload android restores the reverse, including after a host
|
|
5275
5738
|
adb server restart. Reload broadcasts through the local Metro and never runs
|
|
5276
|
-
adb against the host serial on this
|
|
5739
|
+
adb against the host serial on this machine. Release variants skip Metro. Launch
|
|
5277
5740
|
is true only with client bundle evidence or a live host release process;
|
|
5278
5741
|
bundling requires a bundle request and unverified has no launch evidence.
|
|
5279
5742
|
|
|
@@ -5303,7 +5766,7 @@ arrive through local Metro.
|
|
|
5303
5766
|
|
|
5304
5767
|
AGENT CONTROL
|
|
5305
5768
|
|
|
5306
|
-
Set hosting.agentDriver to agent-device on the hosting Mac. Both
|
|
5769
|
+
Set hosting.agentDriver to agent-device on the hosting Mac. Both machines need
|
|
5307
5770
|
agent-device 0.21.22 or later. The host advertises hosted-android-agent and
|
|
5308
5771
|
starts one loopback daemon per installed Android session. Its policy allows
|
|
5309
5772
|
only the exact ledger-owned emulator serial and denies device shutdown.
|
|
@@ -5344,8 +5807,8 @@ on the owned emulator until Stim deletes it. A daemon exit rotates only that
|
|
|
5344
5807
|
session's grant; rerun stim android to refresh its config.
|
|
5345
5808
|
|
|
5346
5809
|
Stim Desktop and the phone app view and control the emulator through this
|
|
5347
|
-
|
|
5348
|
-
phones in Desktop and pair the phone with this
|
|
5810
|
+
machine's local stim-server relay, with an "on <machine>" label. Turn on Serve to
|
|
5811
|
+
phones in Desktop and pair the phone with this machine, not the hosting Mac.
|
|
5349
5812
|
frames.subscribe and control.begin address workspace, platform android and
|
|
5350
5813
|
slot, including named slots. The host verifies its exact ledger-owned serial,
|
|
5351
5814
|
AVD identity and ABI before capture or input; clients never use that serial
|
|
@@ -5359,9 +5822,9 @@ are unavailable through the scrcpy path.
|
|
|
5359
5822
|
|
|
5360
5823
|
Reruns send only missing manifest and APK digests from the session-scoped blob
|
|
5361
5824
|
store. The host verifies reused bytes; each new attempt still installs the APK.
|
|
5362
|
-
When an Android build ran on the hosting Mac's
|
|
5825
|
+
When an Android build ran on the hosting Mac's own stim-server, the host takes only
|
|
5363
5826
|
the single App.apk matching the client's manifest. The build and hosting approvals
|
|
5364
|
-
must belong to the same
|
|
5827
|
+
must belong to the same client key. Handoff failure falls back to upload,
|
|
5365
5828
|
retrying a busy host for at most one minute.
|
|
5366
5829
|
|
|
5367
5830
|
stim logs, including --errors and --json, pulls native logcat records as src: device.
|
|
@@ -5392,8 +5855,7 @@ If Stim is not installed globally, replace stim with npx stim.
|
|
|
5392
5855
|
|
|
5393
5856
|
stim settings set remote.machines '["janics-mac-mini"]'
|
|
5394
5857
|
stim doctor --fix
|
|
5395
|
-
# A person there
|
|
5396
|
-
# Or runs stim-server setup on the worker with its client node, ticket and expiry.
|
|
5858
|
+
# A person there runs the stim-server setup command doctor printed.
|
|
5397
5859
|
stim doctor
|
|
5398
5860
|
stim ios --remote janics-mac-mini --device-type "iPhone 17 Pro" --runtime "iOS 27.0"
|
|
5399
5861
|
stim status --json
|
|
@@ -5401,7 +5863,7 @@ If Stim is not installed globally, replace stim with npx stim.
|
|
|
5401
5863
|
stim stop
|
|
5402
5864
|
|
|
5403
5865
|
The same setup serves macos --remote. Approval is separate from build, read
|
|
5404
|
-
and phone control. Set ios.remote to the machine name for a default (machine scope for
|
|
5866
|
+
and phone control. Set ios.remote to the machine name for a default (machine scope for every app on this machine);
|
|
5405
5867
|
no flag or setting runs here. eas and proxy keep their remote backend meanings.
|
|
5406
5868
|
--remote auto (or ios.remote = auto / android.remote = auto) stays here when
|
|
5407
5869
|
there is a free concurrency.maxDevices slot (0 means unlimited), no device
|
|
@@ -5413,7 +5875,8 @@ members from new automatic placement only; an excluded local member is never a
|
|
|
5413
5875
|
fallback. Existing sessions keep their owner and named placement bypasses the pool.
|
|
5414
5876
|
See stim guide settings for separate build/device membership controls.
|
|
5415
5877
|
|
|
5416
|
-
Otherwise Stim asks every approved remote.machines host in parallel,
|
|
5878
|
+
Otherwise Stim asks every approved remote.machines host in parallel, skipping
|
|
5879
|
+
one that tailscale status reports as running an OS other than macOS, with a
|
|
5417
5880
|
3-second probe timeout and this run's model/runtime or image/profile selectors.
|
|
5418
5881
|
A compatible choice, no declined reason, normal memory pressure and available
|
|
5419
5882
|
capacity are required. With a free local slot, a host must report a lower load;
|
|
@@ -5422,11 +5885,11 @@ Hosts rank by the build preference (flag > STIM_REMOTE_BUILD > remote.build)
|
|
|
5422
5885
|
when it names a machine, then lowest load, most free memory and remote.machines order. Automatic build
|
|
5423
5886
|
offload resolves later, after the device architecture is known.
|
|
5424
5887
|
|
|
5425
|
-
When no host admits and this
|
|
5888
|
+
When no host admits and this machine is at its concurrency.maxDevices cap (or runs
|
|
5426
5889
|
are queued ahead), remote.easFallback (default false; EAS Simulator is billed)
|
|
5427
5890
|
runs the device on an EAS Simulator exactly as --remote eas would: the build
|
|
5428
5891
|
stays here, nothing starts an EAS cloud build, stop ends the session, and
|
|
5429
|
-
status reports it under remoteDevices. A busy
|
|
5892
|
+
status reports it under remoteDevices. A busy machine with a free slot never uses
|
|
5430
5893
|
it. Before choosing it Stim checks, without starting a session, that eas-cli
|
|
5431
5894
|
has simulator commands (and 22.2.0+ for --device-type), eas
|
|
5432
5895
|
simulator:availability says this project's account can use it, agent-device
|
|
@@ -5434,7 +5897,7 @@ is on PATH, the slot is default, no --runtime, --system-image or
|
|
|
5434
5897
|
--device-profile flag is given, no EAS Simulator session of this workspace runs
|
|
5435
5898
|
another platform or model, and a Debug run's Metro is reachable (not
|
|
5436
5899
|
metro.tunnel off; on an Expo tunnel, run stim start --remote first). A recorded
|
|
5437
|
-
EAS session is not sticky: once this
|
|
5900
|
+
EAS session is not sticky: once this machine has room, auto runs here and the
|
|
5438
5901
|
session bills until stim stop. If any check fails, or the
|
|
5439
5902
|
setting is off, auto runs here and may wait in the existing FIFO device
|
|
5440
5903
|
slot queue; --no-wait and --wait 0 refuse with STIM_AT_CAPACITY. The placement
|
|
@@ -5449,7 +5912,8 @@ A reserve refusal after a successful offer can race with another run. It fails
|
|
|
5449
5912
|
with STIM_HOSTING_REFUSED naming the host and asking to retry. Stim does not
|
|
5450
5913
|
try the next host or local placement after the build has targeted that host's
|
|
5451
5914
|
architecture, and never falls back once a hosted session exists. A named machine remains strict. --device
|
|
5452
|
-
cannot combine with auto
|
|
5915
|
+
cannot combine with --remote auto, and a --device run ignores ios.remote and
|
|
5916
|
+
android.remote. eas/proxy and macOS placement are unchanged.
|
|
5453
5917
|
--simulator-app is honoured locally with auto and ignored with a note on a host.
|
|
5454
5918
|
Placement measures budgets without reclaiming; only a new local run reclaims.
|
|
5455
5919
|
Android --remote <machine> uses an owned emulator on that Mac; see hosted-android.
|
|
@@ -5459,7 +5923,7 @@ here or elsewhere. --device cannot use a hosting Mac, and --simulator-app
|
|
|
5459
5923
|
refuses. The host boots headless and ignores this Mac's iosSimulatorApp setting.
|
|
5460
5924
|
--slot, --device-type and --runtime select the hosted simulator; --scheme,
|
|
5461
5925
|
--configuration and --eas-profile select the app as usual. The build targets
|
|
5462
|
-
the offered simulator architecture, not this
|
|
5926
|
+
the offered simulator architecture, not this machine's. --remote-build remains
|
|
5463
5927
|
independent and selects a compatible build worker for a Debug cache miss.
|
|
5464
5928
|
|
|
5465
5929
|
The host's own owned devices count toward concurrency.maxDevices.
|
|
@@ -5482,7 +5946,7 @@ sessions.
|
|
|
5482
5946
|
|
|
5483
5947
|
Stim builds or fetches before reserving, records the session immediately, then
|
|
5484
5948
|
uploads the app on every run. React Native and Expo Debug keep Metro here; the supervisor owns a
|
|
5485
|
-
private gateway bound to this
|
|
5949
|
+
private gateway bound to this machine's Tailscale address, pinned to the host peer
|
|
5486
5950
|
and protected by a per-session secret. The host exposes only a loopback bridge.
|
|
5487
5951
|
No start --remote is needed; metro.tunnel and metro.publicUrl are ignored.
|
|
5488
5952
|
Debug requires a running supervisor with private gateway support before reserving
|
|
@@ -5494,7 +5958,7 @@ apps use process mode in every configuration and require no Metro; see native-io
|
|
|
5494
5958
|
|
|
5495
5959
|
A rerun on the same named Mac reattaches and delivers a new app attempt. A
|
|
5496
5960
|
stopped or missing session is replaced; an unreachable or unknown owner refuses
|
|
5497
|
-
replacement. Switching between this
|
|
5961
|
+
replacement. Switching between this machine and a hosting Mac, or to a different
|
|
5498
5962
|
hosting Mac, refuses for that slot: run stim stop first.
|
|
5499
5963
|
Status adds ios.host { machine, session, selected, device: { name, runtime },
|
|
5500
5964
|
agent, state } per slot. A shutdown local simulator is replaced in status; a
|
|
@@ -5562,7 +6026,8 @@ tail before parking or deletion, including on revocation or server close; stop c
|
|
|
5562
6026
|
back afterwards. If the final collection drops a backlog interval and eventually
|
|
5563
6027
|
succeeds, a device warning record names that interval. A damaged collection checkpoint is ignored and
|
|
5564
6028
|
rebuilt; it never blocks reading collected records. The client waits up to
|
|
5565
|
-
|
|
6029
|
+
280 seconds for stop. The final collection, parking, the stop that follows a failed
|
|
6030
|
+
park and worker termination paths fit within
|
|
5566
6031
|
that wait; an in-flight handoff copy and closing Metro or view transports are
|
|
5567
6032
|
outside those worker bounds.
|
|
5568
6033
|
Collected records remain in the session home after parking or deletion;
|
|
@@ -5574,7 +6039,7 @@ host gets an update note, uses uploads and shows logs already copied here.
|
|
|
5574
6039
|
|
|
5575
6040
|
AGENT CONTROL
|
|
5576
6041
|
|
|
5577
|
-
On the hosting Mac, set hosting.agentDriver to agent-device. Both
|
|
6042
|
+
On the hosting Mac, set hosting.agentDriver to agent-device. Both machines need
|
|
5578
6043
|
agent-device 0.21.20 or later (the policy and remote-config contract). The host
|
|
5579
6044
|
starts one loopback daemon per installed iOS session under a child-aware
|
|
5580
6045
|
ownership claim. Its daemon policy pins exactly that simulator UDID and denies
|
|
@@ -5631,8 +6096,8 @@ daemon startup or grant issuance on client support. The client checks the host's
|
|
|
5631
6096
|
hosted-ios-agent feature before using a grant.
|
|
5632
6097
|
|
|
5633
6098
|
Stim Desktop and the phone app view and control the simulator through this
|
|
5634
|
-
|
|
5635
|
-
in Desktop; pair the phone with this
|
|
6099
|
+
machine's stim-server relay, with an "on <machine>" label. Turn on Serve to phones
|
|
6100
|
+
in Desktop; pair the phone with this machine, not the hosting Mac. frames.subscribe
|
|
5636
6101
|
and control.begin address workspace, platform ios and slot, including named
|
|
5637
6102
|
slots. The relay shares one authenticated host connection with hosted macOS
|
|
5638
6103
|
viewers. Stopped sessions show a rerun remedy; unavailable hosts report why
|
|
@@ -6202,8 +6667,8 @@ PREDICTING THE NEXT BUILD (--plan)
|
|
|
6202
6667
|
architecture or ABI from that Mac's device offer, the question a run asks
|
|
6203
6668
|
before it reserves anything. With auto it repeats the placement decision a
|
|
6204
6669
|
run would make now and reports where in the payload's placement field, for
|
|
6205
|
-
example "this
|
|
6206
|
-
this
|
|
6670
|
+
example "this machine; auto may use janics-mac-mini". When the plan stays on
|
|
6671
|
+
this machine and a listed Mac would build for another architecture, placement
|
|
6207
6672
|
says so, since that Mac's key differs. The plan only predicts the key: a
|
|
6208
6673
|
run reads the architecture of the device it actually gets. A Mac that does
|
|
6209
6674
|
not answer, ios.remote or android.remote set to eas or proxy, or auto that
|
|
@@ -6399,7 +6864,8 @@ then compiles through the cache the selection leaves -- ccache, or none when
|
|
|
6399
6864
|
compilerCache is none. It never refuses. See
|
|
6400
6865
|
https://stim.appandflow.com/docs/android-cas for setup, evidence, and limits.
|
|
6401
6866
|
Compiler/PCH modes have separate generated directories under each module's
|
|
6402
|
-
.cxx/stim-<profile> (
|
|
6867
|
+
.cxx/stim-<profile> (.cxx/<first 4 profile characters> on Windows, or custom
|
|
6868
|
+
staging root). Switching modes in Stim selects
|
|
6403
6869
|
the matching directory; direct Gradle builds keep their own configuration.
|
|
6404
6870
|
Generated CAS directories still depend on Stim's environment and adapter paths.
|
|
6405
6871
|
|
|
@@ -6431,8 +6897,8 @@ THE BUILD CACHE HAS THREE LEVELS
|
|
|
6431
6897
|
@stim-cli/cache contract (see \`guide settings\`). Consulted only when
|
|
6432
6898
|
level one misses, and its hit is stored into level one before install.
|
|
6433
6899
|
The same contract serves the Metro transform cache.
|
|
6434
|
-
3. On an EXPO project only,
|
|
6435
|
-
Expo (\`expo.buildCacheProvider\` -- "eas"
|
|
6900
|
+
3. On an EXPO project only, EAS when the project configures it through
|
|
6901
|
+
Expo (\`expo.buildCacheProvider\` -- "eas").
|
|
6436
6902
|
Consulted only when levels one and two miss, bounded so a slow or expired
|
|
6437
6903
|
remote cannot stall the loop, and a hit is copied into level one on the
|
|
6438
6904
|
way past so the next workspace on this machine gets it for free. After a
|
|
@@ -6441,6 +6907,14 @@ THE BUILD CACHE HAS THREE LEVELS
|
|
|
6441
6907
|
tier because its run-options contract cannot distinguish ABIs; levels one
|
|
6442
6908
|
and two remain ABI-keyed and active.
|
|
6443
6909
|
|
|
6910
|
+
The "eas" tier needs eas-build-cache-provider in the app and an installed
|
|
6911
|
+
eas-cli in the app or on PATH. Stim runs its fixed EAS CLI commands without
|
|
6912
|
+
loading the provider SDK into the caller. Fingerprint generation uploads
|
|
6913
|
+
fingerprint metadata to EAS. Fingerprint and transfer commands share one deadline per phase; timeout or
|
|
6914
|
+
cancellation stops that phase's CLI process before returning.
|
|
6915
|
+
Stim never installs eas-cli during cache lookup. A custom Windows batch
|
|
6916
|
+
launcher needs a project eas-cli installation so Stim can stop Node directly.
|
|
6917
|
+
|
|
6444
6918
|
Stim never configures a provider and never suggests changing one: a
|
|
6445
6919
|
project without one is a perfectly ordinary local-only project (doctor does
|
|
6446
6920
|
not ask for one either -- a provider only serves builds run OUTSIDE Stim).
|
|
@@ -6935,6 +7409,8 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
6935
7409
|
install requires an exclusive claim. It releases shared before waiting for
|
|
6936
7410
|
exclusive, then checks the checkout again before fetching or writing. Every
|
|
6937
7411
|
copy holds shared, so no copy reads a node_modules a refresh is rewriting.
|
|
7412
|
+
Each copy also holds an exclusive claim on its target, so concurrent warms
|
|
7413
|
+
into the same linked worktree wait instead of racing destination checks.
|
|
6938
7414
|
The lock is keyed on the repository root, so
|
|
6939
7415
|
two apps of one monorepo share it. It is the same ownership claim the build
|
|
6940
7416
|
locks take: the holder's process IDENTITY decides, so a holder that dies frees
|
|
@@ -6964,9 +7440,10 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
6964
7440
|
paths eligible under the source checkout's Git ignore rules, including .env
|
|
6965
7441
|
and local configuration. The source's nonempty
|
|
6966
7442
|
.worktreeexclude replaces its resolved worktree.exclude setting. Nested
|
|
6967
|
-
registered worktrees, .DS_Store, .DerivedData, .idea, .jj,
|
|
6968
|
-
android/build/generated/autolinking caches are excluded,
|
|
6969
|
-
newly copied directories
|
|
7443
|
+
registered worktrees, .DS_Store, .DerivedData, .idea, .jj, a project-local
|
|
7444
|
+
.pnpm-store, and android/build/generated/autolinking caches are excluded,
|
|
7445
|
+
including inside newly copied directories; pnpm refills its store from the
|
|
7446
|
+
network or its global store. Gradle regenerates autolinking
|
|
6970
7447
|
for the destination checkout on its next build. Warm also skips paths
|
|
6971
7448
|
overlapping a nested destination worktree or below a symlink ancestor.
|
|
6972
7449
|
Tracked .idea settings come from Git and stay untouched by warm.
|
|
@@ -7015,8 +7492,9 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7015
7492
|
filled in. Warm does not copy tracked changes, switch branches, or build,
|
|
7016
7493
|
and it installs dependencies only under \`--refresh\`, in the source checkout. stdout stays empty; stderr reports copied, kept,
|
|
7017
7494
|
and failed entry counts. A copy failure exits 1 and reports incomplete;
|
|
7018
|
-
|
|
7019
|
-
|
|
7495
|
+
completed entries remain. After its child drains, warm removes its own
|
|
7496
|
+
failed partial entry so a retry can copy it again. Unverifiable child cleanup
|
|
7497
|
+
leaves that entry and its ownership claims in place with recovery instructions.
|
|
7020
7498
|
A completed copy is not proof that dependencies match this branch. Follow
|
|
7021
7499
|
any lockfile remedies before building, and install missing dependencies
|
|
7022
7500
|
with the project's package manager when the source has none to copy.
|
|
@@ -7105,7 +7583,8 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7105
7583
|
body: () => ` \`android --device [serial]\` installs and launches on a physical device
|
|
7106
7584
|
connected to this machine instead of this workspace's owned emulator. With
|
|
7107
7585
|
no serial it takes the first device it can lease (\`guide lifecycle lease\`).
|
|
7108
|
-
It cannot be combined with --remote
|
|
7586
|
+
It ignores android.remote and cannot be combined with --remote other than
|
|
7587
|
+
--remote local.
|
|
7109
7588
|
|
|
7110
7589
|
A \`--device\` run LEASES the device from just after the build until it
|
|
7111
7590
|
exits, so a second workspace cannot install over it mid-run
|
|
@@ -7121,7 +7600,8 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7121
7600
|
\`android --device\` selects a connected phone: with no UDID it takes the
|
|
7122
7601
|
first device it can lease (\`guide lifecycle lease\`), and an iPhone
|
|
7123
7602
|
that is unpaired or has Developer Mode off is refused with the fix. It
|
|
7124
|
-
cannot be combined with --remote
|
|
7603
|
+
ignores ios.remote, cannot be combined with --remote other than --remote
|
|
7604
|
+
local, and never creates, boots, or deletes
|
|
7125
7605
|
hardware -- there is no capacity check, no simulator creation, no boot wait,
|
|
7126
7606
|
and no owned-device registry entry. Like
|
|
7127
7607
|
\`android --device\`, it leases the phone for the run
|
|
@@ -7183,6 +7663,33 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7183
7663
|
a CACHED app falls back to a full build; on a freshly built one it exits on
|
|
7184
7664
|
its own code, because building again would produce the same app.
|
|
7185
7665
|
|
|
7666
|
+
PROVISIONING A NEW PHONE is a separate, explicit step, never part of a
|
|
7667
|
+
build: \`stim device provision ios [udid]\` finds the Xcode project the way
|
|
7668
|
+
\`ios\` does (ios/ for React Native and Expo, the app's own .xcodeproj or
|
|
7669
|
+
.xcworkspace for a native app), reads every target of the scheme that is
|
|
7670
|
+
signed with a profile, on any platform (\`--scheme\`, \`--configuration\`,
|
|
7671
|
+
or ios.scheme / ios.configuration), prints the team, the phone and each
|
|
7672
|
+
bundle id whose Development profile it would create or refresh, and asks
|
|
7673
|
+
[y/N]; Ctrl+C or end of input is no, and \`--yes\` replaces the prompt
|
|
7674
|
+
without a terminal. It then runs xcodebuild -allowProvisioningUpdates
|
|
7675
|
+
-allowProvisioningDeviceRegistration for that phone in a throwaway
|
|
7676
|
+
DerivedData and stops it at the first build task, which xcodebuild starts
|
|
7677
|
+
only once planning has resolved signing, before compilation. A native app
|
|
7678
|
+
with Swift packages uses the packages \`ios\` already resolved, with
|
|
7679
|
+
automatic package resolution off, and refuses until \`stim ios\` has
|
|
7680
|
+
resolved them. That stop and a Ctrl+C send xcodebuild
|
|
7681
|
+
SIGINT, then SIGTERM after 10s and SIGKILL 5s later; a SIGTERM sent to Stim,
|
|
7682
|
+
and the 15-minute timeout, send SIGTERM, then SIGKILL after 5s. A second
|
|
7683
|
+
signal kills xcodebuild before Stim exits. The DerivedData is always
|
|
7684
|
+
removed. It authenticates with the Xcode account, or with
|
|
7685
|
+
the App Store Connect API key in ios.appStoreConnectKeyPath,
|
|
7686
|
+
ios.appStoreConnectKeyId and ios.appStoreConnectIssuerId (or
|
|
7687
|
+
STIM_ASC_KEY_PATH, STIM_ASC_KEY_ID, STIM_ASC_ISSUER_ID, each overriding its
|
|
7688
|
+
own setting); it never reads the key and never prints its path. It reports
|
|
7689
|
+
the installed profile and any new keychain identity, and on a failure or
|
|
7690
|
+
interrupt it still reports what had already changed. It changes the team's
|
|
7691
|
+
developer account: agents run it only on the user's explicit go-ahead.
|
|
7692
|
+
|
|
7186
7693
|
DEBUG REACHES METRO OVER THE LAN, because a phone shares no loopback with
|
|
7187
7694
|
the host and USB carries no reverse forward. Stim picks a non-internal IPv4
|
|
7188
7695
|
address (en0 first, RN's own order from react-native-xcode.sh), gates it as
|
|
@@ -7558,11 +8065,16 @@ scoped STIM_HOME homes unless STIM_MAINTENANCE is explicit, so a scratch home
|
|
|
7558
8065
|
or CI run never deletes on its own.
|
|
7559
8066
|
Commands trigger a detached pass when a check is due: disk and memory pressure
|
|
7560
8067
|
(every minute), directory sizes (hourly), finished worktrees (every 15
|
|
7561
|
-
minutes) and the age sweep (daily). guide, settings
|
|
7562
|
-
it; gc --delete
|
|
8068
|
+
minutes) and the age sweep (daily). guide, settings, help and every gc
|
|
8069
|
+
invocation do not trigger it; gc without --delete prints the maintenance plan
|
|
8070
|
+
itself.
|
|
8071
|
+
status --watch and every running dev server supervisor also trigger checks
|
|
8072
|
+
each minute, so the disk check runs while no command does.
|
|
7563
8073
|
Size, worktree and sweep checks defer under high load. Attempts back off for at
|
|
7564
8074
|
least one minute. Measured directories are workspace build outputs and Stim's
|
|
7565
|
-
shared native, Metro, ccache, Swift compilation and registered caches.
|
|
8075
|
+
shared native, Metro, ccache, Swift compilation and registered caches. The size
|
|
8076
|
+
check also records the disk of each owned and parked simulator and emulator
|
|
8077
|
+
(category owned-devices); status prints the total as "owned devices".
|
|
7566
8078
|
Pressure checks read free disk on the Stim home, projects and worker root
|
|
7567
8079
|
volumes. On macOS the memory signal is the sysctl pressure level, with no
|
|
7568
8080
|
signal if sysctl fails. Other platforms use os.freemem(); macOS never falls
|
|
@@ -7580,20 +8092,83 @@ In on mode a pass runs, cheapest to rebuild first:
|
|
|
7580
8092
|
maintenance.capTargetPercent of caches.buildCacheMaxGb or
|
|
7581
8093
|
caches.metroCacheMaxGb, and entries unused for olderThanDays
|
|
7582
8094
|
4. the Swift compilation cache, emptied whole, only below
|
|
7583
|
-
budget.hardFloorDiskGb and
|
|
8095
|
+
budget.hardFloorDiskGb, and kept while an iOS build holds its shared
|
|
8096
|
+
claim (taken for each xcodebuild run that compiles with it) or that
|
|
8097
|
+
claim is unresolved; the emptying holds the exclusive claim
|
|
7584
8098
|
5. linked worktrees whose branch or pull request finished (gc's finished
|
|
7585
8099
|
worktree rules and gc.worktreeGraceMinutes; maintenance.removeFinishedWorktrees)
|
|
8100
|
+
6. owned simulators and emulators of a finished worktree that is kept, such
|
|
8101
|
+
as a dirty one (not one locked with git worktree lock), once it finished
|
|
8102
|
+
and was idle for gc.worktreeGraceMinutes (at least protectRecentHours),
|
|
8103
|
+
and of any
|
|
8104
|
+
workspace idle for maintenance.deviceIdleDays (3; 0 turns it off) in the
|
|
8105
|
+
age sweep. Devices are recreated on the next run.
|
|
7586
8106
|
Disk-driven steps stop once free space is back above the floor. Kept for
|
|
7587
8107
|
every pass: a workspace that is in use, holds a lock, was used within
|
|
7588
8108
|
maintenance.protectRecentHours, is pinned with maintenance.keep, or is the
|
|
7589
8109
|
workspace of the command that started the pass; cache entries used within
|
|
7590
8110
|
protectRecentHours, named by a project's last builds, a parked device or a
|
|
7591
8111
|
live build lock, or in a Metro store with a running or unverifiable dev
|
|
7592
|
-
server. Anything the pass cannot verify is kept. A
|
|
8112
|
+
server. Anything the pass cannot verify is kept. A device is deleted only when
|
|
8113
|
+
its workspace is idle: no dev server, native run, build, lease, managed lock,
|
|
8114
|
+
driven or busy device, and no recorded use within the window. Below disk
|
|
8115
|
+
pressure level 3 a pass never stops a dev server or watchman; removing a
|
|
7593
8116
|
finished worktree or orphaned directory does tear down that workspace's own
|
|
7594
8117
|
dev server, owned devices and Chrome profile, as gc --delete does. ccache evicts by itself under
|
|
7595
8118
|
caches.ccacheMaxGb.
|
|
7596
8119
|
|
|
8120
|
+
DISK PRESSURE LEVELS
|
|
8121
|
+
Level 1 is free disk under the floor above (budget.minFreeDiskGb, 20 GB).
|
|
8122
|
+
Level 2 is under maintenance.urgentFreeDiskGb (12), and level 3 is under
|
|
8123
|
+
maintenance.criticalFreeDiskGb (6) or budget.hardFloorDiskGb, where builds
|
|
8124
|
+
refuse. When level 1 leaves free disk under the floor, a pass goes on with
|
|
8125
|
+
level 2, which runs until free disk is back above the floor; level 3 runs
|
|
8126
|
+
only while free disk stays under the level 3 floor. At levels 2 and 3 the
|
|
8127
|
+
protection window is maintenance.pressureProtectMinutes (10) instead of
|
|
8128
|
+
protectRecentHours. Each step re-measures first and stops once free disk is
|
|
8129
|
+
back above its level's floor, cheapest to rebuild first.
|
|
8130
|
+
Level 2:
|
|
8131
|
+
1. build outputs of workspaces unused for the short window
|
|
8132
|
+
2. parked simulators and emulators, deleted through centralized teardown
|
|
8133
|
+
3. build directories of idle worktrees: ios/build, android/app/build,
|
|
8134
|
+
android/build, android/.gradle and .build, at a project root, the
|
|
8135
|
+
worktree root, or apps/* and packages/*
|
|
8136
|
+
4. owned simulators and emulators of workspaces idle for the short window
|
|
8137
|
+
5. Stim temp directories and xctrace recordings in TMPDIR unmodified for
|
|
8138
|
+
24 hours, with gc --delete's checks (see stim guide cleanup gc)
|
|
8139
|
+
Level 3:
|
|
8140
|
+
1. the Swift compilation cache, emptied whole under the same build rule;
|
|
8141
|
+
when a build keeps it, the last pass's blocked reasons name its size
|
|
8142
|
+
and the build
|
|
8143
|
+
2. finished worktrees, and clean, pushed worktrees with no commits of
|
|
8144
|
+
their own beyond the default branch, with the short window as grace
|
|
8145
|
+
period (maintenance.removeFinishedWorktrees still applies)
|
|
8146
|
+
3. workspaces whose dev server runs but that are otherwise inactive for
|
|
8147
|
+
the short window: their dev server stops and their owned simulators
|
|
8148
|
+
and emulators are deleted
|
|
8149
|
+
4. node_modules and ios/Pods at the root or a project root of idle linked
|
|
8150
|
+
worktrees, never the source checkout
|
|
8151
|
+
5. idle Gradle and Kotlin daemons, stopped as gc --delete --cache
|
|
8152
|
+
gradle-daemons stops them (never during a Stim build, never a busy or
|
|
8153
|
+
unverified one, never with STIM_HOME set), only when every Gradle
|
|
8154
|
+
process that keeps step 6 from running is such a daemon; the pass
|
|
8155
|
+
waits up to 3 seconds for them to exit
|
|
8156
|
+
6. Gradle version caches and wrapper distributions no registered project
|
|
8157
|
+
pins, once unmodified for maintenance.gradleVersionIdleDays days (7;
|
|
8158
|
+
0 turns steps 5 and 6 off), with the same checks as gc --cache
|
|
8159
|
+
gradle-versions, run again after step 5 so a daemon that did not exit
|
|
8160
|
+
still keeps them
|
|
8161
|
+
A directory is cleared only when it is a real directory inside its
|
|
8162
|
+
worktree, git tracks nothing in it, its worktree is not in use, holds no
|
|
8163
|
+
lock or build and is not pinned, and nothing under it, nor the worktree's
|
|
8164
|
+
git index, HEAD or Stim state, changed within the short window. A dirty or
|
|
8165
|
+
unpushed worktree can still be stopped and have these directories cleared;
|
|
8166
|
+
only its removal is refused. Caches of other tools (pnpm and npm stores,
|
|
8167
|
+
CocoaPods, SwiftPM, the shared Gradle caches) are never deleted.
|
|
8168
|
+
status shows the level and, at level 3, the shortfall in the last pass;
|
|
8169
|
+
every command prints one stderr line while the last check, at most 10
|
|
8170
|
+
minutes old, measured level 3.
|
|
8171
|
+
|
|
7597
8172
|
stim status last checks, plan and running pass
|
|
7598
8173
|
stim status --json maintenance observations and recent records
|
|
7599
8174
|
stim logs --source maintenance this workspace's maintenance records
|
|
@@ -7608,6 +8183,9 @@ In report mode actions and explaining skips are logged only when newly
|
|
|
7608
8183
|
planned; in on mode every action taken, failure and explaining skip is logged
|
|
7609
8184
|
with its bytes, and a pass record carries the bytes freed. Removal of a
|
|
7610
8185
|
worktree or orphaned directory is logged to the machine log only.
|
|
8186
|
+
An iOS build that fails on a corrupt compilation cache logs the emptying,
|
|
8187
|
+
or why Stim left the cache alone, with trigger "ios build", in every mode;
|
|
8188
|
+
see \`stim guide errors STIM_COMPILATION_CACHE_CORRUPT\`.
|
|
7611
8189
|
maintenance.logChecks enables debug observations; default false.
|
|
7612
8190
|
status and doctor report invalid settings and unresolved claims with a removal
|
|
7613
8191
|
command to run only after confirming the holder is gone. Invalid cache caps
|
|
@@ -7615,6 +8193,10 @@ fall back to their own defaults; invalid maintenance settings disable passes.
|
|
|
7615
8193
|
Pin a workspace with \`stim settings set maintenance.keep true\` in its project.
|
|
7616
8194
|
The run claim serializes passes with gc --delete; gc refuses a held claim
|
|
7617
8195
|
with the holder and recovery guidance instead of waiting.
|
|
8196
|
+
Each pass keeps a 1 MiB file, maintenance/disk-reserve. When taking the run
|
|
8197
|
+
claim fails with ENOSPC or EDQUOT, the pass deletes it and retries once, so a
|
|
8198
|
+
pass starts at zero free disk as long as an earlier pass left the reserve; the
|
|
8199
|
+
pass writes it again at its end.
|
|
7618
8200
|
|
|
7619
8201
|
CLEANUP AND DISK
|
|
7620
8202
|
|
|
@@ -7630,15 +8212,22 @@ See stim guide logs for AGENT_DEVICE_STATE_DIR examples.
|
|
|
7630
8212
|
WHAT RECLAIMS AN OWNED DEVICE
|
|
7631
8213
|
stim worktree remove parks eligible owned simulators and emulators
|
|
7632
8214
|
(\`guide lifecycle pool\`); deletes them when
|
|
7633
|
-
parking is disabled
|
|
8215
|
+
parking is disabled, their setup cannot be
|
|
8216
|
+
verified, or free disk is at pressure level 2 or 3
|
|
7634
8217
|
stim gc --delete sweeps devices this Stim home created that no project
|
|
7635
8218
|
references (\`guide cleanup gc\`), clears
|
|
7636
8219
|
verified parked simulators and emulators, and
|
|
7637
|
-
runs \`stim worktree remove\` on every clean
|
|
7638
|
-
|
|
8220
|
+
runs \`stim worktree remove\` on every clean
|
|
8221
|
+
linked worktree of a registered repository whose
|
|
8222
|
+
branch is merged,
|
|
7639
8223
|
or whose pull request was merged or closed, and
|
|
7640
8224
|
that shows no activity within
|
|
7641
|
-
gc.worktreeGraceMinutes
|
|
8225
|
+
gc.worktreeGraceMinutes, and deletes the owned
|
|
8226
|
+
devices of a finished worktree it keeps (dirty,
|
|
8227
|
+
unpushed, locked) when its workspace is idle for
|
|
8228
|
+
that grace and not pinned by maintenance.keep
|
|
8229
|
+
automatic maintenance deletes the owned devices of idle workspaces
|
|
8230
|
+
(MAINTENANCE above)
|
|
7642
8231
|
stim gc --delete --older-than <days>
|
|
7643
8232
|
also reaps the device of a workspace no Stim
|
|
7644
8233
|
command has used in that long, even though the
|
|
@@ -7716,7 +8305,7 @@ to stats.json.corrupt-<unix ms> and starts a new one.`,
|
|
|
7716
8305
|
Archived log subscriptions send retained records, then logs-ended.
|
|
7717
8306
|
Archived frame subscriptions need at and cannot be physical or go live.
|
|
7718
8307
|
Replay ranges report recording disabled.
|
|
7719
|
-
Reads stay on this
|
|
8308
|
+
Reads stay on this machine.
|
|
7720
8309
|
An updated server is required; older servers refuse with bad-request when
|
|
7721
8310
|
workspace is omitted. There is no CLI archive log flag.
|
|
7722
8311
|
archive.enabled defaults true and accepts every settings layer. STIM_HOME
|
|
@@ -7789,6 +8378,69 @@ caches, never changes actionable, and --delete and --older-than never select
|
|
|
7789
8378
|
it. Any --cache scope, including all, omits measurement and reports
|
|
7790
8379
|
sections.swiftpmCache: null. Only stats and unscoped gc measure it.
|
|
7791
8380
|
|
|
8381
|
+
GRADLE VERSIONS
|
|
8382
|
+
\`stim gc --cache gradle-versions\` lists, and with --delete removes, the
|
|
8383
|
+
caches/<version> and wrapper/dists/gradle-<version>-* directories under
|
|
8384
|
+
GRADLE_USER_HOME of each Gradle version no registered project pins, read from
|
|
8385
|
+
the wrapper of each project's Android Gradle root and root. Nothing is deleted
|
|
8386
|
+
while a process that may be Gradle using this home runs: a Gradle main
|
|
8387
|
+
class, a Gradle wrapper or distribution jar, or a java process naming a path
|
|
8388
|
+
under the home, unless it names no such path and every gradle.user.home or
|
|
8389
|
+
-g it names is an existing Gradle home elsewhere, while ps fails, while no Stim config
|
|
8390
|
+
exists, while a registered project is missing or its pin cannot be read,
|
|
8391
|
+
while a Gradle directory cannot be listed, or while caches, wrapper or
|
|
8392
|
+
wrapper/dists is a symlink or resolves outside the home;
|
|
8393
|
+
sections.gradleVersions.blocked names the reason. A version is also kept
|
|
8394
|
+
when one of its paths is not a plain directory inside the home, when an
|
|
8395
|
+
entry under it cannot be listed or stat'd, when it holds more than 500000
|
|
8396
|
+
entries, or, with --older-than <days>, when anything under it changed within
|
|
8397
|
+
that many days.
|
|
8398
|
+
Right before removal gc lists processes and reads pins again, then renames
|
|
8399
|
+
each directory to a .stim-delete-* sibling and deletes it. A later gc
|
|
8400
|
+
--delete --cache gradle-versions finishes any .stim-delete-* left by a failed
|
|
8401
|
+
removal, even while the versions are blocked (not while the home is outside
|
|
8402
|
+
a scoped STIM_HOME or its layout is unsafe), since nothing uses those
|
|
8403
|
+
directories, and reports it again when that fails; plain gc --delete and
|
|
8404
|
+
automatic maintenance never touch them. modules-2, build-cache-1, jdks and
|
|
8405
|
+
other shared Gradle caches are never deleted, and --cache all never includes these versions.
|
|
8406
|
+
With STIM_HOME set, gc deletes nothing in a Gradle home outside it. At disk
|
|
8407
|
+
pressure level 3 automatic maintenance first stops the idle Gradle and Kotlin
|
|
8408
|
+
daemons gc --delete --cache gradle-daemons would stop, only when every Gradle
|
|
8409
|
+
process that keeps a version is such a daemon, then does the same for
|
|
8410
|
+
versions unmodified for maintenance.gradleVersionIdleDays days (7; 0 turns
|
|
8411
|
+
both off). A manual gc --delete --cache gradle-versions never stops daemons.
|
|
8412
|
+
|
|
8413
|
+
OTHER TOOLS' MACHINE-WIDE CACHES (REPORT ONLY)
|
|
8414
|
+
Unscoped gc also reports large caches other tools keep for the whole machine,
|
|
8415
|
+
each with its size and the owning tool's own remedy:
|
|
8416
|
+
- Gradle version caches and wrapper dists under GRADLE_USER_HOME (default
|
|
8417
|
+
~/.gradle) for versions no registered project pins in the
|
|
8418
|
+
gradle/wrapper/gradle-wrapper.properties of its Android Gradle root
|
|
8419
|
+
(android.gradleRoot, default android, relative to the app, inside the
|
|
8420
|
+
repository; a custom root must hold settings.gradle and the module's build
|
|
8421
|
+
script) or of the project root, and caches/modules-2. A registered project
|
|
8422
|
+
that is missing, whose settings cannot be resolved, or whose wrapper cannot
|
|
8423
|
+
be read or names no Gradle version is named, since it may still pin a
|
|
8424
|
+
listed version; every version a readable wrapper of it pins still counts as
|
|
8425
|
+
pinned. A directory that cannot be listed adds a notice and marks the
|
|
8426
|
+
section incomplete.
|
|
8427
|
+
Gradle removes version caches and modules-2 entries unused for 30 days on
|
|
8428
|
+
its own. The remedy for a version is stim gc --delete --cache
|
|
8429
|
+
gradle-versions (see GRADLE VERSIONS); modules-2 stays report only.
|
|
8430
|
+
- iOS simulator runtimes with their simulator count. Only a deletable
|
|
8431
|
+
runtime no simulator uses gets the remedy xcrun simctl runtime delete <id>.
|
|
8432
|
+
- Xcode device support entries under ~/Library/Developer/Xcode/*DeviceSupport.
|
|
8433
|
+
Xcode copies an entry again when that device next connects.
|
|
8434
|
+
- agent-device runner builds grouped by agent-device and Xcode build version,
|
|
8435
|
+
compared with the installed agent-device and Xcode. agent-device has no
|
|
8436
|
+
prune command; remove an entry not in use by hand.
|
|
8437
|
+
$STIM_HOME/machine-cache-usage.json caches the sizes, simulator runtimes and
|
|
8438
|
+
tool versions for 10 minutes and measures again when the measured
|
|
8439
|
+
directories change. Stim never deletes any of these. They are never in
|
|
8440
|
+
caches, never change actionable, and --delete and --older-than never select
|
|
8441
|
+
them. Any --cache scope omits measurement and reports sections.machineCaches:
|
|
8442
|
+
null.
|
|
8443
|
+
|
|
7792
8444
|
LINKED WORKTREES
|
|
7793
8445
|
\`stim worktree remove\` works with any linked worktree, warmed or not.
|
|
7794
8446
|
Git registration identifies the worktree; a Stim registry entry is not
|
|
@@ -7819,20 +8471,43 @@ IN USE
|
|
|
7819
8471
|
existence cannot be read (a permission error) is never treated as deleted.
|
|
7820
8472
|
|
|
7821
8473
|
SWEEPING FINISHED WORKTREES
|
|
7822
|
-
Every \`gc\` without --cache looks at every registered project root
|
|
7823
|
-
every workspace.json root,
|
|
8474
|
+
Every \`gc\` without --cache looks at every registered project root,
|
|
8475
|
+
every workspace.json root, and every linked worktree \`git worktree list\`
|
|
8476
|
+
shows for a registered project's repository, whether or not a stim command
|
|
8477
|
+
ever ran in it. It groups them by git worktree and reports each linked
|
|
7824
8478
|
worktree with the reason it is removed or kept. A worktree is finished when
|
|
7825
8479
|
its branch is merged into the default branch, or its pull request was
|
|
7826
8480
|
merged or closed (PULL REQUESTS below). \`--worktrees\` also removes
|
|
7827
8481
|
one that is idle: no recorded use for --older-than days, 7 without it; a
|
|
7828
|
-
worktree whose last use is unknown is kept
|
|
7829
|
-
|
|
8482
|
+
worktree whose last use is unknown is kept, unless it has no commits of its
|
|
8483
|
+
own beyond the default branch (NO COMMITS OF ITS OWN below). Both need the
|
|
8484
|
+
same clean state;
|
|
8485
|
+
a worktree is kept when it is the source checkout, bare, locked, holds
|
|
8486
|
+
another worktree (worktree remove refuses it too), in use,
|
|
7830
8487
|
dirty (untracked files count; pod install churn and
|
|
7831
8488
|
watchman's untracked \`.watchman-cookie-*\` files alone do not), unpushed
|
|
7832
8489
|
(commits no remote-tracking ref or other local branch reaches), or has
|
|
7833
8490
|
initialized submodules. Without --worktrees, the report leaves out the
|
|
7834
8491
|
source checkout and roots outside git.
|
|
7835
8492
|
|
|
8493
|
+
Each worktree line also shows its in-tree build state: the size of the
|
|
8494
|
+
build and dependency directories maintenance clears (DISK PRESSURE LEVELS
|
|
8495
|
+
above) and a root .pnpm-store, largest first (APFS clones count in full).
|
|
8496
|
+
A size comes from the disk-usage cache while it is under an hour old and
|
|
8497
|
+
no entry was added to or removed from its directory since (a build that
|
|
8498
|
+
only grows files deeper inside shows within the hour); otherwise gc runs
|
|
8499
|
+
one du per directory, 4 at once, 10 seconds each, and a directory du did
|
|
8500
|
+
not finish shows "size unknown". du counts hard links shared between two
|
|
8501
|
+
directories in both. gc never deletes them on their own;
|
|
8502
|
+
the JSON field is buildState. Only directories of this worktree count,
|
|
8503
|
+
not those of a worktree nested inside it.
|
|
8504
|
+
|
|
8505
|
+
A directory directly under a registered repository's .worktrees/ that
|
|
8506
|
+
\`git worktree list\` does not show and that no git knows (no .git, or a
|
|
8507
|
+
.git file whose gitdir is gone, as after a prune) is listed under "Directories under .worktrees that git does
|
|
8508
|
+
not list as worktrees" with its size and the rm -rf command, and never
|
|
8509
|
+
removed: gc cannot check it for uncommitted work. Look through it first.
|
|
8510
|
+
|
|
7836
8511
|
IN USE means its dev server supervisor runs, a stim ios, android or stop
|
|
7837
8512
|
run holds its native-run lock, a live build lock or slot names it, a
|
|
7838
8513
|
managed tunnel or remote lock is held, an owned simulator or emulator of
|
|
@@ -7854,9 +8529,32 @@ SWEEPING FINISHED WORKTREES
|
|
|
7854
8529
|
activity cannot be read, the worktree is kept (reason activity-unknown).
|
|
7855
8530
|
0 turns the grace period off.
|
|
7856
8531
|
|
|
8532
|
+
FRESH STATE: \`gc --delete\` and the maintenance worktree check fetch the
|
|
8533
|
+
default branch and ask gh as MERGED and PULL REQUESTS below describe. The
|
|
8534
|
+
worktree check runs in the background when a stim command starts a
|
|
8535
|
+
maintenance pass that has it due, every maintenance.worktreeCheckMinutes;
|
|
8536
|
+
plain gc never starts one. It writes each pull request lookup into the
|
|
8537
|
+
cache \`status --watch\` also writes. A report without --delete runs no
|
|
8538
|
+
fetch and no gh: it judges merges from the existing origin/<default> ref and
|
|
8539
|
+
takes a pull request from that cache when it records the worktree's current
|
|
8540
|
+
branch and HEAD. Both count as fresh while they are younger than twice the
|
|
8541
|
+
worktree check interval, and never less than 10 minutes. A merge found
|
|
8542
|
+
against the existing ref stays true as the default branch moves on, so a
|
|
8543
|
+
report calls a worktree removable only on facts fresh state keeps, with
|
|
8544
|
+
three exceptions: a force-push that dropped the merge from the default
|
|
8545
|
+
branch, a pull request reopened since the lookup, and the grace period of a
|
|
8546
|
+
pull request merged or closed after its merge commit was made. A kept worktree whose
|
|
8547
|
+
verdict fresher state could change says "merge state not refreshed", and
|
|
8548
|
+
its reason not-merged becomes merge-unknown. With maintenance.mode off or
|
|
8549
|
+
maintenance.removeFinishedWorktrees false the check never runs, and only
|
|
8550
|
+
\`gc --delete\` refreshes. \`gc --delete\` always collects fresh state
|
|
8551
|
+
before it removes anything; \`stim worktree remove\` run from a report
|
|
8552
|
+
checks only for uncommitted and unpushed work.
|
|
8553
|
+
|
|
7857
8554
|
MERGED means, with the default branch taken from origin/HEAD, after a
|
|
7858
8555
|
\`git fetch origin <default>\` per repository (30s timeout, no credential
|
|
7859
|
-
prompt; skipped when that checkout fetched in the last 10 minutes
|
|
8556
|
+
prompt; skipped when that checkout fetched in the last 10 minutes; FRESH
|
|
8557
|
+
STATE above for a report):
|
|
7860
8558
|
- HEAD is reachable from origin/<default> through a merge commit, and the
|
|
7861
8559
|
branch's reflog shows a commit made on it that HEAD contains. A branch
|
|
7862
8560
|
with no commit of its own -- fresh, cut from another branch, or reset
|
|
@@ -7877,8 +8575,23 @@ SWEEPING FINISHED WORKTREES
|
|
|
7877
8575
|
not block removal, because their change is on the default branch, and the
|
|
7878
8576
|
branch is kept.
|
|
7879
8577
|
|
|
7880
|
-
|
|
7881
|
-
|
|
8578
|
+
NO COMMITS OF ITS OWN: a worktree whose HEAD the default branch contains
|
|
8579
|
+
and whose branch has no commit made on it (fresh, cut from another
|
|
8580
|
+
branch, or reset onto one; the MERGED rule above) holds nothing git would
|
|
8581
|
+
lose, but looks the same as one just made by git worktree add. Plain gc keeps
|
|
8582
|
+
it (reason not-merged, "no commits of its own beyond origin/<default>").
|
|
8583
|
+
\`--worktrees\` removes it when idle: by its recorded use when there is
|
|
8584
|
+
one, else by the RECENT ACTIVITY sources above being older than
|
|
8585
|
+
--older-than days (reason recently-used while they are newer, and
|
|
8586
|
+
last-use-unknown when they cannot be read). Automatic maintenance removes it
|
|
8587
|
+
only at disk pressure level 3, once that activity is older than
|
|
8588
|
+
maintenance.pressureProtectMinutes and at least 5 minutes old, whatever
|
|
8589
|
+
the setting; unreadable activity keeps it. Removal re-checks, under the removal
|
|
8590
|
+
locks, that HEAD did not move and the worktree is still idle, and
|
|
8591
|
+
\`stim worktree remove\` still refuses dirty or unpushed work.
|
|
8592
|
+
|
|
8593
|
+
PULL REQUESTS: with fresh state, gc runs one \`gh api graphql\` query per
|
|
8594
|
+
repository that asks for the 20 newest pull requests of each linked worktree's branch, as
|
|
7882
8595
|
\`gh pr list --head <branch> --state all\` would, and for each worktree
|
|
7883
8596
|
takes the pull request whose head is HEAD, else one whose head contains
|
|
7884
8597
|
HEAD. A pull request whose head HEAD is past ("PR #12 merged, and HEAD has
|
|
@@ -7896,14 +8609,15 @@ SWEEPING FINISHED WORKTREES
|
|
|
7896
8609
|
not looked up. \`stim worktree remove\` makes the same check when
|
|
7897
8610
|
local-only commits alone would refuse the removal, and accepts a merged
|
|
7898
8611
|
pull request whose head is or contains HEAD.
|
|
7899
|
-
stim gc # report merged worktrees
|
|
7900
|
-
stim gc --delete # remove them
|
|
8612
|
+
stim gc # report merged worktrees from local state
|
|
8613
|
+
stim gc --delete # refresh, then remove them
|
|
7901
8614
|
stim gc --delete --worktrees --older-than 3 # also the clean idle ones
|
|
7902
8615
|
--cache with --worktrees is refused with STIM_BAD_ARG; run them separately.
|
|
7903
8616
|
With --delete it runs the \`stim worktree remove\` pipeline, never --force,
|
|
7904
8617
|
on each removable worktree. That pipeline re-inspects the worktree and
|
|
7905
8618
|
re-checks use and recent activity under the removal locks, and idleness
|
|
7906
|
-
for an idle worktree
|
|
8619
|
+
for an idle worktree, an unchanged HEAD for a merged one, or both for one
|
|
8620
|
+
with no commits of its own, then parks
|
|
7907
8621
|
devices through the same teardown and handles the
|
|
7908
8622
|
branch exactly as a manual \`stim worktree remove\`, which keeps the
|
|
7909
8623
|
checkout when its HEAD moves while devices are reclaimed. A worktree that
|
|
@@ -7935,9 +8649,27 @@ ORPHANED WORKSPACE DIRECTORIES
|
|
|
7935
8649
|
it. A directory with a missing or unparseable workspace.json, or a root on
|
|
7936
8650
|
an unmounted volume, is reported under Skipped and never deleted.
|
|
7937
8651
|
|
|
8652
|
+
TMPDIR LEFTOVERS
|
|
8653
|
+
\`gc\` without --cache reports recognized entries directly in the user's TMPDIR
|
|
8654
|
+
under "TMPDIR leftovers", with their count, size and a remedy: Stim temp
|
|
8655
|
+
directories (stim-claim-*, stim-host-*, stim-fakehome-*,
|
|
8656
|
+
stim-hosted-macos-*, stim-server-*, stim-ws-*), xctrace recordings
|
|
8657
|
+
(instruments*.ktrace) and Jest's jest_<uid in base 36> cache. \`gc --delete\` checks
|
|
8658
|
+
them again and deletes a Stim temp directory or recording only when nothing
|
|
8659
|
+
in it changed for 24 hours. It keeps a Stim temp directory that contains or
|
|
8660
|
+
sits inside a registered project, holds a live or unverifiable ownership
|
|
8661
|
+
claim or a .lock directory that is not a claim set, or cannot be listed. It
|
|
8662
|
+
keeps a recording that cannot be read, and every recording while an xctrace
|
|
8663
|
+
or Instruments process runs or the process list cannot be read. Jest's cache and every other entry
|
|
8664
|
+
are never deleted. gc never follows a symlink and never acts outside TMPDIR.
|
|
8665
|
+
With STIM_HOME set it neither reports nor deletes them, because TMPDIR is
|
|
8666
|
+
shared by every Stim home. Automatic maintenance runs the same deletion at disk pressure
|
|
8667
|
+
level 2.
|
|
8668
|
+
|
|
7938
8669
|
STALE STATUS CACHE ENTRIES
|
|
7939
8670
|
\`stim status\` caches each folder's size under $STIM_HOME/disk-usage and
|
|
7940
|
-
each worktree's pull request under $STIM_HOME/pull-requests
|
|
8671
|
+
each worktree's pull request under $STIM_HOME/pull-requests, which the
|
|
8672
|
+
maintenance worktree check and \`gc --delete\` also write. \`worktree
|
|
7941
8673
|
remove\` drops the entries of the worktree it removed (its checkout,
|
|
7942
8674
|
node_modules and workspace folder, and its pull request), not the size
|
|
7943
8675
|
entries of its owned devices' data folders. \`gc\` reports the
|
|
@@ -8037,6 +8769,12 @@ run drops the dead config ENTRIES those projects left behind and frees their
|
|
|
8037
8769
|
Metro ports. \`stim gc --json\` prints the same report as one payload
|
|
8038
8770
|
(\`guide facts gc\`); show the user its sections before \`gc --delete\`.
|
|
8039
8771
|
|
|
8772
|
+
Ctrl-C stops pending GC actions and drains verified owned children before exiting
|
|
8773
|
+
130. Completed actions remain applied. Unverifiable child cleanup keeps its
|
|
8774
|
+
ownership claims and prints STIM_CLAIM_UNAVAILABLE with a recovery remedy.
|
|
8775
|
+
With --json, cancellation prints one STIM_CANCELLED payload, or the cleanup
|
|
8776
|
+
refusal when cleanup cannot be verified.
|
|
8777
|
+
|
|
8040
8778
|
REMOTE EAS SESSIONS
|
|
8041
8779
|
Plain \`stim gc\` is a dry run. \`gc --delete\` can stop active stim-* EAS
|
|
8042
8780
|
sessions after workspace state is missing. The stop needs verified
|
|
@@ -8303,8 +9041,11 @@ WORKSPACE BUILD OUTPUTS
|
|
|
8303
9041
|
and worktree warm record in state.json, lastBuild.startedAt,
|
|
8304
9042
|
supervisor.startedAt and the mtimes under logs/, so a dev server that keeps
|
|
8305
9043
|
logging keeps its workspace in use.
|
|
8306
|
-
|
|
8307
|
-
|
|
9044
|
+
A workspace with none of those was last used when its workspace.json was
|
|
9045
|
+
written, which happens once, when the workspace is created; only a
|
|
9046
|
+
workspace with no readable workspace.json has an unknown last use. The
|
|
9047
|
+
same time decides \`--older-than\` device reaping and automatic device
|
|
9048
|
+
deletion, and a workspace whose last use is unknown keeps its device.
|
|
8308
9049
|
The next build of an unchanged app installs from the shared build cache.
|
|
8309
9050
|
After a native change the Xcode compilation cache speeds the rebuild, but on
|
|
8310
9051
|
React Native 0.86 Swift does not use it (explicit modules are off), so that
|
|
@@ -8492,9 +9233,10 @@ KEYS STIM READS
|
|
|
8492
9233
|
flag overrides this per invocation. Unset means Debug.
|
|
8493
9234
|
ios.remote "proxy", "eas", or a named approved Mac from
|
|
8494
9235
|
remote.machines, with the same meaning as --remote.
|
|
8495
|
-
"auto" places on an approved Mac when this
|
|
9236
|
+
"auto" places on an approved Mac when this machine is full or
|
|
8496
9237
|
busy. Unset runs here; "local" runs here even when a
|
|
8497
|
-
lower layer says otherwise.
|
|
9238
|
+
lower layer says otherwise. A --device run ignores
|
|
9239
|
+
it. See lifecycle hosted-ios.
|
|
8498
9240
|
ios.projectPath directory under the app holding a bare React Native
|
|
8499
9241
|
app's Xcode project and Podfile; default "ios". "."
|
|
8500
9242
|
is the app directory itself (RNTester's layout).
|
|
@@ -8535,6 +9277,19 @@ KEYS STIM READS
|
|
|
8535
9277
|
name: Stim is non-interactive, so it refuses an
|
|
8536
9278
|
ambiguous identity rather than picking one. It wins
|
|
8537
9279
|
over ios.signingIdentity.
|
|
9280
|
+
ios.appStoreConnectKeyPath, ios.appStoreConnectKeyId, ios.appStoreConnectIssuerId
|
|
9281
|
+
machine scope only; STIM_ASC_KEY_PATH, STIM_ASC_KEY_ID
|
|
9282
|
+
and STIM_ASC_ISSUER_ID each override their own
|
|
9283
|
+
setting when set and non-empty. The absolute
|
|
9284
|
+
path of an App Store Connect API key (.p8), its key
|
|
9285
|
+
ID and its issuer ID. Only \`stim device provision
|
|
9286
|
+
ios\` reads them, passing them to xcodebuild as
|
|
9287
|
+
-authenticationKeyPath/-authenticationKeyID/
|
|
9288
|
+
-authenticationKeyIssuerID instead of the Xcode
|
|
9289
|
+
account, so provisioning works on a Mac where nobody
|
|
9290
|
+
signs in to Xcode. Set all three or none; Stim never
|
|
9291
|
+
reads the key file or prints its path. Builds never
|
|
9292
|
+
use them.
|
|
8538
9293
|
ios.lanHost e.g. "192.168.1.42" -- the address a phone uses to
|
|
8539
9294
|
reach this workspace's Metro on an \`ios --device\`
|
|
8540
9295
|
Debug run, pinning the interface on a multi-NIC Mac
|
|
@@ -8653,6 +9408,18 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8653
9408
|
build: embedded JS, no Metro, cache keyed on the
|
|
8654
9409
|
variant, and an APK re-pack on cache hits. See
|
|
8655
9410
|
\`guide lifecycle release\`.
|
|
9411
|
+
android.artifactInputs a native Gradle APK cache declaration:
|
|
9412
|
+
complete: true, ignored: [exact repository-relative files],
|
|
9413
|
+
outputs: [generated repository-relative directories],
|
|
9414
|
+
localFiles: [exact project-relative or absolute files],
|
|
9415
|
+
environment: [variable names]. complete promises all
|
|
9416
|
+
inputs are repeatable and dependencies pinned. Include
|
|
9417
|
+
signing keys and every external or environment input.
|
|
9418
|
+
Missing local files and environment values are hashed
|
|
9419
|
+
as absent. Configured files providers can share the APK
|
|
9420
|
+
and verification receipt. Input values stay local;
|
|
9421
|
+
this is not build-worker transfer authorization.
|
|
9422
|
+
See the native Android guide.
|
|
8656
9423
|
android.offloadInputs a native Gradle build-worker declaration:
|
|
8657
9424
|
{"complete":true,"ignored":[],"outputs":["build","app/build"]}.
|
|
8658
9425
|
complete confirms Git-visible source plus the exact
|
|
@@ -8660,7 +9427,7 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8660
9427
|
build. outputs names generated directories reported
|
|
8661
9428
|
by AGP; recorded outputs can survive worker sync.
|
|
8662
9429
|
Omitted optional inputs can change build results.
|
|
8663
|
-
|
|
9430
|
+
Worker APK caching also requires artifactInputs. See
|
|
8664
9431
|
\`stim guide lifecycle native-android\` for input,
|
|
8665
9432
|
privacy and worker requirements.
|
|
8666
9433
|
android.keystore the keystore a RE-PACKED release APK is signed with,
|
|
@@ -8685,16 +9452,17 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8685
9452
|
the debug keystore's fixed "android".
|
|
8686
9453
|
android.remote "proxy", "eas", or a named approved Mac in
|
|
8687
9454
|
remote.machines; "auto" places on an approved Mac when
|
|
8688
|
-
this
|
|
9455
|
+
this machine is full or busy. Unset runs here; "local"
|
|
8689
9456
|
runs here even when a lower layer says otherwise.
|
|
8690
|
-
See lifecycle
|
|
9457
|
+
A --device run ignores it. See lifecycle
|
|
9458
|
+
hosted-android.
|
|
8691
9459
|
remote.easFallback true lets "auto" (ios.remote, android.remote or
|
|
8692
9460
|
--remote auto) run the simulator or emulator on a
|
|
8693
|
-
billed EAS Simulator when this
|
|
9461
|
+
billed EAS Simulator when this machine is at its
|
|
8694
9462
|
concurrency.maxDevices cap (or has runs queued) and no
|
|
8695
|
-
remote.machines
|
|
9463
|
+
remote.machines entry takes the run, instead of waiting
|
|
8696
9464
|
or refusing with STIM_AT_CAPACITY. Default false. A
|
|
8697
|
-
busy
|
|
9465
|
+
busy machine with a free slot never uses it. Stim checks
|
|
8698
9466
|
first that the run could use --remote eas (eas-cli
|
|
8699
9467
|
with simulator commands, eas simulator:availability,
|
|
8700
9468
|
agent-device, the default slot, a reachable Metro);
|
|
@@ -8802,6 +9570,8 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8802
9570
|
Debug by stim macos
|
|
8803
9571
|
macos.infoPlist development Info.plist relative to Package.swift,
|
|
8804
9572
|
without shared URL schemes or an update feed
|
|
9573
|
+
macos.artifactInputs complete pinned, repeatable inputs producing a relocatable
|
|
9574
|
+
app for completed build caching. See stim guide macos.
|
|
8805
9575
|
macos.arguments string array passed directly to the executable;
|
|
8806
9576
|
see stim guide macos for the prototype's limits
|
|
8807
9577
|
macos.assetCatalog optional .xcassets directory relative to Package.swift,
|
|
@@ -9052,51 +9822,61 @@ test suites and the end-to-end harness use one -- and a scoped config must not
|
|
|
9052
9822
|
leave simulators on the machine it cannot account for. A redirected home that
|
|
9053
9823
|
wants a pool says so with the variable.
|
|
9054
9824
|
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9825
|
+
SETUP TICKETS
|
|
9826
|
+
A remote machine approves this one when a person there runs
|
|
9827
|
+
\`stim-server setup\` with this machine's setup ticket (32 random bytes, 43
|
|
9828
|
+
base64url characters) in STIM_SETUP_TICKET. Stim Desktop's Add wizard makes the
|
|
9829
|
+
ticket and sets STIM_ACCESS_TICKET for one \`doctor --fix\` run; without it,
|
|
9830
|
+
\`doctor --fix\` makes one and prints the setup command to run on the worker.
|
|
9831
|
+
Agents never set STIM_ACCESS_TICKET, never run \`stim-server setup\`, never edit
|
|
9058
9832
|
\`remote.*\`, \`server.*\` or \`hosting.*\` for the user, and never approve requests.
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9833
|
+
Until setup approves, the worker answers unknown-secret and the entry stays
|
|
9834
|
+
pending; every doctor run tries again. The first connection after approval pins
|
|
9835
|
+
the worker's stim-server key in build-machines.json or device-host-machines.json,
|
|
9836
|
+
and every later connection must prove that key; the tailnet node and address
|
|
9837
|
+
never decide who the worker is. With --fix, a pending entry is replaced when
|
|
9838
|
+
STIM_ACCESS_TICKET names another ticket.
|
|
9063
9839
|
Approved doctor entries under remoteMachines and deviceHosts include host
|
|
9064
9840
|
{ name, screenRecording, accessibility } when the worker reports it.
|
|
9065
9841
|
|
|
9066
|
-
REMOTE
|
|
9067
|
-
When the user mentions slow builds, a busy
|
|
9842
|
+
REMOTE MACHINES AND PHONE APP
|
|
9843
|
+
When the user mentions slow builds, a busy machine, a full disk or device limit, or
|
|
9068
9844
|
wanting updates away from the desk, tell them about Stim Desktop > Settings >
|
|
9069
|
-
Remote
|
|
9070
|
-
|
|
9071
|
-
suggests these itself, at most once a day and never
|
|
9072
|
-
tell the user: they never run \`stim-server setup\`,
|
|
9073
|
-
\`server.*\` or \`hosting.*\` for the user, and never
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9845
|
+
Remote Machines > Add (another machine on the tailnet that builds for this one,
|
|
9846
|
+
or a Mac that also hosts simulators) or Phones > Pair a Phone (the Stim phone
|
|
9847
|
+
app). Stim Desktop also suggests these itself, at most once a day and never
|
|
9848
|
+
during a build. Agents only tell the user: they never run \`stim-server setup\`,
|
|
9849
|
+
never edit \`remote.*\`, \`server.*\` or \`hosting.*\` for the user, and never
|
|
9850
|
+
approve requests.
|
|
9851
|
+
|
|
9852
|
+
REMOTE MACHINES ARE MACHINE-LEVEL
|
|
9853
|
+
\`remote.machines\` names the remote machines this machine may build on and host owned
|
|
9077
9854
|
simulator sessions on, by MagicDNS name with an optional serve port (default
|
|
9078
9855
|
7443). Name each node and port once:
|
|
9079
9856
|
|
|
9080
9857
|
stim settings set remote.machines '["janics-mac-mini"]'
|
|
9081
9858
|
stim doctor --fix
|
|
9082
9859
|
|
|
9083
|
-
Automatic membership is separate from approval. In Desktop Settings > Remote
|
|
9084
|
-
use Builds enabled and Simulators enabled for this
|
|
9085
|
-
The equivalent machine settings list the excluded members;
|
|
9860
|
+
Automatic membership is separate from approval. In Desktop Settings > Remote
|
|
9861
|
+
Machines, use Builds enabled and Simulators enabled for this machine or a
|
|
9862
|
+
configured remote. The equivalent machine settings list the excluded members;
|
|
9863
|
+
both default to []:
|
|
9086
9864
|
|
|
9087
9865
|
stim settings set remote.buildPoolDisabled '["local"]'
|
|
9088
9866
|
stim settings set remote.devicePoolDisabled '["janics-mac-mini"]'
|
|
9089
9867
|
stim settings unset remote.buildPoolDisabled
|
|
9090
9868
|
|
|
9091
|
-
Use local for this
|
|
9869
|
+
Use local for this machine and exact remote.machines entries for remotes, including
|
|
9092
9870
|
case and port. Names are not trimmed; unmatched entries exclude nothing. Copy the
|
|
9093
9871
|
configured name or use Desktop's switches. Each pool
|
|
9094
9872
|
must retain local or at least one configured remote already approved for that role.
|
|
9095
9873
|
Offline approved members count as configured members, but placement still requires
|
|
9096
|
-
an available compatible host.
|
|
9097
|
-
|
|
9874
|
+
an available compatible host. A remote that tailscale status reports as running an
|
|
9875
|
+
OS other than macOS is never a device-pool member or hosting candidate, since it
|
|
9876
|
+
cannot host; an unknown OS counts as able to host. Settings refuses removing the
|
|
9877
|
+
last member, including removing it from remote.machines. Disabling does not unpair a machine or stop a run.
|
|
9098
9878
|
|
|
9099
|
-
These settings apply only to new automatic work requested by this
|
|
9879
|
+
These settings apply only to new automatic work requested by this machine. They do not
|
|
9100
9880
|
change which work other requesters send to a host. Named placement and --remote-build
|
|
9101
9881
|
local bypass membership; the default device placement without --remote auto remains
|
|
9102
9882
|
local. Existing local and hosted device sessions keep their owner. Cache hits remain
|
|
@@ -9106,16 +9886,33 @@ local alone does not trigger billed EAS fallback; an existing explicit EAS opt-i
|
|
|
9106
9886
|
requires the physical device cap or queue condition. Restore membership before retrying or choose
|
|
9107
9887
|
an explicit placement. Build and simulator memberships are independent.
|
|
9108
9888
|
|
|
9109
|
-
A remote
|
|
9110
|
-
and device-host approvals are separate: a
|
|
9889
|
+
A remote machine is used for a capability only after it grants that approval. Build
|
|
9890
|
+
and device-host approvals are separate: a machine in the list that never granted
|
|
9111
9891
|
one is not an error, it is not used for that capability, and doctor reports
|
|
9112
9892
|
it plainly.
|
|
9113
9893
|
|
|
9894
|
+
PAUSE INCOMING WORK
|
|
9895
|
+
On the worker machine, an operator can temporarily refuse new incoming builds or
|
|
9896
|
+
hosted sessions without revoking any clients:
|
|
9897
|
+
|
|
9898
|
+
stim settings set server.buildsPaused true
|
|
9899
|
+
stim settings set server.devicesPaused true
|
|
9900
|
+
|
|
9901
|
+
Both machine settings default to false. The running server reads changes without
|
|
9902
|
+
restarting and rechecks admission after an earlier offer. Running builds and
|
|
9903
|
+
existing iOS, Android and macOS hosted sessions continue; attach, cached artifact
|
|
9904
|
+
retrieval and stop remain available. Local CLI builds and devices are unaffected.
|
|
9905
|
+
These settings apply to every requesting machine, including explicit placement.
|
|
9906
|
+
Desktop's pool switches instead affect only that requester's automatic placement.
|
|
9907
|
+
Set either setting to false to resume that capability. A pause does not make the
|
|
9908
|
+
machine idle: wait for existing work to finish or stop the relevant sessions before
|
|
9909
|
+
benchmarking. Agents change these settings only when the user asks them to.
|
|
9910
|
+
|
|
9114
9911
|
DEVICE HOSTING
|
|
9115
|
-
Only \`doctor --fix\` asks for device-host access
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9912
|
+
Only \`doctor --fix\` asks for device-host access: it makes a setup ticket and
|
|
9913
|
+
prints the command. A person approves by running \`stim-server setup\` on the
|
|
9914
|
+
worker with that ticket: one ticket, one expiry, one record per capability for
|
|
9915
|
+
the key that holds the ticket, with a per-grant Y/n question (Enter approves) in a
|
|
9119
9916
|
terminal or \`--yes\` otherwise. Agents never run \`stim-server setup\` or
|
|
9120
9917
|
approve requests. Setup never changes TCC or enables Funnel; an SSH-driven
|
|
9121
9918
|
run is not offered. Without a terminal or --yes, setup refuses before installing
|
|
@@ -9123,10 +9920,10 @@ unless every chosen capability already has a matching approval. Desktop reuse
|
|
|
9123
9920
|
requires an existing tailnet route. Ctrl-C or SIGTERM completes the journal,
|
|
9124
9921
|
releases the setup claim and exits 1; a typed N also exits 1. Hosting grants
|
|
9125
9922
|
include no read, control or build capability.
|
|
9126
|
-
On a remote Mac that hosts, Stim Desktop > Settings > Remote
|
|
9127
|
-
simulators, emulators and apps approved
|
|
9128
|
-
Mac. Stop asks for confirmation, ends the session and deletes
|
|
9129
|
-
its device on that Mac. Parked sessions remain listed without Stop. The list
|
|
9923
|
+
On a remote Mac that hosts, Stim Desktop > Settings > Remote Machines > Running
|
|
9924
|
+
here lists the simulators, emulators and apps approved machines run there, below
|
|
9925
|
+
Macs Using This Mac. Stop asks for confirmation, ends the session and deletes
|
|
9926
|
+
or parks its device on that Mac. Parked sessions remain listed without Stop. The list
|
|
9130
9927
|
refreshes every five seconds and stays hidden when the local server does not
|
|
9131
9928
|
support it.
|
|
9132
9929
|
$STIM_HOME/device-host-machines.json stores a private token and pinned tailnet
|
|
@@ -9136,7 +9933,7 @@ stim settings set ios.remote auto --scope machine (or android.remote; workspace,
|
|
|
9136
9933
|
repo and committed scopes override the machine default),
|
|
9137
9934
|
or per run stim ios --remote auto / stim ios --remote <machine>.
|
|
9138
9935
|
New Desktop runs pass no --remote flag; recorded hosted sessions keep their
|
|
9139
|
-
machine until stim stop. Only devices outside this
|
|
9936
|
+
machine until stim stop. Only devices outside this machine show "on <machine>"
|
|
9140
9937
|
on tiles, workspace pages, viewer toolbars and sidebar rows, with the reason
|
|
9141
9938
|
as hover text.
|
|
9142
9939
|
Stim sends tokens only to the pinned node's own tailnet address,
|
|
@@ -9162,30 +9959,29 @@ shared daemon only when that agent-device can lease a single app (its
|
|
|
9162
9959
|
notice, and no client is handed the Mac's desktop. STIM_AGENT_DEVICE_BIN in
|
|
9163
9960
|
stim-server's environment names an agent-device binary to use instead of
|
|
9164
9961
|
~/.local/bin/agent-device. Hosted iOS uses one daemon per simulator, pinned by
|
|
9165
|
-
its UDID policy; both
|
|
9962
|
+
its UDID policy; both machines need agent-device 0.21.20 or later. Hosted Android
|
|
9166
9963
|
uses one daemon per emulator, pinned by its serial policy, with agent-device
|
|
9167
|
-
0.21.22 or later on both
|
|
9964
|
+
0.21.22 or later on both machines. See guide lifecycle
|
|
9168
9965
|
hosted-ios. \`doctor\` on that Mac notes an installed hosted app that runs while
|
|
9169
9966
|
the setting is \`none\`.
|
|
9170
9967
|
|
|
9171
9968
|
REMOTE BUILDS
|
|
9172
|
-
The same \`remote.machines\` list names the
|
|
9969
|
+
The same \`remote.machines\` list names the machines that may build for this one:
|
|
9173
9970
|
|
|
9174
9971
|
{
|
|
9175
9972
|
"remote": { "machines": ["janics-mac-mini"] }
|
|
9176
9973
|
}
|
|
9177
9974
|
|
|
9178
|
-
\`doctor --fix\`, run in any app directory,
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
ticket and expiry, under the approval rule above. A build grant is full access
|
|
9975
|
+
\`doctor --fix\`, run in any app directory, makes a setup ticket for each named
|
|
9976
|
+
machine and prints the \`stim-server setup\` command a person runs on that
|
|
9977
|
+
machine to approve this one, under the approval rule above. The next doctor run
|
|
9978
|
+
pins the worker's stim-server key in $STIM_HOME/build-machines.json. A build grant is full access
|
|
9183
9979
|
to the account stim-server runs as: project code runs there unsandboxed, so it
|
|
9184
9980
|
can grant itself read and control. Revoking it does not undo what that code
|
|
9185
|
-
already did. Grant it only to
|
|
9186
|
-
Stim connects to a named
|
|
9981
|
+
already did. Grant it only to machines you trust.
|
|
9982
|
+
Stim connects to a named machine only while its name still belongs to the pinned
|
|
9187
9983
|
node and never sends the token to another node. \`doctor\` reports each
|
|
9188
|
-
remote
|
|
9984
|
+
remote machine's build pairing state and, for an approved one, asks it for one build
|
|
9189
9985
|
offer and lists every reason it would not take this app's iOS build: no
|
|
9190
9986
|
answer, another Stim build, CPU, Xcode, simulator SDK or CocoaPods, no
|
|
9191
9987
|
Bundler for an app whose Gemfile.lock pins CocoaPods, no iPhone simulator on
|
|
@@ -9200,12 +9996,12 @@ configured names case-insensitively, with port 7443 when omitted; reports use
|
|
|
9200
9996
|
the configured entry.
|
|
9201
9997
|
|
|
9202
9998
|
auto follows remote.buildMode, considering only enabled automatic pool members
|
|
9203
|
-
local builds only on this
|
|
9999
|
+
local builds only on this machine for this invocation
|
|
9204
10000
|
name requires a matching entry in remote.machines, already paired and
|
|
9205
|
-
approved for builds; ignores remote.buildMode and this
|
|
10001
|
+
approved for builds; ignores remote.buildMode and this machine's load/slot gating
|
|
9206
10002
|
|
|
9207
|
-
A name never prompts for pairing, tries another remote
|
|
9208
|
-
Any refusal or failure is STIM_OFFLOAD_REFUSED with the remote
|
|
10003
|
+
A name never prompts for pairing, tries another remote machine or falls back here.
|
|
10004
|
+
Any refusal or failure is STIM_OFFLOAD_REFUSED with the remote machine and reason.
|
|
9209
10005
|
Device, Release/non-Debug, --remote, Android CAS compiler builds, builds with
|
|
9210
10006
|
the build cache off, and an unknown simulator runtime cannot build there and
|
|
9211
10007
|
refuse on a cache miss. Invalid values, unlisted names and unpaired names refuse
|
|
@@ -9213,12 +10009,11 @@ at setup before consulting the cache; they create no build record or failed-run
|
|
|
9213
10009
|
stats. A listed paired name with a cache hit compiles nothing, contacts no worker
|
|
9214
10010
|
and records buildMachine with builtOn absent. Build failures retain the selected
|
|
9215
10011
|
value; builtOn is here or the configured machine entry when compilation ran.
|
|
9216
|
-
Prebuild and pod install still run on this
|
|
10012
|
+
Prebuild and pod install still run on this machine before a named offload. A refusal
|
|
9217
10013
|
starts no local xcodebuild, Gradle or SwiftPM compile.
|
|
9218
10014
|
Run stim doctor --fix to ask for build access if not paired. A person on the
|
|
9219
|
-
worker
|
|
9220
|
-
|
|
9221
|
-
the client node, ticket and expiry. Check stim settings get remote.machines,
|
|
10015
|
+
worker approves it by running the stim-server setup command doctor printed, with
|
|
10016
|
+
its ticket and expiry. Check stim settings get remote.machines,
|
|
9222
10017
|
or rerun with --remote-build auto or --remote-build local. Ctrl-C cancels
|
|
9223
10018
|
the remote build without a local xcodebuild, Gradle or SwiftPM compile.
|
|
9224
10019
|
|
|
@@ -9229,23 +10024,29 @@ Copyable agent prompt:
|
|
|
9229
10024
|
With remote.build auto, \`remote.buildMode\` decides where an iOS simulator Debug build or an Android
|
|
9230
10025
|
emulator debug build or a stim macos SwiftPM Debug build compiles:
|
|
9231
10026
|
|
|
9232
|
-
auto (default) here while this
|
|
10027
|
+
auto (default) here while this machine has capacity: a free
|
|
9233
10028
|
\`concurrency.maxBuilds\` slot (always, with no build limit) and a
|
|
9234
10029
|
load per core under \`server.maxLoadPerCore\`. Otherwise on a
|
|
9235
|
-
remote
|
|
9236
|
-
while every slot here is busy, any remote
|
|
10030
|
+
remote machine that accepts the build and is expected to be faster:
|
|
10031
|
+
while every slot here is busy, any remote machine that accepts; while only
|
|
9237
10032
|
the load is high, one whose load per core is lower than this
|
|
9238
|
-
|
|
10033
|
+
machine's. A machine too old to report its load counts only while every
|
|
9239
10034
|
slot here is busy.
|
|
9240
|
-
force on a remote
|
|
10035
|
+
force on a remote machine whenever one accepts it
|
|
9241
10036
|
off here when local remains enabled in the automatic build pool
|
|
9242
10037
|
|
|
9243
|
-
|
|
9244
|
-
|
|
10038
|
+
For React Native and Expo, among machines that can take a new build, a matching dependency installation
|
|
10039
|
+
ranks before load. The worker checks the requested project, lockfile and install
|
|
10040
|
+
arguments, and verifies that its modules and install marker remain present.
|
|
10041
|
+
Older workers' dependency hints and mere checkout or build-folder presence do
|
|
10042
|
+
not influence this ranking. Exact completed-artifact hits still come first.
|
|
10043
|
+
|
|
10044
|
+
Load per core is the 5-minute load average divided by the CPU count; a machine's
|
|
10045
|
+
native builds are its Stim runs in prebuild, pods or compile on that machine, not
|
|
9245
10046
|
the ones it offloaded.
|
|
9246
10047
|
\`server.maxLoadPerCore\` (default 2) is also the busy threshold for
|
|
9247
|
-
automatic iOS and Android device placement. It is the load per core at which a
|
|
9248
|
-
counts as saturated, both here and on a remote
|
|
10048
|
+
automatic iOS and Android device placement. It is the load per core at which a machine
|
|
10049
|
+
counts as saturated, both here and on a remote machine.
|
|
9249
10050
|
|
|
9250
10051
|
STIM_REMOTE_BUILD_MODE overrides it for one command. Device, Release and
|
|
9251
10052
|
\`--remote eas|proxy\` builds, Android builds with the Apple Clang CAS compiler cache,
|
|
@@ -9254,20 +10055,39 @@ Debug builds can use a separate --remote-build, targeting the hosting Mac's
|
|
|
9254
10055
|
architecture and runtime.
|
|
9255
10056
|
macOS uses matching Xcode and macOS SDK, with a per-client SwiftPM dependency
|
|
9256
10057
|
cache on the worker. It skips JavaScript dependencies, prebuild and pods; see
|
|
9257
|
-
stim guide macos.
|
|
10058
|
+
stim guide macos. Completed caching requires macos.artifactInputs and a locally
|
|
10059
|
+
verified compile; remote output is not published under an unverified client key.
|
|
9258
10060
|
An offloaded iOS/Android build first runs prebuild (and \`pod install\` for iOS) here,
|
|
9259
10061
|
then asks every paired machine what it can build. It takes one whose Stim
|
|
9260
|
-
build matches this Mac and CPU matches the target simulator, with enough disk, that does not decline,
|
|
10062
|
+
build matches this Mac and, for iOS and macOS, CPU matches the target simulator, with enough disk, that does not decline,
|
|
9261
10063
|
preferring the one that already holds this repository, then the least loaded,
|
|
9262
10064
|
and moves to the next one in that order when a machine that offered fails the
|
|
9263
10065
|
sync or refuses to start the build.
|
|
10066
|
+
After a local and configured-provider miss, native Xcode simulator builds can
|
|
10067
|
+
reuse an exact completed archive from an enabled paired worker. Its full key
|
|
10068
|
+
includes source, Xcode, SDK, architecture and target options. A hit skips sync
|
|
10069
|
+
and compilation even while the worker is busy or this machine has room. Missing or
|
|
10070
|
+
corrupt archives follow normal placement. Off mode and an explicit local build
|
|
10071
|
+
do not query peer caches. Older workers continue normal placement. This peer
|
|
10072
|
+
lookup also covers declared native Gradle worker APKs when the worker supports
|
|
10073
|
+
native-gradle-peer-cache. It rechecks current private inputs against the saved
|
|
10074
|
+
receipt at offer and fetch for the requested source, resolved variant, ABI and
|
|
10075
|
+
build options. Caller fingerprints stay null; worker keys stay worker-scoped.
|
|
10076
|
+
React Native and Expo development builds also query enabled paired workers
|
|
10077
|
+
with react-native-peer-cache after local and configured-provider misses. Their
|
|
10078
|
+
post-mutation fingerprint, native build choices and compatible toolchain must
|
|
10079
|
+
match. Completed archives survive worker checkout changes or removal; hits
|
|
10080
|
+
need no source upload or build slot. Disabled remote artifact reads skip this
|
|
10081
|
+
lookup. Release and physical-device builds keep their existing paths.
|
|
10082
|
+
SwiftPM, compiler and dependency caches use their existing paths.
|
|
9264
10083
|
For iOS the machine's Xcode and simulator SDK must match, and it needs an
|
|
9265
10084
|
iPhone simulator on the target runtime. Its project-selected CocoaPods must match too, unless
|
|
9266
|
-
the app's Gemfile.lock pins CocoaPods: both
|
|
10085
|
+
the app's Gemfile.lock pins CocoaPods: both machines then run that version through
|
|
9267
10086
|
bundler, so the machine needs only Bundler on its stim-server PATH and
|
|
9268
10087
|
installs the pinned gems itself on the first build. The comparison selects
|
|
9269
|
-
the app's .ruby-version when installed, and
|
|
9270
|
-
For Android its
|
|
10088
|
+
the app's .ruby-version when installed, otherwise rvm's or rbenv's default Ruby, and only when neither exists the GEM_HOME, GEM_PATH and Ruby-related PATH entries of the machine's login shell (read once with $SHELL -lic), unless the caller already sets GEM_HOME, with pod install's UTF-8 locale defaults. pod install, including the Bundler run, uses the same environment.
|
|
10089
|
+
For Android its CPU may differ, since the APK's ABIs come from the NDK, so an
|
|
10090
|
+
x86_64 Linux or Windows machine running stim-server can build for an Apple silicon Mac. Its JDK major
|
|
9271
10091
|
version must match, and its Android SDK must hold the NDK, build-tools and
|
|
9272
10092
|
compile platform that the project's React Native version names in
|
|
9273
10093
|
gradle/libs.versions.toml; Gradle and AGP come from the synced project. When
|
|
@@ -9277,7 +10097,7 @@ reason, such as \`janics-mac-mini: busy (load at or above 2/core; load
|
|
|
9277
10097
|
\`git ls-files -co --exclude-standard\` lists (the machine keeps only files it
|
|
9278
10098
|
lacks, so an unignored secret such as \`.env\` is sent too), builds with
|
|
9279
10099
|
Stim's own code there, refuses unless the fingerprint there equals this one,
|
|
9280
|
-
and brings the \`.app\` or APK back. An Android build there uses this
|
|
10100
|
+
and brings the \`.app\` or APK back. An Android build there uses this machine's
|
|
9281
10101
|
variant, target ABI, Gradle build cache, PCH and compiler cache choices, so
|
|
9282
10102
|
the APK matches the ABI-narrowed cache key. Stim checks the archive's sha256
|
|
9283
10103
|
and fingerprints this checkout again before it stores the app under the
|
|
@@ -9295,11 +10115,11 @@ interrupted while it reconnects, leaves it until those 5 minutes pass. With auto
|
|
|
9295
10115
|
\`--json\` facts record the reason as offloadFallback. Offloading holds no
|
|
9296
10116
|
local build slot; that fallback takes one. \`stim stats\` keeps where each
|
|
9297
10117
|
compiling build ran and why (\`guide facts stats\`).
|
|
9298
|
-
An offloaded app lands only in this
|
|
10118
|
+
An offloaded app lands only in this machine's build cache, not in a remote cache
|
|
9299
10119
|
provider. A project whose xcodebuild changes its own fingerprinted inputs
|
|
9300
10120
|
fails the offload fingerprint check: auto builds here; a named placement refuses.
|
|
9301
10121
|
|
|
9302
|
-
On a remote
|
|
10122
|
+
On a remote machine that builds for others, stim-server keeps each client's checkouts, dependencies,
|
|
9303
10123
|
DerivedData, compilation cache, ccache and Gradle home under
|
|
9304
10124
|
\`server.workerRoot\` (absolute; default $STIM_HOME/build-worker), one area
|
|
9305
10125
|
and Stim home per client and repository, and one Gradle home per client. It
|
|
@@ -9308,21 +10128,23 @@ less than 10 GB free, while its own native builds and the offloaded one fill
|
|
|
9308
10128
|
its \`concurrency.maxBuilds\`, or while its load per core is at or above its
|
|
9309
10129
|
\`server.maxLoadPerCore\`, and reports the reason in its offer. It boots and
|
|
9310
10130
|
installs nothing. While an offloaded build runs there, it holds one of that
|
|
9311
|
-
|
|
10131
|
+
machine's \`concurrency.maxBuilds\` slots, so a local Stim build there waits for it
|
|
9312
10132
|
and counts it as busy; the slot is freed when the build ends, is cancelled or
|
|
9313
10133
|
its process is gone. Android builds there run on the JDK in stim-server's
|
|
9314
10134
|
JAVA_HOME (else the macOS default JDK) with the SDK in its ANDROID_HOME (else
|
|
9315
|
-
~/Library/Android/sdk). The client's Gradle daemon stays warm there for
|
|
10135
|
+
~/Library/Android/sdk, or ~/Android/Sdk on Linux). The client's Gradle daemon stays warm there for
|
|
9316
10136
|
\`server.gradleDaemonIdleMinutes\` (default 30; 0 stops it when each build
|
|
9317
10137
|
ends; a new value applies from the next daemon) and never holds a build
|
|
9318
10138
|
slot. While none of the client's builds runs, stim-server stops it sooner
|
|
9319
10139
|
when a build is cancelled, the client is revoked, or the machine has less
|
|
9320
10140
|
than 2 GB of memory available, and deleting the client's directory under the
|
|
9321
10141
|
worker root stops it too.
|
|
9322
|
-
\`stim-server service install [--serve]\` on
|
|
9323
|
-
running as a login LaunchAgent
|
|
9324
|
-
|
|
9325
|
-
|
|
10142
|
+
\`stim-server service install [--serve]\` on a remote machine keeps stim-server
|
|
10143
|
+
running as a login LaunchAgent on macOS, a systemd user service on Linux
|
|
10144
|
+
(\`sudo loginctl enable-linger <user>\` keeps it running after logout; install
|
|
10145
|
+
prints that command and never runs it), or a logon scheduled task on Windows; \`--path-prepend <dir>\` and \`--env KEY=VALUE\`
|
|
10146
|
+
pin a PATH entry or variable, such as a private CocoaPods, that stim-server's
|
|
10147
|
+
toolchain discovery does not find.
|
|
9326
10148
|
\`stim-server service update --release <version>\` there moves the service to
|
|
9327
10149
|
that exact stim-server release from the public npm registry once npm verifies
|
|
9328
10150
|
its integrity and registry signatures; \`--from <dir>\` installs the packed
|
|
@@ -9330,15 +10152,15 @@ packages of a checkout instead, with the same signature check on each npm
|
|
|
9330
10152
|
dependency but none for Stim's own packages. It waits for offloaded builds and hosted
|
|
9331
10153
|
sessions to finish, restarts the job, and switches back when the new server
|
|
9332
10154
|
exits or does not answer within 90 seconds; \`stim-server service rollback\` returns
|
|
9333
|
-
to the previous server. A client
|
|
10155
|
+
to the previous server. A client machine approved for builds or device hosting
|
|
9334
10156
|
there can ask for the same update over its tailnet connection: an npm release
|
|
9335
10157
|
always, and its own packed build only while \`server.acceptClientBuilds\` is
|
|
9336
10158
|
true on that machine (default false).
|
|
9337
10159
|
Replacing a loaded service waits up to 45 seconds for its existing listeners to
|
|
9338
10160
|
release the port. Uninstall does not wait for the port. If stopping the old job
|
|
9339
|
-
or starting the new one fails, install restores the previous plist and attempts
|
|
9340
|
-
to restart a previously
|
|
9341
|
-
launchctl bootout/bootstrap remedy. A running
|
|
10161
|
+
or starting the new one fails, install restores the previous plist or unit and attempts
|
|
10162
|
+
to restart a previously running service; if it cannot, it prints the
|
|
10163
|
+
launchctl bootout/bootstrap or systemctl --user daemon-reload/restart remedy. A running service does not prove readiness; check \`stim-server service status\`
|
|
9342
10164
|
and its reported log. The server listens before it touches the Stim home; a
|
|
9343
10165
|
read-only child process reads the Stim home, server and recording directories,
|
|
9344
10166
|
and until it returns \`/health\` answers 503 with \`startup.state\` pending.
|
|
@@ -9370,7 +10192,7 @@ stim-server records the screens of owned simulators, emulators and the
|
|
|
9370
10192
|
Stim-owned Chrome page while an automation tool drives them or a paired client
|
|
9371
10193
|
watches them, so the phone app can scrub back through them. It keeps the last
|
|
9372
10194
|
15 minutes of footage per device under $STIM_HOME/workspaces/<id>/recordings/,
|
|
9373
|
-
on this
|
|
10195
|
+
on this machine only, and serves it only to paired clients. \`recording.enabled\`
|
|
9374
10196
|
turns it off:
|
|
9375
10197
|
|
|
9376
10198
|
stim settings set recording.enabled false --scope machine
|
|
@@ -9463,8 +10285,11 @@ The example shows the defaults. Full setting names and behavior:
|
|
|
9463
10285
|
optimizations.remoteBuildCache
|
|
9464
10286
|
false skips both optional remote artifact providers, including loading
|
|
9465
10287
|
their modules and authentication. Local artifact caching stays enabled.
|
|
9466
|
-
|
|
9467
|
-
|
|
10288
|
+
Install @stim-cli/cache-s3 and select it through cache.provider for S3-compatible storage,
|
|
10289
|
+
including Cloudflare R2, or configure another provider through Expo.
|
|
10290
|
+
Stim does not run a hosted cache service; credentials use the AWS SDK chain.
|
|
10291
|
+
S3 file uploads retry connection resets up to three PUT attempts, reopening
|
|
10292
|
+
the completed file each time. Cancellation also stops the retry delays.
|
|
9468
10293
|
optimizations.releaseBundleSwap
|
|
9469
10294
|
false always builds Release from source, including the current JS;
|
|
9470
10295
|
it never installs an old embedded bundle. Fresh artifacts can still store.
|
|
@@ -9534,7 +10359,9 @@ PCH mode matches; disable artifact caching too to force native compilation. Lega
|
|
|
9534
10359
|
cannot key these compiler profiles, so Stim skips that tier for custom profiles
|
|
9535
10360
|
and Android CAS. Providers implementing the Stim key contract remain usable.
|
|
9536
10361
|
Android compiler/PCH profiles also get separate CMake staging directories under
|
|
9537
|
-
<module>/.cxx/stim-<profile
|
|
10362
|
+
<module>/.cxx/stim-<profile> (<module>/.cxx/<first 4 profile characters> on
|
|
10363
|
+
Windows, where every character counts against MAX_PATH), or under the project's
|
|
10364
|
+
custom staging root. Switching
|
|
9538
10365
|
backends in Stim selects the matching directory without deleting previous builds.
|
|
9539
10366
|
These directories accumulate across profile changes and shim upgrades. Stim
|
|
9540
10367
|
does not prune them; remove an obsolete generated profile only with all native
|
|
@@ -9926,24 +10753,65 @@ changing focus: it sets STIM_BACKGROUND_LAUNCH=1 in the app's environment, which
|
|
|
9926
10753
|
Stim Desktop honors, including for reopen events from open -g. An app that
|
|
9927
10754
|
activates itself at launch or on reopen still takes focus.
|
|
9928
10755
|
Hosted launches (macos --remote) do not set it.
|
|
9929
|
-
|
|
10756
|
+
This prototype has no --slot or reload command.
|
|
10757
|
+
Completed app caching is opt-in with macos.artifactInputs:
|
|
10758
|
+
|
|
10759
|
+
{ "macos": { "artifactInputs": { "complete": true,
|
|
10760
|
+
"ignored": [], "outputs": [], "localFiles": [], "environment": [] } } }
|
|
10761
|
+
|
|
10762
|
+
complete declares pinned, repeatable build inputs and an app that runs after its
|
|
10763
|
+
original checkout and scratch directory are gone. Do not enable it for mutable
|
|
10764
|
+
dependencies, build-time network data, undeclared environment or local inputs,
|
|
10765
|
+
or code that needs its original absolute source paths (including #filePath).
|
|
10766
|
+
Stim hashes Git-visible repository source, Package.resolved even when ignored,
|
|
10767
|
+
the development plist, declared resources, Swift/Xcode/SDK identity and CPU
|
|
10768
|
+
architecture. ignored names exact Git-ignored repository-relative input files;
|
|
10769
|
+
outputs names generated repository-relative directories already ignored by Git.
|
|
10770
|
+
localFiles names exact additional private files, relative to the package or
|
|
10771
|
+
absolute; environment names additional build-time variables. Values and private
|
|
10772
|
+
file contents are hashed locally and are not included in the shared receipt.
|
|
10773
|
+
Symbolic links in source inventories are currently ineligible for caching.
|
|
10774
|
+
Without a valid declaration Stim compiles normally and keeps SwiftPM incremental
|
|
10775
|
+
reuse. optimizations.buildCache and optimizations.remoteBuildCache also apply.
|
|
10776
|
+
The completed bundle uses the ordinary shared build cache and an optional
|
|
10777
|
+
cache.provider's files capability, including S3. A hit avoids compiler slots and
|
|
10778
|
+
placement, then gets this workspace's identifier and name on a re-signed copy.
|
|
10779
|
+
Corrupt or incompatible entries fall back to compilation. Inputs changed during
|
|
10780
|
+
compilation prevent publication. Compiler and package scratch state is not shared.
|
|
10781
|
+
An enabled paired worker with swiftpm-peer-cache can retain a completed archive
|
|
10782
|
+
after verifying its actual source, private inputs and toolchain before and after
|
|
10783
|
+
compilation. After local/provider misses, an exact peer hit skips source upload
|
|
10784
|
+
and compiler admission, even while that worker is busy. Private values stay on
|
|
10785
|
+
the worker; its opaque identity is not used as this Mac's local cache key.
|
|
10786
|
+
Ignored bundle files must be declared in ignored or localFiles for peer reuse.
|
|
10787
|
+
The worker rechecks private inputs before offer and fetch; deleting its checkout
|
|
10788
|
+
does not discard an archive whose private inputs remain valid. Toolchain versions and command selection are
|
|
10789
|
+
checked from the package directory. After checkout removal, only verified direct
|
|
10790
|
+
Apple Swift, xcrun and xcodebuild selections can be reproduced; custom launchers
|
|
10791
|
+
require the checkout and otherwise miss safely. SWIFT_EXEC and SWIFT_EXEC_MANIFEST
|
|
10792
|
+
compiler overrides are resolved and versioned separately and require the checkout.
|
|
10793
|
+
The SDK selected by SDKROOT or SWIFTPM_SDKROOT_macosx is checked by real path and build version. Explicit local placement,
|
|
10794
|
+
remote build mode off, disabled pool members and remoteBuildCache
|
|
10795
|
+
false skip peer lookup. Older workers keep their normal compilation path.
|
|
9930
10796
|
--plan validates the Swift Package directory, macos settings, development plist
|
|
9931
|
-
and declared resources without building, signing,
|
|
10797
|
+
and declared resources without building, signing, stopping or launching
|
|
9932
10798
|
an app, writing workspace state or claiming a build slot. It does not execute
|
|
9933
10799
|
Package.swift, so it cannot validate the executable product or package dependencies.
|
|
9934
10800
|
--remote-build is respected, including named-machine setup refusals; no worker
|
|
9935
10801
|
is contacted and live worker availability is unknown. --remote is launch-only
|
|
9936
10802
|
and refuses with --plan. The JSON plan has platform "macos", product and
|
|
9937
|
-
buildMachine
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
10803
|
+
buildMachine. An eligible cache identity supplies fingerprint and cacheKey;
|
|
10804
|
+
cacheHit reports a verified local completed artifact, checked in a disposable
|
|
10805
|
+
temporary copy. Providers and workers are not contacted. cacheSkipped is true
|
|
10806
|
+
when artifact caching is disabled or ineligible. provider, prebuild, outcome
|
|
10807
|
+
and expectedMs remain null, and basis is 0. SwiftPM decides incremental compile
|
|
10808
|
+
work when a build runs; the plan predicts no duration. Desktop checks automatically while build details are visible,
|
|
9941
10809
|
reusing a completed build or check for 60 seconds and skipping running builds.
|
|
9942
10810
|
A failed build records its error and compiler output without launching an app.
|
|
9943
10811
|
While it runs, stim status --json reports it as environments[].build with
|
|
9944
10812
|
platform "macos": phase prepare, compile, install, then launch, and during
|
|
9945
10813
|
compile detail.unit "steps" with SwiftPM's [done / total] counts (fetching and
|
|
9946
|
-
planning are detail.step "configure").
|
|
10814
|
+
planning are detail.step "configure"). outcome and
|
|
9947
10815
|
plannedPhases are null; finished runs and their phase times are in
|
|
9948
10816
|
environments[].builds.macos, where phases includes launch once the launch step finishes
|
|
9949
10817
|
and compileSteps is SwiftPM's step total. An offloaded build reports the worker's
|
|
@@ -10144,11 +11012,11 @@ used.
|
|
|
10144
11012
|
ON ANOTHER MAC
|
|
10145
11013
|
|
|
10146
11014
|
stim macos --remote <machine> builds the Debug app on this Mac and runs it on an
|
|
10147
|
-
approved remote Mac over the tailnet, without SSH. The
|
|
10148
|
-
in remote.machines and approved: stim doctor --fix
|
|
10149
|
-
Mac runs stim-server
|
|
10150
|
-
|
|
10151
|
-
|
|
11015
|
+
approved remote Mac over the tailnet, without SSH. The Mac must be listed
|
|
11016
|
+
in remote.machines and approved: stim doctor --fix makes a setup ticket, a
|
|
11017
|
+
person on that Mac runs stim-server setup with that ticket and expiry (guide
|
|
11018
|
+
settings), and stim doctor then pins that Mac's stim-server key. Stim goes ahead
|
|
11019
|
+
only with the stim-server that proves it holds that key.
|
|
10152
11020
|
A refusal or an unreachable host fails the command; it never launches here
|
|
10153
11021
|
instead.
|
|
10154
11022
|
|
|
@@ -10207,7 +11075,7 @@ approved host that lacks them. A server started by Stim Desktop uses Desktop's
|
|
|
10207
11075
|
grants.
|
|
10208
11076
|
|
|
10209
11077
|
Hosted delivery carries the staged bundle with declared resources and compiled assets.
|
|
10210
|
-
When offload built it on the host's own
|
|
11078
|
+
When offload built it on the host's own stim-server, the host copies the files
|
|
10211
11079
|
from the build it kept for this Mac instead of receiving them again, admitting
|
|
10212
11080
|
only bytes that match the bundle's digests here. That needs both the build and
|
|
10213
11081
|
the device-host approval for this Mac. Files the host cannot take, an older
|
|
@@ -10313,7 +11181,7 @@ outside the user's own projects.`;
|
|
|
10313
11181
|
const local = `The tutorial runs on this Mac. Every time you run the tutorial app on iOS
|
|
10314
11182
|
from a worktree of {base}, use stim ios --remote local --remote-build local,
|
|
10315
11183
|
even when the user's settings would place the device or the build on another
|
|
10316
|
-
|
|
11184
|
+
machine. Only an explicit request to build on another machine changes the build, with
|
|
10317
11185
|
stim ios --remote local --remote-build "<machine>"; the device stays here.`;
|
|
10318
11186
|
const screenshots = `Before and after screenshots, for a pull request: in each change's worktree,
|
|
10319
11187
|
run the app on iOS before you edit anything, open it with agent-device and save
|
|
@@ -10636,7 +11504,7 @@ function renderIndex(version) {
|
|
|
10636
11504
|
return lines.join("\n");
|
|
10637
11505
|
}
|
|
10638
11506
|
function guideCommand(program, version, status = (running) => guideStatus({
|
|
10639
|
-
projectRoot: findProjectRoot(process.cwd()),
|
|
11507
|
+
projectRoot: findProjectRoot$1(process.cwd()),
|
|
10640
11508
|
running
|
|
10641
11509
|
})) {
|
|
10642
11510
|
program.command("guide [topic] [section]").description("Print reference documentation for THIS version of Stim (topics: " + topicNames().join(", ") + "). A topic with sections prints its section index; name a section to print only it, e.g. `stim guide errors STIM_NO_METRO` or `stim guide lifecycle builds`. Generated by the binary, so it cannot drift from the installed CLI.").action(async (topic, section) => {
|