stim 1.27.0 → 1.28.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 (137) hide show
  1. package/dist/{acquire-artifact-BKN2Yuhg.mjs → acquire-artifact-CKByBnTD.mjs} +1 -1
  2. package/dist/{act-ROviTF_t.mjs → act-8iswyfRa.mjs} +36 -18
  3. package/dist/{activity-Cd-ysFes.mjs → activity-DRMg4_mD.mjs} +3 -3
  4. package/dist/{agent-device-usage-output-C5nCKWp9.mjs → agent-device-usage-output-tE90fDdo.mjs} +3 -3
  5. package/dist/{android-Cd6w7_qw.mjs → android-CHmSU4B4.mjs} +40 -37
  6. package/dist/{android-DriNoAVy.mjs → android-CsPs-7Mg.mjs} +3 -3
  7. package/dist/{android-Deb9X3_Y.mjs → android-D577ApKG.mjs} +1 -1
  8. package/dist/{android--HBgpvpW.mjs → android-YWCbmkVK.mjs} +5 -5
  9. package/dist/{android-cas-D5e6ecUg.mjs → android-cas-_aDifWW0.mjs} +2 -2
  10. package/dist/api.d.mts +1 -1
  11. package/dist/api.mjs +24 -24
  12. package/dist/{apk-signed-tail-BHQHx3Rm.mjs → apk-signed-tail-CQbwM0qO.mjs} +2 -2
  13. package/dist/{artifact-faemIZv5.mjs → artifact-DYtHjxsn.mjs} +12 -12
  14. package/dist/{artifact-0AGJYB9O.mjs → artifact-bFkfD3vf.mjs} +12 -12
  15. package/dist/{auto-placement-z-H5pJza.mjs → auto-placement-BVqs8AJi.mjs} +7 -7
  16. package/dist/{browser-web-slD8AvLp.mjs → browser-web-BUaLcafY.mjs} +10 -10
  17. package/dist/{build-hS0QyFlQ.mjs → build-cQURy_KW.mjs} +20 -20
  18. package/dist/{build-cache-gBJ-WKzA.mjs → build-cache-CZULpXVl.mjs} +3 -3
  19. package/dist/{build-plan-CBqYbzYM.mjs → build-plan-CxoYfxsc.mjs} +6 -6
  20. package/dist/{ccache-BWTze1Ls.mjs → ccache-Bm_A1xX9.mjs} +15 -14
  21. package/dist/{cli-ftXDLto1.mjs → cli-CpbaLDa7.mjs} +17 -17
  22. package/dist/cli.mjs +1 -1
  23. package/dist/{client-xsdxrhWA.mjs → client-YxCer6ab.mjs} +39 -6
  24. package/dist/collector-run.mjs +3 -3
  25. package/dist/{command-output-Dj-WT4BP.mjs → command-output-C8R1KIvi.mjs} +1 -1
  26. package/dist/{dependencies-BGokZ-Ng.mjs → dependencies-DKeMzwXY.mjs} +35 -35
  27. package/dist/{dependency-state-C3OtgG94.mjs → dependency-state-CojA2o0t.mjs} +1 -1
  28. package/dist/{dev-client-BMca82xo.mjs → dev-client-D-BW5uiq.mjs} +2 -2
  29. package/dist/{device-tM41-TUq.mjs → device-CgXfbcz5.mjs} +11 -11
  30. package/dist/{device-capacity-6LP7QsaA.mjs → device-capacity-Cd8lMSn3.mjs} +85 -17
  31. package/dist/{device-BJm0irrq.mjs → device-eeK95Lir.mjs} +13 -13
  32. package/dist/device-host-worker.mjs +13 -11
  33. package/dist/{device-ios-534c14fz.mjs → device-ios-Cc9ulihb.mjs} +7 -7
  34. package/dist/{device-lease-run-DwsGfjUN.mjs → device-lease-run-Mtzp4THX.mjs} +3 -3
  35. package/dist/{device-pool-BnQqvs6o.mjs → device-pool-eRz6DtCg.mjs} +2 -2
  36. package/dist/{doctor-DyqE9n1J.mjs → doctor-Bz_ouYAW.mjs} +12 -12
  37. package/dist/{doctor-Dbx1ZpD2.mjs → doctor-C2QyhejJ.mjs} +1 -1
  38. package/dist/doctor-fingerprint.mjs +1 -1
  39. package/dist/{doctor-watchman-CxDbyrrt.mjs → doctor-watchman-BTW82PDC.mjs} +3 -3
  40. package/dist/{doctor-F-3VUUyN.mjs → doctor-xf7ht-5n.mjs} +17 -17
  41. package/dist/{eas-build-CjNSWmjo.mjs → eas-build-Dm6q68QY.mjs} +2 -2
  42. package/dist/{eas-fallback-9fqb46kW.mjs → eas-fallback-DajNpxf-.mjs} +3 -3
  43. package/dist/{eas-session-ledger-DrP4OuuM.mjs → eas-session-ledger-CBFo_Uo1.mjs} +35 -6
  44. package/dist/{error-diagnostics-snej9k4j.mjs → error-diagnostics-D1QfyJzQ.mjs} +7 -7
  45. package/dist/{gc-CGZ1Yg88.mjs → gc-DM5oMm-J.mjs} +17 -16
  46. package/dist/{gc-BRwAY3qT.mjs → gc-PLFwb0k4.mjs} +2 -2
  47. package/dist/{guide-_rfEh_zM.mjs → guide-C4I46XAk.mjs} +106 -42
  48. package/dist/{hosted-android-BMKzUNnY.mjs → hosted-android-DlaKLbW0.mjs} +5 -6
  49. package/dist/{hosted-client-D7Pk_Oo1.mjs → hosted-client-DDRm9hPJ.mjs} +43 -16
  50. package/dist/{hosted-logs-B1gqQuva.mjs → hosted-logs-bSebOKbz.mjs} +5 -5
  51. package/dist/{hosted-logs-sync-Dg3qrZmV.mjs → hosted-logs-sync-B0c53W_c.mjs} +5 -5
  52. package/dist/{hosted-macos-B9w4H8hc.mjs → hosted-macos-B7-8Pv4H.mjs} +5 -5
  53. package/dist/{hosted-native-CdgaiuyP.mjs → hosted-native-CDe33CSr.mjs} +11 -8
  54. package/dist/{idle-shutdown-Cbvo5KEh.mjs → idle-shutdown-CQ0QwU9J.mjs} +5 -5
  55. package/dist/{ios-E26qSpkb.mjs → ios-B1DYuOjh.mjs} +2 -2
  56. package/dist/{ios-Bk4mWbtS.mjs → ios-B1HvafEG.mjs} +8 -8
  57. package/dist/{ios-device-C_QkIf1Z.mjs → ios-device-B4elVFKi.mjs} +1 -1
  58. package/dist/{ios-project-D8Jcy_br.mjs → ios-project-CR4mZ7CH.mjs} +6 -6
  59. package/dist/{ios-state-BZ03NFgF.mjs → ios-state-BPHqMDdZ.mjs} +1 -1
  60. package/dist/{ios-B5HlVMhQ.mjs → ios-tg4tp3q1.mjs} +30 -28
  61. package/dist/{js-swap-Dg2a945i.mjs → js-swap-CVpSW1fn.mjs} +4 -4
  62. package/dist/{launch-CRyBeNsA.mjs → launch-DoySmhjz.mjs} +17 -17
  63. package/dist/{lightened-BCsdAGj_.mjs → lightened-DFAJgfIk.mjs} +4 -4
  64. package/dist/{logs-aJQb-RDg.mjs → logs-BGsW7iPe.mjs} +6 -6
  65. package/dist/{logs-CC_-ZzEE.mjs → logs-DI5ILkYB.mjs} +4 -4
  66. package/dist/{macos-DlCBhMw5.mjs → macos-Bo9st9Di.mjs} +18 -18
  67. package/dist/{macos-BGmTpnv9.mjs → macos-C12RMJQF.mjs} +1 -1
  68. package/dist/macos-run.mjs +1 -1
  69. package/dist/maintenance-run.mjs +4 -4
  70. package/dist/{metro-CvyD-xwe.mjs → metro-BnhXV2Mj.mjs} +1 -1
  71. package/dist/{metro-gateway-BnHdqMO_.mjs → metro-request-DXyKjVDF.mjs} +25 -46
  72. package/dist/{named-ports-BCyMWA6b.mjs → named-ports-Phoi2POD.mjs} +1 -1
  73. package/dist/{native-android-DlpxCyOP.mjs → native-android-vxgtLD7w.mjs} +14 -14
  74. package/dist/{native-gradle-artifact-inputs-C13qT7R_.mjs → native-gradle-artifact-inputs-BN96IVw8.mjs} +3 -3
  75. package/dist/{native-runtime-DqaIBO5w.mjs → native-runtime-DG4Rodzj.mjs} +6 -6
  76. package/dist/{native-xcode-inputs-B1W8SrxB.mjs → native-xcode-inputs-BKarCoKg.mjs} +2 -2
  77. package/dist/{native-xcode-ios-QPP0Rm68.mjs → native-xcode-ios-8A-efGa5.mjs} +14 -14
  78. package/dist/offload-worker.mjs +18 -18
  79. package/dist/{ownership-Bx-0cku-.mjs → ownership-DJCq48IJ.mjs} +2 -2
  80. package/dist/{phone-reverses-C9yAaKEv.mjs → phone-reverses-BzTa8g1F.mjs} +3 -3
  81. package/dist/{placement-log-BXUbiZM6.mjs → placement-log-Cvhta5ib.mjs} +1 -1
  82. package/dist/{plan-placement-UxnQjv5Z.mjs → plan-placement-WkZdccuN.mjs} +5 -5
  83. package/dist/{ports-uUrghqWN.mjs → ports-UV4mJgyC.mjs} +2 -2
  84. package/dist/{prebuild-BDpToDgR.mjs → prebuild-k8d_tqOq.mjs} +8 -8
  85. package/dist/{project-DYj-HVx6.mjs → project-Sui52ywT.mjs} +14 -14
  86. package/dist/{react-native-android-DDBccgJw.mjs → react-native-android-DANlGGQf.mjs} +21 -21
  87. package/dist/{react-native-build-DaK2IFyP.mjs → react-native-build-jUHnIfZ9.mjs} +6 -6
  88. package/dist/{react-native-doctor-B-Mw6DcR.mjs → react-native-doctor-DCWRjS7K.mjs} +5 -5
  89. package/dist/{react-native-ios-DjYwUF9U.mjs → react-native-ios-BwMsFMXi.mjs} +14 -14
  90. package/dist/{recordings-C20iUZfp.mjs → recordings-iy0mkm7b.mjs} +1 -1
  91. package/dist/{reload-DJBeF_rC.mjs → reload-Bj7QyuDy.mjs} +1 -1
  92. package/dist/{reload-fUdkH2_p.mjs → reload-c_uEyc_X.mjs} +13 -13
  93. package/dist/{remote-y6n99WMW.mjs → remote-DFlpAqdV.mjs} +8 -8
  94. package/dist/{result-CTqBw2Te.mjs → result-BIcXREyC.mjs} +14 -14
  95. package/dist/{run-DaCeNKRm.mjs → run-y2HwyNvg.mjs} +1 -1
  96. package/dist/{selection-Bs8phwhN.mjs → selection-CXgM_VK_.mjs} +2 -2
  97. package/dist/{server-bare-BOh-iZEj.mjs → server-bare-2N4vSRZG.mjs} +1 -1
  98. package/dist/{server-command-8CuA51Cv.mjs → server-command-qneHPcRI.mjs} +4 -4
  99. package/dist/{server-expo-ABQs2XFA.mjs → server-expo-Ccm9zB0o.mjs} +2 -2
  100. package/dist/server-expo-WulkyAwT.mjs +2 -0
  101. package/dist/{settings-BDVI8Ivc.mjs → settings-CY5JZlNN.mjs} +46 -2
  102. package/dist/{settings-CMHhQNwI.mjs → settings-Cfd_Q6ys.mjs} +2 -2
  103. package/dist/{settings-payload-cm60Zhib.mjs → settings-payload-DwQiEMCn.mjs} +2 -2
  104. package/dist/{settings-write-BdNRLlBn.mjs → settings-write-CJpjkeAd.mjs} +3 -3
  105. package/dist/{slot-launch-0l7RqSpr.mjs → slot-launch-BpmanOnk.mjs} +5 -5
  106. package/dist/{stage-F4cAfJGi.mjs → stage-CmugrSG5.mjs} +1 -1
  107. package/dist/{start-DcqnF9p8.mjs → start-CHH3zgIU.mjs} +1 -1
  108. package/dist/{start-DrPwER_2.mjs → start-DYLk6GXn.mjs} +8 -8
  109. package/dist/{state-BX1y5syV.mjs → state-B2QJbDwz.mjs} +2 -2
  110. package/dist/{state-CZxLyetD.mjs → state-BXC1Lfxw.mjs} +1 -1
  111. package/dist/{stats-GxuCbles.mjs → stats-DxKqhcGp.mjs} +3 -3
  112. package/dist/{status-BfnK9pUd.mjs → status-BHCkOZga.mjs} +46 -23
  113. package/dist/{status-Bj7ZYvvc.mjs → status-D_Ljc89p.mjs} +1 -1
  114. package/dist/{status-watch-BfabQn03.mjs → status-watch-BmsPqYSU.mjs} +17 -6
  115. package/dist/status-worker.mjs +1 -1
  116. package/dist/{stop-D-EAr25B.mjs → stop-D-dGE9gh.mjs} +14 -14
  117. package/dist/{stop-CH79S3IZ.mjs → stop-DQvE-P76.mjs} +9 -5
  118. package/dist/{stop-x1Yu3He4.mjs → stop-b2pouxAO.mjs} +2 -2
  119. package/dist/supervisor-run.mjs +232 -58
  120. package/dist/{support-CNg_YsOk.mjs → support-04IhBUTT.mjs} +4 -4
  121. package/dist/{support-Be0UeVZU.mjs → support-BtlJKjyQ.mjs} +11 -10
  122. package/dist/{swiftpm-artifact-inputs-uPqYvGBv.mjs → swiftpm-artifact-inputs-Cj2UpmPN.mjs} +1 -1
  123. package/dist/{swiftpm-macos-Ch4YjY_A.mjs → swiftpm-macos-BhF2stxY.mjs} +7 -7
  124. package/dist/{toolchain-CbCG6C5Z.mjs → toolchain-mLA_km-b.mjs} +4 -4
  125. package/dist/{toolchain-JYAOquPg.mjs → toolchain-qktiV8xc.mjs} +1 -1
  126. package/dist/{warm-progress-C0RsbngN.mjs → warm-progress-B0Vpuvpl.mjs} +3 -3
  127. package/dist/{web-Cq_AQ4DK.mjs → web-BYmK0TjL.mjs} +6 -6
  128. package/dist/web-CrVLVQZY.mjs +2 -0
  129. package/dist/web-run.mjs +4 -4
  130. package/dist/{workspace-state-BjqdjnJR.mjs → workspace-state-kIZrdlSg.mjs} +1 -1
  131. package/dist/{workspaces-DFbj07jp.mjs → workspaces-CmOcceDN.mjs} +105 -25
  132. package/dist/{worktree-COAJ3-OD.mjs → worktree-2dk5edza.mjs} +23 -44
  133. package/dist/worktree-nliAoHxB.mjs +2 -0
  134. package/package.json +7 -7
  135. package/dist/server-expo-Ba_Y21vB.mjs +0 -2
  136. package/dist/web-Je6abcpz.mjs +0 -2
  137. package/dist/worktree-JGUd_53L.mjs +0 -2
