@weavetab/mcp 2.5.0 → 2.5.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/AGENTS.md +49 -49
- package/ARCHITECTURE.md +590 -590
- package/LICENSE +216 -216
- package/README.md +269 -269
- package/SECURITY.md +207 -207
- package/TROUBLESHOOTING.md +373 -365
- package/dist/anticaptcha/detector.js +395 -395
- package/dist/anticaptcha/solver.js +130 -130
- package/dist/cdp/bridge.js +73 -73
- package/dist/cdp/connector.js +46 -22
- package/dist/cdp/extension.js +34 -34
- package/dist/cdp/helpers.js +174 -174
- package/dist/cdp/pruner.js +195 -195
- package/dist/cdp/ref_cache.js +66 -66
- package/dist/cdp/security.js +10 -10
- package/dist/cdp/verify.js +57 -57
- package/dist/cdp/walker.js +563 -525
- package/dist/cli/plugin.js +26 -3
- package/dist/config/loader.d.ts +0 -3
- package/dist/config/loader.js +0 -9
- package/dist/index.js +0 -4
- package/dist/intelligence/intent.js +81 -81
- package/dist/intelligence/sessionMemory.js +2 -2
- package/dist/overlay/ghost.js +22 -22
- package/dist/overlay/injector.js +89 -89
- package/dist/plugin/extension_bridge.js +54 -54
- package/dist/plugin/interface.d.ts +7 -0
- package/dist/plugin/loader.js +3 -4
- package/dist/plugin/schema.d.ts +11 -0
- package/dist/plugin/schema.js +59 -0
- package/dist/security/guard.js +18 -18
- package/dist/sensors/actionability.js +167 -167
- package/dist/sensors/guard.js +29 -29
- package/dist/sensors/network.js +15 -17
- package/dist/server.d.ts +1 -1
- package/dist/server.js +173 -144
- package/dist/state/delta.js +6 -7
- package/dist/tools/automation.js +85 -85
- package/dist/tools/canvas.js +48 -25
- package/dist/tools/checkpoint.js +94 -35
- package/dist/tools/click.js +52 -41
- package/dist/tools/clipboard.js +80 -74
- package/dist/tools/design_extract.js +441 -441
- package/dist/tools/dialog.js +13 -13
- package/dist/tools/emulation.d.ts +2 -0
- package/dist/tools/emulation.js +7 -0
- package/dist/tools/fill.js +344 -347
- package/dist/tools/find.js +78 -52
- package/dist/tools/highlight.js +67 -67
- package/dist/tools/inspect.js +54 -25
- package/dist/tools/key.js +42 -35
- package/dist/tools/navigate.d.ts +1 -1
- package/dist/tools/navigate.js +35 -35
- package/dist/tools/office/parse.js +62 -18
- package/dist/tools/pdf.d.ts +9 -0
- package/dist/tools/pdf.js +7 -4
- package/dist/tools/performance.d.ts +11 -4
- package/dist/tools/performance.js +94 -42
- package/dist/tools/performance_test.d.ts +2 -2
- package/dist/tools/performance_test.js +69 -69
- package/dist/tools/pointer.js +116 -116
- package/dist/tools/read.js +99 -67
- package/dist/tools/recording.js +9 -0
- package/dist/tools/scrape.js +146 -146
- package/dist/tools/screenshot.d.ts +2 -0
- package/dist/tools/screenshot.js +46 -4
- package/dist/tools/scroll.d.ts +3 -1
- package/dist/tools/scroll.js +13 -15
- package/dist/tools/select.d.ts +3 -0
- package/dist/tools/select.js +131 -124
- package/dist/tools/snapshot.js +8 -6
- package/dist/tools/storage.d.ts +5 -1
- package/dist/tools/storage.js +16 -0
- package/dist/tools/tabs.d.ts +7 -5
- package/dist/tools/tabs.js +79 -26
- package/dist/tools/thought.js +8 -8
- package/dist/tools/type.js +274 -274
- package/dist/tools/type_secret.js +23 -23
- package/dist/tools/upload.js +3 -3
- package/dist/tools/video_compiler.js +9 -0
- package/dist/tools/wait.js +35 -35
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/DOCUMENTATION.md +583 -585
- package/docs/PLUGINS.md +139 -121
- package/docs/TOOLS.md +3 -4
- package/docs/architecture/blind-injection.md +83 -83
- package/docs/architecture/overview.md +49 -49
- package/docs/architecture/security.md +36 -36
- package/docs/architecture/transport.md +37 -37
- package/docs/cli/cli-commands.md +50 -50
- package/docs/cli/cli-flags.md +28 -28
- package/docs/cli/cli-scripting.md +35 -35
- package/docs/configuration/config-locations.md +23 -23
- package/docs/configuration/configuration.md +39 -27
- package/docs/configuration/env-variables.md +19 -19
- package/docs/configuration/folders.md +62 -55
- package/docs/desktop-automation/electron-apps.md +225 -214
- package/docs/get-started/installation.md +1 -1
- package/docs/get-started/introduction.md +60 -60
- package/docs/get-started/quickstart.md +2 -2
- package/docs/get-started/setup-wizard.md +27 -27
- package/docs/intelligence/site-profiles.md +151 -151
- package/docs/tools/tools.md +582 -631
- package/docs/troubleshooting/trouble-browser.md +27 -27
- package/docs/troubleshooting/trouble-loop.md +31 -31
- package/ext-dist/background.js +415 -415
- package/ext-dist/content.js +2527 -2527
- package/ext-dist/dashboard.html +583 -583
- package/ext-dist/hud/hud.js +3 -3
- package/ext-dist/hud/index.html +20 -20
- package/ext-dist/manifest.json +73 -73
- package/ext-dist/styles.css +223 -223
- package/mcp.json +796 -805
- package/package.json +118 -118
- package/server.json +23 -23
- package/dist/cdp/walker.test.d.ts +0 -2
- package/dist/cdp/walker.test.js +0 -172
- package/dist/intelligence/sessionMemory.test.d.ts +0 -2
- package/dist/intelligence/sessionMemory.test.js +0 -62
- package/dist/intelligence/trail.test.d.ts +0 -2
- package/dist/intelligence/trail.test.js +0 -110
- package/dist/state/cache.test.d.ts +0 -2
- package/dist/state/cache.test.js +0 -76
- package/dist/state/delta.test.d.ts +0 -2
- package/dist/state/delta.test.js +0 -279
- package/dist/state/groups.d.ts +0 -15
- package/dist/state/groups.js +0 -80
- package/dist/tools/accessibility.d.ts +0 -14
- package/dist/tools/accessibility.js +0 -32
- package/dist/tools/ask.d.ts +0 -14
- package/dist/tools/ask.js +0 -49
- package/dist/tools/click_and_wait.d.ts +0 -33
- package/dist/tools/click_and_wait.js +0 -149
- package/dist/tools/drag.d.ts +0 -15
- package/dist/tools/drag.js +0 -29
- package/dist/tools/geo.d.ts +0 -19
- package/dist/tools/geo.js +0 -29
- package/dist/tools/github/analyze.d.ts +0 -4
- package/dist/tools/github/analyze.js +0 -113
- package/dist/tools/github/cache.d.ts +0 -21
- package/dist/tools/github/cache.js +0 -28
- package/dist/tools/github/index.d.ts +0 -19
- package/dist/tools/github/index.js +0 -40
- package/dist/tools/github/issues.d.ts +0 -9
- package/dist/tools/github/issues.js +0 -88
- package/dist/tools/github/pr.d.ts +0 -5
- package/dist/tools/github/pr.js +0 -88
- package/dist/tools/github/rateLimiter.d.ts +0 -4
- package/dist/tools/github/rateLimiter.js +0 -46
- package/dist/tools/github/read.d.ts +0 -34
- package/dist/tools/github/read.js +0 -74
- package/dist/tools/github/repoContext.d.ts +0 -20
- package/dist/tools/github/repoContext.js +0 -129
- package/dist/tools/hover.d.ts +0 -19
- package/dist/tools/hover.js +0 -57
- package/dist/tools/integration.test.d.ts +0 -2
- package/dist/tools/integration.test.js +0 -96
- package/dist/tools/macro_compiler.d.ts +0 -7
- package/dist/tools/macro_compiler.js +0 -82
- package/dist/tools/mouse.d.ts +0 -21
- package/dist/tools/mouse.js +0 -62
- package/dist/tools/response.d.ts +0 -129
- package/dist/tools/response.js +0 -5
- package/dist/tools/wait_for.d.ts +0 -23
- package/dist/tools/wait_for.js +0 -30
- package/dist/tools/windows.d.ts +0 -22
- package/dist/tools/windows.js +0 -57
package/package.json
CHANGED
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@weavetab/mcp",
|
|
3
|
-
"version": "2.5.
|
|
4
|
-
"description": "The open automation engine for AI agents. Control live browsers and desktop apps locally with instant execution.",
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "fy2ne",
|
|
7
|
-
"email": "hello@fy2ne.me",
|
|
8
|
-
"url": "https://fy2ne.me"
|
|
9
|
-
},
|
|
10
|
-
"license": "AGPL-3.0-only",
|
|
11
|
-
"homepage": "https://github.com/
|
|
12
|
-
"repository": {
|
|
13
|
-
"type": "git",
|
|
14
|
-
"url": "https://github.com/
|
|
15
|
-
},
|
|
16
|
-
"bugs": {
|
|
17
|
-
"url": "https://github.com/
|
|
18
|
-
},
|
|
19
|
-
"keywords": [
|
|
20
|
-
"mcp server",
|
|
21
|
-
"mcp",
|
|
22
|
-
"model context protocol",
|
|
23
|
-
"browser automation",
|
|
24
|
-
"electron automation",
|
|
25
|
-
"desktop automation",
|
|
26
|
-
"ai agent",
|
|
27
|
-
"claude mcp",
|
|
28
|
-
"cursor mcp",
|
|
29
|
-
"cdp",
|
|
30
|
-
"chrome devtools protocol",
|
|
31
|
-
"local mcp",
|
|
32
|
-
"Weavetab",
|
|
33
|
-
"Weavetab MCP",
|
|
34
|
-
"@weavetab/mcp",
|
|
35
|
-
"puppeteer alternative",
|
|
36
|
-
"playwright alternative",
|
|
37
|
-
"autonomous agent"
|
|
38
|
-
],
|
|
39
|
-
"engines": {
|
|
40
|
-
"node": "^20.19.0 || ^22.12.0 || >=23"
|
|
41
|
-
},
|
|
42
|
-
"type": "module",
|
|
43
|
-
"main": "./dist/index.js",
|
|
44
|
-
"bin": {
|
|
45
|
-
"weavetab": "dist/index.js"
|
|
46
|
-
},
|
|
47
|
-
"publishConfig": {
|
|
48
|
-
"access": "public"
|
|
49
|
-
},
|
|
50
|
-
"mcpName": "dev.weavetab/mcp",
|
|
51
|
-
"files": [
|
|
52
|
-
"dist/",
|
|
53
|
-
"!dist/**/*.map",
|
|
54
|
-
"!dist/**/*.tsbuildinfo",
|
|
55
|
-
"ext-dist/",
|
|
56
|
-
"!ext-dist/**/src/**",
|
|
57
|
-
"!ext-dist/**/*.ts",
|
|
58
|
-
"docs/",
|
|
59
|
-
"mcp.json",
|
|
60
|
-
"server.json",
|
|
61
|
-
"smithery.yaml",
|
|
62
|
-
"AGENTS.md",
|
|
63
|
-
"SECURITY.md",
|
|
64
|
-
"TROUBLESHOOTING.md",
|
|
65
|
-
"ARCHITECTURE.md",
|
|
66
|
-
"icon.png",
|
|
67
|
-
"LICENSE",
|
|
68
|
-
"README.md"
|
|
69
|
-
],
|
|
70
|
-
"scripts": {
|
|
71
|
-
"build": "
|
|
72
|
-
"build:hud": "
|
|
73
|
-
"build:ext": "node scripts/build-ext.js",
|
|
74
|
-
"docs:generate": "node scripts/generate-docs.js",
|
|
75
|
-
"verify:versions": "node scripts/verify-versions.js",
|
|
76
|
-
"verify:package": "node scripts/verify-package.js",
|
|
77
|
-
"verify": "npm run verify:versions && npm run verify:package",
|
|
78
|
-
"dev": "tsx src/index.ts",
|
|
79
|
-
"start": "node dist/index.js",
|
|
80
|
-
"prepublishOnly": "npm run verify && npm run build",
|
|
81
|
-
"test": "npm run test:unit",
|
|
82
|
-
"test:unit": "node --import tsx/esm --test \"tests/unit/cache.test.ts\" \"tests/unit/delta.test.ts\" \"tests/unit/sessionMemory.test.ts\" \"tests/unit/site_memory.test.ts\" \"tests/unit/trail.test.ts\" \"tests/unit/walker.test.ts\" \"tests/unit/burst.test.ts\" \"tests/unit/navigate.test.ts\" \"tests/unit/select.test.ts\" \"tests/unit/design_extract.test.ts\" \"tests/unit/plugin.test.ts\" \"tests/unit/plugin_lifecycle.test.ts\" \"tests/unit/plugin_interceptors.test.ts\" \"tests/unit/electron.test.ts\" \"tests/unit/stale_ref_recovery.test.ts\" \"tests/unit/secret_containment.test.ts\" \"tests/unit/checkpoint.test.ts\" \"tests/unit/marks.test.ts\" \"tests/unit/highlight.test.ts\"",
|
|
83
|
-
"test:e2e": "tsx tests/e2e/smoke_test.ts"
|
|
84
|
-
},
|
|
85
|
-
"dependencies": {
|
|
86
|
-
"@clack/prompts": "^1.3.0",
|
|
87
|
-
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
88
|
-
"boxen": "^8.0.1",
|
|
89
|
-
"chalk": "^5.6.2",
|
|
90
|
-
"chrome-remote-interface": "^0.33.2",
|
|
91
|
-
"clipboardy": "^5.3.1",
|
|
92
|
-
"csv-parse": "^5.5.0",
|
|
93
|
-
"mammoth": "^1.6.0",
|
|
94
|
-
"open": "^11.0.0",
|
|
95
|
-
"ora": "^9.4.0",
|
|
96
|
-
"pdf-parse": "^1.1.1",
|
|
97
|
-
"picocolors": "^1.1.1",
|
|
98
|
-
"proper-lockfile": "^4.1.2",
|
|
99
|
-
"ws": "^8.20.0",
|
|
100
|
-
"xlsx": "^0.18.5",
|
|
101
|
-
"zod": "^3.25.76"
|
|
102
|
-
},
|
|
103
|
-
"optionalDependencies": {
|
|
104
|
-
"sharp": "^0.34.5"
|
|
105
|
-
},
|
|
106
|
-
"devDependencies": {
|
|
107
|
-
"@types/chrome-remote-interface": "^0.33.0",
|
|
108
|
-
"@types/cors": "^2.8.19",
|
|
109
|
-
"@types/express": "^4.17.25",
|
|
110
|
-
"@types/node": "^22.10.0",
|
|
111
|
-
"@types/pdf-parse": "^1.1.4",
|
|
112
|
-
"@types/proper-lockfile": "^4.1.4",
|
|
113
|
-
"@types/ws": "^8.18.1",
|
|
114
|
-
"esbuild": "^0.28.0",
|
|
115
|
-
"tsx": "^4.19.2",
|
|
116
|
-
"typescript": "^6.0.3"
|
|
117
|
-
}
|
|
118
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@weavetab/mcp",
|
|
3
|
+
"version": "2.5.1",
|
|
4
|
+
"description": "The open automation engine for AI agents. Control live browsers and desktop apps locally with instant execution.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "fy2ne",
|
|
7
|
+
"email": "hello@fy2ne.me",
|
|
8
|
+
"url": "https://fy2ne.me"
|
|
9
|
+
},
|
|
10
|
+
"license": "AGPL-3.0-only",
|
|
11
|
+
"homepage": "https://github.com/Weavetab/mcp",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/Weavetab/mcp.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/Weavetab/mcp/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp server",
|
|
21
|
+
"mcp",
|
|
22
|
+
"model context protocol",
|
|
23
|
+
"browser automation",
|
|
24
|
+
"electron automation",
|
|
25
|
+
"desktop automation",
|
|
26
|
+
"ai agent",
|
|
27
|
+
"claude mcp",
|
|
28
|
+
"cursor mcp",
|
|
29
|
+
"cdp",
|
|
30
|
+
"chrome devtools protocol",
|
|
31
|
+
"local mcp",
|
|
32
|
+
"Weavetab",
|
|
33
|
+
"Weavetab MCP",
|
|
34
|
+
"@weavetab/mcp",
|
|
35
|
+
"puppeteer alternative",
|
|
36
|
+
"playwright alternative",
|
|
37
|
+
"autonomous agent"
|
|
38
|
+
],
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": "^20.19.0 || ^22.12.0 || >=23"
|
|
41
|
+
},
|
|
42
|
+
"type": "module",
|
|
43
|
+
"main": "./dist/index.js",
|
|
44
|
+
"bin": {
|
|
45
|
+
"weavetab": "dist/index.js"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"mcpName": "dev.weavetab/mcp",
|
|
51
|
+
"files": [
|
|
52
|
+
"dist/",
|
|
53
|
+
"!dist/**/*.map",
|
|
54
|
+
"!dist/**/*.tsbuildinfo",
|
|
55
|
+
"ext-dist/",
|
|
56
|
+
"!ext-dist/**/src/**",
|
|
57
|
+
"!ext-dist/**/*.ts",
|
|
58
|
+
"docs/",
|
|
59
|
+
"mcp.json",
|
|
60
|
+
"server.json",
|
|
61
|
+
"smithery.yaml",
|
|
62
|
+
"AGENTS.md",
|
|
63
|
+
"SECURITY.md",
|
|
64
|
+
"TROUBLESHOOTING.md",
|
|
65
|
+
"ARCHITECTURE.md",
|
|
66
|
+
"icon.png",
|
|
67
|
+
"LICENSE",
|
|
68
|
+
"README.md"
|
|
69
|
+
],
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "node scripts/build.js",
|
|
72
|
+
"build:hud": "node scripts/build-hud.js",
|
|
73
|
+
"build:ext": "node scripts/build-ext.js",
|
|
74
|
+
"docs:generate": "node scripts/generate-docs.js",
|
|
75
|
+
"verify:versions": "node scripts/verify-versions.js",
|
|
76
|
+
"verify:package": "node scripts/verify-package.js",
|
|
77
|
+
"verify": "npm run verify:versions && npm run verify:package",
|
|
78
|
+
"dev": "tsx src/index.ts",
|
|
79
|
+
"start": "node dist/index.js",
|
|
80
|
+
"prepublishOnly": "npm run verify && npm run build",
|
|
81
|
+
"test": "npm run test:unit",
|
|
82
|
+
"test:unit": "node --import tsx/esm --test \"tests/unit/cache.test.ts\" \"tests/unit/delta.test.ts\" \"tests/unit/sessionMemory.test.ts\" \"tests/unit/site_memory.test.ts\" \"tests/unit/trail.test.ts\" \"tests/unit/walker.test.ts\" \"tests/unit/burst.test.ts\" \"tests/unit/navigate.test.ts\" \"tests/unit/select.test.ts\" \"tests/unit/design_extract.test.ts\" \"tests/unit/plugin.test.ts\" \"tests/unit/plugin_lifecycle.test.ts\" \"tests/unit/plugin_interceptors.test.ts\" \"tests/unit/electron.test.ts\" \"tests/unit/stale_ref_recovery.test.ts\" \"tests/unit/secret_containment.test.ts\" \"tests/unit/checkpoint.test.ts\" \"tests/unit/marks.test.ts\" \"tests/unit/highlight.test.ts\"",
|
|
83
|
+
"test:e2e": "tsx tests/e2e/smoke_test.ts"
|
|
84
|
+
},
|
|
85
|
+
"dependencies": {
|
|
86
|
+
"@clack/prompts": "^1.3.0",
|
|
87
|
+
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
88
|
+
"boxen": "^8.0.1",
|
|
89
|
+
"chalk": "^5.6.2",
|
|
90
|
+
"chrome-remote-interface": "^0.33.2",
|
|
91
|
+
"clipboardy": "^5.3.1",
|
|
92
|
+
"csv-parse": "^5.5.0",
|
|
93
|
+
"mammoth": "^1.6.0",
|
|
94
|
+
"open": "^11.0.0",
|
|
95
|
+
"ora": "^9.4.0",
|
|
96
|
+
"pdf-parse": "^1.1.1",
|
|
97
|
+
"picocolors": "^1.1.1",
|
|
98
|
+
"proper-lockfile": "^4.1.2",
|
|
99
|
+
"ws": "^8.20.0",
|
|
100
|
+
"xlsx": "^0.18.5",
|
|
101
|
+
"zod": "^3.25.76"
|
|
102
|
+
},
|
|
103
|
+
"optionalDependencies": {
|
|
104
|
+
"sharp": "^0.34.5"
|
|
105
|
+
},
|
|
106
|
+
"devDependencies": {
|
|
107
|
+
"@types/chrome-remote-interface": "^0.33.0",
|
|
108
|
+
"@types/cors": "^2.8.19",
|
|
109
|
+
"@types/express": "^4.17.25",
|
|
110
|
+
"@types/node": "^22.10.0",
|
|
111
|
+
"@types/pdf-parse": "^1.1.4",
|
|
112
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
113
|
+
"@types/ws": "^8.18.1",
|
|
114
|
+
"esbuild": "^0.28.0",
|
|
115
|
+
"tsx": "^4.19.2",
|
|
116
|
+
"typescript": "^6.0.3"
|
|
117
|
+
}
|
|
118
|
+
}
|
package/server.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
-
"name": "dev.weavetab/mcp",
|
|
4
|
-
"title": "Weavetab",
|
|
5
|
-
"description": "Open automation engine for AI agents. Control live browsers and desktop apps locally.",
|
|
6
|
-
"repository": {
|
|
7
|
-
"url": "https://github.com/Weavetab/mcp",
|
|
8
|
-
"source": "github"
|
|
9
|
-
},
|
|
10
|
-
"version": "2.5.
|
|
11
|
-
"packages": [
|
|
12
|
-
{
|
|
13
|
-
"registryType": "npm",
|
|
14
|
-
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
|
-
"identifier": "@weavetab/mcp",
|
|
16
|
-
"version": "2.5.
|
|
17
|
-
"transport": {
|
|
18
|
-
"type": "stdio"
|
|
19
|
-
},
|
|
20
|
-
"environmentVariables": []
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "dev.weavetab/mcp",
|
|
4
|
+
"title": "Weavetab",
|
|
5
|
+
"description": "Open automation engine for AI agents. Control live browsers and desktop apps locally.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"url": "https://github.com/Weavetab/mcp",
|
|
8
|
+
"source": "github"
|
|
9
|
+
},
|
|
10
|
+
"version": "2.5.1",
|
|
11
|
+
"packages": [
|
|
12
|
+
{
|
|
13
|
+
"registryType": "npm",
|
|
14
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
|
+
"identifier": "@weavetab/mcp",
|
|
16
|
+
"version": "2.5.1",
|
|
17
|
+
"transport": {
|
|
18
|
+
"type": "stdio"
|
|
19
|
+
},
|
|
20
|
+
"environmentVariables": []
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
package/dist/cdp/walker.test.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* walker.test.ts — Phase 1.1
|
|
3
|
-
* Unit tests for walker.ts utility functions (no CDP session needed).
|
|
4
|
-
* buildActionMap and buildAXTreeMap require live browser — not tested here.
|
|
5
|
-
*/
|
|
6
|
-
import { test } from "node:test";
|
|
7
|
-
import assert from "node:assert/strict";
|
|
8
|
-
import { toRefEntries, findAllMatches, findBestMatch, toMarkdownTable, safeSelector, clearViewportCache, setShadowDomCache, clearShadowDomCache, clearAXTreeCache, resetFallbackIdCounter as resetIdCounter, } from "./walker.js";
|
|
9
|
-
function makeEl(overrides = {}) {
|
|
10
|
-
return {
|
|
11
|
-
id: "w:1",
|
|
12
|
-
role: "button",
|
|
13
|
-
label: "Submit",
|
|
14
|
-
group: "form",
|
|
15
|
-
fingerprint: "button:submit:form:1",
|
|
16
|
-
depth: 0,
|
|
17
|
-
...overrides,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
test("toRefEntries: converts ActionElements to RefEntries", () => {
|
|
21
|
-
const els = [
|
|
22
|
-
makeEl({ id: "w:1", label: "Sign In", role: "button", type: "submit", fingerprint: "a" }),
|
|
23
|
-
makeEl({ id: "w:2", label: "Email", role: "textbox", type: "email", fingerprint: "b" }),
|
|
24
|
-
];
|
|
25
|
-
const refs = toRefEntries(els);
|
|
26
|
-
assert.equal(refs.length, 2);
|
|
27
|
-
assert.equal(refs[0].id, "w:1");
|
|
28
|
-
assert.equal(refs[0].label, "Sign In");
|
|
29
|
-
assert.equal(refs[0].type, "submit");
|
|
30
|
-
assert.equal(refs[0].disabled, false);
|
|
31
|
-
assert.equal(refs[1].id, "w:2");
|
|
32
|
-
});
|
|
33
|
-
test("toRefEntries: empty array returns empty", () => {
|
|
34
|
-
assert.deepEqual(toRefEntries([]), []);
|
|
35
|
-
});
|
|
36
|
-
test("findAllMatches: exact label match", () => {
|
|
37
|
-
const els = [
|
|
38
|
-
makeEl({ id: "w:1", label: "Sign In" }),
|
|
39
|
-
makeEl({ id: "w:2", label: "Sign Out" }),
|
|
40
|
-
makeEl({ id: "w:3", label: "Email" }),
|
|
41
|
-
];
|
|
42
|
-
const matches = findAllMatches(els, "Sign In");
|
|
43
|
-
assert.equal(matches.length, 1);
|
|
44
|
-
assert.equal(matches[0].id, "w:1");
|
|
45
|
-
});
|
|
46
|
-
test("findAllMatches: partial label match", () => {
|
|
47
|
-
const els = [
|
|
48
|
-
makeEl({ id: "w:1", label: "Sign In" }),
|
|
49
|
-
makeEl({ id: "w:2", label: "Sign Out" }),
|
|
50
|
-
makeEl({ id: "w:3", label: "Email" }),
|
|
51
|
-
];
|
|
52
|
-
const matches = findAllMatches(els, "Sign");
|
|
53
|
-
assert.equal(matches.length, 2);
|
|
54
|
-
assert.ok(matches.find(m => m.id === "w:1"));
|
|
55
|
-
assert.ok(matches.find(m => m.id === "w:2"));
|
|
56
|
-
});
|
|
57
|
-
test("findAllMatches: case insensitive", () => {
|
|
58
|
-
const els = [makeEl({ id: "w:1", label: "SIGN IN" })];
|
|
59
|
-
const matches = findAllMatches(els, "sign in");
|
|
60
|
-
assert.equal(matches.length, 1);
|
|
61
|
-
});
|
|
62
|
-
test("findAllMatches: placeholder match", () => {
|
|
63
|
-
const els = [makeEl({ id: "w:1", label: "", placeholder: "Enter name" })];
|
|
64
|
-
const matches = findAllMatches(els, "Enter name");
|
|
65
|
-
assert.equal(matches.length, 1);
|
|
66
|
-
assert.equal(matches[0].id, "w:1");
|
|
67
|
-
});
|
|
68
|
-
test("findAllMatches: empty query returns empty", () => {
|
|
69
|
-
const els = [makeEl({ id: "w:1", label: "Submit" })];
|
|
70
|
-
assert.deepEqual(findAllMatches(els, ""), []);
|
|
71
|
-
assert.deepEqual(findAllMatches(els, " "), []);
|
|
72
|
-
assert.deepEqual(findAllMatches(els, "\t"), []);
|
|
73
|
-
});
|
|
74
|
-
test("findAllMatches: fuzzy multi-word match", () => {
|
|
75
|
-
const els = [
|
|
76
|
-
makeEl({ id: "w:1", label: "Create New Account" }),
|
|
77
|
-
makeEl({ id: "w:2", label: "Create Post" }),
|
|
78
|
-
];
|
|
79
|
-
const matches = findAllMatches(els, "Create Account");
|
|
80
|
-
assert.equal(matches.length, 1);
|
|
81
|
-
assert.equal(matches[0].id, "w:1");
|
|
82
|
-
});
|
|
83
|
-
test("findAllMatches: returns unique elements only", () => {
|
|
84
|
-
const els = [makeEl({ id: "w:1", label: "Submit" })];
|
|
85
|
-
// label and type both match "Submit"
|
|
86
|
-
const matches = findAllMatches(els, "Submit");
|
|
87
|
-
assert.equal(matches.length, 1);
|
|
88
|
-
});
|
|
89
|
-
test("findBestMatch: returns first match", () => {
|
|
90
|
-
const els = [
|
|
91
|
-
makeEl({ id: "w:1", label: "Sign In" }),
|
|
92
|
-
makeEl({ id: "w:2", label: "Sign Out" }),
|
|
93
|
-
];
|
|
94
|
-
const best = findBestMatch(els, "Sign");
|
|
95
|
-
assert.ok(best);
|
|
96
|
-
assert.equal(best.id, "w:1");
|
|
97
|
-
});
|
|
98
|
-
test("findBestMatch: undefined on no match", () => {
|
|
99
|
-
assert.equal(findBestMatch([], "nonexistent"), undefined);
|
|
100
|
-
});
|
|
101
|
-
test("toMarkdownTable: basic formatting", () => {
|
|
102
|
-
const els = [
|
|
103
|
-
makeEl({ id: "w:1", label: "Submit", role: "button", depth: 0 }),
|
|
104
|
-
makeEl({ id: "w:2", label: "Email", role: "textbox", depth: 0 }),
|
|
105
|
-
];
|
|
106
|
-
const md = toMarkdownTable(els, "https://example.com", "Test Page");
|
|
107
|
-
assert.ok(md.includes("https://example.com"));
|
|
108
|
-
assert.ok(md.includes("Test Page"));
|
|
109
|
-
assert.ok(md.includes("Submit"));
|
|
110
|
-
assert.ok(md.includes("Email"));
|
|
111
|
-
assert.ok(md.includes("(Btn)"));
|
|
112
|
-
assert.ok(md.includes("(Input)"));
|
|
113
|
-
});
|
|
114
|
-
test("toMarkdownTable: respects depth indentation", () => {
|
|
115
|
-
const els = [
|
|
116
|
-
makeEl({ id: "w:1", label: "Root", role: "button", depth: 0 }),
|
|
117
|
-
makeEl({ id: "w:2", label: "Child", role: "textbox", depth: 1 }),
|
|
118
|
-
];
|
|
119
|
-
const md = toMarkdownTable(els, "https://x.com", "X");
|
|
120
|
-
// child should be indented
|
|
121
|
-
const lines = md.split("\n");
|
|
122
|
-
const childLine = lines.find(l => l.includes("Child"));
|
|
123
|
-
assert.ok(childLine, "Child line should exist");
|
|
124
|
-
assert.ok(childLine.startsWith(" "), "Child should be indented");
|
|
125
|
-
});
|
|
126
|
-
test("toMarkdownTable: strips non-interactive elements without label", () => {
|
|
127
|
-
const els = [
|
|
128
|
-
makeEl({ id: "", label: "", role: "generic", depth: 0 }),
|
|
129
|
-
makeEl({ id: "w:1", label: "Real", role: "button", depth: 0 }),
|
|
130
|
-
];
|
|
131
|
-
const md = toMarkdownTable(els, "https://x.com", "X");
|
|
132
|
-
assert.ok(!md.includes("generic"), "Empty generic should be stripped");
|
|
133
|
-
assert.ok(md.includes("Real"));
|
|
134
|
-
});
|
|
135
|
-
test("safeSelector: returns selector when present", () => {
|
|
136
|
-
const el = makeEl({ selector: "#submit-btn" });
|
|
137
|
-
assert.equal(safeSelector(el), "#submit-btn");
|
|
138
|
-
});
|
|
139
|
-
test("safeSelector: returns undefined when no selector", () => {
|
|
140
|
-
assert.equal(safeSelector(makeEl()), undefined);
|
|
141
|
-
});
|
|
142
|
-
test("safeSelector: returns undefined on undefined input", () => {
|
|
143
|
-
assert.equal(safeSelector(undefined), undefined);
|
|
144
|
-
});
|
|
145
|
-
test("clearViewportCache: no-op smoke test", () => {
|
|
146
|
-
clearViewportCache("test-target");
|
|
147
|
-
assert.ok(true, "clearViewportCache should not throw");
|
|
148
|
-
});
|
|
149
|
-
test("resetFallbackIdCounter: no-op smoke test", () => {
|
|
150
|
-
resetIdCounter();
|
|
151
|
-
assert.ok(true, "resetFallbackIdCounter should not throw");
|
|
152
|
-
});
|
|
153
|
-
test("shadowDomCache: set and clear", () => {
|
|
154
|
-
setShadowDomCache("target-a", true);
|
|
155
|
-
setShadowDomCache("target-b", false);
|
|
156
|
-
clearShadowDomCache("target-a");
|
|
157
|
-
clearShadowDomCache("target-b");
|
|
158
|
-
assert.ok(true, "shadowDomCache should not throw");
|
|
159
|
-
});
|
|
160
|
-
test("clearAXTreeCache: no-op smoke test", () => {
|
|
161
|
-
clearAXTreeCache("any-target");
|
|
162
|
-
assert.ok(true, "clearAXTreeCache should not throw");
|
|
163
|
-
});
|
|
164
|
-
test("findAllMatches: type match fallback", () => {
|
|
165
|
-
const els = [
|
|
166
|
-
makeEl({ id: "w:1", label: "", type: "checkbox" }),
|
|
167
|
-
makeEl({ id: "w:2", label: "Checkbox", type: "text" }),
|
|
168
|
-
];
|
|
169
|
-
const matches = findAllMatches(els, "checkbox");
|
|
170
|
-
assert.equal(matches.length, 2);
|
|
171
|
-
});
|
|
172
|
-
//# sourceMappingURL=walker.test.js.map
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sessionMemory.test.ts — Phase 1.1
|
|
3
|
-
* Integrated into node:test runner (npm test / npm run test:unit).
|
|
4
|
-
* Previously a manual runTests() script; ported to node:test format.
|
|
5
|
-
*/
|
|
6
|
-
import { test, before, after } from "node:test";
|
|
7
|
-
import assert from "node:assert/strict";
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
import path from "path";
|
|
10
|
-
import { getBestSelectorForIntent, logMemorySuccess, logMemoryFailure, loadDomainProfile, } from "./sessionMemory.js";
|
|
11
|
-
import { getSystemDir } from "../config/loader.js";
|
|
12
|
-
const hostname = "test.weavetab.dev";
|
|
13
|
-
let profilePath;
|
|
14
|
-
before(() => {
|
|
15
|
-
const memoryDir = getSystemDir("memory");
|
|
16
|
-
profilePath = path.join(memoryDir, `${hostname}.json`);
|
|
17
|
-
if (fs.existsSync(profilePath))
|
|
18
|
-
fs.unlinkSync(profilePath);
|
|
19
|
-
});
|
|
20
|
-
after(() => {
|
|
21
|
-
if (fs.existsSync(profilePath))
|
|
22
|
-
fs.unlinkSync(profilePath);
|
|
23
|
-
});
|
|
24
|
-
test("1: Initial success log — selector is immediately retrievable", async () => {
|
|
25
|
-
await logMemorySuccess(hostname, "Click Login", ".login-btn", { role: "button", tag: "button" });
|
|
26
|
-
const sel = await getBestSelectorForIntent(hostname, "Click Login");
|
|
27
|
-
assert.equal(sel?.selector, ".login-btn", `Expected .login-btn, got ${sel?.selector}`);
|
|
28
|
-
});
|
|
29
|
-
test("2: Dead selector (first strike) — score drops below threshold", async () => {
|
|
30
|
-
// Simulate visit count increment
|
|
31
|
-
const profile = await loadDomainProfile(hostname);
|
|
32
|
-
profile.visitCount++;
|
|
33
|
-
fs.writeFileSync(profilePath, JSON.stringify(profile, null, 2));
|
|
34
|
-
await logMemoryFailure(hostname, "Click Login", ".login-btn", "DEAD_SELECTOR");
|
|
35
|
-
const sel = await getBestSelectorForIntent(hostname, "Click Login");
|
|
36
|
-
assert.equal(sel, undefined, "Expected undefined — score dropped below 0.5 threshold after one failure");
|
|
37
|
-
});
|
|
38
|
-
test("3: Dead selector recovery — new successful selector wins", async () => {
|
|
39
|
-
await logMemorySuccess(hostname, "Click Login", "#login-new", { role: "button", tag: "button" });
|
|
40
|
-
const sel = await getBestSelectorForIntent(hostname, "Click Login");
|
|
41
|
-
assert.equal(sel?.selector, "#login-new", `Expected #login-new, got ${sel?.selector}`);
|
|
42
|
-
});
|
|
43
|
-
test("4: Decay check — both old and new memory entries exist in profile", async () => {
|
|
44
|
-
const profile = await loadDomainProfile(hostname);
|
|
45
|
-
const oldMem = profile.memories.find(m => m.selector === ".login-btn");
|
|
46
|
-
const newMem = profile.memories.find(m => m.selector === "#login-new");
|
|
47
|
-
assert.ok(oldMem !== undefined, "Expected old memory (.login-btn) to still exist");
|
|
48
|
-
assert.ok(newMem !== undefined, "Expected new memory (#login-new) to exist");
|
|
49
|
-
});
|
|
50
|
-
test("5: Negative memory expiration — both selectors decay below threshold after many visits", async () => {
|
|
51
|
-
const profile = await loadDomainProfile(hostname);
|
|
52
|
-
const inFailed = profile.failedSelectors.find(f => f.selector === ".login-btn");
|
|
53
|
-
assert.ok(inFailed !== undefined, "Expected .login-btn in failedSelectors after DEAD_SELECTOR strike");
|
|
54
|
-
// Advance visits far past expiration window (expiration = visitCount + 10).
|
|
55
|
-
// After +15 visits, DecayFactor drops to ~0.25, pulling #login-new below 0.5 threshold too.
|
|
56
|
-
profile.visitCount += 15;
|
|
57
|
-
fs.writeFileSync(profilePath, JSON.stringify(profile, null, 2));
|
|
58
|
-
// Both selectors are now expired / decayed — correct behavior is a miss (force DOM re-resolution)
|
|
59
|
-
const sel = await getBestSelectorForIntent(hostname, "Click Login");
|
|
60
|
-
assert.equal(sel, undefined, "Expected undefined after extreme visit-count decay — selectors should re-confirm via DOM");
|
|
61
|
-
});
|
|
62
|
-
//# sourceMappingURL=sessionMemory.test.js.map
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* trail.test.ts — Phase 1.1
|
|
3
|
-
* Unit tests for the Phase 0.1 fix: resetLoopCounter must NOT wipe the trail,
|
|
4
|
-
* loop detection must respect timestamp-based reset boundaries.
|
|
5
|
-
*/
|
|
6
|
-
import { test } from "node:test";
|
|
7
|
-
import assert from "node:assert/strict";
|
|
8
|
-
import { recordAction, getTrail, clearTrail, getLoopDiagnostics, detectLoop, resetLoopCounter, resetLoopCounterForRef, } from "./trail.js";
|
|
9
|
-
// Helper: record N consecutive failures for a given tool+ref
|
|
10
|
-
function recordFailures(tool, ref, count) {
|
|
11
|
-
for (let i = 0; i < count; i++) {
|
|
12
|
-
recordAction({
|
|
13
|
-
timestamp: new Date().toISOString(),
|
|
14
|
-
tool,
|
|
15
|
-
input: { ref },
|
|
16
|
-
result: { success: false, stuck: true },
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// Helper: record one success
|
|
21
|
-
function recordSuccess(tool, ref) {
|
|
22
|
-
recordAction({
|
|
23
|
-
timestamp: new Date().toISOString(),
|
|
24
|
-
tool,
|
|
25
|
-
input: { ref },
|
|
26
|
-
result: { success: true, stuck: false },
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
test("trail: recordAction appends entries", () => {
|
|
30
|
-
clearTrail();
|
|
31
|
-
recordSuccess("browser_click", "w:1");
|
|
32
|
-
assert.equal(getTrail().length, 1);
|
|
33
|
-
clearTrail();
|
|
34
|
-
});
|
|
35
|
-
test("loop: no warning below threshold (< 5 strikes)", () => {
|
|
36
|
-
clearTrail();
|
|
37
|
-
recordFailures("browser_click", "w:99", 4);
|
|
38
|
-
const diag = getLoopDiagnostics("browser_click", "w:99");
|
|
39
|
-
assert.equal(diag.severity, "none", `Expected none at 4 strikes, got ${diag.severity}`);
|
|
40
|
-
clearTrail();
|
|
41
|
-
});
|
|
42
|
-
test("loop: warning fires at ≥ 5 strikes (half of LOOP_LIMIT=10)", () => {
|
|
43
|
-
clearTrail();
|
|
44
|
-
recordFailures("browser_click", "w:99", 5);
|
|
45
|
-
const diag = getLoopDiagnostics("browser_click", "w:99");
|
|
46
|
-
assert.equal(diag.severity, "warning", `Expected warning at 5 strikes, got ${diag.severity}`);
|
|
47
|
-
clearTrail();
|
|
48
|
-
});
|
|
49
|
-
test("loop: critical fires at ≥ 10 strikes", () => {
|
|
50
|
-
clearTrail();
|
|
51
|
-
recordFailures("browser_click", "w:99", 10);
|
|
52
|
-
const diag = getLoopDiagnostics("browser_click", "w:99");
|
|
53
|
-
assert.equal(diag.severity, "critical", `Expected critical at 10 strikes, got ${diag.severity}`);
|
|
54
|
-
clearTrail();
|
|
55
|
-
});
|
|
56
|
-
test("loop: success resets the consecutive strike count", () => {
|
|
57
|
-
clearTrail();
|
|
58
|
-
recordFailures("browser_click", "w:5", 6);
|
|
59
|
-
recordSuccess("browser_click", "w:5"); // interrupts the consecutive run
|
|
60
|
-
const diag = getLoopDiagnostics("browser_click", "w:5");
|
|
61
|
-
assert.equal(diag.strikes, 0, `Expected 0 strikes after success, got ${diag.strikes}`);
|
|
62
|
-
clearTrail();
|
|
63
|
-
});
|
|
64
|
-
test("Phase 0.1: resetLoopCounter preserves trail history", () => {
|
|
65
|
-
clearTrail();
|
|
66
|
-
recordSuccess("browser_click", "w:1");
|
|
67
|
-
recordSuccess("browser_type", "w:2");
|
|
68
|
-
const countBefore = getTrail().length;
|
|
69
|
-
assert.equal(countBefore, 2);
|
|
70
|
-
resetLoopCounter("test");
|
|
71
|
-
// Trail must still have the same entries — history is preserved
|
|
72
|
-
const countAfter = getTrail().length;
|
|
73
|
-
assert.equal(countAfter, 2, `Trail should still have 2 entries after resetLoopCounter, got ${countAfter}`);
|
|
74
|
-
clearTrail();
|
|
75
|
-
});
|
|
76
|
-
test("Phase 0.1: resetLoopCounter clears strikes without wiping trail", () => {
|
|
77
|
-
clearTrail();
|
|
78
|
-
recordFailures("browser_click", "w:7", 10);
|
|
79
|
-
const before = getLoopDiagnostics("browser_click", "w:7");
|
|
80
|
-
assert.equal(before.severity, "critical");
|
|
81
|
-
resetLoopCounter("test");
|
|
82
|
-
// New failures recorded AFTER reset should count fresh
|
|
83
|
-
recordFailures("browser_click", "w:7", 2);
|
|
84
|
-
const after = getLoopDiagnostics("browser_click", "w:7");
|
|
85
|
-
// Trail still has 12 entries but only 2 are after the reset boundary
|
|
86
|
-
assert.equal(after.strikes, 2, `Expected 2 strikes post-reset, got ${after.strikes}`);
|
|
87
|
-
assert.equal(after.severity, "none", `Expected none at 2 strikes post-reset, got ${after.severity}`);
|
|
88
|
-
clearTrail();
|
|
89
|
-
});
|
|
90
|
-
test("Phase 0.1: resetLoopCounterForRef only affects that ref", () => {
|
|
91
|
-
clearTrail();
|
|
92
|
-
recordFailures("browser_click", "w:A", 10); // critical
|
|
93
|
-
recordFailures("browser_click", "w:B", 10); // critical
|
|
94
|
-
resetLoopCounterForRef("browser_click", "w:A");
|
|
95
|
-
const diagA = getLoopDiagnostics("browser_click", "w:A");
|
|
96
|
-
const diagB = getLoopDiagnostics("browser_click", "w:B");
|
|
97
|
-
assert.equal(diagA.strikes, 0, `w:A should have 0 strikes after per-ref reset, got ${diagA.strikes}`);
|
|
98
|
-
assert.equal(diagB.severity, "critical", `w:B should still be critical, got ${diagB.severity}`);
|
|
99
|
-
clearTrail();
|
|
100
|
-
});
|
|
101
|
-
test("Phase 0.1: detectLoop returns false after resetLoopCounter", () => {
|
|
102
|
-
clearTrail();
|
|
103
|
-
recordFailures("browser_click", "w:X", 10);
|
|
104
|
-
assert.equal(detectLoop("browser_click", "w:X"), true, "Expected loop before reset");
|
|
105
|
-
resetLoopCounter("test");
|
|
106
|
-
recordFailures("browser_click", "w:X", 3); // not enough for loop after reset
|
|
107
|
-
assert.equal(detectLoop("browser_click", "w:X"), false, "Expected no loop after reset with only 3 new strikes");
|
|
108
|
-
clearTrail();
|
|
109
|
-
});
|
|
110
|
-
//# sourceMappingURL=trail.test.js.map
|