@pixerate/editor 0.139.1 → 0.140.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +25 -4
  2. package/dist/agent/formatTools.d.cts +15 -0
  3. package/dist/agent/formatTools.d.ts +15 -0
  4. package/dist/agent/index.cjs +397 -46
  5. package/dist/agent/index.js +365 -14
  6. package/dist/agent/providers.d.cts +5 -3
  7. package/dist/agent/providers.d.ts +5 -3
  8. package/dist/animation-editor/effect-tools.d.cts +1 -1
  9. package/dist/animation-editor/effect-tools.d.ts +1 -1
  10. package/dist/animation-editor/index.cjs +250 -116
  11. package/dist/animation-editor/index.js +228 -94
  12. package/dist/animation-editor/instructions.d.cts +1 -1
  13. package/dist/animation-editor/instructions.d.ts +1 -1
  14. package/dist/animation-editor/parse.d.cts +3 -1
  15. package/dist/animation-editor/parse.d.ts +3 -1
  16. package/dist/animation-editor/tools.d.cts +8 -3
  17. package/dist/animation-editor/tools.d.ts +8 -3
  18. package/dist/bridge/cli.cjs +3 -3
  19. package/dist/bridge/cli.js +2 -2
  20. package/dist/bridge/index.cjs +7 -3
  21. package/dist/bridge/index.d.cts +7 -0
  22. package/dist/bridge/index.d.ts +7 -0
  23. package/dist/bridge/index.js +8 -4
  24. package/dist/bridge/skills.d.cts +9 -0
  25. package/dist/bridge/skills.d.ts +9 -0
  26. package/dist/canvas/effect-tools.d.cts +1 -1
  27. package/dist/canvas/effect-tools.d.ts +1 -1
  28. package/dist/canvas/index.cjs +22 -17
  29. package/dist/canvas/index.js +8 -3
  30. package/dist/chart/file-tools.d.cts +1 -1
  31. package/dist/chart/file-tools.d.ts +1 -1
  32. package/dist/chart/index.cjs +7 -1
  33. package/dist/chart/index.js +7 -1
  34. package/dist/chart/tools.d.cts +1 -1
  35. package/dist/chart/tools.d.ts +1 -1
  36. package/dist/{chunk-BKMU3V6K.js → chunk-5ED73EC6.js} +8 -1
  37. package/dist/{chunk-VRIR53SW.js → chunk-5G3KYRER.js} +2 -1
  38. package/dist/{chunk-KHMVB3SJ.js → chunk-7KWJEYIK.js} +4 -1
  39. package/dist/{chunk-R47NQICB.cjs → chunk-HDCH35UM.cjs} +47 -10
  40. package/dist/{chunk-6NCBFBXA.js → chunk-IQ6KKXOU.js} +1 -1
  41. package/dist/{chunk-PCNCT4ZY.js → chunk-KIBEEN5K.js} +40 -3
  42. package/dist/{chunk-CZRWP6IW.cjs → chunk-N2FGYZ4Q.cjs} +8 -1
  43. package/dist/{chunk-T6Y5FV7G.cjs → chunk-RPW7YL3D.cjs} +2 -1
  44. package/dist/{chunk-3V746PF4.cjs → chunk-RUZQMYXH.cjs} +4 -1
  45. package/dist/{chunk-GUPQ5BNA.cjs → chunk-RWML7TWG.cjs} +44 -44
  46. package/dist/{chunk-HGHXGCKG.cjs → chunk-SVFEVKLF.cjs} +1 -1
  47. package/dist/{chunk-PQMADRCI.js → chunk-UOJS6PUP.js} +1 -1
  48. package/dist/{chunk-BWT4IWLK.cjs → chunk-VKF3PWKR.cjs} +7 -7
  49. package/dist/chunk-WBKLYLZE.js +1156 -0
  50. package/dist/{chunk-TBSPPVTT.js → chunk-XCK7QK5D.js} +1 -1
  51. package/dist/chunk-ZAOOIJ6I.cjs +1156 -0
  52. package/dist/commands/agentTools.d.cts +1 -1
  53. package/dist/commands/agentTools.d.ts +1 -1
  54. package/dist/commands/index.cjs +3 -0
  55. package/dist/commands/index.js +3 -0
  56. package/dist/diagram/index.cjs +3 -0
  57. package/dist/diagram/index.js +3 -0
  58. package/dist/diagram/tools.d.cts +1 -1
  59. package/dist/diagram/tools.d.ts +1 -1
  60. package/dist/effects/index.cjs +32 -32
  61. package/dist/effects/index.js +1 -1
  62. package/dist/effects/tools.d.cts +5 -1
  63. package/dist/effects/tools.d.ts +5 -1
  64. package/dist/extensions/index.cjs +3 -3
  65. package/dist/extensions/index.js +2 -2
  66. package/dist/generation/index.cjs +7 -1
  67. package/dist/generation/index.js +7 -1
  68. package/dist/image-editor/index.cjs +21 -15
  69. package/dist/image-editor/index.js +8 -2
  70. package/dist/image-editor/provider-effect-tools.d.cts +1 -1
  71. package/dist/image-editor/provider-effect-tools.d.ts +1 -1
  72. package/dist/image-editor/tools.d.cts +1 -1
  73. package/dist/image-editor/tools.d.ts +1 -1
  74. package/dist/index.cjs +8 -8
  75. package/dist/index.js +2 -2
  76. package/dist/paint-editor/effect-tools.d.cts +1 -1
  77. package/dist/paint-editor/effect-tools.d.ts +1 -1
  78. package/dist/paint-editor/index.cjs +18 -8
  79. package/dist/paint-editor/index.js +13 -3
  80. package/dist/paint-editor/tools.d.cts +1 -1
  81. package/dist/paint-editor/tools.d.ts +1 -1
  82. package/dist/tools/bridge-client.d.cts +3 -3
  83. package/dist/tools/bridge-client.d.ts +3 -3
  84. package/dist/tools/capture.d.cts +5 -1
  85. package/dist/tools/capture.d.ts +5 -1
  86. package/dist/tools/definitions.d.cts +2 -2
  87. package/dist/tools/definitions.d.ts +2 -2
  88. package/dist/tools/index.cjs +31 -5
  89. package/dist/tools/index.d.cts +3 -0
  90. package/dist/tools/index.d.ts +3 -0
  91. package/dist/tools/index.js +31 -5
  92. package/dist/tools/mcp-server.d.cts +24 -6
  93. package/dist/tools/mcp-server.d.ts +24 -6
  94. package/dist/tools/registry.d.cts +81 -6
  95. package/dist/tools/registry.d.ts +81 -6
  96. package/dist/tools/search.d.cts +30 -0
  97. package/dist/tools/search.d.ts +30 -0
  98. package/dist/tools/skills.d.cts +26 -0
  99. package/dist/tools/skills.d.ts +26 -0
  100. package/dist/tools/view.d.cts +95 -0
  101. package/dist/tools/view.d.ts +95 -0
  102. package/dist/vector/effect-tools.d.cts +1 -1
  103. package/dist/vector/effect-tools.d.ts +1 -1
  104. package/dist/vector/index.cjs +13 -7
  105. package/dist/vector/index.js +8 -2
  106. package/dist/video-editor/effect-tools.d.cts +1 -1
  107. package/dist/video-editor/effect-tools.d.ts +1 -1
  108. package/dist/video-editor/index.cjs +275 -269
  109. package/dist/video-editor/index.js +8 -2
  110. package/dist/video-editor/tools.d.cts +1 -1
  111. package/dist/video-editor/tools.d.ts +1 -1
  112. package/package.json +4 -2
  113. package/skills/README.md +8 -3
  114. package/skills/pixerate-agent-tools/SKILL.md +33 -7
  115. package/skills/pixerate-animation-editor/SKILL.md +7 -0
  116. package/skills/pixerate-rich-text/SKILL.md +18 -4
  117. package/dist/chunk-5RRYDFU2.js +0 -466
  118. package/dist/chunk-SPVIXXIB.cjs +0 -466
  119. /package/dist/{chunk-SMJK5HBJ.js → chunk-MCTQXUXR.js} +0 -0
  120. /package/dist/{chunk-DDF6WQ62.cjs → chunk-R6DFK5OX.cjs} +0 -0
