stim 1.10.0 → 1.11.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.
Files changed (58) hide show
  1. package/dist/{build-progress-BXx-ZBe4.mjs → activity-BtG4Va9l.mjs} +8 -182
  2. package/dist/{android-DPov-fv2.mjs → android-BA2i_KAV.mjs} +1 -1
  3. package/dist/{android-DBkeHwpm.mjs → android-C1q4l523.mjs} +376 -99
  4. package/dist/{android-787HhP5w.mjs → android-C4zG2Tuc.mjs} +63 -18
  5. package/dist/{android-cas-CITmIeWY.mjs → android-cas-DfJkwCXW.mjs} +3 -3
  6. package/dist/{app-install-CrJ6t_bv.mjs → app-install-DHut6JnV.mjs} +1 -1
  7. package/dist/{budget-BP4jZZL4.mjs → budget-De3P2rq_.mjs} +9 -9
  8. package/dist/{dev-client-92U593KT.mjs → build-plan-CeAYgKAx.mjs} +415 -24
  9. package/dist/build-progress-CDwogz6R.mjs +179 -0
  10. package/dist/cli.mjs +14 -14
  11. package/dist/collector-run.mjs +1 -1
  12. package/dist/{deps-DP4eWqea.mjs → deps-OF7CD5Dx.mjs} +2 -2
  13. package/dist/{device-DhTZe7L4.mjs → device-BwH2iI3O.mjs} +47 -9
  14. package/dist/{device-lease-CbEaIk7b.mjs → device-lease-D83nqeMX.mjs} +51 -51
  15. package/dist/{device-pool-Di8Q-9Ro.mjs → device-pool-DHj7cdPy.mjs} +2 -2
  16. package/dist/{device-remote-Dy1jGj3U.mjs → device-remote-BQZSnnmE.mjs} +7 -7
  17. package/dist/{doctor-B-inAJmt.mjs → doctor-D8QdMRMf.mjs} +12 -12
  18. package/dist/{error-diagnostics-xxWKNO3-.mjs → error-diagnostics-UYFSQwRy.mjs} +3 -3
  19. package/dist/{gc-ChPFZMRC.mjs → gc-COZteyiq.mjs} +27 -253
  20. package/dist/{guide-DwmaD_Wa.mjs → guide-NDvTmMi-.mjs} +336 -48
  21. package/dist/{idle-DpRLp5lj.mjs → idle-NETbeNiQ.mjs} +4 -3
  22. package/dist/{in-use-CjUluqIX.mjs → in-use-DVhlSoyn.mjs} +4 -4
  23. package/dist/{ios-Dd-hYJBh.mjs → ios-CQLKpNfr.mjs} +294 -81
  24. package/dist/{ios-B2Fpqvlb.mjs → ios-DArbmwer.mjs} +16 -7
  25. package/dist/{ios-device-CtRdEVjx.mjs → ios-device-CwDZo0X4.mjs} +1 -1
  26. package/dist/{launch-verify-CQS_Kg-C.mjs → launch-verify-CuPDGXdr.mjs} +1 -1
  27. package/dist/logs-B44a1UeU.mjs +485 -0
  28. package/dist/merge-state-DDxS-XIZ.mjs +232 -0
  29. package/dist/{named-ports-DiTfSz6p.mjs → named-ports-Dc7neAlc.mjs} +1 -1
  30. package/dist/native-run-D7yB_AsB.mjs +143 -0
  31. package/dist/{ownership-DZjdx8Gq.mjs → ownership-BiojdtAp.mjs} +3 -3
  32. package/dist/{ports-CLSSFOuz.mjs → ports-DwBaRFJs.mjs} +1 -1
  33. package/dist/{reload-DoETJ3rl.mjs → reload-By9Dwsrt.mjs} +4 -4
  34. package/dist/{server-bare-DVbb7kXH.mjs → server-bare-D_RK1RCj.mjs} +1 -1
  35. package/dist/server-expo-B-CCUJZj.mjs +2 -0
  36. package/dist/{server-expo-BvOCeakp.mjs → server-expo-o6H5gcBc.mjs} +1 -1
  37. package/dist/{settings-DOugPlPz.mjs → settings-B5oFZEri.mjs} +12 -3
  38. package/dist/{settings-EWYNwe72.mjs → settings-C0ugALSC.mjs} +1 -1
  39. package/dist/settings.schema.json +52 -0
  40. package/dist/{simslim-Ca3487H6.mjs → simslim-CIR3IYJO.mjs} +150 -95
  41. package/dist/{slot-launch-C5cg0fmk.mjs → slot-launch-rggO1Esw.mjs} +2 -2
  42. package/dist/{spawn-claims-CUleC2cM.mjs → spawn-claims-BJwXTMPt.mjs} +24 -1
  43. package/dist/{start-F9gv5dcC.mjs → start-BSsf2tUs.mjs} +4 -4
  44. package/dist/{start-VoFsPSes.mjs → start-i8zc9VmS.mjs} +1 -1
  45. package/dist/{status-DLCD-o3s.mjs → status-CitcBRsC.mjs} +227 -22
  46. package/dist/{status-Dr4fRkym.mjs → status-Q-WDEGCB.mjs} +20 -6
  47. package/dist/{stop-Dj4pfmyv.mjs → stop-DIhrvu0B.mjs} +188 -27
  48. package/dist/stop-rst5mL14.mjs +3 -0
  49. package/dist/supervisor-run.mjs +7 -7
  50. package/dist/{workspace-process-lock-BXA96myD.mjs → workspace-process-lock-Cx74RSDZ.mjs} +9 -4
  51. package/dist/{workspaces-BTUyFfkv.mjs → workspaces-COD2xCz-.mjs} +15 -5
  52. package/dist/{worktree-4aZg2NnI.mjs → worktree-DhxDTK44.mjs} +1 -1
  53. package/dist/{worktree-BMS7GeqB.mjs → worktree-KOjMX3zA.mjs} +8 -8
  54. package/dist/{xcode-B2tBkf0m.mjs → xcode-B5SPD--o.mjs} +3 -3
  55. package/package.json +5 -5
  56. package/dist/logs-MARIy6m9.mjs +0 -209
  57. package/dist/server-expo-DBVTdult.mjs +0 -2
  58. package/dist/stop-ZvOeTmKb.mjs +0 -3
@@ -4,18 +4,18 @@ import { N as workspaceStateFile, O as workspaceDir, v as workspaceLastUsed } fr
4
4
  import { C as sourceCheckoutOf, b as resolveFullRef, d as hasUncommittedWork, l as hasPopulatedSubmodules, m as listWorktrees, o as dirtyPaths, w as unpushedCommits } from "./worktree-BlizKDpZ.mjs";
5
5
  import { a as detectIsExpo, o as findProjectRoot } from "./project-BXZzOABt.mjs";
6
6
  import { h as shortUdid, o as formatLongDuration, u as plural } from "./command-output-D5z2_bcF.mjs";
7
- import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-CbEaIk7b.mjs";
8
- import { A as ownedAvdDirectory, C as isStimOwnedAvdName, D as listOrphanedAvdDirectories, K as isStimOwnedSim, T as listAvds } from "./android-787HhP5w.mjs";
9
- import { h as POOL_SETTING_REMEDY, y as parkedMaxSetting } from "./ownership-DZjdx8Gq.mjs";
10
- import { l as listAllIosSims } from "./ios-B2Fpqvlb.mjs";
11
- import { a as parseIdleDuration, o as shutDownIdleDevices, r as idleDeviceLines, t as collectIdleDevices } from "./idle-DpRLp5lj.mjs";
12
- import { i as canonicalPath, o as listBuildSlots, r as workspaceInUse } from "./in-use-CjUluqIX.mjs";
13
- import { C as listOwnedSessionsArgs, D as verifyStoppedSession, E as stopSessionArgs, S as isDefinitiveMissingSessionError, T as parseSessionListPage, b as getSessionArgs, d as withRemoteSessionLock, f as withEasProjectLock, h as removeEasSessionClaim, m as readEasSessionLedger, p as easMachineStateRoot, x as inspectSessionForTeardown, y as findOrphanedOwnedSessions, z as resolveEasCliBin } from "./device-remote-Dy1jGj3U.mjs";
14
- import { A as discoverCaches, C as unverifiedDeviceCommand, D as planCacheEmptying, E as includesWorkspaceOutputs, O as selectCaches, S as findStaleProjectDevices, T as emptyCaches, _ as describeParkedSims, a as collectWorkspaceOutputs, b as findOrphanedDevices, c as listWorkspaceDirs, d as collectDeviceLeases, f as collectParkedAvds, g as deleteProjectDevices, h as deleteParkedSims, i as collectOrphanedWorkspaces, j as sizeCaches, k as trimCaches, l as sizeText, m as deleteParkedAvds, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as collectParkedSims, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as DEVICE_LIST_TIMEOUT_MS, v as describeUnverifiableDevices, w as withAndroidAvdSizes, x as findStaleDeviceRecords, y as deviceSweepIsScoped } from "./workspaces-BTUyFfkv.mjs";
15
- import { a as reclaimKeys, d as removeWorktreeTarget, m as reclaimProject, n as excludePodChurn, p as describeDereferenced, r as matchWorktreeEntry } from "./worktree-BMS7GeqB.mjs";
16
- import { statSync } from "node:fs";
7
+ import { d as removeExpiredLease, h as listBuildLocks } from "./device-lease-D83nqeMX.mjs";
8
+ import { D as listAvds, N as ownedAvdDirectory, Y as isStimOwnedSim, k as listOrphanedAvdDirectories, w as isStimOwnedAvdName } from "./android-C4zG2Tuc.mjs";
9
+ import { h as POOL_SETTING_REMEDY, y as parkedMaxSetting } from "./ownership-BiojdtAp.mjs";
10
+ import { l as listAllIosSims } from "./ios-DArbmwer.mjs";
11
+ import { a as parseIdleDuration, o as shutDownIdleDevices, r as idleDeviceLines, t as collectIdleDevices } from "./idle-NETbeNiQ.mjs";
12
+ import { i as canonicalPath, o as listBuildSlots, r as workspaceInUse } from "./in-use-DVhlSoyn.mjs";
13
+ import { C as listOwnedSessionsArgs, D as verifyStoppedSession, E as stopSessionArgs, S as isDefinitiveMissingSessionError, T as parseSessionListPage, b as getSessionArgs, d as withRemoteSessionLock, f as withEasProjectLock, h as removeEasSessionClaim, m as readEasSessionLedger, p as easMachineStateRoot, x as inspectSessionForTeardown, y as findOrphanedOwnedSessions, z as resolveEasCliBin } from "./device-remote-BQZSnnmE.mjs";
14
+ import { A as discoverCaches, C as unverifiedDeviceCommand, D as planCacheEmptying, E as includesWorkspaceOutputs, O as selectCaches, S as findStaleProjectDevices, T as emptyCaches, _ as describeParkedSims, a as collectWorkspaceOutputs, b as findOrphanedDevices, c as listWorkspaceDirs, d as collectDeviceLeases, f as collectParkedAvds, g as deleteProjectDevices, h as deleteParkedSims, i as collectOrphanedWorkspaces, j as sizeCaches, k as trimCaches, l as sizeText, m as deleteParkedAvds, n as WORKSPACE_OUTPUT_DIRS, o as deleteOrphanedWorkspaces, p as collectParkedSims, r as clearWorkspaceOutputs, s as isInsideWorkspaces, t as REBUILD_COST, u as DEVICE_LIST_TIMEOUT_MS, v as describeUnverifiableDevices, w as withAndroidAvdSizes, x as findStaleDeviceRecords, y as deviceSweepIsScoped } from "./workspaces-COD2xCz-.mjs";
15
+ import { a as reclaimKeys, d as removeWorktreeTarget, m as reclaimProject, n as excludePodChurn, p as describeDereferenced, r as matchWorktreeEntry } from "./worktree-KOjMX3zA.mjs";
16
+ import { n as mergeState, t as fetchDefaultBranch } from "./merge-state-DDxS-XIZ.mjs";
17
17
  import { InvalidArgumentError } from "commander";
