mcp-probe-kit 2.1.2 → 2.2.0

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.
@@ -16,12 +16,15 @@ describe('start_ui 集成测试', () => {
16
16
  const text = result.content[0].text || '';
17
17
  // 1. 应该包含快速开始部分
18
18
  expect(text).toMatch(/^#\s+快速开始/m);
19
- // 2. 应该包含 4 个步骤
20
- expect(text).toMatch(/步骤 1.*生成设计系统/);
21
- expect(text).toMatch(/步骤 2.*生成组件目录/);
22
- expect(text).toMatch(/步骤 3.*搜索.*模板/);
23
- expect(text).toMatch(/步骤 4.*渲染.*代码/);
19
+ // 2. 应该包含 6 个步骤(新增了项目上下文和更新索引)
20
+ expect(text).toMatch(/步骤 1.*生成项目上下文/);
21
+ expect(text).toMatch(/步骤 2.*生成设计系统/);
22
+ expect(text).toMatch(/步骤 3.*生成组件目录/);
23
+ expect(text).toMatch(/步骤 4.*搜索.*模板/);
24
+ expect(text).toMatch(/步骤 5.*渲染.*代码/);
25
+ expect(text).toMatch(/步骤 6.*更新项目上下文/);
24
26
  // 3. 每个步骤应该包含工具名称
27
+ expect(text).toMatch(/init_project_context/);
25
28
  expect(text).toMatch(/ui_design_system/);
26
29
  expect(text).toMatch(/init_component_catalog/);
27
30
  expect(text).toMatch(/ui_search/);
@@ -35,9 +35,9 @@ describe('start_ui 单元测试', () => {
35
35
  });
36
36
  });
37
37
  describe('参数解析', () => {
38
- test('默认 framework 为 react', async () => {
38
+ test('默认 framework 为 html(最通用)', async () => {
39
39
  const result = await startUi({ description: '测试' });
40
- expect(result.content[0].text).toMatch(/react/i);
40
+ expect(result.content[0].text).toMatch(/html/i);
41
41
  });
42
42
  test('支持 vue framework', async () => {
43
43
  const result = await startUi({
@@ -11,20 +11,38 @@ import { parseArgs, getString } from "../utils/parseArgs.js";
11
11
  import { getReasoningEngine } from "./ui-ux-tools.js";
12
12
  import { okStructured } from "../lib/response.js";
13
13
  import { UIReportSchema } from "../schemas/structured-output.js";
14
+ import { detectProjectType } from "../lib/project-detector.js";
14
15
  const PROMPT_TEMPLATE = `# 快速开始
15
16
 
16
17
  **职责说明**: 本工具仅提供执行指导,不执行实际操作。请按顺序调用以下 MCP 工具。
17
18
 
18
19
  执行以下工具:
19
20
 
20
- 1. 检查 \`docs/design-system.md\` 是否存在,不存在则调用 \`ui_design_system --product_type="SaaS" --stack="{framework}"\`
21
- 2. 检查 \`docs/component-catalog.json\` 是否存在,不存在则调用 \`init_component_catalog\`
22
- 3. \`ui_search --mode=template --query="{description}"\`
23
- 4. \`render_ui --template="docs/ui/{templateName}.json" --framework="{framework}"\`
21
+ 1. 检查 \`docs/project-context.md\` 是否存在,不存在则调用 \`init_project_context\`
22
+ 2. 检查 \`docs/design-system.md\` 是否存在,不存在则调用 \`ui_design_system --product_type="SaaS" --stack="{framework}"\`
23
+ 3. 检查 \`docs/component-catalog.json\` 是否存在,不存在则调用 \`init_component_catalog\`
24
+ 4. \`ui_search --mode=template --query="{description}"\`
25
+ 5. \`render_ui --template="docs/ui/{templateName}.json" --framework="{framework}"\`
26
+ 6. 将生成的 UI 文档添加到 \`docs/project-context.md\` 索引中
24
27
 
25
28
  ---
26
29
 
27
- ## 步骤 1: 生成设计系统(如不存在)✅
30
+ ## 步骤 1: 生成项目上下文(如不存在)📋
31
+
32
+ **检查**: 查看 \`docs/project-context.md\` 是否存在
33
+
34
+ **如果不存在,调用工具**: \`init_project_context\`
35
+ **参数**: 无(使用默认配置)
36
+
37
+ **预期输出**:
38
+ - \`docs/project-context.md\` - 项目上下文索引文件
39
+ - \`docs/project-context/\` - 项目文档目录
40
+
41
+ **失败处理**: 确保 docs 目录存在且有写入权限
42
+
43
+ ---
44
+
45
+ ## 步骤 2: 生成设计系统(如不存在)🎨
28
46
 
29
47
  **检查**: 查看 \`docs/design-system.md\` 是否存在
30
48
 
@@ -43,7 +61,7 @@ const PROMPT_TEMPLATE = `# 快速开始
43
61
 
44
62
  ---
45
63
 
46
- ## 步骤 2: 生成组件目录(如不存在)🔄
64
+ ## 步骤 3: 生成组件目录(如不存在)📦
47
65
 
48
66
  **检查**: 查看 \`docs/component-catalog.json\` 是否存在
49
67
 
@@ -51,11 +69,11 @@ const PROMPT_TEMPLATE = `# 快速开始
51
69
  **参数**: 无
52
70
 
53
71
  **预期输出**: \`docs/component-catalog.json\`
54
- **失败处理**: 确保步骤 1 的设计系统文件已生成
72
+ **失败处理**: 确保步骤 2 的设计系统文件已生成
55
73
 
56
74
  ---
57
75
 
58
- ## 步骤 3: 搜索 UI 模板 🔍
76
+ ## 步骤 4: 搜索 UI 模板 🔍
59
77
 
60
78
  **工具**: \`ui_search\`
61
79
  **参数**:
@@ -67,11 +85,11 @@ const PROMPT_TEMPLATE = `# 快速开始
67
85
  \`\`\`
68
86
 
69
87
  **预期输出**: 匹配的模板列表(可能为空)
70
- **失败处理**: 如果没有找到模板,继续到步骤 4 使用默认模板
88
+ **失败处理**: 如果没有找到模板,继续到步骤 5 使用默认模板
71
89
 
72
90
  ---
73
91
 
74
- ## 步骤 4: 渲染最终代码 🎨
92
+ ## 步骤 5: 渲染最终代码 💻
75
93
 
76
94
  **工具**: \`render_ui\`
77
95
  **参数**:
@@ -87,6 +105,32 @@ const PROMPT_TEMPLATE = `# 快速开始
87
105
 
88
106
  ---
89
107
 
108
+ ## 步骤 6: 更新项目上下文索引 📝
109
+
110
+ **操作**: 将生成的 UI 文档添加到 \`docs/project-context.md\` 中
111
+
112
+ **添加内容**:
113
+ 在 "## 📚 文档导航" 部分添加:
114
+
115
+ \`\`\`markdown
116
+ ### [UI 设计系统](./design-system.md)
117
+ 项目的 UI 设计规范,包括颜色、字体、组件样式等
118
+
119
+ ### [UI 组件目录](./component-catalog.json)
120
+ 可用的 UI 组件及其属性定义
121
+ \`\`\`
122
+
123
+ 在 "## 💡 开发时查看对应文档" 部分的 "添加新功能" 下添加:
124
+ \`\`\`markdown
125
+ - **UI 设计系统**: [design-system.md](./design-system.md) - 查看设计规范
126
+ - **UI 组件目录**: [component-catalog.json](./component-catalog.json) - 查看可用组件
127
+ \`\`\`
128
+
129
+ **预期结果**: \`docs/project-context.md\` 包含 UI 相关文档的链接
130
+ **失败处理**: 如果文件不存在,跳过此步骤
131
+
132
+ ---
133
+
90
134
  ## 高级选项
91
135
 
92
136
  ### 自定义设计系统
@@ -103,16 +147,75 @@ A: 不需要。如果文件已存在,直接跳过步骤 1。
103
147
  **Q: 如何使用自定义模板?**
104
148
  A: 在 \`docs/ui/\` 目录创建 JSON 模板文件,然后在步骤 4 中指定模板路径。
105
149
  `;
150
+ /**
151
+ * 从 project-context.md 读取框架信息
152
+ */
153
+ function getFrameworkFromContext(projectRoot) {
154
+ try {
155
+ const fs = require('fs');
156
+ const path = require('path');
157
+ const contextPath = path.join(projectRoot, 'docs', 'project-context.md');
158
+ if (!fs.existsSync(contextPath)) {
159
+ return null;
160
+ }
161
+ const content = fs.readFileSync(contextPath, 'utf-8');
162
+ // 匹配表格中的框架信息:| 框架 | xxx |
163
+ const match = content.match(/\|\s*框架\s*\|\s*([^\|]+)\s*\|/);
164
+ if (match && match[1]) {
165
+ const framework = match[1].trim();
166
+ if (framework && framework !== '无' && framework !== '未检测到') {
167
+ return framework;
168
+ }
169
+ }
170
+ return null;
171
+ }
172
+ catch (error) {
173
+ return null;
174
+ }
175
+ }
106
176
  /**
107
177
  * 统一 UI 开发编排工具
108
178
  */
109
179
  export async function startUi(args) {
110
180
  try {
181
+ const projectRoot = process.cwd();
182
+ // 优先从 project-context.md 读取框架信息
183
+ let detectedFramework = 'html'; // 默认值
184
+ const contextFramework = getFrameworkFromContext(projectRoot);
185
+ if (contextFramework) {
186
+ // 从 project-context.md 中读取到了框架信息
187
+ const fw = contextFramework.toLowerCase();
188
+ if (fw.includes('vue') || fw.includes('nuxt')) {
189
+ detectedFramework = 'vue';
190
+ }
191
+ else if (fw.includes('react') || fw.includes('next')) {
192
+ detectedFramework = 'react';
193
+ }
194
+ else if (fw.includes('html')) {
195
+ detectedFramework = 'html';
196
+ }
197
+ }
198
+ else {
199
+ // 如果没有 project-context.md,则实时检测
200
+ const detection = detectProjectType(projectRoot);
201
+ if (detection.framework) {
202
+ const fw = detection.framework.toLowerCase();
203
+ if (fw.includes('vue') || fw.includes('nuxt')) {
204
+ detectedFramework = 'vue';
205
+ }
206
+ else if (fw.includes('react') || fw.includes('next')) {
207
+ detectedFramework = 'react';
208
+ }
209
+ else if (fw.includes('html') || fw === 'none') {
210
+ detectedFramework = 'html';
211
+ }
212
+ }
213
+ }
111
214
  // 智能参数解析
112
215
  const parsedArgs = parseArgs(args, {
113
216
  defaultValues: {
114
217
  description: "",
115
- framework: "react",
218
+ framework: detectedFramework, // 使用检测到的框架
116
219
  template: "",
117
220
  mode: "manual",
118
221
  },
@@ -125,7 +228,7 @@ export async function startUi(args) {
125
228
  },
126
229
  });
127
230
  const description = getString(parsedArgs.description);
128
- const framework = getString(parsedArgs.framework) || "react";
231
+ const framework = getString(parsedArgs.framework) || detectedFramework;
129
232
  const mode = getString(parsedArgs.mode) || "manual";
130
233
  let templateName = getString(parsedArgs.template);
131
234
  // 验证 mode 参数
@@ -184,27 +287,35 @@ start_ui "用户列表" --mode=auto
184
287
 
185
288
  请按顺序执行以下命令:
186
289
 
187
- ### 1. 生成设计系统 🎨
290
+ ### 1. 生成项目上下文 📋
291
+ \`\`\`bash
292
+ init_project_context
293
+ \`\`\`
294
+
295
+ ### 2. 生成设计系统 🎨
188
296
  \`\`\`bash
189
297
  ui_design_system --product_type="${inferredProductType}" --stack="${inferredStack}" --keywords="${inferredKeywords}" --description="${description}"
190
298
  \`\`\`
191
299
 
192
- ### 2. 生成组件目录 📦
300
+ ### 3. 生成组件目录 📦
193
301
  \`\`\`bash
194
302
  init_component_catalog
195
303
  \`\`\`
196
304
 
197
- ### 3. 生成 UI 模板 📄
305
+ ### 4. 生成 UI 模板 📄
198
306
  \`\`\`bash
199
307
  # 搜索现有模板或生成新模板
200
308
  ui_search --mode=template --query="${templateName || description}"
201
309
  \`\`\`
202
310
 
203
- ### 4. 渲染代码 💻
311
+ ### 5. 渲染代码 💻
204
312
  \`\`\`bash
205
313
  render_ui docs/ui/${templateName || 'template'}.json --framework="${inferredStack}"
206
314
  \`\`\`
207
315
 
316
+ ### 6. 更新项目上下文 📝
317
+ 将生成的 UI 文档链接添加到 \`docs/project-context.md\` 的文档导航部分。
318
+
208
319
  ---
209
320
 
210
321
  ## 💡 为什么选择这个方案?
@@ -216,6 +327,11 @@ ${recommendation.reasoning}
216
327
  summary: `智能 UI 开发:${description}`,
217
328
  status: 'pending',
218
329
  steps: [
330
+ {
331
+ name: '生成项目上下文',
332
+ status: 'pending',
333
+ description: `调用 init_project_context 生成项目文档`,
334
+ },
219
335
  {
220
336
  name: '生成设计系统',
221
337
  status: 'pending',
@@ -236,13 +352,20 @@ ${recommendation.reasoning}
236
352
  status: 'pending',
237
353
  description: '调用 render_ui 生成组件代码',
238
354
  },
355
+ {
356
+ name: '更新项目上下文',
357
+ status: 'pending',
358
+ description: '将 UI 文档添加到 project-context.md 索引',
359
+ },
239
360
  ],
240
361
  artifacts: [],
241
362
  nextSteps: [
363
+ '调用 init_project_context',
242
364
  `调用 ui_design_system --product_type="${inferredProductType}" --stack="${inferredStack}"`,
243
365
  '调用 init_component_catalog',
244
366
  `调用 ui_search --mode=template --query="${description}"`,
245
367
  `调用 render_ui --framework="${inferredStack}"`,
368
+ '更新 docs/project-context.md 添加 UI 文档链接',
246
369
  ],
247
370
  designSystem: {
248
371
  colors: {},
@@ -326,6 +449,11 @@ start_ui "设置页面" --framework=react
326
449
  summary: `UI 开发工作流:${description}`,
327
450
  status: 'pending',
328
451
  steps: [
452
+ {
453
+ name: '检查项目上下文',
454
+ status: 'pending',
455
+ description: '检查 docs/project-context.md 是否存在',
456
+ },
329
457
  {
330
458
  name: '检查设计系统',
331
459
  status: 'pending',
@@ -346,13 +474,20 @@ start_ui "设置页面" --framework=react
346
474
  status: 'pending',
347
475
  description: '调用 render_ui 生成组件代码',
348
476
  },
477
+ {
478
+ name: '更新项目上下文',
479
+ status: 'pending',
480
+ description: '将 UI 文档添加到 project-context.md 索引',
481
+ },
349
482
  ],
350
483
  artifacts: [],
351
484
  nextSteps: [
485
+ '检查项目上下文,如不存在则调用 init_project_context',
352
486
  '检查设计系统文件,如不存在则调用 ui_design_system',
353
487
  '检查组件目录,如不存在则调用 init_component_catalog',
354
488
  `调用 ui_search --mode=template --query="${description}"`,
355
489
  `调用 render_ui --framework="${framework}"`,
490
+ '更新 docs/project-context.md 添加 UI 文档链接',
356
491
  ],
357
492
  designSystem: {
358
493
  colors: {},
@@ -296,13 +296,19 @@
296
296
 
297
297
  <div class="nav-section">
298
298
  <div class="nav-section-title">工具文档</div>
299
- <a href="./all-tools.html" class="nav-item active">
299
+ <div class="nav-item nav-item-toggle active expanded" onclick="toggleSubmenu(this)">
300
300
  <div class="nav-item-content">
301
301
  <span class="icon">🛠️</span>
302
302
  <span>所有工具</span>
303
303
  </div>
304
- <span class="badge">39</span>
305
- </a>
304
+ <div style="display: flex; align-items: center; gap: 8px;">
305
+ <span class="badge">39</span>
306
+ <span class="toggle-icon">▶</span>
307
+ </div>
308
+ </div>
309
+ <div class="nav-submenu expanded" id="tools-submenu">
310
+ <!-- 工具列表将通过 JavaScript 动态生成 -->
311
+ </div>
306
312
  </div>
307
313
 
308
314
  <div class="nav-section">
@@ -464,6 +470,49 @@
464
470
  <!-- 引入工具数据 -->
465
471
  <script src="../data/tools.js"></script>
466
472
  <script>
473
+ // 切换子菜单展开/收起
474
+ function toggleSubmenu(element) {
475
+ element.classList.toggle('expanded');
476
+ const submenu = document.getElementById('tools-submenu');
477
+ submenu.classList.toggle('expanded');
478
+ }
479
+
480
+ // 生成侧边栏工具列表
481
+ function generateSidebarTools() {
482
+ const submenu = document.getElementById('tools-submenu');
483
+ let html = '';
484
+
485
+ for (const [categoryKey, categoryInfo] of Object.entries(categories)) {
486
+ const tools = toolsData[categoryKey];
487
+ if (!tools || tools.length === 0) continue;
488
+
489
+ tools.forEach(tool => {
490
+ const toolId = tool.name.replace(/_/g, '-');
491
+ html += `
492
+ <a href="#${toolId}" class="nav-subitem" onclick="scrollToTool('${toolId}')">
493
+ ${tool.name}
494
+ </a>
495
+ `;
496
+ });
497
+ }
498
+
499
+ submenu.innerHTML = html;
500
+ }
501
+
502
+ // 滚动到指定工具
503
+ function scrollToTool(toolId) {
504
+ const element = document.getElementById(toolId);
505
+ if (element) {
506
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' });
507
+ // 高亮显示
508
+ element.style.transition = 'background 0.3s';
509
+ element.style.background = 'rgba(37, 99, 235, 0.05)';
510
+ setTimeout(() => {
511
+ element.style.background = '';
512
+ }, 2000);
513
+ }
514
+ }
515
+
467
516
  // Topbar scroll effect
468
517
  const topbar = document.getElementById('topbar');
469
518
  window.addEventListener('scroll', () => {
@@ -584,7 +633,7 @@
584
633
  }
585
634
 
586
635
  return `
587
- <div class="tool-card">
636
+ <div class="tool-card" id="${tool.name.replace(/_/g, '-')}">
588
637
  <div class="tool-main">
589
638
  <div class="tool-header">
590
639
  <div class="tool-name">${tool.name}</div>
@@ -632,6 +681,9 @@
632
681
  });
633
682
  }
634
683
 
684
+ // 生成侧边栏工具列表
685
+ generateSidebarTools();
686
+
635
687
  // 渲染所有工具
636
688
  renderTools();
637
689
 
@@ -218,6 +218,55 @@ body {
218
218
  opacity: 1;
219
219
  }
220
220
 
221
+ /* 子菜单样式 */
222
+ .nav-item-toggle {
223
+ cursor: pointer;
224
+ user-select: none;
225
+ }
226
+
227
+ .nav-item-toggle .toggle-icon {
228
+ transition: transform 0.2s;
229
+ font-size: 12px;
230
+ color: var(--text-tertiary);
231
+ }
232
+
233
+ .nav-item-toggle.expanded .toggle-icon {
234
+ transform: rotate(90deg);
235
+ }
236
+
237
+ .nav-submenu {
238
+ max-height: 0;
239
+ overflow: hidden;
240
+ transition: max-height 0.3s ease-out;
241
+ }
242
+
243
+ .nav-submenu.expanded {
244
+ max-height: 2000px;
245
+ }
246
+
247
+ .nav-subitem {
248
+ display: block;
249
+ padding: 8px 20px 8px 48px;
250
+ margin: 2px 12px;
251
+ color: var(--text-secondary);
252
+ text-decoration: none;
253
+ transition: all 0.2s;
254
+ border-radius: 6px;
255
+ font-size: 13px;
256
+ position: relative;
257
+ }
258
+
259
+ .nav-subitem:hover {
260
+ background: var(--bg-hover);
261
+ color: var(--primary);
262
+ }
263
+
264
+ .nav-subitem.active {
265
+ background: rgba(37, 99, 235, 0.05);
266
+ color: var(--primary);
267
+ font-weight: 600;
268
+ }
269
+
221
270
  .badge {
222
271
  background: var(--bg-hover);
223
272
  color: var(--text-secondary);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-probe-kit",
3
- "version": "2.1.2",
3
+ "version": "2.2.0",
4
4
  "description": "AI-Powered Development Toolkit - MCP Server with 39 practical tools covering code quality, development efficiency, project management, and UI/UX design. Features: Structured Output, Workflow Orchestration, UI/UX Pro Max, and Requirements Interview.",
5
5
  "type": "module",
6
6
  "main": "build/index.js",