stim 1.25.0 → 1.27.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 +1 -1
- package/dist/{acquire-artifact-zA4S7RHE.mjs → acquire-artifact-BKN2Yuhg.mjs} +2 -2
- package/dist/{act-BbHS3oV8.mjs → act-ROviTF_t.mjs} +415 -118
- package/dist/{activity-BpjwrQXU.mjs → activity-Cd-ysFes.mjs} +6 -7
- package/dist/{agent-device-usage-output-Bnkerfod.mjs → agent-device-usage-output-C5nCKWp9.mjs} +5 -5
- package/dist/{android-CNZgRC-4.mjs → android--HBgpvpW.mjs} +5 -5
- package/dist/{android-BGwuK3Mc.mjs → android-Cd6w7_qw.mjs} +134 -57
- package/dist/{android-saBeB4lr.mjs → android-Deb9X3_Y.mjs} +37 -15
- package/dist/{android-Cjcj8MCw.mjs → android-DriNoAVy.mjs} +99 -47
- package/dist/{android-cas-BVqh2Zep.mjs → android-cas-D5e6ecUg.mjs} +4 -4
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{android-project-CTYaETc0.d.mts → android-project-DUGMbq28.d.mts} +55 -1
- package/dist/api.d.mts +20 -7
- package/dist/api.mjs +42 -32
- package/dist/apk-signed-tail-BHQHx3Rm.mjs +142 -0
- package/dist/{artifact-Co8zixVx.mjs → artifact-0AGJYB9O.mjs} +28 -28
- package/dist/{artifact-DN8JNwqS.mjs → artifact-faemIZv5.mjs} +40 -30
- package/dist/{artifact-platform-CMRc0M_r.mjs → artifact-platform-BO2Uvk_A.mjs} +1 -1
- package/dist/{attempt-DW-mQqM7.mjs → attempt-ClyJlZPT.mjs} +4 -2
- package/dist/auto-placement-z-H5pJza.mjs +350 -0
- package/dist/{browser-web-CCgZsHmI.mjs → browser-web-slD8AvLp.mjs} +16 -17
- package/dist/{build-cache-CKCzxzxA.mjs → build-cache-gBJ-WKzA.mjs} +141 -37
- package/dist/{build-CAiw8Ezm.mjs → build-hS0QyFlQ.mjs} +38 -31
- package/dist/{build-plan-zCuHGlA8.mjs → build-plan-CBqYbzYM.mjs} +7 -6
- package/dist/{cache-manifest-BPXRONJz.mjs → cache-manifest-DEjqGGat.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{budget-HyShrIpL.mjs → ccache-BWTze1Ls.mjs} +634 -1514
- package/dist/{cdp-BG3FJCCx.mjs → cdp-C3svvXiE.mjs} +1 -1
- package/dist/{chrome-BvV8ssI3.mjs → chrome-DyDWurWG.mjs} +1 -1
- package/dist/{cli-C4w607Pz.mjs → cli-ftXDLto1.mjs} +24 -23
- package/dist/cli.mjs +1 -1
- package/dist/{client-BQsmyp_-.mjs → client-xsdxrhWA.mjs} +77 -116
- package/dist/collector-run.d.mts +10 -9
- package/dist/collector-run.mjs +42 -27
- package/dist/{command-output-BBvS1H6v.mjs → command-output-Dj-WT4BP.mjs} +1 -1
- package/dist/{config-BZhXY15H.mjs → config-Cn94Jc0g.mjs} +343 -18
- package/dist/{launch-DscF1QfM.mjs → dependencies-BGokZ-Ng.mjs} +330 -279
- package/dist/{dependency-state-BwNCYG5Q.mjs → dependency-state-C3OtgG94.mjs} +14 -7
- package/dist/{detached-entry-KmieOKgN.mjs → detached-entry-BPlSaCwC.mjs} +1 -1
- package/dist/{dev-client-CHoXXZeg.mjs → dev-client-BMca82xo.mjs} +2 -2
- package/dist/{device-F5-4z9ef.mjs → device-BJm0irrq.mjs} +16 -16
- package/dist/{device-capacity-ZYaRALv5.mjs → device-capacity-6LP7QsaA.mjs} +103 -25
- package/dist/device-host-worker.mjs +19 -21
- package/dist/{device-ios-DkHBrmvH.mjs → device-ios-534c14fz.mjs} +288 -28
- package/dist/{device-lease-run-ogEeJ62K.mjs → device-lease-run-DwsGfjUN.mjs} +5 -5
- package/dist/{device-pool-BIg8MU8l.mjs → device-pool-BnQqvs6o.mjs} +3 -3
- package/dist/{device-B9FqTBYW.mjs → device-tM41-TUq.mjs} +25 -24
- package/dist/{doctor-A_Nr_fDe.mjs → doctor-Dbx1ZpD2.mjs} +1 -1
- package/dist/{doctor-k3P3PizH.mjs → doctor-DyqE9n1J.mjs} +28 -16
- package/dist/{doctor-Bm8TVpGn.mjs → doctor-F-3VUUyN.mjs} +128 -35
- package/dist/{doctor-fingerprint-zlujA1Gs.mjs → doctor-fingerprint-o7ZI9YLn.mjs} +9 -3
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-watchman-BovI1y3-.mjs → doctor-watchman-CxDbyrrt.mjs} +5 -5
- package/dist/{eas-build-CyDKNTBP.mjs → eas-build-CjNSWmjo.mjs} +4 -4
- package/dist/eas-fallback-9fqb46kW.mjs +87 -0
- package/dist/{eas-session-ledger-BMCA1gdO.mjs → eas-session-ledger-DrP4OuuM.mjs} +6 -6
- package/dist/{error-diagnostics-B1Mj_-7h.mjs → error-diagnostics-snej9k4j.mjs} +51 -25
- package/dist/{exec-VFRpu1iA.mjs → exec-aULwtNly.mjs} +57 -6
- package/dist/{gc-eaz403W6.mjs → gc-BRwAY3qT.mjs} +2 -2
- package/dist/{gc-B9jcnmIk.mjs → gc-CGZ1Yg88.mjs} +218 -72
- package/dist/{guide-DR0K0xW9.mjs → guide-_rfEh_zM.mjs} +839 -222
- package/dist/{hosted-android-Bvb2-ZxD.mjs → hosted-android-BMKzUNnY.mjs} +4 -4
- package/dist/{hosted-client-rsRqysJc.mjs → hosted-client-D7Pk_Oo1.mjs} +13 -9
- package/dist/{hosted-logs-CWKGYWNX.mjs → hosted-logs-B1gqQuva.mjs} +18 -12
- package/dist/hosted-logs-sync-Dg3qrZmV.mjs +195 -0
- package/dist/{hosted-macos-d0pv9Tth.mjs → hosted-macos-B9w4H8hc.mjs} +6 -6
- package/dist/{hosted-native-BxTizGU2.mjs → hosted-native-CdgaiuyP.mjs} +17 -17
- package/dist/{idle-shutdown-BIyfl0Zj.mjs → idle-shutdown-Cbvo5KEh.mjs} +21 -9
- package/dist/{ios-BRVM8b0P.mjs → ios-B5HlVMhQ.mjs} +138 -55
- package/dist/{ios-Dvt97HgQ.mjs → ios-Bk4mWbtS.mjs} +8 -8
- package/dist/{ios-ENC4sRPA.mjs → ios-CsRVik64.mjs} +7 -1
- package/dist/{ios-BQzvJlzw.mjs → ios-E26qSpkb.mjs} +94 -11
- package/dist/{ios-device-CKSvk0bu.mjs → ios-device-C_QkIf1Z.mjs} +3 -3
- package/dist/{ios-device-B6HK951C.mjs → ios-device-CiBA-er9.mjs} +1 -1
- package/dist/{ios-project-DCUDo06I.mjs → ios-project-D8Jcy_br.mjs} +22 -9
- package/dist/{ios-signing-4c_qXvQm.mjs → ios-signing-BJzvDPfU.mjs} +2 -2
- package/dist/{ios-state-CT9nV5SP.mjs → ios-state-BZ03NFgF.mjs} +1 -1
- package/dist/{js-swap-Z9HbC4cj.mjs → js-swap-Dg2a945i.mjs} +8 -7
- package/dist/{launch-D0lPvFFu.mjs → launch-CRyBeNsA.mjs} +53 -44
- package/dist/lightened-BCsdAGj_.mjs +171 -0
- package/dist/{logs-BsIRre8x.mjs → logs-CC_-ZzEE.mjs} +10 -174
- package/dist/{logs-Crs9y34Z.mjs → logs-aJQb-RDg.mjs} +112 -38
- package/dist/{macos-CcUlJPMu.mjs → macos-BGmTpnv9.mjs} +1 -1
- package/dist/{macos-D477nfzH.mjs → macos-DlCBhMw5.mjs} +73 -39
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +30 -13
- package/dist/{metro-1pJgCX4U.mjs → metro-CvyD-xwe.mjs} +4 -4
- package/dist/{metro-gateway-Bp9gJQAN.mjs → metro-gateway-BnHdqMO_.mjs} +3 -4
- package/dist/{named-ports-BVbn8SvC.mjs → named-ports-BCyMWA6b.mjs} +3 -3
- package/dist/{native-android-BvMizJn1.mjs → native-android-DlpxCyOP.mjs} +17 -18
- package/dist/{native-gradle-artifact-inputs-BJscK4vN.mjs → native-gradle-artifact-inputs-C13qT7R_.mjs} +5 -5
- package/dist/{native-runtime-B9w_Qyz3.mjs → native-runtime-DqaIBO5w.mjs} +9 -9
- package/dist/{native-source-D-4Dh4JU.mjs → native-source-D1AzWiuP.mjs} +1 -1
- package/dist/{native-xcode-inputs-Cv4l-obn.mjs → native-xcode-inputs-B1W8SrxB.mjs} +3 -3
- package/dist/{native-xcode-ios-DGrg90hE.mjs → native-xcode-ios-QPP0Rm68.mjs} +17 -18
- package/dist/{ndjson-CgE_o3Dl.mjs → ndjson-Dy2W4vRa.mjs} +2 -2
- package/dist/offload-worker.d.mts +3 -1
- package/dist/offload-worker.mjs +34 -25
- package/dist/{operation-exec-CUZifp6Z.mjs → operation-exec-Dp4FuIGR.mjs} +1 -1
- package/dist/{ownership-jxxz-19m.mjs → ownership-Bx-0cku-.mjs} +3 -3
- package/dist/{page-CzEA_-5_.mjs → page-CQJlcj3x.mjs} +2 -2
- package/dist/{phone-reverses-CYb7RRAx.mjs → phone-reverses-C9yAaKEv.mjs} +18 -4
- package/dist/{placement-log-DjOXJRIH.mjs → placement-log-BXUbiZM6.mjs} +3 -3
- package/dist/{plan-placement-BqKgKHCi.mjs → plan-placement-UxnQjv5Z.mjs} +36 -10
- package/dist/{ports-DtS1Amb0.mjs → ports-uUrghqWN.mjs} +3 -3
- package/dist/prebuild-BDpToDgR.mjs +1246 -0
- package/dist/{project-BiC68mIp.mjs → project-DYj-HVx6.mjs} +17 -18
- package/dist/{pull-request-CbNlkFok.mjs → pull-request-BzLmzAIQ.mjs} +2 -2
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-DRYqoJc4.mjs → react-native-android-DDBccgJw.mjs} +56 -36
- package/dist/{react-native-build-CwZB-agu.mjs → react-native-build-DaK2IFyP.mjs} +9 -9
- package/dist/{react-native-doctor-BCrytK7h.mjs → react-native-doctor-B-Mw6DcR.mjs} +50 -9
- package/dist/{react-native-ios-Cr1buNFo.mjs → react-native-ios-DjYwUF9U.mjs} +45 -25
- package/dist/{recordings-BaoQ0t-J.mjs → recordings-C20iUZfp.mjs} +1 -1
- package/dist/{registration-CN6nlhcD.mjs → registration-BwCe64PH.mjs} +1 -1
- package/dist/{reload-Beftw2X3.mjs → reload-DJBeF_rC.mjs} +1 -1
- package/dist/{reload-FbSgMF8x.mjs → reload-fUdkH2_p.mjs} +16 -16
- package/dist/{remote-BuZj6AyU.mjs → remote-y6n99WMW.mjs} +22 -9
- package/dist/{result-CR2vk2cj.mjs → result-CTqBw2Te.mjs} +32 -21
- package/dist/{run-BtzE09Dl.mjs → run-DaCeNKRm.mjs} +3 -3
- package/dist/{selection-D5cxEl3t.mjs → selection-Bs8phwhN.mjs} +183 -62
- package/dist/{server-bare-CH9X0RLn.mjs → server-bare-BOh-iZEj.mjs} +2 -2
- package/dist/{server-command-CaBbDNU2.mjs → server-command-8CuA51Cv.mjs} +6 -6
- package/dist/{server-expo-Ck8EIidM.mjs → server-expo-ABQs2XFA.mjs} +4 -4
- package/dist/server-expo-Ba_Y21vB.mjs +2 -0
- package/dist/{settings-B5tCoq9N.mjs → settings-BDVI8Ivc.mjs} +331 -62
- package/dist/{settings-DzH9mGQZ.mjs → settings-CMHhQNwI.mjs} +24 -3
- package/dist/settings-payload-cm60Zhib.mjs +257 -0
- package/dist/settings-write-BdNRLlBn.mjs +185 -0
- package/dist/settings.schema.json +84 -39
- package/dist/{simslim-BjxszUAb.mjs → simslim-DCQwzoPy.mjs} +4 -3
- package/dist/{slot-launch-QeuJMlnJ.mjs → slot-launch-0l7RqSpr.mjs} +6 -6
- package/dist/{stage-D8xlRU2D.mjs → stage-F4cAfJGi.mjs} +2 -2
- package/dist/{start-C1JLjkNw.mjs → start-DcqnF9p8.mjs} +1 -1
- package/dist/{start-YMpNwLhh.mjs → start-DrPwER_2.mjs} +27 -23
- package/dist/{state-DMRNP7-4.mjs → state-BX1y5syV.mjs} +4 -5
- package/dist/{state-DPaM3u5K.mjs → state-CZxLyetD.mjs} +2 -3
- package/dist/{stats-CP7STzZw.mjs → stats-GxuCbles.mjs} +5 -5
- package/dist/{stats-report-n2U5plhk.mjs → stats-report-B86Cv7Uc.mjs} +1 -1
- package/dist/{status-Fect2w9R.mjs → status-7ULDEJ1e.mjs} +1 -1
- package/dist/{status-CRLiJ-O_.mjs → status-BfnK9pUd.mjs} +25 -26
- package/dist/{status-cNw6i0_t.mjs → status-Bj7ZYvvc.mjs} +1 -1
- package/dist/{status-watch-Bc2J4TZn.mjs → status-watch-BfabQn03.mjs} +5 -5
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-DS0mzR8U.mjs → stim-desktop-CbWo21kb.mjs} +2 -2
- package/dist/{stop-COP6PQqw.mjs → stop-CH79S3IZ.mjs} +5 -6
- package/dist/{stop-Db9Kh-UA.mjs → stop-D-EAr25B.mjs} +25 -22
- package/dist/{stop-Br7LKxBE.mjs → stop-x1Yu3He4.mjs} +2 -2
- package/dist/supervisor-run.d.mts +1 -0
- package/dist/supervisor-run.mjs +17 -18
- package/dist/{support-qKcbgmI5.mjs → support-Be0UeVZU.mjs} +10 -10
- package/dist/{support-Cxj9CmII.mjs → support-CNg_YsOk.mjs} +6 -6
- package/dist/{swiftpm-artifact-inputs-iY9fsmOc.mjs → swiftpm-artifact-inputs-uPqYvGBv.mjs} +4 -4
- package/dist/{swiftpm-macos-Bp_sn9P4.mjs → swiftpm-macos-Ch4YjY_A.mjs} +11 -12
- package/dist/toolchain-CbCG6C5Z.mjs +2413 -0
- package/dist/toolchain-JYAOquPg.mjs +2 -0
- package/dist/{trigger-CBMe2YLH.mjs → trigger-DMou-X7j.mjs} +3 -3
- package/dist/trigger-qp2ji5wE.mjs +2 -0
- package/dist/{warm-progress-BV3ZPmcY.mjs → warm-progress-C0RsbngN.mjs} +731 -728
- package/dist/{web-B4Yjyt1G.mjs → web-Cq_AQ4DK.mjs} +9 -10
- package/dist/web-Je6abcpz.mjs +2 -0
- package/dist/web-run.mjs +9 -9
- package/dist/windows-report.mjs +1 -1
- package/dist/{workspace-state-CPSp3mav.mjs → workspace-state-BjqdjnJR.mjs} +46 -8
- package/dist/{workspaces-C9w4aeXF.mjs → workspaces-DFbj07jp.mjs} +1801 -76
- package/dist/{worktree-CclFIe1Z.mjs → worktree-COAJ3-OD.mjs} +934 -511
- package/dist/{worktree-Ct9Gk3KL.mjs → worktree-JGUd_53L.mjs} +1 -1
- package/package.json +8 -8
- package/dist/ccache-h1FKhZeg.mjs +0 -143
- package/dist/created-devices-D2Aca-xu.mjs +0 -52
- package/dist/eas-fallback-gaZi-dJL.mjs +0 -381
- package/dist/hosted-ios-RtVcJH3u.mjs +0 -15
- package/dist/native-run-D5OJsGwA.mjs +0 -276
- package/dist/paths-DQtTgsBf.mjs +0 -42
- package/dist/prebuild-JUaqOLpc.mjs +0 -501
- package/dist/server-expo-C16Zf2k7.mjs +0 -2
- package/dist/settings-write-n0zwfohx.mjs +0 -360
- package/dist/toolchain-DB1aeqxO.mjs +0 -2
- package/dist/toolchain-VzLJzZ7O.mjs +0 -908
- package/dist/trigger-BLsHgAGR.mjs +0 -2
- package/dist/web-DS4UDWvf.mjs +0 -2
- package/dist/xcode-CiIIDnuD.mjs +0 -910
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-
|
|
2
|
-
import { i as findProjectRoot$1 } from "./project-
|
|
3
|
-
import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-
|
|
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-BDVI8Ivc.mjs";
|
|
2
|
+
import { i as findProjectRoot$1 } from "./project-DYj-HVx6.mjs";
|
|
3
|
+
import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-DrP4OuuM.mjs";
|
|
4
|
+
import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-CxDbyrrt.mjs";
|
|
5
|
+
import "./status-watch-BfabQn03.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
|
|
@@ -188,6 +188,11 @@ RULES DURING THE LOOP
|
|
|
188
188
|
you do other work.
|
|
189
189
|
- Run ios or android again after a native input changes. A JavaScript-only
|
|
190
190
|
change does not need one.
|
|
191
|
+
- The build cache counts an installed package by its name and version, so it
|
|
192
|
+
cannot see a file you edit inside node_modules/. Change a dependency's native
|
|
193
|
+
code with a patch (patch-package or pnpm patch), which is hashed, or run ios or
|
|
194
|
+
android with --no-build-cache --remote-build local to compile it here. See
|
|
195
|
+
guide lifecycle builds.
|
|
191
196
|
- For stale Metro transforms or file-map state, use stim start --reset-cache.
|
|
192
197
|
It restarts only this app's verified owned Metro, preserving devices and other
|
|
193
198
|
apps' caches. See guide lifecycle for reset scope.
|
|
@@ -292,16 +297,20 @@ reserved named ports, even outside the workspace. Read guide ports before use.
|
|
|
292
297
|
|
|
293
298
|
Ask the user before these actions:
|
|
294
299
|
|
|
295
|
-
- worktree remove
|
|
296
|
-
device. It works with any linked worktree, warmed or not, without requiring
|
|
300
|
+
- worktree remove of a worktree you did not create, because it deletes the
|
|
301
|
+
worktree and gives up its owned device. It works with any linked worktree, warmed or not, without requiring
|
|
297
302
|
a Stim registry entry. Git-created branches are kept; a branch with an
|
|
298
303
|
existing Stim ownership record is deleted only when it has no unique commits.
|
|
299
304
|
- worktree remove --force, because it also discards uncommitted and untracked
|
|
300
305
|
files.
|
|
301
306
|
- gc --delete, because it deletes orphaned resources, removes clean linked
|
|
302
307
|
worktrees whose branch or pull request is merged (or whose pull request
|
|
303
|
-
was closed), and
|
|
304
|
-
|
|
308
|
+
was closed), and lightens every workspace that is not building and ran
|
|
309
|
+
no ios, android or macos command in the last 15 minutes, a running dev
|
|
310
|
+
server included, by clearing its build outputs and its git-ignored
|
|
311
|
+
in-tree build directories, and deletes node_modules and ios/Pods of idle
|
|
312
|
+
linked worktrees, which the next start, ios or android restores with
|
|
313
|
+
worktree warm. Run stim gc --json first and show
|
|
305
314
|
the user the entries its sections list (guide facts gc). gc --delete
|
|
306
315
|
--cache all empties the shared build caches and those outputs instead, and
|
|
307
316
|
gc --delete --cache workspaces clears only the outputs; both inspect
|
|
@@ -322,8 +331,10 @@ Ask the user before these actions:
|
|
|
322
331
|
|
|
323
332
|
LEAVE THE MACHINE CLEAN
|
|
324
333
|
|
|
325
|
-
Run stim stop when you pause or finish a task, and stim worktree remove
|
|
326
|
-
|
|
334
|
+
Run stim stop when you pause or finish a task, and stim worktree remove on
|
|
335
|
+
the worktree you created once its work is merged or abandoned. Keep scratch
|
|
336
|
+
files, test output and downloads outside the worktree: a stray untracked file
|
|
337
|
+
blocks that removal, and automatic cleanup then has to archive it. Never create a simulator or emulator by hand;
|
|
327
338
|
every device comes from Stim. Before starting a new workspace, check stim
|
|
328
339
|
status for an idle workspace to reuse and confirm capacity headroom instead of
|
|
329
340
|
adding another. Never quit Device Hub or Simulator.app: on Xcode 27
|
|
@@ -395,7 +406,7 @@ FULL TOPIC LIST
|
|
|
395
406
|
stim guide errors fallbacks # swap, cache, and install notes on a release cache hit
|
|
396
407
|
stim guide lifecycle # the ordered flow, consent rules, and capacity
|
|
397
408
|
stim guide lifecycle verification # reproduce, edit, verify the UI, and retain proof
|
|
398
|
-
stim guide lifecycle readiness # add
|
|
409
|
+
stim guide lifecycle readiness # add recommended app readiness logs; no package required
|
|
399
410
|
stim guide lifecycle builds # build optimizations, optional cache warm-up, fingerprints
|
|
400
411
|
stim guide lifecycle concurrency # shared builds, wait timeouts, capacity limits
|
|
401
412
|
stim guide lifecycle budget # disk and memory budgets, automatic reclaim
|
|
@@ -1009,7 +1020,7 @@ leased until <time>" for each one.`,
|
|
|
1009
1020
|
JavaScript running -- the first screen may
|
|
1010
1021
|
still be rendering\` (\`stable for 3s\` when
|
|
1011
1022
|
no \`Running\` log arrived). Poll the UI
|
|
1012
|
-
before you trust a screenshot.
|
|
1023
|
+
before you trust a screenshot. Recommended
|
|
1013
1024
|
app-declared readiness adds a separate
|
|
1014
1025
|
stderr readiness phase; it does not change
|
|
1015
1026
|
this field. See
|
|
@@ -1256,13 +1267,27 @@ leased until <time>" for each one.`,
|
|
|
1256
1267
|
pins Node (bin, version and match are null when no install
|
|
1257
1268
|
fits the pin; match is "exact", or "major" for the newest
|
|
1258
1269
|
install of the pinned major not older than the pin), else null
|
|
1259
|
-
remoteMachines one { machine, state, dnsName?, deviceId?, requestedAt?,
|
|
1270
|
+
remoteMachines one { machine, state, diagnosis?, dnsName?, deviceId?, requestedAt?,
|
|
1260
1271
|
expiresAt?, offloadable?, reasons?, problems?, capacity?, host? } per
|
|
1261
1272
|
remote.machines entry, for its build approval; state is "approved", "pending", "not-asked",
|
|
1262
1273
|
"revoked" (revoked or denied), "lapsed" (the request lapsed
|
|
1263
1274
|
before approval), "key-changed", "outdated",
|
|
1264
1275
|
"not-on-tailnet", "tailscale-off", "unreachable" or
|
|
1265
|
-
"invalid".
|
|
1276
|
+
"invalid". diagnosis is { layer, code, title, message, remedy }
|
|
1277
|
+
for the first layer that stopped this machine, present for
|
|
1278
|
+
"tailscale-off", "not-on-tailnet", "outdated" and "unreachable"
|
|
1279
|
+
(deviceHosts carries it too); the codes are
|
|
1280
|
+
tailscale-stopped, tailscale-logged-out, tailscale-unavailable
|
|
1281
|
+
(this machine's Tailscale), peer-not-found, peer-ambiguous,
|
|
1282
|
+
peer-offline (with last seen), peer-no-answer (the connection
|
|
1283
|
+
got no reply and tailscale ping fails), route-missing (nothing accepts
|
|
1284
|
+
connections on the serve port), route-tls, route-http-error
|
|
1285
|
+
(any HTTP status but 502 and 503), server-not-running (502:
|
|
1286
|
+
nothing behind the route), server-not-ready (503: running but
|
|
1287
|
+
not serving; its message gives the cause the server reports),
|
|
1288
|
+
server-no-answer (silent route while tailscale ping reaches the Mac), server-outdated and connect-failed (none of the above).
|
|
1289
|
+
Tailscale's own "offline" flag lags a reachable peer, so an
|
|
1290
|
+
answer from the machine outranks it. host has the same shape and presence rule as in
|
|
1266
1291
|
deviceHosts, as do expiresAt (a pending request's lapse
|
|
1267
1292
|
time) and "lapsed" (--fix asks again). An approved machine also carries offloadable,
|
|
1268
1293
|
true when it would take this app's builds now (iOS
|
|
@@ -1278,7 +1303,16 @@ leased until <time>" for each one.`,
|
|
|
1278
1303
|
checkout, stim-build, arch, xcode, simulator-sdk, macos-sdk,
|
|
1279
1304
|
cocoapods, bundler, runtime, jdk, android-sdk, ndk,
|
|
1280
1305
|
build-tools, compile-sdk, disk, busy or platform). problems lists the same
|
|
1281
|
-
reasons as { code, reason } with that code
|
|
1306
|
+
reasons as { code, reason } with that code; an ndk, build-tools,
|
|
1307
|
+
compile-sdk, jdk, xcode or runtime problem can also carry commands and a
|
|
1308
|
+
lead, the lines to run on that machine (sdkmanager, the JDK install,
|
|
1309
|
+
xcode-select, xcodebuild or xcodes) and what they do, or followsFrom, the
|
|
1310
|
+
code of the problem whose fix also clears it. notes lists what a build there does without stopping:
|
|
1311
|
+
{ code, reason, commands, lead } for an ndk, build-tools or compile-sdk package its
|
|
1312
|
+
Android SDK lacks and Gradle downloads on the first build (licenses
|
|
1313
|
+
accepted there, no android.builder.sdkDownload=false in the app), with the sdkmanager
|
|
1314
|
+
command that installs it ahead of time; each
|
|
1315
|
+
also a build-machine-<code> finding at level note. capacity
|
|
1282
1316
|
is the machine's offer: { running, max, diskFreeBytes,
|
|
1283
1317
|
minDiskFreeBytes, cpus?, loadPerCore?, builds?, maxBuilds?,
|
|
1284
1318
|
maxLoadPerCore?, memoryUsedBytes?, memoryTotalBytes?, declined? }; an older stim-server omits the
|
|
@@ -1289,6 +1323,7 @@ leased until <time>" for each one.`,
|
|
|
1289
1323
|
with an abnormally large footprint and, when it is safe to
|
|
1290
1324
|
restart, the command
|
|
1291
1325
|
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
|
|
1326
|
+
readiness-markers-missing is a note when no JS or TS source under the app directory contains [stim:readiness]; the scan skips node_modules, native and build output directories and dot-directories, and reports nothing past 5000 source files; see stim guide lifecycle readiness
|
|
1292
1327
|
|
|
1293
1328
|
ON FAILURE
|
|
1294
1329
|
\`start\`, \`ios\`, \`android\` and \`web\` all print the error contract instead,
|
|
@@ -1306,7 +1341,8 @@ ON FAILURE
|
|
|
1306
1341
|
An \`ios\` or \`android\` run that \`stim stop\` or Ctrl-C interrupted
|
|
1307
1342
|
reports STIM_CANCELLED and exits 130. A
|
|
1308
1343
|
run that exits on the interrupt at once (a second Ctrl-C, or Ctrl-C with no
|
|
1309
|
-
build tool
|
|
1344
|
+
build tool, SimSlim, launch readiness wait or hosted app delivery to stop)
|
|
1345
|
+
exits 130 with no payload.
|
|
1310
1346
|
|
|
1311
1347
|
\`stop --json\` prints { root, ok, supervisor, collectors, metro, device,
|
|
1312
1348
|
port, metroTunnel, releasedLeases, macos? }. macos is { status: stopped | failed,
|
|
@@ -1503,7 +1539,8 @@ RULES
|
|
|
1503
1539
|
why) or "failed" (detail says why and what to retry).
|
|
1504
1540
|
kind: device, parkedDevice, parkedHostedDevice, idleDevice,
|
|
1505
1541
|
deviceRecord,
|
|
1506
|
-
workspaceOutputs,
|
|
1542
|
+
workspaceOutputs, worktreeDependencies, recording,
|
|
1543
|
+
workspaceDirectory, project,
|
|
1507
1544
|
buildLock, buildSlot, deviceLease, easSession, worktree,
|
|
1508
1545
|
cache, gradleVersion, tempLeftover (one "done" labelled
|
|
1509
1546
|
with the TMPDIR it cleared, plus a "kept" or "failed" per
|
|
@@ -1571,9 +1608,9 @@ RULES
|
|
|
1571
1608
|
else null. buildState is { bytes, dirs:
|
|
1572
1609
|
{ path, bytes } } for the in-tree build and
|
|
1573
1610
|
dependency directories automatic maintenance
|
|
1574
|
-
clears (
|
|
1575
|
-
android
|
|
1576
|
-
|
|
1611
|
+
clears (android/app/build, android/build,
|
|
1612
|
+
android/.gradle, .build, node_modules,
|
|
1613
|
+
ios/Pods, at the root, a
|
|
1577
1614
|
project root, or apps/* and packages/* for
|
|
1578
1615
|
build directories) and a root .pnpm-store,
|
|
1579
1616
|
paths relative to the worktree, largest
|
|
@@ -1672,18 +1709,29 @@ RULES
|
|
|
1672
1709
|
Metro, client and device logs over twice the
|
|
1673
1710
|
8 MiB cap; willTrim marks the ones it would
|
|
1674
1711
|
trim
|
|
1712
|
+
worktreeDependencies { path, willDelete, detail } node_modules and
|
|
1713
|
+
ios/Pods of linked worktrees; willDelete marks
|
|
1714
|
+
the ones --delete would lighten, and detail
|
|
1715
|
+
says why the others stay. Sizes are not
|
|
1716
|
+
measured: APFS clones make them misleading
|
|
1675
1717
|
recordings { dir, projectRoot, bytes, deleteBytes,
|
|
1676
1718
|
willDelete, withWorkspace, reason, detail }
|
|
1677
1719
|
recordings/ of each workspace; deleteBytes is
|
|
1678
1720
|
what --delete would remove; withWorkspace
|
|
1679
1721
|
marks those of a gone workspace, removed with
|
|
1680
1722
|
its workspace directory
|
|
1681
|
-
workspaceBuildOutputs { dir, projectRoot, bytes, idleDays,
|
|
1682
|
-
reason, detail } derived-data,
|
|
1683
|
-
android-cas, cache-provider,
|
|
1684
|
-
macos/<Product>.app and
|
|
1685
|
-
|
|
1686
|
-
|
|
1723
|
+
workspaceBuildOutputs { dir, projectRoot, inTreeDirs, bytes, idleDays,
|
|
1724
|
+
willClear, reason, detail } derived-data,
|
|
1725
|
+
gradle-build, android-cas, cache-provider,
|
|
1726
|
+
macos/build, macos/<Product>.app and
|
|
1727
|
+
macos/staging-* of each workspace; inTreeDirs
|
|
1728
|
+
lists the project's android/app/build,
|
|
1729
|
+
android/build,
|
|
1730
|
+
android/.gradle and .build that --delete
|
|
1731
|
+
clears with them, every file in them
|
|
1732
|
+
ignored by git and none tracked, and
|
|
1733
|
+
bytes includes them; willClear marks the ones
|
|
1734
|
+
--delete would lighten; --cache workspaces omits the
|
|
1687
1735
|
directories that --delete removes whole (dead
|
|
1688
1736
|
projects and orphanedWorkspaces), and --cache
|
|
1689
1737
|
all does not
|
|
@@ -1742,11 +1790,13 @@ RULES
|
|
|
1742
1790
|
bytes, willDelete, kept }] } | null ignored
|
|
1743
1791
|
directories worktree remove moved out of a
|
|
1744
1792
|
worktree into $STIM_HOME/trash before git
|
|
1745
|
-
removed it
|
|
1793
|
+
removed it, and paths worktree warm moved out
|
|
1794
|
+
of a copy. bytes is null while a removal is
|
|
1746
1795
|
deleting the entry. kept names the live or
|
|
1747
1796
|
unresolved ownership claim, the missing or
|
|
1748
1797
|
invalid trash.json, or the worktree that
|
|
1749
|
-
still exists
|
|
1798
|
+
still exists (not for a warm entry), that
|
|
1799
|
+
keeps a directory;
|
|
1750
1800
|
--delete deletes the rest, only remove-*
|
|
1751
1801
|
entries with a valid trash.json. null when the
|
|
1752
1802
|
trash is empty or under any --cache scope
|
|
@@ -2244,6 +2294,10 @@ RULES
|
|
|
2244
2294
|
build: ios compile on janics-mac-mini (build, 2m10s), 3m05s elapsed
|
|
2245
2295
|
build: ios launch (bundling JS 45%, 12s), 58s elapsed
|
|
2246
2296
|
|
|
2297
|
+
The machine keeps every native build run, not only the latest, in
|
|
2298
|
+
$STIM_HOME/builds/builds.ndjson (newest 500), read with
|
|
2299
|
+
\`stim logs --source builds --json\` (\`guide logs\`, BUILD LEDGER).
|
|
2300
|
+
|
|
2247
2301
|
An environment with a recorded run also carries lastBuilds, each
|
|
2248
2302
|
platform's most recent ios or android run, finished or failed:
|
|
2249
2303
|
|
|
@@ -2440,6 +2494,8 @@ RULES
|
|
|
2440
2494
|
lastPass carries startedAt, durationMs, trigger, mode, freedBytes
|
|
2441
2495
|
(0 in report mode), actions, stopped (0), blocked. recent holds the last 20 action, failure
|
|
2442
2496
|
and blocked NDJSON records from maintenance/maintenance.ndjson.
|
|
2497
|
+
What each run cleared, kept or failed is in $STIM_HOME/gc/gc.ndjson,
|
|
2498
|
+
read with \`stim logs --source gc --json\` (\`guide logs\`, GC LOG).
|
|
2443
2499
|
invalid names invalid settings; invalid cache caps use their defaults,
|
|
2444
2500
|
while invalid maintenance settings disable passes. claim contains an
|
|
2445
2501
|
unresolved claim's path and reason, plus removeCommand from the claim
|
|
@@ -2519,9 +2575,10 @@ RULES
|
|
|
2519
2575
|
plan does not, so changes compare the fingerprint before that
|
|
2520
2576
|
prebuild; changeCount 0 then means those inputs match the
|
|
2521
2577
|
baseline. rekeyedBy is empty.
|
|
2522
|
-
placement with ios.remote or android.remote set to auto
|
|
2523
|
-
where the plan assumes the device runs:
|
|
2524
|
-
"this machine;
|
|
2578
|
+
placement with ios.remote or android.remote set to auto, remote,
|
|
2579
|
+
remote-only or a Mac, where the plan assumes the device runs:
|
|
2580
|
+
"on <machine>" or "this machine; <word> may use <machines>";
|
|
2581
|
+
absent otherwise
|
|
2525
2582
|
refusal { code, message, remedy } when the run would refuse:
|
|
2526
2583
|
STIM_PREBUILD_FAILED for a tracked native dir the fingerprint
|
|
2527
2584
|
leaves out, STIM_EAS_BUILD_MISSING for an EAS miss
|
|
@@ -2676,9 +2733,9 @@ BUILD PLACEMENT (\`offload\`)
|
|
|
2676
2733
|
decision is "here", "offloaded", or "fell-back" (it tried a remote machine
|
|
2677
2734
|
and built here). reason is why: the run's \`placement:\` reason, such as
|
|
2678
2735
|
"load 0.6/core, 1 of 3 build slots busy here" (auto keeps the build here
|
|
2679
|
-
while this machine has room) or "remote
|
|
2736
|
+
while this machine has room) or "--remote-build local" (which prints no line),
|
|
2680
2737
|
or for a fallback the cause, prefixed by the machine it concerns, such as
|
|
2681
|
-
"mini:
|
|
2738
|
+
"mini: saturated: load 2.4/core there, at or above 2/core". buildMs is the compile here, or the offloaded build's
|
|
2682
2739
|
total (offer, sync, build and fetch); localEstimateMs is this project's
|
|
2683
2740
|
last cold build here before the run. A run that hits the cache or waits
|
|
2684
2741
|
for another workspace's build compiles nothing and records none.
|
|
@@ -3168,6 +3225,8 @@ FLAGS
|
|
|
3168
3225
|
shared untagged Metro and app client records (not the web
|
|
3169
3226
|
page's); default also includes untagged legacy records
|
|
3170
3227
|
--source <s...> metro, client, device, build, agent, maintenance, placement (one or more), or all.
|
|
3228
|
+
gc alone reads the machine-wide gc log (GC LOG below);
|
|
3229
|
+
builds alone reads the machine-wide build ledger (BUILD LEDGER below).
|
|
3171
3230
|
An unknown value is REJECTED rather than quietly matching
|
|
3172
3231
|
nothing.
|
|
3173
3232
|
--level <l> minimum level: debug, info, warn, error, fatal
|
|
@@ -3220,7 +3279,8 @@ serve bounded log queries.
|
|
|
3220
3279
|
SecTrust, WebKit, CoreUI) that have nothing to do with your app. The proven
|
|
3221
3280
|
ones are demoted to info by the collector, and iOS main-thread
|
|
3222
3281
|
"Synchronous URL loading" performance diagnostics (Expo icons served by
|
|
3223
|
-
Metro raise them)
|
|
3282
|
+
Metro raise them) and SwiftUI "Invalid Configuration" faults (the Expo dev
|
|
3283
|
+
launcher raises them for a duplicated server entry) to warn, so a launch does not count them as app errors;
|
|
3224
3284
|
the scope rule covers the rest.
|
|
3225
3285
|
The metro stream carries exactly one demotion of its own, and it is Stim's
|
|
3226
3286
|
doing: the dev-client deep link \`ios\`/\`android\` open to wire the app to
|
|
@@ -3338,12 +3398,99 @@ THE RECORD
|
|
|
3338
3398
|
there are none. Stim adds it at query time; it is not in the
|
|
3339
3399
|
log files.
|
|
3340
3400
|
|
|
3401
|
+
IOS BOOT RECORDS
|
|
3402
|
+
Booting an owned iOS simulator writes records to the workspace's device.ndjson:
|
|
3403
|
+
src device, platform ios, deviceId the simulator udid, slot when it is not
|
|
3404
|
+
default, level info unless noted. They show in a plain \`logs\` and in
|
|
3405
|
+
\`--source device\`, and never in \`--errors\`.
|
|
3406
|
+
event ios_boot, with phase:
|
|
3407
|
+
boot_requested just before simctl boot; boot is adopted (a parked
|
|
3408
|
+
simulator), created, existing (an owned simulator
|
|
3409
|
+
that was shut down) or restart
|
|
3410
|
+
bootstatus_done simctl bootstatus -b returned
|
|
3411
|
+
springboard_started SpringBoard finished starting; pid is its pid
|
|
3412
|
+
viewer_opened the simulator viewer was asked to open it
|
|
3413
|
+
simslim_reboot SimSlim changed the simulator and SpringBoard's pid
|
|
3414
|
+
changed; pidBefore and pidAfter are null when the pid
|
|
3415
|
+
could not be read
|
|
3416
|
+
restart warn: SpringBoard is not running after boot and the
|
|
3417
|
+
simulator was shut down; Stim boots it once more
|
|
3418
|
+
event springboard_crash_reports, written before that restart and again if
|
|
3419
|
+
SpringBoard is still missing after it. files lists the SpringBoard-*.ips
|
|
3420
|
+
reports that name this simulator and were captured in the last ten minutes,
|
|
3421
|
+
copied from ~/Library/Logs/DiagnosticReports and its Retired folder into
|
|
3422
|
+
the workspace logs directory; level is warn, or info with an empty files
|
|
3423
|
+
when none matched. dropped counts matching reports that exceeded the limits
|
|
3424
|
+
below and were not copied; failure is the message of a write that failed,
|
|
3425
|
+
with the reports copied before it in files. macOS deletes the originals
|
|
3426
|
+
after about two days; Stim only reads that folder. It looks at the newest
|
|
3427
|
+
100 reports of at most 1 MiB each, copies at most 8 MiB per run, and keeps
|
|
3428
|
+
at most 40 in the directory.
|
|
3429
|
+
|
|
3341
3430
|
Maintenance records use src: maintenance and appear in the plain timeline.
|
|
3342
3431
|
stim logs --source maintenance
|
|
3343
3432
|
Add --errors to --source maintenance to show only maintenance_failure events;
|
|
3344
3433
|
failures before a later launch marker are hidden. Machine passes are reported in
|
|
3345
3434
|
status and maintenance/maintenance.ndjson; this command reads workspace logs.
|
|
3346
3435
|
|
|
3436
|
+
GC LOG
|
|
3437
|
+
stim logs --source gc reads $STIM_HOME/gc/gc.ndjson from any directory: one
|
|
3438
|
+
record per item that a gc run, a maintenance action or the budget gate
|
|
3439
|
+
cleared, kept or failed to clear. It cannot be combined with other sources,
|
|
3440
|
+
and --source all does not include it. --errors shows the failed items.
|
|
3441
|
+
Each record has src: gc, level (info, or error for a failed item), msg and
|
|
3442
|
+
runId the stim invocation, or the pass id of maintenance.ndjson
|
|
3443
|
+
trigger manual (stim gc in a terminal), desktop (STIM_DESKTOP_APP is set, so also a gc run through a stim-server Desktop started),
|
|
3444
|
+
maintenance, or budget (the disk, memory or workspace check before
|
|
3445
|
+
start, ios and android)
|
|
3446
|
+
via maintenance only: the command whose run started the pass
|
|
3447
|
+
options gc only: delete, worktrees, olderThan, cache, idleMs
|
|
3448
|
+
kind what the item was (the kind of gc --json results, plus devServer
|
|
3449
|
+
for a dev server the budget gate stops; maintenance also writes
|
|
3450
|
+
buildDirectory and dependencies)
|
|
3451
|
+
status done, kept or failed
|
|
3452
|
+
label, id, path, bytes, detail
|
|
3453
|
+
name, identifier, absolute path when the item is one, bytes freed,
|
|
3454
|
+
and the reason a kept or failed item was left
|
|
3455
|
+
Records of one run share runId. See stim guide cleanup, WHAT WAS CLEARED.
|
|
3456
|
+
|
|
3457
|
+
BUILD LEDGER
|
|
3458
|
+
stim logs --source builds reads $STIM_HOME/builds/builds.ndjson from any
|
|
3459
|
+
directory: one record per native build run (ios, android or macos; compiled
|
|
3460
|
+
here, offloaded or fetched from a cache; succeeded, failed or cancelled). It
|
|
3461
|
+
keeps the newest 500 records, outlives the workspace that ran the build, and
|
|
3462
|
+
is never removed by gc. It cannot be combined with other sources, and --source
|
|
3463
|
+
all does not include it. --errors shows the failed runs. A record has
|
|
3464
|
+
src: builds, event: build, level (info, warn for cancelled, error for failed),
|
|
3465
|
+
msg and
|
|
3466
|
+
ts, startedAt epoch milliseconds when the run finished and started
|
|
3467
|
+
id the run
|
|
3468
|
+
project, workspace, branch
|
|
3469
|
+
project root, workspace id and the branch checked out
|
|
3470
|
+
platform ios, android or macos
|
|
3471
|
+
scheme, variant, configuration
|
|
3472
|
+
the iOS scheme when one was selected, the Android variant,
|
|
3473
|
+
the build configuration
|
|
3474
|
+
placement { where: local | offloaded, machine?, fellBack?, reason? };
|
|
3475
|
+
machine is the build machine that compiled the app, and
|
|
3476
|
+
fellBack with reason marks a build that considered
|
|
3477
|
+
offloading and compiled here
|
|
3478
|
+
cache { result: hit | miss | bypassed, source?: local | remote,
|
|
3479
|
+
key, fingerprint, missReason? }
|
|
3480
|
+
durationMs, phases
|
|
3481
|
+
wall time and milliseconds in each local phase (prepare,
|
|
3482
|
+
cache-lookup, wait, prebuild, pods, compile, device,
|
|
3483
|
+
install, launch)
|
|
3484
|
+
offloadPhases milliseconds on the build machine: sync, deps, prebuild,
|
|
3485
|
+
pods, build, fetch
|
|
3486
|
+
outcome succeeded, failed or cancelled
|
|
3487
|
+
failure failed or cancelled runs: { code, message, remedy, phase }
|
|
3488
|
+
device { name, runtime? } of the simulator, emulator or device;
|
|
3489
|
+
never its serial or UDID
|
|
3490
|
+
stimVersion the stim that ran the build
|
|
3491
|
+
A run that stopped before it had an app to build (a refused flag, a missing
|
|
3492
|
+
project) writes no record. Writing the record never changes the run's result.
|
|
3493
|
+
|
|
3347
3494
|
REMOTE REQUEST RECORDS
|
|
3348
3495
|
A request to another machine that fails is a warn record with src: build in the
|
|
3349
3496
|
run's build log: remote_connect_failed { host, capability, ms, timeoutMs, msg,
|
|
@@ -3373,16 +3520,45 @@ Events: run_start, run_end { exit, ms }, exec { program, ms, ok, exit? }, and
|
|
|
3373
3520
|
remote_connect and remote_request { ms, ok, code? } for requests to another
|
|
3374
3521
|
machine. They carry no arguments, tokens or tickets.
|
|
3375
3522
|
|
|
3523
|
+
TIMING TRACES
|
|
3524
|
+
STIM_TRACE=<path> makes a stim command write a timeline of where it spent its
|
|
3525
|
+
time, as Chrome trace events. Open the file in Perfetto (ui.perfetto.dev) or
|
|
3526
|
+
chrome://tracing. Unset, nothing is written and no file is opened. There is no
|
|
3527
|
+
setting for it, and the trace goes only to that file, never to stdout or stderr.
|
|
3528
|
+
Use a new path for each command: the command you start truncates the file, and
|
|
3529
|
+
the processes it starts (a Metro supervisor, collectors, a nested stim) append
|
|
3530
|
+
to it.
|
|
3531
|
+
STIM_TRACE=/tmp/ios.json stim ios
|
|
3532
|
+
The file is a JSON array with one event per line and no closing bracket, so
|
|
3533
|
+
read it with JSON.parse(text.trimEnd().replace(/,$/, '') + ']'). Every event
|
|
3534
|
+
has pid; spans have ts and dur in microseconds since the epoch. Events:
|
|
3535
|
+
command one span named "stim <command>" with the exit code in args.exit
|
|
3536
|
+
exec one span per child process. args.argv (or args.command for a shell
|
|
3537
|
+
command) has the values of secret-looking flags, credentials in
|
|
3538
|
+
URLs and token shapes replaced by [redacted], and the credentials
|
|
3539
|
+
of curl -u and security import -P; other short flags such as -p
|
|
3540
|
+
and -u are kept. args also has cwd, ok, exit and signal
|
|
3541
|
+
phase the build phases of an ios, android or macos run on a
|
|
3542
|
+
"phases: <platform> build" track, named as in stats.json and the
|
|
3543
|
+
build ledger (prepare, cache-lookup, wait, prebuild, pods, compile,
|
|
3544
|
+
device, install, launch), and the steps of worktree warm
|
|
3545
|
+
span fingerprint, wait for metro and carry ignored entries
|
|
3546
|
+
mark instant events such as a fingerprint memo hit
|
|
3547
|
+
Children running at the same time are drawn on separate tracks. A span still
|
|
3548
|
+
open when its process exits is written with unfinished: true; a process ended
|
|
3549
|
+
by a signal writes none. A trace holds
|
|
3550
|
+
full paths and arguments, so treat it like a log.
|
|
3551
|
+
|
|
3376
3552
|
Placement records use src: placement and sit in the run's build log
|
|
3377
3553
|
(build-*.ndjson), so a new run replaces the previous run's. A run writes one
|
|
3378
3554
|
record per decision it makes (a build that compiles and has a remote machine to
|
|
3379
|
-
consider, or ios/android --remote auto), with event build_placement,
|
|
3555
|
+
consider, or ios/android --remote auto|remote|remote-only), with event build_placement,
|
|
3380
3556
|
device_placement or placement_fallback. A cache hit, a project with no paired
|
|
3381
3557
|
remote machine and a named --remote target write none:
|
|
3382
3558
|
stim logs --source placement
|
|
3383
3559
|
stim logs --source placement --json
|
|
3384
3560
|
Fields: kind (build or device), platform, settings [{ key, value, from }] with
|
|
3385
|
-
from flag, env, setting or default (remote.build
|
|
3561
|
+
from flag, env, setting or default (remote.build for a
|
|
3386
3562
|
build, ios.remote or android.remote, plus remote.easFallback when it is on, for
|
|
3387
3563
|
a device), candidates [{ machine, code,
|
|
3388
3564
|
msg, detail? }], choice { machine, code, msg } with machine local when the run
|
|
@@ -3403,6 +3579,10 @@ they stay in the local logs. These records carry no tokens.
|
|
|
3403
3579
|
|
|
3404
3580
|
WHAT WRITES WHAT
|
|
3405
3581
|
maintenance.ndjson workspace maintenance actions, failures and explaining skips
|
|
3582
|
+
$STIM_HOME/gc/gc.ndjson machine-wide, not in a workspace: what gc, maintenance
|
|
3583
|
+
and the budget gate cleared (stim logs --source gc)
|
|
3584
|
+
$STIM_HOME/builds/builds.ndjson machine-wide: the last 500 native builds
|
|
3585
|
+
(stim logs --source builds)
|
|
3406
3586
|
metro.ndjson the bundler, in every supervisor mode. Stim's
|
|
3407
3587
|
middleware adds one record per bundle request
|
|
3408
3588
|
(bundle_response_started, _progress, _finished,
|
|
@@ -3425,7 +3605,8 @@ WHAT WRITES WHAT
|
|
|
3425
3605
|
-- and, on iOS, where every Apple framework running in
|
|
3426
3606
|
the app's process also logs. The proven noise sources
|
|
3427
3607
|
are recorded at info rather than error (Synchronous
|
|
3428
|
-
URL loading diagnostics
|
|
3608
|
+
URL loading diagnostics and SwiftUI Invalid Configuration
|
|
3609
|
+
faults at warn); the rest is why
|
|
3429
3610
|
--errors leaves this source out unless asked. A VERIFIED
|
|
3430
3611
|
LAUNCH counts these records and prints one line:
|
|
3431
3612
|
|
|
@@ -3436,7 +3617,7 @@ WHAT WRITES WHAT
|
|
|
3436
3617
|
The count does not attribute unknown OS errors to the app.
|
|
3437
3618
|
Known JavaScript errors also print individually: Android
|
|
3438
3619
|
ReactNativeJS records, and iOS com.facebook.react.log /
|
|
3439
|
-
javascript records. These can interrupt
|
|
3620
|
+
javascript records. These can interrupt a recommended
|
|
3440
3621
|
readiness wait even without a client or Metro copy.
|
|
3441
3622
|
Client and Metro errors still print individually.
|
|
3442
3623
|
A native app that loaded its bundle but reported app errors
|
|
@@ -3618,7 +3799,12 @@ Branch on the code, never on the message.`,
|
|
|
3618
3799
|
hosted session. Auto skips declined offers before building, then uses the
|
|
3619
3800
|
local queue if none admits. A reserve refusal after an accepted offer fails
|
|
3620
3801
|
with this code and asks to retry; it does not re-place the built architecture.
|
|
3621
|
-
|
|
3802
|
+
remote-only never runs here and never joins the local queue: it refuses
|
|
3803
|
+
with this code when no host could ever take the run, and waits for a host that
|
|
3804
|
+
is only full or loaded (see STIM_AT_CAPACITY).
|
|
3805
|
+
An unreachable host's message and remedy are the diagnosis stim doctor gives
|
|
3806
|
+
(Tailscale off, Mac offline with last seen, serve route, stim-server), without
|
|
3807
|
+
tailscale ping. Check stim-server and Tailscale there,
|
|
3622
3808
|
then run stim doctor. Correct --device-type / --runtime for iOS or
|
|
3623
3809
|
--system-image / --device-profile for Android when the offer names
|
|
3624
3810
|
an unavailable choice. A session that exists stays recorded even if delivery
|
|
@@ -3740,9 +3926,14 @@ Branch on the code, never on the message.`,
|
|
|
3740
3926
|
note naming which of the two set it; Gemfile.lock is never edited either way.
|
|
3741
3927
|
\`worktree warm --refresh\` reports the same code for the install it runs in
|
|
3742
3928
|
the SOURCE CHECKOUT -- the lockfile's own command (\`pnpm install\`,
|
|
3743
|
-
\`yarn install\`, \`bun install\`, \`npm ci\`)
|
|
3929
|
+
\`yarn install\`, \`bun install\`, \`npm ci\`), the \`npm run postinstall\`
|
|
3930
|
+
it runs when npm's config there sets ignore-scripts, or that same pod ladder. The
|
|
3744
3931
|
message names the command, quotes its last lines, and nothing is copied: fix
|
|
3745
|
-
the source checkout, then warm again
|
|
3932
|
+
the source checkout, then warm again.
|
|
3933
|
+
start, ios and android also refuse with this code when \`gc --delete\`
|
|
3934
|
+
lightened the worktree and the \`stim worktree warm\` they ran to restore
|
|
3935
|
+
its node_modules and ios/Pods failed. The warm's own lines say why; fix
|
|
3936
|
+
that, then run \`stim worktree warm\` or retry the command.`
|
|
3746
3937
|
},
|
|
3747
3938
|
STIM_BUILD_FAILED: {
|
|
3748
3939
|
summary: "xcodebuild or gradle failed; the Android missing-SDK and APK refusals",
|
|
@@ -3980,6 +4171,11 @@ and no enabled remote can finish this build, or when the build requires a local
|
|
|
3980
4171
|
compiler. Enable local or choose an explicit --remote-build placement. Existing
|
|
3981
4172
|
builds are not interrupted and a cache hit needs no compiler.
|
|
3982
4173
|
|
|
4174
|
+
remote-only never builds here: it refuses when no remote machine in remote.machines
|
|
4175
|
+
can take the build, naming each machine and why it was skipped, and for a build that
|
|
4176
|
+
cannot leave this machine. Rerun with --remote-build remote to allow a local build
|
|
4177
|
+
when no remote machine can take it.
|
|
4178
|
+
|
|
3983
4179
|
A named --remote-build selection is strict. The message names the machine
|
|
3984
4180
|
and why it cannot take or finish the build: not configured or paired, approval
|
|
3985
4181
|
pending or denied, unreachable, changed pinned server key, a stim-server
|
|
@@ -3987,7 +4183,12 @@ too old to speak protocol 2, incompatible
|
|
|
3987
4183
|
toolchain/runtime/CPU, low disk, busy, sync/build failure, artifact failure,
|
|
3988
4184
|
or a checkout that changed while it built. Unsupported build kinds also refuse.
|
|
3989
4185
|
No local xcodebuild, Gradle or SwiftPM compile or alternate machine follows a
|
|
3990
|
-
refusal.
|
|
4186
|
+
refusal. For stim ios, a toolchain difference on the named machine, such as Xcode,
|
|
4187
|
+
the simulator runtime or the CPU, refuses before this machine runs prebuild or pod
|
|
4188
|
+
install, even when prebuild would have produced an app the local cache already holds, or the
|
|
4189
|
+
machine already holds the exact artifact. A
|
|
4190
|
+
missing or different global CocoaPods never refuses a named machine; a pod install
|
|
4191
|
+
that fails on it reports "pod install failed" with the command to run there.
|
|
3991
4192
|
Unlisted or unpaired names refuse at setup before consulting the cache, without
|
|
3992
4193
|
a build record or failed-run stats. A listed paired name with a cache hit needs
|
|
3993
4194
|
no build and does not contact the selected machine.
|
|
@@ -4003,7 +4204,7 @@ Run stim doctor --fix to ask for build access if not paired. Check
|
|
|
4003
4204
|
stim settings get remote.machines. A person on the worker approves this machine
|
|
4004
4205
|
by running the stim-server setup command doctor --fix printed, with its ticket
|
|
4005
4206
|
and expiry (guide settings). Agents never run setup or approve requests.
|
|
4006
|
-
Rerun with --remote-build auto for
|
|
4207
|
+
Rerun with --remote-build auto or remote for placement with local fallback, or
|
|
4007
4208
|
--remote-build local to keep the build here.
|
|
4008
4209
|
`
|
|
4009
4210
|
},
|
|
@@ -4098,6 +4299,13 @@ Rerun with --remote-build auto for normal placement and local fallback, or
|
|
|
4098
4299
|
Trust, then run the command again. It is a per-developer-certificate tap, not
|
|
4099
4300
|
a per-build one -- but an uninstall clears it, including the one Stim's own
|
|
4100
4301
|
signer-conflict retry performs.
|
|
4302
|
+
On a local iOS simulator, a cache-hit app that dyld kills at launch because
|
|
4303
|
+
one part of the app cannot bind a symbol from another part of the same app
|
|
4304
|
+
(for example React.framework against hermesvm.framework) is a damaged build,
|
|
4305
|
+
not a launch problem. Stim removes that cache entry, and the remedy names
|
|
4306
|
+
it. Run the command again to build the app fresh. A cache provider's copy is
|
|
4307
|
+
not removed; add \`--no-build-cache\` to skip it. If the fresh app crashes
|
|
4308
|
+
the same way, the project's own native code is the cause.
|
|
4101
4309
|
With \`--remote eas\` the remedy names the EAS Simulator session that is
|
|
4102
4310
|
still running, as for STIM_INSTALL_FAILED.`
|
|
4103
4311
|
},
|
|
@@ -4379,6 +4587,16 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
4379
4587
|
installation. If it fails, the refusal includes observed host memory pressure
|
|
4380
4588
|
when available. Free memory before retrying under pressure; see
|
|
4381
4589
|
\`stim guide lifecycle simslim\`. Booted alone does not prove readiness.
|
|
4590
|
+
The same probe lists the simulator's launchd jobs and requires a running
|
|
4591
|
+
SpringBoard. A simulator that reports Booted while SpringBoard has died
|
|
4592
|
+
(\`simctl launch\` then says "The system shell probably crashed") is shut
|
|
4593
|
+
down through teardown and booted once more; if SpringBoard is still not
|
|
4594
|
+
running, the refusal names the udid and the remedy: \`stim stop\`, then
|
|
4595
|
+
\`stim ios\` again. Repeated SpringBoard crashes leave reports in
|
|
4596
|
+
~/Library/Logs/DiagnosticReports, and macOS deletes them after about two
|
|
4597
|
+
days; before the restart Stim copies the simulator's recent ones into the
|
|
4598
|
+
workspace logs directory and records the boot steps by udid
|
|
4599
|
+
(\`stim logs --source device\`, \`stim guide logs\`, IOS BOOT RECORDS).
|
|
4382
4600
|
On Android the emulator's own stdio is captured to
|
|
4383
4601
|
the global workspace logs/emulator.log (truncated per boot), and when it printed a
|
|
4384
4602
|
\`FATAL |\` / \`ERROR |\` / \`PANIC:\` line THAT is the message and the remedy
|
|
@@ -4481,6 +4699,11 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
4481
4699
|
locks, builds, viewers and recent activity. Reclaim excludes this workspace,
|
|
4482
4700
|
physical, hosted, remote, parked and other homes' devices and never deletes.
|
|
4483
4701
|
A failed reclaim is logged and skipped; the run keeps waiting.
|
|
4702
|
+
--remote remote-only (and macos.remote remote-only) has no local queue: when every
|
|
4703
|
+
approved host is full, loaded or short of memory it polls the hosts every 5 seconds
|
|
4704
|
+
for the same wait (--wait, default 600 seconds) and then refuses with this code;
|
|
4705
|
+
--no-wait and --wait 0 refuse at once. Builds under remote-only refuse with
|
|
4706
|
+
STIM_OFFLOAD_REFUSED instead.
|
|
4484
4707
|
Stop an environment (\`stim stop\`), pass a longer \`--wait <seconds>\`,
|
|
4485
4708
|
or raise concurrency.maxDevices. With --remote auto, remote.machines and
|
|
4486
4709
|
the opt-in remote.easFallback (billed EAS Simulator) are tried before this
|
|
@@ -4920,8 +5143,8 @@ Inspect what remains with gc() before retrying a mutation.
|
|
|
4920
5143
|
`
|
|
4921
5144
|
},
|
|
4922
5145
|
STIM_CANCELLED: {
|
|
4923
|
-
summary: "an ios or
|
|
4924
|
-
body: () => `STIM_CANCELLED (ios, android; exit 130)
|
|
5146
|
+
summary: "an ios, android or macos run was interrupted by `stim stop` or Ctrl-C before it finished",
|
|
5147
|
+
body: () => `STIM_CANCELLED (ios, android, macos; exit 130)
|
|
4925
5148
|
"The ios run was cancelled by \`stim stop\` (pid <n>) before it finished."
|
|
4926
5149
|
The run was interrupted: by \`stim stop\`, which cancels a build it leaves
|
|
4927
5150
|
with nothing to deploy to, or by Ctrl-C. It forwarded the interrupt
|
|
@@ -4930,8 +5153,11 @@ Inspect what remains with gc() before retrying a mutation.
|
|
|
4930
5153
|
stopped at. An interrupted build stores no artifact, so the next run looks
|
|
4931
5154
|
up the cache as usual. Stopped between build tools, a run that \`stop\`
|
|
4932
5155
|
cancelled starts no further build tool and stops before it installs. A
|
|
4933
|
-
|
|
4934
|
-
|
|
5156
|
+
Ctrl-C while the run delivers the app to a hosting Mac, or waits for the app
|
|
5157
|
+
to load its bundle or report readiness, ends that work and reports
|
|
5158
|
+
STIM_CANCELLED. A second Ctrl-C exits at once, and so does a Ctrl-C with no
|
|
5159
|
+
build tool, SimSlim, hosted app delivery or launch readiness wait to stop;
|
|
5160
|
+
those exits print no payload. Run the same command again when you want the
|
|
4935
5161
|
app on a device.`
|
|
4936
5162
|
},
|
|
4937
5163
|
STIM_STOP_BLOCKED: {
|
|
@@ -5144,8 +5370,9 @@ not on any remote" (worktree remove)
|
|
|
5144
5370
|
lockfile says nothing about the one on disk now, whose dependencies may well
|
|
5145
5371
|
have been installed since; and a repository with no record at all -- every
|
|
5146
5372
|
repository before its first \`--refresh\` -- copies as it always has.
|
|
5147
|
-
|
|
5148
|
-
|
|
5373
|
+
Each directory that owns a lockfile the refresh installs has its own record:
|
|
5374
|
+
the repository root and, when the app has a lockfile of its own, the app. A
|
|
5375
|
+
plain warm reads both.`
|
|
5149
5376
|
},
|
|
5150
5377
|
warm: {
|
|
5151
5378
|
summary: "worktree warm claim storage refusals and recovery",
|
|
@@ -5442,10 +5669,11 @@ simulators to volume zero through Xcode's devicectl, and Android 15 and later
|
|
|
5442
5669
|
emulators to media volume zero. The iOS mute runs after SimSlim has applied its
|
|
5443
5670
|
profile and once SpringBoard has finished starting, because both a SimSlim
|
|
5444
5671
|
reboot and SpringBoard's startup reset the volume. A device that is already
|
|
5445
|
-
running keeps its volume, except that
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5672
|
+
running keeps its volume, except that a running simulator SimSlim reboots (a
|
|
5673
|
+
first slim, a profile change, or restoring stock services) is muted again once
|
|
5674
|
+
SpringBoard is back; an already slim simulator is not touched. Turn sound on
|
|
5675
|
+
for one device with Sound (iOS) or Media sound (Android) in its Stim Desktop
|
|
5676
|
+
options; the choice lasts until that device next boots. Android 14 and older images have no shell command that can
|
|
5449
5677
|
set media volume, so startup warns, as it does whenever a mute is not
|
|
5450
5678
|
confirmed. Host volume, Android alarm and ringtone volumes, hosted devices and
|
|
5451
5679
|
physical devices are unchanged.
|
|
@@ -5840,9 +6068,9 @@ If Stim is not installed globally, replace stim with npx stim.
|
|
|
5840
6068
|
|
|
5841
6069
|
A person on the host approves device-host access, separately from build, read
|
|
5842
6070
|
and control. The setup in hosted-ios also serves Android. android.remote sets
|
|
5843
|
-
a workspace default. eas and proxy remain backends. --remote auto or
|
|
5844
|
-
android.remote
|
|
5845
|
-
policy. No flag or setting runs on this machine.
|
|
6071
|
+
a workspace default. eas and proxy remain backends. --remote auto, remote or
|
|
6072
|
+
remote-only (or the same android.remote value) places automatically; see
|
|
6073
|
+
hosted-ios for the shared policy. No flag or setting runs on this machine.
|
|
5846
6074
|
|
|
5847
6075
|
A named Mac is strict: refusal, unreachable, declined or failed preparation
|
|
5848
6076
|
returns STIM_HOSTING_REFUSED without fallback. --device with --remote
|
|
@@ -5969,8 +6197,8 @@ Logcat retains a finite buffer; records already evicted or persisted beyond the
|
|
|
5969
6197
|
overlap may be unavailable. An oversized query retries the recent tail and writes
|
|
5970
6198
|
a device warning naming any dropped interval. Followers share a child-aware log
|
|
5971
6199
|
claim; install and stop cancel and settle the worker before native operations.
|
|
5972
|
-
Stop copies logs
|
|
5973
|
-
|
|
6200
|
+
Stop copies logs once, after the host's final collection and teardown, bounded to
|
|
6201
|
+
30 seconds with progress on stderr; Ctrl-C cancels the copy and keeps the placement. Collected logs
|
|
5974
6202
|
remain readable after stop. The host advertises hosted-android-data for Android
|
|
5975
6203
|
handoff and native logs. Older hosts get a newer stim-server note, use upload
|
|
5976
6204
|
and show records already copied here.`
|
|
@@ -5990,28 +6218,44 @@ If Stim is not installed globally, replace stim with npx stim.
|
|
|
5990
6218
|
stim reload ios
|
|
5991
6219
|
stim stop
|
|
5992
6220
|
|
|
5993
|
-
The same setup serves macos --remote. Approval is separate from build, read
|
|
6221
|
+
The same setup serves macos --remote and macos.remote. Approval is separate from build, read
|
|
5994
6222
|
and phone control. Set ios.remote to the machine name for a default (machine scope for every app on this machine);
|
|
5995
6223
|
no flag or setting runs here. eas and proxy keep their remote backend meanings.
|
|
5996
6224
|
--remote auto (or ios.remote = auto / android.remote = auto) stays here when
|
|
5997
6225
|
there is a free concurrency.maxDevices slot (0 means unlimited), no device
|
|
5998
6226
|
waiter ahead, normal host memory pressure, no budget shortfall,
|
|
5999
6227
|
and 5-minute load per core below server.maxLoadPerCore. Without remote.machines,
|
|
6000
|
-
auto
|
|
6228
|
+
auto and remote are local and remote-only refuses with STIM_HOSTING_REFUSED. An unknown local device count also stays local; boot admission
|
|
6001
6229
|
still decides. The default without a flag or setting stays local. remote.devicePoolDisabled excludes
|
|
6002
6230
|
members from new automatic placement only; an excluded local member is never a
|
|
6003
6231
|
fallback. Existing sessions keep their owner and named placement bypasses the pool.
|
|
6004
6232
|
See stim guide settings for separate build/device membership controls.
|
|
6005
6233
|
|
|
6234
|
+
--remote remote (or ios.remote = remote) skips that local check and asks the hosts
|
|
6235
|
+
first, in remote.machines order; the simulator runs here only when none admits
|
|
6236
|
+
it, with the same wait and EAS fallback as auto. --remote remote-only never runs
|
|
6237
|
+
here and never joins the local queue or uses EAS. When every host that answered is
|
|
6238
|
+
only full, loaded or short of memory, it waits for one to have room, polling every
|
|
6239
|
+
5 seconds for --wait seconds (default 600) and printing one placement line; --no-wait,
|
|
6240
|
+
--wait 0 or the end of the wait refuse with STIM_AT_CAPACITY. When no host can ever take
|
|
6241
|
+
the run (none configured, unreachable, declined for another reason such as paused),
|
|
6242
|
+
it refuses at once with STIM_HOSTING_REFUSED, naming each skipped host and its reason.
|
|
6243
|
+
--plan never waits. It prints the same STIM_HOSTING_REFUSED, or a STIM_BAD_ARG naming
|
|
6244
|
+
an invalid remote.build or STIM_REMOTE_BUILD.
|
|
6245
|
+
Excluding local in remote.devicePoolDisabled has the same effect on auto and remote.
|
|
6246
|
+
|
|
6006
6247
|
Otherwise Stim asks every approved remote.machines host in parallel, skipping
|
|
6007
6248
|
one that tailscale status reports as running an OS other than macOS, with a
|
|
6008
6249
|
3-second probe timeout and this run's model/runtime or image/profile selectors.
|
|
6009
|
-
A compatible choice, no declined reason, normal memory pressure
|
|
6010
|
-
capacity
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6250
|
+
A compatible choice, no declined reason, normal memory pressure, available
|
|
6251
|
+
capacity and a load per core under the host's own server.maxLoadPerCore are
|
|
6252
|
+
required (a host that reports no limit uses this machine's). With a free local
|
|
6253
|
+
slot, a host with unknown load is skipped under auto (remote admits it); with a full cap or a queue ahead, an
|
|
6254
|
+
admitted host with unknown load is allowed. Admitted hosts are tried in order:
|
|
6255
|
+
the host named by the build preference (flag > STIM_REMOTE_BUILD > remote.build)
|
|
6256
|
+
when it names a machine, then remote.machines order, so the first listed host with
|
|
6257
|
+
room fills before the next gets a run. Load and free memory do not rank hosts.
|
|
6258
|
+
Automatic build offload resolves later, after the device architecture is known.
|
|
6015
6259
|
|
|
6016
6260
|
When no host admits and this machine is at its concurrency.maxDevices cap (or runs
|
|
6017
6261
|
are queued ahead), remote.easFallback (default false; EAS Simulator is billed)
|
|
@@ -6028,7 +6272,7 @@ metro.tunnel off; on an Expo tunnel, run stim start --remote first). A recorded
|
|
|
6028
6272
|
EAS session is not sticky: once this machine has room, auto runs here and the
|
|
6029
6273
|
session bills until stim stop or remote.easMaxDurationMinutes. If any check fails, or the
|
|
6030
6274
|
setting is off, auto runs here and may wait in the existing FIFO device
|
|
6031
|
-
slot queue; --no-wait and --wait 0 refuse with STIM_AT_CAPACITY. The placement
|
|
6275
|
+
slot queue; --no-wait and --wait 0 refuse with STIM_AT_CAPACITY (remote-only has no local queue and waits for a remote host instead, as described above). The placement
|
|
6032
6276
|
line explains the decision, the skipped hosts and why EAS was not used
|
|
6033
6277
|
(machine "eas"). JSON progress goes to stderr.
|
|
6034
6278
|
The same decision, with a reason code per host, is a src: placement record in
|
|
@@ -6040,8 +6284,8 @@ A reserve refusal after a successful offer can race with another run. It fails
|
|
|
6040
6284
|
with STIM_HOSTING_REFUSED naming the host and asking to retry. Stim does not
|
|
6041
6285
|
try the next host or local placement after the build has targeted that host's
|
|
6042
6286
|
architecture, and never falls back once a hosted session exists. A named machine remains strict. --device
|
|
6043
|
-
cannot combine with --remote auto, and a --device run ignores ios.remote and
|
|
6044
|
-
android.remote. eas/proxy
|
|
6287
|
+
cannot combine with --remote auto, remote or remote-only, and a --device run ignores ios.remote and
|
|
6288
|
+
android.remote. eas/proxy placement is unchanged; macOS placement follows macos.remote (stim guide macos).
|
|
6045
6289
|
--simulator-app is honoured locally with auto and ignored with a note on a host.
|
|
6046
6290
|
Placement measures budgets without reclaiming; only a new local run reclaims.
|
|
6047
6291
|
Android --remote <machine> uses an owned emulator on that Mac; see hosted-android.
|
|
@@ -6320,8 +6564,8 @@ command before any EAS lookup. stim doctor reports it in a project with eas.json
|
|
|
6320
6564
|
If another run holds the artifact claim, wait for it to finish and retry.`
|
|
6321
6565
|
},
|
|
6322
6566
|
readiness: {
|
|
6323
|
-
summary: "implement
|
|
6324
|
-
body: () => `
|
|
6567
|
+
summary: "implement recommended pending/ready app logs, deadlines, errors, and platform isolation",
|
|
6568
|
+
body: () => `RECOMMENDED APP READINESS
|
|
6325
6569
|
|
|
6326
6570
|
No package or SDK is needed. This applies to debug ios/android launches with
|
|
6327
6571
|
Metro verification enabled, not release builds or --no-metro-check.
|
|
@@ -6382,7 +6626,10 @@ Only exact standalone info/debug messages captured from this app's device log
|
|
|
6382
6626
|
for this platform and current launch are accepted. Stale, other-platform,
|
|
6383
6627
|
error-level, and embedded example messages are ignored. Unlabelled shared
|
|
6384
6628
|
Metro output cannot identify a platform. If pending is not captured in time,
|
|
6385
|
-
including when device logs are unavailable, the default check applies.
|
|
6629
|
+
including when device logs are unavailable, the default check applies. On a
|
|
6630
|
+
device hosted on another Mac (--remote <machine>), the device log is the copy
|
|
6631
|
+
pulled from that Mac during the launch check, and each window waits up to 10
|
|
6632
|
+
seconds for the copy to cover it.
|
|
6386
6633
|
|
|
6387
6634
|
The app declares readiness; Stim does not inspect a rendered frame. This does
|
|
6388
6635
|
not change launched JSON semantics or the need to inspect the expected UI and
|
|
@@ -6674,7 +6921,8 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
6674
6921
|
|
|
6675
6922
|
\`gc --older-than <days>\` reports and deletes, or with \`--cache parked\`
|
|
6676
6923
|
erases, only the devices parked at least that long; one parked at an unknown
|
|
6677
|
-
time stays.
|
|
6924
|
+
time stays. Automatic maintenance's daily age sweep deletes the devices
|
|
6925
|
+
parked for maintenance.olderThanDays (7; 0 never) the same way.
|
|
6678
6926
|
|
|
6679
6927
|
If simulator listing or deletion fails, \`gc --delete\` reports the failure
|
|
6680
6928
|
and keeps that entry. It never turns an unverified absence into a dropped
|
|
@@ -6846,11 +7094,27 @@ IOS SCHEME SELECTION
|
|
|
6846
7094
|
|
|
6847
7095
|
AN ARTIFACT THE DEVICE ALREADY HOLDS IS NOT INSTALLED AGAIN
|
|
6848
7096
|
Both platforms store the artifact verbatim, so its hash is its identity.
|
|
6849
|
-
Before installing, Stim
|
|
6850
|
-
one the device already has
|
|
6851
|
-
\`simctl get_app_container\` bundle
|
|
6852
|
-
is skipped. The phase still reports the
|
|
6853
|
-
avoids the ~43s a 400MB APK can cost to
|
|
7097
|
+
Before installing, Stim compares the artifact it is about to install with
|
|
7098
|
+
the one the device already has. On iOS it hashes both bundles: the
|
|
7099
|
+
\`simctl get_app_container\` bundle and the one about to be installed.
|
|
7100
|
+
Byte-identical means the install is skipped. The phase still reports the
|
|
7101
|
+
cost of proving that identity, but avoids the ~43s a 400MB APK can cost to
|
|
7102
|
+
copy and install over USB.
|
|
7103
|
+
|
|
7104
|
+
On Android the proof is one \`adb shell\` call that returns the installed
|
|
7105
|
+
APK's path, size, and the SHA-256 of its tail: the v2 or v3 signing block,
|
|
7106
|
+
the central directory, and the end record. That tail carries the signed
|
|
7107
|
+
digests of every other byte, and Android verified them when it installed
|
|
7108
|
+
the APK. Stim verifies the local APK against the same digests once, with
|
|
7109
|
+
\`apksigner verify\`, and keeps the size and tail digest in
|
|
7110
|
+
\`apk-signed-tail.json\` beside the APK in its build cache entry (stored with
|
|
7111
|
+
the build; an older entry gets it on first use). The same size and tail
|
|
7112
|
+
digest mean the same file, on an owned emulator, an adopted one, a
|
|
7113
|
+
\`--device\` phone and a plain rerun. A different size or tail digest
|
|
7114
|
+
installs without hashing the whole APK. An APK outside a build cache entry,
|
|
7115
|
+
one without a v2 or v3 signing block, an apksigner that is missing or fails,
|
|
7116
|
+
and a device whose \`tail\` or \`stat\` does not answer as expected fall back
|
|
7117
|
+
to \`pm path\` then \`sha256sum\` of the whole installed APK.
|
|
6854
7118
|
|
|
6855
7119
|
install unchanged (emulator-5584 already has this build) (0.4s)
|
|
6856
7120
|
|
|
@@ -6863,8 +7127,9 @@ AN ARTIFACT THE DEVICE ALREADY HOLDS IS NOT INSTALLED AGAIN
|
|
|
6863
7127
|
install unchanged (stim-app already has this build) (0.4s)
|
|
6864
7128
|
install dev client prepared (0.9s)
|
|
6865
7129
|
|
|
6866
|
-
The skip needs PROOF. A package that is not installed, a split install,
|
|
6867
|
-
|
|
7130
|
+
The skip needs PROOF. A package that is not installed, a split install, a
|
|
7131
|
+
device that answers neither probe (no \`tail\` and no \`sha256sum\`), and any
|
|
7132
|
+
adb or simctl failure all read as
|
|
6868
7133
|
"cannot determine", and the run installs exactly as it always did. A release
|
|
6869
7134
|
run swaps this workspace's JS into a COPY of the artifact, which is a
|
|
6870
7135
|
different artifact and is therefore always installed.
|
|
@@ -7065,6 +7330,67 @@ THE BUILD CACHE HAS THREE LEVELS
|
|
|
7065
7330
|
trims, and clears local caches only: the provider contract has no delete
|
|
7066
7331
|
operation, so no local command can remove data a team or CI system shares.
|
|
7067
7332
|
|
|
7333
|
+
WHAT THE KEY COUNTS. Stim runs @expo/fingerprint with its default
|
|
7334
|
+
\`balanced\` preset, the one the project's own Expo uses. An installed
|
|
7335
|
+
dependency, and a config plugin loaded from node_modules, counts by its name
|
|
7336
|
+
and version, not by its files. A package whose real path is outside
|
|
7337
|
+
node_modules -- a workspace package, a link: dependency, a local Expo module
|
|
7338
|
+
-- counts by its files, and so do patches/, the app's committed ios/ or
|
|
7339
|
+
android/, the evaluated app config and its local plugins. patches/ and
|
|
7340
|
+
.yarn/patches/ next to a monorepo's lockfile count too, and so do the patch
|
|
7341
|
+
hashes pnpm-lock.yaml records, wherever the patch files live. The app's
|
|
7342
|
+
version, ios.buildNumber and android.versionCode, eas.json, .easignore and
|
|
7343
|
+
the path overrides of react-native.config.js are left out, so a Release
|
|
7344
|
+
cache hit keeps the version it was built with. A project that wants native
|
|
7345
|
+
package files hashed sets \`preset: 'strict'\` in fingerprint.config.js, at
|
|
7346
|
+
about twice the fingerprint's CPU.
|
|
7347
|
+
|
|
7348
|
+
AN EDIT INSIDE node_modules/ IS NOT SEEN. Editing a dependency's native file
|
|
7349
|
+
in place (node_modules/<pkg>/ios, android, cpp, a podspec or build.gradle)
|
|
7350
|
+
leaves the key unchanged, so the next run installs the cached app without
|
|
7351
|
+
the edit. Make the change a patch (patch-package's patches/, or pnpm patch,
|
|
7352
|
+
whose patches the fingerprint hashes), or build it with
|
|
7353
|
+
\`--no-build-cache --remote-build local\`. --no-build-cache alone can still
|
|
7354
|
+
place the build on another machine, which installs dependencies from the
|
|
7355
|
+
lockfile and so builds without the edit. The fresh build is stored under the
|
|
7356
|
+
unchanged key in the machine-wide cache and handed to any cache provider, so
|
|
7357
|
+
every worktree reuses it, edit included, until the dependency's version or
|
|
7358
|
+
patches change; undo the edit with another --no-build-cache build.
|
|
7359
|
+
|
|
7360
|
+
A KNOWN TREE SKIPS THE FULL FINGERPRINT. After a full fingerprint at the
|
|
7361
|
+
first lookup of a React Native or Expo run, Stim records it in
|
|
7362
|
+
$STIM_HOME/fingerprint-memo (~/.stim by default) under a static digest of
|
|
7363
|
+
the tree: git blob ids of the native inputs git tracks, the contents of the
|
|
7364
|
+
untracked, modified and ignored ones, the app config's sources and the files
|
|
7365
|
+
and directories it names, each installed package's path, version and native
|
|
7366
|
+
markers, the lockfile, and the environment variables the config and its
|
|
7367
|
+
.env files read. Any worktree whose tree has the same digest, a fresh one
|
|
7368
|
+
included, reuses the record instead of evaluating the config and running
|
|
7369
|
+
autolinking:
|
|
7370
|
+
|
|
7371
|
+
fingerprint matches a recorded fingerprint of this tree; confirming it in the background
|
|
7372
|
+
|
|
7373
|
+
A full fingerprint then runs at low priority while the app installs and
|
|
7374
|
+
launches. The record is put back only when it agrees. If the run reaches its
|
|
7375
|
+
end first, it waits up to 3 seconds more, then gives the check up and leaves
|
|
7376
|
+
no record, so the next run fingerprints in full. A disagreement prints a
|
|
7377
|
+
warning naming both hashes at the end of the run and writes a
|
|
7378
|
+
fingerprint_memo_stale record to the build log; run the command again to use
|
|
7379
|
+
the current tree.
|
|
7380
|
+
|
|
7381
|
+
A config the digest cannot follow always fingerprints in full: a dynamic
|
|
7382
|
+
require or import, process.env used other than by literal name, file,
|
|
7383
|
+
process or network access while it is evaluated, a dotenv import, a
|
|
7384
|
+
fileHookTransform, or a preset that hashes package files. A local config
|
|
7385
|
+
plugin counts as evaluated too, with one exception: the digest does not
|
|
7386
|
+
track the files a plugin that applies mods reads, assuming it reads them in
|
|
7387
|
+
its mods at prebuild. A plugin that also puts what it reads into the config
|
|
7388
|
+
is a gap only the background check catches. So does a project outside git or on Yarn Plug'n'Play. The record is
|
|
7389
|
+
never consulted after prebuild or pod install, by a build worker, by doctor,
|
|
7390
|
+
or with --no-build-cache; ios --plan and android --plan read one without
|
|
7391
|
+
writing. Records are 0600, at most 256 per platform, and gc prunes them by
|
|
7392
|
+
age with the other caches.
|
|
7393
|
+
|
|
7068
7394
|
A MISS EXPLAINS ITSELF. Each local cache entry keeps the per-source hashes
|
|
7069
7395
|
of its fingerprint (hashes only, pruned with the entry). Before compiling,
|
|
7070
7396
|
Stim compares the sources it is about to store with a baseline: the entry
|
|
@@ -7301,8 +7627,10 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7301
7627
|
Waiting prints the count, holder workspace names
|
|
7302
7628
|
and elapsed time at once and about every 10s, then
|
|
7303
7629
|
the queue position, head workspace name and
|
|
7304
|
-
$STIM_HOME/device-waits path.
|
|
7305
|
-
|
|
7630
|
+
$STIM_HOME/device-waits path. Workspaces that
|
|
7631
|
+
share a project name show the directory that tells
|
|
7632
|
+
them apart, as in mobile (qa-b-p2). Timeout names
|
|
7633
|
+
the same head and path. Stop cancels a queued run and
|
|
7306
7634
|
releases its ticket without booting its device.
|
|
7307
7635
|
Status JSON adds build.waitingFor independently
|
|
7308
7636
|
of phase: { kind: "device-slot" | "build-slot",
|
|
@@ -7380,7 +7708,14 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7380
7708
|
(\`gc --delete\` semantics; the next build installs from the shared
|
|
7381
7709
|
cache). A workspace whose last use is unknown is kept
|
|
7382
7710
|
4. trim shared cache entries nothing has used for 14 days
|
|
7383
|
-
(\`gc --delete --older-than 14\` for the caches)
|
|
7711
|
+
(\`gc --delete --older-than 14\` for the caches). Caches with nothing
|
|
7712
|
+
to trim print one line, not one each. A trim that removed nothing is
|
|
7713
|
+
recorded in $STIM_HOME/budget-sweep.json and not repeated for 5
|
|
7714
|
+
minutes while the set of caches is the same and free disk has not
|
|
7715
|
+
fallen by more than 1 GB since; the run prints one budget line saying
|
|
7716
|
+
it skipped. \`gc\` and automatic maintenance never skip, and a dry
|
|
7717
|
+
run (\`doctor\`) still plans the step. The STIM_LOW_DISK message
|
|
7718
|
+
measures the largest uses of disk at the same time.
|
|
7384
7719
|
|
|
7385
7720
|
IDLE SHUTDOWN (30 MINUTES BY DEFAULT): with devices.idleShutdownMinutes above
|
|
7386
7721
|
0, a workspace's supervisor shuts down that workspace's owned simulators and
|
|
@@ -7397,9 +7732,13 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7397
7732
|
status\` shows "shut down after 30m idle" on the device until the next
|
|
7398
7733
|
\`ios\` or \`android\` run boots it again. When metro.idleStopMinutes is
|
|
7399
7734
|
shorter, the dev server's idle stop first shuts down the devices idle that
|
|
7400
|
-
long, because no supervisor is left to check afterwards.
|
|
7401
|
-
|
|
7402
|
-
|
|
7735
|
+
long, because no supervisor is left to check afterwards. Devices with no
|
|
7736
|
+
supervisor (release runs, a dev server that exited) are shut down by
|
|
7737
|
+
automatic maintenance while maintenance.mode is on (guide cleanup): every maintenance.idleCheckMinutes
|
|
7738
|
+
(5) a command starts a background check that applies each workspace's
|
|
7739
|
+
current setting with the same idle rules, native-run lock recheck, status
|
|
7740
|
+
and log record, and skips the workspace of the command that started it.
|
|
7741
|
+
The supervisor reads the setting when it starts. Stim Desktop's simulator view is not a
|
|
7403
7742
|
stim-server client and does not count as a viewer. Change it with
|
|
7404
7743
|
\`stim settings set devices.idleShutdownMinutes <minutes> --scope machine\`;
|
|
7405
7744
|
0 turns it off, and an explicit 0 stays 0.
|
|
@@ -7445,8 +7784,8 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7445
7784
|
summary: "every flag per command, Android variants and flavors, the per-run simulator model, runtime and system image",
|
|
7446
7785
|
body: () => `THE OPTION SURFACE, IN FULL
|
|
7447
7786
|
start --json --wait <seconds> --remote --reset-cache
|
|
7448
|
-
ios --remote-build <auto|
|
|
7449
|
-
android --remote-build <auto|
|
|
7787
|
+
ios --remote-build <local|auto|remote|remote-only|name> --slot <name> --json --plan --no-metro-check --no-build-cache --scheme <name> --configuration <name> --device-type <name> --runtime <version> --simulator-app <xcode|siniulator|stim-desktop> --device [udid] --wait <seconds> --no-wait --remote <eas|proxy|local|auto|remote|remote-only|machine>
|
|
7788
|
+
android --remote-build <local|auto|remote|remote-only|name> --slot <name> --json --plan --no-metro-check --no-build-cache --variant <name> --system-image <id> --device-profile <id> --device [serial] --wait <seconds> --no-wait --remote <proxy|eas|local|auto|remote|remote-only|machine>
|
|
7450
7789
|
ios/android --wait bounds owned-device slot waits (default 600s), or physical
|
|
7451
7790
|
leases with --device (default 60s). Remote targets do not join this local
|
|
7452
7791
|
slot queue. --no-wait refuses a full/queued owned
|
|
@@ -7554,12 +7893,24 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7554
7893
|
.stim.json, else \`git symbolic-ref --short refs/remotes/origin/HEAD\`;
|
|
7555
7894
|
when neither answers it says so and makes no warning.
|
|
7556
7895
|
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7896
|
+
The app is the one warm prepares: the app the command was invoked from, or,
|
|
7897
|
+
from a monorepo root, the one app registered in the source checkout or in
|
|
7898
|
+
the worktree. With no such app, a refresh from the root updates only the
|
|
7899
|
+
repository root and says so on stderr.
|
|
7900
|
+
Dependencies install where the repository root's lockfile is and, when the
|
|
7901
|
+
app has its own lockfile (a nested package outside the root workspaces),
|
|
7902
|
+
there too; a root that has neither installed dependencies nor an install
|
|
7903
|
+
record is left alone when the app has its own lockfile. Each installs when
|
|
7904
|
+
its lockfile moved, when its patches/ directory moved (npm projects only),
|
|
7905
|
+
when nothing is installed, or when npm reports a tree that differs from the
|
|
7906
|
+
one it reported after the last completed install. An npm project whose
|
|
7907
|
+
npm config sets ignore-scripts gets no postinstall from \`npm ci\`, so when its
|
|
7908
|
+
package.json defines one the refresh runs \`npm run postinstall\` next
|
|
7909
|
+
(patch-package, usually); dependencies' own install scripts stay blocked.
|
|
7910
|
+
Pods run for that app, and only that app, when its ios/Podfile.lock moved or
|
|
7911
|
+
ios/Pods/Manifest.lock does not match it. Each completed or skipped deps and
|
|
7912
|
+
pods step names its source directory and reason. A failed install or
|
|
7913
|
+
postinstall refuses with STIM_DEPS_FAILED and nothing is copied.
|
|
7563
7914
|
|
|
7564
7915
|
An install that did not finish is remembered, and a PLAIN warm reads that
|
|
7565
7916
|
before it copies. The refresh records the completed install of the lockfile it
|
|
@@ -7624,7 +7975,11 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
7624
7975
|
expo-modules-jsi/apple/.DerivedData Xcode build state, directly under
|
|
7625
7976
|
node_modules or in the pnpm virtual store. An ignored directory that Git
|
|
7626
7977
|
reports above those names (for example an app directory with no tracked
|
|
7627
|
-
files) is copied as is. Warm
|
|
7978
|
+
files) is copied as is. Warm renames those deleted paths into
|
|
7979
|
+
$STIM_HOME/trash and a detached, low-priority rm deletes them after warm
|
|
7980
|
+
returns (through the programmatic API, before the call resolves); when the
|
|
7981
|
+
rename is not possible (Windows, $STIM_HOME on another volume), warm deletes
|
|
7982
|
+
them before it returns. Warm also skips paths
|
|
7628
7983
|
overlapping a nested destination worktree or below a symlink ancestor.
|
|
7629
7984
|
Tracked .idea settings come from Git and stay untouched by warm.
|
|
7630
7985
|
|
|
@@ -8160,17 +8515,23 @@ THE POOL: WHICH DEVICE AN ID-LESS \`--device\` PICKS
|
|
|
8160
8515
|
\`ios.simslim off\` opts that app out and restores stock services on its
|
|
8161
8516
|
simulator. The defaults disable push, StoreKit, iCloud, Safari sync, Mail,
|
|
8162
8517
|
Calendar and Contacts services, among others; move an app that needs them
|
|
8163
|
-
to a profile that keeps those categories, or to \`off\`. A running
|
|
8164
|
-
|
|
8165
|
-
|
|
8518
|
+
to a profile that keeps those categories, or to \`off\`. A running
|
|
8519
|
+
simulator is slimmed on the next \`stim ios\`, without a boot first, and a
|
|
8520
|
+
parked simulator when Stim adopts it. An already slim simulator is left
|
|
8521
|
+
alone, so only the first slim reboots it.
|
|
8166
8522
|
Without the \`simslim\` command, doctor reports it and \`stim ios\` boots
|
|
8167
8523
|
the simulator unslimmed with a one-line note. Hosted simulators on a named
|
|
8168
8524
|
Mac are never slimmed, whatever either Mac's setting says.
|
|
8169
8525
|
|
|
8170
8526
|
SimSlim 0.8 requires iOS 18.5 or newer. On each local \`stim ios\`,
|
|
8171
8527
|
Stim reconciles that profile on the owned simulator before the app build.
|
|
8172
|
-
The first change can update services and reboot the simulator.
|
|
8173
|
-
|
|
8528
|
+
The first change can update services and reboot the simulator. Stim records
|
|
8529
|
+
the applied profile (the default categories, or a hash of the profile file)
|
|
8530
|
+
and the boot of the simulator it was applied on, so a later launch on the
|
|
8531
|
+
same boot with the same profile skips the \`simslim\` call. A changed
|
|
8532
|
+
profile, a reboot, or a missing record reconciles again. A manual
|
|
8533
|
+
\`simslim off\` on a running simulator is not noticed until the simulator
|
|
8534
|
+
reboots or the profile changes. The settings persist across normal
|
|
8174
8535
|
shutdowns and reboots. Removing the setting restores stock services when
|
|
8175
8536
|
Stim applied the profile. Stim never changes an unowned or remote simulator.
|
|
8176
8537
|
Each SimSlim operation has a 12-minute outer deadline, including discovery.
|
|
@@ -8267,13 +8628,14 @@ and logs, and never deletes anything. off disables it. It is off in CI and
|
|
|
8267
8628
|
scoped STIM_HOME homes unless STIM_MAINTENANCE is explicit, so a scratch home
|
|
8268
8629
|
or CI run never deletes on its own.
|
|
8269
8630
|
Commands trigger a detached pass when a check is due: disk and memory pressure
|
|
8270
|
-
(every minute),
|
|
8271
|
-
|
|
8631
|
+
(every minute), idle devices (every 5 minutes, maintenance.idleCheckMinutes),
|
|
8632
|
+
directory sizes (hourly), finished worktrees (every 15 minutes) and the age
|
|
8633
|
+
sweep (daily). guide, settings, help and every gc
|
|
8272
8634
|
invocation do not trigger it; gc without --delete prints the maintenance plan
|
|
8273
8635
|
itself.
|
|
8274
8636
|
status --watch and every running dev server supervisor also trigger checks
|
|
8275
8637
|
each minute, so the disk check runs while no command does.
|
|
8276
|
-
Size, worktree and sweep checks defer under high load. Attempts back off for at
|
|
8638
|
+
Size, idle, worktree and sweep checks defer under high load. Attempts back off for at
|
|
8277
8639
|
least one minute. Measured directories are workspace build outputs and Stim's
|
|
8278
8640
|
shared native, Metro, ccache, Swift compilation and registered caches. The size
|
|
8279
8641
|
check also records the disk of each owned and parked simulator and emulator
|
|
@@ -8282,7 +8644,10 @@ Pressure checks read free disk on the Stim home, projects and worker root
|
|
|
8282
8644
|
volumes. On macOS the memory signal is the sysctl pressure level, with no
|
|
8283
8645
|
signal if sysctl fails. Other platforms use os.freemem(); macOS never falls
|
|
8284
8646
|
back to it. Memory pressure is recorded only; stopping devices, dev servers
|
|
8285
|
-
and helpers is not automatic.
|
|
8647
|
+
and helpers for memory is not automatic. The idle check shuts down (never
|
|
8648
|
+
deletes) owned simulators and emulators idle for their workspace's
|
|
8649
|
+
devices.idleShutdownMinutes, also with no supervisor running, through the
|
|
8650
|
+
supervisor's idle rules and records (guide lifecycle budget). While the level is warning or critical, the
|
|
8286
8651
|
check also names abnormally large processes (guide lifecycle simslim) in
|
|
8287
8652
|
status's maintenance block and the maintenance log.
|
|
8288
8653
|
|
|
@@ -8299,13 +8664,28 @@ In on mode a pass runs, cheapest to rebuild first:
|
|
|
8299
8664
|
claim (taken for each xcodebuild run that compiles with it) or that
|
|
8300
8665
|
claim is unresolved; the emptying holds the exclusive claim
|
|
8301
8666
|
5. linked worktrees whose branch or pull request finished (gc's finished
|
|
8302
|
-
worktree rules and gc.worktreeGraceMinutes; maintenance.removeFinishedWorktrees)
|
|
8303
|
-
|
|
8667
|
+
worktree rules and gc.worktreeGraceMinutes; maintenance.removeFinishedWorktrees),
|
|
8668
|
+
a dirty finished one after archiving its uncommitted files (ARCHIVED
|
|
8669
|
+
CHANGES in stim guide cleanup gc), clean ones with no commits of their
|
|
8670
|
+
own (NO COMMITS OF ITS OWN there), and, with
|
|
8671
|
+
maintenance.removeIdleWorktrees (off by default), in the age
|
|
8672
|
+
sweep clean, pushed ones unused for olderThanDays, as gc --delete
|
|
8673
|
+
--worktrees --older-than removes them, git-ignored files included; never
|
|
8674
|
+
an unfinished dirty one, one with unpushed commits, the source checkout,
|
|
8675
|
+
a locked one, or one whose last use is unknown
|
|
8676
|
+
6. parked simulators and emulators unused for olderThanDays in the age
|
|
8677
|
+
sweep, through centralized teardown with ownership checked again
|
|
8678
|
+
7. owned simulators and emulators of a finished worktree that is kept, such
|
|
8304
8679
|
as a dirty one (not one locked with git worktree lock), once it finished
|
|
8305
8680
|
and was idle for gc.worktreeGraceMinutes (at least protectRecentHours),
|
|
8306
8681
|
and of any
|
|
8307
8682
|
workspace idle for maintenance.deviceIdleDays (3; 0 turns it off) in the
|
|
8308
8683
|
age sweep. Devices are recreated on the next run.
|
|
8684
|
+
The age sweep runs every maintenance.sweepHours (24) in the background of
|
|
8685
|
+
commands, never at a set hour.
|
|
8686
|
+
maintenance.olderThanDays (7) is its age for steps 2, 3, 5 and 6; with 0 the
|
|
8687
|
+
sweep removes nothing in them by age, while step 1, step 7, finished
|
|
8688
|
+
worktrees and the cap and disk-driven parts of steps 2 and 3 still run.
|
|
8309
8689
|
Disk-driven steps stop once free space is back above the floor. Kept for
|
|
8310
8690
|
every pass: a workspace that is in use, holds a lock, was used within
|
|
8311
8691
|
maintenance.protectRecentHours, is pinned with maintenance.keep, or is the
|
|
@@ -8328,14 +8708,21 @@ DISK PRESSURE LEVELS
|
|
|
8328
8708
|
level 2, which runs until free disk is back above the floor; level 3 runs
|
|
8329
8709
|
only while free disk stays under the level 3 floor. At levels 2 and 3 the
|
|
8330
8710
|
protection window is maintenance.pressureProtectMinutes (10) instead of
|
|
8331
|
-
protectRecentHours
|
|
8332
|
-
|
|
8711
|
+
protectRecentHours, except for the build outputs and build directories of
|
|
8712
|
+
level 2, which follow the lightening rule of gc --delete (WORKSPACE BUILD
|
|
8713
|
+
OUTPUTS): a running dev server, a booted or hosted device and a managed
|
|
8714
|
+
tunnel do not keep them, a build or a running macOS app does, and they stay
|
|
8715
|
+
for 15 minutes after the workspace's last ios, android or macos run.
|
|
8716
|
+
Each step re-measures first and stops once free disk is back above its
|
|
8717
|
+
level's floor, cheapest to rebuild first.
|
|
8333
8718
|
Level 2:
|
|
8334
|
-
1. build outputs of workspaces
|
|
8719
|
+
1. build outputs of workspaces, with the lightening rule above
|
|
8335
8720
|
2. parked simulators and emulators, deleted through centralized teardown
|
|
8336
|
-
3. build directories of
|
|
8337
|
-
android/build, android/.gradle and .build, at
|
|
8338
|
-
worktree root, or apps/* and packages
|
|
8721
|
+
3. build directories of worktrees with a Stim workspace, by the same
|
|
8722
|
+
rule: android/app/build, android/build, android/.gradle and .build, at
|
|
8723
|
+
a project root, the worktree root, or apps/* and packages/*. ios/build
|
|
8724
|
+
stays: React Native's pod install writes the codegen output and
|
|
8725
|
+
podspec facades there that only pod install recreates
|
|
8339
8726
|
4. owned simulators and emulators of workspaces idle for the short window
|
|
8340
8727
|
5. Stim temp directories, xctrace recordings and SwiftPM temp directories
|
|
8341
8728
|
in TMPDIR unmodified for 24 hours, with gc --delete's checks (see stim guide cleanup gc)
|
|
@@ -8345,12 +8732,14 @@ DISK PRESSURE LEVELS
|
|
|
8345
8732
|
and the build
|
|
8346
8733
|
2. finished worktrees, and clean, pushed worktrees with no commits of
|
|
8347
8734
|
their own beyond the default branch, with the short window as grace
|
|
8348
|
-
period (maintenance.removeFinishedWorktrees still applies)
|
|
8735
|
+
period and idle window (maintenance.removeFinishedWorktrees still applies)
|
|
8349
8736
|
3. workspaces whose dev server runs but that are otherwise inactive for
|
|
8350
8737
|
the short window: their dev server stops and their owned simulators
|
|
8351
8738
|
and emulators are deleted
|
|
8352
8739
|
4. node_modules and ios/Pods at the root or a project root of idle linked
|
|
8353
|
-
worktrees, never the source checkout
|
|
8740
|
+
worktrees, never the source checkout, with the running-process checks
|
|
8741
|
+
of WORKTREE DEPENDENCIES; when worktree warm can restore them they are
|
|
8742
|
+
recorded for the next start, ios or android to restore
|
|
8354
8743
|
5. idle Gradle and Kotlin daemons, stopped as gc --delete --cache
|
|
8355
8744
|
gradle-daemons stops them (never during a Stim build, never a busy or
|
|
8356
8745
|
unverified one, never with STIM_HOME set), only when every Gradle
|
|
@@ -8363,8 +8752,11 @@ DISK PRESSURE LEVELS
|
|
|
8363
8752
|
still keeps them
|
|
8364
8753
|
A directory is cleared only when it is a real directory inside its
|
|
8365
8754
|
worktree, git tracks nothing in it, its worktree is not in use, holds no
|
|
8366
|
-
lock or build and is not pinned, and
|
|
8367
|
-
|
|
8755
|
+
lock or build and is not pinned, and, for the node_modules and ios/Pods of
|
|
8756
|
+
level 3, nothing under it, nor the worktree's git index, HEAD or Stim
|
|
8757
|
+
state, changed within the short window. A build directory of level 2 also
|
|
8758
|
+
stays in a worktree where no Stim workspace has recorded any state; a build
|
|
8759
|
+
that Stim did not run is not detected. A dirty or
|
|
8368
8760
|
unpushed worktree can still be stopped and have these directories cleared;
|
|
8369
8761
|
only its removal is refused. Caches of other tools (pnpm and npm stores,
|
|
8370
8762
|
CocoaPods, SwiftPM, the shared Gradle caches) are never deleted.
|
|
@@ -8401,6 +8793,23 @@ claim fails with ENOSPC or EDQUOT, the pass deletes it and retries once, so a
|
|
|
8401
8793
|
pass starts at zero free disk as long as an earlier pass left the reserve; the
|
|
8402
8794
|
pass writes it again at its end.
|
|
8403
8795
|
|
|
8796
|
+
WHAT WAS CLEARED
|
|
8797
|
+
Every run that deletes or changes something appends one record per item to
|
|
8798
|
+
the machine gc log, $STIM_HOME/gc/gc.ndjson: gc --delete with any flags, gc
|
|
8799
|
+
--idle, gc --cache --delete, each maintenance action taken, and what the budget gate
|
|
8800
|
+
reclaims before stim start, ios or android. A dry run writes nothing, and a
|
|
8801
|
+
gc run that only kept items writes nothing. Failed and kept items carry their
|
|
8802
|
+
reason. The file rotates at maintenance.logMaxMb and its old generation is
|
|
8803
|
+
kept for maintenance.logRetentionDays, like the maintenance log.
|
|
8804
|
+
stim logs --source gc the retained records, oldest first
|
|
8805
|
+
stim logs --source gc --json one record per line
|
|
8806
|
+
stim logs --source gc --errors only the items that failed
|
|
8807
|
+
gc works from any directory because the log is machine-wide; it cannot be
|
|
8808
|
+
combined with other --source values and --source all leaves it out. Fields
|
|
8809
|
+
(\`guide logs\`, GC LOG): runId, trigger (manual, desktop, maintenance or
|
|
8810
|
+
budget), options, kind, status (done, kept or failed), label, id, path,
|
|
8811
|
+
bytes, detail.
|
|
8812
|
+
|
|
8404
8813
|
CLEANUP AND DISK
|
|
8405
8814
|
|
|
8406
8815
|
worktree remove stops the agent-device daemon when the workspace's
|
|
@@ -8478,6 +8887,11 @@ this cleanup. agent-device is optional: a missing binary skips this step, and a
|
|
|
8478
8887
|
failed or timed-out list/close prints a device line on stderr while teardown
|
|
8479
8888
|
continues. Each cleanup pass allows at most 15 seconds of agent-device calls
|
|
8480
8889
|
per device; the pass \`stop\` makes after shutdown has its own budget.
|
|
8890
|
+
A daemon agent-device will not replace (daemon-busy: it is starting up or still
|
|
8891
|
+
has sessions, requests or leases) is not retried. Stim prints one line per
|
|
8892
|
+
device, naming each busy daemon, even though it lists sessions before and after
|
|
8893
|
+
shutdown: sessions on the device in them stay open until the daemon is idle or,
|
|
8894
|
+
if it is yours, stopped with agent-device daemon stop --state-dir <dir>.
|
|
8481
8895
|
A local daemon that cannot use socket transport or a CLI without the target guard
|
|
8482
8896
|
skips cleanup with a warning; no remote daemon is used.
|
|
8483
8897
|
|
|
@@ -8668,7 +9082,10 @@ LINKED WORKTREES
|
|
|
8668
9082
|
still exists, as after a removal killed between the rename and git, stays
|
|
8669
9083
|
with the reason; if that worktree is the one the entry came from, run
|
|
8670
9084
|
\`stim worktree remove\` on it to finish the removal.
|
|
8671
|
-
gc never moves the directories back.
|
|
9085
|
+
gc never moves the directories back. Warm uses the same trash for the
|
|
9086
|
+
known paths it deletes from a copy (such as a copied .pnpm-store); gc
|
|
9087
|
+
--delete deletes such an entry (trash.json kind warm) once its claim is free,
|
|
9088
|
+
whatever the state of the worktree.
|
|
8672
9089
|
When git still refuses the removal, the kept ownership record no longer
|
|
8673
9090
|
names the devices that were parked or deleted. A workspace that is in use
|
|
8674
9091
|
(see IN USE below) keeps its directory, devices and registry entry, and the
|
|
@@ -8677,11 +9094,14 @@ LINKED WORKTREES
|
|
|
8677
9094
|
only when it has no unique commits.
|
|
8678
9095
|
|
|
8679
9096
|
IN USE
|
|
8680
|
-
gc and worktree remove never delete a workspace's directory
|
|
8681
|
-
|
|
9097
|
+
gc and worktree remove never delete a workspace's directory or checkout
|
|
9098
|
+
while it is in use: its dev server supervisor is running or
|
|
8682
9099
|
cannot be verified, a \`stim ios\`, \`stim android\` or \`stim stop\` run
|
|
8683
9100
|
holds its native-run.lock, a live or unresolvable build lock or slot names it,
|
|
8684
|
-
or its managed tunnel or managed remote lock is held.
|
|
9101
|
+
or its managed tunnel or managed remote lock is held. Build outputs follow
|
|
9102
|
+
the narrower rule in WORKSPACE BUILD OUTPUTS (\`guide cleanup disk\`): only
|
|
9103
|
+
a build, a running macOS app, or an ios, android or macos run in the last
|
|
9104
|
+
15 minutes keeps them. The deletion holds
|
|
8685
9105
|
native-run.lock itself, so no native run can start partway through. A lock
|
|
8686
9106
|
that names no workspace blocks nothing, because every build also holds its
|
|
8687
9107
|
own workspace's native-run.lock; gc lists it with the command that removes
|
|
@@ -8698,14 +9118,17 @@ SWEEPING FINISHED WORKTREES
|
|
|
8698
9118
|
ever ran in it. It groups them by git worktree and reports each linked
|
|
8699
9119
|
worktree with the reason it is removed or kept. A worktree is finished when
|
|
8700
9120
|
its branch is merged into the default branch, or its pull request was
|
|
8701
|
-
merged or closed (PULL REQUESTS below).
|
|
9121
|
+
merged or closed (PULL REQUESTS below). A clean worktree with no commits
|
|
9122
|
+
of its own counts as finished once idle (NO COMMITS OF ITS OWN below).
|
|
9123
|
+
\`--worktrees\` also removes
|
|
8702
9124
|
one that is idle: no recorded use for --older-than days, 7 without it; a
|
|
8703
9125
|
worktree whose last use is unknown is kept, unless it has no commits of its
|
|
8704
|
-
own beyond the default branch (NO COMMITS OF ITS OWN below).
|
|
8705
|
-
|
|
9126
|
+
own beyond the default branch (NO COMMITS OF ITS OWN below). Each needs a
|
|
9127
|
+
clean state, except a finished one whose changes are archived;
|
|
8706
9128
|
a worktree is kept when it is the source checkout, bare, locked, holds
|
|
8707
9129
|
another worktree (worktree remove refuses it too), in use,
|
|
8708
|
-
dirty
|
|
9130
|
+
dirty and not finished, or dirty and finished when its changes cannot be
|
|
9131
|
+
archived (ARCHIVED CHANGES below; untracked files count; pod install churn and
|
|
8709
9132
|
watchman's untracked \`.watchman-cookie-*\` files alone do not), unpushed
|
|
8710
9133
|
(commits no remote-tracking ref or other local branch reaches), or has
|
|
8711
9134
|
initialized submodules. Without --worktrees, the report leaves out the
|
|
@@ -8736,14 +9159,17 @@ SWEEPING FINISHED WORKTREES
|
|
|
8736
9159
|
an unexpired device lease. When the simulator or emulator list cannot be
|
|
8737
9160
|
read, the worktree counts as in use. A device left booted keeps the
|
|
8738
9161
|
worktree until \`stim stop\` in it, or \`gc --idle <duration>\`, shuts
|
|
8739
|
-
the device down.
|
|
9162
|
+
the device down. A worktree that holds the running stim or the realpath of
|
|
9163
|
+
the \`stim\` on PATH is in use too, and \`stim worktree remove\` refuses it
|
|
9164
|
+
even with --force, as it refuses an installed stim-server service's checkout.
|
|
8740
9165
|
|
|
8741
9166
|
RECENT ACTIVITY keeps a worktree gc would otherwise remove until
|
|
8742
9167
|
gc.worktreeGraceMinutes (120 by default, \`guide settings\`) have passed
|
|
8743
9168
|
since the latest of: a write to its git index, HEAD or HEAD reflog, a write
|
|
8744
9169
|
to its Stim workspace state or log files, and, for a merged branch, the
|
|
8745
9170
|
committer date of the commit that brought it into the default branch, or
|
|
8746
|
-
the time its pull request was merged or closed
|
|
9171
|
+
the time its pull request was merged or closed, and, for a dirty finished
|
|
9172
|
+
worktree, the newest change to its uncommitted or untracked files. That
|
|
8747
9173
|
window is when an agent that just merged runs \`stim stop\` and \`stim
|
|
8748
9174
|
worktree remove\` itself. The reason is recent-activity, and the report
|
|
8749
9175
|
and the JSON eligibleAt field say when it becomes removable. When that
|
|
@@ -8798,18 +9224,56 @@ SWEEPING FINISHED WORKTREES
|
|
|
8798
9224
|
|
|
8799
9225
|
NO COMMITS OF ITS OWN: a worktree whose HEAD the default branch contains
|
|
8800
9226
|
and whose branch has no commit made on it (fresh, cut from another
|
|
8801
|
-
branch,
|
|
8802
|
-
lose, but looks the same as one just made by git
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
9227
|
+
branch, reset onto one, or a detached HEAD; the MERGED rule above) holds
|
|
9228
|
+
nothing git would lose, but looks the same as one just made by git
|
|
9229
|
+
worktree add. gc --delete and the maintenance worktree check remove a clean
|
|
9230
|
+
one without an open pull request once the RECENT ACTIVITY sources above
|
|
9231
|
+
are older than gc.worktreeGraceMinutes and maintenance.protectRecentHours
|
|
9232
|
+
(2 hours by default), and never younger than 5 minutes (reason
|
|
9233
|
+
recent-activity until then, activity-unknown when they cannot be read). At
|
|
9234
|
+
disk pressure level 3 the window is maintenance.pressureProtectMinutes,
|
|
9235
|
+
still at least 5 minutes. Removal re-checks, under the removal locks, that
|
|
9236
|
+
HEAD did not move and the worktree is still idle, and \`stim worktree
|
|
9237
|
+
remove\` still refuses dirty or unpushed work. A process Stim does not
|
|
9238
|
+
track, such as a benchmark run from a detached build, does not keep it.
|
|
9239
|
+
|
|
9240
|
+
ARCHIVED CHANGES: a dirty worktree that is otherwise finished, idle past
|
|
9241
|
+
RECENT ACTIVITY and not in use is archived, then removed, by gc --delete
|
|
9242
|
+
and the maintenance worktree check. Under the removal locks Stim writes
|
|
9243
|
+
\`git diff --binary HEAD\` (staged and unstaged changes together) to
|
|
9244
|
+
tracked.patch, the untracked files git does not ignore to untracked.tar,
|
|
9245
|
+
HEAD's commits the default branch lacks to head.bundle,
|
|
9246
|
+
with a manifest.json naming the branch, HEAD, pull request and files, in
|
|
9247
|
+
$STIM_HOME/archive/worktrees/<repository>/<branch-or-dir>-<timestamp>/.
|
|
9248
|
+
Ignored files (node_modules, build output) are not saved. It verifies the
|
|
9249
|
+
patch with \`git apply --check -R\`, the tarball's file list, and that no
|
|
9250
|
+
archived file changed, again just before git removes the worktree; any
|
|
9251
|
+
failure keeps the worktree and deletes the archive. It also keeps a
|
|
9252
|
+
worktree whose archive.enabled is false, or false for a project registered
|
|
9253
|
+
inside it, with archive.maxAgeDays or
|
|
9254
|
+
archive.maxTotalGb 0, whose untracked files or patch exceed
|
|
9255
|
+
archive.maxTotalGb, whose archive would leave less free disk than
|
|
9256
|
+
budget.hardFloorDiskGb, whose staged version of a file differs from its
|
|
9257
|
+
working tree, or that holds an untracked nested repository; disk
|
|
9258
|
+
pressure level 3 never archives. Archives are 0700 and 0600 with no
|
|
9259
|
+
redaction, so an untracked secret such as a .env file that git does not
|
|
9260
|
+
ignore is saved; use archive.enabled false for a sensitive repository. A
|
|
9261
|
+
\`git status\` or editor refresh that rewrites the index restarts RECENT
|
|
9262
|
+
ACTIVITY. The removal line and the gc
|
|
9263
|
+
and maintenance logs name the archive and the restore commands; head.bundle
|
|
9264
|
+
exists only when the default branch lacks HEAD, and lets the restore work
|
|
9265
|
+
after the branch is deleted:
|
|
9266
|
+
git -C <repository> bundle unbundle <archive>/head.bundle (with a bundle)
|
|
9267
|
+
git -C <repository> worktree add --detach <path> <HEAD>
|
|
9268
|
+
git -C <path> apply <archive>/tracked.patch
|
|
9269
|
+
tar -xf <archive>/untracked.tar -C <path>
|
|
9270
|
+
Archive retention, which runs before and after each new worktree archive
|
|
9271
|
+
and after each removal that archives a workspace, deletes worktree archives
|
|
9272
|
+
older than archive.maxAgeDays. A new archive that would not fit beside the
|
|
9273
|
+
others in archive.maxTotalGb keeps its worktree instead, so the oldest are
|
|
9274
|
+
deleted for size only after that cap is lowered. An archive whose removal
|
|
9275
|
+
is still running holds an ownership claim and is never deleted. Plain \`stim worktree remove\` never archives; it
|
|
9276
|
+
refuses dirty work as before.
|
|
8813
9277
|
|
|
8814
9278
|
PULL REQUESTS: with fresh state, gc runs one \`gh api graphql\` query per
|
|
8815
9279
|
repository that asks for the 20 newest pull requests of each linked worktree's branch, as
|
|
@@ -9201,9 +9665,10 @@ THE ONE CASE GC WILL NOT REAP
|
|
|
9201
9665
|
summary: "disk usage, workspace build outputs, logs and device recordings, AVD and build-log sizes, the data partition, trimming the shared caches",
|
|
9202
9666
|
body: () => `DISK
|
|
9203
9667
|
Logs, state, pidfiles and Xcode DerivedData are under the global workspace
|
|
9204
|
-
directory, and \`worktree remove\` reclaims them. \`gc --delete\`
|
|
9205
|
-
|
|
9206
|
-
|
|
9668
|
+
directory, and \`worktree remove\` reclaims them. \`gc --delete\` lightens
|
|
9669
|
+
every workspace that is not building and did not run a native command in
|
|
9670
|
+
the last 15 minutes, clearing its build outputs (WORKSPACE BUILD OUTPUTS
|
|
9671
|
+
below), and keeps the rest. Gradle retains its normal
|
|
9207
9672
|
project build directories while sharing task outputs through its build cache.
|
|
9208
9673
|
|
|
9209
9674
|
Android AVDs normally live under ~/.android/avd, and a booted owned AVD can
|
|
@@ -9254,18 +9719,35 @@ a changed value.
|
|
|
9254
9719
|
WORKSPACE BUILD OUTPUTS
|
|
9255
9720
|
Each workspace directory holds derived-data/, gradle-build/, android-cas/,
|
|
9256
9721
|
cache-provider/, macos/build, the staged macos/<Product>.app and macos/staging-*
|
|
9257
|
-
leftovers.
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9722
|
+
leftovers. The project's own android/app/build, android/build,
|
|
9723
|
+
android/.gradle and .build count with them when git ignores every file in
|
|
9724
|
+
the directory and tracks none; one that fails that check, or is not in a
|
|
9725
|
+
git checkout, stays, and \`gc --delete\` prints why when the check fails
|
|
9726
|
+
between the report and the deletion. ios/build stays: React Native's pod
|
|
9727
|
+
install writes podspec facades and codegen output there that only pod
|
|
9728
|
+
install recreates. \`gc\` reports them as one
|
|
9729
|
+
detected cache, "Workspace build outputs", with a per-workspace size, last
|
|
9730
|
+
use and verdict. Plain \`gc --delete\` lightens every workspace, before
|
|
9731
|
+
anything else, by clearing them, and prints the bytes freed per workspace.
|
|
9732
|
+
A running dev server, a booted or hosted simulator or emulator and a managed
|
|
9733
|
+
tunnel no longer keep them. They stay while the workspace is building (its
|
|
9734
|
+
native-run.lock is held, a live or unresolvable build lock or slot names
|
|
9735
|
+
it, or its build claim is live), while its macOS app or build runs or cannot
|
|
9736
|
+
be verified, and for 15 minutes after its last ios, android or macos run,
|
|
9737
|
+
cache hits included, as recorded in state.json's build records. Dev server
|
|
9738
|
+
starts, reloads and logs do not count as a native run. The shared build
|
|
9739
|
+
cache, the Xcode compilation cache, the Gradle caches and the Metro cache
|
|
9740
|
+
are never touched. \`--older-than <days>\` limits that to
|
|
9261
9741
|
workspaces idle at least that long, and keeps one whose last use is
|
|
9262
9742
|
unknown. \`--cache workspaces\` acts on them alone, except in the workspace
|
|
9263
9743
|
directories that plain \`gc --delete\` removes whole (dead projects and
|
|
9264
9744
|
orphaned directories); \`--cache all\` includes them. macos/ itself,
|
|
9265
9745
|
macos/runtime.lock and its claim set, workspace.json, state.json, logs/,
|
|
9266
|
-
other macOS files, locks and device records stay
|
|
9267
|
-
|
|
9268
|
-
|
|
9746
|
+
other macOS files, locks and device records stay. The workspace keeps its
|
|
9747
|
+
devices, ports and running dev server. Automatic maintenance at disk
|
|
9748
|
+
pressure level 2 clears them by the same rule (DISK PRESSURE LEVELS); level
|
|
9749
|
+
1 keeps its own rules. A running, building, unverified or hosted macOS app
|
|
9750
|
+
keeps its workspace untouched.
|
|
9269
9751
|
stim gc --delete --cache workspaces --older-than 7
|
|
9270
9752
|
Last use is the newest of the lastUsedAt that start, ios, android, reload
|
|
9271
9753
|
and worktree warm record in state.json, lastBuild.startedAt,
|
|
@@ -9282,6 +9764,30 @@ WORKSPACE BUILD OUTPUTS
|
|
|
9282
9764
|
build recompiles Swift. The next \`stim macos\` rebuilds its scratch from
|
|
9283
9765
|
nothing (a full Swift build) and restages the app.
|
|
9284
9766
|
|
|
9767
|
+
WORKTREE DEPENDENCIES
|
|
9768
|
+
Plain \`gc --delete\` also lightens linked worktrees: it deletes the
|
|
9769
|
+
node_modules and ios/Pods at the root or a project root of a linked
|
|
9770
|
+
worktree that has a Stim workspace, never the source checkout. A worktree
|
|
9771
|
+
keeps them while it is in use (its dev server runs, a native run or build
|
|
9772
|
+
holds it), while it was used in the last 15 minutes (a git index, HEAD or
|
|
9773
|
+
reflog write, a Stim state or log write, or a write at the top of the
|
|
9774
|
+
directory), while git tracks a file in them, while a stim-server service
|
|
9775
|
+
or the stim on PATH runs from it, while a live process has its command
|
|
9776
|
+
line or working directory in it, and when the running processes cannot be
|
|
9777
|
+
listed (always on Windows). It also keeps them when \`stim worktree warm\`
|
|
9778
|
+
could not put the same thing back: warm would not copy that directory from
|
|
9779
|
+
the source checkout (it is missing there, excluded by .worktreeexclude or
|
|
9780
|
+
worktree.exclude, or inside a larger ignored directory such as a wholly
|
|
9781
|
+
ignored ios/), the worktree's lockfile (or ios/Podfile.lock for Pods)
|
|
9782
|
+
differs from the source checkout's, or the source checkout's own copy was
|
|
9783
|
+
not installed from its lockfile. gc records what it deleted in the
|
|
9784
|
+
workspace's lightened.json; the next \`stim start\`, \`stim ios\` or
|
|
9785
|
+
\`stim android\` there runs \`stim worktree warm\` first to restore it, and
|
|
9786
|
+
refuses with STIM_DEPS_FAILED, keeping the record, when those checks no
|
|
9787
|
+
longer pass, when warm fails, or when it leaves a directory missing. A
|
|
9788
|
+
deletion that stopped part-way is finished before the warm. Other commands, such as a test run, find the directory missing
|
|
9789
|
+
until then. .pnpm-store stays: it is all clones and frees nothing.
|
|
9790
|
+
|
|
9285
9791
|
WORKSPACE LOGS
|
|
9286
9792
|
\`gc\` reports the size of each workspace's logs/ (the workspaceLogs
|
|
9287
9793
|
section of \`gc --json\`). metro.ndjson, client.ndjson and device.ndjson and
|
|
@@ -9341,6 +9847,12 @@ SHARED BUILD CACHES
|
|
|
9341
9847
|
report-only because every Gradle build shares it. Stim reports its size
|
|
9342
9848
|
but never prunes or empties it, including with --older-than or --cache all.
|
|
9343
9849
|
|
|
9850
|
+
A cache directory that \`gc --delete --older-than\` cannot list (EACCES,
|
|
9851
|
+
EPERM or ELOOP, for example) is a failed trim, not an empty one: the run
|
|
9852
|
+
prints "N entries in <dir> could not be read or removed", records the cache
|
|
9853
|
+
as failed and exits 1. Fix the directory's permissions and run it again. A
|
|
9854
|
+
directory that is missing or is not a directory is not a failure.
|
|
9855
|
+
|
|
9344
9856
|
Trim rather than empty. Emptying costs the next build in every project the
|
|
9345
9857
|
time the cache was saving.`
|
|
9346
9858
|
}
|
|
@@ -9461,12 +9973,16 @@ KEYS STIM READS
|
|
|
9461
9973
|
embedded JS, no Metro, cache keyed -release-sim, and
|
|
9462
9974
|
a JS-bundle swap on cache hits. The \`--configuration\`
|
|
9463
9975
|
flag overrides this per invocation. Unset means Debug.
|
|
9464
|
-
ios.remote
|
|
9465
|
-
remote
|
|
9466
|
-
"auto"
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9976
|
+
ios.remote where the simulator runs, with the same meaning as
|
|
9977
|
+
--remote: "local" here, even when a lower layer says
|
|
9978
|
+
otherwise; "auto" here, and on an approved Mac from
|
|
9979
|
+
remote.machines when this machine is full or busy;
|
|
9980
|
+
"remote" on the first approved Mac in remote.machines
|
|
9981
|
+
order with room, here only when none takes it;
|
|
9982
|
+
"remote-only" the same but never here; a named
|
|
9983
|
+
approved Mac exactly that Mac; "proxy" or "eas" a
|
|
9984
|
+
remote device backend. Unset runs here. A --device run
|
|
9985
|
+
ignores it. See lifecycle hosted-ios.
|
|
9470
9986
|
ios.projectPath directory under the app holding a bare React Native
|
|
9471
9987
|
app's Xcode project and Podfile; default "ios". "."
|
|
9472
9988
|
is the app directory itself (RNTester's layout).
|
|
@@ -9495,9 +10011,9 @@ KEYS STIM READS
|
|
|
9495
10011
|
iOS work after reviewing service tradeoffs; see
|
|
9496
10012
|
\`stim guide lifecycle simslim\`. Each local \`stim ios\`
|
|
9497
10013
|
reconciles the profile on its Stim-owned simulator.
|
|
9498
|
-
The first change can reboot it;
|
|
9499
|
-
|
|
9500
|
-
when Stim applied the profile. Absolute paths, root or
|
|
10014
|
+
The first change can reboot it; an unchanged profile on
|
|
10015
|
+
the same boot is skipped. Removing the setting
|
|
10016
|
+
restores stock services when Stim applied the profile. Absolute paths, root or
|
|
9501
10017
|
symlink escapes, and missing files are refused before
|
|
9502
10018
|
simulator creation. Remote and unowned simulators are
|
|
9503
10019
|
never changed.
|
|
@@ -9687,14 +10203,13 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
9687
10203
|
password, handed to apksigner through its
|
|
9688
10204
|
environment, never its command line. Unset means
|
|
9689
10205
|
the debug keystore's fixed "android".
|
|
9690
|
-
android.remote
|
|
9691
|
-
remote
|
|
9692
|
-
|
|
9693
|
-
runs here
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
--remote auto) run the simulator or emulator on a
|
|
10206
|
+
android.remote where the emulator runs, with the same words as
|
|
10207
|
+
ios.remote: "local", "auto", "remote", "remote-only",
|
|
10208
|
+
a named approved Mac in remote.machines, "proxy" or
|
|
10209
|
+
"eas". Unset runs here. A --device run ignores it. See
|
|
10210
|
+
lifecycle hosted-android.
|
|
10211
|
+
remote.easFallback true lets "auto" or "remote" (ios.remote, android.remote
|
|
10212
|
+
or --remote) run the simulator or emulator on a
|
|
9698
10213
|
billed EAS Simulator when this machine is at its
|
|
9699
10214
|
concurrency.maxDevices cap (or has runs queued) and no
|
|
9700
10215
|
remote.machines entry takes the run, instead of waiting
|
|
@@ -9828,6 +10343,16 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
9828
10343
|
compiled into Contents/Resources before signing
|
|
9829
10344
|
macos.resources map of Contents/Resources destinations to source paths
|
|
9830
10345
|
relative to Package.swift; see stim guide macos
|
|
10346
|
+
macos.remote where stim macos launches the app, with the words of
|
|
10347
|
+
ios.remote except "eas" and "proxy": "local" here;
|
|
10348
|
+
"auto" here unless this machine is busy, then an
|
|
10349
|
+
approved Mac in remote.machines; "remote" on the
|
|
10350
|
+
first approved Mac in order with room, here only when
|
|
10351
|
+
none takes it; "remote-only" the same but never here,
|
|
10352
|
+
which keeps the app from taking focus on this Mac; a
|
|
10353
|
+
named Mac exactly that Mac. The --remote flag
|
|
10354
|
+
overrides it. A recorded hosted app keeps its Mac
|
|
10355
|
+
until stim stop. Unset runs here. See stim guide macos.
|
|
9831
10356
|
web.url the page \`stim web\` opens in the owned Chrome, an
|
|
9832
10357
|
http:// or https:// URL. {port:<label>} becomes the
|
|
9833
10358
|
workspace's named port (allocated like \`stim ports
|
|
@@ -9885,8 +10410,9 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
9885
10410
|
them from the environment or the machine layers.
|
|
9886
10411
|
|
|
9887
10412
|
Each setting takes its documented type: string, array of strings, number,
|
|
9888
|
-
boolean, or object. ios.remote
|
|
9889
|
-
|
|
10413
|
+
boolean, or object. ios.remote, android.remote, macos.remote and remote.build
|
|
10414
|
+
accept placement words (local, auto, remote, remote-only) or tailnet machine
|
|
10415
|
+
names, and ios.remote and android.remote also the backend names. metro.tunnel, web.viewport,
|
|
9890
10416
|
optimizations.android.compilerCache and optimizations.android.pch take only
|
|
9891
10417
|
their listed choices. A value of the wrong
|
|
9892
10418
|
type or outside those choices is refused by name on every command that resolves
|
|
@@ -10088,6 +10614,11 @@ never decide who the worker is. With --fix, a pending entry is replaced when
|
|
|
10088
10614
|
STIM_ACCESS_TICKET names another ticket.
|
|
10089
10615
|
Approved doctor entries under remoteMachines and deviceHosts include host
|
|
10090
10616
|
{ name, screenRecording, accessibility } when the worker reports it.
|
|
10617
|
+
A remote machine doctor cannot use carries a diagnosis { layer, code, title,
|
|
10618
|
+
message, remedy } naming the first layer that failed: Tailscale on this machine,
|
|
10619
|
+
the peer, the serve route, stim-server, or compatibility. Tell the user its
|
|
10620
|
+
message and remedy; the remedies run on the remote machine or in Tailscale, so
|
|
10621
|
+
agents do not run them. \`stim guide facts doctor\` lists the codes.
|
|
10091
10622
|
|
|
10092
10623
|
REMOTE MACHINES AND PHONE APP
|
|
10093
10624
|
When the user mentions slow builds, a busy machine, a full disk or device limit, or
|
|
@@ -10107,6 +10638,21 @@ simulator sessions on, by MagicDNS name with an optional serve port (default
|
|
|
10107
10638
|
stim settings set remote.machines '["janics-mac-mini"]'
|
|
10108
10639
|
stim doctor --fix
|
|
10109
10640
|
|
|
10641
|
+
The order of \`remote.machines\` is the priority order for every workload: the
|
|
10642
|
+
build, simulator, emulator and macOS app each go to the first listed machine that
|
|
10643
|
+
has approval, a free slot and a 5-minute load per core under that machine's own
|
|
10644
|
+
\`server.maxLoadPerCore\`, and the next one in order only when it does not. A
|
|
10645
|
+
machine at its caps, over its load limit, unreachable or lacking approval is
|
|
10646
|
+
skipped; load does not rank the machines that qualify, so the first one fills
|
|
10647
|
+
before the next is used. Put the fastest machine first and set the order with
|
|
10648
|
+
one command; \`stim doctor\` prints it as \`placement order\` and gives each
|
|
10649
|
+
machine a \`priority\` in its JSON:
|
|
10650
|
+
|
|
10651
|
+
stim settings set remote.machines '["fast-mini","slow-mini"]'
|
|
10652
|
+
|
|
10653
|
+
A host reports its own load limit in its device offer; a stim-server older than
|
|
10654
|
+
that does not, and this machine's \`server.maxLoadPerCore\` stands in for it.
|
|
10655
|
+
|
|
10110
10656
|
Automatic membership is separate from approval. In Desktop Settings > Remote
|
|
10111
10657
|
Machines, use Builds enabled and Simulators enabled for this machine or a
|
|
10112
10658
|
configured remote. The equivalent machine settings list the excluded members;
|
|
@@ -10194,9 +10740,9 @@ An invalid remote.machines setting reports an error and preserves every saved cr
|
|
|
10194
10740
|
replaced machine, run it, then re-add the name to request a new approval.
|
|
10195
10741
|
A definite revoked or lapsed request can be requested again with --fix.
|
|
10196
10742
|
An in-progress approval inspection reports busy rather than replacing its
|
|
10197
|
-
pending token. \`stim macos --remote <
|
|
10198
|
-
approved remote Mac (stim guide macos)
|
|
10199
|
-
place
|
|
10743
|
+
pending token. \`stim macos --remote <placement>\` or \`macos.remote\` runs a macOS
|
|
10744
|
+
app on an approved remote Mac (stim guide macos), and \`ios.remote\` and
|
|
10745
|
+
\`android.remote\` place simulators and emulators on them. To view or control a hosted macOS app, a person
|
|
10200
10746
|
on that Mac approves Screen & System Audio Recording and Device Control and Data
|
|
10201
10747
|
Access (Accessibility on macOS 26 and earlier) for Stim Host, the app
|
|
10202
10748
|
\`stim-server service install\` runs the server under.
|
|
@@ -10243,18 +10789,35 @@ builds, or the build messages change; their Stim builds can differ. A
|
|
|
10243
10789
|
stim-server too old to report one needs the same Stim build as this machine.
|
|
10244
10790
|
|
|
10245
10791
|
\`remote.build\` (machine scope, default auto) selects placement for
|
|
10246
|
-
\`ios\`, \`android\` and \`macos\`. \`--remote-build <auto|
|
|
10792
|
+
\`ios\`, \`android\` and \`macos\`. \`--remote-build <local|auto|remote|remote-only|name>\`
|
|
10247
10793
|
overrides STIM_REMOTE_BUILD, which overrides the setting. A blank environment
|
|
10248
|
-
value is unset.
|
|
10794
|
+
value is unset. \`doctor\` flags an invalid value in the machine config or in
|
|
10795
|
+
STIM_REMOTE_BUILD before a build refuses on it. Trimmed placement words are case-insensitive. Machine names match
|
|
10249
10796
|
configured names case-insensitively, with port 7443 when omitted; reports use
|
|
10250
10797
|
the configured entry.
|
|
10251
10798
|
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10799
|
+
local builds only on this machine for this invocation
|
|
10800
|
+
auto (default) here while this machine has capacity, a remote
|
|
10801
|
+
machine from remote.machines when it does not; only enabled
|
|
10802
|
+
automatic pool members count
|
|
10803
|
+
remote on the first remote machine in remote.machines order that
|
|
10804
|
+
accepts the build, here only when none does
|
|
10805
|
+
remote-only the same, never here: when no remote machine accepts the build
|
|
10806
|
+
it refuses with STIM_OFFLOAD_REFUSED
|
|
10807
|
+
name requires a matching entry in remote.machines, already paired and
|
|
10808
|
+
approved for builds; ignores this machine's load/slot gating
|
|
10809
|
+
|
|
10810
|
+
\`remote.buildMode\` and STIM_REMOTE_BUILD_MODE were removed and are no longer read.
|
|
10811
|
+
\`doctor\` and \`stim settings\` report any left in a config file or the environment,
|
|
10812
|
+
\`stim settings set remote.buildMode\` refuses with the \`remote.build\` command that
|
|
10813
|
+
replaces it (auto stays auto, force becomes remote, off becomes local), and
|
|
10814
|
+
\`stim settings unset remote.buildMode\` removes the leftover key from every layer
|
|
10815
|
+
that has it (--scope limits it to one).
|
|
10256
10816
|
|
|
10257
10817
|
A name never prompts for pairing, tries another remote machine or falls back here.
|
|
10818
|
+
remote-only refuses instead of building here for a build that cannot leave this
|
|
10819
|
+
machine (device, Release, an unknown simulator runtime, the build cache off), and
|
|
10820
|
+
when no pairing or approval exists.
|
|
10258
10821
|
Any refusal or failure is STIM_OFFLOAD_REFUSED with the remote machine and reason.
|
|
10259
10822
|
Device, Release/non-Debug, --remote, Android CAS compiler builds, builds with
|
|
10260
10823
|
the build cache off, and an unknown simulator runtime cannot build there and
|
|
@@ -10263,7 +10826,8 @@ at setup before consulting the cache; they create no build record or failed-run
|
|
|
10263
10826
|
stats. A listed paired name with a cache hit compiles nothing, contacts no worker
|
|
10264
10827
|
and records buildMachine with builtOn absent. Build failures retain the selected
|
|
10265
10828
|
value; builtOn is here or the configured machine entry when compilation ran.
|
|
10266
|
-
Prebuild and pod install still run on this machine before a named offload
|
|
10829
|
+
Prebuild and pod install still run on this machine before a named offload; stim ios
|
|
10830
|
+
checks the machine's toolchain first. A refusal
|
|
10267
10831
|
starts no local xcodebuild, Gradle or SwiftPM compile.
|
|
10268
10832
|
A React Native offload sends the tracked and untracked files, and the gitignored
|
|
10269
10833
|
files the native fingerprint hashes or the Expo config reads, such as .env.local
|
|
@@ -10280,26 +10844,29 @@ Copyable agent prompt:
|
|
|
10280
10844
|
Run stim ios --remote-build janics-mac-mini. If it refuses, report the
|
|
10281
10845
|
STIM_OFFLOAD_REFUSED reason and remedy; do not retry with another placement.
|
|
10282
10846
|
|
|
10283
|
-
|
|
10284
|
-
|
|
10847
|
+
Which remote machine takes a build that leaves this machine follows the order of
|
|
10848
|
+
\`remote.machines\`: the first machine that accepts it, meaning it has a free slot
|
|
10849
|
+
(\`concurrency.maxBuilds\`), enough disk, a matching toolchain, and a load per core
|
|
10850
|
+
under its own \`server.maxLoadPerCore\`. A machine past its limit is skipped like a
|
|
10851
|
+
full one and the next in order is tried; the first machine fills to its caps before
|
|
10852
|
+
the next one gets a build. A machine that already holds the exact completed
|
|
10853
|
+
artifact goes ahead of the order, since that needs no build. With \`auto\` the
|
|
10854
|
+
build leaves this machine only when it is busy:
|
|
10285
10855
|
|
|
10286
10856
|
auto (default) here while this machine has capacity: a free
|
|
10287
10857
|
\`concurrency.maxBuilds\` slot (always, with no build limit) and a
|
|
10288
|
-
load per core under \`server.maxLoadPerCore\`. Otherwise on
|
|
10289
|
-
remote machine that accepts the build
|
|
10290
|
-
while every slot here is busy
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
and install marker remain present.
|
|
10301
|
-
Older workers' dependency hints and mere checkout or build-folder presence do
|
|
10302
|
-
not influence this ranking. Exact completed-artifact hits still come first.
|
|
10858
|
+
load per core under \`server.maxLoadPerCore\`. Otherwise on the first
|
|
10859
|
+
remote machine in order that accepts the build. A machine too old to
|
|
10860
|
+
report its load counts only while every slot here is busy.
|
|
10861
|
+
remote on the first remote machine in order that accepts the build, whatever
|
|
10862
|
+
load this machine is under; here only when none does
|
|
10863
|
+
remote-only as remote, but when none does the build refuses
|
|
10864
|
+
|
|
10865
|
+
A worker that holds a matching dependency installation does not rank ahead of an
|
|
10866
|
+
earlier machine in the order; it only saves the install on the machine that gets
|
|
10867
|
+
the build. The worker checks the requested project, lockfile, install arguments
|
|
10868
|
+
and the major of the Node the app pins, and verifies that its modules and install
|
|
10869
|
+
marker remain present.
|
|
10303
10870
|
|
|
10304
10871
|
The worker installs dependencies with the lockfile nearest the app: the first
|
|
10305
10872
|
pnpm-lock.yaml, yarn.lock or package-lock.json in its directory or above it in
|
|
@@ -10324,10 +10891,11 @@ Load per core is the 5-minute load average divided by the CPU count; a machine's
|
|
|
10324
10891
|
native builds are its Stim runs in prebuild, pods or compile on that machine, not
|
|
10325
10892
|
the ones it offloaded.
|
|
10326
10893
|
\`server.maxLoadPerCore\` (default 2) is also the busy threshold for
|
|
10327
|
-
automatic iOS and
|
|
10328
|
-
counts as saturated
|
|
10894
|
+
automatic iOS, Android and macOS placement. It is the load per core at which a
|
|
10895
|
+
machine counts as saturated: each machine applies its own value, and a remote
|
|
10896
|
+
machine past it is skipped like a full one.
|
|
10329
10897
|
|
|
10330
|
-
|
|
10898
|
+
Device, Release and
|
|
10331
10899
|
\`--remote eas|proxy\` builds, Android builds with the Apple Clang CAS compiler cache,
|
|
10332
10900
|
and iOS/Android runs with the build cache off, always build here. Hosted iOS
|
|
10333
10901
|
Debug builds can use a separate --remote-build, targeting the hosting Mac's
|
|
@@ -10340,7 +10908,7 @@ verified compile; remote output is not published under an unverified client key.
|
|
|
10340
10908
|
An offloaded iOS/Android build first runs prebuild (and \`pod install\` for iOS) here,
|
|
10341
10909
|
then asks every paired machine what it can build. It takes one whose Stim
|
|
10342
10910
|
build matches this Mac and, for iOS and macOS, CPU matches the target simulator, with enough disk, that does not decline,
|
|
10343
|
-
|
|
10911
|
+
taking the first in remote.machines order that qualifies,
|
|
10344
10912
|
and moves to the next one in that order when a machine that offered fails the
|
|
10345
10913
|
sync or refuses to start the build.
|
|
10346
10914
|
After a local and configured-provider miss, native Xcode simulator builds can
|
|
@@ -10360,18 +10928,44 @@ match. Completed archives survive worker checkout changes or removal; hits
|
|
|
10360
10928
|
need no source upload or build slot. Disabled remote artifact reads skip this
|
|
10361
10929
|
lookup. Release and physical-device builds keep their existing paths.
|
|
10362
10930
|
SwiftPM, compiler and dependency caches use their existing paths.
|
|
10363
|
-
For iOS the machine's Xcode and simulator SDK must match
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10931
|
+
For iOS the machine's Xcode and simulator SDK must match. Its offer reports the
|
|
10932
|
+
developerDir xcode-select prints and the Xcode apps in /Applications (version,
|
|
10933
|
+
build, and license and first-launch checks while no Xcode works), so doctor's
|
|
10934
|
+
fix for no usable Xcode is the exact command to run there: sudo xcode-select -s
|
|
10935
|
+
<the Xcode with this machine's build, else the newest>/Contents/Developer when
|
|
10936
|
+
the Command Line Tools or another Xcode is selected, sudo xcodebuild -license
|
|
10937
|
+
accept and sudo xcodebuild -runFirstLaunch for the checks that fail, or xcodes
|
|
10938
|
+
install <version> with no Xcode app. A runtime the machine lacks gets
|
|
10939
|
+
xcodebuild -downloadPlatform iOS -buildVersion <version>, or a pointer to the
|
|
10940
|
+
Xcode problem when xcode-select is the cause. A stim-server that reports no
|
|
10941
|
+
developerDir keeps the prose fix. It also needs an
|
|
10942
|
+
iPhone simulator on the target runtime. A missing or different global CocoaPods
|
|
10943
|
+
keeps auto, remote and remote-only placement from choosing the machine for a project that does not
|
|
10944
|
+
pin it, unless the machine already holds the exact artifact; the placement line
|
|
10945
|
+
says why and doctor shows the install command. A named --remote-build still
|
|
10946
|
+
sends the build, and a pod install that fails there reports "pod install failed"
|
|
10947
|
+
with the fix on that machine. When the app's Gemfile.lock, in ios/ or the project
|
|
10948
|
+
root, pins CocoaPods, both machines run that version through
|
|
10949
|
+
bundler, so the machine needs Bundler on its stim-server PATH and
|
|
10367
10950
|
installs the pinned gems itself on the first build. This Mac's side of the
|
|
10368
10951
|
comparison runs \`pod --version\` in the directory pod install runs in. The comparison selects
|
|
10369
10952
|
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.
|
|
10370
10953
|
For Android its CPU may differ, since the APK's ABIs come from the NDK, so an
|
|
10371
10954
|
x86_64 Linux or Windows machine running stim-server can build for an Apple silicon Mac. Its JDK major
|
|
10372
|
-
version must match,
|
|
10955
|
+
version must match this machine's, which can be an installed JDK that is not the
|
|
10956
|
+
worker's default: its offer lists \`jdks\`, and a build sent with the build-jdk
|
|
10957
|
+
feature runs with JAVA_HOME at the one of that major. A major no installed JDK
|
|
10958
|
+
has gets the install command for the worker's OS as doctor's fix. A nearby major
|
|
10959
|
+
never counts (Gradle, AGP and Kotlin support and the shared build cache assume
|
|
10960
|
+
one JDK). Also, its Android SDK must hold the NDK, build-tools and
|
|
10373
10961
|
compile platform that the project's React Native version names in
|
|
10374
|
-
gradle/libs.versions.toml; Gradle and AGP come from the synced project.
|
|
10962
|
+
gradle/libs.versions.toml; Gradle and AGP come from the synced project. A
|
|
10963
|
+
package the SDK lacks is a note, not a blocker, when its offer reports the SDK
|
|
10964
|
+
licenses accepted (\`licenses/android-sdk-license\`) and the app's
|
|
10965
|
+
Gradle root's gradle.properties does not set android.builder.sdkDownload=false:
|
|
10966
|
+
Gradle downloads the package on the first build there (the NDK is about 1-2 GB).
|
|
10967
|
+
Otherwise it blocks, and doctor's fix is the sdkmanager commands to run on that
|
|
10968
|
+
machine; a stim-server that does not report its licenses keeps that rule. When
|
|
10375
10969
|
no machine takes the build in auto placement, the run prints one line with each machine's
|
|
10376
10970
|
reason, such as \`janics-mac-mini: busy (load at or above 2/core; load
|
|
10377
10971
|
8.2/core, 2 builds) -> building here\`, and compiles here. It sends the files
|
|
@@ -10510,6 +11104,9 @@ be setup steps are supplied by Stim on the command lines it composes itself:
|
|
|
10510
11104
|
SWIFT_OTHER_PREFIX_MAPPINGS on a Swift 6.4+ toolchain -- so no
|
|
10511
11105
|
Podfile post_install block (Xcode 26+ only, and skipped when the
|
|
10512
11106
|
project configured ccache, which defeats it)
|
|
11107
|
+
Debug builds for the iOS simulator also get
|
|
11108
|
+
DEBUG_INFORMATION_FORMAT=dwarf, which skips the dSYM bundle;
|
|
11109
|
+
Release and device builds keep the project's setting
|
|
10513
11110
|
gradlew --build-cache -- so no org.gradle.caching=true in a committed
|
|
10514
11111
|
gradle.properties. Debug builds add
|
|
10515
11112
|
-PreactNativeArchitectures=<target ABI> when the owned
|
|
@@ -10968,7 +11565,7 @@ var macos_default = {
|
|
|
10968
11565
|
|
|
10969
11566
|
If Stim is not installed globally, replace stim with npx stim.
|
|
10970
11567
|
|
|
10971
|
-
ios --remote <
|
|
11568
|
+
ios --remote <placement> shares remote.machines and its separate device-host
|
|
10972
11569
|
approval. Read guide lifecycle hosted-ios for simulator placement and Metro.
|
|
10973
11570
|
|
|
10974
11571
|
Run from the directory containing Package.swift. This prototype builds one
|
|
@@ -11072,7 +11669,7 @@ Apple Swift, xcrun and xcodebuild selections can be reproduced; custom launchers
|
|
|
11072
11669
|
require the checkout and otherwise miss safely. SWIFT_EXEC and SWIFT_EXEC_MANIFEST
|
|
11073
11670
|
compiler overrides are resolved and versioned separately and require the checkout.
|
|
11074
11671
|
The SDK selected by SDKROOT or SWIFTPM_SDKROOT_macosx is checked by real path and build version. Explicit local placement,
|
|
11075
|
-
|
|
11672
|
+
disabled pool members and remoteBuildCache
|
|
11076
11673
|
false skip peer lookup. Older workers keep their normal compilation path.
|
|
11077
11674
|
--plan validates the Swift Package directory, macos settings, development plist
|
|
11078
11675
|
and declared resources without building, signing, stopping or launching
|
|
@@ -11104,17 +11701,16 @@ line instead of when the app exits.
|
|
|
11104
11701
|
|
|
11105
11702
|
BUILD OFFLOAD
|
|
11106
11703
|
|
|
11107
|
-
--remote-build <auto|
|
|
11704
|
+
--remote-build <local|auto|remote|remote-only|name> overrides STIM_REMOTE_BUILD and the
|
|
11108
11705
|
machine setting remote.build (default auto). local builds here; a name
|
|
11109
|
-
requires the matching configured and paired remote Mac, ignoring
|
|
11110
|
-
and this Mac's capacity. Any failure is STIM_OFFLOAD_REFUSED without a local xcodebuild, Gradle or
|
|
11706
|
+
requires the matching configured and paired remote Mac, ignoring this Mac's capacity. Any failure is STIM_OFFLOAD_REFUSED without a local xcodebuild, Gradle or
|
|
11111
11707
|
SwiftPM compile or another machine. Invalid, unlisted or unpaired selections
|
|
11112
11708
|
refuse before stopping the app or changing its build record. See stim guide errors STIM_OFFLOAD_REFUSED.
|
|
11113
11709
|
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11710
|
+
remote.build places these SwiftPM Debug builds: auto builds here while this Mac has
|
|
11711
|
+
capacity, remote uses the first approved build machine in remote.machines order that
|
|
11712
|
+
accepts and otherwise builds here, remote-only never builds here and refuses when none
|
|
11713
|
+
accepts, and local builds here. remote.buildPoolDisabled excludes members from automatic placement,
|
|
11118
11714
|
including its local fallback. Explicit local or named placement bypasses membership.
|
|
11119
11715
|
Configure remote.machines
|
|
11120
11716
|
and approve build access as described in stim guide settings. The worker needs
|
|
@@ -11136,8 +11732,8 @@ identity comes from the worker's toolchain. Any other combination keeps the matc
|
|
|
11136
11732
|
The client validates the development plist and resource entries before asking a machine. It verifies
|
|
11137
11733
|
the returned archive's sha256, bundle identifier, executable, declared resources
|
|
11138
11734
|
and ad hoc signature
|
|
11139
|
-
before replacing the owned bundle, then launches locally as usual. With auto, every offload
|
|
11140
|
-
failure falls back to the local build
|
|
11735
|
+
before replacing the owned bundle, then launches locally as usual. With auto or remote, every offload
|
|
11736
|
+
failure falls back to the local build. Failed staging preserves
|
|
11141
11737
|
the previous bundle. No failed artifact is promoted or cached. The build record
|
|
11142
11738
|
is unchanged by invalid, unlisted or unpaired setup refusals. It
|
|
11143
11739
|
carries buildMachine (selected) and builtOn (here or the machine, absent until
|
|
@@ -11299,19 +11895,40 @@ used.
|
|
|
11299
11895
|
|
|
11300
11896
|
ON ANOTHER MAC
|
|
11301
11897
|
|
|
11302
|
-
stim macos --remote <machine> builds the Debug app on this Mac and runs it on an
|
|
11898
|
+
stim macos --remote <machine> or macos.remote builds the Debug app on this Mac and runs it on an
|
|
11303
11899
|
approved remote Mac over the tailnet, without SSH. The Mac must be listed
|
|
11304
11900
|
in remote.machines and approved: stim doctor --fix makes a setup ticket, a
|
|
11305
11901
|
person on that Mac runs stim-server setup with that ticket and expiry (guide
|
|
11306
11902
|
settings), and stim doctor then pins that Mac's stim-server key. Stim goes ahead
|
|
11307
11903
|
only with the stim-server that proves it holds that key.
|
|
11308
|
-
A refusal or an unreachable host fails the command; it never launches here
|
|
11904
|
+
A refusal or an unreachable host fails the command; with a named Mac it never launches here
|
|
11309
11905
|
instead.
|
|
11310
11906
|
|
|
11311
|
-
The --remote
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11907
|
+
The --remote flag and the macos.remote setting take the placement words of
|
|
11908
|
+
ios.remote and a remote Mac name from remote.machines; the flag overrides the
|
|
11909
|
+
setting:
|
|
11910
|
+
|
|
11911
|
+
local launch here (the default when neither is set)
|
|
11912
|
+
auto launch here unless this Mac is busy (host memory pressure or load
|
|
11913
|
+
per core at or above server.maxLoadPerCore), then on the first
|
|
11914
|
+
approved Mac in remote.machines order that has room
|
|
11915
|
+
remote on the first approved Mac in remote.machines order that has room
|
|
11916
|
+
and a load per core under its own server.maxLoadPerCore, here only
|
|
11917
|
+
when none does
|
|
11918
|
+
remote-only the same, never here, so a macOS app never takes focus on this Mac:
|
|
11919
|
+
when every Mac that answered is only full or loaded it waits up to
|
|
11920
|
+
600 seconds for one with room and then refuses with STIM_AT_CAPACITY;
|
|
11921
|
+
with no Mac that could ever take it (none configured, unreachable,
|
|
11922
|
+
declined for another reason) it refuses at once with
|
|
11923
|
+
STIM_HOSTING_REFUSED and the reason each Mac was skipped
|
|
11924
|
+
<machine> exactly that Mac, with no fallback
|
|
11925
|
+
|
|
11926
|
+
A placement word picks the Mac on a new launch and keeps the recorded one while an
|
|
11927
|
+
app runs there, until stim stop. The command prints a placement: line with the
|
|
11928
|
+
choice and the skipped Macs. macOS refuses eas and proxy because it has neither
|
|
11929
|
+
backend. Reserved names are case-insensitive and trimmed; they refuse with
|
|
11930
|
+
STIM_BAD_ARG before state access or a connection. The device pool switches
|
|
11931
|
+
(remote.devicePoolDisabled) also apply to automatic macOS placement.
|
|
11315
11932
|
|
|
11316
11933
|
Logs: the host records the hosted app's stdout, stderr and exit like a local run.
|
|
11317
11934
|
stim logs, including --errors, --json and --follow, asks the host over the same
|