omp packages

atomic-edit0.2.2

Pi extension that overrides edit with sequential matching, atomic writes, rename retries, and a direct-write fallback.

judohippo Published 2 hours ago MIT ~420 downloads/mo

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.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

atomic-edit

atomic-edit preview

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 writeFile can leave a half-written file behind.

atomic-edit keeps the tool name edit (the model never learns a new API) and changes two defaults:

  1. Sequential matching — edits[i] is matched against the file after edits[i-1] has been applied, so chained and overlapping edits just work.
  2. Atomic writes — write to a temp file in the same directory, fsync, then rename over 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.