stim 1.13.0 → 1.15.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 (133) hide show
  1. package/README.md +2 -0
  2. package/dist/{activity-DfVKZTEB.mjs → activity-B2-kb7k0.mjs} +281 -41
  3. package/dist/{android-BHfAu2mf.mjs → android-CYmq0jNi.mjs} +2 -2
  4. package/dist/{android-CD8pr8Q2.mjs → android-Cu_L4RpL.mjs} +524 -412
  5. package/dist/{android-qx_31wJo.mjs → android-Db2eEMaf.mjs} +152 -65
  6. package/dist/android-cas-PnKfAdB2.mjs +167 -0
  7. package/dist/android-cas-compiler.mjs +2 -2
  8. package/dist/{app-install-CDFY2nUL.mjs → app-install-CAAplXAt.mjs} +162 -173
  9. package/dist/{budget-E5o91NR1.mjs → budget-CMiqghig.mjs} +1048 -77
  10. package/dist/{build-plan-BTa93o_r.mjs → build-plan-aeGMFX7e.mjs} +193 -650
  11. package/dist/build-progress-C2Jv1AtA.mjs +872 -0
  12. package/dist/build-slots-Df1ApSuH.mjs +127 -0
  13. package/dist/{cache-manifest-DWPF4RKJ.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
  14. package/dist/cache-manifest.mjs +1 -1
  15. package/dist/{chrome-B5hWgQJS.mjs → chrome-BrcVWQyD.mjs} +4 -4
  16. package/dist/cli-0cX5s4NM.mjs +45 -0
  17. package/dist/cli.mjs +6 -42
  18. package/dist/client-C2IS36Qf.mjs +1333 -0
  19. package/dist/collector-run.mjs +8 -7
  20. package/dist/{command-output-BIL7rlX7.mjs → command-output-CliHHn7a.mjs} +1 -1
  21. package/dist/{config-0jCcMM0E.mjs → config-D0DbpZtM.mjs} +29 -29
  22. package/dist/{created-devices-Cd558h31.mjs → created-devices-BwVb3liH.mjs} +2 -2
  23. package/dist/{dependency-state-DNN0yfx6.mjs → dependency-state-BmsjKZ2H.mjs} +2 -2
  24. package/dist/{deps-2Wo81np9.mjs → deps-BFlKbOIp.mjs} +3 -3
  25. package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
  26. package/dist/dev-client-CjzLoNs0.mjs +80 -0
  27. package/dist/{device-Cf7vl-so.mjs → device-BZ1IyS5A.mjs} +7 -7
  28. package/dist/device-capacity-DMuKC7nx.mjs +136 -0
  29. package/dist/device-host-worker.d.mts +1 -0
  30. package/dist/device-host-worker.mjs +769 -0
  31. package/dist/device-ios-DMQBUPus.mjs +381 -0
  32. package/dist/{device-lease-CL9dZf73.mjs → device-lease-W5Pi1q38.mjs} +43 -36
  33. package/dist/{device-pool-MuoiyRcu.mjs → device-pool-B2r38YjS.mjs} +4 -4
  34. package/dist/{device-remote-DT9ngZiD.mjs → device-remote-9ulPsdhY.mjs} +68 -162
  35. package/dist/{doctor-D2iysNNH.mjs → doctor-BcE5xsBn.mjs} +191 -99
  36. package/dist/{error-diagnostics-BoiOhck8.mjs → error-diagnostics-Cb0P1WLS.mjs} +12 -11
  37. package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
  38. package/dist/{gc-eA-PRBX8.mjs → gc-BuL1Genr.mjs} +430 -102
  39. package/dist/{android-cas-B9Kv9aIy.mjs → gradle-CmdOBq1d.mjs} +8 -294
  40. package/dist/{guide-BfZ0OmiP.mjs → guide-cCSGRFd3.mjs} +2052 -240
  41. package/dist/{guide-status-BaMYu55M.mjs → guide-status-CIoWK6mG.mjs} +3 -3
  42. package/dist/hosted-macos-DwowNU7W.mjs +447 -0
  43. package/dist/idle-shutdown-B5LPaNyY.mjs +122 -0
  44. package/dist/in-use-CndPMilN.mjs +110 -0
  45. package/dist/{ios-CmEzZiOj.mjs → ios-3CtCRhwr.mjs} +201 -10
  46. package/dist/{ios-CcfCeZ19.mjs → ios-Chob8ny7.mjs} +560 -259
  47. package/dist/{ios-device-BW-t_Lkv.mjs → ios-device-DERmMmk-.mjs} +12 -7
  48. package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
  49. package/dist/{launch-verify-CuJaBpEa.mjs → launch-verify-CLlofxRt.mjs} +42 -11
  50. package/dist/{logs-DcSRbC2t.mjs → logs-h9h6MUvE.mjs} +95 -13
  51. package/dist/machine-usage-D_YYMzfR.mjs +283 -0
  52. package/dist/machines-CYtOCqcj.mjs +259 -0
  53. package/dist/macos-BwtbUtTN.mjs +468 -0
  54. package/dist/macos-run.d.mts +5 -0
  55. package/dist/macos-run.mjs +2 -0
  56. package/dist/{merge-state-ytFQCeh4.mjs → merge-state-BnxLNQiM.mjs} +22 -12
  57. package/dist/{metro-BPeY1YMh.mjs → metro-Di8EN2Tb.mjs} +20 -120
  58. package/dist/{named-ports-n7tnJsI8.mjs → named-ports-Dj_XBNaL.mjs} +8 -64
  59. package/dist/native-run-DFDoIRbY.mjs +147 -0
  60. package/dist/{native-runtime-CiiFHt0e.mjs → native-runtime-i6OkVg-w.mjs} +11 -6
  61. package/dist/offload-worker.d.mts +121 -0
  62. package/dist/offload-worker.mjs +601 -0
  63. package/dist/{ownership-Bz2kETAS.mjs → ownership-BkYxUtuj.mjs} +3 -2
  64. package/dist/{page-BTu7I60K.mjs → page-QF_Ke10s.mjs} +7 -2
  65. package/dist/{ports-C5UutqpJ.mjs → ports-DddwttKM.mjs} +3 -3
  66. package/dist/prebuild-BvxDlD6C.mjs +213 -0
  67. package/dist/process-identity-BmRm1qV0.mjs +12 -0
  68. package/dist/{project-DGeclhvO.mjs → project-CV3tDFHl.mjs} +9 -18
  69. package/dist/pull-request-pxnDCQzn.mjs +322 -0
  70. package/dist/pull-requests.d.mts +120 -0
  71. package/dist/pull-requests.mjs +2 -0
  72. package/dist/recordings-GEXp4iBT.mjs +37 -0
  73. package/dist/{reload-C-cV5yy_.mjs → reload-ChPiwvot.mjs} +70 -22
  74. package/dist/{remote-cache--aehr4Pr.mjs → remote-cache-CO2elm_b.mjs} +4 -4
  75. package/dist/run-B-xqRrsg.mjs +119 -0
  76. package/dist/{server-bare-Bq8BpSIo.mjs → server-bare-X7PUgizL.mjs} +60 -13
  77. package/dist/{server-expo-DUCg52-K.mjs → server-expo-DhtX6bom.mjs} +6 -10
  78. package/dist/server-expo-KJeD109I.mjs +2 -0
  79. package/dist/{settings-xB0Frkg6.mjs → settings-CduVcoxj.mjs} +77 -26
  80. package/dist/{settings-ssVBToDR.mjs → settings-DbL6uhH8.mjs} +16 -10
  81. package/dist/settings.schema.json +357 -2
  82. package/dist/{simslim-Bbg9UWrt.mjs → simslim-Ciluxlq4.mjs} +8 -132
  83. package/dist/slot-launch-BY0BrOLh.mjs +65 -0
  84. package/dist/{spawn-claims-PT8aQpCa.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
  85. package/dist/spawn-entry-DncpJvWL.mjs +16 -0
  86. package/dist/stage-CzaiwFsI.mjs +143 -0
  87. package/dist/start-CPO4wRg7.mjs +2 -0
  88. package/dist/{start-BZhItkiL.mjs → start-CUD9nasA.mjs} +108 -61
  89. package/dist/state-B4PQFXMW.d.mts +12 -0
  90. package/dist/state-BxCgeTQu.mjs +41 -0
  91. package/dist/{state-DwAU2_-D.mjs → state-CaeaHbDA.mjs} +7 -4
  92. package/dist/{state-l1pYwOre.mjs → state-DFm77wRn.mjs} +67 -5
  93. package/dist/stats-DBLLFmKd.mjs +66 -0
  94. package/dist/{status-TJlL0HWo.mjs → status-DYXxNOT0.mjs} +425 -260
  95. package/dist/{status-sszP4XKU.mjs → status-l84Gbvp2.mjs} +122 -20
  96. package/dist/stdout-reader-C8yjre1x.mjs +23 -0
  97. package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
  98. package/dist/stim-footprint.swift +32 -0
  99. package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
  100. package/dist/{stop-BZ2qMiBP.mjs → stop-Bad61z_2.mjs} +128 -19
  101. package/dist/stop-Bvf1MflS.mjs +48 -0
  102. package/dist/{stop-DskDKNTU.mjs → stop-CceYh1yG.mjs} +2 -2
  103. package/dist/stop-cause-CZ_Mr-v9.mjs +665 -0
  104. package/dist/supervisor-run.d.mts +44 -12
  105. package/dist/supervisor-run.mjs +276 -33
  106. package/dist/support-CDQbDkL5.mjs +315 -0
  107. package/dist/support-WLOzVKUv.mjs +176 -0
  108. package/dist/teardown-BYuQafiA.mjs +718 -0
  109. package/dist/{xcode-LM6A8cNZ.mjs → toolchain-DmeYjXD9.mjs} +363 -13
  110. package/dist/warm-progress-DVHLN4uC.mjs +463 -0
  111. package/dist/{idle-DxLi5OkN.mjs → watchman-Bx0wceoF.mjs} +55 -8
  112. package/dist/{web-sWXd5iek.mjs → web-k6w8-HnE.mjs} +39 -22
  113. package/dist/web-run.mjs +326 -13
  114. package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
  115. package/dist/workspace-state-CL2V2Ons.mjs +371 -0
  116. package/dist/worktree-BT_uULFx.mjs +2 -0
  117. package/dist/{worktree-DeBQSVtR.mjs → worktree-C0c5Udwa.mjs} +55 -54
  118. package/dist/{worktree-D4Do_XiQ.mjs → worktree-qXKzADSC.mjs} +161 -255
  119. package/package.json +10 -5
  120. package/shim/bundle-response.cjs +55 -10
  121. package/shim/bundle-response.d.cts +1 -0
  122. package/shim/expo-metro-config.cjs +10 -2
  123. package/dist/build-progress-l7d-X-ZP.mjs +0 -247
  124. package/dist/in-use-wYEaKQM9.mjs +0 -249
  125. package/dist/ownership-PUP4Dwai.mjs +0 -1138
  126. package/dist/server-expo-BeYwP_Xy.mjs +0 -2
  127. package/dist/slot-launch-BIWEW-wI.mjs +0 -19
  128. package/dist/start-Rw2GD3nV.mjs +0 -2
  129. package/dist/stats-CaSwmsSZ.mjs +0 -62
  130. package/dist/stats-D8rUTPHd.mjs +0 -368
  131. package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
  132. package/dist/worktree-3cBa-bQt.mjs +0 -2
  133. package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
@@ -1,14 +1,15 @@
1
- import { G as validateDeviceSlot, O as process_identity_exports, z as deviceSlotKey } from "./config-0jCcMM0E.mjs";
2
- import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
+ import { R as deviceSlotKey, W as validateDeviceSlot } from "./config-D0DbpZtM.mjs";
3
+ import { t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
3
4
  import { r as createNdjsonWriter } from "./ndjson-CDY9IkVC.mjs";
4
- import { M as workspaceLogsDir } from "./metro-BPeY1YMh.mjs";
5
+ import { C as workspaceLogsDir } from "./workspace-state-CL2V2Ons.mjs";
5
6
  import { t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
6
- import { a as startIosDeviceConsole, i as parseDeviceConsoleLine } from "./ios-device-BiOsSVzd.mjs";
7
- import { a as unregisterCollector, i as registerCollector, r as readCollectors, t as collectorProcessTitle } from "./ownership-Bz2kETAS.mjs";
8
- import { a as watchAppPid, i as waitForAppPid, n as parseLogcatLine, r as startAndroidLogcat, t as androidClockOffset } from "./android-BHfAu2mf.mjs";
7
+ import { a as startIosDeviceConsole, i as parseDeviceConsoleLine } from "./ios-device-Ee7sDXfp.mjs";
8
+ import { a as unregisterCollector, i as registerCollector, r as readCollectors, t as collectorProcessTitle } from "./ownership-BkYxUtuj.mjs";
9
+ import { a as watchAppPid, i as waitForAppPid, n as parseLogcatLine, r as startAndroidLogcat, t as androidClockOffset } from "./android-CYmq0jNi.mjs";
9
10
  import { existsSync } from "node:fs";
10
- import { LOG_ROTATE_BYTES } from "@stim-cli/core";
11
11
  import { isAbsolute, join, resolve } from "node:path";
12
+ import { LOG_ROTATE_BYTES } from "@stim-cli/core";
12
13
  import { fileURLToPath } from "node:url";
13
14
  //#region src/collector/ios.ts
14
15
  const MESSAGE_TYPE_LEVEL = {
@@ -1,4 +1,4 @@
1
- import { t as NO_PROJECT_REFUSAL } from "./project-DGeclhvO.mjs";
1
+ import { t as NO_PROJECT_REFUSAL } from "./project-CV3tDFHl.mjs";
2
2
  import { n as stripAnsi } from "./process-output-Fpl8PYi8.mjs";
3
3
  import { quotedPath } from "@stim-cli/core";
4
4
  import chalk from "chalk";
@@ -1,11 +1,11 @@
1
- import { n as __exportAll, r as __reExport } from "./rolldown-runtime-BsOwBuO_.mjs";
2
- import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
3
- import { InvalidArgumentError } from "commander";
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
+ import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
3
+ import { join } from "node:path";
4
4
  import { existsSync, lstatSync, mkdirSync, readdirSync, readlinkSync, renameSync, statSync, unlinkSync, writeFileSync } from "fs";
5
- import { dirname, isAbsolute, join, normalize, parse, sep } from "path";
5
+ import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, normalize, parse as parse$1, sep as sep$1 } from "path";
6
6
  import { configDir } from "@stim-cli/core";
7
+ import { InvalidArgumentError } from "commander";
7
8
  import { allMetroPorts, configCorruptRepair, findEnclosingWorktreeRoot, getConcurrencyLimits, getConfigPath, getConfigPath as getConfigPath$1, getProject, getProjectSettings, getRepoSettings, isPathPrefix, loadConfig, loadConfig as loadConfig$1, withConfigLock, withConfigLock as withConfigLock$1 } from "@stim-cli/core/state";
8
- import { join as join$1 } from "node:path";
9
9
  //#region src/devices/device-slots.ts
10
10
  const DEFAULT_DEVICE_SLOT = "default";
11
11
  const DEVICE_SLOT_RULE = "A device slot must be 1-64 letters, digits, underscores or hyphens, starting with a letter or digit.";
@@ -26,6 +26,7 @@ function validateDeviceSlot(slot = "default") {
26
26
  }
27
27
  function parseDeviceSlotOption(slot) {
28
28
  if (!isDeviceSlot(slot)) throw new InvalidArgumentError(DEVICE_SLOT_RULE);
29
+ if (slot === "web") throw new InvalidArgumentError(`web names this workspace's owned Chrome (stim stop --slot web); choose another device slot name.`);
29
30
  return slot;
30
31
  }
31
32
  function deviceSlotPlatforms(project, slot = DEFAULT_DEVICE_SLOT) {
@@ -107,23 +108,23 @@ const WINDOWS = process.platform === "win32";
107
108
  const DRIVE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
108
109
  function volumeRootFor(path) {
109
110
  const normalized = normalize(String(path));
110
- if (WINDOWS) return parse(normalized).root.replace(/^[a-z]:/, (drive) => drive.toUpperCase());
111
+ if (WINDOWS) return parse$1(normalized).root.replace(/^[a-z]:/, (drive) => drive.toUpperCase());
111
112
  const m = normalized.match(/^\/volumes\/([^/]+)/i);
112
113
  return m ? `/Volumes/${m[1]}` : "/";
113
114
  }
114
115
  function resolveWorkspaceRealish(workspacePath) {
115
116
  const raw = String(workspacePath);
116
- if (!isAbsolute(raw)) return null;
117
+ if (!isAbsolute$1(raw)) return null;
117
118
  let current = raw;
118
119
  const MAX_HOPS = 40;
119
120
  for (let hops = 0; hops < MAX_HOPS; hops++) {
120
121
  const normalized = normalize(current);
121
- const root = parse(normalized).root;
122
- const segments = normalized.slice(root.length).split(sep).filter(Boolean);
123
- let prefix = root.endsWith(sep) ? root.slice(0, -sep.length) : root;
122
+ const root = parse$1(normalized).root;
123
+ const segments = normalized.slice(root.length).split(sep$1).filter(Boolean);
124
+ let prefix = root.endsWith(sep$1) ? root.slice(0, -sep$1.length) : root;
124
125
  let followedSymlink = false;
125
126
  for (const segment of segments) {
126
- prefix += `${sep}${segment}`;
127
+ prefix += `${sep$1}${segment}`;
127
128
  let st;
128
129
  try {
129
130
  st = lstatSync(prefix);
@@ -138,7 +139,7 @@ function resolveWorkspaceRealish(workspacePath) {
138
139
  } catch {
139
140
  return null;
140
141
  }
141
- current = `${isAbsolute(target) ? target : normalize(join(dirname(prefix), target))}${normalized.slice(prefix.length)}`;
142
+ current = `${isAbsolute$1(target) ? target : normalize(join$1(dirname$1(prefix), target))}${normalized.slice(prefix.length)}`;
142
143
  followedSymlink = true;
143
144
  break;
144
145
  }
@@ -153,7 +154,7 @@ function isRealMount(entryDev, rootDev) {
153
154
  function listWindowsVolumeRoots(statFn) {
154
155
  const roots = [];
155
156
  for (const letter of DRIVE_LETTERS) {
156
- const root = `${letter}:${sep}`;
157
+ const root = `${letter}:${sep$1}`;
157
158
  try {
158
159
  statFn(root);
159
160
  } catch {
@@ -174,7 +175,7 @@ function listMountedVolumes({ statFn = statSync } = {}) {
174
175
  }
175
176
  try {
176
177
  for (const name of readdirSync("/Volumes")) {
177
- const path = join("/Volumes", name);
178
+ const path = join$1("/Volumes", name);
178
179
  let entryDev;
179
180
  try {
180
181
  entryDev = statFn(path).dev;
@@ -191,7 +192,7 @@ function resolveVolumeRoot(path) {
191
192
  return realish === null ? null : volumeRootFor(realish);
192
193
  }
193
194
  function uncShareIsReachable(volume, statFn) {
194
- if (!WINDOWS || !volume.startsWith(`${sep}${sep}`)) return false;
195
+ if (!WINDOWS || !volume.startsWith(`${sep$1}${sep$1}`)) return false;
195
196
  try {
196
197
  return statFn(volume).isDirectory();
197
198
  } catch {
@@ -224,14 +225,9 @@ function formatBytes(bytes) {
224
225
  return `${Math.round(bytes / 1024)}K`;
225
226
  }
226
227
  //#endregion
227
- //#region src/ownership-claim.ts
228
- var ownership_claim_exports = /* @__PURE__ */ __exportAll({});
229
- import * as import__stim_cli_core_ownership_claim from "@stim-cli/core/ownership-claim";
230
- __reExport(ownership_claim_exports, import__stim_cli_core_ownership_claim);
231
- //#endregion
232
228
  //#region src/devices/avd-claim.ts
233
229
  function acquireAvdClaim(avdName) {
234
- const root = join$1(configDir(), "avd-locks", `${encodeURIComponent(avdName.toLowerCase())}.lock`);
230
+ const root = join(configDir(), "avd-locks", `${encodeURIComponent(avdName.toLowerCase())}.lock`);
235
231
  const label = `AVD ${avdName}`;
236
232
  const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
237
233
  root,
@@ -248,11 +244,6 @@ function acquireAvdClaim(avdName) {
248
244
  });
249
245
  }
250
246
  //#endregion
251
- //#region src/process-identity.ts
252
- var process_identity_exports = /* @__PURE__ */ __exportAll({});
253
- import * as import__stim_cli_core_process_identity from "@stim-cli/core/process-identity";
254
- __reExport(process_identity_exports, import__stim_cli_core_process_identity);
255
- //#endregion
256
247
  //#region src/workspace/config.ts
257
248
  function getConfigDir() {
258
249
  return configDir();
@@ -264,7 +255,7 @@ function refuseRelativeStimPaths(env = process.env) {
264
255
  "STIM_METRO_CACHE"
265
256
  ]) {
266
257
  const value = env[name];
267
- if (!value || isAbsolute(value)) continue;
258
+ if (!value || isAbsolute$1(value)) continue;
268
259
  const error = /* @__PURE__ */ new Error(`${name}=${value} is not an absolute path. Set it to an absolute path, or unset it to use the default.`);
269
260
  error.code = "STIM_RELATIVE_PATH";
270
261
  throw error;
@@ -309,7 +300,7 @@ function ensureConfig() {
309
300
  });
310
301
  }
311
302
  function requireAbsoluteProjectPath(projectPath) {
312
- if (isAbsolute(projectPath)) return;
303
+ if (isAbsolute$1(projectPath)) return;
313
304
  throw new Error(`Project key "${projectPath}" is not an absolute path. The registry is keyed by the realpath of a workspace root, so a relative key can never resolve.`);
314
305
  }
315
306
  function upsertProject(projectPath, fields) {
@@ -379,6 +370,15 @@ function releaseAndroidConsolePort(projectPath, consolePort, slot = "default") {
379
370
  return true;
380
371
  });
381
372
  }
373
+ function recordIosSchemeApprovals(projectPath, deviceUdid, schemeApprovals, slot = "default") {
374
+ withConfigLock(() => {
375
+ const cfg = loadConfig();
376
+ const ios = deviceSlotPlatforms(cfg?.projects?.[projectPath], slot)?.ios;
377
+ if (!cfg || !ios?.owned || ios.deviceUdid !== deviceUdid) return;
378
+ ios.schemeApprovals = schemeApprovals;
379
+ saveConfig(cfg);
380
+ });
381
+ }
382
382
  function clearAndroidBootPending(projectPath, avdName, slot = "default") {
383
383
  withConfigLock(() => {
384
384
  const cfg = loadConfig();
@@ -521,4 +521,4 @@ function allConsolePortsAndSerials({ isMounted = isOnMountedVolume } = {}) {
521
521
  return result;
522
522
  }
523
523
  //#endregion
524
- export { ownership_claim_exports as A, deviceSlotPlatforms as B, setDevice as C, writeConfigSetting as D, withConfigLock$1 as E, measuredDirectorySize as F, validateDeviceSlot as G, parseDeviceSlotOption as H, volumeRootFor as I, assignSlotDevice as L, formatBytes as M, isOnMountedVolume as N, process_identity_exports as O, listMountedVolumes as P, deviceSlotFileKey as R, saveConfig as S, upsertProject as T, projectDeviceSlots as U, parseDeviceSlotKey as V, removeSlotDevice as W, loadConfig$1 as _, clearDevice as a, releaseMetroPort as b, ensureConfig as c, getConfigDir as d, getConfigPath$1 as f, isPathPrefix as g, getRepoSettings as h, clearAndroidBootPending as i, directorySize as j, acquireAvdClaim as k, findEnclosingWorktreeRoot as l, getProjectSettings as m, allMetroPorts as n, clearSupervisor as o, getProject as p, claimMetroPort as r, configCorruptRepair as s, allConsolePortsAndSerials as t, getConcurrencyLimits as u, refuseRelativeStimPaths as v, setSupervisor as w, removeProject as x, releaseAndroidConsolePort as y, deviceSlotKey as z };
524
+ export { directorySize as A, parseDeviceSlotKey as B, saveConfig as C, withConfigLock$1 as D, upsertProject as E, volumeRootFor as F, projectDeviceSlots as H, assignSlotDevice as I, deviceSlotFileKey as L, isOnMountedVolume as M, listMountedVolumes as N, writeConfigSetting as O, measuredDirectorySize as P, deviceSlotKey as R, removeProject as S, setSupervisor as T, removeSlotDevice as U, parseDeviceSlotOption as V, validateDeviceSlot as W, loadConfig$1 as _, clearDevice as a, releaseAndroidConsolePort as b, ensureConfig as c, getConfigDir as d, getConfigPath$1 as f, isPathPrefix as g, getRepoSettings as h, clearAndroidBootPending as i, formatBytes as j, acquireAvdClaim as k, findEnclosingWorktreeRoot as l, getProjectSettings as m, allMetroPorts as n, clearSupervisor as o, getProject as p, claimMetroPort as r, configCorruptRepair as s, allConsolePortsAndSerials as t, getConcurrencyLimits as u, recordIosSchemeApprovals as v, setDevice as w, releaseMetroPort as x, refuseRelativeStimPaths as y, deviceSlotPlatforms as z };
@@ -1,5 +1,5 @@
1
- import { d as getConfigDir } from "./config-0jCcMM0E.mjs";
2
- import { F as withDirLock } from "./metro-BPeY1YMh.mjs";
1
+ import { d as getConfigDir } from "./config-D0DbpZtM.mjs";
2
+ import { E as withDirLock } from "./workspace-state-CL2V2Ons.mjs";
3
3
  import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { createdDevicesFile, createdDevicesLock, readCreatedDevices, readCreatedDevices as readCreatedDevices$1 } from "@stim-cli/core/state";
5
5
  //#region src/devices/created-devices.ts
@@ -1,5 +1,5 @@
1
- import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
2
- import { y as repoRoot } from "./worktree-DeBQSVtR.mjs";
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
+ import { y as repoRoot } from "./worktree-C0c5Udwa.mjs";
3
3
  import { existsSync } from "node:fs";
4
4
  import { dirname, join, relative } from "node:path";
5
5
  //#region src/dependency-state.ts
@@ -1,7 +1,7 @@
1
- import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
2
- import { a as spawnDeclared } from "./spawn-claims-PT8aQpCa.mjs";
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
+ import { a as spawnDeclared } from "./spawn-claims-D0XfSe8u.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
- import { d as startBuildHeartbeat, m as bundlerPin, n as HEARTBEAT_INTERVAL_MS } from "./xcode-LM6A8cNZ.mjs";
4
+ import { S as bundlerPin, u as HEARTBEAT_INTERVAL_MS, y as startBuildHeartbeat } from "./toolchain-DmeYjXD9.mjs";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import { delimiter, dirname, join, relative, resolve, sep } from "node:path";
7
7
  import { homedir } from "node:os";
@@ -1,4 +1,4 @@
1
- import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
2
  import { openSync } from "node:fs";
3
3
  //#region src/detached-entry.ts
4
4
  const LOG_FILE_FLAG = "--log-file";
@@ -0,0 +1,80 @@
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
+ import { f as resolvePackageJson, s as isPackageResolvable } from "./project-CV3tDFHl.mjs";
3
+ import { dirname, join } from "node:path";
4
+ import { isJsonObject, readJsonObject } from "@stim-cli/core/state";
5
+ //#region src/commands/dev-client.ts
6
+ function devClientScheme(root, appPath = null, { exec = null } = {}) {
7
+ if (!hasDevClient(root)) return void 0;
8
+ const fromBundle = pickDevClientScheme(readBundleSchemes(appPath, { exec }));
9
+ if (fromBundle) return fromBundle;
10
+ const app = readJsonObject(join(root, "app.json"));
11
+ const expo = app?.expo;
12
+ const raw = (isJsonObject(expo) ? expo.scheme : void 0) ?? app?.scheme ?? null;
13
+ const scheme = Array.isArray(raw) ? raw.find((s) => typeof s === "string" && s.trim() !== "") : raw;
14
+ if (typeof scheme !== "string" || scheme.trim() === "") return void 0;
15
+ return scheme.trim();
16
+ }
17
+ function schemesFromInfoPlist(plist) {
18
+ const types = plist?.CFBundleURLTypes;
19
+ if (!Array.isArray(types)) return [];
20
+ const out = [];
21
+ for (const type of types) {
22
+ const schemes = type?.CFBundleURLSchemes;
23
+ if (Array.isArray(schemes)) out.push(...schemes.filter((s) => typeof s === "string" && s.trim() !== ""));
24
+ }
25
+ return out;
26
+ }
27
+ function readBundleSchemes(appPath, { exec = null } = {}) {
28
+ if (typeof appPath !== "string" || appPath.trim() === "") return [];
29
+ const e = exec || getExecutor();
30
+ let out;
31
+ try {
32
+ out = e.runFile("plutil", [
33
+ "-convert",
34
+ "json",
35
+ "-o",
36
+ "-",
37
+ join(appPath, "Info.plist")
38
+ ]);
39
+ } catch {
40
+ return [];
41
+ }
42
+ try {
43
+ return schemesFromInfoPlist(JSON.parse(String(out)));
44
+ } catch {
45
+ return [];
46
+ }
47
+ }
48
+ const THIRD_PARTY_SCHEME = /^(?:fb\d+|com\.googleusercontent\.apps\.|msauth\.|msauthv2|twitterkit-|db-[a-z0-9]+$|spotify|snapchat|com\.facebook)/i;
49
+ function pickDevClientScheme(schemes) {
50
+ const all = (Array.isArray(schemes) ? schemes : []).filter((s) => typeof s === "string" && s.trim() !== "").map((s) => s.trim()).filter((s) => !/^(?:https?|mailto|tel|sms|itms(?:-apps)?)$/i.test(s));
51
+ const expo = all.filter((s) => s.startsWith("exp+"));
52
+ return (expo.length ? expo : all.filter((s) => !THIRD_PARTY_SCHEME.test(s))).toSorted((a, b) => b.length - a.length)[0] ?? null;
53
+ }
54
+ function hasDevClient(root) {
55
+ const pkg = readJsonObject(join(root, "package.json"));
56
+ if ([pkg?.dependencies, pkg?.devDependencies].some((deps) => isJsonObject(deps) && "expo-dev-client" in deps)) return true;
57
+ return isPackageResolvable(root, "expo-dev-client");
58
+ }
59
+ /**
60
+ * Whether `version` of expo-dev-launcher reads the `disableFab=1` and `disableAutoLaunch=1` launch
61
+ * URL params (expo/expo#49651, first published in 58.0.0; no 58.0.0 prerelease carries it).
62
+ */
63
+ function devLauncherReadsDevMenuParams(version) {
64
+ const match = /^(\d+)\.(\d+)\.(\d+)(-.+)?$/.exec(version?.trim() ?? "");
65
+ if (!match) return false;
66
+ const [major, minor, patch] = match.slice(1, 4).map(Number);
67
+ if (major !== 58) return major > 58;
68
+ return minor > 0 || patch > 0 || match[4] === void 0;
69
+ }
70
+ function devClientTakesDevMenuParams(root) {
71
+ return devLauncherReadsDevMenuParams(installedDevLauncherVersion(root));
72
+ }
73
+ function installedDevLauncherVersion(root) {
74
+ const devClient = resolvePackageJson(root, "expo-dev-client");
75
+ const launcher = resolvePackageJson(devClient ? dirname(devClient) : root, "expo-dev-launcher");
76
+ const version = launcher ? readJsonObject(launcher)?.version : null;
77
+ return typeof version === "string" ? version : null;
78
+ }
79
+ //#endregion
80
+ export { schemesFromInfoPlist as i, devClientTakesDevMenuParams as n, pickDevClientScheme as r, devClientScheme as t };
@@ -1,10 +1,10 @@
1
- import { H as parseDeviceSlotOption, U as projectDeviceSlots, p as getProject, z as deviceSlotKey } from "./config-0jCcMM0E.mjs";
2
- import { a as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-DGeclhvO.mjs";
3
- import { r as clockTime } from "./command-output-BIL7rlX7.mjs";
4
- import { n as fileLeaseIo, o as parseLeaseDuration, p as takeLease, u as releaseWorkspaceLeases } from "./device-lease-CL9dZf73.mjs";
5
- import { D as listAdbDevices, H as physicalDeviceModel, J as resolvePhysicalDevice, M as memoizeEmulatorProbe, T as getAvdNameForSerial, W as probeEmulatorSerial, o as androidPoolCandidates, s as androidPoolNoCandidatesRefusal } from "./android-qx_31wJo.mjs";
6
- import { d as waitForDevice, s as parseDeviceWait, t as selectFromPool } from "./device-pool-MuoiyRcu.mjs";
7
- import { a as iosPoolCandidates, c as listIosDevices, o as iosPoolNoCandidatesRefusal, s as isWirelessIosDevice, u as resolveIosPhysicalDevice } from "./ios-device-BW-t_Lkv.mjs";
1
+ import { H as projectDeviceSlots, R as deviceSlotKey, V as parseDeviceSlotOption, p as getProject } from "./config-D0DbpZtM.mjs";
2
+ import { a as findProjectRoot, t as NO_PROJECT_REFUSAL } from "./project-CV3tDFHl.mjs";
3
+ import { r as clockTime } from "./command-output-CliHHn7a.mjs";
4
+ import { n as fileLeaseIo, o as parseLeaseDuration, p as takeLease, u as releaseWorkspaceLeases } from "./device-lease-W5Pi1q38.mjs";
5
+ import { E as getAvdNameForSerial, G as probeEmulatorSerial, N as memoizeEmulatorProbe, O as listAdbDevices, U as physicalDeviceModel, Y as resolvePhysicalDevice, c as androidPoolNoCandidatesRefusal, s as androidPoolCandidates } from "./android-Db2eEMaf.mjs";
6
+ import { d as waitForDevice, s as parseDeviceWait, t as selectFromPool } from "./device-pool-B2r38YjS.mjs";
7
+ import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, l as listIosDevices, o as iosPoolNoCandidatesRefusal } from "./ios-device-DERmMmk-.mjs";
8
8
  import chalk from "chalk";
9
9
  //#region src/commands/device.ts
10
10
  const DEFAULT_FOR = "5m";
@@ -0,0 +1,136 @@
1
+ import { H as projectDeviceSlots, _ as loadConfig, z as deviceSlotPlatforms } from "./config-D0DbpZtM.mjs";
2
+ import { O as listAdbDevices } from "./android-Db2eEMaf.mjs";
3
+ import { _ as parseRuntimeVersion, c as iosRuntimeMatches, u as listAllIosSims } from "./ios-3CtCRhwr.mjs";
4
+ //#region src/engine/device-capacity.ts
5
+ function liveOwnedDeviceCount({ sims = [], adbEmulators = [], config = null } = {}) {
6
+ let count = 0;
7
+ for (const sim of sims) if (sim?.state === "Booted" && sim.name?.startsWith("stim-")) count++;
8
+ const livePorts = new Set(adbEmulators.map((e) => e.consolePort));
9
+ for (const proj of Object.values(config?.projects || {})) for (const { platforms } of projectDeviceSlots(proj)) {
10
+ const android = platforms.android;
11
+ if (android?.owned && android.avdName && typeof android.consolePort === "number" && livePorts.has(android.consolePort)) count++;
12
+ }
13
+ return count;
14
+ }
15
+ function workspaceHasLiveDevice({ platform, project, slot = "default", sims = [], adbEmulators = [] } = {}) {
16
+ if (!platform) return false;
17
+ const record = deviceSlotPlatforms(project, slot)?.[platform];
18
+ if (!record) return false;
19
+ if (platform === "ios") return sims.some((s) => s.udid === record.deviceUdid && s.state === "Booted");
20
+ return typeof record.consolePort === "number" && adbEmulators.some((e) => e.consolePort === record.consolePort);
21
+ }
22
+ function deviceCapacityRefusal({ platform, project, slot = "default", max, sims = [], adb = null, config = null } = {}) {
23
+ if (!max || max <= 0) return null;
24
+ const adbEmulators = adb?.emulators || [];
25
+ if (workspaceHasLiveDevice({
26
+ platform,
27
+ project,
28
+ slot,
29
+ sims,
30
+ adbEmulators
31
+ })) return null;
32
+ const count = liveOwnedDeviceCount({
33
+ sims,
34
+ adbEmulators,
35
+ config
36
+ });
37
+ if (count < max) return null;
38
+ return {
39
+ code: "STIM_AT_CAPACITY",
40
+ message: `${count} Stim device(s) are already booted and concurrency.maxDevices is ${max}, so booting another would exceed the cap.`,
41
+ remedy: "stop an environment (stim stop) or raise concurrency.maxDevices"
42
+ };
43
+ }
44
+ function checkDeviceCapacity({ platform, project, slot = "default", max, sims = listAllIosSims, adb = listAdbDevices, config = loadConfig } = {}) {
45
+ if (!max || max <= 0) return null;
46
+ let simList = [];
47
+ let adbRes = {
48
+ emulators: [],
49
+ physical: [],
50
+ unhealthy: []
51
+ };
52
+ try {
53
+ simList = typeof sims === "function" ? sims() || [] : sims || [];
54
+ } catch {}
55
+ try {
56
+ adbRes = typeof adb === "function" ? adb() || adbRes : adb || adbRes;
57
+ } catch {}
58
+ let cfg = null;
59
+ try {
60
+ cfg = typeof config === "function" ? config() : config ?? null;
61
+ } catch {}
62
+ return deviceCapacityRefusal({
63
+ platform,
64
+ project,
65
+ slot,
66
+ max,
67
+ sims: simList,
68
+ adb: adbRes,
69
+ config: cfg
70
+ });
71
+ }
72
+ function deviceTypeMismatch(recordedTypeId, requestedName, deviceTypes) {
73
+ if (!requestedName || !recordedTypeId) return null;
74
+ const wanted = (deviceTypes || []).find((d) => d.name === requestedName);
75
+ if (!wanted) return null;
76
+ if (wanted.identifier === recordedTypeId) return null;
77
+ const recorded = (deviceTypes || []).find((d) => d.identifier === recordedTypeId);
78
+ return `this project's sim is ${recorded ? recorded.name : recordedTypeId}, but --device-type asked for ${requestedName}`;
79
+ }
80
+ function runtimeMismatch(recordedRuntimeId, requested, runtimes) {
81
+ if (!requested || !recordedRuntimeId) return null;
82
+ const wanted = runtimes.find((r) => iosRuntimeMatches(r, requested));
83
+ if (!wanted || wanted.identifier === recordedRuntimeId) return null;
84
+ return `this project's sim runs iOS ${parseRuntimeVersion(recordedRuntimeId)}, but --runtime asked for ${requested}`;
85
+ }
86
+ function installedNames(names) {
87
+ const unique = [...new Set(names.filter((n) => typeof n === "string" && n !== ""))];
88
+ return unique.length > 0 ? unique.join(", ") : "none";
89
+ }
90
+ /** Appends which settings layer supplied an unresolved device selector, so the user knows where to fix it. */
91
+ function layerNote(refusal, key, flag, origin) {
92
+ if (flag !== void 0 && flag !== null) return refusal;
93
+ if (!origin) return refusal;
94
+ return {
95
+ message: `${refusal.message} ${key} is set at the ${origin} layer.`,
96
+ remedy: `${refusal.remedy} Fix it with \`stim settings set ${key} <value> --scope ${origin}\` or \`stim settings unset ${key} --scope ${origin}\`.`
97
+ };
98
+ }
99
+ function unknownIosRuntimeRefusal(requested, runtimes) {
100
+ if (!requested) return null;
101
+ if ((runtimes || []).some((r) => iosRuntimeMatches(r, requested))) return null;
102
+ return {
103
+ message: `No installed simulator runtime matches "${requested}". Installed runtimes: ${installedNames((runtimes || []).map((r) => r.version))}.`,
104
+ remedy: "Pass `--runtime` (or set ios.runtime) a version printed above (\"26.5\") or a runtime's full name (\"iOS 26.5\"); nothing else matches. Install more runtimes through Xcode."
105
+ };
106
+ }
107
+ function creatableIosDeviceTypeNames(runtimes, runtime) {
108
+ return (runtime ? (runtimes || []).filter((r) => iosRuntimeMatches(r, runtime)) : runtimes || []).flatMap((r) => (r.supportedDeviceTypes || []).map((d) => d.name));
109
+ }
110
+ function unknownIosDeviceTypeRefusal(requested, runtimes, runtime) {
111
+ if (!requested) return null;
112
+ const creatable = creatableIosDeviceTypeNames(runtimes, runtime);
113
+ if (creatable.includes(requested)) return null;
114
+ return {
115
+ message: `No device type named "${requested}" can be created on ${runtime ? `runtime ${runtime}` : "any installed simulator runtime"}. ${runtime ? `Device types runtime ${runtime} supports` : "Device types the installed runtimes support"}: ${installedNames(creatable)}.`,
116
+ remedy: "Pass `--device-type` (or set ios.deviceType) one of the names printed above, exactly as `xcrun simctl list devicetypes` spells it. `xcrun simctl list devicetypes` also lists watchOS, tvOS and visionOS models, which no iOS runtime can create. Install more models through Xcode."
117
+ };
118
+ }
119
+ function unknownAndroidSystemImageRefusal(requested, images) {
120
+ if (!requested) return null;
121
+ if ((images || []).some((i) => i.pkg === requested)) return null;
122
+ return {
123
+ message: `No installed Android system image is named "${requested}". Installed system images: ${installedNames((images || []).map((i) => i.pkg))}.`,
124
+ remedy: "Pass `--system-image` (or set android.systemImage) to one of the package ids printed above. Install more with `sdkmanager \"system-images;android-36;google_apis;arm64-v8a\"`."
125
+ };
126
+ }
127
+ function unknownAndroidDeviceProfileRefusal(requested, profiles) {
128
+ if (!requested) return null;
129
+ if (profiles.includes(requested)) return null;
130
+ return {
131
+ message: `No Android hardware profile is named "${requested}". Profiles avdmanager offers: ${installedNames(profiles)}.`,
132
+ remedy: "Pass `--device-profile` (or set android.deviceProfile) to one of the ids printed above, exactly as `avdmanager list device -c` spells it, e.g. \"pixel_fold\" or \"pixel_tablet\"."
133
+ };
134
+ }
135
+ //#endregion
136
+ export { runtimeMismatch as a, unknownIosDeviceTypeRefusal as c, liveOwnedDeviceCount as i, unknownIosRuntimeRefusal as l, deviceTypeMismatch as n, unknownAndroidDeviceProfileRefusal as o, layerNote as r, unknownAndroidSystemImageRefusal as s, checkDeviceCapacity as t };
@@ -0,0 +1 @@
1
+ export {}