mcp-probe-kit 3.0.19 → 3.0.22

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 (81) hide show
  1. package/README.md +12 -5
  2. package/build/index.js +3 -1
  3. package/build/lib/__tests__/agents-md-template.unit.test.js +2 -0
  4. package/build/lib/__tests__/memory-config.unit.test.js +9 -0
  5. package/build/lib/__tests__/memory-injection.unit.test.d.ts +1 -0
  6. package/build/lib/__tests__/memory-injection.unit.test.js +51 -0
  7. package/build/lib/__tests__/memory-orchestration.unit.test.d.ts +1 -0
  8. package/build/lib/__tests__/memory-orchestration.unit.test.js +84 -0
  9. package/build/lib/__tests__/memory-payload.unit.test.d.ts +1 -0
  10. package/build/lib/__tests__/memory-payload.unit.test.js +35 -0
  11. package/build/lib/agents-md-template.js +7 -5
  12. package/build/lib/memory-client.d.ts +8 -1
  13. package/build/lib/memory-client.js +53 -44
  14. package/build/lib/memory-config.d.ts +8 -0
  15. package/build/lib/memory-config.js +19 -0
  16. package/build/lib/memory-orchestration.d.ts +7 -2
  17. package/build/lib/memory-orchestration.js +81 -8
  18. package/build/lib/memory-payload.d.ts +21 -0
  19. package/build/lib/memory-payload.js +65 -0
  20. package/build/lib/shadcn-ui.d.ts +11 -0
  21. package/build/lib/shadcn-ui.js +78 -0
  22. package/build/resources/ui-ux-data/guidelines/vercel-web-interface.json +1632 -0
  23. package/build/resources/ui-ux-data/metadata.json +27 -3
  24. package/build/resources/ui-ux-data/shadcn/blocks.json +2541 -0
  25. package/build/resources/ui-ux-data/shadcn/components.json +997 -0
  26. package/build/resources/ui-ux-data/themes/presets.json +483 -0
  27. package/build/schemas/index.d.ts +38 -9
  28. package/build/schemas/memory-tools.d.ts +38 -9
  29. package/build/schemas/memory-tools.js +24 -9
  30. package/build/schemas/output/ui-ux-tools.d.ts +16 -0
  31. package/build/schemas/output/ui-ux-tools.js +4 -0
  32. package/build/schemas/ui-ux-schemas.js +3 -3
  33. package/build/tools/__tests__/start_ui.property.test.js +4 -3
  34. package/build/tools/index.d.ts +1 -0
  35. package/build/tools/index.js +1 -0
  36. package/build/tools/memorize_asset.js +12 -0
  37. package/build/tools/scan_and_extract_patterns.js +7 -7
  38. package/build/tools/search_memory.d.ts +7 -0
  39. package/build/tools/search_memory.js +57 -0
  40. package/build/tools/start_bugfix.js +3 -3
  41. package/build/tools/start_feature.js +3 -3
  42. package/build/tools/start_ui.js +33 -6
  43. package/build/tools/ui-ux-tools.js +322 -244
  44. package/build/utils/__tests__/shadcn-sync.unit.test.d.ts +1 -0
  45. package/build/utils/__tests__/shadcn-sync.unit.test.js +49 -0
  46. package/build/utils/__tests__/theme-pick.unit.test.d.ts +1 -0
  47. package/build/utils/__tests__/theme-pick.unit.test.js +9 -0
  48. package/build/utils/__tests__/themes-sync.unit.test.d.ts +1 -0
  49. package/build/utils/__tests__/themes-sync.unit.test.js +21 -0
  50. package/build/utils/__tests__/ui-metadata.unit.test.d.ts +1 -0
  51. package/build/utils/__tests__/ui-metadata.unit.test.js +35 -0
  52. package/build/utils/__tests__/vercel-guidelines-sync.unit.test.d.ts +1 -0
  53. package/build/utils/__tests__/vercel-guidelines-sync.unit.test.js +34 -0
  54. package/build/utils/bm25.d.ts +2 -1
  55. package/build/utils/bm25.js +17 -5
  56. package/build/utils/shadcn-sync.d.ts +55 -0
  57. package/build/utils/shadcn-sync.js +146 -0
  58. package/build/utils/themes-sync.d.ts +32 -0
  59. package/build/utils/themes-sync.js +201 -0
  60. package/build/utils/ui-data-loader.js +13 -2
  61. package/build/utils/ui-metadata.d.ts +27 -0
  62. package/build/utils/ui-metadata.js +39 -0
  63. package/build/utils/ui-search-engine.d.ts +1 -0
  64. package/build/utils/ui-search-engine.js +20 -6
  65. package/build/utils/ui-sync.d.ts +24 -2
  66. package/build/utils/ui-sync.js +152 -86
  67. package/build/utils/vercel-guidelines-sync.d.ts +30 -0
  68. package/build/utils/vercel-guidelines-sync.js +133 -0
  69. package/docs/data/tools.js +18 -0
  70. package/docs/i18n/all-tools/en.json +6 -1
  71. package/docs/i18n/all-tools/ja.json +2 -1
  72. package/docs/i18n/all-tools/ko.json +2 -1
  73. package/docs/i18n/all-tools/zh-CN.json +7 -2
  74. package/docs/i18n/en.json +5 -5
  75. package/docs/i18n/ja.json +2 -2
  76. package/docs/i18n/ko.json +2 -2
  77. package/docs/i18n/zh-CN.json +7 -7
  78. package/docs/memory-local-setup.md +1 -1
  79. package/docs/memory-local-setup.zh-CN.md +5 -2
  80. package/docs/pages/getting-started.html +3 -2
  81. package/package.json +2 -2
