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.
- package/README.md +12 -5
- package/build/index.js +3 -1
- package/build/lib/__tests__/agents-md-template.unit.test.js +2 -0
- package/build/lib/__tests__/memory-config.unit.test.js +9 -0
- package/build/lib/__tests__/memory-injection.unit.test.d.ts +1 -0
- package/build/lib/__tests__/memory-injection.unit.test.js +51 -0
- package/build/lib/__tests__/memory-orchestration.unit.test.d.ts +1 -0
- package/build/lib/__tests__/memory-orchestration.unit.test.js +84 -0
- package/build/lib/__tests__/memory-payload.unit.test.d.ts +1 -0
- package/build/lib/__tests__/memory-payload.unit.test.js +35 -0
- package/build/lib/agents-md-template.js +7 -5
- package/build/lib/memory-client.d.ts +8 -1
- package/build/lib/memory-client.js +53 -44
- package/build/lib/memory-config.d.ts +8 -0
- package/build/lib/memory-config.js +19 -0
- package/build/lib/memory-orchestration.d.ts +7 -2
- package/build/lib/memory-orchestration.js +81 -8
- package/build/lib/memory-payload.d.ts +21 -0
- package/build/lib/memory-payload.js +65 -0
- package/build/lib/shadcn-ui.d.ts +11 -0
- package/build/lib/shadcn-ui.js +78 -0
- package/build/resources/ui-ux-data/guidelines/vercel-web-interface.json +1632 -0
- package/build/resources/ui-ux-data/metadata.json +27 -3
- package/build/resources/ui-ux-data/shadcn/blocks.json +2541 -0
- package/build/resources/ui-ux-data/shadcn/components.json +997 -0
- package/build/resources/ui-ux-data/themes/presets.json +483 -0
- package/build/schemas/index.d.ts +38 -9
- package/build/schemas/memory-tools.d.ts +38 -9
- package/build/schemas/memory-tools.js +24 -9
- package/build/schemas/output/ui-ux-tools.d.ts +16 -0
- package/build/schemas/output/ui-ux-tools.js +4 -0
- package/build/schemas/ui-ux-schemas.js +3 -3
- package/build/tools/__tests__/start_ui.property.test.js +4 -3
- package/build/tools/index.d.ts +1 -0
- package/build/tools/index.js +1 -0
- package/build/tools/memorize_asset.js +12 -0
- package/build/tools/scan_and_extract_patterns.js +7 -7
- package/build/tools/search_memory.d.ts +7 -0
- package/build/tools/search_memory.js +57 -0
- package/build/tools/start_bugfix.js +3 -3
- package/build/tools/start_feature.js +3 -3
- package/build/tools/start_ui.js +33 -6
- package/build/tools/ui-ux-tools.js +322 -244
- package/build/utils/__tests__/shadcn-sync.unit.test.d.ts +1 -0
- package/build/utils/__tests__/shadcn-sync.unit.test.js +49 -0
- package/build/utils/__tests__/theme-pick.unit.test.d.ts +1 -0
- package/build/utils/__tests__/theme-pick.unit.test.js +9 -0
- package/build/utils/__tests__/themes-sync.unit.test.d.ts +1 -0
- package/build/utils/__tests__/themes-sync.unit.test.js +21 -0
- package/build/utils/__tests__/ui-metadata.unit.test.d.ts +1 -0
- package/build/utils/__tests__/ui-metadata.unit.test.js +35 -0
- package/build/utils/__tests__/vercel-guidelines-sync.unit.test.d.ts +1 -0
- package/build/utils/__tests__/vercel-guidelines-sync.unit.test.js +34 -0
- package/build/utils/bm25.d.ts +2 -1
- package/build/utils/bm25.js +17 -5
- package/build/utils/shadcn-sync.d.ts +55 -0
- package/build/utils/shadcn-sync.js +146 -0
- package/build/utils/themes-sync.d.ts +32 -0
- package/build/utils/themes-sync.js +201 -0
- package/build/utils/ui-data-loader.js +13 -2
- package/build/utils/ui-metadata.d.ts +27 -0
- package/build/utils/ui-metadata.js +39 -0
- package/build/utils/ui-search-engine.d.ts +1 -0
- package/build/utils/ui-search-engine.js +20 -6
- package/build/utils/ui-sync.d.ts +24 -2
- package/build/utils/ui-sync.js +152 -86
- package/build/utils/vercel-guidelines-sync.d.ts +30 -0
- package/build/utils/vercel-guidelines-sync.js +133 -0
- package/docs/data/tools.js +18 -0
- package/docs/i18n/all-tools/en.json +6 -1
- package/docs/i18n/all-tools/ja.json +2 -1
- package/docs/i18n/all-tools/ko.json +2 -1
- package/docs/i18n/all-tools/zh-CN.json +7 -2
- package/docs/i18n/en.json +5 -5
- package/docs/i18n/ja.json +2 -2
- package/docs/i18n/ko.json +2 -2
- package/docs/i18n/zh-CN.json +7 -7
- package/docs/memory-local-setup.md +1 -1
- package/docs/memory-local-setup.zh-CN.md +5 -2
- package/docs/pages/getting-started.html +3 -2
- 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: "
|
|
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: "
|
|
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: '
|
|
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: '
|
|
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
|
|
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: "
|
|
51
|
+
description: "数据类别(search 模式):colors、icons、charts、landing、products、typography、styles、ux-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
|
|
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
|
-
// 硬性约束:必须少于
|
|
21
|
-
expect(tokenCount).toBeLessThan(
|
|
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 });
|
package/build/tools/index.d.ts
CHANGED
|
@@ -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";
|
package/build/tools/index.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
334
|
+
patterns.push(buildPattern(normalized, relativePath));
|
|
335
335
|
}
|
|
336
336
|
return okStructured(`已扫描 ${files.length} 个文件,提取 ${patterns.length} 个候选模式`, {
|
|
337
337
|
mode: 'directory',
|
|
@@ -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
|
package/build/tools/start_ui.js
CHANGED
|
@@ -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 ? ['记忆系统:
|
|
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 ? ['记忆系统:
|
|
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
|
-
'
|
|
1155
|
-
'
|
|
1156
|
-
'
|
|
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}"`,
|