Commit Graph
189 Commits
Author SHA1 Message Date
Martin Vogel 8ca7199847 Add Content-Length framed transport support (OpenCode compatibility)
Some MCP clients (OpenCode, some VS Code extensions) use LSP-style
Content-Length framing instead of bare JSONL:

  Content-Length: 123\r\n\r\n{"jsonrpc":"2.0",...}

The server now auto-detects the transport: if a line starts with
"Content-Length:", it reads the header, skips the blank separator,
reads the exact payload, and responds with Content-Length framing.
Regular JSONL clients are unaffected — the detection only triggers
on the Content-Length prefix.

Fixes #78.
2026-03-20 21:22:06 +01:00
Martin Vogel f7315b9bc5 Robust UI audit: skip inline URL scan on dist/, keep structural checks
Minified JS in dist/ contains hundreds of string-constant URLs from
bundled npm libraries (React error pages, W3C namespace URIs, CDN
references, OSS credits) that are never fetched at runtime. Scanning
them produced an endless stream of false positives requiring per-URL
allowlisting.

Fix: split the A1 URL check by directory:
- src/ (our code): strict — any external URL is blocked
- dist/ (npm build output): skip inline URL scan entirely

Structural checks (A2-A6) still apply to dist/:
- External <script>/<link> loads in HTML
- Tracking/analytics identifiers
- Iframes, eval/Function, external WebSockets
2026-03-20 20:56:52 +01:00
Martin Vogel a9382ce110 Fix UI audit: allow truncated CDN URL in dist/ scan 2026-03-20 20:52:58 +01:00
Martin Vogel e09f27130e Fix Windows bulk test + dual MCP config location + CONTRIBUTING.md
- Bulk test: use cbm_tmpdir() instead of hardcoded /tmp/ (fixes
  Windows/MSYS2 where /tmp/ doesn't resolve for SQLite)
- Install: write MCP config to both ~/.claude/.mcp.json (Claude Code
  <=2.1.x) and ~/.claude.json (Claude Code >=2.1.80). Fixes #69.
- Uninstall: remove from both locations
- CONTRIBUTING.md: rewrite for pure C project (was still describing Go,
  causing contributors to submit Go PRs)
- Fix clang-format in mcp.c protocol version negotiation (PR #79 merge)
2026-03-20 20:32:38 +01:00
Martin Vogel de427776c0 Fix clang-format in merged PR #79 + update CONTRIBUTING.md
- Fix formatting in mcp.c protocol version negotiation (from PR #79 merge)
- Rewrite CONTRIBUTING.md for pure C project (was still describing Go,
  causing contributors to submit Go PRs that can't be merged)
2026-03-20 20:09:25 +01:00
Martin Vogel 92275ffa95 Merge PR #79: Fix VS Code compatibility (schema, install, protocol negotiation) 2026-03-20 19:52:59 +01:00
Martin Vogel b5b9c6bf78 Merge PR #72: keep WAL journal mode during bulk write 2026-03-20 19:29:40 +01:00
f92fd666b5 Port FastAPI Depends() + DLL resolve edge tracking (PR #66)
- FastAPI Depends(func_ref): scans Python function signatures for
  Depends() patterns and creates CALLS edges to the dependency function.
  Without this, auth/DI functions appear as dead code (in_degree=0).
- DLL resolve: scans C/C++ source for GetProcAddress/dlsym/Resolve
  patterns and creates CALLS edges to synthetic stub nodes, enabling
  call graph tracking across DLL boundaries.
- Extension scoping (#28) was already ported in 6a2b1f5.
- SQL size guard (#62) not needed: our C workers use 8MB stacks.

Tests: 3 new (httplink_laravel_path_filter, pipeline_fastapi_depends_edges,
pipeline_dll_resolve_edges). Total: 2041.

Co-Authored-By: kingchenc <kingchenc@users.noreply.github.com>
Co-Authored-By: mariomeyer <mariomeyer@users.noreply.github.com>
2026-03-20 19:19:12 +01:00
Martin Vogel 93d332d1e0 Fix security audit false positives in CI
- UI audit (L6): allowlist bundled framework URLs in dist/ (React error
  URLs, W3C namespace URIs, Three.js credits, Google Fonts, Tailwind).
  These are embedded by npm deps during Vite build, not our code.
- Binary strings (L2): skip URLs shorter than 15 chars — Windows binary
  has byte sequences that strings(1) interprets as "https://H9" etc.
- Allow Google Fonts <link> in HTML (loaded by index.html for Inter/
  JetBrains Mono fonts).
2026-03-20 18:47:55 +01:00
Martin Vogelandmariomeyer 6a2b1f547f Fix Laravel route false positives: extension scoping + path filter
Port of community fix (PR #65):
- Scope source-based route extractors by file extension: Go routes
  only on .go, Express on .js/.ts, Laravel on .php, Ktor on .kt/.kts.
  Prevents cross-framework false positives (e.g. Ktor regex matching
  PHP Cache::get calls).
- Filter Laravel route paths containing $ or : characters — these are
  cache keys or interpolated expressions, not URL paths. Laravel route
  parameters use {param} syntax, so valid routes are unaffected.

Co-Authored-By: mariomeyer <mariomeyer@users.noreply.github.com>
2026-03-20 18:42:44 +01:00
Martin Vogel f80d35094b Remove .mcp.json from repo (user-local config)
Was accidentally committed with a hardcoded absolute path.
The install command generates per-user MCP configs in the
correct editor-specific locations. Added to .gitignore.
2026-03-20 18:31:18 +01:00
Martin Vogel cd1417427c Add 8-layer security test suite + hardening
Code-level defenses:
- cbm_validate_shell_arg(): reject shell metacharacters before popen/system
- SQLite authorizer: block ATTACH/DETACH at engine level
- CORS localhost-only origin reflection (replaces wildcard *)
- Path containment: realpath() check in get_code_snippet
- process-kill restricted to server-spawned PIDs
- SHA256 checksum verification in update command

Security audit scripts (8 layers):
- L1: Static allow-list for dangerous calls + URLs
- L2: Binary string audit (URLs, payloads, credentials)
- L3: Network egress monitoring via strace (Linux)
- L4: Install output path + content validation
- L5: Smoke test hardening (clean shutdown, residual procs)
- L6: Graph UI audit (external domains, CORS, binding)
- L7: MCP robustness (23 adversarial JSON-RPC payloads)
- L8: Vendored integrity (checksums + dangerous call scan)

CI: parallel security-static job (no build needed), binary
layers in smoke jobs per-platform. Cleanup of test fixture
dirs in clean.sh + .gitignore.
2026-03-20 18:19:15 +01:00
Bing Ho 83619f8d41 Bump MCP protocol version with proper negotiation
Support protocol versions 2025-11-25, 2025-06-18, 2025-03-26, and
2024-11-05. The server now reads the client's requested version and
echoes it if supported, falling back to its latest otherwise. This
fixes the "unsupported protocol" warning in VS Code 1.112+ while
remaining backward-compatible with older clients.
2026-03-20 10:42:52 -05:00
Martin VogelandJay Sync c66d88745d Fix Swift call extraction: 0 CALLS edges (#43)
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>
2026-03-20 14:46:46 +01:00
Bing Ho 02575fb307 Add VS Code detection and MCP registration to install/uninstall
The install command detected many editors (Cursor, Zed, Gemini, etc.)
but not VS Code, even though cbm_install_vscode_mcp() already existed.
Add VS Code User config dir detection and wire it into both install
and uninstall flows, writing to ~/.config/Code/User/mcp.json (Linux)
or ~/Library/Application Support/Code/User/mcp.json (macOS).
2026-03-20 08:37:44 -05:00
Bing Ho 89970f2b3e Fix ingest_traces array schema missing items property
VS Code 1.112+ validates that all MCP tool array-type parameters
include an "items" definition (microsoft/vscode#248810). The
ingest_traces tool's "traces" parameter was missing this, causing
startup failures.
2026-03-20 08:31:06 -05:00
Martin Vogel f6b9b39c60 Fix snippet tests: align with simplified get_code_snippet handler
The snippet handler now uses exact QN + suffix matching only (no fuzzy/auto-resolve).
Updated 3 tests to match: fuzzy_suggestions, fuzzy_last_segment, auto_resolve_enabled.
v0.5.3
2026-03-20 13:45:17 +01:00
Martin Vogel d6a5f8984e Add incremental reindex + ADR hints in index/schema/adr responses
Incremental pipeline (pipeline_incremental.c):
- Disk-based delta re-indexing: classifies files by mtime+size vs stored
  hashes, deletes changed nodes (edges cascade), re-parses only changed
  files, merges into existing DB via cbm_gbuf_merge_into_store
- pipeline.c auto-routes: existing DB with hashes -> incremental, else full
- Full pipeline persists file hashes after dump for next incremental run
- No-op when nothing changed (watcher polls every 5-60s, 99% skip)
- 4 tests: noop, changed file, deleted file, new file added

ADR hints (ported from Go):
- index_repository: adr_present + adr_hint when no ADR exists
- get_graph_schema: adr_present + adr_hint per project
- manage_adr GET: adr_hint with creation instructions when no ADR
2026-03-20 13:15:01 +01:00
DeusData 54930c6544 README.md aktualisieren 2026-03-20 01:14:42 +01:00
Shane McCarronandClaude Sonnet 4.6 a0e809d425 fix(store): address QA round 2 findings
- Validate child exit status (WIFEXITED + WEXITSTATUS) after waitpid so
  the test fails fast if the child couldn't open the store, rather than
  passing vacuously due to the "crashed" row never being written

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:17:55 -05:00
Shane McCarronandClaude Sonnet 4.6 675fdf341e fix(store): address QA round 1 findings
- Wrap bulk_crash_recovery test and its POSIX includes with #ifndef _WIN32
  guards to fix compilation failure on Windows (fork/waitpid unavailable)
- Add negative assertion that the uncommitted "crashed" row is absent
  after crash recovery, completing the test's correctness verification

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:07:17 -05:00
Martin Vogel 78e1df2021 Refine messaging: seconds for avg repos, clarify AST (64 langs) vs LSP hybrid (Go/C/C++) 2026-03-19 23:44:35 +01:00
Martin Vogel d1ad61fec3 Update README + website: performance-first messaging, graph UI, 8 agents
- Lead with speed (3-min Linux kernel) and plug-and-play static binaries
- Highlight tree-sitter + LSP hybrid quality (Go, C, C++)
- Add graph UI screenshot to README and website hero
- Update agent list to 8 (add Antigravity, KiloCode, Aider)
- Remove all stale Go build references (go build, CGO_ENABLED, golangci-lint)
- Update architecture section to reflect C source layout
- Update comparison table: Visual web UI now Yes
- Fix stats: 14 tools, 64 languages, 8 agents
- Condense feature list and usage examples
2026-03-19 23:35:30 +01:00
Shane McCarronandClaude Sonnet 4.6 8dd490b47c fix(store): keep WAL journal mode during bulk write to prevent DB corruption on crash
cbm_store_begin_bulk() was switching the SQLite journal mode from WAL to
MEMORY for write throughput.  If the process crashed mid-bulk-write the
in-memory rollback journal was lost, leaving the database file in a
partially-written, unrecoverable state.

WAL mode is inherently crash-safe: uncommitted WAL entries are discarded
on the next open.  The performance benefit of bulk mode is preserved via
synchronous=OFF and an enlarged cache_size, both of which are safe under
WAL.

Remove the PRAGMA journal_mode = MEMORY from cbm_store_begin_bulk and
the matching PRAGMA journal_mode = WAL from cbm_store_end_bulk.  Update
the header comments to reflect the new invariant.

Add tests/test_store_bulk.c with three tests:
- bulk_pragma_wal_invariant: asserts journal_mode remains "wal" after
  cbm_store_begin_bulk via an independent read-only connection
- bulk_pragma_end_wal_invariant: asserts journal_mode remains "wal" after
  cbm_store_end_bulk
- bulk_crash_recovery: forks a child that enters bulk mode, opens an
  explicit transaction, writes data, then calls _exit() without committing;
  the parent verifies the database opens cleanly and baseline data survives

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 17:21:48 -05:00
Martin Vogel 0ef1b7b8c4 Release RAM after indexing, static-link Windows binary
- Call cbm_mem_collect() (mi_collect(true)) after pipeline_free in both
  index_repository and auto-index, returning mimalloc pages to OS
- Add -static to Windows linker flags so the binary is standalone
  (no libc++.dll / libunwind.dll dependency)
v0.5.2
2026-03-19 22:17:38 +01:00
Martin Vogel 3744c6d419 Fix MCP protocolVersion: return plain string, not nested object
protocolVersion was {"version":"2024-11-05"} — MCP spec requires "2024-11-05".
Claude Code rejected the malformed response and marked the server as failed.
v0.5.1
2026-03-19 21:20:06 +01:00
Martin Vogel 7629940dca Restore session auto-detect + auto-index + config CLI from Go
- Config store: persistent SQLite key-value in _config.db (get/set/delete/bool/int)
- Config CLI: codebase-memory-mcp config list|get|set|reset
  Keys: auto_index (default false), auto_index_limit (default 50000)
- Session detection: detect project root from CWD on MCP initialize
- Auto-index: if auto_index=true and project not yet indexed, background pipeline
- Watcher hookup: after index completes, register project for ongoing git polling
- 6 new config store tests (open/close, get/set, bool, int, delete, persistence)

Enable auto-indexing:
  codebase-memory-mcp config set auto_index true
v0.5.0
2026-03-19 20:13:17 +01:00
Martin Vogel 0b8a456b52 Restore startup update check: notify on first tool call if newer release exists
Background thread checks api.github.com/repos/.../releases/latest on initialize,
stores one-shot notice prepended to the first tools/call response content array.
Ported from Go internal/tools/tools.go checkForUpdate + addUpdateNotice pattern.
2026-03-19 19:30:21 +01:00
442cb958f0 Add KiloCode support, fix Zed JSONC parsing (#24, #53)
- KiloCode: detect globalStorage dir, upsert mcp_settings.json, install
  global rules at ~/.kilocode/rules/codebase-memory-mcp.md
- Zed: parse JSONC (comments + trailing commas) in existing settings.json
  — fixes "Invalid JSON" error on install with existing Zed config
- 2 new tests: KiloCode detection, Zed JSONC settings parsing
- Now supports 8 agents: Claude Code, Codex, Gemini, Zed, OpenCode,
  Antigravity, Aider, KiloCode

Co-Authored-By: David34920 <179368816+David34920@users.noreply.github.com>
Co-Authored-By: Paul Cohen <200370+sonicviz@users.noreply.github.com>
Co-Authored-By: Chitral Verma <11135032+chitralverma@users.noreply.github.com>
Co-Authored-By: Noel Kurian <1851449+noelkurian@users.noreply.github.com>
Co-Authored-By: José Almeida <57680069+zeval@users.noreply.github.com>
Co-Authored-By: Vasani Harshil <147682127+harshil480@users.noreply.github.com>
2026-03-19 18:56:16 +01:00
Martin Vogel 159378ad8e Multi-agent install: auto-detect 7 coding agents, upsert configs + hooks + instructions
- Detect Claude Code, Codex CLI, Gemini CLI, Zed, OpenCode, Antigravity, Aider
- Per-agent MCP config upsert: Codex TOML, OpenCode JSON, Antigravity JSON
- Instruction file upsert with marker-based sections (no duplicates on re-install)
- Claude Code PreToolUse hook (Grep|Glob|Read -> MCP reminder)
- Gemini CLI BeforeTool hook (grep_search|read_file -> MCP reminder)
- Fix Zed MCP config: args:[""] instead of broken source:"custom" (#24)
- Rewrite skill descriptions to directive pattern (100% auto-activation)
- Keyword-rich MCP tool descriptions for Tool Search discovery
- 35 new tests (agent detection, config upsert, instructions, hooks)
- All platforms green: macOS 2022, Linux 2004+18skip, Windows cross-compile OK
2026-03-19 16:08:43 +01:00
Martin Vogel 5890aecd48 Fix smoke-windows: skip self-copy for standard variant, fail-fast off
The cp command fails when SUFFIX is empty because source and destination
are the same file. Only copy when SUFFIX is non-empty (ui variant).
Also add fail-fast: false to smoke-windows so both variants always run.
2026-03-19 13:11:23 +01:00
Martin Vogel 796782e08a Fix smoke-windows (ui): rename extracted binary to match expected name
The UI zip contains codebase-memory-mcp-ui.exe but the smoke test
always runs ./codebase-memory-mcp.exe. Copy the extracted binary
to the expected name so both standard and ui variants work.
2026-03-19 12:50:45 +01:00
Martin Vogel 0f3c772014 Fix Windows smoke: convert MSYS2 POSIX paths for native binary
MSYS2 mktemp returns /tmp/tmp.XXX but the Windows binary can't resolve
POSIX paths. Use cygpath -m to convert to C:/msys64/tmp/tmp.XXX which
works in both MSYS2 shell and Windows file APIs.
2026-03-19 12:29:54 +01:00
Martin Vogel dc919b2231 Create cache directory before SQLite dump in pipeline
The dump phase writes to ~/.cache/codebase-memory-mcp/<project>.db
but the directory may not exist on fresh CI runners. Add cbm_mkdir_p()
to ensure the parent directory is created before writing. This fixes
smoke test failures where index_repository returned status "error"
because the dump phase couldn't create the database file.
2026-03-19 12:11:02 +01:00
Martin Vogel a71a65f68e Fix smoke tests: CLANG64 runtime for Windows, debug stderr on error
1. smoke-windows: Use CLANG64 (not UCRT64) so runtime matches the
   build environment. Binary built with CLANG64 needs CLANG64 DLLs.
2. smoke-unix: Add fail-fast: false so one platform failure doesn't
   cancel all 7 other smoke jobs.
3. smoke-test.sh: Capture and display stderr on indexing failure to
   help debug smoke-unix errors.
4. release.yml: Same CLANG64 smoke fix.
2026-03-19 11:31:12 +01:00
Martin Vogel 0e9a47177b Fix Windows build: add zip pkg, portable embed (od replaces xxd)
1. Add zip to MSYS2 build packages (both dry-run and release).
2. embed-frontend.sh: replace xxd with od+sed for hex dump — xxd
   requires vim which isn't in MSYS2 CLANG64 by default.
3. embed-frontend.sh: flip IS_MACOS→IS_LINUX — Linux gets ld -r -b
   binary (ELF-only), everything else (macOS, Windows) gets the
   portable C-array approach via od.
4. release.yml: same Windows archive fix (msys2 shell + .exe detect).
2026-03-19 10:59:14 +01:00
Martin Vogel 89dd3bb7c6 Add skip_tests/skip_builds flags, fix build-stage failures
1. dry-run.yml: Add skip_tests and skip_builds workflow_dispatch inputs
   for faster iteration. Build jobs use always() to run even when tests
   are skipped.

2. Windows archive: Switch from PowerShell Copy-Item to MSYS2 shell
   with .exe extension detection. MSYS2 Clang produces .exe suffix
   that Copy-Item didn't account for.

3. Linux embed: Use absolute path for ld output when cd'd into dist
   directory. Relative path build/c/embedded/*.o was invalid from
   inside graph-ui/dist/.

4. release.yml: Same Windows archive fix as dry-run.
2026-03-19 10:43:32 +01:00
Martin Vogel c4d38c4d5a Fix parallel build race and portable mkdir in tests
1. cbm-with-ui target: add $(OBJS_VENDORED_PROD) as dependency so
   grammar .o files are compiled before linking in parallel make.
   Without this, make -jN fires the link step as soon as embed
   finishes, racing against grammar compilations.

2. test_ui.c: replace system("mkdir -p") with cbm_mkdir_p() for
   Windows compatibility. Add compat_fs.h include.
2026-03-19 09:30:20 +01:00
Martin Vogel 0d7a9a891b Fix Windows UI config tests: replace system("mkdir -p") with cbm_mkdir_p()
Two UI config tests (config_corrupt_file, config_missing_fields) used
Unix-only system("mkdir -p") to create test directories. On Windows this
fails with "The syntax of the command is incorrect." — replaced with the
portable cbm_mkdir_p() function already in compat_fs.h.
2026-03-19 03:48:10 +01:00
Martin Vogel 3abc5cdf02 Fix flaky parallelism test, skip 4 remaining Windows compat issues
- parallel_for_actually_parallel: skip on single-core CI runners
  instead of failing (assertion requires >= 2 concurrent threads)
- Fix mkdir -p → portable mkdir in test_ui.c config tests
- Skip store_dump_to_file and cli_find_cli_on_path on Windows
  (temp file path handling and PATH search need porting)
2026-03-19 03:34:36 +01:00
Martin Vogel 90577d45b0 Skip 12 discover tests on Windows (use Unix shell commands)
Discover integration tests use system("rm -rf && mkdir -p && echo >")
which are Unix shell commands. These tests are properly skipped on
Windows with SKIP_UNIX_SHELL macro. The remaining 4 Windows test
failures (store_dump, cli_find, ui_config x2) need individual fixes.

TODO: Port discover test helpers to use C file operations.
2026-03-19 03:19:06 +01:00
Martin Vogel 18c23d438f Fix 12 more Windows test failures: mkstemp, temp paths, TRE config
- cbm_mkstemp: Windows implementation using _mktemp + _open
- cbm_tmpdir(): portable temp directory function (replaces /tmp/)
- Fix hardcoded /tmp/ paths in test_language, test_gitignore,
  test_store_search, test_sqlite_writer
- Enlarge remaining small path buffers for Windows %TEMP% paths
2026-03-19 02:58:03 +01:00
Martin Vogel d6ec954b9c Fix cbm_mkdtemp: enlarge all test buffers to 256 bytes
The /tmp/ → %TEMP%\ translation produces longer paths (~50 chars)
than the original templates (~25 chars). Changed all 68 test
declarations from char tmpdir[] = "..." (sized to literal) to
char tmpdir[256] with snprintf initialization.
2026-03-19 02:38:02 +01:00
Martin Vogel 6f5b77aeba Fix TRE wchar: undefine TRE_WCHAR/TRE_MULTIBYTE (ifdef checks presence) 2026-03-19 02:21:56 +01:00
Martin Vogel 5f7cd226cb Use system regex on MSYS2, TRE only for pure MinGW (CBM_USE_TRE) 2026-03-19 02:05:20 +01:00
Martin Vogel 07f82b9c54 Vendor TRE regex for Windows, fix cbm_mkdtemp buffer overflow
- Vendor TRE regex library (BSD-licensed, ~9K LOC) for Windows —
  eliminates the TODO stub that caused all regex tests to fail
- Fix cbm_mkdtemp stack-buffer-overflow: use static buffer for
  /tmp/ → %TEMP%\ path translation (Windows paths are longer)
- Wine test results: 1861 passed, 50 failed (Wine filesystem limits),
  75 skipped — remaining failures are Wine-specific, not Windows bugs
2026-03-19 01:47:37 +01:00
Martin Vogel d1632ec7e1 Fix cbm_mkdtemp for Windows, add Wine test execution to Docker
- cbm_mkdtemp: translate /tmp/ to %TEMP%\ on Windows
- Docker test-windows: cross-compile + run under Wine (without ASan,
  which doesn't work under Wine)
- Wine on PATH fix for Ubuntu noble (/usr/lib/wine/)
- Tool preflight check in Dockerfile
- 1887/1992 tests pass under Wine (52 fail: regex not available in
  pure MinGW — works on real MSYS2 which provides <regex.h>)
2026-03-19 00:59:54 +01:00
Martin Vogel 51839ca3bd Set 8MB stack on Windows (matches Linux/macOS default) 2026-03-19 00:16:41 +01:00
Martin Vogel 0f83f08653 Auto-detect WIN32_LIBS in Makefile, remove shell quoting entirely 2026-03-19 00:00:19 +01:00
Martin Vogel b5f14f115d Fix WIN32_LIBS quoting via env vars, add skip_lint to dry-run
- Use env: block instead of shell quoting for WIN32_LIBS in CI
- Forward WIN32_LIBS from environment in test.sh and build.sh
- Add skip_lint input to dry-run workflow for faster iteration
2026-03-18 23:35:35 +01:00