@pixerate/editor 0.222.2 → 0.223.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 (41) hide show
  1. package/dist/agent/index.cjs +13 -3
  2. package/dist/agent/index.js +12 -2
  3. package/dist/bridge/cli.cjs +3 -3
  4. package/dist/bridge/cli.js +2 -2
  5. package/dist/bridge/index.cjs +3 -3
  6. package/dist/bridge/index.js +2 -2
  7. package/dist/{chunk-I5MRJW7B.js → chunk-67JAEU53.js} +1 -1
  8. package/dist/{chunk-U4QN36YT.cjs → chunk-BDT2IYXK.cjs} +128 -16
  9. package/dist/{chunk-S4EIAIEW.cjs → chunk-OJTZKDLJ.cjs} +7 -7
  10. package/dist/{chunk-XZB3TJ6K.js → chunk-SAN4SBBS.js} +25 -7
  11. package/dist/{chunk-GI3AVES4.js → chunk-SVHXD2VH.js} +117 -5
  12. package/dist/{chunk-AMX23CSN.cjs → chunk-Z7BVK32C.cjs} +25 -7
  13. package/dist/image-editor/index.cjs +12 -11
  14. package/dist/image-editor/index.js +12 -11
  15. package/dist/image-editor/layers/panel.d.cts +6 -2
  16. package/dist/image-editor/layers/panel.d.ts +6 -2
  17. package/dist/tools/index.cjs +13 -3
  18. package/dist/tools/index.d.cts +1 -0
  19. package/dist/tools/index.d.ts +1 -0
  20. package/dist/tools/index.js +12 -2
  21. package/dist/tools/skill-evals.d.cts +102 -0
  22. package/dist/tools/skill-evals.d.ts +102 -0
  23. package/dist/tools/skills.d.cts +12 -1
  24. package/dist/tools/skills.d.ts +12 -1
  25. package/package.json +1 -1
  26. package/skills/README.md +8 -3
  27. package/skills/pixerate-agent-tools/SKILL.md +5 -3
  28. package/skills/pixerate-paint-watercolour/evals/sky-wash.json +1 -1
  29. package/skills/pixerate-video-colour-grade/SKILL.md +105 -0
  30. package/skills/pixerate-video-colour-grade/evals/look-in-one-place.json +16 -0
  31. package/skills/pixerate-video-colour-grade/evals/lut-keep-skin.json +132 -0
  32. package/skills/pixerate-video-colour-grade/evals/match-exposure.json +14 -0
  33. package/skills/pixerate-video-editor/SKILL.md +3 -0
  34. package/skills/pixerate-video-montage/SKILL.md +99 -0
  35. package/skills/pixerate-video-montage/evals/assemble-on-beats.json +231 -0
  36. package/skills/pixerate-video-montage/evals/music-and-ending.json +210 -0
  37. package/skills/pixerate-video-montage/evals/short-crossfades.json +190 -0
  38. package/skills/pixerate-video-social-cut/SKILL.md +105 -0
  39. package/skills/pixerate-video-social-cut/evals/hook-first.json +19 -0
  40. package/skills/pixerate-video-social-cut/evals/opening-title.json +14 -0
  41. package/skills/pixerate-video-social-cut/evals/vertical-reframe.json +15 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseSkillFrontmatter
3
- } from "./chunk-XZB3TJ6K.js";
3
+ } from "./chunk-SAN4SBBS.js";
4
4
  import {
5
5
  readingTime
6
6
  } from "./chunk-EHTX34RE.js";
@@ -12,6 +12,113 @@ import {
12
12
  stripPrototypeKeys
13
13
  } from "./chunk-HF5QZS7Z.js";
14
14
 
