@weavetab/mcp 2.5.0-beta.5 → 2.5.1

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 (160) hide show
  1. package/AGENTS.md +49 -49
  2. package/ARCHITECTURE.md +590 -590
  3. package/README.md +216 -100
  4. package/SECURITY.md +207 -207
  5. package/TROUBLESHOOTING.md +373 -365
  6. package/dist/anticaptcha/detector.js +395 -395
  7. package/dist/anticaptcha/solver.js +130 -130
  8. package/dist/cdp/bridge.js +73 -73
  9. package/dist/cdp/connector.js +46 -22
  10. package/dist/cdp/extension.js +34 -34
  11. package/dist/cdp/helpers.js +174 -174
  12. package/dist/cdp/pruner.js +195 -195
  13. package/dist/cdp/ref_cache.js +66 -66
  14. package/dist/cdp/security.js +10 -10
  15. package/dist/cdp/verify.js +57 -57
  16. package/dist/cdp/walker.js +563 -525
  17. package/dist/cli/plugin.js +26 -3
  18. package/dist/config/loader.d.ts +0 -3
  19. package/dist/config/loader.js +0 -9
  20. package/dist/index.js +0 -4
  21. package/dist/intelligence/intent.js +81 -81
  22. package/dist/intelligence/sessionMemory.js +2 -2
  23. package/dist/overlay/ghost.js +22 -22
  24. package/dist/overlay/injector.js +89 -89
  25. package/dist/plugin/extension_bridge.js +54 -54
  26. package/dist/plugin/interface.d.ts +7 -0
  27. package/dist/plugin/loader.js +3 -4
  28. package/dist/plugin/schema.d.ts +11 -0
  29. package/dist/plugin/schema.js +59 -0
  30. package/dist/security/guard.js +18 -18
  31. package/dist/sensors/actionability.js +167 -167
  32. package/dist/sensors/guard.js +29 -29
  33. package/dist/sensors/network.js +15 -17
  34. package/dist/server.d.ts +1 -1
  35. package/dist/server.js +173 -144
  36. package/dist/state/delta.js +6 -7
  37. package/dist/tools/automation.js +85 -85
  38. package/dist/tools/canvas.js +48 -25
  39. package/dist/tools/checkpoint.js +94 -35
  40. package/dist/tools/click.js +52 -41
  41. package/dist/tools/clipboard.js +80 -74
  42. package/dist/tools/design_extract.js +441 -441
  43. package/dist/tools/dialog.js +13 -13
  44. package/dist/tools/emulation.d.ts +2 -0
  45. package/dist/tools/emulation.js +7 -0
  46. package/dist/tools/fill.js +344 -347
  47. package/dist/tools/find.js +78 -52
  48. package/dist/tools/highlight.js +67 -67
  49. package/dist/tools/inspect.js +54 -25
  50. package/dist/tools/key.js +42 -35
  51. package/dist/tools/navigate.d.ts +1 -1
  52. package/dist/tools/navigate.js +35 -35
  53. package/dist/tools/office/parse.js +62 -18
  54. package/dist/tools/pdf.d.ts +9 -0
  55. package/dist/tools/pdf.js +7 -4
  56. package/dist/tools/performance.d.ts +11 -4
  57. package/dist/tools/performance.js +94 -42
  58. package/dist/tools/performance_test.d.ts +2 -2
  59. package/dist/tools/performance_test.js +69 -69
  60. package/dist/tools/pointer.js +116 -116
  61. package/dist/tools/read.js +99 -67
  62. package/dist/tools/recording.js +9 -0
  63. package/dist/tools/scrape.js +146 -146
  64. package/dist/tools/screenshot.d.ts +2 -0
  65. package/dist/tools/screenshot.js +46 -4
  66. package/dist/tools/scroll.d.ts +3 -1
  67. package/dist/tools/scroll.js +13 -15
  68. package/dist/tools/select.d.ts +3 -0
  69. package/dist/tools/select.js +131 -124
  70. package/dist/tools/snapshot.js +8 -6
  71. package/dist/tools/storage.d.ts +5 -1
  72. package/dist/tools/storage.js +16 -0
  73. package/dist/tools/tabs.d.ts +7 -5
  74. package/dist/tools/tabs.js +79 -26
  75. package/dist/tools/thought.js +8 -8
  76. package/dist/tools/type.js +274 -274
  77. package/dist/tools/type_secret.js +23 -23
  78. package/dist/tools/upload.js +3 -3
  79. package/dist/tools/video_compiler.js +9 -0
  80. package/dist/tools/wait.js +35 -35
  81. package/dist/version.d.ts +1 -1
  82. package/dist/version.js +1 -1
  83. package/docs/DOCUMENTATION.md +583 -585
  84. package/docs/PLUGINS.md +139 -121
  85. package/docs/TOOLS.md +3 -4
  86. package/docs/architecture/blind-injection.md +83 -83
  87. package/docs/architecture/overview.md +49 -49
  88. package/docs/configuration/configuration.md +39 -27
  89. package/docs/configuration/folders.md +62 -55
  90. package/docs/desktop-automation/electron-apps.md +225 -214
  91. package/docs/get-started/installation.md +1 -1
  92. package/docs/get-started/introduction.md +60 -60
  93. package/docs/get-started/quickstart.md +2 -2
  94. package/docs/get-started/setup-wizard.md +1 -1
  95. package/docs/intelligence/site-profiles.md +151 -151
  96. package/docs/tools/tools.md +582 -631
  97. package/docs/troubleshooting/trouble-loop.md +31 -31
  98. package/ext-dist/background.js +415 -415
  99. package/ext-dist/content.js +2527 -2527
  100. package/ext-dist/dashboard.html +583 -583
  101. package/ext-dist/hud/hud.js +3 -3
  102. package/ext-dist/hud/index.html +20 -20
  103. package/ext-dist/manifest.json +73 -73
  104. package/ext-dist/styles.css +223 -223
  105. package/mcp.json +796 -805
  106. package/package.json +8 -8
  107. package/server.json +23 -23
  108. package/smithery.yaml +7 -11
  109. package/dist/cdp/walker.test.d.ts +0 -2
  110. package/dist/cdp/walker.test.js +0 -172
  111. package/dist/intelligence/sessionMemory.test.d.ts +0 -2
  112. package/dist/intelligence/sessionMemory.test.js +0 -62
  113. package/dist/intelligence/trail.test.d.ts +0 -2
  114. package/dist/intelligence/trail.test.js +0 -110
  115. package/dist/state/cache.test.d.ts +0 -2
  116. package/dist/state/cache.test.js +0 -76
  117. package/dist/state/delta.test.d.ts +0 -2
  118. package/dist/state/delta.test.js +0 -279
  119. package/dist/state/groups.d.ts +0 -15
  120. package/dist/state/groups.js +0 -80
  121. package/dist/tools/accessibility.d.ts +0 -14
  122. package/dist/tools/accessibility.js +0 -32
  123. package/dist/tools/ask.d.ts +0 -14
  124. package/dist/tools/ask.js +0 -49
  125. package/dist/tools/click_and_wait.d.ts +0 -33
  126. package/dist/tools/click_and_wait.js +0 -149
  127. package/dist/tools/drag.d.ts +0 -15
  128. package/dist/tools/drag.js +0 -29
  129. package/dist/tools/geo.d.ts +0 -19
  130. package/dist/tools/geo.js +0 -29
  131. package/dist/tools/github/analyze.d.ts +0 -4
  132. package/dist/tools/github/analyze.js +0 -113
  133. package/dist/tools/github/cache.d.ts +0 -21
  134. package/dist/tools/github/cache.js +0 -28
  135. package/dist/tools/github/index.d.ts +0 -19
  136. package/dist/tools/github/index.js +0 -40
  137. package/dist/tools/github/issues.d.ts +0 -9
  138. package/dist/tools/github/issues.js +0 -88
  139. package/dist/tools/github/pr.d.ts +0 -5
  140. package/dist/tools/github/pr.js +0 -88
  141. package/dist/tools/github/rateLimiter.d.ts +0 -4
  142. package/dist/tools/github/rateLimiter.js +0 -46
  143. package/dist/tools/github/read.d.ts +0 -34
  144. package/dist/tools/github/read.js +0 -74
  145. package/dist/tools/github/repoContext.d.ts +0 -20
  146. package/dist/tools/github/repoContext.js +0 -129
  147. package/dist/tools/hover.d.ts +0 -19
  148. package/dist/tools/hover.js +0 -57
  149. package/dist/tools/integration.test.d.ts +0 -2
  150. package/dist/tools/integration.test.js +0 -96
  151. package/dist/tools/macro_compiler.d.ts +0 -7
  152. package/dist/tools/macro_compiler.js +0 -82
  153. package/dist/tools/mouse.d.ts +0 -21
  154. package/dist/tools/mouse.js +0 -62
  155. package/dist/tools/response.d.ts +0 -129
  156. package/dist/tools/response.js +0 -5
  157. package/dist/tools/wait_for.d.ts +0 -23
  158. package/dist/tools/wait_for.js +0 -30
  159. package/dist/tools/windows.d.ts +0 -22
  160. package/dist/tools/windows.js +0 -57
