@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.
- package/README.md +19 -21
- package/package.json +10 -7
- package/src/analysis/context.js +408 -0
- package/src/analysis/dependencies.js +341 -0
- package/src/analysis/exports.js +130 -0
- package/src/analysis/impact.js +463 -0
- package/src/analysis/module-map.js +322 -0
- package/src/analysis/roles.js +45 -0
- package/src/analysis/symbol-lookup.js +232 -0
- package/src/ast-analysis/shared.js +5 -4
- package/src/batch.js +2 -1
- package/src/builder/context.js +85 -0
- package/src/builder/helpers.js +218 -0
- package/src/builder/incremental.js +178 -0
- package/src/builder/pipeline.js +130 -0
- package/src/builder/stages/build-edges.js +297 -0
- package/src/builder/stages/build-structure.js +113 -0
- package/src/builder/stages/collect-files.js +44 -0
- package/src/builder/stages/detect-changes.js +413 -0
- package/src/builder/stages/finalize.js +139 -0
- package/src/builder/stages/insert-nodes.js +195 -0
- package/src/builder/stages/parse-files.js +28 -0
- package/src/builder/stages/resolve-imports.js +143 -0
- package/src/builder/stages/run-analyses.js +44 -0
- package/src/builder.js +10 -1472
- package/src/cfg.js +1 -2
- package/src/cli/commands/ast.js +26 -0
- package/src/cli/commands/audit.js +46 -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 +30 -0
- package/src/cli/commands/check.js +79 -0
- package/src/cli/commands/children.js +31 -0
- package/src/cli/commands/co-change.js +65 -0
- package/src/cli/commands/communities.js +23 -0
- package/src/cli/commands/complexity.js +45 -0
- package/src/cli/commands/context.js +34 -0
- package/src/cli/commands/cycles.js +28 -0
- package/src/cli/commands/dataflow.js +32 -0
- package/src/cli/commands/deps.js +16 -0
- package/src/cli/commands/diff-impact.js +30 -0
- package/src/cli/commands/embed.js +30 -0
- package/src/cli/commands/export.js +75 -0
- package/src/cli/commands/exports.js +18 -0
- package/src/cli/commands/flow.js +36 -0
- package/src/cli/commands/fn-impact.js +30 -0
- package/src/cli/commands/impact.js +16 -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 +80 -0
- package/src/cli/commands/query.js +49 -0
- package/src/cli/commands/registry.js +100 -0
- package/src/cli/commands/roles.js +34 -0
- package/src/cli/commands/search.js +42 -0
- package/src/cli/commands/sequence.js +32 -0
- package/src/cli/commands/snapshot.js +61 -0
- package/src/cli/commands/stats.js +15 -0
- package/src/cli/commands/structure.js +32 -0
- package/src/cli/commands/triage.js +78 -0
- package/src/cli/commands/watch.js +12 -0
- package/src/cli/commands/where.js +24 -0
- package/src/cli/index.js +118 -0
- package/src/cli/shared/options.js +39 -0
- package/src/cli/shared/output.js +1 -0
- package/src/cli.js +11 -1514
- package/src/commands/check.js +5 -5
- package/src/commands/manifesto.js +3 -3
- package/src/commands/structure.js +1 -1
- package/src/communities.js +15 -87
- package/src/complexity.js +1 -1
- package/src/cycles.js +30 -85
- package/src/dataflow.js +1 -2
- package/src/db/connection.js +4 -4
- package/src/db/migrations.js +41 -0
- package/src/db/query-builder.js +6 -5
- package/src/db/repository/base.js +201 -0
- package/src/db/repository/cached-stmt.js +19 -0
- package/src/db/repository/cfg.js +27 -38
- package/src/db/repository/cochange.js +16 -3
- package/src/db/repository/complexity.js +11 -6
- package/src/db/repository/dataflow.js +6 -1
- package/src/db/repository/edges.js +120 -98
- package/src/db/repository/embeddings.js +14 -3
- package/src/db/repository/graph-read.js +32 -9
- package/src/db/repository/in-memory-repository.js +584 -0
- package/src/db/repository/index.js +6 -1
- package/src/db/repository/nodes.js +110 -40
- package/src/db/repository/sqlite-repository.js +219 -0
- package/src/db.js +5 -0
- package/src/embeddings/generator.js +163 -0
- package/src/embeddings/index.js +13 -0
- package/src/embeddings/models.js +218 -0
- package/src/embeddings/search/cli-formatter.js +151 -0
- package/src/embeddings/search/filters.js +46 -0
- package/src/embeddings/search/hybrid.js +121 -0
- package/src/embeddings/search/keyword.js +68 -0
- package/src/embeddings/search/prepare.js +66 -0
- package/src/embeddings/search/semantic.js +145 -0
- package/src/embeddings/stores/fts5.js +27 -0
- package/src/embeddings/stores/sqlite-blob.js +24 -0
- package/src/embeddings/strategies/source.js +14 -0
- package/src/embeddings/strategies/structured.js +43 -0
- package/src/embeddings/strategies/text-utils.js +43 -0
- package/src/errors.js +78 -0
- package/src/export.js +217 -520
- 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 +38 -1
- package/src/extractors/php.js +3 -1
- package/src/extractors/python.js +14 -3
- package/src/extractors/rust.js +3 -1
- 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 +91 -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.js +33 -204
- 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/tool-registry.js +801 -0
- 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 +10 -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/mcp.js +2 -1470
- package/src/native.js +34 -10
- package/src/parser.js +53 -2
- package/src/presentation/colors.js +44 -0
- package/src/presentation/export.js +444 -0
- package/src/presentation/result-formatter.js +21 -0
- package/src/presentation/sequence-renderer.js +43 -0
- package/src/presentation/table.js +47 -0
- package/src/presentation/viewer.js +634 -0
- package/src/queries.js +35 -2276
- package/src/resolve.js +1 -1
- package/src/sequence.js +2 -38
- 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/snapshot.js +6 -5
- package/src/structure.js +15 -40
- package/src/triage.js +20 -72
- package/src/viewer.js +35 -656
- package/src/watcher.js +8 -148
- 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 {
|
|
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
|
|
9
|
-
import { createParseTreeCache, getActiveEngine
|
|
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
|
-
|
|
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
|
|
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;
|