stim 1.23.0 → 1.24.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.
Files changed (169) hide show
  1. package/README.md +3 -2
  2. package/dist/{acquire-artifact-ybouwJSR.mjs → acquire-artifact-CEs02U2o.mjs} +2 -2
  3. package/dist/{act-DG54PWtJ.mjs → act-Cyvm8xYc.mjs} +40 -25
  4. package/dist/{activity-B5RtpFda.mjs → activity-Dq3ZcdD8.mjs} +6 -6
  5. package/dist/{agent-device-usage-output-UJ5gC80l.mjs → agent-device-usage-output-CccomeE0.mjs} +5 -5
  6. package/dist/{android-C7sVmyI9.mjs → android-882m4hxX.mjs} +140 -46
  7. package/dist/{android-BoUJKbfz.mjs → android-BZppyPe_.mjs} +66 -46
  8. package/dist/{android-DR5lZ2Az.mjs → android-CX5IcRuf.mjs} +13 -3
  9. package/dist/{android-CHH4KLOR.mjs → android-DcztblCT.mjs} +5 -5
  10. package/dist/{android-cas-ngferVq2.mjs → android-cas-BtCOrNqb.mjs} +3 -3
  11. package/dist/android-cas-compiler.mjs +1 -1
  12. package/dist/api.d.mts +22 -4
  13. package/dist/api.mjs +32 -31
  14. package/dist/{artifact-5RteZem7.mjs → artifact-BR5VNArK.mjs} +17 -16
  15. package/dist/{artifact-Dwdo7k1E.mjs → artifact-Bdt_n9Jc.mjs} +17 -16
  16. package/dist/{artifact-platform-CXcmX_j3.mjs → artifact-platform-CMRc0M_r.mjs} +3 -3
  17. package/dist/{browser-web-CeEVlGug.mjs → browser-web-ycg9qWB8.mjs} +16 -17
  18. package/dist/{budget-DnPX3DXj.mjs → budget-dPGuhNai.mjs} +101 -40
  19. package/dist/{build-CqufZFqy.mjs → build-CaF574eS.mjs} +31 -28
  20. package/dist/{build-cache-Dv7RN200.mjs → build-cache-HFUQ9eLz.mjs} +152 -19
  21. package/dist/{build-plan-C8CIvRyi.mjs → build-plan-JsDUq4w1.mjs} +8 -7
  22. package/dist/{cache-manifest-DSeQjt-Q.mjs → cache-manifest-BPXRONJz.mjs} +1 -1
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{ccache-RcAy92gH.mjs → ccache-CCn1S6qG.mjs} +6 -6
  25. package/dist/{cdp-3fwICjzi.mjs → cdp-BG3FJCCx.mjs} +1 -1
  26. package/dist/{chrome-Bbw689-6.mjs → chrome-BvV8ssI3.mjs} +1 -1
  27. package/dist/{cli-D-J9fWGV.mjs → cli-xqAidP7O.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-yyso1bwi.mjs → client-18-ZowoT.mjs} +254 -28
  30. package/dist/collector-run.mjs +6 -6
  31. package/dist/{command-output-Db8BqzxH.mjs → command-output-DxC0k2rk.mjs} +3 -2
  32. package/dist/{config-DlrsduwG.mjs → config-BZhXY15H.mjs} +3 -3
  33. package/dist/{created-devices-x9rN6bhs.mjs → created-devices-D2Aca-xu.mjs} +6 -2
  34. package/dist/{dependency-state-1I9KZT1Y.mjs → dependency-state-C56ll9hY.mjs} +2 -2
  35. package/dist/{detached-entry-BwNEtIrP.mjs → detached-entry-KmieOKgN.mjs} +1 -1
  36. package/dist/{dev-client-BnYSDiKa.mjs → dev-client-w_fok0Ek.mjs} +3 -3
  37. package/dist/{device-BvzPUBs3.mjs → device-4RUugw5X.mjs} +16 -16
  38. package/dist/{device-CCkWmkAA.mjs → device-BktRGdjS.mjs} +40 -44
  39. package/dist/{device-capacity-CjaSdrhg.mjs → device-capacity-Ic-kdmEV.mjs} +20 -16
  40. package/dist/device-host-worker.mjs +17 -17
  41. package/dist/{device-ios-uOiEETX2.mjs → device-ios-DzpSlZyd.mjs} +23 -24
  42. package/dist/{device-lease-run-BgwPHc6u.mjs → device-lease-run-DUtkbqBQ.mjs} +5 -5
  43. package/dist/{device-pool-C-ptmZTa.mjs → device-pool-CgBHk401.mjs} +3 -3
  44. package/dist/{doctor-pxxvipYC.mjs → doctor-BZ6oxNum.mjs} +1 -1
  45. package/dist/{doctor-8sr2tFOL.mjs → doctor-C33AzVfR.mjs} +28 -28
  46. package/dist/{doctor-D2SN3Ltx.mjs → doctor-DZgpqR6J.mjs} +17 -16
  47. package/dist/{doctor-fingerprint-DZLoYFVb.mjs → doctor-fingerprint-zlujA1Gs.mjs} +1 -1
  48. package/dist/doctor-fingerprint.mjs +1 -1
  49. package/dist/{doctor-watchman-sy_RNhFt.mjs → doctor-watchman-B453A231.mjs} +5 -5
  50. package/dist/{eas-build-CyjU5K7E.mjs → eas-build-CxKUNHsb.mjs} +4 -4
  51. package/dist/{eas-fallback-DV3Wytf1.mjs → eas-fallback-LMxk9Kw0.mjs} +14 -14
  52. package/dist/{eas-session-ledger-BzzsX97d.mjs → eas-session-ledger-Ck6YXPAO.mjs} +12 -8
  53. package/dist/{error-diagnostics-C6sVoeqO.mjs → error-diagnostics-BkKCZq4P.mjs} +17 -42
  54. package/dist/{exec-DEoAhcze.mjs → exec-VFRpu1iA.mjs} +116 -28
  55. package/dist/{gc-DLbzvTP2.mjs → gc-DDWEAj0w.mjs} +2 -2
  56. package/dist/{gc-CDoogxAI.mjs → gc-yVKpAOKM.mjs} +205 -28
  57. package/dist/{guide-BC37GcDG.mjs → guide-Bggftwc5.mjs} +252 -73
  58. package/dist/{hosted-android-CkclQig_.mjs → hosted-android-D4dweBof.mjs} +4 -4
  59. package/dist/{hosted-client-ByuMMO5s.mjs → hosted-client-BBTVe3X6.mjs} +4 -4
  60. package/dist/{hosted-ios-DtYHeuYR.mjs → hosted-ios-Sn0djzg8.mjs} +1 -1
  61. package/dist/{hosted-logs-Br84qWy1.mjs → hosted-logs-CYIZ5ubJ.mjs} +11 -6
  62. package/dist/{hosted-macos-DdtYajZt.mjs → hosted-macos-CXjsUNBR.mjs} +7 -7
  63. package/dist/{hosted-native-UPI9zdZ4.mjs → hosted-native-Doxbfzem.mjs} +58 -11
  64. package/dist/{idle-shutdown-DO7oIRlc.mjs → idle-shutdown-BInjLKqm.mjs} +10 -10
  65. package/dist/{ios-DZZbNYlY.mjs → ios-B1FXRCMX.mjs} +71 -44
  66. package/dist/{ios-vbUOqGXu.mjs → ios-BItP6lkn.mjs} +8 -8
  67. package/dist/{ios-hcBpnEGk.mjs → ios-CVUFFZ6C.mjs} +70 -13
  68. package/dist/{ios-xtlRHaeB.mjs → ios-ENC4sRPA.mjs} +1 -1
  69. package/dist/{ios-device-BXZ0c7Kb.mjs → ios-device-B6HK951C.mjs} +1 -1
  70. package/dist/{ios-device-JC3uWM4K.mjs → ios-device-BI38NFFH.mjs} +3 -3
  71. package/dist/{ios-project-CVyNwjAF.mjs → ios-project-KYqeJURj.mjs} +5 -5
  72. package/dist/{ios-signing-BtAffm0A.mjs → ios-signing-4c_qXvQm.mjs} +2 -2
  73. package/dist/{ios-state-Dtw5K2aI.mjs → ios-state-DlElquYD.mjs} +15 -7
  74. package/dist/{js-swap-C3QxUFJR.mjs → js-swap-BvrQvXHY.mjs} +7 -6
  75. package/dist/{launch-CHY3p-yz.mjs → launch-BVlyQw3T.mjs} +51 -49
  76. package/dist/{launch-Bz7JtaC4.mjs → launch-SfzGH_s9.mjs} +48 -29
  77. package/dist/{logs-mxqsWpJs.mjs → logs-DXE32kyb.mjs} +16 -9
  78. package/dist/{logs-CtNeNDuq.mjs → logs-ovlU7m7N.mjs} +8 -6
  79. package/dist/{macos-inNFbBWc.mjs → macos-B3BveDrU.mjs} +1 -1
  80. package/dist/{macos-u0BoHKnO.mjs → macos-CCfhb-jT.mjs} +49 -42
  81. package/dist/macos-run.mjs +1 -1
  82. package/dist/maintenance-run.mjs +7 -7
  83. package/dist/{metro-DiXtA3Ty.mjs → metro-Bu8LBfzS.mjs} +4 -4
  84. package/dist/{metro-gateway-CKZqKqx7.mjs → metro-gateway-DtsOy-0P.mjs} +3 -4
  85. package/dist/{named-ports-DkEzOfzO.mjs → named-ports-BWDuU5oQ.mjs} +3 -3
  86. package/dist/{native-android-CdCSylTn.mjs → native-android-96BBizbq.mjs} +17 -17
  87. package/dist/{native-gradle-artifact-inputs-DHFnmrVf.mjs → native-gradle-artifact-inputs-BcLYBZil.mjs} +5 -5
  88. package/dist/{native-run-BUTu8T7A.mjs → native-run-BmH7U8pr.mjs} +6 -6
  89. package/dist/{native-runtime-CRSOZxKY.mjs → native-runtime-DgtJkzIa.mjs} +10 -9
  90. package/dist/{native-source-Y0yLhFyQ.mjs → native-source-D-4Dh4JU.mjs} +7 -4
  91. package/dist/{native-xcode-inputs-G6rkkhxu.mjs → native-xcode-inputs-irplbQb0.mjs} +2 -2
  92. package/dist/{native-xcode-ios-_os2PlCD.mjs → native-xcode-ios-BY-6hh6M.mjs} +18 -18
  93. package/dist/offload-worker.d.mts +7 -2
  94. package/dist/offload-worker.mjs +104 -43
  95. package/dist/{operation-exec-BW0em61G.mjs → operation-exec-CUZifp6Z.mjs} +2 -25
  96. package/dist/{ownership-C5fo5Edb.mjs → ownership-DxlZGDcV.mjs} +3 -3
  97. package/dist/{page-DBL2PiUU.mjs → page-CzEA_-5_.mjs} +2 -3
  98. package/dist/phone-reverses-BdsdesVF.mjs +57 -0
  99. package/dist/{placement-log-BnGgJRRZ.mjs → placement-log-DUvqqsB-.mjs} +1 -1
  100. package/dist/{plan-placement-BU42oOyT.mjs → plan-placement-4axc0Hs7.mjs} +3 -3
  101. package/dist/{ports-BSmQKzW7.mjs → ports-D-E_OiAO.mjs} +3 -3
  102. package/dist/{prebuild-BFm63bQ0.mjs → prebuild-DmVCf5xb.mjs} +14 -9
  103. package/dist/{project-CTLNHCfE.mjs → project-Dz-hWkb-.mjs} +21 -17
  104. package/dist/{pull-request-W1IuLXDt.mjs → pull-request-CbNlkFok.mjs} +2 -2
  105. package/dist/pull-requests.mjs +1 -1
  106. package/dist/{react-native-android-CFgUroxW.mjs → react-native-android-DOinxgwB.mjs} +75 -32
  107. package/dist/{react-native-build-CmJkTljQ.mjs → react-native-build-AuCu-aAP.mjs} +22 -19
  108. package/dist/{react-native-doctor-LTF-Xt8l.mjs → react-native-doctor-2ivJUmwZ.mjs} +10 -9
  109. package/dist/{react-native-ios-ChBF1MkB.mjs → react-native-ios-D5zTIuH8.mjs} +38 -22
  110. package/dist/{recordings-CQmfzAh7.mjs → recordings-CdPwYwvs.mjs} +1 -1
  111. package/dist/{registration-BcRgF6Ox.mjs → registration-CN6nlhcD.mjs} +1 -1
  112. package/dist/{reload-DF9hqUUB.mjs → reload-C1TTVesC.mjs} +144 -42
  113. package/dist/{reload-RBi1nj6Z.mjs → reload-Ck9RJeSq.mjs} +1 -1
  114. package/dist/{remote-BmvMCcJw.mjs → remote-DEZ7AOVq.mjs} +7 -7
  115. package/dist/{result-Cx5CRLvS.mjs → result-DqBrb12U.mjs} +40 -17
  116. package/dist/{run-DidHghD1.mjs → run-BIwoU44q.mjs} +2 -2
  117. package/dist/{selection-DSMbWEX2.mjs → selection-BLtvaqxc.mjs} +11 -5
  118. package/dist/{server-bare-CafzuyFB.mjs → server-bare-Z1ToVLPn.mjs} +2 -2
  119. package/dist/{server-command-BTiGPEjS.mjs → server-command-C0pmjNdG.mjs} +6 -6
  120. package/dist/server-expo-CEntXzRw.mjs +2 -0
  121. package/dist/{server-expo-D9lEz4aq.mjs → server-expo-Tt_hLRpy.mjs} +37 -13
  122. package/dist/{settings-C7O8A6ZI.mjs → settings-RKwY33wv.mjs} +114 -19
  123. package/dist/{settings-eKF_vJJs.mjs → settings-kkt0vP4w.mjs} +1 -1
  124. package/dist/{settings-write-79mQRr9C.mjs → settings-write--gj6MACV.mjs} +7 -7
  125. package/dist/settings.schema.json +13 -0
  126. package/dist/{simslim-BNckWpXi.mjs → simslim-CdWKT3vA.mjs} +2 -2
  127. package/dist/{slot-launch-D7M2nE4b.mjs → slot-launch-A1BgotaM.mjs} +6 -6
  128. package/dist/{stage-DKNM4ZPd.mjs → stage-ERTMh88n.mjs} +2 -3
  129. package/dist/{start-bjfiScgz.mjs → start-BKGrEhzG.mjs} +75 -35
  130. package/dist/{start-CRfN1kWV.mjs → start-Bmg_qmHi.mjs} +1 -1
  131. package/dist/{state--smjFSTL.mjs → state-B1ig0Kqy.mjs} +4 -4
  132. package/dist/{state-08I3hw3_.mjs → state-BfAltYJP.mjs} +2 -2
  133. package/dist/{stats-DioA6cBU.mjs → stats-B-ckuiUg.mjs} +5 -5
  134. package/dist/{stats-report-BzaPrRm6.mjs → stats-report-n2U5plhk.mjs} +1 -1
  135. package/dist/{status-kzbeWk4x.mjs → status-DfFp6a76.mjs} +24 -24
  136. package/dist/{status-BRROykC8.mjs → status-Fect2w9R.mjs} +1 -1
  137. package/dist/{status-Eqx_20WC.mjs → status-Pw-807f0.mjs} +1 -1
  138. package/dist/{status-watch-BIqqbJ6q.mjs → status-watch-XC7F-AMf.mjs} +5 -5
  139. package/dist/status-worker.mjs +1 -1
  140. package/dist/stim-clonefile.c +18 -0
  141. package/dist/{stim-desktop-D5OGpYZM.mjs → stim-desktop-DS0mzR8U.mjs} +2 -2
  142. package/dist/{stop-B18d8KDw.mjs → stop-BFu7X_Do.mjs} +2 -2
  143. package/dist/{stop-B2uLQfoM.mjs → stop-CL1kDHds.mjs} +55 -21
  144. package/dist/{stop-DzLJc7Ei.mjs → stop-DhclRwOO.mjs} +5 -5
  145. package/dist/supervisor-run.mjs +16 -16
  146. package/dist/{support-BTpZ6RAJ.mjs → support-B1W-hmC2.mjs} +8 -8
  147. package/dist/{support-DTBV56gy.mjs → support-B3tzVhKn.mjs} +6 -6
  148. package/dist/{swiftpm-artifact-inputs-DFcGsXDP.mjs → swiftpm-artifact-inputs-BWYPj9Sn.mjs} +4 -4
  149. package/dist/{swiftpm-macos-r_WSKlXr.mjs → swiftpm-macos-BVCP5mO4.mjs} +14 -13
  150. package/dist/{toolchain-GVgnf8d1.mjs → toolchain-BjgKdoEf.mjs} +1 -1
  151. package/dist/{toolchain-CWeGJgCc.mjs → toolchain-D3bmRMia.mjs} +57 -36
  152. package/dist/trigger-BLsHgAGR.mjs +2 -0
  153. package/dist/{trigger-Cbyc41d_.mjs → trigger-CBMe2YLH.mjs} +2 -2
  154. package/dist/{warm-progress-CA3TgT3-.mjs → warm-progress-ol0ZypEu.mjs} +6 -6
  155. package/dist/{web-CwREhjD-.mjs → web-BH7peScT.mjs} +12 -10
  156. package/dist/web-BdOFlTJr.mjs +2 -0
  157. package/dist/web-run.mjs +8 -9
  158. package/dist/windows-report.mjs +12 -1
  159. package/dist/windows-report.ps1 +1 -1
  160. package/dist/{workspace-state-U08dEzhG.mjs → workspace-state-CeBpIZgr.mjs} +11 -4
  161. package/dist/{workspaces-BxzYlo3P.mjs → workspaces-CSV2Orf4.mjs} +36 -32
  162. package/dist/{worktree-BxfVxG_b.mjs → worktree-DEDUzO_L.mjs} +1 -1
  163. package/dist/{worktree-8lqn_lBp.mjs → worktree-Dw8kfacb.mjs} +324 -99
  164. package/dist/{xcode-iQnROM5o.mjs → xcode-DHu41qQ4.mjs} +41 -27
  165. package/package.json +7 -7
  166. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +0 -211
  167. package/dist/server-expo-C-Buqvn_.mjs +0 -2
  168. package/dist/trigger-yb_nFzPF.mjs +0 -2
  169. package/dist/web-Cduk0NSE.mjs +0 -2
