The GSAP family README described HyperFrames as a 'future' engine ('if the
parallel HyperFrames engine gets wired in', 'becomes a day-1 skill', 'Future
hyperframes_compose tool — if added'). Every other artifact (AGENT_GUIDE.md,
skills/core/hyperframes.md, skills/INDEX.md) treats HyperFrames as a fully
production composition runtime, and hyperframes_compose is a registered tool.
Update the HyperFrames references to present-tense production reality. Also add
a scope note: this directory has no SKILL.md and is not a loadable skill — it
is a navigation map for the sibling gsap-* skills, which removes the ambiguity
about why it is not loadable via agent_skills[].
Closes#61
Three skill directories ship a long-form upstream AGENTS.md alongside their
loadable SKILL.md:
.agents/skills/flux-best-practices/AGENTS.md
.agents/skills/vercel-composition-patterns/AGENTS.md
.agents/skills/vercel-react-best-practices/AGENTS.md
None were referenced by their parent SKILL.md, skills/INDEX.md, AGENT_GUIDE.md,
or any pipeline manifest, leaving their authority scope undefined relative to
the repository-root AGENTS.md (override / extend / ignore?).
Reference each from its SKILL.md with explicit scope: the AGENTS.md is
supplementary upstream reference material for that skill only, SKILL.md is the
loadable entry point and the authority, and it does not override or extend the
root AGENTS.md / AGENT_GUIDE.md. Preserves the vendored content while removing
the ambiguity.
Refs #61
runway (estimate_cost/estimate_runtime/execute) defaulted to gen4_turbo and
higgsfield (execute) defaulted to kling_3.0, while both schemas advertise
seedance_2.0 as model.default. Omitting model under-quoted cost (runway 6x:
$0.25 vs $1.50) and silently generated a different model than advertised,
violating the Decision-Communication / cost-accuracy contract.
Root cause was a default duplicated across schema + 3 methods that drifted.
Collapse it to a single _DEFAULT_MODEL constant referenced everywhere.
Add tests/tools/test_provider_model_defaults.py to lock each tool's
estimate default to its schema default and guard the execute path.
The video-reference-analyst capability audit pre-locked Remotion as the
default composition engine ('Remotion is the default ... Never default to
FFmpeg when Remotion is available'). Because the analyst skill runs first
in any reference-led flow, this silently locked the runtime before the user
was ever offered a choice — violating the 'Present Both Composition Runtimes
(HARD RULE)' in AGENT_GUIDE.md, which forbids silently picking a default and
treats Remotion and HyperFrames as parallel, non-ranked runtimes.
It also omitted HyperFrames from the engine list entirely, so it was never
surfaced as an option in the reference-led path.
Update Step 2 (Capability Audit) to:
- add HyperFrames to the audited runtime list
- remove the 'Remotion is the default / preferred' framing
- defer engine selection to the AGENT_GUIDE 'Present Both' gate
- keep FFmpeg scoped to standalone ops, not composition
Closes#60
tools/video/green_screen_composite.py imports numpy at module level (and
declares "python:numpy" as a dependency), but numpy was missing from
requirements.txt. Because registry.discover() imports every tool module,
a fresh `make setup` followed by the mandatory preflight crashes with
ModuleNotFoundError: No module named 'numpy'. Add numpy>=1.24.
Also gitignore *.onnx/*.onnx.json so Piper TTS voice models fetched at
runtime (e.g. en_US-lessac-medium.onnx, ~60MB) aren't accidentally
committed to the repo root.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The repo had no .github issue or PR templates, so bug reports arrived
with inconsistent detail and questions landed on the tracker instead of
Discussions.
Add GitHub community templates:
- ISSUE_TEMPLATE/bug_report.yml: structured form (OS, pipeline, runtime,
repro, expected vs actual, logs)
- ISSUE_TEMPLATE/feature_request.yml: problem / solution / alternatives
- ISSUE_TEMPLATE/config.yml: disables blank issues and routes questions,
ideas, and show-and-tell to the existing Discussions categories
- PULL_REQUEST_TEMPLATE.md: summary, linked issue, testing, checklist
Additive only; no source changes.
Closes#189
Without a .gitattributes, line-ending normalization depends on each
contributor's local core.autocrlf. On Windows checkouts this can
materialize text files — and shell scripts like render-demo.sh — with
CRLF, which breaks script shebangs and produces noisy cross-platform
diffs.
Add a root .gitattributes that:
- defaults all text files to LF (* text=auto eol=lf)
- pins shell scripts, Makefile and .env.example to LF explicitly
- keeps .bat/.cmd as CRLF
- marks image/video/audio/font assets as binary so Git never
normalizes or diffs them
Only the policy file is added; existing files are intentionally left
unrenormalized to keep this change reviewable.
Closes#187
On Windows, passing --props and the JSON path as two separate CLI
arguments causes Remotion to mis-parse the value due to platform quote
escaping, failing with "neither valid JSON nor a file path to a valid
JSON file". Switch to the --props=<path> equals form, which Remotion
recommends for file paths and which works consistently across
platforms.
Fixes#172
tests/qa/test_08_end_to_end.py runs at module import, so pytest fails
collection with CheckpointValidationError: the Stage 5 edit_decisions
fixture omits render_runtime, which edit_decisions.schema.json lists as
required. Per AGENT_GUIDE the runtime is locked at proposal and carried
through edit unchanged, so the fixture now sources it from the same
proposal_packet["production_plan"]["render_runtime"] ("remotion")
instead of hardcoding an unrelated value, keeping the fixture internally
consistent with the proposal it builds on.
Google's TTS and Imagen tools advertised service-account auth
(GOOGLE_APPLICATION_CREDENTIALS) but only ever authenticated with an API
key string, so users with a service-account JSON could not use either tool.
google_tts.get_status() also over-reported availability when the JSON was
set, then failed at execute() — a silent-availability bug.
Separately, both hand-rolled _load_dotenv parsers kept inline comments as
values, so after `cp .env.example .env` every keyed tool falsely reported
"available" with no real credentials.
Changes:
- Add tools/google_credentials.py: lazy google-auth Bearer-token helper.
- google_tts: authenticate via Cloud TTS Bearer token when only a service
account is configured; make get_status() honest.
- google_imagen: route service-account auth to Vertex AI
({location}-aiplatform.googleapis.com) with project/location resolution,
alongside the existing AI Studio API-key path.
- Fix both _load_dotenv parsers to strip inline comments (quote-aware).
- Add google-auth to requirements; document the new env vars in .env.example.
- .gitignore: never commit GCP service-account key files.
Verified locally with a real service account: TTS produced a valid MP3 and
Imagen produced a valid 1408x768 PNG via Vertex AI. Existing test suite
passes (2 unrelated pre-existing failures only).
Closes#131
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ARCHITECTURE.md said `npx @hyperframes/cli` but that scoped package
is a 404. The published npm package is `hyperframes`, consumed as
`npx hyperframes`. hyperframes_compose.py already documents this
distinction in its _NPM_PACKAGE constant and install_instructions.
ToolRegistry exposes get(name) but source_media_review called the
non-existent get_tool(name) in four places — audio_probe (×2),
frame_sampler, and transcriber. All four renamed to .get().
Lines 219 and 227 imported upload_image_fal from _shared but called
the non-existent upload_image_to_fal, raising a NameError whenever
image_to_video or reference_to_video used local image paths.
Adds a transcript_comparison check to VideoCompose._run_final_review
that word-diffs the whisper/whisperx transcript against script.txt and
fails loudly when the TTS engine literally voiced punctuation tokens
(dot, dots, ellipsis, comma, dash, hyphen, period). Chirp3-HD did this
to ellipses in a production run and it slipped past review; now it
cannot.
Also corrects the "tiny background video" gotcha in
skills/core/hyperframes.md. After six renders of blaming HyperFrames
CSS, the real root cause was 640x360 Pexels sources combined with a
fit-and-pad pre-transform — HyperFrames was rendering the letterboxed
input faithfully. Gotcha now walks through the ffprobe diagnostic and
the scale-to-cover fix, and keeps the wrapper-div pattern for the
right reasons (aspect mismatch handling, not framework bug workaround).
Four regression tests cover the new check: punctuation-leak detection,
clean-audio false-positive guard, graceful skip when inputs missing,
and always-present transcript_comparison section.
Surfaces six real traps an agent learns the expensive way: full-frame
videos need BOTH HTML width/height attrs AND `!important` CSS because
the runtime applies inline size from intrinsic dimensions; preview-scrub
matters more than a 60-minute render for visual bugs; legibility comes
from scrims + text-shadow, not from lowering video opacity; downloaded
stock needs dense keyframes (-g 30) before render or parallel capture
times out; --workers 1 is mandatory for video-heavy compositions; the
deterministic-font compiler silently replaces unmapped families like
Space Grotesk, use Outfit/Inter/JetBrains Mono/Poppins instead. Each
gotcha documented with the fix-at-author-time pattern so the next agent
ships a clean first render.
Separates creative grammar (renderer_family) from technical engine
(render_runtime) so HyperFrames can stand alongside Remotion as a
first-class runtime instead of masquerading as a Remotion sub-case.
Locks runtime choice at proposal stage and enforces it end-to-end: the
schemas require it, video_compose routes by it, the reviewer fails
closed on silent swaps, and a parametrized contract test walks every
pipeline manifest to ensure each planning-stage skill explains the
conversation to the user. Adds hyperframes_compose (scaffold/lint/
validate/render/doctor/add_block), a playbook -> CSS style bridge, and
vendored HyperFrames Layer 3 skills from commit d291358, pinned via
PROVENANCE.md for future re-sync. Final_review now records
render_runtime_used and runtime_swap_detected so compose lies are
catchable after the fact.