- Remove legacy admin-ui/js/ vanilla JS components - Add .dss/ directory with core tokens, skins, themes - Add Storybook configuration and generated stories - Add DSS management scripts (dss-services, dss-init, dss-setup, dss-reset) - Add MCP command definitions for DSS plugin - Add Figma sync architecture and scripts - Update pre-commit hooks with documentation validation - Fix JSON trailing commas in skin files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
Intelligent Figma Sync Architecture
Deep research synthesis from Figmagic, Design Tokens plugin, Figma MCP patterns, and Gemini 3 Pro analysis.
Executive Summary
DSS intelligent Figma sync should implement a 4-layer pipeline architecture with hybrid token extraction, W3C token format compliance, intelligent caching, and strict design contract enforcement.
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ FIGMA API LAYER │
├─────────────────────────────────────────────────────────────┤
│ GET /files/{key} → File metadata, lastModified │
│ GET /files/{key}/variables → Variables + collections │
│ GET /files/{key}/styles → Color, text, effect styles │
│ GET /files/{key}/nodes → Component structure │
│ GET /images/{key} → Component thumbnails │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ VALIDATION LAYER (NEW) │
├─────────────────────────────────────────────────────────────┤
│ DesignLinter: │
│ - Reject components without proper variant props │
│ - Enforce naming conventions (no "Property 1", "Frame X")│
│ - Mark non-compliant as "Raw" (skip code gen) │
│ - Generate lint report for designers │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ EXTRACTION LAYER │
├─────────────────────────────────────────────────────────────┤
│ VariableExtractor → semantic tokens (color, spacing) │
│ StyleExtractor → typography, effects, grids │
│ ComponentExtractor → component sets, variants, props │
│ AssetExtractor → icons, images (optional) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ TRANSLATION LAYER │
├─────────────────────────────────────────────────────────────┤
│ FigmaToDSSTranslator: │
│ - Maps Figma naming → DSS canonical names │
│ - Preserves variable REFERENCES (not resolved values) │
│ - Normalizes units (px → rem where appropriate) │
│ - Applies merge strategies (PREFER_FIGMA, LAST, etc) │
│ - Outputs W3C Design Token format │
│ - Separates Visual Props from Interaction States │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ OUTPUT LAYER │
├─────────────────────────────────────────────────────────────┤
│ TokenWriter → .dss/data/_system/tokens/figma-tokens.json│
│ ComponentWriter→ .dss/components/figma-registry.json │
│ StoryGenerator → admin-ui/src/stories/Components/*.stories │
│ CSSGenerator → .dss/themes/figma.css │
└─────────────────────────────────────────────────────────────┘
Key Architectural Decisions
1. Hybrid Token Extraction Strategy
| Source | Token Types | Priority |
|---|---|---|
| Variables | Semantic colors, spacing, breakpoints | Primary |
| Styles | Typography, effects, grids | Secondary |
| Components | UI registry, variants | Tertiary |
Rationale: Variables provide modern theming with modes (light/dark), while Styles capture typography which isn't fully available in Variables yet.
2. W3C Design Token Format
{
"$schema": "https://design-tokens.org/schema.json",
"color": {
"primary": {
"$value": "{color.blue.600}",
"$type": "color",
"$extensions": {
"figma": {"styleId": "S:abc123", "source": "variables"}
}
}
}
}
Critical: Preserve token references ({color.blue.600}), not resolved values (#0066cc). This enables:
- Multi-theme switching (Skins)
- Style Dictionary transformation
- Proper CSS variable generation
3. Component Variant Classification
VARIANT_CLASSIFICATION = {
# Visual Props → React props / Storybook args
"visual_props": ["Size", "Variant", "Roundness", "Type", "Icon"],
# Interaction States → CSS pseudo-classes (NOT React props)
"interaction_states": ["State", "Hover", "Focused", "Pressed", "Disabled"],
# Boolean toggles → React boolean props
"boolean_props": ["Checked?", "Selected", "Open", "Expanded"]
}
Example Mapping:
- Figma:
Button / Primary / Hover / Large - Code:
<Button variant="primary" size="large" /> - CSS handles
:hoverstate via pseudo-class
4. Canonical Token Interface (CTI)
DSS defines universal tokens that Skins map to:
DSS Canonical → shadcn Skin → HeroUI Skin
─────────────────────────────────────────────────────────────
--dss-action-bg → --primary → --heroui-primary
--dss-action-fg → --primary-foreground → --heroui-primary-fg
--dss-surface-bg → --background → --heroui-background
--dss-muted-bg → --muted → --heroui-default-100
Intelligent Caching Strategy
ETag-like Caching
class FigmaSyncCache:
def should_sync(self, file_key: str) -> bool:
manifest = self.load_manifest()
cached = manifest.get(file_key, {})
# Lightweight API call for lastModified
remote_modified = self.get_file_version(file_key)
return (
cached.get("lastModified") != remote_modified or
cached.get("age_hours", 999) > 24
)
def get_changed_nodes(self, file_key: str) -> list:
"""Compare node hashes to find what changed"""
local_hashes = self.load_node_hashes(file_key)
remote_nodes = self.fetch_node_tree(file_key)
changed = []
for node_id, node in remote_nodes.items():
node_hash = hash_node_properties(node)
if local_hashes.get(node_id) != node_hash:
changed.append(node_id)
return changed
Cache Manifest Structure
{
"evCZlaeZrP7X20NIViSJbl": {
"lastModified": "2025-12-10T12:00:00Z",
"syncedAt": "2025-12-10T12:05:00Z",
"nodeHashes": {
"66:5034": "abc123...",
"58:5416": "def456..."
},
"extractedTokens": 245,
"extractedComponents": 67
}
}
Implementation Priorities
| Priority | Task | Impact | Effort |
|---|---|---|---|
| P0 | Rate limit handling (exponential backoff, request queue) | Critical | Low |
| P0 | lastModified caching check | High | Low |
| P1 | Variable extraction (Figma Variables API) | High | Medium |
| P1 | Translation layer (Figma → DSS canonical) | High | Medium |
| P1 | Design validation/linting | Medium | Medium |
| P2 | Incremental node-level sync | Medium | High |
| P2 | W3C token output format | Medium | Low |
| P3 | Storybook story generation with variant controls | Medium | Medium |
| P3 | Asset extraction (icons, images) | Low | Low |
Design Contract Enforcement
Principle: Don't write complex code to handle messy design. Enforce design standards.
Required Variant Properties
Components must have properly named variant properties to be eligible for code generation:
✓ Valid: Button[Size=Large, Variant=Primary, State=Hover]
✗ Invalid: Button[Property 1=true, Frame 4221]
Naming Convention Rules
- Variant properties: PascalCase (
Size,Variant,State) - Variant values: PascalCase (
Large,Primary,Hover) - No auto-generated names (
Property 1,Frame 123) - Boolean variants: End with
?(Checked?,Selected?)
File Outputs
| File | Purpose | Format |
|---|---|---|
.dss/data/_system/tokens/figma-variables.json |
Raw Figma variables | W3C Token |
.dss/data/_system/tokens/figma-styles.json |
Typography & effects | W3C Token |
.dss/components/figma-registry.json |
Component catalog | DSS Registry |
.dss/cache/figma-sync-manifest.json |
Sync state cache | Internal |
.dss/logs/figma-lint-report.json |
Design validation | Report |
Research Sources
- Figmagic - Design token extraction patterns
- Design Tokens Plugin - W3C format, Style Dictionary integration
- Tokens Studio - Variable aliasing, theming
- Figma MCP - AI-assisted code generation
- Figma Developer API - Official documentation
Next Steps
- Implement P0 items: Rate limiting and caching
- Create token-map.json: Bridge between Figma IDs and DSS canonical names
- Build validation layer: Design linting before extraction
- Test with Obra shadcn UIKit: Validate against real Figma file