Archives >3MB may not be unpacked by VirusTotal, meaning only the
container gets scanned (meaningless). Now extracts the actual
executables from tar.gz/zip before uploading to VirusTotal.
Users still download archives (preserves Unix permissions).
Also fixes analysis ID parsing (base64 format, not SHA256).
Also fixes SBOM format (SPDX 2.3 instead of CycloneDX).
- Wait until at least 60 engines have actually scanned (not just
reported type-unsupported/failure/timeout)
- 20 minute timeout per binary (was 5 minutes)
- If scan doesn't complete in time → FAIL (incomplete scan is not clean)
- Engines that can't scan (type-unsupported, failure, timeout) are
excluded from the completion count
freshclam requires DatabaseMirror set in config. Without it, ClamAV
scans with empty signatures (catches nothing). Now properly configures
freshclam.conf on both Linux (apt) and macOS (Homebrew) before updating.
Every platform now has a real antivirus gate that fails the build:
- Windows: Windows Defender with ML heuristics (MpCmdRun.exe)
- Linux: ClamAV with freshclam signature update
- macOS: ClamAV with freshclam signature update
Any detection on any platform blocks the release-draft from being
created. This is on top of the VirusTotal zero-tolerance gate in
the verify job.
SECURITY.md updated with complete security architecture.
- Output is comma-separated, not newline — use tr ',' '\n' to split
- URLs are /gui/file/<sha256> permalinks — extract SHA256 hash and
query /api/v3/files/<sha256> for last_analysis_stats
- Release notes table builder uses same comma-split fix
- Gate uses /tmp flag file to propagate failure from subshell
The verify job polls VirusTotal API for completed scan results.
If ANY engine flags ANY binary as malicious or suspicious, the
release stays as draft and the pipeline fails. Zero tolerance —
investigate and fix before retrying.
- VirusTotal: scans all release binaries (tar.gz + zip) via
crazy-max/ghaction-virustotal after publishing. Scan result
links are appended to the release notes automatically.
- CHANGELOG.md: local copy of all release notes so history
is preserved in the repo, not just on GitHub.
The DLL resolve feature (f92fd66) contained literal strings
GetProcAddress, dlsym, LoadLibrary that triggered Windows Defender
Wacatac.B!ml heuristic detection on the v0.5.4 binary. These are
the exact API names malware uses for dynamic API resolution.
Removed the feature entirely — it served a niche use case (C/C++
projects with dynamic DLL loading) and the false positive blocks
all Windows users from using the tool.
Fixes#89.
- OpenClaw: detect ~/.openclaw/, write MCP config to openclaw.json
- VS Code was already wired in PR #79 but not counted in README
- Agent struct initializer uses memset instead of counting booleans
- README updated: 8 → 10 agents
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.
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
- 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)
- 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)
- 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>
- 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).
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>
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.
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.
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>
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).
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.
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.
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
- 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>
- 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>