stim 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/{activity-BtG4Va9l.mjs → activity-DfVKZTEB.mjs} +44 -26
- package/dist/{android-BA2i_KAV.mjs → android-BHfAu2mf.mjs} +1 -1
- package/dist/{android-C1q4l523.mjs → android-CD8pr8Q2.mjs} +112 -54
- package/dist/{android-cas-DfJkwCXW.mjs → android-cas-B9Kv9aIy.mjs} +12 -10
- package/dist/{android-C4zG2Tuc.mjs → android-qx_31wJo.mjs} +414 -118
- package/dist/{app-install-DHut6JnV.mjs → app-install-CDFY2nUL.mjs} +1 -1
- package/dist/budget-E5o91NR1.mjs +1739 -0
- package/dist/{build-plan-CeAYgKAx.mjs → build-plan-BTa93o_r.mjs} +125 -107
- package/dist/{build-progress-CDwogz6R.mjs → build-progress-l7d-X-ZP.mjs} +76 -8
- package/dist/{cache-manifest-Pubfp8wV.mjs → cache-manifest-DWPF4RKJ.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cdp-Dq_ypAlJ.mjs +115 -0
- package/dist/chrome-B5hWgQJS.mjs +61 -0
- package/dist/cli.mjs +17 -16
- package/dist/collector-run.mjs +15 -9
- package/dist/{command-output-D5z2_bcF.mjs → command-output-BIL7rlX7.mjs} +1 -1
- package/dist/{config-BEq0Qw_a.mjs → config-0jCcMM0E.mjs} +10 -1
- package/dist/created-devices-Cd558h31.mjs +37 -0
- package/dist/{dependency-state-r9UesA9a.mjs → dependency-state-DNN0yfx6.mjs} +1 -1
- package/dist/{deps-OF7CD5Dx.mjs → deps-2Wo81np9.mjs} +2 -2
- package/dist/{device-BwH2iI3O.mjs → device-Cf7vl-so.mjs} +7 -7
- package/dist/{device-lease-D83nqeMX.mjs → device-lease-CL9dZf73.mjs} +55 -6
- package/dist/{device-pool-DHj7cdPy.mjs → device-pool-MuoiyRcu.mjs} +4 -4
- package/dist/{device-remote-BQZSnnmE.mjs → device-remote-DT9ngZiD.mjs} +254 -579
- package/dist/{doctor-D8QdMRMf.mjs → doctor-D2iysNNH.mjs} +50 -20
- package/dist/{error-diagnostics-UYFSQwRy.mjs → error-diagnostics-BoiOhck8.mjs} +7 -7
- package/dist/{gc-COZteyiq.mjs → gc-eA-PRBX8.mjs} +1022 -131
- package/dist/{guide-NDvTmMi-.mjs → guide-BfZ0OmiP.mjs} +909 -132
- package/dist/{guide-status-CWvti2Lg.mjs → guide-status-BaMYu55M.mjs} +2 -2
- package/dist/{idle-NETbeNiQ.mjs → idle-DxLi5OkN.mjs} +43 -10
- package/dist/{in-use-DVhlSoyn.mjs → in-use-wYEaKQM9.mjs} +11 -7
- package/dist/{ios-CQLKpNfr.mjs → ios-CcfCeZ19.mjs} +103 -58
- package/dist/{ios-DArbmwer.mjs → ios-CmEzZiOj.mjs} +31 -22
- package/dist/{ios-device-CwDZo0X4.mjs → ios-device-BW-t_Lkv.mjs} +1 -1
- package/dist/{launch-verify-CuPDGXdr.mjs → launch-verify-CuJaBpEa.mjs} +33 -20
- package/dist/{logs-B44a1UeU.mjs → logs-DcSRbC2t.mjs} +12 -11
- package/dist/{merge-state-DDxS-XIZ.mjs → merge-state-ytFQCeh4.mjs} +38 -8
- package/dist/{metro-BWLOJ_Wr.mjs → metro-BPeY1YMh.mjs} +5 -5
- package/dist/{named-ports-Dc7neAlc.mjs → named-ports-n7tnJsI8.mjs} +78 -6
- package/dist/native-runtime-CiiFHt0e.mjs +74 -0
- package/dist/{ownership-D2xbLVoz.mjs → ownership-Bz2kETAS.mjs} +2 -2
- package/dist/{ownership-BiojdtAp.mjs → ownership-PUP4Dwai.mjs} +175 -217
- package/dist/page-BTu7I60K.mjs +29 -0
- package/dist/{ports-DwBaRFJs.mjs → ports-C5UutqpJ.mjs} +5 -5
- package/dist/{project-BXZzOABt.mjs → project-DGeclhvO.mjs} +55 -87
- package/dist/{reload-By9Dwsrt.mjs → reload-C-cV5yy_.mjs} +80 -21
- package/dist/remote-cache--aehr4Pr.mjs +526 -0
- package/dist/{server-bare-D_RK1RCj.mjs → server-bare-Bq8BpSIo.mjs} +1 -1
- package/dist/server-expo-BeYwP_Xy.mjs +2 -0
- package/dist/{server-expo-o6H5gcBc.mjs → server-expo-DUCg52-K.mjs} +2 -2
- package/dist/{settings-C0ugALSC.mjs → settings-ssVBToDR.mjs} +29 -17
- package/dist/{settings-B5oFZEri.mjs → settings-xB0Frkg6.mjs} +13 -4
- package/dist/settings.schema.json +74 -2
- package/dist/{simslim-CIR3IYJO.mjs → simslim-Bbg9UWrt.mjs} +13 -6
- package/dist/{slot-launch-rggO1Esw.mjs → slot-launch-BIWEW-wI.mjs} +4 -4
- package/dist/{spawn-claims-BJwXTMPt.mjs → spawn-claims-PT8aQpCa.mjs} +1 -1
- package/dist/{start-BSsf2tUs.mjs → start-BZhItkiL.mjs} +110 -18
- package/dist/{start-i8zc9VmS.mjs → start-Rw2GD3nV.mjs} +1 -1
- package/dist/{state-WGdIbi_d.mjs → state-DwAU2_-D.mjs} +15 -3
- package/dist/state-l1pYwOre.mjs +148 -0
- package/dist/{stats-DBYJ5bxL.mjs → stats-CaSwmsSZ.mjs} +4 -4
- package/dist/{stats-BAgJaLA4.mjs → stats-D8rUTPHd.mjs} +1 -1
- package/dist/{status-CitcBRsC.mjs → status-TJlL0HWo.mjs} +649 -116
- package/dist/{status-Q-WDEGCB.mjs → status-sszP4XKU.mjs} +130 -28
- package/dist/stim-desktop-CXt8-Z3J.mjs +40 -0
- package/dist/{stop-DIhrvu0B.mjs → stop-BZ2qMiBP.mjs} +50 -18
- package/dist/{stop-rst5mL14.mjs → stop-DskDKNTU.mjs} +2 -2
- package/dist/supervisor-run.mjs +11 -11
- package/dist/web-run.d.mts +22 -0
- package/dist/web-run.mjs +481 -0
- package/dist/web-sWXd5iek.mjs +394 -0
- package/dist/{worktree-DhxDTK44.mjs → worktree-3cBa-bQt.mjs} +1 -1
- package/dist/{worktree-KOjMX3zA.mjs → worktree-D4Do_XiQ.mjs} +229 -21
- package/dist/{worktree-BlizKDpZ.mjs → worktree-DeBQSVtR.mjs} +3 -1
- package/dist/{xcode-B5SPD--o.mjs → xcode-LM6A8cNZ.mjs} +7 -7
- package/package.json +5 -5
- package/dist/budget-De3P2rq_.mjs +0 -620
- package/dist/native-run-D7yB_AsB.mjs +0 -143
- package/dist/server-expo-B-CCUJZj.mjs +0 -2
- package/dist/workspace-process-lock-Cx74RSDZ.mjs +0 -57
- package/dist/workspaces-COD2xCz-.mjs +0 -1013
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-
|
|
3
|
-
import { t as
|
|
1
|
+
import { a as findProjectRoot } from "./project-DGeclhvO.mjs";
|
|
2
|
+
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-xB0Frkg6.mjs";
|
|
3
|
+
import { t as RECENT_LAUNCH_MS } from "./status-sszP4XKU.mjs";
|
|
4
|
+
import { t as guideStatus } from "./guide-status-BaMYu55M.mjs";
|
|
4
5
|
import { SETTINGS_SCHEMA_URL } from "@stim-cli/core/state";
|
|
5
6
|
import chalk from "chalk";
|
|
6
7
|
//#endregion
|
|
@@ -80,7 +81,14 @@ other apps or other workspaces' devices.
|
|
|
80
81
|
stim worktree warm
|
|
81
82
|
|
|
82
83
|
stim start
|
|
83
|
-
stim ios # or: stim android
|
|
84
|
+
stim ios # or: stim android, or: stim web
|
|
85
|
+
|
|
86
|
+
For the web target, stim web opens the page in a Stim-owned headless Chrome
|
|
87
|
+
and captures its console and errors in stim logs. It never starts a web
|
|
88
|
+
server: start the dev server first, then run stim web. For Expo web the dev
|
|
89
|
+
server is stim start, and the app needs the react-dom, react-native-web and
|
|
90
|
+
@expo/metro-runtime dependencies. Any other server runs on stim ports get web
|
|
91
|
+
and needs web.url. Read stim guide web first.
|
|
84
92
|
|
|
85
93
|
For a project using EAS development builds, read stim guide lifecycle eas to
|
|
86
94
|
select a profile from eas.json for the requested target, then run
|
|
@@ -177,7 +185,8 @@ RULES DURING THE LOOP
|
|
|
177
185
|
them. Use stim doctor when a build is unexpectedly slow or the environment
|
|
178
186
|
looks incomplete. If status reports a changed Android serial, rerun stim
|
|
179
187
|
android with the same build options to restore forwarding, then reopen your automation
|
|
180
|
-
session on the reported serial (guide lifecycle).
|
|
188
|
+
session on the reported serial (guide lifecycle). Each status issue names a
|
|
189
|
+
remedy to run from its workspace (guide facts status).
|
|
181
190
|
|
|
182
191
|
OWNERSHIP AND DELETION
|
|
183
192
|
|
|
@@ -221,7 +230,8 @@ Ask the user before these actions:
|
|
|
221
230
|
- worktree remove --force, because it also discards uncommitted and untracked
|
|
222
231
|
files.
|
|
223
232
|
- gc --delete, because it deletes orphaned resources, removes clean linked
|
|
224
|
-
worktrees whose branch
|
|
233
|
+
worktrees whose branch or pull request is merged (or whose pull request
|
|
234
|
+
was closed), and clears the build outputs of every
|
|
225
235
|
workspace not in use. Run stim gc --json first and show
|
|
226
236
|
the user the entries its sections list (guide facts gc). gc --delete
|
|
227
237
|
--cache all empties the shared build caches and those outputs instead, and
|
|
@@ -242,7 +252,11 @@ Run stim stop when you pause or finish a task, and stim worktree remove once
|
|
|
242
252
|
it is merged or abandoned. Never create a simulator or emulator by hand;
|
|
243
253
|
every device comes from Stim. Before starting a new workspace, check stim
|
|
244
254
|
status for an idle workspace to reuse and confirm capacity headroom instead of
|
|
245
|
-
adding another.
|
|
255
|
+
adding another. Never quit Device Hub or Simulator.app: on Xcode 27
|
|
256
|
+
(confirmed on 27A266a), quitting Device Hub by default shuts down every booted
|
|
257
|
+
simulator on the machine, including ones it never opened a window for and
|
|
258
|
+
ones other workspaces or agents are using. Use stim stop on workspaces you
|
|
259
|
+
own instead.
|
|
246
260
|
|
|
247
261
|
SANDBOXES
|
|
248
262
|
|
|
@@ -266,7 +280,8 @@ Read the matching guide before acting in these situations:
|
|
|
266
280
|
| Refusal with a CODE | stim guide errors <CODE> |
|
|
267
281
|
| Running under a sandbox | stim guide errors sandbox |
|
|
268
282
|
| Release configuration or ...Release variant | stim guide lifecycle release |
|
|
269
|
-
| Web
|
|
283
|
+
| Web app in an owned Chrome (stim web) | stim guide web |
|
|
284
|
+
| Web or API server ports | stim guide ports |
|
|
270
285
|
| Remote device, custom Metro, or tunnel | stim guide metro |
|
|
271
286
|
| Cache miss, bypass, or fingerprint exclusions | stim guide lifecycle builds |
|
|
272
287
|
| Capacity limits | stim guide lifecycle concurrency |
|
|
@@ -310,6 +325,7 @@ FULL TOPIC LIST
|
|
|
310
325
|
stim guide lifecycle release # Release configurations and ...Release variants
|
|
311
326
|
stim guide facts # the --json payloads
|
|
312
327
|
stim guide facts devmenu # the Expo dev menu or Tools button over the app
|
|
328
|
+
stim guide web # stim web: owned Chrome, page logs, launched, teardown
|
|
313
329
|
stim guide ports # named ports for web and API servers
|
|
314
330
|
stim guide metro # supervisor, custom Metro, tunnels, and remote devices
|
|
315
331
|
stim guide logs # filters, record shape, and capture limits
|
|
@@ -318,7 +334,7 @@ FULL TOPIC LIST
|
|
|
318
334
|
stim guide settings # configuration files and supported keys`
|
|
319
335
|
},
|
|
320
336
|
facts: {
|
|
321
|
-
summary: "The --json payloads: `start`, `ios`, `android`, `ios|android --plan`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
|
|
337
|
+
summary: "The --json payloads: `start`, `ios`, `android`, `web`, `ios|android --plan`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
|
|
322
338
|
preamble: () => `SLOTS
|
|
323
339
|
Named ios/android runs add slot to their JSON facts. Default-run fields remain
|
|
324
340
|
compatible. status adds a slots array per environment with each named slot's
|
|
@@ -327,7 +343,7 @@ Named collector, lease-holder, and launch keys use platform:slot internally.
|
|
|
327
343
|
|
|
328
344
|
FACTS CONTRACT
|
|
329
345
|
|
|
330
|
-
\`start\`, \`ios\`, \`android\`, \`reload\`, \`stop\`, \`status\`, \`stats\`, \`doctor\`,
|
|
346
|
+
\`start\`, \`ios\`, \`android\`, \`web\`, \`reload\`, \`stop\`, \`status\`, \`stats\`, \`doctor\`,
|
|
331
347
|
\`gc\`, and \`device lock\`/\`device unlock\` each print exactly ONE line of JSON on
|
|
332
348
|
stdout for \`--json\`. Every other line goes to stderr, so it is always safe
|
|
333
349
|
to pipe. \`logs --json\` is the one exception: it is NDJSON, one record per
|
|
@@ -366,8 +382,11 @@ status runs \`git status --porcelain=v2 --branch\` in every worktree in
|
|
|
366
382
|
parallel, and caches the merge verdict by HEAD and default-branch commit
|
|
367
383
|
under $STIM_HOME/git-merge. One call starts no new merge check 250 ms after
|
|
368
384
|
its first; later calls judge the rest, and until then a verdict for the same
|
|
369
|
-
HEAD at an older default-branch commit stands in
|
|
370
|
-
|
|
385
|
+
HEAD at an older default-branch commit stands in; a check that timed out
|
|
386
|
+
is retried after 5 minutes. \`status --watch\` reuses a worktree's git read
|
|
387
|
+
until its index, HEAD, reflog or the branch, upstream or default-branch refs
|
|
388
|
+
change, and for at most 60 s, so a file edit, creation or deletion that is
|
|
389
|
+
not staged can take up to a minute to show. Plain status prints "git: 2 changed, 1 untracked, ahead 3" under
|
|
371
390
|
each environment, and the same after each worktree with no environment.
|
|
372
391
|
|
|
373
392
|
status's remoteDevices lists each environment's recorded EAS Simulator
|
|
@@ -390,7 +409,7 @@ Plain status prints one "remote <platform>: EAS session <id> billable" line
|
|
|
390
409
|
per session, with the preview URL.`,
|
|
391
410
|
sections: {
|
|
392
411
|
payloads: {
|
|
393
|
-
summary: "every field of the start, ios, android and reload payloads, the error contract, the device rules",
|
|
412
|
+
summary: "every field of the start, ios, android, web and reload payloads, the error contract, the device rules",
|
|
394
413
|
body: () => ` stim start --json
|
|
395
414
|
|
|
396
415
|
port the Metro port RESERVED for this workspace
|
|
@@ -431,13 +450,18 @@ per session, with the preview URL.`,
|
|
|
431
450
|
hit 6564e2.. (post-prebuild key)\`), so a cold tree -- a
|
|
432
451
|
fresh worktree or clone of a CNG app -- installs an entry
|
|
433
452
|
another workspace already built instead of compiling
|
|
434
|
-
beside it.
|
|
435
|
-
Gradle plugins can rewrite native inputs
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
453
|
+
beside it. Both platforms fingerprint again after the
|
|
454
|
+
compile because Gradle plugins can rewrite native inputs
|
|
455
|
+
while they build; a change under node_modules/ or the
|
|
456
|
+
native directory stores the artifact only under that
|
|
457
|
+
post-build hash. A stable fingerprint prints no shift line.
|
|
458
|
+
If any other input changed while the build ran (the app
|
|
459
|
+
config or a config plugin since the first lookup, other
|
|
460
|
+
than the bundle id or package prebuild adds, or any
|
|
461
|
+
other source during the compile), or a fingerprint after
|
|
462
|
+
prebuild, pod install or the compile cannot be computed,
|
|
463
|
+
the build is installed but not cached, and fingerprint and
|
|
464
|
+
cacheKey are null
|
|
441
465
|
configuration the Xcode configuration that was built ("Release" from
|
|
442
466
|
--configuration or the ios.configuration setting); null for
|
|
443
467
|
the default Debug
|
|
@@ -518,6 +542,12 @@ per session, with the preview URL.`,
|
|
|
518
542
|
finishing
|
|
519
543
|
"unverified" nothing was observed at all: usually a
|
|
520
544
|
dev-client server picker awaiting a tap
|
|
545
|
+
Neither "bundling" nor "unverified" is reported for an app
|
|
546
|
+
whose process is gone when the bundle timeout closes: the
|
|
547
|
+
run fails as FATAL, "the app process exited", with the
|
|
548
|
+
device log's errors. An iOS crash report can land a minute
|
|
549
|
+
after the crash, so \`logs --errors\` may show the native
|
|
550
|
+
stack only later
|
|
521
551
|
See \`guide facts devmenu\` for the dev menu and its button.
|
|
522
552
|
metroPort the port the app was wired to; NULL on a non-Debug
|
|
523
553
|
configuration, whose JS is embedded and which is launched
|
|
@@ -615,18 +645,20 @@ per session, with the preview URL.`,
|
|
|
615
645
|
reason is "not running" or "stopped (idle)" when the
|
|
616
646
|
supervisor had stopped it after metro.idleStopMinutes
|
|
617
647
|
|
|
618
|
-
stim reload [ios|android] --json
|
|
648
|
+
stim reload [ios|android|web] --json
|
|
619
649
|
|
|
620
650
|
Exit 0 and this payload confirm that the reload request was sent. They do
|
|
621
651
|
not prove that new JavaScript loaded or that the screen recovered. The
|
|
622
652
|
command does not observe completion. Verify the expected UI on deviceId
|
|
623
653
|
and inspect stim logs --errors before claiming recovery.
|
|
624
654
|
|
|
625
|
-
platform "ios" | "android"
|
|
626
|
-
deviceId the exact owned simulator UDID or emulator serial targeted
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
655
|
+
platform "ios" | "android" | "web"
|
|
656
|
+
deviceId the exact owned simulator UDID or emulator serial targeted;
|
|
657
|
+
for web, the owned Chrome's DevTools endpoint
|
|
658
|
+
deviceName the owned simulator or AVD name; for web, the Chrome version
|
|
659
|
+
appId the live bundle id or Android package; for web, the page URL
|
|
660
|
+
metroPort the workspace's verified Metro port; for web, the reserved
|
|
661
|
+
Metro port or null
|
|
630
662
|
strategy how the reload was addressed.
|
|
631
663
|
"metro-websocket" -- Metro named its clients and Stim
|
|
632
664
|
addressed every peer matching this platform. A workspace
|
|
@@ -636,11 +668,35 @@ per session, with the preview URL.`,
|
|
|
636
668
|
the reload went to all of them and Stim cannot confirm appId
|
|
637
669
|
was among them. Verify the UI on deviceId; if it did not
|
|
638
670
|
change, reload from the app's own error screen or dev menu
|
|
671
|
+
"cdp" -- web: Page.reload on the owned Chrome page, sent
|
|
672
|
+
over a DevTools connection verified to reach that Chrome
|
|
639
673
|
targets how many peers the reload was addressed to, or null when
|
|
640
674
|
broadcast. Greater than 1 means several devices are running
|
|
641
675
|
this app on that Metro and the request addressed all of
|
|
642
676
|
them, not only deviceId. Completion is not observed
|
|
643
677
|
|
|
678
|
+
stim web --json
|
|
679
|
+
|
|
680
|
+
platform "web"
|
|
681
|
+
browser "chrome"
|
|
682
|
+
version the Chrome product, such as "Chrome/153.0.8010.49", or null
|
|
683
|
+
running true: the owned Chrome answered and holds the page
|
|
684
|
+
pid the owned Chrome's browser process; null when not running
|
|
685
|
+
supervisorPid the Stim process holding its DevTools session, or null
|
|
686
|
+
url the page opened, web.url with its ports filled in
|
|
687
|
+
headless false only with --headed
|
|
688
|
+
viewport "desktop" | "phone" (web.viewport)
|
|
689
|
+
profile the Stim-owned Chrome user data directory
|
|
690
|
+
cdpEndpoint http://127.0.0.1:<port>, the reserved DevTools endpoint, or
|
|
691
|
+
null when not running
|
|
692
|
+
reused true when the running Chrome navigated again instead of
|
|
693
|
+
starting: same --headed, viewport and certificate options
|
|
694
|
+
launched true | "bundling" | "unverified" (see \`guide web\`)
|
|
695
|
+
metroPort the Metro port the page loads from, or null for a web.url
|
|
696
|
+
that does not use {port:metro}
|
|
697
|
+
logs { dir }: web.ndjson holds the page records
|
|
698
|
+
durationMs wall time of the run
|
|
699
|
+
|
|
644
700
|
stim doctor --json
|
|
645
701
|
|
|
646
702
|
project the resolved app root
|
|
@@ -664,7 +720,7 @@ per session, with the preview URL.`,
|
|
|
664
720
|
costs-time finding with a PATH or installation remedy
|
|
665
721
|
|
|
666
722
|
ON FAILURE
|
|
667
|
-
\`start\`, \`ios\` and \`
|
|
723
|
+
\`start\`, \`ios\`, \`android\` and \`web\` all print the error contract instead,
|
|
668
724
|
still one line on stdout, and exit 1:
|
|
669
725
|
|
|
670
726
|
{ "code": "STIM_METRO_TIMEOUT", "message": "...", "remedy": "..." }
|
|
@@ -689,6 +745,12 @@ ON FAILURE
|
|
|
689
745
|
|
|
690
746
|
{ "root": "...", "ok": false, "code": "STIM_STOP_BLOCKED", "message": "...", "remedy": "..." }
|
|
691
747
|
|
|
748
|
+
device.web is present when the workspace had an owned Chrome:
|
|
749
|
+
{ status, label: "Chrome", kind?, reason?, remedy? }; kind is null when no
|
|
750
|
+
kind applies. status is "shut-down"
|
|
751
|
+
when Chrome closed (its profile is kept), else "skipped" (its identity could
|
|
752
|
+
not be verified) or "failed", and ok is then false.
|
|
753
|
+
|
|
692
754
|
Branch on \`code\`, never on the message text. \`guide errors\` enumerates
|
|
693
755
|
every code.
|
|
694
756
|
|
|
@@ -805,13 +867,13 @@ RULES
|
|
|
805
867
|
full commands.`
|
|
806
868
|
},
|
|
807
869
|
gc: {
|
|
808
|
-
summary: "the gc report payload: mode, sections, reasons, failures, and the gc refusals",
|
|
870
|
+
summary: "the gc report payload: mode, sections, reasons, failures, results, inventory, and the gc refusals",
|
|
809
871
|
body: () => ` stim gc [--delete] [--older-than <days>] [--cache <name|all|workspaces>]
|
|
810
872
|
[--worktrees] [--idle <duration>] --json
|
|
811
873
|
|
|
812
874
|
The report the text prints, as one payload. Show the user its sections
|
|
813
875
|
before you run \`gc --delete\`. Under --delete it is the report that run
|
|
814
|
-
acted on: each entry's outcome
|
|
876
|
+
acted on: \`results\` lists each entry's outcome, \`failures\` counts the
|
|
815
877
|
entries it could not delete, and a nonzero count exits 1. Run
|
|
816
878
|
\`stim gc --json\` again to see what is left.
|
|
817
879
|
|
|
@@ -828,6 +890,46 @@ RULES
|
|
|
828
890
|
actionable true when --delete with the same flags reclaims something
|
|
829
891
|
failures null on a dry run without --idle; otherwise the entries it
|
|
830
892
|
could not delete or shut down
|
|
893
|
+
results what --delete or --idle did, one { kind, status, label,
|
|
894
|
+
id, bytes, detail } per entry it acted on; empty on a dry
|
|
895
|
+
run. status is "done", "kept" (left alone, detail says
|
|
896
|
+
why) or "failed" (detail says why and what to retry).
|
|
897
|
+
kind: device, parkedDevice, idleDevice, deviceRecord,
|
|
898
|
+
workspaceOutputs, workspaceDirectory, project, buildLock,
|
|
899
|
+
buildSlot, deviceLease, easSession, worktree, cache.
|
|
900
|
+
label is a device, path or cache name; id is the UDID,
|
|
901
|
+
AVD name or path behind it, or null
|
|
902
|
+
inventory null except on a dry run without --cache or --idle. Report
|
|
903
|
+
only: gc never acts on it, even under --delete.
|
|
904
|
+
{ devices, runtimes, systemImages, notices }
|
|
905
|
+
devices { kind, id, name, model, runtime, state, lastUsedAt, bytes,
|
|
906
|
+
directory, owner, project, slot } every available iOS
|
|
907
|
+
simulator and registered AVD. runtime is the simctl
|
|
908
|
+
runtime identifier or the AVD's system image package.
|
|
909
|
+
lastUsedAt is simctl's last use, or when the emulator
|
|
910
|
+
last wrote the AVD's hardware-qemu.ini. bytes is the
|
|
911
|
+
simulator's data size from simctl; null for AVDs.
|
|
912
|
+
owner is workspace (project and slot say which),
|
|
913
|
+
parked, orphaned (this Stim home created it and no
|
|
914
|
+
workspace holds it), otherStimHome (a stim-* device this
|
|
915
|
+
home has no record of creating, even when a workspace
|
|
916
|
+
names it) or user. Off macOS no simulator is listed
|
|
917
|
+
runtimes { identifier, runtimeIdentifier, version, build, bytes,
|
|
918
|
+
lastUsedAt, deviceCount, command } iOS simulator
|
|
919
|
+
runtimes from \`xcrun simctl runtime list -j\`, then
|
|
920
|
+
any other \`simctl list runtimes\` shows, with bytes
|
|
921
|
+
and command null. deviceCount is the simulators on
|
|
922
|
+
it; command is the \`xcrun simctl runtime delete\`
|
|
923
|
+
line for a deletable runtime, else null. Stim never
|
|
924
|
+
runs it
|
|
925
|
+
systemImages { package, directory, avdCount, command } installed
|
|
926
|
+
Android system images; avdCount is the AVDs whose
|
|
927
|
+
image.sysdir.1 names it; command is the
|
|
928
|
+
\`sdkmanager --uninstall\` line. Stim never runs it
|
|
929
|
+
notices why a listing is missing or partial, such as simctl
|
|
930
|
+
timing out or an AVD or system image folder Stim
|
|
931
|
+
cannot read. A macOS privacy denial (EPERM) names the
|
|
932
|
+
Privacy & Security setting to grant
|
|
831
933
|
sections one array per report section, in the text order. Every key
|
|
832
934
|
is present, empty when there is nothing to report:
|
|
833
935
|
deadProjects { path }
|
|
@@ -835,26 +937,42 @@ RULES
|
|
|
835
937
|
orphanedPorts { project, label, port }
|
|
836
938
|
orphanedWorkspaces { dir, projectRoot, bytes } --delete removes the
|
|
837
939
|
whole workspace directory
|
|
838
|
-
linkedWorktrees { path, idleDays, mergedInto,
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
("
|
|
843
|
-
|
|
844
|
-
|
|
940
|
+
linkedWorktrees { path, idleDays, mergedInto, pullRequest,
|
|
941
|
+
pullRequestUnknown, willRemove, reason,
|
|
942
|
+
detail, eligibleAt } mergedInto is the
|
|
943
|
+
default branch HEAD is merged into
|
|
944
|
+
("origin/main"), or null. pullRequest is the
|
|
945
|
+
branch's pull request { number, state:
|
|
946
|
+
"open" | "merged" | "closed", url,
|
|
947
|
+
containsHead }, or null; pullRequestUnknown
|
|
948
|
+
says why gh could not answer, else null.
|
|
949
|
+
detail says why it is removed ("merged into
|
|
950
|
+
origin/main", "PR #12 closed", "idle 9d") or
|
|
951
|
+
kept. eligibleAt is the ISO time a
|
|
952
|
+
recent-activity worktree becomes removable,
|
|
953
|
+
else null. Without --worktrees, the source
|
|
954
|
+
checkout and roots outside git are left out
|
|
845
955
|
parkedSimulators { udid, name, model, runtime, parkedAt, bytes,
|
|
846
956
|
listed } with --older-than, only those parked
|
|
847
957
|
at least that long
|
|
848
958
|
parkedEmulators { name, systemImage, deviceProfile, parkedAt, bytes, listed }
|
|
849
959
|
likewise
|
|
850
960
|
orphanedDevices { kind, id, name, bytes, directory }
|
|
851
|
-
unverifiedDevices { kind, id, name, command } stim-* devices
|
|
852
|
-
has no record of creating; never
|
|
853
|
-
command yourself
|
|
961
|
+
unverifiedDevices { kind, id, name, command } stim-* devices this
|
|
962
|
+
Stim home has no record of creating; never
|
|
963
|
+
deleted, run command yourself (rm -rf <dir>
|
|
964
|
+
for AVD data with no registration)
|
|
854
965
|
staleDevices { kind, id, name, project, slot, idleDays,
|
|
855
966
|
bytes } only with --older-than
|
|
856
967
|
staleDeviceRecords { kind, id, project, slot } --delete clears
|
|
857
968
|
the record only
|
|
969
|
+
staleLedgerEntries { kind: "ios" | "android" | "web", id }
|
|
970
|
+
simulators this Stim home created that a
|
|
971
|
+
complete simctl listing no longer shows, AVD
|
|
972
|
+
names with no registration or data in any AVD
|
|
973
|
+
root, and browser profile paths whose
|
|
974
|
+
directory is gone; --delete forgets the
|
|
975
|
+
ledger entry only
|
|
858
976
|
idleDevices { kind, id, name, project, slot, lastActivityAt,
|
|
859
977
|
idleForMs, buildInProgress } booted owned
|
|
860
978
|
devices whose status activity is "idle";
|
|
@@ -872,6 +990,12 @@ RULES
|
|
|
872
990
|
deviceSweepNotices { message }
|
|
873
991
|
easSessionSweepNotices { message }
|
|
874
992
|
skipped { path, detail } not classified as dead
|
|
993
|
+
workspaceLogs { dir, projectRoot, bytes, trimBytes, willTrim,
|
|
994
|
+
reason, detail } logs/ of each workspace;
|
|
995
|
+
trimBytes is what --delete would drop from
|
|
996
|
+
Metro, client and device logs over twice the
|
|
997
|
+
8 MiB cap; willTrim marks the ones it would
|
|
998
|
+
trim
|
|
875
999
|
workspaceBuildOutputs { dir, projectRoot, bytes, idleDays, willClear,
|
|
876
1000
|
reason, detail } derived-data, gradle-build,
|
|
877
1001
|
android-cas and cache-provider of each
|
|
@@ -890,12 +1014,14 @@ RULES
|
|
|
890
1014
|
A linked worktree's detail is never null.
|
|
891
1015
|
workspaceBuildOutputs unresolved | in-use | last-use-unknown |
|
|
892
1016
|
recently-used
|
|
1017
|
+
workspaceLogs unresolved | in-use | collector
|
|
893
1018
|
linkedWorktrees not-a-worktree | bare-repository |
|
|
894
1019
|
source-checkout-unknown | source-checkout |
|
|
895
1020
|
locked | in-use | status-unreadable | dirty |
|
|
896
1021
|
unpushed-unchecked | unpushed | submodules |
|
|
897
1022
|
not-merged | merge-unknown | last-use-unknown |
|
|
898
|
-
recently-used
|
|
1023
|
+
recently-used | activity-unknown |
|
|
1024
|
+
recent-activity
|
|
899
1025
|
|
|
900
1026
|
These print the error contract instead and exit 1:
|
|
901
1027
|
|
|
@@ -906,9 +1032,66 @@ RULES
|
|
|
906
1032
|
- --cache together with --worktrees or --idle`
|
|
907
1033
|
},
|
|
908
1034
|
status: {
|
|
909
|
-
summary: "the status payload's build and device activity fields: a running build, its estimate, each platform's last build,
|
|
1035
|
+
summary: "the status payload's issues and their codes, build and device activity fields: a running build, its estimate, each platform's last build, who drives each device, whether the app runs on it, and what uses CPU and memory now",
|
|
910
1036
|
body: () => ` stim status --json
|
|
911
1037
|
|
|
1038
|
+
Each environment carries issues, the things in that workspace that need
|
|
1039
|
+
the user, and warnings, the same issues as text ("<slot>: " when not the
|
|
1040
|
+
default slot, then "<message>; run \`<remedy>\`"):
|
|
1041
|
+
|
|
1042
|
+
issues [{ code, severity, message, remedy, workspace, slot? }]
|
|
1043
|
+
|
|
1044
|
+
code port-not-ours something other than this workspace's
|
|
1045
|
+
Metro answers its reserved port
|
|
1046
|
+
sim-missing the recorded simulator no longer exists
|
|
1047
|
+
sim-without-metro the simulator is booted and no Metro
|
|
1048
|
+
serves the workspace
|
|
1049
|
+
avd-serial-changed the owned emulator came back on another
|
|
1050
|
+
serial, so Metro forwarding is lost
|
|
1051
|
+
avd-missing the recorded AVD no longer exists
|
|
1052
|
+
avd-not-detected adb does not see the owned emulator while
|
|
1053
|
+
the workspace expects it: it holds an
|
|
1054
|
+
unexpired lease on its serial, or it
|
|
1055
|
+
launched onto it and has not stopped
|
|
1056
|
+
that slot since, and its dev server runs
|
|
1057
|
+
or the launch was in the last
|
|
1058
|
+
${RECENT_LAUNCH_MS / 6e4} minutes. An idle workspace's
|
|
1059
|
+
shut-down emulator is android.state
|
|
1060
|
+
"not-detected" with no issue.
|
|
1061
|
+
avd-unchecked the emulator listing could not be read
|
|
1062
|
+
supervisor-unverified a supervisor record whose process status
|
|
1063
|
+
cannot prove gone or ours; stop refuses to
|
|
1064
|
+
signal it
|
|
1065
|
+
browser-unverified the owned Chrome's supervisor or Chrome
|
|
1066
|
+
process cannot be proven gone or ours;
|
|
1067
|
+
stop and stim web refuse to signal it
|
|
1068
|
+
browser-orphaned the owned Chrome runs but its supervisor
|
|
1069
|
+
exited, so page logs are not captured;
|
|
1070
|
+
stim stop closes it
|
|
1071
|
+
severity "error" when stop or start refuses until it is resolved, else
|
|
1072
|
+
"warning"
|
|
1073
|
+
remedy a command to run from workspace, such as "stim android --slot
|
|
1074
|
+
fold"
|
|
1075
|
+
slot absent for the default slot
|
|
1076
|
+
|
|
1077
|
+
A supervisor record whose pid is gone or reused is not an issue: status
|
|
1078
|
+
reports supervisor null, and the next stop or start clears the record.
|
|
1079
|
+
\`stop --slot <name>\` forgets that slot's launch, so a device stopped on
|
|
1080
|
+
purpose is not reported while the shared dev server keeps running.
|
|
1081
|
+
|
|
1082
|
+
An environment where \`stim web\` ran carries web, its Stim-owned Chrome:
|
|
1083
|
+
|
|
1084
|
+
web { browser, version, running, pid, supervisorPid, url, headless,
|
|
1085
|
+
viewport, profile, cdpEndpoint }
|
|
1086
|
+
|
|
1087
|
+
running the browser supervisor and Chrome are both verified live;
|
|
1088
|
+
pid, supervisorPid and cdpEndpoint are null when false
|
|
1089
|
+
cdpEndpoint http://127.0.0.1:<port>, the reserved loopback DevTools
|
|
1090
|
+
endpoint of that Chrome. Attach Playwright MCP
|
|
1091
|
+
(--cdp-endpoint) or agent-browser (--cdp <port>) to it; it
|
|
1092
|
+
reaches only the Stim profile, never your own browser
|
|
1093
|
+
profile the Stim-owned user data directory under STIM_HOME
|
|
1094
|
+
|
|
912
1095
|
Each booted simulator and detected emulator in environments (and in
|
|
913
1096
|
slots) carries activity; a shut-down or physical device has none:
|
|
914
1097
|
|
|
@@ -925,7 +1108,8 @@ RULES
|
|
|
925
1108
|
the claim does not record them
|
|
926
1109
|
lastActivityAt the newest of this device's app log records, this
|
|
927
1110
|
platform's Metro bundle requests and the workspace's last
|
|
928
|
-
Stim run; absent when none is
|
|
1111
|
+
Stim run, rounded down to the minute; absent when none is
|
|
1112
|
+
recorded
|
|
929
1113
|
basis the evidence behind state, strongest first:
|
|
930
1114
|
agent-device-claim, agent-device-lease agent-device state,
|
|
931
1115
|
read only; live only when every recorded process is alive
|
|
@@ -941,6 +1125,29 @@ RULES
|
|
|
941
1125
|
\`gc --idle <duration>\` shuts down owned devices idle that long
|
|
942
1126
|
(\`guide cleanup gc\`).
|
|
943
1127
|
|
|
1128
|
+
An owned booted simulator or detected emulator also carries app, whether
|
|
1129
|
+
the workspace's app process is alive on it now:
|
|
1130
|
+
|
|
1131
|
+
app { id, state }
|
|
1132
|
+
|
|
1133
|
+
id the bundle identifier or package checked: the one launched on this
|
|
1134
|
+
device, else the project's
|
|
1135
|
+
state "running" a process of that app runs on the device
|
|
1136
|
+
"stopped" no such process: it crashed, was killed or never launched
|
|
1137
|
+
"unknown" the process listing or the app's Info.plist could not be
|
|
1138
|
+
read; never "stopped"
|
|
1139
|
+
|
|
1140
|
+
app is absent when the device is not owned or no app id is known: the
|
|
1141
|
+
process was not checked.
|
|
1142
|
+
|
|
1143
|
+
This is current process state, read from one host ps (simulator apps are
|
|
1144
|
+
host processes) and the same adb shell ps as activity, so a status --watch
|
|
1145
|
+
refresh notices an exit within its 30-second fallback. It is not launch
|
|
1146
|
+
evidence: launched in an ios or android result keeps its own meaning. For
|
|
1147
|
+
"stopped", run \`stim ios\` or \`stim android\` to launch it again. Plain
|
|
1148
|
+
status appends "<id> running", "<id> not running" or "<id> process
|
|
1149
|
+
unknown" to the device line.
|
|
1150
|
+
|
|
944
1151
|
An environment's metro carries idleStop { reason: "idle", at, idleMinutes }
|
|
945
1152
|
when its supervisor stopped the dev server for idleness and nothing serves
|
|
946
1153
|
the port since; plain \`status\` prints "stopped (idle)" (\`guide metro\`).
|
|
@@ -980,7 +1187,7 @@ RULES
|
|
|
980
1187
|
|
|
981
1188
|
lastBuilds { ios?, android? }, each { platform, status, cacheHit,
|
|
982
1189
|
cacheSkipped, durationMs, fingerprint, startedAt, finishedAt,
|
|
983
|
-
errorCode?, missReason? }
|
|
1190
|
+
errorCode?, missReason?, diagnostics? }
|
|
984
1191
|
|
|
985
1192
|
status "ok" or "failed"
|
|
986
1193
|
cacheHit "local" or "remote" for an app from that cache tier; false
|
|
@@ -998,19 +1205,87 @@ RULES
|
|
|
998
1205
|
baseline is { fingerprint, from: "workspace" | "project" }, the
|
|
999
1206
|
cached build compared with; rekeyedBy lists "prebuild" or
|
|
1000
1207
|
"pod install" when those steps moved the key.
|
|
1208
|
+
diagnostics only on a failed run whose compiler reported errors: up to
|
|
1209
|
+
5 { file, line, column, message }, null where the compiler
|
|
1210
|
+
gave no position.
|
|
1001
1211
|
|
|
1002
1212
|
Plain status prints "last build: ios local cache in 12s, android compiled
|
|
1003
1213
|
in 7m02s". To predict the next run instead, see \`guide facts plan\`.
|
|
1004
1214
|
|
|
1215
|
+
An environment with a recorded run also carries builds, each platform's
|
|
1216
|
+
last 10 runs, newest first. Its newest entry that is not "interrupted" is
|
|
1217
|
+
the run lastBuilds reports, once a run has recorded builds.
|
|
1218
|
+
|
|
1219
|
+
builds { ios?, android? }, each a list of lastBuilds entries
|
|
1220
|
+
with { result, slot, configuration, cacheKey, phases }
|
|
1221
|
+
result "succeeded", "failed", "cancelled" (Stim stopped the run
|
|
1222
|
+
after an interrupt or \`stim stop\`) or "interrupted": its
|
|
1223
|
+
process ended without recording a result, such as a kill or a
|
|
1224
|
+
second interrupt, so the next run recorded it with
|
|
1225
|
+
null durationMs and finishedAt, no cache facts, and 0 for the
|
|
1226
|
+
phase it stopped in
|
|
1227
|
+
slot the device slot, "default" without --slot
|
|
1228
|
+
configuration the iOS configuration or Android variant the run built,
|
|
1229
|
+
"Debug" or "debug" by default; null when the run ended
|
|
1230
|
+
before resolving it
|
|
1231
|
+
cacheKey the cache key the run looked up or stored under
|
|
1232
|
+
phases milliseconds spent in each phase the run entered, among
|
|
1233
|
+
prepare, cache-lookup, wait, prebuild, pods, compile,
|
|
1234
|
+
install and launch
|
|
1235
|
+
|
|
1236
|
+
Only runs that record a last build are listed: a run that stops before
|
|
1237
|
+
looking up a build, such as a bad flag, is not. Estimates (expectedMs) come from run statistics, not builds.
|
|
1238
|
+
|
|
1005
1239
|
There is no completion fraction: a compile's log volume depends on what
|
|
1006
|
-
is already built, so it does not measure progress
|
|
1240
|
+
is already built, so it does not measure progress.
|
|
1241
|
+
|
|
1242
|
+
An environment's memoryMb is an estimate, not a measurement: a fixed amount
|
|
1243
|
+
per booted simulator, detected emulator, running Metro and running Chrome.
|
|
1244
|
+
capacity.committedMb sums it, and the memory budget uses the same estimate.
|
|
1245
|
+
What is using CPU and memory now is the top-level machine section:
|
|
1246
|
+
|
|
1247
|
+
machine null, or { owners: [{ kind, name, workspace, slot?, id, owned,
|
|
1248
|
+
cpuPercent, residentMb, processes }] }
|
|
1249
|
+
|
|
1250
|
+
kind simulator a booted simulator's launchd_sim tree
|
|
1251
|
+
emulator an emulator's launcher and qemu tree, by its -avd
|
|
1252
|
+
metro a workspace's supervisor and Metro trees
|
|
1253
|
+
build a running ios or android run's process tree,
|
|
1254
|
+
xcodebuild, Gradle and compilers included
|
|
1255
|
+
browser the Chrome of \`stim web\` and its supervisor
|
|
1256
|
+
server stim-server
|
|
1257
|
+
shared machine-wide processes no workspace owns:
|
|
1258
|
+
CoreSimulator services, adb server, Gradle and
|
|
1259
|
+
Kotlin daemons, Watchman, the emulator's netsimd
|
|
1260
|
+
workspace the workspace that records the device or runs the process;
|
|
1261
|
+
null for a device no workspace records and for server and
|
|
1262
|
+
shared
|
|
1263
|
+
id the simulator's UDID, the AVD name, Metro's port or the
|
|
1264
|
+
build's platform; null otherwise
|
|
1265
|
+
owned true for what Stim started and stops: a workspace's owned
|
|
1266
|
+
device (\`stim stop --slot <slot>\`), its Metro (\`stim
|
|
1267
|
+
stop\`), build or Chrome. Never act on an owner with false.
|
|
1268
|
+
cpuPercent ps %CPU summed over the owner's processes; 100 is one core
|
|
1269
|
+
residentMb summed resident set size. Pages shared between processes
|
|
1270
|
+
count once per process, so a simulator reports well above
|
|
1271
|
+
its physical footprint.
|
|
1272
|
+
|
|
1273
|
+
Each process counts in exactly one owner, the one whose root process is
|
|
1274
|
+
its nearest ancestor, so the supervisor a build started counts as Metro,
|
|
1275
|
+
not as the build, and a Gradle or Kotlin daemon counts in the build that
|
|
1276
|
+
started it until that build exits, then as shared. Processes with no owner
|
|
1277
|
+
are left out. machine comes from one host ps, the one status reads for
|
|
1278
|
+
device activity, and is null when no simulator is booted, no workspace is
|
|
1279
|
+
live and no build runs: status then reads no process table. \`status --watch --json\` rereads it every 15 seconds while
|
|
1280
|
+
machine is not null, with no other subprocess.`
|
|
1007
1281
|
},
|
|
1008
1282
|
plan: {
|
|
1009
|
-
summary: "the ios and android --plan payload: fingerprint, cacheHit, prebuild, expectedMs and basis",
|
|
1283
|
+
summary: "the ios and android --plan payload: fingerprint, cacheHit, prebuild, missReason, expectedMs and basis",
|
|
1010
1284
|
body: () => ` stim ios --plan --json # or: stim android --plan --json
|
|
1011
1285
|
|
|
1012
1286
|
{ platform, slot?, fingerprint, cacheKey, cacheHit, provider,
|
|
1013
|
-
cacheSkipped, prebuild, outcome, expectedMs, basis,
|
|
1287
|
+
cacheSkipped, prebuild, outcome, expectedMs, basis, missReason?,
|
|
1288
|
+
refusal? }
|
|
1014
1289
|
|
|
1015
1290
|
fingerprint the fingerprint the run would look up first; with
|
|
1016
1291
|
--eas-profile, the one EAS CLI computes
|
|
@@ -1025,6 +1300,15 @@ RULES
|
|
|
1025
1300
|
expectedMs the median wall time of this project's last successful runs
|
|
1026
1301
|
with that outcome on that platform, or null with none
|
|
1027
1302
|
basis how many runs expectedMs comes from (at most 10)
|
|
1303
|
+
missReason on a predicted cold build with cache reads on, why the
|
|
1304
|
+
cache has no app, in the shape of lastBuilds.<platform>
|
|
1305
|
+
.missReason (\`guide facts status\`), compared with the same
|
|
1306
|
+
baseline the run would use. kind is "changed",
|
|
1307
|
+
"no-baseline", "same-sources" or "prebuild-pending": a
|
|
1308
|
+
baseline exists and the run would prebuild first, which the
|
|
1309
|
+
plan does not, so changes compare the fingerprint before that
|
|
1310
|
+
prebuild; changeCount 0 then means those inputs match the
|
|
1311
|
+
baseline. rekeyedBy is empty.
|
|
1028
1312
|
refusal { code, message, remedy } when the run would refuse:
|
|
1029
1313
|
STIM_PREBUILD_FAILED for a tracked native dir the fingerprint
|
|
1030
1314
|
leaves out, STIM_EAS_BUILD_MISSING for an EAS miss
|
|
@@ -1298,7 +1582,16 @@ their owning workspaces.
|
|
|
1298
1582
|
|
|
1299
1583
|
The machine registry, under STIM_HOME, serializes allocation and cleanup.
|
|
1300
1584
|
The workspace is the nearest package.json directory, resolved through
|
|
1301
|
-
symlinks.
|
|
1585
|
+
symlinks. In a monorepo, a package that depends on neither react-native nor
|
|
1586
|
+
expo, such as a Vite web app, uses the one Stim app registered in the same
|
|
1587
|
+
git worktree instead, and says so on stderr. ports, web, settings, logs,
|
|
1588
|
+
reload, stop and status follow this rule (status stars the app instead of
|
|
1589
|
+
printing the note); other commands use the nearest package.json. Register the app first: run stim ports get <label>, stim start,
|
|
1590
|
+
stim ios or stim android from the app directory. Every ports command then
|
|
1591
|
+
acts on the app's ports, so ports stop without a label there also stops the
|
|
1592
|
+
app's other labels. A package that already holds ports keeps them; release
|
|
1593
|
+
them to move to the app. With no registered app, or more than one, the
|
|
1594
|
+
nearest package.json stays the workspace; run ports from the app directory.
|
|
1302
1595
|
The allocation reserves a number, not a listening socket. Another process
|
|
1303
1596
|
can bind it before your server does. Use strict-port behavior when supported
|
|
1304
1597
|
and verify the server bound the number supplied. Stim does not start,
|
|
@@ -1340,7 +1633,10 @@ discovered, not enumerated.
|
|
|
1340
1633
|
metro.ndjson, client.ndjson and device.ndjson are size-capped. At about 8 MiB a file
|
|
1341
1634
|
becomes <name>.1, replacing the previous .1, and a new file starts. Queries read
|
|
1342
1635
|
both generations, so the oldest records drop off first. History and --since
|
|
1343
|
-
reach back only as far as those records.
|
|
1636
|
+
reach back only as far as those records. A file written before the cap
|
|
1637
|
+
existed can be larger; \`gc\` reports each workspace's log size and \`gc
|
|
1638
|
+
--delete\` trims a file over 16 MiB to its newest 8 MiB in a workspace not in use
|
|
1639
|
+
(\`guide cleanup disk\`).
|
|
1344
1640
|
|
|
1345
1641
|
EXIT 0 MEANS THE QUERY SUCCEEDED, whether or not records matched. A clean
|
|
1346
1642
|
\`stim logs --errors\` check requires exit code 0 AND no matching errors in
|
|
@@ -1370,18 +1666,23 @@ FLAGS
|
|
|
1370
1666
|
--tail <n> only the last n MATCHING records (applied after filtering,
|
|
1371
1667
|
so --level error --tail 5 is the last five ERRORS)
|
|
1372
1668
|
--errors errors and fatals since the last marker, from metro, client
|
|
1373
|
-
and build, plus confirmed native app-crash reports
|
|
1669
|
+
and build, plus confirmed native app-crash reports and the
|
|
1670
|
+
owned Chrome's device errors (platform web: failed
|
|
1671
|
+
requests, browser errors).
|
|
1374
1672
|
Capped at 20 printed records.
|
|
1375
1673
|
--follow keep streaming until interrupted (Ctrl+C is exit 0)
|
|
1376
1674
|
--json the raw records, one per line, so stdout is valid NDJSON.
|
|
1377
1675
|
ZERO matches is ZERO bytes on stdout (an empty NDJSON
|
|
1378
1676
|
stream), exit 0 -- parse stdout line by line, never as one
|
|
1379
1677
|
JSON document. The "No matching log records" note is human
|
|
1380
|
-
mode only, on stderr.
|
|
1678
|
+
mode only, on stderr. With --errors, an Expo error record
|
|
1679
|
+
also carries context (see THE RECORD).
|
|
1381
1680
|
|
|
1382
1681
|
--ERRORS, PRECISELY
|
|
1383
1682
|
Level error or fatal, from metro, client and build, plus device records with
|
|
1384
|
-
event native_crash (app/device/time-correlated OS reports or fatal app console output)
|
|
1683
|
+
event native_crash (app/device/time-correlated OS reports or fatal app console output)
|
|
1684
|
+
and device records with platform web (the owned page's failed requests and
|
|
1685
|
+
browser errors, from stim web), timestamped after the
|
|
1385
1686
|
marker that closes their window. Three rules, and a field test
|
|
1386
1687
|
caught all three wrong at once -- it returned 3,004 iOS syslog lines on a
|
|
1387
1688
|
healthy app while hiding a real startup crash.
|
|
@@ -1390,7 +1691,10 @@ FLAGS
|
|
|
1390
1691
|
\`simctl log stream\` is predicated on the app's PROCESS, and inside that
|
|
1391
1692
|
process Apple's frameworks log thousands of Error-typed lines (nw_socket,
|
|
1392
1693
|
SecTrust, WebKit, CoreUI) that have nothing to do with your app. The proven
|
|
1393
|
-
ones are demoted to info by the collector
|
|
1694
|
+
ones are demoted to info by the collector, and iOS main-thread
|
|
1695
|
+
"Synchronous URL loading" performance diagnostics (Expo icons served by
|
|
1696
|
+
Metro raise them) to warn, so a launch does not count them as app errors;
|
|
1697
|
+
the scope rule covers the rest.
|
|
1394
1698
|
The metro stream carries exactly one demotion of its own, and it is Stim's
|
|
1395
1699
|
doing: the dev-client deep link \`ios\`/\`android\` open to wire the app to
|
|
1396
1700
|
your port arrives inside the app as a link, and React Navigation logs at
|
|
@@ -1416,8 +1720,15 @@ FLAGS
|
|
|
1416
1720
|
errors are reported -- and nothing else. A failed attempt's own summary
|
|
1417
1721
|
and details land at or after its marker, so they stay reported.
|
|
1418
1722
|
a LAUNCH marker (src build, written before \`ios\` / \`android\` attempts
|
|
1419
|
-
launch) resets EVERYTHING
|
|
1420
|
-
native crash is not hidden by a marker written
|
|
1723
|
+
launch) resets EVERYTHING except the web page's records. It precedes the
|
|
1724
|
+
tool call so an immediate native crash is not hidden by a marker written
|
|
1725
|
+
after the process died.
|
|
1726
|
+
a PAGE-LOAD marker (the web_navigation record \`stim web\` writes for each
|
|
1727
|
+
load of the page's top-level document) resets only the page's records,
|
|
1728
|
+
those with platform web. It is written when the load starts, so a
|
|
1729
|
+
failure logged in the same millisecond belongs to that load, and so does
|
|
1730
|
+
anything the old page logs before it is replaced. Until the first page
|
|
1731
|
+
load is logged, the page's records follow the launch windows.
|
|
1421
1732
|
A finished bundle is not evidence that the app which loaded it is fine.
|
|
1422
1733
|
In the field case the app threw at 16:03:54 and Metro wrote its marker at
|
|
1423
1734
|
16:03:55, one second later, because the bundler finishes accounting for a
|
|
@@ -1438,11 +1749,18 @@ FLAGS
|
|
|
1438
1749
|
not stack depth. For untouched captured records use:
|
|
1439
1750
|
stim logs --source all --json
|
|
1440
1751
|
Neither form can restore text the runtime truncated before capture.
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1752
|
+
With --errors, an Expo error includes the code frame and stack lines Expo
|
|
1753
|
+
printed after it, in human and --json output, with or without --follow.
|
|
1754
|
+
Stim's own Metro records that land between those lines, such as bundle
|
|
1755
|
+
responses, do not cut the stack short. Human output joins the lines to the
|
|
1756
|
+
message. --json leaves msg as captured and adds them to the error record as
|
|
1757
|
+
a context array of strings; each record is still one line. --follow holds an
|
|
1758
|
+
Expo error until a poll, about every 500 ms, adds no more of its lines, so
|
|
1759
|
+
it can print up to about a second after Expo does. Non-follow human output
|
|
1760
|
+
also shows bare React Native symbolication as separate context, because
|
|
1761
|
+
Metro does not provide an error correlation identifier. Context never
|
|
1762
|
+
changes the error count or adds records to --json. --json is never capped,
|
|
1763
|
+
and neither is an explicit --tail.
|
|
1446
1764
|
|
|
1447
1765
|
In --follow mode the marker window is dropped -- every error arriving from
|
|
1448
1766
|
then on is by definition after the last marker seen.
|
|
@@ -1464,6 +1782,10 @@ THE RECORD
|
|
|
1464
1782
|
A collector_clock warning then says timestamps retain device time.
|
|
1465
1783
|
raw true when the level was inferred from a line of text rather than
|
|
1466
1784
|
reported by the producer (every expo-child record)
|
|
1785
|
+
context --errors --json only: the code frame and stack lines Expo
|
|
1786
|
+
printed after this error, as an array of strings. Absent when
|
|
1787
|
+
there are none. Stim adds it at query time; it is not in the
|
|
1788
|
+
log files.
|
|
1467
1789
|
|
|
1468
1790
|
WHAT WRITES WHAT
|
|
1469
1791
|
metro.ndjson the bundler, in both supervisor modes
|
|
@@ -1479,7 +1801,8 @@ WHAT WRITES WHAT
|
|
|
1479
1801
|
is where a native crash that never reached JS shows up
|
|
1480
1802
|
-- and, on iOS, where every Apple framework running in
|
|
1481
1803
|
the app's process also logs. The proven noise sources
|
|
1482
|
-
are recorded at info rather than error
|
|
1804
|
+
are recorded at info rather than error (Synchronous
|
|
1805
|
+
URL loading diagnostics at warn); the rest is why
|
|
1483
1806
|
--errors leaves this source out unless asked. A VERIFIED
|
|
1484
1807
|
LAUNCH counts these records and prints one line:
|
|
1485
1808
|
|
|
@@ -1741,11 +2064,17 @@ Branch on the code, never on the message.`,
|
|
|
1741
2064
|
the source checkout, then warm again.`
|
|
1742
2065
|
},
|
|
1743
2066
|
STIM_BUILD_FAILED: {
|
|
1744
|
-
summary: "xcodebuild or gradle failed; the
|
|
2067
|
+
summary: "xcodebuild or gradle failed; the Android missing-SDK and APK refusals; a damaged compilation-cache object",
|
|
1745
2068
|
body: () => `STIM_BUILD_FAILED
|
|
1746
2069
|
xcodebuild or gradle failed. The EXTRACTED diagnostics are printed (capped),
|
|
1747
2070
|
not the transcript. Read the log path on the next line for the rest.
|
|
1748
|
-
|
|
2071
|
+
Three Android refusals share this code without gradle itself failing:
|
|
2072
|
+
- NO ANDROID SDK, before gradle starts: nothing exists at the SDK path
|
|
2073
|
+
Stim resolves (ANDROID_HOME, else ANDROID_SDK_ROOT, else the default
|
|
2074
|
+
location), and there is no android/local.properties. Set ANDROID_HOME to the SDK or write sdk.dir
|
|
2075
|
+
into android/local.properties; \`stim doctor --platform android\` reports
|
|
2076
|
+
the same condition. When the SDK is found and neither variable is set,
|
|
2077
|
+
Stim passes its path to gradle as ANDROID_HOME.
|
|
1749
2078
|
- MORE THAN ONE debug APK under android/app/build/outputs/apk and nothing
|
|
1750
2079
|
configured to pick one (a project with product flavors, several flavors
|
|
1751
2080
|
already built). Stim will not guess which flavor to install: the
|
|
@@ -2248,6 +2577,12 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2248
2577
|
\`gc --delete\`) and run \`stim ios\` again to create the requested model.
|
|
2249
2578
|
That loses the old sim's app state.
|
|
2250
2579
|
|
|
2580
|
+
"this project's sim runs iOS X, but --runtime asked for Y"
|
|
2581
|
+
The same refusal for an explicit \`--runtime\` that names another installed
|
|
2582
|
+
iOS version than the project's sim runs. Reap the sim the same way, or pass
|
|
2583
|
+
\`--slot <name>\` to create one on the requested runtime beside it. The
|
|
2584
|
+
ios.runtime setting alone never refuses; it applies at creation.
|
|
2585
|
+
|
|
2251
2586
|
"this project's emulator uses device profile X, but Y was requested"
|
|
2252
2587
|
The Android counterpart, from \`--device-profile\` or android.deviceProfile.
|
|
2253
2588
|
Reap the AVD the same way, or pass \`--slot <name>\` to create the requested
|
|
@@ -2428,10 +2763,11 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2428
2763
|
metro.publicUrl for an existing endpoint.`
|
|
2429
2764
|
},
|
|
2430
2765
|
STIM_RELOAD_AMBIGUOUS: {
|
|
2431
|
-
summary: "
|
|
2432
|
-
separator: "--- RELOAD CODES (`stim reload [ios|android]`) ---",
|
|
2766
|
+
summary: "more than one owned app or the owned Chrome is live; name the platform",
|
|
2767
|
+
separator: "--- RELOAD CODES (`stim reload [ios|android|web]`) ---",
|
|
2433
2768
|
body: () => `STIM_RELOAD_AMBIGUOUS
|
|
2434
|
-
|
|
2769
|
+
More than one of the owned iOS app, Android app and Chrome page is live.
|
|
2770
|
+
Name ios, android or web; Stim never guesses.`
|
|
2435
2771
|
},
|
|
2436
2772
|
STIM_RELOAD_RELEASE: {
|
|
2437
2773
|
summary: "the live app has embedded JS; run a Debug build first",
|
|
@@ -2444,7 +2780,10 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2444
2780
|
aliases: ["STIM_RELOAD_UNOWNED", "STIM_RELOAD_PROBE_FAILED"],
|
|
2445
2781
|
body: () => `STIM_RELOAD_STOPPED / STIM_RELOAD_UNOWNED / STIM_RELOAD_PROBE_FAILED
|
|
2446
2782
|
The recorded app is gone, its exact device is not live and owned by this
|
|
2447
|
-
workspace, or simctl/adb could not prove the process exists.
|
|
2783
|
+
workspace, or simctl/adb could not prove the process exists. For web,
|
|
2784
|
+
STOPPED means no owned Chrome is running (run stim web) and PROBE_FAILED
|
|
2785
|
+
that its identity could not be verified. A bare reload picks the Chrome page
|
|
2786
|
+
only when no native launch is recorded. No launch or
|
|
2448
2787
|
device lifecycle action is taken; follow the printed platform-command or
|
|
2449
2788
|
process-probe remedy.`
|
|
2450
2789
|
},
|
|
@@ -2476,6 +2815,51 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
2476
2815
|
MORE THAN ONE MATCHING PEER IS NOT A FAILURE. A workspace Metro serves one
|
|
2477
2816
|
app, so several matching peers are that app on several devices. Stim reloads
|
|
2478
2817
|
every one of them and reports the count in the facts as targets.`
|
|
2818
|
+
},
|
|
2819
|
+
STIM_WEB_NO_CHROME: {
|
|
2820
|
+
summary: "stim web found no installed Chrome or Chromium",
|
|
2821
|
+
separator: "--- WEB CODES (`stim web`) ---",
|
|
2822
|
+
body: () => `STIM_WEB_NO_CHROME
|
|
2823
|
+
stim web drives the installed Google Chrome (or Chromium) with a profile
|
|
2824
|
+
Stim creates. It looks in /Applications and ~/Applications on macOS, in
|
|
2825
|
+
Program Files on Windows, and for google-chrome or chromium on PATH. Stim
|
|
2826
|
+
never installs a browser. Install Chrome, then run stim doctor.`
|
|
2827
|
+
},
|
|
2828
|
+
STIM_WEB_NO_URL: {
|
|
2829
|
+
summary: "not an Expo app and web.url is unset, so Stim does not know which page to open",
|
|
2830
|
+
body: () => `STIM_WEB_NO_URL
|
|
2831
|
+
Only Expo serves web from Metro, so for any other app Stim needs web.url.
|
|
2832
|
+
stim web never starts a web server, for any framework. Start yours on a
|
|
2833
|
+
named port and point web.url at it:
|
|
2834
|
+
pnpm exec vite --port "$(stim ports get web)" --strictPort
|
|
2835
|
+
stim settings set web.url 'http://localhost:{port:web}/' --scope workspace
|
|
2836
|
+
See stim guide web.`
|
|
2837
|
+
},
|
|
2838
|
+
STIM_WEB_DEPS_MISSING: {
|
|
2839
|
+
summary: "an Expo app without react-native-web cannot render on the web",
|
|
2840
|
+
body: () => `STIM_WEB_DEPS_MISSING
|
|
2841
|
+
The Expo app does not resolve react-native-web, so Metro cannot build a web
|
|
2842
|
+
bundle. Install the web dependencies, start Metro, then run stim web again:
|
|
2843
|
+
npx expo install react-dom react-native-web @expo/metro-runtime
|
|
2844
|
+
stim start`
|
|
2845
|
+
},
|
|
2846
|
+
STIM_WEB_BROWSER_HELD: {
|
|
2847
|
+
summary: "the previous owned Chrome could not be stopped or verified; it was left running",
|
|
2848
|
+
body: () => `STIM_WEB_BROWSER_HELD
|
|
2849
|
+
stim web replaces the workspace's owned Chrome when its options change, and
|
|
2850
|
+
the previous one could not be stopped: its supervisor or Chrome did not
|
|
2851
|
+
exit, or their process identities could not be verified. Stim never signals
|
|
2852
|
+
a process it cannot verify. Check stim status for browser-unverified, then
|
|
2853
|
+
follow stim guide errors teardown.`
|
|
2854
|
+
},
|
|
2855
|
+
STIM_WEB_LAUNCH_FAILED: {
|
|
2856
|
+
summary: "the owned Chrome did not start or did not open DevTools on its reserved port",
|
|
2857
|
+
body: () => `STIM_WEB_LAUNCH_FAILED
|
|
2858
|
+
The browser supervisor exited before Chrome answered on its reserved
|
|
2859
|
+
DevTools port. The remedy names the supervisor log; web.ndjson carries the
|
|
2860
|
+
failure as web_browser_failed, and browser.log holds Chrome's own output.
|
|
2861
|
+
A port another process bound first also lands here: run stim web again to
|
|
2862
|
+
reserve a fresh one.`
|
|
2479
2863
|
},
|
|
2480
2864
|
STIM_WORKTREE_REMOVAL_IN_PROGRESS: {
|
|
2481
2865
|
summary: "a managed remote start found worktree remove holding the lock; wait, then rerun",
|
|
@@ -2574,7 +2958,11 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2574
2958
|
ios.deviceType, ios.runtime, android.systemImage or android.deviceProfile
|
|
2575
2959
|
setting is checked the same way, and the check applies
|
|
2576
2960
|
even when this workspace ALREADY owns a device, so a name that could never
|
|
2577
|
-
create anything is caught rather than left to a later run.
|
|
2961
|
+
create anything is caught rather than left to a later run. The
|
|
2962
|
+
\`pixel_fold\` and \`resizable\` profiles on a system image without
|
|
2963
|
+
foldable support (SupportPixelFold in its advancedFeatures.ini) refuse the
|
|
2964
|
+
same way, since the emulator quits on boot; the remedy names an installed
|
|
2965
|
+
image that has it, or an sdkmanager install when none does.
|
|
2578
2966
|
\`gc --json --cache <name>\` refuses with STIM_BAD_ARG when no shared cache
|
|
2579
2967
|
carries the name; the remedy names the caches on this machine. \`gc\`
|
|
2580
2968
|
refuses --cache together with --worktrees the same way.
|
|
@@ -2643,9 +3031,17 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2643
3031
|
summary: "a lock held past the wait; workspace-process and short directory locks",
|
|
2644
3032
|
body: () => `STIM_LOCK_TIMEOUT
|
|
2645
3033
|
The same locks, held by an ordinary command that is still running, for
|
|
2646
|
-
longer than the wait -- 60s by default, 4 minutes for the remote-session
|
|
2647
|
-
|
|
2648
|
-
|
|
3034
|
+
longer than the wait -- 60s by default, 4 minutes for the remote-session lock
|
|
3035
|
+
and for \`gc\` deleting EAS sessions under the EAS project lock (its sweep
|
|
3036
|
+
skips at once while that lock is held), and ~90 minutes for the \`worktree warm\` lock, which one
|
|
3037
|
+
\`--refresh\` can hold for a whole dependency install. The machine-wide EAS
|
|
3038
|
+
project lock admits one EAS session start at a time. A \`--remote eas\` run
|
|
3039
|
+
waits on it after its build with no overall limit, printing \`lock waiting
|
|
3040
|
+
for EAS remote start (pid 41233, in <workspace>, running for 1m12s) to
|
|
3041
|
+
release the EAS project lock\` at once and \`still waiting for ...\` every 30
|
|
3042
|
+
seconds. It refuses only when one holder has held the lock for longer than
|
|
3043
|
+
the slowest EAS session start (39 minutes), naming that pid.
|
|
3044
|
+
The \`worktree warm\` wait prints its
|
|
2649
3045
|
elapsed waiting time and holder every 30 seconds (\`lock waiting 40s
|
|
2650
3046
|
for stim worktree warm --refresh (pid 41233)\`) and the refusal names the same holder
|
|
2651
3047
|
and the lock directory under ~/.stim/warm-locks.
|
|
@@ -2658,8 +3054,10 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2658
3054
|
"Timed out waiting for the lock at <path>."
|
|
2659
3055
|
Short directory locks serialize writes to config, workspace state, device
|
|
2660
3056
|
leases, ownership records, metadata, and cache manifests. The path identifies
|
|
2661
|
-
the lock. These locks wait up to 12s and never expire based on age.
|
|
2662
|
-
|
|
3057
|
+
the lock. These locks wait up to 12s and never expire based on age. When
|
|
3058
|
+
another Stim command holds the lock, the message says so: wait for it and
|
|
3059
|
+
retry. A failed marker write, such as ENOSPC on a full disk, removes the
|
|
3060
|
+
directory it just created before Stim reports the write error.
|
|
2663
3061
|
Short locks use the same process-identity claims as long operations, stored
|
|
2664
3062
|
beside the visible directory at <path>.claims. An opaque marker in the visible
|
|
2665
3063
|
directory also excludes older Stim versions. Only the exclusive claim holder
|
|
@@ -2669,9 +3067,12 @@ captured" (in metro.ndjson, bare RN)
|
|
|
2669
3067
|
STIM_CLAIM_REFUSED and names the claim to inspect; an unavailable native
|
|
2670
3068
|
identity reports STIM_CLAIM_UNAVAILABLE without running the protected work.
|
|
2671
3069
|
Older lock directories have no process identity. A visible directory left
|
|
2672
|
-
empty before marker publication
|
|
2673
|
-
|
|
2674
|
-
|
|
3070
|
+
empty before marker publication (a process killed between creating it and
|
|
3071
|
+
writing its marker) or during final removal also cannot prove it is free.
|
|
3072
|
+
These paths still time out, and the message says no current Stim holds the
|
|
3073
|
+
lock and ends with \`rm -rf '<path>'\`. An older Stim version may still be
|
|
3074
|
+
using it: if none is running, remove the named directory with that command.
|
|
3075
|
+
Standalone Metro and Expo cache packages use the
|
|
2675
3076
|
same core protocol and do not require the Stim CLI.`
|
|
2676
3077
|
},
|
|
2677
3078
|
teardown: {
|
|
@@ -2708,7 +3109,23 @@ the supervisor could not be verified" (stop)
|
|
|
2708
3109
|
"teardown failed: <reason>"
|
|
2709
3110
|
Stim could not release the owned device and keeps its record for a retry.
|
|
2710
3111
|
\`worktree remove\` exits 1 without removing the worktree while the device is
|
|
2711
|
-
still tracked. Fix the reported cause and re-run
|
|
3112
|
+
still tracked. Fix the reported cause and re-run.
|
|
3113
|
+
|
|
3114
|
+
"teardown failed: Owned AVD <name> did not finish shutting down after <n>s:
|
|
3115
|
+
emulator process <pid> is still running"
|
|
3116
|
+
An owned emulator counts as stopped only when no process launched for its
|
|
3117
|
+
AVD (\`qemu-system-*\` or \`emulator\` with \`-avd <name>\`) is left in the
|
|
3118
|
+
process table. Stim asks it to quit with \`adb emu kill\` and waits 60s.
|
|
3119
|
+
Then it sends SIGTERM and, 5s later, SIGKILL. When adb cannot reach the
|
|
3120
|
+
emulator, Stim sends SIGTERM at once and waits 60s before SIGKILL. It signals
|
|
3121
|
+
only a pid whose command line names the AVD and whose process identity,
|
|
3122
|
+
recorded before shutdown, still matches. "(Stim could not verify the
|
|
3123
|
+
identity of <pid>, so it sent no signal)" means that identity could not be
|
|
3124
|
+
read or no longer matches. Check \`ps -p <pid> -o command=\`, stop the
|
|
3125
|
+
process yourself, then re-run the command or \`gc --delete\`. Windows has
|
|
3126
|
+
no process-table check and Stim signals nothing there: it waits for the pid
|
|
3127
|
+
in the AVD's process lock after \`adb emu kill\`, and refuses at once when
|
|
3128
|
+
adb cannot reach the emulator.`
|
|
2712
3129
|
},
|
|
2713
3130
|
remove: {
|
|
2714
3131
|
summary: "worktree remove refused a dirty tree: what it restores itself and what --force discards",
|
|
@@ -3111,13 +3528,13 @@ ANDROID EMULATOR RESTARTS
|
|
|
3111
3528
|
started is alive. Stim keeps waiting on the same emulator; it never
|
|
3112
3529
|
launches a duplicate. See \`stim guide errors STIM_NO_DEVICE\` for the
|
|
3113
3530
|
wait windows, diagnostics, and recovery steps.
|
|
3114
|
-
On macOS,
|
|
3115
|
-
boots owned emulators without a window and shows them in Stim
|
|
3116
|
-
guide settings. An emulator that is already running keeps its current
|
|
3531
|
+
On macOS, androidEmulatorApp "stim-desktop", the default while Stim Desktop
|
|
3532
|
+
is installed, boots owned emulators without a window and shows them in Stim
|
|
3533
|
+
Desktop; see guide settings. An emulator that is already running keeps its current
|
|
3117
3534
|
display until it next boots.
|
|
3118
3535
|
|
|
3119
3536
|
DESTRUCTIVE COMMANDS -- ask the user first
|
|
3120
|
-
gc --delete deletes orphaned devices Stim created, tens of GB
|
|
3537
|
+
gc --delete deletes orphaned devices this Stim home created, tens of GB
|
|
3121
3538
|
gc --delete --cache all empties the shared build caches every project uses
|
|
3122
3539
|
gc --delete --cache <name>
|
|
3123
3540
|
empties only the caches that carry <name>
|
|
@@ -3170,8 +3587,10 @@ WAITING FOR A CHANGE
|
|
|
3170
3587
|
status payload per line: one at once, then one each time the payload
|
|
3171
3588
|
changes, never two identical ones in a row. It reacts to Stim state files,
|
|
3172
3589
|
the EAS session ledger, adb device arrivals and departures, and simulator
|
|
3173
|
-
state, and recomputes every 30 seconds as a fallback.
|
|
3174
|
-
|
|
3590
|
+
state, and recomputes every 30 seconds as a fallback. A log append updates
|
|
3591
|
+
only the log error count and device activity, no sooner than 15 seconds
|
|
3592
|
+
after the previous refresh. Ctrl+C, SIGTERM or closing its stdout ends it
|
|
3593
|
+
with exit 0. Without --json it reprints the human view on change.`,
|
|
3175
3594
|
sections: {
|
|
3176
3595
|
eas: {
|
|
3177
3596
|
summary: "download a matching EAS development build; explicit profile, costs, cache and miss remedies",
|
|
@@ -3657,7 +4076,11 @@ PREDICTING THE NEXT BUILD (--plan)
|
|
|
3657
4076
|
the cache.provider tier into a temporary directory the plan removes, the
|
|
3658
4077
|
app config's provider wherever it keeps its downloads, as during a run.
|
|
3659
4078
|
On a miss it adds the prebuild decision the run would make (generate,
|
|
3660
|
-
regenerate, none, or refuse with STIM_PREBUILD_FAILED)
|
|
4079
|
+
regenerate, none, or refuse with STIM_PREBUILD_FAILED) and, with cache
|
|
4080
|
+
reads on, the miss reason the run would print, such as "native dependency
|
|
4081
|
+
added: expo-clipboard". A plan never prebuilds, so when the run would and a
|
|
4082
|
+
baseline exists, the reason's kind is prebuild-pending and it compares the
|
|
4083
|
+
fingerprint before that prebuild. With --eas-profile it asks EAS for a matching
|
|
3661
4084
|
build (config, fingerprint:generate, build:list) and downloads nothing.
|
|
3662
4085
|
expectedMs is the median of this project's recorded runs with that outcome;
|
|
3663
4086
|
the payload is in \`guide facts plan\`.
|
|
@@ -3895,7 +4318,10 @@ THE BUILD CACHE HAS THREE LEVELS
|
|
|
3895
4318
|
records the reason as lastBuilds.<platform>.missReason in status --json
|
|
3896
4319
|
(see \`guide facts status\`), and writes the changed sources (capped at 20
|
|
3897
4320
|
names) to the build log as a fingerprint_diff record. With no baseline the
|
|
3898
|
-
line says there was nothing to compare with.
|
|
4321
|
+
line says there was nothing to compare with. status --json also lists each
|
|
4322
|
+
platform's last 10 runs in builds.<platform>, with their result, cache
|
|
4323
|
+
outcome, miss reason, phase timings and diagnostics, so a hit that turned
|
|
4324
|
+
into a miss shows which run changed what.
|
|
3899
4325
|
|
|
3900
4326
|
THE KEY CAN MOVE MID-RUN, and the run says so in two facts rather than two
|
|
3901
4327
|
explanations. \`expo prebuild\` and \`pod install\` rewrite fingerprinted
|
|
@@ -3932,11 +4358,28 @@ THE BUILD CACHE HAS THREE LEVELS
|
|
|
3932
4358
|
\`expo prebuild --clean\` yourself or delete the directory so the next build
|
|
3933
4359
|
regenerates it.
|
|
3934
4360
|
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
4361
|
+
Both platforms fingerprint once more after the compile. A change the build
|
|
4362
|
+
itself makes to a fingerprinted file under node_modules/ or the native
|
|
4363
|
+
directory moves the key the same way, printed as \`(after Gradle)\` or
|
|
4364
|
+
\`(after xcodebuild)\`. Any other input that changed while the build ran
|
|
4365
|
+
-- the app config or a config plugin at any point after the first lookup,
|
|
4366
|
+
or any other source during the compile -- means the artifact may not match
|
|
4367
|
+
the key, so Stim installs what it built and stores nothing. The one config
|
|
4368
|
+
change exempted is the ios.bundleIdentifier or android.package that
|
|
4369
|
+
\`expo prebuild\` adds to a static app.json that lacks one:
|
|
4370
|
+
|
|
4371
|
+
fingerprint expoConfig changed while the build ran, so the artifact may not match its key; the build will be installed but not cached
|
|
4372
|
+
|
|
4373
|
+
The prebuild record never takes a hash that includes the edit, so the next
|
|
4374
|
+
run regenerates a CNG directory from the edited config and compiles it
|
|
4375
|
+
instead of reusing the stale one. An edit under node_modules/ or the native
|
|
4376
|
+
directory during the compile cannot be told apart from the build's own
|
|
4377
|
+
writes and moves the key. Stim also skips storing when the fingerprint
|
|
4378
|
+
after prebuild, pod install or the compile cannot be computed. In every
|
|
4379
|
+
skipped case nothing goes to the local cache, the cache provider or a
|
|
4380
|
+
remote upload, fingerprint and cacheKey are null in the result and
|
|
4381
|
+
lastBuild, and the old key is not reused. These null fields mean
|
|
4382
|
+
unavailable cache information, not an install failure.
|
|
3940
4383
|
|
|
3941
4384
|
WHAT MAKES THE CACHE ACTUALLY HIT: .FINGERPRINTIGNORE
|
|
3942
4385
|
Every entry is keyed on what the tree hashes, so two workspaces share an
|
|
@@ -4357,13 +4800,22 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
4357
4800
|
(\`iOS 26.5\`), exactly; no prefix or suffix matches.
|
|
4358
4801
|
|
|
4359
4802
|
These flags describe a device that does not exist yet. When this workspace
|
|
4360
|
-
ALREADY owns a simulator and \`--device-type\` names a different model,
|
|
4361
|
-
Stim refuses rather than silently
|
|
4362
|
-
sim with \`stim worktree remove\`
|
|
4363
|
-
\`stim ios\` again to create the
|
|
4364
|
-
the same for an AVD of another
|
|
4365
|
-
one its own \`--slot\`.
|
|
4366
|
-
|
|
4803
|
+
ALREADY owns a simulator and \`--device-type\` names a different model, or
|
|
4804
|
+
\`--runtime\` a different iOS version, Stim refuses rather than silently
|
|
4805
|
+
booting the wrong one: reap the current sim with \`stim worktree remove\`
|
|
4806
|
+
(or \`stim gc --delete\`), then run \`stim ios\` again to create the
|
|
4807
|
+
requested one. \`--device-profile\` does the same for an AVD of another
|
|
4808
|
+
profile. To keep both devices, give the new one its own \`--slot\`. The
|
|
4809
|
+
ios.runtime and android.systemImage settings apply at creation only, so an
|
|
4810
|
+
existing device keeps the version it was made with. An explicit \`--system-image\` that
|
|
4811
|
+
names another image than this workspace's AVD refuses the same way, unless
|
|
4812
|
+
that AVD never finished a boot (for example one made from an image its
|
|
4813
|
+
profile cannot boot): Stim then deletes it through owned-device teardown and
|
|
4814
|
+
creates the requested one. \`--device-profile pixel_fold\` or
|
|
4815
|
+
\`resizable\` on a system image without foldable support (SupportPixelFold
|
|
4816
|
+
in its advancedFeatures.ini) refuses with STIM_BAD_ARG before anything is
|
|
4817
|
+
created, since the emulator quits on boot; the remedy names an installed
|
|
4818
|
+
image that has it.
|
|
4367
4819
|
The --json payload reports what was actually used: \`deviceType\` and
|
|
4368
4820
|
\`runtime\` on iOS, \`systemImage\` and \`deviceProfile\` on Android, read
|
|
4369
4821
|
from the device itself, so a settings-driven run reports them too.`
|
|
@@ -4723,9 +5175,10 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
4723
5175
|
boot (including the initial boot request) up to 10 minutes, and app installation
|
|
4724
5176
|
up to 5 minutes. Process termination confirmation can take another 10 seconds;
|
|
4725
5177
|
a final boot-state query can take 30 seconds. After boot, Stim opens the owned
|
|
4726
|
-
simulator in
|
|
4727
|
-
|
|
4728
|
-
|
|
5178
|
+
simulator in Stim Desktop while it is installed, otherwise in the selected
|
|
5179
|
+
Xcode's Device Hub on Xcode 27, or Simulator on older Xcode. Top-level
|
|
5180
|
+
iosSimulatorApp in the machine config can select another viewer; see guide
|
|
5181
|
+
settings. Override it for one
|
|
4729
5182
|
local run with \`stim ios --simulator-app siniulator\`,
|
|
4730
5183
|
\`--simulator-app stim-desktop\`, or \`--simulator-app xcode\`. This also
|
|
4731
5184
|
opens an already running owned simulator without rebooting it or saving the
|
|
@@ -4734,6 +5187,8 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
4734
5187
|
and takes at most 10 seconds. A timeout is not proof of an app crash or OOM.
|
|
4735
5188
|
During boot, Stim reports elapsed time, the simulator name, last boot output,
|
|
4736
5189
|
current pressure and the highest observed pressure roughly every 15 seconds.
|
|
5190
|
+
Warning or critical pressure adds recovery advice to the first report at
|
|
5191
|
+
that level; later reports repeat it only after the level changes.
|
|
4737
5192
|
Failure diagnostics retain the highest pressure and unavailable sample count;
|
|
4738
5193
|
they do not infer the cause of a timeout. Monitoring stops when boot ends.
|
|
4739
5194
|
Monitoring and timeout handling are best-effort: synchronous CLI work can
|
|
@@ -4745,7 +5200,11 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
4745
5200
|
|
|
4746
5201
|
If pressure is elevated, free host memory before retrying. Use \`stim stop\`
|
|
4747
5202
|
only in workspaces you own and have finished using; ask before closing other
|
|
4748
|
-
agents' simulators or heavy apps.
|
|
5203
|
+
agents' simulators or heavy apps. Never quit Device Hub or Simulator.app to
|
|
5204
|
+
free memory: on Xcode 27 (confirmed on 27A266a), quitting Device Hub by
|
|
5205
|
+
default shuts down every booted simulator on the machine, including ones it
|
|
5206
|
+
never opened a window for and ones other workspaces or agents are using.
|
|
5207
|
+
Rebooting a simulator under the same pressure
|
|
4749
5208
|
can repeat the stall. Consider fewer concurrent builds/devices (guide lifecycle
|
|
4750
5209
|
concurrency) and a reviewed SimSlim profile for future runs.`
|
|
4751
5210
|
}
|
|
@@ -4768,11 +5227,14 @@ WHAT RECLAIMS AN OWNED DEVICE
|
|
|
4768
5227
|
stim worktree remove parks eligible owned simulators and emulators
|
|
4769
5228
|
(\`guide lifecycle pool\`); deletes them when
|
|
4770
5229
|
parking is disabled or their setup cannot be verified
|
|
4771
|
-
stim gc --delete sweeps devices Stim created that no project
|
|
5230
|
+
stim gc --delete sweeps devices this Stim home created that no project
|
|
4772
5231
|
references (\`guide cleanup gc\`), clears
|
|
4773
5232
|
verified parked simulators and emulators, and
|
|
4774
5233
|
runs \`stim worktree remove\` on every clean,
|
|
4775
|
-
Stim-managed linked worktree whose branch is merged
|
|
5234
|
+
Stim-managed linked worktree whose branch is merged,
|
|
5235
|
+
or whose pull request was merged or closed, and
|
|
5236
|
+
that shows no activity within
|
|
5237
|
+
gc.worktreeGraceMinutes
|
|
4776
5238
|
stim gc --delete --older-than <days>
|
|
4777
5239
|
also reaps the device of a workspace no Stim
|
|
4778
5240
|
command has used in that long, even though the
|
|
@@ -4788,15 +5250,20 @@ WHAT RECLAIMS AN OWNED DEVICE
|
|
|
4788
5250
|
|
|
4789
5251
|
\`worktree remove\` and \`gc --delete\` are the only two commands that delete;
|
|
4790
5252
|
\`gc --delete\` deletes worktrees only through \`worktree remove\`. \`gc
|
|
4791
|
-
--delete\` also clears workspace build outputs
|
|
4792
|
-
orphaned workspace directories, never a
|
|
5253
|
+
--delete\` also clears workspace build outputs, trims oversized workspace logs
|
|
5254
|
+
(\`guide cleanup disk\`) and removes orphaned workspace directories, never a
|
|
5255
|
+
checkout. \`stim stop\` shuts a device
|
|
4793
5256
|
DOWN and leaves it assigned, which is what makes returning to a branch cost a
|
|
4794
5257
|
boot rather than a create, a provision and a reinstall.
|
|
4795
5258
|
|
|
4796
5259
|
Before shutting down, parking or deleting an owned device, Stim best-effort
|
|
4797
5260
|
closes local agent-device sessions bound to its exact iOS UDID or live Android
|
|
4798
|
-
serial.
|
|
4799
|
-
|
|
5261
|
+
serial. An Android session must also name the owned AVD, because the next
|
|
5262
|
+
emulator on a console port reuses its serial. \`stop\` closes a session only
|
|
5263
|
+
when agent-device's claim on the device names it and was taken inside this
|
|
5264
|
+
workspace; sessions from another workspace or claim stay open. Stim rechecks
|
|
5265
|
+
device ownership and uses agent-device's rejecting session target guard;
|
|
5266
|
+
sessions on other devices stay open. Physical devices are outside
|
|
4800
5267
|
this cleanup. agent-device is optional: a missing binary skips this step, and a
|
|
4801
5268
|
failed or timed-out list/close prints a device line on stderr while teardown
|
|
4802
5269
|
continues. Cleanup allows at most 15 seconds of agent-device calls per device.
|
|
@@ -4843,7 +5310,8 @@ SWEEPING FINISHED WORKTREES
|
|
|
4843
5310
|
Every \`gc\` without --cache looks at every registered project root and
|
|
4844
5311
|
every workspace.json root, grouped by git worktree, and reports each linked
|
|
4845
5312
|
worktree with the reason it is removed or kept. A worktree is finished when
|
|
4846
|
-
its branch is merged into the default branch
|
|
5313
|
+
its branch is merged into the default branch, or its pull request was
|
|
5314
|
+
merged or closed (PULL REQUESTS below). \`--worktrees\` also removes
|
|
4847
5315
|
one that is idle: no recorded use for --older-than days, 7 without it; a
|
|
4848
5316
|
worktree whose last use is unknown is kept. Both need the same clean state;
|
|
4849
5317
|
a worktree is kept when it is the source checkout, bare, locked, in use,
|
|
@@ -4852,6 +5320,27 @@ SWEEPING FINISHED WORKTREES
|
|
|
4852
5320
|
initialized submodules. Without --worktrees, the report leaves out the
|
|
4853
5321
|
source checkout and roots outside git.
|
|
4854
5322
|
|
|
5323
|
+
IN USE means its dev server supervisor runs, a stim ios, android or stop
|
|
5324
|
+
run holds its native-run lock, a live build lock or slot names it, a
|
|
5325
|
+
managed tunnel or remote lock is held, an owned simulator or emulator of
|
|
5326
|
+
the workspace is booted (an agent-device session needs one), or it holds
|
|
5327
|
+
an unexpired device lease. When the simulator or emulator list cannot be
|
|
5328
|
+
read, the worktree counts as in use. A device left booted keeps the
|
|
5329
|
+
worktree until \`stim stop\` in it, or \`gc --idle <duration>\`, shuts
|
|
5330
|
+
the device down.
|
|
5331
|
+
|
|
5332
|
+
RECENT ACTIVITY keeps a worktree gc would otherwise remove until
|
|
5333
|
+
gc.worktreeGraceMinutes (120 by default, \`guide settings\`) have passed
|
|
5334
|
+
since the latest of: a write to its git index, HEAD or HEAD reflog, a write
|
|
5335
|
+
to its Stim workspace state or log files, and, for a merged branch, the
|
|
5336
|
+
committer date of the commit that brought it into the default branch, or
|
|
5337
|
+
the time its pull request was merged or closed. That
|
|
5338
|
+
window is when an agent that just merged runs \`stim stop\` and \`stim
|
|
5339
|
+
worktree remove\` itself. The reason is recent-activity, and the report
|
|
5340
|
+
and the JSON eligibleAt field say when it becomes removable. When that
|
|
5341
|
+
activity cannot be read, the worktree is kept (reason activity-unknown).
|
|
5342
|
+
0 turns the grace period off.
|
|
5343
|
+
|
|
4855
5344
|
MERGED means, with the default branch taken from origin/HEAD, after a
|
|
4856
5345
|
\`git fetch origin <default>\` per repository (30s timeout, no credential
|
|
4857
5346
|
prompt; skipped when that checkout fetched in the last 10 minutes):
|
|
@@ -4864,24 +5353,42 @@ SWEEPING FINISHED WORKTREES
|
|
|
4864
5353
|
commit on the default branch (a rebase merge), or its whole diff since the
|
|
4865
5354
|
merge base has the same verbatim patch id as a commit there, compared on
|
|
4866
5355
|
the files the branch changes (a squash merge).
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
5356
|
+
From git alone, a squash merge whose content changed during the merge (a
|
|
5357
|
+
conflict resolution, a suggested edit, even whitespace) does not match, and
|
|
5358
|
+
neither does a fast-forwarded branch or a stacked pull request merged after
|
|
5359
|
+
the one below it; the pull request check covers those. When origin/HEAD is not set, the fetch fails, or git
|
|
4871
5360
|
cannot answer, the state is unknown and never counts as merged (reason
|
|
4872
5361
|
merge-unknown, with the remedy); with --worktrees an idle worktree is still
|
|
4873
5362
|
removed. A squash- or rebase-merged branch whose upstream is gone (deleted
|
|
4874
5363
|
after the merge and pruned locally) has commits only it reaches; they do
|
|
4875
5364
|
not block removal, because their change is on the default branch, and the
|
|
4876
5365
|
branch is kept.
|
|
5366
|
+
|
|
5367
|
+
PULL REQUESTS: gc runs one \`gh api graphql\` query per repository that
|
|
5368
|
+
asks for the 20 newest pull requests of each linked worktree's branch, as
|
|
5369
|
+
\`gh pr list --head <branch> --state all\` would, and for each worktree
|
|
5370
|
+
takes the pull request whose head is HEAD, else one whose head contains
|
|
5371
|
+
HEAD. A pull request whose head HEAD is past ("PR #12 merged, and HEAD has
|
|
5372
|
+
commits it does not"), one unrelated to HEAD (an older use of the branch
|
|
5373
|
+
name), and one from a fork do not count. A merged or closed one makes the worktree finished
|
|
5374
|
+
under the same clean state. Merged, its commits are kept on GitHub, so local
|
|
5375
|
+
commits whose remote branch was deleted do not block removal. Closed, they
|
|
5376
|
+
do: a closed pull request whose remote branch is gone keeps the worktree as
|
|
5377
|
+
unpushed. An open pull request never makes a worktree finished. When gh is
|
|
5378
|
+
not installed, not signed in, or fails, the JSON pullRequestUnknown field
|
|
5379
|
+
and the report say why, and gc judges from git alone. A detached HEAD is
|
|
5380
|
+
not looked up. \`stim worktree remove\` makes the same check when
|
|
5381
|
+
local-only commits alone would refuse the removal, and accepts a merged
|
|
5382
|
+
pull request whose head is or contains HEAD.
|
|
4877
5383
|
stim gc # report merged worktrees
|
|
4878
5384
|
stim gc --delete # remove them
|
|
4879
5385
|
stim gc --delete --worktrees --older-than 3 # also the clean idle ones
|
|
4880
5386
|
--cache with --worktrees is refused with STIM_BAD_ARG; run them separately.
|
|
4881
5387
|
With --delete it runs the \`stim worktree remove\` pipeline, never --force,
|
|
4882
5388
|
on each removable worktree. That pipeline re-inspects the worktree and
|
|
4883
|
-
re-checks use under the removal locks, and idleness
|
|
4884
|
-
or an unchanged HEAD for a merged one, then parks
|
|
5389
|
+
re-checks use and recent activity under the removal locks, and idleness
|
|
5390
|
+
for an idle worktree or an unchanged HEAD for a merged one, then parks
|
|
5391
|
+
devices through the same teardown and handles the
|
|
4885
5392
|
branch exactly as a manual \`stim worktree remove\`, which keeps the
|
|
4886
5393
|
checkout when its HEAD moves while devices are reclaimed. A worktree that
|
|
4887
5394
|
changed since the report is kept with the reason. A worktree that fails is
|
|
@@ -4941,15 +5448,16 @@ it. A record is what makes the device findable again, so it outlives a failed
|
|
|
4941
5448
|
teardown rather than turning it into an orphan.
|
|
4942
5449
|
|
|
4943
5450
|
WHICH stim-* DEVICES gc DELETES
|
|
4944
|
-
A \`stim-\`
|
|
4945
|
-
|
|
5451
|
+
A \`stim-\` name is not proof that this Stim home made a device: every
|
|
5452
|
+
STIM_HOME names its devices the same way. gc deletes an unreferenced device
|
|
5453
|
+
only when this home created it: the device is listed in
|
|
4946
5454
|
$STIM_HOME/created-devices.json, where Stim records every simulator and AVD
|
|
4947
|
-
it creates, or it predates that ledger and
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
disk.dataPartition.size Stim writes. gc lists any other stim-* device under
|
|
5455
|
+
it creates, or it predates that ledger and this home's config records it in
|
|
5456
|
+
the device pool or in a project as owned. gc lists any other stim-* device,
|
|
5457
|
+
including those another STIM_HOME created, under
|
|
4951
5458
|
"Unrecognized stim-* devices" with the command that deletes it
|
|
4952
|
-
(\`xcrun simctl delete <udid
|
|
5459
|
+
(\`xcrun simctl delete <udid>\`, \`avdmanager delete avd -n <name>\`, or
|
|
5460
|
+
\`rm -rf <dir>\` for AVD data with no registration), and
|
|
4953
5461
|
never runs it. Boot, shutdown and teardown re-check ownership by the same
|
|
4954
5462
|
rule, so a device that stops matching is left alone.
|
|
4955
5463
|
|
|
@@ -5018,6 +5526,26 @@ THE MIRROR IMAGE: A STALE DEVICE RECORD
|
|
|
5018
5526
|
at simctl or avdmanager, and the project keeps its entry, its label and its
|
|
5019
5527
|
Metro port. The next \`ios\` / \`android\` creates a fresh owned device.
|
|
5020
5528
|
|
|
5529
|
+
The ledger of devices Stim created (created-devices.json) keeps a
|
|
5530
|
+
simulator's UDID after the simulator is deleted outside Stim. \`gc\`
|
|
5531
|
+
reports such UDIDs under "Stale device ledger entries" when a complete
|
|
5532
|
+
simctl listing, unavailable simulators included, does not show them, and
|
|
5533
|
+
\`gc --delete\` forgets them under the ledger lock. If the listing fails,
|
|
5534
|
+
nothing is reported or forgotten, and like the device sweep it is skipped
|
|
5535
|
+
without a config or under a scoped STIM_HOME. UDIDs are never reused, so a
|
|
5536
|
+
forgotten entry cannot belong to a later simulator.
|
|
5537
|
+
|
|
5538
|
+
Android ledger entries are AVD names, and names are reused: another
|
|
5539
|
+
STIM_HOME can later create an AVD with the same name. \`gc\` reports an
|
|
5540
|
+
AVD name as stale only when \`emulator -list-avds\` answered, the first AVD
|
|
5541
|
+
root exists (a missing one may be an unmounted volume), no AVD root holds
|
|
5542
|
+
<name>.ini or <name>.avd, and no unfinished setup reserves the name.
|
|
5543
|
+
\`gc --delete\` takes that AVD's claim, then re-checks and forgets the name
|
|
5544
|
+
under the config and ledger locks, so a setup in progress or an AVD
|
|
5545
|
+
recreated since the report keeps its entry. A name reused before \`gc\`
|
|
5546
|
+
runs still counts as this home's; run \`gc\` after deleting a Stim AVD by
|
|
5547
|
+
hand.
|
|
5548
|
+
|
|
5021
5549
|
THE ONE CASE GC WILL NOT REAP
|
|
5022
5550
|
If the config is gone entirely (deleted ~/.stim, or a throwaway
|
|
5023
5551
|
STIM_HOME), gc cannot tell your stale devices from another config's LIVE
|
|
@@ -5084,7 +5612,7 @@ THE ONE CASE GC WILL NOT REAP
|
|
|
5084
5612
|
Wall-clock timestamps and command names are not ownership proof.`
|
|
5085
5613
|
},
|
|
5086
5614
|
disk: {
|
|
5087
|
-
summary: "disk usage, workspace build outputs, AVD and build-log sizes, the data partition, trimming the shared caches",
|
|
5615
|
+
summary: "disk usage, workspace build outputs and logs, AVD and build-log sizes, the data partition, trimming the shared caches",
|
|
5088
5616
|
body: () => `DISK
|
|
5089
5617
|
Logs, state, pidfiles and Xcode DerivedData are under the global workspace
|
|
5090
5618
|
directory, and \`worktree remove\` reclaims them. \`gc --delete\` clears the
|
|
@@ -5100,12 +5628,16 @@ THE ONE CASE GC WILL NOT REAP
|
|
|
5100
5628
|
disabled. The first boot and a boot after the emulator, system image, or AVD
|
|
5101
5629
|
settings change are cold, while later supported boots load the one automatic
|
|
5102
5630
|
snapshot saved on exit. \`stop\` waits for the emulator process and, when
|
|
5103
|
-
enabled, the snapshot save to finish.
|
|
5631
|
+
enabled, the snapshot save to finish. An emulator that ignores \`adb emu
|
|
5632
|
+
kill\` or is unreachable over adb is signalled once its identity is verified;
|
|
5633
|
+
one that still runs fails the teardown and keeps its record (see \`stim guide
|
|
5634
|
+
errors teardown\`).
|
|
5104
5635
|
New owned AVDs default to an 8 GiB data partition, though project settings can
|
|
5105
5636
|
change it. When enabled, Quick Boot keeps one automatic snapshot until the AVD is
|
|
5106
5637
|
parked or deleted.
|
|
5107
5638
|
\`gc\` prints the on-disk size beside an orphaned or stale owned Android AVD
|
|
5108
|
-
when its content directory can be read
|
|
5639
|
+
when its content directory can be read, and beside an orphaned or stale
|
|
5640
|
+
owned simulator the data size simctl reports for it.
|
|
5109
5641
|
|
|
5110
5642
|
So are the logs, and one of them is not small: build-ios.ndjson /
|
|
5111
5643
|
build-android.ndjson hold the whole xcodebuild or gradle transcript at debug
|
|
@@ -5154,6 +5686,19 @@ WORKSPACE BUILD OUTPUTS
|
|
|
5154
5686
|
React Native 0.86 Swift does not use it (explicit modules are off), so that
|
|
5155
5687
|
build recompiles Swift.
|
|
5156
5688
|
|
|
5689
|
+
WORKSPACE LOGS
|
|
5690
|
+
\`gc\` reports the size of each workspace's logs/ (the workspaceLogs
|
|
5691
|
+
section of \`gc --json\`). metro.ndjson, client.ndjson and device.ndjson and
|
|
5692
|
+
their .1 generations rotate at 8 MiB (\`guide logs\`), but a file written by
|
|
5693
|
+
a Stim version before the cap can be hundreds of MB. \`gc --delete\` trims
|
|
5694
|
+
each of those six files that is over 16 MiB to its newest 8 MiB, cut at a
|
|
5695
|
+
record boundary; a file just past 8 MiB is normal rotation and stays.
|
|
5696
|
+
\`--older-than\` does not limit it. It skips a workspace that is in use (a
|
|
5697
|
+
dev server, a native run, a build or a held tunnel) or that has a device
|
|
5698
|
+
log collector recorded; \`stim stop\`
|
|
5699
|
+
stops the collector. Build transcripts keep the whole run and are never
|
|
5700
|
+
trimmed, and nothing else under logs/ is touched.
|
|
5701
|
+
|
|
5157
5702
|
SHARED BUILD CACHES
|
|
5158
5703
|
The caches that make a second workspace fast are alive by design and never
|
|
5159
5704
|
included in a plain \`gc --delete\`. Every \`gc\` run reports them anyway,
|
|
@@ -5202,7 +5747,9 @@ shape, before anything is written. Writes to the machine file take its lock
|
|
|
5202
5747
|
and replace it atomically; a committed write keeps the file's other keys and
|
|
5203
5748
|
indentation. Run \`stim settings\` from the app directory: workspace and
|
|
5204
5749
|
committed resolve from the nearest package.json, repo from its Git
|
|
5205
|
-
repository.
|
|
5750
|
+
repository. From a monorepo web package that resolves to its worktree's app
|
|
5751
|
+
(see stim guide ports), workspace and committed are that app's entry and
|
|
5752
|
+
.stim.json. worktree.exclude and worktree.defaultBranch are read only from
|
|
5206
5753
|
the repo layer and the repository root's .stim.json.
|
|
5207
5754
|
|
|
5208
5755
|
android.keystorePassword is sensitive: its value prints as ******** in every
|
|
@@ -5332,6 +5879,12 @@ KEYS STIM READS
|
|
|
5332
5879
|
profile. When this workspace already owns an AVD of
|
|
5333
5880
|
another profile, a requested profile refuses rather
|
|
5334
5881
|
than booting it; reap the AVD to create the new one.
|
|
5882
|
+
"pixel_fold" and "resizable" need a system image
|
|
5883
|
+
whose advancedFeatures.ini turns on SupportPixelFold
|
|
5884
|
+
(recent images such as API 34 google_apis do); the
|
|
5885
|
+
emulator quits on boot without it, so Stim refuses
|
|
5886
|
+
the pair with
|
|
5887
|
+
STIM_BAD_ARG and names an installed image that has it.
|
|
5335
5888
|
Existing AVDs keep their display settings; parked AVDs
|
|
5336
5889
|
from the old generic profile are not adopted.
|
|
5337
5890
|
android.dataPartitionSizeGb
|
|
@@ -5360,6 +5913,10 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
5360
5913
|
keys are protected. The emulator may normalize a valid
|
|
5361
5914
|
value. These overrides apply only to a newly created
|
|
5362
5915
|
AVD; existing and recovered AVDs are never rewritten.
|
|
5916
|
+
Unless these settings set hw.keyboard, every AVD Stim
|
|
5917
|
+
creates gets hw.keyboard=yes, so the emulator takes
|
|
5918
|
+
gRPC key events. The one rewrite: a parked AVD created
|
|
5919
|
+
before that default gets it when a workspace adopts it.
|
|
5363
5920
|
On displayless Linux, Stim launches with
|
|
5364
5921
|
-gpu swiftshader_indirect -noaudio; those arguments
|
|
5365
5922
|
override hw.gpu.enabled, hw.gpu.mode, hw.audioInput,
|
|
@@ -5442,6 +5999,21 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
5442
5999
|
driven. Read
|
|
5443
6000
|
when \`start\` spawns the supervisor; see
|
|
5444
6001
|
\`guide metro\`.
|
|
6002
|
+
web.url the page \`stim web\` opens in the owned Chrome, an
|
|
6003
|
+
http:// or https:// URL. {port:<label>} becomes the
|
|
6004
|
+
workspace's named port (allocated like \`stim ports
|
|
6005
|
+
get <label>\`), and {port:metro} its Metro port.
|
|
6006
|
+
Unset, Expo apps open http://localhost:<metroPort>/
|
|
6007
|
+
and other apps refuse until it is set. Example:
|
|
6008
|
+
http://localhost:{port:web}/apps/groups/.
|
|
6009
|
+
See \`guide web\`.
|
|
6010
|
+
web.ignoreCertificateErrors
|
|
6011
|
+
true starts the owned Chrome with
|
|
6012
|
+
--ignore-certificate-errors, for dev servers with
|
|
6013
|
+
self-signed certificates (default false). It applies
|
|
6014
|
+
only to Stim's own profile, never to your browser.
|
|
6015
|
+
web.viewport desktop (default, 1280x800) or phone (390x844 at 3x
|
|
6016
|
+
with touch events) for the owned Chrome page.
|
|
5445
6017
|
worktree.exclude ignored-path skip list for worktree warm. Settings
|
|
5446
6018
|
come from the source checkout's repository-root
|
|
5447
6019
|
.stim.json. A nonempty .worktreeexclude in the source
|
|
@@ -5484,7 +6056,7 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
|
|
|
5484
6056
|
them from the environment or the machine layers.
|
|
5485
6057
|
|
|
5486
6058
|
Each setting takes its documented type: string, array of strings, number,
|
|
5487
|
-
boolean, or object. ios.remote, android.remote, metro.tunnel,
|
|
6059
|
+
boolean, or object. ios.remote, android.remote, metro.tunnel, web.viewport,
|
|
5488
6060
|
optimizations.android.compilerCache and optimizations.android.pch take only
|
|
5489
6061
|
their listed choices. A value of the wrong
|
|
5490
6062
|
type or outside those choices is refused by name on every command that resolves
|
|
@@ -5543,8 +6115,13 @@ STIM_BAD_ARG. See \`guide lifecycle budget\` for what each limit reclaims.
|
|
|
5543
6115
|
THE IOS SIMULATOR APP IS MACHINE-LEVEL
|
|
5544
6116
|
Top-level \`iosSimulatorApp\` in ~/.stim/config.json selects the macOS app that
|
|
5545
6117
|
displays Stim's owned local iOS simulator after boot. It is not a project
|
|
5546
|
-
setting. Unset
|
|
5547
|
-
|
|
6118
|
+
setting. Unset, it is \`"stim-desktop"\` while Stim Desktop is installed and
|
|
6119
|
+
\`"xcode"\` otherwise. \`"xcode"\` opens the selected Xcode's Device Hub on Xcode 27,
|
|
6120
|
+
or Simulator on older Xcode. On Xcode 27 (confirmed on 27A266a), quitting
|
|
6121
|
+
Device Hub by default shuts down every booted simulator on the machine,
|
|
6122
|
+
including ones it never opened a window for and ones other workspaces or
|
|
6123
|
+
agents are using; never quit it to free memory or clean up. To use an
|
|
6124
|
+
installed Siniulator instead:
|
|
5548
6125
|
|
|
5549
6126
|
{ "iosSimulatorApp": "siniulator" }
|
|
5550
6127
|
|
|
@@ -5554,6 +6131,10 @@ To show the booted simulator in Stim Desktop and open no simulator window:
|
|
|
5554
6131
|
|
|
5555
6132
|
Stim Desktop selects the workspace that owns the simulator and focuses that
|
|
5556
6133
|
device. It only displays the simulator; it never boots or shuts it down.
|
|
6134
|
+
When Stim Desktop is not running, Stim starts it without the command's
|
|
6135
|
+
\`STIM_HOME\`, so it reads the same Stim home as when you open it yourself.
|
|
6136
|
+
It shows only devices from that home: under another \`STIM_HOME\`, pick
|
|
6137
|
+
\`--simulator-app xcode\` to see the simulator.
|
|
5557
6138
|
|
|
5558
6139
|
Override the preference for one local launch with
|
|
5559
6140
|
\`stim ios --simulator-app siniulator\`, \`stim ios --simulator-app stim-desktop\`,
|
|
@@ -5570,9 +6151,10 @@ window behavior.
|
|
|
5570
6151
|
|
|
5571
6152
|
THE ANDROID EMULATOR APP IS MACHINE-LEVEL
|
|
5572
6153
|
Top-level \`androidEmulatorApp\` in ~/.stim/config.json selects how an owned
|
|
5573
|
-
Android emulator that Stim boots on macOS is displayed. Unset
|
|
5574
|
-
\`"
|
|
5575
|
-
|
|
6154
|
+
Android emulator that Stim boots on macOS is displayed. Unset, it is
|
|
6155
|
+
\`"stim-desktop"\` while Stim Desktop is installed and \`"emulator"\`
|
|
6156
|
+
otherwise. \`"emulator"\` opens the emulator's own window. To boot it
|
|
6157
|
+
headlessly and show it in Stim Desktop:
|
|
5576
6158
|
|
|
5577
6159
|
{ "androidEmulatorApp": "stim-desktop" }
|
|
5578
6160
|
|
|
@@ -5581,8 +6163,17 @@ Stim then starts the emulator with \`-no-window -gpu host\` and opens
|
|
|
5581
6163
|
frames and sends input over the emulator's gRPC endpoint. The setting applies
|
|
5582
6164
|
only when Stim boots the emulator: one that is already running keeps its
|
|
5583
6165
|
current display until it next boots, and physical devices are unaffected.
|
|
5584
|
-
|
|
5585
|
-
|
|
6166
|
+
Like the iOS viewer, it starts Stim Desktop without the command's
|
|
6167
|
+
\`STIM_HOME\`. An invalid value refuses before boot. On Linux and Windows the
|
|
6168
|
+
setting has no effect.
|
|
6169
|
+
|
|
6170
|
+
Stim finds Stim Desktop by its bundle id, dev.stim.desktop, in Launch Services.
|
|
6171
|
+
A command Stim Desktop runs skips that lookup: Desktop sets \`STIM_DESKTOP_APP\`
|
|
6172
|
+
to its app path for every command it starts.
|
|
6173
|
+
\`stim settings\` shows that default as \`(default: Stim Desktop installed)\`,
|
|
6174
|
+
\`settings get\` prints it on stderr, and \`--json\` adds
|
|
6175
|
+
\`"defaultReason": "Stim Desktop installed"\`. A set value always wins; set
|
|
6176
|
+
\`"xcode"\` or \`"emulator"\` to keep the device windows.
|
|
5586
6177
|
|
|
5587
6178
|
THE DEVICE POOL BOUNDS ARE MACHINE-LEVEL TOO
|
|
5588
6179
|
\`pool.iosParkedMax\` caps how many parked simulators \`worktree remove\` may
|
|
@@ -5614,6 +6205,22 @@ test suites and the end-to-end harness use one -- and a scoped config must not
|
|
|
5614
6205
|
leave simulators on the machine it cannot account for. A redirected home that
|
|
5615
6206
|
wants a pool says so with the variable.
|
|
5616
6207
|
|
|
6208
|
+
THE GC WORKTREE GRACE PERIOD IS MACHINE-LEVEL
|
|
6209
|
+
\`gc.worktreeGraceMinutes\` is how long \`gc --delete\` waits before it removes
|
|
6210
|
+
a merged or idle linked worktree. The clock starts at the worktree's latest
|
|
6211
|
+
activity: a write to its git index, HEAD or HEAD reflog, its Stim workspace
|
|
6212
|
+
state or logs, the merge of its branch into the default branch, or when its
|
|
6213
|
+
pull request was merged or closed.
|
|
6214
|
+
|
|
6215
|
+
{
|
|
6216
|
+
"gc": { "worktreeGraceMinutes": 120 }
|
|
6217
|
+
}
|
|
6218
|
+
|
|
6219
|
+
in ~/.stim/config.json, or STIM_GC_WORKTREE_GRACE_MINUTES in the environment,
|
|
6220
|
+
which overrides the file. Absent means 120. \`0\` removes a finished worktree at
|
|
6221
|
+
once. A value that is not a whole number 0 or more is warned about by \`gc\`,
|
|
6222
|
+
which then uses 120. See \`guide cleanup\` for what else keeps a worktree.
|
|
6223
|
+
|
|
5617
6224
|
STIM NEEDS NO PROJECT CHANGES TO RUN
|
|
5618
6225
|
Nothing above is required to use Stim. The performance caches that used to
|
|
5619
6226
|
be setup steps are supplied by Stim on the command lines it composes itself:
|
|
@@ -5841,6 +6448,176 @@ platform instead of one entry. Pass prune: 'atomic' for a cache whose index
|
|
|
5841
6448
|
references its own data (an LLVM CAS): it is then left alone by --older-than
|
|
5842
6449
|
and emptied whole only by 'gc --delete --cache all'.
|
|
5843
6450
|
Registration is idempotent and keyed on the directory.`
|
|
6451
|
+
},
|
|
6452
|
+
web: {
|
|
6453
|
+
summary: "stim web: an owned headless Chrome per workspace, its logs, launched, and teardown",
|
|
6454
|
+
body: () => `WEB: AN OWNED CHROME PER WORKSPACE
|
|
6455
|
+
|
|
6456
|
+
If Stim is not installed globally, replace stim with npx stim.
|
|
6457
|
+
|
|
6458
|
+
stim web opens this workspace's page in a Chrome that Stim owns, captures the
|
|
6459
|
+
page's console, uncaught errors and failed requests in stim logs, and reports
|
|
6460
|
+
whether the page loaded. It uses the installed Google Chrome (or Chromium)
|
|
6461
|
+
with a profile Stim creates under STIM_HOME. Stim never installs a browser;
|
|
6462
|
+
stim doctor reports a missing Chrome.
|
|
6463
|
+
|
|
6464
|
+
stim web never starts a web server, for any framework. It opens, reuses or
|
|
6465
|
+
reloads the owned Chrome at the page URL. Every web project follows the same
|
|
6466
|
+
two steps: start your dev server, then run stim web.
|
|
6467
|
+
|
|
6468
|
+
stim web # headless, the default
|
|
6469
|
+
stim web --headed # show the Chrome window
|
|
6470
|
+
stim web --json # one payload on stdout; progress on stderr
|
|
6471
|
+
stim logs --errors # page errors land here with platform "web"
|
|
6472
|
+
stim reload web # Page.reload on the owned page
|
|
6473
|
+
stim stop # closes Chrome with the rest; the profile stays
|
|
6474
|
+
|
|
6475
|
+
WHICH PAGE AND WHICH DEV SERVER
|
|
6476
|
+
|
|
6477
|
+
Expo web runs on the workspace's Metro. With web.url unset, an Expo app
|
|
6478
|
+
opens http://localhost:<metroPort>/. Its dev server is stim start:
|
|
6479
|
+
|
|
6480
|
+
npx expo install react-dom react-native-web @expo/metro-runtime # once
|
|
6481
|
+
stim start
|
|
6482
|
+
stim web
|
|
6483
|
+
|
|
6484
|
+
Any other web server (Vite, Next, webpack) starts with its own command.
|
|
6485
|
+
Reserve its port with stim ports get, start it with strict-port behavior, and
|
|
6486
|
+
point web.url at it. {port:<label>} in web.url becomes that named port,
|
|
6487
|
+
{port:metro} the Metro port:
|
|
6488
|
+
|
|
6489
|
+
pnpm exec vite --port "$(stim ports get web)" --strictPort
|
|
6490
|
+
stim settings set web.url 'http://localhost:{port:web}/' --scope workspace
|
|
6491
|
+
stim web
|
|
6492
|
+
|
|
6493
|
+
When nothing serves the page, stim web still opens Chrome, reports launched
|
|
6494
|
+
"unverified", and prints the remedy for this workspace: stim start for an
|
|
6495
|
+
Expo web app, the stim ports get web recipe for any other server. A Metro
|
|
6496
|
+
port held by another process is also "unverified", and the page it serves
|
|
6497
|
+
still reaches stim logs; stim start then reserves a free port for this
|
|
6498
|
+
workspace. When this workspace's supervisor is still recorded, run stim stop
|
|
6499
|
+
first.
|
|
6500
|
+
|
|
6501
|
+
In a monorepo whose web app is its own package (apps/web beside apps/mobile),
|
|
6502
|
+
stim ports, web, settings, logs, reload, stop and status run from the web
|
|
6503
|
+
package resolve to the one Stim app registered in the same Git worktree; each
|
|
6504
|
+
names the app on stderr, and status stars it. The port, the browser, web.url
|
|
6505
|
+
and the logs all belong to that app's workspace, so every command can run from
|
|
6506
|
+
the web package. Register the app first, from its directory. See stim guide
|
|
6507
|
+
ports for the exact rule.
|
|
6508
|
+
|
|
6509
|
+
HTTPS dev servers with a self-signed certificate, such as Vite with
|
|
6510
|
+
@vitejs/plugin-basic-ssl, fail with net::ERR_CERT_AUTHORITY_INVALID until
|
|
6511
|
+
web.ignoreCertificateErrors is true, which accepts the certificate in the
|
|
6512
|
+
owned profile only:
|
|
6513
|
+
stim settings set web.url 'https://localhost:{port:web}/' --scope workspace
|
|
6514
|
+
stim settings set web.ignoreCertificateErrors true --scope workspace
|
|
6515
|
+
An https:// URL on a plain HTTP server fails with ERR_SSL_PROTOCOL_ERROR, and
|
|
6516
|
+
an http:// URL on an HTTPS server with ERR_EMPTY_RESPONSE; the remedy line
|
|
6517
|
+
prints the settings command that switches the scheme. web.viewport phone
|
|
6518
|
+
gives the page a 390x844 touch screen at 3x instead of the 1280x800 desktop
|
|
6519
|
+
window. See stim guide settings.
|
|
6520
|
+
|
|
6521
|
+
MONOREPO RECIPE: A VITE PACKAGE WITH A BASE PATH AND HTTPS
|
|
6522
|
+
|
|
6523
|
+
apps/web runs Vite through its dev script, serves the app under /apps/groups/,
|
|
6524
|
+
and uses @vitejs/plugin-basic-ssl; apps/mobile is the Stim app. The flow is
|
|
6525
|
+
the same as for any web project: start the dev server, then run stim web.
|
|
6526
|
+
|
|
6527
|
+
cd apps/mobile && stim ports get web # registers the app; no Metro
|
|
6528
|
+
cd ../web
|
|
6529
|
+
stim settings set web.url 'https://localhost:{port:web}/apps/groups/' --scope repo
|
|
6530
|
+
stim settings set web.ignoreCertificateErrors true --scope repo
|
|
6531
|
+
pnpm dev --port "$(stim ports get web)" --strictPort # keep it running
|
|
6532
|
+
stim web
|
|
6533
|
+
stim logs --errors
|
|
6534
|
+
stim reload web
|
|
6535
|
+
stim stop # closes Chrome; stim ports stop web stops Vite
|
|
6536
|
+
stim worktree remove # in a linked worktree: Chrome, Vite and profile
|
|
6537
|
+
|
|
6538
|
+
The repo layer is shared by every worktree of the repository, so a new
|
|
6539
|
+
worktree skips the two settings lines; the certificate and scheme remedies
|
|
6540
|
+
print --scope workspace, which overrides it for one worktree only. Run ports
|
|
6541
|
+
get from the app directory before any ports or web command in the web
|
|
6542
|
+
package: a reservation made there first keeps the web package as its own
|
|
6543
|
+
workspace until you release it and stop. Pass --port and --strictPort
|
|
6544
|
+
through the dev script: Vite otherwise binds its config default and moves to
|
|
6545
|
+
the next free port when that one is taken. Put the base path in web.url: a
|
|
6546
|
+
path outside it can reach the dev server's proxy instead of the app. API
|
|
6547
|
+
calls the dev server proxies to a backend that is not running fail as device
|
|
6548
|
+
errors in stim logs --errors; the page still loads.
|
|
6549
|
+
|
|
6550
|
+
LAUNCHED
|
|
6551
|
+
|
|
6552
|
+
The web payload's launched keeps its native meaning, from evidence in the
|
|
6553
|
+
owned page rather than a shared port:
|
|
6554
|
+
true the page's document answered and its load event fired; on
|
|
6555
|
+
Metro, the page also fetched a web bundle
|
|
6556
|
+
"bundling" Metro was still building the web bundle when the check ended
|
|
6557
|
+
"unverified" the document failed (for example ERR_CONNECTION_REFUSED:
|
|
6558
|
+
the dev server is not running, or ERR_CERT_AUTHORITY_INVALID: a
|
|
6559
|
+
self-signed certificate), loaded without a Metro bundle, or
|
|
6560
|
+
did not finish: 20 seconds with no answer, 60 once a server
|
|
6561
|
+
other than Metro answered. The remedy line names the fix
|
|
6562
|
+
false is never produced. A page that loads and then throws is still launched
|
|
6563
|
+
true; read stim logs --errors.
|
|
6564
|
+
|
|
6565
|
+
A second stim web with the same options reuses the running Chrome and
|
|
6566
|
+
navigates it again. Changing --headed, web.viewport or the certificate
|
|
6567
|
+
setting restarts it.
|
|
6568
|
+
|
|
6569
|
+
LOGS
|
|
6570
|
+
|
|
6571
|
+
Records go to web.ndjson in the workspace log directory, all with
|
|
6572
|
+
platform "web":
|
|
6573
|
+
src client console calls at their level (console.error is error) and
|
|
6574
|
+
uncaught errors and rejections, with stack frames
|
|
6575
|
+
src device failed requests, which stim logs --errors includes: a failed
|
|
6576
|
+
page document is error whatever its
|
|
6577
|
+
status; another request's network failure or HTTP 5xx is
|
|
6578
|
+
error, a 4xx warn, a canceled request debug; browser messages such
|
|
6579
|
+
as CSP violations; the browser's own lifecycle
|
|
6580
|
+
Expo also prints web console calls on Metro ("Web LOG"), so they can appear
|
|
6581
|
+
twice: once from the page (client), once from Metro (metro, level info).
|
|
6582
|
+
Each load of the page's top-level document is a page-load marker: stim web,
|
|
6583
|
+
stim reload, and a reload or navigation the page makes itself. logs --errors
|
|
6584
|
+
and the status error count report the page's records (platform web) from the
|
|
6585
|
+
latest load only, the way Chrome DevTools clears its console when the page
|
|
6586
|
+
navigates. A page load does not hide the native app's errors, and an ios or
|
|
6587
|
+
android launch does not hide the page's.
|
|
6588
|
+
|
|
6589
|
+
AGENTS AND OTHER TOOLS ON THE SAME BROWSER
|
|
6590
|
+
|
|
6591
|
+
stim status --json shows environments[].web.cdpEndpoint, a reserved loopback
|
|
6592
|
+
DevTools endpoint on 127.0.0.1. Point browser tools at it instead of letting
|
|
6593
|
+
them start their own browser:
|
|
6594
|
+
Playwright MCP --cdp-endpoint http://127.0.0.1:<port>
|
|
6595
|
+
agent-browser --cdp <port>
|
|
6596
|
+
The port reaches only the Stim profile: Chrome refuses remote debugging on
|
|
6597
|
+
your default profile, and Stim never attaches to a browser it did not start.
|
|
6598
|
+
The port is managed like metro: stim ports lists it as web-cdp (managed),
|
|
6599
|
+
and ports get, stop and release refuse it.
|
|
6600
|
+
|
|
6601
|
+
OWNERSHIP AND CLEANUP
|
|
6602
|
+
|
|
6603
|
+
A browser supervisor process holds the DevTools session and an ownership
|
|
6604
|
+
claim for its lifetime; Chrome is the claim's child. Stim signals the
|
|
6605
|
+
supervisor or Chrome only after verifying the process identity it recorded.
|
|
6606
|
+
stim stop closes Chrome and keeps the profile, so cookies and
|
|
6607
|
+
storage survive the next stim web
|
|
6608
|
+
stim worktree remove closes Chrome and deletes the profile
|
|
6609
|
+
stim gc --delete does the same for a workspace whose path is gone,
|
|
6610
|
+
and forgets ledger entries of deleted profiles
|
|
6611
|
+
The profile is deleted only when the created-devices ledger lists it. After
|
|
6612
|
+
Chrome is gone, Stim removes the SingletonLock files a killed Chrome leaves,
|
|
6613
|
+
which would otherwise block the next launch. status reports
|
|
6614
|
+
browser-unverified when an identity cannot be proven; follow stim guide
|
|
6615
|
+
errors teardown.
|
|
6616
|
+
|
|
6617
|
+
LIMITS
|
|
6618
|
+
|
|
6619
|
+
Chrome and Chromium only. No Stim Desktop or phone viewer yet. The owned page
|
|
6620
|
+
is one tab: a page the app opens in a new window is not captured.`
|
|
5844
6621
|
}
|
|
5845
6622
|
};
|
|
5846
6623
|
//#endregion
|