Prefix-to-decorator bridge now matches by file path segments: prefix
"/bq/bulk/ranked" only connects to handlers in paths containing
"bq/bulk/ranked", not all handlers in the service.
HCL infra binding extraction: scan resource blocks for attribute pairs
with source keys (topic, queue_name) and target keys (uri, push_endpoint).
Handles nested blocks (push_config { push_endpoint = "..." }).
Extract route_path and route_method directly from decorator AST nodes
during tree-sitter walk. Route + HANDLES edges created during
definition node creation. ensure_decorator_routes pass recreates
Route+HANDLES for existing nodes in incremental mode.
Prefix Routes bridged to handler Functions by service directory matching.
Route registration detection now works for unresolved local variables
(app.include_router, app.mount) by matching callee name suffix when
QN resolution fails. Scans ALL arguments for URL paths — handles
prefix=, path=, route= keyword args across frameworks.
New route_reg_suffixes: include_router, mount, add_url_rule,
register_blueprint, use, register, add_route, add_api_route.
Infrastructure bindings: YAML/JSON extraction captures topic→URL
pairs from subscription configs (push_endpoint, uri). Creates
INFRA_MAPS edges linking async topic Routes to endpoint URLs.
Improved match_infra_routes: matches prefix Routes from include_router,
supports service-only matching for generic "/" handlers, correct
Cloud Run hostname parsing for new project-number format.
sqlite_writer.c pb_build_interior: final root-level sep_cell
allocations were not freed. Each cbm_write_db call leaked 84 bytes.
Detected by ASan on Linux CI with 155 incremental test iterations.
Also fix CI timing: use MAX_TOOL_MS (15s) for perf assertions,
skip timing on full re-index operations (CI runners are slower).
- Serialize return_type, parent_class, base_classes on definition nodes
- DATA_FLOWS edges link callers through Route nodes to handlers
- YAML nested field extraction with dotted key paths (key_path property)
- Rename trace_call_path → trace_path with mode parameter:
calls (default), data_flow, cross_service
- Backward compatible: trace_call_path alias still accepted
- Updated CLI help text and all tests
CBMCallArg struct captures up to 8 arguments per call with expression
text, resolved constant values, keyword names, and positional index.
Member expressions produce dotted chain expressions automatically.
Serialized as "args" array on CALLS, HTTP_CALLS, ASYNC_CALLS, and
CONFIGURES edge properties. Enables data flow tracing across function
and service boundaries.
Function/Method nodes now include param_names and param_types arrays
in their properties JSON. Data was already extracted by tree-sitter
but not serialized.
- append_json_str_array helper replaces inline decorator serialization
- build_def_props in both pass_parallel.c and pass_definitions.c
- extract_param_names: add Python default_parameter, typed_default_parameter,
bare identifier node types
- Sample project: 114 Python functions now have param_names
- Zero extraction overhead, ~3MB more in properties for large projects
ts_node_child(root, i) and ts_node_next_sibling() both call
ts_node_child_with_descendant() internally, making sibling iteration
O(N²) total on roots with many children (e.g. generated TypeScript
.d.ts files or large Perl files with 5,000–50,000 top-level nodes).
Replace with TSTreeCursor: ts_tree_cursor_goto_next_sibling() maintains
traversal state across calls and is O(1) per step, reducing total
complexity from O(N²) to O(N).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- lang_specs.c: add LangSpec entries for CBM_LANG_KUSTOMIZE and CBM_LANG_K8S
(both reuse tree_sitter_yaml()); add cbm_ts_language() switch cases
- extract_k8s.c: new file implementing cbm_extract_k8s(); kustomize path
walks block_sequence items under resources/bases/patches/components/
patchesStrategicMerge and emits CBMImport per scalar; k8s path extracts
apiVersion/kind/metadata.name and emits CBMDefinition with label "Resource"
and name "Kind/metadata-name"; malformed manifests (missing kind or name)
produce zero definitions
- cbm.h: declare cbm_extract_k8s() alongside other sub-extractor entry points
- cbm.c: call cbm_extract_k8s() after unified extraction for the two new langs
- Makefile.cbm: add extract_k8s.c to EXTRACTION_SRCS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add CBM_LANG_KUSTOMIZE and CBM_LANG_K8S to CBMLanguage enum (before CBM_LANG_COUNT)
- Add kustomization.yaml/yml to FILENAME_TABLE mapped to CBM_LANG_KUSTOMIZE
- Add Kustomize and Kubernetes entries to LANG_NAMES
- Implement cbm_is_kustomize_file() with to_lower+strcmp pattern
- Implement cbm_is_k8s_manifest() scanning first 4KB for apiVersion: via ci_strstr()
- Declare both helpers in pipeline_internal.h Infrascan helpers section
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Swift tree-sitter grammar uses positional children (not named fields) for
call_expression, so extract_callee_name() returned NULL for every call.
- extract_calls.c: Swift-specific callee extraction via first named child
for call_expression and constructor_expression nodes
- lang_specs.c: add constructor_expression to swift_call_types
- 4 new C tests: simple calls, method calls, constructors, chained calls
Co-Authored-By: Jay Sync <63868998+jay-sync@users.noreply.github.com>
- Arena-allocate pair_field_types in cpp_stdlib_data.c (was stack array
escaping scope via registry pointer — caught by GCC ASan)
- Add sysfs fallback for L2 cache on Linux ARM (sysconf returns 0)
- Expose cbm_node_free_fields() and fix 12+ leak sites in tests where
find_node_by_id/qn results were never freed (caught by LeakSanitizer)
Enforce WarningsAsErrors: '*' with zero suppressions of entire check categories.
All non-FP warnings fixed at source; true false positives get per-instance NOLINT
with reasoning. Fixes include: braces around statements (1679), isolate declarations
(75), explicit casts for multilevel pointer conversions, missing includes, function
parameter documentation via NOLINT, and proper NOLINTBEGIN/NOLINTEND nesting.
Delete Go MCP server, CGo bridges, Go pipeline, store, tools, watcher,
cypher engine, language specs, and all Go tests. Replace Go pre-commit
hook with C-only linting (clang-tidy, cppcheck, clang-format, tests).
Tree-sitter extraction engine (internal/cbm/*.c) retained for C pipeline.
Complete C implementation of the indexing pipeline (src/), parallel worker
pool, graph buffer with merge support, SQLite writer, and 1893-test suite.
Linter setup: zero warnings from clang-tidy (all checks enabled, no NOLINT
suppressions), cppcheck, and clang-format. All issues fixed at source —
proper headers for external linkage, GROW_ARRAY macro restructured to
eliminate type parameter, null-deref paths guarded, named intermediates
for suspicious-argument checks.
Full indexing now runs entirely in RAM:
- One filepath.Walk, one bulk file read (LZ4 HC compressed sourceStore)
- In-memory SQLite for all passes, single Backup API dump at end
- Source access via C LZ4 decompression (~3μs per file, 5.7 GB/s)
Aho-Corasick engine (internal/cbm/ac.c):
- Custom ACISM automaton with bitmask output (≤64 patterns)
- Fused LZ4 decompress + AC scan in C-side thread-local buffer
- Batch API: single CGo call scans all files (ScanLZ4Batch)
- Compact alphabet mode for configlinker (38-char table)
Pipeline optimizations:
- httplinks: AC pre-screens files for HTTP client + route keywords
- configlinker: AC batch scan replaces O(n×m) substring matching
- Infrascan/envscan: iterate sourceStore keys instead of walking disk
- All source reads via getSource() (LZ4 decompress from RAM)
- File hashes pre-computed during bulk load (zero re-reads)
Type system improvements:
- Overload resolution by parameter type (score_overload_match with type compatibility)
- Lambda return type inference (trailing return type + shallow body walk)
- Inline namespace normalization (strip __1, __cxx11, __gnu_cxx)
- Implicit conversions in overload scoring (const char* → string, numeric promotions)
- Virtual dispatch: prefer derived override over base method
- CRTP detection: template param → derived class mapping
- Range-for iterator protocol: map element fix + begin()/operator*() fallback
- Default argument support via min_params range matching
- Free function auto deduction: identifier eval order fix (function before type)
- decltype() return type parsing in c_parse_return_type_text
- Trailing return type syncs both return_type and return_types array
Watcher no longer polls every indexed project via ListProjects(). Instead,
projects are added to an explicit watch list on index/auto-index and removed
on delete. Cross-project tool calls (search_graph, trace_call_path, etc.)
touch the watch list so referenced projects stay fresh.
- Fix ref counting race in ListProjects and watcher pollAll: use AcquireStore
instead of ForProject to prevent evictor from closing stores mid-query (#52)
- Add recoverStaleSHM: remove stale SHM files after SIGKILL to prevent
deadlock on next connection (#52)
- Increase busy_timeout from 5s to 10s for large databases (#52)
- Default GOMEMLIMIT to 2GB when not configured, preventing unbounded
memory growth and OOM kills (#49, #46)
- Reduce mmap_size from 256MB to 64MB per database (#49, #46)
- Increase watcher base interval from 1s to 5s and poll interval base
from 1s to 5s, reducing CPU usage by ~5x (#45)
- Normalize Windows drive letter to lowercase in ProjectNameFromPath,
preventing duplicate databases for same path (#50)
The Swift external scanner called calloc(0, sizeof(ScannerState)) which
returns a 0-or-1-byte allocation per the C standard. The scanner then
writes a uint32_t (4 bytes) to this region via state->ongoing_raw_str_hash_count,
causing a heap-buffer-overflow detected by AddressSanitizer.
Fix: calloc(0, ...) → calloc(1, ...).
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
- 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.
- 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
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.