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

112 lines
4.8 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 autoFixTool = {
name: "auto_fix",
description: "自动修复代码问题。运行 Prettier 格式化、ESLint --fix 自动修复、以及其他自动修复工具。返回修复前后的变更摘要。",
inputSchema: {
type: "object",
properties: {
project_path: {
type: "string",
description: "项目根目录(绝对路径)",
},
files: {
type: "string",
description: "指定修复的文件或 glob可选默认修复整个项目",
},
tools: {
type: "string",
description: "指定修复工具逗号分隔可选prettier, eslint, autopep8。默认自动检测。",
},
},
required: ["project_path"],
},
};
async function runFix(cmd, cwd) {
try {
const { stdout, stderr } = await execAsync(cmd, {
cwd,
timeout: 30000,
maxBuffer: 1024 * 1024 * 5,
shell: process.platform === "win32" ? "powershell.exe" : "/bin/bash",
});
return { success: true, output: stdout || stderr || "✅ 修复完成" };
}
catch (error) {
return { success: false, output: error.stdout || error.stderr || error.message };
}
}
export async function executeAutoFix(args) {
const { project_path, files, tools } = args;
const hasFile = (name) => existsSync(join(project_path, name));
const fixResults = [];
// 先获取 git diff 作为修复前基线
let diffBefore = "";
try {
const { stdout } = await execAsync("git diff --stat", { cwd: project_path, timeout: 5000 });
diffBefore = stdout;
}
catch { }
const requestedTools = tools ? tools.split(",").map((t) => t.trim().toLowerCase()) : [];
const autoDetect = requestedTools.length === 0;
// Prettier
if (autoDetect ? (hasFile(".prettierrc") || hasFile(".prettierrc.json") || hasFile("prettier.config.js")) : requestedTools.includes("prettier")) {
const target = files || ".";
const result = await runFix(`npx prettier --write "${target}"`, project_path);
fixResults.push({ tool: "Prettier", ...result });
}
// ESLint --fix
if (autoDetect ? (hasFile(".eslintrc.js") || hasFile(".eslintrc.json") || hasFile("eslint.config.js") || hasFile("eslint.config.mjs")) : requestedTools.includes("eslint")) {
const target = files || "src/";
const result = await runFix(`npx eslint "${target}" --fix`, project_path);
fixResults.push({ tool: "ESLint --fix", ...result });
}
// Python autopep8
if (autoDetect ? (hasFile("requirements.txt") || hasFile("pyproject.toml")) : requestedTools.includes("autopep8")) {
const target = files || ".";
const result = await runFix(`python -m autopep8 --in-place --recursive "${target}"`, project_path);
if (!result.output.includes("No module named")) {
fixResults.push({ tool: "autopep8", ...result });
}
}
// 如果没有检测到工具配置,尝试 package.json 中的 format 脚本
if (fixResults.length === 0 && hasFile("package.json")) {
const result = await runFix("npm run format 2>&1 || npm run lint:fix 2>&1 || echo NO_FIX_SCRIPT", project_path);
if (!result.output.includes("NO_FIX_SCRIPT") && !result.output.includes("Missing script")) {
fixResults.push({ tool: "npm script (format/lint:fix)", ...result });
}
}
// 获取修复后的 diff
let diffAfter = "";
try {
const { stdout } = await execAsync("git diff --stat", { cwd: project_path, timeout: 5000 });
diffAfter = stdout;
}
catch { }
// 组装报告
const output = [
`# 自动修复报告`,
``,
`📂 项目: ${project_path}`,
``,
];
if (fixResults.length === 0) {
output.push("⚠️ 未检测到格式化/修复工具", "", "建议安装:", "- `npm install -D prettier` — 代码格式化", "- `npm install -D eslint` — 代码质量检查和自动修复", "- `pip install autopep8` — Python 代码格式化");
}
else {
for (const r of fixResults) {
output.push(`## ${r.success ? "✅" : "⚠️"} ${r.tool}`, "```", r.output.slice(0, 2000), "```", ``);
}
if (diffAfter && diffAfter !== diffBefore) {
output.push("## 变更摘要 (git diff --stat)", "```", diffAfter, "```");
}
else if (fixResults.some((r) => r.success)) {
output.push("📝 修复完成,代码已更新");
}
}
return output.join("\n");
}
//# sourceMappingURL=autoFix.js.map