@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.
Files changed (98) hide show
  1. package/AGENTS.md +1 -0
  2. package/LICENSE +2 -2
  3. package/README.md +208 -43
  4. package/SECURITY.md +3 -3
  5. package/TROUBLESHOOTING.md +1 -1
  6. package/dist/cdp/bridge.d.ts +10 -0
  7. package/dist/cdp/bridge.js +288 -68
  8. package/dist/cdp/connector.d.ts +5 -3
  9. package/dist/cdp/connector.js +188 -74
  10. package/dist/cdp/extension.js +0 -1
  11. package/dist/cdp/helpers.js +0 -2
  12. package/dist/cdp/lock.d.ts +9 -6
  13. package/dist/cdp/lock.js +72 -59
  14. package/dist/cdp/omni_broker.d.ts +1 -0
  15. package/dist/cdp/omni_broker.js +12 -6
  16. package/dist/cdp/profiles.d.ts +10 -0
  17. package/dist/cdp/profiles.js +65 -0
  18. package/dist/cdp/walker.js +50 -0
  19. package/dist/cli/plugin.d.ts +0 -2
  20. package/dist/cli/plugin.js +31 -683
  21. package/dist/cli/updater.js +2 -2
  22. package/dist/config/loader.d.ts +25 -6
  23. package/dist/config/loader.js +133 -20
  24. package/dist/index.js +48 -52
  25. package/dist/lifecycle/mission_manager.d.ts +0 -1
  26. package/dist/lifecycle/mission_manager.js +0 -3
  27. package/dist/overlay/ghost.d.ts +4 -0
  28. package/dist/overlay/ghost.js +118 -94
  29. package/dist/overlay/injector.d.ts +1 -1
  30. package/dist/overlay/injector.js +1 -15
  31. package/dist/plugin/extension_bridge.d.ts +40 -0
  32. package/dist/plugin/extension_bridge.js +158 -0
  33. package/dist/plugin/interface.d.ts +78 -16
  34. package/dist/plugin/loader.d.ts +4 -0
  35. package/dist/plugin/loader.js +178 -57
  36. package/dist/plugin/registry.js +11 -1
  37. package/dist/plugin/storage.d.ts +51 -0
  38. package/dist/plugin/storage.js +164 -0
  39. package/dist/server.js +217 -151
  40. package/dist/state/session.d.ts +2 -2
  41. package/dist/state/session.js +33 -13
  42. package/dist/tools/browser_detect.d.ts +2 -1
  43. package/dist/tools/browser_detect.js +6 -5
  44. package/dist/tools/burst.d.ts +1 -0
  45. package/dist/tools/burst.js +4 -6
  46. package/dist/tools/click.js +23 -28
  47. package/dist/tools/clipboard.js +31 -24
  48. package/dist/tools/navigate.d.ts +1 -1
  49. package/dist/tools/navigate.js +28 -10
  50. package/dist/tools/read.js +1 -1
  51. package/dist/tools/tabs.d.ts +10 -10
  52. package/dist/tools/tabs.js +47 -39
  53. package/dist/tools/type.js +2 -2
  54. package/docs/DOCUMENTATION.md +63 -6
  55. package/docs/architecture/blind-injection.md +20 -0
  56. package/docs/architecture/dual-injection.md +32 -0
  57. package/docs/architecture/overview.md +49 -0
  58. package/docs/architecture/security.md +35 -0
  59. package/docs/architecture/transport.md +37 -0
  60. package/docs/captcha-stealth/captcha-solver.md +75 -0
  61. package/docs/captcha-stealth/stealth-physics.md +60 -0
  62. package/docs/cli/cli-commands.md +44 -0
  63. package/docs/cli/cli-flags.md +20 -0
  64. package/docs/cli/cli-introduction.md +20 -0
  65. package/docs/cli/cli-scripting.md +32 -0
  66. package/docs/cli/g-ide/ide-antigravity.md +24 -0
  67. package/docs/cli/g-ide/ide-claude-code.md +24 -0
  68. package/docs/cli/g-ide/ide-claude-desktop.md +32 -0
  69. package/docs/cli/g-ide/ide-cursor.md +31 -0
  70. package/docs/cli/g-ide/ide-generic.md +34 -0
  71. package/docs/cli/g-ide/ide-opencode.md +24 -0
  72. package/docs/cli/g-ide/ide-vscode-copilot.md +24 -0
  73. package/docs/cli/g-ide/ide-windsurf.md +24 -0
  74. package/docs/configuration/config-locations.md +24 -0
  75. package/docs/configuration/configuration.md +73 -0
  76. package/docs/configuration/env-variables.md +19 -0
  77. package/docs/configuration/folders.md +54 -0
  78. package/docs/desktop-automation/electron-apps.md +162 -0
  79. package/docs/get-started/installation.md +47 -0
  80. package/docs/get-started/introduction.md +60 -0
  81. package/docs/get-started/quickstart.md +54 -0
  82. package/docs/get-started/setup-wizard.md +26 -0
  83. package/docs/skills-ecosystem/skills-overview.md +35 -0
  84. package/docs/skills-ecosystem/skills-recipes.md +36 -0
  85. package/docs/tools/tools.md +293 -0
  86. package/docs/troubleshooting/trouble-browser.md +27 -0
  87. package/docs/troubleshooting/trouble-config.md +20 -0
  88. package/docs/troubleshooting/trouble-loop.md +31 -0
  89. package/ext-dist/content.js +126 -101
  90. package/mcp.json +8 -15
  91. package/package.json +11 -5
  92. package/server.json +3 -3
  93. package/dist/tools/plan.d.ts +0 -39
  94. package/dist/tools/plan.js +0 -161
  95. package/docs/DEV_MODE.md +0 -68
  96. package/docs/PLUGINS.md +0 -538
  97. package/docs/TOOLS.md +0 -104
  98. package/docs/dev_plugin.md +0 -310
