stim 1.19.0 → 1.20.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 +20 -3
- package/dist/{activity-BSw0x84R.mjs → activity-BrGh9EAI.mjs} +3 -3
- package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-DVyv_hWj.mjs} +7 -7
- package/dist/android-0vv-OruW.mjs +6 -0
- package/dist/android-Brx6EKvJ.mjs +1258 -0
- package/dist/{android-BdQC6zs1.mjs → android-BsYNR81W.mjs} +103 -45
- package/dist/{android-DE5g_5gv.mjs → android-CK3fpEyZ.mjs} +2 -2
- package/dist/{android-cas-C87geAg-.mjs → android-cas-DCAuXryb.mjs} +9 -5
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/api-run.mjs +159 -8
- package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
- package/dist/api.d.mts +98 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-install-CFI4ptUL.mjs → app-install-0LgaQRT7.mjs} +9 -8
- package/dist/artifact-CnC0mfov.mjs +807 -0
- package/dist/artifact-DClXJNWx.mjs +772 -0
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
- package/dist/{browser-web-CDhqQxhv.mjs → browser-web-CzBmhmgs.mjs} +19 -19
- package/dist/{budget-Dz-kyXLv.mjs → budget-BONq9vXY.mjs} +3101 -3062
- package/dist/build-BixRI6sB.mjs +462 -0
- package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
- package/dist/build-plan-CP0tckNU.mjs +553 -0
- package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{manifest-CX0d1IkZ.mjs → ccache-CjHQ5F8g.mjs} +13 -19
- package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
- package/dist/{cli-C9Zvgbdc.mjs → cli-B2R8wH1F.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-CuUo8Nvg.mjs → client-BLy1Pw2V.mjs} +89 -307
- package/dist/collector-run.d.mts +4 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-Bt8ygHE7.mjs → command-output-BjPN99ZB.mjs} +2 -2
- package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
- package/dist/{created-devices-D0s26Hx5.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
- package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
- package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
- package/dist/{dev-client-CDY_zAmD.mjs → dev-client-ClATaJoH.mjs} +2 -2
- package/dist/{device-BHw0WlHl.mjs → device-B7lsC0K1.mjs} +8 -8
- package/dist/device-DVCwAFlX.mjs +727 -0
- package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-Ca_ke1LE.mjs} +13 -14
- package/dist/device-host-worker.mjs +38 -18
- package/dist/device-ios-CRUqPxKw.mjs +413 -0
- package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-DHOBXGgS.mjs} +135 -22
- package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
- package/dist/{device-pool-CP4rAsHx.mjs → device-pool-L2-5GxMy.mjs} +3 -3
- package/dist/{device-remote-B5GiUifk.mjs → device-remote-Bmg42063.mjs} +17 -68
- package/dist/doctor-C2MSuMMg.mjs +515 -0
- package/dist/{doctor-PRJH94v6.mjs → doctor-DPAqhVCK.mjs} +333 -744
- package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-CB4NnVZm.mjs} +13 -12
- package/dist/{simslim-D9LkJxIO.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
- package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
- package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
- package/dist/errors-DzkMYh8Q.mjs +205 -0
- package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
- package/dist/{gc-CyHMcKcn.mjs → gc-PWp34zGb.mjs} +21 -20
- package/dist/{device-ios-B2ruohE-.mjs → gradle-C2OEKCCI.mjs} +21 -650
- package/dist/{guide-dRaQJJk9.mjs → guide-Dai9lphv.mjs} +504 -117
- package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
- package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client-Io01s5By.mjs} +9 -3
- package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
- package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
- package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
- package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-BdAQi21M.mjs} +17 -14
- package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
- package/dist/{ios-DYUr9LGc.mjs → ios-BZ9dg2Fr.mjs} +8 -7
- package/dist/{ios-BWbHFZVz.mjs → ios-CXLIUxXJ.mjs} +180 -24
- package/dist/ios-CZuv6gRv.mjs +1112 -0
- package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
- package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
- package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BreZOpM0.mjs} +3 -3
- package/dist/ios-project-B9drt_aY.mjs +197 -0
- package/dist/{ios-state-By0XuLTQ.mjs → ios-state-CjrL2qv-.mjs} +1 -1
- package/dist/js-swap-C8icNYIY.mjs +432 -0
- package/dist/launch-DxH0THLP.mjs +745 -0
- package/dist/{react-native-ios-CSpIxexZ.mjs → launch-YrbqaIFj.mjs} +59 -612
- package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
- package/dist/{logs-Bao1HOMy.mjs → logs-DHaRNfg7.mjs} +11 -11
- package/dist/macos-C0iljhsN.mjs +2 -0
- package/dist/{macos-ciyBdTY5.mjs → macos-V_3Ui7g4.mjs} +42 -50
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -10
- package/dist/{metro-DI2AjPF_.mjs → metro-D_j9sN-B.mjs} +18 -5
- package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
- package/dist/miss-reason-BPAzZS0r.mjs +238 -0
- package/dist/{named-ports-B4iWH4E-.mjs → named-ports-C2lvoPsb.mjs} +3 -3
- package/dist/native-android-lHzaew7r.mjs +226 -0
- package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
- package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-BRmWL7ru.mjs} +9 -8
- package/dist/native-xcode-inputs-eutS19jU.mjs +307 -0
- package/dist/native-xcode-ios-DP3cHLwu.mjs +434 -0
- package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
- package/dist/offload-worker.d.mts +41 -7
- package/dist/offload-worker.mjs +409 -74
- package/dist/{ownership-EB0ySdGK.mjs → ownership-DXzMMSx6.mjs} +2 -2
- package/dist/{placement-log-Dxe34rJm.mjs → placement-log-reFbjqEr.mjs} +1 -1
- package/dist/plan-BDk2AeY_.mjs +260 -0
- package/dist/plan-placement-D_YYlE6N.mjs +73 -0
- package/dist/{ports-ByPc0_97.mjs → ports-jzvAJXXL.mjs} +3 -3
- package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-Bw44QxVh.mjs} +4 -4
- package/dist/{preview-BbSottmO.mjs → preview-BaBJ72Al.mjs} +50 -32
- package/dist/project-B8_duAzW.mjs +1067 -0
- package/dist/project-plan-BPwbLwQu.mjs +10 -0
- package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-android-chm1DMlA.mjs +921 -0
- package/dist/react-native-build-oAw6gQeW.mjs +239 -0
- package/dist/react-native-doctor-DYXoh-6I.mjs +78 -0
- package/dist/react-native-ios-SCTK_CT5.mjs +595 -0
- package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
- package/dist/{reload-rAPdqeRR.mjs → reload-D34GkY78.mjs} +17 -13
- package/dist/remote-BU9UyhCJ.mjs +192 -0
- package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
- package/dist/result-BDoRk1k3.mjs +186 -0
- package/dist/{run-lAkle1-c.mjs → run-qvff78hv.mjs} +3 -3
- package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
- package/dist/server-command-7XIKlWtO.mjs +69 -0
- package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CsYu2aKL.mjs} +107 -82
- package/dist/server-expo-DV43vep4.mjs +2 -0
- package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
- package/dist/{settings-2am7TSxp.mjs → settings-CT3E71-i.mjs} +6 -6
- package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
- package/dist/settings.schema.json +84 -0
- package/dist/simslim-ChMfe8rg.mjs +149 -0
- package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-B9hn96wd.mjs} +6 -6
- package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
- package/dist/start-CbQCSnXQ.mjs +2 -0
- package/dist/{start-DtxthMfI.mjs → start-CdvcTaXr.mjs} +97 -68
- package/dist/{state-Tp4uImDS.mjs → state-Boo0IMJq.mjs} +1 -1
- package/dist/{state-D2KtnALG.mjs → state-DI84A-uu.mjs} +29 -10
- package/dist/{stats-8EJ5ivFT.mjs → stats-BIIDrjA8.mjs} +5 -5
- package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
- package/dist/{status-BOyp0CUl.mjs → status-DARMkc9q.mjs} +81 -293
- package/dist/status-watch-DvmI3SmN.mjs +296 -0
- package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
- package/dist/{stop-DRipAg-e.mjs → stop-CCZS-C9m.mjs} +2 -2
- package/dist/{stop-D0UIpZuh.mjs → stop-WQPQHLuy.mjs} +5 -5
- package/dist/{stop-zDlknFoz.mjs → stop-iNemHsJC.mjs} +21 -20
- package/dist/supervisor-run.d.mts +7 -2
- package/dist/supervisor-run.mjs +32 -20
- package/dist/{support-DsNaFg6D.mjs → support-CnE_SIjt.mjs} +17 -7
- package/dist/{support-CNqYkV0y.mjs → support-DCco5fut.mjs} +61 -8
- package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-afeNUExW.mjs} +5 -5
- package/dist/tailnet-CoJUb2tB.mjs +265 -0
- package/dist/toolchain-BIupIro1.mjs +2 -0
- package/dist/{toolchain-C3xSoyUl.mjs → toolchain-DqyDXs30.mjs} +206 -53
- package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
- package/dist/trigger-SHLOWJ4O.mjs +2 -0
- package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-C3ASD6z5.mjs} +6 -6
- package/dist/{watchman-BL1IdOtq.mjs → watchman-CQl51YZu.mjs} +6 -6
- package/dist/{web-DbbrPUn0.mjs → web-B3eldHFH.mjs} +9 -13
- package/dist/web-BLXpOe6b.mjs +2 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
- package/dist/{workspaces-Djb2gfi9.mjs → workspaces-D2xSHBDY.mjs} +1260 -1258
- package/dist/{worktree-BL4M1rhB.mjs → worktree-BxDqaTev.mjs} +84 -48
- package/dist/worktree-q7_OZNY0.mjs +2 -0
- package/package.json +8 -6
- package/shim/native-android.gradle +101 -0
- package/dist/android-BXc6BmEi.mjs +0 -3732
- package/dist/android-BvV1gGdN.mjs +0 -4
- package/dist/ios-ITYno9rO.mjs +0 -2241
- package/dist/macos-nIOATJmR.mjs +0 -2
- package/dist/metro-store-BAHFcJm6.mjs +0 -106
- package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
- package/dist/plan-placement-BVY59qa8.mjs +0 -290
- package/dist/project-B5eQ1USs.mjs +0 -612
- package/dist/react-native-ios-BMh2i25I.mjs +0 -2
- package/dist/server-expo-DGsdUGX2.mjs +0 -2
- package/dist/start-D8NbxNBb.mjs +0 -2
- package/dist/trigger-CoalsMTV.mjs +0 -2
- package/dist/web-DFpFeZu5.mjs +0 -2
- package/dist/worktree-DV-A0LNL.mjs +0 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { s as RECENT_LAUNCH_MS } from "./watchman-
|
|
4
|
-
import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-
|
|
1
|
+
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-Bbztm4oV.mjs";
|
|
2
|
+
import { r as findProjectRoot } from "./project-B8_duAzW.mjs";
|
|
3
|
+
import { s as RECENT_LAUNCH_MS } from "./watchman-CQl51YZu.mjs";
|
|
4
|
+
import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-CB4NnVZm.mjs";
|
|
5
|
+
import "./status-watch-DvmI3SmN.mjs";
|
|
5
6
|
import { SETTINGS, SETTINGS_SCHEMA_URL, TUTORIAL_VERSION } from "@stim-cli/core/state";
|
|
6
7
|
import chalk from "chalk";
|
|
7
8
|
//#region src/guide/agent.ts
|
|
@@ -14,6 +15,9 @@ device with another workspace. Prefer plain output: it streams each phase and
|
|
|
14
15
|
ends with the facts the next step needs. Use --json only when a script must
|
|
15
16
|
parse a stable payload.
|
|
16
17
|
|
|
18
|
+
For a native Xcode or Gradle app without React Native or Expo, read guide
|
|
19
|
+
lifecycle native-ios or guide lifecycle native-android before running it.
|
|
20
|
+
|
|
17
21
|
TWO WORKFLOWS
|
|
18
22
|
|
|
19
23
|
WORKTREE is the default. Take SINGLE CHECKOUT only when the user asks to work in
|
|
@@ -91,7 +95,10 @@ the printed remedy and keep concurrent runs on the same STIM_HOME.
|
|
|
91
95
|
Before native work, run doctor for the platform in scope when the STATUS block
|
|
92
96
|
at the top of this topic says it is due. No block means doctor is current and
|
|
93
97
|
Stim is up to date. In the worktree workflow, run it from the linked worktree
|
|
94
|
-
so it also checks the source checkout.
|
|
98
|
+
so it also checks the source checkout. Doctor never loads fingerprint.config.js
|
|
99
|
+
or runs an eas from the project tree; its fingerprint checks can still run
|
|
100
|
+
installed Expo packages, including hoisted ones, as a build does. warm,
|
|
101
|
+
start, ios and android run project code. Follow each finding's printed remedy,
|
|
95
102
|
and read the routed topic below before acting on one you do not understand. If
|
|
96
103
|
the stim resolved from PATH is older than another installation, fix PATH or the
|
|
97
104
|
installation before continuing so commands and guidance match. Under host
|
|
@@ -405,7 +412,7 @@ FULL TOPIC LIST
|
|
|
405
412
|
//#endregion
|
|
406
413
|
//#region src/guide/api.ts
|
|
407
414
|
var api_default = {
|
|
408
|
-
summary: "Typed lifecycle API: createStim, run, stop, diagnostics, and cancellation",
|
|
415
|
+
summary: "Typed lifecycle API: createStim, build, run, stop, diagnostics, and cancellation",
|
|
409
416
|
body: () => `PROGRAMMATIC API
|
|
410
417
|
|
|
411
418
|
Install stim as a project dependency: npm install --save-dev stim.
|
|
@@ -435,8 +442,27 @@ run takes platform plus its options:
|
|
|
435
442
|
macos: remoteBuild
|
|
436
443
|
web: headed (default false)
|
|
437
444
|
iOS and Android also accept slot, metroCheck, buildCache, and remoteBuild.
|
|
438
|
-
All methods accept signal. run builds, installs and launches
|
|
439
|
-
|
|
445
|
+
All methods accept signal. run builds, installs and launches.
|
|
446
|
+
Web requires a running server, just like stim web.
|
|
447
|
+
|
|
448
|
+
build produces an artifact without acquiring a device, starting a runtime, or
|
|
449
|
+
stopping an existing session. Its result is inferred from platform:
|
|
450
|
+
const result = await stim.build({ platform: 'ios' });
|
|
451
|
+
console.log(result.facts.appPath);
|
|
452
|
+
|
|
453
|
+
Build options:
|
|
454
|
+
ios: scheme, configuration, arch (arm64, x86_64, all), buildCache, remoteBuild
|
|
455
|
+
android: variant, abi (arm64-v8a, armeabi-v7a, x86, x86_64, all), buildCache, remoteBuild
|
|
456
|
+
macos: remoteBuild
|
|
457
|
+
An iOS build targets the simulator. A Debug build defaults to the host
|
|
458
|
+
architecture (Android only while optimizations.android.targetAbiOnly is on, the
|
|
459
|
+
default); Release defaults to all. macOS builds the configured Debug SwiftPM app.
|
|
460
|
+
Build results retain an owned appPath (iOS), apkPath (Android) or bundle (macOS)
|
|
461
|
+
inside this workspace until worktree removal. Later builds keep earlier copies.
|
|
462
|
+
A build leaves a running app's last build record and build log untouched; it
|
|
463
|
+
writes its own build-artifact-<platform>.ndjson. No distribution archive or web build
|
|
464
|
+
pipeline is inferred. Use @stim-cli/ci's buildCI to export a portable artifact and
|
|
465
|
+
diagnostics for your CI provider.
|
|
440
466
|
|
|
441
467
|
run returns { platform, facts }. iOS facts include udid; Android includes
|
|
442
468
|
serial; both include bundleId, appPath, metroPort, cacheHit and launched.
|
|
@@ -518,7 +544,9 @@ worktree, carries git:
|
|
|
518
544
|
null when git fails or does not answer within 3 s, or the
|
|
519
545
|
worktree has no environment and sits in ~/Desktop, ~/Documents,
|
|
520
546
|
~/Downloads, iCloud Drive, ~/Library/CloudStorage or /Volumes,
|
|
521
|
-
which status does not open on macOS
|
|
547
|
+
which status does not open on macOS; one-shot status also
|
|
548
|
+
leaves it null for a worktree with no live environment and
|
|
549
|
+
for every unprovisioned worktree
|
|
522
550
|
changed tracked paths with staged or unstaged changes, conflicts included
|
|
523
551
|
untracked untracked entries as git status lists them; a new directory
|
|
524
552
|
counts once
|
|
@@ -528,16 +556,17 @@ worktree, carries git:
|
|
|
528
556
|
mergedInto "origin/<default>" when gc would call the branch merged, judged
|
|
529
557
|
from local refs without fetching, else null
|
|
530
558
|
|
|
531
|
-
status runs \`git status --porcelain=v2 --branch\` in
|
|
532
|
-
|
|
559
|
+
status runs \`git status --porcelain=v2 --branch\` in the worktrees it reads,
|
|
560
|
+
six git calls at a time, and caches the merge verdict by HEAD and default-branch commit
|
|
533
561
|
under $STIM_HOME/git-merge. One call starts no new merge check 250 ms after
|
|
534
562
|
its first; later calls judge the rest, and until then a verdict for the same
|
|
535
563
|
HEAD at an older default-branch commit stands in; a check that timed out
|
|
536
564
|
is retried after 5 minutes. \`status --watch\` reuses a worktree's git read
|
|
537
565
|
until its index, HEAD, reflog or the branch, upstream or default-branch refs
|
|
538
566
|
change, and for at most 60 s, so a file edit, creation or deletion that is
|
|
539
|
-
not staged can take up to a minute to show.
|
|
540
|
-
|
|
567
|
+
not staged can take up to a minute to show. One-shot status reads git only
|
|
568
|
+
for live environments; \`status --watch\` reads every worktree. Plain status prints "git: 2 changed, 1 untracked, ahead 3" under
|
|
569
|
+
each environment it read, and the same after each worktree with no environment under \`--watch\`.
|
|
541
570
|
|
|
542
571
|
The paired phone's Work sheet can open changed and untracked files when the
|
|
543
572
|
server advertises workspace-diff. File lists and selected patches load on
|
|
@@ -632,7 +661,8 @@ leased until <time>" for each one.`,
|
|
|
632
661
|
port the Metro port RESERVED for this workspace
|
|
633
662
|
supervisorPid the detached supervisor's pid, or NULL when a dev server was
|
|
634
663
|
already answering that Stim did not start
|
|
635
|
-
mode "bare-inproc" | "expo-child" |
|
|
664
|
+
mode "bare-inproc" | "expo-child" | "command-child" | null
|
|
665
|
+
(see \`guide metro\`)
|
|
636
666
|
logsDir where the NDJSON timeline is written
|
|
637
667
|
agentDevice { stateDir }: absolute workspace agent-device state path;
|
|
638
668
|
set AGENT_DEVICE_STATE_DIR to it (see guide logs)
|
|
@@ -696,8 +726,9 @@ leased until <time>" for each one.`,
|
|
|
696
726
|
configuration the Xcode configuration that was built ("Release" from
|
|
697
727
|
--configuration or the ios.configuration setting); null for
|
|
698
728
|
the default Debug
|
|
699
|
-
scheme the explicit shared Xcode scheme selected by --scheme
|
|
700
|
-
absent for automatic selection;
|
|
729
|
+
scheme the explicit shared Xcode scheme selected by --scheme or
|
|
730
|
+
the ios.scheme setting; absent for automatic selection;
|
|
731
|
+
not the app URL scheme
|
|
701
732
|
cacheKey the shared-build-cache key derived from it (the
|
|
702
733
|
configuration is part of it: -release-sim vs
|
|
703
734
|
-debug-sim-arm64). A single-architecture simulator build
|
|
@@ -757,8 +788,11 @@ leased until <time>" for each one.`,
|
|
|
757
788
|
the bundle would cost more than installing it
|
|
758
789
|
launched true, "bundling", or "unverified". THE THREE ARE DIFFERENT
|
|
759
790
|
FACTS and only the last one is a problem.
|
|
760
|
-
true Metro finished the bundle response,
|
|
761
|
-
|
|
791
|
+
true Metro finished the bundle response, or an app
|
|
792
|
+
without Metro (a release build, or a native
|
|
793
|
+
Xcode or Gradle app) has a live process; then
|
|
794
|
+
the app stayed alive through a three-second
|
|
795
|
+
stability window.
|
|
762
796
|
The command checks process liveness when the
|
|
763
797
|
platform exposes it. Errors from that window
|
|
764
798
|
are printed even when the app stays alive,
|
|
@@ -1013,6 +1047,9 @@ leased until <time>" for each one.`,
|
|
|
1013
1047
|
optional fields
|
|
1014
1048
|
findings the diagnostic findings; a lower resolved Stim is a
|
|
1015
1049
|
costs-time finding with a PATH or installation remedy
|
|
1050
|
+
memory-culprit is a costs-time finding naming a process
|
|
1051
|
+
with an abnormally large footprint and, when it is safe to
|
|
1052
|
+
restart, the command
|
|
1016
1053
|
offload-candidate is a note after 3+ successful local cold builds in 7 days average over 3 min, with no remote.machines and an online tailnet Mac; open Stim Desktop Settings > Remote Macs > Add
|
|
1017
1054
|
|
|
1018
1055
|
ON FAILURE
|
|
@@ -1464,6 +1501,9 @@ RULES
|
|
|
1464
1501
|
of the Stim tutorial app (stim guide tutorial). Status
|
|
1465
1502
|
reports whatever version it finds; Desktop decides which
|
|
1466
1503
|
versions it supports. Static app.json only.
|
|
1504
|
+
doctorRuns { ios?: { at }, android?: { at } }: when stim doctor last
|
|
1505
|
+
ran in the workspace, per platform, as ISO timestamps;
|
|
1506
|
+
absent until it has run.
|
|
1467
1507
|
recording { enabled }: whether stim-server may record the workspace's
|
|
1468
1508
|
device screens for replay, from recording.enabled
|
|
1469
1509
|
|
|
@@ -1733,8 +1773,8 @@ RULES
|
|
|
1733
1773
|
build { platform, slot, state, phase, startedAt, phaseStartedAt,
|
|
1734
1774
|
outcome, outcomeKnown, cacheLookupOutcome?, expectedMs, expectedPhaseMs,
|
|
1735
1775
|
completedPhaseMs?, basis,
|
|
1736
|
-
plannedPhases, missReason?, missProvisional?, detail?,
|
|
1737
|
-
waitingOn?, waitingFor? }
|
|
1776
|
+
plannedPhases, missReason?, missProvisional?, detail?, activity?,
|
|
1777
|
+
placement, waitingOn?, waitingFor? }
|
|
1738
1778
|
|
|
1739
1779
|
state "running" while the run's own native-run claim is live;
|
|
1740
1780
|
"stale" when that claim was released or its process is
|
|
@@ -1826,6 +1866,16 @@ RULES
|
|
|
1826
1866
|
to file names, at most 160 characters
|
|
1827
1867
|
updatedAt when the build last wrote it; the run writes it at most
|
|
1828
1868
|
every 2 seconds
|
|
1869
|
+
activity during device or launch, once Stim observed what the run
|
|
1870
|
+
waits on: { name, startedAt, percent? }. name is
|
|
1871
|
+
"booting" while device waits for the owned simulator or
|
|
1872
|
+
emulator the run is booting; during launch, "bundling"
|
|
1873
|
+
from the app's bundle request to this workspace's Metro
|
|
1874
|
+
until Metro delivered it, or "waiting-ready" while the
|
|
1875
|
+
app reports its readiness pending; absent in between.
|
|
1876
|
+
startedAt is the evidence's time. percent is Metro's own
|
|
1877
|
+
progress for that request, present only once Metro
|
|
1878
|
+
reported one. Activity never changes launched.
|
|
1829
1879
|
placement where the build runs: "local", or while it is offloaded
|
|
1830
1880
|
{ host, phase, startedAt, phaseStartedAt }. host is the
|
|
1831
1881
|
remote.machines entry; phase is the step there: sync,
|
|
@@ -1846,6 +1896,7 @@ RULES
|
|
|
1846
1896
|
|
|
1847
1897
|
build: ios compile, 1m10s elapsed -- about 3 min left (median of 4 cold runs)
|
|
1848
1898
|
build: ios compile on janics-mac-mini (build, 2m10s), 3m05s elapsed
|
|
1899
|
+
build: ios launch (bundling JS 45%, 12s), 58s elapsed
|
|
1849
1900
|
|
|
1850
1901
|
An environment with a recorded run also carries lastBuilds, each
|
|
1851
1902
|
platform's most recent ios or android run, finished or failed:
|
|
@@ -2025,7 +2076,9 @@ RULES
|
|
|
2025
2076
|
builds included, when machine.memorySource is footprint. Otherwise it is
|
|
2026
2077
|
the estimate, with memorySource estimate.
|
|
2027
2078
|
|
|
2028
|
-
capacity.committedMb sums memoryMb
|
|
2079
|
+
capacity.committedMb sums memoryMb; in a \`status --watch --json\` line each
|
|
2080
|
+
figure, including an environment's memoryMb, is held on its own (see
|
|
2081
|
+
\`guide lifecycle\`), so the sums can differ from what they sum. The memory budget plans before a boot
|
|
2029
2082
|
and always uses the estimate. What is using CPU and memory now is the
|
|
2030
2083
|
top-level machine section:
|
|
2031
2084
|
|
|
@@ -2441,8 +2494,9 @@ WHAT THE SUPERVISOR IS
|
|
|
2441
2494
|
to install, and no cross-project state. It hosts the dev server, writes its
|
|
2442
2495
|
output as NDJSON into the global workspace logs directory
|
|
2443
2496
|
($STIM_HOME/workspaces/<project>--<digest>/logs; see \`guide logs\`), and
|
|
2444
|
-
records itself in that workspace's state.json before it starts serving.
|
|
2445
|
-
|
|
2497
|
+
records itself in that workspace's state.json before it starts serving. Three
|
|
2498
|
+
modes: metro.command selects command-child, otherwise ecosystem detection
|
|
2499
|
+
picks one of the first two:
|
|
2446
2500
|
|
|
2447
2501
|
bare-inproc bare React Native: Metro is hosted INSIDE the supervisor,
|
|
2448
2502
|
from the project's own node_modules, with Stim's reporter
|
|
@@ -2451,6 +2505,15 @@ WHAT THE SUPERVISOR IS
|
|
|
2451
2505
|
expo-child Expo: the project's own \`expo start --port <port>\` runs as
|
|
2452
2506
|
a child and its stdout is parsed into records. Levels are
|
|
2453
2507
|
INFERRED from each line, so those records carry raw: true.
|
|
2508
|
+
command-child metro.command (\`guide settings\`): that argv runs as a
|
|
2509
|
+
child in its own process group, with {port} replaced by the
|
|
2510
|
+
reserved port, and its output is parsed like expo-child's
|
|
2511
|
+
under command_stdout and command_stderr events. Stopping the
|
|
2512
|
+
dev server signals the whole group, so a wrapper such as
|
|
2513
|
+
yarn takes its Metro with it. Stim adds no reporter, warmup
|
|
2514
|
+
observer or shared transform store, so ios and android
|
|
2515
|
+
launches stay UNVERIFIED: read \`stim logs --source metro\`
|
|
2516
|
+
for the bundle lines.
|
|
2454
2517
|
|
|
2455
2518
|
In expo-child mode, remote intent plus metro.tunnel "expo" makes \`start\` pass
|
|
2456
2519
|
\`--tunnel\` and EXPO_UNSTABLE_TUNNEL_V2=1 (the legacy ws-tunnel path is
|
|
@@ -2469,7 +2532,8 @@ WHAT THE SUPERVISOR IS
|
|
|
2469
2532
|
|
|
2470
2533
|
IDLE STOP: the supervisor stops its dev server after metro.idleStopMinutes
|
|
2471
2534
|
(default 60; 0 never stops) with no bundle request, no client log record
|
|
2472
|
-
(in-app console logs; for Expo, any stdout line of the
|
|
2535
|
+
(in-app console logs; for Expo or metro.command, any stdout line of the
|
|
2536
|
+
dev server) and no Stim
|
|
2473
2537
|
command in the workspace (start, ios, android, reload, worktree warm). It
|
|
2474
2538
|
checks once a minute. It keeps running while a bundle response is in
|
|
2475
2539
|
flight, while a build in the workspace is in progress, while a stim ios,
|
|
@@ -2650,11 +2714,12 @@ ports release [label] releases without signalling a process.
|
|
|
2650
2714
|
Omitting the label selects every named port, never Metro. stim stop leaves
|
|
2651
2715
|
named ports alone.
|
|
2652
2716
|
|
|
2653
|
-
worktree remove
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2717
|
+
worktree remove, gc --delete and automatic maintenance release named
|
|
2718
|
+
allocations without signalling their listeners; run ports stop first to stop
|
|
2719
|
+
a server this workspace started. gc reports allocations whose workspace no
|
|
2720
|
+
longer exists; gc --delete releases them. Unmounted or unresolved workspace
|
|
2721
|
+
paths are retained. Use the same current Stim version for cleanup: versions
|
|
2722
|
+
without ports do not know about named allocations.
|
|
2658
2723
|
|
|
2659
2724
|
A shared API does not get a shared reservation. Pass its port by environment
|
|
2660
2725
|
instead of allocating a separate label in every worktree.`
|
|
@@ -2879,7 +2944,8 @@ THE RECORD
|
|
|
2879
2944
|
clockOffsetMs the offset added to deviceTs; absent if the query failed.
|
|
2880
2945
|
A collector_clock warning then says timestamps retain device time.
|
|
2881
2946
|
raw true when the level was inferred from a line of text rather than
|
|
2882
|
-
reported by the producer (every expo-child
|
|
2947
|
+
reported by the producer (every expo-child and command-child
|
|
2948
|
+
record)
|
|
2883
2949
|
context --errors --json only: the code frame and stack lines Expo
|
|
2884
2950
|
printed after this error, as an array of strings. Absent when
|
|
2885
2951
|
there are none. Stim adds it at query time; it is not in the
|
|
@@ -2950,11 +3016,11 @@ they stay in the local logs. These records carry no tokens.
|
|
|
2950
3016
|
|
|
2951
3017
|
WHAT WRITES WHAT
|
|
2952
3018
|
maintenance.ndjson workspace maintenance actions, failures and explaining skips
|
|
2953
|
-
metro.ndjson the bundler, in
|
|
3019
|
+
metro.ndjson the bundler, in every supervisor mode
|
|
2954
3020
|
client.ndjson in-app console logs and redboxes -- BARE PROJECTS ONLY.
|
|
2955
|
-
In expo-child mode everything
|
|
2956
|
-
metro.ndjson with raw: true,
|
|
2957
|
-
returns nothing there.
|
|
3021
|
+
In expo-child and command-child mode everything the
|
|
3022
|
+
dev server prints lands in metro.ndjson with raw: true,
|
|
3023
|
+
so \`--source client\` returns nothing there.
|
|
2958
3024
|
device.ndjson the device-log collector uses \`simctl log stream\`
|
|
2959
3025
|
predicated on the app, or \`adb logcat\` filtered to
|
|
2960
3026
|
the app's pid. Local iOS simulator capture starts
|
|
@@ -3117,7 +3183,9 @@ WHAT WRITES WHAT
|
|
|
3117
3183
|
build-android.ndjson extracted diagnostics at level error, and the launch as
|
|
3118
3184
|
a marker record. One RUN's worth: each build starts the
|
|
3119
3185
|
file over, so the first error in it always belongs to
|
|
3120
|
-
the run that pointed you at it.
|
|
3186
|
+
the run that pointed you at it. A build from the API's
|
|
3187
|
+
build() writes build-artifact-<platform>.ndjson
|
|
3188
|
+
instead, so it never replaces a run's transcript.
|
|
3121
3189
|
|
|
3122
3190
|
Only a dev server Stim hosted is captured. If you started the bundler
|
|
3123
3191
|
yourself, the metro and client sources stay empty -- which is not a sign of a
|
|
@@ -3579,7 +3647,8 @@ Rerun with --remote-build auto for normal placement and local fallback, or
|
|
|
3579
3647
|
body: () => `STIM_NO_SCHEME
|
|
3580
3648
|
Stim could not list or select an app scheme in ios/. Share the intended app
|
|
3581
3649
|
scheme so xcodebuild can see it. Select an available exact name with
|
|
3582
|
-
\`stim ios --scheme <name
|
|
3650
|
+
\`stim ios --scheme <name>\`, or set it once with the ios.scheme setting. An
|
|
3651
|
+
unknown explicit name prints available choices.
|
|
3583
3652
|
Without an explicit selector, a workspace
|
|
3584
3653
|
name match wins; otherwise Stim accepts a sole non-test scheme, or a listed
|
|
3585
3654
|
scheme matching app.json. Unmatched ambiguous schemes are refused.`
|
|
@@ -4255,10 +4324,10 @@ captured" (in metro.ndjson, bare RN)
|
|
|
4255
4324
|
\`--device-profile\` on an eas/proxy run (\`--remote\` or android.remote), a
|
|
4256
4325
|
\`android --remote auto\`, a changed hosted placement, or hosted Debug
|
|
4257
4326
|
with \`--no-metro-check\` (see lifecycle hosted-android), a working directory
|
|
4258
|
-
with no
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4327
|
+
with no supported app project, or a project whose integration refuses this
|
|
4328
|
+
operation. React Native and Expo require a readable package.json that
|
|
4329
|
+
declares react-native or expo; the refusal names the invalid file.
|
|
4330
|
+
\`doctor\` reports project admission problems as findings. A \`logs\` query in
|
|
4262
4331
|
a workspace that has never produced a log timeline (the refusal names the
|
|
4263
4332
|
nearest registered descendant app with logs when one exists), an
|
|
4264
4333
|
android/app/build.gradle that declares product flavors with
|
|
@@ -4285,7 +4354,7 @@ captured" (in metro.ndjson, bare RN)
|
|
|
4285
4354
|
\`gc --json --cache <name>\` refuses with STIM_BAD_ARG when no shared cache
|
|
4286
4355
|
carries the name; the remedy names the caches on this machine. \`gc\`
|
|
4287
4356
|
refuses --cache together with --worktrees the same way.
|
|
4288
|
-
A working directory with no
|
|
4357
|
+
A working directory with no supported project above it gets the same
|
|
4289
4358
|
STIM_NO_PROJECT refusal from \`start\`, \`ios\`, \`android\`, \`stop\`,
|
|
4290
4359
|
\`reload\`, \`logs\`, \`doctor\` and \`device lock|unlock\`. With \`--json\` the { code, message, remedy } object
|
|
4291
4360
|
is on stdout, except \`logs --json\`, whose stdout stays empty NDJSON; the
|
|
@@ -4746,6 +4815,10 @@ const lifecycle = {
|
|
|
4746
4815
|
summary: "The full worktree -> start -> ios/android -> logs -> teardown flow, with sections for builds, devices and flags",
|
|
4747
4816
|
preamble: () => `ENVIRONMENT LIFECYCLE
|
|
4748
4817
|
|
|
4818
|
+
For a native Xcode or Gradle app without React Native or Expo, read
|
|
4819
|
+
\`stim guide lifecycle native-ios\` or \`stim guide lifecycle native-android\`.
|
|
4820
|
+
The Metro and JavaScript steps below apply to React Native and Expo.
|
|
4821
|
+
|
|
4749
4822
|
Two workflows share steps 2 through 6.
|
|
4750
4823
|
|
|
4751
4824
|
SINGLE CHECKOUT: work in place, on a branch, in one directory. There is no
|
|
@@ -4821,7 +4894,7 @@ a seed belongs to this workflow.
|
|
|
4821
4894
|
# unwarmed worktrees with no Stim registry entry. Git-created branches stay.
|
|
4822
4895
|
stim worktree remove
|
|
4823
4896
|
|
|
4824
|
-
A Debug \`ios\` or \`android\` run checks the reserved port before the device
|
|
4897
|
+
A React Native or Expo Debug \`ios\` or \`android\` run checks the reserved port before the device
|
|
4825
4898
|
or the build. When no healthy dev server of this workspace answers there, it
|
|
4826
4899
|
runs the same start as step 2: a dev server started outside Stim is reused, a
|
|
4827
4900
|
reservation held by a foreign process moves to a free port, and the budgets
|
|
@@ -4985,7 +5058,10 @@ WAITING FOR A CHANGE
|
|
|
4985
5058
|
To wait for a device, a build or a dev server instead of polling, run
|
|
4986
5059
|
\`stim status --watch --json\`. It keeps running and prints one complete
|
|
4987
5060
|
status payload per line: one at once, then one each time the payload
|
|
4988
|
-
changes, never two identical ones in a row.
|
|
5061
|
+
changes, never two identical ones in a row. In a watch line, a usage
|
|
5062
|
+
figure repeats its value in the previous line until it moves by a step: an owner's cpuPercent 5 points, an
|
|
5063
|
+
owner's or environment's memoryMb and capacity.committedMb 16 MB. An owner's row
|
|
5064
|
+
changes as a whole, so its residentMb and processes update with it. It reacts to Stim state files,
|
|
4989
5065
|
the EAS session ledger, adb device arrivals and departures, and simulator
|
|
4990
5066
|
state, and recomputes every 30 seconds as a fallback. A log append updates
|
|
4991
5067
|
only the log error count and device activity, no sooner than 15 seconds
|
|
@@ -4996,6 +5072,121 @@ WAITING FOR A CHANGE
|
|
|
4996
5072
|
still running, which it notices at the next change.
|
|
4997
5073
|
Without --json it reprints the human view on change.`,
|
|
4998
5074
|
sections: {
|
|
5075
|
+
"native-ios": {
|
|
5076
|
+
summary: "native Xcode project selection, process launch, cache behavior and current limits",
|
|
5077
|
+
body: () => `NATIVE XCODE APPS
|
|
5078
|
+
Run from the directory containing the .xcodeproj or .xcworkspace. A Node
|
|
5079
|
+
package.json is not required. React Native and Expo apps keep their existing
|
|
5080
|
+
integration.
|
|
5081
|
+
|
|
5082
|
+
stim doctor --platform ios
|
|
5083
|
+
stim ios --scheme MyApp --configuration Debug --json
|
|
5084
|
+
stim ios --scheme MyApp --configuration Release --json
|
|
5085
|
+
stim logs --errors
|
|
5086
|
+
stim stop
|
|
5087
|
+
|
|
5088
|
+
Use the project's actual scheme and configuration names. Shared Run schemes
|
|
5089
|
+
select application targets; a unique application target can also use its
|
|
5090
|
+
automatic scheme. A workspace owns its referenced projects. --scheme selects
|
|
5091
|
+
an exact name; duplicate container/scheme matches refuse instead of guessing.
|
|
5092
|
+
--configuration overrides ios.configuration in .stim.json, then defaults to
|
|
5093
|
+
Debug. Custom configurations such as Staging use the same path.
|
|
5094
|
+
|
|
5095
|
+
Native Debug, Release and custom configurations do not start or require Metro,
|
|
5096
|
+
embed JavaScript, or swap a JavaScript bundle. The app is launched as a native
|
|
5097
|
+
process and reports metroPort: null. launched: true establishes a live process;
|
|
5098
|
+
verify the expected screen and interaction on the reported device separately.
|
|
5099
|
+
After a native source edit, rerun stim ios. stim reload is for JavaScript.
|
|
5100
|
+
The existing owned simulator, device lease, signing, log and teardown services
|
|
5101
|
+
still apply. Stim does not change signing accounts or provisioning profiles.
|
|
5102
|
+
|
|
5103
|
+
A reusable artifact key includes the selected build configuration, source and
|
|
5104
|
+
known dependency inputs, toolchain and build options. In a git checkout,
|
|
5105
|
+
ignored files the project does not reference are not part of the key. Native
|
|
5106
|
+
Release cache reuse does not depend on releaseBundleSwap. Xcode compilation
|
|
5107
|
+
uses the shared compilation cache when the toolchain and settings support it.
|
|
5108
|
+
--plan predicts this same local artifact without preparing dependencies or
|
|
5109
|
+
choosing a device.
|
|
5110
|
+
|
|
5111
|
+
Inputs whose complete build closure cannot be established build locally with
|
|
5112
|
+
artifact caching skipped. This includes shell build phases, custom build rules,
|
|
5113
|
+
C-family header graphs, Swift package graphs and unresolved external input
|
|
5114
|
+
paths or compiler overrides. The miss reason explains the exclusion. --plan
|
|
5115
|
+
refuses such a prediction; omit --plan to prepare and build the app.
|
|
5116
|
+
|
|
5117
|
+
A compatible approved build Mac can compile a native Xcode app with
|
|
5118
|
+
--remote-build auto or --remote-build <name>. Both peers must support
|
|
5119
|
+
native-xcode-build. This first worker path requires a verified artifact identity
|
|
5120
|
+
and all inputs contained in the repository and visible to git. Ignored or
|
|
5121
|
+
external inputs keep the build here, and placement names the first one; their
|
|
5122
|
+
bytes are never silently omitted. The common case is a Finder .DS_Store that a
|
|
5123
|
+
global gitignore hides: delete it, or stop ignoring it, to offload. The worker
|
|
5124
|
+
compares its own toolchain and compiler environment identity before compiling
|
|
5125
|
+
and refuses, naming the differing parameter, so the build falls back here.
|
|
5126
|
+
Worker source mirrors remove stale inputs, while Xcode compilation caches remain
|
|
5127
|
+
in the worker's private Stim home. Physical builds stay local.
|
|
5128
|
+
|
|
5129
|
+
Native Xcode apps can install on an already approved hosting Mac with
|
|
5130
|
+
process-mode support:
|
|
5131
|
+
stim ios --scheme MyApp --configuration Debug --remote janics-mac-mini --json
|
|
5132
|
+
|
|
5133
|
+
The host must advertise hosted-ios-process; older hosts refuse with an update
|
|
5134
|
+
remedy before reservation or upload. --remote auto skips incompatible hosts,
|
|
5135
|
+
but an existing session stays on its recorded host until stim stop. Debug,
|
|
5136
|
+
Release and custom configurations use the offered simulator architecture,
|
|
5137
|
+
report metroPort: null, and close any previous session Metro bridge. Logs,
|
|
5138
|
+
view/control, agent access and scoped stop use the existing hosted-ios services.
|
|
5139
|
+
Verify UI and interaction separately from the host's live process evidence.
|
|
5140
|
+
|
|
5141
|
+
Unbounded native build offload, hosted --plan, eas/proxy devices and EAS artifact
|
|
5142
|
+
profiles remain unsupported for native Xcode apps. These limits do not change React Native or
|
|
5143
|
+
Expo support.
|
|
5144
|
+
|
|
5145
|
+
Copyable agent request:
|
|
5146
|
+
Run this native Xcode app with stim ios --scheme MyApp --configuration Debug
|
|
5147
|
+
--json. Verify its expected screen and interaction on the reported device,
|
|
5148
|
+
inspect stim logs --errors, then stop only this workspace with stim stop.`
|
|
5149
|
+
},
|
|
5150
|
+
"native-android": {
|
|
5151
|
+
summary: "native Gradle app selection, hosted emulators, build-worker inputs and current limits",
|
|
5152
|
+
body: () => `NATIVE ANDROID GRADLE APPS
|
|
5153
|
+
Native Android Gradle apps run directly with \`stim android [--variant freeDebug]\`:
|
|
5154
|
+
no Metro, npm install or React Native dependency is required. The directory must
|
|
5155
|
+
contain a Gradle wrapper and settings.gradle or settings.gradle.kts. AGP resolves
|
|
5156
|
+
one application module and the exact variant (debug by default). Stim installs
|
|
5157
|
+
one signed universal or matching-ABI APK on an owned emulator or leased phone.
|
|
5158
|
+
Use \`--remote <approved-mac>\` or \`--remote auto\` for a hosted emulator; the host
|
|
5159
|
+
must support native Android process mode. Multiple application modules,
|
|
5160
|
+
density/split APK sets and EAS/proxy targets are unsupported. Set
|
|
5161
|
+
org.gradle.configureondemand=false; configuration cache remains supported.
|
|
5162
|
+
Stim verifies the existing APK signature; it does not sign it.
|
|
5163
|
+
|
|
5164
|
+
Stim artifact caching is unavailable because arbitrary Gradle inputs are not fully
|
|
5165
|
+
tracked. Build workers require a project-scoped \`android.offloadInputs\` declaration:
|
|
5166
|
+
\`{"complete":true,"ignored":["app/src/main/assets/generated.json"],"outputs":["build","app/build"]}\`.
|
|
5167
|
+
Use \`stim android --remote-build <approved-mac>\` after reviewing this declaration.
|
|
5168
|
+
Paths are exact repository-relative paths. complete affirms that Git-visible
|
|
5169
|
+
source plus the listed ignored files suffice, including optional files; Gradle
|
|
5170
|
+
DSL can read undeclared input without failing. Never list secrets or user Gradle
|
|
5171
|
+
homes. External inputs, directory links, submodules and custom local.properties
|
|
5172
|
+
refuse; an SDK-only local.properties stays local. Only declared directories
|
|
5173
|
+
reported by AGP and previously produced by this worker remain warm, along with
|
|
5174
|
+
worker project .gradle/.kotlin state. Undeclared bytes are removed. Gradle owns
|
|
5175
|
+
incremental, task-cache and configuration-cache reuse; transfer digests never
|
|
5176
|
+
become reusable APK cache keys. Older hosts refuse before source upload.
|
|
5177
|
+
|
|
5178
|
+
outputs must list every build directory of this build's projects that the build
|
|
5179
|
+
creates: the root build directory and each module's, library modules included.
|
|
5180
|
+
A remote build that creates an undeclared one fails with its name, and Stim
|
|
5181
|
+
builds locally; add it to outputs. A buildSrc directory refuses before upload.
|
|
5182
|
+
Included builds (includeBuild, such as a build-logic plugin build) and
|
|
5183
|
+
externalNativeBuild staging (.cxx) are not reported by AGP and cannot be
|
|
5184
|
+
declared, so a remote build that creates them fails and Stim builds locally.
|
|
5185
|
+
|
|
5186
|
+
Native Android \`--plan\` refuses without executing Gradle; \`doctor\` reports native
|
|
5187
|
+
prerequisites. \`reload\` refuses because the app has no Metro runtime. Re-run
|
|
5188
|
+
\`stim android\` after an edit and use \`stim stop\` for scoped cleanup.`
|
|
5189
|
+
},
|
|
4999
5190
|
ci: {
|
|
5000
5191
|
summary: "Run an app and tests through @stim-cli/ci with diagnostics and scoped cleanup",
|
|
5001
5192
|
body: () => `CONTINUOUS INTEGRATION
|
|
@@ -5059,7 +5250,7 @@ policy. No flag or setting runs on this Mac.
|
|
|
5059
5250
|
A named Mac is strict: refusal, unreachable, declined or failed preparation
|
|
5060
5251
|
returns STIM_HOSTING_REFUSED without fallback. --device, a different recorded
|
|
5061
5252
|
machine, a running local owned emulator in the slot, and --no-metro-check for
|
|
5062
|
-
hosted
|
|
5253
|
+
hosted Metro development apps refuse STIM_BAD_ARG. Run stim stop before switching placement.
|
|
5063
5254
|
Unreadable android.host blocks only its slot; restore its recorded machine and
|
|
5064
5255
|
session from the host before stopping that slot.
|
|
5065
5256
|
|
|
@@ -5069,7 +5260,7 @@ compatible build worker. Stim builds before reserving, records the session as
|
|
|
5069
5260
|
soon as it exists, then delivers one App.apk. The emulator boots headless;
|
|
5070
5261
|
androidEmulatorApp is ignored with a note.
|
|
5071
5262
|
|
|
5072
|
-
Debug requires the local Metro supervisor. metro.publicUrl and metro.tunnel
|
|
5263
|
+
React Native Debug requires the local Metro supervisor. metro.publicUrl and metro.tunnel
|
|
5073
5264
|
are ignored with a note. A private tailnet gateway reaches the host loopback
|
|
5074
5265
|
bridge; the host reverses the client's Metro port into that bridge on its exact
|
|
5075
5266
|
ledger-owned serial and sets debug_http_host to localhost:<clientMetroPort>.
|
|
@@ -5079,6 +5270,14 @@ adb against the host serial on this Mac. Release variants skip Metro. Launch
|
|
|
5079
5270
|
is true only with client bundle evidence or a live host release process;
|
|
5080
5271
|
bundling requires a bundle request and unverified has no launch evidence.
|
|
5081
5272
|
|
|
5273
|
+
Native Gradle apps use process mode for every variant. The host must advertise
|
|
5274
|
+
hosted-android-process; older hosts refuse before admission or APK upload.
|
|
5275
|
+
Native runs close any previous Metro bridge, launch the signed APK and require
|
|
5276
|
+
a live app process for launched=true. --no-metro-check is allowed, and reload
|
|
5277
|
+
refuses because there is no Metro runtime. Re-run stim android after an edit.
|
|
5278
|
+
Native EAS/proxy targets remain unsupported. Build offload requires the complete
|
|
5279
|
+
android.offloadInputs declaration; see stim guide lifecycle native-android.
|
|
5280
|
+
|
|
5082
5281
|
Status adds android.host { machine, session, selected, agent, device: { name,
|
|
5083
5282
|
systemImage, api }, state } per slot. The public name is the profile and API
|
|
5084
5283
|
level, never the host serial or AVD name. ready, stopped and unverified are
|
|
@@ -5275,7 +5474,7 @@ sessions.
|
|
|
5275
5474
|
|
|
5276
5475
|
|
|
5277
5476
|
Stim builds or fetches before reserving, records the session immediately, then
|
|
5278
|
-
uploads the app on every run. Debug
|
|
5477
|
+
uploads the app on every run. React Native and Expo Debug keep Metro here; the supervisor owns a
|
|
5279
5478
|
private gateway bound to this Mac's Tailscale address, pinned to the host peer
|
|
5280
5479
|
and protected by a per-session secret. The host exposes only a loopback bridge.
|
|
5281
5480
|
No start --remote is needed; metro.tunnel and metro.publicUrl are ignored.
|
|
@@ -5283,7 +5482,8 @@ Debug requires a running supervisor with private gateway support before reservin
|
|
|
5283
5482
|
a simulator. --no-metro-check refuses with STIM_BAD_ARG for hosted Debug runs.
|
|
5284
5483
|
If its supervisor is missing or older, run stim stop; stim start, then retry.
|
|
5285
5484
|
Non-Debug runs skip Metro. Launch is unverified until this workspace's Metro
|
|
5286
|
-
provides bundle evidence, or the host proves a live release process.
|
|
5485
|
+
provides bundle evidence, or the host proves a live release process. Native Xcode
|
|
5486
|
+
apps use process mode in every configuration and require no Metro; see native-ios.
|
|
5287
5487
|
|
|
5288
5488
|
A rerun on the same named Mac reattaches and delivers a new app attempt. A
|
|
5289
5489
|
stopped or missing session is replaced; an unreachable or unknown owner refuses
|
|
@@ -5956,6 +6156,11 @@ PREDICTING THE NEXT BUILD (--plan)
|
|
|
5956
6156
|
installing, or starting Metro. They take no workspace lock and write no
|
|
5957
6157
|
Stim state, cache entry or statistic, so they run beside a build.
|
|
5958
6158
|
|
|
6159
|
+
The selected project integration supplies the read-only plan and uses its
|
|
6160
|
+
build recipe's identity and cache policy. If it has no planner, --plan
|
|
6161
|
+
refuses with STIM_BAD_ARG; run the command without --plan. The refusal
|
|
6162
|
+
reports no cache hit. React Native and Expo planning behaves as follows.
|
|
6163
|
+
|
|
5959
6164
|
stim ios --plan
|
|
5960
6165
|
plan ios 1b625d.. -> local cache hit
|
|
5961
6166
|
expect ~2.7s (median of 1 hit run)
|
|
@@ -6006,13 +6211,16 @@ IOS SCHEME SELECTION
|
|
|
6006
6211
|
Xcode scheme, not the app's URL scheme. Combine it with --configuration
|
|
6007
6212
|
when choosing both an app scheme and a build configuration.
|
|
6008
6213
|
|
|
6009
|
-
|
|
6214
|
+
The ios.scheme setting names the scheme once for the app (guide settings);
|
|
6215
|
+
--scheme overrides it per run, and both give the same keys below.
|
|
6216
|
+
|
|
6217
|
+
Without --scheme or ios.scheme, automatic selection is unchanged:
|
|
6010
6218
|
Stim keeps a scheme matching the workspace/project name, or the sole non-test
|
|
6011
6219
|
scheme. When neither identifies one, it also checks the static top-level name
|
|
6012
6220
|
in the app directory's app.json against Xcode's listed schemes. It does not
|
|
6013
6221
|
execute app config or choose an arbitrary scheme from an ambiguous list.
|
|
6014
|
-
If selection fails, pass --scheme with an available name,
|
|
6015
|
-
scheme in Xcode first. See guide errors STIM_NO_SCHEME.
|
|
6222
|
+
If selection fails, pass --scheme with an available name, set ios.scheme, or
|
|
6223
|
+
share the app scheme in Xcode first. See guide errors STIM_NO_SCHEME.
|
|
6016
6224
|
|
|
6017
6225
|
Explicit schemes have separate artifact keys, shared-build locks, and Xcode
|
|
6018
6226
|
build directories. Stim identifies the resulting application from Xcode's
|
|
@@ -6021,7 +6229,8 @@ IOS SCHEME SELECTION
|
|
|
6021
6229
|
configured Stim cache providers use the scheme-specific key. The older Expo
|
|
6022
6230
|
buildCacheProvider tier is skipped for explicit schemes because a provider
|
|
6023
6231
|
may key only on the fingerprint and return another scheme's app. Omitting
|
|
6024
|
-
--scheme retains the existing cache keys and provider
|
|
6232
|
+
both --scheme and ios.scheme retains the existing cache keys and provider
|
|
6233
|
+
behavior.
|
|
6025
6234
|
|
|
6026
6235
|
AN ARTIFACT THE DEVICE ALREADY HOLDS IS NOT INSTALLED AGAIN
|
|
6027
6236
|
Both platforms store the artifact verbatim, so its hash is its identity.
|
|
@@ -6063,7 +6272,9 @@ A RUNNING APP IS RESTARTED, LIKE XCODE'S RUN
|
|
|
6063
6272
|
launch com.example.app restarted running app (was pid 4242) (0.9s)
|
|
6064
6273
|
|
|
6065
6274
|
A stop that fails refuses the launch rather than reusing the old process.
|
|
6066
|
-
When
|
|
6275
|
+
When a simulator's process list cannot be read, Stim launches with
|
|
6276
|
+
\`simctl launch --terminate-running-process\`, which replaces any running
|
|
6277
|
+
copy. When an emulator's cannot be read, Stim launches without stopping
|
|
6067
6278
|
anything and verification reports what it observes. An iPhone run
|
|
6068
6279
|
(\`ios --device\`) needs no extra step: its collector launches with
|
|
6069
6280
|
devicectl's \`--terminate-existing\`. Remote targets launch through
|
|
@@ -6982,7 +7193,7 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
6982
7193
|
MUTATE: the cache entry stays the pristine, shareable artifact, and the
|
|
6983
7194
|
per-run address lives only in the copy that is installed and then deleted.
|
|
6984
7195
|
|
|
6985
|
-
A RELEASE device run builds fresh every time for now. A cached Release app
|
|
7196
|
+
A React Native or Expo RELEASE device run builds fresh every time for now. A cached Release app
|
|
6986
7197
|
carries its BUILDER's JS, and the device JS swap (which has to re-seal what
|
|
6987
7198
|
it injects) lands with phase 6 of appandflow/stim#178, so the cache hit is
|
|
6988
7199
|
refused rather than installed with someone else's JavaScript.
|
|
@@ -7197,8 +7408,8 @@ THE POOL: WHICH DEVICE AN ID-LESS \`--device\` PICKS
|
|
|
7197
7408
|
distribution stay out of scope.
|
|
7198
7409
|
|
|
7199
7410
|
\`ios --configuration <name>\` selects the Xcode configuration --
|
|
7200
|
-
\`--configuration Release\` builds a SIMULATOR
|
|
7201
|
-
bundle embedded. It overrides the ios.configuration setting (the app-level
|
|
7411
|
+
for React Native and Expo, \`--configuration Release\` builds a SIMULATOR
|
|
7412
|
+
Release app with the JS bundle embedded. It overrides the ios.configuration setting (the app-level
|
|
7202
7413
|
default); unset, the Debug flow is unchanged. A non-Debug configuration
|
|
7203
7414
|
skips Metro ENTIRELY: no gate, no port wiring, no dev-client deep link (a
|
|
7204
7415
|
plain \`simctl launch\`), and the payload says \`metroPort: null\` --
|
|
@@ -7287,6 +7498,19 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
7287
7498
|
a failed query remains unknown. Existing swap or low free RAM alone is not
|
|
7288
7499
|
enough to diagnose pressure.
|
|
7289
7500
|
|
|
7501
|
+
Doctor, and boot messages under warning or critical pressure, also name any
|
|
7502
|
+
process whose physical footprint is abnormal, read from macOS top (it counts
|
|
7503
|
+
compressed and swapped memory, which ps RSS leaves out, and reads root-owned
|
|
7504
|
+
daemons). Abnormal is at least a quarter of physical memory and 8 GiB, or
|
|
7505
|
+
2 GiB for fseventsd and Watchman, which are normally far smaller. A known
|
|
7506
|
+
safe-to-restart process comes with its command; Stim never runs it:
|
|
7507
|
+
fseventsd sudo killall fseventsd (launchd restarts it;
|
|
7508
|
+
file watchers rescan once)
|
|
7509
|
+
Watchman stim gc --delete --cache watchman
|
|
7510
|
+
Gradle or Kotlin daemon stim gc --delete --cache gradle-daemons
|
|
7511
|
+
Any other process is named with its size only; ask before quitting it.
|
|
7512
|
+
Doctor skips this check when STIM_HOME is set: processes are machine-global.
|
|
7513
|
+
|
|
7290
7514
|
If pressure is elevated, free host memory before retrying. Use \`stim stop\`
|
|
7291
7515
|
only in workspaces you own and have finished using; ask before closing other
|
|
7292
7516
|
agents' simulators or heavy apps. Never quit Device Hub or Simulator.app to
|
|
@@ -7335,7 +7559,9 @@ Pressure checks read free disk on the Stim home, projects and worker root
|
|
|
7335
7559
|
volumes. On macOS the memory signal is the sysctl pressure level, with no
|
|
7336
7560
|
signal if sysctl fails. Other platforms use os.freemem(); macOS never falls
|
|
7337
7561
|
back to it. Memory pressure is recorded only; stopping devices, dev servers
|
|
7338
|
-
and helpers is not automatic.
|
|
7562
|
+
and helpers is not automatic. While the level is warning or critical, the
|
|
7563
|
+
check also names abnormally large processes (guide lifecycle simslim) in
|
|
7564
|
+
status's maintenance block and the maintenance log.
|
|
7339
7565
|
|
|
7340
7566
|
In on mode a pass runs, cheapest to rebuild first:
|
|
7341
7567
|
1. orphaned workspace directories whose project is gone, and registered
|
|
@@ -7716,11 +7942,11 @@ STALE STATUS CACHE ENTRIES
|
|
|
7716
7942
|
if it comes back.
|
|
7717
7943
|
|
|
7718
7944
|
NAMED SERVER PORTS
|
|
7719
|
-
worktree remove
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
registered.
|
|
7723
|
-
stim stop does not touch named ports. See guide ports.
|
|
7945
|
+
worktree remove, gc --delete and automatic maintenance release named
|
|
7946
|
+
allocations without signalling their listeners. gc reports named
|
|
7947
|
+
allocations for missing workspaces; gc --delete releases them. Unmounted or
|
|
7948
|
+
unresolved paths stay registered. Only ports stop stops a named listener,
|
|
7949
|
+
and stim stop does not touch named ports. See guide ports.
|
|
7724
7950
|
|
|
7725
7951
|
ON THE SOURCE CHECKOUT
|
|
7726
7952
|
git cannot remove a repository's main working tree, and deleting the source
|
|
@@ -8232,6 +8458,15 @@ KEYS STIM READS
|
|
|
8232
8458
|
The \`--runtime\` flag overrides this per invocation,
|
|
8233
8459
|
and an uninstalled version refuses the same way,
|
|
8234
8460
|
naming the layer the value came from
|
|
8461
|
+
ios.scheme e.g. "RNTester" -- the shared Xcode scheme to build
|
|
8462
|
+
when the workspace lists several and none matches
|
|
8463
|
+
its name, which otherwise refuses with
|
|
8464
|
+
STIM_NO_SCHEME. The \`--scheme\` flag overrides it
|
|
8465
|
+
per invocation; an \`--eas-profile\` build reads only
|
|
8466
|
+
the flag. Part of the cache key, like the flag, so
|
|
8467
|
+
it also skips the older Expo buildCacheProvider tier,
|
|
8468
|
+
which may key only on the fingerprint. Workspace or
|
|
8469
|
+
committed scope.
|
|
8235
8470
|
ios.configuration e.g. "Release" -- the Xcode configuration to build
|
|
8236
8471
|
(simulator only). Committing
|
|
8237
8472
|
{ "ios": { "configuration": "Release" } } makes every
|
|
@@ -8244,6 +8479,19 @@ KEYS STIM READS
|
|
|
8244
8479
|
"auto" places on an approved Mac when this Mac is full or
|
|
8245
8480
|
busy. Unset runs here; "local" runs here even when a
|
|
8246
8481
|
lower layer says otherwise. See lifecycle hosted-ios.
|
|
8482
|
+
ios.projectPath directory under the app holding a bare React Native
|
|
8483
|
+
app's Xcode project and Podfile; default "ios". "."
|
|
8484
|
+
is the app directory itself (RNTester's layout).
|
|
8485
|
+
Detection, pod install, xcodebuild, the bundle id,
|
|
8486
|
+
doctor, worktree warm and remove, and remote builds
|
|
8487
|
+
all use it. A subdirectory is fingerprinted the way
|
|
8488
|
+
ios/ is; "." hashes every top-level entry except
|
|
8489
|
+
node_modules, Pods, build, android, .stim.json and
|
|
8490
|
+
anything git ignores, so a JS edit misses the build
|
|
8491
|
+
cache instead of risking a stale build. Workspace or committed scope. ios refuses
|
|
8492
|
+
with STIM_BAD_ARG a path that escapes the app or
|
|
8493
|
+
holds no .xcworkspace or .xcodeproj, and any value
|
|
8494
|
+
on an Expo app, whose prebuild writes ios/.
|
|
8247
8495
|
ios.simslimProfile a SimSlim JSON profile under the app directory,
|
|
8248
8496
|
at most 64 KiB. Install the
|
|
8249
8497
|
external tool once with
|
|
@@ -8354,6 +8602,26 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8354
8602
|
and hw.audioOutput for that headless launch. With
|
|
8355
8603
|
androidEmulatorApp "stim-desktop" on macOS, -gpu host
|
|
8356
8604
|
overrides hw.gpu.mode the same way.
|
|
8605
|
+
android.gradleRoot directory holding gradlew and settings.gradle(.kts),
|
|
8606
|
+
relative to the app; default "android". It may sit
|
|
8607
|
+
outside the app but not outside the repository:
|
|
8608
|
+
RNTester in the React Native monorepo uses "../..".
|
|
8609
|
+
android.module the app's Gradle project path; default ":app", e.g.
|
|
8610
|
+
":packages:rn-tester:android:app". Its directory is
|
|
8611
|
+
Gradle's default mapping from the root and must hold
|
|
8612
|
+
a build.gradle(.kts). With either set, Gradle runs
|
|
8613
|
+
from the root with qualified tasks such as
|
|
8614
|
+
<module>:assembleDebug; both values join the cache
|
|
8615
|
+
key and the remote build job, and the root's
|
|
8616
|
+
settings, build script, gradle.properties and
|
|
8617
|
+
gradle/ are fingerprinted. Native sources Gradle
|
|
8618
|
+
builds from elsewhere in the repository are not:
|
|
8619
|
+
list them in fingerprint.config.js extraSources.
|
|
8620
|
+
android refuses with STIM_BAD_ARG a root outside the
|
|
8621
|
+
repository or without settings.gradle, a module
|
|
8622
|
+
without a build script, and either value on an Expo
|
|
8623
|
+
app, whose prebuild writes android/. Workspace or
|
|
8624
|
+
committed scope.
|
|
8357
8625
|
android.variant e.g. "productionDebug" -- the gradle variant to
|
|
8358
8626
|
assemble and install on a project with product
|
|
8359
8627
|
flavors. A repo like tlon-mobile with
|
|
@@ -8369,20 +8637,36 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8369
8637
|
build: embedded JS, no Metro, cache keyed on the
|
|
8370
8638
|
variant, and an APK re-pack on cache hits. See
|
|
8371
8639
|
\`guide lifecycle release\`.
|
|
8640
|
+
android.offloadInputs a native Gradle build-worker declaration:
|
|
8641
|
+
{"complete":true,"ignored":[],"outputs":["build","app/build"]}.
|
|
8642
|
+
complete confirms Git-visible source plus the exact
|
|
8643
|
+
repository-relative ignored files suffice for this
|
|
8644
|
+
build. outputs names generated directories reported
|
|
8645
|
+
by AGP; recorded outputs can survive worker sync.
|
|
8646
|
+
Omitted optional inputs can change build results.
|
|
8647
|
+
Stim artifact caching remains unavailable. See
|
|
8648
|
+
\`stim guide lifecycle native-android\` for input,
|
|
8649
|
+
privacy and worker requirements.
|
|
8372
8650
|
android.keystore the keystore a RE-PACKED release APK is signed with,
|
|
8373
8651
|
absolute or relative to the project root. Unset means
|
|
8374
8652
|
android/app/debug.keystore, which every RN and Expo
|
|
8375
8653
|
android project carries -- the right default, because
|
|
8376
8654
|
what this signs is a local emulator install and never
|
|
8377
8655
|
anything distributed. Set it only when the release
|
|
8378
|
-
variant must be signed with the repo's own key.
|
|
8656
|
+
variant must be signed with the repo's own key. A
|
|
8657
|
+
value in the committed .stim.json must resolve
|
|
8658
|
+
inside the repository (symlinks included); an
|
|
8659
|
+
absolute path outside it needs --scope workspace
|
|
8660
|
+
or repo.
|
|
8379
8661
|
android.keystorePassword
|
|
8380
8662
|
the password for it. apksigner's SCHEMED form is
|
|
8381
8663
|
passed through unchanged (\`env:MY_KS_PASS\`,
|
|
8382
8664
|
\`file:/keys/pw.txt\`, \`stdin\`), which is how a
|
|
8383
8665
|
committed .stim.json avoids carrying a secret; a
|
|
8384
|
-
bare string
|
|
8385
|
-
|
|
8666
|
+
bare string (or \`pass:<password>\`) is the literal
|
|
8667
|
+
password, handed to apksigner through its
|
|
8668
|
+
environment, never its command line. Unset means
|
|
8669
|
+
the debug keystore's fixed "android".
|
|
8386
8670
|
android.remote "proxy", "eas", or a named approved Mac in
|
|
8387
8671
|
remote.machines; "auto" places on an approved Mac when
|
|
8388
8672
|
this Mac is full or busy. Unset runs here; "local"
|
|
@@ -8416,6 +8700,21 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
8416
8700
|
foreground serve process, never Funnel; "auto" never
|
|
8417
8701
|
selects it. The device must share the tailnet. See
|
|
8418
8702
|
\`guide metro\`. Any other value is refused as invalid.
|
|
8703
|
+
metro.command argv array that starts this app's dev server, for an
|
|
8704
|
+
app whose Metro only runs through its own command,
|
|
8705
|
+
e.g. ["node", "../react-native/cli.js", "start",
|
|
8706
|
+
"--port", "{port}"]. No shell; it runs from the app
|
|
8707
|
+
directory, and {port} becomes the reserved Metro port,
|
|
8708
|
+
which the command must pass. It replaces bare-inproc
|
|
8709
|
+
and expo-child with command-child (see \`guide
|
|
8710
|
+
metro\`). Workspace or committed scope.
|
|
8711
|
+
Metro must keep running from inside the app, which
|
|
8712
|
+
is how Stim proves it is this app's. Without Stim's
|
|
8713
|
+
Metro reporter, launches stay UNVERIFIED. start
|
|
8714
|
+
refuses with STIM_BAD_ARG a value that is not such an
|
|
8715
|
+
array or has no {port}, --reset-cache (put the
|
|
8716
|
+
command's own reset flag in metro.command instead),
|
|
8717
|
+
and any use on Windows.
|
|
8419
8718
|
metro.ngrokUrl the stable managed ngrok URL. It requires metro.tunnel
|
|
8420
8719
|
"ngrok" and passes --url to ngrok http. Stim owns
|
|
8421
8720
|
this process.
|
|
@@ -8766,7 +9065,7 @@ simulator sessions on, by MagicDNS name with an optional serve port (default
|
|
|
8766
9065
|
stim doctor --fix
|
|
8767
9066
|
|
|
8768
9067
|
Automatic membership is separate from approval. In Desktop Settings > Remote Macs,
|
|
8769
|
-
use
|
|
9068
|
+
use Builds enabled and Simulators enabled for this Mac or a configured remote.
|
|
8770
9069
|
The equivalent machine settings list the excluded members; both default to []:
|
|
8771
9070
|
|
|
8772
9071
|
stim settings set remote.buildPoolDisabled '["local"]'
|
|
@@ -8949,7 +9248,7 @@ iPhone simulator on the target runtime. Its project-selected CocoaPods must matc
|
|
|
8949
9248
|
the app's Gemfile.lock pins CocoaPods: both Macs then run that version through
|
|
8950
9249
|
bundler, so the machine needs only Bundler on its stim-server PATH and
|
|
8951
9250
|
installs the pinned gems itself on the first build. The comparison selects
|
|
8952
|
-
the app's .ruby-version when installed, with pod install's UTF-8 locale defaults.
|
|
9251
|
+
the app's .ruby-version when installed, and otherwise the GEM_HOME, GEM_PATH and Ruby-related PATH entries of the Mac'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.
|
|
8953
9252
|
For Android its JDK major
|
|
8954
9253
|
version must match, and its Android SDK must hold the NDK, build-tools and
|
|
8955
9254
|
compile platform that the project's React Native version names in
|
|
@@ -9381,7 +9680,7 @@ the same as for any web project: start the dev server, then run stim web.
|
|
|
9381
9680
|
stim logs --errors
|
|
9382
9681
|
stim reload web
|
|
9383
9682
|
stim stop # closes Chrome; stim ports stop web stops Vite
|
|
9384
|
-
stim worktree remove # in a linked worktree: Chrome
|
|
9683
|
+
stim worktree remove # in a linked worktree: Chrome and profile, not Vite
|
|
9385
9684
|
|
|
9386
9685
|
The repo layer is shared by every worktree of the repository, so a new
|
|
9387
9686
|
worktree skips the two settings lines; the certificate and scheme remedies
|
|
@@ -9955,15 +10254,16 @@ const TUTORIAL_REPO = "appandflow/stim-tutorial";
|
|
|
9955
10254
|
const TUTORIAL_BUNDLE_ID = "dev.stim.tutorial";
|
|
9956
10255
|
const TUTORIAL_RESTART_PROMPT = "Restart the Stim tutorial.";
|
|
9957
10256
|
/**
|
|
9958
|
-
* The requests Stim Desktop offers to copy, written the way a developer would ask. {base}, {tour}
|
|
9959
|
-
*
|
|
10257
|
+
* The requests Stim Desktop offers to copy, written the way a developer would ask. {base}, {tour} and {worktrees}
|
|
10258
|
+
* are filled in by Desktop. A step with a section names the guide section that holds its safety rules.
|
|
9960
10259
|
*/
|
|
9961
10260
|
const TUTORIAL_ASKS = {
|
|
9962
|
-
begin: `Clone ${TUTORIAL_REPO} into {base} and
|
|
10261
|
+
begin: `Clone ${TUTORIAL_REPO} into {base} and follow stim guide tutorial run.`,
|
|
10262
|
+
build: "Make the title purple in the Stim tutorial app and check it on the simulator.",
|
|
9963
10263
|
agent: "Open the app on the iOS simulator, take a screenshot and confirm the title color.",
|
|
9964
|
-
machine: "Build the app for iOS on {machine} with stim instead of on this Mac. Do not approve or pair anything.",
|
|
9965
10264
|
finish: "I'm done with these experiments in {base} and don't need the changes. Stop the apps and remove the worktrees {worktrees}, and keep the clone. Follow stim guide tutorial finish.",
|
|
9966
|
-
|
|
10265
|
+
delete: "Remove the Stim tutorial: remove its worktrees and the clone at {base} with stim worktree remove, then delete {base}. Follow stim guide tutorial delete.",
|
|
10266
|
+
share: `Open a pull request to ${TUTORIAL_REPO} with my title color change, with before and after screenshots from the simulator. See stim guide tutorial share.`,
|
|
9967
10267
|
retry: "The first iOS build of the tutorial app in {tour} failed. Find out why and run it on iOS again."
|
|
9968
10268
|
};
|
|
9969
10269
|
const TUTORIAL_STEPS = [
|
|
@@ -9981,7 +10281,7 @@ const TUTORIAL_STEPS = [
|
|
|
9981
10281
|
title: "Make a Change",
|
|
9982
10282
|
who: "you",
|
|
9983
10283
|
optional: false,
|
|
9984
|
-
ask:
|
|
10284
|
+
ask: TUTORIAL_ASKS.build,
|
|
9985
10285
|
section: null,
|
|
9986
10286
|
commands: []
|
|
9987
10287
|
},
|
|
@@ -10037,15 +10337,6 @@ const TUTORIAL_STEPS = [
|
|
|
10037
10337
|
section: null,
|
|
10038
10338
|
commands: []
|
|
10039
10339
|
},
|
|
10040
|
-
{
|
|
10041
|
-
id: "machine",
|
|
10042
|
-
title: "Build on Another Mac",
|
|
10043
|
-
who: "both",
|
|
10044
|
-
optional: true,
|
|
10045
|
-
ask: TUTORIAL_ASKS.machine,
|
|
10046
|
-
section: null,
|
|
10047
|
-
commands: ["cd \"{tour}\"", "stim ios --remote local --remote-build \"{machine}\" --no-build-cache"]
|
|
10048
|
-
},
|
|
10049
10340
|
{
|
|
10050
10341
|
id: "share",
|
|
10051
10342
|
title: "Share Your Finish",
|
|
@@ -10055,11 +10346,16 @@ const TUTORIAL_STEPS = [
|
|
|
10055
10346
|
section: "share",
|
|
10056
10347
|
commands: [
|
|
10057
10348
|
"cd \"{tour}\"",
|
|
10058
|
-
"git commit -am \"
|
|
10059
|
-
"
|
|
10349
|
+
"git commit -am \"<one-line summary>\"",
|
|
10350
|
+
"mkdir -p .expo/screenshots",
|
|
10351
|
+
"git checkout origin/main -- theme.js",
|
|
10352
|
+
"xcrun simctl io {udid} screenshot .expo/screenshots/before.png",
|
|
10353
|
+
"git checkout HEAD -- theme.js",
|
|
10354
|
+
"xcrun simctl io {udid} screenshot .expo/screenshots/after.png",
|
|
10355
|
+
"cp .github/pull_request_template.md .expo/screenshots/body.md",
|
|
10060
10356
|
`gh repo fork ${TUTORIAL_REPO} --remote --remote-name fork`,
|
|
10061
10357
|
"git push -u fork HEAD",
|
|
10062
|
-
`gh pr create --repo ${TUTORIAL_REPO} --
|
|
10358
|
+
`gh pr create --repo ${TUTORIAL_REPO} --title "<one-line summary>" --body-file .expo/screenshots/body.md --attach ".expo/screenshots/before.png#Before" --attach ".expo/screenshots/after.png#After"`
|
|
10063
10359
|
]
|
|
10064
10360
|
},
|
|
10065
10361
|
{
|
|
@@ -10078,6 +10374,23 @@ const TUTORIAL_STEPS = [
|
|
|
10078
10374
|
"stim worktree remove \"{tour}\"",
|
|
10079
10375
|
"stim worktree remove \"{second}\""
|
|
10080
10376
|
]
|
|
10377
|
+
},
|
|
10378
|
+
{
|
|
10379
|
+
id: "delete",
|
|
10380
|
+
title: "Delete the Test App",
|
|
10381
|
+
who: "agent",
|
|
10382
|
+
optional: true,
|
|
10383
|
+
ask: TUTORIAL_ASKS.delete,
|
|
10384
|
+
section: "delete",
|
|
10385
|
+
commands: [
|
|
10386
|
+
"cd \"{base}\"",
|
|
10387
|
+
"grep stimTutorial app.json",
|
|
10388
|
+
"git worktree list",
|
|
10389
|
+
"stim stop",
|
|
10390
|
+
"stim worktree remove \"{base}\"",
|
|
10391
|
+
"cd ..",
|
|
10392
|
+
"rm -rf \"{base}\""
|
|
10393
|
+
]
|
|
10081
10394
|
}
|
|
10082
10395
|
];
|
|
10083
10396
|
//#endregion
|
|
@@ -10090,6 +10403,23 @@ from a worktree of {base}, use stim ios --remote local --remote-build local,
|
|
|
10090
10403
|
even when the user's settings would place the device or the build on another
|
|
10091
10404
|
Mac. Only an explicit request to build on another Mac changes the build, with
|
|
10092
10405
|
stim ios --remote local --remote-build "<machine>"; the device stays here.`;
|
|
10406
|
+
const screenshots = `Before and after screenshots, for a pull request: in each change's worktree,
|
|
10407
|
+
run the app on iOS before you edit anything, open it with agent-device and save
|
|
10408
|
+
the screen, then make the change and, once Fast Refresh applies it, save the
|
|
10409
|
+
same screen on the same device:
|
|
10410
|
+
|
|
10411
|
+
mkdir -p .expo/screenshots
|
|
10412
|
+
export AGENT_DEVICE_STATE_DIR="<agentDevice.stateDir from stim status --json>"
|
|
10413
|
+
agent-device open ${TUTORIAL_BUNDLE_ID} --platform ios --udid <ios.udid>
|
|
10414
|
+
agent-device screenshot .expo/screenshots/before.png
|
|
10415
|
+
(make the change)
|
|
10416
|
+
agent-device screenshot .expo/screenshots/after.png
|
|
10417
|
+
|
|
10418
|
+
Without agent-device, use xcrun simctl io <ios.udid> screenshot
|
|
10419
|
+
.expo/screenshots/before.png, using that worktree's udid from stim status --json,
|
|
10420
|
+
never booted. Take both with the same tool so they match in size. .expo/ is
|
|
10421
|
+
ignored and outside the native fingerprint, so the files are never committed,
|
|
10422
|
+
never change the build, and never block stim worktree remove. Keep each PNG under 1 MB.`;
|
|
10093
10423
|
function commands(id) {
|
|
10094
10424
|
return TUTORIAL_STEPS.find((step) => step.id === id).commands.join("\n");
|
|
10095
10425
|
}
|
|
@@ -10114,7 +10444,7 @@ const TOPICS = {
|
|
|
10114
10444
|
preamble: () => `STIM TUTORIAL
|
|
10115
10445
|
|
|
10116
10446
|
The tutorial clones ${TUTORIAL_REPO}, a tiny Expo app, into {base}; the clone is
|
|
10117
|
-
never run
|
|
10447
|
+
never run, and only the optional delete step removes it. The user then asks for a visual change, and for another
|
|
10118
10448
|
change while the first builds. Each change runs in its own linked worktree of
|
|
10119
10449
|
{base}, so each has its own simulator and Metro port, and the second worktree's
|
|
10120
10450
|
first iOS build reuses the first one's native build. Only the clone, the
|
|
@@ -10126,6 +10456,7 @@ ${local}
|
|
|
10126
10456
|
|
|
10127
10457
|
"Follow stim guide tutorial run" means stim guide tutorial run.
|
|
10128
10458
|
"Follow stim guide tutorial finish" means stim guide tutorial finish.
|
|
10459
|
+
"Follow stim guide tutorial delete" means stim guide tutorial delete.
|
|
10129
10460
|
"${TUTORIAL_RESTART_PROMPT}" means stim guide tutorial restart.
|
|
10130
10461
|
|
|
10131
10462
|
${paths}
|
|
@@ -10139,8 +10470,14 @@ For commands to type yourself, read stim guide tutorial manual.`,
|
|
|
10139
10470
|
|
|
10140
10471
|
${paths}
|
|
10141
10472
|
|
|
10142
|
-
Folder safety:
|
|
10143
|
-
|
|
10473
|
+
Folder safety: if {base} does not exist, clone into it. If it exists, reuse it
|
|
10474
|
+
only when all of these hold: app.json has expo.extra.stimTutorial equal to
|
|
10475
|
+
${TUTORIAL_VERSION}, git remote get-url origin names ${TUTORIAL_REPO}, git
|
|
10476
|
+
rev-parse --show-toplevel equals {base}, and git status --porcelain prints
|
|
10477
|
+
nothing. Then skip the clone, install its dependencies (npm ci), run stim doctor
|
|
10478
|
+
--platform ios there, and continue at PAUSE. For any other existing folder (another
|
|
10479
|
+
repository, local changes, no tutorial marker), stop and ask the user for
|
|
10480
|
+
another folder; never overwrite or delete it. Before cloning, check the parent folder:
|
|
10144
10481
|
create it if absent, then run git -C <parent> rev-parse --is-inside-work-tree.
|
|
10145
10482
|
If that succeeds, the folder is inside another repository: stop and ask the
|
|
10146
10483
|
user for another folder. Never git add in the user's repo.
|
|
@@ -10154,13 +10491,16 @@ ${TUTORIAL_VERSION}. If it does not, report the mismatch and stop; the user need
|
|
|
10154
10491
|
Enter the clone and install its dependencies (npm ci) so the worktrees made for
|
|
10155
10492
|
the changes inherit them, then run stim doctor --platform ios there: it registers
|
|
10156
10493
|
the clone with Stim so Stim Desktop sees it, and builds or boots nothing. Do not
|
|
10157
|
-
run the app: the clone is only the base for the user's changes
|
|
10494
|
+
run the app: the clone is only the base for the user's changes; only the optional
|
|
10495
|
+
delete step removes it.
|
|
10158
10496
|
Report the findings of stim doctor and do not act on them: no SimSlim install, no
|
|
10159
10497
|
--fix, nothing that changes the machine during the tutorial. On npm or network failure, report stderr
|
|
10160
10498
|
and stop.
|
|
10161
10499
|
|
|
10162
10500
|
${local}
|
|
10163
10501
|
|
|
10502
|
+
${screenshots}
|
|
10503
|
+
|
|
10164
10504
|
PAUSE: end the turn. Tell the user to ask for a visual change next, such as
|
|
10165
10505
|
making the title purple, in their own words. Each change runs in a new linked
|
|
10166
10506
|
worktree of {base} (stim guide agent), and its first iOS build takes a few
|
|
@@ -10185,18 +10525,47 @@ changes, which is the consent stim guide agent asks for before worktree remove
|
|
|
10185
10525
|
--force, for exactly those two paths: if the plain remove refuses one of them
|
|
10186
10526
|
only because of uncommitted changes or commits found nowhere else, remove that
|
|
10187
10527
|
worktree with --force. Never use --force on the clone or on any other
|
|
10188
|
-
worktree, and on any other refusal report it and stop. Keep the clone
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
rm -rf "{base}"
|
|
10528
|
+
worktree, and on any other refusal report it and stop. Keep the clone: the
|
|
10529
|
+
optional delete step removes it only when the user asks (stim guide tutorial
|
|
10530
|
+
delete).
|
|
10192
10531
|
|
|
10193
10532
|
If archive is enabled, tell the user the worktrees appear under Archived in
|
|
10194
10533
|
Stim Desktop. With archive disabled, report removal without promising an
|
|
10195
10534
|
archive. Without Desktop, inspect stim status --json for the removed
|
|
10196
10535
|
environments. End the turn.`
|
|
10536
|
+
},
|
|
10537
|
+
delete: {
|
|
10538
|
+
summary: "Remove the tutorial worktrees and the clone through Stim, then delete the folder",
|
|
10539
|
+
body: () => `DELETE THE TEST APP (OPTIONAL)
|
|
10540
|
+
|
|
10541
|
+
${paths}
|
|
10542
|
+
|
|
10543
|
+
Only on the user's explicit request, which the delete prompt is. It covers
|
|
10544
|
+
{base} and its linked worktrees, nothing else. Remove them through Stim so their
|
|
10545
|
+
simulators, Metro ports and Stim records are torn down before the files go.
|
|
10546
|
+
|
|
10547
|
+
First check that {base}/app.json has expo.extra.stimTutorial. If it does not,
|
|
10548
|
+
{base} is not the tutorial clone: report it and stop.
|
|
10549
|
+
|
|
10550
|
+
List the worktrees with git -C "{base}" worktree list. For each linked worktree
|
|
10551
|
+
(every entry except {base} itself), run stim stop from its path, then
|
|
10552
|
+
stim worktree remove "<path>" from {base}. Never use --force here: the delete
|
|
10553
|
+
request does not say which changes the user can lose. If a remove refuses, report
|
|
10554
|
+
it and stop without deleting anything, so the user can decide about that
|
|
10555
|
+
worktree.
|
|
10556
|
+
|
|
10557
|
+
Then, from {base}, run stim stop and stim worktree remove "{base}". On the
|
|
10558
|
+
source checkout it reclaims the Stim environment and leaves the files. If it
|
|
10559
|
+
refuses, report it and stop. Only after it succeeds, from the parent folder,
|
|
10560
|
+
delete the clone:
|
|
10561
|
+
|
|
10562
|
+
rm -rf "{base}"
|
|
10563
|
+
|
|
10564
|
+
Never use --force in this step, and never delete any path other than {base}. Report
|
|
10565
|
+
what you removed and end the turn.`
|
|
10197
10566
|
},
|
|
10198
10567
|
share: {
|
|
10199
|
-
summary: "Optionally open a public pull request with
|
|
10568
|
+
summary: "Optionally open a public pull request with before and after screenshots of the change",
|
|
10200
10569
|
body: () => `SHARE YOUR FINISH (OPTIONAL)
|
|
10201
10570
|
|
|
10202
10571
|
Only on the user's explicit request, which the share prompt is, and before the
|
|
@@ -10204,31 +10573,50 @@ finish step removes the worktrees. The pull request is public: the user's GitHub
|
|
|
10204
10573
|
name and change appear on ${TUTORIAL_REPO}, and a bot replies and closes it. It
|
|
10205
10574
|
needs gh signed in. Never open it unprompted or from any other step.
|
|
10206
10575
|
|
|
10207
|
-
Work from the worktree holding the user's change, {tour}. Commit the
|
|
10208
|
-
there,
|
|
10209
|
-
no write access:
|
|
10576
|
+
Work from the worktree holding the user's change, {tour}. Commit only the
|
|
10577
|
+
change's files there, never .expo/screenshots/. Fork the repository and push the
|
|
10578
|
+
branch to the fork, since the user has no write access:
|
|
10210
10579
|
|
|
10211
10580
|
gh repo fork ${TUTORIAL_REPO} --remote --remote-name fork
|
|
10212
10581
|
git push -u fork HEAD
|
|
10213
10582
|
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10583
|
+
Screenshots: use .expo/screenshots/before.png and .expo/screenshots/after.png from that
|
|
10584
|
+
worktree (stim guide tutorial run). If either is missing, take it now on the same
|
|
10585
|
+
device, that worktree's ios.udid from stim status --json, never booted, with the
|
|
10586
|
+
app running from the branch (run it again first if needed). For
|
|
10587
|
+
a missing before, show the original screen with
|
|
10588
|
+
git checkout origin/main -- <changed files>, capture it once Fast Refresh applies,
|
|
10589
|
+
then restore the change with git checkout HEAD -- <changed files> and capture the
|
|
10590
|
+
after again with the same tool, so both match in size.
|
|
10591
|
+
|
|
10592
|
+
Body: write .expo/screenshots/body.md from the clone's
|
|
10593
|
+
.github/pull_request_template.md, keeping its headings, table and Stim link and
|
|
10594
|
+
dropping its <!-- --> comments. An older clone without the template gets the
|
|
10595
|
+
same parts, in this order:
|
|
10596
|
+
- the first line: one sentence saying what changed and why;
|
|
10597
|
+
- the table, with  and
|
|
10598
|
+
 in its cells;
|
|
10599
|
+
- a How it was verified section, with only what you observed: Device is ios.name from
|
|
10600
|
+
stim status --json; Readiness is the "app reported ready" time stim ios
|
|
10601
|
+
printed; Build is lastBuilds.ios.durationMs and whether lastBuilds.ios.cacheHit
|
|
10602
|
+
was local or remote (a cache hit) or false (a full build), plus, when you know
|
|
10603
|
+
it, whether the second worktree's first iOS build was a cache hit; Logs is the
|
|
10604
|
+
result of stim logs --errors. Drop a line you did not observe rather than
|
|
10605
|
+
guess it;
|
|
10606
|
+
- the closing line: Built and verified with [Stim](https://github.com/appandflow/stim).
|
|
10607
|
+
|
|
10608
|
+
Open the pull request from {tour}:
|
|
10609
|
+
|
|
10610
|
+
gh pr create --repo ${TUTORIAL_REPO} --title "<the one-line summary>" \\
|
|
10611
|
+
--body-file .expo/screenshots/body.md \\
|
|
10612
|
+
--attach ".expo/screenshots/before.png#Before" --attach ".expo/screenshots/after.png#After"
|
|
10613
|
+
|
|
10614
|
+
--attach uploads each image and rewrites the matching ./.expo/screenshots/ reference in
|
|
10615
|
+
the body to the uploaded file, so the table shows both images. gh 2.99.0
|
|
10616
|
+
(2026-09-01) has --attach; confirm with gh pr create --help rather than guessing
|
|
10617
|
+
a version. When gh has no --attach, open the pull request with --body-file alone
|
|
10618
|
+
and tell the user to drag the two images into the table on GitHub. Give the user
|
|
10619
|
+
the pull request URL.`
|
|
10232
10620
|
},
|
|
10233
10621
|
restart: {
|
|
10234
10622
|
summary: "Start the tutorial again without removing anything",
|
|
@@ -10253,8 +10641,7 @@ ${paths}
|
|
|
10253
10641
|
Replace {base}, {tour} and {second} with absolute paths: {base} is the clone,
|
|
10254
10642
|
{tour} the first worktree and {second} the second. For Agent Actions, replace
|
|
10255
10643
|
{stateDir} with agentDevice.stateDir from stim ios or stim status --json and
|
|
10256
|
-
{udid} with the workspace's ios.udid.
|
|
10257
|
-
{machine} with a machine you have already approved, or skip it. Clone with git
|
|
10644
|
+
{udid} with the workspace's ios.udid. Clone with git
|
|
10258
10645
|
clone https://github.com/${TUTORIAL_REPO}.git into a fresh folder outside any
|
|
10259
10646
|
repository. Each change runs in its own worktree of that clone (stim guide
|
|
10260
10647
|
agent); the clone itself is never run. Run each worktree on iOS with
|