mr-sliy 1.0.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.
Files changed (50) hide show
  1. package/.env.example +145 -0
  2. package/database/schema.sql +187 -0
  3. package/package.json +74 -0
  4. package/scripts/download-tree-sitter.js +171 -0
  5. package/scripts/postinstall.js +134 -0
  6. package/src/agent/agent.js +563 -0
  7. package/src/agent.js +87 -0
  8. package/src/cli/index.js +1643 -0
  9. package/src/config/index.js +232 -0
  10. package/src/engine/dualModeEngine.js +486 -0
  11. package/src/index.js +165 -0
  12. package/src/middlewares/errorHandler.js +166 -0
  13. package/src/middlewares/index.js +23 -0
  14. package/src/routes/aiRoutes.js +117 -0
  15. package/src/routes/configRoutes.js +31 -0
  16. package/src/routes/index.js +75 -0
  17. package/src/routes/issueRoutes.js +195 -0
  18. package/src/routes/projectRoutes.js +46 -0
  19. package/src/routes/reportRoutes.js +40 -0
  20. package/src/routes/scanRoutes.js +245 -0
  21. package/src/routes/userRoutes.js +47 -0
  22. package/src/services/ast/parser.js +503 -0
  23. package/src/services/detection/detector.js +934 -0
  24. package/src/services/llm/providers.js +1107 -0
  25. package/src/services/rag/agent.js +375 -0
  26. package/src/services/vector/knowledgeBase.js +863 -0
  27. package/src/skills/Skill.js +38 -0
  28. package/src/skills/code-analysis/index.js +272 -0
  29. package/src/skills/code-detection/index.js +166 -0
  30. package/src/skills/code-detection/rules/console-log.js +45 -0
  31. package/src/skills/code-detection/rules/deep-nesting.js +76 -0
  32. package/src/skills/code-detection/rules/duplicate-code.js +57 -0
  33. package/src/skills/code-detection/rules/high-complexity.js +109 -0
  34. package/src/skills/code-detection/rules/index.js +59 -0
  35. package/src/skills/code-detection/rules/long-functions.js +54 -0
  36. package/src/skills/code-detection/rules/magic-numbers.js +48 -0
  37. package/src/skills/code-detection/rules/missing-comment.js +64 -0
  38. package/src/skills/code-detection/rules/null-check.js +71 -0
  39. package/src/skills/code-detection/rules/unnecessary-else.js +46 -0
  40. package/src/skills/code-detection/rules/unused-functions.js +57 -0
  41. package/src/skills/code-detection/rules/unused-imports.js +57 -0
  42. package/src/skills/code-detection/rules/unused-variables.js +54 -0
  43. package/src/skills/code-optimization/index.js +319 -0
  44. package/src/skills/index.js +152 -0
  45. package/src/utils/crypto.js +212 -0
  46. package/src/utils/database.js +125 -0
  47. package/src/utils/helpers.js +226 -0
  48. package/src/utils/logger.js +202 -0
  49. package/src/utils/mysql.js +198 -0
  50. package/src/utils/response.js +124 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * RAG代码优化Agent服务
