@jobshimo/browser-link 0.28.9 → 0.30.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/activity/extract.js +3 -0
- package/dist/activity/extract.js.map +1 -1
- package/dist/agent-instructions/content.js +11 -1
- package/dist/agent-instructions/content.js.map +1 -1
- package/dist/bridge/dispatch.js +5 -3
- package/dist/bridge/dispatch.js.map +1 -1
- package/dist/bridge/events.d.ts +1 -1
- package/dist/bridge/events.js.map +1 -1
- package/dist/cdp/inpage/builders.d.ts +15 -0
- package/dist/cdp/inpage/builders.js +46 -0
- package/dist/cdp/inpage/builders.js.map +1 -1
- package/dist/cdp/screenshot.d.ts +109 -0
- package/dist/cdp/screenshot.js +189 -0
- package/dist/cdp/screenshot.js.map +1 -0
- package/dist/cdp/support.d.ts +2 -1
- package/dist/cdp/support.js +7 -1
- package/dist/cdp/support.js.map +1 -1
- package/dist/cdp/transport.js +15 -1
- package/dist/cdp/transport.js.map +1 -1
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/about.js +4 -0
- package/dist/commands/about.js.map +1 -1
- package/dist/commands/config.d.ts +12 -0
- package/dist/commands/config.js +49 -4
- package/dist/commands/config.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.js.map +1 -1
- package/dist/downloads.d.ts +127 -0
- package/dist/downloads.js +303 -0
- package/dist/downloads.js.map +1 -0
- package/dist/extension/background.js +74 -1
- package/dist/extension/background.js.map +1 -1
- package/dist/extension/download-capture.d.ts +96 -0
- package/dist/extension/download-capture.js +131 -0
- package/dist/extension/download-capture.js.map +1 -0
- package/dist/extension/inpage/builders.d.ts +15 -0
- package/dist/extension/inpage/builders.js +46 -0
- package/dist/extension/inpage/builders.js.map +1 -1
- package/dist/extension/manifest.json +1 -1
- package/dist/extension/screenshot.d.ts +113 -0
- package/dist/extension/screenshot.js +193 -0
- package/dist/extension/screenshot.js.map +1 -0
- package/dist/permissions.js +12 -0
- package/dist/permissions.js.map +1 -1
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/browser-definitions.js +101 -1
- package/dist/tools/browser-definitions.js.map +1 -1
- package/dist/tools/browser-dispatch.d.ts +12 -1
- package/dist/tools/browser-dispatch.js +171 -0
- package/dist/tools/browser-dispatch.js.map +1 -1
- package/dist/tools/responses.d.ts +14 -2
- package/dist/tools/responses.js +21 -0
- package/dist/tools/responses.js.map +1 -1
- package/dist/tools/server-instructions.js +27 -4
- package/dist/tools/server-instructions.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture the download a click starts BEFORE Chrome can show its native
|
|
3
|
+
* "Save as" dialog — the dialog nothing in CDP or the page can press.
|
|
4
|
+
*
|
|
5
|
+
* Why this shape, and not "tell Chrome to save without asking":
|
|
6
|
+
* - CDP `Browser.setDownloadBehavior` / `Page.setDownloadBehavior` answer
|
|
7
|
+
* "Not allowed" to any `chrome.debugger` client (Chromium gates them on
|
|
8
|
+
* `MayWriteLocalFiles()`, which the extension debugger host hard-codes to
|
|
9
|
+
* false).
|
|
10
|
+
* - `chrome.downloads.download({ saveAs: false })` still prompts when the
|
|
11
|
+
* user enabled "Ask where to save each file" — that preference is checked
|
|
12
|
+
* independently of the flag.
|
|
13
|
+
* - But Chrome asks every `onDeterminingFilename` listener BEFORE it gets to
|
|
14
|
+
* the prompt, and only prompts a download that is still in progress. So a
|
|
15
|
+
* listener that holds the download (returns `true`), cancels it, and only
|
|
16
|
+
* then releases `suggest()` makes the prompt unreachable.
|
|
17
|
+
*
|
|
18
|
+
* The cancelled download's URL goes back to the server, which fetches the
|
|
19
|
+
* bytes in the page and writes them itself (see the server's `downloads.ts`).
|
|
20
|
+
*
|
|
21
|
+
* The listener is registered ONLY while a capture is armed: an
|
|
22
|
+
* `onDeterminingFilename` listener makes Chrome wait on it for every
|
|
23
|
+
* download, so leaving one installed would tax every download the user makes.
|
|
24
|
+
*/
|
|
25
|
+
function originOf(url) {
|
|
26
|
+
try {
|
|
27
|
+
return new URL(url).origin;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Could this download have come from a page on `origin`? `DownloadItem` has
|
|
35
|
+
* no tab id, so this is the cheapest narrowing available: a download whose
|
|
36
|
+
* referrer (or, for a `blob:` URL, whose own origin) points at ANOTHER origin
|
|
37
|
+
* is certainly not the clicked tab's and is left alone. A download with no
|
|
38
|
+
* such evidence (a `no-referrer` page, a `data:` URL) is still taken —
|
|
39
|
+
* refusing it would turn a working capture into a timeout.
|
|
40
|
+
*/
|
|
41
|
+
export function mayComeFrom(item, origin) {
|
|
42
|
+
if (item.referrer)
|
|
43
|
+
return originOf(item.referrer) === origin;
|
|
44
|
+
if (item.url.startsWith('blob:'))
|
|
45
|
+
return originOf(item.url.slice('blob:'.length)) === origin;
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
export function createDownloadCapture(api) {
|
|
49
|
+
let armed = false;
|
|
50
|
+
return {
|
|
51
|
+
arm(timeoutMs, origin) {
|
|
52
|
+
if (armed) {
|
|
53
|
+
throw new Error('download: another browser.download is already waiting for a download');
|
|
54
|
+
}
|
|
55
|
+
armed = true;
|
|
56
|
+
let settle;
|
|
57
|
+
const result = new Promise((resolve) => {
|
|
58
|
+
settle = resolve;
|
|
59
|
+
});
|
|
60
|
+
const done = (value) => {
|
|
61
|
+
if (!armed)
|
|
62
|
+
return;
|
|
63
|
+
armed = false;
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
api.onDeterminingFilename.removeListener(listener);
|
|
66
|
+
settle(value);
|
|
67
|
+
};
|
|
68
|
+
const listener = (item, suggest) => {
|
|
69
|
+
// Not ours: return without holding it, so Chrome carries on exactly
|
|
70
|
+
// as if no listener were installed.
|
|
71
|
+
if (!armed)
|
|
72
|
+
return undefined;
|
|
73
|
+
if (origin !== undefined && !mayComeFrom(item, origin))
|
|
74
|
+
return undefined;
|
|
75
|
+
done({
|
|
76
|
+
url: item.finalUrl || item.url,
|
|
77
|
+
original_url: item.url,
|
|
78
|
+
filename: item.filename,
|
|
79
|
+
mime: item.mime ?? '',
|
|
80
|
+
});
|
|
81
|
+
// Hold Chrome (return true) until the cancel has landed; only then
|
|
82
|
+
// release it. A cancelled download is never prompted for.
|
|
83
|
+
void api
|
|
84
|
+
.cancel(item.id)
|
|
85
|
+
.then(() => api.erase({ id: item.id }))
|
|
86
|
+
.catch(() => undefined)
|
|
87
|
+
.finally(() => {
|
|
88
|
+
try {
|
|
89
|
+
suggest();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// The download is already gone — nothing left to release.
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return true;
|
|
96
|
+
};
|
|
97
|
+
const timer = setTimeout(() => {
|
|
98
|
+
done(null);
|
|
99
|
+
}, timeoutMs);
|
|
100
|
+
api.onDeterminingFilename.addListener(listener);
|
|
101
|
+
return {
|
|
102
|
+
result,
|
|
103
|
+
disarm: () => {
|
|
104
|
+
done(null);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Arm `capture`, run `click`, then wait for the download it starts. The
|
|
112
|
+
* capture is ALWAYS disarmed when the click fails or throws, so a broken
|
|
113
|
+
* click can never leave the worker-wide listener eating the user's next
|
|
114
|
+
* download (or refusing every later `browser.download` as "already waiting").
|
|
115
|
+
*/
|
|
116
|
+
export async function captureAround(capture, opts, click) {
|
|
117
|
+
const armed = capture.arm(opts.timeoutMs, opts.origin);
|
|
118
|
+
let clicked = false;
|
|
119
|
+
try {
|
|
120
|
+
const outcome = await click();
|
|
121
|
+
if (!outcome.ok)
|
|
122
|
+
return outcome;
|
|
123
|
+
clicked = true;
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
if (!clicked)
|
|
127
|
+
armed.disarm();
|
|
128
|
+
}
|
|
129
|
+
return { ok: true, captured: await armed.result };
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=download-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download-capture.js","sourceRoot":"","sources":["../src/download-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA2CH,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,IAAqB,EAAE,MAAc;IAC/D,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC;IAC7D,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC;IAC7F,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,MAAM,UAAU,qBAAqB,CAAC,GAAiB;IACrD,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,OAAO;QACL,GAAG,CAAC,SAAiB,EAAE,MAAe;YACpC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;YAC1F,CAAC;YACD,KAAK,GAAG,IAAI,CAAC;YACb,IAAI,MAAiD,CAAC;YACtD,MAAM,MAAM,GAAG,IAAI,OAAO,CAA0B,CAAC,OAAO,EAAE,EAAE;gBAC9D,MAAM,GAAG,OAAO,CAAC;YACnB,CAAC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,CAAC,KAA8B,EAAQ,EAAE;gBACpD,IAAI,CAAC,KAAK;oBAAE,OAAO;gBACnB,KAAK,GAAG,KAAK,CAAC;gBACd,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,GAAG,CAAC,qBAAqB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACnD,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC,CAAC;YAEF,MAAM,QAAQ,GAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;gBACtD,oEAAoE;gBACpE,oCAAoC;gBACpC,IAAI,CAAC,KAAK;oBAAE,OAAO,SAAS,CAAC;gBAC7B,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC;oBAAE,OAAO,SAAS,CAAC;gBACzE,IAAI,CAAC;oBACH,GAAG,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG;oBAC9B,YAAY,EAAE,IAAI,CAAC,GAAG;oBACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAC;gBACH,mEAAmE;gBACnE,0DAA0D;gBAC1D,KAAK,GAAG;qBACL,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;qBACf,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;qBACtC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;qBACtB,OAAO,CAAC,GAAG,EAAE;oBACZ,IAAI,CAAC;wBACH,OAAO,EAAE,CAAC;oBACZ,CAAC;oBAAC,MAAM,CAAC;wBACP,0DAA0D;oBAC5D,CAAC;gBACH,CAAC,CAAC,CAAC;gBACL,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;YAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,CAAC,EAAE,SAAS,CAAC,CAAC;YACd,GAAG,CAAC,qBAAqB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAEhD,OAAO;gBACL,MAAM;gBACN,MAAM,EAAE,GAAG,EAAE;oBACX,IAAI,CAAC,IAAI,CAAC,CAAC;gBACb,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAwB,EACxB,IAA4C,EAC5C,KAAiE;IAEjE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,OAAO,CAAC;QAChC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,OAAO;YAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -126,6 +126,21 @@ export interface FocusResolveOpts {
|
|
|
126
126
|
selector: string;
|
|
127
127
|
}
|
|
128
128
|
export declare function buildFocusJs(opts: FocusResolveOpts): string;
|
|
129
|
+
/**
|
|
130
|
+
* Build the element-rect probe for `browser.screenshot`'s element mode.
|
|
131
|
+
* Resolves the selector with the same deep search scope as click/find,
|
|
132
|
+
* scrolls it into view (frames first), and returns its border-box rect in
|
|
133
|
+
* TOP-document page coordinates (viewport rect + accumulated iframe content
|
|
134
|
+
* origins + top-window scroll) — the space `Page.captureScreenshot`'s
|
|
135
|
+
* `clip` expects. Returns:
|
|
136
|
+
* { ok: true, x, y, width, height }
|
|
137
|
+
* { ok: false, reason: 'invalid-selector', error }
|
|
138
|
+
* { ok: false, reason: 'not-found' }
|
|
139
|
+
*/
|
|
140
|
+
export interface ElementRectOpts {
|
|
141
|
+
selector: string;
|
|
142
|
+
}
|
|
143
|
+
export declare function buildElementRectJs(opts: ElementRectOpts): string;
|
|
129
144
|
/**
|
|
130
145
|
* Build the drag endpoint-resolution probe for `browser.drag`. Resolves
|
|
131
146
|
* `from_selector`/`to_selector` across the SAME deep search scope
|
|
@@ -323,6 +323,52 @@ export function buildFocusJs(opts) {
|
|
|
323
323
|
return true;
|
|
324
324
|
})()`;
|
|
325
325
|
}
|
|
326
|
+
export function buildElementRectJs(opts) {
|
|
327
|
+
const optsJson = JSON.stringify({ selector: opts.selector });
|
|
328
|
+
return `
|
|
329
|
+
(() => {
|
|
330
|
+
${DEEP_QUERY_JS}
|
|
331
|
+
const opts = ${optsJson};
|
|
332
|
+
try {
|
|
333
|
+
document.querySelector(opts.selector);
|
|
334
|
+
} catch (e) {
|
|
335
|
+
return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
|
|
336
|
+
}
|
|
337
|
+
const el = deepQueryFirst(opts.selector);
|
|
338
|
+
if (!el) return { ok: false, reason: 'not-found' };
|
|
339
|
+
const chain = frameElementChain(el);
|
|
340
|
+
// behavior 'instant' overrides CSS scroll-behavior: smooth, which would
|
|
341
|
+
// leave the rect below stale while the scroll is still animating.
|
|
342
|
+
const jump = { block: 'center', inline: 'center', behavior: 'instant' };
|
|
343
|
+
for (const fe of chain) {
|
|
344
|
+
if (fe.scrollIntoView) fe.scrollIntoView(jump);
|
|
345
|
+
}
|
|
346
|
+
if (el.scrollIntoView) el.scrollIntoView(jump);
|
|
347
|
+
const rect = el.getBoundingClientRect();
|
|
348
|
+
let offsetX = 0;
|
|
349
|
+
let offsetY = 0;
|
|
350
|
+
for (const fe of chain) {
|
|
351
|
+
const fr = fe.getBoundingClientRect();
|
|
352
|
+
const origin = frameViewportOriginOffset(fe);
|
|
353
|
+
offsetX += fr.left + origin.x;
|
|
354
|
+
offsetY += fr.top + origin.y;
|
|
355
|
+
}
|
|
356
|
+
let scrollX = 0;
|
|
357
|
+
let scrollY = 0;
|
|
358
|
+
try {
|
|
359
|
+
const top = window.top || window;
|
|
360
|
+
scrollX = top.scrollX || 0;
|
|
361
|
+
scrollY = top.scrollY || 0;
|
|
362
|
+
} catch (_) {}
|
|
363
|
+
return {
|
|
364
|
+
ok: true,
|
|
365
|
+
x: offsetX + rect.left + scrollX,
|
|
366
|
+
y: offsetY + rect.top + scrollY,
|
|
367
|
+
width: rect.width,
|
|
368
|
+
height: rect.height,
|
|
369
|
+
};
|
|
370
|
+
})()`;
|
|
371
|
+
}
|
|
326
372
|
export function buildDragProbeJs(opts) {
|
|
327
373
|
const optsJson = JSON.stringify({
|
|
328
374
|
from_selector: opts.from_selector,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"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"}
|
|
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;AA6BlD,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FxB,CAAC;AACF,CAAC;AAwCD,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QAC9E,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI;QAC1B,cAAc,EAAE,CAAC;QACjB,aAAa,EAAE,CAAC;KACjB,CAAC,CAAC;IACH,OAAO;;IAEL,aAAa;IACb,cAAc;iBACD,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmIxB,CAAC;AACF,CAAC;AAiCD,MAAM,UAAU,mBAAmB,CAAC,IAAsB;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAChF,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;CAwBxB,CAAC;AACF,CAAC;AAqBD,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;;;;;;IASrB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gGAAgG,CAAC,CAAC,CAAC,EAAE;;KAEjH,CAAC;AACN,CAAC;AAeD,MAAM,UAAU,YAAY,CAAC,IAAsB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;;KAKpB,CAAC;AACN,CAAC;AAiBD,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuCpB,CAAC;AACN,CAAC;AAwCD,MAAM,UAAU,gBAAgB,CAAC,IAAmB;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAC;IACH,OAAO;;IAEL,aAAa;cACH,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsDrB,CAAC;AACF,CAAC;AA8BD,MAAM,UAAU,aAAa,CAAC,IAAgB;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;QACrC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC;KAC/C,CAAC,CAAC;IACH,OAAO;;iBAEQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6CpB,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;;IAEL,aAAa;IACb,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFjB,CAAC;AACF,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "browser-link",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.30.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",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `browser.screenshot` planning and capture, shared by the extension
|
|
3
|
+
* (`chrome.debugger`) and — as a verbatim copy at
|
|
4
|
+
* `packages/server/src/cdp/screenshot.ts`, guarded by `cdp/drift.test.ts` —
|
|
5
|
+
* the cdp-direct transport. Both speak raw CDP, so the logic is identical;
|
|
6
|
+
* it only needs a `send(method, params)` primitive and an element-rect
|
|
7
|
+
* resolver, which makes it unit-testable without Chrome.
|
|
8
|
+
*
|
|
9
|
+
* Coordinates: `Page.captureScreenshot`'s `clip` is in CSS pixels of the
|
|
10
|
+
* page (document) space; `scale` multiplies it into output pixels.
|
|
11
|
+
*/
|
|
12
|
+
export type ScreenshotMode = 'viewport' | 'full_page' | 'element';
|
|
13
|
+
export type ScreenshotFormat = 'png' | 'jpeg';
|
|
14
|
+
export declare const DEFAULT_MAX_DIMENSION = 8000;
|
|
15
|
+
/** Below this scale the text in a page is unreadable; crop instead. */
|
|
16
|
+
export declare const MIN_SCALE = 0.25;
|
|
17
|
+
/** Cap on the decoded image size returned to the agent. */
|
|
18
|
+
export declare const MAX_IMAGE_BYTES: number;
|
|
19
|
+
export declare const DEFAULT_JPEG_QUALITY = 80;
|
|
20
|
+
export interface Size {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}
|
|
24
|
+
export interface Rect extends Size {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
}
|
|
28
|
+
export interface LayoutMetrics {
|
|
29
|
+
cssContentSize?: Size;
|
|
30
|
+
contentSize?: Size;
|
|
31
|
+
cssVisualViewport?: {
|
|
32
|
+
pageX: number;
|
|
33
|
+
pageY: number;
|
|
34
|
+
clientWidth: number;
|
|
35
|
+
clientHeight: number;
|
|
36
|
+
};
|
|
37
|
+
visualViewport?: {
|
|
38
|
+
pageX: number;
|
|
39
|
+
pageY: number;
|
|
40
|
+
clientWidth: number;
|
|
41
|
+
clientHeight: number;
|
|
42
|
+
};
|
|
43
|
+
/** Layout viewport in device pixels / CSS pixels — their ratio is the DPR. */
|
|
44
|
+
layoutViewport?: {
|
|
45
|
+
clientWidth: number;
|
|
46
|
+
};
|
|
47
|
+
cssLayoutViewport?: {
|
|
48
|
+
clientWidth: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export interface ScreenshotPlan {
|
|
52
|
+
clip: Rect & {
|
|
53
|
+
scale: number;
|
|
54
|
+
};
|
|
55
|
+
/** Output size in pixels. */
|
|
56
|
+
width: number;
|
|
57
|
+
height: number;
|
|
58
|
+
scale: number;
|
|
59
|
+
/** Device pixels per CSS pixel; the capture is clip x scale x dpr pixels. */
|
|
60
|
+
dpr: number;
|
|
61
|
+
truncated: boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Device pixels per CSS pixel, derived from the layout metrics (no extra
|
|
65
|
+
* in-page round trip): layout-viewport width ratio, else content-size
|
|
66
|
+
* ratio, else 1.
|
|
67
|
+
*/
|
|
68
|
+
export declare function dprFromMetrics(m: LayoutMetrics): number;
|
|
69
|
+
export declare function planClip(mode: ScreenshotMode, metrics: LayoutMetrics, elementRect: Rect | undefined, maxDimension: number): ScreenshotPlan;
|
|
70
|
+
/** Decoded byte length of a base64 string. */
|
|
71
|
+
export declare function base64ByteLength(b64: string): number;
|
|
72
|
+
export interface Attempt {
|
|
73
|
+
format: ScreenshotFormat;
|
|
74
|
+
scale: number;
|
|
75
|
+
quality: number | undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* What to try after an image came back over the byte cap: PNG → JPEG at the
|
|
79
|
+
* same scale, then JPEG at a scale reduced in proportion to the overshoot.
|
|
80
|
+
* `null` when nothing smaller is worth trying.
|
|
81
|
+
*/
|
|
82
|
+
export declare function nextOversizeAttempt(prev: Attempt, bytes: number, cap: number): Attempt | null;
|
|
83
|
+
export type ElementRectOutcome = ({
|
|
84
|
+
ok: true;
|
|
85
|
+
} & Rect) | {
|
|
86
|
+
ok: false;
|
|
87
|
+
reason: 'invalid-selector' | 'not-found';
|
|
88
|
+
error?: string;
|
|
89
|
+
};
|
|
90
|
+
export interface ScreenshotDeps {
|
|
91
|
+
send: (method: string, params?: Record<string, unknown>) => Promise<unknown>;
|
|
92
|
+
resolveElementRect: (selector: string) => Promise<ElementRectOutcome>;
|
|
93
|
+
}
|
|
94
|
+
export interface ScreenshotOptions {
|
|
95
|
+
mode?: ScreenshotMode;
|
|
96
|
+
selector?: string;
|
|
97
|
+
format?: ScreenshotFormat;
|
|
98
|
+
quality?: number;
|
|
99
|
+
maxDimension?: number;
|
|
100
|
+
}
|
|
101
|
+
export interface ScreenshotResult {
|
|
102
|
+
ok: true;
|
|
103
|
+
mode: ScreenshotMode;
|
|
104
|
+
format: ScreenshotFormat;
|
|
105
|
+
width: number;
|
|
106
|
+
height: number;
|
|
107
|
+
scale: number;
|
|
108
|
+
bytes: number;
|
|
109
|
+
truncated?: true;
|
|
110
|
+
size_reduced?: true;
|
|
111
|
+
image_b64: string;
|
|
112
|
+
}
|
|
113
|
+
export declare function runScreenshot(deps: ScreenshotDeps, opts: ScreenshotOptions): Promise<ScreenshotResult>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `browser.screenshot` planning and capture, shared by the extension
|
|
3
|
+
* (`chrome.debugger`) and — as a verbatim copy at
|
|
4
|
+
* `packages/server/src/cdp/screenshot.ts`, guarded by `cdp/drift.test.ts` —
|
|
5
|
+
* the cdp-direct transport. Both speak raw CDP, so the logic is identical;
|
|
6
|
+
* it only needs a `send(method, params)` primitive and an element-rect
|
|
7
|
+
* resolver, which makes it unit-testable without Chrome.
|
|
8
|
+
*
|
|
9
|
+
* Coordinates: `Page.captureScreenshot`'s `clip` is in CSS pixels of the
|
|
10
|
+
* page (document) space; `scale` multiplies it into output pixels.
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_MAX_DIMENSION = 8000;
|
|
13
|
+
/** Below this scale the text in a page is unreadable; crop instead. */
|
|
14
|
+
export const MIN_SCALE = 0.25;
|
|
15
|
+
/** Hard floor when shrinking to satisfy the byte cap. */
|
|
16
|
+
const ABSOLUTE_MIN_SCALE = 0.1;
|
|
17
|
+
/** Cap on the decoded image size returned to the agent. */
|
|
18
|
+
export const MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
19
|
+
export const DEFAULT_JPEG_QUALITY = 80;
|
|
20
|
+
const MAX_ATTEMPTS = 4;
|
|
21
|
+
/**
|
|
22
|
+
* Device pixels per CSS pixel, derived from the layout metrics (no extra
|
|
23
|
+
* in-page round trip): layout-viewport width ratio, else content-size
|
|
24
|
+
* ratio, else 1.
|
|
25
|
+
*/
|
|
26
|
+
export function dprFromMetrics(m) {
|
|
27
|
+
const pairs = [
|
|
28
|
+
[m.layoutViewport?.clientWidth, m.cssLayoutViewport?.clientWidth],
|
|
29
|
+
[m.contentSize?.width, m.cssContentSize?.width],
|
|
30
|
+
[m.visualViewport?.clientWidth, m.cssVisualViewport?.clientWidth],
|
|
31
|
+
];
|
|
32
|
+
for (const [device, css] of pairs) {
|
|
33
|
+
if (positive(device) && positive(css))
|
|
34
|
+
return device / css;
|
|
35
|
+
}
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
function positive(n) {
|
|
39
|
+
return typeof n === 'number' && Number.isFinite(n) && n > 0;
|
|
40
|
+
}
|
|
41
|
+
export function planClip(mode, metrics, elementRect, maxDimension) {
|
|
42
|
+
const dpr = dprFromMetrics(metrics);
|
|
43
|
+
let region;
|
|
44
|
+
if (mode === 'element') {
|
|
45
|
+
if (!elementRect)
|
|
46
|
+
throw new Error('screenshot: element rect missing for element mode');
|
|
47
|
+
region = { ...elementRect };
|
|
48
|
+
}
|
|
49
|
+
else if (mode === 'viewport') {
|
|
50
|
+
// Device-pixel fallback values are converted to the CSS pixels clip uses.
|
|
51
|
+
const css = metrics.cssVisualViewport;
|
|
52
|
+
const dev = metrics.visualViewport;
|
|
53
|
+
if (css) {
|
|
54
|
+
region = { x: css.pageX, y: css.pageY, width: css.clientWidth, height: css.clientHeight };
|
|
55
|
+
}
|
|
56
|
+
else if (dev) {
|
|
57
|
+
region = {
|
|
58
|
+
x: dev.pageX / dpr,
|
|
59
|
+
y: dev.pageY / dpr,
|
|
60
|
+
width: dev.clientWidth / dpr,
|
|
61
|
+
height: dev.clientHeight / dpr,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
throw new Error('screenshot: layout metrics have no viewport');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const size = metrics.cssContentSize
|
|
70
|
+
? metrics.cssContentSize
|
|
71
|
+
: metrics.contentSize
|
|
72
|
+
? { width: metrics.contentSize.width / dpr, height: metrics.contentSize.height / dpr }
|
|
73
|
+
: undefined;
|
|
74
|
+
if (!size)
|
|
75
|
+
throw new Error('screenshot: layout metrics have no content size');
|
|
76
|
+
region = { x: 0, y: 0, width: size.width, height: size.height };
|
|
77
|
+
}
|
|
78
|
+
if (!positive(region.width) || !positive(region.height)) {
|
|
79
|
+
throw new Error(`screenshot: ${mode} region is zero-sized — nothing to capture`);
|
|
80
|
+
}
|
|
81
|
+
// The output is clip x scale x dpr DEVICE pixels, so max_dimension bounds
|
|
82
|
+
// the longest side in device pixels.
|
|
83
|
+
let scale = Math.min(1, maxDimension / (Math.max(region.width, region.height) * dpr));
|
|
84
|
+
let truncated = false;
|
|
85
|
+
if (scale < MIN_SCALE) {
|
|
86
|
+
scale = MIN_SCALE;
|
|
87
|
+
const limit = maxDimension / (MIN_SCALE * dpr);
|
|
88
|
+
if (region.width > limit)
|
|
89
|
+
region.width = limit;
|
|
90
|
+
if (region.height > limit)
|
|
91
|
+
region.height = limit;
|
|
92
|
+
truncated = true;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
clip: { ...region, scale },
|
|
96
|
+
width: Math.max(1, Math.round(region.width * scale * dpr)),
|
|
97
|
+
height: Math.max(1, Math.round(region.height * scale * dpr)),
|
|
98
|
+
scale,
|
|
99
|
+
dpr,
|
|
100
|
+
truncated,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Decoded byte length of a base64 string. */
|
|
104
|
+
export function base64ByteLength(b64) {
|
|
105
|
+
if (b64.length === 0)
|
|
106
|
+
return 0;
|
|
107
|
+
let padding = 0;
|
|
108
|
+
if (b64.endsWith('=='))
|
|
109
|
+
padding = 2;
|
|
110
|
+
else if (b64.endsWith('='))
|
|
111
|
+
padding = 1;
|
|
112
|
+
return Math.floor((b64.length * 3) / 4) - padding;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* What to try after an image came back over the byte cap: PNG → JPEG at the
|
|
116
|
+
* same scale, then JPEG at a scale reduced in proportion to the overshoot.
|
|
117
|
+
* `null` when nothing smaller is worth trying.
|
|
118
|
+
*/
|
|
119
|
+
export function nextOversizeAttempt(prev, bytes, cap) {
|
|
120
|
+
if (prev.format === 'png') {
|
|
121
|
+
return { format: 'jpeg', scale: prev.scale, quality: prev.quality ?? DEFAULT_JPEG_QUALITY };
|
|
122
|
+
}
|
|
123
|
+
if (prev.scale <= ABSOLUTE_MIN_SCALE)
|
|
124
|
+
return null;
|
|
125
|
+
const next = Math.max(ABSOLUTE_MIN_SCALE, prev.scale * Math.sqrt(cap / bytes) * 0.85);
|
|
126
|
+
return { format: 'jpeg', scale: next, quality: prev.quality ?? DEFAULT_JPEG_QUALITY };
|
|
127
|
+
}
|
|
128
|
+
export async function runScreenshot(deps, opts) {
|
|
129
|
+
const mode = opts.mode ?? 'viewport';
|
|
130
|
+
const maxDimension = opts.maxDimension ?? DEFAULT_MAX_DIMENSION;
|
|
131
|
+
let elementRect;
|
|
132
|
+
if (mode === 'element') {
|
|
133
|
+
if (!opts.selector)
|
|
134
|
+
throw new Error('screenshot: selector is required for element mode');
|
|
135
|
+
const r = await deps.resolveElementRect(opts.selector);
|
|
136
|
+
if (!r.ok) {
|
|
137
|
+
if (r.reason === 'invalid-selector') {
|
|
138
|
+
throw new Error(`Invalid selector "${opts.selector}": ${r.error ?? 'syntax error'}`);
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`Element not found: ${opts.selector}`);
|
|
141
|
+
}
|
|
142
|
+
elementRect = { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
143
|
+
}
|
|
144
|
+
// Always read the metrics: besides the page size they carry the DPR the
|
|
145
|
+
// output dimensions depend on.
|
|
146
|
+
const metrics = (await deps.send('Page.getLayoutMetrics'));
|
|
147
|
+
const plan = planClip(mode, metrics, elementRect, maxDimension);
|
|
148
|
+
let attempt = {
|
|
149
|
+
format: opts.format ?? 'png',
|
|
150
|
+
scale: plan.scale,
|
|
151
|
+
quality: opts.quality,
|
|
152
|
+
};
|
|
153
|
+
let reduced = false;
|
|
154
|
+
let lastBytes = 0;
|
|
155
|
+
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
|
156
|
+
const params = {
|
|
157
|
+
format: attempt.format,
|
|
158
|
+
captureBeyondViewport: mode !== 'viewport',
|
|
159
|
+
clip: { ...plan.clip, scale: attempt.scale },
|
|
160
|
+
};
|
|
161
|
+
if (attempt.format === 'jpeg' && attempt.quality !== undefined) {
|
|
162
|
+
params.quality = attempt.quality;
|
|
163
|
+
}
|
|
164
|
+
const res = (await deps.send('Page.captureScreenshot', params));
|
|
165
|
+
const bytes = base64ByteLength(res.data);
|
|
166
|
+
lastBytes = bytes;
|
|
167
|
+
if (bytes <= MAX_IMAGE_BYTES) {
|
|
168
|
+
const result = {
|
|
169
|
+
ok: true,
|
|
170
|
+
mode,
|
|
171
|
+
format: attempt.format,
|
|
172
|
+
width: Math.max(1, Math.round(plan.clip.width * attempt.scale * plan.dpr)),
|
|
173
|
+
height: Math.max(1, Math.round(plan.clip.height * attempt.scale * plan.dpr)),
|
|
174
|
+
scale: attempt.scale,
|
|
175
|
+
bytes,
|
|
176
|
+
image_b64: res.data,
|
|
177
|
+
};
|
|
178
|
+
if (plan.truncated)
|
|
179
|
+
result.truncated = true;
|
|
180
|
+
if (reduced)
|
|
181
|
+
result.size_reduced = true;
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
const next = nextOversizeAttempt(attempt, bytes, MAX_IMAGE_BYTES);
|
|
185
|
+
if (!next)
|
|
186
|
+
break;
|
|
187
|
+
attempt = next;
|
|
188
|
+
reduced = true;
|
|
189
|
+
}
|
|
190
|
+
const mb = (n) => (n / (1024 * 1024)).toFixed(1);
|
|
191
|
+
throw new Error(`screenshot: image is ${mb(lastBytes)} MB, which exceeds the ${mb(MAX_IMAGE_BYTES)} MB cap even after reducing quality and scale — use mode "element", a smaller max_dimension, or jpeg`);
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":"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"}
|
package/dist/permissions.js
CHANGED
|
@@ -53,6 +53,12 @@ export const TOOL_CATALOGUE = [
|
|
|
53
53
|
category: 'read',
|
|
54
54
|
summary: 'Screenshot a <canvas> as PNG/JPEG — for Qt-WASM, WebGL and other DOMless surfaces',
|
|
55
55
|
},
|
|
56
|
+
{
|
|
57
|
+
name: 'browser.screenshot',
|
|
58
|
+
family: 'bridge',
|
|
59
|
+
category: 'read',
|
|
60
|
+
summary: 'Screenshot the viewport, the FULL page or one element as PNG/JPEG',
|
|
61
|
+
},
|
|
56
62
|
{
|
|
57
63
|
name: 'browser.console',
|
|
58
64
|
family: 'bridge',
|
|
@@ -144,6 +150,12 @@ export const TOOL_CATALOGUE = [
|
|
|
144
150
|
category: 'action',
|
|
145
151
|
summary: 'Grant or deny a browser permission for an origin (geo, notifs, etc.)',
|
|
146
152
|
},
|
|
153
|
+
{
|
|
154
|
+
name: 'browser.download',
|
|
155
|
+
family: 'bridge',
|
|
156
|
+
category: 'action',
|
|
157
|
+
summary: 'Download a file (click a button or fetch a URL) without the native "Save as" dialog',
|
|
158
|
+
},
|
|
147
159
|
{
|
|
148
160
|
name: 'browser.claim_tab',
|
|
149
161
|
family: 'bridge',
|
package/dist/permissions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -8,6 +8,8 @@ import { record } from './activity/queries.js';
|
|
|
8
8
|
import { SERVER_INSTRUCTIONS } from './tools/server-instructions.js';
|
|
9
9
|
import { INSTRUCTIONS_INSTALLERS } from './agent-instructions/index.js';
|
|
10
10
|
import { loadConfig } from './config.js';
|
|
11
|
+
import { resolveDownloadsDir, writeDownloadFile } from './downloads.js';
|
|
12
|
+
import { getDataDir } from './map/paths.js';
|
|
11
13
|
import { handleToolCall, handleToolsList } from './bridge/dispatch.js';
|
|
12
14
|
import { IpcServer } from './bridge/server.js';
|
|
13
15
|
import { runProxy } from './bridge/proxy.js';
|
|
@@ -182,6 +184,12 @@ async function runPrimary(cfg) {
|
|
|
182
184
|
listCdpTabs: () => listCdpTargets(),
|
|
183
185
|
callCdpTool,
|
|
184
186
|
cdpGate: () => checkCdpDirectGate(),
|
|
187
|
+
// browser.download writes here. The directory is re-read per download so
|
|
188
|
+
// `browser-link config set downloads.dir` applies without a restart.
|
|
189
|
+
saveDownload: (filename, data) => writeDownloadFile(resolveDownloadsDir(loadConfig(), getDataDir()), filename, data),
|
|
190
|
+
emitEvent: (kind, data) => {
|
|
191
|
+
events.add(kind, data);
|
|
192
|
+
},
|
|
185
193
|
resetBridge: () => {
|
|
186
194
|
// Close every WS to the extension first so the client side flips to
|
|
187
195
|
// "Not connected" before we drop the local state. Best-effort: a tab
|