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