stim 1.10.1 → 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-Bu4mbDzc.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-Cfmqr3TQ.mjs → app-install-DHut6JnV.mjs} +1 -1
  7. package/dist/{budget-nDCEwtJv.mjs → budget-De3P2rq_.mjs} +9 -9
  8. package/dist/{dev-client-DExzPiOa.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-Czh5kO8A.mjs → device-BwH2iI3O.mjs} +47 -9
  14. package/dist/{device-lease-CbEaIk7b.mjs → device-lease-D83nqeMX.mjs} +51 -51
  15. package/dist/{device-pool-BBWLAr55.mjs → device-pool-DHj7cdPy.mjs} +2 -2
  16. package/dist/{device-remote-powUHdbK.mjs → device-remote-BQZSnnmE.mjs} +7 -7
  17. package/dist/{doctor-CmqK1LcQ.mjs → doctor-D8QdMRMf.mjs} +12 -12
  18. package/dist/{error-diagnostics-xxWKNO3-.mjs → error-diagnostics-UYFSQwRy.mjs} +3 -3
  19. package/dist/{gc-zCDpmdHU.mjs → gc-COZteyiq.mjs} +27 -253
  20. package/dist/{guide-DwmaD_Wa.mjs → guide-NDvTmMi-.mjs} +336 -48
  21. package/dist/{idle--jn7pBNe.mjs → idle-NETbeNiQ.mjs} +4 -3
  22. package/dist/{in-use-CNIWU-r-.mjs → in-use-DVhlSoyn.mjs} +4 -4
  23. package/dist/{ios-CbdqTqOc.mjs → ios-CQLKpNfr.mjs} +294 -81
  24. package/dist/{ios-COGcGEcN.mjs → ios-DArbmwer.mjs} +2 -1
  25. package/dist/{ios-device-DNjPXBnb.mjs → ios-device-CwDZo0X4.mjs} +1 -1
  26. package/dist/{launch-verify-BhgkYAws.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-BfPNRf3-.mjs → ownership-BiojdtAp.mjs} +3 -3
  32. package/dist/{ports-CLSSFOuz.mjs → ports-DwBaRFJs.mjs} +1 -1
  33. package/dist/{reload-CymyF6Kk.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-DZUxzsjq.mjs → simslim-CIR3IYJO.mjs} +150 -95
  41. package/dist/{slot-launch-Dk4oTREM.mjs → slot-launch-rggO1Esw.mjs} +2 -2
  42. package/dist/{spawn-claims-CUleC2cM.mjs → spawn-claims-BJwXTMPt.mjs} +24 -1
  43. package/dist/{start-RbmFPeZ7.mjs → start-BSsf2tUs.mjs} +4 -4
  44. package/dist/{start-qWapeB4W.mjs → start-i8zc9VmS.mjs} +1 -1
  45. package/dist/{status-Zp8kvexe.mjs → status-CitcBRsC.mjs} +227 -22
  46. package/dist/{status-Dr4fRkym.mjs → status-Q-WDEGCB.mjs} +20 -6
  47. package/dist/{stop-DcEv5sk-.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-wrH6dXfu.mjs → workspaces-COD2xCz-.mjs} +15 -5
  52. package/dist/{worktree-DEG2o9F8.mjs → worktree-DhxDTK44.mjs} +1 -1
  53. package/dist/{worktree-Bd4dRvx7.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-DI4BG4Os.mjs +0 -3
@@ -1,5 +1,5 @@
1
1
  import { o as findProjectRoot } from "./project-BXZzOABt.mjs";
2
- import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-DOugPlPz.mjs";
2
+ import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-B5oFZEri.mjs";
3
3
  import { t as guideStatus } from "./guide-status-CWvti2Lg.mjs";
4
4
  import { SETTINGS_SCHEMA_URL } from "@stim-cli/core/state";
5
5
  import chalk from "chalk";
@@ -92,6 +92,10 @@ presence of eas.json does not select EAS or authorize building.
92
92
  Physical --device targets are supported. Follow EAS device-registration and
93
93
  rebuild remedies only when the session authorizes those account changes.
94
94
 
95
+ To learn whether the next build is a cache hit and how long it should take,
96
+ without building, run stim ios --plan (or stim android --plan); see stim guide
97
+ lifecycle builds.
98
+
95
99
  Read stim guide lifecycle concurrency when a build waits on another workspace
96
100
  or a build call times out. A native build can outlive a shell timeout; if the
97
101
  tool call timed out, retry the same command and follow its printed remedy if
@@ -228,7 +232,9 @@ Ask the user before these actions:
228
232
  - stop when the workspace owns an EAS session, because it irreversibly ends
229
233
  that remote session. For a local device, stop shuts it down but does not
230
234
  delete it. An explicit stop shuts down a Stim-owned simulator even when
231
- another process uses it. It never shuts down an unowned simulator.
235
+ another process uses it. It never shuts down an unowned simulator. It also
236
+ cancels an ios or android run still building for the device it stops
237
+ (guide lifecycle).
232
238
 
233
239
  LEAVE THE MACHINE CLEAN
234
240
 
@@ -299,7 +305,7 @@ FULL TOPIC LIST
299
305
  stim guide lifecycle builds # build optimizations, optional cache warm-up, fingerprints
300
306
  stim guide lifecycle concurrency # shared builds, wait timeouts, capacity limits
301
307
  stim guide lifecycle budget # disk and memory budgets, automatic reclaim
302
- stim guide lifecycle options # every flag, Android variants, --device-type, --system-image
308
+ stim guide lifecycle options # every flag, Android variants, --device-type, --system-image, --device-profile
303
309
  stim guide lifecycle devices # ios --device and android --device on a physical phone
304
310
  stim guide lifecycle release # Release configurations and ...Release variants
305
311
  stim guide facts # the --json payloads
@@ -312,7 +318,7 @@ FULL TOPIC LIST
312
318
  stim guide settings # configuration files and supported keys`
313
319
  },
