Skip to content

feat: native Remotion templates, RFC-07 renames, KPI pulse, agent skill - #37

Open
yasenchen-cmd wants to merge 6 commits into
nexu-io:mainfrom
yasenchen-cmd:feat/native-templates
Open

feat: native Remotion templates, RFC-07 renames, KPI pulse, agent skill#37
yasenchen-cmd wants to merge 6 commits into
nexu-io:mainfrom
yasenchen-cmd:feat/native-templates

Conversation

@yasenchen-cmd

@yasenchen-cmd yasenchen-cmd commented Jun 9, 2026

Copy link
Copy Markdown

Summary

Expands feat/native-templates beyond the original 4 Remotion chart templates:

  • Native Remotion chartsframe-data-donut / hbars / line / radar (RFC-08 Phase 2), completing the pattern from frame-data-rollup
  • Non-chart enhanceframe-kpi-pulse (single-metric spring + count-up + ring)
  • RFC-07 namingframe-pentagram-statframe-editorial-anchor, frame-build-minimalframe-luxe-minimal, frame-takram-organicframe-soft-radar (studio names only in provenance.origin)
  • RFC-06 — formal content-graph spec at research/2026-05-28-spec-06-content-graph.md
  • Agent skill — root SKILL.md, installable copies, scripts/install-agent-skill.sh, validate-templates
  • Tooling — CI (pnpm verify), Remotion/studio/CLI/runtime hardening, provenance on remaining templates, preview posters, package tests

Curated gallery is now 28 templates.

Test plan

  • pnpm validate-templates → 28 templates, 0 errors
  • html-video list-native-templates --json includes frame-kpi-pulse + 5 charts
  • html-video search-templates --intent "swiss grid editorial" ranks frame-editorial-anchor
  • rg 'frame-pentagram-stat|frame-build-minimal|frame-takram-organic' templates/ → empty (except historical docs)
  • Enhance a data node with frame-kpi-pulse and export a short MP4 (non-black)
  • pnpm verify (or CI check) green on this PR

… radar

Adapted from Hermes Studio (chenys/hermes-studio) scene components:

- frame-data-donut (DataDonut.tsx): SVG donut/ring chart with spring-animated
  slices, center figure rollup, staggered legend. 382 lines.
  ← src/video/scenes.tsx SceneDonut

- frame-data-hbars (DataHBars.tsx): Horizontal bars with top/bottom grouping,
  spring growth, rollup values, log-scale fallback. 281 lines.
  ← src/video/scenes.tsx SceneDeptBars

- frame-data-line (DataLine.tsx): SVG line chart with stroke-dashoffset path
  drawing, gradient area fill, staggered data points, trend arrow. 320 lines.
  ← src/video/scenes.tsx SceneMonthlyTrend

- frame-data-radar (DataRadar.tsx): SVG radar/spider chart with concentric
  grid rings, spring polygon, warn-threshold coloring. 230 lines.
  ← src/video/scenes.tsx SceneRadar

All templates: pure system fonts, responsive layout (16:9/9:16/1:1 via
useVideoConfig), no external assets, offline-deterministic.

Co-Authored-By: chenys <noreply@github.com>
@lefarcen lefarcen added size/XXL Size XXL (1500+ LOC) risk/medium Medium risk type/feature Feature change labels Jun 9, 2026
@lefarcen
lefarcen requested a review from nettee June 9, 2026 01:28
@lefarcen

lefarcen commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Hey @yasenchen-cmd! 👋 Four data-viz templates in one shot — the spring-physics animation language consistency and the log-scale fallback on hbars are both thoughtful details that will matter a lot at render time. Nice to see Phase 2 land.

I've assigned @nettee for review and tagged the PR size/XXL / risk/medium / type/feature.

Since this is a large surface area, you might find it handy to have an AI agent drive the PR to merge hands-free once feedback arrives:

💡 To drive this PR to merge hands-free, paste this to your AI coding agent (Claude Code / Codex / opencode / Cursor …):
Take over nexu-io/html-video#37 until it merges — read https://raw.githubusercontent.com/nexu-io/looper/main/skills/pr-takeover/SKILL.md and follow it.

