@weavetab/mcp 2.5.0-beta.2 → 2.5.0-beta.5

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 (127) hide show
  1. package/AGENTS.md +1 -1
  2. package/ARCHITECTURE.md +6 -6
  3. package/LICENSE +216 -631
  4. package/README.md +153 -1074
  5. package/SECURITY.md +33 -22
  6. package/TROUBLESHOOTING.md +2 -2
  7. package/dist/cdp/bridge.js +2 -1
  8. package/dist/cdp/connector.d.ts +2 -0
  9. package/dist/cdp/connector.js +10 -6
  10. package/dist/cdp/helpers.d.ts +4 -0
  11. package/dist/cdp/helpers.js +181 -0
  12. package/dist/cdp/omni_broker.d.ts +1 -1
  13. package/dist/cdp/omni_broker.js +1 -1
  14. package/dist/cdp/walker.d.ts +25 -1
  15. package/dist/cdp/walker.js +304 -7
  16. package/dist/cli/plugin.d.ts +1 -0
  17. package/dist/cli/plugin.js +81 -18
  18. package/dist/cli/updater.d.ts +1 -1
  19. package/dist/cli/updater.js +27 -7
  20. package/dist/config/loader.d.ts +9 -1
  21. package/dist/config/loader.js +42 -3
  22. package/dist/desktop/discovery.d.ts +44 -0
  23. package/dist/desktop/discovery.js +364 -0
  24. package/dist/index.js +137 -21
  25. package/dist/intelligence/marks.d.ts +36 -0
  26. package/dist/intelligence/marks.js +30 -0
  27. package/dist/intelligence/patternCompiler.d.ts +118 -0
  28. package/dist/intelligence/patternCompiler.js +259 -0
  29. package/dist/intelligence/sessionMemory.d.ts +2 -0
  30. package/dist/intelligence/sessionMemory.js +18 -8
  31. package/dist/overlay/injector.js +2 -2
  32. package/dist/plugin/interface.d.ts +88 -5
  33. package/dist/plugin/loader.d.ts +12 -1
  34. package/dist/plugin/loader.js +280 -70
  35. package/dist/plugin/pipeline.d.ts +75 -0
  36. package/dist/plugin/pipeline.js +183 -0
  37. package/dist/plugin/registry.d.ts +2 -1
  38. package/dist/plugin/registry.js +24 -14
  39. package/dist/security/secrets.d.ts +7 -0
  40. package/dist/security/secrets.js +37 -0
  41. package/dist/sensors/actionability.js +1 -2
  42. package/dist/sensors/guard.js +4 -10
  43. package/dist/sensors/mutations.js +12 -0
  44. package/dist/sensors/operation_monitor.js +1 -0
  45. package/dist/server.d.ts +1 -1
  46. package/dist/server.js +453 -178
  47. package/dist/state/agent.d.ts +1 -0
  48. package/dist/state/agent.js +3 -0
  49. package/dist/state/delta.d.ts +12 -4
  50. package/dist/state/delta.js +67 -14
  51. package/dist/state/session.d.ts +6 -0
  52. package/dist/state/session.js +27 -0
  53. package/dist/tools/browser_detect.d.ts +16 -3
  54. package/dist/tools/browser_detect.js +52 -7
  55. package/dist/tools/burst.d.ts +17 -8
  56. package/dist/tools/burst.js +236 -77
  57. package/dist/tools/captcha.js +1 -1
  58. package/dist/tools/checkpoint.d.ts +38 -0
  59. package/dist/tools/checkpoint.js +271 -0
  60. package/dist/tools/click.d.ts +1 -0
  61. package/dist/tools/click.js +74 -70
  62. package/dist/tools/design_extract.js +1 -1
  63. package/dist/tools/eval.js +1 -1
  64. package/dist/tools/fill.d.ts +20 -1
  65. package/dist/tools/fill.js +199 -40
  66. package/dist/tools/find.d.ts +16 -0
  67. package/dist/tools/find.js +67 -44
  68. package/dist/tools/github/index.d.ts +19 -4
  69. package/dist/tools/github/index.js +40 -4
  70. package/dist/tools/highlight.d.ts +6 -2
  71. package/dist/tools/highlight.js +158 -72
  72. package/dist/tools/inspect.js +1 -1
  73. package/dist/tools/key.js +65 -56
  74. package/dist/tools/navigate.d.ts +1 -1
  75. package/dist/tools/navigate.js +34 -39
  76. package/dist/tools/pdf.js +21 -13
  77. package/dist/tools/pointer.d.ts +18 -3
  78. package/dist/tools/pointer.js +89 -1
  79. package/dist/tools/read.d.ts +28 -8
  80. package/dist/tools/read.js +230 -56
  81. package/dist/tools/scrape.js +67 -13
  82. package/dist/tools/screenshot.js +21 -16
  83. package/dist/tools/scroll.js +6 -11
  84. package/dist/tools/select.js +8 -2
  85. package/dist/tools/snapshot.js +3 -34
  86. package/dist/tools/tabs.js +15 -7
  87. package/dist/tools/thought.d.ts +2 -0
  88. package/dist/tools/thought.js +13 -14
  89. package/dist/tools/type.d.ts +2 -0
  90. package/dist/tools/type.js +107 -58
  91. package/dist/tools/type_secret.js +42 -76
  92. package/dist/tools/upload.js +1 -1
  93. package/dist/tools/video_compiler.d.ts +1 -1
  94. package/dist/tools/video_compiler.js +11 -12
  95. package/dist/version.d.ts +5 -0
  96. package/dist/version.js +5 -0
  97. package/docs/DOCUMENTATION.md +37 -41
  98. package/docs/PLUGINS.md +121 -0
  99. package/docs/TOOLS.md +54 -0
  100. package/docs/architecture/blind-injection.md +83 -20
  101. package/docs/architecture/overview.md +49 -49
  102. package/docs/architecture/security.md +8 -7
  103. package/docs/architecture/transport.md +2 -2
  104. package/docs/cli/cli-commands.md +7 -1
  105. package/docs/cli/cli-flags.md +15 -7
  106. package/docs/cli/cli-scripting.md +6 -3
  107. package/docs/configuration/config-locations.md +3 -4
  108. package/docs/configuration/env-variables.md +4 -4
  109. package/docs/configuration/folders.md +55 -54
  110. package/docs/desktop-automation/electron-apps.md +214 -162
  111. package/docs/get-started/introduction.md +60 -60
  112. package/docs/get-started/setup-wizard.md +7 -6
  113. package/docs/intelligence/site-profiles.md +151 -0
  114. package/docs/tools/tools.md +631 -293
  115. package/docs/troubleshooting/trouble-browser.md +1 -1
  116. package/docs/troubleshooting/trouble-loop.md +31 -31
  117. package/ext-dist/background.js +10 -62
  118. package/ext-dist/content.js +333 -920
  119. package/ext-dist/hud/hud.js +9 -9
  120. package/ext-dist/manifest.json +2 -6
  121. package/ext-dist/styles.css +6 -1
  122. package/icon.png +0 -0
  123. package/mcp.json +87 -71
  124. package/package.json +118 -119
  125. package/server.json +5 -5
  126. package/ext-dist/sidepanel/sidepanel.js +0 -25
  127. package/ext-dist/sidepanel.html +0 -547
