@aiready/visualizer 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +30 -19
- package/dist/cli.js.map +1 -1
- package/dist/graph/index.d.ts +10 -14
- package/dist/graph/index.js +30 -18
- package/dist/graph/index.js.map +1 -1
- package/dist/index.js +30 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { spawn } from 'child_process';
|
|
|
4
4
|
import path, { dirname, resolve } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import fs from 'fs';
|
|
7
|
-
import { generateHTML } from '@aiready/core';
|
|
7
|
+
import { generateHTML, UnifiedReportSchema, Severity } from '@aiready/core';
|
|
8
8
|
|
|
9
9
|
var GraphBuilder = class _GraphBuilder {
|
|
10
10
|
constructor(rootDir = process.cwd()) {
|
|
@@ -100,15 +100,21 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
100
100
|
* Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)
|
|
101
101
|
*/
|
|
102
102
|
static buildFromReport(report, rootDir = process.cwd()) {
|
|
103
|
+
const validation = UnifiedReportSchema.safeParse(report);
|
|
104
|
+
if (!validation.success) {
|
|
105
|
+
console.warn(
|
|
106
|
+
"Visualizer: Report does not fully match UnifiedReportSchema, proceeding with best-effort parsing."
|
|
107
|
+
);
|
|
108
|
+
}
|
|
103
109
|
const builder = new _GraphBuilder(rootDir);
|
|
104
110
|
const fileIssues = /* @__PURE__ */ new Map();
|
|
105
111
|
const rankSeverity = (s) => {
|
|
106
112
|
if (!s) return null;
|
|
107
113
|
const ss = String(s).toLowerCase();
|
|
108
|
-
if (ss.includes("critical")) return
|
|
109
|
-
if (ss.includes("major")) return
|
|
110
|
-
if (ss.includes("minor")) return
|
|
111
|
-
if (ss.includes("info")) return
|
|
114
|
+
if (ss.includes("critical")) return Severity.Critical;
|
|
115
|
+
if (ss.includes("major")) return Severity.Major;
|
|
116
|
+
if (ss.includes("minor")) return Severity.Minor;
|
|
117
|
+
if (ss.includes("info")) return Severity.Info;
|
|
112
118
|
return null;
|
|
113
119
|
};
|
|
114
120
|
const bumpIssue = (file, sev) => {
|
|
@@ -119,7 +125,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
119
125
|
const rec = fileIssues.get(id);
|
|
120
126
|
rec.count += 1;
|
|
121
127
|
if (sev) {
|
|
122
|
-
const order = {
|
|
128
|
+
const order = {
|
|
129
|
+
[Severity.Critical]: 3,
|
|
130
|
+
[Severity.Major]: 2,
|
|
131
|
+
[Severity.Minor]: 1,
|
|
132
|
+
[Severity.Info]: 0
|
|
133
|
+
};
|
|
123
134
|
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
124
135
|
rec.maxSeverity = sev;
|
|
125
136
|
}
|
|
@@ -130,7 +141,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
130
141
|
if (!basenameMap.has(base)) basenameMap.set(base, /* @__PURE__ */ new Set());
|
|
131
142
|
basenameMap.get(base).add(p.fileName);
|
|
132
143
|
});
|
|
133
|
-
const patterns = report.patternDetect?.results || report.patterns || [];
|
|
144
|
+
const patterns = report.patternDetect?.results || report.results || report.patterns || [];
|
|
134
145
|
patterns.forEach((entry) => {
|
|
135
146
|
const file = entry.fileName;
|
|
136
147
|
builder.addNode(
|
|
@@ -191,12 +202,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
191
202
|
});
|
|
192
203
|
const context = report.contextAnalyzer?.results || report.context || [];
|
|
193
204
|
context.forEach((ctx) => {
|
|
194
|
-
const file = ctx.file;
|
|
205
|
+
const file = ctx.fileName || ctx.file;
|
|
195
206
|
builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
|
|
196
207
|
if (ctx.issues && Array.isArray(ctx.issues)) {
|
|
197
208
|
ctx.issues.forEach((issue) => {
|
|
198
209
|
const sev = rankSeverity(
|
|
199
|
-
issue.severity || issue.severityLevel || null
|
|
210
|
+
typeof issue === "string" ? ctx.severity : issue.severity || issue.severityLevel || null
|
|
200
211
|
);
|
|
201
212
|
bumpIssue(file, sev);
|
|
202
213
|
});
|
|
@@ -241,7 +252,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
241
252
|
});
|
|
242
253
|
const docDriftResults = report.docDrift?.results || report.docDrift?.issues || [];
|
|
243
254
|
docDriftResults.forEach((issue) => {
|
|
244
|
-
const file = issue.location?.file;
|
|
255
|
+
const file = issue.fileName || issue.location?.file;
|
|
245
256
|
if (file) {
|
|
246
257
|
builder.addNode(file, "Doc-Drift Issue", 5);
|
|
247
258
|
const sev = rankSeverity(issue.severity || null);
|
|
@@ -250,7 +261,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
250
261
|
});
|
|
251
262
|
const depsResults = report.dependencyHealth?.results || report.deps?.issues || [];
|
|
252
263
|
depsResults.forEach((issue) => {
|
|
253
|
-
const file = issue.location?.file;
|
|
264
|
+
const file = issue.fileName || issue.location?.file;
|
|
254
265
|
if (file) {
|
|
255
266
|
builder.addNode(file, "Dependency Issue", 5);
|
|
256
267
|
const sev = rankSeverity(issue.severity || null);
|
|
@@ -261,16 +272,16 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
261
272
|
const edges = builder.edges;
|
|
262
273
|
const colorFor = (sev) => {
|
|
263
274
|
switch (sev) {
|
|
264
|
-
case
|
|
275
|
+
case Severity.Critical:
|
|
265
276
|
return "#ff4d4f";
|
|
266
277
|
// red
|
|
267
|
-
case
|
|
278
|
+
case Severity.Major:
|
|
268
279
|
return "#ff9900";
|
|
269
280
|
// orange
|
|
270
|
-
case
|
|
281
|
+
case Severity.Minor:
|
|
271
282
|
return "#ffd666";
|
|
272
283
|
// yellow
|
|
273
|
-
case
|
|
284
|
+
case Severity.Info:
|
|
274
285
|
return "#91d5ff";
|
|
275
286
|
// light blue
|
|
276
287
|
default:
|
|
@@ -288,10 +299,10 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
288
299
|
n.duplicates = rec.duplicates || 0;
|
|
289
300
|
n.color = colorFor(rec.maxSeverity);
|
|
290
301
|
n.group = builder.getPackageGroup(n.id) || void 0;
|
|
291
|
-
if (rec.maxSeverity ===
|
|
292
|
-
else if (rec.maxSeverity ===
|
|
293
|
-
else if (rec.maxSeverity ===
|
|
294
|
-
else if (rec.maxSeverity ===
|
|
302
|
+
if (rec.maxSeverity === Severity.Critical) criticalIssues += rec.count;
|
|
303
|
+
else if (rec.maxSeverity === Severity.Major) majorIssues += rec.count;
|
|
304
|
+
else if (rec.maxSeverity === Severity.Minor) minorIssues += rec.count;
|
|
305
|
+
else if (rec.maxSeverity === Severity.Info) infoIssues += rec.count;
|
|
295
306
|
} else {
|
|
296
307
|
n.color = colorFor(null);
|
|
297
308
|
n.group = builder.getPackageGroup(n.id) || void 0;
|
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 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 {\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 (Support unified patternDetect.results or legacy patterns)\n const patterns = report.patternDetect?.results || report.patterns || [];\n 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 (Support unified patternDetect.duplicates or legacy duplicates)\n const duplicates =\n report.patternDetect?.duplicates || report.duplicates || [];\n 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 (Support unified contextAnalyzer.results or legacy context)\n const context = report.contextAnalyzer?.results || report.context || [];\n 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 {\n // ignore any edge errors\n }\n });\n\n const absoluteFile = path.resolve(builder.rootDir, file);\n const fileDir = path.dirname(absoluteFile);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.') || 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 const docDriftResults =\n report.docDrift?.results || report.docDrift?.issues || [];\n docDriftResults.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 const depsResults =\n report.dependencyHealth?.results || report.deps?.issues || [];\n depsResults.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 tokenBudget: report.scoring?.tokenBudget,\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';\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"]}
|
|
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 { Severity, UnifiedReportSchema } from '@aiready/core';\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\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 {\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 // Optional: Validate report with Zod schema if needed, but allow partials for visualizer\n const validation = UnifiedReportSchema.safeParse(report);\n if (!validation.success) {\n console.warn(\n 'Visualizer: Report does not fully match UnifiedReportSchema, proceeding with best-effort parsing.'\n );\n }\n\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: Severity | null; duplicates: number }\n > = new Map();\n\n const rankSeverity = (s?: string | null): Severity | null => {\n if (!s) return null;\n const ss = String(s).toLowerCase();\n if (ss.includes('critical')) return Severity.Critical;\n if (ss.includes('major')) return Severity.Major;\n if (ss.includes('minor')) return Severity.Minor;\n if (ss.includes('info')) return Severity.Info;\n return null;\n };\n\n const bumpIssue = (file: string, sev?: Severity | 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 = {\n [Severity.Critical]: 3,\n [Severity.Major]: 2,\n [Severity.Minor]: 1,\n [Severity.Info]: 0,\n } as Record<Severity, number>;\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 (Support unified patternDetect.results or legacy patterns)\n const patterns =\n report.patternDetect?.results || report.results || report.patterns || [];\n 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 (Support unified patternDetect.duplicates or legacy duplicates)\n const duplicates =\n report.patternDetect?.duplicates || report.duplicates || [];\n 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 (Support unified contextAnalyzer.results or legacy context)\n const context = report.contextAnalyzer?.results || report.context || [];\n context.forEach((ctx: any) => {\n // Handle context analyzer results (which use 'file' instead of 'fileName')\n const file = ctx.fileName || 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 typeof issue === 'string'\n ? ctx.severity\n : issue.severity || issue.severityLevel || null\n );\n bumpIssue(file, sev);\n });\n }\n\n // Add related files\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 try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch {\n // ignore any edge errors\n }\n });\n\n const absoluteFile = path.resolve(builder.rootDir, file);\n const fileDir = path.dirname(absoluteFile);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.') || 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 const docDriftResults =\n report.docDrift?.results || report.docDrift?.issues || [];\n docDriftResults.forEach((issue: any) => {\n const file = issue.fileName || 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 const depsResults =\n report.dependencyHealth?.results || report.deps?.issues || [];\n depsResults.forEach((issue: any) => {\n const file = issue.fileName || 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: Severity | null) => {\n switch (sev) {\n case Severity.Critical:\n return '#ff4d4f'; // red\n case Severity.Major:\n return '#ff9900'; // orange\n case Severity.Minor:\n return '#ffd666'; // yellow\n case Severity.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 === Severity.Critical) criticalIssues += rec.count;\n else if (rec.maxSeverity === Severity.Major) majorIssues += rec.count;\n else if (rec.maxSeverity === Severity.Minor) minorIssues += rec.count;\n else if (rec.maxSeverity === Severity.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 tokenBudget: report.scoring?.tokenBudget,\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';\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.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import { TokenBudget } from '@aiready/core';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Core types for graph visualization
|
|
5
|
-
*/
|
|
1
|
+
import { GraphEdge, GraphNode, Severity, GraphData as GraphData$1, GraphMetadata as GraphMetadata$1, TokenBudget } from '@aiready/core';
|
|
6
2
|
|
|
7
3
|
/**
|
|
8
4
|
* Severity levels for issues
|
|
9
5
|
*/
|
|
10
|
-
type IssueSeverity =
|
|
6
|
+
type IssueSeverity = Severity;
|
|
11
7
|
/**
|
|
12
8
|
* Base graph node (compatible with d3-force SimulationNodeDatum)
|
|
13
9
|
*/
|
|
@@ -31,7 +27,7 @@ interface BaseGraphLink {
|
|
|
31
27
|
/**
|
|
32
28
|
* File node in the dependency graph
|
|
33
29
|
*/
|
|
34
|
-
interface FileNode extends BaseGraphNode {
|
|
30
|
+
interface FileNode extends BaseGraphNode, GraphNode {
|
|
35
31
|
id: string;
|
|
36
32
|
path: string;
|
|
37
33
|
label: string;
|
|
@@ -49,10 +45,10 @@ interface FileNode extends BaseGraphNode {
|
|
|
49
45
|
/**
|
|
50
46
|
* Dependency edge between files
|
|
51
47
|
*/
|
|
52
|
-
interface DependencyEdge extends BaseGraphLink {
|
|
48
|
+
interface DependencyEdge extends BaseGraphLink, GraphEdge {
|
|
53
49
|
source: string | FileNode;
|
|
54
50
|
target: string | FileNode;
|
|
55
|
-
type?: 'import' | 'require' | 'dynamic';
|
|
51
|
+
type?: 'import' | 'require' | 'dynamic' | any;
|
|
56
52
|
weight?: number;
|
|
57
53
|
color?: string;
|
|
58
54
|
width?: number;
|
|
@@ -73,8 +69,8 @@ interface Cluster {
|
|
|
73
69
|
*/
|
|
74
70
|
interface IssueOverlay {
|
|
75
71
|
id: string;
|
|
76
|
-
type:
|
|
77
|
-
severity:
|
|
72
|
+
type: string;
|
|
73
|
+
severity: Severity;
|
|
78
74
|
nodeIds: string[];
|
|
79
75
|
edgeIds?: string[];
|
|
80
76
|
message: string;
|
|
@@ -83,7 +79,7 @@ interface IssueOverlay {
|
|
|
83
79
|
/**
|
|
84
80
|
* Complete graph data structure
|
|
85
81
|
*/
|
|
86
|
-
interface GraphData {
|
|
82
|
+
interface GraphData extends GraphData$1 {
|
|
87
83
|
nodes: FileNode[];
|
|
88
84
|
edges: DependencyEdge[];
|
|
89
85
|
clusters: Cluster[];
|
|
@@ -93,7 +89,7 @@ interface GraphData {
|
|
|
93
89
|
/**
|
|
94
90
|
* Metadata about the graph
|
|
95
91
|
*/
|
|
96
|
-
interface GraphMetadata {
|
|
92
|
+
interface GraphMetadata extends GraphMetadata$1 {
|
|
97
93
|
projectName?: string;
|
|
98
94
|
timestamp: string;
|
|
99
95
|
totalFiles: number;
|
|
@@ -117,7 +113,7 @@ interface GraphMetadata {
|
|
|
117
113
|
*/
|
|
118
114
|
interface FilterOptions {
|
|
119
115
|
severities?: IssueSeverity[];
|
|
120
|
-
issueTypes?:
|
|
116
|
+
issueTypes?: string[];
|
|
121
117
|
domains?: string[];
|
|
122
118
|
moduleTypes?: FileNode['moduleType'][];
|
|
123
119
|
minTokenCost?: number;
|
package/dist/graph/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { UnifiedReportSchema, Severity } from '@aiready/core';
|
|
3
4
|
|
|
4
5
|
// src/graph/builder.ts
|
|
5
6
|
var GraphBuilder = class _GraphBuilder {
|
|
@@ -96,15 +97,21 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
96
97
|
* Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)
|
|
97
98
|
*/
|
|
98
99
|
static buildFromReport(report, rootDir = process.cwd()) {
|
|
100
|
+
const validation = UnifiedReportSchema.safeParse(report);
|
|
101
|
+
if (!validation.success) {
|
|
102
|
+
console.warn(
|
|
103
|
+
"Visualizer: Report does not fully match UnifiedReportSchema, proceeding with best-effort parsing."
|
|
104
|
+
);
|
|
105
|
+
}
|
|
99
106
|
const builder = new _GraphBuilder(rootDir);
|
|
100
107
|
const fileIssues = /* @__PURE__ */ new Map();
|
|
101
108
|
const rankSeverity = (s) => {
|
|
102
109
|
if (!s) return null;
|
|
103
110
|
const ss = String(s).toLowerCase();
|
|
104
|
-
if (ss.includes("critical")) return
|
|
105
|
-
if (ss.includes("major")) return
|
|
106
|
-
if (ss.includes("minor")) return
|
|
107
|
-
if (ss.includes("info")) return
|
|
111
|
+
if (ss.includes("critical")) return Severity.Critical;
|
|
112
|
+
if (ss.includes("major")) return Severity.Major;
|
|
113
|
+
if (ss.includes("minor")) return Severity.Minor;
|
|
114
|
+
if (ss.includes("info")) return Severity.Info;
|
|
108
115
|
return null;
|
|
109
116
|
};
|
|
110
117
|
const bumpIssue = (file, sev) => {
|
|
@@ -115,7 +122,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
115
122
|
const rec = fileIssues.get(id);
|
|
116
123
|
rec.count += 1;
|
|
117
124
|
if (sev) {
|
|
118
|
-
const order = {
|
|
125
|
+
const order = {
|
|
126
|
+
[Severity.Critical]: 3,
|
|
127
|
+
[Severity.Major]: 2,
|
|
128
|
+
[Severity.Minor]: 1,
|
|
129
|
+
[Severity.Info]: 0
|
|
130
|
+
};
|
|
119
131
|
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
120
132
|
rec.maxSeverity = sev;
|
|
121
133
|
}
|
|
@@ -126,7 +138,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
126
138
|
if (!basenameMap.has(base)) basenameMap.set(base, /* @__PURE__ */ new Set());
|
|
127
139
|
basenameMap.get(base).add(p.fileName);
|
|
128
140
|
});
|
|
129
|
-
const patterns = report.patternDetect?.results || report.patterns || [];
|
|
141
|
+
const patterns = report.patternDetect?.results || report.results || report.patterns || [];
|
|
130
142
|
patterns.forEach((entry) => {
|
|
131
143
|
const file = entry.fileName;
|
|
132
144
|
builder.addNode(
|
|
@@ -187,12 +199,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
187
199
|
});
|
|
188
200
|
const context = report.contextAnalyzer?.results || report.context || [];
|
|
189
201
|
context.forEach((ctx) => {
|
|
190
|
-
const file = ctx.file;
|
|
202
|
+
const file = ctx.fileName || ctx.file;
|
|
191
203
|
builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
|
|
192
204
|
if (ctx.issues && Array.isArray(ctx.issues)) {
|
|
193
205
|
ctx.issues.forEach((issue) => {
|
|
194
206
|
const sev = rankSeverity(
|
|
195
|
-
issue.severity || issue.severityLevel || null
|
|
207
|
+
typeof issue === "string" ? ctx.severity : issue.severity || issue.severityLevel || null
|
|
196
208
|
);
|
|
197
209
|
bumpIssue(file, sev);
|
|
198
210
|
});
|
|
@@ -237,7 +249,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
237
249
|
});
|
|
238
250
|
const docDriftResults = report.docDrift?.results || report.docDrift?.issues || [];
|
|
239
251
|
docDriftResults.forEach((issue) => {
|
|
240
|
-
const file = issue.location?.file;
|
|
252
|
+
const file = issue.fileName || issue.location?.file;
|
|
241
253
|
if (file) {
|
|
242
254
|
builder.addNode(file, "Doc-Drift Issue", 5);
|
|
243
255
|
const sev = rankSeverity(issue.severity || null);
|
|
@@ -246,7 +258,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
246
258
|
});
|
|
247
259
|
const depsResults = report.dependencyHealth?.results || report.deps?.issues || [];
|
|
248
260
|
depsResults.forEach((issue) => {
|
|
249
|
-
const file = issue.location?.file;
|
|
261
|
+
const file = issue.fileName || issue.location?.file;
|
|
250
262
|
if (file) {
|
|
251
263
|
builder.addNode(file, "Dependency Issue", 5);
|
|
252
264
|
const sev = rankSeverity(issue.severity || null);
|
|
@@ -257,16 +269,16 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
257
269
|
const edges = builder.edges;
|
|
258
270
|
const colorFor = (sev) => {
|
|
259
271
|
switch (sev) {
|
|
260
|
-
case
|
|
272
|
+
case Severity.Critical:
|
|
261
273
|
return "#ff4d4f";
|
|
262
274
|
// red
|
|
263
|
-
case
|
|
275
|
+
case Severity.Major:
|
|
264
276
|
return "#ff9900";
|
|
265
277
|
// orange
|
|
266
|
-
case
|
|
278
|
+
case Severity.Minor:
|
|
267
279
|
return "#ffd666";
|
|
268
280
|
// yellow
|
|
269
|
-
case
|
|
281
|
+
case Severity.Info:
|
|
270
282
|
return "#91d5ff";
|
|
271
283
|
// light blue
|
|
272
284
|
default:
|
|
@@ -284,10 +296,10 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
284
296
|
n.duplicates = rec.duplicates || 0;
|
|
285
297
|
n.color = colorFor(rec.maxSeverity);
|
|
286
298
|
n.group = builder.getPackageGroup(n.id) || void 0;
|
|
287
|
-
if (rec.maxSeverity ===
|
|
288
|
-
else if (rec.maxSeverity ===
|
|
289
|
-
else if (rec.maxSeverity ===
|
|
290
|
-
else if (rec.maxSeverity ===
|
|
299
|
+
if (rec.maxSeverity === Severity.Critical) criticalIssues += rec.count;
|
|
300
|
+
else if (rec.maxSeverity === Severity.Major) majorIssues += rec.count;
|
|
301
|
+
else if (rec.maxSeverity === Severity.Minor) minorIssues += rec.count;
|
|
302
|
+
else if (rec.maxSeverity === Severity.Info) infoIssues += rec.count;
|
|
291
303
|
} else {
|
|
292
304
|
n.color = colorFor(null);
|
|
293
305
|
n.group = builder.getPackageGroup(n.id) || void 0;
|
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 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 {\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 (Support unified patternDetect.results or legacy patterns)\n const patterns = report.patternDetect?.results || report.patterns || [];\n 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 (Support unified patternDetect.duplicates or legacy duplicates)\n const duplicates =\n report.patternDetect?.duplicates || report.duplicates || [];\n 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 (Support unified contextAnalyzer.results or legacy context)\n const context = report.contextAnalyzer?.results || report.context || [];\n 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 {\n // ignore any edge errors\n }\n });\n\n const absoluteFile = path.resolve(builder.rootDir, file);\n const fileDir = path.dirname(absoluteFile);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.') || 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 const docDriftResults =\n report.docDrift?.results || report.docDrift?.issues || [];\n docDriftResults.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 const depsResults =\n report.dependencyHealth?.results || report.deps?.issues || [];\n depsResults.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 tokenBudget: report.scoring?.tokenBudget,\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"]}
|
|
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 { Severity, UnifiedReportSchema } from '@aiready/core';\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\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 {\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 // Optional: Validate report with Zod schema if needed, but allow partials for visualizer\n const validation = UnifiedReportSchema.safeParse(report);\n if (!validation.success) {\n console.warn(\n 'Visualizer: Report does not fully match UnifiedReportSchema, proceeding with best-effort parsing.'\n );\n }\n\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: Severity | null; duplicates: number }\n > = new Map();\n\n const rankSeverity = (s?: string | null): Severity | null => {\n if (!s) return null;\n const ss = String(s).toLowerCase();\n if (ss.includes('critical')) return Severity.Critical;\n if (ss.includes('major')) return Severity.Major;\n if (ss.includes('minor')) return Severity.Minor;\n if (ss.includes('info')) return Severity.Info;\n return null;\n };\n\n const bumpIssue = (file: string, sev?: Severity | 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 = {\n [Severity.Critical]: 3,\n [Severity.Major]: 2,\n [Severity.Minor]: 1,\n [Severity.Info]: 0,\n } as Record<Severity, number>;\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 (Support unified patternDetect.results or legacy patterns)\n const patterns =\n report.patternDetect?.results || report.results || report.patterns || [];\n 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 (Support unified patternDetect.duplicates or legacy duplicates)\n const duplicates =\n report.patternDetect?.duplicates || report.duplicates || [];\n 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 (Support unified contextAnalyzer.results or legacy context)\n const context = report.contextAnalyzer?.results || report.context || [];\n context.forEach((ctx: any) => {\n // Handle context analyzer results (which use 'file' instead of 'fileName')\n const file = ctx.fileName || 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 typeof issue === 'string'\n ? ctx.severity\n : issue.severity || issue.severityLevel || null\n );\n bumpIssue(file, sev);\n });\n }\n\n // Add related files\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 try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch {\n // ignore any edge errors\n }\n });\n\n const absoluteFile = path.resolve(builder.rootDir, file);\n const fileDir = path.dirname(absoluteFile);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.') || 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 const docDriftResults =\n report.docDrift?.results || report.docDrift?.issues || [];\n docDriftResults.forEach((issue: any) => {\n const file = issue.fileName || 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 const depsResults =\n report.dependencyHealth?.results || report.deps?.issues || [];\n depsResults.forEach((issue: any) => {\n const file = issue.fileName || 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: Severity | null) => {\n switch (sev) {\n case Severity.Critical:\n return '#ff4d4f'; // red\n case Severity.Major:\n return '#ff9900'; // orange\n case Severity.Minor:\n return '#ffd666'; // yellow\n case Severity.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 === Severity.Critical) criticalIssues += rec.count;\n else if (rec.maxSeverity === Severity.Major) majorIssues += rec.count;\n else if (rec.maxSeverity === Severity.Minor) minorIssues += rec.count;\n else if (rec.maxSeverity === Severity.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 tokenBudget: report.scoring?.tokenBudget,\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"]}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { UnifiedReportSchema, Severity } from '@aiready/core';
|
|
3
4
|
|
|
4
5
|
// src/graph/builder.ts
|
|
5
6
|
var GraphBuilder = class _GraphBuilder {
|
|
@@ -96,15 +97,21 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
96
97
|
* Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)
|
|
97
98
|
*/
|
|
98
99
|
static buildFromReport(report, rootDir = process.cwd()) {
|
|
100
|
+
const validation = UnifiedReportSchema.safeParse(report);
|
|
101
|
+
if (!validation.success) {
|
|
102
|
+
console.warn(
|
|
103
|
+
"Visualizer: Report does not fully match UnifiedReportSchema, proceeding with best-effort parsing."
|
|
104
|
+
);
|
|
105
|
+
}
|
|
99
106
|
const builder = new _GraphBuilder(rootDir);
|
|
100
107
|
const fileIssues = /* @__PURE__ */ new Map();
|
|
101
108
|
const rankSeverity = (s) => {
|
|
102
109
|
if (!s) return null;
|
|
103
110
|
const ss = String(s).toLowerCase();
|
|
104
|
-
if (ss.includes("critical")) return
|
|
105
|
-
if (ss.includes("major")) return
|
|
106
|
-
if (ss.includes("minor")) return
|
|
107
|
-
if (ss.includes("info")) return
|
|
111
|
+
if (ss.includes("critical")) return Severity.Critical;
|
|
112
|
+
if (ss.includes("major")) return Severity.Major;
|
|
113
|
+
if (ss.includes("minor")) return Severity.Minor;
|
|
114
|
+
if (ss.includes("info")) return Severity.Info;
|
|
108
115
|
return null;
|
|
109
116
|
};
|
|
110
117
|
const bumpIssue = (file, sev) => {
|
|
@@ -115,7 +122,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
115
122
|
const rec = fileIssues.get(id);
|
|
116
123
|
rec.count += 1;
|
|
117
124
|
if (sev) {
|
|
118
|
-
const order = {
|
|
125
|
+
const order = {
|
|
126
|
+
[Severity.Critical]: 3,
|
|
127
|
+
[Severity.Major]: 2,
|
|
128
|
+
[Severity.Minor]: 1,
|
|
129
|
+
[Severity.Info]: 0
|
|
130
|
+
};
|
|
119
131
|
if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
|
|
120
132
|
rec.maxSeverity = sev;
|
|
121
133
|
}
|
|
@@ -126,7 +138,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
126
138
|
if (!basenameMap.has(base)) basenameMap.set(base, /* @__PURE__ */ new Set());
|
|
127
139
|
basenameMap.get(base).add(p.fileName);
|
|
128
140
|
});
|
|
129
|
-
const patterns = report.patternDetect?.results || report.patterns || [];
|
|
141
|
+
const patterns = report.patternDetect?.results || report.results || report.patterns || [];
|
|
130
142
|
patterns.forEach((entry) => {
|
|
131
143
|
const file = entry.fileName;
|
|
132
144
|
builder.addNode(
|
|
@@ -187,12 +199,12 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
187
199
|
});
|
|
188
200
|
const context = report.contextAnalyzer?.results || report.context || [];
|
|
189
201
|
context.forEach((ctx) => {
|
|
190
|
-
const file = ctx.file;
|
|
202
|
+
const file = ctx.fileName || ctx.file;
|
|
191
203
|
builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
|
|
192
204
|
if (ctx.issues && Array.isArray(ctx.issues)) {
|
|
193
205
|
ctx.issues.forEach((issue) => {
|
|
194
206
|
const sev = rankSeverity(
|
|
195
|
-
issue.severity || issue.severityLevel || null
|
|
207
|
+
typeof issue === "string" ? ctx.severity : issue.severity || issue.severityLevel || null
|
|
196
208
|
);
|
|
197
209
|
bumpIssue(file, sev);
|
|
198
210
|
});
|
|
@@ -237,7 +249,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
237
249
|
});
|
|
238
250
|
const docDriftResults = report.docDrift?.results || report.docDrift?.issues || [];
|
|
239
251
|
docDriftResults.forEach((issue) => {
|
|
240
|
-
const file = issue.location?.file;
|
|
252
|
+
const file = issue.fileName || issue.location?.file;
|
|
241
253
|
if (file) {
|
|
242
254
|
builder.addNode(file, "Doc-Drift Issue", 5);
|
|
243
255
|
const sev = rankSeverity(issue.severity || null);
|
|
@@ -246,7 +258,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
246
258
|
});
|
|
247
259
|
const depsResults = report.dependencyHealth?.results || report.deps?.issues || [];
|
|
248
260
|
depsResults.forEach((issue) => {
|
|
249
|
-
const file = issue.location?.file;
|
|
261
|
+
const file = issue.fileName || issue.location?.file;
|
|
250
262
|
if (file) {
|
|
251
263
|
builder.addNode(file, "Dependency Issue", 5);
|
|
252
264
|
const sev = rankSeverity(issue.severity || null);
|
|
@@ -257,16 +269,16 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
257
269
|
const edges = builder.edges;
|
|
258
270
|
const colorFor = (sev) => {
|
|
259
271
|
switch (sev) {
|
|
260
|
-
case
|
|
272
|
+
case Severity.Critical:
|
|
261
273
|
return "#ff4d4f";
|
|
262
274
|
// red
|
|
263
|
-
case
|
|
275
|
+
case Severity.Major:
|
|
264
276
|
return "#ff9900";
|
|
265
277
|
// orange
|
|
266
|
-
case
|
|
278
|
+
case Severity.Minor:
|
|
267
279
|
return "#ffd666";
|
|
268
280
|
// yellow
|
|
269
|
-
case
|
|
281
|
+
case Severity.Info:
|
|
270
282
|
return "#91d5ff";
|
|
271
283
|
// light blue
|
|
272
284
|
default:
|
|
@@ -284,10 +296,10 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
284
296
|
n.duplicates = rec.duplicates || 0;
|
|
285
297
|
n.color = colorFor(rec.maxSeverity);
|
|
286
298
|
n.group = builder.getPackageGroup(n.id) || void 0;
|
|
287
|
-
if (rec.maxSeverity ===
|
|
288
|
-
else if (rec.maxSeverity ===
|
|
289
|
-
else if (rec.maxSeverity ===
|
|
290
|
-
else if (rec.maxSeverity ===
|
|
299
|
+
if (rec.maxSeverity === Severity.Critical) criticalIssues += rec.count;
|
|
300
|
+
else if (rec.maxSeverity === Severity.Major) majorIssues += rec.count;
|
|
301
|
+
else if (rec.maxSeverity === Severity.Minor) minorIssues += rec.count;
|
|
302
|
+
else if (rec.maxSeverity === Severity.Info) infoIssues += rec.count;
|
|
291
303
|
} else {
|
|
292
304
|
n.color = colorFor(null);
|
|
293
305
|
n.group = builder.getPackageGroup(n.id) || void 0;
|
package/dist/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 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 {\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 (Support unified patternDetect.results or legacy patterns)\n const patterns = report.patternDetect?.results || report.patterns || [];\n 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 (Support unified patternDetect.duplicates or legacy duplicates)\n const duplicates =\n report.patternDetect?.duplicates || report.duplicates || [];\n 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 (Support unified contextAnalyzer.results or legacy context)\n const context = report.contextAnalyzer?.results || report.context || [];\n 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 {\n // ignore any edge errors\n }\n });\n\n const absoluteFile = path.resolve(builder.rootDir, file);\n const fileDir = path.dirname(absoluteFile);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.') || 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 const docDriftResults =\n report.docDrift?.results || report.docDrift?.issues || [];\n docDriftResults.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 const depsResults =\n report.dependencyHealth?.results || report.deps?.issues || [];\n depsResults.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 tokenBudget: report.scoring?.tokenBudget,\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"]}
|
|
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 { Severity, UnifiedReportSchema } from '@aiready/core';\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\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 {\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 // Optional: Validate report with Zod schema if needed, but allow partials for visualizer\n const validation = UnifiedReportSchema.safeParse(report);\n if (!validation.success) {\n console.warn(\n 'Visualizer: Report does not fully match UnifiedReportSchema, proceeding with best-effort parsing.'\n );\n }\n\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: Severity | null; duplicates: number }\n > = new Map();\n\n const rankSeverity = (s?: string | null): Severity | null => {\n if (!s) return null;\n const ss = String(s).toLowerCase();\n if (ss.includes('critical')) return Severity.Critical;\n if (ss.includes('major')) return Severity.Major;\n if (ss.includes('minor')) return Severity.Minor;\n if (ss.includes('info')) return Severity.Info;\n return null;\n };\n\n const bumpIssue = (file: string, sev?: Severity | 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 = {\n [Severity.Critical]: 3,\n [Severity.Major]: 2,\n [Severity.Minor]: 1,\n [Severity.Info]: 0,\n } as Record<Severity, number>;\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 (Support unified patternDetect.results or legacy patterns)\n const patterns =\n report.patternDetect?.results || report.results || report.patterns || [];\n 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 (Support unified patternDetect.duplicates or legacy duplicates)\n const duplicates =\n report.patternDetect?.duplicates || report.duplicates || [];\n 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 (Support unified contextAnalyzer.results or legacy context)\n const context = report.contextAnalyzer?.results || report.context || [];\n context.forEach((ctx: any) => {\n // Handle context analyzer results (which use 'file' instead of 'fileName')\n const file = ctx.fileName || 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 typeof issue === 'string'\n ? ctx.severity\n : issue.severity || issue.severityLevel || null\n );\n bumpIssue(file, sev);\n });\n }\n\n // Add related files\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 try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch {\n // ignore any edge errors\n }\n });\n\n const absoluteFile = path.resolve(builder.rootDir, file);\n const fileDir = path.dirname(absoluteFile);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.') || 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 const docDriftResults =\n report.docDrift?.results || report.docDrift?.issues || [];\n docDriftResults.forEach((issue: any) => {\n const file = issue.fileName || 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 const depsResults =\n report.dependencyHealth?.results || report.deps?.issues || [];\n depsResults.forEach((issue: any) => {\n const file = issue.fileName || 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: Severity | null) => {\n switch (sev) {\n case Severity.Critical:\n return '#ff4d4f'; // red\n case Severity.Major:\n return '#ff9900'; // orange\n case Severity.Minor:\n return '#ffd666'; // yellow\n case Severity.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 === Severity.Critical) criticalIssues += rec.count;\n else if (rec.maxSeverity === Severity.Major) majorIssues += rec.count;\n else if (rec.maxSeverity === Severity.Minor) minorIssues += rec.count;\n else if (rec.maxSeverity === Severity.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 tokenBudget: report.scoring?.tokenBudget,\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/visualizer",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Interactive graph visualization for AIReady analysis results",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"react-dom": "19.2.4",
|
|
50
50
|
"regenerator-runtime": "^0.14.1",
|
|
51
51
|
"d3": "^7",
|
|
52
|
-
"@aiready/core": "0.19.
|
|
52
|
+
"@aiready/core": "0.19.3"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@tailwindcss/vite": "^4.1.18",
|