@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.
Files changed (58) hide show
  1. package/dist/activity/extract.js +3 -0
  2. package/dist/activity/extract.js.map +1 -1
  3. package/dist/agent-instructions/content.js +11 -1
  4. package/dist/agent-instructions/content.js.map +1 -1
  5. package/dist/bridge/dispatch.js +5 -3
  6. package/dist/bridge/dispatch.js.map +1 -1
  7. package/dist/bridge/events.d.ts +1 -1
  8. package/dist/bridge/events.js.map +1 -1
  9. package/dist/cdp/inpage/builders.d.ts +15 -0
  10. package/dist/cdp/inpage/builders.js +46 -0
  11. package/dist/cdp/inpage/builders.js.map +1 -1
  12. package/dist/cdp/screenshot.d.ts +109 -0
  13. package/dist/cdp/screenshot.js +189 -0
  14. package/dist/cdp/screenshot.js.map +1 -0
  15. package/dist/cdp/support.d.ts +2 -1
  16. package/dist/cdp/support.js +7 -1
  17. package/dist/cdp/support.js.map +1 -1
  18. package/dist/cdp/transport.js +15 -1
  19. package/dist/cdp/transport.js.map +1 -1
  20. package/dist/cli.js +8 -0
  21. package/dist/cli.js.map +1 -1
  22. package/dist/commands/about.js +4 -0
  23. package/dist/commands/about.js.map +1 -1
  24. package/dist/commands/config.d.ts +12 -0
  25. package/dist/commands/config.js +49 -4
  26. package/dist/commands/config.js.map +1 -1
  27. package/dist/config.d.ts +8 -0
  28. package/dist/config.js.map +1 -1
  29. package/dist/downloads.d.ts +127 -0
  30. package/dist/downloads.js +303 -0
  31. package/dist/downloads.js.map +1 -0
  32. package/dist/extension/background.js +74 -1
  33. package/dist/extension/background.js.map +1 -1
  34. package/dist/extension/download-capture.d.ts +96 -0
  35. package/dist/extension/download-capture.js +131 -0
  36. package/dist/extension/download-capture.js.map +1 -0
  37. package/dist/extension/inpage/builders.d.ts +15 -0
  38. package/dist/extension/inpage/builders.js +46 -0
  39. package/dist/extension/inpage/builders.js.map +1 -1
  40. package/dist/extension/manifest.json +1 -1
  41. package/dist/extension/screenshot.d.ts +113 -0
  42. package/dist/extension/screenshot.js +193 -0
  43. package/dist/extension/screenshot.js.map +1 -0
  44. package/dist/permissions.js +12 -0
  45. package/dist/permissions.js.map +1 -1
  46. package/dist/server.js +8 -0
  47. package/dist/server.js.map +1 -1
  48. package/dist/tools/browser-definitions.js +101 -1
  49. package/dist/tools/browser-definitions.js.map +1 -1
  50. package/dist/tools/browser-dispatch.d.ts +12 -1
  51. package/dist/tools/browser-dispatch.js +171 -0
  52. package/dist/tools/browser-dispatch.js.map +1 -1
  53. package/dist/tools/responses.d.ts +14 -2
  54. package/dist/tools/responses.js +21 -0
  55. package/dist/tools/responses.js.map +1 -1
  56. package/dist/tools/server-instructions.js +27 -4
  57. package/dist/tools/server-instructions.js.map +1 -1
  58. 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":"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"}
