Skip to content

Releases: cortexkit/aft

v0.7.6

01 Apr 10:23

Choose a tag to compare

Critical Bug Fix

  • Replaced jsonc-parser with self-contained JSONC stripperjsonc-parser's UMD bundle breaks under both ESM named imports (Node.js strict ESM in OpenCode's runtime) and createRequire (Bun/OpenCode hybrid). Replaced with a zero-dependency comment stripper + trailing comma removal + JSON.parse. This was the root cause of plugin loading failures since v0.7.2.

Full Changelog: v0.7.5...v0.7.6

v0.7.5

01 Apr 09:35

Choose a tag to compare

Bug Fixes

Version Mismatch Loop Prevention

  • Fixed infinite configure loop — When the binary version is older than the plugin, the version mismatch handler now fires only once per binary version instead of re-triggering on every bridge respawn. Prevents the Failed to configure bridge after 3 attempts error users were hitting.
  • Tracker doesn't reset prematurely — Per Oracle audit, the upgrade tracker stays set after replacement so a still-outdated downloaded binary doesn't re-trigger the loop. Resets naturally on plugin reload.

User Experience

  • Log file path in errorsFailed to configure bridge after 3 attempts and Max restarts reached now include the path to $TMPDIR/aft-plugin.log so users can find diagnostic logs.
  • Empty param handlinglsp_diagnostics treats empty string filePath/directory as absent instead of throwing a false mutual-exclusivity error.

Full Changelog: v0.7.4...v0.7.5

v0.7.3

30 Mar 19:59

Choose a tag to compare

Bug Fixes

  • lsp_diagnostics empty string handling — Empty string filePath or directory params are now treated as absent instead of triggering the mutual-exclusivity error. Fixes 'filePath' and 'directory' are mutually exclusive when agents send filePath: "" with a directory value.

Full Changelog: v0.7.2...v0.7.3

v0.7.2

27 Mar 21:42

Choose a tag to compare

Improvements & Bug Fixes (Council Audit Round 2)

