mcp-probe-kit 1.13.0 → 1.15.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.
Files changed (49) hide show
  1. package/README.md +54 -3
  2. package/build/index.js +14 -1
  3. package/build/schemas/index.d.ts +108 -0
  4. package/build/schemas/index.js +2 -0
  5. package/build/schemas/ui-ux-schemas.d.ts +248 -0
  6. package/build/schemas/ui-ux-schemas.js +147 -0
  7. package/build/tools/__tests__/start_ui.integration.test.d.ts +6 -0
  8. package/build/tools/__tests__/start_ui.integration.test.js +179 -0
  9. package/build/tools/__tests__/start_ui.property.test.d.ts +6 -0
  10. package/build/tools/__tests__/start_ui.property.test.js +263 -0
  11. package/build/tools/__tests__/start_ui.unit.test.d.ts +6 -0
  12. package/build/tools/__tests__/start_ui.unit.test.js +109 -0
  13. package/build/tools/css_order.js +55 -55
  14. package/build/tools/index.d.ts +4 -0
  15. package/build/tools/index.js +5 -0
  16. package/build/tools/init_component_catalog.d.ts +22 -0
  17. package/build/tools/init_component_catalog.js +809 -0
  18. package/build/tools/render_ui.d.ts +22 -0
  19. package/build/tools/render_ui.js +384 -0
  20. package/build/tools/start_ui.d.ts +25 -0
  21. package/build/tools/start_ui.js +299 -0
  22. package/build/tools/ui-ux-tools.d.ts +116 -0
  23. package/build/tools/ui-ux-tools.js +756 -0
  24. package/build/tools/ui-ux-tools.test.d.ts +6 -0
  25. package/build/tools/ui-ux-tools.test.js +132 -0
  26. package/build/utils/ascii-box-formatter.d.ts +29 -0
  27. package/build/utils/ascii-box-formatter.js +195 -0
  28. package/build/utils/bm25.d.ts +60 -0
  29. package/build/utils/bm25.js +139 -0
  30. package/build/utils/cache-manager.d.ts +65 -0
  31. package/build/utils/cache-manager.js +156 -0
  32. package/build/utils/design-docs-generator.d.ts +1 -0
  33. package/build/utils/design-docs-generator.js +1 -0
  34. package/build/utils/design-reasoning-engine.d.ts +158 -0
  35. package/build/utils/design-reasoning-engine.js +363 -0
  36. package/build/utils/design-system-json-formatter.d.ts +41 -0
  37. package/build/utils/design-system-json-formatter.js +165 -0
  38. package/build/utils/ui-data-loader.d.ts +56 -0
  39. package/build/utils/ui-data-loader.js +164 -0
  40. package/build/utils/ui-search-engine.d.ts +57 -0
  41. package/build/utils/ui-search-engine.js +123 -0
  42. package/build/utils/ui-sync.d.ts +13 -0
  43. package/build/utils/ui-sync.js +241 -0
  44. package/docs/BEST_PRACTICES.md +257 -1
  45. package/docs/HOW_TO_TRIGGER.md +71 -1
  46. package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.html +89 -29
  47. package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.md +582 -1
  48. package/package.json +18 -5
  49. package/docs/HOW_TO_TRIGGER.html +0 -255
