visualfries 0.1.10115 → 0.3.2
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/README.md +122 -0
- package/bin/visualfries.js +1570 -0
- package/dist/DIContainer.d.ts +2 -1
- package/dist/DIContainer.js +16 -5
- package/dist/SceneBuilder.svelte.d.ts +70 -1
- package/dist/SceneBuilder.svelte.js +96 -29
- package/dist/agent/audioMixer.d.ts +34 -0
- package/dist/agent/audioMixer.js +308 -0
- package/dist/agent/broll.d.ts +35 -0
- package/dist/agent/broll.js +226 -0
- package/dist/agent/capabilities.d.ts +34 -0
- package/dist/agent/capabilities.js +246 -0
- package/dist/agent/captionScene.d.ts +23 -0
- package/dist/agent/captionScene.js +204 -0
- package/dist/agent/catalog.d.ts +24 -0
- package/dist/agent/catalog.js +67 -0
- package/dist/agent/cueFiles.d.ts +54 -0
- package/dist/agent/cueFiles.js +219 -0
- package/dist/agent/cuePresets.d.ts +7 -0
- package/dist/agent/cuePresets.js +50 -0
- package/dist/agent/deterministicMedia.d.ts +61 -0
- package/dist/agent/deterministicMedia.js +303 -0
- package/dist/agent/index.d.ts +18 -0
- package/dist/agent/index.js +18 -0
- package/dist/agent/inspectScene.d.ts +36 -0
- package/dist/agent/inspectScene.js +139 -0
- package/dist/agent/localRender.d.ts +82 -0
- package/dist/agent/localRender.js +702 -0
- package/dist/agent/overlays.d.ts +40 -0
- package/dist/agent/overlays.js +325 -0
- package/dist/agent/productionPlan.d.ts +131 -0
- package/dist/agent/productionPlan.js +322 -0
- package/dist/agent/renderPlan.d.ts +27 -0
- package/dist/agent/renderPlan.js +68 -0
- package/dist/agent/renderRanges.d.ts +24 -0
- package/dist/agent/renderRanges.js +73 -0
- package/dist/agent/runtimeSupport.d.ts +19 -0
- package/dist/agent/runtimeSupport.js +192 -0
- package/dist/agent/streamingEncoder.d.ts +31 -0
- package/dist/agent/streamingEncoder.js +208 -0
- package/dist/agent/transcripts.d.ts +29 -0
- package/dist/agent/transcripts.js +146 -0
- package/dist/agent/transitions.d.ts +20 -0
- package/dist/agent/transitions.js +169 -0
- package/dist/animations/PixiAnimationTarget.d.ts +29 -0
- package/dist/animations/PixiAnimationTarget.js +63 -0
- package/dist/animations/builders/LineHighlighterAnimationBuilder.js +20 -3
- package/dist/animations/builders/WordHighlighterAnimationBuilder.js +15 -2
- package/dist/browser/browserExport.d.ts +73 -0
- package/dist/browser/browserExport.js +180 -0
- package/dist/browser/glTransitions.d.ts +37 -0
- package/dist/browser/glTransitions.js +261 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/mediaDecode.d.ts +31 -0
- package/dist/browser/mediaDecode.js +152 -0
- package/dist/builders/PixiComponentBuilder.d.ts +6 -0
- package/dist/builders/PixiComponentBuilder.js +12 -0
- package/dist/builders/_ComponentState.svelte.d.ts +7 -5
- package/dist/builders/_ComponentState.svelte.js +29 -15
- package/dist/builders/html/StyleBuilder.js +9 -8
- package/dist/builders/html/TextComponentHtmlBuilder.js +4 -2
- package/dist/builders/html/processors/AppearanceStyleProcessor.js +1 -1
- package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +7 -0
- package/dist/builders/html/processors/TextEffectsStyleProcessor.js +32 -13
- package/dist/commands/ReplaceSourceOnTimeCommand.js +9 -1
- package/dist/commands/SeekCommand.js +19 -6
- package/dist/components/AnimatedGIF.d.ts +3 -0
- package/dist/components/AnimatedGIF.js +28 -1
- package/dist/components/Component.svelte.d.ts +5 -5
- package/dist/components/Component.svelte.js +29 -13
- package/dist/components/ComponentContext.svelte.js +68 -23
- package/dist/components/hooks/AnimationHook.js +1 -1
- package/dist/components/hooks/CanvasFillHook.d.ts +12 -0
- package/dist/components/hooks/CanvasFillHook.js +75 -0
- package/dist/components/hooks/DeterministicMediaFrameHook.js +3 -0
- package/dist/components/hooks/HtmlTextHook.js +11 -3
- package/dist/components/hooks/HtmlToCanvasHook.js +8 -25
- package/dist/components/hooks/MediaHook.js +172 -47
- package/dist/components/hooks/MediaSeekingHook.js +138 -88
- package/dist/components/hooks/PixiGifHook.js +4 -4
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.d.ts +3 -0
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +85 -8
- package/dist/components/hooks/PixiVideoTextureHook.js +10 -4
- package/dist/components/hooks/PixiVisualTransformHook.d.ts +16 -0
- package/dist/components/hooks/PixiVisualTransformHook.js +102 -0
- package/dist/components/hooks/SubtitlesHook.js +48 -24
- package/dist/components/hooks/VerifyMediaHook.js +2 -2
- package/dist/directors/ComponentDirector.d.ts +1 -0
- package/dist/directors/ComponentDirector.js +41 -8
- package/dist/factories/SceneBuilderFactory.d.ts +3 -0
- package/dist/factories/SceneBuilderFactory.js +6 -0
- package/dist/fonts/fontDiscovery.js +12 -1
- package/dist/layers/Layer.svelte.d.ts +54 -0
- package/dist/layers/Layer.svelte.js +2 -25
- package/dist/managers/AppManager.svelte.d.ts +12 -0
- package/dist/managers/AppManager.svelte.js +180 -8
- package/dist/managers/ComponentsManager.svelte.d.ts +7 -7
- package/dist/managers/ComponentsManager.svelte.js +29 -15
- package/dist/managers/DeterministicMediaManager.d.ts +6 -0
- package/dist/managers/DeterministicMediaManager.js +57 -3
- package/dist/managers/EventManager.js +3 -1
- package/dist/managers/LayersManager.svelte.d.ts +54 -0
- package/dist/managers/RenderManager.d.ts +5 -0
- package/dist/managers/RenderManager.js +67 -21
- package/dist/managers/StateManager.svelte.d.ts +56 -0
- package/dist/managers/StateManager.svelte.js +60 -58
- package/dist/managers/SubtitlesManager.svelte.js +1 -3
- package/dist/managers/TimeManager.svelte.d.ts +4 -0
- package/dist/managers/TimeManager.svelte.js +23 -7
- package/dist/schemas/runtime/deterministic.d.ts +3 -0
- package/dist/schemas/runtime/deterministic.js +5 -1
- package/dist/schemas/runtime/types.d.ts +36 -15
- package/dist/schemas/scene/components.d.ts +126 -0
- package/dist/schemas/scene/components.js +11 -0
- package/dist/schemas/scene/core.d.ts +109 -10
- package/dist/schemas/scene/core.js +1 -1
- package/dist/utils/mediaWindow.d.ts +13 -0
- package/dist/utils/mediaWindow.js +25 -0
- package/dist/utils/svgGenerator.js +1 -1
- package/dist/utils/timelineWindow.d.ts +2 -0
- package/dist/utils/timelineWindow.js +7 -0
- package/dist/utils/utils.js +2 -4
- package/docs/AGENT_PATTERNS.md +243 -0
- package/docs/AGENT_WORKFLOW.md +364 -0
- package/docs/AUTHORING_BEST_PRACTICES.md +188 -0
- package/docs/AUTHORING_SYSTEM_AUDIT.md +98 -0
- package/docs/BROWSER_EXPORT_SPIKE.md +55 -0
- package/docs/DETERMINISTIC_RENDERER.md +83 -0
- package/docs/NEXT_RELEASE.md +28 -0
- package/docs/PROPOSED_VISUALFRIES_SKILL.md +68 -0
- package/docs/examples/agent-cues.json +49 -0
- package/docs/examples/agent-transcript.json +23 -0
- package/docs/examples/agent-transcript.srt +7 -0
- package/docs/examples/agent-transcript.vtt +7 -0
- package/docs/examples/image-animation.json +87 -0
- package/docs/examples/native-text-metric-badge.json +109 -0
- package/package.json +133 -100
- package/skills/visualfries/SKILL.md +328 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# VisualFries Authoring Best Practices
|
|
2
|
+
|
|
3
|
+
VisualFries is an authoring system, not only a schema. A scene is correct only when its semantic components survive validation, runtime evaluation, frame QA, and final rendering.
|
|
4
|
+
|
|
5
|
+
## Default workflow
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
inspect inputs and runtime
|
|
9
|
+
-> choose native semantic components
|
|
10
|
+
-> author scene
|
|
11
|
+
-> validate + inspect structure
|
|
12
|
+
-> frame-QA entry, settled, and exit states
|
|
13
|
+
-> reseek the same frames
|
|
14
|
+
-> render with the deterministic final path
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Validation proves shape. `inspect` proves structural references and timing. Neither proves that a renderer evaluates an animation or effect.
|
|
18
|
+
|
|
19
|
+
## Component decision tree
|
|
20
|
+
|
|
21
|
+
1. Is the visible content typography?
|
|
22
|
+
- Use `TEXT` for headings, metrics, labels, badges, cards, verdicts, CTAs, and other editable words.
|
|
23
|
+
- Use `SUBTITLES` when typography follows transcript timing.
|
|
24
|
+
2. Is it a photo, screenshot, logo, illustration, or supplied bitmap/vector asset?
|
|
25
|
+
- Use `IMAGE` (`GIF` for animated image assets).
|
|
26
|
+
3. Is it moving footage or sound?
|
|
27
|
+
- Use `VIDEO` or `AUDIO`.
|
|
28
|
+
4. Is it independent geometry, decoration, progress, a mask-like layout element, or a transition cover?
|
|
29
|
+
- Use `SHAPE`.
|
|
30
|
+
5. Does typography require a treatment that native `TEXT` cannot render?
|
|
31
|
+
- Rasterization is an explicit fallback. Record the missing native capability and frame-QA the result. Do not rasterize typography merely for convenience.
|
|
32
|
+
|
|
33
|
+
## Native TEXT is mandatory by default
|
|
34
|
+
|
|
35
|
+
Use one `TEXT` component for a normal metric badge such as `881 VIEWS`. It owns its text, background, radius, alignment, outline, shadow, and animation.
|
|
36
|
+
|
|
37
|
+
Good:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"id": "views-badge",
|
|
42
|
+
"type": "TEXT",
|
|
43
|
+
"text": "881 VIEWS",
|
|
44
|
+
"timeline": { "startAt": 0.2, "endAt": 2.8 },
|
|
45
|
+
"order": 10,
|
|
46
|
+
"appearance": {
|
|
47
|
+
"x": 90,
|
|
48
|
+
"y": 150,
|
|
49
|
+
"width": 420,
|
|
50
|
+
"height": 132,
|
|
51
|
+
"horizontalAlign": "center",
|
|
52
|
+
"verticalAlign": "center",
|
|
53
|
+
"background": {
|
|
54
|
+
"enabled": true,
|
|
55
|
+
"color": "#F5D547",
|
|
56
|
+
"target": "wrapper",
|
|
57
|
+
"radius": 24
|
|
58
|
+
},
|
|
59
|
+
"text": {
|
|
60
|
+
"fontFamily": "Montserrat",
|
|
61
|
+
"fontSize": { "value": 72, "unit": "px" },
|
|
62
|
+
"fontWeight": "900",
|
|
63
|
+
"color": "#101820",
|
|
64
|
+
"textAlign": "center",
|
|
65
|
+
"outline": { "enabled": true, "color": "#FFFFFF", "size": 2 },
|
|
66
|
+
"shadow": {
|
|
67
|
+
"enabled": true,
|
|
68
|
+
"color": "#000000",
|
|
69
|
+
"blur": 12,
|
|
70
|
+
"offsetX": 0,
|
|
71
|
+
"offsetY": 4,
|
|
72
|
+
"opacity": 0.55
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Bad:
|
|
80
|
+
|
|
81
|
+
- `881 VIEWS.png` as a full-card `IMAGE`.
|
|
82
|
+
- A rectangle `SHAPE` whose only purpose is to sit behind ordinary `TEXT`.
|
|
83
|
+
- SVG typography generated by a production plan without an explicit native limitation.
|
|
84
|
+
- Assuming schema-valid `clipColor`, dashed outline, or a generic blur must render.
|
|
85
|
+
|
|
86
|
+
A separate `SHAPE` is justified when geometry needs independent timing, motion, progress behavior, or decoration. It is not the default badge background.
|
|
87
|
+
|
|
88
|
+
Directly authored transition geometry is `SHAPE`. `addAgentTransitions` now emits a full-frame animated rectangle rather than the former empty-TEXT compatibility cover.
|
|
89
|
+
|
|
90
|
+
Complete example: [`examples/native-text-metric-badge.json`](examples/native-text-metric-badge.json).
|
|
91
|
+
|
|
92
|
+
## TEXT rendering and compositing
|
|
93
|
+
|
|
94
|
+
`TEXT` uses a wrapper plus an inner text element.
|
|
95
|
+
|
|
96
|
+
- `appearance.background.target: "wrapper"` fills the fixed component box. Use this for badges/cards and for gradient text on a background.
|
|
97
|
+
- `appearance.background.target: "element"` hugs the glyph block and receives legacy `0.22em` padding only when explicit padding is absent.
|
|
98
|
+
- `appearance.text.padding` accepts a non-negative pixel number or `{ top, right, bottom, left }`.
|
|
99
|
+
- `appearance.background.radius` is in pixels.
|
|
100
|
+
- `appearance.text.color` accepts solid colors or gradients. Gradient glyphs use CSS background clipping.
|
|
101
|
+
- `appearance.background.color` accepts solid colors or gradients.
|
|
102
|
+
- Avoid gradient glyphs plus an element-target background: both compete for the inner element's CSS background. Use a wrapper background.
|
|
103
|
+
- Structured outline uses pixel width. Only solid outline is rendered; `dashed`, `dotted`, and `dashArray` remain validation-only.
|
|
104
|
+
- Structured shadow renders color, opacity, x/y offsets, and blur. Legacy named shadow presets remain separate behavior.
|
|
105
|
+
- Wrapper-background TEXT animations target the wrapper, so background and glyph enter together.
|
|
106
|
+
- Plain `TEXT` can target `words`, `lines`, or `chars` through SplitText animations. Transcript-timed active-word behavior belongs on `SUBTITLES`; plain TEXT has no typed word-timing authoring field.
|
|
107
|
+
- `activeWord` and `activeLine` support color/background/weight/scale. `highlightColors` cycles solid colors by active index. If both modes are enabled, `activeWord` wins and validation reports the conflict.
|
|
108
|
+
- Gradient entries in `highlightColors` are diagnosed as unsupported.
|
|
109
|
+
- `clipColor` has no defined runtime semantics. Runtime-aware validation warns before permissive nested parsing can strip it; strict mode rejects it.
|
|
110
|
+
|
|
111
|
+
Browser preview keeps TEXT as HTML above the Pixi canvas. Server/final rendering rasterizes TEXT into Pixi. Risky cross-type stacking and CSS effects require final-render frame QA because preview and final compositing can differ.
|
|
112
|
+
|
|
113
|
+
## Animation contract
|
|
114
|
+
|
|
115
|
+
Runtime-confirmed component animation support:
|
|
116
|
+
|
|
117
|
+
| Component | Animation status | Notes |
|
|
118
|
+
| ------------------- | --------------------- | -------------------------------------------------------------------------------------------- |
|
|
119
|
+
| `TEXT` | Supported | Element or wrapper target; words/lines/chars available. |
|
|
120
|
+
| `SUBTITLES` | Supported with limits | Cue timing works; advanced `out` anchors need visual QA. |
|
|
121
|
+
| `IMAGE` | Supported | Shared Pixi target: relative x/y offsets, opacity, degree rotation, uniform and axis scales. |
|
|
122
|
+
| `VIDEO` | Supported transforms | Same Pixi contract; playback-rate/loop parity remains limited. |
|
|
123
|
+
| `GIF` | Supported transforms | Same Pixi contract; native/final GIF timing parity remains limited. |
|
|
124
|
+
| `SHAPE` | Supported | Regular and progress shapes use a stable outer Pixi target. |
|
|
125
|
+
| `COLOR`, `GRADIENT` | Supported | Canvas fill rendered into Pixi, then the shared transform target. |
|
|
126
|
+
| `AUDIO` | Not applicable | AUDIO has no visual animation target. |
|
|
127
|
+
|
|
128
|
+
For Pixi visuals, animation `x` and `y` are translation offsets relative to authored placement. Pivot/transform origin is fixed at the component center and is not author-configurable. This matches TEXT translation semantics and keeps swipe/drift helpers coherent.
|
|
129
|
+
|
|
130
|
+
Animation rules:
|
|
131
|
+
|
|
132
|
+
- `component.timeline.startAt` offsets the component timeline.
|
|
133
|
+
- Animation-entry `startAt` is relative to component start.
|
|
134
|
+
- `enabled: false` entries do not run.
|
|
135
|
+
- Prefer frame-index-derived times (`frame / fps`) for deterministic QA.
|
|
136
|
+
- For each animation, inspect pre-entry, first-active/mid-entry, settled, and exit frames.
|
|
137
|
+
- Seek forward, backward, and back to the same frame. Same frame must reproduce the same transform/pixels.
|
|
138
|
+
- Destroy/rebuild tests matter; teardown must revert and kill GSAP timelines.
|
|
139
|
+
- SplitText selectors (`words`, `lines`, `chars`, CSS selectors) are TEXT-only. Runtime-aware validation warns (or errors in strict mode) instead of treating Pixi root fallback as support.
|
|
140
|
+
- Animation `setup` steps and `alignTween: "end"|"center"` are not production-safe yet.
|
|
141
|
+
|
|
142
|
+
Complete IMAGE example: [`examples/image-animation.json`](examples/image-animation.json).
|
|
143
|
+
|
|
144
|
+
## Effects and renderer truth
|
|
145
|
+
|
|
146
|
+
Confirmed:
|
|
147
|
+
|
|
148
|
+
- TEXT: structured shadow and solid outline.
|
|
149
|
+
- IMAGE/VIDEO: `layoutSplit` and `fillBackgroundBlur` through the Pixi split-screen path.
|
|
150
|
+
- SHAPE: basic canvas/Pixi geometry and progress shapes.
|
|
151
|
+
|
|
152
|
+
Validation-only or incomplete:
|
|
153
|
+
|
|
154
|
+
- Generic `blur`, `colorAdjustment`, and `rotationRandomizer` are not generally attached to renderers.
|
|
155
|
+
- SHAPE rectangle `cornerRadius` and gradient fill require explicit rendered verification; do not treat schema acceptance as support.
|
|
156
|
+
- Agent transition helpers emit native animated SHAPE rectangles.
|
|
157
|
+
- Same-layer component stacking uses `component.order` (higher order renders later/on top after synchronization). Higher layer order renders above lower layer order in final Pixi composition.
|
|
158
|
+
|
|
159
|
+
## QA checklist
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
visualfries doctor --json
|
|
163
|
+
visualfries catalog --component TEXT --capabilities --json
|
|
164
|
+
visualfries validate scene.json --strict-runtime-support
|
|
165
|
+
visualfries inspect scene.json --json
|
|
166
|
+
visualfries explain scene.json --component views-badge --frame 12 --json
|
|
167
|
+
visualfries parity scene.json --frames 5,12,35 --output qa/parity --json
|
|
168
|
+
|
|
169
|
+
# Render explicit frame windows around authored events.
|
|
170
|
+
visualfries render scene.json --frames-only --from-frame 5 --to-frame 20 --output qa/entry
|
|
171
|
+
visualfries render scene.json --frames-only --from-frame 35 --to-frame 36 --output qa/settled
|
|
172
|
+
|
|
173
|
+
# Final VIDEO/GIF scenes use deterministic-local rendering.
|
|
174
|
+
visualfries render scene.json --stream-encode --output out.mp4
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Uniform three-frame sampling can miss a late or short entrance. Production plans should declare exact `qa.framesAt`; raw scenes should render explicit frame ranges.
|
|
178
|
+
|
|
179
|
+
`parity` captures actual client composition and final server composition, records SHA-256 plus raw and semantic ffmpeg SSIM, evaluates optional class/ROI thresholds from `--rois`, and renders every requested frame forward then backward. It also writes 4× amplified diff rows and a contact sheet. Add `--strict` for CI. The torture-scene baseline passes with zero runtime/resource errors; raw GIF/video decoder noise remains visible and is reported separately from semantic mismatch.
|
|
180
|
+
|
|
181
|
+
## Known open limitations
|
|
182
|
+
|
|
183
|
+
- Visual transform origin is fixed center for Pixi targets; TEXT uses CSS transform ownership. No authorable cross-renderer origin exists.
|
|
184
|
+
- Browser HTML TEXT versus final Pixi TEXT can produce cross-type stacking differences.
|
|
185
|
+
- `clipColor`, gradient highlight palettes, dashed/dotted outline, generic effects, and animation setup steps are unsupported.
|
|
186
|
+
- Native GIF timing and VIDEO/GIF playback controls are not yet preview/final parity guarantees.
|
|
187
|
+
- `componentCenter` and advanced out/align anchors have timing limitations.
|
|
188
|
+
- Radial GRADIENT shape/position currently uses a centered max-radius fallback.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# VisualFries Authoring System Audit
|
|
2
|
+
|
|
3
|
+
Date: 2026-07-12
|
|
4
|
+
|
|
5
|
+
Scope: schema/runtime truth, semantic component selection, visual animation, TEXT compositing, agent diagnostics, preview/final parity, and real frame QA. The current repo is authoritative. The browser/WebGL/MediaBunny worktree was evidence only; browser export was not blindly ported.
|
|
6
|
+
|
|
7
|
+
## Findings, evidence, disposition
|
|
8
|
+
|
|
9
|
+
| Severity | Finding | Evidence | Disposition |
|
|
10
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| Critical | Schema accepted animation data for every component although construction attached `AnimationHook` only to TEXT/SUBTITLES/IMAGE. | Base component schema versus `ComponentDirector`; browser regression from the Funeral short. | Fixed for every visual type through a shared Pixi wrapper target; AUDIO remains explicitly nonvisual. Registry/director synchronization tests prevent silent drift. |
|
|
12
|
+
| Critical | COLOR and GRADIENT validated but had no render hook. | `ComponentDirector` returned bare components. | Fixed with canvas fills, Pixi texture/display construction, shared animation target, tests, and frame-QA scene coverage. |
|
|
13
|
+
| High | IMAGE x/y bridge used absolute-center semantics that contradicted TEXT and authored drift/swipe helpers. | `PixiAnimationTarget`, b-roll helpers, transition helpers. | Fixed: all Pixi x/y are placement-relative offsets around a fixed-center outer wrapper. Migration note added. |
|
|
14
|
+
| High | Unsupported runtime fields could validate silently. | Base animation catchalls, permissive nested TEXT parsing, effect schemas. | Fixed materially: capability registry, default warnings, strict runtime-support gate, property/selector/effect/text conflict diagnostics, and pre-parse clipColor detection. Unknown string presets still need deeper static resolution. |
|
|
15
|
+
| High | Production-plan visible typography defaulted to raster/SVG. | Overlay schema/compiler. | Fixed: native TEXT is default; SVG remains explicit documented fallback. |
|
|
16
|
+
| High | Transition helpers used empty TEXT as full-frame geometry. | Agent transition helper and regressions. | Fixed: helpers now emit animated native SHAPE rectangles. |
|
|
17
|
+
| High | Browser HTML TEXT and final Pixi-rasterized TEXT do not share one stacking representation. | `DomManager`, `HtmlTextHook`, `HtmlToCanvasHook`. | Calibrated parity now passes for supported stacking in the torture scene. Arbitrary HTML/Pixi cross-layer interleaving remains an explicit architectural limitation. |
|
|
18
|
+
| Critical | Generated browser harness replaced EventEmitter3 with a shim that discarded listener context, breaking Pixi WebGL prerender and texture updates. | Browser stacks at `BatchRenderer.onPrerender` (`_flushId`) and `Texture.onBaseTextureUpdated` (`noFrame`). | Fixed with a context/once/removal-compatible shim and regression. Browser IMAGE/VIDEO/GIF/SHAPE/COLOR/GRADIENT now render with zero runtime errors. |
|
|
19
|
+
| High | Client seek returned before its asynchronous render and newly attached animation timelines settled. | `TimelineManager.seek`, `RenderManager` queue, sparse browser captures. | Fixed: both renderer paths now render, re-seek after lazy construction, render again, and the harness performs an initialized seek barrier. |
|
|
20
|
+
| High | Preview and final used different hard-coded canvas backgrounds and ignored scene background. | `AppManager` renderer options. | Fixed: both paths use the solid scene background contract; gradient scene backgrounds still require a GRADIENT component. |
|
|
21
|
+
| Medium | Unconfigured system fonts were treated as Google Fonts, creating CORS failures and nondeterministic fallback noise. | Font discovery and SVG text generation. | Fixed: remote font loading is explicit; unconfigured Arial/system families stay local. |
|
|
22
|
+
| Medium | TEXT padding, active scale, and highlight palette fields were absent/ignored. | TEXT schema/builders/highlighter builders. | Fixed: px padding, active word/line scale, solid palette cycling, reset coverage, and deterministic active-word precedence. |
|
|
23
|
+
| Medium | Active-line reset restored background styling instead of glyph color. | `LineHighlighterAnimationBuilder`. | Fixed and asserted explicitly. |
|
|
24
|
+
| Medium | `clipColor` was silently stripped by permissive nested parsing and had no defined semantics. | Runtime/schema search plus parse behavior. | Not invented. Warned by default, rejected by strict gate, documented as open semantic design. |
|
|
25
|
+
| Medium | `visible: false` became true in component state. | Truthy fallback in `_ComponentState`. | Fixed with nullish default and shared wrapper visibility enforcement. |
|
|
26
|
+
| Medium | Same-layer order, component teardown, structured shadow/outline, wrapper transform ownership, and radius units had confirmed defects. | Prior audit source/render tests. | Fixed in the current uncommitted audit set with regression coverage. |
|
|
27
|
+
| High | Scene teardown destroyed Pixi before async component hooks completed, while manager listeners could not be removed by identity. | `SceneBuilder.destroy`, `ComponentsManager.destroy`, `EventManager.on`, `RenderManager`. | Fixed: component/media teardown is awaited before Pixi/DOM destruction; registered callback identities are detached and covered by lifecycle regressions. |
|
|
28
|
+
|
|
29
|
+
## Runtime truth
|
|
30
|
+
|
|
31
|
+
- TEXT/SUBTITLES: HTML animation target; TEXT selectors include container, words, lines, chars, and CSS.
|
|
32
|
+
- IMAGE/VIDEO/GIF/SHAPE/COLOR/GRADIENT: stable outer Pixi target with relative x/y, opacity, degree rotation, scale, scaleX, and scaleY. Pixi selectors support container only.
|
|
33
|
+
- AUDIO: no visual target and no visual animation claim.
|
|
34
|
+
- Visual timing is component-relative; disabled global/list entries do not evaluate; destroy reverts/kills timelines.
|
|
35
|
+
- Pixi transform origin is fixed component center and not authorable.
|
|
36
|
+
- COLOR supports CSS-color canvas fill including alpha. GRADIENT supports linear/radial canvas fills; radial shape/position currently falls back to centered max radius.
|
|
37
|
+
|
|
38
|
+
## TEXT/compositing truth
|
|
39
|
+
|
|
40
|
+
- Paint/style merge order is component background, glyph fill/gradient, then text effects. Active highlight background is a separate element behind split glyphs.
|
|
41
|
+
- Wrapper-target background is preferred for badges/cards and required when both background and glyph are gradients.
|
|
42
|
+
- Element-target gradient background plus gradient glyph fill is diagnosed because both use `background-image` on the inner element.
|
|
43
|
+
- Pixel padding is authorable through `appearance.text.padding`; absent element-target padding keeps the prior `0.22em` fallback.
|
|
44
|
+
- Active word/line scale and solid `highlightColors` work. Active word takes precedence if both modes are enabled. Gradient highlight palettes remain unsupported.
|
|
45
|
+
- Structured solid outline and structured shadow work. Dashed/dotted outline and generic effects remain unsupported/incomplete.
|
|
46
|
+
|
|
47
|
+
## Agent contract
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
visualfries catalog --component TEXT --capabilities --json
|
|
51
|
+
visualfries validate scene.json # compatible load + explicit warnings
|
|
52
|
+
visualfries validate scene.json --strict-runtime-support
|
|
53
|
+
visualfries inspect scene.json --json
|
|
54
|
+
visualfries explain scene.json --component <id> --frame <n> --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`explain` seeks the actual browser runtime and reads the chosen HTML/Pixi target; it does not approximate easing in a separate static evaluator.
|
|
58
|
+
|
|
59
|
+
## Verification state
|
|
60
|
+
|
|
61
|
+
- `pnpm exec vitest run`: 64/64 files, 439/439 tests passed.
|
|
62
|
+
- `pnpm run check`: 0 errors; 8 pre-existing docs/accessibility/CSS warnings.
|
|
63
|
+
- `pnpm run build`: passed; `pnpm run package` and standalone `pnpm exec publint` passed.
|
|
64
|
+
- A local runtime-truth torture scene passed strict runtime validation with 0 issues across 9 visual components. Generated QA inputs and outputs are intentionally not committed.
|
|
65
|
+
- Real deterministic final render: 46 frames; frames 0, 9, 18, 30, and 45 visually reviewed.
|
|
66
|
+
- Sparse forward/back/reseek `[18, 30, 18]`: repeated frame 18 matched exactly at SHA-256 `5e30d8dd44ed7cd9ee7ecca8dd6f48dcbf8a48adfd4ac11b47d0eb3d1645636b`.
|
|
67
|
+
- Runtime `explain` at SHAPE frame 18 returned the actual Pixi target and computed x/y/opacity/rotation/scales.
|
|
68
|
+
- Browser/final parity is green on frames 0, 9, 18, 30, and 45. Raw whole-frame SSIM is `0.926262–0.999791`; semantic SSIM is `0.967344–0.999804`. Same-Pixi settled ROIs are `0.995803–1.0` raw, TEXT/SUBTITLES are `0.997588–0.999813`, and zero browser/final runtime or resource errors were recorded.
|
|
69
|
+
- Forward/reverse order `[0,9,18,30,45,45,30,18,9,0]` is stable. Frames 9/18/30/45 are byte-exact in both paths; final frame 0 repeats at SSIM `0.999791` because SVG text rasterization differs by at most three luma levels.
|
|
70
|
+
- A local contact sheet and parity manifest were reviewed across preview, final, and amplified-difference outputs; generated files are intentionally not committed.
|
|
71
|
+
- `git diff --check`: clean. No commit, push, merge, publish, or global-skill modification occurred.
|
|
72
|
+
|
|
73
|
+
## Open limitations
|
|
74
|
+
|
|
75
|
+
1. Browser HTML typography is always above the shared Pixi canvas. Arbitrary TEXT/Pixi cross-layer interleaving can still differ from final ordering; the supported torture composition keeps typography above Pixi visuals.
|
|
76
|
+
2. Native GIF and deterministic ffmpeg decoding differ in palette dithering. Raw GIF ROI reaches `0.539`; 2px semantic SSIM is `0.977`, confirming matching structure/color fields without pretending pixels are identical.
|
|
77
|
+
3. Native browser VIDEO and predecoded final VIDEO use different decode/color paths; current ROI semantic SSIM is `0.939–0.998`. Exact media-frame identity needs a future PTS contract for half-frame starts.
|
|
78
|
+
4. Plain absolute local paths now load, but relative paths are still resolved from process cwd rather than the scene file directory, and assetId-only component sources still need runtime hydration from the asset registry.
|
|
79
|
+
5. Final frame-0 SVG text reseek is visually stable (`0.999791`) but not byte-exact. Other sampled forward/back reseeks are exact.
|
|
80
|
+
6. Transform origin is not authorable across visual renderers.
|
|
81
|
+
7. `clipColor` semantics, gradient highlight palettes, generic effects, dashed/dotted outline, and animation setup steps remain unsupported.
|
|
82
|
+
8. Unknown system animation preset names are still resolved at construction time rather than fully diagnosed statically.
|
|
83
|
+
9. Advanced animation center/end anchors and active-line transcript timing remain limited.
|
|
84
|
+
10. Radial gradient shape/position fields use a centered fallback.
|
|
85
|
+
11. Browser export remains a separate next phase; the MediaBunny spike was not promoted without the higher-priority runtime-truth/parity gates.
|
|
86
|
+
|
|
87
|
+
## Honest readiness score
|
|
88
|
+
|
|
89
|
+
| Dimension | Score | Reason |
|
|
90
|
+
| --- | ---: | --- |
|
|
91
|
+
| Creative speed | 8.3/10 | Semantic helpers, native transitions, and capability discovery remove substantial source-reading. |
|
|
92
|
+
| Runtime trust | 8.2/10 | Strict runtime gate and construction-synchronized registry close the largest silent-success gaps. Unknown preset resolution remains. |
|
|
93
|
+
| Editability | 8.7/10 | Native TEXT defaults, padding/highlighting, SHAPE transitions, and raw JSON output preserve authorability. |
|
|
94
|
+
| Determinism | 8.2/10 | Shared targets and frames 9/18/30/45 reseek exactly; frame-0 SVG text is visually stable rather than byte-exact, and native media timing caveats remain. |
|
|
95
|
+
| Debugging | 8.0/10 | Runtime-backed explain plus stable capability IDs are useful; deeper preset/effect state could improve. |
|
|
96
|
+
| Agent ergonomics | 8.1/10 | Catalog, strict validate, inspect, explain, docs, examples, and release notes form a coherent loop. |
|
|
97
|
+
| Preview/final parity | 8.2/10 | Zero missing visuals/errors; semantic whole-frame and all class ROIs pass. Cross-layer HTML/Pixi ordering and decoder-level pixel differences remain. |
|
|
98
|
+
| Production readiness | 8.0/10 | Agent-visible runtime truth plus green supported-path parity clears the 8/10 bar. Relative/assetId media hydration and arbitrary mixed stacking still block 9/10. |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Browser WebGL + MediaBunny export spike
|
|
2
|
+
|
|
3
|
+
This spike adds a separate deterministic browser export path. Existing interactive preview and local/cloud FFmpeg rendering are unchanged.
|
|
4
|
+
|
|
5
|
+
MediaBunny is pinned to `1.49.0` for this spike. The newer release available during implementation was less than 14 days old.
|
|
6
|
+
|
|
7
|
+
## Architecture and next slices
|
|
8
|
+
|
|
9
|
+
Current scene transitions are schema data only; existing agent transitions are full-frame overlay components. This milestone therefore keeps normal preview untouched and proves a separate browser export boundary: server-mode Pixi scene canvases → curated WebGL transition canvas → MediaBunny encode/mux. Next reviewable slices are: wire the curated adapter into a frame-index transition manager at the renderer's pre-present seam, adapt MediaBunny decoded samples to the deterministic media provider for real browser video inputs, then add an OPFS/File System Access target for long exports. None requires replacing the FFmpeg/cf-worker fallback.
|
|
10
|
+
|
|
11
|
+
## What it proves
|
|
12
|
+
|
|
13
|
+
- VisualFries/Pixi renders two animated 1080x1920 scenes at exact `frameIndex / 30` timestamps.
|
|
14
|
+
- A curated gl-transitions-compatible WebGL adapter composites `from`, `to`, `progress`, `ratio`, and whitelisted parameters. It ships `fade` and `radial-wipe`; shader compile/link failure falls back to fade.
|
|
15
|
+
- The final WebGL canvas is fed directly to MediaBunny `CanvasSource`. No PNG/JPEG serialization and no websocket frame transport occurs.
|
|
16
|
+
- MediaBunny encodes AVC/H.264 video and AAC audio and muxes MP4. The in-browser audio mix starts at timestamp zero.
|
|
17
|
+
- Every `CanvasSource.add()` is awaited, propagating encoder/writer backpressure. The 10-second demo uses `BufferTarget`; larger integrations can pass a positional `StreamTarget` writable that honors each chunk's `position`.
|
|
18
|
+
|
|
19
|
+
## Run interactively
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Open `http://localhost:5173/browser-export-spike`, confirm the AVC + AAC capability report, then click **Render 10-second MP4**.
|
|
26
|
+
|
|
27
|
+
## Produce the checked artifact
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
node scripts/render-browser-export-spike.mjs
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Default output: `artifacts/browser-export-spike/demo.mp4`.
|
|
34
|
+
|
|
35
|
+
Inspect it:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ffprobe -v error -show_streams -show_format artifacts/browser-export-spike/demo.mp4
|
|
39
|
+
ffmpeg -i artifacts/browser-export-spike/demo.mp4 -vf "select='eq(n,119)+eq(n,120)+eq(n,135)+eq(n,149)+eq(n,150)'" -vsync 0 artifacts/browser-export-spike/frame-%02d.png
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Expected: 300 frames, 10 seconds, 1080x1920 AVC video, AAC stereo audio with `start_time=0`, no blank transition samples, and zero shader fallbacks on a compatible WebGL implementation.
|
|
43
|
+
|
|
44
|
+
## Verified artifact (2026-07-11)
|
|
45
|
+
|
|
46
|
+
- H.264, 1080x1920, 30fps, 300 decoded frames, video duration `10.000000`
|
|
47
|
+
- AAC stereo, 48kHz, audio `start_time=0.000000` (AAC padding extends its reported duration to `10.069333`)
|
|
48
|
+
- First 100ms audio RMS approximately `-34.6 dB`, confirming immediate non-silent audio
|
|
49
|
+
- Transition-window sampled average luma ranged `38.49..50.77`; visual frame inspection found no blank/white frame
|
|
50
|
+
- Four motion samples produced four different decoded-frame hashes
|
|
51
|
+
- Runtime shader fallback count: `0`
|
|
52
|
+
|
|
53
|
+
## Capability and fallback contract
|
|
54
|
+
|
|
55
|
+
The browser path probes the exact requested dimensions and AVC/AAC configuration before work starts. It never silently changes codecs. If unavailable, the structured result names `deterministic-local-ffmpeg`, preserving the existing VisualFries/cf-worker fallback. This milestone does not promise mobile support or arbitrary user GLSL.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# VisualFries Deterministic Renderer
|
|
2
|
+
|
|
3
|
+
VisualFries should own final rendering as a local, first-class capability.
|
|
4
|
+
|
|
5
|
+
## Decision
|
|
6
|
+
|
|
7
|
+
Final output for scenes containing `VIDEO` or `GIF` media must not rely on native browser media seek. Browser media seek is acceptable for preview and QA only.
|
|
8
|
+
|
|
9
|
+
The local deterministic renderer is the source-of-truth path:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
scene.json
|
|
13
|
+
-> collect VIDEO/GIF requirements
|
|
14
|
+
-> predecode media to exact frame images/manifests
|
|
15
|
+
-> browser compositor receives exact frame image for each scene frame
|
|
16
|
+
-> encode frames with ffmpeg
|
|
17
|
+
-> mix/mux audio with ffmpeg
|
|
18
|
+
-> mp4
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
ContentFries cloud workers should eventually become hosted execution wrappers around this VisualFries renderer. They own queues, uploads, progress, retries, chunking, URL signing, auth-specific asset resolution, and deployment concerns, but the render semantics should live in VisualFries.
|
|
22
|
+
|
|
23
|
+
## Preview Contract
|
|
24
|
+
|
|
25
|
+
Preview means cheap and fast:
|
|
26
|
+
|
|
27
|
+
- sampled QA frames,
|
|
28
|
+
- low-resolution or short-range renders,
|
|
29
|
+
- layout inspection,
|
|
30
|
+
- rough browser media playback when explicitly requested.
|
|
31
|
+
|
|
32
|
+
Preview is not a slower copy of final render. If a preview takes longer than final output, it is not a useful preview.
|
|
33
|
+
|
|
34
|
+
## Current Migration State
|
|
35
|
+
|
|
36
|
+
This package now exposes agent-safe render planning:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { resolveAgentRenderPlan, requiresDeterministicRender } from 'visualfries/agent';
|
|
40
|
+
|
|
41
|
+
const plan = resolveAgentRenderPlan(scene, { mode: 'final' });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The CLI blocks final `VIDEO`/`GIF` renders unless the caller explicitly chooses preview or the legacy escape hatch:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
visualfries render scene.json --render-mode preview --output preview.mp4
|
|
48
|
+
visualfries render scene.json --allow-browser-media-final --output unsafe-experiment.mp4
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The package also includes the first local predecode core:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { prepareLocalDeterministicMedia } from 'visualfries/agent';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`prepareLocalDeterministicMedia()` resolves `VIDEO`/`GIF` components, computes active frame windows, extracts exact image sequences with local `ffmpeg`, and returns a `visualfries-provider-predecoded` frame manifest. The CLI can inject that manifest into the render page as a deterministic media provider.
|
|
58
|
+
|
|
59
|
+
The CLI also supports image-pipe final encoding:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
visualfries render scene.json --stream-encode --image-format jpg --output out.mp4
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
With `--stream-encode`, rendered frames are written directly into local `ffmpeg` through `image2pipe` instead of first creating a temporary frame sequence. If audio is present, the CLI writes a silent video first and then muxes audio with `-c:v copy`.
|
|
66
|
+
|
|
67
|
+
Audio mixing is local-first as well. The CLI now plans audio from active `VIDEO`/`AUDIO` components, `audioTracks`, and `settings.audio`, prepares each source to 48k stereo FLAC, applies timeline delay/volume, mixes with `amix`, trims to the rendered range, and muxes the mixed track into the final MP4.
|
|
68
|
+
|
|
69
|
+
The same implementation is available as an importable local render boundary:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { renderSceneLocally } from 'visualfries/agent';
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Hosted workers should call this boundary instead of reimplementing frame extraction, browser composition, stream encoding, or audio mixing. The scene passed into this boundary must already contain public, local, or otherwise render-accessible media URLs. URL signing, signed URL refresh, and private asset authorization are wrapper responsibilities, not VisualFries responsibilities. VisualFries must not know how to authenticate ContentFries private assets; if media URLs are not render-accessible, it should fail with useful diagnostics. The package must stay light: `ffmpeg`, Playwright/Chromium, and hosted queue/upload infrastructure are runtime dependencies of the caller, not bundled VisualFries assets.
|
|
76
|
+
|
|
77
|
+
The local renderer owns trim-aware final output. When `scene.settings.trimZones` intersects the requested contiguous frame window, VisualFries renders only the kept frame ranges and concatenates them through the stream encoder. Audio mixing uses the same kept scene-time ranges so video duration and audio duration stay aligned.
|
|
78
|
+
|
|
79
|
+
The same boundary also supports exact single-frame output with `framesOnly: true` and explicit server renderer selection through `serverRendererMode: "canvas" | "webgl"`. Hosted wrappers should pass these options through instead of maintaining separate single-frame or renderer-mode semantics.
|
|
80
|
+
|
|
81
|
+
Frame image quality accepts either browser form (`0..1`) or percent form (`0..100`) and is normalized before the browser render starts. This keeps wrappers from failing later with opaque frame extraction errors when they pass values such as `88`.
|
|
82
|
+
|
|
83
|
+
The next migration slice is making the ContentFries worker call the VisualFries core instead of carrying its own duplicate render semantics.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Next Release Notes (Unreleased)
|
|
2
|
+
|
|
3
|
+
Recommended semver: **0.2.0**. The schemas remain additive/loadable, but confirmed ignored behavior now evaluates and can change pixels. This deserves a pre-1.0 minor release rather than pretending it is a patch-only change.
|
|
4
|
+
|
|
5
|
+
## Added
|
|
6
|
+
|
|
7
|
+
- Typed component capability registry exposed through agent exports and `catalog --component <TYPE> --capabilities --json`.
|
|
8
|
+
- Warning-by-default runtime-support diagnostics and `validate --strict-runtime-support` for agents/CI.
|
|
9
|
+
- Runtime-backed `explain --component <id> --frame <n>` computed target state.
|
|
10
|
+
- Shared deterministic Pixi animation target for IMAGE, VIDEO, GIF, regular/progress SHAPE, COLOR, and GRADIENT.
|
|
11
|
+
- Real COLOR and GRADIENT canvas-to-Pixi render paths.
|
|
12
|
+
- Native TEXT pixel padding, active word/line scale, and solid highlight palette cycling.
|
|
13
|
+
|
|
14
|
+
## Behavior fixes / migration notes
|
|
15
|
+
|
|
16
|
+
- Pixi animation x/y now mean placement-relative translation offsets, matching TEXT and existing swipe/drift helpers. Scenes authored against the short-lived absolute-center IMAGE bridge should subtract the component center from old x/y values.
|
|
17
|
+
- `addAgentTransitions` now emits native SHAPE rectangles instead of background-only empty TEXT.
|
|
18
|
+
- `visible: false` is preserved by component state and shared visual wrappers.
|
|
19
|
+
- Active word wins when active word and active line are both enabled; runtime validation reports the conflict.
|
|
20
|
+
- `clipColor` is diagnosed before permissive parsing can silently discard it. Strict runtime validation rejects it.
|
|
21
|
+
|
|
22
|
+
## Still limited
|
|
23
|
+
|
|
24
|
+
- Transform origin is fixed-center for Pixi visuals and not authorable across renderers.
|
|
25
|
+
- Client HTML TEXT stacking versus final Pixi TEXT remains an architectural parity gap.
|
|
26
|
+
- Native GIF timing and VIDEO/GIF loop/playback-rate parity are not guarantees yet.
|
|
27
|
+
- Gradient highlight palettes, clipColor semantics, generic effects, and advanced setup/anchor behavior remain unsupported.
|
|
28
|
+
- Radial gradient shape/position uses a centered max-radius fallback.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Proposed VisualFries Skill Update (Review Only)
|
|
2
|
+
|
|
3
|
+
This is a repo-local proposal. It does not modify `/Users/lukasgregor/.agents/skills/visualfries/SKILL.md`.
|
|
4
|
+
|
|
5
|
+
Apply these sections to the installed skill only after review/approval.
|
|
6
|
+
|
|
7
|
+
## Replace the agent rule
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
inspect inputs and actual runtime capability
|
|
11
|
+
-> choose native semantic components
|
|
12
|
+
-> author scene JSON
|
|
13
|
+
-> validate + inspect structure
|
|
14
|
+
-> frame-QA entry, settled, exit, and deterministic reseeks
|
|
15
|
+
-> final deterministic render
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Add: Semantic component policy
|
|
19
|
+
|
|
20
|
+
- Visible/editable typography defaults to native `TEXT`, including metrics, labels, badges, verdicts, cards, hooks, and CTAs.
|
|
21
|
+
- Transcript-timed typography uses `SUBTITLES`.
|
|
22
|
+
- A TEXT badge owns its background/gradient/radius/alignment/outline/shadow/animation when those treatments are runtime-supported.
|
|
23
|
+
- Do not create a separate `SHAPE` merely as an ordinary text background. SHAPE is independent geometry, decoration, progress, mask-like layout, or transition content.
|
|
24
|
+
- Transition covers use native animated `SHAPE`; do not use empty TEXT as geometry.
|
|
25
|
+
- Use `IMAGE` for real image assets: photos, screenshots, logos, illustrations, or supplied raster/vector artwork.
|
|
26
|
+
- Raster/SVG typography is an explicit fallback. Record which native limitation requires it and frame-QA it.
|
|
27
|
+
- Production-plan overlays default to native TEXT. Use `renderAs: "SVG"` only for a documented compatibility fallback.
|
|
28
|
+
|
|
29
|
+
## Add: Runtime truth
|
|
30
|
+
|
|
31
|
+
- Validation is not rendering proof.
|
|
32
|
+
- Confirmed visual targets: `TEXT`, `SUBTITLES`, `IMAGE`, `VIDEO`, `GIF`, `SHAPE`, `COLOR`, and `GRADIENT`. AUDIO is nonvisual.
|
|
33
|
+
- Pixi animation `x`/`y` are placement-relative offsets. Pivot is fixed center. Supported properties: x, y, opacity, rotation (degrees), scale, scaleX, scaleY.
|
|
34
|
+
- `clipColor` is unsupported and strict runtime validation rejects it.
|
|
35
|
+
- `appearance.text.padding` supports pixels; absent element-target padding preserves the legacy `0.22em` fallback.
|
|
36
|
+
- Active word/line scale and solid `highlightColors` cycling work. Active word wins when both word and line modes are enabled.
|
|
37
|
+
- Gradient text should use wrapper-target background when a card background is also needed.
|
|
38
|
+
- Browser HTML TEXT and final Pixi-rasterized TEXT can stack differently; verify risky cross-type compositions in final mode.
|
|
39
|
+
|
|
40
|
+
## Replace QA guidance
|
|
41
|
+
|
|
42
|
+
For every animated component:
|
|
43
|
+
|
|
44
|
+
1. Render a pre-entry frame.
|
|
45
|
+
2. Render first-active or mid-entry frame.
|
|
46
|
+
3. Render settled frame.
|
|
47
|
+
4. Render exit frame when applicable.
|
|
48
|
+
5. Seek away and back to the same frame; compare state/pixels.
|
|
49
|
+
|
|
50
|
+
Uniform three-frame QA is not enough for short or late events. Prefer exact production-plan `qa.framesAt` or explicit `--from-frame`/`--to-frame` windows.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
visualfries doctor --json
|
|
54
|
+
visualfries catalog --component TEXT --capabilities --json
|
|
55
|
+
visualfries validate scene.json --strict-runtime-support
|
|
56
|
+
visualfries inspect scene.json --json
|
|
57
|
+
visualfries explain scene.json --component <id> --frame <n> --json
|
|
58
|
+
visualfries parity scene.json --frames <csv> --output qa/parity --json
|
|
59
|
+
visualfries render scene.json --frames-only --from-frame 5 --to-frame 20 --output qa/entry
|
|
60
|
+
visualfries render scene.json --frames-only --from-frame 35 --to-frame 36 --output qa/settled
|
|
61
|
+
visualfries render scene.json --stream-encode --output out.mp4
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Replace the current limitation section
|
|
65
|
+
|
|
66
|
+
- Cookbook depth is not the only remaining gap.
|
|
67
|
+
- Open engine gaps include authorable transform origin, browser/final TEXT stacking parity, clipColor semantics, gradient highlight palettes, generic effects, VIDEO/GIF playback parity, advanced animation anchors/setup, and calibrated preview/final parity metrics.
|
|
68
|
+
- Link the installed skill to `docs/AUTHORING_BEST_PRACTICES.md` in the package/repository.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"broll": [
|
|
3
|
+
{
|
|
4
|
+
"url": "./assets/profile-scroll.mp4",
|
|
5
|
+
"start": 0.2,
|
|
6
|
+
"end": 1.4,
|
|
7
|
+
"type": "VIDEO",
|
|
8
|
+
"fade": 0.18
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"url": "./assets/chart.png",
|
|
12
|
+
"start": 1.4,
|
|
13
|
+
"end": 2.6,
|
|
14
|
+
"type": "IMAGE",
|
|
15
|
+
"motion": "slow-zoom-in"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"overlays": [
|
|
19
|
+
{
|
|
20
|
+
"text": "LOVE THIS \ud83d\ude0d",
|
|
21
|
+
"start": 0.4,
|
|
22
|
+
"end": 1.1,
|
|
23
|
+
"style": "hook-punch"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"text": "NECK \ud83e\udd2f",
|
|
27
|
+
"start": 1.1,
|
|
28
|
+
"end": 1.7,
|
|
29
|
+
"style": "shock-word"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"text": "your move",
|
|
33
|
+
"start": 2.1,
|
|
34
|
+
"end": 2.7,
|
|
35
|
+
"style": "cta-card"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"transitions": [
|
|
39
|
+
{
|
|
40
|
+
"time": 1.4,
|
|
41
|
+
"style": "dip-to-black"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"time": 2.3,
|
|
45
|
+
"style": "swipe-left",
|
|
46
|
+
"color": "#04483D"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"segments": [
|
|
3
|
+
{
|
|
4
|
+
"id": "s1",
|
|
5
|
+
"text": "Your content is free therapy for people who will never buy.",
|
|
6
|
+
"start": 0,
|
|
7
|
+
"end": 2.8,
|
|
8
|
+
"words": [
|
|
9
|
+
{ "text": "Your", "start": 0, "end": 0.2 },
|
|
10
|
+
{ "text": "content", "start": 0.2, "end": 0.55 },
|
|
11
|
+
{ "text": "is", "start": 0.55, "end": 0.7 },
|
|
12
|
+
{ "text": "free", "start": 0.7, "end": 1.05 },
|
|
13
|
+
{ "text": "therapy", "start": 1.05, "end": 1.5 },
|
|
14
|
+
{ "text": "for", "start": 1.5, "end": 1.68 },
|
|
15
|
+
{ "text": "people", "start": 1.68, "end": 2.0 },
|
|
16
|
+
{ "text": "who", "start": 2.0, "end": 2.15 },
|
|
17
|
+
{ "text": "will", "start": 2.15, "end": 2.32 },
|
|
18
|
+
{ "text": "never", "start": 2.32, "end": 2.55 },
|
|
19
|
+
{ "text": "buy.", "start": 2.55, "end": 2.8 }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|