文件操作工具
AggRoot 提供六个核心文件操作工具,覆盖文件读取、写入、编辑、搜索、内容查找和目录扫描。核心原则:优先使用专用工具而非 Shell 命令。
Read — 读取文件
智能文件读取工具,支持分页、大纲模式、内容搜索和图片分析。
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| path | string | 否* | — | 单个文件路径 |
| paths | string[] | 否* | — | 多文件路径数组(与 path 二选一) |
| offset | number | 否 | 1 | 起始行号(1-based) |
| limit | number | 否 | 2000 | 读取行数上限 |
| outline | boolean | 否 | false | 仅返回函数/类/接口签名(忽略 offset/limit/search) |
| search | string | 否 | — | 搜索关键词,返回匹配行及上下文(支持正则) |
| contextLines | number | 否 | 5 | search 模式下的上下文行数 |
*path 和 paths 至少提供一个。
功能特性
- 分页读取:
offset+limit实现大文件分段阅读 - 大纲模式:
outline: true快速了解文件结构,提取函数/类/接口签名 - 内容搜索:
search参数在文件内定位关键代码,支持正则表达式 - 多文件并发:
paths数组传入多个路径,并发读取 - 图片分析:开启视觉服务后(
VISION_ENABLED=true),可直接读取图片文件并返回文字描述 - 智能路径:自动处理中英文空格问题,模糊匹配文件名
- 缓存机制:已读取文件自动缓存,重复读取时提示缓存状态
示例
// 读取整个文件
Read({"path": "src/index.ts"})
// 分页读取大文件
Read({"path": "src/large-file.ts", "offset": 100, "limit": 50})
// 查看文件大纲
Read({"path": "src/index.ts", "outline": true})
// 搜索特定内容
Read({"path": "src/index.ts", "search": "function main", "contextLines": 3})
// 并发读取多个文件
Read({"paths": ["src/a.ts", "src/b.ts", "src/c.ts"]})
技巧
- 先用
outline: true了解文件结构,再按需offset读取具体部分 search支持正则:"import.*from"、"class\\s+\\w+"- 大文件分段读取后,用 Edit 定向修改,避免全文重写
Write — 写入文件
创建新文件或覆盖现有文件,自动创建不存在的目录。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 文件绝对路径或相对路径 |
| content | string | 是 | 要写入的内容 |
功能特性
- 自动创建目录:路径中的中间目录不存在时自动递归创建
- 写入验证:写入后回读文件,验证内容完整性
- Diff 展示:覆盖已有文件时显示彩色 diff,新建文件时显示预览
- 统计摘要:返回新增/删除行数、文件大小
示例
// 创建新文件
Write({"path": "src/utils.ts", "content": "export function hello() { return 'world'; }"})
// 覆盖已有文件(会展示 diff)
Write({"path": "src/config.json", "content": "{\"port\": 3000}"})
注意事项
- Write 是全量覆盖,如只需修改部分内容,请使用 Edit
- 写入验证失败时会返回错误(内容长度不匹配)
Edit — 编辑文件
精确文本替换工具,类似 diff 补丁,只修改指定部分,保留其余内容不变。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 文件路径 |
| oldText | string | 是 | 要替换的原始文本(必须与文件内容完全匹配) |
| newText | string | 是 | 替换后的新文本 |
| fuzzy | boolean | 否 | 忽略空白差异进行模糊匹配(默认 false) |
匹配机制
Edit 按以下优先级尝试匹配:
- 精确匹配:
oldText必须与文件内容完全一致(包括缩进、空格、换行) - 行号前缀剥离:自动去除 Read 输出中的行号前缀(如
42│) - 引号标准化:自动处理弯引号(''"")和直引号的差异
- 模糊匹配:
fuzzy: true时忽略空白差异
示例
// 修改变量名
Edit({
"path": "src/app.ts",
"oldText": "const port = 3000;",
"newText": "const port = 8080;"
})
// 替换多行代码
Edit({
"path": "src/handler.ts",
"oldText": "function oldName() {\n return 1;\n}",
"newText": "function newName() {\n return 2;\n}"
})
// 模糊匹配(忽略空白差异)
Edit({
"path": "src/app.ts",
"oldText": "if (condition) { doSomething(); }",
"newText": "if (condition) { doSomethingElse(); }",
"fuzzy": true
})
注意事项
- oldText 必须精确匹配:包括缩进、空格、换行符。建议先 Read 文件,再复制原文作为 oldText
- 匹配失败时会显示最近似行的上下文,帮助定位问题
- 如果 oldText 在文件中出现多次,只替换第一个匹配
- Edit 比 Write 更安全:只修改目标文本,不会意外改变其他内容
Glob — 搜索文件
按文件名/路径模式搜索文件,底层优先使用 ripgrep,回退到 npm glob。
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| pattern | string | 否* | — | 单个 glob 模式 |
| patterns | string[] | 否* | — | 多个 glob 模式(与 pattern 二选一) |
| path | string | 否 | 当前目录 | 搜索起始目录 |
| limit | number | 否 | 100 | 最大结果数 |
*pattern 和 patterns 至少提供一个。
排除目录
自动排除:node_modules、.git、dist、coverage、build、out
支持的模式语法
**/*.ts— 递归搜索所有.ts文件src/**/*.test.ts— 搜索 src 下的测试文件*.{ts,tsx}— 搜索.ts和.tsx文件docs/**/*.md— 搜索 docs 下的 Markdown 文件
示例
// 搜索所有 TypeScript 文件
Glob({"pattern": "**/*.ts"})
// 搜索多种类型
Glob({"patterns": ["src/**/*.ts", "test/**/*.ts"]})
// 限定搜索目录
Glob({"pattern": "**/*.md", "path": "docs"})
// 限制结果数量
Glob({"pattern": "**/*.json", "limit": 20})
技巧
- Glob 按文件名搜索,Grep 按内容搜索 — 根据需求选择
- 大量结果时使用更精确的路径或模式,或调小
limit
Grep — 搜索内容
在文件内容中搜索匹配文本,底层使用 ripgrep(速度快),回退到 GNU grep 或 JS 实现。
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| pattern | string | 是 | — | 搜索模式(支持正则表达式) |
| include | string | 否 | **/* | 文件类型过滤,如 *.ts、*.{ts,tsx} |
| path | string | 否 | 当前目录 | 搜索路径 |
| ignoreCase | boolean | 否 | false | 忽略大小写 |
| limit | number | 否 | 100 | 每个模式的最大匹配数 |
| contextLines | number | 否 | 0 | 上下文行数 |
| fileType | string | 否 | — | 预定义文件类型(如 ts、py、java) |
支持的文件类型
ripgrep 内置 40+ 种文件类型:ts、js、py、java、go、rust、cpp、c、cs、rb、php、swift、kt、html、css、md、json、yaml、sql、sh 等。
排除目录
自动排除:node_modules、.git、dist、coverage
示例
// 搜索函数定义
Grep({"pattern": "function\\s+\\w+", "fileType": "ts"})
// 搜索特定字符串
Grep({"pattern": "TODO", "include": "*.ts", "ignoreCase": true})
// 搜索带上下文
Grep({"pattern": "class App", "contextLines": 3, "fileType": "ts"})
// 限定搜索路径
Grep({"pattern": "import.*from", "path": "src/domain"})
技巧
- 使用
fileType比用include更高效(ripgrep 原生类型过滤) contextLines设为 2-3 可看到匹配行的前后文,便于判断- 搜索无结果时,工具会根据关键词建议可能包含该内容的文件
DirectoryTree — 目录扫描
快速扫描目录结构,获取树形视图。在探索不熟悉的项目时,应优先使用此工具。
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| path | string | 否 | 当前目录 | 扫描的根目录 |
| depth | number | 否 | 3 | 扫描深度 |
| excludeDirs | string[] | 否 | 见下方 | 排除的目录名 |
默认排除目录
node_modules、.git、dist、coverage、build、out、.next、.nuxt、__pycache__、.cache
示例
// 查看项目结构
DirectoryTree({"path": ".", "depth": 2})
// 深入查看某个目录
DirectoryTree({"path": "src/domain", "depth": 4})
// 自定义排除
DirectoryTree({"path": ".", "depth": 3, "excludeDirs": ["node_modules", ".git", "dist", "test"]})
技巧
- 先 DirectoryTree 再 Launch Agent:了解目录结构后再定向探索,避免盲目启动广域探索代理
- 深度 2-3 足以了解项目结构,无需扫到叶子节点
- 输出为树形结构,直观显示文件和目录的层级关系
核心原则
| 操作 | 推荐工具 | 避免使用 |
|---|---|---|
| 读取文件 | Read | cat、head、tail |
| 写入文件 | Write | echo >、cat <<EOF |
| 编辑文件 | Edit | sed、awk |
| 搜索文件名 | Glob | find、ls |
| 搜索内容 | Grep | grep、rg |
| 目录结构 | DirectoryTree | tree、ls -R |
专用工具比 Shell 命令更安全、更高效,且输出格式对 AI 更友好。