@jobshimo/browser-link 0.14.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-instructions/content.js +28 -5
- package/dist/agent-instructions/content.js.map +1 -1
- package/dist/commands/about.js +2 -0
- package/dist/commands/about.js.map +1 -1
- package/dist/extension/background.js +93 -250
- package/dist/extension/background.js.map +1 -1
- package/dist/extension/inpage/builders.d.ts +111 -0
- package/dist/extension/inpage/builders.js +290 -0
- package/dist/extension/inpage/builders.js.map +1 -0
- package/dist/extension/inpage/deep-query.d.ts +40 -0
- package/dist/extension/inpage/deep-query.js +308 -0
- package/dist/extension/inpage/deep-query.js.map +1 -0
- package/dist/extension/inpage/dom-helpers.d.ts +22 -0
- package/dist/extension/inpage/dom-helpers.js +142 -0
- package/dist/extension/inpage/dom-helpers.js.map +1 -0
- package/dist/extension/keymap.d.ts +82 -0
- package/dist/extension/keymap.js +205 -0
- package/dist/extension/keymap.js.map +1 -0
- package/dist/extension/manifest.json +1 -1
- package/dist/extension/settle.d.ts +39 -0
- package/dist/extension/settle.js +69 -0
- package/dist/extension/settle.js.map +1 -0
- package/dist/permissions.js +6 -0
- package/dist/permissions.js.map +1 -1
- package/dist/tools/browser-definitions.js +82 -4
- package/dist/tools/browser-definitions.js.map +1 -1
- package/dist/tools/browser-dispatch.js +67 -4
- package/dist/tools/browser-dispatch.js.map +1 -1
- package/dist/tools/server-instructions.js +23 -7
- package/dist/tools/server-instructions.js.map +1 -1
- package/package.json +1 -1
|
@@ -83,6 +83,17 @@ function body() {
|
|
|
83
83
|
' SILENTLY), applies visibility + ARIA checks, returns a stable',
|
|
84
84
|
' selector + viewport coords, and on multi-match returns up to 5',
|
|
85
85
|
' candidates with snippets for disambiguation.',
|
|
86
|
+
'- `snapshot`/`find`/`click`/`type` all pierce OPEN Shadow DOM roots and',
|
|
87
|
+
' same-origin iframes automatically — no special handling needed for',
|
|
88
|
+
' web components or in-page iframes. CLOSED shadow roots and',
|
|
89
|
+
' cross-origin iframes stay out of reach (no CDP workaround). If',
|
|
90
|
+
' `click` returns "Element covered by …", something else is on top of',
|
|
91
|
+
' the target — click or dismiss that element first, do not blindly',
|
|
92
|
+
' retry with `force:true`.',
|
|
93
|
+
'- A snapshot/find entry with `ambiguous: true` has a selector that',
|
|
94
|
+
' matches structurally-identical twins in other shadow roots/iframes',
|
|
95
|
+
' (no CSS syntax can scope to one root). It resolves first-match-wins:',
|
|
96
|
+
' use it in the SAME turn, and NEVER `browser.map.save` it.',
|
|
86
97
|
'- Trimming snapshot size → `browser.snapshot({ within_selector, only_interactive, exclude, max_interactive })`.',
|
|
87
98
|
' Filters are applied IN-page so the dropped material never travels back.',
|
|
88
99
|
' Pass `exclude:["nav","footer"]` to skip repeated landmarks; pass',
|
|
@@ -92,11 +103,23 @@ function body() {
|
|
|
92
103
|
' Never N separate evaluates for N reads.',
|
|
93
104
|
'- Scrolling → `browser.evaluate` with `pane.scrollTop = N` or',
|
|
94
105
|
' `el.scrollIntoView({ block: "center" })`. No dedicated tool needed.',
|
|
95
|
-
'- Special keys (Enter/Tab/Escape/arrows) → `browser.
|
|
96
|
-
' `
|
|
97
|
-
'
|
|
98
|
-
'
|
|
99
|
-
'
|
|
106
|
+
'- Special keys (Enter/Tab/Escape/arrows/shortcuts) → `browser.press`,',
|
|
107
|
+
' NOT `browser.evaluate` with a synthetic `KeyboardEvent`. Synthetic',
|
|
108
|
+
' `dispatchEvent` produces `isTrusted:false` events — rich editors,',
|
|
109
|
+
' autocompletes, and non-DOM runtimes (Qt-WASM, WebGL) silently ignore',
|
|
110
|
+
' them. `browser.press` dispatches a real CDP `Input.dispatchKeyEvent`',
|
|
111
|
+
' sequence (`isTrusted:true`). For TYPING text → `browser.type` (native',
|
|
112
|
+
' setter; controlled components update their state).',
|
|
113
|
+
'- After `click`/`type`/`press`, a separate `browser.wait_for` is',
|
|
114
|
+
' usually unnecessary — all three accept `settle_ms` (default 150) and',
|
|
115
|
+
' return a `settle` object (`{ settled, duration_ms, mutation_count,',
|
|
116
|
+
' url_changed?, focus_moved? }`) once the page goes quiet. Settle',
|
|
117
|
+
' proves QUIET, not EFFECT: mutations completing before the observer',
|
|
118
|
+
' installs (right after dispatch) and async reactions starting after',
|
|
119
|
+
' the quiet window are both invisible — `mutation_count: 0` does NOT',
|
|
120
|
+
' mean the action did nothing. Reach for `wait_for` when you need a',
|
|
121
|
+
' SPECIFIC condition (a particular selector, network request, or',
|
|
122
|
+
' expression), not just "did anything change".',
|
|
100
123
|
'- Paging `browser.events` → keep `lastId = result.latest_id` in your',
|
|
101
124
|
' working notes and pass as `since_id` next call. One variable. The',
|
|
102
125
|
' server does not maintain per-agent cursors.',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/agent-instructions/content.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,sCAAsC,CAAC;AACnE,MAAM,CAAC,MAAM,UAAU,GAAG,wCAAwC,CAAC;AAEnE,MAAM,UAAU,WAAW,CAAC,OAAO,GAAG,OAAO;IAC3C,OAAO,GAAG,YAAY,KAAK,OAAO,MAAM,CAAC;AAC3C,CAAC;AAED;;;;yCAIyC;AACzC,MAAM,CAAC,MAAM,QAAQ,GACnB,gFAAgF,CAAC;AACnF,MAAM,CAAC,MAAM,MAAM,GAAG,4CAA4C,CAAC;AAEnE;;;;mBAImB;AACnB,SAAS,IAAI;IACX,OAAO;QACL,mDAAmD;QACnD,EAAE;QACF,kFAAkF;QAClF,wEAAwE;QACxE,+DAA+D;QAC/D,EAAE;QACF,0DAA0D;QAC1D,EAAE;QACF,kDAAkD;QAClD,qEAAqE;QACrE,+DAA+D;QAC/D,yEAAyE;QACzE,oDAAoD;QACpD,yEAAyE;QACzE,sEAAsE;QACtE,kFAAkF;QAClF,EAAE;QACF,qDAAqD;QACrD,qEAAqE;QACrE,EAAE;QACF,yCAAyC;QACzC,gEAAgE;QAChE,EAAE;QACF,yEAAyE;QACzE,mBAAmB;QACnB,qEAAqE;QACrE,EAAE;QACF,4DAA4D;QAC5D,wEAAwE;QACxE,0CAA0C;QAC1C,EAAE;QACF,wCAAwC;QACxC,EAAE;QACF,8EAA8E;QAC9E,2EAA2E;QAC3E,EAAE;QACF,WAAW;QACX,EAAE;QACF,iDAAiD;QACjD,4EAA4E;QAC5E,2DAA2D;QAC3D,2EAA2E;QAC3E,EAAE;QACF,8EAA8E;QAC9E,EAAE;QACF,uEAAuE;QACvE,oEAAoE;QACpE,EAAE;QACF,yEAAyE;QACzE,mEAAmE;QACnE,sEAAsE;QACtE,iEAAiE;QACjE,kEAAkE;QAClE,gDAAgD;QAChD,iHAAiH;QACjH,2EAA2E;QAC3E,oEAAoE;QACpE,mDAAmD;QACnD,kEAAkE;QAClE,oEAAoE;QACpE,2CAA2C;QAC3C,+DAA+D;QAC/D,uEAAuE;QACvE,
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/agent-instructions/content.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/about.js
CHANGED
|
@@ -45,6 +45,7 @@ export const I18N_ABOUT = {
|
|
|
45
45
|
' browser.navigate change the tab URL',
|
|
46
46
|
' browser.click click an element by CSS selector',
|
|
47
47
|
' browser.type type into an input',
|
|
48
|
+
' browser.press press a key (trusted CDP input, not synthetic)',
|
|
48
49
|
' browser.evaluate run JavaScript in the page context',
|
|
49
50
|
' browser.console recent console messages (rolling 200)',
|
|
50
51
|
' browser.network recent network requests (rolling 200)',
|
|
@@ -141,6 +142,7 @@ export const I18N_ABOUT = {
|
|
|
141
142
|
' browser.navigate cambiar la URL de la pestaña',
|
|
142
143
|
' browser.click hacer click en un elemento por CSS selector',
|
|
143
144
|
' browser.type escribir en un input',
|
|
145
|
+
' browser.press presionar una tecla (input CDP confiable, no sintético)',
|
|
144
146
|
' browser.evaluate ejecutar JavaScript en el contexto de la página',
|
|
145
147
|
' browser.console mensajes recientes de consola (200 últimos)',
|
|
146
148
|
' browser.network peticiones de red recientes (200 últimas)',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"about.js","sourceRoot":"","sources":["../../src/commands/about.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"about.js","sourceRoot":"","sources":["../../src/commands/about.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { buildSnapshotJs, buildFindJs, buildClickResolveJs, buildTypeResolveJs, buildFocusJs, } from './inpage/builders.js';
|
|
2
|
+
import { buildKeyEventSequence, resolveKey, modifiersToBitmask, MODIFIER_BITS, } from './keymap.js';
|
|
3
|
+
import { resolveSettleParams, settleSafely } from './settle.js';
|
|
1
4
|
const WS_URL = 'ws://127.0.0.1:17529';
|
|
2
5
|
const CDP_VERSION = '1.3';
|
|
3
6
|
const CONSOLE_BUFFER_MAX = 200;
|
|
@@ -105,6 +108,28 @@ function sleep(ms) {
|
|
|
105
108
|
}
|
|
106
109
|
});
|
|
107
110
|
}
|
|
111
|
+
/** Run the shared post-action settle wait for a tab. Thin closure binder
|
|
112
|
+
* over `settleSafely` (see settle.ts) — which is guaranteed not to throw,
|
|
113
|
+
* so an action that navigated the page (destroying the settle expression's
|
|
114
|
+
* execution context) still returns ok:true with a degraded settle object
|
|
115
|
+
* instead of flipping the whole response to ok:false. */
|
|
116
|
+
function runSettle(tabId, settle) {
|
|
117
|
+
return settleSafely((expression) => evaluateInTab(tabId, expression), settle);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Dispatch the CDP `Input.dispatchKeyEvent` sequence for one resolved key.
|
|
121
|
+
* The event shapes come from `buildKeyEventSequence` (keymap.ts) — pure and
|
|
122
|
+
* unit-tested there; this wrapper only feeds them to chrome.debugger. This
|
|
123
|
+
* is the ONLY path in this extension that produces `isTrusted: true`
|
|
124
|
+
* keyboard events — see browser.press's doc block for why that matters
|
|
125
|
+
* (Qt-WASM and similar runtimes discard synthetic KeyboardEvents dispatched
|
|
126
|
+
* via browser.evaluate).
|
|
127
|
+
*/
|
|
128
|
+
async function dispatchKeyEvent(tabId, def, modifiers) {
|
|
129
|
+
for (const event of buildKeyEventSequence(def, modifiers)) {
|
|
130
|
+
await cdp(tabId, 'Input.dispatchKeyEvent', event);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
108
133
|
/**
|
|
109
134
|
* Wait for ONE CDP event of a given method on a given tab. Adds a temporary
|
|
110
135
|
* chrome.debugger.onEvent listener for the duration of the wait. Resolves
|
|
@@ -379,218 +404,6 @@ function attachDebuggerListener(state) {
|
|
|
379
404
|
};
|
|
380
405
|
state.debuggerListener = listener;
|
|
381
406
|
}
|
|
382
|
-
/**
|
|
383
|
-
* Shared in-page DOM helpers, injected verbatim into any JS template that
|
|
384
|
-
* needs them (`buildSnapshotJs`, `buildFindJs`). Defining them once here
|
|
385
|
-
* keeps the heuristics (visibility, selector generation, accessible text)
|
|
386
|
-
* identical across tools so a selector returned by `snapshot` and a selector
|
|
387
|
-
* returned by `find` follow the same rules.
|
|
388
|
-
*/
|
|
389
|
-
const DOM_HELPERS_JS = `
|
|
390
|
-
function isVisible(el) {
|
|
391
|
-
if (!(el instanceof HTMLElement)) return true;
|
|
392
|
-
const style = getComputedStyle(el);
|
|
393
|
-
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false;
|
|
394
|
-
if (el.offsetParent === null && style.position !== 'fixed') return false;
|
|
395
|
-
return true;
|
|
396
|
-
}
|
|
397
|
-
function shortText(el) {
|
|
398
|
-
const t = (el.innerText || el.textContent || '').trim();
|
|
399
|
-
return t.length > 120 ? t.slice(0, 120) + '...' : t;
|
|
400
|
-
}
|
|
401
|
-
function safeCss(s) {
|
|
402
|
-
return s.replace(/"/g, '\\\\"');
|
|
403
|
-
}
|
|
404
|
-
function genSelector(el) {
|
|
405
|
-
if (el.id && !/^[\\d]/.test(el.id) && !/\\s/.test(el.id)) {
|
|
406
|
-
try { if (document.querySelectorAll('#' + CSS.escape(el.id)).length === 1) return '#' + CSS.escape(el.id); } catch (_) {}
|
|
407
|
-
}
|
|
408
|
-
const tid = el.getAttribute('data-testid');
|
|
409
|
-
if (tid) return '[data-testid="' + safeCss(tid) + '"]';
|
|
410
|
-
const al = el.getAttribute('aria-label');
|
|
411
|
-
if (al && al.length < 60) return el.tagName.toLowerCase() + '[aria-label="' + safeCss(al) + '"]';
|
|
412
|
-
const name = el.getAttribute('name');
|
|
413
|
-
if (name && (el.tagName === 'INPUT' || el.tagName === 'SELECT' || el.tagName === 'TEXTAREA')) {
|
|
414
|
-
return el.tagName.toLowerCase() + '[name="' + safeCss(name) + '"]';
|
|
415
|
-
}
|
|
416
|
-
const parts = [];
|
|
417
|
-
let cur = el;
|
|
418
|
-
while (cur && cur.nodeType === 1 && cur !== document.body && parts.length < 6) {
|
|
419
|
-
let part = cur.tagName.toLowerCase();
|
|
420
|
-
const parent = cur.parentElement;
|
|
421
|
-
if (parent) {
|
|
422
|
-
const sib = Array.from(parent.children).filter(s => s.tagName === cur.tagName);
|
|
423
|
-
if (sib.length > 1) {
|
|
424
|
-
part += ':nth-of-type(' + (sib.indexOf(cur) + 1) + ')';
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
parts.unshift(part);
|
|
428
|
-
cur = parent;
|
|
429
|
-
}
|
|
430
|
-
return parts.join(' > ');
|
|
431
|
-
}
|
|
432
|
-
function accessibleText(el) {
|
|
433
|
-
const aria = el.getAttribute && el.getAttribute('aria-label');
|
|
434
|
-
if (aria) return aria;
|
|
435
|
-
const txt = (el.innerText || el.textContent || '').trim();
|
|
436
|
-
if (txt) return txt;
|
|
437
|
-
if ('value' in el && el.value) return String(el.value);
|
|
438
|
-
const ph = el.getAttribute && el.getAttribute('placeholder');
|
|
439
|
-
if (ph) return ph;
|
|
440
|
-
const title = el.getAttribute && el.getAttribute('title');
|
|
441
|
-
if (title) return title;
|
|
442
|
-
return '';
|
|
443
|
-
}
|
|
444
|
-
`;
|
|
445
|
-
function buildSnapshotJs(opts = {}) {
|
|
446
|
-
const optsJson = JSON.stringify({
|
|
447
|
-
withinSelector: typeof opts.within_selector === 'string' ? opts.within_selector : null,
|
|
448
|
-
onlyInteractive: opts.only_interactive === true,
|
|
449
|
-
exclude: Array.isArray(opts.exclude) ? opts.exclude : [],
|
|
450
|
-
maxInteractive: typeof opts.max_interactive === 'number' && opts.max_interactive > 0
|
|
451
|
-
? Math.min(opts.max_interactive, 500)
|
|
452
|
-
: 120,
|
|
453
|
-
});
|
|
454
|
-
return `
|
|
455
|
-
(() => {
|
|
456
|
-
${DOM_HELPERS_JS}
|
|
457
|
-
const opts = ${optsJson};
|
|
458
|
-
let root = document;
|
|
459
|
-
let notice = '';
|
|
460
|
-
if (opts.withinSelector) {
|
|
461
|
-
const sub = document.querySelector(opts.withinSelector);
|
|
462
|
-
if (!sub) {
|
|
463
|
-
return {
|
|
464
|
-
title: document.title,
|
|
465
|
-
url: location.href,
|
|
466
|
-
interactive: [],
|
|
467
|
-
notice: 'within_selector did not match any element',
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
root = sub;
|
|
471
|
-
}
|
|
472
|
-
const excludeSet = new Set((opts.exclude || []).map(s => String(s).toLowerCase()));
|
|
473
|
-
function inExcludedLandmark(el) {
|
|
474
|
-
if (excludeSet.size === 0) return false;
|
|
475
|
-
let cur = el.parentElement;
|
|
476
|
-
while (cur && cur !== document.body) {
|
|
477
|
-
const tag = cur.tagName ? cur.tagName.toLowerCase() : '';
|
|
478
|
-
if (excludeSet.has(tag)) return true;
|
|
479
|
-
if (cur === root) return false;
|
|
480
|
-
cur = cur.parentElement;
|
|
481
|
-
}
|
|
482
|
-
return false;
|
|
483
|
-
}
|
|
484
|
-
const sel = 'a[href], button, input, select, textarea, [role=button], [role=link], [role=checkbox], [role=tab], [role=menuitem], [contenteditable=true]';
|
|
485
|
-
const interactive = [];
|
|
486
|
-
const scope = (root.querySelectorAll ? root : document);
|
|
487
|
-
scope.querySelectorAll(sel).forEach((el) => {
|
|
488
|
-
if (!isVisible(el)) return;
|
|
489
|
-
if (inExcludedLandmark(el)) return;
|
|
490
|
-
const tag = el.tagName.toLowerCase();
|
|
491
|
-
const role = el.getAttribute('role') || tag;
|
|
492
|
-
const entry = { tag, role, selector: genSelector(el) };
|
|
493
|
-
const txt = shortText(el);
|
|
494
|
-
if (txt) entry.text = txt;
|
|
495
|
-
if ('value' in el && el.value) entry.value = String(el.value);
|
|
496
|
-
const placeholder = el.getAttribute('placeholder');
|
|
497
|
-
if (placeholder) entry.placeholder = placeholder;
|
|
498
|
-
const aria_label = el.getAttribute('aria-label');
|
|
499
|
-
if (aria_label) entry.aria_label = aria_label;
|
|
500
|
-
const name = el.getAttribute('name');
|
|
501
|
-
if (name) entry.name = name;
|
|
502
|
-
const type = el.getAttribute('type');
|
|
503
|
-
if (type) entry.type = type;
|
|
504
|
-
const href = el.getAttribute('href');
|
|
505
|
-
if (href) entry.href = href;
|
|
506
|
-
if ('disabled' in el && el.disabled) entry.disabled = true;
|
|
507
|
-
interactive.push(entry);
|
|
508
|
-
});
|
|
509
|
-
const result = {
|
|
510
|
-
title: document.title,
|
|
511
|
-
url: location.href,
|
|
512
|
-
interactive: interactive.slice(0, opts.maxInteractive),
|
|
513
|
-
};
|
|
514
|
-
if (!opts.onlyInteractive) {
|
|
515
|
-
const headings = [];
|
|
516
|
-
scope.querySelectorAll('h1, h2, h3').forEach((h) => {
|
|
517
|
-
if (!isVisible(h)) return;
|
|
518
|
-
if (inExcludedLandmark(h)) return;
|
|
519
|
-
const t = shortText(h);
|
|
520
|
-
if (t) headings.push({ level: h.tagName, text: t });
|
|
521
|
-
});
|
|
522
|
-
result.headings = headings.slice(0, 30);
|
|
523
|
-
const textRoot = (root === document) ? (document.body || document) : root;
|
|
524
|
-
const visibleText = (textRoot && textRoot.innerText) ? textRoot.innerText.slice(0, 4000) : '';
|
|
525
|
-
if (visibleText) result.text = visibleText;
|
|
526
|
-
}
|
|
527
|
-
if (notice) result.notice = notice;
|
|
528
|
-
return result;
|
|
529
|
-
})()
|
|
530
|
-
`;
|
|
531
|
-
}
|
|
532
|
-
function buildFindJs(opts) {
|
|
533
|
-
const optsJson = JSON.stringify({
|
|
534
|
-
text: opts.text,
|
|
535
|
-
role: typeof opts.role === 'string' && opts.role.length > 0 ? opts.role : null,
|
|
536
|
-
exact: opts.exact === true,
|
|
537
|
-
candidateLimit: 5,
|
|
538
|
-
});
|
|
539
|
-
return `
|
|
540
|
-
(() => {
|
|
541
|
-
${DOM_HELPERS_JS}
|
|
542
|
-
const opts = ${optsJson};
|
|
543
|
-
const needle = opts.text.toLowerCase();
|
|
544
|
-
const ROLE_SELECTORS = {
|
|
545
|
-
button: 'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',
|
|
546
|
-
link: 'a[href], [role="link"]',
|
|
547
|
-
textbox: 'input[type="text"], input[type="email"], input[type="password"], input[type="search"], input[type="url"], input[type="tel"], input:not([type]), textarea, [role="textbox"], [contenteditable="true"]',
|
|
548
|
-
checkbox: 'input[type="checkbox"], [role="checkbox"]',
|
|
549
|
-
tab: '[role="tab"]',
|
|
550
|
-
menuitem: '[role="menuitem"]',
|
|
551
|
-
};
|
|
552
|
-
const selectorSet = opts.role && ROLE_SELECTORS[opts.role]
|
|
553
|
-
? ROLE_SELECTORS[opts.role]
|
|
554
|
-
: 'button, a, input, textarea, select, [role], [onclick], [contenteditable="true"], [tabindex]';
|
|
555
|
-
const all = Array.from(document.querySelectorAll(selectorSet));
|
|
556
|
-
const matches = [];
|
|
557
|
-
for (const el of all) {
|
|
558
|
-
if (!isVisible(el)) continue;
|
|
559
|
-
const text = accessibleText(el).trim();
|
|
560
|
-
if (text.length === 0) continue;
|
|
561
|
-
const lower = text.toLowerCase();
|
|
562
|
-
const ok = opts.exact ? lower === needle : lower.includes(needle);
|
|
563
|
-
if (ok) matches.push(el);
|
|
564
|
-
}
|
|
565
|
-
if (matches.length === 0) {
|
|
566
|
-
return { matched: false, reason: 'not-found' };
|
|
567
|
-
}
|
|
568
|
-
if (matches.length > 1) {
|
|
569
|
-
return {
|
|
570
|
-
matched: false,
|
|
571
|
-
reason: 'multiple-matches',
|
|
572
|
-
candidates: matches.slice(0, opts.candidateLimit).map((el) => ({
|
|
573
|
-
selector: genSelector(el),
|
|
574
|
-
text: shortText(el),
|
|
575
|
-
tag: el.tagName.toLowerCase(),
|
|
576
|
-
})),
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
const el = matches[0];
|
|
580
|
-
const rect = el.getBoundingClientRect();
|
|
581
|
-
return {
|
|
582
|
-
matched: true,
|
|
583
|
-
selector: genSelector(el),
|
|
584
|
-
coords: {
|
|
585
|
-
x: Math.round(rect.left + rect.width / 2),
|
|
586
|
-
y: Math.round(rect.top + rect.height / 2),
|
|
587
|
-
},
|
|
588
|
-
tag: el.tagName.toLowerCase(),
|
|
589
|
-
text: shortText(el),
|
|
590
|
-
};
|
|
591
|
-
})()
|
|
592
|
-
`;
|
|
593
|
-
}
|
|
594
407
|
function buildCanvasScreenshotJs(opts) {
|
|
595
408
|
const optsJson = JSON.stringify({
|
|
596
409
|
selector: opts.selector ?? null,
|
|
@@ -817,16 +630,18 @@ async function handleTool(state, msg) {
|
|
|
817
630
|
}
|
|
818
631
|
case 'click': {
|
|
819
632
|
const selector = str('selector');
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
633
|
+
const force = p.force === true;
|
|
634
|
+
const settle = resolveSettleParams(p);
|
|
635
|
+
const resolved = await evaluateInTab(tabId, buildClickResolveJs({ selector, force }));
|
|
636
|
+
if (!resolved.ok) {
|
|
637
|
+
if (resolved.reason === 'occluded') {
|
|
638
|
+
return {
|
|
639
|
+
kind: 'tool.response',
|
|
640
|
+
id: msg.id,
|
|
641
|
+
ok: false,
|
|
642
|
+
error: `Element covered by ${resolved.blocker} — click the covering element or dismiss it first`,
|
|
643
|
+
};
|
|
644
|
+
}
|
|
830
645
|
return {
|
|
831
646
|
kind: 'tool.response',
|
|
832
647
|
id: msg.id,
|
|
@@ -836,43 +651,35 @@ async function handleTool(state, msg) {
|
|
|
836
651
|
}
|
|
837
652
|
await cdp(tabId, 'Input.dispatchMouseEvent', {
|
|
838
653
|
type: 'mouseMoved',
|
|
839
|
-
x:
|
|
840
|
-
y:
|
|
654
|
+
x: resolved.x,
|
|
655
|
+
y: resolved.y,
|
|
841
656
|
});
|
|
842
657
|
await cdp(tabId, 'Input.dispatchMouseEvent', {
|
|
843
658
|
type: 'mousePressed',
|
|
844
|
-
x:
|
|
845
|
-
y:
|
|
659
|
+
x: resolved.x,
|
|
660
|
+
y: resolved.y,
|
|
846
661
|
button: 'left',
|
|
847
662
|
clickCount: 1,
|
|
848
663
|
});
|
|
849
664
|
await cdp(tabId, 'Input.dispatchMouseEvent', {
|
|
850
665
|
type: 'mouseReleased',
|
|
851
|
-
x:
|
|
852
|
-
y:
|
|
666
|
+
x: resolved.x,
|
|
667
|
+
y: resolved.y,
|
|
853
668
|
button: 'left',
|
|
854
669
|
clickCount: 1,
|
|
855
670
|
});
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
};
|
|
671
|
+
const settleResult = await runSettle(tabId, settle);
|
|
672
|
+
const result = { clicked: selector, tag: resolved.tag };
|
|
673
|
+
if (settleResult)
|
|
674
|
+
result.settle = settleResult;
|
|
675
|
+
return { kind: 'tool.response', id: msg.id, ok: true, result };
|
|
862
676
|
}
|
|
863
677
|
case 'type': {
|
|
864
678
|
const selector = str('selector');
|
|
865
679
|
const text = str('text');
|
|
866
680
|
const clear = p.clear === true;
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
const el = document.querySelector(${JSON.stringify(selector)});
|
|
870
|
-
if (!el) return false;
|
|
871
|
-
el.focus();
|
|
872
|
-
${clear ? "if ('value' in el) { el.value = ''; el.dispatchEvent(new Event('input', { bubbles: true })); }" : ''}
|
|
873
|
-
return true;
|
|
874
|
-
})()`;
|
|
875
|
-
const focused = await evaluateInTab(tabId, focusExpr);
|
|
681
|
+
const settle = resolveSettleParams(p);
|
|
682
|
+
const focused = await evaluateInTab(tabId, buildTypeResolveJs({ selector, clear }));
|
|
876
683
|
if (!focused) {
|
|
877
684
|
return {
|
|
878
685
|
kind: 'tool.response',
|
|
@@ -882,12 +689,49 @@ async function handleTool(state, msg) {
|
|
|
882
689
|
};
|
|
883
690
|
}
|
|
884
691
|
await cdp(tabId, 'Input.insertText', { text });
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
692
|
+
const settleResult = await runSettle(tabId, settle);
|
|
693
|
+
const result = { typed: text.length, selector };
|
|
694
|
+
if (settleResult)
|
|
695
|
+
result.settle = settleResult;
|
|
696
|
+
return { kind: 'tool.response', id: msg.id, ok: true, result };
|
|
697
|
+
}
|
|
698
|
+
case 'press': {
|
|
699
|
+
const key = optStr('key');
|
|
700
|
+
if (!key) {
|
|
701
|
+
return { kind: 'tool.response', id: msg.id, ok: false, error: 'press: key required' };
|
|
702
|
+
}
|
|
703
|
+
const def = resolveKey(key);
|
|
704
|
+
if (!def) {
|
|
705
|
+
return {
|
|
706
|
+
kind: 'tool.response',
|
|
707
|
+
id: msg.id,
|
|
708
|
+
ok: false,
|
|
709
|
+
error: `press: unrecognized key "${key}"`,
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
const modifierNames = Array.isArray(p.modifiers)
|
|
713
|
+
? p.modifiers.filter((m) => typeof m === 'string')
|
|
714
|
+
: [];
|
|
715
|
+
const modifiers = modifiersToBitmask(modifierNames) | (def.needsShift ? MODIFIER_BITS.Shift : 0);
|
|
716
|
+
const selector = optStr('selector');
|
|
717
|
+
const settle = resolveSettleParams(p);
|
|
718
|
+
if (selector) {
|
|
719
|
+
const focused = await evaluateInTab(tabId, buildFocusJs({ selector }));
|
|
720
|
+
if (!focused) {
|
|
721
|
+
return {
|
|
722
|
+
kind: 'tool.response',
|
|
723
|
+
id: msg.id,
|
|
724
|
+
ok: false,
|
|
725
|
+
error: `Element not found: ${selector}`,
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
await dispatchKeyEvent(tabId, def, modifiers);
|
|
730
|
+
const settleResult = await runSettle(tabId, settle);
|
|
731
|
+
const result = { key, modifiers: modifierNames };
|
|
732
|
+
if (settleResult)
|
|
733
|
+
result.settle = settleResult;
|
|
734
|
+
return { kind: 'tool.response', id: msg.id, ok: true, result };
|
|
891
735
|
}
|
|
892
736
|
case 'drag': {
|
|
893
737
|
const optNum = (key) => {
|
|
@@ -1711,5 +1555,4 @@ setInterval(() => {
|
|
|
1711
1555
|
});
|
|
1712
1556
|
}
|
|
1713
1557
|
}, WS_IDLE_SWEEP_MS);
|
|
1714
|
-
export {};
|
|
1715
1558
|
//# sourceMappingURL=background.js.map
|