stim 1.1.0 → 1.2.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 (59) hide show
  1. package/README.md +7 -0
  2. package/dist/{android-CC5bUer7.mjs → android-BW8i_YxU.mjs} +1 -1
  3. package/dist/{android-DnZlT3aU.mjs → android-Bcmev2s2.mjs} +86 -31
  4. package/dist/{android-xmyGBNy5.mjs → android-K63_0UfF.mjs} +77 -15
  5. package/dist/{android-cas-DGlTStWu.mjs → android-cas-D6HPZ6UQ.mjs} +6 -6
  6. package/dist/android-cas-compiler.mjs +1 -1
  7. package/dist/{app-install-oZIQRbdD.mjs → app-install-NFxUahnH.mjs} +25 -17
  8. package/dist/{build-lock-vE45ZzJZ.mjs → build-lock-BsVoLDaq.mjs} +6 -6
  9. package/dist/{build-slots-CgacA9zQ.mjs → build-slots-D0b6sJyo.mjs} +3 -3
  10. package/dist/{cache-manifest-oeH18ERr.mjs → cache-manifest-Cu4_Znw9.mjs} +1 -1
  11. package/dist/cache-manifest.mjs +1 -1
  12. package/dist/cli.mjs +13 -13
  13. package/dist/collector-run.d.mts +1 -0
  14. package/dist/collector-run.mjs +6 -6
  15. package/dist/{config-D7uu8Gbq.mjs → config-CMtIaTk9.mjs} +1 -1
  16. package/dist/{deps-64wVnpZc.mjs → deps-BLBsTNDS.mjs} +2 -2
  17. package/dist/{dev-client-Bvky1hya.mjs → dev-client-RpvXxCXV.mjs} +72 -9
  18. package/dist/{device-DJKv5Qej.mjs → device-CoCPmazS.mjs} +5 -5
  19. package/dist/{device-lease-D-G3SgVe.mjs → device-lease-Dpik41RY.mjs} +3 -3
  20. package/dist/{device-pool-BlHXnYYs.mjs → device-pool-B5pEVa3t.mjs} +3 -3
  21. package/dist/{device-remote-CCgkG82J.mjs → device-remote-E81KAdXf.mjs} +8 -8
  22. package/dist/{doctor-DlVxTtMq.mjs → doctor-CqPeMsSm.mjs} +19 -26
  23. package/dist/{doctor-BRF9aAJ3.mjs → doctor-D_CX7ib5.mjs} +10 -10
  24. package/dist/{error-diagnostics-B5IJwv3-.mjs → error-diagnostics-Dw8Gn3yw.mjs} +8 -8
  25. package/dist/{exec-bsN9MJXb.mjs → exec-CyylIdq9.mjs} +4 -2
  26. package/dist/{gc-DhXdgSdt.mjs → gc-B7KkDinF.mjs} +39 -25
  27. package/dist/{guide-DrhrDBo5.mjs → guide-BS2Xc24o.mjs} +220 -36
  28. package/dist/{ios-CK1Vrk6Q.mjs → ios-B7KLgIp5.mjs} +38 -26
  29. package/dist/{ios-BZxKPuqP.mjs → ios-D1h1Di39.mjs} +79 -10
  30. package/dist/{ios-device-CYbuRNXR.mjs → ios-device-D3pzTKQE.mjs} +1 -1
  31. package/dist/{ios-device-CdSm0GDw.mjs → ios-device-xNt0Lg6v.mjs} +2 -2
  32. package/dist/{logs-Dxoy16Qv.mjs → logs-DcX9AvRF.mjs} +3 -3
  33. package/dist/{metro-B01H3EuD.mjs → metro-COslRK_F.mjs} +3 -3
  34. package/dist/{ownership-D8HmSv2E.mjs → ownership-CGPart6T.mjs} +3 -3
  35. package/dist/{ownership-B9QIdQOw.mjs → ownership-CYOyqxUo.mjs} +4 -4
  36. package/dist/{ownership-claim-CeJLEpjD.mjs → ownership-claim-7zRxxTfZ.mjs} +1 -1
  37. package/dist/{project-COj6nzzh.mjs → project-BBTVABUz.mjs} +2 -2
  38. package/dist/{reclaim-BPvN2HlP.mjs → reclaim-C5Jmuahx.mjs} +9 -8
  39. package/dist/{reload-DYZEBbZy.mjs → reload-Z8nKifAk.mjs} +7 -7
  40. package/dist/{remote-cache-DOi5-zLj.mjs → remote-cache-DDmJ1Roq.mjs} +73 -13
  41. package/dist/{server-bare-BYHqEeyw.mjs → server-bare-DEk37Mz2.mjs} +7 -2
  42. package/dist/{server-expo-BEMr_m6p.mjs → server-expo-C3ktAwUG.mjs} +4 -4
  43. package/dist/server-expo-Drd7ksHu.mjs +2 -0
  44. package/dist/{settings-BSwrY4FZ.mjs → settings-DwU1_U_q.mjs} +26 -5
  45. package/dist/{start-ByCylYtB.mjs → start-BrY4EuIg.mjs} +10 -10
  46. package/dist/{state-IYEY-zi8.mjs → state-CZ-ER-8d.mjs} +1 -1
  47. package/dist/{stats-wqxPm7Tv.mjs → stats-BCWEVLrM.mjs} +1 -1
  48. package/dist/{stats-DZ4Q5J-7.mjs → stats-BsF15Bti.mjs} +3 -3
  49. package/dist/{status-Dia0XTqG.mjs → status-DFI1Hfpg.mjs} +46 -16
  50. package/dist/{stop-D6o5zAdm.mjs → stop-B7DR4awK.mjs} +2 -2
  51. package/dist/{stop-BApyaF21.mjs → stop-Btg770vV.mjs} +9 -9
  52. package/dist/supervisor-run.mjs +4 -4
  53. package/dist/{workspace-process-lock-CxOO9-pf.mjs → workspace-process-lock-BKfdys1q.mjs} +1 -1
  54. package/dist/{worktree-DxEmUI_n.mjs → worktree-BPTbI-LN.mjs} +16 -16
  55. package/dist/{worktree-Dx3ZC5lS.mjs → worktree-C79xx_kM.mjs} +7 -3
  56. package/dist/{xcode-CDB6fytw.mjs → xcode-DeKCribl.mjs} +190 -63
  57. package/package.json +5 -5
  58. package/shim/bundle-response.cjs +5 -0
  59. package/dist/server-expo-rb0k-0w7.mjs +0 -2
