@pixerate/editor 0.146.0 → 0.148.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 (132) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +1 -1
  3. package/dist/agent/index.cjs +36 -34
  4. package/dist/agent/index.js +7 -5
  5. package/dist/animation/index.cjs +5 -3
  6. package/dist/animation/index.js +4 -2
  7. package/dist/animation-editor/index.cjs +62 -60
  8. package/dist/animation-editor/index.js +6 -4
  9. package/dist/canvas/index.cjs +36 -34
  10. package/dist/canvas/index.js +19 -17
  11. package/dist/chart/index.cjs +88 -86
  12. package/dist/chart/index.js +7 -5
  13. package/dist/{chunk-WBJ6BG4R.js → chunk-2AQL4JHM.js} +6 -6
  14. package/dist/{chunk-HLMF3E53.cjs → chunk-2WDZI6QD.cjs} +15 -15
  15. package/dist/{chunk-ZNHB5RG6.js → chunk-37RLSNQ3.js} +2 -2
  16. package/dist/{chunk-5WOY52O6.cjs → chunk-4YQKRHMI.cjs} +8 -8
  17. package/dist/chunk-6ONMQ6WF.js +113 -0
  18. package/dist/{chunk-L434J57V.cjs → chunk-6QTON3VW.cjs} +16 -16
  19. package/dist/chunk-AA34BA7G.js +1913 -0
  20. package/dist/{chunk-QX25HWFL.js → chunk-AY65VQSU.js} +1 -1
  21. package/dist/{chunk-ONZJD2OD.cjs → chunk-BROJYMWU.cjs} +57 -153
  22. package/dist/{chunk-YM75DN54.js → chunk-DSZCDNTM.js} +1 -1
  23. package/dist/{chunk-PUR6BZFA.cjs → chunk-DVLMW3GB.cjs} +53 -53
  24. package/dist/{chunk-ALUWD3FG.js → chunk-EIUTJPEL.js} +1 -1
  25. package/dist/{chunk-X65C4DWV.js → chunk-EQ4SF4X4.js} +1 -1
  26. package/dist/{chunk-77SG47WT.js → chunk-FLOGD3QB.js} +1 -1
  27. package/dist/{chunk-AJSW5GMP.js → chunk-HVQVHUTV.js} +19 -115
  28. package/dist/{chunk-UR37VCIR.cjs → chunk-I4AHLP7F.cjs} +16 -35
  29. package/dist/chunk-IPJ3TEYR.cjs +113 -0
  30. package/dist/chunk-KY3FYKP3.js +52 -0
  31. package/dist/chunk-LEUZ4FRC.cjs +52 -0
  32. package/dist/{chunk-H6FX45CP.cjs → chunk-LIXLD433.cjs} +37 -37
  33. package/dist/{chunk-6GAYGQDC.js → chunk-O5ML2I6O.js} +3 -3
  34. package/dist/{chunk-KI2VBONS.js → chunk-OET45HIR.js} +2 -2
  35. package/dist/{chunk-XNZWATSB.cjs → chunk-QCEQIRJQ.cjs} +85 -85
  36. package/dist/{chunk-HRI3ZMDM.cjs → chunk-RHXW4TA5.cjs} +3 -3
  37. package/dist/{chunk-UUTTJK77.cjs → chunk-SUF6WRXR.cjs} +2 -2
  38. package/dist/{chunk-RN767PO6.js → chunk-SUVZJ2CP.js} +15 -34
  39. package/dist/{chunk-FLUTRPLY.cjs → chunk-TLMRGLQQ.cjs} +16 -16
  40. package/dist/{chunk-DAS7M4RY.js → chunk-UILRJQFD.js} +2 -2
  41. package/dist/chunk-UKCJ43YL.cjs +1913 -0
  42. package/dist/{chunk-XQ33O5BC.cjs → chunk-X35BV5YT.cjs} +44 -44
  43. package/dist/{chunk-6HMEHNWW.cjs → chunk-XTU6QO2W.cjs} +26 -26
  44. package/dist/{chunk-VM6JYWXQ.js → chunk-ZQUANEK4.js} +2 -2
  45. package/dist/cms/index.cjs +5 -3
  46. package/dist/cms/index.js +18 -16
  47. package/dist/color/contrast.d.cts +14 -0
  48. package/dist/color/contrast.d.ts +14 -0
  49. package/dist/color/convert.d.cts +30 -0
  50. package/dist/color/convert.d.ts +30 -0
  51. package/dist/color/dual.d.cts +98 -0
  52. package/dist/color/dual.d.ts +98 -0
  53. package/dist/color/format.d.cts +12 -0
  54. package/dist/color/format.d.ts +12 -0
  55. package/dist/color/gamut.d.cts +12 -0
  56. package/dist/color/gamut.d.ts +12 -0
  57. package/dist/color/harmony.d.cts +22 -0
  58. package/dist/color/harmony.d.ts +22 -0
  59. package/dist/color/index.cjs +115 -0
  60. package/dist/color/index.d.cts +18 -0
  61. package/dist/color/index.d.ts +18 -0
  62. package/dist/color/index.js +115 -0
  63. package/dist/color/mix.d.cts +11 -0
  64. package/dist/color/mix.d.ts +11 -0
  65. package/dist/color/named.d.cts +5 -0
  66. package/dist/color/named.d.ts +5 -0
  67. package/dist/color/parse.d.cts +11 -0
  68. package/dist/color/parse.d.ts +11 -0
  69. package/dist/color/picker.d.cts +52 -0
  70. package/dist/color/picker.d.ts +52 -0
  71. package/dist/color/recent.d.cts +8 -0
  72. package/dist/color/recent.d.ts +8 -0
  73. package/dist/color/tools.d.cts +15 -0
  74. package/dist/color/tools.d.ts +15 -0
  75. package/dist/color/types.d.cts +41 -0
  76. package/dist/color/types.d.ts +41 -0
  77. package/dist/color/vision.d.cts +36 -0
  78. package/dist/color/vision.d.ts +36 -0
  79. package/dist/effects/authoring-session.d.cts +25 -0
  80. package/dist/effects/authoring-session.d.ts +25 -0
  81. package/dist/effects/authoring-tools.d.cts +31 -0
  82. package/dist/effects/authoring-tools.d.ts +31 -0
  83. package/dist/effects/authoring.d.cts +152 -0
  84. package/dist/effects/authoring.d.ts +152 -0
  85. package/dist/effects/conformance.d.cts +2 -0
  86. package/dist/effects/conformance.d.ts +2 -0
  87. package/dist/effects/fake.d.cts +2 -0
  88. package/dist/effects/fake.d.ts +2 -0
  89. package/dist/effects/index.cjs +1216 -9
  90. package/dist/effects/index.d.cts +3 -0
  91. package/dist/effects/index.d.ts +3 -0
  92. package/dist/effects/index.js +1210 -3
  93. package/dist/effects/types.d.cts +9 -2
  94. package/dist/effects/types.d.ts +9 -2
  95. package/dist/effects/ui.d.cts +8 -0
  96. package/dist/effects/ui.d.ts +8 -0
  97. package/dist/export/index.cjs +6 -4
  98. package/dist/export/index.js +5 -3
  99. package/dist/extensions/index.cjs +10 -8
  100. package/dist/extensions/index.js +9 -7
  101. package/dist/gradient/controller.d.cts +109 -0
  102. package/dist/gradient/controller.d.ts +109 -0
  103. package/dist/gradient/editor.d.cts +38 -0
  104. package/dist/gradient/editor.d.ts +38 -0
  105. package/dist/gradient/index.cjs +1549 -0
  106. package/dist/gradient/index.d.cts +5 -0
  107. package/dist/gradient/index.d.ts +5 -0
  108. package/dist/gradient/index.js +1549 -0
  109. package/dist/gradient/model.d.cts +94 -0
  110. package/dist/gradient/model.d.ts +94 -0
  111. package/dist/gradient/tools.d.cts +11 -0
  112. package/dist/gradient/tools.d.ts +11 -0
  113. package/dist/gradient/types.d.cts +44 -0
  114. package/dist/gradient/types.d.ts +44 -0
  115. package/dist/image-editor/index.cjs +649 -647
  116. package/dist/image-editor/index.js +6 -4
  117. package/dist/index.cjs +19 -17
  118. package/dist/index.js +16 -14
  119. package/dist/paint-editor/color.d.cts +3 -13
  120. package/dist/paint-editor/color.d.ts +3 -13
  121. package/dist/paint-editor/index.cjs +23 -68
  122. package/dist/paint-editor/index.js +15 -60
  123. package/dist/vector/index.cjs +950 -948
  124. package/dist/vector/index.js +5 -3
  125. package/dist/video-editor/index.cjs +5 -3
  126. package/dist/video-editor/index.js +4 -2
  127. package/package.json +21 -1
  128. package/skills/README.md +2 -0
  129. package/skills/pixerate-color/SKILL.md +69 -0
  130. package/skills/pixerate-effect-authoring/SKILL.md +80 -0
  131. package/dist/chunk-45VRG4RB.js +0 -65
  132. package/dist/chunk-5FXOR7F2.cjs +0 -65
