@pixerate/editor 0.181.0 → 0.182.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/agent/index.cjs +5 -5
  2. package/dist/agent/index.js +3 -3
  3. package/dist/animation/index.cjs +2 -2
  4. package/dist/animation/index.js +1 -1
  5. package/dist/chart/index.cjs +7 -7
  6. package/dist/chart/index.js +1 -1
  7. package/dist/{chunk-5EMS4BZG.cjs → chunk-3SLBXKAW.cjs} +15 -7
  8. package/dist/{chunk-WL4IN36A.js → chunk-EHTX34RE.js} +13 -5
  9. package/dist/{chunk-ZXTO6U7T.js → chunk-GI3AVES4.js} +1 -1
  10. package/dist/{chunk-O2ANJFUF.js → chunk-IVSWRVB4.js} +8 -1
  11. package/dist/{chunk-SWTUM32H.cjs → chunk-K7ENM55P.cjs} +8 -1
  12. package/dist/{chunk-NJGFSOPP.cjs → chunk-U4QN36YT.cjs} +2 -2
  13. package/dist/commands/index.cjs +3 -3
  14. package/dist/commands/index.js +2 -2
  15. package/dist/diagram/index.cjs +7 -7
  16. package/dist/diagram/index.js +1 -1
  17. package/dist/image-editor/controller.d.cts +2 -0
  18. package/dist/image-editor/controller.d.ts +2 -0
  19. package/dist/image-editor/index.cjs +135 -115
  20. package/dist/image-editor/index.js +28 -8
  21. package/dist/image-editor/playback.d.cts +14 -4
  22. package/dist/image-editor/playback.d.ts +14 -4
  23. package/dist/image-editor/selection/segmentation.d.cts +3 -0
  24. package/dist/image-editor/selection/segmentation.d.ts +3 -0
  25. package/dist/paint-editor/index.cjs +6 -6
  26. package/dist/paint-editor/index.js +1 -1
  27. package/dist/tools/index.cjs +4 -4
  28. package/dist/tools/index.js +3 -3
  29. package/dist/tools/playback.d.cts +4 -1
  30. package/dist/tools/playback.d.ts +4 -1
  31. package/dist/tools/presence.d.cts +15 -3
  32. package/dist/tools/presence.d.ts +15 -3
  33. package/dist/tools/registry.d.cts +7 -1
  34. package/dist/tools/registry.d.ts +7 -1
  35. package/package.json +1 -1
