Lzh on GitHub

write_to_file

write_to_file 工具可以通过交互式审批流程创建新文件或完全替换现有文件内容。它提供一个差异视图,用于在应用更改之前进行审查。

write_to_file 工具可以通过交互式审批流程创建新文件或完全替换现有文件内容。它提供一个差异视图,用于在应用更改之前进行审查。

参数

该工具接受以下参数:

  • path(必填):要写入的文件的路径,相对于当前工作目录。
  • content(必填):要写入文件的完整内容。
  • line_count(必填):文件中的行数,包括空行。

功能

此工具将内容写入指定文件,如果文件不存在则创建新文件,或完全覆盖现有文件。所有更改都需要通过差异视图界面进行明确的用户批准,用户可以在应用更改之前审查甚至编辑提议的更改。

使用时机

  • 当 Roo 需要从头开始创建新文件时。
  • 当 Roo 需要完全重写现有文件时。
  • 当为新项目创建多个文件时。
  • 当生成配置文件、文档或源代码时。
  • 当需要在应用更改之前审查更改时。

主要功能

  • 交互式审批:在应用前,在差异视图中显示更改,需要明确批准。
  • 支持用户编辑:允许在最终批准前编辑提议的内容。
  • 安全措施:检测代码遗漏、验证路径并防止内容被截断。
  • 编辑器集成:打开一个差异视图,自动滚动到第一个差异处。
  • 内容预处理:处理来自不同 AI 模型的工件,以确保内容干净。
  • 访问控制:在进行更改前,根据 .rooignore 限制进行验证。
  • 父目录:可以通过系统依赖项处理目录创建。
  • 完全替换:在一次操作中提供一个完全转换的文件。

局限性

  • 不适用于现有文件:对于修改现有文件,比 apply_diff 慢得多且效率低。
  • 大文件性能:操作在大文件上会显著变慢。
  • 完全覆盖:替换整个文件内容,无法保留原始内容。
  • 需要行数:需要准确的行数来检测潜在的内容截断。
  • 审查开销:与直接编辑相比,审批过程增加了额外的步骤。
  • 仅限交互式:不能用于需要非交互式执行的自动化工作流。

工作原理

当调用 write_to_file 工具时,它遵循以下过程:

  1. 参数验证
  • 验证所需的参数和权限。
  • 检查是否提供了 pathcontentline_count
  • 如果 line_count 缺失/无效,则回滚任何差异视图更改并返回错误,如果正在修改现有文件,则建议使用其他工具(apply_diffinsert_content 等)。
  • 验证文件是否被允许(未受 .rooignore 限制)。
  • 确保路径在工作区边界内。
  • 跟踪缺少参数的连续错误计数。
  • 为每个验证失败显示特定的错误消息。
  1. 内容预处理
  • 移除可能由 AI 模型添加的代码块标记。
  • 处理转义的 HTML 实体(特别是对于非 Claude 模型)。
  • 如果意外地包含在内容中,则去除行号。
  • 为不同的 AI 提供商执行特定于模型的处理。
  1. 差异视图生成
  • 在编辑器中打开一个差异视图,显示提议的更改。
  • 添加 300 毫秒的延迟以确保 UI 响应。
  • 自动滚动到第一个差异处。
  • 高亮显示更改以便于审查。
  1. 用户审批流程
  • 等待明确的用户批准以继续。
  • 允许用户在差异视图中编辑内容。
  • 捕获任何用户编辑以用于最终内容。
  • 提供完全拒绝更改的选项。
  • 检测并将用户修改纳入最终结果。
  1. 安全验证
  • 通过与提供的行数进行比较来检测潜在的内容截断。
  • 如果内容看起来不完整,则显示警告。
  • 验证文件路径和访问权限。
  • 特别检查文件是否通过 isOutsideWorkspace 标志在工作区之外。
  1. 文件写入
  • 将批准的内容(以及任何用户编辑)写入文件。
  • 提供成功写入的确认。
  • 成功后重置连续错误计数器。

使用示例

  • 当创建新项目时,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>