Files
bigwo/dev-assistant-mcp/dist/tools/lintCheck.js
2026-03-12 12:47:56 +08:00

133 lines
5.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { exec } from "child_process";
import { promisify } from "util";
import { existsSync } from "fs";
import { join } from "path";
const execAsync = promisify(exec);
export const lintCheckTool = {
name: "lint_check",
description: "对项目执行代码检查。自动检测项目类型并运行对应的 lint 工具ESLint、TypeScript 编译检查、Pylint 等),返回结构化的错误列表。",
inputSchema: {
type: "object",
properties: {
project_path: {
type: "string",
description: "项目根目录(绝对路径)",
},
fix: {
type: "boolean",
description: "是否自动修复可修复的问题(默认 false",
},
files: {
type: "string",
description: "指定检查的文件或 glob可选默认检查整个项目",
},
},
required: ["project_path"],
},
};
async function runCommand(cmd, cwd, timeout = 30000) {
try {
const { stdout, stderr } = await execAsync(cmd, {
cwd,
timeout,
maxBuffer: 1024 * 1024 * 5,
shell: process.platform === "win32" ? "powershell.exe" : "/bin/bash",
});
return { stdout, stderr, code: 0 };
}
catch (error) {
return {
stdout: error.stdout || "",
stderr: error.stderr || "",
code: error.code ?? 1,
};
}
}
export async function executeLintCheck(args) {
const { project_path, fix = false, files } = args;
const results = [];
const hasFile = (name) => existsSync(join(project_path, name));
const hasNodeModules = hasFile("node_modules");
// TypeScript 编译检查
if (hasFile("tsconfig.json")) {
const result = await runCommand("npx tsc --noEmit --pretty", project_path);
const errorCount = (result.stdout.match(/error TS/g) || []).length;
results.push({
tool: "TypeScript (tsc --noEmit)",
success: result.code === 0,
errorCount,
warningCount: 0,
output: result.stdout || result.stderr || "(无输出)",
});
}
// ESLint
if (hasFile(".eslintrc.js") || hasFile(".eslintrc.json") || hasFile(".eslintrc.yml") || hasFile("eslint.config.js") || hasFile("eslint.config.mjs")) {
const target = files || "src/";
const fixFlag = fix ? " --fix" : "";
const result = await runCommand(`npx eslint ${target}${fixFlag} --format stylish`, project_path);
const errorMatch = result.stdout.match(/(\d+) errors?/);
const warnMatch = result.stdout.match(/(\d+) warnings?/);
results.push({
tool: `ESLint${fix ? " (--fix)" : ""}`,
success: result.code === 0,
errorCount: errorMatch ? parseInt(errorMatch[1]) : 0,
warningCount: warnMatch ? parseInt(warnMatch[1]) : 0,
output: result.stdout || result.stderr || "✅ 无问题",
});
}
// Python: pylint / flake8
if (hasFile("requirements.txt") || hasFile("setup.py") || hasFile("pyproject.toml")) {
const target = files || ".";
// 优先 flake8
const result = await runCommand(`python -m flake8 ${target} --max-line-length=120 --count`, project_path);
if (result.code !== 127) { // 127 = command not found
const lines = result.stdout.trim().split("\n").filter(Boolean);
results.push({
tool: "Flake8",
success: result.code === 0,
errorCount: lines.length,
warningCount: 0,
output: result.stdout || result.stderr || "✅ 无问题",
});
}
}
// 如果什么检查工具都没找到
if (results.length === 0) {
// 尝试通用的 package.json lint 脚本
if (hasFile("package.json")) {
const result = await runCommand("npm run lint 2>&1 || echo LINT_SCRIPT_NOT_FOUND", project_path);
if (!result.stdout.includes("LINT_SCRIPT_NOT_FOUND") && !result.stdout.includes("Missing script")) {
results.push({
tool: "npm run lint",
success: result.code === 0,
errorCount: result.code === 0 ? 0 : 1,
warningCount: 0,
output: result.stdout || result.stderr,
});
}
}
}
if (results.length === 0) {
return `# Lint 检查结果\n\n⚠️ 未检测到 lint 工具配置ESLint、tsconfig、pylint 等)\n项目路径: ${project_path}\n\n建议:\n- TypeScript 项目:添加 tsconfig.json\n- JS 项目npm init @eslint/config\n- Python 项目pip install flake8`;
}
// 组装报告
const totalErrors = results.reduce((sum, r) => sum + r.errorCount, 0);
const totalWarnings = results.reduce((sum, r) => sum + r.warningCount, 0);
const allPassed = results.every((r) => r.success);
const output = [
`# Lint 检查报告`,
``,
`📂 项目: ${project_path}`,
`${allPassed ? "✅ 全部通过" : "❌ 发现问题"} | 错误: ${totalErrors} | 警告: ${totalWarnings}`,
``,
];
for (const r of results) {
output.push(`## ${r.success ? "✅" : "❌"} ${r.tool}`, `错误: ${r.errorCount} | 警告: ${r.warningCount}`, "```", r.output.slice(0, 3000), // 限制输出长度
"```", ``);
}
if (!allPassed && !fix) {
output.push(`💡 提示: 可以设置 fix=true 自动修复可修复的问题`);
}
return output.join("\n");
}
//# sourceMappingURL=lintCheck.js.map