@@ -1,279 +0,0 @@
1
- /**
2
- * delta.test.ts — Phase 1.1
3
- * Unit tests for snapshot diffing and delta computation.
4
- */
5
- import { test } from "node:test";
6
- import assert from "node:assert/strict";
7
- import { storeSnapshot, computeDelta, seedRichSnapshot, computeRichDelta, clearAllSnapshots, } from "./delta.js";
8
- test("delta: first visit returns null (no baseline)", () => {
9
- const targetId = "tab-1";
10
- clearAllSnapshots();
11
- const refs = [
12
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
13
- ];
14
- const result = computeDelta(targetId, 'http://test.com', refs);
15
- assert.equal(result, null, "First visit should return null");
16
- });
17
- test("delta: detects added elements", () => {
18
- const targetId = "tab-2";
19
- clearAllSnapshots();
20
- const initial = [
21
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
22
- ];
23
- storeSnapshot(targetId, 'http://test.com', initial);
24
- const updated = [
25
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
26
- { id: "w:2", role: "link", label: "Home", fingerprint: "link:home:nav:1" },
27
- ];
28
- const result = computeDelta(targetId, 'http://test.com', updated);
29
- assert.ok(result !== null);
30
- assert.equal(result?.added.length, 1, "One element added");
31
- assert.equal(result?.added[0]?.id, "w:2");
32
- assert.equal(result?.removed.length, 0);
33
- assert.equal(result?.changed.length, 0);
34
- });
35
- test("delta: detects removed elements", () => {
36
- const targetId = "tab-3";
37
- clearAllSnapshots();
38
- const initial = [
39
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
40
- { id: "w:2", role: "link", label: "Home", fingerprint: "link:home:nav:1" },
41
- ];
42
- storeSnapshot(targetId, 'http://test.com', initial);
43
- const updated = [
44
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
45
- ];
46
- const result = computeDelta(targetId, 'http://test.com', updated);
47
- assert.ok(result !== null);
48
- assert.equal(result?.added.length, 0);
49
- assert.equal(result?.removed.length, 1, "One element removed");
50
- assert.equal(result?.removed[0], "w:2");
51
- assert.equal(result?.changed.length, 0);
52
- });
53
- test("delta: detects changed elements (label)", () => {
54
- const targetId = "tab-4";
55
- clearAllSnapshots();
56
- const initial = [
57
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
58
- ];
59
- storeSnapshot(targetId, 'http://test.com', initial);
60
- const updated = [
61
- { id: "w:1", role: "button", label: "Cancel", fingerprint: "button:cancel:div:0" },
62
- ];
63
- const result = computeDelta(targetId, 'http://test.com', updated);
64
- assert.ok(result !== null);
65
- assert.equal(result?.added.length, 0);
66
- assert.equal(result?.removed.length, 0);
67
- assert.equal(result?.changed.length, 1, "One element changed");
68
- assert.equal(result?.changed[0]?.id, "w:1");
69
- assert.equal(result?.changed[0]?.label, "Cancel");
70
- });
71
- test("delta: detects changed elements (disabled)", () => {
72
- const targetId = "tab-5";
73
- clearAllSnapshots();
74
- const initial = [
75
- { id: "w:1", role: "button", label: "Submit", disabled: false, fingerprint: "button:submit:div:0" },
76
- ];
77
- storeSnapshot(targetId, 'http://test.com', initial);
78
- const updated = [
79
- { id: "w:1", role: "button", label: "Submit", disabled: true, fingerprint: "button:submit:div:0" },
80
- ];
81
- const result = computeDelta(targetId, 'http://test.com', updated);
82
- assert.ok(result !== null);
83
- assert.equal(result?.changed.length, 1, "Disabled state change detected");
84
- assert.equal(result?.changed[0]?.disabled, true);
85
- });
86
- test("delta: detects changed elements (value)", () => {
87
- const targetId = "tab-6";
88
- clearAllSnapshots();
89
- const initial = [
90
- { id: "w:1", role: "textbox", label: "Email", value: "", fingerprint: "textbox:email:form:0" },
91
- ];
92
- storeSnapshot(targetId, 'http://test.com', initial);
93
- const updated = [
94
- { id: "w:1", role: "textbox", label: "Email", value: "test@example.com", fingerprint: "textbox:email:form:0" },
95
- ];
96
- const result = computeDelta(targetId, 'http://test.com', updated);
97
- assert.ok(result !== null);
98
- assert.equal(result?.changed.length, 1, "Value change detected");
99
- assert.equal(result?.changed[0]?.value, "test@example.com");
100
- });
101
- test("delta: counts stable elements", () => {
102
- const targetId = "tab-7";
103
- clearAllSnapshots();
104
- const initial = [
105
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
106
- { id: "w:2", role: "link", label: "Home", fingerprint: "link:home:nav:1" },
107
- { id: "w:3", role: "textbox", label: "Email", fingerprint: "textbox:email:form:0" },
108
- ];
109
- storeSnapshot(targetId, 'http://test.com', initial);
110
- const updated = [
111
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
112
- { id: "w:2", role: "link", label: "Home", fingerprint: "link:home:nav:1" },
113
- { id: "w:3", role: "textbox", label: "Email", value: "test@example.com", fingerprint: "textbox:email:form:0" },
114
- ];
115
- const result = computeDelta(targetId, 'http://test.com', updated);
116
- assert.ok(result !== null);
117
- assert.equal(result?.stable_count, 2, "Two stable elements");
118
- assert.equal(result?.changed.length, 1);
119
- });
120
- test("delta: updates stored snapshot", () => {
121
- const targetId = "tab-8";
122
- clearAllSnapshots();
123
- const initial = [
124
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
125
- ];
126
- storeSnapshot(targetId, 'http://test.com', initial);
127
- const updated = [
128
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
129
- { id: "w:2", role: "link", label: "Home", fingerprint: "link:home:nav:1" },
130
- ];
131
- computeDelta(targetId, 'http://test.com', updated);
132
- // Second call should see no changes since snapshot was updated
133
- const secondCall = computeDelta(targetId, 'http://test.com', updated);
134
- assert.ok(secondCall !== null);
135
- assert.equal(secondCall?.added.length, 0);
136
- assert.equal(secondCall?.removed.length, 0);
137
- assert.equal(secondCall?.changed.length, 0);
138
- assert.equal(secondCall?.stable_count, 2);
139
- });
140
- test("delta: rich delta - first visit returns null", async () => {
141
- const targetId = "tab-9";
142
- clearAllSnapshots();
143
- const elements = [
144
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0", group: "utility", depth: 0 },
145
- ];
146
- const result = await computeRichDelta(targetId, 'http://test.com', elements);
147
- assert.equal(result, null, "First visit rich delta returns null");
148
- });
149
- test("delta: rich delta - basic changed properties", async () => {
150
- const targetId = "tab-10";
151
- clearAllSnapshots();
152
- const initial = [
153
- {
154
- id: "w:1",
155
- role: "button",
156
- label: "Submit",
157
- value: "",
158
- disabled: false,
159
- fingerprint: "button:submit:div:0",
160
- group: "utility",
161
- depth: 0
162
- },
163
- ];
164
- // Seed the snapshot first
165
- seedRichSnapshot(targetId, 'http://test.com', initial);
166
- const updated = [
167
- {
168
- id: "w:1",
169
- role: "button",
170
- label: "Submit",
171
- value: "",
172
- disabled: true,
173
- fingerprint: "button:submit:div:0",
174
- group: "utility",
175
- depth: 0
176
- },
177
- ];
178
- const result = await computeRichDelta(targetId, 'http://test.com', updated);
179
- assert.ok(result !== null);
180
- assert.ok(!("delta_timeout" in result));
181
- const diff = result;
182
- assert.equal(diff.changed.length, 1);
183
- assert.equal(diff.changed[0]?.ref, "w:1");
184
- assert.ok("disabled" in diff.changed[0]?.changes);
185
- assert.equal(diff.changed[0]?.changes?.disabled?.from, "false");
186
- assert.equal(diff.changed[0]?.changes?.disabled?.to, "true");
187
- });
188
- test("delta: rich delta - marks interactive elements as actionable", async () => {
189
- const targetId = "tab-11";
190
- clearAllSnapshots();
191
- const initial = [
192
- {
193
- id: "w:1",
194
- role: "button",
195
- label: "Submit",
196
- fingerprint: "button:submit:div:0",
197
- group: "utility",
198
- depth: 0
199
- },
200
- ];
201
- // Seed the snapshot first
202
- seedRichSnapshot(targetId, 'http://test.com', initial);
203
- const updated = [
204
- {
205
- id: "w:1",
206
- role: "button",
207
- label: "Submit",
208
- value: "",
209
- disabled: false, // Changed from undefined/missing to false
210
- fingerprint: "button:submit:div:0",
211
- group: "utility",
212
- depth: 0
213
- },
214
- ];
215
- const result = await computeRichDelta(targetId, 'http://test.com', updated);
216
- assert.ok(result !== null);
217
- assert.ok(!("delta_timeout" in result));
218
- const diff = result;
219
- assert.equal(diff.changed.length, 1);
220
- assert.equal(diff.changed[0]?.actionable, true);
221
- assert.equal(diff.changed[0]?.recommended_action, "click");
222
- });
223
- test("delta: rich delta - iframe tracking", async () => {
224
- const targetId = "tab-12";
225
- clearAllSnapshots();
226
- const initial = [
227
- {
228
- id: "w:1",
229
- role: "button",
230
- label: "Submit",
231
- frameUrl: "https://example.com",
232
- fingerprint: "button:submit:div:0",
233
- group: "utility",
234
- depth: 0
235
- },
236
- ];
237
- // Seed the snapshot first
238
- seedRichSnapshot(targetId, 'http://test.com', initial);
239
- const updated = [
240
- {
241
- id: "w:1",
242
- role: "button",
243
- label: "Submit",
244
- frameUrl: "https://example.com",
245
- fingerprint: "button:submit:div:0",
246
- group: "utility",
247
- depth: 0
248
- },
249
- {
250
- id: "w:2",
251
- role: "link",
252
- label: "Home",
253
- frameUrl: "https://iframe.com",
254
- fingerprint: "link:home:nav:1",
255
- group: "navigation",
256
- depth: 1
257
- },
258
- ];
259
- const result = await computeRichDelta(targetId, 'http://test.com', updated);
260
- assert.ok(result !== null);
261
- assert.ok(!("delta_timeout" in result));
262
- const diff = result;
263
- assert.ok(diff.iframes !== undefined);
264
- assert.equal(diff.iframes?.length, 1);
265
- assert.equal(diff.iframes?.[0]?.status, "added");
266
- assert.equal(diff.iframes?.[0]?.frameUrl, "https://iframe.com");
267
- });
268
- test("delta: clearSnapshot removes all data", () => {
269
- const targetId = "tab-13";
270
- const refs = [
271
- { id: "w:1", role: "button", label: "Submit", fingerprint: "button:submit:div:0" },
272
- ];
273
- storeSnapshot(targetId, 'http://test.com', refs);
274
- seedRichSnapshot(targetId, 'http://test.com', []);
275
- clearAllSnapshots();
276
- const result = computeDelta(targetId, 'http://test.com', refs);
277
- assert.equal(result, null, "Cache cleared");
278
- });
279
- //# sourceMappingURL=delta.test.js.map
@@ -1,15 +0,0 @@
1
- import CDP from "chrome-remote-interface";
2
- interface GroupEntry {
3
- groupName: string;
4
- tabIds: string[];
5
- }
6
- interface GroupStore {
7
- [windowId: number]: GroupEntry[];
8
- }
9
- export declare function saveGroup(windowId: number, groupName: string, tabIds: string[]): void;
10
- export declare function removeTabFromGroups(tabId: string): void;
11
- export declare function clearStore(): void;
12
- export declare function getStore(): GroupStore;
13
- export declare function restoreGroups(session: CDP.Client): Promise<void>;
14
- export {};
15
- //# sourceMappingURL=groups.d.ts.map
@@ -1,80 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import * as os from "node:os";
4
- const GROUPS_DIR = path.join(os.homedir(), ".Weavetab-system", "groups");
5
- const GROUPS_FILE = path.join(GROUPS_DIR, "groups.json");
6
- function ensureDir() {
7
- if (!fs.existsSync(GROUPS_DIR)) {
8
- fs.mkdirSync(GROUPS_DIR, { recursive: true });
9
- }
10
- }
11
- function readStore() {
12
- try {
13
- if (fs.existsSync(GROUPS_FILE)) {
14
- return JSON.parse(fs.readFileSync(GROUPS_FILE, "utf-8"));
15
- }
16
- }
17
- catch {
18
- // corrupted — reset
19
- }
20
- return {};
21
- }
22
- function writeStore(store) {
23
- ensureDir();
24
- fs.writeFileSync(GROUPS_FILE, JSON.stringify(store), "utf-8");
25
- }
26
- export function saveGroup(windowId, groupName, tabIds) {
27
- const store = readStore();
28
- if (!store[windowId])
29
- store[windowId] = [];
30
- const existing = store[windowId].find(g => g.groupName === groupName);
31
- if (existing) {
32
- existing.tabIds = tabIds;
33
- }
34
- else {
35
- store[windowId].push({ groupName, tabIds });
36
- }
37
- writeStore(store);
38
- }
39
- export function removeTabFromGroups(tabId) {
40
- const store = readStore();
41
- let changed = false;
42
- for (const windowId of Object.keys(store)) {
43
- const groups = store[Number(windowId)];
44
- for (const group of groups) {
45
- const idx = group.tabIds.indexOf(tabId);
46
- if (idx !== -1) {
47
- group.tabIds.splice(idx, 1);
48
- changed = true;
49
- }
50
- }
51
- store[Number(windowId)] = groups.filter(g => g.tabIds.length > 0);
52
- }
53
- if (changed)
54
- writeStore(store);
55
- }
56
- export function clearStore() {
57
- try {
58
- if (fs.existsSync(GROUPS_FILE))
59
- fs.unlinkSync(GROUPS_FILE);
60
- }
61
- catch { /* ignore */ }
62
- }
63
- export function getStore() {
64
- return readStore();
65
- }
66
- export async function restoreGroups(session) {
67
- const store = readStore();
68
- const entries = Object.entries(store).flatMap(([windowId, groups]) => groups.map(g => ({ windowId: Number(windowId), groupName: g.groupName, tabIds: g.tabIds })));
69
- if (entries.length === 0)
70
- return;
71
- try {
72
- const { sendToExtension } = await import("../cdp/helpers.js");
73
- await sendToExtension(session, {
74
- type: "Weavetab_RESTORE_GROUPS",
75
- groups: entries,
76
- });
77
- }
78
- catch { /* best-effort */ }
79
- }
80
- //# sourceMappingURL=groups.js.map
@@ -1,14 +0,0 @@
1
- /**
2
- * Weavetab — tools/accessibility.ts
3
- * browser_accessibility: returns the full Chrome accessibility tree via Accessibility.getFullAXTree.
4
- *
5
- * Use this to understand ARIA-heavy UIs when the standard DOM map is insufficient.
6
- * Weavetab by fy2ne
7
- */
8
- import CDP from "chrome-remote-interface";
9
- import type { Config } from "../config/loader.js";
10
- export interface AccessibilityResult {
11
- success: boolean;
12
- tree: any;
13
- }
14
- export declare function browserAccessibility(session: CDP.Client, _config: Config): Promise<AccessibilityResult>;
@@ -1,32 +0,0 @@
1
- export async function browserAccessibility(session, _config) {
2
- try {
3
- // Enable Accessibility domain
4
- await session.Accessibility.enable();
5
- const tree = await session.Accessibility.getFullAXTree();
6
- // Simplify tree for LLM consumption
7
- const simplify = (node) => {
8
- if (node.ignored)
9
- return null;
10
- const role = node.role?.value;
11
- const name = node.name?.value;
12
- const value = node.value?.value;
13
- const children = (node.children || []).map(simplify).filter(Boolean);
14
- if (!name && children.length === 0 && !value)
15
- return null; // skip noise
16
- return {
17
- role,
18
- name: name || undefined,
19
- value: value || undefined,
20
- nodeId: node.nodeId,
21
- backendDOMNodeId: node.backendDOMNodeId,
22
- children: children.length > 0 ? children : undefined
23
- };
24
- };
25
- const root = tree.nodes.find((n) => !n.parentId);
26
- const simplifiedTree = simplify(root);
27
- return { success: true, tree: simplifiedTree };
28
- }
29
- catch (error) {
30
- throw new Error(`Failed to get accessibility tree: ${error}`);
31
- }
32
- }
@@ -1,14 +0,0 @@
1
- import CDP from "chrome-remote-interface";
2
- export interface AskResult {
3
- success: true;
4
- response: string;
5
- timeout?: boolean;
6
- }
7
- export declare function browserAsk(session: CDP.Client, args: {
8
- question: string;
9
- }): Promise<AskResult | {
10
- success: false;
11
- error_code: string;
12
- message: string;
13
- }>;
14
- //# sourceMappingURL=ask.d.ts.map
package/dist/tools/ask.js DELETED
@@ -1,49 +0,0 @@
1
- // src/tools/ask.ts
2
- // browser_ask — renders ask UI in content.js via sendToExtension, polls result
3
- import { logAction } from "../audit/logger.js";
4
- import { sendToExtension } from "../cdp/helpers.js";
5
- function sleep(ms) {
6
- return new Promise(r => setTimeout(r, ms));
7
- }
8
- export async function browserAsk(session, args) {
9
- const { question } = args;
10
- const ASK_TIMEOUT_MS = 300000;
11
- const COUNTDOWN_SEC = 300;
12
- logAction("browser_ask", "prompting", question);
13
- // Show HUD hint + waiting state
14
- await sendToExtension(session, { type: 'Weavetab_STATE', state: 'waiting', hud: { action: question.slice(0, 40) + (question.length > 40 ? '...' : '') } });
15
- // Show ask UI via content.js
16
- await sendToExtension(session, { type: 'Weavetab_ASK', question }).catch(() => { });
17
- // Poll for result via DOM bridge (shared between isolated & main worlds)
18
- const start = Date.now();
19
- while (Date.now() - start < ASK_TIMEOUT_MS) {
20
- await sleep(500);
21
- try {
22
- const { result } = await session.Runtime.evaluate({
23
- expression: `(() => { try {
24
- var el = document.getElementById('__wt_ask_bridge');
25
- if (!el || el.dataset.status === 'pending') return null;
26
- return JSON.stringify({ status: el.dataset.status, result: el.dataset.result });
27
- } catch(e) { return null; } })()`,
28
- returnByValue: true,
29
- });
30
- if (result?.value) {
31
- const data = JSON.parse(result.value);
32
- if (data.status === 'submitted') {
33
- logAction("browser_ask", "answered", data.result);
34
- return { success: true, response: data.result };
35
- }
36
- if (data.status === 'cancelled' || data.status === 'timeout') {
37
- logAction("browser_ask", data.status, "");
38
- return { success: true, response: "", timeout: true };
39
- }
40
- }
41
- }
42
- catch {
43
- // polling error — retry
44
- }
45
- }
46
- logAction("browser_ask", "timeout", "");
47
- return { success: true, response: "", timeout: true };
48
- }
49
- //# sourceMappingURL=ask.js.map
@@ -1,33 +0,0 @@
1
- import CDP from "chrome-remote-interface";
2
- import type { Config } from "../config/loader.js";
3
- import type { ClickResult, WeaveError } from "./click.js";
4
- export interface ClickAndWaitOptions {
5
- /** Element identifier - can be id, label, intent, or selector */
6
- id?: string;
7
- label?: string;
8
- intent?: string;
9
- /** Direct coordinates bypass */
10
- x?: number;
11
- y?: number;
12
- /** Time to wait after click for page response (ms) */
13
- waitAfter?: number;
14
- /** Whether to wait for network idle after click */
15
- waitForNetwork?: boolean;
16
- /** Whether to return the page map after click */
17
- includeMap?: boolean;
18
- /** Fast mode - skip stability checks */
19
- fast?: boolean;
20
- /** Execute in a specific tab instead of active */
21
- tab_id?: string;
22
- }
23
- export interface ClickAndWaitResult extends ClickResult {
24
- /** Time waited after click */
25
- waited_ms: number;
26
- /** Whether network was idle after wait */
27
- network_idle?: boolean;
28
- }
29
- /**
30
- * Consolidated tool that combines element resolution, clicking, and waiting.
31
- * Eliminates 2-3 tool calls in the common pattern: find → click → wait
32
- */
33
- export declare function weaveClickAndWait(session: CDP.Client, args: ClickAndWaitOptions, config: Config): Promise<ClickAndWaitResult | WeaveError>;
@@ -1,149 +0,0 @@
1
- // src/tools/click_and_wait.ts
2
- // Consolidated tool: find element + click + wait for response in one CDP round-trip
3
- // Eliminates the common pattern: browser_map → browser_click → browser_wait
4
- import { buildActionMap, findBestMatch, safeSelector, toMarkdownTable } from "../cdp/walker.js";
5
- import { recordAction, trackToolCall, detectStuckLoop } from "../intelligence/trail.js";
6
- import { waitForDOMStable } from "../sensors/guard.js";
7
- import { waitForNetworkIdle } from "../sensors/wait.js";
8
- import { ghostMove, ghostClick } from "../overlay/ghost.js";
9
- import { cacheActionMap, getCachedActionMap } from "../state/cache.js";
10
- import { storeSnapshot, computeDelta } from "../state/delta.js";
11
- import { sessionRegistry } from "../state/session.js";
12
- import { getConfigAgentId } from "../config/loader.js";
13
- import { operationMonitor } from "../sensors/operation_monitor.js";
14
- /**
15
- * Consolidated tool that combines element resolution, clicking, and waiting.
16
- * Eliminates 2-3 tool calls in the common pattern: find → click → wait
17
- */
18
- export async function weaveClickAndWait(session, args, config) {
19
- const { id, label, intent, x, y, waitAfter = 500, waitForNetwork = true, includeMap = false, fast = false, tab_id } = args;
20
- const { Page, DOM, Input } = session;
21
- const startMs = Date.now();
22
- const targetId = sessionRegistry.getActive(getConfigAgentId(config))?.targetId ?? "default";
23
- const operationId = `clickAndWait-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
24
- operationMonitor.startOperation(operationId, 'browser_click_and_wait');
25
- // Handle tab switching if tab_id is provided
26
- let targetSession = session;
27
- if (tab_id) {
28
- const { connectToTab } = await import("../cdp/connector.js");
29
- const client = await connectToTab(tab_id);
30
- targetSession = client.session;
31
- }
32
- // Check for stuck loop before processing
33
- const stuckCheck = detectStuckLoop();
34
- if (stuckCheck.stuck) {
35
- return {
36
- success: false,
37
- error_code: "STUCK_LOOP",
38
- message: stuckCheck.diagnosis || "Agent is stuck in a loop",
39
- suggestion: "Try a different approach or reset the loop counter",
40
- };
41
- }
42
- // Get initial URL
43
- const initialUrl = (await targetSession.Page.getFrameTree()).frameTree.frame.url;
44
- // Build or get cached action map
45
- let map = getCachedActionMap(targetId, initialUrl);
46
- if (!map) {
47
- map = await buildActionMap(targetSession, { lite: true }, targetId);
48
- cacheActionMap(targetId, map);
49
- }
50
- await storeSnapshot(targetId, initialUrl, map.elements);
51
- // Resolve element
52
- let element;
53
- if (id) {
54
- element = map.elements.find((el) => el.id === id || el.id.endsWith(id));
55
- }
56
- if (!element && label) {
57
- element = findBestMatch(map.elements, label);
58
- }
59
- if (!element && intent) {
60
- element = findBestMatch(map.elements, intent);
61
- }
62
- if (!element && !x && !y) {
63
- return {
64
- success: false,
65
- error_code: "ELEMENT_NOT_FOUND",
66
- message: `Element not found with id="${id}", label="${label}", or intent="${intent}"`,
67
- suggestion: "Try browser_map to see available elements, or use x/y coordinates",
68
- };
69
- }
70
- const clickX = x ?? element?.x;
71
- const clickY = y ?? element?.y;
72
- const selector = element ? safeSelector(element) : undefined;
73
- if (!clickX || !clickY) {
74
- return {
75
- success: false,
76
- error_code: "NO_COORDINATES",
77
- message: "Could not determine click coordinates",
78
- suggestion: "Provide explicit x/y coordinates or ensure element has position data",
79
- };
80
- }
81
- // Perform click with ghost move
82
- await ghostMove(targetSession, clickX, clickY, config, element?.label || "target");
83
- await ghostClick(targetSession, clickX, clickY, { pointerType: 'mouse' });
84
- await new Promise(r => setTimeout(r, 30 + Math.random() * 40));
85
- await targetSession.Input.dispatchMouseEvent({
86
- type: 'mouseReleased',
87
- x: clickX,
88
- y: clickY,
89
- button: 'left',
90
- clickCount: 1,
91
- pointerType: 'mouse'
92
- });
93
- // Wait for response
94
- const waitStart = Date.now();
95
- if (waitForNetwork) {
96
- await Promise.all([
97
- waitForDOMStable(targetSession, 50, 300),
98
- waitForNetworkIdle(targetSession, waitAfter, waitAfter * 2).catch(() => { })
99
- ]);
100
- }
101
- else {
102
- await new Promise(r => setTimeout(r, waitAfter));
103
- }
104
- const waitedMs = Date.now() - waitStart;
105
- // Check result
106
- const finalUrl = (await targetSession.Page.getFrameTree()).frameTree.frame.url;
107
- const urlChanged = finalUrl !== initialUrl;
108
- let newMap = map;
109
- let domChanged = false;
110
- if (urlChanged || includeMap) {
111
- newMap = await buildActionMap(targetSession, { lite: true }, targetId);
112
- cacheActionMap(targetId, newMap);
113
- const delta = computeDelta(targetId, initialUrl, newMap.elements);
114
- domChanged = delta ? delta.added.length + delta.removed.length + delta.changed.length > 0 : urlChanged;
115
- }
116
- else {
117
- const delta = computeDelta(targetId, initialUrl, map.elements);
118
- domChanged = delta ? delta.added.length + delta.removed.length + delta.changed.length > 0 : false;
119
- }
120
- const executionMs = Date.now() - startMs;
121
- // Track tool call
122
- trackToolCall("browser_click_and_wait", element?.id || id || label || "coordinates", {
123
- success: true,
124
- urlChanged
125
- });
126
- recordAction({
127
- timestamp: new Date().toISOString(),
128
- tool: "browser_click_and_wait",
129
- input: { ref: element?.id || id || label, waitAfter, waitForNetwork },
130
- result: { success: true, urlChanged, domChanged, waitedMs },
131
- });
132
- operationMonitor.endOperation(operationId);
133
- const result = {
134
- success: true,
135
- clicked: element?.label || "coordinates",
136
- ref: element?.id || id || "coordinates",
137
- execution_ms: executionMs,
138
- tab_id: targetId,
139
- url: finalUrl,
140
- title: newMap?.title || "",
141
- url_changed: urlChanged,
142
- ...(includeMap ? { page_map: newMap ? toMarkdownTable(newMap.elements, finalUrl, newMap.title) : "" } : {}),
143
- dom_changed: domChanged,
144
- stuck_warning: false,
145
- waited_ms: waitedMs,
146
- network_idle: waitForNetwork,
147
- };
148
- return result;
149
- }