stim 1.11.0 → 1.12.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 (71) hide show
  1. package/dist/{activity-BtG4Va9l.mjs → activity-CCZJs__P.mjs} +4 -3
  2. package/dist/{android-C4zG2Tuc.mjs → android-75Sk2rIR.mjs} +25 -8
  3. package/dist/{android-C1q4l523.mjs → android-B7X-8H7h.mjs} +75 -32
  4. package/dist/{android-BA2i_KAV.mjs → android-BQiKJYK0.mjs} +1 -1
  5. package/dist/{android-cas-DfJkwCXW.mjs → android-cas-DzLPXiEn.mjs} +7 -7
  6. package/dist/{app-install-DHut6JnV.mjs → app-install-CsZi0SAT.mjs} +1 -1
  7. package/dist/{workspaces-COD2xCz-.mjs → budget-DbzW5VTD.mjs} +641 -32
  8. package/dist/{build-plan-CeAYgKAx.mjs → build-plan-CqntbR7b.mjs} +120 -35
  9. package/dist/{build-progress-CDwogz6R.mjs → build-progress-h60GPV27.mjs} +3 -3
  10. package/dist/{cache-manifest-Pubfp8wV.mjs → cache-manifest-DWPF4RKJ.mjs} +1 -1
  11. package/dist/cache-manifest.mjs +1 -1
  12. package/dist/cli.mjs +16 -16
  13. package/dist/collector-run.mjs +4 -4
  14. package/dist/{command-output-D5z2_bcF.mjs → command-output-BWCj5Vh-.mjs} +1 -1
  15. package/dist/{config-BEq0Qw_a.mjs → config-0jCcMM0E.mjs} +10 -1
  16. package/dist/{dependency-state-r9UesA9a.mjs → dependency-state-DNN0yfx6.mjs} +1 -1
  17. package/dist/{deps-OF7CD5Dx.mjs → deps-CO-_7UOm.mjs} +2 -2
  18. package/dist/{device-BwH2iI3O.mjs → device-9r9xRYDa.mjs} +7 -7
  19. package/dist/{device-lease-D83nqeMX.mjs → device-lease-B9LAXIUH.mjs} +5 -5
  20. package/dist/{device-pool-DHj7cdPy.mjs → device-pool-BoezJd-c.mjs} +4 -4
  21. package/dist/{device-remote-BQZSnnmE.mjs → device-remote-C0_o-tJH.mjs} +254 -579
  22. package/dist/{doctor-D8QdMRMf.mjs → doctor-LfDlbR-N.mjs} +19 -18
  23. package/dist/{error-diagnostics-UYFSQwRy.mjs → error-diagnostics-CCxjn31V.mjs} +7 -7
  24. package/dist/{gc-COZteyiq.mjs → gc-C4nQFcTX.mjs} +203 -39
  25. package/dist/{guide-NDvTmMi-.mjs → guide-BPBlh9ML.mjs} +189 -38
  26. package/dist/{guide-status-CWvti2Lg.mjs → guide-status-i9ogHt4v.mjs} +2 -2
  27. package/dist/{idle-NETbeNiQ.mjs → idle-S3tFZ53_.mjs} +7 -7
  28. package/dist/{in-use-DVhlSoyn.mjs → in-use-D9XYEgFD.mjs} +7 -7
  29. package/dist/{ios-CQLKpNfr.mjs → ios-CDzWL1mj.mjs} +30 -29
  30. package/dist/{ios-DArbmwer.mjs → ios-CZWOHTTc.mjs} +23 -19
  31. package/dist/{ios-device-CwDZo0X4.mjs → ios-device-D9cLxVr5.mjs} +1 -1
  32. package/dist/{launch-verify-CuPDGXdr.mjs → launch-verify-B2oR_kFN.mjs} +2 -2
  33. package/dist/{logs-B44a1UeU.mjs → logs-SzuYudOj.mjs} +6 -6
  34. package/dist/{merge-state-DDxS-XIZ.mjs → merge-state-ytFQCeh4.mjs} +38 -8
  35. package/dist/{metro-BWLOJ_Wr.mjs → metro-Dzo30hvJ.mjs} +1 -1
  36. package/dist/{named-ports-Dc7neAlc.mjs → named-ports-Dn1o61D9.mjs} +3 -3
  37. package/dist/{ownership-BiojdtAp.mjs → ownership-B8d4kXBx.mjs} +49 -16
  38. package/dist/{ownership-D2xbLVoz.mjs → ownership-Dqnrjrio.mjs} +2 -2
  39. package/dist/{ports-DwBaRFJs.mjs → ports-Dp_QTwTC.mjs} +3 -3
  40. package/dist/{project-BXZzOABt.mjs → project-B8rbutVC.mjs} +4 -72
  41. package/dist/{reload-By9Dwsrt.mjs → reload-nocmx8KB.mjs} +9 -9
  42. package/dist/remote-cache-BRsRZru5.mjs +526 -0
  43. package/dist/{server-bare-D_RK1RCj.mjs → server-bare-Gn3ssSdK.mjs} +1 -1
  44. package/dist/{server-expo-o6H5gcBc.mjs → server-expo-CeT1nIIk.mjs} +2 -2
  45. package/dist/server-expo-eWi9Coof.mjs +2 -0
  46. package/dist/{settings-B5oFZEri.mjs → settings-BlyDn2Oz.mjs} +2 -2
  47. package/dist/{settings-C0ugALSC.mjs → settings-bE-Gu3Ti.mjs} +23 -11
  48. package/dist/settings.schema.json +22 -2
  49. package/dist/{simslim-CIR3IYJO.mjs → simslim-COtEEP7x.mjs} +6 -5
  50. package/dist/{slot-launch-rggO1Esw.mjs → slot-launch-DIACGEfH.mjs} +4 -4
  51. package/dist/{spawn-claims-BJwXTMPt.mjs → spawn-claims-PT8aQpCa.mjs} +1 -1
  52. package/dist/{start-i8zc9VmS.mjs → start-BFstVBlx.mjs} +1 -1
  53. package/dist/{start-BSsf2tUs.mjs → start-BboE1HIS.mjs} +108 -17
  54. package/dist/{state-WGdIbi_d.mjs → state-DcDgzfu3.mjs} +15 -3
  55. package/dist/{stats-BAgJaLA4.mjs → stats-D8rUTPHd.mjs} +1 -1
  56. package/dist/{stats-DBYJ5bxL.mjs → stats-DiCtmluY.mjs} +4 -4
  57. package/dist/{status-Q-WDEGCB.mjs → status-BUASYyy_.mjs} +73 -28
  58. package/dist/{status-CitcBRsC.mjs → status-DI9Tjo7T.mjs} +41 -29
  59. package/dist/stim-desktop-D0xhpZt8.mjs +29 -0
  60. package/dist/{stop-rst5mL14.mjs → stop-BI7QY76M.mjs} +2 -2
  61. package/dist/{stop-DIhrvu0B.mjs → stop-Bn6v-GvS.mjs} +23 -16
  62. package/dist/supervisor-run.mjs +11 -11
  63. package/dist/{workspace-process-lock-Cx74RSDZ.mjs → workspace-process-lock-BvvJTfo_.mjs} +2 -2
  64. package/dist/{worktree-DhxDTK44.mjs → worktree-B5sTRskL.mjs} +1 -1
  65. package/dist/{worktree-KOjMX3zA.mjs → worktree-ChDL5fO1.mjs} +17 -16
  66. package/dist/{worktree-BlizKDpZ.mjs → worktree-DeBQSVtR.mjs} +3 -1
  67. package/dist/{xcode-B5SPD--o.mjs → xcode-BzplpQzc.mjs} +7 -7
  68. package/package.json +5 -5
  69. package/dist/budget-De3P2rq_.mjs +0 -620
  70. package/dist/native-run-D7yB_AsB.mjs +0 -143
  71. package/dist/server-expo-B-CCUJZj.mjs +0 -2
