@swmansion/argent 0.31.2-next.4 → 0.31.2-next.6

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.
package/dist/cli-cmds.mjs CHANGED
@@ -35797,7 +35797,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
35797
35797
  var SESSION_ID2 = randomUUID5();
35798
35798
  function readCliVersion() {
35799
35799
  if (true) {
35800
- return "0.31.2-next.3";
35800
+ return "0.31.2-next.6";
35801
35801
  }
35802
35802
  return "0.0.0";
35803
35803
  }
@@ -16922,7 +16922,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16922
16922
  var SESSION_ID = randomUUID4();
16923
16923
  function readCliVersion() {
16924
16924
  if (true) {
16925
- return "0.31.2-next.3";
16925
+ return "0.31.2-next.6";
16926
16926
  }
16927
16927
  return "0.0.0";
16928
16928
  }
@@ -101080,7 +101080,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
101080
101080
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
101081
101081
  function readCliVersion() {
101082
101082
  if (true) {
101083
- return "0.31.2-next.3";
101083
+ return "0.31.2-next.6";
101084
101084
  }
101085
101085
  return "0.0.0";
101086
101086
  }
@@ -158868,8 +158868,8 @@ var import_util14 = require("util");
158868
158868
  var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
158869
158869
  var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
158870
158870
  async function execFileAsyncWithTimeout(file2, args, options = {}) {
158871
- const execFileAsync37 = (0, import_util14.promisify)(import_child_process2.execFile);
158872
- const { stdout, stderr } = await execFileAsync37(file2, args, {
158871
+ const execFileAsync36 = (0, import_util14.promisify)(import_child_process2.execFile);
158872
+ const { stdout, stderr } = await execFileAsync36(file2, args, {
158873
158873
  encoding: "utf-8",
158874
158874
  ...options,
158875
158875
  // Applied after ...options so a caller cannot weaken the guards; maxBuffer
@@ -179026,18 +179026,68 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
179026
179026
 
179027
179027
  // ../tool-server/src/utils/simulator-watcher.ts
179028
179028
  var fs69 = __toESM(require("node:fs"));
179029
- var import_node_child_process45 = require("node:child_process");
179030
- var import_node_util33 = require("node:util");
179031
179029
  init_external_devices();
179032
- var execFileAsync36 = (0, import_node_util33.promisify)(import_node_child_process45.execFile);
179030
+
179031
+ // ../tool-server/src/utils/simctl-exec.ts
179032
+ var import_node_child_process45 = require("node:child_process");
179033
+ var SimctlTimeoutError = class extends Error {
179034
+ constructor(args, timeoutMs) {
179035
+ super(`xcrun ${args.join(" ")} did not answer within ${timeoutMs} ms`);
179036
+ this.name = "SimctlTimeoutError";
179037
+ }
179038
+ };
179039
+ function execSimctl(args, options = {}) {
179040
+ const timeoutMs = options.timeoutMs ?? SIMCTL_SPAWN_TIMEOUT_MS;
179041
+ return new Promise((resolve16, reject) => {
179042
+ if (options.signal?.aborted) {
179043
+ reject(new Error(`xcrun ${args.join(" ")} aborted`));
179044
+ return;
179045
+ }
179046
+ const child = (0, import_node_child_process45.spawn)("xcrun", args, { detached: true, stdio: ["ignore", "pipe", "pipe"] });
179047
+ let stdout = "";
179048
+ let stderr = "";
179049
+ let settled = false;
179050
+ child.stdout.setEncoding("utf8").on("data", (chunk) => stdout += chunk);
179051
+ child.stderr.setEncoding("utf8").on("data", (chunk) => stderr += chunk);
179052
+ const settle3 = (err) => {
179053
+ if (settled) return;
179054
+ settled = true;
179055
+ clearTimeout(timer);
179056
+ options.signal?.removeEventListener("abort", onAbort);
179057
+ if (err) reject(err);
179058
+ else resolve16(stdout);
179059
+ };
179060
+ const killGroup2 = () => {
179061
+ if (child.pid) signalGroup(child.pid, "SIGKILL");
179062
+ };
179063
+ const onAbort = () => {
179064
+ killGroup2();
179065
+ settle3(new Error(`xcrun ${args.join(" ")} aborted`));
179066
+ };
179067
+ const timer = setTimeout(() => {
179068
+ killGroup2();
179069
+ settle3(new SimctlTimeoutError(args, timeoutMs));
179070
+ }, timeoutMs);
179071
+ options.signal?.addEventListener("abort", onAbort, { once: true });
179072
+ child.on("error", (err) => settle3(err));
179073
+ child.on("close", (code, sig) => {
179074
+ if (code === 0) return settle3(null);
179075
+ settle3(
179076
+ new Error(
179077
+ `xcrun ${args.join(" ")} exited with ${sig ?? `code ${code}`}` + (stderr.trim() ? `: ${stderr.trim()}` : "")
179078
+ )
179079
+ );
179080
+ });
179081
+ });
179082
+ }
179083
+
179084
+ // ../tool-server/src/utils/simulator-watcher.ts
179033
179085
  var POLL_INTERVAL_MS2 = 1e4;
179034
- async function getBootedUdidsInSet(deviceSet) {
179035
- const { stdout } = await execFileAsync36("xcrun", [
179036
- ...simctlPrefix(deviceSet),
179037
- "list",
179038
- "devices",
179039
- "--json"
179040
- ]);
179086
+ var MAX_BACKOFF_TICKS = 29;
179087
+ async function getBootedUdidsInSet(deviceSet, signal) {
179088
+ const stdout = await execSimctl([...simctlPrefix(deviceSet), "list", "devices", "--json"], {
179089
+ signal
179090
+ });
179041
179091
  const data = JSON.parse(stdout);
179042
179092
  const udids = /* @__PURE__ */ new Set();
179043
179093
  for (const devices of Object.values(data.devices)) {
@@ -179050,13 +179100,17 @@ async function getBootedUdidsInSet(deviceSet) {
179050
179100
  }
179051
179101
  return udids;
179052
179102
  }
179053
- async function getBootedUdids() {
179103
+ async function getBootedUdids(signal) {
179054
179104
  const sets = [
179055
179105
  null,
179056
179106
  ...configuredAdditionalDeviceSets().filter((p) => fs69.existsSync(p))
179057
179107
  ];
179058
- const perSet = await Promise.all(sets.map(getBootedUdidsInSet));
179059
- return new Set(perSet.flatMap((s) => [...s]));
179108
+ const perSet = await Promise.allSettled(sets.map((set2) => getBootedUdidsInSet(set2, signal)));
179109
+ const failures = perSet.flatMap((r) => r.status === "rejected" ? [r.reason] : []);
179110
+ if (failures.length) {
179111
+ throw failures.find((err) => err instanceof SimctlTimeoutError) ?? failures[0];
179112
+ }
179113
+ return new Set(perSet.flatMap((r) => r.status === "fulfilled" ? [...r.value] : []));
179060
179114
  }
179061
179115
  async function initUdid(registry2, udid, trackedServices) {
179062
179116
  const ndRef = nativeDevtoolsRef({ id: udid, platform: "ios", kind: "simulator" });
@@ -179069,6 +179123,9 @@ async function initUdid(registry2, udid, trackedServices) {
179069
179123
  function startSimulatorWatcher(registry2) {
179070
179124
  const trackedServices = /* @__PURE__ */ new Map();
179071
179125
  const reportedSkips = /* @__PURE__ */ new Set();
179126
+ const stopController = new AbortController();
179127
+ let consecutiveTimeouts = 0;
179128
+ let ticksToSkip = 0;
179072
179129
  function withoutForeignSimulators(booted) {
179073
179130
  const ours = /* @__PURE__ */ new Set();
179074
179131
  const claimed = /* @__PURE__ */ new Set();
@@ -179117,10 +179174,23 @@ function startSimulatorWatcher(registry2) {
179117
179174
  let booted;
179118
179175
  let claimed;
179119
179176
  try {
179120
- ({ ours: booted, claimed } = withoutForeignSimulators(await getBootedUdids()));
179121
- } catch {
179177
+ ({ ours: booted, claimed } = withoutForeignSimulators(
179178
+ await getBootedUdids(stopController.signal)
179179
+ ));
179180
+ } catch (err) {
179181
+ if (err instanceof SimctlTimeoutError) {
179182
+ consecutiveTimeouts += 1;
179183
+ ticksToSkip = Math.min(2 ** consecutiveTimeouts - 1, MAX_BACKOFF_TICKS);
179184
+ if (consecutiveTimeouts === 1) {
179185
+ process.stderr.write(
179186
+ `[simulator-watcher] ${err.message}; retrying with backoff until it does. If Xcode was just updated, open Xcode once or run \`sudo xcodebuild -runFirstLaunch\`.
179187
+ `
179188
+ );
179189
+ }
179190
+ }
179122
179191
  return;
179123
179192
  }
179193
+ consecutiveTimeouts = 0;
179124
179194
  await handBackClaimed(claimed);
179125
179195
  const newUdids = [...booted].filter((udid) => !trackedServices.has(udid));
179126
179196
  const pendingAttempts = newUdids.map(
@@ -179145,9 +179215,24 @@ function startSimulatorWatcher(registry2) {
179145
179215
  }
179146
179216
  }
179147
179217
  const ready2 = poll(true);
179148
- const interval2 = setInterval(() => poll(false).catch(() => {
179149
- }), POLL_INTERVAL_MS2);
179150
- return { stop: () => clearInterval(interval2), ready: ready2 };
179218
+ let inFlight2 = ready2.catch(() => {
179219
+ }).finally(() => inFlight2 = null);
179220
+ const interval2 = setInterval(() => {
179221
+ if (inFlight2) return;
179222
+ if (ticksToSkip > 0) {
179223
+ ticksToSkip -= 1;
179224
+ return;
179225
+ }
179226
+ inFlight2 = poll(false).catch(() => {
179227
+ }).finally(() => inFlight2 = null);
179228
+ }, POLL_INTERVAL_MS2);
179229
+ return {
179230
+ stop: () => {
179231
+ clearInterval(interval2);
179232
+ stopController.abort();
179233
+ },
179234
+ ready: ready2
179235
+ };
179151
179236
  }
179152
179237
 
179153
179238
  // ../tool-server/src/utils/preview-window.ts
@@ -179470,6 +179555,7 @@ function start() {
179470
179555
  if (exitCode > finalExitCode) finalExitCode = exitCode;
179471
179556
  if (shuttingDown) return;
179472
179557
  shuttingDown = true;
179558
+ stopWatcher();
179473
179559
  eventLog?.info({
179474
179560
  type: "tool_server.stopping",
179475
179561
  msg: "Tool server is stopping.",
@@ -179484,7 +179570,6 @@ function start() {
179484
179570
  }
179485
179571
  previewWindow.dispose();
179486
179572
  updateChecker.dispose();
179487
- stopWatcher();
179488
179573
  httpHandle.dispose();
179489
179574
  try {
179490
179575
  await registry2.dispose();
@@ -179547,6 +179632,7 @@ function start() {
179547
179632
  }
179548
179633
  });
179549
179634
  Promise.all([watcherReady, identityWarm]).then(() => {
179635
+ if (shuttingDown) return;
179550
179636
  server = httpHandle.app.listen(PORT, HOST, () => {
179551
179637
  listening = true;
179552
179638
  const addr = server.address();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.31.2-next.4",
3
+ "version": "0.31.2-next.6",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",