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,12 +1,198 @@
1
- import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
- import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig, n as allMetroPorts, r as claimMetroPort, x as releaseMetroPort } from "./config-D0DbpZtM.mjs";
3
- import { t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
4
- import { r as readWorkspaceState } from "./workspace-state-DqcCbpE7.mjs";
5
- import { existsSync, readlinkSync, realpathSync } from "fs";
1
+ import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
+ import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
3
+ import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig, n as allMetroPorts, r as claimMetroPort, x as releaseMetroPort } from "./config-DC5jEtd1.mjs";
4
+ import { r as readWorkspaceState } from "./workspace-state-CR9X86xJ.mjs";
6
5
  import { sep } from "path";
6
+ import { existsSync, readlinkSync, realpathSync } from "fs";
7
+ import { readFile } from "node:fs/promises";
7
8
  import { request } from "http";
8
- import { connect } from "net";
9
+ import { connect } from "node:net";
10
+ //#region src/listening-ports.ts
11
+ /**
12
+ * Returns occupied TCP ports across local interfaces. Rejects if listener inspection fails.
13
+ */
14
+ async function readListeningPorts(platform = process.platform) {
15
+ switch (platform) {
16
+ case "darwin": return parseDarwinPorts(await readNetstat("/usr/sbin/netstat", [
17
+ "-anL",
18
+ "-p",
19
+ "tcp"
20
+ ]));
21
+ case "linux": return parseLinuxPorts(await Promise.all([readFile("/proc/net/tcp", "utf8"), readFile("/proc/net/tcp6", "utf8").catch((error) => {
22
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
23
+ throw error;
24
+ })]));
25
+ case "win32": return parseWindowsPorts(await readNetstat("netstat", ["-an"]));
26
+ default: throw new Error(`TCP listener inspection is not supported on ${platform}.`);
27
+ }
28
+ }
29
+ const DARWIN_TITLE = "Current listen queue sizes (qlen/incqlen/maxqlen)";
30
+ const DARWIN_COLUMNS = /^Listen\s+Local Address$/;
31
+ const DARWIN_TABLE_CHANGE = /^Some tcp sockets may have been (?:created|deleted|created or deleted)\.?$/;
32
+ const DARWIN_LISTENER = /^\d+\/\d+\/\d+\s+\S+\.(?<port>\d+)$/;
33
+ function parseDarwinPorts(output) {
34
+ const ports = /* @__PURE__ */ new Set();
35
+ let title = false;
36
+ let columns = false;
37
+ for (const raw of output.split("\n")) {
38
+ const line = raw.trim();
39
+ if (line === DARWIN_TITLE) title = true;
40
+ else if (DARWIN_COLUMNS.test(line)) columns = true;
41
+ if (!line || line === DARWIN_TITLE || DARWIN_COLUMNS.test(line) || DARWIN_TABLE_CHANGE.test(line)) continue;
42
+ const listener = DARWIN_LISTENER.exec(line)?.groups;
43
+ if (!listener) throw new Error("Cannot parse the TCP listen table from netstat.");
44
+ addPort(ports, Number(listener.port));
45
+ }
46
+ if (!title || !columns) throw new Error("netstat printed no TCP listen table.");
47
+ return ports;
48
+ }
49
+ const LINUX_COLUMNS = /^\s*sl\s+local_address\s+rem(?:ote)?_address\s+st\s/;
50
+ const LINUX_TCP_STATE = /^[0-9A-F]{2}$/i;
51
+ const LINUX_LOCAL_ADDRESS = /^(?:[0-9A-F]{8}|[0-9A-F]{32}):(?<port>[0-9A-F]{4})$/i;
52
+ const LINUX_LISTEN_STATE = "0A";
53
+ function parseLinuxPorts(tables) {
54
+ const ports = /* @__PURE__ */ new Set();
55
+ for (const table of tables) {
56
+ if (table === null) continue;
57
+ const [header, ...rows] = table.trim().split("\n");
58
+ if (!header || !LINUX_COLUMNS.test(header)) throw new Error("Cannot parse the TCP socket table from /proc/net.");
59
+ for (const raw of rows) {
60
+ const line = raw.trim();
61
+ if (!line) continue;
62
+ const [, localAddress, , state] = line.split(/\s+/);
63
+ if (!state || !LINUX_TCP_STATE.test(state)) throw new Error("Invalid TCP state in /proc/net.");
64
+ if (state.toUpperCase() !== LINUX_LISTEN_STATE) continue;
65
+ const listener = localAddress && LINUX_LOCAL_ADDRESS.exec(localAddress)?.groups;
66
+ if (!listener) throw new Error("Invalid TCP listener in /proc/net.");
67
+ addPort(ports, Number(`0x${listener.port}`));
68
+ }
69
+ }
70
+ return ports;
71
+ }
72
+ const WINDOWS_COLUMNS = /^Proto\s/;
73
+ const WINDOWS_TCP_ROW = /^TCP\s+\S*:(?<localPort>\d+)\s+\S*:(?<remotePort>\d+)\s+\S/;
74
+ function parseWindowsPorts(output) {
75
+ const ports = /* @__PURE__ */ new Set();
76
+ let table = false;
77
+ for (const raw of output.split("\n")) {
78
+ const line = raw.trim();
79
+ if (WINDOWS_COLUMNS.test(line)) table = true;
80
+ const [protocol] = line.split(/\s+/, 1);
81
+ if (protocol !== "TCP") continue;
82
+ table = true;
83
+ const connection = WINDOWS_TCP_ROW.exec(line)?.groups;
84
+ if (!connection) throw new Error("Cannot parse the TCP connection table from netstat.");
85
+ if (Number(connection.remotePort) === 0) addPort(ports, Number(connection.localPort));
86
+ }
87
+ if (!table) throw new Error("netstat printed no TCP connection table.");
88
+ return ports;
89
+ }
90
+ function readNetstat(file, args) {
91
+ return getExecutor().runFileAsync(file, args, {
92
+ timeoutMs: 5e3,
93
+ rejectStderr: true,
94
+ env: { LC_ALL: "C" }
95
+ });
96
+ }
97
+ function addPort(ports, port) {
98
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid TCP listener port.");
99
+ ports.add(port);
100
+ }
101
+ function addressPort(address) {
102
+ const colon = String(address ?? "").lastIndexOf(":");
103
+ return colon < 0 ? NaN : Number(String(address).slice(colon + 1));
104
+ }
105
+ function parseLsofListeners(out) {
106
+ const byPort = /* @__PURE__ */ new Map();
107
+ let pid = null;
108
+ for (const line of String(out ?? "").split("\n")) if (line.startsWith("p")) pid = parseInt(line.slice(1), 10);
109
+ else if (line.startsWith("n") && pid !== null && Number.isFinite(pid)) {
110
+ const port = addressPort(line.slice(1));
111
+ const pids = byPort.get(port) ?? [];
112
+ if (!pids.includes(pid)) pids.push(pid);
113
+ byPort.set(port, pids);
114
+ }
115
+ return byPort;
116
+ }
117
+ const PORT_INSPECTION_REMEDY = "Allow Stim to run netstat or lsof, or to connect to 127.0.0.1 and ::1, then retry. A metro.port pin skips the scan for Metro.";
118
+ var PortInspectionError = class extends Error {
119
+ code = "STIM_PORT_INSPECTION_FAILED";
120
+ reason;
121
+ constructor(reason) {
122
+ super(`${reason} ${PORT_INSPECTION_REMEDY}`);
123
+ this.reason = reason;
124
+ }
125
+ };
126
+ /**
127
+ * Returns the TCP ports lsof lists as listening, or null when lsof cannot list them.
128
+ */
129
+ async function readLsofListeningPorts() {
130
+ try {
131
+ const out = await getExecutor().runFileAsync("lsof", [
132
+ "-nP",
133
+ "-iTCP",
134
+ "-sTCP:LISTEN",
135
+ "-Fpn"
136
+ ], { timeoutMs: 5e3 });
137
+ return new Set([...parseLsofListeners(out).keys()].filter(Number.isInteger));
138
+ } catch (error) {
139
+ const result = error;
140
+ if (result.status === 1 && !String(result.stdout ?? "").trim() && !String(result.stderr ?? "").trim()) return /* @__PURE__ */ new Set();
141
+ return null;
142
+ }
143
+ }
144
+ const IPV6_UNAVAILABLE = /* @__PURE__ */ new Set([
145
+ "EADDRNOTAVAIL",
146
+ "EAFNOSUPPORT",
147
+ "ENETUNREACH"
148
+ ]);
149
+ /**
150
+ * Connects to a loopback port: `taken` when something accepts or the connect hangs, `free` when
151
+ * it is refused or IPv6 is unavailable, `unknown` for any other connect error.
152
+ */
153
+ function probeLoopback(port, host, timeoutMs = 400) {
154
+ return new Promise((resolve) => {
155
+ const socket = connect({
156
+ port,
157
+ host
158
+ });
159
+ const done = (answer) => {
160
+ socket.removeAllListeners();
161
+ socket.destroy();
162
+ resolve(answer);
163
+ };
164
+ socket.setTimeout(timeoutMs);
165
+ socket.once("connect", () => done("taken"));
166
+ socket.once("timeout", () => done("taken"));
167
+ socket.once("error", (error) => {
168
+ const refused = error.code === "ECONNREFUSED" || host === "::1" && IPV6_UNAVAILABLE.has(error.code ?? "");
169
+ done(refused ? "free" : "unknown");
170
+ });
171
+ });
172
+ }
173
+ //#endregion
9
174
  //#region src/ports.ts
