From bridge-ds
Generates Figma components or screens by compiling a CSpec into a scene graph and executing it via MCP. Use when the user asks to make, design, or build new UI in Figma.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bridge-ds:generating-figma-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
{{ACTIVE_RULES}}
{{ACTIVE_RULES}}
Unified make flow: CSpec → scene graph → compiler → Figma execute → screenshot → verify. Replaces the legacy spec → design → review cycle with a single compiler-driven action. All tokens resolve against the knowledge base; all Figma API rules are enforced by the compiler.
Invoke when the user:
make, design, create, build, generate, or asks for a "new component" / "new screen"setup (knowledge base exists)Do NOT use if:
learning-from-corrections insteadshipping-and-archivingextracting-design-system firstBefore starting, load:
references/compiler-reference.md (repo-root) — scene graph JSON format and rulesreferences/transport-adapter.md (repo-root) — transport detection and tool mappingsetup first"references/transport-adapter.md (repo-root) Section A)Read references/transport-adapter.md (repo-root) Section A. Determine console vs official transport.
Console: figma_get_status() -> setup.valid: true
Official: whoami() + test use_figma call
Report:
Transport: {console | official}
Load the summary of available DS components — names and types only, not full registry data:
registries/components.json — extract component names, variant property names, and keysregistries/variables.json — extract variable name paths (for token reference validation)registries/text-styles.json — extract style names (for $text/ reference validation)registries/icons.json — extract icon names (if file exists)registries/logos.json — extract logo names (if file exists)Do NOT load guides, patterns, or figma-api-rules.md. The compiler handles all Figma API rules.
The compiler guarantees every $token resolves against the KB — but NOT that the
KB still matches the live Figma library. A token removed/renamed in Figma but
still present in a stale KB will compile fine and then fail at execute time.
This check is a runtime guard; it deliberately lives here (not in the compiler),
because a time-based check would break the compiler's determinism law.
Read generatedAt from each loaded registry and compare to today's date:
generatedAt missing → STRONGLY warn and recommend re-running
setup (or the KB cron) before generating: resolved tokens that were removed or
renamed in Figma will pass compile but fail on execute.Carry the KB age into the C4 plan ("KB age: {N}d"). This does not block generation
— it informs the user before they commit to a make.
Load knowledge-base/learnings.json (skip if file doesn't exist).
Filter by context matching the user's description:
scope: "global")context.screenType or context.component matchesLoad knowledge-base/recipes/_index.json (skip if file doesn't exist — no recipes yet).
From the user's description, identify:
For each recipe in _index.json, compute a match score:
| Dimension | Weight | Method |
|---|---|---|
| Archetype match | 0.40 | Exact match on meta.archetype vs extracted archetype |
| Tag overlap | 0.25 | Jaccard similarity between recipe tags and extracted keywords |
| Structural match | 0.20 | Zone count, component types, parameter compatibility |
| Confidence | 0.15 | Recipe's current confidence score |
| Score | Action |
|---|---|
| >= 0.85 | Exact match. Load recipe file, pre-fill CSpec from recipe parameters. Report: "Recipe match: {name} (score: {score}). Using as template." |
| 0.60 -- 0.84 | Partial match. Load recipe as scaffold. Report: "Partial recipe match: {name} (score: {score}). Using as starting point, will supplement missing zones." |
| < 0.60 | No match. Proceed from scratch. Report: "No recipe match. Generating from scratch." |
Before writing any node, break the request into its major sections, then decide HOW each section is built. This is where DS fidelity and composition are won.
1. Decompose the request into major sections, top to bottom:
2. Classify each section into exactly one bucket — this decides INSTANCE vs build:
exact — a published DS component (or one of its variants) covers the whole
section → one INSTANCE node; set its variant + properties. Preferred.compose — no single component fits, but the section is built from DS pieces
(component INSTANCEs inside tokenized FRAMEs) → never raw shapes with hardcoded
values.new — no DS component covers it and it is not composable from existing ones
→ hand to C3 (new_components); the component is built first.Default preference: exact > compose > new. A raw RECTANGLE/ELLIPSE whose
name matches a DS component is a red flag — the compiler warns (Rule 18); use an
INSTANCE instead.
Report the section map before C1:
SECTIONS:
{Section} → {exact: Component(variant) | compose | new: name}
Choose the appropriate template:
skills/generating-figma-design/references/templates/screen-cspec.yamlskills/generating-figma-design/references/templates/component-cspec.yamlFill the CSpec based on:
If a recipe was matched (>= 0.60):
graph structure{{ param }} placeholders with values from the user's description@lookup:ComponentName references against the live registryIf no recipe match (from scratch):
$token references for all spacing, colors, radius, typography — and pick
the most specific token that carries intent. When collections alias each
other (primitive ← semantic ← component), reference the most specific one:
prefer a semantic token ($color/bg/...) over a raw palette value, and a
component-level token over a semantic one when it exists. Never reference a
primitive when a semantic/component token expresses the same intent — a
primitive ignores theme/mode switches.Integrate learnings from A3 into the CSpec:
scope: "global"): auto-apply — replace default token values with learned preferencesscope: "contextual"): suggest — note in comments, apply if context matchesReport applied learnings:
LEARNINGS APPLIED ({n}):
- {rule} (signals: {n}, scope: {scope})
- {rule} (signals: {n}, scope: {scope})
Take the sections C0 classified as new (the patterns no existing DS component
covers and that are not composable from existing ones). Add each to the
new_components section of the CSpec. Sections classified exact become INSTANCE
nodes; sections classified compose become FRAMEs of INSTANCEs — neither reaches
this step.
If new components are identified:
{N} new DS component(s) needed:
1. {name} — {description}
These must be created before this screen. Starting with: {name}
-> Trigger a nested make flow for each new component. When all are done, resume the screen make.
Show a readable summary of the CSpec (NOT raw YAML). Format as a plan tree:
PLAN: {name}
Mode: {screen | component}
Canvas: {1440px (web) | 390px (mobile) | 1024px (tablet)}
Recipe: {recipe name or "from scratch"}
Learnings: {n} applied
KB age: {N}d{ ⚠ stale — consider `setup` if > 30d}
STRUCTURE:
Root ({width}x{height}, {layout direction})
+-- {Zone 1} ({width}, {layout})
| +-- {Component} ({variant})
| +-- {Component} ({variant})
+-- {Zone 2} ({fillH}, {layout})
| +-- {Section 1}
| | +-- {Component} ({variant})
| +-- {Section 2}
| | +-- REPEAT x{n}: {Component}
DS COMPONENTS: {n} instances
TOKENS: {n} references
STATES: {list or "populated only"}
Generate this design?
Wait for explicit user confirmation. The user can:
Save the CSpec YAML to specs/active/{name}.cspec.yaml.
Transform the CSpec's layout tree into the scene graph JSON format defined in references/compiler-reference.md (repo-root):
layout nodes map directly to scene graph nodes$token references are preserved (the compiler resolves them)Add the root wrapper:
{
"version": "3.0",
"metadata": {
"name": "{CSpec meta.name}",
"width": {CSpec meta.width},
"height": {CSpec meta.height},
"transport": "{detected transport}",
"fileKey": "{user's file key}"
},
"fonts": [ ... ],
"nodes": [ ... ]
}
Font list: Collect all unique font families and styles referenced by $text/ tokens in the scene graph. Cross-reference against registries/text-styles.json to get actual font family + style values.
# Write JSON to temp file
cat > /tmp/bridge-scene-{name}.json << 'EOF'
{ ... scene graph JSON ... }
EOF
bridge-ds compile \
--input /tmp/bridge-scene-{name}.json \
--kb {kb-path} \
--transport {console|official}
The compiler outputs a JSON array of { id, code, description } chunks to stdout.
If the compiler returns errors to stderr:
references/compiler-reference.md (repo-root) Section 8 for common errors)For each output chunk from the compiler:
Console transport:
figma_execute({ code: "{chunk.code}" })
Official transport:
use_figma({
fileKey: "{fileKey}",
description: "{chunk.description}",
code: "{chunk.code}"
})
Execute chunks sequentially. If a chunk fails:
Take a screenshot AFTER the final chunk (not after each chunk):
Console: figma_take_screenshot({ node_id: "{rootNodeId}", file_key: "{fileKey}" })
Official: get_screenshot({ nodeId: "{rootNodeId}", fileKey: "{fileKey}" })
Save a snapshot of the design's node tree for future fix diffing.
Run a node tree extraction script via figma_execute (or use_figma), using the root node ID from D5.
Save to specs/active/{name}-snapshot.json:
{
"meta": {
"spec": "{name}",
"generatedAt": "{ISO timestamp}",
"rootNodeId": "{rootId}",
"fileKey": "{fileKey}",
"recipe": "{recipe ID or null}",
"learningsApplied": ["{learning IDs}"]
},
"tree": { ... extracted node tree ... }
}
Display the screenshot taken in D6.
Design compiled and executed.
File: {figma_url}
Created:
- {n} component instances
- {n} bound variables (colors + spacing + radius)
- {n} learnings applied
- Recipe: {recipe name or "from scratch"}
- Chunks: {n} executed
Warnings:
- {any issues}
Looks good? Options:
- Describe changes -> I'll modify and recompile
- "I adjusted in Figma" -> triggers fix flow
- "done" / "ship it" -> triggers done flow
Trigger the fix flow via the learning-from-corrections skill.
Trigger the done flow via the shipping-and-archiving skill.
| Turn | Action |
|---|---|
| 1 | Phase A (context load) + Phase B (recipe match) |
| 2 | Phase C (CSpec generation, present plan to user) |
| 3 | User confirms or adjusts |
| 4 | Phase D (compile + execute all chunks) |
| 5 | Phase E (screenshot, report, offer next step) |
| 6+ | Iteration loop (if changes requested) |
Target: 5 turns for a first-pass generation. Each iteration adds 2-3 turns.
In v3, Claude NEVER writes raw Figma Plugin API scripts. The workflow is:
Claude produces scene graph JSON
-> Compiler resolves tokens, validates structure, generates code
-> Code chunks are executed via MCP
NOT:
Claude writes figma_execute scripts directly
This means:
figma-api-rules.mdThe only time Claude touches raw Plugin API code is:
NEVER write raw Figma Plugin API code. All scene graphs go through
lib/compiler/compile.ts (shipped as bridge-ds compile).
NEVER use hardcoded primitive values in the scene graph. Only
$token references.
See the full catalog at references/red-flags-catalog.md (repo-root).
Top flags for this skill:
This skill is gated by references/verification-gates.md (repo-root):
figma_execute / use_figma.Evidence to surface: compiler stdout, scene graph JSON, screenshot tool result, user confirmation text.
./references/templates/component-cspec.yaml — CSpec template for components./references/templates/screen-cspec.yaml — CSpec template for screensdigraph make_flow {
"User says 'make X'" [shape=doublecircle];
"Load context (recipes, learnings)" [shape=box];
"Generate CSpec" [shape=box];
"Compile" [shape=box];
"Compile exit 0?" [shape=diamond];
"Surface compile error" [shape=box style=filled fillcolor=lightcoral];
"Execute via MCP" [shape=box];
"Screenshot" [shape=box];
"User satisfied?" [shape=diamond];
"Gate A passed" [shape=doublecircle style=filled fillcolor=lightgreen];
"Capture intent diff" [shape=box];
"User says 'make X'" -> "Load context (recipes, learnings)";
"Load context (recipes, learnings)" -> "Generate CSpec";
"Generate CSpec" -> "Compile";
"Compile" -> "Compile exit 0?";
"Compile exit 0?" -> "Surface compile error" [label="no"];
"Surface compile error" -> "Generate CSpec";
"Compile exit 0?" -> "Execute via MCP" [label="yes"];
"Execute via MCP" -> "Screenshot";
"Screenshot" -> "User satisfied?";
"User satisfied?" -> "Gate A passed" [label="yes"];
"User satisfied?" -> "Capture intent diff" [label="no"];
"Capture intent diff" -> "Generate CSpec";
}
npx claudepluginhub noemuch/bridge --plugin bridge-dsOrchestrates multi-phase Figma design system builds from code, creating variables, tokens, and component libraries with variant bindings and theming.
Designs UI/UX systems with style guides, color palettes, typography, and component specs for new interfaces. Asks about product type, tech stack, and deliverables before producing design tokens, layouts, or style guides.
Creates UI/UX designs, wireframes, and design systems. Guides user research, WCAG accessibility, Figma workflows, and Storybook integration.