import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs"; import { dirname, extname } from "path"; export const readFileTool = { name: "read_local_file", description: "读取本地文件内容。支持任意文本文件,返回带行号的内容。", inputSchema: { type: "object", properties: { path: { type: "string", description: "文件绝对路径", }, start_line: { type: "number", description: "起始行号(可选,从 1 开始)", }, end_line: { type: "number", description: "结束行号(可选)", }, }, required: ["path"], }, }; export const writeFileTool = { name: "write_local_file", description: "写入内容到本地文件。如果文件不存在会自动创建(含父目录)。支持完整写入或按行替换。", inputSchema: { type: "object", properties: { path: { type: "string", description: "文件绝对路径", }, content: { type: "string", description: "要写入的完整文件内容", }, create_dirs: { type: "boolean", description: "是否自动创建父目录(默认 true)", }, }, required: ["path", "content"], }, }; export const patchFileTool = { name: "patch_file", description: "精确修改本地文件。查找指定文本并替换为新文本,支持多次替换。适合自动纠错和代码修改。", inputSchema: { type: "object", properties: { path: { type: "string", description: "文件绝对路径", }, old_text: { type: "string", description: "要查找并替换的原文本(必须精确匹配)", }, new_text: { type: "string", description: "替换后的新文本", }, replace_all: { type: "boolean", description: "是否替换所有匹配项(默认 false,只替换第一个)", }, }, required: ["path", "old_text", "new_text"], }, }; export async function executeReadFile(args) { const { path: filePath, start_line, end_line } = args; if (!existsSync(filePath)) { return `❌ 文件不存在: ${filePath}`; } try { const content = readFileSync(filePath, "utf-8"); const lines = content.split("\n"); const start = (start_line || 1) - 1; const end = end_line || lines.length; const selected = lines.slice(start, end); const numbered = selected.map((line, i) => `${String(start + i + 1).padStart(4)} | ${line}`).join("\n"); return [ `📄 ${filePath}`, `行数: ${lines.length} | 显示: ${start + 1}-${Math.min(end, lines.length)}`, `类型: ${extname(filePath) || "unknown"}`, ``, numbered, ].join("\n"); } catch (error) { return `❌ 读取失败: ${error.message}`; } } export async function executeWriteFile(args) { const { path: filePath, content, create_dirs = true } = args; try { if (create_dirs) { const dir = dirname(filePath); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } } const existed = existsSync(filePath); const oldLines = existed ? readFileSync(filePath, "utf-8").split("\n").length : 0; writeFileSync(filePath, content, "utf-8"); const newLines = content.split("\n").length; return [ `✅ 文件已${existed ? "更新" : "创建"}: ${filePath}`, existed ? `行数变化: ${oldLines} → ${newLines}` : `行数: ${newLines}`, ].join("\n"); } catch (error) { return `❌ 写入失败: ${error.message}`; } } export async function executePatchFile(args) { const { path: filePath, old_text, new_text, replace_all = false } = args; if (!existsSync(filePath)) { return `❌ 文件不存在: ${filePath}`; } try { const content = readFileSync(filePath, "utf-8"); if (!content.includes(old_text)) { return `❌ 未找到匹配文本。\n\n搜索内容:\n\`\`\`\n${old_text.slice(0, 200)}\n\`\`\`\n\n提示: old_text 必须精确匹配文件中的内容(包括空格和换行)`; } const occurrences = content.split(old_text).length - 1; let newContent; if (replace_all) { newContent = content.split(old_text).join(new_text); } else { const idx = content.indexOf(old_text); newContent = content.substring(0, idx) + new_text + content.substring(idx + old_text.length); } writeFileSync(filePath, newContent, "utf-8"); const replacedCount = replace_all ? occurrences : 1; return [ `✅ 文件已修改: ${filePath}`, `替换: ${replacedCount} 处${occurrences > 1 && !replace_all ? `(共找到 ${occurrences} 处匹配,仅替换第 1 处)` : ""}`, ``, `--- 旧代码 ---`, "```", old_text.slice(0, 500), "```", ``, `+++ 新代码 +++`, "```", new_text.slice(0, 500), "```", ].join("\n"); } catch (error) { return `❌ 修改失败: ${error.message}`; } } //# sourceMappingURL=fileOps.js.map