@@ -1,8 +1,8 @@
1
- import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-C7O8A6ZI.mjs";
2
- import { i as findProjectRoot$1 } from "./project-CTLNHCfE.mjs";
3
- import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-BzzsX97d.mjs";
4
- import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-sy_RNhFt.mjs";
5
- import "./status-watch-BIqqbJ6q.mjs";
1
+ import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-RKwY33wv.mjs";
2
+ import { i as findProjectRoot$1 } from "./project-Dz-hWkb-.mjs";
3
+ import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-Ck6YXPAO.mjs";
4
+ import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-B453A231.mjs";
5
+ import "./status-watch-XC7F-AMf.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
@@ -191,13 +191,15 @@ RULES DURING THE LOOP
191
191
  - For stale Metro transforms or file-map state, use stim start --reset-cache.
192
192
  It restarts only this app's verified owned Metro, preserving devices and other
193
193
  apps' caches. See guide lifecycle for reset scope.
194
- - Reload is not part of the normal workflow. Use stim reload on an owned local
195
- simulator or emulator when an error screen remains after the fix, and on
194
+ - Reload is not part of the normal workflow. Use stim reload when an error
195
+ screen remains after the fix on an owned local simulator or emulator, a
196
+ physical device (an EAS Simulator session when its app connects to Metro), and on
196
197
  Android after a failed first bundle load. It reloads JavaScript and never
