github yvgude/lean-ctx v3.8.12

4 hours ago

Added

  • Addon ecosystem — lean-ctx addon (#858). A package manager for community
    extensions: an addon wraps an external MCP server behind a small
    lean-ctx-addon.toml manifest and plugs into the MCP gateway with one
    lean-ctx addon add — no fork, no recompile. list / search / info browse
    a curated registry (bundled rust/data/addon_registry.json, overridable per
    entry via <data_dir>/addon_registry.json); add resolves a registry name or
    a local manifest path, discloses the exact transport/command/args/env it will
    run, then — after confirmation (--yes to skip; refuses non-interactively
    without it) — wires a [[gateway.servers]] entry via the safe global-only
    Config::update_global path and records it in <data_dir>/addons/installed.json;
    remove unwinds exactly what it wired. Registry entries without a runnable
    [mcp] block are listed (directory + homepage link), never installed with
    fabricated wiring. Reuses the gateway trust model (global-only, opt-in) and the
    cli::prompt confirmation gate; no new config section, so schema parity is
    untouched. Manifest, registry and install logic live in small, unit-tested
    core::addons::{manifest,registry,store,install} modules. Spec:
    addon-manifest-v1 · guide:
    docs/guides/addons.md.
  • Repo-stack-aware profile recommendation — lean-ctx profile suggest (#851).
    Scans the current repo for deterministic, local signals (languages + source-file
    count, monorepo layout via pathutil::has_multi_repo_children + workspace
    markers, build/CI markers, configured LLM providers) and recommends a context
    profile plus key settings (profile, output_density, proxy.history_mode;
    proxy.effort is left off — it is never inferred from a repo). Prints the exact
    export / config set commands to apply it, plus task-oriented alternatives
    (ci-debug first when CI is detected, then hotfix/bugfix/review). Strictly
    read-only — it never writes config. --json for scripting. The mapping
    (core::profile_suggest::suggest) is a pure, unit-tested function separated from
    the gitignore-aware scan, so the suggestion is a deterministic function of the
    repo + environment (no network, no telemetry).
  • Review-before-overwrite for consequential CLI writes (#852). State-mutating
    writes that could clobber existing state now print a before→after diff plus a
    risk note and require confirmation (or --yes) — mirroring the yolo / secure
    pattern, and refusing to run non-interactively without --yes. Covers
    lean-ctx config set for security/egress-relevant keys (path_jail,
    shell_security, sandbox_level, secret_detection.*, boundary_policy,
    proxy.*_upstream) and lean-ctx knowledge remember when it would overwrite an
    existing fact with a materially different value (the prior value is archived).
    The knowledge gate reuses the exact overwrite predicate the write path applies
    (check_contradiction), so additive, identical, near-identical (>0.8 similarity)
    and no-op writes stay frictionless. The shared prompt/confirm helper is now a
    single cli::prompt module (extracted from security_cmd), and config-key risk
    classification lives in core::config::risk — deterministic and local-only. The
    MCP ctx_knowledge tool path is unchanged (agent writes stay versioned and
    contradiction-warned without an interactive gate).
  • Tool & rule budget — lean-ctx tools health (#848). A deterministic,
    local-only "rot" report answering whether every always-on token earns its
    place. Cross-references the fixed cost of each advertised MCP tool schema,
    the MCP instructions, and every auto-loaded rules file with recorded usage
    (the post-dispatch cost ledger) to flag: tools that cost schema tokens every
    session but are never called (unused), heavy-schema tools used for <1% of
    calls (low-use), rules files that bill the same guidance to a client more
    than once, and stale knowledge facts (>30d, never retrieved). Reuses existing
    telemetry and adds no new hot-path cost — per-tool last_used rides the
    cost-attribution write that already happens. Text (rot candidates only; --all
    for the full list), --json for scripting, and a Tool Budget panel in the
    dashboard health view (/api/tools-health). Never auto-applies: every finding
    is a suggestion (lean-ctx tools lean, lean-ctx rules dedup --apply).
  • Cache-safe cross-provider reasoning-effort control — proxy.effort (#834).
    One opt-in setting (off | minimal | low | medium | high) pins a single
    reasoning-effort level across all three providers without breaking the provider
    prompt cache. lean-ctx translates the constant level to each provider's native
    parameter — OpenAI reasoning_effort / reasoning.effort, Anthropic
    output_config.effort, and Gemini thinkingConfig (thinkingLevel on 3.x,
    thinkingBudget on 2.5 pro/flash) — only on models that accept it and only when the
    client didn't set its own value. Unlike per-turn "effort routing" (which flips
    effort between turns and invalidates the cache — OpenAI lists effort changes as a
    cache-invalidation cause; Anthropic breaks its message-cache breakpoints), the level
    is a constant, so the cached prefix stays byte-stable (#448/#498) and only the
    model's reasoning depth changes. Conservative by design: off is a strict no-op, it
    never overrides a client value, never enables reasoning the client didn't ask for
    (Anthropic adaptive-only; Gemini skips 2.5 flash-lite and never sends both thinking
    fields), is model-gated (never turns a working 200 into a 400) and deterministic.
    lean-ctx proxy status surfaces the active level plus per-provider steer counts. Set
    via proxy.effort or the LEAN_CTX_PROXY_EFFORT env (env wins).
  • Unified security posture + lean-ctx yolo / secure master switches (#507).
    Decouples lean-ctx's two independent security planes and makes them discoverable:
    containment (path jail + shell gating — protects the machine from the agent)
    vs secret defense (.env/credential redaction — protects secrets from the LLM
    provider). lean-ctx security status prints a posture board (and a coarse
    STRICT / RELAXED / OPEN label) reused by lean-ctx doctor, which now also shows a
    dedicated Secret redaction line. lean-ctx yolo (alias security open) drops
    containment in one step — writes path_jail = false + shell_security = "off",
    takes effect immediately, and deliberately keeps secret redaction on;
    lean-ctx secure (alias security strict / lockdown) restores the secure
    defaults. The standalone .env switch is lean-ctx security secrets <on|off>.
    path_jail is now a first-class, schema-documented config key (the blanket
    "any path" opt-out, equivalent to allow_paths = ["/"]), so granular re-enabling
    via lean-ctx config set … / lean-ctx allow <cmd> composes cleanly after a
    yolo. Disabling either plane requires a confirmation (or --yes) and refuses to
    run non-interactively, so an agent can never silently weaken security.
  • Observation tier — synthesized, recall-prioritized entity summaries (GL #802).
    A 9th cognition-loop step distils clusters of related facts into compact,
    per-entity observations (Hindsight-inspired). Synthesis is deterministic by
    default
    — facts are grouped by an entity anchor (file path in key/value, else
    category) and each cluster of ≥ cognition_synthesis_min_cluster (default 3)
    facts is written through the normal remember() path, so versioning, persistence
    and idempotency come for free and the value stays byte-stable (#498). An optional
    LLM refinement sits behind llm.enabled with the deterministic digest as
    fallback. Recall gives a balanced boost to relevant synthesized observations
    (above incidental matches, below an exact key hit). Facts are now epistemically
    typed
    on write (evidence vs. inference) via infer_from_category, feeding
    salience and — opt-in via archetype_aware_decay — slower decay for structural
    evidence. Gated by cognition_loop_max_steps >= 9 (the new default; set 8 to
    disable); visible as observation_synthesis in lean-ctx introspect cognition.
  • Configurable shell-security mode — enforce | warn | off (GL #788). One
    switch now governs all command gating (the allowlist and the hard blocks:
    eval/exec/source, $()/backticks at command position, interpreter -c),
    applied at a single chokepoint so MCP ctx_shell and the CLI (lean-ctx -c/-t)
    behave identically. enforce stays the secure default; warn runs every check
    but only logs violations; off is a deliberate opt-out that skips gating entirely
    while compression stays fully active. Set via shell_security in config or
    the LEAN_CTX_SHELL_SECURITY env (env wins; unknown values fall back to
    enforce, never fail open). off does not lift the read-only-output doctrine
    (no >/tee/heredoc writes via shell). lean-ctx doctor surfaces the active
    mode whenever it is not enforce. Supersedes the CLI-only
    LEAN_CTX_ALLOWLIST_WARN_ONLY (kept for backward compatibility).
  • /v1 contract clients published under one name — lean-ctx-client. The thin,
    engine-independent clients now ship on every registry under a single consistent
    name: PyPI (import module stays
    leanctx), npm, and
    crates.io. Replaces docs that pointed
    at an unrelated third-party leanctx / unpublished @leanctx/sdk (GL #783). A
    dedicated, idempotent publish-clients.yml workflow ships the family independently
    of the engine.
  • Cognition v2 — science-grounded context engineering, deterministic by default,
    provably active.
    Ten neuroscience/physics-motivated mechanisms are wired to
    real hot-path call sites and made inspectable via lean-ctx introspect cognition
    (each subsystem reports wired/active/last-run/count; also surfaced in lean-ctx doctor). All decision layers are deterministic by default (Rule #498 / prompt
    cache intact); stochastic exploration is gated behind LEAN_CTX_STOCHASTIC.
    • Time-variant Φ (attention). Context salience is recomputed and EMA-blended
      on every re-read instead of being frozen on first sight (context_ledger).
    • Ebbinghaus forgetting + spacing effect. Knowledge confidence decays as
      R = exp(-Δt/S) with stability S growing per retrieval, replacing linear
      decay. Configurable via forgetting_model (ebbinghaus|linear),
      base_stability_days, and LEAN_CTX_LIFECYCLE_FORGETTING (memory_lifecycle).
    • Hebbian eviction. Co-accessed cache entries protect each other from
      eviction ("fire together, wire together") via a deterministic association bonus
      (cache, hebbian_cache).
    • Complementary-learning-systems consolidation. Idle/loop replay lifts the
      confidence of related, frequently-retrieved facts (cognition_loop).
    • Integration-aware Φ (IIT non-redundancy / MMR). The context compiler now
      selects via greedy Maximal-Marginal-Relevance and deduplicates on content
      (fixes a bug that compared file paths), so near-duplicate items collapse to
      one (context_compiler, context_field).
    • Global-workspace ignition. High-salience Φ-outliers (z-score > θ, default
      LEAN_CTX_GWT_IGNITION_Z) are broadcast/pinned and resist reinjection
      downgrades (context_ledger, context_gate).
    • Learned field weights (bandit). Φ field weights are chosen by a Thompson
      bandit — deterministic argmax-of-posterior-mean by default, sampling only under
      LEAN_CTX_STOCHASTIC (bandit, context_field, adaptive_thresholds).
    • Sharp-wave-ripple idle replay. A quiet gap (default 300 s,
      LEAN_CTX_COGNITION_IDLE_SECS) triggers a deeper replay-consolidation pass in
      the background (cognition_scheduler, cognition_loop).
    • FEP prefetch (active inference). After a read, likely-next files from the
      co-access graph are surfaced as a deterministic warmup hint — never an automatic
      read (fep_prefetch, context_gate).
    • Immune detector (artificial immune system). External provider data is
      screened for prompt-injection/poisoning before it can become a fact, edge or
      cache entry; untrusted workspaces get a stricter screen (coupled to Workspace
      Trust) (immune_detector, consolidation, ctx_provider).
  • lean-ctx introspect cognition / introspect qubo. New CLI to prove which
    cognition subsystems are wired and active, and to run the experimental
    QUBO-vs-greedy selection benchmark.
  • QUBO selection spike (research only). A deterministic simulated-annealing
    QUBO solver and benchmark harness for redundancy-aware context selection, gated
    behind LEAN_CTX_EXPERIMENTAL_QUBO. On clean problems it reaches parity with the
    greedy knapsack (no measurable win), so greedy remains the default; promotion
    is conditional on a future measurable gain (qubo_select).
  • Opt-in debug log — LEAN_CTX_DEBUG_LOG / lean-ctx debug-log (#520). A
    human-readable, off-by-default trace of every MCP tool call (tool, arguments,
    outcome) and every shell-hook routing decision (compress / track / pass-through
    and why), for diagnosing "why did lean-ctx do X?" without attaching a debugger.
    Enable via the LEAN_CTX_DEBUG_LOG env (truthy) or lean-ctx config set debug_log true; read or clear it with lean-ctx debug-log (--clear). Writes
    to a single rolling file under the state dir; never on the hot path when
    disabled, and the body carries no secrets (arguments are redaction-screened).
  • In-band remote-proxy expansion marker — <lc_expand:HASH> (#493). Lets the
    cold-prefix/CCR retrieval layer work through a remote proxy with no shared
    filesystem: the model can emit a <lc_expand:HASH> marker in its output and the
    proxy splices the referenced content back in band, across all three providers
    (OpenAI chat + responses, Anthropic, Gemini). Opt-in and cache-safe by
    construction (the marker is deterministic), follow-up to #482.

Security

  • Shell allowlist now enforced on the -t / track path (external audit, finding 1).
    exec_argv (used by the default shell hook _lc() { lean-ctx -t "$@" } for
    multi-arg commands) never called check_shell_allowlist, so every aliased
    invocation like _lc git status bypassed the restriction that lean-ctx -c
    enforces. Both paths now share a single allowlist_gate, so the track path
    blocks non-allowlisted commands (exit 126) exactly like the compress path.
  • Agent API keys are no longer captured or forwarded to ctx_shell children
    (external audit, finding 2).
    The agent-runtime-env bridge forwarded every
    CODEX_*/CLAUDE_*/OPENCODE_*/GEMINI_*… var — including *_API_KEY,
    *_TOKEN, *_SECRET, *_PASSWORD — into the env of every command the agent
    ran, where output redaction can't stop network exfiltration. is_forwardable
    now excludes credential-shaped names (only session/thread identifiers cross the
    bridge), and load retroactively scrubs such vars from any capture file
    written by an older build, removing the plaintext secret at rest.
  • Path-jail relaxations are now surfaced loudly (external audit, finding 3).
    path_jail = false, the no-jail build feature and the env channels
    (LEAN_CTX_ALLOW_PATH, LEAN_CTX_EXTRA_ROOTS, LEAN_CTX_ALLOW_IDE_DIRS) that
    widen or disable the jail are inherited from the IDE/launchd env and previously
    loosened the boundary with no in-band signal. The MCP and HTTP servers now emit
    a [SECURITY] warning at startup for each active relaxation, and lean-ctx doctor reports env-channel relaxations alongside the config-level ones.
  • Workspace Trust for project-local .lean-ctx.toml overrides (external audit,
    finding 4).
    A cloned repo's .lean-ctx.toml is merged over the global config
    and could raise security-sensitive settings — replace the shell allowlist, widen
    the path jail (allow_paths/extra_roots), repoint the proxy upstream, define
    command aliases, change rules_scope/rules_injection. For an untrusted
    workspace those overrides are now withheld (comfort knobs like
    compression/theme still apply) with a [SECURITY] warning; lean-ctx doctor
    shows the state. Grant trust with lean-ctx trust (and lean-ctx untrust /
    lean-ctx trust status / --list); trust is pinned to the workspace path and
    a content hash of .lean-ctx.toml, so editing the file re-gates it. Headless use
    can opt in via LEAN_CTX_TRUST_WORKSPACE=1 or LEAN_CTX_TRUSTED_ROOTS.

Changed

  • Change-aware pre-push gate + no-test advisory (#850/#849). scripts/preflight.sh
    now classifies the diff against origin/main: a docs-only push (README, CHANGELOG,
    *.md, website, scripts) skips the Rust gates (fmt/clippy/rustdoc/Windows
    cross-compile) and the pre-push hook finishes in ~0.1 s instead of ~140 s.
    gen_docs --check still runs whenever Rust or a committed file under
    docs/reference/generated/** changed. CI is unchanged and remains the source of
    truth (a docs-only diff cannot turn a Rust gate red, so the local skip can never
    cause a local-green / CI-red split); make preflight forces the full gate. A change
    to contract code (proxy/, tools/, config/schema/) with no test signal in the
    diff prints a no-test advisory — blocking under LEAN_CTX_PREFLIGHT_STRICT_TESTS=1.
  • Faster semantic search on a native ONNX Runtime (#497). The
    embedding/index stack moves from the pure-Rust rten backend to native ort
    (ONNX Runtime 2.0), with a rebuilt indexing pipeline (int8-quantized vectors,
    tighter HNSW, a compact postcard on-disk format). ONNX Runtime is loaded at
    runtime (ort's load-dynamic), resolved across platforms from ORT_DYLIB_PATH,
    Nix profiles, and well-known system locations — so it is provided once by the
    platform onnxruntime package (declared as a dependency in the Arch/Homebrew
    packages), pip install onnxruntime, or a manual ORT_DYLIB_PATH. The ort
    crate is exact-pinned (=2.0.0-rc.12) until a stable 2.0 ships. One-time
    re-index:
    the new index format is not backward-compatible; the first semantic
    search after upgrade rebuilds the index automatically (a load-time version guard
    removes any stale index rather than risk mis-decoding it). The jina-code-v2
    built-in (pre-existing broken) is removed; code-specialized embeddings remain
    available through the hf:org/repo[@rev] custom scheme
    (hf:jinaai/jina-embeddings-v2-base-code), which auto-probes the model's
    ONNX I/O signature. Thanks to @omar-mohamed-khallaf for the optimization work.
  • lean-ctx bypass renamed to lean-ctx raw (external audit, finding 5).
    The "bypass" wording read to a model like a security bypass, but it only
    skips output compression — the shell allowlist and path jail still apply.
    lean-ctx bypass stays as a back-compat alias; model-visible hints now use
    raw and state that the allowlist still holds.
  • Fewer, less-duplicated MCP read tools (#509 Phase 1+2 / #527, #528, #532).
    The read-variant cluster (ctx_smart_read, ctx_multi_read) folds into a
    single ctx_read (multi-path + auto mode); the former tool names stay as
    deprecated aliases that still work but no longer cost schema tokens in
    tools/list, shrinking the always-on surface. Internally, ctx_read modes are
    now a type-safe ReadMode vocabulary (parsed once, FromStr/Display) instead
    of ad-hoc strings, with behavioural-equivalence tests and the eval A/B gate
    guarding zero output regression. SessionCache is retained (the decoupling
    thesis was evaluated and rejected as net-negative).
  • Configurable ctx_shell timeouts + opt-in writes (#526 / #523, #529). The
    hard-coded 2-min / 10-min shell ceilings are now tunable via shell_timeout_secs
    and shell_heavy_timeout_secs (env LEAN_CTX_SHELL_TIMEOUT*), and the read-only
    output doctrine can be relaxed deliberately with shell_allow_writes (env
    LEAN_CTX_SHELL_ALLOW_WRITES) so a trusted operator can permit >/tee/heredoc
    writes through ctx_shell — off by default, part of making prohibitive security
    opt-in rather than absolute (#526).
  • Leaner always-on tool & rules schema (#510/#517, #505/#508). Power-tier tool
    descriptions are reworked workflow-first and de-duplicated, and the optimized
    tools schema + canonical rules consolidation land, trimming the fixed
    per-session token cost of advertised tools and auto-loaded rules without
    changing behaviour (eval-gated).

Fixed

  • config set now accepts every valid Option config key (persona,
    bypass_hints) instead of rejecting them as "Unknown config key" (#856).

    config set resolves keys via the hand-written schema (ConfigSchema::lookup)
    only. An Option<_> scalar field defaults to None, so serde omits it from
    Config::default() and it never appears in config_derived_keys() (which feeds
    only config validate/apply). Any such field that wasn't hand-registered was
    therefore accepted from config.toml but rejected by config set and flagged
    "unknown" by config validate — the class behind the path_jail report (fixed
    earlier in #507). Auditing all 17 root-level Option fields found two more:
    persona and bypass_hints are now registered in the root schema (persona
    as an open string so custom <name>.toml personas stay valid; bypass_hints
    as enum(on|off|aggressive) so config set validates the value). A new
    regression test (option_scalar_keys_are_cli_settable) asserts the
    Option-scalar knobs resolve via schema lookup, guarding the whole class.
  • lean-ctx -c no longer kills hook-running git commit/git push at the
    2-minute default (#854).
    The shell wrapper enforces DEFAULT_TIMEOUT (2 min)
    on ordinary commands and HEAVY_TIMEOUT (10 min) on build/test commands, but
    git commit/git push were treated as ordinary — even though, in a repo with
    hooks, git commit fans out into cargo clippy (pre-commit) and git push
    into the full scripts/preflight.sh (pre-push), each of which routinely runs
    3–10 min. The wrapper SIGKILLed git mid-hook, leaving the tree
    staged-but-uncommitted or the push half-done. is_heavy_command now classifies
    git commit and git push as heavy (10-min ceiling, 32 MB buffer); read-only
    verbs (git status/log/diff) stay on the default ceiling because matching
    is on the full git <verb> prefix.
  • Hybrid/dense cold-start no longer re-embeds the whole corpus inline (#512).
    On a large repo, the first ctx_semantic_search mode=hybrid (or dense) call on
    an MCP server that started before the on-disk dense index existed would embed the
    entire corpus under the 120s per-request watchdog. The watchdog abandons the response
    but cannot cancel the spawned compute, so the embed kept running — observed as a 500%+
    CPU child for >10 min after the call "returned". A new cold-start guard counts the
    chunks a re-embed would touch (EmbeddingIndex::pending_chunk_count) and, above a
    budget (default 2000 chunks, tunable via LEAN_CTX_HYBRID_INLINE_EMBED_MAX; 0
    disables — the pre-#512 behavior), refuses the inline embed across all four search
    entry points
    (hybrid/dense × the MCP tool and the CLI/editor search_hits path):
    hybrid degrades to the coherent BM25(+graph) ranking (the same fallback used when
    dense is disabled) and dense fails fast — both with a one-line hint to build the
    index once, out of band (lean-ctx index build-semantic). Warm and incremental paths
    (a few changed chunks on an existing index) are untouched and still embed inline.
  • Shell-output compression can no longer inflate token counts (Windows CI
    flake).
    The VCS branch of compress_output (git/jj/gh/glab/hg) returned its
    authoritative compressor's result even when it was not strictly shorter — so a
    compact git log --oneline stays verbatim — but it skipped the token guard the
    other paths use. A tiny adversarial git status body could reshape into a
    one-token-larger summary, breaking the compress_output_never_inflates_tokens
    property on Windows. The VCS path now allows equal (verbatim) output but
    rejects any growth, restoring the never-inflate invariant deterministically.
    Pinned with a regression unit test for the exact failing input.
  • Cold-prefix repack is now sticky, persistent, and marker-stable (#499). Three
    fixes to the opt-in big-gap repack (#480): (1) once a resumed conversation is judged
    cold and repacked, the decision latches so every warm follow-up keeps the same
    deterministic prefix compression and hits the cache written at the cold turn — the
    previous one-shot repack re-sent the uncompressed prefix on the very next turn and
    busted its own fresh cache (net-negative for the common resume-then-continue case);
    (2) per-conversation baselines now persist to disk (cold_prefix_touch.json,
    atomic write) and reload on proxy startup, so a long idle gap that straddles a daemon
    restart is still detected; (3) the conversation key ignores the volatile
    cache_control marker
    , so a moving cache breakpoint no longer flips the key into a
    permanent first-sighting that never repacks. All three are cache-safe by construction
    (deterministic re-compression) and covered by new N→N+1, restart, and marker-stability
    tests. Thanks to @phawrylak for the precise analysis.
  • gain no longer reports 0 saved when MCP tools wrote to a different data
    dir (#500).
    The savings headline, gain score, cost view and net-of-injection
    line now sum stats across every auto-resolved data dir that holds a
    stats.json. When an agent host launches the lean-ctx MCP server with a
    different HOME/XDG_* than the user's shell (e.g. a containerised Hermes
    Agent) the savings landed in a sibling tree while the CLI read an empty primary
    dir and showed a false zero. Aggregation is a no-op without a split and is
    skipped entirely when LEAN_CTX_DATA_DIR pins one dir, so non-split users are
    unaffected. The empty-state screen now also cross-checks the tamper-evident
    savings ledger and, when it holds events that stats.json does not, names the
    data-dir split outright (lean-ctx savings / lean-ctx doctor). Finally, the
    proxy "bridge OFF — savings cannot be measured" caveat is suppressed whenever
    there are real (MCP-measured) savings to show, since gain measures MCP-tool
    savings directly and needs no proxy. Thanks to the reporter for the detailed
    Hermes + OpenRouter writeup.
  • Billing edge no longer downgrades a paying account on a billing-service blip
    (GL #785).
    Entitlement resolution at the cloud edge now caches each user's
    last known plan (in-memory, short TTL) and, when the upstream billing service
    is unreachable or returns a bad response, serves that cached plan instead of
    silently falling back to Free. Successful lookups refresh the cache; only
    never-seen accounts fall to Free. A transient upstream outage can no longer
    lock a Pro subscriber out of paid features mid-session.
  • Windows PowerShell/cmd no longer rewrites the lean-ctx path (#518 / #521).
    The terminal-integration shell hook used a Unix-style /c/... path that
    PowerShell and cmd can't execute, so lean-ctx invocations failed on Windows.
    The hook now emits the native binary path on PowerShell/cmd, restoring terminal
    integration there.
  • No more flaky ORT SIGSEGV on process exit (#519 / #522). Short-lived
    processes that loaded the ONNX Runtime model could crash with a ~30% flaky
    SIGSEGV/EXC_BAD_ACCESS during static OpSchema teardown at exit (arm64
    macOS). lean-ctx now skips the detached ORT model load in short-lived processes
    that won't use it, removing the teardown crash without affecting real search.
  • Inherited LEAN_CTX_ACTIVE no longer silently disables compression (#533 /
    #537).
    LEAN_CTX_ACTIVE served double duty as both a shell-hook re-entrancy
    guard and a compression bypass; when an agent (e.g. Codex) inherited it into the
    MCP server's environment, every tool output came back uncompressed. Re-entrancy
    ownership now rides a dedicated LEAN_CTX_WRAPPED marker, so an inherited
    LEAN_CTX_ACTIVE no longer turns compression off.
  • ctx_read raw:true / mode=raw now honored and documented (#513 / #514).
    The verbatim escape hatch was silently ignored on the raw:true argument and
    undocumented for mode=raw, so non-Opus models (GLM 5.2 report) fought the
    compression by retrying reads. Both forms now reliably return uncompressed,
    un-elided bytes and are documented as the way to get exact file content.
  • allow_paths / shell_allowlist_extra failures are no longer silent (#540 /
    #541, #542).
    Two invisible-over-MCP failure modes are surfaced at the point of
    the block: (1) a project-local .lean-ctx.toml whose security-sensitive
    overrides are withheld because the workspace is untrusted now names the
    ignored keys and the lean-ctx trust / global-config remedies; (2) when the
    runtime resolves a global config.toml that doesn't exist (an edit that
    landed in a different dir — XDG vs legacy ~/.lean-ctx, or a sandboxed/container
    $HOME), both the allowlist and path-jail block messages now say so and name
    the path actually read. The stderr-only tracing::warn was invisible to MCP
    clients (OpenCode), making these read as "the setting does nothing".

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.12...v3.8.12

Don't miss a new lean-ctx release

NewReleases is sending notifications on new releases.