@xcanwin/manyoyo 8.3.0 → 8.3.1
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.en.md +1 -1
- package/README.md +1 -1
- package/bin/manyoyo.js +70 -164
- package/docker/manyoyo.Dockerfile +16 -4
- package/docker/res/playwright/browser.json +28 -0
- package/docker/res/playwright/playwright-cli.sh +26 -0
- package/docker/res/playwright/stealth.init.js +14 -0
- package/lib/global-config.js +8 -33
- package/lib/init-config.js +11 -2
- package/lib/json5-text-edit.js +6 -3
- package/lib/plugin/fingerprint.js +176 -0
- package/lib/plugin/index.js +62 -47
- package/lib/plugin/playwright-assets/vnc-entry.sh +21 -0
- package/lib/plugin/playwright-extensions.js +299 -0
- package/lib/plugin/playwright-probe.js +53 -0
- package/lib/plugin/playwright-relay.js +88 -0
- package/lib/plugin/playwright-server.js +23 -0
- package/lib/plugin/playwright.js +707 -1853
- package/lib/web/server.js +27 -3
- package/manyoyo.example.json +16 -28
- package/package.json +4 -5
- package/docker/res/playwright/cli-cont-headless.init.js +0 -12
- package/docker/res/playwright/cli-cont-headless.json +0 -37
- package/lib/plugin/playwright-assets/compose-headed.yaml +0 -19
- package/lib/plugin/playwright-assets/compose-headless.yaml +0 -11
- package/lib/plugin/playwright-assets/headed.Dockerfile +0 -15
- package/lib/plugin/playwright-assets/init-headed.sh +0 -17
package/lib/web/server.js
CHANGED
|
@@ -10,6 +10,7 @@ const http = require('http');
|
|
|
10
10
|
const WebSocket = require('ws');
|
|
11
11
|
const JSON5 = require('json5');
|
|
12
12
|
const { buildContainerRunArgs } = require('../container-run');
|
|
13
|
+
const { buildContainerIntegration, mergeIntegration } = require('../plugin');
|
|
13
14
|
const { applyAptMirror } = require('../mirrors');
|
|
14
15
|
const { normalizeMirrors } = require('../runtime-normalizers');
|
|
15
16
|
const { estimateContainerCapacity } = require('../capacity');
|
|
@@ -3325,6 +3326,27 @@ function readWebMirrors(state) {
|
|
|
3325
3326
|
}
|
|
3326
3327
|
}
|
|
3327
3328
|
|
|
3329
|
+
// 会话容器与 CLI run 共用同一个 Playwright 浏览器模式集成(挂载目录、NO_PROXY 等)
|
|
3330
|
+
async function buildWebPlaywrightIntegration(ctx, state, runtime) {
|
|
3331
|
+
let globalConfig = {};
|
|
3332
|
+
try {
|
|
3333
|
+
const snapshot = readWebConfigSnapshot(state.webConfigPath);
|
|
3334
|
+
globalConfig = snapshot.parseError ? {} : (snapshot.parsed || {});
|
|
3335
|
+
} catch (e) {
|
|
3336
|
+
globalConfig = {};
|
|
3337
|
+
}
|
|
3338
|
+
const integration = await buildContainerIntegration({
|
|
3339
|
+
globalConfig,
|
|
3340
|
+
homeDir: ctx.homeDir,
|
|
3341
|
+
runtimeCommand: ctx.dockerCmd || 'docker',
|
|
3342
|
+
envEntries: (runtime.containerEnvs || []).filter((_, i) => i % 2 === 1)
|
|
3343
|
+
});
|
|
3344
|
+
if (integration.warning) {
|
|
3345
|
+
console.warn(integration.warning);
|
|
3346
|
+
}
|
|
3347
|
+
return mergeIntegration(runtime, integration);
|
|
3348
|
+
}
|
|
3349
|
+
|
|
3328
3350
|
async function ensureWebContainer(ctx, state, containerInput, messageSessionRef = null) {
|
|
3329
3351
|
const runtime = typeof containerInput === 'string'
|
|
3330
3352
|
? buildStaticContainerRuntime(ctx, containerInput)
|
|
@@ -3336,6 +3358,7 @@ async function ensureWebContainer(ctx, state, containerInput, messageSessionRef
|
|
|
3336
3358
|
|
|
3337
3359
|
if (!ctx.containerExists(runtime.containerName)) {
|
|
3338
3360
|
const mirrors = readWebMirrors(state);
|
|
3361
|
+
const playwright = await buildWebPlaywrightIntegration(ctx, state, runtime);
|
|
3339
3362
|
const args = buildContainerRunArgs({
|
|
3340
3363
|
mirrors,
|
|
3341
3364
|
containerName: runtime.containerName,
|
|
@@ -3344,9 +3367,9 @@ async function ensureWebContainer(ctx, state, containerInput, messageSessionRef
|
|
|
3344
3367
|
imageName: runtime.imageName,
|
|
3345
3368
|
imageVersion: runtime.imageVersion,
|
|
3346
3369
|
contModeArgs: runtime.contModeArgs,
|
|
3347
|
-
containerExtraArgs:
|
|
3348
|
-
containerEnvs:
|
|
3349
|
-
containerVolumes:
|
|
3370
|
+
containerExtraArgs: playwright.containerExtraArgs,
|
|
3371
|
+
containerEnvs: playwright.containerEnvs,
|
|
3372
|
+
containerVolumes: playwright.containerVolumes,
|
|
3350
3373
|
containerPorts: runtime.containerPorts,
|
|
3351
3374
|
defaultCommand: runtime.defaultCommand
|
|
3352
3375
|
});
|
|
@@ -6327,6 +6350,7 @@ async function startWebServer(options) {
|
|
|
6327
6350
|
authPassAuto: options.authPassAuto,
|
|
6328
6351
|
serveTitle: typeof options.serveTitle === 'string' ? options.serveTitle : null,
|
|
6329
6352
|
dockerCmd: options.dockerCmd,
|
|
6353
|
+
homeDir: options.homeDir,
|
|
6330
6354
|
dockerEnv: options.dockerEnv,
|
|
6331
6355
|
loginTokenDir: options.loginTokenDir || '',
|
|
6332
6356
|
doctorCheck: options.doctorCheck,
|
package/manyoyo.example.json
CHANGED
|
@@ -68,38 +68,25 @@
|
|
|
68
68
|
// }
|
|
69
69
|
// },
|
|
70
70
|
|
|
71
|
-
// 可选插件(manyoyo playwright
|
|
71
|
+
// 可选插件(manyoyo playwright):容器内浏览器默认就能用,这里只放少量可调项
|
|
72
72
|
"plugins": {
|
|
73
73
|
"playwright": {
|
|
74
|
-
//
|
|
75
|
-
"
|
|
76
|
-
//
|
|
77
|
-
"
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
//
|
|
83
|
-
"
|
|
84
|
-
// playwright ext-download 的 CRX prodversion 参数
|
|
85
|
-
"extensionProdversion": "132.0.0.0",
|
|
86
|
-
// 注入 navigator.platform(默认与内置 UA 对齐为 MacIntel)
|
|
87
|
-
"navigatorPlatform": "MacIntel",
|
|
74
|
+
// headed / chrome / vnc 模式的浏览器服务端口(容器通过 token 路径连接)
|
|
75
|
+
"port": 8935,
|
|
76
|
+
// vnc 模式的原生 VNC 端口与 noVNC 网页端口(只发布到 127.0.0.1)
|
|
77
|
+
"vncPort": 5900,
|
|
78
|
+
"novncPort": 6080,
|
|
79
|
+
// 浏览器语言与时区,留空时跟随宿主机
|
|
80
|
+
"locale": "",
|
|
81
|
+
"timezoneId": "",
|
|
82
|
+
// 强制 navigator.platform;留空则使用浏览器真实值(推荐,与 UA、字体、WebGL 自洽)
|
|
83
|
+
"navigatorPlatform": "",
|
|
88
84
|
// 是否禁用 WebRTC(默认 false)
|
|
89
85
|
"disableWebRTC": false,
|
|
90
|
-
//
|
|
86
|
+
// chrome 模式读取的 DevToolsActivePort 文件;留空时自动探测常见路径
|
|
91
87
|
"devtoolsActivePortPath": "",
|
|
92
|
-
//
|
|
93
|
-
"
|
|
94
|
-
"ports": {
|
|
95
|
-
"mcpContHeadless": 8931,
|
|
96
|
-
"mcpContHeaded": 8932,
|
|
97
|
-
"mcpHostHeadless": 8933,
|
|
98
|
-
"mcpHostHeaded": 8934,
|
|
99
|
-
"cliHostHeadless": 8935,
|
|
100
|
-
"cliHostHeaded": 8936,
|
|
101
|
-
"mcpContHeadedNoVnc": 6080
|
|
102
|
-
}
|
|
88
|
+
// playwright ext-download 的 CRX prodversion 参数
|
|
89
|
+
"extensionProdversion": "132.0.0.0"
|
|
103
90
|
}
|
|
104
91
|
},
|
|
105
92
|
|
|
@@ -118,7 +105,8 @@
|
|
|
118
105
|
"yolo": "c",
|
|
119
106
|
"plugins": {
|
|
120
107
|
"playwright": {
|
|
121
|
-
"
|
|
108
|
+
"locale": "zh-CN",
|
|
109
|
+
"timezoneId": "Asia/Shanghai"
|
|
122
110
|
}
|
|
123
111
|
}
|
|
124
112
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcanwin/manyoyo",
|
|
3
|
-
"version": "8.3.
|
|
4
|
-
"imageVersion": "2.1.
|
|
3
|
+
"version": "8.3.1",
|
|
4
|
+
"imageVersion": "2.1.1-common",
|
|
5
5
|
"playwrightCliVersion": "0.1.21",
|
|
6
6
|
"description": "MANYOYO – open-source AI agent sandbox: run AI coding agents (Claude Code / Codex / Gemini) safely in Docker/Podman",
|
|
7
7
|
"keywords": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"prepack": "npm run build:web",
|
|
41
41
|
"test": "jest --coverage && npm run test:web",
|
|
42
42
|
"test:unit": "jest test/ --testPathIgnorePatterns '<rootDir>/temp/' '<rootDir>/test/integration/' && npm run test:web",
|
|
43
|
-
"test:integration": "jest test/integration/",
|
|
43
|
+
"test:integration": "jest test/integration/ --runInBand",
|
|
44
44
|
"test:installer": "jest test/installer.test.js",
|
|
45
45
|
"lint:sh": "command -v shellcheck >/dev/null 2>&1 || { echo '未安装 shellcheck:macOS 用 brew install shellcheck,Debian/Ubuntu 用 sudo apt install shellcheck,或用 docker run --rm -v \"$PWD:/mnt\" -w /mnt koalaman/shellcheck:stable scripts/install.sh scripts/offline/*.sh' >&2; exit 1; } && shellcheck -s sh -x -e SC1091 scripts/install.sh scripts/offline/*.sh",
|
|
46
46
|
"docs:dev": "vitepress dev docs --host 127.0.0.1 --port 5173",
|
|
@@ -65,10 +65,9 @@
|
|
|
65
65
|
"manyoyo.example.json"
|
|
66
66
|
],
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@playwright/
|
|
68
|
+
"@playwright/cli": "0.1.21",
|
|
69
69
|
"commander": "^15.0.0",
|
|
70
70
|
"json5": "^2.2.3",
|
|
71
|
-
"playwright": "1.63.0",
|
|
72
71
|
"ws": "^8.21.3"
|
|
73
72
|
},
|
|
74
73
|
"devDependencies": {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
(function () {
|
|
4
|
-
const platformValue = 'MacIntel';
|
|
5
|
-
try {
|
|
6
|
-
const navProto = Object.getPrototypeOf(navigator);
|
|
7
|
-
Object.defineProperty(navProto, 'platform', {
|
|
8
|
-
configurable: true,
|
|
9
|
-
get: () => platformValue
|
|
10
|
-
});
|
|
11
|
-
} catch (_) {}
|
|
12
|
-
})();
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"outputDir": "/tmp/.playwright-cli",
|
|
3
|
-
"browser": {
|
|
4
|
-
"chromiumSandbox": true,
|
|
5
|
-
"browserName": "chromium",
|
|
6
|
-
"initScript": [
|
|
7
|
-
"/app/config/cli-cont-headless.init.js"
|
|
8
|
-
],
|
|
9
|
-
"launchOptions": {
|
|
10
|
-
"channel": "chromium",
|
|
11
|
-
"headless": true,
|
|
12
|
-
"args": [
|
|
13
|
-
"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
|
|
14
|
-
"--lang=zh-CN",
|
|
15
|
-
"--window-size=1366,768",
|
|
16
|
-
"--disable-blink-features=AutomationControlled",
|
|
17
|
-
"--force-webrtc-ip-handling-policy=disable_non_proxied_udp"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
"contextOptions": {
|
|
21
|
-
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
|
|
22
|
-
"locale": "zh-CN",
|
|
23
|
-
"timezoneId": "Asia/Shanghai",
|
|
24
|
-
"viewport": {
|
|
25
|
-
"width": 1366,
|
|
26
|
-
"height": 768
|
|
27
|
-
},
|
|
28
|
-
"screen": {
|
|
29
|
-
"width": 1366,
|
|
30
|
-
"height": 768
|
|
31
|
-
},
|
|
32
|
-
"extraHTTPHeaders": {
|
|
33
|
-
"Accept-Language": "zh-CN,zh;q=0.9"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
playwright:
|
|
3
|
-
build:
|
|
4
|
-
context: .
|
|
5
|
-
dockerfile: headed.Dockerfile
|
|
6
|
-
args:
|
|
7
|
-
PLAYWRIGHT_MCP_BASE_IMAGE: mcr.microsoft.com/playwright/mcp:${PLAYWRIGHT_MCP_DOCKER_TAG:-latest}
|
|
8
|
-
image: ${PLAYWRIGHT_MCP_IMAGE:-localhost/xcanwin/manyoyo-playwright-headed}
|
|
9
|
-
container_name: ${PLAYWRIGHT_MCP_CONTAINER_NAME:-my-playwright-mcp-cont-headed}
|
|
10
|
-
init: true
|
|
11
|
-
stdin_open: true
|
|
12
|
-
ports:
|
|
13
|
-
- "127.0.0.1:${PLAYWRIGHT_MCP_PORT:-8932}:${PLAYWRIGHT_MCP_PORT:-8932}"
|
|
14
|
-
- "127.0.0.1:${PLAYWRIGHT_MCP_NOVNC_PORT:-6080}:6080"
|
|
15
|
-
environment:
|
|
16
|
-
VNC_PASSWORD: "${VNC_PASSWORD:?VNC_PASSWORD is required}"
|
|
17
|
-
volumes:
|
|
18
|
-
- ${PLAYWRIGHT_MCP_CONFIG_PATH:?PLAYWRIGHT_MCP_CONFIG_PATH is required}:/app/config/playwright.json:ro
|
|
19
|
-
command: ["node", "cli.js", "--config", "/app/config/playwright.json"]
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
playwright:
|
|
3
|
-
image: mcr.microsoft.com/playwright/mcp:${PLAYWRIGHT_MCP_DOCKER_TAG:-latest}
|
|
4
|
-
container_name: ${PLAYWRIGHT_MCP_CONTAINER_NAME:-my-playwright-mcp-cont-headless}
|
|
5
|
-
init: true
|
|
6
|
-
stdin_open: true
|
|
7
|
-
ports:
|
|
8
|
-
- "127.0.0.1:${PLAYWRIGHT_MCP_PORT:-8931}:${PLAYWRIGHT_MCP_PORT:-8931}"
|
|
9
|
-
volumes:
|
|
10
|
-
- ${PLAYWRIGHT_MCP_CONFIG_PATH:?PLAYWRIGHT_MCP_CONFIG_PATH is required}:/app/config/playwright.json:ro
|
|
11
|
-
command: ["--config", "/app/config/playwright.json"]
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
ARG PLAYWRIGHT_MCP_BASE_IMAGE=mcr.microsoft.com/playwright/mcp:latest
|
|
2
|
-
FROM ${PLAYWRIGHT_MCP_BASE_IMAGE}
|
|
3
|
-
|
|
4
|
-
USER root
|
|
5
|
-
RUN apt-get update && \
|
|
6
|
-
apt-get install -y --no-install-recommends \
|
|
7
|
-
ca-certificates xvfb x11vnc novnc websockify fluxbox && \
|
|
8
|
-
update-ca-certificates && \
|
|
9
|
-
apt-get clean && \
|
|
10
|
-
rm -rf /tmp/* /var/tmp/* /var/log/apt /var/log/*.log /var/lib/apt/lists/*
|
|
11
|
-
|
|
12
|
-
COPY init-headed.sh /usr/local/bin/init-headed.sh
|
|
13
|
-
RUN chmod +x /usr/local/bin/init-headed.sh
|
|
14
|
-
|
|
15
|
-
ENTRYPOINT ["/usr/local/bin/init-headed.sh"]
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
export DISPLAY=:99
|
|
5
|
-
|
|
6
|
-
Xvfb :99 -screen 0 1920x1080x24 -nolisten tcp &
|
|
7
|
-
fluxbox >/tmp/fluxbox.log 2>&1 &
|
|
8
|
-
|
|
9
|
-
if [[ -z "${VNC_PASSWORD:-}" ]]; then
|
|
10
|
-
echo "VNC_PASSWORD is required."
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
x11vnc -display :99 -forever -shared -rfbport 5900 -localhost -passwd "$VNC_PASSWORD" >/tmp/x11vnc.log 2>&1 &
|
|
15
|
-
websockify --web=/usr/share/novnc/ 6080 localhost:5900 >/tmp/websockify.log 2>&1 &
|
|
16
|
-
|
|
17
|
-
exec "$@"
|