@aiready/visualizer 0.1.37 → 0.1.38
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 +46 -17
- package/dist/cli.js.map +1 -1
- package/dist/graph/index.js +36 -13
- package/dist/graph/index.js.map +1 -1
- package/dist/index.js +36 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/web/dist/assets/{index-C9b__qGk.js → index-5leRjvmV.js} +1 -1
- package/web/dist/index.html +2 -2
- package/web/dist/report-data.json +224 -742
- package/web/index.html +1 -1
- package/web/package.json +1 -1
- package/web/public/report-data.json +224 -742
- package/web/src/App.tsx +61 -47
- package/web/src/components/ErrorDisplay.tsx +31 -17
- package/web/src/components/GraphCanvas.tsx +90 -24
- package/web/src/components/LegendPanel.tsx +242 -139
- package/web/src/components/LoadingSpinner.tsx +6 -3
- package/web/src/components/Navbar.tsx +66 -52
- package/web/src/components/NodeDetails.tsx +98 -68
- package/web/src/hooks/useTheme.ts +5 -2
- package/web/src/main.tsx +1 -1
- package/web/src/style.css +14 -2
- package/web/src/styles/index.css +7 -5
- package/web/src/utils.ts +86 -25
- package/web/tsconfig.json +1 -1
- package/web/vite.config.ts +9 -4
package/dist/cli.js
CHANGED
|
@@ -32,7 +32,8 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
32
32
|
if (!fp) return null;
|
|
33
33
|
const parts = fp.split(path.sep);
|
|
34
34
|
const pkgIdx = parts.indexOf("packages");
|
|
35
|
-
if (pkgIdx >= 0 && parts.length > pkgIdx + 1)
|
|
35
|
+
if (pkgIdx >= 0 && parts.length > pkgIdx + 1)
|
|
36
|
+
return `packages/${parts[pkgIdx + 1]}`;
|
|
36
37
|
const landingIdx = parts.indexOf("landing");
|
|
37
38
|
if (landingIdx >= 0) return "landing";
|
|
38
39
|
const scriptsIdx = parts.indexOf("scripts");
|
|
@@ -75,7 +76,9 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
75
76
|
*/
|
|
76
77
|
build() {
|
|
77
78
|
const nodes = Array.from(this.nodesMap.values());
|
|
78
|
-
const edges = this.edges.map(
|
|
79
|
+
const edges = this.edges.map(
|
|
80
|
+
(e) => ({ source: e.source, target: e.target, type: e.type })
|
|
81
|
+
);
|
|
79
82
|
return {
|
|
80
83
|
nodes,
|
|
81
84
|
edges,
|
|
@@ -111,12 +114,14 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
111
114
|
const bumpIssue = (file, sev) => {
|
|
112
115
|
if (!file) return;
|
|
113
116
|
const id = path.resolve(rootDir, file);
|
|
114
|
-
if (!fileIssues.has(id))
|
|
117
|
+
if (!fileIssues.has(id))
|
|
118
|
+
fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
115
119
|
const rec = fileIssues.get(id);
|
|
116
120
|
rec.count += 1;
|
|
117
121
|
if (sev) {
|
|
118
122
|
const order = { critical: 3, major: 2, minor: 1, info: 0 };
|
|
119
|
-
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
123
|
+
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
124
|
+
rec.maxSeverity = sev;
|
|
120
125
|
}
|
|
121
126
|
};
|
|
122
127
|
const basenameMap = /* @__PURE__ */ new Map();
|
|
@@ -127,10 +132,16 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
127
132
|
});
|
|
128
133
|
(report.patterns || []).forEach((entry) => {
|
|
129
134
|
const file = entry.fileName;
|
|
130
|
-
builder.addNode(
|
|
135
|
+
builder.addNode(
|
|
136
|
+
file,
|
|
137
|
+
`Issues: ${(entry.issues || []).length}`,
|
|
138
|
+
entry.metrics && entry.metrics.tokenCost || 5
|
|
139
|
+
);
|
|
131
140
|
if ((entry.issues || []).length > 0) {
|
|
132
141
|
(entry.issues || []).forEach((issue) => {
|
|
133
|
-
const sev = rankSeverity(
|
|
142
|
+
const sev = rankSeverity(
|
|
143
|
+
issue.severity || issue.severityLevel || null
|
|
144
|
+
);
|
|
134
145
|
bumpIssue(file, sev);
|
|
135
146
|
});
|
|
136
147
|
}
|
|
@@ -151,7 +162,8 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
151
162
|
if (wantFuzzy) {
|
|
152
163
|
const fileGroup = builder.getPackageGroup(file);
|
|
153
164
|
for (const [base, pathsSet] of basenameMap.entries()) {
|
|
154
|
-
if (!message.includes(base) || base === path.basename(file))
|
|
165
|
+
if (!message.includes(base) || base === path.basename(file))
|
|
166
|
+
continue;
|
|
155
167
|
for (const target of pathsSet) {
|
|
156
168
|
const targetGroup = builder.getPackageGroup(target);
|
|
157
169
|
if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;
|
|
@@ -168,8 +180,10 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
168
180
|
builder.addEdge(dup.file1, dup.file2, "similarity");
|
|
169
181
|
const f1 = path.resolve(rootDir, dup.file1);
|
|
170
182
|
const f2 = path.resolve(rootDir, dup.file2);
|
|
171
|
-
if (!fileIssues.has(f1))
|
|
172
|
-
|
|
183
|
+
if (!fileIssues.has(f1))
|
|
184
|
+
fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
185
|
+
if (!fileIssues.has(f2))
|
|
186
|
+
fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
173
187
|
fileIssues.get(f1).duplicates += 1;
|
|
174
188
|
fileIssues.get(f2).duplicates += 1;
|
|
175
189
|
});
|
|
@@ -178,7 +192,9 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
178
192
|
builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
|
|
179
193
|
if (ctx.issues && Array.isArray(ctx.issues)) {
|
|
180
194
|
ctx.issues.forEach((issue) => {
|
|
181
|
-
const sev = rankSeverity(
|
|
195
|
+
const sev = rankSeverity(
|
|
196
|
+
issue.severity || issue.severityLevel || null
|
|
197
|
+
);
|
|
182
198
|
bumpIssue(file, sev);
|
|
183
199
|
});
|
|
184
200
|
}
|
|
@@ -186,9 +202,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
186
202
|
const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);
|
|
187
203
|
const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;
|
|
188
204
|
const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;
|
|
189
|
-
if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB))
|
|
205
|
+
if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB))
|
|
206
|
+
return;
|
|
190
207
|
builder.addNode(resolvedRel, "Related file", 5);
|
|
191
|
-
const n = builder.nodesMap.get(
|
|
208
|
+
const n = builder.nodesMap.get(
|
|
209
|
+
path.resolve(builder.rootDir, resolvedRel)
|
|
210
|
+
);
|
|
192
211
|
if (n) n.size = (n.size || 1) + 2;
|
|
193
212
|
try {
|
|
194
213
|
builder.addEdge(file, resolvedRel, "related");
|
|
@@ -297,7 +316,11 @@ function createSampleGraph() {
|
|
|
297
316
|
builder.addNode("src/components/Button.tsx", "Button", 15);
|
|
298
317
|
builder.addNode("src/utils/helpers.ts", "helpers", 12);
|
|
299
318
|
builder.addNode("src/services/api.ts", "api", 18);
|
|
300
|
-
builder.addEdge(
|
|
319
|
+
builder.addEdge(
|
|
320
|
+
"src/components/Button.tsx",
|
|
321
|
+
"src/utils/helpers.ts",
|
|
322
|
+
"dependency"
|
|
323
|
+
);
|
|
301
324
|
builder.addEdge("src/utils/helpers.ts", "src/services/api.ts", "dependency");
|
|
302
325
|
return builder.build();
|
|
303
326
|
}
|
|
@@ -305,7 +328,9 @@ var __filename$1 = fileURLToPath(import.meta.url);
|
|
|
305
328
|
var __dirname$1 = dirname(__filename$1);
|
|
306
329
|
var WEB_PORT = 8e3;
|
|
307
330
|
var program = new Command();
|
|
308
|
-
program.name("aiready-visualize").description(
|
|
331
|
+
program.name("aiready-visualize").description(
|
|
332
|
+
"Generate interactive visualizations from AIReady analysis results"
|
|
333
|
+
).version("0.1.0").option("-d, --dev", "Start interactive web application (default)", true).option("-o, --output <file>", "Output HTML file for static generation").passThroughOptions();
|
|
309
334
|
function startDevServer(rootDir) {
|
|
310
335
|
const webDir = resolve(__dirname$1, "../web");
|
|
311
336
|
console.log("\u{1F3AF} AIReady Visualizer");
|
|
@@ -336,8 +361,10 @@ program.command("sample").description("Generate a sample visualization for testi
|
|
|
336
361
|
const { exec } = await import('child_process');
|
|
337
362
|
console.log("Generating sample visualization...");
|
|
338
363
|
const graph = createSampleGraph();
|
|
339
|
-
console.log(
|
|
340
|
-
|
|
364
|
+
console.log(
|
|
365
|
+
`
|
|
366
|
+
Sample graph created with ${graph.nodes.length} nodes and ${graph.edges.length} edges`
|
|
367
|
+
);
|
|
341
368
|
const html = generateHTML(graph);
|
|
342
369
|
const outputPath = resolve(options.output);
|
|
343
370
|
writeFileSync(outputPath, html);
|
|
@@ -354,7 +381,9 @@ program.command("generate").description("Generate visualization from analysis re
|
|
|
354
381
|
const report = JSON.parse(readFileSync(input, "utf-8"));
|
|
355
382
|
const rootDir = process.cwd();
|
|
356
383
|
const graph = GraphBuilder.buildFromReport(report, rootDir);
|
|
357
|
-
console.log(
|
|
384
|
+
console.log(
|
|
385
|
+
`Graph built: ${graph.nodes.length} nodes, ${graph.edges.length} edges`
|
|
386
|
+
);
|
|
358
387
|
const html = generateHTML(graph);
|
|
359
388
|
const outputPath = resolve(options.output);
|
|
360
389
|
writeFileSync(outputPath, html);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graph/builder.ts","../src/cli/index.ts"],"names":["__filename","__dirname"],"mappings":"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","file":"cli.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 // Also add a visual 'related' edge so that built/packed visualizations\n // (which use this GraphBuilder) include related connections rather\n // than only bumping node prominence.\n try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch (e) {\n // ignore any edge errors\n }\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 // 4. Doc Drift\n (report.docDrift?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Doc-Drift Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // 5. Dependencies\n (report.deps?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Dependency Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\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}","#!/usr/bin/env node\n\n/**\n * CLI for AIReady Visualizer\n * \n * Usage:\n * aiready visualise # Start dev server (default)\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { GraphBuilder, createSampleGraph } from '../graph/builder';\nimport { generateHTML } from '@aiready/core';\nimport type { GraphData } from '../types';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst WEB_PORT = 8000;\n\nconst program = new Command();\n\nprogram\n .name('aiready-visualize')\n .description('Generate interactive visualizations from AIReady analysis results')\n .version('0.1.0')\n .option('-d, --dev', 'Start interactive web application (default)', true)\n .option('-o, --output <file>', 'Output HTML file for static generation')\n .passThroughOptions();\n\n/**\n * Start the interactive web dev server\n */\nfunction startDevServer(rootDir: string): void {\n const webDir = resolve(__dirname, '../web');\n \n console.log('🎯 AIReady Visualizer');\n console.log('🚀 Starting interactive web application...');\n console.log();\n console.log(`📁 Project root: ${rootDir}`);\n console.log(`🌐 Web server: http://localhost:${WEB_PORT}`);\n console.log();\n console.log('💡 The web app requires report data to visualize.');\n console.log(' Run \"pnpm aiready scan .\" then copy the report to:');\n console.log(` web/public/report-data.json`);\n console.log();\n console.log('Press Ctrl+C to stop the server.');\n console.log();\n\n // Start vite dev server\n const vite = spawn('pnpm', ['dev'], {\n cwd: webDir,\n stdio: 'inherit',\n shell: true,\n env: { ...process.env, FORCE_COLOR: '1' }\n });\n\n vite.on('error', (err) => {\n console.error('❌ Failed to start dev server:', err.message);\n process.exit(1);\n });\n}\n\n\nprogram\n .command('sample')\n .description('Generate a sample visualization for testing')\n .option('-o, --output <file>', 'Output HTML file', 'visualization.html')\n .option('--open', 'Open in browser')\n .action(async (options) => {\n const { writeFileSync } = await import('fs');\n const { exec } = await import('child_process');\n \n console.log('Generating sample visualization...');\n const graph = createSampleGraph();\n \n console.log(`\\nSample graph created with ${graph.nodes.length} nodes and ${graph.edges.length} edges`);\n \n const html = generateHTML(graph);\n const outputPath = resolve(options.output);\n writeFileSync(outputPath, html);\n \n console.log(`✅ HTML saved to: ${outputPath}`);\n \n if (options.open) {\n const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n exec(`${opener} \"${outputPath}\"`);\n }\n });\n\nprogram\n .command('generate')\n .description('Generate visualization from analysis results')\n .argument('<input>', 'Input JSON file with analysis results')\n .option('-o, --output <file>', 'Output HTML file', 'visualization.html')\n .option('--open', 'Open in browser')\n .action(async (input, options) => {\n const { readFileSync, writeFileSync } = await import('fs');\n const { exec } = await import('child_process');\n \n console.log(`Reading analysis results from: ${input}`);\n const report = JSON.parse(readFileSync(input, 'utf-8'));\n \n const rootDir = process.cwd();\n const graph = GraphBuilder.buildFromReport(report, rootDir);\n \n console.log(`Graph built: ${graph.nodes.length} nodes, ${graph.edges.length} edges`);\n \n const html = generateHTML(graph);\n const outputPath = resolve(options.output);\n writeFileSync(outputPath, html);\n \n console.log(`✅ HTML saved to: ${outputPath}`);\n \n if (options.open) {\n const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n exec(`${opener} \"${outputPath}\"`);\n }\n });\n\n// Handle default case: start dev server when no arguments provided\nconst args = process.argv.slice(2);\nif (args.length === 0 || (args.length === 1 && (args[0] === '--dev' || args[0] === '-d'))) {\n startDevServer(process.cwd());\n} else {\n program.parse();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graph/builder.ts","../src/cli/index.ts"],"names":["__filename","__dirname"],"mappings":"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","file":"cli.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 =\n /(?:\\.\\/|\\.\\.\\/)(?:[\\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)\n 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(\n (e) =>\n ({ source: e.source, target: e.target, type: e.type }) as DependencyEdge\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 * 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<\n string,\n { count: number; maxSeverity: IssueSeverity | null; duplicates: number }\n > = 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))\n 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<\n IssueSeverity,\n number\n >;\n if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])\n 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(\n file,\n `Issues: ${(entry.issues || []).length}`,\n (entry.metrics && entry.metrics.tokenCost) || 5\n );\n\n // record aggregate for this file\n if ((entry.issues || []).length > 0) {\n (entry.issues || []).forEach((issue: any) => {\n const sev = rankSeverity(\n issue.severity || issue.severityLevel || null\n );\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 =\n issue.type === 'duplicate-pattern' ||\n /similar/i.test(message) ||\n (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))\n 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))\n fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });\n if (!fileIssues.has(f2))\n 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(\n issue.severity || issue.severityLevel || null\n );\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)\n ? rel\n : 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 (\n (builder as any).edgesSet.has(keyA) ||\n (builder as any).edgesSet.has(keyB)\n )\n return;\n builder.addNode(resolvedRel, 'Related file', 5);\n // bump size to reflect relatedness\n const n = (builder as any).nodesMap.get(\n path.resolve(builder.rootDir, resolvedRel)\n );\n if (n) n.size = (n.size || 1) + 2;\n // Also add a visual 'related' edge so that built/packed visualizations\n // (which use this GraphBuilder) include related connections rather\n // than only bumping node prominence.\n try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch (e) {\n // ignore any edge errors\n }\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 // 4. Doc Drift\n (report.docDrift?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Doc-Drift Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // 5. Dependencies\n (report.deps?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Dependency Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\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(\n 'src/components/Button.tsx',\n 'src/utils/helpers.ts',\n 'dependency'\n );\n builder.addEdge('src/utils/helpers.ts', 'src/services/api.ts', 'dependency');\n return builder.build();\n}\n","#!/usr/bin/env node\n\n/**\n * CLI for AIReady Visualizer\n *\n * Usage:\n * aiready visualise # Start dev server (default)\n */\n\nimport { Command } from 'commander';\nimport { spawn } from 'child_process';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { GraphBuilder, createSampleGraph } from '../graph/builder';\nimport { generateHTML } from '@aiready/core';\nimport type { GraphData } from '../types';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst WEB_PORT = 8000;\n\nconst program = new Command();\n\nprogram\n .name('aiready-visualize')\n .description(\n 'Generate interactive visualizations from AIReady analysis results'\n )\n .version('0.1.0')\n .option('-d, --dev', 'Start interactive web application (default)', true)\n .option('-o, --output <file>', 'Output HTML file for static generation')\n .passThroughOptions();\n\n/**\n * Start the interactive web dev server\n */\nfunction startDevServer(rootDir: string): void {\n const webDir = resolve(__dirname, '../web');\n\n console.log('🎯 AIReady Visualizer');\n console.log('🚀 Starting interactive web application...');\n console.log();\n console.log(`📁 Project root: ${rootDir}`);\n console.log(`🌐 Web server: http://localhost:${WEB_PORT}`);\n console.log();\n console.log('💡 The web app requires report data to visualize.');\n console.log(' Run \"pnpm aiready scan .\" then copy the report to:');\n console.log(` web/public/report-data.json`);\n console.log();\n console.log('Press Ctrl+C to stop the server.');\n console.log();\n\n // Start vite dev server\n const vite = spawn('pnpm', ['dev'], {\n cwd: webDir,\n stdio: 'inherit',\n shell: true,\n env: { ...process.env, FORCE_COLOR: '1' },\n });\n\n vite.on('error', (err) => {\n console.error('❌ Failed to start dev server:', err.message);\n process.exit(1);\n });\n}\n\nprogram\n .command('sample')\n .description('Generate a sample visualization for testing')\n .option('-o, --output <file>', 'Output HTML file', 'visualization.html')\n .option('--open', 'Open in browser')\n .action(async (options) => {\n const { writeFileSync } = await import('fs');\n const { exec } = await import('child_process');\n\n console.log('Generating sample visualization...');\n const graph = createSampleGraph();\n\n console.log(\n `\\nSample graph created with ${graph.nodes.length} nodes and ${graph.edges.length} edges`\n );\n\n const html = generateHTML(graph);\n const outputPath = resolve(options.output);\n writeFileSync(outputPath, html);\n\n console.log(`✅ HTML saved to: ${outputPath}`);\n\n if (options.open) {\n const opener =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start'\n : 'xdg-open';\n exec(`${opener} \"${outputPath}\"`);\n }\n });\n\nprogram\n .command('generate')\n .description('Generate visualization from analysis results')\n .argument('<input>', 'Input JSON file with analysis results')\n .option('-o, --output <file>', 'Output HTML file', 'visualization.html')\n .option('--open', 'Open in browser')\n .action(async (input, options) => {\n const { readFileSync, writeFileSync } = await import('fs');\n const { exec } = await import('child_process');\n\n console.log(`Reading analysis results from: ${input}`);\n const report = JSON.parse(readFileSync(input, 'utf-8'));\n\n const rootDir = process.cwd();\n const graph = GraphBuilder.buildFromReport(report, rootDir);\n\n console.log(\n `Graph built: ${graph.nodes.length} nodes, ${graph.edges.length} edges`\n );\n\n const html = generateHTML(graph);\n const outputPath = resolve(options.output);\n writeFileSync(outputPath, html);\n\n console.log(`✅ HTML saved to: ${outputPath}`);\n\n if (options.open) {\n const opener =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start'\n : 'xdg-open';\n exec(`${opener} \"${outputPath}\"`);\n }\n });\n\n// Handle default case: start dev server when no arguments provided\nconst args = process.argv.slice(2);\nif (\n args.length === 0 ||\n (args.length === 1 && (args[0] === '--dev' || args[0] === '-d'))\n) {\n startDevServer(process.cwd());\n} else {\n program.parse();\n}\n"]}
|
package/dist/graph/index.js
CHANGED
|
@@ -28,7 +28,8 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
28
28
|
if (!fp) return null;
|
|
29
29
|
const parts = fp.split(path.sep);
|
|
30
30
|
const pkgIdx = parts.indexOf("packages");
|
|
31
|
-
if (pkgIdx >= 0 && parts.length > pkgIdx + 1)
|
|
31
|
+
if (pkgIdx >= 0 && parts.length > pkgIdx + 1)
|
|
32
|
+
return `packages/${parts[pkgIdx + 1]}`;
|
|
32
33
|
const landingIdx = parts.indexOf("landing");
|
|
33
34
|
if (landingIdx >= 0) return "landing";
|
|
34
35
|
const scriptsIdx = parts.indexOf("scripts");
|
|
@@ -71,7 +72,9 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
71
72
|
*/
|
|
72
73
|
build() {
|
|
73
74
|
const nodes = Array.from(this.nodesMap.values());
|
|
74
|
-
const edges = this.edges.map(
|
|
75
|
+
const edges = this.edges.map(
|
|
76
|
+
(e) => ({ source: e.source, target: e.target, type: e.type })
|
|
77
|
+
);
|
|
75
78
|
return {
|
|
76
79
|
nodes,
|
|
77
80
|
edges,
|
|
@@ -107,12 +110,14 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
107
110
|
const bumpIssue = (file, sev) => {
|
|
108
111
|
if (!file) return;
|
|
109
112
|
const id = path.resolve(rootDir, file);
|
|
110
|
-
if (!fileIssues.has(id))
|
|
113
|
+
if (!fileIssues.has(id))
|
|
114
|
+
fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
111
115
|
const rec = fileIssues.get(id);
|
|
112
116
|
rec.count += 1;
|
|
113
117
|
if (sev) {
|
|
114
118
|
const order = { critical: 3, major: 2, minor: 1, info: 0 };
|
|
115
|
-
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
119
|
+
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
120
|
+
rec.maxSeverity = sev;
|
|
116
121
|
}
|
|
117
122
|
};
|
|
118
123
|
const basenameMap = /* @__PURE__ */ new Map();
|
|
@@ -123,10 +128,16 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
123
128
|
});
|
|
124
129
|
(report.patterns || []).forEach((entry) => {
|
|
125
130
|
const file = entry.fileName;
|
|
126
|
-
builder.addNode(
|
|
131
|
+
builder.addNode(
|
|
132
|
+
file,
|
|
133
|
+
`Issues: ${(entry.issues || []).length}`,
|
|
134
|
+
entry.metrics && entry.metrics.tokenCost || 5
|
|
135
|
+
);
|
|
127
136
|
if ((entry.issues || []).length > 0) {
|
|
128
137
|
(entry.issues || []).forEach((issue) => {
|
|
129
|
-
const sev = rankSeverity(
|
|
138
|
+
const sev = rankSeverity(
|
|
139
|
+
issue.severity || issue.severityLevel || null
|
|
140
|
+
);
|
|
130
141
|
bumpIssue(file, sev);
|
|
131
142
|
});
|
|
132
143
|
}
|
|
@@ -147,7 +158,8 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
147
158
|
if (wantFuzzy) {
|
|
148
159
|
const fileGroup = builder.getPackageGroup(file);
|
|
149
160
|
for (const [base, pathsSet] of basenameMap.entries()) {
|
|
150
|
-
if (!message.includes(base) || base === path.basename(file))
|
|
161
|
+
if (!message.includes(base) || base === path.basename(file))
|
|
162
|
+
continue;
|
|
151
163
|
for (const target of pathsSet) {
|
|
152
164
|
const targetGroup = builder.getPackageGroup(target);
|
|
153
165
|
if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;
|
|
@@ -164,8 +176,10 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
164
176
|
builder.addEdge(dup.file1, dup.file2, "similarity");
|
|
165
177
|
const f1 = path.resolve(rootDir, dup.file1);
|
|
166
178
|
const f2 = path.resolve(rootDir, dup.file2);
|
|
167
|
-
if (!fileIssues.has(f1))
|
|
168
|
-
|
|
179
|
+
if (!fileIssues.has(f1))
|
|
180
|
+
fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
181
|
+
if (!fileIssues.has(f2))
|
|
182
|
+
fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });
|
|
169
183
|
fileIssues.get(f1).duplicates += 1;
|
|
170
184
|
fileIssues.get(f2).duplicates += 1;
|
|
171
185
|
});
|
|
@@ -174,7 +188,9 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
174
188
|
builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
|
|
175
189
|
if (ctx.issues && Array.isArray(ctx.issues)) {
|
|
176
190
|
ctx.issues.forEach((issue) => {
|
|
177
|
-
const sev = rankSeverity(
|
|
191
|
+
const sev = rankSeverity(
|
|
192
|
+
issue.severity || issue.severityLevel || null
|
|
193
|
+
);
|
|
178
194
|
bumpIssue(file, sev);
|
|
179
195
|
});
|
|
180
196
|
}
|
|
@@ -182,9 +198,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
182
198
|
const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);
|
|
183
199
|
const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;
|
|
184
200
|
const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;
|
|
185
|
-
if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB))
|
|
201
|
+
if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB))
|
|
202
|
+
return;
|
|
186
203
|
builder.addNode(resolvedRel, "Related file", 5);
|
|
187
|
-
const n = builder.nodesMap.get(
|
|
204
|
+
const n = builder.nodesMap.get(
|
|
205
|
+
path.resolve(builder.rootDir, resolvedRel)
|
|
206
|
+
);
|
|
188
207
|
if (n) n.size = (n.size || 1) + 2;
|
|
189
208
|
try {
|
|
190
209
|
builder.addEdge(file, resolvedRel, "related");
|
|
@@ -293,7 +312,11 @@ function createSampleGraph() {
|
|
|
293
312
|
builder.addNode("src/components/Button.tsx", "Button", 15);
|
|
294
313
|
builder.addNode("src/utils/helpers.ts", "helpers", 12);
|
|
295
314
|
builder.addNode("src/services/api.ts", "api", 18);
|
|
296
|
-
builder.addEdge(
|
|
315
|
+
builder.addEdge(
|
|
316
|
+
"src/components/Button.tsx",
|
|
317
|
+
"src/utils/helpers.ts",
|
|
318
|
+
"dependency"
|
|
319
|
+
);
|
|
297
320
|
builder.addEdge("src/utils/helpers.ts", "src/services/api.ts", "dependency");
|
|
298
321
|
return builder.build();
|
|
299
322
|
}
|
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 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 // Also add a visual 'related' edge so that built/packed visualizations\n // (which use this GraphBuilder) include related connections rather\n // than only bumping node prominence.\n try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch (e) {\n // ignore any edge errors\n }\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 // 4. Doc Drift\n (report.docDrift?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Doc-Drift Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // 5. Dependencies\n (report.deps?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Dependency Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\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}"]}
|
|
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 =\n /(?:\\.\\/|\\.\\.\\/)(?:[\\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)\n 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(\n (e) =>\n ({ source: e.source, target: e.target, type: e.type }) as DependencyEdge\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 * 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<\n string,\n { count: number; maxSeverity: IssueSeverity | null; duplicates: number }\n > = 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))\n 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<\n IssueSeverity,\n number\n >;\n if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])\n 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(\n file,\n `Issues: ${(entry.issues || []).length}`,\n (entry.metrics && entry.metrics.tokenCost) || 5\n );\n\n // record aggregate for this file\n if ((entry.issues || []).length > 0) {\n (entry.issues || []).forEach((issue: any) => {\n const sev = rankSeverity(\n issue.severity || issue.severityLevel || null\n );\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 =\n issue.type === 'duplicate-pattern' ||\n /similar/i.test(message) ||\n (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))\n 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))\n fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });\n if (!fileIssues.has(f2))\n 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(\n issue.severity || issue.severityLevel || null\n );\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)\n ? rel\n : 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 (\n (builder as any).edgesSet.has(keyA) ||\n (builder as any).edgesSet.has(keyB)\n )\n return;\n builder.addNode(resolvedRel, 'Related file', 5);\n // bump size to reflect relatedness\n const n = (builder as any).nodesMap.get(\n path.resolve(builder.rootDir, resolvedRel)\n );\n if (n) n.size = (n.size || 1) + 2;\n // Also add a visual 'related' edge so that built/packed visualizations\n // (which use this GraphBuilder) include related connections rather\n // than only bumping node prominence.\n try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch (e) {\n // ignore any edge errors\n }\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 // 4. Doc Drift\n (report.docDrift?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Doc-Drift Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // 5. Dependencies\n (report.deps?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Dependency Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\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(\n 'src/components/Button.tsx',\n 'src/utils/helpers.ts',\n 'dependency'\n );\n builder.addEdge('src/utils/helpers.ts', 'src/services/api.ts', 'dependency');\n return builder.build();\n}\n"]}
|