3
+ * 基于检索增强生成技术的代码智能优化
4
+ */
5
+
6
+ const { config, isOnlineMode } = require('../../config');
7
+ const { logger } = require('../../utils/logger');
8
+ const { generateUUID, retry } = require('../../utils/helpers');
9
+ const { getDatabase } = require('../../utils/database');
10
+
11
+ // 代码片段向量存储(简化版)
12
+ const codeVectorStore = new Map();
13
+
14
+ // 优化历史记录缓存
15
+ const optimizationHistory = [];
16
+
17
+ /**
18
+ * AI API客户端(模拟实现)
19
+ * 实际项目中应使用真实的AI API客户端
20
+ */
21
+ class AIClient {
22
+ constructor() {
23
+ this.apiUrl = config.ai.apiUrl;
24
+ this.apiKey = config.ai.apiKey;
25
+ this.model = config.ai.model;
26
+ this.timeout = config.ai.timeout;
27
+ }
28
+
29
+ /**
30
+ * 调用AI API进行代码优化
31
+ */
32
+ async optimizeCode(codeSnippet, context) {
33
+ if (!isOnlineMode()) {
34
+ return {
35
+ success: false,
36
+ message: '离线模式,无法使用AI优化功能'
37
+ };
38
+ }
39
+
40
+ try {
41
+ // 这里是模拟的AI调用,实际项目需要调用真实的API
42
+ // 例如:OpenAI, Claude, 或本地部署的LLM
43
+
44
+ const prompt = this.buildOptimizationPrompt(codeSnippet, context);
45
+
46
+ // 模拟AI响应(实际项目中应调用真实API)
47
+ const mockResponse = await this.mockAIResponse(prompt);
48
+
49
+ return {
50
+ success: true,
51
+ optimizedCode: mockResponse.optimizedCode,
52
+ explanation: mockResponse.explanation,
53
+ suggestions: mockResponse.suggestions,
54
+ tokensUsed: mockResponse.tokensUsed
55
+ };
56
+ } catch (error) {
57
+ logger.error('AI优化调用失败:', error);
58
+ return {
59
+ success: false,
60
+ message: error.message
61
+ };
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 构建优化提示词
67
+ */
68
+ buildOptimizationPrompt(codeSnippet, context) {
69
+ return `
70
+ 你是一个代码优化专家。请分析以下代码片段并提供优化建议。
71
+
72
+ 代码语言: ${context.language}
73
+ 代码类型: ${context.issueType}
74
+ 问题描述: ${context.message}
75
+
76
+ 原始代码:
77
+ \`\`\`${context.language}
78
+ ${codeSnippet}
79
+ \`\`\`
80
+
81
+ 请提供以下内容:
82
+ 1. 优化后的代码
83
+ 2. 优化说明(为什么这样优化)
84
+ 3. 最佳实践建议
85
+
86
+ 请以JSON格式返回:
87
+ {
88
+ "optimizedCode": "...",
89
+ "explanation": "...",
90
+ "suggestions": ["...", "..."]
91
+ }
92
+ `;
93
+ }
94
+
95
+ /**
96
+ * 模拟AI响应(用于演示)
97
+ */
98
+ async mockAIResponse(prompt) {
99
+ // 模拟API延迟
100
+ await new Promise(resolve => setTimeout(resolve, 500));
101
+
102
+ // 返回模拟的优化结果
103
+ return {
104
+ optimizedCode: '// 优化后的代码\nconst optimized = true;',
105
+ explanation: '这是一个模拟的优化建议,实际项目中应调用真实的AI API',
106
+ suggestions: [
107
+ '建议使用更清晰的变量名',
108
+ '考虑添加适当的注释',
109
+ '遵循代码规范和最佳实践'
110
+ ],
111
+ tokensUsed: 100
112
+ };
113
+ }
114
+ }
115
+
116
+ const aiClient = new AIClient();
117
+
118
+ /**
119
+ * 代码片段索引(简化版向量存储)
120
+ */
121
+ function indexCodeSnippet(snippet, metadata) {
122
+ const id = generateUUID();
123
+
124
+ // 简化的特征提取(实际应使用embedding模型)
125
+ const features = extractFeatures(snippet);
126
+
127
+ codeVectorStore.set(id, {
128
+ id,
129
+ snippet,
130
+ features,
131
+ metadata,
132
+ indexedAt: new Date()
133
+ });
134
+
135
+ logger.info(`索引代码片段: ${id}`);
136
+ return id;
137
+ }
138
+
139
+ /**
140
+ * 提取代码特征(简化版)
141
+ */
142
+ function extractFeatures(code) {
143
+ const features = {
144
+ length: code.length,
145
+ lines: code.split('\n').length,
146
+ keywords: extractKeywords(code),
147
+ complexity: calculateComplexity(code)
148
+ };
149
+
150
+ return features;
151
+ }
152
+
153
+ /**
154
+ * 提取关键词
155
+ */
156
+ function extractKeywords(code) {
157
+ const keywords = [];
158
+ const patterns = [
159
+ /\b(function|const|let|var|if|else|for|while|return|class|import|export)\b/g,
160
+ /\b(async|await|try|catch|throw|new|this)\b/g
161
+ ];
162
+
163
+ patterns.forEach(pattern => {
164
+ const matches = code.match(pattern);
165
+ if (matches) {
166
+ keywords.push(...matches);
167
+ }
168
+ });
169
+
170
+ return keywords;
171
+ }
172
+
173
+ /**
174
+ * 计算代码复杂度(简化版)
175
+ */
176
+ function calculateComplexity(code) {
177
+ let complexity = 1;
178
+
179
+ // 计算控制流语句
180
+ const controlPatterns = [
181
+ /\bif\b/g,
182
+ /\belse\b/g,
183
+ /\bfor\b/g,
184
+ /\bwhile\b/g,
185
+ /\bswitch\b/g,
186
+ /\bcatch\b/g
187
+ ];
188
+
189
+ controlPatterns.forEach(pattern => {
190
+ const matches = code.match(pattern);
191
+ if (matches) {
192
+ complexity += matches.length;
193
+ }
194
+ });
195
+
196
+ return complexity;
197
+ }
198
+
199
+ /**
200
+ * 检索相似代码片段
201
+ */
202
+ function retrieveSimilarSnippets(querySnippet, topK = 5) {
203
+ const queryFeatures = extractFeatures(querySnippet);
204
+ const results = [];
205
+
206
+ codeVectorStore.forEach((value, id) => {
207
+ const similarity = calculateSimilarity(queryFeatures, value.features);
208
+ results.push({
209
+ id,
210
+ snippet: value.snippet,
211
+ similarity,
212
+ metadata: value.metadata
213
+ });
214
+ });
215
+
216
+ // 按相似度排序
217
+ results.sort((a, b) => b.similarity - a.similarity);
218
+
219
+ return results.slice(0, topK);
220
+ }
221
+
222
+ /**
223
+ * 计算相似度(简化版)
224
+ */
225
+ function calculateSimilarity(features1, features2) {
226
+ let similarity = 0;
227
+
228
+ // 长度相似度
229
+ const lengthSim = 1 - Math.abs(features1.length - features2.length) / Math.max(features1.length, features2.length);
230
+ similarity += lengthSim * 0.3;
231
+
232
+ // 关键词相似度
233
+ const keywordIntersection = features1.keywords.filter(k => features2.keywords.includes(k));
234
+ const keywordSim = keywordIntersection.length / Math.max(features1.keywords.length, features2.keywords.length);
235
+ similarity += keywordSim * 0.4;
236
+
237
+ // 复杂度相似度
238
+ const complexitySim = 1 - Math.abs(features1.complexity - features2.complexity) / Math.max(features1.complexity, features2.complexity);
239
+ similarity += complexitySim * 0.3;
240
+
241
+ return similarity;
242
+ }
243
+
244
+ /**
245
+ * RAG优化流程
246
+ */
247
+ async function optimizeWithRAG(issue, context) {
248
+ const startTime = Date.now();
249
+
250
+ try {
251
+ // 1. 检索相似代码片段
252
+ const similarSnippets = retrieveSimilarSnippets(issue.codeSnippet, 3);
253
+
254
+ // 2. 构建增强上下文
255
+ const enhancedContext = {
256
+ ...context,
257
+ similarExamples: similarSnippets.map(s => ({
258
+ snippet: s.snippet,
259
+ similarity: s.similarity
260
+ }))
261
+ };
262
+
263
+ // 3. 调用AI进行优化
264
+ const aiResult = await retry(
265
+ () => aiClient.optimizeCode(issue.codeSnippet, enhancedContext),
266
+ 3,
267
+ 1000
268
+ );
269
+
270
+ if (!aiResult.success) {
271
+ return aiResult;
272
+ }
273
+
274
+ // 4. 记录优化历史
275
+ const optimizationRecord = {
276
+ id: generateUUID(),
277
+ issueId: issue.id,
278
+ taskId: context.taskId,
279
+ originalCode: issue.codeSnippet,
280
+ optimizedCode: aiResult.optimizedCode,
281
+ explanation: aiResult.explanation,
282
+ suggestions: aiResult.suggestions,
283
+ similarSnippetsCount: similarSnippets.length,
284
+ tokensUsed: aiResult.tokensUsed,
285
+ durationMs: Date.now() - startTime,
286
+ createdAt: new Date()
287
+ };
288
+
289
+ // 存储到数据库
290
+ saveOptimizationRecord(optimizationRecord);
291
+
292
+ // 索引优化后的代码
293
+ indexCodeSnippet(aiResult.optimizedCode, {
294
+ type: 'optimized',
295
+ issueType: context.issueType,
296
+ language: context.language
297
+ });
298
+
299
+ logger.info(`RAG优化完成: ${optimizationRecord.id}`);
300
+
301
+ return {
302
+ success: true,
303
+ optimizationId: optimizationRecord.id,
304
+ optimizedCode: aiResult.optimizedCode,
305
+ explanation: aiResult.explanation,
306
+ suggestions: aiResult.suggestions,
307
+ similarSnippets: similarSnippets,
308
+ tokensUsed: aiResult.tokensUsed,
309
+ durationMs: Date.now() - startTime
310
+ };
311
+ } catch (error) {
312
+ logger.error('RAG优化失败:', error);
313
+ return {
314
+ success: false,
315
+ message: error.message,
316
+ durationMs: Date.now() - startTime
317
+ };
318
+ }
319
+ }
320
+
321
+ /**
322
+ * 存储优化记录到数据库
323
+ */
324
+ function saveOptimizationRecord(record) {
325
+ try {
326
+ const db = getDatabase();
327
+ const stmt = db.prepare(`
328
+ INSERT INTO ai_optimize_record
329
+ (id, issue_id, task_id, original_code, optimized_code, explanation,
330
+ optimization_type, ai_model, tokens_used, api_latency_ms)
331
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
332
+ `);
333
+
334
+ stmt.run(
335
+ record.id,
336
+ record.issueId,
337
+ record.taskId,
338
+ record.originalCode,
339
+ record.optimizedCode,
340
+ record.explanation,
341
+ 'refactor',
342
+ config.ai.model,
343
+ record.tokensUsed,
344
+ record.durationMs
345
+ );
346
+
347
+ optimizationHistory.push(record);
348
+ } catch (error) {
349
+ logger.error('存储优化记录失败:', error);
350
+ }
351
+ }
352
+
353
+ /**
354
+ * 获取优化历史
355
+ */
356
+ function getOptimizationHistory(limit = 10) {
357
+ return optimizationHistory.slice(0, limit);
358
+ }
359
+
360
+ /**
361
+ * 清空向量存储
362
+ */
363
+ function clearVectorStore() {
364
+ codeVectorStore.clear();
365
+ logger.info('向量存储已清空');
366
+ }
367
+
368
+ module.exports = {
369
+ indexCodeSnippet,
370
+ retrieveSimilarSnippets,
371
+ optimizeWithRAG,
372
+ getOptimizationHistory,
373
+ clearVectorStore,
374
+ AIClient
375
+ };