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
@@ -1,4 +1,33 @@
1
1
  export declare const memoryToolSchemas: readonly [{
2
+ readonly name: "search_memory";
3
+ readonly description: "按语义检索共享记忆库。适合在 start_* 之外主动查找历史 Bug 修复或可复用模式;命中后用 read_memory_asset 读取全文。";
4
+ readonly inputSchema: {
5
+ readonly type: "object";
6
+ readonly properties: {
7
+ readonly query: {
8
+ readonly type: "string";
9
+ readonly description: "检索 query(现象、报错、关键词、功能描述等)";
10
+ };
11
+ readonly type: {
12
+ readonly type: "string";
13
+ readonly description: "优先匹配的资产类型,如 bugfix、pattern、component";
14
+ };
15
+ readonly tags: {
16
+ readonly type: "array";
17
+ readonly items: {
18
+ readonly type: "string";
19
+ };
20
+ readonly description: "优先匹配的标签";
21
+ };
22
+ readonly limit: {
23
+ readonly type: "number";
24
+ readonly description: "返回条数,默认 MEMORY_SEARCH_LIMIT";
25
+ };
26
+ };
27
+ readonly required: readonly ["query"];
28
+ readonly additionalProperties: true;
29
+ };
30
+ }, {
2
31
  readonly name: "read_memory_asset";
3
32
  readonly description: "当编排阶段已检索到记忆摘要,且 AI 需要查看完整沉淀代码或详细规范时使用。根据 asset_id 读取记忆资产详情。";
4
33
  readonly inputSchema: {
@@ -14,7 +43,7 @@ export declare const memoryToolSchemas: readonly [{
14
43
  };
15
44
  }, {
16
45
  readonly name: "memorize_asset";
17
- readonly description: "沉淀可检索资产到记忆系统:可复用代码/模式;Bug 修复后必须写入 type=bugfix(现象、根因、改法、tags bugfix)。";
46
+ readonly description: "沉淀可检索资产到共享记忆库。Bug 修复后必须 type=bugfix,content 含【现象】【根因】【修复】【验证】。跨仓库共享时勿填 source_project/source_path,路径写入 content 即可。";
18
47
  readonly inputSchema: {
19
48
  readonly type: "object";
20
49
  readonly properties: {
@@ -24,7 +53,7 @@ export declare const memoryToolSchemas: readonly [{
24
53
  };
25
54
  readonly type: {
26
55
  readonly type: "string";
27
- readonly description: "资产类型,如 code/component/pattern/spec";
56
+ readonly description: "资产类型:bugfix / pattern / component / code 等";
28
57
  };
29
58
  readonly description: {
30
59
  readonly type: "string";
@@ -32,11 +61,11 @@ export declare const memoryToolSchemas: readonly [{
32
61
  };
33
62
  readonly summary: {
34
63
  readonly type: "string";
35
- readonly description: "用于检索的凝练摘要";
64
+ readonly description: "检索用一句话摘要(关键词 + 根因/要点)";
36
65
  };
37
66
  readonly content: {
38
67
  readonly type: "string";
39
- readonly description: "完整内容";
68
+ readonly description: "完整内容(bugfix 建议结构化四段)";
40
69
  };
41
70
  readonly code_snippet: {
42
71
  readonly type: "string";
@@ -44,15 +73,15 @@ export declare const memoryToolSchemas: readonly [{
44
73
  };
45
74
  readonly file_path: {
46
75
  readonly type: "string";
47
- readonly description: "来源文件路径";
76
+ readonly description: "已废弃:勿用于跨仓库沉淀,路径写入 content";
48
77
  };
49
78
  readonly source_project: {
50
79
  readonly type: "string";
51
- readonly description: "来源项目";
80
+ readonly description: "已废弃:仅同仓库追溯时可选";
52
81
  };
53
82
  readonly source_path: {
54
83
  readonly type: "string";
55
- readonly description: "来源路径";
84
+ readonly description: "已废弃:仅同仓库追溯时可选";
56
85
  };
57
86
  readonly usage: {
58
87
  readonly type: "string";
@@ -67,7 +96,7 @@ export declare const memoryToolSchemas: readonly [{
67
96
  readonly items: {
68
97
  readonly type: "string";
69
98
  };
70
- readonly description: "标签列表";
99
+ readonly description: "标签列表,如 bugfix, root-cause";
71
100
  };
72
101
  };
73
102
  readonly required: readonly ["name", "description", "summary"];
@@ -89,7 +118,7 @@ export declare const memoryToolSchemas: readonly [{
89
118
  };
90
119
  readonly project_name: {
91
120
  readonly type: "string";
92
- readonly description: "来源项目名";
121
+ readonly description: "已废弃,扫描结果不再写入 source_project";
93
122
  };
94
123
  readonly directory_path: {
95
124
  readonly type: "string";
@@ -1,4 +1,19 @@
1
1
  export const memoryToolSchemas = [
2
+ {
3
+ name: 'search_memory',
4
+ description: '按语义检索共享记忆库。适合在 start_* 之外主动查找历史 Bug 修复或可复用模式;命中后用 read_memory_asset 读取全文。',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: {
8
+ query: { type: 'string', description: '检索 query(现象、报错、关键词、功能描述等)' },
9
+ type: { type: 'string', description: '优先匹配的资产类型,如 bugfix、pattern、component' },
10
+ tags: { type: 'array', items: { type: 'string' }, description: '优先匹配的标签' },
11
+ limit: { type: 'number', description: '返回条数,默认 MEMORY_SEARCH_LIMIT' },
12
+ },
13
+ required: ['query'],
14
+ additionalProperties: true,
15
+ },
16
+ },
2
17
  {
3
18
  name: 'read_memory_asset',
4
19
  description: '当编排阶段已检索到记忆摘要,且 AI 需要查看完整沉淀代码或详细规范时使用。根据 asset_id 读取记忆资产详情。',
@@ -16,22 +31,22 @@ export const memoryToolSchemas = [
16
31
  },
17
32
  {
18
33
  name: 'memorize_asset',
19
- description: '沉淀可检索资产到记忆系统:可复用代码/模式;Bug 修复后必须写入 type=bugfix(现象、根因、改法、tags bugfix)。',
34
+ description: '沉淀可检索资产到共享记忆库。Bug 修复后必须 type=bugfix,content 含【现象】【根因】【修复】【验证】。跨仓库共享时勿填 source_project/source_path,路径写入 content 即可。',
20
35
  inputSchema: {
21
36
  type: 'object',
22
37
  properties: {
23
38
  name: { type: 'string', description: '资产名称' },
24
- type: { type: 'string', description: '资产类型,如 code/component/pattern/spec' },
39
+ type: { type: 'string', description: '资产类型:bugfix / pattern / component / code 等' },
25
40
  description: { type: 'string', description: '资产描述' },
26
- summary: { type: 'string', description: '用于检索的凝练摘要' },
27
- content: { type: 'string', description: '完整内容' },
41
+ summary: { type: 'string', description: '检索用一句话摘要(关键词 + 根因/要点)' },
42
+ content: { type: 'string', description: '完整内容(bugfix 建议结构化四段)' },
28
43
  code_snippet: { type: 'string', description: '代码片段,content 的别名' },
29
- file_path: { type: 'string', description: '来源文件路径' },
30
- source_project: { type: 'string', description: '来源项目' },
31
- source_path: { type: 'string', description: '来源路径' },
44
+ file_path: { type: 'string', description: '已废弃:勿用于跨仓库沉淀,路径写入 content' },
45
+ source_project: { type: 'string', description: '已废弃:仅同仓库追溯时可选' },
46
+ source_path: { type: 'string', description: '已废弃:仅同仓库追溯时可选' },
32
47
  usage: { type: 'string', description: '适用场景/使用方式' },
33
48
  confidence: { type: 'number', description: '置信度,0-1' },
34
- tags: { type: 'array', items: { type: 'string' }, description: '标签列表' },
49
+ tags: { type: 'array', items: { type: 'string' }, description: '标签列表,如 bugfix, root-cause' },
35
50
  },
36
51
  required: ['name', 'description', 'summary'],
37
52
  additionalProperties: true,
@@ -45,7 +60,7 @@ export const memoryToolSchemas = [
45
60
  properties: {
46
61
  content: { type: 'string', description: '待分析的代码或文本内容。传入该字段时走单段分析模式' },
47
62
  file_path: { type: 'string', description: '来源文件路径。单段分析时作为来源路径使用' },
48
- project_name: { type: 'string', description: '来源项目名' },
63
+ project_name: { type: 'string', description: '已废弃,扫描结果不再写入 source_project' },
49
64
  directory_path: { type: 'string', description: '要扫描的目录路径。最佳实践是传相对 `project_root` 的路径,例如 `app/utils`;如果拿不到 `project_root`,才传目录绝对路径。不要传带项目名的半相对路径,例如 `font-miniapp-api/app/utils`。' },
50
65
  project_root: { type: 'string', description: '项目根目录绝对路径。目录扫描时建议始终传入;传入后,`directory_path` 应写成相对项目根的路径。' },
51
66
  max_files: { type: 'number', description: '最多扫描多少个文件,默认 30,最大 200' },
@@ -194,6 +194,18 @@ export declare const SyncReportSchema: {
194
194
  readonly patterns: {
195
195
  readonly type: "number";
196
196
  };
197
+ readonly shadcnBlocks: {
198
+ readonly type: "number";
199
+ };
200
+ readonly shadcnComponents: {
201
+ readonly type: "number";
202
+ };
203
+ readonly themes: {
204
+ readonly type: "number";
205
+ };
206
+ readonly vercelGuidelines: {
207
+ readonly type: "number";
208
+ };
197
209
  };
198
210
  };
199
211
  readonly version: {
@@ -421,6 +433,10 @@ export interface SyncReport {
421
433
  icons?: number;
422
434
  components?: number;
423
435
  patterns?: number;
436
+ shadcnBlocks?: number;
437
+ shadcnComponents?: number;
438
+ themes?: number;
439
+ vercelGuidelines?: number;
424
440
  };
425
441
  version?: string;
426
442
  timestamp?: string;
@@ -100,6 +100,10 @@ export const SyncReportSchema = {
100
100
  icons: { type: 'number' },
101
101
  components: { type: 'number' },
102
102
  patterns: { type: 'number' },
103
+ shadcnBlocks: { type: 'number' },
104
+ shadcnComponents: { type: 'number' },
105
+ themes: { type: 'number' },
106
+ vercelGuidelines: { type: 'number' },
103
107
  },
104
108
  },
105
109
  version: { type: 'string' },
@@ -33,7 +33,7 @@ export const uiDesignSystemSchema = {
33
33
  };
34
34
  export const uiSearchSchema = {
35
35
  name: "ui_search",
36
- description: "搜索 UI/UX 数据库,包括颜色、图标、图表、组件、设计模式等。支持三种模式:search(搜索数据)、catalog(查看组件目录)、template(搜索 UI 模板)。使用 BM25 算法进行智能搜索,支持按类别和技术栈过滤。数据来源:uipro-cli npm 包(v2.2.0+)。",
36
+ description: "搜索 UI/UX 数据库,包括颜色、图标、图表、组件、设计模式,以及 shadcn/ui blocks、UI 主题预设(CSS variables)、Vercel Web Interface Guidelines 等。支持 search / catalog / template 三种模式。",
37
37
  inputSchema: {
38
38
  type: "object",
39
39
  properties: {
@@ -48,7 +48,7 @@ export const uiSearchSchema = {
48
48
  },
49
49
  category: {
50
50
  type: "string",
51
- description: "数据类别(仅 search 模式):colors(颜色)、icons(图标)、charts(图表)、landing(落地页)、products(产品)、typography(字体)、styles(样式)、ux-guidelines(UX 指南)、web-interface(Web 界面)等",
51
+ description: "数据类别(search 模式):colorsiconschartslandingproductstypographystylesux-guidelines、shadcn-blocks、shadcn-components、ui-themes、ui-guidelines-vercel ",
52
52
  },
53
53
  stack: {
54
54
  type: "string",
@@ -69,7 +69,7 @@ export const uiSearchSchema = {
69
69
  };
70
70
  export const syncUiDataSchema = {
71
71
  name: "sync_ui_data",
72
- description: "同步 UI/UX 数据到本地缓存。从 npm 包 uipro-cli 下载最新数据,支持自动检查更新和强制同步。数据存储在 ~/.mcp-probe-kit/ui-ux-data/,默认在下次启动时生效以保证当前会话一致性。",
72
+ description: "同步 UI/UX 数据到本地缓存。来源:uipro-cli、shadcn/ui registry、内嵌 UI 主题预设、Vercel Web Interface Guidelines。",
73
73
  inputSchema: {
74
74
  type: "object",
75
75
  properties: {
@@ -17,8 +17,8 @@ describe('start_ui 属性测试', () => {
17
17
  const text = result.content[0].text || '';
18
18
  // 简单的 token 估算:按空格和标点分割
19
19
  const tokenCount = text.split(/[\s\n]+/).length;
20
- // 硬性约束:必须少于 800 tokens
21
- expect(tokenCount).toBeLessThan(800);
20
+ // 硬性约束:必须少于 1050 tokens(含 shadcn/主题/规范路径后略增)
21
+ expect(tokenCount).toBeLessThan(1050);
22
22
  }), { numRuns: 100 });
23
23
  });
24
24
  // Feature: ui-workflow-execution-issue, Property 18: 一致的 Markdown 结构
@@ -242,7 +242,8 @@ test('任务 6.4: 无模糊语言', async () => {
242
242
  match.includes('文件') ||
243
243
  match.includes('权限') ||
244
244
  match.includes('docs/') ||
245
- match.includes('目录');
245
+ match.includes('目录') ||
246
+ match.includes('`');
246
247
  expect(hasSpecific).toBe(true);
247
248
  });
248
249
  }), { numRuns: 100 });
@@ -16,6 +16,7 @@ export { interview } from "./interview.js";
16
16
  export { askUser } from "./ask_user.js";
17
17
  export { uiDesignSystem, uiSearch, syncUiData } from "./ui-ux-tools.js";
18
18
  export { startUi } from "./start_ui.js";
19
+ export { searchMemory } from "./search_memory.js";
19
20
  export { readMemoryAsset } from "./read_memory_asset.js";
20
21
  export { memorizeAsset } from "./memorize_asset.js";
21
22
  export { scanAndExtractPatterns } from "./scan_and_extract_patterns.js";
@@ -20,6 +20,7 @@ export { askUser } from "./ask_user.js";
20
20
  export { uiDesignSystem, uiSearch, syncUiData } from "./ui-ux-tools.js";
21
21
  export { startUi } from "./start_ui.js";
22
22
  // 记忆工具
23
+ export { searchMemory } from "./search_memory.js";
23
24
  export { readMemoryAsset } from "./read_memory_asset.js";
24
25
  export { memorizeAsset } from "./memorize_asset.js";
25
26
  export { scanAndExtractPatterns } from "./scan_and_extract_patterns.js";
@@ -42,6 +42,17 @@ export async function memorizeAsset(args) {
42
42
  if (!client.isEnabled()) {
43
43
  return okStructured('记忆服务未开启,已跳过沉淀。', { enabled: false, stored: false });
44
44
  }
45
+ const warnings = [];
46
+ if (type === 'bugfix') {
47
+ const requiredSections = ['【现象】', '【根因】', '【修复】'];
48
+ const missing = requiredSections.filter((section) => !content.includes(section));
49
+ if (missing.length > 0) {
50
+ warnings.push(`建议 content 包含 ${missing.join('、')},便于跨仓库检索与复用`);
51
+ }
52
+ }
53
+ if (sourceProject || sourcePath) {
54
+ warnings.push('跨仓库共享记忆时请勿依赖 source_project/source_path;路径请写入 content 正文(可选)');
55
+ }
45
56
  const asset = await client.upsertAsset({
46
57
  name,
47
58
  type,
@@ -58,6 +69,7 @@ export async function memorizeAsset(args) {
58
69
  enabled: true,
59
70
  stored: true,
60
71
  asset,
72
+ warnings: warnings.length > 0 ? warnings : undefined,
61
73
  });
62
74
  }
63
75
  catch (error) {
@@ -108,21 +108,22 @@ function summarizeContent(content, maxChars = 200) {
108
108
  .trim()
109
109
  .slice(0, maxChars);
110
110
  }
111
- function buildPattern(content, filePath, projectName) {
111
+ function buildPattern(content, filePath) {
112
112
  const normalized = content.trim();
113
113
  const candidateNames = collectCandidateNames(normalized);
114
114
  const primaryName = candidateNames[0] || (filePath ? path.basename(filePath) : 'snippet');
115
115
  const type = detectPatternType(normalized, filePath);
116
116
  const summary = summarizeContent(normalized);
117
+ const fileHint = filePath ? `(摘录自 ${filePath})` : '';
117
118
  return {
118
119
  name: primaryName,
119
120
  type,
120
- description: filePath ? `从 ${filePath} 提取的可复用模式` : '从代码片段提取的可复用模式',
121
+ description: filePath
122
+ ? `从 ${filePath} 提取的可复用模式${fileHint}`
123
+ : '从代码片段提取的可复用模式',
121
124
  summary,
122
125
  content: normalized,
123
126
  tags: inferTags(normalized, filePath),
124
- sourcePath: filePath || undefined,
125
- sourceProject: projectName || undefined,
126
127
  confidence: filePath ? 0.62 : 0.55,
127
128
  candidateNames,
128
129
  };
@@ -271,7 +272,6 @@ export async function scanAndExtractPatterns(args) {
271
272
  });
272
273
  const content = getString(parsed.content);
273
274
  const filePath = getString(parsed.file_path);
274
- const projectName = getString(parsed.project_name);
275
275
  const directoryPath = getString(parsed.directory_path);
276
276
  const projectRoot = resolveWorkspaceRoot(getString(parsed.project_root));
277
277
  const maxFiles = Math.max(1, Math.min(200, getNumber(parsed.max_files, 30)));
@@ -282,7 +282,7 @@ export async function scanAndExtractPatterns(args) {
282
282
  .map((item) => item.startsWith('.') ? item.toLowerCase() : `.${item.toLowerCase()}`)
283
283
  : DEFAULT_INCLUDE_EXTENSIONS);
284
284
  if (content) {
285
- const pattern = buildPattern(content, filePath, projectName || undefined);
285
+ const pattern = buildPattern(content, filePath);
286
286
  return okStructured(`已提取 1 个候选模式${filePath ? `: ${filePath}` : ''}`, {
287
287
  mode: 'single',
288
288
  patterns: [pattern],
@@ -331,7 +331,7 @@ export async function scanAndExtractPatterns(args) {
331
331
  continue;
332
332
  }
333
333
  const relativePath = toRelativePath(absoluteFile, projectRoot).replace(/\\/g, '/');
334
- patterns.push(buildPattern(normalized, relativePath, projectName || path.basename(projectRoot)));
334
+ patterns.push(buildPattern(normalized, relativePath));
335
335
  }
336
336
  return okStructured(`已扫描 ${files.length} 个文件,提取 ${patterns.length} 个候选模式`, {
337
337
  mode: 'directory',
@@ -0,0 +1,7 @@
1
+ export declare function searchMemory(args: unknown): Promise<import("../lib/response.js").ToolResponse | {
2
+ content: Array<{
3
+ type: string;
4
+ text: string;
5
+ }>;
6
+ isError: true;
7
+ }>;
@@ -0,0 +1,57 @@
1
+ import { parseArgs, getString, getNumber } from '../utils/parseArgs.js';
2
+ import { okStructured } from '../lib/response.js';
3
+ import { createMemoryClient } from '../lib/memory-client.js';
4
+ import { shouldShowSourceInSearch } from '../lib/memory-orchestration.js';
5
+ import { getMemoryConfig } from '../lib/memory-config.js';
6
+ import { handleToolError } from '../utils/error-handler.js';
7
+ export async function searchMemory(args) {
8
+ try {
9
+ const parsed = parseArgs(args, {
10
+ defaultValues: {
11
+ query: '',
12
+ type: '',
13
+ limit: 0,
14
+ },
15
+ });
16
+ const query = getString(parsed.query);
17
+ if (!query) {
18
+ throw new Error('缺少必填参数: query');
19
+ }
20
+ const client = createMemoryClient();
21
+ if (!client.isEnabled()) {
22
+ return okStructured('记忆服务未开启,无法检索。', {
23
+ enabled: false,
24
+ results: [],
25
+ });
26
+ }
27
+ const config = getMemoryConfig();
28
+ const limit = getNumber(parsed.limit, config.searchLimit);
29
+ const typeFilter = getString(parsed.type);
30
+ const tags = Array.isArray(parsed.tags)
31
+ ? parsed.tags.filter((item) => typeof item === 'string')
32
+ : [];
33
+ const results = await client.search(query, {
34
+ limit,
35
+ preferTypes: typeFilter ? [typeFilter] : [],
36
+ preferTags: tags,
37
+ });
38
+ const items = results.map((item) => ({
39
+ id: item.id,
40
+ score: item.score,
41
+ name: item.name,
42
+ type: item.type,
43
+ summary: item.summary,
44
+ tags: item.tags,
45
+ sourcePath: shouldShowSourceInSearch(item, config) ? item.sourcePath : undefined,
46
+ }));
47
+ return okStructured(results.length > 0 ? `找到 ${results.length} 条相关记忆` : '未找到相关记忆', {
48
+ enabled: true,
49
+ query,
50
+ count: results.length,
51
+ results: items,
52
+ });
53
+ }
54
+ catch (error) {
55
+ return handleToolError(error, 'search_memory');
56
+ }
57
+ }
@@ -423,7 +423,7 @@ ${graphContext.highlights.length > 0
423
423
  : "- 任务级线索: 无"}
424
424
  - 使用方式: 先读取基线图谱,再用本次任务图谱做 TBP-4 / TBP-5 / TBP-6 的边界与真因收敛
425
425
  `;
426
- const memoryContext = await loadMemoryInjectionContext([errorMessage, stackTrace, codeContext].filter(Boolean).join("\n"));
426
+ const memoryContext = await loadMemoryInjectionContext([errorMessage, stackTrace, codeContext].filter(Boolean).join("\n"), "bugfix");
427
427
  const memoryGuideSection = renderMemoryGuideSection(memoryContext);
428
428
  if (requirementsMode === "loop") {
429
429
  throwIfAborted(context?.signal, "start_bugfix(loop) 已取消");
@@ -512,7 +512,7 @@ ${graphContext.highlights.length > 0
512
512
  ],
513
513
  notes: [
514
514
  ...headerNotes,
515
- ...(memoryContext.enabled ? ['记忆系统: 已启用,优先复用历史修复经验并在结束后评估沉淀'] : []),
515
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,历史修复经验全文已自动注入,结束后评估沉淀'] : []),
516
516
  ],
517
517
  });
518
518
  const loopTemplate = profileDecision.resolved === 'strict'
@@ -577,7 +577,7 @@ ${graphContext.highlights.length > 0
577
577
  ],
578
578
  notes: [
579
579
  ...headerNotes,
580
- ...(memoryContext.enabled ? ['记忆系统: 已启用,必要时先读取相似历史资产'] : []),
580
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,相似历史经验全文已自动注入'] : []),
581
581
  ],
582
582
  });
583
583
  const promptTemplate = profileDecision.resolved === 'strict'
@@ -303,7 +303,7 @@ ${graphContext.highlights.length > 0
303
303
  ]
304
304
  .filter(Boolean)
305
305
  .join("\n");
306
- const memoryContext = await loadMemoryInjectionContext(`${featureName}\n${description}`);
306
+ const memoryContext = await loadMemoryInjectionContext(`${featureName}\n${description}`, 'feature');
307
307
  const memoryGuideSection = renderMemoryGuideSection(memoryContext);
308
308
  if (requirementsMode === "loop") {
309
309
  throwIfAborted(context?.signal, "start_feature(loop) 已取消");
@@ -392,7 +392,7 @@ ${graphContext.highlights.length > 0
392
392
  notes: [
393
393
  `模板档位: ${templateProfile}`,
394
394
  graphStatusNote,
395
- ...(memoryContext.enabled ? ['记忆系统: 已启用,按需读取历史资产并在结束后评估是否沉淀'] : []),
395
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,历史经验全文已自动注入,结束后评估是否沉淀'] : []),
396
396
  ],
397
397
  });
398
398
  const guide = (header + LOOP_PROMPT_TEMPLATE
@@ -452,7 +452,7 @@ ${graphContext.highlights.length > 0
452
452
  notes: [
453
453
  `模板档位: ${templateProfile}`,
454
454
  graphStatusNote,
455
- ...(memoryContext.enabled ? ['记忆系统: 已启用,先复用摘要资产,必要时读取详情'] : []),
455
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,历史经验全文已自动注入'] : []),
456
456
  ],
457
457
  });
458
458
  const guide = (header + PROMPT_TEMPLATE
@@ -17,6 +17,27 @@ import { detectProjectType } from "../lib/project-detector.js";
17
17
  import { resolveWorkspaceRoot, isLikelyProjectNamedRelativePath, buildProjectRootRetryHint } from "../lib/workspace-root.js";
18
18
  import { reportToolProgress, throwIfAborted, } from "../lib/tool-execution-context.js";
19
19
  import { buildMemoryPlanStep, loadMemoryInjectionContext, renderMemoryGuideSection, } from "../lib/memory-orchestration.js";
20
+ import { isShadcnStack } from "../lib/shadcn-ui.js";
21
+ function buildShadcnBlocksPlanStep(description, framework) {
22
+ if (!isShadcnStack(framework)) {
23
+ return [];
24
+ }
25
+ return [
26
+ {
27
+ id: 'shadcn-blocks',
28
+ tool: 'ui_search',
29
+ when: 'React/Next 栈:调用 ui_search(category=shadcn-blocks)匹配 block',
30
+ args: {
31
+ mode: 'search',
32
+ query: description,
33
+ category: 'shadcn-blocks',
34
+ stack: framework,
35
+ limit: 5,
36
+ },
37
+ outputs: [],
38
+ },
39
+ ];
40
+ }
20
41
  function inferProductType(description) {
21
42
  const text = (description || '').toLowerCase();
22
43
  if (/电商|e-?commerce|shop|商城|购物/.test(text))
@@ -542,7 +563,7 @@ export async function startUi(args, context) {
542
563
  const skillBridgeStep = buildSkillBridgePlanStep(skillBridge);
543
564
  const skillBridgeSection = renderSkillBridgeSection(skillBridge);
544
565
  headerNotes.push(buildSkillHeaderNote(skillBridge));
545
- const memoryContext = await loadMemoryInjectionContext(description || templateName);
566
+ const memoryContext = await loadMemoryInjectionContext(description || templateName, 'ui');
546
567
  const memoryGuideSection = renderMemoryGuideSection(memoryContext);
547
568
  // 验证 mode 参数
548
569
  const validModes = ["auto", "manual"];
@@ -651,6 +672,7 @@ start_ui <描述> --requirements_mode=loop
651
672
  args: {},
652
673
  outputs: ['docs/ui/component-catalog.json'],
653
674
  },
675
+ ...buildShadcnBlocksPlanStep(description, framework),
654
676
  {
655
677
  id: 'template',
656
678
  tool: 'ui_search',
@@ -867,6 +889,7 @@ ${recommendation.reasoning}
867
889
  args: {},
868
890
  outputs: ['docs/ui/component-catalog.json'],
869
891
  },
892
+ ...buildShadcnBlocksPlanStep(description, inferredStack),
870
893
  {
871
894
  id: 'template',
872
895
  tool: 'ui_search',
@@ -906,7 +929,7 @@ ${recommendation.reasoning}
906
929
  ],
907
930
  notes: [
908
931
  ...headerNotes,
909
- ...(memoryContext.enabled ? ['记忆系统: 已启用,必要时先读取相似历史 UI 资产'] : []),
932
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,相似历史 UI 经验全文已自动注入'] : []),
910
933
  ],
911
934
  });
912
935
  const smartPlan = header + skillBridgeSection + (profileDecision.resolved === 'strict' ? smartPlanStrict : smartPlanGuided) + memoryGuideSection;
@@ -1037,7 +1060,7 @@ start_ui "设置页面" --framework=react
1037
1060
  ],
1038
1061
  notes: [
1039
1062
  ...headerNotes,
1040
- ...(memoryContext.enabled ? ['记忆系统: 已启用,必要时先读取相似历史 UI 资产'] : []),
1063
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,相似历史 UI 经验全文已自动注入'] : []),
1041
1064
  ],
1042
1065
  });
1043
1066
  const baseTemplate = profileDecision.resolved === 'strict'
@@ -1078,6 +1101,7 @@ start_ui "设置页面" --framework=react
1078
1101
  args: {},
1079
1102
  outputs: ['docs/ui/component-catalog.json'],
1080
1103
  },
1104
+ ...buildShadcnBlocksPlanStep(description, framework),
1081
1105
  {
1082
1106
  id: 'template',
1083
1107
  tool: 'ui_search',
@@ -1151,9 +1175,12 @@ start_ui "设置页面" --framework=react
1151
1175
  ],
1152
1176
  artifacts: [],
1153
1177
  nextSteps: [
1154
- '检查项目上下文,如不存在则调用 init_project_context',
1155
- '检查设计系统文件,如不存在则调用 ui_design_system',
1156
- '检查组件目录,如不存在则调用 init_component_catalog',
1178
+ '检查 docs/project-context.md,如不存在则调用 init_project_context',
1179
+ '检查 docs/design-system.md,如不存在则调用 ui_design_system',
1180
+ '检查 docs/ui/component-catalog.json,如不存在则调用 init_component_catalog',
1181
+ ...(isShadcnStack(framework)
1182
+ ? [`调用 ui_search --category=shadcn-blocks --query="${description}" 匹配 shadcn block`]
1183
+ : []),
1157
1184
  `调用 ui_search --mode=template --query="${description}"`,
1158
1185
  `保存模板到 docs/ui/${templateName}.json`,
1159
1186
  `调用 render_ui --framework="${framework}"`,