atomwrite 0.1.2

Atomic file operations CLI for LLM agents — read, write, edit, search, replace with NDJSON output
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
[Read in Portuguese / Leia em Portugues](README.pt-BR.md)


# atomwrite

> Atomic file operations for LLM agents -- one CLI, zero corruption

[![Crates.io](https://img.shields.io/crates/v/atomwrite)](https://crates.io/crates/atomwrite)
[![License](https://img.shields.io/crates/l/atomwrite)](LICENSE)
[![CI](https://github.com/daniloaguiarbr/atomwrite/actions/workflows/ci.yml/badge.svg)](https://github.com/daniloaguiarbr/atomwrite/actions)


## What Is It
- A single Rust binary that handles every file operation an LLM agent needs
- Read, write, edit, search, replace, diff, copy, move, delete, transform, scope, backup, rollback, apply -- all in one tool
- 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


## 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

### 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: true` on stdout

### BLAKE3 Checksums
- Every `read` and `write` response includes a BLAKE3 hash
- Use `--expect-checksum` for optimistic locking on concurrent edits
- Detect state drift before applying changes

### Parallel Search
- Built on the ripgrep engine for file content search
- Respects `.gitignore` automatically
- 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

### 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 `--pattern` for 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 `--transaction` for all-or-nothing execution with automatic rollback
- All operations in a batch share the same atomic guarantees
- Use `backup` and `rollback` commands for manual snapshot and restore workflows
- One CLI call replaces hundreds of individual tool invocations


## Quick Start
```bash
cargo install atomwrite

# Write a file atomically from stdin
echo "hello world" | atomwrite write src/hello.txt

# Read it back with checksum
atomwrite read src/hello.txt

# Search across a directory
atomwrite search 'hello' src/

# Replace text with atomic writes
atomwrite replace 'hello' 'world' src/

# Evaluate math and unit conversions
atomwrite calc "2 hours + 30 minutes to seconds"
```


## Installation
### From crates.io
```bash
cargo install atomwrite
```

### From source
```bash
git clone https://github.com/daniloaguiarbr/atomwrite.git
cd atomwrite
cargo build --release
```

### Shell Completions
```bash
# Bash
atomwrite completions bash > ~/.local/share/bash-completion/completions/atomwrite

# Zsh
atomwrite completions zsh > ~/.zfunc/_atomwrite

# Fish
atomwrite completions fish > ~/.config/fish/completions/atomwrite.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 `--dry-run` before destructive operations
- Use `--expect-checksum <HASH>` for optimistic locking
- Use `--lang <LOCALE>` to override the display language (en, pt-BR)
- Pipe stdin for `write` and `batch` commands


## Commands

### read
- Read one or more files with metadata, size, permissions, and BLAKE3 checksum
- Use `--stat` to skip file content and return only metadata
```bash
atomwrite read src/main.rs
```

### write
- Create or overwrite a file atomically from stdin
- Returns the BLAKE3 checksum of the written content
- Use `--line-ending lf|crlf|cr|auto` to normalize line endings (default: auto preserves original)
```bash
echo "fn main() {}" | atomwrite write src/main.rs
```

### edit
- Surgically edit a file by line number, text marker, or exact match
- Supports insert, replace, and delete operations
- Use `--expect-checksum` to prevent concurrent edit conflicts
- Use `--fuzzy auto|off|aggressive` for fuzzy text matching
- Use `--line-ending lf|crlf|cr|auto` to normalize line endings
- Use `--multi` to apply multiple edits via NDJSON stdin in a single atomic write
```bash
echo "new content" | atomwrite edit src/main.rs --after-line 5
atomwrite edit src/main.rs --old "old text" --new "new text"
```

### search
- Search file contents in parallel using the ripgrep engine
- Returns structured matches with file, line, column, and context
- Exits with code 1 when zero matches are found (not an error)
- Use `--context N` for surrounding context lines
- Use `--max-count N` to limit matches per file
- Use `--invert` to show lines without a match
- Use `--sort path` to sort results by file path
```bash
atomwrite search 'TODO' src/ --include '*.rs'
```

### replace
- Replace text across files with atomic writes
- Supports regex patterns and literal strings
- Use `--dry-run` to preview changes
```bash
atomwrite replace 'old_name' 'new_name' src/ --include '*.rs'
```

### hash
- Calculate BLAKE3 checksums for one or more files
```bash
atomwrite hash src/main.rs src/lib.rs
```

### delete
- Delete files with optional backup before removal
- Use `--backup` to create a `.bak` copy first
```bash
atomwrite delete src/temp.rs --backup
```

### count
- Count lines in files or count files by extension in a directory
```bash
atomwrite count src/ --by-extension
```

### diff
- Compare two files with unified, stat, or changes-only output
```bash
atomwrite diff src/old.rs src/new.rs --unified
```

### move
- Move or rename files atomically
- Falls back to copy+delete for cross-device moves
```bash
atomwrite move src/old.rs src/new.rs
```

### copy
- Copy files with BLAKE3 checksum verification after copy
```bash
atomwrite copy src/template.rs src/new_module.rs
```

### list
- List project file structure with metadata
- Respects `.gitignore` by default
```bash
atomwrite list src/ --depth 2
```

### extract
- Extract fields from NDJSON input or text columns from stdin
```bash
atomwrite search 'TODO' src/ | atomwrite extract path line
```

### calc
- Evaluate math expressions and unit conversions
- Powered by fend for arbitrary-precision arithmetic
```bash
atomwrite calc "2 GiB to bytes"
atomwrite calc "sqrt(144) + 3^2"
```

### regex
- Generate regex patterns from example strings
- Powered by grex for automatic inference
```bash
atomwrite regex "2024-01-15" "2025-12-31" "2026-06-01"
```

### transform
- Structural AST search and rewrite powered by ast-grep
- Covers 306 programming languages
- Both `--pattern` and `--rewrite` are required
```bash
atomwrite transform -p 'println!($$$ARGS)' -r 'tracing::info!($$$ARGS)' -l rust src/
atomwrite transform -p 'console.log($$$ARGS)' -r 'logger.info($$$ARGS)' -l js src/
```

### batch
- Execute multiple operations from an NDJSON manifest on stdin
- Supports write, replace, delete, edit, hash, move, and copy operations
- Use `--transaction` for all-or-nothing execution with automatic rollback
```bash
cat manifest.ndjson | atomwrite batch
cat manifest.ndjson | atomwrite batch --transaction
```

### scope
- Grammatical scoping: select AST categories and apply actions
- Use `--query` for prepared queries (fn, comments, strings, struct, etc.)
- Use `--pattern` for custom AST patterns
- Use `--delete` to remove matched content or `--action upper|lower|titlecase|squeeze`
- Covers Rust, Python, JavaScript, TypeScript, and Go
```bash
atomwrite scope src/ --lang rust --query comments --delete
atomwrite scope src/ --lang rust --query fn --action upper --dry-run
```

### backup
- Create timestamped backups of files with BLAKE3 checksums
- Use `--retention N` to control how many backups to keep
```bash
atomwrite backup src/config.toml
atomwrite backup src/main.rs src/lib.rs --retention 3
```

### rollback
- Restore a file from a previous backup
- Use `--verify` to check BLAKE3 checksum after restoration
```bash
atomwrite rollback src/config.toml
atomwrite rollback src/config.toml --timestamp 20260530_120000
```

### apply
- Apply a patch from stdin (unified diff, SEARCH/REPLACE blocks, or full file replacement)
- Auto-detects patch format or use `--format` to specify
```bash
echo "new content" | atomwrite apply src/file.txt --format full
git diff src/file.txt | atomwrite apply src/file.txt --format unified
```

### completions
- Generate shell completion scripts for bash, zsh, fish, elvish, or PowerShell
```bash
atomwrite completions bash
```


## Environment Variables
- `NO_COLOR`: disable colored output when set to any value
- `RUST_LOG`: control log verbosity (e.g., `RUST_LOG=debug`)
- `ATOMWRITE_LANG`: override locale for translated messages (e.g., `en`, `pt-BR`)
- `RAYON_NUM_THREADS`: override number of parallel threads for search, replace, transform and scope


## Exit Codes
- `0`: success
- `1`: no matches found (search, not an error)
- `4`: file not found
- `13`: permission denied
- `28`: disk full (no space left on device)
- `30`: quota exceeded
- `65`: invalid input (bad arguments or malformed data)
- `73`: cross-device rename (filesystem boundary)
- `74`: I/O error
- `78`: configuration invalid
- `82`: state drift (checksum mismatch, optimistic lock failed)
- `85`: FIFO detected (named pipe cannot be atomically written)
- `86`: device file detected (block or character device)
- `126`: workspace jail violated (path escapes workspace)
- `127`: symlink blocked (symlink target outside workspace)
- `128`: file immutable (cannot modify)
- `130`: interrupted by SIGINT
- `141`: broken pipe (SIGPIPE)
- `143`: terminated by SIGTERM
- `255`: 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) or `exit` (Windows)
- Walker threads (search, replace, transform, scope) stop between files
- Batch operations stop between operations
- Unsupported platforms: signal handlers are not installed (warning logged)


## Error Handling
- All errors emit a JSON object on stdout with `error: true`
- Error fields: `code`, `exit`, `message`, `path`, `error_class`, `retryable`, `suggestion`
- Error classes: `permanent`, `transient`, `conflict`, `precondition_failed`
- Transient and conflict errors set `retryable: true`
- The `suggestion` field provides actionable recovery guidance for agents


## Performance
- Single static binary with zero runtime dependencies
- Release builds use LTO, single codegen unit, and symbol stripping
- Memory-mapped file reads via `memmap2` for 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
- `write` reads from stdin and waits for EOF
- Example: `echo "content" | atomwrite 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 `move` across devices
- Use `copy` followed by `delete` as 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 `--workspace` boundary
- Verify the path does not contain `..` traversals or symlinks escaping the workspace


## Architecture
- See [ARCHITECTURE.md]ARCHITECTURE.md for module map, data flow, and design decisions


## Contributing
- See [CONTRIBUTING.md]CONTRIBUTING.md for development setup and guidelines


## Security
- See [SECURITY.md]SECURITY.md for vulnerability reporting


## Changelog
- See [CHANGELOG.md]CHANGELOG.md for release history


## License
- Licensed under MIT OR Apache-2.0
- See [LICENSE-MIT]LICENSE-MIT and [LICENSE-APACHE]LICENSE-APACHE for details