Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ OLLAMA_MODEL=llama3.2
HIGGSFIELD_MCP_ACTIVE=true
TOPVIEW_API_KEY=
WAVESPEED_API_KEY=
# HyperFrames is a local HTML→MP4 renderer; no API key needed.
# Set HYPERFRAMES_ACTIVE=true once `npx hyperframes doctor` passes locally
# (Node >= 22, FFmpeg on PATH). See https://github.com/wesleysimplicio/hyperframes
HYPERFRAMES_ACTIVE=false

# Publish + ads
ADAPTLYPOST_API_KEY=
Expand Down
88 changes: 88 additions & 0 deletions .skills/hyperframes-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
name: hyperframes-cli
description: Runs the HyperFrames CLI dev loop — init, lint, inspect, preview, render — for compositions authored under the `hyperframes` skill. Invoked after the composition HTML is on disk and before the piece is marked complete.
version: 0.1.0
upstream: https://github.com/wesleysimplicio/hyperframes
---

# HyperFrames CLI

Wraps `npx hyperframes` for the marketing-engine pipeline. Requires Node.js >= 22 and FFmpeg on PATH (`npx hyperframes doctor` verifies). All commands run in DRY_RUN-safe mode by default — the lint/inspect passes have no external calls; only `render` writes an MP4.

## When to invoke

- Immediately after `hyperframes-prompt-builder` produces a project under `outputs/<client>/<date>/<piece-id>/`.
- Whenever a composition needs validation before publish (`lint` + `inspect`).
- For local preview during iteration on a piece (`preview`).
- For the final render that produces the artefact picked up by the publish step (`render`).
- For environment troubleshooting when render fails (`doctor`, `browser`, `info`).

## Inputs

- `project_path`: string. Path to the HyperFrames project (must contain `index.html` and `composition.json`).
- `mode`: `"lint" | "inspect" | "preview" | "render" | "doctor"`.
- `render_opts`: object, optional, only for `mode = "render"`. Recognized keys:
- `fps`: 24 | 30 | 60 (default 30).
- `quality`: `"draft" | "standard" | "high"` (default `"standard"`; use `"draft"` while iterating).
- `format`: `"mp4" | "webm"` (default `"mp4"`).
- `variables`: object. JSON object keyed by variable id, overrides `data-composition-variables` defaults.
- `strict`: boolean. Maps to `--strict`. Default `true` in the pipeline — fail render on lint errors.
- `strict_variables`: boolean. Maps to `--strict-variables`. Default `true` for piece runs.
- `workers`: integer 1-8 or `"auto"`. Default `"auto"`.
- `output`: string. Output file path inside `outputs/<client>/<date>/<piece-id>/`.

## Process

1. **Verify environment** on first run of a session: `npx hyperframes doctor`. Surface missing FFmpeg or Chrome as a hard block — do not attempt to render.
2. **Lint.** `npx hyperframes lint <project_path> --json`. Treat all `error`-level findings as blockers. Warnings are surfaced to the orchestrator; let the operator decide.
3. **Inspect.** `npx hyperframes inspect <project_path> --json`. Resolve any reported text overflow or canvas escape before render. If the overflow is intentional for an entrance/exit, mark the element with `data-layout-allow-overflow` (or the ancestor with `data-layout-ignore` for decorative elements) — do not silence the rule globally.
4. **Preview** (operator only). `npx hyperframes preview <project_path> --port <port>`. Hand back the **Studio project URL** (`http://localhost:<port>/#project/<project-name>`), not the source `index.html` path.
5. **Render.** `npx hyperframes render <project_path>` with the flags resolved from `render_opts`. Build the `--variables` argument from `render_opts.variables` using a single-line JSON string. Always pass `--strict` and `--strict-variables` for piece runs.
6. **Verify output.** After render, check the MP4 exists and is non-zero. Log to `data/video-usage.jsonl` with `{ ts, provider: "hyperframes", composition_id, render_args, duration_seconds, file_bytes, latency_ms }`.

## Outputs

- `lint`: `{ pass: boolean, errors: [...], warnings: [...] }`.
- `inspect`: `{ pass: boolean, findings: [...] }`.
- `render`: `{ artifact_path: string, duration_s: number, file_bytes: number, render_ms: number }`.
- `preview`: `{ url: string }`.

## Command cheat sheet

