stim 1.28.0 → 1.30.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 (155) hide show
  1. package/dist/{acquire-artifact-CKByBnTD.mjs → acquire-artifact-CrZ4rEbI.mjs} +1 -1
  2. package/dist/{act-8iswyfRa.mjs → act-BaKjDWGw.mjs} +479 -29
  3. package/dist/{activity-DRMg4_mD.mjs → activity-BTaUf0tc.mjs} +6 -5
  4. package/dist/{agent-device-usage-output-tE90fDdo.mjs → agent-device-usage-output-DYBpO17K.mjs} +4 -4
  5. package/dist/{android-YWCbmkVK.mjs → android-BCYLwmH6.mjs} +5 -5
  6. package/dist/{android-D577ApKG.mjs → android-BEQUDpOg.mjs} +1 -1
  7. package/dist/{android-CHmSU4B4.mjs → android-BWqdDK6R.mjs} +44 -42
  8. package/dist/{android-CsPs-7Mg.mjs → android-DdKG6lyD.mjs} +44 -35
  9. package/dist/{android-cas-_aDifWW0.mjs → android-cas-BH6K12__.mjs} +4 -4
  10. package/dist/{android-project-DUGMbq28.d.mts → android-project-CCEQyYJK.d.mts} +6 -2
  11. package/dist/api.d.mts +7 -4
  12. package/dist/api.mjs +27 -27
  13. package/dist/{apk-signed-tail-CQbwM0qO.mjs → apk-signed-tail-B8kw4a8K.mjs} +2 -2
  14. package/dist/{artifact-DYtHjxsn.mjs → artifact-DTHXcmQ3.mjs} +12 -12
  15. package/dist/{artifact-bFkfD3vf.mjs → artifact-M6W2l-xh.mjs} +12 -12
  16. package/dist/{auto-placement-BVqs8AJi.mjs → auto-placement-CZaWDmcY.mjs} +10 -10
  17. package/dist/{browser-web-BUaLcafY.mjs → browser-web-JQ7lFej3.mjs} +12 -12
  18. package/dist/{build-cQURy_KW.mjs → build-C2ZWoCmg.mjs} +23 -23
  19. package/dist/{build-cache-CZULpXVl.mjs → build-cache-DlC3owap.mjs} +4 -4
  20. package/dist/{build-plan-CxoYfxsc.mjs → build-plan-J3iRR3gI.mjs} +6 -6
  21. package/dist/{cache-manifest-DEjqGGat.mjs → cache-manifest-evF_zJ9U.mjs} +1 -1
  22. package/dist/cache-manifest.mjs +1 -1
  23. package/dist/{ccache-Bm_A1xX9.mjs → ccache-B8gY50-h.mjs} +18 -18
  24. package/dist/{cli-CpbaLDa7.mjs → cli-xRPXJPtA.mjs} +19 -19
  25. package/dist/cli.mjs +1 -1
  26. package/dist/{client-YxCer6ab.mjs → client-DrHykA24.mjs} +5 -5
  27. package/dist/collector-run.mjs +5 -5
  28. package/dist/{command-output-C8R1KIvi.mjs → command-output-BBW8eWPL.mjs} +1 -1
  29. package/dist/{config-Cn94Jc0g.mjs → config-AbUjIBOQ.mjs} +121 -19
  30. package/dist/{dependencies-DKeMzwXY.mjs → dependencies-vUh9mp5z.mjs} +39 -38
  31. package/dist/{dependency-state-CojA2o0t.mjs → dependency-state-CPKAKCZ8.mjs} +1 -1
  32. package/dist/{dev-client-D-BW5uiq.mjs → dev-client-CASgAOu7.mjs} +2 -2
  33. package/dist/device-ChnO7bR9.mjs +761 -0
  34. package/dist/device-CsIdRXfm.mjs +175 -0
  35. package/dist/{device-CgXfbcz5.mjs → device-android-CcdQqQWg.mjs} +28 -195
  36. package/dist/{device-capacity-Cd8lMSn3.mjs → device-capacity-C5C_jOQd.mjs} +11 -11
  37. package/dist/device-host-worker.mjs +44 -35
  38. package/dist/{device-ios-Cc9ulihb.mjs → device-ios-DbmtPIiw.mjs} +28 -18
  39. package/dist/{device-lease-run-Mtzp4THX.mjs → device-lease-run-Do6zYA7y.mjs} +4 -4
  40. package/dist/{device-pool-eRz6DtCg.mjs → device-pool-CpoYiCGO.mjs} +3 -3
  41. package/dist/{device-eeK95Lir.mjs → device-provision-B5Ms94qY.mjs} +11 -302
  42. package/dist/{doctor-xf7ht-5n.mjs → doctor-CJSB5q-s.mjs} +20 -20
  43. package/dist/{doctor-Bz_ouYAW.mjs → doctor-CLE4AZEI.mjs} +20 -15
  44. package/dist/{doctor-C2QyhejJ.mjs → doctor-CpfbYh3Q.mjs} +1 -1
  45. package/dist/doctor-fingerprint.mjs +1 -1
  46. package/dist/{doctor-watchman-BTW82PDC.mjs → doctor-watchman-D1IyMle9.mjs} +4 -4
  47. package/dist/{eas-build-Dm6q68QY.mjs → eas-build-DIDOHw2P.mjs} +2 -2
  48. package/dist/{eas-fallback-DajNpxf-.mjs → eas-fallback-DVS9oBSc.mjs} +4 -4
  49. package/dist/{eas-session-ledger-CBFo_Uo1.mjs → eas-session-ledger-CW3l-inB.mjs} +5 -5
  50. package/dist/{error-diagnostics-D1QfyJzQ.mjs → error-diagnostics-XJ9eWdtq.mjs} +8 -8
  51. package/dist/{gc-PLFwb0k4.mjs → gc-BVIcxCxE.mjs} +2 -2
  52. package/dist/{gc-DM5oMm-J.mjs → gc-Co7PE36D.mjs} +80 -18
  53. package/dist/{guide-C4I46XAk.mjs → guide-DkepBgHT.mjs} +235 -34
  54. package/dist/{hosted-android-DlaKLbW0.mjs → hosted-android-Du7NxufJ.mjs} +3 -3
  55. package/dist/{hosted-client-DDRm9hPJ.mjs → hosted-client-Cect92SZ.mjs} +3 -3
  56. package/dist/{hosted-logs-bSebOKbz.mjs → hosted-logs-Opcjv1Lr.mjs} +17 -8
  57. package/dist/{hosted-logs-sync-B0c53W_c.mjs → hosted-logs-sync-wsI7N1Hv.mjs} +7 -11
  58. package/dist/{hosted-macos-B7-8Pv4H.mjs → hosted-macos-BP9Kucat.mjs} +5 -5
  59. package/dist/{hosted-native-CDe33CSr.mjs → hosted-native-DmdLSmvu.mjs} +9 -8
  60. package/dist/{idle-shutdown-CQ0QwU9J.mjs → idle-shutdown-BcMN_cLm.mjs} +7 -7
  61. package/dist/{ios-B1HvafEG.mjs → ios-BFkBHuRT.mjs} +8 -8
  62. package/dist/{ios-tg4tp3q1.mjs → ios-CG0IsLtt.mjs} +29 -29
  63. package/dist/{ios-B1DYuOjh.mjs → ios-CXnoVO_z.mjs} +4 -4
  64. package/dist/{ios-device-B4elVFKi.mjs → ios-device-ClSfuu-_.mjs} +1 -1
  65. package/dist/{ios-project-CR4mZ7CH.mjs → ios-project-BM9TbTE7.mjs} +7 -7
  66. package/dist/{ios-state-BPHqMDdZ.mjs → ios-state-Ce_dystM.mjs} +1 -1
  67. package/dist/{js-swap-CVpSW1fn.mjs → js-swap-9Rx-5Nqz.mjs} +4 -4
  68. package/dist/{launch-DoySmhjz.mjs → launch-DvJV1Mx4.mjs} +19 -19
  69. package/dist/{lightened-DFAJgfIk.mjs → lightened-23pqe7LS.mjs} +4 -4
  70. package/dist/{logs-BGsW7iPe.mjs → logs-DJgZlf2K.mjs} +9 -8
  71. package/dist/{logs-DI5ILkYB.mjs → logs-Pkeh3wZk.mjs} +7 -6
  72. package/dist/{macos-Bo9st9Di.mjs → macos-DPvPQadc.mjs} +20 -20
  73. package/dist/{macos-C12RMJQF.mjs → macos-Du07NsOB.mjs} +1 -1
  74. package/dist/macos-run.mjs +1 -1
  75. package/dist/maintenance-run.mjs +13 -9
  76. package/dist/{metro-BnhXV2Mj.mjs → metro-BMQHczcf.mjs} +2 -2
  77. package/dist/{metro-request-DXyKjVDF.mjs → metro-request-BtF7ox53.mjs} +1 -1
  78. package/dist/{named-ports-Phoi2POD.mjs → named-ports-DcktE2Pw.mjs} +2 -2
  79. package/dist/{native-android-vxgtLD7w.mjs → native-android-CBOM1_gB.mjs} +16 -16
  80. package/dist/{native-gradle-artifact-inputs-BN96IVw8.mjs → native-gradle-artifact-inputs-D_iAfPuS.mjs} +3 -3
  81. package/dist/{native-runtime-DG4Rodzj.mjs → native-runtime-D4cTwU0Z.mjs} +6 -6
  82. package/dist/{native-xcode-inputs-BKarCoKg.mjs → native-xcode-inputs-BF-ogSnG.mjs} +2 -2
  83. package/dist/{native-xcode-ios-8A-efGa5.mjs → native-xcode-ios-DwJBfMP6.mjs} +15 -15
  84. package/dist/{ndjson-Dy2W4vRa.mjs → ndjson-CrjIsGzw.mjs} +2 -2
  85. package/dist/offload-worker.d.mts +1 -1
  86. package/dist/offload-worker.mjs +22 -22
  87. package/dist/{ownership-DJCq48IJ.mjs → ownership-Dtz9G5Gl.mjs} +2 -2
  88. package/dist/{phone-reverses-BzTa8g1F.mjs → phone-reverses-CvhhkGMH.mjs} +4 -4
  89. package/dist/{placement-log-Cvhta5ib.mjs → placement-log-CRR_TE1r.mjs} +1 -1
  90. package/dist/{plan-placement-WkZdccuN.mjs → plan-placement-CdLc-pTb.mjs} +6 -6
  91. package/dist/{ports-UV4mJgyC.mjs → ports-g4N_cfyg.mjs} +3 -3
  92. package/dist/{prebuild-k8d_tqOq.mjs → prebuild-DBJMhwSS.mjs} +9 -9
  93. package/dist/{project-Sui52ywT.mjs → project-DPQjnpcI.mjs} +15 -15
  94. package/dist/{react-native-android-DANlGGQf.mjs → react-native-android-idMWOwkX.mjs} +24 -24
  95. package/dist/{react-native-build-jUHnIfZ9.mjs → react-native-build-BSoh4HkH.mjs} +7 -7
  96. package/dist/{react-native-doctor-DCWRjS7K.mjs → react-native-doctor-CYibY8-4.mjs} +9 -8
  97. package/dist/{react-native-ios-BwMsFMXi.mjs → react-native-ios-13KIIOOy.mjs} +16 -15
  98. package/dist/{recordings-iy0mkm7b.mjs → recordings-CHMaF73C.mjs} +1 -1
  99. package/dist/{reload-Bj7QyuDy.mjs → reload-B9DZOjcV.mjs} +1 -1
  100. package/dist/{reload-c_uEyc_X.mjs → reload-BUQI3dSu.mjs} +14 -14
  101. package/dist/{remote-DFlpAqdV.mjs → remote-C-RGHhAP.mjs} +8 -8
  102. package/dist/{result-BIcXREyC.mjs → result-W4HCum4A.mjs} +16 -16
  103. package/dist/{run-y2HwyNvg.mjs → run-BQAmrohh.mjs} +2 -2
  104. package/dist/{selection-CXgM_VK_.mjs → selection-PCMT97XD.mjs} +105 -62
  105. package/dist/{server-bare-2N4vSRZG.mjs → server-bare-CEQdB_F4.mjs} +37 -1
  106. package/dist/{server-command-qneHPcRI.mjs → server-command-oqi3TDy7.mjs} +5 -5
  107. package/dist/server-expo-BUFAq2In.mjs +2 -0
  108. package/dist/{server-expo-Ccm9zB0o.mjs → server-expo-C1K07shx.mjs} +8 -5
  109. package/dist/{settings-Cfd_Q6ys.mjs → settings-CKlMOmhj.mjs} +2 -2
  110. package/dist/{settings-CY5JZlNN.mjs → settings-D776ygML.mjs} +1 -1
  111. package/dist/{settings-Djl-mpjX.mjs → settings-D9LtQaUw.mjs} +2 -1
  112. package/dist/{settings-payload-DwQiEMCn.mjs → settings-payload-CE-NZ6Lq.mjs} +4 -4
  113. package/dist/{settings-write-CJpjkeAd.mjs → settings-write-D7Xwa_-M.mjs} +5 -5
  114. package/dist/settings.schema.json +58 -9
  115. package/dist/{simslim-DCQwzoPy.mjs → simslim-CbpHERcv.mjs} +1 -1
  116. package/dist/{slot-launch-BpmanOnk.mjs → slot-launch-CeIK1iUI.mjs} +6 -6
  117. package/dist/{stage-CmugrSG5.mjs → stage-Blqe6bWb.mjs} +1 -1
  118. package/dist/{start-DYLk6GXn.mjs → start-B7J5a9nS.mjs} +11 -11
  119. package/dist/{start-CHH3zgIU.mjs → start-CvP2pJjc.mjs} +1 -1
  120. package/dist/{state-BXC1Lfxw.mjs → state-C2AUjjhg.mjs} +1 -1
  121. package/dist/{state-B2QJbDwz.mjs → state-D5ZxwCGJ.mjs} +2 -2
  122. package/dist/{stats-DxKqhcGp.mjs → stats-Uo7l8OAk.mjs} +4 -4
  123. package/dist/{status-7ULDEJ1e.mjs → status-CK7ZoEhV.mjs} +2 -2
  124. package/dist/{status-D_Ljc89p.mjs → status-CqJI1TgG.mjs} +1 -1
  125. package/dist/{status-BHCkOZga.mjs → status-_rWXFSO7.mjs} +24 -24
  126. package/dist/{status-watch-BmsPqYSU.mjs → status-watch-CnSyXUmj.mjs} +4 -4
  127. package/dist/status-worker.mjs +1 -1
  128. package/dist/{stim-desktop-CbWo21kb.mjs → stim-desktop-CYXLFpFS.mjs} +1 -1
  129. package/dist/{stop-b2pouxAO.mjs → stop-Bogo9oO2.mjs} +2 -2
  130. package/dist/{stop-DQvE-P76.mjs → stop-CMVfaA-6.mjs} +4 -4
  131. package/dist/{stop-D-dGE9gh.mjs → stop-CnF9ixYe.mjs} +20 -19
  132. package/dist/supervisor-run.d.mts +1 -0
  133. package/dist/supervisor-run.mjs +23 -19
  134. package/dist/{support-04IhBUTT.mjs → support-BGqpYMV8.mjs} +15 -11
  135. package/dist/{support-BtlJKjyQ.mjs → support-DUevTPur.mjs} +9 -9
  136. package/dist/{swiftpm-artifact-inputs-Cj2UpmPN.mjs → swiftpm-artifact-inputs-BcJk6-3u.mjs} +1 -1
  137. package/dist/{swiftpm-macos-BhF2stxY.mjs → swiftpm-macos-DBrmoocG.mjs} +8 -8
  138. package/dist/toolchain-Cw9VVHOY.mjs +2 -0
  139. package/dist/{toolchain-mLA_km-b.mjs → toolchain-DLdoyxIt.mjs} +19 -11
  140. package/dist/{trigger-DMou-X7j.mjs → trigger-CfnOfpDd.mjs} +1 -1
  141. package/dist/trigger-DBZ-GBrl.mjs +2 -0
  142. package/dist/{warm-progress-B0Vpuvpl.mjs → warm-progress-DQ2wQZKp.mjs} +3 -3
  143. package/dist/web-CI_qCRPw.mjs +2 -0
  144. package/dist/{web-BYmK0TjL.mjs → web-g9U7L1sR.mjs} +8 -8
  145. package/dist/web-run.mjs +5 -5
  146. package/dist/{workspace-state-kIZrdlSg.mjs → workspace-state-DGwkPXwq.mjs} +2 -2
  147. package/dist/{workspaces-CmOcceDN.mjs → workspaces-7_RWoi6c.mjs} +11 -11
  148. package/dist/{worktree-nliAoHxB.mjs → worktree-DEet9H3p.mjs} +1 -1
  149. package/dist/{worktree-2dk5edza.mjs → worktree-qKJ3x07S.mjs} +25 -25
  150. package/package.json +7 -7
  151. package/shim/bundle-response.cjs +37 -0
  152. package/dist/server-expo-WulkyAwT.mjs +0 -2
  153. package/dist/toolchain-qktiV8xc.mjs +0 -2
  154. package/dist/trigger-qp2ji5wE.mjs +0 -2
  155. package/dist/web-CrVLVQZY.mjs +0 -2
