Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@

All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.

## [3.8.0](https://github.com/optave/ops-codegraph-tool/compare/v3.7.0...v3.8.0) (2026-04-01)

**34 languages and a fully native build pipeline.** This release completes Phase 7 (Expanded Language Support) by shipping the final 11 languages — F#, Gleam, Clojure, Julia, R, Erlang, Solidity, Objective-C, CUDA, Groovy, and Verilog — bringing codegraph from 23 to 34 supported languages. On the performance side, the entire build pipeline now runs natively in Rust: graph algorithms (BFS, shortest path, Louvain, centrality), import edge building with barrel resolution, and build-glue queries all migrate from JS to napi-rs. A new Rust build orchestration layer coordinates the full native pipeline end-to-end.

### Features

* add F#, Gleam, Clojure, Julia, R, Erlang language support ([#722](https://github.com/optave/ops-codegraph-tool/pull/722))
* add Solidity, Objective-C, CUDA, Groovy, Verilog language support ([#729](https://github.com/optave/ops-codegraph-tool/pull/729))
* full Rust build orchestration ([#740](https://github.com/optave/ops-codegraph-tool/pull/740))

### Bug Fixes

* **native:** enable bulkInsertNodes native path ([#736](https://github.com/optave/ops-codegraph-tool/pull/736))
* **native:** enable bulkInsertNodes native path — null-visibility serialisation ([#737](https://github.com/optave/ops-codegraph-tool/pull/737))
* **native:** prevent SQLITE_CORRUPT in incremental pipeline ([#728](https://github.com/optave/ops-codegraph-tool/pull/728))
* **ocaml:** use LANGUAGE_OCAML_INTERFACE grammar for .mli files ([#730](https://github.com/optave/ops-codegraph-tool/pull/730))
* address unresolved review feedback from batch4 language extractors ([#731](https://github.com/optave/ops-codegraph-tool/pull/731))
* **bench:** report partial native results when incremental rebuild fails ([#741](https://github.com/optave/ops-codegraph-tool/pull/741))

### Performance

* migrate graph algorithms (BFS, shortest path, Louvain, centrality) to Rust ([#732](https://github.com/optave/ops-codegraph-tool/pull/732))
* migrate import edge building + barrel resolution to Rust ([#738](https://github.com/optave/ops-codegraph-tool/pull/738))
* **native:** expose standalone complexity/CFG/dataflow analysis via napi-rs ([#733](https://github.com/optave/ops-codegraph-tool/pull/733))
* native Rust build-glue queries (detect-changes, finalize, incremental) ([#735](https://github.com/optave/ops-codegraph-tool/pull/735))

### Refactors

* **native:** remove call kind from AST node extraction ([#734](https://github.com/optave/ops-codegraph-tool/pull/734))

## [3.7.0](https://github.com/optave/ops-codegraph-tool/compare/v3.6.0...v3.7.0) (2026-03-30)

**Six more languages and a CFG stability fix.** Codegraph now supports Elixir, Lua, Dart, Zig, Haskell, and OCaml — bringing the total to 23 languages with dual-engine extractors. A WAL conflict in the native CFG bulk-insert path is also fixed, preventing database corruption when JS and native connections overlap during control-flow graph writes.
Expand Down
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ No config files, no Docker, no JVM, no API keys, no accounts. Point your agent a

| Capability | codegraph | [joern](https://github.com/joernio/joern) | [narsil-mcp](https://github.com/postrv/narsil-mcp) | [cpg](https://github.com/Fraunhofer-AISEC/cpg) | [axon](https://github.com/harshkedia177/axon) | [GitNexus](https://github.com/abhigyanpatwari/GitNexus) |
|---|:---:|:---:|:---:|:---:|:---:|:---:|
| Languages | **23** | ~12 | **32** | ~10 | 3 | 13 |
| Languages | **34** | ~12 | **32** | ~10 | 3 | 13 |
| MCP server | **Yes** | — | **Yes** | **Yes** | **Yes** | **Yes** |
| Dataflow + CFG + AST querying | **Yes** | **Yes** | **Yes**¹ | **Yes** | — | — |
| Hybrid search (BM25 + semantic) | **Yes** | — | — | — | **Yes** | **Yes** |
Expand All @@ -104,9 +104,9 @@ No config files, no Docker, no JVM, no API keys, no accounts. Point your agent a
| **🔬** | **Function-level, not just files** | Traces `handleAuth()` → `validateToken()` → `decryptJWT()` and shows 14 callers across 9 files break if `decryptJWT` changes |
| **⚡** | **Always-fresh graph** | Three-tier change detection: journal (O(changed)) → mtime+size (O(n) stats) → hash (O(changed) reads). Sub-second rebuilds — agents work with current data |
| **💥** | **Git diff impact** | `codegraph diff-impact` shows changed functions, their callers, and full blast radius — enriched with historically coupled files from git co-change analysis. Ships with a GitHub Actions workflow |
| **🌐** | **Multi-language, one graph** | JS/TS + Python + Go + Rust + Java + C# + PHP + Ruby + C + C++ + Kotlin + Swift + Scala + Bash + HCL + Elixir + Lua + Dart + Zig + Haskell + OCaml in a single graph — agents don't need per-language tools |
| **🌐** | **Multi-language, one graph** | 34 languages in a single graph — JS/TS, Python, Go, Rust, Java, C#, PHP, Ruby, C/C++, Kotlin, Swift, Scala, Bash, HCL, Elixir, Lua, Dart, Zig, Haskell, OCaml, F#, Gleam, Clojure, Julia, R, Erlang, Solidity, Objective-C, CUDA, Groovy, Verilog — agents don't need per-language tools |
| **🧠** | **Hybrid search** | BM25 keyword + semantic embeddings fused via RRF — `hybrid` (default), `semantic`, or `keyword` mode; multi-query via `"auth; token; JWT"` |
| **🔬** | **Dataflow + CFG** | Track how data flows through functions (`flows_to`, `returns`, `mutates`) and visualize intraprocedural control flow graphs for all 23 languages |
| **🔬** | **Dataflow + CFG** | Track how data flows through functions (`flows_to`, `returns`, `mutates`) and visualize intraprocedural control flow graphs for all 34 languages |
| **🔓** | **Fully local, zero cost** | No API keys, no accounts, no network calls. Optionally bring your own LLM provider — your code only goes where you choose |

---
Expand Down Expand Up @@ -200,7 +200,7 @@ cd codegraph && npm install && npm link
| 📋 | **Composite audit** | Single `audit` command combining explain + impact + health metrics per function — one call instead of 3-4 |
| 🚦 | **Triage queue** | `triage` merges connectivity, hotspots, roles, and complexity into a ranked audit priority queue |
| 🔬 | **Dataflow analysis** | Track how data moves through functions with `flows_to`, `returns`, and `mutates` edges — all 23 languages, included by default, skip with `--no-dataflow` |
| 🧩 | **Control flow graph** | Intraprocedural CFG construction for all 23 languages — `cfg` command with text/DOT/Mermaid output, included by default, skip with `--no-cfg` |
| 🧩 | **Control flow graph** | Intraprocedural CFG construction for all 34 languages — `cfg` command with text/DOT/Mermaid output, included by default, skip with `--no-cfg` |
| 🔎 | **AST node querying** | Stored queryable AST nodes (calls, `new`, string, regex, throw, await) — `ast` command with SQL GLOB pattern matching |
| 🧬 | **Expanded node/edge types** | `parameter`, `property`, `constant` node kinds with `parent_id` for sub-declaration queries; `contains`, `parameter_of`, `receiver` edge kinds |
| 📊 | **Exports analysis** | `exports <file>` shows all exported symbols with per-symbol consumers, re-export detection, and counts |
Expand Down Expand Up @@ -320,7 +320,7 @@ codegraph ast -k call # Filter by kind: call, new, string, regex
codegraph ast -k throw --file src/ # Combine kind and file filters
```

> **Note:** Dataflow and CFG are included by default for all 23 languages. Use `--no-dataflow` / `--no-cfg` for faster builds.
> **Note:** Dataflow and CFG are included by default for all 34 languages. Use `--no-dataflow` / `--no-cfg` for faster builds.


### Audit, Triage & Batch
Expand Down Expand Up @@ -494,6 +494,17 @@ codegraph registry remove <name> # Unregister
| ![Zig](https://img.shields.io/badge/-Zig-F7A41D?style=flat-square&logo=zig&logoColor=white) | `.zig` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Haskell](https://img.shields.io/badge/-Haskell-5D4F85?style=flat-square&logo=haskell&logoColor=white) | `.hs` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![OCaml](https://img.shields.io/badge/-OCaml-EC6813?style=flat-square&logo=ocaml&logoColor=white) | `.ml`, `.mli` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![F#](https://img.shields.io/badge/-F%23-378BBA?style=flat-square&logo=fsharp&logoColor=white) | `.fs`, `.fsx`, `.fsi` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Gleam](https://img.shields.io/badge/-Gleam-FFAFF3?style=flat-square&logoColor=black) | `.gleam` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Clojure](https://img.shields.io/badge/-Clojure-5881D8?style=flat-square&logo=clojure&logoColor=white) | `.clj`, `.cljs`, `.cljc` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Julia](https://img.shields.io/badge/-Julia-9558B2?style=flat-square&logo=julia&logoColor=white) | `.jl` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![R](https://img.shields.io/badge/-R-276DC3?style=flat-square&logo=r&logoColor=white) | `.r`, `.R` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Erlang](https://img.shields.io/badge/-Erlang-A90533?style=flat-square&logo=erlang&logoColor=white) | `.erl`, `.hrl` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Solidity](https://img.shields.io/badge/-Solidity-363636?style=flat-square&logo=solidity&logoColor=white) | `.sol` | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| ![Objective-C](https://img.shields.io/badge/-Objective--C-438EFF?style=flat-square&logoColor=white) | `.m` | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| ![CUDA](https://img.shields.io/badge/-CUDA-76B900?style=flat-square&logo=nvidia&logoColor=white) | `.cu`, `.cuh` | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| ![Groovy](https://img.shields.io/badge/-Groovy-4298B8?style=flat-square&logo=apachegroovy&logoColor=white) | `.groovy`, `.gvy` | ✓ | ✓ | ✓ | ✓ | — | ✓ |
| ![Verilog](https://img.shields.io/badge/-Verilog-848484?style=flat-square&logoColor=white) | `.v`, `.sv` | ✓ | ✓ | ✓ | — | — | ✓ |
| ![Terraform](https://img.shields.io/badge/-Terraform-844FBA?style=flat-square&logo=terraform&logoColor=white) | `.tf`, `.hcl` | ✓ | —³ | —³ | —³ | —³ | —³ |

> ¹ **Heritage** = `extends`, `implements`, `include`/`extend` (Ruby), trait `impl` (Rust), receiver methods (Go).
Expand Down Expand Up @@ -798,7 +809,7 @@ See **[ROADMAP.md](docs/roadmap/ROADMAP.md)** for the full development roadmap a
6. ~~**Resolution Accuracy**~~ — **Complete** (v3.3.1) — type inference, receiver type tracking, dead role sub-categories, resolution benchmarks, `package.json` exports, monorepo workspace resolution
7. ~~**TypeScript Migration**~~ — **Complete** (v3.4.0) — all 271 source files migrated from JS to TS, zero `.js` remaining
8. ~~**Native Analysis Acceleration**~~ — **Complete** (v3.5.0) — all build phases in Rust/rusqlite, sub-100ms incremental rebuilds, better-sqlite3 lazy-loaded as fallback only
9. **Expanded Language Support** — **In Progress** (v3.7.0) — Batch 1 shipped (C, C++, Kotlin, Swift, Scala, Bash), Batch 2 shipped (Elixir, Lua, Dart, Zig, Haskell, OCaml); 11 remaining in 2 batches (23 → 34)
9. ~~**Expanded Language Support**~~ — **Complete** (v3.8.0) — 23 new languages in 4 batches (11 → 34), dual-engine WASM + Rust support for all
10. **Analysis Depth** — TypeScript-native resolution, inter-procedural type propagation, field-based points-to analysis
11. **Runtime & Extensibility** — event-driven pipeline, plugin system, query caching, pagination
12. **Quality, Security & Technical Debt** — supply-chain security (SBOM, SLSA), CI coverage gates, timer cleanup, tech debt kill list
Expand Down
2 changes: 1 addition & 1 deletion crates/codegraph-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "codegraph-core"
version = "3.7.0"
version = "3.8.0"
edition = "2021"
license = "Apache-2.0"

Expand Down
25 changes: 18 additions & 7 deletions crates/codegraph-core/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,18 @@ fn collect_function_nodes<'a>(
}

/// Parse source code and return a tree + language kind, or None if unsupported.
fn parse_source(source: &str, file_path: &str) -> Option<(tree_sitter::Tree, LanguageKind)> {
let lang = LanguageKind::from_extension(file_path)?;
/// When `lang_id` is provided, it is used as the primary language hint (supports
/// files whose language is inferred by content rather than extension, e.g. `.vue`
/// files tagged as `"javascript"` or extension-less files with a shebang).
/// Falls back to extension detection when `lang_id` is `None`.
fn parse_source(
source: &str,
file_path: &str,
lang_id: Option<&str>,
) -> Option<(tree_sitter::Tree, LanguageKind)> {
let lang = lang_id
.and_then(LanguageKind::from_lang_id)
.or_else(|| LanguageKind::from_extension(file_path))?;
let mut parser = Parser::new();
parser.set_language(&lang.tree_sitter_language()).ok()?;
let tree = parser.parse(source.as_bytes(), None)?;
Expand All @@ -57,8 +67,9 @@ fn parse_source(source: &str, file_path: &str) -> Option<(tree_sitter::Tree, Lan
pub fn analyze_complexity_standalone(
source: &str,
file_path: &str,
lang_id: Option<&str>,
) -> Vec<FunctionComplexityResult> {
let (tree, lang) = match parse_source(source, file_path) {
let (tree, lang) = match parse_source(source, file_path, lang_id) {
Some(v) => v,
None => return Vec::new(),
};
Expand Down Expand Up @@ -91,8 +102,8 @@ pub fn analyze_complexity_standalone(

/// Build control-flow graphs for all functions in the given source.
/// Returns per-function results with name, line, and CFG data.
pub fn build_cfg_standalone(source: &str, file_path: &str) -> Vec<FunctionCfgResult> {
let (tree, lang) = match parse_source(source, file_path) {
pub fn build_cfg_standalone(source: &str, file_path: &str, lang_id: Option<&str>) -> Vec<FunctionCfgResult> {
let (tree, lang) = match parse_source(source, file_path, lang_id) {
Some(v) => v,
None => return Vec::new(),
};
Expand Down Expand Up @@ -130,7 +141,7 @@ pub fn build_cfg_standalone(source: &str, file_path: &str) -> Vec<FunctionCfgRes

/// Extract dataflow analysis for the given source.
/// Returns file-level dataflow result (parameters, returns, assignments, arg flows, mutations).
pub fn extract_dataflow_standalone(source: &str, file_path: &str) -> Option<DataflowResult> {
let (tree, lang) = parse_source(source, file_path)?;
pub fn extract_dataflow_standalone(source: &str, file_path: &str, lang_id: Option<&str>) -> Option<DataflowResult> {
let (tree, lang) = parse_source(source, file_path, lang_id)?;
extract_dataflow(&tree, source.as_bytes(), lang.lang_id_str())
}
20 changes: 13 additions & 7 deletions crates/codegraph-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,30 +129,36 @@ pub fn engine_version() -> String {

/// Analyze complexity metrics for all functions in the given source.
/// Returns per-function results (name, line, endLine, complexity metrics).
/// Language is detected from the file extension or treated as a lang_id.
/// When `lang_id` is provided, it takes priority over extension-based detection.
#[napi]
pub fn analyze_complexity(
source: String,
file_path: String,
lang_id: Option<String>,
) -> Vec<types::FunctionComplexityResult> {
analysis::analyze_complexity_standalone(&source, &file_path)
analysis::analyze_complexity_standalone(&source, &file_path, lang_id.as_deref())
}

/// Build control-flow graphs for all functions in the given source.
/// Returns per-function results (name, line, endLine, CFG blocks + edges).
/// Language is detected from the file extension or treated as a lang_id.
/// When `lang_id` is provided, it takes priority over extension-based detection.
#[napi]
pub fn build_cfg_analysis(source: String, file_path: String) -> Vec<types::FunctionCfgResult> {
analysis::build_cfg_standalone(&source, &file_path)
pub fn build_cfg_analysis(
source: String,
file_path: String,
lang_id: Option<String>,
) -> Vec<types::FunctionCfgResult> {
analysis::build_cfg_standalone(&source, &file_path, lang_id.as_deref())
}

/// Extract dataflow analysis for the given source.
/// Returns file-level dataflow (parameters, returns, assignments, arg flows, mutations).
/// Language is detected from the file extension or treated as a lang_id.
/// When `lang_id` is provided, it takes priority over extension-based detection.
#[napi]
pub fn extract_dataflow_analysis(
source: String,
file_path: String,
lang_id: Option<String>,
) -> Option<types::DataflowResult> {
analysis::extract_dataflow_standalone(&source, &file_path)
analysis::extract_dataflow_standalone(&source, &file_path, lang_id.as_deref())
}
2 changes: 1 addition & 1 deletion docs/roadmap/BACKLOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Codegraph Feature Backlog

**Last updated:** 2026-03-30
**Last updated:** 2026-04-01
**Source:** Features derived from [COMPETITIVE_ANALYSIS.md](../../generated/competitive/COMPETITIVE_ANALYSIS.md) and internal roadmap discussions.

---
Expand Down
Loading
Loading