| v1.108.397 | ### Changed - a cut search names the files it left off, and file_pattern takes braces An agent asked for every caller of a module on a large repository. Its first broad `search_text` stopped at `max_results` (20 lines by default). On the home-assistant/core index those 20 lines came from the first 4 files in index order. The files it needed weren't on the page, and nothing said which files were, so it narrowed by guesswork. When it then wrote a brace pattern such as `components/{update,websocke | High | 10/24/2026 |
| v1.108.396 | ### Changed - the first search on a large repository resolves each import once The first `search_symbols` in a process builds the import graph to rank files by how often they are imported. On a large repository that meant resolving every import of every file, one at a time, and two parts of the resolver repeated work on each call: - The SQL-stem fallback (for bare names such as a dbt `ref`) found its cached table by first reading every indexed path to build the cache key, on every call tha | High | 10/23/2026 |
| v1.108.394 | ### Fixed - index_dependency validates package paths `index_dependency` now accepts only a package name: an npm name (`lodash`, `@scope/name`) or a PyPI name (`requests`), never a path. Each name read from an installed distribution's `top_level.txt` must be a module name, and every package directory, after symlinks, must be inside the repo, and must be one package: never a directory that is or contains the repo root, `node_modules`, a site-packages or a virtualenv. An npm package must have its | High | 10/23/2026 |
| v1.108.387 | ### Fixed - a licensed install is not shown a sales line `init` ended every real run with "Using jCodeMunch at work? A commercial license is $79", and `install-pack`'s catalog listing ended with "Get a license", whether or not the install already had a license key. A paying customer was being sold the thing they had bought, and jMunch promises paid clients they are never marketed to (jjg, 2026-10-20). Both lines now print only when no key is configured (for `install-pack --list`, a key passed w | High | 10/21/2026 |
| v1.108.379 | ### Fixed - a spawned agent no longer waits minutes for its jCodeMunch briefing (#1139) The `SubagentStart` hook adds a repo briefing to every agent Claude Code spawns, and Claude Code waits for it before the agent starts. It picked repos by path overlap in either direction, so a project inside an indexed parent briefed the parent's index too, and a cwd that matched nothing (or no cwd at all) briefed every index on the machine. Then it hydrated and PageRanked each one, with no size cap and no t | High | 10/19/2026 |
| v1.108.376 | ### Added - `init` and `install` end with one licence line A real run of `jcodemunch-mcp init` or `jcodemunch-mcp install <agent>` now ends with two lines after "Done.": jCodeMunch at work needs a commercial licence, $79 one time (the Builder price README.md lists), with the licence page and the 30-day money-back guarantee's terms page (https://jcodemunch.com/guarantee.php, which states the 30 days). It is shown at the end of a real `init` or `install` run, not on upgrades: `upgrade` re-runs `i | High | 10/17/2026 |
| v1.108.374 | ### Fixed - a Python virtualenv is skipped whatever its folder is called `index_folder` skipped a virtualenv only when its folder was named `venv` or `.venv`. A venv called `env`, `jcm-venv` or `py313` was walked file by file, and where nothing else excluded it (a stdlib venv before Python 3.13 or an older virtualenv writes no `.gitignore`, and uv also writes a `CACHEDIR.TAG`) its site-packages entered the index, competed with your own code in ranking and used up `max_folder_files`. On a worksp | High | 10/17/2026 |
| v1.108.370 | ### Fixed - seven import forms record the names they import A name the import extractor does not record is a name `find_references` answers 0 for and `check_references` counts no import of. Seven common forms recorded the edge with no names, or no edge at all (L-177): - a PHP group use, `use App\Models\{User, Post};`, recorded no edge. Each member is now one edge, as `use App\Models\User;` is; - a Kotlin `import a.b.D as E` recorded no edge; - a Scala selector, `import a.b.{C, D}`, recorded | High | 10/16/2026 |
| v1.108.364 | ### Fixed - a T-SQL/Sybase stored procedure or trigger indexed to nothing, and SQL objects all read as `type` (#1080, @outoftheblue9) On a real T-SQL and Sybase codebase a large share of files indexed to NOTHING, and what was lost was the logic -- the stored procedures and triggers -- so symbol search, `find_references` and `get_blast_radius` were blind to exactly the part that matters. The derekstride grammar collapses `CREATE PROCEDURE`/`CREATE TRIGGER` into ONE `ERROR` node with loose-punctu | High | 10/15/2026 |
| v1.108.360 | ### Fixed - a Web Forms attribute is read in every form ASP.NET accepts, and a schema outside a .NET repository is no longer given .NET advice ASP.NET's directive parser takes a double-quoted, single-quoted or unquoted value, and the Web Forms reader took only the first. An unquoted `runat=server` failed the server-control gate, so that control's `OnClick=` handler gave its codebehind method no reference, and a `CodeFile='Q.aspx.cs'` directive gave the page no edge to its codebehind. The direct | High | 10/14/2026 |
| v1.108.355 | ### Fixed - a Ruby method called by its bare name recorded no call (LEDGER L-172) Ruby writes a call of a method with no receiver and no arguments as a bare name: `settings`. The grammar gives that the `identifier` node of a local variable, and the parser read only `call` nodes, so the commonest way one Ruby method calls another recorded nothing unless the name happened to be a receiver (`settings.environment`). A helper called only by its bare name read `no_callers` in `get_dead_code_v2`: live | High | 10/13/2026 |
| v1.108.348 | ### Fixed - a Go, Java, C#, Rust or Ruby function called only from another file was reported as having no caller (LEDGER L-165) `get_dead_code_v2` looked for a caller of a function in two places: the function's own file, and each file the import graph says imports that file. That is the right rule for Python and JavaScript, where a file must import a name to call it. It is the wrong rule where a file calls another with no import between them: two files of one Go package, two classes of one Java | High | 10/12/2026 |
| v1.108.340 | ### Fixed - a Web Forms handler wired in markup is referenced, and markup reaches the file graph Web Forms binds codebehind methods in ways the AST call graph cannot see, so every such method read as uncalled. `On*=` on a `runat="server"` control (matched case-insensitively -- real markup mixes `OnClick` and `onclick`, and ASP.NET honours both, including after an inline `<%# ... %>` attribute value) now emits an import edge naming the handler; `OnClient*` is excluded because it is JavaScript, a | High | 10/10/2026 |
| v1.108.339 | ### Fixed - **Indexing a Python file that holds a dynamic import no longer walks the file once per table (LEDGER L-147).** The dynamic-import scan added in 1.108.320 (#876) has to know two things about names in the file: whether a module-level literal table is only ever read, and whether a loop variable is bound only by its loops. It answered each by walking the file's whole syntax tree, once or twice per name. It then walked the tree again for each of its passes, and walked a functio | High | 10/10/2026 |
| v1.108.336 | ### Fixed - **A fusion search no longer scores a query against another model's vectors (LEDGER L-135).** `search_symbols` with `fusion=true` embeds the query with the active model and scores it against the stored vectors as its similarity channel. The semantic exit has asked what built those vectors since 1.108.334; this exit asked nothing. Measured at the tool with a mocked provider (`evidence/l135_before_after.txt`), over a store built by another model: the provider was called for t | High | 10/9/2026 |
| v1.108.333 | ### Fixed - **`init`'s index line reports what the indexer did (reported by Dave).** After indexing, `jcodemunch-mcp init` printed `indexed <folder> (? files, ? symbols)`. The line read `files_indexed` and `symbols_indexed` from the indexer's result. No run returns the second, and only a run cut short by the file cap returns the first. A full index answers `file_count` and `symbol_count`, a run that re-indexes some files answers `changed`, `new`, `deleted` and `symbol_count`. So the lin | High | 10/7/2026 |
| v1.108.331 | ### Fixed - **A large Vue or Svelte `<script>` is indexed in time proportional to its size (LEDGER L-115).** Both script walks look for the comment above each declaration, and both did it by scanning the parent's children from the first one, once per declaration: a script of N top-level functions cost N times N child visits, all in Python after the parse. The two scans are one shared table now, built in one pass per parent node and read per declaration. Measured on a 368,717-byte `.vu | High | 10/6/2026 |
| v1.108.329 | ### Fixed - **`JCODEMUNCH_PARSE_BUDGET_SECONDS` stops a slow parse (LEDGER L-114).** The budget was a thread wait around `parse_file`, and tree-sitter's parse holds the GIL for its whole duration, so the wait could not return before the parse did. An over-budget file came back with its symbols and no warning after the full parse time, and the first index of a folder never consulted the budget at all. The limit is now inside the parser: `parse_file` opens one deadline per file, the one l | High | 10/5/2026 |
| v1.108.328 | ### Fixed - **A repeat `index <subdir>` inside a git root is incremental (#961, @ebataeva).** A subdirectory of a git working tree is indexed under the git root's identity and walked as `walk_prefix`; the collision guard sets `_merge_with_existing` so files outside the prefix carry over, and the incremental branch ran only when `_merge_with_existing` was `None`. So no repeat subdir walk could reach the no-change path: every run re-parsed the whole subdirectory and saved it through the m | High | 10/4/2026 |
| v1.108.327 | ### Security - **A local model path is refused when the installed `sentence-transformers` would run its code.** 1.108.326 raised the `semantic` extra's floor to 5.6.0 (GHSA-jhr6-gm9c-rqjv), and a floor is install metadata: `pip install -U jcodemunch-mcp` without the extra named, or a `sentence-transformers` installed directly, keeps the older release, and nothing said so. The embedding call now checks the release it imported. When `embed_model` (or `JCODEMUNCH_EMBED_MODEL`) is a path th | High | 10/2/2026 |
| v1.108.324 | ### Fixed - **A test directory at the repository root was not a test directory (LEDGER L-101).** `find_dead_code` and `get_dead_code_v2` asked whether `"/tests/"` appears in a path, which needs a slash BEFORE the directory, so `tests/helpers.py`, `test/helpers.py` and `__tests__/shapes.js` at the root were reported dead at confidence 1.0 while `pkg/tests/helpers.py` was skipped. The deletion investigator asks `find_dead_code` whether an importer is dead (L-94), so it called a name such | High | 10/2/2026 |
| v1.108.321 | A Java, C# or JavaScript call can spell a name with a Unicode escape, and the compiler reads it as the plain name. The reference search compared raw text, so it never saw such a call, and the delete preflight graded the called function `safe_to_delete` at confidence 1.0. This release decodes escapes in the one comparison every reference match goes through. It is also the first release cut under the release cadence: an unreleased change now fails the fast tier once it has waited past the Floor (S | High | 10/1/2026 |
| v1.108.319 | ### Fixed - the published benchmark tables are derived from the reference, not from three different runs (W-16) `/release` step 4 recomputes every published figure and refuses on a disagreement. It refused three consecutive releases on the same thing, and the first two shipped over it โ which is how a refusal becomes ceremony. The disagreement was real and larger than it had been recorded. Three artifacts carried a per-repo jCodeMunch column for one run: | source | express | fastapi | gin | g | High | 9/16/2026 |
| v1.108.318 | Three layers ship in this block, every one off by default where it can act: the workflows layer (seven Claude Code commands and the hooks that refuse a commit without the fast tier, a PR without a full-tier run on the tree it describes, and every irreversible verb), the inbound layer (nine headless jobs that draft and never post, the model never holding a token that can write) and the competitive tier (the null alternatives, jCodeMunch and nine competitors over pinned corpora in a sandbox, every | High | 9/11/2026 |
| v1.108.317 | ### Changed - CI runs the harness on every change; publishing is a dispatched workflow The eight workflows are five: `pr-gate.yml` (five staged jobs, every one a required check on `main` by name), `main.yml` (full witness + online bench after a merge, a `regression` issue per failing Floor, a weekly results PR), `nightly.yml` (the matrix with fresh corpora, `drift` issues), `security.yml` (CodeQL) and `release.yml` (dispatch with a version: pre-flight, build once, Test PyPI, clean-venv s | High | 9/4/2026 |
| v1.108.291 | Two metrics summed `byte_length` over every symbol in a file, so a class span and its methods spans were both counted. **The inflation is not uniform**, which is why it corrupted the metric rather than scaling it: it tracks how class-heavy a file is. Measured on this repo at **33.4% overall and up to 2.28x on a single file**, with `get_architecture_metrics` byte mass reaching **2.85x the real size of the files it describes**. A Gini coefficient compares *across* files, so an error that varies p | High | 8/22/2026 |
| v1.108.264 | Read side of the cp1252 hazard, and the third member of one family: | Release | Direction | |---------|-----------| | v1.108.230 | subprocess **input** | | v1.108.262 | our own **output** | | v1.108.264 | **file IO**, this one | `open()`, `Path.read_text()` and `Path.write_text()` use the platform default when no encoding is given, which is cp1252 on Windows. Reading a UTF-8 file then raises on the five bytes cp1252 leaves undefined (`81 8D 8F 90 9D`) and silently mangles everything else it ca | High | 8/8/2026 |
| v1.108.175 | **An ignored argument cannot prove absence.** Found live while auditing [#375](https://github.com/jgravelle/jcodemunch-mcp/issues/375), against this repo. A `search_text` call passed `regex=true`. The parameter is `is_regex`. Every tool reads its arguments key-by-key (`arguments.get("is_regex", False)`), so the flag was dropped in silence, the regex source text was searched as a LITERAL substring, nothing matched, and the response reached `state: "absent"` carrying "treat this as strong eviden | High | 7/26/2026 |
| v1.108.129 | Opt-in `compress=True` on `get_ranked_context` fits more relevant symbols into the same token budget: a model-free structural pass prunes low-signal lines from oversized symbol bodies while always preserving keystone lines (control-flow, returns/raises, signatures, and decision/constraint cues). Dropped runs collapse into an honest `โฆ N low-signal line(s) elided โฆ` marker, so a pruned view is never mistaken for the full body. The signal is normalized Shannon entropy of each line's tokens โ headl | High | 7/14/2026 |
| v1.108.91 | ## Endpoint-scoped infrastructure links `get_endpoint_impact(include_infra=True)` now crosses the code/infra boundary at endpoint granularity. Per impact, it attaches an `infra` block: the project-intel cross-references (env vars, compose services, Dockerfile ENTRYPOINT/COPY, CI jobs, package/Make scripts) intersected against that endpoint's blast-radius file set. "Change `GET /users`" now also surfaces the `.env` variable its handler chain reads and the compose service or Dockerfile that buil | High | 7/1/2026 |
| v1.108.65 | **Surface the composition tools in agent-facing docs.** `assemble_task_context` (the single-call, intent-classified, token-budgeted context orchestrator) was absent from every agent-facing surface while `plan_turn` was already prominent. This release makes the suite's orchestration layer legible: - The injected CLAUDE.md / Cursor / Windsurf policy gains an "Opening move" step describing `assemble_task_context`: a natural-language task in, an intent-classified (explore / debug / refactor / exte | High | 6/21/2026 |
| v1.108.55 | ## v1.108.55 - turn-budget reset, honest budget packing, fast search_text rejection (#327, #328, #329) Patch release closing the jcodemunch side of @mmashwani's 2026-06-11/12 report batch (the four jdocmunch siblings shipped as jdocmunch-mcp v1.70.1/v1.70.2). **#327 - Turn budget now resets in every reader.** The idle-gap reset only fired lazily inside `record_output` (post-dispatch), so readers that run during tool execution - `plan_turn`'s budget advisor via `percent_used()`, `should_compact | High | 6/12/2026 |
| v1.108.29 | ## 1.108.29 - WRR signal fusion was inert Closes #324 (reported by @sektor10, with a full root-cause analysis and a clean reproduction). ### The bug The Weighted Reciprocal Rank fusion pipeline in `retrieval/signal_fusion.py` never applied its channel weights. Every fused score came out `0.0`, and the final ordering silently fell back to a stable sort over insertion order. The documented ranking (identity 2.0 > lexical 1.0 > similarity 0.8 > structural 0.4) was a no-op on the `fusion=True` pa | High | 6/5/2026 |
| v1.108.26 | # 1.108.26 โ get_file_outline batch mode dropped all symbols ## Fixed `get_file_outline` in **batch mode** (`file_paths=[...]`) returned empty outlines for every file โ models saw "the outline came back empty" and either gave up or burned tokens re-querying (issue #319, reported by @MariusAdrian88, corroborated by @ImJustWeed). The bug was confined to the MUNCH `fo1` encoder: it only understood the **singular** response shape, where `symbols` sits at the top level. Batch mode nests the data o | High | 5/29/2026 |
| v1.108.22 | Six additive enterprise-hardening items in one release. All purely additive; no user-facing behavior changes. Full notes in [CHANGELOG.md](https://github.com/jgravelle/jcodemunch-mcp/blob/v1.108.22/CHANGELOG.md). ## Highlights - **Keyring credentials** (P1.3): Any credential env var can be set to `keyring:<name>` to load from the system keyring. New `jcodemunch-mcp keyring set|get|delete|list` CLI. Requires `pip install "jcodemunch-mcp[keyring]"`. - **Metadata-only cache mode** (P1.4): New `ca | High | 5/22/2026 |
| v1.108.18 | Patch release. Closes #304 โ the runtime gap I flagged when shipping v1.108.17's display fix. ## The gap `batch_summarize.py` read every summarizer-related config key from `_GLOBAL_CONFIG` only (no `repo=` passed). So a user with `summarizer_model` in `.jcodemunch.jsonc` saw the runtime ignore it โ the AI summarizer used the env-var fallback or hardcoded default instead of their configured value. Same plumbing-audit shape as #300 / #301 but in summarizer code. ## The fix Thread `repo` from c | High | 5/17/2026 |
| v1.108.7 | ## v1.108.7 โ Windows hook path: forward slashes + path-shape-agnostic dedup Fixes the recurring `PreToolUse:Read hook error / command not found` loop on Windows. Two coupled bugs: ### Bug 1: bash silently eats backslashes in hook paths `_hook_invocation()` returned `shutil.which("jcodemunch-mcp")` raw, which on Windows yields `C:\Python314\Scripts\jcodemunch-mcp.EXE`. JSON serialisation preserves the backslashes in settings.json (`C:\\Python314\\Scripts\\jcodemunch-mcp.EXE`), but Claude Code | High | 5/12/2026 |
| v1.81.3 | **Fixes #276** โ Bare-name `repo` lookups crashing when `JCODEMUNCH_PERF_TELEMETRY=1`. `list_repos()` globbed `*.db` indiscriminately, so `~/.code-index/telemetry.db` was treated as an indexed repo. Worse, `_connect()` auto-initialised the code-index schema on it, vandalising telemetry.db, and `_list_repo_from_db` returned a phantom entry with `repo=""`. That empty owner/name then crashed `_get_bare_name_map` (`"".split("/", 1)` โ `ValueError: not enough values to unpack`), aborting the bare-na | High | 5/7/2026 |
| v1.80.3 | Fixes #269 via PR #270 (DrHayt). The WorktreeRemove hook never actually removed worktrees from disk because two bugs in cli/hook_event.py conspired: (1) a legacy worktree_path early-return wrote the manifest and skipped git commands on remove, and (2) git worktree remove ran with cwd set to the worktree being removed, which git refuses. Fix: gate the legacy early-return on event_type=='create' and resolve the main repo via git rev-parse --git-common-dir before running removal commands. 3700 pass | High | 5/1/2026 |
| v1.80.1 | ## Fixed - **Scala 3 symbol extraction** (#262, @irreversible-paths). The Scala language spec only matched `function_definition` nodes, silently dropping abstract defs (`function_declaration`), fields (`val_definition` / `var_definition`), and type aliases (`type_definition`). It also assumed the identifier field was named `name`, but tree-sitter-scala uses `pattern` for val/var nodes. `SCALA_SPEC` now declares the additional node types and the `pattern` name field. On a real Scala 3 + Spring Bo | High | 4/26/2026 |
| v1.72.0 | Correctness + reach release: fixes six tier-1 MUNCH encoders that had shipped against imagined response shapes (silent data loss in `get_blast_radius`, `find_importers`, `find_references`, `get_signal_chains`, `get_tectonic_map`, `get_dependency_cycles`), and adds generic monorepo/`extends`-chain support to the tsconfig alias loader so path aliases resolve in any workspace layout. ### Fixed - **MUNCH tier-1 encoder alignment** (#256, credit @MariusAdrian88). Six encoders realigned to the act | High | 4/22/2026 |
| v1.71.0 | Resolves #255 (credit @rsubr). ## Added - **jcodemunch_guide tool.** Returns the version-current policy snippet โ the same text jcodemunch-mcp claude-md --generate emits โ plus the running version. Keep a single line in CLAUDE.md / AGENT.md and never hand-edit it when the tool surface changes: Call the jcodemunch_guide tool and strictly follow its instructions. Force-included alongside set_tool_tier / announce_model, so disabled_tools and tier filtering can't hide it. No repo context; | High | 4/21/2026 |
| v1.70.0 | ## Highlights **Default detail_level flipped "standard" โ "auto".** `search_symbols` now returns the cheapest representation by default for broad discovery queries โ compact shape when `max_results>=5` with no `token_budget` and no `debug`, standard otherwise. Explicit `detail_level` values are always honored. **Full-mode respects token_budget.** Previously the packer saw each result's signature-only byte_length, then full-mode appended `source`/`docstring`/`end_line` AFTER packing โ overshoot | High | 4/19/2026 |
| v1.63.1 | Hotfix for get_hotspots (and get_repo_health, which aggregates it) crashing with UnboundLocalError on any repo whose source_root isn't a git worktree. This is the common case for index_repo extracts โ they live in the cache dir with no .git. Root cause: candidate-building block was mis-indented inside 'if rc_check == 0:'. The existing test suite masked it because tmp_path nested inside the maintainer's git worktree and rev-parse accidentally walked up and succeeded. Regression test now monkeypa | High | 4/19/2026 |
| v1.63.0 | Closes #252. Fixes under-resolution on Python layouts where the effective source root is injected at runtime (conftest.py sys.path shims, PYTHONPATH, setuptools package_dir with nested roots). resolve_specifier now falls back to a cached package_basename โ parent_dirs index and retries against the parents of any package whose name matches the specifier's first dotted segment. Scoped by concrete first-segment evidence in the import itself, not a broad suffix sweep โ zero false-positive risk, mem | High | 4/19/2026 |
| v1.62.0 | Audit remediation for findings F1, F2, F3, F5, F6, F11. - **F1** MUNCH scalar values with embedded newlines now escape to \n/\r (and \) inside quoted fields; decoder reverses the escapes so round-tripped payloads no longer truncate at blank-line section boundaries. - **F11** Generic encoder schema embed now percent-escapes %25/%3A/%7C/%2C in tag/key/column/type tokens โ table keys with ':' and column names with '|' round-trip cleanly. - **F5** Generic decoder no longer drops nested tables when | High | 4/19/2026 |
| v1.61.1 | Low-risk audit remediation. No wire-format or session-state changes. ### Fixed - **tier_resolver substring match normalizes both sides (F4, closes #249)** โ provider-prefixed keys like anthropic/claude-haiku now match claude-haiku-4-5. - **Bearer-token redaction requires Authorization anchor (F9)** โ prose containing the word Bearer no longer trips redaction. - **Redaction depth cap collapses all scalars (F10)** โ short credential prefixes (AWS, GitHub tokens) under 16 chars no longer leak past | High | 4/19/2026 |
| v1.61.0 | ## Added - **Per-session tier state makes adaptive_tiering: true safe under HTTP (#253).** The process-global _session_tier_override is now a session-keyed OrderedDict of overrides (LRU-capped at 256 entries). The key is the MCP session's session_id when present, otherwise id(request_context.session); stdio and tests fall through to a \"__default__\" sentinel so their behavior is byte-for-byte unchanged. One HTTP client's plan_turn(model=...) or set_tool_tier(...) call no longer leaks into every | High | 4/19/2026 |
| v1.60.1 | ## Changed - **adaptive_tiering: true + HTTP transport now refuses to start (#248).** Previously emitted a startup WARNING. Process-global tier state leaks across concurrent HTTP clients โ one client's plan_turn(model=...) flip silently changes the tool surface for every other client on the same server. That is a misconfiguration, not a heads-up condition. The server now logs an ERROR and aborts via HttpAdaptiveTieringError (a SystemExit subclass) on both sse and streamable-http transports. Std | High | 4/19/2026 |
| v1.60.0 | Thanks to @MariusAdrian88 for PR #246 โ the tier surface, the three bundled fixes, and +215 tests of coverage. ## Added - **Tiered tool surface with runtime model-driven switching (#246).** jcodemunch's 60+ tools now narrow per model at runtime. Three tiers (core / standard / full); tier bundle contents moved from hardcoded constants into user-editable config.jsonc with baked-in defaults as fallback. New model_tier_map maps model identifiers to tiers via normalize โ exact โ glob โ substring โ | High | 4/18/2026 |
| v1.59.1 | Patch release fixing six issues surfaced by the 2026-04-18 adversarial audit. Zero behavior change for normal usage; all fixes either tighten safety or remove false-positives. ## Fixed - **F1 โ Redaction no longer mangles source code.** The bearer_token pattern was over-broad: case-insensitive token + any 20+ char identifier. Now header-anchored (Authorization: context or capital Bearer). generic_api_key now requires upper+lower+digit character classes plus entropy >= 3.5 bits/char. - **F2 โ De | High | 4/18/2026 |
| v1.59.0 | ## render_diagram โ mmd-viewer integration (#245, @MariusAdrian88) Opt-in visual preview for `render_diagram`. When enabled, calling `render_diagram(..., open_in_viewer=True)` writes the rendered Mermaid to a `jcm-`-prefixed `.mmd` file and spawns the companion [mmd-viewer](https://github.com/MariusAdrian88/mmd-viewer) binary โ no copy/paste into mermaid.live required. ### Config (default: off) ```jsonc "render_diagram_viewer_enabled": true, "mermaid_viewer_path": "C:/tools/mmd-viewer.exe" // | High | 4/18/2026 |
| v1.58.0 | ## MUNCH phase 5 โ TypeScript decoder + agent hints Final phase of the MUNCH rollout. Non-Python clients and agents can now consume compact payloads directly. ### Added - **clients/ts/decoder.ts** โ zero-dependency TypeScript reference decoder (~200 lines). Handles both tier-1 encoder payloads (fr1, dg1, ch1, etc.) and generic-fallback (gen1) payloads through a single entry point. Falls through to JSON.parse for non-MUNCH input, so callers can hand it any tool-response string without branching | High | 4/17/2026 |
| v1.57.0 | ## MUNCH phase 4 โ spec + benchmarks ### Added - **SPEC_MUNCH.md** โ full on-wire format spec so third-party clients and alternate MCP servers can decode MUNCH payloads without depending on the Python reference decoder. - **Encoding benchmark harness** โ `python -m munch_bench.encoding_bench` runs representative fixtures through the dispatcher and reports JSON bytes, compact bytes, savings %, and token-saved estimate. - **README compact-output section** + **TOKEN_SAVINGS.md** dual-axis framing | High | 4/17/2026 |
| v1.56.0 | ## MUNCH phase 3 โ hardened generic fallback The shape-sniffer that covers every tool without a hand-tuned encoder now produces fully round-trippable output. ### Changed - **Original table keys preserved** (was emitting synthesized `table_<tag>`). - **Per-column types preserved** (int / float / bool / str) via embedded schema. - **Top-level scalar types preserved** via compact `__stypes` companion map. - **Nested dict-of-list-of-dicts flattened** with dotted key so downstream tools can still r | High | 4/17/2026 |
| v1.55.0 | ## MUNCH compact encoding โ phase 2 15 hand-tuned per-tool compact encoders now ship, replacing the generic fallback for the highest-payoff graph/list/search tools. Dispatcher auto-selects the custom encoder when available and falls back to the generic shape-sniffer otherwise. ### Encoders shipped | Tool | Encoding ID | |---|---| | `get_dependency_graph` | `dg1` | | `get_call_hierarchy` | `ch1` | | `find_references` | `fr1` | | `find_importers` | `fi1` | | `get_blast_radius` | `br1` | | `get_i | High | 4/17/2026 |
| v1.54.0 | ## MUNCH compact response encoding โ phase 1 Opt-in **second-axis token savings** independent from jCodeMunch's retrieval-side optimization. Tool responses can now be emitted in a purpose-built compact format (path/symbol interning, tabular row packing, quoted-CSV data sections) instead of verbose JSON. ### New `format` argument on every tool - `"auto"` (default) โ encode compact; fall back to JSON if savings below 15% - `"compact"` โ force MUNCH regardless of savings - `"json"` โ never encode | High | 4/17/2026 |
| v1.53.0 | ## Added **Constraint-chain retrieval** โ new `winnow_symbols` tool runs a multi-axis query against the index in a single round trip. Accepts an ordered list of `{axis, op, value}` criteria (AND semantics) that intersect signals no existing tool composes: - `kind`, `language` - `name` (regex), `file` (glob) - `complexity`, `decorator` - `calls` (direct call references) - `summary`/`docstring` text - git `churn` (with configurable `window_days`) Survivors are ranked by PageRank-based `importan | High | 4/17/2026 |
| v1.52.1 | ### Changed - **`plan_refactoring` full language coverage** โ import and definition patterns, import rewrite logic, and import formatting extended to ~40 previously-uncovered languages (erlang, solidity, zig, clojure, powershell, ocaml, fsharp, nim, tcl, dlang, pascal, ada, cobol, matlab, apex, css/scss/sass/less/styl, razor, blade, al, nix, ejs, verse, asm, vue, and others). Refactorings in these languages now emit correct edits instead of falling through to a generic default. New `TestLanguage | High | 4/16/2026 |
| v1.52.0 | ## What's New ### `search_ast` โ Cross-language AST pattern matching Write one query, match across all 70+ languages. No need to know language-specific tree-sitter node types. **10 preset anti-pattern detectors:** - `empty_catch` โ silently swallowed errors - `bare_except` โ catch-all without specific type - `deeply_nested` โ 5+ control-flow levels - `nested_loops` โ O(nยณ)+ triple-nested loops - `god_function` โ 100+ line functions - `eval_exec` โ dynamic code execution (injection risk) - `ha | High | 4/16/2026 |
| v1.51.0 | ## What's New ### Symbol Provenance (`get_symbol_provenance`) Git archaeology per symbol โ traces the complete authorship lineage through git history. Uses `git log -L` line-range tracking to find every commit that touched a symbol, classifies each into semantic categories (creation, bugfix, refactor, feature, perf, rename, revert), extracts motivating intent from commit bodies, and generates a human-readable narrative summarising who created it, why, and how it evolved. Use before refactoring | High | 4/16/2026 |
| v1.50.1 | Fix: index_folder no longer rejects shallow paths like /workspace or /app when running inside a container. Auto-detects Docker, Podman, VS Code devcontainers, GitHub Codespaces, and generic container orchestrators. Minimum path depth relaxed from 3 to 2 components in container environments; bare / is still rejected. trusted_folders remains available as a manual override for non-container setups. Fixes #243. | High | 4/16/2026 |
| v1.50.0 | ## Branch-Aware Delta-Layered Indexing jcodemunch-mcp now maintains per-branch delta layers instead of re-indexing from scratch when you switch git branches. ### How it works - **One base index** (typically `main`/`master`) stores the full index - **Per-branch deltas** record only what changed relative to the base โ O(delta) storage instead of O(full) per branch - **Auto-detection**: all 55+ tools detect the current branch via `git rev-parse --abbrev-ref HEAD` โ no new parameters - **Compose a | High | 4/15/2026 |
| v1.49.0 | ## New Tool: `get_project_intel` Auto-discovers and structurally parses non-code knowledge files, cross-references them to indexed code symbols. Zero config, zero manual input. ### What it discovers - **Infra**: Dockerfiles (stages, ports, entrypoints), docker-compose (services, build contexts), K8s manifests (deployments, services, images), Terraform resources (from index) - **CI/CD**: GitHub Actions, GitLab CI, CircleCI (jobs, triggers, run commands) - **Config**: .env templates (var names, | High | 4/15/2026 |
| v1.48.0 | ## render_diagram โ one tool renders every graph New `render_diagram` tool transforms any graph-producing tool's output into rich, annotated Mermaid markup. ### Auto-detects source, picks optimal diagram type: - **get_call_hierarchy** โ `flowchart TD` with confidence-colored edges (green=LSP, blue=AST, orange=inferred, red=heuristic) - **get_signal_chains** โ `sequenceDiagram` with kind-grouped participant boxes (HTTP/CLI/Task/Event) - **get_tectonic_map** โ `flowchart LR` subgraph clusters wi | High | 4/15/2026 |
| v1.47.0 | ## Signal Chain Discovery New `get_signal_chains` tool traces how external signals (HTTP requests, CLI commands, scheduled tasks, events) propagate through the codebase via the call graph. ### Two modes - **Discovery** โ omit `symbol` to map all entry-point-to-leaf pathways with orphan detection - **Lookup** โ pass a `symbol` to find which user-facing chains it participates in (e.g. "validate_email sits on POST /api/users and cli:import-users") ### Gateway detection Detects entry points from | High | 4/15/2026 |
| v1.46.0 | ## Tectonic Analysis โ `get_tectonic_map` New tool that discovers the logical module topology of a codebase by fusing three independent coupling signals: - **Structural** โ import edges between files - **Behavioral** โ shared symbol references (files that import the same symbols are coupled) - **Temporal** โ git co-churn (files that change together in the same commits) The weighted file graph is partitioned via label propagation to reveal the *actual* module boundaries. Every discovered **pla | High | 4/15/2026 |
| v1.45.1 | ### Documentation - Added "Works with" section to README with Hermes Agent integration config - Submitted optional skill PR to [NousResearch/hermes-agent#10413](https://github.com/NousResearch/hermes-agent/pull/10413) | High | 4/15/2026 |
| v1.45.0 | ### Added - **Enhanced BM25 tokenizer** โ Porter-style suffix stemming ("searching" โ "search", "running" โ "run") and bidirectional abbreviation expansion (40 entries: "db" โ "database", "config" โ "configuration", etc.). Significantly improves recall for natural-language queries against code symbols. - **Diversity-aware budget packing** โ `get_ranked_context` now spreads results across files (per-file cap of 3, decay penalty for same-file repeats) instead of greedy same-file stacking. Produces | High | 4/15/2026 |
| v1.44.3 | ### Added - **Native performance backend** โ Windows x64 users automatically get a compiled native backend for tokenizer, budget packing, hotspot scoring, fusion, and PageRank. Installs seamlessly via `pip install jcodemunch-mcp`. Other platforms fall back gracefully to pure Python. Linux and macOS wheels coming soon. **Full Changelog**: https://github.com/jgravelle/jcodemunch-mcp/compare/v1.44.2...v1.44.3 | High | 4/15/2026 |
| v1.44.2 | ### Fixed - **Content hash consistency** โ drift detection now always uses SHA-256, preventing false-positive staleness on existing indexes. - **Budget packing efficiency** โ lazy source loading cuts memory usage for large repos (only loads ~2ร budget worth of candidates instead of all). - **Hotspot filtering** โ pre-filters symbols by kind/complexity before scoring, avoiding unnecessary work on large indexes. - **BM25 tokenizer quality** โ abbreviation expansions ("database", "configuration") a | High | 4/15/2026 |
| v1.44.1 | Fixed: claude-md, Cursor rules, and Windsurf rules generators now respect tool_profile and disabled_tools from config. Only tools the model can actually call are emitted in the generated policy. (#242 follow-up by @gebeer) | High | 4/15/2026 |
| v1.44.0 | ## Tool Profiles & Compact Schemas (#242) New config options to control context budget: - **`tool_profile`** โ `"core"` (16 tools, ~4k tokens), `"standard"` (~40 tools), or `"full"` (all, default) - **`compact_schemas`** โ strips rarely-used advanced parameters from tool schemas (~1-2k token savings) Combined, `"core"` + `compact_schemas: true` reduces the schema footprint from ~11.5k to ~4k tokens โ a 65% reduction. ### Quick start ```jsonc // ~/.code-index/config.jsonc { "tool_profile": | High | 4/14/2026 |
| v1.43.0 | ### Added - **6 new languages** from TIOBE 51-100: F# (`.fs`, `.fsi`, `.fsx`), Clojure (`.clj`, `.cljs`, `.cljc`, `.edn`), Emacs Lisp (`.el`), Nim (`.nim`, `.nims`, `.nimble`), Tcl (`.tcl`, `.tk`, `.itcl`), D (`.d`, `.di`) - Custom tree-sitter parsers for all 6 with full symbol extraction - 26 new tests (3023 total) Install: `pip install jcodemunch-mcp==1.43.0` | High | 4/13/2026 |
| v1.42.0 | ## 11 New Languages Added full symbol extraction for **11 new programming languages**, bringing the total to 55+ supported languages: | Language | Extensions | TIOBE Rank | |----------|-----------|------------| | Pascal / Delphi | `.pas`, `.dpr`, `.dpk`, `.lpr`, `.pp` | #9 (1.98%) | | MATLAB / Octave | `.mat`, `.mlx`, `.m`* | #14 (1.40%) | | Ada | `.adb`, `.ads` | #18 (1.19%) | | COBOL | `.cob`, `.cbl`, `.cpy` | #21 (0.95%) | | Common Lisp | `.lisp`, `.cl`, `.lsp`, `.asd` | #31 (0.34%) | | Sol | Medium | 4/13/2026 |
| v1.41.0 | ## munch-bench joins the mothership Phase 5 of the Groq Integration Suite โ consolidated from standalone repo into `jcodemunch-mcp/munch-bench/`, same pattern as speedreview. ### Install ```bash pip install jcodemunch-mcp[bench] ``` ### Run ```bash munch-bench run --provider groq munch-bench compare results/*.json -o leaderboard.html ``` ### First Results (31 questions โ Flask, FastAPI, Express) | # | Model | Judge Score | P@5 | Recall | Cost | |---|-------|-------------|-----|--------|---- | Medium | 4/13/2026 |
| v1.40.1 | ### Fixed - Fix `jcodemunch-mcp index <owner/repo>` CLI crash โ was passing `repo=` instead of `url=` to `index_repo()`, causing `TypeError` PyPI: https://pypi.org/project/jcodemunch-mcp/1.40.1/ | Medium | 4/13/2026 |
| v1.40.0 | ## Phase 4: Wow Factor Two new `gcm` modes powered by Groq's full audio stack: ### Voice-to-Codebase (`gcm --voice`) Speak a question about your codebase, hear the answer spoken back in real-time. ```bash pip install jcodemunch-mcp[groq-voice] gcm --voice --repo pallets/flask ``` Full pipeline: Whisper STT โ jCodeMunch retrieval โ Groq LLM โ Orpheus TTS playback. Push-to-talk via Enter key, with text fallback for environments without a microphone. ### Auto Repo Explainer (`gcm explain`) Gen | Medium | 4/13/2026 |
| v1.39.1 | ### Fixed - **gcm: GitHub repo detection on Linux** โ `_is_github_repo("pallets/flask")` was returning `False` on Linux where `/` is `os.path.sep`. Now uses structural heuristics that work cross-platform. **Full Changelog**: https://github.com/jgravelle/jcodemunch-mcp/compare/v1.39.0...v1.39.1 | Medium | 4/13/2026 |
| v1.39.0 | ## gcm โ Ask any question about any codebase New `gcm` command line tool powered by jCodeMunch retrieval + Groq inference. Get answers about any codebase in under 3 seconds. ```bash pip install jcodemunch-mcp[groq] export GROQ_API_KEY=gsk_... gcm "how does authentication work?" --repo pallets/flask gcm "where are the API routes?" gcm --chat --repo facebook/react ``` ### Features - **GitHub repos** โ `--repo owner/name` auto-indexes on first use - **Local directories** โ defaults to current | Medium | 4/13/2026 |
| v1.38.0 | ## speedreview โ AI Code Review in Under 5 Seconds New `speedreview/` subdirectory adds a GitHub Action that reviews PRs using jCodeMunch retrieval + Groq inference. ### Setup (3 steps) 1. Add `GROQ_API_KEY` to your repo secrets 2. Add this workflow: ```yaml name: speedreview on: [pull_request] permissions: pull-requests: write contents: read jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: jgrave | Medium | 4/13/2026 |
| v1.37.0 | ## Groq Remote MCP Integration Use jCodeMunch as a remote MCP tool with [Groq's](https://groq.com) ultra-fast inference API โ answer codebase questions in seconds via a single API call. ### Added - **GROQ.md** โ full tutorial with Python/curl/JS quickstarts, allowed-tools presets (explore, deep, review, full), model recommendations, and deployment guides - **Docker deployment** โ `Dockerfile` + `docker-compose.yml` + `Caddyfile` for one-command HTTPS deployment with auto-TLS - **Validation scr | Medium | 4/13/2026 |
| v1.36.0 | Three new languages, courtesy of @MariusAdrian88 (#239): - **Arduino** (.ino, .pde) โ parsed via tree-sitter-arduino grammar (C++ superset). Classes, structs, enums, functions, constants. Import extraction reuses #include path. - **VHDL** (.vhd, .vhdl, .vho, .vhs) โ regex parser. Entity, architecture, package, process, function, procedure, component, signal, constant, type/subtype. Library/use import extraction (work library excluded). - **Verilog/SystemVerilog** (.v, .vh, .sv, .svh) โ regex pa | Medium | 4/13/2026 |
| v1.35.1 | Four reliability fixes from MariusAdrian88 (#238): - invalidate_cache followed by index_folder (incremental) no longer returns "No changes detected" -- fixes Windows WAL file-locking race, legacy JSON resurrection, adds _force_full_reindex coordination flag - meta_fields config now applied to nested _meta in batch tool results (e.g. get_file_outline with file_paths=[...]) - WatcherManager self-restarts on crash with 100ms backoff, up to 5 consecutive attempts - Orphan index cleanup on startup - | Medium | 4/12/2026 |
| v1.35.0 | New tool: plan_refactoring -- generate edit-ready {old_text, new_text} refactoring plans in a single call. - 4 refactoring types: rename, move, extract, signature change - Import rewrites for 20+ languages - Collision detection, inter-symbol dependency warnings, path alias detection - Multi-line signature capture with paren balancing - Non-code file scanning (YAML, JSON, TOML, etc.) - 325 new tests, 2995 total passing Full changelog: https://github.com/jgravelle/jcodemunch-mcp/blob/main/CHANGE | Medium | 4/12/2026 |
| v1.34.0 | Long-running tools now emit MCP progress notifications so hosts like VS Code show a live inline indicator instead of a static spinner. Zero token cost -- notifications go to the host, never the model. ### Added - **MCP progress notifications** (#232): index_folder, index_repo, index_file, and embed_repo emit notifications/progress when the client provides a progressToken - **ProgressReporter** (progress.py): thread-safe, monotonic progress helper. No pulse threads, no fake drift -- progress ref | High | 4/11/2026 |
| v1.33.0 | When watch: true is set in config (or JCODEMUNCH_WATCH=1), the server automatically reindexes and starts watching any unwatched repo before a tool executes. Eliminates silent-stale-data that causes LLMs to abandon jcodemunch tools for the session. ### Added - **Auto-watch on demand** (#233): race-safe pre-dispatch hook via asyncio.Condition -- concurrent tool calls to the same unwatched repo trigger only one reindex - **WatcherManager class** (watcher.py): dynamic folder watching with add_folde | Medium | 4/11/2026 |
| v1.32.1 | ### Fixed - **embed_repo preflight performance** (#231): cache-discovery no longer loads and decodes every stored embedding blob just to get symbol IDs. New EmbeddingStore.get_all_ids() queries only the symbol_id column. Eliminates unnecessary CPU, memory, and latency on repos with existing embeddings. ### Upgrade pip install --upgrade jcodemunch-mcp | Medium | 4/11/2026 |
| v1.32.0 | ### Version correction Releases 2.0.0 and 2.1.0 were numbered incorrectly -- every change was purely additive with no breaking API changes. Those releases have been marked as deprecated pre-releases. This release (1.32.0) is the corrected successor. See the full renumbering table in CHANGELOG.md. ### Added - **jcodemunch-mcp index CLI command** (#230): Index a local folder or GitHub repo directly from the terminal. Defaults to the current directory when no target is given -- no init required. | Medium | 4/10/2026 |
| v2.1.0 | > **DEPRECATED**: This version number was a semver error. No breaking changes were introduced. Install v1.32.0 instead: `pip install jcodemunch-mcp>=1.32.0` --- ### Added - **jcodemunch-mcp index CLI command** (#230): Index a local folder or GitHub repo directly from the terminal. Defaults to the current directory when no target is given โ no init required. Supports --no-ai-summaries, --follow-symlinks, and --extra-ignore flags. Full changelog: https://github.com/jgravelle/jcodemunch-mcp/blob | Medium | 4/10/2026 |
| v2.0.0 | > **DEPRECATED**: This version number was a semver error. The 2.0.0 bump contained no breaking changes โ all features are additive and opt-in. Install v1.32.0 instead, which is the corrected successor: `pip install jcodemunch-mcp>=1.32.0` --- ## Phase 5: Interface & Trait Dispatch Resolution (Gap 2C) Resolves interface/trait method calls to their concrete implementations via LSP textDocument/implementation: - **Go** interfaces, **Rust** traits, **TypeScript/Java/C#/PHP** interfaces and abstr | Medium | 4/10/2026 |