# atomwrite
> Atomic file operations for LLM agents — one CLI, zero corruption
atomwrite is a Rust CLI that provides 33 subcommands for file manipulation with atomic write guarantees. Every write uses tempfile + fsync + rename + directory fsync. Every response is NDJSON with BLAKE3 checksums. Built for LLM agents that need reliable, structured file operations without corruption risk.
**Latest release: v0.1.27** (2026-06-24) — 10 bug fixes across 3 audit rounds: CRITICAL symlink-directory jail escape (BUG-SEC-001), CRITICAL scope --delete code destruction (BUG-SCOPE-004), scope pub visibility for all Rust queries, Go var type-inferred declarations, edit-loop hardened (empty stdin, invalid JSON, pair_results fields). 3 known limitations documented (GAP-01/02/03). 631+ tests, 33 subcommands. See `CHANGELOG.md` for full notes.
**Previous release: v0.1.26** (2026-06-23) — 9 bug fixes (GAP-135 to GAP-147): exit code consistency, scope dual AST patterns, 631 tests. See `CHANGELOG.md`.
## 33 Subcommands
### Core I/O (7)
- `read` — read files with metadata, checksum, optional content. `--mode raw|envelope` selects byte-stream vs NDJSON envelope
- `write` — create or overwrite files atomically via stdin. `--preserve-timestamps` keeps source mtime
- `edit` — surgically edit by line number, text marker, or exact/fuzzy match; multi-pair `--old`/`--new` with per-pair fuzzy cascade, `pair_results` and `--partial` (v0.1.15)
- `delete` — delete files with optional backup
- `copy` — copy files with checksum verification
- `move` — move or rename files atomically (EXDEV copy-fallback)
- `apply` — apply patches from stdin (unified diff, search/replace, full, markdown)
### Search and replace (3)
- `search` — search file contents in parallel (ripgrep engine). `--no-begin-end` disables anchor emission
- `replace` — replace text across files with atomic writes
- `transform` — AST refactoring via ast-grep (306 languages)
### Inspection (9)
- `hash` — calculate BLAKE3 checksums
- `count` — count lines, files by extension. `--by-size` lists largest files
- `diff` — compare two files (unified, stat, or changes)
- `list` — list files in a directory tree
- `extract` — extract fields from NDJSON input via pipe
- `scope` — grammatical scoping (delete all comments, etc.). `--lang rust` alias accepted
- `regex` — generate regex from examples
- `calc` — math and unit conversions
- `completions` — generate shell completions (bash, zsh, fish, elvish, powershell)
### Backup and recovery (3)
- `backup` — create timestamped backups with BLAKE3 checksums
- `rollback` — restore from a previous backup
- `batch` — NDJSON-driven batch operations (transactional)
### Batch helpers (2)
- `edit-loop` — N edits in 1 invocation via JSON array or NDJSON stdin
- `prune-backups` — manual cleanup of legacy `.bak.*` files with `--max-age-secs`, `--max-count`
### WAL diagnostics (2)
- `wal-stats` — snapshot of WAL journal state (counts, ages, sizes)
- `wal-heal` — remove orphan terminal journals older than threshold
### Verification (1)
- `verify <PATH> <HASH>` — verify BLAKE3 checksum of a file (delegates to `hash --verify`)
### Structured config editors (v14 Tier 3, v0.1.12) (4)
- `set <PATH> <KEY_PATH> <VALUE>` — write a value at a dotted path in a TOML or JSON file. Preserves comments and key order via `toml_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-missing` flag treats missing keys as a no-op success.
- `case <PATHS...> --subvert OLD NEW --to <style>` — rename identifiers across multiple files via `heck`. Styles: `snake`, `camel`, `pascal`, `kebab`, `screaming-snake`.
### AST tools (v14 Tier 3 + G72, v0.1.12, via tree-sitter-language-pack) (2)
- `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.
Plus the G72 syntax check on `write --syntax-check` (24 languages, exit 88).
## v0.1.20 Highlights — Intention Guards
- **5 intention-guard flags** form a new safety layer that intercepts destructive mutations before they touch the disk:
- `--require-backup <N>` — refuse the operation when fewer than `N` retained backups exist for the target
- `--confirm` — emit a confirmation prompt listing the planned mutation in NDJSON before executing
- `--auto-rotate <N>` — automatically rotate the backup ring down to `N` entries after a successful write
- `--risk-threshold <LOW|MEDIUM|HIGH>` — block operations whose classified risk meets or exceeds the threshold
- `--locale <en|pt-BR>` — renamed from `--lang` to avoid clashing with the language selector used by `scope` and `transform` (G121+)
- **`count --by-size`** — list the largest files in the tree with sizes and line counts
- **`read --mode raw|envelope`** — select between byte-stream output and structured NDJSON envelope
- **`search --no-begin-end`** — disable the implicit `^` and `$` anchor decoration in regex output
- **`write --preserve-timestamps`** — keep the source file mtime when overwriting
- **542 tests passing** in 47 integration suites, 0 failures, 3 Windows cross-compile targets green
- **19 ADRs** in `docs/decisions/` (0019-0037): v0.1.20 adds 0031 (exit code canonicalization), 0032 (intention guards as new layer), 0033-0037 covering scope/lang alias, locale rename, by-size count, read mode, no-begin-end
## v0.1.20 Migration From v0.1.19
- `--lang` on global config commands is renamed to `--locale` to disambiguate from the tree-sitter `--lang` used by `scope` and `transform`. Use `sd` or `ruplacer` to update existing scripts:
- `rg -l -- '--lang\b' .` then `ruplacer --subvert --lang --locale` (or `fd -e sh -e md -x sd -- '--lang\b' '--locale' {}`)
- Intention guards are OPT-IN. Default behavior is unchanged
- `count --by-size` is ADDITIVE. Default `count` output unchanged
- `read --mode raw` is ADDITIVE. Default envelope output unchanged
- See `docs/MIGRATION.md` for the full upgrade guide
## Primary Documentation
- [README](https://github.com/daniloaguiarbr/atomwrite/blob/main/README.md): Full documentation with all 33 subcommands and examples
- [HOW_TO_USE](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/HOW_TO_USE.md): Quickstart guide
- [COOKBOOK](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/COOKBOOK.md): Recipes for common tasks
- [AGENTS.md](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/AGENTS.md): Agent discovery file with output contract and token budget
- [TESTING](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/TESTING.md): 542 tests across 47 test suites
- [MIGRATION](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/MIGRATION.md): Migration guide between versions
- [INSTALL](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/INSTALL.md): Platform-specific install instructions
- [CROSS_PLATFORM](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/CROSS_PLATFORM.md): macOS, Linux, Windows quirks
- [CHANGELOG](https://github.com/daniloaguiarbr/atomwrite/blob/main/CHANGELOG.md): Release history
- [CONTRIBUTING](https://github.com/daniloaguiarbr/atomwrite/blob/main/CONTRIBUTING.md): Development setup and guidelines
- [SECURITY](https://github.com/daniloaguiarbr/atomwrite/blob/main/SECURITY.md): Vulnerability reporting
- [docs/decisions/](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/decisions/): 29 ADRs (0019-0047, v0.1.12 through v0.1.24 architectural decisions)
- [docs/schemas/](https://github.com/daniloaguiarbr/atomwrite/blob/main/docs/schemas/): 29 stable JSON Schema contracts
- [Crates.io](https://crates.io/crates/atomwrite): Package registry
- [Repository](https://github.com/daniloaguiarbr/atomwrite): Source code