mcp-probe-kit 1.13.0 → 1.15.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.
Files changed (46) 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/index.d.ts +4 -0
  14. package/build/tools/index.js +5 -0
  15. package/build/tools/init_component_catalog.d.ts +22 -0
  16. package/build/tools/init_component_catalog.js +809 -0
  17. package/build/tools/render_ui.d.ts +22 -0
  18. package/build/tools/render_ui.js +384 -0
  19. package/build/tools/start_ui.d.ts +25 -0
  20. package/build/tools/start_ui.js +299 -0
  21. package/build/tools/ui-ux-tools.d.ts +116 -0
  22. package/build/tools/ui-ux-tools.js +756 -0
  23. package/build/tools/ui-ux-tools.test.d.ts +6 -0
  24. package/build/tools/ui-ux-tools.test.js +132 -0
  25. package/build/utils/ascii-box-formatter.d.ts +29 -0
  26. package/build/utils/ascii-box-formatter.js +195 -0
  27. package/build/utils/bm25.d.ts +60 -0
  28. package/build/utils/bm25.js +139 -0
  29. package/build/utils/cache-manager.d.ts +65 -0
  30. package/build/utils/cache-manager.js +156 -0
  31. package/build/utils/design-reasoning-engine.d.ts +158 -0
  32. package/build/utils/design-reasoning-engine.js +363 -0
  33. package/build/utils/design-system-json-formatter.d.ts +41 -0
  34. package/build/utils/design-system-json-formatter.js +165 -0
  35. package/build/utils/ui-data-loader.d.ts +56 -0
  36. package/build/utils/ui-data-loader.js +164 -0
  37. package/build/utils/ui-search-engine.d.ts +57 -0
  38. package/build/utils/ui-search-engine.js +123 -0
  39. package/build/utils/ui-sync.d.ts +13 -0
  40. package/build/utils/ui-sync.js +241 -0
  41. package/docs/BEST_PRACTICES.md +257 -1
  42. package/docs/HOW_TO_TRIGGER.md +71 -1
  43. package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.html +89 -29
  44. package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.md +582 -1
  45. package/package.json +19 -6
  46. package/docs/HOW_TO_TRIGGER.html +0 -255