@@ -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://weavetab.dev/changelog/v${latest}`)}`
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://weavetab.dev/changelog/v${latest}\n`);
70
+ console.error(`Changelog: https://github.com/weavetab/mcp/changelog/v${latest}\n`);
71
71
  }
72
72
  }
@@ -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
- visuals: boolean;
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 getConfigVisuals(config: Config): boolean;
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.
@@ -30,13 +30,13 @@ export const DEFAULT_CONFIG = {
30
30
  browserPath: "auto",
31
31
  browserType: "chromium",
32
32
  headless: false,
33
- visuals: true,
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
- visuals: sectioned.browser?.visuals ?? true,
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
- visuals: validateField("visuals", raw.visuals, isBool, d.visuals),
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: wt config`);
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 getConfigVisuals(config) {
555
- return config.visuals;
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, getConfigVisuals, getConfigDarkMode, getConfigMaxTabs, getConfigSessionTimeout, getConfigNavigationTimeout, getConfigIdleTimeout, getConfigMaxActionsPerMinute, getConfigTelemetry, getConfigBlock, getConfigAllow, getConfigPolicies, getConfigProxy, getDownloadDir, getOutputDir, getConfigDevMode } from "./config/loader.js";
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
- const { runPluginInit } = await import("./cli/plugin.js");
139
- await runPluginInit(args.slice(1));
140
- process.exit(0);
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: "wt",
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 & Theming
433
+ // Section C: Developer & Telemetry
437
434
  if (sectionChoice === "C") {
438
- console.log(boxen(pc.cyan("SECTION C: DEVELOPER & THEMING"), { padding: 1, borderStyle: 'round', borderColor: 'cyan' }));
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: "wt",
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: "wt",
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: "wt",
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: wt config-mcp"));
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("wt help")} ${pc.dim("to see available commands.")}`);
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 'wt config' to create a configuration"));
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("Visuals:")} ${getConfigVisuals(config) ? "yes" : "no"}`,
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("Weavetab.dev")}`);
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://Weavetab.dev");
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("wt <command> [options]")}`);
1085
+ console.log(` ${pc.cyan("weavetab <command> [options]")}`);
1087
1086
  console.log();
1088
1087
  console.log(pc.bold("COMMANDS"));
1089
- console.log(` ${pc.cyan("init [name]")} Scaffold a new enterprise TypeScript Weavetab plugin`);
1090
- console.log(` ${pc.cyan("build")} Compile TypeScript plugin & sync weavetab.json manifest`);
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 encrypted credentials (set, list, rm)`);
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 DEVELOPER COMMANDS"));
1100
- console.log(` ${pc.cyan("wt init [name]")} Scaffold a new enterprise plugin with TypeScript & MCP tools`);
1101
- console.log(` ${pc.cyan("wt build")} Compile TS sources & synchronize weavetab.json`);
1102
- console.log(` ${pc.cyan("wt manifest")} Validate & update plugin weavetab.json manifest`);
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 USER COMMANDS"));
1105
- console.log(` ${pc.cyan("wt plugin add <pkg>")} Install a plugin (resolves official @weavetab/plugin- & community)`);
1106
- console.log(` ${pc.cyan("wt plugin browse")} Interactive terminal explorer to browse & 1-click install`);
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("wt secrets set <key>")} Store a new encrypted secret`);
1114
- console.log(` ${pc.cyan("wt secrets list")} List all stored secrets`);
1115
- console.log(` ${pc.cyan("wt secrets rm <key>")} Remove a secret by key`);
1116
- console.log(` ${pc.cyan("wt secrets init --project")} Initialize project-scoped secrets`);
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://Weavetab.dev")}`);
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: wt secrets <set|list|rm> [key]"));
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: wt secrets rm <key>"));
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: wt secrets set <key>"));
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: wt secrets <set|list|rm> [key]"));
1242
+ console.log(pc.red("Usage: weavetab secrets <set|list|rm> [key]"));
1247
1243
  process.exit(1);
1248
1244
  }
@@ -9,7 +9,6 @@ export interface MissionState {
9
9
  agentId: string;
10
10
  status: "active" | "suspended" | "completed";
11
11
  timestamp: number;
12
- plan: any;
13
12
  tabs: any[];
14
13
  }
15
14
  export declare function suspendMission(agentId: string, missionId: string): Promise<void>;
@@ -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));
@@ -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;