314
320
  facts: {
315
- summary: "The --json payloads: `start`, `ios`, `android`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
321
+ summary: "The --json payloads: `start`, `ios`, `android`, `ios|android --plan`, `reload`, `stop`, `status`, `doctor`, `device lock`/`unlock`, `gc`, and the error contract",
316
322
  preamble: () => `SLOTS
317
323
  Named ios/android runs add slot to their JSON facts. Default-run fields remain
318
324
  compatible. status adds a slots array per environment with each named slot's
@@ -331,12 +337,38 @@ status's unprovisionedWorktrees lists the linked worktrees with no Stim
331
337
  environment in every repository with a registered environment, plus the
332
338
  repository status runs from. A worktree counts as having an
333
339
  environment when one is registered at it or inside it. Each entry is
334
- { path, branch, repository }; repository is the main checkout, or the git
335
- directory of a bare repository. status reads git's own worktree records and
336
- never opens the worktree directories, so a worktree under a macOS-protected
337
- folder such as ~/Documents is listed without a privacy prompt.
340
+ { path, branch, repository, git }; repository is the main checkout, or the git
341
+ directory of a bare repository. status lists worktrees from git's own worktree
342
+ records, and on macOS runs no git in a worktree with no environment under a
343
+ protected folder such as ~/Documents, so listing it raises no privacy prompt.
338
344
  \`worktree warm\` does not create an environment; \`start\`, \`ios\`,
339
- \`android\` and \`doctor\` register it.
345
+ \`android\` and \`doctor\` register it. An environment's worktree is the
346
+ linked worktree it is registered at or inside.
347
+
348
+ Each worktree entry, in unprovisionedWorktrees and in an environment's
349
+ worktree, carries git:
350
+
351
+ git { changed, untracked, upstream, ahead, behind, mergedInto }, or
352
+ null when git fails or does not answer within 3 s, or the
353
+ worktree has no environment and sits in ~/Desktop, ~/Documents,
354
+ ~/Downloads, iCloud Drive, ~/Library/CloudStorage or /Volumes,
355
+ which status does not open on macOS
356
+ changed tracked paths with staged or unstaged changes, conflicts included
357
+ untracked untracked entries as git status lists them; a new directory
358
+ counts once
359
+ upstream the branch's upstream, such as "origin/feat/x", or null
360
+ ahead commits on HEAD and not on upstream; null with no upstream, or
361
+ behind when the upstream branch no longer exists
362
+ mergedInto "origin/<default>" when gc would call the branch merged, judged
363
+ from local refs without fetching, else null
364
+
365
+ status runs \`git status --porcelain=v2 --branch\` in every worktree in
366
+ parallel, and caches the merge verdict by HEAD and default-branch commit
367
+ under $STIM_HOME/git-merge. One call starts no new merge check 250 ms after
368
+ its first; later calls judge the rest, and until then a verdict for the same
369
+ HEAD at an older default-branch commit stands in. \`status --watch\` reuses a worktree's git read
370
+ for 5 s. Plain status prints "git: 2 changed, 1 untracked, ahead 3" under
371
+ each environment, and the same after each worktree with no environment.
340
372
 
341
373
  status's remoteDevices lists each environment's recorded EAS Simulator
342
374
  session. The session is billable while it runs, and it makes the environment
@@ -518,6 +550,10 @@ per session, with the preview URL.`,
518
550
  android.systemImage setting reports it too, not only a
519
551
  \`--system-image\` run. Null on \`--device\` and on an
520
552
  emulator Stim does not own
553
+ deviceProfile the avdmanager hardware profile of the owned AVD
554
+ ("pixel_6", "pixel_fold"), read from its config.ini
555
+ hw.device.name. Null where systemImage is null, and on an
556
+ AVD of the old generic profile, which has no hw.device.name
521
557
  fingerprint / cacheKey / cacheHit / cacheSkipped / waitedForBuild /
522
558
  appPath / installSkipped / launched
523
559
  as above -- cacheKey keys on the VARIANT here
@@ -640,6 +676,19 @@ ON FAILURE
640
676
  \`reclaimed\` is present the same way as on success when the run reclaimed
641
677
  before failing, including a STIM_LOW_DISK refusal.
642
678
 
679
+ An \`ios\` or \`android\` run that \`stim stop\` or Ctrl-C interrupted
680
+ reports STIM_CANCELLED and exits 130. A
681
+ run that exits on the interrupt at once (a second SIGINT, a physical-device
682
+ lease, Ctrl-C with no build tool running) exits 130 with no payload.
683
+
684
+ \`stop --json\` prints { root, ok, supervisor, collectors, metro, device,
685
+ port, metroTunnel, releasedLeases }. When it cannot end the \`ios\` or
686
+ \`android\` run holding the workspace, it prints the error contract with
687
+ root and ok: false instead, plus device.remote when it ended a recorded EAS
688
+ session first, and exits 1:
689
+
690
+ { "root": "...", "ok": false, "code": "STIM_STOP_BLOCKED", "message": "...", "remedy": "..." }
691
+
643
692
  Branch on \`code\`, never on the message text. \`guide errors\` enumerates
644
693
  every code.
645
694
 
@@ -796,7 +845,7 @@ RULES
796
845
  parkedSimulators { udid, name, model, runtime, parkedAt, bytes,
797
846
  listed } with --older-than, only those parked
798
847
  at least that long
799
- parkedEmulators { name, systemImage, parkedAt, bytes, listed }
848
+ parkedEmulators { name, systemImage, deviceProfile, parkedAt, bytes, listed }
800
849
  likewise
801
850
  orphanedDevices { kind, id, name, bytes, directory }
802
851
  unverifiedDevices { kind, id, name, command } stim-* devices Stim
@@ -857,7 +906,7 @@ RULES
857
906
  - --cache together with --worktrees or --idle`
858
907
  },
