@createlex/figma-swiftui-mcp 1.2.2 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -276,7 +276,23 @@ function startBridgeServer(options = {}) {
|
|
|
276
276
|
return res.status(502).json({ ok: false, error: response.error || 'Plugin returned an error' });
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
|
|
279
|
+
const data = response.data || {};
|
|
280
|
+
|
|
281
|
+
// Attach explicit AI workflow instructions so any agent that fetches this URL
|
|
282
|
+
// knows exactly how to generate and write correct SwiftUI code with real images.
|
|
283
|
+
const assetCount = data.assetExportPlan?.candidates?.length ?? 0;
|
|
284
|
+
const aiWorkflow = {
|
|
285
|
+
step1: 'You have the Figma design context. Do NOT generate SwiftUI code from scratch — that produces grey placeholder rectangles instead of real images.',
|
|
286
|
+
step2: 'Call the MCP tool `write_selection_to_xcode`. It generates SwiftUI with correct Image("name") asset references AND writes the PNG files to Assets.xcassets automatically.',
|
|
287
|
+
step3: 'After write_selection_to_xcode returns, ONLY refine the code it produced: add GeometryReader for responsiveness, wire interactions. DO NOT rewrite Image("name") calls or replace them with Rectangle()/shapes.',
|
|
288
|
+
step4: 'If the caller has no MCP access, use the structName and assetExportPlan below to write SwiftUI that references Image("name") for every asset candidate listed.',
|
|
289
|
+
mcpTool: 'write_selection_to_xcode',
|
|
290
|
+
mcpServer: 'figma-swiftui',
|
|
291
|
+
assetCandidateCount: assetCount,
|
|
292
|
+
warning: 'Photos, 3D renders, illustrations and icons are pre-exported as PNG assets. Always use Image("name") — never reconstruct them with SwiftUI shapes or colors.',
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
res.json({ ok: true, ...data, _aiWorkflow: aiWorkflow });
|
|
280
296
|
});
|
|
281
297
|
|
|
282
298
|
function sendBridgeMessage(ws, payload) {
|
|
@@ -35,6 +35,8 @@ RULES:
|
|
|
35
35
|
9. End every file with a #Preview { StructName() } block.
|
|
36
36
|
10. Emit best-effort code for anything complex — never emit TODO comments or placeholder stubs.
|
|
37
37
|
11. If reusableComponents are present, output each as a separate <file name="ComponentName.swift"> tag.
|
|
38
|
+
12. FONTS: Always use .font(.system(size: X, weight: .bold)) — NEVER reference custom font names like "Inter-Bold", "Roboto", or any fontName from Figma. Custom fonts are not bundled in the Xcode project and will cause runtime errors. System font only.
|
|
39
|
+
13. IMAGES: Every node listed in assetExportPlan MUST be referenced as Image("assetName").resizable().scaledToFill() — NEVER replace with Rectangle(), Color, or shapes. These PNGs are pre-exported to Assets.xcassets.
|
|
38
40
|
|
|
39
41
|
RESPONSIVE LAYOUT RULES:
|
|
40
42
|
- Root frame with FILL sizing → .frame(maxWidth: .infinity)
|
package/companion/mcp-server.mjs
CHANGED
|
@@ -420,7 +420,7 @@ server.registerTool('get_metadata', {
|
|
|
420
420
|
});
|
|
421
421
|
|
|
422
422
|
server.registerTool('get_design_context', {
|
|
423
|
-
description: 'Return node metadata, asset export candidates, and generation hints for the current selection
|
|
423
|
+
description: 'Return node metadata, asset export candidates, and generation hints for the current Figma selection. PREFERRED WORKFLOW: call write_selection_to_xcode instead — it generates correct SwiftUI with Image("name") asset refs AND writes PNGs to Assets.xcassets in one step, no planning needed. Only call get_design_context if you need to inspect the raw node tree before generating.',
|
|
424
424
|
inputSchema: {
|
|
425
425
|
nodeIds: z.array(z.string()).optional().describe('Optional list of Figma node ids. If omitted, uses the current selection'),
|
|
426
426
|
nodeId: z.string().optional().describe('Optional single Figma node id'),
|
|
@@ -438,7 +438,7 @@ server.registerTool('get_design_context', {
|
|
|
438
438
|
});
|
|
439
439
|
|
|
440
440
|
server.registerTool('get_swiftui_generation_prompt', {
|
|
441
|
-
description: 'Return a ready-to-use SwiftUI system prompt and user message for AI-native generation.
|
|
441
|
+
description: 'Return a ready-to-use SwiftUI system prompt and user message for AI-native generation. WARNING: prefer write_selection_to_xcode — it handles Image() asset refs and PNG export automatically. Only use get_swiftui_generation_prompt when you must generate code yourself. If you do use this: (a) use .font(.system(size:weight:)) — never hardcode custom font names like Inter or Roboto, (b) reference every assetExportPlan entry as Image("name") not Rectangle().',
|
|
442
442
|
inputSchema: {
|
|
443
443
|
nodeIds: z.array(z.string()).optional().describe('Optional list of Figma node ids. If omitted, uses the current selection'),
|
|
444
444
|
nodeId: z.string().optional().describe('Optional single Figma node id'),
|
|
@@ -832,6 +832,8 @@ server.registerTool('write_selection_to_xcode', {
|
|
|
832
832
|
filePath: result.results?.swiftFile ?? null,
|
|
833
833
|
});
|
|
834
834
|
|
|
835
|
+
const imageNames = (generated.images ?? []).map((img) => img.name);
|
|
836
|
+
|
|
835
837
|
return jsonResult(buildCompactResponse({
|
|
836
838
|
result,
|
|
837
839
|
structName: effectiveStructName,
|
|
@@ -839,6 +841,14 @@ server.registerTool('write_selection_to_xcode', {
|
|
|
839
841
|
diagnostics: generated.diagnostics ?? [],
|
|
840
842
|
refinementInstructions,
|
|
841
843
|
analysisHints,
|
|
844
|
+
_critical: [
|
|
845
|
+
`✅ SwiftUI written to ${result.results?.swiftFile ?? 'Xcode'}. Images written to Assets.xcassets.`,
|
|
846
|
+
imageNames.length > 0
|
|
847
|
+
? `🖼 ${imageNames.length} PNG asset(s) written: ${imageNames.join(', ')}. The generated code already references them with Image("name") calls.`
|
|
848
|
+
: null,
|
|
849
|
+
'🚫 DO NOT rewrite or overwrite the generated Swift file. DO NOT replace Image("name") calls with Rectangle(), shapes, or colors.',
|
|
850
|
+
'✏️ You may ONLY: add GeometryReader for responsiveness, wire @State interactions, extract reusable sub-views. Nothing else.',
|
|
851
|
+
].filter(Boolean),
|
|
842
852
|
}));
|
|
843
853
|
});
|
|
844
854
|
|
package/package.json
CHANGED