@pixerate/editor 0.227.1 → 0.228.1

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 (35) hide show
  1. package/dist/agent/index.cjs +6 -6
  2. package/dist/agent/index.js +4 -4
  3. package/dist/bridge/cli.cjs +3 -3
  4. package/dist/bridge/cli.js +2 -2
  5. package/dist/bridge/index.cjs +3 -3
  6. package/dist/bridge/index.js +2 -2
  7. package/dist/canvas/drawController.d.cts +6 -0
  8. package/dist/canvas/drawController.d.ts +6 -0
  9. package/dist/canvas/gestures.d.cts +87 -0
  10. package/dist/canvas/gestures.d.ts +87 -0
  11. package/dist/canvas/index.cjs +30 -2
  12. package/dist/canvas/index.d.cts +1 -0
  13. package/dist/canvas/index.d.ts +1 -0
  14. package/dist/canvas/index.js +30 -2
  15. package/dist/{chunk-VXLYEYP4.cjs → chunk-4I76OCVD.cjs} +2 -2
  16. package/dist/{chunk-SAN4SBBS.js → chunk-ABHOYBZD.js} +39 -14
  17. package/dist/{chunk-53GOGBTM.cjs → chunk-CHAWTXBE.cjs} +243 -39
  18. package/dist/{chunk-OJTZKDLJ.cjs → chunk-KBNCEZZB.cjs} +7 -7
  19. package/dist/{chunk-7KZ2HKKC.js → chunk-LPFQHVCO.js} +244 -1
  20. package/dist/{chunk-H73MSHYZ.js → chunk-QTMQ5TGA.js} +1 -1
  21. package/dist/{chunk-Z7BVK32C.cjs → chunk-RTPBM46F.cjs} +39 -14
  22. package/dist/{chunk-67JAEU53.js → chunk-SPPDMY7T.js} +1 -1
  23. package/dist/{chunk-4EFNS2HV.cjs → chunk-T7QSEKDY.cjs} +248 -5
  24. package/dist/{chunk-ZPJEH456.js → chunk-XVIK73LS.js} +206 -2
  25. package/dist/commands/agentTools.d.cts +14 -0
  26. package/dist/commands/agentTools.d.ts +14 -0
  27. package/dist/commands/builtins.d.cts +11 -1
  28. package/dist/commands/builtins.d.ts +11 -1
  29. package/dist/commands/index.cjs +23 -9
  30. package/dist/commands/index.js +17 -3
  31. package/dist/tools/index.cjs +3 -3
  32. package/dist/tools/index.js +2 -2
  33. package/package.json +1 -1
  34. package/skills/pixerate-agent-tools/SKILL.md +5 -0
  35. package/skills/pixerate-canvas/SKILL.md +41 -2
@@ -3,7 +3,7 @@
3
3
 
4
4
 
5
5
 
6
- var _chunkZ7BVK32Ccjs = require('./chunk-Z7BVK32C.cjs');
6
+ var _chunkRTPBM46Fcjs = require('./chunk-RTPBM46F.cjs');
7
7
 
8
8
  // src/bridge/index.ts
9
9
  var _http = require('http');
