atomic-edit0.2.2
Pi extension that overrides edit with sequential matching, atomic writes, rename retries, and a direct-write fallback.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
atomic-edit

A pi extension that overrides the built-in edit tool to fix two problems we
kept hitting while working with slower models.
Why this exists
We use pi with a mix of fast and slow models, and multi-edit calls were the single most common source of wasted turns:
- Slow models batch edits, then fail on
edits[1]. The built-in tool matches every edit against the original file. So any edit that overlaps text changed by an earlier edit — a very natural thing for a model to write — is rejected after the first edit has already succeeded. - The retry loop is expensive. The model re-reads the file, re-derives all the edits, and tries again. On a large file that is seconds of latency per round trip, and slower models often make the same mistake twice.
- Interrupted writes can truncate. A crash or full disk during a plain
writeFilecan leave a half-written file behind.
atomic-edit keeps the tool name edit (the model never learns a new API) and
changes two defaults:
- Sequential matching —
edits[i]is matched against the file afteredits[i-1]has been applied, so chained and overlapping edits just work. - Atomic writes — write to a temp file in the same directory,
fsync, thenrenameover the target. A failed edit never leaves a torn file.
Both behaviors are independently switchable, including live via /edit-mode, so
you can get built-in behavior back at any time: with snapshot matching the file
contents are byte-for-byte identical (for the one narrow ambiguity difference,
see the matching caveat).
Install
package.json declares a Pi package
(pi.extensions -> ./index.ts, host packages as peer dependencies), so there
is no build step:
# install from npm into ~/.pi/agent/settings.json
pi install npm:atomic-edit
# one-off, without changing settings
pi -e npm:atomic-edit
# from git (pin a tag or commit for reproducible behavior)
pi install git:gitlab.com/openbracket/atomic-edit@v0.2.2
# from a local checkout
pi install ./atomic-edit
Uninstall with pi remove npm:atomic-edit. For a development checkout you can
also load the directory directly: pi --extension /path/to/atomic-edit.
Highlights
Chained edits that would fail on the built-in tool
With the built-in edit, this call fails because edits[1] no longer matches
the original text after edits[0] ran:
[
{ "oldText": "const timeout = 30", "newText": "const timeout = 60" },
{ "oldText": "const timeout = 60", "newText": "const timeout = 60000 // ms" }
]
atomic-edit applies them in order and succeeds.
One write, one file, no torn state
The file is read once, all edits are applied in memory, and the result is
written once via temp file + fsync + rename. If a later edit fails to match,
nothing is written at all.
Speed
Medians from bench.ts on a 3.80 MB / 80k-line file
(Linux, ext4 SSD, Node 22, pi 1.4.0). Ratios matter more than absolutes;
expect roughly 10% run-to-run variation.
Matching only (CPU, no I/O):
| Workload | pi built-in | snapshot | default (sequential) |
|---|---|---|---|
| 25 edits | 432 ms | 43 ms | 68 ms |
| 100 edits | 1.74 s | 153 ms | 258 ms |
| 25 fuzzy edits | 613 ms | 274 ms | 369 ms |
Full tool path (read + match + diff + write):
| Workload | pi built-in | atomic + fsync | atomic (PI_EDIT_FSYNC=0) |
|---|---|---|---|
| 3.80 MB / 100 edits, snapshot | 1.97 s | 0.29 s | 0.27 s |
| 3.80 MB / 100 edits, sequential | 1.97 s | 0.41 s | 0.40 s |
| 4 KB / 1 edit | 0.45 ms | 9.2 ms | 0.55 ms |
On large files, exact-match editing is ~10–12× faster and the full path is
~6.8× faster in snapshot mode (~4.8× in the default sequential mode);
fuzzy-heavy calls are ~2.2× faster. On small files the atomic fsync is the
only slowdown: 9.2 ms versus 0.45 ms, negligible next to model latency.
PI_EDIT_FSYNC=0 restores parity while keeping the atomic rename.
Documentation
- Usage — flags,
/edit-mode, environment variables, matching rules, atomic-write details, and caveats. - Development — internals, benchmarking, tests, and the file layout.
License
MIT. Includes attribution for code derived from pi; see LICENSE.