# Guia de Instalação
[Read in English](INSTALL.md)
- Instruções completas para instalar atomwrite em Linux, macOS e Windows
- Versão alvo atual: v0.1.34 (fuzzy one-shot, timeout padrão 120, exit 124 no prazo esgotado, recipes, sparse, semantic-merge, 41 subcomandos; builds slim/full por features)
- Seções ordenadas por plataforma, com pré-requisitos e solução de problemas
## O Que Há de Novo na v0.1.34
- Publicação docs-complete do runtime one-shot da v0.1.33 (mesmo comportamento do binário)
- Global `--timeout-secs` (alias `--timeout`) **padrão 120** (era 0); `0` desabilita; prazo esgotado → exit **124**
- Multi-apply fuzzy é **one-pass** E→D no conteúdo original (`apply_fuzzy_one_pass`); nunca reescaneia texto inserido
- Máximo de applies fuzzy padrão = **1** se `--max-replacements` omitido; teto rígido 10_000; embeds forçam apply único
- ADR-0054; suíte `cargo test --test cli_v0133_oneshot_fuzzy`
- Pin `^0.1.34` / 41 subcomandos
## O Que Há de Novo na v0.1.12
Esta seção resume as mudanças relevantes para instalação em v0.1.12.
### Instalação (Linux/macOS/Windows)
A release v0.1.12 é um substituto drop-in para v0.1.4. Instale com:
```bash
cargo install atomwrite --locked --version "^0.1.12"
```
O fix do Windows 10/11 de v0.1.4 é preservado (cargo install agora funciona). v0.1.12 adiciona:
- 6 novos subcomandos (`set`, `get`, `del`, `case`, `query`, `outline`) via implementação Tier 3 v14
- G72 verificação de sintaxe REAL via tree-sitter (24 linguagens via `tree-sitter-language-pack`)
- G114 sidecar WAL para recuperação de crash (consultivo, sem auto-replay)
- 5 novos códigos de erro (83 LockTimeout, 88 SyntaxError, 91 ExdevFallbackDisabled, 92 CopyBackBlake3Failed, 93 OrphanJournal)
### Nova Dependência
- `tree-sitter-language-pack = "1.8"` com features `download` + `dynamic-loading`
- Parsers baixam no primeiro uso (~5-10MB footprint total, não empacotados)
- Sem `cargo build` manual ou compilação de fonte necessária para suporte a linguagens
### Notas Específicas do Windows
- v0.1.12 preserva o fix do Windows da v0.1.4: `cargo install atomwrite` funciona no Windows 10/11.
- Melhorias no `init_console` (de v0.1.4) garantem que UTF-8 e sequências ANSI funcionem no Windows Terminal e PowerShell 7+.
- `persist_with_retry` lida com `PermissionDenied` durante rename atômico com backoff exponencial (compensação do Windows Defender).
### Notas Específicas do Linux
- v0.1.12 requer Rust 1.88 ou posterior (igual a v0.1.4).
- `cargo install atomwrite` do crates.io é o caminho de instalação recomendado.
- Sem dependências de nível de sistema além do toolchain Rust padrão.
### Notas Específicas do macOS
- v0.1.12 preserva os fixes de build do macOS arm64 (Apple Silicon) e macOS x86_64 da v0.1.2.
- Gatekeeper pode exigir `xattr -d com.apple.quarantine $(which atomwrite)` no primeiro uso.
- `posix_fadvise` é corretamente gateado a `cfg(target_os = "linux")` apenas (no-op no macOS).
### Cobertura de Testes
- 700+ testes listados (working tree v0.1.34; suíte `cli_v0133_oneshot_fuzzy`)
- ADRs em `docs/decisions/` até 0054
- 38 schemas JSON em `docs/schemas/`
- Veja [docs/decisions/README.md](decisions/README.md) para decisões arquiteturais
## Linux
### Instalação Rápida (Ubuntu/Debian)
```bash
# Instalar Rust 1.88+ via rustup
# Instalar atomwrite v0.1.34 (path/fonte recomendado até o crates.io publicar)
cargo install --path . --locked --force
# Ou pin do crates.io quando 0.1.34 estiver publicada:
# cargo install atomwrite --locked --version "^0.1.34"
# Verificar
atomwrite --version
```
### Instalação Rápida (Fedora/RHEL)
```bash
# Instalar ferramentas de build
sudo dnf install rust cargo gcc
# Preferido: a partir do clone (v0.1.34)
cargo install --path . --locked --force
# Alternativa quando o crates.io publicar 0.1.34:
# cargo install atomwrite --locked --version "^0.1.34"
# Nota: o crates.io pode ainda listar versão mais antiga
```
### Instalação Rápida (Arch)
```bash
sudo pacman -S rust
# Preferido: a partir do clone (v0.1.34)
cargo install --path . --locked --force
# Alternativa quando o crates.io publicar 0.1.34:
# cargo install atomwrite --locked --version "^0.1.34"
# Nota: o crates.io pode ainda listar versão mais antiga
```
## macOS
### Instalação Rápida
```bash
# Instalar Rust 1.88+ via rustup
# Preferido: a partir do clone (v0.1.34)
cargo install --path . --locked --force
# Alternativa quando o crates.io publicar 0.1.34:
# cargo install atomwrite --locked --version "^0.1.34"
# Nota: o crates.io pode ainda listar versão mais antiga
# Liberar no Gatekeeper se solicitado
## Windows 10 / Windows 11
### Pré-Requisitos
1. **Rust 1.88 ou posterior** — instalar via [rustup.rs](https://rustup.rs)
2. **Visual Studio Build Tools 2019 ou posterior** com o workload "Desenvolvimento para desktop com C++" — necessário para linkagem. Baixar de [visualstudio.microsoft.com](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
3. **Windows Terminal** ou **PowerShell 7+** (Windows Terminal recomendado para renderização UTF-8)
4. **Git for Windows** se instalar do código fonte
### Instalação Rápida (do código fonte — preferido)
```powershell
git clone https://github.com/danilo-aguiar-br/atomwrite.git
cd atomwrite
cargo install --path . --locked --force
```
### Instalação Rápida (do crates.io — quando 0.1.34 estiver publicada)
```powershell
# Abrir PowerShell 7+ ou Windows Terminal
rustup default stable
rustup target add x86_64-pc-windows-msvc
# Prefira pin de versão; o crates.io pode ainda listar versão mais antiga
cargo install atomwrite --locked --version "^0.1.34"
# Verificar (esperar saída NDJSON)
atomwrite --version
```
### Solução de Problemas
#### "error: linker 'link.exe' not found"
Instale Visual Studio Build Tools com o workload C++. O instalador está em
<https://visualstudio.microsoft.com/visual-cpp-build-tools/>. Após instalar,
reinicie o terminal para que o PATH atualizado seja carregado.
#### "error[E0433]: failed to resolve: use of undeclared type `AtomwriteError`"
Este bug foi corrigido em v0.1.4. v0.1.12 é um substituto drop-in que também inclui 6 novos subcomandos, G72 verificação de sintaxe real, G114 sidecar WAL, e 5 novos códigos de erro. Certifique-se de
instalar v0.1.12 ou posterior:
```powershell
cargo install atomwrite --locked --version "^0.1.12"
```
Se não puder atualizar, compile do código fonte com o fix aplicado.
#### "error: linking with `link.exe` failed: exit code: 1125"
Antivírus (Windows Defender, McAfee, etc.) está bloqueando o linker. Adicione
exceção para `%USERPROFILE%\.cargo` e `%USERPROFILE%\.rustup`, depois tente
novamente.
#### Mojibake na saída do console
Console legado do Windows (`cmd.exe`) não suporta UTF-8 por padrão. Use
**Windows Terminal** (que ativa UTF-8 automaticamente) ou execute:
```powershell
chcp 65001
```
antes de invocar atomwrite. A função `init_console` do atomwrite também ativa
UTF-8 e sequências ANSI nos handles do console Windows quando executada de
um terminal configurado adequadamente.
#### "operation not permitted" durante escrita atômica
O pipeline de escrita atômica tenta até 3 vezes em caso de `PermissionDenied`.
Se um arquivo está aberto por outro processo (ex.: editor sem liberação
adequada, scanner antivírus, busca indexada), as tentativas podem esgotar.
Feche o arquivo na aplicação que o segura e tente novamente.
## Instalando Versões Específicas
```bash
# Preferido: árvore fonte v0.1.34 (até publicar no crates.io)
cargo install --path . --locked --force
# Pin no crates.io quando 0.1.34 estiver publicada
cargo install atomwrite --locked --version "^0.1.34"
# Pin histórico de exemplo (0.1.28)
cargo install atomwrite --locked --version 0.1.28
# Forçar reinstalação (path ou versão pinada)
cargo install --path . --locked --force
```
A flag `--locked` garante que o `Cargo.lock` seja respeitado, garantindo um build
reproduzível que corresponde ao que os maintainers testaram.
Nota: o crates.io pode ainda listar versão mais antiga depois que a árvore chega em 0.1.34.
Use `cargo install --path . --locked --force` para a árvore que você tem no checkout.
## Verificando Instalação
```bash
atomwrite --version
# Esperar saída NDJSON com versão, data de build e info de plataforma
```
Se o comando não for encontrado, garanta que `~/.cargo/bin` (Linux/macOS)
ou `%USERPROFILE%\.cargo\bin` (Windows) está no seu `PATH`.
## Compilando do Código Fonte (todas plataformas)
```bash
git clone https://github.com/danilo-aguiar-br/atomwrite.git
cd atomwrite
cargo build --release
./target/release/atomwrite --version
```
O binário de release fica em `target/release/atomwrite` (ou `atomwrite.exe`
no Windows).
## Builds Slim vs Full por Features (v0.1.34)
A v0.1.34 expõe features do Cargo para trocar tamanho AST por um binário slim de agente.
| slim (`core` apenas) | `cargo install --path . --locked --force --no-default-features --features core` | ~7.7 MiB | size-gate local ≤15 MiB |
| default (subconjunto AST) | `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` |
### Flags de feature
- `core` — read/write/edit/search/replace atômicos e demais comandos sem AST
- `ast` — stack tree-sitter / ast-grep (`transform`, `scope`, `query`, `outline`, `--syntax-check`)
- `lang-rust` / `lang-ts` / `lang-py` / `lang-go` — packs de linguagem para AST
- `lang-full` — todos os packs de linguagem acima
- `watch` — subcomando `watch` (`notify`)
- `semantic` — helpers semânticos reservados a caminhos opcionais
- `full` — `default` + `lang-full` + `watch` + `semantic`
### Exemplos
```bash
# Instalação slim (agente)
cargo install --path . --locked --force --no-default-features --features core
# Instalação default/full com AST
cargo install --path . --locked --force
# Default mais watch e todas as linguagens
cargo install --path . --locked --force --features full
# Verificar instalação (41 subcomandos no --help)
atomwrite --version
atomwrite --help
```
O crates.io pode ainda publicar versão mais antiga até o maintainer lançar 0.1.34. Prefira
`--path . --force` para esta árvore.
## Verificação de Saúde (G119)
Após instalar v0.1.15 ou posterior, execute os comandos de saúde do WAL para confirmar que os novos subcomandos estão cabeados corretamente. Estas operações são read-only ou de reparo escopado, seguras para smoke tests locais pós-instalação.
### Inspecionar Estado do WAL (read-only)
```bash
atomwrite --workspace . wal-stats
```
Envelope NDJSON esperado (truncado):
```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}
```
O campo `reclaimable` conta journals terminais (Committed ou Aborted) mais antigos que o threshold de obsolescência. Um valor não-zero indica sidecars órfãos elegíveis para limpeza segura.
### Reap de Journals Terminais
A camada G119 L3 adiciona `wal-heal` para remover journals terminais (Committed e Aborted). Nunca toca em entradas Started.
```bash
# Remover todos os journals terminais independentemente da idade (seguro: ignora Started)
atomwrite --workspace . wal-heal --threshold-secs 0
```
Use este comando em smoke tests pós-instalação, hooks de pre-build locais, ou após uma varredura de recuperação de crash.
## Validação Cross-Compile (para contribuidores)
O projeto inclui um gate de cross-compile para detectar erros de compilação
exclusivos de Windows antes do release. Execute:
```bash
# Instalar targets Windows
rustup target add x86_64-pc-windows-gnu
rustup target add x86_64-pc-windows-msvc
# No Linux, instalar mingw-w64 para o target GNU
sudo dnf install mingw64-gcc mingw64-gcc-c++ # Fedora
sudo apt install mingw-w64 # Ubuntu
# Executar gate de cross-compile
cargo test --test cross_compile_check -- --ignored
```
Isto é obrigatório para qualquer release que toque em caminhos de código
`#[cfg(windows)]`, conforme o fix do GAP 14 em v0.1.4 (preservado para referência histórica; instale v0.1.12 ou posterior).
## v0.1.20 — Novidades
Esta release introduz uma nova camada de segurança chamada **intention guards** e renomeia a flag global `--lang` para `--locale` para desambiguar do seletor tree-sitter `--lang` usado por `scope` e `transform`.
### Intention Guards (5 flags OPT-IN)
- `--require-backup <N>` — recusa a operação quando menos de `N` backups retidos existem para o alvo
- `--confirm` — emite um prompt de confirmação listando a mutação planejada em NDJSON antes de executar
- `--auto-rotate <N>` — rotaciona automaticamente o anel de backups para `N` entradas após uma escrita bem-sucedida
- `--risk-threshold <LOW|MEDIUM|HIGH>` — bloqueia operações cujo risco classificado atinge ou excede o threshold
- `--locale <en|pt-BR>` — renomeado de `--lang` para desambiguar do `--lang` tree-sitter
### Outras Adições
- `count --by-size` — lista os maiores arquivos da árvore com tamanhos e contagem de linhas
- `read --mode raw|envelope` — seleciona entre saída byte-stream e envelope NDJSON estruturado
- `search --no-begin-end` — desabilita a decoração implícita de âncoras `^` e `$` na saída regex
- `write --preserve-timestamps` — preserva o mtime do arquivo fonte ao sobrescrever
- `scope --lang rust` — alias explícito aceito para simetria ergonômica com `transform --lang`
### Estatísticas
- 700+ testes listados (working tree v0.1.34)
- 11 GAP-2026 fechados
- 3 targets de cross-compile Windows verdes
- ADRs em `docs/decisions/` até 0051; 38 schemas JSON
### Migração `--lang` para `--locale`
```bash
# Descobrir todos os arquivos com --lang
rg -l -- '--lang\b' .
# Substituir em massa preservando outros matches
fd -e sh -e md -e toml -e yml -e yaml -e json -x sd -- '--lang\b' '--locale' {}
# Ou via ruplacer
ruplacer --subvert --lang --locale
```
## v0.1.21 — Novidades
Esta release fecha 3 GAP-2026 items e altera o comportamento padrão de retenção de backups:
- **`--allow-sequential-drift`** em `edit` — flag opt-in para pipelines de edição sequencial
- **`--backup` paridade 4/4** — `edit` e `rollback` agora aceitam `--backup` (eram hardcoded `false`)
- **`--keep-backup`** em 6 sub-comandos — flag opt-in para preservar o backup após sucesso
- **Mudança de comportamento padrão** — backups são DELETADOS após operações `--backup` bem-sucedidas; adicione `--keep-backup` para preservar
- 555+ testes passando, 1 novo ADR (0038)
## v0.1.22 — Novidades
Esta release adiciona 2 novos sub-comandos para limpeza e padrão de N-edits-em-1-invocação:
- **`prune-backups [PATHS]...`** — limpeza manual de siblings `.bak.YYYYMMDD_HHMMSS` legados
- Flags: `--max-age-secs <SECONDS>`, `--max-count <N>`, `--dry-run` (default true)
- Saída NDJSON com linhas por backup e summary
- **`edit-loop <PATH>`** — aplica N pares `{old, new}` via NDJSON no stdin em 1 invocação
- Flags: `--workspace`, `--expect-checksum`, `--partial`, `--fuzzy`, `--backup`, `--keep-backup`
- Saída NDJSON com `pair_result` por par e summary
- 575+ testes passando, 2 novos ADRs (0039, 0040), 2 novos schemas NDJSON
- 32 sub-comandos totais (de 30 em v0.1.20)
### Instalar v0.1.22
```bash
# Do crates.io
cargo install atomwrite --locked --version "^0.1.22"
# Verificar
atomwrite --version
# Smoke test dos novos sub-comandos
atomwrite --workspace . prune-backups --max-age-secs 86400 .
printf '%s\n' '{"old":"foo","new":"bar"}' \
| atomwrite --workspace . edit-loop src/foo.rs
```