@@ -1,6 +1,7 @@
1
- import { o as findProjectRoot } from "./project-BXZzOABt.mjs";
2
- import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-B5oFZEri.mjs";
3
- import { t as guideStatus } from "./guide-status-CWvti2Lg.mjs";
1
+ import { i as findProjectRoot } from "./project-B8rbutVC.mjs";
2
+ import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-BlyDn2Oz.mjs";
3
+ import { t as RECENT_LAUNCH_MS } from "./status-BUASYyy_.mjs";
4
+ import { t as guideStatus } from "./guide-status-i9ogHt4v.mjs";
4
5
  import { SETTINGS_SCHEMA_URL } from "@stim-cli/core/state";
5
6
  import chalk from "chalk";
6
7
  //#endregion
@@ -177,7 +178,8 @@ RULES DURING THE LOOP
177
178
  them. Use stim doctor when a build is unexpectedly slow or the environment
178
179
  looks incomplete. If status reports a changed Android serial, rerun stim
179
180
  android with the same build options to restore forwarding, then reopen your automation
180
- session on the reported serial (guide lifecycle).
181
+ session on the reported serial (guide lifecycle). Each status issue names a
182
+ remedy to run from its workspace (guide facts status).
181
183
 
182
184
  OWNERSHIP AND DELETION
183
185
 
@@ -242,7 +244,11 @@ Run stim stop when you pause or finish a task, and stim worktree remove once
242
244
  it is merged or abandoned. Never create a simulator or emulator by hand;
243
245
  every device comes from Stim. Before starting a new workspace, check stim
244
246
  status for an idle workspace to reuse and confirm capacity headroom instead of
245
- adding another.
247
+ adding another. Never quit Device Hub or Simulator.app: on Xcode 27
248
+ (confirmed on 27A266a), quitting Device Hub by default shuts down every booted
249
+ simulator on the machine, including ones it never opened a window for and
250
+ ones other workspaces or agents are using. Use stim stop on workspaces you
251
+ own instead.
246
252
 
247
253
  SANDBOXES
248
254
 
@@ -836,12 +842,14 @@ RULES
836
842
  orphanedWorkspaces { dir, projectRoot, bytes } --delete removes the
837
843
  whole workspace directory
838
844
  linkedWorktrees { path, idleDays, mergedInto, willRemove,
839
- reason, detail } mergedInto is the default
840
- branch HEAD is merged into ("origin/main"),
841
- or null; detail says why it is removed
842
- ("merged into origin/main", "idle 9d") or kept.
843
- Without --worktrees, the source checkout and
844
- roots outside git are left out
845
+ reason, detail, eligibleAt } mergedInto is
846
+ the default branch HEAD is merged into
847
+ ("origin/main"), or null; detail says why it
848
+ is removed ("merged into origin/main", "idle
849
+ 9d") or kept. eligibleAt is the ISO time a
850
+ recent-activity worktree becomes removable,
851
+ else null. Without --worktrees, the source
852
+ checkout and roots outside git are left out
845
853
  parkedSimulators { udid, name, model, runtime, parkedAt, bytes,
846
854
  listed } with --older-than, only those parked
847
855
  at least that long
@@ -895,7 +903,8 @@ RULES
895
903
  locked | in-use | status-unreadable | dirty |
896
904
  unpushed-unchecked | unpushed | submodules |
897
905
  not-merged | merge-unknown | last-use-unknown |
898
- recently-used
906
+ recently-used | activity-unknown |
907
+ recent-activity
899
908
 
900
909
  These print the error contract instead and exit 1:
901
910
 
@@ -906,9 +915,47 @@ RULES
906
915
  - --cache together with --worktrees or --idle`
907
916
  },
908
917
  status: {
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",
918
+ summary: "the status payload's issues and their codes, build and device activity fields: a running build, its estimate, each platform's last build, and who drives each device",
910
919
  body: () => ` stim status --json
911
920
 
921
+ Each environment carries issues, the things in that workspace that need
922
+ the user, and warnings, the same issues as text ("<slot>: " when not the
923
+ default slot, then "<message>; run \`<remedy>\`"):
924
+
925
+ issues [{ code, severity, message, remedy, workspace, slot? }]
926
+
927
+ code port-not-ours something other than this workspace's
928
+ Metro answers its reserved port
929
+ sim-missing the recorded simulator no longer exists
930
+ sim-without-metro the simulator is booted and no Metro
931
+ serves the workspace
932
+ avd-serial-changed the owned emulator came back on another
933
+ serial, so Metro forwarding is lost
934
+ avd-missing the recorded AVD no longer exists
935
+ avd-not-detected adb does not see the owned emulator while
936
+ the workspace expects it: it holds an
937
+ unexpired lease on its serial, or it
938
+ launched onto it and has not stopped
939
+ that slot since, and its dev server runs
940
+ or the launch was in the last
941
+ ${RECENT_LAUNCH_MS / 6e4} minutes. An idle workspace's
942
+ shut-down emulator is android.state
943
+ "not-detected" with no issue.
944
+ avd-unchecked the emulator listing could not be read
945
+ supervisor-unverified a supervisor record whose process status
946
+ cannot prove gone or ours; stop refuses to
947
+ signal it
948
+ severity "error" when stop or start refuses until it is resolved, else
949
+ "warning"
950
+ remedy a command to run from workspace, such as "stim android --slot
951
+ fold"
952
+ slot absent for the default slot
953
+
954
+ A supervisor record whose pid is gone or reused is not an issue: status
955
+ reports supervisor null, and the next stop or start clears the record.
956
+ \`stop --slot <name>\` forgets that slot's launch, so a device stopped on
957
+ purpose is not reported while the shared dev server keeps running.
958
+
912
959
  Each booted simulator and detected emulator in environments (and in
913
960
  slots) carries activity; a shut-down or physical device has none:
914
961
 
@@ -1006,11 +1053,12 @@ RULES
1006
1053
  is already built, so it does not measure progress.`
1007
1054
  },
