@jobshimo/browser-link 0.16.0 → 0.18.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 +30 -1
- package/dist/agent-instructions/content.js.map +1 -1
- package/dist/commands/about.js +4 -0
- package/dist/commands/about.js.map +1 -1
- package/dist/extension/background.js +308 -195
- package/dist/extension/background.js.map +1 -1
- package/dist/extension/flow.d.ts +174 -0
- package/dist/extension/flow.js +213 -0
- package/dist/extension/flow.js.map +1 -0
- package/dist/extension/inpage/builders.d.ts +56 -2
- package/dist/extension/inpage/builders.js +201 -4
- package/dist/extension/inpage/builders.js.map +1 -1
- package/dist/extension/manifest.json +1 -1
- package/dist/map/db.js +26 -0
- package/dist/map/db.js.map +1 -1
- package/dist/map/queries.d.ts +29 -0
- package/dist/map/queries.js +44 -2
- package/dist/map/queries.js.map +1 -1
- package/dist/map/tools.js +71 -8
- package/dist/map/tools.js.map +1 -1
- package/dist/permissions.js +12 -0
- package/dist/permissions.js.map +1 -1
- package/dist/tools/browser-definitions.js +185 -1
- package/dist/tools/browser-definitions.js.map +1 -1
- package/dist/tools/browser-dispatch.d.ts +37 -0
- package/dist/tools/browser-dispatch.js +221 -2
- package/dist/tools/browser-dispatch.js.map +1 -1
- package/dist/tools/server-instructions.js +41 -3
- package/dist/tools/server-instructions.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ export interface SnapshotOpts {
|
|
|
22
22
|
export declare function buildSnapshotJs(opts?: SnapshotOpts): string;
|
|
23
23
|
/** Build the find-by-text expression. Returns one of:
|
|
24
24
|
* { matched: true, selector, coords:{x,y}, tag, text, frame?, ambiguous? }
|
|
25
|
-
* { matched: false, reason: 'not-found' }
|
|
25
|
+
* { matched: false, reason: 'not-found', error?, near_misses?: [{text,selector,role?}] }
|
|
26
26
|
* { matched: false, reason: 'multiple-matches', candidates: [{selector,text,tag}] }
|
|
27
27
|
*
|
|
28
28
|
* Role-aware: when `role` is provided, only elements whose explicit ARIA
|
|
@@ -33,6 +33,22 @@ export declare function buildSnapshotJs(opts?: SnapshotOpts): string;
|
|
|
33
33
|
* `deepQueryAll`. `coords` are mapped to TOP-LEVEL viewport coordinates
|
|
34
34
|
* (accounting for ancestor iframe offsets) so they are directly usable by
|
|
35
35
|
* `browser.drag` and other coordinate-based tools.
|
|
36
|
+
*
|
|
37
|
+
* `not-found` carries up to 3 `near_misses` — VISIBLE interactive-ish
|
|
38
|
+
* elements ranked by (1) case-insensitive substring containment of the
|
|
39
|
+
* query in the candidate's accessible text/name, then (2) token overlap —
|
|
40
|
+
* so the agent gets a "did you mean" instead of a bare miss. Omitted
|
|
41
|
+
* entirely when nothing scores (no junk suggestions). When `role` narrowed
|
|
42
|
+
* the scan and the text DOES exist outside that role, `error` names the
|
|
43
|
+
* exclusion explicitly (e.g. `text matched 2 elements but none with role
|
|
44
|
+
* "button" — closest: <div onclick> "GIF picker"`) and `near_misses` is
|
|
45
|
+
* populated from that broader, role-agnostic match set instead.
|
|
46
|
+
*
|
|
47
|
+
* Near-miss entries use `genSelector` (not `genSelectorInfo`), so the
|
|
48
|
+
* `ambiguous` flag is intentionally NOT carried — a near-miss selector
|
|
49
|
+
* that collides with structurally-identical twins in other roots resolves
|
|
50
|
+
* first-match-wins silently. Documented on the tool as: hints for the
|
|
51
|
+
* next `find`, never click targets.
|
|
36
52
|
*/
|
|
37
53
|
export interface FindOpts {
|
|
38
54
|
text: string;
|
|
@@ -47,8 +63,16 @@ export declare function buildFindJs(opts: FindOpts): string;
|
|
|
47
63
|
* is set — hit-tests that point before returning it, so a covering overlay
|
|
48
64
|
* is caught before background.ts dispatches CDP mouse events. Returns:
|
|
49
65
|
* { ok: true, x, y, tag }
|
|
66
|
+
* { ok: false, reason: 'invalid-selector', error }
|
|
50
67
|
* { ok: false, reason: 'not-found' }
|
|
51
68
|
* { ok: false, reason: 'occluded', blocker }
|
|
69
|
+
*
|
|
70
|
+
* The `invalid-selector` check runs BEFORE `deepQueryFirst` — a malformed
|
|
71
|
+
* CSS selector throws the identical `SyntaxError` from every root's own
|
|
72
|
+
* `querySelector`, which `deepQueryFirst`'s per-root try/catch otherwise
|
|
73
|
+
* swallows into an indistinguishable "not-found". Checking once against
|
|
74
|
+
* `document` up front separates "the selector text is broken" from "the
|
|
75
|
+
* selector is valid but nothing on the page matches it".
|
|
52
76
|
*/
|
|
53
77
|
export interface ClickResolveOpts {
|
|
54
78
|
selector: string;
|
|
@@ -61,7 +85,13 @@ export declare function buildClickResolveJs(opts: ClickResolveOpts): string;
|
|
|
61
85
|
* success so background.ts can follow up with CDP `Input.insertText`
|
|
62
86
|
* (which types into whatever currently has focus at the browser level —
|
|
63
87
|
* works the same whether that focus target lives in the top document, a
|
|
64
|
-
* shadow root, or a same-origin iframe).
|
|
88
|
+
* shadow root, or a same-origin iframe). Returns:
|
|
89
|
+
* { ok: true }
|
|
90
|
+
* { ok: false, reason: 'invalid-selector', error }
|
|
91
|
+
* { ok: false, reason: 'not-found' }
|
|
92
|
+
*
|
|
93
|
+
* Same invalid-selector pre-check as `buildClickResolveJs` — see its doc
|
|
94
|
+
* comment for why the check has to run before `deepQueryFirst`.
|
|
65
95
|
*/
|
|
66
96
|
export interface TypeResolveOpts {
|
|
67
97
|
selector: string;
|
|
@@ -109,3 +139,27 @@ export interface SettleOpts {
|
|
|
109
139
|
settle_timeout_ms: number;
|
|
110
140
|
}
|
|
111
141
|
export declare function buildSettleJs(opts: SettleOpts): string;
|
|
142
|
+
/**
|
|
143
|
+
* Build the `browser.state` expression: a compact orientation snapshot —
|
|
144
|
+
* current url/title, the deep-resolved focused element, visible dialog-role
|
|
145
|
+
* elements, scroll position, and viewport size. Cheaper than a full
|
|
146
|
+
* `browser.snapshot` when the agent only needs "where am I right now".
|
|
147
|
+
*
|
|
148
|
+
* `focused` descends through `document.activeElement` past shadow-root and
|
|
149
|
+
* same-origin-iframe boundaries to the real innermost focused element (a
|
|
150
|
+
* shadow host or an <iframe> being "active" at one level is not the actual
|
|
151
|
+
* focus target the agent cares about). Its `selector` goes through the same
|
|
152
|
+
* `genSelectorInfo` uniqueness check `snapshot`/`find` use, so it carries
|
|
153
|
+
* `ambiguous: true` under the same structurally-identical-twins condition.
|
|
154
|
+
*
|
|
155
|
+
* `dialogs` matches visible `[role=dialog]`, `[role=alertdialog]` and open
|
|
156
|
+
* `<dialog>` elements found via the same deep walk, with a best-effort
|
|
157
|
+
* `label` resolved from aria-label / aria-labelledby / the first heading
|
|
158
|
+
* inside the dialog.
|
|
159
|
+
*
|
|
160
|
+
* Every optional field is omitted when there is nothing to report: no
|
|
161
|
+
* `focused` beyond `<body>`, no `dialogs` when none are open, and no
|
|
162
|
+
* `scroll` when the page is at its default (0,0) position — token-lean by
|
|
163
|
+
* construction, matching the omit-falsy convention the other builders use.
|
|
164
|
+
*/
|
|
165
|
+
export declare function buildStateJs(): string;
|
|
@@ -121,6 +121,7 @@ export function buildFindJs(opts) {
|
|
|
121
121
|
role: typeof opts.role === 'string' && opts.role.length > 0 ? opts.role : null,
|
|
122
122
|
exact: opts.exact === true,
|
|
123
123
|
candidateLimit: 5,
|
|
124
|
+
nearMissLimit: 3,
|
|
124
125
|
});
|
|
125
126
|
return `
|
|
126
127
|
(() => {
|
|
@@ -128,6 +129,7 @@ export function buildFindJs(opts) {
|
|
|
128
129
|
${DOM_HELPERS_JS}
|
|
129
130
|
const opts = ${optsJson};
|
|
130
131
|
const needle = opts.text.toLowerCase();
|
|
132
|
+
const needleTokens = needle.split(/[^a-z0-9]+/).filter(Boolean);
|
|
131
133
|
const ROLE_SELECTORS = {
|
|
132
134
|
button: 'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',
|
|
133
135
|
link: 'a[href], [role="link"]',
|
|
@@ -136,9 +138,10 @@ export function buildFindJs(opts) {
|
|
|
136
138
|
tab: '[role="tab"]',
|
|
137
139
|
menuitem: '[role="menuitem"]',
|
|
138
140
|
};
|
|
141
|
+
const BROAD_SELECTOR = 'button, a, input, textarea, select, [role], [onclick], [contenteditable="true"], [tabindex]';
|
|
139
142
|
const selectorSet = opts.role && ROLE_SELECTORS[opts.role]
|
|
140
143
|
? ROLE_SELECTORS[opts.role]
|
|
141
|
-
:
|
|
144
|
+
: BROAD_SELECTOR;
|
|
142
145
|
const all = deepQueryAll(selectorSet);
|
|
143
146
|
const matches = [];
|
|
144
147
|
for (const el of all) {
|
|
@@ -150,7 +153,79 @@ export function buildFindJs(opts) {
|
|
|
150
153
|
if (ok) matches.push(el);
|
|
151
154
|
}
|
|
152
155
|
if (matches.length === 0) {
|
|
153
|
-
|
|
156
|
+
// Near-miss ranking: containment beats token overlap; anything scoring
|
|
157
|
+
// 0 is dropped so the suggestion list never pads itself with noise.
|
|
158
|
+
function snippetOf(el) {
|
|
159
|
+
const t = accessibleText(el).trim();
|
|
160
|
+
return t.length > 60 ? t.slice(0, 60) + '...' : t;
|
|
161
|
+
}
|
|
162
|
+
function scoreText(text) {
|
|
163
|
+
const lower = text.toLowerCase();
|
|
164
|
+
const contains = lower.includes(needle);
|
|
165
|
+
const candTokens = lower.split(/[^a-z0-9]+/).filter(Boolean);
|
|
166
|
+
let overlap = 0;
|
|
167
|
+
for (let i = 0; i < needleTokens.length; i++) {
|
|
168
|
+
if (candTokens.indexOf(needleTokens[i]) !== -1) overlap++;
|
|
169
|
+
}
|
|
170
|
+
if (!contains && overlap === 0) return -1;
|
|
171
|
+
return (contains ? 1000 : 0) + overlap * 10;
|
|
172
|
+
}
|
|
173
|
+
function rankCandidates(elements) {
|
|
174
|
+
const scored = [];
|
|
175
|
+
for (const el of elements) {
|
|
176
|
+
if (!isVisible(el)) continue;
|
|
177
|
+
const text = accessibleText(el).trim();
|
|
178
|
+
if (text.length === 0) continue;
|
|
179
|
+
const score = scoreText(text);
|
|
180
|
+
if (score < 0) continue;
|
|
181
|
+
scored.push({ el: el, score: score });
|
|
182
|
+
}
|
|
183
|
+
scored.sort((a, b) => b.score - a.score);
|
|
184
|
+
return scored.slice(0, opts.nearMissLimit).map((s) => s.el);
|
|
185
|
+
}
|
|
186
|
+
function toNearMiss(el) {
|
|
187
|
+
const entry = { text: snippetOf(el), selector: genSelector(el) };
|
|
188
|
+
const roleAttr = el.getAttribute('role');
|
|
189
|
+
if (roleAttr) entry.role = roleAttr;
|
|
190
|
+
return entry;
|
|
191
|
+
}
|
|
192
|
+
function describeForError(el) {
|
|
193
|
+
const tag = el.tagName.toLowerCase();
|
|
194
|
+
if (el.hasAttribute('onclick')) return '<' + tag + ' onclick>';
|
|
195
|
+
const role = el.getAttribute('role');
|
|
196
|
+
if (role) return '<' + tag + ' role="' + role + '">';
|
|
197
|
+
return '<' + tag + '>';
|
|
198
|
+
}
|
|
199
|
+
const result = { matched: false, reason: 'not-found' };
|
|
200
|
+
if (opts.role) {
|
|
201
|
+
// Role narrowed the scan — check whether the text exists OUTSIDE the
|
|
202
|
+
// role filter so the error can name the exclusion explicitly instead
|
|
203
|
+
// of reporting a bare not-found.
|
|
204
|
+
const broadAll = deepQueryAll(BROAD_SELECTOR);
|
|
205
|
+
const broadTextMatches = [];
|
|
206
|
+
for (const el of broadAll) {
|
|
207
|
+
if (!isVisible(el)) continue;
|
|
208
|
+
const text = accessibleText(el).trim();
|
|
209
|
+
if (text.length === 0) continue;
|
|
210
|
+
if (text.toLowerCase().includes(needle)) broadTextMatches.push(el);
|
|
211
|
+
}
|
|
212
|
+
if (broadTextMatches.length > 0) {
|
|
213
|
+
const ranked = rankCandidates(broadTextMatches);
|
|
214
|
+
const closest = ranked[0];
|
|
215
|
+
result.error = 'text matched ' + broadTextMatches.length + ' element' +
|
|
216
|
+
(broadTextMatches.length === 1 ? '' : 's') +
|
|
217
|
+
' but none with role "' + opts.role + '"' +
|
|
218
|
+
(closest ? ' — closest: ' + describeForError(closest) + ' "' + snippetOf(closest) + '"' : '');
|
|
219
|
+
result.near_misses = ranked.map(toNearMiss);
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
const ranked = rankCandidates(broadAll);
|
|
223
|
+
if (ranked.length > 0) result.near_misses = ranked.map(toNearMiss);
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
const ranked = rankCandidates(all);
|
|
227
|
+
if (ranked.length > 0) result.near_misses = ranked.map(toNearMiss);
|
|
228
|
+
return result;
|
|
154
229
|
}
|
|
155
230
|
if (matches.length > 1) {
|
|
156
231
|
return {
|
|
@@ -189,6 +264,11 @@ export function buildClickResolveJs(opts) {
|
|
|
189
264
|
(() => {
|
|
190
265
|
${DEEP_QUERY_JS}
|
|
191
266
|
const opts = ${optsJson};
|
|
267
|
+
try {
|
|
268
|
+
document.querySelector(opts.selector);
|
|
269
|
+
} catch (e) {
|
|
270
|
+
return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
|
|
271
|
+
}
|
|
192
272
|
const el = deepQueryFirst(opts.selector);
|
|
193
273
|
if (!el) return { ok: false, reason: 'not-found' };
|
|
194
274
|
const chain = frameElementChain(el);
|
|
@@ -214,11 +294,16 @@ export function buildTypeResolveJs(opts) {
|
|
|
214
294
|
(() => {
|
|
215
295
|
${DEEP_QUERY_JS}
|
|
216
296
|
const opts = ${optsJson};
|
|
297
|
+
try {
|
|
298
|
+
document.querySelector(opts.selector);
|
|
299
|
+
} catch (e) {
|
|
300
|
+
return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
|
|
301
|
+
}
|
|
217
302
|
const el = deepQueryFirst(opts.selector);
|
|
218
|
-
if (!el) return false;
|
|
303
|
+
if (!el) return { ok: false, reason: 'not-found' };
|
|
219
304
|
el.focus();
|
|
220
305
|
${opts.clear ? "if ('value' in el) { el.value = ''; el.dispatchEvent(new Event('input', { bubbles: true })); }" : ''}
|
|
221
|
-
return true;
|
|
306
|
+
return { ok: true };
|
|
222
307
|
})()`;
|
|
223
308
|
}
|
|
224
309
|
export function buildFocusJs(opts) {
|
|
@@ -287,4 +372,116 @@ export function buildSettleJs(opts) {
|
|
|
287
372
|
});
|
|
288
373
|
})()`;
|
|
289
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Build the `browser.state` expression: a compact orientation snapshot —
|
|
377
|
+
* current url/title, the deep-resolved focused element, visible dialog-role
|
|
378
|
+
* elements, scroll position, and viewport size. Cheaper than a full
|
|
379
|
+
* `browser.snapshot` when the agent only needs "where am I right now".
|
|
380
|
+
*
|
|
381
|
+
* `focused` descends through `document.activeElement` past shadow-root and
|
|
382
|
+
* same-origin-iframe boundaries to the real innermost focused element (a
|
|
383
|
+
* shadow host or an <iframe> being "active" at one level is not the actual
|
|
384
|
+
* focus target the agent cares about). Its `selector` goes through the same
|
|
385
|
+
* `genSelectorInfo` uniqueness check `snapshot`/`find` use, so it carries
|
|
386
|
+
* `ambiguous: true` under the same structurally-identical-twins condition.
|
|
387
|
+
*
|
|
388
|
+
* `dialogs` matches visible `[role=dialog]`, `[role=alertdialog]` and open
|
|
389
|
+
* `<dialog>` elements found via the same deep walk, with a best-effort
|
|
390
|
+
* `label` resolved from aria-label / aria-labelledby / the first heading
|
|
391
|
+
* inside the dialog.
|
|
392
|
+
*
|
|
393
|
+
* Every optional field is omitted when there is nothing to report: no
|
|
394
|
+
* `focused` beyond `<body>`, no `dialogs` when none are open, and no
|
|
395
|
+
* `scroll` when the page is at its default (0,0) position — token-lean by
|
|
396
|
+
* construction, matching the omit-falsy convention the other builders use.
|
|
397
|
+
*/
|
|
398
|
+
export function buildStateJs() {
|
|
399
|
+
return `
|
|
400
|
+
(() => {
|
|
401
|
+
${DEEP_QUERY_JS}
|
|
402
|
+
${DOM_HELPERS_JS}
|
|
403
|
+
function deepActiveElement() {
|
|
404
|
+
let el = document.activeElement;
|
|
405
|
+
let guard = 0;
|
|
406
|
+
while (el && guard < 20) {
|
|
407
|
+
guard++;
|
|
408
|
+
if (el.shadowRoot && el.shadowRoot.activeElement) {
|
|
409
|
+
el = el.shadowRoot.activeElement;
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (el.tagName === 'IFRAME') {
|
|
413
|
+
let innerDoc = null;
|
|
414
|
+
try {
|
|
415
|
+
innerDoc = el.contentDocument;
|
|
416
|
+
} catch (_) {
|
|
417
|
+
innerDoc = null;
|
|
418
|
+
}
|
|
419
|
+
if (innerDoc && innerDoc.activeElement && innerDoc.activeElement !== innerDoc.body) {
|
|
420
|
+
el = innerDoc.activeElement;
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
return el;
|
|
427
|
+
}
|
|
428
|
+
function dialogLabel(el) {
|
|
429
|
+
const aria = el.getAttribute('aria-label');
|
|
430
|
+
if (aria) return aria;
|
|
431
|
+
const labelledby = el.getAttribute('aria-labelledby');
|
|
432
|
+
if (labelledby) {
|
|
433
|
+
const ids = labelledby.split(/\\s+/);
|
|
434
|
+
const parts = [];
|
|
435
|
+
for (let i = 0; i < ids.length; i++) {
|
|
436
|
+
if (!ids[i]) continue;
|
|
437
|
+
const target = deepQueryFirst('#' + CSS.escape(ids[i]));
|
|
438
|
+
if (target) {
|
|
439
|
+
const t = shortText(target);
|
|
440
|
+
if (t) parts.push(t);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
const joined = parts.join(' ').trim();
|
|
444
|
+
if (joined) return joined;
|
|
445
|
+
}
|
|
446
|
+
const heading = deepQueryFirst('h1, h2, h3', el);
|
|
447
|
+
if (heading) {
|
|
448
|
+
const t = shortText(heading);
|
|
449
|
+
if (t) return t;
|
|
450
|
+
}
|
|
451
|
+
return '';
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const result = {
|
|
455
|
+
url: location.href,
|
|
456
|
+
title: document.title,
|
|
457
|
+
viewport: { w: window.innerWidth, h: window.innerHeight },
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
const active = deepActiveElement();
|
|
461
|
+
if (active && active !== document.body && active.tagName) {
|
|
462
|
+
const selInfo = genSelectorInfo(active);
|
|
463
|
+
const focused = { selector: selInfo.selector, tag: active.tagName.toLowerCase() };
|
|
464
|
+
if (selInfo.ambiguous) focused.ambiguous = true;
|
|
465
|
+
result.focused = focused;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const dialogs = [];
|
|
469
|
+
deepQueryAll('[role="dialog"], [role="alertdialog"], dialog[open]').forEach((el) => {
|
|
470
|
+
if (!isVisible(el)) return;
|
|
471
|
+
const role = el.getAttribute('role') || 'dialog';
|
|
472
|
+
const entry = { selector: genSelector(el), role: role };
|
|
473
|
+
const label = dialogLabel(el);
|
|
474
|
+
if (label) entry.label = label;
|
|
475
|
+
dialogs.push(entry);
|
|
476
|
+
});
|
|
477
|
+
if (dialogs.length > 0) result.dialogs = dialogs;
|
|
478
|
+
|
|
479
|
+
const scrollX = Math.round(window.scrollX);
|
|
480
|
+
const scrollY = Math.round(window.scrollY);
|
|
481
|
+
if (scrollX !== 0 || scrollY !== 0) result.scroll = { x: scrollX, y: scrollY };
|
|
482
|
+
|
|
483
|
+
return result;
|
|
484
|
+
})()
|
|
485
|
+
`;
|
|
486
|
+
}
|
|
290
487
|
//# sourceMappingURL=builders.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAwBlD,MAAM,UAAU,eAAe,CAAC,OAAqB,EAAE;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,cAAc,EAAE,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;QACtF,eAAe,EAAE,IAAI,CAAC,gBAAgB,KAAK,IAAI;QAC/C,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACxD,cAAc,EACZ,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC;YAClE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC;YACrC,CAAC,CAAC,GAAG;KACV,CAAC,CAAC;IACH,OAAO;;IAEL,aAAa;IACb,cAAc;iBACD,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4FxB,CAAC;AACF,CAAC;
|
|
1
|
+
{"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "browser-link",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.18.0",
|
|
5
5
|
"description": "Bridge between Chrome and an MCP client (Claude Code, OpenCode, GitHub Copilot CLI, …). Per-tab manual activation.",
|
|
6
6
|
"permissions": [
|
|
7
7
|
"debugger",
|
package/dist/map/db.js
CHANGED
|
@@ -71,6 +71,32 @@ function runMigrations(db) {
|
|
|
71
71
|
|
|
72
72
|
CREATE INDEX IF NOT EXISTS idx_entries_lookup ON entries(app_id, url_pattern);
|
|
73
73
|
`);
|
|
74
|
+
// v0.18.0: named, replayable browser.flow recipes per app. Deliberately a
|
|
75
|
+
// separate table from `entries` — the pre-existing `entries.kind='flow'`
|
|
76
|
+
// is a free-form payload with no shape guarantee, while a row here always
|
|
77
|
+
// holds a `steps_json` array validated against the EXACT browser.flow step
|
|
78
|
+
// grammar (see `validateFlowSteps` in tools/browser-dispatch.ts, reused by
|
|
79
|
+
// map/tools.ts). Not scoped by url_pattern like entries — a flow recipe
|
|
80
|
+
// is identified by (app, name) only, since a multi-step recipe is not
|
|
81
|
+
// tied to a single route the way a selector or gotcha usually is.
|
|
82
|
+
// Same idempotent CREATE-TABLE-IF-NOT-EXISTS pattern as above, so an
|
|
83
|
+
// existing DB from before this table existed picks it up on next getDb()
|
|
84
|
+
// without touching any pre-existing row.
|
|
85
|
+
db.exec(`
|
|
86
|
+
CREATE TABLE IF NOT EXISTS flows (
|
|
87
|
+
id INTEGER PRIMARY KEY,
|
|
88
|
+
app_id INTEGER NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
|
|
89
|
+
name TEXT NOT NULL,
|
|
90
|
+
description TEXT,
|
|
91
|
+
steps_json TEXT NOT NULL,
|
|
92
|
+
created_at TEXT NOT NULL,
|
|
93
|
+
updated_at TEXT NOT NULL,
|
|
94
|
+
use_count INTEGER NOT NULL DEFAULT 0,
|
|
95
|
+
UNIQUE(app_id, name)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
CREATE INDEX IF NOT EXISTS idx_flows_app ON flows(app_id);
|
|
99
|
+
`);
|
|
74
100
|
}
|
|
75
101
|
export function closeDb() {
|
|
76
102
|
if (dbInstance) {
|
package/dist/map/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/map/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,IAAI,UAAU,GAA6B,IAAI,CAAC;AAEhD,MAAM,UAAU,KAAK;IACnB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,UAAU,GAAG,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,UAAkB;IACzC,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7F,OAAO;IACT,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,EAAqB;IAC1C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/map/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,IAAI,UAAU,GAA6B,IAAI,CAAC;AAEhD,MAAM,UAAU,KAAK;IACnB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,UAAU,GAAG,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,UAAkB;IACzC,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7F,OAAO;IACT,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,EAAqB;IAC1C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BP,CAAC,CAAC;IAEH,0EAA0E;IAC1E,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,wEAAwE;IACxE,sEAAsE;IACtE,kEAAkE;IAClE,qEAAqE;IACrE,yEAAyE;IACzE,yCAAyC;IACzC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;GAcP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;AACH,CAAC"}
|
package/dist/map/queries.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export interface RecallInput {
|
|
|
50
50
|
export interface RecallResult {
|
|
51
51
|
app: AppRow | null;
|
|
52
52
|
entries: EntryRow[];
|
|
53
|
+
flows: FlowRow[];
|
|
53
54
|
}
|
|
54
55
|
export declare function recall(input: RecallInput): RecallResult;
|
|
55
56
|
export interface RecordUseInput {
|
|
@@ -70,3 +71,31 @@ export interface ForgetResult {
|
|
|
70
71
|
export declare function forget(input: ForgetInput): ForgetResult;
|
|
71
72
|
export declare function renameApp(app_id: number, new_app_key: string): AppRow | null;
|
|
72
73
|
export declare function listApps(): AppRow[];
|
|
74
|
+
export interface FlowRow {
|
|
75
|
+
id: number;
|
|
76
|
+
app_id: number;
|
|
77
|
+
name: string;
|
|
78
|
+
description: string | null;
|
|
79
|
+
steps: unknown;
|
|
80
|
+
created_at: string;
|
|
81
|
+
updated_at: string;
|
|
82
|
+
use_count: number;
|
|
83
|
+
}
|
|
84
|
+
export interface SaveFlowInput {
|
|
85
|
+
origin: string;
|
|
86
|
+
app_key?: string | null;
|
|
87
|
+
title?: string | null;
|
|
88
|
+
name: string;
|
|
89
|
+
description?: string | null;
|
|
90
|
+
steps: unknown;
|
|
91
|
+
}
|
|
92
|
+
/** Upsert on (app, name) — saving an existing name replaces its
|
|
93
|
+
* description/steps and bumps updated_at, mirroring saveEntry's upsert
|
|
94
|
+
* semantics. `use_count` is left untouched on update (re-saving is not a
|
|
95
|
+
* "use"). */
|
|
96
|
+
export declare function saveFlow(input: SaveFlowInput): {
|
|
97
|
+
app: AppRow;
|
|
98
|
+
flow: FlowRow;
|
|
99
|
+
};
|
|
100
|
+
/** Every flow recipe saved for an app, alphabetical by name. */
|
|
101
|
+
export declare function listFlows(app_id: number): FlowRow[];
|
package/dist/map/queries.js
CHANGED
|
@@ -99,7 +99,7 @@ export function recall(input) {
|
|
|
99
99
|
.get(input.origin);
|
|
100
100
|
}
|
|
101
101
|
if (!app)
|
|
102
|
-
return { app: null, entries: [] };
|
|
102
|
+
return { app: null, entries: [], flows: [] };
|
|
103
103
|
// Touch last_seen_at so apps that are actively used bubble up.
|
|
104
104
|
db.prepare('UPDATE apps SET last_seen_at = ? WHERE id = ?').run(now(), app.id);
|
|
105
105
|
const pathname = input.url ? extractPathname(input.url) : null;
|
|
@@ -110,7 +110,10 @@ export function recall(input) {
|
|
|
110
110
|
: db
|
|
111
111
|
.prepare(`SELECT * FROM entries WHERE app_id = ? ORDER BY url_pattern, updated_at DESC`)
|
|
112
112
|
.all(app.id));
|
|
113
|
-
|
|
113
|
+
// Flow recipes are not url_pattern-scoped (see the schema comment in
|
|
114
|
+
// db.ts) — recall always returns every flow saved for the app, regardless
|
|
115
|
+
// of the optional `url` filter.
|
|
116
|
+
return { app, entries: rows.map(hydrate), flows: listFlows(app.id) };
|
|
114
117
|
}
|
|
115
118
|
function extractPathname(url) {
|
|
116
119
|
try {
|
|
@@ -159,4 +162,43 @@ export function renameApp(app_id, new_app_key) {
|
|
|
159
162
|
export function listApps() {
|
|
160
163
|
return getDb().prepare('SELECT * FROM apps ORDER BY last_seen_at DESC').all();
|
|
161
164
|
}
|
|
165
|
+
function hydrateFlow(row) {
|
|
166
|
+
const { steps_json, ...rest } = row;
|
|
167
|
+
return { ...rest, steps: parsePayload(steps_json) };
|
|
168
|
+
}
|
|
169
|
+
/** Upsert on (app, name) — saving an existing name replaces its
|
|
170
|
+
* description/steps and bumps updated_at, mirroring saveEntry's upsert
|
|
171
|
+
* semantics. `use_count` is left untouched on update (re-saving is not a
|
|
172
|
+
* "use"). */
|
|
173
|
+
export function saveFlow(input) {
|
|
174
|
+
const app = upsertApp({
|
|
175
|
+
origin: input.origin,
|
|
176
|
+
app_key: input.app_key ?? null,
|
|
177
|
+
title: input.title ?? null,
|
|
178
|
+
});
|
|
179
|
+
const ts = now();
|
|
180
|
+
const stepsJson = JSON.stringify(input.steps);
|
|
181
|
+
const db = getDb();
|
|
182
|
+
const existing = db
|
|
183
|
+
.prepare('SELECT * FROM flows WHERE app_id = ? AND name = ?')
|
|
184
|
+
.get(app.id, input.name);
|
|
185
|
+
if (existing) {
|
|
186
|
+
db.prepare('UPDATE flows SET description = ?, steps_json = ?, updated_at = ? WHERE id = ?').run(input.description ?? null, stepsJson, ts, existing.id);
|
|
187
|
+
const updated = db.prepare('SELECT * FROM flows WHERE id = ?').get(existing.id);
|
|
188
|
+
return { app, flow: hydrateFlow(updated) };
|
|
189
|
+
}
|
|
190
|
+
const info = db
|
|
191
|
+
.prepare(`INSERT INTO flows (app_id, name, description, steps_json, created_at, updated_at, use_count)
|
|
192
|
+
VALUES (?, ?, ?, ?, ?, ?, 0)`)
|
|
193
|
+
.run(app.id, input.name, input.description ?? null, stepsJson, ts, ts);
|
|
194
|
+
const inserted = db.prepare('SELECT * FROM flows WHERE id = ?').get(info.lastInsertRowid);
|
|
195
|
+
return { app, flow: hydrateFlow(inserted) };
|
|
196
|
+
}
|
|
197
|
+
/** Every flow recipe saved for an app, alphabetical by name. */
|
|
198
|
+
export function listFlows(app_id) {
|
|
199
|
+
const rows = getDb()
|
|
200
|
+
.prepare('SELECT * FROM flows WHERE app_id = ? ORDER BY name')
|
|
201
|
+
.all(app_id);
|
|
202
|
+
return rows.map(hydrateFlow);
|
|
203
|
+
}
|
|
162
204
|
//# sourceMappingURL=queries.js.map
|
package/dist/map/queries.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/map/queries.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/map/queries.ts"],"names":[],"mappings":"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"}
|