```bash
npx hyperframes init <name> # scaffold (used once per piece by the prompt builder)
npx hyperframes lint <path> # validate markup
npx hyperframes inspect <path> # layout/overflow audit
npx hyperframes preview <path> --port 3017 # local dev
npx hyperframes render <path> \
--fps 30 --quality standard --strict --strict-variables \
--variables '{"leads":42,"delta_pct":12}' \
--output outputs/<client>/<date>/<piece-id>/final.mp4
npx hyperframes doctor # environment check
npx hyperframes info # version/env details
```

## Non-negotiable rules

- Never render without a passing `lint` and `inspect` pass. The pipeline has no recovery path for a malformed composition.
- Never silence a lint or inspect finding globally — fix the markup, or whitelist the specific element with `data-layout-allow-overflow` / `data-layout-ignore`.
- For pieces with declared variables, always pass `--strict-variables`. A typo in a variable id must fail loudly, not silently fall through to the default.
- For final-delivery renders, `--quality high`. For iteration loops, `--quality draft` to save compute.
- Asset preprocessing (`tts`, `transcribe`, `remove-background`) is **out of scope** for this skill — invoke them through a future `hyperframes-media` skill rather than inlining here.

## Failure modes

- `doctor` reports missing FFmpeg or Chrome: install via the project's setup instructions; do not work around.
- `render` fails with `unknown variable`: a key passed via `--variables` is not declared in `data-composition-variables`. Fix the markup or remove the override.
- `render` exceeds wall-time budget: drop `--quality` to `standard`, or split the composition into sub-compositions and parallelize via `--workers`.
- Output MP4 has zero bytes: re-run `doctor`; almost always a Chrome crash mid-capture.

## Related skills

- `hyperframes`: composition authoring rules; produces the project this skill validates and renders.
- `hyperframes-prompt-builder`: brief → composition spec; runs before this skill.
- `qa-tech-specs`: runs after this skill against the rendered MP4 to validate platform specs.

## Upstream reference

Full upstream skill (every flag, troubleshooting matrix, parametrized renders): https://github.com/wesleysimplicio/hyperframes/tree/main/skills/hyperframes-cli
90 changes: 90 additions & 0 deletions .skills/hyperframes-prompt-builder/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
name: hyperframes-prompt-builder
description: Translates a marketing-engine piece brief into the input shape the `hyperframes` skill expects (composition spec) and the flags the `hyperframes-cli` skill needs to render it. Selected by `video-prompt-builder` when the routing matrix resolves to the `hyperframes` provider.
version: 0.1.0
---

# HyperFrames Prompt Builder

Specialist that bridges the marketing-engine piece model (`brief`, `task_kind`, `provider_override`) and the HyperFrames composition contract. Mirrors `higgsfield-prompt-builder` and `topview-prompt-builder` in shape — same dispatcher, different target — so `video-prompt-builder` can swap providers without changing its own logic.

## When to invoke

- `video-prompt-builder` resolves the video provider to `hyperframes` for a piece.
- `task_kind` is one of `motion-typography`, `data-viz-reel`, `programmatic-short` (the hyperframes-native tasks in `PROVIDERS.md`).
- A piece declares `provider_override.video: hyperframes` in its frontmatter.
- An approved still (quote card from `gpt-image`, carousel from `topview`) is being promoted to motion and the type system must stay byte-faithful to the original.
- The orchestrator needs the same composition re-rendered with new variable values (weekly KPI reel, daily price update, A/B variant copy) without re-prompting an AI generator.

## Inputs

- `brief`: object. The piece brief with at least `headline`, `body?`, `cta?`, `aspect`, `duration_seconds`.
- `task_kind`: `"motion-typography" | "data-viz-reel" | "programmatic-short"`.
- `piece_path`: string, optional. Path to `.specs/pieces/<piece-id>.md`. Frontmatter may carry `provider_override`, `compliance_flags`, `variables`.
- `client_slug`: string. Used to load `.marketing-engine/clients/<slug>/design.md` (or `clients/<slug>/design.md` in the engine repo).
- `output_dir`: string. Where the project and final MP4 live (defaults to `outputs/<client>/<date>/<piece-id>/`).
- `dry_run`: boolean, optional. When true, returns the composition spec and render args without invoking `hyperframes-cli`.

## Process

