@ada-mcp/mcp-server 0.1.17 → 0.1.19
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/README.md +10 -10
- package/dist/cli.cjs +291 -18
- package/package.json +1 -1
- package/scripts/preinstall-probes.mjs +10 -5
package/README.md
CHANGED
|
@@ -8,27 +8,27 @@ ADA MCP server package that supports:
|
|
|
8
8
|
|
|
9
9
|
## 标准安装(Cursor / MCP)
|
|
10
10
|
|
|
11
|
-
请使用 **`@ada-mcp/launcher@0.1.
|
|
11
|
+
请使用 **`@ada-mcp/launcher@0.1.19`** 拉起本包(见 [launcher README](../ada-mcp-launcher/README.md)):
|
|
12
12
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
15
15
|
"mcpServers": {
|
|
16
16
|
"ada-mcp": {
|
|
17
17
|
"command": "pnpm",
|
|
18
|
-
"args": ["dlx", "@ada-mcp/launcher@0.1.
|
|
18
|
+
"args": ["dlx", "@ada-mcp/launcher@0.1.19"]
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
本包版本:**`@ada-mcp/mcp-server@0.1.
|
|
24
|
+
本包版本:**`@ada-mcp/mcp-server@0.1.19`**(由 launcher 默认拉取;依赖锁定 `playwright@1.59.1`)。
|
|
25
25
|
|
|
26
26
|
直接调试本包(无 launcher 拉包前测速):
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
pnpm dlx @ada-mcp/mcp-server@0.1.
|
|
29
|
+
pnpm dlx @ada-mcp/mcp-server@0.1.19
|
|
30
30
|
# npx 等价:
|
|
31
|
-
npx -y @ada-mcp/mcp-server@0.1.
|
|
31
|
+
npx -y @ada-mcp/mcp-server@0.1.19
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## 启动时自动安装依赖(默认仅 Playwright)
|
|
@@ -83,27 +83,27 @@ npx -y @ada-mcp/mcp-server@0.1.17
|
|
|
83
83
|
在标准 `args` 后追加,例如安装全部依赖:
|
|
84
84
|
|
|
85
85
|
```json
|
|
86
|
-
"args": ["dlx", "@ada-mcp/launcher@0.1.
|
|
86
|
+
"args": ["dlx", "@ada-mcp/launcher@0.1.19", "--install-deps=all"]
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
## Cursor MCP 配置
|
|
90
90
|
|
|
91
|
-
**pnpm(推荐)**:`pnpm` + `dlx @ada-mcp/launcher@0.1.
|
|
91
|
+
**pnpm(推荐)**:`pnpm` + `dlx @ada-mcp/launcher@0.1.19`
|
|
92
92
|
|
|
93
|
-
**npx 等价**(`launcher@0.1.7+`):`npx` + `-y @ada-mcp/launcher@0.1.
|
|
93
|
+
**npx 等价**(`launcher@0.1.7+`):`npx` + `-y @ada-mcp/launcher@0.1.19`(内层同样 `npx -y` mcp-server,测速逻辑与 pnpm 一致)
|
|
94
94
|
|
|
95
95
|
```json
|
|
96
96
|
{
|
|
97
97
|
"mcpServers": {
|
|
98
98
|
"ada-mcp": {
|
|
99
99
|
"command": "npx",
|
|
100
|
-
"args": ["-y", "@ada-mcp/launcher@0.1.
|
|
100
|
+
"args": ["-y", "@ada-mcp/launcher@0.1.19"]
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
Windows 若找不到 `pnpm`,可将 `command` 改为 `pnpm.cmd` 绝对路径;无 pnpm 时只能直接 `npx -y @ada-mcp/mcp-server@0.1.
|
|
106
|
+
Windows 若找不到 `pnpm`,可将 `command` 改为 `pnpm.cmd` 绝对路径;无 pnpm 时只能直接 `npx -y @ada-mcp/mcp-server@0.1.19`(无 launcher 拉包测速)。
|
|
107
107
|
|
|
108
108
|
## Remote mode
|
|
109
109
|
|
package/dist/cli.cjs
CHANGED
|
@@ -3671,7 +3671,132 @@ function playwrightInstallPackageSpec() {
|
|
|
3671
3671
|
return `playwright@${fromEnv || PINNED_PLAYWRIGHT_VERSION}`;
|
|
3672
3672
|
}
|
|
3673
3673
|
function resolveInstallPackageSpecs(packages) {
|
|
3674
|
-
|
|
3674
|
+
const out = [];
|
|
3675
|
+
for (const pkg of packages) {
|
|
3676
|
+
if (pkg === "playwright") {
|
|
3677
|
+
out.push(playwrightInstallPackageSpec());
|
|
3678
|
+
continue;
|
|
3679
|
+
}
|
|
3680
|
+
if (pkg === "zod") {
|
|
3681
|
+
const fromEnv = process.env.ADA_ZOD_VERSION?.trim();
|
|
3682
|
+
out.push(`zod@${fromEnv || PINNED_ZOD_VERSION}`);
|
|
3683
|
+
continue;
|
|
3684
|
+
}
|
|
3685
|
+
out.push(pkg);
|
|
3686
|
+
}
|
|
3687
|
+
return out;
|
|
3688
|
+
}
|
|
3689
|
+
function skipConflictRemoval() {
|
|
3690
|
+
const v = process.env.ADA_DEPS_SKIP_CONFLICT_REMOVAL?.trim().toLowerCase();
|
|
3691
|
+
return v === "1" || v === "true" || v === "yes";
|
|
3692
|
+
}
|
|
3693
|
+
function readInstalledPackageVersion(packageName) {
|
|
3694
|
+
try {
|
|
3695
|
+
const pkgPath = require2.resolve(`${packageName}/package.json`);
|
|
3696
|
+
const raw = (0, import_node_fs.readFileSync)(pkgPath, "utf8");
|
|
3697
|
+
return String(JSON.parse(raw).version ?? "").trim() || void 0;
|
|
3698
|
+
} catch {
|
|
3699
|
+
return void 0;
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
function zodExportsV3Subpath(version2) {
|
|
3703
|
+
try {
|
|
3704
|
+
const pkgPath = require2.resolve("zod/package.json");
|
|
3705
|
+
const raw = (0, import_node_fs.readFileSync)(pkgPath, "utf8");
|
|
3706
|
+
const exportsField = JSON.parse(raw).exports;
|
|
3707
|
+
if (exportsField && "./v3" in exportsField) {
|
|
3708
|
+
return true;
|
|
3709
|
+
}
|
|
3710
|
+
} catch {
|
|
3711
|
+
}
|
|
3712
|
+
const major = Number(version2.split(".")[0]);
|
|
3713
|
+
const minor = Number(version2.split(".")[1]);
|
|
3714
|
+
if (major > 3) {
|
|
3715
|
+
return true;
|
|
3716
|
+
}
|
|
3717
|
+
return major === 3 && minor >= 25;
|
|
3718
|
+
}
|
|
3719
|
+
function detectWorkspacePackageConflicts(packages) {
|
|
3720
|
+
const conflicts = [];
|
|
3721
|
+
const expectedPlaywright = process.env.ADA_PLAYWRIGHT_VERSION?.trim() || PINNED_PLAYWRIGHT_VERSION;
|
|
3722
|
+
const expectedZod = process.env.ADA_ZOD_VERSION?.trim() || PINNED_ZOD_VERSION;
|
|
3723
|
+
if (packages.includes("playwright") && hasPackage("playwright")) {
|
|
3724
|
+
const installed = readInstalledPackageVersion("playwright");
|
|
3725
|
+
if (installed && installed !== expectedPlaywright) {
|
|
3726
|
+
conflicts.push({
|
|
3727
|
+
name: "playwright",
|
|
3728
|
+
installed,
|
|
3729
|
+
expected: expectedPlaywright,
|
|
3730
|
+
reason: "\u4E0E ADA \u9501\u5B9A\u7684 Playwright \u6D4F\u89C8\u5668\u5305\u7248\u672C\u4E0D\u4E00\u81F4"
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
if (hasPackage("@modelcontextprotocol/sdk") && hasPackage("zod")) {
|
|
3735
|
+
const zodVer = readInstalledPackageVersion("zod");
|
|
3736
|
+
if (zodVer && !zodExportsV3Subpath(zodVer)) {
|
|
3737
|
+
conflicts.push({
|
|
3738
|
+
name: "zod",
|
|
3739
|
+
installed: zodVer,
|
|
3740
|
+
expected: expectedZod,
|
|
3741
|
+
reason: "\u5F53\u524D zod \u4E0D\u652F\u6301 zod/v3\uFF0C\u4E0E @modelcontextprotocol/sdk \u51B2\u7A81"
|
|
3742
|
+
});
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
return conflicts;
|
|
3746
|
+
}
|
|
3747
|
+
function packagesToRemoveForConflicts(conflicts) {
|
|
3748
|
+
const names = /* @__PURE__ */ new Set();
|
|
3749
|
+
for (const c of conflicts) {
|
|
3750
|
+
names.add(c.name);
|
|
3751
|
+
if (c.name === "playwright") {
|
|
3752
|
+
names.add("playwright-core");
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
return Array.from(names);
|
|
3756
|
+
}
|
|
3757
|
+
async function removeWorkspacePackages(names, onLogLine) {
|
|
3758
|
+
const unique = Array.from(new Set(names)).filter(Boolean);
|
|
3759
|
+
if (unique.length === 0) {
|
|
3760
|
+
return true;
|
|
3761
|
+
}
|
|
3762
|
+
const timeoutMs = installStrategyTimeoutMs();
|
|
3763
|
+
const attempts = [
|
|
3764
|
+
{ tool: "pnpm", args: ["remove", ...unique] },
|
|
3765
|
+
{ tool: "npm", args: ["uninstall", ...unique] }
|
|
3766
|
+
];
|
|
3767
|
+
for (const { tool, args } of attempts) {
|
|
3768
|
+
try {
|
|
3769
|
+
await runCommand2(tool, args, { timeoutMs, onLogLine });
|
|
3770
|
+
return true;
|
|
3771
|
+
} catch {
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
return false;
|
|
3775
|
+
}
|
|
3776
|
+
async function reconcileWorkspacePackageConflicts(packages, onLogLine) {
|
|
3777
|
+
if (skipConflictRemoval()) {
|
|
3778
|
+
return [];
|
|
3779
|
+
}
|
|
3780
|
+
const conflicts = detectWorkspacePackageConflicts(packages);
|
|
3781
|
+
if (conflicts.length === 0) {
|
|
3782
|
+
return [];
|
|
3783
|
+
}
|
|
3784
|
+
for (const c of conflicts) {
|
|
3785
|
+
onLogLine?.(`[deps] \u68C0\u6D4B\u5230\u51B2\u7A81 ${c.name}@${c.installed}\uFF0C\u76EE\u6807 ${c.expected}\uFF08${c.reason}\uFF09`);
|
|
3786
|
+
}
|
|
3787
|
+
const toRemove = packagesToRemoveForConflicts(conflicts);
|
|
3788
|
+
onLogLine?.(`[deps] \u6B63\u5728\u5378\u8F7D: ${toRemove.join(", ")}`);
|
|
3789
|
+
const removed = await removeWorkspacePackages(toRemove, onLogLine);
|
|
3790
|
+
if (!removed) {
|
|
3791
|
+
onLogLine?.("[deps][warn] \u81EA\u52A8\u5378\u8F7D\u672A\u5B8C\u6210\uFF0C\u8BF7\u624B\u52A8\u6267\u884C: pnpm remove " + toRemove.join(" "));
|
|
3792
|
+
} else {
|
|
3793
|
+
onLogLine?.("[deps] \u51B2\u7A81\u5305\u5DF2\u5378\u8F7D\uFF0C\u5C06\u5B89\u88C5\u9501\u5B9A\u7248\u672C");
|
|
3794
|
+
}
|
|
3795
|
+
const extraInstall = [];
|
|
3796
|
+
if (conflicts.some((c) => c.name === "zod") && hasPackage("@modelcontextprotocol/sdk")) {
|
|
3797
|
+
extraInstall.push("zod");
|
|
3798
|
+
}
|
|
3799
|
+
return extraInstall;
|
|
3675
3800
|
}
|
|
3676
3801
|
function shouldUseShell(command) {
|
|
3677
3802
|
if (process.platform !== "win32") {
|
|
@@ -3693,7 +3818,14 @@ function briefErrorMessage(error2) {
|
|
|
3693
3818
|
}
|
|
3694
3819
|
return String(error2).split(/\r?\n/)[0]?.trim() || String(error2);
|
|
3695
3820
|
}
|
|
3821
|
+
function depsVerboseEnabled() {
|
|
3822
|
+
return isTruthyEnv("ADA_DEPS_VERBOSE");
|
|
3823
|
+
}
|
|
3696
3824
|
function shouldEmitPlaywrightCliLine(line) {
|
|
3825
|
+
if (depsVerboseEnabled()) {
|
|
3826
|
+
const t2 = line.trim();
|
|
3827
|
+
return t2.length > 0 && !/^\s*at\s/.test(t2) && !t2.includes("processTicksAndRejections");
|
|
3828
|
+
}
|
|
3697
3829
|
const t = line.trim();
|
|
3698
3830
|
if (!t) {
|
|
3699
3831
|
return false;
|
|
@@ -3723,7 +3855,8 @@ function summarizePlaywrightCliLine(line) {
|
|
|
3723
3855
|
return "[playwright][warn] \u5F53\u524D\u955C\u50CF\u672A\u5B89\u88C5\u6210\u529F";
|
|
3724
3856
|
}
|
|
3725
3857
|
if (/^Progress:/i.test(t)) {
|
|
3726
|
-
|
|
3858
|
+
const pct = t.match(/(\d{1,3})%/)?.[1];
|
|
3859
|
+
return pct ? `[playwright] \u4E0B\u8F7D\u8FDB\u5EA6 ${pct}%` : "[playwright] \u4E0B\u8F7D\u4E2D\u2026";
|
|
3727
3860
|
}
|
|
3728
3861
|
if (t.length > 200) {
|
|
3729
3862
|
return `[playwright] ${t.slice(0, 120)}\u2026`;
|
|
@@ -3735,15 +3868,27 @@ function createPlaywrightInstallLogSink(onLogLine) {
|
|
|
3735
3868
|
return void 0;
|
|
3736
3869
|
}
|
|
3737
3870
|
const seen = /* @__PURE__ */ new Set();
|
|
3871
|
+
let lastProgressEmitAt = 0;
|
|
3738
3872
|
return (line) => {
|
|
3739
3873
|
if (!shouldEmitPlaywrightCliLine(line)) {
|
|
3740
3874
|
return;
|
|
3741
3875
|
}
|
|
3876
|
+
if (depsVerboseEnabled()) {
|
|
3877
|
+
onLogLine(line.trimEnd());
|
|
3878
|
+
return;
|
|
3879
|
+
}
|
|
3742
3880
|
const summary = summarizePlaywrightCliLine(line);
|
|
3743
3881
|
if (!summary) {
|
|
3744
3882
|
return;
|
|
3745
3883
|
}
|
|
3746
|
-
|
|
3884
|
+
const isProgress = /^Progress:/i.test(line.trim());
|
|
3885
|
+
if (isProgress) {
|
|
3886
|
+
const now = Date.now();
|
|
3887
|
+
if (now - lastProgressEmitAt < 12e3) {
|
|
3888
|
+
return;
|
|
3889
|
+
}
|
|
3890
|
+
lastProgressEmitAt = now;
|
|
3891
|
+
} else if (seen.has(summary)) {
|
|
3747
3892
|
return;
|
|
3748
3893
|
}
|
|
3749
3894
|
seen.add(summary);
|
|
@@ -3920,7 +4065,13 @@ function installStrategyTimeoutMs() {
|
|
|
3920
4065
|
return parsePositiveMs(process.env.ADA_INSTALL_STRATEGY_TIMEOUT_MS, 12e4);
|
|
3921
4066
|
}
|
|
3922
4067
|
function playwrightInstallTimeoutMs() {
|
|
3923
|
-
return parsePositiveMs(process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS,
|
|
4068
|
+
return parsePositiveMs(process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS, 18e5);
|
|
4069
|
+
}
|
|
4070
|
+
function playwrightInstallAttemptTimeoutMs(attemptIndex, baseTimeoutMs) {
|
|
4071
|
+
if (attemptIndex <= 0) {
|
|
4072
|
+
return baseTimeoutMs;
|
|
4073
|
+
}
|
|
4074
|
+
return Math.min(baseTimeoutMs, 6e5);
|
|
3924
4075
|
}
|
|
3925
4076
|
function majorOf(versionLike) {
|
|
3926
4077
|
const text = versionLike.trim().replace(/^v/i, "");
|
|
@@ -4024,12 +4175,73 @@ function stepMeta(stage) {
|
|
|
4024
4175
|
stepTotal: PROGRESS_STEPS.length
|
|
4025
4176
|
};
|
|
4026
4177
|
}
|
|
4178
|
+
function formatProgressDetail(stage, details) {
|
|
4179
|
+
if (!details) {
|
|
4180
|
+
return null;
|
|
4181
|
+
}
|
|
4182
|
+
if (stage === "registry.probe.result") {
|
|
4183
|
+
const candidate = String(details.candidate ?? "");
|
|
4184
|
+
const latency = details.latencyMs;
|
|
4185
|
+
return `[deps] npm \u955C\u50CF ${candidate} -> ${latency === null || latency === void 0 ? "fail" : `${latency}ms`}`;
|
|
4186
|
+
}
|
|
4187
|
+
if (stage === "playwright.host.probe.result") {
|
|
4188
|
+
const candidate = String(details.candidate ?? "");
|
|
4189
|
+
const latency = details.latencyMs;
|
|
4190
|
+
const artifactOk = details.artifactOk === true;
|
|
4191
|
+
const tail = artifactOk ? "\uFF0C\u6D4F\u89C8\u5668\u5305\u53EF\u4E0B\u8F7D" : latency === null || latency === void 0 ? "" : "\uFF0C\u4EC5\u8FDE\u901A";
|
|
4192
|
+
return `[playwright] CDN ${candidate} -> ${latency === null || latency === void 0 ? "fail" : `${latency}ms`}${tail}`;
|
|
4193
|
+
}
|
|
4194
|
+
if (stage === "packages.install.done") {
|
|
4195
|
+
const strategy = String(details.strategy ?? "");
|
|
4196
|
+
return strategy ? `[deps] \u5305\u5B89\u88C5\u5B8C\u6210\uFF08${strategy}\uFF09` : null;
|
|
4197
|
+
}
|
|
4198
|
+
if (stage === "playwright.browser.install.done") {
|
|
4199
|
+
const host = String(details.selectedHost ?? "");
|
|
4200
|
+
const attempt = details.attempt;
|
|
4201
|
+
return host ? `[playwright] \u6D4F\u89C8\u5668\u5B89\u88C5\u5B8C\u6210\uFF08${host}${attempt ? `\uFF0C\u7B2C ${attempt} \u4E2A\u955C\u50CF` : ""}\uFF09` : null;
|
|
4202
|
+
}
|
|
4203
|
+
return null;
|
|
4204
|
+
}
|
|
4205
|
+
function structuredLogToHuman(level, payload) {
|
|
4206
|
+
const { event, details } = payload;
|
|
4207
|
+
const d = details && typeof details === "object" ? details : {};
|
|
4208
|
+
if (event === "deps.playwright.browser.install.host.fail") {
|
|
4209
|
+
return `[playwright][warn] \u955C\u50CF ${d.host} \u5931\u8D25 (${d.attempt}): ${d.message}`;
|
|
4210
|
+
}
|
|
4211
|
+
if (event === "deps.install.strategy.try") {
|
|
4212
|
+
return `[deps] \u5C1D\u8BD5\u5B89\u88C5\u7B56\u7565: ${d.strategy}`;
|
|
4213
|
+
}
|
|
4214
|
+
if (event === "deps.install.strategy.ok") {
|
|
4215
|
+
return `[deps] \u5305\u5B89\u88C5\u6210\u529F: ${d.strategy}`;
|
|
4216
|
+
}
|
|
4217
|
+
if (event === "deps.install.strategy.fail") {
|
|
4218
|
+
return `[deps][warn] \u5B89\u88C5\u7B56\u7565\u5931\u8D25 (${d.strategy}): ${d.message}`;
|
|
4219
|
+
}
|
|
4220
|
+
if (event === "deps.registry.auto-selected") {
|
|
4221
|
+
return `[deps] \u9009\u7528 npm \u955C\u50CF: ${d.selected}`;
|
|
4222
|
+
}
|
|
4223
|
+
if (event === "deps.playwright.host.auto-selected") {
|
|
4224
|
+
return `[playwright] CDN \u6D4B\u901F\u6392\u5E8F: ${Array.isArray(d.ranked) ? d.ranked.join(" -> ") : d.selected}`;
|
|
4225
|
+
}
|
|
4226
|
+
if (level === "warn" || level === "error") {
|
|
4227
|
+
const msg = d.message ?? d.detail;
|
|
4228
|
+
return `[deps][${level}] ${event}${msg ? `: ${msg}` : ""}`;
|
|
4229
|
+
}
|
|
4230
|
+
if (depsVerboseEnabled()) {
|
|
4231
|
+
return `[deps] ${event}${Object.keys(d).length > 0 ? ` ${JSON.stringify(d)}` : ""}`;
|
|
4232
|
+
}
|
|
4233
|
+
return null;
|
|
4234
|
+
}
|
|
4027
4235
|
function progress(stage, details) {
|
|
4028
4236
|
if (depsHumanLog) {
|
|
4029
4237
|
const label = PROGRESS_HUMAN_LABELS[stage];
|
|
4030
4238
|
if (label) {
|
|
4031
4239
|
depsHumanLog(label);
|
|
4032
4240
|
}
|
|
4241
|
+
const detail = formatProgressDetail(stage, details);
|
|
4242
|
+
if (detail) {
|
|
4243
|
+
depsHumanLog(detail);
|
|
4244
|
+
}
|
|
4033
4245
|
return;
|
|
4034
4246
|
}
|
|
4035
4247
|
const meta3 = stepMeta(stage);
|
|
@@ -4044,6 +4256,10 @@ function progress(stage, details) {
|
|
|
4044
4256
|
}
|
|
4045
4257
|
function depsStructuredLog(level, payload) {
|
|
4046
4258
|
if (depsHumanLog) {
|
|
4259
|
+
const human = structuredLogToHuman(level, payload);
|
|
4260
|
+
if (human) {
|
|
4261
|
+
depsHumanLog(human);
|
|
4262
|
+
}
|
|
4047
4263
|
return;
|
|
4048
4264
|
}
|
|
4049
4265
|
log(level, payload);
|
|
@@ -4142,12 +4358,42 @@ function playwrightProbeUrls(host) {
|
|
|
4142
4358
|
}
|
|
4143
4359
|
return [h];
|
|
4144
4360
|
}
|
|
4361
|
+
function isChinaFriendlyNpmRegistry(registry2) {
|
|
4362
|
+
const r = registry2.toLowerCase();
|
|
4363
|
+
return CHINA_NPM_REGISTRY_HINTS.some((hint) => r.includes(hint));
|
|
4364
|
+
}
|
|
4365
|
+
function isTruthyEnv(name) {
|
|
4366
|
+
const s = String(process.env[name] ?? "").trim().toLowerCase();
|
|
4367
|
+
return s === "1" || s === "true" || s === "yes" || s === "on";
|
|
4368
|
+
}
|
|
4369
|
+
function playwrightHostConfiguredByUser(config2) {
|
|
4370
|
+
if (process.env.ADA_PLAYWRIGHT_HOST_FROM_PREINSTALL === "1") {
|
|
4371
|
+
return "";
|
|
4372
|
+
}
|
|
4373
|
+
const raw = process.env.PLAYWRIGHT_DOWNLOAD_HOST?.trim() || playwrightDownloadHost(config2).trim();
|
|
4374
|
+
return raw ? normalizeHostUrl(raw) : "";
|
|
4375
|
+
}
|
|
4376
|
+
function preferPlaywrightHostsForNpmRegistry(ranked, npmRegistry) {
|
|
4377
|
+
if (!isTruthyEnv("ADA_PLAYWRIGHT_PREFER_CN_MIRROR") && !isChinaFriendlyNpmRegistry(npmRegistry)) {
|
|
4378
|
+
return ranked;
|
|
4379
|
+
}
|
|
4380
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4381
|
+
const out = [];
|
|
4382
|
+
for (const url2 of [...CHINA_PLAYWRIGHT_HOST_PRIORITY, ...ranked]) {
|
|
4383
|
+
const n = normalizeHostUrl(url2);
|
|
4384
|
+
if (!seen.has(n)) {
|
|
4385
|
+
seen.add(n);
|
|
4386
|
+
out.push(n);
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
return out;
|
|
4390
|
+
}
|
|
4145
4391
|
function playwrightHostCandidates(config2) {
|
|
4146
|
-
const configured =
|
|
4392
|
+
const configured = playwrightHostConfiguredByUser(config2);
|
|
4147
4393
|
const fromConfig = Array.isArray(config2.dependencies.playwrightHostCandidates) ? config2.dependencies.playwrightHostCandidates.map((x) => normalizeHostUrl(String(x).trim())).filter(Boolean) : [];
|
|
4148
4394
|
const configuredList = fromConfig.length > 0 ? fromConfig : [...DEFAULT_PLAYWRIGHT_HOST_CANDIDATES];
|
|
4149
4395
|
const extra = process.env.ADA_PLAYWRIGHT_HOST_CANDIDATES ? process.env.ADA_PLAYWRIGHT_HOST_CANDIDATES.split(",").map((x) => normalizeHostUrl(x.trim())).filter(Boolean) : [];
|
|
4150
|
-
const ordered = [configured, ...configuredList, ...extra];
|
|
4396
|
+
const ordered = configured ? [configured, ...configuredList, ...extra] : [...configuredList, ...extra];
|
|
4151
4397
|
const seen = /* @__PURE__ */ new Set();
|
|
4152
4398
|
const out = [];
|
|
4153
4399
|
for (const url2 of ordered) {
|
|
@@ -4236,7 +4482,9 @@ async function rankPlaywrightHosts(config2) {
|
|
|
4236
4482
|
return ranked.length > 0 ? ranked : [...candidates];
|
|
4237
4483
|
}
|
|
4238
4484
|
async function runInstallWithPriority(config2, packages, onLogLine) {
|
|
4239
|
-
const
|
|
4485
|
+
const extraFromReconcile = await reconcileWorkspacePackageConflicts(packages, onLogLine);
|
|
4486
|
+
const allPackages = Array.from(/* @__PURE__ */ new Set([...packages, ...extraFromReconcile]));
|
|
4487
|
+
const specs = resolveInstallPackageSpecs(allPackages);
|
|
4240
4488
|
const npmProxy = await detectBestRegistry(config2, npmProxyRegistry());
|
|
4241
4489
|
const pnpmProxy = await detectBestRegistry(config2, pnpmProxyRegistry());
|
|
4242
4490
|
progress("packages.install.start", { packages: specs, npmProxy, pnpmProxy });
|
|
@@ -4281,6 +4529,7 @@ async function runInstallWithPriority(config2, packages, onLogLine) {
|
|
|
4281
4529
|
let lastError = void 0;
|
|
4282
4530
|
for (const strategy of strategies) {
|
|
4283
4531
|
try {
|
|
4532
|
+
onLogLine?.(`[deps] \u5C1D\u8BD5 ${strategy.name} \u5B89\u88C5\u5305\u2026`);
|
|
4284
4533
|
depsStructuredLog("info", { event: "deps.install.strategy.try", details: { strategy: strategy.name, packages } });
|
|
4285
4534
|
await strategy.run();
|
|
4286
4535
|
depsStructuredLog("info", { event: "deps.install.strategy.ok", details: { strategy: strategy.name } });
|
|
@@ -4397,24 +4646,32 @@ async function installPlaywrightBrowser(config2, onLogLine, options) {
|
|
|
4397
4646
|
if (targets.length > 0) {
|
|
4398
4647
|
installArgs.push(...targets);
|
|
4399
4648
|
}
|
|
4400
|
-
const
|
|
4401
|
-
|
|
4402
|
-
|
|
4649
|
+
const npmRegistry = await detectBestRegistry(config2, npmProxyRegistry());
|
|
4650
|
+
let rankedHosts = await rankPlaywrightHosts(config2);
|
|
4651
|
+
rankedHosts = preferPlaywrightHostsForNpmRegistry(rankedHosts, npmRegistry);
|
|
4652
|
+
const baseTimeoutMs = playwrightInstallTimeoutMs();
|
|
4653
|
+
onLogLine?.(
|
|
4654
|
+
`[playwright] \u5B89\u88C5\u8D85\u65F6\uFF1A\u9996\u4E2A\u955C\u50CF ${Math.round(baseTimeoutMs / 1e3)}s\uFF0C\u540E\u7EED\u955C\u50CF\u81F3\u591A 600s\uFF08ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS \u53EF\u8C03\uFF09`
|
|
4655
|
+
);
|
|
4656
|
+
if (isChinaFriendlyNpmRegistry(npmRegistry) || isTruthyEnv("ADA_PLAYWRIGHT_PREFER_CN_MIRROR")) {
|
|
4657
|
+
onLogLine?.(`[playwright] \u56FD\u5185 npm \u6E90 ${npmRegistry}\uFF0C\u4F18\u5148 npmmirror Playwright CDN`);
|
|
4658
|
+
}
|
|
4403
4659
|
let lastHost = "";
|
|
4404
4660
|
for (let i = 0; i < rankedHosts.length; i++) {
|
|
4405
4661
|
const host = rankedHosts[i];
|
|
4662
|
+
const attemptTimeoutMs = playwrightInstallAttemptTimeoutMs(i, baseTimeoutMs);
|
|
4406
4663
|
lastHost = host;
|
|
4407
4664
|
if (i > 0) {
|
|
4408
|
-
onLogLine?.(`[playwright] \u6362\u955C\u50CF: ${host}`);
|
|
4665
|
+
onLogLine?.(`[playwright] \u6362\u955C\u50CF (${i + 1}/${rankedHosts.length}): ${host}`);
|
|
4409
4666
|
} else {
|
|
4410
4667
|
onLogLine?.(
|
|
4411
|
-
`[playwright] playwright@${version2}\uFF0CCDN ${host}\uFF0C\u76EE\u6807 ${targets.length ? targets.join(",") : "chromium"}`
|
|
4668
|
+
`[playwright] playwright@${version2}\uFF0CCDN ${host}\uFF08${i + 1}/${rankedHosts.length}\uFF09\uFF0C\u76EE\u6807 ${targets.length ? targets.join(",") : "chromium"}`
|
|
4412
4669
|
);
|
|
4413
4670
|
}
|
|
4414
4671
|
try {
|
|
4415
4672
|
await runCommand2(command, installArgs, {
|
|
4416
4673
|
env: { PLAYWRIGHT_DOWNLOAD_HOST: host },
|
|
4417
|
-
timeoutMs,
|
|
4674
|
+
timeoutMs: attemptTimeoutMs,
|
|
4418
4675
|
onLogLine: createPlaywrightInstallLogSink(onLogLine)
|
|
4419
4676
|
});
|
|
4420
4677
|
progress("playwright.browser.install.done", { selectedHost: host, attempt: i + 1 });
|
|
@@ -4433,7 +4690,7 @@ async function installPlaywrightBrowser(config2, onLogLine, options) {
|
|
|
4433
4690
|
}
|
|
4434
4691
|
}
|
|
4435
4692
|
onLogLine?.(
|
|
4436
|
-
`[playwright][warn] \u6D4F\u89C8\u5668\u672A\u5B89\u88C5\u5B8C\u6210\uFF08\u5DF2\u5C1D\u8BD5 ${rankedHosts.length} \u4E2A CDN\uFF09\u3002\
|
|
4693
|
+
`[playwright][warn] \u6D4F\u89C8\u5668\u672A\u5B89\u88C5\u5B8C\u6210\uFF08\u5DF2\u5C1D\u8BD5 ${rankedHosts.length} \u4E2A CDN\uFF09\u3002\u56FD\u5185\u5EFA\u8BAE: set PLAYWRIGHT_DOWNLOAD_HOST=https://cdn.npmmirror.com/binaries/playwright \u5E76\u589E\u5927 ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS=1800000\uFF1B\u6216\u624B\u52A8: npx playwright@${PINNED_PLAYWRIGHT_VERSION} install chromium`
|
|
4437
4694
|
);
|
|
4438
4695
|
if (lastHost) {
|
|
4439
4696
|
onLogLine?.(`[playwright][warn] \u6700\u540E\u5C1D\u8BD5: ${lastHost}`);
|
|
@@ -4925,7 +5182,7 @@ async function getDependencyHealth(config2) {
|
|
|
4925
5182
|
missingAppiumDrivers
|
|
4926
5183
|
};
|
|
4927
5184
|
}
|
|
4928
|
-
var import_node_module, import_node_fs, import_node_child_process2, import_promises5, import_node_path5, require2, PINNED_PLAYWRIGHT_VERSION, depsHumanLog, DEFAULT_NPM_REGISTRY_CANDIDATES, detectedBestRegistryByKey, PROGRESS_STEPS, PROGRESS_HUMAN_LABELS, DEFAULT_PLAYWRIGHT_HOST_CANDIDATES, PLAYWRIGHT_HOST_FALLBACK, PW_INSTALL_TARGETS;
|
|
5185
|
+
var import_node_module, import_node_fs, import_node_child_process2, import_promises5, import_node_path5, require2, PINNED_PLAYWRIGHT_VERSION, PINNED_ZOD_VERSION, depsHumanLog, DEFAULT_NPM_REGISTRY_CANDIDATES, detectedBestRegistryByKey, PROGRESS_STEPS, PROGRESS_HUMAN_LABELS, DEFAULT_PLAYWRIGHT_HOST_CANDIDATES, CHINA_NPM_REGISTRY_HINTS, CHINA_PLAYWRIGHT_HOST_PRIORITY, PLAYWRIGHT_HOST_FALLBACK, PW_INSTALL_TARGETS;
|
|
4929
5186
|
var init_dependency_installer = __esm({
|
|
4930
5187
|
"../ada-agent/src/dependency-installer.ts"() {
|
|
4931
5188
|
import_node_module = require("node:module");
|
|
@@ -4938,6 +5195,7 @@ var init_dependency_installer = __esm({
|
|
|
4938
5195
|
init_src2();
|
|
4939
5196
|
require2 = (0, import_node_module.createRequire)(import_node_path5.default.join(process.cwd(), "package.json"));
|
|
4940
5197
|
PINNED_PLAYWRIGHT_VERSION = "1.59.1";
|
|
5198
|
+
PINNED_ZOD_VERSION = "3.25.76";
|
|
4941
5199
|
DEFAULT_NPM_REGISTRY_CANDIDATES = [
|
|
4942
5200
|
"https://registry.npmmirror.com",
|
|
4943
5201
|
"https://mirrors.cloud.tencent.com/npm",
|
|
@@ -4958,9 +5216,16 @@ var init_dependency_installer = __esm({
|
|
|
4958
5216
|
"deps.ensure.start": "[deps] \u5F00\u59CB\u68C0\u6D4B\u4F9D\u8D56",
|
|
4959
5217
|
"registry.probe.start": "[deps] \u63A2\u6D4B npm \u955C\u50CF\u2026",
|
|
4960
5218
|
"packages.install.start": "[deps] \u5B89\u88C5 npm \u5305\u2026",
|
|
5219
|
+
"packages.install.done": "[deps] npm \u5305\u5B89\u88C5\u5B8C\u6210",
|
|
4961
5220
|
"playwright.host.probe.start": "[playwright] \u63A2\u6D4B\u6D4F\u89C8\u5668 CDN\u2026",
|
|
4962
5221
|
"playwright.browser.install.start": "[playwright] \u5B89\u88C5\u6D4F\u89C8\u5668\u2026",
|
|
5222
|
+
"playwright.browser.install.done": "[playwright] \u6D4F\u89C8\u5668\u5B89\u88C5\u5B8C\u6210",
|
|
5223
|
+
"playwright.selfcheck.start": "[playwright] \u81EA\u68C0\u2026",
|
|
5224
|
+
"playwright.selfcheck.done": "[playwright] \u81EA\u68C0\u5B8C\u6210",
|
|
4963
5225
|
"appium.driver.ensure.start": "[appium] \u5B89\u88C5\u9A71\u52A8\u2026",
|
|
5226
|
+
"appium.driver.ensure.done": "[appium] \u9A71\u52A8\u5B89\u88C5\u5B8C\u6210",
|
|
5227
|
+
"selenium.check.start": "[selenium] \u68C0\u6D4B\u539F\u751F\u9A71\u52A8\u2026",
|
|
5228
|
+
"selenium.check.done": "[selenium] \u68C0\u6D4B\u5B8C\u6210",
|
|
4964
5229
|
"deps.ensure.done": "[deps] \u4F9D\u8D56\u68C0\u6D4B\u5B8C\u6210"
|
|
4965
5230
|
};
|
|
4966
5231
|
DEFAULT_PLAYWRIGHT_HOST_CANDIDATES = [
|
|
@@ -4969,6 +5234,11 @@ var init_dependency_installer = __esm({
|
|
|
4969
5234
|
"https://npmmirror.com/mirrors/playwright",
|
|
4970
5235
|
"https://cdn.npmmirror.com/binaries/playwright"
|
|
4971
5236
|
];
|
|
5237
|
+
CHINA_NPM_REGISTRY_HINTS = ["npmmirror.com", "tencent", "huaweicloud", "huawei.com"];
|
|
5238
|
+
CHINA_PLAYWRIGHT_HOST_PRIORITY = [
|
|
5239
|
+
"https://cdn.npmmirror.com/binaries/playwright",
|
|
5240
|
+
"https://npmmirror.com/mirrors/playwright"
|
|
5241
|
+
];
|
|
4972
5242
|
PLAYWRIGHT_HOST_FALLBACK = DEFAULT_PLAYWRIGHT_HOST_CANDIDATES[0];
|
|
4973
5243
|
PW_INSTALL_TARGETS = /* @__PURE__ */ new Set([
|
|
4974
5244
|
"chromium",
|
|
@@ -32848,7 +33118,9 @@ function resolveBootstrapInstallDeps(argv2) {
|
|
|
32848
33118
|
}
|
|
32849
33119
|
var PREINSTALL_PLAYWRIGHT_HOST_ALLOW = /* @__PURE__ */ new Set([
|
|
32850
33120
|
"https://cdn.playwright.dev",
|
|
32851
|
-
"https://playwright.azureedge.net"
|
|
33121
|
+
"https://playwright.azureedge.net",
|
|
33122
|
+
"https://cdn.npmmirror.com/binaries/playwright",
|
|
33123
|
+
"https://npmmirror.com/mirrors/playwright"
|
|
32852
33124
|
]);
|
|
32853
33125
|
function normalizePlaywrightHost(url2) {
|
|
32854
33126
|
return url2.replace(/\/$/, "");
|
|
@@ -32866,7 +33138,8 @@ function applyPreinstallPlaywrightHostFile() {
|
|
|
32866
33138
|
const host = normalizePlaywrightHost(import_node_fs3.default.readFileSync(file2, "utf8").trim());
|
|
32867
33139
|
if (host.length > 0 && PREINSTALL_PLAYWRIGHT_HOST_ALLOW.has(host)) {
|
|
32868
33140
|
process.env.PLAYWRIGHT_DOWNLOAD_HOST = host;
|
|
32869
|
-
|
|
33141
|
+
process.env.ADA_PLAYWRIGHT_HOST_FROM_PREINSTALL = "1";
|
|
33142
|
+
console.error(`[ADA-MCP] using playwright CDN from ${file2}: ${host} (install-deps \u5C06\u91CD\u65B0\u6D4B\u901F\u6392\u5E8F)`);
|
|
32870
33143
|
return;
|
|
32871
33144
|
}
|
|
32872
33145
|
if (host.length > 0) {
|
|
@@ -32884,7 +33157,7 @@ function ensureDefaultInstallTimeouts() {
|
|
|
32884
33157
|
process.env.ADA_INSTALL_STRATEGY_TIMEOUT_MS = "120000";
|
|
32885
33158
|
}
|
|
32886
33159
|
if (!process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS?.trim()) {
|
|
32887
|
-
process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS = "
|
|
33160
|
+
process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS = "1800000";
|
|
32888
33161
|
}
|
|
32889
33162
|
}
|
|
32890
33163
|
async function runBootstrapInstallDeps(argv2) {
|
package/package.json
CHANGED
|
@@ -62,11 +62,16 @@ async function main() {
|
|
|
62
62
|
console.error(`[ada-mcp preinstall] registry ${candidate} -> ${latency === null ? "fail" : `${latency}ms`}`);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
const chinaRegistry = /npmmirror|tencent|huaweicloud|huawei\.com/i.test(reg.best);
|
|
66
|
+
/** preinstall 无 playwright 包时无法 HEAD 浏览器包;国内 registry 时优先写入 npmmirror CDN */
|
|
67
|
+
const pwCandidates = chinaRegistry
|
|
68
|
+
? [
|
|
69
|
+
"https://cdn.npmmirror.com/binaries/playwright",
|
|
70
|
+
"https://npmmirror.com/mirrors/playwright",
|
|
71
|
+
"https://cdn.playwright.dev",
|
|
72
|
+
"https://playwright.azureedge.net"
|
|
73
|
+
]
|
|
74
|
+
: ["https://cdn.playwright.dev", "https://playwright.azureedge.net"];
|
|
70
75
|
const pw = await detectBestPlaywrightHost(pwCandidates);
|
|
71
76
|
const hostFile = path.join(root, ".ada-mcp-playwright-host");
|
|
72
77
|
fs.writeFileSync(hostFile, `${pw.best}\n`, "utf8");
|