@@ -1,20 +1,20 @@
1
1
  import { C as reportSignal } from "./exec-aULwtNly.mjs";
2
- import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-C8R1KIvi.mjs";
3
- import { B as publicUrlSetting, G as remoteIosSetting, W as remoteEasFallbackSetting, Y as resolveIosProjectDir, a as SETTING_SHAPE_REMEDY, ot as tunnelModeSetting, p as cacheProviderSettingError, rt as settingShapeErrors } from "./settings-CY5JZlNN.mjs";
4
- import { Tn as processContext } from "./ccache-Bm_A1xX9.mjs";
5
- import { lt as statsProjectKey } from "./workspaces-CmOcceDN.mjs";
6
- import { J as bundlerPin, ot as runCancellationSignal, s as iosToolchainAsync } from "./toolchain-mLA_km-b.mjs";
7
- import { O as trackedFingerprintPaths, S as refingerprintAfterMutation, _ as inputsChangedDuringBuild, a as configInputsChanged, d as filesystemBuildCapability, f as fingerprintDiffRecord, g as ignoredFingerprintPaths, h as gitignoredFingerprintInputs, k as untrackedMissLine, n as buildCacheKey, r as changedDuringBuildLine } from "./build-cache-CZULpXVl.mjs";
2
+ import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-BBW8eWPL.mjs";
3
+ import { B as publicUrlSetting, G as remoteIosSetting, W as remoteEasFallbackSetting, Y as resolveIosProjectDir, a as SETTING_SHAPE_REMEDY, ot as tunnelModeSetting, p as cacheProviderSettingError, rt as settingShapeErrors } from "./settings-D776ygML.mjs";
4
+ import { Tn as processContext } from "./ccache-B8gY50-h.mjs";
5
+ import { lt as statsProjectKey } from "./workspaces-7_RWoi6c.mjs";
6
+ import { Y as bundlerPin, a as buildsOnlyOnWorker, c as iosToolchainAsync, st as runCancellationSignal } from "./toolchain-DLdoyxIt.mjs";
7
+ import { O as trackedFingerprintPaths, S as refingerprintAfterMutation, _ as inputsChangedDuringBuild, a as configInputsChanged, d as filesystemBuildCapability, f as fingerprintDiffRecord, g as ignoredFingerprintPaths, h as gitignoredFingerprintInputs, k as untrackedMissLine, n as buildCacheKey, r as changedDuringBuildLine } from "./build-cache-DlC3owap.mjs";
8
8
  import { d as optimizationBuildProfile, l as artifactCachePolicy, p as resolveOptimizations } from "./errors-DHm_U5gv.mjs";
