frameyard 0.8.0 → 0.10.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 +177 -14
- package/GLOSSARY.md +112 -2
- package/README.md +302 -265
- package/dist/assets/integrations.d.ts +8 -4
- package/dist/assets/integrations.d.ts.map +1 -1
- package/dist/assets/integrations.js +8 -4
- package/dist/assets/integrations.js.map +1 -1
- package/dist/assets/provenance.d.ts +2 -2
- package/dist/assets/provenance.d.ts.map +1 -1
- package/dist/assets/provenance.js +5 -3
- package/dist/assets/provenance.js.map +1 -1
- package/dist/assets/tts-supertonic.d.ts +28 -0
- package/dist/assets/tts-supertonic.d.ts.map +1 -0
- package/dist/assets/tts-supertonic.js +156 -0
- package/dist/assets/tts-supertonic.js.map +1 -0
- package/dist/assets/tts.d.ts +18 -6
- package/dist/assets/tts.d.ts.map +1 -1
- package/dist/assets/tts.js +219 -97
- package/dist/assets/tts.js.map +1 -1
- package/dist/cli.js +1685 -93
- package/dist/cli.js.map +1 -1
- package/dist/composition/format.d.ts +1 -1
- package/dist/composition/format.d.ts.map +1 -1
- package/dist/composition/format.js +1 -1
- package/dist/composition/format.js.map +1 -1
- package/dist/context.d.ts +82 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +277 -0
- package/dist/context.js.map +1 -0
- package/dist/contracts.d.ts +25 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/doctor.d.ts +14 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +166 -7
- package/dist/doctor.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/fonts/add.d.ts +41 -0
- package/dist/fonts/add.d.ts.map +1 -0
- package/dist/fonts/add.js +259 -0
- package/dist/fonts/add.js.map +1 -0
- package/dist/fonts/binary.d.ts +4 -0
- package/dist/fonts/binary.d.ts.map +1 -0
- package/dist/fonts/binary.js +21 -0
- package/dist/fonts/binary.js.map +1 -0
- package/dist/fonts/css.d.ts +4 -0
- package/dist/fonts/css.d.ts.map +1 -0
- package/dist/fonts/css.js +50 -0
- package/dist/fonts/css.js.map +1 -0
- package/dist/fonts/fontsource.d.ts +107 -0
- package/dist/fonts/fontsource.d.ts.map +1 -0
- package/dist/fonts/fontsource.js +565 -0
- package/dist/fonts/fontsource.js.map +1 -0
- package/dist/fonts/index.d.ts +11 -0
- package/dist/fonts/index.d.ts.map +1 -0
- package/dist/fonts/index.js +11 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/fonts/install.d.ts +24 -0
- package/dist/fonts/install.d.ts.map +1 -0
- package/dist/fonts/install.js +145 -0
- package/dist/fonts/install.js.map +1 -0
- package/dist/fonts/manifest.d.ts +21 -0
- package/dist/fonts/manifest.d.ts.map +1 -0
- package/dist/fonts/manifest.js +96 -0
- package/dist/fonts/manifest.js.map +1 -0
- package/dist/fonts/options.d.ts +9 -0
- package/dist/fonts/options.d.ts.map +1 -0
- package/dist/fonts/options.js +66 -0
- package/dist/fonts/options.js.map +1 -0
- package/dist/fonts/schema.d.ts +4 -0
- package/dist/fonts/schema.d.ts.map +1 -0
- package/dist/fonts/schema.js +316 -0
- package/dist/fonts/schema.js.map +1 -0
- package/dist/fonts/summary.d.ts +16 -0
- package/dist/fonts/summary.d.ts.map +1 -0
- package/dist/fonts/summary.js +22 -0
- package/dist/fonts/summary.js.map +1 -0
- package/dist/fonts/types.d.ts +56 -0
- package/dist/fonts/types.d.ts.map +1 -0
- package/dist/fonts/types.js +8 -0
- package/dist/fonts/types.js.map +1 -0
- package/dist/fonts/verify.d.ts +33 -0
- package/dist/fonts/verify.d.ts.map +1 -0
- package/dist/fonts/verify.js +200 -0
- package/dist/fonts/verify.js.map +1 -0
- package/dist/html/validate.d.ts.map +1 -1
- package/dist/html/validate.js +59 -0
- package/dist/html/validate.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +61 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +325 -0
- package/dist/inspect.js.map +1 -0
- package/dist/lint.d.ts +63 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +265 -0
- package/dist/lint.js.map +1 -0
- package/dist/policy.d.ts +69 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +361 -0
- package/dist/policy.js.map +1 -0
- package/dist/preview/fonts/LICENSE-figtree.txt +93 -0
- package/dist/preview/fonts/LICENSE-space-mono.txt +93 -0
- package/dist/preview/fonts/README.md +23 -0
- package/dist/preview/fonts/figtree-latin-wght-normal.woff2 +0 -0
- package/dist/preview/fonts/space-mono-latin-400-normal.woff2 +0 -0
- package/dist/preview/fonts/space-mono-latin-700-normal.woff2 +0 -0
- package/dist/preview/main.js +5 -2
- package/dist/preview/main.js.map +1 -1
- package/dist/preview/timeline-data.d.ts +17 -69
- package/dist/preview/timeline-data.d.ts.map +1 -1
- package/dist/preview/timeline-host.d.ts.map +1 -1
- package/dist/preview/timeline-host.js +70 -45
- package/dist/preview/timeline-host.js.map +1 -1
- package/dist/preview/timeline-main.d.ts.map +1 -1
- package/dist/preview/timeline-main.js +88 -27
- package/dist/preview/timeline-main.js.map +1 -1
- package/dist/project.d.ts +10 -3
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +20 -17
- package/dist/project.js.map +1 -1
- package/dist/renderer/audio.d.ts +6 -0
- package/dist/renderer/audio.d.ts.map +1 -1
- package/dist/renderer/audio.js +3 -1
- package/dist/renderer/audio.js.map +1 -1
- package/dist/renderer/browser.d.ts.map +1 -1
- package/dist/renderer/browser.js +13 -0
- package/dist/renderer/browser.js.map +1 -1
- package/dist/renderer/concurrency.d.ts +6 -0
- package/dist/renderer/concurrency.d.ts.map +1 -0
- package/dist/renderer/concurrency.js +27 -0
- package/dist/renderer/concurrency.js.map +1 -0
- package/dist/renderer/ffmpeg.d.ts +104 -5
- package/dist/renderer/ffmpeg.d.ts.map +1 -1
- package/dist/renderer/ffmpeg.js +580 -67
- package/dist/renderer/ffmpeg.js.map +1 -1
- package/dist/renderer/index.js +1 -1
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/keyframe-expressions.d.ts +39 -0
- package/dist/renderer/keyframe-expressions.d.ts.map +1 -0
- package/dist/renderer/keyframe-expressions.js +180 -0
- package/dist/renderer/keyframe-expressions.js.map +1 -0
- package/dist/renderer/session-pool.d.ts +28 -0
- package/dist/renderer/session-pool.d.ts.map +1 -0
- package/dist/renderer/session-pool.js +91 -0
- package/dist/renderer/session-pool.js.map +1 -0
- package/dist/renderer/timeline.d.ts +2 -0
- package/dist/renderer/timeline.d.ts.map +1 -1
- package/dist/renderer/timeline.js +600 -147
- package/dist/renderer/timeline.js.map +1 -1
- package/dist/renderer/timings.d.ts +13 -0
- package/dist/renderer/timings.d.ts.map +1 -0
- package/dist/renderer/timings.js +29 -0
- package/dist/renderer/timings.js.map +1 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/host.js +4 -0
- package/dist/runtime/host.js.map +1 -1
- package/dist/scaffold.d.ts +3 -0
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +48 -320
- package/dist/scaffold.js.map +1 -1
- package/dist/server/composition-html.d.ts +2 -0
- package/dist/server/composition-html.d.ts.map +1 -1
- package/dist/server/composition-html.js +7 -0
- package/dist/server/composition-html.js.map +1 -1
- package/dist/server/preview-html.d.ts.map +1 -1
- package/dist/server/preview-html.js +74 -188
- package/dist/server/preview-html.js.map +1 -1
- package/dist/server/preview-style.d.ts +11 -0
- package/dist/server/preview-style.d.ts.map +1 -0
- package/dist/server/preview-style.js +298 -0
- package/dist/server/preview-style.js.map +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +31 -1
- package/dist/server/server.js.map +1 -1
- package/dist/server/timeline-preview-data.d.ts.map +1 -1
- package/dist/server/timeline-preview-data.js +12 -34
- package/dist/server/timeline-preview-data.js.map +1 -1
- package/dist/server/timeline-preview-html.d.ts.map +1 -1
- package/dist/server/timeline-preview-html.js +140 -148
- package/dist/server/timeline-preview-html.js.map +1 -1
- package/dist/templates.d.ts +16 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +186 -0
- package/dist/templates.js.map +1 -0
- package/dist/timeline/easing.d.ts +36 -0
- package/dist/timeline/easing.d.ts.map +1 -0
- package/dist/timeline/easing.js +225 -0
- package/dist/timeline/easing.js.map +1 -0
- package/dist/timeline/keyframes.d.ts +23 -0
- package/dist/timeline/keyframes.d.ts.map +1 -0
- package/dist/timeline/keyframes.js +95 -0
- package/dist/timeline/keyframes.js.map +1 -0
- package/dist/timeline/plan.d.ts +6 -12
- package/dist/timeline/plan.d.ts.map +1 -1
- package/dist/timeline/plan.js +17 -30
- package/dist/timeline/plan.js.map +1 -1
- package/dist/timeline/resolve.d.ts +12 -0
- package/dist/timeline/resolve.d.ts.map +1 -1
- package/dist/timeline/resolve.js +105 -9
- package/dist/timeline/resolve.js.map +1 -1
- package/dist/timeline/scene.d.ts +126 -0
- package/dist/timeline/scene.d.ts.map +1 -0
- package/dist/timeline/scene.js +109 -0
- package/dist/timeline/scene.js.map +1 -0
- package/dist/timeline/schema.d.ts +31 -0
- package/dist/timeline/schema.d.ts.map +1 -1
- package/dist/timeline/schema.js +240 -9
- package/dist/timeline/schema.js.map +1 -1
- package/dist/timeline/transitions.d.ts +21 -0
- package/dist/timeline/transitions.d.ts.map +1 -0
- package/dist/timeline/transitions.js +23 -0
- package/dist/timeline/transitions.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/adr/0007-make-html-documents-the-composition-unit.md +1 -1
- package/docs/adr/0010-make-timelines-the-render-unit.md +3 -2
- package/docs/adr/0012-render-timelines-with-segmented-lossless-clip-intermediates.md +1 -1
- package/docs/adr/0014-compose-timeline-clips-with-css-blend-modes.md +2 -1
- package/docs/adr/0015-inherit-composition-format-from-the-project.md +2 -2
- package/docs/adr/0016-author-compositions-as-html-fragments.md +1 -1
- package/docs/adr/0018-animate-timeline-clips-with-keyframes.md +35 -0
- package/docs/adr/0019-make-same-track-overlap-the-transition-window.md +36 -0
- package/docs/adr/0020-crossfade-audio-clips-on-audio-tracks.md +27 -0
- package/docs/adr/0021-project-timeline-scenes-once.md +32 -0
- package/docs/adr/0022-gate-heavy-operations-with-a-workspace-resource-policy.md +35 -0
- package/docs/adr/0023-pin-fonts-as-project-assets.md +98 -0
- package/docs/adr/0024-stream-composition-captures-and-skip-trivial-composites.md +86 -0
- package/docs/adr/0025-capture-timeline-layers-in-parallel-with-a-global-limit.md +67 -0
- package/docs/adr/0026-reuse-loaded-composition-sessions-across-segments.md +70 -0
- package/docs/adr/0027-encode-two-full-frame-layers-through-dual-pipes.md +76 -0
- package/docs/adr/0028-encode-full-frame-video-segments-directly.md +65 -0
- package/docs/migration-0.4.md +2 -2
- package/docs/preview-testing.md +27 -6
- package/docs/{v0.1-design.md → v0.x-design.md} +57 -32
- package/examples/blend/README.md +3 -3
- package/examples/demo/README.md +2 -2
- package/examples/intro/README.md +71 -0
- package/examples/intro/assets/fonts/figtree/LICENSE.txt +93 -0
- package/examples/intro/assets/fonts/figtree/figtree-latin-wght-normal.woff2 +0 -0
- package/examples/intro/assets/fonts/instrument-serif/LICENSE.txt +93 -0
- package/examples/intro/assets/fonts/instrument-serif/instrument-serif-latin-400-italic.woff2 +0 -0
- package/examples/intro/assets/fonts/space-mono/LICENSE.txt +93 -0
- package/examples/intro/assets/fonts/space-mono/space-mono-latin-400-normal.woff2 +0 -0
- package/examples/intro/assets/fonts/space-mono/space-mono-latin-700-normal.woff2 +0 -0
- package/examples/intro/assets/grain.png +0 -0
- package/examples/intro/assets/score.ogg +0 -0
- package/examples/intro/compositions/brand.html +412 -0
- package/examples/intro/compositions/chrome.controller.js +63 -0
- package/examples/intro/compositions/chrome.html +256 -0
- package/examples/intro/compositions/lattice.controller.js +148 -0
- package/examples/intro/compositions/lattice.html +308 -0
- package/examples/intro/compositions/opening.html +504 -0
- package/examples/intro/compositions/studio.html +930 -0
- package/examples/intro/compositions/theme.css +218 -0
- package/examples/intro/fy.config.js +13 -0
- package/examples/intro/fy.fonts.json +100 -0
- package/examples/intro/scripts/make-grain.mjs +79 -0
- package/examples/intro/scripts/make-score.mjs +702 -0
- package/examples/intro/timelines/intro.timeline.json +60 -0
- package/examples/keyframes/README.md +76 -0
- package/examples/keyframes/compositions/backdrop.html +60 -0
- package/examples/keyframes/compositions/card.html +99 -0
- package/examples/keyframes/fy.config.js +10 -0
- package/examples/keyframes/timelines/keyframes.timeline.json +60 -0
- package/examples/nested/README.md +112 -0
- package/examples/nested/assets/pulse.wav +0 -0
- package/examples/nested/compositions/backdrop.html +84 -0
- package/examples/nested/compositions/card.html +275 -0
- package/examples/nested/compositions/overlay.html +307 -0
- package/examples/nested/fy.config.js +13 -0
- package/examples/nested/scripts/make-pulse.sh +20 -0
- package/examples/nested/timelines/chapter-a.timeline.json +39 -0
- package/examples/nested/timelines/chapter-b.timeline.json +39 -0
- package/examples/nested/timelines/nested-reel.timeline.json +52 -0
- package/examples/static/README.md +2 -2
- package/examples/transitions/README.md +128 -0
- package/examples/transitions/assets/alpha.wav +0 -0
- package/examples/transitions/assets/beta.wav +0 -0
- package/examples/transitions/assets/gamma.wav +0 -0
- package/examples/transitions/compositions/alpha.html +56 -0
- package/examples/transitions/compositions/beta.html +56 -0
- package/examples/transitions/compositions/gamma.html +56 -0
- package/examples/transitions/fy.config.js +12 -0
- package/examples/transitions/timelines/audio-crossfade.timeline.json +44 -0
- package/examples/transitions/timelines/transitions.timeline.json +31 -0
- package/examples/video/README.md +4 -4
- package/examples/webgl/README.md +1 -1
- package/package.json +13 -6
- package/scaffolds/init/AGENTS.md +131 -0
- package/scaffolds/init/README.md +56 -0
- package/scaffolds/init/compositions/hello.html +79 -0
- package/scaffolds/init/fy.config.js +9 -0
- package/scaffolds/init/gitignore.template +1 -0
- package/scaffolds/init/package.json +11 -0
- package/scaffolds/init/props/hello.json +4 -0
- package/scaffolds/init/props/main.json +6 -0
- package/scaffolds/init/timelines/main.timeline.json +20 -0
- package/scaffolds/local-models/LOCAL-MODELS.md +77 -0
- package/scaffolds/local-models/fy.policy.json +5 -0
- package/scaffolds/local-models/opencode/opencode.jsonc +17 -0
- package/scaffolds/local-models/pi/APPEND_SYSTEM.md +21 -0
- package/scaffolds/local-models/pi/sandbox.json +15 -0
- package/scaffolds/local-models/pi/settings.json +15 -0
- package/skills/frameyard/README.md +1 -0
- package/skills/frameyard/SKILL.md +59 -61
- package/skills/frameyard/references/audio-assets.md +32 -3
- package/skills/frameyard/references/common-mistakes.md +53 -2
- package/skills/frameyard/references/deterministic-authoring.md +10 -3
- package/skills/frameyard/references/diagnostics.md +31 -1
- package/skills/frameyard/references/failure-recovery.md +32 -6
- package/skills/frameyard/references/fonts.md +132 -0
- package/skills/frameyard/references/json-results.md +119 -6
- package/skills/frameyard/references/quick-reference.md +222 -0
- package/skills/frameyard/references/timelines.md +97 -7
- /package/examples/blend/{video.config.js → fy.config.js} +0 -0
- /package/examples/demo/{video.config.js → fy.config.js} +0 -0
- /package/examples/static/{video.config.js → fy.config.js} +0 -0
- /package/examples/video/{video.config.js → fy.config.js} +0 -0
- /package/examples/webgl/{video.config.js → fy.config.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,180 @@ Frameyard uses `0.x` versions until the composition, configuration, CLI,
|
|
|
8
8
|
JSON-result, transcript, and skill contracts stabilize. Before `1.0.0`, a
|
|
9
9
|
contract change may ship in a minor release and is called out explicitly below.
|
|
10
10
|
|
|
11
|
+
## [Unreleased]
|
|
12
|
+
|
|
13
|
+
## [0.10.0] - 2026-11-07
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `FRAMEYARD_TIMINGS=1` emits one JSON line per render stage to stderr without
|
|
18
|
+
changing the `--json` result on stdout. `bench/summarize-timings.mjs`
|
|
19
|
+
aggregates session, capture, PNG-write, FFV1, composite, concat, audio, and
|
|
20
|
+
publish timings for production-path profiling,
|
|
21
|
+
`bench/timeline-60min-gate.mjs` generates the 60-minute composition-only
|
|
22
|
+
production gate, and `bench/timeline-60min-representative.mjs` generates the
|
|
23
|
+
representative 60-minute 50/50 gate. The representative gate rendered 108,000
|
|
24
|
+
frames in 16.82 minutes with eight workers, clean scratch, and video
|
|
25
|
+
re-encoded rather than stream-copied. `FRAMEYARD_FFV1_THREADS` bounds the streaming FFV1 encoder.
|
|
26
|
+
- Composition clips now stream captured PNGs directly into FFV1 instead of
|
|
27
|
+
writing a PNG sequence to scratch first. A segment with one full-frame,
|
|
28
|
+
untransformed composition skips the FFV1 intermediate and the FFmpeg
|
|
29
|
+
composite, encoding the capture directly to the delivery segment over the
|
|
30
|
+
timeline background. See
|
|
31
|
+
`docs/adr/0024-stream-composition-captures-and-skip-trivial-composites.md`.
|
|
32
|
+
- Independent layer captures run concurrently under a FIFO semaphore, bounded
|
|
33
|
+
by `FRAMEYARD_CAPTURE_CONCURRENCY` or `min(workers * 2, 12)` by default. The
|
|
34
|
+
two-layer 60-second gate fell from 59.60 s to 43.78 s. See
|
|
35
|
+
`docs/adr/0025-capture-timeline-layers-in-parallel-with-a-global-limit.md`.
|
|
36
|
+
- The timeline renderer reuses loaded composition sessions across segments,
|
|
37
|
+
keyed by entry, props, and transparency, with a bounded idle pool. The
|
|
38
|
+
10-minute one-layer gate fell from 211.8 s to 192.6 s, and the 60-minute gate
|
|
39
|
+
fell from 19.83 to 18.78 minutes with eight sessions instead of 360. See
|
|
40
|
+
`docs/adr/0026-reuse-loaded-composition-sessions-across-segments.md`.
|
|
41
|
+
- A full-frame composition base and a static composition overlay (including a
|
|
42
|
+
static PIP box) encode through dual image pipes into one delivery segment,
|
|
43
|
+
skipping FFV1 and the separate composite. The full-frame two-layer 60-second
|
|
44
|
+
workload fell from 53.27 s to 34.62 s with byte-identical output, the PIP
|
|
45
|
+
60-second workload from 43.78 s to 33.90 s with pixel-identical frames, and
|
|
46
|
+
the full two-layer 60-minute gates completed in 29.69 minutes (full-frame) and
|
|
47
|
+
25.75 minutes (PIP) with eight workers. Windows keeps the segmented fallback. See
|
|
48
|
+
`docs/adr/0027-encode-two-full-frame-layers-through-dual-pipes.md`.
|
|
49
|
+
- A single full-frame video with an identity transform re-encodes its source
|
|
50
|
+
range directly into the delivery segment, skipping the composite filter
|
|
51
|
+
graph while keeping the normal encoder settings and the RGBA color round trip
|
|
52
|
+
for pixel parity. A 60-second video-only gate fell from 10.65 s to 7.61 s
|
|
53
|
+
with identical decoded frames, and the representative 60-minute 50/50 gate
|
|
54
|
+
fell from 16.82 to 15.57 minutes with a byte-identical file. See
|
|
55
|
+
`docs/adr/0028-encode-full-frame-video-segments-directly.md`.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- The composition and timeline preview pages share one visual language:
|
|
60
|
+
ink-black surfaces, paper-white type, a single lime signal, monospace
|
|
61
|
+
instrument labels, and a tick-marked progress rail. The timeline strip adds a
|
|
62
|
+
frame ruler that tracks the playhead. The chrome bundles its own Figtree and
|
|
63
|
+
Space Mono faces and no longer links the project font sheet; project fonts
|
|
64
|
+
still apply inside compositions. See `src/server/preview-style.ts` and
|
|
65
|
+
`src/preview/fonts/`.
|
|
66
|
+
|
|
67
|
+
### Fixed
|
|
68
|
+
|
|
69
|
+
- Timeline preview plays composition audio once instead of restarting it when
|
|
70
|
+
the mapped clip window is longer than the source file. An embedded `<audio>`
|
|
71
|
+
without `data-fy-duration` now stops at the end of the source instead of
|
|
72
|
+
looping for the rest of the composition clip.
|
|
73
|
+
- Timeline inspection no longer reports an overrun when a composition's
|
|
74
|
+
natural-duration audio ends before its mapped clip window. The clip is still
|
|
75
|
+
mixed and padded with silence, while explicit trim ranges beyond the source
|
|
76
|
+
keep warning.
|
|
77
|
+
|
|
78
|
+
[0.10.0]: https://github.com/vladiantio/frameyard/compare/v0.9.0...v0.10.0
|
|
79
|
+
|
|
80
|
+
## [0.9.0] - 2026-11-06
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
|
|
84
|
+
- `fy.fonts.json` records vendored font families, files, licenses, and
|
|
85
|
+
SHA-256 values. `frameyard font search` filters the Fontsource catalog, and
|
|
86
|
+
`font add <id>` pins a Fontsource `npmVersion`, vendors its WOFF2 files and
|
|
87
|
+
license, and supports variable `wght` or explicit static weights. `font add
|
|
88
|
+
--file` copies a local WOFF2/WOFF/TTF/OTF font, `font add --url` vendors an
|
|
89
|
+
HTTPS source with an optional SHA-256, and `font list`/`verify`/`remove`
|
|
90
|
+
manage the manifest. The server injects the generated `@font-face` sheet into
|
|
91
|
+
every composition, the host fails with `FONT_LOAD_FAILED` when a used face
|
|
92
|
+
does not load, and static validation warns with `FONT_REMOTE` for remote font
|
|
93
|
+
URLs. See
|
|
94
|
+
`docs/adr/0023-pin-fonts-as-project-assets.md`.
|
|
95
|
+
- `fy.policy.json` is a workspace resource policy discovered from the
|
|
96
|
+
working directory upward. It gates `tts`, `transcribe`, and `render`, caps
|
|
97
|
+
`still`, denies `--force`/`--overwrite`, and supports the `shared-cpu`
|
|
98
|
+
profile. `FRAMEYARD_POLICY` overrides the file. See
|
|
99
|
+
`docs/adr/0022-gate-heavy-operations-with-a-workspace-resource-policy.md`.
|
|
100
|
+
- `frameyard lint <id>` runs static validation, timeline resolution, scene and
|
|
101
|
+
keyframe projection for every frame, a controller determinism scan, and media
|
|
102
|
+
metadata probing without Chromium. It is the edit-loop gate; `check` remains
|
|
103
|
+
the full gate.
|
|
104
|
+
- `frameyard context --json` prints a compact project digest with resolved
|
|
105
|
+
composition metadata, prop keys and types, timeline clip summaries, unique
|
|
106
|
+
assets, diagnostics, the active policy, and next commands.
|
|
107
|
+
- `frameyard inspect <image> --json` reports dimensions, alpha coverage, blank
|
|
108
|
+
detection, background and dominant colors, a content bounding box, a coarse
|
|
109
|
+
luminance grid, and edge density. `frameyard compare <a> <b> --json` reports
|
|
110
|
+
pixel and 3×3 region differences and exits 1 when the images differ.
|
|
111
|
+
- `frameyard add --list` and `frameyard add <composition|timeline> <id>
|
|
112
|
+
--template <name>` write `static-poster`, `title-card`, `lower-third`, or
|
|
113
|
+
`slideshow` entries and print the exact `fy.config.js` registration
|
|
114
|
+
snippet. `add local-models` and `init --local-models` install the optional
|
|
115
|
+
policy, OpenCode permissions, and Pi settings. `add` never edits the config
|
|
116
|
+
and never overwrites an existing entry. The skill adds a compact quick
|
|
117
|
+
reference for limited-context hosts.
|
|
118
|
+
- `init` templates now live under `scaffolds/init/`; `src/scaffold.ts` reads
|
|
119
|
+
them and renders the project-name and version placeholders.
|
|
120
|
+
- `pnpm eval:local` runs an opt-in local-model authoring eval against a
|
|
121
|
+
llama.cpp router. It covers eight tasks, feeds `quick-reference.md` into the
|
|
122
|
+
system prompt, repairs lint failures, and reports first-pass status, turns,
|
|
123
|
+
tokens, wall time, sampled server CPU/RSS/GPU, and optional budgets. It never
|
|
124
|
+
renders and stays outside `pnpm check`.
|
|
125
|
+
- `tts`, `transcribe`, and `render` accept `--dry-run`, which validates inputs
|
|
126
|
+
and returns `plan`, `commandLine`, `prerequisites`, and `blockers` without
|
|
127
|
+
writing outputs, loading a model, launching Chromium, or encoding.
|
|
128
|
+
`--profile shared-cpu` caps timeline workers at 2 and composition concurrency
|
|
129
|
+
at 1; `--low-priority` lowers process priority without the caps.
|
|
130
|
+
- `doctor` reports the active resource policy and basic CPU, load, and memory
|
|
131
|
+
resources. Local-model host setup is opt-in through
|
|
132
|
+
`scaffolds/local-models/`, which contains the `authoring` policy, OpenCode
|
|
133
|
+
permissions, and Pi settings; the repository does not enable it by default.
|
|
134
|
+
- `tts --engine supertonic` synthesizes 31-language speech through
|
|
135
|
+
`sherpa-onnx-offline-tts` and the Supertonic 3 model archive. It normalizes
|
|
136
|
+
the engine output to the frozen 24 kHz mono WAV contract, records the seven
|
|
137
|
+
model files in the provenance manifest, and adds `doctor --sherpa-onnx-tts`
|
|
138
|
+
and `doctor --model-dir` inspection. The default engine remains `qwen`.
|
|
139
|
+
- Timeline clips on one video track may dissolve across their overlap through a
|
|
140
|
+
timeline-level `transitions` array. The window is `to.start .. from.end`; the
|
|
141
|
+
incoming clip composites above the outgoing clip with `opacity × eased
|
|
142
|
+
progress`, contributed audio crossfades with equal power, and preview draws a
|
|
143
|
+
read-only band. Undeclared overlap stays an error. See
|
|
144
|
+
`docs/adr/0019-make-same-track-overlap-the-transition-window.md` and
|
|
145
|
+
`examples/transitions/`.
|
|
146
|
+
- Audio clips on an audio track may crossfade through the same `transitions`
|
|
147
|
+
array with `kind: "crossfade"`. The kind/track matrix is explicit: `dissolve`
|
|
148
|
+
is video-only, `crossfade` is audio-only. See
|
|
149
|
+
`docs/adr/0020-crossfade-audio-clips-on-audio-tracks.md` and the
|
|
150
|
+
`audio-crossfade` timeline in `examples/transitions/`.
|
|
151
|
+
- Timeline clips animate `x`, `y`, `scale`, `rotation`, and `opacity` with
|
|
152
|
+
clip-local `keyframes`, CSS easing, preview markers, and FFmpeg expressions.
|
|
153
|
+
Animated opacity composes through blend modes. See
|
|
154
|
+
`docs/adr/0018-animate-timeline-clips-with-keyframes.md` and
|
|
155
|
+
`examples/keyframes/`.
|
|
156
|
+
|
|
157
|
+
### Changed
|
|
158
|
+
|
|
159
|
+
- `frameyard init` without a directory prompts for a project name (default
|
|
160
|
+
`my-video`) on an interactive terminal and creates a directory with that
|
|
161
|
+
name. Non-interactive and `--json` runs use `my-video` without prompting.
|
|
162
|
+
Pass a directory to scaffold into an explicit path or the current directory.
|
|
163
|
+
- The project configuration file is `fy.config.js` (previously
|
|
164
|
+
`video.config.js`), the assets manifest is `fy.assets.json` (previously
|
|
165
|
+
`frameyard.assets.json`), and the workspace resource policy is
|
|
166
|
+
`fy.policy.json` (previously `frameyard.policy.json`). Rename existing files
|
|
167
|
+
in place; the loaders read only the new names. `FRAMEYARD_POLICY` keeps
|
|
168
|
+
its name.
|
|
169
|
+
|
|
170
|
+
### Fixed
|
|
171
|
+
|
|
172
|
+
- Timeline preview layers pin `color-scheme: light` on the embedded document
|
|
173
|
+
root. A composition that declared a dark scheme could paint an opaque canvas
|
|
174
|
+
base and hide every layer beneath it, so a timeline with a transparent
|
|
175
|
+
overlay composition appeared to show only the overlay.
|
|
176
|
+
- Rotated timeline clips keep their full corners. Keyed rotation uses a
|
|
177
|
+
segment-stable diagonal bound; static rotation uses its exact rotated
|
|
178
|
+
bounding box.
|
|
179
|
+
- Animated-opacity masks use a 2×2 FFmpeg source instead of 1×1. FFmpeg 6
|
|
180
|
+
rejects a 1×1 `yuv420p` frame, which broke keyframe, transition, and example
|
|
181
|
+
renders on Ubuntu 24.04 runners.
|
|
182
|
+
|
|
183
|
+
[0.9.0]: https://github.com/vladiantio/frameyard/compare/v0.8.0...v0.9.0
|
|
184
|
+
|
|
11
185
|
## [0.8.0] - 2026-11-03
|
|
12
186
|
|
|
13
187
|
### Changed
|
|
@@ -61,12 +235,9 @@ contract change may ship in a minor release and is called out explicitly below.
|
|
|
61
235
|
applies `mix-blend-mode` and stacks layers by track; production uses an
|
|
62
236
|
alpha-aware FFmpeg composite. Nested timelines blend as flattened groups.
|
|
63
237
|
See ADR 0014 and `examples/blend/`.
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
composition format.
|
|
68
|
-
- Static composition validation, host, CLI, timeline, preview, and example
|
|
69
|
-
coverage.
|
|
238
|
+
- Static composition validation, host, CLI, timeline, and preview coverage.
|
|
239
|
+
|
|
240
|
+
[0.8.0]: https://github.com/vladiantio/frameyard/compare/v0.7.0...v0.8.0
|
|
70
241
|
|
|
71
242
|
## [0.7.0] - 2026-11-02
|
|
72
243
|
|
|
@@ -111,7 +282,6 @@ contract change may ship in a minor release and is called out explicitly below.
|
|
|
111
282
|
layer iframes reach the preview transport, while text entry does not step
|
|
112
283
|
frames across iframe boundaries.
|
|
113
284
|
|
|
114
|
-
[0.8.0]: https://github.com/vladiantio/frameyard/compare/v0.7.0...v0.8.0
|
|
115
285
|
[0.7.0]: https://github.com/vladiantio/frameyard/compare/v0.6.0...v0.7.0
|
|
116
286
|
|
|
117
287
|
## [0.6.0] - 2026-11-01
|
|
@@ -142,8 +312,6 @@ contract change may ship in a minor release and is called out explicitly below.
|
|
|
142
312
|
`timelines` map. `project.json` publishes `format` and `timelines`.
|
|
143
313
|
- Timeline-first `init` scaffold with a composition clip, timeline override
|
|
144
314
|
props, and `main` commands.
|
|
145
|
-
- The video example adds WebM and MP4 timelines that place video clips under a
|
|
146
|
-
transparent HTML overlay.
|
|
147
315
|
- Official skill reference for timelines, clips, tracks, nested timelines,
|
|
148
316
|
props overrides, commands, preview, and determinism.
|
|
149
317
|
- Timeline config, schema, resolution, planning, rendering, preview, and
|
|
@@ -173,11 +341,6 @@ contract change may ship in a minor release and is called out explicitly below.
|
|
|
173
341
|
|
|
174
342
|
### Added
|
|
175
343
|
|
|
176
|
-
- `examples/webgl/` demonstrates a frame-seeked WebGL shader driven by an
|
|
177
|
-
external controller.
|
|
178
|
-
- `examples/video/` demonstrates two-pass embedded video with the same
|
|
179
|
-
composition rendered from WebM and MP4 sources, plus a script that
|
|
180
|
-
regenerates both clips with FFmpeg.
|
|
181
344
|
- `test/examples.test.ts` captures a still from every bundled example.
|
|
182
345
|
- `pnpm compare-stills <a.png> <b.png>` reports an exact decoded-pixel diff and
|
|
183
346
|
exits nonzero on any difference, for checking determinism at the capture
|
package/GLOSSARY.md
CHANGED
|
@@ -151,17 +151,79 @@ How a clip source's natural frame is fitted into the project frame or an explici
|
|
|
151
151
|
_Avoid_: Resize mode, object-fit
|
|
152
152
|
|
|
153
153
|
**Clip transform**:
|
|
154
|
-
The
|
|
154
|
+
The size, position, rotation, and opacity applied to a visual clip. Size is either an explicit `width`/`height` box or a `scale` multiplier. Static transform values and keyframe tracks are separate; a keyed channel cannot also be a static scalar.
|
|
155
155
|
_Avoid_: Effect, animation
|
|
156
156
|
|
|
157
|
+
**Clip keyframes**:
|
|
158
|
+
A per-channel animation on a visual clip's presentation: `x`, `y`, `scale`, `rotation`, or `opacity`. Keys use clip-local integer frames and hold before the first and after the last key.
|
|
159
|
+
_Avoid_: CSS keyframes, composition animation
|
|
160
|
+
|
|
161
|
+
**Keyframe**:
|
|
162
|
+
One `{ frame, value, easing? }` entry in a clip keyframe track. `frame` is clip-local; `easing` applies to the interval after it.
|
|
163
|
+
_Avoid_: Marker, cue
|
|
164
|
+
|
|
165
|
+
**Keyframe track**:
|
|
166
|
+
The ordered keyframes for one presentation channel. Keys are strictly increasing and stay within the clip's `0..duration` range.
|
|
167
|
+
_Avoid_: Animation curve, property lane
|
|
168
|
+
|
|
169
|
+
**Easing**:
|
|
170
|
+
A CSS timing function that shapes the interval between two timeline keyframes. Preview evaluates it exactly; production approximates it in the FFmpeg filter graph.
|
|
171
|
+
_Avoid_: Interpolation, curve
|
|
172
|
+
|
|
157
173
|
**Blend mode**:
|
|
158
174
|
The static CSS `mix-blend-mode` a visual clip applies against the accumulated backdrop of all lower layers and the timeline background. It respects the clip's source alpha and is not animated.
|
|
159
175
|
_Avoid_: Filter, effect, composite mode
|
|
160
176
|
|
|
177
|
+
**Transition**:
|
|
178
|
+
A declared handoff between two clips on one track, written as `{ from, to, kind, easing? }` in the timeline's `transitions` array. `dissolve` is a visual fade on a video track; `crossfade` is an audio gain ramp on an audio track. The clips overlap; an overlap without a declared transition is still an error.
|
|
179
|
+
_Avoid_: Overlap
|
|
180
|
+
|
|
181
|
+
**Crossfade**:
|
|
182
|
+
The audio-track transition kind. It ramps the outgoing audio clip down and the incoming clip up with equal power and changes no pixels.
|
|
183
|
+
_Avoid_: Dissolve, fade
|
|
184
|
+
|
|
185
|
+
**Transition window**:
|
|
186
|
+
The overlap `to.start .. from.end` where both clips are active. During a dissolve the incoming clip composites above the outgoing clip with `opacity × eased progress`, evaluated at absolute timeline frames.
|
|
187
|
+
_Avoid_: Handle, overlap region
|
|
188
|
+
|
|
189
|
+
**Transition role**:
|
|
190
|
+
The side a clip takes in a transition: `out` for the clip being replaced, `in` for the clip replacing it.
|
|
191
|
+
_Avoid_: Transition direction, fade side
|
|
192
|
+
|
|
193
|
+
**Equal-power crossfade**:
|
|
194
|
+
The audio gain curve inside either transition kind: the outgoing clip ramps as `sqrt(1 - t)` and the incoming clip as `sqrt(t)` after easing, keeping perceived loudness steady.
|
|
195
|
+
_Avoid_: Linear fade
|
|
196
|
+
|
|
161
197
|
**Nested timeline**:
|
|
162
198
|
A timeline used as a clip source inside another timeline.
|
|
163
199
|
_Avoid_: Compound composition
|
|
164
200
|
|
|
201
|
+
### Fonts
|
|
202
|
+
|
|
203
|
+
**Font manifest**:
|
|
204
|
+
The versioned `fy.fonts.json` file that records vendored font families, their CSS family names, providers, licenses, and file hashes. It is the source of truth for the generated `@font-face` sheet.
|
|
205
|
+
_Avoid_: Font config, font cache
|
|
206
|
+
|
|
207
|
+
**Font provider**:
|
|
208
|
+
The acquisition source recorded for a font family: `local` for a user-supplied file, `fontsource` for a pinned Fontsource download, or `url` for an explicit HTTPS source.
|
|
209
|
+
_Avoid_: Font catalog, font CDN
|
|
210
|
+
|
|
211
|
+
**Font family entry**:
|
|
212
|
+
One manifest entry keyed by a stable id. It contains the CSS family name, provider metadata, license, optional variable axes, and one or more font files.
|
|
213
|
+
_Avoid_: Font face, font package
|
|
214
|
+
|
|
215
|
+
**Font face**:
|
|
216
|
+
One file entry inside a family: a subset, style, weight or weight range, format, optional unicode range, SHA-256, and byte size.
|
|
217
|
+
_Avoid_: Font variant, font weight
|
|
218
|
+
|
|
219
|
+
**Font subset**:
|
|
220
|
+
A provider-defined slice of a family's glyph coverage, such as `latin` or `latin-ext`. Subsets are recorded per face and may carry a CSS `unicode-range`.
|
|
221
|
+
_Avoid_: Language, charset
|
|
222
|
+
|
|
223
|
+
**Variable font**:
|
|
224
|
+
A font file that carries a continuous range for one or more axes instead of separate static weights. Frameyard records the axes and emits a CSS weight range; the first version installs the `wght` axis only.
|
|
225
|
+
_Avoid_: Dynamic font, multiple weight font
|
|
226
|
+
|
|
165
227
|
### Deterministic execution
|
|
166
228
|
|
|
167
229
|
**Frame**:
|
|
@@ -172,6 +234,10 @@ _Avoid_: Timestamp, animation tick
|
|
|
172
234
|
A clip whose timeline range contains the current timeline frame.
|
|
173
235
|
_Avoid_: Visible clip
|
|
174
236
|
|
|
237
|
+
**Timeline scene**:
|
|
238
|
+
The ordered active clips and their presentation at one timeline frame or over one render range, including transition roles and composite order. It is the timeline-level arrangement, not a composition.
|
|
239
|
+
_Avoid_: Timeline composition, frame snapshot
|
|
240
|
+
|
|
175
241
|
**Clip capture**:
|
|
176
242
|
The pixel frames a composition produces for a timeline clip before the timeline compositor combines layers.
|
|
177
243
|
_Avoid_: Screenshot, render
|
|
@@ -312,6 +378,46 @@ _Avoid_: Frame export, image sequence
|
|
|
312
378
|
The guarantee that, for the same timeline or composition revision, props, assets, and frame under a pinned runtime/browser environment, the visual state is identical. It does not imply identical encoded bytes, even on the same machine; encoded output depends on the encoder and its runtime.
|
|
313
379
|
_Avoid_: Bit-for-bit encoding equality
|
|
314
380
|
|
|
381
|
+
### Resource policy
|
|
382
|
+
|
|
383
|
+
**Resource policy**:
|
|
384
|
+
A workspace-local `fy.policy.json` declaration of which CLI operations are allowed and which resource limits apply. It is discovered from the working directory upward, independent of `fy.config.js`, and can only tighten its tier.
|
|
385
|
+
_Avoid_: Project config, agent runtime
|
|
386
|
+
|
|
387
|
+
**Policy tier**:
|
|
388
|
+
One of `light`, `authoring`, or `full`. A tier fixes the allowed heavy operations, the still-frame cap (1, 4, or the library cap of 32), and overwrite permission. `FRAMEYARD_POLICY` replaces the policy file for a human override.
|
|
389
|
+
_Avoid_: Permission mode, sandbox
|
|
390
|
+
|
|
391
|
+
**Resource profile**:
|
|
392
|
+
A named set of runtime caps and priority settings for a shared machine. `shared-cpu` caps timeline workers at two, composition concurrency at one, and lowers process priority.
|
|
393
|
+
_Avoid_: Encoder preset, render mode
|
|
394
|
+
|
|
395
|
+
**Lint**:
|
|
396
|
+
A Node-only validation pass that resolves a composition or timeline, projects every timeline scene and keyframe channel, scans controller source for wall-clock and randomness calls, and probes media metadata without launching Chromium. Lint is not a substitute for `check`.
|
|
397
|
+
_Avoid_: Static check, fast render
|
|
398
|
+
|
|
399
|
+
**Dry run**:
|
|
400
|
+
A heavy command mode that validates inputs and returns a plan, handoff command, prerequisites, and blockers without writing outputs, loading a model, launching Chromium, or encoding.
|
|
401
|
+
_Avoid_: Preview, partial render
|
|
402
|
+
|
|
403
|
+
### Inspection and templates
|
|
404
|
+
|
|
405
|
+
**Project context**:
|
|
406
|
+
A compact, read-only digest of a project's format, composition metadata, prop types, timeline clips, assets, installed fonts, diagnostics, active policy, and next commands.
|
|
407
|
+
_Avoid_: Project dump, repo summary
|
|
408
|
+
|
|
409
|
+
**Image inspection**:
|
|
410
|
+
Text facts extracted from a decoded still: dimensions, alpha coverage, blank detection, background and dominant colors, content bounding box, luminance grid, and edge density.
|
|
411
|
+
_Avoid_: Visual review, AI vision
|
|
412
|
+
|
|
413
|
+
**Image comparison**:
|
|
414
|
+
A pixel and region diff between two decoded images. It reports differing pixels, channel deltas, a bounding box, and a 3×3 region breakdown.
|
|
415
|
+
_Avoid_: Pixel hash, visual diff
|
|
416
|
+
|
|
417
|
+
**Project template**:
|
|
418
|
+
A known-good composition or timeline entry that `add` writes while printing the explicit `fy.config.js` registration snippet.
|
|
419
|
+
_Avoid_: Generator, project scaffold
|
|
420
|
+
|
|
315
421
|
### Agent operation
|
|
316
422
|
|
|
317
423
|
**Agent-assisted authoring and operation**:
|
|
@@ -333,9 +439,13 @@ A versioned, project-local record of generated assets, their content hashes, and
|
|
|
333
439
|
_Avoid_: Render cache
|
|
334
440
|
|
|
335
441
|
**Speech synthesis** (TTS):
|
|
336
|
-
The local production of a spoken audio asset from text using a named speaker.
|
|
442
|
+
The local production of a spoken audio asset from text using a named speaker or numeric speaker id.
|
|
337
443
|
_Avoid_: Voice generation, voice cloning, voice design
|
|
338
444
|
|
|
445
|
+
**Speech engine**:
|
|
446
|
+
A local executable that turns text into a speech asset. Frameyard supports qwentts.cpp CustomVoice and sherpa-onnx Supertonic 3.
|
|
447
|
+
_Avoid_: TTS provider, cloud voice
|
|
448
|
+
|
|
339
449
|
**Transcription**:
|
|
340
450
|
The local production of timed text from source audio or video.
|
|
341
451
|
_Avoid_: Subtitle rendering
|