859
908
  status: {
860
- summary: "the status payload's build and device activity fields: a running build, its estimate, and who drives each device",
909
+ summary: "the status payload's build and device activity fields: a running build, its estimate, each platform's last build, and who drives each device",
861
910
  body: () => ` stim status --json
862
911
 
863
912
  Each booted simulator and detected emulator in environments (and in
@@ -926,8 +975,65 @@ RULES
926
975
 
927
976
  build: ios compile, 1m10s elapsed -- about 3 min left (median of 4 cold runs)
928
977
 
978
+ An environment with a recorded run also carries lastBuilds, each
979
+ platform's most recent ios or android run, finished or failed:
980
+
981
+ lastBuilds { ios?, android? }, each { platform, status, cacheHit,
982
+ cacheSkipped, durationMs, fingerprint, startedAt, finishedAt,
983
+ errorCode?, missReason? }
984
+
985
+ status "ok" or "failed"
986
+ cacheHit "local" or "remote" for an app from that cache tier; false
987
+ for an ok run that compiled, or a failed run that had none
988
+ durationMs the run's wall time; finishedAt is startedAt plus it. Both
989
+ are null when the record carries no duration.
990
+ fingerprint the key's fingerprint after any prebuild or pod install
991
+ missReason only on a run that did not install a cached app (it
992
+ compiled, or failed before finding one): { kind, summary, changes,
993
+ changeCount, baseline, rekeyedBy }. kind is "changed",
994
+ "no-baseline", "same-sources", "cache-skipped" or
995
+ "fingerprint-error"; summary names the cause, such as
996
+ "native dependency added: expo-clipboard". changes holds up to
997
+ 20 { source, change, category } of changeCount changed sources;
998
+ baseline is { fingerprint, from: "workspace" | "project" }, the
999
+ cached build compared with; rekeyedBy lists "prebuild" or
1000
+ "pod install" when those steps moved the key.
1001
+
1002
+ Plain status prints "last build: ios local cache in 12s, android compiled
1003
+ in 7m02s". To predict the next run instead, see \`guide facts plan\`.
1004
+
929
1005
  There is no completion fraction: a compile's log volume depends on what
930
1006
  is already built, so it does not measure progress.`
1007
+ },
1008
+ plan: {
1009
+ summary: "the ios and android --plan payload: fingerprint, cacheHit, prebuild, expectedMs and basis",
1010
+ body: () => ` stim ios --plan --json # or: stim android --plan --json
1011
+
1012
+ { platform, slot?, fingerprint, cacheKey, cacheHit, provider,
1013
+ cacheSkipped, prebuild, outcome, expectedMs, basis, refusal? }
1014
+
1015
+ fingerprint the fingerprint the run would look up first; with
1016
+ --eas-profile, the one EAS CLI computes
1017
+ cacheKey the key under that fingerprint; null for an EAS miss
1018
+ cacheHit "local", "remote", or false for a miss
1019
+ provider the remote tier that answered, "eas" with --eas-profile,
1020
+ otherwise null
1021
+ cacheSkipped true when cache reads are off (--no-build-cache or config)
1022
+ prebuild on a miss, the run's decision for the native dir: "none",
1023
+ "generate", "regenerate" or "refuse"; null on a hit
1024
+ outcome "hit" or "cold"; null when the run would refuse
1025
+ expectedMs the median wall time of this project's last successful runs
1026
+ with that outcome on that platform, or null with none
1027
+ basis how many runs expectedMs comes from (at most 10)
1028
+ refusal { code, message, remedy } when the run would refuse:
1029
+ STIM_PREBUILD_FAILED for a tracked native dir the fingerprint
1030
+ leaves out, STIM_EAS_BUILD_MISSING for an EAS miss
1031
+
1032
+ A plan that would refuse still exits 0: the payload is the answer. A plan
1033
+ that cannot be computed prints the error contract and exits 1, for example
1034
+ STIM_NO_FINGERPRINT, STIM_EAS_UNAVAILABLE, or STIM_BAD_ARG for a flag that
1035
+ picks a device. When and why a plan and the run can differ: \`guide
1036
+ lifecycle builds\`.`
931
1037
  },
