@pixerate/editor 0.141.0 → 0.142.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 (67) hide show
  1. package/dist/agent/index.cjs +33 -14
  2. package/dist/agent/index.js +24 -5
  3. package/dist/agent/providers.d.cts +4 -1
  4. package/dist/agent/providers.d.ts +4 -1
  5. package/dist/animation-editor/index.cjs +69 -19
  6. package/dist/animation-editor/index.d.cts +1 -0
  7. package/dist/animation-editor/index.d.ts +1 -0
  8. package/dist/animation-editor/index.js +54 -4
  9. package/dist/animation-editor/playback.d.cts +10 -0
  10. package/dist/animation-editor/playback.d.ts +10 -0
  11. package/dist/chart/index.cjs +254 -170
  12. package/dist/chart/index.d.cts +1 -0
  13. package/dist/chart/index.d.ts +1 -0
  14. package/dist/chart/index.js +243 -159
  15. package/dist/chart/playback.d.cts +22 -0
  16. package/dist/chart/playback.d.ts +22 -0
  17. package/dist/{chunk-MFFE55CS.js → chunk-54GVEVXS.js} +6 -4
  18. package/dist/{chunk-E747F3D5.js → chunk-CC6WKVIH.js} +86 -5
  19. package/dist/{chunk-VTY64I6H.cjs → chunk-QSM3MDDJ.cjs} +85 -85
  20. package/dist/{chunk-2RUNJYOX.cjs → chunk-QZFEX2N4.cjs} +86 -5
  21. package/dist/{chunk-LMSFXRAJ.js → chunk-VGJTUCWM.js} +1 -1
  22. package/dist/{chunk-6SFREX6H.cjs → chunk-X2HQP7DF.cjs} +6 -4
  23. package/dist/chunk-XH32BATE.cjs +68 -0
  24. package/dist/chunk-Y6SGC6KO.js +68 -0
  25. package/dist/commands/index.cjs +2 -2
  26. package/dist/commands/index.js +1 -1
  27. package/dist/index.cjs +7 -3
  28. package/dist/index.js +6 -2
  29. package/dist/paint-editor/index.cjs +67 -19
  30. package/dist/paint-editor/index.d.cts +1 -0
  31. package/dist/paint-editor/index.d.ts +1 -0
  32. package/dist/paint-editor/index.js +67 -19
  33. package/dist/paint-editor/playback.d.cts +16 -0
  34. package/dist/paint-editor/playback.d.ts +16 -0
  35. package/dist/parameters/index.cjs +32 -8
  36. package/dist/parameters/index.d.cts +1 -0
  37. package/dist/parameters/index.d.ts +1 -0
  38. package/dist/parameters/index.js +28 -4
  39. package/dist/parameters/playback.d.cts +10 -0
  40. package/dist/parameters/playback.d.ts +10 -0
  41. package/dist/spreadsheet/index.cjs +7 -3
  42. package/dist/spreadsheet/index.d.cts +1 -0
  43. package/dist/spreadsheet/index.d.ts +1 -0
  44. package/dist/spreadsheet/index.js +6 -2
  45. package/dist/spreadsheet/playback.d.cts +15 -0
  46. package/dist/spreadsheet/playback.d.ts +15 -0
  47. package/dist/tools/index.cjs +10 -3
  48. package/dist/tools/index.d.cts +1 -0
  49. package/dist/tools/index.d.ts +1 -0
  50. package/dist/tools/index.js +9 -2
  51. package/dist/tools/script.d.cts +77 -0
  52. package/dist/tools/script.d.ts +77 -0
  53. package/dist/video-editor/index.cjs +81 -28
  54. package/dist/video-editor/index.d.cts +1 -0
  55. package/dist/video-editor/index.d.ts +1 -0
  56. package/dist/video-editor/index.js +58 -5
  57. package/dist/video-editor/playback.d.cts +20 -0
  58. package/dist/video-editor/playback.d.ts +20 -0
  59. package/package.json +1 -1
  60. package/skills/pixerate-animation-editor/SKILL.md +1 -0
  61. package/skills/pixerate-chart/SKILL.md +1 -0
  62. package/skills/pixerate-paint-editor/SKILL.md +1 -0
  63. package/skills/pixerate-parameters/SKILL.md +1 -0
  64. package/skills/pixerate-spreadsheet/SKILL.md +1 -0
  65. package/skills/pixerate-video-editor/SKILL.md +1 -0
  66. package/dist/chunk-PLKIYNJZ.js +0 -0
  67. package/dist/chunk-TNCWKC5M.cjs +0 -1
@@ -14,7 +14,11 @@ var _chunkGLQQ2VILcjs = require('../chunk-GLQQ2VIL.cjs');
14
14
 
15
15
  var _chunkUBRYHNRUcjs = require('../chunk-UBRYHNRU.cjs');
16
16
  require('../chunk-4EFNS2HV.cjs');
17
- require('../chunk-TNCWKC5M.cjs');
17
+
18
+
19
+
20
+
21
+ var _chunkXH32BATEcjs = require('../chunk-XH32BATE.cjs');
18
22
 
19
23
 
20
24
 
@@ -49,7 +53,7 @@ var _chunkY4BWZB6Jcjs = require('../chunk-Y4BWZB6J.cjs');
49
53
 
50
54
 
51
55
 
52
- var _chunk6SFREX6Hcjs = require('../chunk-6SFREX6H.cjs');
56
+ var _chunkX2HQP7DFcjs = require('../chunk-X2HQP7DF.cjs');
53
57
 
54
58
 
55
59
 
@@ -132,7 +136,8 @@ var _chunk2BSBFBOAcjs = require('../chunk-2BSBFBOA.cjs');
132
136
 
133
137
 
134
138
 
135
- var _chunk2RUNJYOXcjs = require('../chunk-2RUNJYOX.cjs');
139
+
140
+ var _chunkQZFEX2N4cjs = require('../chunk-QZFEX2N4.cjs');
136
141
 
137
142
 
138
143
 
@@ -540,7 +545,7 @@ function planCanvasPlaybackSteps(steps, nodes, rectOptions) {
540
545
  const node = placed.get(id);
541
546
  if (node) placed.set(id, { ...node, position });
542
547
  }
543
- const rect = _chunk6SFREX6Hcjs.unionRects.call(void 0, moved.map(([id]) => rectOf(id)));
548
+ const rect = _chunkX2HQP7DFcjs.unionRects.call(void 0, moved.map(([id]) => rectOf(id)));
544
549
  if (rect) after.push({ type: "move", to: centre(rect) }, { type: "focus", rect }, { type: "wait", ms: 450 });
545
550
  break;
546
551
  }
