Line-hash anchored read/edit/write for AI coding agents — windowed reads, strict version checks, atomic writes
Project description
hash-edit (Python)
Line-hash anchored read/edit/write for AI coding agents — windowed reads, strict version checks, atomic writes.
Install
pip install hash-edit
# or
uv add hash-edit
Quick start
from hash_edit import HashEditHarness
h = HashEditHarness("/path/to/project")
# 1. Read — returns rendered lines with hashes and a full-file version digest
result = h.read("src/app.py")
# result["version"] == "4a3f..."
# result["lines"] == ["1:ab|import os", "2:cd|", "3:ef|def main(): ..."]
# result["total_lines"] == 3
# 2. Edit — anchored ops verified against expected_version
h.edit(
"src/app.py",
[
{"op": "replace", "line": 3, "hash": "ef", "lines": ["def main():", " pass"]},
],
expected_version=result["version"],
)
# 3. Write — safely create or overwrite; expected_version required when overwriting
h.write("src/new_file.py", "# new content\n")
Windowed reads
For large files, pass start_line / end_line to read only the lines you need (saves 55–87% tokens):
result = h.read("src/app.py", start_line=100, end_line=150)
# result["lines"] — 51 rendered lines, numbered 100–150
# result["total_lines"] — full file length (e.g. 1 200)
# result["version"] — full-file digest, same as a whole-file read
The version is always the full-file blake2s digest, so a windowed read still gives you a valid expected_version to pass to edit().
Error classes
| Error | When it is raised |
|---|---|
VersionConflictError |
The file changed between your last read() and the current edit() or write() |
AnchorMismatchError |
A hash field does not match the current line; the error message includes updated rendered context so the agent can retry immediately |
InvalidOperationError |
The edit payload is structurally invalid (missing field, out-of-range line, no-op replace, etc.) |
PathEscapeError |
The requested path resolves outside the configured root directory |
MixedNewlineError |
The file mixes newline styles (\n, \r\n, \r) and is rejected before mutation |
FileEncodingError |
The file cannot be decoded with the configured encoding (UTF-8 by default) |
All six inherit from HashEditError.
Further reading
- Root README — project overview, TypeScript package, and benchmarks
docs/spec.md— full protocol specificationdocs/INTERFACE_DESIGN.md— design rationale
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hash_edit-0.1.0.tar.gz.
File metadata
- Download URL: hash_edit-0.1.0.tar.gz
- Upload date:
- Size: 7.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89d815a7825038458f8b3974664e85f240cb48e231aa2c20728233fce8bbfe57
|
|
| MD5 |
e027d375dbc19b943dad06d74c5fcc21
|
|
| BLAKE2b-256 |
17a36268dd2a44a7d73db2be8bd60bdb406a70dda2deab74e35b23414c9edf61
|
File details
Details for the file hash_edit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hash_edit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
206a68efa46f39d87a1eb21c5c8abad08deffda618d74acec3115c4e556b0650
|
|
| MD5 |
1877eebd26c90a4e86e701a0cf09541b
|
|
| BLAKE2b-256 |
7c7e3afe09f8511044d6b1bc611d342e2f31d39b7342e597998322bbaf4d14af
|