v3.4.0

Released September 17, 2026 · View on GitHub →

TL;DR — Security and reliability release: a repo can no longer grant itself access or start MCP servers, secrets stay out of prompts, MCP tools ask first, and /commit, /scan, /undo and sessions stop losing work.

A wide bug hunt across the CLI and the editor integration (VS Code, Zed): five independent audits, every finding reproduced before it was fixed, and a regression test for each fix that was shown to fail without it.

Upgrade notes

also stored the grant in the project's own .codeep/config.json, a file a cloned repository can ship. Grants now live only in your own config.

mode (and in Manual mode in editors). Read-only resource and prompt lookups still run without asking. Always mode now asks before every write, edit, delete and command, as its description always said.

(brave-search__brave_web_search, not brave_search__…). Update a hook that matched the old form.

quotes, ^, %, !, &, |, < or >: cmd.exe reads them differently from the check, so they cannot be checked.

Security

.codeep/config.json in the repo was read as your permission grant, so the "Allow access?" question never appeared. Only grants you made count now.

from untrusted repositories**, in the terminal and in editors, although opening the project skipped them. They now apply the same trust rule, and a repo server can no longer stop or replace one of your own.

allow-list, blocked patterns and the network address guard — and in the default mode nobody was asked. They are now checked like local commands.

Dangerous mode, while a local file write in the same session did.

context put .env.local or server.key into the system prompt whenever the prompt mentioned them — even after the @ mention was refused — and @dir ~/.ssh attached private keys. Now: - secrets files are never inlined implicitly; - private keys are recognised by content, whatever the file is called and however it is written (PEM, OpenSSH, PGP, PuTTY, on one line, in JSON or in string literals); - .git-credentials, .pypirc and the Docker, kube and gh credential files are refused; - a symlink is judged by the file it points at; - a refused @.env.template stays out of smart context too.

A committed CODEEP.md -> ~/.aws/credentials, or an agent, personality, custom command, skill bundle, profile or progress file linked outside the project, is no longer read.

a symlinked .codeep/.** Sessions, project config, the audit log, logs, checkpoints, memory notes, the progress log, the project profile, the MCP config and installed skill bundles are never written through a symlink; a symlinked .codeep is announced and sessions go to ~/.codeep/sessions.

.gitignore, SKILL.md, personality or context file hung every run.

/skill delete ../mcp_servers deleted ~/.codeep/mcp_servers.json, and a bundle name from the server chose where files were written.

bidi characters are shown literally, long commands and MCP calls are shown from their first character, an exec tool's arguments are listed, and a credential is replaced only where it appears — not the whole value.

that started them.

every command in the line, including after redirects such as 2>&1.

cmd.exe.

Tracked as GHSA-q466-ch7g-2322.

Fixed — lost or overwritten work

one (and in editors without asking); /commit <message> is committed as typed and shown before it runs; /branch always failed.

overwrote another conversation (terminal and editors), two editor threads wrote over each other's file, and a turn that finished after you switched conversations landed in the new one.

/rename right after a reply brought the old file back.

overwrite a file you changed since, or a deleted file that exists again.

preview, graceful shutdown and /skill delete.

write was reported as a success.

Fixed — the agent loop

the run did not touch, output it could not parse, fix attempts used up), and a run that hit its iteration limit counted as a success.

counts as failed again; one that only timed out is reported as not run.

tool calls queued behind it, and cancels Ollama's native API requests. Processes a command started itself keep running, as they do when a command times out.

brave-search) could not be called.

following commit or deploy step still ran.

still fail.

Fixed — terminal

now listed under "Not loaded".

longer lists undone changes.

gitignored.

and sync now say why a profile sync failed and exit non-zero.

Fixed — VS Code and Zed

turn as cancelled.

second time locally.

registered under the id the editor asked for.

it.

at the end of a reply.

/plan.

Internal

importing the CLI entry module no longer starts the app.

Downloads

Install with npm install -g codeep@3.4.0.