@weavetab/mcp 2.5.0-beta.2 → 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.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +6 -6
- package/LICENSE +1 -1
- package/README.md +158 -961
- package/SECURITY.md +33 -22
- package/TROUBLESHOOTING.md +2 -2
- package/dist/cdp/bridge.js +2 -1
- package/dist/cdp/connector.d.ts +2 -0
- package/dist/cdp/connector.js +8 -4
- package/dist/cdp/helpers.d.ts +4 -0
- package/dist/cdp/helpers.js +181 -0
- package/dist/cdp/omni_broker.d.ts +1 -1
- package/dist/cdp/omni_broker.js +1 -1
- package/dist/cdp/walker.d.ts +25 -1
- package/dist/cdp/walker.js +304 -7
- package/dist/cli/plugin.js +24 -17
- package/dist/cli/updater.d.ts +1 -1
- package/dist/cli/updater.js +27 -7
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.js +41 -2
- package/dist/desktop/discovery.d.ts +44 -0
- package/dist/desktop/discovery.js +364 -0
- package/dist/index.js +95 -15
- package/dist/intelligence/marks.d.ts +36 -0
- package/dist/intelligence/marks.js +30 -0
- package/dist/intelligence/patternCompiler.d.ts +118 -0
- package/dist/intelligence/patternCompiler.js +259 -0
- package/dist/intelligence/sessionMemory.d.ts +2 -0
- package/dist/intelligence/sessionMemory.js +18 -8
- package/dist/overlay/injector.js +2 -2
- package/dist/plugin/interface.d.ts +76 -2
- package/dist/plugin/loader.d.ts +15 -1
- package/dist/plugin/loader.js +217 -70
- package/dist/plugin/pipeline.d.ts +75 -0
- package/dist/plugin/pipeline.js +183 -0
- package/dist/plugin/registry.js +3 -2
- package/dist/security/secrets.d.ts +1 -0
- package/dist/security/secrets.js +13 -0
- package/dist/sensors/actionability.js +1 -2
- package/dist/sensors/guard.js +4 -10
- package/dist/sensors/mutations.js +12 -0
- package/dist/sensors/operation_monitor.js +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +428 -156
- package/dist/state/agent.d.ts +1 -0
- package/dist/state/agent.js +3 -0
- package/dist/state/delta.d.ts +12 -4
- package/dist/state/delta.js +67 -14
- package/dist/state/session.d.ts +6 -0
- package/dist/state/session.js +27 -0
- package/dist/tools/browser_detect.d.ts +16 -3
- package/dist/tools/browser_detect.js +50 -5
- package/dist/tools/burst.d.ts +17 -8
- package/dist/tools/burst.js +236 -77
- package/dist/tools/checkpoint.d.ts +38 -0
- package/dist/tools/checkpoint.js +271 -0
- package/dist/tools/click.d.ts +1 -0
- package/dist/tools/click.js +74 -70
- package/dist/tools/design_extract.js +1 -1
- package/dist/tools/eval.js +1 -1
- package/dist/tools/fill.d.ts +20 -1
- package/dist/tools/fill.js +199 -40
- package/dist/tools/find.d.ts +16 -0
- package/dist/tools/find.js +67 -44
- package/dist/tools/github/index.d.ts +19 -4
- package/dist/tools/github/index.js +40 -4
- package/dist/tools/highlight.d.ts +6 -2
- package/dist/tools/highlight.js +158 -72
- package/dist/tools/inspect.js +1 -1
- package/dist/tools/key.js +65 -56
- package/dist/tools/navigate.js +29 -34
- package/dist/tools/pdf.js +21 -13
- package/dist/tools/pointer.d.ts +18 -3
- package/dist/tools/pointer.js +89 -1
- package/dist/tools/read.d.ts +28 -8
- package/dist/tools/read.js +230 -56
- package/dist/tools/scrape.js +67 -13
- package/dist/tools/screenshot.js +21 -16
- package/dist/tools/scroll.js +6 -11
- package/dist/tools/select.js +8 -2
- package/dist/tools/snapshot.js +3 -34
- package/dist/tools/tabs.js +14 -6
- package/dist/tools/thought.d.ts +2 -0
- package/dist/tools/thought.js +13 -14
- package/dist/tools/type.d.ts +2 -0
- package/dist/tools/type.js +107 -58
- package/dist/tools/type_secret.js +42 -76
- package/dist/tools/upload.js +1 -1
- package/dist/tools/video_compiler.d.ts +1 -1
- package/dist/tools/video_compiler.js +11 -12
- package/dist/version.d.ts +5 -0
- package/dist/version.js +5 -0
- package/docs/DOCUMENTATION.md +21 -32
- package/docs/PLUGINS.md +121 -0
- package/docs/TOOLS.md +56 -0
- package/docs/architecture/blind-injection.md +83 -20
- package/docs/architecture/overview.md +49 -49
- package/docs/configuration/folders.md +55 -54
- package/docs/desktop-automation/electron-apps.md +217 -162
- package/docs/get-started/introduction.md +60 -60
- package/docs/intelligence/site-profiles.md +151 -0
- package/docs/tools/tools.md +631 -293
- package/docs/troubleshooting/trouble-loop.md +31 -31
- package/ext-dist/background.js +10 -62
- package/ext-dist/content.js +333 -920
- package/ext-dist/hud/hud.js +9 -9
- package/ext-dist/manifest.json +2 -6
- package/ext-dist/styles.css +6 -1
- package/mcp.json +101 -67
- package/package.json +5 -6
- package/server.json +3 -3
- package/ext-dist/sidepanel/sidepanel.js +0 -25
- package/ext-dist/sidepanel.html +0 -547
package/dist/tools/burst.js
CHANGED
|
@@ -28,70 +28,88 @@ import { buildActionMap } from "../cdp/walker.js";
|
|
|
28
28
|
import { sessionRegistry } from "../state/session.js";
|
|
29
29
|
import { getConfigAgentId, getConfigBrowserType } from "../config/loader.js";
|
|
30
30
|
import { sendToExtension } from "../cdp/helpers.js";
|
|
31
|
-
import { resetLoopCounter } from "../intelligence/trail.js";
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
import { resetLoopCounter, getTrail } from "../intelligence/trail.js";
|
|
32
|
+
function extractTarget(params) {
|
|
33
|
+
const target = {};
|
|
34
|
+
if (!params || typeof params !== "object")
|
|
35
|
+
return target;
|
|
36
|
+
if (params.ref !== undefined)
|
|
37
|
+
target.ref = params.ref;
|
|
38
|
+
if (params.id !== undefined)
|
|
39
|
+
target.id = params.id;
|
|
40
|
+
if (params.target !== undefined) {
|
|
41
|
+
if (typeof params.target === "string" && params.target.startsWith("w:"))
|
|
42
|
+
target.ref = params.target;
|
|
43
|
+
else
|
|
44
|
+
target.selector = params.target;
|
|
45
|
+
}
|
|
46
|
+
if (params.selector !== undefined)
|
|
47
|
+
target.selector = params.selector;
|
|
48
|
+
if (params.label !== undefined)
|
|
49
|
+
target.label = params.label;
|
|
50
|
+
if (params.x !== undefined)
|
|
51
|
+
target.x = params.x;
|
|
52
|
+
if (params.y !== undefined)
|
|
53
|
+
target.y = params.y;
|
|
54
|
+
return target;
|
|
55
|
+
}
|
|
35
56
|
function expandMacro(step) {
|
|
57
|
+
const args = step.args || {};
|
|
36
58
|
if (step.tool === "type_and_send") {
|
|
37
|
-
const {
|
|
38
|
-
|
|
39
|
-
throw new Error("type_and_send macro failed: no target specified (requires id, label, or x/y)");
|
|
40
|
-
}
|
|
59
|
+
const { text, pressEnter = true } = args;
|
|
60
|
+
const target = extractTarget(args);
|
|
41
61
|
if (text === undefined) {
|
|
42
|
-
throw new Error("type_and_send
|
|
62
|
+
throw new Error("type_and_send failed: text is required");
|
|
43
63
|
}
|
|
44
|
-
const typeArgs = { text, noRetry: true };
|
|
45
|
-
if (x !== undefined)
|
|
46
|
-
typeArgs.x = x;
|
|
47
|
-
if (y !== undefined)
|
|
48
|
-
typeArgs.y = y;
|
|
49
|
-
if (id)
|
|
50
|
-
typeArgs.id = id;
|
|
51
|
-
if (label)
|
|
52
|
-
typeArgs.label = label;
|
|
64
|
+
const typeArgs = { ...target, text, noRetry: true };
|
|
53
65
|
const steps = [{ tool: "browser_type", args: typeArgs }];
|
|
54
66
|
if (pressEnter)
|
|
55
67
|
steps.push({ tool: "browser_key", args: { key: "Enter" } });
|
|
56
68
|
return steps;
|
|
57
69
|
}
|
|
58
70
|
if (step.tool === "navigate_and_read") {
|
|
59
|
-
const { url } =
|
|
71
|
+
const { url } = args;
|
|
60
72
|
return [
|
|
61
73
|
{ tool: "browser_go", args: { url } },
|
|
62
74
|
{ tool: "browser_map", args: {} },
|
|
63
75
|
];
|
|
64
76
|
}
|
|
65
77
|
if (step.tool === "click_and_wait") {
|
|
66
|
-
const {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return [
|
|
79
|
-
{ tool: "browser_click", args: clickArgs },
|
|
80
|
-
];
|
|
78
|
+
const { wait_for, wait_value, wait_after, waitAfter } = args;
|
|
79
|
+
const target = extractTarget(args);
|
|
80
|
+
const clickArgs = {
|
|
81
|
+
...target,
|
|
82
|
+
waitForNetwork: true,
|
|
83
|
+
waitAfter: wait_after ?? waitAfter ?? 500,
|
|
84
|
+
};
|
|
85
|
+
const steps = [{ tool: "browser_click", args: clickArgs }];
|
|
86
|
+
if (wait_for) {
|
|
87
|
+
steps.push({ tool: "browser_wait", args: { wait_for, value: wait_value } });
|
|
88
|
+
}
|
|
89
|
+
return steps;
|
|
81
90
|
}
|
|
82
91
|
if (step.tool === "scroll_and_read") {
|
|
83
|
-
const { direction, distance } =
|
|
92
|
+
const { direction, distance } = args;
|
|
84
93
|
return [
|
|
85
94
|
{ tool: "browser_scroll", args: { direction, distance } },
|
|
86
95
|
{ tool: "browser_map", args: {} },
|
|
87
96
|
];
|
|
88
97
|
}
|
|
89
98
|
if (step.tool === "fill_form") {
|
|
90
|
-
const { fields, submit } =
|
|
99
|
+
const { fields, submit } = args;
|
|
91
100
|
const steps = [];
|
|
92
|
-
if (fields
|
|
93
|
-
for (const
|
|
94
|
-
|
|
101
|
+
if (Array.isArray(fields)) {
|
|
102
|
+
for (const f of fields) {
|
|
103
|
+
if (f && typeof f === "object") {
|
|
104
|
+
const target = extractTarget(f);
|
|
105
|
+
steps.push({ tool: "browser_fill", args: { ...target, value: f.value } });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (fields && typeof fields === "object") {
|
|
110
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
111
|
+
const target = key.startsWith("w:") ? { ref: key } : { id: key };
|
|
112
|
+
steps.push({ tool: "browser_fill", args: { ...target, value } });
|
|
95
113
|
}
|
|
96
114
|
}
|
|
97
115
|
if (submit) {
|
|
@@ -100,18 +118,13 @@ function expandMacro(step) {
|
|
|
100
118
|
return steps;
|
|
101
119
|
}
|
|
102
120
|
if (step.tool === "drag_and_drop") {
|
|
103
|
-
const {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
121
|
+
const { end_id, end_ref, end_x, end_y } = args;
|
|
122
|
+
const target = extractTarget(args);
|
|
123
|
+
const pointerArgs = { action: "drag_and_drop", ...target };
|
|
124
|
+
if (end_ref)
|
|
125
|
+
pointerArgs.end_ref = end_ref;
|
|
107
126
|
if (end_id)
|
|
108
|
-
pointerArgs.
|
|
109
|
-
if (label)
|
|
110
|
-
pointerArgs.label = label;
|
|
111
|
-
if (x !== undefined)
|
|
112
|
-
pointerArgs.x = x;
|
|
113
|
-
if (y !== undefined)
|
|
114
|
-
pointerArgs.y = y;
|
|
127
|
+
pointerArgs.end_id = end_id;
|
|
115
128
|
if (end_x !== undefined)
|
|
116
129
|
pointerArgs.end_x = end_x;
|
|
117
130
|
if (end_y !== undefined)
|
|
@@ -119,53 +132,163 @@ function expandMacro(step) {
|
|
|
119
132
|
return [{ tool: "browser_pointer", args: pointerArgs }];
|
|
120
133
|
}
|
|
121
134
|
if (step.tool === "hover_and_read") {
|
|
122
|
-
const {
|
|
123
|
-
const
|
|
124
|
-
if (id)
|
|
125
|
-
pointerArgs.ref = id;
|
|
126
|
-
if (label)
|
|
127
|
-
pointerArgs.label = label;
|
|
128
|
-
if (x !== undefined)
|
|
129
|
-
pointerArgs.x = x;
|
|
130
|
-
if (y !== undefined)
|
|
131
|
-
pointerArgs.y = y;
|
|
135
|
+
const { holdMs = 300 } = args;
|
|
136
|
+
const target = extractTarget(args);
|
|
132
137
|
return [
|
|
133
|
-
{ tool: "browser_pointer", args:
|
|
138
|
+
{ tool: "browser_pointer", args: { action: "hover", holdMs, ...target } },
|
|
134
139
|
{ tool: "browser_map", args: {} },
|
|
135
140
|
];
|
|
136
141
|
}
|
|
137
142
|
return [];
|
|
138
143
|
}
|
|
144
|
+
function normalizeRawSteps(raw) {
|
|
145
|
+
const norm = [];
|
|
146
|
+
for (const item of raw) {
|
|
147
|
+
if (!item || typeof item !== "object")
|
|
148
|
+
continue;
|
|
149
|
+
const entry = item;
|
|
150
|
+
const tool = (entry.tool || entry.action);
|
|
151
|
+
if (!tool)
|
|
152
|
+
continue;
|
|
153
|
+
let stepArgs = {};
|
|
154
|
+
if (entry.args && typeof entry.args === "object" && !Array.isArray(entry.args)) {
|
|
155
|
+
stepArgs = { ...entry.args };
|
|
156
|
+
}
|
|
157
|
+
for (const [k, v] of Object.entries(entry)) {
|
|
158
|
+
if (k === "tool" || k === "args")
|
|
159
|
+
continue;
|
|
160
|
+
if (stepArgs[k] === undefined)
|
|
161
|
+
stepArgs[k] = v;
|
|
162
|
+
}
|
|
163
|
+
norm.push({ tool, args: stepArgs });
|
|
164
|
+
}
|
|
165
|
+
return norm;
|
|
166
|
+
}
|
|
167
|
+
function extractArgs(step) {
|
|
168
|
+
const s = step;
|
|
169
|
+
const knownKeys = [
|
|
170
|
+
'arguments', 'args', 'mcp_arguments', 'input',
|
|
171
|
+
'params', 'parameters', 'tool_args', 'toolInput',
|
|
172
|
+
'data', 'payload', 'options',
|
|
173
|
+
];
|
|
174
|
+
for (const key of knownKeys) {
|
|
175
|
+
const val = s[key];
|
|
176
|
+
if (val !== null && val !== undefined && typeof val === 'object' && !Array.isArray(val)) {
|
|
177
|
+
return val;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const metaKeys = new Set([
|
|
181
|
+
'tool', 'result', 'timestamp', 'type', 'id',
|
|
182
|
+
'status', 'error', 'duration', 'startTime', 'endTime',
|
|
183
|
+
'session', 'tabId', 'targetId',
|
|
184
|
+
]);
|
|
185
|
+
for (const key of Object.keys(s)) {
|
|
186
|
+
if (metaKeys.has(key))
|
|
187
|
+
continue;
|
|
188
|
+
const val = s[key];
|
|
189
|
+
if (val !== null && val !== undefined && typeof val === 'object' && !Array.isArray(val)) {
|
|
190
|
+
return val;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return {};
|
|
194
|
+
}
|
|
195
|
+
const BURST_TOOLS = new Set([
|
|
196
|
+
"browser_click", "browser_type", "browser_navigate", "browser_go",
|
|
197
|
+
"browser_key", "browser_scroll", "browser_wait", "browser_select",
|
|
198
|
+
"browser_pointer", "browser_eval", "browser_console", "browser_find",
|
|
199
|
+
"browser_fill", "browser_type_secret", "browser_inspect",
|
|
200
|
+
"browser_screenshot", "browser_storage", "browser_cookies",
|
|
201
|
+
"browser_highlight", "browser_scrape",
|
|
202
|
+
"browser_canvas", "browser_performance", "browser_snapshot",
|
|
203
|
+
"browser_pdf", "browser_dialog", "browser_upload", "browser_automation",
|
|
204
|
+
"browser_viewport", "browser_clipboard", "browser_detect",
|
|
205
|
+
"browser_recording",
|
|
206
|
+
"type_and_send", "navigate_and_read", "click_and_wait",
|
|
207
|
+
"scroll_and_read", "fill_form", "drag_and_drop", "hover_and_read",
|
|
208
|
+
]);
|
|
209
|
+
export function compileTraceToMacro(steps) {
|
|
210
|
+
const macro = [];
|
|
211
|
+
let lastKey = "";
|
|
212
|
+
steps.forEach((step, idx) => {
|
|
213
|
+
if (step.result && !step.result.success)
|
|
214
|
+
return;
|
|
215
|
+
if (step.tool === "browser_map") {
|
|
216
|
+
if (idx === steps.length - 1) {
|
|
217
|
+
macro.push({ tool: "browser_map", args: step.input || {} });
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (BURST_TOOLS.has(step.tool)) {
|
|
222
|
+
const args = extractArgs(step);
|
|
223
|
+
const key = `${step.tool}:${JSON.stringify(args)}`;
|
|
224
|
+
if (key !== lastKey) {
|
|
225
|
+
macro.push({ tool: step.tool, args });
|
|
226
|
+
lastKey = key;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
return macro;
|
|
231
|
+
}
|
|
139
232
|
export async function browserBurst(session, args, config) {
|
|
140
|
-
|
|
141
|
-
|
|
233
|
+
let rawSteps = args.steps || args.actions;
|
|
234
|
+
let compiledSteps;
|
|
235
|
+
if (args.compile_from_history) {
|
|
236
|
+
const trail = getTrail();
|
|
237
|
+
const limit = args.history_limit ?? 20;
|
|
238
|
+
const slice = limit > 0 ? trail.slice(-limit) : trail;
|
|
239
|
+
compiledSteps = compileTraceToMacro(slice);
|
|
240
|
+
if (args.dry_run) {
|
|
241
|
+
return {
|
|
242
|
+
success: true,
|
|
243
|
+
steps_completed: 0,
|
|
244
|
+
results: [],
|
|
245
|
+
aborted: false,
|
|
246
|
+
compiled_steps: compiledSteps,
|
|
247
|
+
message: `compiled ${compiledSteps.length} macro steps from history`,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (!rawSteps || rawSteps.length === 0) {
|
|
251
|
+
rawSteps = compiledSteps;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const normalized = normalizeRawSteps(rawSteps || []);
|
|
255
|
+
if (normalized.length === 0) {
|
|
256
|
+
return {
|
|
257
|
+
success: true,
|
|
258
|
+
steps_completed: 0,
|
|
259
|
+
results: [],
|
|
260
|
+
aborted: false,
|
|
261
|
+
compiled_steps: compiledSteps,
|
|
262
|
+
message: args.compile_from_history ? "no actionable steps found in history" : "no steps provided",
|
|
263
|
+
};
|
|
142
264
|
}
|
|
143
|
-
// Expand macro steps into primitive steps first
|
|
144
265
|
const steps = [];
|
|
145
266
|
const MACRO_TOOLS = new Set(["type_and_send", "navigate_and_read", "click_and_wait", "scroll_and_read", "fill_form", "drag_and_drop", "hover_and_read"]);
|
|
146
|
-
for (const step of
|
|
267
|
+
for (const step of normalized) {
|
|
147
268
|
if (MACRO_TOOLS.has(step.tool)) {
|
|
148
269
|
steps.push(...expandMacro(step));
|
|
149
270
|
}
|
|
150
271
|
else {
|
|
151
272
|
steps.push({
|
|
152
273
|
tool: step.tool,
|
|
153
|
-
args: JSON.parse(JSON.stringify(step.args || {}))
|
|
274
|
+
args: JSON.parse(JSON.stringify(step.args || {})),
|
|
154
275
|
});
|
|
155
276
|
}
|
|
156
277
|
}
|
|
157
|
-
const { batch } = args;
|
|
158
|
-
|
|
278
|
+
const { batch, stop_on_error } = args;
|
|
279
|
+
const stopOnError = stop_on_error !== false;
|
|
159
280
|
if (batch) {
|
|
160
281
|
for (const step of steps) {
|
|
161
|
-
if (step.args.fast === undefined)
|
|
282
|
+
if (step.args.fast === undefined)
|
|
162
283
|
step.args.fast = true;
|
|
163
|
-
}
|
|
164
284
|
}
|
|
165
285
|
}
|
|
166
286
|
const results = [];
|
|
167
287
|
let stepsCompleted = 0;
|
|
168
|
-
await sendToExtension(session, {
|
|
288
|
+
await sendToExtension(session, {
|
|
289
|
+
type: 'Weavetab_STATE',
|
|
290
|
+
hud: { action: `running ${steps.length} steps ${batch ? 'in batch' : 'in sequence'}...` },
|
|
291
|
+
});
|
|
169
292
|
resetLoopCounter("burst");
|
|
170
293
|
for (let i = 0; i < steps.length; i++) {
|
|
171
294
|
const step = steps[i];
|
|
@@ -305,38 +428,74 @@ export async function browserBurst(session, args, config) {
|
|
|
305
428
|
results.push({ step: i + 1, tool: step.tool, success: false, error: stepError });
|
|
306
429
|
stepsCompleted++;
|
|
307
430
|
logAction("browser_burst", `step_${i + 1}`, `error: ${stepError}`);
|
|
431
|
+
if (stopOnError) {
|
|
432
|
+
await sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } });
|
|
433
|
+
return {
|
|
434
|
+
success: false,
|
|
435
|
+
steps_completed: stepsCompleted,
|
|
436
|
+
results,
|
|
437
|
+
aborted: true,
|
|
438
|
+
abort_reason: `halted on step ${i + 1} (${step.tool}): ${stepError}`,
|
|
439
|
+
compiled_steps: compiledSteps,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
308
442
|
continue;
|
|
309
443
|
}
|
|
310
444
|
const resultObj = result && typeof result === "object" ? result : {};
|
|
311
445
|
const isError = resultObj.success === false;
|
|
446
|
+
const errDetail = resultObj.message || resultObj.stuck_hint || undefined;
|
|
312
447
|
results.push({
|
|
313
448
|
step: i + 1,
|
|
314
449
|
tool: step.tool,
|
|
315
450
|
success: !isError,
|
|
316
451
|
result: isError ? undefined : result,
|
|
317
|
-
error: isError ?
|
|
452
|
+
error: isError ? errDetail : undefined,
|
|
318
453
|
});
|
|
319
454
|
stepsCompleted++;
|
|
455
|
+
if (isError && stopOnError) {
|
|
456
|
+
logAction("browser_burst", `step_${i + 1}`, `halted on error: ${errDetail}`);
|
|
457
|
+
await sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } });
|
|
458
|
+
return {
|
|
459
|
+
success: false,
|
|
460
|
+
steps_completed: stepsCompleted,
|
|
461
|
+
results,
|
|
462
|
+
aborted: true,
|
|
463
|
+
abort_reason: `halted on step ${i + 1} (${step.tool}): ${errDetail ?? "action failed"}`,
|
|
464
|
+
compiled_steps: compiledSteps,
|
|
465
|
+
};
|
|
466
|
+
}
|
|
320
467
|
}
|
|
321
468
|
catch (err) {
|
|
322
|
-
|
|
323
|
-
|
|
469
|
+
const errMsg = err?.message ?? String(err);
|
|
470
|
+
logAction("browser_burst", `step_${i + 1}`, `exception: ${errMsg}`);
|
|
471
|
+
results.push({ step: i + 1, tool: step.tool, success: false, error: `Exception: ${errMsg}` });
|
|
324
472
|
stepsCompleted++;
|
|
473
|
+
if (stopOnError) {
|
|
474
|
+
await sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } });
|
|
475
|
+
return {
|
|
476
|
+
success: false,
|
|
477
|
+
steps_completed: stepsCompleted,
|
|
478
|
+
results,
|
|
479
|
+
aborted: true,
|
|
480
|
+
abort_reason: `exception on step ${i + 1} (${step.tool}): ${errMsg}`,
|
|
481
|
+
compiled_steps: compiledSteps,
|
|
482
|
+
};
|
|
483
|
+
}
|
|
325
484
|
}
|
|
326
485
|
logAction("browser_burst", `step_${i + 1}/${steps.length}`, step.tool);
|
|
327
486
|
}
|
|
328
|
-
// If batch was used, update cache once at the end
|
|
329
487
|
if (batch) {
|
|
330
488
|
const targetId = sessionRegistry.getActive(getConfigAgentId(config))?.targetId || "default";
|
|
331
489
|
const map = await buildActionMap(session, { lite: true }, targetId);
|
|
332
490
|
cacheActionMap(targetId, map);
|
|
333
491
|
}
|
|
334
492
|
await sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } });
|
|
335
|
-
const
|
|
493
|
+
const allPassed = results.length > 0 && results.every(r => r.success);
|
|
336
494
|
return {
|
|
337
|
-
success:
|
|
495
|
+
success: allPassed,
|
|
338
496
|
steps_completed: stepsCompleted,
|
|
339
497
|
results,
|
|
340
498
|
aborted: false,
|
|
499
|
+
compiled_steps: compiledSteps,
|
|
341
500
|
};
|
|
342
501
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weavetab — tools/checkpoint.ts
|
|
3
|
+
* browser_checkpoint: Session time-travel and rollback.
|
|
4
|
+
*
|
|
5
|
+
* Captures and restores named checkpoints of browser state:
|
|
6
|
+
* - Cookies (HttpOnly and Secure via CDP Network)
|
|
7
|
+
* - LocalStorage & SessionStorage
|
|
8
|
+
* - URL, page title, and viewport scroll position
|
|
9
|
+
* - Optional lightweight DOM snapshot
|
|
10
|
+
*
|
|
11
|
+
* Saves tokens and time when trial-and-error automation branches fail.
|
|
12
|
+
*
|
|
13
|
+
* Weavetab by fy2ne
|
|
14
|
+
*/
|
|
15
|
+
import CDP from "chrome-remote-interface";
|
|
16
|
+
import type { Config } from "../config/loader.js";
|
|
17
|
+
export interface CheckpointData {
|
|
18
|
+
name: string;
|
|
19
|
+
url: string;
|
|
20
|
+
title: string;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
cookies: any[];
|
|
23
|
+
localStorage: Record<string, string>;
|
|
24
|
+
sessionStorage: Record<string, string>;
|
|
25
|
+
scroll?: {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
};
|
|
29
|
+
domSnapshot?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface CheckpointArgs {
|
|
32
|
+
action: "save" | "restore" | "list" | "delete";
|
|
33
|
+
name?: string;
|
|
34
|
+
includeDom?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare function getCheckpointsForTarget(targetId: string): Map<string, CheckpointData>;
|
|
37
|
+
export declare function clearAllCheckpoints(): void;
|
|
38
|
+
export declare function browserCheckpoint(session: CDP.Client, args: CheckpointArgs, config: Config): Promise<any>;
|