@weavetab/mcp 2.5.0-beta.1 → 2.5.0-beta.4

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 (156) hide show
  1. package/AGENTS.md +2 -1
  2. package/ARCHITECTURE.md +6 -6
  3. package/LICENSE +1 -1
  4. package/README.md +164 -802
  5. package/SECURITY.md +33 -22
  6. package/TROUBLESHOOTING.md +3 -3
  7. package/dist/cdp/bridge.d.ts +10 -0
  8. package/dist/cdp/bridge.js +285 -78
  9. package/dist/cdp/connector.d.ts +7 -3
  10. package/dist/cdp/connector.js +196 -75
  11. package/dist/cdp/helpers.d.ts +4 -0
  12. package/dist/cdp/helpers.js +181 -0
  13. package/dist/cdp/lock.d.ts +9 -6
  14. package/dist/cdp/lock.js +72 -59
  15. package/dist/cdp/omni_broker.d.ts +2 -1
  16. package/dist/cdp/omni_broker.js +13 -7
  17. package/dist/cdp/profiles.d.ts +10 -0
  18. package/dist/cdp/profiles.js +65 -0
  19. package/dist/cdp/walker.d.ts +25 -1
  20. package/dist/cdp/walker.js +354 -7
  21. package/dist/cli/plugin.d.ts +0 -2
  22. package/dist/cli/plugin.js +51 -696
  23. package/dist/cli/updater.d.ts +1 -1
  24. package/dist/cli/updater.js +27 -7
  25. package/dist/config/loader.d.ts +33 -6
  26. package/dist/config/loader.js +174 -22
  27. package/dist/desktop/discovery.d.ts +44 -0
  28. package/dist/desktop/discovery.js +364 -0
  29. package/dist/index.js +140 -64
  30. package/dist/intelligence/marks.d.ts +36 -0
  31. package/dist/intelligence/marks.js +30 -0
  32. package/dist/intelligence/patternCompiler.d.ts +118 -0
  33. package/dist/intelligence/patternCompiler.js +259 -0
  34. package/dist/intelligence/sessionMemory.d.ts +2 -0
  35. package/dist/intelligence/sessionMemory.js +18 -8
  36. package/dist/overlay/ghost.js +2 -2
  37. package/dist/overlay/injector.js +3 -5
  38. package/dist/plugin/extension_bridge.d.ts +40 -0
  39. package/dist/plugin/extension_bridge.js +158 -0
  40. package/dist/plugin/interface.d.ts +151 -15
  41. package/dist/plugin/loader.d.ts +19 -1
  42. package/dist/plugin/loader.js +331 -63
  43. package/dist/plugin/pipeline.d.ts +75 -0
  44. package/dist/plugin/pipeline.js +183 -0
  45. package/dist/plugin/registry.js +12 -1
  46. package/dist/plugin/storage.d.ts +51 -0
  47. package/dist/plugin/storage.js +164 -0
  48. package/dist/security/secrets.d.ts +1 -0
  49. package/dist/security/secrets.js +13 -0
  50. package/dist/sensors/actionability.js +1 -2
  51. package/dist/sensors/guard.js +4 -10
  52. package/dist/sensors/mutations.js +12 -0
  53. package/dist/sensors/operation_monitor.js +1 -0
  54. package/dist/server.d.ts +1 -1
  55. package/dist/server.js +600 -236
  56. package/dist/state/agent.d.ts +1 -0
  57. package/dist/state/agent.js +3 -0
  58. package/dist/state/delta.d.ts +12 -4
  59. package/dist/state/delta.js +67 -14
  60. package/dist/state/session.d.ts +8 -2
  61. package/dist/state/session.js +60 -13
  62. package/dist/tools/browser_detect.d.ts +16 -2
  63. package/dist/tools/browser_detect.js +54 -6
  64. package/dist/tools/burst.d.ts +17 -7
  65. package/dist/tools/burst.js +240 -83
  66. package/dist/tools/checkpoint.d.ts +38 -0
  67. package/dist/tools/checkpoint.js +271 -0
  68. package/dist/tools/click.d.ts +1 -0
  69. package/dist/tools/click.js +97 -98
  70. package/dist/tools/clipboard.js +31 -24
  71. package/dist/tools/design_extract.js +1 -1
  72. package/dist/tools/eval.js +1 -1
  73. package/dist/tools/fill.d.ts +20 -1
  74. package/dist/tools/fill.js +199 -40
  75. package/dist/tools/find.d.ts +16 -0
  76. package/dist/tools/find.js +67 -44
  77. package/dist/tools/github/index.d.ts +19 -4
  78. package/dist/tools/github/index.js +40 -4
  79. package/dist/tools/highlight.d.ts +6 -2
  80. package/dist/tools/highlight.js +158 -72
  81. package/dist/tools/inspect.js +1 -1
  82. package/dist/tools/key.js +65 -56
  83. package/dist/tools/navigate.d.ts +1 -1
  84. package/dist/tools/navigate.js +57 -44
  85. package/dist/tools/pdf.js +21 -13
  86. package/dist/tools/pointer.d.ts +18 -3
  87. package/dist/tools/pointer.js +89 -1
  88. package/dist/tools/read.d.ts +28 -8
  89. package/dist/tools/read.js +230 -56
  90. package/dist/tools/scrape.js +67 -13
  91. package/dist/tools/screenshot.js +21 -16
  92. package/dist/tools/scroll.js +6 -11
  93. package/dist/tools/select.js +8 -2
  94. package/dist/tools/snapshot.js +3 -34
  95. package/dist/tools/tabs.d.ts +10 -10
  96. package/dist/tools/tabs.js +55 -39
  97. package/dist/tools/thought.d.ts +2 -0
  98. package/dist/tools/thought.js +13 -14
  99. package/dist/tools/type.d.ts +2 -0
  100. package/dist/tools/type.js +109 -60
  101. package/dist/tools/type_secret.js +42 -76
  102. package/dist/tools/upload.js +1 -1
  103. package/dist/tools/video_compiler.d.ts +1 -1
  104. package/dist/tools/video_compiler.js +11 -12
  105. package/dist/version.d.ts +5 -0
  106. package/dist/version.js +5 -0
  107. package/docs/DOCUMENTATION.md +82 -36
  108. package/docs/PLUGINS.md +82 -499
  109. package/docs/TOOLS.md +51 -99
  110. package/docs/architecture/blind-injection.md +83 -0
  111. package/docs/architecture/dual-injection.md +32 -0
  112. package/docs/architecture/overview.md +49 -0
  113. package/docs/architecture/security.md +35 -0
  114. package/docs/architecture/transport.md +37 -0
  115. package/docs/captcha-stealth/captcha-solver.md +75 -0
  116. package/docs/captcha-stealth/stealth-physics.md +60 -0
  117. package/docs/cli/cli-commands.md +44 -0
  118. package/docs/cli/cli-flags.md +20 -0
  119. package/docs/cli/cli-introduction.md +20 -0
  120. package/docs/cli/cli-scripting.md +32 -0
  121. package/docs/cli/g-ide/ide-antigravity.md +24 -0
  122. package/docs/cli/g-ide/ide-claude-code.md +24 -0
  123. package/docs/cli/g-ide/ide-claude-desktop.md +32 -0
  124. package/docs/cli/g-ide/ide-cursor.md +31 -0
  125. package/docs/cli/g-ide/ide-generic.md +34 -0
  126. package/docs/cli/g-ide/ide-opencode.md +24 -0
  127. package/docs/cli/g-ide/ide-vscode-copilot.md +24 -0
  128. package/docs/cli/g-ide/ide-windsurf.md +24 -0
  129. package/docs/configuration/config-locations.md +24 -0
  130. package/docs/configuration/configuration.md +73 -0
  131. package/docs/configuration/env-variables.md +19 -0
  132. package/docs/configuration/folders.md +55 -0
  133. package/docs/desktop-automation/electron-apps.md +217 -0
  134. package/docs/get-started/installation.md +47 -0
  135. package/docs/get-started/introduction.md +60 -0
  136. package/docs/get-started/quickstart.md +54 -0
  137. package/docs/get-started/setup-wizard.md +26 -0
  138. package/docs/intelligence/site-profiles.md +151 -0
  139. package/docs/skills-ecosystem/skills-overview.md +35 -0
  140. package/docs/skills-ecosystem/skills-recipes.md +36 -0
  141. package/docs/tools/tools.md +631 -0
  142. package/docs/troubleshooting/trouble-browser.md +27 -0
  143. package/docs/troubleshooting/trouble-config.md +20 -0
  144. package/docs/troubleshooting/trouble-loop.md +31 -0
  145. package/ext-dist/background.js +10 -62
  146. package/ext-dist/content.js +333 -921
  147. package/ext-dist/hud/hud.js +9 -9
  148. package/ext-dist/manifest.json +2 -6
  149. package/ext-dist/styles.css +6 -1
  150. package/mcp.json +108 -72
  151. package/package.json +14 -9
  152. package/server.json +3 -3
  153. package/docs/DEV_MODE.md +0 -68
  154. package/docs/dev_plugin.md +0 -310
  155. package/ext-dist/sidepanel/sidepanel.js +0 -25
  156. package/ext-dist/sidepanel.html +0 -547
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";
@@ -11,6 +11,7 @@ import { createRequire } from "node:module";
11
11
  import chalk from "chalk";
