Edit
Replace an exact substring in a file. On Go projects, lint findings for the edited file are appended to the success message. On Python / Node / Rust projects, a single-file format check (ruff format --check --diff, prettier --check, rustfmt --check) is appended under --- format ---.
Schema
Section titled “Schema”| Param | Type | Required | Default | Notes |
|---|---|---|---|---|
file_path | string | yes | — | Absolute or workspace-relative path. |
old_string | string | yes | — | Must be non-empty. |
new_string | string | yes | — | May be empty (deletes the match). |
replace_all | boolean | no | false | If false and old_string appears more than once, call is rejected. |
Behaviour
Section titled “Behaviour”- Resolve the path (containment check).
- Verify the file exists and isn’t a directory.
- Verify the file has been
Readin the current session — otherwiserefusing to edit %s: Read it first. - Verify
old_stringis non-empty (prevents anos.WriteFile-shaped corruption path). - Count occurrences of
old_string:- 0 → error
old_string not found in %s - 1 → replace, atomic write.
- >1 with
replace_all=false→ errorold_string matched N times in %s; add context to make it unique or set replace_all=true - >1 with
replace_all=true→ replace all, atomic write.
- 0 → error
- On success, run the project’s linter with a 30s timeout. If any findings apply to the edited file, append them to the response.
- If the detected language declares a per-file format check (
Detector.FormatCheckCmd) and its binary is on PATH, run it with a 10s timeout and append any output under a--- format ---header. Go’sFormatCheckCmdis nil (its lint path already covers gofmt), so Go edits never render a format section.
Post-edit lint feedback
Section titled “Post-edit lint feedback”The “single biggest quality win” per the project proposal. On Go projects, after every successful Edit:
verify.Lintrunsgolangci-lint run ./...from the workspace root.- Findings are parsed into structured
file:line:col:rule: messagerecords. - Findings whose file matches the edited path are appended to the success body.
Best-effort: if the linter times out, isn’t installed, or the project isn’t Go, the base success message is unchanged.
Post-edit format check
Section titled “Post-edit format check”On non-Go projects, after the lint section (if any), Edit runs the detector’s FormatCheckCmd against the edited file with a 10s timeout. Per language:
| Language | Command | Notes |
|---|---|---|
| Go | (nil) | Skipped — the lint path already covers gofmt / gofumpt coverage. |
| Python | ruff format --check --diff <file> | --diff prints the fix ruff would apply; --check keeps it non-destructive. |
| Node | prettier --check <file> | Assumes prettier is on PATH directly; projects installing it locally shadow via a wrapper script. |
| Rust | rustfmt --check <file> | Edition is inherited from the enclosing Cargo.toml. |
Output rules:
- Formatter exit 0 (file is formatted) → no section rendered.
- Formatter exit non-zero with output → appended under
--- format ---, truncated to 500 lines. - Detector declares a formatter but the binary isn’t on PATH → a single line
post-edit format: <binary> not found on PATHis appended (Edit never fails on format feedback).
Example output
Section titled “Example output”Clean edit:
replaced 1 occurrence(s) in probe.goEdit that introduces a lint violation:
replaced 1 occurrence(s) in probe.go
post-edit lint findings (1):probe.go:5:3:errcheck: Error return value of `os.WriteFile` is not checkedEdit on a Python file that’s not formatted (rendered under --- format ---):
replaced 1 occurrence(s) in app.py
--- format ------ app.py+++ app.py@@ -1 +1 @@-x=1+x = 1