@@ -38,7 +38,7 @@ import {
38
38
  reverseMorphContour,
39
39
  subpathToMorphContour,
40
40
  turnMorphContour
41
- } from "../chunk-DAS7M4RY.js";
41
+ } from "../chunk-UILRJQFD.js";
42
42
  import {
43
43
  DEFAULT_VECTOR_FONT,
44
44
  IDENTITY_MATRIX,
@@ -507,7 +507,7 @@ import {
507
507
  withVectorStrokes,
508
508
  withVectorTargetPaint,
509
509
  zigzagPaths
510
- } from "../chunk-77SG47WT.js";
510
+ } from "../chunk-FLOGD3QB.js";
511
511
  import "../chunk-ORDXMBD4.js";
512
512
  import {
513
513
  createProvenance
@@ -562,10 +562,12 @@ import {
562
562
  HistoryManager
563
563
  } from "../chunk-RNSANXPT.js";
564
564
  import "../chunk-5UJHB3BW.js";
565
- import "../chunk-45VRG4RB.js";
565
+ import "../chunk-KY3FYKP3.js";
566
566
  import {
567
567
  hexToRgba
568
568
  } from "../chunk-2WPNAGHI.js";
569
+ import "../chunk-AA34BA7G.js";
570
+ import "../chunk-6ONMQ6WF.js";
569
571
 
570
572
  // src/vector/trace.ts
571
573
  var VECTOR_TRACE_MAX_PIXELS = 4e6;
@@ -150,10 +150,12 @@ require('../chunk-WOFXZ3XU.cjs');
150
150
  var _chunkFJ2MSI43cjs = require('../chunk-FJ2MSI43.cjs');
151
151
 
152
152
 
153
- var _chunkUUTTJK77cjs = require('../chunk-UUTTJK77.cjs');
153
+ var _chunkSUF6WRXRcjs = require('../chunk-SUF6WRXR.cjs');
154
154
  require('../chunk-DWJJI6RT.cjs');
155
- require('../chunk-5FXOR7F2.cjs');
155
+ require('../chunk-LEUZ4FRC.cjs');
156
156
  require('../chunk-A6QWKBJP.cjs');
157
+ require('../chunk-UKCJ43YL.cjs');
158
+ require('../chunk-IPJ3TEYR.cjs');
157
159
 
158
160
  // src/video-editor/parse.ts
159
161
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
@@ -2807,7 +2809,7 @@ var VideoEditorController = (_class6 = class {
2807
2809
  this.readOnly = _nullishCoalesce(options.readOnly, () => ( false));
2808
2810
  this.previewScale = checkPreviewScale(_nullishCoalesce(options.previewScale, () => ( "auto")));
2809
2811
  this.onChange = options.onChange;
2810
- this.player = new (0, _chunkUUTTJK77cjs.AnimationPlayer)({ clock: options.clock, duration: () => _chunkVKF3PWKRcjs.videoProjectDuration.call(void 0, this.project), loop: "none" });
2812
+ this.player = new (0, _chunkSUF6WRXRcjs.AnimationPlayer)({ clock: options.clock, duration: () => _chunkVKF3PWKRcjs.videoProjectDuration.call(void 0, this.project), loop: "none" });
2811
2813
  this.state = this.computeState();
2812
2814
  this.connect();
2813
2815
  }
@@ -150,10 +150,12 @@ import {
150
150
  } from "../chunk-RNSANXPT.js";
151
151
  import {
152
152
  AnimationPlayer
153
- } from "../chunk-QX25HWFL.js";
153
+ } from "../chunk-AY65VQSU.js";
154
154
  import "../chunk-5UJHB3BW.js";
155
- import "../chunk-45VRG4RB.js";
155
+ import "../chunk-KY3FYKP3.js";
156
156
  import "../chunk-2WPNAGHI.js";
157
+ import "../chunk-AA34BA7G.js";
158
+ import "../chunk-6ONMQ6WF.js";
157
159
 
158
160
  // src/video-editor/parse.ts
159
161
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.146.0",
3
+ "version": "0.148.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -234,6 +234,26 @@
234
234
  "default": "./dist/tokens/index.cjs"
235
235
  }
