Files
bigwo/dev-assistant-mcp/dist/tools/codeReview.js

159 lines
7.0 KiB
JavaScript
Raw Normal View History

2026-03-12 12:47:56 +08:00
export const codeReviewTool = {
name: "code_review",
description: "审查代码质量。根据审查重点返回结构化的检查清单和分析结果,涵盖 bug、安全、性能、风格等维度。",
inputSchema: {
type: "object",
properties: {
code: {
type: "string",
description: "要审查的代码",
},
language: {
type: "string",
description: "编程语言(如 typescript, python, java 等)",
},
focus: {
type: "string",
description: "审查重点可选security=安全性, performance=性能, style=代码风格, all=全面审查",
enum: ["security", "performance", "style", "all"],
},
},
required: ["code", "language"],
},
};
const reviewChecklists = {
security: [
"检查是否存在 SQL 注入、XSS、CSRF 等注入攻击风险",
"检查是否硬编码了密钥、密码、Token 等敏感信息",
"检查用户输入是否经过验证和清洗",
"检查权限控制是否完善,是否有越权风险",
"检查是否使用了不安全的加密算法或随机数生成",
"检查第三方依赖是否有已知安全漏洞",
],
performance: [
"检查是否存在不必要的循环嵌套或 O(n²) 以上复杂度",
"检查是否有内存泄漏(未清理的定时器、事件监听、闭包)",
"检查是否有不必要的重复计算,是否需要缓存/记忆化",
"检查异步操作是否可以并行化Promise.all",
"检查是否有阻塞主线程的同步操作",
"检查数据库查询是否有 N+1 问题",
],
style: [
"检查命名是否清晰表达意图(变量、函数、类)",
"检查函数长度是否超过 50 行,是否需要拆分",
"检查嵌套层级是否过深(>3 层),是否可用 guard clause",
"检查是否有重复代码DRY 原则)",
"检查注释是否准确且必要,而非冗余",
"检查是否遵循语言社区的标准代码风格",
],
};
export async function executeCodeReview(args) {
const { code, language, focus = "all" } = args;
const lines = code.split("\n");
const lineCount = lines.length;
// 基础代码统计
const stats = {
totalLines: lineCount,
blankLines: lines.filter((l) => l.trim() === "").length,
commentLines: lines.filter((l) => {
const t = l.trim();
return t.startsWith("//") || t.startsWith("#") || t.startsWith("/*") || t.startsWith("*");
}).length,
codeLines: 0,
maxLineLength: Math.max(...lines.map((l) => l.length)),
maxNestingDepth: 0,
};
stats.codeLines = stats.totalLines - stats.blankLines - stats.commentLines;
// 计算最大嵌套深度
let depth = 0;
for (const line of lines) {
const opens = (line.match(/{/g) || []).length;
const closes = (line.match(/}/g) || []).length;
depth += opens - closes;
if (depth > stats.maxNestingDepth)
stats.maxNestingDepth = depth;
}
// 检测潜在问题
const issues = [];
// 通用检查
if (stats.maxLineLength > 120)
issues.push(`⚠️ 存在超长行(最长 ${stats.maxLineLength} 字符),建议不超过 120`);
if (stats.maxNestingDepth > 4)
issues.push(`⚠️ 嵌套层级过深(${stats.maxNestingDepth} 层),建议重构`);
if (stats.codeLines > 300)
issues.push(`⚠️ 文件过长(${stats.codeLines} 行代码),建议拆分`);
if (stats.commentLines === 0 && stats.codeLines > 30)
issues.push("🔵 缺少注释,建议为关键逻辑添加说明");
// 安全检查
if (focus === "security" || focus === "all") {
if (/eval\s*\(/.test(code))
issues.push("🔴 使用了 eval(),存在代码注入风险");
if (/innerHTML\s*=/.test(code))
issues.push("🔴 使用了 innerHTML存在 XSS 风险");
if (/(password|secret|api_?key|token)\s*=\s*["'][^"']+["']/i.test(code))
issues.push("🔴 可能硬编码了敏感信息");
if (/\bhttp:\/\//.test(code))
issues.push("🟡 使用了 HTTP 而非 HTTPS");
if (/exec\s*\(|spawn\s*\(/.test(code) && !/sanitize|escape|validate/.test(code))
issues.push("🟡 执行了外部命令,确认输入已清洗");
}
// 性能检查
if (focus === "performance" || focus === "all") {
if (/for\s*\(.*for\s*\(/s.test(code))
issues.push("🟡 存在嵌套循环,注意时间复杂度");
if (/setTimeout|setInterval/.test(code) && !/clearTimeout|clearInterval/.test(code))
issues.push("<22> 设置了定时器但未见清理,可能内存泄漏");
if (/\.forEach\(.*await/.test(code))
issues.push("🟡 在 forEach 中使用 await不会等待完成建议用 for...of");
if (/new RegExp\(/.test(code) && /for|while|map|forEach/.test(code))
issues.push("🔵 循环中创建正则表达式,建议提取到循环外");
}
// 风格检查
if (focus === "style" || focus === "all") {
if (/var\s+/.test(code) && (language === "typescript" || language === "javascript"))
issues.push("🔵 使用了 var建议改用 const/let");
if (/console\.log/.test(code))
issues.push("🔵 包含 console.log确认是否需要在生产环境移除");
if (/any/.test(code) && language === "typescript")
issues.push("🔵 使用了 any 类型,建议使用具体类型");
if (/TODO|FIXME|HACK|XXX/.test(code))
issues.push("🔵 存在 TODO/FIXME 标记,建议处理");
}
// 获取对应的检查清单
let checklist;
if (focus === "all") {
checklist = [
...reviewChecklists.security,
...reviewChecklists.performance,
...reviewChecklists.style,
];
}
else {
checklist = reviewChecklists[focus] || reviewChecklists.style;
}
// 组装结果
const output = [
`# 代码审查报告`,
``,
`**语言**: ${language} | **审查重点**: ${focus}`,
``,
`## 代码统计`,
`- 总行数: ${stats.totalLines}(代码 ${stats.codeLines} / 注释 ${stats.commentLines} / 空行 ${stats.blankLines}`,
`- 最长行: ${stats.maxLineLength} 字符`,
`- 最大嵌套深度: ${stats.maxNestingDepth}`,
``,
`## 自动检测到的问题(${issues.length} 项)`,
issues.length > 0 ? issues.map((i) => `- ${i}`).join("\n") : "- ✅ 未检测到明显问题",
``,
`## 人工审查清单`,
`请逐项检查以下内容:`,
...checklist.map((item, idx) => `${idx + 1}. ${item}`),
``,
`## 待审查代码`,
"```" + language,
code,
"```",
];
return output.join("\n");
}
//# sourceMappingURL=codeReview.js.map