@ada-mcp/mcp-server 0.1.9 → 0.1.10

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 (2) hide show
  1. package/dist/cli.cjs +92 -36
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -3568,6 +3568,39 @@ function resolveBundledPlaywrightCli() {
3568
3568
  const version = String(JSON.parse(raw).version ?? "");
3569
3569
  return { command: "node", cliArgs: [import_node_path5.default.join(root, "cli.js")], version };
3570
3570
  }
3571
+ function resolveChromiumBrowserVersion() {
3572
+ try {
3573
+ const browsersPath = require2.resolve("playwright-core/browsers.json");
3574
+ const raw = (0, import_node_fs.readFileSync)(browsersPath, "utf8");
3575
+ const parsed = JSON.parse(raw);
3576
+ const chromium = parsed.browsers?.find((b) => b.name === "chromium");
3577
+ return String(chromium?.browserVersion ?? "").trim();
3578
+ } catch {
3579
+ return "";
3580
+ }
3581
+ }
3582
+ function playwrightChromiumZipUrl(host, browserVersion) {
3583
+ const h = normalizeHostUrl(host);
3584
+ const base = h.includes("cdn.npmmirror.com/binaries/playwright") || h.endsWith("/binaries/playwright") ? "https://cdn.npmmirror.com/binaries/playwright" : h.includes("npmmirror.com") && !h.includes("/mirrors/playwright") ? "https://npmmirror.com/mirrors/playwright" : h;
3585
+ return `${base}/builds/cft/${browserVersion}/win64/chrome-win64.zip`;
3586
+ }
3587
+ async function probePlaywrightBrowserArtifact(host, browserVersion) {
3588
+ const url = playwrightChromiumZipUrl(host, browserVersion);
3589
+ const started = Date.now();
3590
+ const controller = new AbortController();
3591
+ const timer = setTimeout(() => controller.abort(), 8e3);
3592
+ try {
3593
+ const response = await fetch(url, { method: "HEAD", redirect: "follow", signal: controller.signal });
3594
+ if (response.status === 200) {
3595
+ return Date.now() - started;
3596
+ }
3597
+ return null;
3598
+ } catch {
3599
+ return null;
3600
+ } finally {
3601
+ clearTimeout(timer);
3602
+ }
3603
+ }
3571
3604
  function requiredAppiumDrivers(config) {
3572
3605
  return Array.from(new Set(config.appium.requiredDrivers ?? []));
3573
3606
  }
@@ -3677,7 +3710,6 @@ async function resolveCompatibleDriverSpecs(driver) {
3677
3710
  return Array.from(new Set(specs));
3678
3711
  }
3679
3712
  var detectedBestRegistryByKey = /* @__PURE__ */ new Map();
3680
- var detectedBestPlaywrightHost = null;
3681
3713
  var PROGRESS_STEPS = [
3682
3714
  "deps.ensure.start",
3683
3715
  "registry.probe.start",
@@ -3859,40 +3891,43 @@ async function probePlaywrightHostLatency(host) {
3859
3891
  }
3860
3892
  return best;
3861
3893
  }
