Repository navigation
v0.61.0
v0.61.0
AFT 0.61.0 hands every OpenCode 2 permission decision to OpenCode, and replaces the on/off shell sandbox with per-role profiles. Edits keep a file's permissions and ownership, and replace it atomically whenever that is safe. The CortexKit daemon does much less background CPU, disk and memory work, AFT stops indexing your home folder and filesystem roots, and many reported issues are fixed.
Upgrading
- OpenCode 2 now requires 2.0.29 or newer.
opencode.server_urlandopencode.server_password_envare removed and fail config loading;npx @cortexkit/aft doctor --fixdeletes them (docs). sandbox.enabledis replaced bysandbox.profile, set per role tooff,relaxedorstrict.doctor --fixmigrates it, andtruebecomesstrict(docs).- CortexKit daemon: worker shells now default to
relaxedinstead of the strict jail, and other sessions tooff. Setsandbox.profile.workertostrictto keep the old confinement. - AFT no longer indexes or watches a filesystem or drive root, your home folder, or any folder above it. Tools still work there with explicit paths.
New
- Shell sandbox profiles:
relaxedkeeps caches, toolchains and compile servers working while protecting credentials, CortexKit data, other checkouts and Git configuration. Enforced on macOS only. write,editandapply_patchsay when a file they create does not parse; the file is still written as given.- Semantic search waits out a paused embedding model and resumes where it stopped, using keyword search with a notice meanwhile.
- gh shim:
gh workflow disableandgh workflow enablerun under the operator bypass, and an operatorgh repo renamerefuses when the repository publishes reusable workflows or actions (docs). - CortexKit daemon: codemode programs can call every AFT tool with the head agent's own access. A call that would need a permission prompt is refused as
permission_ask_unavailable, and background commands stop when the run ends. - CortexKit daemon: worker catalogs can set
confine: "root"to keep a read-only session inside its own checkout, even after a restart. - CortexKit daemon: Basal can read one exact file under its head agent's permissions. Refusals explain what is missing, and unsupported operations are named.
- CortexKit daemon: an ENGRAM backup catalog is written at startup, listing what to back up and what to skip.
Changed
- OpenCode 2: OpenCode decides every AFT permission, so its hooks and per-file read rules apply, including to multi-file
aft_outlineandaft_zoomcalls (#562, thanks @iceteaSA). - No more permission prompts for reading a session's own bash output and scratch files, or, for workers, Cargo registry sources and Rust toolchains. Other sessions' files and all writes stay protected.
- A finished command's
$TMPDIRscratch stays readable by the same session for 30 minutes. After it is removed, reading it reports "file not found" instead of asking for permission. - CortexKit daemon: a worker's permission ask for a read now offers whole-folder approval, also when it reads several files at once, and keeps it when approved later.
- The daemon starts formatters, checkers, git probes and non-terminal bash commands without forking itself, which had stalled other work on macOS.
- Lighter background work: health summaries, bash task cleanup, Git policy checks, storage retention, disk-limit checks, worktree setup and language-server detection reuse earlier results or do less filesystem work.
- Storage cleanup frees cache database space a little at a time instead of rewriting multi-gigabyte files, and finished bash tasks release their scratch folders.
- Search starts faster: restarts reload search data with fewer filesystem lookups, branch switches reuse the saved index, and new worker checkouts reuse vectors from sibling checkouts.
- Semantic search uses less memory: idle projects release their vectors and reload them when needed, and checkouts with index views share vectors instead of copying them.
- With index views on, rebuilding a checkout's call graph after a small edit takes seconds instead of about two minutes.
- Long remote (
runon) commands save their output progress every 5 seconds instead of every second, and status checks no longer wait for those saves. - The daemon log no longer fills with warnings for expected states; real failures still warn.
Fixed
- Edits and syntax rollbacks keep a file's permissions, ACLs, extended attributes, owner and hard links. They replace the file atomically when they can; a hard-linked file, or one whose attributes a replacement would lose, is rewritten in place, with a recovery copy kept until the write completes.
apply_patchrejects malformed patches and ambiguous matches before writing anything. editwithedits[]or line ranges works on existing paths containing brackets, such as Next.jsapp/[id]/page.tsx(#486, thanks @ybw0014).aft_safetyrestore asks permission for each file it writes, so path rules apply (#541, thanks @iceteaSA).- LuaLS and clangd auto-installs keep their runtime files, and broken cached servers are repaired (#547, thanks @chpock).
- Scoped
aft_inspectreports errors in files outside the project, or names them as unchecked, instead of claiming a clean result (#559, thanks @iceteaSA). - AFT's status refresh no longer holds up other tool replies while another AFT process writes the inspect cache, and a shell command that outlasts its call now names its task instead of saying none exists (#577, thanks @chpock).
- OpenCode 2: queued messages no longer interrupt shell waits; steer messages and
&detachstill do (#563, thanks @iceteaSA). - Blocking shell waits return before the client times out, so a full 30-minute wait keeps its reply, and a message sent just before a shell call still detaches it (#465, thanks @null-axiom).
aft_callgraphanswers are marked incomplete, naming the file, while an edit is still being applied, andaft_inspectandaft_zoomreport a busy call graph as building.aft_inspectno longer waits past its time limit for another process's cache lock or reports a reopened file clean too early, and refreshes dead code after index views update.readofpr://N/diffworks again, and URL outlines show the requested URL instead of a cache file name.- Bash: an empty
runonruns locally, a refused remote job says why, and remote jobs keep their output and exit codes across AFT and build-server restarts. - Background commands started before a project's database is ready are saved and survive a daemon restart.
- Windows: terminal commands find
pwshwhen it is only on the process PATH, PowerShell command-not-found errors are no longer reported as success, project paths keep one identity, and project binds are no longer refused during setup. - Scans skip AFT's own databases and task folders, fixing daemon crashes and lost database locks; source folders with database-like names stay searchable.
- File watching no longer hangs when a build folder links to an unresponsive or disconnected drive.
- Tool calls no longer fail while the database opens or is briefly busy, and on busy machines file reads, edits and deletes no longer fail as blocked.
- AFT's own edits to files outside a project no longer stop that project's search index from saving, which had forced a full rebuild on every start.
- A second AFT process saving a large symbol cache on a slow disk no longer loses its write.
- Storage spread over several volumes: folder moves, repairs and retention work across volumes, and migration checks free space on each.
- The plugin no longer blocks its host while checking migrations, extracting ONNX Runtime or delivering setup warnings.
- Failed edits and moves keep their undo data, a move no longer overwrites a destination created meanwhile, and
appendContentinto a new folder no longer reports a false failure. - Config files and saved state are replaced atomically, edits through a symlinked config update the linked file, and several commands keep Unicode text intact.
- Git detection no longer mistakes damaged metadata or a killed git process for "not a repository", and GitHub identity and Ruff version checks can no longer hang.
- Shell commands start with a cleaner environment, a briefly busy login shell no longer leaves them with a system-only PATH, and wide characters render correctly in terminal sessions.
- The daemon stops every running language server when it exits.
- CortexKit daemon: worker shell commands can use folders their session was granted, without opening sibling folders or protected paths, and a bind that timed out on a lock is retried.