@pixerate/editor 0.59.0 → 0.61.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 (39) hide show
  1. package/THIRD_PARTY_NOTICES.md +2 -0
  2. package/dist/agent/index.cjs +111 -38
  3. package/dist/agent/index.cjs.map +1 -1
  4. package/dist/agent/index.d.cts +30 -2
  5. package/dist/agent/index.d.ts +30 -2
  6. package/dist/agent/index.js +96 -23
  7. package/dist/agent/index.js.map +1 -1
  8. package/dist/agent-caret-BmYhQF7L.d.cts +106 -0
  9. package/dist/agent-caret-BmYhQF7L.d.ts +106 -0
  10. package/dist/animation-editor/index.cjs +197 -82
  11. package/dist/animation-editor/index.cjs.map +1 -1
  12. package/dist/animation-editor/index.d.cts +136 -3
  13. package/dist/animation-editor/index.d.ts +136 -3
  14. package/dist/animation-editor/index.js +163 -48
  15. package/dist/animation-editor/index.js.map +1 -1
  16. package/dist/{chunk-LMUDHBWR.js → chunk-4YFMSPBU.js} +2 -2
  17. package/dist/{chunk-3I6V7PI4.cjs → chunk-7ZSU4MQZ.cjs} +45 -45
  18. package/dist/{chunk-3I6V7PI4.cjs.map → chunk-7ZSU4MQZ.cjs.map} +1 -1
  19. package/dist/{chunk-WLVZ235X.js → chunk-OK7T2LHK.js} +229 -2
  20. package/dist/chunk-OK7T2LHK.js.map +1 -0
  21. package/dist/{chunk-AHCENCU4.cjs → chunk-T4XWVPJK.cjs} +253 -26
  22. package/dist/chunk-T4XWVPJK.cjs.map +1 -0
  23. package/dist/extensions/index.cjs +27 -3
  24. package/dist/extensions/index.cjs.map +1 -1
  25. package/dist/extensions/index.d.cts +2 -1
  26. package/dist/extensions/index.d.ts +2 -1
  27. package/dist/extensions/index.js +26 -2
  28. package/dist/{index-CTCc3m3C.d.ts → index-B16wbOn_.d.ts} +1 -0
  29. package/dist/{index-BcHyG0Wq.d.cts → index-BAt14aIU.d.cts} +1 -0
  30. package/dist/index.cjs +32 -8
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +3 -2
  33. package/dist/index.d.ts +3 -2
  34. package/dist/index.js +26 -2
  35. package/dist/index.js.map +1 -1
  36. package/package.json +1 -1
  37. package/dist/chunk-AHCENCU4.cjs.map +0 -1
  38. package/dist/chunk-WLVZ235X.js.map +0 -1
  39. /package/dist/{chunk-LMUDHBWR.js.map → chunk-4YFMSPBU.js.map} +0 -0
@@ -30,6 +30,7 @@ reproduced at the end of this file. Paths are relative to each source repository
30
30
  © 2026 ArtCraft Team and the DeckCraft contributors.
31
31
 