@nettee nettee left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found three blocking correctness issues in the new native templates. They are all in changed code/schema paths, and each one includes a concrete fix inline.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment on lines +145 to +158
const donutSize = Math.min(
width - padX * 2,
height - padY * 2 - (data.title ? height * 0.1 : 0),
);
if (!isVertical) {
// Leave room for legend on the right.
const donutMaxW = width * 0.55;
const legendW = width * 0.35;
const donutW = Math.min(donutMaxW, donutSize);
// donutSize stays as computed; the SVG will just be positioned left.
}
const donutR = Math.max(20, donutSize * 0.38);
const strokeW = Math.max(8, donutR * 0.26);
const cx = isVertical ? width / 2 : Math.round(width * 0.30);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wide-layout sizing here does not actually reserve space for the legend. On a supported 1:1 render (width=height=1080), donutSize becomes 907 while cx stays at width * 0.30 = 324, so the SVG is positioned at left = -129 and gets cropped off the left edge. The unused donutMaxW / donutW locals on lines 151-153 look like the intended fix. Please clamp the rendered donut size/position for non-vertical layouts, or switch 1:1 to the stacked layout, so every advertised aspect ratio stays fully on-canvas.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment on lines +89 to +94
const barHeight = Math.max(14, Math.round(height * 0.032));
const barGap = Math.round(barHeight * 0.65);
const labelW = Math.round(width * 0.2);
const barAreaX = padX + labelW + Math.round(width * 0.02);
const barAreaW = width - barAreaX - padX;
const chartH = items.length * (barHeight + barGap);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This layout cannot satisfy the schema's maxItems: 20. barHeight scales with canvas height and chartH = items.length * (barHeight + barGap), so at the default 1920x1080 size 20 rows need roughly 20 * (35 + 23) = 1160px before title/padding, which pushes the last bars below the frame; 9:16 is even worse. Because template.html-video.yaml accepts 20 items, callers can send valid input and get truncated output. Please either derive barHeight / barGap from the available vertical space or lower the schema cap to the largest count that fits every supported aspect ratio.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

const muted = props.muted ?? DEFAULTS.muted;
const accent = props.accent ?? DEFAULTS.accent;
const accentWarn = props.accentWarn ?? DEFAULTS.accentWarn;
const warnThreshold = props.warnThreshold ?? 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warn-threshold feature is wired to a different prop shape than the rest of this PR. Root.tsx, template.html-video.yaml, and example.md all pass warnThreshold inside data, but this component only reads props.warnThreshold, so the documented/sample input never highlights weak axes and the generated preview misses the advertised behavior. Please make the code, DataRadarData type, root sample, and YAML/example agree on one shape; the least disruptive fix is usually reading data.warnThreshold and adding that field to DataRadarData.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen

lefarcen commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Hey @yasenchen-cmd@nettee's review is in with three correctness blockers. Each one has a concrete fix path right in the inline comments, so they should be straightforward to address:

  1. frame-data-donut — 1:1 render clips the SVG: at width=height=1080, the computed cx = width * 0.30 = 324 positions the donut off the left edge. The unused donutMaxW/donutW locals look like the intended guard — the fix is clamping position/size for non-vertical layouts, or routing 1:1 through the stacked path.

  2. frame-data-hbarsmaxItems: 20 overflows at 1920×1080: static barHeight means 20 rows need ~1160px before title/padding, which exceeds the canvas. Either derive bar height from the available vertical space or lower the schema cap to the largest count that fits across every supported aspect ratio.

  3. frame-data-radarwarnThreshold is silently disconnected: Root.tsx, template.html-video.yaml, and example.md all pass it inside data, but the component reads props.warnThreshold — so highlighting never fires on any sample input. The quickest fix is reading data.warnThreshold and adding it to DataRadarData.

Push fixes and re-request review from @nettee when ready. 🙌

@lefarcen

Copy link
Copy Markdown
Contributor

Heads-up: you also have #85 open against the same area — both PRs touch the templates/frame-data-{donut,hbars,line,radar}/** files. #85 looks like the broader slice because it carries the template set plus the CLI/studio/skill wiring, so it may be worth consolidating or closing one of them to keep review on a single merge path.

chenys and others added 5 commits August 5, 2026 22:10
Pin the multi-frame schema/agent protocol in research/, link it from
@html-video/content-graph, and replace stale "HF stub / empty MP4" notes
in CLAUDE.md with the 2026-08-05 capability truth source.

Co-authored-by: Cursor <cursoragent@cursor.com>
Per RFC-07 §③: pentagram-stat→editorial-anchor, build-minimal→luxe-minimal,
takram-organic→soft-radar. Studio names stay only in provenance.origin;
sample copy replaced with html-video-owned metrics.

Co-authored-by: Cursor <cursoragent@cursor.com>
Land installable SKILL.md copies + scripts/install-agent-skill.sh and
validate-templates. Add frame-kpi-pulse (non-chart Remotion enhance) with
normalizeNativeData support so data frames can opt into a single-metric
spring/count-up instead of a multi-series chart.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Bring in the rest of the branch WIP: CI workflows, verify/validate scripts,
Remotion/studio/CLI/runtime hardening, provenance on remaining templates,
preview posters, and package tests. Exclude local .pnpm-store from git.

Co-authored-by: Cursor <cursoragent@cursor.com>
@yasenchen-cmd yasenchen-cmd changed the title feat: 4 native Remotion templates — donut, hbars, line, radar (RFC-08 Phase 2) feat: native Remotion templates, RFC-07 renames, KPI pulse, agent skill Aug 5, 2026
@nettee

nettee commented Aug 5, 2026

Copy link
Copy Markdown

@yasenchen-cmd I'm holding off on generating review comments for #37 because this pull request has merge conflicts right now.

Please resolve the conflicts with main and push the updated branch. Once that's done, request or wait for the review to run again and I'll take another look.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen lefarcen added the needs-product-review Product review required before merge label Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-product-review Product review required before merge risk/medium Medium risk size/XXL Size XXL (1500+ LOC) type/feature Feature change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants