@weavetab/mcp 2.5.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/AGENTS.md +48 -0
  2. package/ARCHITECTURE.md +590 -0
  3. package/LICENSE +631 -0
  4. package/README.md +909 -0
  5. package/SECURITY.md +196 -0
  6. package/TROUBLESHOOTING.md +365 -0
  7. package/dist/anticaptcha/detector.d.ts +49 -0
  8. package/dist/anticaptcha/detector.js +465 -0
  9. package/dist/anticaptcha/integration.d.ts +36 -0
  10. package/dist/anticaptcha/integration.js +123 -0
  11. package/dist/anticaptcha/solver.d.ts +27 -0
  12. package/dist/anticaptcha/solver.js +552 -0
  13. package/dist/audit/logger.d.ts +13 -0
  14. package/dist/audit/logger.js +177 -0
  15. package/dist/audit/telemetry.d.ts +36 -0
  16. package/dist/audit/telemetry.js +162 -0
  17. package/dist/cdp/bridge.d.ts +16 -0
  18. package/dist/cdp/bridge.js +826 -0
  19. package/dist/cdp/confirm.d.ts +26 -0
  20. package/dist/cdp/confirm.js +79 -0
  21. package/dist/cdp/connector.d.ts +37 -0
  22. package/dist/cdp/connector.js +661 -0
  23. package/dist/cdp/extension.d.ts +36 -0
  24. package/dist/cdp/extension.js +118 -0
  25. package/dist/cdp/finder.d.ts +1 -0
  26. package/dist/cdp/finder.js +2 -0
  27. package/dist/cdp/helpers.d.ts +11 -0
  28. package/dist/cdp/helpers.js +195 -0
  29. package/dist/cdp/label_cache.d.ts +12 -0
  30. package/dist/cdp/label_cache.js +51 -0
  31. package/dist/cdp/lock.d.ts +33 -0
  32. package/dist/cdp/lock.js +206 -0
  33. package/dist/cdp/omni_broker.d.ts +17 -0
  34. package/dist/cdp/omni_broker.js +119 -0
  35. package/dist/cdp/profiles.d.ts +1 -0
  36. package/dist/cdp/profiles.js +87 -0
  37. package/dist/cdp/pruner.d.ts +41 -0
  38. package/dist/cdp/pruner.js +263 -0
  39. package/dist/cdp/ref_cache.d.ts +101 -0
  40. package/dist/cdp/ref_cache.js +234 -0
  41. package/dist/cdp/retry.d.ts +5 -0
  42. package/dist/cdp/retry.js +39 -0
  43. package/dist/cdp/retry_enhanced.d.ts +44 -0
  44. package/dist/cdp/retry_enhanced.js +102 -0
  45. package/dist/cdp/security.d.ts +50 -0
  46. package/dist/cdp/security.js +237 -0
  47. package/dist/cdp/verify.d.ts +39 -0
  48. package/dist/cdp/verify.js +143 -0
  49. package/dist/cdp/walker.d.ts +91 -0
  50. package/dist/cdp/walker.js +896 -0
  51. package/dist/cdp/walker.test.d.ts +2 -0
  52. package/dist/cdp/walker.test.js +172 -0
  53. package/dist/cdp/websocket_transport.d.ts +15 -0
  54. package/dist/cdp/websocket_transport.js +118 -0
  55. package/dist/cli/plugin.d.ts +9 -0
  56. package/dist/cli/plugin.js +1134 -0
  57. package/dist/cli/updater.d.ts +1 -0
  58. package/dist/cli/updater.js +72 -0
  59. package/dist/config/loader.d.ts +120 -0
  60. package/dist/config/loader.js +704 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.js +1248 -0
  63. package/dist/intelligence/hints.d.ts +11 -0
  64. package/dist/intelligence/hints.js +39 -0
  65. package/dist/intelligence/intent.d.ts +33 -0
  66. package/dist/intelligence/intent.js +171 -0
  67. package/dist/intelligence/sessionMemory.d.ts +66 -0
  68. package/dist/intelligence/sessionMemory.js +284 -0
  69. package/dist/intelligence/sessionMemory.test.d.ts +2 -0
  70. package/dist/intelligence/sessionMemory.test.js +62 -0
  71. package/dist/intelligence/trail.d.ts +64 -0
  72. package/dist/intelligence/trail.js +233 -0
  73. package/dist/intelligence/trail.test.d.ts +2 -0
  74. package/dist/intelligence/trail.test.js +110 -0
  75. package/dist/intelligence/vision.d.ts +24 -0
  76. package/dist/intelligence/vision.js +151 -0
  77. package/dist/lifecycle/mission_manager.d.ts +16 -0
  78. package/dist/lifecycle/mission_manager.js +44 -0
  79. package/dist/overlay/bubble.d.ts +16 -0
  80. package/dist/overlay/bubble.js +37 -0
  81. package/dist/overlay/ghost.d.ts +35 -0
  82. package/dist/overlay/ghost.js +508 -0
  83. package/dist/overlay/injector.d.ts +22 -0
  84. package/dist/overlay/injector.js +198 -0
  85. package/dist/plugin/interface.d.ts +134 -0
  86. package/dist/plugin/interface.js +1 -0
  87. package/dist/plugin/loader.d.ts +18 -0
  88. package/dist/plugin/loader.js +155 -0
  89. package/dist/plugin/registry.d.ts +50 -0
  90. package/dist/plugin/registry.js +234 -0
  91. package/dist/security/blacklist.d.ts +24 -0
  92. package/dist/security/blacklist.js +80 -0
  93. package/dist/security/filter.d.ts +2 -0
  94. package/dist/security/filter.js +20 -0
  95. package/dist/security/guard.d.ts +8 -0
  96. package/dist/security/guard.js +35 -0
  97. package/dist/security/ratelimit.d.ts +11 -0
  98. package/dist/security/ratelimit.js +57 -0
  99. package/dist/security/secrets.d.ts +75 -0
  100. package/dist/security/secrets.js +365 -0
  101. package/dist/sensors/actionability.d.ts +81 -0
  102. package/dist/sensors/actionability.js +303 -0
  103. package/dist/sensors/guard.d.ts +25 -0
  104. package/dist/sensors/guard.js +168 -0
  105. package/dist/sensors/mutations.d.ts +23 -0
  106. package/dist/sensors/mutations.js +93 -0
  107. package/dist/sensors/network.d.ts +67 -0
  108. package/dist/sensors/network.js +193 -0
  109. package/dist/sensors/operation_monitor.d.ts +80 -0
  110. package/dist/sensors/operation_monitor.js +203 -0
  111. package/dist/sensors/pacing.d.ts +44 -0
  112. package/dist/sensors/pacing.js +111 -0
  113. package/dist/sensors/thoughts.d.ts +2 -0
  114. package/dist/sensors/thoughts.js +59 -0
  115. package/dist/sensors/wait.d.ts +12 -0
  116. package/dist/sensors/wait.js +44 -0
  117. package/dist/server.d.ts +7 -0
  118. package/dist/server.js +1687 -0
  119. package/dist/state/agent.d.ts +36 -0
  120. package/dist/state/agent.js +101 -0
  121. package/dist/state/cache.d.ts +16 -0
  122. package/dist/state/cache.js +92 -0
  123. package/dist/state/cache.test.d.ts +2 -0
  124. package/dist/state/cache.test.js +76 -0
  125. package/dist/state/delta.d.ts +71 -0
  126. package/dist/state/delta.js +234 -0
  127. package/dist/state/delta.test.d.ts +2 -0
  128. package/dist/state/delta.test.js +279 -0
  129. package/dist/state/groups.d.ts +15 -0
  130. package/dist/state/groups.js +80 -0
  131. package/dist/state/session.d.ts +30 -0
  132. package/dist/state/session.js +155 -0
  133. package/dist/tools/accessibility.d.ts +14 -0
  134. package/dist/tools/accessibility.js +32 -0
  135. package/dist/tools/ask.d.ts +14 -0
  136. package/dist/tools/ask.js +49 -0
  137. package/dist/tools/automation.d.ts +36 -0
  138. package/dist/tools/automation.js +218 -0
  139. package/dist/tools/browser_detect.d.ts +13 -0
  140. package/dist/tools/browser_detect.js +73 -0
  141. package/dist/tools/burst.d.ts +35 -0
  142. package/dist/tools/burst.js +344 -0
  143. package/dist/tools/canvas.d.ts +25 -0
  144. package/dist/tools/canvas.js +132 -0
  145. package/dist/tools/captcha.d.ts +38 -0
  146. package/dist/tools/captcha.js +209 -0
  147. package/dist/tools/click.d.ts +36 -0
  148. package/dist/tools/click.js +561 -0
  149. package/dist/tools/click_and_wait.d.ts +33 -0
  150. package/dist/tools/click_and_wait.js +149 -0
  151. package/dist/tools/clipboard.d.ts +29 -0
  152. package/dist/tools/clipboard.js +279 -0
  153. package/dist/tools/console.d.ts +21 -0
  154. package/dist/tools/console.js +107 -0
  155. package/dist/tools/cookies.d.ts +67 -0
  156. package/dist/tools/cookies.js +121 -0
  157. package/dist/tools/design_extract.d.ts +109 -0
  158. package/dist/tools/design_extract.js +641 -0
  159. package/dist/tools/dialog.d.ts +24 -0
  160. package/dist/tools/dialog.js +109 -0
  161. package/dist/tools/drag.d.ts +15 -0
  162. package/dist/tools/drag.js +29 -0
  163. package/dist/tools/emulation.d.ts +33 -0
  164. package/dist/tools/emulation.js +69 -0
  165. package/dist/tools/eval.d.ts +20 -0
  166. package/dist/tools/eval.js +92 -0
  167. package/dist/tools/fill.d.ts +41 -0
  168. package/dist/tools/fill.js +667 -0
  169. package/dist/tools/find.d.ts +30 -0
  170. package/dist/tools/find.js +60 -0
  171. package/dist/tools/geo.d.ts +19 -0
  172. package/dist/tools/geo.js +29 -0
  173. package/dist/tools/github/analyze.d.ts +4 -0
  174. package/dist/tools/github/analyze.js +113 -0
  175. package/dist/tools/github/cache.d.ts +21 -0
  176. package/dist/tools/github/cache.js +28 -0
  177. package/dist/tools/github/index.d.ts +4 -0
  178. package/dist/tools/github/index.js +4 -0
  179. package/dist/tools/github/issues.d.ts +9 -0
  180. package/dist/tools/github/issues.js +88 -0
  181. package/dist/tools/github/pr.d.ts +5 -0
  182. package/dist/tools/github/pr.js +88 -0
  183. package/dist/tools/github/rateLimiter.d.ts +4 -0
  184. package/dist/tools/github/rateLimiter.js +46 -0
  185. package/dist/tools/github/read.d.ts +34 -0
  186. package/dist/tools/github/read.js +74 -0
  187. package/dist/tools/github/repoContext.d.ts +20 -0
  188. package/dist/tools/github/repoContext.js +129 -0
  189. package/dist/tools/highlight.d.ts +20 -0
  190. package/dist/tools/highlight.js +140 -0
  191. package/dist/tools/hover.d.ts +19 -0
  192. package/dist/tools/hover.js +57 -0
  193. package/dist/tools/inspect.d.ts +17 -0
  194. package/dist/tools/inspect.js +125 -0
  195. package/dist/tools/integration.test.d.ts +2 -0
  196. package/dist/tools/integration.test.js +96 -0
  197. package/dist/tools/key.d.ts +25 -0
  198. package/dist/tools/key.js +173 -0
  199. package/dist/tools/macro_compiler.d.ts +7 -0
  200. package/dist/tools/macro_compiler.js +82 -0
  201. package/dist/tools/mouse.d.ts +21 -0
  202. package/dist/tools/mouse.js +62 -0
  203. package/dist/tools/navigate.d.ts +16 -0
  204. package/dist/tools/navigate.js +188 -0
  205. package/dist/tools/network_intercept.d.ts +17 -0
  206. package/dist/tools/network_intercept.js +151 -0
  207. package/dist/tools/office/index.d.ts +9 -0
  208. package/dist/tools/office/index.js +7 -0
  209. package/dist/tools/office/list.d.ts +15 -0
  210. package/dist/tools/office/list.js +41 -0
  211. package/dist/tools/office/parse.d.ts +20 -0
  212. package/dist/tools/office/parse.js +172 -0
  213. package/dist/tools/pdf.d.ts +22 -0
  214. package/dist/tools/pdf.js +42 -0
  215. package/dist/tools/performance.d.ts +12 -0
  216. package/dist/tools/performance.js +47 -0
  217. package/dist/tools/performance_test.d.ts +70 -0
  218. package/dist/tools/performance_test.js +128 -0
  219. package/dist/tools/plan.d.ts +39 -0
  220. package/dist/tools/plan.js +161 -0
  221. package/dist/tools/pointer.d.ts +35 -0
  222. package/dist/tools/pointer.js +522 -0
  223. package/dist/tools/read.d.ts +30 -0
  224. package/dist/tools/read.js +488 -0
  225. package/dist/tools/recording.d.ts +45 -0
  226. package/dist/tools/recording.js +124 -0
  227. package/dist/tools/response.d.ts +129 -0
  228. package/dist/tools/response.js +5 -0
  229. package/dist/tools/scrape.d.ts +24 -0
  230. package/dist/tools/scrape.js +140 -0
  231. package/dist/tools/screenshot.d.ts +40 -0
  232. package/dist/tools/screenshot.js +79 -0
  233. package/dist/tools/scroll.d.ts +23 -0
  234. package/dist/tools/scroll.js +196 -0
  235. package/dist/tools/select.d.ts +13 -0
  236. package/dist/tools/select.js +217 -0
  237. package/dist/tools/snapshot.d.ts +27 -0
  238. package/dist/tools/snapshot.js +99 -0
  239. package/dist/tools/storage.d.ts +18 -0
  240. package/dist/tools/storage.js +29 -0
  241. package/dist/tools/tabs.d.ts +77 -0
  242. package/dist/tools/tabs.js +342 -0
  243. package/dist/tools/thought.d.ts +16 -0
  244. package/dist/tools/thought.js +79 -0
  245. package/dist/tools/type.d.ts +65 -0
  246. package/dist/tools/type.js +1061 -0
  247. package/dist/tools/type_secret.d.ts +23 -0
  248. package/dist/tools/type_secret.js +229 -0
  249. package/dist/tools/upload.d.ts +19 -0
  250. package/dist/tools/upload.js +103 -0
  251. package/dist/tools/video_compiler.d.ts +24 -0
  252. package/dist/tools/video_compiler.js +199 -0
  253. package/dist/tools/viewport.d.ts +44 -0
  254. package/dist/tools/viewport.js +230 -0
  255. package/dist/tools/wait.d.ts +19 -0
  256. package/dist/tools/wait.js +202 -0
  257. package/dist/tools/wait_for.d.ts +23 -0
  258. package/dist/tools/wait_for.js +30 -0
  259. package/dist/tools/windows.d.ts +22 -0
  260. package/dist/tools/windows.js +57 -0
  261. package/dist/ui/index.d.ts +1 -0
  262. package/dist/ui/index.js +12 -0
  263. package/docs/DEV_MODE.md +68 -0
  264. package/docs/DOCUMENTATION.md +532 -0
  265. package/docs/PLUGINS.md +538 -0
  266. package/docs/TOOLS.md +104 -0
  267. package/docs/dev_plugin.md +310 -0
  268. package/ext-dist/background.js +467 -0
  269. package/ext-dist/content.js +3089 -0
  270. package/ext-dist/dashboard.html +583 -0
  271. package/ext-dist/hud/hud.js +73 -0
  272. package/ext-dist/hud/index.html +20 -0
  273. package/ext-dist/manifest.json +77 -0
  274. package/ext-dist/sidepanel/sidepanel.js +25 -0
  275. package/ext-dist/sidepanel.html +547 -0
  276. package/ext-dist/styles.css +218 -0
  277. package/icon.png +0 -0
  278. package/mcp.json +796 -0
  279. package/package.json +113 -0
  280. package/server.json +23 -0
  281. package/smithery.yaml +11 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Weavetab — tools/dialog.ts