1008
1055
  plan: {
1009
- summary: "the ios and android --plan payload: fingerprint, cacheHit, prebuild, expectedMs and basis",
1056
+ summary: "the ios and android --plan payload: fingerprint, cacheHit, prebuild, missReason, expectedMs and basis",
1010
1057
  body: () => ` stim ios --plan --json # or: stim android --plan --json
1011
1058
 
1012
1059
  { platform, slot?, fingerprint, cacheKey, cacheHit, provider,
1013
- cacheSkipped, prebuild, outcome, expectedMs, basis, refusal? }
1060
+ cacheSkipped, prebuild, outcome, expectedMs, basis, missReason?,
1061
+ refusal? }
1014
1062
 
1015
1063
  fingerprint the fingerprint the run would look up first; with
1016
1064
  --eas-profile, the one EAS CLI computes
@@ -1025,6 +1073,15 @@ RULES
1025
1073
  expectedMs the median wall time of this project's last successful runs
1026
1074
  with that outcome on that platform, or null with none
1027
1075
  basis how many runs expectedMs comes from (at most 10)
1076
+ missReason on a predicted cold build with cache reads on, why the
1077
+ cache has no app, in the shape of lastBuilds.<platform>
1078
+ .missReason (\`guide facts status\`), compared with the same
1079
+ baseline the run would use. kind is "changed",
1080
+ "no-baseline", "same-sources" or "prebuild-pending": a
1081
+ baseline exists and the run would prebuild first, which the
1082
+ plan does not, so changes compare the fingerprint before that
1083
+ prebuild; changeCount 0 then means those inputs match the
1084
+ baseline. rekeyedBy is empty.
1028
1085
  refusal { code, message, remedy } when the run would refuse:
1029
1086
  STIM_PREBUILD_FAILED for a tracked native dir the fingerprint
1030
1087
  leaves out, STIM_EAS_BUILD_MISSING for an EAS miss
@@ -2574,7 +2631,11 @@ captured" (in metro.ndjson, bare RN)
2574
2631
  ios.deviceType, ios.runtime, android.systemImage or android.deviceProfile
2575
2632
  setting is checked the same way, and the check applies
2576
2633
  even when this workspace ALREADY owns a device, so a name that could never
2577
- create anything is caught rather than left to a later run.
2634
+ create anything is caught rather than left to a later run. The
2635
+ \`pixel_fold\` and \`resizable\` profiles on a system image without
2636
+ foldable support (SupportPixelFold in its advancedFeatures.ini) refuse the
2637
+ same way, since the emulator quits on boot; the remedy names an installed
2638
+ image that has it, or an sdkmanager install when none does.
2578
2639
  \`gc --json --cache <name>\` refuses with STIM_BAD_ARG when no shared cache
2579
2640
  carries the name; the remedy names the caches on this machine. \`gc\`
2580
2641
  refuses --cache together with --worktrees the same way.
@@ -2643,9 +2704,17 @@ captured" (in metro.ndjson, bare RN)
2643
2704
  summary: "a lock held past the wait; workspace-process and short directory locks",
2644
2705
  body: () => `STIM_LOCK_TIMEOUT
2645
2706
  The same locks, held by an ordinary command that is still running, for
2646
- longer than the wait -- 60s by default, 4 minutes for the remote-session and
2647
- EAS project locks, and ~90 minutes for the \`worktree warm\` lock, which one
2648
- \`--refresh\` can hold for a whole dependency install. That wait prints its
2707
+ longer than the wait -- 60s by default, 4 minutes for the remote-session lock
2708
+ and for \`gc\` deleting EAS sessions under the EAS project lock (its sweep
2709
+ skips at once while that lock is held), and ~90 minutes for the \`worktree warm\` lock, which one
2710
+ \`--refresh\` can hold for a whole dependency install. The machine-wide EAS
2711
+ project lock admits one EAS session start at a time. A \`--remote eas\` run
2712
+ waits on it after its build with no overall limit, printing \`lock waiting
2713
+ for EAS remote start (pid 41233, in <workspace>, running for 1m12s) to
2714
+ release the EAS project lock\` at once and \`still waiting for ...\` every 30
2715
+ seconds. It refuses only when one holder has held the lock for longer than
2716
+ the slowest EAS session start (39 minutes), naming that pid.
2717
+ The \`worktree warm\` wait prints its
2649
2718
  elapsed waiting time and holder every 30 seconds (\`lock waiting 40s
2650
2719
  for stim worktree warm --refresh (pid 41233)\`) and the refusal names the same holder
2651
2720
  and the lock directory under ~/.stim/warm-locks.
@@ -3111,9 +3180,9 @@ ANDROID EMULATOR RESTARTS
3111
3180
  started is alive. Stim keeps waiting on the same emulator; it never
3112
3181
  launches a duplicate. See \`stim guide errors STIM_NO_DEVICE\` for the
3113
3182
  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
3183
+ On macOS, androidEmulatorApp "stim-desktop", the default while Stim Desktop
3184
+ is installed, boots owned emulators without a window and shows them in Stim
3185
+ Desktop; see guide settings. An emulator that is already running keeps its current
3117
3186
  display until it next boots.
3118
3187
 
3119
3188
  DESTRUCTIVE COMMANDS -- ask the user first
@@ -3657,7 +3726,11 @@ PREDICTING THE NEXT BUILD (--plan)
3657
3726
  the cache.provider tier into a temporary directory the plan removes, the
3658
3727
  app config's provider wherever it keeps its downloads, as during a run.
3659
3728
  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
3729
+ regenerate, none, or refuse with STIM_PREBUILD_FAILED) and, with cache
3730
+ reads on, the miss reason the run would print, such as "native dependency
3731
+ added: expo-clipboard". A plan never prebuilds, so when the run would and a
3732
+ baseline exists, the reason's kind is prebuild-pending and it compares the
3733
+ fingerprint before that prebuild. With --eas-profile it asks EAS for a matching
3661
3734
  build (config, fingerprint:generate, build:list) and downloads nothing.
3662
3735
  expectedMs is the median of this project's recorded runs with that outcome;
3663
3736
  the payload is in \`guide facts plan\`.
@@ -4362,8 +4435,17 @@ OPT-IN CONCURRENCY LIMITS (UNLIMITED BY DEFAULT)
4362
4435
  sim with \`stim worktree remove\` (or \`stim gc --delete\`), then run
4363
4436
  \`stim ios\` again to create the requested one. \`--device-profile\` does
4364
4437
  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.
4438
+ one its own \`--slot\`. \`--runtime\` and the ios.runtime and
4439
+ android.systemImage settings apply at creation only, so an existing device
4440
+ keeps the version it was made with. An explicit \`--system-image\` that
4441
+ names another image than this workspace's AVD refuses the same way, unless
4442
+ that AVD never finished a boot (for example one made from an image its
4443
+ profile cannot boot): Stim then deletes it through owned-device teardown and
4444
+ creates the requested one. \`--device-profile pixel_fold\` or
4445
+ \`resizable\` on a system image without foldable support (SupportPixelFold
4446
+ in its advancedFeatures.ini) refuses with STIM_BAD_ARG before anything is
4447
+ created, since the emulator quits on boot; the remedy names an installed
4448
+ image that has it.
4367
4449
  The --json payload reports what was actually used: \`deviceType\` and
4368
4450
  \`runtime\` on iOS, \`systemImage\` and \`deviceProfile\` on Android, read
4369
4451
  from the device itself, so a settings-driven run reports them too.`
@@ -4723,9 +4805,10 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
4723
4805
  boot (including the initial boot request) up to 10 minutes, and app installation
4724
4806
  up to 5 minutes. Process termination confirmation can take another 10 seconds;
4725
4807
  a final boot-state query can take 30 seconds. After boot, Stim opens the owned
4726
- simulator in the selected Xcode's Device Hub on Xcode 27, or Simulator on
4727
- older Xcode. Top-level iosSimulatorApp in the machine config can select
4728
- Siniulator or Stim Desktop instead; see guide settings. Override it for one
4808
+ simulator in Stim Desktop while it is installed, otherwise in the selected
4809
+ Xcode's Device Hub on Xcode 27, or Simulator on older Xcode. Top-level
4810
+ iosSimulatorApp in the machine config can select another viewer; see guide
4811
+ settings. Override it for one
4729
4812
  local run with \`stim ios --simulator-app siniulator\`,
4730
4813
  \`--simulator-app stim-desktop\`, or \`--simulator-app xcode\`. This also
4731
4814
  opens an already running owned simulator without rebooting it or saving the
@@ -4745,7 +4828,11 @@ HOST MEMORY PRESSURE AND STALLED SIMULATORS
4745
4828
 
4746
4829
  If pressure is elevated, free host memory before retrying. Use \`stim stop\`
4747
4830
  only in workspaces you own and have finished using; ask before closing other
4748
- agents' simulators or heavy apps. Rebooting a simulator under the same pressure
4831
+ agents' simulators or heavy apps. Never quit Device Hub or Simulator.app to
4832
+ free memory: on Xcode 27 (confirmed on 27A266a), quitting Device Hub by
4833
+ default shuts down every booted simulator on the machine, including ones it
4834
+ never opened a window for and ones other workspaces or agents are using.
4835
+ Rebooting a simulator under the same pressure
4749
4836
  can repeat the stall. Consider fewer concurrent builds/devices (guide lifecycle
4750
4837
  concurrency) and a reviewed SimSlim profile for future runs.`
4751
4838
  }
