Structured interview that auto-discovers Figma file structure, project context, and asks 3-5 targeted questions to produce a build-spec.json. Entry point for the autonomous build pipeline. Keywords: Figma intake, build spec, project discovery, figma interview, build plan
Scanned 9/13/2026
Install to Claude Code
npx -y skills add PMDevSolutions/Aurelius --skill figma-intake --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Figma Intake?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/pmdevsolutions-figma-intake)More formats (shields.io, HTML) on the badges page.
---
name: figma-intake
description: Structured interview that auto-discovers Figma file structure, project context, and asks 3-5 targeted questions to produce a build-spec.json. Entry point for the autonomous build pipeline. Keywords: Figma intake, build spec, project discovery, figma interview, build plan
---
# Figma Intake — Structured Discovery
## Purpose
Gather everything needed to build a React app from a Figma design in a single structured pass. Auto-discovers what it can, asks the user only what it must, and outputs a machine-readable `build-spec.json` that downstream skills consume without re-asking questions.
## When to Use
- First phase of `/build-from-figma` pipeline
- Any time a user provides a Figma URL and wants to build from it
- When you need to understand a Figma file's structure before generating code
## Inputs
- **Required:** Figma file URL (with optional node-id)
- **Optional:** Existing project directory to integrate into
## Process
### Step 0: Conversation Fast-Path (Skip the Interview)
If `.claude/plans/build-spec.json` already exists with `"source": "conversation"`, the spec was produced by the `conversation-intake` skill and the Figma file was generated from it by `design-brief-to-figma` — the interview already happened in `/build-from-conversation`. Do **not** re-interview the user. Instead:
```
1. Verify the spec's figma block is populated (fileKey, url) and matches the
URL this skill was invoked with. Mismatch → ask which file wins.
2. Verify the file is reachable: get_metadata(fileKey).
3. Backfill any pages[].figmaNodeId that is still null from the metadata
(match generated frames to pages by name/order).
4. Keep "source": "conversation" unchanged — downstream phases treat the spec
exactly like a Figma-sourced one; the source value preserves provenance.
5. Expect no Figma variables in the generated file: token extraction
(design-token-lock) will fall back to computed styles, which is correct
here because the captured mockups were rendered from the design brief's
exact values.
6. Skip Steps 1-3 below entirely and proceed to Step 4 validation /
Step 5 confirmation only if the spec is incomplete; otherwise report
"fast-path: spec reused" and hand control back to the pipeline (Phase 2).
```
If the file at `figma.url` no longer exists, fall through to the normal flow below using the URL the user provided.
### Step 1: Auto-Discovery (No User Input)
Run these Figma MCP calls to gather context automatically:
```
1. get_metadata(fileKey) → File name, pages, frames, component counts
2. get_variable_defs(fileKey) → Design tokens (colors, typography, spacing)
3. get_screenshot(fileKey) → Visual overview of each page/top-level frame
```
Simultaneously scan the local project:
```
1. Detect framework via the renderer registry:
- Run: node scripts/renderer-registry.js detect . --json
- On { "renderer": "<name>", "language": "<lang>" }:
set build-spec renderer = <name>
set build-spec outputTarget = <language> (react | vue | svelte | react-native)
- On { "renderer": null }:
no framework detected → New project needed (ask output target question)
Do not hand-sniff config files or package.json deps; the registry owns detection.
2. Detect app type:
- manifest.json with "manifest_version" → Chrome Extension
- manifest.json with "start_url" or "display" → PWA
- Otherwise → Web App
3. Scan existing components:
- Glob: src/components/**/*.tsx, app/components/**/*.tsx
- Build inventory: name, props interface, file path
4. Check package.json for UI libraries:
- @shadcn/ui, @radix-ui/*, @headlessui/react
- tailwindcss, @emotion/*, styled-components
- State: zustand, jotai, @tanstack/react-query
5. Check for existing design tokens:
- tailwind.config.ts theme.extend
- src/styles/tokens.css or similar
- design-tokens.lock.json (from prior runs)
6. Load pipeline config:
- Read .claude/pipeline.config.json for thresholds and app type definitions
- Use appTypes[detected] for E2E strategy defaults
```
### Step 2: Compile Discovery Summary
Present findings to the user in a structured format:
```
## Figma File: [name]
- Pages: [list with frame counts]
- Components: [count] unique components
- Design tokens: [count] variables defined
- Color modes: [list if any]
## Local Project
- Framework: [detected or "none"]
- Existing components: [count] in [path]
- UI library: [detected or "none"]
- Design tokens: [existing or "none"]
## Component Mapping
| Figma Component | Existing Match? | Action |
|----------------|-----------------|--------|
| Button/Primary | src/components/ui/Button.tsx | Reuse / Regenerate |
| Card | (none) | Generate new |
| ... | ... | ... |
```
### Step 3: Ask Targeted Questions (Max 5)
Only ask questions whose answers cannot be derived from the Figma file or local project. Skip any question where the answer is obvious from context.
**Question 1 — Scope:**
> Which pages/frames should I build? [Show numbered list from Figma]
> (Default: all top-level frames)
**Question 2 — Component Reuse:**
> I found [N] existing components that match Figma components. Should I:
> a) Reuse them and only generate missing ones
> b) Regenerate all from Figma (replaces existing)
> c) Generate alongside with new names (no overwrites)
> (Only ask if existing components were found)
**Question 3 — Business Logic:**
> Are there any interactions or business logic beyond what's visible in the design?
> (e.g., form validation rules, API calls, auth requirements, state machines)
> (Default: pure presentational)
**Question 4 — Text Content:**
> I extracted these labels/text from Figma. Confirm they're correct as-is?
> [Show condensed list of headings, button labels, placeholder text]
> (Default: use as-is)
**Question 5 — Integration:**
> Should this be:
> a) A standalone app (new project scaffold)
> b) Integrated into the existing project at [detected path]
> (Only ask if existing project detected)
**Question 6 — Output Target (only if no framework detected):**
> Run `node scripts/renderer-registry.js list --json` and present the returned
> renderer names as the choices (each entry has `name` and `language`):
> "Which renderer should I build this in? [numbered list of registry renderers]"
> - Greenfield React default: `vite`.
> - Set build-spec `renderer` = the chosen name and `outputTarget` = its `language`.
> (Skip if the registry already detected a framework for the existing project.)
**Question 7 — App Type (only if ambiguous):**
> I detected this as a [chrome-extension / web-app / pwa]. Is that correct?
> (Skip if detection is unambiguous. Skip if manifest.json clearly identifies type.)
### Step 4: Generate build-spec.json
Write the spec file that all downstream phases consume:
```jsonc
// .claude/plans/build-spec.json
{
"version": "1.0.0",
"source": "figma", // "figma" | "canva" | "screenshot" | "conversation"
"renderer": "vite", // registry renderer name (from `renderer-registry list`): "nextjs" | "vite" | "sveltekit" | "expo" | "astro" | ...
"outputTarget": "react", // resolved language; equals the renderer's language. "react" | "vue" | "svelte" | "react-native"
"createdAt": "2026-03-16T12:00:00Z",
"figma": {
"fileKey": "abc123",
"fileName": "My App Design",
"url": "https://figma.com/file/abc123/My-App-Design"
},
"appType": "web-app", // "web-app" | "chrome-extension" | "pwa"
"framework": {
"type": "vite", // DEPRECATED — superseded by top-level `renderer`. Retained for back-compat only.
"version": "6.0.0",
"outputDir": "src"
},
"styling": {
"approach": "tailwind", // "tailwind" | "css-modules" | "styled-components"
"uiLibrary": "shadcn", // "shadcn" | "radix" | "headless" | "none"
"existingTokens": false
},
"pages": [
{
"figmaNodeId": "1:2",
"name": "Home",
"route": "/",
"sections": ["hero", "features", "pricing", "footer"]
}
],
"components": [
{
"figmaNodeId": "3:45",
"figmaName": "Button/Primary",
"reactName": "Button",
"category": "ui", // "ui" | "layout" | "sections" | "pages"
"action": "generate", // "generate" | "reuse" | "extend"
"existingPath": null, // path if reusing
"variants": ["primary", "secondary", "outline"],
"props": ["variant", "size", "disabled", "children"]
}
],
"textContent": {
"hero-heading": "Build faster with AI",
"hero-subheading": "Ship production apps in days, not months",
"cta-primary": "Get Started",
"cta-secondary": "Learn More"
// ... all text extracted from Figma
},
"businessLogic": {
// User-provided requirements beyond the design
"forms": [],
"apiCalls": [],
"auth": null,
"stateManagement": null
},
"e2e": {
"strategy": "navigate-interact-verify", // From pipeline.config.json appTypes
"flows": [
{
"name": "page-navigation",
"description": "Navigate between all pages and verify rendering",
"steps": ["navigate to /", "verify hero section visible", "click nav link"]
}
],
// Chrome extension specific (when appType === "chrome-extension"):
"extensionManifest": {
"hasPopup": true,
"hasBackground": true,
"hasContentScript": true,
"contentScriptMatches": ["*://*.example.com/*"],
"permissions": ["storage", "activeTab"],
"buildCommand": "pnpm build",
"extensionPath": "dist"
}
},
"testStrategy": {
"unit": true, // Vitest + RTL for components
"e2e": true, // Playwright E2E
"visual": true, // Screenshot comparison
"crossBrowser": false, // Firefox + WebKit (web apps only)
"coverageThreshold": 80
},
"options": {
"componentReuse": "reuse", // "reuse" | "regenerate" | "alongside"
"integration": "existing" // "standalone" | "existing"
}
}
```
**Renderer fields:**
- `renderer` (string) is the authoritative framework field. Valid values are the renderer names from `node scripts/renderer-registry.js list --json` (currently `nextjs`, `vite`, `sveltekit`, `expo`, `astro`).
- `outputTarget` is retained and **equals the resolved renderer's `language`** (react / vue / svelte / react-native). Set both together from the registry `detect`/`resolve` output.
- `framework.type` is **deprecated** — folded into `renderer`. Keep it only for back-compat with older specs; `renderer` wins on any conflict.
- **Back-compat rule:** a build-spec carrying only `outputTarget` (no `renderer`) resolves to that language's DEFAULT renderer: `react → vite`, `svelte → sveltekit`, `react-native → expo`. (`vue` has no renderer yet — its default is unsupported/future.)
### Step 5: Confirm and Proceed
Present a summary of the build plan:
```
## Build Plan Summary
- Framework: Vite 6.0
- Pages: 3 (Home, Pricing, Dashboard)
- Components: 12 to generate, 4 to reuse
- Design tokens: 45 variables to extract
- Output: src/components/, src/pages/
Proceed with token extraction? (This starts the autonomous pipeline)
```
Wait for user confirmation before the pipeline continues.
## Output
**Primary:** `.claude/plans/build-spec.json`
**Secondary:** Build plan summary displayed to user
## Error Handling
- **Figma MCP unavailable:** Ask user to verify Figma Desktop is running or provide file key manually
- **No Figma variables defined:** Warn that token extraction will rely on computed styles (less accurate)
- **Ambiguous framework:** Ask user to specify rather than guessing
- **Empty Figma file:** Abort with clear message
## Integration
- **Consumed by:** `design-token-lock`, `tdd-from-figma`, `figma-to-react-workflow`, `/build-from-figma`
- **Fast-path trigger:** a build-spec with `"source": "conversation"` (written by `conversation-intake` and completed by `design-brief-to-figma` in `/build-from-conversation`) skips the interview — see Step 0
- **Uses:** Figma MCP (`get_metadata`, `get_variable_defs`, `get_screenshot`), Glob, Read
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!