@@ -1,8 +1,8 @@
1
- import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-BDVI8Ivc.mjs";
2
- import { i as findProjectRoot$1 } from "./project-DYj-HVx6.mjs";
3
- import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-DrP4OuuM.mjs";
4
- import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-CxDbyrrt.mjs";
5
- import "./status-watch-BfabQn03.mjs";
1
+ import { t as ANDROID_AVD_CONFIG_HELP } from "./settings-CY5JZlNN.mjs";
2
+ import { i as findProjectRoot$1 } from "./project-Sui52ywT.mjs";
3
+ import { h as RECENT_LAUNCH_MS } from "./eas-session-ledger-CBFo_Uo1.mjs";
4
+ import { o as guideStatus, t as WATCHMAN_NESTED_WORKTREES } from "./doctor-watchman-BTW82PDC.mjs";
5
+ import "./status-watch-BmsPqYSU.mjs";
6
6
  import { SETTINGS, SETTINGS_SCHEMA_URL, TUTORIAL_VERSION } from "@stim-cli/core/state";
7
7
  import chalk from "chalk";
8
8
  //#region src/guide/agent.ts
@@ -1834,8 +1834,8 @@ RULES
1834
1834
  reason is null for an entry --delete acts on, and otherwise a stable code
1835
1835
  to branch on; detail is the text line, for the user. Never parse detail.
