@pixerate/editor 0.25.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +30 -0
  2. package/THIRD_PARTY_NOTICES.md +11 -0
  3. package/dist/agent/index.cjs +174 -11
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +18 -4
  6. package/dist/agent/index.d.ts +18 -4
  7. package/dist/agent/index.js +167 -4
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/{arrangeShortcuts-B8O3f8-P.d.cts → arrange-BICutYPk.d.cts} +243 -29
  10. package/dist/{arrangeShortcuts-sLlD2rSX.d.ts → arrange-BICutYPk.d.ts} +243 -29
  11. package/dist/builtins-CdPcLwwF.d.cts +176 -0
  12. package/dist/builtins-Chj6zv_O.d.ts +176 -0
  13. package/dist/canvas/index.cjs +3917 -19
  14. package/dist/canvas/index.cjs.map +1 -1
  15. package/dist/canvas/index.d.cts +1232 -7
  16. package/dist/canvas/index.d.ts +1232 -7
  17. package/dist/canvas/index.js +3916 -18
  18. package/dist/canvas/index.js.map +1 -1
  19. package/dist/chunk-3CC7OPUQ.cjs +831 -0
  20. package/dist/chunk-3CC7OPUQ.cjs.map +1 -0
  21. package/dist/{chunk-7WISYZFO.cjs → chunk-66IMF6OD.cjs} +174 -67
  22. package/dist/chunk-66IMF6OD.cjs.map +1 -0
  23. package/dist/{chunk-AL6JMGWW.cjs → chunk-CS6NZWWA.cjs} +24 -24
  24. package/dist/{chunk-AL6JMGWW.cjs.map → chunk-CS6NZWWA.cjs.map} +1 -1
  25. package/dist/{chunk-C7P22VIP.cjs → chunk-EWCOFSCQ.cjs} +17 -6
  26. package/dist/chunk-EWCOFSCQ.cjs.map +1 -0
  27. package/dist/chunk-HDYMLS3X.cjs +409 -0
  28. package/dist/chunk-HDYMLS3X.cjs.map +1 -0
  29. package/dist/{chunk-V3CHHWOE.cjs → chunk-HNDSPZ5T.cjs} +4 -4
  30. package/dist/{chunk-V3CHHWOE.cjs.map → chunk-HNDSPZ5T.cjs.map} +1 -1
  31. package/dist/{chunk-X4N4WUKB.cjs → chunk-IFHKKVXH.cjs} +150 -38
  32. package/dist/chunk-IFHKKVXH.cjs.map +1 -0
  33. package/dist/chunk-KRGXUQ2Y.js +1696 -0
  34. package/dist/chunk-KRGXUQ2Y.js.map +1 -0
  35. package/dist/{chunk-PO6A6QQH.cjs → chunk-LN2POBHT.cjs} +742 -970
  36. package/dist/chunk-LN2POBHT.cjs.map +1 -0
  37. package/dist/chunk-MR2764X2.js +831 -0
  38. package/dist/chunk-MR2764X2.js.map +1 -0
  39. package/dist/{chunk-WSQKHXW7.cjs → chunk-NQF32I6Z.cjs} +1209 -457
  40. package/dist/chunk-NQF32I6Z.cjs.map +1 -0
  41. package/dist/{chunk-NAXVVS5I.js → chunk-QJSOZFCZ.js} +2 -2
  42. package/dist/{chunk-UAKDG62Z.js → chunk-SWE3NPOU.js} +116 -4
  43. package/dist/chunk-SWE3NPOU.js.map +1 -0
  44. package/dist/chunk-TXXNBDQX.cjs +1696 -0
  45. package/dist/chunk-TXXNBDQX.cjs.map +1 -0
  46. package/dist/chunk-UBCFIABU.js +409 -0
  47. package/dist/chunk-UBCFIABU.js.map +1 -0
  48. package/dist/{chunk-ECCCYKGL.js → chunk-UKI64KUD.js} +147 -40
  49. package/dist/chunk-UKI64KUD.js.map +1 -0
  50. package/dist/{chunk-QGYDWPRM.js → chunk-WON34HKM.js} +2 -2
  51. package/dist/{chunk-RR7F5GUM.js → chunk-X7HXL2SB.js} +941 -189
  52. package/dist/chunk-X7HXL2SB.js.map +1 -0
  53. package/dist/{chunk-IXHSYOVY.js → chunk-XQFHLT53.js} +638 -866
  54. package/dist/chunk-XQFHLT53.js.map +1 -0
  55. package/dist/{chunk-FH6F67DN.js → chunk-ZRNHGAQT.js} +17 -6
  56. package/dist/{chunk-FH6F67DN.js.map → chunk-ZRNHGAQT.js.map} +1 -1
  57. package/dist/commands/index.cjs +352 -4
  58. package/dist/commands/index.cjs.map +1 -1
  59. package/dist/commands/index.d.cts +37 -108
  60. package/dist/commands/index.d.ts +37 -108
  61. package/dist/commands/index.js +351 -3
  62. package/dist/commands/index.js.map +1 -1
  63. package/dist/compare/index.cjs +3 -3
  64. package/dist/compare/index.js +2 -2
  65. package/dist/{controller-BIJiNoVs.d.cts → controller-CxXGOEmy.d.cts} +209 -13
  66. package/dist/{controller-BIJiNoVs.d.ts → controller-CxXGOEmy.d.ts} +209 -13
  67. package/dist/export/index.cjs +36 -0
  68. package/dist/export/index.cjs.map +1 -0
  69. package/dist/export/index.d.cts +243 -0
  70. package/dist/export/index.d.ts +243 -0
  71. package/dist/export/index.js +36 -0
  72. package/dist/export/index.js.map +1 -0
  73. package/dist/extensions/index.cjs +54 -6
  74. package/dist/extensions/index.cjs.map +1 -1
  75. package/dist/extensions/index.d.cts +7 -2
  76. package/dist/extensions/index.d.ts +7 -2
  77. package/dist/extensions/index.js +59 -11
  78. package/dist/{index-7a6bHTLy.d.ts → index-B273Zllk.d.ts} +211 -207
  79. package/dist/{index-Csd5qI8u.d.cts → index-jcJwmBYt.d.cts} +211 -207
  80. package/dist/index.cjs +146 -32
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.d.cts +50 -14
  83. package/dist/index.d.ts +50 -14
  84. package/dist/index.js +138 -24
  85. package/dist/index.js.map +1 -1
  86. package/dist/registry-CED5C0lA.d.cts +204 -0
  87. package/dist/registry-CED5C0lA.d.ts +204 -0
  88. package/dist/{registry-D32LpIc4.d.cts → registry-D0GADKc7.d.cts} +1 -1
  89. package/dist/{registry-evKTP4ls.d.ts → registry-DhVUZioj.d.ts} +1 -1
  90. package/dist/serializers/index.cjs +6 -4
  91. package/dist/serializers/index.cjs.map +1 -1
  92. package/dist/serializers/index.d.cts +15 -4
  93. package/dist/serializers/index.d.ts +15 -4
  94. package/dist/serializers/index.js +5 -3
  95. package/dist/spreadsheet/index.cjs +33 -3
  96. package/dist/spreadsheet/index.cjs.map +1 -1
  97. package/dist/spreadsheet/index.d.cts +106 -3
  98. package/dist/spreadsheet/index.d.ts +106 -3
  99. package/dist/spreadsheet/index.js +32 -2
  100. package/package.json +10 -1
  101. package/dist/chunk-7WISYZFO.cjs.map +0 -1
  102. package/dist/chunk-C7P22VIP.cjs.map +0 -1
  103. package/dist/chunk-ECCCYKGL.js.map +0 -1
  104. package/dist/chunk-IXHSYOVY.js.map +0 -1
  105. package/dist/chunk-PO6A6QQH.cjs.map +0 -1
  106. package/dist/chunk-RR7F5GUM.js.map +0 -1
  107. package/dist/chunk-UAKDG62Z.js.map +0 -1
  108. package/dist/chunk-WSQKHXW7.cjs.map +0 -1
  109. package/dist/chunk-X4N4WUKB.cjs.map +0 -1
  110. package/dist/types-DX4Mh4SL.d.cts +0 -217
  111. package/dist/types-DX4Mh4SL.d.ts +0 -217
  112. /package/dist/{chunk-NAXVVS5I.js.map → chunk-QJSOZFCZ.js.map} +0 -0
  113. /package/dist/{chunk-QGYDWPRM.js.map → chunk-WON34HKM.js.map} +0 -0
