Skip to content

v3.8.6

Latest

Choose a tag to compare

@github-actions github-actions released this 15 Jun 12:20
· 11 commits to main since this release

Added

  • CodeBuddy AI platform support (#423) — CodeBuddy joins Claude Code / Codex
    as a first-class agent: detection, init / setup / uninstall, MCP wiring
    at ~/.codebuddy/mcp.json, dedicated rules injection, and the same path-jail
    protection as .claude / .codex (~/.codebuddy in IDE_CONFIG_DIRS, the
    broad-root guard, and the home/agent-dir checks). Thanks @studyzy.
  • Structure-first cold reads (structure_first, #361) — an opt-in bias (off
    by default; env LEAN_CTX_STRUCTURE_FIRST) for auto to prefer map on a
    cold read of a medium-sized source file. It is the one read saving that
    survives a phase-isolated harness (no warm-session re-read to amortise a full
    read) and is capability-safe: the active-diagnostic / edit-fail / small-file
    guards still force full.
  • gain now reports net-of-injection bill impact (#361)lean-ctx gain
    (and gain --json) surface the observed proxy turns, the total injected
    overhead (per-turn tax × turns) and net_tokens_saved (which can go negative
    and says so), so the meter reconciles to the provider bill instead of a
    tool-local ratio. The proxy persists its request count to make this honest.
  • Faithful benchmark arm config (#361)bench/agent-task/r2/ ships a
    zero-injection, capability-safe lean-ctx arm (rules_injection=off, minimal
    tool profile, structure_first, proxy on with cache-aware pruning) plus the pi
    extension config and proxy env wiring, so an independent benchmark runs
    lean-ctx "installed = running as designed".

Changed

  • Suspect files are never compressed away on a fix task (#361) — when the
    task text explicitly names a file (e.g. "fix the sort in versioncmp.c"), auto
    now forces full for that file ahead of any compression-favouring intent, so
    the agent always gets the body it needs to localise and edit the defect.
  • The proxy protects build/test fidelity and foreign tools (#361) — a
    generic/foreign shell tool_result that looks like a build failure or test run
    is preserved verbatim at the wire (compiler errors, panics and test summaries
    kept intact), and vendor-prefixed tools (forge_read, pi.shell, …) are now
    classified by name segment so a foreign source read is protected and a foreign
    shell log is compressed. Request-body compression is deterministic, keeping the
    provider prompt-cache prefix byte-stable.
  • The pi extension can route shell through ctx_shell (#361) — a new
    routeShell opt-in (env LEAN_CTX_PI_ROUTE_SHELL, implied by replace mode)
    suppresses the native bash builtin so build/test/log output is compressed and
    metered (lossless for signal), while the read/list/search builtins stay
    available alongside ctx_*.

Fixed

  • [archive] could exhaust host RAM and force a reboot (#417) — archived
    tool outputs (.txt + .meta.json + SQLite FTS) were written on every large
    call, but the configured max_disk_mb / max_age_hours limits were never
    enforced: archive::cleanup() had no production caller and the FTS cap deleted
    only DB rows, orphaning the (much larger) .txt blobs. The store therefore
    grew unbounded on disk and starved the host of RAM via the page cache.
    cleanup() now enforces both the age TTL and the on-disk size budget, prunes
    the content files and FTS index together (no more orphans), runs at MCP start
    and periodically off the hot path, and lean-ctx cache prune reclaims the
    archive too.
  • doctor reported the proxy as broken on Windows (#416) — proxy autostart
    has no backend on Windows, so doctor treated its absence as a hard failure
    (a permanent 27/28). The proxy check is now platform-aware: a reachable proxy
    is green, an unreachable proxy on a platform without autostart is a warning
    (run lean-ctx proxy start), and "running but autostart not installed" is a
    warning rather than a failure on macOS/Linux.
  • setup reported compression settings it never saved (#415) — the wizard
    printed "✓ Compression: …" before writing and swallowed the write error, so a
    failed save still looked successful. Success (and the rules-prompt injection)
    is now reported only after the config is actually persisted. doctor also
    displayed "power" for an unpinned install; it now correctly reports
    "lean (default)".
  • A data dir split across two trees could not be merged (#414) — when both a
    legacy (~/.lean-ctx) and an XDG tree held a stats.json, the old migration
    bailed and doctor pointed at lean-ctx setup instead of doctor --fix.
    doctor --fix now consolidates every non-canonical data tree into the
    canonical one (newer file wins, never clobbering a newer copy) before the XDG
    split, the hint points to the right command, and $XDG_DATA_HOME/lean-ctx is
    included in split detection.
  • JetBrains plugin now ships as a downloadable GitHub Release asset (#418)
    the plugin .zip is built and attached to every release. It was missing from
    v3.8.5 because the plugin's Release Asset job only ran on release events,
    which a GITHUB_TOKEN-created release never triggers. The plugin version is now
    single-sourced in gradle.properties and mirrors the engine release via
    -Pversion=<tag>, so it can no longer drift (it had been stuck at 3.8.3).
  • The wake-up briefing listed dead and foreign agents (#419)ctx_overview
    read the raw AgentRegistry, so it showed peers from crashed or exited MCP
    processes (and from other projects). It now prunes stale entries
    (cleanup_stale) and scopes the list to the current project root, matching
    what ctx_agent list and the dashboard already do.
  • ctx_read map/signatures served pre-rebuild output (#420)lean-ctx graph build --force and lean-ctx index build-full only dropped the in-process graph
    cache, but a running daemon kept serving stale map/signatures from its
    long-lived SessionCache in another process. Both commands now also flush the
    daemon's read cache over IPC (never auto-starting one), so derivations
    re-derive on the next read.
  • ctx_multi_read ignored auto mode (#421) — batch reads forced
    autofull, so every file came back fully expanded regardless of the active
    profile. ctx_multi_read now honours auto like a single ctx_read, resolving
    the optimal mode per file. Tool descriptions, schemas and the injected rules
    (bumped to v12) now steer agents to omit mode (= auto) and reserve full
    for the read immediately before an edit.
  • ctx_semantic_search was hidden in the default profile (#422) — the
    meaning-based search tool was categorised under Memory and absent from the
    lean core set, so it never appeared in the default ("lean") gate. It is now a
    Core tool and part of the advertised core surface; the setup/doctor tool counts
    are derived dynamically instead of a hard-coded "13".
  • A cold read could cost more tokens than the raw file (#361) — an
    independent benchmark measured ctx_read auto-mode payloads up to +21.6%
    larger than the source on a small codebase: on a tiny file the one-line
    framing header (file ref + deps/exports summary) is net overhead that only
    amortises across re-reads, and the CLI one-shot path used a divergent resolver
    that lacked the small-file guard. ctx_read now enforces a hard anti-inflation
    invariant — a read never returns more tokens than the raw file. When
    framing would exceed the bare content (auto-resolved or full reads) the file
    is shipped verbatim, so a read is break-even at worst and a win whenever a
    compressed mode or cached re-read applies; an explicitly requested view
    (map/signatures/lines:) is always honoured untouched. The same guarantee
    now covers the additive one-shot CLI path, which also routes through the
    unified auto-mode resolver. Re-reads are unaffected (the cache keys on path and
    re-derives the file ref). Follow-up: map mode no longer repeats exports the
    API: section already lists with full signatures — the same symbols were
    emitted twice (once as a bare exports: line, once in API:). A shared
    exports_not_in_signatures helper now drives the MCP, CLI and benchmark map
    renderers, so every export is shown exactly once (re-exports/const aliases the
    API can't capture still surface) and the scorecard measures the deduped output
    agents actually receive.
  • A knowledge store could grow to 2× its fact cap on import (#417)
    remember() hard-caps a project's facts at max_facts, but the bulk
    import_facts() path still used the old max_facts * 2 guard, so a
    merge/import could inflate a store to twice its budget before any eviction
    fired (observed live as a doctor capacity CRIT, e.g. facts 232/200). The
    import path now runs the memory lifecycle as soon as it exceeds max_facts,
    draining the excess by importance (archived, not lost). The eviction invariant
    now holds on every write path (remember, import, persist-merge).
  • Knowledge stores for deleted projects accumulated forever (#615) — a store
    at knowledge/<hash>/ is keyed to a project_root; when that root is deleted
    (a removed git worktree, a thrown-away project) the store can never be written
    again, so its eviction cap can never self-heal and it lingers as pure disk
    bloat (one such store surfaced live as a permanent doctor capacity CRIT).
    lean-ctx doctor now reports orphaned stores and the reclaimable size,
    lean-ctx cache prune reclaims them (alongside BM25/graph/archive), and
    doctor --fix prunes them as part of a repair. Detection is conservative — a
    store with an empty (legacy/global) root or a still-existing root is never
    touched, and only the explicit prune commands delete (never the background
    lifecycle), so a temporarily-unmounted drive can't trigger data loss.
  • auto_update_mcp = false was ignored by the hooks-layer MCP writers (#281)
    — the hooks integration still registered and rewrote MCP server entries even
    when auto_update_mcp was disabled, contradicting the setting's contract. The
    hooks-layer writers now honour the flag on every path, so a user who opts out
    of automatic MCP registration is respected (the proxy/daemon paths already
    did).

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-ctx

Note: After upgrading via cargo/npm/brew, run lean-ctx setup to refresh shell aliases. lean-ctx update does this automatically.

Full Changelog: v3.8.6...v3.8.6