Releases: cortexkit/aft
v0.13.0
v0.13.0
🧠 External Semantic Embedding Backends (PR #11 by @freelanceagent1)
- OpenAI-compatible — connect to LM Studio, OpenAI, or any
/v1/embeddingsAPI - Ollama — native Ollama embeddings API support
- Build progress reporting — semantic index build shows stage, file count, and entry progress
- Fingerprint invalidation — cached indexes auto-rebuild when backend/model/dimension changes
- V2 serialization — backward-compatible format with embedded fingerprint metadata
Configure in ~/.config/opencode/aft.jsonc:
🔒 Security Hardening (13 council audit findings)
- P0: Config exfiltration fix — project config can no longer set
semantic.backend,base_url, orapi_key_env. Only user-level config controls external backend connections, preventing supply-chain attacks via malicious.opencode/aft.jsoncfiles. - SSRF validation — only
http://andhttps://schemes allowed, redirect following disabled - Deep-merge fix — partial project config overrides no longer erase unrelated user settings
🐛 Bug Fixes
- OpenAI index-field bug — providers that omit the
indexfield in responses no longer silently corrupt multi-item batches - Cross-batch dimension tracking — errors on inconsistent embedding dimensions instead of silent corruption
- Semantic timeout clamped to bridge timeout (25s max) to prevent bridge kills on slow backends
- HTTP retry — 2 retries with exponential backoff for transient 5xx/429 errors
- Stale cache detection — file mtime verification on restart, rebuilds indexes with changed files
- Fingerprint normalization — base_url is normalized before fingerprinting to avoid spurious rebuilds
- Unknown fastembed models now return explicit errors instead of silent fallback
- Flaky LSP timing test — widened threshold from 1s to 3s
📊 Stats
- 689 Rust tests, 211 TypeScript tests (900 total)
- 7 new tests covering security bypass, cardinality validation, dimension mismatch, and V1→V2 migration
v0.12.2
v0.12.2
🐛 Bug Fixes
- TUI plugin loading — ship raw
.tsxsource instead of pre-bundled JS. OpenCode's TUI loader processes JSX/TSX directly via Bun's built-in JSX transform; the pre-bundleddist/tui.jshad lost the@jsxImportSourcepragma and Solid.js bindings, causing/aft-statusdialog to not appear in TUI mode. - Import resolution — removed explicit
.jsextensions fromsrc/shared/imports. Bun resolves.tsfiles without extensions; the.jsfiles don't exist in the npm package and caused ENOENT errors when the TUI loader tried to import them.
🤝 Community
- Windows config paths (PR #9 by @freelanceagent1) — runtime config lookup now honors
OPENCODE_CONFIG_DIRand useshomedir()instead ofprocess.env.HOME, fixing config resolution on Windows whereHOMEis often unset. - Windows ONNX Runtime extraction (PR #9 by @freelanceagent1) — ZIP extraction uses PowerShell
Expand-Archivefirst, falls back tocmd.exe /c tar, replacing the Unix-onlyunzipcommand that failed on standard Windows installations.
v0.12.1
v0.12.1
🐛 TUI Plugin Fix (Windows + macOS)
- Bundled TUI plugin —
dist/tui.jsis now a self-contained 12KB bundle instead of raw TypeScript source. FixesENOENT: no such file or directory, open '...rpc-utils.js'on Windows and any environment where the TUI loader cannot resolve.tsimports. - Slimmer npm package —
src/tuiandsrc/shareddirectories no longer shipped; everything is indist/.
🐛 Windows Extended-Length Path Fix
\\?\C:\...paths normalized before file URI conversion. LSP startup no longer fails withfailed to convert workspace root '\\?\C:\Users\...' to file URIon Windows.
📝 Documentation
- Added Bash and HTML to the README supported languages table (14 languages total).
Closes #8.
v0.12.0
v0.12.0
🐚 Bash/Shell Language Support
- Outline, zoom, and AST search for
.sh,.bash,.zshfiles - Detects both
function foo()andfoo()style function definitions - 14 languages now supported: TypeScript, JavaScript, TSX, JSX, Python, Rust, Go, C, C++, Zig, C#, HTML, Markdown, Bash
Closes #6.
📊 Stats
- 677 Rust tests, 201 TypeScript tests (878 total)
v0.11.5
v0.11.5
Linux GLIBC Compatibility Fix
- Linux x64 binary now built on Ubuntu 22.04 (GLIBC 2.35) instead of Ubuntu 24.04 (GLIBC 2.39)
- Fixes
GLIBC_2.39 not foundcrash on Ubuntu 22.04 LTS, Pop!OS 22.04, Debian 12, and any distro with GLIBC < 2.39 - Linux ARM64 binary was already compatible (built via
crosswith GLIBC 2.31)
Affected users: Clear your plugin cache and restart OpenCode:
rm -rf ~/.cache/opencode/packages/@cortexkit
v0.11.4
v0.11.4
Semantic Index Safeguards
- Don't persist empty semantic indexes — prevents stale 0-entry cache from blocking future builds when files are added to a project
- Reject empty cached indexes on load — deletes and rebuilds instead of returning a permanently empty index
- 10K file cap for semantic indexing — prevents OOM on large project roots (e.g., opening OpenCode from
/home/userindexed 49K files and hit 4.1GB RSS before OOM kill)
Watcher Noise Reduction
- Event kind filter — only processes
Create,Modify, andRemoveevents. SkipsAccessevents that caused a feedback loop on Linux withatimeenabled (reading files during index update triggered new access events) - Directory filter — skips
.git/,.opencode/,node_modules/, andtarget/paths which generated the bulk of spurious invalidation events
Doctor CLI Improvements
- Full-body sanitization in
doctor --issue— all paths (including inside JSON diagnostic blocks) are now redacted, not just log lines - ONNX Runtime version detection in doctor — scans system paths and auto-download cache for installed ORT versions, warns when incompatible (< v1.20)
v0.11.3
Full Changelog: v0.11.2...v0.11.3
v0.11.2
v0.11.2
Critical: ONNX Runtime crash prevention (fixes #4, #5)
An incompatible or broken libonnxruntime.so on the system (e.g., v1.19 when AFT needs v1.20+) previously caused the entire AFT binary to crash via SIGABRT, taking down all tools — not just semantic search.
Two-layer fix:
pre_validate_onnx_runtime()— rawdlopenprobe catches broken/incompatible.sofiles before theortcrate touches them. Returns a clear error with the detected version, required version, and removal instructions.panic = "unwind"in release profile —catch_unwindnow works as a safety net ifortstill panics through other paths. Binary size increased from 19MB to 23MB.
Version detection: extracts ORT version from .so/.dylib filenames (e.g., libonnxruntime.so.1.19.0) and compares against the required minimum (v1.20+).
Doctor: ORT version check
bunx @cortexkit/aft-opencode@latest doctor now detects incompatible ONNX Runtime versions:
✗ ONNX Runtime v1.19.0 found at /usr/local/lib — INCOMPATIBLE (need v1.20+)
Solutions:
1. Remove old version: sudo rm /usr/local/lib/libonnxruntime* && sudo ldconfig
Then restart OpenCode — AFT auto-downloads the correct version.
2. Or install v1.24: https://github.com/microsoft/onnxruntime/releases/tag/v1.24.0
Docker E2E test suite
New tests/docker/ infrastructure using aimock for deterministic OpenAI-compatible mock sessions on Linux x64:
- 3 ONNX scenarios: no ORT, broken
.so, badORT_DYLIB_PATH— all verified crash-free - Full OpenCode → AFT plugin → bridge → aft binary stack on real Debian Bookworm
- Release script runs Docker E2E as a pre-release gate (skips if Docker unavailable)
Other fixes
doctor --issuenow sanitizes ALL sections (not just logs) — paths in JSON diagnostic blocks are redacted- Grep
^/$anchors now work correctly withmulti_line(true)on both indexed and fallback paths
v0.11.1
🩺 Standalone CLI (setup / doctor / --issue)
AFT now ships a standalone CLI binary that you can run with `bunx`.
# Interactive first-time setup (adds plugin entries, enables experimental features)
bunx @cortexkit/aft-opencode@latest setup
# Check configuration and auto-fix common issues
bunx @cortexkit/aft-opencode@latest doctor
# Force-clear the OpenCode plugin cache (fixes stale @latest resolution)
bunx @cortexkit/aft-opencode@latest doctor --force
# Collect diagnostics and open a GitHub issue with sanitized logs
bunx @cortexkit/aft-opencode@latest doctor --issue`setup`
Interactive wizard that registers AFT in `opencode.json` and `tui.json`, asks whether to enable `experimental_search_index` and `experimental_semantic_search`, and writes the result to `~/.config/opencode/aft.jsonc`. Run this once after installing.
`doctor`
Checks everything that can go wrong: OpenCode install, plugin registration, plugin cache version, AFT binary cache, config parse errors, ONNX Runtime availability (for semantic search), storage directory sizes, and log file status. Auto-fixes missing plugin entries and outdated plugin caches in place.
`doctor --force`
Same as `doctor` but always clears the OpenCode plugin cache, forcing a fresh download of the latest plugin version. Use this when `@latest` doesn't seem to update — OpenCode caches npm packages aggressively and needs a nudge.
`doctor --issue`
Collects a full diagnostic report, strips your username and home path out of the logs, and opens a pre-filled GitHub issue. If you have `gh` installed, it submits directly; otherwise it writes the report to `./aft-issue-.md` and opens the GitHub new-issue page in your browser.
GitHub issue templates (bug report, feature request) now ship in `.github/ISSUE_TEMPLATE/` to match the report format.
🐛 grep `^` and `$` anchor fix
`grep` was silently returning `0 matches` for patterns like `^## ` or `}$` because both the indexed and fallback regex paths compiled without multi-line mode — so `^` only matched file position 0 and `$` only matched the final byte. Both paths now build with `multi_line(true)`, matching ripgrep and grep semantics.
Three new regression tests cover the fallback path, the trigram-indexed path, and end-of-line anchors.
v0.11.0
🌐 URL Support for aft_outline and aft_zoom
Fetch HTTP/HTTPS URLs and outline/zoom the content directly. No more downloading docs to a temp file manually.
aft_outline(url: "...")
- Fetches the page and returns the heading hierarchy (for Markdown/HTML) or symbol structure
- 1-day disk cache per URL — repeated outline/zoom calls on the same URL share one fetch
- Works great on documentation sites, GitHub READMEs, and raw file URLs
aft_zoom(url: "...", symbol: "Section Name")
- Fetches the page and returns just the section under the given heading
- Share the cache with
aft_outline— outline → zoom → zoom is a single network fetch
Content-Type Handling
- Accept header:
application/vnd.github.raw, text/markdown, text/x-markdown, text/html;q=0.9, text/plain;q=0.5 - Prioritizes markdown for content-negotiating servers (GitHub API, many docs frameworks)
- Falls back to HTML for static sites that don't support content negotiation
- Recognizes GitHub's vendor types:
application/vnd.github.raw→ markdown
GitHub API Support
The GitHub API /repos/{owner}/{repo}/readme endpoint now works out of the box — it returns raw markdown via our vnd.github.raw Accept header.
aft_outline(url: "https://api.github.com/repos/cortexkit/aft/readme")
Error Handling
- Max response: 10 MB
- Fetch timeout: 30 seconds
- Mutually exclusive with
filePath,files,directory— provide exactly one - Clear errors for unsupported content types, network failures, invalid URLs
🧹 Leaner Tool Descriptions
aft_outline and aft_zoom descriptions trimmed to focus on what agents actually need:
- Removed parameter-level details from top-level descriptions (cache TTL, content-type whitelist, max file size)
- Removed verbose mode examples with JSON snippets
- Parameter descriptions now carry the nuance (e.g., "Symbol name for code, or heading text for Markdown/HTML")
📊 Stats
- 194 TypeScript tests, 672 Rust tests (866 total)
- URL fetch helper at `packages/opencode-plugin/src/shared/url-fetch.ts`
- PluginContext extended with `storageDir` for cache access
{ "experimental_semantic_search": true, "semantic": { "backend": "ollama", // or "openai_compatible" or "fastembed" (default) "base_url": "http://localhost:11434", "model": "all-MiniLM-L6-v2" } }