Skip to content

Releases: cortexkit/aft

v0.13.0

16 Apr 12:54

Choose a tag to compare

v0.13.0

🧠 External Semantic Embedding Backends (PR #11 by @freelanceagent1)

  • OpenAI-compatible — connect to LM Studio, OpenAI, or any /v1/embeddings API
  • 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:

{
  "experimental_semantic_search": true,
  "semantic": {
    "backend": "ollama",          // or "openai_compatible" or "fastembed" (default)
    "base_url": "http://localhost:11434",
    "model": "all-MiniLM-L6-v2"
  }
}

🔒 Security Hardening (13 council audit findings)

  • P0: Config exfiltration fix — project config can no longer set semantic.backend, base_url, or api_key_env. Only user-level config controls external backend connections, preventing supply-chain attacks via malicious .opencode/aft.jsonc files.
  • SSRF validation — only http:// and https:// 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 index field 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

15 Apr 07:06

Choose a tag to compare

v0.12.2

🐛 Bug Fixes

  • TUI plugin loading — ship raw .tsx source instead of pre-bundled JS. OpenCode's TUI loader processes JSX/TSX directly via Bun's built-in JSX transform; the pre-bundled dist/tui.js had lost the @jsxImportSource pragma and Solid.js bindings, causing /aft-status dialog to not appear in TUI mode.
  • Import resolution — removed explicit .js extensions from src/shared/ imports. Bun resolves .ts files without extensions; the .js files 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_DIR and uses homedir() instead of process.env.HOME, fixing config resolution on Windows where HOME is often unset.
  • Windows ONNX Runtime extraction (PR #9 by @freelanceagent1) — ZIP extraction uses PowerShell Expand-Archive first, falls back to cmd.exe /c tar, replacing the Unix-only unzip command that failed on standard Windows installations.

v0.12.1

14 Apr 15:12

Choose a tag to compare

v0.12.1

🐛 TUI Plugin Fix (Windows + macOS)

  • Bundled TUI plugindist/tui.js is now a self-contained 12KB bundle instead of raw TypeScript source. Fixes ENOENT: no such file or directory, open '...rpc-utils.js' on Windows and any environment where the TUI loader cannot resolve .ts imports.
  • Slimmer npm packagesrc/tui and src/shared directories no longer shipped; everything is in dist/.

🐛 Windows Extended-Length Path Fix

  • \\?\C:\... paths normalized before file URI conversion. LSP startup no longer fails with failed to convert workspace root '\\?\C:\Users\...' to file URI on Windows.

📝 Documentation

  • Added Bash and HTML to the README supported languages table (14 languages total).

Closes #8.

v0.12.0

14 Apr 10:20

Choose a tag to compare

v0.12.0

🐚 Bash/Shell Language Support

  • Outline, zoom, and AST search for .sh, .bash, .zsh files
  • Detects both function foo() and foo() 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

13 Apr 16:59

Choose a tag to compare

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 found crash 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 cross with GLIBC 2.31)

Affected users: Clear your plugin cache and restart OpenCode:

rm -rf ~/.cache/opencode/packages/@cortexkit

v0.11.4

12 Apr 14:02

Choose a tag to compare

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/user indexed 49K files and hit 4.1GB RSS before OOM kill)

Watcher Noise Reduction

  • Event kind filter — only processes Create, Modify, and Remove events. Skips Access events that caused a feedback loop on Linux with atime enabled (reading files during index update triggered new access events)
  • Directory filter — skips .git/, .opencode/, node_modules/, and target/ 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

12 Apr 12:40

Choose a tag to compare

Full Changelog: v0.11.2...v0.11.3

v0.11.2

12 Apr 10:51

Choose a tag to compare

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() — raw dlopen probe catches broken/incompatible .so files before the ort crate touches them. Returns a clear error with the detected version, required version, and removal instructions.
  • panic = "unwind" in release profile — catch_unwind now works as a safety net if ort still 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, bad ORT_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 --issue now sanitizes ALL sections (not just logs) — paths in JSON diagnostic blocks are redacted
  • Grep ^/$ anchors now work correctly with multi_line(true) on both indexed and fallback paths

v0.11.1

10 Apr 18:05

Choose a tag to compare

🩺 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

10 Apr 12:56

Choose a tag to compare

🌐 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