197
198
  restarts the app. An iOS app whose first bundle failed never connects to
198
199
  Metro, so reload cannot reach it and says to use the device's own Reload
199
- control. For a physical device that reached Metro, use agent-device metro
200
- reload with the reported port. The detected iOS Local Network first-load
200
+ control. With no owned launch recorded, reload goes through this workspace's
201
+ Metro to the apps connected to it, so an app that never connected is not
202
+ reached. The detected iOS Local Network first-load
201
203
  remedy uses UI automation instead because that app never established a Metro
202
204
  connection.
203
205
  - A successful stim reload confirms that the request was sent, not that new
@@ -482,12 +484,14 @@ refuses with STIM_CLAIM_UNAVAILABLE instead of cancellation or timeout. The
482
484
  child cleanup error names the launcher PID; unverifiable processes and descendants are left
483
485
  untouched. On POSIX, a launcher that exited before identity capture can only finish
484
486
  successfully once its process group is proven gone.
485
- After a termination request, cleanup waits at most one second for a child to
486
- close. Overall cleanup has a 35 second budget, including temporary-worktree
487
+ After a termination request, cleanup waits for a child to close, then for its
488
+ process group to exit: each wait is 5 seconds times the host's load per CPU,
489
+ from 5 to 15 seconds. Overall cleanup has a 35 second budget, including temporary-worktree
487
490
  removal; unfinished cleanup returns STIM_CLAIM_UNAVAILABLE and leaves unresolved
488
491
  resources in place. Credential refresh waits asynchronously and checks
489
492
  cancellation before writing.
490
493
  On Windows, report probes require the built-in Windows PowerShell for process-tree containment.
494
+ A probe's time limit counts only the probe itself; PowerShell's startup and exit each have their own 30 second limit.
491
495
 
492
496
  requestMachineAccess({ ticket?, signal? }) requests build and device-host access
493
497
  from configured remote machines without granting capabilities or repairing project
@@ -642,9 +646,10 @@ STIM_CLAIM_UNAVAILABLE, taking precedence over cancellation or callback failure;
642
646
  follow its remedy before retrying. Startup never retries automatically.
643
647
 
644
648
  reload({ platform?, signal?, beforeReload? }) requests a JavaScript reload in
645
- the live iOS/Android app or reloads the owned Chrome page. It returns the flat
646
- stim reload --json facts: platform, deviceId, deviceName, appId, metroPort,
647
- strategy, targets and reverseRestored. Choose ios, android or web when more
649
+ the live iOS/Android app (owned, on a physical device or in an EAS Simulator
650
+ session) or reloads the owned Chrome page. It returns the flat
651
+ stim reload --json facts: platform, deviceId, deviceName, appId (null for an
652
+ app Stim did not launch), metroPort, strategy, targets and reverseRestored. Choose ios, android or web when more
648
653
  than one platform is live. A request does not prove completion; verify the UI
649
654
  and inspect logs. A Metro broadcast can reach other connected clients.
650
655
  beforeReload(workspace) runs once after resolving the workspace and before
@@ -802,8 +807,10 @@ warns when gh is unavailable.
802
807
 
803
808
  status's remoteDevices lists each environment's recorded EAS Simulator
804
809
  session. The session is billable while it runs, and it makes the environment
805
- live. status reads only local records; it does not ask EAS whether the session
806
- is still running.
810
+ live. EAS stops it by itself after remote.easMaxDurationMinutes (default 30).
811
+ status reads only local records; it does not ask EAS whether the session is
812
+ still running, so a session EAS already stopped stays listed until the next
813
+ run replaces it or stop clears it.
807
814
 
808
815
  remoteDevices [{ platform, backend, sessionId, state, startedAt,
809
816
  webPreviewUrl }], empty when the workspace has none
@@ -1131,10 +1138,15 @@ leased until <time>" for each one.`,
1131
1138
 
1132
1139
  platform "ios" | "android" | "web"
1133
1140
  deviceId the exact owned simulator UDID or emulator serial targeted;
