@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.
Files changed (232) hide show
  1. package/README.md +38 -84
  2. package/package.json +13 -8
  3. package/src/ast-analysis/engine.js +32 -12
  4. package/src/ast-analysis/shared.js +6 -5
  5. package/src/cli/commands/ast.js +22 -0
  6. package/src/cli/commands/audit.js +45 -0
  7. package/src/cli/commands/batch.js +68 -0
  8. package/src/cli/commands/branch-compare.js +21 -0
  9. package/src/cli/commands/build.js +26 -0
  10. package/src/cli/commands/cfg.js +26 -0
  11. package/src/cli/commands/check.js +74 -0
  12. package/src/cli/commands/children.js +28 -0
  13. package/src/cli/commands/co-change.js +67 -0
  14. package/src/cli/commands/communities.js +19 -0
  15. package/src/cli/commands/complexity.js +46 -0
  16. package/src/cli/commands/context.js +30 -0
  17. package/src/cli/commands/cycles.js +32 -0
  18. package/src/cli/commands/dataflow.js +28 -0
  19. package/src/cli/commands/deps.js +12 -0
  20. package/src/cli/commands/diff-impact.js +26 -0
  21. package/src/cli/commands/embed.js +30 -0
  22. package/src/cli/commands/export.js +78 -0
  23. package/src/cli/commands/exports.js +14 -0
  24. package/src/cli/commands/flow.js +32 -0
  25. package/src/cli/commands/fn-impact.js +26 -0
  26. package/src/cli/commands/impact.js +12 -0
  27. package/src/cli/commands/info.js +76 -0
  28. package/src/cli/commands/map.js +19 -0
  29. package/src/cli/commands/mcp.js +18 -0
  30. package/src/cli/commands/models.js +19 -0
  31. package/src/cli/commands/owners.js +25 -0
  32. package/src/cli/commands/path.js +36 -0
  33. package/src/cli/commands/plot.js +89 -0
  34. package/src/cli/commands/query.js +45 -0
  35. package/src/cli/commands/registry.js +100 -0
  36. package/src/cli/commands/roles.js +30 -0
  37. package/src/cli/commands/search.js +42 -0
  38. package/src/cli/commands/sequence.js +28 -0
  39. package/src/cli/commands/snapshot.js +66 -0
  40. package/src/cli/commands/stats.js +15 -0
  41. package/src/cli/commands/structure.js +33 -0
  42. package/src/cli/commands/triage.js +78 -0
  43. package/src/cli/commands/watch.js +12 -0
  44. package/src/cli/commands/where.js +20 -0
  45. package/src/cli/index.js +124 -0
  46. package/src/cli/shared/open-graph.js +13 -0
  47. package/src/cli/shared/options.js +59 -0
  48. package/src/cli/shared/output.js +1 -0
  49. package/src/cli.js +11 -1522
  50. package/src/db/connection.js +130 -7
  51. package/src/{db.js → db/index.js} +17 -5
  52. package/src/db/migrations.js +42 -1
  53. package/src/db/query-builder.js +20 -12
  54. package/src/db/repository/base.js +201 -0
  55. package/src/db/repository/graph-read.js +7 -4
  56. package/src/db/repository/in-memory-repository.js +575 -0
  57. package/src/db/repository/index.js +5 -1
  58. package/src/db/repository/nodes.js +60 -6
  59. package/src/db/repository/sqlite-repository.js +219 -0
  60. package/src/domain/analysis/context.js +408 -0
  61. package/src/domain/analysis/dependencies.js +341 -0
  62. package/src/domain/analysis/exports.js +134 -0
  63. package/src/domain/analysis/impact.js +466 -0
  64. package/src/domain/analysis/module-map.js +322 -0
  65. package/src/domain/analysis/roles.js +45 -0
  66. package/src/domain/analysis/symbol-lookup.js +238 -0
  67. package/src/domain/graph/builder/context.js +85 -0
  68. package/src/domain/graph/builder/helpers.js +218 -0
  69. package/src/domain/graph/builder/incremental.js +178 -0
  70. package/src/domain/graph/builder/pipeline.js +130 -0
  71. package/src/domain/graph/builder/stages/build-edges.js +297 -0
  72. package/src/domain/graph/builder/stages/build-structure.js +113 -0
  73. package/src/domain/graph/builder/stages/collect-files.js +44 -0
  74. package/src/domain/graph/builder/stages/detect-changes.js +413 -0
  75. package/src/domain/graph/builder/stages/finalize.js +139 -0
  76. package/src/domain/graph/builder/stages/insert-nodes.js +195 -0
  77. package/src/domain/graph/builder/stages/parse-files.js +28 -0
  78. package/src/domain/graph/builder/stages/resolve-imports.js +143 -0
  79. package/src/domain/graph/builder/stages/run-analyses.js +44 -0
  80. package/src/domain/graph/builder.js +11 -0
  81. package/src/{change-journal.js → domain/graph/change-journal.js} +1 -1
  82. package/src/domain/graph/cycles.js +82 -0
  83. package/src/{journal.js → domain/graph/journal.js} +1 -1
  84. package/src/{resolve.js → domain/graph/resolve.js} +3 -3
  85. package/src/{watcher.js → domain/graph/watcher.js} +10 -150
  86. package/src/{parser.js → domain/parser.js} +5 -5
  87. package/src/domain/queries.js +48 -0
  88. package/src/domain/search/generator.js +163 -0
  89. package/src/domain/search/index.js +13 -0
  90. package/src/domain/search/models.js +218 -0
  91. package/src/domain/search/search/cli-formatter.js +151 -0
  92. package/src/domain/search/search/filters.js +46 -0
  93. package/src/domain/search/search/hybrid.js +121 -0
  94. package/src/domain/search/search/keyword.js +68 -0
  95. package/src/domain/search/search/prepare.js +66 -0
  96. package/src/domain/search/search/semantic.js +145 -0
  97. package/src/domain/search/stores/fts5.js +27 -0
  98. package/src/domain/search/stores/sqlite-blob.js +24 -0
  99. package/src/domain/search/strategies/source.js +14 -0
  100. package/src/domain/search/strategies/structured.js +43 -0
  101. package/src/domain/search/strategies/text-utils.js +43 -0
  102. package/src/extractors/csharp.js +10 -2
  103. package/src/extractors/go.js +3 -1
  104. package/src/extractors/helpers.js +71 -0
  105. package/src/extractors/java.js +9 -2
  106. package/src/extractors/javascript.js +39 -2
  107. package/src/extractors/php.js +3 -1
  108. package/src/extractors/python.js +14 -3
  109. package/src/extractors/rust.js +3 -1
  110. package/src/{ast.js → features/ast.js} +8 -8
  111. package/src/{audit.js → features/audit.js} +16 -44
  112. package/src/{batch.js → features/batch.js} +6 -5
  113. package/src/{boundaries.js → features/boundaries.js} +2 -2
  114. package/src/{branch-compare.js → features/branch-compare.js} +3 -3
  115. package/src/{cfg.js → features/cfg.js} +11 -12
  116. package/src/{check.js → features/check.js} +13 -30
  117. package/src/{cochange.js → features/cochange.js} +5 -5
  118. package/src/{communities.js → features/communities.js} +18 -90
  119. package/src/{complexity.js → features/complexity.js} +13 -13
  120. package/src/{dataflow.js → features/dataflow.js} +12 -13
  121. package/src/features/export.js +378 -0
  122. package/src/{flow.js → features/flow.js} +4 -4
  123. package/src/features/graph-enrichment.js +327 -0
  124. package/src/{manifesto.js → features/manifesto.js} +6 -6
  125. package/src/{owners.js → features/owners.js} +2 -2
  126. package/src/{sequence.js → features/sequence.js} +16 -52
  127. package/src/{snapshot.js → features/snapshot.js} +8 -7
  128. package/src/{structure.js → features/structure.js} +20 -45
  129. package/src/{triage.js → features/triage.js} +27 -79
  130. package/src/graph/algorithms/bfs.js +49 -0
  131. package/src/graph/algorithms/centrality.js +16 -0
  132. package/src/graph/algorithms/index.js +5 -0
  133. package/src/graph/algorithms/louvain.js +26 -0
  134. package/src/graph/algorithms/shortest-path.js +41 -0
  135. package/src/graph/algorithms/tarjan.js +49 -0
  136. package/src/graph/builders/dependency.js +110 -0
  137. package/src/graph/builders/index.js +3 -0
  138. package/src/graph/builders/structure.js +40 -0
  139. package/src/graph/builders/temporal.js +33 -0
  140. package/src/graph/classifiers/index.js +2 -0
  141. package/src/graph/classifiers/risk.js +85 -0
  142. package/src/graph/classifiers/roles.js +64 -0
  143. package/src/graph/index.js +13 -0
  144. package/src/graph/model.js +230 -0
  145. package/src/index.cjs +16 -0
  146. package/src/index.js +42 -219
  147. package/src/{native.js → infrastructure/native.js} +3 -1
  148. package/src/infrastructure/result-formatter.js +2 -21
  149. package/src/mcp/index.js +2 -0
  150. package/src/mcp/middleware.js +26 -0
  151. package/src/mcp/server.js +128 -0
  152. package/src/{mcp.js → mcp/tool-registry.js} +6 -675
  153. package/src/mcp/tools/ast-query.js +14 -0
  154. package/src/mcp/tools/audit.js +21 -0
  155. package/src/mcp/tools/batch-query.js +11 -0
  156. package/src/mcp/tools/branch-compare.js +12 -0
  157. package/src/mcp/tools/cfg.js +21 -0
  158. package/src/mcp/tools/check.js +43 -0
  159. package/src/mcp/tools/co-changes.js +20 -0
  160. package/src/mcp/tools/code-owners.js +12 -0
  161. package/src/mcp/tools/communities.js +15 -0
  162. package/src/mcp/tools/complexity.js +18 -0
  163. package/src/mcp/tools/context.js +17 -0
  164. package/src/mcp/tools/dataflow.js +26 -0
  165. package/src/mcp/tools/diff-impact.js +24 -0
  166. package/src/mcp/tools/execution-flow.js +26 -0
  167. package/src/mcp/tools/export-graph.js +57 -0
  168. package/src/mcp/tools/file-deps.js +12 -0
  169. package/src/mcp/tools/file-exports.js +13 -0
  170. package/src/mcp/tools/find-cycles.js +15 -0
  171. package/src/mcp/tools/fn-impact.js +15 -0
  172. package/src/mcp/tools/impact-analysis.js +12 -0
  173. package/src/mcp/tools/index.js +71 -0
  174. package/src/mcp/tools/list-functions.js +14 -0
  175. package/src/mcp/tools/list-repos.js +11 -0
  176. package/src/mcp/tools/module-map.js +6 -0
  177. package/src/mcp/tools/node-roles.js +14 -0
  178. package/src/mcp/tools/path.js +12 -0
  179. package/src/mcp/tools/query.js +30 -0
  180. package/src/mcp/tools/semantic-search.js +65 -0
  181. package/src/mcp/tools/sequence.js +17 -0
  182. package/src/mcp/tools/structure.js +15 -0
  183. package/src/mcp/tools/symbol-children.js +14 -0
  184. package/src/mcp/tools/triage.js +35 -0
  185. package/src/mcp/tools/where.js +13 -0
  186. package/src/{commands → presentation}/audit.js +2 -2
  187. package/src/{commands → presentation}/batch.js +1 -1
  188. package/src/{commands → presentation}/branch-compare.js +2 -2
  189. package/src/{commands → presentation}/cfg.js +1 -1
  190. package/src/{commands → presentation}/check.js +6 -6
  191. package/src/presentation/colors.js +44 -0
  192. package/src/{commands → presentation}/communities.js +1 -1
  193. package/src/{commands → presentation}/complexity.js +1 -1
  194. package/src/{commands → presentation}/dataflow.js +1 -1
  195. package/src/presentation/export.js +444 -0
  196. package/src/{commands → presentation}/flow.js +2 -2
  197. package/src/{commands → presentation}/manifesto.js +4 -4
  198. package/src/{commands → presentation}/owners.js +1 -1
  199. package/src/presentation/queries-cli/exports.js +46 -0
  200. package/src/presentation/queries-cli/impact.js +198 -0
  201. package/src/presentation/queries-cli/index.js +5 -0
  202. package/src/presentation/queries-cli/inspect.js +334 -0
  203. package/src/presentation/queries-cli/overview.js +197 -0
  204. package/src/presentation/queries-cli/path.js +58 -0
  205. package/src/presentation/queries-cli.js +27 -0
  206. package/src/{commands → presentation}/query.js +1 -1
  207. package/src/presentation/result-formatter.js +144 -0
  208. package/src/presentation/sequence-renderer.js +43 -0
  209. package/src/{commands → presentation}/sequence.js +2 -2
  210. package/src/{commands → presentation}/structure.js +2 -2
  211. package/src/presentation/table.js +47 -0
  212. package/src/{commands → presentation}/triage.js +1 -1
  213. package/src/{viewer.js → presentation/viewer.js} +68 -382
  214. package/src/{constants.js → shared/constants.js} +1 -1
  215. package/src/shared/errors.js +78 -0
  216. package/src/shared/file-utils.js +153 -0
  217. package/src/shared/generators.js +125 -0
  218. package/src/shared/hierarchy.js +27 -0
  219. package/src/shared/normalize.js +59 -0
  220. package/src/builder.js +0 -1486
  221. package/src/cycles.js +0 -137
  222. package/src/embedder.js +0 -1097
  223. package/src/export.js +0 -681
  224. package/src/queries-cli.js +0 -866
  225. package/src/queries.js +0 -2289
  226. /package/src/{config.js → infrastructure/config.js} +0 -0
  227. /package/src/{logger.js → infrastructure/logger.js} +0 -0
  228. /package/src/{registry.js → infrastructure/registry.js} +0 -0
  229. /package/src/{update-check.js → infrastructure/update-check.js} +0 -0
  230. /package/src/{commands → presentation}/cochange.js +0 -0
  231. /package/src/{kinds.js → shared/kinds.js} +0 -0
  232. /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
