@aiready/visualizer 0.1.0 → 0.1.3
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/cli.js +272 -96
- package/dist/cli.js.map +1 -1
- package/dist/graph/index.d.ts +23 -8
- package/dist/graph/index.js +274 -118
- package/dist/graph/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +274 -118
- package/dist/index.js.map +1 -1
- package/package.json +12 -4
- package/web/dist/assets/index-D7ntVmj0.js +49 -0
- package/web/dist/assets/index-bqNDd5sg.css +1 -0
- package/web/dist/index.html +13 -0
package/dist/graph/index.js
CHANGED
|
@@ -1,127 +1,283 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
1
4
|
// src/graph/builder.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
totalFiles: nodes.length,
|
|
15
|
-
totalDependencies: edges.length,
|
|
16
|
-
analysisTypes: [],
|
|
17
|
-
criticalIssues: 0,
|
|
18
|
-
majorIssues: 0,
|
|
19
|
-
minorIssues: 0,
|
|
20
|
-
infoIssues: 0
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function createSampleGraph() {
|
|
25
|
-
const nodes = [
|
|
26
|
-
{
|
|
27
|
-
id: "file1",
|
|
28
|
-
path: "src/components/Button.tsx",
|
|
29
|
-
label: "Button",
|
|
30
|
-
linesOfCode: 120,
|
|
31
|
-
tokenCost: 450,
|
|
32
|
-
domain: "components",
|
|
33
|
-
moduleType: "component",
|
|
34
|
-
color: "#3b82f6",
|
|
35
|
-
size: 15
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
id: "file2",
|
|
39
|
-
path: "src/utils/helpers.ts",
|
|
40
|
-
label: "helpers",
|
|
41
|
-
linesOfCode: 80,
|
|
42
|
-
tokenCost: 300,
|
|
43
|
-
domain: "utils",
|
|
44
|
-
moduleType: "util",
|
|
45
|
-
color: "#10b981",
|
|
46
|
-
size: 12
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
id: "file3",
|
|
50
|
-
path: "src/services/api.ts",
|
|
51
|
-
label: "api",
|
|
52
|
-
linesOfCode: 200,
|
|
53
|
-
tokenCost: 750,
|
|
54
|
-
domain: "services",
|
|
55
|
-
moduleType: "service",
|
|
56
|
-
color: "#f59e0b",
|
|
57
|
-
size: 18
|
|
58
|
-
}
|
|
59
|
-
];
|
|
60
|
-
const edges = [
|
|
61
|
-
{
|
|
62
|
-
source: "file1",
|
|
63
|
-
target: "file2",
|
|
64
|
-
type: "import",
|
|
65
|
-
weight: 1
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
source: "file2",
|
|
69
|
-
target: "file3",
|
|
70
|
-
type: "import",
|
|
71
|
-
weight: 1
|
|
5
|
+
var GraphBuilder = class _GraphBuilder {
|
|
6
|
+
constructor(rootDir = process.cwd()) {
|
|
7
|
+
this.rootDir = rootDir;
|
|
8
|
+
this.nodesMap = /* @__PURE__ */ new Map();
|
|
9
|
+
this.edges = [];
|
|
10
|
+
this.edgesSet = /* @__PURE__ */ new Set();
|
|
11
|
+
}
|
|
12
|
+
normalizeLabel(filePath) {
|
|
13
|
+
try {
|
|
14
|
+
return path.relative(this.rootDir, filePath);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
return filePath;
|
|
72
17
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
18
|
+
}
|
|
19
|
+
extractReferencedPaths(message) {
|
|
20
|
+
if (!message || typeof message !== "string") return [];
|
|
21
|
+
const reAbs = /\/(?:[\w\-.]+\/)+[\w\-.]+\.(?:ts|tsx|js|jsx|py|java|go)/g;
|
|
22
|
+
const reRel = /(?:\.\/|\.\.\/)(?:[\w\-.]+\/)+[\w\-.]+\.(?:ts|tsx|js|jsx|py|java|go)/g;
|
|
23
|
+
const abs = message.match(reAbs) || [];
|
|
24
|
+
const rel = message.match(reRel) || [];
|
|
25
|
+
return abs.concat(rel);
|
|
26
|
+
}
|
|
27
|
+
getPackageGroup(fp) {
|
|
28
|
+
if (!fp) return null;
|
|
29
|
+
const parts = fp.split(path.sep);
|
|
30
|
+
const pkgIdx = parts.indexOf("packages");
|
|
31
|
+
if (pkgIdx >= 0 && parts.length > pkgIdx + 1) return `packages/${parts[pkgIdx + 1]}`;
|
|
32
|
+
const landingIdx = parts.indexOf("landing");
|
|
33
|
+
if (landingIdx >= 0) return "landing";
|
|
34
|
+
const scriptsIdx = parts.indexOf("scripts");
|
|
35
|
+
if (scriptsIdx >= 0) return "scripts";
|
|
36
|
+
return parts.length > 1 ? parts[1] : parts[0];
|
|
37
|
+
}
|
|
38
|
+
addNode(file, title = "", value = 1) {
|
|
39
|
+
if (!file) return;
|
|
40
|
+
const id = path.resolve(this.rootDir, file);
|
|
41
|
+
if (!this.nodesMap.has(id)) {
|
|
42
|
+
const node = {
|
|
43
|
+
id,
|
|
44
|
+
path: id,
|
|
45
|
+
label: this.normalizeLabel(id),
|
|
46
|
+
title,
|
|
47
|
+
size: value || 1
|
|
48
|
+
};
|
|
49
|
+
this.nodesMap.set(id, node);
|
|
50
|
+
} else {
|
|
51
|
+
const node = this.nodesMap.get(id);
|
|
52
|
+
if (title && (!node.title || !node.title.includes(title))) {
|
|
53
|
+
node.title = (node.title ? node.title + "\n" : "") + title;
|
|
54
|
+
}
|
|
55
|
+
if (value > (node.size || 0)) node.size = value;
|
|
92
56
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
57
|
+
}
|
|
58
|
+
addEdge(from, to, type = "link") {
|
|
59
|
+
if (!from || !to) return;
|
|
60
|
+
const a = path.resolve(this.rootDir, from);
|
|
61
|
+
const b = path.resolve(this.rootDir, to);
|
|
62
|
+
if (a === b) return;
|
|
63
|
+
const key = `${a}->${b}`;
|
|
64
|
+
if (!this.edgesSet.has(key)) {
|
|
65
|
+
this.edges.push({ source: a, target: b, type });
|
|
66
|
+
this.edgesSet.add(key);
|
|
102
67
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Build final GraphData
|
|
71
|
+
*/
|
|
72
|
+
build() {
|
|
73
|
+
const nodes = Array.from(this.nodesMap.values());
|
|
74
|
+
const edges = this.edges.map((e) => ({ source: e.source, target: e.target, type: e.type }));
|
|
75
|
+
return {
|
|
76
|
+
nodes,
|
|
77
|
+
edges,
|
|
78
|
+
clusters: [],
|
|
79
|
+
issues: [],
|
|
80
|
+
metadata: {
|
|
81
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
82
|
+
totalFiles: nodes.length,
|
|
83
|
+
totalDependencies: edges.length,
|
|
84
|
+
analysisTypes: [],
|
|
85
|
+
criticalIssues: 0,
|
|
86
|
+
majorIssues: 0,
|
|
87
|
+
minorIssues: 0,
|
|
88
|
+
infoIssues: 0
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)
|
|
94
|
+
*/
|
|
95
|
+
static buildFromReport(report, rootDir = process.cwd()) {
|
|
96
|
+
const builder = new _GraphBuilder(rootDir);
|
|
97
|
+
const fileIssues = /* @__PURE__ */ new Map();
|
|
98
|
+
const rankSeverity = (s) => {
|
|
99
|
+
if (!s) return null;
|
|
100
|
+
const ss = String(s).toLowerCase();
|
|
101
|
+
if (ss.includes("critical")) return "critical";
|
|
102
|
+
if (ss.includes("major")) return "major";
|
|
103
|
+
if (ss.includes("minor")) return "minor";
|
|
104
|
+
if (ss.includes("info")) return "info";
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
const bumpIssue = (file, sev) => {
|
|
108
|
+
if (!file) return;
|
|
109
|
+
const id = path.resolve(rootDir, file);
|
|
110
|
+
if (!fileIssues.has(id)) fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
111
|
+
const rec = fileIssues.get(id);
|
|
112
|
+
rec.count += 1;
|
|
113
|
+
if (sev) {
|
|
114
|
+
const order = { critical: 3, major: 2, minor: 1, info: 0 };
|
|
115
|
+
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity]) rec.maxSeverity = sev;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const basenameMap = /* @__PURE__ */ new Map();
|
|
119
|
+
(report.patterns || []).forEach((p) => {
|
|
120
|
+
const base = path.basename(p.fileName);
|
|
121
|
+
if (!basenameMap.has(base)) basenameMap.set(base, /* @__PURE__ */ new Set());
|
|
122
|
+
basenameMap.get(base).add(p.fileName);
|
|
123
|
+
});
|
|
124
|
+
(report.patterns || []).forEach((entry) => {
|
|
125
|
+
const file = entry.fileName;
|
|
126
|
+
builder.addNode(file, `Issues: ${(entry.issues || []).length}`, entry.metrics && entry.metrics.tokenCost || 5);
|
|
127
|
+
if ((entry.issues || []).length > 0) {
|
|
128
|
+
(entry.issues || []).forEach((issue) => {
|
|
129
|
+
const sev = rankSeverity(issue.severity || issue.severityLevel || null);
|
|
130
|
+
bumpIssue(file, sev);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
(entry.issues || []).forEach((issue) => {
|
|
134
|
+
const message = issue.message || "";
|
|
135
|
+
const refs = builder.extractReferencedPaths(message);
|
|
136
|
+
refs.forEach((ref) => {
|
|
137
|
+
let target = ref;
|
|
138
|
+
if (!path.isAbsolute(ref)) {
|
|
139
|
+
target = path.resolve(path.dirname(file), ref);
|
|
140
|
+
}
|
|
141
|
+
builder.addNode(target, "Referenced file", 5);
|
|
142
|
+
builder.addEdge(file, target, "reference");
|
|
143
|
+
});
|
|
144
|
+
const percMatch = (message.match(/(\d+)%/) || [])[1];
|
|
145
|
+
const perc = percMatch ? parseInt(percMatch, 10) : null;
|
|
146
|
+
const wantFuzzy = issue.type === "duplicate-pattern" || /similar/i.test(message) || perc && perc >= 50;
|
|
147
|
+
if (wantFuzzy) {
|
|
148
|
+
const fileGroup = builder.getPackageGroup(file);
|
|
149
|
+
for (const [base, pathsSet] of basenameMap.entries()) {
|
|
150
|
+
if (!message.includes(base) || base === path.basename(file)) continue;
|
|
151
|
+
for (const target of pathsSet) {
|
|
152
|
+
const targetGroup = builder.getPackageGroup(target);
|
|
153
|
+
if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;
|
|
154
|
+
builder.addNode(target, "Fuzzy match", 5);
|
|
155
|
+
builder.addEdge(file, target, "similarity");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
(report.duplicates || []).forEach((dup) => {
|
|
162
|
+
builder.addNode(dup.file1, "Similarity target", 5);
|
|
163
|
+
builder.addNode(dup.file2, "Similarity target", 5);
|
|
164
|
+
builder.addEdge(dup.file1, dup.file2, "similarity");
|
|
165
|
+
const f1 = path.resolve(rootDir, dup.file1);
|
|
166
|
+
const f2 = path.resolve(rootDir, dup.file2);
|
|
167
|
+
if (!fileIssues.has(f1)) fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
168
|
+
if (!fileIssues.has(f2)) fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
169
|
+
fileIssues.get(f1).duplicates += 1;
|
|
170
|
+
fileIssues.get(f2).duplicates += 1;
|
|
171
|
+
});
|
|
172
|
+
(report.context || []).forEach((ctx) => {
|
|
173
|
+
const file = ctx.file;
|
|
174
|
+
builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
|
|
175
|
+
if (ctx.issues && Array.isArray(ctx.issues)) {
|
|
176
|
+
ctx.issues.forEach((issue) => {
|
|
177
|
+
const sev = rankSeverity(issue.severity || issue.severityLevel || null);
|
|
178
|
+
bumpIssue(file, sev);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
(ctx.relatedFiles || []).forEach((rel) => {
|
|
182
|
+
const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);
|
|
183
|
+
const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;
|
|
184
|
+
const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;
|
|
185
|
+
if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB)) return;
|
|
186
|
+
builder.addNode(resolvedRel, "Related file", 5);
|
|
187
|
+
const n = builder.nodesMap.get(path.resolve(builder.rootDir, resolvedRel));
|
|
188
|
+
if (n) n.size = (n.size || 1) + 2;
|
|
189
|
+
});
|
|
190
|
+
const fileDir = path.dirname(file);
|
|
191
|
+
(ctx.dependencyList || []).forEach((dep) => {
|
|
192
|
+
if (dep.startsWith(".")) {
|
|
193
|
+
const possiblePaths = [
|
|
194
|
+
path.resolve(fileDir, dep),
|
|
195
|
+
path.resolve(fileDir, dep + ".ts"),
|
|
196
|
+
path.resolve(fileDir, dep + ".tsx"),
|
|
197
|
+
path.resolve(fileDir, dep + ".js"),
|
|
198
|
+
path.resolve(fileDir, dep, "index.ts"),
|
|
199
|
+
path.resolve(fileDir, dep, "index.tsx")
|
|
200
|
+
];
|
|
201
|
+
for (const p of possiblePaths) {
|
|
202
|
+
if (fs.existsSync(p)) {
|
|
203
|
+
builder.addNode(p, "Dependency", 2);
|
|
204
|
+
builder.addEdge(file, p, "dependency");
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
const nodes = Array.from(builder.nodesMap.values());
|
|
212
|
+
const edges = builder.edges;
|
|
213
|
+
const colorFor = (sev) => {
|
|
214
|
+
switch (sev) {
|
|
215
|
+
case "critical":
|
|
216
|
+
return "#ff4d4f";
|
|
217
|
+
// red
|
|
218
|
+
case "major":
|
|
219
|
+
return "#ff9900";
|
|
220
|
+
// orange
|
|
221
|
+
case "minor":
|
|
222
|
+
return "#ffd666";
|
|
223
|
+
// yellow
|
|
224
|
+
case "info":
|
|
225
|
+
return "#91d5ff";
|
|
226
|
+
// light blue
|
|
227
|
+
default:
|
|
228
|
+
return "#97c2fc";
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
let criticalIssues = 0;
|
|
232
|
+
let majorIssues = 0;
|
|
233
|
+
let minorIssues = 0;
|
|
234
|
+
let infoIssues = 0;
|
|
235
|
+
for (const node of nodes) {
|
|
236
|
+
const n = node;
|
|
237
|
+
const rec = fileIssues.get(n.id);
|
|
238
|
+
if (rec) {
|
|
239
|
+
n.duplicates = rec.duplicates || 0;
|
|
240
|
+
n.color = colorFor(rec.maxSeverity);
|
|
241
|
+
n.group = builder.getPackageGroup(n.id) || void 0;
|
|
242
|
+
if (rec.maxSeverity === "critical") criticalIssues += rec.count;
|
|
243
|
+
else if (rec.maxSeverity === "major") majorIssues += rec.count;
|
|
244
|
+
else if (rec.maxSeverity === "minor") minorIssues += rec.count;
|
|
245
|
+
else if (rec.maxSeverity === "info") infoIssues += rec.count;
|
|
246
|
+
} else {
|
|
247
|
+
n.color = colorFor(null);
|
|
248
|
+
n.group = builder.getPackageGroup(n.id) || void 0;
|
|
249
|
+
n.duplicates = 0;
|
|
250
|
+
}
|
|
121
251
|
}
|
|
122
|
-
|
|
252
|
+
const graph = {
|
|
253
|
+
nodes,
|
|
254
|
+
edges,
|
|
255
|
+
clusters: [],
|
|
256
|
+
issues: [],
|
|
257
|
+
metadata: {
|
|
258
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
259
|
+
totalFiles: nodes.length,
|
|
260
|
+
totalDependencies: edges.length,
|
|
261
|
+
analysisTypes: [],
|
|
262
|
+
criticalIssues,
|
|
263
|
+
majorIssues,
|
|
264
|
+
minorIssues,
|
|
265
|
+
infoIssues
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
return graph;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
function createSampleGraph() {
|
|
272
|
+
const builder = new GraphBuilder(process.cwd());
|
|
273
|
+
builder.addNode("src/components/Button.tsx", "Button", 15);
|
|
274
|
+
builder.addNode("src/utils/helpers.ts", "helpers", 12);
|
|
275
|
+
builder.addNode("src/services/api.ts", "api", 18);
|
|
276
|
+
builder.addEdge("src/components/Button.tsx", "src/utils/helpers.ts", "dependency");
|
|
277
|
+
builder.addEdge("src/utils/helpers.ts", "src/services/api.ts", "dependency");
|
|
278
|
+
return builder.build();
|
|
123
279
|
}
|
|
124
280
|
|
|
125
|
-
export {
|
|
281
|
+
export { GraphBuilder, createSampleGraph };
|
|
126
282
|
//# sourceMappingURL=index.js.map
|
|
127
283
|
//# sourceMappingURL=index.js.map
|
package/dist/graph/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/graph/builder.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Graph builder - transforms AIReady analysis results into graph data\n */\n\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\n Cluster,\n IssueOverlay,\n IssueSeverity,\n} from '../types';\n\n/**\n * Build graph data from AIReady analysis results\n * This is a placeholder that will be expanded to handle real analysis data\n */\nexport function buildGraph(analysisResults: any): GraphData {\n const nodes: FileNode[] = [];\n const edges: DependencyEdge[] = [];\n const clusters: Cluster[] = [];\n const issues: IssueOverlay[] = [];\n\n // TODO: Parse analysis results and build graph\n // For now, return empty graph structure\n \n return {\n nodes,\n edges,\n clusters,\n issues,\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 0,\n infoIssues: 0,\n },\n };\n}\n\n/**\n * Create a sample graph for testing\n */\nexport function createSampleGraph(): GraphData {\n const nodes: FileNode[] = [\n {\n id: 'file1',\n path: 'src/components/Button.tsx',\n label: 'Button',\n linesOfCode: 120,\n tokenCost: 450,\n domain: 'components',\n moduleType: 'component',\n color: '#3b82f6',\n size: 15,\n },\n {\n id: 'file2',\n path: 'src/utils/helpers.ts',\n label: 'helpers',\n linesOfCode: 80,\n tokenCost: 300,\n domain: 'utils',\n moduleType: 'util',\n color: '#10b981',\n size: 12,\n },\n {\n id: 'file3',\n path: 'src/services/api.ts',\n label: 'api',\n linesOfCode: 200,\n tokenCost: 750,\n domain: 'services',\n moduleType: 'service',\n color: '#f59e0b',\n size: 18,\n },\n ];\n\n const edges: DependencyEdge[] = [\n {\n source: 'file1',\n target: 'file2',\n type: 'import',\n weight: 1,\n },\n {\n source: 'file2',\n target: 'file3',\n type: 'import',\n weight: 1,\n },\n ];\n\n const clusters: Cluster[] = [\n {\n id: 'cluster1',\n name: 'Components',\n nodeIds: ['file1'],\n color: '#3b82f6',\n },\n {\n id: 'cluster2',\n name: 'Utils',\n nodeIds: ['file2'],\n color: '#10b981',\n },\n {\n id: 'cluster3',\n name: 'Services',\n nodeIds: ['file3'],\n color: '#f59e0b',\n },\n ];\n\n const issues: IssueOverlay[] = [\n {\n id: 'issue1',\n type: 'high-cost',\n severity: 'minor',\n nodeIds: ['file3'],\n message: 'High token cost detected',\n details: 'This file has a token cost of 750, consider refactoring',\n },\n ];\n\n return {\n nodes,\n edges,\n clusters,\n issues,\n metadata: {\n projectName: 'Sample Project',\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: ['sample'],\n totalLinesOfCode: 400,\n totalTokenCost: 1500,\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 1,\n infoIssues: 0,\n },\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/graph/builder.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Graph builder - transforms AIReady analysis results into graph data\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\n Cluster,\n IssueOverlay,\n IssueSeverity,\n} from '../types';\n\n/**\n * GraphBuilder: programmatic builder and report-based builder\n */\nexport class GraphBuilder {\n rootDir: string;\n private nodesMap: Map<string, FileNode>;\n private edges: DependencyEdge[];\n private edgesSet: Set<string>;\n\n constructor(rootDir = process.cwd()) {\n this.rootDir = rootDir;\n this.nodesMap = new Map();\n this.edges = [];\n this.edgesSet = new Set();\n }\n\n private normalizeLabel(filePath: string) {\n try {\n return path.relative(this.rootDir, filePath);\n } catch (e) {\n return filePath;\n }\n }\n\n private extractReferencedPaths(message: string): string[] {\n if (!message || typeof message !== 'string') return [];\n const reAbs = /\\/(?:[\\w\\-.]+\\/)+[\\w\\-.]+\\.(?:ts|tsx|js|jsx|py|java|go)/g;\n const reRel = /(?:\\.\\/|\\.\\.\\/)(?:[\\w\\-.]+\\/)+[\\w\\-.]+\\.(?:ts|tsx|js|jsx|py|java|go)/g;\n const abs = (message.match(reAbs) || []) as string[];\n const rel = (message.match(reRel) || []) as string[];\n return abs.concat(rel);\n }\n\n private getPackageGroup(fp?: string | null) {\n if (!fp) return null;\n const parts = fp.split(path.sep);\n const pkgIdx = parts.indexOf('packages');\n if (pkgIdx >= 0 && parts.length > pkgIdx + 1) return `packages/${parts[pkgIdx + 1]}`;\n const landingIdx = parts.indexOf('landing');\n if (landingIdx >= 0) return 'landing';\n const scriptsIdx = parts.indexOf('scripts');\n if (scriptsIdx >= 0) return 'scripts';\n return parts.length > 1 ? parts[1] : parts[0];\n }\n\n addNode(file: string, title = '', value = 1) {\n if (!file) return;\n const id = path.resolve(this.rootDir, file);\n if (!this.nodesMap.has(id)) {\n const node = {\n id,\n path: id,\n label: this.normalizeLabel(id),\n title,\n size: value || 1,\n } as any;\n this.nodesMap.set(id, node as FileNode);\n } else {\n const node = this.nodesMap.get(id)! as any;\n if (title && (!node.title || !node.title.includes(title))) {\n node.title = (node.title ? node.title + '\\n' : '') + title;\n }\n if (value > (node.size || 0)) node.size = value;\n }\n }\n\n addEdge(from: string, to: string, type: string = 'link') {\n if (!from || !to) return;\n const a = path.resolve(this.rootDir, from);\n const b = path.resolve(this.rootDir, to);\n if (a === b) return;\n const key = `${a}->${b}`;\n if (!this.edgesSet.has(key)) {\n this.edges.push({ source: a, target: b, type: (type as any) });\n this.edgesSet.add(key);\n }\n }\n\n /**\n * Build final GraphData\n */\n build(): GraphData {\n const nodes = Array.from(this.nodesMap.values());\n const edges = this.edges.map((e) => ({ source: e.source, target: e.target, type: e.type } as DependencyEdge));\n return {\n nodes,\n edges,\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 0,\n infoIssues: 0,\n },\n };\n }\n\n /**\n * Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)\n */\n static buildFromReport(report: any, rootDir = process.cwd()): GraphData {\n const builder = new GraphBuilder(rootDir);\n\n // Map to collect per-file issue aggregates\n const fileIssues: Map<string, { count: number; maxSeverity: IssueSeverity | null; duplicates: number }> = new Map();\n\n const rankSeverity = (s?: string | null): IssueSeverity | null => {\n if (!s) return null;\n const ss = String(s).toLowerCase();\n if (ss.includes('critical')) return 'critical';\n if (ss.includes('major')) return 'major';\n if (ss.includes('minor')) return 'minor';\n if (ss.includes('info')) return 'info';\n return null;\n };\n\n const bumpIssue = (file: string, sev?: IssueSeverity | null) => {\n if (!file) return;\n const id = path.resolve(rootDir, file);\n if (!fileIssues.has(id)) fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });\n const rec = fileIssues.get(id)!;\n rec.count += 1;\n if (sev) {\n const order = { critical: 3, major: 2, minor: 1, info: 0 } as Record<IssueSeverity, number>;\n if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity]) rec.maxSeverity = sev;\n }\n };\n\n // Pre-scan for basenames\n const basenameMap = new Map<string, Set<string>>();\n (report.patterns || []).forEach((p: any) => {\n const base = path.basename(p.fileName);\n if (!basenameMap.has(base)) basenameMap.set(base, new Set());\n basenameMap.get(base)!.add(p.fileName);\n });\n\n // 1. Process patterns\n (report.patterns || []).forEach((entry: any) => {\n const file = entry.fileName;\n builder.addNode(file, `Issues: ${(entry.issues || []).length}`, (entry.metrics && entry.metrics.tokenCost) || 5);\n\n // record aggregate for this file\n if ((entry.issues || []).length > 0) {\n (entry.issues || []).forEach((issue: any) => {\n const sev = rankSeverity(issue.severity || issue.severityLevel || null);\n bumpIssue(file, sev);\n });\n }\n\n (entry.issues || []).forEach((issue: any) => {\n const message = issue.message || '';\n\n // Path extraction\n const refs = builder.extractReferencedPaths(message);\n refs.forEach((ref) => {\n let target = ref;\n if (!path.isAbsolute(ref)) {\n target = path.resolve(path.dirname(file), ref);\n }\n builder.addNode(target, 'Referenced file', 5);\n builder.addEdge(file, target, 'reference');\n });\n\n // Fuzzy matching heuristics\n const percMatch = (message.match(/(\\d+)%/) || [])[1];\n const perc = percMatch ? parseInt(percMatch, 10) : null;\n const wantFuzzy = issue.type === 'duplicate-pattern' || /similar/i.test(message) || (perc && perc >= 50);\n if (wantFuzzy) {\n const fileGroup = builder.getPackageGroup(file as any);\n for (const [base, pathsSet] of basenameMap.entries()) {\n if (!message.includes(base) || base === path.basename(file)) continue;\n for (const target of pathsSet) {\n const targetGroup = builder.getPackageGroup(target as any);\n if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;\n builder.addNode(target, 'Fuzzy match', 5);\n builder.addEdge(file, target, 'similarity');\n }\n }\n }\n });\n });\n\n // 2. Duplicates\n (report.duplicates || []).forEach((dup: any) => {\n builder.addNode(dup.file1, 'Similarity target', 5);\n builder.addNode(dup.file2, 'Similarity target', 5);\n builder.addEdge(dup.file1, dup.file2, 'similarity');\n // count duplicates as issues (no explicit severity available)\n const f1 = path.resolve(rootDir, dup.file1);\n const f2 = path.resolve(rootDir, dup.file2);\n if (!fileIssues.has(f1)) fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });\n if (!fileIssues.has(f2)) fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });\n fileIssues.get(f1)!.duplicates += 1;\n fileIssues.get(f2)!.duplicates += 1;\n });\n\n // 3. Context: dependencies and related files\n (report.context || []).forEach((ctx: any) => {\n const file = ctx.file;\n builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);\n\n // context-level issues\n if (ctx.issues && Array.isArray(ctx.issues)) {\n ctx.issues.forEach((issue: any) => {\n const sev = rankSeverity(issue.severity || issue.severityLevel || null);\n bumpIssue(file, sev);\n });\n }\n\n // Add related files: do not create visual edges for 'related' links to\n // avoid clutter. Instead, increase the related node's prominence so the\n // layout reflects contextual proximity without extra lines.\n (ctx.relatedFiles || []).forEach((rel: string) => {\n const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);\n const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;\n const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;\n if ((builder as any).edgesSet.has(keyA) || (builder as any).edgesSet.has(keyB)) return;\n builder.addNode(resolvedRel, 'Related file', 5);\n // bump size to reflect relatedness\n const n = (builder as any).nodesMap.get(path.resolve(builder.rootDir, resolvedRel));\n if (n) n.size = (n.size || 1) + 2;\n });\n\n const fileDir = path.dirname(file);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.')) {\n const possiblePaths = [\n path.resolve(fileDir, dep),\n path.resolve(fileDir, dep + '.ts'),\n path.resolve(fileDir, dep + '.tsx'),\n path.resolve(fileDir, dep + '.js'),\n path.resolve(fileDir, dep, 'index.ts'),\n path.resolve(fileDir, dep, 'index.tsx'),\n ];\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n builder.addNode(p, 'Dependency', 2);\n builder.addEdge(file, p, 'dependency');\n break;\n }\n }\n }\n });\n });\n\n // Finalize nodes: assign colors and duplicate counts based on collected issue data\n const nodes = Array.from((builder as any).nodesMap.values()) as FileNode[];\n const edges = (builder as any).edges as DependencyEdge[];\n\n // Color mapping by highest severity\n const colorFor = (sev: IssueSeverity | null) => {\n switch (sev) {\n case 'critical':\n return '#ff4d4f'; // red\n case 'major':\n return '#ff9900'; // orange\n case 'minor':\n return '#ffd666'; // yellow\n case 'info':\n return '#91d5ff'; // light blue\n default:\n return '#97c2fc'; // default blue\n }\n };\n\n // Populate node-level visual props and metadata counters\n let criticalIssues = 0;\n let majorIssues = 0;\n let minorIssues = 0;\n let infoIssues = 0;\n\n for (const node of nodes) {\n const n = node as any;\n const rec = fileIssues.get(n.id);\n if (rec) {\n n.duplicates = rec.duplicates || 0;\n // choose color by maxSeverity\n n.color = colorFor(rec.maxSeverity);\n // assign package group for boundary drawing\n n.group = builder.getPackageGroup(n.id as any) || undefined;\n // increment metadata counts by severity seen on this file\n if (rec.maxSeverity === 'critical') criticalIssues += rec.count;\n else if (rec.maxSeverity === 'major') majorIssues += rec.count;\n else if (rec.maxSeverity === 'minor') minorIssues += rec.count;\n else if (rec.maxSeverity === 'info') infoIssues += rec.count;\n } else {\n n.color = colorFor(null);\n n.group = builder.getPackageGroup(n.id as any) || undefined;\n n.duplicates = 0;\n }\n }\n\n const graph: GraphData = {\n nodes,\n edges,\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues,\n majorIssues,\n minorIssues,\n infoIssues,\n },\n };\n\n return graph;\n }\n}\n\nexport function createSampleGraph(): GraphData {\n const builder = new GraphBuilder(process.cwd());\n builder.addNode('src/components/Button.tsx', 'Button', 15);\n builder.addNode('src/utils/helpers.ts', 'helpers', 12);\n builder.addNode('src/services/api.ts', 'api', 18);\n builder.addEdge('src/components/Button.tsx', 'src/utils/helpers.ts', 'dependency');\n builder.addEdge('src/utils/helpers.ts', 'src/services/api.ts', 'dependency');\n return builder.build();\n}"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { BaseGraphLink, BaseGraphNode, Cluster, DependencyEdge, FileNode, FilterOptions, GraphData, GraphMetadata, IssueOverlay, IssueSeverity, LayoutConfig, VisualizationConfig,
|
|
1
|
+
export { BaseGraphLink, BaseGraphNode, Cluster, DependencyEdge, FileNode, FilterOptions, GraphBuilder, GraphData, GraphMetadata, IssueOverlay, IssueSeverity, LayoutConfig, VisualizationConfig, createSampleGraph } from './graph/index.js';
|