Skip to content

v0.39.4

Choose a tag to compare

@github-actions github-actions released this 18 Jun 13:47
· 2523 commits to main since this release

v0.39.4: clearer signals, no surprise blocks, tighter listings

A patch focused on closing gaps where AFT did the right thing but withheld the information needed next: a sync wait that turned a busy bridge into a red failure, diagnostics that reported a count without the message, and formatter reflows that left a follow-up edit anchored on stale text. Plus a clean fix for external-path access under restrict_to_project_root, and folded ls/find output that keeps the entry that matters.

bash_watch no longer fails on a busy bridge

A sync bash_watch polls the bridge while it waits. Each poll carried a 30-second transport timeout, so if the bridge was briefly busy (a background scan, a parallel tool call), one poll could time out and abort the whole watch — surfacing a red "bash_status timed out after 30000ms" even though the task was fine and the bridge stayed warm. Re-issuing the watch hit the same window, repeating the failure. A busy-bridge poll timeout now means "retry," not "the watch failed": the wait continues to its own deadline, and only reports a graceful "bridge stayed busy" if it genuinely can't read status in time. A real command failure still surfaces immediately.

aft_inspect shows the diagnostic, not just a count

aft_inspect reported diagnostics: 1 errors but kept the message and location behind the sections parameter, like the other categories. A bare count isn't actionable — there's no fixing "1 error" without knowing what and where. Diagnostics detail (message + file:line) is now always included, capped by topK. It self-suppresses when there are no diagnostics, so a clean inspect costs nothing extra. The other categories (dead code, unused exports, duplicates) stay behind sections — their detail can run to hundreds of rows and a count there is a useful at-a-glance signal.

Edits surface formatter reflows

When the project formatter reflows an edit — rustfmt splitting a one-line call across four lines, Prettier re-wrapping an object — the file on disk no longer matches the submitted text. A follow-up edit anchored on the original text could then fail to match. Edit results now show the reflowed region's on-disk text when the formatter changed the edit, so the next edit can re-anchor on what's actually there. It only appears when a reflow happened; a no-op format adds nothing.

restrict_to_project_root blocks cleanly (#125)

With restrict_to_project_root: true, reading or globbing a path outside the project failed after you granted the permission prompt — the grant never reached the isolation boundary, so access was approved and then refused. restrict_to_project_root is AFT's full-isolation knob and is no longer tied to the host permission system: an out-of-project path is blocked up front with a clear explanation (and a note on how to allow external paths), instead of a prompt that can't be honored. With the setting off (the default), external paths work exactly as before.

ls and find keep the entry that matters

Long ls/find output was compressed by truncation, which dropped entries from the middle of the listing — including the specific file being searched for. Runs of similar names now fold to a single summary line (module_*.ts — 200 files (module_000.ts … module_199.ts)) while any structurally distinct entry stays in the listing verbatim. A 200-file directory collapses to a few lines, and the one distinct outlier survives.

Smaller refinements

aft_zoom suggests close symbol names when a requested symbol isn't found. aft_callgraph marks edges resolved by name alone with a trailing ~, so a possibly-wrong same-name match is distinguishable from an exact one; the marker is explained in the tool description.