conductor-figma 0.3.1 → 1.0.1
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.
- package/package.json +1 -1
- package/src/design/craftguide.js +181 -0
- package/src/index.js +1 -0
- package/src/relay.js +3 -1
- package/src/tools/handlers.js +63 -0
- package/src/tools/registry.js +60 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conductor-figma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Design-intelligent MCP server for Figma. 61 tools across 10 categories. 8px grid, type scale ratios, auto-layout, component reuse, accessibility — real design intelligence, not shape proxying.",
|
|
5
5
|
"author": "0xDragoon",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// CONDUCTOR — Design Craft Guide
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
// Professional design rules. The AI reads this before designing anything.
|
|
5
|
+
// This is what separates amateur output from production quality.
|
|
6
|
+
|
|
7
|
+
export function getDesignCraftGuide() {
|
|
8
|
+
return `# CONDUCTOR Design Craft Guide
|
|
9
|
+
|
|
10
|
+
You are a senior product designer working in Figma. Every frame, every text node, every color choice must follow these rules. No exceptions.
|
|
11
|
+
|
|
12
|
+
## Layout Architecture
|
|
13
|
+
|
|
14
|
+
### Frame Structure
|
|
15
|
+
- ALWAYS use auto-layout. Never absolute positioning.
|
|
16
|
+
- Direction: VERTICAL for page sections, HORIZONTAL for rows of items.
|
|
17
|
+
- Every frame needs explicit padding and gap. Never 0 unless intentional.
|
|
18
|
+
- Use primaryAxisSizingMode: "HUG" for content-driven frames, "FIXED" for containers with set widths.
|
|
19
|
+
- Use counterAxisSizingMode: "FILL" for child frames that should stretch to parent width.
|
|
20
|
+
|
|
21
|
+
### Spacing System (8px grid)
|
|
22
|
+
- Base unit: 8px. All spacing values must be multiples of 8.
|
|
23
|
+
- Micro spacing: 4px, 8px (within components, between label and input)
|
|
24
|
+
- Small spacing: 12px, 16px (between related elements, card padding)
|
|
25
|
+
- Medium spacing: 24px, 32px (between component groups, section padding)
|
|
26
|
+
- Large spacing: 48px, 64px (between page sections)
|
|
27
|
+
- Extra large: 80px, 96px, 120px (page-level vertical rhythm)
|
|
28
|
+
- NEVER use: 5, 7, 10, 13, 15, 17, 22, 25, 30, 35, 50, 55, 65, 70, 75, 90, 100
|
|
29
|
+
|
|
30
|
+
### Content Width
|
|
31
|
+
- Max content width: 1200px for desktop, centered in wider frames
|
|
32
|
+
- For a 1440px page, use 48-80px horizontal padding to create margins
|
|
33
|
+
- Card grid max: 3-4 columns. Never 5+ columns for content cards.
|
|
34
|
+
- Sidebar: 240-280px. Never wider than 320px.
|
|
35
|
+
|
|
36
|
+
## Typography
|
|
37
|
+
|
|
38
|
+
### Type Scale (use Inter font family)
|
|
39
|
+
- Display: 56-72px, Bold or Extra Bold, line-height 1.1
|
|
40
|
+
- H1: 40-48px, Bold, line-height 1.15
|
|
41
|
+
- H2: 32-36px, Bold or Semi Bold, line-height 1.2
|
|
42
|
+
- H3: 24-28px, Semi Bold, line-height 1.25
|
|
43
|
+
- H4: 18-20px, Semi Bold, line-height 1.3
|
|
44
|
+
- Body large: 18px, Regular, line-height 1.6
|
|
45
|
+
- Body: 15-16px, Regular, line-height 1.6
|
|
46
|
+
- Body small: 13-14px, Regular, line-height 1.5
|
|
47
|
+
- Caption: 11-12px, Medium, line-height 1.4
|
|
48
|
+
- Overline: 10-12px, Semi Bold or Bold, uppercase, letter-spacing 0.08em
|
|
49
|
+
|
|
50
|
+
### Typography Rules
|
|
51
|
+
- Maximum 2 font weights per section (e.g., Bold + Regular, Semi Bold + Regular)
|
|
52
|
+
- Body text color should NEVER be pure white (#ffffff). Use #f0f0f8 or #e8e8f0 for dark themes.
|
|
53
|
+
- Muted text: #a0a0b8 for dark themes, #666680 for light themes.
|
|
54
|
+
- Heading to body size ratio should be at least 1.5x.
|
|
55
|
+
- Line length: 45-75 characters for body text. Use max-width on text containers.
|
|
56
|
+
|
|
57
|
+
## Color
|
|
58
|
+
|
|
59
|
+
### Dark Theme Palette
|
|
60
|
+
- Background levels: #09090f → #0c0c18 → #0f0f1c → #12122a → #16163a
|
|
61
|
+
- Each level should be visibly distinct but not jarring.
|
|
62
|
+
- Card backgrounds should be 1-2 levels lighter than the page background.
|
|
63
|
+
- Text hierarchy: #f0f0f8 (primary) → #a0a0b8 (secondary) → #686880 (tertiary)
|
|
64
|
+
- Dividers: #1a1a32 or #1e1e3a (subtle, never bright)
|
|
65
|
+
- NEVER use pure black (#000000) as a background.
|
|
66
|
+
- NEVER use pure white (#ffffff) as text on dark backgrounds.
|
|
67
|
+
|
|
68
|
+
### Light Theme Palette
|
|
69
|
+
- Background levels: #ffffff → #f9f9fb → #f3f3f7 → #ebebf0
|
|
70
|
+
- Card backgrounds: #ffffff with subtle border (#e4e4ec)
|
|
71
|
+
- Text hierarchy: #111118 (primary) → #55556a (secondary) → #88889a (tertiary)
|
|
72
|
+
- Dividers: #e4e4ec
|
|
73
|
+
|
|
74
|
+
### Brand Color Usage
|
|
75
|
+
- Primary brand color: buttons, links, badges, icons, active states.
|
|
76
|
+
- NEVER use brand color for large background areas.
|
|
77
|
+
- Brand color for text only in overlines, links, and badges.
|
|
78
|
+
- Hover states: darken brand color by 10%. Active: darken by 15%.
|
|
79
|
+
|
|
80
|
+
## Components
|
|
81
|
+
|
|
82
|
+
### Buttons
|
|
83
|
+
- Height: 36px (small), 40px (default), 48px (large), 56px (hero)
|
|
84
|
+
- Horizontal padding: 16px (small), 20px (default), 28px (large), 32px (hero)
|
|
85
|
+
- Corner radius: 8px (default), 10-12px (large/hero)
|
|
86
|
+
- Primary: brand color fill, white text, Semi Bold
|
|
87
|
+
- Secondary: transparent fill, border or muted text, Medium weight
|
|
88
|
+
- Ghost: transparent, text only, Medium weight
|
|
89
|
+
- Always center text both axes in buttons
|
|
90
|
+
|
|
91
|
+
### Cards
|
|
92
|
+
- Padding: 24-32px (compact), 28-40px (standard)
|
|
93
|
+
- Corner radius: 12-16px
|
|
94
|
+
- Gap between elements inside: 12-20px
|
|
95
|
+
- On dark themes: use a lighter background, no border
|
|
96
|
+
- On light themes: white background + subtle border (#e4e4ec) + optional shadow
|
|
97
|
+
- Cards in a row should all be the same height (use counterAxisAlignItems: "STRETCH" on parent)
|
|
98
|
+
|
|
99
|
+
### Navigation
|
|
100
|
+
- Height: 64-72px for top nav
|
|
101
|
+
- Logo left, links center or right, CTA button far right
|
|
102
|
+
- Use a spacer frame (FILL sizing) between logo and links to push them apart
|
|
103
|
+
- Nav links: 14px Medium, 24-32px gap between items
|
|
104
|
+
- Active state: brand color or bolder weight
|
|
105
|
+
- Add a 1px divider below the nav
|
|
106
|
+
|
|
107
|
+
### Metric/Stat Cards
|
|
108
|
+
- Stack: label on top (12-13px, muted, Medium), value below (28-36px, Bold)
|
|
109
|
+
- Optional: change indicator below value (12-13px, green for positive, red for negative)
|
|
110
|
+
- Equal width cards in a horizontal row
|
|
111
|
+
- 20-24px gap between metric cards
|
|
112
|
+
|
|
113
|
+
### Tables
|
|
114
|
+
- Header row: 40-48px height, uppercase 10-11px labels, muted color, Medium weight
|
|
115
|
+
- Data rows: 48-56px height, 14-15px Regular text
|
|
116
|
+
- Cell padding: 16-20px horizontal
|
|
117
|
+
- Alternating row backgrounds or horizontal dividers (not both)
|
|
118
|
+
- Status badges: small colored pills with 4-6px padding, rounded
|
|
119
|
+
|
|
120
|
+
### Forms
|
|
121
|
+
- Input height: 40-44px
|
|
122
|
+
- Label: 13-14px, Medium weight, 4-8px gap below label
|
|
123
|
+
- Input: 14-15px Regular, 12-16px horizontal padding
|
|
124
|
+
- Corner radius: 8px
|
|
125
|
+
- Border: 1px, muted color. Focus: brand color border
|
|
126
|
+
- 20-24px gap between field groups
|
|
127
|
+
|
|
128
|
+
## Section Patterns
|
|
129
|
+
|
|
130
|
+
### Hero Section
|
|
131
|
+
- Vertical padding: 80-120px
|
|
132
|
+
- Content centered (both axes)
|
|
133
|
+
- Overline badge → Heading (56-72px) → Subtitle (18-20px) → Button row → Social proof
|
|
134
|
+
- Max heading width: ~600px
|
|
135
|
+
- Subtitle max width: ~500px
|
|
136
|
+
- 28-32px gap between heading and subtitle
|
|
137
|
+
- 32-40px gap between subtitle and buttons
|
|
138
|
+
|
|
139
|
+
### Feature Section
|
|
140
|
+
- Heading + subtitle centered at top
|
|
141
|
+
- 3 cards in a row (or 2 for detailed features)
|
|
142
|
+
- Each card: icon/emoji → title → description → optional link
|
|
143
|
+
- 48px gap between heading group and card row
|
|
144
|
+
|
|
145
|
+
### Stats/Social Proof
|
|
146
|
+
- Background color shift (one level different from surrounding sections)
|
|
147
|
+
- 3-4 stats in a horizontal row, centered
|
|
148
|
+
- Each stat centered: big number + label below
|
|
149
|
+
|
|
150
|
+
### CTA Section
|
|
151
|
+
- Often wrapped in a card or a background shift
|
|
152
|
+
- Centered: heading → subtitle → button row
|
|
153
|
+
- Generous padding: 64-96px vertical
|
|
154
|
+
|
|
155
|
+
### Footer
|
|
156
|
+
- Logo left, copyright right, spacer between
|
|
157
|
+
- Or: multi-column with link groups
|
|
158
|
+
- Divider line above
|
|
159
|
+
- Muted text, smaller font sizes (13px)
|
|
160
|
+
|
|
161
|
+
## Anti-Patterns (NEVER do these)
|
|
162
|
+
- Never use absolute positioning. Always auto-layout.
|
|
163
|
+
- Never use font sizes that aren't in the type scale.
|
|
164
|
+
- Never use spacing values that aren't multiples of 4 or 8.
|
|
165
|
+
- Never put more than 3-4 cards in a row.
|
|
166
|
+
- Never use pure black or pure white on dark themes.
|
|
167
|
+
- Never make buttons without sufficient padding (minimum 16px horizontal).
|
|
168
|
+
- Never stack more than 4-5 levels of nesting without good reason.
|
|
169
|
+
- Never use inconsistent corner radii on the same page.
|
|
170
|
+
- Never use more than 2-3 distinct background colors per page.
|
|
171
|
+
- Never center-align body paragraphs (center headings only).
|
|
172
|
+
- Never use text smaller than 11px.
|
|
173
|
+
- Never create frames without naming them descriptively.
|
|
174
|
+
|
|
175
|
+
## Naming Convention
|
|
176
|
+
- Pages: "Landing Page", "Pricing Page", "Dashboard"
|
|
177
|
+
- Sections: "Hero Section", "Features Section", "CTA Section"
|
|
178
|
+
- Components: "Nav CTA", "Feature Card", "Stat Card", "Price Tier"
|
|
179
|
+
- Layout: "Card Row", "Button Row", "Nav Links"
|
|
180
|
+
- Never use "Frame 1", "Rectangle 2", or auto-generated names.`;
|
|
181
|
+
}
|
package/src/index.js
CHANGED
package/src/relay.js
CHANGED
|
@@ -15,15 +15,17 @@ import { createServer } from 'node:http';
|
|
|
15
15
|
const FIGMA_COMMANDS = new Set([
|
|
16
16
|
// Create
|
|
17
17
|
'create_frame', 'create_text', 'create_rect', 'create_section', 'create_component',
|
|
18
|
+
'create_ellipse', 'create_svg_node',
|
|
18
19
|
// Layout
|
|
19
20
|
'set_auto_layout', 'set_constraints', 'apply_grid', 'align_nodes',
|
|
20
21
|
// Style
|
|
21
22
|
'set_fills', 'set_strokes', 'set_effects', 'set_corner_radius', 'set_opacity',
|
|
22
23
|
// Typography
|
|
23
|
-
'set_text_props', 'load_font',
|
|
24
|
+
'set_text_props', 'load_font', 'style_text_range',
|
|
24
25
|
// Read
|
|
25
26
|
'get_selection', 'get_page_info', 'get_styles', 'get_components',
|
|
26
27
|
'read_node', 'read_tree', 'read_spacing', 'read_colors', 'read_typography',
|
|
28
|
+
'find_nodes',
|
|
27
29
|
// Edit
|
|
28
30
|
'rename_node', 'move_node', 'resize_node', 'delete_node',
|
|
29
31
|
'clone_node', 'group_nodes', 'ungroup_node', 'reorder_node',
|
package/src/tools/handlers.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import * as design from '../design/intelligence.js';
|
|
8
8
|
import * as exporter from '../design/exporter.js';
|
|
9
|
+
import { getDesignCraftGuide } from '../design/craftguide.js';
|
|
9
10
|
|
|
10
11
|
function text(str) {
|
|
11
12
|
return { content: [{ type: 'text', text: str }] };
|
|
@@ -389,6 +390,68 @@ const HANDLERS = {
|
|
|
389
390
|
},
|
|
390
391
|
export_spec(args) { return json({ action: 'generate_spec', nodeId: args.nodeId, format: args.format || 'markdown' }); },
|
|
391
392
|
export_changelog(args) { return json({ action: 'diff_frames', nodeIdA: args.nodeIdA, nodeIdB: args.nodeIdB, format: args.format || 'markdown' }); },
|
|
393
|
+
|
|
394
|
+
// ═══ DESIGN CRAFT ═══
|
|
395
|
+
get_design_craft_guide() {
|
|
396
|
+
return text(getDesignCraftGuide());
|
|
397
|
+
},
|
|
398
|
+
|
|
399
|
+
// ═══ CREATE (additional) ═══
|
|
400
|
+
create_ellipse(args) {
|
|
401
|
+
return json({
|
|
402
|
+
action: 'create_ellipse',
|
|
403
|
+
name: args.name || 'Ellipse',
|
|
404
|
+
width: args.width, height: args.height,
|
|
405
|
+
fill: args.fill || '#ffffff',
|
|
406
|
+
x: args.x, y: args.y,
|
|
407
|
+
parentId: args.parentId,
|
|
408
|
+
opacity: args.opacity,
|
|
409
|
+
});
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
create_line(args) {
|
|
413
|
+
var dir = args.direction || 'horizontal';
|
|
414
|
+
return json({
|
|
415
|
+
action: 'create_rect',
|
|
416
|
+
name: args.name || 'Divider',
|
|
417
|
+
width: dir === 'horizontal' ? args.length : 1,
|
|
418
|
+
height: dir === 'horizontal' ? 1 : args.length,
|
|
419
|
+
fill: args.color || '#1a1a32',
|
|
420
|
+
parentId: args.parentId,
|
|
421
|
+
});
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
create_svg_node(args) {
|
|
425
|
+
return json({
|
|
426
|
+
action: 'create_svg_node',
|
|
427
|
+
name: args.name || 'SVG',
|
|
428
|
+
svg: args.svg,
|
|
429
|
+
x: args.x, y: args.y,
|
|
430
|
+
parentId: args.parentId,
|
|
431
|
+
});
|
|
432
|
+
},
|
|
433
|
+
|
|
434
|
+
find_nodes(args) {
|
|
435
|
+
return json({
|
|
436
|
+
action: 'find_nodes',
|
|
437
|
+
query: args.query,
|
|
438
|
+
type: args.type,
|
|
439
|
+
parentId: args.parentId,
|
|
440
|
+
});
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
// ═══ TYPOGRAPHY (additional) ═══
|
|
444
|
+
style_text_range(args) {
|
|
445
|
+
return json({
|
|
446
|
+
action: 'style_text_range',
|
|
447
|
+
nodeId: args.nodeId,
|
|
448
|
+
start: args.start,
|
|
449
|
+
end: args.end,
|
|
450
|
+
fontSize: args.fontSize,
|
|
451
|
+
fontWeight: args.fontWeight,
|
|
452
|
+
color: args.color,
|
|
453
|
+
});
|
|
454
|
+
},
|
|
392
455
|
};
|
|
393
456
|
|
|
394
457
|
// ─── Helpers ───
|
package/src/tools/registry.js
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
// Each tool has: name, description, category, inputSchema, handler reference.
|
|
6
6
|
|
|
7
7
|
export const CATEGORIES = {
|
|
8
|
-
|
|
8
|
+
craft: { label: 'Design Craft', icon: '✦', count: 1 },
|
|
9
|
+
create: { label: 'Create', icon: '⊞', count: 12 },
|
|
9
10
|
layout: { label: 'Layout', icon: '▤', count: 7 },
|
|
10
|
-
typography: { label: 'Typography', icon: '◆', count:
|
|
11
|
+
typography: { label: 'Typography', icon: '◆', count: 7 },
|
|
11
12
|
color: { label: 'Color & Style', icon: '◑', count: 7 },
|
|
12
13
|
components: { label: 'Components', icon: '◎', count: 6 },
|
|
13
14
|
spacing: { label: 'Spacing & Grid', icon: '◧', count: 6 },
|
|
@@ -26,16 +27,40 @@ function opt(schema) { return { ...schema, optional: true }; }
|
|
|
26
27
|
export const TOOLS = [
|
|
27
28
|
// ═══ CREATE ═══
|
|
28
29
|
{ name: 'create_frame', category: 'create',
|
|
29
|
-
description: 'Create
|
|
30
|
-
inputSchema: { type: 'object', properties: { name: str('Frame name'), width: opt(num('Width')), height: opt(num('Height')), direction: opt(str('
|
|
30
|
+
description: 'Create a single auto-layout frame. IMPORTANT: For multi-element designs (pages, sections, dashboards), use create_page or create_section instead — they handle all nesting automatically. If using create_frame directly, ALWAYS set parentId to nest inside a parent frame, and ALWAYS set direction, padding, and gap for auto-layout.',
|
|
31
|
+
inputSchema: { type: 'object', properties: { name: str('Frame name'), width: opt(num('Width')), height: opt(num('Height')), direction: opt(str('VERTICAL or HORIZONTAL')), padding: opt(num('Padding in px (use multiples of 8)')), paddingTop: opt(num('Top padding')), paddingBottom: opt(num('Bottom padding')), paddingLeft: opt(num('Left padding')), paddingRight: opt(num('Right padding')), gap: opt(num('Gap between children (use multiples of 8)')), fill: opt(str('Background color hex')), cornerRadius: opt(num('Corner radius')), parentId: opt(str('REQUIRED for nesting: parent frame ID')), primaryAxisAlignItems: opt(str('MIN, CENTER, MAX, SPACE_BETWEEN')), counterAxisAlignItems: opt(str('MIN, CENTER, MAX, STRETCH')), primaryAxisSizingMode: opt(str('FIXED, HUG, FILL')), counterAxisSizingMode: opt(str('FIXED, HUG, FILL')) }, required: ['name'] } },
|
|
31
32
|
|
|
32
33
|
{ name: 'create_page', category: 'create',
|
|
33
|
-
description: '
|
|
34
|
-
inputSchema: { type: 'object', properties: {
|
|
34
|
+
description: 'THE PRIMARY TOOL FOR DESIGNING PAGES. Creates a complete, polished, production-ready page with all sections, components, and content — fully nested with auto-layout, proper spacing, and design-intelligent values. One call generates 40-80 Figma elements. Use this INSTEAD of calling create_frame/create_text individually. Supports: landing, pricing, dashboard page types. Pass brand color, title, features, stats, and other content as parameters.',
|
|
35
|
+
inputSchema: { type: 'object', properties: {
|
|
36
|
+
pageType: str('Page type: landing, pricing, dashboard'),
|
|
37
|
+
title: opt(str('Hero heading text')),
|
|
38
|
+
subtitle: opt(str('Hero subtitle text')),
|
|
39
|
+
brand: opt(str('Brand/company name (appears in nav and footer)')),
|
|
40
|
+
brandColor: opt(str('Primary brand color hex (default #6366f1)')),
|
|
41
|
+
ctaText: opt(str('Primary CTA button text')),
|
|
42
|
+
darkMode: opt(bool('Dark mode (default true)')),
|
|
43
|
+
width: opt(num('Page width (default 1440)')),
|
|
44
|
+
navItems: opt(arr('Navigation link labels')),
|
|
45
|
+
features: opt(arr('Feature objects with icon, title, desc fields')),
|
|
46
|
+
stats: opt(arr('Stat objects with value and label fields')),
|
|
47
|
+
tiers: opt(arr('Pricing tier objects with name, price, period, desc, features, cta, highlighted fields')),
|
|
48
|
+
metrics: opt(arr('Dashboard metric objects with label, value, change, positive fields')),
|
|
49
|
+
}, required: ['pageType'] } },
|
|
35
50
|
|
|
36
51
|
{ name: 'create_section', category: 'create',
|
|
37
|
-
description: '
|
|
38
|
-
inputSchema: { type: 'object', properties: {
|
|
52
|
+
description: 'Creates a complete page section with all child elements, auto-layout, and proper nesting. One call generates 5-20 Figma elements. Use this INSTEAD of manually building sections. Supports: hero, features, pricing, cta, testimonials, faq section types.',
|
|
53
|
+
inputSchema: { type: 'object', properties: {
|
|
54
|
+
sectionType: str('Section type: hero, features, testimonials, faq, cta, pricing'),
|
|
55
|
+
heading: opt(str('Section heading')),
|
|
56
|
+
subheading: opt(str('Section subtitle')),
|
|
57
|
+
brandColor: opt(str('Brand color hex')),
|
|
58
|
+
ctaText: opt(str('CTA button text')),
|
|
59
|
+
width: opt(num('Section width (default 1440)')),
|
|
60
|
+
features: opt(arr('Feature objects for features section')),
|
|
61
|
+
testimonials: opt(arr('Testimonial objects with quote, author, role')),
|
|
62
|
+
faqs: opt(arr('FAQ objects with q and a fields')),
|
|
63
|
+
}, required: ['sectionType'] } },
|
|
39
64
|
|
|
40
65
|
{ name: 'create_card', category: 'create',
|
|
41
66
|
description: 'Create a card with proper padding, radius, shadow depth, and content hierarchy.',
|
|
@@ -277,6 +302,33 @@ export const TOOLS = [
|
|
|
277
302
|
{ name: 'export_changelog', category: 'export',
|
|
278
303
|
description: 'Diff two frames and export what changed as structured markdown or JSON.',
|
|
279
304
|
inputSchema: { type: 'object', properties: { nodeIdA: str('First frame (before)'), nodeIdB: str('Second frame (after)'), format: opt(str('markdown or json')) }, required: ['nodeIdA', 'nodeIdB'] } },
|
|
305
|
+
|
|
306
|
+
// ═══ DESIGN CRAFT ═══
|
|
307
|
+
{ name: 'get_design_craft_guide', category: 'craft',
|
|
308
|
+
description: 'CALL THIS FIRST before any design work. Returns professional design rules: typography scales, spacing systems (8px grid), color palettes, component patterns, and anti-patterns. Following these rules is the difference between amateur and production-quality output. Read the full guide before calling any create_ tools.',
|
|
309
|
+
inputSchema: { type: 'object', properties: {}, required: [] } },
|
|
310
|
+
|
|
311
|
+
// ═══ CREATE (additional) ═══
|
|
312
|
+
{ name: 'create_ellipse', category: 'create',
|
|
313
|
+
description: 'Create a circle or oval. Use for avatars, status indicators, decorative elements, and icon backgrounds. Set equal width and height for a perfect circle.',
|
|
314
|
+
inputSchema: { type: 'object', properties: { name: opt(str('Element name')), width: num('Width in px'), height: num('Height in px'), fill: opt(str('Fill color hex')), x: opt(num('X position')), y: opt(num('Y position')), parentId: opt(str('Parent frame ID')), opacity: opt(num('Opacity 0-1')) }, required: ['width', 'height'] } },
|
|
315
|
+
|
|
316
|
+
{ name: 'create_line', category: 'create',
|
|
317
|
+
description: 'Create a horizontal or vertical line. Use for dividers between sections, separators in navigation, and visual breaks. A line is a rectangle with 1px height (horizontal) or 1px width (vertical).',
|
|
318
|
+
inputSchema: { type: 'object', properties: { name: opt(str('Element name')), length: num('Length in px'), direction: opt(str('horizontal or vertical (default horizontal)')), color: opt(str('Line color hex')), parentId: opt(str('Parent frame ID')) }, required: ['length'] } },
|
|
319
|
+
|
|
320
|
+
{ name: 'create_svg_node', category: 'create',
|
|
321
|
+
description: 'Create a vector graphic from raw SVG markup. Use for icons, logos, illustrations, and any custom vector shape. Pass the SVG string directly.',
|
|
322
|
+
inputSchema: { type: 'object', properties: { name: opt(str('Element name')), svg: str('Raw SVG markup string'), x: opt(num('X position')), y: opt(num('Y position')), parentId: opt(str('Parent frame ID')) }, required: ['svg'] } },
|
|
323
|
+
|
|
324
|
+
{ name: 'find_nodes', category: 'create',
|
|
325
|
+
description: 'Search for elements by name or type within a frame or the entire page. Returns matching nodes with their IDs, positions, and basic properties. Use to locate elements before editing them.',
|
|
326
|
+
inputSchema: { type: 'object', properties: { query: opt(str('Search by name (partial match)')), type: opt(str('Filter by type: FRAME, TEXT, RECTANGLE, ELLIPSE, COMPONENT, INSTANCE')), parentId: opt(str('Search within this frame only')) }, required: [] } },
|
|
327
|
+
|
|
328
|
+
// ═══ TYPOGRAPHY (additional) ═══
|
|
329
|
+
{ name: 'style_text_range', category: 'typography',
|
|
330
|
+
description: 'Apply different styles to specific character ranges within a text node. Use for mixed-weight text (e.g., bold product name within a regular sentence), colored keywords, or size variations within a single text element.',
|
|
331
|
+
inputSchema: { type: 'object', properties: { nodeId: str('Text node ID'), start: num('Start character index'), end: num('End character index'), fontSize: opt(num('Font size for range')), fontWeight: opt(num('Font weight: 400, 500, 600, 700')), color: opt(str('Color hex for range')) }, required: ['nodeId', 'start', 'end'] } },
|
|
280
332
|
];
|
|
281
333
|
|
|
282
334
|
export function getToolsByCategory(category) {
|