@ingcreators/annot-mcp 0.3.0 → 0.3.2

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/index.js CHANGED
@@ -1,11 +1,9 @@
1
- import { BBOX_ANNOTATION_SCHEMA as e, BBOX_REDACT_REGION_SCHEMA as t, DEFAULT_ENCODE_OPTIONS as n, SHARED_DEFS as r, arrowBetween as i, bboxAnnotationsToSvg as a, bboxAnnotationsToSvg as o, createAnnotator as s, decodeAndEncodeImage as c, rectForBoundingBox as l, textAt as u } from "@ingcreators/annot-annotator";
2
- import { createCanvas as d, loadImage as f } from "@napi-rs/canvas";
3
- import ee from "pixelmatch";
4
- import { readFile as te, writeFile as p } from "node:fs/promises";
1
+ import { BBOX_ANNOTATION_SCHEMA as e, BBOX_REDACT_REGION_SCHEMA as t, DEFAULT_ENCODE_OPTIONS as n, DimensionMismatchError as r, SHARED_DEFS as i, aggregateDiffRegions as a, arrowBetween as o, bboxAnnotationsToSvg as s, bboxAnnotationsToSvg as c, burnRedactions as l, burnRegions as u, createAnnotator as d, decodeAndEncodeImage as f, diffScreenshots as ee, rectForBoundingBox as te, textAt as ne } from "@ingcreators/annot-annotator";
2
+ import { readFile as re, writeFile as p } from "node:fs/promises";
5
3
  import { isAbsolute as m } from "node:path";
6
- import { Server as ne } from "@modelcontextprotocol/sdk/server/index.js";
7
- import { CallToolRequestSchema as re, ListToolsRequestSchema as ie } from "@modelcontextprotocol/sdk/types.js";
8
- import { detectDrift as ae, lintableScreens as oe, parseMdxFile as se, parseSnapshot as ce } from "@ingcreators/annot-product-docs";
4
+ import { Server as ie } from "@modelcontextprotocol/sdk/server/index.js";
5
+ import { CallToolRequestSchema as ae, ListToolsRequestSchema as oe } from "@modelcontextprotocol/sdk/types.js";
6
+ import { detectDrift as se, lintableScreens as ce, parseMdxFile as h, parseSnapshot as g } from "@ingcreators/annot-product-docs";
9
7
  import { StdioServerTransport as le } from "@modelcontextprotocol/sdk/server/stdio.js";
10
8
  //#region src/browser/capture.ts