@@ -4773,6 +4860,8 @@ WHAT RECLAIMS AN OWNED DEVICE
4773
4860
  verified parked simulators and emulators, and
4774
4861
  runs \`stim worktree remove\` on every clean,
4775
4862
  Stim-managed linked worktree whose branch is merged
4863
+ and that shows no activity within
4864
+ gc.worktreeGraceMinutes
4776
4865
  stim gc --delete --older-than <days>
4777
4866
  also reaps the device of a workspace no Stim
4778
4867
  command has used in that long, even though the
@@ -4795,8 +4884,12 @@ boot rather than a create, a provision and a reinstall.
4795
4884
 
4796
4885
  Before shutting down, parking or deleting an owned device, Stim best-effort
4797
4886
  closes local agent-device sessions bound to its exact iOS UDID or live Android
4798
- serial. It rechecks device ownership and uses agent-device's rejecting session
4799
- target guard; sessions on other devices stay open. Physical devices are outside
4887
+ serial. An Android session must also name the owned AVD, because the next
4888
+ emulator on a console port reuses its serial. \`stop\` closes a session only
4889
+ when agent-device's claim on the device names it and was taken inside this
4890
+ workspace; sessions from another workspace or claim stay open. Stim rechecks
4891
+ device ownership and uses agent-device's rejecting session target guard;
4892
+ sessions on other devices stay open. Physical devices are outside
4800
4893
  this cleanup. agent-device is optional: a missing binary skips this step, and a
4801
4894
  failed or timed-out list/close prints a device line on stderr while teardown
4802
4895
  continues. Cleanup allows at most 15 seconds of agent-device calls per device.
@@ -4852,6 +4945,26 @@ SWEEPING FINISHED WORKTREES
4852
4945
  initialized submodules. Without --worktrees, the report leaves out the
4853
4946
  source checkout and roots outside git.
4854
4947
 
4948
+ IN USE means its dev server supervisor runs, a stim ios, android or stop
4949
+ run holds its native-run lock, a live build lock or slot names it, a
4950
+ managed tunnel or remote lock is held, an owned simulator or emulator of
4951
+ the workspace is booted (an agent-device session needs one), or it holds
4952
+ an unexpired device lease. When the simulator or emulator list cannot be
4953
+ read, the worktree counts as in use. A device left booted keeps the
4954
+ worktree until \`stim stop\` in it, or \`gc --idle <duration>\`, shuts
4955
+ the device down.
4956
+
4957
+ RECENT ACTIVITY keeps a worktree gc would otherwise remove until
4958
+ gc.worktreeGraceMinutes (120 by default, \`guide settings\`) have passed
4959
+ since the latest of: a write to its git index, HEAD or HEAD reflog, a write
4960
+ to its Stim workspace state or log files, and, for a merged branch, the
4961
+ committer date of the commit that brought it into the default branch. That
4962
+ window is when an agent that just merged runs \`stim stop\` and \`stim
4963
+ worktree remove\` itself. The reason is recent-activity, and the report
4964
+ and the JSON eligibleAt field say when it becomes removable. When that
4965
+ activity cannot be read, the worktree is kept (reason activity-unknown).
4966
+ 0 turns the grace period off.
4967
+
4855
4968
  MERGED means, with the default branch taken from origin/HEAD, after a
4856
4969
  \`git fetch origin <default>\` per repository (30s timeout, no credential
4857
4970
  prompt; skipped when that checkout fetched in the last 10 minutes):
@@ -4880,8 +4993,9 @@ SWEEPING FINISHED WORKTREES
4880
4993
  --cache with --worktrees is refused with STIM_BAD_ARG; run them separately.
4881
4994
  With --delete it runs the \`stim worktree remove\` pipeline, never --force,
4882
4995
  on each removable worktree. That pipeline re-inspects the worktree and
4883
- re-checks use under the removal locks, and idleness for an idle worktree
4884
- or an unchanged HEAD for a merged one, then parks devices and handles the
4996
+ re-checks use and recent activity under the removal locks, and idleness
4997
+ for an idle worktree or an unchanged HEAD for a merged one, then parks
4998
+ devices through the same teardown and handles the
4885
4999
  branch exactly as a manual \`stim worktree remove\`, which keeps the
4886
5000
  checkout when its HEAD moves while devices are reclaimed. A worktree that
4887
5001
  changed since the report is kept with the reason. A worktree that fails is
@@ -5332,6 +5446,12 @@ KEYS STIM READS
5332
5446
  profile. When this workspace already owns an AVD of
5333
5447
  another profile, a requested profile refuses rather
5334
5448
  than booting it; reap the AVD to create the new one.
5449
+ "pixel_fold" and "resizable" need a system image
5450
+ whose advancedFeatures.ini turns on SupportPixelFold
5451
+ (recent images such as API 34 google_apis do); the
5452
+ emulator quits on boot without it, so Stim refuses
5453
+ the pair with
5454
+ STIM_BAD_ARG and names an installed image that has it.
5335
5455
  Existing AVDs keep their display settings; parked AVDs
5336
5456
  from the old generic profile are not adopted.
5337
5457
  android.dataPartitionSizeGb
@@ -5360,6 +5480,10 @@ ${ANDROID_AVD_CONFIG_HELP.map((line) => ` ${line}`).joi
5360
5480
  keys are protected. The emulator may normalize a valid
5361
5481
  value. These overrides apply only to a newly created
5362
5482
  AVD; existing and recovered AVDs are never rewritten.
5483
+ Unless these settings set hw.keyboard, every AVD Stim
5484
+ creates gets hw.keyboard=yes, so the emulator takes
5485
+ gRPC key events. The one rewrite: a parked AVD created
5486
+ before that default gets it when a workspace adopts it.
5363
5487
  On displayless Linux, Stim launches with
5364
5488
  -gpu swiftshader_indirect -noaudio; those arguments
5365
5489
  override hw.gpu.enabled, hw.gpu.mode, hw.audioInput,
@@ -5543,8 +5667,13 @@ STIM_BAD_ARG. See \`guide lifecycle budget\` for what each limit reclaims.
5543
5667
  THE IOS SIMULATOR APP IS MACHINE-LEVEL
5544
5668
  Top-level \`iosSimulatorApp\` in ~/.stim/config.json selects the macOS app that
5545
5669
  displays Stim's owned local iOS simulator after boot. It is not a project
5546
- setting. Unset or \`"xcode"\` opens the selected Xcode's Device Hub on Xcode 27,
5547
- or Simulator on older Xcode. To use an installed Siniulator instead:
5670
+ setting. Unset, it is \`"stim-desktop"\` while Stim Desktop is installed and
5671
+ \`"xcode"\` otherwise. \`"xcode"\` opens the selected Xcode's Device Hub on Xcode 27,
5672
+ or Simulator on older Xcode. On Xcode 27 (confirmed on 27A266a), quitting
5673
+ Device Hub by default shuts down every booted simulator on the machine,
5674
+ including ones it never opened a window for and ones other workspaces or
5675
+ agents are using; never quit it to free memory or clean up. To use an
5676
+ installed Siniulator instead:
5548
5677
 
5549
5678
  { "iosSimulatorApp": "siniulator" }
5550
5679
 
@@ -5570,9 +5699,10 @@ window behavior.
5570
5699
 
5571
5700
  THE ANDROID EMULATOR APP IS MACHINE-LEVEL
5572
5701
  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:
5702
+ Android emulator that Stim boots on macOS is displayed. Unset, it is
5703
+ \`"stim-desktop"\` while Stim Desktop is installed and \`"emulator"\`
5704
+ otherwise. \`"emulator"\` opens the emulator's own window. To boot it
5705
+ headlessly and show it in Stim Desktop:
5576
5706
 
5577
5707
  { "androidEmulatorApp": "stim-desktop" }
5578
5708
 
@@ -5584,6 +5714,12 @@ current display until it next boots, and physical devices are unaffected.
5584
5714
  An invalid value refuses before boot. On Linux and Windows the setting has
5585
5715
  no effect.
5586
5716
 
5717
+ Stim finds Stim Desktop by its bundle id, dev.stim.desktop, in Launch Services.
5718
+ \`stim settings\` shows that default as \`(default: Stim Desktop installed)\`,
5719
+ \`settings get\` prints it on stderr, and \`--json\` adds
5720
+ \`"defaultReason": "Stim Desktop installed"\`. A set value always wins; set
5721
+ \`"xcode"\` or \`"emulator"\` to keep the device windows.
5722
+
5587
5723
  THE DEVICE POOL BOUNDS ARE MACHINE-LEVEL TOO
5588
5724
  \`pool.iosParkedMax\` caps how many parked simulators \`worktree remove\` may
5589
5725
  leave behind for a later workspace to adopt. It is machine-level for the same
@@ -5614,6 +5750,21 @@ test suites and the end-to-end harness use one -- and a scoped config must not
5614
5750
  leave simulators on the machine it cannot account for. A redirected home that
5615
5751
  wants a pool says so with the variable.
5616
5752
 
5753
+ THE GC WORKTREE GRACE PERIOD IS MACHINE-LEVEL
5754
+ \`gc.worktreeGraceMinutes\` is how long \`gc --delete\` waits before it removes
5755
+ a merged or idle linked worktree. The clock starts at the worktree's latest
5756
+ activity: a write to its git index, HEAD or HEAD reflog, its Stim workspace
5757
+ state or logs, or the merge of its branch into the default branch.
5758
+
5759
+ {
5760
+ "gc": { "worktreeGraceMinutes": 120 }
5761
+ }
5762
+
5763
+ in ~/.stim/config.json, or STIM_GC_WORKTREE_GRACE_MINUTES in the environment,
5764
+ which overrides the file. Absent means 120. \`0\` removes a finished worktree at
5765
+ once. A value that is not a whole number 0 or more is warned about by \`gc\`,
5766
+ which then uses 120. See \`guide cleanup\` for what else keeps a worktree.
5767
+
5617
5768
  STIM NEEDS NO PROJECT CHANGES TO RUN
5618
5769
  Nothing above is required to use Stim. The performance caches that used to
5619
5770
  be setup steps are supplied by Stim on the command lines it composes itself:
@@ -1,5 +1,5 @@
1
- import { f as getProject, u as getConfigDir, w as upsertProject } from "./config-BEq0Qw_a.mjs";
2
- import { n as appProjectProblem } from "./project-BXZzOABt.mjs";
1
+ import { T as upsertProject, d as getConfigDir, p as getProject } from "./config-0jCcMM0E.mjs";
2
+ import { n as appProjectProblem } from "./project-B8rbutVC.mjs";
3
3
  import { t as compareStimVersions } from "./stim-installations-CINXy_su.mjs";
4
4
  import { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
5
5
  import { join } from "node:path";
@@ -1,10 +1,10 @@
1
- import { H as projectDeviceSlots } from "./config-BEq0Qw_a.mjs";
2
- import { m as readWorkspaceState } from "./metro-BWLOJ_Wr.mjs";
3
- import { o as formatLongDuration } from "./command-output-D5z2_bcF.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";
1
+ import { U as projectDeviceSlots } from "./config-0jCcMM0E.mjs";
2
+ import { m as readWorkspaceState } from "./metro-Dzo30hvJ.mjs";
3
+ import { o as formatLongDuration } from "./command-output-BWCj5Vh-.mjs";
4
+ import { n as createActivityReader, r as idleForMs } from "./activity-CCZJs__P.mjs";
5
+ import { L as ownedAvdSerialResolver } from "./android-75Sk2rIR.mjs";
6
+ import { d as teardownOwnedAvd, f as teardownOwnedIosSim } from "./ownership-B8d4kXBx.mjs";
7
+ import { r as activeBuildState, s as parseActiveBuild, t as ACTIVE_BUILD_KEY } from "./build-progress-h60GPV27.mjs";
8
8
  import chalk from "chalk";
9
9
  //#region src/commands/gc/idle.ts
10
10
  function findOwnedDeviceActivity({ config, sims, androidSerial, readActivity, deadProjects = [] }) {
@@ -1,10 +1,10 @@
1
- import { f as getProject, k as ownership_claim_exports, u as getConfigDir } from "./config-BEq0Qw_a.mjs";
2
- import { O as workspaceDir, m as readWorkspaceState } from "./metro-BWLOJ_Wr.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
- import { a as formatElapsed } from "./command-output-D5z2_bcF.mjs";
6
- import { h as listBuildLocks } from "./device-lease-D83nqeMX.mjs";
7
- import { n as managedLockHolders, t as resolveSupervisorTarget } from "./ownership-BiojdtAp.mjs";
1
+ import { A as ownership_claim_exports, d as getConfigDir, p as getProject } from "./config-0jCcMM0E.mjs";
2
+ import { O as workspaceDir, m as readWorkspaceState } from "./metro-Dzo30hvJ.mjs";
3
+ import { n as declareSpawnsOn, o as stopDeclaringSpawnsOn } from "./spawn-claims-PT8aQpCa.mjs";
4
+ import { n as workspaceProcessLockError, r as workspaceProcessLockPath, t as withWorkspaceProcessLock } from "./workspace-process-lock-BvvJTfo_.mjs";
5
+ import { a as formatElapsed } from "./command-output-BWCj5Vh-.mjs";
6
+ import { h as listBuildLocks } from "./device-lease-B9LAXIUH.mjs";
7
+ import { n as managedLockHolders, t as resolveSupervisorTarget } from "./ownership-B8d4kXBx.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";
@@ -1,33 +1,33 @@
1
- import { L as deviceSlotFileKey, R as deviceSlotKey, V as parseDeviceSlotOption, W as validateDeviceSlot, f as getProject, k as ownership_claim_exports, l as getConcurrencyLimits, w as upsertProject } from "./config-BEq0Qw_a.mjs";
1
+ import { A as ownership_claim_exports, G as validateDeviceSlot, H as parseDeviceSlotOption, R as deviceSlotFileKey, T as upsertProject, p as getProject, u as getConcurrencyLimits, z as deviceSlotKey } from "./config-0jCcMM0E.mjs";
2
2
  import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
3
3
  import { r as createNdjsonWriter } from "./ndjson-CDY9IkVC.mjs";
4
- import { O as workspaceDir, c as signalProcessTree, h as recordWorkspaceUse, i as pidExists, j as workspaceLogsDir, m as readWorkspaceState$1, s as resolveProjectMetro, y as writeWorkspaceState } from "./metro-BWLOJ_Wr.mjs";
5
- import { D as makeTemporaryDirectory, O as removeTemporaryEntry, s as gitCommonDir, y as repoRoot } from "./worktree-BlizKDpZ.mjs";
6
- import { a as detectIsExpo, i as detectBundleId, n as appProjectProblem, o as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-BXZzOABt.mjs";
7
- import { n as MODE_EXPO, p as writeWorkspaceLaunch, t as MODE_BARE } from "./state-WGdIbi_d.mjs";
8
- import { _ as stepTimer, c as launchErrorReport, g as stepClock, h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-D5z2_bcF.mjs";
9
- import { A as resolveBuild, C as filesystemBuildCapability, D as providerDownloadPath, E as prepareProviderDownloadDir, F as untrackedNativeFiles, O as providerUploadOutcome, P as untrackedMissLine, T as fingerprintProject, _ as waitForBuild, b as buildCacheKey, g as releaseBuildLock, j as storeBuild, k as refingerprintAfterMutation, m as acquireBuildLock, v as waitForSharedBuild, w as fingerprintDiffRecord } from "./device-lease-D83nqeMX.mjs";
10
- import { A as resolveCacheProviderConfig, E as publicUrlSetting, I as tunnelModeSetting, L as unknownSettingKeys, P as settingShapeErrors, S as metroWarmupUrlSetting, U as optimizationBuildProfile, V as artifactCachePolicy, W as resolveOptimizations, _ as iosSigningIdentitySha1SettingError, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, f as iosLanHostSetting, g as iosSigningIdentitySha1Setting, h as iosSigningIdentitySettingError, j as resolveSettings, k as remoteIosSetting, m as iosSigningIdentitySetting, p as iosLanHostSettingError, r as REMOTE_DEVICE_BACKENDS, z as detectProviders } from "./settings-B5oFZEri.mjs";
11
- import { h as POOL_SETTING_REMEDY, y as parkedMaxSetting } from "./ownership-BiojdtAp.mjs";
12
- import { D as parseIosSimulatorApp, f as listIosRuntimes } from "./ios-DArbmwer.mjs";
13
- import { c as startBuildProgress, n as NO_BUILD_PROGRESS } from "./build-progress-CDwogz6R.mjs";
14
- import { a as acquireBuildSlot, s as releaseBuildSlot } from "./in-use-DVhlSoyn.mjs";
15
- import { n as verifyCollectorOwnership } from "./ownership-D2xbLVoz.mjs";
16
- import { A as UPLOAD_TIMEOUT_MS, B as resolveRemote, F as isEasAuthFailureText, I as loadProjectProvider, M as checkEasAuth, N as easAuthNote, O as gateMetroOrigin, P as exitAfterFlush, V as uploadRemote, a as ensureMetroReachable, j as cacheLevel, k as RESOLVE_TIMEOUT_MS, l as remoteIosDeps, n as binOnPath, o as ensureRemoteBootOwned, r as bundleEntryPoint, u as resolveRemoteContext, w as ownedSessionName, z as resolveEasCliBin } from "./device-remote-BQZSnnmE.mjs";
17
- import { c as clearOtherUserApps, h as iosAppProcess, m as installIosApp, r as DEFAULT_METRO_PORT, u as devClientUrl, v as launchIosApp } from "./app-install-DHut6JnV.mjs";
18
- import { c as readMetroRecords, d as verifyLaunch, f as verifyReleaseLaunch, i as RELEASE_VERIFY_WAIT_MS, l as unverifiedLaunchLines, n as LAUNCH_FATAL, o as isBundleProof, r as LAUNCH_UNVERIFIED, s as readCollectorRecords, t as LAUNCH_BUNDLING } from "./launch-verify-CuPDGXdr.mjs";
19
- import { c as unknownIosDeviceTypeRefusal, d as easDeviceBuildRemedy, f as isEasBuildFailure, l as unknownIosRuntimeRefusal, m as resolveEasDevelopmentBuild, p as planEasDevelopmentBuild, r as checkDeviceCapacity } from "./simslim-CIR3IYJO.mjs";
20
- import { d as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-D7yB_AsB.mjs";
21
- import { a as lostLine, c as releaseLeaseOnSignal, i as leaseExpiryText, l as runLease, n as DEBUG_VERIFY_STEP_MS, o as lostRefusal, r as acquireRunLease, s as parseDeviceWait, t as selectFromPool, u as waitFlagConflict } from "./device-pool-DHj7cdPy.mjs";
22
- import { C as ensureDevServer, D as sleep, E as launchOutcomeRecord, O as warmMetro, S as clearIosAdoptionPending, T as isPhysicalDeviceRequest, _ as staleNativeDirRefusal, a as refusePlan, c as skippedMissReason, d as schemesFromInfoPlist, g as runPrebuild, h as recordPrebuild, i as printPlan, l as devClientScheme, m as planPrebuild, n as planFlagRefusal, o as explainBuildMiss, p as swapJsBundle, r as planPayload, s as fingerprintErrorMissReason, t as planCachedBuild, u as pickDevClientScheme, v as ensureBooted, w as ensureWorkspaceStorageSafely, y as ensureOwnedDevice } from "./build-plan-CeAYgKAx.mjs";
23
- import { t as budgetGate } from "./budget-De3P2rq_.mjs";
24
- import { f as spawnEntry, s as startDevServer } from "./start-BSsf2tUs.mjs";
25
- import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-BAgJaLA4.mjs";
26
- import { a as compilationCacheActivityLine, c as readBundleExecutable, l as readBundleId, p as describeDiagnostic, r as buildIos, s as discoverXcodeProject, t as COMPILATION_CACHE_NOT_RUN, u as resolveScheme } from "./xcode-B5SPD--o.mjs";
27
- import { n as nativeRunCommand, t as launchSlotScope } from "./slot-launch-rggO1Esw.mjs";
28
- import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-UYFSQwRy.mjs";
29
- import { a as iosPoolCandidates, c as listIosDevices, d as verifyIosDeviceReleaseLaunch, i as iosDeviceProcess, l as localNetworkPending, n as installIosDeviceApp, o as iosPoolNoCandidatesRefusal, r as iosDeviceBounds, s as isWirelessIosDevice, t as awaitIosDeviceLaunch, u as resolveIosPhysicalDevice } from "./ios-device-CwDZo0X4.mjs";
30
- import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-OF7CD5Dx.mjs";
4
+ import { O as workspaceDir, c as signalProcessTree, h as recordWorkspaceUse, i as pidExists, j as workspaceLogsDir, m as readWorkspaceState$1, s as resolveProjectMetro, y as writeWorkspaceState } from "./metro-Dzo30hvJ.mjs";
5
+ import { D as makeTemporaryDirectory, O as removeTemporaryEntry, s as gitCommonDir, y as repoRoot } from "./worktree-DeBQSVtR.mjs";
6
+ import { i as findProjectRoot, n as appProjectProblem, r as detectIsExpo, t as NO_PROJECT_REFUSAL } from "./project-B8rbutVC.mjs";
7
+ import { m as writeWorkspaceLaunch, n as MODE_EXPO, t as MODE_BARE } from "./state-DcDgzfu3.mjs";
8
+ import { _ as stepTimer, c as launchErrorReport, g as stepClock, h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-BWCj5Vh-.mjs";
9
+ import { A as resolveBuild, C as filesystemBuildCapability, D as providerDownloadPath, E as prepareProviderDownloadDir, F as untrackedNativeFiles, O as providerUploadOutcome, P as untrackedMissLine, T as fingerprintProject, _ as waitForBuild, b as buildCacheKey, g as releaseBuildLock, j as storeBuild, k as refingerprintAfterMutation, m as acquireBuildLock, v as waitForSharedBuild, w as fingerprintDiffRecord } from "./device-lease-B9LAXIUH.mjs";
10
+ import { A as resolveCacheProviderConfig, E as publicUrlSetting, I as tunnelModeSetting, L as unknownSettingKeys, P as settingShapeErrors, S as metroWarmupUrlSetting, U as optimizationBuildProfile, V as artifactCachePolicy, W as resolveOptimizations, _ as iosSigningIdentitySha1SettingError, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, f as iosLanHostSetting, g as iosSigningIdentitySha1Setting, h as iosSigningIdentitySettingError, j as resolveSettings, k as remoteIosSetting, m as iosSigningIdentitySetting, p as iosLanHostSettingError, r as REMOTE_DEVICE_BACKENDS, z as detectProviders } from "./settings-BlyDn2Oz.mjs";
11
+ import { h as POOL_SETTING_REMEDY, y as parkedMaxSetting } from "./ownership-B8d4kXBx.mjs";
12
+ import { D as parseIosSimulatorApp, f as listIosRuntimes } from "./ios-CZWOHTTc.mjs";
13
+ import { c as startBuildProgress, n as NO_BUILD_PROGRESS } from "./build-progress-h60GPV27.mjs";
14
+ import { a as acquireBuildSlot, s as releaseBuildSlot } from "./in-use-D9XYEgFD.mjs";
15
+ import { n as verifyCollectorOwnership } from "./ownership-Dqnrjrio.mjs";
16
+ import { a as easAuthNote, c as loadProjectProvider, f as resolveEasCliBin, i as checkEasAuth, m as uploadRemote, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as resolveRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS } from "./remote-cache-BRsRZru5.mjs";
17
+ import { F as ownedSessionName, S as withNativeBuildRun, a as ensureMetroReachable, l as remoteIosDeps, m as cancelledFailure, n as binOnPath, o as ensureRemoteBootOwned, r as bundleEntryPoint, u as resolveRemoteContext, x as runCancellation, z as gateMetroOrigin } from "./device-remote-C0_o-tJH.mjs";
18
+ import { c as clearOtherUserApps, h as iosAppProcess, m as installIosApp, r as DEFAULT_METRO_PORT, u as devClientUrl, v as launchIosApp } from "./app-install-CsZi0SAT.mjs";
19
+ import { c as readMetroRecords, d as verifyLaunch, f as verifyReleaseLaunch, i as RELEASE_VERIFY_WAIT_MS, l as unverifiedLaunchLines, n as LAUNCH_FATAL, o as isBundleProof, r as LAUNCH_UNVERIFIED, s as readCollectorRecords, t as LAUNCH_BUNDLING } from "./launch-verify-B2oR_kFN.mjs";
20
+ import { c as unknownIosDeviceTypeRefusal, d as easDeviceBuildRemedy, f as isEasBuildFailure, l as unknownIosRuntimeRefusal, m as resolveEasDevelopmentBuild, p as planEasDevelopmentBuild, r as checkDeviceCapacity } from "./simslim-COtEEP7x.mjs";
21
+ import { f as spawnEntry, h as detectBundleId, s as startDevServer } from "./start-BboE1HIS.mjs";
22
+ import { a as lostLine, c as releaseLeaseOnSignal, i as leaseExpiryText, l as runLease, n as DEBUG_VERIFY_STEP_MS, o as lostRefusal, r as acquireRunLease, s as parseDeviceWait, t as selectFromPool, u as waitFlagConflict } from "./device-pool-BoezJd-c.mjs";
23
+ import { C as ensureDevServer, D as sleep, E as launchOutcomeRecord, O as warmMetro, S as clearIosAdoptionPending, T as isPhysicalDeviceRequest, _ as staleNativeDirRefusal, a as refusePlan, c as skippedMissReason, d as schemesFromInfoPlist, g as runPrebuild, h as recordPrebuild, i as printPlan, l as devClientScheme, m as planPrebuild, n as planFlagRefusal, o as explainBuildMiss, p as swapJsBundle, r as planPayload, s as fingerprintErrorMissReason, t as planCachedBuild, u as pickDevClientScheme, v as ensureBooted, w as ensureWorkspaceStorageSafely, y as ensureOwnedDevice } from "./build-plan-CqntbR7b.mjs";
24
+ import { t as budgetGate } from "./budget-DbzW5VTD.mjs";
25
+ import { a as statsProjectKey, i as recordRunStats, n as readRunEstimates, t as createRunRecorder } from "./stats-D8rUTPHd.mjs";
26
+ import { a as compilationCacheActivityLine, c as readBundleExecutable, l as readBundleId, p as describeDiagnostic, r as buildIos, s as discoverXcodeProject, t as COMPILATION_CACHE_NOT_RUN, u as resolveScheme } from "./xcode-BzplpQzc.mjs";
27
+ import { n as nativeRunCommand, t as launchSlotScope } from "./slot-launch-DIACGEfH.mjs";
28
+ import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-CCxjn31V.mjs";
29
+ import { a as iosPoolCandidates, c as listIosDevices, d as verifyIosDeviceReleaseLaunch, i as iosDeviceProcess, l as localNetworkPending, n as installIosDeviceApp, o as iosPoolNoCandidatesRefusal, r as iosDeviceBounds, s as isWirelessIosDevice, t as awaitIosDeviceLaunch, u as resolveIosPhysicalDevice } from "./ios-device-D9cLxVr5.mjs";
30
+ import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-CO-_7UOm.mjs";
31
31
  import { existsSync, mkdirSync, mkdtempSync, openSync, rmSync, writeFileSync } from "node:fs";
32
32
  import { InvalidArgumentError } from "commander";
33
33
  import { LAST_BUILD_KEYS } from "@stim-cli/core/state";
@@ -3023,7 +3023,8 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3023
3023
  abandonCreatedSession: remoteDevice.abandonCreatedSession,
3024
3024
  webPreviewUrl: remoteDevice.webPreviewUrl,
3025
3025
  writeState: d.writeWorkspaceState,
3026
- register: registerProject
3026
+ register: registerProject,
3027
+ notice: (line) => note(chalk.dim(phaseLine("lock", line)))
3027
3028
  }) : boot()).then((result) => {
3028
3029
  bootDuration = bootTimer();
3029
3030
  return result;
@@ -1,9 +1,10 @@
1
- import { g as loadConfig$1 } from "./config-BEq0Qw_a.mjs";
1
+ import { _ as loadConfig$1 } from "./config-0jCcMM0E.mjs";
2
2
  import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
- import { X as forgetCreatedDevice, Y as isStimOwnedSim, Z as recordCreatedDevice } from "./android-C4zG2Tuc.mjs";
4
+ import { t as settingDefault } from "./stim-desktop-D0xhpZt8.mjs";
5
+ import { $ as forgetCreatedDevice, Q as isStimOwnedSim, et as recordCreatedDevice } from "./android-75Sk2rIR.mjs";
5
6
  import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
6
- import { IOS_SIMULATOR_APPS } from "@stim-cli/core/state";
7
+ import { IOS_SIMULATOR_APPS, settingDefinition } from "@stim-cli/core/state";
7
8
  import { dirname, join, resolve } from "node:path";
8
9
  import { tmpdir } from "node:os";
9
10
  //#region src/host-memory.ts
@@ -31,40 +32,43 @@ const OPEN_OPTIONS = {
31
32
  killSignal: "SIGKILL"
32
33
  };
33
34
  function parseIosSimulatorApp(value, source = "iosSimulatorApp in machine config") {
34
- if (value === void 0) return "xcode";
35
35
  if (IOS_SIMULATOR_APPS.includes(value)) return value;
36
36
  const error = /* @__PURE__ */ new Error(`Invalid ${source}. Use "xcode", "siniulator", or "stim-desktop".`);
37
37
  Object.assign(error, { code: "STIM_BAD_ARG" });
38
38
  throw error;
39
39
  }
40
40
  function configuredIosSimulatorViewer(override) {
41
- const app = override ?? parseIosSimulatorApp(loadConfig$1()?.iosSimulatorApp);
41
+ const configured = loadConfig$1()?.iosSimulatorApp;
42
+ const chosen = override ?? (configured === void 0 ? void 0 : parseIosSimulatorApp(configured));
43
+ return { open: (udid) => openSimulator(chosen ?? settingDefault(settingDefinition("iosSimulatorApp")).value, udid) };
44
+ }
45
+ function openSimulator(app, udid) {
42
46
  const exec = getExecutor();
43
- if (app === "stim-desktop") return { open: (udid) => {
47
+ if (app === "stim-desktop") {
44
48
  exec.runFileQuiet("open", [
45
49
  "-g",
46
50
  "-a",
47
51
  "Stim",
48
52
  `stim-desktop://open?udid=${udid}`