12
12
  import boxen from "boxen";
13
13
  import pc from "picocolors";
14
+ import { WEAVETAB_VERSION } from "./version.js";
14
15
  // ─── Server-Process Singleton Lock ────────────────────────────────────────────
15
16
  // When an IDE opens multiple windows or reconnects after a crash, it spawns a new
16
17
  // `node dist/index.js` MCP process each time. Without a guard, these stack up
@@ -32,13 +33,29 @@ function _acquireServerLock() {
32
33
  fs.mkdirSync(_SERVER_LOCK_DIR, { recursive: true });
33
34
  if (fs.existsSync(_SERVER_LOCK_FILE)) {
34
35
  const existingPid = parseInt(fs.readFileSync(_SERVER_LOCK_FILE, "utf-8").trim(), 10);
35
- if (!isNaN(existingPid) && existingPid !== process.pid && _isProcessAlive(existingPid)) {
36
- process.stderr.write(`[Weavetab] Another Weavetab MCP server is running (PID ${existingPid}). Multiple clients active.\n`);
37
- // We no longer return false here. The analyticsInterval.unref() call
38
- // prevents zombie leaks, so it's safe to allow multiple agents (e.g.
39
- // Openchamber + Antigravity) to run their own MCP processes concurrently
40
- // and share the browser.
36
+ if (!isNaN(existingPid) && existingPid !== process.pid) {
37
+ if (_isProcessAlive(existingPid)) {
38
+ process.stderr.write(`[Weavetab] Another Weavetab MCP server is running (PID ${existingPid}). Client session active.\n`);
39
+ }
40
+ else {
41
+ // Process is dead: reap stale PID lock
42
+ try {
43
+ fs.unlinkSync(_SERVER_LOCK_FILE);
44
+ }
45
+ catch { /* ignore */ }
46
+ }
47
+ }
48
+ }
49
+ // Also reap stale browser lock file if the recorded browser PID is dead
50
+ const browserLockFile = path.join(_SERVER_LOCK_DIR, ".weavetab.lock");
51
+ if (fs.existsSync(browserLockFile)) {
52
+ try {
53
+ const lockData = JSON.parse(fs.readFileSync(browserLockFile, "utf-8"));
54
+ if (lockData.pid && !_isProcessAlive(lockData.pid)) {
55
+ fs.unlinkSync(browserLockFile);
56
+ }
41
57
  }
58
+ catch { /* malformed lock, ignore */ }
42
59
  }
43
60
  fs.writeFileSync(_SERVER_LOCK_FILE, String(process.pid), "utf-8");
44
61
  return true;
@@ -134,14 +151,22 @@ async function main() {
134
151
  await runPluginCli(args.slice(1));
135
152
  process.exit(0);
136
153
  }
137
- if (cmd === "init" || cmd === "create") {
138
- const { runPluginInit } = await import("./cli/plugin.js");
139
- await runPluginInit(args.slice(1));
154
+ if (cmd === "skills") {
155
+ const { execSync: exec } = await import("node:child_process");
156
+ const subArgs = args.slice(1).join(" ");
157
+ try {
158
+ exec(`npx -y @weavetab/skills@latest ${subArgs}`.trim(), { stdio: "inherit" });
159
+ }
160
+ catch {
161
+ process.exit(1);
162
+ }
140
163
  process.exit(0);
141
164
  }
142
- if (cmd === "build" || cmd === "manifest") {
143
- const { runPluginBuild } = await import("./cli/plugin.js");
144
- await runPluginBuild(args.slice(1));
165
+ if (cmd === "init" || cmd === "create" || cmd === "build" || cmd === "manifest") {
166
+ console.log(pc.yellow(`\n[Weavetab] Plugin authoring commands are part of the developer SDK (@weavetab/sdk).`));
167
+ console.log(pc.dim("To scaffold a new plugin: ") + pc.cyan("npx -y @weavetab/sdk init <name>"));
168
+ console.log(pc.dim("To build/validate a plugin: ") + pc.cyan("npx @weavetab/sdk build"));
169
+ console.log(pc.dim("SDK documentation: ") + pc.cyan("https://github.com/weavetab/sdk\n"));
145
170
  process.exit(0);
146
171
  }
147
172
  }
@@ -188,7 +213,7 @@ async function main() {
188
213
  }
189
214
  function generateMCPConfigEntry(configPath) {
190
215
  const entry = {
191
- command: "wt",
216
+ command: "weavetab",
192
217
  args: [],
193
218
  env: {}
194
219
  };
@@ -407,8 +432,9 @@ async function main() {
407
432
  { value: "webkit", label: "WebKit", hint: "Experimental" },
408
433
  ]
409
434
  }, "browserType"),
435
+ S.cf("Enable Weavetab browser extension?", "extension", true),
410
436
  S.cf("Persist cookies across sessions?", "cookies", false),
411
- S.cf("Disable ALL external extensions?", "disableExtensions", false),
437
+ S.cf("Sync browser data across profiles?", "syncDataAcrossBrowsers", false),
412
438
  S.tx("Extra browser flags (space-separated)", "browserFlagsRaw", ""),
413
439
  S.tx("Custom browser profile directory", "profileDir", ""),
414
440
  ])) === "back")
