| title | Reliable Editing for Coding Agents |
|---|---|
| weight | 3 |
| description | Why coding agents need validated, explainable, and recoverable file editing. |
A coding agent does not edit a file in a vacuum. Between reading a range and applying a generated patch, another process, tool call, or earlier edit may have changed the file. The model may also send malformed content, choose the wrong range, or retry a failed operation without updating its assumptions.
better-edit-tools treats those failure modes as part of the normal design space. Its editing primitives are intended to make file changes precise, observable, and recoverable.
read the current target
|
v
record content and session state
|
v
apply a precise edit
|
+--> validate exact assumptions
|
+--> write atomically
|
+--> return a next action on failure
The normal MCP workflow is:
- Use
be-readto inspect the target range and obtainviewed_code_id. - Use a range helper such as
be-func-rangeorbe-tag-rangewhen the boundary should be resolved structurally. - Use
be-replace,be-insert, orbe-deletefor the smallest suitable change. - Provide
oldwhen the current content must match exactly. - Provide
viewed_code_idwhen the edit depends on the earlier read remaining current. - If the operation fails or warns, follow the returned action: re-read, inspect the diff, retry with corrected arguments, or recover through snapshots/chips.
When old is provided, the target content must match exactly. A mismatch is an error because silently applying the edit would mean the model is editing a state it has not verified.
The safe response is to re-read the file and construct a new edit. Blindly retrying the same arguments does not repair the stale assumption.
viewed_code_id connects a later edit to a previous be-read operation. It records the content of the relevant range and the file's total line count. Range-content changes that keep the total line count stable are detected as a warning-level signal (warn but do not block): the range is still accurate, so the edit can safely continue after reviewing the warning.
If the file's total line count changes anywhere since the read, the recorded line numbers may have shifted (for example lines inserted above the target) — be-replace rejects by default even when the old range still fits the current file, and the error explains that a re-read (or an explicit force=true override) is required. This check is a guard against editing the wrong lines, not a replacement for old; workflows that require strict content identity should also provide old.
An error message is useful to a coding agent only when it helps choose the next action. Examples of useful recovery guidance include:
- re-read the file to obtain current content and line numbers;
- inspect the line-by-line diff before retrying;
- create the missing directory or correct the path;
- use a saved chip to recover content from a failed write;
- use transaction rollback when a sequence of edits needs to be undone.
This is different from returning a generic content mismatch or invalid input. The tool result should explain both what failed and what the agent can do next.
The underlying write operations use a temporary file and rename sequence, with synchronization around the file and directory where appropriate. The goal is to avoid leaving a partially written target when the process or machine fails during a write.
preview allows a caller to inspect the proposed diff before changing the file. A previewed be-replace returns an opaque event_id that can later be applied exactly once via confirm, after re-verifying that the file has not changed since the preview. Transaction snapshots provide a further recovery boundary for multiple edits, while chip storage preserves useful arguments or content after selected failures.
Line numbers alone are often a weak editing boundary. The project therefore includes helpers for:
- locating the enclosing function or brace range;
- locating the enclosing HTML/XML/Vue tag range;
- checking brackets, braces, parentheses, tags, and quote balance while ignoring strings and comments.
These tools do not replace a language parser. They provide small, local signals that help an agent choose a safer edit range without requiring a full compiler or language server.
- It cannot determine whether a change is semantically correct for the application.
- A valid
oldstring does not prove that the replacement is a good design. - Structural balance is not equivalent to successful compilation.
- A warning still requires the agent or user to make a decision.
- Protocol support does not replace the editing library's validation and recovery semantics.
The project narrows the gap between a model's proposed edit and a safely applied file change. It does not turn an LLM into a compiler or a reviewer.
The reliability behavior is protected with focused regression tests for cases such as:
- content changes that keep the same number of lines;
- stale or mismatched
oldcontent; - malformed model-generated write payloads;
- line comments accidentally swallowing later source lines;
- strings and comments containing bracket-like characters;
- complete strings being mistaken for unmatched quotes.
The intended development loop is:
issue or failure report
|
v
minimal reproduction
|
v
focused regression test
|
v
small implementation change
|
v
full test suite and CLI/MCP verification
This keeps reliability claims tied to reproducible behavior rather than to feature count.