9
- import { a as deviceModelRefusal, c as iosProjectPathError, f as podAction, h as resolveDeviceType, l as iosProviderRunOptions, m as resolveConfiguration, u as isReleaseConfiguration, v as resolveRuntime, x as simulatorBuildArch, y as resolveSchemeSelection } from "./support-BtlJKjyQ.mjs";
9
+ import { a as deviceModelRefusal, c as iosProjectPathError, f as podAction, h as resolveDeviceType, l as iosProviderRunOptions, m as resolveConfiguration, u as isReleaseConfiguration, v as resolveRuntime, x as simulatorBuildArch, y as resolveSchemeSelection } from "./support-DUevTPur.mjs";
10
10
  import { t as readDoctorFingerprint } from "./doctor-fingerprint-o7ZI9YLn.mjs";
11
- import { i as planEasDevelopmentBuild, n as easDeviceBuildRemedy } from "./eas-build-Dm6q68QY.mjs";
12
- import { c as fingerprintErrorMissReason, d as memoizedFingerprint, i as recordPrebuildAsync, o as staleNativeDirRefusal, s as explainBuildMiss } from "./prebuild-k8d_tqOq.mjs";
13
- import { r as planPayload, t as planCachedBuild } from "./build-plan-CxoYfxsc.mjs";
14
- import { t as IosRecipeRefusal } from "./ios-project-CR4mZ7CH.mjs";
15
- import { a as hostedIosSelectors } from "./remote-DFlpAqdV.mjs";
16
- import { a as writeIpTxt, c as iosProcessRuntime, r as copyAppAside, s as iosMetroRuntime, t as DEFAULT_DEPS } from "./dependencies-DKeMzwXY.mjs";
17
- import { t as planHostedDevice } from "./plan-placement-WkZdccuN.mjs";
11
+ import { i as planEasDevelopmentBuild, n as easDeviceBuildRemedy } from "./eas-build-DIDOHw2P.mjs";
12
+ import { c as fingerprintErrorMissReason, d as memoizedFingerprint, i as recordPrebuildAsync, o as staleNativeDirRefusal, s as explainBuildMiss } from "./prebuild-DBJMhwSS.mjs";
13
+ import { r as planPayload, t as planCachedBuild } from "./build-plan-J3iRR3gI.mjs";
14
+ import { t as IosRecipeRefusal } from "./ios-project-BM9TbTE7.mjs";
15
+ import { a as hostedIosSelectors } from "./remote-C-RGHhAP.mjs";
16
+ import { a as writeIpTxt, c as iosProcessRuntime, r as copyAppAside, s as iosMetroRuntime, t as DEFAULT_DEPS } from "./dependencies-vUh9mp5z.mjs";
17
+ import { t as planHostedDevice } from "./plan-placement-CdLc-pTb.mjs";
18
18
  import { rmSync } from "node:fs";
19
19
  import chalk from "chalk";
20
20
  //#region src/integrations/react-native-ios-plan.ts
