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/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-BTy2Psol.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-BTy2Psol.js";
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucent-ui",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "An AI-first React component library with machine-readable manifests.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",