932
1038
  stats: {
933
1039
  summary: "the stats payload, what counts as a run, hit, miss and failed, timeSavedMs, the heartbeat estimate",
@@ -1051,9 +1157,12 @@ REMOTE DEVICE BACKENDS
1051
1157
  AGENT_DEVICE_DAEMON_AUTH_TOKEN. Stim creates no remote session for it.
1052
1158
 
1053
1159
  The EAS backend needs eas-cli 21.6.0 or later and an account with EAS
1054
- Simulator access. An EAS session is billable. EAS does not inherit the proxy
1055
- credentials. Always tear the session down: \`stop\`, \`worktree remove\`,
1056
- and \`gc --delete\` can end sessions that Stim proves it owns.
1160
+ Simulator access. An EAS session is billable. Stim prepares the app before
1161
+ it creates or reconnects the session, so a failed build starts no session
1162
+ and the install follows the connection directly. EAS does not inherit the
1163
+ proxy credentials. Always tear the session down: \`stop\`,
1164
+ \`worktree remove\`, and \`gc --delete\` can end sessions that Stim proves
1165
+ it owns.
1057
1166
  \`stim status\` lists each recorded session with its preview URL (see
1058
1167
  \`guide facts\`).
1059
1168
 
@@ -1252,8 +1361,8 @@ usually untagged: use an unfiltered workspace query to inspect those errors.
1252
1361
 
1253
1362
  FLAGS
1254
1363
  --slot <name> only this slot's records (default includes untagged records)
1255
- --source <s...> metro, client, device, build (one or more), or all. An
1256
- unknown value is REJECTED rather than quietly matching
1364
+ --source <s...> metro, client, device, build, agent (one or more), or all.
1365
+ An unknown value is REJECTED rather than quietly matching
1257
1366
  nothing.
1258
1367
  --level <l> minimum level: debug, info, warn, error, fatal
1259
1368
  --since <d> only records newer than this: 30s, 5m, 2h
@@ -1344,7 +1453,7 @@ FLAGS
1344
1453
 
1345
1454
  THE RECORD
1346
1455
  { ts, src, level, msg } always. ts is epoch milliseconds; src is one of
1347
- metro / client / device / build; level is one of the five above.
1456
+ metro / client / device / build / agent; level is one of the five above.
1348
1457
  Optional fields:
1349
1458
  event the producer's own event name (bundle_build_done, client_log, ...)
1350
1459
  stack frames of { file, line, column, fn }, passed through as reported
@@ -1493,6 +1602,21 @@ WHAT WRITES WHAT
1493
1602
  archive rather than a stream. Streaming with full fidelity needs
1494
1603
  libimobiledevice or pymobiledevice3, which are third-party installs Stim
1495
1604
  does not require. See appandflow/stim#179.
1605
+ agent no file. Each query reads agent-device's session
1606
+ records (~/.agent-device/sessions, or
1607
+ AGENT_DEVICE_STATE_DIR) for this workspace's owned
1608
+ simulators and emulators, read-only. An action is
1609
+ info (msg is agent-device's summary, e.g. "Tapped
1610
+ (201, 731)"; event agent_action with command, session,
1611
+ deviceId and details); a failed command is error
1612
+ (event agent_failed). A plain query includes them;
1613
+ --errors only with --source agent or all. iOS sessions
1614
+ match a simulator through their runner.log, Android
1615
+ sessions only while agent-device's claim on the
1616
+ emulator is live (released claims drop their
1617
+ actions from later queries). A session in an
1618
+ unrecognized format yields one warn record
1619
+ (agent_format_unknown) instead of its actions.
1496
1620
  build-ios.ndjson the xcodebuild / gradle transcript at level debug, the
1497
1621
  build-android.ndjson extracted diagnostics at level error, and the launch as
1498
1622
  a marker record. One RUN's worth: each build starts the
@@ -2122,7 +2246,12 @@ so a Debug run on one is wired to a LAN origin instead of localhost.`,
2122
2246
  The project already owns a simulator of a different model, and Stim will
2123
2247
  not silently boot a different one. Reap it (\`worktree remove\`, or
2124
2248
  \`gc --delete\`) and run \`stim ios\` again to create the requested model.
2125
- That loses the old sim's app state.`
2249
+ That loses the old sim's app state.
2250
+
2251
+ "this project's emulator uses device profile X, but Y was requested"
2252
+ The Android counterpart, from \`--device-profile\` or android.deviceProfile.
2253
+ Reap the AVD the same way, or pass \`--slot <name>\` to create the requested
2254
+ profile beside it.`
2126
2255
  },
2127
2256
  STIM_DEVICE_BUSY: {
2128
2257
  summary: "another workspace holds the lease on that phone and the wait ran out",
@@ -2434,14 +2563,16 @@ captured" (in metro.ndjson, bare RN)
2434
2563
  nearest registered descendant app with logs when one exists), an
2435
2564
  android/app/build.gradle that declares product flavors with
2436
2565
  no variant selected (the refusal names the debug variants), or a
2437
- \`--device-type\`, \`--runtime\` or \`--system-image\` name that is BLANK or
2438
- is not installed on this machine. For the unknown-name case the installed
2439
- names are printed in the message -- the versions \`xcrun simctl list
2440
- runtimes\` reports, the models those runtimes can actually CREATE (not the
2441
- whole \`simctl list devicetypes\` table, which also names watchOS, tvOS and
2442
- visionOS models no iOS runtime offers), or the system images the SDK has --
2443
- so the remedy is to re-run with one of them. An ios.deviceType, ios.runtime
2444
- or android.systemImage setting is checked the same way, and the check applies
2566
+ \`--device-type\`, \`--runtime\`, \`--system-image\` or \`--device-profile\`
2567
+ name that is BLANK or is not installed on this machine. For the
2568
+ unknown-name case the installed names are printed in the message -- the
2569
+ versions \`xcrun simctl list runtimes\` reports, the models those runtimes
2570
+ can actually CREATE (not the whole \`simctl list devicetypes\` table, which
2571
+ also names watchOS, tvOS and visionOS models no iOS runtime offers), the
2572
+ system images the SDK has, or the hardware profiles \`avdmanager list device
2573
+ -c\` offers -- so the remedy is to re-run with one of them. An
2574
+ ios.deviceType, ios.runtime, android.systemImage or android.deviceProfile
2575
+ setting is checked the same way, and the check applies
2445
2576
  even when this workspace ALREADY owns a device, so a name that could never
2446
2577
  create anything is caught rather than left to a later run.
2447
2578
  \`gc --json --cache <name>\` refuses with STIM_BAD_ARG when no shared cache
@@ -2455,7 +2586,8 @@ captured" (in metro.ndjson, bare RN)
2455
2586
  reporting that nothing was running.
2456
2587
  These errors are caught before the port is reserved and before any build or
2457
2588
  device work, so nothing was started. The one listing they need
2458
- (\`simctl list runtimes\`, the SDK's system-images directory) runs only when
2589
+ (\`simctl list runtimes\`, the SDK's system-images directory, \`avdmanager
2590
+ list device -c\`) runs only when
2459
2591
  a name was actually given, and a listing that fails is reported as
2460
2592
  STIM_NO_DEVICE naming the tool, never as a crash.`
2461
2593
  },
@@ -2471,6 +2603,41 @@ captured" (in metro.ndjson, bare RN)
2471
2603
  \`workspace removal\` -- both are \`stim worktree remove\`). Let it finish,
2472
2604
  then run the command again. \`start --remote\` reports this same case as
2473
2605
  STIM_WORKTREE_REMOVAL_IN_PROGRESS instead.`