@@ -12,7 +12,7 @@ var _chunkGLQQ2VILcjs = require('../chunk-GLQQ2VIL.cjs');
12
12
 
13
13
  var _chunkMRD3NXKRcjs = require('../chunk-MRD3NXKR.cjs');
14
14
  require('../chunk-4EFNS2HV.cjs');
15
- require('../chunk-DDF6WQ62.cjs');
15
+ require('../chunk-R6DFK5OX.cjs');
16
16
 
17
17
 
18
18
 
@@ -25,7 +25,6 @@ require('../chunk-DDF6WQ62.cjs');
25
25
 
26
26
 
27
27
 
28
- var _chunkSPVIXXIBcjs = require('../chunk-SPVIXXIB.cjs');
29
28
 
30
29
 
31
30
 
@@ -39,6 +38,7 @@ var _chunkSPVIXXIBcjs = require('../chunk-SPVIXXIB.cjs');
39
38
 
40
39
 
41
40
 
41
+ var _chunkZAOOIJ6Icjs = require('../chunk-ZAOOIJ6I.cjs');
42
42
 
43
43
 
44
44
 
@@ -53,7 +53,6 @@ var _chunkSPVIXXIBcjs = require('../chunk-SPVIXXIB.cjs');
53
53
 
54
54
 
55
55
 
56
- var _chunkHGHXGCKGcjs = require('../chunk-HGHXGCKG.cjs');
57
56
 
58
57
 
59
58
 
@@ -62,12 +61,12 @@ var _chunkHGHXGCKGcjs = require('../chunk-HGHXGCKG.cjs');
62
61
 
63
62
 
64
63
 
65
- var _chunkCZRWP6IWcjs = require('../chunk-CZRWP6IW.cjs');
66
64
 
67
65
 
68
66
 
69
67
 
70
68
 
69
+ var _chunkSVFEVKLFcjs = require('../chunk-SVFEVKLF.cjs');
71
70
 
72
71
 
73
72
 
@@ -76,6 +75,7 @@ var _chunkCZRWP6IWcjs = require('../chunk-CZRWP6IW.cjs');
76
75
 
77
76
 
78
77
 
78
+ var _chunkN2FGYZ4Qcjs = require('../chunk-N2FGYZ4Q.cjs');
79
79
 
80
80
 
81
81
 
@@ -83,7 +83,20 @@ var _chunkCZRWP6IWcjs = require('../chunk-CZRWP6IW.cjs');
83
83
 
84
84
 
85
85
 
86
- var _chunkT6Y5FV7Gcjs = require('../chunk-T6Y5FV7G.cjs');
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+ var _chunkRPW7YL3Dcjs = require('../chunk-RPW7YL3D.cjs');
87
100
 
88
101
 
89
102
  var _chunkXQ33O5BCcjs = require('../chunk-XQ33O5BC.cjs');
@@ -439,9 +452,10 @@ function planToolCall(name, args, snapshot, options) {
439
452
 
440
453
  // src/agent/providers.ts
441
454
  var _state = require('@tiptap/pm/state');
455
+ var _history = require('@tiptap/pm/history');
442
456
 
443
457
  // src/agent/documentChartTools.ts
444
- var _history = require('@tiptap/pm/history');
458
+
445
459
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
446
460
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
447
461
  var WRITE_IDEMPOTENT = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false };
