v0.47.1
AFT v0.47.1
Patch release: three data-integrity fixes, much better output for MCP hosts, two requested features, and a batch of hot-path performance work.
Fixes
apply_patch could delete a file when a patch moved it to its own path. An update hunk whose *** Move to: target resolved to the source file wrote the new content and then removed the "source" — deleting the file while reporting success. A same-path move is now treated as what it means: an in-place update. (Affects GPT-family sessions in particular, where apply_patch is the primary edit tool.)
Cross-filesystem moves destroyed symlinks. When aft_move fell back to copy+delete (source and destination on different filesystems), the copy followed the symlink and produced a regular file with the target's contents. The fallback now recreates the link itself, preserving the link text exactly — relative targets stay relative, and moving a dangling link works.
Failed deletes created phantom undo operations. A delete that failed (for example, a read-only parent directory) left its pre-delete backup in the undo history; the next undo "restored" the unchanged file instead of reverting your previous real operation. Failed deletes now leave no trace, including partial failures inside recursive directory deletes.
Auto-update could permanently disable itself. If the process holding the update lock crashed or was killed, the leftover lock file blocked every future update check on that machine. Orphaned locks (dead owner, or older than an hour) are now reclaimed safely.
MCP hosts got raw JSON instead of readable output. Tool replies to MCP clients (for example Claude Code via the CortexKit gateway) carried a structured payload those hosts fed to the model as a JSON dump — with the rendered text buried inside it at several times the token cost. MCP replies are now text-only, and status renders a compact summary instead of a full JSON snapshot.
Pi: file: URLs and batch edits. Pi's path handling now decodes file: URLs at the same choke point as OpenCode's, and both plugins share one decoder implementation matched byte-for-byte with the server's.
Features
file:URL paths (#162): tools accept RFC 8089file:URLs (file:///path,file:/path,file://localhost/path) anywhere a path is expected.- No prompt for your own bash artifacts (#161): reading a background task's own output files (the paths bash results point at) no longer triggers an external-directory prompt; the server already restricts these files to the owning session.
Performance
- Warm symbol lookups (zoom, outline, top search hit rendering) no longer re-read and re-hash the file on every call when size and mtime are unchanged.
- Hybrid search no longer re-reads the same posting lists once per candidate — each query trigram's postings are read once per query.
- Semantic/hybrid search snippets stream only the needed portion of hit files instead of reading whole files per query.
- Edits, writes, and patches no longer deep-copy the file's entire undo history twice per mutation.
- Semantic search caches embedding norms instead of recomputing them for every entry on every query.
Internal
- Symbol-cache freshness formally adopts stat-first trust (matching the search index): size+mtime match serves the cache; content hashing runs only when mtime moved; the file watcher remains the invalidation path.
- CI: unit and e2e stages run in parallel, PR e2e uses a faster build profile (releases still test the exact release profile), and the release pipeline builds binaries alongside tests instead of after them — publishing still gates on everything being green.
- E2E harnesses no longer allow the auto-updater to swap the locally built plugin under test for the published one.