stim 1.9.0 → 1.10.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/dist/{android-_y4Ohi5z.mjs → android-787HhP5w.mjs} +119 -29
- package/dist/{android-BPGizezh.mjs → android-DBkeHwpm.mjs} +168 -95
- package/dist/{android-DEgo4oCo.mjs → android-DPov-fv2.mjs} +2 -2
- package/dist/{android-cas-eiExNLf7.mjs → android-cas-CITmIeWY.mjs} +9 -8
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{app-install-Uf3a83Tv.mjs → app-install-CrJ6t_bv.mjs} +2 -2
- package/dist/budget-BP4jZZL4.mjs +620 -0
- package/dist/build-progress-BXx-ZBe4.mjs +512 -0
- package/dist/{cache-manifest-Dg7OnMrp.mjs → cache-manifest-Pubfp8wV.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +16 -16
- package/dist/collector-run.d.mts +5 -1
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-gByVmIjy.mjs → command-output-D5z2_bcF.mjs} +1 -1
- package/dist/{config-Cp9lM3wX.mjs → config-BEq0Qw_a.mjs} +14 -131
- package/dist/{dependency-state-Bq5DcLGn.mjs → dependency-state-r9UesA9a.mjs} +2 -2
- package/dist/{deps-Cip5vUm1.mjs → deps-DP4eWqea.mjs} +3 -3
- package/dist/{detached-entry-KEu0_AXL.mjs → detached-entry-DJHoca49.mjs} +1 -1
- package/dist/{dev-client-HyqISM0h.mjs → dev-client-92U593KT.mjs} +137 -250
- package/dist/{device-D4U-xLty.mjs → device-DhTZe7L4.mjs} +7 -7
- package/dist/{build-lock-DPXPLgTc.mjs → device-lease-CbEaIk7b.mjs} +370 -12
- package/dist/{device-pool-CnTAz8X1.mjs → device-pool-Di8Q-9Ro.mjs} +4 -4
- package/dist/{device-remote-AQ5rQPqr.mjs → device-remote-Dy1jGj3U.mjs} +547 -468
- package/dist/{doctor-B_Ei3bZu.mjs → doctor-B-inAJmt.mjs} +58 -22
- package/dist/{error-diagnostics-Vfz83GCF.mjs → error-diagnostics-xxWKNO3-.mjs} +11 -12
- package/dist/{exec-jIAlgilk.mjs → exec-DK8KaVHK.mjs} +3 -2
- package/dist/{gc-Ckw8RQHi.mjs → gc-ChPFZMRC.mjs} +500 -1114
- package/dist/{guide-BiAbhs1J.mjs → guide-DwmaD_Wa.mjs} +882 -528
- package/dist/guide-status-CWvti2Lg.mjs +125 -0
- package/dist/idle-DpRLp5lj.mjs +157 -0
- package/dist/in-use-CjUluqIX.mjs +245 -0
- package/dist/{ios-BL2NFckr.mjs → ios-B2Fpqvlb.mjs} +25 -59
- package/dist/{ios-BzUJWk1K.mjs → ios-Dd-hYJBh.mjs} +130 -89
- package/dist/{ios-device-DPsSm0v_.mjs → ios-device-BiOsSVzd.mjs} +1 -1
- package/dist/{ios-device-D972i9wf.mjs → ios-device-CtRdEVjx.mjs} +3 -3
- package/dist/{launch-verify-Q_OtW1Rf.mjs → launch-verify-CQS_Kg-C.mjs} +5 -5
- package/dist/{logs-CI9NQSK7.mjs → logs-MARIy6m9.mjs} +9 -9
- package/dist/{metro-DrLHaMn2.mjs → metro-BWLOJ_Wr.mjs} +116 -10
- package/dist/{named-ports-CmLQSIRj.mjs → named-ports-DiTfSz6p.mjs} +4 -4
- package/dist/{ndjson-9uFNRwfe.mjs → ndjson-CDY9IkVC.mjs} +3 -56
- package/dist/{ndjson-DvHSsNU9.d.mts → ndjson-Du3j0AQ9.d.mts} +1 -0
- package/dist/{ownership-D15Op8vN.mjs → ownership-D2xbLVoz.mjs} +2 -3
- package/dist/ownership-DZjdx8Gq.mjs +1180 -0
- package/dist/{ports-BNKoWVWZ.mjs → ports-CLSSFOuz.mjs} +3 -3
- package/dist/{project-DS112DYB.mjs → project-BXZzOABt.mjs} +2 -2
- package/dist/{reload-ZNJUo1pl.mjs → reload-DoETJ3rl.mjs} +9 -10
- package/dist/{server-bare-DWkkcIxV.mjs → server-bare-DVbb7kXH.mjs} +1 -1
- package/dist/{server-expo-B_lctBR3.mjs → server-expo-BvOCeakp.mjs} +4 -4
- package/dist/server-expo-DBVTdult.mjs +2 -0
- package/dist/{settings-D030k0t4.mjs → settings-DOugPlPz.mjs} +16 -428
- package/dist/{settings-BKNh5rl4.mjs → settings-EWYNwe72.mjs} +16 -14
- package/dist/settings.schema.json +75 -0
- package/dist/{simslim-B_LsGLuJ.mjs → simslim-Ca3487H6.mjs} +182 -5
- package/dist/{slot-launch-DU9A-gYw.mjs → slot-launch-C5cg0fmk.mjs} +4 -4
- package/dist/{spawn-claims-Dn3C_N6w.mjs → spawn-claims-CUleC2cM.mjs} +1 -1
- package/dist/{start-DYkkKF0s.mjs → start-F9gv5dcC.mjs} +147 -98
- package/dist/start-VoFsPSes.mjs +2 -0
- package/dist/{state-NcJzMEBF.mjs → state-WGdIbi_d.mjs} +2 -2
- package/dist/{stats-DG9e66Rz.mjs → stats-BAgJaLA4.mjs} +1 -1
- package/dist/{stats-B63-JVAY.mjs → stats-DBYJ5bxL.mjs} +4 -4
- package/dist/{status-S6ehL4Ui.mjs → status-DLCD-o3s.mjs} +63 -231
- package/dist/status-Dr4fRkym.mjs +216 -0
- package/dist/{guide-status-BAMVU0ZA.mjs → stim-installations-CINXy_su.mjs} +3 -124
- package/dist/{stop-BO28HGqF.mjs → stop-Dj4pfmyv.mjs} +22 -18
- package/dist/{stop-T1R-cZRz.mjs → stop-ZvOeTmKb.mjs} +2 -2
- package/dist/supervisor-run.d.mts +11 -2
- package/dist/supervisor-run.mjs +185 -17
- package/dist/{workspace-process-lock-DWaiRD0e.mjs → workspace-process-lock-BXA96myD.mjs} +2 -2
- package/dist/workspaces-BTUyFfkv.mjs +1003 -0
- package/dist/{worktree-DKhSF0UX.mjs → worktree-4aZg2NnI.mjs} +1 -1
- package/dist/{worktree-LGB-UwgG.mjs → worktree-BMS7GeqB.mjs} +40 -122
- package/dist/{worktree-R_cUlE7s.mjs → worktree-BlizKDpZ.mjs} +143 -18
- package/dist/{xcode-BZqyxh3e.mjs → xcode-B2tBkf0m.mjs} +9 -158
- package/package.json +6 -5
- package/dist/build-progress-CVqkfPC6.mjs +0 -188
- package/dist/device-lease-Crs-HkJY.mjs +0 -366
- package/dist/logs-query-Cqma3WIu.mjs +0 -298
- package/dist/ownership-DCQPuWEc.mjs +0 -489
- package/dist/public-http-probe-CyMDrQ3c.mjs +0 -61
- package/dist/server-expo-CeILEu86.mjs +0 -2
- package/dist/sim-pool-KaIsp2Ft.mjs +0 -723
- package/dist/spawn-entry-nCE6m770.mjs +0 -14
- package/dist/workspace-state-DF2gCFhx.mjs +0 -169
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { o as findProjectRoot } from "./project-
|
|
2
|
-
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-
|
|
3
|
-
import { t as guideStatus } from "./guide-status-
|
|
1
|
+
import { o as findProjectRoot } from "./project-BXZzOABt.mjs";
|
|
2
|
+
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-DOugPlPz.mjs";
|
|
3
|
+
import { t as guideStatus } from "./guide-status-CWvti2Lg.mjs";
|
|
4
|
+
import { SETTINGS_SCHEMA_URL } from "@stim-cli/core/state";
|
|
4
5
|
import chalk from "chalk";
|
|
5
|
-
//#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/guide/index.ts
|
|
8
|
+
const TOPICS = {
|
|
9
|
+
agent: {
|
|
10
|
+
summary: "The normal coding-agent workflow, safety rules, and topic routing",
|
|
11
|
+
body: () => `AGENT WORKFLOW
|
|
9
12
|
|
|
10
13
|
Use Stim to run React Native and Expo apps without sharing a Metro port or
|
|
11
14
|
device with another workspace. Prefer plain output: it streams each phase and
|
|
@@ -119,8 +122,10 @@ RULES DURING THE LOOP
|
|
|
119
122
|
- Put runtime .stim.json beside that app's package.json. Monorepo apps do not
|
|
120
123
|
inherit a repository-root runtime file. Keep repository-wide worktree-copy
|
|
121
124
|
rules at the source checkout root; see guide settings for the two scopes.
|
|
122
|
-
-
|
|
123
|
-
|
|
125
|
+
- A debug ios or android run starts this workspace's dev server when it is
|
|
126
|
+
not running, including after it stopped itself for an hour with no use
|
|
127
|
+
(guide metro). Running start first is optional; it lets Metro warm up while
|
|
128
|
+
you do other work.
|
|
124
129
|
- Run ios or android again after a native input changes. A JavaScript-only
|
|
125
130
|
change does not need one.
|
|
126
131
|
- For stale Metro transforms or file-map state, use stim start --reset-cache.
|
|
@@ -211,8 +216,9 @@ Ask the user before these actions:
|
|
|
211
216
|
existing Stim ownership record is deleted only when it has no unique commits.
|
|
212
217
|
- worktree remove --force, because it also discards uncommitted and untracked
|
|
213
218
|
files.
|
|
214
|
-
- gc --delete, because it deletes orphaned resources
|
|
215
|
-
|
|
219
|
+
- gc --delete, because it deletes orphaned resources, removes clean linked
|
|
220
|
+
worktrees whose branch is merged, and clears the build outputs of every
|
|
221
|
+
workspace not in use. Run stim gc --json first and show
|
|
216
222
|
the user the entries its sections list (guide facts gc). gc --delete
|
|
217
223
|
--cache all empties the shared build caches and those outputs instead, and
|
|
218
224
|
gc --delete --cache workspaces clears only the outputs; both inspect
|
|
@@ -224,6 +230,14 @@ Ask the user before these actions:
|
|
|
224
230
|
delete it. An explicit stop shuts down a Stim-owned simulator even when
|
|
225
231
|
another process uses it. It never shuts down an unowned simulator.
|
|
226
232
|
|
|
233
|
+
LEAVE THE MACHINE CLEAN
|
|
234
|
+
|
|
235
|
+
Run stim stop when you pause or finish a task, and stim worktree remove once
|
|
236
|
+
it is merged or abandoned. Never create a simulator or emulator by hand;
|
|
237
|
+
every device comes from Stim. Before starting a new workspace, check stim
|
|
238
|
+
status for an idle workspace to reuse and confirm capacity headroom instead of
|
|
239
|
+
adding another.
|
|
240
|
+
|
|
227
241
|
SANDBOXES
|
|
228
242
|
|
|
229
243
|
An agent harness that sandboxes shell commands usually permits writes inside
|
|
@@ -250,6 +264,7 @@ Read the matching guide before acting in these situations:
|
|
|
250
264
|
| Remote device, custom Metro, or tunnel | stim guide metro |
|
|
251
265
|
| Cache miss, bypass, or fingerprint exclusions | stim guide lifecycle builds |
|
|
252
266
|
| Capacity limits | stim guide lifecycle concurrency |
|
|
267
|
+
| budget lines, reclaimed field, or low disk | stim guide lifecycle budget |
|
|
253
268
|
| Cache statistics from stim stats | stim guide facts stats |
|
|
254
269
|
| Worktree carry-over | stim guide lifecycle options |
|
|
255
270
|
| Doctor finding: seed checkout or cross-volume copy | stim guide lifecycle options |
|
|
@@ -283,6 +298,7 @@ FULL TOPIC LIST
|
|
|
283
298
|
stim guide lifecycle readiness # add optional app readiness logs; no package required
|
|
284
299
|
stim guide lifecycle builds # build optimizations, optional cache warm-up, fingerprints
|
|
285
300
|
stim guide lifecycle concurrency # shared builds, wait timeouts, capacity limits
|
|
301
|
+
stim guide lifecycle budget # disk and memory budgets, automatic reclaim
|
|
286
302
|
stim guide lifecycle options # every flag, Android variants, --device-type, --system-image
|
|
287
303
|
stim guide lifecycle devices # ios --device and android --device on a physical phone
|
|
288
304
|
stim guide lifecycle release # Release configurations and ...Release variants
|
|
@@ -294,12 +310,10 @@ FULL TOPIC LIST
|
|
|
294
310
|
stim guide cleanup # what reclaims a device, and what deletes
|
|
295
311
|
stim guide cleanup collector # an unproven collector pid; why the app on a phone closed
|
|
296
312
|
stim guide settings # configuration files and supported keys`
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
summary: "The --json payloads: `start`, `ios`, `android`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
|
|
302
|
-
preamble: () => `SLOTS
|
|
313
|
+
},
|
|
314
|
+
facts: {
|
|
315
|
+
summary: "The --json payloads: `start`, `ios`, `android`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
|
|
316
|
+
preamble: () => `SLOTS
|
|
303
317
|
Named ios/android runs add slot to their JSON facts. Default-run fields remain
|
|
304
318
|
compatible. status adds a slots array per environment with each named slot's
|
|
305
319
|
ios/android device facts; top-level ios/android still describe default.
|
|
@@ -313,8 +327,15 @@ stdout for \`--json\`. Every other line goes to stderr, so it is always safe
|
|
|
313
327
|
to pipe. \`logs --json\` is the one exception: it is NDJSON, one record per
|
|
314
328
|
line by design (see \`guide logs\`), not this single-payload contract.
|
|
315
329
|
|
|
316
|
-
status's unprovisionedWorktrees lists
|
|
317
|
-
|
|
330
|
+
status's unprovisionedWorktrees lists the linked worktrees with no Stim
|
|
331
|
+
environment in every repository with a registered environment, plus the
|
|
332
|
+
repository status runs from. A worktree counts as having an
|
|
333
|
+
environment when one is registered at it or inside it. Each entry is
|
|
334
|
+
{ path, branch, repository }; repository is the main checkout, or the git
|
|
335
|
+
directory of a bare repository. status reads git's own worktree records and
|
|
336
|
+
never opens the worktree directories, so a worktree under a macOS-protected
|
|
337
|
+
folder such as ~/Documents is listed without a privacy prompt.
|
|
338
|
+
\`worktree warm\` does not create an environment; \`start\`, \`ios\`,
|
|
318
339
|
\`android\` and \`doctor\` register it.
|
|
319
340
|
|
|
320
341
|
status's remoteDevices lists each environment's recorded EAS Simulator
|
|
@@ -335,10 +356,10 @@ is still running.
|
|
|
335
356
|
|
|
336
357
|
Plain status prints one "remote <platform>: EAS session <id> billable" line
|
|
337
358
|
per session, with the preview URL.`,
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
359
|
+
sections: {
|
|
360
|
+
payloads: {
|
|
361
|
+
summary: "every field of the start, ios, android and reload payloads, the error contract, the device rules",
|
|
362
|
+
body: () => ` stim start --json
|
|
342
363
|
|
|
343
364
|
port the Metro port RESERVED for this workspace
|
|
344
365
|
supervisorPid the detached supervisor's pid, or NULL when a dev server was
|
|
@@ -543,6 +564,20 @@ per session, with the preview URL.`,
|
|
|
543
564
|
error, and this field is separate from cacheHit
|
|
544
565
|
logs the workspace log directory
|
|
545
566
|
durationMs wall time for the whole run
|
|
567
|
+
reclaimed present only when the run was over its disk or memory
|
|
568
|
+
budget and reclaimed first (\`start\`, \`ios\` and
|
|
569
|
+
\`android\`, on success and failure alike). One entry per
|
|
570
|
+
step that acted, in order:
|
|
571
|
+
{ step, targets, failures, freedMb }
|
|
572
|
+
step is "idle-devices", "idle-dev-servers",
|
|
573
|
+
"workspace-outputs" or "stale-cache-entries"; targets names
|
|
574
|
+
the devices, workspaces or caches it acted on; freedMb is the
|
|
575
|
+
free disk the step added. See \`guide lifecycle budget\`
|
|
576
|
+
devServer present only when this run started the workspace's dev
|
|
577
|
+
server because none was running (\`ios\` and \`android\`):
|
|
578
|
+
{ started: true, reason }
|
|
579
|
+
reason is "not running" or "stopped (idle)" when the
|
|
580
|
+
supervisor had stopped it after metro.idleStopMinutes
|
|
546
581
|
|
|
547
582
|
stim reload [ios|android] --json
|
|
548
583
|
|
|
@@ -581,6 +616,14 @@ per session, with the preview URL.`,
|
|
|
581
616
|
PATH and the version each reports. resolvedIsOlder is true
|
|
582
617
|
only when that first executable is below the highest version
|
|
583
618
|
available from this invocation or PATH
|
|
619
|
+
budget { budget, volumes, memory, plan } or null when a budget
|
|
620
|
+
setting is invalid. budget echoes minFreeDiskGb,
|
|
621
|
+
hardFloorDiskGb, maxCommittedMemoryGb and maxLiveWorkspaces;
|
|
622
|
+
volumes is { volume, freeGb } for the volumes holding the app
|
|
623
|
+
and $STIM_HOME; memory is { committedGb, liveWorkspaces } or
|
|
624
|
+
null when off; plan lists what the next start, ios or
|
|
625
|
+
android would reclaim, in the \`reclaimed\` shape without
|
|
626
|
+
freedMb, and is empty while under budget
|
|
584
627
|
findings the diagnostic findings; a lower resolved Stim is a
|
|
585
628
|
costs-time finding with a PATH or installation remedy
|
|
586
629
|
|
|
@@ -588,12 +631,14 @@ ON FAILURE
|
|
|
588
631
|
\`start\`, \`ios\` and \`android\` all print the error contract instead,
|
|
589
632
|
still one line on stdout, and exit 1:
|
|
590
633
|
|
|
591
|
-
{ "code": "
|
|
634
|
+
{ "code": "STIM_METRO_TIMEOUT", "message": "...", "remedy": "..." }
|
|
592
635
|
|
|
593
636
|
If a native build returned before the failure, this payload also carries
|
|
594
637
|
\`ccache\` (Android) or \`compilationCache\` (iOS), with the status and
|
|
595
638
|
counters described above. This includes failed builds and later install
|
|
596
639
|
or launch failures. The field is absent when no native build returned.
|
|
640
|
+
\`reclaimed\` is present the same way as on success when the run reclaimed
|
|
641
|
+
before failing, including a STIM_LOW_DISK refusal.
|
|
597
642
|
|
|
598
643
|
Branch on \`code\`, never on the message text. \`guide errors\` enumerates
|
|
599
644
|
every code.
|
|
@@ -615,10 +660,10 @@ RULES
|
|
|
615
660
|
\`android --device\` and
|
|
616
661
|
\`ios --device\`, which use a connected physical device Stim never
|
|
617
662
|
creates, boots, or deletes.`
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
663
|
+
},
|
|
664
|
+
devmenu: {
|
|
665
|
+
summary: "why the Expo dev menu or Tools button is or is not over the app, per platform and device kind",
|
|
666
|
+
body: () => ` EVERY DEV-CLIENT DEEP LINK CARRIES disableOnboarding=1
|
|
622
667
|
INSIDE ITS PROJECT URL
|
|
623
668
|
(\`...?url=http%3A%2F%2Fhost%3Aport%2F%3FdisableOnboarding%3D1&disableFab=1\`),
|
|
624
669
|
and expo-dev-launcher finishes its own dev-menu ONBOARDING
|
|
@@ -709,11 +754,11 @@ RULES
|
|
|
709
754
|
developer trust, has no API at all and is always the user's.
|
|
710
755
|
\`guide errors unverified\` has the signature and the
|
|
711
756
|
full commands.`
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
[--worktrees] --json
|
|
757
|
+
},
|
|
758
|
+
gc: {
|
|
759
|
+
summary: "the gc report payload: mode, sections, reasons, failures, and the gc refusals",
|
|
760
|
+
body: () => ` stim gc [--delete] [--older-than <days>] [--cache <name|all|workspaces>]
|
|
761
|
+
[--worktrees] [--idle <duration>] --json
|
|
717
762
|
|
|
718
763
|
The report the text prints, as one payload. Show the user its sections
|
|
719
764
|
before you run \`gc --delete\`. Under --delete it is the report that run
|
|
@@ -722,16 +767,18 @@ RULES
|
|
|
722
767
|
\`stim gc --json\` again to see what is left.
|
|
723
768
|
|
|
724
769
|
mode "dry-run" | "delete"
|
|
770
|
+
idle the --idle duration in milliseconds, or null
|
|
725
771
|
cacheScope the --cache name, or null. When set, devices, project
|
|
726
772
|
entries and locks were not inspected and their sections
|
|
727
773
|
are empty
|
|
728
774
|
olderThan the --older-than days, or null
|
|
729
775
|
worktreeSweep null without --worktrees; otherwise { olderThan, defaulted }:
|
|
730
776
|
the idle days a linked worktree needs, and whether that is
|
|
731
|
-
the default 7 because --older-than was not given
|
|
777
|
+
the default 7 because --older-than was not given. Merged
|
|
778
|
+
worktrees are swept either way
|
|
732
779
|
actionable true when --delete with the same flags reclaims something
|
|
733
|
-
failures null on a dry run
|
|
734
|
-
not delete
|
|
780
|
+
failures null on a dry run without --idle; otherwise the entries it
|
|
781
|
+
could not delete or shut down
|
|
735
782
|
sections one array per report section, in the text order. Every key
|
|
736
783
|
is present, empty when there is nothing to report:
|
|
737
784
|
deadProjects { path }
|
|
@@ -739,16 +786,31 @@ RULES
|
|
|
739
786
|
orphanedPorts { project, label, port }
|
|
740
787
|
orphanedWorkspaces { dir, projectRoot, bytes } --delete removes the
|
|
741
788
|
whole workspace directory
|
|
742
|
-
linkedWorktrees { path, idleDays,
|
|
743
|
-
|
|
789
|
+
linkedWorktrees { path, idleDays, mergedInto, willRemove,
|
|
790
|
+
reason, detail } mergedInto is the default
|
|
791
|
+
branch HEAD is merged into ("origin/main"),
|
|
792
|
+
or null; detail says why it is removed
|
|
793
|
+
("merged into origin/main", "idle 9d") or kept.
|
|
794
|
+
Without --worktrees, the source checkout and
|
|
795
|
+
roots outside git are left out
|
|
744
796
|
parkedSimulators { udid, name, model, runtime, parkedAt, bytes,
|
|
745
|
-
listed }
|
|
797
|
+
listed } with --older-than, only those parked
|
|
798
|
+
at least that long
|
|
746
799
|
parkedEmulators { name, systemImage, parkedAt, bytes, listed }
|
|
800
|
+
likewise
|
|
747
801
|
orphanedDevices { kind, id, name, bytes, directory }
|
|
802
|
+
unverifiedDevices { kind, id, name, command } stim-* devices Stim
|
|
803
|
+
has no record of creating; never deleted, run
|
|
804
|
+
command yourself
|
|
748
805
|
staleDevices { kind, id, name, project, slot, idleDays,
|
|
749
806
|
bytes } only with --older-than
|
|
750
807
|
staleDeviceRecords { kind, id, project, slot } --delete clears
|
|
751
808
|
the record only
|
|
809
|
+
idleDevices { kind, id, name, project, slot, lastActivityAt,
|
|
810
|
+
idleForMs, buildInProgress } booted owned
|
|
811
|
+
devices whose status activity is "idle";
|
|
812
|
+
--idle shuts down those idle long enough,
|
|
813
|
+
--delete never touches them
|
|
752
814
|
orphanedEasSessions { id, name, platform, status, projectScope }
|
|
753
815
|
staleBuildLocks { path, platform, key, pid, projectRoot }
|
|
754
816
|
staleBuildSlots { path, index, pid, projectRoot }
|
|
@@ -776,13 +838,15 @@ RULES
|
|
|
776
838
|
|
|
777
839
|
reason is null for an entry --delete acts on, and otherwise a stable code
|
|
778
840
|
to branch on; detail is the text line, for the user. Never parse detail.
|
|
841
|
+
A linked worktree's detail is never null.
|
|
779
842
|
workspaceBuildOutputs unresolved | in-use | last-use-unknown |
|
|
780
843
|
recently-used
|
|
781
844
|
linkedWorktrees not-a-worktree | bare-repository |
|
|
782
845
|
source-checkout-unknown | source-checkout |
|
|
783
846
|
locked | in-use | status-unreadable | dirty |
|
|
784
847
|
unpushed-unchecked | unpushed | submodules |
|
|
785
|
-
last-use-unknown |
|
|
848
|
+
not-merged | merge-unknown | last-use-unknown |
|
|
849
|
+
recently-used
|
|
786
850
|
|
|
787
851
|
These print the error contract instead and exit 1:
|
|
788
852
|
|
|
@@ -790,13 +854,49 @@ RULES
|
|
|
790
854
|
|
|
791
855
|
- a --cache name that no shared cache carries; the remedy names the
|
|
792
856
|
caches on this machine
|
|
793
|
-
- --cache together with --worktrees`
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
Each
|
|
857
|
+
- --cache together with --worktrees or --idle`
|
|
858
|
+
},
|
|
859
|
+
status: {
|
|
860
|
+
summary: "the status payload's build and device activity fields: a running build, its estimate, and who drives each device",
|
|
861
|
+
body: () => ` stim status --json
|
|
862
|
+
|
|
863
|
+
Each booted simulator and detected emulator in environments (and in
|
|
864
|
+
slots) carries activity; a shut-down or physical device has none:
|
|
865
|
+
|
|
866
|
+
activity { state, driver?, lastActivityAt?, basis }
|
|
867
|
+
|
|
868
|
+
state "driven" a live claim or driver holds the device now
|
|
869
|
+
"active" no driver, but activity in the last 10 minutes
|
|
870
|
+
"idle" no driver and no activity for 10 minutes or more
|
|
871
|
+
"unknown" a claim or driver check could not be read;
|
|
872
|
+
never treated as idle
|
|
873
|
+
driver { tool, pid, since } for "driven": agent-device, stim device
|
|
874
|
+
lock, xcodebuild, idb, maestro, appium, simctl,
|
|
875
|
+
uiautomator or instrumentation; pid and since are null when
|
|
876
|
+
the claim does not record them
|
|
877
|
+
lastActivityAt the newest of this device's app log records, this
|
|
878
|
+
platform's Metro bundle requests and the workspace's last
|
|
879
|
+
Stim run; absent when none is recorded
|
|
880
|
+
basis the evidence behind state, strongest first:
|
|
881
|
+
agent-device-claim, agent-device-lease agent-device state,
|
|
882
|
+
read only; live only when every recorded process is alive
|
|
883
|
+
with its recorded start time, so a reused pid is dead
|
|
884
|
+
device-lock an unexpired \`stim device lock\` lease
|
|
885
|
+
driver-process a host process naming the UDID or serial
|
|
886
|
+
instrumentation an on-device uiautomator or androidx.test
|
|
887
|
+
process (one adb shell ps per emulator)
|
|
888
|
+
device-log, metro-bundle, workspace-use recency
|
|
889
|
+
|
|
890
|
+
Plain \`stim status\` appends it to each device line: "driven by
|
|
891
|
+
agent-device for 12m", "active", "idle 3h", or "activity unknown (...)".
|
|
892
|
+
\`gc --idle <duration>\` shuts down owned devices idle that long
|
|
893
|
+
(\`guide cleanup gc\`).
|
|
894
|
+
|
|
895
|
+
An environment's metro carries idleStop { reason: "idle", at, idleMinutes }
|
|
896
|
+
when its supervisor stopped the dev server for idleness and nothing serves
|
|
897
|
+
the port since; plain \`status\` prints "stopped (idle)" (\`guide metro\`).
|
|
898
|
+
|
|
899
|
+
Each entry of environments also carries build: null, or the ios or android
|
|
800
900
|
run that holds this workspace's native-run.lock:
|
|
801
901
|
|
|
802
902
|
build { platform, slot, state, phase, startedAt, phaseStartedAt,
|
|
@@ -828,10 +928,10 @@ RULES
|
|
|
828
928
|
|
|
829
929
|
There is no completion fraction: a compile's log volume depends on what
|
|
830
930
|
is already built, so it does not measure progress.`
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
931
|
+
},
|
|
932
|
+
stats: {
|
|
933
|
+
summary: "the stats payload, what counts as a run, hit, miss and failed, timeSavedMs, the heartbeat estimate",
|
|
934
|
+
body: () => ` stim stats --json
|
|
835
935
|
|
|
836
936
|
{ "version": 1,
|
|
837
937
|
"project": { "key": "<path>", "ios": <bucket|null>,
|
|
@@ -885,14 +985,12 @@ HOW A RUN IS COUNTED (\`stats\`)
|
|
|
885
985
|
and a warm run has no long phase to size. That read takes no lock and
|
|
886
986
|
ignores what it cannot read, so nothing about statistics can change a
|
|
887
987
|
run's outcome.`
|
|
988
|
+
}
|
|
888
989
|
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
var metro_default = {
|
|
894
|
-
summary: "The dev server: `stim start`, the supervisor, and starting your own",
|
|
895
|
-
body: () => `THE DEV SERVER
|
|
990
|
+
},
|
|
991
|
+
metro: {
|
|
992
|
+
summary: "The dev server: `stim start`, the supervisor, and starting your own",
|
|
993
|
+
body: () => `THE DEV SERVER
|
|
896
994
|
|
|
897
995
|
stim start
|
|
898
996
|
stim start --remote # prepare Metro for a remote device
|
|
@@ -952,11 +1050,12 @@ REMOTE DEVICE BACKENDS
|
|
|
952
1050
|
requires AGENT_DEVICE_DAEMON_BASE_URL and
|
|
953
1051
|
AGENT_DEVICE_DAEMON_AUTH_TOKEN. Stim creates no remote session for it.
|
|
954
1052
|
|
|
955
|
-
The EAS backend needs eas-cli and an account with EAS
|
|
956
|
-
EAS session is billable. EAS does not inherit the proxy
|
|
957
|
-
tear the session down: \`stop\`, \`worktree remove\`,
|
|
958
|
-
can end sessions that Stim proves it owns.
|
|
959
|
-
recorded session with its preview URL (see
|
|
1053
|
+
The EAS backend needs eas-cli 21.6.0 or later and an account with EAS
|
|
1054
|
+
Simulator access. An EAS session is billable. EAS does not inherit the proxy
|
|
1055
|
+
credentials. Always tear the session down: \`stop\`, \`worktree remove\`,
|
|
1056
|
+
and \`gc --delete\` can end sessions that Stim proves it owns.
|
|
1057
|
+
\`stim status\` lists each recorded session with its preview URL (see
|
|
1058
|
+
\`guide facts\`).
|
|
960
1059
|
|
|
961
1060
|
IDEMPOTENT
|
|
962
1061
|
A healthy dev server on the reserved port is a no-op: \`start\` prints the
|
|
@@ -995,6 +1094,31 @@ WHAT THE SUPERVISOR IS
|
|
|
995
1094
|
the device-log collectors, shuts the owned device down (never deletes it)
|
|
996
1095
|
and frees the port.
|
|
997
1096
|
|
|
1097
|
+
IDLE STOP: the supervisor stops its dev server after metro.idleStopMinutes
|
|
1098
|
+
(default 60; 0 never stops) with no bundle request, no client log record
|
|
1099
|
+
(in-app console logs; for Expo, any stdout line of the Expo CLI) and no Stim
|
|
1100
|
+
command in the workspace (start, ios, android, reload, worktree warm). It
|
|
1101
|
+
checks once a minute. It keeps running while a bundle response is in
|
|
1102
|
+
flight, while a build in the workspace is in progress, while a stim ios,
|
|
1103
|
+
android or stop run holds the workspace's native-run lock, while the
|
|
1104
|
+
workspace holds an unexpired device lease (\`stim device lock\` or a
|
|
1105
|
+
--device run, physical devices included), while one of the workspace's
|
|
1106
|
+
devices is driven or its activity is unknown (\`guide facts status\`; on
|
|
1107
|
+
Windows, which has no ps, the host driver-process probe is skipped), and
|
|
1108
|
+
while a \`stim start\` holds the workspace's metro-start lock. It checks
|
|
1109
|
+
all of this again under the native-run and metro-start locks before it
|
|
1110
|
+
stops the server. A Fast Refresh update is not a bundle request:
|
|
1111
|
+
an open app that only hot-reloads and logs nothing counts as idle, and a
|
|
1112
|
+
connected app alone does not keep the server. It records a
|
|
1113
|
+
supervisor_idle_stopped line in metro.ndjson and devServerStop in
|
|
1114
|
+
state.json, so \`status\` shows "stopped (idle)" rather than a crash.
|
|
1115
|
+
Devices stay booted. The next \`stim start\` starts it again and clears the
|
|
1116
|
+
record, also when it reuses a dev server that another process started. A
|
|
1117
|
+
Debug \`ios\` or \`android\` run starts it the same way and reports
|
|
1118
|
+
devServer.reason "stopped (idle)". The setting
|
|
1119
|
+
is read when \`start\` spawns the supervisor; a value that is not a whole
|
|
1120
|
+
number of 0 or more is refused, as \`stim settings set\` refuses it.
|
|
1121
|
+
|
|
998
1122
|
ENVIRONMENT: the supervisor -- and through it the dev server, including a
|
|
999
1123
|
metro.config.js evaluated inside the expo child -- inherits the environment
|
|
1000
1124
|
of the \`start\` call that SPAWNED it. A later \`start\` that finds a healthy
|
|
@@ -1038,12 +1162,10 @@ STARTING YOUR OWN BUNDLER STILL WORKS
|
|
|
1038
1162
|
\`stop\` leaves an externally started server running and keeps the port
|
|
1039
1163
|
reserved while it answers from this project. Stop it with the tool that
|
|
1040
1164
|
started it.`
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
summary: "Workspace ports for web and API servers that Stim does not manage",
|
|
1046
|
-
body: () => `NAMED SERVER PORTS
|
|
1165
|
+
},
|
|
1166
|
+
ports: {
|
|
1167
|
+
summary: "Workspace ports for web and API servers that Stim does not manage",
|
|
1168
|
+
body: () => `NAMED SERVER PORTS
|
|
1047
1169
|
|
|
1048
1170
|
If Stim is not installed globally, replace stim with npx stim.
|
|
1049
1171
|
|
|
@@ -1095,12 +1217,10 @@ cleanup: versions without ports do not know about named allocations.
|
|
|
1095
1217
|
|
|
1096
1218
|
A shared API does not get a shared reservation. Pass its port by environment
|
|
1097
1219
|
instead of allocating a separate label in every worktree.`
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
summary: "Querying the merged NDJSON timeline, and what --errors means",
|
|
1103
|
-
body: () => `LOGS
|
|
1220
|
+
},
|
|
1221
|
+
logs: {
|
|
1222
|
+
summary: "Querying the merged NDJSON timeline, and what --errors means",
|
|
1223
|
+
body: () => `LOGS
|
|
1104
1224
|
|
|
1105
1225
|
stim logs [filters]
|
|
1106
1226
|
|
|
@@ -1386,41 +1506,40 @@ WHAT WRITES WHAT
|
|
|
1386
1506
|
|
|
1387
1507
|
A collector is killed and replaced on the next \`ios\` / \`android\` run for
|
|
1388
1508
|
that platform, and reaped by \`stop\`.`
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
sectionHint: "<CODE>",
|
|
1395
|
-
preamble: () => `WHAT STIM REFUSES, AND WHY
|
|
1509
|
+
},
|
|
1510
|
+
errors: {
|
|
1511
|
+
summary: "Every refusal Stim can print: an index of codes, and one section for each",
|
|
1512
|
+
sectionHint: "<CODE>",
|
|
1513
|
+
preamble: () => `WHAT STIM REFUSES, AND WHY
|
|
1396
1514
|
|
|
1397
1515
|
Every refusal listed here carries a stable CODE, whichever command prints it.
|
|
1398
1516
|
Branch on the code, never on the message.`,
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1517
|
+
sections: {
|
|
1518
|
+
STIM_EAS_BUILD_MISSING: {
|
|
1519
|
+
summary: "no completed EAS development build matches; build only with session authorization",
|
|
1520
|
+
separator: "--- EAS BUILD CODES (`ios --eas-profile` / `android --eas-profile`) ---",
|
|
1521
|
+
body: () => `STIM_EAS_BUILD_MISSING
|
|
1404
1522
|
No compatible build matches the selected EAS project, profile, platform and
|
|
1405
1523
|
native fingerprint. No device was acquired and no local or cloud build was
|
|
1406
1524
|
started. The remedy prints the exact npx eas-cli build command. Check session
|
|
1407
1525
|
authorization for its potential cost before running it, then retry Stim.
|
|
1408
1526
|
See stim guide lifecycle eas.`
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
EAS CLI is unavailable, a profile/fingerprint/list/download
|
|
1414
|
-
the response could not be validated, or another run holds
|
|
1527
|
+
},
|
|
1528
|
+
STIM_EAS_UNAVAILABLE: {
|
|
1529
|
+
summary: "EAS lookup/download failed, or another run holds the artifact claim",
|
|
1530
|
+
body: () => `STIM_EAS_UNAVAILABLE
|
|
1531
|
+
EAS CLI is unavailable or older than 18.9.0, a profile/fingerprint/list/download
|
|
1532
|
+
operation failed, the response could not be validated, or another run holds
|
|
1533
|
+
the artifact claim.
|
|
1415
1534
|
Follow the printed remedy: inspect the named EAS command or retry once the
|
|
1416
1535
|
holder finishes. This is not proof that a build is missing. No native build
|
|
1417
1536
|
is started. See stim guide lifecycle eas.`
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1537
|
+
},
|
|
1538
|
+
STIM_WORKSPACE_STATE: {
|
|
1539
|
+
summary: "$STIM_HOME/workspaces could not be prepared, or the digest directory belongs to another project",
|
|
1540
|
+
aliases: ["STIM_WORKSPACE_COLLISION"],
|
|
1541
|
+
separator: "--- BUILD-PATH CODES (`stim ios` / `stim android`) ---",
|
|
1542
|
+
body: () => `STIM_WORKSPACE_STATE / STIM_WORKSPACE_COLLISION
|
|
1424
1543
|
Stim could not prepare this project's global workspace directory under
|
|
1425
1544
|
$STIM_HOME/workspaces. Check that STIM_HOME is writable and has free
|
|
1426
1545
|
space. An EPERM on a directory the user CAN write is a sandbox, not a
|
|
@@ -1428,44 +1547,47 @@ Branch on the code, never on the message.`,
|
|
|
1428
1547
|
readable-name-plus-digest directory already has a workspace.json for a
|
|
1429
1548
|
different canonical project path; do not overwrite it until you identify
|
|
1430
1549
|
which workspace owns it.`
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
Nothing that could be proven to be THIS workspace's dev server holds the
|
|
1436
|
-
reserved port -- or no port is reserved at all. The gate fires in about a
|
|
1437
|
-
second, before the device is even booted, rather than after four minutes of
|
|
1438
|
-
compiling an app that could not load a bundle. Run \`stim start\` first.
|
|
1439
|
-
\`--no-metro-check\` overrides it and wires the app to the reservation (or to
|
|
1440
|
-
8081 when there is none). A non-Debug \`ios --configuration\` never emits
|
|
1441
|
-
this: a release-shaped build embeds its JS, so the gate does not run at all.
|
|
1442
|
-
A port held by SOMETHING ELSE reports what: usually a bundler started from
|
|
1443
|
-
the wrong directory (the repo root instead of the app dir in a monorepo), or
|
|
1444
|
-
another repo's Metro. Restart it from inside the project, or free the port
|
|
1445
|
-
and run \`stim start\` to get a fresh reservation.
|
|
1446
|
-
|
|
1550
|
+
},
|
|
1551
|
+
STIM_NO_METRO: {
|
|
1552
|
+
summary: "the recorded launch's port is not this workspace's live dev server (reload)",
|
|
1553
|
+
body: () => `STIM_NO_METRO
|
|
1447
1554
|
Reload requires the recorded launch's port to be this workspace's live
|
|
1448
|
-
Metro. It refuses a missing, changed, unresponsive, or foreign port
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1555
|
+
Metro. It refuses a missing, changed, unresponsive, or foreign port. Run
|
|
1556
|
+
\`stim start\`, or run \`ios\` or \`android\` again.
|
|
1557
|
+
|
|
1558
|
+
\`ios\` and \`android\` do not emit this code. A Debug run with no healthy
|
|
1559
|
+
dev server on the reserved port starts one, as \`stim start\` would, and
|
|
1560
|
+
refuses only when that start fails, with the start's code
|
|
1561
|
+
(STIM_METRO_TIMEOUT, STIM_SUPERVISOR_EXITED, ...). A port held by SOMETHING
|
|
1562
|
+
ELSE, usually a bundler started from the wrong directory or another repo's
|
|
1563
|
+
Metro, gets a fresh reservation.`
|
|
1564
|
+
},
|
|
1565
|
+
STIM_NO_FINGERPRINT: {
|
|
1566
|
+
summary: "@expo/fingerprint produced no hash, so the shared cache cannot be addressed",
|
|
1567
|
+
body: () => `STIM_NO_FINGERPRINT
|
|
1453
1568
|
\`@expo/fingerprint\` produced no hash, so the shared build cache cannot be
|
|
1454
1569
|
addressed. Stim uses its declared @expo/fingerprint dependency directly,
|
|
1455
1570
|
independently of the target project's package graph. This is a refusal
|
|
1456
1571
|
rather than a silent full build because an unaddressable cache means every
|
|
1457
1572
|
workspace on the commit compiles from scratch, forever.`
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
\`expo prebuild\` could not generate the missing native directory
|
|
1463
|
-
extracted output is above the code; the
|
|
1464
|
-
the global workspace logs/build-<platform>.ndjson file
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1573
|
+
},
|
|
1574
|
+
STIM_PREBUILD_FAILED: {
|
|
1575
|
+
summary: "expo prebuild could not generate or regenerate the native directory",
|
|
1576
|
+
body: () => `STIM_PREBUILD_FAILED
|
|
1577
|
+
\`expo prebuild\` could not generate the missing native directory, or
|
|
1578
|
+
regenerate a stale one. The extracted output is above the code; the
|
|
1579
|
+
transcript is in the global workspace logs/build-<platform>.ndjson file.
|
|
1580
|
+
The same code refuses a native directory that the fingerprint leaves out of
|
|
1581
|
+
the cache key while git tracks its files, or when git cannot answer: Stim
|
|
1582
|
+
cannot show those files came from the current app config, and will not
|
|
1583
|
+
delete tracked files with \`expo prebuild --clean\`. Stop excluding the
|
|
1584
|
+
directory from the fingerprint (.fingerprintignore), or gitignore and
|
|
1585
|
+
untrack it so Stim regenerates it. When git itself is failing, fix the
|
|
1586
|
+
checkout first.`
|
|
1587
|
+
},
|
|
1588
|
+
STIM_DEPS_FAILED: {
|
|
1589
|
+
summary: "pod install or gradle sync failed; the bundler ladder and BUNDLE_FROZEN",
|
|
1590
|
+
body: () => `STIM_DEPS_FAILED
|
|
1469
1591
|
\`pod install\` (iOS) or the gradle dependency sync (Android) failed. On iOS
|
|
1470
1592
|
this runs only when Podfile.lock and Pods/Manifest.lock disagree, or Pods is
|
|
1471
1593
|
absent -- which is exactly what a carried worktree produces.
|
|
@@ -1493,10 +1615,10 @@ Branch on the code, never on the message.`,
|
|
|
1493
1615
|
\`yarn install\`, \`bun install\`, \`npm ci\`) or that same pod ladder. The
|
|
1494
1616
|
message names the command, quotes its last lines, and nothing is copied: fix
|
|
1495
1617
|
the source checkout, then warm again.`
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1618
|
+
},
|
|
1619
|
+
STIM_BUILD_FAILED: {
|
|
1620
|
+
summary: "xcodebuild or gradle failed; the two Android APK refusals; a damaged compilation-cache object",
|
|
1621
|
+
body: () => `STIM_BUILD_FAILED
|
|
1500
1622
|
xcodebuild or gradle failed. The EXTRACTED diagnostics are printed (capped),
|
|
1501
1623
|
not the transcript. Read the log path on the next line for the rest.
|
|
1502
1624
|
Two Android refusals share this code without gradle itself failing:
|
|
@@ -1527,10 +1649,10 @@ Branch on the code, never on the message.`,
|
|
|
1527
1649
|
object, and upgrading the CLI does not clear it. Empty that one cache with
|
|
1528
1650
|
\`gc --delete --cache "compilation cache"\`, then build again. The next
|
|
1529
1651
|
build is a cold one.`
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1652
|
+
},
|
|
1653
|
+
STIM_PATH_TOO_LONG: {
|
|
1654
|
+
summary: "Windows only: the project root leaves no room for the NDK object paths ninja must open",
|
|
1655
|
+
body: () => `STIM_PATH_TOO_LONG (android, Windows only)
|
|
1534
1656
|
The NDK's ninja is not long-path aware, so every CMake object path has to
|
|
1535
1657
|
stay under Windows' MAX_PATH. React Native's codegen objects are named
|
|
1536
1658
|
after their mangled absolute source path, so each carries the project root
|
|
@@ -1546,10 +1668,10 @@ Branch on the code, never on the message.`,
|
|
|
1546
1668
|
preflight does not inspect that configured path and may refuse it too.
|
|
1547
1669
|
\`doctor --platform android\` reports the same root as a finding for the
|
|
1548
1670
|
emulator's ABI.`
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1671
|
+
},
|
|
1672
|
+
fallbacks: {
|
|
1673
|
+
summary: "release cache-hit notes that are not codes: swap failure, asset gate, uninstall, device fallbacks",
|
|
1674
|
+
body: () => `FALLBACK NOTES THAT ARE NOT CODES (release cache hits)
|
|
1553
1675
|
On a release cache hit Stim regenerates this workspace's JS bundle into a
|
|
1554
1676
|
COPY of the cached artifact before installing it -- \`ios --configuration
|
|
1555
1677
|
Release\` into a copy of the .app, \`android --variant ...Release\` into a
|
|
@@ -1615,10 +1737,10 @@ Branch on the code, never on the message.`,
|
|
|
1615
1737
|
The same refusal on a FRESHLY BUILT app is a code (STIM_NO_PROFILE,
|
|
1616
1738
|
STIM_PROFILE_MISMATCH, STIM_NO_SIGNING_IDENTITY), not a note: building again
|
|
1617
1739
|
would produce the same app and refuse again.`
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1740
|
+
},
|
|
1741
|
+
STIM_BUILD_WAIT_TIMEOUT: {
|
|
1742
|
+
summary: "waited ~90 minutes for another workspace's build of the same fingerprint",
|
|
1743
|
+
body: () => `STIM_BUILD_WAIT_TIMEOUT
|
|
1622
1744
|
This run was waiting for ANOTHER workspace's build of the same fingerprint
|
|
1623
1745
|
(see \`guide lifecycle concurrency\`), and no artifact arrived within ~90
|
|
1624
1746
|
minutes.
|
|
@@ -1627,10 +1749,10 @@ Branch on the code, never on the message.`,
|
|
|
1627
1749
|
may have failed. The message names the current pid and lock directory:
|
|
1628
1750
|
check the pid, and if it is not really building, remove that directory and
|
|
1629
1751
|
run the command again.`
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1752
|
+
},
|
|
1753
|
+
STIM_CLAIM_REFUSED: {
|
|
1754
|
+
summary: "an ownership claim blocks the operation; inspect its holder before removing an unresolved claim",
|
|
1755
|
+
body: () => `STIM_CLAIM_REFUSED
|
|
1634
1756
|
A build lock records the holder's process IDENTITY, not just its pid, so a
|
|
1635
1757
|
recycled pid reads as a gone builder rather than a live one, and a builder
|
|
1636
1758
|
busy in a long \`simctl\` or gradle call reads as live rather than as stale.
|
|
@@ -1668,10 +1790,10 @@ Branch on the code, never on the message.`,
|
|
|
1668
1790
|
Legacy inline \`deletionClaim\` fields in config.json have no process
|
|
1669
1791
|
identity and require separate manual inspection; \`stim guide lifecycle pool\`
|
|
1670
1792
|
describes their field-only recovery.`
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1793
|
+
},
|
|
1794
|
+
STIM_CLAIM_UNAVAILABLE: {
|
|
1795
|
+
summary: "a process identity or warm claim store is unavailable, so the protected operation refuses",
|
|
1796
|
+
body: () => `STIM_CLAIM_UNAVAILABLE
|
|
1675
1797
|
Every ownership claim records the holder's process identity, captured through
|
|
1676
1798
|
the \`unique-pid\` native module. This code is that capture failing: no
|
|
1677
1799
|
prebuilt binary for this platform and architecture, or the OS refusing to
|
|
@@ -1691,10 +1813,10 @@ Branch on the code, never on the message.`,
|
|
|
1691
1813
|
access to the existing claim store, checking parent permissions, symlink
|
|
1692
1814
|
targets, mount access and sandbox rules, then retry. Do not switch STIM_HOME to evade a claim:
|
|
1693
1815
|
concurrent runs must coordinate through the same store.`
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1816
|
+
},
|
|
1817
|
+
STIM_INSTALL_FAILED: {
|
|
1818
|
+
summary: "simctl, adb, or devicectl refused the artifact; the one signer-conflict retry",
|
|
1819
|
+
body: () => `STIM_INSTALL_FAILED
|
|
1698
1820
|
The artifact built or came from cache, but \`simctl install\` / \`adb install\` /
|
|
1699
1821
|
\`devicectl device install app\` refused it. A signature or architecture
|
|
1700
1822
|
mismatch, or a full device.
|
|
@@ -1712,11 +1834,14 @@ Branch on the code, never on the message.`,
|
|
|
1712
1834
|
installed -- the built APK's applicationId, which on a flavored project is
|
|
1713
1835
|
the flavor's id and not the gradle namespace -- and gives you the
|
|
1714
1836
|
\`adb -s <serial> uninstall <applicationId>\` that clears it. Re-running after
|
|
1715
|
-
that is a cache hit: one install, no build
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1837
|
+
that is a cache hit: one install, no build.
|
|
1838
|
+
On a REMOTE device (\`--remote\`) agent-device refused the upload or install.
|
|
1839
|
+
With \`--remote eas\` the EAS Simulator session stays up and billed; the
|
|
1840
|
+
remedy names it. Rerun to reuse it, or run \`stim stop\` to end it.`
|
|
1841
|
+
},
|
|
1842
|
+
STIM_LAUNCH_FAILED: {
|
|
1843
|
+
summary: "installed but would not start; the developer-trust tap on a phone",
|
|
1844
|
+
body: () => `STIM_LAUNCH_FAILED
|
|
1720
1845
|
Installed, but the app would not start. On Android this usually means no
|
|
1721
1846
|
launchable activity resolved.
|
|
1722
1847
|
On a local iOS simulator, a timed-out launch can mean the simulator cannot
|
|
@@ -1733,26 +1858,28 @@ Branch on the code, never on the message.`,
|
|
|
1733
1858
|
VPN & Device Management, tap the developer profile under DEVELOPER APP, tap
|
|
1734
1859
|
Trust, then run the command again. It is a per-developer-certificate tap, not
|
|
1735
1860
|
a per-build one -- but an uninstall clears it, including the one Stim's own
|
|
1736
|
-
signer-conflict retry performs
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1861
|
+
signer-conflict retry performs.
|
|
1862
|
+
With \`--remote eas\` the remedy names the EAS Simulator session that is
|
|
1863
|
+
still running, as for STIM_INSTALL_FAILED.`
|
|
1864
|
+
},
|
|
1865
|
+
STIM_NO_SCHEME: {
|
|
1866
|
+
summary: "Xcode schemes unavailable or no unambiguous app scheme in ios/",
|
|
1867
|
+
body: () => `STIM_NO_SCHEME
|
|
1741
1868
|
Stim could not list or select an app scheme in ios/. Share the intended app
|
|
1742
1869
|
scheme so xcodebuild can see it. Select an available exact name with
|
|
1743
1870
|
\`stim ios --scheme <name>\`. An unknown explicit name prints available choices.
|
|
1744
1871
|
Without an explicit selector, a workspace
|
|
1745
1872
|
name match wins; otherwise Stim accepts a sole non-test scheme, or a listed
|
|
1746
1873
|
scheme matching app.json. Unmatched ambiguous schemes are refused.`
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1874
|
+
},
|
|
1875
|
+
STIM_NO_PROFILE: {
|
|
1876
|
+
summary: "no or undecodable embedded.mobileprovision; build once from Xcode",
|
|
1877
|
+
separator: "--- iOS SIGNING CODES (`ios --device`, and only there) ---",
|
|
1878
|
+
context: `A simulator build needs no signature, which is why none of these can fire on
|
|
1752
1879
|
the normal path. A device build carries one, and Stim re-seals any bundle it
|
|
1753
1880
|
modifies with the identity the bundle already names -- so it checks, before
|
|
1754
1881
|
spending a build or a bundle, that the check can succeed.`,
|
|
1755
|
-
|
|
1882
|
+
body: () => `STIM_NO_PROFILE
|
|
1756
1883
|
The built or cached .app has no embedded.mobileprovision, or
|
|
1757
1884
|
\`openssl smime\` could not decode the one it has. The first means the build
|
|
1758
1885
|
produced an unsigned app -- almost always a simulator-sliced artifact.
|
|
@@ -1761,14 +1888,14 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
1761
1888
|
profile. Stim will not do that step: registering a device or minting a
|
|
1762
1889
|
profile changes your Apple Developer account, so Stim never passes
|
|
1763
1890
|
-allowProvisioningUpdates.`
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1891
|
+
},
|
|
1892
|
+
STIM_PROFILE_MISMATCH: {
|
|
1893
|
+
summary: "the profile is expired, has no ProvisionedDevices, or does not name this UDID",
|
|
1894
|
+
context: `A simulator build needs no signature, which is why none of these can fire on
|
|
1768
1895
|
the normal path. A device build carries one, and Stim re-seals any bundle it
|
|
1769
1896
|
modifies with the identity the bundle already names -- so it checks, before
|
|
1770
1897
|
spending a build or a bundle, that the check can succeed.`,
|
|
1771
|
-
|
|
1898
|
+
body: () => `STIM_PROFILE_MISMATCH
|
|
1772
1899
|
The profile inside the app cannot admit this phone. Three shapes, and the
|
|
1773
1900
|
message names which one and the profile type it found:
|
|
1774
1901
|
- it expired, or carries no ExpirationDate at all;
|
|
@@ -1782,14 +1909,14 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
1782
1909
|
With --eas-profile, follow the EAS device:create and build commands in the
|
|
1783
1910
|
refusal instead. Registration, signing changes and cloud builds need session
|
|
1784
1911
|
authorization. See stim guide lifecycle eas.`
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1912
|
+
},
|
|
1913
|
+
STIM_NO_SIGNING_IDENTITY: {
|
|
1914
|
+
summary: "no single keychain identity resolves; ios.signingIdentitySha1 for two certificates",
|
|
1915
|
+
context: `A simulator build needs no signature, which is why none of these can fire on
|
|
1789
1916
|
the normal path. A device build carries one, and Stim re-seals any bundle it
|
|
1790
1917
|
modifies with the identity the bundle already names -- so it checks, before
|
|
1791
1918
|
spending a build or a bundle, that the check can succeed.`,
|
|
1792
|
-
|
|
1919
|
+
body: () => `STIM_NO_SIGNING_IDENTITY
|
|
1793
1920
|
No single keychain identity could be resolved to re-seal with. Either
|
|
1794
1921
|
\`security find-identity -v -p codesigning\` lists nothing, or the identity
|
|
1795
1922
|
the artifact's own profile names is absent, or two certificates share that
|
|
@@ -1797,14 +1924,14 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
1797
1924
|
Open Xcode > Settings > Accounts and download your certificates, or unlock
|
|
1798
1925
|
the login keychain with \`security unlock-keychain\`. For the two-certificate
|
|
1799
1926
|
case, set ios.signingIdentitySha1 to the SHA-1 hash beside the one you want.`
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1927
|
+
},
|
|
1928
|
+
STIM_CODESIGN_FAILED: {
|
|
1929
|
+
summary: "codesign failed on the modified copy; the cache entry is untouched and the run builds fresh",
|
|
1930
|
+
context: `A simulator build needs no signature, which is why none of these can fire on
|
|
1804
1931
|
the normal path. A device build carries one, and Stim re-seals any bundle it
|
|
1805
1932
|
modifies with the identity the bundle already names -- so it checks, before
|
|
1806
1933
|
spending a build or a bundle, that the check can succeed.`,
|
|
1807
|
-
|
|
1934
|
+
body: () => `STIM_CODESIGN_FAILED
|
|
1808
1935
|
\`codesign --force --sign\` or \`codesign --verify --strict\` exited non-zero
|
|
1809
1936
|
on the modified copy. The verbatim codesign stderr is quoted, because it is
|
|
1810
1937
|
the answer: a locked login keychain reports errSecInternalComponent, an
|
|
@@ -1812,14 +1939,14 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
1812
1939
|
and confirm exactly one identity matches the name. The cache entry itself is
|
|
1813
1940
|
never modified -- the failure is on a temporary copy, and the run builds
|
|
1814
1941
|
fresh.`
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1942
|
+
},
|
|
1943
|
+
STIM_NO_LAN_ADDRESS: {
|
|
1944
|
+
summary: "the Mac has no non-internal IPv4 interface; a tunnel cannot help a phone",
|
|
1945
|
+
separator: "--- iOS DEVICE DEBUG REACHABILITY CODES (`ios --device` in Debug) ---",
|
|
1946
|
+
context: `A phone does not share the host's loopback and USB carries no reverse forward,
|
|
1820
1947
|
so a Debug run on one is wired to a LAN origin instead of localhost. Both codes
|
|
1821
1948
|
fire BEFORE the build, because a refusal that costs a build is a bad refusal.`,
|
|
1822
|
-
|
|
1949
|
+
body: () => `STIM_NO_LAN_ADDRESS
|
|
1823
1950
|
This Mac reports no non-internal IPv4 interface, so there is no address to
|
|
1824
1951
|
give the phone: it is offline, or on nothing but utun/awdl/bridge. Join a
|
|
1825
1952
|
Wi-Fi or Ethernet network, or connect this Mac by cable, and run again.
|
|
@@ -1828,13 +1955,13 @@ fire BEFORE the build, because a refusal that costs a build is a bad refusal.`,
|
|
|
1828
1955
|
ip.txt is read by RCTBundleURLProvider, which prefixes the scheme. A tunnel
|
|
1829
1956
|
cannot be expressed to a phone, so --device ignores metro.publicUrl,
|
|
1830
1957
|
metro.tunnel and metro.ngrokUrl and says so when one is set.`
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1958
|
+
},
|
|
1959
|
+
STIM_LAN_METRO_UNREACHABLE: {
|
|
1960
|
+
summary: "the LAN origin did not answer as this workspace's Metro; ios.lanHost on a multi-NIC Mac",
|
|
1961
|
+
context: `A phone does not share the host's loopback and USB carries no reverse forward,
|
|
1835
1962
|
so a Debug run on one is wired to a LAN origin instead of localhost. Both codes
|
|
1836
1963
|
fire BEFORE the build, because a refusal that costs a build is a bad refusal.`,
|
|
1837
|
-
|
|
1964
|
+
body: () => `STIM_LAN_METRO_UNREACHABLE
|
|
1838
1965
|
The chosen LAN origin did not answer as THIS workspace's Metro: no answer, a
|
|
1839
1966
|
5xx, or a dev server that is not this one -- the message says which.
|
|
1840
1967
|
\`stim start\` prints the port it reserved. On a Mac with several interfaces
|
|
@@ -1844,12 +1971,12 @@ fire BEFORE the build, because a refusal that costs a build is a bad refusal.`,
|
|
|
1844
1971
|
routes a host connection to its own address over loopback, so the gate passes
|
|
1845
1972
|
through a firewall that will block the phone. That evidence only ever arrives
|
|
1846
1973
|
from the phone's own bundle request, which is what \`launched\` reports.`
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1974
|
+
},
|
|
1975
|
+
unverified: {
|
|
1976
|
+
summary: "launched: \"unverified\" with the Local Network path reason, and the routed recovery",
|
|
1977
|
+
context: `A phone does not share the host's loopback and USB carries no reverse forward,
|
|
1851
1978
|
so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
1852
|
-
|
|
1979
|
+
body: () => `LAUNCH UNVERIFIED, LOCAL NETWORK NOT GRANTED (not a code -- a routed remedy)
|
|
1853
1980
|
An app that has not been granted Local Network reaches nothing on the LAN,
|
|
1854
1981
|
and CFNetwork reports each attempt as NSURLErrorDomain -1009 "The Internet
|
|
1855
1982
|
connection appears to be offline." with the path reason
|
|
@@ -1935,11 +2062,11 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
1935
2062
|
General > VPN & Device Management) is refused to automation by the same gate
|
|
1936
2063
|
that refuses the app, agent-device's own runner included, so its remedy is
|
|
1937
2064
|
"ask the user" and nothing else. An uninstall clears both.`
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
2065
|
+
},
|
|
2066
|
+
STIM_NO_DEVICE: {
|
|
2067
|
+
summary: "no usable phone, or the owned simulator or emulator could not be created or booted",
|
|
2068
|
+
separator: "--- DEVICE AND CAPACITY CODES ---",
|
|
2069
|
+
body: () => `STIM_NO_DEVICE
|
|
1943
2070
|
With \`--device\`, no physical device answered the selection: none connected,
|
|
1944
2071
|
a named serial/UDID that is not connected, several connected with none named
|
|
1945
2072
|
(the refusal lists them), or one that is connected but unusable -- an
|
|
@@ -1996,10 +2123,10 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
1996
2123
|
not silently boot a different one. Reap it (\`worktree remove\`, or
|
|
1997
2124
|
\`gc --delete\`) and run \`stim ios\` again to create the requested model.
|
|
1998
2125
|
That loses the old sim's app state.`
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2126
|
+
},
|
|
2127
|
+
STIM_DEVICE_BUSY: {
|
|
2128
|
+
summary: "another workspace holds the lease on that phone and the wait ran out",
|
|
2129
|
+
body: () => `STIM_DEVICE_BUSY
|
|
2003
2130
|
Only on a \`--device\` run. Another workspace holds the lease on that phone,
|
|
2004
2131
|
and the wait ran out: the message names the holder root, the device, and the
|
|
2005
2132
|
expiry as a clock time and a remaining duration, and \`--json\` adds
|
|
@@ -2013,10 +2140,10 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2013
2140
|
no token left in its \`state.json\` (its workspace directory was recreated).
|
|
2014
2141
|
The remedy for that last one is \`stim device unlock\`, which releases by
|
|
2015
2142
|
holder rather than by token.`
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2143
|
+
},
|
|
2144
|
+
STIM_DEVICE_WIRELESS_FAILED: {
|
|
2145
|
+
summary: "an iPhone paired over Wi-Fi timed out or dropped during install or launch; use the cable",
|
|
2146
|
+
body: () => `STIM_DEVICE_WIRELESS_FAILED
|
|
2020
2147
|
Only on an \`ios --device\` run whose iPhone devicectl reaches over Wi-Fi
|
|
2021
2148
|
(transportType localNetwork). The \`devicectl device install app\` ran past
|
|
2022
2149
|
its 15-minute Wi-Fi bound, the phone did not appear in its own process list
|
|
@@ -2028,10 +2155,10 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2028
2155
|
untrusted host, Developer Mode off, full storage, the developer-trust tap --
|
|
2029
2156
|
keeps STIM_INSTALL_FAILED or STIM_LAUNCH_FAILED and its own remedy, even
|
|
2030
2157
|
when the step also timed out and even during a signer-conflict reinstall.`
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2158
|
+
},
|
|
2159
|
+
STIM_DEVICE_LOST: {
|
|
2160
|
+
summary: "the lease was gone or re-held at the pre-install check; rerun",
|
|
2161
|
+
body: () => `STIM_DEVICE_LOST
|
|
2035
2162
|
Only on a \`--device\` run. The run held a lease, and the raise before the
|
|
2036
2163
|
install found it gone or held under another token -- another workspace took
|
|
2037
2164
|
the device in that window. The message names the new holder and its expiry.
|
|
@@ -2039,10 +2166,10 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2039
2166
|
AFTER the install has started this is not a failure: the app is already on
|
|
2040
2167
|
the phone, so the run prints one warning, continues, and reports
|
|
2041
2168
|
\`lease: null\` in \`--json\`.`
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2169
|
+
},
|
|
2170
|
+
STIM_AT_CAPACITY: {
|
|
2171
|
+
summary: "concurrency.maxDevices reached; a refusal, not a queue",
|
|
2172
|
+
body: () => `STIM_AT_CAPACITY
|
|
2046
2173
|
Only when concurrency.maxDevices is set (it is UNSET by default, so this never
|
|
2047
2174
|
fires unless you opted in). Booting a NEW owned device would exceed the cap:
|
|
2048
2175
|
the machine already has that many Stim-owned devices booted. It is a refusal, not
|
|
@@ -2053,10 +2180,34 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2053
2180
|
\`ios\` on an environment you already have is idempotent. (The build cap
|
|
2054
2181
|
behaves differently: a compile WAITS for a free slot rather than refusing.
|
|
2055
2182
|
See \`guide lifecycle concurrency\`.)`
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2183
|
+
},
|
|
2184
|
+
STIM_LOW_DISK: {
|
|
2185
|
+
summary: "free disk stayed below budget.hardFloorDiskGb after reclaiming",
|
|
2186
|
+
body: () => `STIM_LOW_DISK
|
|
2187
|
+
\`start\`, \`ios\` and \`android\` check free disk on the volumes holding
|
|
2188
|
+
the app and $STIM_HOME before they build or boot anything. Below
|
|
2189
|
+
budget.minFreeDiskGb (20 GB by default) they first reclaim what Stim can
|
|
2190
|
+
prove idle (\`guide lifecycle budget\`). This code means a volume was still
|
|
2191
|
+
below budget.hardFloorDiskGb (5 GB by default) afterwards, so the run
|
|
2192
|
+
stopped instead of filling the disk. Nothing was built or booted.
|
|
2193
|
+
|
|
2194
|
+
The message names the free space and the largest uses it could measure:
|
|
2195
|
+
Stim state, the shared build cache, simulators, Xcode DerivedData and
|
|
2196
|
+
Android emulators. The \`--json\` payload lists what was already reclaimed
|
|
2197
|
+
under \`reclaimed\`. To free more:
|
|
2198
|
+
|
|
2199
|
+
stim gc # what else Stim can reclaim
|
|
2200
|
+
stim gc --delete # clear idle workspace outputs, dead entries
|
|
2201
|
+
stim gc --delete --cache all # empty the shared caches
|
|
2202
|
+
stim gc --delete --worktrees # remove clean, idle worktrees
|
|
2203
|
+
|
|
2204
|
+
Ask before deleting anything outside Stim, such as Xcode DerivedData or
|
|
2205
|
+
simulators Stim did not create. Lowering budget.hardFloorDiskGb (0 never
|
|
2206
|
+
refuses) only removes the protection.`
|
|
2207
|
+
},
|
|
2208
|
+
STIM_BUILD_SLOT_TIMEOUT: {
|
|
2209
|
+
summary: "the maxBuilds wait gave up with every slot held by a running process",
|
|
2210
|
+
body: () => `STIM_BUILD_SLOT_TIMEOUT
|
|
2060
2211
|
Only when concurrency.maxBuilds is set. The build cap does not refuse, it
|
|
2061
2212
|
WAITS -- this code is that wait giving up: ~90 minutes elapsed and every one
|
|
2062
2213
|
of the N slots was still held by a running process, or by a holder Stim could
|
|
@@ -2070,50 +2221,54 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2070
2221
|
the message names the directory: remove the slot of a builder that is not
|
|
2071
2222
|
building, or raise concurrency.maxBuilds
|
|
2072
2223
|
(\`guide lifecycle concurrency\`).`
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2224
|
+
},
|
|
2225
|
+
STIM_NO_REMOTE_SESSION: {
|
|
2226
|
+
summary: "the backend could not use agent-device, or metro.tunnel names an unusable provider",
|
|
2227
|
+
separator: "--- REMOTE-DEVICE CODES (`ios --remote <proxy|eas>` / `android --remote <proxy|eas>`) ---",
|
|
2228
|
+
body: () => `STIM_NO_REMOTE_SESSION
|
|
2078
2229
|
The selected backend could not use agent-device, or metro.tunnel names a
|
|
2079
2230
|
provider or mode this workspace cannot use (e.g. "expo" on a bare RN
|
|
2080
2231
|
project). The remedy line says which. Nothing was created yet.`
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2232
|
+
},
|
|
2233
|
+
STIM_REMOTE_PROXY_CONFIG: {
|
|
2234
|
+
summary: "--remote proxy needs AGENT_DEVICE_DAEMON_BASE_URL and AGENT_DEVICE_DAEMON_AUTH_TOKEN",
|
|
2235
|
+
body: () => `STIM_REMOTE_PROXY_CONFIG
|
|
2085
2236
|
\`--remote proxy\` requires AGENT_DEVICE_DAEMON_BASE_URL and
|
|
2086
2237
|
AGENT_DEVICE_DAEMON_AUTH_TOKEN. These variables provide credentials after
|
|
2087
2238
|
proxy is selected. They never select the backend.`
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
\`--remote eas\` requires eas-cli.
|
|
2239
|
+
},
|
|
2240
|
+
STIM_REMOTE_EAS_UNAVAILABLE: {
|
|
2241
|
+
summary: "--remote eas needs eas-cli 21.6.0 or later",
|
|
2242
|
+
body: () => `STIM_REMOTE_EAS_UNAVAILABLE
|
|
2243
|
+
\`--remote eas\` requires eas-cli 21.6.0 or later, the first release with
|
|
2244
|
+
the \`eas simulator:*\` commands Stim runs. Stim reads \`eas --version\` and
|
|
2245
|
+
refuses before any build or session work when eas-cli is missing, older, or
|
|
2246
|
+
reports no version. Upgrade it (\`npm install --global eas-cli@latest\`, or
|
|
2247
|
+
the project's eas-cli dependency). Proxy environment variables do not change
|
|
2093
2248
|
this selection and are not passed to EAS.`
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2249
|
+
},
|
|
2250
|
+
STIM_REMOTE_PLATFORM_MISMATCH: {
|
|
2251
|
+
summary: "the recorded remote session belongs to the other platform; stop, then rerun",
|
|
2252
|
+
body: () => `STIM_REMOTE_PLATFORM_MISMATCH
|
|
2098
2253
|
This workspace already has a recorded remote session, and it belongs to the
|
|
2099
2254
|
OTHER platform ("Session <id> belongs to android, not ios"). A workspace
|
|
2100
2255
|
holds one remote session, and Stim will not end the recorded one to make
|
|
2101
2256
|
room -- it may be mid-run for whoever started it. Run \`stim stop\` for this
|
|
2102
2257
|
workspace, then re-run with the platform you want. Nothing was created here.`
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2258
|
+
},
|
|
2259
|
+
STIM_REMOTE_SESSION_STATE: {
|
|
2260
|
+
summary: "the EAS session was created but its state could not be recorded, so Stim stopped it",
|
|
2261
|
+
body: () => `STIM_REMOTE_SESSION_STATE
|
|
2107
2262
|
The EAS session was created and is healthy, but recording it in this
|
|
2108
2263
|
workspace's state failed (an unwritable STIM_HOME, a full disk). A session
|
|
2109
2264
|
nothing references is a session nothing will ever stop, so Stim stopped the
|
|
2110
2265
|
one it had just created and removed its ownership claim before reporting:
|
|
2111
2266
|
this code means nothing is running and nothing is still billing. Repair the
|
|
2112
2267
|
state storage the message names, then run the remote command again.`
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2268
|
+
},
|
|
2269
|
+
STIM_REMOTE_SESSION_CLEANUP: {
|
|
2270
|
+
summary: "Stim could not prove an EAS session ended; eas simulator:stop --id",
|
|
2271
|
+
body: () => `STIM_REMOTE_SESSION_CLEANUP
|
|
2117
2272
|
Stim tried to end an EAS session and could not PROVE it ended: \`eas
|
|
2118
2273
|
simulator:stop\` failed, or its output did not confirm the stop, or the
|
|
2119
2274
|
session stopped but its claim in the machine ledger could not be removed.
|
|
@@ -2122,10 +2277,10 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2122
2277
|
\`eas simulator:stop --id <id>\` -- and for a ledger that outlived its
|
|
2123
2278
|
session, the ledger path to repair. The same code covers a recorded session
|
|
2124
2279
|
that could not be verified before replacement: inspect it, then \`stim stop\`.`
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2280
|
+
},
|
|
2281
|
+
STIM_REMOTE_METRO_WRONG: {
|
|
2282
|
+
summary: "the tunnel reaches a Metro that is not this workspace's",
|
|
2283
|
+
body: () => `STIM_REMOTE_METRO_WRONG
|
|
2129
2284
|
The gate that proves a tunnel still reaches THIS workspace's Metro failed --
|
|
2130
2285
|
before a session or a build, whether the tunnel is Expo's own, one Stim
|
|
2131
2286
|
started (metro.tunnel: cloudflared/ngrok/auto), or a named metro.publicUrl.
|
|
@@ -2134,39 +2289,39 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2134
2289
|
port), and it now serves ANOTHER workspace's dev server -- healthy, and
|
|
2135
2290
|
wrong. Re-run \`stim start\` (it prints the port it reserved) and, for a
|
|
2136
2291
|
manual tunnel, rebuild it against that port.`
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2292
|
+
},
|
|
2293
|
+
STIM_REMOTE_METRO_UNREACHABLE: {
|
|
2294
|
+
summary: "a remote start could not create its managed tunnel or tell the device where Metro is",
|
|
2295
|
+
body: () => `STIM_REMOTE_METRO_UNREACHABLE
|
|
2141
2296
|
A remote start could not create its selected managed tunnel, or the device
|
|
2142
2297
|
could not be told where Metro is. Follows the same remedy as
|
|
2143
2298
|
STIM_NO_REMOTE_SESSION's tunnel guidance -- set metro.tunnel, or use
|
|
2144
2299
|
metro.publicUrl for an existing endpoint.`
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2300
|
+
},
|
|
2301
|
+
STIM_RELOAD_AMBIGUOUS: {
|
|
2302
|
+
summary: "both owned apps are live; name the platform",
|
|
2303
|
+
separator: "--- RELOAD CODES (`stim reload [ios|android]`) ---",
|
|
2304
|
+
body: () => `STIM_RELOAD_AMBIGUOUS
|
|
2150
2305
|
Both owned apps are live. Name ios or android; Stim never guesses.`
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2306
|
+
},
|
|
2307
|
+
STIM_RELOAD_RELEASE: {
|
|
2308
|
+
summary: "the live app has embedded JS; run a Debug build first",
|
|
2309
|
+
body: () => `STIM_RELOAD_RELEASE
|
|
2155
2310
|
The live app was launched with embedded JavaScript. Run the platform command
|
|
2156
2311
|
with a Debug configuration or variant first.`
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2312
|
+
},
|
|
2313
|
+
STIM_RELOAD_STOPPED: {
|
|
2314
|
+
summary: "the recorded app is gone, its device is not live and owned, or the process could not be proven",
|
|
2315
|
+
aliases: ["STIM_RELOAD_UNOWNED", "STIM_RELOAD_PROBE_FAILED"],
|
|
2316
|
+
body: () => `STIM_RELOAD_STOPPED / STIM_RELOAD_UNOWNED / STIM_RELOAD_PROBE_FAILED
|
|
2162
2317
|
The recorded app is gone, its exact device is not live and owned by this
|
|
2163
2318
|
workspace, or simctl/adb could not prove the process exists. No launch or
|
|
2164
2319
|
device lifecycle action is taken; follow the printed platform-command or
|
|
2165
2320
|
process-probe remedy.`
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2321
|
+
},
|
|
2322
|
+
STIM_RELOAD_FAILED: {
|
|
2323
|
+
summary: "the reload failed; the remedy differs by shape -- read it before acting",
|
|
2324
|
+
body: () => `STIM_RELOAD_FAILED
|
|
2170
2325
|
The Metro websocket reload did not reach a peer Stim could identify. Two
|
|
2171
2326
|
shapes reach this code and the remedy differs. Read it rather than assuming.
|
|
2172
2327
|
|
|
@@ -2192,27 +2347,27 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2192
2347
|
MORE THAN ONE MATCHING PEER IS NOT A FAILURE. A workspace Metro serves one
|
|
2193
2348
|
app, so several matching peers are that app on several devices. Stim reloads
|
|
2194
2349
|
every one of them and reports the count in the facts as targets.`
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2350
|
+
},
|
|
2351
|
+
STIM_WORKTREE_REMOVAL_IN_PROGRESS: {
|
|
2352
|
+
summary: "a managed remote start found worktree remove holding the lock; wait, then rerun",
|
|
2353
|
+
separator: "--- DEV-SERVER CODES (`stim start`) ---",
|
|
2354
|
+
body: () => `STIM_WORKTREE_REMOVAL_IN_PROGRESS
|
|
2200
2355
|
A managed remote start found that \`stim worktree remove\` owns the
|
|
2201
2356
|
worktree lock. The start did not register the project or create a tunnel.
|
|
2202
2357
|
Wait for removal to finish, then run \`stim start --remote\` again.`
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2358
|
+
},
|
|
2359
|
+
STIM_REMOTE_START_REQUIRED: {
|
|
2360
|
+
summary: "a running server cannot gain a remote tunnel; stop, then start --remote, or metro.publicUrl",
|
|
2361
|
+
body: () => `STIM_REMOTE_START_REQUIRED
|
|
2207
2362
|
A healthy bare or Expo server was started without its required remote
|
|
2208
2363
|
tunnel. A running server cannot gain that option. For a Stim supervisor,
|
|
2209
2364
|
run \`stim stop\`, then \`stim start --remote\`. For an external server,
|
|
2210
2365
|
configure metro.publicUrl or let Stim supervise the server.`
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2366
|
+
},
|
|
2367
|
+
STIM_BARE_DEPS: {
|
|
2368
|
+
summary: "the supervisor cannot host Metro from the project's node_modules; the @stim-cli/metro capture note",
|
|
2369
|
+
aliases: ["STIM_BARE_LOAD", "STIM_BARE_API"],
|
|
2370
|
+
body: () => `STIM_BARE_DEPS / STIM_BARE_LOAD / STIM_BARE_API (bare RN)
|
|
2216
2371
|
The supervisor hosts Metro out of the PROJECT's node_modules, so metro,
|
|
2217
2372
|
@react-native/dev-middleware and @react-native-community/cli-server-api must
|
|
2218
2373
|
be installed there and must match the project's React Native. DEPS = not
|
|
@@ -2224,25 +2379,27 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2224
2379
|
The dev server is serving; only capture is missing, so \`logs\` would report
|
|
2225
2380
|
a quiet timeline for a broken build. Install \`@stim-cli/metro\` as a
|
|
2226
2381
|
devDependency of the project.`
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2382
|
+
},
|
|
2383
|
+
STIM_EXPO_BIN: {
|
|
2384
|
+
summary: "node_modules/.bin/expo is missing; install dependencies",
|
|
2385
|
+
body: () => `STIM_EXPO_BIN (Expo)
|
|
2231
2386
|
node_modules/.bin/expo does not exist. Install the project's dependencies.`
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2387
|
+
},
|
|
2388
|
+
STIM_METRO_TIMEOUT: {
|
|
2389
|
+
summary: "the supervisor is alive but Metro or the tunnel was not ready within the wait; --wait 180",
|
|
2390
|
+
body: () => `STIM_METRO_TIMEOUT
|
|
2236
2391
|
"The dev server did not answer on port <n> within <s>s."
|
|
2237
2392
|
The supervisor is alive, but Metro or its requested Expo tunnel is not ready.
|
|
2238
|
-
\`
|
|
2393
|
+
A Debug \`ios\` or \`android\` run that starts the dev server reports the
|
|
2394
|
+
same refusal after the default 60s; re-running it waits for the same
|
|
2395
|
+
supervisor again, and \`stim start --wait 180\` waits longer. \`start\` has already
|
|
2239
2396
|
printed the last lines of the global workspace logs/supervisor.log above this -- read
|
|
2240
2397
|
them. A cold Metro on a large graph can genuinely need more than the default
|
|
2241
2398
|
60s: re-run with \`--wait 180\`. Otherwise \`stim stop\`, then \`start\`.`
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2399
|
+
},
|
|
2400
|
+
STIM_SUPERVISOR_EXITED: {
|
|
2401
|
+
summary: "the dev server failed outright; the quoted supervisor.log tail is the real error",
|
|
2402
|
+
body: () => `STIM_SUPERVISOR_EXITED
|
|
2246
2403
|
"The supervisor exited (<code|signal>) before the dev server came up"
|
|
2247
2404
|
The dev server failed outright, and the quoted evidence is the real error:
|
|
2248
2405
|
the supervisor.log tail if it wrote one, plus this attempt's error records
|
|
@@ -2257,11 +2414,11 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2257
2414
|
Stim's processes. For a legacy record, stop the server with the tool that
|
|
2258
2415
|
started it before retrying. Never reconstruct ownership from a process
|
|
2259
2416
|
name, port, or wall-clock timestamp.`
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2417
|
+
},
|
|
2418
|
+
STIM_BAD_ARG: {
|
|
2419
|
+
summary: "an argument, setting, directory, flavor, or device name refused before anything starts",
|
|
2420
|
+
aliases: ["STIM_NO_PROJECT"],
|
|
2421
|
+
body: () => `STIM_BAD_ARG / STIM_NO_PROJECT
|
|
2265
2422
|
The command refused before doing anything: an unusable --wait value, a known
|
|
2266
2423
|
setting with the wrong type ("Invalid <key> setting <value>. Expected <shape>."
|
|
2267
2424
|
-- \`guide settings\` names the type each key takes), an invalid
|
|
@@ -2301,11 +2458,11 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2301
2458
|
(\`simctl list runtimes\`, the SDK's system-images directory) runs only when
|
|
2302
2459
|
a name was actually given, and a listing that fails is reported as
|
|
2303
2460
|
STIM_NO_DEVICE naming the tool, never as a crash.`
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2461
|
+
},
|
|
2462
|
+
STIM_LOCK_REFUSED: {
|
|
2463
|
+
summary: "a directory lock is held by a removal, which is never waited out",
|
|
2464
|
+
separator: "--- COORDINATION CODES (any command that shares a resource) ---",
|
|
2465
|
+
body: () => `STIM_LOCK_REFUSED
|
|
2309
2466
|
A directory lock that serialises two commands over the same thing -- this
|
|
2310
2467
|
workspace's managed tunnel, its managed remote worktree, the machine's EAS
|
|
2311
2468
|
project ledger -- is held by a REMOVAL, and a removal is never waited out:
|
|
@@ -2314,10 +2471,10 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2314
2471
|
\`workspace removal\` -- both are \`stim worktree remove\`). Let it finish,
|
|
2315
2472
|
then run the command again. \`start --remote\` reports this same case as
|
|
2316
2473
|
STIM_WORKTREE_REMOVAL_IN_PROGRESS instead.`
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2474
|
+
},
|
|
2475
|
+
STIM_LOCK_TIMEOUT: {
|
|
2476
|
+
summary: "a lock held past the wait; workspace-process and short directory locks",
|
|
2477
|
+
body: () => `STIM_LOCK_TIMEOUT
|
|
2321
2478
|
The same locks, held by an ordinary command that is still running, for
|
|
2322
2479
|
longer than the wait -- 60s by default, 4 minutes for the remote-session and
|
|
2323
2480
|
EAS project locks, and ~90 minutes for the \`worktree warm\` lock, which one
|
|
@@ -2349,11 +2506,11 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2349
2506
|
These paths still time out; verify that no holder is running before removing
|
|
2350
2507
|
only the named directory. Standalone Metro and Expo cache packages use the
|
|
2351
2508
|
same core protocol and do not require the Stim CLI.`
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2509
|
+
},
|
|
2510
|
+
teardown: {
|
|
2511
|
+
summary: "an unmanaged port, an unverified supervisor, and a failed device teardown",
|
|
2512
|
+
separator: "--- TEARDOWN AND WORKSPACE REFUSALS ---",
|
|
2513
|
+
body: () => `"metro refusing to kill port <n>: ... runs from <dir>, outside
|
|
2357
2514
|
<project>" (stop)
|
|
2358
2515
|
Stim only signals processes it launched and whose saved identity still
|
|
2359
2516
|
matches. Stop an externally started server with the tool that started it.
|
|
@@ -2385,10 +2542,10 @@ the supervisor could not be verified" (stop)
|
|
|
2385
2542
|
Stim could not release the owned device and keeps its record for a retry.
|
|
2386
2543
|
\`worktree remove\` exits 1 without removing the worktree while the device is
|
|
2387
2544
|
still tracked. Fix the reported cause and re-run.`
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2545
|
+
},
|
|
2546
|
+
remove: {
|
|
2547
|
+
summary: "worktree remove refused a dirty tree: what it restores itself and what --force discards",
|
|
2548
|
+
body: () => `"Refusing to remove <path>: uncommitted changes / untracked files / commits
|
|
2392
2549
|
not on any remote" (worktree remove)
|
|
2393
2550
|
A native build rewrites tracked files, and Stim now RESTORES the one class
|
|
2394
2551
|
it can prove is not work: when the only dirt left is \`pod install\` churn
|
|
@@ -2408,10 +2565,10 @@ not on any remote" (worktree remove)
|
|
|
2408
2565
|
refusal actually named.
|
|
2409
2566
|
Use --force only when you genuinely intend to discard work; it deletes
|
|
2410
2567
|
uncommitted and untracked files permanently.`
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2568
|
+
},
|
|
2569
|
+
STIM_MAIN_DIRTY: {
|
|
2570
|
+
summary: "warm --refresh will not move a source checkout with local work or an operation in progress",
|
|
2571
|
+
body: () => `STIM_MAIN_DIRTY
|
|
2415
2572
|
\`worktree warm --refresh\` writes to the SOURCE CHECKOUT, and it refuses one
|
|
2416
2573
|
it cannot move: tracked files with uncommitted changes (the refusal names
|
|
2417
2574
|
them), or a rebase or merge in progress. Untracked files are not a reason to
|
|
@@ -2421,28 +2578,28 @@ not on any remote" (worktree remove)
|
|
|
2421
2578
|
or \`git -C <source-checkout> rebase --abort\`. Nothing was installed or
|
|
2422
2579
|
copied. Plain \`stim worktree warm\` does not care: it copies from a dirty
|
|
2423
2580
|
source checkout exactly as it always has.`
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2581
|
+
},
|
|
2582
|
+
STIM_MAIN_DETACHED: {
|
|
2583
|
+
summary: "warm --refresh needs a branch to fast-forward, not a detached HEAD",
|
|
2584
|
+
body: () => `STIM_MAIN_DETACHED
|
|
2428
2585
|
The source checkout's HEAD is detached, so there is no branch to fast-forward
|
|
2429
2586
|
and no upstream to fast-forward it to. Run
|
|
2430
2587
|
\`git -C <source-checkout> checkout <branch>\` and warm again. \`--refresh\`
|
|
2431
2588
|
never picks a branch for you; a checkout whose job is to seed worktrees
|
|
2432
2589
|
should sit on a branch someone chose.`
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2590
|
+
},
|
|
2591
|
+
STIM_MAIN_DIVERGED: {
|
|
2592
|
+
summary: "the source checkout is both ahead of and behind its upstream; warm --refresh will not merge",
|
|
2593
|
+
body: () => `STIM_MAIN_DIVERGED
|
|
2437
2594
|
The source checkout's branch has commits its upstream does not, AND its
|
|
2438
2595
|
upstream has commits it does not. A fast-forward is impossible, and
|
|
2439
2596
|
\`--refresh\` will not merge or reset someone else's checkout to make one:
|
|
2440
2597
|
that decision is yours. Rebase or merge it yourself, then warm again. The
|
|
2441
2598
|
message reports both counts. Nothing was installed or copied.`
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2599
|
+
},
|
|
2600
|
+
STIM_DEPS_INCOMPLETE: {
|
|
2601
|
+
summary: "the last install recorded for the lockfile on disk now did not finish, so warm will not copy it",
|
|
2602
|
+
body: () => `STIM_DEPS_INCOMPLETE
|
|
2446
2603
|
\`worktree warm\` refuses to copy dependencies the source checkout never
|
|
2447
2604
|
finished installing. \`--refresh\` records a COMPLETED install of the lockfile
|
|
2448
2605
|
it read under ~/.stim/warm-installs; an install that failed, or whose process
|
|
@@ -2460,20 +2617,20 @@ not on any remote" (worktree remove)
|
|
|
2460
2617
|
repository before its first \`--refresh\` -- copies as it always has.
|
|
2461
2618
|
In a monorepo the record is keyed on the directory that owns the lockfile,
|
|
2462
2619
|
which is usually the repository root, so every app of it reads the same one.`
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2620
|
+
},
|
|
2621
|
+
warm: {
|
|
2622
|
+
summary: "worktree warm claim storage refusals and recovery",
|
|
2623
|
+
body: () => `Both plain warm and --refresh require an ownership claim.
|
|
2467
2624
|
Permission-denied or read-only claim storage reports STIM_CLAIM_UNAVAILABLE
|
|
2468
2625
|
and names the path. Restore access to the existing claim store and retry.
|
|
2469
2626
|
A non-directory claim ancestor reports STIM_CLAIM_REFUSED and names the
|
|
2470
2627
|
blocking file. Inspect it and use the printed move-aside command to preserve
|
|
2471
2628
|
its contents before retrying. See guide errors STIM_CLAIM_UNAVAILABLE and
|
|
2472
2629
|
guide errors STIM_CLAIM_REFUSED for the recovery details.`
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2630
|
+
},
|
|
2631
|
+
carry: {
|
|
2632
|
+
summary: "worktree warm copy results, lockfile mismatches, and remedies",
|
|
2633
|
+
body: () => `"carry incomplete: ... ignored entries copied, ... kept, ... failed"
|
|
2477
2634
|
(worktree warm)
|
|
2478
2635
|
At least one entry could not be copied. The command exits 1 and names each
|
|
2479
2636
|
failure. Existing entries stay untouched; any files already published remain.
|
|
@@ -2492,9 +2649,21 @@ not on any remote" (worktree remove)
|
|
|
2492
2649
|
Warm copied Pods but the destination has no Podfile.lock. Follow the printed
|
|
2493
2650
|
pod-install command before building.
|
|
2494
2651
|
|
|
2652
|
+
"carry carried [<dir>/]node_modules was installed from a different <lockfile> than ..."
|
|
2653
|
+
The carried node_modules records the lockfile it was installed from (npm
|
|
2654
|
+
node_modules/.package-lock.json, pnpm node_modules/.pnpm/lock.yaml, Yarn
|
|
2655
|
+
node_modules/.yarn-integrity or node_modules/.yarn-state.yml), and it
|
|
2656
|
+
differs from this worktree's lockfile. This fires even when both checkouts
|
|
2657
|
+
share the lockfile, because the source checkout itself was not reinstalled
|
|
2658
|
+
after it changed. Run the printed install command before building;
|
|
2659
|
+
otherwise pod install and native builds resolve the old package versions.
|
|
2660
|
+
A pnpm source checkout installed with --filter or --prod also reads as a
|
|
2661
|
+
mismatch, because pnpm records only what it installed.
|
|
2662
|
+
|
|
2495
2663
|
"carry carried dependencies may be stale: they do not match ..."
|
|
2496
|
-
|
|
2497
|
-
|
|
2664
|
+
node_modules records no install state Stim can read (Bun, or no record),
|
|
2665
|
+
and the source checkout's lockfile differs from this branch's lockfile. Run
|
|
2666
|
+
the printed package-manager command before building. A carry whose lockfile
|
|
2498
2667
|
matches is silent; the warning means a real difference.
|
|
2499
2668
|
|
|
2500
2669
|
If the source checkout has no dependencies to copy, use this project's
|
|
@@ -2502,11 +2671,11 @@ not on any remote" (worktree remove)
|
|
|
2502
2671
|
the app is ready, unless \`--refresh\` installed them in the SOURCE CHECKOUT
|
|
2503
2672
|
first; even then the copy can still carry a lockfile this branch does not
|
|
2504
2673
|
have, which is exactly what these carry warnings report.`
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2674
|
+
},
|
|
2675
|
+
environment: {
|
|
2676
|
+
summary: "npx registry E401/E404, the Node floor, no free Metro port, the reservation race",
|
|
2677
|
+
separator: "--- ENVIRONMENT ---",
|
|
2678
|
+
body: () => `"npm error code E401 / E404" while \`npx\` resolves the stim package
|
|
2510
2679
|
The repo probably pins a private registry in \`.npmrc\`, so \`npx\` looked for
|
|
2511
2680
|
the package there instead of on npm. Use the public registry for this command:
|
|
2512
2681
|
|
|
@@ -2527,10 +2696,10 @@ not on any remote" (worktree remove)
|
|
|
2527
2696
|
"Could not reserve a Metro port after 5 attempts"
|
|
2528
2697
|
Several commands raced for the same ports and each one lost. Nothing is
|
|
2529
2698
|
wrong; retry.`
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2699
|
+
},
|
|
2700
|
+
sandbox: {
|
|
2701
|
+
summary: "running under a sandboxing harness: EPERM under STIM_HOME, CoreSimulatorService, adb",
|
|
2702
|
+
body: () => `RUNNING UNDER A SANDBOX
|
|
2534
2703
|
|
|
2535
2704
|
An agent harness that sandboxes shell commands typically permits writes
|
|
2536
2705
|
inside the project and blocks the rest. Three things Stim needs sit outside
|
|
@@ -2577,10 +2746,10 @@ not on any remote" (worktree remove)
|
|
|
2577
2746
|
|
|
2578
2747
|
A git credential helper is often blocked too. It prints \`failed to store\`
|
|
2579
2748
|
on a fetch that otherwise succeeded, and is safe to ignore.`
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2749
|
+
},
|
|
2750
|
+
STIM_CONFIG_CORRUPT: {
|
|
2751
|
+
summary: "~/.stim/config.json is not a valid JSON object and Stim never resets it",
|
|
2752
|
+
body: () => `STIM_CONFIG_CORRUPT ("Stim config at <path> is not valid JSON",
|
|
2584
2753
|
"... is not a JSON object",
|
|
2585
2754
|
"... has a projects that is not an object",
|
|
2586
2755
|
"... has a projects entry "<key>" that is not an object")
|
|
@@ -2591,23 +2760,21 @@ not on any remote" (worktree remove)
|
|
|
2591
2760
|
resets it for you -- a silent reset would orphan every simulator it names.
|
|
2592
2761
|
Repair the file, or move it aside (\`mv <path> <path>.broken\`) and accept
|
|
2593
2762
|
that the devices it recorded become orphans you delete by hand.`
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2763
|
+
},
|
|
2764
|
+
STIM_RELATIVE_PATH: {
|
|
2765
|
+
summary: "STIM_HOME, STIM_BUILD_CACHE or STIM_METRO_CACHE is set to a relative path",
|
|
2766
|
+
body: () => `STIM_RELATIVE_PATH ("<NAME>=<value> is not an absolute path")
|
|
2598
2767
|
Any command refuses before it reads or writes state. A relative value would
|
|
2599
2768
|
resolve against each process's working directory, so the CLI, Metro and the
|
|
2600
2769
|
Expo build-cache provider would each use a different store. Set the named
|
|
2601
2770
|
variable to an absolute path, or unset it to use the default. Metro and the
|
|
2602
2771
|
cache provider, which cannot refuse, ignore a relative value with a warning.`
|
|
2772
|
+
}
|
|
2603
2773
|
}
|
|
2604
|
-
}
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
const lifecycle = {
|
|
2609
|
-
summary: "The full worktree -> start -> ios/android -> logs -> teardown flow, with sections for builds, devices and flags",
|
|
2610
|
-
preamble: () => `ENVIRONMENT LIFECYCLE
|
|
2774
|
+
},
|
|
2775
|
+
lifecycle: {
|
|
2776
|
+
summary: "The full worktree -> start -> ios/android -> logs -> teardown flow, with sections for builds, devices and flags",
|
|
2777
|
+
preamble: () => `ENVIRONMENT LIFECYCLE
|
|
2611
2778
|
|
|
2612
2779
|
Two workflows share steps 2 through 6.
|
|
2613
2780
|
|
|
@@ -2638,8 +2805,9 @@ a seed belongs to this workflow.
|
|
|
2638
2805
|
deps source /w/main: pnpm-lock.yaml changed -> pnpm install (41s)
|
|
2639
2806
|
pods source /w/main/apps/mobile: ios/Podfile.lock unchanged -> skipped
|
|
2640
2807
|
|
|
2641
|
-
# 2.
|
|
2642
|
-
# verifiably THIS project's, then hands your shell back.
|
|
2808
|
+
# 2. Optional: the dev server, under a detached supervisor. Blocks until it
|
|
2809
|
+
# is verifiably THIS project's, then hands your shell back. Step 3 runs
|
|
2810
|
+
# this same start when the dev server is not running.
|
|
2643
2811
|
stim start
|
|
2644
2812
|
port 8082 (reserved)
|
|
2645
2813
|
supervisor pid 41233
|
|
@@ -2683,10 +2851,17 @@ a seed belongs to this workflow.
|
|
|
2683
2851
|
# unwarmed worktrees with no Stim registry entry. Git-created branches stay.
|
|
2684
2852
|
stim worktree remove
|
|
2685
2853
|
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2854
|
+
A Debug \`ios\` or \`android\` run checks the reserved port before the device
|
|
2855
|
+
or the build. When no healthy dev server of this workspace answers there, it
|
|
2856
|
+
runs the same start as step 2: a dev server started outside Stim is reused, a
|
|
2857
|
+
reservation held by a foreign process moves to a free port, and the budgets
|
|
2858
|
+
apply. The run then reports \`devServer: { started: true, reason }\` in its
|
|
2859
|
+
JSON, with reason "not running" or "stopped (idle)". When that start fails,
|
|
2860
|
+
the run refuses with the start's own code (STIM_METRO_TIMEOUT,
|
|
2861
|
+
STIM_SUPERVISOR_EXITED, ...) before any build work. Release builds and
|
|
2862
|
+
\`--no-metro-check\` neither check nor start the dev server. \`--remote\`
|
|
2863
|
+
starts it the way \`stim start --remote\` does. Step 2 remains useful to warm
|
|
2864
|
+
Metro while other work happens.
|
|
2690
2865
|
|
|
2691
2866
|
Repeat step 3 whenever a NATIVE input changes. A JS-only edit needs nothing --
|
|
2692
2867
|
that is what Fast Refresh over the running dev server is for. \`stim reload\` is
|
|
@@ -2771,7 +2946,7 @@ ANDROID EMULATOR RESTARTS
|
|
|
2771
2946
|
wait windows, diagnostics, and recovery steps.
|
|
2772
2947
|
|
|
2773
2948
|
DESTRUCTIVE COMMANDS -- ask the user first
|
|
2774
|
-
gc --delete deletes orphaned
|
|
2949
|
+
gc --delete deletes orphaned devices Stim created, tens of GB
|
|
2775
2950
|
gc --delete --cache all empties the shared build caches every project uses
|
|
2776
2951
|
gc --delete --cache <name>
|
|
2777
2952
|
empties only the caches that carry <name>
|
|
@@ -2808,10 +2983,10 @@ WAITING FOR A CHANGE
|
|
|
2808
2983
|
the EAS session ledger, adb device arrivals and departures, and simulator
|
|
2809
2984
|
state, and recomputes every 30 seconds as a fallback. Ctrl+C, SIGTERM or
|
|
2810
2985
|
closing its stdout ends it with exit 0. Without --json it reprints the human view on change.`,
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2986
|
+
sections: {
|
|
2987
|
+
eas: {
|
|
2988
|
+
summary: "download a matching EAS development build; explicit profile, costs, cache and miss remedies",
|
|
2989
|
+
body: () => `EAS DEVELOPMENT BUILDS
|
|
2815
2990
|
|
|
2816
2991
|
stim ios --eas-profile ios-simulator
|
|
2817
2992
|
stim android --eas-profile development
|
|
@@ -2883,11 +3058,14 @@ cloud build. Once it completes, retry the same Stim command. No build-on-miss
|
|
|
2883
3058
|
flag exists, and Stim never starts a cloud build or falls back to local
|
|
2884
3059
|
compilation in this mode. Authentication, network, invalid output or download
|
|
2885
3060
|
failures produce STIM_EAS_UNAVAILABLE, with the failed EAS command to inspect.
|
|
3061
|
+
An eas-cli older than 18.9.0 cannot run build:download --build-id; Stim reads
|
|
3062
|
+
eas --version first and refuses with STIM_EAS_UNAVAILABLE and the upgrade
|
|
3063
|
+
command before any EAS lookup. stim doctor reports it in a project with eas.json.
|
|
2886
3064
|
If another run holds the artifact claim, wait for it to finish and retry.`
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
3065
|
+
},
|
|
3066
|
+
readiness: {
|
|
3067
|
+
summary: "implement optional pending/ready app logs, deadlines, errors, and platform isolation",
|
|
3068
|
+
body: () => `OPTIONAL APP READINESS
|
|
2891
3069
|
|
|
2892
3070
|
No package or SDK is needed. This applies to debug ios/android launches with
|
|
2893
3071
|
Metro verification enabled, not release builds or --no-metro-check.
|
|
@@ -2947,10 +3125,10 @@ including when device logs are unavailable, the default check applies.
|
|
|
2947
3125
|
The app declares readiness; Stim does not inspect a rendered frame. This does
|
|
2948
3126
|
not change launched JSON semantics or the need to inspect the expected UI and
|
|
2949
3127
|
stim logs --errors. A reload request does not run this launch check.`
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
3128
|
+
},
|
|
3129
|
+
verification: {
|
|
3130
|
+
summary: "reproduce the affected behavior, verify the change on the reported device, and retain proof",
|
|
3131
|
+
body: () => `VERIFY THE CHANGE
|
|
2954
3132
|
|
|
2955
3133
|
For a UI change or bug fix, decide what observable result would prove the task
|
|
2956
3134
|
is complete. A successful build, a live process, or an empty log query does
|
|
@@ -2980,10 +3158,10 @@ not prove that result.
|
|
|
2980
3158
|
|
|
2981
3159
|
For a change without a UI effect, use the relevant runtime output or test
|
|
2982
3160
|
result as proof instead of requiring an unrelated screenshot.`
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
3161
|
+
},
|
|
3162
|
+
progress: {
|
|
3163
|
+
summary: "phase lines, the label set, heartbeats and their ~ estimate, what warm, start, stop and remove print",
|
|
3164
|
+
body: () => `PROGRESS ON A LONG RUN
|
|
2987
3165
|
Native build progress goes to stderr. In \`--json\` mode, stdout carries only
|
|
2988
3166
|
the result payload. Plain \`start\` also prints progress on stdout. Every
|
|
2989
3167
|
progress line has the same shape -- two spaces, a label padded to eleven
|
|
@@ -2994,8 +3172,8 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
2994
3172
|
The labels are a closed set, and nothing else is ever printed in that
|
|
2995
3173
|
column:
|
|
2996
3174
|
|
|
2997
|
-
branch build cache caches carry
|
|
2998
|
-
deps device
|
|
3175
|
+
branch budget build cache caches carry
|
|
3176
|
+
checkout deps device
|
|
2999
3177
|
devices error failed findings fingerprint gems
|
|
3000
3178
|
install installs ip.txt lan launch lease
|
|
3001
3179
|
lock log
|
|
@@ -3077,6 +3255,23 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3077
3255
|
device shut down stim-e2e-2
|
|
3078
3256
|
port released 8084
|
|
3079
3257
|
|
|
3258
|
+
\`stop\` verifies the outcome instead of trusting that the shutdown command
|
|
3259
|
+
ran: for a simulator it waits for the Shutdown state the same way park does
|
|
3260
|
+
(\`guide lifecycle pool\`), and for an emulator it waits for the AVD's
|
|
3261
|
+
process lock to clear. A device that never gets there is reported as
|
|
3262
|
+
FAILED, not shut down, and the run's exit code reflects it; \`--json\`
|
|
3263
|
+
carries the same outcome in \`device.<platform>.status\` ("failed") plus a
|
|
3264
|
+
\`remedy\` field naming the manual command and \`stim gc --delete\` as the
|
|
3265
|
+
fallback:
|
|
3266
|
+
|
|
3267
|
+
device failed to shut down stim-e2e-2: simulator 9C1F.. is still
|
|
3268
|
+
Booted after 2 shutdown attempts and 30s of waiting
|
|
3269
|
+
check it with \`xcrun simctl list devices\`, then \`xcrun
|
|
3270
|
+
simctl shutdown 9C1F..\` yourself -- if it will not respond,
|
|
3271
|
+
\`stim gc --delete\` reclaims it
|
|
3272
|
+
|
|
3273
|
+
\`stop\` still never deletes the device itself, even on this failure path.
|
|
3274
|
+
|
|
3080
3275
|
\`worktree remove\` reports itself the same way: the branch decision, the
|
|
3081
3276
|
owned device, any released device lease, and this workspace's own state
|
|
3082
3277
|
directory, each on its own line. Nothing prints on stdout; even the removed
|
|
@@ -3103,29 +3298,32 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3103
3298
|
until it returns; the next heartbeat then lands on the grid, which is why an
|
|
3104
3299
|
elapsed value can jump. Read the phase lines, not the wall clock, before
|
|
3105
3300
|
killing a run.`
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3301
|
+
},
|
|
3302
|
+
pool: {
|
|
3303
|
+
summary: "parked and adopted simulators: what park and adoption clear or keep, the model and runtime match",
|
|
3304
|
+
body: () => ` THE SIMULATOR POOL
|
|
3110
3305
|
\`worktree remove\` PARKS this workspace's owned simulator instead of
|
|
3111
3306
|
deleting it, and the next workspace that wants the same model and runtime
|
|
3112
|
-
ADOPTS it.
|
|
3113
|
-
created one costs about 30s, and \`simctl erase\` puts most of that back, so
|
|
3114
|
-
a parked simulator keeps its app installed and is cleaned in pieces:
|
|
3307
|
+
ADOPTS it. Adoption reuses the simulator but not its contents:
|
|
3115
3308
|
|
|
3116
|
-
at park shut down,
|
|
3117
|
-
|
|
3118
|
-
|
|
3309
|
+
at park shut down, \`simctl erase\` (apps, app data, keychain,
|
|
3310
|
+
privacy grants, pasteboard, photos, settings), renamed
|
|
3311
|
+
\`stim-parked (<model> <runtime>) <4 hex>\`
|
|
3119
3312
|
at adoption renamed for the adopting workspace, then, inside the boot
|
|
3120
3313
|
the run pays anyway, \`simctl privacy reset all\` and
|
|
3121
|
-
\`simctl keychain reset\`; at install,
|
|
3122
|
-
|
|
3314
|
+
\`simctl keychain reset\`; at install, any other app is
|
|
3315
|
+
uninstalled
|
|
3123
3316
|
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3317
|
+
An erased simulator takes about 18 MB on disk instead of the gigabytes a used
|
|
3318
|
+
one holds. Its first boot after the erase takes about 15s instead of a warm
|
|
3319
|
+
boot's few seconds, and the app is always installed again. A SimSlim
|
|
3320
|
+
profile survives the erase.
|
|
3321
|
+
|
|
3322
|
+
Park erases only a simulator that reports Shutdown. It waits up to 15s for
|
|
3323
|
+
the shutdown to settle, retries the shutdown once, and waits up to 15s more.
|
|
3324
|
+
A simulator that is still booted after that is deleted instead, and
|
|
3325
|
+
\`worktree remove\` prints
|
|
3326
|
+
\`could not park <name>: ... -- deleted it instead\`.
|
|
3129
3327
|
|
|
3130
3328
|
Adoption matches the device type AND the runtime EXACTLY: a ticket that asks
|
|
3131
3329
|
for an iPad never gets an iPhone, and a request for iOS 18.5 never gets 26.5.
|
|
@@ -3133,8 +3331,7 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3133
3331
|
parked simulators on the old runtime are never adopted; they leave by
|
|
3134
3332
|
eviction or \`gc --delete\`.
|
|
3135
3333
|
|
|
3136
|
-
The pool targets at most \`pool.iosParkedMax\` simulators (default 3
|
|
3137
|
-
2.5 GB each). Past that the oldest parked one is deleted:
|
|
3334
|
+
The pool targets at most \`pool.iosParkedMax\` simulators (default 3). Past that the oldest parked one is deleted:
|
|
3138
3335
|
|
|
3139
3336
|
device parked stim-parked (iPhone 17 26.5) 9c1f (9C1F..)
|
|
3140
3337
|
device deleted stim-parked (iPhone 17 26.5) 4b02 (pool over 3)
|
|
@@ -3161,9 +3358,10 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3161
3358
|
|
|
3162
3359
|
and an adopting run says so where a plain boot would say \`booted\`:
|
|
3163
3360
|
|
|
3164
|
-
device stim-app-412 (iPhone 17 26.5) (9C1F..) adopted (
|
|
3361
|
+
device stim-app-412 (iPhone 17 26.5) (9C1F..) adopted (17s)
|
|
3165
3362
|
|
|
3166
|
-
That time includes the
|
|
3363
|
+
That time includes the first boot after the erase and the two resets, so it
|
|
3364
|
+
runs longer than a plain boot.
|
|
3167
3365
|
\`stim status\` prints one line while the pool is not empty:
|
|
3168
3366
|
|
|
3169
3367
|
pool: 2 parked iOS simulators (max 3)
|
|
@@ -3171,10 +3369,13 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3171
3369
|
\`stim gc\` reports the pool, and \`stim gc --delete\` empties every entry
|
|
3172
3370
|
it can re-verify:
|
|
3173
3371
|
|
|
3174
|
-
Parked simulators (2,
|
|
3175
|
-
ios stim-parked (iPhone 17 26.5) 9c1f (9C1F..) iPhone 17 26.5 parked 3d ago
|
|
3372
|
+
Parked simulators (2, 36 MB):
|
|
3373
|
+
ios stim-parked (iPhone 17 26.5) 9c1f (9C1F..) iPhone 17 26.5 parked 3d ago 18 MB
|
|
3176
3374
|
--delete attempts every parked simulator and keeps failures.
|
|
3177
3375
|
|
|
3376
|
+
\`gc --older-than <days>\` reports and deletes only the devices parked at
|
|
3377
|
+
least that long; one parked at an unknown time stays.
|
|
3378
|
+
|
|
3178
3379
|
If simulator listing or deletion fails, \`gc --delete\` reports the failure
|
|
3179
3380
|
and keeps that entry. It never turns an unverified absence into a dropped
|
|
3180
3381
|
ownership record.
|
|
@@ -3190,12 +3391,15 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3190
3391
|
\`pool.androidParkedMax\` (default 3) or STIM_POOL_ANDROID_PARKED_MAX.
|
|
3191
3392
|
A redirected STIM_HOME disables parking unless that environment override
|
|
3192
3393
|
is set. Zero disables parking and adoption. \`stop\` keeps the assignment;
|
|
3193
|
-
\`worktree remove\` parks eligible AVDs, and \`gc --delete\` empties the pool
|
|
3394
|
+
\`worktree remove\` parks eligible AVDs, and \`gc --delete\` empties the pool
|
|
3395
|
+
(with --older-than, only the AVDs parked that long).
|
|
3194
3396
|
|
|
3195
3397
|
Adoption matches the system image, data partition size, and the creation
|
|
3196
3398
|
settings from android.avdConfig / android.avdConfigFile. The AVD keeps its
|
|
3197
|
-
original stim-<label> name
|
|
3198
|
-
|
|
3399
|
+
original stim-<label> name. Parking wipes its user data, cache and
|
|
3400
|
+
encryption-key images and its snapshots, the files the emulator recreates
|
|
3401
|
+
on the next boot, so a parked AVD takes a few MB and adoption pays a cold
|
|
3402
|
+
boot (about 20s) and a fresh install.
|
|
3199
3403
|
Incompatible AVDs stay parked until eviction or GC. AVDs created by older
|
|
3200
3404
|
versions without a recorded creation configuration are deleted at removal.
|
|
3201
3405
|
|
|
@@ -3211,9 +3415,10 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3211
3415
|
manually clearing a claim, and keep the AVD data while its process state
|
|
3212
3416
|
cannot be verified.
|
|
3213
3417
|
|
|
3214
|
-
Android cleanup happens AFTER boot, before install or launch
|
|
3215
|
-
|
|
3216
|
-
|
|
3418
|
+
Android cleanup happens AFTER boot, before install or launch, for AVDs
|
|
3419
|
+
parked with their data by older versions: \`adb shell pm clear\` clears
|
|
3420
|
+
the adopting app's data while retaining its APK, and other third-party apps
|
|
3421
|
+
are uninstalled. If ADB goes offline or closes the
|
|
3217
3422
|
connection, Stim waits for boot readiness and retries cleanup for up to 30
|
|
3218
3423
|
seconds, verifying the same owned AVD before each destructive command.
|
|
3219
3424
|
Failed cleanup blocks launch and remains pending for a retry. The installed APK's SHA-256 must match the
|
|
@@ -3222,15 +3427,15 @@ result as proof instead of requiring an unrelated screenshot.`
|
|
|
3222
3427
|
If the retained APK has a conflicting signer or version, adoption uninstalls
|
|
3223
3428
|
it and retries installation. Adoption stays pending until installation succeeds.
|
|
3224
3429
|
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3430
|
+
The wipe resets apps, accounts, device settings and the shared storage
|
|
3431
|
+
inside the data partition; the AVD's creation settings and any separate
|
|
3432
|
+
SD card image remain. Status lists parked Android emulators; GC
|
|
3433
|
+
reports their system image, age and disk size.
|
|
3229
3434
|
`
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3435
|
+
},
|
|
3436
|
+
builds: {
|
|
3437
|
+
summary: "optional cache warm-up, build optimizations, fingerprints, .fingerprintignore, install unchanged, runtime state",
|
|
3438
|
+
body: () => `OPTIONAL CACHE WARM-UP FOR REPEATED NATIVE WORK
|
|
3234
3439
|
When several native worktrees are coming, build the source checkout once to
|
|
3235
3440
|
seed the shared caches before warming the linked worktrees. Skip this extra
|
|
3236
3441
|
build for one-off or JavaScript-only work. For local simulator or emulator
|
|
@@ -3475,6 +3680,25 @@ THE BUILD CACHE HAS THREE LEVELS
|
|
|
3475
3680
|
of compiling beside it. No second line means nothing was found there and the
|
|
3476
3681
|
run compiles.
|
|
3477
3682
|
|
|
3683
|
+
A GITIGNORED (CNG) ios/ OR android/ IS NOT IN THE KEY: @expo/fingerprint
|
|
3684
|
+
hashes the app config instead, so the directory must come from that config.
|
|
3685
|
+
Stim records the fingerprint each of its prebuilds produced in the
|
|
3686
|
+
workspace state. On a miss, an existing CNG directory with no matching
|
|
3687
|
+
record -- the app config, a config plugin or a dependency changed since, or
|
|
3688
|
+
someone else generated it -- is regenerated with \`expo prebuild --clean\`
|
|
3689
|
+
before pods and the compile, so a stale directory is never built and stored
|
|
3690
|
+
under the new key:
|
|
3691
|
+
|
|
3692
|
+
prebuild ios/ not generated from this fingerprint -> regenerated with --clean (9s)
|
|
3693
|
+
|
|
3694
|
+
Regeneration discards hand edits under a gitignored ios/ or android/ (for
|
|
3695
|
+
example a signing team set in Xcode); put them in the app config, such as
|
|
3696
|
+
ios.appleTeamId, or a config plugin. A committed native directory is hashed
|
|
3697
|
+
into the key and never regenerated. The record only covers prebuilds Stim
|
|
3698
|
+
ran: after a manual \`expo prebuild\` with a different config, run
|
|
3699
|
+
\`expo prebuild --clean\` yourself or delete the directory so the next build
|
|
3700
|
+
regenerates it.
|
|
3701
|
+
|
|
3478
3702
|
If the iOS fingerprint after prebuild or pod install is unavailable, Stim
|
|
3479
3703
|
installs the build but skips local storage and remote uploads. fingerprint
|
|
3480
3704
|
and cacheKey are null in the result and lastBuild; the old key is not reused.
|
|
@@ -3528,10 +3752,10 @@ WHAT MAKES THE CACHE ACTUALLY HIT: .FINGERPRINTIGNORE
|
|
|
3528
3752
|
mismatch naming the differing sources. Untracked, non-gitignored files under
|
|
3529
3753
|
ios/ or android/ count too -- they are hashed like any other source, so a
|
|
3530
3754
|
stray file there moves the key on your machine and nowhere else.`
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3755
|
+
},
|
|
3756
|
+
concurrency: {
|
|
3757
|
+
summary: "waiting on another workspace's build, --no-build-cache, concurrency.maxBuilds and maxDevices",
|
|
3758
|
+
body: () => `ONE COMPILE PER FINGERPRINT, ACROSS EVERY WORKSPACE
|
|
3535
3759
|
The cache makes the SECOND workspace on a commit free -- but only once the
|
|
3536
3760
|
first has finished. Three agents starting within the same minute all miss it,
|
|
3537
3761
|
and without this all three compile the same app at once, fighting for the
|
|
@@ -3610,10 +3834,67 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
3610
3834
|
reports stale build locks, and \`gc --delete\` clears them. Set the caps
|
|
3611
3835
|
with \`stim settings set concurrency.maxBuilds 2\`, by editing
|
|
3612
3836
|
~/.stim/config.json, or via the two env vars (see \`guide settings\`).`
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3837
|
+
},
|
|
3838
|
+
budget: {
|
|
3839
|
+
summary: "disk and memory budgets: what start, ios and android reclaim first, and STIM_LOW_DISK",
|
|
3840
|
+
body: () => `DISK AND MEMORY BUDGETS (ON BY DEFAULT)
|
|
3841
|
+
Before \`start\`, \`ios\` and \`android\` build or boot anything, they
|
|
3842
|
+
compare the machine against four MACHINE-level settings:
|
|
3843
|
+
|
|
3844
|
+
budget.minFreeDiskGb free disk on the volumes holding the app and
|
|
3845
|
+
$STIM_HOME. Default 20. Below it, Stim reclaims.
|
|
3846
|
+
budget.hardFloorDiskGb default 5. Still below it after reclaiming,
|
|
3847
|
+
the run refuses with STIM_LOW_DISK.
|
|
3848
|
+
budget.maxCommittedMemoryGb the rough memory of live environments, the
|
|
3849
|
+
figure \`stim status\` prints (a booted
|
|
3850
|
+
simulator 1.5 GB, an emulator 2.5 GB, a dev
|
|
3851
|
+
server 0.7 GB). Default 60% of physical memory.
|
|
3852
|
+
budget.maxLiveWorkspaces workspaces with a booted device or running dev
|
|
3853
|
+
server. Unset by default.
|
|
3854
|
+
|
|
3855
|
+
0 turns a check off; with budget.minFreeDiskGb at 0, Stim still reclaims
|
|
3856
|
+
below the hard floor before refusing. A \`start\` whose dev server already
|
|
3857
|
+
answers checks nothing; \`start --reset-cache\` checks before it stops the
|
|
3858
|
+
server.
|
|
3859
|
+
|
|
3860
|
+
Over budget, Stim reclaims in this order and stops as soon as it is back
|
|
3861
|
+
under budget. Each step prints a \`budget\` line on stderr, and the \`--json\`
|
|
3862
|
+
payload lists the steps that acted under \`reclaimed\`:
|
|
3863
|
+
|
|
3864
|
+
1. shut down idle owned devices in other workspaces: booted, no driver,
|
|
3865
|
+
no Stim or agent-device lock, no activity for 10 minutes, and no build
|
|
3866
|
+
in progress (\`gc --idle\` semantics; shut down, never deleted)
|
|
3867
|
+
2. stop idle dev servers in other workspaces: a Stim supervisor with no
|
|
3868
|
+
bundle request, device log, Stim command or supervisor start for 10
|
|
3869
|
+
minutes, no build in progress, and no device in that workspace that is
|
|
3870
|
+
driven, active, or of unknown activity. Stim rechecks under that
|
|
3871
|
+
workspace's native-run and metro-start locks before it stops the
|
|
3872
|
+
server, and skips the step when simulators cannot be listed. The next
|
|
3873
|
+
\`start\`, \`ios\` or \`android\` there brings it back
|
|
3874
|
+
3. clear the build outputs of workspaces not in use and idle for 10
|
|
3875
|
+
minutes, least recently used first, re-measuring after each
|
|
3876
|
+
(\`gc --delete\` semantics; the next build installs from the shared
|
|
3877
|
+
cache). A workspace whose last use is unknown is kept
|
|
3878
|
+
4. trim shared cache entries nothing has used for 14 days
|
|
3879
|
+
(\`gc --delete --older-than 14\` for the caches)
|
|
3880
|
+
|
|
3881
|
+
Steps 3 and 4 run only for disk. Memory and workspace limits never refuse;
|
|
3882
|
+
a run still over them prints one \`budget\` warning and continues. The
|
|
3883
|
+
current workspace is never reclaimed.
|
|
3884
|
+
|
|
3885
|
+
With STIM_HOME set, the budget is off unless its environment variable is
|
|
3886
|
+
set (STIM_BUDGET_MIN_FREE_DISK_GB, STIM_BUDGET_HARD_FLOOR_DISK_GB,
|
|
3887
|
+
STIM_BUDGET_MAX_COMMITTED_MEMORY_GB, STIM_BUDGET_MAX_LIVE_WORKSPACES), and
|
|
3888
|
+
step 1 never runs because devices are machine-global.
|
|
3889
|
+
|
|
3890
|
+
\`stim doctor\` prints a \`budget\` line with the free disk and committed
|
|
3891
|
+
memory against the budget, and a finding with the reclaim plan when over it.
|
|
3892
|
+
Change a limit with \`stim settings set budget.minFreeDiskGb 30\`.
|
|
3893
|
+
See \`guide errors STIM_LOW_DISK\`.`
|
|
3894
|
+
},
|
|
3895
|
+
options: {
|
|
3896
|
+
summary: "every flag per command, Android variants and flavors, the per-run simulator model, runtime and system image",
|
|
3897
|
+
body: () => `THE OPTION SURFACE, IN FULL
|
|
3617
3898
|
start --json --wait <seconds> --remote --reset-cache
|
|
3618
3899
|
ios --slot <name> --json --no-metro-check --no-build-cache --scheme <name> --configuration <name> --device-type <name> --runtime <version> --simulator-app <xcode|siniulator|stim-desktop> --device [udid] --wait <seconds> --no-wait --remote <proxy|eas>
|
|
3619
3900
|
android --slot <name> --json --no-metro-check --no-build-cache --variant <name> --system-image <id> --device [serial] --wait <seconds> --no-wait --remote <proxy|eas>
|
|
@@ -3841,10 +4122,10 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
3841
4122
|
version it was made with. The --json payload reports what was actually
|
|
3842
4123
|
used: \`deviceType\` and \`runtime\` on iOS, \`systemImage\` on Android,
|
|
3843
4124
|
read from the device itself, so a settings-driven run reports them too.`
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
4125
|
+
},
|
|
4126
|
+
devices: {
|
|
4127
|
+
summary: "ios --device and android --device on a phone: what the run skips, signing, the LAN wiring, the collector",
|
|
4128
|
+
body: () => ` \`android --device [serial]\` installs and launches on a physical device
|
|
3848
4129
|
connected to this machine instead of this workspace's owned emulator. With
|
|
3849
4130
|
no serial it takes the first device it can lease (\`guide lifecycle lease\`).
|
|
3850
4131
|
It cannot be combined with --remote.
|
|
@@ -3968,10 +4249,10 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
3968
4249
|
by hashing the installed container; there is no cheap equivalent through
|
|
3969
4250
|
devicectl, so a device run always installs. It is an upgrade install: the
|
|
3970
4251
|
app's data, and the Local Network permission the phone granted it, survive.`
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
4252
|
+
},
|
|
4253
|
+
lease: {
|
|
4254
|
+
summary: "run-scoped leases, --wait and --no-wait, device lock and unlock, which phone an id-less --device picks",
|
|
4255
|
+
body: () => `THE DEVICE LEASE ON A \`--device\` RUN
|
|
3975
4256
|
A physical device is shared, so a \`--device\` run takes a lease on it. The
|
|
3976
4257
|
lease step sits AFTER the build (a build touches no device) and before the
|
|
3977
4258
|
install, and the run releases what it took when the command exits: on
|
|
@@ -4067,10 +4348,10 @@ THE POOL: WHICH DEVICE AN ID-LESS \`--device\` PICKS
|
|
|
4067
4348
|
The chosen device is on the phase line and in \`--json\` (\`udid\` or
|
|
4068
4349
|
\`serial\`, plus \`deviceName\`), so an agent can hand the same id to its
|
|
4069
4350
|
device tool.`
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4351
|
+
},
|
|
4352
|
+
release: {
|
|
4353
|
+
summary: "Release configurations and ...Release variants: Metro skipped, process-proven launch, the JS swap",
|
|
4354
|
+
body: () => ` A VARIANT WHOSE NAME ENDS IN "Release" IS A RELEASE BUILD (\`release\`,
|
|
4074
4355
|
\`productionRelease\`), and that is the whole opt-in -- there is no second
|
|
4075
4356
|
flag. It is the Android half of \`ios --configuration Release\` and behaves
|
|
4076
4357
|
the same way: AGP's bundle task embeds the JS, so Metro is skipped ENTIRELY
|
|
@@ -4143,10 +4424,10 @@ THE POOL: WHICH DEVICE AN ID-LESS \`--device\` PICKS
|
|
|
4143
4424
|
builds the \`iphoneos\` slice for a cabled iPhone and keys its cache
|
|
4144
4425
|
\`-device\` instead of \`-sim\`, but does not install it yet. Archives,
|
|
4145
4426
|
\`.ipa\` export, store signing and distribution stay out of scope.`
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4427
|
+
},
|
|
4428
|
+
simslim: {
|
|
4429
|
+
summary: "recommended SimSlim profiles and recovery from host memory pressure",
|
|
4430
|
+
body: () => `SIMSLIM FOR PARALLEL IOS WORK
|
|
4150
4431
|
SimSlim is recommended as an optional way to reduce simulator background
|
|
4151
4432
|
services and memory use, especially with several workspaces. Review which
|
|
4152
4433
|
services your app and tests need; a slim profile can disable those features.
|
|
@@ -4216,14 +4497,12 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
4216
4497
|
agents' simulators or heavy apps. Rebooting a simulator under the same pressure
|
|
4217
4498
|
can repeat the stall. Consider fewer concurrent builds/devices (guide lifecycle
|
|
4218
4499
|
concurrency) and a reviewed SimSlim profile for future runs.`
|
|
4500
|
+
}
|
|
4219
4501
|
}
|
|
4220
|
-
}
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
const cleanup = {
|
|
4225
|
-
summary: "Where simulators come from, and how they get reclaimed",
|
|
4226
|
-
preamble: () => `DEVICE SLOTS
|
|
4502
|
+
},
|
|
4503
|
+
cleanup: {
|
|
4504
|
+
summary: "Where simulators come from, and how they get reclaimed",
|
|
4505
|
+
preamble: () => `DEVICE SLOTS
|
|
4227
4506
|
|
|
4228
4507
|
Cleanup enumerates every slot. stop --slot <name> keeps the shared server and
|
|
4229
4508
|
other slots; plain stop and worktree remove handle the whole workspace.
|
|
@@ -4238,18 +4517,26 @@ WHAT RECLAIMS AN OWNED DEVICE
|
|
|
4238
4517
|
stim worktree remove parks eligible owned simulators and emulators
|
|
4239
4518
|
(\`guide lifecycle pool\`); deletes them when
|
|
4240
4519
|
parking is disabled or their setup cannot be verified
|
|
4241
|
-
stim gc --delete sweeps
|
|
4242
|
-
|
|
4520
|
+
stim gc --delete sweeps devices Stim created that no project
|
|
4521
|
+
references (\`guide cleanup gc\`), clears
|
|
4522
|
+
verified parked simulators and emulators, and
|
|
4523
|
+
runs \`stim worktree remove\` on every clean,
|
|
4524
|
+
Stim-managed linked worktree whose branch is merged
|
|
4243
4525
|
stim gc --delete --older-than <days>
|
|
4244
4526
|
also reaps the device of a workspace no Stim
|
|
4245
4527
|
command has used in that long, even though the
|
|
4246
|
-
project is still on disk
|
|
4528
|
+
project is still on disk, and clears only the
|
|
4529
|
+
devices parked at least that long
|
|
4247
4530
|
stim gc --delete --worktrees
|
|
4248
|
-
runs \`stim worktree remove\` on every clean,
|
|
4249
|
-
Stim-managed linked worktree
|
|
4531
|
+
also runs \`stim worktree remove\` on every clean,
|
|
4532
|
+
idle, Stim-managed linked worktree
|
|
4533
|
+
(\`guide cleanup gc\`)
|
|
4534
|
+
stim gc --idle <duration>
|
|
4535
|
+
shuts DOWN (never deletes) owned devices with no
|
|
4536
|
+
driver, claim or activity for that long
|
|
4250
4537
|
|
|
4251
4538
|
\`worktree remove\` and \`gc --delete\` are the only two commands that delete;
|
|
4252
|
-
\`gc --delete
|
|
4539
|
+
\`gc --delete\` deletes worktrees only through \`worktree remove\`. \`gc
|
|
4253
4540
|
--delete\` also clears workspace build outputs (\`guide cleanup disk\`) and
|
|
4254
4541
|
orphaned workspace directories, never a checkout. \`stim stop\` shuts a device
|
|
4255
4542
|
DOWN and leaves it assigned, which is what makes returning to a branch cost a
|
|
@@ -4271,10 +4558,10 @@ start the counters over. A file this version cannot read -- unparseable, or
|
|
|
4271
4558
|
written by a newer Stim -- costs one dim line on stderr and is otherwise left
|
|
4272
4559
|
alone; only the next \`ios\` or \`android\` run moves an unparseable one aside
|
|
4273
4560
|
to stats.json.corrupt-<unix ms> and starts a new one.`,
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4561
|
+
sections: {
|
|
4562
|
+
gc: {
|
|
4563
|
+
summary: "what gc and worktree remove delete, keep and refuse: orphans, stale records, locks, leases, EAS sessions",
|
|
4564
|
+
body: () => `LINKED WORKTREES
|
|
4278
4565
|
\`stim worktree remove\` works with any linked worktree, warmed or not.
|
|
4279
4566
|
Git registration identifies the worktree; a Stim registry entry is not
|
|
4280
4567
|
required. Before it reclaims anything, the command refuses a worktree git
|
|
@@ -4302,23 +4589,67 @@ IN USE
|
|
|
4302
4589
|
existence cannot be read (a permission error) is never treated as deleted.
|
|
4303
4590
|
|
|
4304
4591
|
SWEEPING FINISHED WORKTREES
|
|
4305
|
-
\`gc
|
|
4306
|
-
every
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4592
|
+
Every \`gc\` without --cache looks at every registered project root and
|
|
4593
|
+
every workspace.json root, grouped by git worktree, and reports each linked
|
|
4594
|
+
worktree with the reason it is removed or kept. A worktree is finished when
|
|
4595
|
+
its branch is merged into the default branch. \`--worktrees\` also removes
|
|
4596
|
+
one that is idle: no recorded use for --older-than days, 7 without it; a
|
|
4597
|
+
worktree whose last use is unknown is kept. Both need the same clean state;
|
|
4598
|
+
a worktree is kept when it is the source checkout, bare, locked, in use,
|
|
4599
|
+
dirty (untracked files count; pod install churn alone does not), unpushed
|
|
4600
|
+
(commits no remote-tracking ref or other local branch reaches), or has
|
|
4601
|
+
initialized submodules. Without --worktrees, the report leaves out the
|
|
4602
|
+
source checkout and roots outside git.
|
|
4603
|
+
|
|
4604
|
+
MERGED means, with the default branch taken from origin/HEAD, after a
|
|
4605
|
+
\`git fetch origin <default>\` per repository (30s timeout, no credential
|
|
4606
|
+
prompt; skipped when that checkout fetched in the last 10 minutes):
|
|
4607
|
+
- HEAD is reachable from origin/<default> through a merge commit, and the
|
|
4608
|
+
branch's reflog shows a commit made on it that HEAD contains. A branch
|
|
4609
|
+
with no commit of its own -- fresh, cut from another branch, or reset
|
|
4610
|
+
onto one -- is not merged.
|
|
4611
|
+
- the branch changes the tree, and either it has no merge commits and every
|
|
4612
|
+
commit since the merge base has the same \`git patch-id --verbatim\` as a
|
|
4613
|
+
commit on the default branch (a rebase merge), or its whole diff since the
|
|
4614
|
+
merge base has the same verbatim patch id as a commit there, compared on
|
|
4615
|
+
the files the branch changes (a squash merge).
|
|
4616
|
+
Merge state comes from git alone, not from a hosting service. A squash
|
|
4617
|
+
merge whose content changed during the merge (a conflict resolution, a
|
|
4618
|
+
suggested edit, even whitespace) does not match and is kept, and so is a
|
|
4619
|
+
fast-forwarded branch. When origin/HEAD is not set, the fetch fails, or git
|
|
4620
|
+
cannot answer, the state is unknown and never counts as merged (reason
|
|
4621
|
+
merge-unknown, with the remedy); with --worktrees an idle worktree is still
|
|
4622
|
+
removed. A squash- or rebase-merged branch whose upstream is gone (deleted
|
|
4623
|
+
after the merge and pruned locally) has commits only it reaches; they do
|
|
4624
|
+
not block removal, because their change is on the default branch, and the
|
|
4625
|
+
branch is kept.
|
|
4626
|
+
stim gc # report merged worktrees
|
|
4627
|
+
stim gc --delete # remove them
|
|
4628
|
+
stim gc --delete --worktrees --older-than 3 # also the clean idle ones
|
|
4629
|
+
--cache with --worktrees is refused with STIM_BAD_ARG; run them separately.
|
|
4316
4630
|
With --delete it runs the \`stim worktree remove\` pipeline, never --force,
|
|
4317
4631
|
on each removable worktree. That pipeline re-inspects the worktree and
|
|
4318
|
-
re-checks use
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4632
|
+
re-checks use under the removal locks, and idleness for an idle worktree
|
|
4633
|
+
or an unchanged HEAD for a merged one, then parks devices and handles the
|
|
4634
|
+
branch exactly as a manual \`stim worktree remove\`, which keeps the
|
|
4635
|
+
checkout when its HEAD moves while devices are reclaimed. A worktree that
|
|
4636
|
+
changed since the report is kept with the reason. A worktree that fails is
|
|
4637
|
+
reported, gc exits 1, and the sweep continues.
|
|
4638
|
+
|
|
4639
|
+
IDLE DEVICES
|
|
4640
|
+
Plain \`gc\` lists booted owned simulators and emulators whose \`status\`
|
|
4641
|
+
activity is idle (\`guide facts status\`), with how long. \`gc --idle
|
|
4642
|
+
<duration>\` (30m, 2h, 1d) shuts down each one idle at least that long
|
|
4643
|
+
through the same teardown as \`stim stop\`: ownership is re-checked, the
|
|
4644
|
+
device and its record stay, and the next \`ios\` or \`android\` run boots
|
|
4645
|
+
it again. It acts without --delete and never deletes. It skips a device
|
|
4646
|
+
that is driven (agent-device, a device lock, a test runner), whose
|
|
4647
|
+
activity is unknown, whose idle time is unknown, or whose workspace has a
|
|
4648
|
+
build in progress, and re-checks each device just before shutting it down.
|
|
4649
|
+
Physical and remote devices are out of scope. --cache with --idle is
|
|
4650
|
+
refused with STIM_BAD_ARG.
|
|
4651
|
+
stim gc # lists idle devices
|
|
4652
|
+
stim gc --idle 2h # shuts down those idle 2 hours or more
|
|
4322
4653
|
|
|
4323
4654
|
ORPHANED WORKSPACE DIRECTORIES
|
|
4324
4655
|
A worktree deleted with \`git worktree remove\`, \`rm -rf\` or a /tmp wipe
|
|
@@ -4358,6 +4689,19 @@ If a delete fails, the device's config record is KEPT and the command reports
|
|
|
4358
4689
|
it. A record is what makes the device findable again, so it outlives a failed
|
|
4359
4690
|
teardown rather than turning it into an orphan.
|
|
4360
4691
|
|
|
4692
|
+
WHICH stim-* DEVICES gc DELETES
|
|
4693
|
+
A \`stim-\` prefix alone is not proof that Stim made a device. gc deletes an
|
|
4694
|
+
unreferenced device only when Stim created it: the device is listed in
|
|
4695
|
+
$STIM_HOME/created-devices.json, where Stim records every simulator and AVD
|
|
4696
|
+
it creates, or it predates that ledger and matches Stim's own format
|
|
4697
|
+
exactly -- an iOS name \`stim-<label> (<model> <runtime>)\`, or an AVD
|
|
4698
|
+
named \`stim-<label>\` whose config.ini holds the byte-valued
|
|
4699
|
+
disk.dataPartition.size Stim writes. gc lists any other stim-* device under
|
|
4700
|
+
"Unrecognized stim-* devices" with the command that deletes it
|
|
4701
|
+
(\`xcrun simctl delete <udid>\` or \`avdmanager delete avd -n <name>\`), and
|
|
4702
|
+
never runs it. Boot, shutdown and teardown re-check ownership by the same
|
|
4703
|
+
rule, so a device that stops matching is left alone.
|
|
4704
|
+
|
|
4361
4705
|
ANDROID DATA WITHOUT A REGISTRATION
|
|
4362
4706
|
\`gc\` also reports stim-*.avd directories whose .ini registration is
|
|
4363
4707
|
gone. \`gc --delete\` rechecks the directory, emulator process locks, and
|
|
@@ -4430,10 +4774,10 @@ THE ONE CASE GC WILL NOT REAP
|
|
|
4430
4774
|
it found, so you can judge. Delete them yourself:
|
|
4431
4775
|
xcrun simctl delete <udid>
|
|
4432
4776
|
avdmanager delete avd -n <name>`
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4777
|
+
},
|
|
4778
|
+
collector: {
|
|
4779
|
+
summary: "log collector reaping: an unproven collector pid, and why the app on a phone closed",
|
|
4780
|
+
body: () => `WHAT ELSE STOP REAPS
|
|
4437
4781
|
The device-log collectors (\`simctl log stream\` / \`adb logcat\`) that
|
|
4438
4782
|
\`ios\` / \`android\` attach after launch. They are recorded in
|
|
4439
4783
|
the global workspace state.json, and nothing outside this workspace can name them,
|
|
@@ -4487,10 +4831,10 @@ THE ONE CASE GC WILL NOT REAP
|
|
|
4487
4831
|
is gone, and the unrelated process is never signalled. A missing, malformed,
|
|
4488
4832
|
or unreadable identity leaves the record unverified and kept for a retry.
|
|
4489
4833
|
Wall-clock timestamps and command names are not ownership proof.`
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4834
|
+
},
|
|
4835
|
+
disk: {
|
|
4836
|
+
summary: "disk usage, workspace build outputs, AVD and build-log sizes, the data partition, trimming the shared caches",
|
|
4837
|
+
body: () => `DISK
|
|
4494
4838
|
Logs, state, pidfiles and Xcode DerivedData are under the global workspace
|
|
4495
4839
|
directory, and \`worktree remove\` reclaims them. \`gc --delete\` clears the
|
|
4496
4840
|
build outputs of workspaces nobody is using (WORKSPACE BUILD OUTPUTS
|
|
@@ -4498,16 +4842,17 @@ THE ONE CASE GC WILL NOT REAP
|
|
|
4498
4842
|
project build directories while sharing task outputs through its build cache.
|
|
4499
4843
|
|
|
4500
4844
|
Android AVDs normally live under ~/.android/avd, and a booted owned AVD can
|
|
4501
|
-
use several GB. \`worktree remove\`
|
|
4502
|
-
|
|
4845
|
+
use several GB. \`worktree remove\` parks the workspace's owned AVD with its
|
|
4846
|
+
user data and snapshots wiped, or deletes it when the pool is off or full;
|
|
4847
|
+
plain \`stop\` only shuts it down for reuse. Stim uses Android's default Quick Boot
|
|
4503
4848
|
unless displayless Linux requires software rendering, where snapshots are
|
|
4504
4849
|
disabled. The first boot and a boot after the emulator, system image, or AVD
|
|
4505
4850
|
settings change are cold, while later supported boots load the one automatic
|
|
4506
4851
|
snapshot saved on exit. \`stop\` waits for the emulator process and, when
|
|
4507
4852
|
enabled, the snapshot save to finish.
|
|
4508
4853
|
New owned AVDs default to an 8 GiB data partition, though project settings can
|
|
4509
|
-
change it. When enabled, Quick Boot keeps one automatic snapshot
|
|
4510
|
-
|
|
4854
|
+
change it. When enabled, Quick Boot keeps one automatic snapshot until the AVD is
|
|
4855
|
+
parked or deleted.
|
|
4511
4856
|
\`gc\` prints the on-disk size beside an orphaned or stale owned Android AVD
|
|
4512
4857
|
when its content directory can be read.
|
|
4513
4858
|
|
|
@@ -4579,21 +4924,9 @@ SHARED BUILD CACHES
|
|
|
4579
4924
|
|
|
4580
4925
|
Trim rather than empty. Emptying costs the next build in every project the
|
|
4581
4926
|
time the cache was saving.`
|
|
4927
|
+
}
|
|
4582
4928
|
}
|
|
4583
|
-
}
|
|
4584
|
-
};
|
|
4585
|
-
const SETTINGS_SCHEMA_URL = `https://unpkg.com/stim/dist/settings.schema.json`;
|
|
4586
|
-
//#endregion
|
|
4587
|
-
//#region src/guide/index.ts
|
|
4588
|
-
const TOPICS = {
|
|
4589
|
-
agent: agent_default,
|
|
4590
|
-
facts,
|
|
4591
|
-
metro: metro_default,
|
|
4592
|
-
ports: ports_default,
|
|
4593
|
-
logs: logs_default,
|
|
4594
|
-
errors,
|
|
4595
|
-
lifecycle,
|
|
4596
|
-
cleanup,
|
|
4929
|
+
},
|
|
4597
4930
|
settings: {
|
|
4598
4931
|
summary: "Settings Stim reads, and where they can live",
|
|
4599
4932
|
body: () => `SETTINGS
|
|
@@ -4829,6 +5162,14 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
4829
5162
|
validates the shape and platform but cannot discover
|
|
4830
5163
|
runtime entry-point or dev-menu overrides or auto-fix
|
|
4831
5164
|
them. See \`guide metro\` for warmup behavior.
|
|
5165
|
+
metro.idleStopMinutes minutes without a bundle request, client log record or
|
|
5166
|
+
Stim command before the supervisor stops the dev
|
|
5167
|
+
server (default 60). 0 never stops it. Never during a
|
|
5168
|
+
build or bundle response, while the workspace holds
|
|
5169
|
+
a device lock, or while a workspace device is
|
|
5170
|
+
driven. Read
|
|
5171
|
+
when \`start\` spawns the supervisor; see
|
|
5172
|
+
\`guide metro\`.
|
|
4832
5173
|
worktree.exclude ignored-path skip list for worktree warm. Settings
|
|
4833
5174
|
come from the source checkout's repository-root
|
|
4834
5175
|
.stim.json. A nonempty .worktreeexclude in the source
|
|
@@ -4914,6 +5255,19 @@ Unset, 0, or any non-positive value means NO enforcement -- the default, where
|
|
|
4914
5255
|
Stim limits nothing. See \`guide lifecycle concurrency\` for what each cap
|
|
4915
5256
|
does.
|
|
4916
5257
|
|
|
5258
|
+
DISK AND MEMORY BUDGETS ARE MACHINE-LEVEL AND ON BY DEFAULT
|
|
5259
|
+
Top-level \`budget\` in ~/.stim/config.json, or the environment, which
|
|
5260
|
+
overrides the file:
|
|
5261
|
+
|
|
5262
|
+
budget.minFreeDiskGb STIM_BUDGET_MIN_FREE_DISK_GB default 20
|
|
5263
|
+
budget.hardFloorDiskGb STIM_BUDGET_HARD_FLOOR_DISK_GB default 5
|
|
5264
|
+
budget.maxCommittedMemoryGb STIM_BUDGET_MAX_COMMITTED_MEMORY_GB 60% of RAM
|
|
5265
|
+
budget.maxLiveWorkspaces STIM_BUDGET_MAX_LIVE_WORKSPACES unset
|
|
5266
|
+
|
|
5267
|
+
0 turns a check off. With STIM_HOME set and no environment variable, the
|
|
5268
|
+
budget is off. A value of the wrong shape refuses start, ios and android with
|
|
5269
|
+
STIM_BAD_ARG. See \`guide lifecycle budget\` for what each limit reclaims.
|
|
5270
|
+
|
|
4917
5271
|
THE IOS SIMULATOR APP IS MACHINE-LEVEL
|
|
4918
5272
|
Top-level \`iosSimulatorApp\` in ~/.stim/config.json selects the macOS app that
|
|
4919
5273
|
displays Stim's owned local iOS simulator after boot. It is not a project
|
|
@@ -4945,7 +5299,7 @@ window behavior.
|
|
|
4945
5299
|
THE DEVICE POOL BOUNDS ARE MACHINE-LEVEL TOO
|
|
4946
5300
|
\`pool.iosParkedMax\` caps how many parked simulators \`worktree remove\` may
|
|
4947
5301
|
leave behind for a later workspace to adopt. It is machine-level for the same
|
|
4948
|
-
reason: the disk they sit on is the whole machine's, about
|
|
5302
|
+
reason: the disk they sit on is the whole machine's, about 18 MB each once erased.
|
|
4949
5303
|
|
|
4950
5304
|
{
|
|
4951
5305
|
"pool": { "iosParkedMax": 3 }
|