@optave/codegraph 3.1.3 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -84
- package/package.json +13 -8
- package/src/ast-analysis/engine.js +32 -12
- package/src/ast-analysis/shared.js +6 -5
- package/src/cli/commands/ast.js +22 -0
- package/src/cli/commands/audit.js +45 -0
- package/src/cli/commands/batch.js +68 -0
- package/src/cli/commands/branch-compare.js +21 -0
- package/src/cli/commands/build.js +26 -0
- package/src/cli/commands/cfg.js +26 -0
- package/src/cli/commands/check.js +74 -0
- package/src/cli/commands/children.js +28 -0
- package/src/cli/commands/co-change.js +67 -0
- package/src/cli/commands/communities.js +19 -0
- package/src/cli/commands/complexity.js +46 -0
- package/src/cli/commands/context.js +30 -0
- package/src/cli/commands/cycles.js +32 -0
- package/src/cli/commands/dataflow.js +28 -0
- package/src/cli/commands/deps.js +12 -0
- package/src/cli/commands/diff-impact.js +26 -0
- package/src/cli/commands/embed.js +30 -0
- package/src/cli/commands/export.js +78 -0
- package/src/cli/commands/exports.js +14 -0
- package/src/cli/commands/flow.js +32 -0
- package/src/cli/commands/fn-impact.js +26 -0
- package/src/cli/commands/impact.js +12 -0
- package/src/cli/commands/info.js +76 -0
- package/src/cli/commands/map.js +19 -0
- package/src/cli/commands/mcp.js +18 -0
- package/src/cli/commands/models.js +19 -0
- package/src/cli/commands/owners.js +25 -0
- package/src/cli/commands/path.js +36 -0
- package/src/cli/commands/plot.js +89 -0
- package/src/cli/commands/query.js +45 -0
- package/src/cli/commands/registry.js +100 -0
- package/src/cli/commands/roles.js +30 -0
- package/src/cli/commands/search.js +42 -0
- package/src/cli/commands/sequence.js +28 -0
- package/src/cli/commands/snapshot.js +66 -0
- package/src/cli/commands/stats.js +15 -0
- package/src/cli/commands/structure.js +33 -0
- package/src/cli/commands/triage.js +78 -0
- package/src/cli/commands/watch.js +12 -0
- package/src/cli/commands/where.js +20 -0
- package/src/cli/index.js +124 -0
- package/src/cli/shared/open-graph.js +13 -0
- package/src/cli/shared/options.js +59 -0
- package/src/cli/shared/output.js +1 -0
- package/src/cli.js +11 -1522
- package/src/db/connection.js +130 -7
- package/src/{db.js → db/index.js} +17 -5
- package/src/db/migrations.js +42 -1
- package/src/db/query-builder.js +20 -12
- package/src/db/repository/base.js +201 -0
- package/src/db/repository/graph-read.js +7 -4
- package/src/db/repository/in-memory-repository.js +575 -0
- package/src/db/repository/index.js +5 -1
- package/src/db/repository/nodes.js +60 -6
- package/src/db/repository/sqlite-repository.js +219 -0
- package/src/domain/analysis/context.js +408 -0
- package/src/domain/analysis/dependencies.js +341 -0
- package/src/domain/analysis/exports.js +134 -0
- package/src/domain/analysis/impact.js +466 -0
- package/src/domain/analysis/module-map.js +322 -0
- package/src/domain/analysis/roles.js +45 -0
- package/src/domain/analysis/symbol-lookup.js +238 -0
- package/src/domain/graph/builder/context.js +85 -0
- package/src/domain/graph/builder/helpers.js +218 -0
- package/src/domain/graph/builder/incremental.js +178 -0
- package/src/domain/graph/builder/pipeline.js +130 -0
- package/src/domain/graph/builder/stages/build-edges.js +297 -0
- package/src/domain/graph/builder/stages/build-structure.js +113 -0
- package/src/domain/graph/builder/stages/collect-files.js +44 -0
- package/src/domain/graph/builder/stages/detect-changes.js +413 -0
- package/src/domain/graph/builder/stages/finalize.js +139 -0
- package/src/domain/graph/builder/stages/insert-nodes.js +195 -0
- package/src/domain/graph/builder/stages/parse-files.js +28 -0
- package/src/domain/graph/builder/stages/resolve-imports.js +143 -0
- package/src/domain/graph/builder/stages/run-analyses.js +44 -0
- package/src/domain/graph/builder.js +11 -0
- package/src/{change-journal.js → domain/graph/change-journal.js} +1 -1
- package/src/domain/graph/cycles.js +82 -0
- package/src/{journal.js → domain/graph/journal.js} +1 -1
- package/src/{resolve.js → domain/graph/resolve.js} +3 -3
- package/src/{watcher.js → domain/graph/watcher.js} +10 -150
- package/src/{parser.js → domain/parser.js} +5 -5
- package/src/domain/queries.js +48 -0
- package/src/domain/search/generator.js +163 -0
- package/src/domain/search/index.js +13 -0
- package/src/domain/search/models.js +218 -0
- package/src/domain/search/search/cli-formatter.js +151 -0
- package/src/domain/search/search/filters.js +46 -0
- package/src/domain/search/search/hybrid.js +121 -0
- package/src/domain/search/search/keyword.js +68 -0
- package/src/domain/search/search/prepare.js +66 -0
- package/src/domain/search/search/semantic.js +145 -0
- package/src/domain/search/stores/fts5.js +27 -0
- package/src/domain/search/stores/sqlite-blob.js +24 -0
- package/src/domain/search/strategies/source.js +14 -0
- package/src/domain/search/strategies/structured.js +43 -0
- package/src/domain/search/strategies/text-utils.js +43 -0
- package/src/extractors/csharp.js +10 -2
- package/src/extractors/go.js +3 -1
- package/src/extractors/helpers.js +71 -0
- package/src/extractors/java.js +9 -2
- package/src/extractors/javascript.js +39 -2
- package/src/extractors/php.js +3 -1
- package/src/extractors/python.js +14 -3
- package/src/extractors/rust.js +3 -1
- package/src/{ast.js → features/ast.js} +8 -8
- package/src/{audit.js → features/audit.js} +16 -44
- package/src/{batch.js → features/batch.js} +6 -5
- package/src/{boundaries.js → features/boundaries.js} +2 -2
- package/src/{branch-compare.js → features/branch-compare.js} +3 -3
- package/src/{cfg.js → features/cfg.js} +11 -12
- package/src/{check.js → features/check.js} +13 -30
- package/src/{cochange.js → features/cochange.js} +5 -5
- package/src/{communities.js → features/communities.js} +18 -90
- package/src/{complexity.js → features/complexity.js} +13 -13
- package/src/{dataflow.js → features/dataflow.js} +12 -13
- package/src/features/export.js +378 -0
- package/src/{flow.js → features/flow.js} +4 -4
- package/src/features/graph-enrichment.js +327 -0
- package/src/{manifesto.js → features/manifesto.js} +6 -6
- package/src/{owners.js → features/owners.js} +2 -2
- package/src/{sequence.js → features/sequence.js} +16 -52
- package/src/{snapshot.js → features/snapshot.js} +8 -7
- package/src/{structure.js → features/structure.js} +20 -45
- package/src/{triage.js → features/triage.js} +27 -79
- package/src/graph/algorithms/bfs.js +49 -0
- package/src/graph/algorithms/centrality.js +16 -0
- package/src/graph/algorithms/index.js +5 -0
- package/src/graph/algorithms/louvain.js +26 -0
- package/src/graph/algorithms/shortest-path.js +41 -0
- package/src/graph/algorithms/tarjan.js +49 -0
- package/src/graph/builders/dependency.js +110 -0
- package/src/graph/builders/index.js +3 -0
- package/src/graph/builders/structure.js +40 -0
- package/src/graph/builders/temporal.js +33 -0
- package/src/graph/classifiers/index.js +2 -0
- package/src/graph/classifiers/risk.js +85 -0
- package/src/graph/classifiers/roles.js +64 -0
- package/src/graph/index.js +13 -0
- package/src/graph/model.js +230 -0
- package/src/index.cjs +16 -0
- package/src/index.js +42 -219
- package/src/{native.js → infrastructure/native.js} +3 -1
- package/src/infrastructure/result-formatter.js +2 -21
- package/src/mcp/index.js +2 -0
- package/src/mcp/middleware.js +26 -0
- package/src/mcp/server.js +128 -0
- package/src/{mcp.js → mcp/tool-registry.js} +6 -675
- package/src/mcp/tools/ast-query.js +14 -0
- package/src/mcp/tools/audit.js +21 -0
- package/src/mcp/tools/batch-query.js +11 -0
- package/src/mcp/tools/branch-compare.js +12 -0
- package/src/mcp/tools/cfg.js +21 -0
- package/src/mcp/tools/check.js +43 -0
- package/src/mcp/tools/co-changes.js +20 -0
- package/src/mcp/tools/code-owners.js +12 -0
- package/src/mcp/tools/communities.js +15 -0
- package/src/mcp/tools/complexity.js +18 -0
- package/src/mcp/tools/context.js +17 -0
- package/src/mcp/tools/dataflow.js +26 -0
- package/src/mcp/tools/diff-impact.js +24 -0
- package/src/mcp/tools/execution-flow.js +26 -0
- package/src/mcp/tools/export-graph.js +57 -0
- package/src/mcp/tools/file-deps.js +12 -0
- package/src/mcp/tools/file-exports.js +13 -0
- package/src/mcp/tools/find-cycles.js +15 -0
- package/src/mcp/tools/fn-impact.js +15 -0
- package/src/mcp/tools/impact-analysis.js +12 -0
- package/src/mcp/tools/index.js +71 -0
- package/src/mcp/tools/list-functions.js +14 -0
- package/src/mcp/tools/list-repos.js +11 -0
- package/src/mcp/tools/module-map.js +6 -0
- package/src/mcp/tools/node-roles.js +14 -0
- package/src/mcp/tools/path.js +12 -0
- package/src/mcp/tools/query.js +30 -0
- package/src/mcp/tools/semantic-search.js +65 -0
- package/src/mcp/tools/sequence.js +17 -0
- package/src/mcp/tools/structure.js +15 -0
- package/src/mcp/tools/symbol-children.js +14 -0
- package/src/mcp/tools/triage.js +35 -0
- package/src/mcp/tools/where.js +13 -0
- package/src/{commands → presentation}/audit.js +2 -2
- package/src/{commands → presentation}/batch.js +1 -1
- package/src/{commands → presentation}/branch-compare.js +2 -2
- package/src/{commands → presentation}/cfg.js +1 -1
- package/src/{commands → presentation}/check.js +6 -6
- package/src/presentation/colors.js +44 -0
- package/src/{commands → presentation}/communities.js +1 -1
- package/src/{commands → presentation}/complexity.js +1 -1
- package/src/{commands → presentation}/dataflow.js +1 -1
- package/src/presentation/export.js +444 -0
- package/src/{commands → presentation}/flow.js +2 -2
- package/src/{commands → presentation}/manifesto.js +4 -4
- package/src/{commands → presentation}/owners.js +1 -1
- package/src/presentation/queries-cli/exports.js +46 -0
- package/src/presentation/queries-cli/impact.js +198 -0
- package/src/presentation/queries-cli/index.js +5 -0
- package/src/presentation/queries-cli/inspect.js +334 -0
- package/src/presentation/queries-cli/overview.js +197 -0
- package/src/presentation/queries-cli/path.js +58 -0
- package/src/presentation/queries-cli.js +27 -0
- package/src/{commands → presentation}/query.js +1 -1
- package/src/presentation/result-formatter.js +144 -0
- package/src/presentation/sequence-renderer.js +43 -0
- package/src/{commands → presentation}/sequence.js +2 -2
- package/src/{commands → presentation}/structure.js +2 -2
- package/src/presentation/table.js +47 -0
- package/src/{commands → presentation}/triage.js +1 -1
- package/src/{viewer.js → presentation/viewer.js} +68 -382
- package/src/{constants.js → shared/constants.js} +1 -1
- package/src/shared/errors.js +78 -0
- package/src/shared/file-utils.js +153 -0
- package/src/shared/generators.js +125 -0
- package/src/shared/hierarchy.js +27 -0
- package/src/shared/normalize.js +59 -0
- package/src/builder.js +0 -1486
- package/src/cycles.js +0 -137
- package/src/embedder.js +0 -1097
- package/src/export.js +0 -681
- package/src/queries-cli.js +0 -866
- package/src/queries.js +0 -2289
- /package/src/{config.js → infrastructure/config.js} +0 -0
- /package/src/{logger.js → infrastructure/logger.js} +0 -0
- /package/src/{registry.js → infrastructure/registry.js} +0 -0
- /package/src/{update-check.js → infrastructure/update-check.js} +0 -0
- /package/src/{commands → presentation}/cochange.js +0 -0
- /package/src/{kinds.js → shared/kinds.js} +0 -0
- /package/src/{paginate.js → shared/paginate.js} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { findDbPath, openReadonlyOrFail } from '../db/index.js';
|
|
5
|
+
import { bfsTransitiveCallers } from '../domain/analysis/impact.js';
|
|
6
|
+
import { findCycles } from '../domain/graph/cycles.js';
|
|
7
|
+
import { loadConfig } from '../infrastructure/config.js';
|
|
8
|
+
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
8
9
|
import { matchOwners, parseCodeowners } from './owners.js';
|
|
9
10
|
|
|
10
11
|
// ─── Diff Parser ──────────────────────────────────────────────────────
|
|
@@ -96,31 +97,10 @@ export function checkMaxBlastRadius(db, changedRanges, threshold, noTests, maxDe
|
|
|
96
97
|
}
|
|
97
98
|
if (!overlaps) continue;
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
for (let d = 1; d <= maxDepth; d++) {
|
|
104
|
-
const nextFrontier = [];
|
|
105
|
-
for (const fid of frontier) {
|
|
106
|
-
const callers = db
|
|
107
|
-
.prepare(
|
|
108
|
-
`SELECT DISTINCT n.id, n.name, n.kind, n.file, n.line
|
|
109
|
-
FROM edges e JOIN nodes n ON e.source_id = n.id
|
|
110
|
-
WHERE e.target_id = ? AND e.kind = 'calls'`,
|
|
111
|
-
)
|
|
112
|
-
.all(fid);
|
|
113
|
-
for (const c of callers) {
|
|
114
|
-
if (!visited.has(c.id) && (!noTests || !isTestFile(c.file))) {
|
|
115
|
-
visited.add(c.id);
|
|
116
|
-
nextFrontier.push(c.id);
|
|
117
|
-
totalCallers++;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
frontier = nextFrontier;
|
|
122
|
-
if (frontier.length === 0) break;
|
|
123
|
-
}
|
|
100
|
+
const { totalDependents: totalCallers } = bfsTransitiveCallers(db, def.id, {
|
|
101
|
+
noTests,
|
|
102
|
+
maxDepth,
|
|
103
|
+
});
|
|
124
104
|
|
|
125
105
|
if (totalCallers > maxFound) maxFound = totalCallers;
|
|
126
106
|
if (totalCallers > threshold) {
|
|
@@ -240,7 +220,10 @@ export function checkData(customDbPath, opts = {}) {
|
|
|
240
220
|
const maxDepth = opts.depth || 3;
|
|
241
221
|
|
|
242
222
|
// Load config defaults for check predicates
|
|
243
|
-
|
|
223
|
+
// NOTE: opts.config is loaded from process.cwd() at startup (via CLI context),
|
|
224
|
+
// which may differ from the DB's parent repo root when --db points to an external
|
|
225
|
+
// project. This is an acceptable trade-off to avoid duplicate I/O on the hot path.
|
|
226
|
+
const config = opts.config || loadConfig(repoRoot);
|
|
244
227
|
const checkConfig = config.check || {};
|
|
245
228
|
|
|
246
229
|
// Resolve which predicates are enabled: CLI flags ?? config ?? built-in defaults
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
import { execFileSync } from 'node:child_process';
|
|
9
9
|
import fs from 'node:fs';
|
|
10
10
|
import path from 'node:path';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { isTestFile } from '
|
|
14
|
-
import {
|
|
15
|
-
import { paginateResult } from '
|
|
11
|
+
import { closeDb, findDbPath, initSchema, openDb, openReadonlyOrFail } from '../db/index.js';
|
|
12
|
+
import { warn } from '../infrastructure/logger.js';
|
|
13
|
+
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
14
|
+
import { normalizePath } from '../shared/constants.js';
|
|
15
|
+
import { paginateResult } from '../shared/paginate.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Scan git history and return parsed commit data.
|
|
@@ -1,78 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
getCallEdges,
|
|
7
|
-
getFileNodesAll,
|
|
8
|
-
getImportEdges,
|
|
9
|
-
openReadonlyOrFail,
|
|
10
|
-
} from './db.js';
|
|
11
|
-
import { isTestFile } from './infrastructure/test-filter.js';
|
|
12
|
-
import { paginateResult } from './paginate.js';
|
|
13
|
-
|
|
14
|
-
// ─── Graph Construction ───────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Build a graphology graph from the codegraph SQLite database.
|
|
18
|
-
*
|
|
19
|
-
* @param {object} db - open better-sqlite3 database (readonly)
|
|
20
|
-
* @param {object} opts
|
|
21
|
-
* @param {boolean} [opts.functions] - Function-level instead of file-level
|
|
22
|
-
* @param {boolean} [opts.noTests] - Exclude test files
|
|
23
|
-
* @returns {Graph}
|
|
24
|
-
*/
|
|
25
|
-
function buildGraphologyGraph(db, opts = {}) {
|
|
26
|
-
const graph = new Graph({ type: 'undirected' });
|
|
27
|
-
|
|
28
|
-
if (opts.functions) {
|
|
29
|
-
// Function-level: nodes = function/method/class symbols, edges = calls
|
|
30
|
-
let nodes = getCallableNodes(db);
|
|
31
|
-
if (opts.noTests) nodes = nodes.filter((n) => !isTestFile(n.file));
|
|
32
|
-
|
|
33
|
-
const nodeIds = new Set();
|
|
34
|
-
for (const n of nodes) {
|
|
35
|
-
const key = String(n.id);
|
|
36
|
-
graph.addNode(key, { label: n.name, file: n.file, kind: n.kind });
|
|
37
|
-
nodeIds.add(n.id);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const edges = getCallEdges(db);
|
|
41
|
-
for (const e of edges) {
|
|
42
|
-
if (!nodeIds.has(e.source_id) || !nodeIds.has(e.target_id)) continue;
|
|
43
|
-
const src = String(e.source_id);
|
|
44
|
-
const tgt = String(e.target_id);
|
|
45
|
-
if (src === tgt) continue;
|
|
46
|
-
if (!graph.hasEdge(src, tgt)) {
|
|
47
|
-
graph.addEdge(src, tgt);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
} else {
|
|
51
|
-
// File-level: nodes = files, edges = imports + imports-type (deduplicated, cross-file)
|
|
52
|
-
let nodes = getFileNodesAll(db);
|
|
53
|
-
if (opts.noTests) nodes = nodes.filter((n) => !isTestFile(n.file));
|
|
54
|
-
|
|
55
|
-
const nodeIds = new Set();
|
|
56
|
-
for (const n of nodes) {
|
|
57
|
-
const key = String(n.id);
|
|
58
|
-
graph.addNode(key, { label: n.file, file: n.file });
|
|
59
|
-
nodeIds.add(n.id);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const edges = getImportEdges(db);
|
|
63
|
-
for (const e of edges) {
|
|
64
|
-
if (!nodeIds.has(e.source_id) || !nodeIds.has(e.target_id)) continue;
|
|
65
|
-
const src = String(e.source_id);
|
|
66
|
-
const tgt = String(e.target_id);
|
|
67
|
-
if (src === tgt) continue;
|
|
68
|
-
if (!graph.hasEdge(src, tgt)) {
|
|
69
|
-
graph.addEdge(src, tgt);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return graph;
|
|
75
|
-
}
|
|
2
|
+
import { openRepo } from '../db/index.js';
|
|
3
|
+
import { louvainCommunities } from '../graph/algorithms/louvain.js';
|
|
4
|
+
import { buildDependencyGraph } from '../graph/builders/dependency.js';
|
|
5
|
+
import { paginateResult } from '../shared/paginate.js';
|
|
76
6
|
|
|
77
7
|
// ─── Directory Helpers ────────────────────────────────────────────────
|
|
78
8
|
|
|
@@ -96,40 +26,39 @@ function getDirectory(filePath) {
|
|
|
96
26
|
* @returns {{ communities: object[], modularity: number, drift: object, summary: object }}
|
|
97
27
|
*/
|
|
98
28
|
export function communitiesData(customDbPath, opts = {}) {
|
|
99
|
-
const
|
|
100
|
-
const resolution = opts.resolution ?? 1.0;
|
|
29
|
+
const { repo, close } = openRepo(customDbPath, opts);
|
|
101
30
|
let graph;
|
|
102
31
|
try {
|
|
103
|
-
graph =
|
|
104
|
-
|
|
32
|
+
graph = buildDependencyGraph(repo, {
|
|
33
|
+
fileLevel: !opts.functions,
|
|
105
34
|
noTests: opts.noTests,
|
|
106
35
|
});
|
|
107
36
|
} finally {
|
|
108
|
-
|
|
37
|
+
close();
|
|
109
38
|
}
|
|
110
39
|
|
|
111
40
|
// Handle empty or trivial graphs
|
|
112
|
-
if (graph.
|
|
41
|
+
if (graph.nodeCount === 0 || graph.edgeCount === 0) {
|
|
113
42
|
return {
|
|
114
43
|
communities: [],
|
|
115
44
|
modularity: 0,
|
|
116
45
|
drift: { splitCandidates: [], mergeCandidates: [] },
|
|
117
|
-
summary: { communityCount: 0, modularity: 0, nodeCount: graph.
|
|
46
|
+
summary: { communityCount: 0, modularity: 0, nodeCount: graph.nodeCount, driftScore: 0 },
|
|
118
47
|
};
|
|
119
48
|
}
|
|
120
49
|
|
|
121
50
|
// Run Louvain
|
|
122
|
-
const
|
|
123
|
-
const assignments
|
|
124
|
-
const modularity = details.modularity;
|
|
51
|
+
const resolution = opts.resolution ?? 1.0;
|
|
52
|
+
const { assignments, modularity } = louvainCommunities(graph, { resolution });
|
|
125
53
|
|
|
126
54
|
// Group nodes by community
|
|
127
55
|
const communityMap = new Map(); // community id → node keys[]
|
|
128
|
-
graph.
|
|
129
|
-
const cid = assignments
|
|
56
|
+
for (const [key] of graph.nodes()) {
|
|
57
|
+
const cid = assignments.get(key);
|
|
58
|
+
if (cid == null) continue;
|
|
130
59
|
if (!communityMap.has(cid)) communityMap.set(cid, []);
|
|
131
60
|
communityMap.get(cid).push(key);
|
|
132
|
-
}
|
|
61
|
+
}
|
|
133
62
|
|
|
134
63
|
// Build community objects
|
|
135
64
|
const communities = [];
|
|
@@ -139,7 +68,7 @@ export function communitiesData(customDbPath, opts = {}) {
|
|
|
139
68
|
const dirCounts = {};
|
|
140
69
|
const memberData = [];
|
|
141
70
|
for (const key of members) {
|
|
142
|
-
const attrs = graph.
|
|
71
|
+
const attrs = graph.getNodeAttrs(key);
|
|
143
72
|
const dir = getDirectory(attrs.file);
|
|
144
73
|
dirCounts[dir] = (dirCounts[dir] || 0) + 1;
|
|
145
74
|
memberData.push({
|
|
@@ -196,7 +125,6 @@ export function communitiesData(customDbPath, opts = {}) {
|
|
|
196
125
|
mergeCandidates.sort((a, b) => b.directoryCount - a.directoryCount);
|
|
197
126
|
|
|
198
127
|
// Drift score: 0-100 based on how much directory structure diverges from communities
|
|
199
|
-
// Higher = more drift (directories don't match communities)
|
|
200
128
|
const totalDirs = dirToCommunities.size;
|
|
201
129
|
const splitDirs = splitCandidates.length;
|
|
202
130
|
const splitRatio = totalDirs > 0 ? splitDirs / totalDirs : 0;
|
|
@@ -214,7 +142,7 @@ export function communitiesData(customDbPath, opts = {}) {
|
|
|
214
142
|
summary: {
|
|
215
143
|
communityCount: communities.length,
|
|
216
144
|
modularity: +modularity.toFixed(4),
|
|
217
|
-
nodeCount: graph.
|
|
145
|
+
nodeCount: graph.nodeCount,
|
|
218
146
|
driftScore,
|
|
219
147
|
},
|
|
220
148
|
};
|
|
@@ -3,20 +3,20 @@ import path from 'node:path';
|
|
|
3
3
|
import {
|
|
4
4
|
computeLOCMetrics as _computeLOCMetrics,
|
|
5
5
|
computeMaintainabilityIndex as _computeMaintainabilityIndex,
|
|
6
|
-
} from '
|
|
7
|
-
import { COMPLEXITY_RULES, HALSTEAD_RULES } from '
|
|
6
|
+
} from '../ast-analysis/metrics.js';
|
|
7
|
+
import { COMPLEXITY_RULES, HALSTEAD_RULES } from '../ast-analysis/rules/index.js';
|
|
8
8
|
import {
|
|
9
9
|
findFunctionNode as _findFunctionNode,
|
|
10
10
|
buildExtensionSet,
|
|
11
11
|
buildExtToLangMap,
|
|
12
|
-
} from '
|
|
13
|
-
import { walkWithVisitors } from '
|
|
14
|
-
import { createComplexityVisitor } from '
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { paginateResult } from '
|
|
12
|
+
} from '../ast-analysis/shared.js';
|
|
13
|
+
import { walkWithVisitors } from '../ast-analysis/visitor.js';
|
|
14
|
+
import { createComplexityVisitor } from '../ast-analysis/visitors/complexity-visitor.js';
|
|
15
|
+
import { getFunctionNodeId, openReadonlyOrFail } from '../db/index.js';
|
|
16
|
+
import { loadConfig } from '../infrastructure/config.js';
|
|
17
|
+
import { info } from '../infrastructure/logger.js';
|
|
18
|
+
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
19
|
+
import { paginateResult } from '../shared/paginate.js';
|
|
20
20
|
|
|
21
21
|
// Re-export rules for backward compatibility
|
|
22
22
|
export { COMPLEXITY_RULES, HALSTEAD_RULES };
|
|
@@ -360,12 +360,12 @@ export async function buildComplexityMetrics(db, fileSymbols, rootDir, _engineOp
|
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
if (needsFallback) {
|
|
363
|
-
const { createParsers } = await import('
|
|
363
|
+
const { createParsers } = await import('../domain/parser.js');
|
|
364
364
|
parsers = await createParsers();
|
|
365
365
|
extToLang = buildExtToLangMap();
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
const { getParser } = await import('
|
|
368
|
+
const { getParser } = await import('../domain/parser.js');
|
|
369
369
|
|
|
370
370
|
const upsert = db.prepare(
|
|
371
371
|
`INSERT OR REPLACE INTO function_complexity
|
|
@@ -524,7 +524,7 @@ export function complexityData(customDbPath, opts = {}) {
|
|
|
524
524
|
const kindFilter = opts.kind || null;
|
|
525
525
|
|
|
526
526
|
// Load thresholds from config
|
|
527
|
-
const config = loadConfig(process.cwd());
|
|
527
|
+
const config = opts.config || loadConfig(process.cwd());
|
|
528
528
|
const thresholds = config.manifesto?.rules || {
|
|
529
529
|
cognitive: { warn: 15, fail: null },
|
|
530
530
|
cyclomatic: { warn: 10, fail: null },
|
|
@@ -11,23 +11,22 @@
|
|
|
11
11
|
|
|
12
12
|
import fs from 'node:fs';
|
|
13
13
|
import path from 'node:path';
|
|
14
|
-
import { DATAFLOW_RULES } from '
|
|
14
|
+
import { DATAFLOW_RULES } from '../ast-analysis/rules/index.js';
|
|
15
15
|
import {
|
|
16
16
|
makeDataflowRules as _makeDataflowRules,
|
|
17
17
|
buildExtensionSet,
|
|
18
18
|
buildExtToLangMap,
|
|
19
|
-
} from '
|
|
20
|
-
import { walkWithVisitors } from '
|
|
21
|
-
import { createDataflowVisitor } from '
|
|
22
|
-
import { hasDataflowTable, openReadonlyOrFail } from '
|
|
23
|
-
import {
|
|
24
|
-
import { info } from '
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
19
|
+
} from '../ast-analysis/shared.js';
|
|
20
|
+
import { walkWithVisitors } from '../ast-analysis/visitor.js';
|
|
21
|
+
import { createDataflowVisitor } from '../ast-analysis/visitors/dataflow-visitor.js';
|
|
22
|
+
import { hasDataflowTable, openReadonlyOrFail } from '../db/index.js';
|
|
23
|
+
import { ALL_SYMBOL_KINDS, normalizeSymbol } from '../domain/queries.js';
|
|
24
|
+
import { info } from '../infrastructure/logger.js';
|
|
25
|
+
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
26
|
+
import { paginateResult } from '../shared/paginate.js';
|
|
27
27
|
|
|
28
28
|
// Re-export for backward compatibility
|
|
29
|
-
export { DATAFLOW_RULES };
|
|
30
|
-
export { _makeDataflowRules as makeDataflowRules };
|
|
29
|
+
export { _makeDataflowRules as makeDataflowRules, DATAFLOW_RULES };
|
|
31
30
|
|
|
32
31
|
export const DATAFLOW_EXTENSIONS = buildExtensionSet(DATAFLOW_RULES);
|
|
33
32
|
|
|
@@ -89,13 +88,13 @@ export async function buildDataflowEdges(db, fileSymbols, rootDir, _engineOpts)
|
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
if (needsFallback) {
|
|
92
|
-
const { createParsers } = await import('
|
|
91
|
+
const { createParsers } = await import('../domain/parser.js');
|
|
93
92
|
parsers = await createParsers();
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
let getParserFn = null;
|
|
97
96
|
if (parsers) {
|
|
98
|
-
const mod = await import('
|
|
97
|
+
const mod = await import('../domain/parser.js');
|
|
99
98
|
getParserFn = mod.getParser;
|
|
100
99
|
}
|
|
101
100
|
|