@@ -7,7 +7,8 @@
7
7
  import { UIDataLoader } from '../utils/ui-data-loader.js';
8
8
  import { DesignReasoningEngine } from '../utils/design-reasoning-engine.js';
9
9
  import { ASCIIBoxFormatter } from '../utils/ascii-box-formatter.js';
10
- import { syncUIDataToCache } from '../utils/ui-sync.js';
10
+ import { syncUIDataToCache, checkUISourcesUpdate } from '../utils/ui-sync.js';
11
+ import { formatShadcnResult, formatGuidelineResult, formatThemeResult, isGuidelineCategory, isShadcnCategory, isShadcnStack, isThemeCategory, pickThemeForProductType } from '../lib/shadcn-ui.js';
11
12
  import { formatDesignSystemJson } from '../utils/design-system-json-formatter.js';
12
13
  import { okStructured } from '../lib/response.js';
13
14
  import { reportToolProgress, throwIfAborted, } from '../lib/tool-execution-context.js';
@@ -127,6 +128,8 @@ export function generateCreationGuidance(productType, stack) {
127
128
  if (stackLower.includes('react') || stackLower.includes('next')) {
128
129
  config.push('React 组件样式方案(CSS Modules / Styled Components)');
129
130
  config.push('Theme Provider 配置');
131
+ config.push('shadcn/ui 初始化与主题变量(components.json、globals.css)');
132
+ config.push('优先使用 shadcn blocks/components,通过 `npx shadcn@latest add <name>` 安装');
130
133
  }
131
134
  if (stackLower.includes('vue') || stackLower.includes('nuxt')) {
132
135
  config.push('Vue 组件样式方案(Scoped CSS / CSS Modules)');
@@ -151,8 +154,14 @@ export function generateCreationGuidance(productType, stack) {
151
154
  '确保所有文档之间保持一致性',
152
155
  '使用清晰的标题层级和结构',
153
156
  ];
154
- // 根据技术栈添加特定提示
155
- if (stack) {
157
+ if (stack && isShadcnStack(stack)) {
158
+ tips.push(`在技术配置文档中提供 ${stack} + shadcn/ui 的具体实现示例`);
159
+ tips.push('用 `ui_search --category=ui-themes` 选主题,把 globalsCssSnippet 写入 globals.css');
160
+ tips.push('用 `ui_search --category=ui-guidelines-vercel` 对照 Vercel 界面规范(无障碍/动效/表单)');
161
+ tips.push('实现阶段先 `ui_search --category=shadcn-blocks` 匹配 block,再 `npx shadcn@latest add <name>` 安装');
162
+ tips.push('避免手写泛 Tailwind 模板;组件结构对齐 shadcn/ui new-york 风格');
163
+ }
164
+ else if (stack) {
156
165
  tips.push(`在技术配置文档中提供 ${stack} 的具体实现示例`);
157
166
  tips.push(`确保代码示例符合 ${stack} 的最佳实践`);
158
167
  }
@@ -250,6 +259,31 @@ export async function uiDesignSystem(args) {
250
259
  const fileIndex = generateFileIndex();
251
260
  // 生成创作指导
252
261
  const creationGuidance = generateCreationGuidance(request.productType, request.stack);
262
+ const loader = await getDataLoader();
263
+ const themeRecommendation = isShadcnStack(request.stack)
264
+ ? pickThemeForProductType(loader.getSearchEngine().getCategoryData('ui-themes') || [], request.productType)
265
+ : undefined;
266
+ const themeSection = themeRecommendation
267
+ ? `
268
+ ## 🎨 推荐 shadcn 主题(内嵌预设)
269
+
270
+ - **主题**: ${themeRecommendation.title} (\`${themeRecommendation.name}\`)
271
+ - **说明**: ${themeRecommendation.description}
272
+ - **操作**: 将下方 CSS variables 写入 \`app/globals.css\`;也可用 \`ui_search --category=ui-themes --query="${request.productType}"\`
273
+
274
+ \`\`\`css
275
+ ${themeRecommendation.globalsCssSnippet}
276
+ \`\`\`
277
+ `
278
+ : '';
279
+ const vercelSection = isShadcnStack(request.stack)
280
+ ? `
281
+ ## ✅ Vercel 界面规范(实现时对照)
282
+
283
+ - 检索: \`ui_search --category=ui-guidelines-vercel --query="form accessibility animation"\`
284
+ - 重点: 表单可访问性、\`prefers-reduced-motion\`、对比度、键盘焦点、禁止 \`transition: all\`
285
+ `
286
+ : '';
253
287
  // 构建输出对象
254
288
  const output = {
255
289
  asciiBox,
@@ -263,117 +297,126 @@ export async function uiDesignSystem(args) {
263
297
  .map(file => `${file.order}. **${file.path}** ${file.required ? '(必需)' : '(可选)'}\n ${file.purpose}`)
264
298
  .join('\n\n');
265
299
  // 格式化创作指导
266
- const guidanceText = `
267
- ### 设计原则文档主题
268
- ${creationGuidance.principles.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
269
-
270
- ### 交互规范文档主题
271
- ${creationGuidance.interaction.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
272
-
273
- ### 布局规范文档主题
274
- ${creationGuidance.layout.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
275
-
276
- ### 技术配置文档主题
277
- ${creationGuidance.config.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
278
-
279
- ### 创作提示
280
- ${creationGuidance.tips.map((tip, i) => `${i + 1}. ${tip}`).join('\n')}
300
+ const guidanceText = `
301
+ ### 设计原则文档主题
302
+ ${creationGuidance.principles.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
303
+
304
+ ### 交互规范文档主题
305
+ ${creationGuidance.interaction.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
306
+
307
+ ### 布局规范文档主题
308
+ ${creationGuidance.layout.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
309
+
310
+ ### 技术配置文档主题
311
+ ${creationGuidance.config.map((topic, i) => `${i + 1}. ${topic}`).join('\n')}
312
+
313
+ ### 创作提示
314
+ ${creationGuidance.tips.map((tip, i) => `${i + 1}. ${tip}`).join('\n')}
281
315
  `;
282
- const message = `# ✅ 设计系统推荐已生成
283
-
284
- **产品类型**: ${request.productType}
285
- **技术栈**: ${request.stack || 'html'}
286
- ${request.targetAudience ? `**目标用户**: ${request.targetAudience}` : ''}
287
-
288
- ---
289
-
290
- ## 🎨 1. 核心设计推荐(ASCII Box)
291
-
292
- 以下是基于 AI 推理引擎生成的核心设计推荐:
293
-
294
- \`\`\`
295
- ${asciiBox}
296
- \`\`\`
297
-
298
- ---
299
-
300
- ## 📊 2. 精确配置数据(JSON)
301
-
302
- 以下是机器可读的设计系统配置,包含所有精确数值:
303
-
304
- \`\`\`json
305
- ${JSON.stringify(designSystemJson, null, 2)}
306
- \`\`\`
307
-
308
- ---
309
-
310
- ## 📁 3. 文件索引(按创建顺序)
311
-
312
- 请严格按照以下顺序创建文件:
313
-
314
- ${fileIndexList}
315
-
316
- **注意**: design-system.md 是最后创建的主文档,它应该包含完整的设计系统概览和 ASCII Box 推荐。
317
-
318
- ---
319
-
320
- ## 📝 4. 文档创作指导
321
-
322
- 以下是各类文档应包含的关键主题。**请根据上述 ASCII Box 推荐和 JSON 数据自由创作内容,不要使用固定模板**:
323
-
324
- ${guidanceText}
325
-
326
- ---
327
-
328
- ## ✨ 请根据以上推荐和指导创建文档
329
-
330
- **现在,请按照文件索引的顺序,逐个创建设计系统文档。**
331
-
332
- ### 创作要求:
333
-
334
- 1. **使用核心数据**:
335
- - 将 ASCII Box 中的核心推荐作为设计依据
336
- - 使用 JSON 数据中的精确数值(颜色代码、字体大小、间距值等)
337
- - 确保所有数值与 JSON 配置保持一致
338
-
339
- 2. **遵循文件顺序**:
340
- - 严格按照文件索引的顺序创建(1→2→3→4→5→6→7)
341
- - design-system.json 最先创建(包含所有精确配置)
342
- - design-system.md 最后创建(包含完整概览)
343
-
344
- 3. **自由创作内容**:
345
- - 参考创作指导中的主题列表
346
- - 根据产品类型 "${request.productType}" 调整重点
347
- ${request.stack ? `- 提供 ${request.stack} 的具体实现示例` : ''}
348
- - 不要局限于固定模板,发挥创造力
349
-
350
- 4. **保持一致性**:
351
- - 所有文档使用相同的设计 Token(颜色、字体、间距)
352
- - 确保术语和命名规范统一
353
- - 交叉引用其他文档时保持准确
354
-
355
- 5. **提供实用示例**:
356
- - 包含具体的代码示例(不要抽象描述)
357
- - 展示实际应用场景
358
- - 参考反模式(antiPatterns)提供"应避免"的建议
359
-
360
- ### 开始创作:
361
-
362
- **第一步**:创建 \`docs/design-system.json\`,包含所有精确配置数据(使用上面的 JSON)
363
-
364
- **第二步**:创建 \`docs/design-guidelines/README.md\`,提供设计指南的索引和导航
365
-
366
- **第三步至第六步**:依次创建四个设计指南文档(principles、interaction、layout、config)
367
-
368
- **最后一步**:创建 \`docs/design-system.md\`,包含以下内容:
369
- - ASCII Box 推荐(核心设计)
370
- - 完整的设计系统概览
371
- - **文件索引**(列出所有设计文档的链接,方便后续查看和使用)
372
- - 快速开始指南
373
-
374
- ---
375
-
376
- 🚀 **准备好了吗?让我们开始创建第一个文件吧!**
316
+ const message = `# ✅ 设计系统推荐已生成
317
+
318
+ **产品类型**: ${request.productType}
319
+ **技术栈**: ${request.stack || 'html'}
320
+ ${request.targetAudience ? `**目标用户**: ${request.targetAudience}` : ''}
321
+
322
+ ---
323
+
324
+ ## 🎨 1. 核心设计推荐(ASCII Box)
325
+
326
+ 以下是基于 AI 推理引擎生成的核心设计推荐:
327
+
328
+ \`\`\`
329
+ ${asciiBox}
330
+ \`\`\`
331
+
332
+ ---
333
+
334
+ ## 📊 2. 精确配置数据(JSON)
335
+
336
+ 以下是机器可读的设计系统配置,包含所有精确数值:
337
+
338
+ \`\`\`json
339
+ ${JSON.stringify(designSystemJson, null, 2)}
340
+ \`\`\`
341
+
342
+ ---
343
+
344
+ ## 📁 3. 文件索引(按创建顺序)
345
+
346
+ 请严格按照以下顺序创建文件:
347
+
348
+ ${fileIndexList}
349
+
350
+ **注意**: design-system.md 是最后创建的主文档,它应该包含完整的设计系统概览和 ASCII Box 推荐。
351
+
352
+ ---
353
+
354
+ ## 📝 4. 文档创作指导
355
+
356
+ 以下是各类文档应包含的关键主题。**请根据上述 ASCII Box 推荐和 JSON 数据自由创作内容,不要使用固定模板**:
357
+
358
+ ${guidanceText}
359
+ ${themeSection}
360
+ ${vercelSection}
361
+
362
+ ---
363
+
364
+ ## ✨ 请根据以上推荐和指导创建文档
365
+
366
+ **现在,请按照文件索引的顺序,逐个创建设计系统文档。**
367
+
368
+ ### 创作要求:
369
+
370
+ 1. **使用核心数据**:
371
+ - ASCII Box 中的核心推荐作为设计依据
372
+ - 使用 JSON 数据中的精确数值(颜色代码、字体大小、间距值等)
373
+ - 确保所有数值与 JSON 配置保持一致
374
+
375
+ 2. **遵循文件顺序**:
376
+ - 严格按照文件索引的顺序创建(1→2→3→4→5→6→7)
377
+ - design-system.json 最先创建(包含所有精确配置)
378
+ - design-system.md 最后创建(包含完整概览)
379
+
380
+ 3. **自由创作内容**:
381
+ - 参考创作指导中的主题列表
382
+ - 根据产品类型 "${request.productType}" 调整重点
383
+ ${request.stack ? `- 提供 ${request.stack} 的具体实现示例` : ''}
384
+ - 不要局限于固定模板,发挥创造力
385
+
386
+ 4. **保持一致性**:
387
+ - 所有文档使用相同的设计 Token(颜色、字体、间距)
388
+ - 确保术语和命名规范统一
389
+ - 交叉引用其他文档时保持准确
390
+
391
+ 5. **提供实用示例**:
392
+ - 包含具体的代码示例(不要抽象描述)
393
+ - 展示实际应用场景
394
+ - 参考反模式(antiPatterns)提供"应避免"的建议
395
+ ${isShadcnStack(request.stack) ? `
396
+ 6. **shadcn/ui 实现路径**(${request.stack}):
397
+ - 用 \`ui_search --category=ui-themes\` 确认主题;上文的 globals.css 片段可直接使用
398
+ - \`ui_search --category=shadcn-blocks --query="..."\` 找 block,再 \`npx shadcn@latest add <name>\`
399
+ - 用 \`ui_search --category=ui-guidelines-vercel\` 对照 Vercel 规范
400
+ - 在 block 基础上改文案/数据,不要从零写 Card/Button
401
+ ` : ''}
402
+
403
+ ### 开始创作:
404
+
405
+ **第一步**:创建 \`docs/design-system.json\`,包含所有精确配置数据(使用上面的 JSON)
406
+
407
+ **第二步**:创建 \`docs/design-guidelines/README.md\`,提供设计指南的索引和导航
408
+
409
+ **第三步至第六步**:依次创建四个设计指南文档(principles、interaction、layout、config)
410
+
411
+ **最后一步**:创建 \`docs/design-system.md\`,包含以下内容:
412
+ - ASCII Box 推荐(核心设计)
413
+ - 完整的设计系统概览
414
+ - **文件索引**(列出所有设计文档的链接,方便后续查看和使用)
415
+ - 快速开始指南
416
+
417
+ ---
418
+
419
+ 🚀 **准备好了吗?让我们开始创建第一个文件吧!**
377
420
  `;
378
421
  // 构建结构化数据对象
379
422
  const structuredData = {
@@ -409,17 +452,17 @@ ${guidanceText}
409
452
  colors: {},
410
453
  typography: {},
411
454
  };
412
- return okStructured(`❌ 设计系统生成失败: ${errorMessage}
413
-
414
- **可能的原因**:
415
- 1. 数据未加载完成
416
- 2. 产品类型不明确
417
- 3. 数据格式错误
418
-
419
- **建议**:
420
- 1. 提供更具体的产品类型(如 "SaaS", "E-commerce", "Healthcare")
421
- 2. 添加产品描述帮助推理引擎理解需求
422
- 3. 检查数据是否已同步(使用 \`sync_ui_data\` 工具)
455
+ return okStructured(`❌ 设计系统生成失败: ${errorMessage}
456
+
457
+ **可能的原因**:
458
+ 1. 数据未加载完成
459
+ 2. 产品类型不明确
460
+ 3. 数据格式错误
461
+
462
+ **建议**:
463
+ 1. 提供更具体的产品类型(如 "SaaS", "E-commerce", "Healthcare")
464
+ 2. 添加产品描述帮助推理引擎理解需求
465
+ 3. 检查数据是否已同步(使用 \`sync_ui_data\` 工具)
423
466
  `, errorData, {
424
467
  schema: (await import('../schemas/output/ui-ux-tools.js')).DesignSystemSchema,
425
468
  });
@@ -443,22 +486,22 @@ export async function uiSearch(args) {
443
486
  // 格式化组件列表
444
487
  const components = catalog.components || [];
445
488
  const componentList = components.map((comp, index) => {
446
- return `### ${index + 1}. ${comp.name}
447
-
448
- **描述**: ${comp.description || '无'}
449
- **Props**: ${Object.keys(comp.props || {}).join(', ')}
450
- **样式**: ${comp.styles ? Object.keys(comp.styles).join(', ') : '无'}
489
+ return `### ${index + 1}. ${comp.name}
490
+
491
+ **描述**: ${comp.description || '无'}
492
+ **Props**: ${Object.keys(comp.props || {}).join(', ')}
493
+ **样式**: ${comp.styles ? Object.keys(comp.styles).join(', ') : '无'}
451
494
  `;
452
495
  }).join('\n---\n\n');
453
- const message = `# 📦 组件目录
454
-
455
- 共 ${components.length} 个可用组件
456
-
457
- ---
458
-
459
- ${componentList}
460
-
461
- **提示**: 这些组件可以在 UI 模板中使用
496
+ const message = `# 📦 组件目录
497
+
498
+ 共 ${components.length} 个可用组件
499
+
500
+ ---
501
+
502
+ ${componentList}
503
+
504
+ **提示**: 这些组件可以在 UI 模板中使用
462
505
  `;
463
506
  const structuredData = {
464
507
  summary: `组件目录 - ${components.length} 个组件`,
@@ -483,9 +526,9 @@ ${componentList}
483
526
  results: [],
484
527
  totalResults: 0,
485
528
  };
486
- return okStructured(`❌ 未找到组件目录文件
487
-
488
- 请先运行 \`init_component_catalog\` 生成组件目录。
529
+ return okStructured(`❌ 未找到组件目录文件
530
+
531
+ 请先运行 \`init_component_catalog\` 生成组件目录。
489
532
  `, errorData, {
490
533
  schema: (await import('../schemas/output/ui-ux-tools.js')).UISearchResultSchema,
491
534
  });
@@ -510,18 +553,18 @@ ${componentList}
510
553
  results: [],
511
554
  totalResults: 0,
512
555
  };
513
- return okStructured(`📭 暂无可用模板
514
-
515
- **建议**:
516
- 1. 使用 \`start_ui\` 生成新模板
517
- 2. 模板会自动保存到 \`docs/ui/pages/\` 目录
518
- 3. 下次可以直接搜索使用
519
-
520
- **示例**:
521
- \`\`\`
522
- start_ui "登录页面"
523
- start_ui "用户列表"
524
- \`\`\`
556
+ return okStructured(`📭 暂无可用模板
557
+
558
+ **建议**:
559
+ 1. 使用 \`start_ui\` 生成新模板
560
+ 2. 模板会自动保存到 \`docs/ui/pages/\` 目录
561
+ 3. 下次可以直接搜索使用
562
+
563
+ **示例**:
564
+ \`\`\`
565
+ start_ui "登录页面"
566
+ start_ui "用户列表"
567
+ \`\`\`
525
568
  `, emptyData, {
526
569
  schema: (await import('../schemas/output/ui-ux-tools.js')).UISearchResultSchema,
527
570
  });
@@ -558,41 +601,41 @@ start_ui "用户列表"
558
601
  })),
559
602
  totalResults: 0,
560
603
  };
561
- return okStructured(`未找到匹配的模板
562
-
563
- **查询**: ${query}
564
- **可用模板**: ${templates.map(t => t.name).join(', ')}
565
-
566
- **建议**: 使用 \`start_ui "${query}"\` 生成新模板
604
+ return okStructured(`未找到匹配的模板
605
+
606
+ **查询**: ${query}
607
+ **可用模板**: ${templates.map(t => t.name).join(', ')}
608
+
609
+ **建议**: 使用 \`start_ui "${query}"\` 生成新模板
567
610
  `, noMatchData, {
568
611
  schema: (await import('../schemas/output/ui-ux-tools.js')).UISearchResultSchema,
569
612
  });
570
613
  }
571
614
  // 格式化模板列表
572
615
  const templateList = filteredTemplates.map((t, index) => {
573
- return `### ${index + 1}. ${t.name}
574
-
575
- **文件**: \`docs/ui/pages/${t.file}\`
576
- **描述**: ${t.description}
577
- **组件数**: ${JSON.stringify(t.template).match(/"type":/g)?.length || 0}
578
-
579
- \`\`\`json
580
- ${JSON.stringify(t.template, null, 2)}
581
- \`\`\`
616
+ return `### ${index + 1}. ${t.name}
617
+
618
+ **文件**: \`docs/ui/pages/${t.file}\`
619
+ **描述**: ${t.description}
620
+ **组件数**: ${JSON.stringify(t.template).match(/"type":/g)?.length || 0}
621
+
622
+ \`\`\`json
623
+ ${JSON.stringify(t.template, null, 2)}
624
+ \`\`\`
582
625
  `;
583
626
  }).join('\n---\n\n');
584
- const message = `# 📄 UI 模板搜索结果
585
-
586
- 找到 ${filteredTemplates.length} 个匹配模板
587
-
588
- ---
589
-
590
- ${templateList}
591
-
592
- **使用方法**:
593
- \`\`\`
594
- render_ui docs/ui/pages/<文件名>.json --framework=react
595
- \`\`\`
627
+ const message = `# 📄 UI 模板搜索结果
628
+
629
+ 找到 ${filteredTemplates.length} 个匹配模板
630
+
631
+ ---
632
+
633
+ ${templateList}
634
+
635
+ **使用方法**:
636
+ \`\`\`
637
+ render_ui docs/ui/pages/<文件名>.json --framework=react
638
+ \`\`\`
596
639
  `;
597
640
  const structuredData = {
598
641
  summary: `找到 ${filteredTemplates.length} 个模板`,
@@ -619,20 +662,20 @@ render_ui docs/ui/pages/<文件名>.json --framework=react
619
662
  results: [],
620
663
  totalResults: 0,
621
664
  };
622
- return okStructured(`📭 暂无可用模板
623
-
624
- 模板目录不存在或为空。
625
-
626
- **建议**:
627
- 使用 \`start_ui\` 生成第一个模板:
628
-
629
- \`\`\`
630
- start_ui "登录页面"
631
- start_ui "用户列表"
632
- start_ui "设置页面"
633
- \`\`\`
634
-
635
- 模板会自动保存到 \`docs/ui/pages/\` 目录。
665
+ return okStructured(`📭 暂无可用模板
666
+
667
+ 模板目录不存在或为空。
668
+
669
+ **建议**:
670
+ 使用 \`start_ui\` 生成第一个模板:
671
+
672
+ \`\`\`
673
+ start_ui "登录页面"
674
+ start_ui "用户列表"
675
+ start_ui "设置页面"
676
+ \`\`\`
677
+
678
+ 模板会自动保存到 \`docs/ui/pages/\` 目录。
636
679
  `, errorData, {
637
680
  schema: (await import('../schemas/output/ui-ux-tools.js')).UISearchResultSchema,
638
681
  });
@@ -656,17 +699,17 @@ start_ui "设置页面"
656
699
  results: [],
657
700
  totalResults: 0,
658
701
  };
659
- return okStructured(`未找到匹配的 UI/UX 数据。
660
-
661
- **搜索条件:**
662
- - 查询: ${query}
663
- - 类别: ${options.category || '全部'}
664
- - 技术栈: ${options.stack || '全部'}
665
-
666
- **建议:**
667
- 1. 尝试使用更通用的关键词
668
- 2. 检查拼写是否正确
669
- 3. 移除类别或技术栈限制
702
+ return okStructured(`未找到匹配的 UI/UX 数据。
703
+
704
+ **搜索条件:**
705
+ - 查询: ${query}
706
+ - 类别: ${options.category || '全部'}
707
+ - 技术栈: ${options.stack || '全部'}
708
+
709
+ **建议:**
710
+ 1. 尝试使用更通用的关键词
711
+ 2. 检查拼写是否正确
712
+ 3. 移除类别或技术栈限制
670
713
  `, noResultData, {
671
714
  schema: (await import('../schemas/output/ui-ux-tools.js')).UISearchResultSchema,
672
715
  });
@@ -674,6 +717,24 @@ start_ui "设置页面"
674
717
  // 格式化结果
675
718
  const formattedResults = results.map((result, index) => {
676
719
  const data = result.data;
720
+ if (isShadcnCategory(result.category)) {
721
+ return `### ${index + 1}. ${data.name || data.title} (相关度: ${result.score.toFixed(2)})
722
+
723
+ ${formatShadcnResult(data)}
724
+ `;
725
+ }
726
+ if (isThemeCategory(result.category)) {
727
+ return `### ${index + 1}. ${data.title || data.name} (相关度: ${result.score.toFixed(2)})
728
+
729
+ ${formatThemeResult(data)}
730
+ `;
731
+ }
732
+ if (isGuidelineCategory(result.category)) {
733
+ return `### ${index + 1}. ${data.level} (相关度: ${result.score.toFixed(2)})
734
+
735
+ ${formatGuidelineResult(data)}
736
+ `;
737
+ }
677
738
  const fields = Object.entries(data)
678
739
  .filter(([_key, value]) => value != null && value !== '')
679
740
  .map(([key, value]) => {
@@ -683,35 +744,41 @@ start_ui "设置页面"
683
744
  return `- **${key}**: ${value}`;
684
745
  })
685
746
  .join('\n');
686
- return `### ${index + 1}. ${result.category} (相关度: ${result.score.toFixed(2)})
687
-
688
- ${fields}
747
+ return `### ${index + 1}. ${result.category} (相关度: ${result.score.toFixed(2)})
748
+
749
+ ${fields}
689
750
  `;
690
751
  }).join('\n---\n\n');
691
- const message = `# UI/UX 搜索结果
692
-
693
- 找到 ${results.length} 条匹配结果
694
-
695
- **搜索条件:**
696
- - 查询: ${query}
697
- - 类别: ${options.category || '全部'}
698
- - 技术栈: ${options.stack || '全部'}
699
-
700
- ---
701
-
702
- ${formattedResults}
752
+ const message = `# UI/UX 搜索结果
753
+
754
+ 找到 ${results.length} 条匹配结果
755
+
756
+ **搜索条件:**
757
+ - 查询: ${query}
758
+ - 类别: ${options.category || '全部'}
759
+ - 技术栈: ${options.stack || '全部'}
760
+
761
+ ---
762
+
763
+ ${formattedResults}
703
764
  `;
704
765
  const structuredData = {
705
766
  summary: `找到 ${results.length} 条结果`,
706
767
  query: query,
707
768
  category: options.category,
708
769
  results: results.map(result => ({
709
- id: result.data.id || result.data.name || '',
770
+ id: result.data.name || result.data.id || result.data.title || '',
710
771
  title: result.data.title || result.data.name || '',
711
772
  description: result.data.description || '',
712
773
  category: result.category,
713
774
  score: result.score,
714
- preview: JSON.stringify(result.data, null, 2),
775
+ preview: isShadcnCategory(result.category)
776
+ ? `${result.data.installCommand || ''}\n${JSON.stringify(result.data, null, 2)}`
777
+ : isThemeCategory(result.category)
778
+ ? String(result.data.globalsCssSnippet || JSON.stringify(result.data, null, 2))
779
+ : isGuidelineCategory(result.category)
780
+ ? `${result.data.level}: ${result.data.rule}`
781
+ : JSON.stringify(result.data, null, 2),
715
782
  })),
716
783
  totalResults: results.length,
717
784
  };
@@ -746,29 +813,31 @@ export async function syncUiData(args, context) {
746
813
  throwIfAborted(context?.signal, 'sync_ui_data 已取消');
747
814
  await reportToolProgress(context, 15, 'sync_ui_data: 检查上游版本');
748
815
  const loader = await getDataLoader();
749
- const cacheManager = loader.getCacheManager();
816
+ const cacheDir = loader.getCacheManager().getCacheDir();
750
817
  try {
751
- const updateInfo = await cacheManager.checkUpdate();
818
+ const updateInfo = await checkUISourcesUpdate(cacheDir, context?.signal);
752
819
  if (!updateInfo.hasUpdate) {
753
820
  await reportToolProgress(context, 100, 'sync_ui_data: 数据已是最新');
754
821
  const upToDateData = {
755
822
  summary: "UI/UX 数据已是最新版本",
756
823
  status: 'success',
757
824
  synced: {},
758
- version: updateInfo.currentVersion || 'unknown',
825
+ version: updateInfo.uipro.current || updateInfo.uipro.latest,
759
826
  timestamp: new Date().toISOString(),
760
827
  };
761
- return okStructured(`✅ UI/UX 数据已是最新版本
762
-
763
- **当前版本:** ${updateInfo.currentVersion}
764
- **最新版本:** ${updateInfo.latestVersion}
765
-
766
- 无需更新。如需强制同步,请使用 \`force: true\` 参数。
828
+ return okStructured(`✅ UI/UX 数据已是最新版本
829
+
830
+ **uipro-cli:** ${updateInfo.uipro.current || 'unknown'} (latest ${updateInfo.uipro.latest})
831
+ **shadcn registry:** ${updateInfo.shadcn.current || 'unknown'} (latest ${updateInfo.shadcn.latest})
832
+ **ui-themes:** ${updateInfo.themes.current || 'unknown'} (latest ${updateInfo.themes.latest})
833
+ **vercel guidelines:** ${updateInfo.vercel.current || 'unknown'} (latest ${updateInfo.vercel.latest})
834
+
835
+ 无需更新。如需强制同步,请使用 \`force: true\` 参数。
767
836
  `, upToDateData, {
768
837
  schema: (await import('../schemas/output/ui-ux-tools.js')).SyncReportSchema,
769
838
  });
770
839
  }
771
- console.log(`Update available: ${updateInfo.currentVersion || 'none'} -> ${updateInfo.latestVersion}`);
840
+ console.log(`Update available: uipro ${updateInfo.uipro.current || 'none'} -> ${updateInfo.uipro.latest}; shadcn ${updateInfo.shadcn.current || 'none'} -> ${updateInfo.shadcn.latest}`);
772
841
  }
773
842
  catch (error) {
774
843
  console.log('Failed to check update, proceeding with sync...');
@@ -779,6 +848,7 @@ export async function syncUiData(args, context) {
779
848
  await reportToolProgress(context, 30, 'sync_ui_data: 下载并处理数据');
780
849
  await syncUIDataToCache(force, verbose, {
781
850
  signal: context?.signal,
851
+ force,
782
852
  onProgress: async (progress, message) => {
783
853
  await reportToolProgress(context, 30 + Math.round(progress * 0.6), `sync_ui_data: ${message}`);
784
854
  },
@@ -799,6 +869,10 @@ export async function syncUiData(args, context) {
799
869
  icons: (searchEngine.getCategoryData('icons') || []).length,
800
870
  components: (searchEngine.getCategoryData('products') || []).length,
801
871
  patterns: (searchEngine.getCategoryData('landing') || []).length,
872
+ shadcnBlocks: (searchEngine.getCategoryData('shadcn-blocks') || []).length,
873
+ shadcnComponents: (searchEngine.getCategoryData('shadcn-components') || []).length,
874
+ themes: (searchEngine.getCategoryData('ui-themes') || []).length,
875
+ vercelGuidelines: (searchEngine.getCategoryData('ui-guidelines-vercel') || []).length,
802
876
  },
803
877
  version: metadata?.version,
804
878
  timestamp: new Date().toISOString(),
@@ -814,6 +888,10 @@ export async function syncUiData(args, context) {
814
888
  - 图标: ${syncedData.synced.icons} 条
815
889
  - 组件: ${syncedData.synced.components} 条
816
890
  - 模式: ${syncedData.synced.patterns} 条
891
+ - shadcn blocks: ${syncedData.synced.shadcnBlocks || 0} 条
892
+ - shadcn components: ${syncedData.synced.shadcnComponents || 0} 条
893
+ - UI 主题: ${syncedData.synced.themes || 0} 套
894
+ - Vercel 规范: ${syncedData.synced.vercelGuidelines || 0} 条
817
895
 
818
896
  **会话状态:**
819
897
  - 当前会话使用版本: ${sessionInfo.activeVersion || 'unknown'}(source: ${sessionInfo.source})
@@ -833,18 +911,18 @@ export async function syncUiData(args, context) {
833
911
  timestamp: new Date().toISOString(),
834
912
  errors: [errorMessage],
835
913
  };
836
- return okStructured(`❌ UI 数据同步失败: ${errorMessage}
837
-
838
- **可能的原因:**
839
- 1. 网络连接问题
840
- 2. npm registry 不可访问
841
- 3. 磁盘空间不足
842
- 4. 权限问题
843
-
844
- **建议:**
845
- 1. 检查网络连接
846
- 2. 稍后重试
847
- 3. 使用 \`verbose: true\` 查看详细日志
914
+ return okStructured(`❌ UI 数据同步失败: ${errorMessage}
915
+
916
+ **可能的原因:**
917
+ 1. 网络连接问题
918
+ 2. npm registry 不可访问
919
+ 3. 磁盘空间不足
920
+ 4. 权限问题
921
+
922
+ **建议:**
923
+ 1. 检查网络连接
924
+ 2. 稍后重试
925
+ 3. 使用 \`verbose: true\` 查看详细日志
848
926
  `, errorData, {
849
927
  schema: (await import('../schemas/output/ui-ux-tools.js')).SyncReportSchema,
850
928
  });