repo-codegraph 0.0.0-stage → 0.1.0
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 +405 -2
- package/dist/analyzer/analyzeProject.d.ts +17 -0
- package/dist/analyzer/analyzeProject.d.ts.map +1 -0
- package/dist/analyzer/analyzeProject.js +338 -0
- package/dist/analyzer/analyzeProject.js.map +1 -0
- package/dist/analyzer/buildDefinitionGraph.d.ts +47 -0
- package/dist/analyzer/buildDefinitionGraph.d.ts.map +1 -0
- package/dist/analyzer/buildDefinitionGraph.js +60 -0
- package/dist/analyzer/buildDefinitionGraph.js.map +1 -0
- package/dist/analyzer/incrementalIndex.d.ts +21 -0
- package/dist/analyzer/incrementalIndex.d.ts.map +1 -0
- package/dist/analyzer/incrementalIndex.js +115 -0
- package/dist/analyzer/incrementalIndex.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +221 -0
- package/dist/cli.js.map +1 -0
- package/dist/files/discoverSourceFiles.d.ts +8 -0
- package/dist/files/discoverSourceFiles.d.ts.map +1 -0
- package/dist/files/discoverSourceFiles.js +46 -0
- package/dist/files/discoverSourceFiles.js.map +1 -0
- package/dist/git/diffImpact.d.ts +22 -0
- package/dist/git/diffImpact.d.ts.map +1 -0
- package/dist/git/diffImpact.js +113 -0
- package/dist/git/diffImpact.js.map +1 -0
- package/dist/graph/DirectedGraph.d.ts +44 -0
- package/dist/graph/DirectedGraph.d.ts.map +1 -0
- package/dist/graph/DirectedGraph.js +258 -0
- package/dist/graph/DirectedGraph.js.map +1 -0
- package/dist/graph/types.d.ts +13 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +2 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/projectSession.d.ts +18 -0
- package/dist/mcp/projectSession.d.ts.map +1 -0
- package/dist/mcp/projectSession.js +86 -0
- package/dist/mcp/projectSession.js.map +1 -0
- package/dist/mcp/server.d.ts +23 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +512 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +3 -0
- package/dist/mcp/stdio.d.ts.map +1 -0
- package/dist/mcp/stdio.js +35 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/parser/extractDeclarations.d.ts +30 -0
- package/dist/parser/extractDeclarations.d.ts.map +1 -0
- package/dist/parser/extractDeclarations.js +83 -0
- package/dist/parser/extractDeclarations.js.map +1 -0
- package/dist/parser/parseSourceFile.d.ts +4 -0
- package/dist/parser/parseSourceFile.d.ts.map +1 -0
- package/dist/parser/parseSourceFile.js +9 -0
- package/dist/parser/parseSourceFile.js.map +1 -0
- package/dist/persistence/jsonPersistence.d.ts +7 -0
- package/dist/persistence/jsonPersistence.d.ts.map +1 -0
- package/dist/persistence/jsonPersistence.js +98 -0
- package/dist/persistence/jsonPersistence.js.map +1 -0
- package/dist/queries/analyzeImpact.d.ts +14 -0
- package/dist/queries/analyzeImpact.d.ts.map +1 -0
- package/dist/queries/analyzeImpact.js +56 -0
- package/dist/queries/analyzeImpact.js.map +1 -0
- package/dist/queries/codeGraphQueries.d.ts +7 -0
- package/dist/queries/codeGraphQueries.d.ts.map +1 -0
- package/dist/queries/codeGraphQueries.js +86 -0
- package/dist/queries/codeGraphQueries.js.map +1 -0
- package/package.json +44 -3
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
/**
|
|
3
|
+
* Extracts a deliberately small set of named declarations from one AST.
|
|
4
|
+
*
|
|
5
|
+
* This is syntax extraction, not symbol resolution: two declarations with the
|
|
6
|
+
* same name are still separate syntax nodes and are not linked semantically.
|
|
7
|
+
*/
|
|
8
|
+
export function extractDeclarations(sourceFile) {
|
|
9
|
+
const declarations = [];
|
|
10
|
+
function addDeclaration(kind, name, qualifiedName, parentQualifiedName, declarationNode, nameNode) {
|
|
11
|
+
const position = sourceFile.getLineAndCharacterOfPosition(nameNode.getStart(sourceFile));
|
|
12
|
+
const rangeStart = sourceFile.getLineAndCharacterOfPosition(declarationNode.getStart(sourceFile));
|
|
13
|
+
const rangeEnd = sourceFile.getLineAndCharacterOfPosition(declarationNode.getEnd());
|
|
14
|
+
declarations.push({
|
|
15
|
+
kind,
|
|
16
|
+
name,
|
|
17
|
+
qualifiedName,
|
|
18
|
+
parentQualifiedName,
|
|
19
|
+
location: {
|
|
20
|
+
file: sourceFile.fileName,
|
|
21
|
+
line: position.line + 1,
|
|
22
|
+
column: position.character + 1,
|
|
23
|
+
},
|
|
24
|
+
range: {
|
|
25
|
+
file: sourceFile.fileName,
|
|
26
|
+
startLine: rangeStart.line + 1,
|
|
27
|
+
startColumn: rangeStart.character + 1,
|
|
28
|
+
endLine: rangeEnd.line + 1,
|
|
29
|
+
endColumn: rangeEnd.character + 1,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function qualifyName(parentQualifiedName, name) {
|
|
34
|
+
if (parentQualifiedName === null) {
|
|
35
|
+
return name;
|
|
36
|
+
}
|
|
37
|
+
return `${parentQualifiedName}.${name}`;
|
|
38
|
+
}
|
|
39
|
+
function visit(node, parentQualifiedName) {
|
|
40
|
+
if (ts.isFunctionDeclaration(node) && node.name !== undefined) {
|
|
41
|
+
const name = node.name.text;
|
|
42
|
+
const qualifiedName = qualifyName(parentQualifiedName, name);
|
|
43
|
+
addDeclaration("function", name, qualifiedName, parentQualifiedName, node, node.name);
|
|
44
|
+
ts.forEachChild(node, (child) => visit(child, qualifiedName));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (ts.isClassDeclaration(node)) {
|
|
48
|
+
if (node.name === undefined) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const name = node.name.text;
|
|
52
|
+
const qualifiedName = qualifyName(parentQualifiedName, name);
|
|
53
|
+
addDeclaration("class", name, qualifiedName, parentQualifiedName, node, node.name);
|
|
54
|
+
for (const member of node.members) {
|
|
55
|
+
visit(member, qualifiedName);
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (ts.isInterfaceDeclaration(node)) {
|
|
60
|
+
const name = node.name.text;
|
|
61
|
+
const qualifiedName = qualifyName(parentQualifiedName, name);
|
|
62
|
+
addDeclaration("interface", name, qualifiedName, parentQualifiedName, node, node.name);
|
|
63
|
+
for (const member of node.members) {
|
|
64
|
+
visit(member, qualifiedName);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const isClassMethod = ts.isMethodDeclaration(node) && ts.isClassDeclaration(node.parent);
|
|
69
|
+
const isInterfaceMethod = ts.isMethodSignature(node) && ts.isInterfaceDeclaration(node.parent);
|
|
70
|
+
if (parentQualifiedName !== null &&
|
|
71
|
+
(isClassMethod || isInterfaceMethod)) {
|
|
72
|
+
const name = node.name.getText(sourceFile);
|
|
73
|
+
const qualifiedName = qualifyName(parentQualifiedName, name);
|
|
74
|
+
addDeclaration("method", name, qualifiedName, parentQualifiedName, node, node.name);
|
|
75
|
+
ts.forEachChild(node, (child) => visit(child, qualifiedName));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
ts.forEachChild(node, (child) => visit(child, parentQualifiedName));
|
|
79
|
+
}
|
|
80
|
+
visit(sourceFile, null);
|
|
81
|
+
return declarations;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=extractDeclarations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractDeclarations.js","sourceRoot":"","sources":["../../src/parser/extractDeclarations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseSourceFile.d.ts","sourceRoot":"","sources":["../../src/parser/parseSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,kEAAkE;AAClE,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,EAAE,CAAC,UAAU,CAYf"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
/** Parses TypeScript or TSX source text into a TypeScript AST. */
|
|
3
|
+
export function parseSourceFile(fileName, sourceText) {
|
|
4
|
+
const scriptKind = fileName.endsWith(".tsx")
|
|
5
|
+
? ts.ScriptKind.TSX
|
|
6
|
+
: ts.ScriptKind.TS;
|
|
7
|
+
return ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true, scriptKind);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=parseSourceFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseSourceFile.js","sourceRoot":"","sources":["../../src/parser/parseSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,kEAAkE;AAClE,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,UAAkB;IAElB,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1C,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;QACnB,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IAErB,OAAO,EAAE,CAAC,gBAAgB,CACxB,QAAQ,EACR,UAAU,EACV,EAAE,CAAC,YAAY,CAAC,MAAM,EACtB,IAAI,EACJ,UAAU,CACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProjectAnalysis } from "../analyzer/analyzeProject.js";
|
|
2
|
+
export declare const CODEGRAPH_JSON_SCHEMA_VERSION = 2;
|
|
3
|
+
export declare function serializeProjectAnalysis(analysis: ProjectAnalysis): string;
|
|
4
|
+
export declare function deserializeProjectAnalysis(serialized: string): ProjectAnalysis;
|
|
5
|
+
export declare function saveProjectAnalysis(analysis: ProjectAnalysis, outputPath: string): Promise<void>;
|
|
6
|
+
export declare function loadProjectAnalysis(inputPath: string): Promise<ProjectAnalysis>;
|
|
7
|
+
//# sourceMappingURL=jsonPersistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/jsonPersistence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAa/C,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAa1E;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CA8B9E;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAE1B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { DirectedGraph } from "../graph/DirectedGraph.js";
|
|
4
|
+
export const CODEGRAPH_JSON_SCHEMA_VERSION = 2;
|
|
5
|
+
export function serializeProjectAnalysis(analysis) {
|
|
6
|
+
const document = {
|
|
7
|
+
format: "codegraph",
|
|
8
|
+
schemaVersion: CODEGRAPH_JSON_SCHEMA_VERSION,
|
|
9
|
+
generatedAt: new Date().toISOString(),
|
|
10
|
+
rootDirectory: analysis.rootDirectory,
|
|
11
|
+
nodes: analysis.graph.getNodes(),
|
|
12
|
+
edges: analysis.graph.getEdges(),
|
|
13
|
+
diagnostics: analysis.diagnostics,
|
|
14
|
+
fileHashes: analysis.fileHashes,
|
|
15
|
+
};
|
|
16
|
+
return `${JSON.stringify(document, null, 2)}\n`;
|
|
17
|
+
}
|
|
18
|
+
export function deserializeProjectAnalysis(serialized) {
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(serialized);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
throw new Error(`Invalid Codegraph JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
25
|
+
}
|
|
26
|
+
assertPersistedDocument(parsed);
|
|
27
|
+
const graph = new DirectedGraph();
|
|
28
|
+
for (const node of parsed.nodes) {
|
|
29
|
+
graph.addNode(node);
|
|
30
|
+
}
|
|
31
|
+
for (const edge of parsed.edges) {
|
|
32
|
+
graph.addEdge(edge);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
rootDirectory: parsed.rootDirectory,
|
|
36
|
+
graph,
|
|
37
|
+
diagnostics: parsed.diagnostics,
|
|
38
|
+
fileHashes: parsed.fileHashes,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export async function saveProjectAnalysis(analysis, outputPath) {
|
|
42
|
+
const absoluteOutputPath = path.resolve(outputPath);
|
|
43
|
+
await mkdir(path.dirname(absoluteOutputPath), { recursive: true });
|
|
44
|
+
const temporaryPath = `${absoluteOutputPath}.${process.pid}.${Date.now()}.tmp`;
|
|
45
|
+
try {
|
|
46
|
+
await writeFile(temporaryPath, serializeProjectAnalysis(analysis), "utf8");
|
|
47
|
+
await rename(temporaryPath, absoluteOutputPath);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
await rm(temporaryPath, { force: true });
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function loadProjectAnalysis(inputPath) {
|
|
55
|
+
return deserializeProjectAnalysis(await readFile(inputPath, "utf8"));
|
|
56
|
+
}
|
|
57
|
+
function assertPersistedDocument(value) {
|
|
58
|
+
if (!isRecord(value) || value.format !== "codegraph") {
|
|
59
|
+
throw new Error("Invalid Codegraph index: expected format 'codegraph'");
|
|
60
|
+
}
|
|
61
|
+
if (value.schemaVersion !== CODEGRAPH_JSON_SCHEMA_VERSION) {
|
|
62
|
+
throw new Error(`Unsupported Codegraph schema version: ${String(value.schemaVersion)}`);
|
|
63
|
+
}
|
|
64
|
+
if (typeof value.rootDirectory !== "string") {
|
|
65
|
+
throw new Error("Invalid Codegraph index: rootDirectory must be a string");
|
|
66
|
+
}
|
|
67
|
+
if (!Array.isArray(value.nodes) || !value.nodes.every(isPersistedNode)) {
|
|
68
|
+
throw new Error("Invalid Codegraph index: nodes must contain valid graph nodes");
|
|
69
|
+
}
|
|
70
|
+
if (!Array.isArray(value.edges) || !value.edges.every(isPersistedEdge)) {
|
|
71
|
+
throw new Error("Invalid Codegraph index: edges must contain valid graph edges");
|
|
72
|
+
}
|
|
73
|
+
if (!Array.isArray(value.diagnostics)) {
|
|
74
|
+
throw new Error("Invalid Codegraph index: diagnostics must be an array");
|
|
75
|
+
}
|
|
76
|
+
if (!isStringRecord(value.fileHashes)) {
|
|
77
|
+
throw new Error("Invalid Codegraph index: fileHashes must map paths to hashes");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function isPersistedNode(value) {
|
|
81
|
+
if (!isRecord(value) || typeof value.id !== "string" || !isRecord(value.data)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return value.data.nodeType === "file" || value.data.nodeType === "symbol";
|
|
85
|
+
}
|
|
86
|
+
function isPersistedEdge(value) {
|
|
87
|
+
return isRecord(value) &&
|
|
88
|
+
typeof value.from === "string" &&
|
|
89
|
+
typeof value.to === "string" &&
|
|
90
|
+
(value.type === "DEFINES" || value.type === "IMPORTS" || value.type === "CALLS");
|
|
91
|
+
}
|
|
92
|
+
function isRecord(value) {
|
|
93
|
+
return typeof value === "object" && value !== null;
|
|
94
|
+
}
|
|
95
|
+
function isStringRecord(value) {
|
|
96
|
+
return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=jsonPersistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonPersistence.js","sourceRoot":"","sources":["../../src/persistence/jsonPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAa/C,MAAM,UAAU,wBAAwB,CAAC,QAAyB;IAChE,MAAM,QAAQ,GAA6B;QACzC,MAAM,EAAE,WAAW;QACnB,aAAa,EAAE,6BAA6B;QAC5C,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;QAChC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;QAChC,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;KAChC,CAAC;IAEF,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,UAAkB;IAC3D,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACpF,CAAC;IACJ,CAAC;IAED,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,aAAa,EAI5B,CAAC;IAEJ,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,KAAK;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAyB,EACzB,UAAkB;IAElB,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,GAAG,kBAAkB,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;IAE/E,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,aAAa,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3E,MAAM,MAAM,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,EAAE,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB;IAEjB,OAAO,0BAA0B,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAc;IAEd,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,KAAK,6BAA6B,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,yCAAyC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CACvE,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC5E,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,QAAQ,CAAC,KAAK,CAAC;QACpB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAClD,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CACrC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GraphNode } from "../graph/types.js";
|
|
2
|
+
import type { CodeGraph, CodeGraphEdgeType, CodeGraphNodeData } from "../analyzer/buildDefinitionGraph.js";
|
|
3
|
+
export interface ImpactOptions {
|
|
4
|
+
readonly maxDepth?: number;
|
|
5
|
+
readonly relationships?: readonly CodeGraphEdgeType[];
|
|
6
|
+
}
|
|
7
|
+
export interface ImpactResult {
|
|
8
|
+
readonly changed: GraphNode<CodeGraphNodeData>;
|
|
9
|
+
readonly directDependents: readonly GraphNode<CodeGraphNodeData>[];
|
|
10
|
+
readonly indirectDependents: readonly GraphNode<CodeGraphNodeData>[];
|
|
11
|
+
readonly affectedFiles: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function analyzeImpact(graph: CodeGraph, changedNodeId: string, options?: ImpactOptions): ImpactResult;
|
|
14
|
+
//# sourceMappingURL=analyzeImpact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzeImpact.d.ts","sourceRoot":"","sources":["../../src/queries/analyzeImpact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,qCAAqC,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC/C,QAAQ,CAAC,gBAAgB,EAAE,SAAS,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACnE,QAAQ,CAAC,kBAAkB,EAAE,SAAS,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACrE,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CA8Dd"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function analyzeImpact(graph, changedNodeId, options = {}) {
|
|
2
|
+
const changed = graph.getNode(changedNodeId);
|
|
3
|
+
if (changed === undefined) {
|
|
4
|
+
throw new Error(`Node does not exist: ${changedNodeId}`);
|
|
5
|
+
}
|
|
6
|
+
const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
|
|
7
|
+
if (maxDepth < 0) {
|
|
8
|
+
throw new Error("maxDepth must be zero or greater");
|
|
9
|
+
}
|
|
10
|
+
const allowed = new Set(options.relationships ?? ["CALLS", "IMPORTS"]);
|
|
11
|
+
const visited = new Set([changedNodeId]);
|
|
12
|
+
const queue = [
|
|
13
|
+
{ id: changedNodeId, depth: 0 },
|
|
14
|
+
];
|
|
15
|
+
const direct = [];
|
|
16
|
+
const indirect = [];
|
|
17
|
+
let nextIndex = 0;
|
|
18
|
+
while (nextIndex < queue.length) {
|
|
19
|
+
const current = queue[nextIndex];
|
|
20
|
+
nextIndex += 1;
|
|
21
|
+
if (current === undefined || current.depth >= maxDepth) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
for (const edge of graph.getIncomingEdges(current.id)) {
|
|
25
|
+
if (!allowed.has(edge.type) || visited.has(edge.from)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
visited.add(edge.from);
|
|
29
|
+
const node = graph.getNode(edge.from);
|
|
30
|
+
if (node === undefined) {
|
|
31
|
+
throw new Error(`Internal graph invariant failed for node: ${edge.from}`);
|
|
32
|
+
}
|
|
33
|
+
const depth = current.depth + 1;
|
|
34
|
+
if (depth === 1) {
|
|
35
|
+
direct.push(node);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
indirect.push(node);
|
|
39
|
+
}
|
|
40
|
+
queue.push({ id: edge.from, depth });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const affectedFiles = new Set();
|
|
44
|
+
for (const node of [...direct, ...indirect]) {
|
|
45
|
+
affectedFiles.add(node.data.nodeType === "file"
|
|
46
|
+
? node.data.filePath
|
|
47
|
+
: node.data.location.file);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
changed,
|
|
51
|
+
directDependents: direct,
|
|
52
|
+
indirectDependents: indirect,
|
|
53
|
+
affectedFiles: [...affectedFiles].sort(),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=analyzeImpact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzeImpact.js","sourceRoot":"","sources":["../../src/queries/analyzeImpact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GraphNode } from "../graph/types.js";
|
|
2
|
+
import type { CodeGraph, CodeGraphEdgeType, CodeGraphNodeData, SymbolNodeData } from "../analyzer/buildDefinitionGraph.js";
|
|
3
|
+
export declare function findSymbols(graph: CodeGraph, query: string): readonly GraphNode<SymbolNodeData>[];
|
|
4
|
+
export declare function getCodeDependencies(graph: CodeGraph, nodeId: string, relationships?: readonly CodeGraphEdgeType[]): readonly GraphNode<CodeGraphNodeData>[];
|
|
5
|
+
export declare function getCodeDependents(graph: CodeGraph, nodeId: string, relationships?: readonly CodeGraphEdgeType[]): readonly GraphNode<CodeGraphNodeData>[];
|
|
6
|
+
export declare function findCodePath(graph: CodeGraph, sourceId: string, targetId: string, relationships?: readonly CodeGraphEdgeType[]): readonly string[] | null;
|
|
7
|
+
//# sourceMappingURL=codeGraphQueries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeGraphQueries.d.ts","sourceRoot":"","sources":["../../src/queries/codeGraphQueries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACf,MAAM,qCAAqC,CAAC;AAO7C,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,GACZ,SAAS,SAAS,CAAC,cAAc,CAAC,EAAE,CAmBtC;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,SAAS,iBAAiB,EAAqC,GAC7E,SAAS,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAMzC;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,SAAS,iBAAiB,EAAqC,GAC7E,SAAS,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAMzC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,GAAE,SAAS,iBAAiB,EAAqC,GAC7E,SAAS,MAAM,EAAE,GAAG,IAAI,CAkC1B"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const DEFAULT_DEPENDENCY_RELATIONSHIPS = [
|
|
2
|
+
"CALLS",
|
|
3
|
+
"IMPORTS",
|
|
4
|
+
];
|
|
5
|
+
export function findSymbols(graph, query) {
|
|
6
|
+
const normalizedQuery = query.toLocaleLowerCase();
|
|
7
|
+
return graph
|
|
8
|
+
.getNodes()
|
|
9
|
+
.filter((node) => node.data.nodeType === "symbol" &&
|
|
10
|
+
(node.data.name.toLocaleLowerCase().includes(normalizedQuery) ||
|
|
11
|
+
node.data.qualifiedName.toLocaleLowerCase().includes(normalizedQuery)))
|
|
12
|
+
.sort((left, right) => {
|
|
13
|
+
const leftExact = left.data.qualifiedName.toLocaleLowerCase() === normalizedQuery;
|
|
14
|
+
const rightExact = right.data.qualifiedName.toLocaleLowerCase() === normalizedQuery;
|
|
15
|
+
if (leftExact !== rightExact) {
|
|
16
|
+
return leftExact ? -1 : 1;
|
|
17
|
+
}
|
|
18
|
+
return left.data.qualifiedName.localeCompare(right.data.qualifiedName);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function getCodeDependencies(graph, nodeId, relationships = DEFAULT_DEPENDENCY_RELATIONSHIPS) {
|
|
22
|
+
const allowed = new Set(relationships);
|
|
23
|
+
return graph
|
|
24
|
+
.getOutgoingEdges(nodeId)
|
|
25
|
+
.filter((edge) => allowed.has(edge.type))
|
|
26
|
+
.map((edge) => requiredNode(graph, edge.to));
|
|
27
|
+
}
|
|
28
|
+
export function getCodeDependents(graph, nodeId, relationships = DEFAULT_DEPENDENCY_RELATIONSHIPS) {
|
|
29
|
+
const allowed = new Set(relationships);
|
|
30
|
+
return graph
|
|
31
|
+
.getIncomingEdges(nodeId)
|
|
32
|
+
.filter((edge) => allowed.has(edge.type))
|
|
33
|
+
.map((edge) => requiredNode(graph, edge.from));
|
|
34
|
+
}
|
|
35
|
+
export function findCodePath(graph, sourceId, targetId, relationships = DEFAULT_DEPENDENCY_RELATIONSHIPS) {
|
|
36
|
+
requiredNode(graph, sourceId);
|
|
37
|
+
requiredNode(graph, targetId);
|
|
38
|
+
if (sourceId === targetId) {
|
|
39
|
+
return [sourceId];
|
|
40
|
+
}
|
|
41
|
+
const allowed = new Set(relationships);
|
|
42
|
+
const visited = new Set([sourceId]);
|
|
43
|
+
const parent = new Map();
|
|
44
|
+
const queue = [sourceId];
|
|
45
|
+
let nextIndex = 0;
|
|
46
|
+
while (nextIndex < queue.length) {
|
|
47
|
+
const currentId = queue[nextIndex];
|
|
48
|
+
nextIndex += 1;
|
|
49
|
+
if (currentId === undefined) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
for (const edge of graph.getOutgoingEdges(currentId)) {
|
|
53
|
+
if (!allowed.has(edge.type) || visited.has(edge.to)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
visited.add(edge.to);
|
|
57
|
+
parent.set(edge.to, currentId);
|
|
58
|
+
if (edge.to === targetId) {
|
|
59
|
+
return reconstructPath(parent, sourceId, targetId);
|
|
60
|
+
}
|
|
61
|
+
queue.push(edge.to);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function reconstructPath(parent, sourceId, targetId) {
|
|
67
|
+
const reversed = [targetId];
|
|
68
|
+
let currentId = targetId;
|
|
69
|
+
while (currentId !== sourceId) {
|
|
70
|
+
const parentId = parent.get(currentId);
|
|
71
|
+
if (parentId === undefined) {
|
|
72
|
+
throw new Error("Internal query invariant failed while rebuilding path");
|
|
73
|
+
}
|
|
74
|
+
reversed.push(parentId);
|
|
75
|
+
currentId = parentId;
|
|
76
|
+
}
|
|
77
|
+
return reversed.reverse();
|
|
78
|
+
}
|
|
79
|
+
function requiredNode(graph, nodeId) {
|
|
80
|
+
const node = graph.getNode(nodeId);
|
|
81
|
+
if (node === undefined) {
|
|
82
|
+
throw new Error(`Node does not exist: ${nodeId}`);
|
|
83
|
+
}
|
|
84
|
+
return node;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=codeGraphQueries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeGraphQueries.js","sourceRoot":"","sources":["../../src/queries/codeGraphQueries.ts"],"names":[],"mappings":"AAQA,MAAM,gCAAgC,GAAiC;IACrE,OAAO;IACP,SAAS;CACV,CAAC;AAEF,MAAM,UAAU,WAAW,CACzB,KAAgB,EAChB,KAAa;IAEb,MAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAElD,OAAO,KAAK;SACT,QAAQ,EAAE;SACV,MAAM,CACL,CAAC,IAAI,EAAqC,EAAE,CAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ;QAC/B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;YAC3D,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAC3E;SACA,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,KAAK,eAAe,CAAC;QAClF,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,KAAK,eAAe,CAAC;QACpF,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAgB,EAChB,MAAc,EACd,gBAA8C,gCAAgC;IAE9E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACvC,OAAO,KAAK;SACT,gBAAgB,CAAC,MAAM,CAAC;SACxB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAgB,EAChB,MAAc,EACd,gBAA8C,gCAAgC;IAE9E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACvC,OAAO,KAAK;SACT,gBAAgB,CAAC,MAAM,CAAC;SACxB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,KAAgB,EAChB,QAAgB,EAChB,QAAgB,EAChB,gBAA8C,gCAAgC;IAE9E,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9B,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9B,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QACnC,SAAS,IAAI,CAAC,CAAC;QACf,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpD,SAAS;YACX,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC/B,IAAI,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACrD,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CACtB,MAAmC,EACnC,QAAgB,EAChB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,SAAS,GAAG,QAAQ,CAAC;IACzB,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,SAAS,GAAG,QAAQ,CAAC;IACvB,CAAC;IACD,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,YAAY,CACnB,KAAgB,EAChB,MAAc;IAEd,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "repo-codegraph",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A TypeScript code-intelligence graph for imports, calls, queries, and impact analysis",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./mcp": {
|
|
18
|
+
"types": "./dist/mcp/server.d.ts",
|
|
19
|
+
"import": "./dist/mcp/server.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"bin": {
|
|
23
|
+
"codegraph": "./dist/cli.js",
|
|
24
|
+
"codegraph-mcp": "./dist/mcp/stdio.js"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -p tsconfig.build.json",
|
|
28
|
+
"check": "tsc --noEmit",
|
|
29
|
+
"codegraph": "node --import tsx src/cli.ts",
|
|
30
|
+
"codegraph-mcp": "node --import tsx src/mcp/stdio.ts",
|
|
31
|
+
"example": "node --import tsx examples/basic.ts",
|
|
32
|
+
"inspect-ast": "node --import tsx examples/inspectAst.ts",
|
|
33
|
+
"test": "node --import tsx --test test/*.test.ts"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^20.19.0",
|
|
40
|
+
"tsx": "^4.20.0",
|
|
41
|
+
"typescript": "^5.9.0"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
45
|
+
"zod": "^4.6.7"
|
|
46
|
+
}
|
|
6
47
|
}
|