1134
- for web, the owned Chrome's DevTools endpoint
1135
- deviceName the owned simulator or AVD name; for web, the Chrome version
1141
+ for web, the owned Chrome's DevTools endpoint; metro:<port>
1142
+ when the apps were reached through Metro alone
1143
+ deviceName the owned simulator or AVD name; for web, the Chrome version;
1144
+ "EAS Simulator session <id>" or "devices connected to
1145
+ Metro" when reached through Metro alone
1136
1146
  appId the live bundle id or Android package; for web, the URL the
1137
- owned page was on when Stim sent the reload
1147
+ owned page was on when Stim sent the reload; null when no
1148
+ launch is recorded (a physical device or EAS Simulator
1149
+ session) and Stim reloaded the apps connected to Metro
1138
1150
  metroPort the workspace's verified Metro port; for web, the reserved
1139
1151
  Metro port or null
1140
1152
  strategy how the reload was addressed.
@@ -1226,10 +1238,11 @@ leased until <time>" for each one.`,
1226
1238
  brew and adb: source "environment" when this process's
1227
1239
  environment provides it, "discovered" when stim-server's
1228
1240
  toolchain discovery would find it (from says where), or
1229
- "missing". projectNode is { pin, spec, bin, version } when
1241
+ "missing". projectNode is { pin, spec, bin, version, match } when
1230
1242
  .nvmrc, .node-version, .tool-versions or package.json volta
1231
- pins Node (bin and version are null when no install
1232
- satisfies the pin), else null
1243
+ pins Node (bin, version and match are null when no install
1244
+ fits the pin; match is "exact", or "major" for the newest
1245
+ install of the pinned major not older than the pin), else null
1233
1246
  remoteMachines one { machine, state, dnsName?, deviceId?, requestedAt?,
1234
1247
  expiresAt?, offloadable?, reasons?, problems?, capacity?, host? } per
1235
1248
  remote.machines entry, for its build approval; state is "approved", "pending", "not-asked",
@@ -1481,7 +1494,8 @@ RULES
1481
1494
  buildLock, buildSlot, deviceLease, easSession, worktree,
1482
1495
  cache, gradleVersion, tempLeftover (one "done" labelled
1483
1496
  with the TMPDIR it cleared, plus a "kept" or "failed" per
1484
- entry gc checked again or could not delete).
1497
+ entry gc checked again or could not delete), trash (the
1498
+ same, labelled with $STIM_HOME/trash).
1485
1499
  label is a device, path or cache name; id is the UDID,
1486
1500
  AVD name or path behind it, or null. Under --cache
1487
1501
  parked, a "done" parkedDevice was erased and stays
@@ -1706,10 +1720,23 @@ RULES
1706
1720
  kind is stim (stim-claim-*, stim-host-*,
1707
1721
  stim-fakehome-*, stim-hosted-macos-*,
1708
1722
  stim-server-*, stim-ws-* directories), xctrace
