fix(skills): force figma.com sources through /figma, not raw MCP tools

Two real incidents this week had agents skip /figma entirely and drive
Figma via raw MCP tools (get_metadata/get_screenshot/get_design_context)
when a figma.com URL landed inside a creation-workflow skill. Root cause:
none of the creation workflows mention Figma at all, and the only routing
table that does (/hyperframes) is skipped whenever a workflow is invoked
directly rather than through the entry router — which is the common path.

Going raw loses real infrastructure the CLI/skill guarantees: sanitizeSvg()
before freezing (raw-fetched SVGs are unsanitized), .media/manifest.jsonl
provenance (no cache-hit, no version tracking), and brand-token var()
binding (colors bake as literals, so a later Figma brand change can't
propagate without a full re-import).

Added a "figma source" callout to every creation workflow that could
plausibly receive a figma.com link (product-launch-video, website-to-video,
general-video, motion-graphics, slideshow), plus a defense-in-depth line
in /hyperframes's own routing checklist. The fix lives in the workflows
themselves so it doesn't depend on the entry router being consulted.

Co-Authored-By: Claude Opus <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-07-09 19:35:22 -07:00
co-authored by Claude Opus
parent c8eff1a4ba
commit d13c96d470
7 changed files with 17 additions and 6 deletions
+6 -6
View File
@@ -14,11 +14,11 @@
"files": 2 "files": 2
}, },
"general-video": { "general-video": {
"hash": "e26710c3537b3a07", "hash": "67f3dae100541eed",
"files": 1 "files": 1
}, },
"hyperframes": { "hyperframes": {
"hash": "7ddbb928a3674e5e", "hash": "132596767485f923",
"files": 1 "files": 1
}, },
"hyperframes-animation": { "hyperframes-animation": {
@@ -50,7 +50,7 @@
"files": 113 "files": 113
}, },
"motion-graphics": { "motion-graphics": {
"hash": "96ed2f7d8051b009", "hash": "0f1ac928e387a74c",
"files": 23 "files": 23
}, },
"music-to-video": { "music-to-video": {
@@ -62,7 +62,7 @@
"files": 22 "files": 22
}, },
"product-launch-video": { "product-launch-video": {
"hash": "4f858cc4d59324da", "hash": "937dcd6c581fb054",
"files": 20 "files": 20
}, },
"remotion-to-hyperframes": { "remotion-to-hyperframes": {
@@ -70,7 +70,7 @@
"files": 70 "files": 70
}, },
"slideshow": { "slideshow": {
"hash": "19a0332616bc397b", "hash": "114b57cf22b39068",
"files": 2 "files": 2
}, },
"talking-head-recut": { "talking-head-recut": {
@@ -78,7 +78,7 @@
"files": 27 "files": 27
}, },
"website-to-video": { "website-to-video": {
"hash": "32bdb559f4d18f99", "hash": "79af52a847abaa43",
"files": 32 "files": 32
} }
} }
+2
View File
@@ -12,6 +12,8 @@ metadata: { "tags": "orchestrator, general-video, fallback, freeform, compositio
> **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill. > **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill.
> **figma source**: If any input is a figma.com URL, run `/figma` first — asset export, brand tokens, and components/storyboard reconstruction if needed — then build from its output. Don't drive Figma via raw MCP tools directly: that skips SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding, so a later brand change can't propagate without a full re-import.
# general-video — general video workflow # general-video — general video workflow
> **Confirm the route before you build.** This is the **fallback** for custom composition authoring. If the input clearly fits a specialized workflow, prefer it: marketed product → `/product-launch-video`; general site → `/website-to-video`; topic explainer → `/faceless-explainer`; GitHub PR → `/pr-to-video`; existing footage → `/embedded-captions` · `/talking-head-recut`; short unnarrated motion graphic → `/motion-graphics`; Remotion port → `/remotion-to-hyperframes`. **Out of scope**: live / at-render-time data, NLE-style editing of a finished video, or producing footage HyperFrames can't capture. Unsure? **Read `/hyperframes` first.** > **Confirm the route before you build.** This is the **fallback** for custom composition authoring. If the input clearly fits a specialized workflow, prefer it: marketed product → `/product-launch-video`; general site → `/website-to-video`; topic explainer → `/faceless-explainer`; GitHub PR → `/pr-to-video`; existing footage → `/embedded-captions` · `/talking-head-recut`; short unnarrated motion graphic → `/motion-graphics`; Remotion port → `/remotion-to-hyperframes`. **Out of scope**: live / at-render-time data, NLE-style editing of a finished video, or producing footage HyperFrames can't capture. Unsure? **Read `/hyperframes` first.**
+1
View File
@@ -47,6 +47,7 @@ This section knows only the top-level workflows; it does not load their internal
Routing needs to know **what the video is about** — its input and subject. If that's unspecified ("make a video about our thing" with no URL, product, topic, or asset), ask before entering any workflow — committing to a workflow IS the routing decision. At most two questions: Routing needs to know **what the video is about** — its input and subject. If that's unspecified ("make a video about our thing" with no URL, product, topic, or asset), ask before entering any workflow — committing to a workflow IS the routing decision. At most two questions:
- **Input** — a product (URL / brief), a general website, a GitHub PR, a topic to explain, or an existing talking-head video? - **Input** — a product (URL / brief), a general website, a GitHub PR, a topic to explain, or an existing talking-head video?
- **Figma source** — if the input is a figma.com URL, `/figma` extracts assets/tokens/(components/storyboard) first, regardless of which workflow below is chosen for the video's shape; that workflow then builds from `/figma`'s output — never by driving Figma via raw MCP tools directly (skips SVG sanitization, provenance, and brand-token binding).
**Mode** — if the request carries an ongoing autonomous signal ("surprise me", "decide for me", "just build it"), note it and pass it into the workflow: the whole run goes autonomous and no later step re-asks. With no signal, the workflow asks the mode as its first brief question. Default is collaborative. (`/motion-graphics` is autonomous by design.) Semantics: `hyperframes-core``references/brief-contract.md`. **Mode** — if the request carries an ongoing autonomous signal ("surprise me", "decide for me", "just build it"), note it and pass it into the workflow: the whole run goes autonomous and no later step re-asks. With no signal, the workflow asks the mode as its first brief question. Default is collaborative. (`/motion-graphics` is autonomous by design.) Semantics: `hyperframes-core``references/brief-contract.md`.
+2
View File
@@ -17,6 +17,8 @@ metadata:
> **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update motion-graphics`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them. > **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update motion-graphics`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them.
> **figma source**: If the logo/asset/animation to build from comes from a figma.com URL, run `/figma` first — asset export, brand tokens, and Motion→GSAP translation if the graphic is a Figma Motion import — then build from its output. Don't drive Figma via raw MCP tools directly: that skips SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding, so a later brand change can't propagate without a full re-import.
# motion-graphics — dispatch entry # motion-graphics — dispatch entry
> **Confirm the route before Step 0.** This skill makes a **short, design-led, unnarrated motion graphic** (motion is the message; ~under 10s, no voice-over). A **longer, multi-scene, or narrated** treatment → `/general-video`; a **narrated video of a website** → `/website-to-video`; a **topic explainer** → `/faceless-explainer`; a **product promo** → `/product-launch-video`; **captions on existing footage** → `/embedded-captions`. **Out of scope**: live / at-render-time data, or footage it can't capture. Unsure motion-first-vs-narrated? **Read `/hyperframes` first.** > **Confirm the route before Step 0.** This skill makes a **short, design-led, unnarrated motion graphic** (motion is the message; ~under 10s, no voice-over). A **longer, multi-scene, or narrated** treatment → `/general-video`; a **narrated video of a website** → `/website-to-video`; a **topic explainer** → `/faceless-explainer`; a **product promo** → `/product-launch-video`; **captions on existing footage** → `/embedded-captions`. **Out of scope**: live / at-render-time data, or footage it can't capture. Unsure motion-first-vs-narrated? **Read `/hyperframes` first.**
+2
View File
@@ -7,6 +7,8 @@ description: "Turn a product or marketing URL, pasted script, or brief into a pr
> **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill. > **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill.
> **figma source**: If the source is a figma.com URL, run `/figma` first — asset export, brand tokens, and components/storyboard reconstruction if needed — then build this workflow from its output. Don't drive Figma via raw MCP tools directly: that skips SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding, so a later brand change can't propagate without a full re-import.
# Product Launch to HyperFrames # Product Launch to HyperFrames
Use this skill to capture a product, understand its brand, plan a launch video, and build it frame by frame in HyperFrames. Use this skill to capture a product, understand its brand, plan a launch video, and build it frame by frame in HyperFrames.
+2
View File
@@ -11,6 +11,8 @@ description: >
> **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update slideshow`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them. > **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update slideshow`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them.
> **figma source**: If the deck's content or storyboard comes from a figma.com URL, run `/figma` first — asset export, brand tokens, and storyboard reconstruction if the source is a strip of scene frames — then build from its output. Don't drive Figma via raw MCP tools directly: that skips SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding, so a later brand change can't propagate without a full re-import.
# Slideshow authoring contract # Slideshow authoring contract
A HyperFrames slideshow is a normal HyperFrames composition — scenes, clips, GSAP timelines — with one extra ingredient: a **JSON island** that declares which scenes are slides and how they connect. The player's `SlideshowController` reads the island and turns the continuous GSAP timeline into a discrete, navigable deck. A HyperFrames slideshow is a normal HyperFrames composition — scenes, clips, GSAP timelines — with one extra ingredient: a **JSON island** that declares which scenes are slides and how they connect. The player's `SlideshowController` reads the island and turns the continuous GSAP timeline into a discrete, navigable deck.
+2
View File
@@ -7,6 +7,8 @@ description: "Capture a general website/URL and turn it into a video OF the site
> **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill. > **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill.
> **figma source**: If the URL is a figma.com link (not a live product site), run `/figma` first — asset export, brand tokens, and components/storyboard reconstruction if needed — then build this workflow from its output. Don't drive Figma via raw MCP tools directly: that skips SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding, so a later brand change can't propagate without a full re-import.
# Website to HyperFrames # Website to HyperFrames
Capture a website, then produce a professional video from it. Capture a website, then produce a professional video from it.