@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.
- package/AGENTS.md +2 -1
- package/ARCHITECTURE.md +6 -6
- package/LICENSE +1 -1
- package/README.md +164 -802
- package/SECURITY.md +33 -22
- package/TROUBLESHOOTING.md +3 -3
- package/dist/cdp/bridge.d.ts +10 -0
- package/dist/cdp/bridge.js +285 -78
- package/dist/cdp/connector.d.ts +7 -3
- package/dist/cdp/connector.js +196 -75
- package/dist/cdp/helpers.d.ts +4 -0
- package/dist/cdp/helpers.js +181 -0
- package/dist/cdp/lock.d.ts +9 -6
- package/dist/cdp/lock.js +72 -59
- package/dist/cdp/omni_broker.d.ts +2 -1
- package/dist/cdp/omni_broker.js +13 -7
- package/dist/cdp/profiles.d.ts +10 -0
- package/dist/cdp/profiles.js +65 -0
- package/dist/cdp/walker.d.ts +25 -1
- package/dist/cdp/walker.js +354 -7
- package/dist/cli/plugin.d.ts +0 -2
- package/dist/cli/plugin.js +51 -696
- package/dist/cli/updater.d.ts +1 -1
- package/dist/cli/updater.js +27 -7
- package/dist/config/loader.d.ts +33 -6
- package/dist/config/loader.js +174 -22
- package/dist/desktop/discovery.d.ts +44 -0
- package/dist/desktop/discovery.js +364 -0
- package/dist/index.js +140 -64
- 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/ghost.js +2 -2
- package/dist/overlay/injector.js +3 -5
- package/dist/plugin/extension_bridge.d.ts +40 -0
- package/dist/plugin/extension_bridge.js +158 -0
- package/dist/plugin/interface.d.ts +151 -15
- package/dist/plugin/loader.d.ts +19 -1
- package/dist/plugin/loader.js +331 -63
- package/dist/plugin/pipeline.d.ts +75 -0
- package/dist/plugin/pipeline.js +183 -0
- package/dist/plugin/registry.js +12 -1
- package/dist/plugin/storage.d.ts +51 -0
- package/dist/plugin/storage.js +164 -0
- 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 +600 -236
- 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 +8 -2
- package/dist/state/session.js +60 -13
- package/dist/tools/browser_detect.d.ts +16 -2
- package/dist/tools/browser_detect.js +54 -6
- package/dist/tools/burst.d.ts +17 -7
- package/dist/tools/burst.js +240 -83
- 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 +97 -98
- package/dist/tools/clipboard.js +31 -24
- 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.d.ts +1 -1
- package/dist/tools/navigate.js +57 -44
- 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.d.ts +10 -10
- package/dist/tools/tabs.js +55 -39
- 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 +109 -60
- 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 +82 -36
- package/docs/PLUGINS.md +82 -499
- package/docs/TOOLS.md +51 -99
- package/docs/architecture/blind-injection.md +83 -0
- package/docs/architecture/dual-injection.md +32 -0
- package/docs/architecture/overview.md +49 -0
- package/docs/architecture/security.md +35 -0
- package/docs/architecture/transport.md +37 -0
- package/docs/captcha-stealth/captcha-solver.md +75 -0
- package/docs/captcha-stealth/stealth-physics.md +60 -0
- package/docs/cli/cli-commands.md +44 -0
- package/docs/cli/cli-flags.md +20 -0
- package/docs/cli/cli-introduction.md +20 -0
- package/docs/cli/cli-scripting.md +32 -0
- package/docs/cli/g-ide/ide-antigravity.md +24 -0
- package/docs/cli/g-ide/ide-claude-code.md +24 -0
- package/docs/cli/g-ide/ide-claude-desktop.md +32 -0
- package/docs/cli/g-ide/ide-cursor.md +31 -0
- package/docs/cli/g-ide/ide-generic.md +34 -0
- package/docs/cli/g-ide/ide-opencode.md +24 -0
- package/docs/cli/g-ide/ide-vscode-copilot.md +24 -0
- package/docs/cli/g-ide/ide-windsurf.md +24 -0
- package/docs/configuration/config-locations.md +24 -0
- package/docs/configuration/configuration.md +73 -0
- package/docs/configuration/env-variables.md +19 -0
- package/docs/configuration/folders.md +55 -0
- package/docs/desktop-automation/electron-apps.md +217 -0
- package/docs/get-started/installation.md +47 -0
- package/docs/get-started/introduction.md +60 -0
- package/docs/get-started/quickstart.md +54 -0
- package/docs/get-started/setup-wizard.md +26 -0
- package/docs/intelligence/site-profiles.md +151 -0
- package/docs/skills-ecosystem/skills-overview.md +35 -0
- package/docs/skills-ecosystem/skills-recipes.md +36 -0
- package/docs/tools/tools.md +631 -0
- package/docs/troubleshooting/trouble-browser.md +27 -0
- package/docs/troubleshooting/trouble-config.md +20 -0
- package/docs/troubleshooting/trouble-loop.md +31 -0
- package/ext-dist/background.js +10 -62
- package/ext-dist/content.js +333 -921
- 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 +108 -72
- package/package.json +14 -9
- package/server.json +3 -3
- package/docs/DEV_MODE.md +0 -68
- package/docs/dev_plugin.md +0 -310
- 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];
|
|
@@ -180,7 +303,8 @@ export async function browserBurst(session, args, config) {
|
|
|
180
303
|
result = await weaveType(session, step.args, config);
|
|
181
304
|
break;
|
|
182
305
|
case "browser_go":
|
|
183
|
-
|
|
306
|
+
case "browser_navigate":
|
|
307
|
+
result = await weaveNavigate(session, step.args.url, config, undefined, false, false, args.app);
|
|
184
308
|
break;
|
|
185
309
|
case "browser_key":
|
|
186
310
|
result = await weaveKey(session, step.args, config);
|
|
@@ -192,7 +316,7 @@ export async function browserBurst(session, args, config) {
|
|
|
192
316
|
result = await browserWait(session, step.args, config);
|
|
193
317
|
break;
|
|
194
318
|
case "browser_map": {
|
|
195
|
-
const mapTargetId = sessionRegistry.getActive(getConfigAgentId(config))?.targetId || "default";
|
|
319
|
+
const mapTargetId = sessionRegistry.getActive(getConfigAgentId(config), args.app)?.targetId || "default";
|
|
196
320
|
result = await browserMap(session, step.args, mapTargetId, config);
|
|
197
321
|
break;
|
|
198
322
|
}
|
|
@@ -207,7 +331,7 @@ export async function browserBurst(session, args, config) {
|
|
|
207
331
|
break;
|
|
208
332
|
case "browser_console": {
|
|
209
333
|
let targetId = "default";
|
|
210
|
-
const active = sessionRegistry.getActive(getConfigAgentId(config));
|
|
334
|
+
const active = sessionRegistry.getActive(getConfigAgentId(config), args.app);
|
|
211
335
|
if (active)
|
|
212
336
|
targetId = active.targetId;
|
|
213
337
|
result = await browserConsole(session, step.args, config, targetId);
|
|
@@ -219,9 +343,6 @@ export async function browserBurst(session, args, config) {
|
|
|
219
343
|
case "browser_fill":
|
|
220
344
|
result = await browserFill(session, step.args, config);
|
|
221
345
|
break;
|
|
222
|
-
case "browser_navigate":
|
|
223
|
-
result = await weaveNavigate(session, step.args.url, config);
|
|
224
|
-
break;
|
|
225
346
|
case "browser_type_secret":
|
|
226
347
|
result = await weaveTypeSecret(session, step.args, config);
|
|
227
348
|
break;
|
|
@@ -307,38 +428,74 @@ export async function browserBurst(session, args, config) {
|
|
|
307
428
|
results.push({ step: i + 1, tool: step.tool, success: false, error: stepError });
|
|
308
429
|
stepsCompleted++;
|
|
309
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
|
+
}
|
|
310
442
|
continue;
|
|
311
443
|
}
|
|
312
444
|
const resultObj = result && typeof result === "object" ? result : {};
|
|
313
445
|
const isError = resultObj.success === false;
|
|
446
|
+
const errDetail = resultObj.message || resultObj.stuck_hint || undefined;
|
|
314
447
|
results.push({
|
|
315
448
|
step: i + 1,
|
|
316
449
|
tool: step.tool,
|
|
317
450
|
success: !isError,
|
|
318
451
|
result: isError ? undefined : result,
|
|
319
|
-
error: isError ?
|
|
452
|
+
error: isError ? errDetail : undefined,
|
|
320
453
|
});
|
|
321
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
|
+
}
|
|
322
467
|
}
|
|
323
468
|
catch (err) {
|
|
324
|
-
|
|
325
|
-
|
|
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}` });
|
|
326
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
|
+
}
|
|
327
484
|
}
|
|
328
485
|
logAction("browser_burst", `step_${i + 1}/${steps.length}`, step.tool);
|
|
329
486
|
}
|
|
330
|
-
// If batch was used, update cache once at the end
|
|
331
487
|
if (batch) {
|
|
332
488
|
const targetId = sessionRegistry.getActive(getConfigAgentId(config))?.targetId || "default";
|
|
333
489
|
const map = await buildActionMap(session, { lite: true }, targetId);
|
|
334
490
|
cacheActionMap(targetId, map);
|
|
335
491
|
}
|
|
336
492
|
await sendToExtension(session, { type: 'Weavetab_STATE', hud: { action: '' } });
|
|
337
|
-
const
|
|
493
|
+
const allPassed = results.length > 0 && results.every(r => r.success);
|
|
338
494
|
return {
|
|
339
|
-
success:
|
|
495
|
+
success: allPassed,
|
|
340
496
|
steps_completed: stepsCompleted,
|
|
341
497
|
results,
|
|
342
498
|
aborted: false,
|
|
499
|
+
compiled_steps: compiledSteps,
|
|
343
500
|
};
|
|
344
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>;
|