236
236
  },
237
+ "./color": {
238
+ "import": {
239
+ "types": "./dist/color/index.d.ts",
240
+ "default": "./dist/color/index.js"
241
+ },
242
+ "require": {
243
+ "types": "./dist/color/index.d.cts",
244
+ "default": "./dist/color/index.cjs"
245
+ }
246
+ },
247
+ "./gradient": {
248
+ "import": {
249
+ "types": "./dist/gradient/index.d.ts",
250
+ "default": "./dist/gradient/index.js"
251
+ },
252
+ "require": {
253
+ "types": "./dist/gradient/index.d.cts",
254
+ "default": "./dist/gradient/index.cjs"
255
+ }
256
+ },
237
257
  "./export": {
238
258
  "import": {
239
259
  "types": "./dist/export/index.d.ts",
package/skills/README.md CHANGED
@@ -20,6 +20,8 @@ that uses the tools can load the matching skill.
20
20
  | [`pixerate-video-editor`](pixerate-video-editor/SKILL.md) | Non-linear video editing: tracks, clips, transitions, export. |
21
21
  | [`pixerate-generation`](pixerate-generation/SKILL.md) | Planning, estimating and running paid media generation. |
22
22
  | [`pixerate-parameters`](pixerate-parameters/SKILL.md) | Effect parameters, presets and keyframes. |
23
+ | [`pixerate-effect-authoring`](pixerate-effect-authoring/SKILL.md) | Authoring shaders and procedural effects: inspecting parameters and source code, setting values and presets, keyframing animation tracks, playback timing, and previewing. |
24
+ | [`pixerate-color`](pixerate-color/SKILL.md) | Colour inspection, WCAG accessibility and contrast optimization, CVD simulation, palette audits, harmonies, and OKLab/OKLCH blends. |
23
25
 
24
26
  ## Using them
25
27
 
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: pixerate-color
3
+ description: How to inspect colours, check and optimize WCAG contrast and accessibility, check palette distinctness across colour-vision deficiencies, generate harmonic color palettes, and blend colours across OKLab, OKLCH, and sRGB color spaces. Use when asked to evaluate contrast, choose accessible colours, create colour palettes, simulate colour blindness, or blend colours.
4
+ ---
5
+
6
+ # Colour tools
7
+
8
+ The colour module provides DOM-free colour tools for inspection, WCAG accessibility validation, colour-vision deficiency simulation, palette audits, colour harmony suggestions, and perceptual blending.
9
+
10
+ ## Working method
11
+
12
+ 1. **Inspect and convert.** Run `inspect_color` to parse any hex, `rgb()`, `hsl()`, `oklch()`, or CSS named colour into standard formats (hex, rgb, hsl, oklch) and relative luminance, and to check if it fits within the sRGB gamut.
13
+ 2. **Validate contrast.** Use `check_color_contrast` to compare text foreground against a background surface. It checks against WCAG 2 AA (4.5:1 regular, 3:1 large) and AAA (7:1 regular, 4.5:1 large). If AA contrast fails, it automatically calculates and suggests an adjusted lightness in OKLCH that preserves the hue and chroma while meeting accessibility standards.
14
+ 3. **Audit palettes.** For multi-colour sets (such as chart series, UI accents, or status tags), run `check_color_palette` with the array of colours. This checks mutual perceptual distinctness under normal vision as well as protanopia, deuteranopia, and tritanopia, and verifies adequate contrast against the background surface.
15
+ 4. **Harmonies and palettes.** Run `suggest_color_harmony` with a base colour and harmony kind (`complementary`, `split-complementary`, `analogous`, `triadic`, `tetradic`, `square`, or `monochromatic`) using either standard RGB or artistic RYB colour wheels.
16
+ 5. **Perceptual blending.** Run `blend_colors` to interpolate between two colours in OKLab, OKLCH, sRGB, or sRGB-linear. Pass a factor `t` (0..1) for a single midpoint, or `steps` (2..32) for an even ramp.
17
+ 6. **Design dual colours (light and dark mode).**
18
+ - Design the light mode colour.
19
+ - Run `derive_dual_color` with the app's real surfaces to automatically generate an accessible dark mode counterpart that matches contrast.
20
+ - Run `check_dual_color_contrast` for each text and background pair across both modes.
21
+ - Fix whichever mode fails using the suggested lightness.
22
+ - Run `export_dual_colors_css` to output clean CSS custom properties using `light-dark()`, `@media (prefers-color-scheme: dark)`, or `.dark` class rules.
23
+ 7. **Inspect and edit gradients.**
24
+ - Run `get_gradient` to inspect the active gradient model, CSS output, SVG def markup, and dual-colour status.
25
+ - Run `check_gradient` to audit for crowded stops, banding risk, out-of-gamut colours, and text contrast along the ramp.
26
+ - Run `list_gradient_presets` and `apply_gradient_preset` to quickly set tested gradient compositions.
27
+ - Modify gradient structure using `set_gradient`, `set_gradient_geometry`, `add_gradient_stop`, `update_gradient_stop`, `remove_gradient_stop`, `reverse_gradient`, or `distribute_gradient_stops`.
28
+
29
+ ## Best practices
30
+
31
+ - **Accessibility first.** Always check text and icon contrast against the actual background surface. Use the suggested foreground colour when `passesAA` is false.
32
+ - **Check both modes every time.** When authoring themes, verify contrast in both light and dark modes. Never assume dark mode passes just because light mode does.
33
+ - **Don't simply invert lightness for brand colours.** When creating dark-mode variants, keep the hue and lower the chroma slightly rather than just inverting RGB channels.
34
+ - **Perceptual spaces.** Use OKLab / OKLCH for interpolation and distance metrics to avoid muddy midpoints and hue shifts common in linear RGB or HSL blending.
35
+ - **Palette distinctness.** In data visualizations and charts, ensure colours can be distinguished not only under normal vision but also under deuteranopia and protanopia.
36
+ - **Alpha in contrast checks.** A translucent foreground is composited over the background, and a translucent background over white, before the ratio is taken. If the real backdrop behind a translucent background isn't white, pass the opaque colour the user actually sees.
37
+
38
+ ## Tool reference
39
+
40
+ | Tool | When to use | Returns |
41
+ | --- | --- | --- |
42
+ | `inspect_color` | Inspects a colour string and converts between hex, rgb, hsl, and oklch, checking sRGB gamut and relative luminance | `{ hex, rgb, hsl, oklch, css, inSrgbGamut, relativeLuminance }` |
43
+ | `check_color_contrast` | Evaluates WCAG 2 contrast ratio between foreground and background, returning AA/AAA pass status and an OKLCH lightness suggestion if failing | `{ ratio, level, passesAA, passesAAA, suggestion? }` |
44
+ | `check_color_palette` | Audits an array of colours for pairwise distinctness across normal vision and CVD (protanopia, deuteranopia, tritanopia), and surface contrast | `{ ok, closest, contrast, issues, skipped }` |
45
+ | `suggest_color_harmony` | Generates harmonic colour combinations on RGB or RYB colour wheels | `{ colors: [{ hex, angle }] }` |
46
+ | `blend_colors` | Interpolates between two colours in OKLab, OKLCH, sRGB, or sRGB-linear at factor `t` or as an even `steps` ramp | `{ color }` or `{ colors }` |
47
+ | `derive_dual_color` | Automatically derives the opposing scheme colour (light or dark) from a base colour, optionally preserving contrast against background surfaces | `{ light, dark, css, contrast: { light, dark } }` |
48
+ | `check_dual_color_contrast` | Evaluates WCAG contrast compliance for a foreground and background dual colour across both light and dark modes, with suggestions | `{ light: { ratio, level }, dark: { ratio, level }, issues, suggestion? }` |
49
+ | `export_dual_colors_css` | Generates CSS custom properties for dual colours using light-dark(), media queries, or darkSelector class | `{ css }` |
50
+ | `get_gradient` | Returns the current gradient model, CSS string, SVG def, and dual status | `{ gradient, css, svgDef, isDual, selectedStopId, readOnly }` |
51
+ | `check_gradient` | Audits gradient for crowded stops, banding risk, out-of-gamut colours, and text contrast | `{ pass, issueCount, issues }` |
52
+ | `list_gradient_presets` | Returns the collection of built-in gradient presets | `{ presets: [{ id, name, category, css, gradient }] }` |
53
+ | `set_gradient` | Replaces the entire gradient with a new gradient object or CSS string | `{ gradient, css }` |
54
+ | `set_gradient_geometry` | Changes any of type, angle, center, shape, interpolation, repeating in one undo step; pass only the fields to change. Angle applies to linear and conic, center to radial and conic, shape to radial only; a field that doesn't fit the (new) type fails the whole call and changes nothing | `{ gradient, css }` |
55
+ | `add_gradient_stop` | Adds a new color stop to the gradient ramp | `{ stop, gradient, css }` |
56
+ | `update_gradient_stop` | Updates an existing stop's color, offset, or midpoint | `{ stop, gradient, css }` |
57
+ | `remove_gradient_stop` | Removes a color stop by ID | `{ gradient, css }` |
58
+ | `reverse_gradient` | Reverses the order and offsets of all stops | `{ gradient, css }` |
59
+ | `distribute_gradient_stops` | Evenly distributes all color stops between 0 and 1 | `{ gradient, css }` |
60
+ | `apply_gradient_preset` | Applies a built-in gradient preset by ID | `{ preset, gradient, css }` |
61
+
62
+ ## Pitfalls
63
+
64
+ - **`light-dark()` requires `color-scheme`.** CSS `light-dark()` only resolves the dark colour when `color-scheme: light dark;` is set on the element or an ancestor (such as `:root`). Without `color-scheme`, browsers always render the light colour.
65
+ - **JavaScript resolution required for non-CSS targets.** Canvas 2D, WebGL, SVG presentation attributes, and raster image exporters cannot read `light-dark()` strings; resolve them in JavaScript with `resolveColor(value, scheme)`.
66
+ - **Gamut clipping.** Colours specified in wide-gamut spaces (e.g. high-chroma OKLCH) will be mapped into sRGB for hex representations. Check `inSrgbGamut` if exact fidelity is required.
67
+ - **Large text thresholds.** WCAG allows 3:1 for large text (18pt / 24px or 14pt / 18.5px bold); pass `large: true` to avoid overly aggressive contrast suggestions.
68
+ - **Geometry fields depend on the type.** To make a radial circle, send `type: "radial"` and `shape: "circle"` in the same `set_gradient_geometry` call; sending `shape` to a linear gradient is an error.
69
+ - **Ramp steps bounds.** `blend_colors` requires `steps` to be between 2 and 32 when generating a ramp.
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: pixerate-effect-authoring
3
+ description: How to author and edit procedural effects, shaders, and filters through the effect authoring agent tools - inspecting effect schemas and current control values, reading and compiling shader source code, adjusting parameters with all-or-nothing validation, applying and saving presets, keyframing animation tracks with easing, configuring timeline playback duration and looping, scrubbing the playhead, and capturing visual previews. Use when asked to author, modify, or debug shaders or procedural effects, animate effect parameters over time, or when effect_authoring tools are available.
4
+ ---
5
+
6
+ # Pixerate effect authoring
7
+
8
+ An effect authoring session hosts an active effect definition (shader or procedural filter) and
9
+ exposes its controls, animated tracks, compile status, playback timing, and visual preview.
10
+ Control values can be static or animated via keyframes along a timeline. Each edit creates a
11
+ single undoable history step.
12
+
13
+ When an effect session is opened, tools allow inspecting the control schema, updating control
14
+ values, modifying shader code (for code-backed effects), saving and loading presets, managing
15
+ keyframe animation tracks with interpolation easing, seeking the playhead, and capturing rendered
16
+ preview frames.
17
+
18
+ For general error reporting and undo conventions, see `pixerate-agent-tools`.
19
+
20
+ ## Working method
21
+
22
+ 1. **Inspect first.** Run `effect_authoring_describe` to inspect the effect name, kind, source
23
+ language (`glsl`, `svg`, or null when the effect has no source to edit), control parameter schemas, current
24
+ values, existing tracks, and compile issues.
25
+ 2. **Read or update source code.** If `sourceLanguage` is non-null, use `effect_authoring_get_source`
26
+ to read the shader or script code. Use `effect_authoring_set_source` to recompile with new code
27
+ and immediately inspect any reported syntax or compilation issues with line numbers.
28
+ 3. **Adjust parameters.** Use `effect_authoring_set_values` to set one or more controls at once.
29
+ This runs all-or-nothing validation: any invalid control name or out-of-range value cancels the
30
+ change and returns a helpful error.
31
+ 4. **Animate with keyframes.** For controls that change over time, set keyframes using
32
+ `effect_authoring_set_keyframe` specifying `control`, `time` (ms), optional `value`, and `easing` (a preset name such as `ease-in-out`, or a `cubic-bezier`, `spring` or `elastic` curve object).
33
+ Use `effect_authoring_seek` to move the playhead across the timeline and check resolved values.
34
+ Use `effect_authoring_remove_keyframe` to delete specific points, or `effect_authoring_clear_track`
35
+ to revert a parameter to static behavior (both refuse a control that has no keyframes, and say which controls are animated).
36
+ 5. **Tune timing.** Use `effect_authoring_set_timing` to configure total `duration` in ms and
37
+ whether playback loops.
38
+ 6. **Save presets.** When an interesting look is achieved, save it with `effect_authoring_save_preset`
39
+ or restore known presets with `effect_authoring_apply_preset`.
40
+ 7. **Verify visually.** When `effect_authoring_view` is available, capture rendered preview frames
41
+ at specific times to visually confirm effect appearance.
42
+
43
+ ## Best practices
44
+
45
+ - **Batch parameter changes.** Set all related control values in a single `effect_authoring_set_values`
46
+ call so they apply cleanly in a single undo step.
47
+ - **Check compile issues.** When editing source code via `effect_authoring_set_source`, always verify
48
+ the returned `issues` array. Fix errors before attempting to preview or set controls.
49
+ - **Keyframe animation tracks.** Controls with active keyframes calculate their values dynamically
50
+ based on the playhead time. Setting a value on an animated control at the current playhead updates
51
+ or adds a keyframe at that time.
52
+ - **Safe exploration.** Use `effect_authoring_save_preset` before major shader or parameter
53
+ refactoring, and use `effect_authoring_undo` / `effect_authoring_redo` to step through changes.
54
+
55
+ ## Tools
56
+
57
+ | Tool | Description and usage |
58
+ | --- | --- |
59
+ | `effect_authoring_describe` | Reads the currently open effect session: name, kind, source language, controls schema and current values, presets, animated tracks with keyframe counts, duration, loop, and compile issues. |
60
+ | `effect_authoring_get_source` | Retrieves shader or script source code and language for code-backed effects. Refused if `sourceLanguage` is null. |
61
+ | `effect_authoring_set_source` | Recompiles the effect with new shader or script source code. Returns compiler issues with line numbers and messages. Available only when supported by the session. |
62
+ | `effect_authoring_set_values` | Sets one or more control values at the current playhead time as a single undo step. Rejects all changes if any control name or value is invalid. |
63
+ | `effect_authoring_reset_values` | Resets specified controls (or all controls if omitted) back to their schema defaults in a single undo step. |
64
+ | `effect_authoring_apply_preset` | Applies a built-in or user-saved preset by name, updating current control values in one undo step. |
65
+ | `effect_authoring_save_preset` | Saves the current control values as a user preset under the given name. Replaces an existing preset with the same name. |
66
+ | `effect_authoring_set_keyframe` | Adds or replaces a keyframe on a control track at a specific time in milliseconds, with optional value and easing curve. |
67
+ | `effect_authoring_remove_keyframe` | Deletes a keyframe at the exact millisecond timestamp from a control animation track. |
68
+ | `effect_authoring_clear_track` | Removes all keyframes from an animated control track. The control's value at the playhead becomes its static value. |
69
+ | `effect_authoring_set_timing` | Configures the effect's timeline duration in milliseconds and whether playback loops. |
70
+ | `effect_authoring_seek` | Moves the preview playhead to a specific timeline position in milliseconds (clamped to 0..duration) and returns values at that time. |
71
+ | `effect_authoring_undo` | Undoes the most recent edit in the authoring session. |
72
+ | `effect_authoring_redo` | Redoes the most recently undone edit in the authoring session. |
73
+ | `effect_authoring_view` | Captures a preview image of the effect at the current playhead or a specified timestamp. Available when preview capture is supported. |
74
+
75
+ ## Pitfalls
76
+
77
+ - Calling authoring tools when no authoring session is open returns an error explaining that a session must be opened first.
78
+ - Animated controls calculate their values dynamically from keyframes; clearing a track reverts the parameter to static behavior.
79
+ - Compiling invalid shader code produces issues in `effect_authoring_set_source`; inspect the line numbers and messages to correct syntax.
80
+ - Control values must match their schema types and bounds; colours must be `#rrggbb` (or `#rrggbbaa`), and numbers must fall within `[min, max]`.
@@ -1,65 +0,0 @@
1
- import {
2
- hexToRgba,
3
- normalizeTokenColor,
4
- rgbaToHex
5
- } from "./chunk-2WPNAGHI.js";
6
-
7
- // src/animation/color.ts
8
- var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
9
- var toGamma = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * Math.sign(c) * Math.abs(c) ** (1 / 2.4) - 0.055;
10
- function rgbToOklab(r, g, b, alpha = 1) {
11
- const lr = toLinear(r);
12
- const lg = toLinear(g);
13
- const lb = toLinear(b);
14
- const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
15
- const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
16
- const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
17
- return {
18
- l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
19
- a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
20
- b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
21
- alpha
22
- };
23
- }
24
- function oklabToRgb(color) {
25
- const l_ = color.l + 0.3963377774 * color.a + 0.2158037573 * color.b;
26
- const m_ = color.l - 0.1055613458 * color.a - 0.0638541728 * color.b;
27
- const s_ = color.l - 0.0894841775 * color.a - 1.291485548 * color.b;
28
- const l = l_ ** 3;
29
- const m = m_ ** 3;
30
- const s = s_ ** 3;
31
- const clamp01 = (v) => Math.min(1, Math.max(0, v));
32
- return {
33
- r: clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s)),
34
- g: clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s)),
35
- b: clamp01(toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s)),
36
- a: clamp01(color.alpha)
37
- };
38
- }
39
- function parseOklab(input) {
40
- const hex = normalizeTokenColor(input);
41
- if (hex === null) return null;
42
- const c = hexToRgba(hex);
43
- return rgbToOklab(c.r, c.g, c.b, c.a);
44
- }
45
- function formatOklab(color) {
46
- const { r, g, b, a } = oklabToRgb(color);
47
- return rgbaToHex(r, g, b, a);
48
- }
49
- function mixColorsOklab(from, to, t) {
50
- const a = parseOklab(from);
51
- const b = parseOklab(to);
52
- if (!a || !b) return null;
53
- const alpha = a.alpha + (b.alpha - a.alpha) * t;
54
- const premul = (k) => a[k] * a.alpha + (b[k] * b.alpha - a[k] * a.alpha) * t;
55
- if (alpha <= 1e-9) return formatOklab({ l: a.l + (b.l - a.l) * t, a: 0, b: 0, alpha: 0 });
56
- return formatOklab({ l: premul("l") / alpha, a: premul("a") / alpha, b: premul("b") / alpha, alpha });
57
- }
58
-
59
- export {
60
- rgbToOklab,
61
- oklabToRgb,
62
- parseOklab,
63
- formatOklab,
64
- mixColorsOklab
65
- };
@@ -1,65 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
-
4
-
5
- var _chunkA6QWKBJPcjs = require('./chunk-A6QWKBJP.cjs');
6
-
7
- // src/animation/color.ts
8
- var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
9
- var toGamma = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * Math.sign(c) * Math.abs(c) ** (1 / 2.4) - 0.055;
10
- function rgbToOklab(r, g, b, alpha = 1) {
11
- const lr = toLinear(r);
12
- const lg = toLinear(g);
13
- const lb = toLinear(b);
14
- const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
15
- const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
16
- const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
17
- return {
18
- l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
19
- a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
20
- b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
21
- alpha
22
- };
23
- }
24
- function oklabToRgb(color) {
25
- const l_ = color.l + 0.3963377774 * color.a + 0.2158037573 * color.b;
26
- const m_ = color.l - 0.1055613458 * color.a - 0.0638541728 * color.b;
27
- const s_ = color.l - 0.0894841775 * color.a - 1.291485548 * color.b;
28
- const l = l_ ** 3;
29
- const m = m_ ** 3;
30
- const s = s_ ** 3;
31
- const clamp01 = (v) => Math.min(1, Math.max(0, v));
32
- return {
33
- r: clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s)),
34
- g: clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s)),
35
- b: clamp01(toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s)),
36
- a: clamp01(color.alpha)
37
- };
38
- }
39
- function parseOklab(input) {
40
- const hex = _chunkA6QWKBJPcjs.normalizeTokenColor.call(void 0, input);
41
- if (hex === null) return null;
42
- const c = _chunkA6QWKBJPcjs.hexToRgba.call(void 0, hex);
43
- return rgbToOklab(c.r, c.g, c.b, c.a);
44
- }
45
- function formatOklab(color) {
46
- const { r, g, b, a } = oklabToRgb(color);
47
- return _chunkA6QWKBJPcjs.rgbaToHex.call(void 0, r, g, b, a);
48
- }
49
- function mixColorsOklab(from, to, t) {
50
- const a = parseOklab(from);
51
- const b = parseOklab(to);
52
- if (!a || !b) return null;
53
- const alpha = a.alpha + (b.alpha - a.alpha) * t;
54
- const premul = (k) => a[k] * a.alpha + (b[k] * b.alpha - a[k] * a.alpha) * t;
55
- if (alpha <= 1e-9) return formatOklab({ l: a.l + (b.l - a.l) * t, a: 0, b: 0, alpha: 0 });
56
- return formatOklab({ l: premul("l") / alpha, a: premul("a") / alpha, b: premul("b") / alpha, alpha });
57
- }
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
- exports.rgbToOklab = rgbToOklab; exports.oklabToRgb = oklabToRgb; exports.parseOklab = parseOklab; exports.formatOklab = formatOklab; exports.mixColorsOklab = mixColorsOklab;