@@ -1,8 +1,27 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
2
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
3
3
  import { mkdtempSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
+ //#region src/host-memory.ts
7
+ function readHostMemoryPressure(exec = getExecutor(), platform = process.platform) {
8
+ if (platform !== "darwin") return null;
9
+ try {
10
+ switch (exec.runFile("/usr/sbin/sysctl", ["-n", "kern.memorystatus_vm_pressure_level"], { timeoutMs: 2e3 }).trim()) {
11
+ case "1": return "normal";
12
+ case "2": return "warning";
13
+ case "4": return "critical";
14
+ default: return null;
15
+ }
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+ function hostMemoryPressureAdvice(pressure) {
21
+ if (pressure === null || pressure === "normal") return null;
22
+ return `macOS reports ${pressure} host memory pressure. Simulator processes can stall even when the device is Booted. Free memory before retrying: use \`stim stop\` only in workspaces you own, and ask before closing other apps or devices. For parallel iOS work, consider a reviewed SimSlim profile (\`stim guide lifecycle simslim\`). This observation does not establish an OOM crash.`;
23
+ }
24
+ //#endregion
6
25
  //#region src/sim/ios.ts
7
26
  function parseSimctlList(jsonOutput, { includeUnavailable = false } = {}) {
8
27
  const parsed = JSON.parse(jsonOutput);
@@ -42,8 +61,16 @@ function parseSimctlList(jsonOutput, { includeUnavailable = false } = {}) {
42
61
  }
43
62
  return sims;
44
63
  }
45
- function listAllIosSims({ timeoutMs, includeUnavailable = false } = {}) {
46
- return parseSimctlList(getExecutor().run("xcrun simctl list devices --json", { timeoutMs }), { includeUnavailable });
64
+ function listAllIosSims({ timeoutMs = 3e4, includeUnavailable = false } = {}) {
65
+ return parseSimctlList(getExecutor().runFile("xcrun", [
66
+ "simctl",
67
+ "list",
68
+ "devices",
69
+ "--json"
70
+ ], {
71
+ timeoutMs,
72
+ killSignal: "SIGKILL"
73
+ }), { includeUnavailable });
47
74
  }
48
75
  function parseRuntimeVersion(runtimeId) {
49
76
  const m = runtimeId.match(/iOS-(\d+)(?:-(\d+))?$/);
@@ -57,6 +84,9 @@ const IOS_BOOT_TIMEOUT_MS = 6e5;
57
84
  const BOOTSTATUS_ATTEMPT_MS = 24e4;
58
85
  const BOOTSTATUS_ATTEMPT_FLOOR_MS = 1e3;
59
86
  const BOOT_STATE_LIST_TIMEOUT_MS = 3e4;
87
+ function iosSimulatorFailureAdvice(exec = getExecutor()) {
88
+ return hostMemoryPressureAdvice(readHostMemoryPressure(exec)) ?? "The simulator may be unresponsive. Check Activity Monitor for memory pressure and free host memory before retrying.";
89
+ }
60
90
  function bootstatusTimeout(udid) {
61
91
  const e = /* @__PURE__ */ new Error(`xcrun simctl bootstatus ${udid} -b timed out`);
62
92
  e.code = "ETIMEDOUT";
@@ -86,11 +116,24 @@ async function awaitBootstatus(udid, attemptMs) {
86
116
  const attempt = new Promise((resolve) => {
87
117
  timer = setTimeout(() => resolve("timeout"), attemptMs);
88
118
  });
119
+ const exited = new Promise((resolve) => child.once("exit", () => resolve()));
89
120
  const result = await Promise.race([waitForChild(child), attempt]);
90
121
  clearTimeout(timer);
91
122
  reader.flush();
92
123
  if (result === "timeout") {
93
- child.kill("SIGKILL");
124
+ try {
125
+ child.kill("SIGKILL");
126
+ } catch {}
127
+ const stopped = await Promise.race([exited.then(() => true), new Promise((resolve) => {
128
+ timer = setTimeout(() => resolve(false), 1e4);
129
+ })]);
130
+ clearTimeout(timer);
131
+ if (!stopped) {
132
+ child.stdout?.destroy?.();
133
+ child.stderr?.destroy?.();
134
+ child.unref();
135
+ throw new Error(`Timed out waiting for simctl bootstatus ${udid}; its process could not be confirmed stopped. Inspect pid ${child.pid ?? "unknown"} before retrying.`);
136
+ }
94
137
  throw bootstatusTimeout(udid);
95
138
  }
96
139
  if (result.error) throw result.error;
@@ -100,12 +143,19 @@ async function awaitBootstatus(udid, attemptMs) {
100
143
  }
101
144
  async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = BOOTSTATUS_ATTEMPT_MS } = {}) {
102
145
  const exec = getExecutor();
146
+ const deadline = Date.now() + timeoutMs;
103
147
  try {
104
- exec.run(`xcrun simctl boot ${udid}`);
148
+ exec.runFile("xcrun", [
149
+ "simctl",
150
+ "boot",
151
+ udid
152
+ ], {
153
+ timeoutMs,
154
+ killSignal: "SIGKILL"
155
+ });
105
156
  } catch (e) {
106
157
  if (!String(e?.message || e).includes("Booted")) throw e;
107
158
  }
108
- const deadline = Date.now() + timeoutMs;
109
159
  for (;;) {
110
160
  const remaining = deadline - Date.now();
111
161
  if (remaining > 0) try {
@@ -125,13 +175,24 @@ async function bootIosSim(udid, { timeoutMs = IOS_BOOT_TIMEOUT_MS, attemptMs = B
125
175
  if (state !== "Booting" && state !== void 0) throw new Error(`Simulator ${udid} reports "${state ?? "missing"}" after ${waited}s of boot wait.`);
126
176
  if (deadline - Date.now() <= 0) throw new Error(`Simulator ${udid} did not finish booting within ${Math.round(timeoutMs / 1e3)}s.`);
127
177
  }
128
- exec.runQuiet("open -a Simulator");
178
+ exec.runFileQuiet("open", ["-a", "Simulator"], {
179
+ timeoutMs: 5e3,
180
+ killSignal: "SIGKILL"
181
+ });
129
182
  }
130
183
  function shutdownIosSim(udid) {
131
184
  getExecutor().runQuiet(`xcrun simctl shutdown ${udid}`);
132
185
  }
133
186
  function listIosDeviceTypes() {
134
- const out = getExecutor().run("xcrun simctl list devicetypes --json");
187
+ const out = getExecutor().runFile("xcrun", [
188
+ "simctl",
189
+ "list",
190
+ "devicetypes",
191
+ "--json"
192
+ ], {
193
+ timeoutMs: 3e4,
194
+ killSignal: "SIGKILL"
195
+ });
135
196
  return (JSON.parse(out).devicetypes || []).map((dt) => ({
136
197
  identifier: dt.identifier,
137
198
  name: dt.name
@@ -367,7 +428,15 @@ function deleteParkedIosSim(udid) {
367
428
  ], { timeoutMs: PARKED_DELETE_TIMEOUT_MS });
368
429
  }
369
430
  function listIosRuntimes() {
370
- const out = getExecutor().run("xcrun simctl list runtimes --json");
431
+ const out = getExecutor().runFile("xcrun", [
432
+ "simctl",
433
+ "list",
434
+ "runtimes",
435
+ "--json"
436
+ ], {
437
+ timeoutMs: 3e4,
438
+ killSignal: "SIGKILL"
439
+ });
371
440
  return (JSON.parse(out).runtimes || []).filter((r) => r.isAvailable && r.platform === "iOS").map((r) => ({
372
441
  identifier: r.identifier,
373
442
  name: r.name,
@@ -379,4 +448,4 @@ function listIosRuntimes() {
379
448
  }));
380
449
  }
381
450
  //#endregion
382
- export { uninstallIosApp as C, shutdownIosSim as S, resetIosKeychain as _, deleteIosSim as a, resolveOwnedIosSim as b, iosRuntimeMatches as c, listIosRuntimes as d, listUserApps as f, renameIosSim as g, parseRuntimeVersion as h, createOwnedIosSim as i, listAllIosSims as l, parkedSimName as m, bootIosSim as n, deleteParkedIosSim as o, ownedSimName as p, clearAppDataContainer as r, findAppDataContainer as s, IOS_BOOT_TIMEOUT_MS as t, listIosDeviceTypes as u, resetIosPrivacy as v, sanitizeDeviceLabel as x, resolveIosCreation as y };
451
+ export { shutdownIosSim as C, readHostMemoryPressure as E, sanitizeDeviceLabel as S, hostMemoryPressureAdvice as T, renameIosSim as _, deleteIosSim as a, resolveIosCreation as b, iosRuntimeMatches as c, listIosDeviceTypes as d, listIosRuntimes as f, parseRuntimeVersion as g, parkedSimName as h, createOwnedIosSim as i, iosSimulatorFailureAdvice as l, ownedSimName as m, bootIosSim as n, deleteParkedIosSim as o, listUserApps as p, clearAppDataContainer as r, findAppDataContainer as s, IOS_BOOT_TIMEOUT_MS as t, listAllIosSims as u, resetIosKeychain as v, uninstallIosApp as w, resolveOwnedIosSim as x, resetIosPrivacy as y };
@@ -1,4 +1,4 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
2
  //#region src/collector/ios-device.ts
3
3
  const CONSOLE_ENV = { OS_ACTIVITY_DT_MODE: "enable" };
4
4
  const DEV_MENU_LAUNCH_ARGS = [
@@ -1,5 +1,5 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
2
- import { r as INSTALL_ERROR } from "./app-install-oZIQRbdD.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
+ import { r as INSTALL_ERROR } from "./app-install-NFxUahnH.mjs";
3
3
  import { mkdtempSync, readFileSync, rmSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
@@ -1,8 +1,8 @@
1
1
  import { n as SOURCES, t as LEVELS } from "./ndjson-DcAtEx_K.mjs";
2
- import { D as workspaceLogsDir, p as readWorkspaceState } from "./state-IYEY-zi8.mjs";
3
- import { a as findProjectRoot } from "./project-COj6nzzh.mjs";
2
+ import { D as workspaceLogsDir, p as readWorkspaceState } from "./state-CZ-ER-8d.mjs";
3
+ import { a as findProjectRoot } from "./project-BBTVABUz.mjs";
4
4
  import { _ as launchErrorPreview } from "./command-output-8wHMEde0.mjs";
5
- import { i as captureWorkspaceCrashes, t as errorDiagnostics } from "./error-diagnostics-B5IJwv3-.mjs";
5
+ import { i as captureWorkspaceCrashes, t as errorDiagnostics } from "./error-diagnostics-Dw8Gn3yw.mjs";
6
6
  import { a as followLogs, i as fileSizes, n as buildCriteria, o as parseSince, r as compileGrep, s as queryLogs } from "./logs-query-oqn47Ffx.mjs";
7
7
  import chalk from "chalk";
8
8
  //#region src/commands/logs.ts
@@ -1,6 +1,6 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
2
- import { E as inspectProcessIdentity, M as isOnMountedVolume, N as listMountedVolumes, g as loadConfig, n as allMetroPorts, r as claimMetroPort, v as removeProject } from "./config-D7uu8Gbq.mjs";
3
- import { p as readWorkspaceState } from "./state-IYEY-zi8.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
+ import { E as inspectProcessIdentity, M as isOnMountedVolume, N as listMountedVolumes, g as loadConfig, n as allMetroPorts, r as claimMetroPort, v as removeProject } from "./config-CMtIaTk9.mjs";
3
+ import { p as readWorkspaceState } from "./state-CZ-ER-8d.mjs";
4
4
  import { existsSync, readlinkSync, realpathSync } from "fs";
5
5
  import { sep } from "path";
6
6
  import { request } from "http";
@@ -1,6 +1,6 @@
1
- import { D as sameProcessRecord, E as inspectProcessIdentity } from "./config-D7uu8Gbq.mjs";
2
- import { _ as writeWorkspaceState, m as withWorkspaceStateLock, p as readWorkspaceState } from "./state-IYEY-zi8.mjs";
3
- import { r as pidExists } from "./metro-B01H3EuD.mjs";
1
+ import { D as sameProcessRecord, E as inspectProcessIdentity } from "./config-CMtIaTk9.mjs";
2
+ import { _ as writeWorkspaceState, m as withWorkspaceStateLock, p as readWorkspaceState } from "./state-CZ-ER-8d.mjs";
3
+ import { r as pidExists } from "./metro-COslRK_F.mjs";
4
4
  import { realpathSync } from "node:fs";
5
5
  //#region src/collector/state.ts
6
6
  function collectorRoot(root) {
@@ -1,8 +1,8 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
2
- import { E as inspectProcessIdentity, T as captureProcessToken, u as getConfigDir } from "./config-D7uu8Gbq.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
+ import { E as inspectProcessIdentity, T as captureProcessToken, u as getConfigDir } from "./config-CMtIaTk9.mjs";
3
3
  import { t as createLineReader } from "./process-output-C7IlIzd7.mjs";
4
- import { r as pidExists } from "./metro-B01H3EuD.mjs";
5
- import { t as withWorkspaceProcessLock } from "./workspace-process-lock-CxOO9-pf.mjs";
4
+ import { r as pidExists } from "./metro-COslRK_F.mjs";
5
+ import { t as withWorkspaceProcessLock } from "./workspace-process-lock-BKfdys1q.mjs";
6
6
  import { closeSync, mkdirSync, openSync, readFileSync, unlinkSync } from "node:fs";
7
7
  import { createHash, randomUUID } from "node:crypto";
8
8
  import { basename, join, resolve, sep } from "node:path";
@@ -1,4 +1,4 @@
1
- import { E as inspectProcessIdentity, w as captureProcessIdentity } from "./config-D7uu8Gbq.mjs";
1
+ import { E as inspectProcessIdentity, w as captureProcessIdentity } from "./config-CMtIaTk9.mjs";
2
2
  import { d as quotedPath } from "./command-output-8wHMEde0.mjs";
3
3
  import { lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { randomUUID } from "node:crypto";
@@ -1,5 +1,5 @@
1
- import { c as findEnclosingWorktreeRoot, f as getProject } from "./config-D7uu8Gbq.mjs";
2
- import { g as repoRoot } from "./worktree-Dx3ZC5lS.mjs";
1
+ import { c as findEnclosingWorktreeRoot, f as getProject } from "./config-CMtIaTk9.mjs";
2
+ import { g as repoRoot } from "./worktree-C79xx_kM.mjs";
3
3
  import { existsSync, readFileSync, readdirSync, realpathSync } from "fs";
4
4
  import { basename, dirname, join, resolve } from "path";
5
5
  import { createRequire } from "module";
@@ -1,11 +1,11 @@
1
- import { D as sameProcessRecord, O as waitForProcessExit, f as getProject, v as removeProject } from "./config-D7uu8Gbq.mjs";
2
- import { T as workspaceDir, a as clearRemoteSession, c as readMetroTunnel, d as readRemoteSessionId, i as clearManagedMetroTunnel, p as readWorkspaceState } from "./state-IYEY-zi8.mjs";
3
- import { i as resolveProjectMetro, n as killMetroTree, r as pidExists } from "./metro-B01H3EuD.mjs";
4
- import { n as verifyCollectorOwnership } from "./ownership-D8HmSv2E.mjs";
5
- import { d as resolveEasCliBin, h as teardownOwnedIosSim, m as teardownOwnedAvd, x as parkedMaxSetting } from "./remote-cache-DOi5-zLj.mjs";
6
- import { l as releaseWorkspaceLeases } from "./device-lease-D-G3SgVe.mjs";
7
- import { i as endRecordedSession } from "./device-remote-CCgkG82J.mjs";
8
- import { r as stopTunnel, t as resolveSupervisorTarget } from "./ownership-B9QIdQOw.mjs";
1
+ import { D as sameProcessRecord, O as waitForProcessExit, f as getProject, v as removeProject } from "./config-CMtIaTk9.mjs";
2
+ import { T as workspaceDir, a as clearRemoteSession, c as readMetroTunnel, d as readRemoteSessionId, i as clearManagedMetroTunnel, p as readWorkspaceState } from "./state-CZ-ER-8d.mjs";
3
+ import { i as resolveProjectMetro, n as killMetroTree, r as pidExists } from "./metro-COslRK_F.mjs";
4
+ import { n as verifyCollectorOwnership } from "./ownership-CGPart6T.mjs";
5
+ import { d as resolveEasCliBin, h as teardownOwnedIosSim, m as teardownOwnedAvd, x as parkedMaxSetting } from "./remote-cache-DDmJ1Roq.mjs";
6
+ import { l as releaseWorkspaceLeases } from "./device-lease-Dpik41RY.mjs";
7
+ import { i as endRecordedSession } from "./device-remote-E81KAdXf.mjs";
8
+ import { r as stopTunnel, t as resolveSupervisorTarget } from "./ownership-CYOyqxUo.mjs";
9
9
  import { existsSync, rmSync } from "node:fs";
10
10
  //#region src/reclaim.ts
11
11
  async function reapCollectors(root, { verify = verifyCollectorOwnership, collectors }) {
@@ -207,6 +207,7 @@ function reclaimOwnedDevices(project, projectPath, { park = false } = {}) {
207
207
  const bound = parkedMaxSetting("android");
208
208
  const r = teardownOwnedAvd(android.avdName, {
209
209
  del: true,
210
+ owner: { projectPath },
210
211
  ...park && !bound.error && bound.max > 0 ? { park: {
211
212
  projectPath,
212
213
  max: bound.max,
@@ -1,11 +1,11 @@
1
- import { f as getProject } from "./config-D7uu8Gbq.mjs";
2
- import { f as readWorkspaceLaunches } from "./state-IYEY-zi8.mjs";
3
- import { a as findProjectRoot } from "./project-COj6nzzh.mjs";
4
- import { i as resolveProjectMetro } from "./metro-B01H3EuD.mjs";
1
+ import { f as getProject } from "./config-CMtIaTk9.mjs";
2
+ import { f as readWorkspaceLaunches } from "./state-CZ-ER-8d.mjs";
3
+ import { a as findProjectRoot } from "./project-BBTVABUz.mjs";
4
+ import { i as resolveProjectMetro } from "./metro-COslRK_F.mjs";
5
5
  import { l as phaseLine } from "./command-output-8wHMEde0.mjs";
6
- import { u as androidAppProcess, y as iosAppProcess } from "./app-install-oZIQRbdD.mjs";
7
- import { b as resolveOwnedIosSim } from "./ios-BZxKPuqP.mjs";
8
- import { A as resolveOwnedAvdSerial } from "./android-xmyGBNy5.mjs";
6
+ import { u as androidAppProcess, y as iosAppProcess } from "./app-install-NFxUahnH.mjs";
7
+ import { x as resolveOwnedIosSim } from "./ios-D1h1Di39.mjs";
8
+ import { N as resolveOwnedAvdSerial } from "./android-K63_0UfF.mjs";
9
9
  import chalk from "chalk";
10
10
  import { WebSocket } from "ws";
11
11
  //#region src/engine/reload.ts
@@ -1,16 +1,16 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
2
- import { C as withConfigLock, g as loadConfig, s as ensureConfig, y as saveConfig } from "./config-D7uu8Gbq.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
+ import { C as withConfigLock, g as loadConfig, s as ensureConfig, y as saveConfig } from "./config-CMtIaTk9.mjs";
3
3
  import { r as createNdjsonWriter } from "./ndjson-DcAtEx_K.mjs";
4
- import { D as workspaceLogsDir } from "./state-IYEY-zi8.mjs";
5
- import { l as resolvePackageJson } from "./project-COj6nzzh.mjs";
4
+ import { D as workspaceLogsDir } from "./state-CZ-ER-8d.mjs";
5
+ import { l as resolvePackageJson } from "./project-BBTVABUz.mjs";
6
6
  import { n as stripAnsi } from "./process-output-C7IlIzd7.mjs";
7
- import { S as shutdownIosSim, a as deleteIosSim, b as resolveOwnedIosSim, g as renameIosSim, h as parseRuntimeVersion, m as parkedSimName, o as deleteParkedIosSim, r as clearAppDataContainer, s as findAppDataContainer, u as listIosDeviceTypes } from "./ios-BZxKPuqP.mjs";
8
- import { A as resolveOwnedAvdSerial, C as ownedAvdMatchesConfiguration, M as shutdownAndroidEmulator, N as waitForAndroidEmulatorShutdown, T as ownedAvdSystemImage, d as deleteAvd, o as assertOwnedAvdStopped } from "./android-xmyGBNy5.mjs";
9
- import { n as expoBinFromPackage, r as expoBinPath, s as findBinUpward } from "./server-expo-BEMr_m6p.mjs";
7
+ import { C as shutdownIosSim, _ as renameIosSim, a as deleteIosSim, d as listIosDeviceTypes, g as parseRuntimeVersion, h as parkedSimName, o as deleteParkedIosSim, r as clearAppDataContainer, s as findAppDataContainer, x as resolveOwnedIosSim } from "./ios-D1h1Di39.mjs";
8
+ import { E as ownedAvdMatchesConfiguration, F as shutdownAndroidEmulator, I as waitForAndroidEmulatorShutdown, N as resolveOwnedAvdSerial, O as ownedAvdSystemImage, S as listOrphanedAvdDirectories, T as ownedAvdDirectory, l as avdStorageRoots, o as assertOwnedAvdStopped, p as deleteAvd, s as avdPathExists } from "./android-K63_0UfF.mjs";
9
+ import { n as expoBinFromPackage, r as expoBinPath, s as findBinUpward } from "./server-expo-C3ktAwUG.mjs";
10
10
  import { createRequire } from "node:module";
11
- import { existsSync, readFileSync } from "node:fs";
11
+ import { existsSync, lstatSync, readFileSync, renameSync, rmSync } from "node:fs";
12
12
  import { randomUUID } from "node:crypto";
13
- import { join } from "node:path";
13
+ import { dirname, join } from "node:path";
14
14
  import { pathToFileURL } from "node:url";
15
15
  import { format } from "node:util";
16
16
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -218,7 +218,10 @@ function dropParked(platform, udid) {
218
218
  function teardownParkedAvd(avdName) {
219
219
  try {
220
220
  return removeParkedAfter("android", avdName, () => {
221
- const result = teardownOwnedAvd(avdName, { del: true });
221
+ const result = teardownOwnedAvd(avdName, {
222
+ del: true,
223
+ owner: { pool: true }
224
+ });
222
225
  if (result.status !== "torn-down" && result.status !== "missing") throw new Error(result.reason);
223
226
  }) ? {
224
227
  status: "torn-down",
@@ -343,16 +346,68 @@ function teardownOwnedIosSim(udid, { del = false, label, park } = {}) {
343
346
  };
344
347
  }
345
348
  }
346
- function teardownOwnedAvd(avdName, { del = false, park, waitForShutdown = waitForAndroidEmulatorShutdown, assertStopped = assertOwnedAvdStopped, resolveAvd = resolveOwnedAvdSerial } = {}) {
349
+ function removeOrphanedAvdDirectory(candidate, owner) {
350
+ const detached = withConfigLock(() => {
351
+ const current = listOrphanedAvdDirectories(candidate.name).find((entry) => entry.directory === candidate.directory);
352
+ if (!current || current.name !== candidate.name || current.dev !== candidate.dev || current.ino !== candidate.ino) throw new Error(`AVD data at ${candidate.directory} changed or is registered; it was kept.`);
353
+ const config = loadConfig();
354
+ if (!config) throw new Error("Cannot verify AVD references without a Stim config; the data was kept.");
355
+ for (const [projectPath, project] of Object.entries(config.projects)) {
356
+ if (project.platforms?.android?.avdName !== candidate.name) continue;
357
+ if (!owner || !("projectPath" in owner) || owner.projectPath !== projectPath || !project.platforms.android.owned) throw new Error(`AVD ${candidate.name} is referenced by ${projectPath}; its data was kept.`);
358
+ }
359
+ if (readParked("android", { config }).some((entry) => entry.name === candidate.name) && !(owner && "pool" in owner)) throw new Error(`AVD ${candidate.name} is in the emulator pool; its data was kept.`);
360
+ assertOwnedAvdStopped(candidate.name, { resolveDirectory: () => candidate.directory });
361
+ const destination = join(dirname(candidate.directory), `stim-gc-${randomUUID()}.avd`);
362
+ renameSync(candidate.directory, destination);
363
+ return destination;
364
+ });
365
+ const current = lstatSync(detached);
366
+ if (!current.isDirectory() || current.dev !== candidate.dev || current.ino !== candidate.ino) throw new Error(`Detached AVD data changed at ${detached}; it was kept.`);
367
+ try {
368
+ rmSync(detached, { recursive: true });
369
+ } catch (error) {
370
+ throw new Error(`Could not remove AVD data at ${detached}; retry gc --delete: ${error.message}`, { cause: error });
371
+ }
372
+ }
373
+ function teardownUnregisteredAvd(avdName, del, owner, surveyed) {
374
+ const candidates = surveyed ? [surveyed] : listOrphanedAvdDirectories(avdName);
375
+ if (candidates.length === 0) {
376
+ if (avdStorageRoots().some((root) => avdPathExists(join(root, `${avdName}.ini`)) || avdPathExists(join(root, `${avdName}.avd`)))) throw new Error(`AVD ${avdName} is not listed but its storage remains; it was kept.`);
377
+ return { status: "missing" };
378
+ }
379
+ if (!del) return {
380
+ status: "skipped",
381
+ reason: "AVD registration is missing; its data was kept."
382
+ };
383
+ for (const candidate of candidates) {
384
+ if (candidate.name !== avdName) throw new Error(`AVD data does not match ${avdName}; it was kept.`);
385
+ removeOrphanedAvdDirectory(candidate, owner);
386
+ }
387
+ return {
388
+ status: "torn-down",
389
+ label: avdName
390
+ };
391
+ }
392
+ function teardownOwnedAvd(avdName, { del = false, park, owner, orphanedDirectory, waitForShutdown = waitForAndroidEmulatorShutdown, assertStopped = assertOwnedAvdStopped, resolveAvd = resolveOwnedAvdSerial } = {}) {
347
393
  let parkFallback;
348
394
  try {
395
+ if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return {
396
+ status: "skipped",
397
+ kind: "not-owned",
398
+ reason: `AVD ${avdName} is not Stim-owned by name`
399
+ };
349
400
  const resolved = resolveAvd(avdName);
350
401
  if (resolved.notOwned) return {
351
402
  status: "skipped",
352
403
  kind: "not-owned",
353
404
  reason: `AVD ${avdName} is not Stim-owned by name`
354
405
  };
355
- if (resolved.missing) return { status: "missing" };
406
+ if (resolved.missing) return teardownUnregisteredAvd(avdName, del, owner, orphanedDirectory);
407
+ if (orphanedDirectory) return {
408
+ status: "skipped",
409
+ reason: "AVD registration appeared; its data was kept."
410
+ };
356
411
  const serial = resolved.serial;
357
412
  if (serial) waitForShutdown(avdName, (timeoutMs) => shutdownAndroidEmulator(serial, timeoutMs));
358
413
  else assertStopped(avdName);
@@ -363,7 +418,7 @@ function teardownOwnedAvd(avdName, { del = false, park, waitForShutdown = waitFo
363
418
  kind: "not-owned",
364
419
  reason: `AVD ${avdName} is not Stim-owned by name`
365
420
  };
366
- if (current.missing) return { status: "missing" };
421
+ if (current.missing) return teardownUnregisteredAvd(avdName, del, owner);
367
422
  if (current.serial) throw new Error(`Owned AVD ${avdName} started again before deletion.`);
368
423
  assertStopped(avdName);
369
424
  if (park && park.max > 0) try {
@@ -406,7 +461,12 @@ function teardownOwnedAvd(avdName, { del = false, park, waitForShutdown = waitFo
406
461
  } catch (error) {
407
462
  parkFallback = String(error?.message || error);
408
463
  }
464
+ const directory = ownedAvdDirectory(avdName);
465
+ const paths = avdStorageRoots().map((root) => join(root, `${avdName}.ini`));
466
+ if (directory) paths.push(directory);
409
467
  deleteAvd(avdName);
468
+ const remaining = paths.filter(avdPathExists);
469
+ if (remaining.length) throw new Error(`AVD ${avdName} was only partially deleted; data remains at ${remaining.join(", ")}.`);
410
470
  }
411
471
  return {
412
472
  status: "torn-down",
@@ -1,6 +1,6 @@
1
- import { p as readWorkspaceState } from "./state-IYEY-zi8.mjs";
1
+ import { p as readWorkspaceState } from "./state-CZ-ER-8d.mjs";
2
2
  import { n as supervisorError } from "./errors-B6W7FkxQ.mjs";
3
- import { S as projectMetroSharedCache } from "./settings-BSwrY4FZ.mjs";
3
+ import { C as projectMetroSharedCache } from "./settings-DwU1_U_q.mjs";
4
4
  import { a as metroStoreRoot, o as registerMetroStore, t as appendCacheStore } from "./metro-store-CDDZHtPl.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import { dirname, isAbsolute, join, relative, sep } from "node:path";
@@ -13,6 +13,11 @@ var require_bundle_response = /* @__PURE__ */ __commonJSMin(((exports, module) =
13
13
  const { randomUUID } = __require("node:crypto");
14
14
  function bundleResponseMiddleware(write) {
15
15
  return (req, res, next) => {
16
+ if (req.method === "GET" && req.url === "/_stim/metro-warmup") {
17
+ res.end("ready");
18
+ return;
19
+ }
20
+ if (req.headers["x-stim-metro-warmup"] === "1") return next();
16
21
  let url;
17
22
  try {
18
23
  url = new URL(req.url, "http://localhost");
@@ -1,10 +1,10 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
2
  import { r as createNdjsonWriter } from "./ndjson-DcAtEx_K.mjs";
3
- import { p as readWorkspaceState } from "./state-IYEY-zi8.mjs";
4
- import { l as resolvePackageJson } from "./project-COj6nzzh.mjs";
3
+ import { p as readWorkspaceState } from "./state-CZ-ER-8d.mjs";
4
+ import { l as resolvePackageJson } from "./project-BBTVABUz.mjs";
5
5
  import { n as supervisorError } from "./errors-B6W7FkxQ.mjs";
6
6
  import { n as stripAnsi, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
7
- import { S as projectMetroSharedCache } from "./settings-BSwrY4FZ.mjs";
7
+ import { C as projectMetroSharedCache } from "./settings-DwU1_U_q.mjs";
8
8
  import { a as metroStoreRoot, i as metroStoreConfirmedRoot, n as expoMetroConfigPath, o as registerMetroStore, r as expoMetroStoreEnv } from "./metro-store-CDDZHtPl.mjs";
9
9
  import { accessSync, constants, existsSync, readFileSync } from "node:fs";
10
10
  import { dirname, join, parse } from "node:path";
@@ -0,0 +1,2 @@
1
+ import { p as startExpoServer } from "./server-expo-C3ktAwUG.mjs";
2
+ export { startExpoServer };
@@ -1,5 +1,5 @@
1
- import { d as getConfigPath, g as loadConfig, m as getRepoSettings, p as getProjectSettings } from "./config-D7uu8Gbq.mjs";
2
- import { g as repoRoot, s as gitCommonDir } from "./worktree-Dx3ZC5lS.mjs";
1
+ import { d as getConfigPath, g as loadConfig, m as getRepoSettings, p as getProjectSettings } from "./config-CMtIaTk9.mjs";
2
+ import { g as repoRoot, s as gitCommonDir } from "./worktree-C79xx_kM.mjs";
3
3
  import { createHash } from "node:crypto";
4
4
  import { isAbsolute } from "node:path";
5
5
  import { existsSync, readFileSync, realpathSync, statSync } from "fs";
@@ -11,6 +11,7 @@ const OPTIMIZATION_SHAPES = {
11
11
  "optimizations.remoteBuildCache": "boolean",
12
12
  "optimizations.releaseBundleSwap": "boolean",
13
13
  "optimizations.metroSharedCache": "boolean",
14
+ "optimizations.metroWarmup": "boolean",
14
15
  "optimizations.ios": "object",
15
16
  "optimizations.ios.compilationCache": "boolean",
16
17
  "optimizations.ios.swiftCompilationCache": "boolean",
@@ -78,6 +79,7 @@ function resolveOptimizations(settings = {}, env = process.env) {
78
79
  remoteBuildCache: optimizationBoolean(settings, "remoteBuildCache"),
79
80
  releaseBundleSwap: optimizationBoolean(settings, "releaseBundleSwap"),
80
81
  metroSharedCache: optimizationBoolean(settings, "metroSharedCache"),
82
+ metroWarmup: optimizationBoolean(settings, "metroWarmup"),
81
83
  ios: {
82
84
  compilationCache: optimizationBoolean(settings, "ios.compilationCache"),
83
85
  swiftCompilationCache: optimizationBoolean(settings, "ios.swiftCompilationCache", false),
@@ -209,6 +211,18 @@ const SETTING_SHAPE_RULES = {
209
211
  object: {
210
212
  expected: "an object",
211
213
  accepts: isPlainObject
214
+ },
215
+ "bundle-url": {
216
+ expected: "an HTTP(S) URL or /path ending in .bundle with a matching platform query and no fragment",
217
+ accepts: (value, key) => {
218
+ if (typeof value !== "string" || !/^(https?:\/\/|\/(?!\/))/.test(value) || /[\s\\#]/.test(value)) return false;
219
+ try {
220
+ const url = new URL(value, "http://localhost");
221
+ return /\.bundle\/*$/.test(url.pathname) && url.searchParams.get("platform") === key.split(".").at(-1);
222
+ } catch {
223
+ return false;
224
+ }
225
+ }
212
226
  }
213
227
  };
214
228
  const SETTING_SHAPES = {
@@ -232,6 +246,9 @@ const SETTING_SHAPES = {
232
246
  "metro.tunnel": "string",
233
247
  "metro.ngrokUrl": "string",
234
248
  "metro.publicUrl": "string",
249
+ "metro.warmupUrl": "object",
250
+ "metro.warmupUrl.ios": "bundle-url",
251
+ "metro.warmupUrl.android": "bundle-url",
235
252
  "worktree.exclude": "strings",
236
253
  "worktree.defaultBranch": "string",
237
254
  "cache.provider": "string",
@@ -256,7 +273,7 @@ function settingShapeErrors(settings) {
256
273
  const value = settingValueAt(settings, path);
257
274
  if (value === void 0) continue;
258
275
  const rule = SETTING_SHAPE_RULES[shape];
259
- if (rule.accepts(value)) continue;
276
+ if (rule.accepts(value, path)) continue;
260
277
  errors.push(`Invalid ${path} setting ${JSON.stringify(value)}. Expected ${rule.expected}.`);
261
278
  }
262
279
  return errors;
@@ -506,7 +523,7 @@ function unknownSettingKeys(settings, prefix = "") {
506
523
  const unknown = [];
507
524
  for (const [key, value] of Object.entries(settings)) {
508
525
  const path = prefix ? `${prefix}.${key}` : key;
509
- if (KNOWN_SETTINGS.has(path) && ![...KNOWN_SETTINGS].some((k) => k.startsWith(`${path}.`))) continue;
526
+ if (KNOWN_SETTINGS.has(path) && (!isPlainObject(value) || ![...KNOWN_SETTINGS].some((k) => k.startsWith(`${path}.`)))) continue;
510
527
  if (isPlainObject(value) && [...KNOWN_SETTINGS].some((k) => k.startsWith(`${path}.`))) {
511
528
  unknown.push(...unknownSettingKeys(value, path));
512
529
  continue;
@@ -669,6 +686,10 @@ function publicUrlSetting(settings) {
669
686
  const url = block.publicUrl;
670
687
  return typeof url === "string" && url.trim() ? url : null;
671
688
  }
689
+ function metroWarmupUrlSetting(settings, platform) {
690
+ const value = settingValueAt(settings, `metro.warmupUrl.${platform}`);
691
+ return typeof value === "string" ? value : null;
692
+ }
672
693
  function ngrokUrlSetting(settings) {
673
694
  const block = settings.metro;
674
695
  if (typeof block !== "object" || block === null) return null;
@@ -684,4 +705,4 @@ function normalizedHttpsUrl(raw) {
684
705
  }
685
706
  }
686
707
  //#endregion
687
- export { settingFile as A, compilerCacheFallbackMessage as B, projectOptimizations as C, remoteIosSetting as D, remoteDeviceSettingError as E, unknownSettingKeys as F, resolveOptimizations as H, PUBLIC_METRO_ENV as I, detectProviders as L, settingShapeErrors as M, settingsLayers as N, resolveCacheProviderConfig as O, tunnelModeSetting as P, planMetroReach as R, projectMetroSharedCache as S, remoteAndroidSetting as T, optimizationBuildProfile as V, iosSigningIdentitySha1SettingError as _, SETTING_SHAPE_REMEDY as a, metroTunnelSettingError as b, androidDataPartitionSizeBytes as c, cacheProviderSettingError as d, iosLanHostSetting as f, iosSigningIdentitySha1Setting as g, iosSigningIdentitySettingError as h, SETTINGS_WITH_RESOLVE_TIME_FALLBACK as i, settingOrigin as j, resolveSettings as k, androidDataPartitionSizeGbSetting as l, iosSigningIdentitySetting as m, PATH_SETTINGS as n, androidAvdConfigSetting as o, iosLanHostSettingError as p, REMOTE_DEVICE_BACKENDS as r, androidAvdConfigSettingError as s, ANDROID_AVD_CONFIG_HELP as t, androidDataPartitionSizeGbSettingError as u, iosSimSlimProfileSetting as v, publicUrlSetting as w, ngrokUrlSetting as x, mergeSettingsLayers as y, artifactCachePolicy as z };
708
+ export { resolveSettings as A, artifactCachePolicy as B, projectMetroSharedCache as C, remoteDeviceSettingError as D, remoteAndroidSetting as E, tunnelModeSetting as F, optimizationBuildProfile as H, unknownSettingKeys as I, PUBLIC_METRO_ENV as L, settingOrigin as M, settingShapeErrors as N, remoteIosSetting as O, settingsLayers as P, detectProviders as R, ngrokUrlSetting as S, publicUrlSetting as T, resolveOptimizations as U, compilerCacheFallbackMessage as V, iosSigningIdentitySha1SettingError as _, SETTING_SHAPE_REMEDY as a, metroTunnelSettingError as b, androidDataPartitionSizeBytes as c, cacheProviderSettingError as d, iosLanHostSetting as f, iosSigningIdentitySha1Setting as g, iosSigningIdentitySettingError as h, SETTINGS_WITH_RESOLVE_TIME_FALLBACK as i, settingFile as j, resolveCacheProviderConfig as k, androidDataPartitionSizeGbSetting as l, iosSigningIdentitySetting as m, PATH_SETTINGS as n, androidAvdConfigSetting as o, iosLanHostSettingError as p, REMOTE_DEVICE_BACKENDS as r, androidAvdConfigSettingError as s, ANDROID_AVD_CONFIG_HELP as t, androidDataPartitionSizeGbSettingError as u, iosSimSlimProfileSetting as v, projectOptimizations as w, metroWarmupUrlSetting as x, mergeSettingsLayers as y, planMetroReach as z };
@@ -1,18 +1,18 @@
1
- import { t as getExecutor } from "./exec-bsN9MJXb.mjs";
2
- import { E as inspectProcessIdentity, O as waitForProcessExit, S as upsertProject, T as captureProcessToken, a as clearSupervisor, f as getProject } from "./config-D7uu8Gbq.mjs";
3
- import { C as supervisorLogFile, D as workspaceLogsDir, _ as writeWorkspaceState, c as readMetroTunnel, i as clearManagedMetroTunnel, p as readWorkspaceState, s as clearWorkspaceSupervisor, y as ensureWorkspaceStorage } from "./state-IYEY-zi8.mjs";
4
- import { g as repoRoot, s as gitCommonDir } from "./worktree-Dx3ZC5lS.mjs";
5
- import { a as findProjectRoot, i as detectIsExpo, n as detectAndroidPackage, r as detectBundleId, t as appProjectProblem } from "./project-COj6nzzh.mjs";
1
+ import { t as getExecutor } from "./exec-CyylIdq9.mjs";
2
+ import { E as inspectProcessIdentity, O as waitForProcessExit, S as upsertProject, T as captureProcessToken, a as clearSupervisor, f as getProject } from "./config-CMtIaTk9.mjs";
3
+ import { C as supervisorLogFile, D as workspaceLogsDir, _ as writeWorkspaceState, c as readMetroTunnel, i as clearManagedMetroTunnel, p as readWorkspaceState, s as clearWorkspaceSupervisor, y as ensureWorkspaceStorage } from "./state-CZ-ER-8d.mjs";
4
+ import { g as repoRoot, s as gitCommonDir } from "./worktree-C79xx_kM.mjs";
5
+ import { a as findProjectRoot, i as detectIsExpo, n as detectAndroidPackage, r as detectBundleId, t as appProjectProblem } from "./project-BBTVABUz.mjs";
6
6
  import { n as supervisorError } from "./errors-B6W7FkxQ.mjs";
7
- import { i as resolveProjectMetro, n as killMetroTree, o as reserveMetroPort, r as pidExists } from "./metro-B01H3EuD.mjs";
8
- import { D as remoteIosSetting, E as remoteDeviceSettingError, F as unknownSettingKeys, I as PUBLIC_METRO_ENV, L as detectProviders, M as settingShapeErrors, O as resolveCacheProviderConfig, P as tunnelModeSetting, R as planMetroReach, T as remoteAndroidSetting, a as SETTING_SHAPE_REMEDY, b as metroTunnelSettingError, d as cacheProviderSettingError, k as resolveSettings, w as publicUrlSetting, x as ngrokUrlSetting } from "./settings-BSwrY4FZ.mjs";
7
+ import { i as resolveProjectMetro, n as killMetroTree, o as reserveMetroPort, r as pidExists } from "./metro-COslRK_F.mjs";
8
+ import { A as resolveSettings, D as remoteDeviceSettingError, E as remoteAndroidSetting, F as tunnelModeSetting, I as unknownSettingKeys, L as PUBLIC_METRO_ENV, N as settingShapeErrors, O as remoteIosSetting, R as detectProviders, S as ngrokUrlSetting, T as publicUrlSetting, a as SETTING_SHAPE_REMEDY, b as metroTunnelSettingError, d as cacheProviderSettingError, k as resolveCacheProviderConfig, z as planMetroReach } from "./settings-DwU1_U_q.mjs";
9
9
  import { g as stepTimer, l as phaseLine } from "./command-output-8wHMEde0.mjs";
10
- import { n as workspaceProcessLockError, t as withWorkspaceProcessLock } from "./workspace-process-lock-CxOO9-pf.mjs";
10
+ import { n as workspaceProcessLockError, t as withWorkspaceProcessLock } from "./workspace-process-lock-BKfdys1q.mjs";
11
11
  import { n as expoMetroConfigPath } from "./metro-store-CDDZHtPl.mjs";
12
- import { o as expoSdkMajor } from "./server-expo-BEMr_m6p.mjs";
12
+ import { o as expoSdkMajor } from "./server-expo-C3ktAwUG.mjs";
13
13
  import { t as spawnEntry } from "./spawn-entry-nCE6m770.mjs";
14
14
  import { s as queryLogs } from "./logs-query-oqn47Ffx.mjs";
15
- import { a as withManagedRemoteWorktreeLock, i as terminateChild, n as startTunnelSequence, r as stopTunnel, s as withManagedTunnelLock, t as resolveSupervisorTarget } from "./ownership-B9QIdQOw.mjs";
15
+ import { a as withManagedRemoteWorktreeLock, i as terminateChild, n as startTunnelSequence, r as stopTunnel, s as withManagedTunnelLock, t as resolveSupervisorTarget } from "./ownership-CYOyqxUo.mjs";
16
16
  import { mkdirSync, openSync, readFileSync } from "node:fs";
17
17
  import { randomUUID } from "node:crypto";
18
18
  import { dirname } from "node:path";
@@ -1,4 +1,4 @@
1
- import { D as sameProcessRecord, k as withDirLock, u as getConfigDir } from "./config-D7uu8Gbq.mjs";
1
+ import { D as sameProcessRecord, k as withDirLock, u as getConfigDir } from "./config-CMtIaTk9.mjs";
2
2
  import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
3
  import { dirname } from "node:path";
4
4
  import { join as join$1, resolve as resolve$1 } from "path";
@@ -1,4 +1,4 @@
1
- import { C as withConfigLock, u as getConfigDir } from "./config-D7uu8Gbq.mjs";
1
+ import { C as withConfigLock, u as getConfigDir } from "./config-CMtIaTk9.mjs";
2
2
  import { readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
3
  import { basename, dirname, join, relative, resolve } from "node:path";
4
4
  const PLATFORMS = ["ios", "android"];
@@ -1,7 +1,7 @@
1
- import { g as repoRoot, s as gitCommonDir } from "./worktree-Dx3ZC5lS.mjs";
2
- import { a as findProjectRoot } from "./project-COj6nzzh.mjs";
1
+ import { g as repoRoot, s as gitCommonDir } from "./worktree-C79xx_kM.mjs";
2
+ import { a as findProjectRoot } from "./project-BBTVABUz.mjs";
3
3
  import { o as formatLongDuration } from "./command-output-8wHMEde0.mjs";
4
- import { a as statsProjectKey, r as readStats } from "./stats-wqxPm7Tv.mjs";
4
+ import { a as statsProjectKey, r as readStats } from "./stats-BCWEVLrM.mjs";
5
5
  import chalk from "chalk";
6
6
  //#region src/commands/stats.ts
7
7
  const PLATFORMS = ["ios", "android"];