@optave/codegraph 3.1.2 → 3.1.4

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 (194) hide show
  1. package/README.md +19 -21
  2. package/package.json +10 -7
  3. package/src/analysis/context.js +408 -0
  4. package/src/analysis/dependencies.js +341 -0
  5. package/src/analysis/exports.js +130 -0
  6. package/src/analysis/impact.js +463 -0
  7. package/src/analysis/module-map.js +322 -0
  8. package/src/analysis/roles.js +45 -0
  9. package/src/analysis/symbol-lookup.js +232 -0
  10. package/src/ast-analysis/shared.js +5 -4
  11. package/src/batch.js +2 -1
  12. package/src/builder/context.js +85 -0
  13. package/src/builder/helpers.js +218 -0
  14. package/src/builder/incremental.js +178 -0
  15. package/src/builder/pipeline.js +130 -0
  16. package/src/builder/stages/build-edges.js +297 -0
  17. package/src/builder/stages/build-structure.js +113 -0
  18. package/src/builder/stages/collect-files.js +44 -0
  19. package/src/builder/stages/detect-changes.js +413 -0
  20. package/src/builder/stages/finalize.js +139 -0
  21. package/src/builder/stages/insert-nodes.js +195 -0
  22. package/src/builder/stages/parse-files.js +28 -0
  23. package/src/builder/stages/resolve-imports.js +143 -0
  24. package/src/builder/stages/run-analyses.js +44 -0
  25. package/src/builder.js +10 -1472
  26. package/src/cfg.js +1 -2
  27. package/src/cli/commands/ast.js +26 -0
  28. package/src/cli/commands/audit.js +46 -0
  29. package/src/cli/commands/batch.js +68 -0
  30. package/src/cli/commands/branch-compare.js +21 -0
  31. package/src/cli/commands/build.js +26 -0
  32. package/src/cli/commands/cfg.js +30 -0
  33. package/src/cli/commands/check.js +79 -0
  34. package/src/cli/commands/children.js +31 -0
  35. package/src/cli/commands/co-change.js +65 -0
  36. package/src/cli/commands/communities.js +23 -0
  37. package/src/cli/commands/complexity.js +45 -0
  38. package/src/cli/commands/context.js +34 -0
  39. package/src/cli/commands/cycles.js +28 -0
  40. package/src/cli/commands/dataflow.js +32 -0
  41. package/src/cli/commands/deps.js +16 -0
  42. package/src/cli/commands/diff-impact.js +30 -0
  43. package/src/cli/commands/embed.js +30 -0
  44. package/src/cli/commands/export.js +75 -0
  45. package/src/cli/commands/exports.js +18 -0
  46. package/src/cli/commands/flow.js +36 -0
  47. package/src/cli/commands/fn-impact.js +30 -0
  48. package/src/cli/commands/impact.js +16 -0
  49. package/src/cli/commands/info.js +76 -0
  50. package/src/cli/commands/map.js +19 -0
  51. package/src/cli/commands/mcp.js +18 -0
  52. package/src/cli/commands/models.js +19 -0
  53. package/src/cli/commands/owners.js +25 -0
  54. package/src/cli/commands/path.js +36 -0
  55. package/src/cli/commands/plot.js +80 -0
  56. package/src/cli/commands/query.js +49 -0
  57. package/src/cli/commands/registry.js +100 -0
  58. package/src/cli/commands/roles.js +34 -0
  59. package/src/cli/commands/search.js +42 -0
  60. package/src/cli/commands/sequence.js +32 -0
  61. package/src/cli/commands/snapshot.js +61 -0
  62. package/src/cli/commands/stats.js +15 -0
  63. package/src/cli/commands/structure.js +32 -0
  64. package/src/cli/commands/triage.js +78 -0
  65. package/src/cli/commands/watch.js +12 -0
  66. package/src/cli/commands/where.js +24 -0
  67. package/src/cli/index.js +118 -0
  68. package/src/cli/shared/options.js +39 -0
  69. package/src/cli/shared/output.js +1 -0
  70. package/src/cli.js +11 -1514
  71. package/src/commands/check.js +5 -5
  72. package/src/commands/manifesto.js +3 -3
  73. package/src/commands/structure.js +1 -1
  74. package/src/communities.js +15 -87
  75. package/src/complexity.js +1 -1
  76. package/src/cycles.js +30 -85
  77. package/src/dataflow.js +1 -2
  78. package/src/db/connection.js +4 -4
  79. package/src/db/migrations.js +41 -0
  80. package/src/db/query-builder.js +6 -5
  81. package/src/db/repository/base.js +201 -0
  82. package/src/db/repository/cached-stmt.js +19 -0
  83. package/src/db/repository/cfg.js +27 -38
  84. package/src/db/repository/cochange.js +16 -3
  85. package/src/db/repository/complexity.js +11 -6
  86. package/src/db/repository/dataflow.js +6 -1
  87. package/src/db/repository/edges.js +120 -98
  88. package/src/db/repository/embeddings.js +14 -3
  89. package/src/db/repository/graph-read.js +32 -9
  90. package/src/db/repository/in-memory-repository.js +584 -0
  91. package/src/db/repository/index.js +6 -1
  92. package/src/db/repository/nodes.js +110 -40
  93. package/src/db/repository/sqlite-repository.js +219 -0
  94. package/src/db.js +5 -0
  95. package/src/embeddings/generator.js +163 -0
  96. package/src/embeddings/index.js +13 -0
  97. package/src/embeddings/models.js +218 -0
  98. package/src/embeddings/search/cli-formatter.js +151 -0
  99. package/src/embeddings/search/filters.js +46 -0
  100. package/src/embeddings/search/hybrid.js +121 -0
  101. package/src/embeddings/search/keyword.js +68 -0
  102. package/src/embeddings/search/prepare.js +66 -0
  103. package/src/embeddings/search/semantic.js +145 -0
  104. package/src/embeddings/stores/fts5.js +27 -0
  105. package/src/embeddings/stores/sqlite-blob.js +24 -0
  106. package/src/embeddings/strategies/source.js +14 -0
  107. package/src/embeddings/strategies/structured.js +43 -0
  108. package/src/embeddings/strategies/text-utils.js +43 -0
  109. package/src/errors.js +78 -0
  110. package/src/export.js +217 -520
  111. package/src/extractors/csharp.js +10 -2
  112. package/src/extractors/go.js +3 -1
  113. package/src/extractors/helpers.js +71 -0
  114. package/src/extractors/java.js +9 -2
  115. package/src/extractors/javascript.js +38 -1
  116. package/src/extractors/php.js +3 -1
  117. package/src/extractors/python.js +14 -3
  118. package/src/extractors/rust.js +3 -1
  119. package/src/graph/algorithms/bfs.js +49 -0
  120. package/src/graph/algorithms/centrality.js +16 -0
  121. package/src/graph/algorithms/index.js +5 -0
  122. package/src/graph/algorithms/louvain.js +26 -0
  123. package/src/graph/algorithms/shortest-path.js +41 -0
  124. package/src/graph/algorithms/tarjan.js +49 -0
  125. package/src/graph/builders/dependency.js +91 -0
  126. package/src/graph/builders/index.js +3 -0
  127. package/src/graph/builders/structure.js +40 -0
  128. package/src/graph/builders/temporal.js +33 -0
  129. package/src/graph/classifiers/index.js +2 -0
  130. package/src/graph/classifiers/risk.js +85 -0
  131. package/src/graph/classifiers/roles.js +64 -0
  132. package/src/graph/index.js +13 -0
  133. package/src/graph/model.js +230 -0
  134. package/src/index.js +33 -204
  135. package/src/infrastructure/result-formatter.js +2 -21
  136. package/src/mcp/index.js +2 -0
  137. package/src/mcp/middleware.js +26 -0
  138. package/src/mcp/server.js +128 -0
  139. package/src/mcp/tool-registry.js +801 -0
  140. package/src/mcp/tools/ast-query.js +14 -0
  141. package/src/mcp/tools/audit.js +21 -0
  142. package/src/mcp/tools/batch-query.js +11 -0
  143. package/src/mcp/tools/branch-compare.js +10 -0
  144. package/src/mcp/tools/cfg.js +21 -0
  145. package/src/mcp/tools/check.js +43 -0
  146. package/src/mcp/tools/co-changes.js +20 -0
  147. package/src/mcp/tools/code-owners.js +12 -0
  148. package/src/mcp/tools/communities.js +15 -0
  149. package/src/mcp/tools/complexity.js +18 -0
  150. package/src/mcp/tools/context.js +17 -0
  151. package/src/mcp/tools/dataflow.js +26 -0
  152. package/src/mcp/tools/diff-impact.js +24 -0
  153. package/src/mcp/tools/execution-flow.js +26 -0
  154. package/src/mcp/tools/export-graph.js +57 -0
  155. package/src/mcp/tools/file-deps.js +12 -0
  156. package/src/mcp/tools/file-exports.js +13 -0
  157. package/src/mcp/tools/find-cycles.js +15 -0
  158. package/src/mcp/tools/fn-impact.js +15 -0
  159. package/src/mcp/tools/impact-analysis.js +12 -0
  160. package/src/mcp/tools/index.js +71 -0
  161. package/src/mcp/tools/list-functions.js +14 -0
  162. package/src/mcp/tools/list-repos.js +11 -0
  163. package/src/mcp/tools/module-map.js +6 -0
  164. package/src/mcp/tools/node-roles.js +14 -0
  165. package/src/mcp/tools/path.js +12 -0
  166. package/src/mcp/tools/query.js +30 -0
  167. package/src/mcp/tools/semantic-search.js +65 -0
  168. package/src/mcp/tools/sequence.js +17 -0
  169. package/src/mcp/tools/structure.js +15 -0
  170. package/src/mcp/tools/symbol-children.js +14 -0
  171. package/src/mcp/tools/triage.js +35 -0
  172. package/src/mcp/tools/where.js +13 -0
  173. package/src/mcp.js +2 -1470
  174. package/src/native.js +34 -10
  175. package/src/parser.js +53 -2
  176. package/src/presentation/colors.js +44 -0
  177. package/src/presentation/export.js +444 -0
  178. package/src/presentation/result-formatter.js +21 -0
  179. package/src/presentation/sequence-renderer.js +43 -0
  180. package/src/presentation/table.js +47 -0
  181. package/src/presentation/viewer.js +634 -0
  182. package/src/queries.js +35 -2276
  183. package/src/resolve.js +1 -1
  184. package/src/sequence.js +2 -38
  185. package/src/shared/file-utils.js +153 -0
  186. package/src/shared/generators.js +125 -0
  187. package/src/shared/hierarchy.js +27 -0
  188. package/src/shared/normalize.js +59 -0
  189. package/src/snapshot.js +6 -5
  190. package/src/structure.js +15 -40
  191. package/src/triage.js +20 -72
  192. package/src/viewer.js +35 -656
  193. package/src/watcher.js +8 -148
  194. package/src/embedder.js +0 -1097