32
32
  - `crates/geom/src/morph.rs` (`contours`: every segment as a cubic, lines with handles at thirds; `align`: contours paired in order, one without a partner meeting a point at the same place relative to the other outline's box (`place`); `turn`: a closed contour restarted at another anchor; `match_pair`: the closed side of a pair turned, open paired with closed) → `subpathToMorphContour`, `turnMorphContour` and `correspondMorphContours` in `packages/core/src/vector/blend.ts`; anchors are inserted by arc length rather than split evenly per curve, and the winding of closed shapes follows their areas (effectcraft) instead of a cost comparison; test cases re-expressed → `packages/core/tests/vector-blend.test.ts`
33
+ - `crates/anim/src/morph.rs` (`morph_pairs`: shapes paired in passes, each used once — by name, then by matching content, then by kind — and unpaired shapes faded out) → `matchMotionNodes` and the `match` command in `packages/core/src/animation-editor/match.ts` and `compile.ts`; the passes are name, then id with the groups' own ids taken out, then kind in stacking order, and paired groups pair their own parts
33
34
  - `crates/pptx/src/read/chart.rs` (DrawingML chart reading: group → type mapping, secondary value axis by axis id and position rather than file order, cached and literal data, data-label number-format precedence, point fills) → `chartFromOoxml` in `packages/core/src/chart/ooxml.ts`
34
35
 
35
36
  ## designcraft
@@ -55,6 +56,7 @@ reproduced at the end of this file. Paths are relative to each source repository
55
56
 
56
57
  © 2026 ArtCraft Team and the FigCraft contributors.
57
58
 
59
+ - `crates/ui-egui/src/present.rs` (`match_layers`: Smart Animate pairs layers by their name path, nested groups pairing their own layers, and fades out what has no partner) → `matchMotionNodes` in `packages/core/src/animation-editor/match.ts`
58
60
  - `crates/engine/src/distance.rs` (`between`, `inside`, `to_guide`, `label`) → `packages/core/src/canvas/measure.ts`
59
61
  - `crates/engine/src/measure_tests.rs` (test cases re-expressed) → `packages/core/tests/canvas-measure.test.ts`
60
62
  - `crates/engine/src/snap.rs` (`spacings` / `equal_spacing` / `spacing_guides`: centred between neighbours, repeating the gap of the pair before or after, gap labels; threshold in screen pixels divided by the zoom) → `VectorSnapTargets.snapRect` in `packages/core/src/vector/snap.ts`; its equal-spacing cases re-expressed → `packages/core/tests/vector-snap.test.ts`
@@ -63,7 +63,14 @@ var _chunkRIWPYSKUcjs = require('../chunk-RIWPYSKU.cjs');
63
63
 
64
64
 
65
65
 
66
- var _chunkAHCENCU4cjs = require('../chunk-AHCENCU4.cjs');
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+ var _chunkT4XWVPJKcjs = require('../chunk-T4XWVPJK.cjs');
67
74
 
68
75
 
69
76
  var _chunkTKPPIVW7cjs = require('../chunk-TKPPIVW7.cjs');
@@ -75,7 +82,6 @@ var _chunkCKRNELPOcjs = require('../chunk-CKRNELPO.cjs');
75
82
 
76
83
 
77
84
 
78
-
79
85
  var _chunk66IMF6ODcjs = require('../chunk-66IMF6OD.cjs');
80
86
  require('../chunk-BVP3TSLH.cjs');
81
87
  require('../chunk-IFHKKVXH.cjs');
@@ -466,7 +472,7 @@ function describe(chart, includeSpec) {
466
472
  function sparklines(doc) {
467
473
  const found = [];
468
474
  doc.descendants((node, pos) => {
469
- if (node.type.name === "sparkline") found.push({ pos, kind: node.attrs.kind, values: node.attrs.values, label: _chunkAHCENCU4cjs.sparklineLabel.call(void 0, node) });
475
+ if (node.type.name === "sparkline") found.push({ pos, kind: node.attrs.kind, values: node.attrs.values, label: _chunkT4XWVPJKcjs.sparklineLabel.call(void 0, node) });
470
476
  });
471
477
  return found;
472
478
  }
@@ -477,7 +483,7 @@ function checkPosition(editor, at) {
477
483
  function createDocumentChartTools(editor) {
478
484
  const chartType = () => editor().schema.nodes.chart;
479
485
  const findChart = (args) => {
480
- const charts = _chunkAHCENCU4cjs.getDocumentCharts.call(void 0, editor().state.doc);
486
+ const charts = _chunkT4XWVPJKcjs.getDocumentCharts.call(void 0, editor().state.doc);
481
487
  const list = charts.map((c) => `"${c.id}" at ${c.pos}`).join(", ") || "none; add one with insert_chart";
482
488
  if (args.chartId !== void 0) {
483
489
  const chart = charts.find((c) => c.id === args.chartId);
@@ -504,7 +510,7 @@ function createDocumentChartTools(editor) {
504
510
  annotations: { title: "List charts in the document", ...READ },
505
511
  handler: ({ includeSpec = false }) => {
506
512
  const doc = editor().state.doc;
507
- return { charts: _chunkAHCENCU4cjs.getDocumentCharts.call(void 0, doc).map((c) => describe(c, includeSpec)), sparklines: editor().schema.nodes.sparkline ? sparklines(doc) : [] };
513
+ return { charts: _chunkT4XWVPJKcjs.getDocumentCharts.call(void 0, doc).map((c) => describe(c, includeSpec)), sparklines: editor().schema.nodes.sparkline ? sparklines(doc) : [] };
508
514
  }
509
515
  };
510
516
  const insertChart = {
@@ -531,7 +537,7 @@ function createDocumentChartTools(editor) {
531
537
  const node = { type: "chart", attrs: { id, spec, width, ...height !== void 0 ? { height } : {} } };
532
538
  const chain = ed.chain().command(({ tr }) => (_history.closeHistory.call(void 0, tr), true));
533
539
  const ok = (at !== void 0 ? chain.insertContentAt(at, node) : chain.insertContent(node)).run();
534
- const chart = _chunkAHCENCU4cjs.getDocumentCharts.call(void 0, ed.state.doc).find((c) => c.id === id);
540
+ const chart = _chunkT4XWVPJKcjs.getDocumentCharts.call(void 0, ed.state.doc).find((c) => c.id === id);
535
541
  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.`);
536
542
  return { id: chart.id, pos: chart.pos, spec: chart.spec, width: chart.node.attrs.width, height: chart.node.attrs.height };
537
543
  }
@@ -578,8 +584,8 @@ function createDocumentChartTools(editor) {
578
584
  inputSchema: {
579
585
  type: "object",
580
586
  properties: {
581
- values: { type: "array", items: _chunkDK6QBGCScjs.VALUE, minItems: 1, maxItems: _chunkAHCENCU4cjs.MAX_SPARKLINE_VALUES, description: "Values in order (null for a gap)." },
582
- kind: { type: "string", enum: [..._chunkAHCENCU4cjs.SPARKLINE_KINDS], description: "line (default), column, or win-loss (sign only)." },
587
+ values: { type: "array", items: _chunkDK6QBGCScjs.VALUE, minItems: 1, maxItems: _chunkT4XWVPJKcjs.MAX_SPARKLINE_VALUES, description: "Values in order (null for a gap)." },
588
+ kind: { type: "string", enum: [..._chunkT4XWVPJKcjs.SPARKLINE_KINDS], description: "line (default), column, or win-loss (sign only)." },
583
589
  at: { type: "integer", minimum: 0, description: "Document position inside a paragraph (default: the selection)." },
584
590
  width: { type: "number", minimum: 4, maximum: 1e3, description: "Width in pixels (default 80)." },
585
591
  height: { type: "number", minimum: 4, maximum: 200, description: "Height in pixels (default 18)." },
@@ -598,7 +604,7 @@ function createDocumentChartTools(editor) {
598
604
  if (bad >= 0) throw new Error(`values[${bad}] ("${String(values[bad])}") is not a number; pass numbers, numeric text or null. Nothing was inserted.`);
599
605
  const pos = _nullishCoalesce(at, () => ( ed.state.selection.from));
600
606
  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}).`);
601
- const stored = _chunkAHCENCU4cjs.normalizeSparklineValues.call(void 0, parsed);
607
+ const stored = _chunkT4XWVPJKcjs.normalizeSparklineValues.call(void 0, parsed);
602
608
  ed.chain().command(({ tr }) => (_history.closeHistory.call(void 0, tr), true)).insertContentAt(pos, { type: "sparkline", attrs: { values: stored, kind, width, height, color, label } }).run();
603
609
  return { pos, kind, values: stored };
604
610
  }
@@ -611,11 +617,6 @@ function createDocumentChartTools(editor) {
611
617
 
612
618
  // src/agent/providers.ts
613
619
  var toEditor = (target) => "commands" in target ? target : target.editor;
614
- function replaceWithText(editor, from, to, text) {
615
- const { state, view } = editor;
616
- const tr = /[\r\n]/.test(text) ? state.tr.replace(from, to, _chunk66IMF6ODcjs.plainTextToSlice.call(void 0, text, state.schema)) : text ? state.tr.insertText(text, from, to) : state.tr.delete(from, to);
617
- view.dispatch(tr.scrollIntoView());
618
- }
619
620
  function selectionInfo(editor) {
620
621
  const { from, to } = editor.state.selection;
621
622
  return { from, to, text: editor.state.doc.textBetween(from, to, "\n") };
@@ -634,6 +635,71 @@ function textBlocks(editor) {
634
635
  });
635
636
  return blocks;
636
637
  }
638
+ function createTextPresence(editor, providerId, option) {
639
+ const config = option === false ? null : option === true || option === void 0 ? {} : option;
640
+ const caret = {
641
+ id: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _23 => _23.id]), () => ( providerId)),
642
+ name: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _24 => _24.name]), () => ( _chunkT4XWVPJKcjs.DEFAULT_AGENT_CARET_NAME)),
643
+ color: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _25 => _25.color]), () => ( _chunkT4XWVPJKcjs.DEFAULT_AGENT_CARET_COLOR))
644
+ };
645
+ const typing = !_optionalChain([config, 'optionalAccess', _26 => _26.typing]) ? null : config.typing === true ? {} : config.typing;
646
+ const idleMs = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _27 => _27.idleMs]), () => ( 12e3));
647
+ const changedMs = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _28 => _28.changedMs]), () => ( 1500));
648
+ let idleTimer;
649
+ let tintTimer;
650
+ const live = () => {
651
+ const ed = editor();
652
+ return config && ed && !ed.isDestroyed ? ed : null;
653
+ };
654
+ const touch = () => {
655
+ clearTimeout(idleTimer);
656
+ if (idleMs > 0) idleTimer = setTimeout(() => live() && _chunkT4XWVPJKcjs.clearAgentCaret.call(void 0, live(), caret.id), idleMs);
657
+ };
658
+ const tint = (ed, ranges) => {
659
+ clearTimeout(tintTimer);
660
+ _chunkT4XWVPJKcjs.markAgentChanges.call(void 0, ed, caret.id, ranges);
661
+ if (changedMs > 0 && ranges.length) tintTimer = setTimeout(() => live() && _chunkT4XWVPJKcjs.markAgentChanges.call(void 0, live(), caret.id, []), changedMs);
662
+ };
663
+ return {
664
+ /** Puts the caret at `head`, selecting from `anchor`. */
665
+ show(anchor, head = anchor) {
666
+ const ed = live();
667
+ if (!ed) return;
668
+ _chunkT4XWVPJKcjs.setAgentCaret.call(void 0, ed, { ...caret, from: anchor, to: head });
669
+ touch();
670
+ },
671
+ /** Shows the caret after ranges just changed by a tool, tinting them. */
672
+ changed(ranges) {
673
+ const ed = live();
674
+ if (!ed || !ranges.length) return;
675
+ const last = ranges[ranges.length - 1];
676
+ _chunkT4XWVPJKcjs.setAgentCaret.call(void 0, ed, { ...caret, from: last.to });
677
+ tint(ed, ranges);
678
+ touch();
679
+ },
680
+ /** Replaces `from..to` with literal text, typed out when typing is on. Returns the inserted range. */
681
+ async write(ed, from, to, text, signal) {
682
+ if (live() && typing) {
683
+ clearTimeout(tintTimer);
684
+ const range2 = await _chunkT4XWVPJKcjs.typeAgentText.call(void 0, ed, { ...typing, from, to, text, caret, signal });
685
+ if (changedMs > 0) tintTimer = setTimeout(() => live() && _chunkT4XWVPJKcjs.markAgentChanges.call(void 0, live(), caret.id, []), changedMs);
686
+ touch();
687
+ return range2;
688
+ }
689
+ const tr = _chunkT4XWVPJKcjs.replaceWithTextTransaction.call(void 0, ed.state, from, to, text);
690
+ const end = tr.mapping.map(to, 1);
691
+ const range = { from: Math.min(tr.mapping.map(from, -1), end), to: end };
692
+ ed.view.dispatch(tr.scrollIntoView());
693
+ if (range.from < range.to) this.changed([range]);
694
+ else this.show(range.to);
695
+ return range;
696
+ },
697
+ dispose() {
698
+ clearTimeout(idleTimer);
699
+ clearTimeout(tintTimer);
700
+ }
701
+ };
702
+ }
637
703
  var FIND_SCHEMA_PROPERTIES = {
638
704
  matchCase: { type: "boolean", description: "Case-sensitive match (default false)." },
639
705
  wholeWord: { type: "boolean", description: "Match whole words only (default false)." },
@@ -649,13 +715,14 @@ function findMatches(editor, query, args, replacement) {
649
715
  wholeWord: !!args.wholeWord,
650
716
  ...args.regex ? { regex: true } : { literal: true }
651
717
  };
652
- const result = _chunkAHCENCU4cjs.searchDocument.call(void 0, editor.state.doc, query, options, replacement !== void 0 ? { replacement } : {});
718
+ const result = _chunkT4XWVPJKcjs.searchDocument.call(void 0, editor.state.doc, query, options, replacement !== void 0 ? { replacement } : {});
653
719
  if (result.error) throw new Error(`Invalid search pattern: ${result.error.message}`);
654
720
  return { matches: result.matches, truncated: result.truncated };
655
721
  }
