This repository implements an AI-driven Code → Design synchronization system.
- Code is the source of truth (optimistic UI model)
- Design is synchronized to code
- This is a distributed system with strict runtime boundaries
-
Watcher (Node.js)
- Can read filesystem
- Can call LLMs
- Produces Intent Models and Figma Operations
-
Server (Bridge)
- Relays messages only
- Owns logging and audit
- No UI interpretation
-
Figma Plugin
- ui.html: network allowed
- code.ts: NO network, NO filesystem
-
Storybook Dev Server (optional, Phase 16C)
- Runs on http://localhost:6006 (configurable)
- Exposes MCP endpoint via @storybook/addon-mcp at /mcp
- Read-only data source for cross-surface drift analysis
- Start with:
pnpm dev:storybook
- All cross-process communication uses shared TypeScript interfaces
- Single canonical protocol file:
/packages/shared/src/protocol.ts - Every message must include:
{ version, type, requestId, payload }
- When JSON is requested, output JSON only
- Never mix explanation with structured output
- Retry with repair prompts if validation fails
- Adapters are read-only with default-deny tool policies
- Storybook MCP adapter:
af design drift [component]for cross-surface analysis - Storybook adapter requires dev server running (
pnpm dev:storybook) - Cross-surface drift is a separate analysis pass — it does NOT modify reconciliation
- Prefer semantic tokens over raw values
- Token resolution happens before Figma operations
- MVP first
- Deterministic plumbing before AI intelligence
- No overengineering
- Node.js 18+ installed
- Figma desktop app
cd ~/Desktop/aesthetic-function
pnpm dev:serverServer runs on http://localhost:3001
Figma plugins cannot reach localhost. Open a new terminal:
pnpm tunnel
# or manually:
npx cloudflared tunnel --url http://localhost:3001Copy the tunnel URL (e.g., https://random-words.trycloudflare.com)
Alternative: Use ngrok
ngrok http 3001- In Figma, go to Plugins → Development → Import plugin from manifest...
- Select:
~/Desktop/aesthetic-function/packages/figma-plugin/manifest.json - Run the plugin: Plugins → Development → Aesthetic Function
- In the plugin UI, paste the tunnel URL (not localhost!)
- Click Connect
- Should show "Connected (WebSocket)" or "Connected (Polling)"
- Create a rectangle, name it
TestBox - (Optional) Create a text node, name it
TestText - Select the
TestBoxnode
In a new terminal:
pnpm test:redThis sends a SET_FILL operation with color #FF0000
- The
TestBoxrectangle turns red - Plugin log shows "Forwarding 1 operation(s)..."
- Plugin log shows "✓ Success"
pnpm test:blue # Turn TestBox blue (#3B82F6)
pnpm test:text # Update TestText contentSERVER_URL=https://your-tunnel.trycloudflare.com pnpm test:red- Connection failed: Make sure tunnel is running and URL is correct
- No target node found: Select a node in Figma or create one named
TestBox - Node is not TEXT: For SET_TEXT, target must be a text node