@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
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified in-memory graph model.
|
|
3
|
+
*
|
|
4
|
+
* Stores directed (default) or undirected graphs with node/edge attributes.
|
|
5
|
+
* Node IDs are always strings. DB integer IDs should be stringified before use.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import Graph from 'graphology';
|
|
9
|
+
|
|
10
|
+
export class CodeGraph {
|
|
11
|
+
/**
|
|
12
|
+
* @param {{ directed?: boolean }} [opts]
|
|
13
|
+
*/
|
|
14
|
+
constructor(opts = {}) {
|
|
15
|
+
this._directed = opts.directed !== false;
|
|
16
|
+
/** @type {Map<string, object>} */
|
|
17
|
+
this._nodes = new Map();
|
|
18
|
+
/** @type {Map<string, Map<string, object>>} node → (target → edgeAttrs) */
|
|
19
|
+
this._successors = new Map();
|
|
20
|
+
/** @type {Map<string, Map<string, object>>} node → (source → edgeAttrs) */
|
|
21
|
+
this._predecessors = new Map();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get directed() {
|
|
25
|
+
return this._directed;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get nodeCount() {
|
|
29
|
+
return this._nodes.size;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get edgeCount() {
|
|
33
|
+
let count = 0;
|
|
34
|
+
for (const targets of this._successors.values()) count += targets.size;
|
|
35
|
+
// Undirected graphs store each edge twice (a→b and b→a)
|
|
36
|
+
return this._directed ? count : count / 2;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ─── Node operations ────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
addNode(id, attrs = {}) {
|
|
42
|
+
const key = String(id);
|
|
43
|
+
this._nodes.set(key, attrs);
|
|
44
|
+
if (!this._successors.has(key)) this._successors.set(key, new Map());
|
|
45
|
+
if (!this._predecessors.has(key)) this._predecessors.set(key, new Map());
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
hasNode(id) {
|
|
50
|
+
return this._nodes.has(String(id));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getNodeAttrs(id) {
|
|
54
|
+
return this._nodes.get(String(id));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** @returns {IterableIterator<[string, object]>} */
|
|
58
|
+
nodes() {
|
|
59
|
+
return this._nodes.entries();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @returns {string[]} */
|
|
63
|
+
nodeIds() {
|
|
64
|
+
return [...this._nodes.keys()];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ─── Edge operations ────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
addEdge(source, target, attrs = {}) {
|
|
70
|
+
const src = String(source);
|
|
71
|
+
const tgt = String(target);
|
|
72
|
+
// Auto-add nodes if missing
|
|
73
|
+
if (!this._nodes.has(src)) this.addNode(src);
|
|
74
|
+
if (!this._nodes.has(tgt)) this.addNode(tgt);
|
|
75
|
+
|
|
76
|
+
this._successors.get(src).set(tgt, attrs);
|
|
77
|
+
this._predecessors.get(tgt).set(src, attrs);
|
|
78
|
+
|
|
79
|
+
if (!this._directed) {
|
|
80
|
+
this._successors.get(tgt).set(src, attrs);
|
|
81
|
+
this._predecessors.get(src).set(tgt, attrs);
|
|
82
|
+
}
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
hasEdge(source, target) {
|
|
87
|
+
const src = String(source);
|
|
88
|
+
const tgt = String(target);
|
|
89
|
+
return this._successors.has(src) && this._successors.get(src).has(tgt);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getEdgeAttrs(source, target) {
|
|
93
|
+
const src = String(source);
|
|
94
|
+
const tgt = String(target);
|
|
95
|
+
return this._successors.get(src)?.get(tgt);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** @yields {[string, string, object]} source, target, attrs */
|
|
99
|
+
*edges() {
|
|
100
|
+
const seen = this._directed ? null : new Set();
|
|
101
|
+
for (const [src, targets] of this._successors) {
|
|
102
|
+
for (const [tgt, attrs] of targets) {
|
|
103
|
+
if (!this._directed) {
|
|
104
|
+
// \0 is safe as separator — node IDs are file paths/symbols, never contain null bytes
|
|
105
|
+
const key = src < tgt ? `${src}\0${tgt}` : `${tgt}\0${src}`;
|
|
106
|
+
if (seen.has(key)) continue;
|
|
107
|
+
seen.add(key);
|
|
108
|
+
}
|
|
109
|
+
yield [src, tgt, attrs];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ─── Adjacency ──────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
/** Direct successors of a node (outgoing edges). */
|
|
117
|
+
successors(id) {
|
|
118
|
+
const key = String(id);
|
|
119
|
+
const map = this._successors.get(key);
|
|
120
|
+
return map ? [...map.keys()] : [];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Direct predecessors of a node (incoming edges). */
|
|
124
|
+
predecessors(id) {
|
|
125
|
+
const key = String(id);
|
|
126
|
+
const map = this._predecessors.get(key);
|
|
127
|
+
return map ? [...map.keys()] : [];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** All neighbors (union of successors + predecessors). */
|
|
131
|
+
neighbors(id) {
|
|
132
|
+
const key = String(id);
|
|
133
|
+
const set = new Set();
|
|
134
|
+
const succ = this._successors.get(key);
|
|
135
|
+
if (succ) for (const k of succ.keys()) set.add(k);
|
|
136
|
+
const pred = this._predecessors.get(key);
|
|
137
|
+
if (pred) for (const k of pred.keys()) set.add(k);
|
|
138
|
+
return [...set];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
outDegree(id) {
|
|
142
|
+
const map = this._successors.get(String(id));
|
|
143
|
+
return map ? map.size : 0;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
inDegree(id) {
|
|
147
|
+
const map = this._predecessors.get(String(id));
|
|
148
|
+
return map ? map.size : 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ─── Filtering ──────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
/** Return a new graph containing only nodes matching the predicate. */
|
|
154
|
+
subgraph(predicate) {
|
|
155
|
+
const g = new CodeGraph({ directed: this._directed });
|
|
156
|
+
for (const [id, attrs] of this._nodes) {
|
|
157
|
+
if (predicate(id, attrs)) g.addNode(id, { ...attrs });
|
|
158
|
+
}
|
|
159
|
+
for (const [src, tgt, attrs] of this.edges()) {
|
|
160
|
+
if (g.hasNode(src) && g.hasNode(tgt)) {
|
|
161
|
+
g.addEdge(src, tgt, { ...attrs });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return g;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Return a new graph containing only edges matching the predicate. */
|
|
168
|
+
filterEdges(predicate) {
|
|
169
|
+
const g = new CodeGraph({ directed: this._directed });
|
|
170
|
+
for (const [id, attrs] of this._nodes) {
|
|
171
|
+
g.addNode(id, { ...attrs });
|
|
172
|
+
}
|
|
173
|
+
for (const [src, tgt, attrs] of this.edges()) {
|
|
174
|
+
if (predicate(src, tgt, attrs)) {
|
|
175
|
+
g.addEdge(src, tgt, { ...attrs });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return g;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ─── Conversion ─────────────────────────────────────────────────
|
|
182
|
+
|
|
183
|
+
/** Convert to flat edge array for native Rust interop. */
|
|
184
|
+
toEdgeArray() {
|
|
185
|
+
const result = [];
|
|
186
|
+
for (const [source, target] of this.edges()) {
|
|
187
|
+
result.push({ source, target });
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Convert to graphology instance (for Louvain etc). */
|
|
193
|
+
toGraphology(opts = {}) {
|
|
194
|
+
const type = opts.type || (this._directed ? 'directed' : 'undirected');
|
|
195
|
+
const g = new Graph({ type });
|
|
196
|
+
for (const [id] of this._nodes) {
|
|
197
|
+
g.addNode(id);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
for (const [src, tgt] of this.edges()) {
|
|
201
|
+
if (src === tgt) continue;
|
|
202
|
+
if (!g.hasEdge(src, tgt)) g.addEdge(src, tgt);
|
|
203
|
+
}
|
|
204
|
+
return g;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ─── Utilities ──────────────────────────────────────────────────
|
|
208
|
+
|
|
209
|
+
clone() {
|
|
210
|
+
const g = new CodeGraph({ directed: this._directed });
|
|
211
|
+
for (const [id, attrs] of this._nodes) {
|
|
212
|
+
g.addNode(id, { ...attrs });
|
|
213
|
+
}
|
|
214
|
+
for (const [src, tgt, attrs] of this.edges()) {
|
|
215
|
+
g.addEdge(src, tgt, { ...attrs });
|
|
216
|
+
}
|
|
217
|
+
return g;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Merge another graph into this one. Nodes/edges from other override on conflict. */
|
|
221
|
+
merge(other) {
|
|
222
|
+
for (const [id, attrs] of other.nodes()) {
|
|
223
|
+
this.addNode(id, attrs);
|
|
224
|
+
}
|
|
225
|
+
for (const [src, tgt, attrs] of other.edges()) {
|
|
226
|
+
this.addEdge(src, tgt, attrs);
|
|
227
|
+
}
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
}
|
package/src/index.cjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CJS compatibility wrapper — delegates to ESM via dynamic import().
|
|
3
|
+
*
|
|
4
|
+
* This wrapper always returns a Promise on every Node version, because
|
|
5
|
+
* import() is unconditionally async. You must always await the result:
|
|
6
|
+
*
|
|
7
|
+
* const codegraph = await require('@optave/codegraph');
|
|
8
|
+
*
|
|
9
|
+
* // Named destructuring at require-time does NOT work — always await the full result first.
|
|
10
|
+
* // BAD: const { buildGraph } = require('@optave/codegraph'); // buildGraph is undefined
|
|
11
|
+
* // GOOD: const { buildGraph } = await require('@optave/codegraph');
|
|
12
|
+
*/
|
|
13
|
+
// Note: if import() rejects (e.g. missing dependency), the rejected Promise is cached
|
|
14
|
+
// by the CJS module system and every subsequent require() call will re-surface the same
|
|
15
|
+
// rejection without re-attempting the load.
|
|
16
|
+
module.exports = import('./index.js');
|
package/src/index.js
CHANGED
|
@@ -1,243 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* codegraph — Programmatic API
|
|
3
3
|
*
|
|
4
|
+
* Curated public surface: *Data() query functions, graph building,
|
|
5
|
+
* export formats, and essential constants. CLI formatters and internal
|
|
6
|
+
* utilities are not exported — import them directly if needed.
|
|
7
|
+
*
|
|
4
8
|
* Usage:
|
|
5
|
-
* import { buildGraph, queryNameData, findCycles, exportDOT } from 'codegraph';
|
|
9
|
+
* import { buildGraph, queryNameData, findCycles, exportDOT } from '@optave/codegraph';
|
|
6
10
|
*/
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
// Audit (composite report)
|
|
11
|
-
export { auditData } from './audit.js';
|
|
12
|
-
// Batch querying
|
|
13
|
-
export {
|
|
14
|
-
BATCH_COMMANDS,
|
|
15
|
-
batchData,
|
|
16
|
-
multiBatchData,
|
|
17
|
-
splitTargets,
|
|
18
|
-
} from './batch.js';
|
|
19
|
-
// Architecture boundary rules
|
|
20
|
-
export { evaluateBoundaries, PRESETS, validateBoundaryConfig } from './boundaries.js';
|
|
21
|
-
// Branch comparison
|
|
22
|
-
export { branchCompareData, branchCompareMermaid } from './branch-compare.js';
|
|
23
|
-
// Graph building
|
|
24
|
-
export { buildGraph, collectFiles, loadPathAliases, resolveImportPath } from './builder.js';
|
|
25
|
-
// Control flow graph (intraprocedural)
|
|
26
|
-
export {
|
|
27
|
-
buildCFGData,
|
|
28
|
-
buildFunctionCFG,
|
|
29
|
-
CFG_RULES,
|
|
30
|
-
cfgData,
|
|
31
|
-
cfgToDOT,
|
|
32
|
-
cfgToMermaid,
|
|
33
|
-
} from './cfg.js';
|
|
34
|
-
// Check (CI validation predicates)
|
|
35
|
-
export { checkData } from './check.js';
|
|
36
|
-
// Co-change analysis
|
|
37
|
-
export {
|
|
38
|
-
analyzeCoChanges,
|
|
39
|
-
coChangeData,
|
|
40
|
-
coChangeForFiles,
|
|
41
|
-
coChangeTopData,
|
|
42
|
-
computeCoChanges,
|
|
43
|
-
scanGitHistory,
|
|
44
|
-
} from './cochange.js';
|
|
45
|
-
export { audit } from './commands/audit.js';
|
|
46
|
-
export { batch, batchQuery } from './commands/batch.js';
|
|
47
|
-
export { cfg } from './commands/cfg.js';
|
|
48
|
-
export { check } from './commands/check.js';
|
|
49
|
-
export { communities } from './commands/communities.js';
|
|
50
|
-
export { complexity } from './commands/complexity.js';
|
|
51
|
-
export { dataflow } from './commands/dataflow.js';
|
|
52
|
-
export { manifesto } from './commands/manifesto.js';
|
|
53
|
-
export { owners } from './commands/owners.js';
|
|
54
|
-
export { sequence } from './commands/sequence.js';
|
|
55
|
-
export { formatHotspots, formatModuleBoundaries, formatStructure } from './commands/structure.js';
|
|
56
|
-
export { triage } from './commands/triage.js';
|
|
57
|
-
// Community detection
|
|
58
|
-
export { communitiesData, communitySummaryForStats } from './communities.js';
|
|
59
|
-
// Complexity metrics
|
|
60
|
-
export {
|
|
61
|
-
COMPLEXITY_RULES,
|
|
62
|
-
complexityData,
|
|
63
|
-
computeFunctionComplexity,
|
|
64
|
-
computeHalsteadMetrics,
|
|
65
|
-
computeLOCMetrics,
|
|
66
|
-
computeMaintainabilityIndex,
|
|
67
|
-
findFunctionNode,
|
|
68
|
-
HALSTEAD_RULES,
|
|
69
|
-
iterComplexity,
|
|
70
|
-
} from './complexity.js';
|
|
71
|
-
// Configuration
|
|
72
|
-
export { loadConfig } from './config.js';
|
|
73
|
-
// Shared constants
|
|
74
|
-
export { EXTENSIONS, IGNORE_DIRS, normalizePath } from './constants.js';
|
|
75
|
-
// Circular dependency detection
|
|
76
|
-
export { findCycles, formatCycles } from './cycles.js';
|
|
77
|
-
// Dataflow analysis
|
|
78
|
-
export {
|
|
79
|
-
buildDataflowEdges,
|
|
80
|
-
dataflowData,
|
|
81
|
-
dataflowImpactData,
|
|
82
|
-
dataflowPathData,
|
|
83
|
-
extractDataflow,
|
|
84
|
-
} from './dataflow.js';
|
|
85
|
-
// Database utilities
|
|
86
|
-
export {
|
|
87
|
-
countEdges,
|
|
88
|
-
countFiles,
|
|
89
|
-
countNodes,
|
|
90
|
-
fanInJoinSQL,
|
|
91
|
-
fanOutJoinSQL,
|
|
92
|
-
findDbPath,
|
|
93
|
-
findNodesForTriage,
|
|
94
|
-
findNodesWithFanIn,
|
|
95
|
-
getBuildMeta,
|
|
96
|
-
initSchema,
|
|
97
|
-
iterateFunctionNodes,
|
|
98
|
-
kindInClause,
|
|
99
|
-
listFunctionNodes,
|
|
100
|
-
NodeQuery,
|
|
101
|
-
openDb,
|
|
102
|
-
openReadonlyOrFail,
|
|
103
|
-
setBuildMeta,
|
|
104
|
-
testFilterSQL,
|
|
105
|
-
} from './db.js';
|
|
106
|
-
// Embeddings
|
|
107
|
-
export {
|
|
108
|
-
buildEmbeddings,
|
|
109
|
-
cosineSim,
|
|
110
|
-
DEFAULT_MODEL,
|
|
111
|
-
disposeModel,
|
|
112
|
-
EMBEDDING_STRATEGIES,
|
|
113
|
-
embed,
|
|
114
|
-
estimateTokens,
|
|
115
|
-
ftsSearchData,
|
|
116
|
-
hybridSearchData,
|
|
117
|
-
MODELS,
|
|
118
|
-
multiSearchData,
|
|
119
|
-
search,
|
|
120
|
-
searchData,
|
|
121
|
-
} from './embedder.js';
|
|
122
|
-
// Export (DOT/Mermaid/JSON/GraphML/GraphSON/Neo4j CSV)
|
|
123
|
-
export {
|
|
124
|
-
exportDOT,
|
|
125
|
-
exportGraphML,
|
|
126
|
-
exportGraphSON,
|
|
127
|
-
exportJSON,
|
|
128
|
-
exportMermaid,
|
|
129
|
-
exportNeo4jCSV,
|
|
130
|
-
} from './export.js';
|
|
131
|
-
// Execution flow tracing
|
|
132
|
-
export { entryPointType, flowData, listEntryPointsData } from './flow.js';
|
|
133
|
-
// Result formatting
|
|
134
|
-
export { outputResult } from './infrastructure/result-formatter.js';
|
|
135
|
-
// Test file detection
|
|
136
|
-
export { isTestFile, TEST_PATTERN } from './infrastructure/test-filter.js';
|
|
137
|
-
// Logger
|
|
138
|
-
export { setVerbose } from './logger.js';
|
|
139
|
-
// Manifesto rule engine
|
|
140
|
-
export { manifestoData, RULE_DEFS } from './manifesto.js';
|
|
141
|
-
// Native engine
|
|
142
|
-
export { isNativeAvailable } from './native.js';
|
|
143
|
-
// Ownership (CODEOWNERS)
|
|
144
|
-
export { matchOwners, ownersData, ownersForFiles, parseCodeowners } from './owners.js';
|
|
145
|
-
// Pagination utilities
|
|
146
|
-
export { MCP_DEFAULTS, MCP_MAX_LIMIT, paginate, paginateResult, printNdjson } from './paginate.js';
|
|
147
|
-
// Unified parser API
|
|
12
|
+
export { buildGraph } from './domain/graph/builder.js';
|
|
13
|
+
export { findCycles } from './domain/graph/cycles.js';
|
|
148
14
|
export {
|
|
149
|
-
disposeParsers,
|
|
150
|
-
getActiveEngine,
|
|
151
|
-
isWasmAvailable,
|
|
152
|
-
parseFileAuto,
|
|
153
|
-
parseFilesAuto,
|
|
154
|
-
} from './parser.js';
|
|
155
|
-
// Query functions (data-returning)
|
|
156
|
-
export {
|
|
157
|
-
ALL_SYMBOL_KINDS,
|
|
158
|
-
CORE_EDGE_KINDS,
|
|
159
|
-
CORE_SYMBOL_KINDS,
|
|
160
15
|
childrenData,
|
|
161
16
|
contextData,
|
|
162
17
|
diffImpactData,
|
|
163
|
-
diffImpactMermaid,
|
|
164
|
-
EVERY_EDGE_KIND,
|
|
165
|
-
EVERY_SYMBOL_KIND,
|
|
166
|
-
EXTENDED_SYMBOL_KINDS,
|
|
167
18
|
explainData,
|
|
168
19
|
exportsData,
|
|
169
|
-
FALSE_POSITIVE_CALLER_THRESHOLD,
|
|
170
|
-
FALSE_POSITIVE_NAMES,
|
|
171
20
|
fileDepsData,
|
|
172
21
|
fnDepsData,
|
|
173
22
|
fnImpactData,
|
|
174
23
|
impactAnalysisData,
|
|
175
|
-
iterListFunctions,
|
|
176
|
-
iterRoles,
|
|
177
|
-
iterWhere,
|
|
178
|
-
kindIcon,
|
|
179
24
|
moduleMapData,
|
|
180
|
-
normalizeSymbol,
|
|
181
25
|
pathData,
|
|
182
26
|
queryNameData,
|
|
183
27
|
rolesData,
|
|
184
|
-
STRUCTURAL_EDGE_KINDS,
|
|
185
28
|
statsData,
|
|
186
|
-
VALID_ROLES,
|
|
187
29
|
whereData,
|
|
188
|
-
} from './queries.js';
|
|
189
|
-
// Query CLI display wrappers
|
|
190
|
-
export {
|
|
191
|
-
children,
|
|
192
|
-
context,
|
|
193
|
-
diffImpact,
|
|
194
|
-
explain,
|
|
195
|
-
fileDeps,
|
|
196
|
-
fileExports,
|
|
197
|
-
fnDeps,
|
|
198
|
-
fnImpact,
|
|
199
|
-
impactAnalysis,
|
|
200
|
-
moduleMap,
|
|
201
|
-
queryName,
|
|
202
|
-
roles,
|
|
203
|
-
stats,
|
|
204
|
-
symbolPath,
|
|
205
|
-
where,
|
|
206
|
-
} from './queries-cli.js';
|
|
207
|
-
// Registry (multi-repo)
|
|
30
|
+
} from './domain/queries.js';
|
|
208
31
|
export {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
} from './
|
|
218
|
-
|
|
219
|
-
export {
|
|
220
|
-
|
|
221
|
-
export {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
} from './
|
|
229
|
-
|
|
32
|
+
buildEmbeddings,
|
|
33
|
+
hybridSearchData,
|
|
34
|
+
multiSearchData,
|
|
35
|
+
searchData,
|
|
36
|
+
} from './domain/search/index.js';
|
|
37
|
+
export { astQueryData } from './features/ast.js';
|
|
38
|
+
export { auditData } from './features/audit.js';
|
|
39
|
+
export { batchData } from './features/batch.js';
|
|
40
|
+
export { branchCompareData } from './features/branch-compare.js';
|
|
41
|
+
export { cfgData } from './features/cfg.js';
|
|
42
|
+
export { checkData } from './features/check.js';
|
|
43
|
+
export { coChangeData } from './features/cochange.js';
|
|
44
|
+
export { communitiesData } from './features/communities.js';
|
|
45
|
+
export { complexityData } from './features/complexity.js';
|
|
46
|
+
export { dataflowData } from './features/dataflow.js';
|
|
47
|
+
export { exportDOT, exportJSON, exportMermaid } from './features/export.js';
|
|
48
|
+
export { flowData, listEntryPointsData } from './features/flow.js';
|
|
49
|
+
export { manifestoData } from './features/manifesto.js';
|
|
50
|
+
export { ownersData } from './features/owners.js';
|
|
51
|
+
export { sequenceData } from './features/sequence.js';
|
|
52
|
+
export { hotspotsData, moduleBoundariesData, structureData } from './features/structure.js';
|
|
53
|
+
export { triageData } from './features/triage.js';
|
|
54
|
+
export { loadConfig } from './infrastructure/config.js';
|
|
55
|
+
export { EXTENSIONS, IGNORE_DIRS } from './shared/constants.js';
|
|
230
56
|
export {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
export { generatePlotHTML, loadPlotConfig } from './viewer.js';
|
|
242
|
-
// Watch mode
|
|
243
|
-
export { watchProject } from './watcher.js';
|
|
57
|
+
AnalysisError,
|
|
58
|
+
BoundaryError,
|
|
59
|
+
CodegraphError,
|
|
60
|
+
ConfigError,
|
|
61
|
+
DbError,
|
|
62
|
+
EngineError,
|
|
63
|
+
ParseError,
|
|
64
|
+
ResolutionError,
|
|
65
|
+
} from './shared/errors.js';
|
|
66
|
+
export { EVERY_EDGE_KIND, EVERY_SYMBOL_KIND } from './shared/kinds.js';
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { createRequire } from 'node:module';
|
|
10
10
|
import os from 'node:os';
|
|
11
|
+
import { EngineError } from '../shared/errors.js';
|
|
11
12
|
|
|
12
13
|
let _cached; // undefined = not yet tried, null = failed, object = module
|
|
13
14
|
let _loadError = null;
|
|
@@ -101,9 +102,10 @@ export function getNativePackageVersion() {
|
|
|
101
102
|
export function getNative() {
|
|
102
103
|
const mod = loadNative();
|
|
103
104
|
if (!mod) {
|
|
104
|
-
throw new
|
|
105
|
+
throw new EngineError(
|
|
105
106
|
`Native codegraph-core not available: ${_loadError?.message || 'unknown error'}. ` +
|
|
106
107
|
'Install the platform package or use --engine wasm.',
|
|
108
|
+
{ cause: _loadError },
|
|
107
109
|
);
|
|
108
110
|
}
|
|
109
111
|
return mod;
|
|
@@ -1,21 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Shared JSON / NDJSON output dispatch for CLI wrappers.
|
|
5
|
-
*
|
|
6
|
-
* @param {object} data - Result object from a *Data() function
|
|
7
|
-
* @param {string} field - Array field name for NDJSON streaming (e.g. 'results')
|
|
8
|
-
* @param {object} opts - CLI options ({ json?, ndjson? })
|
|
9
|
-
* @returns {boolean} true if output was handled (caller should return early)
|
|
10
|
-
*/
|
|
11
|
-
export function outputResult(data, field, opts) {
|
|
12
|
-
if (opts.ndjson) {
|
|
13
|
-
printNdjson(data, field);
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
if (opts.json) {
|
|
17
|
-
console.log(JSON.stringify(data, null, 2));
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
1
|
+
// Re-export from presentation layer — this file exists for backward compatibility.
|
|
2
|
+
export { outputResult } from '../presentation/result-formatter.js';
|
package/src/mcp/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP middleware helpers — pagination defaults and limits.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { MCP_DEFAULTS, MCP_MAX_LIMIT } from '../shared/paginate.js';
|
|
6
|
+
|
|
7
|
+
export { MCP_DEFAULTS, MCP_MAX_LIMIT };
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve effective limit for a tool call.
|
|
11
|
+
* @param {object} args - Tool arguments
|
|
12
|
+
* @param {string} toolName - Tool name (for default lookup)
|
|
13
|
+
* @returns {number}
|
|
14
|
+
*/
|
|
15
|
+
export function effectiveLimit(args, toolName) {
|
|
16
|
+
return Math.min(args.limit ?? MCP_DEFAULTS[toolName] ?? 100, MCP_MAX_LIMIT);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Resolve effective offset for a tool call.
|
|
21
|
+
* @param {object} args - Tool arguments
|
|
22
|
+
* @returns {number}
|
|
23
|
+
*/
|
|
24
|
+
export function effectiveOffset(args) {
|
|
25
|
+
return args.offset ?? 0;
|
|
26
|
+
}
|