Skip to content

feat(script): cinematography agents + hook layering + ssr cache fix#10

Merged
cuio merged 2 commits intomainfrom
feat/cinematography-on-main
Apr 25, 2026
Merged

feat(script): cinematography agents + hook layering + ssr cache fix#10
cuio merged 2 commits intomainfrom
feat/cinematography-on-main

Conversation

@cuio
Copy link
Copy Markdown
Owner

@cuio cuio commented Apr 25, 2026

Summary

This PR fixes five things in one bundle. Two are missing pieces from earlier PRs that didn't actually land on main, three are user-flagged regressions/UX issues that surfaced when running the framework end-to-end on a real project.

1. Cinematography agents + asset library (re-PR of #9)

PR #9 was merged into the wrong base (PR #7's branch instead of main), so its content never reached main. Re-applied here.

  • Asset library: 4 new atmosphere presets (registry 5→9): radial-pulse, cosmic-dust, geometric-grid, flow-lines
  • Icon library: 20 hand-drawn 24×24 stroke SVGs (lock, network, bolt, dollar, globe, target, shield, etc.)
  • concept-callout items support {text, icon} — icon replaces the number badge
  • Planner tool schema gains background and transition fields per scene as enums
  • Schema validation + one-shot retry pass: catches missing required props / chart-scene without chart.type, sends a corrective system prompt for one retry
  • Hook composer pass (improveHook): cheap second-agent critic that scores s01 against the hook quality checklist and proposes a swap with a stronger sentence later in the script

2. Hook layering — stake / data / claim / why

The user's primary feedback: "the hook should have information, data, why, what's at stake."

  • Playbook hook section rewritten around the four-layer rubric. A bare claim is a press release, not a hook
  • Per-template recipes show which prop carries each layer (hook-bigtext / hook-statreveal / chart-scene-as-opener)
  • New optional subtext prop on hook-bigtext renders one short line below the title with an accent left-rule, fading in after the letter cascade — for the WHY context
  • Hook quality checklist expanded; reasoning must NAME the four layers or the hook is incomplete

3. Target duration removed

The user: "having target seconds is wrong. time is based on script."

  • Total video length now follows the script's natural read time
  • "Target (s)" input deleted from ScriptTab
  • Planner's user-message no longer carries "Target overall duration" constraint
  • PlanOptions.targetDurationSeconds kept as @deprecated for back-compat with older API clients

4. SSR module cache invalidation

The silent root cause behind the user's "all the gradient effects are gone after I ran generate again".

  • The studio's Vite plugin captured the studio-api module reference once at process start and never invalidated. Edits to assemble.ts / planner.ts / playbook.ts didn't take effect until restart, which made every PR look broken until someone manually restarted bun run dev
  • New apiInvalidatedSince() walks the SSR module graph; if any transitive dep's lastInvalidationTimestamp is newer than when _api was built, the cache drops and the next request rebuilds with fresh bindings

5. "Use the assets" doc

The user: "how to use these assets?"

  • New playbook section: defaults are a floor, not a ceiling
  • At least 3 of every ~12 scenes should override background or transition with a non-default that earns its place in the reasoning
  • Concept-callout with 2+ items that map cleanly to the icon library should USE the icons
  • A great plan reads like a director making choices. A passable plan reads like a template engine.

Test plan

  • After studio restart and full generate, all 12 scenes carry per-scene atmospheres (aurora / mesh / particles distribution)
  • DESIGN.md → tokens overlay works: bg #0a0a0a, accent #7c3aed, accent2 #06b6d4 on the my-first-video project (HyperSpeedrun "Data Drift meets Swiss Pulse" aesthetic)
  • Per-scene rendered HTML uses dark-theme tokens (purple badges with halo, cyan title accents, deep black bg)
  • Lint, format check, typecheck all pass

Stack note

The previous "all PRs merged but main is missing #9" issue happened because GitHub's PR-stack base interaction merged #9 into PR #7's branch, not into main. This PR cherry-picks #9's commit fresh against main + adds the new fixes on top. Single PR, single base — no stacking.

ishan pandey added 2 commits April 25, 2026 22:12
Three things in one PR — the planner stops being template-only and
starts directing cinematography, scenes get a much richer kit of
visual presets to draw on, and a cheap second-pass critic protects
the cold-open.

Asset library:
- Four new atmosphere presets bringing the registry from 5 → 9:
  - radial-pulse: concentric ring pulses from canvas centre. Magnetises
    the eye for centred hero elements (hook-statreveal).
  - cosmic-dust: sparse twinkling stars + two drifting halos. Cosmic
    scale feel for hooks/outros.
  - geometric-grid: drifting + pulsing isometric grid lines.
    Engineering aesthetic for chart-scene and comparison.
  - flow-lines: wavy horizontal SVG paths drifting across the canvas.
    Audio-waveform vibe for quote scenes and time-series charts.
- New icons/ registry — 20 hand-drawn 24x24 stroke SVGs (lock, network,
  bolt, dollar, globe, target, shield, etc). Pure geometric primitives,
  no third-party paths. Renders at any size, picks up token colours via
  currentColor.
- concept-callout items can now carry an icon that REPLACES the number
  badge: { text, icon } per item, mixed with plain strings allowed.
  Backwards-compatible with existing scripts that pass plain strings.

Slice 8 — planner cinematography:
- New "Cinematography" section in playbook teaches the AI when to pick
  each atmosphere preset, which transition fits which moment, and
  which icon belongs on which list item.
- Planner tool schema gains optional background and transition fields
  per scene, both as enums of registered ids. Unknown values fall back
  to defaults so a hallucination can't break assembly.
- After the first planner pass, schema validation walks every scene
  and flags missing required props or chart-scene without chart.type /
  chart.props matching the chart's required fields. Issues are sent
  back as a corrective system prompt for ONE retry — turns ~90% first-
  pass success into ~99% at the cost of one extra round-trip on the
  failing case. Lingering issues land in meta.warnings so the UI can
  surface them.

Slice 9 — hook composer pass:
- New improveHook(script, opts) that critiques s01 against the hook
  quality checklist and either keeps it or proposes a swap with a
  stronger sentence later in the script. Cheap (~1k input + 200 output
  tokens, ~$0.01/video on Sonnet 4.6).
- Verbatim fidelity skips by contract — strict mode never swaps.
  Refine and split-merge run the critic.
- Wired into POST /projects/:id/script/plan as an optional second pass,
  default on. Body flag improveHook=false skips. Decision and reasoning
  surface in meta.warnings.
- Failures are non-fatal: a failed critic call returns the original
  script with a reasoning string instead of bubbling.

Verified: assembled the existing my-first-video with explicit overrides
to props.background = radial-pulse / cosmic-dust / geometric-grid /
flow-lines on different scenes. All four new presets reach the
assembler and render correctly. Concept-callout with mixed string and
{text, icon} items renders icon SVGs inside badges where set, plain
two-digit numbers elsewhere.
Five things in one PR — addresses the regressions and missing pieces
the user hit when trying to actually use the framework end-to-end.

Hook quality (the user's #1 concern):
- Playbook hook section rewritten around the four-layer rubric:
  STAKE / DATA / CLAIM / WHY. A bare claim is a press release, not a
  hook. Per-template recipes show which prop carries each layer for
  hook-bigtext, hook-statreveal, and chart-scene-as-opener.
- New optional `subtext` prop on hook-bigtext renders one short line
  below the title with an accent left-rule, fading in after the letter
  cascade. Designed for the WHY context the user asked for.
- Hook quality checklist expanded to six items including "name the
  four layers in the reasoning, or the hook is incomplete".
- Output section reminds the planner about the new prop.

Target duration removed:
- Total video length follows the script's natural read time. Removing
  the target made the planner stop padding/truncating to hit a number;
  per-scene durationHint still controls visual rhythm.
- Studio "Target (s)" input deleted from ScriptTab.
- Planner's user-message no longer includes "Target overall duration"
  constraint; PlanOptions.targetDurationSeconds kept as @deprecated for
  back-compat with older API clients.

SSR module cache invalidation (the silent root cause behind "atmospheres
gone after Generate"):
- Studio's Vite plugin captured the studio-api module reference once at
  process start and never invalidated. Source edits to assemble.ts /
  planner.ts / playbook.ts didn't take effect until the dev server was
  restarted, which made every PR look broken until restart.
- New apiInvalidatedSince() walks the SSR module graph for the
  studio-api entry; if any transitive dep's
  lastInvalidationTimestamp is newer than when we built _api, drop
  the cache so the next request rebuilds with fresh bindings.

"Use the assets" doc:
- New playbook section: defaults are a floor, not a ceiling. At least
  3 of every ~12 scenes should override background or transition with
  a non-default that earns its place in the reasoning. Concept-callout
  with 2+ items that map cleanly to the icon library should USE the
  icons. A great plan reads like a director making choices.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant