@weavetab/mcp 2.5.0-beta.4 → 2.5.0
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/LICENSE +212 -627
- package/README.md +25 -27
- package/dist/cdp/connector.js +2 -2
- package/dist/cli/plugin.d.ts +1 -0
- package/dist/cli/plugin.js +60 -4
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.js +1 -1
- package/dist/index.js +42 -6
- package/dist/plugin/interface.d.ts +14 -5
- package/dist/plugin/loader.d.ts +0 -3
- package/dist/plugin/loader.js +78 -15
- package/dist/plugin/registry.d.ts +2 -1
- package/dist/plugin/registry.js +21 -12
- package/dist/security/secrets.d.ts +6 -0
- package/dist/security/secrets.js +24 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +37 -34
- package/dist/tools/browser_detect.js +2 -2
- package/dist/tools/captcha.js +1 -1
- package/dist/tools/navigate.d.ts +1 -1
- package/dist/tools/navigate.js +5 -5
- package/dist/tools/tabs.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/DOCUMENTATION.md +18 -11
- package/docs/PLUGINS.md +5 -5
- package/docs/TOOLS.md +54 -56
- package/docs/architecture/overview.md +1 -1
- package/docs/architecture/security.md +36 -35
- package/docs/architecture/transport.md +37 -37
- package/docs/cli/cli-commands.md +50 -44
- package/docs/cli/cli-flags.md +28 -20
- package/docs/cli/cli-scripting.md +35 -32
- package/docs/configuration/config-locations.md +23 -24
- package/docs/configuration/env-variables.md +19 -19
- package/docs/desktop-automation/electron-apps.md +3 -6
- package/docs/get-started/introduction.md +4 -4
- package/docs/get-started/setup-wizard.md +27 -26
- package/docs/tools/tools.md +1 -1
- package/docs/troubleshooting/trouble-browser.md +27 -27
- package/icon.png +0 -0
- package/mcp.json +3 -21
- package/package.json +3 -3
- package/server.json +6 -6
- package/smithery.yaml +7 -11
|
@@ -19,7 +19,8 @@ export interface PluginCandidate {
|
|
|
19
19
|
description?: string;
|
|
20
20
|
}
|
|
21
21
|
export declare const OFFICIAL_PLUGIN_PREFIX = "@weavetab/plugin-";
|
|
22
|
-
export declare const REGISTRY_URL = "https://
|
|
22
|
+
export declare const REGISTRY_URL = "https://weavetab.dev/api/registry/verified.json";
|
|
23
|
+
export declare const REGISTRY_FALLBACK_URL = "https://raw.githubusercontent.com/weavetab/registry/main/verified.json";
|
|
23
24
|
/**
|
|
24
25
|
* Returns the set of verified package names.
|
|
25
26
|
* - Tries local registry/verified.json first (dev/test mode).
|
package/dist/plugin/registry.js
CHANGED
|
@@ -18,8 +18,9 @@ const __dirname = dirname(__filename);
|
|
|
18
18
|
// Verification Registry
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
20
|
export const OFFICIAL_PLUGIN_PREFIX = "@weavetab/plugin-";
|
|
21
|
-
// The production remote
|
|
22
|
-
export const REGISTRY_URL = "https://
|
|
21
|
+
// The production remote URLs — weavetab.dev (D1-backed) primary, GitHub raw fallback.
|
|
22
|
+
export const REGISTRY_URL = "https://weavetab.dev/api/registry/verified.json";
|
|
23
|
+
export const REGISTRY_FALLBACK_URL = "https://raw.githubusercontent.com/weavetab/registry/main/verified.json";
|
|
23
24
|
// Local override: when this file exists at the root of the repo, we use it instead
|
|
24
25
|
// of the remote URL. This allows full offline/local testing.
|
|
25
26
|
const LOCAL_REGISTRY_PATH = join(__dirname, "..", "..", "..", "registry", "verified.json");
|
|
@@ -59,16 +60,24 @@ function loadLocalRegistry() {
|
|
|
59
60
|
return null;
|
|
60
61
|
}
|
|
61
62
|
async function fetchRemoteRegistry() {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
for (const url of [REGISTRY_URL, REGISTRY_FALLBACK_URL]) {
|
|
64
|
+
try {
|
|
65
|
+
const res = await fetch(url, {
|
|
66
|
+
signal: AbortSignal.timeout(5000),
|
|
67
|
+
headers: { "User-Agent": "Weavetab-Registry-Check/1.0" },
|
|
68
|
+
});
|
|
69
|
+
if (!res.ok)
|
|
70
|
+
continue;
|
|
71
|
+
const data = await res.json();
|
|
72
|
+
if (!Array.isArray(data.verified))
|
|
73
|
+
continue;
|
|
74
|
+
return extractPackageNames(data.verified);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
throw new Error("registry fetch failed: all sources unreachable");
|
|
72
81
|
}
|
|
73
82
|
/**
|
|
74
83
|
* Returns the set of verified package names.
|
|
@@ -18,6 +18,12 @@ export interface SecretListEntry {
|
|
|
18
18
|
updatedAt: string;
|
|
19
19
|
}
|
|
20
20
|
export declare const GLOBAL_SECRETS_PATH: string;
|
|
21
|
+
export declare const PROJECT_SECRETS_DIRNAME = ".weavetab";
|
|
22
|
+
export declare const PROJECT_SECRETS_FILENAME = "secrets.json";
|
|
23
|
+
/** Absolute path of the project-scoped secrets file for a directory (default: cwd). */
|
|
24
|
+
export declare function getProjectSecretsPath(cwd?: string): string;
|
|
25
|
+
/** Creates an empty project-scoped secrets file (chmod 600). Returns its path. */
|
|
26
|
+
export declare function initProjectSecrets(cwd?: string): string;
|
|
21
27
|
declare class JsonSecretStoreImpl implements SecretProvider {
|
|
22
28
|
/**
|
|
23
29
|
* Resolve a secret value by key.
|
package/dist/security/secrets.js
CHANGED
|
@@ -86,7 +86,31 @@ function decrypt(ciphertext) {
|
|
|
86
86
|
import { GLOBAL_CONFIG_DIR } from "../config/loader.js";
|
|
87
87
|
// ─── Path resolution ──────────────────────────────────────────────────────────
|
|
88
88
|
export const GLOBAL_SECRETS_PATH = path.join(GLOBAL_CONFIG_DIR, "secrets.json");
|
|
89
|
+
export const PROJECT_SECRETS_DIRNAME = ".weavetab";
|
|
90
|
+
export const PROJECT_SECRETS_FILENAME = "secrets.json";
|
|
91
|
+
/** Absolute path of the project-scoped secrets file for a directory (default: cwd). */
|
|
92
|
+
export function getProjectSecretsPath(cwd = process.cwd()) {
|
|
93
|
+
return path.join(cwd, PROJECT_SECRETS_DIRNAME, PROJECT_SECRETS_FILENAME);
|
|
94
|
+
}
|
|
95
|
+
/** Creates an empty project-scoped secrets file (chmod 600). Returns its path. */
|
|
96
|
+
export function initProjectSecrets(cwd = process.cwd()) {
|
|
97
|
+
const filePath = getProjectSecretsPath(cwd);
|
|
98
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
99
|
+
if (!fs.existsSync(filePath)) {
|
|
100
|
+
fs.writeFileSync(filePath, JSON.stringify({ version: 1, secrets: {} }, null, 2), { mode: 0o600 });
|
|
101
|
+
}
|
|
102
|
+
return filePath;
|
|
103
|
+
}
|
|
89
104
|
function resolveSecretsPath() {
|
|
105
|
+
// Project-scoped file wins when present — lets a checkout carry its own keys.
|
|
106
|
+
try {
|
|
107
|
+
const projectPath = getProjectSecretsPath();
|
|
108
|
+
if (fs.existsSync(projectPath))
|
|
109
|
+
return projectPath;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// fall through to global
|
|
113
|
+
}
|
|
90
114
|
return GLOBAL_SECRETS_PATH;
|
|
91
115
|
}
|
|
92
116
|
// ─── Permission guard ─────────────────────────────────────────────────────────
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Weavetab — server.ts
|
|
3
|
-
* MCP server:
|
|
3
|
+
* MCP server: 42 browser automation tools with security, rate limiting, and visual overlay.
|
|
4
4
|
* Weavetab by fy2ne
|
|
5
5
|
*/
|
|
6
6
|
import type { Config } from "./config/loader.js";
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Weavetab — server.ts
|
|
3
|
-
* MCP server:
|
|
3
|
+
* MCP server: 42 browser automation tools with security, rate limiting, and visual overlay.
|
|
4
4
|
* Weavetab by fy2ne
|
|
5
5
|
*/
|
|
6
6
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -53,7 +53,7 @@ import { browserCheckpoint } from "./tools/checkpoint.js";
|
|
|
53
53
|
import { getActiveEngine } from "./cdp/connector.js";
|
|
54
54
|
import { resetLoopCounter } from "./intelligence/trail.js";
|
|
55
55
|
import { getSiteProfile, learnPattern, recordPatternExecution, recordQuirk, getPatternReliability, formatSiteProfileHint } from "./intelligence/patternCompiler.js";
|
|
56
|
-
import { discoverPlugins
|
|
56
|
+
import { discoverPlugins } from "./plugin/loader.js";
|
|
57
57
|
import { hookPipeline } from "./plugin/pipeline.js";
|
|
58
58
|
import { agentAction } from "./sensors/pacing.js";
|
|
59
59
|
import { getCachedConfig, getElectronApps } from "./config/loader.js";
|
|
@@ -1701,22 +1701,32 @@ DO NOT use browser_scrape or browser_map for binary documents — they cannot re
|
|
|
1701
1701
|
}
|
|
1702
1702
|
// 1. Tool Removals (disable built-in tools)
|
|
1703
1703
|
const manifestPerms = plugin.manifest?.permissions;
|
|
1704
|
-
const
|
|
1704
|
+
const declaredRemove = Array.isArray(manifestPerms)
|
|
1705
1705
|
? []
|
|
1706
1706
|
: manifestPerms?.tools?.remove || [];
|
|
1707
1707
|
const toRemove = [
|
|
1708
1708
|
...(plugin.removeTools || []),
|
|
1709
|
-
...manifestToolsRemove,
|
|
1710
1709
|
];
|
|
1711
1710
|
for (const toolName of toRemove) {
|
|
1711
|
+
if (!declaredRemove.includes(toolName)) {
|
|
1712
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} tried to remove "${toolName}" but it's not listed in permissions.tools.remove — skipped.\x1b[0m\n`);
|
|
1713
|
+
continue;
|
|
1714
|
+
}
|
|
1712
1715
|
if (server._registeredTools?.[toolName]) {
|
|
1713
1716
|
delete server._registeredTools[toolName];
|
|
1714
1717
|
removedNames.push(toolName);
|
|
1715
1718
|
}
|
|
1716
1719
|
}
|
|
1717
1720
|
// 2. Tool Overrides (replace or wrap built-in tools)
|
|
1721
|
+
const declaredOverride = Array.isArray(manifestPerms)
|
|
1722
|
+
? []
|
|
1723
|
+
: manifestPerms?.tools?.override || [];
|
|
1718
1724
|
const overrides = plugin.overrides || [];
|
|
1719
1725
|
for (const ov of overrides) {
|
|
1726
|
+
if (!declaredOverride.includes(ov.name)) {
|
|
1727
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} tried to override "${ov.name}" but it's not listed in permissions.tools.override — skipped.\x1b[0m\n`);
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1720
1730
|
const existingTool = server._registeredTools?.[ov.name];
|
|
1721
1731
|
const existingDesc = existingTool?.description || "";
|
|
1722
1732
|
const existingSchema = existingTool?.parameters?.shape || {};
|
|
@@ -1745,8 +1755,13 @@ DO NOT use browser_scrape or browser_map for binary documents — they cannot re
|
|
|
1745
1755
|
overriddenNames.push(ov.name);
|
|
1746
1756
|
}
|
|
1747
1757
|
// 3. Tool Additions (new tools)
|
|
1758
|
+
const canAdd = !Array.isArray(manifestPerms) && manifestPerms?.tools?.add === true;
|
|
1748
1759
|
const newTools = plugin.tools || [];
|
|
1749
1760
|
for (const td of newTools) {
|
|
1761
|
+
if (!canAdd) {
|
|
1762
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} tried to add tool "${td.name}" but permissions.tools.add is not declared — skipped.\x1b[0m\n`);
|
|
1763
|
+
continue;
|
|
1764
|
+
}
|
|
1750
1765
|
if (server._registeredTools?.[td.name]) {
|
|
1751
1766
|
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} registered tool "${td.name}" which replaced an existing tool.\x1b[0m\n`);
|
|
1752
1767
|
delete server._registeredTools[td.name];
|
|
@@ -1768,6 +1783,10 @@ DO NOT use browser_scrape or browser_map for binary documents — they cannot re
|
|
|
1768
1783
|
const fullPluginCtx = plugin._context;
|
|
1769
1784
|
if (fullPluginCtx && fullPluginCtx.mcp) {
|
|
1770
1785
|
fullPluginCtx.mcp.registerTool = (tool) => {
|
|
1786
|
+
if (!canAdd) {
|
|
1787
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} dynamic registerTool("${tool?.name}"): permissions.tools.add not declared — skipped.\x1b[0m\n`);
|
|
1788
|
+
return;
|
|
1789
|
+
}
|
|
1771
1790
|
if (server._registeredTools?.[tool.name]) {
|
|
1772
1791
|
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} dynamic tool "${tool.name}" replaced an existing tool.\x1b[0m\n`);
|
|
1773
1792
|
delete server._registeredTools[tool.name];
|
|
@@ -1780,6 +1799,10 @@ DO NOT use browser_scrape or browser_map for binary documents — they cannot re
|
|
|
1780
1799
|
});
|
|
1781
1800
|
};
|
|
1782
1801
|
fullPluginCtx.mcp.overrideTool = (toolName, overrideHandler) => {
|
|
1802
|
+
if (!declaredOverride.includes(toolName)) {
|
|
1803
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} dynamic overrideTool("${toolName}"): not in permissions.tools.override — skipped.\x1b[0m\n`);
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1783
1806
|
const existingTool = server._registeredTools?.[toolName];
|
|
1784
1807
|
if (existingTool) {
|
|
1785
1808
|
delete server._registeredTools[toolName];
|
|
@@ -1799,11 +1822,19 @@ DO NOT use browser_scrape or browser_map for binary documents — they cannot re
|
|
|
1799
1822
|
});
|
|
1800
1823
|
};
|
|
1801
1824
|
fullPluginCtx.mcp.removeTool = (toolName) => {
|
|
1825
|
+
if (!declaredRemove.includes(toolName)) {
|
|
1826
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} dynamic removeTool("${toolName}"): not in permissions.tools.remove — skipped.\x1b[0m\n`);
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1802
1829
|
if (server._registeredTools?.[toolName]) {
|
|
1803
1830
|
delete server._registeredTools[toolName];
|
|
1804
1831
|
}
|
|
1805
1832
|
};
|
|
1806
1833
|
fullPluginCtx.mcp.unregisterTool = (toolName) => {
|
|
1834
|
+
if (!declaredRemove.includes(toolName)) {
|
|
1835
|
+
process.stderr.write(` \x1b[33m[!] Plugin ${plugin.name} dynamic unregisterTool("${toolName}"): not in permissions.tools.remove — skipped.\x1b[0m\n`);
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1807
1838
|
if (server._registeredTools?.[toolName]) {
|
|
1808
1839
|
delete server._registeredTools[toolName];
|
|
1809
1840
|
}
|
|
@@ -1830,38 +1861,10 @@ DO NOT use browser_scrape or browser_map for binary documents — they cannot re
|
|
|
1830
1861
|
// Ignore if client doesn't support it or not connected yet
|
|
1831
1862
|
}
|
|
1832
1863
|
};
|
|
1833
|
-
//
|
|
1834
|
-
server.tool("list_plugins", "List all available Weavetab plugins that can be loaded.", {}, async () => {
|
|
1835
|
-
const installed = listInstalledPlugins();
|
|
1836
|
-
const available = installed
|
|
1837
|
-
.filter(info => !loadedPluginNames.has(info.packageName))
|
|
1838
|
-
.map(info => `- ${info.packageName}: ${info.manifest?.description || "No description"}`);
|
|
1839
|
-
if (available.length === 0) {
|
|
1840
|
-
return { content: [{ type: "text", text: "No un-loaded plugins available." }] };
|
|
1841
|
-
}
|
|
1842
|
-
return { content: [{ type: "text", text: `Available plugins:\n${available.join("\n")}\n\nUse load_plugin with the plugin package name to load one.` }] };
|
|
1843
|
-
});
|
|
1844
|
-
server.tool("load_plugin", "Load any Weavetab plugin dynamically by npm package name (e.g. '@fy2ne/wt-youtube', 'my-plugin').", {
|
|
1845
|
-
name: z.string().describe("The exact npm package name of the plugin to load (e.g. '@fy2ne/wt-youtube', 'my-plugin')")
|
|
1846
|
-
}, async ({ name }) => {
|
|
1847
|
-
if (loadedPluginNames.has(name)) {
|
|
1848
|
-
return { content: [{ type: "text", text: `Plugin ${name} is already loaded.` }] };
|
|
1849
|
-
}
|
|
1850
|
-
const plugin = loadPluginByName(name);
|
|
1851
|
-
if (!plugin) {
|
|
1852
|
-
return { content: [{ type: "text", text: `Plugin "${name}" not found. Make sure it is installed via "weavetab plugin add ${name}".` }] };
|
|
1853
|
-
}
|
|
1854
|
-
await registerPluginTools(plugin);
|
|
1855
|
-
const toolsList = (plugin.tools || []).map((t) => t.name).join(", ");
|
|
1856
|
-
return { content: [{ type: "text", text: `loaded plugin ${name}. Tools registered: ${toolsList || "(dynamic tools registered)"}` }] };
|
|
1857
|
-
});
|
|
1858
|
-
// Auto-load plugins by default unless explicitly marked with lazy: true
|
|
1864
|
+
// Auto-load all installed plugins at startup
|
|
1859
1865
|
const allPlugins = discoverPlugins();
|
|
1860
1866
|
for (const plugin of allPlugins) {
|
|
1861
|
-
|
|
1862
|
-
if (!isExplicitlyLazy) {
|
|
1863
|
-
await registerPluginTools(plugin);
|
|
1864
|
-
}
|
|
1867
|
+
await registerPluginTools(plugin);
|
|
1865
1868
|
}
|
|
1866
1869
|
let transport;
|
|
1867
1870
|
if (transportMode === "ws") {
|
|
@@ -10,7 +10,7 @@ const ENGINE_COVERAGE = {
|
|
|
10
10
|
"browser_network_intercept",
|
|
11
11
|
"browser_viewport",
|
|
12
12
|
"browser_recording",
|
|
13
|
-
"
|
|
13
|
+
"browser_thoughts",
|
|
14
14
|
"browser_highlight",
|
|
15
15
|
"browser_inspect",
|
|
16
16
|
"browser_snapshot",
|
|
@@ -24,7 +24,7 @@ const ENGINE_COVERAGE = {
|
|
|
24
24
|
"browser_network_intercept",
|
|
25
25
|
"browser_viewport",
|
|
26
26
|
"browser_recording",
|
|
27
|
-
"
|
|
27
|
+
"browser_thoughts",
|
|
28
28
|
"browser_highlight",
|
|
29
29
|
"browser_inspect",
|
|
30
30
|
"browser_snapshot",
|
package/dist/tools/captcha.js
CHANGED
|
@@ -111,7 +111,7 @@ export async function browserCaptcha(session, args, _config) {
|
|
|
111
111
|
user_instructions: solution.userInstructions,
|
|
112
112
|
next_action: isVisionAssisted
|
|
113
113
|
? "Take a screenshot to view the CAPTCHA, then use browser_click or browser_type to solve it yourself. Do not ask the user for help."
|
|
114
|
-
: `Call
|
|
114
|
+
: `Call browser_thoughts({ action: "question", message: "${solution.userInstructions}" }) to ask the user to complete it, then call browser_captcha({ action: "wait_for_user" }).`,
|
|
115
115
|
execution_ms: Date.now() - t0,
|
|
116
116
|
};
|
|
117
117
|
}
|
package/dist/tools/navigate.d.ts
CHANGED
package/dist/tools/navigate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Weavetab
|
|
2
|
+
* Weavetab — tools/navigate.ts
|
|
3
3
|
* URL navigation with domain blocklist enforcement and post-navigation DOM stability wait.
|
|
4
4
|
* Weavetab by fy2ne
|
|
5
5
|
*/
|
|
@@ -71,10 +71,10 @@ export async function weaveNavigate(session, url, config, targetId = "default",
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
// Extension pages: open in new tab instead of navigating current tab
|
|
74
|
-
// (chrome-extension:// pages use a different process context
|
|
74
|
+
// (chrome-extension:// pages use a different process context — Page.navigate
|
|
75
75
|
// can break the CDP session or not fire loadEventFired properly)
|
|
76
76
|
if (parsed.protocol === 'chrome-extension:') {
|
|
77
|
-
logDebug(`[weaveNavigate] Extension URL detected
|
|
77
|
+
logDebug(`[weaveNavigate] Extension URL detected — opening in new tab: ${parsed.href}`);
|
|
78
78
|
const { sendToExtension } = await import("../cdp/helpers.js");
|
|
79
79
|
await sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: `opening extension page...` } });
|
|
80
80
|
const { WeavetabOpen } = await import("./tabs.js");
|
|
@@ -98,7 +98,7 @@ export async function weaveNavigate(session, url, config, targetId = "default",
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
catch { /* overlay install is best-effort */ }
|
|
101
|
-
logAction("
|
|
101
|
+
logAction("browser_navigate", url, `opened extension tab ${openRes.tabId}`);
|
|
102
102
|
return {
|
|
103
103
|
success: true,
|
|
104
104
|
url: openRes.url,
|
|
@@ -194,7 +194,7 @@ export async function weaveNavigate(session, url, config, targetId = "default",
|
|
|
194
194
|
if (active)
|
|
195
195
|
active.url = finalUrl;
|
|
196
196
|
sendToExtension(session, { type: 'Weavetab_STATE', cursor: { x: 10, y: 10 }, state: 'idle', hud: { action: '' } }).catch(() => { });
|
|
197
|
-
logAction("
|
|
197
|
+
logAction("browser_navigate", url, `arrived at ${title}`);
|
|
198
198
|
// Bump the visit counter for this domain exactly once per navigation
|
|
199
199
|
bumpVisitCount(parsed.hostname).catch(() => { });
|
|
200
200
|
return { success: true, url: finalUrl, title, tab_id: resolvedTargetId };
|
package/dist/tools/tabs.js
CHANGED
|
@@ -17,7 +17,7 @@ function resolvePort(_config, appName) {
|
|
|
17
17
|
}
|
|
18
18
|
const port = getPort() || readLock()?.port;
|
|
19
19
|
if (!port)
|
|
20
|
-
throw new Error("[!] No active browser session. Run
|
|
20
|
+
throw new Error("[!] No active browser session. Run browser_navigate first.");
|
|
21
21
|
return port;
|
|
22
22
|
}
|
|
23
23
|
const IDLE_THRESHOLD_MS = 30_000;
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/docs/DOCUMENTATION.md
CHANGED
|
@@ -65,7 +65,7 @@ MCP Client → stdio/WebSocket → WithSecurity Pipeline → CDP WebSocket → C
|
|
|
65
65
|
|
|
66
66
|
All tools share: Zod schema validation, `withSecurity()` pipeline (rate limiting + domain policy + RBAC), structured audit logging.
|
|
67
67
|
|
|
68
|
-
### Vision & Reading (
|
|
68
|
+
### Vision & Reading (8 tools)
|
|
69
69
|
|
|
70
70
|
| Tool | Description |
|
|
71
71
|
|------|-------------|
|
|
@@ -76,6 +76,7 @@ All tools share: Zod schema validation, `withSecurity()` pipeline (rate limiting
|
|
|
76
76
|
| `browser_snapshot` | MHTML capture/restore of DOM state + resources |
|
|
77
77
|
| `browser_screenshot` | PNG/JPEG capture via CDP, full-page + clip region, returns base64 data URL (no file pollution) |
|
|
78
78
|
| `browser_console` | Read/clear buffered console logs and exceptions |
|
|
79
|
+
| `browser_extract_design` | Extract design tokens, typography, colors, and clean CSS with pixel fidelity |
|
|
79
80
|
|
|
80
81
|
### Navigation (1 tool)
|
|
81
82
|
|
|
@@ -116,14 +117,15 @@ All tools share: Zod schema validation, `withSecurity()` pipeline (rate limiting
|
|
|
116
117
|
| Tool | Description |
|
|
117
118
|
|------|-------------|
|
|
118
119
|
| `browser_dialog` | Accept/dismiss JavaScript alert/confirm/prompt dialogs |
|
|
119
|
-
| `
|
|
120
|
+
| `browser_thoughts` | Green thought bubbles: feedback (one-way) or question with input (sentence/paragraph modes) |
|
|
120
121
|
| `browser_clipboard` | System clipboard R/W (text + images) |
|
|
121
122
|
|
|
122
|
-
### Wait & Timing (
|
|
123
|
+
### Wait & Timing (2 tools)
|
|
123
124
|
|
|
124
125
|
| Tool | Description |
|
|
125
126
|
|------|-------------|
|
|
126
127
|
| `browser_wait` | Wait for element/text/URL/stable/network/auto — timeout configurable, optional loop counter reset (`reset_loop: true`) |
|
|
128
|
+
| `browser_captcha` | Autonomous zero-API detection and solving for Cloudflare Turnstile, reCAPTCHA v2/v3, GeeTest, and hCaptcha via CDP mouse physics |
|
|
127
129
|
|
|
128
130
|
### Storage & Cookies (2 tools)
|
|
129
131
|
|
|
@@ -132,11 +134,12 @@ All tools share: Zod schema validation, `withSecurity()` pipeline (rate limiting
|
|
|
132
134
|
| `browser_storage` | localStorage & sessionStorage get/set/clear |
|
|
133
135
|
| `browser_cookies` | Cookies get/set/delete |
|
|
134
136
|
|
|
135
|
-
### Device & Environment (
|
|
137
|
+
### Device & Environment (2 tools)
|
|
136
138
|
|
|
137
139
|
| Tool | Description |
|
|
138
140
|
|------|-------------|
|
|
139
141
|
| `browser_viewport` | Viewport, device emulation, geolocation, timezone override |
|
|
142
|
+
| `browser_emulate` | Network throttling (3G/4G/offline), CPU slowdown, geolocation, timezone, and User-Agent override |
|
|
140
143
|
|
|
141
144
|
### Network (1 tool)
|
|
142
145
|
|
|
@@ -176,12 +179,15 @@ All tools share: Zod schema validation, `withSecurity()` pipeline (rate limiting
|
|
|
176
179
|
|------|-------------|
|
|
177
180
|
| `browser_github` | Action-based repo metadata analysis, raw source file reading, issue triage, and PR inspection |
|
|
178
181
|
|
|
179
|
-
### Utility (
|
|
182
|
+
### Utility (5 tools)
|
|
180
183
|
|
|
181
184
|
| Tool | Description |
|
|
182
185
|
|------|-------------|
|
|
183
|
-
| `
|
|
184
|
-
|
|
|
186
|
+
| `list_plugins` | Inspect installed SDK plugins, loaded tool overrides, and capability manifests |
|
|
187
|
+
| `load_plugin` | Dynamically load a Weavetab plugin by npm package name with isolated sandboxing |
|
|
188
|
+
| `browser_checkpoint` | Snapshot and restore browser state (cookies, storage, scroll/URL) into named checkpoints for time-travel and rollback |
|
|
189
|
+
| `browser_pattern_learn` | Read, register, and update named workflow patterns and site quirks per origin |
|
|
190
|
+
| `browser_office` | Parse Word (`.docx`), Excel (`.xlsx`), PDF, and CSV files into structured data |
|
|
185
191
|
|
|
186
192
|
---
|
|
187
193
|
|
|
@@ -341,10 +347,11 @@ Configure policies directly in your config file (or via `~/.Weavetab/policy.json
|
|
|
341
347
|
|
|
342
348
|
| Role | Permissions |
|
|
343
349
|
|------|-------------|
|
|
344
|
-
| `admin` | Full access to all tools
|
|
345
|
-
| `operator` | Full
|
|
346
|
-
| `viewer` | Read-only
|
|
347
|
-
| `automation` |
|
|
350
|
+
| `admin` | Full access to all tools |
|
|
351
|
+
| `operator` | Full access to all tools (standard agent role) |
|
|
352
|
+
| `viewer` | Read-only observation tools only (`browser_map`, `browser_find`, `browser_scrape`, `browser_console`, `browser_eval`, `browser_inspect`, `browser_extract_design`, `browser_snapshot`, `browser_screenshot`, `browser_pdf`, `browser_cookies`, `browser_tabs`, `browser_wait`, `browser_pattern_learn`, `browser_github`) |
|
|
353
|
+
| `automation` | Full access except `browser_thoughts` (non-interactive CI/CD mode) |
|
|
354
|
+
| `system` | Internal tools only (`browser_thoughts`, `browser_detect`, `browser_performance`, `browser_checkpoint`, `browser_pattern_learn`) |
|
|
348
355
|
|
|
349
356
|
### Setting Role
|
|
350
357
|
|
package/docs/PLUGINS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# Weavetab Plugin System & SDK Specification
|
|
2
2
|
|
|
3
|
-
> **Version:** 2.5.0
|
|
3
|
+
> **Version:** 2.5.0 | **SDK:** @weavetab/sdk (MIT) | **Runtime:** AGPL-3.0-only
|
|
4
4
|
|
|
5
5
|
The **Weavetab Plugin System** allows developers to extend the MCP runtime with custom tools, visual HUD overlays, thought bubbles, lifecycle hooks, and tool overrides.
|
|
6
6
|
|
|
@@ -9,14 +9,14 @@ The **Weavetab Plugin System** allows developers to extend the MCP runtime with
|
|
|
9
9
|
## 1. Quick Start
|
|
10
10
|
|
|
11
11
|
### Scaffold a New Plugin
|
|
12
|
-
|
|
12
|
+
````bash
|
|
13
13
|
npx @weavetab/sdk init my-custom-plugin
|
|
14
14
|
cd my-custom-plugin
|
|
15
15
|
npm install
|
|
16
16
|
`
|
|
17
17
|
|
|
18
18
|
### Build & Compile
|
|
19
|
-
|
|
19
|
+
````bash
|
|
20
20
|
npm run build
|
|
21
21
|
`
|
|
22
22
|
|
|
@@ -104,7 +104,7 @@ Plugins require a weavetab.json manifest in their package root:
|
|
|
104
104
|
|
|
105
105
|
## 5. Installing Plugins
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
```bash
|
|
108
108
|
# Install an official plugin
|
|
109
109
|
weavetab plugin add @weavetab/plugin-youtube
|
|
110
110
|
|