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,16 +1,16 @@
1
- import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
- import { C as saveConfig, D as withConfigLock$1, H as projectDeviceSlots, I as assignSlotDevice, U as removeSlotDevice, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as deviceSlotPlatforms } from "./config-D0DbpZtM.mjs";
3
- import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
4
- import { s as androidDataPartitionSizeBytes } from "./settings-Cfd-0r2d.mjs";
5
- import { o as pidExists, u as signalProcessTree } from "./metro-g8NqiJp-.mjs";
6
- import { n as readCreatedDevices$1, r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-CpvzBL25.mjs";
7
- import { n as settingDefault, r as stimDesktopInstalled, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-Cnz8CPnl.mjs";
1
+ import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
+ import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
3
+ import { C as saveConfig, D as withConfigLock$1, H as projectDeviceSlots, I as assignSlotDevice, U as removeSlotDevice, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as deviceSlotPlatforms } from "./config-DC5jEtd1.mjs";
4
+ import { s as androidDataPartitionSizeBytes } from "./settings-CxgngUZk.mjs";
5
+ import { d as signalProcessTree, s as pidExists } from "./metro-DI2AjPF_.mjs";
6
+ import { n as readCreatedDevices$1, r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-D0s26Hx5.mjs";
7
+ import { n as settingDefault, r as stimDesktopInstalled, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-C65jk_q2.mjs";
8
8
  import { join } from "node:path";
9
- import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
10
- import { homedir, tmpdir } from "os";
11
9
  import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, resolve as resolve$1 } from "path";
12
10
  import { ANDROID_EMULATOR_APPS, getParkedMax, loadConfig, settingDefinition } from "@stim-cli/core/state";
13
11
  import { isDeepStrictEqual } from "node:util";
12
+ import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
13
+ import { homedir, tmpdir } from "os";
14
14
  //#region src/devices/sim-pool.ts
15
15
  const POOL_SETTING_REMEDY = "Run `stim guide settings` for the device pool bounds and where it can be set.";
16
16
  function parkedMaxSetting(platform, options = {}) {
@@ -0,0 +1,4 @@
1
+ import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-Bt8ygHE7.mjs";
2
+ import { a as collectorLogFile, c as androidFacts, i as runAndroidOperation, l as lastBuildRecord, n as registerAndroid, o as killPreviousCollector, r as runAndroid, s as startCollector, t as androidCommand } from "./android-BXc6BmEi.mjs";
3
+ import { C as resolveSystemImage, _ as isReleaseVariant, c as androidSystemImageSetting, d as apkPackage, h as findAapt, i as NO_FINGERPRINT, l as androidVariantSetting, m as dumpApkManifest, p as displayPath, r as NO_DEVICE, s as androidDevClientScheme, u as apkDevClientFacts, v as noDeviceDiagnostic, w as resolveVariant, y as parseXmltree } from "./support-DsNaFg6D.mjs";
4
+ export { NO_DEVICE, NO_FINGERPRINT, androidDevClientScheme, androidFacts, androidSystemImageSetting, androidVariantSetting, apkDevClientFacts, apkPackage, collectorLogFile, androidCommand as default, displayPath, dumpApkManifest, findAapt, formatDuration, isReleaseVariant, killPreviousCollector, lastBuildRecord, noDeviceDiagnostic, parseXmltree, phaseLine, registerAndroid, resolveSystemImage, resolveVariant, runAndroid, runAndroidOperation, shortHash, startCollector };
@@ -1,5 +1,5 @@
1
- import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
- import { u as androidToolCwd } from "./android-B_YNZy61.mjs";
1
+ import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
+ import { u as androidToolCwd } from "./android-BdQC6zs1.mjs";
3
3
  //#region src/collector/android.ts
4
4
  const LEVEL_BY_LETTER = {
5
5
  V: "debug",
@@ -1,12 +1,12 @@
1
- import { d as getConfigDir } from "./config-D0DbpZtM.mjs";
2
- import { r as register } from "./cache-manifest-DnUHBJaU.mjs";
3
- import { u as ensureWorkspaceStorage, w as withDirLock$1 } from "./workspace-state-DqcCbpE7.mjs";
4
- import { createHash, randomUUID } from "node:crypto";
1
+ import { d as getConfigDir } from "./config-DC5jEtd1.mjs";
2
+ import { u as ensureWorkspaceStorage, w as withDirLock$1 } from "./workspace-state-CR9X86xJ.mjs";
3
+ import { r as register } from "./cache-manifest-DiwKSyv9.mjs";
5
4
  import { accessSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
6
5
  import { join } from "node:path";
7
- import { quotedPath } from "@stim-cli/core";
8
6
  import { isJsonObject, readJsonFile } from "@stim-cli/core/state";
9
7
  import { fileURLToPath, pathToFileURL } from "node:url";
8
+ import { quotedPath } from "@stim-cli/core";
9
+ import { createHash, randomUUID } from "node:crypto";
10
10
  //#region src/engine/android-cas.ts
11
11
  const CAS_TOOLCHAIN_FIELDS = [
12
12
  "clang",
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { t as getExecutor } from "./exec-CaErVv7t.mjs";
3
- import { createHash, randomUUID } from "node:crypto";
2
+ import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
4
3
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
5
4
  import { join } from "node:path";
5
+ import { createHash, randomUUID } from "node:crypto";
6
6
  import { once } from "node:events";
7
7
  //#region bin/android-cas-compiler.ts
8
8
  const context = process.env.STIM_ANDROID_CAS_CONTEXT;
@@ -0,0 +1,150 @@
1
+ import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
+ import { t as spawnEntry } from "./spawn-entry-Dcb7sDUz.mjs";
3
+ import { realpathSync } from "node:fs";
4
+ import { isAbsolute } from "node:path";
5
+ //#region src/api.ts
6
+ var StimError = class extends Error {
7
+ code;
8
+ remedy;
9
+ details;
10
+ constructor({ code, message, remedy = null, details }) {
11
+ super(message);
12
+ this.name = "StimError";
13
+ this.code = code;
14
+ this.remedy = remedy;
15
+ this.details = details;
16
+ }
17
+ };
18
+ /**
19
+ * Creates a client without starting processes or changing the caller's cwd, environment, or signal handlers.
20
+ * Each operation runs in a separate Stim worker. Resources remain workspace-owned until stop() is called.
21
+ */
22
+ function createStim(options) {
23
+ let projectRoot;
24
+ try {
25
+ projectRoot = realpathSync(options.projectRoot);
26
+ } catch (error) {
27
+ throw new StimError({
28
+ code: "STIM_NO_PROJECT",
29
+ message: `Could not resolve projectRoot ${options.projectRoot}: ${error instanceof Error ? error.message : String(error)}`,
30
+ remedy: "Pass the path to an existing, readable app directory."
31
+ });
32
+ }
33
+ for (const [name, path] of [["home", options.home], ["buildCache", options.buildCache]]) if (path !== void 0 && !isAbsolute(path)) throw new StimError({
34
+ code: "STIM_BAD_ARG",
35
+ message: `${name} must be an absolute path.`
36
+ });
37
+ const context = {
38
+ ...options,
39
+ projectRoot,
40
+ env: {
41
+ ...process.env,
42
+ ...options.home === void 0 ? {} : { STIM_HOME: options.home },
43
+ ...options.buildCache === void 0 ? {} : { STIM_BUILD_CACHE: options.buildCache },
44
+ FORCE_COLOR: "0"
45
+ }
46
+ };
47
+ return {
48
+ projectRoot,
49
+ run: (({ signal, ...request }) => invoke(context, {
50
+ operation: "run",
51
+ options: request
52
+ }, signal)),
53
+ stop({ signal, ...request } = {}) {
54
+ return invoke(context, {
55
+ operation: "stop",
56
+ options: request
57
+ }, signal);
58
+ },
59
+ diagnostics({ signal, ...request } = {}) {
60
+ if (request.tail !== void 0 && (!Number.isSafeInteger(request.tail) || request.tail < 0)) return Promise.reject(new StimError({
61
+ code: "STIM_BAD_ARG",
62
+ message: "tail must be a non-negative integer."
63
+ }));
64
+ return invoke(context, {
65
+ operation: "diagnostics",
66
+ options: request
67
+ }, signal);
68
+ }
69
+ };
70
+ }
71
+ function cancelled() {
72
+ return new StimError({
73
+ code: "STIM_CANCELLED",
74
+ message: "The Stim operation was cancelled."
75
+ });
76
+ }
77
+ function invoke(context, request, signal) {
78
+ if (signal?.aborted) return Promise.reject(cancelled());
79
+ return new Promise((resolve, reject) => {
80
+ const child = getExecutor().spawn(process.execPath, [spawnEntry("api-run")], {
81
+ cwd: context.projectRoot,
82
+ env: context.env,
83
+ stdio: [
84
+ "ignore",
85
+ "pipe",
86
+ "pipe",
87
+ "ipc"
88
+ ]
89
+ });
90
+ let response;
91
+ let transportError;
92
+ let callbackError;
93
+ let callbackFailed = false;
94
+ let stderr = "";
95
+ const abort = () => {
96
+ child.send?.({ operation: "cancel" }, (error) => {
97
+ if (error) child.kill("SIGINT");
98
+ });
99
+ };
100
+ signal?.addEventListener("abort", abort, { once: true });
101
+ if (signal?.aborted) abort();
102
+ const progress = (stream, message) => {
103
+ if (stream === "stderr") stderr = (stderr + message).slice(-16384);
104
+ if (!context.onProgress || callbackFailed) return;
105
+ try {
106
+ context.onProgress({
107
+ stream,
108
+ message
109
+ });
110
+ } catch (error) {
111
+ callbackError = error;
112
+ callbackFailed = true;
113
+ abort();
114
+ }
115
+ };
116
+ child.stdout?.setEncoding("utf8").on("data", (chunk) => progress("stdout", chunk));
117
+ child.stderr?.setEncoding("utf8").on("data", (chunk) => progress("stderr", chunk));
118
+ child.on("message", (message) => {
119
+ response = message;
120
+ });
121
+ child.on("error", (error) => {
122
+ transportError = error;
123
+ });
124
+ child.on("close", (code, exitSignal) => {
125
+ signal?.removeEventListener("abort", abort);
126
+ if (callbackFailed) return reject(callbackError);
127
+ if (signal?.aborted) return reject(cancelled());
128
+ if (transportError) return reject(new StimError({
129
+ code: "STIM_WORKER_FAILED",
130
+ message: transportError.message,
131
+ details: { stderr }
132
+ }));
133
+ if (response?.ok === false) return reject(new StimError(response.error));
134
+ if (code === 0 && response?.ok) return resolve(response.result);
135
+ reject(new StimError({
136
+ code: "STIM_WORKER_FAILED",
137
+ message: `Stim worker exited without a result (${exitSignal ?? code}).`,
138
+ details: { stderr }
139
+ }));
140
+ });
141
+ child.send?.({
142
+ ...request,
143
+ projectRoot: context.projectRoot
144
+ }, (error) => {
145
+ if (error) transportError = error;
146
+ });
147
+ });
148
+ }
149
+ //#endregion
150
+ export { createStim as n, StimError as t };
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,145 @@
1
+ import { t as StimError } from "./api-DIf_s86s.mjs";
2
+ import { y as refuseRelativeStimPaths } from "./config-DC5jEtd1.mjs";
3
+ import { x as workspaceLogsDir$1 } from "./workspace-state-CR9X86xJ.mjs";
4
+ import { i as runAndroidOperation } from "./android-BXc6BmEi.mjs";
5
+ import { r as runIosOperation } from "./ios-ITYno9rO.mjs";
6
+ import { n as runMacos } from "./macos-ciyBdTY5.mjs";
7
+ import { c as stopWorkspaceNow } from "./stop-zDlknFoz.mjs";
8
+ import { t as runWeb } from "./web-DbbrPUn0.mjs";
9
+ import { queryJsonLogs } from "@stim-cli/core/state";
10
+ //#region src/api-run.ts
11
+ async function dispatch({ projectRoot: root, ...request }) {
12
+ let directory;
13
+ try {
14
+ refuseRelativeStimPaths();
15
+ directory = workspaceLogsDir$1(root);
16
+ if (request.operation === "diagnostics") {
17
+ const { tail = 200, errors = false } = request.options;
18
+ return {
19
+ ok: true,
20
+ result: {
21
+ directory,
22
+ records: tail === 0 ? [] : queryJsonLogs({
23
+ dir: directory,
24
+ tail,
25
+ errorsOnly: errors
26
+ })
27
+ }
28
+ };
29
+ }
30
+ if (request.operation === "stop") {
31
+ const result = await stopWorkspaceNow({
32
+ root,
33
+ slot: request.options.slot
34
+ });
35
+ if ("refusal" in result) throw new StimError({
36
+ ...result.refusal,
37
+ details: result.remote
38
+ });
39
+ return {
40
+ ok: true,
41
+ result
42
+ };
43
+ }
44
+ const options = request.options;
45
+ switch (options.platform) {
46
+ case "ios": {
47
+ let error;
48
+ const result = await runIosOperation(root, options, {}, (failure) => {
49
+ error = failure;
50
+ });
51
+ if (!result) throw new StimError({
52
+ code: error?.code ?? "STIM_RUN_FAILED",
53
+ message: error?.message ?? "The iOS run failed.",
54
+ remedy: error?.remedy,
55
+ details: error
56
+ });
57
+ return {
58
+ ok: true,
59
+ result: {
60
+ platform: "ios",
61
+ facts: result.facts
62
+ }
63
+ };
64
+ }
65
+ case "android": {
66
+ const result = await runAndroidOperation(root, options);
67
+ if (!result.ok || !result.facts) throw new StimError({
68
+ code: result.error?.code ?? "STIM_RUN_FAILED",
69
+ message: result.error?.message ?? "The Android run failed.",
70
+ remedy: result.error?.remedy
71
+ });
72
+ return {
73
+ ok: true,
74
+ result: {
75
+ platform: "android",
76
+ facts: result.facts
77
+ }
78
+ };
79
+ }
80
+ case "macos": {
81
+ const record = await runMacos(root, console.error, void 0, options.remoteBuild);
82
+ return {
83
+ ok: true,
84
+ result: {
85
+ platform: "macos",
86
+ facts: {
87
+ product: record.product,
88
+ bundle: record.bundle,
89
+ bundleId: record.bundleId,
90
+ executable: record.executable,
91
+ pid: record.app?.pid ?? null,
92
+ launched: record.app !== void 0,
93
+ build: record.build,
94
+ logs: { dir: directory }
95
+ }
96
+ }
97
+ };
98
+ }
99
+ case "web": {
100
+ const result = await runWeb({
101
+ root,
102
+ headed: options.headed ?? false,
103
+ note: console.error
104
+ });
105
+ if (!result.ok) throw new StimError(result.error);
106
+ return {
107
+ ok: true,
108
+ result: {
109
+ platform: "web",
110
+ facts: result.facts
111
+ }
112
+ };
113
+ }
114
+ default: throw new StimError({
115
+ code: "STIM_BAD_ARG",
116
+ message: "Unknown Stim platform."
117
+ });
118
+ }
119
+ } catch (error) {
120
+ const failure = error;
121
+ return {
122
+ ok: false,
123
+ error: {
124
+ code: failure.code ?? "STIM_RUN_FAILED",
125
+ message: error instanceof Error ? error.message : String(error),
126
+ remedy: failure.remedy ?? null,
127
+ details: {
128
+ logs: directory,
129
+ cause: failure.details
130
+ }
131
+ }
132
+ };
133
+ }
134
+ }
135
+ function interrupt() {
136
+ if (!process.emit("SIGINT")) process.exit(130);
137
+ }
138
+ process.once("disconnect", interrupt);
139
+ process.on("message", async (request) => {
140
+ if (request.operation === "cancel") return interrupt();
141
+ const response = await dispatch(request);
142
+ process.send?.(response, () => process.exit(response.ok ? 0 : 1));
143
+ });
144
+ //#endregion
145
+ export {};
package/dist/api.d.mts ADDED
@@ -0,0 +1,218 @@
1
+ import "./state-lKh8shBp.mjs";
2
+ import { i as IosFacts, t as AndroidFacts } from "./build-facts-B87vo-Im.mjs";
3
+ import "./ndjson-Du3j0AQ9.mjs";
4
+ import { MacosBuild, NdjsonRecord, WebBrowserState, WebViewport } from "@stim-cli/core/state";
5
+ import { Command } from "commander";
6
+ import "@stim-cli/cache";
7
+ import { ChildProcess } from "node:child_process";
8
+ //#region src/engine/device-lease.d.ts
9
+ type LeasePlatform = "ios" | "android";
10
+ interface ReleasedLease {
11
+ platform: LeasePlatform;
12
+ id: string;
13
+ deviceName: string | null;
14
+ expiresAt: string;
15
+ }
16
+ //#endregion
17
+ //#region src/commands/stop.d.ts
18
+ interface SupervisorOutcome {
19
+ status: string;
20
+ pid?: number;
21
+ reason?: string;
22
+ port?: number | null;
23
+ mode?: string | null;
24
+ }
25
+ interface CollectorEntry {
26
+ platform: string;
27
+ pid: number | null;
28
+ status: string;
29
+ reason?: string;
30
+ }
31
+ interface CollectorsOutcome {
32
+ status: string;
33
+ entries: CollectorEntry[];
34
+ }
35
+ interface MetroOutcome {
36
+ status: string;
37
+ port?: number | null;
38
+ pid?: number | null;
39
+ reason?: string;
40
+ }
41
+ interface DeviceOutcomeEntry {
42
+ status: string;
43
+ label?: string;
44
+ reason?: string;
45
+ kind?: string | null;
46
+ remedy?: string;
47
+ }
48
+ interface DeviceOutcome {
49
+ [key: string]: DeviceOutcomeEntry | null | undefined;
50
+ ios: DeviceOutcomeEntry | null;
51
+ android: DeviceOutcomeEntry | null;
52
+ remote?: DeviceOutcomeEntry | null;
53
+ web?: DeviceOutcomeEntry | null;
54
+ }
55
+ interface PortOutcome {
56
+ status: string;
57
+ port?: number | null;
58
+ reason?: string;
59
+ }
60
+ interface StopOutcomes {
61
+ supervisor: SupervisorOutcome;
62
+ collectors: CollectorsOutcome;
63
+ metro: MetroOutcome;
64
+ device: DeviceOutcome;
65
+ macos?: {
66
+ status: string;
67
+ reason?: string;
68
+ };
69
+ port: PortOutcome;
70
+ metroTunnel: TunnelOutcome;
71
+ releasedLeases: ReleasedLease[];
72
+ }
73
+ interface StopResult {
74
+ ok: boolean;
75
+ outcomes: StopOutcomes;
76
+ summary: string;
77
+ }
78
+ interface TunnelOutcome {
79
+ status: string;
80
+ provider?: string;
81
+ reason?: string;
82
+ }
83
+ //#endregion
84
+ //#region src/web/launch.d.ts
85
+ type WebLaunched = true | "bundling" | "unverified";
86
+ //#endregion
87
+ //#region src/commands/web.d.ts
88
+ interface WebFacts extends WebBrowserState {
89
+ platform: "web";
90
+ reused: boolean;
91
+ launched: WebLaunched;
92
+ metroPort: number | null;
93
+ logs: {
94
+ dir: string;
95
+ };
96
+ durationMs: number;
97
+ }
98
+ //#endregion
99
+ //#region src/api/types.d.ts
100
+ type StimPlatform = "ios" | "android" | "macos" | "web";
101
+ interface StimProgress {
102
+ stream: "stdout" | "stderr";
103
+ message: string;
104
+ }
105
+ interface StimOptions {
106
+ /** Absolute or relative path to the app directory, resolved once when creating the client. */
107
+ projectRoot: string;
108
+ /** Absolute Stim state directory. Omit to use the caller's STIM_HOME or the default home. */
109
+ home?: string;
110
+ /** Absolute native artifact cache directory. Its coordinating home must be shared by all writers. */
111
+ buildCache?: string;
112
+ /**
113
+ * Receives output chunks without writing to the importing process's terminal.
114
+ * An exception cancels the operation and rejects it with that exception.
115
+ */
116
+ onProgress?: (event: StimProgress) => void;
117
+ }
118
+ interface NativeRunOptions {
119
+ slot?: string;
120
+ metroCheck?: boolean;
121
+ buildCache?: boolean;
122
+ remoteBuild?: string;
123
+ }
124
+ type StimRunOptions = ((NativeRunOptions & {
125
+ platform: "ios";
126
+ configuration?: string;
127
+ scheme?: string;
128
+ deviceType?: string;
129
+ runtime?: string;
130
+ }) | (NativeRunOptions & {
131
+ platform: "android";
132
+ variant?: string;
133
+ systemImage?: string;
134
+ deviceProfile?: string;
135
+ }) | {
136
+ platform: "macos";
137
+ remoteBuild?: string;
138
+ } | {
139
+ platform: "web";
140
+ headed?: boolean;
141
+ }) & {
142
+ signal?: AbortSignal;
143
+ };
144
+ type StimRunResult = {
145
+ platform: "ios";
146
+ facts: IosFacts;
147
+ } | {
148
+ platform: "android";
149
+ facts: AndroidFacts;
150
+ } | {
151
+ platform: "macos";
152
+ facts: {
153
+ product: string;
154
+ bundle: string;
155
+ bundleId: string;
156
+ executable: string;
157
+ pid: number | null;
158
+ launched: boolean;
159
+ build: MacosBuild;
160
+ logs: {
161
+ dir: string;
162
+ };
163
+ };
164
+ } | {
165
+ platform: "web";
166
+ facts: WebFacts;
167
+ };
168
+ interface StimStopOptions {
169
+ slot?: string;
170
+ signal?: AbortSignal;
171
+ }
172
+ type StimStopResult = StopResult;
173
+ interface StimDiagnosticsOptions {
174
+ /** Maximum number of records, default 200. Zero returns paths without records. */
175
+ tail?: number;
176
+ errors?: boolean;
177
+ signal?: AbortSignal;
178
+ }
179
+ interface StimDiagnostics {
180
+ directory: string;
181
+ records: NdjsonRecord[];
182
+ }
183
+ interface StimClient {
184
+ readonly projectRoot: string;
185
+ run<P extends StimPlatform>(options: StimRunOptions & {
186
+ platform: P;
187
+ }): Promise<Extract<StimRunResult, {
188
+ platform: P;
189
+ }>>;
190
+ run(options: StimRunOptions): Promise<StimRunResult>;
191
+ /** Stops this workspace, including resources created before a failed run. Use a fresh signal for cleanup. */
192
+ stop(options?: StimStopOptions): Promise<StimStopResult>;
193
+ /** Reads the existing local timeline; available even when run failed before creating any logs. */
194
+ diagnostics(options?: StimDiagnosticsOptions): Promise<StimDiagnostics>;
195
+ }
196
+ interface StimFailure {
197
+ code: string;
198
+ message: string;
199
+ remedy: string | null;
200
+ details?: unknown;
201
+ }
202
+ //#endregion
203
+ //#region src/api.d.ts
204
+ declare class StimError extends Error {
205
+ readonly code: string;
206
+ readonly remedy: string | null;
207
+ readonly details: unknown;
208
+ constructor({ code, message, remedy, details }: Omit<StimFailure, "remedy"> & {
209
+ remedy?: string | null;
210
+ });
211
+ }
212
+ /**
213
+ * Creates a client without starting processes or changing the caller's cwd, environment, or signal handlers.
214
+ * Each operation runs in a separate Stim worker. Resources remain workspace-owned until stop() is called.
215
+ */
216
+ declare function createStim(options: StimOptions): StimClient;
217
+ //#endregion
218
+ export { type StimClient, type StimDiagnostics, type StimDiagnosticsOptions, StimError, type StimOptions, type StimPlatform, type StimProgress, type StimRunOptions, type StimRunResult, type StimStopOptions, type StimStopResult, createStim };
package/dist/api.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { n as createStim, t as StimError } from "./api-DIf_s86s.mjs";
2
+ export { StimError, createStim };
@@ -1,6 +1,6 @@
1
- import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
- import { D as uninstallIosApp, M as deviceHoldsApk, N as deviceHoldsBundle, l as iosSimulatorFailureAdvice, m as listUserApps } from "./ios-DSfnPfse.mjs";
3
- import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-Ee7sDXfp.mjs";
1
+ import { n as debugLog, t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
+ import { N as deviceHoldsApk, O as uninstallIosApp, P as deviceHoldsBundle, h as listUserApps, u as iosSimulatorFailureAdvice } from "./ios-BWbHFZVz.mjs";
3
+ import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-CrW8aMb5.mjs";
4
4
  import { join } from "node:path";
5
5
  //#region src/engine/app-schemes.ts
6
6
  function schemesFromInfoPlist(plist) {
@@ -207,25 +207,45 @@ function parseLaunchedPid(text) {
207
207
  }
208
208
  function iosAppProcess(udid, bundleId, { exec = null } = {}) {
209
209
  const e = exec || getExecutor();
210
- let out = "";
210
+ const started = performance.now();
211
+ let pid;
212
+ let failure = {};
211
213
  try {
212
- out = e.runFile("xcrun", [
214
+ const out = e.runFile("xcrun", [
213
215
  "simctl",
214
216
  "spawn",
215
217
  udid,
216
218
  "launchctl",
217
219
  "list"
218
220
  ], { timeoutMs: 2e3 });
219
- } catch {
221
+ const label = `UIKitApplication:${bundleId}[`;
222
+ pid = null;
223
+ for (const line of out.split("\n")) {
224
+ if (!line.includes(label)) continue;
225
+ const candidate = Number(line.trim().split(/\s+/)[0]);
226
+ if (Number.isInteger(candidate) && candidate > 0) {
227
+ pid = candidate;
228
+ break;
229
+ }
230
+ }
231
+ return pid;
232
+ } catch (error) {
233
+ const { code, status } = error ?? {};
234
+ failure = {
235
+ ...typeof code === "string" ? { code } : {},
236
+ ...typeof status === "number" ? { exit: status } : {}
237
+ };
220
238
  return;
239
+ } finally {
240
+ debugLog.log("ios.app-process", {
241
+ deviceId: udid,
242
+ bundleId,
243
+ state: pid === void 0 ? "unknown" : pid === null ? "absent" : "running",
244
+ ...typeof pid === "number" ? { appPid: pid } : {},
245
+ ms: Math.round(performance.now() - started),
246
+ ...failure
247
+ });
221
248
  }
222
- const label = `UIKitApplication:${bundleId}[`;
223
- for (const line of out.split("\n")) {
224
- if (!line.includes(label)) continue;
225
- const pid = Number(line.trim().split(/\s+/)[0]);
226
- if (Number.isInteger(pid) && pid > 0) return pid;
227
- }
228
- return null;
229
249
  }
230
250
  function launchedIosAppAfterNoHandle(error, udid, bundleId, exec) {
231
251
  const stderr = String(error?.stderr ?? "");
@@ -6,10 +6,20 @@ const ATTEMPT_BACKOFF_MS = 6e4;
6
6
  function due(state, settings, now, attemptedAt) {
7
7
  const elapsed = (stamp) => stamp === void 0 || stamp > now ? Infinity : now - stamp;
8
8
  if (elapsed(attemptedAt) < ATTEMPT_BACKOFF_MS) return [];
9
- return ["pressure", "size"].filter((check) => {
10
- if (elapsed(state?.deferredAt?.[check]) < DEFERRED_RETRY_MS) return false;
11
- const interval = check === "pressure" ? settings.pressureCheckMinutes : settings.sizeCheckMinutes;
12
- return elapsed(state?.lastAt[check]) >= interval * 6e4;
9
+ const intervalMs = {
10
+ pressure: settings.pressureCheckMinutes * 6e4,
11
+ size: settings.sizeCheckMinutes * 6e4,
12
+ worktree: settings.removeFinishedWorktrees ? settings.worktreeCheckMinutes * 6e4 : Infinity,
13
+ sweep: settings.sweepHours > 0 ? settings.sweepHours * 36e5 : Infinity
14
+ };
15
+ return [
16
+ "pressure",
17
+ "size",
18
+ "worktree",
19
+ "sweep"
20
+ ].filter((check) => {
21
+ if (intervalMs[check] === Infinity || elapsed(state?.deferredAt?.[check]) < DEFERRED_RETRY_MS) return false;
22
+ return elapsed(state?.lastAt[check]) >= intervalMs[check];
13
23
  });
14
24
  }
15
25
  //#endregion