stim 1.12.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-CCZJs__P.mjs → activity-DfVKZTEB.mjs} +42 -25
- package/dist/{android-BQiKJYK0.mjs → android-BHfAu2mf.mjs} +1 -1
- package/dist/{android-B7X-8H7h.mjs → android-CD8pr8Q2.mjs} +62 -47
- package/dist/{android-cas-DzLPXiEn.mjs → android-cas-B9Kv9aIy.mjs} +9 -7
- package/dist/{android-75Sk2rIR.mjs → android-qx_31wJo.mjs} +395 -116
- package/dist/{app-install-CsZi0SAT.mjs → app-install-CDFY2nUL.mjs} +1 -1
- package/dist/{budget-DbzW5VTD.mjs → budget-E5o91NR1.mjs} +154 -37
- package/dist/{build-plan-CqntbR7b.mjs → build-plan-BTa93o_r.mjs} +21 -88
- package/dist/{build-progress-h60GPV27.mjs → build-progress-l7d-X-ZP.mjs} +75 -7
- package/dist/cdp-Dq_ypAlJ.mjs +115 -0
- package/dist/chrome-B5hWgQJS.mjs +61 -0
- package/dist/cli.mjs +16 -15
- package/dist/collector-run.mjs +14 -8
- package/dist/{command-output-BWCj5Vh-.mjs → command-output-BIL7rlX7.mjs} +1 -1
- package/dist/created-devices-Cd558h31.mjs +37 -0
- package/dist/{deps-CO-_7UOm.mjs → deps-2Wo81np9.mjs} +1 -1
- package/dist/{device-9r9xRYDa.mjs → device-Cf7vl-so.mjs} +6 -6
- package/dist/{device-lease-B9LAXIUH.mjs → device-lease-CL9dZf73.mjs} +52 -3
- package/dist/{device-pool-BoezJd-c.mjs → device-pool-MuoiyRcu.mjs} +3 -3
- package/dist/{device-remote-C0_o-tJH.mjs → device-remote-DT9ngZiD.mjs} +10 -10
- package/dist/{doctor-LfDlbR-N.mjs → doctor-D2iysNNH.mjs} +47 -18
- package/dist/{error-diagnostics-CCxjn31V.mjs → error-diagnostics-BoiOhck8.mjs} +6 -6
- package/dist/{gc-C4nQFcTX.mjs → gc-eA-PRBX8.mjs} +853 -126
- package/dist/{guide-BPBlh9ML.mjs → guide-BfZ0OmiP.mjs} +736 -110
- package/dist/{guide-status-i9ogHt4v.mjs → guide-status-BaMYu55M.mjs} +1 -1
- package/dist/{idle-S3tFZ53_.mjs → idle-DxLi5OkN.mjs} +42 -9
- package/dist/{in-use-D9XYEgFD.mjs → in-use-wYEaKQM9.mjs} +9 -5
- package/dist/{ios-CDzWL1mj.mjs → ios-CcfCeZ19.mjs} +98 -54
- package/dist/{ios-CZWOHTTc.mjs → ios-CmEzZiOj.mjs} +10 -5
- package/dist/{ios-device-D9cLxVr5.mjs → ios-device-BW-t_Lkv.mjs} +1 -1
- package/dist/{launch-verify-B2oR_kFN.mjs → launch-verify-CuJaBpEa.mjs} +33 -20
- package/dist/{logs-SzuYudOj.mjs → logs-DcSRbC2t.mjs} +11 -10
- package/dist/{metro-Dzo30hvJ.mjs → metro-BPeY1YMh.mjs} +4 -4
- package/dist/{named-ports-Dn1o61D9.mjs → named-ports-n7tnJsI8.mjs} +78 -6
- package/dist/native-runtime-CiiFHt0e.mjs +74 -0
- package/dist/{ownership-Dqnrjrio.mjs → ownership-Bz2kETAS.mjs} +1 -1
- package/dist/{ownership-B8d4kXBx.mjs → ownership-PUP4Dwai.mjs} +134 -209
- package/dist/page-BTu7I60K.mjs +29 -0
- package/dist/{ports-Dp_QTwTC.mjs → ports-C5UutqpJ.mjs} +4 -4
- package/dist/{project-B8rbutVC.mjs → project-DGeclhvO.mjs} +53 -17
- package/dist/{reload-nocmx8KB.mjs → reload-C-cV5yy_.mjs} +79 -20
- package/dist/{remote-cache-BRsRZru5.mjs → remote-cache--aehr4Pr.mjs} +3 -3
- package/dist/{server-bare-Gn3ssSdK.mjs → server-bare-Bq8BpSIo.mjs} +1 -1
- package/dist/server-expo-BeYwP_Xy.mjs +2 -0
- package/dist/{server-expo-CeT1nIIk.mjs → server-expo-DUCg52-K.mjs} +2 -2
- package/dist/{settings-bE-Gu3Ti.mjs → settings-ssVBToDR.mjs} +10 -10
- package/dist/{settings-BlyDn2Oz.mjs → settings-xB0Frkg6.mjs} +11 -2
- package/dist/settings.schema.json +53 -1
- package/dist/{simslim-COtEEP7x.mjs → simslim-Bbg9UWrt.mjs} +12 -6
- package/dist/{slot-launch-DIACGEfH.mjs → slot-launch-BIWEW-wI.mjs} +3 -3
- package/dist/{start-BboE1HIS.mjs → start-BZhItkiL.mjs} +11 -10
- package/dist/{start-BFstVBlx.mjs → start-Rw2GD3nV.mjs} +1 -1
- package/dist/{state-DcDgzfu3.mjs → state-DwAU2_-D.mjs} +1 -1
- package/dist/state-l1pYwOre.mjs +148 -0
- package/dist/{stats-DiCtmluY.mjs → stats-CaSwmsSZ.mjs} +2 -2
- package/dist/{status-DI9Tjo7T.mjs → status-TJlL0HWo.mjs} +624 -103
- package/dist/{status-BUASYyy_.mjs → status-sszP4XKU.mjs} +59 -2
- package/dist/{stim-desktop-D0xhpZt8.mjs → stim-desktop-CXt8-Z3J.mjs} +13 -2
- package/dist/{stop-Bn6v-GvS.mjs → stop-BZ2qMiBP.mjs} +37 -12
- package/dist/{stop-BI7QY76M.mjs → stop-DskDKNTU.mjs} +2 -2
- package/dist/supervisor-run.mjs +10 -10
- 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-B5sTRskL.mjs → worktree-3cBa-bQt.mjs} +1 -1
- package/dist/{worktree-ChDL5fO1.mjs → worktree-D4Do_XiQ.mjs} +226 -19
- package/dist/{xcode-BzplpQzc.mjs → xcode-LM6A8cNZ.mjs} +5 -5
- package/package.json +5 -5
- package/dist/server-expo-eWi9Coof.mjs +0 -2
- package/dist/workspace-process-lock-BvvJTfo_.mjs +0 -57
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
|
|
2
|
-
import { T as uninstallIosApp, c as iosSimulatorFailureAdvice, p as listUserApps } from "./ios-
|
|
2
|
+
import { T as uninstallIosApp, c as iosSimulatorFailureAdvice, p as listUserApps } from "./ios-CmEzZiOj.mjs";
|
|
3
3
|
import { closeSync, lstatSync, openSync, readSync, readdirSync } from "node:fs";
|
|
4
4
|
import { isAbsolute, join } from "node:path";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { B as deviceSlotPlatforms, E as withConfigLock$1, F as measuredDirectorySize, I as volumeRootFor, M as formatBytes, N as isOnMountedVolume, O as process_identity_exports, P as listMountedVolumes, U as projectDeviceSlots, _ as loadConfig$1, a as clearDevice, d as getConfigDir, g as isPathPrefix, j as directorySize, o as clearSupervisor, p as getProject } from "./config-0jCcMM0E.mjs";
|
|
2
2
|
import { i as registeredCaches } from "./cache-manifest-DWPF4RKJ.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { C as sharedBuildCache, N as workspaceName$1, c as resolveProjectMetro, h as readWorkspaceState$1, k as workspaceDir, n as killMetroTree, y as workspaceLastUsed } from "./metro-BPeY1YMh.mjs";
|
|
4
4
|
import { n as supervisorError } from "./errors-B6W7FkxQ.mjs";
|
|
5
|
-
import { s as clearWorkspaceSupervisor } from "./state-
|
|
6
|
-
import {
|
|
7
|
-
import { l as phaseLine, u as plural } from "./command-output-
|
|
8
|
-
import { i as listLeaseFiles, r as leaseIsExpired } from "./device-lease-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { d as listIosDeviceTypes, g as parseRuntimeVersion, l as listAllIosSims } from "./ios-
|
|
13
|
-
import { i as idleShutdownCandidates, n as collectOwnedDeviceActivity, o as shutDownIdleDevices, s as workspaceBuildInProgress, t as collectIdleDevices } from "./idle-
|
|
14
|
-
import { i as canonicalPath, n as withIdleWorkspace, r as workspaceInUse, t as emptyWorkspaceDir } from "./in-use-
|
|
15
|
-
import { c as formatSpace, r as capacity, s as environmentState } from "./status-
|
|
5
|
+
import { s as clearWorkspaceSupervisor } from "./state-DwAU2_-D.mjs";
|
|
6
|
+
import { a as withWorkspaceProcessLock, o as workspaceProcessLockError } from "./named-ports-n7tnJsI8.mjs";
|
|
7
|
+
import { l as phaseLine, u as plural } from "./command-output-BIL7rlX7.mjs";
|
|
8
|
+
import { i as listLeaseFiles, r as leaseIsExpired } from "./device-lease-CL9dZf73.mjs";
|
|
9
|
+
import { o as workspaceActivity } from "./activity-DfVKZTEB.mjs";
|
|
10
|
+
import { F as ownedAvdDirectory, R as ownedAvdSerialResolver, at as dropParked, k as listAvds, lt as readParked, nt as isStimOwnedSim, tt as isStimOwnedAvd } from "./android-qx_31wJo.mjs";
|
|
11
|
+
import { f as teardownOwnedAvd, g as teardownParkedIosSim, h as teardownParkedAvd, m as teardownOwnedIosSim, p as teardownOwnedBrowser, t as resolveSupervisorTarget } from "./ownership-PUP4Dwai.mjs";
|
|
12
|
+
import { d as listIosDeviceTypes, g as parseRuntimeVersion, l as listAllIosSims } from "./ios-CmEzZiOj.mjs";
|
|
13
|
+
import { c as recordGcResult, i as idleShutdownCandidates, n as collectOwnedDeviceActivity, o as shutDownIdleDevices, s as workspaceBuildInProgress, t as collectIdleDevices } from "./idle-DxLi5OkN.mjs";
|
|
14
|
+
import { i as canonicalPath, n as withIdleWorkspace, r as workspaceInUse, t as emptyWorkspaceDir } from "./in-use-wYEaKQM9.mjs";
|
|
15
|
+
import { c as formatSpace, r as capacity, s as environmentState } from "./status-sszP4XKU.mjs";
|
|
16
16
|
import { existsSync, statSync, statfsSync } from "node:fs";
|
|
17
17
|
import { existsSync as existsSync$1, lstatSync as lstatSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, rmSync as rmSync$1, statSync as statSync$1 } from "fs";
|
|
18
18
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "path";
|
|
@@ -394,7 +394,12 @@ function emptyCache(cache) {
|
|
|
394
394
|
}
|
|
395
395
|
function reportFailures(cache, failed) {
|
|
396
396
|
if (!failed) return;
|
|
397
|
-
|
|
397
|
+
const message = `${failed} entr${failed === 1 ? "y" : "ies"} in ${cache.dir} could not be removed`;
|
|
398
|
+
console.log(chalk.red(`${cache.name}: ${message}`));
|
|
399
|
+
recordGcResult("cache", "failed", cache.name, {
|
|
400
|
+
id: cache.dir,
|
|
401
|
+
detail: message
|
|
402
|
+
});
|
|
398
403
|
process.exitCode = 1;
|
|
399
404
|
}
|
|
400
405
|
function trimCaches(caches, olderThan) {
|
|
@@ -403,13 +408,26 @@ function trimCaches(caches, olderThan) {
|
|
|
403
408
|
for (const c of caches) {
|
|
404
409
|
if (c.machineGlobal) {
|
|
405
410
|
console.log(chalk.yellow(`Left ${c.name} alone: ${c.machineGlobal}`));
|
|
411
|
+
recordGcResult("cache", "kept", c.name, {
|
|
412
|
+
id: c.dir,
|
|
413
|
+
detail: c.machineGlobal
|
|
414
|
+
});
|
|
406
415
|
continue;
|
|
407
416
|
}
|
|
408
417
|
const r = pruneCache(c, { olderThanDays: olderThan });
|
|
409
|
-
if (r.skipped)
|
|
410
|
-
|
|
418
|
+
if (r.skipped) {
|
|
419
|
+
console.log(chalk.yellow(`Left ${c.name} alone: ${r.skipped}`));
|
|
420
|
+
recordGcResult("cache", "kept", c.name, {
|
|
421
|
+
id: c.dir,
|
|
422
|
+
detail: r.skipped
|
|
423
|
+
});
|
|
424
|
+
} else if (r.removed) {
|
|
411
425
|
cacheBytes += r.bytes;
|
|
412
426
|
trimmed.push(c);
|
|
427
|
+
recordGcResult("cache", "done", c.name, {
|
|
428
|
+
id: c.dir,
|
|
429
|
+
bytes: r.bytes
|
|
430
|
+
});
|
|
413
431
|
console.log(chalk.green(`Trimmed ${c.name}: ${r.removed} entr${r.removed === 1 ? "y" : "ies"} (${formatBytes(r.bytes)})`));
|
|
414
432
|
} else if (!r.failed) console.log(chalk.dim(`${c.name}: nothing older than ${olderThan}d`));
|
|
415
433
|
reportFailures(c, r.failed);
|
|
@@ -422,12 +440,25 @@ function emptyCaches(caches) {
|
|
|
422
440
|
for (const c of caches) {
|
|
423
441
|
if (!c.willEmpty) {
|
|
424
442
|
console.log(chalk.yellow(`Left ${c.name} alone: ${c.emptySkipped}`));
|
|
443
|
+
recordGcResult("cache", "kept", c.name, {
|
|
444
|
+
id: c.dir,
|
|
445
|
+
detail: c.emptySkipped ?? null
|
|
446
|
+
});
|
|
425
447
|
continue;
|
|
426
448
|
}
|
|
427
449
|
const r = emptyCache(c);
|
|
428
|
-
if (r.skipped)
|
|
429
|
-
|
|
450
|
+
if (r.skipped) {
|
|
451
|
+
console.log(chalk.yellow(`Left ${c.name} alone: ${r.skipped}`));
|
|
452
|
+
recordGcResult("cache", "kept", c.name, {
|
|
453
|
+
id: c.dir,
|
|
454
|
+
detail: r.skipped
|
|
455
|
+
});
|
|
456
|
+
} else if (r.removed) {
|
|
430
457
|
cacheBytes += r.bytes;
|
|
458
|
+
recordGcResult("cache", "done", c.name, {
|
|
459
|
+
id: c.dir,
|
|
460
|
+
bytes: r.bytes
|
|
461
|
+
});
|
|
431
462
|
console.log(chalk.green(`Emptied ${c.name}: ${r.removed} entr${r.removed === 1 ? "y" : "ies"} (${formatBytes(r.bytes)})`));
|
|
432
463
|
} else if (!r.failed) console.log(chalk.dim(`${c.name}: already empty`));
|
|
433
464
|
reportFailures(c, r.failed);
|
|
@@ -442,7 +473,7 @@ const DAY_MS$1 = 864e5;
|
|
|
442
473
|
function describeKept(ref) {
|
|
443
474
|
return ref.mounted ? `referenced by ${ref.path}` : `referenced by ${ref.path} (volume not mounted; kept just in case)`;
|
|
444
475
|
}
|
|
445
|
-
function findOrphanedDevices({ sims = [], avds = [], config, isMounted, deadProjects = []
|
|
476
|
+
function findOrphanedDevices({ sims = [], avds = [], config, isMounted, deadProjects = [] }) {
|
|
446
477
|
const dead = new Set(deadProjects);
|
|
447
478
|
const referenced = /* @__PURE__ */ new Map();
|
|
448
479
|
for (const [path, proj] of Object.entries(config?.projects || {})) {
|
|
@@ -480,8 +511,11 @@ function findOrphanedDevices({ sims = [], avds = [], config, isMounted, deadProj
|
|
|
480
511
|
id: sim.udid,
|
|
481
512
|
name: sim.name
|
|
482
513
|
};
|
|
483
|
-
if (!ref && !
|
|
484
|
-
else if (!ref) orphaned.push(
|
|
514
|
+
if (!ref && !isStimCreated(device)) unverified.push(device);
|
|
515
|
+
else if (!ref) orphaned.push({
|
|
516
|
+
...device,
|
|
517
|
+
...simBytes(sim)
|
|
518
|
+
});
|
|
485
519
|
else kept.push({
|
|
486
520
|
kind: "ios",
|
|
487
521
|
id: sim.udid,
|
|
@@ -497,7 +531,7 @@ function findOrphanedDevices({ sims = [], avds = [], config, isMounted, deadProj
|
|
|
497
531
|
id: avdName,
|
|
498
532
|
name: avdName
|
|
499
533
|
};
|
|
500
|
-
if (!ref && !
|
|
534
|
+
if (!ref && !isStimCreated(device)) unverified.push(device);
|
|
501
535
|
else if (!ref) orphaned.push(device);
|
|
502
536
|
else kept.push({
|
|
503
537
|
kind: "android",
|
|
@@ -512,20 +546,24 @@ function findOrphanedDevices({ sims = [], avds = [], config, isMounted, deadProj
|
|
|
512
546
|
unverified
|
|
513
547
|
};
|
|
514
548
|
}
|
|
549
|
+
function simBytes(sim) {
|
|
550
|
+
return typeof sim.dataPathSize === "number" ? { bytes: sim.dataPathSize } : {};
|
|
551
|
+
}
|
|
515
552
|
function isStimCreated(device) {
|
|
516
553
|
return device.kind === "ios" ? isStimOwnedSim({
|
|
517
554
|
udid: device.id,
|
|
518
555
|
name: device.name
|
|
519
|
-
}) :
|
|
556
|
+
}) : isStimOwnedAvd(device.id);
|
|
520
557
|
}
|
|
521
558
|
function unverifiedDeviceCommand(device) {
|
|
522
|
-
|
|
559
|
+
if (device.kind === "ios") return `xcrun simctl delete ${device.id}`;
|
|
560
|
+
return device.directory ? `rm -rf ${JSON.stringify(device.directory)}` : `avdmanager delete avd -n ${JSON.stringify(device.id)}`;
|
|
523
561
|
}
|
|
524
562
|
function findStaleProjectDevices({ config, sims = [], avds = [], olderThanDays, now = Date.now(), lastTouched, deadProjects = [] }) {
|
|
525
563
|
if (!Number.isFinite(olderThanDays) || typeof lastTouched !== "function") return [];
|
|
526
564
|
const cutoff = now - olderThanDays * DAY_MS$1;
|
|
527
565
|
const dead = new Set(deadProjects);
|
|
528
|
-
const liveSims = new Map(sims.filter((s) => s?.name?.startsWith("stim-")).map((s) => [s.udid, s
|
|
566
|
+
const liveSims = new Map(sims.filter((s) => s?.name?.startsWith("stim-")).map((s) => [s.udid, s]));
|
|
529
567
|
const liveAvds = new Set(avds.filter((a) => typeof a === "string" && a.startsWith("stim-")));
|
|
530
568
|
const stale = [];
|
|
531
569
|
for (const [path, proj] of Object.entries(config?.projects || {})) {
|
|
@@ -535,13 +573,15 @@ function findStaleProjectDevices({ config, sims = [], avds = [], olderThanDays,
|
|
|
535
573
|
const idleDays = Math.floor((now - touched) / DAY_MS$1);
|
|
536
574
|
for (const { slot, platforms } of projectDeviceSlots(proj)) {
|
|
537
575
|
const ios = platforms.ios;
|
|
538
|
-
|
|
576
|
+
const sim = ios?.owned && ios.deviceUdid ? liveSims.get(ios.deviceUdid) : void 0;
|
|
577
|
+
if (sim) stale.push({
|
|
539
578
|
kind: "ios",
|
|
540
|
-
id:
|
|
541
|
-
name:
|
|
579
|
+
id: sim.udid,
|
|
580
|
+
name: sim.name,
|
|
542
581
|
project: path,
|
|
543
582
|
...slot === "default" ? {} : { slot },
|
|
544
|
-
idleDays
|
|
583
|
+
idleDays,
|
|
584
|
+
...simBytes(sim)
|
|
545
585
|
});
|
|
546
586
|
const android = platforms.android;
|
|
547
587
|
if (android?.owned && android.avdName && liveAvds.has(android.avdName)) stale.push({
|
|
@@ -681,14 +721,27 @@ function deleteParkedAvds(avds) {
|
|
|
681
721
|
if (avd.listed === null) {
|
|
682
722
|
failures++;
|
|
683
723
|
console.log(chalk.red(`Could not verify parked android emulator ${avd.name}; its pool record was kept.`));
|
|
724
|
+
recordGcResult("parkedDevice", "failed", avd.name, {
|
|
725
|
+
id: avd.name,
|
|
726
|
+
detail: "Stim could not list emulators to verify it; its pool record was kept. Retry stim gc --delete."
|
|
727
|
+
});
|
|
684
728
|
continue;
|
|
685
729
|
}
|
|
686
730
|
const result = teardownParkedAvd(avd.name);
|
|
687
731
|
if (result.status === "failed") {
|
|
688
732
|
failures++;
|
|
689
733
|
console.log(chalk.red(`Failed to delete parked android emulator ${avd.name}: ${result.reason}`));
|
|
690
|
-
|
|
691
|
-
|
|
734
|
+
recordGcResult("parkedDevice", "failed", avd.name, {
|
|
735
|
+
id: avd.name,
|
|
736
|
+
detail: result.reason
|
|
737
|
+
});
|
|
738
|
+
} else if (result.status === "torn-down") {
|
|
739
|
+
console.log(chalk.green(`Deleted parked android emulator ${avd.name}`));
|
|
740
|
+
recordGcResult("parkedDevice", "done", avd.name, {
|
|
741
|
+
id: avd.name,
|
|
742
|
+
bytes: avd.bytes
|
|
743
|
+
});
|
|
744
|
+
} else console.log(chalk.dim(`Skipped ${avd.name}; it is no longer parked.`));
|
|
692
745
|
}
|
|
693
746
|
return failures;
|
|
694
747
|
}
|
|
@@ -699,6 +752,10 @@ function deleteParkedSims(parkedSims, deps = {}) {
|
|
|
699
752
|
if (sim.listed === null) {
|
|
700
753
|
failures++;
|
|
701
754
|
console.log(chalk.red(`Could not verify parked ios sim ${sim.name} (${sim.udid}); its pool record was kept.`));
|
|
755
|
+
recordGcResult("parkedDevice", "failed", sim.name, {
|
|
756
|
+
id: sim.udid,
|
|
757
|
+
detail: "Stim could not list simulators to verify it; its pool record was kept. Retry stim gc --delete."
|
|
758
|
+
});
|
|
702
759
|
continue;
|
|
703
760
|
}
|
|
704
761
|
try {
|
|
@@ -710,14 +767,26 @@ function deleteParkedSims(parkedSims, deps = {}) {
|
|
|
710
767
|
if (teardown?.status === "failed") {
|
|
711
768
|
failures++;
|
|
712
769
|
console.log(chalk.red(`Failed to delete parked ios sim ${sim.name}: ${teardown.reason}`));
|
|
770
|
+
recordGcResult("parkedDevice", "failed", sim.name, {
|
|
771
|
+
id: sim.udid,
|
|
772
|
+
detail: teardown.reason
|
|
773
|
+
});
|
|
713
774
|
} else console.log(chalk.dim(`Skipped ${sim.name} (${sim.udid}); it is no longer parked.`));
|
|
714
775
|
continue;
|
|
715
776
|
}
|
|
716
777
|
emptied++;
|
|
778
|
+
recordGcResult("parkedDevice", "done", sim.name, {
|
|
779
|
+
id: sim.udid,
|
|
780
|
+
bytes: sim.listed ? sim.bytes : null
|
|
781
|
+
});
|
|
717
782
|
console.log(chalk.green(sim.listed ? `Deleted parked ios sim ${sim.name} (${sim.udid})` : `Dropped the parked record for ${sim.name} (${sim.udid}); it is not on this machine.`));
|
|
718
783
|
} catch (err) {
|
|
719
784
|
failures++;
|
|
720
785
|
console.log(chalk.red(`Failed to delete parked ios sim ${sim.name}: ${err?.message || err}`));
|
|
786
|
+
recordGcResult("parkedDevice", "failed", sim.name, {
|
|
787
|
+
id: sim.udid,
|
|
788
|
+
detail: err?.message || String(err)
|
|
789
|
+
});
|
|
721
790
|
}
|
|
722
791
|
}
|
|
723
792
|
if (emptied) console.log(chalk.dim(` emptied ${plural(emptied, "parked simulator")} from the pool`));
|
|
@@ -773,12 +842,27 @@ function deleteProjectDevices(orphanedDevices, staleDevices, staleDeviceRecords)
|
|
|
773
842
|
..."orphanedDirectory" in d ? { orphanedDirectory: d.orphanedDirectory } : {}
|
|
774
843
|
});
|
|
775
844
|
const what = d.kind === "ios" ? `ios sim ${d.name} (${d.id})` : `android avd ${d.name}`;
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
845
|
+
const result = {
|
|
846
|
+
id: d.id,
|
|
847
|
+
bytes: d.bytes ?? null
|
|
848
|
+
};
|
|
849
|
+
if (r.status === "torn-down") {
|
|
850
|
+
console.log(chalk.green(`Deleted ${what}`));
|
|
851
|
+
recordGcResult("device", "done", d.name, result);
|
|
852
|
+
} else if (r.status === "missing") console.log(chalk.dim(`${what} is already gone; nothing to delete.`));
|
|
853
|
+
else if (r.status === "skipped") {
|
|
854
|
+
console.log(chalk.yellow(`Skipped ${what}: ${r.reason} -- left for a later gc`));
|
|
855
|
+
recordGcResult("device", "kept", d.name, {
|
|
856
|
+
...result,
|
|
857
|
+
detail: `${r.reason}; left for a later gc`
|
|
858
|
+
});
|
|
859
|
+
} else {
|
|
780
860
|
deleteFailures++;
|
|
781
861
|
console.log(chalk.red(`Failed to delete ${d.kind} device ${d.name}: ${r.reason}`));
|
|
862
|
+
recordGcResult("device", "failed", d.name, {
|
|
863
|
+
...result,
|
|
864
|
+
detail: r.reason
|
|
865
|
+
});
|
|
782
866
|
}
|
|
783
867
|
return r.status;
|
|
784
868
|
}
|
|
@@ -798,7 +882,10 @@ function deleteProjectDevices(orphanedDevices, staleDevices, staleDeviceRecords)
|
|
|
798
882
|
else if (withConfigLock$1(() => {
|
|
799
883
|
if (r.kind === "android" && deviceSlotPlatforms(getProject(r.project), r.slot)?.android?.owned) return false;
|
|
800
884
|
return clearDevice(r.project, r.kind, r.slot, r.id);
|
|
801
|
-
}))
|
|
885
|
+
})) {
|
|
886
|
+
console.log(chalk.green(`Cleared the ${r.kind} record for ${r.project} (${r.id} is not on this machine)`));
|
|
887
|
+
recordGcResult("deviceRecord", "done", r.project, { id: r.id });
|
|
888
|
+
}
|
|
802
889
|
return deleteFailures;
|
|
803
890
|
}
|
|
804
891
|
//#endregion
|
|
@@ -984,7 +1071,13 @@ async function clearWorkspaceOutputs(report, { olderThan, now = Date.now() }) {
|
|
|
984
1071
|
for (const entry of report.workspaces) {
|
|
985
1072
|
const root = entry.projectRoot;
|
|
986
1073
|
if (!entry.willClear || root === null) {
|
|
987
|
-
if (entry.keptReason)
|
|
1074
|
+
if (entry.keptReason) {
|
|
1075
|
+
console.log(chalk.dim(`Kept the build outputs of ${root ?? entry.dir}: ${entry.keptReason}`));
|
|
1076
|
+
recordGcResult("workspaceOutputs", "kept", root ?? entry.dir, {
|
|
1077
|
+
bytes: entry.bytes,
|
|
1078
|
+
detail: entry.keptReason
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
988
1081
|
continue;
|
|
989
1082
|
}
|
|
990
1083
|
let run;
|
|
@@ -1009,16 +1102,25 @@ async function clearWorkspaceOutputs(report, { olderThan, now = Date.now() }) {
|
|
|
1009
1102
|
} catch (error) {
|
|
1010
1103
|
failures++;
|
|
1011
1104
|
console.log(chalk.red(`Could not clear the build outputs of ${root}: ${error?.message || String(error)}`));
|
|
1105
|
+
recordGcResult("workspaceOutputs", "failed", root, {
|
|
1106
|
+
bytes: entry.bytes,
|
|
1107
|
+
detail: error?.message || String(error)
|
|
1108
|
+
});
|
|
1012
1109
|
continue;
|
|
1013
1110
|
}
|
|
1014
1111
|
const kept = run.ran ? run.value : `in use: ${run.reasons.join("; ")}`;
|
|
1015
1112
|
if (kept) {
|
|
1016
1113
|
console.log(chalk.yellow(`Kept the build outputs of ${root}: ${kept}`));
|
|
1114
|
+
recordGcResult("workspaceOutputs", "kept", root, {
|
|
1115
|
+
bytes: entry.bytes,
|
|
1116
|
+
detail: kept
|
|
1117
|
+
});
|
|
1017
1118
|
continue;
|
|
1018
1119
|
}
|
|
1019
1120
|
cleared += entry.bytes ?? 0;
|
|
1020
1121
|
clearedRoots.push(root);
|
|
1021
1122
|
console.log(chalk.green(`Cleared the build outputs of ${root} (${sizeText(entry.bytes)})`));
|
|
1123
|
+
recordGcResult("workspaceOutputs", "done", root, { bytes: entry.bytes });
|
|
1022
1124
|
}
|
|
1023
1125
|
if (cleared) console.log(chalk.dim(`Cleared ${formatBytes(cleared)} of workspace build outputs. ${REBUILD_COST}`));
|
|
1024
1126
|
return {
|
|
@@ -1036,26 +1138,41 @@ async function deleteOrphanedWorkspaces(orphaned) {
|
|
|
1036
1138
|
if (!existsSync$1(entry.dir)) continue;
|
|
1037
1139
|
let run;
|
|
1038
1140
|
try {
|
|
1039
|
-
run = await withIdleWorkspace(entry.projectRoot, () => {
|
|
1141
|
+
run = await withIdleWorkspace(entry.projectRoot, async () => {
|
|
1040
1142
|
if (!stillOrphaned(entry)) return false;
|
|
1143
|
+
const browser = await teardownOwnedBrowser(entry.projectRoot, { deleteProfile: true });
|
|
1144
|
+
if (browser.status === "failed" || browser.status === "skipped") throw new Error(`its owned Chrome profile was kept: ${browser.reason}`);
|
|
1041
1145
|
emptyWorkspaceDir(entry.dir);
|
|
1042
1146
|
return true;
|
|
1043
1147
|
}, { purpose: "gc" });
|
|
1044
1148
|
} catch (error) {
|
|
1045
1149
|
failures++;
|
|
1046
1150
|
console.log(chalk.red(`Could not remove ${entry.dir}: ${error?.message || error}`));
|
|
1151
|
+
recordGcResult("workspaceDirectory", "failed", entry.dir, {
|
|
1152
|
+
bytes: entry.bytes ?? null,
|
|
1153
|
+
detail: error?.message || String(error)
|
|
1154
|
+
});
|
|
1047
1155
|
continue;
|
|
1048
1156
|
}
|
|
1049
1157
|
if (!run.ran) {
|
|
1050
1158
|
console.log(chalk.yellow(`Kept ${entry.dir}: ${run.reasons.join("; ")}`));
|
|
1159
|
+
recordGcResult("workspaceDirectory", "kept", entry.dir, {
|
|
1160
|
+
bytes: entry.bytes ?? null,
|
|
1161
|
+
detail: run.reasons.join("; ")
|
|
1162
|
+
});
|
|
1051
1163
|
continue;
|
|
1052
1164
|
}
|
|
1053
1165
|
if (!run.value) {
|
|
1054
1166
|
console.log(chalk.yellow(`Kept ${entry.dir}: it can no longer be confirmed orphaned.`));
|
|
1167
|
+
recordGcResult("workspaceDirectory", "kept", entry.dir, {
|
|
1168
|
+
bytes: entry.bytes ?? null,
|
|
1169
|
+
detail: "it can no longer be confirmed orphaned"
|
|
1170
|
+
});
|
|
1055
1171
|
continue;
|
|
1056
1172
|
}
|
|
1057
1173
|
const size = entry.bytes === void 0 ? "" : ` (${sizeText(entry.bytes)})`;
|
|
1058
1174
|
console.log(chalk.green(`Removed the orphaned workspace directory ${entry.dir}${size}`));
|
|
1175
|
+
recordGcResult("workspaceDirectory", "done", entry.dir, { bytes: entry.bytes ?? null });
|
|
1059
1176
|
}
|
|
1060
1177
|
return failures;
|
|
1061
1178
|
}
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { B as deviceSlotPlatforms, C as setDevice, E as withConfigLock$1, S as saveConfig, U as projectDeviceSlots, _ as loadConfig$1, a as clearDevice, d as getConfigDir, i as clearAndroidBootPending, k as acquireAvdClaim, t as allConsolePortsAndSerials, y as releaseAndroidConsolePort } from "./config-0jCcMM0E.mjs";
|
|
2
2
|
import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { A as workspaceId, C as sharedBuildCache, _ as updateWorkspaceState, a as pidExists, h as readWorkspaceState$1 } from "./metro-BPeY1YMh.mjs";
|
|
4
4
|
import { D as makeTemporaryDirectory, O as removeTemporaryEntry, c as gitCommonDirOnDisk } from "./worktree-DeBQSVtR.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { c as ownedDeviceLabel, r as detectIsExpo, s as isPackageResolvable } from "./project-DGeclhvO.mjs";
|
|
6
6
|
import { a as spawnDeclared } from "./spawn-claims-PT8aQpCa.mjs";
|
|
7
|
-
import {
|
|
7
|
+
import { a as withWorkspaceProcessLock } from "./named-ports-n7tnJsI8.mjs";
|
|
8
8
|
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
|
|
9
|
-
import { i as formatDuration, l as phaseLine, m as shortHash, u as plural } from "./command-output-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting, v as iosSimSlimProfileSetting } from "./settings-
|
|
13
|
-
import {
|
|
14
|
-
import { E as configuredIosSimulatorViewer, O as hostMemoryPressureAdvice, S as resolveOwnedIosSim, b as resetIosPrivacy, c as iosSimulatorFailureAdvice, d as listIosDeviceTypes, g as parseRuntimeVersion, k as readHostMemoryPressure, l as listAllIosSims, m as ownedSimName, n as bootIosSim, r as createOwnedIosSim, v as renameIosSim, x as resolveIosCreation, y as resetIosKeychain } from "./ios-
|
|
15
|
-
import { o as estimateBuild } from "./build-progress-
|
|
16
|
-
import { i as expoBinRefusal, r as expoBinPath, t as cleanLine } from "./server-expo-
|
|
17
|
-
import { a as easAuthNote } from "./remote-cache
|
|
18
|
-
import {
|
|
19
|
-
import { a as liveOwnedDeviceCount, i as deviceTypeMismatch, t as reconcileSimSlim } from "./simslim-COtEEP7x.mjs";
|
|
20
|
-
import { s as startDevServer } from "./start-BboE1HIS.mjs";
|
|
9
|
+
import { i as formatDuration, l as phaseLine, m as shortHash, u as plural } from "./command-output-BIL7rlX7.mjs";
|
|
10
|
+
import { C as diffFingerprintSources, I as storedSources, w as entryDir, y as artifactIn } from "./device-lease-CL9dZf73.mjs";
|
|
11
|
+
import { $ as waitForBoot, A as listInstalledSystemImages, D as listAdbDevices, I as ownedAvdMatchesConfiguration, L as ownedAvdName, N as nextConsolePort, P as ownedAvdDeviceProfile, T as getAvdNameForSerial, U as pickDefaultSystemImage, _ as bootAndroidEmulator, at as dropParked, ct as parkedMaxSetting, d as assertOwnedAvdStopped, dt as selectParked, h as avdPoolConfiguration, it as adoptParked, k as listAvds, lt as readParked, n as OWNED_AVD_CONFIG_DEFAULTS, ot as isLegacyDeletionClaim, q as resolveOwnedAvdSerial, t as DEFAULT_AVD_DEVICE_PROFILE, v as configureNewOwnedAvd, y as createOwnedAvd, z as ownedAvdSystemImage } from "./android-qx_31wJo.mjs";
|
|
12
|
+
import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting, v as iosSimSlimProfileSetting } from "./settings-xB0Frkg6.mjs";
|
|
13
|
+
import { f as teardownOwnedAvd, g as teardownParkedIosSim, h as teardownParkedAvd } from "./ownership-PUP4Dwai.mjs";
|
|
14
|
+
import { E as configuredIosSimulatorViewer, O as hostMemoryPressureAdvice, S as resolveOwnedIosSim, b as resetIosPrivacy, c as iosSimulatorFailureAdvice, d as listIosDeviceTypes, f as listIosRuntimes, g as parseRuntimeVersion, k as readHostMemoryPressure, l as listAllIosSims, m as ownedSimName, n as bootIosSim, r as createOwnedIosSim, v as renameIosSim, x as resolveIosCreation, y as resetIosKeychain } from "./ios-CmEzZiOj.mjs";
|
|
15
|
+
import { o as estimateBuild } from "./build-progress-l7d-X-ZP.mjs";
|
|
16
|
+
import { i as expoBinRefusal, r as expoBinPath, t as cleanLine } from "./server-expo-DUCg52-K.mjs";
|
|
17
|
+
import { a as easAuthNote } from "./remote-cache--aehr4Pr.mjs";
|
|
18
|
+
import { a as liveOwnedDeviceCount, i as deviceTypeMismatch, o as runtimeMismatch, t as reconcileSimSlim } from "./simslim-Bbg9UWrt.mjs";
|
|
21
19
|
import { r as readStats } from "./stats-D8rUTPHd.mjs";
|
|
22
|
-
import { d as startBuildHeartbeat, f as tailLines, n as HEARTBEAT_INTERVAL_MS } from "./xcode-
|
|
20
|
+
import { d as startBuildHeartbeat, f as tailLines, n as HEARTBEAT_INTERVAL_MS } from "./xcode-LM6A8cNZ.mjs";
|
|
23
21
|
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync } from "node:fs";
|
|
24
|
-
import { LAST_BUILD_KEYS, isJsonObject, loadConfig,
|
|
22
|
+
import { LAST_BUILD_KEYS, isJsonObject, loadConfig, readJsonObject, readWorkspaceState } from "@stim-cli/core/state";
|
|
25
23
|
import { basename, dirname, join, relative } from "node:path";
|
|
26
24
|
import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
|
|
27
25
|
import { captureProcessIdentity } from "@stim-cli/core/process-identity";
|
|
@@ -93,73 +91,6 @@ async function warmMetro({ port, platform, isExpo, appId, bundleUrl }) {
|
|
|
93
91
|
} catch {}
|
|
94
92
|
}
|
|
95
93
|
//#endregion
|
|
96
|
-
//#region src/commands/native-runtime.ts
|
|
97
|
-
const sleep$1 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
98
|
-
async function ensureDevServer({ root, port, settings, remote, note, resolve = resolveProjectMetro, start = startDevServer, readState = readWorkspaceState$1 }) {
|
|
99
|
-
const held = port === null ? null : (await resolve(port, root)).metro;
|
|
100
|
-
if (port !== null && held) return {
|
|
101
|
-
ok: true,
|
|
102
|
-
port,
|
|
103
|
-
pid: held.pid ?? null,
|
|
104
|
-
devServer: null,
|
|
105
|
-
reclaimed: []
|
|
106
|
-
};
|
|
107
|
-
const reason = readIdleStop(readState(root)) ? "stopped (idle)" : "not running";
|
|
108
|
-
note(chalk.dim(phaseLine("metro", `dev server ${reason}; starting it${remote ? " for a remote device" : ""}`)));
|
|
109
|
-
const result = await start({
|
|
110
|
-
root,
|
|
111
|
-
settings,
|
|
112
|
-
remote,
|
|
113
|
-
out: note,
|
|
114
|
-
note
|
|
115
|
-
});
|
|
116
|
-
if (!result.ok) return {
|
|
117
|
-
ok: false,
|
|
118
|
-
code: result.error.code,
|
|
119
|
-
message: `Could not start this workspace's dev server: ${result.error.message}`,
|
|
120
|
-
remedy: result.error.remedy,
|
|
121
|
-
lines: result.lines,
|
|
122
|
-
reclaimed: result.reclaimed
|
|
123
|
-
};
|
|
124
|
-
const { facts } = result;
|
|
125
|
-
return {
|
|
126
|
-
ok: true,
|
|
127
|
-
port: facts.port,
|
|
128
|
-
pid: facts.supervisorPid,
|
|
129
|
-
devServer: facts.alreadyRunning ? null : {
|
|
130
|
-
started: true,
|
|
131
|
-
reason
|
|
132
|
-
},
|
|
133
|
-
reclaimed: result.reclaimed
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
async function ensureWorkspaceStorageSafely(root, { note = (_line) => {} } = {}) {
|
|
137
|
-
try {
|
|
138
|
-
return ensureWorkspaceStorage(root);
|
|
139
|
-
} catch (err) {
|
|
140
|
-
note(chalk.dim(`Could not prepare this workspace's Stim state: ${err?.message || err}`));
|
|
141
|
-
throw err;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function launchOutcomeRecord({ launchState, release, bundleId, configuration, metroPort }) {
|
|
145
|
-
const unverified = launchState === LAUNCH_UNVERIFIED;
|
|
146
|
-
const bundling = launchState === LAUNCH_BUNDLING;
|
|
147
|
-
let msg;
|
|
148
|
-
if (release) msg = unverified ? `${bundleId} could not be verified as running after its ${configuration} launch` : `${bundleId} is running its embedded ${configuration} bundle`;
|
|
149
|
-
else if (unverified) msg = `no bundle request from ${bundleId} reached this workspace's Metro on port ${metroPort}`;
|
|
150
|
-
else if (bundling) msg = `${bundleId} requested a bundle from this workspace's Metro on port ${metroPort}; it was still being built when the launch check ended`;
|
|
151
|
-
else msg = `${bundleId} fetched a bundle from this workspace's Metro on port ${metroPort}`;
|
|
152
|
-
return {
|
|
153
|
-
src: "build",
|
|
154
|
-
level: unverified ? "warn" : "info",
|
|
155
|
-
event: unverified ? "launch_unverified" : bundling ? "launch_bundling" : "launch_verified",
|
|
156
|
-
msg
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
function isPhysicalDeviceRequest(flag) {
|
|
160
|
-
return flag !== null && flag !== void 0 && flag !== false;
|
|
161
|
-
}
|
|
162
|
-
//#endregion
|
|
163
94
|
//#region src/engine/device-ios.ts
|
|
164
95
|
function startIosBoot(udid, configure, label, out, simulatorApp) {
|
|
165
96
|
const done = (async () => {
|
|
@@ -183,13 +114,15 @@ async function ensureOwnedIosDevice({ record, projectPath, slot, settingsRoot, l
|
|
|
183
114
|
if (record?.deviceUdid) {
|
|
184
115
|
if (record.owned) {
|
|
185
116
|
const resolved = resolveOwnedIosSim(record.deviceUdid);
|
|
186
|
-
if (resolved.notOwned) note(chalk.yellow(`Note: recorded sim is now named "${resolved.notOwned}", not Stim-owned
|
|
117
|
+
if (resolved.notOwned) note(chalk.yellow(`Note: recorded sim is now named "${resolved.notOwned}", not Stim-owned -- creating a fresh owned sim instead of booting it.`));
|
|
187
118
|
else if (resolved.missing) {} else {
|
|
188
119
|
const sim = resolved.sim;
|
|
189
120
|
const wantedType = flags.deviceType || settings?.ios?.deviceType;
|
|
190
121
|
const deviceTypes = listIosDeviceTypes();
|
|
191
122
|
const mismatch = deviceTypeMismatch(sim.deviceTypeIdentifier, wantedType, deviceTypes);
|
|
192
123
|
if (mismatch) throw new Error(`${mismatch}. Stim will not silently boot a different model. Run \`stim worktree remove\` (or \`stim gc --delete\`) to reap the current sim, then \`stim ios\` again to create the requested one.`);
|
|
124
|
+
const versionMismatch = flags.runtimeFlag ? runtimeMismatch(sim.runtime, flags.runtimeFlag, listIosRuntimes()) : null;
|
|
125
|
+
if (versionMismatch) throw new Error(`${versionMismatch}. Stim will not silently boot a different iOS version. Run \`stim worktree remove\` (or \`stim gc --delete\`) to reap the current sim, then \`stim ios\` again to create the requested one, or pass \`--slot <name>\` to create it beside the current one.`);
|
|
193
126
|
const model = {
|
|
194
127
|
model: deviceTypes.find((d) => d.identifier === sim.deviceTypeIdentifier)?.name ?? null,
|
|
195
128
|
runtime: parseRuntimeVersion(sim.runtime)
|
|
@@ -731,7 +664,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
|
|
|
731
664
|
const resolved = resolveOwnedAvdSerial(record.avdName);
|
|
732
665
|
const currentProfile = resolved.notOwned || resolved.missing ? null : ownedAvdDeviceProfile(record.avdName);
|
|
733
666
|
if (requestedProfile && currentProfile && currentProfile !== requestedProfile) throw new AvdRecoveryError(`this project's emulator uses device profile ${currentProfile}, but ${requestedProfile} was requested. Stim will not silently boot a different model.`, "Run `stim worktree remove` (or `stim gc --delete`) to reap the current emulator, then `stim android` again to create the requested one, or pass `--slot <name>` to create it beside the current one.");
|
|
734
|
-
if (resolved.notOwned) note(chalk.yellow(`Note: recorded AVD ${record.avdName} is not Stim-owned
|
|
667
|
+
if (resolved.notOwned) note(chalk.yellow(`Note: recorded AVD ${record.avdName} is not Stim-owned -- creating a fresh owned AVD instead of reusing it.`));
|
|
735
668
|
else if (resolved.serial) {
|
|
736
669
|
const consolePort = Number(resolved.serial.replace(/^emulator-/, ""));
|
|
737
670
|
if (record.consolePort && record.consolePort !== consolePort) out(phaseLine("device", `${record.avdName} changed serial (emulator-${record.consolePort} -> ${resolved.serial}); reconnecting this run, reopen agent-device on ${resolved.serial}`));
|
|
@@ -1003,7 +936,7 @@ async function ensureAndroidBooted({ device, projectPath, slot, timeoutMs, out,
|
|
|
1003
936
|
};
|
|
1004
937
|
if (resolved.notOwned) return {
|
|
1005
938
|
failed: true,
|
|
1006
|
-
reason: `AVD ${device.avdName} is not Stim-owned
|
|
939
|
+
reason: `AVD ${device.avdName} is not Stim-owned; refusing to boot it.`
|
|
1007
940
|
};
|
|
1008
941
|
const avdName = device.avdName;
|
|
1009
942
|
const booted = (result) => {
|
|
@@ -2048,4 +1981,4 @@ function planFlagRefusal(flag) {
|
|
|
2048
1981
|
};
|
|
2049
1982
|
}
|
|
2050
1983
|
//#endregion
|
|
2051
|
-
export {
|
|
1984
|
+
export { warmMetro as C, clearIosAdoptionPending as S, staleNativeDirRefusal as _, refusePlan as a, AvdBootError as b, skippedMissReason as c, schemesFromInfoPlist as d, detectEntryFile as f, runPrebuild as g, recordPrebuild as h, printPlan as i, devClientScheme as l, planPrebuild as m, planFlagRefusal as n, explainBuildMiss as o, swapJsBundle as p, planPayload as r, fingerprintErrorMissReason as s, planCachedBuild as t, pickDevClientScheme as u, ensureBooted as v, AvdRecoveryError as x, ensureOwnedDevice as y };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as ownership_claim_exports } from "./config-0jCcMM0E.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as formatElapsed, u as plural } from "./command-output-
|
|
4
|
-
import { BUILD_PHASES } from "@stim-cli/core/state";
|
|
2
|
+
import { _ as updateWorkspaceState, p as clearWorkspaceStateKey } from "./metro-BPeY1YMh.mjs";
|
|
3
|
+
import { a as formatElapsed, u as plural } from "./command-output-BIL7rlX7.mjs";
|
|
4
|
+
import { BUILD_HISTORY_KEY, BUILD_HISTORY_LIMIT, BUILD_PHASES, LAST_BUILD_KEYS } from "@stim-cli/core/state";
|
|
5
5
|
//#region src/engine/build-progress.ts
|
|
6
6
|
const ACTIVE_BUILD_KEY = "activeBuild";
|
|
7
7
|
const NO_BUILD_PROGRESS = {
|
|
@@ -44,11 +44,11 @@ function startBuildProgress({ root, platform, slot, claim, now = Date.now, note
|
|
|
44
44
|
note(`Build progress could not be recorded in the workspace state: ${error?.message || error}`);
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
const write = () => guard(() => updateWorkspaceState(root, (state) => ({
|
|
48
|
-
...state,
|
|
47
|
+
const write = (before = (state) => state) => guard(() => updateWorkspaceState(root, (state) => ({
|
|
48
|
+
...before(state),
|
|
49
49
|
[ACTIVE_BUILD_KEY]: record
|
|
50
50
|
})));
|
|
51
|
-
write();
|
|
51
|
+
write(withInterruptedBuild);
|
|
52
52
|
return {
|
|
53
53
|
step(phase) {
|
|
54
54
|
if (phase === record.phase) return;
|
|
@@ -82,6 +82,74 @@ function phaseDurations(phases, now) {
|
|
|
82
82
|
});
|
|
83
83
|
return out;
|
|
84
84
|
}
|
|
85
|
+
const HISTORY_FIELDS = [
|
|
86
|
+
"platform",
|
|
87
|
+
"status",
|
|
88
|
+
"configuration",
|
|
89
|
+
"fingerprint",
|
|
90
|
+
"cacheKey",
|
|
91
|
+
"cacheHit",
|
|
92
|
+
"cacheSkipped",
|
|
93
|
+
"durationMs",
|
|
94
|
+
"startedAt",
|
|
95
|
+
"errorCode",
|
|
96
|
+
"missReason",
|
|
97
|
+
"diagnostics"
|
|
98
|
+
];
|
|
99
|
+
function withHistoryEntry(state, platform, entry) {
|
|
100
|
+
const saved = state[BUILD_HISTORY_KEY];
|
|
101
|
+
const history = saved && typeof saved === "object" && !Array.isArray(saved) ? saved : {};
|
|
102
|
+
const list = Array.isArray(history[platform]) ? history[platform] : [];
|
|
103
|
+
return {
|
|
104
|
+
...state,
|
|
105
|
+
[BUILD_HISTORY_KEY]: {
|
|
106
|
+
...history,
|
|
107
|
+
[platform]: [entry, ...list].slice(0, BUILD_HISTORY_LIMIT)
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function finishedResult(record) {
|
|
112
|
+
if (record.status === "ok") return "succeeded";
|
|
113
|
+
return record.errorCode === "STIM_CANCELLED" ? "cancelled" : "failed";
|
|
114
|
+
}
|
|
115
|
+
function recordFinishedBuild(root, record, { update = updateWorkspaceState, now = Date.now } = {}) {
|
|
116
|
+
const platform = record.platform;
|
|
117
|
+
update(root, (state) => {
|
|
118
|
+
const active = parseActiveBuild(state[ACTIVE_BUILD_KEY]);
|
|
119
|
+
const own = active?.platform === platform ? active : null;
|
|
120
|
+
const entry = {
|
|
121
|
+
...Object.fromEntries(HISTORY_FIELDS.filter((key) => key in record).map((key) => [key, record[key]])),
|
|
122
|
+
result: finishedResult(record),
|
|
123
|
+
slot: own?.slot ?? "default",
|
|
124
|
+
phases: own ? phaseDurations(own.phases, now()) : {}
|
|
125
|
+
};
|
|
126
|
+
return withHistoryEntry({
|
|
127
|
+
...state,
|
|
128
|
+
lastBuild: record,
|
|
129
|
+
[LAST_BUILD_KEYS[platform]]: record
|
|
130
|
+
}, platform, entry);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function withInterruptedBuild(state) {
|
|
134
|
+
const left = parseActiveBuild(state[ACTIVE_BUILD_KEY]);
|
|
135
|
+
if (!left) return state;
|
|
136
|
+
const last = state[LAST_BUILD_KEYS[left.platform]];
|
|
137
|
+
if (Date.parse(String(last?.startedAt)) >= Date.parse(left.startedAt)) return state;
|
|
138
|
+
return withHistoryEntry(state, left.platform, {
|
|
139
|
+
platform: left.platform,
|
|
140
|
+
status: "failed",
|
|
141
|
+
result: "interrupted",
|
|
142
|
+
slot: left.slot,
|
|
143
|
+
configuration: null,
|
|
144
|
+
fingerprint: null,
|
|
145
|
+
cacheKey: null,
|
|
146
|
+
cacheHit: false,
|
|
147
|
+
cacheSkipped: false,
|
|
148
|
+
durationMs: null,
|
|
149
|
+
startedAt: left.startedAt,
|
|
150
|
+
phases: phaseDurations(left.phases, Date.parse(left.phaseStartedAt))
|
|
151
|
+
});
|
|
152
|
+
}
|
|
85
153
|
function parseActiveBuild(value) {
|
|
86
154
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
87
155
|
const record = value;
|
|
@@ -176,4 +244,4 @@ function buildStatusLine(report, now) {
|
|
|
176
244
|
return remainingMs > 0 ? `${head} -- ${remainingText(remainingMs)} (${basis})` : `${head} (usually ~${formatElapsed(report.expectedMs)}, ${basis})`;
|
|
177
245
|
}
|
|
178
246
|
//#endregion
|
|
179
|
-
export { buildStatusLine as a,
|
|
247
|
+
export { buildStatusLine as a, recordFinishedBuild as c, buildReport as i, startBuildProgress as l, NO_BUILD_PROGRESS as n, estimateBuild as o, activeBuildState as r, parseActiveBuild as s, ACTIVE_BUILD_KEY as t };
|