3
+ * Auto-handles JavaScript alert/confirm/prompt dialogs via CDP Page API.
4
+ * Weavetab by fy2ne
5
+ */
6
+ import { logAction } from "../audit/logger.js";
7
+ // Store the last dialog event data per session using a WeakMap. This survives
8
+ // across initDialogHandler → browserDialog calls without leaking memory
9
+ // (entries are GC'd when the session is released).
10
+ const dialogState = new WeakMap();
11
+ export function hasOpenDialog(session) {
12
+ const state = dialogState.get(session);
13
+ return state != null && !state.autoDismiss;
14
+ }
15
+ /** Register the auto-dismiss handler for the given CDP session. */
16
+ export function initDialogHandler(session) {
17
+ session.Page.on("javascriptDialogOpening", async (event) => {
18
+ const { type, message, defaultPrompt } = event;
19
+ // Store dialog metadata WITHOUT auto-dismissing so browserDialog can read
20
+ // the type and handle it appropriately. This is the only point where CDP
21
+ // exposes the real type.
22
+ dialogState.set(session, { type, message, defaultPrompt, autoDismiss: false });
23
+ logAction("browser_dialog", type, `dialog detected: "${message}"`);
24
+ // Inject a visual toast so the user knows we detected it
25
+ const toastScript = `
26
+ (function() {
27
+ if (document.getElementById('wt-dialog-toast')) return;
28
+ const toast = document.createElement("div");
29
+ toast.id = 'wt-dialog-toast';
30
+ toast.style.cssText = "position:fixed;bottom:20px;right:20px;background:#f59e0b;color:white;padding:12px 24px;border-radius:8px;font-family:sans-serif;font-weight:600;z-index:2147483647;box-shadow:0 4px 12px rgba(0,0,0,0.3);animation:fadein 0.3s, fadeout 0.3s 2.5s forwards;";
31
+ toast.textContent = "${type} detected: ${message.substring(0, 50).replace(/"/g, '\\"')}";
32
+ const style = document.createElement("style");
33
+ style.textContent = "@keyframes fadein { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeout { from { opacity: 1; } to { opacity: 0; } }";
34
+ document.head.appendChild(style);
35
+ document.documentElement.appendChild(toast);
36
+ setTimeout(() => toast.remove(), 3000);
37
+ })();
38
+ `;
39
+ session.Runtime.evaluate({ expression: toastScript }).catch(() => { });
40
+ // For security-critical dialogs (like extension removal), auto-dismiss to prevent accidental acceptance
41
+ if (message.toLowerCase().includes("extension") || message.toLowerCase().includes("developer mode")) {
42
+ try {
43
+ await session.Page.handleJavaScriptDialog({ accept: false });
44
+ dialogState.set(session, { type, message, defaultPrompt, autoDismiss: true });
45
+ logAction("browser_dialog", type, `auto-dismissed security dialog: "${message}"`);
46
+ }
47
+ catch {
48
+ // Dialog may have already closed
49
+ }
50
+ }
51
+ else {
52
+ // For normal dialogs, leave them open for 5 seconds so browserDialog can handle them with the correct type
53
+ // After timeout, auto-dismiss to prevent blocking
54
+ const timeoutId = setTimeout(async () => {
55
+ const current = dialogState.get(session);
56
+ if (current && !current.autoDismiss) {
57
+ try {
58
+ await session.Page.handleJavaScriptDialog({ accept: false });
59
+ dialogState.set(session, { type: current.type, message: current.message, defaultPrompt: current.defaultPrompt, autoDismiss: true });
60
+ logAction("browser_dialog", current.type, `auto-dismissed after timeout: "${current.message}"`);
61
+ }
62
+ catch {
63
+ // Dialog may have already been handled
64
+ }
65
+ }
66
+ }, 5000);
67
+ const current = dialogState.get(session);
68
+ if (current) {
69
+ current.timeoutId = timeoutId;
70
+ }
71
+ }
72
+ });
73
+ }
74
+ export async function browserDialog(session, options) {
75
+ const { action, promptText } = options;
76
+ // Read stored dialog metadata before handling. If promptText was provided but
77
+ // the dialog type is 'prompt', pass it through so prompt injection works.
78
+ const stored = dialogState.get(session) || null;
79
+ // Clear the auto-dismiss timer immediately when browserDialog is called
80
+ if (stored?.timeoutId) {
81
+ clearTimeout(stored.timeoutId);
82
+ }
83
+ // Attempt to handle any currently open dialog
84
+ try {
85
+ await session.Page.handleJavaScriptDialog({
86
+ accept: action === "accept",
87
+ promptText: action === "accept"
88
+ ? (promptText !== undefined ? promptText : (stored?.type === "prompt" ? (stored?.defaultPrompt ?? "") : undefined))
89
+ : undefined,
90
+ });
91
+ // Mark as handled so the timeout handler doesn't try to dismiss it
92
+ if (stored) {
93
+ dialogState.set(session, { ...stored, autoDismiss: true });
94
+ }
95
+ // Clean up after a short delay
96
+ setTimeout(() => dialogState.delete(session), 100);
97
+ }
98
+ catch (e) {
99
+ // No dialog was open or it was already handled
100
+ dialogState.delete(session);
101
+ }
102
+ logAction("browser_dialog", "manual", `attempted to ${action} pending dialog`);
103
+ return {
104
+ success: true,
105
+ dialog_type: stored?.type || "unknown",
106
+ message: stored?.message || `Dialog ${action}ed (or no dialog was open)`,
107
+ accepted: action === "accept",
108
+ };
109
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Weavetab — tools/drag.ts
3
+ * browser_drag: mousedown on sourceNodeId, mousemove to targetNodeId, mouseup.
4
+ * Weavetab by fy2ne
5
+ */
6
+ import CDP from "chrome-remote-interface";
7
+ import type { Config } from "../config/loader.js";
8
+ export interface DragOptions {
9
+ sourceNodeId: number;
10
+ targetNodeId: number;
11
+ }
12
+ export declare function browserDrag(session: CDP.Client, options: DragOptions, _config: Config): Promise<{
13
+ success: boolean;
14
+ }>;
15
+ //# sourceMappingURL=drag.d.ts.map
@@ -0,0 +1,29 @@
1
+ export async function browserDrag(session, options, _config) {
2
+ const { sourceNodeId, targetNodeId } = options;
3
+ if (!sourceNodeId || !targetNodeId) {
4
+ throw new Error("browser_drag requires sourceNodeId and targetNodeId");
5
+ }
6
+ const getCoords = async (nodeId) => {
7
+ const { model } = await session.DOM.getBoxModel({ backendNodeId: nodeId });
8
+ return {
9
+ x: (model.content[0] + model.content[2]) / 2,
10
+ y: (model.content[1] + model.content[5]) / 2
11
+ };
12
+ };
13
+ const src = await getCoords(sourceNodeId);
14
+ const tgt = await getCoords(targetNodeId);
15
+ // 1. Move to source
16
+ await session.Input.dispatchMouseEvent({ type: "mouseMoved", x: src.x, y: src.y });
17
+ // 2. Mouse down
18
+ await session.Input.dispatchMouseEvent({ type: "mousePressed", x: src.x, y: src.y, button: "left", clickCount: 1 });
19
+ // Small delay to let UI react (e.g. drag start handlers)
20
+ await new Promise(r => setTimeout(r, 100));
21
+ // 3. Move to target with button held
22
+ // In a real smooth drag, we'd interpolate this, but a direct move often works.
23
+ await session.Input.dispatchMouseEvent({ type: "mouseMoved", x: tgt.x, y: tgt.y, button: "left" });
24
+ await new Promise(r => setTimeout(r, 100));
25
+ // 4. Mouse up
26
+ await session.Input.dispatchMouseEvent({ type: "mouseReleased", x: tgt.x, y: tgt.y, button: "left", clickCount: 1 });
27
+ return { success: true };
28
+ }
29
+ //# sourceMappingURL=drag.js.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Weavetab — tools/emulation.ts
3
+ * browser_emulate: Network, CPU, Geolocation, and Device emulation over CDP.
4
+ * Weavetab by fy2ne
5
+ */
6
+ import CDP from "chrome-remote-interface";
7
+ import type { Config } from "../config/loader.js";
8
+ export interface EmulationOptions {
9
+ /** Network throttling profile or custom parameters */
10
+ network?: "offline" | "slow3g" | "fast3g" | "4g" | "online" | {
11
+ offline?: boolean;
12
+ latency?: number;
13
+ downloadThroughput?: number;
14
+ uploadThroughput?: number;
15
+ };
16
+ /** CPU slowdown multiplier (e.g. 2 for 2x slowdown, 4 for 4x slowdown, 1 to disable) */
17
+ cpuThrottlingRate?: number;
18
+ /** Override geolocation coordinates */
19
+ geolocation?: {
20
+ latitude: number;
21
+ longitude: number;
22
+ accuracy?: number;
23
+ };
24
+ /** Override browser timezone (e.g. "America/New_York", "Europe/London") */
25
+ timezoneId?: string;
26
+ /** User Agent string override */
27
+ userAgent?: string;
28
+ }
29
+ export declare function browserEmulate(session: CDP.Client, options: EmulationOptions, _config: Config): Promise<{
30
+ success: boolean;
31
+ applied: string[];
32
+ error?: string;
33
+ }>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Weavetab — tools/emulation.ts
3
+ * browser_emulate: Network, CPU, Geolocation, and Device emulation over CDP.
4
+ * Weavetab by fy2ne
5
+ */
6
+ import { logAction } from "../audit/logger.js";
7
+ const PRESET_NETWORK_PROFILES = {
8
+ offline: { offline: true, latency: 0, downloadThroughput: 0, uploadThroughput: 0 },
9
+ slow3g: { offline: false, latency: 400, downloadThroughput: 500 * 1024 / 8, uploadThroughput: 500 * 1024 / 8 },
10
+ fast3g: { offline: false, latency: 150, downloadThroughput: 1.6 * 1024 * 1024 / 8, uploadThroughput: 750 * 1024 / 8 },
11
+ "4g": { offline: false, latency: 50, downloadThroughput: 10 * 1024 * 1024 / 8, uploadThroughput: 5 * 1024 * 1024 / 8 },
12
+ online: { offline: false, latency: 0, downloadThroughput: -1, uploadThroughput: -1 },
13
+ };
14
+ export async function browserEmulate(session, options, _config) {
15
+ const applied = [];
16
+ try {
17
+ // 1. Network Throttling
18
+ if (options.network) {
19
+ await session.Network.enable();
20
+ let params = typeof options.network === "string"
21
+ ? PRESET_NETWORK_PROFILES[options.network]
22
+ : options.network;
23
+ if (params) {
24
+ await session.Network.emulateNetworkConditions({
25
+ offline: params.offline ?? false,
26
+ latency: params.latency ?? 0,
27
+ downloadThroughput: params.downloadThroughput ?? -1,
28
+ uploadThroughput: params.uploadThroughput ?? -1,
29
+ });
30
+ applied.push(`network: ${typeof options.network === "string" ? options.network : "custom"}`);
31
+ }
32
+ }
33
+ // 2. CPU Throttling
34
+ if (options.cpuThrottlingRate !== undefined) {
35
+ await session.Emulation.setCPUThrottlingRate({
36
+ rate: options.cpuThrottlingRate,
37
+ });
38
+ applied.push(`cpuThrottlingRate: ${options.cpuThrottlingRate}x`);
39
+ }
40
+ // 3. Geolocation Override
41
+ if (options.geolocation) {
42
+ await session.Emulation.setGeolocationOverride({
43
+ latitude: options.geolocation.latitude,
44
+ longitude: options.geolocation.longitude,
45
+ accuracy: options.geolocation.accuracy ?? 1,
46
+ });
47
+ applied.push(`geolocation: ${options.geolocation.latitude}, ${options.geolocation.longitude}`);
48
+ }
49
+ // 4. Timezone Override
50
+ if (options.timezoneId) {
51
+ await session.Emulation.setTimezoneOverride({
52
+ timezoneId: options.timezoneId,
53
+ });
54
+ applied.push(`timezoneId: ${options.timezoneId}`);
55
+ }
56
+ // 5. User Agent Override
57
+ if (options.userAgent) {
58
+ await session.Network.setUserAgentOverride({
59
+ userAgent: options.userAgent,
60
+ });
61
+ applied.push(`userAgent: ${options.userAgent}`);
62
+ }
63
+ logAction("browser_emulate", "emulation", applied.join(", "));
64
+ return { success: true, applied };
65
+ }
66
+ catch (err) {
67
+ return { success: false, applied, error: err?.message || String(err) };
68
+ }
69
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Weavetab — tools/eval.ts
3
+ * browser_eval: Run arbitrary sandboxed JS via Runtime.evaluate.
4
+ * Special command: expression "Weavetab.usage()" returns session metrics.
5
+ * Weavetab by fy2ne
6
+ */
7
+ import CDP from "chrome-remote-interface";
8
+ import type { Config } from "../config/loader.js";
9
+ export interface EvalOptions {
10
+ expression: string;
11
+ timeout?: number;
12
+ }
13
+ export declare function browserEval(session: CDP.Client, options: EvalOptions, _config: Config): Promise<{
14
+ success: boolean;
15
+ result: any;
16
+ type: string;
17
+ error?: string;
18
+ url?: string;
19
+ title?: string;
20
+ }>;
@@ -0,0 +1,92 @@
1
+ import { sendToExtension } from "../cdp/helpers.js";
2
+ import { SessionSecretTracker } from "../security/secrets.js";
3
+ import { sessionRegistry } from "../state/session.js";
4
+ import { getConfigAgentId } from "../config/loader.js";
5
+ export async function browserEval(session, options, _config) {
6
+ const { expression, timeout = 3000 } = options; // Reduced from 5000ms
7
+ if (!expression)
8
+ throw new Error("browser_eval requires an 'expression'");
9
+ let targetId = "default";
10
+ const active = sessionRegistry.getActive(getConfigAgentId(_config));
11
+ if (active)
12
+ targetId = active.targetId;
13
+ sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: 'evaluating...' } }).catch(() => { });
14
+ // Always capture current page state so agent can detect navigation
15
+ let currentUrl = "";
16
+ let pageTitle = "";
17
+ try {
18
+ const { frameTree } = await session.Page.getFrameTree();
19
+ currentUrl = frameTree.frame.url;
20
+ try {
21
+ const titleRes = await session.Runtime.evaluate({ expression: 'document.title', returnByValue: true });
22
+ if (titleRes?.result?.value) {
23
+ pageTitle = titleRes.result.value;
24
+ }
25
+ }
26
+ catch { }
27
+ if (!pageTitle) {
28
+ const { result: t } = await session.Runtime.evaluate({ expression: 'document.title', returnByValue: true });
29
+ pageTitle = t?.value || "";
30
+ }
31
+ }
32
+ catch { /* non-fatal */ }
33
+ // Special intercept: Weavetab.usage() — returns in-process session metrics
34
+ if (expression.trim() === "Weavetab.usage()") {
35
+ const { getUsageStats } = await import("../sensors/pacing.js");
36
+ return { success: true, result: getUsageStats(), type: "object", url: currentUrl, title: pageTitle };
37
+ }
38
+ let evalExpr = expression.trim();
39
+ const isFunctionDecl = /^(?:async\s+)?function\b/.test(evalExpr) || /^(?:async\s*)?(?:\([^)]*\)|[a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>\s*\{/.test(evalExpr);
40
+ const isAlreadyIIFE = /^\s*\((?:async\s+)?function/.test(evalExpr) || /^\s*\((?:async\s*)?\(/.test(evalExpr);
41
+ if (!isAlreadyIIFE && isFunctionDecl) {
42
+ evalExpr = `(${evalExpr})`;
43
+ }
44
+ let result, exceptionDetails;
45
+ const res1 = await session.Runtime.evaluate({
46
+ expression: evalExpr,
47
+ returnByValue: true,
48
+ awaitPromise: true,
49
+ timeout
50
+ });
51
+ result = res1.result;
52
+ exceptionDetails = res1.exceptionDetails;
53
+ if (exceptionDetails && exceptionDetails.exception?.description?.includes('SyntaxError: Illegal return statement')) {
54
+ evalExpr = `(async function(){\n${expression}\n})()`;
55
+ const res2 = await session.Runtime.evaluate({
56
+ expression: evalExpr,
57
+ returnByValue: true,
58
+ awaitPromise: true,
59
+ timeout
60
+ });
61
+ result = res2.result;
62
+ exceptionDetails = res2.exceptionDetails;
63
+ }
64
+ if (exceptionDetails) {
65
+ sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } }).catch(() => { });
66
+ return {
67
+ success: false,
68
+ result: null,
69
+ type: "error",
70
+ error: SessionSecretTracker.redact(targetId, exceptionDetails.exception?.description || exceptionDetails.text || ""),
71
+ url: currentUrl,
72
+ title: pageTitle,
73
+ };
74
+ }
75
+ sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } }).catch(() => { });
76
+ // When the expression returns undefined (e.g., el.click(), void functions, or IIFEs with no return),
77
+ // result.value is undefined and result.description is unhelpfully a type string.
78
+ // Return a clear message so agents know the eval succeeded — it just returned no value.
79
+ const rawResult = result.type === 'undefined'
80
+ ? "(expression ran successfully — returned undefined. To get a confirmation value, append ; 'ok' or return a string explicitly.)"
81
+ : result.value !== undefined ? result.value : result.description;
82
+ const redactedResult = typeof rawResult === 'string'
83
+ ? SessionSecretTracker.redact(targetId, rawResult)
84
+ : rawResult;
85
+ return {
86
+ success: true,
87
+ result: redactedResult,
88
+ type: result.type,
89
+ url: currentUrl,
90
+ title: pageTitle,
91
+ };
92
+ }
@@ -0,0 +1,41 @@
1
+ import CDP from "chrome-remote-interface";
2
+ import type { Config } from "../config/loader.js";
3
+ export interface FillField {
4
+ ref: string;
5
+ value: string;
6
+ }
7
+ /** A single cell write for Google Sheets / Canvas grid filling. */
8
+ export interface GridCell {
9
+ /** Cell address in A1 notation, e.g. "A1", "B3", "C12". */
10
+ cell: string;
11
+ /** Value to type into the cell. */
12
+ value: string;
13
+ }
14
+ export interface FillOptions {
15
+ fields?: FillField[];
16
+ submit?: string;
17
+ scan_only?: boolean;
18
+ blast_mode?: boolean;
19
+ /** Grid-fill mode for Google Sheets and other canvas-rendered spreadsheets.
20
+ * Provide cell addresses in A1 notation with their values.
21
+ * The tool uses the Chrome Accessibility Tree to locate each cell. */
22
+ grid_data?: GridCell[];
23
+ }
24
+ export interface FillResult {
25
+ success: boolean;
26
+ total_fields: number;
27
+ succeeded: number;
28
+ failed: number;
29
+ submitted: boolean;
30
+ results: {
31
+ ref: string;
32
+ field_type: string;
33
+ success: boolean;
34
+ message: string;
35
+ value?: string;
36
+ }[];
37
+ execution_ms: number;
38
+ /** Concrete next step for the agent when fill fails */
39
+ suggestedNext?: string;
40
+ }
41
+ export declare function browserFill(session: CDP.Client, options: FillOptions, config: Config): Promise<FillResult>;