github yvgude/lean-ctx v3.6.25

latest release: v3.6.26
3 hours ago

Added

  • Jira Cloud OAuth 2.0 (3LO) (#318): authenticate built-in and custom Jira data sources via the standard 3-legged OAuth flow instead of Basic auth + API token. New lean-ctx provider auth jira runs the interactive flow (loopback redirect, browser consent, accessible-resource/cloudId discovery), persists tokens to ~/.lean-ctx/credentials/jira-oauth.json (0600), and auto-refreshes on expiry with refresh-token rotation. lean-ctx provider list / provider logout round out the surface. The CLI is secret-free: users register their own Atlassian OAuth app and supply the client id/secret via env. Basic auth continues to work unchanged; OAuth is selected automatically when a credential exists or JIRA_AUTH=oauth is set.
  • Context-pressure triage in the Context Cockpit (#249): the Context Manager moves from observation to triage. The Files in Context table gains sortable Used (re-read count), Last (recency), and Evict columns — the Evict score combines high token cost + long idle + rarely re-read so the best eviction candidate is one click away. A triage banner maps the live pressure band to a concrete next action (Healthy / Elevated → prefer map+signatures / High → compress or evict / Critical → evict or handoff pack). The ledger now tracks per-item access_count (backward-compatible via #[serde(default)]).
  • Offline-first Context Cockpit: Chart.js, D3 and the UI fonts are now self-hosted (no external CDN), so the dashboard renders identically offline and with large sessions; libs degrade gracefully with an inline notice if one fails to load. Added a dashboard-wide ⌘K / Ctrl+K command palette with fuzzy search across every view, quick actions (refresh, theme toggle) and full keyboard navigation, plus an embedded favicon and clearer route labels.
  • Friendly first run (UX P0.3): running bare lean-ctx in an interactive terminal now prints a short quickstart (one obvious next step: lean-ctx setup) instead of silently starting the stdio MCP server and appearing to hang. MCP clients (which pipe stdin, not a TTY) and explicit lean-ctx mcp are unaffected — they still get the server.
  • --help leads with the essentials (UX P1): a GETTING STARTED block (setup / doctor / gain) now sits at the top of the help, above the full reference — newcomers see the 3 commands they need first instead of scanning 150 lines.
  • Efficiency Epic — resident line-search index: ctx_search now narrows candidate files in memory via a RAM-resident trigram index (core/search_index.rs) before reading them, eliminating the per-call directory walk + full-corpus read. Benchmarked 17×–1000× faster (p50, warm) on a 2000-file corpus with byte-identical recall. Falls back to the walk path when the index is absent/building; opt-out via LEAN_CTX_DISABLE_SEARCH_INDEX=1.
  • ctx_compose task composer: one call returns extracted keywords, semantically ranked files, exact match locations, and the most relevant symbol's body inline — replacing the typical search→read→outline→read chain.
  • Benchmark harness (rust/benches/efficiency.rs + benchmarks/efficiency/): reproducible latency (p50/p95/p99) + token report comparing the walk and resident-index paths, with a recall-parity assertion.
  • Submodular context packing (core/context_packing.rs): generic greedy max-coverage selector with a provable 1 − 1/e approximation guarantee (Nemhauser–Wolsey–Fisher). ctx_compose now uses it to inline the non-redundant set of symbol bodies with maximal keyword coverage under a token budget, instead of just the first match. Budget via LEAN_CTX_COMPOSE_SYMBOL_TOKENS (default 600).
  • Search index Bloom tier (core/search_index.rs): monorepos whose trigram postings would exceed the memory budget now build compact per-file Bloom filters (~3× smaller, ~12 bits/trigram) instead of falling back to a full directory walk. Bloom filters have zero false negatives (a superset of true matches that ctx_search regex-verifies), so recall is identical to the exact tier. The MAX_FILES ceiling rose 20k→200k. Proven by a parity fuzz test (Bloom ⊇ postings for every query) + end-to-end recall test.
  • Hebbian co-access graph (core/cooccurrence.rs): a persistent, decaying "files that fire together, wire together" association graph. Files surfaced for the same task strengthen their mutual link (LTP); every update decays all weights (the forgetting curve) and prunes below threshold. Bounded by neighbour/file caps. Becomes an associative retrieval signal over time.
  • Spreading-activation retrieval (core/spreading_activation.rs): ACT-R-style associative ranker. Activation seeds at the files a task names and spreads over the project graph (fan-out-normalised, decaying → provably convergent even on cycles), surfacing structurally-close files lexical search misses. ctx_compose runs it over the union of the static import/call graph and the learned co-access graph as a budgeted, additive ## Related (associative…) section (LEAN_CTX_COMPOSE_GRAPH_BUDGET_MS, default 1500).
  • Retrieval eval harness (tests/retrieval_eval.rs): a labelled benchmark (queries + relevance judgments) measuring recall@k, MRR and R-precision. Gates the associative ranker as regression-free (recall ≥ lexical for every query) with a measured gain (mean recall@3 1.00 vs 0.00 lexical, R-precision 1.00 — it recovers in-cluster files without flooding unrelated ones).

Hardening

  • ctx_compose semantic ranking is wall-time budgeted (H1): the only O(corpus) stage (a cold BM25 build) runs in a cache-sharing worker thread bounded by LEAN_CTX_COMPOSE_BUDGET_MS (default 2500). On overrun the call returns immediately with exact-match + symbol sections and a "warming" note, while the worker finishes warming the resident cache for the next call — the agent loop can no longer stall on a cold index.
  • ctx_compose full-path test coverage (H2): new tests/ctx_compose_scenarios.rs exercises the semantic + exact-match + symbol pipeline on a real mini-corpus and asserts the tight-budget degradation path never stalls.
  • Instruction token cap is priority-aware (H3): the compression/output-style guidance suffix is now protected from truncation; only the variable session/knowledge/gotcha blocks are shed when the 1200-token cap is exceeded. Previously a large on-disk session could silently drop the agent's output-style contract.

Changed

  • lean-ctx config points to the simpler surface (UX P2): the full config dump now ends with a tip toward config show (the 5 high-level knobs) and config set <key> <value>, so the 100+ keys no longer feel like the only entry point. The simplified config template (config init) now defaults compression_level = "lite", matching the new friendly default.
  • Friendly-by-default output style (UX P0): the default compression_level is now lite (plain-English "concise" guidance — bullets, no filler) instead of standard (the symbolic dense style). New users, and anyone opening their generated rules files or inspecting the MCP instructions, now see readable directives rather than the → ∵ ∴ vocabulary or CRP MODE. The denser symbolic "power modes" stay one line away (compression_level = "standard" | "max", or LEAN_CTX_COMPRESSION). This only shapes the model's prose; tool-output compression is governed separately and is unchanged — engine efficiency is unaffected.
  • ctx_read auto-mode delivers task-relevant bodies: in map/signatures mode with an active task, the body of the best-matching symbol is inlined, avoiding a follow-up full read. The map heuristic threshold was raised 3000→6000 tokens, and the redundant double disk read in auto-mode selection was removed (cached token counts are reused).
  • Alpha/§MAP symbol substitution is now off by default for agent-facing output (it traded per-call bytes for agent decode work). CLI/batch pipelines can opt back in with LEAN_CTX_SYMBOL_MAP=1.
  • Resident graph-index cache (core/graph_cache.rs): try_load_graph_index reuses a deserialized ProjectIndex from RAM, instead of re-reading + decompressing + parsing on every graph query.
  • BM25 + graph caches use a (mtime, size) content fingerprint instead of mtime alone: coarse (1–2 s) filesystem mtime could miss a same-second background rebuild; pairing it with the file size catches those rewrites without the cost of hashing a multi-MB index on every per-query freshness check. A rebuild is still picked up immediately within the TTL window.

Fixed

  • CLI --help banner tool count no longer drifts (UX P0): the N MCP tools figure in the banner is now derived from the live registry (server::registry::tool_count()) instead of a hardcoded literal — it read 61 while the README and feature catalog already said 63. A unit test pins the banner to the registry count so the three figures can never diverge again.
  • Instruction token-cap truncation was O(lines) tokenizationstruncate_to_token_cap re-counted tokens once per line while walking back from the end. On large session/knowledge blocks this is wasteful, and it timed out the coverage job's ptrace-instrumented run. Replaced with a binary search over line boundaries (O(log lines) tokenizations, identical output).
  • CI: dropin_install_tests failed on shell-less runners (regression from #309): the new "is the shell installed?" guard skips writing zsh hooks when no zsh binary is present, but the drop-in install tests assert the hooks are written — so they failed on the zsh-less ubuntu-latest runner. Added LEAN_CTX_SHELL_HOOK_FORCE (1/true/all or a comma list like zsh,bash) to force hook installation regardless of detection — useful in minimal containers / custom images, and the seam the tests use to stay host-independent.
  • ctx_edit concurrent-edit timeout under multi-agent load (#320): the global cache write-lock was held across the entire disk I/O of an edit, so a second agent editing a different file could time out waiting on the first. Edits now serialize per file via a shared core::path_locks registry, perform disk I/O with no global lock, and take the global cache lock only briefly to apply the resulting cache effect. Concurrent edits to different files now run in parallel; edits to the same file remain correctly serialized.
  • Eval harness reported zero recall on Windows: recall_at_k/mean_reciprocal_rank compared retrieved paths (OS separator, \ on Windows) against expected fixtures (/) with ends_with, so every comparison missed and recall/MRR collapsed to 0 on Windows. Both sides are now normalized to / before comparison.
  • Flaky CI on Windows: made the ctx_tree token-savings test deterministic via a synthetic fixture (instead of walking the live repo, whose size + path tokenization varied by platform), and de-flaked spawned_background_task_doesnt_block_caller by polling for completion with a generous deadline instead of a fixed sleep.

Hardening

  • Per-file advisory lock registry (core/path_locks.rs): a process-wide per_file_lock(path) shared by ctx_read and ctx_edit serializes access to the same file without contending on a global lock, with bounded GC of unused entries. Lock-ordering documentation (LOCK_ORDERING.md) updated accordingly.

Refactoring

  • config/mod.rs split: extracted the enum surface (TeeMode, TerseAgent, OutputDensity, ResponseVerbosity, CompressionLevel, RulesScope) into config/enums.rs, trimming ~250 lines from the module.
  • Premium lean-ctx wrapped artifact: the shareable text summary is now TTY-aware with ANSI colouring, box drawing and a savings sparkline (plain text when piped / NO_COLOR).

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.6.25...v3.6.25

Don't miss a new lean-ctx release

NewReleases is sending notifications on new releases.