@ada-mcp/mcp-server 0.1.18 → 0.1.20
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 +347 -43
- package/package.json +1 -1
- package/plugins/driver-selenium.cjs +40 -0
- 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.18
|
|
|
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
|
@@ -3005,14 +3005,55 @@ async function resolveNativeDriversDir(workspaceRoot) {
|
|
|
3005
3005
|
}
|
|
3006
3006
|
return import_node_path4.default.join(root, DEFAULT_NATIVE_DRIVERS_DIR);
|
|
3007
3007
|
}
|
|
3008
|
-
function
|
|
3008
|
+
function geckodriverMirrorBase() {
|
|
3009
|
+
const fromEnv = process.env.ADA_GECKODRIVER_MIRROR?.trim();
|
|
3010
|
+
return (fromEnv || DEFAULT_GECKODRIVER_MIRROR).replace(/\/$/, "");
|
|
3011
|
+
}
|
|
3012
|
+
function geckodriverPlatformAsset(tag) {
|
|
3013
|
+
const t = tag.startsWith("v") ? tag : `v${tag}`;
|
|
3009
3014
|
if (process.platform === "win32") {
|
|
3010
|
-
|
|
3015
|
+
const winSuffix = process.arch === "arm64" ? "win-aarch64" : process.arch === "ia32" ? "win32" : "win64";
|
|
3016
|
+
return { fileName: `geckodriver-${t}-${winSuffix}.zip`, archiveKind: "zip" };
|
|
3011
3017
|
}
|
|
3012
3018
|
if (process.platform === "darwin") {
|
|
3013
|
-
|
|
3019
|
+
const macSuffix = process.arch === "arm64" ? "macos-aarch64" : "macos";
|
|
3020
|
+
return { fileName: `geckodriver-${t}-${macSuffix}.tar.gz`, archiveKind: "tar.gz" };
|
|
3021
|
+
}
|
|
3022
|
+
const linuxSuffix = process.arch === "arm64" ? "linux-aarch64" : process.arch === "ia32" ? "linux32" : "linux64";
|
|
3023
|
+
return { fileName: `geckodriver-${t}-${linuxSuffix}.tar.gz`, archiveKind: "tar.gz" };
|
|
3024
|
+
}
|
|
3025
|
+
function parseSemverTuple(version2) {
|
|
3026
|
+
const m = version2.replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
3027
|
+
if (!m) {
|
|
3028
|
+
return null;
|
|
3029
|
+
}
|
|
3030
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
3031
|
+
}
|
|
3032
|
+
function compareSemverDesc(a, b) {
|
|
3033
|
+
const pa = parseSemverTuple(a);
|
|
3034
|
+
const pb = parseSemverTuple(b);
|
|
3035
|
+
if (!pa || !pb) {
|
|
3036
|
+
return 0;
|
|
3037
|
+
}
|
|
3038
|
+
for (let i = 0; i < 3; i += 1) {
|
|
3039
|
+
if (pa[i] !== pb[i]) {
|
|
3040
|
+
return pb[i] - pa[i];
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
return 0;
|
|
3044
|
+
}
|
|
3045
|
+
async function fetchGeckodriverLatestFromMirror(mirrorBase) {
|
|
3046
|
+
const res = await fetch(`${mirrorBase}/`);
|
|
3047
|
+
if (!res.ok) {
|
|
3048
|
+
return null;
|
|
3049
|
+
}
|
|
3050
|
+
const html = await res.text();
|
|
3051
|
+
const tags = /* @__PURE__ */ new Set();
|
|
3052
|
+
for (const m of html.matchAll(/href="v(\d+\.\d+\.\d+)\//gi)) {
|
|
3053
|
+
tags.add(`v${m[1]}`);
|
|
3014
3054
|
}
|
|
3015
|
-
|
|
3055
|
+
const sorted = Array.from(tags).sort(compareSemverDesc);
|
|
3056
|
+
return sorted[0] ?? null;
|
|
3016
3057
|
}
|
|
3017
3058
|
function platformChromeLabel() {
|
|
3018
3059
|
if (process.platform === "win32") {
|
|
@@ -3197,6 +3238,21 @@ async function extractZip(zipPath, destDir) {
|
|
|
3197
3238
|
}
|
|
3198
3239
|
await runCommand("unzip", ["-o", zipPath, "-d", destDir]);
|
|
3199
3240
|
}
|
|
3241
|
+
async function extractTarGz(archivePath, destDir) {
|
|
3242
|
+
await import_promises4.default.mkdir(destDir, { recursive: true });
|
|
3243
|
+
if (process.platform === "win32") {
|
|
3244
|
+
await runCommand("tar", ["-xzf", archivePath, "-C", destDir]);
|
|
3245
|
+
return;
|
|
3246
|
+
}
|
|
3247
|
+
await runCommand("tar", ["-xzf", archivePath, "-C", destDir]);
|
|
3248
|
+
}
|
|
3249
|
+
async function extractDriverArchive(archivePath, destDir, kind) {
|
|
3250
|
+
if (kind === "zip") {
|
|
3251
|
+
await extractZip(archivePath, destDir);
|
|
3252
|
+
return;
|
|
3253
|
+
}
|
|
3254
|
+
await extractTarGz(archivePath, destDir);
|
|
3255
|
+
}
|
|
3200
3256
|
async function findFileRecursive(dir, fileName) {
|
|
3201
3257
|
const entries = await import_promises4.default.readdir(dir, { withFileTypes: true });
|
|
3202
3258
|
for (const ent of entries) {
|
|
@@ -3224,13 +3280,26 @@ async function fetchGeckodriverReleaseVersion(requested) {
|
|
|
3224
3280
|
if (requested && requested !== "latest") {
|
|
3225
3281
|
return requested.startsWith("v") ? requested : `v${requested}`;
|
|
3226
3282
|
}
|
|
3227
|
-
const
|
|
3228
|
-
if (
|
|
3229
|
-
|
|
3283
|
+
const mirrorLatest = await fetchGeckodriverLatestFromMirror(geckodriverMirrorBase());
|
|
3284
|
+
if (mirrorLatest) {
|
|
3285
|
+
return mirrorLatest;
|
|
3230
3286
|
}
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3287
|
+
try {
|
|
3288
|
+
const res = await fetch("https://api.github.com/repos/mozilla/geckodriver/releases/latest");
|
|
3289
|
+
if (res.ok) {
|
|
3290
|
+
const json3 = await res.json();
|
|
3291
|
+
const tag = json3.tag_name ?? "v0.36.0";
|
|
3292
|
+
return tag.startsWith("v") ? tag : `v${tag}`;
|
|
3293
|
+
}
|
|
3294
|
+
} catch {
|
|
3295
|
+
}
|
|
3296
|
+
return "v0.36.0";
|
|
3297
|
+
}
|
|
3298
|
+
function buildGeckodriverDownloadUrls(tag) {
|
|
3299
|
+
const { fileName, archiveKind } = geckodriverPlatformAsset(tag);
|
|
3300
|
+
const mirror = `${geckodriverMirrorBase()}/${tag}/${fileName}`;
|
|
3301
|
+
const github = `${GITHUB_GECKODRIVER_RELEASES}/download/${tag}/${fileName}`;
|
|
3302
|
+
return { mirror, github, fileName, archiveKind };
|
|
3234
3303
|
}
|
|
3235
3304
|
async function listChromedriverCfTVersions() {
|
|
3236
3305
|
const res = await fetch(CHROME_FOR_TESTING_JSON);
|
|
@@ -3474,26 +3543,39 @@ async function downloadToFile(url2, destPath) {
|
|
|
3474
3543
|
async function downloadGeckodriver(driversDir, versionInput, onLogLine) {
|
|
3475
3544
|
const tag = await fetchGeckodriverReleaseVersion(versionInput);
|
|
3476
3545
|
const version2 = tag.replace(/^v/, "");
|
|
3477
|
-
const
|
|
3478
|
-
const assetName = `geckodriver-${tag}-${suffix}`.replace("vv", "v");
|
|
3479
|
-
const url2 = `https://github.com/mozilla/geckodriver/releases/download/${tag}/geckodriver-${tag}-${suffix}`;
|
|
3546
|
+
const { mirror, github, fileName, archiveKind } = buildGeckodriverDownloadUrls(tag);
|
|
3480
3547
|
await import_promises4.default.mkdir(driversDir, { recursive: true });
|
|
3481
|
-
const
|
|
3548
|
+
const archiveExt = archiveKind === "zip" ? "zip" : "tar.gz";
|
|
3549
|
+
const archivePath = import_node_path4.default.join(driversDir, `_download_geckodriver_${version2}.${archiveExt}`);
|
|
3482
3550
|
const extractDir = import_node_path4.default.join(driversDir, `_extract_geckodriver_${version2}`);
|
|
3483
|
-
onLogLine?.(`[selenium]
|
|
3484
|
-
onLogLine?.(`[selenium]
|
|
3485
|
-
|
|
3551
|
+
onLogLine?.(`[selenium] ?? geckodriver ${tag}?${fileName}?? ${driversDir}`);
|
|
3552
|
+
onLogLine?.(`[selenium] ??: ${mirror}`);
|
|
3553
|
+
let downloaded = false;
|
|
3554
|
+
try {
|
|
3555
|
+
await downloadToFile(mirror, archivePath);
|
|
3556
|
+
downloaded = true;
|
|
3557
|
+
} catch (mirrorError) {
|
|
3558
|
+
onLogLine?.(
|
|
3559
|
+
`[selenium][warn] ?????????: ${mirrorError instanceof Error ? mirrorError.message : String(mirrorError)}`
|
|
3560
|
+
);
|
|
3561
|
+
onLogLine?.(`[selenium] ?? GitHub: ${github}`);
|
|
3562
|
+
await downloadToFile(github, archivePath);
|
|
3563
|
+
downloaded = true;
|
|
3564
|
+
}
|
|
3565
|
+
if (!downloaded) {
|
|
3566
|
+
throw new Error(`geckodriver download failed for ${tag}`);
|
|
3567
|
+
}
|
|
3486
3568
|
await import_promises4.default.rm(extractDir, { recursive: true, force: true });
|
|
3487
|
-
await
|
|
3569
|
+
await extractDriverArchive(archivePath, extractDir, archiveKind);
|
|
3488
3570
|
const found = await findFileRecursive(extractDir, geckodriverExeName());
|
|
3489
3571
|
if (!found) {
|
|
3490
|
-
throw new Error(`geckodriver binary not found after extracting ${
|
|
3572
|
+
throw new Error(`geckodriver binary not found after extracting ${fileName}`);
|
|
3491
3573
|
}
|
|
3492
3574
|
const dest = import_node_path4.default.join(driversDir, geckodriverExeName());
|
|
3493
3575
|
await copyExecutable(found, dest);
|
|
3494
|
-
await import_promises4.default.rm(
|
|
3576
|
+
await import_promises4.default.rm(archivePath, { force: true });
|
|
3495
3577
|
await import_promises4.default.rm(extractDir, { recursive: true, force: true });
|
|
3496
|
-
onLogLine?.(`[selenium] geckodriver
|
|
3578
|
+
onLogLine?.(`[selenium] geckodriver ???: ${dest}`);
|
|
3497
3579
|
return { path: dest, version: tag };
|
|
3498
3580
|
}
|
|
3499
3581
|
async function downloadChromedriver(driversDir, versionInput, onLogLine) {
|
|
@@ -3653,7 +3735,7 @@ async function ensureNativeWebDrivers(options = {}) {
|
|
|
3653
3735
|
}
|
|
3654
3736
|
return resolved;
|
|
3655
3737
|
}
|
|
3656
|
-
var import_node_child_process, import_promises4, import_node_path4, DEFAULT_NATIVE_DRIVERS_DIR, CHROME_FOR_TESTING_JSON;
|
|
3738
|
+
var import_node_child_process, import_promises4, import_node_path4, DEFAULT_NATIVE_DRIVERS_DIR, CHROME_FOR_TESTING_JSON, DEFAULT_GECKODRIVER_MIRROR, GITHUB_GECKODRIVER_RELEASES, SELENIUM_DRIVER_MANUAL_DOWNLOAD_REFERENCES;
|
|
3657
3739
|
var init_src2 = __esm({
|
|
3658
3740
|
"../../packages/native-drivers/src/index.ts"() {
|
|
3659
3741
|
"use strict";
|
|
@@ -3662,6 +3744,46 @@ var init_src2 = __esm({
|
|
|
3662
3744
|
import_node_path4 = __toESM(require("node:path"), 1);
|
|
3663
3745
|
DEFAULT_NATIVE_DRIVERS_DIR = "dirver";
|
|
3664
3746
|
CHROME_FOR_TESTING_JSON = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json";
|
|
3747
|
+
DEFAULT_GECKODRIVER_MIRROR = "https://mirrors.huaweicloud.com/geckodriver";
|
|
3748
|
+
GITHUB_GECKODRIVER_RELEASES = "https://github.com/mozilla/geckodriver/releases";
|
|
3749
|
+
SELENIUM_DRIVER_MANUAL_DOWNLOAD_REFERENCES = [
|
|
3750
|
+
{
|
|
3751
|
+
browser: "Chrome/Chromium",
|
|
3752
|
+
platforms: "Windows/Linux/macOS",
|
|
3753
|
+
vendor: "\u8C37\u6B4C",
|
|
3754
|
+
url: "https://chromedriver.storage.googleapis.com/index.html"
|
|
3755
|
+
},
|
|
3756
|
+
{
|
|
3757
|
+
browser: "Firefox",
|
|
3758
|
+
platforms: "Windows/Linux/macOS",
|
|
3759
|
+
vendor: "Mozilla / ?????",
|
|
3760
|
+
url: `${DEFAULT_GECKODRIVER_MIRROR}/v0.36.0/?????????????? ${GITHUB_GECKODRIVER_RELEASES}?`
|
|
3761
|
+
},
|
|
3762
|
+
{
|
|
3763
|
+
browser: "Edge",
|
|
3764
|
+
platforms: "win10",
|
|
3765
|
+
vendor: "\u5FAE\u8F6F",
|
|
3766
|
+
url: "https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/"
|
|
3767
|
+
},
|
|
3768
|
+
{
|
|
3769
|
+
browser: "Internet Explorer",
|
|
3770
|
+
platforms: "Windows",
|
|
3771
|
+
vendor: "Selenium \u9879\u76EE\u7EC4",
|
|
3772
|
+
url: "https://selenium-release.storage.googleapis.com/index.html"
|
|
3773
|
+
},
|
|
3774
|
+
{
|
|
3775
|
+
browser: "Safari",
|
|
3776
|
+
platforms: "macOS El Capitan \u53CA\u66F4\u9AD8\u7248\u672C",
|
|
3777
|
+
vendor: "\u82F9\u679C",
|
|
3778
|
+
url: "\uFF08\u7CFB\u7EDF\u5185\u7F6E\uFF0C\u65E0\u9700\u5355\u72EC\u4E0B\u8F7D\uFF09"
|
|
3779
|
+
},
|
|
3780
|
+
{
|
|
3781
|
+
browser: "Opera",
|
|
3782
|
+
platforms: "Windows/macOS/Linux",
|
|
3783
|
+
vendor: "Opera",
|
|
3784
|
+
url: "https://github.com/operasoftware/operachromiumdriver/releases"
|
|
3785
|
+
}
|
|
3786
|
+
];
|
|
3665
3787
|
}
|
|
3666
3788
|
});
|
|
3667
3789
|
|
|
@@ -3818,7 +3940,14 @@ function briefErrorMessage(error2) {
|
|
|
3818
3940
|
}
|
|
3819
3941
|
return String(error2).split(/\r?\n/)[0]?.trim() || String(error2);
|
|
3820
3942
|
}
|
|
3943
|
+
function depsVerboseEnabled() {
|
|
3944
|
+
return isTruthyEnv("ADA_DEPS_VERBOSE");
|
|
3945
|
+
}
|
|
3821
3946
|
function shouldEmitPlaywrightCliLine(line) {
|
|
3947
|
+
if (depsVerboseEnabled()) {
|
|
3948
|
+
const t2 = line.trim();
|
|
3949
|
+
return t2.length > 0 && !/^\s*at\s/.test(t2) && !t2.includes("processTicksAndRejections");
|
|
3950
|
+
}
|
|
3822
3951
|
const t = line.trim();
|
|
3823
3952
|
if (!t) {
|
|
3824
3953
|
return false;
|
|
@@ -3848,7 +3977,8 @@ function summarizePlaywrightCliLine(line) {
|
|
|
3848
3977
|
return "[playwright][warn] \u5F53\u524D\u955C\u50CF\u672A\u5B89\u88C5\u6210\u529F";
|
|
3849
3978
|
}
|
|
3850
3979
|
if (/^Progress:/i.test(t)) {
|
|
3851
|
-
|
|
3980
|
+
const pct = t.match(/(\d{1,3})%/)?.[1];
|
|
3981
|
+
return pct ? `[playwright] \u4E0B\u8F7D\u8FDB\u5EA6 ${pct}%` : "[playwright] \u4E0B\u8F7D\u4E2D\u2026";
|
|
3852
3982
|
}
|
|
3853
3983
|
if (t.length > 200) {
|
|
3854
3984
|
return `[playwright] ${t.slice(0, 120)}\u2026`;
|
|
@@ -3860,15 +3990,27 @@ function createPlaywrightInstallLogSink(onLogLine) {
|
|
|
3860
3990
|
return void 0;
|
|
3861
3991
|
}
|
|
3862
3992
|
const seen = /* @__PURE__ */ new Set();
|
|
3993
|
+
let lastProgressEmitAt = 0;
|
|
3863
3994
|
return (line) => {
|
|
3864
3995
|
if (!shouldEmitPlaywrightCliLine(line)) {
|
|
3865
3996
|
return;
|
|
3866
3997
|
}
|
|
3998
|
+
if (depsVerboseEnabled()) {
|
|
3999
|
+
onLogLine(line.trimEnd());
|
|
4000
|
+
return;
|
|
4001
|
+
}
|
|
3867
4002
|
const summary = summarizePlaywrightCliLine(line);
|
|
3868
4003
|
if (!summary) {
|
|
3869
4004
|
return;
|
|
3870
4005
|
}
|
|
3871
|
-
|
|
4006
|
+
const isProgress = /^Progress:/i.test(line.trim());
|
|
4007
|
+
if (isProgress) {
|
|
4008
|
+
const now = Date.now();
|
|
4009
|
+
if (now - lastProgressEmitAt < 12e3) {
|
|
4010
|
+
return;
|
|
4011
|
+
}
|
|
4012
|
+
lastProgressEmitAt = now;
|
|
4013
|
+
} else if (seen.has(summary)) {
|
|
3872
4014
|
return;
|
|
3873
4015
|
}
|
|
3874
4016
|
seen.add(summary);
|
|
@@ -4045,7 +4187,13 @@ function installStrategyTimeoutMs() {
|
|
|
4045
4187
|
return parsePositiveMs(process.env.ADA_INSTALL_STRATEGY_TIMEOUT_MS, 12e4);
|
|
4046
4188
|
}
|
|
4047
4189
|
function playwrightInstallTimeoutMs() {
|
|
4048
|
-
return parsePositiveMs(process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS,
|
|
4190
|
+
return parsePositiveMs(process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS, 18e5);
|
|
4191
|
+
}
|
|
4192
|
+
function playwrightInstallAttemptTimeoutMs(attemptIndex, baseTimeoutMs) {
|
|
4193
|
+
if (attemptIndex <= 0) {
|
|
4194
|
+
return baseTimeoutMs;
|
|
4195
|
+
}
|
|
4196
|
+
return Math.min(baseTimeoutMs, 6e5);
|
|
4049
4197
|
}
|
|
4050
4198
|
function majorOf(versionLike) {
|
|
4051
4199
|
const text = versionLike.trim().replace(/^v/i, "");
|
|
@@ -4102,6 +4250,32 @@ function appiumDriverPackageName(driver) {
|
|
|
4102
4250
|
}
|
|
4103
4251
|
return null;
|
|
4104
4252
|
}
|
|
4253
|
+
function resolveAppiumDriverInstallTargets(driver, appiumMajor, compatibleSpecs) {
|
|
4254
|
+
const pkg = appiumDriverPackageName(driver);
|
|
4255
|
+
if (appiumMajor !== null && appiumMajor >= 3) {
|
|
4256
|
+
if (!APPIUM3_BUILTIN_DRIVER_NAMES.has(driver)) {
|
|
4257
|
+
const envHarmony = process.env.ADA_APPIUM_DRIVER_SPEC_HARMONYOS?.trim();
|
|
4258
|
+
if (driver === "harmonyos" && (envHarmony || pkg)) {
|
|
4259
|
+
return [envHarmony || pkg];
|
|
4260
|
+
}
|
|
4261
|
+
return pkg ? [pkg] : [driver];
|
|
4262
|
+
}
|
|
4263
|
+
const envOverride = driver === "uiautomator2" ? process.env.ADA_APPIUM_DRIVER_SPEC_UIAUTOMATOR2?.trim() : driver === "xcuitest" ? process.env.ADA_APPIUM_DRIVER_SPEC_XCUITEST?.trim() : "";
|
|
4264
|
+
if (envOverride) {
|
|
4265
|
+
return [envOverride, driver];
|
|
4266
|
+
}
|
|
4267
|
+
return [driver];
|
|
4268
|
+
}
|
|
4269
|
+
const baseTarget = pkg ?? driver;
|
|
4270
|
+
return compatibleSpecs.length > 0 ? compatibleSpecs : [baseTarget];
|
|
4271
|
+
}
|
|
4272
|
+
function buildAppiumDriverInstallArgs(target, appiumMajor) {
|
|
4273
|
+
const useNpmPackageSpec = appiumMajor === null || appiumMajor < 3 || target.includes("@") || target.startsWith("appium-") || target.includes("/");
|
|
4274
|
+
if (useNpmPackageSpec) {
|
|
4275
|
+
return ["exec", "appium", "driver", "install", "--source=npm", target];
|
|
4276
|
+
}
|
|
4277
|
+
return ["exec", "appium", "driver", "install", target];
|
|
4278
|
+
}
|
|
4105
4279
|
async function getAppiumMajorVersion() {
|
|
4106
4280
|
let version2 = "";
|
|
4107
4281
|
try {
|
|
@@ -4149,12 +4323,73 @@ function stepMeta(stage) {
|
|
|
4149
4323
|
stepTotal: PROGRESS_STEPS.length
|
|
4150
4324
|
};
|
|
4151
4325
|
}
|
|
4326
|
+
function formatProgressDetail(stage, details) {
|
|
4327
|
+
if (!details) {
|
|
4328
|
+
return null;
|
|
4329
|
+
}
|
|
4330
|
+
if (stage === "registry.probe.result") {
|
|
4331
|
+
const candidate = String(details.candidate ?? "");
|
|
4332
|
+
const latency = details.latencyMs;
|
|
4333
|
+
return `[deps] npm \u955C\u50CF ${candidate} -> ${latency === null || latency === void 0 ? "fail" : `${latency}ms`}`;
|
|
4334
|
+
}
|
|
4335
|
+
if (stage === "playwright.host.probe.result") {
|
|
4336
|
+
const candidate = String(details.candidate ?? "");
|
|
4337
|
+
const latency = details.latencyMs;
|
|
4338
|
+
const artifactOk = details.artifactOk === true;
|
|
4339
|
+
const tail = artifactOk ? "\uFF0C\u6D4F\u89C8\u5668\u5305\u53EF\u4E0B\u8F7D" : latency === null || latency === void 0 ? "" : "\uFF0C\u4EC5\u8FDE\u901A";
|
|
4340
|
+
return `[playwright] CDN ${candidate} -> ${latency === null || latency === void 0 ? "fail" : `${latency}ms`}${tail}`;
|
|
4341
|
+
}
|
|
4342
|
+
if (stage === "packages.install.done") {
|
|
4343
|
+
const strategy = String(details.strategy ?? "");
|
|
4344
|
+
return strategy ? `[deps] \u5305\u5B89\u88C5\u5B8C\u6210\uFF08${strategy}\uFF09` : null;
|
|
4345
|
+
}
|
|
4346
|
+
if (stage === "playwright.browser.install.done") {
|
|
4347
|
+
const host = String(details.selectedHost ?? "");
|
|
4348
|
+
const attempt = details.attempt;
|
|
4349
|
+
return host ? `[playwright] \u6D4F\u89C8\u5668\u5B89\u88C5\u5B8C\u6210\uFF08${host}${attempt ? `\uFF0C\u7B2C ${attempt} \u4E2A\u955C\u50CF` : ""}\uFF09` : null;
|
|
4350
|
+
}
|
|
4351
|
+
return null;
|
|
4352
|
+
}
|
|
4353
|
+
function structuredLogToHuman(level, payload) {
|
|
4354
|
+
const { event, details } = payload;
|
|
4355
|
+
const d = details && typeof details === "object" ? details : {};
|
|
4356
|
+
if (event === "deps.playwright.browser.install.host.fail") {
|
|
4357
|
+
return `[playwright][warn] \u955C\u50CF ${d.host} \u5931\u8D25 (${d.attempt}): ${d.message}`;
|
|
4358
|
+
}
|
|
4359
|
+
if (event === "deps.install.strategy.try") {
|
|
4360
|
+
return `[deps] \u5C1D\u8BD5\u5B89\u88C5\u7B56\u7565: ${d.strategy}`;
|
|
4361
|
+
}
|
|
4362
|
+
if (event === "deps.install.strategy.ok") {
|
|
4363
|
+
return `[deps] \u5305\u5B89\u88C5\u6210\u529F: ${d.strategy}`;
|
|
4364
|
+
}
|
|
4365
|
+
if (event === "deps.install.strategy.fail") {
|
|
4366
|
+
return `[deps][warn] \u5B89\u88C5\u7B56\u7565\u5931\u8D25 (${d.strategy}): ${d.message}`;
|
|
4367
|
+
}
|
|
4368
|
+
if (event === "deps.registry.auto-selected") {
|
|
4369
|
+
return `[deps] \u9009\u7528 npm \u955C\u50CF: ${d.selected}`;
|
|
4370
|
+
}
|
|
4371
|
+
if (event === "deps.playwright.host.auto-selected") {
|
|
4372
|
+
return `[playwright] CDN \u6D4B\u901F\u6392\u5E8F: ${Array.isArray(d.ranked) ? d.ranked.join(" -> ") : d.selected}`;
|
|
4373
|
+
}
|
|
4374
|
+
if (level === "warn" || level === "error") {
|
|
4375
|
+
const msg = d.message ?? d.detail;
|
|
4376
|
+
return `[deps][${level}] ${event}${msg ? `: ${msg}` : ""}`;
|
|
4377
|
+
}
|
|
4378
|
+
if (depsVerboseEnabled()) {
|
|
4379
|
+
return `[deps] ${event}${Object.keys(d).length > 0 ? ` ${JSON.stringify(d)}` : ""}`;
|
|
4380
|
+
}
|
|
4381
|
+
return null;
|
|
4382
|
+
}
|
|
4152
4383
|
function progress(stage, details) {
|
|
4153
4384
|
if (depsHumanLog) {
|
|
4154
4385
|
const label = PROGRESS_HUMAN_LABELS[stage];
|
|
4155
4386
|
if (label) {
|
|
4156
4387
|
depsHumanLog(label);
|
|
4157
4388
|
}
|
|
4389
|
+
const detail = formatProgressDetail(stage, details);
|
|
4390
|
+
if (detail) {
|
|
4391
|
+
depsHumanLog(detail);
|
|
4392
|
+
}
|
|
4158
4393
|
return;
|
|
4159
4394
|
}
|
|
4160
4395
|
const meta3 = stepMeta(stage);
|
|
@@ -4169,6 +4404,10 @@ function progress(stage, details) {
|
|
|
4169
4404
|
}
|
|
4170
4405
|
function depsStructuredLog(level, payload) {
|
|
4171
4406
|
if (depsHumanLog) {
|
|
4407
|
+
const human = structuredLogToHuman(level, payload);
|
|
4408
|
+
if (human) {
|
|
4409
|
+
depsHumanLog(human);
|
|
4410
|
+
}
|
|
4172
4411
|
return;
|
|
4173
4412
|
}
|
|
4174
4413
|
log(level, payload);
|
|
@@ -4267,12 +4506,42 @@ function playwrightProbeUrls(host) {
|
|
|
4267
4506
|
}
|
|
4268
4507
|
return [h];
|
|
4269
4508
|
}
|
|
4509
|
+
function isChinaFriendlyNpmRegistry(registry2) {
|
|
4510
|
+
const r = registry2.toLowerCase();
|
|
4511
|
+
return CHINA_NPM_REGISTRY_HINTS.some((hint) => r.includes(hint));
|
|
4512
|
+
}
|
|
4513
|
+
function isTruthyEnv(name) {
|
|
4514
|
+
const s = String(process.env[name] ?? "").trim().toLowerCase();
|
|
4515
|
+
return s === "1" || s === "true" || s === "yes" || s === "on";
|
|
4516
|
+
}
|
|
4517
|
+
function playwrightHostConfiguredByUser(config2) {
|
|
4518
|
+
if (process.env.ADA_PLAYWRIGHT_HOST_FROM_PREINSTALL === "1") {
|
|
4519
|
+
return "";
|
|
4520
|
+
}
|
|
4521
|
+
const raw = process.env.PLAYWRIGHT_DOWNLOAD_HOST?.trim() || playwrightDownloadHost(config2).trim();
|
|
4522
|
+
return raw ? normalizeHostUrl(raw) : "";
|
|
4523
|
+
}
|
|
4524
|
+
function preferPlaywrightHostsForNpmRegistry(ranked, npmRegistry) {
|
|
4525
|
+
if (!isTruthyEnv("ADA_PLAYWRIGHT_PREFER_CN_MIRROR") && !isChinaFriendlyNpmRegistry(npmRegistry)) {
|
|
4526
|
+
return ranked;
|
|
4527
|
+
}
|
|
4528
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4529
|
+
const out = [];
|
|
4530
|
+
for (const url2 of [...CHINA_PLAYWRIGHT_HOST_PRIORITY, ...ranked]) {
|
|
4531
|
+
const n = normalizeHostUrl(url2);
|
|
4532
|
+
if (!seen.has(n)) {
|
|
4533
|
+
seen.add(n);
|
|
4534
|
+
out.push(n);
|
|
4535
|
+
}
|
|
4536
|
+
}
|
|
4537
|
+
return out;
|
|
4538
|
+
}
|
|
4270
4539
|
function playwrightHostCandidates(config2) {
|
|
4271
|
-
const configured =
|
|
4540
|
+
const configured = playwrightHostConfiguredByUser(config2);
|
|
4272
4541
|
const fromConfig = Array.isArray(config2.dependencies.playwrightHostCandidates) ? config2.dependencies.playwrightHostCandidates.map((x) => normalizeHostUrl(String(x).trim())).filter(Boolean) : [];
|
|
4273
4542
|
const configuredList = fromConfig.length > 0 ? fromConfig : [...DEFAULT_PLAYWRIGHT_HOST_CANDIDATES];
|
|
4274
4543
|
const extra = process.env.ADA_PLAYWRIGHT_HOST_CANDIDATES ? process.env.ADA_PLAYWRIGHT_HOST_CANDIDATES.split(",").map((x) => normalizeHostUrl(x.trim())).filter(Boolean) : [];
|
|
4275
|
-
const ordered = [configured, ...configuredList, ...extra];
|
|
4544
|
+
const ordered = configured ? [configured, ...configuredList, ...extra] : [...configuredList, ...extra];
|
|
4276
4545
|
const seen = /* @__PURE__ */ new Set();
|
|
4277
4546
|
const out = [];
|
|
4278
4547
|
for (const url2 of ordered) {
|
|
@@ -4408,6 +4677,7 @@ async function runInstallWithPriority(config2, packages, onLogLine) {
|
|
|
4408
4677
|
let lastError = void 0;
|
|
4409
4678
|
for (const strategy of strategies) {
|
|
4410
4679
|
try {
|
|
4680
|
+
onLogLine?.(`[deps] \u5C1D\u8BD5 ${strategy.name} \u5B89\u88C5\u5305\u2026`);
|
|
4411
4681
|
depsStructuredLog("info", { event: "deps.install.strategy.try", details: { strategy: strategy.name, packages } });
|
|
4412
4682
|
await strategy.run();
|
|
4413
4683
|
depsStructuredLog("info", { event: "deps.install.strategy.ok", details: { strategy: strategy.name } });
|
|
@@ -4431,13 +4701,14 @@ async function runAppiumDriverInstallWithPriority(config2, driver, onLogLine) {
|
|
|
4431
4701
|
onLogLine?.(`[appium] \u5B89\u88C5\u9A71\u52A8: ${driver}`);
|
|
4432
4702
|
const compatibleSpecs = await resolveCompatibleDriverSpecs(driver);
|
|
4433
4703
|
const appiumMajor = await getAppiumMajorVersion();
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
const uniqueTargets =
|
|
4704
|
+
if (appiumMajor !== null && appiumMajor >= 3) {
|
|
4705
|
+
onLogLine?.(`[appium] \u68C0\u6D4B\u5230 Appium ${appiumMajor}.x\uFF0C\u4F7F\u7528\u5B98\u65B9\u9A71\u52A8\u540D\u5B89\u88C5\uFF08\u5982 uiautomator2\uFF09`);
|
|
4706
|
+
}
|
|
4707
|
+
const uniqueTargets = resolveAppiumDriverInstallTargets(driver, appiumMajor, compatibleSpecs);
|
|
4438
4708
|
let lastError = void 0;
|
|
4439
4709
|
for (const target of uniqueTargets) {
|
|
4440
|
-
const installArgs =
|
|
4710
|
+
const installArgs = buildAppiumDriverInstallArgs(target, appiumMajor);
|
|
4711
|
+
onLogLine?.(`[appium] \u6267\u884C: npm ${installArgs.join(" ")}`);
|
|
4441
4712
|
const strategies = [
|
|
4442
4713
|
{
|
|
4443
4714
|
name: "npm",
|
|
@@ -4524,24 +4795,32 @@ async function installPlaywrightBrowser(config2, onLogLine, options) {
|
|
|
4524
4795
|
if (targets.length > 0) {
|
|
4525
4796
|
installArgs.push(...targets);
|
|
4526
4797
|
}
|
|
4527
|
-
const
|
|
4528
|
-
|
|
4529
|
-
|
|
4798
|
+
const npmRegistry = await detectBestRegistry(config2, npmProxyRegistry());
|
|
4799
|
+
let rankedHosts = await rankPlaywrightHosts(config2);
|
|
4800
|
+
rankedHosts = preferPlaywrightHostsForNpmRegistry(rankedHosts, npmRegistry);
|
|
4801
|
+
const baseTimeoutMs = playwrightInstallTimeoutMs();
|
|
4802
|
+
onLogLine?.(
|
|
4803
|
+
`[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`
|
|
4804
|
+
);
|
|
4805
|
+
if (isChinaFriendlyNpmRegistry(npmRegistry) || isTruthyEnv("ADA_PLAYWRIGHT_PREFER_CN_MIRROR")) {
|
|
4806
|
+
onLogLine?.(`[playwright] \u56FD\u5185 npm \u6E90 ${npmRegistry}\uFF0C\u4F18\u5148 npmmirror Playwright CDN`);
|
|
4807
|
+
}
|
|
4530
4808
|
let lastHost = "";
|
|
4531
4809
|
for (let i = 0; i < rankedHosts.length; i++) {
|
|
4532
4810
|
const host = rankedHosts[i];
|
|
4811
|
+
const attemptTimeoutMs = playwrightInstallAttemptTimeoutMs(i, baseTimeoutMs);
|
|
4533
4812
|
lastHost = host;
|
|
4534
4813
|
if (i > 0) {
|
|
4535
|
-
onLogLine?.(`[playwright] \u6362\u955C\u50CF: ${host}`);
|
|
4814
|
+
onLogLine?.(`[playwright] \u6362\u955C\u50CF (${i + 1}/${rankedHosts.length}): ${host}`);
|
|
4536
4815
|
} else {
|
|
4537
4816
|
onLogLine?.(
|
|
4538
|
-
`[playwright] playwright@${version2}\uFF0CCDN ${host}\uFF0C\u76EE\u6807 ${targets.length ? targets.join(",") : "chromium"}`
|
|
4817
|
+
`[playwright] playwright@${version2}\uFF0CCDN ${host}\uFF08${i + 1}/${rankedHosts.length}\uFF09\uFF0C\u76EE\u6807 ${targets.length ? targets.join(",") : "chromium"}`
|
|
4539
4818
|
);
|
|
4540
4819
|
}
|
|
4541
4820
|
try {
|
|
4542
4821
|
await runCommand2(command, installArgs, {
|
|
4543
4822
|
env: { PLAYWRIGHT_DOWNLOAD_HOST: host },
|
|
4544
|
-
timeoutMs,
|
|
4823
|
+
timeoutMs: attemptTimeoutMs,
|
|
4545
4824
|
onLogLine: createPlaywrightInstallLogSink(onLogLine)
|
|
4546
4825
|
});
|
|
4547
4826
|
progress("playwright.browser.install.done", { selectedHost: host, attempt: i + 1 });
|
|
@@ -4560,7 +4839,7 @@ async function installPlaywrightBrowser(config2, onLogLine, options) {
|
|
|
4560
4839
|
}
|
|
4561
4840
|
}
|
|
4562
4841
|
onLogLine?.(
|
|
4563
|
-
`[playwright][warn] \u6D4F\u89C8\u5668\u672A\u5B89\u88C5\u5B8C\u6210\uFF08\u5DF2\u5C1D\u8BD5 ${rankedHosts.length} \u4E2A CDN\uFF09\u3002\
|
|
4842
|
+
`[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`
|
|
4564
4843
|
);
|
|
4565
4844
|
if (lastHost) {
|
|
4566
4845
|
onLogLine?.(`[playwright][warn] \u6700\u540E\u5C1D\u8BD5: ${lastHost}`);
|
|
@@ -5052,7 +5331,7 @@ async function getDependencyHealth(config2) {
|
|
|
5052
5331
|
missingAppiumDrivers
|
|
5053
5332
|
};
|
|
5054
5333
|
}
|
|
5055
|
-
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, PLAYWRIGHT_HOST_FALLBACK, PW_INSTALL_TARGETS;
|
|
5334
|
+
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, APPIUM3_BUILTIN_DRIVER_NAMES, detectedBestRegistryByKey, PROGRESS_STEPS, PROGRESS_HUMAN_LABELS, DEFAULT_PLAYWRIGHT_HOST_CANDIDATES, CHINA_NPM_REGISTRY_HINTS, CHINA_PLAYWRIGHT_HOST_PRIORITY, PLAYWRIGHT_HOST_FALLBACK, PW_INSTALL_TARGETS;
|
|
5056
5335
|
var init_dependency_installer = __esm({
|
|
5057
5336
|
"../ada-agent/src/dependency-installer.ts"() {
|
|
5058
5337
|
import_node_module = require("node:module");
|
|
@@ -5072,6 +5351,16 @@ var init_dependency_installer = __esm({
|
|
|
5072
5351
|
"https://repo.huaweicloud.com/repository/npm",
|
|
5073
5352
|
"https://registry.npmjs.org"
|
|
5074
5353
|
];
|
|
5354
|
+
APPIUM3_BUILTIN_DRIVER_NAMES = /* @__PURE__ */ new Set([
|
|
5355
|
+
"uiautomator2",
|
|
5356
|
+
"xcuitest",
|
|
5357
|
+
"espresso",
|
|
5358
|
+
"mac2",
|
|
5359
|
+
"windows",
|
|
5360
|
+
"safari",
|
|
5361
|
+
"gecko",
|
|
5362
|
+
"chromium"
|
|
5363
|
+
]);
|
|
5075
5364
|
detectedBestRegistryByKey = /* @__PURE__ */ new Map();
|
|
5076
5365
|
PROGRESS_STEPS = [
|
|
5077
5366
|
"deps.ensure.start",
|
|
@@ -5086,9 +5375,16 @@ var init_dependency_installer = __esm({
|
|
|
5086
5375
|
"deps.ensure.start": "[deps] \u5F00\u59CB\u68C0\u6D4B\u4F9D\u8D56",
|
|
5087
5376
|
"registry.probe.start": "[deps] \u63A2\u6D4B npm \u955C\u50CF\u2026",
|
|
5088
5377
|
"packages.install.start": "[deps] \u5B89\u88C5 npm \u5305\u2026",
|
|
5378
|
+
"packages.install.done": "[deps] npm \u5305\u5B89\u88C5\u5B8C\u6210",
|
|
5089
5379
|
"playwright.host.probe.start": "[playwright] \u63A2\u6D4B\u6D4F\u89C8\u5668 CDN\u2026",
|
|
5090
5380
|
"playwright.browser.install.start": "[playwright] \u5B89\u88C5\u6D4F\u89C8\u5668\u2026",
|
|
5381
|
+
"playwright.browser.install.done": "[playwright] \u6D4F\u89C8\u5668\u5B89\u88C5\u5B8C\u6210",
|
|
5382
|
+
"playwright.selfcheck.start": "[playwright] \u81EA\u68C0\u2026",
|
|
5383
|
+
"playwright.selfcheck.done": "[playwright] \u81EA\u68C0\u5B8C\u6210",
|
|
5091
5384
|
"appium.driver.ensure.start": "[appium] \u5B89\u88C5\u9A71\u52A8\u2026",
|
|
5385
|
+
"appium.driver.ensure.done": "[appium] \u9A71\u52A8\u5B89\u88C5\u5B8C\u6210",
|
|
5386
|
+
"selenium.check.start": "[selenium] \u68C0\u6D4B\u539F\u751F\u9A71\u52A8\u2026",
|
|
5387
|
+
"selenium.check.done": "[selenium] \u68C0\u6D4B\u5B8C\u6210",
|
|
5092
5388
|
"deps.ensure.done": "[deps] \u4F9D\u8D56\u68C0\u6D4B\u5B8C\u6210"
|
|
5093
5389
|
};
|
|
5094
5390
|
DEFAULT_PLAYWRIGHT_HOST_CANDIDATES = [
|
|
@@ -5097,6 +5393,11 @@ var init_dependency_installer = __esm({
|
|
|
5097
5393
|
"https://npmmirror.com/mirrors/playwright",
|
|
5098
5394
|
"https://cdn.npmmirror.com/binaries/playwright"
|
|
5099
5395
|
];
|
|
5396
|
+
CHINA_NPM_REGISTRY_HINTS = ["npmmirror.com", "tencent", "huaweicloud", "huawei.com"];
|
|
5397
|
+
CHINA_PLAYWRIGHT_HOST_PRIORITY = [
|
|
5398
|
+
"https://cdn.npmmirror.com/binaries/playwright",
|
|
5399
|
+
"https://npmmirror.com/mirrors/playwright"
|
|
5400
|
+
];
|
|
5100
5401
|
PLAYWRIGHT_HOST_FALLBACK = DEFAULT_PLAYWRIGHT_HOST_CANDIDATES[0];
|
|
5101
5402
|
PW_INSTALL_TARGETS = /* @__PURE__ */ new Set([
|
|
5102
5403
|
"chromium",
|
|
@@ -32976,7 +33277,9 @@ function resolveBootstrapInstallDeps(argv2) {
|
|
|
32976
33277
|
}
|
|
32977
33278
|
var PREINSTALL_PLAYWRIGHT_HOST_ALLOW = /* @__PURE__ */ new Set([
|
|
32978
33279
|
"https://cdn.playwright.dev",
|
|
32979
|
-
"https://playwright.azureedge.net"
|
|
33280
|
+
"https://playwright.azureedge.net",
|
|
33281
|
+
"https://cdn.npmmirror.com/binaries/playwright",
|
|
33282
|
+
"https://npmmirror.com/mirrors/playwright"
|
|
32980
33283
|
]);
|
|
32981
33284
|
function normalizePlaywrightHost(url2) {
|
|
32982
33285
|
return url2.replace(/\/$/, "");
|
|
@@ -32994,7 +33297,8 @@ function applyPreinstallPlaywrightHostFile() {
|
|
|
32994
33297
|
const host = normalizePlaywrightHost(import_node_fs3.default.readFileSync(file2, "utf8").trim());
|
|
32995
33298
|
if (host.length > 0 && PREINSTALL_PLAYWRIGHT_HOST_ALLOW.has(host)) {
|
|
32996
33299
|
process.env.PLAYWRIGHT_DOWNLOAD_HOST = host;
|
|
32997
|
-
|
|
33300
|
+
process.env.ADA_PLAYWRIGHT_HOST_FROM_PREINSTALL = "1";
|
|
33301
|
+
console.error(`[ADA-MCP] using playwright CDN from ${file2}: ${host} (install-deps \u5C06\u91CD\u65B0\u6D4B\u901F\u6392\u5E8F)`);
|
|
32998
33302
|
return;
|
|
32999
33303
|
}
|
|
33000
33304
|
if (host.length > 0) {
|
|
@@ -33012,7 +33316,7 @@ function ensureDefaultInstallTimeouts() {
|
|
|
33012
33316
|
process.env.ADA_INSTALL_STRATEGY_TIMEOUT_MS = "120000";
|
|
33013
33317
|
}
|
|
33014
33318
|
if (!process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS?.trim()) {
|
|
33015
|
-
process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS = "
|
|
33319
|
+
process.env.ADA_PLAYWRIGHT_INSTALL_TIMEOUT_MS = "1800000";
|
|
33016
33320
|
}
|
|
33017
33321
|
}
|
|
33018
33322
|
async function runBootstrapInstallDeps(argv2) {
|
package/package.json
CHANGED
|
@@ -232,6 +232,46 @@ var import_node_child_process = require("node:child_process");
|
|
|
232
232
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
233
233
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
234
234
|
var DEFAULT_NATIVE_DRIVERS_DIR = "dirver";
|
|
235
|
+
var DEFAULT_GECKODRIVER_MIRROR = "https://mirrors.huaweicloud.com/geckodriver";
|
|
236
|
+
var GITHUB_GECKODRIVER_RELEASES = "https://github.com/mozilla/geckodriver/releases";
|
|
237
|
+
var SELENIUM_DRIVER_MANUAL_DOWNLOAD_REFERENCES = [
|
|
238
|
+
{
|
|
239
|
+
browser: "Chrome/Chromium",
|
|
240
|
+
platforms: "Windows/Linux/macOS",
|
|
241
|
+
vendor: "\u8C37\u6B4C",
|
|
242
|
+
url: "https://chromedriver.storage.googleapis.com/index.html"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
browser: "Firefox",
|
|
246
|
+
platforms: "Windows/Linux/macOS",
|
|
247
|
+
vendor: "Mozilla / ?????",
|
|
248
|
+
url: `${DEFAULT_GECKODRIVER_MIRROR}/v0.36.0/?????????????? ${GITHUB_GECKODRIVER_RELEASES}?`
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
browser: "Edge",
|
|
252
|
+
platforms: "win10",
|
|
253
|
+
vendor: "\u5FAE\u8F6F",
|
|
254
|
+
url: "https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
browser: "Internet Explorer",
|
|
258
|
+
platforms: "Windows",
|
|
259
|
+
vendor: "Selenium \u9879\u76EE\u7EC4",
|
|
260
|
+
url: "https://selenium-release.storage.googleapis.com/index.html"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
browser: "Safari",
|
|
264
|
+
platforms: "macOS El Capitan \u53CA\u66F4\u9AD8\u7248\u672C",
|
|
265
|
+
vendor: "\u82F9\u679C",
|
|
266
|
+
url: "\uFF08\u7CFB\u7EDF\u5185\u7F6E\uFF0C\u65E0\u9700\u5355\u72EC\u4E0B\u8F7D\uFF09"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
browser: "Opera",
|
|
270
|
+
platforms: "Windows/macOS/Linux",
|
|
271
|
+
vendor: "Opera",
|
|
272
|
+
url: "https://github.com/operasoftware/operachromiumdriver/releases"
|
|
273
|
+
}
|
|
274
|
+
];
|
|
235
275
|
async function fileExists(filePath) {
|
|
236
276
|
try {
|
|
237
277
|
await import_promises.default.access(filePath);
|
|
@@ -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");
|