atomwrite 0.1.34

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
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# Installation Guide

[Leia em Português](INSTALL.pt-BR.md)

- Complete instructions for installing atomwrite on Linux, macOS, and Windows
- Current target version: v0.1.34 (one-shot fuzzy, timeout default 120, exit 124 on deadline, recipes, sparse, semantic-merge, 41 subcommands; slim/full feature builds)
- Sections ordered by platform, with prerequisites and troubleshooting


## What's New in v0.1.34

- Docs-complete publish of the v0.1.33 one-shot runtime (same binary behavior)
- Global `--timeout-secs` (alias `--timeout`) **default 120** (was 0); `0` disables; deadline → exit **124**
- Fuzzy multi-apply is **one-pass** L→R on original content (`apply_fuzzy_one_pass`); never re-scans inserted text
- Default max fuzzy applies = **1** if `--max-replacements` omitted; hard ceiling 10_000; embeds force single apply
- ADR-0054; suite `cargo test --test cli_v0133_oneshot_fuzzy`
- Pin `^0.1.34` / 41 subcommands

## What's New in v0.1.12

This section summarizes installation-relevant changes in v0.1.12.

### Installation (Linux/macOS/Windows)

The v0.1.12 release is a drop-in replacement for v0.1.4. Install with:

```bash
cargo install atomwrite --locked --version "^0.1.12"
```

The Windows 10/11 fix from v0.1.4 is preserved (cargo install now succeeds). v0.1.12 adds:

- 6 new subcommands (`set`, `get`, `del`, `case`, `query`, `outline`) via Tier 3 v14 implementation
- G72 REAL syntax check via tree-sitter (24 languages via `tree-sitter-language-pack`)
- G114 WAL sidecar for crash recovery (consultive, no auto-replay)
- 5 new error codes (83 LockTimeout, 88 SyntaxError, 91 ExdevFallbackDisabled, 92 CopyBackBlake3Failed, 93 OrphanJournal)

### New Dependency

- `tree-sitter-language-pack = "1.8"` with `download` + `dynamic-loading` features
- Parsers download on first use (~5-10MB total footprint, not bundled)
- No manual `cargo build` or source compilation required for language support

### Windows-Specific Notes

- v0.1.12 preserves the v0.1.4 Windows fix: `cargo install atomwrite` succeeds on Windows 10/11.
- New `init_console` improvements (from v0.1.4) ensure UTF-8 and ANSI sequences work in Windows Terminal and PowerShell 7+.
- `persist_with_retry` handles `PermissionDenied` during atomic rename with exponential backoff (Windows Defender compensation).

### Linux-Specific Notes

- v0.1.12 requires Rust 1.88 or later (same as v0.1.4).
- `cargo install atomwrite` from crates.io is the recommended installation path.
- No system-level dependencies required beyond the standard Rust toolchain.

### macOS-Specific Notes

- v0.1.12 preserves the v0.1.2 macOS arm64 (Apple Silicon) and macOS x86_64 build fixes.
- Gatekeeper may require `xattr -d com.apple.quarantine $(which atomwrite)` on first run.
- `posix_fadvise` is correctly gated to `cfg(target_os = "linux")` only (no-op on macOS).

### Test Coverage

- 700+ tests listed (v0.1.34 working tree; suite `cli_v0133_oneshot_fuzzy`)
- ADRs in `docs/decisions/` through 0054
- 38 JSON schemas in `docs/schemas/`
- See [docs/decisions/README.md]decisions/README.md for architectural decisions

## Linux

### Quick Install (Ubuntu/Debian)

```bash
# Install Rust 1.88 or later via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# Install atomwrite v0.1.34 (path/source recommended until crates.io catches up)
cargo install --path . --locked --force
# Or pin crates.io when 0.1.34 is published:
# cargo install atomwrite --locked --version "^0.1.34"

# Verify
atomwrite --version
```

### Quick Install (Fedora/RHEL)

```bash
# Install build tools
sudo dnf install rust cargo gcc

# Preferred: from clone (v0.1.34)
cargo install --path . --locked --force
# Alternative when crates.io publishes 0.1.34:
# cargo install atomwrite --locked --version "^0.1.34"
# Note: crates.io may still list an older version
```

### Quick Install (Arch)

```bash
sudo pacman -S rust

# Preferred: from clone (v0.1.34)
cargo install --path . --locked --force
# Alternative when crates.io publishes 0.1.34:
# cargo install atomwrite --locked --version "^0.1.34"
# Note: crates.io may still list an older version
```


## macOS

### Quick Install

```bash
# Install Rust 1.88+ via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# Preferred: from clone (v0.1.34)
cargo install --path . --locked --force
# Alternative when crates.io publishes 0.1.34:
# cargo install atomwrite --locked --version "^0.1.34"
# Note: crates.io may still list an older version

# Allow in Gatekeeper if prompted
xattr -d com.apple.quarantine $(which atomwrite) 2>/dev/null || true
```


## Windows 10 / Windows 11

### Prerequisites

