1. Semantic Buffer AST
The Semantic Buffer is a stateful tree that receives intention-based nodes from the Voice-to-JSON stream. Unlike raw LLM outputs (which frequently hallucinate unstructured JSON), this component guarantees structural type safety before execution via the Figma MCP.
Schema definition: BufferNode (TypeScript)
interface BufferNode {
id: string; // UUID-v4
type: ElementType; // 'FRAME' | 'TEXT' | 'BUTTON' | 'INPUT'
intent: string; // Original JEV transcript snippet
properties: {
layout: 'FLEX' | 'GRID' | 'ABSOLUTE';
direction?: 'HORIZONTAL' | 'VERTICAL';
padding?: [number, number, number, number];
gap?: number;
fill?: HexColor | 'TRANSPARENT';
stroke?: HexColor;
cornerRadius?: number;
};
children: BufferNode[];
_mcp_ref?: string; // Native Figma node ID after MCP realization
}2. Voice Streaming Protocol
Voice streams are chunked via WebRTC and piped to the JEV endpoint. Partial transcripts are eagerly resolved into diffs against the Semantic Buffer to provide real-time UI feedback while the user is still speaking.
Terminal trace: WebSocket Engine (Port 8080)
[15:42:01.102] INFO: ws_connect client=v_designer_99
< AUDIO_CHUNK [4096 bytes]
< AUDIO_CHUNK [4096 bytes]
> PARTIAL_JSON: {"transcript": "add a red button", "confidence": 0.89}
< AUDIO_CHUNK [4096 bytes]
> COMMIT_JSON: {"transcript": "add a red button that says submit", "intent_parsed": true}
* BUFFER_DIFF: +Node(type=BUTTON, fill=#FF0000, text="Submit")
3. Figma MCP Operations
The MCP server polls the Semantic Buffer and executes atomic design operations via Figma's native Plugin API. By maintaining the _mcp_ref, future edits target existing nodes rather than re-generating elements from scratch.
operation.ts
async function executeMcpCommand(node: BufferNode) {
if (node._mcp_ref) {
// Node exists, apply mutation (progressive editing)
const figmaNode = await figma.getNodeByIdAsync(node._mcp_ref);
if (figmaNode && figmaNode.type === 'FRAME') {
figmaNode.fills = [{ type: 'SOLID', color: hexToFigmaRgb(node.properties.fill) }];
}
return;
}
// Create new native Figma node
const frame = figma.createFrame();
frame.name = `${node.type}_${node.id.substring(0, 4)}`;
// Apply Auto-Layout semantics
if (node.properties.layout === 'FLEX') {
frame.layoutMode = node.properties.direction || 'HORIZONTAL';
frame.itemSpacing = node.properties.gap || 0;
}
// Persist reference back to buffer for future modifications
node._mcp_ref = frame.id;
figma.currentPage.appendChild(frame);
}