@@ -197,7 +197,7 @@ var SKILL_INSTRUCTIONS = "Each editor's tools are documented by an agent skill (
197
197
  async function createToolBridge(options) {
198
198
  const log = _nullishCoalesce(options.log, () => ( ((message) => process.stderr.write(`[${options.name}] ${message}
199
199
  `))));
200
- const port = _nullishCoalesce(options.port, () => ( _chunkZ7BVK32Ccjs.TOOL_BRIDGE_DEFAULT_PORT));
200
+ const port = _nullishCoalesce(options.port, () => ( _chunkRTPBM46Fcjs.TOOL_BRIDGE_DEFAULT_PORT));
201
201
  const retryMs = _nullishCoalesce(options.retryMs, () => ( 2e3));
202
202
  const timeoutMs = _nullishCoalesce(options.timeoutMs, () => ( 6e4));
203
203
  const extraOrigins = new Set(_nullishCoalesce(options.origins, () => ( [])));
@@ -211,7 +211,7 @@ async function createToolBridge(options) {
211
211
  let closed = false;
212
212
  let retry;
213
213
  const send = (editor, message) => editor.socket.send(JSON.stringify(message));
214
- const registry = new (0, _chunkZ7BVK32Ccjs.ToolRegistry)();
214
+ const registry = new (0, _chunkRTPBM46Fcjs.ToolRegistry)();
215
215
  const listeners = /* @__PURE__ */ new Set();
216
216
  const toolsChanged = () => listeners.forEach((l) => l());
217
217
  const describeEditors = () => [...editors.values()].map((e) => `${e.id} (${e.name})`).join(", ");
@@ -319,13 +319,13 @@ async function createToolBridge(options) {
319
319
  return;
320
320
  }
321
321
  if (message.t === "hello") {
322
- if (message.v !== _chunkZ7BVK32Ccjs.TOOL_BRIDGE_PROTOCOL) {
322
+ if (message.v !== _chunkRTPBM46Fcjs.TOOL_BRIDGE_PROTOCOL) {
323
323
  log(`refused an editor speaking protocol v${String(message.v)}`);
324
- return ws.close(1008, `This bridge speaks protocol v${_chunkZ7BVK32Ccjs.TOOL_BRIDGE_PROTOCOL}; update @pixerate/editor.`);
324
+ return ws.close(1008, `This bridge speaks protocol v${_chunkRTPBM46Fcjs.TOOL_BRIDGE_PROTOCOL}; update @pixerate/editor.`);
325
325
  }
326
326
  editor = { id: `e${++editorCounter}`, name: String(message.name || "Editor"), ...message.kind ? { kind: message.kind } : {}, socket: ws, tools: Array.isArray(message.tools) ? message.tools : [], activeAt: Date.now(), activeSeq: ++activity };
327
327
  editors.set(editor.id, editor);
328
- ws.send(JSON.stringify({ t: "welcome", v: _chunkZ7BVK32Ccjs.TOOL_BRIDGE_PROTOCOL, id: editor.id }));
328
+ ws.send(JSON.stringify({ t: "welcome", v: _chunkRTPBM46Fcjs.TOOL_BRIDGE_PROTOCOL, id: editor.id }));
329
329
  log(`editor ${editor.id} connected: ${editor.name} (${editor.tools.length} tools)`);
330
330
  toolsChanged();
331
331
  } else if (message.t === "tools" && editor) {
@@ -381,7 +381,7 @@ async function createToolBridge(options) {
381
381
  `)]);
382
382
  const skills = options.skills === false ? {} : _nullishCoalesce(options.skills, () => ( loadSkillFiles()));
383
383
  const hasSkills = Object.keys(skills).length > 0;
384
- const mcp = _chunkZ7BVK32Ccjs.createMcpServer.call(void 0, registry, {
384
+ const mcp = _chunkRTPBM46Fcjs.createMcpServer.call(void 0, registry, {
385
385
  name: options.name,
386
386
  version: _nullishCoalesce(options.version, () => ( "0.1.0")),
387
387
  instructions: [options.instructions, BRIDGE_INSTRUCTIONS, hasSkills ? SKILL_INSTRUCTIONS : ""].filter(Boolean).join("\n\n"),
@@ -430,6 +430,238 @@ function matchArrangeShortcut(event, bindings = DEFAULT_ARRANGE_SHORTCUTS) {
430
430
  return arrangeShortcutMap(bindings).resolve(event)?.command ?? null;
431
431
  }
432
432
 
433
+ // src/canvas/gestures.ts
434
+ function gestureRandom(seed) {
435
+ let a = seed >>> 0;
436
+ return () => {
437
+ a = a + 1831565813 >>> 0;
438
+ let t = a;
439
+ t = Math.imul(t ^ t >>> 15, t | 1);
440
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
441
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
442
+ };
443
+ }
444
+ function gestureSeed(value) {
445
+ const text = JSON.stringify(value) ?? "";
446
+ let h = 2166136261;
447
+ for (let i = 0; i < text.length; i++) {
448
+ h ^= text.charCodeAt(i);
449
+ h = Math.imul(h, 16777619);
450
+ }
451
+ return h >>> 0;
452
+ }
453
+ function gestureUnion(rects) {
454
+ if (!rects.length) throw new Error("Pass at least one rect.");
455
+ const x = Math.min(...rects.map((r) => r.x));
456
+ const y = Math.min(...rects.map((r) => r.y));
457
+ const right = Math.max(...rects.map((r) => r.x + r.width));
458
+ const bottom = Math.max(...rects.map((r) => r.y + r.height));
459
+ return { x, y, width: right - x, height: bottom - y };
460
+ }
461
+ var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
462
+ var centre = (r) => [r.x + r.width / 2, r.y + r.height / 2];
463
+ function smoothNoise(rand, octaves = 3) {
464
+ const waves = Array.from({ length: octaves }, (_, i) => ({ f: (i + 1) * (0.6 + rand() * 0.8), phase: rand() * Math.PI * 2, amp: 1 / (i + 1) }));
465
+ const total = waves.reduce((sum, w) => sum + w.amp, 0);
466
+ return (t) => waves.reduce((sum, w) => sum + w.amp * Math.sin(2 * Math.PI * w.f * t + w.phase), 0) / total;
467
+ }
468
+ function handPressure(rand) {
469
+ const r = (lo, hi) => Math.round((lo + rand() * (hi - lo)) * 100) / 100;
470
+ return [r(0.35, 0.55), r(0.8, 0.95), r(0.9, 1), r(0.75, 0.95), r(0.4, 0.65)];
471
+ }
472
+ var round = (p) => [Math.round(p[0] * 100) / 100, Math.round(p[1] * 100) / 100];
473
+ function wobblyLine(a, b, rand, amp, bow = 0) {
474
+ const dx = b[0] - a[0];
475
+ const dy = b[1] - a[1];
476
+ const len = Math.hypot(dx, dy);
477
+ if (len === 0) return [a];
478
+ const nx = -dy / len;
479
+ const ny = dx / len;
480
+ const noise = smoothNoise(rand);
481
+ const n = clamp(Math.ceil(len / 4), 8, 200);
482
+ return Array.from({ length: n + 1 }, (_, i) => {
483
+ const t = i / n;
484
+ const off = bow * 4 * t * (1 - t) + amp * noise(t) * Math.sqrt(Math.sin(Math.PI * t));
485
+ return [a[0] + dx * t + nx * off, a[1] + dy * t + ny * off];
486
+ });
487
+ }
488
+ function circleGesture(rect, seed, options = {}) {
489
+ const rand = gestureRandom(seed);
490
+ const pad = Math.max(0, options.padding ?? 8);
491
+ const [cx, cy] = centre(rect);
492
+ const tilt = (rand() - 0.5) * 0.08;
493
+ const c = Math.abs(Math.cos(tilt));
494
+ const s = Math.abs(Math.sin(tilt));
495
+ const a = (rect.width / 2 * c + rect.height / 2 * s) * Math.SQRT2 + pad;
496
+ const b = (rect.width / 2 * s + rect.height / 2 * c) * Math.SQRT2 + pad;
497
+ const dir = rand() < 0.7 ? -1 : 1;
498
+ const start = -Math.PI * 0.75 + (rand() - 0.5) * 0.6;
499
+ const sweep = Math.PI * 2 + Math.PI * (0.1 + rand() * 0.12);
500
+ const jitter = 0.03 + rand() * 0.03;
501
+ const drift = 0.04 + rand() * 0.05;
502
+ const noise = smoothNoise(rand, 4);
503
+ const perimeter = Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));
504
+ const n = clamp(Math.ceil(perimeter * (sweep / (Math.PI * 2)) / 5), 48, 360);
505
+ const points = Array.from({ length: n + 1 }, (_, i) => {
506
+ const t = i / n;
507
+ const angle = start + dir * sweep * t;
508
+ const grow = 1 + jitter * (0.5 + 0.5 * noise(t)) + drift * t * t;
509
+ const ex = a * grow * Math.cos(angle);
510
+ const ey = b * grow * Math.sin(angle);
511
+ return round([cx + ex * Math.cos(tilt) - ey * Math.sin(tilt), cy + ex * Math.sin(tilt) + ey * Math.cos(tilt)]);
512
+ });
513
+ return { points, pressure: handPressure(rand) };
514
+ }
515
+ function underlineGesture(rect, seed, options = {}) {
516
+ const rand = gestureRandom(seed);
517
+ const offset = Math.max(0, options.offset ?? 4);
518
+ const amp = options.wave ? clamp(rect.width * 0.02, 2, 4) : 0;
519
+ const shake = Math.min(1.5, offset * 0.4);
520
+ const base = rect.y + rect.height + offset + amp + shake;
521
+ const slope = Math.min(6, rect.width * 0.03);
522
+ const x0 = rect.x - rect.width * (0.01 + rand() * 0.04);
523
+ const x1 = rect.x + rect.width * (0.96 + rand() * 0.08);
524
+ const line = wobblyLine([x0, base + rand() * slope], [x1, base + rand() * slope], rand, shake, (rand() - 0.5) * 2 * shake);
525
+ const wavelength = clamp(rect.width / 8, 12, 28);
526
+ const phase = rand() * Math.PI * 2;
527
+ const points = amp ? line.map(([x, y]) => [x, y + amp * Math.sin(2 * Math.PI * (x - x0) / wavelength + phase)]) : line;
528
+ return { points: points.map(round), pressure: handPressure(rand) };
529
+ }
530
+ function gestureEdgePoint(rect, toward, gap = 0) {
531
+ const [cx, cy] = centre(rect);
532
+ const dx = toward[0] - cx;
533
+ const dy = toward[1] - cy;
534
+ const len = Math.hypot(dx, dy);
535
+ if (len === 0) return [cx, cy];
536
+ const t = Math.min(dx ? rect.width / 2 / Math.abs(dx) : Infinity, dy ? rect.height / 2 / Math.abs(dy) : Infinity);
537
+ return [cx + dx * t + dx / len * gap, cy + dy * t + dy / len * gap];
538
+ }
539
+ var isRect = (end) => !Array.isArray(end);
540
+ function arrowGesture(from, to, seed, options = {}) {
541
+ const rand = gestureRandom(seed);
542
+ const gap = Math.max(0, options.gap ?? 6);
543
+ const fromCentre = isRect(from) ? centre(from) : from;
544
+ const toCentre = isRect(to) ? centre(to) : to;
545
+ const start = isRect(from) ? gestureEdgePoint(from, toCentre, gap) : from;
546
+ const tip = isRect(to) ? gestureEdgePoint(to, fromCentre, gap) : to;
547
+ const dx = tip[0] - start[0];
548
+ const dy = tip[1] - start[1];
549
+ const len = Math.hypot(dx, dy);
550
+ if (len < 4) throw new Error("The arrow's ends are too close together (or overlap): pass ends at least a few canvas units apart.");
551
+ const curve = clamp(options.curve ?? (0.08 + rand() * 0.08) * (rand() < 0.5 ? -1 : 1), -1, 1);
552
+ const nx = -dy / len;
553
+ const ny = dx / len;
554
+ const control = [(start[0] + tip[0]) / 2 + nx * curve * len, (start[1] + tip[1]) / 2 + ny * curve * len];
555
+ const noise = smoothNoise(rand);
556
+ const amp = Math.min(2, len * 0.01);
557
+ const n = clamp(Math.ceil(len / 4), 12, 200);
558
+ const shaft = Array.from({ length: n + 1 }, (_, i) => {
559
+ const t = i / n;
560
+ const u = 1 - t;
561
+ const x = u * u * start[0] + 2 * u * t * control[0] + t * t * tip[0];
562
+ const y = u * u * start[1] + 2 * u * t * control[1] + t * t * tip[1];
563
+ const off = amp * noise(t) * Math.sqrt(Math.sin(Math.PI * t));
564
+ return [x + nx * off, y + ny * off];
565
+ });
566
+ const tx = tip[0] - control[0];
567
+ const ty = tip[1] - control[1];
568
+ const tl = Math.hypot(tx, ty) || 1;
569
+ const head = clamp(len * 0.15, 8, 22);
570
+ const barb = (angle2, length) => {
571
+ const c = Math.cos(angle2);
572
+ const s = Math.sin(angle2);
573
+ const bx = -(tx / tl) * c + ty / tl * s;
574
+ const by = -(ty / tl) * c - tx / tl * s;
575
+ return [1 / 3, 2 / 3, 1].map((f) => [tip[0] + bx * length * f, tip[1] + by * length * f]);
576
+ };
577
+ const clear = (pts) => !isRect(to) || pts.every(([x, y]) => x <= to.x || x >= to.x + to.width || y <= to.y || y >= to.y + to.height);
578
+ const fit = (angle2) => {
579
+ const length = head * (0.85 + rand() * 0.3);
580
+ for (let k = 1; k > 0.05; k -= 0.15) {
581
+ const pts = barb(angle2 * k, length);
582
+ if (clear(pts)) return pts;
583
+ }
584
+ return barb(0, length);
585
+ };
586
+ const angle = () => (25 + rand() * 8) * Math.PI / 180;
587
+ const first = fit(angle());
588
+ const second = fit(-angle());
589
+ const points = [...shaft, ...first, ...first.slice(0, -1).reverse(), tip, ...second];
590
+ return { points: points.map(round), pressure: handPressure(rand) };
591
+ }
592
+ function bracketGesture(rect, side, seed, options = {}) {
593
+ const rand = gestureRandom(seed);
594
+ const pad = Math.max(0, options.padding ?? 8);
595
+ const vertical = side === "left" || side === "right";
596
+ const span = vertical ? rect.height : rect.width;
597
+ const depth = Math.max(1, options.depth ?? clamp(span * 0.08, 6, 20));
598
+ const from = vertical ? rect.y : rect.x;
599
+ const edge = side === "left" ? rect.x - pad : side === "right" ? rect.x + rect.width + pad : side === "top" ? rect.y - pad : rect.y + rect.height + pad;
600
+ const out = side === "left" || side === "top" ? -1 : 1;
601
+ const at = (s, d) => vertical ? [edge + out * d, from + s * span] : [from + s * span, edge + out * d];
602
+ const noise = smoothNoise(rand);
603
+ const shake = Math.min(1, depth * 0.06);
604
+ const n = clamp(Math.ceil(span / 4), 24, 240);
605
+ let points;
606
+ if (options.shape === "square") {
607
+ const arm = depth * (0.8 + rand() * 0.2);
608
+ const spine = Array.from({ length: n + 1 }, (_, i) => at(i / n, depth + shake * (1 + noise(i / n))));
609
+ points = [at(0, depth - arm), at(0, depth * 0.5), ...spine, at(1, depth * 0.5), at(1, depth - arm * (0.85 + rand() * 0.15))];
610
+ } else {
611
+ const e = clamp(depth / Math.max(span, 1), 0.04, 0.2);
612
+ const brace = (s) => {
613
+ const u = s <= 0.5 ? s : 1 - s;
614
+ if (u < e) return depth / 2 * Math.sin(Math.PI / 2 * u / e);
615
+ if (u < 0.5 - e) return depth / 2;
616
+ return depth / 2 + depth / 2 * (1 - Math.cos(Math.PI / 2 * (u - (0.5 - e)) / e));
617
+ };
618
+ points = Array.from({ length: n + 1 }, (_, i) => {
619
+ const s = i / n;
620
+ return at(s, brace(s) + shake * (1 + noise(s)) * Math.sin(Math.PI * s));
621
+ });
622
+ }
623
+ return { points: points.map(round), pressure: handPressure(rand) };
624
+ }
625
+ function strikeGesture(rect, seed) {
626
+ const rand = gestureRandom(seed);
627
+ const [, cy] = centre(rect);
628
+ const slope = rect.height * 0.08;
629
+ const x0 = rect.x - rect.width * (0.01 + rand() * 0.03);
630
+ const x1 = rect.x + rect.width * (1.01 + rand() * 0.03);
631
+ const y0 = cy + (rand() - 0.5) * rect.height * 0.1 + slope * (rand() - 0.5);
632
+ const y1 = cy + (rand() - 0.5) * rect.height * 0.1 + slope * (rand() - 0.5);
633
+ const points = wobblyLine([x0, y0], [x1, y1], rand, Math.min(1.5, rect.height * 0.05));
634
+ return { points: points.map(round), pressure: handPressure(rand) };
635
+ }
636
+ function crossGesture(rect, seed) {
637
+ const rand = gestureRandom(seed);
638
+ const over = () => 0.02 + rand() * 0.04;
639
+ const left = () => rect.x - rect.width * over();
640
+ const right = () => rect.x + rect.width * (1 + over());
641
+ const top = () => rect.y - rect.height * over();
642
+ const bottom = () => rect.y + rect.height * (1 + over());
643
+ const amp = Math.min(1.5, Math.min(rect.width, rect.height) * 0.03);
644
+ const first = wobblyLine([left(), top()], [right(), bottom()], rand, amp);
645
+ const second = wobblyLine([right(), top()], [left(), bottom()], rand, amp);
646
+ const mid1 = Math.floor(first.length / 2);
647
+ const mid2 = Math.floor(second.length / 2);
648
+ const points = [...first, ...first.slice(mid1, -1).reverse(), ...second.slice(1, mid2 + 1).reverse(), ...second];
649
+ return { points: points.map(round), pressure: handPressure(rand) };
650
+ }
651
+ function checkGesture(at, seed, options = {}) {
652
+ const rand = gestureRandom(seed);
653
+ const [cx, cy] = isRect(at) ? centre(at) : at;
654
+ const s = Math.max(4, options.size ?? (isRect(at) ? clamp(Math.min(at.width, at.height) * 0.6, 12, 48) : 20));
655
+ const turn = (rand() - 0.5) * 12 * Math.PI / 180;
656
+ const place = ([x, y]) => [cx + s * (x * Math.cos(turn) - y * Math.sin(turn)), cy + s * (x * Math.sin(turn) + y * Math.cos(turn))];
657
+ const p0 = [-0.42 + rand() * 0.08, -0.05 + rand() * 0.08];
658
+ const p1 = [-0.12 + rand() * 0.06, 0.38 + rand() * 0.06];
659
+ const p2 = [0.48 + rand() * 0.06, -0.5 + rand() * 0.06];
660
+ const short = wobblyLine(place(p0), place(p1), rand, 0, -s * 0.03);
661
+ const long = wobblyLine(place(p1), place(p2), rand, Math.min(1, s * 0.02), s * 0.06);
662
+ return { points: [...short, ...long.slice(1)].map(round), pressure: [0.5, 0.95, 0.9, 0.7, 0.35] };
663
+ }
664
+
433
665
  export {
434
666
  PLATFORMS,
435
667
  detectPlatform,
@@ -448,5 +680,16 @@ export {
448
680
  toShortcutBindings,
449
681
  ShortcutMap,
450
682
  DEFAULT_ARRANGE_SHORTCUTS,
451
- matchArrangeShortcut
683
+ matchArrangeShortcut,
684
+ gestureRandom,
685
+ gestureSeed,
686
+ gestureUnion,
687
+ circleGesture,
688
+ underlineGesture,
689
+ gestureEdgePoint,
690
+ arrowGesture,
691
+ bracketGesture,
692
+ strikeGesture,
693
+ crossGesture,
694
+ checkGesture
452
695
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseSkillFrontmatter
3
- } from "./chunk-SAN4SBBS.js";
3
+ } from "./chunk-ABHOYBZD.js";
4
4
  import {
5
5
  readingTime
6
6
  } from "./chunk-EHTX34RE.js";
@@ -806,6 +806,17 @@ function summarize(description, max = 200) {
806
806
  }
807
807
  var COMMON_VERBS = /* @__PURE__ */ new Set(["add", "set", "get", "remove", "list", "update", "change", "make", "create", "delete", "read", "show", "put", "use", "edit"]);
808
808
  var WEIGHTS = { name: 4, title: 2.5, toolset: 1.5, description: 1, params: 0.5 };
809
+ var tokenCache = /* @__PURE__ */ new Map();
810
+ var TOKEN_CACHE_LIMIT = 2e4;
811
+ function tokenSet(text) {
812
+ let tokens = tokenCache.get(text);
813
+ if (!tokens) {
814
+ if (tokenCache.size >= TOKEN_CACHE_LIMIT) tokenCache.clear();
815
+ tokens = new Set(searchTokens(text));
816
+ tokenCache.set(text, tokens);
817
+ }
818
+ return tokens;
819
+ }
809
820
  function paramText(schema, depth = 0) {
810
821
  if (!schema || typeof schema !== "object" || depth > 2) return "";
811
822
  const s = schema;
@@ -817,17 +828,24 @@ function paramText(schema, depth = 0) {
817
828
  if (Array.isArray(s.anyOf)) for (const branch of s.anyOf) parts.push(paramText(branch, depth + 1));
818
829
  return parts.join(" ");
819
830
  }
820
- function document(tool, toolset) {
831
+ var schemaTextCache = /* @__PURE__ */ new WeakMap();
832
+ function schemaText(schema) {
833
+ let text = schemaTextCache.get(schema);
834
+ if (text === void 0) {
835
+ text = paramText(schema);
836
+ schemaTextCache.set(schema, text);
837
+ }
838
+ return text;
839
+ }
840
+ function document(tool, toolset, toolsetTokens) {
821
841
  const fields = {
822
- name: new Set(searchTokens(baseToolName(tool.name))),
823
- title: new Set(searchTokens(_nullishCoalesce(_nullishCoalesce(tool.title, () => ( _optionalChain([tool, 'access', _22 => _22.annotations, 'optionalAccess', _23 => _23.title]))), () => ( "")))),
824
- toolset: new Set(searchTokens(`${toolset.name} ${_nullishCoalesce(toolset.title, () => ( ""))} ${_nullishCoalesce(toolset.description, () => ( ""))}`)),
825
- description: new Set(searchTokens(_nullishCoalesce(tool.description, () => ( "")))),
826
- params: new Set(searchTokens(paramText(tool.inputSchema)))
842
+ name: tokenSet(baseToolName(tool.name)),
843
+ title: tokenSet(_nullishCoalesce(_nullishCoalesce(tool.title, () => ( _optionalChain([tool, 'access', _22 => _22.annotations, 'optionalAccess', _23 => _23.title]))), () => ( ""))),
844
+ toolset: toolsetTokens,
845
+ description: tokenSet(_nullishCoalesce(tool.description, () => ( ""))),
846
+ params: tokenSet(schemaText(tool.inputSchema))
827
847
  };
828
- const all = /* @__PURE__ */ new Set();
829
- for (const set of Object.values(fields)) for (const t of set) all.add(t);
830
- return { tool, toolset, fields, all };
848
+ return { tool, toolset, fields };
831
849
  }
832
850
  function matchValue(tokens, word, alternatives, idf) {
833
851
  const rarity = _nullishCoalesce(idf.get(word), () => ( 1));
@@ -849,18 +867,25 @@ function matchValue(tokens, word, alternatives, idf) {
849
867
  function searchTools(tools, toolsets, query, options = {}) {
850
868
  const setOf = /* @__PURE__ */ new Map();
851
869
  for (const set of toolsets) for (const name of set.tools) setOf.set(name, set);
852
- const docs = tools.flatMap((tool) => {
870
+ const setTokens = /* @__PURE__ */ new Map();
871
+ const all = tools.map((tool) => {
853
872
  const set = _nullishCoalesce(setOf.get(tool.name), () => ( { name: "", providers: [], tools: [tool.name] }));
854
- return !options.toolset || set.name === options.toolset ? [document(tool, set)] : [];
873
+ let tokens = setTokens.get(set);
874
+ if (!tokens) {
875
+ tokens = tokenSet(`${set.name} ${_nullishCoalesce(set.title, () => ( ""))} ${_nullishCoalesce(set.description, () => ( ""))}`);
876
+ setTokens.set(set, tokens);
877
+ }
878
+ return document(tool, set, tokens);
855
879
  });
880
+ const docs = options.toolset ? all.filter((d) => d.toolset.name === options.toolset) : all;
856
881
  const words = Array.from(new Set(searchTokens(query)));
857
882
  if (words.length === 0 || docs.length === 0) return [];
858
883
  const alternatives = new Map(words.map((w) => [w, (_nullishCoalesce(SYNONYMS[w], () => ( []))).map(stem)]));
859
- const all = options.toolset ? tools.map((t) => document(t, _nullishCoalesce(setOf.get(t.name), () => ( { name: "", providers: [], tools: [] })))) : docs;
884
+ const fieldNames = Object.keys(WEIGHTS);
860
885
  const idf = /* @__PURE__ */ new Map();
861
886
  for (const word of [...words, ...[...alternatives.values()].flat()]) {
862
887
  if (idf.has(word)) continue;
863
- const df = all.filter((d) => d.all.has(word)).length;
888
+ const df = all.filter((d) => fieldNames.some((field) => d.fields[field].has(word))).length;
864
889
  idf.set(word, Math.log(1 + all.length / (1 + df)));
865
890
  }
866
891
  const phrase = query.trim().toLowerCase().replace(/\s+/g, "_");
@@ -870,7 +895,7 @@ function searchTools(tools, toolsets, query, options = {}) {
870
895
  let matched = 0;
871
896
  for (const word of words) {
872
897
  let best = 0;
873
- for (const field of Object.keys(WEIGHTS)) {
898
+ for (const field of fieldNames) {
874
899
  const weight = COMMON_VERBS.has(word) ? Math.min(WEIGHTS[field], WEIGHTS.description) : WEIGHTS[field];
875
900
  const value = matchValue(doc.fields[field], word, _nullishCoalesce(alternatives.get(word), () => ( [])), idf) * weight;
876
901
  best = Math.max(best, value);
@@ -3,7 +3,7 @@ import {
3
3
  TOOL_BRIDGE_PROTOCOL,
4
4
  ToolRegistry,
5
5
  createMcpServer
6
- } from "./chunk-SAN4SBBS.js";
6
+ } from "./chunk-ABHOYBZD.js";
7
7
 
8
8
  // src/bridge/index.ts
9
9
  import { createServer } from "http";