1. **Rust 1.88 or later** — install via [rustup.rs]https://rustup.rs
2. **Visual Studio Build Tools 2019 or later** with the "Desktop development with C++" workload — required for linking. Download from [visualstudio.microsoft.com]https://visualstudio.microsoft.com/visual-cpp-build-tools/
3. **Windows Terminal** or **PowerShell 7+** (Windows Terminal recommended for UTF-8 rendering)
4. **Git for Windows** if installing from source

### Quick Install (from source — preferred)

```powershell
git clone https://github.com/danilo-aguiar-br/atomwrite.git
cd atomwrite
cargo install --path . --locked --force
```

### Quick Install (from crates.io — when 0.1.34 is published)

```powershell
# Open PowerShell 7+ or Windows Terminal
rustup default stable
rustup target add x86_64-pc-windows-msvc

# Prefer a version pin; crates.io may still list an older version
cargo install atomwrite --locked --version "^0.1.34"

# Verify (expect NDJSON output)
atomwrite --version
```

### Troubleshooting

#### "error: linker 'link.exe' not found"

Install Visual Studio Build Tools with the C++ workload. The installer is at
<https://visualstudio.microsoft.com/visual-cpp-build-tools/>. After installation,
restart your terminal so the updated PATH is picked up.

#### "error[E0433]: failed to resolve: use of undeclared type `AtomwriteError`"

This bug was fixed in v0.1.4. v0.1.12 is a drop-in replacement that also includes 6 new subcommands, G72 real syntax check, G114 WAL sidecar, and 5 new error codes. Make sure you install
v0.1.12 or later:

```powershell
cargo install atomwrite --locked --version "^0.1.12"
```

If you cannot upgrade, compile from source with the fix applied.

#### "error: linking with `link.exe` failed: exit code: 1125"

Antivirus (Windows Defender, McAfee, etc.) is blocking the linker. Add an
exclusion for `%USERPROFILE%\.cargo` and `%USERPROFILE%\.rustup`, then retry.

#### Mojibake in console output

Windows legacy console (`cmd.exe`) does not support UTF-8 by default. Use
**Windows Terminal** (which auto-enables UTF-8) or run:

```powershell
chcp 65001
```

before invoking atomwrite. The `init_console` function in atomwrite also
enables UTF-8 and ANSI escape sequences on Windows console handles when run
from a properly configured terminal.

#### "operation not permitted" during atomic write

The atomic write pipeline retries up to 3 times on `PermissionDenied`. If
a file is held open by another process (e.g., editor without proper file
release, antivirus scanner, indexed search), the retry may exhaust. Close
the file in the locking application and retry.


## Installing Specific Versions

```bash
# Preferred: source tree v0.1.34 (until crates.io is published)
cargo install --path . --locked --force

# Pin crates.io when 0.1.34 is published
cargo install atomwrite --locked --version "^0.1.34"

# Historical pin example (0.1.28)
cargo install atomwrite --locked --version 0.1.28

# Force reinstall (path or pinned version)
cargo install --path . --locked --force
```

The `--locked` flag ensures `Cargo.lock` is honored, guaranteeing a reproducible
build that matches what the maintainers tested.

Note: crates.io may still list an older version after the tree reaches 0.1.34. Use
`cargo install --path . --locked --force` for the source tree you have checked out.


## Verifying Installation

```bash
atomwrite --version
# Expect NDJSON output with version, build date, and platform info
```

If the command is not found, ensure `~/.cargo/bin` (Linux/macOS) or
`%USERPROFILE%\.cargo\bin` (Windows) is in your `PATH`.


## Building from Source (all platforms)

```bash
git clone https://github.com/danilo-aguiar-br/atomwrite.git
cd atomwrite
cargo build --release
./target/release/atomwrite --version
```

The release binary is at `target/release/atomwrite` (or `atomwrite.exe` on
Windows).


## Slim vs Full Feature Builds (v0.1.34)

v0.1.34 exposes Cargo features so you can trade AST size for a slim agent binary.

| Profile | Command | Approx size | Notes |
|---|---|---|---|
| slim (`core` only) | `cargo install --path . --locked --force --no-default-features --features core` | ~7.7 MiB | local size-gate ≤15 MiB |
| default (full AST subset) | `cargo install --path . --locked --force` | ~52 MB | `core` + `ast` + `lang-rust` + `lang-ts` + `lang-py` |
| `full` | `cargo install --path . --locked --force --features full` | ~52 MB+ | default + `lang-full` + `watch` + `semantic` |

### Feature flags

- `core` — atomic read/write/edit/search/replace and other non-AST commands
- `ast` — tree-sitter / ast-grep stack (`transform`, `scope`, `query`, `outline`, `--syntax-check`)
- `lang-rust` / `lang-ts` / `lang-py` / `lang-go` — language packs for AST work
- `lang-full` — all language packs above
- `watch``watch` subcommand (`notify`)
- `semantic` — semantic helpers reserved for optional paths
- `full``default` + `lang-full` + `watch` + `semantic`

### Examples