656
722
  function createRichTextToolProvider(target, options) {
657
723
  const editor = () => toEditor(target);
658
724
  const charts = createDocumentChartTools(editor);
725
+ const presence = createTextPresence(editor, options.id, options.presence);
659
726
  const getText = {
660
727
  name: "get_text",
661
728
  title: "Get document text",
@@ -697,7 +764,7 @@ function createRichTextToolProvider(target, options) {
697
764
  const insertText = {
698
765
  name: "insert_text",
699
766
  title: "Insert text",
700
- description: "Inserts literal text (newlines start new paragraphs) at a document position, or at the cursor when `at` is omitted.",
767
+ description: "Inserts literal text (newlines start new paragraphs) at a document position, or at the cursor when `at` is omitted. Returns the inserted `range` {from, to}.",
701
768
  inputSchema: {
702
769
  type: "object",
703
770
  properties: {
@@ -714,15 +781,15 @@ function createRichTextToolProvider(target, options) {
714
781
  idempotentHint: false,
715
782
  openWorldHint: false
716
783
  },
717
- handler: ({ text, at }) => {
784
+ handler: async ({ text, at }, { signal }) => {
718
785
  const ed = editor();
719
786
  const size = ed.state.doc.content.size;
720
787
  if (at !== void 0 && at > size) {
721
788
  throw new Error(`Position ${at} is outside the document (size ${size}).`);
722
789
  }
723
790
  const { from, to } = ed.state.selection;
724
- replaceWithText(ed, _nullishCoalesce(at, () => ( from)), _nullishCoalesce(at, () => ( to)), text);
725
- return { inserted: text.length, selection: selectionInfo(ed) };
791
+ const range = await presence.write(ed, _nullishCoalesce(at, () => ( from)), _nullishCoalesce(at, () => ( to)), text, signal);
792
+ return { inserted: text.length, range, selection: selectionInfo(ed) };
726
793
  }
727
794
  };
728
795
  const findText = {
@@ -750,6 +817,7 @@ function createRichTextToolProvider(target, options) {
750
817
  const ed = editor();
751
818
  const { doc } = ed.state;
752
819
  const { matches, truncated } = findMatches(ed, query, flags);
820
+ if (matches.length) presence.show(matches[0].from, matches[0].to);
753
821
  return {
754
822
  total: matches.length,
755
823
  truncated: truncated || matches.length > maxResults,
@@ -801,12 +869,14 @@ function createRichTextToolProvider(target, options) {
801
869
  replacement: String(replace).replace(/\r\n?|\n/g, "\r")
802
870
  }));
803
871
  const tr = ed.state.tr;
804
- const ends = _chunkAHCENCU4cjs.applyReplacements.call(void 0, tr, chosen);
872
+ const ends = _chunkT4XWVPJKcjs.applyReplacements.call(void 0, tr, chosen);
805
873
  ed.view.dispatch(tr.scrollIntoView());
874
+ const ranges = chosen.map((m, i) => ({ from: tr.mapping.map(m.from, -1), to: ends[i] }));
875
+ presence.changed(ranges.filter((r) => r.from < r.to));
806
876
  return {
807
877
  replaced: chosen.length,
808
878
  total: matches.length,
809
- ranges: chosen.map((m, i) => ({ from: tr.mapping.map(m.from, -1), to: ends[i] })),
879
+ ranges,
810
880
  selection: selectionInfo(ed)
811
881
  };
812
882
  }
@@ -814,7 +884,7 @@ function createRichTextToolProvider(target, options) {
814
884
  const replaceRange = {
815
885
  name: "replace_range",
816
886
  title: "Replace a range",
817
- description: "Replaces the content between two document positions (from get_text `blocks` or find_text) with literal text. from === to inserts; an empty text deletes.",
887
+ description: "Replaces the content between two document positions (from get_text `blocks` or find_text) with literal text. from === to inserts; an empty text deletes. Returns the new text's `range` {from, to}.",
818
888
  inputSchema: {
819
889
  type: "object",
820
890
  properties: {
@@ -832,11 +902,11 @@ function createRichTextToolProvider(target, options) {
832
902
  idempotentHint: false,
833
903
  openWorldHint: false
834
904
  },
835
- handler: ({ from, to, text }) => {
905
+ handler: async ({ from, to, text }, { signal }) => {
836
906
  const ed = editor();
837
907
  checkRange(ed, from, to);
838
- replaceWithText(ed, from, to, text);
839
- return { replaced: { from, to }, selection: selectionInfo(ed), size: ed.state.doc.content.size };
908
+ const range = await presence.write(ed, from, to, text, signal);
909
+ return { replaced: { from, to }, range, selection: selectionInfo(ed), size: ed.state.doc.content.size };
840
910
  }
841
911
  };
842
912
  const setSelection = {
@@ -864,13 +934,15 @@ function createRichTextToolProvider(target, options) {
864
934
  checkRange(ed, from, to);
865
935
  const { doc } = ed.state;
866
936
  ed.view.dispatch(ed.state.tr.setSelection(_state.TextSelection.between(doc.resolve(from), doc.resolve(to))));
867
- return { selection: selectionInfo(ed) };
937
+ const selection = selectionInfo(ed);
938
+ presence.show(selection.from, selection.to);
939
+ return { selection };
868
940
  }
869
941
  };
870
942
  const replaceSelection = {
871
943
  name: "replace_selection",
872
944
  title: "Replace selection",
873
- description: "Replaces the selected content with literal text (an empty string deletes the selection).",
945
+ description: "Replaces the selected content with literal text (an empty string deletes the selection). Returns the new text's `range` {from, to}.",
874
946
  inputSchema: {
875
947
  type: "object",
876
948
  properties: { text: { type: "string", description: "Replacement text." } },
@@ -884,11 +956,11 @@ function createRichTextToolProvider(target, options) {
884
956
  idempotentHint: false,
885
957
  openWorldHint: false
886
958
  },
887
- handler: ({ text }) => {
959
+ handler: async ({ text }, { signal }) => {
888
960
  const ed = editor();
889
961
  const { from, to } = ed.state.selection;
890
- replaceWithText(ed, from, to, text);
891
- return { replaced: { from, to }, selection: selectionInfo(ed) };
962
+ const range = await presence.write(ed, from, to, text, signal);
963
+ return { replaced: { from, to }, range, selection: selectionInfo(ed) };
892
964
  }
893
965
  };
894
966
  const editTable = {
@@ -898,7 +970,7 @@ function createRichTextToolProvider(target, options) {
898
970
  inputSchema: {
899
971
  type: "object",
900
972
  properties: {
901
- operation: { type: "string", enum: _chunkAHCENCU4cjs.TABLE_ACTIONS.map((a) => a.action), description: "Table operation." },
973
+ operation: { type: "string", enum: _chunkT4XWVPJKcjs.TABLE_ACTIONS.map((a) => a.action), description: "Table operation." },
902
974
  at: { type: "integer", minimum: 0, description: "Document position to place the cursor first (e.g. inside a cell)." },
903
975
  rows: { type: "integer", minimum: 1, maximum: 100, description: "insertTable: rows (default 3)." },
904
976
  cols: { type: "integer", minimum: 1, maximum: 50, description: "insertTable: columns (default 3)." },
@@ -928,10 +1000,10 @@ function createRichTextToolProvider(target, options) {
928
1000
  ed.view.dispatch(ed.state.tr.setSelection(_state.TextSelection.near(ed.state.doc.resolve(at))));
929
1001
  }
930
1002
  const action = operation;
931
- const state = _chunkAHCENCU4cjs.getTableActionState.call(void 0, ed, action, params);
1003
+ const state = _chunkT4XWVPJKcjs.getTableActionState.call(void 0, ed, action, params);
932
1004
  if (state !== true) throw new Error(state);
933
- _chunkAHCENCU4cjs.runTableAction.call(void 0, ed, action, params);
934
- const table = _chunkAHCENCU4cjs.getTableState.call(void 0, ed);
1005
+ _chunkT4XWVPJKcjs.runTableAction.call(void 0, ed, action, params);
1006
+ const table = _chunkT4XWVPJKcjs.getTableState.call(void 0, ed);
935
1007
  return {
936
1008
  operation,
937
1009
  table: table.inTable ? { rows: table.rows, columns: table.columns, row: table.row, column: table.column } : null,
@@ -947,7 +1019,7 @@ function createRichTextToolProvider(target, options) {
947
1019
  if (!ed || ed.isDestroyed) return [];
948
1020
  if (!ed.isEditable) return [getText, findText, ...charts.read()];
949
1021
  const tools = [getText, findText, insertText, replaceText, replaceRange, replaceSelection, setSelection];
950
- return [...tools, ..._chunkAHCENCU4cjs.isTableEnabled.call(void 0, ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
1022
+ return [...tools, ..._chunkT4XWVPJKcjs.isTableEnabled.call(void 0, ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
951
1023
  },
952
1024
  subscribe: (notify) => {
953
1025
  const ed = editor();
@@ -956,6 +1028,7 @@ function createRichTextToolProvider(target, options) {
956
1028
  return () => {
957
1029
  ed.off("update", notify);
958
1030
  ed.off("destroy", notify);
1031
+ presence.dispose();
959
1032
  };
960
1033
  }
961
1034
  };
@@ -1209,7 +1282,7 @@ function missingArgumentsMessage(name, args) {
1209
1282
  const required = _chunkK73CKYUMcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS[name][args.operation];
1210
1283
  if (!required) return `Unknown operation "${args.operation}".`;
1211
1284
  const missing = required.filter(
1212
- (key) => key === "id" ? args.id === void 0 && _optionalChain([args, 'access', _23 => _23.node, 'optionalAccess', _24 => _24.id]) === void 0 : args[key] === void 0
1285
+ (key) => key === "id" ? args.id === void 0 && _optionalChain([args, 'access', _29 => _29.node, 'optionalAccess', _30 => _30.id]) === void 0 : args[key] === void 0
1213
1286
  );
1214
1287
  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).`;
1215
1288
  }
@@ -1241,8 +1314,8 @@ function createEditorMcpToolProvider(options) {
1241
1314
  await options.applySteps(steps);
1242
1315
  return describeSteps(steps);
1243
1316
  };
1244
- const canvas = _nullishCoalesce(_optionalChain([options, 'access', _25 => _25.surfaces, 'optionalAccess', _26 => _26.canvas]), () => ( true));
1245
- const prompt = _nullishCoalesce(_optionalChain([options, 'access', _27 => _27.surfaces, 'optionalAccess', _28 => _28.prompt]), () => ( true));
1317
+ const canvas = _nullishCoalesce(_optionalChain([options, 'access', _31 => _31.surfaces, 'optionalAccess', _32 => _32.canvas]), () => ( true));
1318
+ const prompt = _nullishCoalesce(_optionalChain([options, 'access', _33 => _33.surfaces, 'optionalAccess', _34 => _34.prompt]), () => ( true));
1246
1319
  const editTools = options.toolStyle === "combined" ? [...canvas ? [_chunkK73CKYUMcjs.MCP_TOOL_EDIT_CANVAS] : [], ...prompt ? [_chunkK73CKYUMcjs.MCP_TOOL_EDIT_PROMPT] : []] : [...canvas ? _chunkK73CKYUMcjs.EDITOR_CANVAS_TOOLS : [], ...prompt ? _chunkK73CKYUMcjs.EDITOR_PROMPT_TOOLS : []];
1247
1320
  const tools = [
1248
1321
  {