49
53
  ], OPEN_OPTIONS);
50
- } };
51
- if (app === "siniulator") return { open: (udid) => {
54
+ return;
55
+ }
56
+ if (app === "siniulator") {
52
57
  exec.runFileQuiet("open", [
53
58
  "-a",
54
59
  "Siniulator",
55
60
  `siniulator://open?udid=${udid}`
56
61
  ], OPEN_OPTIONS);
57
- } };
58
- return { open: (udid) => {
59
- const simctlPath = exec.runFileQuiet("xcrun", ["--find", "simctl"], OPEN_OPTIONS);
60
- const deviceHubApp = simctlPath ? resolve(dirname(simctlPath), "..", "..", "..", "Applications", "DeviceHub.app") : null;
61
- const args = deviceHubApp && existsSync(deviceHubApp) ? [
62
- "-a",
63
- deviceHubApp,
64
- `devices://device/open?id=${udid}`
65
- ] : ["-a", "Simulator"];
66
- exec.runFileQuiet("open", args, OPEN_OPTIONS);
67
- } };
62
+ return;
63
+ }
64
+ const simctlPath = exec.runFileQuiet("xcrun", ["--find", "simctl"], OPEN_OPTIONS);
65
+ const deviceHubApp = simctlPath ? resolve(dirname(simctlPath), "..", "..", "..", "Applications", "DeviceHub.app") : null;
66
+ const args = deviceHubApp && existsSync(deviceHubApp) ? [
67
+ "-a",
68
+ deviceHubApp,
69
+ `devices://device/open?id=${udid}`
70
+ ] : ["-a", "Simulator"];
71
+ exec.runFileQuiet("open", args, OPEN_OPTIONS);
68
72
  }
69
73
  //#endregion
70
74
  //#region src/devices/ios.ts
@@ -1,6 +1,6 @@
1
1
  import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
2
2
  import { n as TOOL_ERROR_PREFIX } from "./ios-device-BiOsSVzd.mjs";
3
- import { i as INSTALL_ERROR } from "./app-install-DHut6JnV.mjs";
3
+ import { i as INSTALL_ERROR } from "./app-install-CsZi0SAT.mjs";
4
4
  import { mkdtempSync, readFileSync, rmSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
  import { tmpdir } from "node:os";