11
9
  var ue = {
@@ -13,7 +11,7 @@ var ue = {
13
11
  height: 800,
14
12
  deviceScaleFactor: 1
15
13
  }, de = "load";
16
- async function h(e, t) {
14
+ async function _(e, t) {
17
15
  let n = {
18
16
  ...ue,
19
17
  ...t.viewport
@@ -56,7 +54,7 @@ async function h(e, t) {
56
54
  }
57
55
  //#endregion
58
56
  //#region src/browser/pool.ts
59
- var fe = 3e4, g = class {
57
+ var fe = 3e4, v = class {
60
58
  #e;
61
59
  #t;
62
60
  #n;
@@ -96,73 +94,73 @@ var fe = 3e4, g = class {
96
94
  }
97
95
  };
98
96
  function pe(e = {}) {
99
- return new g({ async launch() {
97
+ return new v({ async launch() {
100
98
  let e;
101
99
  try {
102
100
  ({chromium: e} = await import("playwright-core"));
103
101
  } catch (e) {
104
- throw new _("Failed to load `playwright-core`. Reinstall `@ingcreators/annot-mcp` to restore the dependency.", e);
102
+ throw new y("Failed to load `playwright-core`. Reinstall `@ingcreators/annot-mcp` to restore the dependency.", e);
105
103
  }
106
104
  try {
107
105
  return await e.launch({ headless: !0 });
108
106
  } catch (e) {
109
- throw new _("Failed to launch Chromium. Run `npx playwright install chromium` to download the runtime, then retry.", e);
107
+ throw new y("Failed to launch Chromium. Run `npx playwright install chromium` to download the runtime, then retry.", e);
110
108
  }
111
109
  } }, e);
112
110
  }
113
- var _ = class extends Error {
111
+ var y = class extends Error {
114
112
  cause;
115
113
  constructor(e, t) {
116
114
  super(e), this.name = "ChromiumUnavailableError", this.cause = t;
117
115
  }
118
- }, v = class extends Error {
116
+ }, b = class extends Error {
119
117
  locator;
120
118
  constructor(e, t) {
121
119
  super(t), this.name = "LocatorResolutionError", this.locator = e;
122
120
  }
123
121
  };
124
- async function y(e, t) {
122
+ async function x(e, t) {
125
123
  let n = await e.locator(t).boundingBox();
126
- if (!n) throw new v(t, `Locator "${t}" resolved to no visible element. Check the selector matches at least one element and the element is inside the captured viewport.`);
124
+ if (!n) throw new b(t, `Locator "${t}" resolved to no visible element. Check the selector matches at least one element and the element is inside the captured viewport.`);
127
125
  return n;
128
126
  }
129
127
  async function me(e, t) {
130
128
  switch (t.type) {
131
129
  case "rect": {
132
- let n = t.bbox ?? await y(e, x(t.locator));
130
+ let n = t.bbox ?? await x(e, C(t.locator));
133
131
  return {
134
- ...S(t),
132
+ ...w(t),
135
133
  type: "rect",
136
134
  bbox: n
137
135
  };
138
136
  }
139
137
  case "circle": {
140
138
  if (t.center !== void 0 && t.radius !== void 0) return {
141
- ...S(t),
139
+ ...w(t),
142
140
  type: "circle",
143
141
  center: t.center,
144
142
  radius: t.radius
145
143
  };
146
- let n = await y(e, x(t.locator));
144
+ let n = await x(e, C(t.locator));
147
145
  return {
148
- ...S(t),
146
+ ...w(t),
149
147
  type: "circle",
150
- center: b(n),
148
+ center: S(n),
151
149
  radius: Math.min(n.width, n.height) / 2
152
150
  };
153
151
  }
154
152
  case "arrow": {
155
- let n = t.from ?? b(await y(e, x(t.fromLocator))), r = t.to ?? b(await y(e, x(t.toLocator)));
153
+ let n = t.from ?? S(await x(e, C(t.fromLocator))), r = t.to ?? S(await x(e, C(t.toLocator)));
156
154
  return {
157
- ...S(t),
155
+ ...w(t),
158
156
  type: "arrow",
159
157
  from: n,
160
158
  to: r
161
159
  };
162
160
  }
163
161
  case "text": {
164
- let n = t.at ?? _e(await y(e, x(t.locator)), t.fontSize), r = {
165
- ...S(t),
162
+ let n = t.at ?? _e(await x(e, C(t.locator)), t.fontSize), r = {
163
+ ...w(t),
166
164
  type: "text",
167
165
  at: n,
168
166
  content: t.content
@@ -170,9 +168,9 @@ async function me(e, t) {
170
168
  return t.fontSize !== void 0 && (r.fontSize = t.fontSize), t.anchor !== void 0 && (r.anchor = t.anchor), r;
171
169
  }
172
170
  case "callout": {
173
- let n = t.at ?? await ge(e, t.atLocator), r = t.targetBbox ?? await y(e, x(t.targetLocator));
171
+ let n = t.at ?? await ge(e, t.atLocator), r = t.targetBbox ?? await x(e, C(t.targetLocator));
174
172
  return {
175
- ...S(t),
173
+ ...w(t),
176
174
  type: "callout",
177
175
  at: n,
178
176
  targetBbox: r,
@@ -188,10 +186,10 @@ async function he(e, t) {
188
186
  return n;
189
187
  }
190
188
  async function ge(e, t) {
191
- if (!t) throw new v("<callout.at>", "callout annotations require either `at` or `atLocator`.");
192
- return b(await y(e, t));
189
+ if (!t) throw new b("<callout.at>", "callout annotations require either `at` or `atLocator`.");
190
+ return S(await x(e, t));
193
191
  }
194
- function b(e) {
192
+ function S(e) {
195
193
  return {
196
194
  x: e.x + e.width / 2,
197
195
  y: e.y + e.height / 2
@@ -204,95 +202,24 @@ function _e(e, t) {
204
202
  y: Math.max(0, e.y - n)
205
203
  };
206
204
  }
207
- function x(e) {
208
- if (e === void 0) throw new v("<missing>", "Internal error: annotation passed schema validation without a locator or bbox. This is a bug.");
205
+ function C(e) {
206
+ if (e === void 0) throw new b("<missing>", "Internal error: annotation passed schema validation without a locator or bbox. This is a bug.");
209
207
  return e;
210
208
  }
211
- function S(e) {
209
+ function w(e) {
212
210
  if (e.type === "raw") return {};
213
211
  let t = {};
214
212
  return e.intent !== void 0 && (t.intent = e.intent), e.stroke !== void 0 && (t.stroke = e.stroke), e.strokeWidth !== void 0 && (t.strokeWidth = e.strokeWidth), e.fill !== void 0 && (t.fill = e.fill), e.color !== void 0 && (t.color = e.color), t;
215
213
  }
216
214
  //#endregion
217
- //#region src/compare/aggregate.ts
218
- var ve = 4;
219
- function ye(e, t, n) {
220
- let r = new Uint8Array(t * n), i = [];
221
- for (let a = 0; a < n; a++) for (let o = 0; o < t; o++) {
222
- let s = a * t + o;
223
- if (r[s] || !be(e, s)) continue;
224
- let c = xe(e, r, o, a, t, n);
225
- c.count >= ve && i.push({
226
- x: c.minX,
227
- y: c.minY,
228
- width: c.maxX - c.minX + 1,
229
- height: c.maxY - c.minY + 1
230
- });
231
- }
232
- return i;
233
- }
234
- function be(e, t) {
235
- return e[t * 4 + 3] > 0;
236
- }
237
- function xe(e, t, n, r, i, a) {
238
- let o = {
239
- count: 0,
240
- minX: n,
241
- minY: r,
242
- maxX: n,
243
- maxY: r
244
- }, s = [n, r];
245
- for (; s.length > 0;) {
246
- let n = s.pop(), r = s.pop();
247
- if (r < 0 || r >= i || n < 0 || n >= a) continue;
248
- let c = n * i + r;
249
- t[c] || be(e, c) && (t[c] = 1, o.count += 1, r < o.minX && (o.minX = r), n < o.minY && (o.minY = n), r > o.maxX && (o.maxX = r), n > o.maxY && (o.maxY = n), s.push(r + 1, n), s.push(r - 1, n), s.push(r, n + 1), s.push(r, n - 1));
250
- }
251
- return o;
252
- }
253
- //#endregion
254
- //#region src/compare/diff.ts
255
- var Se = class extends Error {
256
- constructor(e, t) {
257
- super(`Cannot compare screenshots of different dimensions: before is ${e.width}×${e.height}, after is ${t.width}×${t.height}.`), this.name = "DimensionMismatchError";
258
- }
259
- };
260
- async function C(e, t, n = {}) {
261
- let [r, i] = await Promise.all([f(Buffer.from(e)), f(Buffer.from(t))]);
262
- if (r.width !== i.width || r.height !== i.height) throw new Se({
263
- width: r.width,
264
- height: r.height
265
- }, {
266
- width: i.width,
267
- height: i.height
268
- });
269
- let { width: a, height: o } = r, s = w(r, a, o), c = w(i, a, o), l = new Uint8Array(a * o * 4);
270
- return {
271
- mismatchedPixels: ee(s, c, l, a, o, {
272
- threshold: n.threshold ?? .1,
273
- includeAA: !1,
274
- diffMask: !0
275
- }),
276
- regions: ye(l, a, o),
277
- width: a,
278
- height: o
279
- };
280
- }
281
- function w(e, t, n) {
282
- let r = d(t, n).getContext("2d");
283
- r.drawImage(e, 0, 0);
284
- let i = r.getImageData(0, 0, t, n).data;
285
- return new Uint8Array(i.buffer, i.byteOffset, i.byteLength);
286
- }
287
- //#endregion
288
215
  //#region src/dsl/schema.ts
289
216
  var T = {
290
- ...r,
217
+ ...i,
291
218
  Locator: {
292
219
  type: "string",
293
220
  minLength: 1
294
221
  }
295
- }, E = { oneOf: [
222
+ }, ve = { oneOf: [
296
223
  {
297
224
  type: "object",
298
225
  required: ["type"],
@@ -407,7 +334,7 @@ var T = {
407
334
  svgFragment: { type: "string" }
408
335
  }
409
336
  }
410
- ] }, D = {
337
+ ] }, E = {
411
338
  type: "object",
412
339
  additionalProperties: !1,
413
340
  properties: {
@@ -447,7 +374,7 @@ var T = {
447
374
  description: "JPEG quality 60–100. Default 92."
448
375
  }
449
376
  }
450
- }, Ce = {
377
+ }, D = {
451
378
  type: "object",
452
379
  additionalProperties: !1,
453
380
  properties: {
@@ -464,7 +391,7 @@ var T = {
464
391
  color: { type: "string" }
465
392
  },
466
393
  anyOf: [{ required: ["bbox"] }, { required: ["locator"] }]
467
- }, we = [
394
+ }, O = [
468
395
  137,
469
396
  80,
470
397
  78,
@@ -473,18 +400,18 @@ var T = {
473
400
  10,
474
401
  26,
475
402
  10
476
- ], O = 12, Te = "IHDR", Ee = 16, De = 20, Oe = 24, k = class extends Error {
403
+ ], ye = 12, be = "IHDR", xe = 16, Se = 20, k = 24, A = class extends Error {
477
404
  constructor(e) {
478
405
  super(e), this.name = "InvalidPngError";
479
406
  }
480
407
  };
481
- function A(e) {
482
- if (e.byteLength < Oe) throw new k(`Expected at least ${Oe} bytes for a PNG header, got ${e.byteLength}.`);
483
- for (let t = 0; t < we.length; t++) if (e[t] !== we[t]) throw new k("Input does not start with the PNG signature (89 50 4E 47 0D 0A 1A 0A). Confirm the input is a PNG — JPEG / WebP / other formats are not supported in v1.");
484
- let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = String.fromCharCode(e[O], e[O + 1], e[O + 2], e[O + 3]);
485
- if (n !== Te) throw new k(`Expected IHDR chunk after PNG signature, found "${n}". The file may be a corrupt or non-standard PNG.`);
486
- let r = t.getUint32(Ee, !1), i = t.getUint32(De, !1);
487
- if (r === 0 || i === 0) throw new k(`PNG dimensions ${r}×${i} include a zero axis.`);
408
+ function j(e) {
409
+ if (e.byteLength < k) throw new A(`Expected at least ${k} bytes for a PNG header, got ${e.byteLength}.`);
410
+ for (let t = 0; t < O.length; t++) if (e[t] !== O[t]) throw new A("Input does not start with the PNG signature (89 50 4E 47 0D 0A 1A 0A). Confirm the input is a PNG — JPEG / WebP / other formats are not supported in v1.");
411
+ let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = String.fromCharCode(e[ye], e[13], e[14], e[15]);
412
+ if (n !== be) throw new A(`Expected IHDR chunk after PNG signature, found "${n}". The file may be a corrupt or non-standard PNG.`);
413
+ let r = t.getUint32(xe, !1), i = t.getUint32(Se, !1);
414
+ if (r === 0 || i === 0) throw new A(`PNG dimensions ${r}×${i} include a zero axis.`);
488
415
  return {
489
416
  width: r,
490
417
  height: i
@@ -492,89 +419,58 @@ function A(e) {
492
419
  }
493
420
  //#endregion
494
421
  //#region src/io/read-image.ts
495
- var j = class extends Error {
422
+ var M = class extends Error {
496
423
  constructor(e) {
497
424
  super(e), this.name = "InvalidImageInputError";
498
425
  }
499
- }, ke = "data:", Ae = /^data:image\/png;base64,/i;
500
- async function M(e) {
501
- if (typeof e != "string" || e.length === 0) throw new j("`image` must be a non-empty string (data URL or absolute filesystem path).");
502
- if (e.startsWith(ke)) return je(e);
503
- if (!m(e)) throw new j(`Filesystem path "${e}" is not absolute. Pass an absolute path so resolution doesn't depend on the MCP server's working directory.`);
504
- return Me(e);
426
+ }, Ce = "data:", we = /^data:image\/png;base64,/i;
427
+ async function N(e) {
428
+ if (typeof e != "string" || e.length === 0) throw new M("`image` must be a non-empty string (data URL or absolute filesystem path).");
429
+ if (e.startsWith(Ce)) return Te(e);
430
+ if (!m(e)) throw new M(`Filesystem path "${e}" is not absolute. Pass an absolute path so resolution doesn't depend on the MCP server's working directory.`);
431
+ return Ee(e);
505
432
  }
506
- function je(e) {
507
- if (!Ae.test(e)) throw new j("Only `data:image/png;base64,...` URLs are supported. JPEG / WebP / SVG data URLs are not accepted in v1.");
508
- let t = Pe(e.slice(e.indexOf(",") + 1));
433
+ function Te(e) {
434
+ if (!we.test(e)) throw new M("Only `data:image/png;base64,...` URLs are supported. JPEG / WebP / SVG data URLs are not accepted in v1.");
435
+ let t = De(e.slice(e.indexOf(",") + 1));
509
436
  return {
510
437
  bytes: t,
511
438
  dataUrl: e,
512
- dimensions: Ne(t)
439
+ dimensions: P(t)
513
440
  };
514
441
  }
515
- async function Me(e) {
442
+ async function Ee(e) {
516
443
  let t;
517
444
  try {
518
- let n = await te(e);
445
+ let n = await re(e);
519
446
  t = new Uint8Array(n.buffer, n.byteOffset, n.byteLength);
520
447
  } catch (t) {
521
- throw new j(`Failed to read image at "${e}": ${t instanceof Error ? t.message : String(t)}`);
448
+ throw new M(`Failed to read image at "${e}": ${t instanceof Error ? t.message : String(t)}`);
522
449
  }
523
- let n = Ne(t), r = `data:image/png;base64,${Fe(t)}`;
450
+ let n = P(t), r = `data:image/png;base64,${Oe(t)}`;
524
451
  return {
525
452
  bytes: t,
526
453
  dataUrl: r,
527
454
  dimensions: n
528
455
  };
529
456
  }
530
- function Ne(e) {
457
+ function P(e) {
531
458
  try {
532
- return A(e);
459
+ return j(e);
533
460
  } catch (e) {
534
- throw e instanceof k ? new j(e.message) : e;
461
+ throw e instanceof A ? new M(e.message) : e;
535
462
  }
536
463
  }
537
- function Pe(e) {
464
+ function De(e) {
538
465
  let t = Buffer.from(e, "base64");
539
466
  return new Uint8Array(t.buffer, t.byteOffset, t.byteLength);
540
467
  }
541
- function Fe(e) {
468
+ function Oe(e) {
542
469
  return Buffer.from(e.buffer, e.byteOffset, e.byteLength).toString("base64");
543
470
  }
544
471
  //#endregion
545
- //#region src/redact/burn.ts
546
- var Ie = "solid", Le = "#000000", Re = 16, ze = 12;
547
- async function N(e, t) {
548
- if (t.length === 0) return e;
549
- let n = await f(Buffer.from(e)), r = d(n.width, n.height), i = r.getContext("2d");
550
- i.drawImage(n, 0, 0);
551
- for (let e of t) if (!(e.bbox.width <= 0 || e.bbox.height <= 0)) switch (e.style ?? Ie) {
552
- case "solid":
553
- Be(i, e.bbox, e.color ?? Le);
554
- break;
555
- case "mosaic":
556
- Ve(i, n, e.bbox);
557
- break;
558
- case "blur":
559
- He(i, n, e.bbox);
560
- break;
561
- }
562
- let a = r.toBuffer("image/png");
563
- return new Uint8Array(a.buffer, a.byteOffset, a.byteLength);
564
- }
565
- function Be(e, t, n) {
566
- e.save(), e.fillStyle = n, e.fillRect(t.x, t.y, t.width, t.height), e.restore();
567
- }
568
- function Ve(e, t, n) {
569
- let r = Math.max(1, Math.round(n.width / Re)), i = Math.max(1, Math.round(n.height / Re)), a = d(r, i), o = a.getContext("2d");
570
- o.imageSmoothingEnabled = !1, o.drawImage(t, n.x, n.y, n.width, n.height, 0, 0, r, i), e.save(), e.imageSmoothingEnabled = !1, e.drawImage(a, 0, 0, r, i, n.x, n.y, n.width, n.height), e.restore();
571
- }
572
- function He(e, t, n) {
573
- e.save(), e.beginPath(), e.rect(n.x, n.y, n.width, n.height), e.clip(), e.filter = `blur(${ze}px)`, e.drawImage(t, 0, 0), e.restore();
574
- }
575
- //#endregion
576
472
  //#region src/io/encode-output.ts
577
- async function P(e, t, r) {
473
+ async function F(e, t, r) {
578
474
  if (!r || Object.keys(r).length === 0) return {
579
475
  bytes: e,
580
476
  mimeType: "image/png",
@@ -582,7 +478,7 @@ async function P(e, t, r) {
582
478
  width: t.width,
583
479
  height: t.height
584
480
  };
585
- let i = await c(e, {
481
+ let i = await f(e, {
586
482
  ...n,
587
483
  ...r
588
484
  });
@@ -597,8 +493,8 @@ async function P(e, t, r) {
597
493
  }
598
494
  //#endregion
599
495
  //#region src/tools/annotate-screenshot.ts
600
- var F = "annot_annotate_screenshot", I = {
601
- name: F,
496
+ var I = "annot_annotate_screenshot", L = {
497
+ name: I,
602
498
  description: "Overlay annotations (rectangles, circles, arrows, callouts, text) on a PNG screenshot. Annotation positions are specified as bounding boxes or points; pair with `annot_annotate_url` if you want locator-driven positioning. Returns the annotated PNG inline unless `output` is specified, in which case the PNG is written to that absolute path.",
603
499
  inputSchema: {
604
500
  type: "object",
@@ -626,13 +522,13 @@ var F = "annot_annotate_screenshot", I = {
626
522
  $defs: {
627
523
  ...T,
628
524
  BboxAnnotation: e,
629
- EncodeOptions: D
525
+ EncodeOptions: E
630
526
  }
631
527
  }
632
528
  };
633
- async function L(e, t) {
529
+ async function R(e, t) {
634
530
  try {
635
- let n = Ue(e), r = await M(n.image), i = o(n.annotations), a = await P(t.annotator.toPng({
531
+ let n = ke(e), r = await N(n.image), i = c(n.annotations), a = await F(t.annotator.toPng({
636
532
  originalDataUrl: r.dataUrl,
637
533
  annotationsSvg: i,
638
534
  width: r.dimensions.width,
@@ -648,25 +544,25 @@ async function L(e, t) {
648
544
  }
649
545
  return { content: [{
650
546
  type: "image",
651
- data: Ge(a.bytes),
547
+ data: je(a.bytes),
652
548
  mimeType: a.mimeType
653
549
  }] };
654
550
  } catch (e) {
655
- return We(e);
551
+ return Ae(e);
656
552
  }
657
553
  }
658
- function Ue(e) {
659
- if (typeof e.image != "string") throw new j("`image` is required and must be a string.");
660
- if (!Array.isArray(e.annotations)) throw new R("`annotations` is required and must be an array.");
554
+ function ke(e) {
555
+ if (typeof e.image != "string") throw new M("`image` is required and must be a string.");
556
+ if (!Array.isArray(e.annotations)) throw new z("`annotations` is required and must be an array.");
661
557
  let t = e.annotations, n;
662
558
  if (e.output !== void 0) {
663
- if (typeof e.output != "string") throw new R("`output` must be a string when provided.");
664
- if (!m(e.output)) throw new R(`\`output\` path "${e.output}" must be absolute so the file lands at a predictable location.`);
559
+ if (typeof e.output != "string") throw new z("`output` must be a string when provided.");
560
+ if (!m(e.output)) throw new z(`\`output\` path "${e.output}" must be absolute so the file lands at a predictable location.`);
665
561
  n = e.output;
666
562
  }
667
563
  let r;
668
564
  if (e.encode !== void 0) {
669
- if (typeof e.encode != "object" || e.encode === null) throw new R("`encode` must be an object when provided.");
565
+ if (typeof e.encode != "object" || e.encode === null) throw new z("`encode` must be an object when provided.");
670
566
  r = e.encode;
671
567
  }
672
568
  return {
@@ -676,12 +572,12 @@ function Ue(e) {
676
572
  encode: r
677
573
  };
678
574
  }
679
- var R = class extends Error {
575
+ var z = class extends Error {
680
576
  constructor(e) {
681
577
  super(e), this.name = "InvalidToolInputError";
682
578
  }
683
579
  };
684
- function We(e) {
580
+ function Ae(e) {
685
581
  return {
686
582
  content: [{
687
583
  type: "text",
@@ -690,13 +586,13 @@ function We(e) {
690
586
  isError: !0
691
587
  };
692
588
  }
693
- function Ge(e) {
589
+ function je(e) {
694
590
  return Buffer.from(e.buffer, e.byteOffset, e.byteLength).toString("base64");
695
591
  }
696
592
  //#endregion
697
593
  //#region src/tools/annotate-url.ts
698
- var z = "annot_annotate_url", B = {
699
- name: z,
594
+ var B = "annot_annotate_url", Me = {
595
+ name: B,
700
596
  description: "Open a URL in a headless browser, capture a screenshot, and overlay annotations whose positions are specified as Playwright locator strings (`button:has-text(\"Submit\")`, `[data-testid=\"email\"]`, `role=button[name=\"Sign in\"]`) or bounding boxes. Returns the annotated PNG inline unless `output` is specified.",
701
597
  inputSchema: {
702
598
  type: "object",
@@ -760,8 +656,8 @@ var z = "annot_annotate_url", B = {
760
656
  },
761
657
  $defs: {
762
658
  ...T,
763
- LocatorAnnotation: E,
764
- EncodeOptions: D
659
+ LocatorAnnotation: ve,
660
+ EncodeOptions: E
765
661
  }
766
662
  }
767
663
  }, V = class extends Error {
@@ -769,9 +665,9 @@ var z = "annot_annotate_url", B = {
769
665
  super(e), this.name = "InvalidAnnotateUrlInputError";
770
666
  }
771
667
  };
772
- async function Ke(e, t) {
668
+ async function Ne(e, t) {
773
669
  try {
774
- let n = qe(e), r = await h(t.pool, {
670
+ let n = Pe(e), r = await _(t.pool, {
775
671
  url: n.url,
776
672
  viewport: n.viewport,
777
673
  fullPage: n.fullPage,
@@ -782,30 +678,30 @@ async function Ke(e, t) {
782
678
  } finally {
783
679
  await r.handle.close();
784
680
  }
785
- let a = A(r.pngBytes), s = o(i), c = await P(t.annotator.toPng({
786
- originalDataUrl: `data:image/png;base64,${Ye(r.pngBytes)}`,
787
- annotationsSvg: s,
681
+ let a = j(r.pngBytes), o = c(i), s = await F(t.annotator.toPng({
682
+ originalDataUrl: `data:image/png;base64,${Ie(r.pngBytes)}`,
683
+ annotationsSvg: o,
788
684
  width: a.width,
789
685
  height: a.height
790
686
  }), a, n.encode);
791
687
  if (n.output) {
792
- await p(n.output, c.bytes);
793
- let e = c.reason ? `, reason: ${c.reason}` : "";
688
+ await p(n.output, s.bytes);
689
+ let e = s.reason ? `, reason: ${s.reason}` : "";
794
690
  return { content: [{
795
691
  type: "text",
796
- text: `Wrote ${c.bytes.byteLength}-byte ${c.chosen.toUpperCase()} to ${n.output} (${c.width}×${c.height}, ${n.annotations.length} annotation${n.annotations.length === 1 ? "" : "s"}, captured from ${n.url}${e}).`
692
+ text: `Wrote ${s.bytes.byteLength}-byte ${s.chosen.toUpperCase()} to ${n.output} (${s.width}×${s.height}, ${n.annotations.length} annotation${n.annotations.length === 1 ? "" : "s"}, captured from ${n.url}${e}).`
797
693
  }] };
798
694
  }
799
695
  return { content: [{
800
696
  type: "image",
801
- data: Ye(c.bytes),
802
- mimeType: c.mimeType
697
+ data: Ie(s.bytes),
698
+ mimeType: s.mimeType
803
699
  }] };
804
700
  } catch (e) {
805
- return Je(e);
701
+ return Fe(e);
806
702
  }
807
703
  }
808
- function qe(e) {
704
+ function Pe(e) {
809
705
  if (typeof e.url != "string" || e.url.length === 0) throw new V("`url` is required and must be a non-empty string.");
810
706
  if (!Array.isArray(e.annotations)) throw new V("`annotations` is required and must be an array.");
811
707
  let t = e.annotations, n;
@@ -839,7 +735,7 @@ function qe(e) {
839
735
  encode: o
840
736
  };
841
737
  }
842
- function Je(e) {
738
+ function Fe(e) {
843
739
  return {
844
740
  content: [{
845
741
  type: "text",
@@ -848,21 +744,21 @@ function Je(e) {
848
744
  isError: !0
849
745
  };
850
746
  }
851
- function Ye(e) {
747
+ function Ie(e) {
852
748
  return Buffer.from(e.buffer, e.byteOffset, e.byteLength).toString("base64");
853
749
  }
854
750
  //#endregion
855
751
  //#region src/browser/aria-snapshot.ts
856
- var Xe = {
752
+ var Le = {
857
753
  width: 1280,
858
754
  height: 800,
859
755
  deviceScaleFactor: 1
860
- }, Ze = "load", Qe = "body";
756
+ }, Re = "load", ze = "body";
861
757
  async function H(e, t) {
862
758
  let n = {
863
- ...Xe,
759
+ ...Le,
864
760
  ...t.viewport
865
- }, r = t.waitFor ?? Ze, i = t.rootSelector ?? Qe, a = await e.acquire(), o, s = !1, c = () => {
761
+ }, r = t.waitFor ?? Re, i = t.rootSelector ?? ze, a = await e.acquire(), o, s = !1, c = () => {
866
762
  s || (s = !0, e.release());
867
763
  };
868
764
  try {
@@ -889,8 +785,8 @@ async function H(e, t) {
889
785
  }
890
786
  //#endregion
891
787
  //#region src/tools/aria-snapshot.ts
892
- var $e = "annot_aria_snapshot", et = {
893
- name: $e,
788
+ var Be = "annot_aria_snapshot", Ve = {
789
+ name: Be,
894
790
  description: "Open a URL in a headless browser and return Playwright's AI-mode aria-snapshot (YAML format with `[ref=eN]` markers). The same primitive `playwright-mcp` and `playwright-cli` use. Refs are session-local — store `role + name` (not refs) as persistent identifiers across snapshots.",
895
791
  inputSchema: {
896
792
  type: "object",
@@ -951,9 +847,9 @@ var $e = "annot_aria_snapshot", et = {
951
847
  }
952
848
  }
953
849
  };
954
- async function tt(e, t) {
850
+ async function He(e, t) {
955
851
  if (typeof e.url != "string" || e.url.length === 0) return U("`url` is required (string).");
956
- let n = nt(e.viewport), r = rt(e.waitFor), i = typeof e.rootSelector == "string" ? e.rootSelector : void 0, a = typeof e.timeout == "number" ? e.timeout : void 0, o = it(e.output);
852
+ let n = Ue(e.viewport), r = We(e.waitFor), i = typeof e.rootSelector == "string" ? e.rootSelector : void 0, a = typeof e.timeout == "number" ? e.timeout : void 0, o = Ge(e.output);
957
853
  if (o && !o.ok) return U(o.error);
958
854
  let s;
959
855
  try {
@@ -983,7 +879,7 @@ async function tt(e, t) {
983
879
  text: s.yaml
984
880
  }] };
985
881
  }
986
- function nt(e) {
882
+ function Ue(e) {
987
883
  if (typeof e != "object" || !e) return;
988
884
  let t = e, n = typeof t.width == "number" ? t.width : 1280, r = typeof t.height == "number" ? t.height : 800, i = typeof t.deviceScaleFactor == "number" ? t.deviceScaleFactor : void 0;
989
885
  return {
@@ -992,10 +888,10 @@ function nt(e) {
992
888
  ...i === void 0 ? {} : { deviceScaleFactor: i }
993
889
  };
994
890
  }
995
- function rt(e) {
891
+ function We(e) {
996
892
  if (e === "load" || e === "domcontentloaded" || e === "networkidle") return e;
997
893
  }
998
- function it(e) {
894
+ function Ge(e) {
999
895
  if (e != null) return typeof e != "string" || e.length === 0 ? {
1000
896
  ok: !1,
1001
897
  error: "`output` must be a non-empty string when set."
@@ -1018,7 +914,7 @@ function U(e) {
1018
914
  }
1019
915
  //#endregion
1020
916
  //#region src/tools/compare-screenshots.ts
1021
- var W = "annot_compare_screenshots", at = {
917
+ var W = "annot_compare_screenshots", Ke = {
1022
918
  name: W,
1023
919
  description: "Compare two screenshots (must have identical dimensions) and return a PNG of the `after` image with changed regions highlighted as red rectangles. Useful for visual-diff PR review.",
1024
920
  inputSchema: {
@@ -1049,14 +945,14 @@ var W = "annot_compare_screenshots", at = {
1049
945
  output: { type: "string" },
1050
946
  encode: { $ref: "#/$defs/EncodeOptions" }
1051
947
  },
1052
- $defs: { EncodeOptions: D }
948
+ $defs: { EncodeOptions: E }
1053
949
  }
1054
950
  }, G = class extends Error {
1055
951
  constructor(e) {
1056
952
  super(e), this.name = "InvalidCompareInputError";
1057
953
  }
1058
954
  };
1059
- async function ot(e, t) {
955
+ async function qe(e, t) {
1060
956
  try {
1061
957
  if (typeof e.before != "string") throw new G("`before` is required and must be a string.");
1062
958
  if (typeof e.after != "string") throw new G("`after` is required and must be a string.");
@@ -1071,12 +967,12 @@ async function ot(e, t) {
1071
967
  if (typeof e.encode != "object" || e.encode === null) throw new G("`encode` must be an object when provided.");
1072
968
  a = e.encode;
1073
969
  }
1074
- let [s, c] = await Promise.all([M(e.before), M(e.after)]), l = await C(s.bytes, c.bytes, { threshold: n }), u = o(l.regions.map((e) => ({
970
+ let [o, s] = await Promise.all([N(e.before), N(e.after)]), l = await ee(o.bytes, s.bytes, { threshold: n }), u = c(l.regions.map((e) => ({
1075
971
  type: "rect",
1076
972
  bbox: e,
1077
973
  intent: "warning"
1078
- }))), d = await P(t.annotator.toPng({
1079
- originalDataUrl: c.dataUrl,
974
+ }))), d = await F(t.annotator.toPng({
975
+ originalDataUrl: s.dataUrl,
1080
976
  annotationsSvg: u,
1081
977
  width: l.width,
1082
978
  height: l.height
@@ -1113,8 +1009,8 @@ async function ot(e, t) {
1113
1009
  }
1114
1010
  //#endregion
1115
1011
  //#region src/tools/draft-screen-spec.ts
1116
- var st = "annot_draft_screen_spec", ct = {
1117
- name: st,
1012
+ var Je = "annot_draft_screen_spec", Ye = {
1013
+ name: Je,
1118
1014
  description: "Given a URL, propose an `.mdx` skeleton for an annot product-docs screen spec. The tool opens the page in a headless browser, takes a Playwright `aria-snapshot`, and emits an MDX with frontmatter + a `<Screen>` block containing one `<Overlay match={{ role, name }}>` per interactive element. The agent fills in the prose body of each overlay; the structural skeleton is mechanical.",
1119
1015
  inputSchema: {
1120
1016
  type: "object",
@@ -1175,7 +1071,7 @@ var st = "annot_draft_screen_spec", ct = {
1175
1071
  }
1176
1072
  }
1177
1073
  }
1178
- }, lt = new Set([
1074
+ }, Xe = /* @__PURE__ */ new Set([
1179
1075
  "button",
1180
1076
  "checkbox",
1181
1077
  "combobox",
@@ -1193,20 +1089,20 @@ var st = "annot_draft_screen_spec", ct = {
1193
1089
  "textbox",
1194
1090
  "treeitem"
1195
1091
  ]);
1196
- async function ut(e, t) {
1092
+ async function Ze(e, t) {
1197
1093
  if (typeof e.url != "string" || e.url.length === 0) return K("`url` is required (string).");
1198
1094
  if (typeof e.id != "string" || e.id.length === 0) return K("`id` is required (string).");
1199
1095
  let n = e.id, r = typeof e.title == "string" ? e.title : void 0, i = typeof e.book == "string" ? e.book : void 0, a = (typeof e.screenImageSrc == "string" ? e.screenImageSrc : "./shots/{id}.png").replace(/\{id\}/g, n), o;
1200
1096
  try {
1201
1097
  o = await H(t.pool, {
1202
1098
  url: e.url,
1203
- viewport: dt(e.viewport),
1204
- waitFor: ft(e.waitFor)
1099
+ viewport: Qe(e.viewport),
1100
+ waitFor: $e(e.waitFor)
1205
1101
  });
1206
1102
  } catch (e) {
1207
1103
  return K(`Failed to capture aria-snapshot: ${e instanceof Error ? e.message : String(e)}`);
1208
1104
  }
1209
- let s = ce(o.yaml).filter((e) => lt.has(e.role)).map((e, t) => `<Overlay match={{ role: ${JSON.stringify(e.role)}, name: ${JSON.stringify(e.name)} }} number={${t + 1}}>
1105
+ let s = g(o.yaml).filter((e) => Xe.has(e.role)).map((e, t) => `<Overlay match={{ role: ${JSON.stringify(e.role)}, name: ${JSON.stringify(e.name)} }} number={${t + 1}}>
1210
1106
  TODO: describe ${e.role} "${e.name}".
1211
1107
  </Overlay>`);
1212
1108
  return { content: [{
@@ -1237,7 +1133,7 @@ TODO: describe ${e.role} "${e.name}".
1237
1133
  ].join("\n")}\n`
1238
1134
  }] };
1239
1135
  }
1240
- function dt(e) {
1136
+ function Qe(e) {
1241
1137
  if (typeof e != "object" || !e) return;
1242
1138
  let t = e, n = typeof t.width == "number" ? t.width : 1280, r = typeof t.height == "number" ? t.height : 800, i = typeof t.deviceScaleFactor == "number" ? t.deviceScaleFactor : void 0;
1243
1139
  return {
@@ -1246,7 +1142,7 @@ function dt(e) {
1246
1142
  ...i === void 0 ? {} : { deviceScaleFactor: i }
1247
1143
  };
1248
1144
  }
1249
- function ft(e) {
1145
+ function $e(e) {
1250
1146
  if (e === "load" || e === "domcontentloaded" || e === "networkidle") return e;
1251
1147
  }
1252
1148
  function K(e) {
@@ -1260,8 +1156,8 @@ function K(e) {
1260
1156
  }
1261
1157
  //#endregion
1262
1158
  //#region src/tools/propose-drift-fixes.ts
1263
- var pt = "annot_propose_drift_fixes", mt = {
1264
- name: pt,
1159
+ var et = "annot_propose_drift_fixes", tt = {
1160
+ name: et,
1265
1161
  description: "Given an MDX path + the live URL the screen renders at, run drift detection between the stored `<Overlay match>` keys and the current `aria-snapshot`. Returns a structured Markdown report: one section per finding with the kind / severity / message / suggested fix. The agent reads the report and applies edits via its own patch primitive.",
1266
1162
  inputSchema: {
1267
1163
  type: "object",
@@ -1314,12 +1210,12 @@ var pt = "annot_propose_drift_fixes", mt = {
1314
1210
  }
1315
1211
  }
1316
1212
  };
1317
- async function ht(e, t) {
1213
+ async function nt(e, t) {
1318
1214
  if (typeof e.mdxPath != "string" || e.mdxPath.length === 0) return q("`mdxPath` is required (string).");
1319
1215
  if (typeof e.url != "string" || e.url.length === 0) return q("`url` is required (string).");
1320
- let n = typeof e.screenId == "string" ? e.screenId : void 0, r = await se(e.mdxPath);
1216
+ let n = typeof e.screenId == "string" ? e.screenId : void 0, r = await h(e.mdxPath);
1321
1217
  if (!r) return q(`${e.mdxPath} has no \`annot:\` frontmatter.`);
1322
- let i = oe(r.screens).filter((e) => !n || e.id === n);
1218
+ let i = ce(r.screens).filter((e) => !n || e.id === n);
1323
1219
  if (i.length === 0) return { content: [{
1324
1220
  type: "text",
1325
1221
  text: `No lintable screens in ${e.mdxPath}${n ? ` (screenId=${n})` : ""}.`
@@ -1330,15 +1226,15 @@ async function ht(e, t) {
1330
1226
  try {
1331
1227
  r = await H(t.pool, {
1332
1228
  url: e.url,
1333
- viewport: _t(e.viewport),
1334
- waitFor: vt(e.waitFor)
1229
+ viewport: it(e.viewport),
1230
+ waitFor: at(e.waitFor)
1335
1231
  });
1336
1232
  } catch (e) {
1337
1233
  return q(`Failed to capture aria-snapshot for screen=${n.id}: ${e instanceof Error ? e.message : String(e)}`);
1338
1234
  }
1339
- let i = ae({
1235
+ let i = se({
1340
1236
  screen: n,
1341
- liveSnapshot: ce(r.yaml)
1237
+ liveSnapshot: g(r.yaml)
1342
1238
  });
1343
1239
  for (let e of i) a.push({
1344
1240
  screenId: n.id,
@@ -1350,16 +1246,16 @@ async function ht(e, t) {
1350
1246
  text: `No drift detected in ${e.mdxPath} against ${e.url}.`
1351
1247
  }] } : { content: [{
1352
1248
  type: "text",
1353
- text: gt(e.mdxPath, e.url, a)
1249
+ text: rt(e.mdxPath, e.url, a)
1354
1250
  }] };
1355
1251
  }
1356
- function gt(e, t, n) {
1252
+ function rt(e, t, n) {
1357
1253
  let r = [];
1358
1254
  r.push(`# Drift report — ${e}`), r.push(""), r.push(`Live URL: ${t}`), r.push(`Findings: ${n.length}`), r.push("");
1359
1255
  for (let { screenId: e, finding: t } of n) r.push(`## ${t.severity.toUpperCase()} [${e}] ${t.kind}`), r.push(""), r.push(t.message), t.match && (r.push(""), r.push("Current match key:"), r.push("```ts"), r.push(JSON.stringify(t.match, null, 2)), r.push("```")), t.suggestion && (r.push(""), r.push("Suggested replacement:"), r.push("```ts"), r.push(JSON.stringify(t.suggestion, null, 2)), r.push("```")), r.push("");
1360
1256
  return r.join("\n");
1361
1257
  }
1362
- function _t(e) {
1258
+ function it(e) {
1363
1259
  if (typeof e != "object" || !e) return;
1364
1260
  let t = e, n = typeof t.width == "number" ? t.width : 1280, r = typeof t.height == "number" ? t.height : 800, i = typeof t.deviceScaleFactor == "number" ? t.deviceScaleFactor : void 0;
1365
1261
  return {
@@ -1368,7 +1264,7 @@ function _t(e) {
1368
1264
  ...i === void 0 ? {} : { deviceScaleFactor: i }
1369
1265
  };
1370
1266
  }
1371
- function vt(e) {
1267
+ function at(e) {
1372
1268
  if (e === "load" || e === "domcontentloaded" || e === "networkidle") return e;
1373
1269
  }
1374
1270
  function q(e) {
@@ -1382,7 +1278,7 @@ function q(e) {
1382
1278
  }
1383
1279
  //#endregion
1384
1280
  //#region src/tools/redact-screenshot.ts
1385
- var J = "annot_redact_screenshot", yt = {
1281
+ var J = "annot_redact_screenshot", Y = {
1386
1282
  name: J,
1387
1283
  description: "Destructively burn redactions (solid / mosaic / blur) into a PNG screenshot. The original pixels under each region are irrecoverably replaced. Returns the redacted PNG inline unless `output` is specified.",
1388
1284
  inputSchema: {
@@ -1407,30 +1303,30 @@ var J = "annot_redact_screenshot", yt = {
1407
1303
  $defs: {
1408
1304
  ...T,
1409
1305
  BboxRedactRegion: t,
1410
- EncodeOptions: D
1306
+ EncodeOptions: E
1411
1307
  }
1412
1308
  }
1413
- }, Y = class extends Error {
1309
+ }, X = class extends Error {
1414
1310
  constructor(e) {
1415
1311
  super(e), this.name = "InvalidRedactInputError";
1416
1312
  }
1417
1313
  };
1418
- async function X(e) {
1314
+ async function ot(e) {
1419
1315
  try {
1420
- if (typeof e.image != "string") throw new Y("`image` is required and must be a string.");
1421
- if (!Array.isArray(e.regions)) throw new Y("`regions` is required and must be an array.");
1316
+ if (typeof e.image != "string") throw new X("`image` is required and must be a string.");
1317
+ if (!Array.isArray(e.regions)) throw new X("`regions` is required and must be an array.");
1422
1318
  let t = e.regions, n;
1423
1319
  if (e.output !== void 0) {
1424
- if (typeof e.output != "string") throw new Y("`output` must be a string when provided.");
1425
- if (!m(e.output)) throw new Y(`\`output\` path "${e.output}" must be absolute.`);
1320
+ if (typeof e.output != "string") throw new X("`output` must be a string when provided.");
1321
+ if (!m(e.output)) throw new X(`\`output\` path "${e.output}" must be absolute.`);
1426
1322
  n = e.output;
1427
1323
  }
1428
1324
  let r;
1429
1325
  if (e.encode !== void 0) {
1430
- if (typeof e.encode != "object" || e.encode === null) throw new Y("`encode` must be an object when provided.");
1326
+ if (typeof e.encode != "object" || e.encode === null) throw new X("`encode` must be an object when provided.");
1431
1327
  r = e.encode;
1432
1328
  }
1433
- let i = await M(e.image), a = await P(await N(i.bytes, t), i.dimensions, r);
1329
+ let i = await N(e.image), a = await F(await l(i.bytes, t), i.dimensions, r);
1434
1330
  if (n) {
1435
1331
  await p(n, a.bytes);
1436
1332
  let e = a.reason ? `, reason: ${a.reason}` : "";
@@ -1456,7 +1352,7 @@ async function X(e) {
1456
1352
  }
1457
1353
  //#endregion
1458
1354
  //#region src/tools/redact-url.ts
1459
- var Z = "annot_redact_url", bt = {
1355
+ var Z = "annot_redact_url", st = {
1460
1356
  name: Z,
1461
1357
  description: "Open a URL in a headless browser, capture a screenshot, and destructively burn redactions over regions identified by locator strings or bboxes. Returns the redacted PNG inline unless `output` is specified.",
1462
1358
  inputSchema: {
@@ -1511,8 +1407,8 @@ var Z = "annot_redact_url", bt = {
1511
1407
  },
1512
1408
  $defs: {
1513
1409
  ...T,
1514
- LocatorRedactRegion: Ce,
1515
- EncodeOptions: D
1410
+ LocatorRedactRegion: D,
1411
+ EncodeOptions: E
1516
1412
  }
1517
1413
  }
1518
1414
  }, Q = class extends Error {
@@ -1520,9 +1416,9 @@ var Z = "annot_redact_url", bt = {
1520
1416
  super(e), this.name = "InvalidRedactUrlInputError";
1521
1417
  }
1522
1418
  };
1523
- async function xt(e, t) {
1419
+ async function ct(e, t) {
1524
1420
  try {
1525
- let n = St(e), r = await h(t.pool, {
1421
+ let n = lt(e), r = await _(t.pool, {
1526
1422
  url: n.url,
1527
1423
  viewport: n.viewport,
1528
1424
  fullPage: n.fullPage,
@@ -1531,13 +1427,13 @@ async function xt(e, t) {
1531
1427
  try {
1532
1428
  i = [];
1533
1429
  for (let e of n.regions) {
1534
- let t = { bbox: await Ct(r.handle.page, e) };
1430
+ let t = { bbox: await ut(r.handle.page, e) };
1535
1431
  e.style !== void 0 && (t.style = e.style), e.color !== void 0 && (t.color = e.color), i.push(t);
1536
1432
  }
1537
1433
  } finally {
1538
1434
  await r.handle.close();
1539
1435
  }
1540
- let a = await P(await N(r.pngBytes, i), A(r.pngBytes), n.encode);
1436
+ let a = await F(await l(r.pngBytes, i), j(r.pngBytes), n.encode);
1541
1437
  if (n.output) {
1542
1438
  await p(n.output, a.bytes);
1543
1439
  let e = a.reason ? `, reason: ${a.reason}` : "";
@@ -1561,7 +1457,7 @@ async function xt(e, t) {
1561
1457
  };
1562
1458
  }
1563
1459
  }
1564
- function St(e) {
1460
+ function lt(e) {
1565
1461
  if (typeof e.url != "string" || e.url.length === 0) throw new Q("`url` is required and must be a non-empty string.");
1566
1462
  if (!Array.isArray(e.regions)) throw new Q("`regions` is required and must be an array.");
1567
1463
  let t = e.regions, n;
@@ -1595,15 +1491,15 @@ function St(e) {
1595
1491
  encode: o
1596
1492
  };
1597
1493
  }
1598
- async function Ct(e, t) {
1494
+ async function ut(e, t) {
1599
1495
  if (t.bbox !== void 0) return t.bbox;
1600
- if (t.locator !== void 0) return y(e, t.locator);
1496
+ if (t.locator !== void 0) return x(e, t.locator);
1601
1497
  throw new Q("redact region requires either `bbox` or `locator`.");
1602
1498
  }
1603
1499
  //#endregion
1604
1500
  //#region src/tools/translate-screen-spec.ts
1605
- var wt = "annot_translate_screen_spec", Tt = {
1606
- name: wt,
1501
+ var dt = "annot_translate_screen_spec", ft = {
1502
+ name: dt,
1607
1503
  description: "Given an MDX with `annot:` frontmatter and a target locale (e.g. `en-US` / `ja-JP` / `ko-KR`), emit a structured translation manifest listing every translatable string the agent should localise: frontmatter title / purpose, per-overlay Markdown bodies, per-transition prose. The agent translates the strings via its own LLM call and the host writes the localised MDX.",
1608
1504
  inputSchema: {
1609
1505
  type: "object",
@@ -1625,10 +1521,10 @@ var wt = "annot_translate_screen_spec", Tt = {
1625
1521
  }
1626
1522
  }
1627
1523
  };
1628
- async function Et(e) {
1524
+ async function pt(e) {
1629
1525
  if (typeof e.mdxPath != "string" || e.mdxPath.length === 0) return $("`mdxPath` is required (string).");
1630
1526
  if (typeof e.targetLocale != "string" || e.targetLocale.length === 0) return $("`targetLocale` is required (string).");
1631
- let t = await se(e.mdxPath);
1527
+ let t = await h(e.mdxPath);
1632
1528
  if (!t) return $(`${e.mdxPath} has no \`annot:\` frontmatter.`);
1633
1529
  let n = [];
1634
1530
  t.frontmatter.title && n.push({
@@ -1692,54 +1588,54 @@ function $(e) {
1692
1588
  }
1693
1589
  //#endregion
1694
1590
  //#region src/server.ts
1695
- var Dt = "annot-mcp", Ot = "0.1.0", kt = [
1696
- I,
1697
- B,
1698
- yt,
1699
- bt,
1700
- at,
1701
- et,
1702
- ct,
1703
- mt,
1704
- Tt
1591
+ var mt = "annot-mcp", ht = "0.1.0", gt = [
1592
+ L,
1593
+ Me,
1594
+ Y,
1595
+ st,
1596
+ Ke,
1597
+ Ve,
1598
+ Ye,
1599
+ tt,
1600
+ ft
1705
1601
  ];
1706
- function At(e = {}) {
1707
- let t = new ne({
1708
- name: Dt,
1709
- version: e.version ?? Ot
1710
- }, { capabilities: { tools: {} } }), n = e.annotator ?? s(e.annotatorOptions ?? {}), r = e.pool ?? pe();
1711
- return t.setRequestHandler(ie, async () => ({ tools: kt })), t.setRequestHandler(re, async (e) => {
1602
+ function _t(e = {}) {
1603
+ let t = new ie({
1604
+ name: mt,
1605
+ version: e.version ?? ht
1606
+ }, { capabilities: { tools: {} } }), n = e.annotator ?? d(e.annotatorOptions ?? {}), r = e.pool ?? pe();
1607
+ return t.setRequestHandler(oe, async () => ({ tools: gt })), t.setRequestHandler(ae, async (e) => {
1712
1608
  let { name: t, arguments: i } = e.params, a;
1713
1609
  switch (t) {
1714
- case F:
1715
- a = await L(i ?? {}, { annotator: n });
1610
+ case I:
1611
+ a = await R(i ?? {}, { annotator: n });
1716
1612
  break;
1717
- case z:
1718
- a = await Ke(i ?? {}, {
1613
+ case B:
1614
+ a = await Ne(i ?? {}, {
1719
1615
  annotator: n,
1720
1616
  pool: r
1721
1617
  });
1722
1618
  break;
1723
1619
  case J:
1724
- a = await X(i ?? {});
1620
+ a = await ot(i ?? {});
1725
1621
  break;
1726
1622
  case Z:
1727
- a = await xt(i ?? {}, { pool: r });
1623
+ a = await ct(i ?? {}, { pool: r });
1728
1624
  break;
1729
1625
  case W:
1730
- a = await ot(i ?? {}, { annotator: n });
1626
+ a = await qe(i ?? {}, { annotator: n });
1731
1627
  break;
1732
- case $e:
1733
- a = await tt(i ?? {}, { pool: r });
1628
+ case Be:
1629
+ a = await He(i ?? {}, { pool: r });
1734
1630
  break;
1735
- case st:
1736
- a = await ut(i ?? {}, { pool: r });
1631
+ case Je:
1632
+ a = await Ze(i ?? {}, { pool: r });
1737
1633
  break;
1738
- case pt:
1739
- a = await ht(i ?? {}, { pool: r });
1634
+ case et:
1635
+ a = await nt(i ?? {}, { pool: r });
1740
1636
  break;
1741
- case wt:
1742
- a = await Et(i ?? {});
1637
+ case dt:
1638
+ a = await pt(i ?? {});
1743
1639
  break;
1744
1640
  default: a = {
1745
1641
  content: [{
@@ -1754,9 +1650,9 @@ function At(e = {}) {
1754
1650
  }
1755
1651
  //#endregion
1756
1652
  //#region src/transport.ts
1757
- async function jt() {
1758
- let e = At(), t = new le();
1653
+ async function vt() {
1654
+ let e = _t(), t = new le();
1759
1655
  await e.connect(t);
1760
1656
  }
1761
1657
  //#endregion
1762
- export { F as ANNOTATE_SCREENSHOT_TOOL_NAME, z as ANNOTATE_URL_TOOL_NAME, e as BBOX_ANNOTATION_SCHEMA, t as BBOX_REDACT_REGION_SCHEMA, g as BrowserPool, W as COMPARE_SCREENSHOTS_TOOL_NAME, _ as ChromiumUnavailableError, Se as DimensionMismatchError, j as InvalidImageInputError, k as InvalidPngError, E as LOCATOR_ANNOTATION_SCHEMA, Ce as LOCATOR_REDACT_REGION_SCHEMA, v as LocatorResolutionError, J as REDACT_SCREENSHOT_TOOL_NAME, Z as REDACT_URL_TOOL_NAME, T as SHARED_DEFS, ye as aggregateDiffRegions, I as annotateScreenshotTool, B as annotateUrlTool, i as arrowBetween, a as bboxAnnotationsToSvg, N as burnRedactions, h as capturePage, at as compareScreenshotsTool, pe as createChromiumPool, At as createServer, C as diffScreenshots, L as handleAnnotateScreenshot, Ke as handleAnnotateUrl, ot as handleCompareScreenshots, X as handleRedactScreenshot, xt as handleRedactUrl, A as readPngDimensions, l as rectForBoundingBox, yt as redactScreenshotTool, bt as redactUrlTool, M as resolveImageInput, y as resolveLocator, me as resolveLocatorAnnotation, he as resolveLocatorAnnotations, jt as runStdioServer, u as textAt };
1658
+ export { I as ANNOTATE_SCREENSHOT_TOOL_NAME, B as ANNOTATE_URL_TOOL_NAME, e as BBOX_ANNOTATION_SCHEMA, t as BBOX_REDACT_REGION_SCHEMA, v as BrowserPool, W as COMPARE_SCREENSHOTS_TOOL_NAME, y as ChromiumUnavailableError, r as DimensionMismatchError, M as InvalidImageInputError, A as InvalidPngError, ve as LOCATOR_ANNOTATION_SCHEMA, D as LOCATOR_REDACT_REGION_SCHEMA, b as LocatorResolutionError, J as REDACT_SCREENSHOT_TOOL_NAME, Z as REDACT_URL_TOOL_NAME, T as SHARED_DEFS, a as aggregateDiffRegions, L as annotateScreenshotTool, Me as annotateUrlTool, o as arrowBetween, s as bboxAnnotationsToSvg, l as burnRedactions, u as burnRegions, _ as capturePage, Ke as compareScreenshotsTool, pe as createChromiumPool, _t as createServer, ee as diffScreenshots, R as handleAnnotateScreenshot, Ne as handleAnnotateUrl, qe as handleCompareScreenshots, ot as handleRedactScreenshot, ct as handleRedactUrl, j as readPngDimensions, te as rectForBoundingBox, Y as redactScreenshotTool, st as redactUrlTool, N as resolveImageInput, x as resolveLocator, me as resolveLocatorAnnotation, he as resolveLocatorAnnotations, vt as runStdioServer, ne as textAt };