@@ -3105,7 +3105,7 @@ function hueRange(pixels, center) {
3105
3105
 
3106
3106
  // src/image-editor/selection/segmentation.ts
3107
3107
  var isPoint = (p) => !!p && typeof p === "object" && Number.isFinite(p.x) && Number.isFinite(p.y);
3108
- function polygonsOf(result) {
3108
+ function segmentationOutlines(result) {
3109
3109
  const p = result.polygon;
3110
3110
  if (!Array.isArray(p) || !p.length) return [];
3111
3111
  const rings = Array.isArray(p[0]) ? p : [p];
@@ -3113,7 +3113,7 @@ function polygonsOf(result) {
3113
3113
  }
3114
3114
  function segmentToSelection(width, height, result) {
3115
3115
  let out = null;
3116
- for (const ring of polygonsOf(result)) {
3116
+ for (const ring of segmentationOutlines(result)) {
3117
3117
  out = combineSelections(out, polygonSelection(width, height, ring), "add");
3118
3118
  }
3119
3119
  if (result.mask && result.mask.width > 0 && result.mask.height > 0) {
@@ -7719,6 +7719,15 @@ var ImageEditorController = class {
7719
7719
  return { label: r.label || description, bounds: one?.bounds ?? null, ...r.score !== void 0 ? { score: r.score } : {} };
7720
7720
  });
7721
7721
  const mask = segmentsToSelection(width, height, decoded);
7722
+ if (mask && options.beforeApply) {
7723
+ const outlines = decoded.flatMap((r, i) => {
7724
+ const rings = segmentationOutlines(r);
7725
+ const b = segments[i]?.bounds;
7726
+ return rings.length ? rings : b ? [[{ x: b.x, y: b.y }, { x: b.x + b.width, y: b.y }, { x: b.x + b.width, y: b.y + b.height }, { x: b.x, y: b.y + b.height }]] : [];
7727
+ });
7728
+ await options.beforeApply(outlines);
7729
+ options.signal?.throwIfAborted();
7730
+ }
7722
7731
  if (mask) this.shapeCommand(mask, options);
7723
7732
  return { segments: segments.filter((s) => s.bounds) };
7724
7733
  }
@@ -10134,20 +10143,24 @@ function createImagePlaybackLocator(controller) {
10134
10143
  }
10135
10144
  var num = (v) => typeof v === "number" && Number.isFinite(v);
10136
10145
  var isPoint2 = (p) => !!p && typeof p === "object" && num(p.x) && num(p.y);
10137
- function trace(points, max = 32) {
10146
+ function trace(points, max = 32, ms = 900) {
10138
10147
  const list = points.length <= max ? points : Array.from({ length: max }, (_, i) => points[Math.round(i * (points.length - 1) / (max - 1))]);
10139
10148
  if (!list.length) return [];
10140
10149
  if (list.length === 1) return [{ type: "move", to: list[0] }, { type: "press" }, { type: "release" }];
10141
10150
  let total = 0;
10142
10151
  for (let i = 1; i < list.length; i++) total += Math.hypot(list[i].x - list[i - 1].x, list[i].y - list[i - 1].y);
10143
- const ms = (i) => total > 0 ? Math.max(16, 900 * Math.hypot(list[i].x - list[i - 1].x, list[i].y - list[i - 1].y) / total) : 16;
10152
+ const stepMs = (i) => total > 0 ? Math.max(16, ms * Math.hypot(list[i].x - list[i - 1].x, list[i].y - list[i - 1].y) / total) : 16;
10144
10153
  return [
10145
10154
  { type: "move", to: list[0] },
10146
- { type: "press" },
10147
- ...list.slice(1).map((to, i) => ({ type: "drag", to, ms: ms(i + 1) })),
10155
+ { type: "press", gesture: "path" },
10156
+ ...list.slice(1).map((to, i) => ({ type: "drag", to, ms: stepMs(i + 1) })),
10148
10157
  { type: "release" }
10149
10158
  ];
10150
10159
  }
10160
+ function planOutlineTrace(outlines, options = {}) {
10161
+ const rings = outlines.map((ring) => ring.filter(isPoint2)).filter((ring) => ring.length >= 3);
10162
+ return rings.slice(0, options.maxOutlines ?? 4).flatMap((ring) => trace([...ring, ring[0]], options.maxPoints ?? 32, rings.length > 1 ? 700 : 1100));
10163
+ }
10151
10164
  function boxOf(args) {
10152
10165
  for (const o of [args, args.shape, args.box, args.rect, args.bounds]) {
10153
10166
  if (!o || typeof o !== "object") continue;
@@ -10197,6 +10210,7 @@ function withImagePlayback(provider, surface) {
10197
10210
  }
10198
10211
  function agentDragDraft(mode, box, image) {
10199
10212
  if (mode === "select") {
10213
+ if ("gesture" in box && box.gesture === "path" && box.path.length >= 2) return { selectionPath: box.path.map((p) => ({ x: p.x, y: p.y })) };
10200
10214
  return {
10201
10215
  selectionPath: [
10202
10216
  { x: box.x, y: box.y },
@@ -10522,12 +10536,16 @@ function createImageSubjectSelectionTool(controller) {
10522
10536
  additionalProperties: false
10523
10537
  },
10524
10538
  annotations: { ...writeAnnotations("Select a subject"), openWorldHint: true },
10525
- handler: async ({ target, maxSegments, mode, feather }) => {
10539
+ handler: async ({ target, maxSegments, mode, feather }, context) => {
10526
10540
  if (typeof target !== "string" || !target.trim()) throw new Error("target must describe what to select.");
10541
+ const perform = context?.perform;
10527
10542
  const { segments } = await controller.selectSubject(target, {
10528
10543
  mode: parseSelectionMode(mode),
10529
10544
  feather: num2(feather, 0),
10530
- maxSegments: typeof maxSegments === "number" ? Math.max(1, Math.round(maxSegments)) : void 0
10545
+ maxSegments: typeof maxSegments === "number" ? Math.max(1, Math.round(maxSegments)) : void 0,
10546
+ signal: context?.signal,
10547
+ // Under playback the cursor traces what the model found, as a lasso, before it is selected.
10548
+ beforeApply: perform ? (outlines) => perform(planOutlineTrace(outlines)) : void 0
10531
10549
  });
10532
10550
  return { ...summary(controller), found: segments };
10533
10551
  }
@@ -16665,6 +16683,7 @@ export {
16665
16683
  placementBounds,
16666
16684
  placementGeometry,
16667
16685
  planImageToolPlayback,
16686
+ planOutlineTrace,
16668
16687
  pngDataUrl,
16669
16688
  pointerPressure,
16670
16689
  pointerStrokeSample,
@@ -16763,6 +16782,7 @@ export {
16763
16782
  seamlessClone,
16764
16783
  seedFromString,
16765
16784
  segmentToSelection,
16785
+ segmentationOutlines,
16766
16786
  segmentsToSelection,
16767
16787
  selectionArea,
16768
16788
  selectionFromCoverage,
@@ -1,6 +1,6 @@
1
1
  import type { AgentToolProvider } from '../tools/registry.cjs';
2
2
  import type { PlaybackPoint, PlaybackRect, PlaybackRef, PlaybackStep } from '../tools/playback.cjs';
3
- import type { PresenceDragBox } from '../tools/presence.cjs';
3
+ import type { PresenceDrag, PresenceDragBox } from '../tools/presence.cjs';
4
4
  import type { ImageEditorController } from './controller.cjs';
5
5
  /** The playback kind of an image layer (`{ kind: 'layer', id }`, as in `data-layer-id`). */
6
6
  export declare const IMAGE_PLAYBACK_KIND = "layer";
@@ -10,6 +10,15 @@ export type ImagePlaybackPanel = 'crop' | 'adjust' | 'layers' | 'paint' | 'selec
10
10
  export declare function imagePlaybackPanel(tool: string): ImagePlaybackPanel | null;
11
11
  /** Finds `{ kind: 'layer', id }` (the layer's pixels, in document pixels) for agent playback. */
12
12
  export declare function createImagePlaybackLocator(controller: Pick<ImageEditorController, 'getLayerBounds'>): (ref: PlaybackRef) => PlaybackRect | null;
13
+ /**
14
+ * Cursor steps that trace closed outlines (document pixels) as lasso drags, one after another: how
15
+ * playback shows a selection whose shape a tool learns mid-call (`select_subject`, through
16
+ * `context.perform`). Long outlines are thinned to `maxPoints`; at most `maxOutlines` are traced.
17
+ */
18
+ export declare function planOutlineTrace(outlines: readonly (readonly PlaybackPoint[])[], options?: {
19
+ maxOutlines?: number;
20
+ maxPoints?: number;
21
+ }): PlaybackStep[];
13
22
  /**
14
23
  * The cursor steps for one image tool call (by bare name), or null to fall back to the ids it names.
15
24
  * Steps open the tool's panel first, then act on the canvas or on the panel's controls.
@@ -23,10 +32,11 @@ export declare function planImageToolPlayback(tool: string, args: Record<string,
23
32
  export declare function withImagePlayback(provider: AgentToolProvider, surface?: string): AgentToolProvider;
24
33
  /**
25
34
  * What a canvas draws while an agent drags on it (see `trackPresenceDrag`): in crop mode, the crop
26
- * box being pulled out (clamped to the image); in select mode, the marquee as a selection path.
27
- * The tool call that follows sets the real crop or selection.
35
+ * box being pulled out (clamped to the image); in select mode, the lasso traced so far (a drag
36
+ * with the `path` gesture) or else the marquee, as a selection path. The tool call that follows
37
+ * sets the real crop or selection.
28
38
  */
29
- export declare function agentDragDraft(mode: string, box: PresenceDragBox, image: {
39
+ export declare function agentDragDraft(mode: string, box: PresenceDragBox | PresenceDrag, image: {
30
40
  width: number;
31
41
  height: number;
32
42
  }): {
@@ -1,6 +1,6 @@
1
1
  import type { AgentToolProvider } from '../tools/registry.js';
2
2
  import type { PlaybackPoint, PlaybackRect, PlaybackRef, PlaybackStep } from '../tools/playback.js';
3
- import type { PresenceDragBox } from '../tools/presence.js';
3
+ import type { PresenceDrag, PresenceDragBox } from '../tools/presence.js';
4
4
  import type { ImageEditorController } from './controller.js';
5
5
  /** The playback kind of an image layer (`{ kind: 'layer', id }`, as in `data-layer-id`). */
6
6
  export declare const IMAGE_PLAYBACK_KIND = "layer";
@@ -10,6 +10,15 @@ export type ImagePlaybackPanel = 'crop' | 'adjust' | 'layers' | 'paint' | 'selec
10
10
  export declare function imagePlaybackPanel(tool: string): ImagePlaybackPanel | null;
11
11
  /** Finds `{ kind: 'layer', id }` (the layer's pixels, in document pixels) for agent playback. */
12
12
  export declare function createImagePlaybackLocator(controller: Pick<ImageEditorController, 'getLayerBounds'>): (ref: PlaybackRef) => PlaybackRect | null;
13
+ /**
14
+ * Cursor steps that trace closed outlines (document pixels) as lasso drags, one after another: how
15
+ * playback shows a selection whose shape a tool learns mid-call (`select_subject`, through
16
+ * `context.perform`). Long outlines are thinned to `maxPoints`; at most `maxOutlines` are traced.
17
+ */
18
+ export declare function planOutlineTrace(outlines: readonly (readonly PlaybackPoint[])[], options?: {
19
+ maxOutlines?: number;
20
+ maxPoints?: number;
21
+ }): PlaybackStep[];
13
22
  /**
14
23
  * The cursor steps for one image tool call (by bare name), or null to fall back to the ids it names.
15
24
  * Steps open the tool's panel first, then act on the canvas or on the panel's controls.
@@ -23,10 +32,11 @@ export declare function planImageToolPlayback(tool: string, args: Record<string,
23
32
  export declare function withImagePlayback(provider: AgentToolProvider, surface?: string): AgentToolProvider;
24
33
  /**
25
34
  * What a canvas draws while an agent drags on it (see `trackPresenceDrag`): in crop mode, the crop
26
- * box being pulled out (clamped to the image); in select mode, the marquee as a selection path.
27
- * The tool call that follows sets the real crop or selection.
35
+ * box being pulled out (clamped to the image); in select mode, the lasso traced so far (a drag
36
+ * with the `path` gesture) or else the marquee, as a selection path. The tool call that follows
37
+ * sets the real crop or selection.
28
38
  */
29
- export declare function agentDragDraft(mode: string, box: PresenceDragBox, image: {
39
+ export declare function agentDragDraft(mode: string, box: PresenceDragBox | PresenceDrag, image: {
30
40
  width: number;
31
41
  height: number;
32
42
  }): {
@@ -40,6 +40,9 @@ export interface SegmentationProvider {
40
40
  export type DecodedSegmentationResult = Omit<SegmentationResult, 'mask'> & {
41
41
  mask?: PixelBuffer;
42
42
  };
43
+ /** A result's polygons as lists of at least three points. */
44
+ /** A result's polygon outlines (rings of at least 3 points), in image pixels. */
45
+ export declare function segmentationOutlines(result: Pick<SegmentationResult, 'polygon'>): ImagePoint[][];
43
46
  /**
44
47
  * One segmentation result as a selection over a `width × height` image, or null when it has no
45
48
  * usable shape. Polygons are anti-aliased; several polygons and a mask are added together.
@@ -40,6 +40,9 @@ export interface SegmentationProvider {
40
40
  export type DecodedSegmentationResult = Omit<SegmentationResult, 'mask'> & {
41
41
  mask?: PixelBuffer;
42
42
  };
43
+ /** A result's polygons as lists of at least three points. */
44
+ /** A result's polygon outlines (rings of at least 3 points), in image pixels. */
45
+ export declare function segmentationOutlines(result: Pick<SegmentationResult, 'polygon'>): ImagePoint[][];
43
46
  /**
44
47
  * One segmentation result as a selection over a `width × height` image, or null when it has no
45
48
  * usable shape. Polygons are anti-aliased; several polygons and a mask are added together.
@@ -53,7 +53,7 @@ var _chunkJLWLX52Lcjs = require('../chunk-JLWLX52L.cjs');
53
53
 
54
54
 
55
55
 
56
- var _chunkSWTUM32Hcjs = require('../chunk-SWTUM32H.cjs');
56
+ var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
57
57
  require('../chunk-EGZM52EO.cjs');
58
58
 
59
59
 
@@ -6006,7 +6006,7 @@ function resampleInto(src, rect, width, height) {
6006
6006
  }
6007
6007
 
6008
6008
  // src/paint-editor/presence.ts
6009
- var PaintPresence = class extends _chunkSWTUM32Hcjs.PresenceStore {
6009
+ var PaintPresence = class extends _chunkK7ENM55Pcjs.PresenceStore {
6010
6010
  };
6011
6011
  var FRAME = 16;
6012
6012
  function strokeSchedule(points) {
@@ -6050,8 +6050,8 @@ var PaintDirector = class {
6050
6050
  this.controller = controller;
6051
6051
  this.presence = presence;
6052
6052
  this.options = options;
6053
- this.clock = _nullishCoalesce(options.clock, () => ( _chunkSWTUM32Hcjs.realPresenceClock));
6054
- this.queue = new (0, _chunkSWTUM32Hcjs.PerformanceQueue)(presence, { clock: this.clock, linger: options.linger });
6053
+ this.clock = _nullishCoalesce(options.clock, () => ( _chunkK7ENM55Pcjs.realPresenceClock));
6054
+ this.queue = new (0, _chunkK7ENM55Pcjs.PerformanceQueue)(presence, { clock: this.clock, linger: options.linger });
6055
6055
  }
6056
6056
 
6057
6057
 
@@ -6086,7 +6086,7 @@ var PaintDirector = class {
6086
6086
  this.presence.set({ id, x: to.x, y: to.y });
6087
6087
  return;
6088
6088
  }
6089
- await _chunkSWTUM32Hcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, this.where(id), to, this.ms(ms));
6089
+ await _chunkK7ENM55Pcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, this.where(id), to, this.ms(ms));
6090
6090
  }
6091
6091
  async say(id, text, ms) {
6092
6092
  if (!text) return;
@@ -6116,7 +6116,7 @@ var PaintDirector = class {
6116
6116
  await this.glide(id, path[0]);
6117
6117
  this.presence.set({ id, pressed: true });
6118
6118
  try {
6119
- for (let i = 1; i < path.length; i++) await _chunkSWTUM32Hcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, path[i - 1], path[i], this.ms(i % 2 ? 260 : 90));
6119
+ for (let i = 1; i < path.length; i++) await _chunkK7ENM55Pcjs.tweenPresenceCursor.call(void 0, this.presence, this.clock, id, path[i - 1], path[i], this.ms(i % 2 ? 260 : 90));
6120
6120
  } finally {
6121
6121
  this.presence.set({ id, pressed: false });
6122
6122
  }
@@ -53,7 +53,7 @@ import {
53
53
  PresenceStore,
54
54
  realPresenceClock,
55
55
  tweenPresenceCursor
56
- } from "../chunk-O2ANJFUF.js";
56
+ } from "../chunk-IVSWRVB4.js";
57
57
  import "../chunk-LPIKXPBM.js";
58
58
  import {
59
59
  BRUSH_ID,
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkNJGFSOPPcjs = require('../chunk-NJGFSOPP.cjs');
11
+ var _chunkU4QN36YTcjs = require('../chunk-U4QN36YT.cjs');
12
12
 
13
13
 
14
14
 
@@ -46,7 +46,7 @@ var _chunkAMX23CSNcjs = require('../chunk-AMX23CSN.cjs');
46
46
 
47
47
 
48
48
 
49
- var _chunk5EMS4BZGcjs = require('../chunk-5EMS4BZG.cjs');
49
+ var _chunk3SLBXKAWcjs = require('../chunk-3SLBXKAW.cjs');
50
50
 
51
51
 
52
52
 
@@ -92,7 +92,7 @@ var _chunkN2FGYZ4Qcjs = require('../chunk-N2FGYZ4Q.cjs');
92
92
 
93
93
 
94
94
 
95
- var _chunkSWTUM32Hcjs = require('../chunk-SWTUM32H.cjs');
95
+ var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
96
96
 
97
97
 
98
98
  var _chunkWOFXZ3XUcjs = require('../chunk-WOFXZ3XU.cjs');
@@ -189,4 +189,4 @@ var _chunk2BSBFBOAcjs = require('../chunk-2BSBFBOA.cjs');
189
189
 
190
190
 
191
191
 
192
- exports.AgentPlayback = _chunk5EMS4BZGcjs.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 = _chunkAMX23CSNcjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkAMX23CSNcjs.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 = _chunkSWTUM32Hcjs.PRESENCE_COLORS; exports.PerformanceQueue = _chunkSWTUM32Hcjs.PerformanceQueue; exports.PresenceStore = _chunkSWTUM32Hcjs.PresenceStore; exports.TOOL_BRIDGE_DEFAULT_PORT = _chunkAMX23CSNcjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkAMX23CSNcjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_DISCOVERY_TOOLS = _chunkAMX23CSNcjs.TOOL_DISCOVERY_TOOLS; exports.TOOL_NAMESPACE_SEPARATOR = _chunkAMX23CSNcjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkAMX23CSNcjs.ToolRegistry; exports.ToolRegistryError = _chunkAMX23CSNcjs.ToolRegistryError; exports.ToolRegistryView = _chunkAMX23CSNcjs.ToolRegistryView; exports.UNSAFE_JSON_KEYS = _chunk2BSBFBOAcjs.UNSAFE_JSON_KEYS; exports.baseToolName = _chunkAMX23CSNcjs.baseToolName; exports.captureInputSchema = _chunkN2FGYZ4Qcjs.captureInputSchema; exports.captureOutputSize = _chunkN2FGYZ4Qcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkSVFEVKLFcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkAMX23CSNcjs.connectToolBridge; exports.createAgentPlayback = _chunk5EMS4BZGcjs.createAgentPlayback; exports.createCaptureTool = _chunkN2FGYZ4Qcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkN2FGYZ4Qcjs.createCaptureToolProvider; exports.createElementCaptureSurface = _chunkSVFEVKLFcjs.createElementCaptureSurface; exports.createInstantPresenceClock = _chunkSWTUM32Hcjs.createInstantPresenceClock; exports.createMcpServer = _chunkAMX23CSNcjs.createMcpServer; exports.createPlaybackToolProvider = _chunk5EMS4BZGcjs.createPlaybackToolProvider; exports.createStyleResolver = _chunkNJGFSOPPcjs.createStyleResolver; exports.createStyleToolProvider = _chunkNJGFSOPPcjs.createStyleToolProvider; exports.createToolRegistry = _chunkAMX23CSNcjs.createToolRegistry; exports.derivePlaybackSteps = _chunk5EMS4BZGcjs.derivePlaybackSteps; exports.elementToSvg = _chunkSVFEVKLFcjs.elementToSvg; exports.errorResult = _chunkAMX23CSNcjs.errorResult; exports.isUnsafeJsonKey = _chunk2BSBFBOAcjs.isUnsafeJsonKey; exports.listSkills = _chunkAMX23CSNcjs.listSkills; exports.locatePlaybackChrome = _chunk5EMS4BZGcjs.locatePlaybackChrome; exports.memoryStyleStore = _chunkNJGFSOPPcjs.memoryStyleStore; exports.parseSkillFrontmatter = _chunkAMX23CSNcjs.parseSkillFrontmatter; exports.parseStyleDomains = _chunkNJGFSOPPcjs.parseStyleDomains; exports.playbackRectFromClient = _chunk5EMS4BZGcjs.playbackRectFromClient; exports.playbackRefsFromArgs = _chunk5EMS4BZGcjs.playbackRefsFromArgs; exports.playbackRefsFromResult = _chunk5EMS4BZGcjs.playbackRefsFromResult; exports.rasterizeElement = _chunkSVFEVKLFcjs.rasterizeElement; exports.readSkillFile = _chunkAMX23CSNcjs.readSkillFile; exports.readingTime = _chunk5EMS4BZGcjs.readingTime; exports.realPresenceClock = _chunkSWTUM32Hcjs.realPresenceClock; exports.renderStyle = _chunkNJGFSOPPcjs.renderStyle; exports.resolveCaptureRequest = _chunkN2FGYZ4Qcjs.resolveCaptureRequest; exports.runStyleChecks = _chunkNJGFSOPPcjs.runStyleChecks; exports.runToolScript = _chunkNJGFSOPPcjs.runToolScript; exports.searchTokens = _chunkAMX23CSNcjs.searchTokens; exports.searchTools = _chunkAMX23CSNcjs.searchTools; exports.stripPrototypeKeys = _chunk2BSBFBOAcjs.stripPrototypeKeys; exports.summarize = _chunkAMX23CSNcjs.summarize; exports.toCapturedImageData = _chunkN2FGYZ4Qcjs.toCapturedImageData; exports.toToolResult = _chunkAMX23CSNcjs.toToolResult; exports.toolResultError = _chunkNJGFSOPPcjs.toolResultError; exports.toolResultValue = _chunkNJGFSOPPcjs.toolResultValue; exports.toolsetInstructions = _chunkAMX23CSNcjs.toolsetInstructions; exports.toolsetName = _chunkAMX23CSNcjs.toolsetName; exports.trackPresenceDrag = _chunkSWTUM32Hcjs.trackPresenceDrag; exports.tweenPresenceCursor = _chunkSWTUM32Hcjs.tweenPresenceCursor; exports.unionCaptureRects = _chunkN2FGYZ4Qcjs.unionCaptureRects; exports.unionRects = _chunk5EMS4BZGcjs.unionRects; exports.unknownToolMessage = _chunkAMX23CSNcjs.unknownToolMessage; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;
192
+ exports.AgentPlayback = _chunk3SLBXKAWcjs.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 = _chunkAMX23CSNcjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkAMX23CSNcjs.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 = _chunkK7ENM55Pcjs.PRESENCE_COLORS; exports.PerformanceQueue = _chunkK7ENM55Pcjs.PerformanceQueue; exports.PresenceStore = _chunkK7ENM55Pcjs.PresenceStore; exports.TOOL_BRIDGE_DEFAULT_PORT = _chunkAMX23CSNcjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkAMX23CSNcjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_DISCOVERY_TOOLS = _chunkAMX23CSNcjs.TOOL_DISCOVERY_TOOLS; exports.TOOL_NAMESPACE_SEPARATOR = _chunkAMX23CSNcjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkAMX23CSNcjs.ToolRegistry; exports.ToolRegistryError = _chunkAMX23CSNcjs.ToolRegistryError; exports.ToolRegistryView = _chunkAMX23CSNcjs.ToolRegistryView; exports.UNSAFE_JSON_KEYS = _chunk2BSBFBOAcjs.UNSAFE_JSON_KEYS; exports.baseToolName = _chunkAMX23CSNcjs.baseToolName; exports.captureInputSchema = _chunkN2FGYZ4Qcjs.captureInputSchema; exports.captureOutputSize = _chunkN2FGYZ4Qcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkSVFEVKLFcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkAMX23CSNcjs.connectToolBridge; exports.createAgentPlayback = _chunk3SLBXKAWcjs.createAgentPlayback; exports.createCaptureTool = _chunkN2FGYZ4Qcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkN2FGYZ4Qcjs.createCaptureToolProvider; exports.createElementCaptureSurface = _chunkSVFEVKLFcjs.createElementCaptureSurface; exports.createInstantPresenceClock = _chunkK7ENM55Pcjs.createInstantPresenceClock; exports.createMcpServer = _chunkAMX23CSNcjs.createMcpServer; exports.createPlaybackToolProvider = _chunk3SLBXKAWcjs.createPlaybackToolProvider; exports.createStyleResolver = _chunkU4QN36YTcjs.createStyleResolver; exports.createStyleToolProvider = _chunkU4QN36YTcjs.createStyleToolProvider; exports.createToolRegistry = _chunkAMX23CSNcjs.createToolRegistry; exports.derivePlaybackSteps = _chunk3SLBXKAWcjs.derivePlaybackSteps; exports.elementToSvg = _chunkSVFEVKLFcjs.elementToSvg; exports.errorResult = _chunkAMX23CSNcjs.errorResult; exports.isUnsafeJsonKey = _chunk2BSBFBOAcjs.isUnsafeJsonKey; exports.listSkills = _chunkAMX23CSNcjs.listSkills; exports.locatePlaybackChrome = _chunk3SLBXKAWcjs.locatePlaybackChrome; exports.memoryStyleStore = _chunkU4QN36YTcjs.memoryStyleStore; exports.parseSkillFrontmatter = _chunkAMX23CSNcjs.parseSkillFrontmatter; exports.parseStyleDomains = _chunkU4QN36YTcjs.parseStyleDomains; exports.playbackRectFromClient = _chunk3SLBXKAWcjs.playbackRectFromClient; exports.playbackRefsFromArgs = _chunk3SLBXKAWcjs.playbackRefsFromArgs; exports.playbackRefsFromResult = _chunk3SLBXKAWcjs.playbackRefsFromResult; exports.rasterizeElement = _chunkSVFEVKLFcjs.rasterizeElement; exports.readSkillFile = _chunkAMX23CSNcjs.readSkillFile; exports.readingTime = _chunk3SLBXKAWcjs.readingTime; exports.realPresenceClock = _chunkK7ENM55Pcjs.realPresenceClock; exports.renderStyle = _chunkU4QN36YTcjs.renderStyle; exports.resolveCaptureRequest = _chunkN2FGYZ4Qcjs.resolveCaptureRequest; exports.runStyleChecks = _chunkU4QN36YTcjs.runStyleChecks; exports.runToolScript = _chunkU4QN36YTcjs.runToolScript; exports.searchTokens = _chunkAMX23CSNcjs.searchTokens; exports.searchTools = _chunkAMX23CSNcjs.searchTools; exports.stripPrototypeKeys = _chunk2BSBFBOAcjs.stripPrototypeKeys; exports.summarize = _chunkAMX23CSNcjs.summarize; exports.toCapturedImageData = _chunkN2FGYZ4Qcjs.toCapturedImageData; exports.toToolResult = _chunkAMX23CSNcjs.toToolResult; exports.toolResultError = _chunkU4QN36YTcjs.toolResultError; exports.toolResultValue = _chunkU4QN36YTcjs.toolResultValue; exports.toolsetInstructions = _chunkAMX23CSNcjs.toolsetInstructions; exports.toolsetName = _chunkAMX23CSNcjs.toolsetName; exports.trackPresenceDrag = _chunkK7ENM55Pcjs.trackPresenceDrag; exports.tweenPresenceCursor = _chunkK7ENM55Pcjs.tweenPresenceCursor; exports.unionCaptureRects = _chunkN2FGYZ4Qcjs.unionCaptureRects; exports.unionRects = _chunk3SLBXKAWcjs.unionRects; exports.unknownToolMessage = _chunkAMX23CSNcjs.unknownToolMessage; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;
@@ -8,7 +8,7 @@ import {
8
8
  runToolScript,
9
9
  toolResultError,
10
10
  toolResultValue
11
- } from "../chunk-ZXTO6U7T.js";
11
+ } from "../chunk-GI3AVES4.js";
12
12
  import {
13
13
  JSON_RPC_ERRORS,
14
14
  MCP_PROTOCOL_VERSIONS,
@@ -46,7 +46,7 @@ import {
46
46
  playbackRefsFromResult,
47
47
  readingTime,
48
48
  unionRects
49
- } from "../chunk-WL4IN36A.js";
49
+ } from "../chunk-EHTX34RE.js";
50
50
  import {
51
51
  CAPTURE_EXCLUDE_SELECTOR,
52
52
  CAPTURE_OVERLAY_SELECTORS,
@@ -92,7 +92,7 @@ import {
92
92
  realPresenceClock,
93
93
  trackPresenceDrag,
94
94
  tweenPresenceCursor
95
- } from "../chunk-O2ANJFUF.js";
95
+ } from "../chunk-IVSWRVB4.js";
96
96
  import {
97
97
  validateJsonSchema
98
98
  } from "../chunk-V2ZCJRDM.js";
@@ -36,8 +36,11 @@ export type PlaybackStep = {
36
36
  type: 'say';
37
37
  text: string;
38
38
  ms?: number;
39
- } | {
39
+ }
40
+ /** Button down. `gesture: 'path'` tells the surface the drag that follows traces an outline (a lasso), not a box. */
41
+ | {
40
42
  type: 'press';
43
+ gesture?: 'path';
41
44
  } | {
42
45
  type: 'release';
43
46
  }
@@ -36,8 +36,11 @@ export type PlaybackStep = {
36
36
  type: 'say';
37
37
  text: string;
38
38
  ms?: number;
39
- } | {
39
+ }
40
+ /** Button down. `gesture: 'path'` tells the surface the drag that follows traces an outline (a lasso), not a box. */
41
+ | {
40
42
  type: 'press';
43
+ gesture?: 'path';
41
44
  } | {
42
45
  type: 'release';
43
46
  }
@@ -7,6 +7,8 @@ export interface PresenceActor {
7
7
  y: number;
8
8
  /** The button is down (dragging). */
9
9
  pressed: boolean;
10
+ /** What a drag traces while `pressed`: `path` for a freehand outline (a lasso), else a box from the press. */
11
+ gesture?: 'path';
10
12
  /** A short note shown next to the cursor (what the agent is doing). */
11
13
  message?: string;
12
14
  /** A rectangle (surface coordinates) the agent is working on, drawn as a highlight ring. */
@@ -87,13 +89,23 @@ export interface PresenceDragBox {
87
89
  width: number;
88
90
  height: number;
89
91
  }
92
+ /** An agent's drag so far: the box from the press to the cursor, and the points it passed through. */
93
+ export interface PresenceDrag extends PresenceDragBox {
94
+ /** The cursor positions since the press, in order (the press first). */
95
+ path: readonly {
96
+ x: number;
97
+ y: number;
98
+ }[];
99
+ /** `path` when the agent traces an outline (see `PresenceActor.gesture`); a box drag otherwise. */
100
+ gesture?: 'path';
101
+ }
90
102
  /**
91
103
  * Follows a presence store for an agent's drag (press, move, release) and reports the box from
92
- * the press to the cursor, so a surface can draw its own drag feedback (a crop box or a marquee
93
- * being pulled out) under the agent's cursor. `onEnd` runs on release, or when the cursor leaves
104
+ * the press to the cursor and the path it took, so a surface can draw its own drag feedback (a crop
105
+ * box, a marquee being pulled out or a lasso being traced) under the agent's cursor. `onEnd` runs on release, or when the cursor leaves
94
106
  * the surface mid-drag. Pass the result to `PresenceStore.subscribe`.
95
107
  */
96
108
  export declare function trackPresenceDrag(handlers: {
97
- onDrag: (box: PresenceDragBox) => void;
109
+ onDrag: (drag: PresenceDrag) => void;
98
110
  onEnd: () => void;
99
111
  }): (state: PresenceState) => void;
@@ -7,6 +7,8 @@ export interface PresenceActor {
7
7
  y: number;
8
8
  /** The button is down (dragging). */
9
9
  pressed: boolean;
10
+ /** What a drag traces while `pressed`: `path` for a freehand outline (a lasso), else a box from the press. */
11
+ gesture?: 'path';
10
12
  /** A short note shown next to the cursor (what the agent is doing). */
11
13
  message?: string;
12
14
  /** A rectangle (surface coordinates) the agent is working on, drawn as a highlight ring. */
@@ -87,13 +89,23 @@ export interface PresenceDragBox {
87
89
  width: number;
88
90
  height: number;
89
91
  }
92
+ /** An agent's drag so far: the box from the press to the cursor, and the points it passed through. */
93
+ export interface PresenceDrag extends PresenceDragBox {
94
+ /** The cursor positions since the press, in order (the press first). */
95
+ path: readonly {
96
+ x: number;
97
+ y: number;
98
+ }[];
99
+ /** `path` when the agent traces an outline (see `PresenceActor.gesture`); a box drag otherwise. */
100
+ gesture?: 'path';
101
+ }
90
102
  /**
91
103
  * Follows a presence store for an agent's drag (press, move, release) and reports the box from
92
- * the press to the cursor, so a surface can draw its own drag feedback (a crop box or a marquee
93
- * being pulled out) under the agent's cursor. `onEnd` runs on release, or when the cursor leaves
104
+ * the press to the cursor and the path it took, so a surface can draw its own drag feedback (a crop
105
+ * box, a marquee being pulled out or a lasso being traced) under the agent's cursor. `onEnd` runs on release, or when the cursor leaves
94
106
  * the surface mid-drag. Pass the result to `PresenceStore.subscribe`.
95
107
  */
96
108
  export declare function trackPresenceDrag(handlers: {
97
- onDrag: (box: PresenceDragBox) => void;
109
+ onDrag: (drag: PresenceDrag) => void;
98
110
  onEnd: () => void;
99
111
  }): (state: PresenceState) => void;
@@ -1,6 +1,6 @@
1
1
  import { type JsonSchema, type SchemaValidationError } from './schema.cjs';
2
2
  import { ToolRegistryView, type ToolViewOptions } from './view.cjs';
3
- import type { ToolPlanner } from './playback.cjs';
3
+ import type { PlaybackStep, ToolPlanner } from './playback.cjs';
4
4
  import type { PresenceActorInfo } from './presence.cjs';
5
5
  /**
6
6
  * MCP-shaped tool definition, as returned by `tools/list`.
@@ -57,6 +57,12 @@ export interface ToolCallContext {
57
57
  * (`await context.stage?.()`), so they appear one by one; without playback it is absent.
58
58
  */
59
59
  stage?: () => Promise<void>;
60
+ /**
61
+ * Set by agent playback while the handler runs: acts out cursor steps (surface coordinates) the
62
+ * handler only learns mid-call, such as the outline a model returned, before it lands its change.
63
+ * `commit`, `stage` and `open` steps are ignored. Without playback it is absent.
64
+ */
65
+ perform?: (steps: readonly PlaybackStep[]) => Promise<void>;
60
66
  }
61
67
  /** Options for `callTool`. */
62
68
  export interface ToolCallOptions {
@@ -1,6 +1,6 @@
1
1
  import { type JsonSchema, type SchemaValidationError } from './schema.js';
2
2
  import { ToolRegistryView, type ToolViewOptions } from './view.js';
3
- import type { ToolPlanner } from './playback.js';
3
+ import type { PlaybackStep, ToolPlanner } from './playback.js';
4
4
  import type { PresenceActorInfo } from './presence.js';
5
5
  /**
6
6
  * MCP-shaped tool definition, as returned by `tools/list`.
@@ -57,6 +57,12 @@ export interface ToolCallContext {
57
57
  * (`await context.stage?.()`), so they appear one by one; without playback it is absent.
58
58
  */
59
59
  stage?: () => Promise<void>;
60
+ /**
61
+ * Set by agent playback while the handler runs: acts out cursor steps (surface coordinates) the
62
+ * handler only learns mid-call, such as the outline a model returned, before it lands its change.
63
+ * `commit`, `stage` and `open` steps are ignored. Without playback it is absent.
64
+ */
65
+ perform?: (steps: readonly PlaybackStep[]) => Promise<void>;
60
66
  }
61
67
  /** Options for `callTool`. */
62
68
  export interface ToolCallOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.181.0",
3
+ "version": "0.182.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",