figma-to-weaverse — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited figma-to-weaverse (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Turn a Figma design into maintainable Weaverse pages. This is the Figma input adapter — the sibling of cloning-websites-to-weaverse, but the source is a Figma file instead of a live URL. Both adapters converge on the same downstream skill, generating-weaverse-project-json.
Figma file / frame ─→ figma-to-weaverse ─→ generating-weaverse-project-json ─→ import / content API
(Figma MCP) (tokens + manifest + preview) (project JSON)The two adapters share the same downstream rules. Section matching, deep schema verification, the content manifest, the clone preview route, and the brand-guideline conflict rule are identical to cloning-websites-to-weaverse — read that skill for the full matching logic. This skill only replaces the extraction layer (Figma MCP instead of Firecrawl) and adds Figma-specific gotchas.
Do not use it for live-website cloning (use cloning-websites-to-weaverse) or tiny copy edits.
.guides/brand-guideline.mdsections.mdapp/weaverse/components.tsWEAVERSE_API_KEY (see weaverse-content-api)Each of these cost a full rework loop when skipped:
INDEX), a landing page (CUSTOM, e.g. /disney), or a per-resource template (COLLECTION/PRODUCT for one handle). It decides which sections are allowed (enabledOn) and how data loads. Don't infer it from the nav link.PUBLIC_STOREFRONT_ID in .env must match the storefront in .shopify/project.json. A mismatched .env renders another brand's sales channel locally, and published collections look missing. Fix with npx shopify hydrogen env pull..guides/brand-guideline.md describes this brand (repos are often cloned from a sibling brand). If it doesn't, follow the Figma tokens, say so in the spec, and ask the user to replace the guideline.pages <projectId>): empty COLLECTION/PRODUCT templates render header + footer only on those routes — flag it, it is not caused by your page..figma/*.md specs in the repo; header/footer/menu work and token decisions may already exist.Same three deliverables as the website cloning skill, plus the live page:
$page branch in app/routes/clone-preview.$page.tsx rendering the full design as React + Tailwind, section-marked, brand-adjusted. User must approve this before section decomposition..clone/<page>/..figma/<page>.visual.json + Figma reference screenshots (blocks and interaction states) in .figma/ref/<page>/, and a final scripts/visual_check.mjs report that says Result: PASS (exceptions listed), including every hover and click interaction. The page is not done without it.Use the Figma MCP tools. They return structured design data — more precise than scraped HTML for tokens and layout, but weaker on real interaction (a static design has no runtime behavior).
Loadfigma-design-to-codebeforeget_design_context, andfigma-usebefore anyuse_figmawrite call.
data-development-annotations (semantics: H1/H2/H3, "not a heading, it's a link") and data-interaction-annotations (menus, link targets, hover behavior). Extract every one into an annotation table in the spec and map each to a requirement — they are easy to lose in a long response. Figma comments are not readable through MCP; ask the user for them if they matter.get_variable_defs when the file uses variables; otherwise use the style list at the end of the get_design_context response. Map them into project.config.theme only for sitewide values; page-specific colors stay as section settings.get_metadata only to orient (pick nodes, find frames). Section boundaries are the top-level frames in the design context.get_metadata / search_design_system locate the set node), then get_context_for_code_connect on the set lists its variant properties, e.g. State=Default|Hover|Pressed|Active|Disabled. Read Default first, then Hover, then click states (pressed/active/open/selected): get_design_context on each variant node for the exact deltas (colour, underline, border, shadow, scale, swapped icon, revealed child), and get_screenshot → .figma/ref/<page>/<interaction>.png as the state reference. If MCP can't resolve the main component, read it with a read-only use_figma script (getMainComponentAsync(), the set's variantGroupProperties, the instance's prototype reactions such as ON_HOVER → CHANGE_TO); load figma-use first.data-interaction-annotations / development annotations on the node or its section (hover menus and their items, link targets, "opens drawer").Grows Upward — Demo (hover to test), Carousel Demo, Sort Dropdown) only tell you where to look; they are not a behaviour spec. Mark the element UNCONFIRMED in the interaction table and ask the user to confirm the behaviour (batch the questions, at the latest at the approval checkpoint), offering "static" as an option. Build no behaviour for it until answered.Interaction table columns: element, trigger (hover / click), evidence (variant: <component> State=Hover (<nodeId>) / annotation: <text> / user: <answer, date> / UNCONFIRMED), expected outcome, state reference image. Every confirmed row becomes an interactions entry in the visual spec (step 11).
figma.com/api/mcp/asset/...). They expire after ~7 days. Download the bytes early; inspect them (some are flat color SVGs, decorative masks, or images meant to be shown flipped/cropped).$00.00, stray labels outside the canvas. Mark them MISSING/placeholder in the manifest and map the block to real data (collection products, Instagram feed) instead of reproducing the placeholders.If the MCP can't reach the file or can't export a specific asset (e.g. a flattened group, an unusual export setting), fall back to a Figma agent plugin export and read its output file. MCP is the primary path; use the plugin only to fill a concrete gap, and note in the manifest which assets came from the fallback.
.guides/brand-guideline.md; ensure sections.md is current..figma/<brand>-<page>.md (token table, annotation table, interaction table, content manifest, gaps). While the node ids are at hand, save a Figma screenshot of every block frame to .figma/ref/<page>/<block>.png and of every interaction state variant to .figma/ref/<page>/<interaction>.png (get_screenshot → curl; the URLs are short-lived). These are the visual-check references.app/routes/clone-preview.$page.tsx — one $page branch per page, React + Tailwind, real Figma assets, {/* === BLOCK NAME === */} markers. Header/footer are not part of it.npm run dev, not a guessed one) + block count, brand overrides, gaps, and the UNCONFIRMED interaction questions. Iterate until the user approves and every interaction row has evidence.weaverse-content-api → upload. Keep the returned media objects in .clone/<page>/shopify-assets.json. Never ship Figma asset URLs.enabledOn against the page type from preflight.sections.md/shared files outside their task, no build/format runs; the integrator owns registration, docs, lint and build.sections.md, run the formatter on changed files only, typecheck and compare against the pre-change error baseline, build the way CI builds.generating-weaverse-project-json (Shopify media objects, no default values, presets written explicitly), validate it.weaverse-content-api): create-page for CUSTOM/template pages (INDEX already exists), then one PATCH that relinks the root main and creates every item. Sitewide values go through theme-update (back up the old values first); menus go through the admin proxy (menuUpdate, back up the old menu). If the page needs code that isn't deployed yet, deploy right after (or tell the user the live page is broken until then)..figma/<page>.visual.json: one block per section ([data-wv-id] selector + reference image; mode: "structure" with a note only for data-driven or placeholder blocks) and one interactions entry per confirmed interaction-table row (hover or click, its evidence as source, the expected outcome, the state reference). Run node <this skill>/scripts/visual_check.mjs .figma/<page>.visual.json from the storefront repo. Spec format, setup and the fix playbook: references/visual-check.md.report.md; for every ❌ open the screenshot, the reference and the .diff.png (or the interaction's problem list), fix one cause (section settings via Content API, or section code), re-run with --only <block-or-interaction>. Repeat until the full run prints Result: PASS on desktop and mobile.structure to hide a real design difference.url change, load more expects the new items visible. Still count products in the rendered DOM, not in loader JSON.--url https://<storefront>/<path>)..figma/visual/ output can stay untracked), push, watch the deploy workflow of this storefront (sibling-brand workflows in the same repo may fail for unrelated reasons). Report the final visual-check result, the accepted exceptions, and what Studio still needs (page SEO, missing collections/links, unpublished resources).| Aspect | Website (Firecrawl) | Figma (MCP) |
|---|---|---|
| Design tokens | inferred from CSS/computed styles | explicit via get_variable_defs — map directly to theme |
| Section boundaries | HTML section markers, slider/grid classes | top-level frames / auto-layout containers from get_metadata |
| Composition | read from HTML positioning | read from auto-layout direction/wrap/spacing |
| Assets | image/video URLs in HTML | download_assets exports; no real video src |
| Interaction | real runtime behavior in HTML | none at runtime — read component state variants first, then annotations; ask the user when neither exists. Never derive behaviour from layer names |
| Responsive variants | <picture> / breakpoint classes | separate desktop/mobile frames if the designer made them; otherwise one frame |
Carousel Demo or hover to test are a pointer, not evidence. Don't classify a frame as a slider just because it shows multiple cards.get_variable_defs is the cleanest token source you'll ever get. Hardcoding colors/sizes when variables exist throws away the main Figma advantage.download_assets; mark MISSING — [describe] in the manifest when an export fails, don't substitute a placeholder.cloning-websites-to-weaverse. Follow them; don't reinvent a looser version.imageMobile/imageDesktop or breakpoint logic, not separate pages.interactions entry in the visual spec, so a regression fails the run.npm run dev; the old process can keep serving previous item data under the same ids.no clipped rounded elements ❌. Run the loop to PASS, desktop and mobile.threshold, deleting a block, or marking it structure to make a real difference go away.cloning-websites-to-weaverse — the website input adapter; owns the shared section-matching, manifest, and preview rules this skill reuses.generating-weaverse-project-json — downstream; turns this skill's spec + manifest + token table into import-ready JSON.weaverse-content-api — push or update content into the live project after import.figma-use / figma-generate-design — Figma MCP plugin skills; load figma-use before any use_figma write call.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.