1. **Load brand context.** Read `clients/<client_slug>/design.md` and resolve `{ colors, type_pairing, spacing_scale, brand_voice }`. If missing, refuse to proceed — surface the missing path. Brand violations cannot be fixed downstream.
2. **Resolve overrides.** If `piece_path` is set and frontmatter has `provider_override.video`, confirm it is `hyperframes`; otherwise this skill should not be running.
3. **Map task_kind to a composition template.**
- `motion-typography` → `kinetic-type` template, single scene, type-driven.
- `data-viz-reel` → `nyt-graph` template, body scene with declared numeric variables.
- `programmatic-short` → `play-mode` template, hook/body/cta, all client copy declared as variables.
4. **Declare variables.** Anything from the brief that could change per re-render (headline, body, KPI numbers, CTA, date stamp) goes into `variables` with explicit type + label + default. Hardcoded copy is forbidden when a variable would work.
5. **Build the composition spec** in the shape `hyperframes` expects: `{ composition_id, aspect, duration_seconds, scenes, design_tokens, variables, assets, output_dir }`. Compute `composition_id` from `<piece-id>` (slug-safe).
6. **Build the render args** in the shape `hyperframes-cli` expects: `{ project_path, mode: "render", render_opts: { fps, quality, format, variables, strict: true, strict_variables: true, output } }`. Pick `quality: "high"` for promoted pieces, `"draft"` for first-pass review.
7. **Cost estimate.** Local render — estimate from `duration_seconds × workers × $0.00` (zero out-of-pocket; report wall-time minutes as `latency_estimate_min` instead).
8. **Log the resolution** to `data/video-usage.jsonl` with `{ ts, provider: "hyperframes", piece_id, task_kind, composition_id, dry_run }`.
9. If `dry_run`, return without calling `hyperframes-cli`. Otherwise invoke `hyperframes` (to author the project) then `hyperframes-cli` (mode `lint` → `inspect` → `render`) in order.

## Outputs

- `provider_used`: `"hyperframes"`.
- `composition_spec`: object. The input passed to the `hyperframes` skill.
- `render_args`: object. The input passed to the `hyperframes-cli` skill (mode `render`).
- `expected_artifact`: string. The MP4 path that will exist after `render`.
- `latency_estimate_min`: number. Wall-time estimate for the render.
- `cost_estimate_usd`: 0 (local render; opex only).

## Examples

### Example 1: weekly KPI reel (`programmatic-short`)

Input: `{ brief: { headline: "Semana 21 em números", aspect: "9:16", duration_seconds: 12 }, task_kind: "programmatic-short", client_slug: "saas-consultoria-imagem", piece_path: ".specs/pieces/2026-05-22-kpi.md" }`
Output: composition spec with `composition_id: "kpi-weekly-2026-05-22"`, three scenes (hook/body/cta), numeric variables (`leads`, `delta_pct`); render args with `--strict --strict-variables --quality high --variables '{"leads":42,"delta_pct":12}'`.

### Example 2: motion quote card (`motion-typography`)

Input: `{ brief: { headline: "Coloque a sua marca onde os olhos já estão.", aspect: "1:1", duration_seconds: 6 }, task_kind: "motion-typography", client_slug: "saas-consultoria-imagem" }`
Output: composition spec with a single kinetic-type scene, masked-text entrance, design tokens pulled from the active client's `design.md`; render args targeting `outputs/saas-consultoria-imagem/<date>/<piece-id>/final.mp4`.

### Example 3: provider override

Input: a piece with `provider_override.video: hyperframes` whose `task_kind` is not in the matrix.
Output: still routed here, default `task_kind` to `programmatic-short`, log the fallback.

## Non-negotiable rules

- Never invent design tokens. Refuse to proceed if `design.md` is missing.
- Always declare per-piece copy as a `variable`, even when it looks static — the composition must be re-renderable without code edits.
- Always pass `--strict-variables` in the render args. A typo in a variable id is a hard fail.
- Never call `hyperframes-cli` directly bypassing the `lint → inspect → render` sequence.

## Failure modes

- Unknown `task_kind`: default to `programmatic-short`, log a warning, and continue.
- `design.md` missing: stop. Do not pick a palette; ask the operator to add the file.
- Brief includes a brand-prohibited claim (per `compliance-<active client>`): block before authoring; compliance runs upstream of render.
- HyperFrames CLI not installed: surface the install command (`npm i -g hyperframes` or `npx hyperframes@latest`) and stop.

## Related skills

- `hyperframes`: composition authoring rules (consumed by this skill).
- `hyperframes-cli`: lint/inspect/render execution (consumed by this skill).
- `video-prompt-builder`: dispatcher that selects this skill.
- `qa-tech-specs`: runs against the final MP4.
- `compliance-<active client>` / `compliance-generic`: runs against the resolved variables and the rendered artefact.
- `llm-router`: not used directly here, but may pick the LLM that drafts the headline/body before this skill assembles the composition spec.
Loading
Loading