@weavetab/mcp 2.5.0-beta.0 → 2.5.0-beta.2
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 +1 -0
- package/LICENSE +2 -2
- package/README.md +208 -43
- package/SECURITY.md +3 -3
- package/TROUBLESHOOTING.md +1 -1
- package/dist/cdp/bridge.d.ts +10 -0
- package/dist/cdp/bridge.js +288 -68
- package/dist/cdp/connector.d.ts +5 -3
- package/dist/cdp/connector.js +188 -74
- package/dist/cdp/extension.js +0 -1
- package/dist/cdp/helpers.js +0 -2
- package/dist/cdp/lock.d.ts +9 -6
- package/dist/cdp/lock.js +72 -59
- package/dist/cdp/omni_broker.d.ts +1 -0
- package/dist/cdp/omni_broker.js +12 -6
- package/dist/cdp/profiles.d.ts +10 -0
- package/dist/cdp/profiles.js +65 -0
- package/dist/cdp/walker.js +50 -0
- package/dist/cli/plugin.d.ts +0 -2
- package/dist/cli/plugin.js +31 -683
- package/dist/cli/updater.js +2 -2
- package/dist/config/loader.d.ts +25 -6
- package/dist/config/loader.js +133 -20
- package/dist/index.js +48 -52
- package/dist/lifecycle/mission_manager.d.ts +0 -1
- package/dist/lifecycle/mission_manager.js +0 -3
- package/dist/overlay/ghost.d.ts +4 -0
- package/dist/overlay/ghost.js +118 -94
- package/dist/overlay/injector.d.ts +1 -1
- package/dist/overlay/injector.js +1 -15
- package/dist/plugin/extension_bridge.d.ts +40 -0
- package/dist/plugin/extension_bridge.js +158 -0
- package/dist/plugin/interface.d.ts +78 -16
- package/dist/plugin/loader.d.ts +4 -0
- package/dist/plugin/loader.js +178 -57
- package/dist/plugin/registry.js +11 -1
- package/dist/plugin/storage.d.ts +51 -0
- package/dist/plugin/storage.js +164 -0
- package/dist/server.js +217 -151
- package/dist/state/session.d.ts +2 -2
- package/dist/state/session.js +33 -13
- package/dist/tools/browser_detect.d.ts +2 -1
- package/dist/tools/browser_detect.js +6 -5
- package/dist/tools/burst.d.ts +1 -0
- package/dist/tools/burst.js +4 -6
- package/dist/tools/click.js +23 -28
- package/dist/tools/clipboard.js +31 -24
- package/dist/tools/navigate.d.ts +1 -1
- package/dist/tools/navigate.js +28 -10
- package/dist/tools/read.js +1 -1
- package/dist/tools/tabs.d.ts +10 -10
- package/dist/tools/tabs.js +47 -39
- package/dist/tools/type.js +2 -2
- package/docs/DOCUMENTATION.md +63 -6
- package/docs/architecture/blind-injection.md +20 -0
- package/docs/architecture/dual-injection.md +32 -0
- package/docs/architecture/overview.md +49 -0
- package/docs/architecture/security.md +35 -0
- package/docs/architecture/transport.md +37 -0
- package/docs/captcha-stealth/captcha-solver.md +75 -0
- package/docs/captcha-stealth/stealth-physics.md +60 -0
- package/docs/cli/cli-commands.md +44 -0
- package/docs/cli/cli-flags.md +20 -0
- package/docs/cli/cli-introduction.md +20 -0
- package/docs/cli/cli-scripting.md +32 -0
- package/docs/cli/g-ide/ide-antigravity.md +24 -0
- package/docs/cli/g-ide/ide-claude-code.md +24 -0
- package/docs/cli/g-ide/ide-claude-desktop.md +32 -0
- package/docs/cli/g-ide/ide-cursor.md +31 -0
- package/docs/cli/g-ide/ide-generic.md +34 -0
- package/docs/cli/g-ide/ide-opencode.md +24 -0
- package/docs/cli/g-ide/ide-vscode-copilot.md +24 -0
- package/docs/cli/g-ide/ide-windsurf.md +24 -0
- package/docs/configuration/config-locations.md +24 -0
- package/docs/configuration/configuration.md +73 -0
- package/docs/configuration/env-variables.md +19 -0
- package/docs/configuration/folders.md +54 -0
- package/docs/desktop-automation/electron-apps.md +162 -0
- package/docs/get-started/installation.md +47 -0
- package/docs/get-started/introduction.md +60 -0
- package/docs/get-started/quickstart.md +54 -0
- package/docs/get-started/setup-wizard.md +26 -0
- package/docs/skills-ecosystem/skills-overview.md +35 -0
- package/docs/skills-ecosystem/skills-recipes.md +36 -0
- package/docs/tools/tools.md +293 -0
- package/docs/troubleshooting/trouble-browser.md +27 -0
- package/docs/troubleshooting/trouble-config.md +20 -0
- package/docs/troubleshooting/trouble-loop.md +31 -0
- package/ext-dist/content.js +126 -101
- package/mcp.json +8 -15
- package/package.json +11 -5
- package/server.json +3 -3
- package/dist/tools/plan.d.ts +0 -39
- package/dist/tools/plan.js +0 -161
- package/docs/DEV_MODE.md +0 -68
- package/docs/PLUGINS.md +0 -538
- package/docs/TOOLS.md +0 -104
- package/docs/dev_plugin.md +0 -310
package/dist/cli/updater.js
CHANGED
|
@@ -52,7 +52,7 @@ async function printUpdateBox(current, latest) {
|
|
|
52
52
|
chalk.bold(`Update available! `) + chalk.dim(current) + chalk.reset(` → `) + chalk.green(latest),
|
|
53
53
|
`Run ${chalk.cyan("npm i -g @weavetab/mcp")} to update.`,
|
|
54
54
|
``,
|
|
55
|
-
`Changelog: ${chalk.blue(`https://
|
|
55
|
+
`Changelog: ${chalk.blue(`https://github.com/weavetab/mcp/changelog/v${latest}`)}`
|
|
56
56
|
].join("\n");
|
|
57
57
|
const box = boxen(msg, {
|
|
58
58
|
padding: 1,
|
|
@@ -67,6 +67,6 @@ async function printUpdateBox(current, latest) {
|
|
|
67
67
|
// Fallback if formatting fails
|
|
68
68
|
console.error(`\n[Weavetab MCP] Update available: ${current} -> ${latest}`);
|
|
69
69
|
console.error(`Run "npm i -g @weavetab/mcp" to update.`);
|
|
70
|
-
console.error(`Changelog: https://
|
|
70
|
+
console.error(`Changelog: https://github.com/weavetab/mcp/changelog/v${latest}\n`);
|
|
71
71
|
}
|
|
72
72
|
}
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -6,6 +6,13 @@ export interface PolicyEntry {
|
|
|
6
6
|
pattern: string;
|
|
7
7
|
mode: PolicyMode;
|
|
8
8
|
}
|
|
9
|
+
export interface ElectronAppConfig {
|
|
10
|
+
path?: string;
|
|
11
|
+
port?: number;
|
|
12
|
+
url?: string;
|
|
13
|
+
args?: string[];
|
|
14
|
+
profileDir?: string;
|
|
15
|
+
}
|
|
9
16
|
export interface Config {
|
|
10
17
|
mode: "session" | "attach";
|
|
11
18
|
session: string;
|
|
@@ -15,13 +22,13 @@ export interface Config {
|
|
|
15
22
|
browserPath: string;
|
|
16
23
|
browserType: BrowserEngine;
|
|
17
24
|
headless: boolean;
|
|
18
|
-
|
|
19
|
-
darkMode: boolean;
|
|
20
|
-
disableExtensions: boolean;
|
|
25
|
+
extension: boolean;
|
|
21
26
|
browserFlags: string[];
|
|
22
27
|
profileDir: string;
|
|
23
28
|
cookies: boolean;
|
|
24
29
|
syncDataAcrossBrowsers: boolean;
|
|
30
|
+
apps?: Record<string, ElectronAppConfig>;
|
|
31
|
+
electron?: Record<string, ElectronAppConfig>;
|
|
25
32
|
role: Role;
|
|
26
33
|
block: string[];
|
|
27
34
|
allow: string[];
|
|
@@ -48,6 +55,11 @@ export declare const GLOBAL_CONFIG_PATH: string;
|
|
|
48
55
|
export declare const DEFAULT_CONFIG: Config;
|
|
49
56
|
export type OnConfigChange = (newConfig: Config) => void;
|
|
50
57
|
export declare function onConfigChange(cb: OnConfigChange): void;
|
|
58
|
+
/**
|
|
59
|
+
* Migrates old sectioned config to new simplified flat format.
|
|
60
|
+
*/
|
|
61
|
+
export declare function migrateToSimple(sectioned: any): Config;
|
|
62
|
+
export declare function validateConfigInternal(raw: Record<string, unknown>): Config;
|
|
51
63
|
/**
|
|
52
64
|
* Priority: Global (user) → Built-in defaults
|
|
53
65
|
*
|
|
@@ -87,9 +99,7 @@ export declare function getConfigTelemetry(config: Config): boolean;
|
|
|
87
99
|
export declare function getConfigBrowserPath(config: Config): string;
|
|
88
100
|
export declare function getConfigBrowserType(config: Config): BrowserEngine;
|
|
89
101
|
export declare function getConfigHeadless(config: Config): boolean;
|
|
90
|
-
export declare function
|
|
91
|
-
export declare function getConfigDarkMode(config: Config): boolean;
|
|
92
|
-
export declare function getConfigDisableExtensions(config: Config): boolean;
|
|
102
|
+
export declare function getConfigExtension(config: Config): boolean;
|
|
93
103
|
export declare function getConfigBrowserFlags(config: Config): string[];
|
|
94
104
|
export declare function getConfigProfileDir(config: Config): string;
|
|
95
105
|
export declare function getConfigCookies(config: Config): boolean;
|
|
@@ -108,10 +118,19 @@ export declare function getConfigActionabilityTimeoutMs(config: Config): number;
|
|
|
108
118
|
export declare function getConfigGithubCacheTtl(config: Config): number;
|
|
109
119
|
export declare function getConfigRefCacheTtl(config: Config): number;
|
|
110
120
|
export declare function getConfigDevMode(config: Config): boolean;
|
|
121
|
+
export declare function getConfigApps(config: Config): Record<string, ElectronAppConfig> | undefined;
|
|
122
|
+
export declare function getConfigElectron(config: Config): Record<string, ElectronAppConfig> | undefined;
|
|
123
|
+
export declare function getAppConfig(appName: string, config?: Config): ElectronAppConfig | null;
|
|
124
|
+
export declare function getElectronAppConfig(appName: string, config?: Config): ElectronAppConfig | null;
|
|
125
|
+
export declare function getAppNames(config?: Config): string[];
|
|
126
|
+
export declare function getElectronAppNames(config?: Config): string[];
|
|
127
|
+
export declare function getApps(config?: Config): Record<string, ElectronAppConfig>;
|
|
128
|
+
export declare function getElectronApps(config?: Config): Record<string, ElectronAppConfig>;
|
|
111
129
|
export declare function getConfigNavigationTimeoutMs(config: Config): number;
|
|
112
130
|
export declare function getConfigGithubCacheTtlMs(config: Config): number;
|
|
113
131
|
export declare function getConfigRefCacheTtlMs(config: Config): number;
|
|
114
132
|
export declare function getSystemDir(subdir: string): string;
|
|
133
|
+
export declare function getSystemAppDir(appName: string): string;
|
|
115
134
|
/**
|
|
116
135
|
* Returns a directory inside the global ~/.weavetab-system/ folder.
|
|
117
136
|
* Alias for consistency — identical to getSystemDir.
|
package/dist/config/loader.js
CHANGED
|
@@ -30,13 +30,13 @@ export const DEFAULT_CONFIG = {
|
|
|
30
30
|
browserPath: "auto",
|
|
31
31
|
browserType: "chromium",
|
|
32
32
|
headless: false,
|
|
33
|
-
|
|
34
|
-
darkMode: true,
|
|
35
|
-
disableExtensions: false,
|
|
33
|
+
extension: true,
|
|
36
34
|
browserFlags: [],
|
|
37
35
|
profileDir: "",
|
|
38
36
|
cookies: false,
|
|
39
37
|
syncDataAcrossBrowsers: false,
|
|
38
|
+
apps: undefined,
|
|
39
|
+
electron: undefined,
|
|
40
40
|
role: "admin",
|
|
41
41
|
block: ["*.bank.*", "paypal.com"],
|
|
42
42
|
allow: [],
|
|
@@ -77,7 +77,7 @@ function isSectionedConfig(raw) {
|
|
|
77
77
|
/**
|
|
78
78
|
* Migrates old sectioned config to new simplified flat format.
|
|
79
79
|
*/
|
|
80
|
-
function migrateToSimple(sectioned) {
|
|
80
|
+
export function migrateToSimple(sectioned) {
|
|
81
81
|
return {
|
|
82
82
|
mode: sectioned.general?.mode || "session",
|
|
83
83
|
session: sectioned.general?.session || "default",
|
|
@@ -87,12 +87,12 @@ function migrateToSimple(sectioned) {
|
|
|
87
87
|
browserPath: sectioned.browser?.path || "auto",
|
|
88
88
|
browserType: sectioned.browser?.type || "chromium",
|
|
89
89
|
headless: sectioned.browser?.headless ?? false,
|
|
90
|
-
|
|
91
|
-
darkMode: sectioned.browser?.darkMode ?? true,
|
|
92
|
-
disableExtensions: sectioned.browser?.disableExtensions || false,
|
|
90
|
+
extension: sectioned.browser?.extension ?? sectioned.browser?.visuals ?? true,
|
|
93
91
|
browserFlags: sectioned.browser?.flags || [],
|
|
94
92
|
profileDir: sectioned.browser?.profileDir || "",
|
|
95
93
|
cookies: sectioned.browser?.cookies || false,
|
|
94
|
+
apps: sectioned.apps || sectioned.electron || undefined,
|
|
95
|
+
electron: sectioned.apps || sectioned.electron || undefined,
|
|
96
96
|
role: sectioned.security?.role || "admin",
|
|
97
97
|
block: sectioned.security?.block || ["*.bank.*", "paypal.com"],
|
|
98
98
|
allow: sectioned.security?.allow || [],
|
|
@@ -149,7 +149,7 @@ function validateConfig(raw) {
|
|
|
149
149
|
// Validate simplified config
|
|
150
150
|
return validateConfigInternal(raw);
|
|
151
151
|
}
|
|
152
|
-
function validateConfigInternal(raw) {
|
|
152
|
+
export function validateConfigInternal(raw) {
|
|
153
153
|
const d = DEFAULT_CONFIG;
|
|
154
154
|
const VALID_MODES = ["session", "attach"];
|
|
155
155
|
const VALID_ENGINES = ["chromium", "firefox", "webkit"];
|
|
@@ -205,6 +205,83 @@ function validateConfigInternal(raw) {
|
|
|
205
205
|
logDebug(`[Weavetab Config] [WARN] Proxy contains literal credentials (://user:pass@). This is a security risk. Use an environment variable instead. Ignoring proxy.`);
|
|
206
206
|
proxy = undefined;
|
|
207
207
|
}
|
|
208
|
+
// Validate apps / electron apps mapping
|
|
209
|
+
let electron = undefined;
|
|
210
|
+
const rawApps = raw.apps || raw.electron;
|
|
211
|
+
if (rawApps && typeof rawApps === "object" && !Array.isArray(rawApps)) {
|
|
212
|
+
const rawMap = rawApps;
|
|
213
|
+
const validatedMap = {};
|
|
214
|
+
for (const [rawKey, rawVal] of Object.entries(rawMap)) {
|
|
215
|
+
const sanitizedKey = rawKey.trim();
|
|
216
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(sanitizedKey)) {
|
|
217
|
+
logDebug(`[Weavetab Config] [WARN] Invalid app name "${rawKey}". Must be alphanumeric, dashes, or underscores.`);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (typeof rawVal === "string") {
|
|
221
|
+
const strVal = rawVal.trim();
|
|
222
|
+
if (/^\d+$/.test(strVal)) {
|
|
223
|
+
const portNum = parseInt(strVal, 10);
|
|
224
|
+
if (portNum > 0 && portNum <= 65535) {
|
|
225
|
+
validatedMap[sanitizedKey] = { port: portNum };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else if (strVal.startsWith("http://") || strVal.startsWith("https://") || strVal.startsWith("ws://") || strVal.startsWith("wss://")) {
|
|
229
|
+
const cfg = { url: strVal };
|
|
230
|
+
try {
|
|
231
|
+
const parsedUrl = new URL(strVal);
|
|
232
|
+
if (parsedUrl.port) {
|
|
233
|
+
const p = parseInt(parsedUrl.port, 10);
|
|
234
|
+
if (p > 0 && p <= 65535)
|
|
235
|
+
cfg.port = p;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch { /* ignore */ }
|
|
239
|
+
validatedMap[sanitizedKey] = cfg;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
const safePath = safePathField(`apps.${sanitizedKey}`, strVal);
|
|
243
|
+
if (safePath) {
|
|
244
|
+
validatedMap[sanitizedKey] = { path: safePath };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (typeof rawVal === "number" && Number.isFinite(rawVal) && rawVal > 0 && rawVal <= 65535) {
|
|
249
|
+
validatedMap[sanitizedKey] = { port: rawVal };
|
|
250
|
+
}
|
|
251
|
+
else if (typeof rawVal === "object" && rawVal !== null && !Array.isArray(rawVal)) {
|
|
252
|
+
const objVal = rawVal;
|
|
253
|
+
const appCfg = {};
|
|
254
|
+
if (typeof objVal.path === "string" && objVal.path.trim()) {
|
|
255
|
+
const safePath = safePathField(`apps.${sanitizedKey}.path`, objVal.path);
|
|
256
|
+
if (safePath)
|
|
257
|
+
appCfg.path = safePath;
|
|
258
|
+
}
|
|
259
|
+
if (typeof objVal.port === "number" && Number.isFinite(objVal.port) && objVal.port > 0 && objVal.port <= 65535) {
|
|
260
|
+
appCfg.port = objVal.port;
|
|
261
|
+
}
|
|
262
|
+
else if (typeof objVal.port === "string" && /^\d+$/.test(objVal.port.trim())) {
|
|
263
|
+
const p = parseInt(objVal.port.trim(), 10);
|
|
264
|
+
if (p > 0 && p <= 65535)
|
|
265
|
+
appCfg.port = p;
|
|
266
|
+
}
|
|
267
|
+
if (typeof objVal.url === "string" && objVal.url.trim()) {
|
|
268
|
+
appCfg.url = objVal.url.trim();
|
|
269
|
+
}
|
|
270
|
+
if (Array.isArray(objVal.args)) {
|
|
271
|
+
appCfg.args = objVal.args.filter(isStr);
|
|
272
|
+
}
|
|
273
|
+
if (typeof objVal.profileDir === "string" && objVal.profileDir.trim()) {
|
|
274
|
+
appCfg.profileDir = safePathField(`apps.${sanitizedKey}.profileDir`, objVal.profileDir);
|
|
275
|
+
}
|
|
276
|
+
if (appCfg.path || appCfg.port || appCfg.url) {
|
|
277
|
+
validatedMap[sanitizedKey] = appCfg;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (Object.keys(validatedMap).length > 0) {
|
|
282
|
+
electron = validatedMap;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
208
285
|
return {
|
|
209
286
|
mode,
|
|
210
287
|
session: validateField("session", raw.session, isStr, d.session),
|
|
@@ -214,12 +291,12 @@ function validateConfigInternal(raw) {
|
|
|
214
291
|
browserPath,
|
|
215
292
|
browserType: validateField("browserType", raw.browserType, isStr, d.browserType, v => VALID_ENGINES.includes(v)),
|
|
216
293
|
headless: validateField("headless", raw.headless, isBool, d.headless),
|
|
217
|
-
|
|
218
|
-
darkMode: validateField("darkMode", raw.darkMode, isBool, d.darkMode),
|
|
219
|
-
disableExtensions: validateField("disableExtensions", raw.disableExtensions, isBool, d.disableExtensions),
|
|
294
|
+
extension: validateField("extension", raw.extension, isBool, d.extension),
|
|
220
295
|
browserFlags: isArr(raw.browserFlags) ? raw.browserFlags.filter(isStr) : d.browserFlags,
|
|
221
296
|
profileDir,
|
|
222
297
|
cookies: validateField("cookies", raw.cookies, isBool, d.cookies),
|
|
298
|
+
apps: electron,
|
|
299
|
+
electron,
|
|
223
300
|
role: validateField("role", raw.role, isStr, d.role, v => VALID_ROLES.includes(v)),
|
|
224
301
|
block: isArr(raw.block) ? raw.block.filter(isStr) : d.block,
|
|
225
302
|
allow: isArr(raw.allow) ? raw.allow.filter(isStr) : d.allow,
|
|
@@ -345,7 +422,7 @@ function resolveConfigMerge() {
|
|
|
345
422
|
logDebug(`[Weavetab Config] [OK] Active directory: ${activeDir}`);
|
|
346
423
|
}
|
|
347
424
|
else {
|
|
348
|
-
logDebug(`[Weavetab Config] [WARN] No config found — using built-in defaults. Run:
|
|
425
|
+
logDebug(`[Weavetab Config] [WARN] No config found — using built-in defaults. Run: weavetab config`);
|
|
349
426
|
logDebug(`[Weavetab Config] [OK] Active directory: ${activeDir}`);
|
|
350
427
|
// Write a starter global config so user isn't surprised
|
|
351
428
|
ensureConfigDir(globalDir);
|
|
@@ -551,14 +628,8 @@ export function getConfigBrowserType(config) {
|
|
|
551
628
|
export function getConfigHeadless(config) {
|
|
552
629
|
return config.headless;
|
|
553
630
|
}
|
|
554
|
-
export function
|
|
555
|
-
return config.
|
|
556
|
-
}
|
|
557
|
-
export function getConfigDarkMode(config) {
|
|
558
|
-
return config.darkMode;
|
|
559
|
-
}
|
|
560
|
-
export function getConfigDisableExtensions(config) {
|
|
561
|
-
return config.disableExtensions;
|
|
631
|
+
export function getConfigExtension(config) {
|
|
632
|
+
return config.extension !== false;
|
|
562
633
|
}
|
|
563
634
|
export function getConfigBrowserFlags(config) {
|
|
564
635
|
return config.browserFlags;
|
|
@@ -614,6 +685,40 @@ export function getConfigRefCacheTtl(config) {
|
|
|
614
685
|
export function getConfigDevMode(config) {
|
|
615
686
|
return config.devMode;
|
|
616
687
|
}
|
|
688
|
+
export function getConfigApps(config) {
|
|
689
|
+
return config.apps || config.electron;
|
|
690
|
+
}
|
|
691
|
+
export function getConfigElectron(config) {
|
|
692
|
+
return config.apps || config.electron;
|
|
693
|
+
}
|
|
694
|
+
export function getAppConfig(appName, config) {
|
|
695
|
+
const cfg = config ?? getCachedConfig();
|
|
696
|
+
const map = cfg.apps || cfg.electron;
|
|
697
|
+
if (!map)
|
|
698
|
+
return null;
|
|
699
|
+
const sanitized = appName.trim();
|
|
700
|
+
return map[sanitized] || null;
|
|
701
|
+
}
|
|
702
|
+
export function getElectronAppConfig(appName, config) {
|
|
703
|
+
return getAppConfig(appName, config);
|
|
704
|
+
}
|
|
705
|
+
export function getAppNames(config) {
|
|
706
|
+
const cfg = config ?? getCachedConfig();
|
|
707
|
+
const map = cfg.apps || cfg.electron;
|
|
708
|
+
if (!map)
|
|
709
|
+
return [];
|
|
710
|
+
return Object.keys(map);
|
|
711
|
+
}
|
|
712
|
+
export function getElectronAppNames(config) {
|
|
713
|
+
return getAppNames(config);
|
|
714
|
+
}
|
|
715
|
+
export function getApps(config) {
|
|
716
|
+
const cfg = config ?? getCachedConfig();
|
|
717
|
+
return cfg.apps || cfg.electron || {};
|
|
718
|
+
}
|
|
719
|
+
export function getElectronApps(config) {
|
|
720
|
+
return getApps(config);
|
|
721
|
+
}
|
|
617
722
|
// ─── Additional Helper Functions for Code Compatibility ─────────────────────────
|
|
618
723
|
export function getConfigNavigationTimeoutMs(config) {
|
|
619
724
|
return config.navigationTimeout;
|
|
@@ -637,6 +742,14 @@ export function getSystemDir(subdir) {
|
|
|
637
742
|
}
|
|
638
743
|
return dir;
|
|
639
744
|
}
|
|
745
|
+
export function getSystemAppDir(appName) {
|
|
746
|
+
const sanitized = appName.trim().replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
747
|
+
const dir = path.join(GLOBAL_SYSTEM_DIR, "apps", sanitized);
|
|
748
|
+
if (!fs.existsSync(dir)) {
|
|
749
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
750
|
+
}
|
|
751
|
+
return dir;
|
|
752
|
+
}
|
|
640
753
|
/**
|
|
641
754
|
* Returns a directory inside the global ~/.weavetab-system/ folder.
|
|
642
755
|
* Alias for consistency — identical to getSystemDir.
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// src/index.ts — Weavetab V3 CLI entrypoint
|
|
3
3
|
import { assertNotRoot } from "./security/guard.js";
|
|
4
|
-
import { loadConfig, saveConfig, getCachedConfig, GLOBAL_CONFIG_PATH, GLOBAL_CONFIG_DIR, getConfigMode, getConfigAttachPort, getConfigBrowserType, getConfigBrowserPath, getConfigRole, getConfigHeadless,
|
|
4
|
+
import { loadConfig, saveConfig, getCachedConfig, GLOBAL_CONFIG_PATH, GLOBAL_CONFIG_DIR, getConfigMode, getConfigAttachPort, getConfigBrowserType, getConfigBrowserPath, getConfigRole, getConfigHeadless, getConfigExtension, getElectronApps, getConfigMaxTabs, getConfigSessionTimeout, getConfigNavigationTimeout, getConfigIdleTimeout, getConfigMaxActionsPerMinute, getConfigTelemetry, getConfigBlock, getConfigAllow, getConfigPolicies, getConfigProxy, getDownloadDir, getOutputDir, getConfigDevMode } from "./config/loader.js";
|
|
5
5
|
import { startServer } from "./server.js";
|
|
6
6
|
import { checkForUpdates } from "./cli/updater.js";
|
|
7
7
|
import fs from "node:fs";
|
|
@@ -134,14 +134,11 @@ async function main() {
|
|
|
134
134
|
await runPluginCli(args.slice(1));
|
|
135
135
|
process.exit(0);
|
|
136
136
|
}
|
|
137
|
-
if (cmd === "init" || cmd === "create") {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (cmd === "build" || cmd === "manifest") {
|
|
143
|
-
const { runPluginBuild } = await import("./cli/plugin.js");
|
|
144
|
-
await runPluginBuild(args.slice(1));
|
|
137
|
+
if (cmd === "init" || cmd === "create" || cmd === "build" || cmd === "manifest") {
|
|
138
|
+
console.log(pc.yellow(`\n[Weavetab] Plugin authoring commands are part of the developer SDK (@weavetab/sdk).`));
|
|
139
|
+
console.log(pc.dim("To scaffold a new plugin: ") + pc.cyan("npx -y @weavetab/sdk init <name>"));
|
|
140
|
+
console.log(pc.dim("To build/validate a plugin: ") + pc.cyan("npx @weavetab/sdk build"));
|
|
141
|
+
console.log(pc.dim("SDK documentation: ") + pc.cyan("https://github.com/weavetab/sdk\n"));
|
|
145
142
|
process.exit(0);
|
|
146
143
|
}
|
|
147
144
|
}
|
|
@@ -188,7 +185,7 @@ async function main() {
|
|
|
188
185
|
}
|
|
189
186
|
function generateMCPConfigEntry(configPath) {
|
|
190
187
|
const entry = {
|
|
191
|
-
command: "
|
|
188
|
+
command: "weavetab",
|
|
192
189
|
args: [],
|
|
193
190
|
env: {}
|
|
194
191
|
};
|
|
@@ -407,8 +404,8 @@ async function main() {
|
|
|
407
404
|
{ value: "webkit", label: "WebKit", hint: "Experimental" },
|
|
408
405
|
]
|
|
409
406
|
}, "browserType"),
|
|
407
|
+
S.cf("Enable Weavetab browser extension?", "extension", true),
|
|
410
408
|
S.cf("Persist cookies across sessions?", "cookies", false),
|
|
411
|
-
S.cf("Disable ALL external extensions?", "disableExtensions", false),
|
|
412
409
|
S.tx("Extra browser flags (space-separated)", "browserFlagsRaw", ""),
|
|
413
410
|
S.tx("Custom browser profile directory", "profileDir", ""),
|
|
414
411
|
])) === "back")
|
|
@@ -433,11 +430,10 @@ async function main() {
|
|
|
433
430
|
])) === "back")
|
|
434
431
|
process.exit(0);
|
|
435
432
|
}
|
|
436
|
-
// Section C: Developer &
|
|
433
|
+
// Section C: Developer & Telemetry
|
|
437
434
|
if (sectionChoice === "C") {
|
|
438
|
-
console.log(boxen(pc.cyan("SECTION C: DEVELOPER &
|
|
435
|
+
console.log(boxen(pc.cyan("SECTION C: DEVELOPER & TELEMETRY"), { padding: 1, borderStyle: 'round', borderColor: 'cyan' }));
|
|
439
436
|
if ((await run([
|
|
440
|
-
S.cf("Use dark mode theme?", "darkMode", true),
|
|
441
437
|
S.cf("Send anonymous telemetry?", "telemetry", false),
|
|
442
438
|
S.tx("GitHub cache TTL (ms)", "githubCacheTtlMs", "1800000", (v) => { const n = parseInt(v ?? ""); if (isNaN(n) || n < 0)
|
|
443
439
|
return "Positive integer."; }),
|
|
@@ -494,8 +490,8 @@ async function main() {
|
|
|
494
490
|
if (a.advanced) {
|
|
495
491
|
Object.assign(partialConfig, {
|
|
496
492
|
browserType: a.browserType || "chromium",
|
|
493
|
+
extension: a.extension !== undefined ? a.extension : true,
|
|
497
494
|
cookies: a.cookies || false,
|
|
498
|
-
disableExtensions: a.disableExtensions || false,
|
|
499
495
|
browserFlags: a.browserFlags || [],
|
|
500
496
|
profileDir: a.profileDir || "",
|
|
501
497
|
sessionTimeout: parseInt(a.sessionTimeout) || 3600,
|
|
@@ -503,7 +499,6 @@ async function main() {
|
|
|
503
499
|
idleTimeout: parseInt(a.idleTimeout) || 60000,
|
|
504
500
|
maxActionsPerMinute: parseInt(a.maxActionsPerMinute) || 60,
|
|
505
501
|
actionabilityTimeout: parseInt(a.actionabilityTimeout) || 500,
|
|
506
|
-
darkMode: a.darkMode ?? true,
|
|
507
502
|
telemetry: a.telemetry || false,
|
|
508
503
|
githubCacheTtlMs: parseInt(a.githubCacheTtlMs) || 1800000,
|
|
509
504
|
downloadDir: a.downloadDir || "",
|
|
@@ -564,7 +559,7 @@ async function main() {
|
|
|
564
559
|
if (!existingConfig.mcpServers)
|
|
565
560
|
existingConfig.mcpServers = {};
|
|
566
561
|
existingConfig.mcpServers.weavetab = {
|
|
567
|
-
command: "
|
|
562
|
+
command: "weavetab",
|
|
568
563
|
args: []
|
|
569
564
|
};
|
|
570
565
|
fs.writeFileSync(ide.configPath, JSON.stringify(existingConfig, null, 2));
|
|
@@ -580,7 +575,7 @@ async function main() {
|
|
|
580
575
|
const configSnippet = JSON.stringify({
|
|
581
576
|
mcpServers: {
|
|
582
577
|
weavetab: {
|
|
583
|
-
command: "
|
|
578
|
+
command: "weavetab",
|
|
584
579
|
args: []
|
|
585
580
|
}
|
|
586
581
|
}
|
|
@@ -604,7 +599,7 @@ async function main() {
|
|
|
604
599
|
const configSnippet = JSON.stringify({
|
|
605
600
|
mcpServers: {
|
|
606
601
|
weavetab: {
|
|
607
|
-
command: "
|
|
602
|
+
command: "weavetab",
|
|
608
603
|
args: []
|
|
609
604
|
}
|
|
610
605
|
}
|
|
@@ -632,9 +627,9 @@ async function main() {
|
|
|
632
627
|
summary.push(`${pc.dim("Allowed:")} ${a.allow.join(", ")}`);
|
|
633
628
|
p.note(summary.join("\n"), "SUMMARY");
|
|
634
629
|
if (!mcpConfigured) {
|
|
635
|
-
console.log(pc.dim("\nTo configure MCP manually, run:
|
|
630
|
+
console.log(pc.dim("\nTo configure MCP manually, run: weavetab config-mcp"));
|
|
636
631
|
}
|
|
637
|
-
p.outro(`${pc.green("Weavetab is ready!")} ${pc.dim("Run")} ${pc.cyan("
|
|
632
|
+
p.outro(`${pc.green("Weavetab is ready!")} ${pc.dim("Run")} ${pc.cyan("weavetab help")} ${pc.dim("to see available commands.")}`);
|
|
638
633
|
}
|
|
639
634
|
catch (err) {
|
|
640
635
|
s.stop(pc.red("Failed to save configuration."));
|
|
@@ -889,7 +884,7 @@ async function main() {
|
|
|
889
884
|
}
|
|
890
885
|
else {
|
|
891
886
|
resolution.push(pc.yellow("[WARNING] No config found - using built-in defaults"));
|
|
892
|
-
resolution.push(pc.dim("Run '
|
|
887
|
+
resolution.push(pc.dim("Run 'weavetab config' to create a configuration"));
|
|
893
888
|
}
|
|
894
889
|
console.log(resolution.join("\n"));
|
|
895
890
|
console.log();
|
|
@@ -902,8 +897,7 @@ async function main() {
|
|
|
902
897
|
`${pc.dim("Role:")} ${getConfigRole(config)}`,
|
|
903
898
|
`${pc.dim("Headless:")} ${getConfigHeadless(config) ? "yes" : "no"}`,
|
|
904
899
|
`${pc.dim("Dev Mode:")} ${typeof getConfigDevMode(config) === "boolean" ? (getConfigDevMode(config) ? "yes" : "no") : "advanced"}`,
|
|
905
|
-
`${pc.dim("
|
|
906
|
-
`${pc.dim("Dark Mode:")} ${getConfigDarkMode(config) ? "yes" : "no"}`,
|
|
900
|
+
`${pc.dim("Extension:")} ${getConfigExtension(config) ? "yes" : "no"}`,
|
|
907
901
|
`${pc.dim("Max Tabs:")} ${getConfigMaxTabs(config)}`,
|
|
908
902
|
`${pc.dim("Session Timeout:")} ${getConfigSessionTimeout(config)}s`,
|
|
909
903
|
`${pc.dim("Navigation Timeout:")} ${getConfigNavigationTimeout(config)}ms`,
|
|
@@ -911,6 +905,11 @@ async function main() {
|
|
|
911
905
|
`${pc.dim("Max Actions/Min:")} ${getConfigMaxActionsPerMinute(config)}`,
|
|
912
906
|
`${pc.dim("Telemetry:")} ${getConfigTelemetry(config) ? "yes" : "no"}`,
|
|
913
907
|
];
|
|
908
|
+
const electronApps = getElectronApps(config);
|
|
909
|
+
const appNames = Object.keys(electronApps);
|
|
910
|
+
if (appNames.length > 0) {
|
|
911
|
+
configLines.push(`${pc.dim("Electron Apps:")} ${appNames.join(", ")}`);
|
|
912
|
+
}
|
|
914
913
|
const blockList = getConfigBlock(config);
|
|
915
914
|
if (blockList?.length) {
|
|
916
915
|
configLines.push(`${pc.dim("Blocked Domains:")} ${blockList.join(", ")}`);
|
|
@@ -1002,7 +1001,7 @@ async function main() {
|
|
|
1002
1001
|
console.log(pc.bold("LINKS"));
|
|
1003
1002
|
console.log(` ${pc.cyan("[G]")} GitHub ${pc.dim("github.com/Weavetab")}`);
|
|
1004
1003
|
console.log(` ${pc.cyan("[N]")} NPM ${pc.dim("npmjs.com/package/Weavetab")}`);
|
|
1005
|
-
console.log(` ${pc.cyan("[W]")} Website ${pc.dim("
|
|
1004
|
+
console.log(` ${pc.cyan("[W]")} Website ${pc.dim("weavetab.pages.dev")}`);
|
|
1006
1005
|
console.log();
|
|
1007
1006
|
console.log(pc.dim("Awaiting command..."));
|
|
1008
1007
|
process.stdin.setRawMode(true);
|
|
@@ -1070,7 +1069,7 @@ async function main() {
|
|
|
1070
1069
|
await open("https://npmjs.com/package/Weavetab");
|
|
1071
1070
|
}
|
|
1072
1071
|
if (k === "w") {
|
|
1073
|
-
await open("https://
|
|
1072
|
+
await open("https://github.com/weavetab/mcp");
|
|
1074
1073
|
}
|
|
1075
1074
|
};
|
|
1076
1075
|
process.stdin.on("data", onKey);
|
|
@@ -1083,37 +1082,34 @@ async function main() {
|
|
|
1083
1082
|
console.log(pc.dim("Production-grade MCP server for Chrome DevTools Protocol"));
|
|
1084
1083
|
console.log();
|
|
1085
1084
|
console.log(pc.bold("USAGE"));
|
|
1086
|
-
console.log(` ${pc.cyan("
|
|
1085
|
+
console.log(` ${pc.cyan("weavetab <command> [options]")}`);
|
|
1087
1086
|
console.log();
|
|
1088
1087
|
console.log(pc.bold("COMMANDS"));
|
|
1089
|
-
console.log(` ${pc.cyan("
|
|
1090
|
-
console.log(` ${pc.cyan("
|
|
1091
|
-
console.log(` ${pc.cyan("plugin")} Manage Weavetab plugins (add, list, remove, verify, browse)`);
|
|
1092
|
-
console.log(` ${pc.cyan("config")} Launch the configuration wizard to configure Weavetab`);
|
|
1088
|
+
console.log(` ${pc.cyan("plugin")} Manage Weavetab plugins (add, list, remove, search, browse, verify)`);
|
|
1089
|
+
console.log(` ${pc.cyan("config")} Launch the interactive configuration wizard`);
|
|
1093
1090
|
console.log(` ${pc.cyan("view")} Display the current active configuration`);
|
|
1094
1091
|
console.log(` ${pc.cyan("reset")} Purge browser profiles, lockfiles, and orphan processes`);
|
|
1095
|
-
console.log(` ${pc.cyan("secrets")} Manage
|
|
1092
|
+
console.log(` ${pc.cyan("secrets")} Manage blind-injected credentials (set, list, rm)`);
|
|
1096
1093
|
console.log(` ${pc.cyan("reload-ext")} Send a reload signal to the browser extension`);
|
|
1097
1094
|
console.log(` ${pc.cyan("help")} Show this help message`);
|
|
1098
1095
|
console.log();
|
|
1099
|
-
console.log(pc.bold("PLUGIN
|
|
1100
|
-
console.log(` ${pc.cyan("
|
|
1101
|
-
console.log(` ${pc.cyan("
|
|
1102
|
-
console.log(` ${pc.cyan("
|
|
1096
|
+
console.log(pc.bold("PLUGIN COMMANDS (User)"));
|
|
1097
|
+
console.log(` ${pc.cyan("weavetab plugin add <pkg>")} Install a plugin (resolves official @weavetab/plugin- & community)`);
|
|
1098
|
+
console.log(` ${pc.cyan("weavetab plugin browse")} Interactive terminal explorer to browse & 1-click install`);
|
|
1099
|
+
console.log(` ${pc.cyan("weavetab plugin search <query>")} Search plugins across registry & npm`);
|
|
1100
|
+
console.log(` ${pc.cyan("weavetab plugin list")} List all installed Weavetab plugins and tools`);
|
|
1101
|
+
console.log(` ${pc.cyan("weavetab plugin remove <pkg>")} Uninstall a plugin`);
|
|
1102
|
+
console.log(` ${pc.cyan("weavetab plugin verify <pkg>")} Check trust tier against Weavetab registry`);
|
|
1103
1103
|
console.log();
|
|
1104
|
-
console.log(pc.bold("PLUGIN
|
|
1105
|
-
console.log(` ${pc.
|
|
1106
|
-
console.log(` ${pc.
|
|
1107
|
-
console.log(` ${pc.cyan("wt plugin search <query>")} Search plugins across registry & npm`);
|
|
1108
|
-
console.log(` ${pc.cyan("wt plugin list")} List all installed Weavetab plugins and tools`);
|
|
1109
|
-
console.log(` ${pc.cyan("wt plugin remove <pkg>")} Uninstall a plugin`);
|
|
1110
|
-
console.log(` ${pc.cyan("wt plugin verify <pkg>")} Check trust tier against Weavetab registry`);
|
|
1104
|
+
console.log(pc.bold("PLUGIN DEVELOPER SDK (@weavetab/sdk)"));
|
|
1105
|
+
console.log(` ${pc.dim("Scaffold a plugin:")} ${pc.cyan("npx -y @weavetab/sdk init <name>")}`);
|
|
1106
|
+
console.log(` ${pc.dim("Build & validate:")} ${pc.cyan("npx @weavetab/sdk build")}`);
|
|
1111
1107
|
console.log();
|
|
1112
1108
|
console.log(pc.bold("SECRETS SUBCOMMANDS"));
|
|
1113
|
-
console.log(` ${pc.cyan("
|
|
1114
|
-
console.log(` ${pc.cyan("
|
|
1115
|
-
console.log(` ${pc.cyan("
|
|
1116
|
-
console.log(` ${pc.cyan("
|
|
1109
|
+
console.log(` ${pc.cyan("weavetab secrets set <key>")} Store a new encrypted secret`);
|
|
1110
|
+
console.log(` ${pc.cyan("weavetab secrets list")} List all stored secrets`);
|
|
1111
|
+
console.log(` ${pc.cyan("weavetab secrets rm <key>")} Remove a secret by key`);
|
|
1112
|
+
console.log(` ${pc.cyan("weavetab secrets init --project")} Initialize project-scoped secrets`);
|
|
1117
1113
|
console.log();
|
|
1118
1114
|
console.log(pc.bold("ENVIRONMENT VARIABLES"));
|
|
1119
1115
|
console.log(` ${pc.cyan("WT_PROXY_URL")} Proxy URL (overrides config value)`);
|
|
@@ -1122,7 +1118,7 @@ async function main() {
|
|
|
1122
1118
|
console.log(pc.bold("LINKS"));
|
|
1123
1119
|
console.log(` ${pc.cyan("GitHub:")} ${pc.dim("https://github.com/Weavetab")}`);
|
|
1124
1120
|
console.log(` ${pc.cyan("npm:")} ${pc.dim("https://npmjs.com/package/Weavetab")}`);
|
|
1125
|
-
console.log(` ${pc.cyan("Website:")} ${pc.dim("https://
|
|
1121
|
+
console.log(` ${pc.cyan("Website:")} ${pc.dim("https://github.com/weavetab/mcp")}`);
|
|
1126
1122
|
console.log();
|
|
1127
1123
|
}
|
|
1128
1124
|
}
|
|
@@ -1161,7 +1157,7 @@ async function runSecretsCommand(args) {
|
|
|
1161
1157
|
const { secretStore } = await import("./security/secrets.js");
|
|
1162
1158
|
const p = await import("@clack/prompts");
|
|
1163
1159
|
if (args.length === 0) {
|
|
1164
|
-
console.log(pc.red("[ERROR] Usage:
|
|
1160
|
+
console.log(pc.red("[ERROR] Usage: weavetab secrets <set|list|rm> [key]"));
|
|
1165
1161
|
process.exit(1);
|
|
1166
1162
|
}
|
|
1167
1163
|
const subcmd = args[0].toLowerCase();
|
|
@@ -1185,7 +1181,7 @@ async function runSecretsCommand(args) {
|
|
|
1185
1181
|
if (subcmd === "rm") {
|
|
1186
1182
|
const key = args[1];
|
|
1187
1183
|
if (!key) {
|
|
1188
|
-
console.log(pc.red("[ERROR] Usage:
|
|
1184
|
+
console.log(pc.red("[ERROR] Usage: weavetab secrets rm <key>"));
|
|
1189
1185
|
process.exit(1);
|
|
1190
1186
|
}
|
|
1191
1187
|
const removed = await secretStore.removeSecret(key);
|
|
@@ -1200,7 +1196,7 @@ async function runSecretsCommand(args) {
|
|
|
1200
1196
|
if (subcmd === "set") {
|
|
1201
1197
|
const key = args[1];
|
|
1202
1198
|
if (!key) {
|
|
1203
|
-
console.log(pc.red("[ERROR] Usage:
|
|
1199
|
+
console.log(pc.red("[ERROR] Usage: weavetab secrets set <key>"));
|
|
1204
1200
|
process.exit(1);
|
|
1205
1201
|
}
|
|
1206
1202
|
console.clear();
|
|
@@ -1243,6 +1239,6 @@ async function runSecretsCommand(args) {
|
|
|
1243
1239
|
return;
|
|
1244
1240
|
}
|
|
1245
1241
|
console.log(pc.red(`[ERROR] Unknown secrets command: ${subcmd}`));
|
|
1246
|
-
console.log(pc.red("Usage:
|
|
1242
|
+
console.log(pc.red("Usage: weavetab secrets <set|list|rm> [key]"));
|
|
1247
1243
|
process.exit(1);
|
|
1248
1244
|
}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Handles suspension, hibernation, and resumption of Weavetab missions.
|
|
5
5
|
* Weavetab by fy2ne
|
|
6
6
|
*/
|
|
7
|
-
import { getActivePlan } from "../tools/plan.js";
|
|
8
7
|
import { getTabList } from "../cdp/connector.js";
|
|
9
8
|
import * as fs from "node:fs";
|
|
10
9
|
import * as path from "node:path";
|
|
@@ -17,14 +16,12 @@ export async function suspendMission(agentId, missionId) {
|
|
|
17
16
|
if (!fs.existsSync(stateDir)) {
|
|
18
17
|
fs.mkdirSync(stateDir, { recursive: true });
|
|
19
18
|
}
|
|
20
|
-
const plan = getActivePlan();
|
|
21
19
|
const tabs = await getTabList(agentId).catch(() => []);
|
|
22
20
|
const state = {
|
|
23
21
|
missionId,
|
|
24
22
|
agentId,
|
|
25
23
|
status: "suspended",
|
|
26
24
|
timestamp: Date.now(),
|
|
27
|
-
plan,
|
|
28
25
|
tabs
|
|
29
26
|
};
|
|
30
27
|
fs.writeFileSync(getMissionPath(missionId), JSON.stringify(state, null, 2));
|
package/dist/overlay/ghost.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export interface CursorOptions {
|
|
|
5
5
|
opacity?: number;
|
|
6
6
|
speed?: "human" | "fast" | "instant";
|
|
7
7
|
}
|
|
8
|
+
export declare function ensureInitialCursorPosition(session: CDP.Client): Promise<{
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}>;
|
|
8
12
|
export interface BurstProfile {
|
|
9
13
|
groupSize: [number, number];
|
|
10
14
|
interCharMin: number;
|