3862
- async function detectBestPlaywrightHost(config) {
3863
- if (detectedBestPlaywrightHost) {
3864
- return detectedBestPlaywrightHost;
3865
- }
3894
+ async function rankPlaywrightHosts(config) {
3866
3895
  const candidates = playwrightHostCandidates(config);
3867
- progress("playwright.host.probe.start", { candidates });
3896
+ const browserVersion = resolveChromiumBrowserVersion();
3897
+ progress("playwright.host.probe.start", { candidates, browserVersion: browserVersion || void 0 });
3868
3898
  const probeResults = await Promise.all(candidates.map(async (candidate) => {
3869
3899
  progress("playwright.host.probe.try", { candidate });
3870
- const latency = await probePlaywrightHostLatency(candidate);
3871
- progress("playwright.host.probe.result", { candidate, latencyMs: latency });
3872
- return { candidate, latency };
3900
+ const artifactLatency = browserVersion ? await probePlaywrightBrowserArtifact(candidate, browserVersion) : null;
3901
+ const rootLatency = await probePlaywrightHostLatency(candidate);
3902
+ const latency = artifactLatency ?? rootLatency;
3903
+ const artifactOk = artifactLatency !== null;
3904
+ progress("playwright.host.probe.result", {
3905
+ candidate,
3906
+ latencyMs: latency,
3907
+ artifactOk,
3908
+ browserVersion: browserVersion || void 0
3909
+ });
3910
+ return { candidate, latency, artifactOk, priority: playwrightHostPriorityIndex(candidates, candidate) };
3873
3911
  }));
3874
- let best = candidates[0] ?? PLAYWRIGHT_HOST_FALLBACK;
3875
- let bestLatency = Number.POSITIVE_INFINITY;
3876
- let bestPriority = Number.POSITIVE_INFINITY;
3877
- for (const { candidate, latency } of probeResults) {
3878
- if (latency === null)
3879
- continue;
3880
- const priority = playwrightHostPriorityIndex(candidates, candidate);
3881
- if (latency < bestLatency || latency === bestLatency && priority < bestPriority) {
3882
- best = candidate;
3883
- bestLatency = latency;
3884
- bestPriority = priority;
3912
+ const reachable = probeResults.filter((x) => x.latency !== null);
3913
+ const withArtifact = reachable.filter((x) => x.artifactOk);
3914
+ const pool = withArtifact.length > 0 ? withArtifact : reachable;
3915
+ pool.sort((a, b) => {
3916
+ if (a.artifactOk !== b.artifactOk) {
3917
+ return a.artifactOk ? -1 : 1;
3885
3918
  }
3886
- }
3887
- detectedBestPlaywrightHost = best;
3888
- log("info", {
3889
- event: "deps.playwright.host.auto-selected",
3890
- details: {
3891
- selected: best,
3892
- candidates
3919
+ if (a.latency !== b.latency) {
3920
+ return (a.latency ?? 0) - (b.latency ?? 0);
3893
3921
  }
3922
+ return a.priority - b.priority;
3894
3923
  });
3895
- return best;
3924
+ const ranked = pool.map((x) => x.candidate);
3925
+ for (const candidate of candidates) {
3926
+ if (!ranked.includes(candidate)) {
3927
+ ranked.push(candidate);
3928
+ }
3929
+ }
3930
+ return ranked.length > 0 ? ranked : [...candidates];
3896
3931
  }
3897
3932
  async function runInstallWithPriority(config, packages, onLogLine) {
3898
3933
  const npmProxy = await detectBestRegistry(config, npmProxyRegistry());
@@ -4035,16 +4070,37 @@ async function installPlaywrightBrowser(config, onLogLine, options) {
4035
4070
  if (targets.length > 0) {
4036
4071
  installArgs.push(...targets);
4037
4072
  }
4038
- const selectedHost = await detectBestPlaywrightHost(config);
4039
- onLogLine?.(`[playwright] \u4F7F\u7528\u5185\u7F6E playwright@${version} CLI\uFF0C\u955C\u50CF ${selectedHost}\uFF0C\u76EE\u6807: ${targets.length ? targets.join(",") : "all"}${options?.force ? " (--force)" : ""}`);
4073
+ const rankedHosts = await rankPlaywrightHosts(config);
4040
4074
  const timeoutMs = playwrightInstallTimeoutMs();
4041
4075
  onLogLine?.(`[playwright] \u5B89\u88C5\u8D85\u65F6\u4E0A\u9650 ${Math.round(timeoutMs / 1e3)}s\uFF08\u53EF\u7528 ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS \u8C03\u6574\uFF09`);
4042
- await runCommand2(command, installArgs, {
4043
- env: { PLAYWRIGHT_DOWNLOAD_HOST: selectedHost },
4044
- timeoutMs,
4045
- onLogLine
4046
- });
4047
- progress("playwright.browser.install.done", { selectedHost });
4076
+ let lastError;
4077
+ for (let i = 0; i < rankedHosts.length; i++) {
4078
+ const host = rankedHosts[i];
4079
+ if (i > 0) {
4080
+ onLogLine?.(`[playwright] \u4E0A\u4E00\u955C\u50CF\u5931\u8D25\uFF0C\u6539\u8BD5 ${host}`);
4081
+ }
4082
+ onLogLine?.(`[playwright] \u4F7F\u7528\u5185\u7F6E playwright@${version} CLI\uFF0C\u955C\u50CF ${host}\uFF0C\u76EE\u6807: ${targets.length ? targets.join(",") : "all"}${options?.force ? " (--force)" : ""}`);
4083
+ try {
4084
+ await runCommand2(command, installArgs, {
4085
+ env: { PLAYWRIGHT_DOWNLOAD_HOST: host },
4086
+ timeoutMs,
4087
+ onLogLine
4088
+ });
4089
+ progress("playwright.browser.install.done", { selectedHost: host, attempt: i + 1 });
4090
+ return;
4091
+ } catch (error) {
4092
+ lastError = error;
4093
+ log("warn", {
4094
+ event: "deps.playwright.browser.install.host.fail",
4095
+ details: {
4096
+ host,
4097
+ attempt: i + 1,
4098
+ message: error instanceof Error ? error.message : String(error)
4099
+ }
4100
+ });
4101
+ }
4102
+ }
4103
+ throw lastError instanceof Error ? lastError : new Error(String(lastError ?? "playwright browser install failed"));
4048
4104
  }
4049
4105
  async function checkPlaywrightLaunchable() {
4050
4106
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ada-mcp/mcp-server",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "ADA MCP server for web/mobile automation (stdio + remote HTTP)",
5
5
  "private": false,
6
6
  "type": "commonjs",