lucasduys-forge
Turn a one-line idea into a branch with tested, reviewed, committed code. The brainstorm-to-commit pipeline for Claude Code.
A Claude Code plugin that turns a brief into a cinematic launch video, an investor pitch deck, or a feature walkthrough — with live FLIP morph transitions, audio bus, scene SFX, and a dev scrubber wired the first time.
$ npx -y skills add LucasDuys/cinemorph --agent claude-code
Repo: LucasDuys/cinemorph
What's inside
A Claude Code plugin that turns a brief into a cinematic launch video, an investor pitch deck, or a feature walkthrough — with live FLIP morph transitions, audio bus, scene SFX, and a dev scrubber wired the first time.
↑ 30-second product film generated by /cinemorph new --from-example launch-cinematic-30s. Click to play the full MP4.
Quick start · Commands · How it works · Examples · GitHub Pages site
Cinemorph is a Claude Code plugin (/cinemorph) that composes a Vite + React deck where persistent elements morph cleanly between stages via Framer Motion's shared-layout (LayoutGroup + layoutId) FLIP transitions. The deck is the artifact: run it live in Chrome, click through with arrow keys, or export to one of three production targets.
| Output | What it produces | When to use |
|---|---|---|
| Live React deck | Vite dev server, hot reload, ?dev=1 timeline scrubber | The projector. Pitches, demos, all-hands. |
| MP4 (Playwright + ffmpeg) | 30-second to 5-minute cinematic film with audio bus, voiceover, SFX, smear cuts | Launch trailers, social, embeddable on a landing page. |
| PPTX with native Morph | Editable PowerPoint with Microsoft Morph transitions between slides | Stakeholder handoff to teams that don't ship from a browser. |
Everything you see in the hero film above is one stages.ts + one data.ts plus a primitive registry. The composer wrote both files, the scaffold rendered them, Playwright recorded the result, and ffmpeg muxed the audio bed + voiceover + SFX cues.
# 1. Install the plugin into Claude Code
git clone https://github.com/LucasDuys/cinemorph.git
cp -r cinemorph/plugin ~/.claude/plugins/cinemorph
# 2. Restart Claude Code, then in a chat:
/cinemorph new --from-example launch-cinematic-30s --out my-launch-video
# 3. Run it
cd my-launch-video
bun install && bun run dev # → http://localhost:5173
# ?dev=1 for the timeline scrubber
Three more things you can do in one command:
# Investor pitch from a brief
/cinemorph new --theme stacklink-dark --prompt "Series A pitch: problem, solution, traction, team, ask"
# Feature walkthrough from a starter
/cinemorph new --from-example feature-demo --out ./changelog-q2
# Export the active deck to MP4 + PPTX + speaker notes
/cinemorph export --all
Auth. Cinemorph spawns the
claudeCLI binary on yourPATHand uses your Claude Code subscription. NoANTHROPIC_API_KEYneeded.
One master RAF clock drives every animation. Phases are non-overlapping windows with 350 ms cross-fade smear cuts at boundaries. The audio bus mixes a music bed, a voiceover, and a curated SFX library. Whooshes ride only real scene transitions; tiles bounce in with aeBounce easing.
00:01 Logo pop | 00:08 Hyper-zoom + sources | 00:13 "every tool. one brain." |
|---|---|---|
![]() | ![]() | ![]() |
00:18 Onboarding card lands | 00:22 Agent constellation | 00:28 Outro + URL chime |
|---|---|---|
![]() | ![]() | ![]() |
▶ Watch the full 30s MP4 (14 MB, 4K source · 3840×2160 @ 30fps)
The stacklink-roundone-pitch example renders five click-through stages with shared-layout morphs. Same engine, different example. Bundle is identical: stages.ts + data.ts + tokens.ts.
| 1. Hook | 2. Problem | 3. Solution |
|---|---|---|
![]() | ![]() | ![]() |
| 4. Differentiation | 5. Team & Ask |
|---|---|
![]() | ![]() |
| Command | What it does |
|---|---|
/cinemorph new "<brief>" [flags] | Generate a fresh deck. Asks clarifying questions when inputs are insufficient. |
/cinemorph iterate "<change>" | Modify the active deck (last-touched in cwd or --deck <path>). |
/cinemorph render | Open the live deck via bun run dev. |
/cinemorph pptx | Export to dist/<name>.pptx with native PowerPoint Morph transitions. |
/cinemorph video | Export to dist/<name>.mp4 via headless Playwright recording + ffmpeg mux. |
/cinemorph export --all | Run pptx + video + notes.md in one shot. |
/cinemorph reference add <path> --name <name> | Register an existing deck as a style reference. |
/morph-deck continues to work as a v1.0 alias.
/cinemorph new--from-example <name> Start from a bundled deck (see Examples)
--theme <name> stacklink-dark | bunq-mint-light | linear-light | minimal-mono | playful-poster
--tokens <path> Load tokens.json or DESIGN.md
--reference <image> Extract a 5-color palette from a screenshot
--prompt "<text>" Free-form brief or style description
--out <path> Where to write the new deck (default: ./<slug>)
Inputs apply in priority order — --theme < --tokens < --reference < --prompt. Later layers win on fields they provide. Missing fields trigger a clarifying question (the composer asks instead of guessing).
brief + flags
│
▼
┌───────────────┐
│ token merger │ --theme --tokens --reference --prompt (priority order)
└──────┬────────┘
│ tokens.ts
▼
┌───────────────────────┐
│ composer (Claude CLI) │ emits stages.ts + data.ts as JSON
└──────┬────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ scaffold renderer │
│ Vite + React 18 + Tailwind + motion/react│
└──────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ live deck → PPTX with Morph → MP4 (Playwright+ffmpeg) │
└──────────────────────────────────────────────────────────────┘
A <LayoutGroup> from motion/react wraps every persistent element on the canvas. Each primitive (wordmark, search bar, kpi tile, connector chip, agent card, …) carries a stable layoutId across stages. Framer Motion's shared-layout (FLIP) algorithm computes the layout-to-layout delta automatically — no keyframes, no per-property animate props, no easing math.
// stages.ts (excerpt — written by the composer)
export const STAGES: Stage[] = [
{
id: 'hook',
elements: {
wordmark: { pos: { left: '50%', top: '50%', width: '20%' }, shape: 'wordmark' },
slack: { pos: { left: '12%', top: '24%' }, shape: 'connectorChip' },
drive: { pos: { left: '88%', top: '24%' }, shape: 'connectorChip' },
},
},
{
id: 'reveal',
elements: {
wordmark: { pos: { left: '50%', top: '14%', width: '12%' }, shape: 'wordmark' },
slack: { pos: { left: '20%', top: '60%' }, shape: 'connectorChip' },
drive: { pos: { left: '80%', top: '60%' }, shape: 'connectorChip' },
cylinder: { pos: { left: '50%', top: '50%' }, shape: 'cylinder' },
},
},
];
When the deck advances from hook → reveal, the wordmark shrinks and slides to the top. The Slack and Drive chips drift outward and down. The cylinder fades in. All in one synchronized 700 ms transition. No code per element.
For 30-second-style films, the composer enforces the principles in plugin/docs/cinematic-launch-video-lessons.md. Every rule there was earned by shipping the hero film above and getting each detail wrong before getting it right:
elapsedMs. Phases are non-overlapping windows; 350 ms cross-fade smear cuts at boundaries.aeBounce easing for any element that lands with weight (Dan Ebberts' AE bounce ported to TypeScript).stoppedSfxRef: Set<number> ensures each cue's stopAtMs runs exactly once. Without it, when multiple cues share an audio file via the pool, the first cue's stop check re-fires every frame and pauses every later cue. This was the single most painful bug in the build.-ss seek-mode trap — input-seek (-ss before -i) when trimming with afade; output-seek can produce silent files that pass duration checks.?dev=1 so a reviewer can give you precise timestamp feedback during iteration.Generate any of these with /cinemorph new --from-example <name>:
| Example | Description |
|---|---|
launch-cinematic-30s | The canonical 30-second film shown above. RAF-clock driven, audio bus wired, dev scrubber, autoplay gate. |
stacklink-roundone-pitch | The 5-slide investor pitch shown above. |
pitch-5slide | Generic investor deck (Problem, Solution, Traction, Team, Ask). |
feature-demo | 4–6-slide feature walkthrough. |
kpi-dashboard-tour | Live-data dashboard tour with morphing kpi tiles. |
case-study | Customer success story format. |
manifesto | Vision / principles statement deck. |
team-intro | Team introduction with morphing pillar cards. |
release-notes | Engineering release-notes deck. |
roadmap | Quarterly roadmap with morphing milestone tiles. |
retro-storyboard | Retrospective / post-mortem storyboard. |
custom-element | Reference for adding your own primitive. |
Each example ships its own README.md, brief.md, stages.ts, data.ts, and tokens.ts — read them as documentation by example.
Five built-in themes cover most needs:
| Theme | Mood |
|---|---|
stacklink-dark | Near-black canvas, monochromatic, EU-enterprise restraint |
bunq-mint-light | Mint green + white, fintech, modern |
linear-light | Slate + blue, minimal, technical |
minimal-mono | Black + white + grays, typographic, editorial |
playful-poster | Vibrant multi-color, creative, event-driven |
Override with your own tokens:
/cinemorph new --tokens ./my-tokens.json --prompt "Q1 product all-hands"
// my-tokens.json
{
"background": "#09090F",
"foreground": "#FAFAFA",
"mutedForeground": "#A1A1AA",
"border": "#27272A",
"fontDisplay": "Space Grotesk, Inter, sans-serif",
"fontBody": "Inter, sans-serif",
"fontMono": "JetBrains Mono, monospace"
}
Or extract a palette from a brand screenshot:
/cinemorph new --reference ./brand-screenshot.png --prompt "Series B pitch"
Wordmark · KPI · Pillar · Quote · ConnectorChip (Slack, GitHub, Notion, Linear, Confluence, Jira, OneDrive, Teams, Salesforce, Drive) · Card · Logo · Image · Diagram · Icon · Chart · MorphChart · OrbitGroup · PipelineGroup · FooterStrip · StatGroup
Turn a one-line idea into a branch with tested, reviewed, committed code. The brainstorm-to-commit pipeline for Claude Code.
FAQ
cinemorph is a Claude Code plugin with 1 hand-picked skill for marketing work, indexed on Flowy. Install it with the command on its page. It includes morph-deck. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it