2606
+ },
2607
+ STIM_CANCELLED: {
2608
+ summary: "an ios or android run was interrupted by `stim stop` or Ctrl-C before it finished",
2609
+ body: () => `STIM_CANCELLED (ios, android; exit 130)
2610
+ "The ios run was cancelled by \`stim stop\` (pid <n>) before it finished."
2611
+ The run received SIGINT: from \`stim stop\`, which interrupts a build it
2612
+ leaves with nothing to deploy to, or from Ctrl-C. It forwarded the interrupt
2613
+ to the build tool it was running (xcodebuild, Gradle, pod install, expo
2614
+ prebuild) and failed through its own cleanup; the next line names the step it
2615
+ stopped at. An interrupted build stores no artifact, so the next run looks
2616
+ up the cache as usual. Stopped between build tools, a run that \`stop\`
2617
+ cancelled starts no further build tool and stops before it installs. A
2618
+ second SIGINT exits at once, and so does a run that holds a physical-device
2619
+ lease; those exits print no payload. Run the same command again when you want the
2620
+ app on a device.`
2621
+ },
2622
+ STIM_STOP_BLOCKED: {
2623
+ summary: "`stop` could not interrupt the ios or android run holding this workspace; names its pid and claim",
2624
+ body: () => `STIM_STOP_BLOCKED (stop)
2625
+ \`stop\` found a live \`ios\` or \`android\` run holding this workspace's
2626
+ native-run claim and could not end it:
2627
+ - "... did not exit within 60s of SIGINT": the run was interrupted but is
2628
+ still running. Wait for it, or end it with the \`kill <pid>\` the remedy
2629
+ prints, then run \`stim stop\` again.
2630
+ - "... pid <n> is no longer that run; the build tool it started (pid <m>)
2631
+ still holds the claim": the run itself died and its build tool keeps the
2632
+ claim. Stim signals only a claim owner whose recorded identity it can
2633
+ prove, so it leaves the tool alone. Wait for pid <m> to exit or end it.
2634
+ On Windows this is the usual outcome of an interrupt: Node cannot deliver
2635
+ a catchable SIGINT to another process there, so the run ends at once and
2636
+ its Gradle build keeps the claim until it exits.
2637
+ A recorded EAS session is ended before this refusal: ending a billable
2638
+ session never waits on a build. The JSON payload carries the session
2639
+ outcome under device.remote. Devices, collectors and the dev server are left
2640
+ as they were.`
2474
2641
  },