@@ -1165,6 +1170,13 @@ function findMatches(editor, query, args, replacement) {
1165
1170
  function createRichTextToolProvider(target, options) {
1166
1171
  const editor = () => toEditor(target);
1167
1172
  const charts = createDocumentChartTools(editor);
1173
+ const withCaret = (tool) => tool.name !== "insert_chart" ? tool : {
1174
+ ...tool,
1175
+ handler: (args, context) => {
1176
+ if (typeof args.at === "number") presence.show(args.at);
1177
+ return tool.handler(args, context);
1178
+ }
1179
+ };
1168
1180
  const presence = createTextPresence(editor, options.id, options.presence);
1169
1181
  const formatting = createDocumentFormatTools(editor, (ranges) => presence.changed(ranges.filter((r) => r.from < r.to)));
1170
1182
  const getText = {
@@ -1466,7 +1478,7 @@ function createRichTextToolProvider(target, options) {
1466
1478
  if (!ed || ed.isDestroyed) return [];
1467
1479
  if (!ed.isEditable) return [getText, findText, ...charts.read()];
1468
1480
  const tools = [getText, findText, insertText, replaceText, replaceRange, replaceSelection, setSelection, ...formatting.tools(ed)];
1469
- return [...tools, ..._chunkL434J57Vcjs.isTableEnabled.call(void 0, ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
1481
+ return [...tools, ..._chunkL434J57Vcjs.isTableEnabled.call(void 0, ed) ? [editTable] : [], ...charts.read(), ...charts.write().map(withCaret)];
1470
1482
  },
1471
1483
  subscribe: (notify) => {
1472
1484
  const ed = editor();
@@ -1496,7 +1508,7 @@ function parseRange(ref) {
1496
1508
  if (extra !== void 0) throw new Error(`Invalid range "${ref}". Use A1 notation, e.g. "A1:C5".`);
1497
1509
  const start = parseCell(startRef);
1498
1510
  const end = parseCell(endRef);
1499
- return _chunk2RUNJYOXcjs.normalizeRange.call(void 0, { startRow: start.row, startCol: start.col, endRow: end.row, endCol: end.col });
1511
+ return _chunkQZFEX2N4cjs.normalizeRange.call(void 0, { startRow: start.row, startCol: start.col, endRow: end.row, endCol: end.col });
1500
1512
  }
1501
1513
  var formatRange = (r) => `${_chunk55AKPTLMcjs.indexToColName.call(void 0, r.startCol)}${r.startRow + 1}:${_chunk55AKPTLMcjs.indexToColName.call(void 0, r.endCol)}${r.endRow + 1}`;
1502
1514
  var CELL_INPUT = { type: ["string", "number", "boolean", "null"] };
@@ -1558,7 +1570,7 @@ function createSpreadsheetToolProvider(controller, options) {
1558
1570
  values,
1559
1571
  raw,
1560
1572
  errors,
1561
- merges: controller.getMerges().filter((m) => _chunk2RUNJYOXcjs.rangesIntersect.call(void 0, m, read)).map(formatRange),
1573
+ merges: controller.getMerges().filter((m) => _chunkQZFEX2N4cjs.rangesIntersect.call(void 0, m, read)).map(formatRange),
1562
1574
  sheet: { rows: rowCount, columns: colCount }
1563
1575
  };
1564
1576
  }
@@ -1753,8 +1765,8 @@ function createSpreadsheetToolProvider(controller, options) {
1753
1765
  ({ range }) => {
1754
1766
  const r = parseRange(range);
1755
1767
  inSheet(r, range);
1756
- if (_chunk2RUNJYOXcjs.isSingleCellRange.call(void 0, r)) throw new Error(`${range} is a single cell; give a range of at least two cells.`);
1757
- const partial = controller.getMerges().find((m) => _chunk2RUNJYOXcjs.rangesIntersect.call(void 0, m, r) && !_chunk2RUNJYOXcjs.rangeContainsRange.call(void 0, r, m));
1768
+ if (_chunkQZFEX2N4cjs.isSingleCellRange.call(void 0, r)) throw new Error(`${range} is a single cell; give a range of at least two cells.`);
1769
+ const partial = controller.getMerges().find((m) => _chunkQZFEX2N4cjs.rangesIntersect.call(void 0, m, r) && !_chunkQZFEX2N4cjs.rangeContainsRange.call(void 0, r, m));
1758
1770
  if (partial) throw new Error(`${range} partly overlaps the merged range ${formatRange(partial)}; include all of it or unmerge it first.`);
1759
1771
  const readOnly = readOnlyIn(r);
1760
1772
  if (readOnly.length) throw new Error(`Read-only cells: ${readOnly.slice(0, 20).join(", ")}. Nothing was merged.`);
@@ -1779,7 +1791,7 @@ function createSpreadsheetToolProvider(controller, options) {
1779
1791
  false,
1780
1792
  ({ range }) => {
1781
1793
  const r = parseRange(range);
1782
- const touched = controller.getMerges().filter((m) => _chunk2RUNJYOXcjs.rangesIntersect.call(void 0, m, r));
1794
+ const touched = controller.getMerges().filter((m) => _chunkQZFEX2N4cjs.rangesIntersect.call(void 0, m, r));
1783
1795
  if (!touched.length) throw new Error(`No merged cells in ${range}. get_range lists the merges in a range.`);
1784
1796
  controller.unmergeCells(r);
1785
1797
  return { unmerged: touched.map(formatRange) };
@@ -1795,14 +1807,14 @@ function createSpreadsheetToolProvider(controller, options) {
1795
1807
  ({ range }) => {
1796
1808
  const s = parseRange(range);
1797
1809
  inSheet(s, range);
1798
- if (_chunk2RUNJYOXcjs.isSingleCellRange.call(void 0, s)) throw new Error(`${range} is a single cell; give a range of at least two cells.`);
1810
+ if (_chunkQZFEX2N4cjs.isSingleCellRange.call(void 0, s)) throw new Error(`${range} is a single cell; give a range of at least two cells.`);
1799
1811
  const t = {
1800
1812
  startRow: s.startRow,
1801
1813
  startCol: s.startCol,
1802
1814
  endRow: s.startRow + (s.endCol - s.startCol),
1803
1815
  endCol: s.startCol + (s.endRow - s.startRow)
1804
1816
  };
1805
- const merge = controller.getMerges().find((m) => _chunk2RUNJYOXcjs.rangesIntersect.call(void 0, m, s) || _chunk2RUNJYOXcjs.rangesIntersect.call(void 0, m, t));
1817
+ const merge = controller.getMerges().find((m) => _chunkQZFEX2N4cjs.rangesIntersect.call(void 0, m, s) || _chunkQZFEX2N4cjs.rangesIntersect.call(void 0, m, t));
1806
1818
  if (merge) throw new Error(`Cannot transpose ${range}: the merged range ${formatRange(merge)} is in the way; unmerge it first.`);
1807
1819
  const readOnly = [.../* @__PURE__ */ new Set([...readOnlyIn(s), ...readOnlyIn(t)])];
1808
1820
  if (readOnly.length) throw new Error(`Read-only cells: ${readOnly.slice(0, 20).join(", ")}. Nothing was transposed.`);
@@ -1816,7 +1828,11 @@ function createSpreadsheetToolProvider(controller, options) {
1816
1828
  title: "Spreadsheet",
1817
1829
  description: "A spreadsheet: read and set cells and ranges, insert and delete rows and columns, merge and transpose.",
1818
1830
  skill: "pixerate-spreadsheet",
1819
- tools: [getRange, setCell, setRange, insertRows, deleteRows, insertColumns, deleteColumns, mergeCells, unmergeCells, transposeRange]
1831
+ // Agent playback: `<SpreadsheetEditor playback>` attaches as `spreadsheet` and finds the cells.
1832
+ playbackSurface: _nullishCoalesce(options.playbackSurface, () => ( "spreadsheet")),
1833
+ tools: [getRange, setCell, setRange, insertRows, deleteRows, insertColumns, deleteColumns, mergeCells, unmergeCells, transposeRange].map(
1834
+ (tool) => ({ ...tool, plan: (args) => _chunkQZFEX2N4cjs.planSpreadsheetToolPlayback.call(void 0, tool.name, args) })
1835
+ )
1820
1836
  };
1821
1837
  }
1822
1838
  function missingArgumentsMessage(name, args) {
@@ -2186,4 +2202,7 @@ function createCanvasComponentToolProvider(controller, options = { id: "canvas-c
2186
2202
 
2187
2203
 
2188
2204
 
2189
- exports.AgentPlayback = _chunk6SFREX6Hcjs.AgentPlayback; exports.CAPTURE_EXCLUDE_SELECTOR = _chunkSVFEVKLFcjs.CAPTURE_EXCLUDE_SELECTOR; exports.CAPTURE_OVERLAY_SELECTORS = _chunkSVFEVKLFcjs.CAPTURE_OVERLAY_SELECTORS; exports.EDITOR_CANVAS_TOOLS = _chunkSVFEVKLFcjs.EDITOR_CANVAS_TOOLS; exports.EDITOR_MCP_TOOLS = _chunkSVFEVKLFcjs.EDITOR_MCP_TOOLS; exports.EDITOR_PROMPT_TOOLS = _chunkSVFEVKLFcjs.EDITOR_PROMPT_TOOLS; exports.EDIT_OPERATION_REQUIRED_ARGUMENTS = _chunkSVFEVKLFcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS; exports.EXPORT_EXCLUDED_SELECTORS = _chunkSVFEVKLFcjs.EXPORT_EXCLUDED_SELECTORS; exports.JSON_RPC_ERRORS = _chunkY4BWZB6Jcjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkY4BWZB6Jcjs.MCP_PROTOCOL_VERSIONS; exports.MCP_TOOL_CANVAS_ADD_NODE = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_ADD_NODE; exports.MCP_TOOL_CANVAS_CONNECT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_CONNECT; exports.MCP_TOOL_CANVAS_HIGHLIGHT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_HIGHLIGHT; exports.MCP_TOOL_CANVAS_LAYOUT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_LAYOUT; exports.MCP_TOOL_CANVAS_REMOVE_NODES = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_REMOVE_NODES; exports.MCP_TOOL_CANVAS_SELECT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_SELECT; exports.MCP_TOOL_CANVAS_UPDATE_NODE = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_UPDATE_NODE; exports.MCP_TOOL_EDIT_CANVAS = _chunkSVFEVKLFcjs.MCP_TOOL_EDIT_CANVAS; exports.MCP_TOOL_EDIT_PROMPT = _chunkSVFEVKLFcjs.MCP_TOOL_EDIT_PROMPT; exports.MCP_TOOL_GET_EDITOR_STATE = _chunkSVFEVKLFcjs.MCP_TOOL_GET_EDITOR_STATE; exports.MCP_TOOL_PROMPT_INSERT_TEXT = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_INSERT_TEXT; exports.MCP_TOOL_PROMPT_REPLACE_RANGE = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_REPLACE_RANGE; exports.MCP_TOOL_PROMPT_SELECT = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_SELECT; exports.MCP_TOOL_PROMPT_SET_VARIABLE = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_SET_VARIABLE; exports.MCP_TOOL_VIEW_EDITOR = _chunkSVFEVKLFcjs.MCP_TOOL_VIEW_EDITOR; exports.PRESENCE_COLORS = _chunkUJGAA6AKcjs.PRESENCE_COLORS; exports.PerformanceQueue = _chunkUJGAA6AKcjs.PerformanceQueue; exports.PresenceStore = _chunkUJGAA6AKcjs.PresenceStore; exports.TOOL_BRIDGE_DEFAULT_PORT = _chunkY4BWZB6Jcjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkY4BWZB6Jcjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_DISCOVERY_TOOLS = _chunkY4BWZB6Jcjs.TOOL_DISCOVERY_TOOLS; exports.TOOL_NAMESPACE_SEPARATOR = _chunkY4BWZB6Jcjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkY4BWZB6Jcjs.ToolRegistry; exports.ToolRegistryError = _chunkY4BWZB6Jcjs.ToolRegistryError; exports.ToolRegistryView = _chunkY4BWZB6Jcjs.ToolRegistryView; exports.UNSAFE_JSON_KEYS = _chunk2BSBFBOAcjs.UNSAFE_JSON_KEYS; exports.baseToolName = _chunkY4BWZB6Jcjs.baseToolName; exports.captureInputSchema = _chunkN2FGYZ4Qcjs.captureInputSchema; exports.captureOutputSize = _chunkN2FGYZ4Qcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkSVFEVKLFcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkY4BWZB6Jcjs.connectToolBridge; exports.createAgentPlayback = _chunk6SFREX6Hcjs.createAgentPlayback; exports.createCanvasComponentToolProvider = createCanvasComponentToolProvider; exports.createCaptureTool = _chunkN2FGYZ4Qcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkN2FGYZ4Qcjs.createCaptureToolProvider; exports.createDocumentChartTools = createDocumentChartTools; exports.createEditorMcpToolProvider = createEditorMcpToolProvider; exports.createElementCaptureSurface = _chunkSVFEVKLFcjs.createElementCaptureSurface; exports.createInstantPresenceClock = _chunkUJGAA6AKcjs.createInstantPresenceClock; exports.createMcpServer = _chunkY4BWZB6Jcjs.createMcpServer; exports.createRichTextToolProvider = createRichTextToolProvider; exports.createSpreadsheetToolProvider = createSpreadsheetToolProvider; exports.createToolRegistry = _chunkY4BWZB6Jcjs.createToolRegistry; exports.derivePlaybackSteps = _chunk6SFREX6Hcjs.derivePlaybackSteps; exports.elementToSvg = _chunkSVFEVKLFcjs.elementToSvg; exports.errorResult = _chunkY4BWZB6Jcjs.errorResult; exports.isUnsafeJsonKey = _chunk2BSBFBOAcjs.isUnsafeJsonKey; exports.listSkills = _chunkY4BWZB6Jcjs.listSkills; exports.normalizeSide = normalizeSide; exports.parseSkillFrontmatter = _chunkY4BWZB6Jcjs.parseSkillFrontmatter; exports.planAgentCommand = planAgentCommand; exports.planCanvasPlaybackSteps = planCanvasPlaybackSteps; exports.planCanvasToolPlayback = planCanvasToolPlayback; exports.planToolCall = planToolCall; exports.playbackRefsFromArgs = _chunk6SFREX6Hcjs.playbackRefsFromArgs; exports.playbackRefsFromResult = _chunk6SFREX6Hcjs.playbackRefsFromResult; exports.rasterizeElement = _chunkSVFEVKLFcjs.rasterizeElement; exports.readSkillFile = _chunkY4BWZB6Jcjs.readSkillFile; exports.readingTime = _chunk6SFREX6Hcjs.readingTime; exports.realPresenceClock = _chunkUJGAA6AKcjs.realPresenceClock; exports.resolveCaptureRequest = _chunkN2FGYZ4Qcjs.resolveCaptureRequest; exports.searchTokens = _chunkY4BWZB6Jcjs.searchTokens; exports.searchTools = _chunkY4BWZB6Jcjs.searchTools; exports.stripPrototypeKeys = _chunk2BSBFBOAcjs.stripPrototypeKeys; exports.summarize = _chunkY4BWZB6Jcjs.summarize; exports.toCapturedImageData = _chunkN2FGYZ4Qcjs.toCapturedImageData; exports.toToolResult = _chunkY4BWZB6Jcjs.toToolResult; exports.toolCallToAgentCommand = toolCallToAgentCommand; exports.toolsetInstructions = _chunkY4BWZB6Jcjs.toolsetInstructions; exports.toolsetName = _chunkY4BWZB6Jcjs.toolsetName; exports.tweenPresenceCursor = _chunkUJGAA6AKcjs.tweenPresenceCursor; exports.unionCaptureRects = _chunkN2FGYZ4Qcjs.unionCaptureRects; exports.unionRects = _chunk6SFREX6Hcjs.unionRects; exports.unknownToolMessage = _chunkY4BWZB6Jcjs.unknownToolMessage; exports.validateAgentCommand = validateAgentCommand; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;
2205
+
2206
+
2207
+
2208
+ exports.AgentPlayback = _chunkX2HQP7DFcjs.AgentPlayback; exports.CAPTURE_EXCLUDE_SELECTOR = _chunkSVFEVKLFcjs.CAPTURE_EXCLUDE_SELECTOR; exports.CAPTURE_OVERLAY_SELECTORS = _chunkSVFEVKLFcjs.CAPTURE_OVERLAY_SELECTORS; exports.EDITOR_CANVAS_TOOLS = _chunkSVFEVKLFcjs.EDITOR_CANVAS_TOOLS; exports.EDITOR_MCP_TOOLS = _chunkSVFEVKLFcjs.EDITOR_MCP_TOOLS; exports.EDITOR_PROMPT_TOOLS = _chunkSVFEVKLFcjs.EDITOR_PROMPT_TOOLS; exports.EDIT_OPERATION_REQUIRED_ARGUMENTS = _chunkSVFEVKLFcjs.EDIT_OPERATION_REQUIRED_ARGUMENTS; exports.EXPORT_EXCLUDED_SELECTORS = _chunkSVFEVKLFcjs.EXPORT_EXCLUDED_SELECTORS; exports.JSON_RPC_ERRORS = _chunkY4BWZB6Jcjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkY4BWZB6Jcjs.MCP_PROTOCOL_VERSIONS; exports.MCP_TOOL_CANVAS_ADD_NODE = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_ADD_NODE; exports.MCP_TOOL_CANVAS_CONNECT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_CONNECT; exports.MCP_TOOL_CANVAS_HIGHLIGHT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_HIGHLIGHT; exports.MCP_TOOL_CANVAS_LAYOUT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_LAYOUT; exports.MCP_TOOL_CANVAS_REMOVE_NODES = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_REMOVE_NODES; exports.MCP_TOOL_CANVAS_SELECT = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_SELECT; exports.MCP_TOOL_CANVAS_UPDATE_NODE = _chunkSVFEVKLFcjs.MCP_TOOL_CANVAS_UPDATE_NODE; exports.MCP_TOOL_EDIT_CANVAS = _chunkSVFEVKLFcjs.MCP_TOOL_EDIT_CANVAS; exports.MCP_TOOL_EDIT_PROMPT = _chunkSVFEVKLFcjs.MCP_TOOL_EDIT_PROMPT; exports.MCP_TOOL_GET_EDITOR_STATE = _chunkSVFEVKLFcjs.MCP_TOOL_GET_EDITOR_STATE; exports.MCP_TOOL_PROMPT_INSERT_TEXT = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_INSERT_TEXT; exports.MCP_TOOL_PROMPT_REPLACE_RANGE = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_REPLACE_RANGE; exports.MCP_TOOL_PROMPT_SELECT = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_SELECT; exports.MCP_TOOL_PROMPT_SET_VARIABLE = _chunkSVFEVKLFcjs.MCP_TOOL_PROMPT_SET_VARIABLE; exports.MCP_TOOL_VIEW_EDITOR = _chunkSVFEVKLFcjs.MCP_TOOL_VIEW_EDITOR; exports.PRESENCE_COLORS = _chunkUJGAA6AKcjs.PRESENCE_COLORS; exports.PerformanceQueue = _chunkUJGAA6AKcjs.PerformanceQueue; exports.PresenceStore = _chunkUJGAA6AKcjs.PresenceStore; exports.TOOL_BRIDGE_DEFAULT_PORT = _chunkY4BWZB6Jcjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkY4BWZB6Jcjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_DISCOVERY_TOOLS = _chunkY4BWZB6Jcjs.TOOL_DISCOVERY_TOOLS; exports.TOOL_NAMESPACE_SEPARATOR = _chunkY4BWZB6Jcjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkY4BWZB6Jcjs.ToolRegistry; exports.ToolRegistryError = _chunkY4BWZB6Jcjs.ToolRegistryError; exports.ToolRegistryView = _chunkY4BWZB6Jcjs.ToolRegistryView; exports.UNSAFE_JSON_KEYS = _chunk2BSBFBOAcjs.UNSAFE_JSON_KEYS; exports.baseToolName = _chunkY4BWZB6Jcjs.baseToolName; exports.captureInputSchema = _chunkN2FGYZ4Qcjs.captureInputSchema; exports.captureOutputSize = _chunkN2FGYZ4Qcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkSVFEVKLFcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkY4BWZB6Jcjs.connectToolBridge; exports.createAgentPlayback = _chunkX2HQP7DFcjs.createAgentPlayback; exports.createCanvasComponentToolProvider = createCanvasComponentToolProvider; exports.createCaptureTool = _chunkN2FGYZ4Qcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkN2FGYZ4Qcjs.createCaptureToolProvider; exports.createDocumentChartTools = createDocumentChartTools; exports.createEditorMcpToolProvider = createEditorMcpToolProvider; exports.createElementCaptureSurface = _chunkSVFEVKLFcjs.createElementCaptureSurface; exports.createInstantPresenceClock = _chunkUJGAA6AKcjs.createInstantPresenceClock; exports.createMcpServer = _chunkY4BWZB6Jcjs.createMcpServer; exports.createRichTextToolProvider = createRichTextToolProvider; exports.createSpreadsheetToolProvider = createSpreadsheetToolProvider; exports.createToolRegistry = _chunkY4BWZB6Jcjs.createToolRegistry; exports.derivePlaybackSteps = _chunkX2HQP7DFcjs.derivePlaybackSteps; exports.elementToSvg = _chunkSVFEVKLFcjs.elementToSvg; exports.errorResult = _chunkY4BWZB6Jcjs.errorResult; exports.isUnsafeJsonKey = _chunk2BSBFBOAcjs.isUnsafeJsonKey; exports.listSkills = _chunkY4BWZB6Jcjs.listSkills; exports.normalizeSide = normalizeSide; exports.parseSkillFrontmatter = _chunkY4BWZB6Jcjs.parseSkillFrontmatter; exports.planAgentCommand = planAgentCommand; exports.planCanvasPlaybackSteps = planCanvasPlaybackSteps; exports.planCanvasToolPlayback = planCanvasToolPlayback; exports.planToolCall = planToolCall; exports.playbackRefsFromArgs = _chunkX2HQP7DFcjs.playbackRefsFromArgs; exports.playbackRefsFromResult = _chunkX2HQP7DFcjs.playbackRefsFromResult; exports.rasterizeElement = _chunkSVFEVKLFcjs.rasterizeElement; exports.readSkillFile = _chunkY4BWZB6Jcjs.readSkillFile; exports.readingTime = _chunkX2HQP7DFcjs.readingTime; exports.realPresenceClock = _chunkUJGAA6AKcjs.realPresenceClock; exports.resolveCaptureRequest = _chunkN2FGYZ4Qcjs.resolveCaptureRequest; exports.runToolScript = _chunkXH32BATEcjs.runToolScript; exports.searchTokens = _chunkY4BWZB6Jcjs.searchTokens; exports.searchTools = _chunkY4BWZB6Jcjs.searchTools; exports.stripPrototypeKeys = _chunk2BSBFBOAcjs.stripPrototypeKeys; exports.summarize = _chunkY4BWZB6Jcjs.summarize; exports.toCapturedImageData = _chunkN2FGYZ4Qcjs.toCapturedImageData; exports.toToolResult = _chunkY4BWZB6Jcjs.toToolResult; exports.toolCallToAgentCommand = toolCallToAgentCommand; exports.toolResultError = _chunkXH32BATEcjs.toolResultError; exports.toolResultValue = _chunkXH32BATEcjs.toolResultValue; exports.toolsetInstructions = _chunkY4BWZB6Jcjs.toolsetInstructions; exports.toolsetName = _chunkY4BWZB6Jcjs.toolsetName; exports.tweenPresenceCursor = _chunkUJGAA6AKcjs.tweenPresenceCursor; exports.unionCaptureRects = _chunkN2FGYZ4Qcjs.unionCaptureRects; exports.unionRects = _chunkX2HQP7DFcjs.unionRects; exports.unknownToolMessage = _chunkY4BWZB6Jcjs.unknownToolMessage; exports.validateAgentCommand = validateAgentCommand; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;
@@ -14,7 +14,11 @@ import {
14
14
  placeBeside
15
15
  } from "../chunk-DW4CV5H4.js";
16
16
  import "../chunk-7KZ2HKKC.js";
17
- import "../chunk-PLKIYNJZ.js";
17
+ import {
18
+ runToolScript,
19
+ toolResultError,
20
+ toolResultValue
21
+ } from "../chunk-Y6SGC6KO.js";
18
22
  import {
19
23
  JSON_RPC_ERRORS,
20
24
  MCP_PROTOCOL_VERSIONS,
@@ -49,7 +53,7 @@ import {
49
53
  playbackRefsFromResult,
50
54
  readingTime,
51
55
  unionRects
52
- } from "../chunk-MFFE55CS.js";
56
+ } from "../chunk-54GVEVXS.js";
53
57
  import {
54
58
  CAPTURE_EXCLUDE_SELECTOR,
55
59
  CAPTURE_OVERLAY_SELECTORS,
@@ -130,9 +134,10 @@ import {
130
134
  import {
131
135
  isSingleCellRange,
132
136
  normalizeRange,
137
+ planSpreadsheetToolPlayback,
133
138
  rangeContainsRange,
134
139
  rangesIntersect
135
- } from "../chunk-E747F3D5.js";
140
+ } from "../chunk-CC6WKVIH.js";
136
141
  import {
137
142
  colNameToIndex,
138
143
  indexToColName,
@@ -1165,6 +1170,13 @@ function findMatches(editor, query, args, replacement) {
1165
1170
  function createRichTextToolProvider(target, options) {
1166
1171
  const editor = () => toEditor(target);
1167
1172
  const charts = createDocumentChartTools(editor);
1173
+ const withCaret = (tool) => tool.name !== "insert_chart" ? tool : {
1174
+ ...tool,
1175
+ handler: (args, context) => {
1176
+ if (typeof args.at === "number") presence.show(args.at);
1177
+ return tool.handler(args, context);
1178
+ }
1179
+ };
1168
1180
  const presence = createTextPresence(editor, options.id, options.presence);
1169
1181
  const formatting = createDocumentFormatTools(editor, (ranges) => presence.changed(ranges.filter((r) => r.from < r.to)));
1170
1182
  const getText = {
@@ -1466,7 +1478,7 @@ function createRichTextToolProvider(target, options) {
1466
1478
  if (!ed || ed.isDestroyed) return [];
1467
1479
  if (!ed.isEditable) return [getText, findText, ...charts.read()];
1468
1480
  const tools = [getText, findText, insertText, replaceText, replaceRange, replaceSelection, setSelection, ...formatting.tools(ed)];
1469
- return [...tools, ...isTableEnabled(ed) ? [editTable] : [], ...charts.read(), ...charts.write()];
1481
+ return [...tools, ...isTableEnabled(ed) ? [editTable] : [], ...charts.read(), ...charts.write().map(withCaret)];
1470
1482
  },
1471
1483
  subscribe: (notify) => {
1472
1484
  const ed = editor();
@@ -1816,7 +1828,11 @@ function createSpreadsheetToolProvider(controller, options) {
1816
1828
  title: "Spreadsheet",
1817
1829
  description: "A spreadsheet: read and set cells and ranges, insert and delete rows and columns, merge and transpose.",
1818
1830
  skill: "pixerate-spreadsheet",
1819
- tools: [getRange, setCell, setRange, insertRows, deleteRows, insertColumns, deleteColumns, mergeCells, unmergeCells, transposeRange]
1831
+ // Agent playback: `<SpreadsheetEditor playback>` attaches as `spreadsheet` and finds the cells.
1832
+ playbackSurface: options.playbackSurface ?? "spreadsheet",
1833
+ tools: [getRange, setCell, setRange, insertRows, deleteRows, insertColumns, deleteColumns, mergeCells, unmergeCells, transposeRange].map(
1834
+ (tool) => ({ ...tool, plan: (args) => planSpreadsheetToolPlayback(tool.name, args) })
1835
+ )
1820
1836
  };
1821
1837
  }
1822
1838
  function missingArgumentsMessage(name, args) {
@@ -2171,6 +2187,7 @@ export {
2171
2187
  readingTime,
2172
2188
  realPresenceClock,
2173
2189
  resolveCaptureRequest,
2190
+ runToolScript,
2174
2191
  searchTokens,
2175
2192
  searchTools,
2176
2193
  stripPrototypeKeys,
@@ -2178,6 +2195,8 @@ export {
2178
2195
  toCapturedImageData,
2179
2196
  toToolResult,
2180
2197
  toolCallToAgentCommand,
2198
+ toolResultError,
2199
+ toolResultValue,
2181
2200
  toolsetInstructions,
2182
2201
  toolsetName,
2183
2202
  tweenPresenceCursor,
@@ -65,7 +65,10 @@ export declare function createRichTextToolProvider(target: RichTextToolTarget, o
65
65
  * `unmerge_cells` / `transpose_range` on an A1 range (not the user's
66
66
  * selection), checked against merges and read-only cells first.
67
67
  */
68
- export declare function createSpreadsheetToolProvider(controller: SpreadsheetController, options: ToolProviderOptions): AgentToolProvider;
68
+ export declare function createSpreadsheetToolProvider(controller: SpreadsheetController, options: ToolProviderOptions & {
69
+ /** The agent playback surface its calls are acted out on (default `spreadsheet`, where `SpreadsheetEditor` attaches). */
70
+ playbackSurface?: string;
71
+ }): AgentToolProvider;
69
72
  export interface EditorMcpToolProviderOptions<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> extends ToolProviderOptions {
70
73
  /** Current editor / canvas state. */
71
74
  getSnapshot: () => EditorSnapshot<TNode, TEdge>;
@@ -65,7 +65,10 @@ export declare function createRichTextToolProvider(target: RichTextToolTarget, o
65
65
  * `unmerge_cells` / `transpose_range` on an A1 range (not the user's
66
66
  * selection), checked against merges and read-only cells first.
67
67
  */
68
- export declare function createSpreadsheetToolProvider(controller: SpreadsheetController, options: ToolProviderOptions): AgentToolProvider;
68
+ export declare function createSpreadsheetToolProvider(controller: SpreadsheetController, options: ToolProviderOptions & {
69
+ /** The agent playback surface its calls are acted out on (default `spreadsheet`, where `SpreadsheetEditor` attaches). */
70
+ playbackSurface?: string;
71
+ }): AgentToolProvider;
69
72
  export interface EditorMcpToolProviderOptions<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> extends ToolProviderOptions {
70
73
  /** Current editor / canvas state. */
71
74
  getSnapshot: () => EditorSnapshot<TNode, TEdge>;
@@ -3972,6 +3972,54 @@ var AnimationEditorController = (_class = class {
3972
3972
  }
3973
3973
  }, _class);
3974
3974
 
3975
+ // src/animation-editor/playback.ts
3976
+ var str = (v) => typeof v === "string" && v.length > 0;
3977
+ function elementsOf(args) {
3978
+ const out = [];
3979
+ const add = (v) => str(v) && !out.includes(v) && out.push(v);
3980
+ const fromCommand = (c) => {
3981
+ if (!c || typeof c !== "object") return;
3982
+ const t = _nullishCoalesce(c.targets, () => ( c.target));
3983
+ if (Array.isArray(t)) t.forEach(add);
3984
+ else add(t);
3985
+ };
3986
+ fromCommand(args);
3987
+ fromCommand(args.command);
3988
+ if (Array.isArray(args.commands)) args.commands.forEach(fromCommand);
3989
+ const fromShot = (s) => {
3990
+ if (!s || typeof s !== "object") return;
3991
+ for (const key of ["run", "commands"]) {
3992
+ const list = s[key];
3993
+ if (Array.isArray(list)) list.forEach(fromCommand);
3994
+ }
3995
+ };
3996
+ if (Array.isArray(args.run)) args.run.forEach(fromCommand);
3997
+ if (Array.isArray(args.shots)) args.shots.forEach(fromShot);
3998
+ if (Array.isArray(args.ops)) {
3999
+ for (const op of args.ops) {
4000
+ fromShot(op);
4001
+ if (Array.isArray(_optionalChain([op, 'optionalAccess', _160 => _160.shots]))) op.shots.forEach(fromShot);
4002
+ }
4003
+ }
4004
+ return out.slice(0, 4);
4005
+ }
4006
+ function planAnimationToolPlayback(tool, args) {
4007
+ const steps = [];
4008
+ const shot = str(args.shot) ? args.shot : str(args.id) && /shot/.test(tool) ? args.id : null;
4009
+ if (shot) steps.push({ type: "target", ref: { kind: "shot", id: shot } }, { type: "press" }, { type: "release" });
4010
+ for (const id of elementsOf(args)) steps.push({ type: "target", ref: { kind: "element", id } });
4011
+ return steps.length ? steps : null;
4012
+ }
4013
+ function withAnimationPlayback(provider, surface = "animation") {
4014
+ const plan = (tool) => tool.plan || tool.playback !== void 0 ? tool : { ...tool, plan: (args) => planAnimationToolPlayback(tool.name, args) };
4015
+ const tools = provider.tools;
4016
+ return {
4017
+ ...provider,
4018
+ playbackSurface: _nullishCoalesce(provider.playbackSurface, () => ( surface)),
4019
+ tools: typeof tools === "function" ? () => tools().map(plan) : tools.map(plan)
4020
+ };
4021
+ }
4022
+
3975
4023
  // src/animation-editor/tools.ts
3976
4024
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
3977
4025
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
@@ -4132,7 +4180,7 @@ var MOTION_COMMAND_SCHEMA = {
4132
4180
  oneOf: MOTION_COMMAND_TYPES.map((type) => MOTION_COMMAND_TYPE_SCHEMAS[type])
4133
4181
  };
4134
4182
  var REF2 = (name, description) => ({ $ref: `#/$defs/${name}`, ...description ? { description } : {} });
4135
- var firstSentence = (text) => _nullishCoalesce(_optionalChain([/^.*?[.;](?=\s|$)/, 'access', _160 => _160.exec, 'call', _161 => _161(text), 'optionalAccess', _162 => _162[0]]), () => ( text));
4183
+ var firstSentence = (text) => _nullishCoalesce(_optionalChain([/^.*?[.;](?=\s|$)/, 'access', _161 => _161.exec, 'call', _162 => _162(text), 'optionalAccess', _163 => _163[0]]), () => ( text));
4136
4184
  var COMMAND_TYPE_LINES = MOTION_COMMAND_TYPES.map((type) => `${type}: ${firstSentence(_nullishCoalesce(MOTION_COMMAND_TYPE_SCHEMAS[type].description, () => ( "")))}`);
4137
4185
  var EASE_COMPACT = {
4138
4186
  description: `Easing: a preset, or a curve { "type": "cubic-bezier", x1, y1, x2, y2 }, { "type": "spring", stiffness, damping, mass, velocity } (spring presets are Figma's; with no "duration" it lasts until it settles) or { "type": "elastic", amplitude, period, mode }. Default: ease-out for entrances, ease-in-out for moves.`,
@@ -4540,9 +4588,9 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4540
4588
  handler: ({ from = 0, to, limit = 200 }) => {
4541
4589
  const s = scene();
4542
4590
  const timeline = compileMotionScene(s);
4543
- const words = _nullishCoalesce(_optionalChain([s, 'access', _163 => _163.narration, 'optionalAccess', _164 => _164.words]), () => ( []));
4591
+ const words = _nullishCoalesce(_optionalChain([s, 'access', _164 => _164.narration, 'optionalAccess', _165 => _165.words]), () => ( []));
4544
4592
  const end = _nullishCoalesce(to, () => ( Math.max(timeline.duration, words.length ? _nullishCoalesce(words[words.length - 1].end, () => ( words[words.length - 1].start)) : 0)));
4545
- const shotAt = (ms) => _optionalChain([timeline, 'access', _165 => _165.shots, 'access', _166 => _166.find, 'call', _167 => _167((x) => ms >= x.start && ms < x.end), 'optionalAccess', _168 => _168.id]);
4593
+ const shotAt = (ms) => _optionalChain([timeline, 'access', _166 => _166.shots, 'access', _167 => _167.find, 'call', _168 => _168((x) => ms >= x.start && ms < x.end), 'optionalAccess', _169 => _169.id]);
4546
4594
  const beats = [];
4547
4595
  if (s.beat && s.beat.bpm > 0) {
4548
4596
  const first = Math.max(0, Math.ceil(motionBeatAt(s.beat, from).beat - 1e-9));
@@ -4864,7 +4912,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4864
4912
  inputSchema: object({ shot: SHOT_ID, commands: { type: "array", items: REF2("command"), minItems: 1, description: "Commands to add." }, at: { type: "integer", minimum: 0, description: "Index in the run (default: the end)." } }, ["shot", "commands"]),
4865
4913
  annotations: { title: "Add commands to a shot", ...WRITE },
4866
4914
  handler: ({ shot, commands, at }) => {
4867
- const before = _nullishCoalesce(_optionalChain([scene, 'call', _169 => _169(), 'access', _170 => _170.shots, 'access', _171 => _171.find, 'call', _172 => _172((s) => s.id === shot), 'optionalAccess', _173 => _173.run, 'access', _174 => _174.length]), () => ( 0));
4915
+ const before = _nullishCoalesce(_optionalChain([scene, 'call', _170 => _170(), 'access', _171 => _171.shots, 'access', _172 => _172.find, 'call', _173 => _173((s) => s.id === shot), 'optionalAccess', _174 => _174.run, 'access', _175 => _175.length]), () => ( 0));
4868
4916
  const first = _nullishCoalesce(at, () => ( before));
4869
4917
  return apply({ op: "add_commands", shot, commands, at }, "Add commands", (s) => {
4870
4918
  const shots = describeMotionShots(s);
@@ -4998,7 +5046,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4998
5046
  const finish = (tools) => tools.map((tool) => ({ ...tool, inputSchema: withDefs(tool.inputSchema) }));
4999
5047
  const reads = finish([getAnimation, getShot, describeCommand, findElements, getTextLayout, getMotionPath, getTimingGrid, checkAnimation, renderFrame, exportFlairMotion, exportFlairEffect, exportLottie, seekAnimation]);
5000
5048
  const writes = finish([setArtworkSvg, importPptx, setDrivers, setClip, copyAnimation, fitAnimation, importFlairEffect, insertShots, updateShot, deleteShots, moveShot, addCommands, updateCommand, deleteCommands, moveCommand, setSettings, setControls, editAnimation, writeAnimation, undo, redo]);
5001
- return {
5049
+ return withAnimationPlayback({
5002
5050
  id: _nullishCoalesce(options.id, () => ( "animation")),
5003
5051
  namespace: options.namespace,
5004
5052
  title: "Animation editor",
@@ -5015,7 +5063,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
5015
5063
  }
5016
5064
  });
5017
5065
  }
5018
- };
5066
+ });
5019
5067
  }
5020
5068
 
5021
5069
  // src/animation-editor/instructions.ts
@@ -5065,7 +5113,7 @@ var TIMING = /* @__PURE__ */ new Set(["duration", "delay", "stagger", "with", "e
5065
5113
  var COLORS = /* @__PURE__ */ new Set(["fill", "stroke", "color"]);
5066
5114
  var NODES = /* @__PURE__ */ new Set(["into", "path"]);
5067
5115
  function branch(type) {
5068
- return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _175 => _175.properties, 'optionalAccess', _176 => _176.type, 'optionalAccess', _177 => _177.const]) === type);
5116
+ return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _176 => _176.properties, 'optionalAccess', _177 => _177.type, 'optionalAccess', _178 => _178.const]) === type);
5069
5117
  }
5070
5118
  function unitOf(type, name) {
5071
5119
  if (name === "duration" || name === "delay" || name === "stagger") return "ms";
@@ -5100,7 +5148,7 @@ function kindOf(name, schema) {
5100
5148
  }
5101
5149
  function motionCommandFields(type) {
5102
5150
  const schema = branch(type);
5103
- if (!_optionalChain([schema, 'optionalAccess', _178 => _178.properties])) return [];
5151
+ if (!_optionalChain([schema, 'optionalAccess', _179 => _179.properties])) return [];
5104
5152
  const required = new Set(_nullishCoalesce(schema.required, () => ( [])));
5105
5153
  const fields = Object.entries(schema.properties).filter(([name]) => name !== "type").map(([name, s]) => {
5106
5154
  const kind = kindOf(name, s);
@@ -5157,7 +5205,7 @@ function defaultMotionCommand(type, targets, scene) {
5157
5205
  if (type === "wait") return { type: "wait", duration: 500 };
5158
5206
  if (!targets.length) return { error: "Pick a target first: click an element on the stage." };
5159
5207
  const nodes = [...indexMotionNodes(scene.artwork.nodes).values()];
5160
- const other = (pred) => _optionalChain([nodes, 'access', _179 => _179.find, 'call', _180 => _180((e) => !targets.includes(e.node.id) && pred(e)), 'optionalAccess', _181 => _181.node, 'access', _182 => _182.id]);
5208
+ const other = (pred) => _optionalChain([nodes, 'access', _180 => _180.find, 'call', _181 => _181((e) => !targets.includes(e.node.id) && pred(e)), 'optionalAccess', _182 => _182.node, 'access', _183 => _183.id]);
5161
5209
  const base = { targets: [...targets] };
5162
5210
  switch (type) {
5163
5211
  case "scale":
@@ -5188,8 +5236,8 @@ function defaultMotionCommand(type, targets, scene) {
5188
5236
  }
5189
5237
  case "effect": {
5190
5238
  for (const id of targets) {
5191
- const node = _optionalChain([nodes, 'access', _183 => _183.find, 'call', _184 => _184((e) => e.node.id === id), 'optionalAccess', _185 => _185.node]);
5192
- for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _186 => _186.effects]), () => ( []))) {
5239
+ const node = _optionalChain([nodes, 'access', _184 => _184.find, 'call', _185 => _185((e) => e.node.id === id), 'optionalAccess', _186 => _186.node]);
5240
+ for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _187 => _187.effects]), () => ( []))) {
5193
5241
  const param = Object.entries(effect.params).find(([, v]) => typeof v === "number");
5194
5242
  if (param) return { type, ...base, effect: effect.id, param: param[0], to: param[1] + 1 };
5195
5243
  }
@@ -5214,11 +5262,11 @@ function motionCommandRows(scene, shotId) {
5214
5262
  return scene.shots[index].run.map((command3, i) => {
5215
5263
  const t = timeline.commands.find((c) => c.shotIndex === index && c.command === i);
5216
5264
  const primitive = motionFlairPrimitive(command3);
5217
- return { index: i, command: command3, summary: motionCommandSummary(command3), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _187 => _187.start]), () => ( 0)), end: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _188 => _188.end]), () => ( 0)), ...primitive ? { flairPrimitive: primitive } : {} };
5265
+ return { index: i, command: command3, summary: motionCommandSummary(command3), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _188 => _188.start]), () => ( 0)), end: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _189 => _189.end]), () => ( 0)), ...primitive ? { flairPrimitive: primitive } : {} };
5218
5266
  });
5219
5267
  }
5220
5268
  function duplicateMotionCommandEdit(scene, shot, command3) {
5221
- const run = _nullishCoalesce(_optionalChain([scene, 'access', _189 => _189.shots, 'access', _190 => _190.find, 'call', _191 => _191((s) => s.id === shot), 'optionalAccess', _192 => _192.run]), () => ( []));
5269
+ const run = _nullishCoalesce(_optionalChain([scene, 'access', _190 => _190.shots, 'access', _191 => _191.find, 'call', _192 => _192((s) => s.id === shot), 'optionalAccess', _193 => _193.run]), () => ( []));
5222
5270
  return { op: "add_commands", shot, commands: run[command3] ? [structuredClone(run[command3])] : [], at: command3 + 1 };
5223
5271
  }
5224
5272
  var MOTION_EASE_CHOICES = [
@@ -5303,7 +5351,7 @@ function motionCueFromKey(key) {
5303
5351
  function motionCueChoices(scene, limit = 256) {
5304
5352
  const choices = [];
5305
5353
  const s = (ms) => `${(ms / 1e3).toFixed(2)} s`;
5306
- const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access', _193 => _193.narration, 'optionalAccess', _194 => _194.words, 'access', _195 => _195.map, 'call', _196 => _196((w) => _nullishCoalesce(w.end, () => ( w.start)))]), () => ( [0]))) + 2e3;
5354
+ const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access', _194 => _194.narration, 'optionalAccess', _195 => _195.words, 'access', _196 => _196.map, 'call', _197 => _197((w) => _nullishCoalesce(w.end, () => ( w.start)))]), () => ( [0]))) + 2e3;
5307
5355
  if (scene.beat && scene.beat.bpm > 0) {
5308
5356
  for (let beat = 0; choices.length < limit; beat++) {
5309
5357
  const time = motionBeatTime(scene.beat, beat);
@@ -5313,7 +5361,7 @@ function motionCueChoices(scene, limit = 256) {
5313
5361
  choices.push({ value: `beat:${beat}`, label: `Beat ${beat} (bar ${at.bar}.${at.beatInBar}) \xB7 ${s(time)}`, time });
5314
5362
  }
5315
5363
  }
5316
- _optionalChain([scene, 'access', _197 => _197.narration, 'optionalAccess', _198 => _198.words, 'access', _199 => _199.forEach, 'call', _200 => _200((w, i) => {
5364
+ _optionalChain([scene, 'access', _198 => _198.narration, 'optionalAccess', _199 => _199.words, 'access', _200 => _200.forEach, 'call', _201 => _201((w, i) => {
5317
5365
  if (choices.length < limit * 2) choices.push({ value: `word:${i}`, label: `Word ${i} \u201C${w.text}\u201D \xB7 ${s(w.start)}`, time: w.start });
5318
5366
  })]);
5319
5367
  return choices;
@@ -5322,7 +5370,7 @@ function motionShotCueTime(scene, cue) {
5322
5370
  return cue ? motionCueTime(scene, cue) : void 0;
5323
5371
  }
5324
5372
  function formatMotionNarration(narration) {
5325
- return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _201 => _201.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
5373
+ return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _202 => _202.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
5326
5374
  }
5327
5375
  function parseMotionNarration(text) {
5328
5376
  const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
@@ -5371,7 +5419,7 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
5371
5419
  if (!r.ok) throw new Error(r.error);
5372
5420
  return { target, effect: info(r.effect), effects: controller.appliedEffects().filter((e) => e.targets.includes(target)).map(info), ...r.notes.length ? { notes: r.notes } : {} };
5373
5421
  };
5374
- return _chunkRUZQMYXHcjs.createEffectToolProvider.call(void 0, {
5422
+ return withAnimationPlayback(_chunkRUZQMYXHcjs.createEffectToolProvider.call(void 0, {
5375
5423
  id: _nullishCoalesce(options.id, () => ( "animation-effects")),
5376
5424
  namespace: options.namespace,
5377
5425
  title: "Animation effects",
@@ -5438,7 +5486,7 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
5438
5486
  }
5439
5487
  }
5440
5488
  ]
5441
- });
5489
+ }));
5442
5490
  }
5443
5491
 
5444
5492
 
@@ -5593,4 +5641,6 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
5593
5641
 
5594
5642
 
5595
5643
 
5596
- exports.ANIMATION_EDITOR_AGENT_INSTRUCTIONS = ANIMATION_EDITOR_AGENT_INSTRUCTIONS; exports.AnimationEditorController = AnimationEditorController; exports.FLAIR_EASES = FLAIR_EASES; exports.FLAIR_EXPORT_VERSION = FLAIR_EXPORT_VERSION; exports.MOTION_ADDITIVE_PROPERTIES = MOTION_ADDITIVE_PROPERTIES; exports.MOTION_BLENDS = MOTION_BLENDS; exports.MOTION_CAMERA_MS = MOTION_CAMERA_MS; exports.MOTION_CASCADES = MOTION_CASCADES; exports.MOTION_CLIP_TARGET = MOTION_CLIP_TARGET; exports.MOTION_COMMAND_FIELDS = MOTION_COMMAND_FIELDS; exports.MOTION_COMMAND_SCHEMA = MOTION_COMMAND_SCHEMA; exports.MOTION_COMMAND_TYPES = MOTION_COMMAND_TYPES; exports.MOTION_COMMAND_TYPE_SCHEMAS = MOTION_COMMAND_TYPE_SCHEMAS; exports.MOTION_DEFAULT_DURATIONS = MOTION_DEFAULT_DURATIONS; exports.MOTION_DEFAULT_HOLD = MOTION_DEFAULT_HOLD; exports.MOTION_DIRECTIONS = MOTION_DIRECTIONS; exports.MOTION_DRAW_EFFECT_ID = MOTION_DRAW_EFFECT_ID; exports.MOTION_DRAW_MS_PER_UNIT = MOTION_DRAW_MS_PER_UNIT; exports.MOTION_DRAW_RANGE = MOTION_DRAW_RANGE; exports.MOTION_DRIVEN_PROPERTIES = MOTION_DRIVEN_PROPERTIES; exports.MOTION_EASE_CHOICES = MOTION_EASE_CHOICES; exports.MOTION_EASE_IN_OUT = MOTION_EASE_IN_OUT; exports.MOTION_EASE_OUT = MOTION_EASE_OUT; exports.MOTION_EDIT_OPS = MOTION_EDIT_OPS; exports.MOTION_ENTER_STYLES = MOTION_ENTER_STYLES; exports.MOTION_EXIT_STYLES = MOTION_EXIT_STYLES; exports.MOTION_IRIS_SHAPES = MOTION_IRIS_SHAPES; exports.MOTION_ISSUE_CODES = _chunkEBDZWIOPcjs.MOTION_ISSUE_CODES; exports.MOTION_MIN_CHANGE_MS = MOTION_MIN_CHANGE_MS; exports.MOTION_REPEAT_MODES = MOTION_REPEAT_MODES; exports.MOTION_SPEED_RANGE = MOTION_SPEED_RANGE; exports.MOTION_SPLIT_ORIENTATIONS = MOTION_SPLIT_ORIENTATIONS; exports.MOTION_TEXT_STAGGER = MOTION_TEXT_STAGGER; exports.MOTION_TEXT_UNITS = MOTION_TEXT_UNITS; exports.MOTION_TRIGGERS = MOTION_TRIGGERS; exports.MotionSceneFormatError = MotionSceneFormatError; exports.activeSegment = activeSegment; exports.applyMotionControlValues = applyMotionControlValues; exports.applyMotionDrivers = applyMotionDrivers; exports.applyMotionEdits = applyMotionEdits; exports.checkMotionScene = checkMotionScene; exports.clipsShapeProblems = clipsShapeProblems; exports.commandShapeProblems = commandShapeProblems; exports.compileMotionScene = compileMotionScene; exports.createAnimationEditorToolProvider = createAnimationEditorToolProvider; exports.createAnimationEffectsToolProvider = createAnimationEffectsToolProvider; exports.createMotionScene = createMotionScene; exports.defaultMotionCommand = defaultMotionCommand; exports.describeMotionElements = describeMotionElements; exports.describeMotionShots = describeMotionShots; exports.driversShapeProblems = driversShapeProblems; exports.duplicateMotionCommandEdit = duplicateMotionCommandEdit; exports.fitMotionRect = fitMotionRect; exports.fitMotionScene = fitMotionScene; exports.fitMotionSceneEdits = fitMotionSceneEdits; exports.flairAtLeast = flairAtLeast; exports.flairCurveFor = flairCurveFor; exports.flairEaseFor = flairEaseFor; exports.formatMotionDrivers = formatMotionDrivers; exports.formatMotionNarration = formatMotionNarration; exports.freshShotId = freshShotId; exports.fromFlairSvgMotion = fromFlairSvgMotion; exports.fromFlairVectorEffect = fromFlairVectorEffect; exports.fromPptxAnimation = fromPptxAnimation; exports.highlightMotionSvg = highlightMotionSvg; exports.indexMotionNodes = indexMotionNodes; exports.interpolateMotionValue = interpolateMotionValue; exports.isMotionCommand = isMotionCommand; exports.isMotionShot = isMotionShot; exports.matchMotionNodes = matchMotionNodes; exports.motionAddTrackKey = motionAddTrackKey; exports.motionArtworkSvg = motionArtworkSvg; exports.motionBeatAt = motionBeatAt; exports.motionBeatTime = motionBeatTime; exports.motionBlurTimes = motionBlurTimes; exports.motionCascade = motionCascade; exports.motionClipAttrs = motionClipAttrs; exports.motionClipLayout = motionClipLayout; exports.motionCommandDuration = motionCommandDuration; exports.motionCommandFields = motionCommandFields; exports.motionCommandRepeat = motionCommandRepeat; exports.motionCommandRows = motionCommandRows; exports.motionCommandSlots = motionCommandSlots; exports.motionCommandSummary = motionCommandSummary; exports.motionCommandsFromEffect = motionCommandsFromEffect; exports.motionContactSheetSvg = motionContactSheetSvg; exports.motionCueChoices = motionCueChoices; exports.motionCueFromKey = motionCueFromKey; exports.motionCueKey = motionCueKey; exports.motionCueTime = motionCueTime; exports.motionCycleDuration = motionCycleDuration; exports.motionDrivenNodes = motionDrivenNodes; exports.motionDriverSources = motionDriverSources; exports.motionEaseKey = motionEaseKey; exports.motionEasingCurve = motionEasingCurve; exports.motionEasingGuides = motionEasingGuides; exports.motionEasingPath = motionEasingPath; exports.motionFieldEdit = motionFieldEdit; exports.motionFieldLabel = motionFieldLabel; exports.motionFlairPrimitive = motionFlairPrimitive; exports.motionFollowRoute = motionFollowRoute; exports.motionFrameAt = motionFrameAt; exports.motionFrameToSvg = motionFrameToSvg; exports.motionGhosts = motionGhosts; exports.motionIssue = _chunkEBDZWIOPcjs.motionIssue; exports.motionIssueKey = _chunkEBDZWIOPcjs.motionIssueKey; exports.motionIssueLine = _chunkEBDZWIOPcjs.motionIssueLine; exports.motionMovingIds = motionMovingIds; exports.motionNodeAtElement = motionNodeAtElement; exports.motionNodeClips = motionNodeClips; exports.motionNodeOffset = motionNodeOffset; exports.motionPartsFromVectorEffect = motionPartsFromVectorEffect; exports.motionPath = motionPath; exports.motionPathLength = motionPathLength; exports.motionPathsSvg = motionPathsSvg; exports.motionPropertyValue = motionPropertyValue; exports.motionRestValue = motionRestValue; exports.motionRevealClip = motionRevealClip; exports.motionRevealPadding = motionRevealPadding; exports.motionRulerTicks = motionRulerTicks; exports.motionSceneEffects = motionSceneEffects; exports.motionSceneShapeProblems = motionSceneShapeProblems; exports.motionSceneToJson = motionSceneToJson; exports.motionShotAt = motionShotAt; exports.motionShotCueTime = motionShotCueTime; exports.motionShotTimeScale = motionShotTimeScale; exports.motionStageSvg = motionStageSvg; exports.motionTextLayout = motionTextLayout; exports.motionTextUnits = motionTextUnits; exports.motionTrackKey = motionTrackKey; exports.namedWithSuggestion = _chunkEBDZWIOPcjs.namedWithSuggestion; exports.nextMotionEffectInstance = nextMotionEffectInstance; exports.parseMotionDrivers = parseMotionDrivers; exports.parseMotionFieldInput = parseMotionFieldInput; exports.parseMotionNarration = parseMotionNarration; exports.parseMotionScene = parseMotionScene; exports.resolveMotionCamera = resolveMotionCamera; exports.resolveMotionEditRefs = resolveMotionEditRefs; exports.segmentProgress = segmentProgress; exports.segmentValue = segmentValue; exports.shotShapeProblems = shotShapeProblems; exports.smoothMotionLegs = smoothMotionLegs; exports.smoothMotionTimes = smoothMotionTimes; exports.suggestName = _chunkEBDZWIOPcjs.suggestName; exports.toFlairEffectDocument = toFlairEffectDocument; exports.toFlairSvgMotion = toFlairSvgMotion; exports.toFlairVectorEffect = toFlairVectorEffect; exports.toLottie = toLottie; exports.trackValue = trackValue; exports.withMotionLayers = withMotionLayers; exports.withViewBox = withViewBox; exports.withoutMotionEffect = withoutMotionEffect;
5644
+
5645
+
5646
+ exports.ANIMATION_EDITOR_AGENT_INSTRUCTIONS = ANIMATION_EDITOR_AGENT_INSTRUCTIONS; exports.AnimationEditorController = AnimationEditorController; exports.FLAIR_EASES = FLAIR_EASES; exports.FLAIR_EXPORT_VERSION = FLAIR_EXPORT_VERSION; exports.MOTION_ADDITIVE_PROPERTIES = MOTION_ADDITIVE_PROPERTIES; exports.MOTION_BLENDS = MOTION_BLENDS; exports.MOTION_CAMERA_MS = MOTION_CAMERA_MS; exports.MOTION_CASCADES = MOTION_CASCADES; exports.MOTION_CLIP_TARGET = MOTION_CLIP_TARGET; exports.MOTION_COMMAND_FIELDS = MOTION_COMMAND_FIELDS; exports.MOTION_COMMAND_SCHEMA = MOTION_COMMAND_SCHEMA; exports.MOTION_COMMAND_TYPES = MOTION_COMMAND_TYPES; exports.MOTION_COMMAND_TYPE_SCHEMAS = MOTION_COMMAND_TYPE_SCHEMAS; exports.MOTION_DEFAULT_DURATIONS = MOTION_DEFAULT_DURATIONS; exports.MOTION_DEFAULT_HOLD = MOTION_DEFAULT_HOLD; exports.MOTION_DIRECTIONS = MOTION_DIRECTIONS; exports.MOTION_DRAW_EFFECT_ID = MOTION_DRAW_EFFECT_ID; exports.MOTION_DRAW_MS_PER_UNIT = MOTION_DRAW_MS_PER_UNIT; exports.MOTION_DRAW_RANGE = MOTION_DRAW_RANGE; exports.MOTION_DRIVEN_PROPERTIES = MOTION_DRIVEN_PROPERTIES; exports.MOTION_EASE_CHOICES = MOTION_EASE_CHOICES; exports.MOTION_EASE_IN_OUT = MOTION_EASE_IN_OUT; exports.MOTION_EASE_OUT = MOTION_EASE_OUT; exports.MOTION_EDIT_OPS = MOTION_EDIT_OPS; exports.MOTION_ENTER_STYLES = MOTION_ENTER_STYLES; exports.MOTION_EXIT_STYLES = MOTION_EXIT_STYLES; exports.MOTION_IRIS_SHAPES = MOTION_IRIS_SHAPES; exports.MOTION_ISSUE_CODES = _chunkEBDZWIOPcjs.MOTION_ISSUE_CODES; exports.MOTION_MIN_CHANGE_MS = MOTION_MIN_CHANGE_MS; exports.MOTION_REPEAT_MODES = MOTION_REPEAT_MODES; exports.MOTION_SPEED_RANGE = MOTION_SPEED_RANGE; exports.MOTION_SPLIT_ORIENTATIONS = MOTION_SPLIT_ORIENTATIONS; exports.MOTION_TEXT_STAGGER = MOTION_TEXT_STAGGER; exports.MOTION_TEXT_UNITS = MOTION_TEXT_UNITS; exports.MOTION_TRIGGERS = MOTION_TRIGGERS; exports.MotionSceneFormatError = MotionSceneFormatError; exports.activeSegment = activeSegment; exports.applyMotionControlValues = applyMotionControlValues; exports.applyMotionDrivers = applyMotionDrivers; exports.applyMotionEdits = applyMotionEdits; exports.checkMotionScene = checkMotionScene; exports.clipsShapeProblems = clipsShapeProblems; exports.commandShapeProblems = commandShapeProblems; exports.compileMotionScene = compileMotionScene; exports.createAnimationEditorToolProvider = createAnimationEditorToolProvider; exports.createAnimationEffectsToolProvider = createAnimationEffectsToolProvider; exports.createMotionScene = createMotionScene; exports.defaultMotionCommand = defaultMotionCommand; exports.describeMotionElements = describeMotionElements; exports.describeMotionShots = describeMotionShots; exports.driversShapeProblems = driversShapeProblems; exports.duplicateMotionCommandEdit = duplicateMotionCommandEdit; exports.fitMotionRect = fitMotionRect; exports.fitMotionScene = fitMotionScene; exports.fitMotionSceneEdits = fitMotionSceneEdits; exports.flairAtLeast = flairAtLeast; exports.flairCurveFor = flairCurveFor; exports.flairEaseFor = flairEaseFor; exports.formatMotionDrivers = formatMotionDrivers; exports.formatMotionNarration = formatMotionNarration; exports.freshShotId = freshShotId; exports.fromFlairSvgMotion = fromFlairSvgMotion; exports.fromFlairVectorEffect = fromFlairVectorEffect; exports.fromPptxAnimation = fromPptxAnimation; exports.highlightMotionSvg = highlightMotionSvg; exports.indexMotionNodes = indexMotionNodes; exports.interpolateMotionValue = interpolateMotionValue; exports.isMotionCommand = isMotionCommand; exports.isMotionShot = isMotionShot; exports.matchMotionNodes = matchMotionNodes; exports.motionAddTrackKey = motionAddTrackKey; exports.motionArtworkSvg = motionArtworkSvg; exports.motionBeatAt = motionBeatAt; exports.motionBeatTime = motionBeatTime; exports.motionBlurTimes = motionBlurTimes; exports.motionCascade = motionCascade; exports.motionClipAttrs = motionClipAttrs; exports.motionClipLayout = motionClipLayout; exports.motionCommandDuration = motionCommandDuration; exports.motionCommandFields = motionCommandFields; exports.motionCommandRepeat = motionCommandRepeat; exports.motionCommandRows = motionCommandRows; exports.motionCommandSlots = motionCommandSlots; exports.motionCommandSummary = motionCommandSummary; exports.motionCommandsFromEffect = motionCommandsFromEffect; exports.motionContactSheetSvg = motionContactSheetSvg; exports.motionCueChoices = motionCueChoices; exports.motionCueFromKey = motionCueFromKey; exports.motionCueKey = motionCueKey; exports.motionCueTime = motionCueTime; exports.motionCycleDuration = motionCycleDuration; exports.motionDrivenNodes = motionDrivenNodes; exports.motionDriverSources = motionDriverSources; exports.motionEaseKey = motionEaseKey; exports.motionEasingCurve = motionEasingCurve; exports.motionEasingGuides = motionEasingGuides; exports.motionEasingPath = motionEasingPath; exports.motionFieldEdit = motionFieldEdit; exports.motionFieldLabel = motionFieldLabel; exports.motionFlairPrimitive = motionFlairPrimitive; exports.motionFollowRoute = motionFollowRoute; exports.motionFrameAt = motionFrameAt; exports.motionFrameToSvg = motionFrameToSvg; exports.motionGhosts = motionGhosts; exports.motionIssue = _chunkEBDZWIOPcjs.motionIssue; exports.motionIssueKey = _chunkEBDZWIOPcjs.motionIssueKey; exports.motionIssueLine = _chunkEBDZWIOPcjs.motionIssueLine; exports.motionMovingIds = motionMovingIds; exports.motionNodeAtElement = motionNodeAtElement; exports.motionNodeClips = motionNodeClips; exports.motionNodeOffset = motionNodeOffset; exports.motionPartsFromVectorEffect = motionPartsFromVectorEffect; exports.motionPath = motionPath; exports.motionPathLength = motionPathLength; exports.motionPathsSvg = motionPathsSvg; exports.motionPropertyValue = motionPropertyValue; exports.motionRestValue = motionRestValue; exports.motionRevealClip = motionRevealClip; exports.motionRevealPadding = motionRevealPadding; exports.motionRulerTicks = motionRulerTicks; exports.motionSceneEffects = motionSceneEffects; exports.motionSceneShapeProblems = motionSceneShapeProblems; exports.motionSceneToJson = motionSceneToJson; exports.motionShotAt = motionShotAt; exports.motionShotCueTime = motionShotCueTime; exports.motionShotTimeScale = motionShotTimeScale; exports.motionStageSvg = motionStageSvg; exports.motionTextLayout = motionTextLayout; exports.motionTextUnits = motionTextUnits; exports.motionTrackKey = motionTrackKey; exports.namedWithSuggestion = _chunkEBDZWIOPcjs.namedWithSuggestion; exports.nextMotionEffectInstance = nextMotionEffectInstance; exports.parseMotionDrivers = parseMotionDrivers; exports.parseMotionFieldInput = parseMotionFieldInput; exports.parseMotionNarration = parseMotionNarration; exports.parseMotionScene = parseMotionScene; exports.planAnimationToolPlayback = planAnimationToolPlayback; exports.resolveMotionCamera = resolveMotionCamera; exports.resolveMotionEditRefs = resolveMotionEditRefs; exports.segmentProgress = segmentProgress; exports.segmentValue = segmentValue; exports.shotShapeProblems = shotShapeProblems; exports.smoothMotionLegs = smoothMotionLegs; exports.smoothMotionTimes = smoothMotionTimes; exports.suggestName = _chunkEBDZWIOPcjs.suggestName; exports.toFlairEffectDocument = toFlairEffectDocument; exports.toFlairSvgMotion = toFlairSvgMotion; exports.toFlairVectorEffect = toFlairVectorEffect; exports.toLottie = toLottie; exports.trackValue = trackValue; exports.withAnimationPlayback = withAnimationPlayback; exports.withMotionLayers = withMotionLayers; exports.withViewBox = withViewBox; exports.withoutMotionEffect = withoutMotionEffect;
@@ -29,3 +29,4 @@ export * from './instructions.cjs';
29
29
  export * from './form.cjs';
30
30
  export * from './effects.cjs';
31
31
  export * from './effect-tools.cjs';
32
+ export * from './playback.cjs';
@@ -29,3 +29,4 @@ export * from './instructions.js';
29
29
  export * from './form.js';
30
30
  export * from './effects.js';
31
31
  export * from './effect-tools.js';
32
+ export * from './playback.js';
@@ -3972,6 +3972,54 @@ var AnimationEditorController = class {
3972
3972
  }
3973
3973
  };
3974
3974
 
3975
+ // src/animation-editor/playback.ts
3976
+ var str = (v) => typeof v === "string" && v.length > 0;
3977
+ function elementsOf(args) {
3978
+ const out = [];
3979
+ const add = (v) => str(v) && !out.includes(v) && out.push(v);
3980
+ const fromCommand = (c) => {
3981
+ if (!c || typeof c !== "object") return;
3982
+ const t = c.targets ?? c.target;
3983
+ if (Array.isArray(t)) t.forEach(add);
3984
+ else add(t);
3985
+ };
3986
+ fromCommand(args);
3987
+ fromCommand(args.command);
3988
+ if (Array.isArray(args.commands)) args.commands.forEach(fromCommand);
3989
+ const fromShot = (s) => {
3990
+ if (!s || typeof s !== "object") return;
3991
+ for (const key of ["run", "commands"]) {
3992
+ const list = s[key];
3993
+ if (Array.isArray(list)) list.forEach(fromCommand);
3994
+ }
3995
+ };
3996
+ if (Array.isArray(args.run)) args.run.forEach(fromCommand);
3997
+ if (Array.isArray(args.shots)) args.shots.forEach(fromShot);
3998
+ if (Array.isArray(args.ops)) {
3999
+ for (const op of args.ops) {
4000
+ fromShot(op);
4001
+ if (Array.isArray(op?.shots)) op.shots.forEach(fromShot);
4002
+ }
4003
+ }
4004
+ return out.slice(0, 4);
4005
+ }
4006
+ function planAnimationToolPlayback(tool, args) {
4007
+ const steps = [];
4008
+ const shot = str(args.shot) ? args.shot : str(args.id) && /shot/.test(tool) ? args.id : null;
4009
+ if (shot) steps.push({ type: "target", ref: { kind: "shot", id: shot } }, { type: "press" }, { type: "release" });
4010
+ for (const id of elementsOf(args)) steps.push({ type: "target", ref: { kind: "element", id } });
4011
+ return steps.length ? steps : null;
4012
+ }
4013
+ function withAnimationPlayback(provider, surface = "animation") {
4014
+ const plan = (tool) => tool.plan || tool.playback !== void 0 ? tool : { ...tool, plan: (args) => planAnimationToolPlayback(tool.name, args) };
4015
+ const tools = provider.tools;
4016
+ return {
4017
+ ...provider,
4018
+ playbackSurface: provider.playbackSurface ?? surface,
4019
+ tools: typeof tools === "function" ? () => tools().map(plan) : tools.map(plan)
4020
+ };
4021
+ }
4022
+
3975
4023
  // src/animation-editor/tools.ts
3976
4024
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
3977
4025
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
@@ -4998,7 +5046,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
4998
5046
  const finish = (tools) => tools.map((tool) => ({ ...tool, inputSchema: withDefs(tool.inputSchema) }));
4999
5047
  const reads = finish([getAnimation, getShot, describeCommand, findElements, getTextLayout, getMotionPath, getTimingGrid, checkAnimation, renderFrame, exportFlairMotion, exportFlairEffect, exportLottie, seekAnimation]);
5000
5048
  const writes = finish([setArtworkSvg, importPptx, setDrivers, setClip, copyAnimation, fitAnimation, importFlairEffect, insertShots, updateShot, deleteShots, moveShot, addCommands, updateCommand, deleteCommands, moveCommand, setSettings, setControls, editAnimation, writeAnimation, undo, redo]);
5001
- return {
5049
+ return withAnimationPlayback({
5002
5050
  id: options.id ?? "animation",
5003
5051
  namespace: options.namespace,
5004
5052
  title: "Animation editor",
@@ -5015,7 +5063,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
5015
5063
  }
5016
5064
  });
5017
5065
  }
5018
- };
5066
+ });
5019
5067
  }
5020
5068
 
5021
5069
  // src/animation-editor/instructions.ts
@@ -5371,7 +5419,7 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
5371
5419
  if (!r.ok) throw new Error(r.error);
5372
5420
  return { target, effect: info(r.effect), effects: controller.appliedEffects().filter((e) => e.targets.includes(target)).map(info), ...r.notes.length ? { notes: r.notes } : {} };
5373
5421
  };
5374
- return createEffectToolProvider({
5422
+ return withAnimationPlayback(createEffectToolProvider({
5375
5423
  id: options.id ?? "animation-effects",
5376
5424
  namespace: options.namespace,
5377
5425
  title: "Animation effects",
@@ -5438,7 +5486,7 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
5438
5486
  }
5439
5487
  }
5440
5488
  ]
5441
- });
5489
+ }));
5442
5490
  }
5443
5491
  export {
5444
5492
  ANIMATION_EDITOR_AGENT_INSTRUCTIONS,
@@ -5577,6 +5625,7 @@ export {
5577
5625
  parseMotionFieldInput,
5578
5626
  parseMotionNarration,
5579
5627
  parseMotionScene,
5628
+ planAnimationToolPlayback,
5580
5629
  resolveMotionCamera,
5581
5630
  resolveMotionEditRefs,
5582
5631
  segmentProgress,
@@ -5590,6 +5639,7 @@ export {
5590
5639
  toFlairVectorEffect,
5591
5640
  toLottie,
5592
5641
  trackValue,
5642
+ withAnimationPlayback,
5593
5643
  withMotionLayers,
5594
5644
  withViewBox,
5595
5645
  withoutMotionEffect