18
- import { existsSync as existsSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, statSync as statSync$1 } from "fs";
18
+ import { existsSync, readFileSync, readdirSync, statSync } from "fs";
19
19
  import { basename, dirname, isAbsolute, join } from "path";
20
20
  import chalk from "chalk";
21
21
  //#region src/commands/gc/eas-sessions.ts
@@ -37,18 +37,18 @@ function readRecordedRemoteSessionIds(roots) {
37
37
  let safe = true;
38
38
  for (const root of new Set(roots)) {
39
39
  try {
40
- if (!statSync$1(root).isDirectory()) throw new Error("path is not a directory");
41
- readdirSync$1(root);
40
+ if (!statSync(root).isDirectory()) throw new Error("path is not a directory");
41
+ readdirSync(root);
42
42
  } catch (error) {
43
43
  safe = false;
44
44
  notices.push(`${root} is not available as a readable workspace directory: ${describeError(error)}`);
45
45
  continue;
46
46
  }
47
47
  const path = workspaceStateFile(root);
48
- if (!existsSync$1(path)) continue;
48
+ if (!existsSync(path)) continue;
49
49
  let state;
50
50
  try {
51
- state = JSON.parse(readFileSync$1(path, "utf-8"));
51
+ state = JSON.parse(readFileSync(path, "utf-8"));
52
52
  } catch (error) {
53
53
  safe = false;
54
54
  notices.push(`${path} could not be read as valid JSON: ${describeError(error)}`);
@@ -84,8 +84,8 @@ function claimStateAbsence(claim) {
84
84
  const stateDir = dirname(claim.stateFile);
85
85
  let entries;
86
86
  try {
87
- if (!statSync$1(stateDir).isDirectory()) throw new Error("path is not a directory");
88
- entries = readdirSync$1(stateDir);
87
+ if (!statSync(stateDir).isDirectory()) throw new Error("path is not a directory");
88
+ entries = readdirSync(stateDir);
89
89
  } catch (error) {
90
90
  return {
91
91
  absent: false,
@@ -98,7 +98,7 @@ function claimStateAbsence(claim) {
98
98
  };
99
99
  let state;
100
100
  try {
101
- state = JSON.parse(readFileSync$1(claim.stateFile, "utf-8"));
101
+ state = JSON.parse(readFileSync(claim.stateFile, "utf-8"));
102
102
  } catch (error) {
103
103
  return {
104
104
  absent: false,
@@ -215,8 +215,8 @@ function easLockRoots(projectRoot, config) {
215
215
  }
216
216
  function unavailableLockRootNotice(roots) {
217
217
  for (const root of roots) try {
218
- if (!statSync$1(root).isDirectory()) throw new Error("path is not a directory");
219
- readdirSync$1(root);
218
+ if (!statSync(root).isDirectory()) throw new Error("path is not a directory");
219
+ readdirSync(root);
220
220
  } catch (error) {
221
221
  return `EAS session sweep skipped: ${root} is not available for remote-session lock inspection: ${describeError(error)}`;
222
222
  }
@@ -225,7 +225,7 @@ function unavailableLockRootNotice(roots) {
225
225
  function malformedRemoteSessionLockNotice(roots) {
226
226
  for (const root of roots) {
227
227
  const lockPath = join(workspaceDir(root), "remote-session.lock");
228
- if (!existsSync$1(lockPath)) continue;
228
+ if (!existsSync(lockPath)) continue;
229
229
  if ((0, ownership_claim_exports.readClaimSet)(lockPath).unresolved.length === 0) continue;
230
230
  return `EAS session sweep skipped: the remote-session lock at ${lockPath} has a malformed owner record.`;
231
231
  }
@@ -399,233 +399,6 @@ async function deleteEasSessions(easSessionSweep, deps) {
399
399
  return deleteFailures;
400
400
  }
401
401
  //#endregion
402
- //#region src/workspace/merge-state.ts
403
- const FETCH_TIMEOUT_MS = 3e4;
404
- const FETCH_FRESH_MS = 6e5;
405
- const GIT_TIMEOUT_MS = 6e4;
406
- const REMOTE_PREFIX = "refs/remotes/origin/";
407
- function failure(error) {
408
- const { stderr, message } = error;
409
- const text = String(stderr ?? "").trim() || String(message ?? error);
410
- return text.split("\n")[0] ?? text;
411
- }
412
- function fetchedRecently(repo, now) {
413
- const path = getExecutor().runFileQuiet("git", [
414
- "-C",
415
- repo,
416
- "rev-parse",
417
- "--path-format=absolute",
418
- "--git-path",
419
- "FETCH_HEAD"
420
- ])?.trim();
421
- try {
422
- return Boolean(path) && now - statSync(path).mtimeMs < FETCH_FRESH_MS;
423
- } catch {
424
- return false;
425
- }
426
- }
427
- /**
428
- * Fetches the default branch that `origin/HEAD` names into its remote-tracking ref, bounded by a timeout and never
429
- * prompting for credentials. It skips the fetch when the checkout fetched anything in the last 10 minutes.
430
- */
431
- function fetchDefaultBranch(repo, now = Date.now()) {
432
- const exec = getExecutor();
433
- const ref = exec.runFileQuiet("git", [
434
- "-C",
435
- repo,
436
- "symbolic-ref",
437
- "--quiet",
438
- "refs/remotes/origin/HEAD"
439
- ])?.trim();
440
- if (!ref?.startsWith(REMOTE_PREFIX)) return { error: `origin/HEAD is not set; run \`git -C ${repo} remote set-head origin --auto\`` };
441
- const branch = ref.slice(20);
442
- if (fetchedRecently(repo, now)) return {
443
- ref,
444
- name: `origin/${branch}`
445
- };
446
- try {
447
- exec.runFile("git", [
448
- "-C",
449
- repo,
450
- "fetch",
451
- "--quiet",
452
- "--no-tags",
453
- "--no-recurse-submodules",
454
- "origin",
455
- `+refs/heads/${branch}:${ref}`
456
- ], {
457
- timeoutMs: FETCH_TIMEOUT_MS,
458
- env: { GIT_TERMINAL_PROMPT: "0" }
459
- });
460
- } catch (error) {
461
- return { error: `git fetch origin ${branch} failed: ${failure(error)}` };
462
- }
463
- return {
464
- ref,
465
- name: `origin/${branch}`
466
- };
467
- }
468
- function notMerged(detail) {
469
- return {
470
- merged: false,
471
- unknown: false,
472
- detail
473
- };
474
- }
475
- function currentBranch(path) {
476
- const ref = getExecutor().runFileQuiet("git", [
477
- "-C",
478
- path,
479
- "symbolic-ref",
480
- "--quiet",
481
- "HEAD"
482
- ])?.trim();
483
- return ref?.startsWith("refs/heads/") ? ref : null;
484
- }
485
- function upstreamGone(path, branch) {
486
- if (!branch) return false;
487
- const [upstream, state] = (getExecutor().runFileQuiet("git", [
488
- "-C",
489
- path,
490
- "for-each-ref",
491
- "--format=%(upstream)%00%(upstream:track)",
492
- branch
493
- ]) ?? "").trim().split("\0");
494
- return Boolean(upstream) && state === "[gone]";
495
- }
496
- function committedOn(path, branch, head) {
497
- if (!branch) return false;
498
- const exec = getExecutor();
499
- return (exec.runFileQuiet("git", [
500
- "-C",
501
- path,
502
- "reflog",
503
- "show",
504
- "--format=%H %gs",
505
- branch
506
- ]) ?? "").split("\n").some((entry) => {
507
- const [sha = "", ...subject] = entry.split(" ");
508
- return /^(commit|cherry-pick|rebase|revert)\b/.test(subject.join(" ")) && exec.runFileQuiet("git", [
509
- "-C",
510
- path,
511
- "merge-base",
512
- "--is-ancestor",
513
- sha,
514
- head
515
- ]) !== null;
516
- });
517
- }
518
- /**
519
- * Whether the worktree's HEAD is merged into `target`. The signals, all local git:
520
- * - HEAD is an ancestor of the default branch, off its first-parent line, and the branch's reflog shows a commit made
521
- * on it that HEAD contains, so a merge commit brought the branch's own work in. A branch with no commit of its own
522
- * is not merged.
523
- * - The branch changes the tree, has no merge commits, and every commit since the merge base has the same
524
- * `git patch-id --verbatim` as a commit on the default branch (a rebase merge).
525
- * - The branch changes the tree and its whole diff since the merge base has the same verbatim patch id as a commit on
526
- * the default branch, limited to the files the branch changes (a squash merge).
527
- * Anything git cannot answer is unknown, never merged. `coversUnpushed` is true for a patch-equivalent HEAD whose
528
- * upstream branch was deleted: its commits exist only locally, but their change is on the default branch.
529
- */
530
- function mergeState(path, { ref, name }) {
531
- const git = (args, input) => getExecutor().runFile("git", [
532
- "--literal-pathspecs",
533
- "-C",
534
- path,
535
- ...args
536
- ], {
537
- timeoutMs: GIT_TIMEOUT_MS,
538
- input
539
- });
540
- const patch = (args) => getExecutor().runFile("git", [
541
- "--literal-pathspecs",
542
- "-C",
543
- path,
544
- ...args
545
- ], {
546
- timeoutMs: GIT_TIMEOUT_MS,
547
- untrimmed: true
548
- });
549
- const patchIds = (text) => text ? git(["patch-id", "--verbatim"], text).split("\n").flatMap((line) => line.split(" ")[0] || []) : [];
550
- const diffOptions = ["--no-color", "--no-ext-diff"];
551
- const noOwnCommits = notMerged(`no commits of its own beyond ${name}`);
552
- try {
553
- const head = git([
554
- "rev-parse",
555
- "--verify",
556
- "HEAD^{commit}"
557
- ]);
558
- const base = git([
559
- "merge-base",
560
- head,
561
- ref
562
- ]);
563
- const branch = currentBranch(path);
564
- if (base === head) {
565
- if (git(["rev-parse", ref]) === head || git([
566
- "rev-list",
567
- "--first-parent",
568
- "--parents",
569
- `${head}..${ref}`
570
- ]).split("\n").some((line) => line.split(" ")[1] === head) || !committedOn(path, branch, head)) return noOwnCommits;
571
- return {
572
- merged: true,
573
- into: name,
574
- head,
575
- coversUnpushed: false
576
- };
577
- }
578
- const files = git([
579
- "diff",
580
- "--name-only",
581
- "--no-renames",
582
- "-z",
583
- base,
584
- head
585
- ]).split("\0").filter(Boolean);
586
- if (!files.length) return notMerged(`no net change beyond ${name}`);
587
- const log = (range, pathspec = []) => patch([
588
- "log",
589
- "-p",
590
- "--no-merges",
591
- ...diffOptions,
592
- "--format=commit %H",
593
- range,
594
- "--",
595
- ...pathspec
596
- ]);
597
- const upstream = new Set(patchIds(log(`${base}..${ref}`, files)));
598
- const patchEquivalent = () => ({
599
- merged: true,
600
- into: name,
601
- head,
602
- coversUnpushed: upstreamGone(path, branch)
603
- });
604
- const squash = patchIds(patch([
605
- "diff",
606
- ...diffOptions,
607
- base,
608
- head
609
- ]));
610
- if (squash.length === 1 && upstream.has(squash[0])) return patchEquivalent();
611
- if (!git([
612
- "rev-list",
613
- "--merges",
614
- `${base}..${head}`
615
- ])) {
616
- const own = patchIds(log(`${base}..${head}`));
617
- if (own.length && own.every((id) => upstream.has(id))) return patchEquivalent();
618
- }
619
- return notMerged(`not merged into ${name}`);
620
- } catch (error) {
621
- return {
622
- merged: false,
623
- unknown: true,
624
- detail: `merge state unknown: ${failure(error)}`
625
- };
626
- }
627
- }
628
- //#endregion
629
402
  //#region src/commands/gc/worktrees.ts
630
403
  const DEFAULT_WORKTREE_IDLE_DAYS = 7;
631
404
  const DAY_MS = 864e5;
@@ -685,7 +458,7 @@ function porcelainOf(path, gitAnswered) {
685
458
  function candidateRoots() {
686
459
  const registered = Object.keys(loadConfig()?.projects ?? {}).filter(isAbsolute);
687
460
  const recorded = listWorkspaceDirs().flatMap((entry) => entry.projectRoot ? [entry.projectRoot] : []);
688
- return [.../* @__PURE__ */ new Set([...registered, ...recorded])].filter((root) => existsSync$1(root)).toSorted();
461
+ return [.../* @__PURE__ */ new Set([...registered, ...recorded])].filter((root) => existsSync(root)).toSorted();
689
462
  }
690
463
  function checkMergeStates(pending, idle, now) {
691
464
  const repos = /* @__PURE__ */ new Map();
@@ -851,7 +624,7 @@ function formatParkedAvdReport(parkedAvds, now) {
851
624
  lines.push(`Parked emulators (${parkedAvds.length}):`);
852
625
  for (const avd of parkedAvds) {
853
626
  const listed = avd.listed === false ? " - not on this machine" : avd.listed === null ? " - listing unavailable; kept" : "";
854
- lines.push(` android ${avd.name} ${avd.systemImage} ${parkedAge(avd.parkedAt, now)}${avd.bytes === null ? "" : ` ${formatBytes(avd.bytes)}`}${listed}`);
627
+ lines.push(` android ${avd.name} ${avd.systemImage}${avd.deviceProfile ? ` ${avd.deviceProfile}` : ""} ${parkedAge(avd.parkedAt, now)}${avd.bytes === null ? "" : ` ${formatBytes(avd.bytes)}`}${listed}`);
855
628
  }
856
629
  lines.push(" --delete attempts verified deletions and keeps failures.");
857
630
  return lines;
@@ -1147,9 +920,10 @@ function gcReportSections({ skipped = [], deadProjects = [], orphanedPorts = [],
1147
920
  bytes,
1148
921
  listed
1149
922
  })),
1150
- parkedEmulators: parkedAvds.map(({ name, systemImage, parkedAt, bytes, listed }) => ({
923
+ parkedEmulators: parkedAvds.map(({ name, systemImage, deviceProfile, parkedAt, bytes, listed }) => ({
1151
924
  name,
1152
925
  systemImage,
926
+ deviceProfile,
1153
927
  parkedAt,
1154
928
  bytes,
1155
929
  listed
@@ -1344,7 +1118,7 @@ async function collectGcReport({ olderThan = null, cache = null, worktrees = fal
1344
1118
  else invalidProjects.push(path);
1345
1119
  continue;
1346
1120
  }
1347
- if (existsSync$1(path)) continue;
1121
+ if (existsSync(path)) continue;
1348
1122
  if (!isOnMountedVolume(path, mountedVolumes)) {
1349
1123
  const volume = volumeRootFor(path);
1350
1124
  skipped.push({
@@ -1634,7 +1408,7 @@ async function runGcCore(opts, deps) {
1634
1408
  deleteFailures += deleteParkedSims(report.parkedSims, deps) + deleteParkedAvds(report.parkedAvds);
1635
1409
  removeInvalidProjectEntries(invalidProjects);
1636
1410
  for (const path of deadProjects) {
1637
- if (existsSync$1(path) || !isOnMountedVolume(path)) {
1411
+ if (existsSync(path) || !isOnMountedVolume(path)) {
1638
1412
  console.log(chalk.yellow(`Kept ${path}: its absence can no longer be confirmed.`));
1639
1413
  continue;
1640
1414
  }