@pixerate/editor 0.139.1 → 0.140.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 (152) hide show
  1. package/README.md +25 -4
  2. package/dist/agent/formatTools.d.cts +15 -0
  3. package/dist/agent/formatTools.d.ts +15 -0
  4. package/dist/agent/index.cjs +408 -49
  5. package/dist/agent/index.js +375 -16
  6. package/dist/agent/providers.d.cts +5 -3
  7. package/dist/agent/providers.d.ts +5 -3
  8. package/dist/animation-editor/effect-tools.d.cts +1 -1
  9. package/dist/animation-editor/effect-tools.d.ts +1 -1
  10. package/dist/animation-editor/index.cjs +250 -116
  11. package/dist/animation-editor/index.js +228 -94
  12. package/dist/animation-editor/instructions.d.cts +1 -1
  13. package/dist/animation-editor/instructions.d.ts +1 -1
  14. package/dist/animation-editor/parse.d.cts +3 -1
  15. package/dist/animation-editor/parse.d.ts +3 -1
  16. package/dist/animation-editor/tools.d.cts +8 -3
  17. package/dist/animation-editor/tools.d.ts +8 -3
  18. package/dist/bridge/cli.cjs +4 -3
  19. package/dist/bridge/cli.js +3 -2
  20. package/dist/bridge/index.cjs +8 -3
  21. package/dist/bridge/index.d.cts +7 -0
  22. package/dist/bridge/index.d.ts +7 -0
  23. package/dist/bridge/index.js +9 -4
  24. package/dist/bridge/skills.d.cts +9 -0
  25. package/dist/bridge/skills.d.ts +9 -0
  26. package/dist/canvas/effect-tools.d.cts +1 -1
  27. package/dist/canvas/effect-tools.d.ts +1 -1
  28. package/dist/canvas/index.cjs +22 -17
  29. package/dist/canvas/index.js +8 -3
  30. package/dist/chart/file-tools.d.cts +1 -1
  31. package/dist/chart/file-tools.d.ts +1 -1
  32. package/dist/chart/index.cjs +7 -1
  33. package/dist/chart/index.js +7 -1
  34. package/dist/chart/tools.d.cts +1 -1
  35. package/dist/chart/tools.d.ts +1 -1
  36. package/dist/chunk-2BSBFBOA.cjs +46 -0
  37. package/dist/{chunk-SWZTQWY7.js → chunk-2INPJDNY.js} +1 -1
  38. package/dist/{chunk-CCKP4XAN.cjs → chunk-34RQAGWI.cjs} +27 -7
  39. package/dist/{chunk-HXCBQ7A6.cjs → chunk-3AJMR7EG.cjs} +7 -4
  40. package/dist/{chunk-BKMU3V6K.js → chunk-5ED73EC6.js} +8 -1
  41. package/dist/{chunk-NKBUVQJW.cjs → chunk-5WOY52O6.cjs} +15 -15
  42. package/dist/{chunk-VRIR53SW.js → chunk-6GAYGQDC.js} +10 -8
  43. package/dist/{chunk-HZZXBTLB.js → chunk-6IN474P4.js} +25 -5
  44. package/dist/{chunk-KHMVB3SJ.js → chunk-7KWJEYIK.js} +4 -1
  45. package/dist/{chunk-R47NQICB.cjs → chunk-AGCD3EHB.cjs} +47 -10
  46. package/dist/{chunk-6I63VZ45.js → chunk-CXXKJBQZ.js} +5 -1
  47. package/dist/{chunk-6NXVDJDR.cjs → chunk-G43MNQ4C.cjs} +5 -5
  48. package/dist/chunk-HDK3T2QS.cjs +1159 -0
  49. package/dist/chunk-HF5QZS7Z.js +46 -0
  50. package/dist/{chunk-S7I3RI5Z.cjs → chunk-HMGWFXEC.cjs} +27 -24
  51. package/dist/{chunk-6NCBFBXA.js → chunk-IQ6KKXOU.js} +1 -1
  52. package/dist/{chunk-T6Y5FV7G.cjs → chunk-L434J57V.cjs} +10 -8
  53. package/dist/{chunk-UCRL6JEV.cjs → chunk-L5OWG2NA.cjs} +8 -3
  54. package/dist/{chunk-CZRWP6IW.cjs → chunk-N2FGYZ4Q.cjs} +8 -1
  55. package/dist/{chunk-GUPQ5BNA.cjs → chunk-PUR6BZFA.cjs} +112 -111
  56. package/dist/chunk-RB62U6MS.js +1159 -0
  57. package/dist/{chunk-3V746PF4.cjs → chunk-RUZQMYXH.cjs} +4 -1
  58. package/dist/{chunk-HGHXGCKG.cjs → chunk-SVFEVKLF.cjs} +1 -1
  59. package/dist/{chunk-PCNCT4ZY.js → chunk-UMS6YFA6.js} +40 -3
  60. package/dist/{chunk-4LGWAJDI.js → chunk-V5OOP74P.js} +5 -2
  61. package/dist/{chunk-BWT4IWLK.cjs → chunk-VKF3PWKR.cjs} +7 -7
  62. package/dist/{chunk-PQMADRCI.js → chunk-WBJ6BG4R.js} +23 -22
  63. package/dist/{chunk-WIYAOZZU.js → chunk-WHKNYFM2.js} +7 -2
  64. package/dist/{chunk-TBSPPVTT.js → chunk-XCK7QK5D.js} +1 -1
  65. package/dist/{chunk-F652BKMS.cjs → chunk-YN6JKAUE.cjs} +6 -2
  66. package/dist/{chunk-YTGF4TJR.js → chunk-ZLZKGHSZ.js} +5 -2
  67. package/dist/{chunk-USU2FL3N.js → chunk-ZNHB5RG6.js} +1 -1
  68. package/dist/commands/agentTools.d.cts +1 -1
  69. package/dist/commands/agentTools.d.ts +1 -1
  70. package/dist/commands/index.cjs +3 -0
  71. package/dist/commands/index.js +3 -0
  72. package/dist/compare/index.cjs +4 -3
  73. package/dist/compare/index.js +3 -2
  74. package/dist/diagram/index.cjs +3 -0
  75. package/dist/diagram/index.js +3 -0
  76. package/dist/diagram/tools.d.cts +1 -1
  77. package/dist/diagram/tools.d.ts +1 -1
  78. package/dist/effects/index.cjs +32 -32
  79. package/dist/effects/index.js +1 -1
  80. package/dist/effects/tools.d.cts +5 -1
  81. package/dist/effects/tools.d.ts +5 -1
  82. package/dist/export/index.cjs +4 -3
  83. package/dist/export/index.js +3 -2
  84. package/dist/extensions/index.cjs +11 -8
  85. package/dist/extensions/index.d.cts +1 -0
  86. package/dist/extensions/index.d.ts +1 -0
  87. package/dist/extensions/index.js +10 -7
  88. package/dist/extensions/safe-merge-attributes.d.cts +10 -0
  89. package/dist/extensions/safe-merge-attributes.d.ts +10 -0
  90. package/dist/generation/index.cjs +7 -1
  91. package/dist/generation/index.js +7 -1
  92. package/dist/image-editor/index.cjs +25 -18
  93. package/dist/image-editor/index.js +10 -3
  94. package/dist/image-editor/provider-effect-tools.d.cts +1 -1
  95. package/dist/image-editor/provider-effect-tools.d.ts +1 -1
  96. package/dist/image-editor/tools.d.cts +1 -1
  97. package/dist/image-editor/tools.d.ts +1 -1
  98. package/dist/index.cjs +42 -29
  99. package/dist/index.d.cts +1 -0
  100. package/dist/index.d.ts +1 -0
  101. package/dist/index.js +22 -9
  102. package/dist/paint-editor/effect-tools.d.cts +1 -1
  103. package/dist/paint-editor/effect-tools.d.ts +1 -1
  104. package/dist/paint-editor/index.cjs +18 -8
  105. package/dist/paint-editor/index.js +13 -3
  106. package/dist/paint-editor/tools.d.cts +1 -1
  107. package/dist/paint-editor/tools.d.ts +1 -1
  108. package/dist/persistence/index.cjs +3 -2
  109. package/dist/persistence/index.js +2 -1
  110. package/dist/serializers/index.cjs +5 -4
  111. package/dist/serializers/index.js +4 -3
  112. package/dist/tools/bridge-client.d.cts +3 -3
  113. package/dist/tools/bridge-client.d.ts +3 -3
  114. package/dist/tools/capture.d.cts +5 -1
  115. package/dist/tools/capture.d.ts +5 -1
  116. package/dist/tools/definitions.d.cts +2 -2
  117. package/dist/tools/definitions.d.ts +2 -2
  118. package/dist/tools/index.cjs +39 -5
  119. package/dist/tools/index.d.cts +4 -0
  120. package/dist/tools/index.d.ts +4 -0
  121. package/dist/tools/index.js +39 -5
  122. package/dist/tools/mcp-server.d.cts +24 -6
  123. package/dist/tools/mcp-server.d.ts +24 -6
  124. package/dist/tools/registry.d.cts +81 -6
  125. package/dist/tools/registry.d.ts +81 -6
  126. package/dist/tools/safe-json.d.cts +27 -0
  127. package/dist/tools/safe-json.d.ts +27 -0
  128. package/dist/tools/search.d.cts +30 -0
  129. package/dist/tools/search.d.ts +30 -0
  130. package/dist/tools/skills.d.cts +26 -0
  131. package/dist/tools/skills.d.ts +26 -0
  132. package/dist/tools/view.d.cts +95 -0
  133. package/dist/tools/view.d.ts +95 -0
  134. package/dist/vector/effect-tools.d.cts +1 -1
  135. package/dist/vector/effect-tools.d.ts +1 -1
  136. package/dist/vector/index.cjs +13 -7
  137. package/dist/vector/index.js +8 -2
  138. package/dist/video-editor/effect-tools.d.cts +1 -1
  139. package/dist/video-editor/effect-tools.d.ts +1 -1
  140. package/dist/video-editor/index.cjs +275 -269
  141. package/dist/video-editor/index.js +8 -2
  142. package/dist/video-editor/tools.d.cts +1 -1
  143. package/dist/video-editor/tools.d.ts +1 -1
  144. package/package.json +31 -29
  145. package/skills/README.md +8 -3
  146. package/skills/pixerate-agent-tools/SKILL.md +33 -7
  147. package/skills/pixerate-animation-editor/SKILL.md +7 -0
  148. package/skills/pixerate-rich-text/SKILL.md +18 -4
  149. package/dist/chunk-5RRYDFU2.js +0 -466
  150. package/dist/chunk-SPVIXXIB.cjs +0 -466
  151. /package/dist/{chunk-SMJK5HBJ.js → chunk-K73HMKQP.js} +0 -0
  152. /package/dist/{chunk-DDF6WQ62.cjs → chunk-LACYURUW.cjs} +0 -0
