@pixerate/editor 0.235.0 → 0.237.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.
- package/README.md +1 -1
- package/dist/agent/index.cjs +286 -27
- package/dist/agent/index.d.cts +1 -0
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.js +261 -2
- package/dist/agent/reviewTools.d.cts +16 -0
- package/dist/agent/reviewTools.d.ts +16 -0
- package/dist/{chunk-CZBRY4SW.cjs → chunk-CZWUDFR3.cjs} +214 -389
- package/dist/{chunk-PI2UYMZY.js → chunk-FSLKBQU7.js} +269 -15
- package/dist/{chunk-3MO3ZS7E.js → chunk-JVSX5QTS.js} +141 -316
- package/dist/{chunk-O7QXVGMP.cjs → chunk-WV5WTOC6.cjs} +295 -41
- package/dist/extensions/index.cjs +8 -6
- package/dist/extensions/index.js +12 -10
- package/dist/extensions/loading-node.d.cts +45 -1
- package/dist/extensions/loading-node.d.ts +45 -1
- package/dist/index.cjs +13 -11
- package/dist/index.js +12 -10
- package/package.json +1 -1
- package/skills/pixerate-rich-text/SKILL.md +28 -1
- package/skills/pixerate-rich-text-revise/SKILL.md +8 -1
|
@@ -17,21 +17,267 @@ import {
|
|
|
17
17
|
plainTextToSlice
|
|
18
18
|
} from "./chunk-2INPJDNY.js";
|
|
19
19
|
import {
|
|
20
|
+
CommentStore,
|
|
20
21
|
TRACK_CHANGES_SKIP_META,
|
|
22
|
+
createReviewId,
|
|
21
23
|
isTrackChangesEnabled,
|
|
22
24
|
safeMergeAttributes
|
|
23
25
|
} from "./chunk-6IN474P4.js";
|
|
24
26
|
|
|
27
|
+
// src/extensions/comments.ts
|
|
28
|
+
import { Mark } from "@tiptap/core";
|
|
29
|
+
import { Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
30
|
+
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
31
|
+
var commentsPluginKey = new PluginKey("comments");
|
|
32
|
+
var COMMENT_MARK_NAME = "comment";
|
|
33
|
+
function findCommentRanges(doc) {
|
|
34
|
+
const result = /* @__PURE__ */ new Map();
|
|
35
|
+
doc.descendants((node, pos) => {
|
|
36
|
+
if (!node.isInline) return;
|
|
37
|
+
node.marks.forEach((mark) => {
|
|
38
|
+
if (mark.type.name !== COMMENT_MARK_NAME) return;
|
|
39
|
+
const id = mark.attrs.commentId;
|
|
40
|
+
if (!id) return;
|
|
41
|
+
const ranges = result.get(id) ?? [];
|
|
42
|
+
const last = ranges[ranges.length - 1];
|
|
43
|
+
const end = pos + node.nodeSize;
|
|
44
|
+
if (last && last.to === pos) {
|
|
45
|
+
last.to = end;
|
|
46
|
+
} else {
|
|
47
|
+
ranges.push({ from: pos, to: end });
|
|
48
|
+
}
|
|
49
|
+
result.set(id, ranges);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
function getCommentAnchors(doc) {
|
|
55
|
+
const anchors = /* @__PURE__ */ new Map();
|
|
56
|
+
findCommentRanges(doc).forEach((ranges, id) => {
|
|
57
|
+
const from = ranges[0].from;
|
|
58
|
+
const to = ranges[ranges.length - 1].to;
|
|
59
|
+
anchors.set(id, {
|
|
60
|
+
from,
|
|
61
|
+
to,
|
|
62
|
+
quote: ranges.map((r) => doc.textBetween(r.from, r.to, " ", " ")).join(" ")
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
return anchors;
|
|
66
|
+
}
|
|
67
|
+
function getCommentIdsAt(state, pos = state.selection.from) {
|
|
68
|
+
const $pos = state.doc.resolve(pos);
|
|
69
|
+
const marks = [
|
|
70
|
+
...$pos.nodeAfter?.marks ?? [],
|
|
71
|
+
...$pos.nodeBefore?.marks ?? []
|
|
72
|
+
];
|
|
73
|
+
const ids = [];
|
|
74
|
+
marks.forEach((m) => {
|
|
75
|
+
if (m.type.name === COMMENT_MARK_NAME && m.attrs.commentId && !ids.includes(m.attrs.commentId)) {
|
|
76
|
+
ids.push(m.attrs.commentId);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return ids;
|
|
80
|
+
}
|
|
81
|
+
function getCommentStore(editor) {
|
|
82
|
+
return editor?.storage?.[COMMENT_MARK_NAME]?.store ?? null;
|
|
83
|
+
}
|
|
84
|
+
function resolveAuthor(author) {
|
|
85
|
+
return typeof author === "function" ? author() : author;
|
|
86
|
+
}
|
|
87
|
+
var Comments = Mark.create({
|
|
88
|
+
name: COMMENT_MARK_NAME,
|
|
89
|
+
// Typing at the edge of a comment does not extend it.
|
|
90
|
+
inclusive: false,
|
|
91
|
+
// Allow several comment marks (different threads) on the same text.
|
|
92
|
+
excludes: "",
|
|
93
|
+
addOptions() {
|
|
94
|
+
return {
|
|
95
|
+
store: null,
|
|
96
|
+
author: { id: "anonymous", name: "Anonymous" },
|
|
97
|
+
HTMLAttributes: {},
|
|
98
|
+
commentClass: "pixerate-comment bg-amber-100 border-b-2 border-amber-400 dark:bg-amber-500/20 cursor-pointer",
|
|
99
|
+
activeClass: "pixerate-comment-active bg-amber-200 dark:bg-amber-500/40",
|
|
100
|
+
resolvedClass: "",
|
|
101
|
+
activateOnSelection: true
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
addStorage() {
|
|
105
|
+
return {
|
|
106
|
+
store: this.options.store ?? new CommentStore(),
|
|
107
|
+
// tiptap-markdown: comments are not part of the exported markdown.
|
|
108
|
+
markdown: { serialize: { open: "", close: "" }, parse: {} }
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
addAttributes() {
|
|
112
|
+
return {
|
|
113
|
+
commentId: {
|
|
114
|
+
default: null,
|
|
115
|
+
parseHTML: (el) => el.getAttribute("data-comment-id"),
|
|
116
|
+
renderHTML: (attrs) => attrs.commentId ? { "data-comment-id": attrs.commentId } : {}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
parseHTML() {
|
|
121
|
+
return [{ tag: "span[data-comment-id]" }];
|
|
122
|
+
},
|
|
123
|
+
renderHTML({ HTMLAttributes }) {
|
|
124
|
+
return ["span", safeMergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
125
|
+
},
|
|
126
|
+
addCommands() {
|
|
127
|
+
const store = () => this.storage.store;
|
|
128
|
+
return {
|
|
129
|
+
addComment: (options = {}) => ({ state, tr, dispatch }) => {
|
|
130
|
+
const { from, to, empty } = state.selection;
|
|
131
|
+
if (empty) return false;
|
|
132
|
+
if (dispatch) {
|
|
133
|
+
const id = options.id ?? createReviewId("comment");
|
|
134
|
+
tr.addMark(from, to, this.type.create({ commentId: id }));
|
|
135
|
+
tr.setMeta(commentsPluginKey, "refresh");
|
|
136
|
+
store().createThread({
|
|
137
|
+
id,
|
|
138
|
+
body: options.body ?? "",
|
|
139
|
+
author: options.author ?? resolveAuthor(this.options.author),
|
|
140
|
+
anchor: { from, to, quote: state.doc.textBetween(from, to, " ", " ") }
|
|
141
|
+
});
|
|
142
|
+
store().setActiveThread(id);
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
},
|
|
146
|
+
resolveComment: (id, resolved = true) => ({ tr, dispatch }) => {
|
|
147
|
+
if (!store().getThread(id)) return false;
|
|
148
|
+
if (dispatch) {
|
|
149
|
+
store().resolveThread(id, resolved, resolveAuthor(this.options.author));
|
|
150
|
+
tr.setMeta(commentsPluginKey, "refresh");
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
},
|
|
154
|
+
deleteComment: (id) => ({ state, tr, dispatch }) => {
|
|
155
|
+
const ranges = findCommentRanges(state.doc).get(id) ?? [];
|
|
156
|
+
if (ranges.length === 0 && !store().getThread(id)) return false;
|
|
157
|
+
if (dispatch) {
|
|
158
|
+
ranges.forEach(({ from, to }) => {
|
|
159
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
160
|
+
const mark = node.marks.find(
|
|
161
|
+
(m) => m.type === this.type && m.attrs.commentId === id
|
|
162
|
+
);
|
|
163
|
+
if (mark) {
|
|
164
|
+
tr.removeMark(Math.max(pos, from), Math.min(pos + node.nodeSize, to), mark);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
tr.setMeta(commentsPluginKey, "refresh");
|
|
169
|
+
store().deleteThread(id);
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
setActiveComment: (id) => ({ tr, dispatch }) => {
|
|
174
|
+
if (id !== null && !store().getThread(id)) return false;
|
|
175
|
+
if (dispatch) {
|
|
176
|
+
store().setActiveThread(id);
|
|
177
|
+
tr.setMeta(commentsPluginKey, "refresh");
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
},
|
|
181
|
+
focusComment: (id) => ({ state, tr, dispatch }) => {
|
|
182
|
+
const ranges = findCommentRanges(state.doc).get(id);
|
|
183
|
+
if (!ranges || ranges.length === 0) return false;
|
|
184
|
+
if (dispatch) {
|
|
185
|
+
const from = ranges[0].from;
|
|
186
|
+
const to = ranges[ranges.length - 1].to;
|
|
187
|
+
tr.setSelection(TextSelection.create(tr.doc, from, to)).scrollIntoView();
|
|
188
|
+
store().setActiveThread(id);
|
|
189
|
+
tr.setMeta(commentsPluginKey, "refresh");
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
},
|
|
195
|
+
addProseMirrorPlugins() {
|
|
196
|
+
const store = this.storage.store;
|
|
197
|
+
const options = this.options;
|
|
198
|
+
let cache = null;
|
|
199
|
+
const buildDecorations2 = (doc) => {
|
|
200
|
+
const snapshot = store.getSnapshot();
|
|
201
|
+
if (cache && cache.doc === doc && cache.snapshot === snapshot) return cache.set;
|
|
202
|
+
const decorations = [];
|
|
203
|
+
findCommentRanges(doc).forEach((ranges, id) => {
|
|
204
|
+
const thread = store.getThread(id);
|
|
205
|
+
const resolved = thread?.resolved ?? false;
|
|
206
|
+
const active = snapshot.activeThreadId === id;
|
|
207
|
+
const cls = [
|
|
208
|
+
resolved ? options.resolvedClass : options.commentClass,
|
|
209
|
+
active ? options.activeClass : ""
|
|
210
|
+
].filter(Boolean).join(" ");
|
|
211
|
+
if (!cls) return;
|
|
212
|
+
ranges.forEach(({ from, to }) => {
|
|
213
|
+
decorations.push(Decoration.inline(from, to, { class: cls }));
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
const set = DecorationSet.create(doc, decorations);
|
|
217
|
+
cache = { doc, snapshot, set };
|
|
218
|
+
return set;
|
|
219
|
+
};
|
|
220
|
+
return [
|
|
221
|
+
new Plugin({
|
|
222
|
+
key: commentsPluginKey,
|
|
223
|
+
props: {
|
|
224
|
+
decorations: (state) => buildDecorations2(state.doc)
|
|
225
|
+
},
|
|
226
|
+
view: (view) => {
|
|
227
|
+
let destroyed = false;
|
|
228
|
+
let scheduled = false;
|
|
229
|
+
const sync = () => store.syncAnchors(getCommentAnchors(view.state.doc));
|
|
230
|
+
sync();
|
|
231
|
+
const unsubscribe = store.subscribe(() => {
|
|
232
|
+
if (scheduled) return;
|
|
233
|
+
scheduled = true;
|
|
234
|
+
queueMicrotask(() => {
|
|
235
|
+
scheduled = false;
|
|
236
|
+
if (destroyed) return;
|
|
237
|
+
sync();
|
|
238
|
+
if (cache?.snapshot !== store.getSnapshot()) {
|
|
239
|
+
view.dispatch(
|
|
240
|
+
view.state.tr.setMeta(commentsPluginKey, "refresh").setMeta("addToHistory", false)
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
update(view2, prevState) {
|
|
247
|
+
if (!prevState.doc.eq(view2.state.doc)) sync();
|
|
248
|
+
if (options.activateOnSelection && !prevState.selection.eq(view2.state.selection)) {
|
|
249
|
+
const ids = getCommentIdsAt(view2.state);
|
|
250
|
+
const active = store.getSnapshot().activeThreadId;
|
|
251
|
+
if (!active || !ids.includes(active)) {
|
|
252
|
+
store.setActiveThread(ids[0] ?? null);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
destroy() {
|
|
257
|
+
destroyed = true;
|
|
258
|
+
unsubscribe();
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
})
|
|
263
|
+
];
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
function getCommentAuthor(editor) {
|
|
267
|
+
const ext = editor?.extensionManager?.extensions.find((e) => e.name === COMMENT_MARK_NAME);
|
|
268
|
+
return ext ? resolveAuthor(ext.options.author) : null;
|
|
269
|
+
}
|
|
270
|
+
|
|
25
271
|
// src/extensions/table/nesting.ts
|
|
26
272
|
import { Fragment, Slice } from "@tiptap/pm/model";
|
|
27
|
-
import { Plugin, PluginKey, Selection } from "@tiptap/pm/state";
|
|
273
|
+
import { Plugin as Plugin2, PluginKey as PluginKey2, Selection } from "@tiptap/pm/state";
|
|
28
274
|
import {
|
|
29
275
|
CellSelection,
|
|
30
276
|
__pastedCells,
|
|
31
277
|
handlePaste as handleTablePaste
|
|
32
278
|
} from "@tiptap/pm/tables";
|
|
33
279
|
var ALLOW_NESTED_TABLES_META = "allowNestedTables";
|
|
34
|
-
var tableNestingPluginKey = new
|
|
280
|
+
var tableNestingPluginKey = new PluginKey2("tableNesting");
|
|
35
281
|
var roleOf = (node) => node.type.spec.tableRole;
|
|
36
282
|
var isTableNode = (node) => roleOf(node) === "table";
|
|
37
283
|
function outermostTableDepth($pos) {
|
|
@@ -171,7 +417,7 @@ var skip = (tr) => !tr.docChanged || tr.getMeta(ALLOW_NESTED_TABLES_META) === tr
|
|
|
171
417
|
// (nested) table back so the deletion can be reviewed.
|
|
172
418
|
!!tr.getMeta("appendedTransaction") || replacesDocument(tr);
|
|
173
419
|
function createTableNestingPlugin() {
|
|
174
|
-
return new
|
|
420
|
+
return new Plugin2({
|
|
175
421
|
key: tableNestingPluginKey,
|
|
176
422
|
props: {
|
|
177
423
|
handlePaste: (view, event, slice) => handleTablePasteWithoutNesting(view, event, slice)
|
|
@@ -1334,7 +1580,7 @@ function createChartNodeView(mount, renderStatic) {
|
|
|
1334
1580
|
|
|
1335
1581
|
// src/extensions/chart/chart-node.ts
|
|
1336
1582
|
import { Node } from "@tiptap/core";
|
|
1337
|
-
import { Plugin as
|
|
1583
|
+
import { Plugin as Plugin3, PluginKey as PluginKey3 } from "@tiptap/pm/state";
|
|
1338
1584
|
|
|
1339
1585
|
// src/extensions/document-structure/utils.ts
|
|
1340
1586
|
import { createDocument } from "@tiptap/core";
|
|
@@ -1419,7 +1665,7 @@ function syncInitialContent(editor, sync) {
|
|
|
1419
1665
|
var STRUCTURE_PRIORITY = 45;
|
|
1420
1666
|
|
|
1421
1667
|
// src/extensions/chart/chart-node.ts
|
|
1422
|
-
var chartPluginKey = new
|
|
1668
|
+
var chartPluginKey = new PluginKey3("chartNode");
|
|
1423
1669
|
function getDocumentCharts(doc, typeName = "chart") {
|
|
1424
1670
|
const charts = [];
|
|
1425
1671
|
doc.descendants((node, pos) => {
|
|
@@ -1614,7 +1860,7 @@ var Chart = Node.create({
|
|
|
1614
1860
|
const { name } = this;
|
|
1615
1861
|
const { generateId } = this.options;
|
|
1616
1862
|
return [
|
|
1617
|
-
new
|
|
1863
|
+
new Plugin3({
|
|
1618
1864
|
key: chartPluginKey,
|
|
1619
1865
|
appendTransaction: (transactions, _oldState, newState) => {
|
|
1620
1866
|
if (!transactions.some((tr) => tr.docChanged)) return null;
|
|
@@ -2007,11 +2253,11 @@ function createTableStore(editor) {
|
|
|
2007
2253
|
// src/extensions/agent-caret.ts
|
|
2008
2254
|
import { Extension } from "@tiptap/core";
|
|
2009
2255
|
import { closeHistory } from "@tiptap/pm/history";
|
|
2010
|
-
import { Plugin as
|
|
2011
|
-
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
2256
|
+
import { Plugin as Plugin4, PluginKey as PluginKey4 } from "@tiptap/pm/state";
|
|
2257
|
+
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
|
|
2012
2258
|
var DEFAULT_AGENT_CARET_COLOR = "#8b5cf6";
|
|
2013
2259
|
var DEFAULT_AGENT_CARET_NAME = "Agent";
|
|
2014
|
-
var agentCaretPluginKey = new
|
|
2260
|
+
var agentCaretPluginKey = new PluginKey4("agentCaret");
|
|
2015
2261
|
var clamp = (pos, size) => Math.max(0, Math.min(size, Math.round(pos)));
|
|
2016
2262
|
function caretWidget(caret) {
|
|
2017
2263
|
return (view) => {
|
|
@@ -2036,7 +2282,7 @@ function buildDecorations(state, carets) {
|
|
|
2036
2282
|
for (const caret of carets) {
|
|
2037
2283
|
for (const range of caret.changed) {
|
|
2038
2284
|
decorations.push(
|
|
2039
|
-
|
|
2285
|
+
Decoration2.inline(range.from, range.to, {
|
|
2040
2286
|
class: "pe-agent-changed",
|
|
2041
2287
|
"data-agent-id": caret.id,
|
|
2042
2288
|
style: `background-color:${tint(caret.color, 18)};`
|
|
@@ -2047,7 +2293,7 @@ function buildDecorations(state, carets) {
|
|
|
2047
2293
|
const to = Math.max(caret.anchor, caret.head);
|
|
2048
2294
|
if (from < to) {
|
|
2049
2295
|
decorations.push(
|
|
2050
|
-
|
|
2296
|
+
Decoration2.inline(from, to, {
|
|
2051
2297
|
class: "pe-agent-selection",
|
|
2052
2298
|
"data-agent-id": caret.id,
|
|
2053
2299
|
style: `background-color:${tint(caret.color, 28)};`
|
|
@@ -2055,20 +2301,20 @@ function buildDecorations(state, carets) {
|
|
|
2055
2301
|
);
|
|
2056
2302
|
}
|
|
2057
2303
|
decorations.push(
|
|
2058
|
-
|
|
2304
|
+
Decoration2.widget(caret.head, caretWidget(caret), {
|
|
2059
2305
|
key: `agent-caret:${caret.id}:${caret.name}:${caret.color}`,
|
|
2060
2306
|
side: 10,
|
|
2061
2307
|
ignoreSelection: true
|
|
2062
2308
|
})
|
|
2063
2309
|
);
|
|
2064
2310
|
}
|
|
2065
|
-
return
|
|
2311
|
+
return DecorationSet2.create(state.doc, decorations);
|
|
2066
2312
|
}
|
|
2067
2313
|
function createAgentCaretPlugin() {
|
|
2068
|
-
return new
|
|
2314
|
+
return new Plugin4({
|
|
2069
2315
|
key: agentCaretPluginKey,
|
|
2070
2316
|
state: {
|
|
2071
|
-
init: (_, state) => ({ carets: [], spans: {}, decorations:
|
|
2317
|
+
init: (_, state) => ({ carets: [], spans: {}, decorations: DecorationSet2.create(state.doc, []) }),
|
|
2072
2318
|
apply(tr, value, _old, state) {
|
|
2073
2319
|
const meta = tr.getMeta(agentCaretPluginKey);
|
|
2074
2320
|
if (!tr.docChanged && !meta) return value;
|
|
@@ -2217,6 +2463,14 @@ async function typeAgentText(editor, options) {
|
|
|
2217
2463
|
}
|
|
2218
2464
|
|
|
2219
2465
|
export {
|
|
2466
|
+
commentsPluginKey,
|
|
2467
|
+
COMMENT_MARK_NAME,
|
|
2468
|
+
findCommentRanges,
|
|
2469
|
+
getCommentAnchors,
|
|
2470
|
+
getCommentIdsAt,
|
|
2471
|
+
getCommentStore,
|
|
2472
|
+
Comments,
|
|
2473
|
+
getCommentAuthor,
|
|
2220
2474
|
ALLOW_NESTED_TABLES_META,
|
|
2221
2475
|
tableNestingPluginKey,
|
|
2222
2476
|
outermostTableDepth,
|