- // AST node queries
9
- export { AST_NODE_KINDS, astQuery, astQueryData } from './ast.js';
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
- listRepos,
210
- loadRegistry,
211
- pruneRegistry,
212
- REGISTRY_PATH,
213
- registerRepo,
214
- resolveRepoDbPath,
215
- saveRegistry,
216
- unregisterRepo,
217
- } from './registry.js';
218
- // Sequence diagram generation
219
- export { sequenceData, sequenceToMermaid } from './sequence.js';
220
- // Snapshot management
221
- export {
222
- snapshotDelete,
223
- snapshotList,
224
- snapshotRestore,
225
- snapshotSave,
226
- snapshotsDir,
227
- validateSnapshotName,
228
- } from './snapshot.js';
229
- // Structure analysis
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
- buildStructure,
232
- classifyNodeRoles,
233
- FRAMEWORK_ENTRY_PREFIXES,
234
- hotspotsData,
235
- moduleBoundariesData,
236
- structureData,
237
- } from './structure.js';
238
- // Triage — composite risk audit
239
- export { triageData } from './triage.js';
240
- // Interactive HTML viewer
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 Error(
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
- import { printNdjson } from '../paginate.js';
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';
@@ -0,0 +1,2 @@
1
+ export { startMCPServer } from './server.js';
2
+ export { buildToolList, TOOLS } from './tool-registry.js';
@@ -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
+ }