v0.56.0
AFT 0.56.0 adds a default-off preview of content-addressed index views, revises search ranking and paging, supports OpenCode 2 GA and OMP, and improves background-task and daemon reliability.
Highlights
- Content-addressed index views (preview): branch switches can become atomic manifest swaps, unchanged files need no new embeddings, and worktrees share immutable blobs. The implementation passes its correctness checks but is not faster for every branch-switch shape. It remains off by default; enable it for one project with
"views": { "enabled": true }in<project>/.cortexkit/aft.jsonc. (#286) - Exact text wins in
aft_search: normalized exact-phrase matches occupy a tier ahead of fused lexical and semantic results, including long natural-language queries. (#295) - Search routing now follows query shape: identifier queries use definition-first lookup without an embedding request, while natural-language queries retain lexical and semantic candidates.
- OpenCode 2 GA is supported:
@cortexkit/aft-opencodeis verified against exact@opencode/*@2.0.3packages, publishes the./serverentry OpenCode 2 resolves, and requires Node 24 or newer on that host path. - GitHub resources now have a single gated surface: when enabled,
read,aft_outline, andaft_zoomacceptissue://andpr://targets;write(issue://N)adds a conversation comment, andedit(issue://N/comments/K)edits one by ordinal. Owner/repository forms, pull requests, ranges, comma lists, and tail selectors such ascomments/-1are supported.
Fixes
- Background completion and pattern-watch notices are delivered only to the session that started the task; stale watch rows are removed instead of replaying into new sessions or other projects. (#304, #308)
- Completed background tasks report live descendants after a short grace period, and
bash_killcan still stop those descendants after the direct shell has exited. (#311) - Deferred foreground bash waits no longer occupy executor workers, so long commands do not starve unrelated tool calls.
- Background completion wakes work again in idle OpenCode sessions; the SDK method is now called with its required receiver. (#297)
- Disposing one OpenCode plugin instance now closes only that directory's resources and leaves other active directories and calls running. (#307)
- Concurrent
aft.dbopens serialize migration planning, migrations are rerunnable, and databases wedged with version-10 objects recorded as version 9 self-heal on open. (#312) - Index-view Git metadata collection pumps input, output, and errors concurrently, avoiding the full-pipe deadlock during large manifest updates.
- Filesystem-lock reclaim tokens carry owner liveness, abandoned tokens are swept with bounded work, and stale-token recovery no longer permits two writers.
- Language servers left behind by reader failure or shutdown errors are killed and reaped before replacement.
- Pull-capable language servers now receive
textDocument/diagnosticrequests after edits, so custom servers such as rumdl supply diagnostics to edits andaft_inspectinstead of timing out. (#305) - Windows GitHub-hosted language-server archives are prechecked with
tar.exe, failed downloads back off, and concurrent plugin instances share one auto-install pass per machine. (#314) - Windows child environments collapse case-insensitive
Path/PATHduplicates without losing the inherited executable path. (#298) - Windows
.cmdand.batlanguage-server, formatter, and checker shims launch throughcmd.exewith spaced paths and literal percent arguments; canonical DOS and UNC paths are converted only at that boundary. (#287, #293) - Unsupported or malformed Windows verbatim namespaces, including volume GUID paths, are preserved rather than rewritten into another path class. (#302)
- The npm CLI loads
node:sqliteonly when needed, so help, setup, and doctor run on Node 20; the SQLite-dependent command reports its Node 22.5 requirement when invoked. (#306) - A bare daemon-connection EOF exits with code 3, and fatal worker teardown exits with code 4 and logs the panic, allowing the supervisor to restart instead of treating either as a requested stop.
- macOS FSEvents now uses 30 ms latency, watcher walks exclude ignored build and dependency subtrees earlier, and overflow status distinguishes kernel-, user-, and unknown-source rescans.
- Transient search caches are reused and legacy per-call temporary directories are removed by a bounded age-and-liveness sweep. (#282)
aft_conflictsaccepts a file path inside a repository and discovers conflicts from that repository's top level.aft_deleterefuses symlink entries without touching their targets.aft_movemoves a symlink itself, including dangling links and cross-device fallbacks.- Optional
pathvalues that are empty or null are treated as omitted byaft_searchand the other optional-path tools. (#288)
Changes
aft_searchsupports zero-basedoffsetpaging and keeps exact candidates stable across page sizes.- External-path
aft_searchrequests use the same ranking engine as project searches; unindexed external projects retain a bounded lexical fallback. - Every list-shaped tool now emits one truncation trailer with the contract
shown N of M <unit> (<reason>) · narrow: …and no duplicate cut notices. - Semantic one-file refreshes persist proportional deltas instead of rewriting the complete index artifact.
- Tier-2 dead-code projection and its cross-root rollup update incrementally from changed paths rather than rebuilding the full snapshot.
- Callgraph cold builds memoize the per-file resolver index and the workspace package map: reference resolution on this repository fell from 6,694 s to 269 s and the full cold build from 115 minutes to 8.4 minutes, and a monorepo refresh no longer walks the workspace tree per import.
- Rust targets under
src/binare treated as crate roots so their callers resolve. - Raw compression events are retained for 30 days, then folded in bounded batches while lifetime event and token totals remain available.
- Post-configure maintenance (storage sweeps, session replay, artifact loads) no longer runs ahead of the first request on the standalone bridge, and a second session on an already-configured project attaches without re-probing it; measured first-request latency on shared storage fell from about 3 seconds to about 135 ms.
aft_outlinefiles mode now walks breadth-first, reports directory rollups and line counts, preserves top-level breadth, and selects code rows before data-only rows.aft_zoommiss responses offer nearby ranged outline candidates.- Search and outline guidance falls back to
readwhenaft_zoomis disabled. (#291) aft profileadds symbolicated CPU sampling with a running-versus-waiting thread census.aft profile --memoryreports per-root memory on every platform.health.checknow includes a lifecycle census of language-server children, thread classes, SQLite connections, and file descriptors.- TOML, CUDA, and Metal are recognized across parsing, outlining, inspection, and language-specific tool routing.
- Undo snapshots over the configured size limit and mutations under an OS temporary directory proceed without a backup and state why undo is unavailable.
npx @cortexkit/aft setup --harness ompand doctor now support OMP's Pi-compatible plugin; OMP tool registration defaults to top-level presentation. (#309)
Configuration
views.enabled: new user/project key, defaultfalse.semantic.query_instruction: default changed to"auto"; it applies the Qwen3-Embedding retrieval instruction to queries only, while other model families and all document vectors remain unchanged.semantic.max_input_tokens: new positive integer; omitted by default, preserving the existing 512-token-safe remote-backend caps. Changing it rebuilds the semantic index; local fastembed ignores it.semantic.timeout_ms: default25000; build deadlines now scale by batch size and measured time per item. A timeout halves the active batch, two successes can grow it again, and only a one-item timeout at the base floor marks the backend down. (#310)semantic.max_batch_size: default64; failed refreshes resume from the retained unembedded file set rather than collecting the full corpus again. (#310)bash.subagent_background: default changed totrue; set it tofalseto convert subagent background requests into foreground waits.bash.watch_sync_max_ms: new user/project key, default120000; values are clamped to1000..=1800000, and1800000restores the former 30-minute ceiling.bash.linux_scope: new Linux user-only key, defaultfalse; when enabled and the user manager is reachable, non-PTY shells run in transientsystemd-run --user --scope --collectscopes and otherwise use normal process-group isolation. (#311)idle.root_ttl_minutes: new user/project key, default30, clamped to5..=30; it evicts an unbound root's in-memory artifacts after inactivity.idle.lsp_ttl_minutes: new user/project key, default10, clamped to1..=10; it shuts down inactive language servers independently of root eviction.github.enabledandgithub.shim: new user-only keys, both defaulttrue(they carry the formergh_shim.enableddefault).github.enabled: falsedisables every GitHub integration and produces zero AFT-originated GitHub traffic.github.shimonly controls whether AFT'sghshim is placed first on the PATH of the processes it spawns; without a CortexKit routing daemon and a signed manifest the shim is a transparent passthrough to the realgh, so a standalone installation'sghcalls are unchanged.github.readandgithub.write: new user-only keys, both defaultfalse; writes imply reads and produce a warning when onlywriteis enabled.pi.tool_presentation: new user/project key for Pi and OMP, default"top_level";"host_default"leaves presentation to the host and mounts OMP tools underxd://.backup.max_file_size: new user/project key, default67108864bytes;0disables automatic snapshots and explicit larger values are honored.
Notes
- Content-addressed index views are a correctness-complete preview, not a performance default. No automatic default change is planned in this release.
- Search truncation text and paging are part of the tool contract; consumers parsing the older collection-specific cut messages should accept the shared trailer.
aft_refactorhas been removed from the agent tool surface. Use the remaining edit, import, move, AST, and callgraph tools for supported operations. (#253)- Hashline mode now also requires a registered tagged
readslot; without it, configuration falls back to default edit/read behavior and reports why tags cannot be minted. (#292) - GitHub reads always attempt a live fetch. Comment writes do not create
aft_safetysnapshots, review-thread comments are not writable, andgh_read.enabled/gh_shim.enabledare deprecated aliases scheduled for removal in v0.57.0. - The governed
ghshim now allows 2 seconds per discovery stage, retries once after 250 ms, and distinguishes a probe timeout from a refused connection. - OpenCode 2 requires Node 24 or newer, but the AFT npm CLI remains usable on Node 20 except for the command that explicitly needs
node:sqlite.
Contributors
- Code contributions: @TreyThomasCodes (#287, #293, #302).
- Reporters and RFC authors: @randomvariable (#286), @iceteaSA (#253, #282, #311, #312), @llc1123 (#292), @tenshiak (#288, #291), @null-axiom (#297, #307), @rohan-patra (#308), @MrDrMcCoy (#306), @TreedsSlop (#314), @SK-DEV-AI (#295, #310), @acramsay (#305), @beh87 (#298), @aredridel (#304), and @flyinghail (#309).