package/README.md CHANGED
@@ -139,6 +139,24 @@ getFindReplaceState(editor); // { open, mode, query, replacement, options, match
139
139
  - **Track changes**: tracked-deleted text is skipped (a match never spans a deletion, but word boundaries see the live text), and replacements made while tracking become tracked deletions and insertions.
140
140
  - Matches are decorated with `pixerate-find-match` and the current one also with `pixerate-find-match-current` (`matchClass` / `currentMatchClass`); style them in your CSS. `createFindReplaceCommands(editor)` returns command-registry specs (`findReplace.open`, `.next`, `.find`, `.replaceAll`, …).
141
141
 
142
+ ## Tables
143
+
144
+ `createRichTextPreset()` includes tables by default (TipTap's `table`, `tableRow`, `tableHeader`, `tableCell`): resizable columns (`colwidth`), header rows, columns and cells, `colspan` / `rowspan` (kept from pasted HTML and from DOCX / PDF import), cell `align` and `backgroundColor`, and table node selection. Configure them with `table: { resizable, cellMinWidth, allowTableNodeSelection, HTMLAttributes, ... }`, or pass `table: false` to leave tables out of the schema (pasted and imported tables are then flattened into paragraphs, as before).
145
+
146
+ ```ts
147
+ import { createTableCommands, getTableState, runTableAction, getTableActionState } from "@pixerate/editor";
148
+
149
+ runTableAction(editor, "insertTable", { rows: 3, cols: 4, withHeaderRow: true });
150
+ getTableActionState(editor, "mergeCells"); // true, or why not: "Select two or more adjacent cells to merge."
151
+ getTableState(editor); // { inTable, rows, columns, row, column, headerRow, headerColumn, headerCell, cellAlignment, actions: { … } }
152
+ registry.register(createTableCommands(editor)); // table.insertTable, table.addRowAfter, table.mergeCells, … (palette & agents)
153
+ ```
154
+
155
+ - **Actions** (`TABLE_ACTIONS`): `insertTable` (no nesting), `addRowBefore` / `addRowAfter` / `deleteRow`, `addColumnBefore` / `addColumnAfter` / `deleteColumn`, `deleteTable`, `mergeCells` / `splitCell`, `toggleHeaderRow` / `toggleHeaderColumn` / `toggleHeaderCell`, `goToNextCell` / `goToPreviousCell` (Tab / Shift+Tab), `setCellAlignment` (`{ align }`) and `setCellBackground` (`{ color }`, sanitized). `createTableStore(editor)` is the external store the React and Svelte toolbars use; `DEFAULT_TABLE_TOOLBAR` lists their buttons. `createRichTextToolProvider` adds an `edit_table` agent tool when the schema has tables.
156
+ - **Export**: `getEditorText` writes each row as a line of tab-separated cells. Markdown (`markdown: true`) writes a GFM pipe table (column alignment from the header cells, `|` escaped) when the first row is all header cells, nothing spans and every cell holds one paragraph; otherwise the table is written as HTML, which parses back. GFM tables in markdown input become tables.
157
+ - **Track changes**: edits inside cells are tracked like any text. Inserting or deleting rows, columns (their cells) or a whole table is tracked as a whole-block change (`blockChange` with `operation`): rejecting an insertion or accepting a deletion removes the rows/cells/table; deleting rows you inserted yourself removes them. Header toggles are tracked as block changes (reject restores the cell type). Cell attributes (alignment, background, widths) are not tracked, and merging or splitting cells is refused while tracking. `compareDocuments` compares tables row by row and cell by cell.
158
+ - Style the tables in your CSS (`.tableWrapper`, `table`, `th`, `td`, `.selectedCell`, `.column-resize-handle`; the table has the `pixerate-table` class).
159
+
142
160
  ## File import and rich clipboard
143
161
 
144
162
  An import adapter registry maps file types (MIME types and extensions) to converters. Built-in `document` adapters cover markdown (`.md`, `.markdown`, `.mdown`, `.mkdn`, `.mkd`, `.Rmd`, `.md.txt`), HTML (sanitized with the same allowlist as markdown), plain text (`.txt`), RTF (best-effort text extraction) and DOCX (`.docx`, `.docm`, `.dotx`). The longest matching extension wins, then exact MIME types, then `priority`, then the most recent registration.
@@ -354,6 +372,18 @@ sheet.findInvalidCells(); // "circle invalid data"
354
372
 
355
373
  `evaluateConditionalFormats(sheet, rules)` and `validateCellInput(sheet, rules, row, col, input)` also work on any grid through the small `ConditionalFormatSheet` / `DataValidationSheet` interfaces. Rule formulas are written for the top-left cell of the first range and shift for other cells; custom validation formulas see the value being entered. `setCellValue`, paste and import never validate (as in Excel); `commitEditing` and `commitCellInput` do.
356
374
 
375
+ ## Large spreadsheets: incremental recalculation and virtualised rendering
376
+
377
+ The dependency graph stores each range a formula reads once, in an interval index per column (wide ranges in a per-sheet index), instead of one key per cell, so `=SUM(A1:A50000)` and `=SUM(A:A)` are one entry each. An edit finds the formulas reading the cell in O(log n + k), recalculates only that dirty subgraph in topological order (a range read by many formulas is resolved once per recalculation), and still detects cycles, re-spills dynamic arrays, follows sheet-qualified, 3-D and defined-name references and recalculates volatile functions (`NOW`, `TODAY`, `RAND`, `RANDBETWEEN`, `RANDARRAY`) on every edit. CSV import, `loadWorkbook` and large pastes register the cells and evaluate each formula once; a single-cell edit is undone without a whole-sheet snapshot. `SUM`, `PRODUCT`, `AVERAGE`, `COUNT`, `COUNTA`, `MIN` and `MAX` read their ranges without materialising blank cells.
378
+
379
+ ```ts
380
+ sheet.setCellValue(rowId, colId, "42");
381
+ sheet.getRecalculationStats(); // { evaluated: 1, planned: 2, passes: 1 }: deterministic work counts
382
+ sheet.depGraph.getIndexStats(); // { formulas, cellEdges, rangeEntries, volatile }
383
+ ```
384
+
385
+ `measureSpreadsheetView`, `getSpreadsheetViewWindow` and `getSpreadsheetScrollToCell` work out which displayed rows and columns to render for a scroll position (frozen rows and columns always, merges crossing the edge whole) and how far to scroll to show the active cell. The React and Svelte `SpreadsheetEditor` use them for sheets with more than 200 displayed rows or 60 columns (`virtualize` prop: `'auto'`, `true` or `false`). `packages/core/tests/spreadsheet-recalc.bench.test.ts` measures 50k-cell sheets (`SPREADSHEET_BENCH=1`).
386
+
357
387
  ## Other modules
358
388
 
359
389
  Each module is also available as a subpath import:
@@ -31,6 +31,9 @@ reproduced at the end of this file. Paths are relative to each source repository
31
31
  - `crates/doc/src/lib.rs` (`modes_for`: modes inherited down the tree) → `getEffectiveTokenModes` in `packages/core/src/canvas/tokenBindings.ts`
32
32
  - `crates/engine/src/variables_io_tests.rs` (behaviour of the variables JSON import / export: merging by name, junk and loop handling, CSS export per mode) → `packages/core/src/tokens/w3c.ts`, `packages/core/src/tokens/css.ts`
33
33
  - `crates/engine/src/{variable_tests.rs,variables_behaviour_tests.rs,variables_io_tests.rs}` (test cases re-expressed) → `packages/core/tests/tokens.test.ts`, `packages/core/tests/canvas-tokens.test.ts`
34
+ - `crates/engine/src/components.rs` (instances rebuilt from their main keeping ids and overrides — `sync_instance`, `carry_overrides`, `path_map` matching, `variant_kept`, `diff_groups`, `sync_after_edit`, `rebuild_instances` ordering, `rebase_instance`, `unlink_layers`, `relink_copy`, component property chains, `default_variant`, `variant_props`, `variant_name`, `variant_options`, `find_variant`, `variant_conflicts`) → `packages/core/src/canvas/components.ts`
35
+ - `crates/engine/src/cmd/component.rs` (create component, combine as variants, create / detach / swap instance, reset instance and overrides, push changes, restore main, set instance properties, add / edit / delete / bind component properties) → `packages/core/src/canvas/components.ts`, `packages/core/src/canvas/componentsController.ts`
36
+ - `crates/engine/src/{components_tests.rs,components_behaviour_tests.rs,components_scale_tests.rs}` (test cases re-expressed) → `packages/core/tests/canvas-components.test.ts`, `packages/core/tests/canvas-components-controller.test.ts`
34
37
 
35
38
  ## filmcraft
36
39
 
@@ -44,6 +47,9 @@ reproduced at the end of this file. Paths are relative to each source repository
44
47
  - `apps/filmcraft-web/src/recovery_policy.rs` (`Policy`, `Action`, `tick` / `written` / `cleaned`: snapshot at most once per interval and revision, retry failed writes, retire only this session's snapshot) → `packages/core/src/persistence/recoveryPolicy.ts`
45
48
  - `apps/filmcraft-web/src/recovery.rs` (snapshot-then-dirty-meta writes, recovery check of a dirty meta) → `packages/core/src/persistence/autosave.ts`
46
49
  - `apps/filmcraft-web/tests/recovery_policy.rs` (test cases re-expressed) → `packages/core/tests/persistence-policy.test.ts`
50
+ - `crates/project/src/keyframe.rs` (`Keyframe`, `Param::value_at` segment evaluation and hold, `set_at` inheriting the previous interpolation, `remove_keyframe_at` keeping the last value, `toggle_animation` keeping the value at a time, temporal influence easing, `cubic_bezier_y_for_x` Newton + bisection solver) → `packages/core/src/canvas/animation/{easing,model,evaluate,edit}.ts`
51
+ - `crates/engine/src/keyframe_move.rs` (`move_many`: one common delta across lanes clamped to the movement range, remove-all-originals-then-insert, validation without partial edits, at most 4096 keys) → `moveKeyframes` / `scaleKeyframes` in `packages/core/src/canvas/animation/edit.ts`, keyframe drags in `packages/core/src/canvas/animation/controller.ts`
52
+ - `crates/project/src/keyframe.rs` tests, `crates/engine/src/keyframe_move.rs` tests and `crates/ui-egui/tests/keyframes_ui.rs` (group move and undo as one step, snapping within a screen-space threshold, Escape cancelling a drag preview; test cases re-expressed) → `packages/core/tests/canvas-animation.test.ts`, `packages/react/tests/canvas-animation.test.tsx`, `packages/svelte/tests/canvas/canvas-animation.test.ts`
47
53
 
48
54
  ## gridcraft
49
55
 
@@ -62,6 +68,8 @@ reproduced at the end of this file. Paths are relative to each source repository
62
68
  - `crates/model/src/features.rs` (conditional formatting and data validation rule model, icon-set thresholds) and `crates/engine/src/cf.rs` (rule evaluation: priority, stop if true, colour scales, data bars, icon sets, top/bottom, averages, duplicates, text and date rules, relative rule formulas) → `packages/core/src/spreadsheet/conditional-format/`
63
69
  - `crates/engine/src/cmd/data.rs` (validation checks, list items, circle invalid data, removing rule cells) and `crates/engine/src/cmd/sheet.rs` (rule ranges following inserted / deleted rows and columns) → `packages/core/src/spreadsheet/validation/`, `packages/core/src/spreadsheet/rule-ranges.ts`
64
70
  - Test cases from `crates/engine/src/cf.rs` and `crates/engine/src/tests.rs` (icon-set thresholds, relative validation formulas), re-expressed → `packages/core/tests/spreadsheet-conditional-format.test.ts`, `packages/core/tests/spreadsheet-data-validation.test.ts`
71
+ - `crates/calc/src/recalc.rs` (`Intervals`: row intervals sorted by start with an implicit max-end segment tree, pending insertions and dead entries merged lazily; ranges indexed per column with a per-sheet index for wide ranges; dependents of a cell in O(log n + k); dirty closure of an edit) → `packages/core/src/spreadsheet/formula/dependency-graph.ts`
72
+ - `crates/calc/src/tests.rs` and `crates/calc/src/recalc.rs` (interval-index and incremental-recalculation cases, re-expressed) → `packages/core/tests/spreadsheet-recalc.test.ts`
65
73
  **Apache POI.** The rows of `packages/core/tests/fixtures/poi-number-format-approx.ts` (format, value and Excel's
66
74
  `TEXT()` result) come from Apache POI's `test-data/spreadsheet/NumberFormatApproxTests.xlsx`, as collected in
67
75
  GridCraft. Apache POI is © The Apache Software Foundation, licensed under the Apache License, Version 2.0
@@ -149,6 +157,9 @@ GridCraft. Apache POI is © The Apache Software Foundation, licensed under the A
149
157
  - Test cases from `crates/engine/src/cmd/moves.rs` (`a_tracked_cut_and_paste_of_a_paragraph_is_a_move`, `accepting_one_end_of_a_move_accepts_both`, `rejecting_a_move_puts_the_text_back`), re-expressed → `packages/core/tests/track-changes-moves.test.ts`
150
158
  - `crates/doc/src/styles.rs` (`Style` with `based_on` / `next` / `linked`, the built-in style set's shape, `gallery`, `chain` (bounded, cycle-safe), `find`, `upsert`, `remove` (rebasing dependants, dropping `next` / `linked` references), `new_id`) and `crates/doc/src/resolve.rs` (cascade: document defaults → paragraph style chain → character style chain → direct formatting) → `packages/core/src/extensions/paragraph-styles/registry.ts`
151
159
  - Test cases from `crates/doc/src/styles.rs` (`builtins_present`, `chain_is_cycle_safe`, `new_ids_unique`) and `crates/doc/src/resolve.rs` (`heading_resolves`, `char_style_then_direct`), re-expressed → `packages/core/tests/paragraph-styles.test.ts`
160
+ - `crates/docx/src/write/mod.rs` (package assembly: `[Content_Types].xml` defaults and overrides, part relationships with reused ids, `comments.xml` + `commentsExtended.xml` with `w15:paraIdParent` / `w15:done`, `annotation_author` and anonymous initials for removed personal information, `core_xml` without creator / last modified by, `styles_xml` / `style_xml` with `basedOn` / `next` / `link` / `uiPriority` / `qFormat`, lower-case built-in style names, `numbering_xml`), `crates/docx/src/write/story.rs` (`rev_open` / `rev_close`, `rev_tag` moves as `w:moveFrom` / `w:moveTo`, `move_ranges` with named move ranges, `w:delText` only for deletions that are not moves, `rpr_change` / `w:pPrChange` last in their properties, comment range start / end / reference runs, `w:p` with `w14:paraId` for comments, tables with `w:tblGrid`, `w:gridSpan`, `w:vMerge`, inline `wp:inline` pictures), `crates/docx/src/write/props.rs` (run property order), `crates/docx/src/package.rs` (relationship types), `crates/docx/src/xml.rs` (`esc`, XML 1.0 character filter, writer) and `crates/docx/src/units.rs` (twips / EMU conversion) → `packages/core/src/export/docx.ts`, `packages/core/src/export/xml.ts`, `packages/core/src/export/units.ts`
161
+ - `crates/docx/src/read/mod.rs` (`read_comments`: comments keyed by the `w14:paraId` of their last paragraph, `commentEx` parents and `done`) and `crates/docx/src/read/story.rs` (tracked insertions, deletions and named move ranges) → `packages/core/src/import/docx.ts`
162
+ - Test cases from `crates/docx/tests/privacy.rs` (`remove_personal_information_and_dates_on_save`: the two-commenter fixture, no names or initials in any part, "Author" / "A"), `crates/docx/tests/roundtrip.rs` and `crates/docx/tests/fixtures.rs` (comments, replies, tracked changes and moves surviving a save and reload), re-expressed → `packages/core/tests/docx-export.test.ts`
152
163
 
153
164
  ## MIT License
154
165
 
@@ -5,14 +5,21 @@ var _chunkCPOKFNBGcjs = require('../chunk-CPOKFNBG.cjs');
5
5
 
6
6
 
7
7
 
8
- var _chunk7WISYZFOcjs = require('../chunk-7WISYZFO.cjs');
8
+
9
+
10
+ var _chunkHDYMLS3Xcjs = require('../chunk-HDYMLS3X.cjs');
11
+
12
+
13
+
14
+
15
+ var _chunk66IMF6ODcjs = require('../chunk-66IMF6OD.cjs');
9
16
  require('../chunk-BVP3TSLH.cjs');
10
- require('../chunk-X4N4WUKB.cjs');
17
+ require('../chunk-IFHKKVXH.cjs');
11
18
 
12
19
 
13
20
 
14
21
 
15
- var _chunkC7P22VIPcjs = require('../chunk-C7P22VIP.cjs');
22
+ var _chunkEWCOFSCQcjs = require('../chunk-EWCOFSCQ.cjs');
16
23
 
17
24
 
18
25
 
@@ -699,10 +706,11 @@ function createToolRegistry(options) {
699
706
  }
700
707
 
701
708
  // src/agent/providers.ts
709
+ var _state = require('@tiptap/pm/state');
702
710
  var toEditor = (target) => "commands" in target ? target : target.editor;
703
711
  function replaceWithText(editor, from, to, text) {
704
712
  const { state, view } = editor;
705
- const tr = /[\r\n]/.test(text) ? state.tr.replace(from, to, _chunk7WISYZFOcjs.plainTextToSlice.call(void 0, text, state.schema)) : text ? state.tr.insertText(text, from, to) : state.tr.delete(from, to);
713
+ 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);
706
714
  view.dispatch(tr.scrollIntoView());
707
715
  }
708
716
  function selectionInfo(editor) {
@@ -735,7 +743,7 @@ function createRichTextToolProvider(target, options) {
735
743
  },
736
744
  handler: ({ format = "text" }) => {
737
745
  const ed = editor();
738
- const content = format === "html" ? ed.getHTML() : format === "markdown" ? _chunk7WISYZFOcjs.getEditorMarkdown.call(void 0, ed) : _chunk7WISYZFOcjs.getEditorText.call(void 0, ed);
746
+ const content = format === "html" ? ed.getHTML() : format === "markdown" ? _chunk66IMF6ODcjs.getEditorMarkdown.call(void 0, ed) : _chunk66IMF6ODcjs.getEditorText.call(void 0, ed);
739
747
  return { format, content, selection: selectionInfo(ed), size: ed.state.doc.content.size };
740
748
  }
741
749
  };
@@ -794,13 +802,62 @@ function createRichTextToolProvider(target, options) {
794
802
  return { replaced: { from, to }, selection: selectionInfo(ed) };
795
803
  }
796
804
  };
805
+ const editTable = {
806
+ name: "edit_table",
807
+ title: "Edit tables",
808
+ description: "Inserts a table or edits the table at the cursor (or at `at`): add/delete rows and columns, delete the table, merge/split cells, toggle header row/column/cell, move between cells, set cell alignment or background. Returns the table size and the cursor cell afterwards.",
809
+ inputSchema: {
810
+ type: "object",
811
+ properties: {
812
+ operation: { type: "string", enum: _chunkHDYMLS3Xcjs.TABLE_ACTIONS.map((a) => a.action), description: "Table operation." },
813
+ at: { type: "integer", minimum: 0, description: "Document position to place the cursor first (e.g. inside a cell)." },
814
+ rows: { type: "integer", minimum: 1, maximum: 100, description: "insertTable: rows (default 3)." },
815
+ cols: { type: "integer", minimum: 1, maximum: 50, description: "insertTable: columns (default 3)." },
816
+ withHeaderRow: { type: "boolean", description: "insertTable: first row is a header row (default true)." },
817
+ align: {
818
+ type: ["string", "null"],
819
+ enum: ["left", "center", "right", "justify", null],
820
+ description: "setCellAlignment: alignment, or null to clear."
821
+ },
822
+ color: { type: ["string", "null"], description: "setCellBackground: CSS color, or null to clear." }
823
+ },
824
+ required: ["operation"],
825
+ additionalProperties: false
826
+ },
827
+ annotations: {
828
+ title: "Edit tables",
829
+ readOnlyHint: false,
830
+ destructiveHint: true,
831
+ idempotentHint: false,
832
+ openWorldHint: false
833
+ },
834
+ handler: ({ operation, at, ...params }) => {
835
+ const ed = editor();
836
+ if (at !== void 0) {
837
+ const size = ed.state.doc.content.size;
838
+ if (at > size) throw new Error(`Position ${at} is outside the document (size ${size}).`);
839
+ ed.view.dispatch(ed.state.tr.setSelection(_state.TextSelection.near(ed.state.doc.resolve(at))));
840
+ }
841
+ const action = operation;
842
+ const state = _chunkHDYMLS3Xcjs.getTableActionState.call(void 0, ed, action, params);
843
+ if (state !== true) throw new Error(state);
844
+ _chunkHDYMLS3Xcjs.runTableAction.call(void 0, ed, action, params);
845
+ const table = _chunkHDYMLS3Xcjs.getTableState.call(void 0, ed);
846
+ return {
847
+ operation,
848
+ table: table.inTable ? { rows: table.rows, columns: table.columns, row: table.row, column: table.column } : null,
849
+ selection: selectionInfo(ed)
850
+ };
851
+ }
852
+ };
797
853
  return {
798
854
  id: options.id,
799
855
  namespace: options.namespace,
800
856
  tools: () => {
801
857
  const ed = editor();
802
858
  if (!ed || ed.isDestroyed) return [];
803
- return ed.isEditable ? [getText, insertText, replaceSelection] : [getText];
859
+ if (!ed.isEditable) return [getText];
860
+ return _chunkHDYMLS3Xcjs.isTableEnabled.call(void 0, ed) ? [getText, insertText, replaceSelection, editTable] : [getText, insertText, replaceSelection];
804
861
  },
805
862
  subscribe: (notify) => {
806
863
  const ed = editor();
@@ -817,7 +874,7 @@ var CELL_REF_REGEX = /^\$?([A-Za-z]{1,3})\$?(\d{1,7})$/;
817
874
  function parseCell(ref) {
818
875
  const match = CELL_REF_REGEX.exec(ref.trim());
819
876
  if (!match) throw new Error(`Invalid cell reference "${ref}". Use A1 notation, e.g. "B3".`);
820
- return { col: _chunkC7P22VIPcjs.colNameToIndex.call(void 0, match[1].toUpperCase()), row: parseInt(match[2], 10) - 1 };
877
+ return { col: _chunkEWCOFSCQcjs.colNameToIndex.call(void 0, match[1].toUpperCase()), row: parseInt(match[2], 10) - 1 };
821
878
  }
822
879
  function createSpreadsheetToolProvider(controller, options) {
823
880
  const lookup = (row, col) => {
@@ -865,14 +922,14 @@ function createSpreadsheetToolProvider(controller, options) {
865
922
  const cell = controller.getCell(found.rowDef.id, found.colDef.id);
866
923
  valueRow.push(_nullishCoalesce(cell.error, () => ( cell.value)));
867
924
  rawRow.push(cell.raw);
868
- const error = _nullishCoalesce(cell.error, () => ( (_chunkC7P22VIPcjs.isFormulaError.call(void 0, cell.value) ? cell.value : void 0)));
869
- if (error) errors.push({ cell: `${_chunkC7P22VIPcjs.indexToColName.call(void 0, c)}${r + 1}`, error });
925
+ const error = _nullishCoalesce(cell.error, () => ( (_chunkEWCOFSCQcjs.isFormulaError.call(void 0, cell.value) ? cell.value : void 0)));
926
+ if (error) errors.push({ cell: `${_chunkEWCOFSCQcjs.indexToColName.call(void 0, c)}${r + 1}`, error });
870
927
  }
871
928
  values.push(valueRow);
872
929
  raw.push(rawRow);
873
930
  }
874
931
  return {
875
- range: values.length && values[0].length ? `${_chunkC7P22VIPcjs.indexToColName.call(void 0, c0)}${r0 + 1}:${_chunkC7P22VIPcjs.indexToColName.call(void 0, c1)}${r1 + 1}` : null,
932
+ range: values.length && values[0].length ? `${_chunkEWCOFSCQcjs.indexToColName.call(void 0, c0)}${r0 + 1}:${_chunkEWCOFSCQcjs.indexToColName.call(void 0, c1)}${r1 + 1}` : null,
876
933
  values,
877
934
  raw,
878
935
  errors,
@@ -951,6 +1008,112 @@ function createEditorMcpToolProvider(options) {
951
1008
  return { id: options.id, namespace: options.namespace, tools };
952
1009
  }
953
1010
 
1011
+ // src/agent/componentTools.ts
1012
+ var IDS = { type: "array", items: { type: "string" }, description: "Node ids (default: the selection)." };
1013
+ var ID = { type: "string", description: "An instance, or a layer inside one (default: the first selected node)." };
1014
+ var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
1015
+ var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
1016
+ var check = (result) => {
1017
+ if (!result.ok) throw new Error(result.reason);
1018
+ return { ids: result.ids };
1019
+ };
1020
+ function createCanvasComponentToolProvider(controller, options = { id: "canvas-components" }) {
1021
+ const tool = (name, description, properties, handler, extra = {}) => ({
1022
+ name,
1023
+ description,
1024
+ inputSchema: { type: "object", properties, ...extra.required ? { required: extra.required } : {}, additionalProperties: false },
1025
+ annotations: extra.readOnly ? READ : WRITE,
1026
+ handler
1027
+ });
1028
+ const tools = [
1029
+ tool("list_components", "Lists components (id, name, variant values, instance count) and component sets with their variant options.", {}, () => controller.list(), {
1030
+ readOnly: true
1031
+ }),
1032
+ tool(
1033
+ "inspect_instance",
1034
+ "Describes an instance: its main component, variant, component property values (with types) and the overrides of its layers.",
1035
+ { id: ID },
1036
+ ({ id }) => {
1037
+ const info = controller.inspect(id);
1038
+ if (!info) throw new Error("Not an instance (or a layer inside one).");
1039
+ return info;
1040
+ },
1041
+ { readOnly: true }
1042
+ ),
1043
+ tool(
1044
+ "create_component",
1045
+ "Turns the given frame into a main component, or wraps the given layers in a new one.",
1046
+ { ids: IDS },
1047
+ ({ ids }) => check(controller.createComponent(ids))
1048
+ ),
1049
+ tool(
1050
+ "combine_as_variants",
1051
+ 'Wraps sibling components in a component set (variants named "Property=Value, \u2026").',
1052
+ { ids: IDS },
1053
+ ({ ids }) => check(controller.combineAsVariants(ids))
1054
+ ),
1055
+ tool(
1056
+ "create_instance",
1057
+ "Places an instance of a component or component set, optionally inside a frame, at a position, with property values.",
1058
+ {
1059
+ componentId: { type: "string" },
1060
+ parentId: { type: "string" },
1061
+ x: { type: "number" },
1062
+ y: { type: "number" },
1063
+ properties: { type: "object", additionalProperties: true, description: "Variant and component property values." }
1064
+ },
1065
+ ({ componentId, parentId, x, y, properties }) => check(
1066
+ controller.createInstance(componentId, {
1067
+ ...parentId !== void 0 ? { parentId } : {},
1068
+ ...x !== void 0 || y !== void 0 ? { position: { x: _nullishCoalesce(x, () => ( 0)), y: _nullishCoalesce(y, () => ( 0)) } } : {},
1069
+ ...properties ? { properties } : {}
1070
+ })
1071
+ ),
1072
+ { required: ["componentId"] }
1073
+ ),
1074
+ tool(
1075
+ "set_instance_properties",
1076
+ "Sets property values of instances: variant properties switch the variant (keeping compatible overrides), booleans toggle layers, text sets text, instance swap takes a component id.",
1077
+ { properties: { type: "object", additionalProperties: true }, ids: IDS },
1078
+ ({ properties, ids }) => check(controller.setInstanceProperties(properties, ids)),
1079
+ { required: ["properties"] }
1080
+ ),
1081
+ tool(
1082
+ "swap_instance",
1083
+ "Makes instances show another component (or a set\u2019s default variant), keeping overrides of layers with matching names.",
1084
+ { componentId: { type: "string" }, ids: IDS },
1085
+ ({ componentId, ids }) => check(controller.swapInstance(componentId, ids)),
1086
+ { required: ["componentId"] }
1087
+ ),
1088
+ tool(
1089
+ "reset_overrides",
1090
+ 'Resets overrides: of a whole instance (default), of one layer, or one override group such as "data.label" or "shape.fill".',
1091
+ { id: ID, group: { type: "string" } },
1092
+ ({ id, group }) => check(controller.resetOverrides(id, group))
1093
+ ),
1094
+ tool(
1095
+ "push_overrides",
1096
+ "Copies an instance\u2019s overrides to its main component (and so to every other instance).",
1097
+ { id: ID },
1098
+ ({ id }) => check(controller.pushOverrides(id))
1099
+ ),
1100
+ tool("detach_instance", "Turns instances into plain frames that keep their current look.", { ids: IDS }, ({ ids }) => check(controller.detachInstance(ids))),
1101
+ tool("go_to_main_component", "Selects the main component of an instance and returns its id.", { id: ID }, ({ id }) => {
1102
+ const main = controller.goToMainComponent(id);
1103
+ if (!main) throw new Error("The main component was not found.");
1104
+ return { id: main };
1105
+ }),
1106
+ tool(
1107
+ "restore_main_component",
1108
+ "Turns an instance whose main component was deleted back into the main component.",
1109
+ { id: ID },
1110
+ ({ id }) => check(controller.restoreMainComponent(id))
1111
+ )
1112
+ ];
1113
+ return { id: options.id, namespace: options.namespace, tools };
1114
+ }
1115
+
1116
+
954
1117
 
955
1118
 
956
1119
 
@@ -970,5 +1133,5 @@ function createEditorMcpToolProvider(options) {
970
1133
 
971
1134
 
972
1135
 
973
- exports.EDITOR_MCP_TOOLS = EDITOR_MCP_TOOLS; exports.EXPORT_EXCLUDED_SELECTORS = EXPORT_EXCLUDED_SELECTORS; exports.MCP_TOOL_EDIT_CANVAS = MCP_TOOL_EDIT_CANVAS; exports.MCP_TOOL_EDIT_PROMPT = MCP_TOOL_EDIT_PROMPT; exports.MCP_TOOL_GET_EDITOR_STATE = MCP_TOOL_GET_EDITOR_STATE; exports.MCP_TOOL_VIEW_EDITOR = MCP_TOOL_VIEW_EDITOR; exports.TOOL_NAMESPACE_SEPARATOR = TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = ToolRegistry; exports.ToolRegistryError = ToolRegistryError; exports.createEditorMcpToolProvider = createEditorMcpToolProvider; exports.createRichTextToolProvider = createRichTextToolProvider; exports.createSpreadsheetToolProvider = createSpreadsheetToolProvider; exports.createToolRegistry = createToolRegistry; exports.normalizeSide = normalizeSide; exports.planAgentCommand = planAgentCommand; exports.planToolCall = planToolCall; exports.toToolResult = toToolResult; exports.toolCallToAgentCommand = toolCallToAgentCommand; exports.validateJsonSchema = _chunkCPOKFNBGcjs.validateJsonSchema;
1136
+ exports.EDITOR_MCP_TOOLS = EDITOR_MCP_TOOLS; exports.EXPORT_EXCLUDED_SELECTORS = EXPORT_EXCLUDED_SELECTORS; exports.MCP_TOOL_EDIT_CANVAS = MCP_TOOL_EDIT_CANVAS; exports.MCP_TOOL_EDIT_PROMPT = MCP_TOOL_EDIT_PROMPT; exports.MCP_TOOL_GET_EDITOR_STATE = MCP_TOOL_GET_EDITOR_STATE; exports.MCP_TOOL_VIEW_EDITOR = MCP_TOOL_VIEW_EDITOR; exports.TOOL_NAMESPACE_SEPARATOR = TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = ToolRegistry; exports.ToolRegistryError = ToolRegistryError; exports.createCanvasComponentToolProvider = createCanvasComponentToolProvider; exports.createEditorMcpToolProvider = createEditorMcpToolProvider; exports.createRichTextToolProvider = createRichTextToolProvider; exports.createSpreadsheetToolProvider = createSpreadsheetToolProvider; exports.createToolRegistry = createToolRegistry; exports.normalizeSide = normalizeSide; exports.planAgentCommand = planAgentCommand; exports.planToolCall = planToolCall; exports.toToolResult = toToolResult; exports.toolCallToAgentCommand = toolCallToAgentCommand; exports.validateJsonSchema = _chunkCPOKFNBGcjs.validateJsonSchema;
974
1137
  //# sourceMappingURL=index.cjs.map