@@ -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":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "browser-link",
4
- "version": "0.28.9",
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":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,uEAAuE;AACvE,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAC9B,yDAAyD;AACzD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,2DAA2D;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,YAAY,GAAG,CAAC,CAAC;AA8BvB;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,CAAgB;IAC7C,MAAM,KAAK,GAA+C;QACxD,CAAC,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC,iBAAiB,EAAE,WAAW,CAAC;QACjE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC;QAC/C,CAAC,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC,iBAAiB,EAAE,WAAW,CAAC;KAClE,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;QAClC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,MAAM,GAAG,GAAG,CAAC;IAC7D,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,IAAoB,EACpB,OAAsB,EACtB,WAA6B,EAC7B,YAAoB;IAEpB,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,MAAY,CAAC;IACjB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvF,MAAM,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;IAC9B,CAAC;SAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,0EAA0E;QAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACtC,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;QACnC,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5F,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,MAAM,GAAG;gBACP,CAAC,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG;gBAClB,CAAC,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG;gBAClB,KAAK,EAAE,GAAG,CAAC,WAAW,GAAG,GAAG;gBAC5B,MAAM,EAAE,GAAG,CAAC,YAAY,GAAG,GAAG;aAC/B,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc;YACjC,CAAC,CAAC,OAAO,CAAC,cAAc;YACxB,CAAC,CAAC,OAAO,CAAC,WAAW;gBACnB,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,GAAG,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG,EAAE;gBACtF,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAC9E,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,4CAA4C,CAAC,CAAC;IACnF,CAAC;IAED,0EAA0E;IAC1E,qCAAqC;IACrC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACtF,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;QACtB,KAAK,GAAG,SAAS,CAAC;QAClB,MAAM,KAAK,GAAG,YAAY,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/C,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;YAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;QACjD,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,OAAO;QACL,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE;QAC1B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;QAC1D,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;QAC5D,KAAK;QACL,GAAG;QACH,SAAS;KACV,CAAC;AACJ,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC;SAC/B,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC;AACpD,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAa,EAAE,KAAa,EAAE,GAAW;IAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oBAAoB,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,IAAI,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oBAAoB,EAAE,CAAC;AACxF,CAAC;AA+BD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAoB,EACpB,IAAuB;IAEvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,qBAAqB,CAAC;IAEhE,IAAI,WAA6B,CAAC;IAClC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACzF,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,IAAI,CAAC,CAAC,MAAM,KAAK,kBAAkB,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC,CAAC;YACvF,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,WAAW,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACrE,CAAC;IACD,wEAAwE;IACxE,+BAA+B;IAC/B,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAkB,CAAC;IAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAEhE,IAAI,OAAO,GAAY;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;QAC5B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC;IACF,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAA4B;YACtC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,qBAAqB,EAAE,IAAI,KAAK,UAAU;YAC1C,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;SAC7C,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/D,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QACnC,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAqB,CAAC;QACpF,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,SAAS,GAAG,KAAK,CAAC;QAClB,IAAI,KAAK,IAAI,eAAe,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAqB;gBAC/B,EAAE,EAAE,IAAI;gBACR,IAAI;gBACJ,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1E,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC5E,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK;gBACL,SAAS,EAAE,GAAG,CAAC,IAAI;aACpB,CAAC;YACF,IAAI,IAAI,CAAC,SAAS;gBAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;YAC5C,IAAI,OAAO;gBAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;YACxC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI;YAAE,MAAM;QACjB,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,MAAM,EAAE,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,IAAI,KAAK,CACb,wBAAwB,EAAE,CAAC,SAAS,CAAC,0BAA0B,EAAE,CAAC,eAAe,CAAC,sGAAsG,CACzL,CAAC;AACJ,CAAC"}
@@ -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',
@@ -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":"AAAA;;;;;;;;;GASG;AAeH,MAAM,CAAC,MAAM,cAAc,GAAwB;IACjD,6BAA6B;IAC7B,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE;IACjG;QACE,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,kDAAkD;KAC5D;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,wDAAwD;KAClE;IACD;QACE,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,4BAA4B;KACtC;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,sFAAsF;KAChG;IACD;QACE,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,wEAAwE;KAClF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,+EAA+E;KACzF;IACD;QACE,IAAI,EAAE,2BAA2B;QACjC,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,mFAAmF;KAC7F;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,mEAAmE;KAC7E;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,8BAA8B;KACxC;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,8BAA8B;KACxC;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,sCAAsC;KAChD;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,wDAAwD;KAClE;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,qDAAqD;KAC/D;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,uDAAuD;KACjE;IAED,2BAA2B;IAC3B;QACE,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,2BAA2B;KACrC;IACD;QACE,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,kCAAkC;KAC5C;IACD;QACE,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,yBAAyB;KACnC;IACD;QACE,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,sDAAsD;KAChE;IACD;QACE,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,kDAAkD;KAC5D;IACD;QACE,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,2EAA2E;KACrF;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,2BAA2B;KACrC;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,2DAA2D;KACrE;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,sEAAsE;KAChF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,qFAAqF;KAC/F;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,qDAAqD;KAC/D;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,qBAAqB;KAC/B;IACD;QACE,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,gEAAgE;KAC1E;IAED,kCAAkC;IAClC;QACE,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,sCAAsC;KAChD;IAED,yBAAyB;IACzB;QACE,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,UAAU;QACpB,OAAO,EAAE,+CAA+C;KACzD;IACD,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE;IAE7F,0BAA0B;IAC1B;QACE,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,oCAAoC;KAC9C;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,kCAAkC;KAC5C;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,gCAAgC;KAC1C;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,mBAAmB;KAC7B;CACF,CAAC;AAWF,SAAS,UAAU,CAAC,SAAmC;IACrD,OAAO,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAyB;IAC3C,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAE;IACjD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,8CAA8C;QACrD,QAAQ,EAAE,UAAU,CAClB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,CACtF;KACF;IACD;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,8CAA8C;QACrD,QAAQ,EAAE,CAAC,kBAAkB,CAAC;KAC/B;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,yCAAyC;QAChD,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC;KAChD;CACF,CAAC;AAEF,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAEpF,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,QAAuC;IACjF,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;kEAEkE;AAClE,MAAM,UAAU,qBAAqB,CAAC,KAAoC;IACxE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAY;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
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