```bash
# Slim agent install (agent-friendly)
cargo install --path . --locked --force --no-default-features --features core

# Default/full install with AST
cargo install --path . --locked --force

# Default plus watch + all languages
cargo install --path . --locked --force --features full

# Verify installation (41 subcommands in --help)
atomwrite --version
atomwrite --help
```

crates.io may still publish an older version until the maintainer ships 0.1.34. Prefer
`--path . --force` for this tree.


## Health Check (G119)

After installing v0.1.15 or later, run the WAL health commands to confirm the new subcommands are wired correctly. These are read-only or scoped-repair operations that are safe to run in local smoke tests after install.

### Inspect WAL State (read-only)

```bash
atomwrite --workspace . wal-stats
```

Expected NDJSON envelope (truncated):

```json
{"type":"result","journals_total":0,"journals_started":0,"journals_committed":0,"journals_aborted":0,"stale_threshold_secs":86400,"reclaimable":0,"action":"stats","elapsed_ms":3}
```

The `reclaimable` field counts terminal journals (Committed or Aborted) older than the stale threshold. A non-zero value indicates orphan sidecars eligible for safe cleanup.

### Reap Terminal Journals

The G119 L3 layer adds `wal-heal` to remove terminal journals (Committed and Aborted). It never touches Started entries.

```bash
# Remove all terminal journals regardless of age (safe: skips Started)
atomwrite --workspace . wal-heal --threshold-secs 0
```

Use this command in post-install smoke tests or after a crash recovery sweep.

## Cross-Compile Validation (for contributors)

The project includes a cross-compile gate to detect Windows-only compilation
errors before release. Run:

```bash
# Install Windows targets
rustup target add x86_64-pc-windows-gnu
rustup target add x86_64-pc-windows-msvc

# On Linux, install mingw-w64 for the GNU target
sudo dnf install mingw64-gcc mingw64-gcc-c++  # Fedora
sudo apt install mingw-w64                     # Ubuntu

# Run the cross-compile gate
cargo test --test cross_compile_check -- --ignored
```

This is required for any release that touches `#[cfg(windows)]` code paths,
per the GAP 14 fix in v0.1.4 (preserved for historical reference, but you should install v0.1.12 or later).


## v0.1.20 — What Is New

This release introduces a new safety layer called **intention guards** and renames the global `--lang` flag to `--locale` to disambiguate from the tree-sitter `--lang` selector used by `scope` and `transform`.

### Intention Guards (5 OPT-IN flags)

- `--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 disambiguate from the tree-sitter `--lang`

### Other Additions

- `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
- `scope --lang rust` — explicit alias accepted for ergonomic symmetry with `transform --lang`

### Statistics

- 700+ tests listed (v0.1.34 working tree)
- 11 GAP-2026 closed
- 3 Windows cross-compile targets green
- ADRs in `docs/decisions/` through 0054; 38 JSON schemas

### Migration `--lang` to `--locale`

```bash
# Discover all files using --lang
rg -l -- '--lang\b' .

# Bulk replace while preserving other matches
fd -e sh -e md -e toml -e yml -e yaml -e json -x sd -- '--lang\b' '--locale' {}

# Or via ruplacer
ruplacer --subvert --lang --locale
```

## v0.1.21 — What Is New

This release closes 3 GAP-2026 items and changes default behavior for backup retention:

- **`--allow-sequential-drift`** on `edit` — opt-in flag for sequential edit pipelines
- **`--backup` parity 4/4**`edit` and `rollback` now accept `--backup` (was hardcoded `false`)
- **`--keep-backup`** on 6 subcommands — opt-in flag to preserve the backup after success
- **Default change** — backups are DELETED after successful `--backup` operations; add `--keep-backup` to preserve
- 555+ tests passing, 1 new ADR (0038)

## v0.1.22 — What Is New

This release adds 2 new subcommands for cleanup and N-edits-in-1-invocation patterns:

- **`prune-backups [PATHS]...`** — manual cleanup of legacy `.bak.YYYYMMDD_HHMMSS` siblings
  - Flags: `--max-age-secs <SECONDS>`, `--max-count <N>`, `--dry-run` (default true)
  - NDJSON output with per-backup lines and summary
- **`edit-loop <PATH>`** — apply N `{old, new}` pairs via NDJSON on stdin in 1 invocation
  - Flags: `--workspace`, `--expect-checksum`, `--partial`, `--fuzzy`, `--backup`, `--keep-backup`
  - NDJSON output with per-pair `pair_result` and summary
- 575+ tests passing, 2 new ADRs (0039, 0040), 2 new NDJSON schemas
- 33 subcommands total (32 from v0.1.22 + `verify` from v0.1.25)

### Install v0.1.22

```bash
# From crates.io
cargo install atomwrite --locked --version "^0.1.22"

# Verify
atomwrite --version

# Smoke test the new subcommands
atomwrite --workspace . prune-backups --max-age-secs 86400 .
printf '%s\n' '{"old":"foo","new":"bar"}' \
  | atomwrite --workspace . edit-loop src/foo.rs
```