2475
2642
  STIM_LOCK_TIMEOUT: {
2476
2643
  summary: "a lock held past the wait; workspace-process and short directory locks",
@@ -2944,6 +3111,10 @@ ANDROID EMULATOR RESTARTS
2944
3111
  started is alive. Stim keeps waiting on the same emulator; it never
2945
3112
  launches a duplicate. See \`stim guide errors STIM_NO_DEVICE\` for the
2946
3113
  wait windows, diagnostics, and recovery steps.
3114
+ On macOS, top-level androidEmulatorApp "stim-desktop" in the machine config
3115
+ boots owned emulators without a window and shows them in Stim Desktop; see
3116
+ guide settings. An emulator that is already running keeps its current
3117
+ display until it next boots.
2947
3118
 
2948
3119
  DESTRUCTIVE COMMANDS -- ask the user first
2949
3120
  gc --delete deletes orphaned devices Stim created, tens of GB
@@ -2961,6 +3132,24 @@ one answers from the project. A dev server whose supervisor died is stopped
2961
3132
  only when its recorded process identity still matches. There is no
2962
3133
  \`--delete\` flag on \`stop\`.
2963
3134
 
3135
+ STOP DURING A BUILD
3136
+ \`ios\`, \`android\` and \`stop\` take turns on the workspace's
3137
+ native-run lock. A command that has to wait says so on stderr at once and
3138
+ every 30 seconds:
3139
+ lock waiting for \`stim ios\` (pid 41233, running for 12m04s) in this workspace to finish
3140
+ \`stop\` does not wait out a build it leaves with nothing to deploy to: a
3141
+ plain \`stop\`, \`stop --slot <name>\` for the slot the build targets, or
3142
+ for the workspace's only device. It sends that run SIGINT, only after
3143
+ proving the run's recorded process identity, and waits up to 60 seconds for
3144
+ it to exit. The run stops its build tool, stores nothing from the
3145
+ interrupted build, and exits 130 with STIM_CANCELLED. A run that does not
3146
+ exit in time, or whose build tool outlived it, is refused with
3147
+ STIM_STOP_BLOCKED naming its pid and claim. \`stop --slot <name>\` while the
3148
+ build targets another slot that stays leaves the build running and stops
3149
+ the slot without the lock. A plain \`stop\` ends a recorded EAS session as
3150
+ soon as it sees the lock held: ending a billable session never waits on a
3151
+ build.
3152
+
2964
3153
  CAPACITY
2965
3154
  A booted iOS sim is roughly 1-2 GB of RAM, an Android emulator 2-3 GB. On a
2966
3155
  16 GB machine plan for 2-3 live environments. Nothing enforces this;
@@ -3430,7 +3619,7 @@ result as proof instead of requiring an unrelated screenshot.`
3430
3619
  The wipe resets apps, accounts, device settings and the shared storage
3431
3620
  inside the data partition; the AVD's creation settings and any separate
3432
3621
  SD card image remain. Status lists parked Android emulators; GC
3433
- reports their system image, age and disk size.
3622
+ reports their system image, hardware profile, age and disk size.
3434
3623
  `
3435
3624
  },
3436
3625
  builds: {
@@ -3448,6 +3637,42 @@ result as proof instead of requiring an unrelated screenshot.`
3448
3637
 
3449
3638
  Follow the normal ownership and consent rules in guide agent.
3450
3639
 
3640
+ PREDICTING THE NEXT BUILD (--plan)
3641
+ \`stim ios --plan\` and \`stim android --plan\` answer "will the next run
3642
+ be a cache hit, and how long will it take?" without building, booting,
3643
+ installing, or starting Metro. They take no workspace lock and write no
3644
+ Stim state, cache entry or statistic, so they run beside a build.
3645
+
3646
+ stim ios --plan
3647
+ plan ios 1b625d.. -> local cache hit
3648
+ expect ~2.7s (median of 1 hit run)
3649
+
3650
+ A plan resolves the fingerprint and cache key the way the run would, with
3651
+ the same --slot, --scheme, --configuration, --variant, --device-type,
3652
+ --runtime, --system-image, --device-profile, --eas-profile and
3653
+ --no-build-cache, then looks
3654
+ in the build's order: the local cache, the cache.provider setting's
3655
+ provider, then the app config's build cache provider. A provider has no
3656
+ lookup that skips the download, so a remote check downloads the artifact:
3657
+ the cache.provider tier into a temporary directory the plan removes, the
3658
+ app config's provider wherever it keeps its downloads, as during a run.
3659
+ On a miss it adds the prebuild decision the run would make (generate,
3660
+ regenerate, none, or refuse with STIM_PREBUILD_FAILED). With --eas-profile it asks EAS for a matching
3661
+ build (config, fingerprint:generate, build:list) and downloads nothing.
3662
+ expectedMs is the median of this project's recorded runs with that outcome;
3663
+ the payload is in \`guide facts plan\`.
3664
+
3665
+ A plan is a prediction for the moment it runs. Three things can still
3666
+ change the run: another workspace can store the key first; a prebuild or
3667
+ pod install can move the fingerprint, and the run then looks up the new
3668
+ key once; and a Release hit that fails its JS swap builds fresh.
3669
+ An Android plan reads the ABI from the emulator the slot records, or from
3670
+ the system image a new one would use. A plan refuses --device, --remote,
3671
+ --wait, --no-wait, --no-metro-check and --simulator-app with STIM_BAD_ARG.
3672
+ Without --eas-profile it also refuses the android.remote setting and the
3673
+ experimental compiler CAS with STIM_BAD_ARG, and refuses with
3674
+ STIM_NO_DEVICE when no system image is installed.
3675
+
3451
3676
  IOS SCHEME SELECTION
3452
3677
  Pass \`stim ios --scheme "App Staging"\` to select an exact shared Xcode
3453
3678
  app scheme. Unknown names refuse with the available choices. This is the
@@ -3659,10 +3884,18 @@ THE BUILD CACHE HAS THREE LEVELS
3659
3884
  trims, and clears local caches only: the provider contract has no delete
3660
3885
  operation, so no local command can remove data a team or CI system shares.
3661
3886
 
3662
- A MISS explains itself when it can. When this workspace's previous build
3663
- stored its fingerprint sources beside the cache entry, the fingerprint line
3664
- gains " -- N sources changed: <up to three paths>", and the full list
3665
- (capped at 20 names) lands in the build log as a fingerprint_diff record.
3887
+ A MISS EXPLAINS ITSELF. Each local cache entry keeps the per-source hashes
3888
+ of its fingerprint (hashes only, pruned with the entry). Before compiling,
3889
+ Stim compares the sources it is about to store with a baseline: the entry
3890
+ this workspace's last build of the same platform used, else the newest one
3891
+ another worktree of the same project used. It prints one line:
3892
+
3893
+ cache miss: native dependency added: expo-clipboard (+2 more)
3894
+
3895
+ records the reason as lastBuilds.<platform>.missReason in status --json
3896
+ (see \`guide facts status\`), and writes the changed sources (capped at 20
3897
+ names) to the build log as a fingerprint_diff record. With no baseline the
3898
+ line says there was nothing to compare with.
3666
3899
 
3667
3900
  THE KEY CAN MOVE MID-RUN, and the run says so in two facts rather than two
3668
3901
  explanations. \`expo prebuild\` and \`pod install\` rewrite fingerprinted
@@ -3896,8 +4129,8 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
3896
4129
  summary: "every flag per command, Android variants and flavors, the per-run simulator model, runtime and system image",
3897
4130
  body: () => `THE OPTION SURFACE, IN FULL
3898
4131
  start --json --wait <seconds> --remote --reset-cache
3899
- ios --slot <name> --json --no-metro-check --no-build-cache --scheme <name> --configuration <name> --device-type <name> --runtime <version> --simulator-app <xcode|siniulator|stim-desktop> --device [udid] --wait <seconds> --no-wait --remote <proxy|eas>
3900
- android --slot <name> --json --no-metro-check --no-build-cache --variant <name> --system-image <id> --device [serial] --wait <seconds> --no-wait --remote <proxy|eas>
4132
+ ios --slot <name> --json --plan --no-metro-check --no-build-cache --scheme <name> --configuration <name> --device-type <name> --runtime <version> --simulator-app <xcode|siniulator|stim-desktop> --device [udid] --wait <seconds> --no-wait --remote <proxy|eas>
4133
+ android --slot <name> --json --plan --no-metro-check --no-build-cache --variant <name> --system-image <id> --device-profile <id> --device [serial] --wait <seconds> --no-wait --remote <proxy|eas>
3901
4134
  reload [ios|android] --json
3902
4135
  device lock <ios|android> [id] --slot <name> --for <duration> --wait <seconds> --json;
3903
4136
  unlock [ios|android] --slot <name> --json
@@ -3927,13 +4160,20 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
3927
4160
  stim stop --slot tablet
3928
4161
 
3929
4162
  All slots share this workspace's Metro server and build cache. Native CLI
3930
- runs serialize workspace mutations; a waiting run can wait up to 30 minutes.
4163
+ runs serialize workspace mutations; a waiting run can wait up to 30 minutes
4164
+ and prints what it waits for. \`stop --slot\` interrupts a build only for
4165
+ its own slot or when it stops the workspace's only device (see STOP DURING
4166
+ A BUILD).
3931
4167
  Named slots support local devices; remote sessions use the default slot.
3932
4168
  Names use 1-64 letters, digits, underscores or hyphens, starting with a letter
3933
4169
  or digit. Reserved object-property names are refused.
3934
4170
 
3935
4171
  stop --slot shuts down that slot's owned devices and releases its leases,
3936
- retaining Metro and sibling slots. Plain stop handles the whole workspace.
4172
+ retaining Metro and sibling slots. stop --slot default targets only the
4173
+ workspace's default device, the same one ios/android address with no
4174
+ --slot and status reports with no [slot] label; it never touches a remote
4175
+ session even though remote sessions use the default slot. Plain stop
4176
+ handles the whole workspace.
3937
4177
  status reports named devices under slots and counts their memory. Device
3938
4178
  caps count every slot. Recycling uses the same model/runtime-matched pool
3939
4179
  for every slot, with one shared cap per platform and oldest-first eviction.
@@ -4094,8 +4334,11 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
4094
4334
  says "happens on iPad on iOS 26.5" gets reproduced without writing a
4095
4335
  \`.stim.json\`. \`android --system-image <id>\` is the Android half, taking
4096
4336
  the sdkmanager package id
4097
- ("system-images;android-36;google_apis;arm64-v8a"). Each overrides its
4098
- setting (ios.deviceType, ios.runtime, android.systemImage) for that one
4337
+ ("system-images;android-36;google_apis;arm64-v8a"), and
4338
+ \`android --device-profile <id>\` picks the Android hardware profile, as
4339
+ \`avdmanager list device -c\` spells it: "pixel_tablet" for a tablet,
4340
+ "pixel_fold" for a foldable. Each overrides its setting (ios.deviceType,
4341
+ ios.runtime, android.systemImage, android.deviceProfile) for that one
4099
4342
  invocation, exactly as \`--configuration\` overrides ios.configuration.
4100
4343
 
4101
4344
  A name that is not INSTALLED on this machine refuses with STIM_BAD_ARG
@@ -4117,11 +4360,13 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
4117
4360
  ALREADY owns a simulator and \`--device-type\` names a different model,
4118
4361
  Stim refuses rather than silently booting the wrong one: reap the current
4119
4362
  sim with \`stim worktree remove\` (or \`stim gc --delete\`), then run
4120
- \`stim ios\` again to create the requested one. \`--runtime\` and
4121
- \`--system-image\` apply at creation only, so an existing device keeps the
4122
- version it was made with. The --json payload reports what was actually
4123
- used: \`deviceType\` and \`runtime\` on iOS, \`systemImage\` on Android,
4124
- read from the device itself, so a settings-driven run reports them too.`
4363
+ \`stim ios\` again to create the requested one. \`--device-profile\` does
4364
+ the same for an AVD of another profile. To keep both devices, give the new
4365
+ one its own \`--slot\`. \`--runtime\` and \`--system-image\` apply at
4366
+ creation only, so an existing device keeps the version it was made with.
4367
+ The --json payload reports what was actually used: \`deviceType\` and
4368
+ \`runtime\` on iOS, \`systemImage\` and \`deviceProfile\` on Android, read
4369
+ from the device itself, so a settings-driven run reports them too.`
4125
4370
  },