175
+ /**
176
+ * Creates one lazy listener snapshot for an allocation attempt; discard the probe before retrying.
177
+ * When the native TCP table cannot be read, each port is checked with an lsof listener scan and
178
+ * loopback connects instead. Rejects with `PortInspectionError` only when none of them can answer.
179
+ */
180
+ function createPortProbe() {
181
+ let snapshot;
182
+ let lsof;
183
+ return async (port) => {
184
+ const listening = await (snapshot ??= readListeningPorts().catch((error) => error instanceof Error ? error : new Error(String(error))));
185
+ if (!(listening instanceof Error)) return !listening.has(port);
186
+ const [listed, ipv4, ipv6] = await Promise.all([
187
+ lsof ??= readLsofListeningPorts(),
188
+ probeLoopback(port, "127.0.0.1"),
189
+ probeLoopback(port, "::1")
190
+ ]);
191
+ if (listed?.has(port) || ipv4 === "taken" || ipv6 === "taken") return false;
192
+ if (listed || ipv4 === "free" && ipv6 === "free") return true;
193
+ throw new PortInspectionError(`Cannot tell whether TCP port ${port} is free: the TCP listener table failed (${listening.message.replace(/\s+/g, " ").trim()}), lsof could not list listeners, and a loopback connect failed.`);
194
+ };
195
+ }
10
196
  function isMetroRunning(port) {
11
197
  return new Promise((resolve) => {
12
198
  const req = request({
@@ -29,25 +215,8 @@ function isMetroRunning(port) {
29
215
  req.end();
30
216
  });
31
217
  }
32
- function isPortFree(port, { timeoutMs = 400 } = {}) {
33
- return new Promise((resolve) => {
34
- const sock = connect({
35
- port,
36
- host: "127.0.0.1"
37
- });
38
- const done = (free) => {
39
- sock.removeAllListeners();
40
- sock.destroy();
41
- resolve(free);
42
- };
43
- sock.setTimeout(timeoutMs);
44
- sock.once("connect", () => done(false));
45
- sock.once("error", () => done(true));
46
- sock.once("timeout", () => done(false));
47
- });
48
- }
49
218
  const FIRST_PORT = 8082;
50
- async function computeNextPort(isFree = isPortFree) {
219
+ async function computeNextPort(isFree = createPortProbe()) {
51
220
  const taken = new Set(allMetroPorts());
52
221
  for (let port = FIRST_PORT; port < 8282; port++) {
53
222
  if (taken.has(port)) continue;
@@ -73,7 +242,7 @@ async function findReclaimablePort(excludeProjectPath, probe = isMetroRunning, {
73
242
  for (const c of candidates) if (!await probe(c.port)) return c;
74
243
  return null;
75
244
  }
76
- async function allocatePort(projectPath, probe = isMetroRunning, isFree = isPortFree) {
245
+ async function allocatePort(projectPath, probe = isMetroRunning, isFree = createPortProbe()) {
77
246
  const reclaim = await findReclaimablePort(projectPath, probe);
78
247
  if (reclaim && await isFree(reclaim.port)) {
79
248
  releaseMetroPort(reclaim.ownerPath, reclaim.port);
@@ -82,7 +251,7 @@ async function allocatePort(projectPath, probe = isMetroRunning, isFree = isPort
82
251
  return computeNextPort(isFree);
83
252
  }
84
253
  const RESERVE_ATTEMPTS = 5;
85
- async function reserveMetroPort(projectPath, probe = isMetroRunning, isFree = isPortFree, pinned = null) {
254
+ async function reserveMetroPort(projectPath, probe = isMetroRunning, isFree, pinned = null) {
86
255
  if (pinned !== null) {
87
256
  if (claimMetroPort(projectPath, pinned) !== null) return pinned;
88
257
  throw new Error(`metro.port ${pinned} is already reserved by another workspace's Metro or named port.`);
@@ -116,10 +285,6 @@ function parseLsofPids(out) {
116
285
  if (!out) return [];
117
286
  return String(out).split("\n").map((s) => parseInt(s.trim(), 10)).filter((n) => Number.isFinite(n));
118
287
  }
119
- function addressPort(address) {
120
- const colon = String(address ?? "").lastIndexOf(":");
121
- return colon < 0 ? NaN : Number(String(address).slice(colon + 1));
122
- }
123
288
  function parseNetstatPids(out, port) {
124
289
  const pids = [];
125
290
  for (const line of String(out ?? "").split("\n")) {
@@ -147,18 +312,6 @@ function parseLsofCwd(out) {
147
312
  function lsofOutput(args) {
148
313
  return getExecutor().runFileAsync("lsof", args).catch((error) => typeof error?.stdout === "string" ? error.stdout : null);
149
314
  }
150
- function parseLsofListeners(out) {
151
- const byPort = /* @__PURE__ */ new Map();
152
- let pid = null;
153
- for (const line of String(out ?? "").split("\n")) if (line.startsWith("p")) pid = parseInt(line.slice(1), 10);
154
- else if (line.startsWith("n") && pid !== null && Number.isFinite(pid)) {
155
- const port = addressPort(line.slice(1));
156
- const pids = byPort.get(port) ?? [];
157
- if (!pids.includes(pid)) pids.push(pid);
158
- byPort.set(port, pids);
159
- }
160
- return byPort;
161
- }
162
315
  /**
163
316
  * `listeningPids` for several ports with one lsof call. A port lsof could not be asked about is
164
317
  * missing from the map.
@@ -306,4 +459,4 @@ function killMetroTree(leader, processToken) {
306
459
  }
307
460
  }
308
461
  //#endregion
309
- export { listeningPidsByPort as a, processCwds as c, isMetroRunning as d, isPortFree as f, listeningPids as i, resolveProjectMetro as l, isInsideProject as n, pidExists as o, reserveMetroPort as p, killMetroTree as r, processCwd as s, NOT_OURS_FOREIGN_CWD as t, signalProcessTree as u };
462
+ export { listeningPidsByPort as a, processCwd as c, signalProcessTree as d, createPortProbe as f, PortInspectionError as g, PORT_INSPECTION_REMEDY as h, listeningPids as i, processCwds as l, reserveMetroPort as m, isInsideProject as n, parseNetstatPids as o, isMetroRunning as p, killMetroTree as r, pidExists as s, NOT_OURS_FOREIGN_CWD as t, resolveProjectMetro as u };
@@ -1,8 +1,8 @@
1
- import { t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
2
- import { a as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-DqcCbpE7.mjs";
3
- import { S as realIo } from "./client-SvBdgObD.mjs";
4
- import { randomBytes, randomUUID } from "node:crypto";
1
+ import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
+ import { a as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-CR9X86xJ.mjs";
3
+ import { L as realIo } from "./client-CuUo8Nvg.mjs";
5
4
  import { HOSTED_METRO_REQUESTS_KEY, findPeer, hostedMetroGateways, hostedMetroRequests, isJsonObject, parseMachine } from "@stim-cli/core/state";
5
+ import { randomBytes, randomUUID } from "node:crypto";
6
6
  import { isIP } from "node:net";
7
7
  //#region src/device-host/metro-gateway.ts
8
8
  function gatewayAddresses(credential, status) {
@@ -1,7 +1,21 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { dirname, join, resolve } from "node:path";
3
- import { METRO_NAMED_CACHE_LAYOUT, metroCacheRoot, registerCache, sharedStoreRoot, tagSharedStore } from "@stim-cli/core";
4
3
  import { fileURLToPath } from "node:url";
4
+ import { METRO_NAMED_CACHE_LAYOUT, metroCacheRoot, registerCache, sharedStoreRoot, tagSharedStore } from "@stim-cli/core";
5
+ //#region src/supervisor/errors.ts
6
+ function supervisorError(code, message, remedy) {
7
+ const err = new Error(message);
8
+ err.code = code;
9
+ if (remedy) err.remedy = remedy;
10
+ return err;
11
+ }
12
+ function describeError(err) {
13
+ if (!err) return "unknown error";
14
+ const e = err;
15
+ const message = e.message || String(err);
16
+ return `${e.code ? `${e.code}: ` : ""}${message}${e.remedy ? ` Remedy: ${e.remedy}` : ""}`;
17
+ }
18
+ //#endregion
5
19
  //#region src/supervisor/metro-store.ts
6
20
  function metroStoreName(root) {
7
21
  try {
@@ -89,4 +103,4 @@ function expoMetroStoreEnv({ root, storeRoot, adapterPath, existingOverride }) {
89
103
  };
90
104
  }
91
105
  //#endregion
92
- export { metroStoreRoot as a, metroStoreConfirmedRoot as i, expoMetroConfigPath as n, registerMetroStore as o, expoMetroStoreEnv as r, appendCacheStore as t };
106
+ export { metroStoreRoot as a, supervisorError as c, metroStoreConfirmedRoot as i, expoMetroConfigPath as n, registerMetroStore as o, expoMetroStoreEnv as r, describeError as s, appendCacheStore as t };