@@ -0,0 +1,756 @@
1
+ /**
2
+ * UI/UX Pro Max 工具集(重构版)
3
+ *
4
+ * 提供智能设计系统生成、UI/UX 数据搜索和数据同步功能
5
+ * 使用模板类实现文档生成的原子化
6
+ */
7
+ import { UIDataLoader } from '../utils/ui-data-loader.js';
8
+ import { DesignReasoningEngine } from '../utils/design-reasoning-engine.js';
9
+ import { ASCIIBoxFormatter } from '../utils/ascii-box-formatter.js';
10
+ import { syncUIDataToCache } from '../utils/ui-sync.js';
11
+ import { formatDesignSystemJson } from '../utils/design-system-json-formatter.js';
12
+ // 全局数据加载器实例
13
+ let dataLoader = null;
14
+ let reasoningEngine = null;
15
+ /**
16
+ * 生成文件索引
17
+ * 定义需要创建的文件列表及其创建顺序
18
+ *
19
+ * @returns FileIndex[] - 按创建顺序排列的文件索引数组
20
+ *
21
+ * Requirements: 3.1, 3.2, 3.3, 3.4
22
+ */
23
+ export function generateFileIndex() {
24
+ return [
25
+ {
26
+ path: 'docs/design-system.json',
27
+ purpose: '机器可读的设计系统配置文件,包含颜色、字体、间距等精确数值',
28
+ order: 1,
29
+ required: true,
30
+ },
31
+ {
32
+ path: 'docs/design-guidelines/README.md',
33
+ purpose: '设计指南目录文件,提供所有设计文档的索引和导航',
34
+ order: 2,
35
+ required: true,
36
+ },
37
+ {
38
+ path: 'docs/design-guidelines/01-principles.md',
39
+ purpose: '设计原则文档,定义核心设计价值观和指导原则',
40
+ order: 3,
41
+ required: true,
42
+ },
43
+ {
44
+ path: 'docs/design-guidelines/02-interaction.md',
45
+ purpose: '交互规范文档,定义用户交互模式和反馈机制',
46
+ order: 4,
47
+ required: true,
48
+ },
49
+ {
50
+ path: 'docs/design-guidelines/03-layout.md',
51
+ purpose: '布局规范文档,定义栅格系统和页面布局模式',
52
+ order: 5,
53
+ required: true,
54
+ },
55
+ {
56
+ path: 'docs/design-guidelines/04-config.md',
57
+ purpose: '技术配置文档,提供具体技术栈的配置代码示例',
58
+ order: 6,
59
+ required: true,
60
+ },
61
+ {
62
+ path: 'docs/design-system.md',
63
+ purpose: '设计系统主文档,包含 ASCII Box 推荐和完整的设计系统概览',
64
+ order: 7,
65
+ required: true,
66
+ },
67
+ ];
68
+ }
69
+ /**
70
+ * 生成创作指导
71
+ * 为 AI 提供文档创作的主题和提示,而非具体内容
72
+ *
73
+ * @param productType - 产品类型(如 "SaaS", "E-commerce")
74
+ * @param stack - 技术栈(如 "react", "vue", "nextjs")
75
+ * @returns CreationGuidance - 包含各类文档的主题列表和创作提示
76
+ *
77
+ * Requirements: 4.2, 4.3, 4.4, 4.5, 5.3, 5.4
78
+ */
79
+ export function generateCreationGuidance(productType, stack) {
80
+ // 设计原则文档的主题列表
81
+ const principles = [
82
+ '核心设计原则(一致性、反馈、效率、容错性)',
83
+ '设计价值观和理念',
84
+ '用户体验目标',
85
+ '可访问性原则',
86
+ '设计决策指导',
87
+ '品牌一致性要求',
88
+ ];
89
+ // 交互规范文档的主题列表
90
+ const interaction = [
91
+ '按钮和链接的交互状态(hover、active、disabled)',
92
+ '表单交互模式(输入、验证、错误提示)',
93
+ '反馈机制(成功、错误、警告、信息提示)',
94
+ '加载状态和骨架屏',
95
+ '动效和过渡效果规范',
96
+ '手势和触摸交互(移动端)',
97
+ '键盘导航和快捷键',
98
+ ];
99
+ // 布局规范文档的主题列表
100
+ const layout = [
101
+ '栅格系统(列数、间距、断点)',
102
+ '页面布局模式(单栏、双栏、三栏)',
103
+ '组件布局和对齐规则',
104
+ '响应式设计策略',
105
+ '间距系统(margin、padding)',
106
+ '容器和包装器规范',
107
+ 'Z-index 层级管理',
108
+ ];
109
+ // 技术配置文档的主题列表
110
+ const config = [
111
+ '设计 Token 配置(颜色、字体、间距)',
112
+ '主题配置代码示例',
113
+ 'CSS Variables 定义',
114
+ '组件样式实现指南',
115
+ '工具类和辅助函数',
116
+ '构建和打包配置',
117
+ ];
118
+ // 根据技术栈调整配置主题
119
+ if (stack) {
120
+ const stackLower = stack.toLowerCase();
121
+ if (stackLower.includes('tailwind')) {
122
+ config.push('Tailwind CSS 配置文件示例');
123
+ config.push('自定义 Tailwind 插件');
124
+ }
125
+ if (stackLower.includes('react') || stackLower.includes('next')) {
126
+ config.push('React 组件样式方案(CSS Modules / Styled Components)');
127
+ config.push('Theme Provider 配置');
128
+ }
129
+ if (stackLower.includes('vue') || stackLower.includes('nuxt')) {
130
+ config.push('Vue 组件样式方案(Scoped CSS / CSS Modules)');
131
+ config.push('Vue 插件配置');
132
+ }
133
+ if (stackLower.includes('svelte')) {
134
+ config.push('Svelte 组件样式方案');
135
+ config.push('Svelte 预处理器配置');
136
+ }
137
+ if (stackLower.includes('astro')) {
138
+ config.push('Astro 组件样式方案');
139
+ config.push('Astro 集成配置');
140
+ }
141
+ }
142
+ // 生成创作提示
143
+ const tips = [
144
+ `根据产品类型 "${productType}" 调整文档重点和示例`,
145
+ '使用 design-system.json 中的精确数值(颜色、字体大小、间距等)',
146
+ '参考 ASCII Box 推荐中的核心建议',
147
+ '根据反模式(antiPatterns)提供"应避免"的建议',
148
+ '提供具体的代码示例,而非抽象描述',
149
+ '确保所有文档之间保持一致性',
150
+ '使用清晰的标题层级和结构',
151
+ ];
152
+ // 根据技术栈添加特定提示
153
+ if (stack) {
154
+ tips.push(`在技术配置文档中提供 ${stack} 的具体实现示例`);
155
+ tips.push(`确保代码示例符合 ${stack} 的最佳实践`);
156
+ }
157
+ // 根据产品类型添加特定提示
158
+ const productTypeLower = productType.toLowerCase();
159
+ if (productTypeLower.includes('saas') || productTypeLower.includes('b2b')) {
160
+ tips.push('强调专业性、效率和数据密集型界面的设计');
161
+ }
162
+ else if (productTypeLower.includes('ecommerce') || productTypeLower.includes('e-commerce')) {
163
+ tips.push('强调产品展示、购物流程和转化率优化');
164
+ }
165
+ else if (productTypeLower.includes('healthcare') || productTypeLower.includes('medical')) {
166
+ tips.push('强调可访问性、清晰度和信任感');
167
+ }
168
+ else if (productTypeLower.includes('fintech') || productTypeLower.includes('finance')) {
169
+ tips.push('强调安全性、可信度和数据可视化');
170
+ }
171
+ return {
172
+ principles,
173
+ interaction,
174
+ layout,
175
+ config,
176
+ tips,
177
+ };
178
+ }
179
+ /**
180
+ * 获取数据加载器实例
181
+ */
182
+ async function getDataLoader() {
183
+ if (!dataLoader) {
184
+ dataLoader = new UIDataLoader({
185
+ useCache: true,
186
+ autoUpdate: true,
187
+ });
188
+ await dataLoader.load();
189
+ }
190
+ return dataLoader;
191
+ }
192
+ /**
193
+ * 获取推理引擎实例
194
+ */
195
+ export async function getReasoningEngine() {
196
+ if (!reasoningEngine) {
197
+ const loader = await getDataLoader();
198
+ const searchEngine = loader.getSearchEngine();
199
+ reasoningEngine = new DesignReasoningEngine();
200
+ // 加载所有数据(包括推理规则)
201
+ const products = searchEngine.getCategoryData('products') || [];
202
+ const styles = searchEngine.getCategoryData('styles') || [];
203
+ const colors = searchEngine.getCategoryData('colors') || [];
204
+ const typography = searchEngine.getCategoryData('typography') || [];
205
+ const landing = searchEngine.getCategoryData('landing') || [];
206
+ const uxGuidelines = searchEngine.getCategoryData('ux-guidelines') || [];
207
+ const reasoning = (searchEngine.getCategoryData('ui-reasoning') || []);
208
+ reasoningEngine.loadData({
209
+ products,
210
+ styles,
211
+ colors,
212
+ typography,
213
+ landing,
214
+ uxGuidelines,
215
+ reasoning: reasoning,
216
+ });
217
+ }
218
+ return reasoningEngine;
219
+ }
220
+ /**
221
+ * UI 设计系统生成工具(重构版 - AI 驱动的文档生成)
222
+ *
223
+ * 不再使用硬编码模板,而是返回核心数据和创作指导,
224
+ * 让 AI 根据推荐自由创建文档内容
225
+ *
226
+ * Requirements: 1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.5, 6.1-6.6
227
+ */
228
+ export async function uiDesignSystem(args) {
229
+ try {
230
+ // 构建设计请求
231
+ const request = {
232
+ productType: args.product_type || args.description || 'SaaS',
233
+ description: args.description,
234
+ stack: args.stack,
235
+ targetAudience: args.target_audience,
236
+ keywords: args.keywords ? args.keywords.split(',').map((k) => k.trim()) : undefined,
237
+ };
238
+ // 获取推理引擎
239
+ const engine = await getReasoningEngine();
240
+ // 生成设计系统推荐
241
+ const recommendation = engine.generateRecommendation(request);
242
+ // 格式化输出(保留 ASCII Box 和 JSON 格式化)
243
+ const formatter = new ASCIIBoxFormatter();
244
+ const asciiBox = formatter.format(recommendation);
245
+ // 生成 JSON 格式
246
+ const designSystemJson = formatDesignSystemJson(recommendation, request.productType, request.stack);
247
+ // 生成文件索引(按创建顺序)
248
+ const fileIndex = generateFileIndex();
249
+ // 生成创作指导
250
+ const creationGuidance = generateCreationGuidance(request.productType, request.stack);
251
+ // 构建输出对象
252
+ const output = {
253
+ asciiBox,
254
+ designSystemJson,
255
+ fileIndex,
256
+ creationGuidance,
257
+ recommendation,
258
+ };
259
+ // 格式化文件索引列表
260
+ const fileIndexList = fileIndex
261
+ .map(file => `${file.order}. **${file.path}** ${file.required ? '(必需)' : '(可选)'}\n ${file.purpose}`)
262
+ .join('\n\n');
263
+ // 格式化创作指导
264
+ const guidanceText = `
265
+ ### 设计原则文档主题
266
+ ${creationGuidance.principles.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
267
+
268
+ ### 交互规范文档主题
269
+ ${creationGuidance.interaction.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
270
+
271
+ ### 布局规范文档主题
272
+ ${creationGuidance.layout.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
273
+
274
+ ### 技术配置文档主题
275
+ ${creationGuidance.config.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
276
+
277
+ ### 创作提示
278
+ ${creationGuidance.tips.map((tip, i) => `${i + 1}. ${tip}`).join('\n')}
279
+ `;
280
+ // 返回新的输出格式(Requirements: 2.1, 2.5, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6)
281
+ return {
282
+ content: [
283
+ {
284
+ type: "text",
285
+ text: `# ✅ 设计系统推荐已生成
286
+
287
+ **产品类型**: ${request.productType}
288
+ **技术栈**: ${request.stack || 'html'}
289
+ ${request.targetAudience ? `**目标用户**: ${request.targetAudience}` : ''}
290
+
291
+ ---
292
+
293
+ ## 🎨 1. 核心设计推荐(ASCII Box)
294
+
295
+ 以下是基于 AI 推理引擎生成的核心设计推荐:
296
+
297
+ \`\`\`
298
+ ${asciiBox}
299
+ \`\`\`
300
+
301
+ ---
302
+
303
+ ## 📊 2. 精确配置数据(JSON)
304
+
305
+ 以下是机器可读的设计系统配置,包含所有精确数值:
306
+
307
+ \`\`\`json
308
+ ${JSON.stringify(designSystemJson, null, 2)}
309
+ \`\`\`
310
+
311
+ ---
312
+
313
+ ## 📁 3. 文件索引(按创建顺序)
314
+
315
+ 请严格按照以下顺序创建文件:
316
+
317
+ ${fileIndexList}
318
+
319
+ **注意**: design-system.md 是最后创建的主文档,它应该包含完整的设计系统概览和 ASCII Box 推荐。
320
+
321
+ ---
322
+
323
+ ## 📝 4. 文档创作指导
324
+
325
+ 以下是各类文档应包含的关键主题。**请根据上述 ASCII Box 推荐和 JSON 数据自由创作内容,不要使用固定模板**:
326
+
327
+ ${guidanceText}
328
+
329
+ ---
330
+
331
+ ## ✨ 请根据以上推荐和指导创建文档
332
+
333
+ **现在,请按照文件索引的顺序,逐个创建设计系统文档。**
334
+
335
+ ### 创作要求:
336
+
337
+ 1. **使用核心数据**:
338
+ - 将 ASCII Box 中的核心推荐作为设计依据
339
+ - 使用 JSON 数据中的精确数值(颜色代码、字体大小、间距值等)
340
+ - 确保所有数值与 JSON 配置保持一致
341
+
342
+ 2. **遵循文件顺序**:
343
+ - 严格按照文件索引的顺序创建(1→2→3→4→5→6→7)
344
+ - design-system.json 最先创建(包含所有精确配置)
345
+ - design-system.md 最后创建(包含完整概览)
346
+
347
+ 3. **自由创作内容**:
348
+ - 参考创作指导中的主题列表
349
+ - 根据产品类型 "${request.productType}" 调整重点
350
+ ${request.stack ? `- 提供 ${request.stack} 的具体实现示例` : ''}
351
+ - 不要局限于固定模板,发挥创造力
352
+
353
+ 4. **保持一致性**:
354
+ - 所有文档使用相同的设计 Token(颜色、字体、间距)
355
+ - 确保术语和命名规范统一
356
+ - 交叉引用其他文档时保持准确
357
+
358
+ 5. **提供实用示例**:
359
+ - 包含具体的代码示例(不要抽象描述)
360
+ - 展示实际应用场景
361
+ - 参考反模式(antiPatterns)提供"应避免"的建议
362
+
363
+ ### 开始创作:
364
+
365
+ **第一步**:创建 \`docs/design-system.json\`,包含所有精确配置数据(使用上面的 JSON)
366
+
367
+ **第二步**:创建 \`docs/design-guidelines/README.md\`,提供设计指南的索引和导航
368
+
369
+ **第三步至第六步**:依次创建四个设计指南文档(principles、interaction、layout、config)
370
+
371
+ **最后一步**:创建 \`docs/design-system.md\`,包含以下内容:
372
+ - ASCII Box 推荐(核心设计)
373
+ - 完整的设计系统概览
374
+ - **文件索引**(列出所有设计文档的链接,方便后续查看和使用)
375
+ - 快速开始指南
376
+
377
+ ---
378
+
379
+ 🚀 **准备好了吗?让我们开始创建第一个文件吧!**
380
+ `,
381
+ },
382
+ ],
383
+ };
384
+ }
385
+ catch (error) {
386
+ const errorMessage = error instanceof Error ? error.message : String(error);
387
+ return {
388
+ content: [
389
+ {
390
+ type: "text",
391
+ text: `❌ 设计系统生成失败: ${errorMessage}
392
+
393
+ **可能的原因**:
394
+ 1. 数据未加载完成
395
+ 2. 产品类型不明确
396
+ 3. 数据格式错误
397
+
398
+ **建议**:
399
+ 1. 提供更具体的产品类型(如 "SaaS", "E-commerce", "Healthcare")
400
+ 2. 添加产品描述帮助推理引擎理解需求
401
+ 3. 检查数据是否已同步(使用 \`sync_ui_data\` 工具)
402
+ `,
403
+ },
404
+ ],
405
+ isError: true,
406
+ };
407
+ }
408
+ }
409
+ /**
410
+ * UI 搜索工具(增强版)
411
+ */
412
+ export async function uiSearch(args) {
413
+ try {
414
+ const mode = args.mode || 'search';
415
+ const query = args.query || '';
416
+ // 模式 1: catalog - 返回组件目录
417
+ if (mode === 'catalog') {
418
+ const fs = await import('fs/promises');
419
+ const path = await import('path');
420
+ const catalogPath = path.join(process.cwd(), 'docs', 'ui', 'component-catalog.json');
421
+ try {
422
+ const catalogContent = await fs.readFile(catalogPath, 'utf-8');
423
+ const catalog = JSON.parse(catalogContent);
424
+ // 格式化组件列表
425
+ const components = catalog.components || [];
426
+ const componentList = components.map((comp, index) => {
427
+ return `### ${index + 1}. ${comp.name}
428
+
429
+ **描述**: ${comp.description || '无'}
430
+ **Props**: ${Object.keys(comp.props || {}).join(', ')}
431
+ **样式**: ${comp.styles ? Object.keys(comp.styles).join(', ') : '无'}
432
+ `;
433
+ }).join('\n---\n\n');
434
+ return {
435
+ content: [
436
+ {
437
+ type: "text",
438
+ text: `# 📦 组件目录
439
+
440
+ 共 ${components.length} 个可用组件
441
+
442
+ ---
443
+
444
+ ${componentList}
445
+
446
+ **提示**: 这些组件可以在 UI 模板中使用
447
+ `,
448
+ },
449
+ ],
450
+ };
451
+ }
452
+ catch (error) {
453
+ return {
454
+ content: [
455
+ {
456
+ type: "text",
457
+ text: `❌ 未找到组件目录文件
458
+
459
+ 请先运行 \`init_component_catalog\` 生成组件目录。
460
+ `,
461
+ },
462
+ ],
463
+ isError: true,
464
+ };
465
+ }
466
+ }
467
+ // 模式 2: template - 搜索 UI 模板
468
+ if (mode === 'template') {
469
+ const fs = await import('fs/promises');
470
+ const path = await import('path');
471
+ const templatesDir = path.join(process.cwd(), 'docs', 'ui', 'pages');
472
+ try {
473
+ // 检查模板目录是否存在
474
+ await fs.access(templatesDir);
475
+ // 读取所有模板文件
476
+ const files = await fs.readdir(templatesDir);
477
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
478
+ if (jsonFiles.length === 0) {
479
+ return {
480
+ content: [
481
+ {
482
+ type: "text",
483
+ text: `📭 暂无可用模板
484
+
485
+ **建议**:
486
+ 1. 使用 \`start_ui\` 生成新模板
487
+ 2. 模板会自动保存到 \`docs/ui/pages/\` 目录
488
+ 3. 下次可以直接搜索使用
489
+
490
+ **示例**:
491
+ \`\`\`
492
+ start_ui "登录页面"
493
+ start_ui "用户列表"
494
+ \`\`\`
495
+ `,
496
+ },
497
+ ],
498
+ };
499
+ }
500
+ // 读取所有模板内容
501
+ const templates = await Promise.all(jsonFiles.map(async (file) => {
502
+ const filePath = path.join(templatesDir, file);
503
+ const content = await fs.readFile(filePath, 'utf-8');
504
+ const template = JSON.parse(content);
505
+ return {
506
+ file,
507
+ name: template.name || file.replace('.json', ''),
508
+ description: template.description || '无描述',
509
+ template,
510
+ };
511
+ }));
512
+ // 如果有查询,进行简单的文本匹配
513
+ let filteredTemplates = templates;
514
+ if (query) {
515
+ const lowerQuery = query.toLowerCase();
516
+ filteredTemplates = templates.filter(t => t.name.toLowerCase().includes(lowerQuery) ||
517
+ t.description.toLowerCase().includes(lowerQuery));
518
+ }
519
+ if (filteredTemplates.length === 0) {
520
+ return {
521
+ content: [
522
+ {
523
+ type: "text",
524
+ text: `未找到匹配的模板
525
+
526
+ **查询**: ${query}
527
+ **可用模板**: ${templates.map(t => t.name).join(', ')}
528
+
529
+ **建议**: 使用 \`start_ui "${query}"\` 生成新模板
530
+ `,
531
+ },
532
+ ],
533
+ };
534
+ }
535
+ // 格式化模板列表
536
+ const templateList = filteredTemplates.map((t, index) => {
537
+ return `### ${index + 1}. ${t.name}
538
+
539
+ **文件**: \`docs/ui/pages/${t.file}\`
540
+ **描述**: ${t.description}
541
+ **组件数**: ${JSON.stringify(t.template).match(/"type":/g)?.length || 0}
542
+
543
+ \`\`\`json
544
+ ${JSON.stringify(t.template, null, 2)}
545
+ \`\`\`
546
+ `;
547
+ }).join('\n---\n\n');
548
+ return {
549
+ content: [
550
+ {
551
+ type: "text",
552
+ text: `# 📄 UI 模板搜索结果
553
+
554
+ 找到 ${filteredTemplates.length} 个匹配模板
555
+
556
+ ---
557
+
558
+ ${templateList}
559
+
560
+ **使用方法**:
561
+ \`\`\`
562
+ render_ui docs/ui/pages/<文件名>.json --framework=react
563
+ \`\`\`
564
+ `,
565
+ },
566
+ ],
567
+ };
568
+ }
569
+ catch (error) {
570
+ return {
571
+ content: [
572
+ {
573
+ type: "text",
574
+ text: `📭 暂无可用模板
575
+
576
+ 模板目录不存在或为空。
577
+
578
+ **建议**:
579
+ 使用 \`start_ui\` 生成第一个模板:
580
+
581
+ \`\`\`
582
+ start_ui "登录页面"
583
+ start_ui "用户列表"
584
+ start_ui "设置页面"
585
+ \`\`\`
586
+
587
+ 模板会自动保存到 \`docs/ui/pages/\` 目录。
588
+ `,
589
+ },
590
+ ],
591
+ };
592
+ }
593
+ }
594
+ // 模式 3: search - 默认搜索模式(原有功能)
595
+ const loader = await getDataLoader();
596
+ const searchEngine = loader.getSearchEngine();
597
+ const options = {
598
+ category: args.category,
599
+ stack: args.stack,
600
+ limit: args.limit || 10,
601
+ minScore: args.min_score || 0,
602
+ };
603
+ const results = searchEngine.search(query, options);
604
+ if (results.length === 0) {
605
+ return {
606
+ content: [
607
+ {
608
+ type: "text",
609
+ text: `未找到匹配的 UI/UX 数据。
610
+
611
+ **搜索条件:**
612
+ - 查询: ${query}
613
+ - 类别: ${options.category || '全部'}
614
+ - 技术栈: ${options.stack || '全部'}
615
+
616
+ **建议:**
617
+ 1. 尝试使用更通用的关键词
618
+ 2. 检查拼写是否正确
619
+ 3. 移除类别或技术栈限制
620
+ `,
621
+ },
622
+ ],
623
+ };
624
+ }
625
+ // 格式化结果
626
+ const formattedResults = results.map((result, index) => {
627
+ const data = result.data;
628
+ const fields = Object.entries(data)
629
+ .filter(([_key, value]) => value != null && value !== '')
630
+ .map(([key, value]) => {
631
+ if (typeof value === 'object') {
632
+ return `- **${key}**: \`${JSON.stringify(value)}\``;
633
+ }
634
+ return `- **${key}**: ${value}`;
635
+ })
636
+ .join('\n');
637
+ return `### ${index + 1}. ${result.category} (相关度: ${result.score.toFixed(2)})
638
+
639
+ ${fields}
640
+ `;
641
+ }).join('\n---\n\n');
642
+ return {
643
+ content: [
644
+ {
645
+ type: "text",
646
+ text: `# UI/UX 搜索结果
647
+
648
+ 找到 ${results.length} 条匹配结果
649
+
650
+ **搜索条件:**
651
+ - 查询: ${query}
652
+ - 类别: ${options.category || '全部'}
653
+ - 技术栈: ${options.stack || '全部'}
654
+
655
+ ---
656
+
657
+ ${formattedResults}
658
+ `,
659
+ },
660
+ ],
661
+ };
662
+ }
663
+ catch (error) {
664
+ const errorMessage = error instanceof Error ? error.message : String(error);
665
+ return {
666
+ content: [
667
+ {
668
+ type: "text",
669
+ text: `❌ UI 搜索失败: ${errorMessage}`,
670
+ },
671
+ ],
672
+ isError: true,
673
+ };
674
+ }
675
+ }
676
+ /**
677
+ * UI 数据同步工具
678
+ */
679
+ export async function syncUiData(args) {
680
+ try {
681
+ const force = args.force || false;
682
+ const verbose = args.verbose || false;
683
+ // 检查是否需要更新
684
+ if (!force) {
685
+ const loader = await getDataLoader();
686
+ const cacheManager = loader.getCacheManager();
687
+ try {
688
+ const updateInfo = await cacheManager.checkUpdate();
689
+ if (!updateInfo.hasUpdate) {
690
+ return {
691
+ content: [
692
+ {
693
+ type: "text",
694
+ text: `✅ UI/UX 数据已是最新版本
695
+
696
+ **当前版本:** ${updateInfo.currentVersion}
697
+ **最新版本:** ${updateInfo.latestVersion}
698
+
699
+ 无需更新。如需强制同步,请使用 \`force: true\` 参数。
700
+ `,
701
+ },
702
+ ],
703
+ };
704
+ }
705
+ console.log(`Update available: ${updateInfo.currentVersion || 'none'} -> ${updateInfo.latestVersion}`);
706
+ }
707
+ catch (error) {
708
+ console.log('Failed to check update, proceeding with sync...');
709
+ }
710
+ }
711
+ // 执行同步
712
+ await syncUIDataToCache(force, verbose);
713
+ // 重新加载数据
714
+ if (dataLoader) {
715
+ await dataLoader.reload();
716
+ }
717
+ const cacheDir = dataLoader?.getCacheManager().getCacheDir() || '';
718
+ return {
719
+ content: [
720
+ {
721
+ type: "text",
722
+ text: `✅ UI/UX 数据同步成功
723
+
724
+ 数据已更新到缓存目录: ${cacheDir}
725
+
726
+ **提示:** 数据已自动重新加载,可以立即使用最新数据。
727
+ `,
728
+ },
729
+ ],
730
+ };
731
+ }
732
+ catch (error) {
733
+ const errorMessage = error instanceof Error ? error.message : String(error);
734
+ return {
735
+ content: [
736
+ {
737
+ type: "text",
738
+ text: `❌ UI 数据同步失败: ${errorMessage}
739
+
740
+ **可能的原因:**
741
+ 1. 网络连接问题
742
+ 2. npm registry 不可访问
743
+ 3. 磁盘空间不足
744
+ 4. 权限问题
745
+
746
+ **建议:**
747
+ 1. 检查网络连接
748
+ 2. 稍后重试
749
+ 3. 使用 \`verbose: true\` 查看详细日志
750
+ `,
751
+ },
752
+ ],
753
+ isError: true,
754
+ };
755
+ }
756
+ }