⚡ Performance

  • Event-driven LSP diagnostics — Replaced blocking thread::sleep (1.5-10s) with recv_timeout polling loop. Post-edit diagnostics now return immediately when the language server responds instead of waiting the full timeout (#10)
  • Callgraph memory reduction — Reduced .clone() calls from 80+ to 52 in build_reverse_index by using Arc<PathBuf> / Arc<str> for shared caller data. Hot loop no longer clones entire FileCallData structs (#7)

🐛 Bug Fixes

  • Backup error misidentificationrestore_latest now reports the actual I/O error (permission denied, disk full) instead of incorrectly claiming "file not found" via new IoError variant (#12)
  • Bridge crash orphan processes — Crash recovery timer now checks isAlive() before spawning, preventing duplicate child processes when ensureSpawned() already created one (#14)
  • LSP workspace/configuration dispatch — Server requests are now dispatched by method: workspace/configuration returns a correctly-typed array instead of null, so language servers receive proper config responses (#19)

🔒 Security

  • Mandatory checksum verification — Binary auto-downloader now aborts if checksums.sha256 is unavailable or missing an entry, preventing MITM attacks that block the checksum request (#16)

📝 Documentation

  • unwrap/expect audit note — Documented in lib.rs that remaining .unwrap() calls are in tree-sitter query operations (compile-time grammar constants) and test code, not production error paths (#2)
  • TypeScript as assertion note — Documented in bridge.ts that as casts are guarded by success === false error checks on all 16 tool handlers (#6)

Full Changelog: v0.7.1...v0.7.2

v0.7.1

27 Mar 19:59

Choose a tag to compare

Bug Fixes (Council Audit P0/P1)

🔒 Security

  • Path validation coverage — Added validate_path() to 6 write-capable commands that were missing it: transaction, ast_replace, lsp_rename, glob edit_match, checkpoint, and restore_checkpoint
  • Path traversal hardeningvalidate_path() canonicalization fallback now normalizes .. components for non-existent paths, preventing root/../outside/file bypass

🐛 Correctness

  • CRLF byte offset fixline_col_to_byte now scans raw bytes instead of using .lines(), fixing byte offset drift on Windows/CRLF files from line 2 onward
  • Code deduplication — Consolidated 5 duplicate line_col_to_byte implementations into one shared function
  • Transaction rollback visibility — Failed rollback file paths now appear in the error response under rollback_failures instead of being silently logged at debug level
  • move_file false success — Returns moved: false with a warning when source file deletion fails after copy, instead of claiming success

🔧 Robustness

  • LSP stderr deadlock prevention — Language server stderr pipe switched to Stdio::null() to prevent blocking after ~64KB of server logs
  • Bridge recursion guardsend() now has a 3-attempt depth limit to prevent infinite recursion on repeated version mismatches
  • Bridge configured flag race — Flag is now set after configure succeeds (not before the await), and reset on failure
  • Format logging fix — Successful auto-format now logs at info level instead of error

Full Changelog: v0.7.0...v0.7.1

v0.7.0

27 Mar 17:52

Choose a tag to compare

What's New

🆕 aft_conflicts — Single-call merge conflict viewer

Show all git merge conflicts across the repository in one call. Auto-discovers conflicted files, parses conflict markers, and returns line-numbered regions with context — the same format agents see from read. Replaces the typical 13-call workflow (2 bash + 11 reads) with a single tool call.

When git merge or git rebase produces conflicts, the plugin automatically appends a hint nudging the agent toward aft_conflicts.

🔧 Improvements

  • aft_outline directory auto-detect — passing a directory path to filePath now routes to directory mode instead of erroring
  • aft_outline tree-text format — compact text output replaces JSON, 80% smaller (~46KB → capped at 30KB), with signatures for single-file mode
  • Session-scoped bridges — each OpenCode session gets its own aft binary process with isolated undo/backup history (~9-15MB per session)
  • Bridge timeout auto-restart — hung aft process gets SIGKILL'd and respawned on the next tool call
  • Transparent version hot-swap — first tool call retries automatically after binary replacement instead of failing
  • restrict_to_project_root — new opt-in config option (default: false, matching OpenCode's built-in write behavior)
  • tool_surface tiersminimal (3 tools), recommended (12 tools, default), all (17 tools)

🐛 Bug Fixes

  • AST replace multi-matchast_grep_replace now replaces all occurrences per file (was only replacing the first)
  • Crash hardening — fixed panics from unchecked capture_names indexing, move_symbol isize overflow, unbounded heading_level, and invalid AST patterns
  • Batch edit fuzzy matching — batch edits now use the same 4-pass fuzzy matching as single edits
  • Hoisted edit batch compatibilityoldString/newString inside edits[] now translates correctly to Rust
  • Error guards on all 16 tool handlers — Rust error responses no longer crash the plugin with TypeError: undefined is not an object
  • Binary resolution loop fixensureBinary no longer falls back to stale legacy cache for versioned requests
  • buildUnifiedDiff size cap — large file diffs (>100KB) are skipped to prevent Node.js event loop hangs
  • Overlapping batch edit detection — batch edits with overlapping ranges now return a clear error instead of corrupted output

📝 Other

  • File-based logging — plugin logs go to $TMPDIR/aft-plugin.log instead of stderr (no more leaking during opencode export)
  • aft --version / -V — CLI flag to check binary version
  • Release script improvements — rebuilds local binary after version bump, updates cache paths, uses bun instead of node
  • Repo migration — moved to cortexkit/aft
  • 89 new tests (730 total) including 54 end-to-end tests through real BinaryBridge

Full Changelog: v0.6.7...v0.7.0

v0.6.7

27 Mar 10:37

Choose a tag to compare

Full Changelog: v0.6.6...v0.6.7

v0.6.6

26 Mar 14:38

Choose a tag to compare

Full Changelog: v0.6.5...v0.6.6

v0.6.5

26 Mar 14:00

Choose a tag to compare

Full Changelog: v0.6.4...v0.6.5

v0.6.4

26 Mar 11:05

Choose a tag to compare

Full Changelog: v0.6.3...v0.6.4

Full Changelog: v0.6.3...v0.6.4