面向 Coding Agent 的可靠编辑#

Coding agent 并不是在真空中编辑文件。从读取一个范围到应用模型生成的修改之间,文件可能已经被其他进程、工具调用或此前的编辑改变。模型也可能生成格式异常的内容、选择错误的范围,或者在一次操作失败后不更新前提就盲目重试。

better-edit-tools 把这些失败模式视为正常的设计输入。它提供的编辑原语,目标是让文件修改更精确、更可观察,也更容易恢复。

编辑闭环#

读取当前目标
        |
        v
记录内容和会话状态
        |
        v
执行精确编辑
        |
        +--> 校验编辑前提
        |
        +--> 原子写入
        |
        +--> 失败时返回下一步动作

标准 MCP 工作流如下:

  1. 使用 be-read 查看目标范围并获取 viewed_code_id
  2. 如果边界应根据结构确定,使用 be-func-rangebe-tag-range 等范围工具。
  3. 根据修改类型,使用 be-replacebe-insertbe-delete 完成尽可能小的变更。
  4. 如果要求当前内容必须完全一致,提供 old
  5. 如果编辑依赖此前读取的结果仍然有效,提供 viewed_code_id
  6. 如果操作失败或返回 warning,按照结果中的建议继续:重新读取、检查 diff、修正参数重试,或通过快照/chip 恢复。

两种校验#

old:内容硬校验#

提供 old 时,目标内容必须完全匹配。不匹配就返回错误,因为静默应用修改意味着模型正在编辑一个未经确认的文件状态。

安全做法是重新读取文件并构造新的编辑参数。盲目重复相同调用,不能修复过期前提。

viewed_code_id:会话一致性信号#

viewed_code_id 把后续编辑关联到之前的 be-read 操作。它记录目标范围的内容以及文件的总行数。总行数不变时范围内的内容变化仍以 warning 级信号提示(只警告不阻塞):范围仍然准确,查看 warning 后可安全继续。

读取后只要文件总行数发生变化(例如目标上方插入了行),记录的行号就可能已漂移——此时即使旧范围仍位于当前文件边界内,be-replace默认拒绝执行,报错会提示重新读取,或显式传 force=true 覆盖。这个检查是防止按旧行号编辑到错误位置,不是 old 的替代品;如果工作流要求严格的内容一致性,还应同时提供 old

失败也是接口的一部分#

对于 coding agent,错误消息只有在能帮助它选择下一步动作时才真正有用。有效的恢复引导包括:

  • 重新读取文件以获取当前内容和行号;
  • 在重试前检查逐行 diff;
  • 创建缺失目录或修正路径;
  • 使用保存下来的 chip 恢复失败写入中的内容;
  • 当一组编辑需要撤销时使用事务回滚。

这与只返回 content mismatchinvalid input 不同。工具结果应同时说明哪里失败,以及 agent 接下来可以做什么。

写入过程中的文件保护#

底层写操作通过临时文件和 rename 完成,并在适当的位置同步文件和目录。目标是避免进程或机器在写入过程中失败后留下半写入状态的文件。

preview 允许调用方在修改文件前检查拟执行的 diff。预览过的 be-replace 会返回一个不透明的 event_id,之后可传 confirm 恰好应用一次,应用前会重新校验文件自预览以来未发生变化。事务快照为多步编辑提供额外的恢复边界,chip 存储则会在特定操作失败后保留有用的参数或内容。

结构感知的查看#

单纯的行号通常不是可靠的编辑边界。因此项目还提供:

  • 定位外层函数或花括号范围;
  • 定位外层 HTML/XML/Vue 标签范围;
  • 检查括号、花括号、圆括号、标签和引号是否平衡,同时避开字符串和注释中的干扰符号。

这些工具不取代语言解析器。它们提供小而局部的结构信号,帮助 agent 在不引入完整编译器或 language server 的情况下选择更安全的编辑范围。

项目不保证什么#

  • 它不能判断修改是否符合应用本身的业务语义。
  • old 内容有效,不等于 replacement 设计一定正确。
  • 结构平衡不等于代码一定能够编译。
  • warning 仍然需要 agent 或用户做判断。
  • 协议层支持不能替代编辑库自身的校验和恢复语义。

项目做的是缩小“模型提出修改”和“安全应用文件变化”之间的差距。它不会把 LLM 变成编译器或代码审查员。

证据与回归测试#

项目通过聚焦的回归测试保护以下可靠性行为:

  • 行数不变但内容发生变化;
  • old 内容过期或不匹配;
  • 模型生成的写入载荷格式异常;
  • 行注释状态意外吞掉后续源代码;
  • 字符串和注释中包含类似括号的字符;
  • 完整字符串被误判成未闭合引号。

预期的开发闭环是:

issue 或失败报告
        |
        v
最小复现
        |
        v
聚焦的回归测试
        |
        v
小范围实现修复
        |
        v
全量测试与 CLI/MCP 验证

这样,项目的可靠性结论就建立在可复现行为上,而不是工具数量上。