@@ -477,7 +477,8 @@ function reactNativeIosArtifact({ operation, root, logFile, configuration, build
477
477
  const podState = d.readPodState(root, iosProject.dir);
478
478
  const verdict = d.podsAreStale(podState.lockText, podState.manifestText, podState.dir);
479
479
  const action = podAction(podState, verdict, { prebuildRan: mutatingSteps.includes("prebuild") });
480
- if (action.install) {
480
+ if (action.install && buildsOnlyOnWorker(await d.iosToolchain(root, null))) phase("pods", `${action.reason} -> no Xcode here; the Mac that builds runs pod install`);
481
+ else if (action.install) {
481
482
  step("pods");
482
483
  const result = await d.runPodInstall(root, logWriter(), {
483
484
  onHeartbeat: note,
@@ -1,4 +1,4 @@
1
- import { Ct as gitCommonDirOnDisk } from "./settings-CY5JZlNN.mjs";
1
+ import { Ct as gitCommonDirOnDisk } from "./settings-D776ygML.mjs";
2
2
  import { existsSync } from "node:fs";
3
3
  import { loadConfig, recordingEnabled, workspaceRecordingsDir } from "@stim-cli/core/state";
4
4
  import { rm } from "node:fs/promises";
@@ -1,2 +1,2 @@
1
- import { n as reloadCommand, r as runReload, t as registerReload } from "./reload-c_uEyc_X.mjs";
1
+ import { n as reloadCommand, r as runReload, t as registerReload } from "./reload-BUQI3dSu.mjs";
2
2
  export { reloadCommand as default, registerReload, runReload };
@@ -1,18 +1,18 @@
1
1
  import { c as throwIfCancelled, i as loadScaledBudgetMs, o as cancellableSleep, s as cancelledError } from "./exec-aULwtNly.mjs";
2
- import { a as recordWorkspaceUseAsync, r as readWorkspaceState$1 } from "./workspace-state-kIZrdlSg.mjs";
3
- import { H as deviceSlotPlatforms, U as parseDeviceSlotKey, p as getProject } from "./config-Cn94Jc0g.mjs";
4
- import { f as refuseNoProject, l as phaseLine } from "./command-output-C8R1KIvi.mjs";
5
- import { Vt as repoRootAsync } from "./settings-CY5JZlNN.mjs";
6
- import { I as readWorkspaceLaunches, P as readRemoteSession, r as findCommandWorkspaceAsync } from "./project-Sui52ywT.mjs";
7
- import { nt as resolveOwnedAvdSerialAsync } from "./android-CsPs-7Mg.mjs";
8
- import { a as listeningPidsAsync, d as resolveProjectMetro, h as isMetroRunning, u as processCwds } from "./metro-BnhXV2Mj.mjs";
9
- import { fn as iosAppProcess, sn as ensureMetroReverse, tn as androidAppProcess } from "./ccache-Bm_A1xX9.mjs";
10
- import { d as webFactsAsync, o as readWebRecord, r as cdpEndpoint } from "./state-B2QJbDwz.mjs";
11
- import { D as resolveOwnedIosSim, f as listAllIosSimsAsync } from "./ios-B1DYuOjh.mjs";
12
- import { p as probeHostedSession } from "./hosted-client-DDRm9hPJ.mjs";
13
- import { r as readHostedNative } from "./ios-state-BPHqMDdZ.mjs";
14
- import { r as reopenHostedAndroidMetro } from "./hosted-android-DlaKLbW0.mjs";
15
- import { n as nativeRunCommand } from "./slot-launch-BpmanOnk.mjs";
2
+ import { a as recordWorkspaceUseAsync, r as readWorkspaceState$1 } from "./workspace-state-DGwkPXwq.mjs";
3
+ import { H as deviceSlotPlatforms, U as parseDeviceSlotKey, p as getProject } from "./config-AbUjIBOQ.mjs";
4
+ import { f as refuseNoProject, l as phaseLine } from "./command-output-BBW8eWPL.mjs";
5
+ import { Vt as repoRootAsync } from "./settings-D776ygML.mjs";
6
+ import { I as readWorkspaceLaunches, P as readRemoteSession, r as findCommandWorkspaceAsync } from "./project-DPQjnpcI.mjs";
7
+ import { nt as resolveOwnedAvdSerialAsync } from "./android-DdKG6lyD.mjs";
8
+ import { a as listeningPidsAsync, d as resolveProjectMetro, h as isMetroRunning, u as processCwds } from "./metro-BMQHczcf.mjs";
9
+ import { fn as iosAppProcess, sn as ensureMetroReverse, tn as androidAppProcess } from "./ccache-B8gY50-h.mjs";
10
+ import { d as webFactsAsync, o as readWebRecord, r as cdpEndpoint } from "./state-D5ZxwCGJ.mjs";
11
+ import { D as resolveOwnedIosSim, f as listAllIosSimsAsync } from "./ios-CXnoVO_z.mjs";
12
+ import { p as probeHostedSession } from "./hosted-client-Cect92SZ.mjs";
13
+ import { r as readHostedNative } from "./ios-state-Ce_dystM.mjs";
14
+ import { r as reopenHostedAndroidMetro } from "./hosted-android-Du7NxufJ.mjs";
15
+ import { n as nativeRunCommand } from "./slot-launch-CeIK1iUI.mjs";
16
16
  import { n as sendToOwnedPage, t as liveWebRecord } from "./page-CQJlcj3x.mjs";
17
17
  import { hostedAndroidDeviceName, hostedNativeRecords } from "@stim-cli/core/state";
18
18
  import { WebSocket } from "ws";
@@ -1,12 +1,12 @@
1
1
  import { l as WorkspaceProcessCleanupError } from "./exec-aULwtNly.mjs";
2
- import { H as deviceSlotPlatforms } from "./config-Cn94Jc0g.mjs";
3
- import { l as phaseLine } from "./command-output-C8R1KIvi.mjs";
4
- import { B as publicUrlSetting, G as remoteIosSetting, L as parseIosRemote, W as remoteEasFallbackSetting, ot as tunnelModeSetting } from "./settings-CY5JZlNN.mjs";
5
- import "./ccache-Bm_A1xX9.mjs";
6
- import { ot as runCancellationSignal } from "./toolchain-mLA_km-b.mjs";
7
- import { b as resolveSimulatorAppFlag } from "./support-BtlJKjyQ.mjs";
8
- import { n as devicePlacementRecord } from "./placement-log-Cvhta5ib.mjs";
9
- import { n as devicePlacementLine } from "./auto-placement-BVqs8AJi.mjs";
2
+ import { H as deviceSlotPlatforms } from "./config-AbUjIBOQ.mjs";
3
+ import { l as phaseLine } from "./command-output-BBW8eWPL.mjs";
4
+ import { B as publicUrlSetting, G as remoteIosSetting, L as parseIosRemote, W as remoteEasFallbackSetting, ot as tunnelModeSetting } from "./settings-D776ygML.mjs";
5
+ import "./ccache-B8gY50-h.mjs";
6
+ import { st as runCancellationSignal } from "./toolchain-DLdoyxIt.mjs";
7
+ import { b as resolveSimulatorAppFlag } from "./support-DUevTPur.mjs";
8
+ import { n as devicePlacementRecord } from "./placement-log-CRR_TE1r.mjs";
9
+ import { n as devicePlacementLine } from "./auto-placement-CZaWDmcY.mjs";
10
10
  import chalk from "chalk";
11
11
  //#region src/commands/ios/remote.ts
12
12
  function deviceRemoteConflict(remote, physical) {
@@ -1,20 +1,20 @@
1
- import { w as workspaceAgentDeviceDir } from "./workspace-state-kIZrdlSg.mjs";
2
- import { H as deviceSlotPlatforms, p as getProject } from "./config-Cn94Jc0g.mjs";
3
- import { i as formatDuration, l as phaseLine } from "./command-output-C8R1KIvi.mjs";
4
- import { J as resolveCacheProviderConfig, L as parseIosRemote, U as remoteAndroidSetting, _ as inertSettingWarning, a as SETTING_SHAPE_REMEDY, at as settingsLayers, d as androidLayoutSetting, et as settingFile, f as androidLayoutSettingError, nt as settingOriginScope, p as cacheProviderSettingError, q as resolveAndroidLayout, rt as settingShapeErrors, s as androidAvdConfigSettingError, st as unknownSettingKeys, u as androidDataPartitionSizeGbSettingError } from "./settings-CY5JZlNN.mjs";
5
- import { v as detectIsExpo } from "./project-Sui52ywT.mjs";
6
- import { a as workspaceLinkLine } from "./stim-desktop-CbWo21kb.mjs";
7
- import { B as ownedAvdDeviceProfile, I as listInstalledSystemImages, K as ownedAvdSystemImage, N as listAvdDeviceProfilesAsync, Q as profileNeedsFoldFeature, X as pickDefaultSystemImage, at as systemImageSupportsFold, k as hostSystemImageArch, l as androidSystemImageAbi, t as DEFAULT_AVD_DEVICE_PROFILE, vt as parkedMaxSetting } from "./android-CsPs-7Mg.mjs";
8
- import { Mn as isEasAuthFailureText, On as UPLOAD_TIMEOUT_MS, jn as easAuthNote, kn as cacheLevel, n as CCACHE_UNAVAILABLE, r as ccacheActivityLine } from "./ccache-Bm_A1xX9.mjs";
9
- import { X as recordFinishedBuild } from "./workspaces-CmOcceDN.mjs";
1
+ import { w as workspaceAgentDeviceDir } from "./workspace-state-DGwkPXwq.mjs";
2
+ import { H as deviceSlotPlatforms, p as getProject } from "./config-AbUjIBOQ.mjs";
3
+ import { i as formatDuration, l as phaseLine } from "./command-output-BBW8eWPL.mjs";
4
+ import { J as resolveCacheProviderConfig, L as parseIosRemote, U as remoteAndroidSetting, _ as inertSettingWarning, a as SETTING_SHAPE_REMEDY, at as settingsLayers, d as androidLayoutSetting, et as settingFile, f as androidLayoutSettingError, nt as settingOriginScope, p as cacheProviderSettingError, q as resolveAndroidLayout, rt as settingShapeErrors, s as androidAvdConfigSettingError, st as unknownSettingKeys, u as androidDataPartitionSizeGbSettingError } from "./settings-D776ygML.mjs";
5
+ import { v as detectIsExpo } from "./project-DPQjnpcI.mjs";
6
+ import { a as workspaceLinkLine } from "./stim-desktop-CYXLFpFS.mjs";
7
+ import { A as hostSystemImageArch, B as ownedAvdDeviceProfile, K as ownedAvdSystemImage, L as listInstalledSystemImages, P as listAvdDeviceProfilesAsync, Q as profileNeedsFoldFeature, X as pickDefaultSystemImage, at as systemImageSupportsFold, l as androidSystemImageAbi, t as DEFAULT_AVD_DEVICE_PROFILE, vt as parkedMaxSetting } from "./android-DdKG6lyD.mjs";
8
+ import { Mn as isEasAuthFailureText, On as UPLOAD_TIMEOUT_MS, jn as easAuthNote, kn as cacheLevel, n as CCACHE_UNAVAILABLE, r as ccacheActivityLine } from "./ccache-B8gY50-h.mjs";
9
+ import { X as recordFinishedBuild } from "./workspaces-7_RWoi6c.mjs";
10
10
  import { d as optimizationBuildProfile, l as artifactCachePolicy, p as resolveOptimizations, u as compilerCacheFallbackMessage } from "./errors-DHm_U5gv.mjs";
11
- import { n as buildPlacementCandidates } from "./client-YxCer6ab.mjs";
12
- import { c as readProductFlavors, s as productFlavorRefusal } from "./react-native-build-jUHnIfZ9.mjs";
13
- import { l as parseDeviceWait } from "./device-lease-run-Mtzp4THX.mjs";
14
- import { t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-Cd8lMSn3.mjs";
15
- import { n as resolveAndroidCas, r as resolveAndroidCompilerCache } from "./android-cas-_aDifWW0.mjs";
16
- import { r as isPhysicalDeviceRequest } from "./native-runtime-DG4Rodzj.mjs";
17
- import { C as remoteAvdFlagRefusal, D as systemImageRefusal, E as resolveVariant, T as resolveSystemImage, a as PLATFORM, m as deviceProfileRefusal, v as foldableImageRefusal, w as resolveDeviceProfile, y as isReleaseVariant } from "./support-04IhBUTT.mjs";
11
+ import { n as buildPlacementCandidates } from "./client-DrHykA24.mjs";
12
+ import { c as readProductFlavors, s as productFlavorRefusal } from "./react-native-build-BSoh4HkH.mjs";
13
+ import { l as parseDeviceWait } from "./device-lease-run-Do6zYA7y.mjs";
14
+ import { t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-C5C_jOQd.mjs";
15
+ import { n as resolveAndroidCas, r as resolveAndroidCompilerCache } from "./android-cas-BH6K12__.mjs";
16
+ import { r as isPhysicalDeviceRequest } from "./native-runtime-D4cTwU0Z.mjs";
17
+ import { C as remoteAvdFlagRefusal, D as systemImageRefusal, E as resolveVariant, T as resolveSystemImage, a as PLATFORM, m as deviceProfileRefusal, v as foldableImageRefusal, w as resolveDeviceProfile, y as isReleaseVariant } from "./support-BGqpYMV8.mjs";
18
18
  import { buildDiagnostics } from "@stim-cli/core/state";
19
19
  import chalk from "chalk";
20
20
  //#region src/commands/android/plan.ts
@@ -1,6 +1,6 @@
1
1
  import { D as ownership_claim_exports, S as process_identity_exports, t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { a as macosRuntimeClaim, i as macosProcess, r as macosLogFile, s as updateMacosRecord } from "./state-BXC1Lfxw.mjs";
3
- import { i as createNdjsonWriter } from "./ndjson-Dy2W4vRa.mjs";
2
+ import { a as macosRuntimeClaim, i as macosProcess, r as macosLogFile, s as updateMacosRecord } from "./state-C2AUjjhg.mjs";
3
+ import { i as createNdjsonWriter } from "./ndjson-CrjIsGzw.mjs";
4
4
  import { LOG_ROTATE_BYTES } from "@stim-cli/core";
5
5
  import { readMacosRecord } from "@stim-cli/core/state";
6
6
  import { StringDecoder } from "node:string_decoder";
@@ -1,12 +1,12 @@
1
1
  import { C as reportSignal, b as operationState } from "./exec-aULwtNly.mjs";
2
- import { M as withDirLock$1 } from "./workspace-state-kIZrdlSg.mjs";
3
- import { $ as endpoint$1, X as diagnoseOutcome, Z as diagnoseTailscale, _ as loadConfig$1, at as realIo, ct as setupRemedy, d as getConfigDir, dt as notOnTailnetDiagnosis, et as findPeer$1, ft as readHostPermissions, it as reachMachine, lt as tailscaleStatusAsync, nt as outdatedServer, rt as parseMachine$1, ut as diagnosisFinding } from "./config-Cn94Jc0g.mjs";
4
- import { o as cocoapodsInstall } from "./toolchain-mLA_km-b.mjs";
2
+ import { M as withDirLock$1 } from "./workspace-state-DGwkPXwq.mjs";
3
+ import { $ as endpoint$1, X as diagnoseOutcome, Z as diagnoseTailscale, _ as loadConfig$1, at as reachMachine, d as getConfigDir, dt as diagnoseLocalUnreachable, et as findPeer$1, ft as diagnosisFinding, ht as readHostPermissions, it as parseMachine$1, lt as setupRemedy, mt as unconfirmedKeyFinding, ot as realIo, pt as notOnTailnetDiagnosis, rt as outdatedServer, ut as tailscaleStatusAsync } from "./config-AbUjIBOQ.mjs";
4
+ import { s as cocoapodsInstall } from "./toolchain-DLdoyxIt.mjs";
5
5
  import { releaseClaim, tryAcquireClaim } from "@stim-cli/core/ownership-claim";
6
6
  import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
7
7
  import { hostname } from "node:os";
8
8
  import { ambientContext, ambientEnv, withDirLockAsync } from "@stim-cli/core";
9
- import { MACHINE_CREDENTIALS_VERSION, acceptsShape, automaticMachineEnabled, buildMachinesFile, buildMachinesLock, cannotHost, deviceHostMachinesClaims, deviceHostMachinesFile, deviceHostMachinesLock, isJsonObject, parseMachine, placementWord, readBuildMachines, readDeviceHostMachines, settingDefinition } from "@stim-cli/core/state";
9
+ import { MACHINE_CREDENTIALS_VERSION, acceptsShape, automaticMachineEnabled, buildMachinesFile, buildMachinesLock, cannotHost, deviceHostMachinesClaims, deviceHostMachinesFile, deviceHostMachinesLock, isJsonObject, localEndpoint, parseMachine, placementWord, readBuildMachines, readDeviceHostMachines, settingDefinition } from "@stim-cli/core/state";
10
10
  import { InvalidArgumentError } from "commander";
11
11
  //#region src/device-host/machines.ts
12
12
  function note$1(title, detail, fix = null) {
@@ -39,7 +39,7 @@ async function hostingMachines(status, signal) {
39
39
  } catch {
40
40
  candidates = configured;
41
41
  }
42
- if (!candidates.length) return candidates;
42
+ if (!candidates.some((machine) => parseMachine$1(machine)?.transport === "tailscale")) return candidates;
43
43
  const current = await (status ? status() : tailscaleStatusAsync(signal));
44
44
  signal?.throwIfAborted();
45
45
  return candidates.filter((machine) => !cannotHost(current, machine));
@@ -72,7 +72,7 @@ async function store(machines, operation) {
72
72
  * Reports the device-host approval of each remote machine, separate from its build approval. Only --fix makes a setup
73
73
  * ticket or forgets credentials; every server key stays pinned.
74
74
  */
75
- async function inspectDeviceHostMachines({ fix, version = "<version>", tickets = /* @__PURE__ */ new Map(), operation }, io = realIo, entries = configuredMachines()) {
75
+ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets = /* @__PURE__ */ new Map(), operation, confirmKey }, io = realIo, entries = configuredMachines()) {
76
76
  if (entries === null) return {
77
77
  findings: [note$1("Invalid remote.machines setting", "Use a remote object with machines as an array of tailnet names. Existing hosting credentials and pinned keys are preserved.", "Run `stim guide settings` and correct the setting before running doctor again.")],
78
78
  machines: []
@@ -126,24 +126,19 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
126
126
  findings: [],
127
127
  machines: []
128
128
  };
129
- const status = await io.status();
130
- if (!isJsonObject(status)) {
131
- const diagnosis = await diagnoseTailscale(io);
132
- return {
133
- findings: [note$1("Remote machines are unreachable", `remote.machines names remote machines. ${diagnosis.message}`, diagnosis.remedy)],
134
- machines: entries.map((machine) => ({
135
- machine,
136
- state: "tailscale-off",
137
- diagnosis
138
- }))
139
- };
140
- }
141
- const self = isJsonObject(status.Self) ? status.Self : {};
142
- const deviceName = (typeof self.HostName === "string" && self.HostName ? self.HostName : hostname()).replace(/[\p{Cc}\p{Cf}]/gu, "").trim().slice(0, 64) || "Mac";
129
+ const tailnet = entries.some((entry) => parseMachine$1(entry)?.transport !== "local");
130
+ const status = tailnet ? await io.status() : null;
143
131
  const inspected = {
144
132
  findings: [],
145
133
  machines: []
146
134
  };
135
+ let off = null;
136
+ if (tailnet && !isJsonObject(status)) {
137
+ off = await diagnoseTailscale(io);
138
+ inspected.findings.push(note$1("Remote machines are unreachable", `remote.machines names remote machines. ${off.message}`, off.remedy));
139
+ }
140
+ const self = isJsonObject(status) && isJsonObject(status.Self) ? status.Self : {};
141
+ const deviceName = (typeof self.HostName === "string" && self.HostName ? self.HostName : hostname()).replace(/[\p{Cc}\p{Cf}]/gu, "").trim().slice(0, 64) || "Mac";
147
142
  const namedNodes = /* @__PURE__ */ new Set();
148
143
  for (const machine of new Set(entries)) {
149
144
  const parsed = parseMachine$1(machine);
@@ -152,11 +147,20 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
152
147
  machine,
153
148
  state: "invalid"
154
149
  });
155
- inspected.findings.push(note$1(`Remote machine ${machine} is not a tailnet name`, "Expected `name` or `name:port`."));
150
+ inspected.findings.push(note$1(`Remote machine ${machine} is not a tailnet name or local: address`, "Expected `name`, `name:port`, `local:<host>` or `local:<host>:port`."));
156
151
  continue;
157
152
  }
158
- const current = await io.status();
159
- if (!isJsonObject(current)) {
153
+ const local = parsed.transport === "local";
154
+ if (!local && off) {
155
+ inspected.machines.push({
156
+ machine,
157
+ state: "tailscale-off",
158
+ diagnosis: off
159
+ });
160
+ continue;
161
+ }
162
+ const current = local ? null : await io.status();
163
+ if (!local && !isJsonObject(current)) {
160
164
  const diagnosis = await diagnoseTailscale(io);
161
165
  inspected.machines.push({
162
166
  machine,
@@ -166,7 +170,7 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
166
170
  inspected.findings.push(diagnosisFinding("device-host-machine", machine, diagnosis));
167
171
  continue;
168
172
  }
169
- const peer = findPeer$1(current, parsed.name);
173
+ const peer = local ? null : findPeer$1(current, parsed.name);
170
174
  if (peer === "missing" || peer === "ambiguous") {
171
175
  const diagnosis = notOnTailnetDiagnosis(machine, peer === "ambiguous");
172
176
  inspected.machines.push({
@@ -177,11 +181,13 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
177
181
  inspected.findings.push(diagnosisFinding("device-host-machine", machine, diagnosis));
178
182
  continue;
179
183
  }
180
- const nodeRoute = `${peer.nodeId}:${parsed.port}`;
184
+ const target = peer ? endpoint$1(peer, parsed.port) : localEndpoint(parsed.name, parsed.port);
185
+ const dnsName = peer ? { dnsName: peer.dnsName } : {};
186
+ const nodeRoute = peer ? `${peer.nodeId}:${parsed.port}` : `local:${parsed.name}:${parsed.port}`;
181
187
  if (namedNodes.has(nodeRoute)) {
182
188
  inspected.machines.push({
183
189
  machine,
184
- dnsName: peer.dnsName,
190
+ ...dnsName,
185
191
  state: "invalid"
186
192
  });
187
193
  inspected.findings.push(note$1(`Remote machine ${machine} repeats a named node`, "Name each tailnet node and serve port only once in remote.machines."));
@@ -191,7 +197,7 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
191
197
  if (cannotHost(current, machine)) {
192
198
  inspected.machines.push({
193
199
  machine,
194
- dnsName: peer.dnsName,
200
+ ...dnsName,
195
201
  state: "not-asked"
196
202
  });
197
203
  continue;
@@ -201,8 +207,8 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
201
207
  const outcome = await reachMachine({
202
208
  machine,
203
209
  access: "device-host",
204
- endpoint: endpoint$1(peer, parsed.port),
205
- address: peer.dnsName,
210
+ endpoint: target,
211
+ address: peer?.dnsName ?? parsed.name,
206
212
  credential,
207
213
  other: () => readBuildMachines().find((each) => each.machine === machine),
208
214
  persist: async (next) => {
@@ -214,7 +220,8 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
214
220
  setupFlags: ["build", "device-host"],
215
221
  serverVersion: version,
216
222
  io,
217
- tickets
223
+ tickets,
224
+ ...local ? { confirmKey: (serverKey) => confirmKey?.(machine, serverKey) ?? Promise.resolve(false) } : {}
218
225
  });
219
226
  reportSignal(operation)?.throwIfAborted();
220
227
  if (outcome.state !== "not-asked" && outcome.credential) {
@@ -227,7 +234,7 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
227
234
  const saved = outcome.state !== "not-asked" ? outcome.credential : void 0;
228
235
  const known = {
229
236
  machine,
230
- dnsName: peer.dnsName,
237
+ ...dnsName,
231
238
  ...saved?.deviceId ? { deviceId: saved.deviceId } : {},
232
239
  ...saved ? { requestedAt: saved.requestedAt } : {}
233
240
  };
@@ -278,14 +285,30 @@ async function inspectDeviceHostMachines({ fix, version = "<version>", tickets =
278
285
  inspected.findings.push(note$1(outdated.title, outdated.detail, outdated.fix));
279
286
  continue;
280
287
  }
288
+ if (outcome.state === "unconfirmed") {
289
+ inspected.machines.push({
290
+ ...known,
291
+ state: "key-unconfirmed",
292
+ fingerprint: outcome.fingerprint
293
+ });
294
+ inspected.findings.push(unconfirmedKeyFinding("device-host-machine", machine, outcome.fingerprint));
295
+ continue;
296
+ }
281
297
  if (outcome.state === "unreachable") {
282
- const diagnosis = await diagnoseOutcome(io, {
298
+ const failure = {
283
299
  entry: machine,
284
- peer,
285
300
  port: parsed.port,
286
- target: endpoint$1(peer, parsed.port),
301
+ target,
287
302
  reason: outcome.reason,
288
303
  transport: outcome.transport
304
+ };
305
+ const startup = !peer && outcome.transport?.kind === "http" && outcome.transport.status === 503 ? await io.startup?.(target) : null;
306
+ const diagnosis = peer ? await diagnoseOutcome(io, {
307
+ ...failure,
308
+ peer
309
+ }) : diagnoseLocalUnreachable({
310
+ ...failure,
311
+ startup
289
312
  });
290
313
  inspected.machines.push({
291
314
  ...known,
@@ -434,16 +457,26 @@ function offloadFindings(entry, problems, notes, operation) {
434
457
  fix: commandFix(each, entry)
435
458
  }))];
436
459
  }
437
- async function inspectMachine(entry, status, deviceName, fix, version, tickets, io, check, operation) {
460
+ async function inspectMachine(entry, tailnet, deviceName, fix, version, tickets, io, check, operation, confirmKey) {
438
461
  const parsed = parseMachine$1(entry);
439
462
  if (!parsed) return {
440
463
  report: {
441
464
  machine: entry,
442
465
  state: "invalid"
443
466
  },
444
- finding: note(`Remote machine ${entry} is not a tailnet name`, "Expected `name` or `name:port`.")
467
+ finding: note(`Remote machine ${entry} is not a tailnet name or local: address`, "Expected `name`, `name:port`, `local:<host>` or `local:<host>:port`.")
445
468
  };
446
- const peer = findPeer$1(status, parsed.name);
469
+ const local = parsed.transport === "local";
470
+ if (!local && "off" in tailnet) return {
471
+ report: {
472
+ machine: entry,
473
+ state: "tailscale-off",
474
+ diagnosis: tailnet.off
475
+ },
476
+ finding: null
477
+ };
478
+ const status = "status" in tailnet ? tailnet.status : {};
479
+ const peer = local ? null : findPeer$1(status, parsed.name);
447
480
  if (peer === "missing" || peer === "ambiguous") {
448
481
  const diagnosis = notOnTailnetDiagnosis(entry, peer === "ambiguous");
449
482
  return {
@@ -455,6 +488,8 @@ async function inspectMachine(entry, status, deviceName, fix, version, tickets,
455
488
  finding: diagnosisFinding("build-machine", entry, diagnosis)
456
489
  };
457
490
  }
491
+ const target = peer ? endpoint$1(peer, parsed.port) : localEndpoint(parsed.name, parsed.port);
492
+ const address = peer?.dnsName ?? parsed.name;
458
493
  const credential = readBuildMachines().find((each) => each.machine === entry);
459
494
  const other = () => {
460
495
  try {
@@ -468,8 +503,8 @@ async function inspectMachine(entry, status, deviceName, fix, version, tickets,
468
503
  const outcome = await reachMachine({
469
504
  machine: entry,
470
505
  access: "build",
471
- endpoint: endpoint$1(peer, parsed.port),
472
- address: peer.dnsName,
506
+ endpoint: target,
507
+ address,
473
508
  credential,
474
509
  other,
475
510
  persist,
@@ -478,11 +513,12 @@ async function inspectMachine(entry, status, deviceName, fix, version, tickets,
478
513
  setupFlags: cannotHost(status, entry) ? ["build"] : ["build", "device-host"],
479
514
  serverVersion: version,
480
515
  io,
481
- tickets
516
+ tickets,
517
+ ...local ? { confirmKey: (serverKey) => confirmKey?.(entry, serverKey) ?? Promise.resolve(false) } : {}
482
518
  });
483
519
  const known = {
484
520
  machine: entry,
485
- dnsName: peer.dnsName
521
+ ...peer ? { dnsName: peer.dnsName } : {}
486
522
  };
487
523
  reportSignal(operation)?.throwIfAborted();
488
524
  if (outcome.state !== "not-asked" && outcome.credential) {
@@ -507,7 +543,15 @@ async function inspectMachine(entry, status, deviceName, fix, version, tickets,
507
543
  ...paired,
508
544
  state: "key-changed"
509
545
  },
510
- finding: note(`Remote machine ${entry} answered with a different server key`, `${peer.dnsName} did not prove it holds the stim-server key this machine pinned at approval. Stim does not connect to it.`, `If that machine or its Stim home was replaced, remove ${entry} from remote.machines, run \`stim doctor --fix\` to forget the old pairing, then add it back and run \`stim doctor --fix\` again.`)
546
+ finding: note(`Remote machine ${entry} answered with a different server key`, `${address} did not prove it holds the stim-server key this machine pinned at approval. Stim does not connect to it.`, `If that machine or its Stim home was replaced, remove ${entry} from remote.machines, run \`stim doctor --fix\` to forget the old pairing, then add it back and run \`stim doctor --fix\` again.`)
547
+ };
548
+ case "unconfirmed": return {
549
+ report: {
550
+ ...paired,
551
+ state: "key-unconfirmed",
552
+ fingerprint: outcome.fingerprint
553
+ },
554
+ finding: unconfirmedKeyFinding("build-machine", entry, outcome.fingerprint)
511
555
  };
512
556
  case "pending": return {
513
557
  report: {
@@ -550,13 +594,20 @@ async function inspectMachine(entry, status, deviceName, fix, version, tickets,
550
594
  };
551
595
  }
552
596
  case "unreachable": {
553
- const diagnosis = await diagnoseOutcome(io, {
597
+ const failure = {
554
598
  entry,
555
- peer,
556
599
  port: parsed.port,
557
- target: endpoint$1(peer, parsed.port),
600
+ target,
558
601
  reason: outcome.reason,
559
602
  transport: outcome.transport
603
+ };
604
+ const startup = !peer && outcome.transport?.kind === "http" && outcome.transport.status === 503 ? await io.startup?.(target) : null;
605
+ const diagnosis = peer ? await diagnoseOutcome(io, {
606
+ ...failure,
607
+ peer
608
+ }) : diagnoseLocalUnreachable({
609
+ ...failure,
610
+ startup
560
611
  });
561
612
  return {
562
613
  report: {
@@ -601,7 +652,7 @@ async function inspectMachine(entry, status, deviceName, fix, version, tickets,
601
652
  * `check`, each approved machine is asked for one build offer and reports every reason it would not take this
602
653
  * project's build.
603
654
  */
604
- async function inspectBuildMachines({ fix, check = null, version = "<version>", tickets = /* @__PURE__ */ new Map(), operation }, io = realIo, entries = configuredMachines()) {
655
+ async function inspectBuildMachines({ fix, check = null, version = "<version>", tickets = /* @__PURE__ */ new Map(), operation, confirmKey }, io = realIo, entries = configuredMachines()) {
605
656
  if (entries === null) return {
606
657
  findings: [note("Invalid remote.machines setting", "Use a remote object with machines as an array of tailnet names. Existing credentials and pinned keys are preserved.", "Run `stim guide settings` and correct the setting before running doctor again.")],
607
658
  machines: []
@@ -612,25 +663,17 @@ async function inspectBuildMachines({ fix, check = null, version = "<version>",
612
663
  findings: [],
613
664
  machines: []
614
665
  };
615
- const status = await io.status();
616
- if (!isJsonObject(status)) {
617
- const diagnosis = await diagnoseTailscale(io);
618
- return {
619
- findings: [note("Remote machines are unreachable", `remote.machines names remote machines. ${diagnosis.message}`, diagnosis.remedy)],
620
- machines: entries.map((machine) => ({
621
- machine,
622
- state: "tailscale-off",
623
- diagnosis
624
- }))
625
- };
626
- }
627
- const self = isJsonObject(status.Self) ? status.Self : {};
628
- const deviceName = (typeof self.HostName === "string" && self.HostName ? self.HostName : hostname()).replace(/[\p{Cc}\p{Cf}]/gu, "").trim().slice(0, 64) || "Mac";
666
+ const tailnet = entries.some((entry) => parseMachine$1(entry)?.transport !== "local");
667
+ const read = tailnet ? await io.status() : null;
668
+ const view = isJsonObject(read) ? { status: read } : tailnet ? { off: await diagnoseTailscale(io) } : { status: {} };
629
669
  const inspection = {
630
670
  findings: [],
631
671
  machines: []
632
672
  };
633
- const inspected = await Promise.all(entries.map((entry) => inspectMachine(entry, status, deviceName, fix, version, tickets, io, check, operation)));
673
+ if ("off" in view) inspection.findings.push(note("Remote machines are unreachable", `remote.machines names remote machines. ${view.off.message}`, view.off.remedy));
674
+ const self = "status" in view && isJsonObject(view.status.Self) ? view.status.Self : {};
675
+ const deviceName = (typeof self.HostName === "string" && self.HostName ? self.HostName : hostname()).replace(/[\p{Cc}\p{Cf}]/gu, "").trim().slice(0, 64) || "Mac";
676
+ const inspected = await Promise.all(entries.map((entry) => inspectMachine(entry, view, deviceName, fix, version, tickets, io, check, operation, confirmKey)));
634
677
  for (const { report, finding, extra = [] } of inspected) {
635
678
  inspection.machines.push(report);
636
679
  if (finding) inspection.findings.push(finding);
@@ -708,7 +751,7 @@ function requireConfiguredMachine(selected, machines) {
708
751
  const entries = Array.isArray(machines) ? machines.filter((entry) => typeof entry === "string") : [];
709
752
  const match = entries.find((entry) => {
710
753
  const candidate = parseMachine(entry);
711
- return candidate?.name === parsed.name && candidate.port === parsed.port;
754
+ return candidate?.transport === parsed.transport && candidate.name === parsed.name && candidate.port === parsed.port;
712
755
  });
713
756
  if (!match) throw new OffloadRefusal(selected, `not listed in remote.machines (configured: ${entries.join(", ") || "none"})`);
714
757
  return match;
@@ -1,5 +1,5 @@
1
1
  import { O as __commonJSMin, k as __require, t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { X as resolveProjectSettings } from "./settings-CY5JZlNN.mjs";
2
+ import { X as resolveProjectSettings } from "./settings-D776ygML.mjs";
3
3
  import { c as registerMetroStore, f as resolveMetroSharedCache, n as supervisorError, r as appendCacheStore, s as metroStoreRoot } from "./errors-DHm_U5gv.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import { isAbsolute, join, relative, sep } from "node:path";
@@ -20,6 +20,9 @@ var import_bundle_response = (/* @__PURE__ */ __commonJSMin(((exports, module) =
20
20
  "/index.exp"
21
21
  ]);
22
22
  const observedServers = /* @__PURE__ */ new WeakSet();
23
+ const HMR_UPDATE = ["\"type\":\"update-start\"", "\"isInitialUpdate\":false"];
24
+ const HMR_UPDATE_INTERVAL_MS = 6e4;
25
+ const hmrServers = /* @__PURE__ */ new WeakSet();
23
26
  function clientPidFromLsof(output, clientPort, serverPort) {
24
27
  const connection = new RegExp(`:${clientPort}->\\S*:${serverPort}$`);
25
28
  let pid = null;
@@ -80,8 +83,40 @@ var import_bundle_response = (/* @__PURE__ */ __commonJSMin(((exports, module) =
80
83
  res.once("close", () => finish(false));
81
84
  });
82
85
  }
86
+ function observeHmrUpdates(server, write) {
87
+ if (!server || hmrServers.has(server)) return;
88
+ hmrServers.add(server);
89
+ let recordedAt = 0;
90
+ server.prependListener("upgrade", (req, socket) => {
91
+ let pathname;
92
+ try {
93
+ pathname = new URL(req.url, "http://localhost").pathname;
94
+ } catch {
95
+ return;
96
+ }
97
+ if (pathname !== "/hot") return;
98
+ const send = socket.write;
99
+ socket.write = function(chunk, ...rest) {
100
+ const now = Date.now();
101
+ if (now - recordedAt >= HMR_UPDATE_INTERVAL_MS && (typeof chunk === "string" || Buffer.isBuffer(chunk)) && HMR_UPDATE.every((part) => chunk.includes(part))) {
102
+ recordedAt = now;
103
+ try {
104
+ write({
105
+ ts: now,
106
+ src: "metro",
107
+ level: "debug",
108
+ event: "hmr_update",
109
+ msg: "HMR update sent to the app"
110
+ });
111
+ } catch {}
112
+ }
113
+ return send.call(this, chunk, ...rest);
114
+ };
115
+ });
116
+ }
83
117
  function bundleResponseMiddleware(write, { runLsof, manifests = false } = {}) {
84
118
  return (req, res, next) => {
119
+ observeHmrUpdates(req.socket.server, write);
85
120
  if (req.method === "GET" && req.url === "/_stim/metro-warmup") {
86
121
  if (manifests) observeManifestRequests(req.socket.server, write);
87
122
  res.end("ready");
@@ -416,6 +451,7 @@ async function startBareServer({ root, port, logsDir, writer = null, deps = null
416
451
  return {
417
452
  mode: "bare-inproc",
418
453
  serverPid: null,
454
+ observesRequests: true,
419
455
  httpServer,
420
456
  onExit(cb) {
421
457
  listeners.push(cb);
@@ -1,9 +1,9 @@
1
1
  import { t as getExecutor } from "./exec-aULwtNly.mjs";
2
- import { n as METRO_COMMAND_PORT } from "./settings-CY5JZlNN.mjs";
3
- import { T as MODE_COMMAND } from "./project-Sui52ywT.mjs";
4
- import { f as signalProcessTree } from "./metro-BnhXV2Mj.mjs";
5
- import { i as createNdjsonWriter } from "./ndjson-Dy2W4vRa.mjs";
6
- import { g as projectNodeLine, p as recordFromLine, v as withProjectNode, y as superviseChildServer } from "./server-expo-Ccm9zB0o.mjs";
2
+ import { n as METRO_COMMAND_PORT } from "./settings-D776ygML.mjs";
3
+ import { T as MODE_COMMAND } from "./project-DPQjnpcI.mjs";
4
+ import { f as signalProcessTree } from "./metro-BMQHczcf.mjs";
5
+ import { i as createNdjsonWriter } from "./ndjson-CrjIsGzw.mjs";
6
+ import { g as projectNodeLine, p as recordFromLine, v as withProjectNode, y as superviseChildServer } from "./server-expo-C1K07shx.mjs";
7
7
  import { join } from "node:path";
8
8
  import { LOG_ROTATE_BYTES } from "@stim-cli/core";
9
9
  //#region src/supervisor/server-command.ts
@@ -0,0 +1,2 @@
1
+ import { m as startExpoServer } from "./server-expo-C1K07shx.mjs";
2
+ export { startExpoServer };