1836
1836
  A linked worktree's detail is never null.
1837
- workspaceBuildOutputs unresolved | in-use | last-use-unknown |
1838
- recently-used
1837
+ workspaceBuildOutputs unresolved | locked | lock-unknown | in-use |
1838
+ last-use-unknown | recently-used
1839
1839
  workspaceLogs unresolved | in-use | collector
1840
1840
  recordings unresolved | retained | recently-recorded
1841
1841
  memory in-use | busy | unknown | build-running |
@@ -2480,7 +2480,35 @@ RULES
2480
2480
 
2481
2481
  capacity.committedMb sums memoryMb; in a \`status --watch --json\` line each
2482
2482
  figure, including an environment's memoryMb, is held on its own (see
2483
- \`guide lifecycle\`), so the sums can differ from what they sum. The memory budget plans before a boot
2483
+ \`guide lifecycle\`), so the sums can differ from what they sum.
2484
+
2485
+ capacity.load is always present. capacity.builds is present only while
2486
+ concurrency.maxBuilds is set, and capacity.devices only while
2487
+ concurrency.maxDevices is set (see \`guide lifecycle concurrency\`):
2488
+
2489
+ load { cpus, loadPerCore, busyAt, limit, state }. loadPerCore is the
2490
+ 5-minute load average divided by cpus, to one decimal. busyAt is
2491
+ server.maxLoadPerCore (\`guide settings\`). state is free under
2492
+ busyAt, busy at or over it, where automatic placement prefers
2493
+ another machine, or holding at or over limit. limit is null
2494
+ because no setting sets it yet, so state is never holding.
2495
+
2496
+ builds { max, inUse, holders: [{ slot, workspace, client, since,
2497
+ unresolved? }] }. inUse counts the slots below max that a new
2498
+ build cannot take. workspace is the root of the local build in
2499
+ the slot; client is the device id of the client whose offloaded
2500
+ build this machine runs in it. An unresolved slot has a claim
2501
+ whose holder Stim cannot identify; both are null, and the slot
2502
+ stays in use until that claim is removed.
2503
+ devices { max, inUse, unknown?, holders: [{ platform, label, workspace,
2504
+ slot, booting? }] }, the owned devices the cap counts: booted or
2505
+ booting stim simulators, owned emulators adb lists, and boots in
2506
+ progress. label is the label of the workspace that records the
2507
+ device, with its device slot; for a device no workspace records,
2508
+ label is its name and workspace and slot are null. inUse is null
2509
+ and unknown says why when the devices could not be listed.
2510
+
2511
+ The memory budget plans before a boot
2484
2512
  and always uses the estimate. What is using CPU and memory now is the
2485
2513
  top-level machine section:
2486
2514
 
@@ -2779,19 +2807,19 @@ comes from \`start --remote\`, eas/proxy in \`ios.remote\`, or \`android.remote\
2779
2807
 
2780
2808
  HOSTED IOS METRO
2781
2809
  ios --remote <machine> keeps Metro local and needs no start --remote.
2782
- The supervisor watches private gateway requests in workspace state, binds
2783
- only this machine's Tailscale address and accepts only the pinned hosting peer
2784
- with a per-session secret. The host's bridge is loopback-only. For an Expo
2785
- dev client it listens on this machine's Metro port, which the dev server
2810
+ The supervisor watches hosted Metro requests in workspace state and keeps a
2811
+ few authenticated connections open to the host for each session. The host
2812
+ pairs one with each connection the device makes to its loopback-only bridge,
2813
+ and the supervisor forwards it to this Metro, so the host never connects back
2814
+ to this machine and a shared or ACL-restricted host works. For an Expo
2815
+ dev client the bridge listens on this machine's Metro port, which the dev server
2786
2816
  writes into the manifest. ios --remote starts Metro on a port free on both
2787
2817
  Macs; a running Metro or a pin on a port the host uses refuses the run before
2788
- the build. Port and secret
2789
- stay in 0600 workspace state and never appear in status, JSON or logs.
2790
- metro.tunnel and metro.publicUrl are ignored. Supervisor restart recreates
2791
- the recorded gateway; stop or a stopped hosted session closes it. A recorded
2818
+ the build. metro.tunnel and metro.publicUrl are ignored. Supervisor restart
2819
+ reopens the recorded links; stop or a stopped hosted session closes them. A recorded
2792
2820
  hosted session prevents Metro idle stop. Release runs skip the bridge.
2793
- Hosted Debug runs require the supervisor's private gateway support before
2794
- reservation. --no-metro-check refuses; restart a missing or older supervisor
2821
+ Hosted Debug runs require a supervisor and a stim-server that support these
2822
+ links before reservation. --no-metro-check refuses; restart a missing or older supervisor
2795
2823
  with stim stop; stim start.
2796
2824
  Native iOS and Android logs are pulled from the host by stim logs, including --errors;
2797
2825
  JavaScript logs still arrive through Metro. Stop pulls native logs before
@@ -2853,8 +2881,8 @@ BUNDLE WARMUP
2853
2881
  device logs may prove a request, but bundle completion may stay unverified.
2854
2882
 
2855
2883
  HOSTED ANDROID
2856
- android --remote <machine> keeps Metro here through the private tailnet
2857
- gateway. The host reverses the client Metro port into its loopback bridge
2884
+ android --remote <machine> keeps Metro here through the same client-opened
2885
+ links as hosted iOS. The host reverses the client Metro port into its loopback bridge
2858
2886
  on the exact owned emulator. Each run and reload restores that reverse;
2859
2887
  no adb command for the host serial runs here. metro.tunnel and metro.publicUrl
2860
2888
  are ignored. See guide lifecycle hosted-android.
@@ -3487,7 +3515,15 @@ msg and
3487
3515
  failure failed or cancelled runs: { code, message, remedy, phase }
3488
3516
  device { name, runtime? } of the simulator, emulator or device;
3489
3517
  never its serial or UDID
3518
+ loadPerCore this machine's 5-minute load average per CPU when the run
3519
+ started, to one decimal
3520
+ boot { startedAt, loadPerCore } of the run's first owned
3521
+ simulator or emulator boot: epoch milliseconds when it
3522
+ started, once any concurrency.maxDevices wait was over,
3523
+ and the load per core then. Absent when the run booted
3524
+ nothing.
3490
3525
  stimVersion the stim that ran the build
3526
+ Records written before these fields existed lack loadPerCore and boot.
3491
3527
  A run that stopped before it had an app to build (a refused flag, a missing
3492
3528
  project) writes no record. Writing the record never changes the run's result.
3493
3529
 
@@ -5661,7 +5697,7 @@ STIM_SUPERVISOR_EXITED, ...) before any build work. Release builds and
5661
5697
  \`--no-metro-check\` neither check nor start the dev server; hosted Debug iOS
5662
5698
  refuses --no-metro-check with STIM_BAD_ARG. \`--remote\`
5663
5699
  with eas or proxy starts it the way \`stim start --remote\` does. A named
5664
- hosting Mac keeps Metro local through a private bridge; see hosted-ios. Step 2 remains useful to warm
5700
+ hosting Mac keeps Metro local through links this machine opens; see hosted-ios. Step 2 remains useful to warm
5665
5701
  Metro while other work happens.
5666
5702
 
5667
5703
  Each time Stim boots an owned local simulator or emulator, it mutes it: iOS
@@ -5841,7 +5877,8 @@ WAITING FOR A CHANGE
5841
5877
  status payload per line: one at once, then one each time the payload
5842
5878
  changes, never two identical ones in a row. In a watch line, a usage
5843
5879
  figure repeats its value in the previous line until it moves by a step: an owner's cpuPercent 5 points, an
5844
- owner's or environment's memoryMb and capacity.committedMb 16 MB. An owner's row
5880
+ owner's or environment's memoryMb and capacity.committedMb 16 MB, and
5881
+ capacity.load as a whole until its loadPerCore moves 1 per core or its state changes. An owner's row
5845
5882
  changes as a whole, so its residentMb and processes update with it. A change
5846
5883
  in only a bookkeeping timestamp prints no line: each pullRequest.checkedAt,
5847
5884
  maintenance.lastChecks, maintenance.lastPass.startedAt and durationMs, and
@@ -6087,8 +6124,8 @@ soon as it exists, then delivers one App.apk. The emulator boots headless;
6087
6124
  androidEmulatorApp is ignored with a note.
6088
6125
 
6089
6126
  React Native Debug requires the local Metro supervisor. metro.publicUrl and metro.tunnel
6090
- are ignored with a note. A private tailnet gateway reaches the host loopback
6091
- bridge; the host reverses the client's Metro port into that bridge on its exact
6127
+ are ignored with a note. Connections this machine opens to the host carry each
6128
+ device connection from the host loopback bridge to local Metro; the host reverses the client's Metro port into that bridge on its exact
6092
6129
  ledger-owned serial and sets debug_http_host to localhost:<clientMetroPort>.
6093
6130
  Each run and stim reload android restores the reverse, including after a host
6094
6131
  adb server restart. Reload broadcasts through the local Metro and never runs
@@ -6111,7 +6148,7 @@ session probe states; a conflicting local emulator remains visible with a
6111
6148
  warning. A recorded placement keeps the workspace in use and blocks idle stop.
6112
6149
 
6113
6150
  stop and worktree remove wait for device-host.stop, park the host's eligible owned
6114
- emulator within pool.androidParkedMax (delete otherwise), close the gateway and clear placement. stop --json reports
6151
+ emulator within pool.androidParkedMax (delete otherwise), close the Metro links and clear placement. stop --json reports
6115
6152
  outcomes.device["android:host:<slot>"]. Forbidden or unknown-session also clears
6116
6153
  placement; an unreachable host keeps it and fails cleanup. A clean host restart
6117
6154
  parks eligible devices; a later reserve by the same client adopts a compatible
@@ -6317,9 +6354,10 @@ sessions.
6317
6354
 
6318
6355
 
6319
6356
  Stim builds or fetches before reserving, records the session immediately, then
6320
- uploads the app on every run. React Native and Expo Debug keep Metro here; the supervisor owns a
6321
- private gateway bound to this machine's Tailscale address, pinned to the host peer
6322
- and protected by a per-session secret. The host exposes only a loopback bridge.
6357
+ uploads the app on every run. React Native and Expo Debug keep Metro here; the supervisor keeps
6358
+ authenticated connections open to the host, and the host pairs one with each
6359
+ connection the simulator makes to its loopback-only bridge. The host never
6360
+ connects back to this machine.
6323
6361
  For an Expo dev client the bridge listens on this machine's Metro port, because
6324
6362
  the dev server writes that port into the manifest's bundle URL. When this run
6325
6363
  starts Metro, it asks the host and picks a port free on both Macs, moving the
@@ -6327,8 +6365,8 @@ recorded port if the host uses it. A running Metro or a metro.port pin on a port
6327
6365
  the host uses refuses before the build: run stim stop, then stim ios --remote
6328
6366
  <machine> without stim start, or pin a port free on both Macs.
6329
6367
  No start --remote is needed; metro.tunnel and metro.publicUrl are ignored.
6330
- Debug requires a running supervisor with private gateway support before reserving
6331
- a simulator. --no-metro-check refuses with STIM_BAD_ARG for hosted Debug runs.
6368
+ Debug requires a running supervisor and a host stim-server that support these
6369
+ links before reserving a simulator. --no-metro-check refuses with STIM_BAD_ARG for hosted Debug runs.
6332
6370
  If its supervisor is missing or older, run stim stop; stim start, then retry.
6333
6371
  Non-Debug runs skip Metro. Launch is unverified until this workspace's Metro
6334
6372
  provides bundle evidence, or the host proves a live release process. Native Xcode
@@ -6341,14 +6379,14 @@ hosting Mac, refuses for that slot: run stim stop first.
6341
6379
  Status adds ios.host { machine, session, selected, device: { name, runtime },
6342
6380
  agent, state } per slot. A shutdown local simulator is replaced in status; a
6343
6381
  booted or unknown local simulator stays visible alongside ios.host with a warning.
6344
- The default slot appears only in ios, never in slots[]. No host UDID or gateway secret enters local device state or
6382
+ The default slot appears only in ios, never in slots[]. No host UDID enters local device state or
6345
6383
  status. Ready is normal; stopped has a rerun hint; unknown or unreachable is
6346
6384
  unverified. A clean host server restart stops its sessions and retains eligible
6347
6385
  parked devices. A running session left by a crash stays unknown until explicit
6348
6386
  stop; the restarted server never re-attaches to a booted device.
6349
6387
 
6350
6388
  stop and worktree remove wait for the host to stop, park its eligible owned
6351
- simulator within pool.iosParkedMax (delete otherwise), close the gateway and clear placement. stop --json
6389
+ simulator within pool.iosParkedMax (delete otherwise), close the Metro links and clear placement. stop --json
6352
6390
  reports each hosted slot under outcomes.device["ios:host:<slot>"], retaining
6353
6391
  local device outcomes and successful siblings when another slot fails. Revoked or
6354
6392
  missing sessions clear placement too. An unreachable host retains placement
@@ -8751,8 +8789,8 @@ DISK PRESSURE LEVELS
8751
8789
  gradle-versions, run again after step 5 so a daemon that did not exit
8752
8790
  still keeps them
8753
8791
  A directory is cleared only when it is a real directory inside its
8754
- worktree, git tracks nothing in it, its worktree is not in use, holds no
8755
- lock or build and is not pinned, and, for the node_modules and ios/Pods of
8792
+ worktree, git tracks nothing in it, its worktree is not in use, is not
8793
+ locked with git worktree lock, holds no build lock and is not pinned, and, for the node_modules and ios/Pods of
8756
8794
  level 3, nothing under it, nor the worktree's git index, HEAD or Stim
8757
8795
  state, changed within the short window. A build directory of level 2 also
8758
8796
  stays in a worktree where no Stim workspace has recorded any state; a build
@@ -9729,7 +9767,12 @@ WORKSPACE BUILD OUTPUTS
9729
9767
  detected cache, "Workspace build outputs", with a per-workspace size, last
9730
9768
  use and verdict. Plain \`gc --delete\` lightens every workspace, before
9731
9769
  anything else, by clearing them, and prints the bytes freed per workspace.
9732
- A running dev server, a booted or hosted simulator or emulator and a managed
9770
+ A workspace whose worktree is locked with git worktree lock is never
9771
+ lightened: not its outputs, not its project's build directories, at any
9772
+ disk pressure level, including gc --older-than and the budget, and gc and
9773
+ the maintenance log name the lock. The outputs also stay when git lists
9774
+ nothing for a project inside a git checkout (code lock-unknown). A
9775
+ running dev server, a booted or hosted simulator or emulator and a managed
9733
9776
  tunnel no longer keep them. They stay while the workspace is building (its
9734
9777
  native-run.lock is held, a live or unresolvable build lock or slot names
9735
9778
  it, or its build claim is live), while its macOS app or build runs or cannot
@@ -9768,10 +9811,11 @@ WORKTREE DEPENDENCIES
9768
9811
  Plain \`gc --delete\` also lightens linked worktrees: it deletes the
9769
9812
  node_modules and ios/Pods at the root or a project root of a linked
9770
9813
  worktree that has a Stim workspace, never the source checkout. A worktree
9771
- keeps them while it is in use (its dev server runs, a native run or build
9772
- holds it), while it was used in the last 15 minutes (a git index, HEAD or
9773
- reflog write, a Stim state or log write, or a write at the top of the
9774
- directory), while git tracks a file in them, while a stim-server service
9814
+ locked with git worktree lock keeps them always, so a rollback checkout
9815
+ stays runnable. Otherwise a worktree keeps them while it is in use (its
9816
+ dev server runs, a native run or build holds it), while it was used in
9817
+ the last 15 minutes (a git index, HEAD or reflog write, a Stim state or
9818
+ log write, or a write at the top of the directory), while git tracks a file in them, while a stim-server service
9775
9819
  or the stim on PATH runs from it, while a live process has its command
9776
9820
  line or working directory in it, and when the running processes cannot be
9777
9821
  listed (always on Windows). It also keeps them when \`stim worktree warm\`
@@ -10893,7 +10937,8 @@ the ones it offloaded.
10893
10937
  \`server.maxLoadPerCore\` (default 2) is also the busy threshold for
10894
10938
  automatic iOS, Android and macOS placement. It is the load per core at which a
10895
10939
  machine counts as saturated: each machine applies its own value, and a remote
10896
- machine past it is skipped like a full one.
10940
+ machine past it is skipped like a full one. \`stim status\` shows this machine's
10941
+ load per core against it, as \`capacity.load\` in JSON.
10897
10942
 
10898
10943
  Device, Release and
10899
10944
  \`--remote eas|proxy\` builds, Android builds with the Apple Clang CAS compiler cache,
@@ -11625,7 +11670,10 @@ owned app, including copies opened through LaunchServices (open, agent-device
11625
11670
  open). stim macos, stim stop, stim worktree remove and stim gc --delete stop all
11626
11671
  of them: SIGTERM, up to 5 s, then SIGKILL, and success only once each has
11627
11672
  exited. When an app cannot be verified or does not exit, stop reports
11628
- STIM_MACOS_OWNER_UNVERIFIED or a failure, and removal keeps the workspace.
11673
+ STIM_MACOS_OWNER_UNVERIFIED or a failure, and removal keeps the workspace. For
11674
+ a hosted session the same rule covers every app bundle the session received, so
11675
+ stop and a replacement launch also end a copy that LaunchServices started from
11676
+ an earlier attempt.
11629
11677
  Local stim macos starts the app in the background without activating it or
11630
11678
  changing focus: it sets STIM_BACKGROUND_LAUNCH=1 in the app's environment, which
11631
11679
  Stim Desktop honors, including for reopen events from open -g. An app that
@@ -12015,6 +12063,12 @@ method the relay does not forward, is refused with an agent-device UNAUTHORIZED
12015
12063
  error whose details.reason is STIM_AGENT_REQUEST_REFUSED and whose message names
12016
12064
  the refused command or method; do not retry it.
12017
12065
 
12066
+ longpress, swipe, back and the other gestures are not in that list; the
12067
+ longpress and swipe that stim guide lifecycle lists belong to hosted Android and
12068
+ iOS sessions. click <ref> --button secondary reaches agent-device, but its native
12069
+ macOS backend, which the lease requires, answers UNSUPPORTED_OPERATION, so a
12070
+ hosted macOS app has no right click or context menu yet.
12071
+
12018
12072
  Agents that built, launched and drove test copies on another Mac with an SSH
12019
12073
  script such as mini-desktop.sh use these instead:
12020
12074
 
@@ -12023,7 +12077,8 @@ script such as mini-desktop.sh use these instead:
12023
12077
  launch the same command; the host launches it under the
12024
12078
  session's own home
12025
12079
  shot <out.png> agent-device screenshot --remote-config <path>
12026
- click, rclick, key, type agent-device click, press or type --remote-config <path>
12080
+ click, key, type agent-device click, press or type --remote-config <path>
12081
+ rclick unavailable: secondary click is not supported
12027
12082
  quit stim stop (verified stop; the host frees the slot
12028
12083
  and removes the app's defaults)
12029
12084
  clean stim worktree remove
@@ -12034,6 +12089,15 @@ The host's own owned devices count toward concurrency.maxDevices.
12034
12089
 
12035
12090
  The agent-device rows work once the host's agent field names agent-device.
12036
12091
 
12092
+ On macOS 27, agent-device screenshot of a hosted app can return an image of the
12093
+ window-sharing indicator (66x20 points, 132x40 pixels) instead of the app
12094
+ window. macOS adds that small window to the app while something captures the
12095
+ app, and agent-device picks it as the front window (callstack/agent-device#3961).
12096
+ snapshot -i lists it as an axdialog named "Window" with a
12097
+ WindowSharingSessionButton before the real window. Read the UI with snapshot
12098
+ until agent-device selects the app's main window. Commands that use the front
12099
+ window's frame, such as scroll, may also target the indicator.
12100
+
12037
12101
  DESKTOP DOGFOOD
12038
12102
 
12039
12103
  This repository's apps/desktop/.stim.json selects the full StimDesktop app,
@@ -1,7 +1,7 @@
1
1
  import { c as throwIfCancelled } from "./exec-aULwtNly.mjs";
2
- import { c as call, l as connectHost } from "./hosted-client-D7Pk_Oo1.mjs";
3
- import { i as requestHostedMetro } from "./metro-gateway-BnHdqMO_.mjs";
4
- import { a as stopHostedNative, i as prepareHostedNative, r as placeHostedNative } from "./hosted-native-CdgaiuyP.mjs";
2
+ import { c as call, l as connectHost } from "./hosted-client-DDRm9hPJ.mjs";
3
+ import { i as requestHostedMetro } from "./metro-request-DXyKjVDF.mjs";
4
+ import { a as stopHostedNative, i as prepareHostedNative, r as placeHostedNative } from "./hosted-native-CDe33CSr.mjs";
5
5
  //#region src/device-host/hosted-android.ts
6
6
  async function prepareHostedAndroid(machine, selectors, recorded, mode) {
7
7
  return await prepareHostedNative(machine, selectors, recorded, "android", false, mode);
@@ -19,12 +19,11 @@ async function stopHostedAndroid(root, slot, signal) {
19
19
  async function reopenHostedAndroidMetro(root, placement, clientMetroPort, signal) {
20
20
  const host = await connectHost(placement.machine, void 0, true, signal);
21
21
  try {
22
- const gateway = await requestHostedMetro(root, placement.session, host.credential, signal);
22
+ await requestHostedMetro(root, placement.session, host.credential, signal);
23
23
  throwIfCancelled(signal, "reload");
24
24
  await call(host, "device-host.metro.open", {
25
25
  session: placement.session,
26
- clientMetroPort,
27
- ...gateway
26
+ clientMetroPort
28
27
  });
29
28
  } finally {
30
29
  host.connection.close();
@@ -1,7 +1,7 @@
1
1
  import { c as throwIfCancelled, o as cancellableSleep } from "./exec-aULwtNly.mjs";
2
2
  import { Y as diagnoseConnectFailure, ot as resolveEndpoint } from "./config-Cn94Jc0g.mjs";
3
- import { t as BuildConnection } from "./client-xsdxrhWA.mjs";
4
- import { g as configuredMachines } from "./selection-Bs8phwhN.mjs";
3
+ import { t as BuildConnection } from "./client-YxCer6ab.mjs";
4
+ import { g as configuredMachines } from "./selection-CXgM_VK_.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  import { lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
7
7
  import { join } from "node:path";
@@ -42,6 +42,11 @@ function hostingCredential(machine) {
42
42
  }
43
43
  return credential;
44
44
  }
45
+ function turnedAway(machine, opened) {
46
+ if (opened.code === "server-outdated") return `${machine} runs a stim-server that speaks an older protocol than this Stim. Run stim doctor for the command that updates it there, then retry.`;
47
+ if (opened.refused) return `${machine} refused this machine: ${opened.failure.replace(/\.+$/, "")}. Run stim doctor.`;
48
+ return null;
49
+ }
45
50
  /** Connects only to the stim-server that proves it holds the approved machine's pinned key, and only for `device-host`. */
46
51
  async function connectHost(machine, timeoutMs = CONNECT_TIMEOUT_MS, strict = false, signal) {
47
52
  signal?.throwIfAborted();
@@ -55,8 +60,9 @@ async function connectHost(machine, timeoutMs = CONNECT_TIMEOUT_MS, strict = fal
55
60
  if (signal?.aborted && opened instanceof BuildConnection) opened.close();
56
61
  signal?.throwIfAborted();
57
62
  if (!(opened instanceof BuildConnection)) {
58
- const diagnosis = opened.refused || opened.code === "server-outdated" ? null : await diagnoseConnectFailure(machine, opened, signal);
59
- throw Object.assign(new Error(opened.code === "server-outdated" ? `${machine} runs a stim-server that speaks an older protocol than this Stim. Run stim doctor for the command that updates it there, then retry.` : opened.refused ? `${machine} refused this machine: ${opened.failure.replace(/\.+$/, "")}. Run stim doctor.` : diagnosis?.message ?? `${machine} is unreachable: ${opened.failure}. Run stim doctor to see which layer failed.`), {
63
+ const refusal = turnedAway(machine, opened);
64
+ const diagnosis = refusal === null ? await diagnoseConnectFailure(machine, opened, signal) : null;
65
+ throw Object.assign(new Error(refusal ?? diagnosis?.message ?? `${machine} is unreachable: ${opened.failure}. Run stim doctor to see which layer failed.`), {
60
66
  code: strict ? "STIM_HOSTING_REFUSED" : opened.refused ? "STIM_HOSTING_REFUSED" : opened.code ?? "closed",
61
67
  hostCode: opened.code,
62
68
  ...diagnosis ? { remedy: diagnosis.remedy } : {}
@@ -68,24 +74,45 @@ async function connectHost(machine, timeoutMs = CONNECT_TIMEOUT_MS, strict = fal
68
74
  connection: opened
69
75
  };
70
76
  }
77
+ /**
78
+ * Opens `device-host` connections to `machine` for a caller that retries on its own, as `connectHost` does but without
79
+ * diagnosing failures, resolving the machine's address again only after one fails. Only a failure a retry cannot fix,
80
+ * such as a refusal or a missing approval, carries a `STIM_` code; Tailscale not running or not listing the machine is
81
+ * worth retrying.
82
+ */
83
+ function hostConnector(machine) {
84
+ let resolving;
85
+ return async () => {
86
+ const credential = hostingCredential(machine);
87
+ const pending = resolving ??= resolveEndpoint(credential);
88
+ const target = await pending.catch((error) => {
89
+ if (resolving === pending) resolving = void 0;
90
+ throw error;
91
+ });
92
+ if (typeof target === "string") {
93
+ if (resolving === pending) resolving = void 0;
94
+ throw Object.assign(/* @__PURE__ */ new Error(`Stim does not connect to ${machine}: ${target}.`), { code: "closed" });
95
+ }
96
+ const opened = await BuildConnection.open(target, credential.serverKey, CONNECT_TIMEOUT_MS, "device-host").catch((error) => ({
97
+ failure: error instanceof Error ? error.message : String(error),
98
+ refused: false
99
+ }));
100
+ if (opened instanceof BuildConnection) return opened;
101
+ const refusal = turnedAway(machine, opened);
102
+ if (refusal !== null) throw credentialRefusal(refusal);
103
+ if (resolving === pending) resolving = void 0;
104
+ throw Object.assign(/* @__PURE__ */ new Error(`${machine} is unreachable: ${opened.failure}. Run stim doctor to see which layer failed.`), { code: opened.code ?? "closed" });
105
+ };
106
+ }
71
107
  function requireHostedAppMode(host, platform, mode) {
72
108
  if (mode !== "process") return;
73
109
  if (!host.connection.supports(platform === "ios" ? "hosted-ios-process" : "hosted-android-process")) throw credentialRefusal(`${host.machine} does not support hosted ${platform} process apps.`, `Update stim-server on ${host.machine} to a version supporting hosted ${platform} process apps, then retry.`);
74
110
  }
75
- const gatewaySecrets = /* @__PURE__ */ new WeakMap();
76
- function redactHostText(host, message) {
77
- const secret = gatewaySecrets.get(host);
78
- return secret ? message.replaceAll(secret, "[redacted]") : message;
79
- }
80
111
  async function call(host, method, params, timeoutMs) {
81
- if (method === "device-host.metro.open" && isJsonObject(params) && typeof params.secret === "string") gatewaySecrets.set(host, params.secret);
82
112
  const reply = await host.connection.request(method, params, timeoutMs);
83
- if ("error" in reply) throw Object.assign(/* @__PURE__ */ new Error(`${host.machine} refused ${method}: ${redactHostText(host, reply.error.message)}`), { code: reply.error.code });
113
+ if ("error" in reply) throw Object.assign(/* @__PURE__ */ new Error(`${host.machine} refused ${method}: ${reply.error.message}`), { code: reply.error.code });
84
114
  if (!isJsonObject(reply.result)) throw new Error(`${host.machine} answered ${method} without a result.`);
85
- return typeof reply.result.notice === "string" ? {
86
- ...reply.result,
87
- notice: redactHostText(host, reply.result.notice)
88
- } : reply.result;
115
+ return reply.result;
89
116
  }
90
117
  function hostedSession(host, value, platform = "macos") {
91
118
  if (typeof value.id !== "string" || typeof value.state !== "string" || value.platform !== platform) throw new Error(`${host.machine} answered with a session that is not a hosted ${platform} session.`);
@@ -226,4 +253,4 @@ async function upload(host, ids, missing, content) {
226
253
  }
227
254
  }
228
255
  //#endregion
229
- export { unknownSession as _, SESSION_TIMEOUT_MS as a, call as c, hostedSession as d, probeHostedSession as f, stoppedSession as g, sha256 as h, RESERVE_TIMEOUT_MS as i, connectHost as l, settle as m, OFFER_TIMEOUT_MS as n, attach as o, requireHostedAppMode as p, PREPARE_TIMEOUT_MS as r, bundleManifest as s, INSTALL_TIMEOUT_MS as t, heldNoLonger as u, upload as v };
256
+ export { stoppedSession as _, SESSION_TIMEOUT_MS as a, call as c, hostConnector as d, hostedSession as f, sha256 as g, settle as h, RESERVE_TIMEOUT_MS as i, connectHost as l, requireHostedAppMode as m, OFFER_TIMEOUT_MS as n, attach as o, probeHostedSession as p, PREPARE_TIMEOUT_MS as r, bundleManifest as s, INSTALL_TIMEOUT_MS as t, heldNoLonger as u, unknownSession as v, upload as y };
@@ -1,11 +1,11 @@
1
1
  import { t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { E as workspaceDir, k as workspaceLogsDir$1 } from "./workspace-state-BjqdjnJR.mjs";
2
+ import { E as workspaceDir, k as workspaceLogsDir$1 } from "./workspace-state-kIZrdlSg.mjs";
3
3
  import { B as deviceSlotFileKey, q as validateDeviceSlot, rt as parseMachine$1 } from "./config-Cn94Jc0g.mjs";
4
- import { l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
5
- import { n as macosDir } from "./state-CZxLyetD.mjs";
6
- import { n as androidLogGroups, r as isAndroidCrashText } from "./android-Deb9X3_Y.mjs";
4
+ import { l as phaseLine } from "./command-output-C8R1KIvi.mjs";
5
+ import { n as macosDir } from "./state-BXC1Lfxw.mjs";
6
+ import { n as androidLogGroups, r as isAndroidCrashText } from "./android-D577ApKG.mjs";
7
7
  import { c as readNdjsonGenerations$1, i as createNdjsonWriter } from "./ndjson-Dy2W4vRa.mjs";
8
- import { c as call } from "./hosted-client-D7Pk_Oo1.mjs";
8
+ import { c as call } from "./hosted-client-DDRm9hPJ.mjs";
9
9
  import { mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { dirname, join } from "node:path";
11
11
  import { LOG_ROTATE_BYTES, ambientWrite, withDirLockAsync } from "@stim-cli/core";
@@ -1,8 +1,8 @@
1
- import { n as pullHostedNativeLogs, r as readHostedNativeLogs, t as pullHostedMacosLogs } from "./hosted-logs-B1gqQuva.mjs";
2
- import { l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
3
- import { l as connectHost } from "./hosted-client-D7Pk_Oo1.mjs";
4
- import { n as readHostedIos, t as readHostedAndroid } from "./ios-state-BZ03NFgF.mjs";
5
- import "./hosted-macos-B9w4H8hc.mjs";
1
+ import { n as pullHostedNativeLogs, r as readHostedNativeLogs, t as pullHostedMacosLogs } from "./hosted-logs-bSebOKbz.mjs";
2
+ import { l as phaseLine } from "./command-output-C8R1KIvi.mjs";
3
+ import { l as connectHost } from "./hosted-client-DDRm9hPJ.mjs";
4
+ import { n as readHostedIos, t as readHostedAndroid } from "./ios-state-BPHqMDdZ.mjs";
5
+ import "./hosted-macos-B7-8Pv4H.mjs";
6
6
  import { watch } from "node:fs";
7
7
  import { dirname, relative, resolve, sep } from "node:path";
8
8
  import { ambientWrite, configDir } from "@stim-cli/core";
@@ -1,9 +1,9 @@
1
1
  import { o as cancellableSleep } from "./exec-aULwtNly.mjs";
2
- import { a as agentAccess, i as closeAgentConnection, o as removeAgentAccess, t as pullHostedMacosLogs } from "./hosted-logs-B1gqQuva.mjs";
3
- import { l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
4
- import { n as macosDir } from "./state-CZxLyetD.mjs";
5
- import { ot as runCancellationSignal } from "./toolchain-CbCG6C5Z.mjs";
6
- import { _ as unknownSession, a as SESSION_TIMEOUT_MS, c as call, d as hostedSession, g as stoppedSession, h as sha256, i as RESERVE_TIMEOUT_MS, l as connectHost, m as settle, o as attach, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as upload } from "./hosted-client-D7Pk_Oo1.mjs";
2
+ import { a as agentAccess, i as closeAgentConnection, o as removeAgentAccess, t as pullHostedMacosLogs } from "./hosted-logs-bSebOKbz.mjs";
3
+ import { l as phaseLine } from "./command-output-C8R1KIvi.mjs";
4
+ import { n as macosDir } from "./state-BXC1Lfxw.mjs";
5
+ import { ot as runCancellationSignal } from "./toolchain-mLA_km-b.mjs";
6
+ import { _ as stoppedSession, a as SESSION_TIMEOUT_MS, c as call, f as hostedSession, g as sha256, h as settle, i as RESERVE_TIMEOUT_MS, l as connectHost, o as attach, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as unknownSession, y as upload } from "./hosted-client-DDRm9hPJ.mjs";
7
7
  import { randomUUID } from "node:crypto";
8
8
  import { join } from "node:path";
9
9
  import { ambientContext, ambientWrite } from "@stim-cli/core";
@@ -1,10 +1,10 @@
1
1
  import { o as cancellableSleep, x as withDrainingCancellation } from "./exec-aULwtNly.mjs";
2
- import { E as workspaceDir, l as withWorkspaceStateLockAsync, r as readWorkspaceState$1 } from "./workspace-state-BjqdjnJR.mjs";
3
- import { a as agentAccess, i as closeAgentConnection, n as pullHostedNativeLogs, o as removeAgentAccess } from "./hosted-logs-B1gqQuva.mjs";
4
- import { ot as runCancellationSignal } from "./toolchain-CbCG6C5Z.mjs";
5
- import { _ as unknownSession, a as SESSION_TIMEOUT_MS, c as call, d as hostedSession, g as stoppedSession, h as sha256, i as RESERVE_TIMEOUT_MS, l as connectHost, m as settle, n as OFFER_TIMEOUT_MS, o as attach, p as requireHostedAppMode, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as upload } from "./hosted-client-D7Pk_Oo1.mjs";
6
- import { a as requireHostedMetro, i as requestHostedMetro, n as closeHostedMetro } from "./metro-gateway-BnHdqMO_.mjs";
7
- import { s as writeHostedNative } from "./ios-state-BZ03NFgF.mjs";
2
+ import { E as workspaceDir, l as withWorkspaceStateLockAsync, r as readWorkspaceState$1 } from "./workspace-state-kIZrdlSg.mjs";
3
+ import { a as agentAccess, i as closeAgentConnection, n as pullHostedNativeLogs, o as removeAgentAccess } from "./hosted-logs-bSebOKbz.mjs";
4
+ import { ot as runCancellationSignal } from "./toolchain-mLA_km-b.mjs";
5
+ import { _ as stoppedSession, a as SESSION_TIMEOUT_MS, c as call, f as hostedSession, g as sha256, h as settle, i as RESERVE_TIMEOUT_MS, l as connectHost, m as requireHostedAppMode, n as OFFER_TIMEOUT_MS, o as attach, r as PREPARE_TIMEOUT_MS, s as bundleManifest, t as INSTALL_TIMEOUT_MS, u as heldNoLonger, v as unknownSession, y as upload } from "./hosted-client-DDRm9hPJ.mjs";
6
+ import { a as requireHostedMetro, i as requestHostedMetro, n as closeHostedMetro } from "./metro-request-DXyKjVDF.mjs";
7
+ import { s as writeHostedNative } from "./ios-state-BPHqMDdZ.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { readFileSync } from "node:fs";
10
10
  import { join } from "node:path";
@@ -139,6 +139,10 @@ async function placeHostedNativeOnce(target, { root, slot, bundle, handoff, bund
139
139
  host = await connectHost(host.machine, void 0, true, signal);
140
140
  target.host = host;
141
141
  requireHostedAppMode(host, platform, mode);
142
+ if (mode === "development" && !host.connection.supports("hosted-metro-link")) throw Object.assign(/* @__PURE__ */ new Error(`${host.machine} runs a stim-server that cannot link Metro.`), {
143
+ code: "STIM_HOSTING_REFUSED",
144
+ remedy: `Update stim-server on ${host.machine}, then retry.`
145
+ });
142
146
  let session = (target.session ? await attach(host, target.session.id, void 0, platform) : null) ?? await reserveHostedNative(host, target, {
143
147
  platform,
144
148
  workspace: root,
@@ -174,10 +178,9 @@ async function placeHostedNativeOnce(target, { root, slot, bundle, handoff, bund
174
178
  };
175
179
  await reserved(placement);
176
180
  if (mode === "development") {
177
- const gateway = await metro(root, session.id, host.credential);
181
+ await metro(root, session.id, host.credential);
178
182
  await call(host, "device-host.metro.open", {
179
183
  session: session.id,
180
- ...gateway,
181
184
  ...platform === "android" || devClientScheme ? { clientMetroPort: metroPort } : {}
182
185
  }).catch((error) => {
183
186
  if (platform === "ios" && devClientScheme && error.code === "device-busy") throw Object.assign(error, { remedy: devClientPortRemedy(host.machine) });
@@ -1,11 +1,11 @@
1
- import { k as workspaceLogsDir$1, r as readWorkspaceState$1, s as updateWorkspaceStateAsync } from "./workspace-state-BjqdjnJR.mjs";
1
+ import { k as workspaceLogsDir$1, r as readWorkspaceState$1, s as updateWorkspaceStateAsync } from "./workspace-state-kIZrdlSg.mjs";
2
2
  import { V as deviceSlotKey, _ as loadConfig$1 } from "./config-Cn94Jc0g.mjs";
3
- import { o as formatLongDuration } from "./command-output-Dj-WT4BP.mjs";
3
+ import { o as formatLongDuration } from "./command-output-C8R1KIvi.mjs";
4
4
  import { i as createNdjsonWriter } from "./ndjson-Dy2W4vRa.mjs";
5
- import { L as workspaceBuildInProgress, ft as teardownOwnedIosSim, j as collectOwnedDeviceActivity, ut as teardownOwnedAvd } from "./workspaces-DFbj07jp.mjs";
5
+ import { B as workspaceBuildInProgress, P as collectOwnedDeviceActivity, ht as teardownOwnedIosSim, pt as teardownOwnedAvd } from "./workspaces-CmOcceDN.mjs";
6
6
  import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
7
- import { _ as workspaceDeviceLastUseAt } from "./activity-Cd-ysFes.mjs";
8
- import { d as listAllIosSims } from "./ios-E26qSpkb.mjs";
7
+ import { _ as workspaceDeviceLastUseAt } from "./activity-DRMg4_mD.mjs";
8
+ import { d as listAllIosSims } from "./ios-B1DYuOjh.mjs";
9
9
  import { join } from "node:path";
10
10
  import { LOG_ROTATE_BYTES } from "@stim-cli/core";
11
11
  import { DEVICE_IDLE_SHUTDOWN_KEY, DEVICE_RECLAIM_REASON, readDeviceIdleShutdowns } from "@stim-cli/core/state";
@@ -3,8 +3,8 @@ import { P as formatBytes, _ as loadConfig$1 } from "./config-Cn94Jc0g.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
4
  import { n as runOperationFileQuiet, t as runOperationFile } from "./operation-exec-Dp4FuIGR.mjs";
5
5
  import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-CbWo21kb.mjs";
6
- import { Ct as forgetCreatedDeviceAsync, Et as recordCreatedDeviceAsync, dt as isStimOwnedSim } from "./android-DriNoAVy.mjs";
7
- import { n as signedTailFor } from "./apk-signed-tail-BHQHx3Rm.mjs";
6
+ import { Ct as forgetCreatedDeviceAsync, Et as recordCreatedDeviceAsync, dt as isStimOwnedSim } from "./android-CsPs-7Mg.mjs";
7
+ import { n as signedTailFor } from "./apk-signed-tail-CQbwM0qO.mjs";
8
8
  import { createHash } from "node:crypto";
9
9
  import { closeSync, existsSync, lstatSync, mkdtempSync, openSync, readSync, readdirSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { tmpdir, totalmem } from "node:os";
@@ -1,9 +1,9 @@
1
- import { h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-Dj-WT4BP.mjs";
2
- import { xn as schemesFromInfoPlist, yn as pickDevClientScheme } from "./ccache-BWTze1Ls.mjs";
3
- import { f as podAction, h as resolveDeviceType, i as deviceLabel, m as resolveConfiguration, n as buildLogFile, s as iosConfigurationSetting, t as appNameFromPath, u as isReleaseConfiguration, v as resolveRuntime } from "./support-Be0UeVZU.mjs";
4
- import { n as ensureWorkspaceStorageSafely } from "./native-runtime-DqaIBO5w.mjs";
5
- import { t as devClientScheme } from "./dev-client-BMca82xo.mjs";
6
- import { c as writeLastBuild, i as iosFacts, n as cacheDescription, o as lastBuildRecord } from "./ios-project-D8Jcy_br.mjs";
7
- import { d as replaceCollector, u as collectorEntry } from "./dependencies-BGokZ-Ng.mjs";
8
- import { n as registerIos, r as runIosOperation, t as iosCommand } from "./ios-B5HlVMhQ.mjs";
1
+ import { h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-C8R1KIvi.mjs";
2
+ import { xn as schemesFromInfoPlist, yn as pickDevClientScheme } from "./ccache-Bm_A1xX9.mjs";
3
+ import { f as podAction, h as resolveDeviceType, i as deviceLabel, m as resolveConfiguration, n as buildLogFile, s as iosConfigurationSetting, t as appNameFromPath, u as isReleaseConfiguration, v as resolveRuntime } from "./support-BtlJKjyQ.mjs";
4
+ import { n as ensureWorkspaceStorageSafely } from "./native-runtime-DG4Rodzj.mjs";
5
+ import { t as devClientScheme } from "./dev-client-D-BW5uiq.mjs";
6
+ import { c as writeLastBuild, i as iosFacts, n as cacheDescription, o as lastBuildRecord } from "./ios-project-CR4mZ7CH.mjs";
7
+ import { d as replaceCollector, u as collectorEntry } from "./dependencies-DKeMzwXY.mjs";
8
+ import { n as registerIos, r as runIosOperation, t as iosCommand } from "./ios-tg4tp3q1.mjs";
9
9
  export { appNameFromPath, buildLogFile, cacheDescription, collectorEntry, iosCommand as default, devClientScheme, deviceLabel, ensureWorkspaceStorageSafely, formatDuration, iosConfigurationSetting, iosFacts, isReleaseConfiguration, lastBuildRecord, phaseLine, pickDevClientScheme, podAction, registerIos, replaceCollector, resolveConfiguration, resolveDeviceType, resolveRuntime, runIosOperation, schemesFromInfoPlist, shortHash, shortUdid, writeLastBuild };
@@ -1,5 +1,5 @@
1
1
  import { t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { $t as INSTALL_ERROR, rn as appProcessFromPid } from "./ccache-BWTze1Ls.mjs";
2
+ import { $t as INSTALL_ERROR, rn as appProcessFromPid } from "./ccache-Bm_A1xX9.mjs";
3
3
  import { n as TOOL_ERROR_PREFIX } from "./ios-device-CiBA-er9.mjs";
4
4
  import { mkdtempSync, readFileSync, rmSync } from "node:fs";
5
5
  import { tmpdir } from "node:os";
@@ -1,10 +1,10 @@
1
- import { w as workspaceAgentDeviceDir } from "./workspace-state-BjqdjnJR.mjs";
2
- import { i as formatDuration, l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
1
+ import { w as workspaceAgentDeviceDir } from "./workspace-state-kIZrdlSg.mjs";
2
+ import { i as formatDuration, l as phaseLine } from "./command-output-C8R1KIvi.mjs";
3
3
  import { a as workspaceLinkLine } from "./stim-desktop-CbWo21kb.mjs";
4
- import { Mn as isEasAuthFailureText, On as UPLOAD_TIMEOUT_MS, jn as easAuthNote, kn as cacheLevel } from "./ccache-BWTze1Ls.mjs";
5
- import { q as recordFinishedBuild } from "./workspaces-DFbj07jp.mjs";
6
- import { P as compilationCacheActivityLine, k as COMPILATION_CACHE_NOT_RUN } from "./toolchain-CbCG6C5Z.mjs";
7
- import { i as deviceLabel } from "./support-Be0UeVZU.mjs";
4
+ import { Mn as isEasAuthFailureText, On as UPLOAD_TIMEOUT_MS, jn as easAuthNote, kn as cacheLevel } from "./ccache-Bm_A1xX9.mjs";
5
+ import { X as recordFinishedBuild } from "./workspaces-CmOcceDN.mjs";
6
+ import { P as compilationCacheActivityLine, k as COMPILATION_CACHE_NOT_RUN } from "./toolchain-mLA_km-b.mjs";
7
+ import { i as deviceLabel } from "./support-BtlJKjyQ.mjs";
8
8
  import { buildDiagnostics } from "@stim-cli/core/state";
9
9
  import chalk from "chalk";
10
10
  //#region src/commands/ios/result.ts
@@ -1,4 +1,4 @@
1
- import { l as withWorkspaceStateLockAsync, o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-BjqdjnJR.mjs";
1
+ import { l as withWorkspaceStateLockAsync, o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-kIZrdlSg.mjs";
2
2
  import { HOSTED_METRO_REQUESTS_KEY, hostedMetroRequests, hostedNativeRecords, isJsonObject, parseHostedNativePlacement, unreadableHostedNative } from "@stim-cli/core/state";
3
3
  //#region src/device-host/ios-state.ts
4
4
  function readHostedNative(root, platform, slot) {