spec-gen-cli 1.2.2 → 1.2.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 +272 -25
- package/dist/api/generate.d.ts.map +1 -1
- package/dist/api/generate.js +11 -7
- package/dist/api/generate.js.map +1 -1
- package/dist/api/run.d.ts.map +1 -1
- package/dist/api/run.js +5 -3
- package/dist/api/run.js.map +1 -1
- package/dist/api/types.d.ts +4 -4
- package/dist/api/types.d.ts.map +1 -1
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +101 -41
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +28 -23
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts +353 -10
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +241 -48
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/view.d.ts.map +1 -1
- package/dist/cli/commands/view.js +33 -4
- package/dist/cli/commands/view.js.map +1 -1
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +11 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/analyzer/artifact-generator.d.ts.map +1 -1
- package/dist/core/analyzer/artifact-generator.js +11 -3
- package/dist/core/analyzer/artifact-generator.js.map +1 -1
- package/dist/core/analyzer/ast-chunker.d.ts +24 -0
- package/dist/core/analyzer/ast-chunker.d.ts.map +1 -0
- package/dist/core/analyzer/ast-chunker.js +198 -0
- package/dist/core/analyzer/ast-chunker.js.map +1 -0
- package/dist/core/analyzer/call-graph.d.ts +52 -5
- package/dist/core/analyzer/call-graph.d.ts.map +1 -1
- package/dist/core/analyzer/call-graph.js +769 -48
- package/dist/core/analyzer/call-graph.js.map +1 -1
- package/dist/core/analyzer/code-shaper.d.ts.map +1 -1
- package/dist/core/analyzer/code-shaper.js +5 -0
- package/dist/core/analyzer/code-shaper.js.map +1 -1
- package/dist/core/analyzer/codebase-digest.d.ts +40 -0
- package/dist/core/analyzer/codebase-digest.d.ts.map +1 -0
- package/dist/core/analyzer/codebase-digest.js +194 -0
- package/dist/core/analyzer/codebase-digest.js.map +1 -0
- package/dist/core/analyzer/cpp-header-resolver.d.ts +30 -0
- package/dist/core/analyzer/cpp-header-resolver.d.ts.map +1 -0
- package/dist/core/analyzer/cpp-header-resolver.js +71 -0
- package/dist/core/analyzer/cpp-header-resolver.js.map +1 -0
- package/dist/core/analyzer/dependency-graph.d.ts +19 -0
- package/dist/core/analyzer/dependency-graph.d.ts.map +1 -1
- package/dist/core/analyzer/dependency-graph.js +76 -0
- package/dist/core/analyzer/dependency-graph.js.map +1 -1
- package/dist/core/analyzer/duplicate-detector.d.ts.map +1 -1
- package/dist/core/analyzer/duplicate-detector.js +7 -1
- package/dist/core/analyzer/duplicate-detector.js.map +1 -1
- package/dist/core/analyzer/function-registry-trie.d.ts +21 -0
- package/dist/core/analyzer/function-registry-trie.d.ts.map +1 -0
- package/dist/core/analyzer/function-registry-trie.js +39 -0
- package/dist/core/analyzer/function-registry-trie.js.map +1 -0
- package/dist/core/analyzer/import-resolver-bridge.d.ts +25 -0
- package/dist/core/analyzer/import-resolver-bridge.d.ts.map +1 -0
- package/dist/core/analyzer/import-resolver-bridge.js +99 -0
- package/dist/core/analyzer/import-resolver-bridge.js.map +1 -0
- package/dist/core/analyzer/signature-extractor.d.ts.map +1 -1
- package/dist/core/analyzer/signature-extractor.js +131 -3
- package/dist/core/analyzer/signature-extractor.js.map +1 -1
- package/dist/core/analyzer/subgraph-extractor.d.ts +10 -2
- package/dist/core/analyzer/subgraph-extractor.d.ts.map +1 -1
- package/dist/core/analyzer/subgraph-extractor.js +25 -7
- package/dist/core/analyzer/subgraph-extractor.js.map +1 -1
- package/dist/core/analyzer/type-inference-engine.d.ts +23 -0
- package/dist/core/analyzer/type-inference-engine.d.ts.map +1 -0
- package/dist/core/analyzer/type-inference-engine.js +130 -0
- package/dist/core/analyzer/type-inference-engine.js.map +1 -0
- package/dist/core/analyzer/vector-index.d.ts +35 -6
- package/dist/core/analyzer/vector-index.d.ts.map +1 -1
- package/dist/core/analyzer/vector-index.js +308 -54
- package/dist/core/analyzer/vector-index.js.map +1 -1
- package/dist/core/generator/spec-pipeline.d.ts +31 -11
- package/dist/core/generator/spec-pipeline.d.ts.map +1 -1
- package/dist/core/generator/spec-pipeline.js +170 -39
- package/dist/core/generator/spec-pipeline.js.map +1 -1
- package/dist/core/generator/stages/stage2-entities.d.ts.map +1 -1
- package/dist/core/generator/stages/stage2-entities.js +2 -1
- package/dist/core/generator/stages/stage2-entities.js.map +1 -1
- package/dist/core/generator/stages/stage3-services.d.ts.map +1 -1
- package/dist/core/generator/stages/stage3-services.js +2 -1
- package/dist/core/generator/stages/stage3-services.js.map +1 -1
- package/dist/core/generator/stages/stage4-api.d.ts.map +1 -1
- package/dist/core/generator/stages/stage4-api.js +2 -1
- package/dist/core/generator/stages/stage4-api.js.map +1 -1
- package/dist/core/generator/stages/stage5-architecture.d.ts +2 -1
- package/dist/core/generator/stages/stage5-architecture.d.ts.map +1 -1
- package/dist/core/generator/stages/stage5-architecture.js +15 -3
- package/dist/core/generator/stages/stage5-architecture.js.map +1 -1
- package/dist/core/services/chat-agent.d.ts +5 -0
- package/dist/core/services/chat-agent.d.ts.map +1 -1
- package/dist/core/services/chat-agent.js +14 -0
- package/dist/core/services/chat-agent.js.map +1 -1
- package/dist/core/services/chat-tools.d.ts.map +1 -1
- package/dist/core/services/chat-tools.js +172 -50
- package/dist/core/services/chat-tools.js.map +1 -1
- package/dist/core/services/llm-service.d.ts +23 -1
- package/dist/core/services/llm-service.d.ts.map +1 -1
- package/dist/core/services/llm-service.js +94 -2
- package/dist/core/services/llm-service.js.map +1 -1
- package/dist/core/services/mcp-handlers/analysis.d.ts +12 -0
- package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/analysis.js +138 -2
- package/dist/core/services/mcp-handlers/analysis.js.map +1 -1
- package/dist/core/services/mcp-handlers/graph.d.ts +21 -1
- package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/graph.js +142 -2
- package/dist/core/services/mcp-handlers/graph.js.map +1 -1
- package/dist/core/services/mcp-handlers/orient.d.ts +17 -0
- package/dist/core/services/mcp-handlers/orient.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/orient.js +200 -0
- package/dist/core/services/mcp-handlers/orient.js.map +1 -0
- package/dist/core/services/mcp-handlers/semantic.d.ts +18 -4
- package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/semantic.js +161 -17
- package/dist/core/services/mcp-handlers/semantic.js.map +1 -1
- package/dist/core/services/mcp-handlers/utils.d.ts +43 -0
- package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/utils.js +66 -1
- package/dist/core/services/mcp-handlers/utils.js.map +1 -1
- package/dist/core/services/mcp-watcher.d.ts +41 -0
- package/dist/core/services/mcp-watcher.d.ts.map +1 -0
- package/dist/core/services/mcp-watcher.js +177 -0
- package/dist/core/services/mcp-watcher.js.map +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/pipeline.d.ts +7 -0
- package/dist/types/pipeline.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/viewer/InteractiveGraphViewer.jsx +39 -10
- package/src/viewer/components/ChatPanel.jsx +8 -5
- package/src/viewer/components/ClassGraph.jsx +782 -0
- package/src/viewer/components/FlatGraph.jsx +3 -3
- package/src/viewer/utils/graph-helpers.js +9 -1
- package/src/viewer/utils/themes.js +36 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST-based chunking using tree-sitter.
|
|
3
|
+
*
|
|
4
|
+
* Breaks content at real declaration boundaries (function, class, interface…)
|
|
5
|
+
* rather than at accidental blank lines. Falls back to blank-line chunking
|
|
6
|
+
* when the language is unsupported or parsing fails.
|
|
7
|
+
*
|
|
8
|
+
* Each chunk after the first is prefixed with the file's import/header block
|
|
9
|
+
* so the LLM always has module-level context.
|
|
10
|
+
*/
|
|
11
|
+
import Parser from 'tree-sitter';
|
|
12
|
+
import { detectLanguage } from './code-shaper.js';
|
|
13
|
+
// ── Lazy parser singletons (one per language, created on first use) ─────────
|
|
14
|
+
let _tsParser;
|
|
15
|
+
let _pyParser;
|
|
16
|
+
let _goParser;
|
|
17
|
+
let _rustParser;
|
|
18
|
+
let _rubyParser;
|
|
19
|
+
let _javaParser;
|
|
20
|
+
async function getParserForLanguage(lang) {
|
|
21
|
+
try {
|
|
22
|
+
switch (lang.toLowerCase()) {
|
|
23
|
+
case 'typescript':
|
|
24
|
+
case 'javascript': {
|
|
25
|
+
if (!_tsParser) {
|
|
26
|
+
const m = await import('tree-sitter-typescript');
|
|
27
|
+
_tsParser = new Parser();
|
|
28
|
+
_tsParser.setLanguage((m.default ?? m).typescript);
|
|
29
|
+
}
|
|
30
|
+
return _tsParser;
|
|
31
|
+
}
|
|
32
|
+
case 'python': {
|
|
33
|
+
if (!_pyParser) {
|
|
34
|
+
const m = await import('tree-sitter-python');
|
|
35
|
+
_pyParser = new Parser();
|
|
36
|
+
_pyParser.setLanguage((m.default ?? m));
|
|
37
|
+
}
|
|
38
|
+
return _pyParser;
|
|
39
|
+
}
|
|
40
|
+
case 'go': {
|
|
41
|
+
if (!_goParser) {
|
|
42
|
+
const m = await import('tree-sitter-go');
|
|
43
|
+
_goParser = new Parser();
|
|
44
|
+
_goParser.setLanguage((m.default ?? m));
|
|
45
|
+
}
|
|
46
|
+
return _goParser;
|
|
47
|
+
}
|
|
48
|
+
case 'rust': {
|
|
49
|
+
if (!_rustParser) {
|
|
50
|
+
const m = await import('tree-sitter-rust');
|
|
51
|
+
_rustParser = new Parser();
|
|
52
|
+
_rustParser.setLanguage((m.default ?? m));
|
|
53
|
+
}
|
|
54
|
+
return _rustParser;
|
|
55
|
+
}
|
|
56
|
+
case 'ruby': {
|
|
57
|
+
if (!_rubyParser) {
|
|
58
|
+
const m = await import('tree-sitter-ruby');
|
|
59
|
+
_rubyParser = new Parser();
|
|
60
|
+
_rubyParser.setLanguage((m.default ?? m));
|
|
61
|
+
}
|
|
62
|
+
return _rubyParser;
|
|
63
|
+
}
|
|
64
|
+
case 'java': {
|
|
65
|
+
if (!_javaParser) {
|
|
66
|
+
const m = await import('tree-sitter-java');
|
|
67
|
+
_javaParser = new Parser();
|
|
68
|
+
_javaParser.setLanguage((m.default ?? m));
|
|
69
|
+
}
|
|
70
|
+
return _javaParser;
|
|
71
|
+
}
|
|
72
|
+
default:
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ── Import-block detection ──────────────────────────────────────────────────
|
|
81
|
+
function isImportNode(type) {
|
|
82
|
+
return (type.startsWith('import') ||
|
|
83
|
+
type === 'use_declaration' || // Rust
|
|
84
|
+
type === 'package_clause' || // Go
|
|
85
|
+
type === 'require_clause' // Ruby
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Return the source text up to (and including) the last contiguous import
|
|
90
|
+
* node at the top of the file. Empty string when no imports are detected.
|
|
91
|
+
*/
|
|
92
|
+
function extractHeader(topNodes, source) {
|
|
93
|
+
let lastImportEnd = 0;
|
|
94
|
+
for (const n of topNodes) {
|
|
95
|
+
if (isImportNode(n.type)) {
|
|
96
|
+
lastImportEnd = n.endIndex;
|
|
97
|
+
}
|
|
98
|
+
else if (lastImportEnd > 0) {
|
|
99
|
+
// Stop at the first non-import node after seeing at least one import
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return lastImportEnd > 0 ? source.slice(0, lastImportEnd).trim() : '';
|
|
104
|
+
}
|
|
105
|
+
// ── Blank-line fallback ─────────────────────────────────────────────────────
|
|
106
|
+
/**
|
|
107
|
+
* Original blank-line chunking, kept as fallback for unsupported languages.
|
|
108
|
+
*/
|
|
109
|
+
export function blankLineChunk(content, maxChars, overlapLines = 10) {
|
|
110
|
+
if (content.length <= maxChars)
|
|
111
|
+
return [content];
|
|
112
|
+
const lines = content.split('\n');
|
|
113
|
+
const chunks = [];
|
|
114
|
+
let currentLines = [];
|
|
115
|
+
let currentSize = 0;
|
|
116
|
+
for (const line of lines) {
|
|
117
|
+
currentLines.push(line);
|
|
118
|
+
currentSize += line.length + 1;
|
|
119
|
+
if (currentSize >= maxChars && line.trim() === '') {
|
|
120
|
+
const chunk = currentLines.join('\n').trim();
|
|
121
|
+
if (chunk)
|
|
122
|
+
chunks.push(chunk);
|
|
123
|
+
const overlap = currentLines.slice(-overlapLines);
|
|
124
|
+
currentLines = [...overlap];
|
|
125
|
+
currentSize = overlap.reduce((s, l) => s + l.length + 1, 0);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const remaining = currentLines.join('\n').trim();
|
|
129
|
+
if (remaining)
|
|
130
|
+
chunks.push(remaining);
|
|
131
|
+
return chunks;
|
|
132
|
+
}
|
|
133
|
+
// ── AST chunker ─────────────────────────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Chunk `content` at real AST declaration boundaries using tree-sitter.
|
|
136
|
+
*
|
|
137
|
+
* Falls back to blank-line chunking if the language is unsupported or parsing
|
|
138
|
+
* fails. Each chunk after the first is prefixed with the file's imports block
|
|
139
|
+
* so the LLM always has module-level context (e.g. class declaration visible
|
|
140
|
+
* when processing a method that was split into a later chunk).
|
|
141
|
+
*/
|
|
142
|
+
export async function astChunkContent(content, filePath, maxChars, overlapLines = 10) {
|
|
143
|
+
if (content.length <= maxChars)
|
|
144
|
+
return [content];
|
|
145
|
+
const language = detectLanguage(filePath);
|
|
146
|
+
const parser = await getParserForLanguage(language);
|
|
147
|
+
if (!parser)
|
|
148
|
+
return blankLineChunk(content, maxChars, overlapLines);
|
|
149
|
+
let tree;
|
|
150
|
+
try {
|
|
151
|
+
tree = parser.parse(content);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return blankLineChunk(content, maxChars, overlapLines);
|
|
155
|
+
}
|
|
156
|
+
// Top-level children that carry real content (skip whitespace / standalone comments)
|
|
157
|
+
const topNodes = tree.rootNode.children.filter(n => n.type !== 'comment' && n.text.trim().length > 0);
|
|
158
|
+
if (topNodes.length === 0)
|
|
159
|
+
return blankLineChunk(content, maxChars, overlapLines);
|
|
160
|
+
// Header = import/package block, prepended to every non-first chunk
|
|
161
|
+
const header = extractHeader(topNodes, content);
|
|
162
|
+
const chunks = [];
|
|
163
|
+
let groupStart = -1;
|
|
164
|
+
let groupEnd = -1;
|
|
165
|
+
const emitGroup = (start, end) => {
|
|
166
|
+
const text = content.slice(start, end).trim();
|
|
167
|
+
if (!text)
|
|
168
|
+
return;
|
|
169
|
+
if (chunks.length > 0 && header) {
|
|
170
|
+
chunks.push(`${header}\n\n${text}`);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
chunks.push(text);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
for (const node of topNodes) {
|
|
177
|
+
if (groupStart === -1) {
|
|
178
|
+
groupStart = node.startIndex;
|
|
179
|
+
groupEnd = node.endIndex;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const nodeSpan = node.endIndex - groupStart;
|
|
183
|
+
// Account for header prefix added to non-first chunks
|
|
184
|
+
const effectiveSize = chunks.length > 0 && header ? header.length + 2 + nodeSpan : nodeSpan;
|
|
185
|
+
if (effectiveSize > maxChars) {
|
|
186
|
+
emitGroup(groupStart, groupEnd);
|
|
187
|
+
groupStart = node.startIndex;
|
|
188
|
+
groupEnd = node.endIndex;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
groupEnd = node.endIndex;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (groupStart !== -1)
|
|
195
|
+
emitGroup(groupStart, groupEnd);
|
|
196
|
+
return chunks.length > 0 ? chunks : blankLineChunk(content, maxChars, overlapLines);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=ast-chunker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-chunker.js","sourceRoot":"","sources":["../../../src/core/analyzer/ast-chunker.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Call Graph Analyzer
|
|
3
3
|
*
|
|
4
4
|
* Performs static analysis of function calls across source files using tree-sitter.
|
|
5
|
-
* Supports TypeScript/JavaScript, Python, Go, Rust, Ruby, Java — no LLM, pure AST.
|
|
5
|
+
* Supports TypeScript/JavaScript, Python, Go, Rust, Ruby, Java, Swift — no LLM, pure AST.
|
|
6
6
|
*
|
|
7
7
|
* Produces:
|
|
8
8
|
* - FunctionNode[] — all identified functions/methods
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* - Entry points — functions with no internal callers
|
|
12
12
|
* - Layer violations — cross-layer calls in the wrong direction
|
|
13
13
|
*/
|
|
14
|
+
import type { ImportMap } from './import-resolver-bridge.js';
|
|
15
|
+
export type EdgeConfidence = 'self_cls' | 'type_inference' | 'import' | 'http_endpoint' | 'same_file' | 'name_only' | 'type_name';
|
|
14
16
|
export interface FunctionNode {
|
|
15
17
|
/** Unique ID: "filepath::ClassName.methodName" or "filepath::functionName" */
|
|
16
18
|
id: string;
|
|
@@ -24,6 +26,10 @@ export interface FunctionNode {
|
|
|
24
26
|
endIndex: number;
|
|
25
27
|
fanIn: number;
|
|
26
28
|
fanOut: number;
|
|
29
|
+
/** First meaningful line of the doc comment / docstring, extracted from AST positions */
|
|
30
|
+
docstring?: string;
|
|
31
|
+
/** Declaration line(s) up to opening brace/colon, whitespace-normalized */
|
|
32
|
+
signature?: string;
|
|
27
33
|
}
|
|
28
34
|
export interface CallEdge {
|
|
29
35
|
callerId: string;
|
|
@@ -32,6 +38,7 @@ export interface CallEdge {
|
|
|
32
38
|
/** Raw name as it appears in source */
|
|
33
39
|
calleeName: string;
|
|
34
40
|
line?: number;
|
|
41
|
+
confidence: EdgeConfidence;
|
|
35
42
|
}
|
|
36
43
|
export interface LayerViolation {
|
|
37
44
|
callerId: string;
|
|
@@ -40,9 +47,47 @@ export interface LayerViolation {
|
|
|
40
47
|
calleeLayer: string;
|
|
41
48
|
reason: string;
|
|
42
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* A class or interface as a structural unit, grouping its methods.
|
|
52
|
+
* Derived from FunctionNode.className after the call graph is built.
|
|
53
|
+
*/
|
|
54
|
+
export interface ClassNode {
|
|
55
|
+
/** Unique ID: first filePath where the class is seen + "::" + className */
|
|
56
|
+
id: string;
|
|
57
|
+
name: string;
|
|
58
|
+
filePath: string;
|
|
59
|
+
language: string;
|
|
60
|
+
/** Direct parent class names (from `extends` / Python base / C++ base) */
|
|
61
|
+
parentClasses: string[];
|
|
62
|
+
/** Implemented interfaces (TypeScript `implements`, Java `implements`) */
|
|
63
|
+
interfaces: string[];
|
|
64
|
+
/** IDs of FunctionNode members that belong to this class */
|
|
65
|
+
methodIds: string[];
|
|
66
|
+
/** Sum of method fanIn values */
|
|
67
|
+
fanIn: number;
|
|
68
|
+
/** Sum of method fanOut values */
|
|
69
|
+
fanOut: number;
|
|
70
|
+
/** True for synthetic file-level module nodes (free functions grouped by file) */
|
|
71
|
+
isModule?: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* An inheritance or implementation edge between two ClassNodes in the graph.
|
|
75
|
+
*/
|
|
76
|
+
export interface InheritanceEdge {
|
|
77
|
+
id: string;
|
|
78
|
+
/** ClassNode id of the parent / base / interface */
|
|
79
|
+
parentId: string;
|
|
80
|
+
/** ClassNode id of the child / derived / implementor */
|
|
81
|
+
childId: string;
|
|
82
|
+
kind: 'extends' | 'implements' | 'embeds';
|
|
83
|
+
}
|
|
43
84
|
export interface CallGraphResult {
|
|
44
85
|
nodes: Map<string, FunctionNode>;
|
|
45
86
|
edges: CallEdge[];
|
|
87
|
+
/** Class-level structural nodes, derived from FunctionNode.className grouping */
|
|
88
|
+
classes: ClassNode[];
|
|
89
|
+
/** Inheritance / implementation edges between ClassNodes */
|
|
90
|
+
inheritanceEdges: InheritanceEdge[];
|
|
46
91
|
/** Functions with fanIn >= HUB_THRESHOLD */
|
|
47
92
|
hubFunctions: FunctionNode[];
|
|
48
93
|
/** Functions with no internal callers (fanIn === 0) */
|
|
@@ -59,6 +104,8 @@ export interface CallGraphResult {
|
|
|
59
104
|
export interface SerializedCallGraph {
|
|
60
105
|
nodes: FunctionNode[];
|
|
61
106
|
edges: CallEdge[];
|
|
107
|
+
classes: ClassNode[];
|
|
108
|
+
inheritanceEdges: InheritanceEdge[];
|
|
62
109
|
hubFunctions: FunctionNode[];
|
|
63
110
|
entryPoints: FunctionNode[];
|
|
64
111
|
layerViolations: LayerViolation[];
|
|
@@ -68,15 +115,15 @@ export declare class CallGraphBuilder {
|
|
|
68
115
|
/**
|
|
69
116
|
* Build a call graph from a list of source files.
|
|
70
117
|
*
|
|
71
|
-
* @param files
|
|
72
|
-
* @param layers
|
|
73
|
-
*
|
|
118
|
+
* @param files Source files with path, content, and language
|
|
119
|
+
* @param layers Optional layer map { layerName: [path prefix, ...] }
|
|
120
|
+
* @param importMap Optional per-file import map (from ImportResolverBridge)
|
|
74
121
|
*/
|
|
75
122
|
build(files: Array<{
|
|
76
123
|
path: string;
|
|
77
124
|
content: string;
|
|
78
125
|
language: string;
|
|
79
|
-
}>, layers?: Record<string, string[]
|
|
126
|
+
}>, layers?: Record<string, string[]>, importMap?: ImportMap): Promise<CallGraphResult>;
|
|
80
127
|
private detectLayerViolations;
|
|
81
128
|
}
|
|
82
129
|
export declare function serializeCallGraph(result: CallGraphResult): SerializedCallGraph;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../../../src/core/analyzer/call-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../../../src/core/analyzer/call-graph.ts"],"names":[],"mappings":"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"}
|