Read in Portuguese / Leia em Portugues
atomwrite
Atomic file operations for LLM agents -- one CLI, zero corruption
What Is It
- A single Rust binary that handles every file operation an LLM agent needs
- 28 subcommands: read, write, edit, search, replace, hash, delete, count, diff, move, copy, list, extract, calc, regex, transform, scope, batch, backup, rollback, apply, set, get, del, case, query, outline, completions
- Every write is atomic: tempfile, fsync, rename, fsync directory
- Every response is NDJSON: one JSON object per line, machine-readable by default
- Every file gets a BLAKE3 checksum: detect drift, verify integrity, enable optimistic locking
What Is New In v0.1.12 (2026-06-07)
- 6 new subcommands (v14 Tier 3):
set,get,del,case,query,outlinefor structured config editing and AST analysis - G72 REAL syntax check --
atomwrite write --syntax-checkinvokes the realtree-sitterparser (24 languages covered) instead of the bracket-balance heuristic. Exit code 88 on the first syntax error - G114 WAL sidecar for crash recovery --
atomic_writewrites.atomwrite.journal.<target>.atomwrite.journal.jsonwithStartedandCommittedentries.recover_orphan_journals(dir)is consultative: reports orphans without auto-replay - 5 new error variants:
LockTimeout(83),SyntaxError(88),ExdevFallbackDisabled(91),CopyBackBlake3Failed(92),OrphanJournal(93). All bilingual EN/PT-BR with actionableErrorContextsuggestions - Dependency added:
tree-sitter-language-pack = "1.8"withdownload+dynamic-loadingfeatures. Parsers download on first use, install footprint stays around 5-10 MB instead of 1+ GB - 445 tests passing (was 320 baseline in v0.1.10, +125 new across v0.1.11 and v0.1.12). 43 integration test suites, 0 failures
- 7 ADRs in
docs/decisions/documenting all architectural decisions for v0.1.12 (tree-sitter-language-pack choice, WAL sidecar design, query/outline kind-name only, etc.) - 7 new JSON Schemas in
docs/schemas/(set, get, del, case, query, outline, wal-recovery)
See docs/HOW_TO_USE.md for the full v0.1.12 quickstart and docs/MIGRATION.md for the v0.1.11 → v0.1.12 upgrade path. v0.1.11 is the previous release.
What Was New In v0.1.11 (2026-06-05)
signal_test::shutdown_message_on_stderrno longer fails on Windows CI (windows-2025-vs2026) —libc::write(STDERR_FILENO, ...)was moved fromsrc/main.rstosrc/signal.rsand gated by#[cfg(unix)]. The Windowsctrlcpath was kept as-is. Also added anEAGAINandEINTRretry loop to make the write robust against interrupted syscalls and tight pipe buffer limits in CI sandboxes- Race-free readiness detection in
signal_test— The test now setsATOMWRITE_READY_FILEto a path under the tempdir, and atomwrite writes its PID there as soon asinstall_handlers_earlyreturns. The test polls the file with a 10 s deadline before sending SIGINT, eliminating the microsecond window where SIGINT could race withposix_spawnand arrive before the kernel'ssigactionis configured - Idempotent signal-handler installation —
install_handlers_earlyandinstall_handlersnow share a singleArc<ShutdownSignal>via aOnceCell. Previously each function created its own instance, and only the first instance was flipped by the signal-hook chain, so the main thread'sis_shutdown()check stayedfalseand the banner was never written
What Was New In v0.1.10 (2026-06-05)
- GAP 20 follow-up:
signal_test::shutdown_message_on_stderrflushes the shutdown message viaio::stderr().lock(). The v0.1.8 fix movedeprintln!from the signal handler to the main thread but usedwriteln!(io::stderr(), ...)which is fully buffered when stderr is redirected to a pipe. The fix uses theStderrLockguard that flushes on Drop
What Was New In v0.1.8 (2026-06-05)
signal_test::shutdown_message_on_stderrno longer fails on Linux CI —eprintln!removed from SIGINT/SIGTERM signal handlers per POSIX.1-2017signal-safety(7). Message now emitted by main thread insrc/main.rsafteratomwrite::runreturnsatomic::tests::create_backup_and_retentionno longer fails on Windows CI —platform::fsync_file_best_effortlogs a warning and continues onERROR_ACCESS_DENIED- CI matrix pinned to
windows-2025-vs2026— Replacedwindows-latestto silence migration NOTICE
What Was New In v0.1.7 (2026-06-05)
- CI GitHub Actions fully green — All 6 jobs (check matrix x3, deny, doc, msrv, security) pass after fixing 4 distinct failures
- MSRV bumped to 1.88 — Required to allow
time0.3.47 which resolves RUSTSEC-2026-0009 - GitHub Actions Node 24 ready —
actions/checkout@v6,actions/cache@v5,FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true - Cross-compile Windows validated locally on macOS — Both
x86_64-pc-windows-gnuandi686-pc-windows-gnupasscargo check,cargo build,cargo clippy --all-targets --all-features -- -D warnings, andcargo test --no-run
What Was New In v0.1.4
cargo install atomwriteworks on Windows 10/11 — Three compilation errors in#[cfg(windows)]blocks are fixed (E0433, E0507, E0308)- Context-aware error suggestions —
WorkspaceJailsuggestion adapts when--workspaceis already provided - Cross-compile gate —
tests/cross_compile_check.rsfails on anyE0433,E0308, orE0507regression incfg(windows)blocks
What Was New In v0.1.3
--preserve-timestampsflag oneditandreplaceto control file mtime (default: mtime is updated to reflect the change)mtime_preservedfield inEditOutputandReplaceResultNDJSON responses- BREAKING: atomic write no longer preserves the original file mtime by default. Fixes a silent no-op in
cargo build/make/cmake/gradle
Why
- LLM agents juggle dozens of shell commands to manipulate files
- A single power failure or crash mid-write corrupts the file
- Parsing unstructured CLI output wastes tokens and causes hallucinations
- Agents need checksums to detect concurrent edits but rarely compute them
- atomwrite solves all four problems with one
cargo install
Superpowers
Atomic Writes
- Uses tempfile + fsync + rename + directory fsync on every write
- Guarantees all-or-nothing: the file is never left half-written
- Survives power loss, OOM kills, and SIGKILL
- Optional G72 REAL syntax check via tree-sitter (
--syntax-checkflag onwrite) - Optional G114 WAL sidecar for crash recovery (
.atomwrite.journal.<target>.atomwrite.journal.json)
NDJSON Output
- stdout is ALWAYS structured JSON, one object per line
- Every object carries a
"type"discriminator field - Agents parse output without regex or brittle text scraping
- Errors also emit JSON with
error: trueon stdout
BLAKE3 Checksums
- Every
readandwriteresponse includes a BLAKE3 hash - Use
--expect-checksumfor optimistic locking on concurrent edits - Detect state drift before applying changes
Parallel Search
- Built on the ripgrep engine for file content search
- Respects
.gitignoreautomatically - Returns structured matches with file, line, column, and context
AST-Aware Transforms
- Structural search and rewrite powered by ast-grep
- Covers 306 programming languages
- Refactor code by syntax tree, not fragile regex
- New
queryandoutlinesubcommands walk tree-sitter ASTs (305 languages) viatree-sitter-language-pack
Grammatical Scoping
- Select AST categories like comments, functions, classes, and strings
- Apply actions: delete, uppercase, lowercase, titlecase, squeeze, or replace
- Covers Rust, Python, JavaScript, TypeScript, and Go with prepared queries
- Use
--patternfor custom AST patterns beyond the built-in queries
Batch Operations
- Execute write, replace, delete, edit, hash, move, and copy operations from an NDJSON manifest
- Use
--transactionfor all-or-nothing execution with automatic rollback - All operations in a batch share the same atomic guarantees
Structured Config Editing (v0.1.12)
setwrites a value at a dotted path in TOML or JSON files (preserves comments viatoml_edit)getreads a value at a dotted path with auto-detected formatdelremoves a key (with--force-missingto treat missing keys as no-op success)caserenames identifiers across multiple files viaheck(snake, camel, pascal, kebab, screaming-snake)
Quick Start
# Write a file atomically from stdin
|
# Read it back with checksum
# Search across a directory
# Replace text with atomic writes
# Evaluate math and unit conversions
# v0.1.12: set a value in a TOML file (preserves comments)
# v0.1.12: walk the AST of a Rust file
# v0.1.12: extract the outline of a Python file
# v0.1.12: REAL tree-sitter syntax check before committing
|
Installation
From crates.io
From source
Shell Completions
# Bash
# Zsh
# Fish
Usage
- All output goes to stdout as NDJSON
- All logs go to stderr (only with
--verbose) - Use
--workspace <DIR>to restrict operations to a project root - Use
ATOMWRITE_WORKSPACEto set the workspace root via env var - Use
--dry-runbefore destructive operations - Use
--expect-checksum <HASH>for optimistic locking - Use
--lang <LOCALE>to override the display language (en, pt-BR) - Pipe stdin for
writeandbatchcommands
Commands (28 total)
Core I/O
read— read files with metadata, checksum, optional contentwrite— create or overwrite files atomically via stdinedit— surgically edit by line number, text marker, or exact matchdelete— delete files with optional backupcopy— copy files with checksum verificationmove— move or rename files atomically (EXDEV copy-fallback)apply— apply patches from stdin (unified diff, search/replace, full, markdown)
Search and replace
search— search file contents in parallel (ripgrep engine)replace— replace text across files with atomic writestransform— AST refactoring via ast-grep (306 languages)
Inspection
hash— calculate BLAKE3 checksumscount— count lines, files by extensiondiff— compare two files (unified, stat, or changes)list— list files in a directory treeextract— extract fields from NDJSON input via pipescope— grammatical scoping (delete all comments, etc.)regex— generate regex from examplescalc— math and unit conversionscompletions— generate shell completions (bash, zsh, fish, elvish, powershell)
Backup and recovery
backup— create timestamped backups with BLAKE3 checksumsrollback— restore from a previous backupbatch— NDJSON-driven batch operations (transactional)
Structured config editors (v0.1.12, v14 Tier 3)
set <PATH> <KEY_PATH> <VALUE>— write a value at a dotted path in a TOML or JSON file. Preserves comments and key order viatoml_edit. Auto-coerces int/bool/float/string.get <PATH> <KEY_PATH>— read a value at a dotted path. NDJSON:{"type":"get","key_path","value","found","format"}.del <PATH> <KEY_PATH>— remove a key.--force-missingflag treats missing keys as a no-op success.case <PATHS...> --subvert OLD NEW --to <style>— rename identifiers across multiple files viaheck. Styles:snake,camel,pascal,kebab,screaming-snake.
AST tools (v0.1.12, v14 Tier 3 + G72, via tree-sitter-language-pack)
query <PATH> [--kinds|--query <KIND>|-Q <KIND>|--tree] [--positions]— walk a tree-sitter AST and emit nodes as NDJSON. 305 languages supported.outline <PATH> [--kind <KIND>] [--positions]— extract high-level structure (functions, classes, structs, enums, traits, modules) as NDJSON.write --syntax-check— G72 REAL syntax check via tree-sitter. 24 languages covered. Exit 88 with first error line/column/kind/message.
Common patterns for each subcommand
# read
# write
|
# edit
# search
# replace
# hash
# delete
# count
# diff
# move
# copy
# list
# extract
|
# calc
# regex
# transform
# scope
# batch
|
# backup
# rollback
# apply
|
# set (v0.1.12)
# get (v0.1.12)
# del (v0.1.12)
# case (v0.1.12)
# query (v0.1.12)
# outline (v0.1.12)
# completions
Environment Variables
NO_COLOR: disable colored output when set to any valueRUST_LOG: control log verbosity (e.g.,RUST_LOG=debug)ATOMWRITE_LANG: override locale for translated messages (e.g.,en,pt-BR)ATOMWRITE_WORKSPACE: set the workspace root for path jail validation (alternative to--workspace)RAYON_NUM_THREADS: override number of parallel threads for search, replace, transform and scope
Exit Codes
0: success1: no matches found (search, not an error)4: file not found13: permission denied28: disk full (no space left on device)30: quota exceeded65: invalid input (bad arguments or malformed data)73: cross-device rename (filesystem boundary)74: I/O error78: configuration invalid81: checksum verify failed82: state drift (checksum mismatch, optimistic lock failed)83: lock timeout (v0.1.12+)85: FIFO detected (named pipe cannot be atomically written)86: device file detected (block or character device)88: syntax error detected (v0.1.12+,--syntax-checkfailed)91: EXDEV fallback disabled (v0.1.12+,--strict-atomicforbids cross-device copy-fallback)92: copy-back BLAKE3 verification failed (v0.1.12+)93: orphan journal detected (v0.1.12+, G114 consultive recovery)126: workspace jail violated (path escapes workspace)127: symlink blocked (symlink target outside workspace)128: file immutable (cannot modify)130: interrupted by SIGINT141: broken pipe (SIGPIPE)143: terminated by SIGTERM255: internal error
Signal Handling
- Unix: SIGINT (Ctrl+C) and SIGTERM intercepted for graceful shutdown
- Unix: SIGPIPE reset to SIG_DFL for standard pipe behavior (exit 141)
- Windows: Ctrl+C intercepted via console handler
- First signal: sets shutdown flag, prints "shutting down..." to stderr
- Second signal: immediate process termination via
_exit(Unix) orexit(Windows) - Walker threads (search, replace, transform, scope) stop between files
- Batch operations stop between operations
Error Handling
- All errors emit a JSON object on stdout with
error: true - Error fields:
code,exit,message,path,error_class,retryable,suggestion,workspace - Error classes:
permanent,transient,conflict,precondition_failed - 25 error variants total (20 baseline from v0.1.4 + 5 added in v0.1.12)
- Transient and conflict errors set
retryable: true - The
suggestionfield provides actionable recovery guidance for agents - See
docs/schemas/error-output.schema.jsonfor the full contract
Performance
- Single static binary with zero runtime dependencies
- Release builds use LTO, single codegen unit, and symbol stripping
- Memory-mapped file reads via
memmap2for large files - Parallel search via rayon and the ripgrep engine
- Typical file operation latency: under 5 ms for small files
Troubleshooting FAQ
atomwrite write hangs with no output
- Ensure you are piping content to stdin
writereads from stdin and waits for EOF- Example:
echo "content" | atomwrite --workspace . write file.txt
search returns exit code 1
- Exit code 1 means zero matches were found
- This is expected behavior, not an error
- Check the pattern and target path
cross-device rename fails with exit 73
- The source and destination are on different filesystems
- atomwrite falls back to copy+delete for
moveacross devices - Use
copyfollowed bydeleteas an alternative
checksum mismatch with exit 82
- Another process modified the file between read and write
- Re-read the file to get the current checksum
- Retry the operation with the updated
--expect-checksum
workspace jail violated with exit 126
- The target path resolves outside the
--workspaceboundary - Verify the path does not contain
..traversals or symlinks escaping the workspace
syntax check failed with exit 88 (v0.1.12+)
- The G72 REAL tree-sitter syntax check found a syntax error in the file
- Inspect the first error line/column/kind/message in the JSON error envelope
- Fix the syntax and retry, or remove
--syntax-checkto bypass
Architecture
- See ARCHITECTURE.md for module map, data flow, and design decisions
- See docs/decisions/ for 7 ADRs covering v0.1.12 architecture (G72, G114, v14 Tier 3)
- See docs/schemas/ for 22 stable JSON Schema contracts for all NDJSON output
Contributing
- See CONTRIBUTING.md for development setup and guidelines
- See docs/decisions/README.md for the decision log
Security
- See SECURITY.md for vulnerability reporting
- See SECURITY.md section "Known Security Advisories" for resolved and active advisories
Changelog
- See CHANGELOG.md for English release history
- See CHANGELOG.pt-BR.md for Portuguese release history
License
- Licensed under MIT OR Apache-2.0
- See LICENSE-MIT and LICENSE-APACHE for details