mcp-probe-kit 3.0.21 → 3.0.23
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 +8 -10
- package/build/index.js +1 -5
- package/build/lib/memory-orchestration.d.ts +1 -0
- package/build/lib/memory-orchestration.js +21 -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 +0 -48
- package/build/schemas/memory-tools.d.ts +0 -48
- package/build/schemas/memory-tools.js +0 -29
- 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__/cursor-history.unit.test.js +0 -49
- package/build/tools/__tests__/search_memory.unit.test.d.ts +1 -0
- package/build/tools/__tests__/search_memory.unit.test.js +83 -0
- package/build/tools/__tests__/start_ui.property.test.js +4 -3
- package/build/tools/index.d.ts +0 -2
- package/build/tools/index.js +0 -2
- package/build/tools/search_memory.js +3 -2
- package/build/tools/start_ui.js +30 -3
- 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 +1 -33
- package/docs/i18n/all-tools/en.json +4 -14
- package/docs/i18n/all-tools/ja.json +3 -5
- package/docs/i18n/all-tools/ko.json +3 -5
- package/docs/i18n/all-tools/zh-CN.json +4 -14
- package/docs/i18n/en.json +10 -10
- package/docs/i18n/ja.json +9 -9
- package/docs/i18n/ko.json +9 -9
- package/docs/i18n/zh-CN.json +10 -10
- package/docs/pages/all-tools.html +4 -4
- package/docs/pages/examples.html +2 -2
- package/docs/pages/getting-started.html +1 -1
- package/docs/pages/migration.html +2 -2
- package/package.json +2 -2
- package/build/tools/cursor_list_conversations.d.ts +0 -7
- package/build/tools/cursor_list_conversations.js +0 -35
- package/build/tools/cursor_search_conversations.d.ts +0 -7
- package/build/tools/cursor_search_conversations.js +0 -36
|
@@ -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: {
|
|
@@ -1,67 +1,18 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
-
const listConversationsMock = vi.fn();
|
|
3
|
-
const searchHistoryMock = vi.fn();
|
|
4
2
|
const readConversationMock = vi.fn();
|
|
5
3
|
vi.mock('../../lib/cursor-history-client.js', () => ({
|
|
6
4
|
createCursorHistoryClient: () => ({
|
|
7
|
-
listConversations: listConversationsMock,
|
|
8
|
-
searchHistory: searchHistoryMock,
|
|
9
5
|
readConversation: readConversationMock,
|
|
10
6
|
}),
|
|
11
7
|
}));
|
|
12
|
-
import { cursorListConversations } from '../cursor_list_conversations.js';
|
|
13
|
-
import { cursorSearchConversations } from '../cursor_search_conversations.js';
|
|
14
8
|
import { cursorReadConversation } from '../cursor_read_conversation.js';
|
|
15
9
|
beforeEach(() => {
|
|
16
|
-
listConversationsMock.mockReset();
|
|
17
|
-
searchHistoryMock.mockReset();
|
|
18
10
|
readConversationMock.mockReset();
|
|
19
11
|
});
|
|
20
12
|
afterEach(() => {
|
|
21
13
|
vi.clearAllMocks();
|
|
22
14
|
});
|
|
23
15
|
describe('cursor history tools', () => {
|
|
24
|
-
test('cursor_list_conversations 返回摘要列表', async () => {
|
|
25
|
-
listConversationsMock.mockResolvedValue([
|
|
26
|
-
{ composerId: 'c1', name: '新需求', source: 'composerHeaders' },
|
|
27
|
-
]);
|
|
28
|
-
const result = await cursorListConversations({ title_query: '新需求', limit: 10 });
|
|
29
|
-
expect(result.isError).toBe(false);
|
|
30
|
-
expect('structuredContent' in result).toBe(true);
|
|
31
|
-
if (!('structuredContent' in result)) {
|
|
32
|
-
throw new Error('structuredContent 缺失');
|
|
33
|
-
}
|
|
34
|
-
expect(result.content[0].text).toContain('已获取 1 条 Cursor 会话摘要');
|
|
35
|
-
expect(result.structuredContent.count).toBe(1);
|
|
36
|
-
expect(listConversationsMock).toHaveBeenCalledWith({
|
|
37
|
-
titleQuery: '新需求',
|
|
38
|
-
workspaceQuery: '',
|
|
39
|
-
includeArchived: false,
|
|
40
|
-
limit: 10,
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
test('cursor_search_conversations 缺少 query 时返回错误', async () => {
|
|
44
|
-
const result = await cursorSearchConversations({});
|
|
45
|
-
expect(result.isError).toBe(true);
|
|
46
|
-
expect(result.content[0].text).toContain('缺少必填参数: query');
|
|
47
|
-
});
|
|
48
|
-
test('cursor_search_conversations 返回命中结果', async () => {
|
|
49
|
-
searchHistoryMock.mockResolvedValue([
|
|
50
|
-
{ composerId: 'c1', conversationName: '新需求', bubbleId: 'b1', type: 1, text: '我们先聊需求' },
|
|
51
|
-
]);
|
|
52
|
-
const result = await cursorSearchConversations({ query: '需求', composer_id: 'c1', limit: 5 });
|
|
53
|
-
expect(result.isError).toBe(false);
|
|
54
|
-
expect('structuredContent' in result).toBe(true);
|
|
55
|
-
if (!('structuredContent' in result)) {
|
|
56
|
-
throw new Error('structuredContent 缺失');
|
|
57
|
-
}
|
|
58
|
-
expect(result.structuredContent.count).toBe(1);
|
|
59
|
-
expect(searchHistoryMock).toHaveBeenCalledWith({
|
|
60
|
-
query: '需求',
|
|
61
|
-
composerId: 'c1',
|
|
62
|
-
limit: 5,
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
16
|
test('cursor_read_conversation 返回消息时间线', async () => {
|
|
66
17
|
readConversationMock.mockResolvedValue({
|
|
67
18
|
composerId: 'c1',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
const searchMock = vi.fn();
|
|
3
|
+
const isEnabledMock = vi.fn();
|
|
4
|
+
vi.mock('../../lib/memory-client.js', () => ({
|
|
5
|
+
createMemoryClient: () => ({
|
|
6
|
+
isEnabled: isEnabledMock,
|
|
7
|
+
search: searchMock,
|
|
8
|
+
}),
|
|
9
|
+
}));
|
|
10
|
+
import { searchMemory } from '../search_memory.js';
|
|
11
|
+
import { formatSearchMemoryResultsText } from '../../lib/memory-orchestration.js';
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
isEnabledMock.mockReset();
|
|
14
|
+
searchMock.mockReset();
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.clearAllMocks();
|
|
18
|
+
});
|
|
19
|
+
describe('formatSearchMemoryResultsText', () => {
|
|
20
|
+
test('renders id, summary, description and read hint', () => {
|
|
21
|
+
const text = formatSearchMemoryResultsText([
|
|
22
|
+
{
|
|
23
|
+
id: '6c97bd10-654e-4f25-a560-99f7469dc11a',
|
|
24
|
+
score: 0.678,
|
|
25
|
+
name: 'playwright-e2e-testing-speed-pattern',
|
|
26
|
+
type: 'pattern',
|
|
27
|
+
description: 'Speed up Playwright E2E suites',
|
|
28
|
+
summary: 'Playwright E2E parallelization pattern',
|
|
29
|
+
tags: ['pattern', 'e2e'],
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
expect(text).toContain('找到 1 条相关记忆');
|
|
33
|
+
expect(text).toContain('id: 6c97bd10-654e-4f25-a560-99f7469dc11a');
|
|
34
|
+
expect(text).toContain('摘要: Playwright E2E parallelization pattern');
|
|
35
|
+
expect(text).toContain('描述: Speed up Playwright E2E suites');
|
|
36
|
+
expect(text).toContain('read_memory_asset {"asset_id": "6c97bd10-654e-4f25-a560-99f7469dc11a"}');
|
|
37
|
+
});
|
|
38
|
+
test('returns empty-state text', () => {
|
|
39
|
+
expect(formatSearchMemoryResultsText([])).toBe('未找到相关记忆');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('search_memory 单元测试', () => {
|
|
43
|
+
test('记忆服务未开启时返回跳过结果', async () => {
|
|
44
|
+
isEnabledMock.mockReturnValue(false);
|
|
45
|
+
const result = await searchMemory({ query: 'test' });
|
|
46
|
+
expect(result.isError).toBe(false);
|
|
47
|
+
expect('structuredContent' in result).toBe(true);
|
|
48
|
+
if (!('structuredContent' in result)) {
|
|
49
|
+
throw new Error('structuredContent 缺失');
|
|
50
|
+
}
|
|
51
|
+
expect(result.content[0].text).toContain('记忆服务未开启');
|
|
52
|
+
expect(result.structuredContent).toEqual({ enabled: false, results: [] });
|
|
53
|
+
expect(searchMock).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
55
|
+
test('命中结果时文本输出包含 asset 字段', async () => {
|
|
56
|
+
isEnabledMock.mockReturnValue(true);
|
|
57
|
+
searchMock.mockResolvedValue([
|
|
58
|
+
{
|
|
59
|
+
id: 'asset-1',
|
|
60
|
+
score: 0.88,
|
|
61
|
+
name: 'feishu-proxy-bug',
|
|
62
|
+
type: 'bugfix',
|
|
63
|
+
description: 'Feishu proxy mismatch',
|
|
64
|
+
summary: 'proxy caused 400 on HTTPS',
|
|
65
|
+
tags: ['bugfix', 'proxy'],
|
|
66
|
+
},
|
|
67
|
+
]);
|
|
68
|
+
const result = await searchMemory({ query: 'proxy', limit: 1 });
|
|
69
|
+
expect(result.isError).toBe(false);
|
|
70
|
+
expect('structuredContent' in result).toBe(true);
|
|
71
|
+
if (!('structuredContent' in result)) {
|
|
72
|
+
throw new Error('structuredContent 缺失');
|
|
73
|
+
}
|
|
74
|
+
expect(result.content[0].text).toContain('id: asset-1');
|
|
75
|
+
expect(result.content[0].text).toContain('摘要: proxy caused 400 on HTTPS');
|
|
76
|
+
expect(result.content[0].text).toContain('描述: Feishu proxy mismatch');
|
|
77
|
+
expect(result.structuredContent.results[0]).toEqual(expect.objectContaining({
|
|
78
|
+
id: 'asset-1',
|
|
79
|
+
description: 'Feishu proxy mismatch',
|
|
80
|
+
summary: 'proxy caused 400 on HTTPS',
|
|
81
|
+
}));
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -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
|
@@ -20,8 +20,6 @@ export { searchMemory } from "./search_memory.js";
|
|
|
20
20
|
export { readMemoryAsset } from "./read_memory_asset.js";
|
|
21
21
|
export { memorizeAsset } from "./memorize_asset.js";
|
|
22
22
|
export { scanAndExtractPatterns } from "./scan_and_extract_patterns.js";
|
|
23
|
-
export { cursorListConversations } from "./cursor_list_conversations.js";
|
|
24
|
-
export { cursorSearchConversations } from "./cursor_search_conversations.js";
|
|
25
23
|
export { cursorReadConversation } from "./cursor_read_conversation.js";
|
|
26
24
|
export { startProduct } from "./start_product.js";
|
|
27
25
|
export { gitWorkReport } from "./git_work_report.js";
|
package/build/tools/index.js
CHANGED
|
@@ -24,8 +24,6 @@ export { searchMemory } from "./search_memory.js";
|
|
|
24
24
|
export { readMemoryAsset } from "./read_memory_asset.js";
|
|
25
25
|
export { memorizeAsset } from "./memorize_asset.js";
|
|
26
26
|
export { scanAndExtractPatterns } from "./scan_and_extract_patterns.js";
|
|
27
|
-
export { cursorListConversations } from "./cursor_list_conversations.js";
|
|
28
|
-
export { cursorSearchConversations } from "./cursor_search_conversations.js";
|
|
29
27
|
export { cursorReadConversation } from "./cursor_read_conversation.js";
|
|
30
28
|
// 产品设计工作流
|
|
31
29
|
export { startProduct } from "./start_product.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseArgs, getString, getNumber } from '../utils/parseArgs.js';
|
|
2
2
|
import { okStructured } from '../lib/response.js';
|
|
3
3
|
import { createMemoryClient } from '../lib/memory-client.js';
|
|
4
|
-
import { shouldShowSourceInSearch } from '../lib/memory-orchestration.js';
|
|
4
|
+
import { formatSearchMemoryResultsText, shouldShowSourceInSearch, } from '../lib/memory-orchestration.js';
|
|
5
5
|
import { getMemoryConfig } from '../lib/memory-config.js';
|
|
6
6
|
import { handleToolError } from '../utils/error-handler.js';
|
|
7
7
|
export async function searchMemory(args) {
|
|
@@ -40,11 +40,12 @@ export async function searchMemory(args) {
|
|
|
40
40
|
score: item.score,
|
|
41
41
|
name: item.name,
|
|
42
42
|
type: item.type,
|
|
43
|
+
description: item.description,
|
|
43
44
|
summary: item.summary,
|
|
44
45
|
tags: item.tags,
|
|
45
46
|
sourcePath: shouldShowSourceInSearch(item, config) ? item.sourcePath : undefined,
|
|
46
47
|
}));
|
|
47
|
-
return okStructured(results
|
|
48
|
+
return okStructured(formatSearchMemoryResultsText(results, config), {
|
|
48
49
|
enabled: true,
|
|
49
50
|
query,
|
|
50
51
|
count: results.length,
|
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))
|
|
@@ -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',
|
|
@@ -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}"`,
|