@@ -0,0 +1,809 @@
1
+ /**
2
+ * 初始化组件目录工具
3
+ *
4
+ * 基于设计系统规范生成组件目录
5
+ * 组件定义包含占位符,渲染时自动替换为实际值
6
+ */
7
+ const PROMPT_TEMPLATE = `# 🎨 初始化组件目录
8
+
9
+ ## 🎯 任务目标
10
+
11
+ 基于设计系统规范(\`docs/design-system.json\`)生成组件目录文件。
12
+
13
+ **输出文件**: \`docs/component-catalog.json\`
14
+
15
+ **文件用途**: 定义可用的 UI 组件及其属性,供后续 UI 生成时使用。
16
+
17
+ ---
18
+
19
+ ## 📋 前置检查
20
+
21
+ ### 第1步:检查设计系统文件
22
+
23
+ **操作**:
24
+ 1. 检查文件 \`docs/design-system.json\` 是否存在
25
+ 2. 如果不存在:
26
+ - 提示用户先运行 \`ui_design_system\` 生成设计系统
27
+ - 停止执行
28
+ 3. 如果存在:
29
+ - 读取文件内容
30
+ - 提取设计规范(颜色、字体、间距等)
31
+
32
+ ---
33
+
34
+ ## 📝 生成组件目录
35
+
36
+ 在 \`docs/component-catalog.json\` 中生成以下内容:
37
+
38
+ \`\`\`json
39
+ {
40
+ "version": "1.0.0",
41
+ "designSystem": "docs/design-system.json",
42
+ "components": {
43
+ "Button": {
44
+ "description": "按钮组件",
45
+ "props": {
46
+ "variant": {
47
+ "type": "enum",
48
+ "values": ["primary", "secondary", "outline", "ghost", "link"],
49
+ "default": "primary",
50
+ "mapping": {
51
+ "primary": "bg-[{colors.primary.500}] text-white hover:bg-[{colors.primary.600}]",
52
+ "secondary": "bg-[{colors.secondary.500}] text-white hover:bg-[{colors.secondary.600}]",
53
+ "outline": "border border-[{colors.neutral.300}] bg-transparent hover:bg-[{colors.neutral.50}]",
54
+ "ghost": "hover:bg-[{colors.neutral.100}]",
55
+ "link": "text-[{colors.primary.500}] underline-offset-4 hover:underline"
56
+ }
57
+ },
58
+ "size": {
59
+ "type": "enum",
60
+ "values": ["sm", "md", "lg"],
61
+ "default": "md",
62
+ "mapping": {
63
+ "sm": "h-9 px-3 text-sm",
64
+ "md": "h-10 px-4 text-base",
65
+ "lg": "h-11 px-6 text-lg"
66
+ }
67
+ },
68
+ "label": {
69
+ "type": "string",
70
+ "required": true
71
+ },
72
+ "disabled": {
73
+ "type": "boolean",
74
+ "default": false
75
+ }
76
+ },
77
+ "baseClasses": "inline-flex items-center justify-center rounded-[{borderRadius.md}] font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[{colors.primary.500}] disabled:pointer-events-none disabled:opacity-50"
78
+ },
79
+ "Input": {
80
+ "description": "输入框组件",
81
+ "props": {
82
+ "label": {
83
+ "type": "string",
84
+ "required": true
85
+ },
86
+ "type": {
87
+ "type": "enum",
88
+ "values": ["text", "email", "password", "number", "tel", "url"],
89
+ "default": "text"
90
+ },
91
+ "placeholder": {
92
+ "type": "string"
93
+ },
94
+ "required": {
95
+ "type": "boolean",
96
+ "default": false
97
+ },
98
+ "disabled": {
99
+ "type": "boolean",
100
+ "default": false
101
+ },
102
+ "error": {
103
+ "type": "string"
104
+ },
105
+ "helperText": {
106
+ "type": "string"
107
+ }
108
+ },
109
+ "baseClasses": "w-full px-3 py-2 border border-[{colors.neutral.300}] rounded-[{borderRadius.md}] text-[{typography.fontSize.base}] focus:outline-none focus:ring-2 focus:ring-[{colors.primary.500}] focus:border-transparent disabled:bg-[{colors.neutral.50}] disabled:cursor-not-allowed"
110
+ },
111
+ "Card": {
112
+ "description": "卡片容器",
113
+ "props": {
114
+ "title": {
115
+ "type": "string"
116
+ },
117
+ "description": {
118
+ "type": "string"
119
+ },
120
+ "padding": {
121
+ "type": "enum",
122
+ "values": ["none", "sm", "md", "lg"],
123
+ "default": "md",
124
+ "mapping": {
125
+ "none": "p-0",
126
+ "sm": "p-4",
127
+ "md": "p-6",
128
+ "lg": "p-8"
129
+ }
130
+ }
131
+ },
132
+ "hasChildren": true,
133
+ "baseClasses": "bg-white rounded-[{borderRadius.lg}] shadow-[{shadows.md}] border border-[{colors.neutral.200}]"
134
+ },
135
+ "Form": {
136
+ "description": "表单容器",
137
+ "props": {
138
+ "title": {
139
+ "type": "string"
140
+ },
141
+ "submitLabel": {
142
+ "type": "string",
143
+ "default": "提交"
144
+ },
145
+ "cancelLabel": {
146
+ "type": "string"
147
+ }
148
+ },
149
+ "hasChildren": true,
150
+ "baseClasses": "space-y-[{spacing.scale.4}]"
151
+ },
152
+ "Modal": {
153
+ "description": "弹窗组件",
154
+ "props": {
155
+ "title": {
156
+ "type": "string",
157
+ "required": true
158
+ },
159
+ "size": {
160
+ "type": "enum",
161
+ "values": ["sm", "md", "lg", "xl"],
162
+ "default": "md",
163
+ "mapping": {
164
+ "sm": "max-w-md",
165
+ "md": "max-w-lg",
166
+ "lg": "max-w-2xl",
167
+ "xl": "max-w-4xl"
168
+ }
169
+ }
170
+ },
171
+ "hasChildren": true,
172
+ "baseClasses": "relative bg-white rounded-[{borderRadius.lg}] shadow-[{shadows.xl}] w-full mx-4 max-h-[90vh] flex flex-col"
173
+ },
174
+ "Table": {
175
+ "description": "数据表格",
176
+ "props": {
177
+ "columns": {
178
+ "type": "array",
179
+ "required": true
180
+ },
181
+ "striped": {
182
+ "type": "boolean",
183
+ "default": false
184
+ },
185
+ "hoverable": {
186
+ "type": "boolean",
187
+ "default": true
188
+ }
189
+ },
190
+ "hasChildren": false,
191
+ "baseClasses": "min-w-full divide-y divide-[{colors.neutral.200}]"
192
+ },
193
+ "Alert": {
194
+ "description": "提示信息",
195
+ "props": {
196
+ "variant": {
197
+ "type": "enum",
198
+ "values": ["info", "success", "warning", "error"],
199
+ "default": "info",
200
+ "mapping": {
201
+ "info": "bg-[{colors.primary.50}] text-[{colors.primary.700}] border-[{colors.primary.200}]",
202
+ "success": "bg-[{colors.success.50}] text-[{colors.success.700}] border-[{colors.success.200}]",
203
+ "warning": "bg-[{colors.warning.50}] text-[{colors.warning.700}] border-[{colors.warning.200}]",
204
+ "error": "bg-[{colors.error.50}] text-[{colors.error.700}] border-[{colors.error.200}]"
205
+ }
206
+ },
207
+ "title": {
208
+ "type": "string"
209
+ },
210
+ "message": {
211
+ "type": "string",
212
+ "required": true
213
+ }
214
+ },
215
+ "baseClasses": "p-4 rounded-[{borderRadius.md}] border"
216
+ }
217
+ },
218
+ "layouts": {
219
+ "Container": {
220
+ "description": "容器布局",
221
+ "props": {
222
+ "maxWidth": {
223
+ "type": "enum",
224
+ "values": ["sm", "md", "lg", "xl", "2xl", "full"],
225
+ "default": "lg",
226
+ "mapping": {
227
+ "sm": "max-w-screen-sm",
228
+ "md": "max-w-screen-md",
229
+ "lg": "max-w-screen-lg",
230
+ "xl": "max-w-screen-xl",
231
+ "2xl": "max-w-screen-2xl",
232
+ "full": "max-w-full"
233
+ }
234
+ },
235
+ "padding": {
236
+ "type": "boolean",
237
+ "default": true
238
+ }
239
+ },
240
+ "hasChildren": true,
241
+ "baseClasses": "mx-auto px-4"
242
+ },
243
+ "Stack": {
244
+ "description": "堆叠布局",
245
+ "props": {
246
+ "direction": {
247
+ "type": "enum",
248
+ "values": ["row", "column"],
249
+ "default": "column"
250
+ },
251
+ "spacing": {
252
+ "type": "enum",
253
+ "values": [2, 4, 6, 8],
254
+ "default": 4,
255
+ "mapping": {
256
+ "2": "space-{direction === 'row' ? 'x' : 'y'}-2",
257
+ "4": "space-{direction === 'row' ? 'x' : 'y'}-4",
258
+ "6": "space-{direction === 'row' ? 'x' : 'y'}-6",
259
+ "8": "space-{direction === 'row' ? 'x' : 'y'}-8"
260
+ }
261
+ },
262
+ "align": {
263
+ "type": "enum",
264
+ "values": ["start", "center", "end", "stretch"],
265
+ "default": "stretch"
266
+ }
267
+ },
268
+ "hasChildren": true,
269
+ "baseClasses": "flex"
270
+ },
271
+ "Grid": {
272
+ "description": "网格布局",
273
+ "props": {
274
+ "cols": {
275
+ "type": "enum",
276
+ "values": [1, 2, 3, 4, 6, 12],
277
+ "default": 1,
278
+ "mapping": {
279
+ "1": "grid-cols-1",
280
+ "2": "grid-cols-2",
281
+ "3": "grid-cols-3",
282
+ "4": "grid-cols-4",
283
+ "6": "grid-cols-6",
284
+ "12": "grid-cols-12"
285
+ }
286
+ },
287
+ "gap": {
288
+ "type": "enum",
289
+ "values": [2, 4, 6, 8],
290
+ "default": 4,
291
+ "mapping": {
292
+ "2": "gap-2",
293
+ "4": "gap-4",
294
+ "6": "gap-6",
295
+ "8": "gap-8"
296
+ }
297
+ }
298
+ },
299
+ "hasChildren": true,
300
+ "baseClasses": "grid"
301
+ }
302
+ }
303
+ }
304
+ \`\`\`
305
+
306
+ ---
307
+
308
+ ## 🔑 关键说明
309
+
310
+ ### 占位符语法
311
+
312
+ 组件定义中使用占位符引用设计规范:
313
+
314
+ - \`{colors.primary.500}\` → 引用主色
315
+ - \`{colors.neutral.300}\` → 引用中性色
316
+ - \`{borderRadius.md}\` → 引用圆角
317
+ - \`{shadows.md}\` → 引用阴影
318
+ - \`{spacing.scale.4}\` → 引用间距
319
+ - \`{typography.fontSize.base}\` → 引用字体大小
320
+
321
+ **渲染时自动替换**:
322
+ \`\`\`
323
+ 占位符: bg-[{colors.primary.500}]
324
+ 替换后: bg-[#3b82f6]
325
+ \`\`\`
326
+
327
+ ### 组件属性
328
+
329
+ 每个组件包含:
330
+ - \`description\`: 组件描述
331
+ - \`props\`: 属性定义
332
+ - \`type\`: 属性类型(string/boolean/enum/array)
333
+ - \`values\`: 枚举值(仅 enum 类型)
334
+ - \`default\`: 默认值
335
+ - \`required\`: 是否必填
336
+ - \`mapping\`: 值到样式的映射
337
+ - \`hasChildren\`: 是否可包含子组件
338
+ - \`baseClasses\`: 基础样式类(包含占位符)
339
+
340
+ ---
341
+
342
+ ## ✅ 验证清单
343
+
344
+ 生成文件后,请验证:
345
+
346
+ - [ ] 文件已创建: \`docs/component-catalog.json\`
347
+ - [ ] JSON 格式正确(无语法错误)
348
+ - [ ] 包含所有基础组件(Button、Input、Card 等)
349
+ - [ ] 包含所有布局组件(Container、Stack、Grid)
350
+ - [ ] 所有占位符格式正确(\`{path.to.value}\`)
351
+ - [ ] 引用的设计规范路径正确
352
+
353
+ ---
354
+
355
+ ## 📌 注意事项
356
+
357
+ 1. **依赖设计规范**: 必须先运行 \`ui_design_system\` 生成 \`design-system.json\`
358
+ 2. **占位符一致性**: 确保占位符路径与 \`design-system.json\` 结构一致
359
+ 3. **可扩展性**: 用户可以添加自定义组件到此文件
360
+ 4. **版本控制**: 建议将此文件纳入 Git 版本控制
361
+
362
+ ---
363
+
364
+ ## 🚀 下一步
365
+
366
+ 生成组件目录后,可以:
367
+
368
+ 1. 使用 \`ui_search --mode=catalog\` 查看可用组件
369
+ 2. 使用 \`ui_search --mode=template\` 获取 UI 模板
370
+ 3. 使用 \`render_ui\` 渲染最终代码
371
+
372
+ **完整工作流**:
373
+ \`\`\`
374
+ ui_design_system → design-system.json
375
+
376
+ init_component_catalog → component-catalog.json
377
+
378
+ ui_search --mode=template → ui/template.json
379
+
380
+ render_ui → 最终代码(自动应用设计规范)
381
+ \`\`\`
382
+ `;
383
+ /**
384
+ * 初始化组件目录工具
385
+ */
386
+ export async function initComponentCatalog(args) {
387
+ try {
388
+ const fs = await import('fs/promises');
389
+ const path = await import('path');
390
+ // 检查设计系统文件是否存在
391
+ const docsDir = path.join(process.cwd(), 'docs');
392
+ const uiDir = path.join(docsDir, 'ui');
393
+ const designSystemPath = path.join(docsDir, 'design-system.json');
394
+ try {
395
+ await fs.access(designSystemPath);
396
+ }
397
+ catch {
398
+ return {
399
+ content: [
400
+ {
401
+ type: "text",
402
+ text: `❌ 未找到设计系统文件
403
+
404
+ 请先运行 \`ui_design_system\` 生成设计系统:
405
+
406
+ \`\`\`
407
+ ui_design_system --product_type="SaaS" --stack="react"
408
+ \`\`\`
409
+
410
+ 然后再运行此工具。
411
+ `,
412
+ },
413
+ ],
414
+ isError: true,
415
+ };
416
+ }
417
+ // 生成组件目录
418
+ const componentCatalog = {
419
+ version: "1.0.0",
420
+ designSystem: "docs/design-system.json",
421
+ components: {
422
+ Button: {
423
+ description: "按钮组件",
424
+ props: {
425
+ variant: {
426
+ type: "enum",
427
+ values: ["primary", "secondary", "outline", "ghost", "link"],
428
+ default: "primary",
429
+ mapping: {
430
+ primary: "bg-[{colors.primary.500}] text-white hover:bg-[{colors.primary.600}]",
431
+ secondary: "bg-[{colors.secondary.500}] text-white hover:bg-[{colors.secondary.600}]",
432
+ outline: "border border-[{colors.neutral.300}] bg-transparent hover:bg-[{colors.neutral.50}]",
433
+ ghost: "hover:bg-[{colors.neutral.100}]",
434
+ link: "text-[{colors.primary.500}] underline-offset-4 hover:underline"
435
+ }
436
+ },
437
+ size: {
438
+ type: "enum",
439
+ values: ["sm", "md", "lg"],
440
+ default: "md",
441
+ mapping: {
442
+ sm: "h-9 px-3 text-sm",
443
+ md: "h-10 px-4 text-base",
444
+ lg: "h-11 px-6 text-lg"
445
+ }
446
+ },
447
+ label: {
448
+ type: "string",
449
+ required: true
450
+ },
451
+ disabled: {
452
+ type: "boolean",
453
+ default: false
454
+ }
455
+ },
456
+ baseClasses: "inline-flex items-center justify-center rounded-[{borderRadius.md}] font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[{colors.primary.500}] disabled:pointer-events-none disabled:opacity-50"
457
+ },
458
+ Input: {
459
+ description: "输入框组件",
460
+ props: {
461
+ label: {
462
+ type: "string",
463
+ required: true
464
+ },
465
+ type: {
466
+ type: "enum",
467
+ values: ["text", "email", "password", "number", "tel", "url"],
468
+ default: "text"
469
+ },
470
+ placeholder: {
471
+ type: "string"
472
+ },
473
+ required: {
474
+ type: "boolean",
475
+ default: false
476
+ },
477
+ disabled: {
478
+ type: "boolean",
479
+ default: false
480
+ },
481
+ error: {
482
+ type: "string"
483
+ },
484
+ helperText: {
485
+ type: "string"
486
+ }
487
+ },
488
+ baseClasses: "w-full px-3 py-2 border border-[{colors.neutral.300}] rounded-[{borderRadius.md}] text-[{typography.fontSize.base}] focus:outline-none focus:ring-2 focus:ring-[{colors.primary.500}] focus:border-transparent disabled:bg-[{colors.neutral.50}] disabled:cursor-not-allowed"
489
+ },
490
+ Card: {
491
+ description: "卡片容器",
492
+ props: {
493
+ title: {
494
+ type: "string"
495
+ },
496
+ description: {
497
+ type: "string"
498
+ },
499
+ padding: {
500
+ type: "enum",
501
+ values: ["none", "sm", "md", "lg"],
502
+ default: "md",
503
+ mapping: {
504
+ none: "p-0",
505
+ sm: "p-4",
506
+ md: "p-6",
507
+ lg: "p-8"
508
+ }
509
+ }
510
+ },
511
+ hasChildren: true,
512
+ baseClasses: "bg-white rounded-[{borderRadius.lg}] shadow-[{shadows.md}] border border-[{colors.neutral.200}]"
513
+ },
514
+ Form: {
515
+ description: "表单容器",
516
+ props: {
517
+ title: {
518
+ type: "string"
519
+ },
520
+ submitLabel: {
521
+ type: "string",
522
+ default: "提交"
523
+ },
524
+ cancelLabel: {
525
+ type: "string"
526
+ }
527
+ },
528
+ hasChildren: true,
529
+ baseClasses: "space-y-[{spacing.scale.4}]"
530
+ },
531
+ Modal: {
532
+ description: "弹窗组件",
533
+ props: {
534
+ title: {
535
+ type: "string",
536
+ required: true
537
+ },
538
+ size: {
539
+ type: "enum",
540
+ values: ["sm", "md", "lg", "xl"],
541
+ default: "md",
542
+ mapping: {
543
+ sm: "max-w-md",
544
+ md: "max-w-lg",
545
+ lg: "max-w-2xl",
546
+ xl: "max-w-4xl"
547
+ }
548
+ }
549
+ },
550
+ hasChildren: true,
551
+ baseClasses: "relative bg-white rounded-[{borderRadius.lg}] shadow-[{shadows.xl}] w-full mx-4 max-h-[90vh] flex flex-col"
552
+ },
553
+ Table: {
554
+ description: "数据表格",
555
+ props: {
556
+ columns: {
557
+ type: "array",
558
+ required: true
559
+ },
560
+ striped: {
561
+ type: "boolean",
562
+ default: false
563
+ },
564
+ hoverable: {
565
+ type: "boolean",
566
+ default: true
567
+ }
568
+ },
569
+ hasChildren: false,
570
+ baseClasses: "min-w-full divide-y divide-[{colors.neutral.200}]"
571
+ },
572
+ Alert: {
573
+ description: "提示信息",
574
+ props: {
575
+ variant: {
576
+ type: "enum",
577
+ values: ["info", "success", "warning", "error"],
578
+ default: "info",
579
+ mapping: {
580
+ info: "bg-[{colors.primary.50}] text-[{colors.primary.700}] border-[{colors.primary.200}]",
581
+ success: "bg-[{colors.success.50}] text-[{colors.success.700}] border-[{colors.success.200}]",
582
+ warning: "bg-[{colors.warning.50}] text-[{colors.warning.700}] border-[{colors.warning.200}]",
583
+ error: "bg-[{colors.error.50}] text-[{colors.error.700}] border-[{colors.error.200}]"
584
+ }
585
+ },
586
+ title: {
587
+ type: "string"
588
+ },
589
+ message: {
590
+ type: "string",
591
+ required: true
592
+ }
593
+ },
594
+ baseClasses: "p-4 rounded-[{borderRadius.md}] border"
595
+ }
596
+ },
597
+ layouts: {
598
+ Container: {
599
+ description: "容器布局",
600
+ props: {
601
+ maxWidth: {
602
+ type: "enum",
603
+ values: ["sm", "md", "lg", "xl", "2xl", "full"],
604
+ default: "lg",
605
+ mapping: {
606
+ sm: "max-w-screen-sm",
607
+ md: "max-w-screen-md",
608
+ lg: "max-w-screen-lg",
609
+ xl: "max-w-screen-xl",
610
+ "2xl": "max-w-screen-2xl",
611
+ full: "max-w-full"
612
+ }
613
+ },
614
+ padding: {
615
+ type: "boolean",
616
+ default: true
617
+ }
618
+ },
619
+ hasChildren: true,
620
+ baseClasses: "mx-auto px-4"
621
+ },
622
+ Stack: {
623
+ description: "堆叠布局",
624
+ props: {
625
+ direction: {
626
+ type: "enum",
627
+ values: ["row", "column"],
628
+ default: "column"
629
+ },
630
+ spacing: {
631
+ type: "enum",
632
+ values: [2, 4, 6, 8],
633
+ default: 4,
634
+ mapping: {
635
+ "2": "space-{direction === 'row' ? 'x' : 'y'}-2",
636
+ "4": "space-{direction === 'row' ? 'x' : 'y'}-4",
637
+ "6": "space-{direction === 'row' ? 'x' : 'y'}-6",
638
+ "8": "space-{direction === 'row' ? 'x' : 'y'}-8"
639
+ }
640
+ },
641
+ align: {
642
+ type: "enum",
643
+ values: ["start", "center", "end", "stretch"],
644
+ default: "stretch"
645
+ }
646
+ },
647
+ hasChildren: true,
648
+ baseClasses: "flex"
649
+ },
650
+ Grid: {
651
+ description: "网格布局",
652
+ props: {
653
+ cols: {
654
+ type: "enum",
655
+ values: [1, 2, 3, 4, 6, 12],
656
+ default: 1,
657
+ mapping: {
658
+ "1": "grid-cols-1",
659
+ "2": "grid-cols-2",
660
+ "3": "grid-cols-3",
661
+ "4": "grid-cols-4",
662
+ "6": "grid-cols-6",
663
+ "12": "grid-cols-12"
664
+ }
665
+ },
666
+ gap: {
667
+ type: "enum",
668
+ values: [2, 4, 6, 8],
669
+ default: 4,
670
+ mapping: {
671
+ "2": "gap-2",
672
+ "4": "gap-4",
673
+ "6": "gap-6",
674
+ "8": "gap-8"
675
+ }
676
+ }
677
+ },
678
+ hasChildren: true,
679
+ baseClasses: "grid"
680
+ }
681
+ }
682
+ };
683
+ // 确保 docs/ui 目录存在
684
+ try {
685
+ await fs.access(uiDir);
686
+ }
687
+ catch {
688
+ await fs.mkdir(uiDir, { recursive: true });
689
+ }
690
+ // 写入文件到 docs/ui/
691
+ const catalogPath = path.join(uiDir, 'component-catalog.json');
692
+ await fs.writeFile(catalogPath, JSON.stringify(componentCatalog, null, 2), 'utf-8');
693
+ // 统计组件数量
694
+ const componentCount = Object.keys(componentCatalog.components).length;
695
+ const layoutCount = Object.keys(componentCatalog.layouts).length;
696
+ return {
697
+ content: [
698
+ {
699
+ type: "text",
700
+ text: `# ✅ 组件目录生成成功
701
+
702
+ ## 📄 文件已保存
703
+
704
+ **文件**: \`docs/ui/component-catalog.json\`
705
+
706
+ ---
707
+
708
+ ## 📦 组件清单
709
+
710
+ ### 基础组件(${componentCount} 个)
711
+ ${Object.entries(componentCatalog.components).map(([name, comp]) => `- **${name}**: ${comp.description}`).join('\n')}
712
+
713
+ ### 布局组件(${layoutCount} 个)
714
+ ${Object.entries(componentCatalog.layouts).map(([name, layout]) => `- **${name}**: ${layout.description}`).join('\n')}
715
+
716
+ **总计**: ${componentCount + layoutCount} 个组件
717
+
718
+ ---
719
+
720
+ ## 🔑 占位符说明
721
+
722
+ 组件样式使用占位符引用设计规范:
723
+
724
+ - \`{colors.primary.500}\` → 主色
725
+ - \`{colors.neutral.300}\` → 中性色
726
+ - \`{borderRadius.md}\` → 圆角
727
+ - \`{shadows.md}\` → 阴影
728
+ - \`{spacing.scale.4}\` → 间距
729
+ - \`{typography.fontSize.base}\` → 字体大小
730
+
731
+ **渲染时自动替换**:
732
+ \`\`\`
733
+ 占位符: bg-[{colors.primary.500}]
734
+ 替换后: bg-[#3b82f6](从 design-system.json 读取)
735
+ \`\`\`
736
+
737
+ ---
738
+
739
+ ## 🚀 下一步
740
+
741
+ ### 方式 1:一键生成 UI(推荐)
742
+
743
+ \`\`\`bash
744
+ start_ui "登录页面"
745
+ start_ui "用户列表"
746
+ start_ui "设置页面"
747
+ \`\`\`
748
+
749
+ 所有页面将自动应用设计规范 ✨
750
+
751
+ ### 方式 2:手动步骤
752
+
753
+ \`\`\`bash
754
+ # 第1步:查看组件目录
755
+ ui_search --mode=catalog
756
+
757
+ # 第2步:搜索 UI 模板
758
+ ui_search --mode=template --query="登录表单"
759
+
760
+ # 第3步:渲染代码
761
+ render_ui docs/ui/your-template.json
762
+ \`\`\`
763
+
764
+ ---
765
+
766
+ ## 💡 自定义组件
767
+
768
+ 如需添加自定义组件:
769
+
770
+ 1. 编辑 \`docs/ui/component-catalog.json\`
771
+ 2. 添加新组件定义
772
+ 3. 使用占位符语法(\`{path.to.value}\`)
773
+ 4. 重新运行 \`start_ui\` 或 \`render_ui\`
774
+
775
+ **示例**:
776
+ \`\`\`json
777
+ {
778
+ "components": {
779
+ "MyButton": {
780
+ "description": "自定义按钮",
781
+ "props": {
782
+ "color": {
783
+ "type": "string",
784
+ "default": "{colors.primary.500}"
785
+ }
786
+ },
787
+ "baseClasses": "px-4 py-2 rounded-[{borderRadius.md}]"
788
+ }
789
+ }
790
+ }
791
+ \`\`\`
792
+ `,
793
+ },
794
+ ],
795
+ };
796
+ }
797
+ catch (error) {
798
+ const errorMessage = error instanceof Error ? error.message : String(error);
799
+ return {
800
+ content: [
801
+ {
802
+ type: "text",
803
+ text: `❌ 初始化组件目录失败: ${errorMessage}`,
804
+ },
805
+ ],
806
+ isError: true,
807
+ };
808
+ }
809
+ }