Repository navigation
v3.11.1
Highlights
- Agents can read across all your projects at once: the path jail now admits every project below your home directory for reading by default, while writes stay in the session's own project and
~/.ssh,~/.aws,~/.config, other top-level dot directories,~/Library,~/AppDataand~/snapstay closed. - Each agent session binds to the project it was started in. Setup no longer pins one project into an agent's global MCP config, and existing pins are removed.
Upgrade notes
- Path jail scope: the new
path_jail_scopesetting defaults to"home": reads anywhere below your home directory outside the protected zones; writes only in the session's project, host-declared roots and allow entries. Setlean-ctx config set path_jail_scope projectto keep the previous single-project boundary. The setting is global-only; a project-local.lean-ctx.tomlcannot change it. With an implausible$HOME(/, a single path component, not owned by you) the scope falls back toproject.path_jail = falsestill disables the jail. - Protected zones are a hard deny in both scopes: a project root or allow entry that only contains a zone (for example a dotfiles repository at
~) no longer opens~/.sshand the like; add an entry inside the zone (lean-ctx allow-path ~/.config/myapp) if a tool must reach it. - Project pins: earlier
lean-ctx setup/doctor --fixruns and MCP-start hook refreshes copied the installing session'sLEAN_CTX_PROJECT_ROOTandLEAN_CTX_EXTRA_ROOTSinto user-global agent configs (~/.codex/config.toml,~/.grok/config.toml, global JSON MCP entries), so every later session of that agent opened the same project. The Codex and Grok entries are cleaned on the next agent refresh;lean-ctx doctorreports remaining pins under "Project binding" andlean-ctx doctor --fixremoves them line by line, keeping key order and comments (a pin that shares a line with other keys is listed for a manual edit).LEAN_CTX_EXTRA_ROOTSvalues move intoextra_roots; per-project entries in~/.claude.jsonare left alone. Restart the agent once afterwards. - Telemetry: the daily aggregates report more (see Changed), and setup no longer asks: setup and the first interactive command after this update print a three-line notice instead. Turn telemetry off any time with
lean-ctx telemetry off,DO_NOT_TRACK=1orLEAN_CTX_TELEMETRY=off; an explicit opt-out made since 3.11.0 stays in effect, andlean-ctx telemetry showprints the exact payload. What the server keeps, including a keyed network hash and the network operator's public name derived from the connection (never the IP address), and how long, is described at leanctx.com/privacy.
Security
- Agent shells can no longer loosen lean-ctx itself.
lean-ctxis on the default shell allowlist, so an agent could runlean-ctx yolo --yes,lean-ctx allow <cmd>,lean-ctx allow-path <dir>,lean-ctx trust,lean-ctx security open,lean-ctx security secrets offorlean-ctx config set <security key>through ctx_shell (or a hook-rewritten Bash call) and then do what the jail or the allowlist had just refused. Those subcommands are now blocked in agent shells with a message to ask the user; listing (--list,status,config show), narrowing (--remove) and tightening (secure,untrust,security secrets on) still run. Run the blocked commands in your own terminal. - Path jail writes: the new
homescope opens other projects for reading only; writes outside the session's project need an explicitlean-ctx allow-path, so an agent in one repository cannot plant another repository's Git hooks or a binary on yourPATH.
Added
lean-ctx allow-path <dir>admits one directory for reading and writing — outside your home directory, a sibling project to edit, or one protected location — effective on the next tool call without a restart.--listshows the jail scope and added directories;--removetakes one out. It refuses/, the home directory and any directory containing it.lean-ctx security statusshows the active jail scope, andlean-ctx doctorreports global project pins.
Changed
- A refused path names the one command that admits it (
lean-ctx allow-path <dir>, offered for the enclosing project) for the user to run in their terminal. The previous hints to open a new IDE window or set an env var that the running server cannot see are gone. - When a stale
LEAN_CTX_PROJECT_ROOTpin is still set and the MCP server starts inside a different real project, the session binds to that project and logs a warning. Host-specific roots (CLAUDE_PROJECT_DIR, workspace folders) keep their precedence. - Telemetry reports where and how long LeanCTX runs, as coarse ranges. The daily heartbeat adds the runtime environment (local, container, Codespaces, Gitpod, Replit, cloud agent, CI), the installation age (under an hour … 30+ days) and the number of active days in the last 30 (1 … 15+), each as a closed value. They let usage numbers separate people from short-lived agent sandboxes. No machine, account, network or path information is sent. The disclosure lists the new category, so every installation sees the one-time notice again;
DO_NOT_TRACK=1,LEAN_CTX_TELEMETRY=offandlean-ctx telemetry offstill turn telemetry off. - The install channel is detected. It was
unknownfor every installation because no build set it; it now follows the location of the running executable (npm, Homebrew, cargo, PyPI, AUR, release binary). Only the channel name is sent. - Telemetry reports token savings and per-tool latency. The daily tool aggregate adds the day's total tool-output tokens before and after compression, and each built-in tool's summed latency. Counts only; no content.
- Telemetry includes the daily usage record and why tools fail. The batch carries the last 90 days of the installation's own
lean-ctx gainrecord (operations and tokens before/after compression per day, lifetime totals, month of first use), so usage through shell hooks and before telemetry is counted. Failed tool calls are reported by class (invalid input, not found, permission, policy, timeout, edit conflict, too large, unavailable), together with the five most frequent error messages per tool and day as templates: the client replaces every quoted text, path, file name, number, identifier, URL and e-mail address with a placeholder before anything is sent, and drops a message entirely when no safe wording remains. Shell commands that exit non-zero are now reported ascommandinstead ofinternal. - Upgrades turn on telemetry that was only off by the old default. Before 3.11 telemetry was opt-in, so
telemetry.enabled = falsewithout a recorded choice is re-enabled once on upgrade, and the one-time notice explains it. An opt-out made since 3.11 (lean-ctx telemetry off, declining in setup, and now alsolean-ctx config set telemetry.enabled false) is recorded as explicit and never overridden;DO_NOT_TRACK=1andLEAN_CTX_TELEMETRY=offalways win, and a read-only config is left untouched. - Telemetry counts which LeanCTX features are used. A daily
feature_aggregatereports how often each CLI command runs (lean-ctx pack export→cli.pack.export,graph build,index build-full,telemetry off…) and every graph, BM25 and semantic index build with its failures. Commands and verbs come from a fixed registry; arguments, paths and queries never become part of a code, and hot-path commands (shell hooks,-c,read,grep, statusline) are not counted. - Telemetry names 21 more AI clients. Cline, Roo Code, Kilo Code, Continue, OpenCode, Goose, Amp, Augment, JetBrains, Warp, Trae, Qwen Code, Crush, Claude Desktop, ChatGPT, LM Studio, Copilot CLI, Visual Studio, Neovim, Emacs and Factory are reported as their own family, and
noneseparates installations used only through the CLI and shell hooks from an unrecognised MCP client (other). The client's name is never sent, and what LeanCTX offers each client over MCP is unchanged. - Setup no longer asks about telemetry. Setup and the first interactive command after an install or update show a three-line notice instead: telemetry is on, how to turn it off (
lean-ctx telemetry off, orenabled = falseunder[telemetry]in theconfig.tomlit names) and where to see what is sent. The full list stays onlean-ctx telemetry on|offand the payload onlean-ctx telemetry show. An earlier explicit choice is kept.
Fixed
- ctx_shell output capture works in your project. Redirects and
tee(> build.log,>> notes.txt,| tee out.txt) were refused everywhere except/tmp,$TMPDIRandwrite_allow_paths; the project root stayed refused even when listed, andallow_paths/extra_rootswere not consulted. Capture may now also go to the session's project and the jail's allow entries./,~, its ancestors andread_only_rootsare never capture targets; downloads (curl -o,wget,dd of=) keep the scratch-only rule. - ctx_shell no longer relocates, queues or throttles your builds. Three multi-agent build settings were on by default:
agents.shared_cargo_targetpointed everycargo build/testrun through ctx_shell at<data dir>/build-cache/cargo-target, so./targetkept a stale binary;agents.serialize_build_commandsmade each build wait for builds from other sessions on the machine;agents.cargo_build_jobs = 3capped cargo at three jobs. All three are now opt-in (false,false,0) and documented in the config reference under[agents]. Set them again inconfig.tomlif you relied on the shared cache. - ctx_shell walk hint judges each invocation on its own (#2027). A scoped
grep -r … tarifffollowed by a stdin-readinggrepin the same command line (…; echo x | grep -c x,| grep -v _test) was treated as a recursive walk of the working directory, so the hint named.claude/worktrees/,node_modules/or.venv/although nothing entered them. Only invocations that walk (find, or a grep-like with its own-r/-R) now contribute search roots. Withraw: truethe hint is no longer appended, matching the verbatim promise. lean-ctx updateandenable-gpuno longer require acosignbinary. 3.11.0 verified release signatures by runningcosign, so on machines without it every binary update andenable-gpustopped with "cosign is unavailable; refusing unsigned release". The updater now verifies the keyless signature in-process: the certificate must chain to the embedded Sigstore Fulcio root, carry a valid SCT from the Sigstore CT log, name the release workflow at the exact release tag with the GitHub Actions OIDC issuer, and sign the file. Whencosignis installed it still runs as an additional check (Rekor transparency log). 3.11.0 installations cannot self-update to this release unlesscosignis onPATH(winget install -e --id Sigstore.Cosign,brew install cosign, or a binary from github.com/sigstore/cosign/releases); alternatively reinstall with the install script (macOS/Linux), npm, Homebrew or Cargo, or replace the binary from the release archive.- Semantic index builds keep their progress. Embeddings were written only after the last chunk, and
lean-ctx index build-semanticgave up after 10 minutes, which ended the process and discarded the work — on CPU-only machines and with larger models the index was never built. Builds now save finished files every minute and on errors, Ctrl-C or memory aborts, the next run resumes where the last one stopped, and the CLI waits until the build finishes.index statusanddoctorreport an interrupted build aspartialwith the resume command. ctx_indexbuilds the semantic index in the background.build-semanticandbuild-fullno longer block the tool call, wait for the BM25 index instead of embedding an empty or stale one, and a per-project lock keeps two processes from building the same semantic index at once.- CLAUDE.md is read in full. Automatic
ctx_readmodes (and redirected native reads) returned a large CLAUDE.md as a headings-only map, because only SKILL.md, AGENTS.md and a few rule files were treated as instructions.CLAUDE.md,CLAUDE.local.md,GEMINI.md,copilot-instructions.md,.windsurfrules, and documents under.claude/agents/and.claude/commands/are now always delivered complete. redirect_excludeworks again. The key was loaded but never applied, so listing a file there changed nothing. Matching paths (globs on the trailing path components, e.g.CLAUDE.md,*.json,docs/**) now skip the native-read hook redirect and are returned in full by automaticctx_readmodes;LEAN_CTX_HOOK_EXCLUDE(comma-separated) takes precedence, as documented since 2.17.4.lean-ctx index build/build-fullno longer stop after 5 minutes while graph and BM25 are still building, which ended the process before the index was saved. A build worker that fails unexpectedly now always releases its slot, so the command reports the failure instead of waiting.
Upgrade
lean-ctx update # recommended (auto-downloads + refreshes shell hooks)
cargo install lean-ctx # or
npm update -g lean-ctx-bin # or
brew upgrade lean-ctxNote: After upgrading via cargo/npm/brew, run
lean-ctx setupto refresh shell aliases.lean-ctx updatedoes this automatically.
Full Changelog: v3.11.0...v3.11.1