1709
- (instruments*.ktrace) or jest (Jest's
1723
+ (instruments*.ktrace), swiftpm
1724
+ (TemporaryDirectory.* directories) or jest (Jest's
1710
1725
  jest_<uid in base 36> cache, never deleted). deleteCount
1711
1726
  is what --delete removes. null with STIM_HOME
1712
1727
  set or any --cache scope
1728
+ trash { root, entries: [{ path, worktree, removedAt,
1729
+ bytes, willDelete, kept }] } | null ignored
1730
+ directories worktree remove moved out of a
1731
+ worktree into $STIM_HOME/trash before git
1732
+ removed it. bytes is null while a removal is
1733
+ deleting the entry. kept names the live or
1734
+ unresolved ownership claim, the missing or
1735
+ invalid trash.json, or the worktree that
1736
+ still exists, that keeps a directory;
1737
+ --delete deletes the rest, only remove-*
1738
+ entries with a valid trash.json. null when the
1739
+ trash is empty or under any --cache scope
1713
1740
  caches { name, dir, source, bytes, note, willEmpty,
1714
1741
  emptySkipped, scopedEmpty } alive, not
1715
1742
  garbage; willEmpty marks the ones --delete
@@ -2291,7 +2318,9 @@ RULES
2291
2318
  existed count their device time in prepare and install
2292
2319
 
2293
2320
  Only runs that record a last build are listed: a run that stops before
2294
- looking up a build, such as a bad flag, is not. Estimates (expectedMs) come from run statistics, not builds.
2321
+ looking up a build, such as a bad flag, is not. A run that builds or reuses
2322
+ an app and then fails at the device, install or launch step is listed as
2323
+ failed with its error code. Estimates (expectedMs) come from run statistics, not builds.
2295
2324
 
2296
2325
  done and total are counts, not a completion fraction: a target or task
2297
2326
  can take a second or ten minutes, and cached work finishes instantly.
@@ -2682,7 +2711,11 @@ HOSTED IOS METRO
2682
2711
  ios --remote <machine> keeps Metro local and needs no start --remote.
2683
2712
  The supervisor watches private gateway requests in workspace state, binds
2684
2713
  only this machine's Tailscale address and accepts only the pinned hosting peer
2685
- with a per-session secret. The host's bridge is loopback-only. Port and secret
2714
+ with a per-session secret. The host's bridge is loopback-only. For an Expo
2715
+ dev client it listens on this machine's Metro port, which the dev server
2716
+ writes into the manifest. ios --remote starts Metro on a port free on both
2717
+ Macs; a running Metro or a pin on a port the host uses refuses the run before
2718
+ the build. Port and secret
2686
2719
  stay in 0600 workspace state and never appear in status, JSON or logs.
2687
2720
  metro.tunnel and metro.publicUrl are ignored. Supervisor restart recreates
2688
2721
  the recorded gateway; stop or a stopped hosted session closes it. A recorded
@@ -2770,7 +2803,9 @@ REMOTE DEVICE BACKENDS
2770
2803
  are Apple silicon. The cache key ends in that architecture.
2771
2804
 
2772
2805
  The EAS backend needs eas-cli 21.6.0 or later and an account with EAS
2773
- Simulator access. An EAS session is billable. Stim prepares the app before
2806
+ Simulator access. An EAS session is billable; Stim has EAS stop each session
2807
+ it creates after remote.easMaxDurationMinutes (default 30), and a later run
2808
+ replaces a session that expired. Stim prepares the app before
2774
2809
  it creates or reconnects the session, so a failed build starts no session
2775
2810
  and the install follows the connection directly. EAS does not inherit the
2776
2811
  proxy credentials. Always tear the session down: \`stop\`,
@@ -2823,9 +2858,13 @@ WHAT THE SUPERVISOR IS
2823
2858
 
2824
2859
  expo-child and command-child put the Node the app pins (.nvmrc,
2825
2860
  .node-version, .tool-versions nodejs, or package.json volta.node) first
2826
- on PATH when an nvm, fnm, Volta, asdf or mise install satisfies the pin
2827
- and the node already on PATH does not; the metro log then records a
2828
- project_node event naming it. bare-inproc runs on the supervisor's Node.
2861
+ on PATH when an nvm, fnm, Volta, asdf, mise or linked Homebrew
2862
+ node/node@NN install satisfies the pin and the node already on PATH does
2863
+ not; the metro log then records a project_node event naming it. When no
2864
+ install has the version the pin names, the newest install of the pinned
2865
+ major that is not older than the pin stands in, and a node on PATH of
2866
+ that major and not older than the pin is kept. bare-inproc runs on the
2867
+ supervisor's Node.
2829
2868
 
2830
2869
  In expo-child mode, remote intent plus metro.tunnel "expo" makes \`start\` pass
2831
2870
  \`--tunnel\` and EXPO_UNSTABLE_TUNNEL_V2=1 (the legacy ws-tunnel path is
@@ -3215,6 +3254,10 @@ serve bounded log queries.
3215
3254
  the safe direction: a client redbox that Fast Refresh already fixed keeps
3216
3255
  being reported until the next launch.
3217
3256
 
3257
+ RUN FAILURES. A run that builds or reuses an app and then fails before the app
3258
+ is running adds one build record with event run_failed, its code and the
3259
+ phase it failed in, so \`status\` and \`logs --errors\` agree.
3260
+
3218
3261
  OUTPUT. Every logs command, including --errors and --follow, shows full captured
3219
3262
  error, component and native stacks, with no frame or message-length limit.
3220
3263
  --errors shows the first 20 matching error records, plus stack context.
@@ -3552,6 +3595,10 @@ Branch on the code, never on the message.`,
3552
3595
  --system-image / --device-profile for Android when the offer names
3553
3596
  an unavailable choice. A session that exists stays recorded even if delivery
3554
3597
  fails: retry stim ios|android --remote <machine>, or run stim stop to reconcile it.
3598
+ An Expo dev client whose running or pinned Metro port is in use on the host
3599
+ refuses before the build: run stim stop, then stim ios --remote <machine>
3600
+ without stim start, so Stim starts Metro on a port free on both Macs, or pin
3601
+ one free on both Macs with metro.port or STIM_METRO_PORT.
3555
3602
  An unreachable stop keeps the placement; rerun stim stop when the host answers.
3556
3603
  To see why a host was slow or refused: stim logs --source placement (hosts checked and
3557
3604
  reason codes), stim logs --source build (remote_connect_failed, remote_request_failed),
@@ -3643,8 +3690,9 @@ Branch on the code, never on the message.`,
3643
3690
  \`pod install\` (iOS) or the gradle dependency sync (Android) failed. On iOS
3644
3691
  this runs only when Podfile.lock and Pods/Manifest.lock disagree, or Pods is
3645
3692
  absent -- which is exactly what a carried worktree produces.
3646
- WHICH POD COMMAND: when the project root has a Gemfile and a Gemfile.lock
3647
- that resolves cocoapods, pods go through bundler -- \`bundle check --dry-run\`,
3693
+ WHICH POD COMMAND: Stim takes the nearest Gemfile from the directory pod
3694
+ install runs in (ios/) up to the project root, as Bundler finds it. When its
3695
+ Gemfile.lock resolves cocoapods, pods go through bundler -- \`bundle check --dry-run\`,
3648
3696
  then \`bundle install\` only when that reports missing gems, then \`bundle exec
3649
3697
  pod install\` -- so the CocoaPods the lockfile pins is the one that writes
3650
3698
  Podfile.lock. Everything else gets plain \`pod install\`: no Gemfile, a Gemfile
@@ -3743,8 +3791,13 @@ Branch on the code, never on the message.`,
3743
3791
  leaves room for. A project with react-native-gesture-handler 3, whose
3744
3792
  shared shadow nodes have the longest known object path, fits a root of at
3745
3793
  most 24 characters for an x86_64 Debug build and 21 for arm64-v8a; other
3746
- projects fit 51 and 48. Refused BEFORE Gradle
3747
- runs -- a cache hit still installs -- because the build would otherwise
3794
+ projects fit 51 and 48. \`stim android\` on
3795
+ an emulator, local or --remote <backend>, refuses before it starts Metro
3796
+ or prepares the emulator, even when a cached build would have installed.
3797
+ That early refusal is skipped for a physical or hosted device, an EAS
3798
+ profile and when build machines are paired; a build that still runs here
3799
+ is refused before Gradle runs, so a cache hit there still installs.
3800
+ The build would otherwise
3748
3801
  fail deep inside ninja ("mkdir ... No such file or directory" or
3749
3802
  "Filename longer than 260 characters"). Move or clone the project under a
3750
3803
  short real path such as C:\\src\\<name> and run Stim there. A subst drive
@@ -3911,6 +3964,13 @@ Unlisted or unpaired names refuse at setup before consulting the cache, without
3911
3964
  a build record or failed-run stats. A listed paired name with a cache hit needs
3912
3965
  no build and does not contact the selected machine.
3913
3966
 
3967
+ A fingerprint-mismatch reason means the worker fingerprints the synced
3968
+ checkout differently. It names the sources that differ and the files pod
3969
+ install or prebuild rewrote there. Stim already sends the gitignored files the
3970
+ fingerprint reads, such as .env.local. Make the named input agree on both Macs,
3971
+ for example by committing the lockfile pod install rewrote there; pairing does
3972
+ not change it.
3973
+
3914
3974
  Run stim doctor --fix to ask for build access if not paired. Check
3915
3975
  stim settings get remote.machines. A person on the worker approves this machine
3916
3976
  by running the stim-server setup command doctor --fix printed, with its ticket
@@ -3954,6 +4014,11 @@ Rerun with --remote-build auto for normal placement and local fallback, or
3954
4014
  copying for the same reason. A copy without a claim would be invisible to a
3955
4015
  refresh starting after it, allowing the source dependencies to change while
3956
4016
  they are read.
4017
+ A report command such as \`gc\` reports it when it cannot confirm that a child
4018
+ it started has stopped, typically on a machine under heavy load. The child is
4019
+ left untouched. The remedy tells you what to check and which command to run
4020
+ again, and when the run held ownership claims it lists the exact \`rm\`
4021
+ command for each retained claim.
3957
4022
  Warm also reports this code for EACCES, EPERM, EROFS and ENOENT while taking a claim.
3958
4023
  The message names the claim path and original filesystem error. Restore write
3959
4024
  access to the existing claim store, checking parent permissions, symlink
@@ -4279,7 +4344,8 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
4279
4344
  and \`adb devices\`, then retry after any other run finishes. Keep the AVD and
4280
4345
  its process locks while its state is unverified.
4281
4346
  On iOS a slow first boot is waited out for up to ten minutes while the
4282
- simulator reports Booting or Booted but bootstatus has not completed.
4347
+ simulator reports Booting or Booted but bootstatus has not completed, and
4348
+ then until SpringBoard has finished starting, which \`simctl launch\` needs.
4283
4349
  Booted alone does not end that wait. The failure names the udid and the wait.
4284
4350
  After boot, a process-spawn probe must finish within 30 seconds before
4285
4351
  installation. If it fails, the refusal includes observed host memory pressure
@@ -4452,14 +4518,19 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
4452
4518
  proxy is selected. They never select the backend.`
4453
4519
  },
4454
4520
  STIM_REMOTE_EAS_UNAVAILABLE: {
4455
- summary: "--remote eas needs eas-cli 21.6.0 or later",
4521
+ summary: "--remote eas needs eas-cli 21.6.0 or later and an Expo app linked to an EAS project",
4456
4522
  body: () => `STIM_REMOTE_EAS_UNAVAILABLE
4457
4523
  \`--remote eas\` requires eas-cli 21.6.0 or later, the first release with
4458
4524
  the \`eas simulator:*\` commands Stim runs. Stim reads \`eas --version\` and
4459
4525
  refuses before any build or session work when eas-cli is missing, older, or
4460
4526
  reports no version. Upgrade it (\`npm install --global eas-cli@latest\`, or
4461
4527
  the project's eas-cli dependency). Proxy environment variables do not change
4462
- this selection and are not passed to EAS.`
4528
+ this selection and are not passed to EAS.
4529
+ It is also the code when EAS reports that the Expo app has no EAS project
4530
+ (no extra.eas.projectId), so no session was created. Link the app with
4531
+ \`eas init --id <project-id> --non-interactive\` or create a project with
4532
+ \`eas init --account <account-name> --non-interactive\`, then rerun. Rerunning
4533
+ \`stim ios\` or \`stim android\` without the link fails the same way.`
4463
4534
  },