@@ -493,7 +507,7 @@ function describe(chart, includeSpec) {
493
507
  function sparklines(doc) {
494
508
  const found = [];
495
509
  doc.descendants((node, pos) => {
496
- if (node.type.name === "sparkline") found.push({ pos, kind: node.attrs.kind, values: node.attrs.values, label: _chunkT6Y5FV7Gcjs.sparklineLabel.call(void 0, node) });
510
+ if (node.type.name === "sparkline") found.push({ pos, kind: node.attrs.kind, values: node.attrs.values, label: _chunkRPW7YL3Dcjs.sparklineLabel.call(void 0, node) });
497
511
  });
498
512
  return found;
499
513
  }
@@ -504,7 +518,7 @@ function checkPosition(editor, at) {
504
518
  function createDocumentChartTools(editor) {
505
519
  const chartType = () => editor().schema.nodes.chart;
506
520
  const findChart = (args) => {
507
- const charts = _chunkT6Y5FV7Gcjs.getDocumentCharts.call(void 0, editor().state.doc);
521
+ const charts = _chunkRPW7YL3Dcjs.getDocumentCharts.call(void 0, editor().state.doc);
508
522
  const list = charts.map((c) => `"${c.id}" at ${c.pos}`).join(", ") || "none; add one with insert_chart";
509
523
  if (args.chartId !== void 0) {
510
524
  const chart = charts.find((c) => c.id === args.chartId);
@@ -531,7 +545,7 @@ function createDocumentChartTools(editor) {
531
545
  annotations: { title: "List charts in the document", ...READ },
532
546
  handler: ({ includeSpec = false }) => {
533
547
  const doc = editor().state.doc;
534
- return { charts: _chunkT6Y5FV7Gcjs.getDocumentCharts.call(void 0, doc).map((c) => describe(c, includeSpec)), sparklines: editor().schema.nodes.sparkline ? sparklines(doc) : [] };
548
+ return { charts: _chunkRPW7YL3Dcjs.getDocumentCharts.call(void 0, doc).map((c) => describe(c, includeSpec)), sparklines: editor().schema.nodes.sparkline ? sparklines(doc) : [] };
535
549
  }
536
550
  };
537
551
  const insertChart = {
@@ -558,7 +572,7 @@ function createDocumentChartTools(editor) {
558
572
  const node = { type: "chart", attrs: { id, spec, width, ...height !== void 0 ? { height } : {} } };
559
573
  const chain = ed.chain().command(({ tr }) => (_history.closeHistory.call(void 0, tr), true));
560
574
  const ok = (at !== void 0 ? chain.insertContentAt(at, node) : chain.insertContent(node)).run();
561
- const chart = _chunkT6Y5FV7Gcjs.getDocumentCharts.call(void 0, ed.state.doc).find((c) => c.id === id);
575
+ const chart = _chunkRPW7YL3Dcjs.getDocumentCharts.call(void 0, ed.state.doc).find((c) => c.id === id);
562
576
  if (!ok || !chart) throw new Error(`A chart cannot go at ${_nullishCoalesce(at, () => ( ed.state.selection.from))}; pass a position between blocks or inside a paragraph.`);
563
577
  return { id: chart.id, pos: chart.pos, spec: chart.spec, width: chart.node.attrs.width, height: chart.node.attrs.height };
564
578
  }
@@ -605,8 +619,8 @@ function createDocumentChartTools(editor) {
605
619
  inputSchema: {
606
620
  type: "object",
607
621
  properties: {
608
- values: { type: "array", items: _chunkFLUTRPLYcjs.VALUE, minItems: 1, maxItems: _chunkT6Y5FV7Gcjs.MAX_SPARKLINE_VALUES, description: "Values in order (null for a gap)." },
609
- kind: { type: "string", enum: [..._chunkT6Y5FV7Gcjs.SPARKLINE_KINDS], description: "line (default), column, or win-loss (sign only)." },
622
+ values: { type: "array", items: _chunkFLUTRPLYcjs.VALUE, minItems: 1, maxItems: _chunkRPW7YL3Dcjs.MAX_SPARKLINE_VALUES, description: "Values in order (null for a gap)." },
623
+ kind: { type: "string", enum: [..._chunkRPW7YL3Dcjs.SPARKLINE_KINDS], description: "line (default), column, or win-loss (sign only)." },
610
624
  at: { type: "integer", minimum: 0, description: "Document position inside a paragraph (default: the selection)." },
611
625
  width: { type: "number", minimum: 4, maximum: 1e3, description: "Width in pixels (default 80)." },
612
626
  height: { type: "number", minimum: 4, maximum: 200, description: "Height in pixels (default 18)." },
@@ -625,7 +639,7 @@ function createDocumentChartTools(editor) {
625
639
  if (bad >= 0) throw new Error(`values[${bad}] ("${String(values[bad])}") is not a number; pass numbers, numeric text or null. Nothing was inserted.`);
626
640
  const pos = _nullishCoalesce(at, () => ( ed.state.selection.from));
627
641
  if (!ed.state.doc.resolve(pos).parent.inlineContent) throw new Error(`Position ${pos} is between blocks; a sparkline goes inside a paragraph (use a position from get_text {blocks: true}).`);
628
- const stored = _chunkT6Y5FV7Gcjs.normalizeSparklineValues.call(void 0, parsed);
642
+ const stored = _chunkRPW7YL3Dcjs.normalizeSparklineValues.call(void 0, parsed);
629
643
  ed.chain().command(({ tr }) => (_history.closeHistory.call(void 0, tr), true)).insertContentAt(pos, { type: "sparkline", attrs: { values: stored, kind, width, height, color, label } }).run();
630
644
  return { pos, kind, values: stored };
631
645
  }
@@ -636,6 +650,309 @@ function createDocumentChartTools(editor) {
636
650
  };
637
651
  }
638
652
 
653
+ // src/agent/formatTools.ts
654
+
655
+
656
+ var WRITE_IDEMPOTENT2 = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false };
657
+ var TOGGLE_MARKS = [
658
+ ["bold", "bold", "Bold (strong) text."],
659
+ ["italic", "italic", "Italic (emphasis)."],
660
+ ["underline", "underline", "Underlined text."],
661
+ ["strike", "strike", "Struck-through text."],
662
+ ["code", "code", "Inline code (monospace; in most schemas it removes the other marks)."],
663
+ ["subscript", "subscript", "Subscript."],
664
+ ["superscript", "superscript", "Superscript."]
665
+ ];
666
+ var BLOCK_TYPES = [
667
+ ["paragraph", "paragraph", "a plain paragraph (also takes the blocks out of lists, quotes and code blocks)"],
668
+ ["heading", "heading", "a heading of `level`"],
669
+ ["bullet_list", "bulletList", "items of a bulleted list"],
670
+ ["ordered_list", "orderedList", "items of a numbered list"],
671
+ ["task_list", "taskList", "items of a checklist"],
672
+ ["blockquote", "blockquote", "a quote"],
673
+ ["code_block", "codeBlock", "a code block (plain text: marks are dropped)"]
674
+ ];
675
+ var LIST_ITEMS = { bulletList: "listItem", orderedList: "listItem", taskList: "taskItem" };
676
+ var UNSAFE_LINK = /^\s*(javascript|data|vbscript):/i;
677
+ var RANGE_PROPERTIES = {
678
+ from: { type: "integer", minimum: 0, description: "Start document position (from find_text or get_text `blocks`). Default: the selection." },
679
+ to: { type: "integer", minimum: 0, description: "End document position. Default: the selection." }
680
+ };
681
+ function targetRange(editor, args, allowEmpty) {
682
+ if (args.from === void 0 !== (args.to === void 0)) throw new Error('Pass both "from" and "to", or neither to use the selection.');
683
+ const { from, to } = args.from === void 0 ? editor.state.selection : { from: args.from, to: args.to };
684
+ const size = editor.state.doc.content.size;
685
+ if (from > to) throw new Error(`"from" (${from}) must not be after "to" (${to}).`);
686
+ if (to > size) throw new Error(`Position ${to} is outside the document (size ${size}).`);
687
+ if (!allowEmpty && from === to) {
688
+ throw new Error('The range is empty: pass "from" and "to" around the text (find_text returns them), or select it first.');
689
+ }
690
+ return { from, to };
691
+ }
692
+ function checkEditable(editor) {
693
+ if (!editor.isEditable) throw new Error("The document is read-only, so it cannot be formatted.");
694
+ }
695
+ function selectionGuard(editor, range) {
696
+ const before = editor.state.selection;
697
+ return {
698
+ select: ({ tr }) => {
699
+ _history.closeHistory.call(void 0, tr);
700
+ tr.setSelection(_state.TextSelection.between(tr.doc.resolve(range.from), tr.doc.resolve(range.to)));
701
+ return true;
702
+ },
703
+ restore: ({ tr }) => {
704
+ const anchor = tr.mapping.map(before.anchor);
705
+ const head = tr.mapping.map(before.head);
706
+ tr.setSelection(_state.TextSelection.between(tr.doc.resolve(anchor), tr.doc.resolve(head)));
707
+ return true;
708
+ },
709
+ /** The acted-on range in the changed document. */
710
+ mapped: (tr) => ({ from: tr.mapping.map(range.from, -1), to: tr.mapping.map(range.to, 1) })
711
+ };
712
+ }
713
+ function blocksIn(doc, from, to) {
714
+ const blocks = [];
715
+ doc.nodesBetween(from, Math.max(to, from + 1), (node, pos, parent) => {
716
+ if (!node.isTextblock) return true;
717
+ const $pos = doc.resolve(pos + 1);
718
+ let wrapper;
719
+ for (let d = $pos.depth - 1; d > 0; d--) {
720
+ const name = $pos.node(d).type.name;
721
+ if (name === "bulletList" || name === "orderedList" || name === "taskList" || name === "blockquote") {
722
+ wrapper = name;
723
+ break;
724
+ }
725
+ }
726
+ blocks.push({
727
+ type: node.type.name,
728
+ from: pos + 1,
729
+ to: pos + 1 + node.content.size,
730
+ text: node.textContent,
731
+ ...node.attrs.level !== void 0 ? { level: node.attrs.level } : {},
732
+ ...node.attrs.textAlign ? { align: node.attrs.textAlign } : {},
733
+ ...wrapper ? { in: wrapper } : {},
734
+ ...parent && parent.type.name === "taskItem" ? { checked: !!parent.attrs.checked } : {}
735
+ });
736
+ return false;
737
+ });
738
+ return blocks;
739
+ }
740
+ function marksOn(doc, schema, from, to) {
741
+ const out = {};
742
+ for (const [arg, mark] of TOGGLE_MARKS) {
743
+ const type = schema.marks[mark];
744
+ if (!type) continue;
745
+ let all = true;
746
+ let any = false;
747
+ doc.nodesBetween(from, to, (node) => {
748
+ if (!node.isText) return true;
749
+ if (type.isInSet(node.marks)) any = true;
750
+ else all = false;
751
+ return false;
752
+ });
753
+ if (any) out[arg] = all ? true : "partly";
754
+ }
755
+ const attrOf = (markName, attr) => {
756
+ const values = /* @__PURE__ */ new Set();
757
+ doc.nodesBetween(from, to, (node) => {
758
+ if (!node.isText) return true;
759
+ const mark = node.marks.find((m) => m.type.name === markName);
760
+ values.add(mark ? _nullishCoalesce(mark.attrs[attr], () => ( null)) : null);
761
+ return false;
762
+ });
763
+ const [only] = values;
764
+ return values.size === 1 ? only : values.size > 1 ? "mixed" : null;
765
+ };
766
+ if (schema.marks.link) {
767
+ const href = attrOf("link", "href");
768
+ if (href !== null) out.link = href;
769
+ }
770
+ if (schema.marks.highlight) {
771
+ const color = attrOf("highlight", "color");
772
+ if (color !== null) out.highlight = color;
773
+ }
774
+ if (schema.marks.textStyle) {
775
+ const color = attrOf("textStyle", "color");
776
+ if (color !== null) out.color = color;
777
+ const size = attrOf("textStyle", "fontSize");
778
+ if (size !== null) out.fontSize = size;
779
+ }
780
+ return out;
781
+ }
782
+ function createDocumentFormatTools(editor, changed) {
783
+ const formatText = (ed) => {
784
+ const { schema } = ed;
785
+ const has = (name) => !!schema.marks[name];
786
+ const hasAttr = (mark, attr) => !!_optionalChain([schema, 'access', _23 => _23.marks, 'access', _24 => _24[mark], 'optionalAccess', _25 => _25.spec, 'access', _26 => _26.attrs, 'optionalAccess', _27 => _27[attr]]);
787
+ const properties = { ...RANGE_PROPERTIES };
788
+ for (const [arg, mark, what] of TOGGLE_MARKS) {
789
+ if (has(mark)) properties[arg] = { type: "boolean", description: `${what} true sets it, false clears it; omit to leave it.` };
790
+ }
791
+ if (has("link")) {
792
+ properties.link = {
793
+ type: ["string", "null"],
794
+ minLength: 1,
795
+ description: "Link the text to this URL (https://\u2026, mailto:\u2026), or null to remove links. Omit to leave links."
796
+ };
797
+ }
798
+ if (has("highlight")) {
799
+ properties.highlight = {
800
+ type: ["string", "null"],
801
+ minLength: 1,
802
+ maxLength: 64,
803
+ description: 'Highlight (background) colour as a CSS colour, e.g. "#fef08a" or "yellow", or null to remove it.'
804
+ };
805
+ }
806
+ if (hasAttr("textStyle", "color")) {
807
+ properties.color = { type: ["string", "null"], minLength: 1, maxLength: 64, description: "Text colour as a CSS colour, or null for the default colour." };
808
+ }
809
+ if (hasAttr("textStyle", "fontSize")) {
810
+ properties.fontSize = { type: ["string", "null"], pattern: "^\\d+(\\.\\d+)?(px|pt|em|rem|%)$", description: 'Font size with a unit, e.g. "18px" or "1.25em", or null for the default size.' };
811
+ }
812
+ const formatting = Object.keys(properties).filter((k) => k !== "from" && k !== "to");
813
+ if (formatting.length === 0) return null;
814
+ return {
815
+ name: "format_text",
816
+ title: "Format text",
817
+ description: `Sets or clears inline formatting on a range of text (or the selection): ${formatting.join(", ")}. Only the properties you pass change. Positions come from find_text or get_text \`blocks\`. One undo step; the selection is left where it was. Returns the \`range\` and the formatting now on it (\`partly\` / \`mixed\` where only some of the text has it). For headings and lists use set_block_type.`,
818
+ inputSchema: { type: "object", properties, additionalProperties: false },
819
+ annotations: { title: "Format text", ...WRITE_IDEMPOTENT2 },
820
+ handler: (args) => {
821
+ const ed2 = editor();
822
+ checkEditable(ed2);
823
+ const asked = formatting.filter((k) => args[k] !== void 0);
824
+ if (asked.length === 0) throw new Error(`Pass at least one formatting property: ${formatting.join(", ")}.`);
825
+ const range = targetRange(ed2, args, false);
826
+ if (typeof args.link === "string" && UNSAFE_LINK.test(args.link)) {
827
+ throw new Error("Links may not use javascript:, data: or vbscript: URLs. Nothing was changed.");
828
+ }
829
+ const guard = selectionGuard(ed2, range);
830
+ let tr = null;
831
+ let chain = ed2.chain().command(guard.select);
832
+ for (const [arg, mark] of TOGGLE_MARKS) {
833
+ if (args[arg] === true) chain = chain.setMark(mark);
834
+ else if (args[arg] === false) chain = chain.unsetMark(mark, { extendEmptyMarkRange: false });
835
+ }
836
+ if (args.link === null) chain = chain.unsetMark("link");
837
+ else if (typeof args.link === "string") chain = chain.setMark("link", { href: args.link.trim() });
838
+ if (args.highlight === null) chain = chain.unsetMark("highlight");
839
+ else if (typeof args.highlight === "string") chain = chain.setMark("highlight", { color: args.highlight });
840
+ const style = {};
841
+ if (args.color !== void 0) style.color = args.color;
842
+ if (args.fontSize !== void 0) style.fontSize = args.fontSize;
843
+ if (Object.keys(style).length) {
844
+ chain = chain.setMark("textStyle", style);
845
+ if (Object.values(style).includes(null)) chain = chain.removeEmptyTextStyle();
846
+ }
847
+ chain.command((props) => {
848
+ tr = props.tr;
849
+ return guard.restore(props);
850
+ }).run();
851
+ const after = tr ? guard.mapped(tr) : range;
852
+ changed([after]);
853
+ const doc = ed2.state.doc;
854
+ return { range: after, text: doc.textBetween(after.from, after.to, "\n"), formatting: marksOn(doc, ed2.schema, after.from, after.to) };
855
+ }
856
+ };
857
+ };
858
+ const blockTypes = (ed) => BLOCK_TYPES.filter(([, node]) => !!ed.schema.nodes[node] && (!LIST_ITEMS[node] || !!ed.schema.nodes[LIST_ITEMS[node]]));
859
+ const headingLevels = (ed) => {
860
+ const ext = ed.extensionManager.extensions.find((e) => e.name === "heading");
861
+ return _nullishCoalesce(_optionalChain([ext, 'optionalAccess', _28 => _28.options, 'optionalAccess', _29 => _29.levels]), () => ( [1, 2, 3, 4, 5, 6]));
862
+ };
863
+ const setBlockType = (ed) => {
864
+ const types = blockTypes(ed);
865
+ if (types.length < 2) return null;
866
+ const levels = ed.schema.nodes.heading ? headingLevels(ed) : [];
867
+ return {
868
+ name: "set_block_type",
869
+ title: "Set the block type",
870
+ description: "Turns every paragraph the range touches (or the one at the cursor) into " + types.map(([value, , what]) => `${value} (${what})`).join(", ") + ". The blocks are first taken out of any list, quote or code block, so one call switches between kinds. One undo step; the selection is left where it was. Returns the resulting `blocks` with their type, positions, text, level, alignment and the list or quote they are in.",
871
+ inputSchema: {
872
+ type: "object",
873
+ properties: {
874
+ ...RANGE_PROPERTIES,
875
+ type: { type: "string", enum: types.map(([value]) => value), description: "What the blocks become." },
876
+ ...levels.length ? { level: { type: "integer", enum: levels, description: `Heading level for type "heading" (${levels.join(", ")}; 1 is the largest).` } } : {}
877
+ },
878
+ required: ["type"],
879
+ additionalProperties: false
880
+ },
881
+ annotations: { title: "Set the block type", ...WRITE_IDEMPOTENT2 },
882
+ handler: (args) => {
883
+ const ed2 = editor();
884
+ checkEditable(ed2);
885
+ const type = args.type;
886
+ if (type === "heading" && args.level === void 0) throw new Error(`Pass a heading "level" (${levels.join(", ")}).`);
887
+ if (type !== "heading" && args.level !== void 0) throw new Error('"level" only applies to type "heading".');
888
+ const range = targetRange(ed2, args, true);
889
+ const node = BLOCK_TYPES.find(([value]) => value === type)[1];
890
+ const guard = selectionGuard(ed2, range);
891
+ let tr = null;
892
+ let chain = ed2.chain().command(guard.select).clearNodes();
893
+ if (type === "heading") chain = chain.setNode("heading", { level: args.level });
894
+ else if (type === "code_block") chain = chain.setNode("codeBlock");
895
+ else if (type === "blockquote") chain = chain.wrapIn("blockquote");
896
+ else if (LIST_ITEMS[node]) chain = chain.toggleList(node, LIST_ITEMS[node]);
897
+ const ok = chain.command((props) => {
898
+ tr = props.tr;
899
+ return guard.restore(props);
900
+ }).run();
901
+ if (!ok || !tr) throw new Error(`Those blocks cannot become ${type} here (for example inside a table cell or a code block). Nothing was changed.`);
902
+ const after = guard.mapped(tr);
903
+ changed([after]);
904
+ return { type, range: after, blocks: blocksIn(ed2.state.doc, after.from, after.to) };
905
+ }
906
+ };
907
+ };
908
+ const setTextAlign = (ed) => {
909
+ const ext = ed.extensionManager.extensions.find((e) => e.name === "textAlign");
910
+ if (!ext) return null;
911
+ const alignments = (_nullishCoalesce(_optionalChain([ext, 'access', _30 => _30.options, 'optionalAccess', _31 => _31.alignments]), () => ( ["left", "center", "right", "justify"]))).slice();
912
+ const types = _nullishCoalesce(_optionalChain([ext, 'access', _32 => _32.options, 'optionalAccess', _33 => _33.types]), () => ( ["heading", "paragraph"]));
913
+ return {
914
+ name: "set_text_align",
915
+ title: "Align text",
916
+ description: `Aligns every ${types.join(" and ")} the range touches (or the one at the cursor): ${alignments.join(", ")}, or null for the default. One undo step; the selection is left where it was. Returns the resulting \`blocks\` with their alignment.`,
917
+ inputSchema: {
918
+ type: "object",
919
+ properties: {
920
+ ...RANGE_PROPERTIES,
921
+ align: { type: ["string", "null"], enum: [...alignments, null], description: "The alignment, or null for the default (usually left)." }
922
+ },
923
+ required: ["align"],
924
+ additionalProperties: false
925
+ },
926
+ annotations: { title: "Align text", ...WRITE_IDEMPOTENT2 },
927
+ handler: (args) => {
928
+ const ed2 = editor();
929
+ checkEditable(ed2);
930
+ const range = targetRange(ed2, args, true);
931
+ const blocks = blocksIn(ed2.state.doc, range.from, range.to);
932
+ if (!blocks.some((b) => types.includes(b.type))) {
933
+ throw new Error(`Only ${types.join(" and ")} blocks can be aligned; the range has ${[...new Set(blocks.map((b) => b.type))].join(", ") || "no text blocks"}.`);
934
+ }
935
+ const guard = selectionGuard(ed2, range);
936
+ let tr = null;
937
+ const chain = ed2.chain().command(guard.select);
938
+ (args.align === null ? chain.unsetTextAlign() : chain.setTextAlign(args.align)).command((props) => {
939
+ tr = props.tr;
940
+ return guard.restore(props);
941
+ }).run();
942
+ const after = tr ? guard.mapped(tr) : range;
943
+ changed([after]);
944
+ return { align: args.align, range: after, blocks: blocksIn(ed2.state.doc, after.from, after.to) };
945
+ }
946
+ };
947
+ };
948
+ return {
949
+ /** The formatting tools this editor's schema supports. */
950
+ tools(ed) {
951
+ return [formatText(ed), setBlockType(ed), setTextAlign(ed)].filter((t) => t !== null);
952
+ }
953
+ };
954
+ }
955
+
639
956
  // src/agent/providers.ts
640
957
  var toEditor = (target) => "commands" in target ? target : target.editor;
641
958
  function selectionInfo(editor) {
@@ -659,13 +976,13 @@ function textBlocks(editor) {
659
976
  function createTextPresence(editor, providerId, option) {
660
977
  const config = option === false ? null : option === true || option === void 0 ? {} : option;
661
978
  const caret = {
662
- id: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _23 => _23.id]), () => ( providerId)),
663
- name: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _24 => _24.name]), () => ( _chunkT6Y5FV7Gcjs.DEFAULT_AGENT_CARET_NAME)),
664
- color: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _25 => _25.color]), () => ( _chunkT6Y5FV7Gcjs.DEFAULT_AGENT_CARET_COLOR))
979
+ id: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _34 => _34.id]), () => ( providerId)),
980
+ name: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _35 => _35.name]), () => ( _chunkRPW7YL3Dcjs.DEFAULT_AGENT_CARET_NAME)),
981
+ color: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _36 => _36.color]), () => ( _chunkRPW7YL3Dcjs.DEFAULT_AGENT_CARET_COLOR))
665
982
  };
