@abhinav2203/codeflow-core 1.0.0 → 1.0.2
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/dist/analyzer/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { buildBlueprintGraph } from "./build.js";
|
|
2
2
|
export { analyzeTypeScriptRepo } from "./repo.js";
|
|
3
3
|
export { analyzeRepo } from "./repo-multi.js";
|
|
4
|
-
export type { AnalyzeRepoOptions } from "./repo-multi.js";
|
|
4
|
+
export type { AnalyzeRepoOptions, RepoAnalysisResult, SourceSpanEntry, CallSiteEntry } from "./repo-multi.js";
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
type RepoGraphPart = Omit<import("../schema/index.js").BlueprintGraph, "projectName" | "mode" | "generatedAt">;
|
|
2
|
+
export interface SourceSpanEntry {
|
|
3
|
+
nodeId: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
startLine: number;
|
|
6
|
+
endLine: number;
|
|
7
|
+
symbol?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CallSiteEntry {
|
|
10
|
+
edgeKey: string;
|
|
11
|
+
fromNodeId: string;
|
|
12
|
+
toNodeId: string;
|
|
13
|
+
filePath: string;
|
|
14
|
+
lineNumbers: number[];
|
|
15
|
+
expressions: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface RepoAnalysisResult extends RepoGraphPart {
|
|
18
|
+
sourceSpans: Record<string, SourceSpanEntry>;
|
|
19
|
+
callSites: Record<string, CallSiteEntry>;
|
|
20
|
+
}
|
|
2
21
|
export interface AnalyzeRepoOptions {
|
|
3
22
|
excludePatterns?: string[];
|
|
4
23
|
}
|
|
5
|
-
export declare const analyzeRepo: (repoPath: string, options?: AnalyzeRepoOptions) => Promise<
|
|
24
|
+
export declare const analyzeRepo: (repoPath: string, options?: AnalyzeRepoOptions) => Promise<RepoAnalysisResult>;
|
|
6
25
|
export {};
|
|
@@ -70,6 +70,16 @@ export const analyzeRepo = async (repoPath, options) => {
|
|
|
70
70
|
allImportEdges.push(...result.importEdges);
|
|
71
71
|
allInheritEdges.push(...result.inheritEdges);
|
|
72
72
|
}
|
|
73
|
+
const sourceSpans = {};
|
|
74
|
+
for (const n of allNodes) {
|
|
75
|
+
sourceSpans[n.nodeId] = {
|
|
76
|
+
nodeId: n.nodeId,
|
|
77
|
+
filePath: n.path,
|
|
78
|
+
startLine: n.startLine,
|
|
79
|
+
endLine: n.endLine,
|
|
80
|
+
symbol: n.sourceRefs.find(r => r.symbol)?.symbol
|
|
81
|
+
};
|
|
82
|
+
}
|
|
73
83
|
const nodeMap = new Map();
|
|
74
84
|
for (const n of allNodes) {
|
|
75
85
|
nodeMap.set(n.nodeId, createNode({
|
|
@@ -237,10 +247,42 @@ export const analyzeRepo = async (repoPath, options) => {
|
|
|
237
247
|
}
|
|
238
248
|
});
|
|
239
249
|
}
|
|
250
|
+
// Build callSites from resolved call edges
|
|
251
|
+
const callSites = {};
|
|
252
|
+
const callSiteGroups = new Map();
|
|
253
|
+
for (const call of allCallEdges) {
|
|
254
|
+
const targetId = [...allSymbolIndex.entries()].find(([key]) => key.endsWith(`::${call.toName}`))?.[1];
|
|
255
|
+
if (!targetId || targetId === call.fromId)
|
|
256
|
+
continue;
|
|
257
|
+
const edgeKey = `calls:${call.fromId}:${targetId}`;
|
|
258
|
+
const callerNode = nodeMap.get(call.fromId);
|
|
259
|
+
const filePath = callerNode?.path ?? "";
|
|
260
|
+
if (!filePath)
|
|
261
|
+
continue;
|
|
262
|
+
let group = callSiteGroups.get(edgeKey);
|
|
263
|
+
if (!group) {
|
|
264
|
+
group = { fromId: call.fromId, toId: targetId, lines: [], texts: [] };
|
|
265
|
+
callSiteGroups.set(edgeKey, group);
|
|
266
|
+
}
|
|
267
|
+
group.lines.push(call.callLine);
|
|
268
|
+
group.texts.push(call.callText);
|
|
269
|
+
}
|
|
270
|
+
for (const [edgeKey, group] of callSiteGroups) {
|
|
271
|
+
callSites[edgeKey] = {
|
|
272
|
+
edgeKey,
|
|
273
|
+
fromNodeId: group.fromId,
|
|
274
|
+
toNodeId: group.toId,
|
|
275
|
+
filePath: nodeMap.get(group.fromId)?.path ?? "",
|
|
276
|
+
lineNumbers: [...new Set(group.lines)].sort((a, b) => a - b),
|
|
277
|
+
expressions: [...new Set(group.texts)]
|
|
278
|
+
};
|
|
279
|
+
}
|
|
240
280
|
return {
|
|
241
281
|
nodes: [...nodeMap.values()],
|
|
242
282
|
edges: dedupeEdges(edges),
|
|
243
283
|
workflows: [],
|
|
244
|
-
warnings
|
|
284
|
+
warnings,
|
|
285
|
+
sourceSpans,
|
|
286
|
+
callSites
|
|
245
287
|
};
|
|
246
288
|
};
|
|
@@ -12,6 +12,8 @@ interface ExtractedNode {
|
|
|
12
12
|
symbol?: string;
|
|
13
13
|
}>;
|
|
14
14
|
ownerId?: string;
|
|
15
|
+
startLine: number;
|
|
16
|
+
endLine: number;
|
|
15
17
|
}
|
|
16
18
|
export declare const extractNodesFromFile: (filePath: string, relativePath: string) => Promise<{
|
|
17
19
|
nodes: ExtractedNode[];
|
|
@@ -21,6 +23,7 @@ export declare const extractNodesFromFile: (filePath: string, relativePath: stri
|
|
|
21
23
|
fromId: string;
|
|
22
24
|
toName: string;
|
|
23
25
|
callText: string;
|
|
26
|
+
callLine: number;
|
|
24
27
|
}>;
|
|
25
28
|
importEdges: Array<{
|
|
26
29
|
fromModuleId: string;
|
|
@@ -147,6 +147,7 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
147
147
|
const importEdges = [];
|
|
148
148
|
const inheritEdges = [];
|
|
149
149
|
const moduleId = createNodeId("module", relativePath, relativePath);
|
|
150
|
+
const moduleEndLine = root.endPosition.row + 1;
|
|
150
151
|
nodes.push({
|
|
151
152
|
nodeId: moduleId,
|
|
152
153
|
kind: "module",
|
|
@@ -154,7 +155,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
154
155
|
summary: `Source module ${relativePath}.`,
|
|
155
156
|
path: relativePath,
|
|
156
157
|
signature: "",
|
|
157
|
-
sourceRefs: [{ kind: "repo", path: relativePath }]
|
|
158
|
+
sourceRefs: [{ kind: "repo", path: relativePath }],
|
|
159
|
+
startLine: 1,
|
|
160
|
+
endLine: moduleEndLine
|
|
158
161
|
});
|
|
159
162
|
const recordFunc = (funcName, funcNode, paramsNode, returnTypeNode, bodyNode, ownerName, ownerId) => {
|
|
160
163
|
if (!funcName)
|
|
@@ -175,7 +178,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
175
178
|
path: relativePath,
|
|
176
179
|
signature,
|
|
177
180
|
sourceRefs: [{ kind: "repo", path: relativePath, symbol: displayName }],
|
|
178
|
-
ownerId: isMethod ? ownerId : (kind === "function" ? moduleId : undefined)
|
|
181
|
+
ownerId: isMethod ? ownerId : (kind === "function" ? moduleId : undefined),
|
|
182
|
+
startLine: funcNode.startPosition.row + 1,
|
|
183
|
+
endLine: funcNode.endPosition.row + 1
|
|
179
184
|
});
|
|
180
185
|
// Only store fully-qualified keys for methods to avoid collisions
|
|
181
186
|
symbolIndex.set(`${relativePath}::${displayName}`, nodeId);
|
|
@@ -206,7 +211,12 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
213
|
if (calleeName) {
|
|
209
|
-
callEdges.push({
|
|
214
|
+
callEdges.push({
|
|
215
|
+
fromId: callerId,
|
|
216
|
+
toName: calleeName,
|
|
217
|
+
callText: child.text,
|
|
218
|
+
callLine: child.startPosition.row + 1
|
|
219
|
+
});
|
|
210
220
|
}
|
|
211
221
|
collectCalls(child, callerId);
|
|
212
222
|
}
|
|
@@ -441,7 +451,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
441
451
|
path: relativePath,
|
|
442
452
|
signature: `class ${className}`,
|
|
443
453
|
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }],
|
|
444
|
-
ownerId: moduleId
|
|
454
|
+
ownerId: moduleId,
|
|
455
|
+
startLine: child.startPosition.row + 1,
|
|
456
|
+
endLine: child.endPosition.row + 1
|
|
445
457
|
});
|
|
446
458
|
symbolIndex.set(`${relativePath}::${className}`, classId);
|
|
447
459
|
if (parentClass)
|
|
@@ -473,7 +485,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
473
485
|
path: relativePath,
|
|
474
486
|
signature: `class ${className}`,
|
|
475
487
|
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }],
|
|
476
|
-
ownerId: moduleId
|
|
488
|
+
ownerId: moduleId,
|
|
489
|
+
startLine: child.startPosition.row + 1,
|
|
490
|
+
endLine: child.endPosition.row + 1
|
|
477
491
|
});
|
|
478
492
|
symbolIndex.set(`${relativePath}::${className}`, classId);
|
|
479
493
|
if (parentClass)
|
|
@@ -496,7 +510,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
496
510
|
summary: buildSummary(className, child, null, [], ""),
|
|
497
511
|
path: relativePath,
|
|
498
512
|
signature: `type ${className} struct`,
|
|
499
|
-
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }]
|
|
513
|
+
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }],
|
|
514
|
+
startLine: structType.startPosition.row + 1,
|
|
515
|
+
endLine: structType.endPosition.row + 1
|
|
500
516
|
});
|
|
501
517
|
symbolIndex.set(`${relativePath}::${className}`, classId);
|
|
502
518
|
walkFunctions(child, className, classId);
|
|
@@ -519,7 +535,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
519
535
|
summary: buildSummary(className, child, null, [], ""),
|
|
520
536
|
path: relativePath,
|
|
521
537
|
signature: `struct ${className}`,
|
|
522
|
-
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }]
|
|
538
|
+
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }],
|
|
539
|
+
startLine: child.startPosition.row + 1,
|
|
540
|
+
endLine: child.endPosition.row + 1
|
|
523
541
|
});
|
|
524
542
|
symbolIndex.set(`${relativePath}::${className}`, classId);
|
|
525
543
|
walkFunctions(child, className, classId);
|
|
@@ -547,7 +565,9 @@ export const extractNodesFromFile = async (filePath, relativePath) => {
|
|
|
547
565
|
summary: buildSummary(className, child, null, [], ""),
|
|
548
566
|
path: relativePath,
|
|
549
567
|
signature: `impl ${className}`,
|
|
550
|
-
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }]
|
|
568
|
+
sourceRefs: [{ kind: "repo", path: relativePath, symbol: className }],
|
|
569
|
+
startLine: child.startPosition.row + 1,
|
|
570
|
+
endLine: child.endPosition.row + 1
|
|
551
571
|
});
|
|
552
572
|
symbolIndex.set(`${relativePath}::${className}`, classId);
|
|
553
573
|
walkFunctions(child, className, classId);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abhinav2203/codeflow-core",
|
|
3
3
|
"description": "Framework-agnostic CodeFlow analysis core for blueprint generation, repository analysis, exports, and conflict detection.",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|