stim 1.2.0 → 1.3.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 +30 -0
- package/dist/android-BqVIJoG7.mjs +1368 -0
- package/dist/{android-Bcmev2s2.mjs → android-CqcW1hrP.mjs} +148 -56
- package/dist/{android-cas-D6HPZ6UQ.mjs → android-cas-BR5YJBYv.mjs} +5 -5
- package/dist/{app-install-NFxUahnH.mjs → app-install-DIp9riNx.mjs} +6 -6
- package/dist/{build-slots-D0b6sJyo.mjs → build-slots-C3-R4XQr.mjs} +2 -2
- package/dist/{cache-manifest-Cu4_Znw9.mjs → cache-manifest-CXR-Y8pH.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +13 -13
- package/dist/collector-run.d.mts +3 -1
- package/dist/collector-run.mjs +33 -8
- package/dist/{config-CMtIaTk9.mjs → config-CcefMY2Q.mjs} +93 -12
- package/dist/{deps-BLBsTNDS.mjs → deps-Spz8ozgo.mjs} +1 -1
- package/dist/{dev-client-RpvXxCXV.mjs → dev-client-BjisHDB5.mjs} +186 -9
- package/dist/{device-CoCPmazS.mjs → device-BkiW-gkk.mjs} +19 -11
- package/dist/{device-lease-Dpik41RY.mjs → device-lease-BJYybF-2.mjs} +107 -83
- package/dist/{device-pool-B5pEVa3t.mjs → device-pool-CPbLGfrB.mjs} +18 -12
- package/dist/{device-remote-E81KAdXf.mjs → device-remote-AkYCKS8U.mjs} +7 -7
- package/dist/{doctor-CqPeMsSm.mjs → doctor-Bmv86UUW.mjs} +11 -12
- package/dist/{doctor-D_CX7ib5.mjs → doctor-fAMXC4vl.mjs} +4 -4
- package/dist/{error-diagnostics-Dw8Gn3yw.mjs → error-diagnostics-DHC31rXA.mjs} +62 -52
- package/dist/{gc-B7KkDinF.mjs → gc-GGu-8ULN.mjs} +66 -57
- package/dist/{guide-BS2Xc24o.mjs → guide-92CPA21s.mjs} +196 -13
- package/dist/{ios-B7KLgIp5.mjs → ios-BSXFeO5H.mjs} +183 -54
- package/dist/{ios-D1h1Di39.mjs → ios-Deh5js5V.mjs} +78 -40
- package/dist/{ios-device-xNt0Lg6v.mjs → ios-device-CWOM_S44.mjs} +1 -1
- package/dist/{logs-DcX9AvRF.mjs → logs-DPNF4C9s.mjs} +9 -6
- package/dist/{logs-query-oqn47Ffx.mjs → logs-query-R-Cqc6Qv.mjs} +22 -5
- package/dist/{metro-COslRK_F.mjs → metro-CORqXyTL.mjs} +2 -2
- package/dist/{ndjson-DcAtEx_K.mjs → ndjson-BZwI1NBv.mjs} +5 -2
- package/dist/{ownership-CGPart6T.mjs → ownership-8O073GIC.mjs} +3 -3
- package/dist/{ownership-CYOyqxUo.mjs → ownership-BpCKiRlQ.mjs} +3 -3
- package/dist/{ownership-claim-7zRxxTfZ.mjs → ownership-claim-Bf2CAfw3.mjs} +4 -3
- package/dist/{project-BBTVABUz.mjs → project-fKmuIaMI.mjs} +2 -2
- package/dist/{reclaim-C5Jmuahx.mjs → reclaim-iW9Cad7k.mjs} +80 -74
- package/dist/{reload-Z8nKifAk.mjs → reload-DazHDSFA.mjs} +32 -24
- package/dist/{server-bare-DEk37Mz2.mjs → server-bare-DEzPZLvf.mjs} +2 -2
- package/dist/server-expo-44em5Pmg.mjs +2 -0
- package/dist/{server-expo-C3ktAwUG.mjs → server-expo-DizT4OMk.mjs} +4 -4
- package/dist/{settings-DwU1_U_q.mjs → settings-DEJf6_kJ.mjs} +2 -2
- package/dist/slot-launch-cci0xvmC.mjs +19 -0
- package/dist/{start-BrY4EuIg.mjs → start-mObjQH2W.mjs} +11 -11
- package/dist/{state-CZ-ER-8d.mjs → state-B3XA2wp2.mjs} +9 -9
- package/dist/{stats-BCWEVLrM.mjs → stats-BR-kwj0B.mjs} +1 -1
- package/dist/{stats-BsF15Bti.mjs → stats-CaaQr4yN.mjs} +3 -3
- package/dist/{status-DFI1Hfpg.mjs → status-BxQNqu9t.mjs} +55 -24
- package/dist/{stop-B7DR4awK.mjs → stop-CrHGcjrV.mjs} +2 -2
- package/dist/{stop-Btg770vV.mjs → stop-DimGXEKY.mjs} +93 -42
- package/dist/supervisor-run.d.mts +1 -2
- package/dist/supervisor-run.mjs +5 -5
- package/dist/{remote-cache-DDmJ1Roq.mjs → teardown-ClFp1Aax.mjs} +887 -888
- package/dist/{workspace-process-lock-BKfdys1q.mjs → workspace-process-lock-3NcQnZ0X.mjs} +1 -1
- package/dist/{worktree-BPTbI-LN.mjs → worktree-DxTgN1CJ.mjs} +12 -12
- package/dist/{worktree-C79xx_kM.mjs → worktree-Eq6TLH8N.mjs} +1 -1
- package/dist/{xcode-DeKCribl.mjs → xcode-D7sAp-Zy.mjs} +82 -56
- package/package.json +5 -5
- package/dist/android-K63_0UfF.mjs +0 -727
- package/dist/build-lock-BsVoLDaq.mjs +0 -645
- package/dist/server-expo-Drd7ksHu.mjs +0 -2
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { A as directorySize, M as isOnMountedVolume, N as listMountedVolumes, P as volumeRootFor, g as loadConfig, i as clearDevice, j as formatBytes, u as getConfigDir, v as removeProject } from "./config-
|
|
3
|
-
import { i as registeredCaches } from "./cache-manifest-
|
|
4
|
-
import { T as workspaceDir, k as workspaceStateFile } from "./state-
|
|
5
|
-
import { g as repoRoot, s as gitCommonDir } from "./worktree-
|
|
6
|
-
import { a as findProjectRoot, i as detectIsExpo } from "./project-
|
|
7
|
-
import { S as readParked, _ as teardownParkedIosSim, b as dropParked, d as resolveEasCliBin, g as teardownParkedAvd, h as teardownOwnedIosSim, m as teardownOwnedAvd, v as POOL_SETTING_REMEDY, x as parkedMaxSetting } from "./remote-cache-DDmJ1Roq.mjs";
|
|
8
|
-
import { A as resolveSettings, N as settingShapeErrors, a as SETTING_SHAPE_REMEDY } from "./settings-DwU1_U_q.mjs";
|
|
2
|
+
import { A as directorySize, M as isOnMountedVolume, N as listMountedVolumes, P as volumeRootFor, g as loadConfig, i as clearDevice, j as formatBytes, u as getConfigDir, v as removeProject, z as projectDeviceSlots } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { i as registeredCaches } from "./cache-manifest-CXR-Y8pH.mjs";
|
|
4
|
+
import { T as workspaceDir, k as workspaceStateFile } from "./state-B3XA2wp2.mjs";
|
|
5
|
+
import { g as repoRoot, s as gitCommonDir } from "./worktree-Eq6TLH8N.mjs";
|
|
6
|
+
import { a as findProjectRoot, i as detectIsExpo } from "./project-fKmuIaMI.mjs";
|
|
9
7
|
import { m as shortUdid, o as formatLongDuration, u as plural } from "./command-output-8wHMEde0.mjs";
|
|
10
|
-
import { d as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { i as
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
8
|
+
import { d as readClaimSet, o as clearFreeClaimSet } from "./ownership-claim-Bf2CAfw3.mjs";
|
|
9
|
+
import { B as listBuildLocks, S as listOrphanedAvdDirectories, T as ownedAvdDirectory, b as listAvds } from "./android-BqVIJoG7.mjs";
|
|
10
|
+
import { A as resolveSettings, N as settingShapeErrors, a as SETTING_SHAPE_REMEDY } from "./settings-DEJf6_kJ.mjs";
|
|
11
|
+
import { a as POOL_SETTING_REMEDY, c as parkedMaxSetting, i as teardownParkedIosSim, l as readParked, n as teardownOwnedIosSim, r as teardownParkedAvd, s as dropParked, t as teardownOwnedAvd, x as resolveEasCliBin } from "./teardown-ClFp1Aax.mjs";
|
|
12
|
+
import { d as listIosDeviceTypes, g as parseRuntimeVersion, u as listAllIosSims } from "./ios-Deh5js5V.mjs";
|
|
13
|
+
import { i as listLeaseFiles, r as leaseIsExpired, u as removeExpiredLease } from "./device-lease-BJYybF-2.mjs";
|
|
14
|
+
import { n as listBuildSlots } from "./build-slots-C3-R4XQr.mjs";
|
|
15
|
+
import { C as verifyStoppedSession, S as stopSessionArgs, _ as inspectSessionForTeardown, d as withEasProjectLock, f as easMachineStateRoot, g as getSessionArgs, h as findOrphanedOwnedSessions, m as removeEasSessionClaim, p as readEasSessionLedger, u as withRemoteSessionLock, v as isDefinitiveMissingSessionError, x as parseSessionListPage, y as listOwnedSessionsArgs } from "./device-remote-AkYCKS8U.mjs";
|
|
16
|
+
import { n as reclaimProject, t as describeDereferenced } from "./reclaim-iW9Cad7k.mjs";
|
|
18
17
|
import { InvalidArgumentError } from "commander";
|
|
19
18
|
import { existsSync, readFileSync, readdirSync, realpathSync, rmSync, statSync } from "fs";
|
|
20
19
|
import { homedir, tmpdir } from "os";
|
|
@@ -413,16 +412,18 @@ function findOrphanedDevices({ sims = [], avds = [], config, isMounted, deadProj
|
|
|
413
412
|
for (const [path, proj] of Object.entries(config?.projects || {})) {
|
|
414
413
|
if (dead.has(path)) continue;
|
|
415
414
|
const mounted = isMounted ? isMounted(path) : true;
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
415
|
+
for (const { platforms } of projectDeviceSlots(proj)) {
|
|
416
|
+
const ios = platforms.ios;
|
|
417
|
+
if (ios?.deviceUdid) referenced.set(ios.deviceUdid, {
|
|
418
|
+
path,
|
|
419
|
+
mounted
|
|
420
|
+
});
|
|
421
|
+
const android = platforms.android;
|
|
422
|
+
if (android?.avdName) referenced.set(android.avdName, {
|
|
423
|
+
path,
|
|
424
|
+
mounted
|
|
425
|
+
});
|
|
426
|
+
}
|
|
426
427
|
}
|
|
427
428
|
for (const sim of readParked("ios", { config })) referenced.set(sim.udid, {
|
|
428
429
|
path: "the simulator pool",
|
|
@@ -481,22 +482,26 @@ function findStaleProjectDevices({ config, sims = [], avds = [], olderThanDays,
|
|
|
481
482
|
const touched = lastTouched(path);
|
|
482
483
|
if (!Number.isFinite(touched) || touched >= cutoff) continue;
|
|
483
484
|
const idleDays = Math.floor((now - touched) / DAY_MS);
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
485
|
+
for (const { slot, platforms } of projectDeviceSlots(proj)) {
|
|
486
|
+
const ios = platforms.ios;
|
|
487
|
+
if (ios?.owned && ios.deviceUdid && liveSims.has(ios.deviceUdid)) stale.push({
|
|
488
|
+
kind: "ios",
|
|
489
|
+
id: ios.deviceUdid,
|
|
490
|
+
name: liveSims.get(ios.deviceUdid),
|
|
491
|
+
project: path,
|
|
492
|
+
...slot === "default" ? {} : { slot },
|
|
493
|
+
idleDays
|
|
494
|
+
});
|
|
495
|
+
const android = platforms.android;
|
|
496
|
+
if (android?.owned && android.avdName && liveAvds.has(android.avdName)) stale.push({
|
|
497
|
+
kind: "android",
|
|
498
|
+
id: android.avdName,
|
|
499
|
+
name: android.avdName,
|
|
500
|
+
project: path,
|
|
501
|
+
idleDays,
|
|
502
|
+
...slot === "default" ? {} : { slot }
|
|
503
|
+
});
|
|
504
|
+
}
|
|
500
505
|
}
|
|
501
506
|
return stale;
|
|
502
507
|
}
|
|
@@ -507,20 +512,24 @@ function findStaleDeviceRecords({ config, sims = [], avds = [], deadProjects = [
|
|
|
507
512
|
const stale = [];
|
|
508
513
|
for (const [path, proj] of Object.entries(config?.projects || {})) {
|
|
509
514
|
if (dead.has(path)) continue;
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
515
|
+
for (const { slot, platforms } of projectDeviceSlots(proj)) {
|
|
516
|
+
const ios = platforms.ios;
|
|
517
|
+
if (simsChecked && ios?.deviceUdid && !liveSims.has(ios.deviceUdid)) stale.push({
|
|
518
|
+
kind: "ios",
|
|
519
|
+
id: ios.deviceUdid,
|
|
520
|
+
project: path,
|
|
521
|
+
...slot === "default" ? {} : { slot },
|
|
522
|
+
owned: Boolean(ios.owned)
|
|
523
|
+
});
|
|
524
|
+
const android = platforms.android;
|
|
525
|
+
if (avdsChecked && android?.avdName && !liveAvds.has(android.avdName)) stale.push({
|
|
526
|
+
kind: "android",
|
|
527
|
+
id: android.avdName,
|
|
528
|
+
project: path,
|
|
529
|
+
...slot === "default" ? {} : { slot },
|
|
530
|
+
owned: Boolean(android.owned)
|
|
531
|
+
});
|
|
532
|
+
}
|
|
524
533
|
}
|
|
525
534
|
return stale;
|
|
526
535
|
}
|
|
@@ -704,12 +713,12 @@ function deleteProjectDevices(orphanedDevices, staleDevices, staleDeviceRecords)
|
|
|
704
713
|
for (const d of staleDevices) {
|
|
705
714
|
const status = reap(d);
|
|
706
715
|
if (status === "torn-down" || status === "missing") {
|
|
707
|
-
clearDevice(d.project, d.kind);
|
|
716
|
+
clearDevice(d.project, d.kind, d.slot);
|
|
708
717
|
console.log(chalk.dim(` cleared the ${d.kind} record for ${d.project}`));
|
|
709
718
|
}
|
|
710
719
|
}
|
|
711
720
|
for (const r of staleDeviceRecords) {
|
|
712
|
-
clearDevice(r.project, r.kind);
|
|
721
|
+
clearDevice(r.project, r.kind, r.slot);
|
|
713
722
|
console.log(chalk.green(`Cleared the ${r.kind} record for ${r.project} (${r.id} is not on this machine)`));
|
|
714
723
|
}
|
|
715
724
|
return deleteFailures;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-
|
|
1
|
+
import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-DEJf6_kJ.mjs";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
//#endregion
|
|
4
4
|
//#region src/guide/index.ts
|
|
@@ -31,6 +31,15 @@ branch that is not the default one -- only once the repository has at least
|
|
|
31
31
|
one linked worktree, so read it from inside the worktree. A single-checkout
|
|
32
32
|
session is never told that its own branch is a problem.
|
|
33
33
|
|
|
34
|
+
MULTIPLE DEVICES
|
|
35
|
+
|
|
36
|
+
Use ios/android --slot <name> to retain multiple devices in one workspace,
|
|
37
|
+
including several of the same model. Reuse the same slot name on subsequent
|
|
38
|
+
runs. Read guide lifecycle options for the complete slot workflow. Use the
|
|
39
|
+
reported device ID for UI interaction. All slots share Metro; reload can reach
|
|
40
|
+
multiple devices, and a shared bundle request does not prove a slot launched.
|
|
41
|
+
Use stop --slot <name> for one slot, or plain stop for the whole workspace.
|
|
42
|
+
|
|
34
43
|
NORMAL WORKFLOW
|
|
35
44
|
|
|
36
45
|
Work in the current checkout by default. When the task needs another branch or
|
|
@@ -66,7 +75,9 @@ For iOS Debug architecture findings, review the project's overrides and imported
|
|
|
66
75
|
Podfile helpers using guide lifecycle options. Doctor --fix does not change them.
|
|
67
76
|
For parallel iOS work, review the recommended optional SimSlim setup in
|
|
68
77
|
stim guide lifecycle simslim. If simulator process startup times out, check
|
|
69
|
-
host memory pressure and free memory before retrying
|
|
78
|
+
host memory pressure and free memory before retrying. Boot progress reports
|
|
79
|
+
current and highest observed pressure; a timeout does not establish OOM.
|
|
80
|
+
Avoid repeated reboots under unchanged pressure; do not restart other
|
|
70
81
|
workspaces' devices or close their apps without asking. That guide covers
|
|
71
82
|
the recovery steps and profile tradeoffs.
|
|
72
83
|
For a linked native library carrying Git metadata, add the printed .git entries to
|
|
@@ -88,6 +99,16 @@ them. It preserves source, custom launcher settings, and the shared ccache.
|
|
|
88
99
|
stim start
|
|
89
100
|
stim ios # or: stim android
|
|
90
101
|
|
|
102
|
+
For a project using EAS development builds, read stim guide lifecycle eas to
|
|
103
|
+
select a profile from eas.json for the requested target, then run
|
|
104
|
+
stim ios --eas-profile <name> or stim android --eas-profile <name>.
|
|
105
|
+
Ask the user if the profile choice is ambiguous. A miss stops with
|
|
106
|
+
STIM_EAS_BUILD_MISSING and an EAS build command. Run that command only when the
|
|
107
|
+
session authorizes the potentially billable build, then retry Stim. The
|
|
108
|
+
presence of eas.json does not select EAS or authorize building.
|
|
109
|
+
Physical --device targets are supported. Follow EAS device-registration and
|
|
110
|
+
rebuild remedies only when the session authorizes those account changes.
|
|
111
|
+
|
|
91
112
|
Read stim guide lifecycle concurrency when a build waits on another workspace
|
|
92
113
|
or a build call times out. A native build can outlive a shell timeout; if the
|
|
93
114
|
tool call timed out, retry the same command and follow its printed remedy if
|
|
@@ -277,7 +298,13 @@ FULL TOPIC LIST
|
|
|
277
298
|
},
|
|
278
299
|
facts: {
|
|
279
300
|
summary: "The --json payloads: `start`, `ios`, `android`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, and the error contract",
|
|
280
|
-
preamble: () => `
|
|
301
|
+
preamble: () => `SLOTS
|
|
302
|
+
Named ios/android runs add slot to their JSON facts. Default-run fields remain
|
|
303
|
+
compatible. status adds a slots array per environment with each named slot's
|
|
304
|
+
ios/android device facts; top-level ios/android still describe default.
|
|
305
|
+
Named collector, lease-holder, and launch keys use platform:slot internally.
|
|
306
|
+
|
|
307
|
+
FACTS CONTRACT
|
|
281
308
|
|
|
282
309
|
\`start\`, \`ios\`, \`android\`, \`reload\`, \`stop\`, \`status\`, \`stats\`, \`doctor\`,
|
|
283
310
|
and \`device lock\`/\`device unlock\` each print exactly ONE line of JSON on
|
|
@@ -341,6 +368,11 @@ line by design (see \`guide logs\`), not this single-payload contract.`,
|
|
|
341
368
|
absent for automatic selection; not the app URL scheme
|
|
342
369
|
cacheKey the shared-build-cache key derived from it (the
|
|
343
370
|
configuration is part of it: -release-sim vs -debug-sim)
|
|
371
|
+
With --eas-profile, fingerprint is computed by EAS CLI using the selected
|
|
372
|
+
profile/environment, and cacheKey identifies the EAS project and build ID
|
|
373
|
+
separately from local native builds. cacheHit is "remote" for the EAS
|
|
374
|
+
source, including when EAS CLI reuses its own downloaded artifact cache.
|
|
375
|
+
|
|
344
376
|
cacheHit WHICH LEVEL answered, not a boolean:
|
|
345
377
|
"local" this machine's shared cache (free, instant)
|
|
346
378
|
"remote" the project's own Expo buildCacheProvider (a
|
|
@@ -874,7 +906,13 @@ one dim note on STDERR reading \`No matching log records in <logs dir>\`
|
|
|
874
906
|
(human mode only -- \`--json\` prints nothing at all, on either stream).
|
|
875
907
|
The only exit-1 paths are a malformed query and no project.
|
|
876
908
|
|
|
909
|
+
Device collectors and build records carry their named slot. Use --slot phone
|
|
910
|
+
for that slot's timeline; its launch marker cannot hide a sibling's errors.
|
|
911
|
+
Untagged legacy records belong to default. Metro/client records are shared and
|
|
912
|
+
usually untagged: use an unfiltered workspace query to inspect those errors.
|
|
913
|
+
|
|
877
914
|
FLAGS
|
|
915
|
+
--slot <name> only this slot's records (default includes untagged records)
|
|
878
916
|
--source <s...> metro, client, device, build (one or more), or all. An
|
|
879
917
|
unknown value is REJECTED rather than quietly matching
|
|
880
918
|
nothing.
|
|
@@ -1138,6 +1176,24 @@ WHAT WRITES WHAT
|
|
|
1138
1176
|
Every refusal from \`ios\` / \`android\` carries a stable CODE. Branch on the
|
|
1139
1177
|
code, never on the message.`,
|
|
1140
1178
|
sections: {
|
|
1179
|
+
STIM_EAS_BUILD_MISSING: {
|
|
1180
|
+
summary: "no completed EAS development build matches; build only with session authorization",
|
|
1181
|
+
body: () => `STIM_EAS_BUILD_MISSING
|
|
1182
|
+
No compatible build matches the selected EAS project, profile, platform and
|
|
1183
|
+
native fingerprint. No device was acquired and no local or cloud build was
|
|
1184
|
+
started. The remedy prints the exact npx eas-cli build command. Check session
|
|
1185
|
+
authorization for its potential cost before running it, then retry Stim.
|
|
1186
|
+
See stim guide lifecycle eas.`
|
|
1187
|
+
},
|
|
1188
|
+
STIM_EAS_UNAVAILABLE: {
|
|
1189
|
+
summary: "EAS lookup/download failed, or another run holds the artifact claim",
|
|
1190
|
+
body: () => `STIM_EAS_UNAVAILABLE
|
|
1191
|
+
EAS CLI is unavailable, a profile/fingerprint/list/download operation failed,
|
|
1192
|
+
the response could not be validated, or another run holds the artifact claim.
|
|
1193
|
+
Follow the printed remedy: inspect the named EAS command or retry once the
|
|
1194
|
+
holder finishes. This is not proof that a build is missing. No native build
|
|
1195
|
+
is started. See stim guide lifecycle eas.`
|
|
1196
|
+
},
|
|
1141
1197
|
STIM_WORKSPACE_STATE: {
|
|
1142
1198
|
summary: "$STIM_HOME/workspaces could not be prepared, or the digest directory belongs to another project",
|
|
1143
1199
|
aliases: ["STIM_WORKSPACE_COLLISION"],
|
|
@@ -1464,7 +1520,10 @@ spending a build or a bundle, that the check can succeed.`,
|
|
|
1464
1520
|
profile;
|
|
1465
1521
|
- it is a development or ad hoc profile whose device list does not name
|
|
1466
1522
|
this UDID. Register the UDID at developer.apple.com, regenerate the
|
|
1467
|
-
profile, and build once from Xcode
|
|
1523
|
+
profile, and build once from Xcode.
|
|
1524
|
+
With --eas-profile, follow the EAS device:create and build commands in the
|
|
1525
|
+
refusal instead. Registration, signing changes and cloud builds need session
|
|
1526
|
+
authorization. See stim guide lifecycle eas.`
|
|
1468
1527
|
},
|
|
1469
1528
|
STIM_NO_SIGNING_IDENTITY: {
|
|
1470
1529
|
summary: "no single keychain identity resolves; ios.signingIdentitySha1 for two certificates",
|
|
@@ -1642,8 +1701,8 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
|
|
|
1642
1701
|
and \`adb devices\`, then retry after any other run finishes. Keep the AVD and
|
|
1643
1702
|
its process locks while its state is unverified.
|
|
1644
1703
|
On iOS a slow first boot is waited out for up to ten minutes while the
|
|
1645
|
-
simulator
|
|
1646
|
-
|
|
1704
|
+
simulator reports Booting or Booted but bootstatus has not completed.
|
|
1705
|
+
Booted alone does not end that wait. The failure names the udid and the wait.
|
|
1647
1706
|
After boot, a process-spawn probe must finish within 30 seconds before
|
|
1648
1707
|
installation. If it fails, the refusal includes observed host memory pressure
|
|
1649
1708
|
when available. Free memory before retrying under pressure; see
|
|
@@ -2403,6 +2462,82 @@ TWO REPORTS, TWO QUESTIONS
|
|
|
2403
2462
|
the machine, with a hit rate and an estimate of the time saved (see
|
|
2404
2463
|
\`guide facts stats\`).`,
|
|
2405
2464
|
sections: {
|
|
2465
|
+
eas: {
|
|
2466
|
+
summary: "download a matching EAS development build; explicit profile, costs, cache and miss remedies",
|
|
2467
|
+
body: () => `EAS DEVELOPMENT BUILDS
|
|
2468
|
+
|
|
2469
|
+
stim ios --eas-profile ios-simulator
|
|
2470
|
+
stim android --eas-profile development
|
|
2471
|
+
stim ios --eas-profile development-device --device <udid>
|
|
2472
|
+
stim android --eas-profile development --device <serial>
|
|
2473
|
+
|
|
2474
|
+
An eas.json file does not select EAS automatically. The flag names the profile
|
|
2475
|
+
and selects EAS Build as the artifact source. The profile must resolve to
|
|
2476
|
+
"developmentClient": true and "distribution": "internal". For iOS, set
|
|
2477
|
+
"ios.simulator": true for a simulator, or false (or omit it) for --device.
|
|
2478
|
+
An explicit ios.buildConfiguration must be Debug;
|
|
2479
|
+
android.gradleCommand must be a single :app:assemble<Variant>Debug task producing
|
|
2480
|
+
an APK. Install eas-cli and authenticate with eas login
|
|
2481
|
+
or EXPO_TOKEN. The Expo app must already be linked to the intended EAS project.
|
|
2482
|
+
|
|
2483
|
+
Use the profile the user names. Otherwise inspect eas.json, including extends
|
|
2484
|
+
and platform overrides, for the requested platform, simulator or physical
|
|
2485
|
+
device, and app variant or environment. Choose a profile only when those
|
|
2486
|
+
requirements identify one compatible development profile. If there is no
|
|
2487
|
+
compatible profile or the choice is ambiguous, ask the user. Profile names
|
|
2488
|
+
alone do not establish compatibility. Confirm the resolved settings with
|
|
2489
|
+
npx eas-cli config --platform <ios|android> --profile <name> --json --non-interactive.
|
|
2490
|
+
Pass the selected name to --eas-profile; the CLI does not infer it.
|
|
2491
|
+
|
|
2492
|
+
Stim delegates profile inheritance, environment resolution and fingerprinting
|
|
2493
|
+
to EAS CLI. fingerprint:generate uploads fingerprint metadata to EAS. It does
|
|
2494
|
+
not start a native build. EAS access is needed even when the artifact is
|
|
2495
|
+
already cached, because the current profile and fingerprint must be resolved.
|
|
2496
|
+
|
|
2497
|
+
Stim matches the EAS project, profile, native fingerprint, platform and
|
|
2498
|
+
simulator/internal distribution target against a completed build. It downloads
|
|
2499
|
+
an iOS .app or Android .apk with EAS CLI, then uses its existing installation,
|
|
2500
|
+
Metro connection, log capture and launch verification on the selected device.
|
|
2501
|
+
The flag also works with --remote; remote EAS Simulator sessions have their
|
|
2502
|
+
own costs, independent of this download path. Local --scheme, --configuration,
|
|
2503
|
+
--variant and --no-build-cache selectors
|
|
2504
|
+
cannot be combined with --eas-profile. Local configuration/variant defaults
|
|
2505
|
+
are ignored for this development-build run.
|
|
2506
|
+
|
|
2507
|
+
Physical devices use Stim's usual selection and lease rules. An iOS app must
|
|
2508
|
+
have a development-client URL scheme and a valid embedded provisioning profile
|
|
2509
|
+
that includes the target UDID. Stim installs the signed app without re-signing
|
|
2510
|
+
it. If the profile does not admit the device, the remedy points to
|
|
2511
|
+
npx eas-cli device:create and npx eas-cli build --platform ios --profile <name>.
|
|
2512
|
+
Registration, signing changes and cloud builds need session authorization.
|
|
2513
|
+
Run the EAS build interactively when its provisioning profile needs refreshing,
|
|
2514
|
+
then retry the same Stim command.
|
|
2515
|
+
|
|
2516
|
+
Start Metro with stim start as usual. Metro uses the local workspace's
|
|
2517
|
+
environment; arrange the appropriate local variables before starting it.
|
|
2518
|
+
EAS environment resolution for native fingerprinting does not configure Metro.
|
|
2519
|
+
|
|
2520
|
+
EAS CLI caches extracted artifacts by project and build ID in its own temporary
|
|
2521
|
+
cache. Stim calls build:download and uses the returned artifact without making
|
|
2522
|
+
another cache copy. Every run queries the latest matching build, so a rebuild
|
|
2523
|
+
with a refreshed provisioning profile is selected even if its native fingerprint
|
|
2524
|
+
is unchanged. Stim coordinates concurrent downloads by project and build ID.
|
|
2525
|
+
cacheHit: "remote" identifies the EAS source, including when EAS CLI reuses its
|
|
2526
|
+
disk cache. The fingerprint fact is the EAS native fingerprint. Stim's local
|
|
2527
|
+
buildCache and remoteBuildCache settings do not control EAS CLI's cache.
|
|
2528
|
+
EAS cache files are managed by EAS CLI and are outside Stim gc.
|
|
2529
|
+
|
|
2530
|
+
On STIM_EAS_BUILD_MISSING, Stim stops before acquiring a device and prints:
|
|
2531
|
+
|
|
2532
|
+
npx eas-cli build --platform ios --profile ios-simulator
|
|
2533
|
+
|
|
2534
|
+
Run that command only when the session authorizes the potentially billable
|
|
2535
|
+
cloud build. Once it completes, retry the same Stim command. No build-on-miss
|
|
2536
|
+
flag exists, and Stim never starts a cloud build or falls back to local
|
|
2537
|
+
compilation in this mode. Authentication, network, invalid output or download
|
|
2538
|
+
failures produce STIM_EAS_UNAVAILABLE, with the failed EAS command to inspect.
|
|
2539
|
+
If another run holds the artifact claim, wait for it to finish and retry.`
|
|
2540
|
+
},
|
|
2406
2541
|
readiness: {
|
|
2407
2542
|
summary: "implement optional pending/ready app logs, deadlines, errors, and platform isolation",
|
|
2408
2543
|
body: () => `OPTIONAL APP READINESS
|
|
@@ -3081,13 +3216,13 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
3081
3216
|
summary: "every flag per command, Android variants and flavors, the per-run simulator model, runtime and system image",
|
|
3082
3217
|
body: () => `THE OPTION SURFACE, IN FULL
|
|
3083
3218
|
start --json --wait <seconds> --remote --reset-cache
|
|
3084
|
-
ios --json --no-metro-check --no-build-cache --scheme <name> --configuration <name> --device-type <name> --runtime <version> --device [udid] --wait <seconds> --no-wait --remote <proxy|eas>
|
|
3085
|
-
android --json --no-metro-check --no-build-cache --variant <name> --system-image <id> --device [serial] --wait <seconds> --no-wait --remote <proxy|eas>
|
|
3219
|
+
ios --slot <name> --json --no-metro-check --no-build-cache --scheme <name> --configuration <name> --device-type <name> --runtime <version> --device [udid] --wait <seconds> --no-wait --remote <proxy|eas>
|
|
3220
|
+
android --slot <name> --json --no-metro-check --no-build-cache --variant <name> --system-image <id> --device [serial] --wait <seconds> --no-wait --remote <proxy|eas>
|
|
3086
3221
|
reload [ios|android] --json
|
|
3087
|
-
device lock <ios|android> [id] --for <duration> --wait <seconds> --json;
|
|
3088
|
-
unlock [ios|android] --json
|
|
3089
|
-
logs --source --level --since --grep --tail --follow --errors --json
|
|
3090
|
-
stop --json
|
|
3222
|
+
device lock <ios|android> [id] --slot <name> --for <duration> --wait <seconds> --json;
|
|
3223
|
+
unlock [ios|android] --slot <name> --json
|
|
3224
|
+
logs --slot <name> --source --level --since --grep --tail --follow --errors --json
|
|
3225
|
+
stop --slot <name> --json
|
|
3091
3226
|
status --json (already machine-wide)
|
|
3092
3227
|
stats --json (this project and machine-wide)
|
|
3093
3228
|
doctor --json --fix --platform <ios|android>
|
|
@@ -3095,6 +3230,38 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
|
|
|
3095
3230
|
gc --delete --older-than <days> --cache <name|all>
|
|
3096
3231
|
worktree warm --refresh; remove [path] --force
|
|
3097
3232
|
|
|
3233
|
+
DEVICE SLOTS
|
|
3234
|
+
Use --slot <name> on ios or android to keep any number of simulators,
|
|
3235
|
+
emulators, or physical devices in the same workspace. Names are reusable
|
|
3236
|
+
identities, not models: two slots can request identical models. A slot has
|
|
3237
|
+
one target per platform. Omitting the flag selects default and preserves
|
|
3238
|
+
the workspace's existing assignment.
|
|
3239
|
+
|
|
3240
|
+
stim ios --slot phone
|
|
3241
|
+
stim ios --slot tablet --device-type "iPad Pro 13-inch (M4)"
|
|
3242
|
+
stim ios --slot hardware --device <udid>
|
|
3243
|
+
stim android --slot second-phone
|
|
3244
|
+
stim logs --slot tablet --source device
|
|
3245
|
+
stim stop --slot tablet
|
|
3246
|
+
|
|
3247
|
+
All slots share this workspace's Metro server and build cache. Native CLI
|
|
3248
|
+
runs serialize workspace mutations; a waiting run can wait up to 30 minutes.
|
|
3249
|
+
Named slots support local devices; remote sessions use the default slot.
|
|
3250
|
+
Names use 1-64 letters, digits, underscores or hyphens, starting with a letter
|
|
3251
|
+
or digit. Reserved object-property names are refused.
|
|
3252
|
+
|
|
3253
|
+
stop --slot shuts down that slot's owned devices and releases its leases,
|
|
3254
|
+
retaining Metro and sibling slots. Plain stop handles the whole workspace.
|
|
3255
|
+
status reports named devices under slots and counts their memory. Device
|
|
3256
|
+
caps count every slot. Recycling uses the same model/runtime-matched pool
|
|
3257
|
+
for every slot, with one shared cap per platform and oldest-first eviction.
|
|
3258
|
+
|
|
3259
|
+
Metro cannot reliably identify a particular simulator's bundle request.
|
|
3260
|
+
When slots coexist, a shared bundle event is not proof that a particular
|
|
3261
|
+
slot launched: Debug launch can report unverified. Check the reported device
|
|
3262
|
+
directly. Release verification still checks its process. reload ios/android
|
|
3263
|
+
addresses matching Metro peers across slots; it is not a single-slot reload.
|
|
3264
|
+
|
|
3098
3265
|
That is the whole surface today, and it is deliberately small. It can grow
|
|
3099
3266
|
when a flag is genuinely the best answer -- but project-specific knowledge
|
|
3100
3267
|
(release builds, variants, device targets) belongs in a script the repo owns,
|
|
@@ -3600,6 +3767,13 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
3600
3767
|
a final boot-state query can take 30 seconds. Opening the Simulator app after
|
|
3601
3768
|
boot is best-effort and takes at most 5 seconds. A timeout is not proof of an
|
|
3602
3769
|
app crash or OOM.
|
|
3770
|
+
During boot, Stim reports elapsed time, the simulator name, last boot output,
|
|
3771
|
+
current pressure and the highest observed pressure roughly every 15 seconds.
|
|
3772
|
+
Failure diagnostics retain the highest pressure and unavailable sample count;
|
|
3773
|
+
they do not infer the cause of a timeout. Monitoring stops when boot ends.
|
|
3774
|
+
Monitoring and timeout handling are best-effort: synchronous CLI work can
|
|
3775
|
+
delay them. Diagnostics report observation gaps over 30 seconds; pressure
|
|
3776
|
+
during a gap is unobserved, even when the surrounding readings are normal.
|
|
3603
3777
|
Doctor and failure diagnostics report macOS memory pressure when available;
|
|
3604
3778
|
a failed query remains unknown. Existing swap or low free RAM alone is not
|
|
3605
3779
|
enough to diagnose pressure.
|
|
@@ -3614,7 +3788,16 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
|
|
|
3614
3788
|
},
|
|
3615
3789
|
cleanup: {
|
|
3616
3790
|
summary: "Where simulators come from, and how they get reclaimed",
|
|
3617
|
-
preamble: () => `
|
|
3791
|
+
preamble: () => `DEVICE SLOTS
|
|
3792
|
+
|
|
3793
|
+
Cleanup enumerates every slot. stop --slot <name> keeps the shared server and
|
|
3794
|
+
other slots; plain stop and worktree remove handle the whole workspace.
|
|
3795
|
+
An upgrade retains existing device assignments as the default slot. Do not
|
|
3796
|
+
wipe state to upgrade: it records ownership needed for safe teardown. Use the
|
|
3797
|
+
same slot-aware CLI for all commands while named assignments exist; older
|
|
3798
|
+
versions cannot reliably manage their assignments.
|
|
3799
|
+
|
|
3800
|
+
CLEANUP AND DISK
|
|
3618
3801
|
|
|
3619
3802
|
WHAT RECLAIMS AN OWNED DEVICE
|
|
3620
3803
|
stim worktree remove parks eligible owned simulators and emulators
|