lucent-ui 0.32.0 → 0.33.0
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/README.md +1 -1
- package/dist/{LucentProvider-BTy2Psol.js → LucentProvider-BAYI38i6.js} +3 -3
- package/dist/devtools.cjs +2 -2
- package/dist/devtools.js +466 -358
- package/dist/index.js +2 -2
- package/dist-server/server/design-rules.js +197 -0
- package/dist-server/server/index.js +48 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as g, jsx as e, Fragment as Q } from "react/jsx-runtime";
|
|
2
|
-
import { T as V, I as ut, B as ce, g as St, a as Me } from "./LucentProvider-
|
|
3
|
-
import { b as gi, C as vi, c as bi, L as yi, S as xi, d as wi, e as ki, f as Si, h as Ti, i as Ci, j as Ii, k as Mi, l as zi, m as Ei, n as Ai, o as qi, p as Di, q as Bi, r as Ri, s as Li, t as Pi, u as Fi, v as Ni, w as $i, x as Wi, y as Oi, z as Vi, A as Hi, D as Gi, E as Ui, F as ji, G as _i, H as Yi, J as Ki, K as Xi, M as Ji, N as Zi, O as Qi, P as es, Q as ts, R as ns, U as rs, V as as, W as os, X as is, Y as ss, Z as ls, _ as cs } from "./LucentProvider-
|
|
2
|
+
import { T as V, I as ut, B as ce, g as St, a as Me } from "./LucentProvider-BAYI38i6.js";
|
|
3
|
+
import { b as gi, C as vi, c as bi, L as yi, S as xi, d as wi, e as ki, f as Si, h as Ti, i as Ci, j as Ii, k as Mi, l as zi, m as Ei, n as Ai, o as qi, p as Di, q as Bi, r as Ri, s as Li, t as Pi, u as Fi, v as Ni, w as $i, x as Wi, y as Oi, z as Vi, A as Hi, D as Gi, E as Ui, F as ji, G as _i, H as Yi, J as Ki, K as Xi, M as Ji, N as Zi, O as Qi, P as es, Q as ts, R as ns, U as rs, V as as, W as os, X as is, Y as ss, Z as ls, _ as cs } from "./LucentProvider-BAYI38i6.js";
|
|
4
4
|
import { forwardRef as pt, useRef as $, useEffect as H, useState as z, useCallback as J, useContext as ee, createContext as fe, useLayoutEffect as te, useId as Pe, Children as Tt, isValidElement as Ct, cloneElement as It } from "react";
|
|
5
5
|
import { createPortal as ae } from "react-dom";
|
|
6
6
|
const Ra = {
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// ─── Design Rules ────────────────────────────────────────────────────────────
|
|
2
|
+
// Structured layout guidance injected into the MCP system prompt so AI agents
|
|
3
|
+
// produce aesthetically consistent Lucent UI layouts, not just valid props.
|
|
4
|
+
export const DESIGN_RULES = [
|
|
5
|
+
{
|
|
6
|
+
id: 'spacing',
|
|
7
|
+
title: 'Spacing scale',
|
|
8
|
+
body: `
|
|
9
|
+
Use Stack and Row components for all layout — never raw flexbox.
|
|
10
|
+
Gap values map to the spacing token scale (default density, 14px base):
|
|
11
|
+
|
|
12
|
+
| Gap | Token | Rem | ~px | Use for |
|
|
13
|
+
|-----|----------|---------|-----|-----------------------------------------------------|
|
|
14
|
+
| 0 | space-0 | 0 | 0 | Stacked label + description (no visible gap) |
|
|
15
|
+
| 1 | space-1 | 0.25rem | 3.5 | Tight inline pairs: icon + label, badge + name |
|
|
16
|
+
| 2 | space-2 | 0.5rem | 7 | Related items in a row: chip gap, button-group gap |
|
|
17
|
+
| 3 | space-3 | 0.75rem | 10 | Label-to-control gap, rows in a settings list |
|
|
18
|
+
| 4 | space-4 | 1rem | 14 | Sections within a card, standard Stack gap (default) |
|
|
19
|
+
| 5 | space-5 | 1.25rem | 17 | Between content blocks inside a page section |
|
|
20
|
+
| 6 | space-6 | 1.5rem | 21 | Card-to-card gap, major section separation |
|
|
21
|
+
| 8 | space-8 | 2rem | 28 | Page-level section separation |
|
|
22
|
+
| 10+ | space-10+| 2.5rem+ | 35+ | Hero spacing, page margins (rare in components) |
|
|
23
|
+
|
|
24
|
+
Card padding sizes:
|
|
25
|
+
- sm: py=space-2, px=space-3 — compact lists, dense data
|
|
26
|
+
- md: py=space-4, px=space-5 — forms, standard content (default)
|
|
27
|
+
- lg: py=space-6, px=space-8 — hero content, featured cards
|
|
28
|
+
`.trim(),
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'typography',
|
|
32
|
+
title: 'Typography hierarchy',
|
|
33
|
+
body: `
|
|
34
|
+
Always use the Text component — never raw HTML tags with inline font styles.
|
|
35
|
+
Three font families: base (DM Sans), mono (DM Mono), display (Georama).
|
|
36
|
+
Use display family for large numeric values (stats, prices, counters).
|
|
37
|
+
|
|
38
|
+
| Role | Size | Weight | Color | Element | Family |
|
|
39
|
+
|--------------|------|----------|-----------|---------|---------|
|
|
40
|
+
| Page title | 2xl | bold | primary | h1 | base |
|
|
41
|
+
| Section head | lg | semibold | primary | h2 | base |
|
|
42
|
+
| Card title | md | semibold | primary | h3 | base |
|
|
43
|
+
| Body text | sm | regular | primary | p | base |
|
|
44
|
+
| Label | xs | medium | secondary | label | base |
|
|
45
|
+
| Caption | xs | regular | secondary | span | base |
|
|
46
|
+
| Stat value | 2xl | bold | primary | span | display |
|
|
47
|
+
| Code/mono | sm | regular | primary | code | mono |
|
|
48
|
+
|
|
49
|
+
Font size scale (14px base):
|
|
50
|
+
- xs: 0.75rem (10.5px) — labels, captions, metadata
|
|
51
|
+
- sm: 0.875rem (12.25px) — body text, descriptions
|
|
52
|
+
- md: 1rem (14px) — card titles, emphasized text
|
|
53
|
+
- lg: 1.125rem (15.75px) — section headings
|
|
54
|
+
- xl: 1.25rem (17.5px) — page subtitles
|
|
55
|
+
- 2xl: 1.5rem (21px) — page titles, stat values
|
|
56
|
+
- 3xl: 1.875rem (26.25px) — hero headings (rare)
|
|
57
|
+
`.trim(),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'buttons',
|
|
61
|
+
title: 'Button pairing rules',
|
|
62
|
+
body: `
|
|
63
|
+
Button variants: primary, secondary (filled), outline (bordered), ghost, danger.
|
|
64
|
+
|
|
65
|
+
Pairing guidelines:
|
|
66
|
+
- Primary + Outline: balanced dual actions (Save / Cancel, Confirm / Back)
|
|
67
|
+
- Primary + Ghost: dominant + dismiss (Submit / Reset, Continue / Skip)
|
|
68
|
+
- Single Primary: sole call-to-action (Sign up, Follow, Add to cart)
|
|
69
|
+
- Outline only: equal-weight options in a row (Edit, Share, Export)
|
|
70
|
+
- Danger + Outline: destructive confirmation (Delete / Cancel)
|
|
71
|
+
- Never place two primary buttons in the same Row
|
|
72
|
+
|
|
73
|
+
Size pairing:
|
|
74
|
+
- Buttons in the same Row should use the same size
|
|
75
|
+
- Form action buttons: md (default)
|
|
76
|
+
- Card inline actions: sm
|
|
77
|
+
- Toolbar/compact actions: xs
|
|
78
|
+
- Button heights (border-box): sm=34px, md=42px, lg=48px — these align with input total heights
|
|
79
|
+
|
|
80
|
+
Icon usage:
|
|
81
|
+
- leftIcon for semantic context (+ Add, ↓ Download)
|
|
82
|
+
- rightIcon for directional flow (Next →)
|
|
83
|
+
- chevron prop for dropdown triggers (built-in chevron-down SVG)
|
|
84
|
+
`.trim(),
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'layout',
|
|
88
|
+
title: 'Common layout patterns',
|
|
89
|
+
body: `
|
|
90
|
+
Always use Stack (vertical) and Row (horizontal) — never raw div with flex styles.
|
|
91
|
+
Stack default gap: 4. Row default gap: 3.
|
|
92
|
+
|
|
93
|
+
Toggle / checkbox row:
|
|
94
|
+
Row gap="3" align="center"
|
|
95
|
+
├── Toggle or Checkbox
|
|
96
|
+
└── Stack gap="0"
|
|
97
|
+
├── Text size="sm" weight="medium" ← label
|
|
98
|
+
└── Text size="xs" color="secondary" ← description
|
|
99
|
+
|
|
100
|
+
Stats block:
|
|
101
|
+
Stack gap="0" align="center"
|
|
102
|
+
├── Text size="2xl" weight="bold" family="display" ← value
|
|
103
|
+
└── Text size="xs" color="secondary" ← label
|
|
104
|
+
|
|
105
|
+
Form layout:
|
|
106
|
+
Stack gap="4"
|
|
107
|
+
└── FormField[] ← each field includes its own label + error
|
|
108
|
+
|
|
109
|
+
Action bar (form actions):
|
|
110
|
+
Row gap="2" justify="end"
|
|
111
|
+
├── Button variant="outline" ← secondary action
|
|
112
|
+
└── Button variant="primary" ← primary action
|
|
113
|
+
|
|
114
|
+
Card content:
|
|
115
|
+
Card padding="md"
|
|
116
|
+
└── Stack gap="4"
|
|
117
|
+
├── Text size="md" weight="semibold" ← card title
|
|
118
|
+
├── Stack gap="3" ← card body
|
|
119
|
+
└── Row gap="2" justify="end" ← card actions
|
|
120
|
+
|
|
121
|
+
Page section:
|
|
122
|
+
Stack gap="5"
|
|
123
|
+
├── Row justify="between" align="center"
|
|
124
|
+
│ ├── Text size="2xl" weight="bold" ← page title
|
|
125
|
+
│ └── Button variant="outline" ← page action
|
|
126
|
+
└── Stack gap="6" ← section content
|
|
127
|
+
`.trim(),
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: 'color',
|
|
131
|
+
title: 'Color usage',
|
|
132
|
+
body: `
|
|
133
|
+
Lucent uses CSS custom properties for all colors. Never use raw hex values.
|
|
134
|
+
|
|
135
|
+
Text colors (via Text color prop):
|
|
136
|
+
- primary: default text, headings, values
|
|
137
|
+
- secondary: labels, captions, metadata, descriptions
|
|
138
|
+
- disabled: disabled state text (neutral gray, never accent-tinted)
|
|
139
|
+
- inverse: text on dark backgrounds
|
|
140
|
+
- onAccent: text on accent-colored backgrounds (auto-computed for contrast)
|
|
141
|
+
- success / warning / danger / info: semantic status text
|
|
142
|
+
|
|
143
|
+
Surface usage:
|
|
144
|
+
- Card variant="elevated": raised cards with shadow
|
|
145
|
+
- Card variant="outline": bordered cards, lower emphasis
|
|
146
|
+
- Card variant="filled": subtle background fill, no border
|
|
147
|
+
|
|
148
|
+
Accent color:
|
|
149
|
+
- Applied automatically by LucentProvider to primary buttons, toggles, checkboxes, radio
|
|
150
|
+
- textOnAccent is auto-computed via APCA contrast algorithm
|
|
151
|
+
- Light mode default accent: near-black (#111827)
|
|
152
|
+
- Dark mode default accent: near-white (#f9fafb)
|
|
153
|
+
- 12 palette presets available: default, brand, indigo, violet, emerald, teal, rose, coral, amber, ocean, slate, sage
|
|
154
|
+
|
|
155
|
+
Status colors (Chip/Badge/Alert variants):
|
|
156
|
+
- success: positive trends, confirmations, online status
|
|
157
|
+
- warning: attention needed, approaching limits
|
|
158
|
+
- danger: errors, destructive actions, critical alerts
|
|
159
|
+
- info: neutral information, tips, updates
|
|
160
|
+
|
|
161
|
+
Disabled state:
|
|
162
|
+
- Always use neutral gray — never accent-tinted surfaces
|
|
163
|
+
- Applied via color-mix with neutral gray, not opacity
|
|
164
|
+
`.trim(),
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: 'density',
|
|
168
|
+
title: 'Density and responsive patterns',
|
|
169
|
+
body: `
|
|
170
|
+
Three density presets scale all spacing tokens proportionally:
|
|
171
|
+
- compact: tighter spacing (~80% of default) — data-dense dashboards, admin panels
|
|
172
|
+
- default: standard spacing — general purpose
|
|
173
|
+
- spacious: generous spacing (~125% of default) — marketing, onboarding, hero sections
|
|
174
|
+
|
|
175
|
+
Responsive wrapping:
|
|
176
|
+
- Use Row with wrap prop for responsive card grids
|
|
177
|
+
- Set minWidth on flex children (e.g. style={{ flex: 1, minWidth: 180 }})
|
|
178
|
+
- This creates equal-width cards that wrap gracefully without media queries
|
|
179
|
+
|
|
180
|
+
Card grids:
|
|
181
|
+
Row gap="4" wrap
|
|
182
|
+
└── Card[] style={{ flex: 1, minWidth: 240 }}
|
|
183
|
+
|
|
184
|
+
Compact list items:
|
|
185
|
+
Stack gap="2"
|
|
186
|
+
└── Row[] gap="3" align="center" (each row is an item)
|
|
187
|
+
`.trim(),
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
/** Full design rules as a single markdown string for system prompt injection. */
|
|
191
|
+
export const DESIGN_RULES_TEXT = DESIGN_RULES.map((s) => `## ${s.title}\n\n${s.body}`).join('\n\n');
|
|
192
|
+
/** Compact summary for the system prompt (keeps token budget reasonable). */
|
|
193
|
+
export const DESIGN_RULES_SUMMARY = `# Lucent UI Design Rules
|
|
194
|
+
|
|
195
|
+
These rules ensure AI-generated layouts are aesthetically consistent, not just technically valid.
|
|
196
|
+
|
|
197
|
+
${DESIGN_RULES_TEXT}`;
|
|
@@ -5,6 +5,7 @@ import { z } from 'zod';
|
|
|
5
5
|
import { ALL_MANIFESTS } from './registry.js';
|
|
6
6
|
import { ALL_PATTERNS } from './pattern-registry.js';
|
|
7
7
|
import { PALETTES, SHAPES, DENSITIES, SHADOWS, COMBINED, generatePresetConfig } from './presets.js';
|
|
8
|
+
import { DESIGN_RULES, DESIGN_RULES_SUMMARY } from './design-rules.js';
|
|
8
9
|
// ─── Auth stub ───────────────────────────────────────────────────────────────
|
|
9
10
|
// LUCENT_API_KEY is reserved for the future paid tier.
|
|
10
11
|
// When set, the server acknowledges it but does not yet enforce it.
|
|
@@ -65,6 +66,8 @@ function scorePattern(r, query) {
|
|
|
65
66
|
const server = new McpServer({
|
|
66
67
|
name: 'lucent-mcp',
|
|
67
68
|
version: '0.1.0',
|
|
69
|
+
}, {
|
|
70
|
+
instructions: DESIGN_RULES_SUMMARY,
|
|
68
71
|
});
|
|
69
72
|
// Tool: list_components
|
|
70
73
|
server.tool('list_components', 'Lists all available Lucent UI components with their name, tier (atom/molecule), and one-line description.', {}, async () => {
|
|
@@ -260,6 +263,51 @@ server.tool('get_preset_config', 'Returns the LucentProvider configuration code
|
|
|
260
263
|
],
|
|
261
264
|
};
|
|
262
265
|
});
|
|
266
|
+
// Tool: get_design_rules
|
|
267
|
+
server.tool('get_design_rules', 'Returns Lucent UI design rules for spacing, typography, button pairing, layout patterns, color usage, and density. These rules ensure AI-generated layouts are aesthetically consistent. Query a specific section or get all rules.', {
|
|
268
|
+
section: z
|
|
269
|
+
.string()
|
|
270
|
+
.optional()
|
|
271
|
+
.describe('Optional section id: "spacing", "typography", "buttons", "layout", "color", or "density". Omit to get all rules.'),
|
|
272
|
+
}, async ({ section }) => {
|
|
273
|
+
if (section) {
|
|
274
|
+
const s = section.trim().toLowerCase();
|
|
275
|
+
const rule = DESIGN_RULES.find((r) => r.id === s);
|
|
276
|
+
if (!rule) {
|
|
277
|
+
return {
|
|
278
|
+
content: [
|
|
279
|
+
{
|
|
280
|
+
type: 'text',
|
|
281
|
+
text: JSON.stringify({
|
|
282
|
+
error: `Section "${section}" not found.`,
|
|
283
|
+
availableSections: DESIGN_RULES.map((r) => ({
|
|
284
|
+
id: r.id,
|
|
285
|
+
title: r.title,
|
|
286
|
+
})),
|
|
287
|
+
}),
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
isError: true,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
content: [
|
|
295
|
+
{
|
|
296
|
+
type: 'text',
|
|
297
|
+
text: `## ${rule.title}\n\n${rule.body}`,
|
|
298
|
+
},
|
|
299
|
+
],
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
content: [
|
|
304
|
+
{
|
|
305
|
+
type: 'text',
|
|
306
|
+
text: DESIGN_RULES_SUMMARY,
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
};
|
|
310
|
+
});
|
|
263
311
|
// ─── Start ────────────────────────────────────────────────────────────────────
|
|
264
312
|
const transport = new StdioServerTransport();
|
|
265
313
|
await server.connect(transport);
|