v0.37.0
v0.37.0: Lower CPU, leaner tools
This release attacks the two complaints we heard most: AFT processes burning CPU in the background, and tool output/descriptions eating more of the agent's context than they should. It also removes a tool, trims several others, and lands a batch of correctness fixes across edits, imports, and search.
Much lower background CPU
A set of independent fixes targeting sustained CPU usage and spikes:
- Idle bridges shut down after 30 minutes. Previously a bridge process stayed alive for every project you touched until the host exited. Bridges with running background tasks are never evicted, and a fresh bridge restores them on the next call.
- Deleted project roots no longer spin the watcher. Removing a directory a bridge was watching (a worktree, a temp checkout) flooded it with delete events and pinned a core; the bridge now detects the deleted root and stops watching.
- Background code-health scans reuse warm caches instead of re-parsing the project from scratch on every debounce, and their parsing pool is bounded to half your cores.
- Semantic index loads and saves stream to disk instead of materializing multi-hundred-MB buffers, and the embedding pipeline no longer clones every batch.
- Cold symbol scans read each file once instead of twice, and cold search-index builds parse in parallel.
aft_transform removed
aft_transform (add_member, add_derive, wrap_try_catch, add_decorator, add_struct_tags) is gone. Usage data showed agents essentially never called it — everything it did is covered by edit's symbol and find/replace modes, which agents already use fluently. Removing it shrinks every request's tool surface. If you listed it in disabled_tools, the entry is ignored harmlessly.
Leaner tool descriptions and smarter guidance
- The
bash,write,edit,apply_patch,aft_search, andaft_refactordescriptions were rewritten to be shorter and to only describe behavior that is actually enabled in your config — e.g.bashno longer advertisesbackground: truewhen background execution is disabled. - The per-call
diagnosticsparameter onwrite/edit/apply_patchis gone; diagnostics flow through the status bar andaft_inspect, withlsp.diagnostics_on_editas the config knob. - The system-prompt guidance was rewritten around what agents should do rather than what they shouldn't: concrete translations from bash habits to the right tool, and a clear protocol for waiting on background commands instead of polling them.
Background bash: right-sized completion reminders
Completion reminders for background tasks now size their output by how the task ended: a successful task shows a short tail, a failed task keeps the head plus a generous tail so the error context survives. Killed or timed-out tasks are treated as failures. Compressors also never render a success summary (N pass, 0 fail) for a command that exited non-zero.
Fixes
- Failed refactors report failure:
aft_refactormove/extract/inline now return an error when a syntax-validation rollback occurs, and a rolled-back destination write can no longer lose the moved symbol.writeandapply_patchreport rollbacks honestly too. aft_importno longer writes a bare side-effect import when a model sendsnamesas a JSON-stringified array; stringified arrays and bare strings are accepted, wrong types are rejected.- Organize imports preserves
pub(crate)/pub(super)visibility in Rust and no longer drops modules from Pythonimport os, sysstatements. ast_grep_replacerejects rewrite meta-variables the pattern never captures (e.g. a$MGStypo), instead of writing them as literal text.- Fuzzy edits preserve the trailing newline of the replaced region in batch mode (the v0.36.1 fix now covers all edit paths).
- Outline/zoom symbol ranges are correct for Rust functions inside
modblocks, multi-declarator statements (const a = 1, b = 2), and Markdown/HTML heading sections; JavaScript files now extract top-levelconst/letsymbols like TypeScript. - The sidebar no longer shows another project's data in multi-window or
opencode -ssetups, and reconnects more reliably. - LSP: a server installed mid-session is picked up on the next configure instead of requiring a restart; per-file diagnostic pulls honor their 10s cap;
tsconfigwith only afileslist no longer treats the whole tree as members. semantic.timeout_msis honored up to the real transport budget (55s) instead of being silently clamped to 25s — slow local embedding backends (LMStudio cold-loads) no longer have their configured headroom cut, and background refresh batches stop getting aborted mid-embed.- Search: capped results are signaled in the output footer, and an uncapped parallel grep no longer falsely reports itself as capped.
- Bash safety: commands with an explicit
workdiroutside the project root are never rewritten to AFT tools, and process-group kill works even after the leader exits. - Redirects to
/dev/nulland friends no longer trigger permission prompts (#106): device-file paths (/dev/null,/dev/stderr, numeric/dev/fd/N, ...) are skipped by the bash permission scanner, matching native shell behavior. - Windows: diagnostic reports redact user paths on all drives and slash styles.