stim 1.17.2 → 1.19.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 (162) hide show
  1. package/README.md +50 -1
  2. package/dist/{activity-IRvJY_ru.mjs → activity-BSw0x84R.mjs} +4 -4
  3. package/dist/{agent-device-usage-output-BK41vnzN.mjs → agent-device-usage-output-Bjxu_VmX.mjs} +8 -8
  4. package/dist/{android-B9yaNKwa.mjs → android-BXc6BmEi.mjs} +658 -404
  5. package/dist/{android-B_YNZy61.mjs → android-BdQC6zs1.mjs} +9 -9
  6. package/dist/android-BvV1gGdN.mjs +4 -0
  7. package/dist/{android-DE4v59Mb.mjs → android-DE5g_5gv.mjs} +2 -2
  8. package/dist/{android-cas-ZFpjJBL_.mjs → android-cas-C87geAg-.mjs} +5 -5
  9. package/dist/android-cas-compiler.mjs +2 -2
  10. package/dist/api-DIf_s86s.mjs +150 -0
  11. package/dist/api-run.d.mts +1 -0
  12. package/dist/api-run.mjs +145 -0
  13. package/dist/api.d.mts +218 -0
  14. package/dist/api.mjs +2 -0
  15. package/dist/{app-install-VPkI5WEg.mjs → app-install-CFI4ptUL.mjs} +33 -13
  16. package/dist/{attempt-Bk2ouQVL.mjs → attempt-DW-mQqM7.mjs} +14 -4
  17. package/dist/{web-Dl0KSRHf.mjs → browser-web-CDhqQxhv.mjs} +138 -176
  18. package/dist/{budget-DfcgFdQB.mjs → budget-Dz-kyXLv.mjs} +1391 -58
  19. package/dist/build-facts-B87vo-Im.d.mts +142 -0
  20. package/dist/{cache-manifest-DnUHBJaU.mjs → cache-manifest-DiwKSyv9.mjs} +3 -3
  21. package/dist/cache-manifest.mjs +1 -1
  22. package/dist/{chrome-BrcVWQyD.mjs → chrome-BTUOo8p2.mjs} +1 -1
  23. package/dist/cli-C9Zvgbdc.mjs +68 -0
  24. package/dist/cli.mjs +1 -1
  25. package/dist/{client-SvBdgObD.mjs → client-CuUo8Nvg.mjs} +381 -49
  26. package/dist/collector-run.d.mts +6 -0
  27. package/dist/collector-run.mjs +9 -9
  28. package/dist/{command-output-CDAIFD-8.mjs → command-output-Bt8ygHE7.mjs} +2 -2
  29. package/dist/{config-D0DbpZtM.mjs → config-DC5jEtd1.mjs} +9 -5
  30. package/dist/{created-devices-CpvzBL25.mjs → created-devices-D0s26Hx5.mjs} +2 -2
  31. package/dist/{dependency-state-CLcBHH2M.mjs → dependency-state-DKaS1OM9.mjs} +2 -2
  32. package/dist/{detached-entry-CiTEgMR1.mjs → detached-entry-pB_IPfV4.mjs} +1 -1
  33. package/dist/{dev-client-B-XC4uRH.mjs → dev-client-CDY_zAmD.mjs} +2 -2
  34. package/dist/{device-C8IOoJPv.mjs → device-BHw0WlHl.mjs} +8 -8
  35. package/dist/{device-capacity-ZC4XSZ4R.mjs → device-capacity-BoN1jQkO.mjs} +25 -14
  36. package/dist/device-host-worker.mjs +19 -19
  37. package/dist/{gradle-dJpre3Yn.mjs → device-ios-B2ruohE-.mjs} +661 -107
  38. package/dist/{device-lease-DpoS36_u.mjs → device-lease-Cu7PtQpZ.mjs} +9 -9
  39. package/dist/{device-lease-run-B8YltIH_.mjs → device-lease-run-D38SnZtt.mjs} +4 -4
  40. package/dist/{device-pool-3o7s5lo4.mjs → device-pool-CP4rAsHx.mjs} +3 -3
  41. package/dist/{device-remote-hFSkpfQu.mjs → device-remote-B5GiUifk.mjs} +15 -16
  42. package/dist/{doctor-CFv1fCrF.mjs → doctor-PRJH94v6.mjs} +61 -34
  43. package/dist/doctor-watchman-wZhyTdp4.mjs +259 -0
  44. package/dist/{error-diagnostics-C-NMnhrk.mjs → error-diagnostics--v5HGOU0.mjs} +11 -11
  45. package/dist/{exec-CaErVv7t.mjs → exec-i8GDPwq9.mjs} +93 -6
  46. package/dist/{gc-DEmkg3Xh.mjs → gc-CyHMcKcn.mjs} +25 -471
  47. package/dist/{guide-CSmhMTf8.mjs → guide-dRaQJJk9.mjs} +681 -507
  48. package/dist/{hosted-android-E1Heoqnv.mjs → hosted-android-Bs7fytj7.mjs} +3 -3
  49. package/dist/{hosted-client-Bp4knSwu.mjs → hosted-client-C5G4h_OJ.mjs} +2 -2
  50. package/dist/{hosted-ios-BnbeYOUD.mjs → hosted-ios-Bik035eL.mjs} +1 -1
  51. package/dist/{hosted-logs-OcgIBvCT.mjs → hosted-logs-CI9Az9a4.mjs} +9 -9
  52. package/dist/{hosted-macos-DcxKjtfH.mjs → hosted-macos-DABm3ScO.mjs} +5 -5
  53. package/dist/{hosted-native-1Ebbig4w.mjs → hosted-native-DbV2aUVw.mjs} +13 -9
  54. package/dist/{idle-shutdown-IGyNV8Cr.mjs → idle-shutdown-DYiMBn34.mjs} +7 -8
  55. package/dist/{ios-DSfnPfse.mjs → ios-BWbHFZVz.mjs} +19 -7
  56. package/dist/{ios-Cr1h5gnO.mjs → ios-DCrkgXEM.mjs} +1 -1
  57. package/dist/ios-DYUr9LGc.mjs +8 -0
  58. package/dist/ios-ITYno9rO.mjs +2241 -0
  59. package/dist/{ios-device-pAN4t54-.mjs → ios-device-CJ_ZOGky.mjs} +3 -3
  60. package/dist/{ios-device-Ee7sDXfp.mjs → ios-device-CrW8aMb5.mjs} +1 -1
  61. package/dist/{ios-state-8L3lgum6.mjs → ios-state-By0XuLTQ.mjs} +1 -1
  62. package/dist/{launch-verify-lTnWZikR.mjs → launch-verify-DCveSE6d.mjs} +5 -5
  63. package/dist/{logs-BAaS7gS2.mjs → logs-Bao1HOMy.mjs} +13 -13
  64. package/dist/{macos-BIRQS90f.mjs → macos-ciyBdTY5.mjs} +194 -132
  65. package/dist/macos-nIOATJmR.mjs +2 -0
  66. package/dist/macos-run.mjs +1 -1
  67. package/dist/maintenance-run.mjs +349 -47
  68. package/dist/manifest-CX0d1IkZ.mjs +148 -0
  69. package/dist/{metro-g8NqiJp-.mjs → metro-DI2AjPF_.mjs} +196 -43
  70. package/dist/{metro-gateway-C-ijGI2F.mjs → metro-gateway-BxpJLIwh.mjs} +4 -4
  71. package/dist/{metro-store-CDDZHtPl.mjs → metro-store-BAHFcJm6.mjs} +16 -2
  72. package/dist/{build-plan-BDsSi09V.mjs → miss-reason-CjQCOKqq.mjs} +207 -249
  73. package/dist/{named-ports-C8m8EQs2.mjs → named-ports-B4iWH4E-.mjs} +70 -8
  74. package/dist/{native-runtime-BEK171xQ.mjs → native-runtime-BGxsbfny.mjs} +6 -6
  75. package/dist/{ndjson-PclOIwVY.mjs → ndjson-LGZAMsqa.mjs} +8 -4
  76. package/dist/offload-worker.d.mts +3 -45
  77. package/dist/offload-worker.mjs +11 -11
  78. package/dist/{ownership-DyRQru0q.mjs → ownership-EB0ySdGK.mjs} +3 -3
  79. package/dist/{page-QF_Ke10s.mjs → page-Bv9s2KwY.mjs} +1 -1
  80. package/dist/placement-log-Dxe34rJm.mjs +88 -0
  81. package/dist/plan-placement-BVY59qa8.mjs +290 -0
  82. package/dist/{ports-4nYqxPWC.mjs → ports-ByPc0_97.mjs} +3 -3
  83. package/dist/{prebuild-D7RUMkwN.mjs → prebuild-BKJ3wJI1.mjs} +5 -5
  84. package/dist/preview-BbSottmO.mjs +986 -0
  85. package/dist/{rolldown-runtime-BsOwBuO_.mjs → process-identity-Biv3arCO.mjs} +11 -1
  86. package/dist/project-B5eQ1USs.mjs +612 -0
  87. package/dist/{pull-request-pxnDCQzn.mjs → pull-request-IHNdMnG8.mjs} +1 -1
  88. package/dist/pull-requests.mjs +1 -1
  89. package/dist/react-native-ios-BMh2i25I.mjs +2 -0
  90. package/dist/react-native-ios-CSpIxexZ.mjs +2083 -0
  91. package/dist/{recordings-BNgsD1Tr.mjs → recordings-Bv8McZN4.mjs} +1 -1
  92. package/dist/{reload-DcRxj3qG.mjs → reload-rAPdqeRR.mjs} +14 -15
  93. package/dist/{remote-cache-Ci4DQYYj.mjs → remote-cache-N3hAEaAL.mjs} +5 -5
  94. package/dist/{run-CkE9y0nc.mjs → run-lAkle1-c.mjs} +5 -5
  95. package/dist/{server-bare-BkrSxSsZ.mjs → server-bare-CkIjnegq.mjs} +5 -6
  96. package/dist/server-expo-DGsdUGX2.mjs +2 -0
  97. package/dist/{server-expo-CHTyXD0G.mjs → server-expo-n3tUi3Em.mjs} +5 -6
  98. package/dist/{settings-SR9OmW9h.mjs → settings-2am7TSxp.mjs} +5 -5
  99. package/dist/{settings-Cfd-0r2d.mjs → settings-CxgngUZk.mjs} +116 -103
  100. package/dist/{settings-BBpMcDbD.mjs → settings-Djl-mpjX.mjs} +1 -1
  101. package/dist/settings.schema.json +198 -9
  102. package/dist/{simslim-BWNrc3M3.mjs → simslim-D9LkJxIO.mjs} +7 -7
  103. package/dist/{slot-launch-DmjBmpQV.mjs → slot-launch-HV_KtPIw.mjs} +6 -6
  104. package/dist/{spawn-claims-D0XfSe8u.mjs → spawn-claims-Kqiifsk2.mjs} +1 -1
  105. package/dist/{spawn-entry-jw19m8Nl.mjs → spawn-entry-Dcb7sDUz.mjs} +1 -0
  106. package/dist/{stage-CzaiwFsI.mjs → stage-BgaZJVZY.mjs} +14 -3
  107. package/dist/{start-AlfCPRVU.mjs → start-D8NbxNBb.mjs} +1 -1
  108. package/dist/{start-DUz3mYdb.mjs → start-DtxthMfI.mjs} +34 -27
  109. package/dist/{state-PeQiJuIu.mjs → state-D2KtnALG.mjs} +4 -4
  110. package/dist/{state-DyaNTgfR.mjs → state-Tp4uImDS.mjs} +5 -3
  111. package/dist/{state-B4PQFXMW.d.mts → state-lKh8shBp.d.mts} +2 -3
  112. package/dist/{stats-Bq4fJOdB.mjs → stats-8EJ5ivFT.mjs} +6 -6
  113. package/dist/{status-DlKvVJBE.mjs → status-BEeL6IKz.mjs} +6 -4
  114. package/dist/{status-BA2pehwf.mjs → status-BOyp0CUl.mjs} +31 -34
  115. package/dist/{stim-desktop-Cnz8CPnl.mjs → stim-desktop-C65jk_q2.mjs} +1 -1
  116. package/dist/{stim-installations-QMEI32v1.mjs → stim-installations-DbmUjsLv.mjs} +1 -1
  117. package/dist/stop-D0UIpZuh.mjs +72 -0
  118. package/dist/{stop-zF1y04f2.mjs → stop-DRipAg-e.mjs} +2 -2
  119. package/dist/{stop-DQIasgKp.mjs → stop-zDlknFoz.mjs} +79 -33
  120. package/dist/supervisor-run.d.mts +24 -22
  121. package/dist/supervisor-run.mjs +21 -22
  122. package/dist/{support-CsJNVfOc.mjs → support-CNqYkV0y.mjs} +7 -7
  123. package/dist/{support-WvD__tSV.mjs → support-DsNaFg6D.mjs} +5 -5
  124. package/dist/swiftpm-macos-aJzPAj1t.mjs +119 -0
  125. package/dist/{toolchain-DNyR3NPq.mjs → toolchain-C3xSoyUl.mjs} +475 -269
  126. package/dist/{trigger-Bemu8ytw.mjs → trigger-CAhmG-4s.mjs} +6 -6
  127. package/dist/trigger-CoalsMTV.mjs +2 -0
  128. package/dist/{warm-progress-DF4JRvYI.mjs → warm-progress-pFLB2e6P.mjs} +135 -38
  129. package/dist/{status-CzS4bPO9.mjs → watchman-BL1IdOtq.mjs} +75 -7
  130. package/dist/web-DFpFeZu5.mjs +2 -0
  131. package/dist/web-DbbrPUn0.mjs +127 -0
  132. package/dist/web-run.mjs +10 -10
  133. package/dist/{workspace-state-DqcCbpE7.mjs → workspace-state-CR9X86xJ.mjs} +3 -3
  134. package/dist/{ownership-BMLqyBgJ.mjs → workspaces-Djb2gfi9.mjs} +661 -23
  135. package/dist/{worktree-Be_7NLKy.mjs → worktree-BL4M1rhB.mjs} +252 -50
  136. package/dist/{worktree-j3IcFAI5.mjs → worktree-DV-A0LNL.mjs} +1 -1
  137. package/package.json +10 -5
  138. package/shim/bundle-response.cjs +2 -1
  139. package/shim/bundle-response.d.cts +1 -1
  140. package/shim/expo-metro-config.cjs +1 -1
  141. package/dist/build-progress-D0WkjCPd.mjs +0 -1036
  142. package/dist/build-slots-41v_d2x9.mjs +0 -142
  143. package/dist/cli-CYXb29oE.mjs +0 -51
  144. package/dist/deps-iKw0eD4P.mjs +0 -438
  145. package/dist/device-ios-C2Um-XUR.mjs +0 -412
  146. package/dist/errors-B6W7FkxQ.mjs +0 -15
  147. package/dist/guide-status-Du-ZQ3FD.mjs +0 -125
  148. package/dist/idle-BXG__1BA.mjs +0 -176
  149. package/dist/in-use-CvGOUn-x.mjs +0 -130
  150. package/dist/ios-BJ4XUSe1.mjs +0 -3867
  151. package/dist/native-run-D1Q56rAD.mjs +0 -158
  152. package/dist/preview-B-g9d7kV.mjs +0 -318
  153. package/dist/process-identity-BmRm1qV0.mjs +0 -12
  154. package/dist/project-D47Rh0ly.mjs +0 -276
  155. package/dist/server-expo-CeakhI8P.mjs +0 -2
  156. package/dist/state-BKa8wNN5.mjs +0 -148
  157. package/dist/stop-BIiM49EY.mjs +0 -48
  158. package/dist/stop-cause-rhmGfwvt.mjs +0 -97
  159. package/dist/trigger-CXts6qt1.mjs +0 -2
  160. package/dist/watchman-APYjXSQa.mjs +0 -48
  161. package/dist/workspace-process-lock-2mNzOlaB.mjs +0 -58
  162. package/dist/workspaces-Bcib97-6.mjs +0 -306
