# v0.39.1: lighter background CPU, sharper Code Health, and a calmer bash watch

A patch focused on what AFT does while you work: the background scans cost far less CPU per edit, Code Health gets more accurate, and a couple of sharp edges are filed off.

## Background scans barely touch your CPU now

Tier-2 (dead code, unused exports, duplicates) re-checked file freshness by re-hashing every file in the project on each change. It now compares file stat metadata and only re-reads the file that actually changed — about 10x less work per edit, and the gain grows with repository size. This is the background-CPU cost that large-repo users felt after every save.

A companion fix makes the watcher recover correctly when the OS drops filesystem events under load (a large checkout or branch switch): instead of silently missing changes, it falls back to a single project rescan.

## Code Health accuracy

- Modules imported only for their side effects (`import "./setup"`) no longer make their exports look dead, and reachable code behind them is counted.
- After a failed incremental refresh, stale call-graph rows are no longer projected as if fresh — dead-code results report honestly instead of showing wrong counts.
- Editing a `tsconfig`/`jsconfig` (including `extends` chains and a package's own `tsconfig` field) now correctly invalidates dead-code and unused-export results that depend on path resolution.
- `aft_search` reports files it couldn't read instead of silently counting them as zero matches.

## Code Health speed

The call-graph cold build is about 13% faster, and the incremental call-graph reads, oxc reachability pass, and search-index cold build all do less redundant work. Results are unchanged.

## Fixes

- **bash watch could freeze the host.** A sync `bash_watch` with a regex pattern compiled and ran that regex on the host event loop; a pathological pattern over large output could hang the UI. Regex matching now runs in the Rust engine (linear, no catastrophic backtracking), and sync/async watches now share the same line-anchor semantics.
- **apply_patch checkpoints and diffs.** A multi-hunk patch that touched the same file twice could lose the original from the undo checkpoint or report the wrong per-file diff. Checkpoints now snapshot every touched path up front, and metadata is tracked per hunk.

## Quality of life

- `aft_zoom` accepts space-separated symbol names in the `symbols` string for code files (e.g. `"foo bar baz"`), splitting them into separate lookups.
- The "use aft_search" nudge on bash `grep` no longer fires when the search targets a path outside the project, where `aft_search` wouldn't help.
- The sidebar remembers its collapsed state across restarts, sorts predictably alongside other CortexKit sidebars, and lets you hide individual sections via `tui-preferences.jsonc`.

---

Questions or feedback? Join us on [Discord](https://discord.gg/DSa65w8wuf).