4464
4535
  STIM_REMOTE_PLATFORM_MISMATCH: {
4465
4536
  summary: "the recorded remote session belongs to the other platform; stop, then rerun",
@@ -4543,12 +4614,17 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
4543
4614
  aliases: ["STIM_RELOAD_UNOWNED", "STIM_RELOAD_PROBE_FAILED"],
4544
4615
  body: () => `STIM_RELOAD_STOPPED / STIM_RELOAD_UNOWNED / STIM_RELOAD_PROBE_FAILED
4545
4616
  The recorded app is gone, its exact device is not live and owned by this
4546
- workspace, or simctl/adb could not prove the process exists. For web,
4617
+ workspace, or Metro has no peer for the app and simctl/adb could not prove the
4618
+ process exists (a probe that times out alone does not stop the reload). For web,
4547
4619
  STOPPED means no owned Chrome is running (run stim web) and PROBE_FAILED
4548
4620
  that its identity could not be verified. A bare reload picks the Chrome page
4549
- only when no native launch is recorded. No launch or
4550
- device lifecycle action is taken; follow the printed platform-command or
4551
- process-probe remedy.`
4621
+ only when no native launch is recorded. Stim records launches only on owned
4622
+ local simulators and emulators. With none recorded, reload asks this
4623
+ workspace's Metro for its connected apps, which reaches an app on a physical
4624
+ device (--device) or an EAS Simulator session; STOPPED then means no app is
4625
+ connected to that Metro, so launch it or, for an Android phone, restore its
4626
+ adb reverse. No launch or device lifecycle action is taken; follow the
4627
+ printed platform-command or process-probe remedy.`
4552
4628
  },
4553
4629
  STIM_RELOAD_FAILED: {
4554
4630
  summary: "the reload failed; the remedy differs by shape -- read it before acting",
@@ -4699,6 +4775,13 @@ captured" (in metro.ndjson, bare RN)
4699
4775
  config -- lands THERE, not in supervisor.log). \`stim logs --errors\` has
4700
4776
  the full records. Fix that and run \`start\` again.
4701
4777
 
4778
+ A bind error on the reserved port ("listen EADDRINUSE ... :<port>") means
4779
+ another process, usually another Stim home, took the port after Stim chose
4780
+ it. \`start\` releases that reservation, reserves another free port and
4781
+ starts again, up to 3 attempts, and says so. A pinned metro.port and
4782
+ \`--remote\` starts are not retried. When all attempts fail, run \`start\`
4783
+ again.
4784
+
4702
4785
  "Cannot reuse or replace the recorded supervisor: ..."
4703
4786
  A live record has no verifiable OS process identity, or the workspace and
4704
4787
  registry records disagree. Nothing new was started; the old process is
@@ -5327,14 +5410,15 @@ hosting Mac keeps Metro local through a private bridge; see hosted-ios. Step 2 r
5327
5410
  Metro while other work happens.
5328
5411
 
5329
5412
  Each time Stim boots an owned local simulator or emulator, it mutes it: iOS
5330
- simulators to volume zero through Xcode's devicectl, and Android 15 and later
5331
- emulators to media volume zero. A device that is already running keeps its
5332
- volume. Turn sound on for one device with Sound (iOS) or Media sound
5333
- (Android) in its Stim Desktop options; the choice lasts until that device next
5334
- boots. Android 14 and older images have no shell command that can set media
5335
- volume, so startup warns, as it does whenever a mute is not confirmed. Host
5336
- volume, Android alarm and ringtone volumes, hosted devices and physical
5337
- devices are unchanged.
5413
+ simulators to volume zero through Xcode's devicectl once SpringBoard has
5414
+ finished starting, because SpringBoard resets the volume while it starts, and
5415
+ Android 15 and later emulators to media volume zero. A device that is already
5416
+ running keeps its volume. Turn sound on for one device with Sound (iOS) or
5417
+ Media sound (Android) in its Stim Desktop options; the choice lasts until that
5418
+ device next boots. Android 14 and older images have no shell command that can
5419
+ set media volume, so startup warns, as it does whenever a mute is not
5420
+ confirmed. Host volume, Android alarm and ringtone volumes, hosted devices and
5421
+ physical devices are unchanged.
5338
5422
 
5339
5423
  Repeat step 3 whenever a NATIVE input changes. A JS-only edit needs nothing --
5340
5424
  that is what Fast Refresh over the running dev server is for. \`stim reload\` is
@@ -5342,16 +5426,25 @@ not part of the normal workflow. It is the explicit recovery path when Fast
5342
5426
  Refresh cannot clear the current screen, and on Android after a failed first
5343
5427
  bundle load. It reloads JavaScript and never restarts the app. Use \`stim
5344
5428
  reload ios\` or \`stim reload android\` to select a platform when both owned
5345
- apps are live. For a physical device that reached Metro, use \`agent-device
5346
- metro reload --metro-port <reported-port>\`. The detected iOS Local Network
5429
+ apps are live. With no owned launch recorded, it reloads the apps connected to
5430
+ this workspace's Metro, such as one on a physical device (--device); an
5431
+ Android phone needs its adb reverse. An app in an EAS Simulator session may not
5432
+ connect to Metro through the tunnel; then reload finds no app and the way to
5433
+ restart it is stim ios|android --remote eas.
5434
+ The detected iOS Local Network
5347
5435
  first-load remedy uses agent-device UI automation because no Metro peer exists
5348
- yet. It never builds, installs, boots, or cold-launches. It acts only on a live
5349
- app on this workspace's owned local simulator or emulator, and refuses release
5350
- builds, stopped or unowned devices, a missing or foreign Metro, and an
5351
- ambiguous no-platform request. Every reload goes over this workspace's Metro
5436
+ yet. It never builds, installs, boots, or cold-launches. It acts on a live app
5437
+ on this workspace's owned local simulator or emulator, or on the apps connected
5438
+ to this workspace's Metro, and refuses release builds, stopped or unowned
5439
+ devices, a missing or foreign Metro, and an ambiguous no-platform request. Every reload goes over this workspace's Metro
5352
5440
  websocket, on both platforms. It never reopens a development-client URL,
5353
5441
  because that restarts the app rather than reloading its JavaScript.
5354
5442
 
5443
+ Before sending, Stim checks that the app process exists. The iOS probe
5444
+ (\`simctl spawn launchctl list\`) waits 5 seconds, scaled up with host load to at
5445
+ most 30. When the device tool still does not answer, Stim sends the reload anyway;
5446
+ \`STIM_RELOAD_PROBE_FAILED\` is then reported only if Metro finds no peer for the app after the reload fails.
5447
+
5355
5448
  An Android reload first lists \`adb reverse\` on each live owned emulator
5356
5449
  launched against this Metro and re-applies the Metro port's reverse where it is
5357
5450
  missing. adb ties a reverse to its transport, and a transport that drops and
@@ -5378,7 +5471,7 @@ dev menu.
5378
5471
  When Metro reports no peer for the app, Stim broadcasts a reload anyway before
5379
5472
  giving up, because matching is best-effort and an unmatched peer may still be
5380
5473
  this app. So verify the UI first: it may already have recovered. If it did not,
5381
- retry: a client reconnects every 2 seconds, which is also this probe's timeout,
5474
+ retry: a client reconnects every 2 seconds, which is also the Metro probe's timeout,
5382
5475
  so a single miss can be a reconnect window rather than an app that never
5383
5476
  connected. If it stays unreachable on iOS, an error in the first bundle leaves
5384
5477
  the app without a packager connection at all, and no retry will make it a peer.
@@ -5902,7 +5995,7 @@ is on PATH, the slot is default, no --runtime, --system-image or
5902
5995
  another platform or model, and a Debug run's Metro is reachable (not
5903
5996
  metro.tunnel off; on an Expo tunnel, run stim start --remote first). A recorded
5904
5997
  EAS session is not sticky: once this machine has room, auto runs here and the
5905
- session bills until stim stop. If any check fails, or the
5998
+ session bills until stim stop or remote.easMaxDurationMinutes. If any check fails, or the
5906
5999
  setting is off, auto runs here and may wait in the existing FIFO device
5907
6000
  slot queue; --no-wait and --wait 0 refuse with STIM_AT_CAPACITY. The placement
5908
6001
  line explains the decision, the skipped hosts and why EAS was not used
@@ -5952,6 +6045,12 @@ Stim builds or fetches before reserving, records the session immediately, then
5952
6045
  uploads the app on every run. React Native and Expo Debug keep Metro here; the supervisor owns a
5953
6046
  private gateway bound to this machine's Tailscale address, pinned to the host peer
5954
6047
  and protected by a per-session secret. The host exposes only a loopback bridge.
6048
+ For an Expo dev client the bridge listens on this machine's Metro port, because
6049
+ the dev server writes that port into the manifest's bundle URL. When this run
6050
+ starts Metro, it asks the host and picks a port free on both Macs, moving the
6051
+ recorded port if the host uses it. A running Metro or a metro.port pin on a port
6052
+ the host uses refuses before the build: run stim stop, then stim ios --remote
6053
+ <machine> without stim start, or pin a port free on both Macs.
5955
6054
  No start --remote is needed; metro.tunnel and metro.publicUrl are ignored.
5956
6055
  Debug requires a running supervisor with private gateway support before reserving
5957
6056
  a simulator. --no-metro-check refuses with STIM_BAD_ARG for hosted Debug runs.
@@ -7037,8 +7136,11 @@ WHAT MAKES THE CACHE ACTUALLY HIT: .FINGERPRINTIGNORE
7037
7136
  BUILD is what breaks that, and it fails silently -- a cache that never hits
7038
7137
  looks exactly like a cache that is not there.
7039
7138
 
7040
- Stim ignores two paths a fresh checkout never has and no native build reads:
7041
- android/local.properties and android/.idea. A project does not repeat those.
7139
+ Stim ignores paths a fresh checkout never has and no native Debug build
7140
+ reads: android/local.properties, android/.idea, *.xcodeproj/xcuserdata, and,
7141
+ while a .gitignore pattern matches them (even when committed), the
7142
+ \`react-native bundle\` output ios/main.jsbundle and ios/assets. A project
7143
+ does not repeat those.
7042
7144
  Everything else is the project's call, including a lockfile whose checksums
7043
7145
  embed machine paths -- ignoring a path any project might read turns a slow
7044
7146
  build into a wrong one.
@@ -7516,7 +7618,10 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
7516
7618
 
7517
7619
  Warm copies directly into the destination, without intermediate staging.
7518
7620
  Keep the source checkout and the linked worktree on the same volume to
7519
- retain copy-on-write cloning where supported. Cross-volume copies require
7621
+ retain copy-on-write cloning where supported. On macOS with the Command Line
7622
+ Tools, an ignored directory on the same APFS volume, such as node_modules or
7623
+ ios/Pods, is cloned in one step, so a large one takes seconds; elsewhere
7624
+ warm clones or copies file by file. Cross-volume copies require
7520
7625
  full file data; doctor reports that cost. STIM_TMPDIR and machine tempDir do
7521
7626
  not affect warming.
7522
7627
 
@@ -8057,6 +8162,8 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
8057
8162
  Watchman stim gc --delete --cache watchman
8058
8163
  Gradle or Kotlin daemon stim gc --delete --cache gradle-daemons
8059
8164
  Any other process is named with its size only; ask before quitting it.
8165
+ Boot does not wait for this read: the pressure message prints at once and the
8166
+ named processes follow on a second memory line when top finishes.
8060
8167
  Doctor skips this check when STIM_HOME is set: processes are machine-global.
8061
8168
 
8062
8169
  If pressure is elevated, free host memory before retrying. Use \`stim stop\`
@@ -8167,8 +8274,8 @@ DISK PRESSURE LEVELS
8167
8274
  android/build, android/.gradle and .build, at a project root, the
8168
8275
  worktree root, or apps/* and packages/*
8169
8276
  4. owned simulators and emulators of workspaces idle for the short window
8170
- 5. Stim temp directories and xctrace recordings in TMPDIR unmodified for
8171
- 24 hours, with gc --delete's checks (see stim guide cleanup gc)
8277
+ 5. Stim temp directories, xctrace recordings and SwiftPM temp directories
8278
+ in TMPDIR unmodified for 24 hours, with gc --delete's checks (see stim guide cleanup gc)
8172
8279
  Level 3:
8173
8280
  1. the Swift compilation cache, emptied whole under the same build rule;
8174
8281
  when a build keeps it, the last pass's blocked reasons name its size
@@ -8481,6 +8588,24 @@ LINKED WORKTREES
8481
8588
  has locked (unlock it first; --force does not override) and, without
8482
8589
  --force, uncommitted or unpushed work and initialized submodules. It then
8483
8590
  reclaims any owned resources it finds and removes the linked checkout.
8591
+ Before git removes it, the command renames the worktree's ignored
8592
+ directories (node_modules, ios/Pods, build outputs) into
8593
+ $STIM_HOME/trash/<entry>, so git removes a light tree, and a detached,
8594
+ low-priority rm deletes the entry after the command returns. Disk is freed
8595
+ when that rm finishes. Through the programmatic API (createStim), the entry
8596
+ is deleted before the call resolves. A directory that does not rename stays
8597
+ for git to delete as before; on Windows, or when $STIM_HOME is on another
8598
+ volume, nothing is renamed. When git refuses the removal, the directories
8599
+ are moved back. Each entry holds an ownership claim while the command or its
8600
+ rm uses it; gc reports every directory under trash with its size ("deleting"
8601
+ while a removal holds it) and, for an entry Stim wrote, its source worktree.
8602
+ gc --delete deletes only a remove-* entry with a valid trash.json whose
8603
+ claim is free and whose worktree path is gone, which finishes a removal that
8604
+ was interrupted, and keeps any other directory. An entry whose worktree path
8605
+ still exists, as after a removal killed between the rename and git, stays
8606
+ with the reason; if that worktree is the one the entry came from, run
8607
+ \`stim worktree remove\` on it to finish the removal.
8608
+ gc never moves the directories back.
8484
8609
  When git still refuses the removal, the kept ownership record no longer
8485
8610
  names the devices that were parked or deleted. A workspace that is in use
8486
8611
  (see IN USE below) keeps its directory, devices and registry entry, and the
@@ -8687,13 +8812,19 @@ TMPDIR LEFTOVERS
8687
8812
  under "TMPDIR leftovers", with their count, size and a remedy: Stim temp
8688
8813
  directories (stim-claim-*, stim-host-*, stim-fakehome-*,
8689
8814
  stim-hosted-macos-*, stim-server-*, stim-ws-*), xctrace recordings
8690
- (instruments*.ktrace) and Jest's jest_<uid in base 36> cache. \`gc --delete\` checks
8691
- them again and deletes a Stim temp directory or recording only when nothing
8692
- in it changed for 24 hours. It keeps a Stim temp directory that contains or
8815
+ (instruments*.ktrace), SwiftPM temp directories (TemporaryDirectory.* with a
8816
+ six-character suffix, left by swift and xcodebuild) and Jest's
8817
+ jest_<uid in base 36> cache. \`gc --delete\` checks them again and deletes a
8818
+ Stim temp directory, recording or SwiftPM temp directory only when nothing in
8819
+ it changed for 24 hours. It keeps a Stim temp directory that contains or
8693
8820
  sits inside a registered project, holds a live or unverifiable ownership
8694
8821
  claim or a .lock directory that is not a claim set, or cannot be listed. It
8695
- keeps a recording that cannot be read, and every recording while an xctrace
8696
- or Instruments process runs or the process list cannot be read. Jest's cache and every other entry
8822
+ keeps a recording or SwiftPM temp directory that cannot be read, every
8823
+ recording while an xctrace or Instruments process runs, and every SwiftPM
8824
+ temp directory while a swift or xcodebuild process runs, or when the process
8825
+ list cannot be read. Stim's own SwiftPM macOS builds run swift with the
8826
+ ambient TMPDIR, because SwiftPM keeps the locks for its shared caches there,
8827
+ so their temp directories land here too. Jest's cache and every other entry
8697
8828
  are never deleted. gc never follows a symlink and never acts outside TMPDIR.
8698
8829
  With STIM_HOME set it neither reports nor deletes them, because TMPDIR is
8699
8830
  shared by every Stim home. Automatic maintenance runs the same deletion at disk pressure
@@ -8794,6 +8925,9 @@ DEVICE LEASES
8794
8925
  its holder and expiry, including holders no config knows. \`stop\` and
8795
8926
  \`worktree remove\` release the leases of the workspace they act on, and
8796
8927
  nothing else deletes a lease file: never remove another workspace's.
8928
+ They also remove the \`adb reverse\` that an \`android --device\` run added
8929
+ for this workspace's Metro port on that phone, using the serial and port the
8930
+ run recorded in its workspace state; any other reverse on the phone stays.
8797
8931
 
8798
8932
  A device leaks when a project is abandoned WITHOUT either delete path -- the
8799
8933
  sim survives with nothing pointing at it. \`stim gc\` (no flag, writes
@@ -9503,6 +9637,17 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
9503
9637
  project scope; a committed value opts in everyone who
9504
9638
  runs the app. Only the user enables it. See lifecycle
9505
9639
  hosted-ios.
9640
+ remote.easMaxDurationMinutes
9641
+ Minutes after which EAS stops each EAS Simulator session
9642
+ Stim creates (--remote eas or the easFallback), so a
9643
+ session nobody ended stops billing. A positive integer;
9644
+ default 30. Machine scope only. stop and gc --delete
9645
+ still end a session sooner; a run after the cap expires
9646
+ replaces the stopped session. Stim passes it to eas sim
9647
+ as --max-duration-minutes. EAS rejects a value above the
9648
+ account plan's session limit, so raise it only as far
9649
+ as the plan allows. A run reuses a live session without
9650
+ checking its remaining time.
9506
9651
  metro.tunnel selects how a remote device reaches this workspace's
9507
9652
  Metro after remote intent exists. Plain \`start\` stays
9508
9653
  local. For Expo and bare React Native, "auto" (default)
@@ -10044,6 +10189,11 @@ and records buildMachine with builtOn absent. Build failures retain the selected
10044
10189
  value; builtOn is here or the configured machine entry when compilation ran.
10045
10190
  Prebuild and pod install still run on this machine before a named offload. A refusal
10046
10191
  starts no local xcodebuild, Gradle or SwiftPM compile.
10192
+ A React Native offload sends the tracked and untracked files, and the gitignored
10193
+ files the native fingerprint hashes or the Expo config reads, such as .env.local
10194
+ and other Expo .env files, secrets included. Nothing under node_modules and no
10195
+ build output the fingerprint ignores is sent. A fingerprint-mismatch refusal
10196
+ names the sources that differ and the files pod install or prebuild rewrote there.
10047
10197
  Run stim doctor --fix to ask for build access if not paired. A person on the
10048
10198
  worker approves it by running the stim-server setup command doctor printed, with
10049
10199
  its ticket and expiry. Check stim settings get remote.machines,
@@ -10069,11 +10219,31 @@ emulator debug build or a stim macos SwiftPM Debug build compiles:
10069
10219
  off here when local remains enabled in the automatic build pool
10070
10220
 
10071
10221
  For React Native and Expo, among machines that can take a new build, a matching dependency installation
10072
- ranks before load. The worker checks the requested project, lockfile and install
10073
- arguments, and verifies that its modules and install marker remain present.
10222
+ ranks before load. The worker checks the requested project, lockfile, install
10223
+ arguments and the major of the Node the app pins, and verifies that its modules
10224
+ and install marker remain present.
10074
10225
  Older workers' dependency hints and mere checkout or build-folder presence do
10075
10226
  not influence this ranking. Exact completed-artifact hits still come first.
10076
10227
 
10228
+ The worker installs dependencies with the lockfile nearest the app: the first
10229
+ pnpm-lock.yaml, yarn.lock or package-lock.json in its directory or above it in
10230
+ the checkout, in the directory that holds it. An app with its own lockfile
10231
+ inside a larger repository installs its own dependencies there. In a pnpm
10232
+ workspace the worker installs every workspace package, as \`pnpm install\` does
10233
+ locally, because a native build can run a script of a package the app does not
10234
+ depend on.
10235
+
10236
+ The worker runs the dependency install, prebuild, pods and xcodebuild with the
10237
+ Node the app pins, in its directory or the nearest one above it in the
10238
+ checkout, first on PATH, chosen as for Metro (see \`stim guide metro\`). On
10239
+ every offloaded iOS build, pinned or not, it writes the first node on its PATH
10240
+ (the pinned Node when it put one first) as NODE_BINARY in the iOS project's
10241
+ .xcode.env.local, replacing any export NODE_BINARY= line already there. A warm
10242
+ Gradle daemon keeps running React Native's node steps on the Node it started
10243
+ with. When no installed Node fits the pin, the steps run on the worker's node
10244
+ and a deps-failed or prebuild-failed reason names the pin and that Node's
10245
+ version. A change of the pinned Node's major reinstalls the dependencies.
10246
+
10077
10247
  Load per core is the 5-minute load average divided by the CPU count; a machine's
10078
10248
  native builds are its Stim runs in prebuild, pods or compile on that machine, not
10079
10249
  the ones it offloaded.
@@ -10086,7 +10256,8 @@ STIM_REMOTE_BUILD_MODE overrides it for one command. Device, Release and
10086
10256
  and iOS/Android runs with the build cache off, always build here. Hosted iOS
10087
10257
  Debug builds can use a separate --remote-build, targeting the hosting Mac's
10088
10258
  architecture and runtime.
10089
- macOS uses matching Xcode and macOS SDK, with a per-client SwiftPM dependency
10259
+ macOS uses matching Xcode and macOS SDK (not when --remote-build and --remote name the
10260
+ same Mac; see stim guide macos), with a per-client SwiftPM dependency
10090
10261
  cache on the worker. It skips JavaScript dependencies, prebuild and pods; see
10091
10262
  stim guide macos. Completed caching requires macos.artifactInputs and a locally
10092
10263
  verified compile; remote output is not published under an unverified client key.
@@ -10115,9 +10286,10 @@ lookup. Release and physical-device builds keep their existing paths.
10115
10286
  SwiftPM, compiler and dependency caches use their existing paths.
10116
10287
  For iOS the machine's Xcode and simulator SDK must match, and it needs an
10117
10288
  iPhone simulator on the target runtime. Its project-selected CocoaPods must match too, unless
10118
- the app's Gemfile.lock pins CocoaPods: both machines then run that version through
10289
+ the app's Gemfile.lock, in ios/ or the project root, pins CocoaPods: both machines then run that version through
10119
10290
  bundler, so the machine needs only Bundler on its stim-server PATH and
10120
- installs the pinned gems itself on the first build. The comparison selects
10291
+ installs the pinned gems itself on the first build. This Mac's side of the
10292
+ comparison runs \`pod --version\` in the directory pod install runs in. The comparison selects
10121
10293
  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.
10122
10294
  For Android its CPU may differ, since the APK's ABIs come from the NDK, so an
10123
10295
  x86_64 Linux or Windows machine running stim-server can build for an Apple silicon Mac. Its JDK major
@@ -10870,7 +11042,8 @@ build pool. remote.buildPoolDisabled excludes members from automatic placement,
10870
11042
  including its local fallback. Explicit local or named placement bypasses membership.
10871
11043
  Configure remote.machines
10872
11044
  and approve build access as described in stim guide settings. The worker needs
10873
- matching Stim, CPU architecture, Xcode and macOS SDK, plus network access to
11045
+ matching Stim, CPU architecture, Xcode and macOS SDK (except for an app built and run on
11046
+ the same Mac, below), plus network access to
10874
11047
  fetch package dependencies the first time. It keeps SwiftPM dependencies in a
10875
11048
  per-client cache and incremental outputs per repository. It runs fixed swift
10876
11049
  build commands without JavaScript installs, prebuild or pods. It receives only
@@ -10878,6 +11051,12 @@ the files git lists (tracked and untracked, not ignored). Resource and catalog
10878
11051
  sources must be among those files. The client sends resolved sources relative
10879
11052
  to the repository root; the worker resolves them inside its checkout.
10880
11053
 
11054
+ With --remote <machine> and --remote-build naming the same machine (the same
11055
+ paired node), the app is built and run there, so this Mac's Xcode, macOS SDK and
11056
+ CPU architecture do not have to match: the worker needs the same Stim build and
11057
+ its own Xcode and macOS SDK. This Mac's cache is skipped and the worker's cache
11058
+ identity comes from the worker's toolchain. Any other combination keeps the match.
11059
+
10881
11060
  The client validates the development plist and resource entries before asking a machine. It verifies
10882
11061
  the returned archive's sha256, bundle identifier, executable, declared resources
10883
11062
  and ad hoc signature