Replace the go-gitignore library's NewRepository (which opens .gitignore
files via os.Open but never closes the handles) with a custom repoMatcher
that reads files via os.ReadFile and passes strings.NewReader to the
library's New() function. This ensures all file handles are closed
immediately after reading.
The library's ignore.Relative() pattern matching is preserved — only the
hierarchy walker and file loading are reimplemented. The matching algorithm
follows standard git precedence: child .gitignore overrides parent,
negation patterns in child override matching patterns in parent, and
.git/info/exclude is checked last.
Fixes Windows CI where leaked handles prevented t.TempDir() cleanup.
applyLimit() silently capped all results to maxRows (default 200), even
when the user specified a higher LIMIT clause. This caused queries like
MATCH (f:Function) RETURN f.name LIMIT 500 to return only 200 rows,
and COUNT() aggregations to silently undercount on large datasets.
Now explicit LIMIT values from Cypher are respected as-is. The 200-row
default still applies when no LIMIT clause is provided.
Incorporates the fix from PR #40 by @re-thc.
Co-authored-by: Harry Chan <38070640+re-thc@users.noreply.github.com>
Git worktrees (stored in .worktrees/) duplicate the entire source tree,
causing the knowledge graph to contain duplicate nodes and edges for
every function, class, and route. Add .worktrees to IGNORE_PATTERNS
alongside .git and .svn.
Incorporates the fix from PR #37 by @wassertim. Closes#31 (partial).
Co-authored-by: wassertim <wassertim@gmail.com>
- Vendor LumaKernel/tree-sitter-wolfram grammar (ABI 13, parser.c + scanner.c)
- Register Wolfram language: .wl/.wls extensions, set_delayed_top/set_top/
set_delayed/set as function types, apply as call type, get_top + Needs[]
as import types
- Add CBM_LANG_WOLFRAM enum, lang spec entry, and grammar bridge
- Extract defs: resolve function name from apply(user_symbol("f"), ...) LHS
of set/set_delayed definitions; recurse into function bodies for nested defs
- Extract calls: skip apply nodes that are definition LHS (not a call)
- Extract imports: handle << "file.wl" (get_top) and Needs["Package`"]
- Fix caller attribution: add func_kinds_wolfram to func_kinds_for_lang and
add Wolfram name extraction in compute_func_qn (extract_unified.c) so the
scope stack correctly tracks enclosing function for all call sites
- Add MATLAB function_call + command call extraction (63 -> 64 with Wolfram)
- Add Lean 4 apply call extraction with type-position filter
- Add regression tests for Wolfram, MATLAB, Lean calls + FORM pipeline test
- Add field('path', ...) to Magma load_statement grammar rule so
parse_generic_imports() finds the import path via field lookup
instead of the broken text fallback (which only extracted 1 per file)
- Fix passImports() to resolve file-path imports (e.g. "utils.mag",
"lib/helpers.h") via fqn.ModuleQN() when raw path doesn't match
any node QN — general fix benefiting any file-path-based import
- Add TestMagmaImport_Regression and TestMagmaCall_Regression
- Update language count 59 → 63 in README, docs/index.html, marketing
Custom tree-sitter grammars for FORM and Magma (no upstream exists).
MATLAB uses acristoffers/tree-sitter-matlab, Lean uses leanprover/tree-sitter-lean4.
Includes .m file disambiguation (Objective-C vs MATLAB) via Linguist heuristics.
- MATLAB: vendored from acristoffers/tree-sitter-matlab, definitions-only
(no call graph due to A(1) indexing ambiguity), .m file disambiguation
via GitHub Linguist heuristics in discover.go
- Lean 4: vendored from Julian/tree-sitter-lean, definitions-only
(Lean 4 syntax is runtime-extensible), ABI 13 backward-compatible
- FORM: custom tree-sitter grammar written from scratch for symbolic
manipulation language used in particle physics (CERN/Nikhef)
- Magma: custom tree-sitter grammar written from scratch for computer
algebra system (Univ. Sydney)
Integration touchpoints per language: cbm.h enum, cbm.go map, lang.go
constants, lang_specs.c (extern + arrays + table + switch), helpers.c
(func_kinds + module_parents + test detection), extract_defs.c
(resolve_func_name for MATLAB/Lean), extract_imports.c, lang/<name>.go
spec, discover.go (.m heuristic), regression_test.go (9 new tests).
tools.Version was a hardcoded const that needed manual bumping.
Now it defaults to "dev" and is set from main.version (injected
via -ldflags during release builds) through tools.SetVersion().
parseFileURI returned /C:/Users/... (with leading /) for Windows
file:///C:/... URIs, causing watcher.root_gone loop because os.Stat
fails on that path. Strip the leading / before drive letters and
normalize with filepath.FromSlash.
Fixes the remaining watcher bug from #20.
- Languages: 35 -> 59
- Add Gemini CLI, VS Code, Zed to supported clients list
- Update benchmark description to match v7 methodology
- Update meta tags and comparison table
- Fix Continue.dev invalid_type error: add properties:{} to list_projects schema (#15)
- Fix Windows paths: sanitize colons and backslashes in ProjectNameFromPath (#20)
- Fix update double-v prefix: strip v from version before display (#17)
- Fix update context canceled: DownloadAsset returns []byte, not ReadCloser (#17)
- Strip v prefix in release workflow ldflags (Unix + Windows builds)
- Add Gemini CLI, VS Code Copilot, and Zed to install/uninstall commands (#19)
- Add tests for new editor configs and Windows path cases
Tests that replace PATH with an empty temp dir break DLL resolution
on Windows (MSYS2 libgcc/libwinpthread). Append original PATH on
Windows so CGo-linked binaries can still find required DLLs.
The vendored ICU-subset headers use "unicode/umachine.h" includes.
Adding src/ to CFLAGS lets the compiler resolve these on Windows
where no system ICU is available.
- Replace Go-binding tree-sitter with vendored C grammars compiled via
CGo (internal/cbm/); eliminates all Go module/linker fragility
- Add 32 new languages: Clojure, CMake, COBOL, Common Lisp, CUDA, Elm,
Emacs Lisp, Fortran, F#, GLSL, GraphQL, INI, JSON, Julia, Makefile,
Markdown, Meson, Nix, Protobuf, Svelte, Verilog, Vim Script, Vue, XML
(plus C, C#, Erlang, SQL, YAML quality improvements)
- Adaptive worker concurrency and mmap prefetch for faster indexing
- Graph buffer: batched SQLite writes for 3-5x throughput improvement
- Fix cancellation test: use 50ms timeout (pipeline now indexes 212-file
Erlang repo in ~400ms, well under the old 2s deadline)
- Fix isTestFunction: add "Test" prefix for C#, "test" prefix for Scala
Replace naive modularityGain (scanned all nodes per call) with
per-community commSumTot accumulators maintained incrementally.
Each iteration is now O(m) instead of O(N^2).
Django benchmark: communities pass 4m40s → 0.94s (297x faster),
total indexing 5m38s → 24s.
Add t.Cleanup(router.CloseAll) to snippet and watcher test helpers.
Windows does not allow deleting files held by another process, so the
SQLite DB must be closed before t.TempDir() removal runs.
New tools:
- get_architecture: codebase architecture overview with 12 selectable aspects
(languages, packages, entry_points, routes, hotspots, boundaries, services,
layers, clusters, file_tree, adr)
- manage_adr: CRUD for Architecture Decision Records with 6 fixed sections,
section filtering, validation, and discovery of existing architecture docs
Architecture analysis fixes:
- Fix qnToPackage extracting segment[2] for meaningful sub-packages instead
of segment[1] which collapsed everything to top-level dirs
- Filter test functions from entry_points, hotspots, and routes using both
is_test property (Module/File nodes) and file_path pattern matching
- Filter boundaries to Function/Method/Class nodes only
- Add FindArchitectureDocs for discovering existing architecture documentation
Naming corrections:
- Rename Leiden to Louvain throughout (algorithm is simplified Louvain,
not actual Leiden which requires CPM-based refinement)
- leiden.go -> louvain.go with all symbols renamed
- Remove unused ClusterInfo.Modularity field (always zero)
Other changes:
- Case-insensitive search by default for search_graph and search_code
- Remove read_file and list_directory tools (handled by coding agents natively)
- Update tool descriptions and README for 8000 char ADR limit
- Release workflow: build binary as `codebase-memory-mcp` (not
`codebase-memory-mcp-<os>-<arch>`) inside tarballs. Users extract
and get the correct name without renaming.
- Codex CLI: replace broken `codex mcp add/remove` calls with direct
config.toml manipulation. Codex uses [mcp_servers.<name>] sections,
not CLI subcommands.
- README: add explicit extract-and-move step to Quick Start.
claude mcp remove without -s user prompts interactively for scope,
which hangs when run from install/uninstall commands. Both
registerClaudeCodeMCP (pre-cleanup remove) and deregisterMCP
(uninstall) now pass -s user explicitly.
- TestMain: append .exe to binary name on Windows
- Add testEnvWithHome/setTestHome helpers for cross-platform HOME override
(Windows uses USERPROFILE, not HOME)
- Add exeSuffix() helper for fake binary creation
- Skip Unix-specific tests on Windows: shell RC detection, PATH append,
fallback path lookup
- Normalize CRLF in skill frontmatter check (git may convert on Windows)
Skill files were only written inside installClaudeCode(), which required
finding the `claude` CLI binary. In CI (Linux) with no claude installed,
skills were never written, causing 4 test failures.
Split into installSkills() (always runs) and registerClaudeCodeMCP()
(only when claude CLI found).
- Feature line: list all 35 languages including Obj-C, Swift, Dart,
Perl, Groovy, Erlang, R, SCSS, SQL, Dockerfile
- Performance section: updated with Django (49K nodes) and Linux
kernel stress test numbers from the v0.3.0 benchmark
- Architecture section: 25 → 35 language specs
- Token efficiency: reference 35 real-world repos instead of single project