@@ -430,14 +456,15 @@ async function main() {
430
456
  return "Positive integer."; }),
431
457
  S.tx("Actionability timeout (ms)", "actionabilityTimeout", "500", (v) => { const n = parseInt(v ?? ""); if (isNaN(n) || n < 100)
432
458
  return "Min 100 ms."; }),
459
+ S.tx("Ref cache TTL (ms) — stale element handle expiry", "refCacheTtlMs", "30000", (v) => { const n = parseInt(v ?? ""); if (isNaN(n) || n < 1000)
460
+ return "Min 1000 ms."; }),
433
461
  ])) === "back")
434
462
  process.exit(0);
435
463
  }
436
- // Section C: Developer & Theming
464
+ // Section C: Developer & Telemetry
437
465
  if (sectionChoice === "C") {
438
- console.log(boxen(pc.cyan("SECTION C: DEVELOPER & THEMING"), { padding: 1, borderStyle: 'round', borderColor: 'cyan' }));
466
+ console.log(boxen(pc.cyan("SECTION C: DEVELOPER & TELEMETRY"), { padding: 1, borderStyle: 'round', borderColor: 'cyan' }));
439
467
  if ((await run([
440
- S.cf("Use dark mode theme?", "darkMode", true),
441
468
  S.cf("Send anonymous telemetry?", "telemetry", false),
442
469
  S.tx("GitHub cache TTL (ms)", "githubCacheTtlMs", "1800000", (v) => { const n = parseInt(v ?? ""); if (isNaN(n) || n < 0)
443
470
  return "Positive integer."; }),
@@ -449,6 +476,10 @@ async function main() {
449
476
  console.log(boxen(pc.cyan("SECTION D: STORAGE & PROXY"), { padding: 1, borderStyle: 'round', borderColor: 'cyan' }));
450
477
  if ((await run([
451
478
  S.tx("Download directory", "downloadDir", ""),
479
+ S.tx("PDF output directory", "pdfDir", ""),
480
+ S.tx("Snapshot directory (screenshots)", "snapshotDir", ""),
481
+ S.tx("Recording output directory", "recordingDir", ""),
482
+ S.tx("Design extraction directory", "designDir", ""),
452
483
  S.tx("Proxy URL (or $WT_PROXY_URL)", "proxy", ""),
453
484
  ])) === "back")
454
485
  process.exit(0);
@@ -494,8 +525,9 @@ async function main() {
494
525
  if (a.advanced) {
495
526
  Object.assign(partialConfig, {
496
527
  browserType: a.browserType || "chromium",
528
+ extension: a.extension !== undefined ? a.extension : true,
497
529
  cookies: a.cookies || false,
498
- disableExtensions: a.disableExtensions || false,
530
+ syncDataAcrossBrowsers: a.syncDataAcrossBrowsers || false,
499
531
  browserFlags: a.browserFlags || [],
500
532
  profileDir: a.profileDir || "",
501
533
  sessionTimeout: parseInt(a.sessionTimeout) || 3600,
@@ -503,10 +535,14 @@ async function main() {
503
535
  idleTimeout: parseInt(a.idleTimeout) || 60000,
504
536
  maxActionsPerMinute: parseInt(a.maxActionsPerMinute) || 60,
505
537
  actionabilityTimeout: parseInt(a.actionabilityTimeout) || 500,
506
- darkMode: a.darkMode ?? true,
538
+ refCacheTtlMs: parseInt(a.refCacheTtlMs) || 30000,
507
539
  telemetry: a.telemetry || false,
508
540
  githubCacheTtlMs: parseInt(a.githubCacheTtlMs) || 1800000,
509
541
  downloadDir: a.downloadDir || "",
542
+ pdfDir: a.pdfDir || "",
543
+ snapshotDir: a.snapshotDir || "",
544
+ recordingDir: a.recordingDir || "",
545
+ designDir: a.designDir || "",
510
546
  proxy: typeof a.proxy === "string" && a.proxy.trim() ? a.proxy.trim() : undefined,
511
547
  policies: a.policies || [],
512
548
  });
@@ -564,7 +600,7 @@ async function main() {
564
600
  if (!existingConfig.mcpServers)
565
601
  existingConfig.mcpServers = {};
566
602
  existingConfig.mcpServers.weavetab = {
567
- command: "wt",
603
+ command: "weavetab",
568
604
  args: []
569
605
  };
570
606
  fs.writeFileSync(ide.configPath, JSON.stringify(existingConfig, null, 2));
@@ -580,7 +616,7 @@ async function main() {
580
616
  const configSnippet = JSON.stringify({
581
617
  mcpServers: {
582
618
  weavetab: {
583
- command: "wt",
619
+ command: "weavetab",
584
620
  args: []
585
621
  }
586
622
  }
@@ -604,7 +640,7 @@ async function main() {
604
640
  const configSnippet = JSON.stringify({
605
641
  mcpServers: {
606
642
  weavetab: {
607
- command: "wt",
643
+ command: "weavetab",
608
644
  args: []
609
645
  }
610
646
  }
@@ -615,7 +651,40 @@ async function main() {
615
651
  mcpConfigured = true;
616
652
  }
617
653
  }
618
- // ── PHASE 5: SUMMARY ───────────────────────────────────────────────────────
654
+ // ── PHASE 5: AGENT SKILLS ────────────────────────────────────────────────────
655
+ console.log(boxen(pc.blue("PHASE 5: AGENT SKILLS"), { padding: 1, borderStyle: 'round', borderColor: 'blue' }));
656
+ let skillsInstalled = false;
657
+ const installSkillsNow = await p.confirm({
658
+ message: "Install or update Weavetab agent skills? (domain guides for your AI agent)",
659
+ initialValue: true
660
+ });
661
+ if (!p.isCancel(installSkillsNow) && installSkillsNow) {
662
+ const agentFramework = await p.select({
663
+ message: "Select your target AI agent framework:",
664
+ options: [
665
+ { value: ".agent", label: "Antigravity", hint: ".agent/skills/<domain>/SKILL.md" },
666
+ { value: ".cursor", label: "Cursor IDE", hint: ".cursor/rules/weavetab-<domain>.mdc" },
667
+ { value: ".clinerules", label: "Cline", hint: ".clinerules" },
668
+ { value: ".windsurf", label: "Windsurf", hint: ".windsurf/rules/" },
669
+ { value: ".openclaw", label: "OpenClaw", hint: ".openclaw/skills/" },
670
+ { value: ".roocode", label: "RooCode", hint: ".roocode/rules/" },
671
+ { value: "generic", label: "Raw Markdown", hint: "weavetab-skills/ directory" },
672
+ ]
673
+ });
674
+ if (!p.isCancel(agentFramework)) {
675
+ const { execSync: exec } = await import("node:child_process");
676
+ p.note(`${pc.dim("Installing skills for")} ${pc.cyan(agentFramework)} ${pc.dim("via")} ${pc.cyan("npx @weavetab/skills@latest")}...`, "SKILLS INSTALLER");
677
+ console.log();
678
+ try {
679
+ exec(`npx -y @weavetab/skills@latest --framework ${agentFramework}`, { stdio: "inherit" });
680
+ skillsInstalled = true;
681
+ }
682
+ catch {
683
+ console.log(pc.yellow(`[WARN] Skills install failed — run 'npx @weavetab/skills@latest -f ${agentFramework}' manually`));
684
+ }
685
+ }
686
+ }
687
+ // ── PHASE 6: SUMMARY ───────────────────────────────────────────────────────
619
688
  console.log(boxen(pc.green("CONFIGURATION COMPLETE"), { padding: 1, borderStyle: 'round', borderColor: 'green' }));
620
689
  const summary = [
621
690
  `${pc.dim("Browser:")} ${a.browser}`,
@@ -625,6 +694,7 @@ async function main() {
625
694
  `${pc.dim("Max tabs:")} ${partialConfig.maxTabs}`,
626
695
  `${pc.dim("Config location:")} ~/.weavetab/config.json`,
627
696
  `${pc.dim("MCP Config:")} ${mcpConfigured ? pc.green("[OK] Configured") : pc.yellow("Pending")}`,
697
+ `${pc.dim("Skills:")} ${skillsInstalled ? pc.green("[OK] Installed") : pc.dim("Skipped")}`,
628
698
  ];
629
699
  if (a.block?.length)
630
700
  summary.push(`${pc.dim("Blocked:")} ${a.block.join(", ")}`);
@@ -632,9 +702,9 @@ async function main() {
632
702
  summary.push(`${pc.dim("Allowed:")} ${a.allow.join(", ")}`);
633
703
  p.note(summary.join("\n"), "SUMMARY");
634
704
  if (!mcpConfigured) {
635
- console.log(pc.dim("\nTo configure MCP manually, run: wt config-mcp"));
705
+ console.log(pc.dim("\nTo configure MCP manually, run: weavetab config-mcp"));
636
706
  }
637
- p.outro(`${pc.green("Weavetab is ready!")} ${pc.dim("Run")} ${pc.cyan("wt help")} ${pc.dim("to see available commands.")}`);
707
+ p.outro(`${pc.green("Weavetab is ready!")} ${pc.dim("Run")} ${pc.cyan("weavetab help")} ${pc.dim("to see available commands.")}`);
638
708
  }
639
709
  catch (err) {
640
710
  s.stop(pc.red("Failed to save configuration."));
@@ -889,7 +959,7 @@ async function main() {
889
959
  }
890
960
  else {
891
961
  resolution.push(pc.yellow("[WARNING] No config found - using built-in defaults"));
892
- resolution.push(pc.dim("Run 'wt config' to create a configuration"));
962
+ resolution.push(pc.dim("Run 'weavetab config' to create a configuration"));
893
963
  }
894
964
  console.log(resolution.join("\n"));
895
965
  console.log();
@@ -902,8 +972,7 @@ async function main() {
902
972
  `${pc.dim("Role:")} ${getConfigRole(config)}`,
903
973
  `${pc.dim("Headless:")} ${getConfigHeadless(config) ? "yes" : "no"}`,
904
974
  `${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"}`,
975
+ `${pc.dim("Extension:")} ${getConfigExtension(config) ? "yes" : "no"}`,
907
976
  `${pc.dim("Max Tabs:")} ${getConfigMaxTabs(config)}`,
908
977
  `${pc.dim("Session Timeout:")} ${getConfigSessionTimeout(config)}s`,
909
978
  `${pc.dim("Navigation Timeout:")} ${getConfigNavigationTimeout(config)}ms`,
@@ -911,6 +980,11 @@ async function main() {
911
980
  `${pc.dim("Max Actions/Min:")} ${getConfigMaxActionsPerMinute(config)}`,
912
981
  `${pc.dim("Telemetry:")} ${getConfigTelemetry(config) ? "yes" : "no"}`,
913
982
  ];
983
+ const electronApps = getElectronApps(config);
984
+ const appNames = Object.keys(electronApps);
985
+ if (appNames.length > 0) {
986
+ configLines.push(`${pc.dim("Electron Apps:")} ${appNames.join(", ")}`);
987
+ }
914
988
  const blockList = getConfigBlock(config);
915
989
  if (blockList?.length) {
916
990
  configLines.push(`${pc.dim("Blocked Domains:")} ${blockList.join(", ")}`);
@@ -971,7 +1045,7 @@ async function main() {
971
1045
  const open = (await import("open")).default;
972
1046
  const config = await loadConfig();
973
1047
  const _require = createRequire(import.meta.url);
974
- const version = _require("../package.json").version || "2.5.0";
1048
+ const version = _require("../package.json").version || WEAVETAB_VERSION;
975
1049
  console.clear();
976
1050
  await checkForUpdates();
977
1051
  // Config resolution info
@@ -1002,7 +1076,7 @@ async function main() {
1002
1076
  console.log(pc.bold("LINKS"));
1003
1077
  console.log(` ${pc.cyan("[G]")} GitHub ${pc.dim("github.com/Weavetab")}`);
1004
1078
  console.log(` ${pc.cyan("[N]")} NPM ${pc.dim("npmjs.com/package/Weavetab")}`);
1005
- console.log(` ${pc.cyan("[W]")} Website ${pc.dim("Weavetab.dev")}`);
1079
+ console.log(` ${pc.cyan("[W]")} Website ${pc.dim("weavetab.dev")}`);
1006
1080
  console.log();
1007
1081
  console.log(pc.dim("Awaiting command..."));
1008
1082
  process.stdin.setRawMode(true);
@@ -1064,65 +1138,67 @@ async function main() {
1064
1138
  runMainUI();
1065
1139
  }
1066
1140
  if (k === "g") {
1067
- await open("https://github.com/Weavetab");
1141
+ await open("https://github.com/weavetab");
1068
1142
  }
1069
1143
  if (k === "n") {
1070
- await open("https://npmjs.com/package/Weavetab");
1144
+ await open("https://www.npmjs.com/package/@weavetab/mcp");
1071
1145
  }
1072
1146
  if (k === "w") {
1073
- await open("https://Weavetab.dev");
1147
+ await open("https://github.com/weavetab/mcp");
1074
1148
  }
1075
1149
  };
1076
1150
  process.stdin.on("data", onKey);
1077
1151
  }
1078
1152
  function runHelp() {
1079
1153
  const _require = createRequire(import.meta.url);
1080
- const version = _require("../package.json").version || "2.5.0";
1154
+ const version = _require("../package.json").version || WEAVETAB_VERSION;
1081
1155
  console.clear();
1082
1156
  console.log(boxen(pc.cyan(`Weavetab v${version}`), { padding: 1, borderStyle: 'round', borderColor: 'cyan' }));
1083
1157
  console.log(pc.dim("Production-grade MCP server for Chrome DevTools Protocol"));
1084
1158
  console.log();
1085
1159
  console.log(pc.bold("USAGE"));
1086
- console.log(` ${pc.cyan("wt <command> [options]")}`);
1160
+ console.log(` ${pc.cyan("weavetab <command> [options]")}`);
1087
1161
  console.log();
1088
1162
  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`);
1163
+ console.log(` ${pc.cyan("plugin")} Manage Weavetab plugins (add, list, remove, search, browse, verify)`);
1164
+ console.log(` ${pc.cyan("config")} Launch the interactive configuration wizard`);
1165
+ console.log(` ${pc.cyan("skills")} Install or update AI agent skills (@weavetab/skills)`);
1093
1166
  console.log(` ${pc.cyan("view")} Display the current active configuration`);
1094
1167
  console.log(` ${pc.cyan("reset")} Purge browser profiles, lockfiles, and orphan processes`);
1095
- console.log(` ${pc.cyan("secrets")} Manage encrypted credentials (set, list, rm)`);
1168
+ console.log(` ${pc.cyan("secrets")} Manage blind-injected credentials (set, list, rm)`);
1096
1169
  console.log(` ${pc.cyan("reload-ext")} Send a reload signal to the browser extension`);
1097
1170
  console.log(` ${pc.cyan("help")} Show this help message`);
1098
1171
  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`);
1172
+ console.log(pc.bold("AGENT SKILLS (@weavetab/skills)"));
1173
+ console.log(` ${pc.dim("Install/update skills:")} ${pc.cyan("npx -y @weavetab/skills@latest")}`);
1174
+ console.log(` ${pc.dim("Via CLI:")} ${pc.cyan("weavetab skills [options]")}`);
1175
+ console.log();
1176
+ console.log(pc.bold("PLUGIN COMMANDS (User)"));
1177
+ console.log(` ${pc.cyan("weavetab plugin add <pkg>")} Install a plugin (resolves official @weavetab/plugin- & community)`);
1178
+ console.log(` ${pc.cyan("weavetab plugin browse")} Interactive terminal explorer to browse & 1-click install`);
1179
+ console.log(` ${pc.cyan("weavetab plugin search <query>")} Search plugins across registry & npm`);
1180
+ console.log(` ${pc.cyan("weavetab plugin list")} List all installed Weavetab plugins and tools`);
1181
+ console.log(` ${pc.cyan("weavetab plugin remove <pkg>")} Uninstall a plugin`);
1182
+ console.log(` ${pc.cyan("weavetab plugin verify <pkg>")} Check trust tier against Weavetab registry`);
1103
1183
  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`);
1184
+ console.log(pc.bold("PLUGIN DEVELOPER SDK (@weavetab/sdk)"));
1185
+ console.log(` ${pc.dim("Scaffold a plugin:")} ${pc.cyan("npx -y @weavetab/sdk init <name>")}`);
1186
+ console.log(` ${pc.dim("Build & validate:")} ${pc.cyan("npx @weavetab/sdk build")}`);
1111
1187
  console.log();
1112
1188
  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`);
1189
+ console.log(` ${pc.cyan("weavetab secrets set <key>")} Store a new encrypted secret`);
1190
+ console.log(` ${pc.cyan("weavetab secrets list")} List all stored secrets`);
1191
+ console.log(` ${pc.cyan("weavetab secrets rm <key>")} Remove a secret by key`);
1192
+ console.log(` ${pc.cyan("weavetab secrets init --project")} Initialize project-scoped secrets`);
1117
1193
  console.log();
1118
1194
  console.log(pc.bold("ENVIRONMENT VARIABLES"));
1119
1195
  console.log(` ${pc.cyan("WT_PROXY_URL")} Proxy URL (overrides config value)`);
1120
1196
  console.log(` ${pc.cyan("WT_AGENT_ID")} Agent identifier (auto-generated if unset)`);
1121
1197
  console.log();
1122
1198
  console.log(pc.bold("LINKS"));
1123
- console.log(` ${pc.cyan("GitHub:")} ${pc.dim("https://github.com/Weavetab")}`);
1124
- console.log(` ${pc.cyan("npm:")} ${pc.dim("https://npmjs.com/package/Weavetab")}`);
1125
- console.log(` ${pc.cyan("Website:")} ${pc.dim("https://Weavetab.dev")}`);
1199
+ console.log(` ${pc.cyan("GitHub:")} ${pc.dim("https://github.com/weavetab")}`);
1200
+ console.log(` ${pc.cyan("npm:")} ${pc.dim("https://www.npmjs.com/package/@weavetab/mcp")}`);
1201
+ console.log(` ${pc.cyan("Website:")} ${pc.dim("https://github.com/weavetab/mcp")}`);
1126
1202
  console.log();
1127
1203
  }
1128
1204
  }
@@ -1161,7 +1237,7 @@ async function runSecretsCommand(args) {
1161
1237
  const { secretStore } = await import("./security/secrets.js");
1162
1238
  const p = await import("@clack/prompts");
1163
1239
  if (args.length === 0) {
1164
- console.log(pc.red("[ERROR] Usage: wt secrets <set|list|rm> [key]"));
1240
+ console.log(pc.red("[ERROR] Usage: weavetab secrets <set|list|rm> [key]"));
1165
1241
  process.exit(1);
1166
1242
  }
1167
1243
  const subcmd = args[0].toLowerCase();
@@ -1185,7 +1261,7 @@ async function runSecretsCommand(args) {
1185
1261
  if (subcmd === "rm") {
1186
1262
  const key = args[1];
1187
1263
  if (!key) {
1188
- console.log(pc.red("[ERROR] Usage: wt secrets rm <key>"));
1264
+ console.log(pc.red("[ERROR] Usage: weavetab secrets rm <key>"));
1189
1265
  process.exit(1);
1190
1266
  }
1191
1267
  const removed = await secretStore.removeSecret(key);
@@ -1200,7 +1276,7 @@ async function runSecretsCommand(args) {
1200
1276
  if (subcmd === "set") {
1201
1277
  const key = args[1];
1202
1278
  if (!key) {
1203
- console.log(pc.red("[ERROR] Usage: wt secrets set <key>"));
1279
+ console.log(pc.red("[ERROR] Usage: weavetab secrets set <key>"));
1204
1280
  process.exit(1);
1205
1281
  }
1206
1282
  console.clear();
@@ -1239,10 +1315,10 @@ async function runSecretsCommand(args) {
1239
1315
  }
1240
1316
  }
1241
1317
  await secretStore.setSecret(key, value, domains);
1242
- console.log(pc.green(`[OK] Secret "${key}" saved successfully.`));
1318
+ console.log(pc.green(`[OK] Secret "${key}" saved.`));
1243
1319
  return;
1244
1320
  }
1245
1321
  console.log(pc.red(`[ERROR] Unknown secrets command: ${subcmd}`));
1246
- console.log(pc.red("Usage: wt secrets <set|list|rm> [key]"));
1322
+ console.log(pc.red("Usage: weavetab secrets <set|list|rm> [key]"));
1247
1323
  process.exit(1);
1248
1324
  }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Weavetab — intelligence/marks.ts
3
+ * Visual grounding mark cache.
4
+ *
5
+ * When browser_map runs with visual: true/auto, numbered SoM badges are
6
+ * injected over the page, a screenshot is taken, and each badge's position
7
+ * and optional DOM ref are stored here. Interaction tools (browser_click,
8
+ * browser_pointer, etc.) can then resolve a { mark: N } argument directly
9
+ * to pixel coordinates without any further DOM walk.
10
+ *
11
+ * Weavetab by fy2ne
12
+ */
13
+ export interface MarkEntry {
14
+ /** Center X coordinate (viewport-relative pixels). */
15
+ x: number;
16
+ /** Center Y coordinate (viewport-relative pixels). */
17
+ y: number;
18
+ /** Width of the element bounding box. */
19
+ width: number;
20
+ /** Height of the element bounding box. */
21
+ height: number;
22
+ /** Volatile ref ID (w:NN) if the element is DOM-backed. Undefined for canvas/visual-only regions. */
23
+ ref?: string;
24
+ /** Visible text or aria-label, if available. */
25
+ label?: string;
26
+ /** Element type hint. */
27
+ type?: "button" | "input" | "link" | "select" | "canvas_region" | "unknown";
28
+ }
29
+ /** Write a full set of marks for a tab. Replaces any previous marks. */
30
+ export declare function marksSet(targetId: string, marks: Map<number, MarkEntry>): void;
31
+ /** Look up a single mark for a tab. Returns null if not found. */
32
+ export declare function marksGet(targetId: string, mark: number): MarkEntry | null;
33
+ /** Clear all marks for a tab (called on navigation). */
34
+ export declare function marksInvalidate(targetId: string): void;
35
+ /** Return all marks for a tab (used for debugging / list output). */
36
+ export declare function marksGetAll(targetId: string): Map<number, MarkEntry>;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Weavetab — intelligence/marks.ts
3
+ * Visual grounding mark cache.
4
+ *
5
+ * When browser_map runs with visual: true/auto, numbered SoM badges are
6
+ * injected over the page, a screenshot is taken, and each badge's position
7
+ * and optional DOM ref are stored here. Interaction tools (browser_click,
8
+ * browser_pointer, etc.) can then resolve a { mark: N } argument directly
9
+ * to pixel coordinates without any further DOM walk.
10
+ *
11
+ * Weavetab by fy2ne
12
+ */
13
+ /** Per-tab: Map<targetId, Map<markNumber, MarkEntry>> */
14
+ const store = new Map();
15
+ /** Write a full set of marks for a tab. Replaces any previous marks. */
16
+ export function marksSet(targetId, marks) {
17
+ store.set(targetId, marks);
18
+ }
19
+ /** Look up a single mark for a tab. Returns null if not found. */
20
+ export function marksGet(targetId, mark) {
21
+ return store.get(targetId)?.get(mark) ?? null;
22
+ }
23
+ /** Clear all marks for a tab (called on navigation). */
24
+ export function marksInvalidate(targetId) {
25
+ store.delete(targetId);
26
+ }
27
+ /** Return all marks for a tab (used for debugging / list output). */
28
+ export function marksGetAll(targetId) {
29
+ return store.get(targetId) ?? new Map();
30
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Weavetab — intelligence/patternCompiler.ts
3
+ *
4
+ * Compiles raw browser session trails (action sequences) into persistent,
5
+ * reusable site workflow patterns stored under ~/.weavetab-system/memory/sites/.
6
+ *
7
+ * Design invariants:
8
+ * - One file per origin (sanitized hostname). Never creates per-path or per-run files.
9
+ * - Pattern names are caller-supplied (snake_case). Duplicate calls for the same
10
+ * name on the same origin UPDATE the existing pattern rather than creating a new file.
11
+ * - Volatile / unstable selectors (auto-generated classes, nth-child paths) are
12
+ * stripped and replaced with semantic anchors where possible.
13
+ * - Never reads or writes to ~/.weavetab/ (user config space).
14
+ */
15
+ export interface WorkflowStep {
16
+ /** MCP tool name, e.g. "browser_click", "browser_fill", "browser_navigate" */
17
+ tool: string;
18
+ /** Primary selector or URL target */
19
+ target?: string;
20
+ /** Optional value (text typed, option selected, etc.) */
21
+ value?: string;
22
+ /** Any extra args forwarded verbatim to browser_burst replay */
23
+ extra?: Record<string, unknown>;
24
+ }
25
+ export interface WorkflowPattern {
26
+ /** Caller-assigned name in snake_case, e.g. "login_flow", "pr_review" */
27
+ name: string;
28
+ /** Compiled, stable steps ready for browser_burst replay */
29
+ steps: WorkflowStep[];
30
+ /** Optional CSS selector / URL fragment that confirms success */
31
+ success_indicator?: string;
32
+ /** URL path or pattern where this workflow starts, e.g. "/pull/:id/files" */
33
+ entry?: string;
34
+ /** Exponentially-weighted moving average of duration in ms */
35
+ avg_duration_ms?: number;
36
+ /** 0.0 – 1.0 reliability. Degrades on failures, climbs on successes. */
37
+ reliability: number;
38
+ /** Consecutive failure counter — 3 strikes triggers re-learn flag */
39
+ strikes: number;
40
+ /** ISO timestamp of last successful verified run */
41
+ last_verified: string;
42
+ /** Total times this pattern was executed */
43
+ total_executions: number;
44
+ /** Times the pattern completed without errors */
45
+ successful_executions: number;
46
+ }
47
+ export interface SiteQuirks {
48
+ cookie_banner?: {
49
+ selector: string;
50
+ action: string;
51
+ appears: "first_visit" | "always" | "random";
52
+ };
53
+ rate_limit?: {
54
+ threshold?: string;
55
+ recovery?: string;
56
+ };
57
+ modal_popups?: Array<{
58
+ trigger?: string;
59
+ dismiss_selector: string;
60
+ }>;
61
+ [key: string]: unknown;
62
+ }
63
+ export interface SiteProfile {
64
+ /** Full origin, e.g. "https://github.com" */
65
+ origin: string;
66
+ /** Detected JS framework: react, vue, angular, next, nuxt, svelte, etc. */
67
+ framework?: string;
68
+ /** True if the site uses Shadow DOM components */
69
+ shadowDom?: boolean;
70
+ /** How often this site presents CAPTCHA challenges */
71
+ captcha_frequency?: "none" | "rare" | "moderate" | "frequent";
72
+ /** Known site-level quirks to handle automatically */
73
+ quirks: SiteQuirks;
74
+ /** Named, compiled workflow patterns indexed by name */
75
+ patterns: Record<string, WorkflowPattern>;
76
+ /** ISO timestamp of last profile write */
77
+ updatedAt: string;
78
+ /** How many times this origin has been visited in automated sessions */
79
+ visitCount: number;
80
+ }
81
+ export declare function clearSiteProfileCache(): void;
82
+ /**
83
+ * Load a site profile from disk. Returns null if the site has never been profiled.
84
+ * Hits in-process cache first — no redundant disk reads within a session.
85
+ */
86
+ export declare function getSiteProfile(origin: string): Promise<SiteProfile | null>;
87
+ /**
88
+ * Persist a site profile. Always deep-merges into existing data on disk — never
89
+ * blindly overwrites — so concurrent tool calls don't clobber each other.
90
+ */
91
+ export declare function saveSiteProfile(profile: SiteProfile): Promise<void>;
92
+ /**
93
+ * Learn or update a named workflow pattern for a given origin.
94
+ * - Duplicate name = merge/update, never duplicate file.
95
+ * - Volatile selectors in steps are dropped to keep patterns stable.
96
+ * - Anti-spam: skips disk write when content is identical to existing.
97
+ */
98
+ export declare function learnPattern(origin: string, name: string, incoming: Partial<WorkflowPattern>): Promise<WorkflowPattern>;
99
+ /**
100
+ * Record the outcome of executing a named pattern.
101
+ * Updates reliability via EWMA (α=0.15) and tracks consecutive strikes.
102
+ * 3 strikes → reliability will naturally fall below 0.4, agent should re-explore.
103
+ */
104
+ export declare function recordPatternExecution(origin: string, patternName: string, success: boolean, durationMs?: number): Promise<WorkflowPattern | null>;
105
+ /**
106
+ * Record or update a site quirk (cookie banner, rate limit, modal popup, etc.)
107
+ * Only writes if the stored data differs from incoming — prevents spam writes.
108
+ */
109
+ export declare function recordQuirk(origin: string, quirkKey: string, quirkData: unknown): Promise<void>;
110
+ /**
111
+ * Returns the reliability score (0–1) of a named pattern, or -1 if unknown.
112
+ */
113
+ export declare function getPatternReliability(origin: string, patternName: string): Promise<number>;
114
+ /**
115
+ * Formats a compact site profile hint string for agent system prompt injection.
116
+ * Called at session start when navigating to a known origin.
117
+ */
118
+ export declare function formatSiteProfileHint(profile: SiteProfile): string;