Skip to content
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ Full agent setup: [AI Agent Guide](docs/guides/ai-agent-guide.md) · [CLAU
| 📋 | **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 |
| 📦 | **Batch querying** | Accept a list of targets and return all results in one JSON payload — enables multi-agent parallel dispatch |
| 🔬 | **Dataflow analysis** | Track how data moves through functions with `flows_to`, `returns`, and `mutates` edges — opt-in via `build --dataflow` (JS/TS) |
| 🧩 | **Control flow graph** | Intraprocedural CFG construction for all 11 languages — `cfg` command with text/DOT/Mermaid output, opt-in via `build --cfg` |
| 🔬 | **Dataflow analysis** | Track how data moves through functions with `flows_to`, `returns`, and `mutates` edges — included by default (JS/TS), skip with `--no-dataflow` |
| 🧩 | **Control flow graph** | Intraprocedural CFG construction for all 11 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 @@ -327,7 +327,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 requires `codegraph build --dataflow` (JS/TS only). CFG requires `codegraph build --cfg`. Both are opt-in to keep default builds fast.
> **Note:** Dataflow (JS/TS only) and CFG are included by default. Use `--no-dataflow` / `--no-cfg` for faster builds.

### Audit, Triage & Batch

Expand Down
23 changes: 9 additions & 14 deletions src/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,9 @@ export async function buildGraph(rootDir, opts = {}) {
}

if (!isFullBuild && parseChanges.length === 0 && removed.length === 0) {
// Check if optional analysis was requested but never computed
// Check if default analyses were never computed (e.g. legacy DB)
const needsCfg =
opts.cfg &&
opts.cfg !== false &&
(() => {
try {
return db.prepare('SELECT COUNT(*) as c FROM cfg_blocks').get().c === 0;
Expand All @@ -533,16 +533,10 @@ export async function buildGraph(rootDir, opts = {}) {
}
})();
const needsDataflow =
opts.dataflow &&
opts.dataflow !== false &&
(() => {
try {
return (
db
.prepare(
"SELECT COUNT(*) as c FROM edges WHERE kind IN ('flows_to','returns','mutates')",
)
.get().c === 0
);
return db.prepare('SELECT COUNT(*) as c FROM dataflow').get().c === 0;
} catch {
return true;
}
Expand Down Expand Up @@ -1271,8 +1265,8 @@ export async function buildGraph(rootDir, opts = {}) {
}
_t.complexityMs = performance.now() - _t.complexity0;

// Opt-in CFG analysis (--cfg)
if (opts.cfg) {
// CFG analysis (skip with --no-cfg)
if (opts.cfg !== false) {
_t.cfg0 = performance.now();
try {
const { buildCFGData } = await import('./cfg.js');
Expand All @@ -1283,8 +1277,8 @@ export async function buildGraph(rootDir, opts = {}) {
_t.cfgMs = performance.now() - _t.cfg0;
}

// Opt-in dataflow analysis (--dataflow)
if (opts.dataflow) {
// Dataflow analysis (skip with --no-dataflow)
if (opts.dataflow !== false) {
_t.dataflow0 = performance.now();
try {
const { buildDataflowEdges } = await import('./dataflow.js');
Expand Down Expand Up @@ -1387,6 +1381,7 @@ export async function buildGraph(rootDir, opts = {}) {
rolesMs: +_t.rolesMs.toFixed(1),
complexityMs: +_t.complexityMs.toFixed(1),
...(_t.cfgMs != null && { cfgMs: +_t.cfgMs.toFixed(1) }),
...(_t.dataflowMs != null && { dataflowMs: +_t.dataflowMs.toFixed(1) }),
},
};
}
3 changes: 2 additions & 1 deletion src/cfg.js
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,8 @@ export function cfgData(name, customDbPath, opts = {}) {
return {
name,
results: [],
warning: 'No CFG data found. Run `codegraph build --cfg` first.',
warning:
'No CFG data found. Rebuild with `codegraph build` (CFG is now included by default).',
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ program
.command('build [dir]')
.description('Parse repo and build graph in .codegraph/graph.db')
.option('--no-incremental', 'Force full rebuild (ignore file hashes)')
.option('--dataflow', 'Extract data flow edges (flows_to, returns, mutates)')
.option('--cfg', 'Build intraprocedural control flow graphs')
.option('--no-dataflow', 'Skip data flow edge extraction')
.option('--no-cfg', 'Skip control flow graph building')
.action(async (dir, opts) => {
const root = path.resolve(dir || '.');
const engine = program.opts().engine;
Expand Down
9 changes: 6 additions & 3 deletions src/dataflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,8 @@ export function dataflowData(name, customDbPath, opts = {}) {
return {
name,
results: [],
warning: 'No dataflow data found. Run `codegraph build --dataflow` first.',
warning:
'No dataflow data found. Rebuild with `codegraph build` (dataflow is now included by default).',
};
}

Expand Down Expand Up @@ -876,7 +877,8 @@ export function dataflowPathData(from, to, customDbPath, opts = {}) {
from,
to,
found: false,
warning: 'No dataflow data found. Run `codegraph build --dataflow` first.',
warning:
'No dataflow data found. Rebuild with `codegraph build` (dataflow is now included by default).',
};
}

Expand Down Expand Up @@ -1005,7 +1007,8 @@ export function dataflowImpactData(name, customDbPath, opts = {}) {
return {
name,
results: [],
warning: 'No dataflow data found. Run `codegraph build --dataflow` first.',
warning:
'No dataflow data found. Rebuild with `codegraph build` (dataflow is now included by default).',
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/mcp.js
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ const BASE_TOOLS = [
},
{
name: 'cfg',
description: 'Show intraprocedural control flow graph for a function. Requires build --cfg.',
description: 'Show intraprocedural control flow graph for a function.',
inputSchema: {
type: 'object',
properties: {
Expand All @@ -658,7 +658,7 @@ const BASE_TOOLS = [
},
{
name: 'dataflow',
description: 'Show data flow edges or data-dependent blast radius. Requires build --dataflow.',
description: 'Show data flow edges or data-dependent blast radius.',
inputSchema: {
type: 'object',
properties: {
Expand Down