666
- const typing = !_optionalChain([config, 'optionalAccess', _26 => _26.typing]) ? null : config.typing === true ? {} : config.typing;
667
- const idleMs = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _27 => _27.idleMs]), () => ( 12e3));
668
- const changedMs = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _28 => _28.changedMs]), () => ( 1500));
983
+ const typing = !_optionalChain([config, 'optionalAccess', _37 => _37.typing]) ? null : config.typing === true ? {} : config.typing;
984
+ const idleMs = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _38 => _38.idleMs]), () => ( 12e3));
985
+ const changedMs = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _39 => _39.changedMs]), () => ( 1500));
669
986
  let idleTimer;
670
987
  let tintTimer;
671
988
  const live = () => {
@@ -674,19 +991,19 @@ function createTextPresence(editor, providerId, option) {
674
991
  };
675
992
  const touch = () => {
676
993
  clearTimeout(idleTimer);
677
- if (idleMs > 0) idleTimer = setTimeout(() => live() && _chunkT6Y5FV7Gcjs.clearAgentCaret.call(void 0, live(), caret.id), idleMs);
994
+ if (idleMs > 0) idleTimer = setTimeout(() => live() && _chunkRPW7YL3Dcjs.clearAgentCaret.call(void 0, live(), caret.id), idleMs);
678
995
  };
679
996
  const tint = (ed, ranges) => {
680
997
  clearTimeout(tintTimer);
681
- _chunkT6Y5FV7Gcjs.markAgentChanges.call(void 0, ed, caret.id, ranges);
682
- if (changedMs > 0 && ranges.length) tintTimer = setTimeout(() => live() && _chunkT6Y5FV7Gcjs.markAgentChanges.call(void 0, live(), caret.id, []), changedMs);
998
+ _chunkRPW7YL3Dcjs.markAgentChanges.call(void 0, ed, caret.id, ranges);
999
+ if (changedMs > 0 && ranges.length) tintTimer = setTimeout(() => live() && _chunkRPW7YL3Dcjs.markAgentChanges.call(void 0, live(), caret.id, []), changedMs);
683
1000
  };
684
1001
  return {
685
1002
  /** Puts the caret at `head`, selecting from `anchor`. */
686
1003
  show(anchor, head = anchor) {
687
1004
  const ed = live();
688
1005
  if (!ed) return;
689
- _chunkT6Y5FV7Gcjs.setAgentCaret.call(void 0, ed, { ...caret, from: anchor, to: head });
1006
+ _chunkRPW7YL3Dcjs.setAgentCaret.call(void 0, ed, { ...caret, from: anchor, to: head });
690
1007
  touch();
691
1008
  },
692
1009
  /** Shows the caret after ranges just changed by a tool, tinting them. */
@@ -694,7 +1011,7 @@ function createTextPresence(editor, providerId, option) {
694
1011
  const ed = live();
695
1012
  if (!ed || !ranges.length) return;
696
1013
  const last = ranges[ranges.length - 1];
697
- _chunkT6Y5FV7Gcjs.setAgentCaret.call(void 0, ed, { ...caret, from: last.to });
1014
+ _chunkRPW7YL3Dcjs.setAgentCaret.call(void 0, ed, { ...caret, from: last.to });
698
1015
  tint(ed, ranges);
699
1016
  touch();
700
1017
  },
@@ -702,12 +1019,12 @@ function createTextPresence(editor, providerId, option) {
702
1019
  async write(ed, from, to, text, signal) {
703
1020
  if (live() && typing) {
704
1021
  clearTimeout(tintTimer);
705
- const range2 = await _chunkT6Y5FV7Gcjs.typeAgentText.call(void 0, ed, { ...typing, from, to, text, caret, signal });
706
- if (changedMs > 0) tintTimer = setTimeout(() => live() && _chunkT6Y5FV7Gcjs.markAgentChanges.call(void 0, live(), caret.id, []), changedMs);
1022
+ const range2 = await _chunkRPW7YL3Dcjs.typeAgentText.call(void 0, ed, { ...typing, from, to, text, caret, signal });
1023
+ if (changedMs > 0) tintTimer = setTimeout(() => live() && _chunkRPW7YL3Dcjs.markAgentChanges.call(void 0, live(), caret.id, []), changedMs);
707
1024
  touch();
708
1025
  return range2;
709
1026
  }
710
- const tr = _chunkT6Y5FV7Gcjs.replaceWithTextTransaction.call(void 0, ed.state, from, to, text);
1027
+ const tr = _history.closeHistory.call(void 0, _chunkRPW7YL3Dcjs.replaceWithTextTransaction.call(void 0, ed.state, from, to, text));
711
1028
  const end = tr.mapping.map(to, 1);
712
1029
  const range = { from: Math.min(tr.mapping.map(from, -1), end), to: end };
713
1030
  ed.view.dispatch(tr.scrollIntoView());
@@ -736,7 +1053,7 @@ function findMatches(editor, query, args, replacement) {
736
1053
  wholeWord: !!args.wholeWord,
737
1054
  ...args.regex ? { regex: true } : { literal: true }
738
1055
  };
739
- const result = _chunkT6Y5FV7Gcjs.searchDocument.call(void 0, editor.state.doc, query, options, replacement !== void 0 ? { replacement } : {});
1056
+ const result = _chunkRPW7YL3Dcjs.searchDocument.call(void 0, editor.state.doc, query, options, replacement !== void 0 ? { replacement } : {});
740
1057
  if (result.error) throw new Error(`Invalid search pattern: ${result.error.message}`);
741
1058
  return { matches: result.matches, truncated: result.truncated };
742
1059
  }
@@ -744,6 +1061,7 @@ function createRichTextToolProvider(target, options) {
744
1061
  const editor = () => toEditor(target);
745
1062
  const charts = createDocumentChartTools(editor);
746
1063
  const presence = createTextPresence(editor, options.id, options.presence);
1064
+ const formatting = createDocumentFormatTools(editor, (ranges) => presence.changed(ranges.filter((r) => r.from < r.to)));
747
1065
  const getText = {
748
1066
  name: "get_text",
749
1067
  title: "Get document text",
@@ -889,8 +1207,8 @@ function createRichTextToolProvider(target, options) {
889
1207
  ...m,
890
1208
  replacement: String(replace).replace(/\r\n?|\n/g, "\r")
891
1209
  }));
892
- const tr = ed.state.tr;
893
- const ends = _chunkT6Y5FV7Gcjs.applyReplacements.call(void 0, tr, chosen);
1210
+ const tr = _history.closeHistory.call(void 0, ed.state.tr);
1211
+ const ends = _chunkRPW7YL3Dcjs.applyReplacements.call(void 0, tr, chosen);
894
1212
  ed.view.dispatch(tr.scrollIntoView());
895
1213
  const ranges = chosen.map((m, i) => ({ from: tr.mapping.map(m.from, -1), to: ends[i] }));
896
1214
  presence.changed(ranges.filter((r) => r.from < r.to));
@@ -991,7 +1309,7 @@ function createRichTextToolProvider(target, options) {
991
1309
  inputSchema: {
992
1310
  type: "object",
993
1311
  properties: {
994
- operation: { type: "string", enum: _chunkT6Y5FV7Gcjs.TABLE_ACTIONS.map((a) => a.action), description: "Table operation." },
1312
+ operation: { type: "string", enum: _chunkRPW7YL3Dcjs.TABLE_ACTIONS.map((a) => a.action), description: "Table operation." },
995
1313
  at: { type: "integer", minimum: 0, description: "Document position to place the cursor first (e.g. inside a cell)." },
996
1314
  rows: { type: "integer", minimum: 1, maximum: 100, description: "insertTable: rows (default 3)." },
997
1315
  cols: { type: "integer", minimum: 1, maximum: 50, description: "insertTable: columns (default 3)." },
@@ -1021,10 +1339,10 @@ function createRichTextToolProvider(target, options) {
1021
1339
  ed.view.dispatch(ed.state.tr.setSelection(_state.TextSelection.near(ed.state.doc.resolve(at))));
1022
1340
  }
1023
1341
  const action = operation;
1024
- const state = _chunkT6Y5FV7Gcjs.getTableActionState.call(void 0, ed, action, params);
1342
+ const state = _chunkRPW7YL3Dcjs.getTableActionState.call(void 0, ed, action, params);
1025
1343
  if (state !== true) throw new Error(state);
1026
- _chunkT6Y5FV7Gcjs.runTableAction.call(void 0, ed, action, params);
1027
- const table = _chunkT6Y5FV7Gcjs.getTableState.call(void 0, ed);
1344
+ _chunkRPW7YL3Dcjs.runTableAction.call(void 0, ed, action, params);
1345
+ const table = _chunkRPW7YL3Dcjs.getTableState.call(void 0, ed);
1028
1346
  return {
1029
1347
  operation,
1030
1348
  table: table.inTable ? { rows: table.rows, columns: table.columns, row: table.row, column: table.column } : null,
@@ -1035,12 +1353,15 @@ function createRichTextToolProvider(target, options) {
1035
1353
  return {
1036
1354
  id: options.id,
1037
1355
  namespace: options.namespace,
1356
+ title: "Document",
1357
+ description: "A rich text document: read and find text, insert, replace and format it, tables, and charts in the document.",
1358
+ skill: "pixerate-rich-text",
1038
1359
  tools: () => {
1039
1360
  const ed = editor();
1040
1361
  if (!ed || ed.isDestroyed) return [];
1041
1362
  if (!ed.isEditable) return [getText, findText, ...charts.read()];
1042
- const tools = [getText, findText, insertText, replaceText, replaceRange, replaceSelection, setSelection];
1043
- return [...tools, ..._chunkT6Y5FV7Gcjs.isTableEnabled.call(void 0, ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
1363
+ const tools = [getText, findText, insertText, replaceText, replaceRange, replaceSelection, setSelection, ...formatting.tools(ed)];
1364
+ return [...tools, ..._chunkRPW7YL3Dcjs.isTableEnabled.call(void 0, ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
1044
1365
  },
1045
1366
  subscribe: (notify) => {
1046
1367
  const ed = editor();
@@ -1387,14 +1708,17 @@ function createSpreadsheetToolProvider(controller, options) {
1387
1708
  return {
1388
1709
  id: options.id,
1389
1710
  namespace: options.namespace,
1711
+ title: "Spreadsheet",
1712
+ description: "A spreadsheet: read and set cells and ranges, insert and delete rows and columns, merge and transpose.",
1713
+ skill: "pixerate-spreadsheet",
1390
1714
  tools: [getRange, setCell, setRange, insertRows, deleteRows, insertColumns, deleteColumns, mergeCells, unmergeCells, transposeRange]
1391
1715
  };
1392
1716
  }
1393
1717
  function missingArgumentsMessage(name, args) {
1394
- const required = _chunkHGHXGCKGcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS[name][args.operation];
1718
+ const required = _chunkSVFEVKLFcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS[name][args.operation];
1395
1719
  if (!required) return `Unknown operation "${args.operation}".`;
1396
1720
  const missing = required.filter(
1397
- (key) => key === "id" ? args.id === void 0 && _optionalChain([args, 'access', _29 => _29.node, 'optionalAccess', _30 => _30.id]) === void 0 : args[key] === void 0
1721
+ (key) => key === "id" ? args.id === void 0 && _optionalChain([args, 'access', _40 => _40.node, 'optionalAccess', _41 => _41.id]) === void 0 : args[key] === void 0
1398
1722
  );
1399
1723
  return missing.length ? `Operation "${args.operation}" requires ${required.join(", ")}; missing: ${missing.join(", ")}.` : `Operation "${args.operation}" has invalid arguments (expected ${required.join(", ")} with the types in the schema).`;
1400
1724
  }
@@ -1426,12 +1750,12 @@ function createEditorMcpToolProvider(options) {
1426
1750
  await options.applySteps(steps);
1427
1751
  return describeSteps(steps);
1428
1752
  };
1429
- const canvas = _nullishCoalesce(_optionalChain([options, 'access', _31 => _31.surfaces, 'optionalAccess', _32 => _32.canvas]), () => ( true));
1430
- const prompt = _nullishCoalesce(_optionalChain([options, 'access', _33 => _33.surfaces, 'optionalAccess', _34 => _34.prompt]), () => ( true));
1431
- const editTools = options.toolStyle === "combined" ? [...canvas ? [_chunkHGHXGCKGcjs.MCP_TOOL_EDIT_CANVAS] : [], ...prompt ? [_chunkHGHXGCKGcjs.MCP_TOOL_EDIT_PROMPT] : []] : [...canvas ? _chunkHGHXGCKGcjs.EDITOR_CANVAS_TOOLS : [], ...prompt ? _chunkHGHXGCKGcjs.EDITOR_PROMPT_TOOLS : []];
1753
+ const canvas = _nullishCoalesce(_optionalChain([options, 'access', _42 => _42.surfaces, 'optionalAccess', _43 => _43.canvas]), () => ( true));
1754
+ const prompt = _nullishCoalesce(_optionalChain([options, 'access', _44 => _44.surfaces, 'optionalAccess', _45 => _45.prompt]), () => ( true));
1755
+ const editTools = options.toolStyle === "combined" ? [...canvas ? [_chunkSVFEVKLFcjs.MCP_TOOL_EDIT_CANVAS] : [], ...prompt ? [_chunkSVFEVKLFcjs.MCP_TOOL_EDIT_PROMPT] : []] : [...canvas ? _chunkSVFEVKLFcjs.EDITOR_CANVAS_TOOLS : [], ...prompt ? _chunkSVFEVKLFcjs.EDITOR_PROMPT_TOOLS : []];
1432
1756
  const tools = [
1433
1757
  {
1434
- ..._chunkHGHXGCKGcjs.MCP_TOOL_GET_EDITOR_STATE,
1758
+ ..._chunkSVFEVKLFcjs.MCP_TOOL_GET_EDITOR_STATE,
1435
1759
  handler: ({ includeDocument = true, includeCanvas = true }) => {
1436
1760
  const snapshot = options.getSnapshot();
1437
1761
  return {
@@ -1445,14 +1769,21 @@ function createEditorMcpToolProvider(options) {
1445
1769
  if (options.captureView) {
1446
1770
  const capture = options.captureView;
1447
1771
  tools.push({
1448
- ..._chunkHGHXGCKGcjs.MCP_TOOL_VIEW_EDITOR,
1772
+ ..._chunkSVFEVKLFcjs.MCP_TOOL_VIEW_EDITOR,
1449
1773
  handler: async (args) => {
1450
1774
  const image = await capture(args);
1451
1775
  return { content: [{ type: "image", data: image.data, mimeType: image.mimeType }] };
1452
1776
  }
1453
1777
  });
1454
1778
  }
1455
- return { id: options.id, namespace: options.namespace, tools };
1779
+ return {
1780
+ id: options.id,
1781
+ namespace: options.namespace,
1782
+ title: "Canvas and prompt editor",
1783
+ description: "The node canvas and the prompt: editor state, nodes and edges, layout, prompt text, and a view of the editor.",
1784
+ skill: "pixerate-canvas",
1785
+ tools
1786
+ };
1456
1787
  }
1457
1788
 
1458
1789
  // src/agent/componentTools.ts
@@ -1648,7 +1979,14 @@ function createCanvasComponentToolProvider(controller, options = { id: "canvas-c
1648
1979
  )
1649
1980
  );
1650
1981
  }
1651
- return { id: options.id, namespace: options.namespace, tools };
1982
+ return {
1983
+ id: options.id,
1984
+ namespace: options.namespace,
1985
+ title: "Canvas components",
1986
+ description: "Reusable canvas components: define them, place instances, manage variants and overrides.",
1987
+ skill: "pixerate-canvas",
1988
+ tools
1989
+ };
1652
1990
  }
1653
1991
 
1654
1992
 
@@ -1706,4 +2044,17 @@ function createCanvasComponentToolProvider(controller, options = { id: "canvas-c
1706
2044
 
1707
2045
 
1708
2046
 
1709
- exports.CAPTURE_EXCLUDE_SELECTOR = _chunkHGHXGCKGcjs.CAPTURE_EXCLUDE_SELECTOR; exports.CAPTURE_OVERLAY_SELECTORS = _chunkHGHXGCKGcjs.CAPTURE_OVERLAY_SELECTORS; exports.EDITOR_CANVAS_TOOLS = _chunkHGHXGCKGcjs.EDITOR_CANVAS_TOOLS; exports.EDITOR_MCP_TOOLS = _chunkHGHXGCKGcjs.EDITOR_MCP_TOOLS; exports.EDITOR_PROMPT_TOOLS = _chunkHGHXGCKGcjs.EDITOR_PROMPT_TOOLS; exports.EDIT_OPERATION_REQUIRED_ARGUMENTS = _chunkHGHXGCKGcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS; exports.EXPORT_EXCLUDED_SELECTORS = _chunkHGHXGCKGcjs.EXPORT_EXCLUDED_SELECTORS; exports.JSON_RPC_ERRORS = _chunkSPVIXXIBcjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkSPVIXXIBcjs.MCP_PROTOCOL_VERSIONS; exports.MCP_TOOL_CANVAS_ADD_NODE = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_ADD_NODE; exports.MCP_TOOL_CANVAS_CONNECT = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_CONNECT; exports.MCP_TOOL_CANVAS_HIGHLIGHT = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_HIGHLIGHT; exports.MCP_TOOL_CANVAS_LAYOUT = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_LAYOUT; exports.MCP_TOOL_CANVAS_REMOVE_NODES = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_REMOVE_NODES; exports.MCP_TOOL_CANVAS_SELECT = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_SELECT; exports.MCP_TOOL_CANVAS_UPDATE_NODE = _chunkHGHXGCKGcjs.MCP_TOOL_CANVAS_UPDATE_NODE; exports.MCP_TOOL_EDIT_CANVAS = _chunkHGHXGCKGcjs.MCP_TOOL_EDIT_CANVAS; exports.MCP_TOOL_EDIT_PROMPT = _chunkHGHXGCKGcjs.MCP_TOOL_EDIT_PROMPT; exports.MCP_TOOL_GET_EDITOR_STATE = _chunkHGHXGCKGcjs.MCP_TOOL_GET_EDITOR_STATE; exports.MCP_TOOL_PROMPT_INSERT_TEXT = _chunkHGHXGCKGcjs.MCP_TOOL_PROMPT_INSERT_TEXT; exports.MCP_TOOL_PROMPT_REPLACE_RANGE = _chunkHGHXGCKGcjs.MCP_TOOL_PROMPT_REPLACE_RANGE; exports.MCP_TOOL_PROMPT_SELECT = _chunkHGHXGCKGcjs.MCP_TOOL_PROMPT_SELECT; exports.MCP_TOOL_PROMPT_SET_VARIABLE = _chunkHGHXGCKGcjs.MCP_TOOL_PROMPT_SET_VARIABLE; exports.MCP_TOOL_VIEW_EDITOR = _chunkHGHXGCKGcjs.MCP_TOOL_VIEW_EDITOR; exports.TOOL_BRIDGE_DEFAULT_PORT = _chunkSPVIXXIBcjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkSPVIXXIBcjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_NAMESPACE_SEPARATOR = _chunkSPVIXXIBcjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkSPVIXXIBcjs.ToolRegistry; exports.ToolRegistryError = _chunkSPVIXXIBcjs.ToolRegistryError; exports.captureInputSchema = _chunkCZRWP6IWcjs.captureInputSchema; exports.captureOutputSize = _chunkCZRWP6IWcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkHGHXGCKGcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkSPVIXXIBcjs.connectToolBridge; exports.createCanvasComponentToolProvider = createCanvasComponentToolProvider; exports.createCaptureTool = _chunkCZRWP6IWcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkCZRWP6IWcjs.createCaptureToolProvider; exports.createDocumentChartTools = createDocumentChartTools; exports.createEditorMcpToolProvider = createEditorMcpToolProvider; exports.createElementCaptureSurface = _chunkHGHXGCKGcjs.createElementCaptureSurface; exports.createMcpServer = _chunkSPVIXXIBcjs.createMcpServer; exports.createRichTextToolProvider = createRichTextToolProvider; exports.createSpreadsheetToolProvider = createSpreadsheetToolProvider; exports.createToolRegistry = _chunkSPVIXXIBcjs.createToolRegistry; exports.elementToSvg = _chunkHGHXGCKGcjs.elementToSvg; exports.normalizeSide = normalizeSide; exports.planAgentCommand = planAgentCommand; exports.planToolCall = planToolCall; exports.rasterizeElement = _chunkHGHXGCKGcjs.rasterizeElement; exports.resolveCaptureRequest = _chunkCZRWP6IWcjs.resolveCaptureRequest; exports.toCapturedImageData = _chunkCZRWP6IWcjs.toCapturedImageData; exports.toToolResult = _chunkSPVIXXIBcjs.toToolResult; exports.toolCallToAgentCommand = toolCallToAgentCommand; exports.unionCaptureRects = _chunkCZRWP6IWcjs.unionCaptureRects; exports.validateAgentCommand = validateAgentCommand; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;
2047
+
2048
+
2049
+
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+
2060
+ exports.CAPTURE_EXCLUDE_SELECTOR = _chunkSVFEVKLFcjs.CAPTURE_EXCLUDE_SELECTOR; exports.CAPTURE_OVERLAY_SELECTORS = _chunkSVFEVKLFcjs.CAPTURE_OVERLAY_SELECTORS; exports.EDITOR_CANVAS_TOOLS = _chunkSVFEVKLFcjs.EDITOR_CANVAS_TOOLS; exports.EDITOR_MCP_TOOLS = _chunkSVFEVKLFcjs.EDITOR_MCP_TOOLS; exports.EDITOR_PROMPT_TOOLS = _chunkSVFEVKLFcjs.EDITOR_PROMPT_TOOLS; exports.EDIT_OPERATION_REQUIRED_ARGUMENTS = _chunkSVFEVKLFcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS; exports.EXPORT_EXCLUDED_SELECTORS = _chunkSVFEVKLFcjs.EXPORT_EXCLUDED_SELECTORS; exports.JSON_RPC_ERRORS = _chunkZAOOIJ6Icjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkZAOOIJ6Icjs.MCP_PROTOCOL_VERSIONS; exports.MCP_TOOL_CANVAS_ADD_NODE = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_ADD_NODE; exports.MCP_TOOL_CANVAS_CONNECT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_CONNECT; exports.MCP_TOOL_CANVAS_HIGHLIGHT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_HIGHLIGHT; exports.MCP_TOOL_CANVAS_LAYOUT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_LAYOUT; exports.MCP_TOOL_CANVAS_REMOVE_NODES = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_REMOVE_NODES; exports.MCP_TOOL_CANVAS_SELECT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_SELECT; exports.MCP_TOOL_CANVAS_UPDATE_NODE = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_UPDATE_NODE; exports.MCP_TOOL_EDIT_CANVAS = _chunkSVFEVKLFcjs.MCP_TOOL_EDIT_CANVAS; exports.MCP_TOOL_EDIT_PROMPT = _chunkSVFEVKLFcjs.MCP_TOOL_EDIT_PROMPT; exports.MCP_TOOL_GET_EDITOR_STATE = _chunkSVFEVKLFcjs.MCP_TOOL_GET_EDITOR_STATE; exports.MCP_TOOL_PROMPT_INSERT_TEXT = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_INSERT_TEXT; exports.MCP_TOOL_PROMPT_REPLACE_RANGE = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_REPLACE_RANGE; exports.MCP_TOOL_PROMPT_SELECT = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_SELECT; exports.MCP_TOOL_PROMPT_SET_VARIABLE = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_SET_VARIABLE; exports.MCP_TOOL_VIEW_EDITOR = _chunkSVFEVKLFcjs.MCP_TOOL_VIEW_EDITOR; exports.TOOL_BRIDGE_DEFAULT_PORT = _chunkZAOOIJ6Icjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkZAOOIJ6Icjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_DISCOVERY_TOOLS = _chunkZAOOIJ6Icjs.TOOL_DISCOVERY_TOOLS; exports.TOOL_NAMESPACE_SEPARATOR = _chunkZAOOIJ6Icjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkZAOOIJ6Icjs.ToolRegistry; exports.ToolRegistryError = _chunkZAOOIJ6Icjs.ToolRegistryError; exports.ToolRegistryView = _chunkZAOOIJ6Icjs.ToolRegistryView; exports.baseToolName = _chunkZAOOIJ6Icjs.baseToolName; exports.captureInputSchema = _chunkN2FGYZ4Qcjs.captureInputSchema; exports.captureOutputSize = _chunkN2FGYZ4Qcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkSVFEVKLFcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkZAOOIJ6Icjs.connectToolBridge; exports.createCanvasComponentToolProvider = createCanvasComponentToolProvider; exports.createCaptureTool = _chunkN2FGYZ4Qcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkN2FGYZ4Qcjs.createCaptureToolProvider; exports.createDocumentChartTools = createDocumentChartTools; exports.createEditorMcpToolProvider = createEditorMcpToolProvider; exports.createElementCaptureSurface = _chunkSVFEVKLFcjs.createElementCaptureSurface; exports.createMcpServer = _chunkZAOOIJ6Icjs.createMcpServer; exports.createRichTextToolProvider = createRichTextToolProvider; exports.createSpreadsheetToolProvider = createSpreadsheetToolProvider; exports.createToolRegistry = _chunkZAOOIJ6Icjs.createToolRegistry; exports.elementToSvg = _chunkSVFEVKLFcjs.elementToSvg; exports.errorResult = _chunkZAOOIJ6Icjs.errorResult; exports.listSkills = _chunkZAOOIJ6Icjs.listSkills; exports.normalizeSide = normalizeSide; exports.parseSkillFrontmatter = _chunkZAOOIJ6Icjs.parseSkillFrontmatter; exports.planAgentCommand = planAgentCommand; exports.planToolCall = planToolCall; exports.rasterizeElement = _chunkSVFEVKLFcjs.rasterizeElement; exports.readSkillFile = _chunkZAOOIJ6Icjs.readSkillFile; exports.resolveCaptureRequest = _chunkN2FGYZ4Qcjs.resolveCaptureRequest; exports.searchTokens = _chunkZAOOIJ6Icjs.searchTokens; exports.searchTools = _chunkZAOOIJ6Icjs.searchTools; exports.summarize = _chunkZAOOIJ6Icjs.summarize; exports.toCapturedImageData = _chunkN2FGYZ4Qcjs.toCapturedImageData; exports.toToolResult = _chunkZAOOIJ6Icjs.toToolResult; exports.toolCallToAgentCommand = toolCallToAgentCommand; exports.toolsetInstructions = _chunkZAOOIJ6Icjs.toolsetInstructions; exports.toolsetName = _chunkZAOOIJ6Icjs.toolsetName; exports.unionCaptureRects = _chunkN2FGYZ4Qcjs.unionCaptureRects; exports.unknownToolMessage = _chunkZAOOIJ6Icjs.unknownToolMessage; exports.validateAgentCommand = validateAgentCommand; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;