@@ -1,47 +1,47 @@
1
- import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
- import { D as withConfigLock$1, H as projectDeviceSlots, _ as loadConfig$1, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, k as acquireAvdClaim, p as getProject, t as allConsolePortsAndSerials, w as setDevice, z as deviceSlotPlatforms } from "./config-D0DbpZtM.mjs";
3
- import { n as ownership_claim_exports } from "./process-identity-BmRm1qV0.mjs";
1
+ import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
2
+ import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
4
3
  import { r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
5
- import { i as formatDuration, l as phaseLine, m as shortHash, u as plural } from "./command-output-CDAIFD-8.mjs";
6
- import { Tt as removeTemporaryEntry, a as androidAvdConfigSetting, at as gitCommonDirOnDisk, c as androidDataPartitionSizeGbSetting, wt as makeTemporaryDirectory } from "./settings-Cfd-0r2d.mjs";
7
- import { u as ownedDeviceLabel } from "./project-D47Rh0ly.mjs";
8
- import { o as pidExists } from "./metro-g8NqiJp-.mjs";
9
- import { d as sharedBuildCache } from "./workspace-state-DqcCbpE7.mjs";
10
- import { o as peekBudget } from "./budget-DfcgFdQB.mjs";
11
- import { C as diffFingerprintSources, I as storedSources, w as entryDir, y as artifactIn } from "./device-lease-DpoS36_u.mjs";
12
- import { A as listAvds, B as ownedAvdSystemImage, E as getAvdNameForSerial, F as ownedAvdDeviceProfile, J as resolveOwnedAvdSerial, L as ownedAvdMatchesConfiguration, O as listAdbDevices, P as nextConsolePort, R as ownedAvdName, W as pickDefaultSystemImage, b as createOwnedAvd, f as assertOwnedAvdStopped, ft as parkedMaxSetting, g as avdPoolConfiguration, j as listInstalledSystemImages, n as OWNED_AVD_CONFIG_DEFAULTS, pt as readParked, st as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, ut as isLegacyDeletionClaim, v as bootAndroidEmulator, y as configureNewOwnedAvd } from "./android-B_YNZy61.mjs";
13
- import { j as readHostMemoryPressure, u as listAllIosSims } from "./ios-DSfnPfse.mjs";
14
- import { _ as teardownParkedAvd, m as teardownOwnedAvd } from "./ownership-BMLqyBgJ.mjs";
15
- import { o as estimateBuild, p as readStats$1 } from "./build-progress-D0WkjCPd.mjs";
16
- import { b as tailLines, u as HEARTBEAT_INTERVAL_MS, y as startBuildHeartbeat } from "./toolchain-DNyR3NPq.mjs";
17
- import { t as cleanLine } from "./server-expo-CHTyXD0G.mjs";
18
- import { f as namedBuildMachine, m as resolveBuildMachine, v as hostingMachines } from "./client-SvBdgObD.mjs";
19
- import { a as call, o as connectHost } from "./hosted-client-Bp4knSwu.mjs";
20
- import { t as clearDeviceIdleShutdown } from "./idle-shutdown-IGyNV8Cr.mjs";
21
- import { i as countLiveOwnedDevices, n as DeviceAdmissionRefusal, p as withDeviceBootAdmission, s as peekDeviceSlots } from "./device-capacity-ZC4XSZ4R.mjs";
22
- import { i as staleNativeDirRefusal } from "./prebuild-D7RUMkwN.mjs";
23
- import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-C2Um-XUR.mjs";
24
- import { r as readHostedNative, s as writeHostedNative } from "./ios-state-8L3lgum6.mjs";
25
- import { n as prepareHostedNative } from "./hosted-native-1Ebbig4w.mjs";
26
- import { a as easAuthNote } from "./remote-cache-Ci4DQYYj.mjs";
27
- import { t as reconcileSimSlim } from "./simslim-BWNrc3M3.mjs";
28
- import { randomUUID } from "node:crypto";
4
+ import { l as phaseLine } from "./command-output-Bt8ygHE7.mjs";
5
+ import { D as withConfigLock$1, H as projectDeviceSlots, _ as loadConfig$1, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, k as acquireAvdClaim, p as getProject, t as allConsolePortsAndSerials, w as setDevice, z as deviceSlotPlatforms } from "./config-DC5jEtd1.mjs";
6
+ import { d as sharedBuildCache } from "./workspace-state-CR9X86xJ.mjs";
7
+ import { E as readMetroTunnel, O as readRemoteSession, o as ownedDeviceLabel } from "./project-B5eQ1USs.mjs";
8
+ import { Ct as removeTemporaryEntry, J as planMetroReach, St as makeTemporaryDirectory, a as androidAvdConfigSetting, c as androidDataPartitionSizeGbSetting, q as detectProviders, rt as gitCommonDirOnDisk } from "./settings-CxgngUZk.mjs";
9
+ import { s as pidExists } from "./metro-DI2AjPF_.mjs";
10
+ import { s as peekBudget } from "./budget-Dz-kyXLv.mjs";
11
+ import { A as teardownParkedAvd, D as teardownOwnedAvd } from "./workspaces-Djb2gfi9.mjs";
12
+ import { C as diffFingerprintSources, I as storedSources } from "./device-lease-Cu7PtQpZ.mjs";
13
+ import { A as listAvds, B as ownedAvdSystemImage, E as getAvdNameForSerial, F as ownedAvdDeviceProfile, J as resolveOwnedAvdSerial, L as ownedAvdMatchesConfiguration, O as listAdbDevices, P as nextConsolePort, R as ownedAvdName, W as pickDefaultSystemImage, b as createOwnedAvd, f as assertOwnedAvdStopped, ft as parkedMaxSetting, g as avdPoolConfiguration, j as listInstalledSystemImages, n as OWNED_AVD_CONFIG_DEFAULTS, pt as readParked, st as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, ut as isLegacyDeletionClaim, v as bootAndroidEmulator, y as configureNewOwnedAvd } from "./android-BdQC6zs1.mjs";
14
+ import { M as readHostMemoryPressure, d as listAllIosSims } from "./ios-BWbHFZVz.mjs";
15
+ import { E as namedBuildMachine, N as hostingMachines, k as resolveBuildMachine } from "./client-CuUo8Nvg.mjs";
16
+ import { t as clearDeviceIdleShutdown } from "./idle-shutdown-DYiMBn34.mjs";
17
+ import { i as countLiveOwnedDevices, n as DeviceAdmissionRefusal, p as withDeviceBootAdmission, s as peekDeviceSlots } from "./device-capacity-BoN1jQkO.mjs";
18
+ import { E as startBuildHeartbeat, O as tailLines, h as HEARTBEAT_INTERVAL_MS } from "./toolchain-C3xSoyUl.mjs";
19
+ import { t as cleanLine } from "./server-expo-n3tUi3Em.mjs";
20
+ import { a as call, o as connectHost } from "./hosted-client-C5G4h_OJ.mjs";
21
+ import { r as readHostedNative, s as writeHostedNative } from "./ios-state-By0XuLTQ.mjs";
22
+ import { n as prepareHostedNative } from "./hosted-native-DbV2aUVw.mjs";
23
+ import { f as resolveEasCliBin, s as isEasAuthFailureText } from "./remote-cache-N3hAEaAL.mjs";
24
+ import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-B2ruohE-.mjs";
25
+ import { _ as MIN_EAS_CLI_SIMULATOR_VERSION, g as MIN_EAS_CLI_DEVICE_VERSION, s as readInstalledEasCliVersion, v as easCliSupport } from "./device-remote-B5GiUifk.mjs";
26
+ import { t as reconcileSimSlim } from "./simslim-D9LkJxIO.mjs";
29
27
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
30
28
  import { basename, dirname, join, relative } from "node:path";
31
- import { LAST_BUILD_KEYS, isJsonObject, loadConfig, machineCapacity, parseHostedChoice, parseHostedNativeOffer, readWorkspaceState } from "@stim-cli/core/state";
32
- import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
33
- import { captureProcessIdentity } from "@stim-cli/core/process-identity";
29
+ import { LAST_BUILD_KEYS, automaticMachineEnabled, isJsonObject, loadConfig, machineCapacity, parseHostedChoice, parseHostedNativeOffer, readWorkspaceState } from "@stim-cli/core/state";
34
30
  import chalk from "chalk";
35
31
  import { isDeepStrictEqual } from "node:util";
32
+ import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
33
+ import { captureProcessIdentity } from "@stim-cli/core/process-identity";
34
+ import { randomUUID } from "node:crypto";
36
35
  import * as expoFingerprint from "@expo/fingerprint";
37
- import { resolveTieredBuild } from "@stim-cli/cache";
38
36
  import { request } from "node:http";
39
37
  //#region src/device-host/placement.ts
40
- function local$1(reason, skipped = []) {
38
+ function local$1(code, reason, skipped = [], atCapacity = false) {
41
39
  return {
42
40
  kind: "local",
41
+ code,
43
42
  reason,
44
- skipped
43
+ skipped,
44
+ ...atCapacity ? { atCapacity: true } : {}
45
45
  };
46
46
  }
47
47
  function decideDevicePlacement(inputs) {
@@ -50,6 +50,7 @@ function decideDevicePlacement(inputs) {
50
50
  const reason = `recorded session on ${inputs.sticky.machine}`;
51
51
  return {
52
52
  kind: "host",
53
+ code: "sticky",
53
54
  reason,
54
55
  machines: [{
55
56
  machine: inputs.sticky.machine,
@@ -60,30 +61,62 @@ function decideDevicePlacement(inputs) {
60
61
  }
61
62
  return {
62
63
  kind: "local",
64
+ code: "sticky",
63
65
  reason: "this workspace's device runs here",
64
66
  skipped: []
65
67
  };
66
68
  }
67
- const { platform, here, offers, buildMachine, noWait } = inputs;
69
+ const { platform, here, offers, buildMachine, noWait, eas } = inputs;
68
70
  const { count, max, queued } = here.devices;
69
- const cannotTake = !(max === 0 || count !== null && count < max) || queued > 0;
71
+ const room = max === 0 || count !== null && count < max;
72
+ const localEnabled = here.localEnabled !== false;
73
+ const cannotTake = !localEnabled || !room || queued > 0;
74
+ const atCapacity = count !== null && (!room || queued > 0);
70
75
  const usage = max > 0 ? `${count} of ${max} devices in use` : `${count} devices in use, no device cap`;
71
- const localReason = count === null ? "cannot tell how many devices run here; local boot admission decides" : cannotTake ? `${usage}${queued ? `, ${queued} runs queued ahead` : ""}` : here.budgetRefusal ?? (here.memoryPressure !== "normal" ? `host memory pressure ${here.memoryPressure ?? "unknown"} here` : `load ${here.loadPerCore.toFixed(1)}/core here, ${usage}`);
72
- if (!offers.length) return local$1("no remote Macs configured; " + localReason);
73
- if (count === null) return local$1(localReason);
74
- if (!cannotTake && here.memoryPressure === "normal" && !here.budgetRefusal && here.loadPerCore < here.maxLoadPerCore) return local$1(localReason);
76
+ const localReason = !localEnabled ? "local is disabled in remote.devicePoolDisabled" : count === null ? "cannot tell how many devices run here; local boot admission decides" : cannotTake ? `${usage}${queued ? `, ${queued} runs queued ahead` : ""}` : here.budgetRefusal ?? (here.memoryPressure !== "normal" ? `host memory pressure ${here.memoryPressure ?? "unknown"} here` : `load ${here.loadPerCore.toFixed(1)}/core here, ${usage}`);
77
+ const nowhere = (code, reason, skipped = [], waiting = "") => {
78
+ if (!localEnabled && !atCapacity) return {
79
+ kind: "refused",
80
+ code: "pool-unavailable",
81
+ reason,
82
+ skipped
83
+ };
84
+ if (!cannotTake || count === null) return local$1(code, reason + waiting, skipped);
85
+ if (eas?.usable) return {
86
+ kind: "eas",
87
+ code: "eas-fallback",
88
+ reason: `${reason}; EAS Simulator (remote.easFallback)`,
89
+ skipped
90
+ };
91
+ const why = eas ? [...skipped, {
92
+ machine: "eas",
93
+ code: eas.code,
94
+ reason: eas.reason
95
+ }] : skipped;
96
+ return localEnabled ? local$1(code, reason + waiting, why, true) : {
97
+ kind: "refused",
98
+ code: "pool-unavailable",
99
+ reason,
100
+ skipped: why,
101
+ atCapacity: true
102
+ };
103
+ };
104
+ if (!offers.length) return nowhere("no-remote-mac", "no remote Macs configured; " + localReason);
105
+ if (localEnabled && count === null) return local$1("device-count-unknown", localReason);
106
+ if (!cannotTake && here.memoryPressure === "normal" && !here.budgetRefusal && here.loadPerCore < here.maxLoadPerCore) return local$1("this-mac-free", localReason);
75
107
  const skipped = [];
76
108
  const admitted = [];
77
109
  offers.forEach((probe, index) => {
78
110
  let reason = null;
111
+ let code = "unreachable";
79
112
  if ("failure" in probe) reason = probe.failure;
80
113
  else {
81
114
  const { offer } = probe;
82
- if (offer.declined !== null) reason = `declined: ${offer.declined}`;
83
- else if (offer.platform !== platform || !offer.choice) reason = `no matching ${platform} device choice`;
84
- else if (offer.resources.memoryPressure !== "normal") reason = "host memory pressure unknown or elevated";
85
- else if (offer.capacity.available === 0) reason = "no hosted device capacity available";
86
- else if (!cannotTake && (offer.resources.loadPerCore === null || offer.resources.loadPerCore >= here.loadPerCore)) reason = offer.resources.loadPerCore === null ? "host load unknown while this Mac has room" : "host is not less loaded than this Mac";
115
+ if (offer.declined !== null) [code, reason] = ["declined", `declined: ${offer.declined}`];
116
+ else if (offer.platform !== platform || !offer.choice) [code, reason] = ["no-matching-device", `no matching ${platform} device choice`];
117
+ else if (offer.resources.memoryPressure !== "normal") [code, reason] = ["memory", "host memory pressure unknown or elevated"];
118
+ else if (offer.capacity.available === 0) [code, reason] = ["no-capacity", "no hosted device capacity available"];
119
+ else if (!cannotTake && (offer.resources.loadPerCore === null || offer.resources.loadPerCore >= here.loadPerCore)) [code, reason] = ["load", offer.resources.loadPerCore === null ? "host load unknown while this Mac has room" : "host is not less loaded than this Mac"];
87
120
  else admitted.push({
88
121
  machine: probe.machine,
89
122
  offer,
@@ -92,17 +125,19 @@ function decideDevicePlacement(inputs) {
92
125
  }
93
126
  if (reason) skipped.push({
94
127
  machine: probe.machine,
128
+ code,
95
129
  reason
96
130
  });
97
131
  });
98
132
  admitted.sort((a, b) => Number(b.machine === buildMachine) - Number(a.machine === buildMachine) || (a.offer.resources.loadPerCore ?? Infinity) - (b.offer.resources.loadPerCore ?? Infinity) || b.offer.resources.memoryFreeBytes - a.offer.resources.memoryFreeBytes || a.index - b.index);
99
- if (!admitted.length) return local$1(`${localReason}; no host admits${cannotTake && !noWait ? "; waiting locally if needed" : ""}`, skipped);
133
+ if (!admitted.length) return nowhere("no-host-admits", `${localReason}; no host admits`, skipped, localEnabled && cannotTake && !noWait ? "; waiting locally if needed" : "");
100
134
  const machines = admitted.map(({ machine, offer }) => ({
101
135
  machine,
102
136
  reason: `${localReason}; ${machine}${machine === buildMachine ? " is the explicit remote Mac," : ""} load ${offer.resources.loadPerCore === null ? "unknown" : offer.resources.loadPerCore.toFixed(1) + "/core"}`
103
137
  }));
104
138
  return {
105
139
  kind: "host",
140
+ code: "placed",
106
141
  machines,
107
142
  reason: machines[0].reason,
108
143
  skipped
@@ -160,7 +195,7 @@ async function probeHost(machine, platform, selectors) {
160
195
  host?.connection.close();
161
196
  }
162
197
  }
163
- function hosted(target, reason, skipped = []) {
198
+ function hosted(target, code, reason, skipped = []) {
164
199
  target.selection = {
165
200
  selected: "auto",
166
201
  reason
@@ -172,20 +207,34 @@ function hosted(target, reason, skipped = []) {
172
207
  machine: target.host.machine,
173
208
  reason
174
209
  },
210
+ code,
175
211
  skipped
176
212
  };
177
213
  }
178
- function local(reason, skipped = []) {
214
+ function local(code, reason, skipped = []) {
179
215
  return {
180
216
  target: null,
181
217
  placement: {
182
218
  decision: "local",
183
219
  reason
184
220
  },
221
+ code,
185
222
  skipped
186
223
  };
187
224
  }
188
- async function automaticDevicePlacement({ root, slot, platform, selectors, buildMachine, noWait }, { machines = hostingMachines, read = readHostedNative, write = writeHostedNative, resume = prepareHostedNative, peek = () => peekDeviceSlots({
225
+ function viaEas(code, reason, skipped) {
226
+ return {
227
+ target: null,
228
+ placement: {
229
+ decision: "eas",
230
+ machine: "eas",
231
+ reason
232
+ },
233
+ code,
234
+ skipped
235
+ };
236
+ }
237
+ async function automaticDevicePlacement({ root, slot, platform, selectors, buildMachine, noWait, eas }, { machines = hostingMachines, read = readHostedNative, write = writeHostedNative, resume = prepareHostedNative, peek = () => peekDeviceSlots({
189
238
  platform,
190
239
  project: getProject(root),
191
240
  slot
@@ -200,6 +249,7 @@ async function automaticDevicePlacement({ root, slot, platform, selectors, build
200
249
  machine: recorded.machine,
201
250
  reason: recorded.reason ?? decideDevicePlacement({ sticky: { machine: recorded.machine } }).reason
202
251
  },
252
+ code: "sticky",
203
253
  skipped: [],
204
254
  sticky: true
205
255
  };
@@ -207,48 +257,134 @@ async function automaticDevicePlacement({ root, slot, platform, selectors, build
207
257
  }
208
258
  const devices = peek();
209
259
  if (devices.localLive) return {
210
- ...local(decideDevicePlacement({ sticky: { local: true } }).reason),
260
+ ...local("sticky", decideDevicePlacement({ sticky: { local: true } }).reason),
211
261
  sticky: true
212
262
  };
213
- const entries = machines();
214
- if (entries === null) throw Object.assign(/* @__PURE__ */ new Error("remote.machines is invalid. Run stim guide settings and correct it."), { code: "STIM_HOSTING_REFUSED" });
215
- const preference = resolveBuildMachine(buildMachine, process.env.STIM_REMOTE_BUILD, loadConfig$1()?.remote?.build);
263
+ const configured = machines();
264
+ if (configured === null) throw Object.assign(/* @__PURE__ */ new Error("remote.machines is invalid. Run stim guide settings and correct it."), { code: "STIM_HOSTING_REFUSED" });
265
+ const config = loadConfig$1();
266
+ const entries = configured.filter((machine) => automaticMachineEnabled("device", machine, config));
267
+ const preference = resolveBuildMachine(buildMachine, process.env.STIM_REMOTE_BUILD, config?.remote?.build);
216
268
  buildMachine = namedBuildMachine(preference) ? preference : void 0;
217
269
  const load = capacity();
218
270
  const here = {
271
+ localEnabled: automaticMachineEnabled("device", "local", config),
219
272
  loadPerCore: load.loadPerCore,
220
273
  maxLoadPerCore: load.maxLoadPerCore,
221
274
  memoryPressure: memory(),
222
275
  devices,
223
276
  budgetRefusal: await budget(root)
224
277
  };
225
- const early = decideDevicePlacement({
278
+ const inputs = (offers) => ({
226
279
  platform,
227
280
  here,
228
- offers: entries.map((machine) => ({
229
- machine,
230
- failure: "not probed"
231
- })),
281
+ offers,
232
282
  buildMachine,
233
283
  noWait
234
284
  });
235
- if (early.kind === "local" && early.skipped.length === 0) return local(early.reason);
236
- const probes = await Promise.all(entries.map((machine) => probe(machine, platform, selectors)));
237
- const decision = decideDevicePlacement({
238
- platform,
239
- here,
240
- offers: probes.map((each) => each.probe),
241
- buildMachine,
242
- noWait
285
+ const notProbed = entries.map((machine) => ({
286
+ machine,
287
+ failure: "not probed"
288
+ }));
289
+ const early = decideDevicePlacement(inputs(notProbed));
290
+ const probes = early.kind === "local" && early.skipped.length === 0 ? [] : await Promise.all(entries.map((machine) => probe(machine, platform, selectors)));
291
+ const offers = probes.length ? probes.map((each) => each.probe) : notProbed;
292
+ let decision = decideDevicePlacement(inputs(offers));
293
+ if ((decision.kind === "local" || decision.kind === "refused") && decision.atCapacity && eas) decision = decideDevicePlacement({
294
+ ...inputs(offers),
295
+ eas: await eas()
243
296
  });
244
- if (decision.kind === "local") return local(decision.reason, decision.skipped);
297
+ if (decision.kind === "refused") throw Object.assign(new Error(devicePlacementLine({
298
+ decision: "local",
299
+ reason: decision.reason
300
+ }, decision.skipped)), {
301
+ code: "STIM_HOSTING_REFUSED",
302
+ remedy: "Enable an available member in remote.devicePoolDisabled or select a machine explicitly."
303
+ });
304
+ if (decision.kind === "eas") return viaEas(decision.code, decision.reason, decision.skipped);
305
+ if (decision.kind === "local") return local(decision.code, decision.reason, decision.skipped);
245
306
  const target = probes.find((each) => each.probe.machine === decision.machines[0].machine).target;
246
- return hosted(target, decision.reason, decision.skipped);
307
+ return hosted(target, decision.code, decision.reason, decision.skipped);
247
308
  }
248
309
  function devicePlacementLine(placement, skipped) {
249
310
  return `${placement.machine ?? "local"}, ${placement.reason}${placement.decision !== "hosted" && skipped.length ? "; " + skipped.map((each) => `${each.machine}: ${each.reason}`).join("; ") : ""}`;
250
311
  }
251
312
  //#endregion
313
+ //#region src/engine/eas-fallback.ts
314
+ const AVAILABILITY_TIMEOUT_MS = 3e4;
315
+ function unusable(code, reason) {
316
+ return {
317
+ usable: false,
318
+ code,
319
+ reason
320
+ };
321
+ }
322
+ /** Reads `eas simulator:availability --json`: `{"available": true, ...}` on stdout, or a failure on stderr. */
323
+ function parseSimulatorAvailability(outcome) {
324
+ if ("failure" in outcome) {
325
+ if (outcome.timedOut) return unusable("eas-unavailable", "eas simulator:availability timed out");
326
+ const detail = outcome.failure.split("\n").map((line) => line.trim()).find((line) => line && !/is now available\.$|^(To upgrade|npm install|Proceeding with|\(node:|\(Use `node)/.test(line));
327
+ if (isEasAuthFailureText(outcome.failure)) return unusable("eas-logged-out", "eas-cli is not logged in (run eas login or set EXPO_TOKEN)");
328
+ return unusable("eas-unavailable", `eas simulator:availability failed${detail ? `: ${detail}` : ""}`);
329
+ }
330
+ let data = null;
331
+ try {
332
+ data = JSON.parse(outcome.stdout.slice(outcome.stdout.indexOf("{")));
333
+ } catch {}
334
+ if (typeof data !== "object" || data === null || typeof data.available !== "boolean") return unusable("eas-unavailable", "eas simulator:availability printed no availability");
335
+ return data.available ? { usable: true } : unusable("eas-not-enabled", "EAS Simulator is not enabled for this EAS account");
336
+ }
337
+ /**
338
+ * Whether this run could use an EAS Simulator the way `--remote eas` does, without starting a session or a build.
339
+ * Each refusal names what `--remote eas` would refuse later, so automatic placement falls through instead.
340
+ */
341
+ async function checkEasFallback({ root, platform, slot, release, isExpo, tunnelMode, publicUrl, deviceTypeFlag, localOnlyFlags, env = process.env, resolveBin = resolveEasCliBin, readVersion = readInstalledEasCliVersion, onPath = (bin) => getExecutor().findExecutable(bin) !== null, readTunnel = readMetroTunnel, readSession = readRemoteSession, metroPort = () => getProject(root)?.metroPort ?? null, availability = async (bin) => {
342
+ try {
343
+ return { stdout: await getExecutor().runFileAsync(bin, [
344
+ "simulator:availability",
345
+ "--json",
346
+ "--non-interactive"
347
+ ], {
348
+ cwd: root,
349
+ timeoutMs: AVAILABILITY_TIMEOUT_MS
350
+ }) };
351
+ } catch (error) {
352
+ const err = error;
353
+ return {
354
+ failure: String(err.stderr || err.message || error),
355
+ timedOut: err.code === "ETIMEDOUT"
356
+ };
357
+ }
358
+ } }) {
359
+ if (slot !== "default") return unusable("eas-named-slot", `an EAS Simulator takes only the default slot, not ${slot}`);
360
+ if (localOnlyFlags.length) return unusable("eas-local-flags", `${localOnlyFlags.join(" and ")} applies only to a ${platform} device on a Mac`);
361
+ const session = readSession(root);
362
+ if (session && session.platform !== platform) return unusable("eas-session-busy", `this workspace's EAS Simulator session ${session.sessionId} runs ${session.platform ?? "another platform"}`);
363
+ if (session && deviceTypeFlag?.trim() && session.deviceType !== deviceTypeFlag.trim()) return unusable("eas-session-busy", `this workspace's EAS Simulator session ${session.sessionId} runs ${session.deviceType ?? "the model EAS chose"}, not ${deviceTypeFlag.trim()}`);
364
+ if (!onPath("agent-device")) return unusable("eas-no-agent-device", "agent-device is not on PATH");
365
+ const bin = resolveBin(root);
366
+ if (!bin) return unusable("eas-no-cli", "eas-cli is not installed for this project or on PATH");
367
+ const versionOutput = readVersion(bin.file, root);
368
+ const minimum = platform === "ios" && deviceTypeFlag?.trim() ? MIN_EAS_CLI_DEVICE_VERSION : MIN_EAS_CLI_SIMULATOR_VERSION;
369
+ const { supported, version } = easCliSupport(versionOutput, minimum);
370
+ if (!supported) return unusable("eas-cli-too-old", `eas-cli ${version ?? "(unknown version)"} is older than ${minimum}`);
371
+ if (!release) {
372
+ const mode = tunnelMode ?? "auto";
373
+ if (mode === "off") return unusable("eas-metro-unreachable", "metro.tunnel is off, so an EAS Simulator cannot reach Metro");
374
+ const plan = planMetroReach({
375
+ mode,
376
+ metroPort: metroPort() ?? "unknown",
377
+ publicUrl: env["STIM_METRO_PUBLIC_URL"]?.trim() || publicUrl,
378
+ isExpo,
379
+ available: detectProviders(onPath, mode)
380
+ });
381
+ if ("failed" in plan) return unusable("eas-metro-unreachable", plan.failed);
382
+ if ("start" in plan && plan.start === "tailscale") return unusable("eas-metro-unreachable", "metro.tunnel is tailscale, which an EAS Simulator cannot reach");
383
+ if ("expoTunnel" in plan && readTunnel(root)?.kind !== "expo") return unusable("eas-metro-unreachable", "Metro has no Expo tunnel; run stim start --remote first");
384
+ }
385
+ return parseSimulatorAvailability(await availability(bin.file));
386
+ }
387
+ //#endregion
252
388
  //#region src/engine/metro-warmup.ts
253
389
  const WARMUP_TIMEOUT_MS = 6e4;
254
390
  async function requestLocal(url, platform, prefetch) {
@@ -891,7 +1027,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
891
1027
  function didSetUpDevice(device, remote) {
892
1028
  return remote ? void 0 : Boolean(device.setup || device.booting);
893
1029
  }
894
- async function ensureOwnedDevice({ platform, project, projectPath, slot, settingsRoot = projectPath, label = ownedDeviceLabel(projectPath), settings, flags = {}, note = () => {}, out = () => {}, logFile = null, alive = pidExists, configureAvd = configureNewOwnedAvd, teardownAvd = teardownOwnedAvd, reconcileIosSimulator = reconcileSimSlim }) {
1030
+ async function ensureOwnedDevice({ platform, project, projectPath, slot, settingsRoot = projectPath, label = ownedDeviceLabel(projectPath), settings, flags = {}, note = () => {}, out = () => {}, logFile = null, alive = pidExists, configureAvd = configureNewOwnedAvd, teardownAvd = teardownOwnedAvd, reconcileIosSimulator = reconcileSimSlim, simSnapshot }) {
895
1031
  clearDeviceIdleShutdown(projectPath, platform, slot);
896
1032
  if (slot && slot !== "default") label = `${label}-${slot}`;
897
1033
  const record = deviceSlotPlatforms(project, slot)?.[platform] ?? null;
@@ -905,7 +1041,8 @@ async function ensureOwnedDevice({ platform, project, projectPath, slot, setting
905
1041
  flags,
906
1042
  note,
907
1043
  out,
908
- reconcileIosSimulator
1044
+ reconcileIosSimulator,
1045
+ simSnapshot
909
1046
  });
910
1047
  return ensureOwnedAndroidDevice({
911
1048
  record,
@@ -1603,183 +1740,4 @@ function fingerprintErrorMissReason(message) {
1603
1740
  };
1604
1741
  }
1605
1742
  //#endregion
1606
- //#region src/commands/build-plan.ts
1607
- const DISCARD = {
1608
- file: "",
1609
- written: 0,
1610
- dropped: 0,
1611
- lastError: null,
1612
- write: () => true,
1613
- close: () => ({
1614
- file: "",
1615
- written: 0,
1616
- dropped: 0,
1617
- lastError: null
1618
- })
1619
- };
1620
- async function providerHit({ root, platform, cacheKey, providerConfig }, deps) {
1621
- if (!providerConfig) return null;
1622
- let destinationDir;
1623
- try {
1624
- destinationDir = makeTemporaryDirectory(root, "stim-plan-");
1625
- } catch (error) {
1626
- deps.note(chalk.yellow(phaseLine("cache", `provider not checked: ${error?.message || error}`)));
1627
- return null;
1628
- }
1629
- try {
1630
- const found = await resolveTieredBuild({
1631
- local: {
1632
- resolve: () => null,
1633
- store: () => null
1634
- },
1635
- loadProvider: () => deps.loadCacheProvider({
1636
- projectRoot: root,
1637
- config: providerConfig
1638
- }),
1639
- target: {
1640
- projectRoot: root,
1641
- platform,
1642
- key: cacheKey
1643
- },
1644
- destinationDir,
1645
- warn: (_code, message) => deps.note(chalk.yellow(phaseLine("cache", message)))
1646
- });
1647
- return found ? found.providerName ?? "the cache provider" : null;
1648
- } finally {
1649
- removeTemporaryEntry(destinationDir);
1650
- }
1651
- }
1652
- async function expoRemoteHit(lookup, deps) {
1653
- if (!lookup.expoRemote) return null;
1654
- const { root, platform, isExpo, fingerprint } = lookup;
1655
- const loaded = await deps.loadProjectProvider(root, { isExpo });
1656
- if (loaded?.unavailable) {
1657
- deps.note(chalk.yellow(phaseLine("cache", `provider not usable: ${loaded.unavailable}`)));
1658
- return null;
1659
- }
1660
- if (!loaded?.provider) return null;
1661
- const name = loaded.name ?? "the build cache provider";
1662
- if (name === "eas") {
1663
- const auth = deps.checkEasAuth({
1664
- projectRoot: root,
1665
- owner: loaded.owner || null
1666
- });
1667
- const authNote = easAuthNote(auth);
1668
- if (authNote) deps.note(chalk.yellow(phaseLine("cache", authNote)));
1669
- if (auth?.code === "logged-out") return null;
1670
- }
1671
- const hit = await deps.resolveRemote({
1672
- provider: loaded.provider,
1673
- platform,
1674
- projectRoot: root,
1675
- fingerprintHash: fingerprint,
1676
- runOptions: lookup.expoRemote.runOptions,
1677
- logWriter: DISCARD
1678
- });
1679
- if (hit?.timedOut) deps.note(chalk.yellow(phaseLine("cache", `${name} did not answer; counted as a miss`)));
1680
- else if (hit?.failed) deps.note(chalk.yellow(phaseLine("cache", `${name} could not be used: ${hit.failed}`)));
1681
- return hit?.appPath ? name : null;
1682
- }
1683
- async function planCachedBuild(lookup, deps) {
1684
- const { root, platform, isExpo, fingerprint, sources, cacheKey, cachePolicy } = lookup;
1685
- let cacheHit = false;
1686
- let provider = null;
1687
- if (cachePolicy.read) {
1688
- if (artifactIn(entryDir(platform, cacheKey))) cacheHit = "local";
1689
- else {
1690
- provider = (cachePolicy.remote ? await providerHit(lookup, deps) : null) ?? await expoRemoteHit(lookup, deps);
1691
- if (provider) cacheHit = "remote";
1692
- }
1693
- }
1694
- let prebuild = null;
1695
- let refusal = null;
1696
- let missReason;
1697
- if (!cacheHit) {
1698
- prebuild = deps.planPrebuild(root, platform, {
1699
- isExpo,
1700
- fingerprint,
1701
- sources
1702
- });
1703
- if (prebuild === "refuse") refusal = staleNativeDirRefusal(platform);
1704
- else if (cachePolicy.read) missReason = predictBuildMiss({
1705
- root,
1706
- platform,
1707
- current: {
1708
- hash: fingerprint,
1709
- sources
1710
- },
1711
- prebuild: prebuild === "generate" || prebuild === "regenerate" ? prebuild : null
1712
- });
1713
- }
1714
- return planPayload(lookup, {
1715
- fingerprint,
1716
- cacheKey,
1717
- cacheHit,
1718
- provider,
1719
- cacheSkipped: !cachePolicy.read,
1720
- prebuild,
1721
- ...missReason ? { missReason } : {},
1722
- refusal
1723
- });
1724
- }
1725
- function planPayload({ platform, slot, projectKey }, found) {
1726
- const { refusal, missReason, ...rest } = found;
1727
- const outcome = refusal ? null : found.cacheHit ? "hit" : "cold";
1728
- const estimate = outcome ? estimateBuild(readStats$1().record?.history?.[projectKey], platform, outcome) : {
1729
- expectedMs: null,
1730
- basis: 0
1731
- };
1732
- return {
1733
- platform,
1734
- ...slot === "default" ? {} : { slot },
1735
- ...rest,
1736
- outcome,
1737
- expectedMs: estimate.expectedMs,
1738
- basis: estimate.basis,
1739
- ...missReason ? { missReason } : {},
1740
- ...refusal ? { refusal } : {}
1741
- };
1742
- }
1743
- function cacheLine(plan) {
1744
- if (plan.refusal) return `the build would refuse with ${plan.refusal.code}`;
1745
- if (plan.cacheHit === "local") return "local cache hit";
1746
- if (plan.cacheHit === "remote") return `remote cache hit (${plan.provider})`;
1747
- return `${plan.cacheSkipped ? "cache reads are off" : "cache miss"}: compiles${plan.prebuild === "generate" || plan.prebuild === "regenerate" ? `, ${plan.prebuild}s the native dir` : ""}`;
1748
- }
1749
- function printPlan(plan, json) {
1750
- if (json) {
1751
- console.log(JSON.stringify(plan));
1752
- return;
1753
- }
1754
- const slot = plan.slot ? ` [${plan.slot}]` : "";
1755
- console.log(phaseLine("plan", `${plan.platform}${slot} ${shortHash(plan.fingerprint)} -> ${cacheLine(plan)}`));
1756
- if (plan.missReason) console.log(phaseLine("cache", `miss: ${plan.missReason.summary}`));
1757
- if (plan.refusal) {
1758
- console.log(phaseLine("error", plan.refusal.message));
1759
- console.log(phaseLine("remedy", plan.refusal.remedy));
1760
- return;
1761
- }
1762
- console.log(phaseLine("expect", plan.expectedMs === null ? `unknown: no ${plan.outcome} run of this project is recorded yet` : `~${formatDuration(plan.expectedMs)} (median of ${plural(plan.basis, `${plan.outcome} run`)})`));
1763
- }
1764
- function refusePlan({ code, message, remedy }, json, lines = []) {
1765
- console.error(chalk.red(phaseLine("error", message)));
1766
- for (const line of lines) console.error(chalk.dim(phaseLine("", line)));
1767
- console.error(chalk.dim(phaseLine("remedy", remedy)));
1768
- console.error(chalk.red(phaseLine("failed", code)));
1769
- if (json) console.log(JSON.stringify({
1770
- code,
1771
- message,
1772
- remedy
1773
- }));
1774
- process.exitCode = 1;
1775
- }
1776
- const PLAN_ONLY_REMEDY = "Drop the flag to plan the owned simulator or emulator build, or run the command without --plan.";
1777
- function planFlagRefusal(flag) {
1778
- return {
1779
- code: "STIM_BAD_ARG",
1780
- message: `${flag} does not apply to --plan, which predicts the next local build without choosing a device.`,
1781
- remedy: PLAN_ONLY_REMEDY
1782
- };
1783
- }
1784
- //#endregion
1785
- export { AvdRecoveryError as _, refusePlan as a, devicePlacementLine as b, skippedMissReason as c, refreshUpdatesManifestFile as d, swapJsBundle as f, AvdBootError as g, ensureOwnedDevice as h, printPlan as i, UPDATES_MANIFEST_NAME as l, ensureBooted as m, planFlagRefusal as n, explainBuildMiss as o, didSetUpDevice as p, planPayload as r, fingerprintErrorMissReason as s, planCachedBuild as t, detectEntryFile as u, warmMetro as v, automaticDevicePlacement as y };
1743
+ export { devicePlacementLine as _, UPDATES_MANIFEST_NAME as a, swapJsBundle as c, ensureOwnedDevice as d, AvdBootError as f, automaticDevicePlacement as g, checkEasFallback as h, skippedMissReason as i, didSetUpDevice as l, warmMetro as m, fingerprintErrorMissReason as n, detectEntryFile as o, AvdRecoveryError as p, predictBuildMiss as r, refreshUpdatesManifestFile as s, explainBuildMiss as t, ensureBooted as u, probeHost as v };