mcp-probe-kit 1.1.1 → 1.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.
package/build/index.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
-
import { detectShell, initSetting, initProject, gencommit, debug, genapi, codeReview, gentest, genpr, checkDeps, gendoc, genchangelog, refactor, perf, fix, gensql, resolveConflict, genui, explain, convert, genreadme, split } from "./tools/index.js";
|
|
5
|
+
import { detectShell, initSetting, initProject, gencommit, debug, genapi, codeReview, gentest, genpr, checkDeps, gendoc, genchangelog, refactor, perf, fix, gensql, resolveConflict, genui, explain, convert, genreadme, split, analyzeProject } from "./tools/index.js";
|
|
6
6
|
// 创建MCP服务器实例
|
|
7
7
|
const server = new Server({
|
|
8
8
|
name: "mcp-probe-kit",
|
|
9
|
-
version: "1.
|
|
9
|
+
version: "1.2.0",
|
|
10
10
|
}, {
|
|
11
11
|
capabilities: {
|
|
12
12
|
tools: {},
|
|
@@ -408,6 +408,28 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
408
408
|
required: [],
|
|
409
409
|
},
|
|
410
410
|
},
|
|
411
|
+
{
|
|
412
|
+
name: "analyze_project",
|
|
413
|
+
description: "【项目分析】深度分析项目结构、代码质量和架构,帮助AI快速理解老项目",
|
|
414
|
+
inputSchema: {
|
|
415
|
+
type: "object",
|
|
416
|
+
properties: {
|
|
417
|
+
project_path: {
|
|
418
|
+
type: "string",
|
|
419
|
+
description: "项目路径(默认当前目录)",
|
|
420
|
+
},
|
|
421
|
+
max_depth: {
|
|
422
|
+
type: "number",
|
|
423
|
+
description: "目录树最大深度(默认 3)",
|
|
424
|
+
},
|
|
425
|
+
include_content: {
|
|
426
|
+
type: "boolean",
|
|
427
|
+
description: "是否包含文件内容(默认 true)",
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
required: [],
|
|
431
|
+
},
|
|
432
|
+
},
|
|
411
433
|
],
|
|
412
434
|
};
|
|
413
435
|
});
|
|
@@ -460,6 +482,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
460
482
|
return await genreadme(args);
|
|
461
483
|
case "split":
|
|
462
484
|
return await split(args);
|
|
485
|
+
case "analyze_project":
|
|
486
|
+
return await analyzeProject(args);
|
|
463
487
|
default:
|
|
464
488
|
throw new Error(`未知工具: ${name}`);
|
|
465
489
|
}
|
|
@@ -530,6 +554,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
530
554
|
convert: "enabled",
|
|
531
555
|
genreadme: "enabled",
|
|
532
556
|
split: "enabled",
|
|
557
|
+
analyze_project: "enabled",
|
|
533
558
|
},
|
|
534
559
|
}, null, 2),
|
|
535
560
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function analyzeProject(args: any): Promise<any>;
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
2
|
+
import { join, extname } from 'path';
|
|
3
|
+
export async function analyzeProject(args) {
|
|
4
|
+
const projectPath = args.project_path || process.cwd();
|
|
5
|
+
const maxDepth = args.max_depth || 3;
|
|
6
|
+
const includeContent = args.include_content !== false;
|
|
7
|
+
try {
|
|
8
|
+
const analysis = await performProjectAnalysis(projectPath, maxDepth, includeContent);
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: `# 📊 项目分析报告
|
|
14
|
+
|
|
15
|
+
## 🏗️ 项目概览
|
|
16
|
+
- **项目名称**: ${analysis.projectStructure.name}
|
|
17
|
+
- **项目类型**: ${analysis.projectStructure.type}
|
|
18
|
+
- **技术栈**: ${analysis.projectStructure.framework}
|
|
19
|
+
- **主要语言**: ${analysis.projectStructure.language}
|
|
20
|
+
- **包管理器**: ${analysis.projectStructure.packageManager}
|
|
21
|
+
|
|
22
|
+
## 📁 目录结构
|
|
23
|
+
\`\`\`
|
|
24
|
+
${analysis.directoryTree}
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
## 🔑 关键文件
|
|
28
|
+
${analysis.keyFiles.map(file => `### ${file.path}
|
|
29
|
+
**用途**: ${file.purpose}
|
|
30
|
+
${includeContent ? `\`\`\`${getFileExtension(file.path)}
|
|
31
|
+
${file.content.substring(0, 500)}${file.content.length > 500 ? '\n...' : ''}
|
|
32
|
+
\`\`\`` : ''}`).join('\n\n')}
|
|
33
|
+
|
|
34
|
+
## 📦 依赖分析
|
|
35
|
+
- **生产依赖**: ${analysis.dependencies.production.length} 个
|
|
36
|
+
- **开发依赖**: ${analysis.dependencies.development.length} 个
|
|
37
|
+
- **总依赖数**: ${analysis.dependencies.total} 个
|
|
38
|
+
|
|
39
|
+
### 主要依赖
|
|
40
|
+
${analysis.dependencies.production.slice(0, 10).map(dep => `- ${dep}`).join('\n')}
|
|
41
|
+
|
|
42
|
+
## 📈 代码指标
|
|
43
|
+
- **总文件数**: ${analysis.codeMetrics.totalFiles}
|
|
44
|
+
- **总行数**: ${analysis.codeMetrics.totalLines}
|
|
45
|
+
- **文件类型分布**:
|
|
46
|
+
${Object.entries(analysis.codeMetrics.fileTypes).map(([type, count]) => ` - ${type}: ${count} 个文件`).join('\n')}
|
|
47
|
+
|
|
48
|
+
### 最大文件
|
|
49
|
+
${analysis.codeMetrics.largestFiles.slice(0, 5).map(file => `- ${file.path} (${file.lines} 行)`).join('\n')}
|
|
50
|
+
|
|
51
|
+
## 🏛️ 架构分析
|
|
52
|
+
- **设计模式**: ${analysis.architecture.patterns.join(', ')}
|
|
53
|
+
- **入口文件**: ${analysis.architecture.entryPoints.join(', ')}
|
|
54
|
+
- **核心模块**: ${analysis.architecture.mainModules.join(', ')}
|
|
55
|
+
|
|
56
|
+
## 📋 项目总结
|
|
57
|
+
**项目目的**: ${analysis.summary.purpose}
|
|
58
|
+
**复杂度**: ${analysis.summary.complexity}
|
|
59
|
+
**建议**:
|
|
60
|
+
${analysis.summary.recommendations.map(rec => `- ${rec}`).join('\n')}
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
*分析完成时间: ${new Date().toLocaleString('zh-CN')}*
|
|
64
|
+
*分析工具: MCP Probe Kit v1.2.0*`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: `❌ 项目分析失败: ${error instanceof Error ? error.message : String(error)}`,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
isError: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function performProjectAnalysis(projectPath, maxDepth, includeContent) {
|
|
82
|
+
// 读取 package.json
|
|
83
|
+
const packageJson = await readPackageJson(projectPath);
|
|
84
|
+
// 分析项目结构
|
|
85
|
+
const projectStructure = analyzeProjectStructure(packageJson);
|
|
86
|
+
// 生成目录树
|
|
87
|
+
const directoryTree = generateDirectoryTree(projectPath, maxDepth);
|
|
88
|
+
// 识别关键文件
|
|
89
|
+
const keyFiles = await identifyKeyFiles(projectPath, includeContent);
|
|
90
|
+
// 分析依赖
|
|
91
|
+
const dependencies = analyzeDependencies(packageJson);
|
|
92
|
+
// 代码指标
|
|
93
|
+
const codeMetrics = await calculateCodeMetrics(projectPath);
|
|
94
|
+
// 架构分析
|
|
95
|
+
const architecture = await analyzeArchitecture(projectPath, keyFiles);
|
|
96
|
+
// 生成总结
|
|
97
|
+
const summary = generateSummary(projectStructure, codeMetrics, architecture);
|
|
98
|
+
return {
|
|
99
|
+
projectStructure,
|
|
100
|
+
directoryTree,
|
|
101
|
+
keyFiles,
|
|
102
|
+
dependencies,
|
|
103
|
+
codeMetrics,
|
|
104
|
+
architecture,
|
|
105
|
+
summary,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async function readPackageJson(projectPath) {
|
|
109
|
+
try {
|
|
110
|
+
const packageJsonPath = join(projectPath, 'package.json');
|
|
111
|
+
const content = readFileSync(packageJsonPath, 'utf-8');
|
|
112
|
+
return JSON.parse(content);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return {};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function analyzeProjectStructure(packageJson) {
|
|
119
|
+
const name = packageJson.name || 'unknown';
|
|
120
|
+
const type = detectProjectType(packageJson);
|
|
121
|
+
const framework = detectFramework(packageJson);
|
|
122
|
+
const language = detectLanguage(packageJson);
|
|
123
|
+
const packageManager = detectPackageManager();
|
|
124
|
+
return { name, type, framework, language, packageManager };
|
|
125
|
+
}
|
|
126
|
+
function detectProjectType(packageJson) {
|
|
127
|
+
if (packageJson.dependencies?.react)
|
|
128
|
+
return 'React 应用';
|
|
129
|
+
if (packageJson.dependencies?.vue)
|
|
130
|
+
return 'Vue 应用';
|
|
131
|
+
if (packageJson.dependencies?.angular)
|
|
132
|
+
return 'Angular 应用';
|
|
133
|
+
if (packageJson.dependencies?.express)
|
|
134
|
+
return 'Node.js 后端';
|
|
135
|
+
if (packageJson.dependencies?.next)
|
|
136
|
+
return 'Next.js 应用';
|
|
137
|
+
if (packageJson.dependencies?.nuxt)
|
|
138
|
+
return 'Nuxt.js 应用';
|
|
139
|
+
if (packageJson.dependencies?.svelte)
|
|
140
|
+
return 'Svelte 应用';
|
|
141
|
+
if (packageJson.dependencies?.electron)
|
|
142
|
+
return 'Electron 应用';
|
|
143
|
+
if (packageJson.dependencies?.jest || packageJson.devDependencies?.jest)
|
|
144
|
+
return '测试项目';
|
|
145
|
+
if (packageJson.dependencies?.webpack || packageJson.devDependencies?.webpack)
|
|
146
|
+
return '构建工具';
|
|
147
|
+
return '通用项目';
|
|
148
|
+
}
|
|
149
|
+
function detectFramework(packageJson) {
|
|
150
|
+
const frameworks = [];
|
|
151
|
+
if (packageJson.dependencies?.react)
|
|
152
|
+
frameworks.push('React');
|
|
153
|
+
if (packageJson.dependencies?.vue)
|
|
154
|
+
frameworks.push('Vue');
|
|
155
|
+
if (packageJson.dependencies?.angular)
|
|
156
|
+
frameworks.push('Angular');
|
|
157
|
+
if (packageJson.dependencies?.express)
|
|
158
|
+
frameworks.push('Express');
|
|
159
|
+
if (packageJson.dependencies?.next)
|
|
160
|
+
frameworks.push('Next.js');
|
|
161
|
+
if (packageJson.dependencies?.nuxt)
|
|
162
|
+
frameworks.push('Nuxt.js');
|
|
163
|
+
if (packageJson.dependencies?.svelte)
|
|
164
|
+
frameworks.push('Svelte');
|
|
165
|
+
if (packageJson.dependencies?.electron)
|
|
166
|
+
frameworks.push('Electron');
|
|
167
|
+
return frameworks.join(', ') || '无框架';
|
|
168
|
+
}
|
|
169
|
+
function detectLanguage(packageJson) {
|
|
170
|
+
if (packageJson.devDependencies?.typescript)
|
|
171
|
+
return 'TypeScript';
|
|
172
|
+
if (packageJson.dependencies?.typescript)
|
|
173
|
+
return 'TypeScript';
|
|
174
|
+
return 'JavaScript';
|
|
175
|
+
}
|
|
176
|
+
function detectPackageManager() {
|
|
177
|
+
if (require('fs').existsSync('yarn.lock'))
|
|
178
|
+
return 'Yarn';
|
|
179
|
+
if (require('fs').existsSync('pnpm-lock.yaml'))
|
|
180
|
+
return 'pnpm';
|
|
181
|
+
return 'npm';
|
|
182
|
+
}
|
|
183
|
+
function generateDirectoryTree(projectPath, maxDepth) {
|
|
184
|
+
const ignoreDirs = ['node_modules', '.git', 'dist', 'build', '.next', '.nuxt'];
|
|
185
|
+
function buildTree(dir, prefix = '', depth = 0) {
|
|
186
|
+
if (depth >= maxDepth)
|
|
187
|
+
return '';
|
|
188
|
+
try {
|
|
189
|
+
const items = readdirSync(dir)
|
|
190
|
+
.filter(item => !ignoreDirs.includes(item) && !item.startsWith('.'))
|
|
191
|
+
.map(item => {
|
|
192
|
+
const fullPath = join(dir, item);
|
|
193
|
+
const stat = statSync(fullPath);
|
|
194
|
+
return { name: item, isDir: stat.isDirectory(), path: fullPath };
|
|
195
|
+
})
|
|
196
|
+
.sort((a, b) => {
|
|
197
|
+
if (a.isDir && !b.isDir)
|
|
198
|
+
return -1;
|
|
199
|
+
if (!a.isDir && b.isDir)
|
|
200
|
+
return 1;
|
|
201
|
+
return a.name.localeCompare(b.name);
|
|
202
|
+
});
|
|
203
|
+
let result = '';
|
|
204
|
+
items.forEach((item, index) => {
|
|
205
|
+
const isLast = index === items.length - 1;
|
|
206
|
+
const currentPrefix = isLast ? '└── ' : '├── ';
|
|
207
|
+
const nextPrefix = isLast ? ' ' : '│ ';
|
|
208
|
+
result += `${prefix}${currentPrefix}${item.name}\n`;
|
|
209
|
+
if (item.isDir) {
|
|
210
|
+
result += buildTree(item.path, prefix + nextPrefix, depth + 1);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return '';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return buildTree(projectPath);
|
|
220
|
+
}
|
|
221
|
+
async function identifyKeyFiles(projectPath, includeContent) {
|
|
222
|
+
const keyFilePatterns = [
|
|
223
|
+
'package.json', 'README.md', 'index.js', 'index.ts', 'main.js', 'main.ts',
|
|
224
|
+
'app.js', 'app.ts', 'server.js', 'server.ts', 'config.js', 'config.ts',
|
|
225
|
+
'webpack.config.js', 'vite.config.js', 'next.config.js', 'nuxt.config.js',
|
|
226
|
+
'tsconfig.json', 'babel.config.js', '.env', '.env.example'
|
|
227
|
+
];
|
|
228
|
+
const keyFiles = [];
|
|
229
|
+
for (const pattern of keyFilePatterns) {
|
|
230
|
+
try {
|
|
231
|
+
const filePath = join(projectPath, pattern);
|
|
232
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
233
|
+
const purpose = getFilePurpose(pattern, content);
|
|
234
|
+
keyFiles.push({
|
|
235
|
+
path: pattern,
|
|
236
|
+
purpose,
|
|
237
|
+
content: includeContent ? content : ''
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
// 文件不存在,跳过
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return keyFiles;
|
|
245
|
+
}
|
|
246
|
+
function getFilePurpose(filename, content) {
|
|
247
|
+
const purposes = {
|
|
248
|
+
'package.json': '项目配置和依赖管理',
|
|
249
|
+
'README.md': '项目说明文档',
|
|
250
|
+
'index.js': '项目入口文件',
|
|
251
|
+
'index.ts': 'TypeScript 项目入口文件',
|
|
252
|
+
'main.js': '主程序文件',
|
|
253
|
+
'main.ts': 'TypeScript 主程序文件',
|
|
254
|
+
'app.js': '应用程序主文件',
|
|
255
|
+
'app.ts': 'TypeScript 应用程序主文件',
|
|
256
|
+
'server.js': '服务器文件',
|
|
257
|
+
'server.ts': 'TypeScript 服务器文件',
|
|
258
|
+
'config.js': '配置文件',
|
|
259
|
+
'config.ts': 'TypeScript 配置文件',
|
|
260
|
+
'webpack.config.js': 'Webpack 构建配置',
|
|
261
|
+
'vite.config.js': 'Vite 构建配置',
|
|
262
|
+
'next.config.js': 'Next.js 配置',
|
|
263
|
+
'nuxt.config.js': 'Nuxt.js 配置',
|
|
264
|
+
'tsconfig.json': 'TypeScript 配置',
|
|
265
|
+
'babel.config.js': 'Babel 配置',
|
|
266
|
+
'.env': '环境变量配置',
|
|
267
|
+
'.env.example': '环境变量示例'
|
|
268
|
+
};
|
|
269
|
+
return purposes[filename] || '配置文件';
|
|
270
|
+
}
|
|
271
|
+
function analyzeDependencies(packageJson) {
|
|
272
|
+
const production = Object.keys(packageJson.dependencies || {});
|
|
273
|
+
const development = Object.keys(packageJson.devDependencies || {});
|
|
274
|
+
return {
|
|
275
|
+
production,
|
|
276
|
+
development,
|
|
277
|
+
total: production.length + development.length
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
async function calculateCodeMetrics(projectPath) {
|
|
281
|
+
const fileTypes = {};
|
|
282
|
+
const largestFiles = [];
|
|
283
|
+
let totalFiles = 0;
|
|
284
|
+
let totalLines = 0;
|
|
285
|
+
function scanDirectory(dir) {
|
|
286
|
+
try {
|
|
287
|
+
const items = readdirSync(dir);
|
|
288
|
+
for (const item of items) {
|
|
289
|
+
const fullPath = join(dir, item);
|
|
290
|
+
const stat = statSync(fullPath);
|
|
291
|
+
if (stat.isDirectory()) {
|
|
292
|
+
if (!['node_modules', '.git', 'dist', 'build'].includes(item)) {
|
|
293
|
+
scanDirectory(fullPath);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
const ext = extname(item);
|
|
298
|
+
const fileType = ext || 'no-extension';
|
|
299
|
+
fileTypes[fileType] = (fileTypes[fileType] || 0) + 1;
|
|
300
|
+
totalFiles++;
|
|
301
|
+
try {
|
|
302
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
303
|
+
const lines = content.split('\n').length;
|
|
304
|
+
totalLines += lines;
|
|
305
|
+
largestFiles.push({ path: fullPath, lines });
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// 忽略无法读取的文件
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// 忽略无法访问的目录
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
scanDirectory(projectPath);
|
|
318
|
+
// 按行数排序,取前10个
|
|
319
|
+
largestFiles.sort((a, b) => b.lines - a.lines);
|
|
320
|
+
return {
|
|
321
|
+
totalFiles,
|
|
322
|
+
totalLines,
|
|
323
|
+
fileTypes,
|
|
324
|
+
largestFiles: largestFiles.slice(0, 10)
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
async function analyzeArchitecture(projectPath, keyFiles) {
|
|
328
|
+
const patterns = [];
|
|
329
|
+
const entryPoints = [];
|
|
330
|
+
const mainModules = [];
|
|
331
|
+
// 分析入口文件
|
|
332
|
+
keyFiles.forEach(file => {
|
|
333
|
+
if (file.path.includes('index') || file.path.includes('main') || file.path.includes('app')) {
|
|
334
|
+
entryPoints.push(file.path);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
// 检测设计模式
|
|
338
|
+
if (keyFiles.some(f => f.path.includes('component')))
|
|
339
|
+
patterns.push('组件化');
|
|
340
|
+
if (keyFiles.some(f => f.path.includes('service')))
|
|
341
|
+
patterns.push('服务层');
|
|
342
|
+
if (keyFiles.some(f => f.path.includes('controller')))
|
|
343
|
+
patterns.push('MVC');
|
|
344
|
+
if (keyFiles.some(f => f.path.includes('middleware')))
|
|
345
|
+
patterns.push('中间件');
|
|
346
|
+
if (keyFiles.some(f => f.path.includes('hook')))
|
|
347
|
+
patterns.push('Hooks');
|
|
348
|
+
if (keyFiles.some(f => f.path.includes('store')))
|
|
349
|
+
patterns.push('状态管理');
|
|
350
|
+
// 识别核心模块
|
|
351
|
+
const srcDir = join(projectPath, 'src');
|
|
352
|
+
try {
|
|
353
|
+
const srcItems = readdirSync(srcDir);
|
|
354
|
+
mainModules.push(...srcItems.filter(item => statSync(join(srcDir, item)).isDirectory()));
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
// src 目录不存在
|
|
358
|
+
}
|
|
359
|
+
return { patterns, entryPoints, mainModules };
|
|
360
|
+
}
|
|
361
|
+
function generateSummary(projectStructure, codeMetrics, architecture) {
|
|
362
|
+
let complexity = 'low';
|
|
363
|
+
if (codeMetrics.totalFiles > 100 || codeMetrics.totalLines > 10000) {
|
|
364
|
+
complexity = 'high';
|
|
365
|
+
}
|
|
366
|
+
else if (codeMetrics.totalFiles > 20 || codeMetrics.totalLines > 1000) {
|
|
367
|
+
complexity = 'medium';
|
|
368
|
+
}
|
|
369
|
+
const purpose = `${projectStructure.type},使用 ${projectStructure.framework} 框架,主要语言为 ${projectStructure.language}`;
|
|
370
|
+
const recommendations = [];
|
|
371
|
+
if (codeMetrics.totalFiles > 50) {
|
|
372
|
+
recommendations.push('考虑模块化重构,减少文件数量');
|
|
373
|
+
}
|
|
374
|
+
if (codeMetrics.largestFiles[0]?.lines > 500) {
|
|
375
|
+
recommendations.push('拆分大文件,提高代码可维护性');
|
|
376
|
+
}
|
|
377
|
+
if (architecture.patterns.length === 0) {
|
|
378
|
+
recommendations.push('引入设计模式,提高代码组织性');
|
|
379
|
+
}
|
|
380
|
+
if (!architecture.entryPoints.length) {
|
|
381
|
+
recommendations.push('明确项目入口文件');
|
|
382
|
+
}
|
|
383
|
+
return { purpose, complexity, recommendations };
|
|
384
|
+
}
|
|
385
|
+
function getFileExtension(filename) {
|
|
386
|
+
const ext = extname(filename).slice(1);
|
|
387
|
+
const extMap = {
|
|
388
|
+
'js': 'javascript',
|
|
389
|
+
'ts': 'typescript',
|
|
390
|
+
'jsx': 'jsx',
|
|
391
|
+
'tsx': 'tsx',
|
|
392
|
+
'vue': 'vue',
|
|
393
|
+
'py': 'python',
|
|
394
|
+
'java': 'java',
|
|
395
|
+
'cpp': 'cpp',
|
|
396
|
+
'c': 'c',
|
|
397
|
+
'cs': 'csharp',
|
|
398
|
+
'php': 'php',
|
|
399
|
+
'rb': 'ruby',
|
|
400
|
+
'go': 'go',
|
|
401
|
+
'rs': 'rust',
|
|
402
|
+
'swift': 'swift',
|
|
403
|
+
'kt': 'kotlin',
|
|
404
|
+
'scala': 'scala',
|
|
405
|
+
'html': 'html',
|
|
406
|
+
'css': 'css',
|
|
407
|
+
'scss': 'scss',
|
|
408
|
+
'sass': 'sass',
|
|
409
|
+
'less': 'less',
|
|
410
|
+
'json': 'json',
|
|
411
|
+
'xml': 'xml',
|
|
412
|
+
'yaml': 'yaml',
|
|
413
|
+
'yml': 'yaml',
|
|
414
|
+
'md': 'markdown',
|
|
415
|
+
'txt': 'text',
|
|
416
|
+
'sql': 'sql',
|
|
417
|
+
'sh': 'bash',
|
|
418
|
+
'bat': 'batch',
|
|
419
|
+
'ps1': 'powershell'
|
|
420
|
+
};
|
|
421
|
+
return extMap[ext] || ext || 'text';
|
|
422
|
+
}
|
package/build/tools/index.d.ts
CHANGED
package/build/tools/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-probe-kit",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Cursor Development Enhancement Toolkit - MCP Server with
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Cursor Development Enhancement Toolkit - MCP Server with 23 practical tools for code quality, development efficiency, and project management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"bin": {
|