@@ -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
- * Expand a macro step into primitive BurstSteps.
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 { x, y, text, id, label, pressEnter = true } = step.args;
38
- if (!id && !label && x === undefined && y === undefined) {
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 macro failed: text argument is required");
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 } = step.args;
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 { id, label, wait_for, wait_value, x, y } = step.args;
67
- const clickArgs = {};
68
- if (id)
69
- clickArgs.id = id;
70
- if (label)
71
- clickArgs.label = label;
72
- if (x !== undefined)
73
- clickArgs.x = x;
74
- if (y !== undefined)
75
- clickArgs.y = y;
76
- clickArgs.waitForNetwork = true;
77
- clickArgs.waitAfter = 500;
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 } = step.args;
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 } = step.args;
99
+ const { fields, submit } = args;
91
100
  const steps = [];
92
- if (fields && typeof fields === "object") {
93
- for (const [id, value] of Object.entries(fields)) {
94
- steps.push({ tool: "browser_fill", args: { id, value } });
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 { id, end_id, x, y, end_x, end_y, label } = step.args;
104
- const pointerArgs = { action: "drag_and_drop" };
105
- if (id)
106
- pointerArgs.ref = id;
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.end_ref = end_id;
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 { id, label, x, y, holdMs = 300 } = step.args;
123
- const pointerArgs = { action: "hover", holdMs };
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: pointerArgs },
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
- if (!args.steps || args.steps.length === 0) {
141
- return { success: true, steps_completed: 0, results: [], aborted: false };
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 args.steps) {
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
- // Inject fast: true if batch mode is on, unless explicitly set to false
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, { type: 'Weavetab_STATE', hud: { action: `running ${steps.length} steps ${batch ? 'in batch' : 'in sequence'}...` } });
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 ? resultObj.message || resultObj.stuck_hint || undefined : undefined,
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
- logAction("browser_burst", `step_${i + 1}`, `exception: ${err?.message ?? err}`);
323
- results.push({ step: i + 1, tool: step.tool, success: false, error: `Exception: ${err?.message ?? String(err)}` });
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 anySuccess = results.some(r => r.success);
493
+ const allPassed = results.length > 0 && results.every(r => r.success);
336
494
  return {
337
- success: anySuccess,
495
+ success: allPassed,
338
496
  steps_completed: stepsCompleted,
339
497
  results,
340
498
  aborted: false,
499
+ compiled_steps: compiledSteps,
341
500
  };
342
501
  }
@@ -111,7 +111,7 @@ export async function browserCaptcha(session, args, _config) {
111
111
  user_instructions: solution.userInstructions,
112
112
  next_action: isVisionAssisted
113
113
  ? "Take a screenshot to view the CAPTCHA, then use browser_click or browser_type to solve it yourself. Do not ask the user for help."
114
- : `Call browser_thought({ action: "question", message: "${solution.userInstructions}" }) to ask the user to complete it, then call browser_captcha({ action: "wait_for_user" }).`,
114
+ : `Call browser_thoughts({ action: "question", message: "${solution.userInstructions}" }) to ask the user to complete it, then call browser_captcha({ action: "wait_for_user" }).`,
115
115
  execution_ms: Date.now() - t0,
116
116
  };
117
117
  }
@@ -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>;