@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.
- package/dist/agent/index.cjs +6 -6
- package/dist/agent/index.js +4 -4
- package/dist/bridge/cli.cjs +3 -3
- package/dist/bridge/cli.js +2 -2
- package/dist/bridge/index.cjs +3 -3
- package/dist/bridge/index.js +2 -2
- package/dist/canvas/drawController.d.cts +6 -0
- package/dist/canvas/drawController.d.ts +6 -0
- package/dist/canvas/gestures.d.cts +87 -0
- package/dist/canvas/gestures.d.ts +87 -0
- package/dist/canvas/index.cjs +30 -2
- package/dist/canvas/index.d.cts +1 -0
- package/dist/canvas/index.d.ts +1 -0
- package/dist/canvas/index.js +30 -2
- package/dist/{chunk-VXLYEYP4.cjs → chunk-4I76OCVD.cjs} +2 -2
- package/dist/{chunk-SAN4SBBS.js → chunk-ABHOYBZD.js} +39 -14
- package/dist/{chunk-53GOGBTM.cjs → chunk-CHAWTXBE.cjs} +243 -39
- package/dist/{chunk-OJTZKDLJ.cjs → chunk-KBNCEZZB.cjs} +7 -7
- package/dist/{chunk-7KZ2HKKC.js → chunk-LPFQHVCO.js} +244 -1
- package/dist/{chunk-H73MSHYZ.js → chunk-QTMQ5TGA.js} +1 -1
- package/dist/{chunk-Z7BVK32C.cjs → chunk-RTPBM46F.cjs} +39 -14
- package/dist/{chunk-67JAEU53.js → chunk-SPPDMY7T.js} +1 -1
- package/dist/{chunk-4EFNS2HV.cjs → chunk-T7QSEKDY.cjs} +248 -5
- package/dist/{chunk-ZPJEH456.js → chunk-XVIK73LS.js} +206 -2
- package/dist/commands/agentTools.d.cts +14 -0
- package/dist/commands/agentTools.d.ts +14 -0
- package/dist/commands/builtins.d.cts +11 -1
- package/dist/commands/builtins.d.ts +11 -1
- package/dist/commands/index.cjs +23 -9
- package/dist/commands/index.js +17 -3
- package/dist/tools/index.cjs +3 -3
- package/dist/tools/index.js +2 -2
- package/package.json +1 -1
- package/skills/pixerate-agent-tools/SKILL.md +5 -0
- package/skills/pixerate-canvas/SKILL.md +41 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
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, () => (
|
|
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,
|
|
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 !==
|
|
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${
|
|
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:
|
|
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 =
|
|
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
|
};
|
|
@@ -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
|
-
|
|
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:
|
|
823
|
-
title:
|
|
824
|
-
toolset:
|
|
825
|
-
description:
|
|
826
|
-
params:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
|
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);
|