write_to_file
write_to_file 工具用于创建新文件或完全替换现有文件内容,并通过交互式确认流程进行操作。它提供差异视图,允许在应用更改前进行审查。
参数
该工具接受以下参数:
path(必需):要写入的文件路径,相对于当前工作目录content(必需):要写入文件的完整内容line_count(必需):文件中的行数,包括空行
功能说明
此工具将内容写入指定文件,如果文件不存在则创建新文件,如果文件已存在则完全覆盖其内容。所有更改都需要通过差异视图进行显式用户确认,用户可以在差异视图中审查甚至编辑建议的更改,然后再应用。
何时使用
- 当 Roo 需要从头创建新文件时
- 当 Roo 需要完全重写现有文件时
- 当为新项目创建多个文件时
- 当生成配置文件、文档或源代码时
- 当需要在应用更改前审查时
主要特性
- 交互式确认:通过差异视图显示更改,需要显式确认后才能应用
- 用户编辑支持:允许在最终确认前编辑建议的内容
- 安全措施:检测代码遗漏、验证路径并防止内容截断
- 编辑器集成:自动滚动到第一个差异处打开差异视图
- 内容预处理:处理来自不同 AI 模型的工件以确保内容清洁
- 访问控制:在应用更改前根据
.rooignore限制进行验证 - 父目录处理:可能通过系统依赖处理目录创建
- 完全替换:在单次操作中提供完全转换的文件
局限性
- 不适用于现有文件:对于修改现有文件,比
apply_diff更慢且效率更低 - 大文件性能:文件越大,操作速度显著下降
- 完全覆盖:替换整个文件内容,无法保留原始内容
- 需要行数:需要准确的行数以检测潜在的内容截断
- 审查开销:确认流程增加了额外步骤,相比直接编辑更繁琐
- 仅支持交互式:无法用于需要非交互式执行的自动化工作流
工作原理
调用 write_to_file 工具时,它遵循以下流程:
-
参数验证:验证必需的参数和权限
- 检查是否提供了
path、content和line_count - 如果
line_count缺失/无效,撤销任何差异视图更改并返回错误,建议使用替代工具(如apply_diff)修改现有文件 - 验证文件是否被允许(未被
.rooignore限制) - 确保路径在工作区边界内
- 跟踪缺失参数的连续错误次数
- 为每个验证失败显示特定错误消息
- 检查是否提供了
-
内容预处理:
- 移除 AI 模型可能添加的代码块标记
- 处理转义的 HTML 实体(特别是针对非 Claude 模型)
- 如果内容中意外包含行号,则将其移除
- 对不同 AI 提供商执行特定模型处理
-
差异视图生成:
- 在编辑器中打开显示建议更改的差异视图
- 添加 300ms 延迟以确保 UI 响应
- 自动滚动到第一个差异处
- 高亮显示更改以便于审查
-
用户确认流程:
- 等待用户显式确认以继续
- 允许用户在差异视图中编辑内容
- 捕获用户对最终内容的任何编辑
- 提供完全拒绝更改的选项
- 检测并将用户修改纳入最终结果
-
安全验证:
- 通过与提供的行数比较检测潜在内容截断
- 如果内容似乎不完整,显示警告
- 验证文件路径和访问权限
- 特别检查文件是否在工作区外,使用
isOutsideWorkspace标志
-
文件写入:
- 将确认的内容(含任何用户编辑)写入文件
- 提供成功写入的确认
- 在成功后重置连续错误计数器
使用示例
- 创建新项目时,Roo 生成多个文件,但会在提交更改前让您审查每个文件。
- 设置配置文件时,Roo 在差异视图中显示建议的配置以供确认。
- 生成文档时,Roo 创建 markdown 文件,但允许您在差异视图中进行最终调整。
- 开发原型时,Roo 在差异视图中显示完整的源文件,您可以在保存前进行微调。
使用示例
创建新的 JSON 配置文件:
<write_to_file>
<path>config/settings.json</path>
<content>
{
"apiEndpoint": "https://api.example.com",
"theme": {
"primaryColor": "#007bff",
"secondaryColor": "#6c757d",
"fontFamily": "Arial, sans-serif"
},
"features": {
"darkMode": true,
"notifications": true,
"analytics": false
},
"version": "1.0.0"
}
</content>
<line_count>14</line_count>
</write_to_file>
创建简单的 HTML 文件:
<write_to_file>
<path>src/index.html</path>
<content>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Application</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="app"></div>
<script src="app.js"></script>
</body>
</html>
</content>
<line_count>13</line_count>
</write_to_file>
创建 JavaScript 模块:
<write_to_file>
<path>src/utils/helpers.js</path>
<content>
/**
* Utility functions for the application
*/
export function formatDate(date) {
return new Date(date).toLocaleDateString();
}
export function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
export function debounce(func, delay) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), delay);
};
}
</content>
<line_count>18</line_count>
</write_to_file>