@pixerate/flair 0.0.0-stage → 0.1.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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +254 -2
- package/dist/catalog/index.d.ts +74 -0
- package/dist/catalog/index.js +47 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/chunk-36DTNSHU.js +160 -0
- package/dist/chunk-36DTNSHU.js.map +1 -0
- package/dist/chunk-3FAUZOGL.js +331 -0
- package/dist/chunk-3FAUZOGL.js.map +1 -0
- package/dist/chunk-CFCLT2XL.js +1 -0
- package/dist/chunk-CFCLT2XL.js.map +1 -0
- package/dist/chunk-EHDJ3CPJ.js +327 -0
- package/dist/chunk-EHDJ3CPJ.js.map +1 -0
- package/dist/chunk-G5FNZDTA.js +536 -0
- package/dist/chunk-G5FNZDTA.js.map +1 -0
- package/dist/chunk-HKXOHRCD.js +763 -0
- package/dist/chunk-HKXOHRCD.js.map +1 -0
- package/dist/chunk-J55UBNAT.js +164 -0
- package/dist/chunk-J55UBNAT.js.map +1 -0
- package/dist/chunk-JWZCPMFG.js +2074 -0
- package/dist/chunk-JWZCPMFG.js.map +1 -0
- package/dist/chunk-MWVTQFV5.js +1894 -0
- package/dist/chunk-MWVTQFV5.js.map +1 -0
- package/dist/chunk-UQQNZSYL.js +594 -0
- package/dist/chunk-UQQNZSYL.js.map +1 -0
- package/dist/chunk-WMZQCUFJ.js +73 -0
- package/dist/chunk-WMZQCUFJ.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +331 -0
- package/dist/cli.js.map +1 -0
- package/dist/clock-BhdXWH-n.d.ts +47 -0
- package/dist/controls-DdXMbovi.d.ts +97 -0
- package/dist/editor/index.d.ts +413 -0
- package/dist/editor/index.js +1009 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/export-FEBPEEO7.js +22 -0
- package/dist/export-FEBPEEO7.js.map +1 -0
- package/dist/index.d.ts +1431 -0
- package/dist/index.js +1263 -0
- package/dist/index.js.map +1 -0
- package/dist/motion-D0TVv2CF.d.ts +148 -0
- package/dist/node.d.ts +24 -0
- package/dist/node.js +10 -0
- package/dist/node.js.map +1 -0
- package/dist/recorder-WJTWMEQN.js +10 -0
- package/dist/recorder-WJTWMEQN.js.map +1 -0
- package/dist/renderer-Oyynz-fs.d.ts +293 -0
- package/dist/types-CkKkavvB.d.ts +71 -0
- package/dist/vector/index.d.ts +83 -0
- package/dist/vector/index.js +39 -0
- package/dist/vector/index.js.map +1 -0
- package/package.json +96 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time source for generative animations and playback.
|
|
3
|
+
* By default that is real time (animation frames and timers).
|
|
4
|
+
* A ManualClock instead moves only when told to, enabling frame-exact
|
|
5
|
+
* rendering, video recording, scrubbing, or fast simulation without waiting.
|
|
6
|
+
*/
|
|
7
|
+
interface Clock {
|
|
8
|
+
/** Current time in milliseconds. */
|
|
9
|
+
now(): number;
|
|
10
|
+
/** Resolves on the next frame. */
|
|
11
|
+
frame(): Promise<void>;
|
|
12
|
+
/** Resolves after `ms` milliseconds of this clock's time. */
|
|
13
|
+
sleep(ms: number): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Whether the clock follows wall time. Live clocks stop when the tab is in
|
|
16
|
+
* the background (browsers pause animation frames there).
|
|
17
|
+
*/
|
|
18
|
+
readonly live: boolean;
|
|
19
|
+
}
|
|
20
|
+
declare const pageHidden: () => boolean;
|
|
21
|
+
declare const realClock: Clock;
|
|
22
|
+
/**
|
|
23
|
+
* A clock that only moves when {@link advance} or {@link tick} is called.
|
|
24
|
+
* Each call fires the sleeps that fall due, in order, letting awaiting code
|
|
25
|
+
* run before the next sleep fires, then resolves pending frames.
|
|
26
|
+
*/
|
|
27
|
+
declare class ManualClock implements Clock {
|
|
28
|
+
readonly live = false;
|
|
29
|
+
private time;
|
|
30
|
+
private frames;
|
|
31
|
+
private sleepers;
|
|
32
|
+
private seq;
|
|
33
|
+
constructor(start?: number);
|
|
34
|
+
now(): number;
|
|
35
|
+
frame(): Promise<void>;
|
|
36
|
+
sleep(ms: number): Promise<void>;
|
|
37
|
+
get pending(): boolean;
|
|
38
|
+
advance(ms: number): Promise<void>;
|
|
39
|
+
tick(fps?: number): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A repeatable pseudo-random number in [0, 1) for a key and index.
|
|
43
|
+
* Useful for deterministic, reproducible animations.
|
|
44
|
+
*/
|
|
45
|
+
declare function jitter(key: string, n: number): number;
|
|
46
|
+
|
|
47
|
+
export { type Clock as C, ManualClock as M, jitter as j, pageHidden as p, realClock as r };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controls declared in a shader's source. A uniform becomes a control when
|
|
3
|
+
* its declaration carries an `@control` comment on the same line:
|
|
4
|
+
*
|
|
5
|
+
* uniform float uSpeed; // @control min=0 max=4 default=1 label="Speed"
|
|
6
|
+
* uniform int uSteps; // @control min=1 max=64 default=16
|
|
7
|
+
* uniform bool uGrain; // @control default=true label="Film grain"
|
|
8
|
+
* uniform vec2 uCenter; // @control min=-1 max=1 default=0,0
|
|
9
|
+
* uniform vec3 uTint; // @control color default=#77C16A label="Tint"
|
|
10
|
+
* uniform sampler2D uPhoto; // @control filter=linear wrap=clamp label="Photo"
|
|
11
|
+
*
|
|
12
|
+
* The source is the single source of truth for which controls exist and
|
|
13
|
+
* their defaults; values someone picks are stored next to it.
|
|
14
|
+
*/
|
|
15
|
+
/** The uniform types a control can have. */
|
|
16
|
+
type ControlType = "float" | "int" | "bool" | "vec2" | "vec3" | "vec4" | "sampler2D";
|
|
17
|
+
/**
|
|
18
|
+
* A control's value: a number (`float`, `int`), a boolean (`bool`), the
|
|
19
|
+
* components of a vector, or an image URL (`sampler2D`; "" for none).
|
|
20
|
+
*/
|
|
21
|
+
type ControlValue = number | boolean | number[] | string;
|
|
22
|
+
/** How an image is sampled: Shadertoy's channel settings. */
|
|
23
|
+
interface TextureSettings {
|
|
24
|
+
/** `mipmap` (the default), `linear` or `nearest` (pixelated). */
|
|
25
|
+
filter: "mipmap" | "linear" | "nearest";
|
|
26
|
+
/** Outside 0–1: `repeat` (the default), `clamp` to the edge, or `mirror`. */
|
|
27
|
+
wrap: "repeat" | "clamp" | "mirror";
|
|
28
|
+
}
|
|
29
|
+
/** A control parsed from an annotated uniform. */
|
|
30
|
+
interface ControlDef {
|
|
31
|
+
/** The uniform's name. */
|
|
32
|
+
name: string;
|
|
33
|
+
type: ControlType;
|
|
34
|
+
/** `label="…"`, or the name made readable ("uFlowSpeed" → "Flow speed"). */
|
|
35
|
+
label: string;
|
|
36
|
+
/** A `vec3` or `vec4` shown as a colour picker. */
|
|
37
|
+
color: boolean;
|
|
38
|
+
min: number;
|
|
39
|
+
/** Always greater than `min`. */
|
|
40
|
+
max: number;
|
|
41
|
+
step: number;
|
|
42
|
+
default: ControlValue;
|
|
43
|
+
/** 1-based line of the declaration. */
|
|
44
|
+
line: number;
|
|
45
|
+
/** Sampling settings, for `sampler2D` controls only. */
|
|
46
|
+
texture?: TextureSettings;
|
|
47
|
+
}
|
|
48
|
+
/** The number of components a control type has: 1 for scalars, `bool` and `sampler2D`, else the vector size. */
|
|
49
|
+
declare function componentCount(type: ControlType): number;
|
|
50
|
+
/** "uFlowSpeed" → "Flow speed". */
|
|
51
|
+
declare function humanise(name: string): string;
|
|
52
|
+
/** "#77C16A" (or "#7c6") → [0.467, 0.757, 0.416]; null when it is not a hex colour. */
|
|
53
|
+
declare function hexToRgb(hex: string): number[] | null;
|
|
54
|
+
/** [0.467, 0.757, 0.416] → "#77c16a". Components are clamped to 0–1; a fourth (alpha) is ignored. */
|
|
55
|
+
declare function rgbToHex(rgb: number[]): string;
|
|
56
|
+
/**
|
|
57
|
+
* The controls a source declares, in source order. A uniform declared twice
|
|
58
|
+
* counts once (the first wins). Unknown attributes are ignored, and missing
|
|
59
|
+
* or malformed ones fall back to defaults: `min=0`, `max=1` (10 for `int`),
|
|
60
|
+
* a step of 1/200 of the range (1 for `int`).
|
|
61
|
+
*/
|
|
62
|
+
declare function parseControls(source: string): ControlDef[];
|
|
63
|
+
/** The value a control has: the stored one when it still fits the declaration, else the default. */
|
|
64
|
+
declare function controlValue(control: ControlDef, values: Record<string, ControlValue> | undefined): ControlValue;
|
|
65
|
+
/** What {@link checkControlValue} decides: the value to store, or a sentence saying what the control takes. */
|
|
66
|
+
type ControlCheck = {
|
|
67
|
+
ok: true;
|
|
68
|
+
value: ControlValue;
|
|
69
|
+
} | {
|
|
70
|
+
ok: false;
|
|
71
|
+
message: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Checks a value from outside (an agent's tool call, a URL, a form) against a
|
|
75
|
+
* control. Colours also accept "#RRGGBB"; `int` values are rounded. Images
|
|
76
|
+
* take a URL: `https:`, `http:`, `data:image/…`, `blob:` or a relative path
|
|
77
|
+
* ("" for none).
|
|
78
|
+
*/
|
|
79
|
+
declare function checkControlValue(control: ControlDef, raw: unknown): ControlCheck;
|
|
80
|
+
/**
|
|
81
|
+
* {@link checkControlValue} for controls whose values are never strings:
|
|
82
|
+
* returns the value to store, or the message. An image control's value is a
|
|
83
|
+
* string too, so use `checkControlValue` where images can appear.
|
|
84
|
+
*/
|
|
85
|
+
declare function coerceControlValue(control: ControlDef, raw: unknown): ControlValue | string;
|
|
86
|
+
/** Whether a string is a URL an image control can load: `http(s):`, `data:image/`, `blob:` or a relative path. */
|
|
87
|
+
declare function isImageUrl(url: string): boolean;
|
|
88
|
+
/** The image URLs the controls show with these values, without duplicates or empty ones. */
|
|
89
|
+
declare function imageUrls(controls: ControlDef[], values: Record<string, ControlValue> | undefined): string[];
|
|
90
|
+
/**
|
|
91
|
+
* A value as compact, JSON-friendly data: colours as hex, numbers to three
|
|
92
|
+
* decimals. A long `data:` URL is shortened to its type and size, which
|
|
93
|
+
* keeps it out of an agent's context but cannot be stored back.
|
|
94
|
+
*/
|
|
95
|
+
declare function describeValue(control: ControlDef, value: ControlValue): unknown;
|
|
96
|
+
|
|
97
|
+
export { type ControlValue as C, type TextureSettings as T, type ControlDef as a, type ControlType as b, type ControlCheck as c, checkControlValue as d, coerceControlValue as e, componentCount as f, controlValue as g, describeValue as h, hexToRgb as i, humanise as j, imageUrls as k, isImageUrl as l, parseControls as p, rgbToHex as r };
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { V as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-CkKkavvB.js';
|
|
2
|
+
import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-DdXMbovi.js';
|
|
3
|
+
import { S as SvgMotion } from '../motion-D0TVv2CF.js';
|
|
4
|
+
import { CommandRegistry, CommandSpec } from '@pixerate/editor/commands';
|
|
5
|
+
import { HistoryManager, HistoryState } from '@pixerate/editor/history';
|
|
6
|
+
import { C as CompileError, a as CompileStatus } from '../renderer-Oyynz-fs.js';
|
|
7
|
+
import { C as Clock } from '../clock-BhdXWH-n.js';
|
|
8
|
+
import { AgentToolProvider, McpToolResult, McpToolDefinition } from '@pixerate/editor/generation';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Keyframed control values. A track holds keyframes `{ time (ms), value,
|
|
12
|
+
* easing }` for one control; the easing governs the segment leaving its
|
|
13
|
+
* keyframe. The shapes and easing names match `@pixerate/editor`'s keyframe
|
|
14
|
+
* animation (`AnimationTrack`, `AnimationEasing`), so timelines move between
|
|
15
|
+
* the two unchanged.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Named easings (CSS keywords plus back and spring curves). */
|
|
19
|
+
type EasingPreset = "linear" | "hold" | "ease" | "ease-in" | "ease-out" | "ease-in-out" | "ease-in-back" | "ease-out-back" | "spring";
|
|
20
|
+
interface CubicBezierEasing {
|
|
21
|
+
type: "cubic-bezier";
|
|
22
|
+
x1: number;
|
|
23
|
+
y1: number;
|
|
24
|
+
x2: number;
|
|
25
|
+
y2: number;
|
|
26
|
+
}
|
|
27
|
+
interface SpringEasing {
|
|
28
|
+
type: "spring";
|
|
29
|
+
/** Default 170. */
|
|
30
|
+
stiffness?: number;
|
|
31
|
+
/** Default 26. */
|
|
32
|
+
damping?: number;
|
|
33
|
+
/** Default 1. */
|
|
34
|
+
mass?: number;
|
|
35
|
+
}
|
|
36
|
+
type Easing = EasingPreset | CubicBezierEasing | SpringEasing;
|
|
37
|
+
/** Every easing preset, in picker order. */
|
|
38
|
+
declare const EASING_PRESETS: readonly EasingPreset[];
|
|
39
|
+
interface Keyframe {
|
|
40
|
+
/** Ms from the start of the timeline. */
|
|
41
|
+
time: number;
|
|
42
|
+
value: ControlValue;
|
|
43
|
+
/** Easing of the segment from this keyframe to the next (default `linear`). */
|
|
44
|
+
easing?: Easing;
|
|
45
|
+
}
|
|
46
|
+
interface Track {
|
|
47
|
+
/** Sorted by time, at most one per time. */
|
|
48
|
+
keyframes: Keyframe[];
|
|
49
|
+
/** Disabled tracks keep their keyframes but do not animate (default `true`). */
|
|
50
|
+
enabled?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Whether `value` is an easing this module understands. */
|
|
53
|
+
declare function isEasing(value: unknown): value is Easing;
|
|
54
|
+
/** CSS `cubic-bezier(x1, y1, x2, y2)` solved for y at progress x. */
|
|
55
|
+
declare function cubicBezierAt(x1: number, y1: number, x2: number, y2: number, x: number): number;
|
|
56
|
+
/** Eased progress at `u` (0–1) through a segment `durationMs` long. */
|
|
57
|
+
declare function evaluateEasing(easing: Easing | undefined, u: number, durationMs?: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* A control value `t` of the way from `a` to `b`: numbers and vectors blend
|
|
60
|
+
* (overshooting with back and spring easings), colours blend in Oklab, `int`s
|
|
61
|
+
* round, and booleans and images switch halfway.
|
|
62
|
+
*/
|
|
63
|
+
declare function interpolateControlValue(control: ControlDef | undefined, a: ControlValue, b: ControlValue, t: number): ControlValue;
|
|
64
|
+
/** A track's value at `time` (ms), or undefined when it has no keyframes or is disabled. */
|
|
65
|
+
declare function evaluateTrack(track: Track | undefined, time: number, control?: ControlDef): ControlValue | undefined;
|
|
66
|
+
/** Keyframes sorted by time, one per time (the later of two at the same time wins). */
|
|
67
|
+
declare function normalizeKeyframes(keyframes: readonly Keyframe[]): Keyframe[];
|
|
68
|
+
/** The keyframe times across tracks, sorted and without duplicates. */
|
|
69
|
+
declare function keyframeTimes(tracks: Record<string, Track>): number[];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The document an effect editor edits: an effect (a shader's source, or a
|
|
73
|
+
* vector picture with its controls), the values picked for its controls,
|
|
74
|
+
* keyframed tracks, presets and a timeline. Plain JSON, so it can be saved,
|
|
75
|
+
* diffed, and written by an agent.
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/** What is being edited: a fragment shader, or an animated SVG with declared controls. */
|
|
79
|
+
type EffectSource = {
|
|
80
|
+
kind: "shader";
|
|
81
|
+
source: string;
|
|
82
|
+
} | {
|
|
83
|
+
kind: "vector";
|
|
84
|
+
motion: SvgMotion;
|
|
85
|
+
controls: VectorControl[];
|
|
86
|
+
hold?: number;
|
|
87
|
+
};
|
|
88
|
+
interface EffectDocument {
|
|
89
|
+
/** Format version (1). */
|
|
90
|
+
version: 1;
|
|
91
|
+
name: string;
|
|
92
|
+
/** The catalog effect it started from, if any. */
|
|
93
|
+
basedOn?: string;
|
|
94
|
+
effect: EffectSource;
|
|
95
|
+
/** Picked control values; controls without one use their default. */
|
|
96
|
+
values: Record<string, ControlValue>;
|
|
97
|
+
/** Keyframed controls, by control name. A track overrides the control's value. */
|
|
98
|
+
tracks: Record<string, Track>;
|
|
99
|
+
/** Timeline length in ms. */
|
|
100
|
+
duration: number;
|
|
101
|
+
loop: boolean;
|
|
102
|
+
presets: EffectPreset[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A new document: blank (a small starter shader), from a catalog effect (by
|
|
106
|
+
* id or definition), or from a shader's source.
|
|
107
|
+
*/
|
|
108
|
+
declare function createEffectDocument(from?: string | EffectDefinition | {
|
|
109
|
+
source: string;
|
|
110
|
+
name?: string;
|
|
111
|
+
}): EffectDocument;
|
|
112
|
+
/** The document's controls. */
|
|
113
|
+
declare function documentControls(doc: EffectDocument): ControlDef[];
|
|
114
|
+
/** Every control's value at `time` (ms): its track if it has one, else the picked value, else its default. */
|
|
115
|
+
declare function valuesAt(doc: EffectDocument, time: number, controls?: ControlDef[]): Record<string, ControlValue>;
|
|
116
|
+
/** A vector document's picture with the values at `time` filled in; undefined for shaders. */
|
|
117
|
+
declare function motionAt(doc: EffectDocument, time: number): SvgMotion | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Problems with a document, as sentences: unknown controls in values, tracks
|
|
120
|
+
* or presets, values a control cannot take, bad keyframes, and (for vector
|
|
121
|
+
* effects) problems with the picture. Shader compile errors come from the
|
|
122
|
+
* GPU, not from here.
|
|
123
|
+
*/
|
|
124
|
+
declare function documentIssues(doc: EffectDocument): string[];
|
|
125
|
+
/** Reads a document from JSON (or a parsed object), checking its shape. */
|
|
126
|
+
declare function parseEffectDocument(input: string | unknown): {
|
|
127
|
+
ok: true;
|
|
128
|
+
document: EffectDocument;
|
|
129
|
+
} | {
|
|
130
|
+
ok: false;
|
|
131
|
+
errors: string[];
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* A UI-agnostic effect editor: the document, its undo history, a playhead,
|
|
136
|
+
* and commands that menus, shortcuts, a palette and agents all run by id.
|
|
137
|
+
* Bring your own UI (any framework, or none) and your own renderer binding
|
|
138
|
+
* (see `bindShaderRenderer` and `bindSvgView`).
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
/** What an edit did: `ok`, or why it was refused (in a sentence an agent can act on). */
|
|
142
|
+
type EditResult = {
|
|
143
|
+
ok: true;
|
|
144
|
+
} | {
|
|
145
|
+
ok: false;
|
|
146
|
+
message: string;
|
|
147
|
+
};
|
|
148
|
+
/** The result of compiling the shader, as reported by a renderer (see `reportCompile`). */
|
|
149
|
+
interface CompileReport {
|
|
150
|
+
ok: boolean;
|
|
151
|
+
errors: CompileError[];
|
|
152
|
+
}
|
|
153
|
+
interface EffectEditorState {
|
|
154
|
+
document: EffectDocument;
|
|
155
|
+
controls: ControlDef[];
|
|
156
|
+
/** Every control's value at the playhead. */
|
|
157
|
+
values: Record<string, ControlValue>;
|
|
158
|
+
/** Problems with the document (see `documentIssues`). */
|
|
159
|
+
issues: string[];
|
|
160
|
+
/** The latest compile report, or null before a renderer reported one (and for vector effects). */
|
|
161
|
+
compile: CompileReport | null;
|
|
162
|
+
/** Playhead, ms. */
|
|
163
|
+
time: number;
|
|
164
|
+
playing: boolean;
|
|
165
|
+
/** Whether changing a value keyframes it at the playhead. */
|
|
166
|
+
recording: boolean;
|
|
167
|
+
history: HistoryState;
|
|
168
|
+
}
|
|
169
|
+
interface EffectEditorOptions {
|
|
170
|
+
/** The document to edit, or what to start one from (see `createEffectDocument`). */
|
|
171
|
+
document?: EffectDocument;
|
|
172
|
+
from?: string | EffectDefinition | {
|
|
173
|
+
source: string;
|
|
174
|
+
name?: string;
|
|
175
|
+
};
|
|
176
|
+
/** Undo history to record into (default: a new one, 100 steps deep). */
|
|
177
|
+
history?: HistoryManager;
|
|
178
|
+
/** Time source for playback (default: animation frames). */
|
|
179
|
+
clock?: Clock;
|
|
180
|
+
/** Ms within which value changes to one control merge into one undo step (default 400). */
|
|
181
|
+
mergeWindowMs?: number;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Edits one effect. Every change to the document is an undo step (value
|
|
185
|
+
* changes in quick succession, like a slider drag, merge into one), and
|
|
186
|
+
* subscribers hear about every change to the state.
|
|
187
|
+
*/
|
|
188
|
+
declare class EffectEditor {
|
|
189
|
+
readonly history: HistoryManager;
|
|
190
|
+
/** Every editing action, by id: for menus, shortcuts, a command palette and agents. */
|
|
191
|
+
readonly commands: CommandRegistry<EffectEditor>;
|
|
192
|
+
private doc;
|
|
193
|
+
private controlsCache;
|
|
194
|
+
private compileReport;
|
|
195
|
+
private time;
|
|
196
|
+
private playing;
|
|
197
|
+
private recording;
|
|
198
|
+
private readonly clock;
|
|
199
|
+
private readonly mergeWindowMs;
|
|
200
|
+
private readonly listeners;
|
|
201
|
+
private state;
|
|
202
|
+
private readonly unsubscribeHistory;
|
|
203
|
+
private disposed;
|
|
204
|
+
constructor(options?: EffectEditorOptions);
|
|
205
|
+
get document(): EffectDocument;
|
|
206
|
+
/** The current state; the same object until something changes (safe for `useSyncExternalStore`). */
|
|
207
|
+
getState(): EffectEditorState;
|
|
208
|
+
/** Calls `listener` with the new state after every change; returns an unsubscribe function. */
|
|
209
|
+
subscribe(listener: (state: EffectEditorState) => void): () => void;
|
|
210
|
+
/** The document's controls. */
|
|
211
|
+
get controls(): ControlDef[];
|
|
212
|
+
/** The document as JSON. */
|
|
213
|
+
toJSON(): EffectDocument;
|
|
214
|
+
/** Replaces the document (one undo step). */
|
|
215
|
+
replaceDocument(next: EffectDocument, label?: string): EditResult;
|
|
216
|
+
/** Starts over from a catalog effect, a shader source, or blank (one undo step). */
|
|
217
|
+
load(from?: string | EffectDefinition | {
|
|
218
|
+
source: string;
|
|
219
|
+
name?: string;
|
|
220
|
+
}, preset?: string): EditResult;
|
|
221
|
+
rename(name: string): EditResult;
|
|
222
|
+
/** Replaces a shader's source. Compile errors arrive later, from the renderer (see `reportCompile`). */
|
|
223
|
+
setSource(source: string): EditResult;
|
|
224
|
+
/** Replaces a vector effect's picture (and optionally its controls). */
|
|
225
|
+
setMotion(motion: SvgMotion, controls?: Extract<EffectDocument["effect"], {
|
|
226
|
+
kind: "vector";
|
|
227
|
+
}>["controls"]): EditResult;
|
|
228
|
+
/** Called by a renderer binding with the result of compiling the current source. */
|
|
229
|
+
reportCompile(report: CompileReport): void;
|
|
230
|
+
/**
|
|
231
|
+
* Sets a control's value. With a track on that control (or while
|
|
232
|
+
* recording) it sets a keyframe at the playhead instead. Quick successive
|
|
233
|
+
* changes to one control merge into one undo step.
|
|
234
|
+
*/
|
|
235
|
+
setValue(name: string, value: unknown): EditResult;
|
|
236
|
+
/** Sets several values in one undo step; refuses them all if any is wrong. */
|
|
237
|
+
setValues(values: Record<string, unknown>): EditResult;
|
|
238
|
+
/** Back to defaults: the named controls, or all of them (values only; tracks stay). */
|
|
239
|
+
resetValues(names?: readonly string[]): EditResult;
|
|
240
|
+
/** Random values in each control's range (colours anywhere), for exploring. */
|
|
241
|
+
randomize(names?: readonly string[], random?: () => number): EditResult;
|
|
242
|
+
applyPreset(name: string): EditResult;
|
|
243
|
+
/** Saves the current values (all, or the named ones) as a preset, replacing one of the same name. */
|
|
244
|
+
savePreset(name: string, names?: readonly string[]): EditResult;
|
|
245
|
+
deletePreset(name: string): EditResult;
|
|
246
|
+
/** Sets (or replaces) a keyframe; `value` defaults to the control's value at that time. */
|
|
247
|
+
setKeyframe(name: string, time: number, value?: unknown, easing?: Easing, mergeKey?: string): EditResult;
|
|
248
|
+
removeKeyframe(name: string, time: number): EditResult;
|
|
249
|
+
setKeyframeEasing(name: string, time: number, easing: Easing): EditResult;
|
|
250
|
+
/** Removes a control's track; it keeps the value it had at the playhead. */
|
|
251
|
+
clearTrack(name: string): EditResult;
|
|
252
|
+
setTiming(timing: {
|
|
253
|
+
duration?: number;
|
|
254
|
+
loop?: boolean;
|
|
255
|
+
}): EditResult;
|
|
256
|
+
play(): void;
|
|
257
|
+
pause(): void;
|
|
258
|
+
toggle(): void;
|
|
259
|
+
/** Moves the playhead (clamped to the timeline). */
|
|
260
|
+
seek(time: number): void;
|
|
261
|
+
stop(): void;
|
|
262
|
+
/** While recording, changing a value keyframes it at the playhead. */
|
|
263
|
+
setRecording(recording: boolean): void;
|
|
264
|
+
undo(): boolean;
|
|
265
|
+
redo(): boolean;
|
|
266
|
+
dispose(): void;
|
|
267
|
+
private run;
|
|
268
|
+
private analysis;
|
|
269
|
+
private control;
|
|
270
|
+
private unknownControl;
|
|
271
|
+
private commit;
|
|
272
|
+
private changed;
|
|
273
|
+
}
|
|
274
|
+
/** A new {@link EffectEditor}. */
|
|
275
|
+
declare function createEffectEditor(options?: EffectEditorOptions): EffectEditor;
|
|
276
|
+
|
|
277
|
+
/** A summary of the editor's state for agents: the document, controls, values at the playhead, issues and compile errors. */
|
|
278
|
+
declare function describeEditor(editor: EffectEditor): {
|
|
279
|
+
controls: {
|
|
280
|
+
default: ControlValue;
|
|
281
|
+
min?: number | undefined;
|
|
282
|
+
max?: number | undefined;
|
|
283
|
+
step?: number | undefined;
|
|
284
|
+
color?: boolean | undefined;
|
|
285
|
+
name: string;
|
|
286
|
+
type: ControlType;
|
|
287
|
+
label: string;
|
|
288
|
+
}[];
|
|
289
|
+
values: Record<string, ControlValue>;
|
|
290
|
+
tracks: Record<string, Track>;
|
|
291
|
+
presets: string[];
|
|
292
|
+
timeline: {
|
|
293
|
+
duration: number;
|
|
294
|
+
loop: boolean;
|
|
295
|
+
time: number;
|
|
296
|
+
playing: boolean;
|
|
297
|
+
recording: boolean;
|
|
298
|
+
};
|
|
299
|
+
issues: string[];
|
|
300
|
+
compile: CompileReport | null;
|
|
301
|
+
history: {
|
|
302
|
+
canUndo: boolean;
|
|
303
|
+
canRedo: boolean;
|
|
304
|
+
};
|
|
305
|
+
source: string;
|
|
306
|
+
name: string;
|
|
307
|
+
basedOn: string | undefined;
|
|
308
|
+
kind: "shader" | "vector";
|
|
309
|
+
} | {
|
|
310
|
+
controls: {
|
|
311
|
+
default: ControlValue;
|
|
312
|
+
min?: number | undefined;
|
|
313
|
+
max?: number | undefined;
|
|
314
|
+
step?: number | undefined;
|
|
315
|
+
color?: boolean | undefined;
|
|
316
|
+
name: string;
|
|
317
|
+
type: ControlType;
|
|
318
|
+
label: string;
|
|
319
|
+
}[];
|
|
320
|
+
values: Record<string, ControlValue>;
|
|
321
|
+
tracks: Record<string, Track>;
|
|
322
|
+
presets: string[];
|
|
323
|
+
timeline: {
|
|
324
|
+
duration: number;
|
|
325
|
+
loop: boolean;
|
|
326
|
+
time: number;
|
|
327
|
+
playing: boolean;
|
|
328
|
+
recording: boolean;
|
|
329
|
+
};
|
|
330
|
+
issues: string[];
|
|
331
|
+
compile: CompileReport | null;
|
|
332
|
+
history: {
|
|
333
|
+
canUndo: boolean;
|
|
334
|
+
canRedo: boolean;
|
|
335
|
+
};
|
|
336
|
+
motion: SvgMotion;
|
|
337
|
+
vectorControls: VectorControl[];
|
|
338
|
+
name: string;
|
|
339
|
+
basedOn: string | undefined;
|
|
340
|
+
kind: "shader" | "vector";
|
|
341
|
+
};
|
|
342
|
+
/** The effect editor's commands (the registry adds `history.undo` / `history.redo`). */
|
|
343
|
+
declare function effectCommands(): CommandSpec<EffectEditor>[];
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Agents edit effects through the editor's commands. Flair ships the tools
|
|
347
|
+
* and the instructions; the model, its credentials and the agent loop are
|
|
348
|
+
* the host's (bridge the provider into an MCP server or any tool-calling LLM).
|
|
349
|
+
*/
|
|
350
|
+
|
|
351
|
+
interface EffectToolProviderOptions {
|
|
352
|
+
/** Provider id (default `flair-effect`). */
|
|
353
|
+
id?: string;
|
|
354
|
+
/** Prefix every tool name with `<namespace>__`. */
|
|
355
|
+
namespace?: string;
|
|
356
|
+
/**
|
|
357
|
+
* Captures the preview as a data URL (PNG or JPEG), adding a `view_effect`
|
|
358
|
+
* tool so the agent can look at what it made. With `ShaderRenderer`:
|
|
359
|
+
* `() => renderer.capture({ type: "image/png" })`.
|
|
360
|
+
*/
|
|
361
|
+
capture?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
362
|
+
/** Commands agents may not see or run. */
|
|
363
|
+
exclude?: (id: string) => boolean;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* The effect editor as agent tools (MCP-shaped, for `@pixerate/editor`'s
|
|
367
|
+
* `ToolRegistry` or any tool loop):
|
|
368
|
+
*
|
|
369
|
+
* - `list_commands`, `run_command`, `run_commands`: every editor command
|
|
370
|
+
* (describe, search the catalog, load, set source, values, presets,
|
|
371
|
+
* keyframes, timing, undo and redo).
|
|
372
|
+
* - `view_effect`, when `capture` is given: an image of the preview.
|
|
373
|
+
*/
|
|
374
|
+
declare function createEffectToolProvider(editor: EffectEditor, options?: EffectToolProviderOptions): AgentToolProvider;
|
|
375
|
+
/** A provider's tool definitions without their handlers, to send to a model. */
|
|
376
|
+
declare function toolDefinitions(provider: AgentToolProvider): McpToolDefinition[];
|
|
377
|
+
/**
|
|
378
|
+
* Runs one of a provider's tools by name, for hosts without a `ToolRegistry`:
|
|
379
|
+
* the handler's result comes back as an MCP `tools/call` result, and a
|
|
380
|
+
* thrown error as an `isError` result.
|
|
381
|
+
*/
|
|
382
|
+
declare function callTool(provider: AgentToolProvider, name: string, args?: Record<string, unknown>): Promise<McpToolResult>;
|
|
383
|
+
/** A system prompt for agents that author effects with these tools. Add your product's own guidance to it. */
|
|
384
|
+
declare const EFFECT_AGENT_INSTRUCTIONS: string;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Keeps a preview in step with an editor: the editor owns the playhead and
|
|
388
|
+
* the values; the preview draws what it is told.
|
|
389
|
+
*/
|
|
390
|
+
|
|
391
|
+
/** What {@link bindShaderRenderer} needs of a renderer (`ShaderRenderer` fits). */
|
|
392
|
+
interface ShaderPreview {
|
|
393
|
+
setSource(source: string): CompileStatus;
|
|
394
|
+
setValues(values: Record<string, ControlValue> | undefined): void;
|
|
395
|
+
/** Seconds. */
|
|
396
|
+
seek(time: number): void;
|
|
397
|
+
pause(): void;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Drives a shader preview from the editor: the source (reporting compile
|
|
401
|
+
* results back), the values at the playhead, and the time. The renderer is
|
|
402
|
+
* paused so the editor's playhead is the only clock. Returns an unbind
|
|
403
|
+
* function.
|
|
404
|
+
*/
|
|
405
|
+
declare function bindShaderRenderer(editor: EffectEditor, renderer: ShaderPreview): () => void;
|
|
406
|
+
/**
|
|
407
|
+
* Draws a vector effect into `container` from the editor: the picture with
|
|
408
|
+
* the values at the playhead, at the playhead's time. Returns an unbind
|
|
409
|
+
* function, which also removes the picture.
|
|
410
|
+
*/
|
|
411
|
+
declare function bindSvgView(editor: EffectEditor, container: HTMLElement): () => void;
|
|
412
|
+
|
|
413
|
+
export { type CompileReport, type CubicBezierEasing, EASING_PRESETS, EFFECT_AGENT_INSTRUCTIONS, type Easing, type EasingPreset, type EditResult, type EffectDocument, EffectEditor, type EffectEditorOptions, type EffectEditorState, type EffectSource, type EffectToolProviderOptions, type Keyframe, type ShaderPreview, type SpringEasing, type Track, bindShaderRenderer, bindSvgView, callTool, createEffectDocument, createEffectEditor, createEffectToolProvider, cubicBezierAt, describeEditor, documentControls, documentIssues, effectCommands, evaluateEasing, evaluateTrack, interpolateControlValue, isEasing, keyframeTimes, motionAt, normalizeKeyframes, parseEffectDocument, toolDefinitions, valuesAt };
|