4126
4371
  devices: {
4127
4372
  summary: "ios --device and android --device on a phone: what the run skips, signing, the LAN wiring, the collector",
@@ -4318,6 +4563,12 @@ HOLDING A DEVICE ACROSS RUNS
4318
4563
  With no id, \`lock\` and a \`--device\` run pick from the POOL of connected
4319
4564
  devices, so two phones on one machine no longer refuse.
4320
4565
 
4566
+ An id may also name this workspace's own Stim-owned simulator (UDID) or
4567
+ running emulator (\`emulator-NNNN\`), in any slot; \`--slot\`, if given,
4568
+ must match it. Status then reports the device \`driven by stim device
4569
+ lock\`, so other agents leave it alone. A workspace holds one lease per
4570
+ platform and slot, so this refuses while the slot leases a phone.
4571
+
4321
4572
  THE POOL: WHICH DEVICE AN ID-LESS \`--device\` PICKS
4322
4573
  Candidates are the connected devices the resolver already accepts: on iOS,
4323
4574
  paired, with Developer Mode on, over a cable or Wi-Fi; on Android, every
@@ -4968,7 +5219,8 @@ Resolution order, first match wins:
4968
5219
  1. workspace ~/.stim/config.json, under this project's entry
4969
5220
  2. repo ~/.stim/config.json, under this repo's git common dir
4970
5221
  3. committed .stim.json beside the app's package.json
4971
- 4. machine ~/.stim/config.json, top-level optimizations only
5222
+ 4. machine ~/.stim/config.json, top-level optimizations and
5223
+ android.deviceProfile only
4972
5224
  5. Stim default
4973
5225
  An environment override, where a setting has one, wins over every layer.
4974
5226
 
@@ -5061,9 +5313,27 @@ KEYS STIM READS
5061
5313
  from. The \`--system-image\` flag overrides this per
5062
5314
  invocation, and an id this SDK has not installed is
5063
5315
  STIM_BAD_ARG with the installed ids printed.
5064
- New AVDs use the Pixel 6 hardware profile (1080x2400,
5065
- 420 dpi). Existing AVDs keep their display settings;
5066
- parked AVDs from the old generic profile are not adopted.
5316
+ android.deviceProfile e.g. "pixel_fold" -- the avdmanager hardware profile a
5317
+ new owned AVD is created with, spelled exactly as
5318
+ \`avdmanager list device -c\` prints it. Defaults to
5319
+ pixel_6 (1080x2400, 420 dpi); "pixel_tablet" and
5320
+ "pixel_fold" give a tablet and a foldable, and
5321
+ avdmanager writes the foldable's hinge and posture
5322
+ keys from its profile. Readable from the machine
5323
+ layer too, so one machine can default every workspace
5324
+ to a tablet. A set profile counts as a request: each
5325
+ run then checks it with avdmanager (about 2s), and a
5326
+ workspace that already owns an AVD of another profile
5327
+ refuses until that AVD is reaped. The \`--device-profile\` flag overrides it
5328
+ per invocation, and an id avdmanager does not offer is
5329
+ STIM_BAD_ARG with the offered ids printed; that check
5330
+ runs avdmanager only when a profile is given. A
5331
+ parked AVD is adopted only by a request for its own
5332
+ profile. When this workspace already owns an AVD of
5333
+ another profile, a requested profile refuses rather
5334
+ than booting it; reap the AVD to create the new one.
5335
+ Existing AVDs keep their display settings; parked AVDs
5336
+ from the old generic profile are not adopted.
5067
5337
  android.dataPartitionSizeGb
5068
5338
  whole GiB for a newly created owned AVD's data
5069
5339
  partition. Defaults to 8; accepts 6 through 16384.
@@ -5093,7 +5363,9 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
5093
5363
  On displayless Linux, Stim launches with
5094
5364
  -gpu swiftshader_indirect -noaudio; those arguments
5095
5365
  override hw.gpu.enabled, hw.gpu.mode, hw.audioInput,
5096
- and hw.audioOutput for that headless launch.
5366
+ and hw.audioOutput for that headless launch. With
5367
+ androidEmulatorApp "stim-desktop" on macOS, -gpu host
5368
+ overrides hw.gpu.mode the same way.
5097
5369
  android.variant e.g. "productionDebug" -- the gradle variant to
5098
5370
  assemble and install on a project with product
5099
5371
  flavors. A repo like tlon-mobile with
@@ -5296,6 +5568,22 @@ window shuts down that simulator. Enable "Leave simulator running after window
5296
5568
  is closed" in Siniulator Settings if Stim should keep it running. See \`guide lifecycle simslim\` for
5297
5569
  window behavior.
5298
5570
 
5571
+ THE ANDROID EMULATOR APP IS MACHINE-LEVEL
5572
+ Top-level \`androidEmulatorApp\` in ~/.stim/config.json selects how an owned
5573
+ Android emulator that Stim boots on macOS is displayed. Unset or
5574
+ \`"emulator"\` opens the emulator's own window. To boot it headlessly and show
5575
+ it in Stim Desktop instead:
5576
+
5577
+ { "androidEmulatorApp": "stim-desktop" }
5578
+
5579
+ Stim then starts the emulator with \`-no-window -gpu host\` and opens
5580
+ \`stim-desktop://open?serial=<serial>\` in the background. Stim Desktop reads
5581
+ frames and sends input over the emulator's gRPC endpoint. The setting applies
5582
+ only when Stim boots the emulator: one that is already running keeps its
5583
+ current display until it next boots, and physical devices are unaffected.
5584
+ An invalid value refuses before boot. On Linux and Windows the setting has
5585
+ no effect.
5586
+
5299
5587
  THE DEVICE POOL BOUNDS ARE MACHINE-LEVEL TOO
5300
5588
  \`pool.iosParkedMax\` caps how many parked simulators \`worktree remove\` may
5301
5589
  leave behind for a later workspace to adopt. It is machine-level for the same
@@ -1,9 +1,10 @@
1
1
  import { H as projectDeviceSlots } from "./config-BEq0Qw_a.mjs";
2
2
  import { m as readWorkspaceState } from "./metro-BWLOJ_Wr.mjs";
3
3
  import { o as formatLongDuration } from "./command-output-D5z2_bcF.mjs";
4
- import { c as createActivityReader, l as idleForMs, o as parseActiveBuild, r as activeBuildState, t as ACTIVE_BUILD_KEY } from "./build-progress-BXx-ZBe4.mjs";
5
- import { N as ownedAvdSerialResolver } from "./android-787HhP5w.mjs";
6
- import { d as teardownOwnedAvd, f as teardownOwnedIosSim } from "./ownership-BfPNRf3-.mjs";
4
+ import { n as createActivityReader, r as idleForMs } from "./activity-BtG4Va9l.mjs";
5
+ import { I as ownedAvdSerialResolver } from "./android-C4zG2Tuc.mjs";
6
+ import { d as teardownOwnedAvd, f as teardownOwnedIosSim } from "./ownership-BiojdtAp.mjs";
7
+ import { r as activeBuildState, s as parseActiveBuild, t as ACTIVE_BUILD_KEY } from "./build-progress-CDwogz6R.mjs";
7
8
  import chalk from "chalk";
8
9
  //#region src/commands/gc/idle.ts
9
10
  function findOwnedDeviceActivity({ config, sims, androidSerial, readActivity, deadProjects = [] }) {
@@ -1,10 +1,10 @@
1
1
  import { f as getProject, k as ownership_claim_exports, u as getConfigDir } from "./config-BEq0Qw_a.mjs";
2
2
  import { O as workspaceDir, m as readWorkspaceState } from "./metro-BWLOJ_Wr.mjs";
3
- import { r as stopDeclaringSpawnsOn, t as declareSpawnsOn } from "./spawn-claims-CUleC2cM.mjs";
4
- import { n as workspaceProcessLockError, r as workspaceProcessLockPath, t as withWorkspaceProcessLock } from "./workspace-process-lock-BXA96myD.mjs";
3
+ import { n as declareSpawnsOn, o as stopDeclaringSpawnsOn } from "./spawn-claims-BJwXTMPt.mjs";
4
+ import { n as workspaceProcessLockError, r as workspaceProcessLockPath, t as withWorkspaceProcessLock } from "./workspace-process-lock-Cx74RSDZ.mjs";
5
5
  import { a as formatElapsed } from "./command-output-D5z2_bcF.mjs";
6
- import { h as listBuildLocks } from "./device-lease-CbEaIk7b.mjs";
7
- import { n as managedLockHolders, t as resolveSupervisorTarget } from "./ownership-BfPNRf3-.mjs";
6
+ import { h as listBuildLocks } from "./device-lease-D83nqeMX.mjs";
7
+ import { n as managedLockHolders, t as resolveSupervisorTarget } from "./ownership-BiojdtAp.mjs";
8
8
  import { lstatSync, readdirSync, rmSync, rmdirSync, statSync, unlinkSync } from "node:fs";
9
9
  import { realpathSync as realpathSync$1 } from "fs";
10
10
  import { resolve } from "path";