@@ -343,7 +343,10 @@ function createEffectToolProvider(host) {
343
343
  ];
344
344
  return {
345
345
  id: host.id,
346
- ...host.namespace ? { namespace: host.namespace } : {},
346
+ ...host.namespace !== void 0 ? { namespace: host.namespace } : {},
347
+ ...host.title ? { title: host.title } : {},
348
+ ...host.description ? { description: host.description } : {},
349
+ ...host.skill ? { skill: host.skill } : {},
347
350
  tools: () => {
348
351
  const extra = _nullishCoalesce(_optionalChain([host, 'access', _5 => _5.extraTools, 'optionalCall', _6 => _6(context)]), () => ( []));
349
352
  if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access', _7 => _7.annotations, 'optionalAccess', _8 => _8.readOnlyHint]))];
@@ -287,7 +287,7 @@ var MCP_TOOL_CANVAS_LAYOUT = {
287
287
  name: "canvas_layout",
288
288
  title: "Lay out the canvas",
289
289
  annotations: { title: "Lay out the canvas", ...IDEMPOTENT_ANNOTATIONS },
290
- description: "Arranges the canvas graph automatically.",
290
+ description: "Arranges the canvas nodes automatically in a layered graph layout that follows the edges, so nodes line up and do not overlap. Nodes that already have a position stay put unless incremental is false.",
291
291
  inputSchema: {
292
292
  type: "object",
293
293
  properties: {
@@ -3,12 +3,41 @@ import {
3
3
  TOOL_BRIDGE_PROTOCOL,
4
4
  ToolRegistry,
5
5
  createMcpServer
6
- } from "./chunk-5RRYDFU2.js";
6
+ } from "./chunk-RB62U6MS.js";
7
7
 
8
8
  // src/bridge/index.ts
9
9
  import { createServer } from "http";
10
10
  import { createInterface } from "readline";
11
11
 
12
+ // src/bridge/skills.ts
13
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
14
+ import { dirname, join, relative, sep } from "path";
15
+ import { fileURLToPath } from "url";
16
+ function defaultSkillsDir() {
17
+ let dir = typeof __dirname === "string" ? __dirname : dirname(fileURLToPath(import.meta.url));
18
+ for (let i = 0; i < 5; i++) {
19
+ const candidate = join(dir, "skills");
20
+ if (existsSync(join(candidate, "pixerate-agent-tools", "SKILL.md"))) return candidate;
21
+ const parent = dirname(dir);
22
+ if (parent === dir) break;
23
+ dir = parent;
24
+ }
25
+ return null;
26
+ }
27
+ function loadSkillFiles(dir = defaultSkillsDir()) {
28
+ const files = {};
29
+ if (!dir || !existsSync(dir)) return files;
30
+ const walk = (current) => {
31
+ for (const name of readdirSync(current)) {
32
+ const path = join(current, name);
33
+ if (statSync(path).isDirectory()) walk(path);
34
+ else if (name.endsWith(".md") && current !== dir) files[relative(dir, path).split(sep).join("/")] = readFileSync(path, "utf8");
35
+ }
36
+ };
37
+ walk(dir);
38
+ return files;
39
+ }
40
+
12
41
  // src/bridge/websocket.ts
13
42
  import { createHash } from "crypto";
14
43
  var GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@@ -163,7 +192,8 @@ var EDITOR_ARG = {
163
192
  type: "string",
164
193
  description: 'Editor id (e.g. "e1") or part of its name, from list_editors. Default: the most recently active editor that has this tool.'
165
194
  };
166
- var BRIDGE_INSTRUCTIONS = "Tools come from editors open in a browser. Call list_editors to see them; when several are open, pass `editor` (an id or part of a name) to pick one, otherwise the most recently active editor that has the tool answers. If no editor is connected, ask the user to open the app and connect it to the bridge.";
195
+ var BRIDGE_INSTRUCTIONS = "Tools come from editors open in a browser. Call list_editors to see them; when several are open, pass `editor` (an id or part of a name) to pick one, otherwise the most recently active editor that has the tool answers. If no editor is connected, ask the user to open the app and connect it to the bridge. Tool names are `<toolset>__<tool>`; when an editor offers list_toolsets and search_tools, use them to find tools that are not listed yet.";
196
+ var SKILL_INSTRUCTIONS = "Each editor's tools are documented by an agent skill (pixerate-chart, pixerate-video-editor, ...), served here as MCP prompts and as resources at skill://<skill>/SKILL.md. Read pixerate-agent-tools and the skill for the editor at hand before working with its tools.";
167
197
  async function createToolBridge(options) {
168
198
  const log = options.log ?? ((message) => process.stderr.write(`[${options.name}] ${message}
169
199
  `));
@@ -251,6 +281,8 @@ async function createToolBridge(options) {
251
281
  };
252
282
  registry.register({
253
283
  id: "bridge",
284
+ // Forwarded tools keep the names their pages gave them.
285
+ namespace: "",
254
286
  tools: () => [listEditors, ...forwardedTools()],
255
287
  subscribe: (notify) => {
256
288
  listeners.add(notify);
@@ -347,10 +379,13 @@ async function createToolBridge(options) {
347
379
  let output = null;
348
380
  const write = (message) => output?.write(`${JSON.stringify(message)}
349
381
  `);
382
+ const skills = options.skills === false ? {} : options.skills ?? loadSkillFiles();
383
+ const hasSkills = Object.keys(skills).length > 0;
350
384
  const mcp = createMcpServer(registry, {
351
385
  name: options.name,
352
386
  version: options.version ?? "0.1.0",
353
- instructions: [options.instructions, BRIDGE_INSTRUCTIONS].filter(Boolean).join("\n\n"),
387
+ instructions: [options.instructions, BRIDGE_INSTRUCTIONS, hasSkills ? SKILL_INSTRUCTIONS : ""].filter(Boolean).join("\n\n"),
388
+ ...hasSkills ? { skills } : {},
354
389
  send: write
355
390
  });
356
391
  let lines = null;
@@ -395,6 +430,8 @@ async function createToolBridge(options) {
395
430
  }
396
431
 
397
432
  export {
433
+ defaultSkillsDir,
434
+ loadSkillFiles,
398
435
  isLocalOrigin,
399
436
  createToolBridge
400
437
  };
@@ -7,7 +7,10 @@ import {
7
7
  createReviewId,
8
8
  getTrackedChanges,
9
9
  resolveTrackedChanges
10
- } from "./chunk-HZZXBTLB.js";
10
+ } from "./chunk-6IN474P4.js";
11
+ import {
12
+ stripPrototypeKeys
13
+ } from "./chunk-HF5QZS7Z.js";
11
14
 
12
15
  // src/compare/diff.ts
13
16
  var EQUAL = 0;
@@ -286,7 +289,7 @@ function toNode(source, schema) {
286
289
  const node = source;
287
290
  return node.type.schema === schema ? node : schema.nodeFromJSON(node.toJSON());
288
291
  }
289
- return schema.nodeFromJSON(source);
292
+ return schema.nodeFromJSON(stripPrototypeKeys(source));
290
293
  }
291
294
  function newAttributes(ctx) {
292
295
  return {
@@ -7,7 +7,7 @@ var _chunkPY4GWSE2cjs = require('./chunk-PY4GWSE2.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunk3V746PF4cjs = require('./chunk-3V746PF4.cjs');
10
+ var _chunkRUZQMYXHcjs = require('./chunk-RUZQMYXH.cjs');
11
11
 
12
12
 
13
13
  var _chunkWOFXZ3XUcjs = require('./chunk-WOFXZ3XU.cjs');
@@ -1174,12 +1174,12 @@ function videoEffectLayerKey(layer, width, height) {
1174
1174
  }
1175
1175
  function mixEffectPixels(a, b, k) {
1176
1176
  if (k >= 1) return b;
1177
- const out = _chunk3V746PF4cjs.createEffectPixels.call(void 0, a.width, a.height);
1177
+ const out = _chunkRUZQMYXHcjs.createEffectPixels.call(void 0, a.width, a.height);
1178
1178
  for (let i = 0; i < out.data.length; i++) out.data[i] = a.data[i] + (b.data[i] - a.data[i]) * k;
1179
1179
  return out;
1180
1180
  }
1181
1181
  function overEffectPixels(base, top, opacity = 1) {
1182
- const out = _chunk3V746PF4cjs.createEffectPixels.call(void 0, base.width, base.height);
1182
+ const out = _chunkRUZQMYXHcjs.createEffectPixels.call(void 0, base.width, base.height);
1183
1183
  const o = out.data;
1184
1184
  const b = base.data;
1185
1185
  const t = top.data;
@@ -1224,7 +1224,7 @@ var VideoEffectsEngine = (_class2 = class {
1224
1224
  __init10() {this.generation = 0}
1225
1225
 
1226
1226
  constructor(options = {}) {;_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);
1227
- this.slot = _nullishCoalesce(options.slot, () => ( new (0, _chunk3V746PF4cjs.EffectsSlot)()));
1227
+ this.slot = _nullishCoalesce(options.slot, () => ( new (0, _chunkRUZQMYXHcjs.EffectsSlot)()));
1228
1228
  this.maxEntries = _nullishCoalesce(options.maxEntries, () => ( 120));
1229
1229
  this.toImage = _nullishCoalesce(options.toImage, () => ( defaultToImage));
1230
1230
  this.pool = new (0, _chunkPY4GWSE2cjs.EffectRendererPool)({ maxRenderers: options.maxRenderers });
@@ -1366,7 +1366,7 @@ function checkVideoEffectPlace(d, place) {
1366
1366
  if (d.kind === "motion" || !d.uses.some((u) => allowed.includes(u))) {
1367
1367
  const where = place === "clip" ? "on a clip" : place === "transition" ? "as a transition" : "as an effect clip";
1368
1368
  const instead = d.uses.includes("transition") ? "set_video_effect_transition" : d.uses.some((u) => VIDEO_EFFECT_PLACES.generator.includes(u)) ? "add_video_effect_clip" : d.uses.some((u) => u === "filter") ? "apply_effect" : null;
1369
- throw new (0, _chunk3V746PF4cjs.EffectUnsupportedError)(
1369
+ throw new (0, _chunkRUZQMYXHcjs.EffectUnsupportedError)(
1370
1370
  `"${d.id}" (${d.name}) is a ${d.uses.join(" / ")} effect and cannot be used ${where}, which takes ${allowed.join(" or ")} effects${instead ? `; use ${instead} instead` : ""}. search_effects with use "${allowed[0]}" lists ones that fit.`,
1371
1371
  d.id
1372
1372
  );
@@ -1387,12 +1387,12 @@ function checkVideoEffectValues(d, values, options = {}) {
1387
1387
  else if (type !== "number" && type !== "integer") errors.push({ path: `/${k}`, message: "only number controls can be keyframed." });
1388
1388
  else for (const [i, key] of v.keys.entries()) for (const e of _chunkWOFXZ3XUcjs.validateJsonSchema.call(void 0, key.v, schema)) errors.push({ path: `/${k}/keys/${i}/v`, message: e.message });
1389
1389
  }
1390
- for (const e of _chunk3V746PF4cjs.effectValueErrors.call(void 0, d, plain)) {
1390
+ for (const e of _chunkRUZQMYXHcjs.effectValueErrors.call(void 0, d, plain)) {
1391
1391
  const name = e.path.split("/")[1];
1392
1392
  const about = name && _optionalChain([d, 'access', _46 => _46.controls, 'access', _47 => _47.properties, 'access', _48 => _48[name], 'optionalAccess', _49 => _49.description]);
1393
1393
  errors.push(about ? { path: e.path, message: `${e.message} (${about})` } : e);
1394
1394
  }
1395
- if (errors.length) throw new (0, _chunk3V746PF4cjs.EffectControlError)(d.id, errors);
1395
+ if (errors.length) throw new (0, _chunkRUZQMYXHcjs.EffectControlError)(d.id, errors);
1396
1396
  return { ..._nullishCoalesce(options.base, () => ( d.defaults)), ..._nullishCoalesce(values, () => ( {})) };
1397
1397
  }
1398
1398
 
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  compareDocuments
3
- } from "./chunk-4LGWAJDI.js";
3
+ } from "./chunk-V5OOP74P.js";
4
4
  import {
5
5
  DEFAULT_STYLES,
6
6
  NORMAL_STYLE_ID,
7
7
  createStyleRegistry,
8
8
  isValidStyleId
9
- } from "./chunk-6I63VZ45.js";
9
+ } from "./chunk-CXXKJBQZ.js";
10
10
  import {
11
11
  CHART_OOXML_NS,
12
12
  chartFromOoxml
@@ -34,7 +34,7 @@ import {
34
34
  searchDocument,
35
35
  sliceContainsTable,
36
36
  syncInitialContent
37
- } from "./chunk-VRIR53SW.js";
37
+ } from "./chunk-6GAYGQDC.js";
38
38
  import {
39
39
  chartDataToTable
40
40
  } from "./chunk-RN767PO6.js";
@@ -46,20 +46,21 @@ import {
46
46
  rtfToPlainText,
47
47
  sanitizeImportedHtml,
48
48
  serializeRichClipboardPayload
49
- } from "./chunk-YTGF4TJR.js";
49
+ } from "./chunk-ZLZKGHSZ.js";
50
50
  import {
51
51
  escapeHtml,
52
52
  htmlToPlainText,
53
53
  markdownToTipTapHtml,
54
54
  plainTextToSlice
55
- } from "./chunk-SWZTQWY7.js";
55
+ } from "./chunk-2INPJDNY.js";
56
56
  import {
57
57
  CommentStore,
58
58
  TRACK_CHANGES_SKIP_META,
59
59
  TrackChanges,
60
60
  createReviewId,
61
+ safeMergeAttributes,
61
62
  trackChangesPluginKey
62
- } from "./chunk-HZZXBTLB.js";
63
+ } from "./chunk-6IN474P4.js";
63
64
  import {
64
65
  readZip
65
66
  } from "./chunk-CIQIM2IP.js";
@@ -409,7 +410,7 @@ var TemplateSuggestions = Extension2.create({
409
410
  });
410
411
 
411
412
  // src/extensions/loading-node.ts
412
- import { Node as Node2, mergeAttributes } from "@tiptap/core";
413
+ import { Node as Node2 } from "@tiptap/core";
413
414
  var LoadingNode = Node2.create({
414
415
  name: "loadingNode",
415
416
  group: "inline",
@@ -438,7 +439,7 @@ var LoadingNode = Node2.create({
438
439
  renderHTML({ HTMLAttributes }) {
439
440
  return [
440
441
  "span",
441
- mergeAttributes(HTMLAttributes, {
442
+ safeMergeAttributes(HTMLAttributes, {
442
443
  "data-type": "loading",
443
444
  class: "inline-flex items-center px-1.5 py-0.5 text-xs text-muted-foreground animate-pulse"
444
445
  }),
@@ -1870,7 +1871,7 @@ var Image2 = BaseImage.extend({
1870
1871
  });
1871
1872
 
1872
1873
  // src/extensions/comments.ts
1873
- import { Mark as Mark3, mergeAttributes as mergeAttributes2 } from "@tiptap/core";
1874
+ import { Mark as Mark3 } from "@tiptap/core";
1874
1875
  import { Plugin as Plugin6, PluginKey as PluginKey3, TextSelection } from "@tiptap/pm/state";
1875
1876
  import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "@tiptap/pm/view";
1876
1877
  var commentsPluginKey = new PluginKey3("comments");
@@ -1966,7 +1967,7 @@ var Comments = Mark3.create({
1966
1967
  return [{ tag: "span[data-comment-id]" }];
1967
1968
  },
1968
1969
  renderHTML({ HTMLAttributes }) {
1969
- return ["span", mergeAttributes2(this.options.HTMLAttributes, HTMLAttributes), 0];
1970
+ return ["span", safeMergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
1970
1971
  },
1971
1972
  addCommands() {
1972
1973
  const store = () => this.storage.store;
@@ -4383,7 +4384,7 @@ var Outline = Extension11.create({
4383
4384
  });
4384
4385
 
4385
4386
  // src/extensions/document-structure/table-of-contents.ts
4386
- import { Node as Node3, mergeAttributes as mergeAttributes3 } from "@tiptap/core";
4387
+ import { Node as Node3 } from "@tiptap/core";
4387
4388
  import {
4388
4389
  Plugin as Plugin11,
4389
4390
  PluginKey as PluginKey8,
@@ -4625,7 +4626,7 @@ var TableOfContents = Node3.create({
4625
4626
  ] : ["p", { class: "toc-empty" }, this.options.emptyText];
4626
4627
  return [
4627
4628
  "nav",
4628
- mergeAttributes3(this.options.HTMLAttributes, HTMLAttributes, {
4629
+ safeMergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
4629
4630
  "data-type": "table-of-contents",
4630
4631
  "aria-label": node.attrs.title || "Table of contents",
4631
4632
  class: "pixerate-toc"
@@ -4710,7 +4711,7 @@ var TableOfContents = Node3.create({
4710
4711
  });
4711
4712
 
4712
4713
  // src/extensions/document-structure/footnotes.ts
4713
- import { Node as Node4, mergeAttributes as mergeAttributes4 } from "@tiptap/core";
4714
+ import { Node as Node4 } from "@tiptap/core";
4714
4715
  import {
4715
4716
  NodeSelection,
4716
4717
  Plugin as Plugin12,
@@ -4879,7 +4880,7 @@ var FootnoteReference = Node4.create({
4879
4880
  const id = node.attrs.id;
4880
4881
  return [
4881
4882
  "sup",
4882
- mergeAttributes4(this.options.HTMLAttributes, HTMLAttributes, {
4883
+ safeMergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
4883
4884
  "data-type": "footnote-reference",
4884
4885
  class: "pixerate-footnote-ref",
4885
4886
  ...id ? { id: `fnref-${id}` } : {}
@@ -5028,7 +5029,7 @@ var Footnotes = Node4.create({
5028
5029
  renderHTML({ HTMLAttributes }) {
5029
5030
  return [
5030
5031
  "section",
5031
- mergeAttributes4(HTMLAttributes, {
5032
+ safeMergeAttributes(HTMLAttributes, {
5032
5033
  "data-type": "footnotes",
5033
5034
  class: "pixerate-footnotes",
5034
5035
  role: "doc-endnotes"
@@ -5080,7 +5081,7 @@ var Footnote = Node4.create({
5080
5081
  renderHTML({ HTMLAttributes }) {
5081
5082
  return [
5082
5083
  "li",
5083
- mergeAttributes4(HTMLAttributes, {
5084
+ safeMergeAttributes(HTMLAttributes, {
5084
5085
  "data-type": "footnote",
5085
5086
  class: "pixerate-footnote"
5086
5087
  }),
@@ -5103,7 +5104,7 @@ var Footnote = Node4.create({
5103
5104
  });
5104
5105
 
5105
5106
  // src/extensions/document-structure/bookmarks.ts
5106
- import { Mark as Mark4, mergeAttributes as mergeAttributes5 } from "@tiptap/core";
5107
+ import { Mark as Mark4 } from "@tiptap/core";
5107
5108
  import { TextSelection as TextSelection5 } from "@tiptap/pm/state";
5108
5109
  var BOOKMARK = "bookmark";
5109
5110
  function getBookmarks(doc) {
@@ -5172,7 +5173,7 @@ var Bookmark = Mark4.create({
5172
5173
  renderHTML({ HTMLAttributes }) {
5173
5174
  return [
5174
5175
  "span",
5175
- mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes, {
5176
+ safeMergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
5176
5177
  class: "pixerate-bookmark"
5177
5178
  }),
5178
5179
  0
@@ -5243,7 +5244,7 @@ var Bookmark = Mark4.create({
5243
5244
  });
5244
5245
 
5245
5246
  // src/extensions/document-structure/cross-reference.ts
5246
- import { Node as Node5, mergeAttributes as mergeAttributes6 } from "@tiptap/core";
5247
+ import { Node as Node5 } from "@tiptap/core";
5247
5248
  import {
5248
5249
  Plugin as Plugin13,
5249
5250
  PluginKey as PluginKey10,
@@ -5347,7 +5348,7 @@ var CrossReference = Node5.create({
5347
5348
  const href = !broken && targetType === "heading" && targetId ? { href: `#${targetId}` } : {};
5348
5349
  return [
5349
5350
  "a",
5350
- mergeAttributes6(this.options.HTMLAttributes, HTMLAttributes, href, {
5351
+ safeMergeAttributes(this.options.HTMLAttributes, HTMLAttributes, href, {
5351
5352
  "data-type": "cross-reference",
5352
5353
  class: broken ? "pixerate-cross-reference is-broken" : "pixerate-cross-reference"
5353
5354
  }),
@@ -5862,7 +5863,7 @@ function safeClipboard(get) {
5862
5863
  }
5863
5864
 
5864
5865
  // src/extensions/paragraph-styles/extension.ts
5865
- import { Extension as Extension13, Mark as Mark5, mergeAttributes as mergeAttributes7 } from "@tiptap/core";
5866
+ import { Extension as Extension13, Mark as Mark5 } from "@tiptap/core";
5866
5867
  import { Plugin as Plugin15, PluginKey as PluginKey12 } from "@tiptap/pm/state";
5867
5868
  var STYLE_ID_ATTRIBUTE = "styleId";
5868
5869
  var CHARACTER_STYLE_MARK_NAME = "characterStyle";
@@ -6024,7 +6025,7 @@ var CharacterStyle = Mark5.create({
6024
6025
  return [{ tag: "span[data-char-style]" }];
6025
6026
  },
6026
6027
  renderHTML({ HTMLAttributes }) {
6027
- return ["span", mergeAttributes7(HTMLAttributes), 0];
6028
+ return ["span", safeMergeAttributes(HTMLAttributes), 0];
6028
6029
  }
6029
6030
  });
6030
6031
  var ParagraphStyles = Extension13.create({
@@ -1,3 +1,8 @@
1
+ import {
2
+ isUnsafeJsonKey,
3
+ stripPrototypeKeys
4
+ } from "./chunk-HF5QZS7Z.js";
5
+
1
6
  // src/persistence/migrate.ts
2
7
  function hasLoadProblems(report) {
3
8
  return report.problems.length > 0 || report.readOnly !== null;
@@ -23,7 +28,7 @@ function toObject(json) {
23
28
  return void 0;
24
29
  }
25
30
  }
26
- return isObject(value) ? deepClone(value) : void 0;
31
+ return isObject(value) ? stripPrototypeKeys(deepClone(value)) : void 0;
27
32
  }
28
33
  function migrateDocument(json, options) {
29
34
  const versionKey = options.versionKey ?? "version";
@@ -106,7 +111,7 @@ function loadSections(doc, sections, options = {}) {
106
111
  }
107
112
  const unknown = {};
108
113
  for (const key of Object.keys(source)) {
109
- if (!(key in sections) && !ignore.has(key)) unknown[key] = source[key];
114
+ if (!(key in sections) && !ignore.has(key) && !isUnsafeJsonKey(key)) unknown[key] = source[key];
110
115
  }
111
116
  return { value, problems, unknown };
112
117
  }
@@ -287,7 +287,7 @@ var MCP_TOOL_CANVAS_LAYOUT = {
287
287
  name: "canvas_layout",
288
288
  title: "Lay out the canvas",
289
289
  annotations: { title: "Lay out the canvas", ...IDEMPOTENT_ANNOTATIONS },
290
- description: "Arranges the canvas graph automatically.",
290
+ description: "Arranges the canvas nodes automatically in a layered graph layout that follows the edges, so nodes line up and do not overlap. Nodes that already have a position stay put unless incremental is false.",
291
291
  inputSchema: {
292
292
  type: "object",
293
293
  properties: {
@@ -1,4 +1,8 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/extensions/paragraph-styles/registry.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
+
3
+ var _chunk2BSBFBOAcjs = require('./chunk-2BSBFBOA.cjs');
4
+
5
+ // src/extensions/paragraph-styles/registry.ts
2
6
  var MAX_CHAIN = 32;
3
7
  var STYLE_ID = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
4
8
  var UNSAFE_CSS = /[;{}<>\\]|\/\*|url\s*\(|expression\s*\(|@import|javascript:/i;
@@ -154,7 +158,7 @@ function overlay(base, patch) {
154
158
  if (!patch) return base;
155
159
  const out = { ...base };
156
160
  Object.entries(patch).forEach(([key, value]) => {
157
- if (value !== void 0 && value !== null) out[key] = value;
161
+ if (value !== void 0 && value !== null && !_chunk2BSBFBOAcjs.isUnsafeJsonKey.call(void 0, key)) out[key] = value;
158
162
  });
159
163
  return out;
160
164
  }
@@ -1,7 +1,10 @@
1
1
  import {
2
2
  escapeHtml,
3
3
  sanitizeHtml
4
- } from "./chunk-SWZTQWY7.js";
4
+ } from "./chunk-2INPJDNY.js";
5
+ import {
6
+ stripPrototypeKeys
7
+ } from "./chunk-HF5QZS7Z.js";
5
8
 
6
9
  // src/serializers/html.ts
7
10
  var DROP_WITH_CONTENT_REGEX = /<(script|style|template|noscript|iframe|object|embed|head|title|svg|math|textarea|select|button)\b[^>]*>[\s\S]*?<\/\1\s*>/gi;
@@ -263,7 +266,7 @@ function parseRichClipboardPayload(data, schema) {
263
266
  if (!payload || payload.version !== 1) return null;
264
267
  if (payload.schema !== getSchemaSignature(schema)) return null;
265
268
  if (!payload.slice) return null;
266
- return Slice.fromJSON(schema, payload.slice);
269
+ return Slice.fromJSON(schema, stripPrototypeKeys(payload.slice));
267
270
  } catch {
268
271
  return null;
269
272
  }
@@ -5,7 +5,7 @@ import {
5
5
  DEFAULT_STYLES,
6
6
  NORMAL_STYLE_ID,
7
7
  isValidStyleId
8
- } from "./chunk-6I63VZ45.js";
8
+ } from "./chunk-CXXKJBQZ.js";
9
9
  import {
10
10
  CHART_OOXML_CONTENT_TYPE,
11
11
  CHART_OOXML_NS,
@@ -3,7 +3,7 @@ import type { CommandRegistry } from './registry.cjs';
3
3
  export interface CommandToolProviderOptions<TContext = any> {
4
4
  /** Provider id (default `commands`). */
5
5
  id?: string;
6
- /** Always prefix the tool names with `<namespace>__`. */
6
+ /** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
7
7
  namespace?: string;
8
8
  /** Context for enablement and runs (default: the registry's). */
9
9
  context?: TContext | (() => TContext);
@@ -3,7 +3,7 @@ import type { CommandRegistry } from './registry.js';
3
3
  export interface CommandToolProviderOptions<TContext = any> {
4
4
  /** Provider id (default `commands`). */
5
5
  id?: string;
6
- /** Always prefix the tool names with `<namespace>__`. */
6
+ /** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
7
7
  namespace?: string;
8
8
  /** Context for enablement and runs (default: the registry's). */
9
9
  context?: TContext | (() => TContext);
@@ -768,6 +768,9 @@ function createCommandToolProvider(registry, options = {}) {
768
768
  return {
769
769
  id: _nullishCoalesce(options.id, () => ( "commands")),
770
770
  namespace: options.namespace,
771
+ title: "Commands",
772
+ description: "The app's commands (menu and keyboard actions) with their params schemas: list them, run one, or run several as one undo step.",
773
+ skill: "pixerate-agent-tools",
771
774
  tools: () => [listCommands, runCommandTool(), runCommands],
772
775
  subscribe: (notify) => registry.subscribe(notify)
773
776
  };
@@ -768,6 +768,9 @@ function createCommandToolProvider(registry, options = {}) {
768
768
  return {
769
769
  id: options.id ?? "commands",
770
770
  namespace: options.namespace,
771
+ title: "Commands",
772
+ description: "The app's commands (menu and keyboard actions) with their params schemas: list them, run one, or run several as one undo step.",
773
+ skill: "pixerate-agent-tools",
771
774
  tools: () => [listCommands, runCommandTool(), runCommands],
772
775
  subscribe: (notify) => registry.subscribe(notify)
773
776
  };
@@ -4,11 +4,12 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkS7I3RI5Zcjs = require('../chunk-S7I3RI5Z.cjs');
8
- require('../chunk-CCKP4XAN.cjs');
7
+ var _chunkHMGWFXECcjs = require('../chunk-HMGWFXEC.cjs');
8
+ require('../chunk-34RQAGWI.cjs');
9
+ require('../chunk-2BSBFBOA.cjs');
9
10
 
10
11
 
11
12
 
12
13
 
13
14
 
14
- exports.compareDocuments = _chunkS7I3RI5Zcjs.compareDocuments; exports.compareHtml = _chunkS7I3RI5Zcjs.compareHtml; exports.diffChanges = _chunkS7I3RI5Zcjs.diffChanges; exports.diffSequences = _chunkS7I3RI5Zcjs.diffSequences;
15
+ exports.compareDocuments = _chunkHMGWFXECcjs.compareDocuments; exports.compareHtml = _chunkHMGWFXECcjs.compareHtml; exports.diffChanges = _chunkHMGWFXECcjs.diffChanges; exports.diffSequences = _chunkHMGWFXECcjs.diffSequences;
@@ -4,8 +4,9 @@ import {
4
4
  compareHtml,
5
5
  diffChanges,
6
6
  diffSequences
7
- } from "../chunk-4LGWAJDI.js";
8
- import "../chunk-HZZXBTLB.js";
7
+ } from "../chunk-V5OOP74P.js";
8
+ import "../chunk-6IN474P4.js";
9
+ import "../chunk-HF5QZS7Z.js";
9
10
  export {
10
11
  compareDocuments,
11
12
  compareHtml,
@@ -2076,6 +2076,9 @@ function createDiagramToolProvider(controller, options = {}) {
2076
2076
  return {
2077
2077
  id: _nullishCoalesce(options.id, () => ( "diagram")),
2078
2078
  namespace: options.namespace,
2079
+ title: "Diagram editor",
2080
+ description: "Mermaid diagrams: nodes, edges and groups, shapes and styles, direction and layout, Mermaid import and export, rendering.",
2081
+ skill: "pixerate-diagram",
2079
2082
  tools: () => readOnlyReason() ? reads : [...reads, ...writes],
2080
2083
  subscribe: (notify) => {
2081
2084
  let last = readOnlyReason();
@@ -2076,6 +2076,9 @@ function createDiagramToolProvider(controller, options = {}) {
2076
2076
  return {
2077
2077
  id: options.id ?? "diagram",
2078
2078
  namespace: options.namespace,
2079
+ title: "Diagram editor",
2080
+ description: "Mermaid diagrams: nodes, edges and groups, shapes and styles, direction and layout, Mermaid import and export, rendering.",
2081
+ skill: "pixerate-diagram",
2079
2082
  tools: () => readOnlyReason() ? reads : [...reads, ...writes],
2080
2083
  subscribe: (notify) => {
2081
2084
  let last = readOnlyReason();
@@ -6,7 +6,7 @@ import { type MermaidDocument, type Point } from './types.cjs';
6
6
  export interface DiagramToolProviderOptions {
7
7
  /** Provider id (unique per registry). Default `diagram`. */
8
8
  id?: string;
9
- /** Always prefix tool names with `<namespace>__`. */
9
+ /** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
10
10
  namespace?: string;
11
11
  /**
12
12
  * The diagram cannot be edited: write tools are hidden and `get_diagram` says why. A
@@ -6,7 +6,7 @@ import { type MermaidDocument, type Point } from './types.js';
6
6
  export interface DiagramToolProviderOptions {
7
7
  /** Provider id (unique per registry). Default `diagram`. */
8
8
  id?: string;
9
- /** Always prefix tool names with `<namespace>__`. */
9
+ /** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
10
10
  namespace?: string;
11
11
  /**
12
12
  * The diagram cannot be edited: write tools are hidden and `get_diagram` says why. A