15
+ // src/tools/skill-evals.ts
16
+ function listSkillEvals(files) {
17
+ const out = [];
18
+ for (const [raw, text] of Object.entries(files)) {
19
+ const path = raw.replace(/\\/g, "/").replace(/^\.?\//, "");
20
+ const match = /^([^/]+)\/evals\/[^/]+\.json$/.exec(path);
21
+ if (match) out.push({ skill: match[1], path, eval: JSON.parse(text) });
22
+ }
23
+ return out.sort((a, b) => a.path.localeCompare(b.path));
24
+ }
25
+ function imageEvalFixturePixels(f) {
26
+ const { width: W, height: H } = f;
27
+ const data = new Uint8ClampedArray(W * H * 4);
28
+ for (let y = 0; y < H; y++) {
29
+ for (let x = 0; x < W; x++) {
30
+ let rgb = f.background;
31
+ for (const s of f.shapes) {
32
+ const inside = s.shape === "rect" ? x >= s.x && x < s.x + s.width && y >= s.y && y < s.y + s.height : ((x + 0.5 - s.x - s.width / 2) / (s.width / 2)) ** 2 + ((y + 0.5 - s.y - s.height / 2) / (s.height / 2)) ** 2 <= 1;
33
+ if (inside) rgb = s.color;
34
+ }
35
+ data.set([...rgb, 255], (y * W + x) * 4);
36
+ }
37
+ }
38
+ return { width: W, height: H, data };
39
+ }
40
+ async function callEvalTool(callTool, { tool, args = {} }) {
41
+ const res = await callTool(tool, await resolve(callTool, args));
42
+ if (res.isError) throw new Error(`${tool}: ${res.content?.[0]?.text ?? "tool error"}`);
43
+ return res.structuredContent;
44
+ }
45
+ async function resolve(callTool, v) {
46
+ if (Array.isArray(v)) return Promise.all(v.map((x) => resolve(callTool, x)));
47
+ if (!v || typeof v !== "object") return v;
48
+ if ("$read" in v) {
49
+ const { $read, args, path } = v;
50
+ return at(await callEvalTool(callTool, { tool: $read, args }), path);
51
+ }
52
+ const out = {};
53
+ for (const [k, x] of Object.entries(v)) out[k] = await resolve(callTool, x);
54
+ return out;
55
+ }
56
+ function at(value, path) {
57
+ const [key, ...rest] = path.split(".");
58
+ if (value == null || key === void 0) return value;
59
+ if (key === "*") return Array.isArray(value) ? rest.length ? value.map((x) => at(x, rest.join("."))) : value : void 0;
60
+ const next = Array.isArray(value) && /^-\d+$/.test(key) ? value[value.length + Number(key)] : value[key];
61
+ return rest.length ? at(next, rest.join(".")) : next;
62
+ }
63
+ var isEmpty = (v) => v === null || v === void 0 || v === "" || Array.isArray(v) && v.every(isEmpty);
64
+ function matchesEvalExpectation(actual, expected) {
65
+ const matches = matchesEvalExpectation;
66
+ if (expected === null || typeof expected !== "object") return Object.is(actual, expected);
67
+ if (Array.isArray(expected)) return Array.isArray(actual) && actual.length === expected.length && expected.every((e, i) => matches(actual[i], e));
68
+ const ops = Object.entries(expected);
69
+ return ops.every(([key, want]) => {
70
+ const list = Array.isArray(actual) ? actual : null;
71
+ switch (key) {
72
+ case "$min":
73
+ return typeof actual === "number" && actual >= want;
74
+ case "$max":
75
+ return typeof actual === "number" && actual <= want;
76
+ case "$type":
77
+ return (actual === null ? "null" : Array.isArray(actual) ? "array" : typeof actual) === want;
78
+ case "$match": {
79
+ const [pattern, flags] = Array.isArray(want) ? want : [want, ""];
80
+ return typeof actual === "string" && new RegExp(pattern, flags).test(actual);
81
+ }
82
+ case "$in":
83
+ return want.some((w) => matches(actual, w));
84
+ case "$not":
85
+ return !matches(actual, want);
86
+ case "$every":
87
+ return !!list && list.every((a) => matches(a, want));
88
+ case "$some":
89
+ return !!list && list.some((a) => matches(a, want));
90
+ case "$length":
91
+ return !!list && matches(list.length, want);
92
+ case "$unique":
93
+ return !!list && new Set(list.map((a) => JSON.stringify(a))).size === list.length;
94
+ case "$distinct":
95
+ return !!list && matches([...new Set(list.map((a) => JSON.stringify(a)))].map((a) => JSON.parse(a)), want);
96
+ case "$sum":
97
+ return !!list && list.every((a) => typeof a === "number") && Math.abs(list.reduce((s, a) => s + a, 0) - want) < 1e-6;
98
+ case "$column": {
99
+ const [index, m] = want;
100
+ return !!list && matches(list.map((row) => Array.isArray(row) ? row[index] : void 0), m);
101
+ }
102
+ case "$expr":
103
+ return !!new Function("v", `return (${want});`)(actual);
104
+ case "$nonEmpty":
105
+ return !!list && matches(list.filter((a) => !isEmpty(a)), want);
106
+ default:
107
+ if (key.startsWith("$")) throw new Error(`Unknown eval operator ${key}.`);
108
+ return actual !== null && typeof actual === "object" && matches(actual[key], want);
109
+ }
110
+ });
111
+ }
112
+ async function failedEvalChecks(callTool, checks) {
113
+ const failed = [];
114
+ for (const check of checks) {
115
+ const result = await callEvalTool(callTool, check).catch((e) => e);
116
+ if (result instanceof Error) failed.push(`${check.why} (${result.message})`);
117
+ else if (!matchesEvalExpectation(result, check.expect)) failed.push(`${check.why} (${check.tool} \u2192 ${JSON.stringify(result).slice(0, 400)})`);
118
+ }
119
+ return failed;
120
+ }
121
+
15
122
  // src/tools/script.ts
16
123
  function toolResultValue(result) {
17
124
  if (result.structuredContent) return result.structuredContent;
@@ -27,7 +134,7 @@ function toolResultError(result) {
27
134
  const text = result.content.find((b) => b.type === "text");
28
135
  return text?.text ?? "The tool failed.";
29
136
  }
30
- var realWait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
137
+ var realWait = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
31
138
  async function runToolScript(source, script, options = {}) {
32
139
  const control = options.control ?? { speed: 1, stopped: false };
33
140
  const wait = options.wait ?? realWait;
@@ -291,7 +398,7 @@ function createStyleResolver(options) {
291
398
  skills.sort((a, b) => a.layerIndex - b.layerIndex || a.info.order - b.info.order || a.info.name.localeCompare(b.info.name));
292
399
  return { skills, issues };
293
400
  }
294
- async function resolve(domainId) {
401
+ async function resolve2(domainId) {
295
402
  requireDomain(domainId);
296
403
  const { skills, issues: loadIssues } = await load();
297
404
  const issues = [...loadIssues];
@@ -323,7 +430,7 @@ function createStyleResolver(options) {
323
430
  const { skills } = await load();
324
431
  return skills.filter((s) => opts.domain === void 0 || s.applies.has(opts.domain)).map((s) => s.info);
325
432
  },
326
- resolve,
433
+ resolve: resolve2,
327
434
  async readFile(name, file) {
328
435
  const layer = await winnerLayer(name);
329
436
  return layer ? layer.store.read(name, file) : void 0;
@@ -334,7 +441,7 @@ function createStyleResolver(options) {
334
441
  },
335
442
  async check(domainId, state) {
336
443
  const domain = requireDomain(domainId);
337
- const style = await resolve(domainId);
444
+ const style = await resolve2(domainId);
338
445
  return { ...runStyleChecks(domain, state, style), style };
339
446
  },
340
447
  subscribe(listener) {
@@ -472,6 +579,11 @@ function createStyleToolProvider(styles, options = {}) {
472
579
  }
473
580
 
474
581
  export {
582
+ listSkillEvals,
583
+ imageEvalFixturePixels,
584
+ callEvalTool,
585
+ matchesEvalExpectation,
586
+ failedEvalChecks,
475
587
  toolResultValue,
476
588
  toolResultError,
477
589
  runToolScript,
@@ -8,13 +8,22 @@ var _chunk2BSBFBOAcjs = require('./chunk-2BSBFBOA.cjs');
8
8
  // src/tools/skills.ts
9
9
  function parseSkillFrontmatter(markdown) {
10
10
  const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(markdown);
11
- if (!match) return { body: markdown };
11
+ if (!match) return { metadata: {}, body: markdown };
12
12
  const fields = {};
13
+ const metadata = {};
14
+ const unquote = (value) => value.trim().replace(/^(['"])([\s\S]*)\1$/, "$2");
15
+ let inMetadata = false;
13
16
  for (const line of match[1].split(/\r?\n/)) {
14
17
  const kv = /^([A-Za-z_-]+):\s*(.*)$/.exec(line);
15
- if (kv) fields[kv[1]] = kv[2].trim().replace(/^(['"])([\s\S]*)\1$/, "$2");
18
+ if (kv) {
19
+ fields[kv[1]] = unquote(kv[2]);
20
+ inMetadata = kv[1] === "metadata" && kv[2].trim() === "";
21
+ continue;
22
+ }
23
+ const nested = inMetadata ? /^\s+([A-Za-z_-]+):\s*(.*)$/.exec(line) : null;
24
+ if (nested) metadata[nested[1]] = unquote(nested[2]);
16
25
  }
17
- return { name: fields.name, description: fields.description, body: markdown.slice(match[0].length) };
26
+ return { name: fields.name, description: fields.description, metadata, body: markdown.slice(match[0].length) };
18
27
  }
19
28
  var normalize = (path) => path.replace(/\\/g, "/").replace(/^\.?\//, "");
20
29
  function listSkills(files) {
@@ -23,8 +32,15 @@ function listSkills(files) {
23
32
  for (const path of paths) {
24
33
  const [dir, ...rest] = path.split("/");
25
34
  if (rest.join("/") !== "SKILL.md") continue;
26
- const { description } = parseSkillFrontmatter(_nullishCoalesce(_nullishCoalesce(files[path], () => ( files[`./${path}`])), () => ( "")));
27
- skills.set(dir, { name: dir, description: _nullishCoalesce(description, () => ( "")), references: [] });
35
+ const { description, metadata } = parseSkillFrontmatter(_nullishCoalesce(_nullishCoalesce(files[path], () => ( files[`./${path}`])), () => ( "")));
36
+ const workflow = metadata.kind === "workflow";
37
+ skills.set(dir, {
38
+ name: dir,
39
+ description: _nullishCoalesce(description, () => ( "")),
40
+ references: [],
41
+ kind: workflow ? "workflow" : "reference",
42
+ ...workflow && metadata.reference ? { reference: metadata.reference } : {}
43
+ });
28
44
  }
29
45
  for (const path of paths) {
30
46
  const [dir, ...rest] = path.split("/");
@@ -259,11 +275,12 @@ var ToolRegistryView = (_class = class {
259
275
  const style = await discovery.styles.resolve(domain);
260
276
  return style.skills.length ? { domain, skills: style.skills.length, layers: [...new Set(style.skills.map((s) => s.layer))] } : void 0;
261
277
  };
278
+ const workflowsOf = (set) => set.skill ? skills.filter((s) => s.kind === "workflow" && s.reference === set.skill).map((s) => s.name) : [];
262
279
  const tools = [
263
280
  {
264
281
  name: "list_toolsets",
265
282
  title: "List toolsets",
266
- description: "Lists the groups of editor tools available here (one per open editor or feature): name, title, what it covers, its agent skill, how many tools it has and whether they are in your tool list (`enabled`: all, some or none). Start here, then call search_tools or enable_tools.",
283
+ description: "Lists the groups of editor tools available here (one per open editor or feature): name, title, what it covers, its agent skill, its workflow skills (`workflows`: skills for whole jobs done with its tools, such as a cutout or a photo correction), how many tools it has and whether they are in your tool list (`enabled`: all, some or none). Start here, then call search_tools or enable_tools.",
267
284
  annotations: READ_ONLY,
268
285
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
269
286
  handler: async () => {
@@ -275,6 +292,7 @@ var ToolRegistryView = (_class = class {
275
292
  ...set.title ? { title: set.title } : {},
276
293
  ...set.description ? { description: set.description } : {},
277
294
  ...set.skill ? { skill: set.skill } : {},
295
+ ...workflowsOf(set).length ? { workflows: workflowsOf(set) } : {},
278
296
  tools: set.tools.length,
279
297
  enabled: enabledState(set),
280
298
  ...styles[i] ? { style: styles[i] } : {}
@@ -344,7 +362,7 @@ var ToolRegistryView = (_class = class {
344
362
  tools.push({
345
363
  name: "get_skill",
346
364
  title: "Get skill",
347
- description: "Reads an agent skill: the guide to a toolset's tools (when to use each, the working method, pitfalls). Read the skill a toolset names in list_toolsets before working with it. Returns markdown; pass `file` for one of its reference files.",
365
+ description: "Reads an agent skill: the guide to a toolset's tools (when to use each, the working method, pitfalls). Read the skill a toolset names in list_toolsets before working with it. When the task is one of the jobs in its `workflows` (or in the skill's own Workflow skills section), read that workflow skill too: it has the steps in order and the checks between them. Returns markdown; pass `file` for one of its reference files.",
348
366
  annotations: READ_ONLY,
349
367
  inputSchema: {
350
368
  type: "object",
@@ -13513,7 +13513,7 @@ var DEPTH_MASK_CONTROLS = [
13513
13513
  // src/image-editor/playback.ts
13514
13514
  var IMAGE_PLAYBACK_KIND = "layer";
13515
13515
  var PAINT = /^(paint_stroke|clone_stamp|heal_brush|spot_heal|dodge|burn|sponge|smudge|blur_stroke|sharpen_stroke|history_brush|set_clone_source|set_clone_transform|fill_pixels|clear_pixels|set_paint|set_retouch_options|load_mixer_brush|clean_mixer_brush)$/;
13516
- var SELECT = /^(make_work_path|add_path|set_path_geometry|rename_path|duplicate_path|delete_path|fill_path|stroke_path|select_region|select_subject|select_by_color|select_all|deselect|invert_selection|select_rect|select_ellipse|select_polygon|quick_select|select_object|select_focus_area|select_sky|select_line|magic_wand|grow_selection|select_similar|reselect|select_layer_transparency|select_color_range|load_selection_from_image|load_selection_from_mask|set_selection_display|modify_selection|refine_selection|transform_selection|apply_selection_as_mask|layer_via_copy|stroke_selection|content_aware_fill|copy_pixels|cut_pixels|paste_pixels|save_selection|load_selection_from_channel|set_channel_properties|duplicate_channel|delete_channel|load_channel_from_image|set_quick_mask|path_to_selection|select_text_shape)$/;
13516
+ var SELECT = /^(make_work_path|add_path|set_path_geometry|rename_path|duplicate_path|delete_path|fill_path|stroke_path|select_region|select_subject|select_by_color|select_all|deselect|invert_selection|select_rect|select_ellipse|select_polygon|quick_select|select_object|select_focus_area|select_sky|select_line|magic_wand|grow_selection|select_similar|reselect|select_layer_transparency|select_color_range|load_selection_from_image|load_selection_from_mask|set_selection_display|modify_selection|refine_selection|transform_selection|apply_selection_as_mask|layer_via_copy|stroke_selection|content_aware_fill|copy_pixels|cut_pixels|paste_pixels|save_selection|load_selection_from_channel|set_channel_properties|duplicate_channel|delete_channel|load_channel_from_image|set_quick_mask|path_to_selection|select_text_shape|compare_selections|edit_selection_step|insert_selection_step|remove_selection_step|freeze_selection|separate_subject)$/;
13517
13517
  var ANNOTATE = /^(add_shape_layer|update_shape|add_shape_component|set_shape_component|remove_shape_component|merge_shape_components|add_text_layer|set_text|set_text_style|set_paragraph_style|set_text_frame|set_text_orientation|convert_text_to_shape)$/;
13518
13518
  var CROP = /^(set_crop|crop_to_selection|reset_crop|set_rotation|flip_image|transform_layer|warp_layer|flip_layer|offset_layer)$/;
13519
13519
  var ADJUST = /^(set_adjustments|add_adjustment_layer|update_adjustment_layer|remove_adjustment_layer|move_adjustment_layer)$/;
@@ -13523,7 +13523,7 @@ function imagePlaybackPanel(tool) {
13523
13523
  if (SELECT.test(tool)) return "select";
13524
13524
  if (ANNOTATE.test(tool)) return "annotate";
13525
13525
  if (CROP.test(tool)) return "crop";
13526
- if (/layer|effect|filter|smart|group|mask|merge|flatten|profile|colors|proof|light/.test(tool)) return "layers";
13526
+ if (/layer|effect|filter|smart|group|mask|merge|flatten|profile|colors|proof|light|^set_edge_/.test(tool)) return "layers";
13527
13527
  return null;
13528
13528
  }
13529
13529
  function createImagePlaybackLocator(controller) {
@@ -20878,12 +20878,12 @@ async function addLayerOfKind(controller, id, init) {
20878
20878
  throw new Error(`Unknown layer kind "${id}"`);
20879
20879
  }
20880
20880
  function layerPanels(layer, options = {}) {
20881
- if (!layer) {
20882
- return [
20883
- { id: "canvas-size", title: "Composition Size" },
20884
- { id: "selection", title: "Selection" }
20885
- ];
20886
- }
20881
+ const documentPanels = [
20882
+ { id: "selection", title: "Selection" },
20883
+ { id: "channels", title: "Channels" },
20884
+ { id: "paths", title: "Paths" }
20885
+ ];
20886
+ if (!layer) return [{ id: "canvas-size", title: "Composition Size" }, ...documentPanels];
20887
20887
  const panels = [{ id: "properties", title: "Layer Properties" }];
20888
20888
  const effects = () => {
20889
20889
  if (options.effects) panels.push({ id: "provider-effects", title: "Effects" });
@@ -20902,10 +20902,10 @@ function layerPanels(layer, options = {}) {
20902
20902
  } else if (layer.type === "smart" || layer.type === "group") {
20903
20903
  effects();
20904
20904
  }
20905
- if (layer.mask) {
20906
- panels.push({ id: "mask", title: "Mask Options" });
20905
+ if (layer.mask || layer.vectorMask) {
20906
+ panels.push({ id: "mask", title: "Mask & Edges" });
20907
20907
  }
20908
- panels.push({ id: "selection", title: "Selection" });
20908
+ panels.push(...documentPanels);
20909
20909
  return panels;
20910
20910
  }
20911
20911
 
@@ -21975,6 +21975,7 @@ function imageToolPanel(tool) {
21975
21975
  if (tool === "move") return null;
21976
21976
  if (isPaintTool(tool)) return "paint";
21977
21977
  if (tool === "select") return "selection";
21978
+ if (tool === "path-pen" || tool === "path-select" || tool === "direct-select") return "paths";
21978
21979
  if (tool === "crop") return "canvas-size";
21979
21980
  if (tool === "shape" || tool === "type") return tool;
21980
21981
  return null;
@@ -13513,7 +13513,7 @@ var DEPTH_MASK_CONTROLS = [
13513
13513
  // src/image-editor/playback.ts
13514
13514
  var IMAGE_PLAYBACK_KIND = "layer";
13515
13515
  var PAINT = /^(paint_stroke|clone_stamp|heal_brush|spot_heal|dodge|burn|sponge|smudge|blur_stroke|sharpen_stroke|history_brush|set_clone_source|set_clone_transform|fill_pixels|clear_pixels|set_paint|set_retouch_options|load_mixer_brush|clean_mixer_brush)$/;
13516
- var SELECT = /^(make_work_path|add_path|set_path_geometry|rename_path|duplicate_path|delete_path|fill_path|stroke_path|select_region|select_subject|select_by_color|select_all|deselect|invert_selection|select_rect|select_ellipse|select_polygon|quick_select|select_object|select_focus_area|select_sky|select_line|magic_wand|grow_selection|select_similar|reselect|select_layer_transparency|select_color_range|load_selection_from_image|load_selection_from_mask|set_selection_display|modify_selection|refine_selection|transform_selection|apply_selection_as_mask|layer_via_copy|stroke_selection|content_aware_fill|copy_pixels|cut_pixels|paste_pixels|save_selection|load_selection_from_channel|set_channel_properties|duplicate_channel|delete_channel|load_channel_from_image|set_quick_mask|path_to_selection|select_text_shape)$/;
13516
+ var SELECT = /^(make_work_path|add_path|set_path_geometry|rename_path|duplicate_path|delete_path|fill_path|stroke_path|select_region|select_subject|select_by_color|select_all|deselect|invert_selection|select_rect|select_ellipse|select_polygon|quick_select|select_object|select_focus_area|select_sky|select_line|magic_wand|grow_selection|select_similar|reselect|select_layer_transparency|select_color_range|load_selection_from_image|load_selection_from_mask|set_selection_display|modify_selection|refine_selection|transform_selection|apply_selection_as_mask|layer_via_copy|stroke_selection|content_aware_fill|copy_pixels|cut_pixels|paste_pixels|save_selection|load_selection_from_channel|set_channel_properties|duplicate_channel|delete_channel|load_channel_from_image|set_quick_mask|path_to_selection|select_text_shape|compare_selections|edit_selection_step|insert_selection_step|remove_selection_step|freeze_selection|separate_subject)$/;
13517
13517
  var ANNOTATE = /^(add_shape_layer|update_shape|add_shape_component|set_shape_component|remove_shape_component|merge_shape_components|add_text_layer|set_text|set_text_style|set_paragraph_style|set_text_frame|set_text_orientation|convert_text_to_shape)$/;
13518
13518
  var CROP = /^(set_crop|crop_to_selection|reset_crop|set_rotation|flip_image|transform_layer|warp_layer|flip_layer|offset_layer)$/;
13519
13519
  var ADJUST = /^(set_adjustments|add_adjustment_layer|update_adjustment_layer|remove_adjustment_layer|move_adjustment_layer)$/;
@@ -13523,7 +13523,7 @@ function imagePlaybackPanel(tool) {
13523
13523
  if (SELECT.test(tool)) return "select";
13524
13524
  if (ANNOTATE.test(tool)) return "annotate";
13525
13525
  if (CROP.test(tool)) return "crop";
13526
- if (/layer|effect|filter|smart|group|mask|merge|flatten|profile|colors|proof|light/.test(tool)) return "layers";
13526
+ if (/layer|effect|filter|smart|group|mask|merge|flatten|profile|colors|proof|light|^set_edge_/.test(tool)) return "layers";
13527
13527
  return null;
13528
13528
  }
13529
13529
  function createImagePlaybackLocator(controller) {
@@ -20878,12 +20878,12 @@ async function addLayerOfKind(controller, id, init) {
20878
20878
  throw new Error(`Unknown layer kind "${id}"`);
20879
20879
  }
20880
20880
  function layerPanels(layer, options = {}) {
20881
- if (!layer) {
20882
- return [
20883
- { id: "canvas-size", title: "Composition Size" },
20884
- { id: "selection", title: "Selection" }
20885
- ];
20886
- }
20881
+ const documentPanels = [
20882
+ { id: "selection", title: "Selection" },
20883
+ { id: "channels", title: "Channels" },
20884
+ { id: "paths", title: "Paths" }
20885
+ ];
20886
+ if (!layer) return [{ id: "canvas-size", title: "Composition Size" }, ...documentPanels];
20887
20887
  const panels = [{ id: "properties", title: "Layer Properties" }];
20888
20888
  const effects = () => {
20889
20889
  if (options.effects) panels.push({ id: "provider-effects", title: "Effects" });
@@ -20902,10 +20902,10 @@ function layerPanels(layer, options = {}) {
20902
20902
  } else if (layer.type === "smart" || layer.type === "group") {
20903
20903
  effects();
20904
20904
  }
20905
- if (layer.mask) {
20906
- panels.push({ id: "mask", title: "Mask Options" });
20905
+ if (layer.mask || layer.vectorMask) {
20906
+ panels.push({ id: "mask", title: "Mask & Edges" });
20907
20907
  }
20908
- panels.push({ id: "selection", title: "Selection" });
20908
+ panels.push(...documentPanels);
20909
20909
  return panels;
20910
20910
  }
20911
20911
 
@@ -21975,6 +21975,7 @@ function imageToolPanel(tool) {
21975
21975
  if (tool === "move") return null;
21976
21976
  if (isPaintTool(tool)) return "paint";
21977
21977
  if (tool === "select") return "selection";
21978
+ if (tool === "path-pen" || tool === "path-select" || tool === "direct-select") return "paths";
21978
21979
  if (tool === "crop") return "canvas-size";
21979
21980
  if (tool === "shape" || tool === "type") return tool;
21980
21981
  return null;
@@ -156,7 +156,11 @@ export interface LayerPanelsOptions {
156
156
  *
157
157
  * `properties` ("Layer Properties") is first for every layer and includes the layer's Layer Style
158
158
  * (drop shadow, stroke, glow…: `layerEffectsPanel`) for layers that can take one, with or without a
159
- * provider. There is no separate `effects` (Layer Effects) or `smart-filters` panel. `selection`
160
- * is last for every layer, and with no active layer follows `canvas-size`.
159
+ * provider. There is no separate `effects` (Layer Effects) or `smart-filters` panel. `mask`
160
+ * ("Mask & Edges": a vector mask's per-segment edges and the layer's edge colour) shows for a layer
161
+ * with a painted or vector mask. The document's panels end the list for every layer, and with no
162
+ * active layer follow `canvas-size`: `selection` (the selection tools and Refine Edge), `channels`
163
+ * and `paths`. A host that lays out its own sidebar from these gets every panel the editor's own
164
+ * `ImageEditor` shows.
161
165
  */
162
166
  export declare function layerPanels(layer: ImageLayer | null, options?: LayerPanelsOptions): LayerPanelDescriptor[];
@@ -156,7 +156,11 @@ export interface LayerPanelsOptions {
156
156
  *
157
157
  * `properties` ("Layer Properties") is first for every layer and includes the layer's Layer Style
158
158
  * (drop shadow, stroke, glow…: `layerEffectsPanel`) for layers that can take one, with or without a
159
- * provider. There is no separate `effects` (Layer Effects) or `smart-filters` panel. `selection`
160
- * is last for every layer, and with no active layer follows `canvas-size`.
159
+ * provider. There is no separate `effects` (Layer Effects) or `smart-filters` panel. `mask`
160
+ * ("Mask & Edges": a vector mask's per-segment edges and the layer's edge colour) shows for a layer
161
+ * with a painted or vector mask. The document's panels end the list for every layer, and with no
162
+ * active layer follow `canvas-size`: `selection` (the selection tools and Refine Edge), `channels`
163
+ * and `paths`. A host that lays out its own sidebar from these gets every panel the editor's own
164
+ * `ImageEditor` shows.
161
165
  */
162
166
  export declare function layerPanels(layer: ImageLayer | null, options?: LayerPanelsOptions): LayerPanelDescriptor[];
@@ -8,12 +8,12 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkU4QN36YTcjs = require('../chunk-U4QN36YT.cjs');
12
11
 
13
12
 
14
13
 
15
14
 
16
15
 
16
+ var _chunkBDT2IYXKcjs = require('../chunk-BDT2IYXK.cjs');
17
17
 
18
18
 
19
19
 
@@ -34,7 +34,12 @@ var _chunkU4QN36YTcjs = require('../chunk-U4QN36YT.cjs');
34
34
 
35
35
 
36
36
 
37
- var _chunkAMX23CSNcjs = require('../chunk-AMX23CSN.cjs');
37
+
38
+
39
+
40
+
41
+
42
+ var _chunkZ7BVK32Ccjs = require('../chunk-Z7BVK32C.cjs');
38
43
 
39
44
 
40
45
 
@@ -189,4 +194,9 @@ var _chunk2BSBFBOAcjs = require('../chunk-2BSBFBOA.cjs');
189
194
 
190
195
 
191
196
 
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;
197
+
198
+
199
+
200
+
201
+
202
+ 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 = _chunkZ7BVK32Ccjs.JSON_RPC_ERRORS; exports.MCP_PROTOCOL_VERSIONS = _chunkZ7BVK32Ccjs.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 = _chunkZ7BVK32Ccjs.TOOL_BRIDGE_DEFAULT_PORT; exports.TOOL_BRIDGE_PROTOCOL = _chunkZ7BVK32Ccjs.TOOL_BRIDGE_PROTOCOL; exports.TOOL_DISCOVERY_TOOLS = _chunkZ7BVK32Ccjs.TOOL_DISCOVERY_TOOLS; exports.TOOL_NAMESPACE_SEPARATOR = _chunkZ7BVK32Ccjs.TOOL_NAMESPACE_SEPARATOR; exports.ToolRegistry = _chunkZ7BVK32Ccjs.ToolRegistry; exports.ToolRegistryError = _chunkZ7BVK32Ccjs.ToolRegistryError; exports.ToolRegistryView = _chunkZ7BVK32Ccjs.ToolRegistryView; exports.UNSAFE_JSON_KEYS = _chunk2BSBFBOAcjs.UNSAFE_JSON_KEYS; exports.baseToolName = _chunkZ7BVK32Ccjs.baseToolName; exports.callEvalTool = _chunkBDT2IYXKcjs.callEvalTool; exports.captureInputSchema = _chunkN2FGYZ4Qcjs.captureInputSchema; exports.captureOutputSize = _chunkN2FGYZ4Qcjs.captureOutputSize; exports.cloneElementWithStyles = _chunkSVFEVKLFcjs.cloneElementWithStyles; exports.connectToolBridge = _chunkZ7BVK32Ccjs.connectToolBridge; exports.createAgentPlayback = _chunk3SLBXKAWcjs.createAgentPlayback; exports.createCaptureTool = _chunkN2FGYZ4Qcjs.createCaptureTool; exports.createCaptureToolProvider = _chunkN2FGYZ4Qcjs.createCaptureToolProvider; exports.createElementCaptureSurface = _chunkSVFEVKLFcjs.createElementCaptureSurface; exports.createInstantPresenceClock = _chunkK7ENM55Pcjs.createInstantPresenceClock; exports.createMcpServer = _chunkZ7BVK32Ccjs.createMcpServer; exports.createPlaybackToolProvider = _chunk3SLBXKAWcjs.createPlaybackToolProvider; exports.createStyleResolver = _chunkBDT2IYXKcjs.createStyleResolver; exports.createStyleToolProvider = _chunkBDT2IYXKcjs.createStyleToolProvider; exports.createToolRegistry = _chunkZ7BVK32Ccjs.createToolRegistry; exports.derivePlaybackSteps = _chunk3SLBXKAWcjs.derivePlaybackSteps; exports.elementToSvg = _chunkSVFEVKLFcjs.elementToSvg; exports.errorResult = _chunkZ7BVK32Ccjs.errorResult; exports.failedEvalChecks = _chunkBDT2IYXKcjs.failedEvalChecks; exports.imageEvalFixturePixels = _chunkBDT2IYXKcjs.imageEvalFixturePixels; exports.isUnsafeJsonKey = _chunk2BSBFBOAcjs.isUnsafeJsonKey; exports.listSkillEvals = _chunkBDT2IYXKcjs.listSkillEvals; exports.listSkills = _chunkZ7BVK32Ccjs.listSkills; exports.locatePlaybackChrome = _chunk3SLBXKAWcjs.locatePlaybackChrome; exports.matchesEvalExpectation = _chunkBDT2IYXKcjs.matchesEvalExpectation; exports.memoryStyleStore = _chunkBDT2IYXKcjs.memoryStyleStore; exports.parseSkillFrontmatter = _chunkZ7BVK32Ccjs.parseSkillFrontmatter; exports.parseStyleDomains = _chunkBDT2IYXKcjs.parseStyleDomains; exports.playbackRectFromClient = _chunk3SLBXKAWcjs.playbackRectFromClient; exports.playbackRefsFromArgs = _chunk3SLBXKAWcjs.playbackRefsFromArgs; exports.playbackRefsFromResult = _chunk3SLBXKAWcjs.playbackRefsFromResult; exports.rasterizeElement = _chunkSVFEVKLFcjs.rasterizeElement; exports.readSkillFile = _chunkZ7BVK32Ccjs.readSkillFile; exports.readingTime = _chunk3SLBXKAWcjs.readingTime; exports.realPresenceClock = _chunkK7ENM55Pcjs.realPresenceClock; exports.renderStyle = _chunkBDT2IYXKcjs.renderStyle; exports.resolveCaptureRequest = _chunkN2FGYZ4Qcjs.resolveCaptureRequest; exports.runStyleChecks = _chunkBDT2IYXKcjs.runStyleChecks; exports.runToolScript = _chunkBDT2IYXKcjs.runToolScript; exports.searchTokens = _chunkZ7BVK32Ccjs.searchTokens; exports.searchTools = _chunkZ7BVK32Ccjs.searchTools; exports.stripPrototypeKeys = _chunk2BSBFBOAcjs.stripPrototypeKeys; exports.summarize = _chunkZ7BVK32Ccjs.summarize; exports.toCapturedImageData = _chunkN2FGYZ4Qcjs.toCapturedImageData; exports.toToolResult = _chunkZ7BVK32Ccjs.toToolResult; exports.toolResultError = _chunkBDT2IYXKcjs.toolResultError; exports.toolResultValue = _chunkBDT2IYXKcjs.toolResultValue; exports.toolsetInstructions = _chunkZ7BVK32Ccjs.toolsetInstructions; exports.toolsetName = _chunkZ7BVK32Ccjs.toolsetName; exports.trackPresenceDrag = _chunkK7ENM55Pcjs.trackPresenceDrag; exports.tweenPresenceCursor = _chunkK7ENM55Pcjs.tweenPresenceCursor; exports.unionCaptureRects = _chunkN2FGYZ4Qcjs.unionCaptureRects; exports.unionRects = _chunk3SLBXKAWcjs.unionRects; exports.unknownToolMessage = _chunkZ7BVK32Ccjs.unknownToolMessage; exports.validateJsonSchema = _chunkWOFXZ3XUcjs.validateJsonSchema;
@@ -17,6 +17,7 @@ export * from './dom-capture.cjs';
17
17
  export * from './view.cjs';
18
18
  export * from './search.cjs';
19
19
  export * from './skills.cjs';
20
+ export * from './skill-evals.cjs';
20
21
  export * from './safe-json.cjs';
21
22
  export * from './presence.cjs';
22
23
  export * from './playback.cjs';
@@ -17,6 +17,7 @@ export * from './dom-capture.js';
17
17
  export * from './view.js';
18
18
  export * from './search.js';
19
19
  export * from './skills.js';
20
+ export * from './skill-evals.js';
20
21
  export * from './safe-json.js';
21
22
  export * from './presence.js';
22
23
  export * from './playback.js';
@@ -1,6 +1,11 @@
1
1
  import {
2
+ callEvalTool,
2
3
  createStyleResolver,
3
4
  createStyleToolProvider,
5
+ failedEvalChecks,
6
+ imageEvalFixturePixels,
7
+ listSkillEvals,
8
+ matchesEvalExpectation,
4
9
  memoryStyleStore,
5
10
  parseStyleDomains,
6
11
  renderStyle,
@@ -8,7 +13,7 @@ import {
8
13
  runToolScript,
9
14
  toolResultError,
10
15
  toolResultValue
11
- } from "../chunk-GI3AVES4.js";
16
+ } from "../chunk-SVHXD2VH.js";
12
17
  import {
13
18
  JSON_RPC_ERRORS,
14
19
  MCP_PROTOCOL_VERSIONS,
@@ -34,7 +39,7 @@ import {
34
39
  toolsetInstructions,
35
40
  toolsetName,
36
41
  unknownToolMessage
37
- } from "../chunk-XZB3TJ6K.js";
42
+ } from "../chunk-SAN4SBBS.js";
38
43
  import {
39
44
  AgentPlayback,
40
45
  createAgentPlayback,
@@ -139,6 +144,7 @@ export {
139
144
  ToolRegistryView,
140
145
  UNSAFE_JSON_KEYS,
141
146
  baseToolName,
147
+ callEvalTool,
142
148
  captureInputSchema,
143
149
  captureOutputSize,
144
150
  cloneElementWithStyles,
@@ -156,9 +162,13 @@ export {
156
162
  derivePlaybackSteps,
157
163
  elementToSvg,
158
164
  errorResult,
165
+ failedEvalChecks,
166
+ imageEvalFixturePixels,
159
167
  isUnsafeJsonKey,
168
+ listSkillEvals,
160
169
  listSkills,
161
170
  locatePlaybackChrome,
171
+ matchesEvalExpectation,
162
172
  memoryStyleStore,
163
173
  parseSkillFrontmatter,
164
174
  parseStyleDomains,
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The evals that workflow skills ship in `skills/<name>/evals/*.json`, for any harness to run.
3
+ *
4
+ * An eval is a task a model would be given (`prompt`), the document it starts from
5
+ * (`fixture`), the checks that decide whether the job was done (`checks`: a read tool, its
6
+ * arguments and what its result must match) and one known-good answer (`solution`: the tool
7
+ * calls an expert would make). The package's own tests prove each eval with its `solution`; an
8
+ * agent harness builds the fixture, gives its model the `prompt` in place of the solution, then
9
+ * runs `failedEvalChecks`. The format is described in `skills/README.md`.
10
+ */
11
+ import type { McpToolResult } from './registry.cjs';
12
+ export interface SkillEvalToolCall {
13
+ tool: string;
14
+ args?: Record<string, unknown>;
15
+ }
16
+ export interface SkillEvalCheck extends SkillEvalToolCall {
17
+ /** What the check is for, shown when it fails. */
18
+ why: string;
19
+ expect: unknown;
20
+ }
21
+ export interface SkillEval {
22
+ prompt: string;
23
+ fixture: SpreadsheetEvalFixture | ImageEvalFixture | VectorEvalFixture | PaintEvalFixture | VideoEvalFixture;
24
+ checks: SkillEvalCheck[];
25
+ solution: SkillEvalToolCall[];
26
+ }
27
+ export interface SpreadsheetEvalFixture {
28
+ editor: 'spreadsheet';
29
+ /** Raw inputs from A1, row by row, typed as a person would (`'` forces text). */
30
+ rows: Array<Array<string | number | boolean | null>>;
31
+ }
32
+ export interface ImageEvalFixture {
33
+ editor: 'image';
34
+ width: number;
35
+ height: number;
36
+ /** RGB background. */
37
+ background: [number, number, number];
38
+ /** Shapes painted over it in order, with RGB colours. */
39
+ shapes: Array<{
40
+ shape: 'rect' | 'ellipse';
41
+ x: number;
42
+ y: number;
43
+ width: number;
44
+ height: number;
45
+ color: [number, number, number];
46
+ }>;
47
+ }
48
+ export interface VectorEvalFixture {
49
+ editor: 'vector';
50
+ width: number;
51
+ height: number;
52
+ /** Commands that build the starting artwork, run in order (`"$0.id"` refers to an earlier result). */
53
+ setup?: Array<{
54
+ id: string;
55
+ params?: Record<string, unknown>;
56
+ }>;
57
+ }
58
+ export interface PaintEvalFixture {
59
+ editor: 'paint';
60
+ width: number;
61
+ height: number;
62
+ /** Tool calls that prepare the canvas (paper, layers, strokes), run in order. */
63
+ setup?: SkillEvalToolCall[];
64
+ }
65
+ export interface VideoEvalFixture {
66
+ editor: 'video';
67
+ /** Tool calls that build the starting project (settings, assets, clips, markers), run in order. */
68
+ setup?: SkillEvalToolCall[];
69
+ }
70
+ /** One eval file of a skill. */
71
+ export interface SkillEvalFile {
72
+ skill: string;
73
+ /** Path relative to the skills directory, e.g. `pixerate-image-selection-masking/evals/local-adjustment.json`. */
74
+ path: string;
75
+ eval: SkillEval;
76
+ }
77
+ /**
78
+ * The evals in a set of skill files (paths relative to the skills directory, contents as text,
79
+ * like `SkillFiles` but including `evals/*.json`), sorted by path.
80
+ */
81
+ export declare function listSkillEvals(files: Readonly<Record<string, string>>): SkillEvalFile[];
82
+ /** The RGBA pixels of an image fixture: shapes painted over the background in order. */
83
+ export declare function imageEvalFixturePixels(f: ImageEvalFixture): {
84
+ width: number;
85
+ height: number;
86
+ data: Uint8ClampedArray;
87
+ };
88
+ /** Calls a tool by the bare name an eval uses; the harness maps it to its own names if it must. */
89
+ export type SkillEvalToolCaller = (tool: string, args: Record<string, unknown>) => Promise<McpToolResult>;
90
+ /** Calls one eval tool step (resolving `$read` arguments); throws with the tool's error text. */
91
+ export declare function callEvalTool(callTool: SkillEvalToolCaller, { tool, args }: SkillEvalToolCall): Promise<unknown>;
92
+ /**
93
+ * Whether `actual` matches `expected`. Objects match key by key (other keys are ignored),
94
+ * arrays element by element with the same length, other values exactly. Operators:
95
+ * `$min` / `$max` (numbers), `$type`, `$match` (a regular expression, or `[pattern, flags]`), `$in`, `$not`,
96
+ * `$every` / `$some` (array elements), `$length`, `$unique`, `$distinct` (the distinct
97
+ * values), `$sum`, `$column: [index, matcher]` (one column of a 2D array), `$nonEmpty`
98
+ * (the array without empty cells or rows) and `$expr` (a JavaScript expression over `v`).
99
+ */
100
+ export declare function matchesEvalExpectation(actual: unknown, expected: unknown): boolean;
101
+ /** The checks that fail, each as its `why` with what the tool returned (or its error). */
102
+ export declare function failedEvalChecks(callTool: SkillEvalToolCaller, checks: readonly SkillEvalCheck[]): Promise<string[]>;