v0.39.0
v0.39.0: Code Health that's accurate, incremental, and barely touches your CPU
This release makes Code Health trustworthy and cheap: the dead-code numbers are correct, and the background scans now reparse only the file you changed instead of the whole project on every edit. Plus R language support and pending diffs in edit approval prompts.
Code Health: accurate Rust dead code
The dead-code analyzer was flagging constructors and associated functions as dead even when they had real callers. Type::new() calls resolved through receiver-type inference were being discarded, so anything reached only that way looked unused. On AFT's own source this over-reported by ~80 symbols — the entire ::new false-positive cluster. Those calls now count toward liveness, while looser name-only matches stay excluded to avoid the opposite error.
Code Health: scans no longer rescan the whole project on every edit
Tier-2 scans (dead code, unused exports, duplicates) used to re-parse every file in the project after each change — a CPU burst of several seconds on a mid-sized repo, far worse on large ones, every time you saved. This was the background-CPU complaint behind several reports.
The scan now caches each file's local facts and reparses only the file that actually changed; the cross-file liveness pass runs over cached facts with no re-parsing. On AFT's repo a single-file edit dropped the dead-code parse from re-reading ~1,800 files to exactly one — measured live at ~130ms of scan work where it used to be ~3 seconds. Results are byte-identical to a full cold scan, verified across importer-removal, file-deletion, rename, barrel/pub use re-exports, tsconfig alias changes, cross-file type references, and manifest entry-point edits.
The two earlier per-scan optimizations are still in here too: dead-code edge lookups went from quadratic to grouped (a ~5x cold-scan speedup on this repo), and the call-graph cold build got ~14% faster.
R language support
.R/.r files now work in aft_outline, aft_zoom, and the AST tools (ast_grep_search/ast_grep_replace). Functions (including the name <- function(...) assignment form), top-level assignments, and calls extract with correct ranges. (#112)
Pending diff in edit approval prompts
When OpenCode asked for approval on an AFT edit, the prompt showed No diff provided instead of the pending change — you couldn't review an edit before approving it. AFT now computes the diff before asking: write diffs the new content client-side, edit previews its transform without committing, and apply_patch previews through the same applier it commits with, so the diff you approve is exactly what gets written. (#115)
Fixes
- Code-search guidance now appears for
grep/rganywhere in a command chain, not only when it leads — multi-statement scripts were slipping through. - The Tier-2 staleness ceiling that forces a refresh during continuous editing was raised from 10 to 30 minutes, so a long refactor no longer triggers a mid-session scan of half-applied changes.
- The bundled tokenizer data is regenerated atomically, so a concurrent build can't observe a half-written file.
Questions or feedback? Join us on Discord.