@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.
- package/README.md +25 -4
- package/dist/agent/formatTools.d.cts +15 -0
- package/dist/agent/formatTools.d.ts +15 -0
- package/dist/agent/index.cjs +397 -46
- package/dist/agent/index.js +365 -14
- package/dist/agent/providers.d.cts +5 -3
- package/dist/agent/providers.d.ts +5 -3
- package/dist/animation-editor/effect-tools.d.cts +1 -1
- package/dist/animation-editor/effect-tools.d.ts +1 -1
- package/dist/animation-editor/index.cjs +250 -116
- package/dist/animation-editor/index.js +228 -94
- package/dist/animation-editor/instructions.d.cts +1 -1
- package/dist/animation-editor/instructions.d.ts +1 -1
- package/dist/animation-editor/parse.d.cts +3 -1
- package/dist/animation-editor/parse.d.ts +3 -1
- package/dist/animation-editor/tools.d.cts +8 -3
- package/dist/animation-editor/tools.d.ts +8 -3
- package/dist/bridge/cli.cjs +3 -3
- package/dist/bridge/cli.js +2 -2
- package/dist/bridge/index.cjs +7 -3
- package/dist/bridge/index.d.cts +7 -0
- package/dist/bridge/index.d.ts +7 -0
- package/dist/bridge/index.js +8 -4
- package/dist/bridge/skills.d.cts +9 -0
- package/dist/bridge/skills.d.ts +9 -0
- package/dist/canvas/effect-tools.d.cts +1 -1
- package/dist/canvas/effect-tools.d.ts +1 -1
- package/dist/canvas/index.cjs +22 -17
- package/dist/canvas/index.js +8 -3
- package/dist/chart/file-tools.d.cts +1 -1
- package/dist/chart/file-tools.d.ts +1 -1
- package/dist/chart/index.cjs +7 -1
- package/dist/chart/index.js +7 -1
- package/dist/chart/tools.d.cts +1 -1
- package/dist/chart/tools.d.ts +1 -1
- package/dist/{chunk-BKMU3V6K.js → chunk-5ED73EC6.js} +8 -1
- package/dist/{chunk-VRIR53SW.js → chunk-5G3KYRER.js} +2 -1
- package/dist/{chunk-KHMVB3SJ.js → chunk-7KWJEYIK.js} +4 -1
- package/dist/{chunk-R47NQICB.cjs → chunk-HDCH35UM.cjs} +47 -10
- package/dist/{chunk-6NCBFBXA.js → chunk-IQ6KKXOU.js} +1 -1
- package/dist/{chunk-PCNCT4ZY.js → chunk-KIBEEN5K.js} +40 -3
- package/dist/{chunk-CZRWP6IW.cjs → chunk-N2FGYZ4Q.cjs} +8 -1
- package/dist/{chunk-T6Y5FV7G.cjs → chunk-RPW7YL3D.cjs} +2 -1
- package/dist/{chunk-3V746PF4.cjs → chunk-RUZQMYXH.cjs} +4 -1
- package/dist/{chunk-GUPQ5BNA.cjs → chunk-RWML7TWG.cjs} +44 -44
- package/dist/{chunk-HGHXGCKG.cjs → chunk-SVFEVKLF.cjs} +1 -1
- package/dist/{chunk-PQMADRCI.js → chunk-UOJS6PUP.js} +1 -1
- package/dist/{chunk-BWT4IWLK.cjs → chunk-VKF3PWKR.cjs} +7 -7
- package/dist/chunk-WBKLYLZE.js +1156 -0
- package/dist/{chunk-TBSPPVTT.js → chunk-XCK7QK5D.js} +1 -1
- package/dist/chunk-ZAOOIJ6I.cjs +1156 -0
- package/dist/commands/agentTools.d.cts +1 -1
- package/dist/commands/agentTools.d.ts +1 -1
- package/dist/commands/index.cjs +3 -0
- package/dist/commands/index.js +3 -0
- package/dist/diagram/index.cjs +3 -0
- package/dist/diagram/index.js +3 -0
- package/dist/diagram/tools.d.cts +1 -1
- package/dist/diagram/tools.d.ts +1 -1
- package/dist/effects/index.cjs +32 -32
- package/dist/effects/index.js +1 -1
- package/dist/effects/tools.d.cts +5 -1
- package/dist/effects/tools.d.ts +5 -1
- package/dist/extensions/index.cjs +3 -3
- package/dist/extensions/index.js +2 -2
- package/dist/generation/index.cjs +7 -1
- package/dist/generation/index.js +7 -1
- package/dist/image-editor/index.cjs +21 -15
- package/dist/image-editor/index.js +8 -2
- package/dist/image-editor/provider-effect-tools.d.cts +1 -1
- package/dist/image-editor/provider-effect-tools.d.ts +1 -1
- package/dist/image-editor/tools.d.cts +1 -1
- package/dist/image-editor/tools.d.ts +1 -1
- package/dist/index.cjs +8 -8
- package/dist/index.js +2 -2
- package/dist/paint-editor/effect-tools.d.cts +1 -1
- package/dist/paint-editor/effect-tools.d.ts +1 -1
- package/dist/paint-editor/index.cjs +18 -8
- package/dist/paint-editor/index.js +13 -3
- package/dist/paint-editor/tools.d.cts +1 -1
- package/dist/paint-editor/tools.d.ts +1 -1
- package/dist/tools/bridge-client.d.cts +3 -3
- package/dist/tools/bridge-client.d.ts +3 -3
- package/dist/tools/capture.d.cts +5 -1
- package/dist/tools/capture.d.ts +5 -1
- package/dist/tools/definitions.d.cts +2 -2
- package/dist/tools/definitions.d.ts +2 -2
- package/dist/tools/index.cjs +31 -5
- package/dist/tools/index.d.cts +3 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +31 -5
- package/dist/tools/mcp-server.d.cts +24 -6
- package/dist/tools/mcp-server.d.ts +24 -6
- package/dist/tools/registry.d.cts +81 -6
- package/dist/tools/registry.d.ts +81 -6
- package/dist/tools/search.d.cts +30 -0
- package/dist/tools/search.d.ts +30 -0
- package/dist/tools/skills.d.cts +26 -0
- package/dist/tools/skills.d.ts +26 -0
- package/dist/tools/view.d.cts +95 -0
- package/dist/tools/view.d.ts +95 -0
- package/dist/vector/effect-tools.d.cts +1 -1
- package/dist/vector/effect-tools.d.ts +1 -1
- package/dist/vector/index.cjs +13 -7
- package/dist/vector/index.js +8 -2
- package/dist/video-editor/effect-tools.d.cts +1 -1
- package/dist/video-editor/effect-tools.d.ts +1 -1
- package/dist/video-editor/index.cjs +275 -269
- package/dist/video-editor/index.js +8 -2
- package/dist/video-editor/tools.d.cts +1 -1
- package/dist/video-editor/tools.d.ts +1 -1
- package/package.json +4 -2
- package/skills/README.md +8 -3
- package/skills/pixerate-agent-tools/SKILL.md +33 -7
- package/skills/pixerate-animation-editor/SKILL.md +7 -0
- package/skills/pixerate-rich-text/SKILL.md +18 -4
- package/dist/chunk-5RRYDFU2.js +0 -466
- package/dist/chunk-SPVIXXIB.cjs +0 -466
- /package/dist/{chunk-SMJK5HBJ.js → chunk-MCTQXUXR.js} +0 -0
- /package/dist/{chunk-DDF6WQ62.cjs → chunk-R6DFK5OX.cjs} +0 -0
package/dist/agent/index.js
CHANGED
|
@@ -12,20 +12,33 @@ import {
|
|
|
12
12
|
placeBeside
|
|
13
13
|
} from "../chunk-BTZS3KZY.js";
|
|
14
14
|
import "../chunk-7KZ2HKKC.js";
|
|
15
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-MCTQXUXR.js";
|
|
16
16
|
import {
|
|
17
17
|
JSON_RPC_ERRORS,
|
|
18
18
|
MCP_PROTOCOL_VERSIONS,
|
|
19
19
|
TOOL_BRIDGE_DEFAULT_PORT,
|
|
20
20
|
TOOL_BRIDGE_PROTOCOL,
|
|
21
|
+
TOOL_DISCOVERY_TOOLS,
|
|
21
22
|
TOOL_NAMESPACE_SEPARATOR,
|
|
22
23
|
ToolRegistry,
|
|
23
24
|
ToolRegistryError,
|
|
25
|
+
ToolRegistryView,
|
|
26
|
+
baseToolName,
|
|
24
27
|
connectToolBridge,
|
|
25
28
|
createMcpServer,
|
|
26
29
|
createToolRegistry,
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
errorResult,
|
|
31
|
+
listSkills,
|
|
32
|
+
parseSkillFrontmatter,
|
|
33
|
+
readSkillFile,
|
|
34
|
+
searchTokens,
|
|
35
|
+
searchTools,
|
|
36
|
+
summarize,
|
|
37
|
+
toToolResult,
|
|
38
|
+
toolsetInstructions,
|
|
39
|
+
toolsetName,
|
|
40
|
+
unknownToolMessage
|
|
41
|
+
} from "../chunk-WBKLYLZE.js";
|
|
29
42
|
import {
|
|
30
43
|
CAPTURE_EXCLUDE_SELECTOR,
|
|
31
44
|
CAPTURE_OVERLAY_SELECTORS,
|
|
@@ -53,7 +66,7 @@ import {
|
|
|
53
66
|
createElementCaptureSurface,
|
|
54
67
|
elementToSvg,
|
|
55
68
|
rasterizeElement
|
|
56
|
-
} from "../chunk-
|
|
69
|
+
} from "../chunk-XCK7QK5D.js";
|
|
57
70
|
import {
|
|
58
71
|
captureInputSchema,
|
|
59
72
|
captureOutputSize,
|
|
@@ -62,7 +75,7 @@ import {
|
|
|
62
75
|
resolveCaptureRequest,
|
|
63
76
|
toCapturedImageData,
|
|
64
77
|
unionCaptureRects
|
|
65
|
-
} from "../chunk-
|
|
78
|
+
} from "../chunk-5ED73EC6.js";
|
|
66
79
|
import {
|
|
67
80
|
DEFAULT_AGENT_CARET_COLOR,
|
|
68
81
|
DEFAULT_AGENT_CARET_NAME,
|
|
@@ -83,7 +96,7 @@ import {
|
|
|
83
96
|
setAgentCaret,
|
|
84
97
|
sparklineLabel,
|
|
85
98
|
typeAgentText
|
|
86
|
-
} from "../chunk-
|
|
99
|
+
} from "../chunk-5G3KYRER.js";
|
|
87
100
|
import {
|
|
88
101
|
describeChart
|
|
89
102
|
} from "../chunk-KI2VBONS.js";
|
|
@@ -438,7 +451,8 @@ function planToolCall(name, args, snapshot, options) {
|
|
|
438
451
|
}
|
|
439
452
|
|
|
440
453
|
// src/agent/providers.ts
|
|
441
|
-
import { TextSelection } from "@tiptap/pm/state";
|
|
454
|
+
import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
455
|
+
import { closeHistory as closeHistory3 } from "@tiptap/pm/history";
|
|
442
456
|
|
|
443
457
|
// src/agent/documentChartTools.ts
|
|
444
458
|
import { closeHistory } from "@tiptap/pm/history";
|
|
@@ -636,6 +650,309 @@ function createDocumentChartTools(editor) {
|
|
|
636
650
|
};
|
|
637
651
|
}
|
|
638
652
|
|
|
653
|
+
// src/agent/formatTools.ts
|
|
654
|
+
import { closeHistory as closeHistory2 } from "@tiptap/pm/history";
|
|
655
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
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
|
+
closeHistory2(tr);
|
|
700
|
+
tr.setSelection(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(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 ? 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) => !!schema.marks[mark]?.spec.attrs?.[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 ext?.options?.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 = (ext.options?.alignments ?? ["left", "center", "right", "justify"]).slice();
|
|
912
|
+
const types = ext.options?.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) {
|
|
@@ -707,7 +1024,7 @@ function createTextPresence(editor, providerId, option) {
|
|
|
707
1024
|
touch();
|
|
708
1025
|
return range2;
|
|
709
1026
|
}
|
|
710
|
-
const tr = replaceWithTextTransaction(ed.state, from, to, text);
|
|
1027
|
+
const tr = closeHistory3(replaceWithTextTransaction(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());
|
|
@@ -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,7 +1207,7 @@ 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;
|
|
1210
|
+
const tr = closeHistory3(ed.state.tr);
|
|
893
1211
|
const ends = applyReplacements(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] }));
|
|
@@ -954,7 +1272,7 @@ function createRichTextToolProvider(target, options) {
|
|
|
954
1272
|
const ed = editor();
|
|
955
1273
|
checkRange(ed, from, to);
|
|
956
1274
|
const { doc } = ed.state;
|
|
957
|
-
ed.view.dispatch(ed.state.tr.setSelection(
|
|
1275
|
+
ed.view.dispatch(ed.state.tr.setSelection(TextSelection2.between(doc.resolve(from), doc.resolve(to))));
|
|
958
1276
|
const selection = selectionInfo(ed);
|
|
959
1277
|
presence.show(selection.from, selection.to);
|
|
960
1278
|
return { selection };
|
|
@@ -1018,7 +1336,7 @@ function createRichTextToolProvider(target, options) {
|
|
|
1018
1336
|
if (at !== void 0) {
|
|
1019
1337
|
const size = ed.state.doc.content.size;
|
|
1020
1338
|
if (at > size) throw new Error(`Position ${at} is outside the document (size ${size}).`);
|
|
1021
|
-
ed.view.dispatch(ed.state.tr.setSelection(
|
|
1339
|
+
ed.view.dispatch(ed.state.tr.setSelection(TextSelection2.near(ed.state.doc.resolve(at))));
|
|
1022
1340
|
}
|
|
1023
1341
|
const action = operation;
|
|
1024
1342
|
const state = getTableActionState(ed, action, params);
|
|
@@ -1035,11 +1353,14 @@ 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];
|
|
1363
|
+
const tools = [getText, findText, insertText, replaceText, replaceRange, replaceSelection, setSelection, ...formatting.tools(ed)];
|
|
1043
1364
|
return [...tools, ...isTableEnabled(ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
|
|
1044
1365
|
},
|
|
1045
1366
|
subscribe: (notify) => {
|
|
@@ -1387,6 +1708,9 @@ 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
|
}
|
|
@@ -1452,7 +1776,14 @@ function createEditorMcpToolProvider(options) {
|
|
|
1452
1776
|
}
|
|
1453
1777
|
});
|
|
1454
1778
|
}
|
|
1455
|
-
return {
|
|
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 {
|
|
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
|
export {
|
|
1654
1992
|
CAPTURE_EXCLUDE_SELECTOR,
|
|
@@ -1677,9 +2015,12 @@ export {
|
|
|
1677
2015
|
MCP_TOOL_VIEW_EDITOR,
|
|
1678
2016
|
TOOL_BRIDGE_DEFAULT_PORT,
|
|
1679
2017
|
TOOL_BRIDGE_PROTOCOL,
|
|
2018
|
+
TOOL_DISCOVERY_TOOLS,
|
|
1680
2019
|
TOOL_NAMESPACE_SEPARATOR,
|
|
1681
2020
|
ToolRegistry,
|
|
1682
2021
|
ToolRegistryError,
|
|
2022
|
+
ToolRegistryView,
|
|
2023
|
+
baseToolName,
|
|
1683
2024
|
captureInputSchema,
|
|
1684
2025
|
captureOutputSize,
|
|
1685
2026
|
cloneElementWithStyles,
|
|
@@ -1695,15 +2036,25 @@ export {
|
|
|
1695
2036
|
createSpreadsheetToolProvider,
|
|
1696
2037
|
createToolRegistry,
|
|
1697
2038
|
elementToSvg,
|
|
2039
|
+
errorResult,
|
|
2040
|
+
listSkills,
|
|
1698
2041
|
normalizeSide,
|
|
2042
|
+
parseSkillFrontmatter,
|
|
1699
2043
|
planAgentCommand,
|
|
1700
2044
|
planToolCall,
|
|
1701
2045
|
rasterizeElement,
|
|
2046
|
+
readSkillFile,
|
|
1702
2047
|
resolveCaptureRequest,
|
|
2048
|
+
searchTokens,
|
|
2049
|
+
searchTools,
|
|
2050
|
+
summarize,
|
|
1703
2051
|
toCapturedImageData,
|
|
1704
2052
|
toToolResult,
|
|
1705
2053
|
toolCallToAgentCommand,
|
|
2054
|
+
toolsetInstructions,
|
|
2055
|
+
toolsetName,
|
|
1706
2056
|
unionCaptureRects,
|
|
2057
|
+
unknownToolMessage,
|
|
1707
2058
|
validateAgentCommand,
|
|
1708
2059
|
validateJsonSchema
|
|
1709
2060
|
};
|
|
@@ -8,7 +8,7 @@ import { type AgentTypingOptions } from '../extensions/agent-caret.cjs';
|
|
|
8
8
|
export interface ToolProviderOptions {
|
|
9
9
|
/** Provider id (unique per registry). */
|
|
10
10
|
id: string;
|
|
11
|
-
/**
|
|
11
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
12
12
|
namespace?: string;
|
|
13
13
|
}
|
|
14
14
|
/** A TipTap editor, or anything exposing one as `.editor` (e.g. `EditorController`). */
|
|
@@ -42,8 +42,10 @@ export interface RichTextToolProviderOptions extends ToolProviderOptions {
|
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Tools for a mounted rich-text editor: `get_text` and `find_text` (always),
|
|
45
|
-
* plus `insert_text`, `replace_text`, `replace_range`, `replace_selection
|
|
46
|
-
* `set_selection`
|
|
45
|
+
* plus `insert_text`, `replace_text`, `replace_range`, `replace_selection`,
|
|
46
|
+
* `set_selection` and the formatting tools (`format_text`, `set_block_type`,
|
|
47
|
+
* `set_text_align`, as far as the schema supports them) while the editor is
|
|
48
|
+
* editable, `edit_table` when the
|
|
47
49
|
* schema has tables (`createRichTextPreset`'s `table`), and the chart tools
|
|
48
50
|
* (`list_document_charts`; `insert_chart`, `update_chart_in_document` and
|
|
49
51
|
* `insert_sparkline` while editable) when it has charts (`chart`).
|
|
@@ -8,7 +8,7 @@ import { type AgentTypingOptions } from '../extensions/agent-caret.js';
|
|
|
8
8
|
export interface ToolProviderOptions {
|
|
9
9
|
/** Provider id (unique per registry). */
|
|
10
10
|
id: string;
|
|
11
|
-
/**
|
|
11
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
12
12
|
namespace?: string;
|
|
13
13
|
}
|
|
14
14
|
/** A TipTap editor, or anything exposing one as `.editor` (e.g. `EditorController`). */
|
|
@@ -42,8 +42,10 @@ export interface RichTextToolProviderOptions extends ToolProviderOptions {
|
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Tools for a mounted rich-text editor: `get_text` and `find_text` (always),
|
|
45
|
-
* plus `insert_text`, `replace_text`, `replace_range`, `replace_selection
|
|
46
|
-
* `set_selection`
|
|
45
|
+
* plus `insert_text`, `replace_text`, `replace_range`, `replace_selection`,
|
|
46
|
+
* `set_selection` and the formatting tools (`format_text`, `set_block_type`,
|
|
47
|
+
* `set_text_align`, as far as the schema supports them) while the editor is
|
|
48
|
+
* editable, `edit_table` when the
|
|
47
49
|
* schema has tables (`createRichTextPreset`'s `table`), and the chart tools
|
|
48
50
|
* (`list_document_charts`; `insert_chart`, `update_chart_in_document` and
|
|
49
51
|
* `insert_sparkline` while editable) when it has charts (`chart`).
|
|
@@ -8,7 +8,7 @@ import type { AnimationEditorController } from './controller.cjs';
|
|
|
8
8
|
export interface AnimationEffectsToolProviderOptions {
|
|
9
9
|
/** Provider id (unique per registry). Default `animation-effects`. */
|
|
10
10
|
id?: string;
|
|
11
|
-
/**
|
|
11
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
12
12
|
namespace?: string;
|
|
13
13
|
/** The scene cannot be edited: write tools are hidden. A string is the reason. */
|
|
14
14
|
readOnly?: boolean | string | (() => boolean | string);
|
|
@@ -8,7 +8,7 @@ import type { AnimationEditorController } from './controller.js';
|
|
|
8
8
|
export interface AnimationEffectsToolProviderOptions {
|
|
9
9
|
/** Provider id (unique per registry). Default `animation-effects`. */
|
|
10
10
|
id?: string;
|
|
11
|
-
/**
|
|
11
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
12
12
|
namespace?: string;
|
|
13
13
|
/** The scene cannot be edited: write tools are hidden. A string is the reason. */
|
|
14
14
|
readOnly?: boolean | string | (() => boolean | string);
|