package/src/watcher.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { readFileSafe } from './builder.js';
3
+ import { rebuildFile } from './builder/incremental.js';
4
4
  import { appendChangeEvents, buildChangeEvent, diffSymbols } from './change-journal.js';
5
5
  import { EXTENSIONS, IGNORE_DIRS, normalizePath } from './constants.js';
6
6
  import { closeDb, getNodeId as getNodeIdQuery, initSchema, openDb } from './db.js';
7
+ import { DbError } from './errors.js';
7
8
  import { appendJournalEntries } from './journal.js';
8
- import { info, warn } from './logger.js';
9
- import { createParseTreeCache, getActiveEngine, parseFileIncremental } from './parser.js';
10
- import { resolveImportPath } from './resolve.js';
9
+ import { info } from './logger.js';
10
+ import { createParseTreeCache, getActiveEngine } from './parser.js';
11
11
 
12
12
  function shouldIgnore(filePath) {
13
13
  const parts = filePath.split(path.sep);
@@ -18,152 +18,10 @@ function isTrackedExt(filePath) {
18
18
  return EXTENSIONS.has(path.extname(filePath));
19
19
  }
20
20
 
21
- /**
22
- * Parse a single file and update the database incrementally.
23
- */
24
- async function updateFile(_db, rootDir, filePath, stmts, engineOpts, cache) {
25
- const relPath = normalizePath(path.relative(rootDir, filePath));
26
-
27
- const oldNodes = stmts.countNodes.get(relPath)?.c || 0;
28
- const _oldEdges = stmts.countEdgesForFile.get(relPath)?.c || 0;
29
- const oldSymbols = stmts.listSymbols.all(relPath);
30
-
31
- stmts.deleteEdgesForFile.run(relPath);
32
- stmts.deleteNodes.run(relPath);
33
-
34
- if (!fs.existsSync(filePath)) {
35
- if (cache) cache.remove(filePath);
36
- const symbolDiff = diffSymbols(oldSymbols, []);
37
- return {
38
- file: relPath,
39
- nodesAdded: 0,
40
- nodesRemoved: oldNodes,
41
- edgesAdded: 0,
42
- deleted: true,
43
- event: 'deleted',
44
- symbolDiff,
45
- nodesBefore: oldNodes,
46
- nodesAfter: 0,
47
- };
48
- }
49
-
50
- let code;
51
- try {
52
- code = readFileSafe(filePath);
53
- } catch (err) {
54
- warn(`Cannot read ${relPath}: ${err.message}`);
55
- return null;
56
- }
57
-
58
- const symbols = await parseFileIncremental(cache, filePath, code, engineOpts);
59
- if (!symbols) return null;
60
-
61
- stmts.insertNode.run(relPath, 'file', relPath, 0, null);
62
-
63
- for (const def of symbols.definitions) {
64
- stmts.insertNode.run(def.name, def.kind, relPath, def.line, def.endLine || null);
65
- }
66
- for (const exp of symbols.exports) {
67
- stmts.insertNode.run(exp.name, exp.kind, relPath, exp.line, null);
68
- }
69
-
70
- const newNodes = stmts.countNodes.get(relPath)?.c || 0;
71
- const newSymbols = stmts.listSymbols.all(relPath);
72
-
73
- let edgesAdded = 0;
74
- const fileNodeRow = stmts.getNodeId.get(relPath, 'file', relPath, 0);
75
- if (!fileNodeRow)
76
- return { file: relPath, nodesAdded: newNodes, nodesRemoved: oldNodes, edgesAdded: 0 };
77
- const fileNodeId = fileNodeRow.id;
78
-
79
- // Load aliases for full import resolution
80
- const aliases = { baseUrl: null, paths: {} };
81
-
82
- for (const imp of symbols.imports) {
83
- const resolvedPath = resolveImportPath(
84
- path.join(rootDir, relPath),
85
- imp.source,
86
- rootDir,
87
- aliases,
88
- );
89
- const targetRow = stmts.getNodeId.get(resolvedPath, 'file', resolvedPath, 0);
90
- if (targetRow) {
91
- const edgeKind = imp.reexport ? 'reexports' : imp.typeOnly ? 'imports-type' : 'imports';
92
- stmts.insertEdge.run(fileNodeId, targetRow.id, edgeKind, 1.0, 0);
93
- edgesAdded++;
94
- }
95
- }
96
-
97
- const importedNames = new Map();
98
- for (const imp of symbols.imports) {
99
- const resolvedPath = resolveImportPath(
100
- path.join(rootDir, relPath),
101
- imp.source,
102
- rootDir,
103
- aliases,
104
- );
105
- for (const name of imp.names) {
106
- importedNames.set(name.replace(/^\*\s+as\s+/, ''), resolvedPath);
107
- }
108
- }
109
-
110
- for (const call of symbols.calls) {
111
- let caller = null;
112
- for (const def of symbols.definitions) {
113
- if (def.line <= call.line) {
114
- const row = stmts.getNodeId.get(def.name, def.kind, relPath, def.line);
115
- if (row) caller = row;
116
- }
117
- }
118
- if (!caller) caller = fileNodeRow;
119
-
120
- const importedFrom = importedNames.get(call.name);
121
- let targets;
122
- if (importedFrom) {
123
- targets = stmts.findNodeInFile.all(call.name, importedFrom);
124
- }
125
- if (!targets || targets.length === 0) {
126
- targets = stmts.findNodeInFile.all(call.name, relPath);
127
- if (targets.length === 0) {
128
- targets = stmts.findNodeByName.all(call.name);
129
- }
130
- }
131
-
132
- for (const t of targets) {
133
- if (t.id !== caller.id) {
134
- stmts.insertEdge.run(
135
- caller.id,
136
- t.id,
137
- 'calls',
138
- importedFrom ? 1.0 : 0.5,
139
- call.dynamic ? 1 : 0,
140
- );
141
- edgesAdded++;
142
- }
143
- }
144
- }
145
-
146
- const symbolDiff = diffSymbols(oldSymbols, newSymbols);
147
- const event = oldNodes === 0 ? 'added' : 'modified';
148
-
149
- return {
150
- file: relPath,
151
- nodesAdded: newNodes,
152
- nodesRemoved: oldNodes,
153
- edgesAdded,
154
- deleted: false,
155
- event,
156
- symbolDiff,
157
- nodesBefore: oldNodes,
158
- nodesAfter: newNodes,
159
- };
160
- }
161
-
162
21
  export async function watchProject(rootDir, opts = {}) {
163
22
  const dbPath = path.join(rootDir, '.codegraph', 'graph.db');
164
23
  if (!fs.existsSync(dbPath)) {
165
- console.error('No graph.db found. Run `codegraph build` first.');
166
- process.exit(1);
24
+ throw new DbError('No graph.db found. Run `codegraph build` first.', { file: dbPath });
167
25
  }
168
26
 
169
27
  const db = openDb(dbPath);
@@ -227,7 +85,9 @@ export async function watchProject(rootDir, opts = {}) {
227
85
 
228
86
  const results = [];
229
87
  for (const filePath of files) {
230
- const result = await updateFile(db, rootDir, filePath, stmts, engineOpts, cache);
88
+ const result = await rebuildFile(db, rootDir, filePath, stmts, engineOpts, cache, {
89
+ diffSymbols,
90
+ });
231
91
  if (result) results.push(result);
232
92
  }
233
93
  const updates = results;