@aiready/visualizer 0.1.37 → 0.1.40

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/index.js CHANGED
@@ -28,7 +28,8 @@ var GraphBuilder = class _GraphBuilder {
28
28
  if (!fp) return null;
29
29
  const parts = fp.split(path.sep);
30
30
  const pkgIdx = parts.indexOf("packages");
31
- if (pkgIdx >= 0 && parts.length > pkgIdx + 1) return `packages/${parts[pkgIdx + 1]}`;
31
+ if (pkgIdx >= 0 && parts.length > pkgIdx + 1)
32
+ return `packages/${parts[pkgIdx + 1]}`;
32
33
  const landingIdx = parts.indexOf("landing");
33
34
  if (landingIdx >= 0) return "landing";
34
35
  const scriptsIdx = parts.indexOf("scripts");
@@ -71,7 +72,9 @@ var GraphBuilder = class _GraphBuilder {
71
72
  */
72
73
  build() {
73
74
  const nodes = Array.from(this.nodesMap.values());
74
- const edges = this.edges.map((e) => ({ source: e.source, target: e.target, type: e.type }));
75
+ const edges = this.edges.map(
76
+ (e) => ({ source: e.source, target: e.target, type: e.type })
77
+ );
75
78
  return {
76
79
  nodes,
77
80
  edges,
@@ -107,12 +110,14 @@ var GraphBuilder = class _GraphBuilder {
107
110
  const bumpIssue = (file, sev) => {
108
111
  if (!file) return;
109
112
  const id = path.resolve(rootDir, file);
110
- if (!fileIssues.has(id)) fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });
113
+ if (!fileIssues.has(id))
114
+ fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });
111
115
  const rec = fileIssues.get(id);
112
116
  rec.count += 1;
113
117
  if (sev) {
114
118
  const order = { critical: 3, major: 2, minor: 1, info: 0 };
115
- if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity]) rec.maxSeverity = sev;
119
+ if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])
120
+ rec.maxSeverity = sev;
116
121
  }
117
122
  };
118
123
  const basenameMap = /* @__PURE__ */ new Map();
@@ -123,10 +128,16 @@ var GraphBuilder = class _GraphBuilder {
123
128
  });
124
129
  (report.patterns || []).forEach((entry) => {
125
130
  const file = entry.fileName;
126
- builder.addNode(file, `Issues: ${(entry.issues || []).length}`, entry.metrics && entry.metrics.tokenCost || 5);
131
+ builder.addNode(
132
+ file,
133
+ `Issues: ${(entry.issues || []).length}`,
134
+ entry.metrics && entry.metrics.tokenCost || 5
135
+ );
127
136
  if ((entry.issues || []).length > 0) {
128
137
  (entry.issues || []).forEach((issue) => {
129
- const sev = rankSeverity(issue.severity || issue.severityLevel || null);
138
+ const sev = rankSeverity(
139
+ issue.severity || issue.severityLevel || null
140
+ );
130
141
  bumpIssue(file, sev);
131
142
  });
132
143
  }
@@ -147,7 +158,8 @@ var GraphBuilder = class _GraphBuilder {
147
158
  if (wantFuzzy) {
148
159
  const fileGroup = builder.getPackageGroup(file);
149
160
  for (const [base, pathsSet] of basenameMap.entries()) {
150
- if (!message.includes(base) || base === path.basename(file)) continue;
161
+ if (!message.includes(base) || base === path.basename(file))
162
+ continue;
151
163
  for (const target of pathsSet) {
152
164
  const targetGroup = builder.getPackageGroup(target);
153
165
  if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;
@@ -164,8 +176,10 @@ var GraphBuilder = class _GraphBuilder {
164
176
  builder.addEdge(dup.file1, dup.file2, "similarity");
165
177
  const f1 = path.resolve(rootDir, dup.file1);
166
178
  const f2 = path.resolve(rootDir, dup.file2);
167
- if (!fileIssues.has(f1)) fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });
168
- if (!fileIssues.has(f2)) fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });
179
+ if (!fileIssues.has(f1))
180
+ fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });
181
+ if (!fileIssues.has(f2))
182
+ fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });
169
183
  fileIssues.get(f1).duplicates += 1;
170
184
  fileIssues.get(f2).duplicates += 1;
171
185
  });
@@ -174,7 +188,9 @@ var GraphBuilder = class _GraphBuilder {
174
188
  builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);
175
189
  if (ctx.issues && Array.isArray(ctx.issues)) {
176
190
  ctx.issues.forEach((issue) => {
177
- const sev = rankSeverity(issue.severity || issue.severityLevel || null);
191
+ const sev = rankSeverity(
192
+ issue.severity || issue.severityLevel || null
193
+ );
178
194
  bumpIssue(file, sev);
179
195
  });
180
196
  }
@@ -182,9 +198,12 @@ var GraphBuilder = class _GraphBuilder {
182
198
  const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);
183
199
  const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;
184
200
  const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;
185
- if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB)) return;
201
+ if (builder.edgesSet.has(keyA) || builder.edgesSet.has(keyB))
202
+ return;
186
203
  builder.addNode(resolvedRel, "Related file", 5);
187
- const n = builder.nodesMap.get(path.resolve(builder.rootDir, resolvedRel));
204
+ const n = builder.nodesMap.get(
205
+ path.resolve(builder.rootDir, resolvedRel)
206
+ );
188
207
  if (n) n.size = (n.size || 1) + 2;
189
208
  try {
190
209
  builder.addEdge(file, resolvedRel, "related");
@@ -293,7 +312,11 @@ function createSampleGraph() {
293
312
  builder.addNode("src/components/Button.tsx", "Button", 15);
294
313
  builder.addNode("src/utils/helpers.ts", "helpers", 12);
295
314
  builder.addNode("src/services/api.ts", "api", 18);
296
- builder.addEdge("src/components/Button.tsx", "src/utils/helpers.ts", "dependency");
315
+ builder.addEdge(
316
+ "src/components/Button.tsx",
317
+ "src/utils/helpers.ts",
318
+ "dependency"
319
+ );
297
320
  builder.addEdge("src/utils/helpers.ts", "src/services/api.ts", "dependency");
298
321
  return builder.build();
299
322
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/graph/builder.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Graph builder - transforms AIReady analysis results into graph data\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\n Cluster,\n IssueOverlay,\n IssueSeverity,\n} from '../types';\n\n/**\n * GraphBuilder: programmatic builder and report-based builder\n */\nexport class GraphBuilder {\n rootDir: string;\n private nodesMap: Map<string, FileNode>;\n private edges: DependencyEdge[];\n private edgesSet: Set<string>;\n\n constructor(rootDir = process.cwd()) {\n this.rootDir = rootDir;\n this.nodesMap = new Map();\n this.edges = [];\n this.edgesSet = new Set();\n }\n\n private normalizeLabel(filePath: string) {\n try {\n return path.relative(this.rootDir, filePath);\n } catch (e) {\n return filePath;\n }\n }\n\n private extractReferencedPaths(message: string): string[] {\n if (!message || typeof message !== 'string') return [];\n const reAbs = /\\/(?:[\\w\\-.]+\\/)+[\\w\\-.]+\\.(?:ts|tsx|js|jsx|py|java|go)/g;\n const reRel = /(?:\\.\\/|\\.\\.\\/)(?:[\\w\\-.]+\\/)+[\\w\\-.]+\\.(?:ts|tsx|js|jsx|py|java|go)/g;\n const abs = (message.match(reAbs) || []) as string[];\n const rel = (message.match(reRel) || []) as string[];\n return abs.concat(rel);\n }\n\n private getPackageGroup(fp?: string | null) {\n if (!fp) return null;\n const parts = fp.split(path.sep);\n const pkgIdx = parts.indexOf('packages');\n if (pkgIdx >= 0 && parts.length > pkgIdx + 1) return `packages/${parts[pkgIdx + 1]}`;\n const landingIdx = parts.indexOf('landing');\n if (landingIdx >= 0) return 'landing';\n const scriptsIdx = parts.indexOf('scripts');\n if (scriptsIdx >= 0) return 'scripts';\n return parts.length > 1 ? parts[1] : parts[0];\n }\n\n addNode(file: string, title = '', value = 1) {\n if (!file) return;\n const id = path.resolve(this.rootDir, file);\n if (!this.nodesMap.has(id)) {\n const node = {\n id,\n path: id,\n label: this.normalizeLabel(id),\n title,\n size: value || 1,\n } as any;\n this.nodesMap.set(id, node as FileNode);\n } else {\n const node = this.nodesMap.get(id)! as any;\n if (title && (!node.title || !node.title.includes(title))) {\n node.title = (node.title ? node.title + '\\n' : '') + title;\n }\n if (value > (node.size || 0)) node.size = value;\n }\n }\n\n addEdge(from: string, to: string, type: string = 'link') {\n if (!from || !to) return;\n const a = path.resolve(this.rootDir, from);\n const b = path.resolve(this.rootDir, to);\n if (a === b) return;\n const key = `${a}->${b}`;\n if (!this.edgesSet.has(key)) {\n this.edges.push({ source: a, target: b, type: (type as any) });\n this.edgesSet.add(key);\n }\n }\n\n /**\n * Build final GraphData\n */\n build(): GraphData {\n const nodes = Array.from(this.nodesMap.values());\n const edges = this.edges.map((e) => ({ source: e.source, target: e.target, type: e.type } as DependencyEdge));\n return {\n nodes,\n edges,\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 0,\n infoIssues: 0,\n },\n };\n }\n\n /**\n * Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)\n */\n static buildFromReport(report: any, rootDir = process.cwd()): GraphData {\n const builder = new GraphBuilder(rootDir);\n\n // Map to collect per-file issue aggregates\n const fileIssues: Map<string, { count: number; maxSeverity: IssueSeverity | null; duplicates: number }> = new Map();\n\n const rankSeverity = (s?: string | null): IssueSeverity | null => {\n if (!s) return null;\n const ss = String(s).toLowerCase();\n if (ss.includes('critical')) return 'critical';\n if (ss.includes('major')) return 'major';\n if (ss.includes('minor')) return 'minor';\n if (ss.includes('info')) return 'info';\n return null;\n };\n\n const bumpIssue = (file: string, sev?: IssueSeverity | null) => {\n if (!file) return;\n const id = path.resolve(rootDir, file);\n if (!fileIssues.has(id)) fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });\n const rec = fileIssues.get(id)!;\n rec.count += 1;\n if (sev) {\n const order = { critical: 3, major: 2, minor: 1, info: 0 } as Record<IssueSeverity, number>;\n if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity]) rec.maxSeverity = sev;\n }\n };\n\n // Pre-scan for basenames\n const basenameMap = new Map<string, Set<string>>();\n (report.patterns || []).forEach((p: any) => {\n const base = path.basename(p.fileName);\n if (!basenameMap.has(base)) basenameMap.set(base, new Set());\n basenameMap.get(base)!.add(p.fileName);\n });\n\n // 1. Process patterns\n (report.patterns || []).forEach((entry: any) => {\n const file = entry.fileName;\n builder.addNode(file, `Issues: ${(entry.issues || []).length}`, (entry.metrics && entry.metrics.tokenCost) || 5);\n\n // record aggregate for this file\n if ((entry.issues || []).length > 0) {\n (entry.issues || []).forEach((issue: any) => {\n const sev = rankSeverity(issue.severity || issue.severityLevel || null);\n bumpIssue(file, sev);\n });\n }\n\n (entry.issues || []).forEach((issue: any) => {\n const message = issue.message || '';\n\n // Path extraction\n const refs = builder.extractReferencedPaths(message);\n refs.forEach((ref) => {\n let target = ref;\n if (!path.isAbsolute(ref)) {\n target = path.resolve(path.dirname(file), ref);\n }\n builder.addNode(target, 'Referenced file', 5);\n builder.addEdge(file, target, 'reference');\n });\n\n // Fuzzy matching heuristics\n const percMatch = (message.match(/(\\d+)%/) || [])[1];\n const perc = percMatch ? parseInt(percMatch, 10) : null;\n const wantFuzzy = issue.type === 'duplicate-pattern' || /similar/i.test(message) || (perc && perc >= 50);\n if (wantFuzzy) {\n const fileGroup = builder.getPackageGroup(file as any);\n for (const [base, pathsSet] of basenameMap.entries()) {\n if (!message.includes(base) || base === path.basename(file)) continue;\n for (const target of pathsSet) {\n const targetGroup = builder.getPackageGroup(target as any);\n if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;\n builder.addNode(target, 'Fuzzy match', 5);\n builder.addEdge(file, target, 'similarity');\n }\n }\n }\n });\n });\n\n // 2. Duplicates\n (report.duplicates || []).forEach((dup: any) => {\n builder.addNode(dup.file1, 'Similarity target', 5);\n builder.addNode(dup.file2, 'Similarity target', 5);\n builder.addEdge(dup.file1, dup.file2, 'similarity');\n // count duplicates as issues (no explicit severity available)\n const f1 = path.resolve(rootDir, dup.file1);\n const f2 = path.resolve(rootDir, dup.file2);\n if (!fileIssues.has(f1)) fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });\n if (!fileIssues.has(f2)) fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });\n fileIssues.get(f1)!.duplicates += 1;\n fileIssues.get(f2)!.duplicates += 1;\n });\n\n // 3. Context: dependencies and related files\n (report.context || []).forEach((ctx: any) => {\n const file = ctx.file;\n builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);\n\n // context-level issues\n if (ctx.issues && Array.isArray(ctx.issues)) {\n ctx.issues.forEach((issue: any) => {\n const sev = rankSeverity(issue.severity || issue.severityLevel || null);\n bumpIssue(file, sev);\n });\n }\n\n // Add related files: do not create visual edges for 'related' links to\n // avoid clutter. Instead, increase the related node's prominence so the\n // layout reflects contextual proximity without extra lines.\n (ctx.relatedFiles || []).forEach((rel: string) => {\n const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);\n const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;\n const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;\n if ((builder as any).edgesSet.has(keyA) || (builder as any).edgesSet.has(keyB)) return;\n builder.addNode(resolvedRel, 'Related file', 5);\n // bump size to reflect relatedness\n const n = (builder as any).nodesMap.get(path.resolve(builder.rootDir, resolvedRel));\n if (n) n.size = (n.size || 1) + 2;\n // Also add a visual 'related' edge so that built/packed visualizations\n // (which use this GraphBuilder) include related connections rather\n // than only bumping node prominence.\n try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch (e) {\n // ignore any edge errors\n }\n });\n\n const fileDir = path.dirname(file);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.')) {\n const possiblePaths = [\n path.resolve(fileDir, dep),\n path.resolve(fileDir, dep + '.ts'),\n path.resolve(fileDir, dep + '.tsx'),\n path.resolve(fileDir, dep + '.js'),\n path.resolve(fileDir, dep, 'index.ts'),\n path.resolve(fileDir, dep, 'index.tsx'),\n ];\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n builder.addNode(p, 'Dependency', 2);\n builder.addEdge(file, p, 'dependency');\n break;\n }\n }\n }\n });\n });\n\n // 4. Doc Drift\n (report.docDrift?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Doc-Drift Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // 5. Dependencies\n (report.deps?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Dependency Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // Finalize nodes: assign colors and duplicate counts based on collected issue data\n const nodes = Array.from((builder as any).nodesMap.values()) as FileNode[];\n const edges = (builder as any).edges as DependencyEdge[];\n\n // Color mapping by highest severity\n const colorFor = (sev: IssueSeverity | null) => {\n switch (sev) {\n case 'critical':\n return '#ff4d4f'; // red\n case 'major':\n return '#ff9900'; // orange\n case 'minor':\n return '#ffd666'; // yellow\n case 'info':\n return '#91d5ff'; // light blue\n default:\n return '#97c2fc'; // default blue\n }\n };\n\n // Populate node-level visual props and metadata counters\n let criticalIssues = 0;\n let majorIssues = 0;\n let minorIssues = 0;\n let infoIssues = 0;\n\n for (const node of nodes) {\n const n = node as any;\n const rec = fileIssues.get(n.id);\n if (rec) {\n n.duplicates = rec.duplicates || 0;\n // choose color by maxSeverity\n n.color = colorFor(rec.maxSeverity);\n // assign package group for boundary drawing\n n.group = builder.getPackageGroup(n.id as any) || undefined;\n // increment metadata counts by severity seen on this file\n if (rec.maxSeverity === 'critical') criticalIssues += rec.count;\n else if (rec.maxSeverity === 'major') majorIssues += rec.count;\n else if (rec.maxSeverity === 'minor') minorIssues += rec.count;\n else if (rec.maxSeverity === 'info') infoIssues += rec.count;\n } else {\n n.color = colorFor(null);\n n.group = builder.getPackageGroup(n.id as any) || undefined;\n n.duplicates = 0;\n }\n }\n\n const graph: GraphData = {\n nodes,\n edges,\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues,\n majorIssues,\n minorIssues,\n infoIssues,\n },\n };\n\n return graph;\n }\n}\n\nexport function createSampleGraph(): GraphData {\n const builder = new GraphBuilder(process.cwd());\n builder.addNode('src/components/Button.tsx', 'Button', 15);\n builder.addNode('src/utils/helpers.ts', 'helpers', 12);\n builder.addNode('src/services/api.ts', 'api', 18);\n builder.addEdge('src/components/Button.tsx', 'src/utils/helpers.ts', 'dependency');\n builder.addEdge('src/utils/helpers.ts', 'src/services/api.ts', 'dependency');\n return builder.build();\n}"]}
1
+ {"version":3,"sources":["../src/graph/builder.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Graph builder - transforms AIReady analysis results into graph data\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport type {\n GraphData,\n FileNode,\n DependencyEdge,\n Cluster,\n IssueOverlay,\n IssueSeverity,\n} from '../types';\n\n/**\n * GraphBuilder: programmatic builder and report-based builder\n */\nexport class GraphBuilder {\n rootDir: string;\n private nodesMap: Map<string, FileNode>;\n private edges: DependencyEdge[];\n private edgesSet: Set<string>;\n\n constructor(rootDir = process.cwd()) {\n this.rootDir = rootDir;\n this.nodesMap = new Map();\n this.edges = [];\n this.edgesSet = new Set();\n }\n\n private normalizeLabel(filePath: string) {\n try {\n return path.relative(this.rootDir, filePath);\n } catch (e) {\n return filePath;\n }\n }\n\n private extractReferencedPaths(message: string): string[] {\n if (!message || typeof message !== 'string') return [];\n const reAbs = /\\/(?:[\\w\\-.]+\\/)+[\\w\\-.]+\\.(?:ts|tsx|js|jsx|py|java|go)/g;\n const reRel =\n /(?:\\.\\/|\\.\\.\\/)(?:[\\w\\-.]+\\/)+[\\w\\-.]+\\.(?:ts|tsx|js|jsx|py|java|go)/g;\n const abs = (message.match(reAbs) || []) as string[];\n const rel = (message.match(reRel) || []) as string[];\n return abs.concat(rel);\n }\n\n private getPackageGroup(fp?: string | null) {\n if (!fp) return null;\n const parts = fp.split(path.sep);\n const pkgIdx = parts.indexOf('packages');\n if (pkgIdx >= 0 && parts.length > pkgIdx + 1)\n return `packages/${parts[pkgIdx + 1]}`;\n const landingIdx = parts.indexOf('landing');\n if (landingIdx >= 0) return 'landing';\n const scriptsIdx = parts.indexOf('scripts');\n if (scriptsIdx >= 0) return 'scripts';\n return parts.length > 1 ? parts[1] : parts[0];\n }\n\n addNode(file: string, title = '', value = 1) {\n if (!file) return;\n const id = path.resolve(this.rootDir, file);\n if (!this.nodesMap.has(id)) {\n const node = {\n id,\n path: id,\n label: this.normalizeLabel(id),\n title,\n size: value || 1,\n } as any;\n this.nodesMap.set(id, node as FileNode);\n } else {\n const node = this.nodesMap.get(id)! as any;\n if (title && (!node.title || !node.title.includes(title))) {\n node.title = (node.title ? node.title + '\\n' : '') + title;\n }\n if (value > (node.size || 0)) node.size = value;\n }\n }\n\n addEdge(from: string, to: string, type: string = 'link') {\n if (!from || !to) return;\n const a = path.resolve(this.rootDir, from);\n const b = path.resolve(this.rootDir, to);\n if (a === b) return;\n const key = `${a}->${b}`;\n if (!this.edgesSet.has(key)) {\n this.edges.push({ source: a, target: b, type: type as any });\n this.edgesSet.add(key);\n }\n }\n\n /**\n * Build final GraphData\n */\n build(): GraphData {\n const nodes = Array.from(this.nodesMap.values());\n const edges = this.edges.map(\n (e) =>\n ({ source: e.source, target: e.target, type: e.type }) as DependencyEdge\n );\n return {\n nodes,\n edges,\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 0,\n infoIssues: 0,\n },\n };\n }\n\n /**\n * Static helper to build graph from an aiready report JSON (ports logic from tools/generate_from_report.cjs)\n */\n static buildFromReport(report: any, rootDir = process.cwd()): GraphData {\n const builder = new GraphBuilder(rootDir);\n\n // Map to collect per-file issue aggregates\n const fileIssues: Map<\n string,\n { count: number; maxSeverity: IssueSeverity | null; duplicates: number }\n > = new Map();\n\n const rankSeverity = (s?: string | null): IssueSeverity | null => {\n if (!s) return null;\n const ss = String(s).toLowerCase();\n if (ss.includes('critical')) return 'critical';\n if (ss.includes('major')) return 'major';\n if (ss.includes('minor')) return 'minor';\n if (ss.includes('info')) return 'info';\n return null;\n };\n\n const bumpIssue = (file: string, sev?: IssueSeverity | null) => {\n if (!file) return;\n const id = path.resolve(rootDir, file);\n if (!fileIssues.has(id))\n fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });\n const rec = fileIssues.get(id)!;\n rec.count += 1;\n if (sev) {\n const order = { critical: 3, major: 2, minor: 1, info: 0 } as Record<\n IssueSeverity,\n number\n >;\n if (!rec.maxSeverity || order[sev] > order[rec.maxSeverity])\n rec.maxSeverity = sev;\n }\n };\n\n // Pre-scan for basenames\n const basenameMap = new Map<string, Set<string>>();\n (report.patterns || []).forEach((p: any) => {\n const base = path.basename(p.fileName);\n if (!basenameMap.has(base)) basenameMap.set(base, new Set());\n basenameMap.get(base)!.add(p.fileName);\n });\n\n // 1. Process patterns\n (report.patterns || []).forEach((entry: any) => {\n const file = entry.fileName;\n builder.addNode(\n file,\n `Issues: ${(entry.issues || []).length}`,\n (entry.metrics && entry.metrics.tokenCost) || 5\n );\n\n // record aggregate for this file\n if ((entry.issues || []).length > 0) {\n (entry.issues || []).forEach((issue: any) => {\n const sev = rankSeverity(\n issue.severity || issue.severityLevel || null\n );\n bumpIssue(file, sev);\n });\n }\n\n (entry.issues || []).forEach((issue: any) => {\n const message = issue.message || '';\n\n // Path extraction\n const refs = builder.extractReferencedPaths(message);\n refs.forEach((ref) => {\n let target = ref;\n if (!path.isAbsolute(ref)) {\n target = path.resolve(path.dirname(file), ref);\n }\n builder.addNode(target, 'Referenced file', 5);\n builder.addEdge(file, target, 'reference');\n });\n\n // Fuzzy matching heuristics\n const percMatch = (message.match(/(\\d+)%/) || [])[1];\n const perc = percMatch ? parseInt(percMatch, 10) : null;\n const wantFuzzy =\n issue.type === 'duplicate-pattern' ||\n /similar/i.test(message) ||\n (perc && perc >= 50);\n if (wantFuzzy) {\n const fileGroup = builder.getPackageGroup(file as any);\n for (const [base, pathsSet] of basenameMap.entries()) {\n if (!message.includes(base) || base === path.basename(file))\n continue;\n for (const target of pathsSet) {\n const targetGroup = builder.getPackageGroup(target as any);\n if (fileGroup !== targetGroup && !(perc && perc >= 80)) continue;\n builder.addNode(target, 'Fuzzy match', 5);\n builder.addEdge(file, target, 'similarity');\n }\n }\n }\n });\n });\n\n // 2. Duplicates\n (report.duplicates || []).forEach((dup: any) => {\n builder.addNode(dup.file1, 'Similarity target', 5);\n builder.addNode(dup.file2, 'Similarity target', 5);\n builder.addEdge(dup.file1, dup.file2, 'similarity');\n // count duplicates as issues (no explicit severity available)\n const f1 = path.resolve(rootDir, dup.file1);\n const f2 = path.resolve(rootDir, dup.file2);\n if (!fileIssues.has(f1))\n fileIssues.set(f1, { count: 0, maxSeverity: null, duplicates: 0 });\n if (!fileIssues.has(f2))\n fileIssues.set(f2, { count: 0, maxSeverity: null, duplicates: 0 });\n fileIssues.get(f1)!.duplicates += 1;\n fileIssues.get(f2)!.duplicates += 1;\n });\n\n // 3. Context: dependencies and related files\n (report.context || []).forEach((ctx: any) => {\n const file = ctx.file;\n builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, 10);\n\n // context-level issues\n if (ctx.issues && Array.isArray(ctx.issues)) {\n ctx.issues.forEach((issue: any) => {\n const sev = rankSeverity(\n issue.severity || issue.severityLevel || null\n );\n bumpIssue(file, sev);\n });\n }\n\n // Add related files: do not create visual edges for 'related' links to\n // avoid clutter. Instead, increase the related node's prominence so the\n // layout reflects contextual proximity without extra lines.\n (ctx.relatedFiles || []).forEach((rel: string) => {\n const resolvedRel = path.isAbsolute(rel)\n ? rel\n : path.resolve(path.dirname(file), rel);\n const keyA = `${path.resolve(builder.rootDir, file)}->${path.resolve(builder.rootDir, resolvedRel)}`;\n const keyB = `${path.resolve(builder.rootDir, resolvedRel)}->${path.resolve(builder.rootDir, file)}`;\n if (\n (builder as any).edgesSet.has(keyA) ||\n (builder as any).edgesSet.has(keyB)\n )\n return;\n builder.addNode(resolvedRel, 'Related file', 5);\n // bump size to reflect relatedness\n const n = (builder as any).nodesMap.get(\n path.resolve(builder.rootDir, resolvedRel)\n );\n if (n) n.size = (n.size || 1) + 2;\n // Also add a visual 'related' edge so that built/packed visualizations\n // (which use this GraphBuilder) include related connections rather\n // than only bumping node prominence.\n try {\n builder.addEdge(file, resolvedRel, 'related');\n } catch (e) {\n // ignore any edge errors\n }\n });\n\n const fileDir = path.dirname(file);\n (ctx.dependencyList || []).forEach((dep: string) => {\n if (dep.startsWith('.')) {\n const possiblePaths = [\n path.resolve(fileDir, dep),\n path.resolve(fileDir, dep + '.ts'),\n path.resolve(fileDir, dep + '.tsx'),\n path.resolve(fileDir, dep + '.js'),\n path.resolve(fileDir, dep, 'index.ts'),\n path.resolve(fileDir, dep, 'index.tsx'),\n ];\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n builder.addNode(p, 'Dependency', 2);\n builder.addEdge(file, p, 'dependency');\n break;\n }\n }\n }\n });\n });\n\n // 4. Doc Drift\n (report.docDrift?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Doc-Drift Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // 5. Dependencies\n (report.deps?.issues || []).forEach((issue: any) => {\n const file = issue.location?.file;\n if (file) {\n builder.addNode(file, 'Dependency Issue', 5);\n const sev = rankSeverity(issue.severity || null);\n bumpIssue(file, sev);\n }\n });\n\n // Finalize nodes: assign colors and duplicate counts based on collected issue data\n const nodes = Array.from((builder as any).nodesMap.values()) as FileNode[];\n const edges = (builder as any).edges as DependencyEdge[];\n\n // Color mapping by highest severity\n const colorFor = (sev: IssueSeverity | null) => {\n switch (sev) {\n case 'critical':\n return '#ff4d4f'; // red\n case 'major':\n return '#ff9900'; // orange\n case 'minor':\n return '#ffd666'; // yellow\n case 'info':\n return '#91d5ff'; // light blue\n default:\n return '#97c2fc'; // default blue\n }\n };\n\n // Populate node-level visual props and metadata counters\n let criticalIssues = 0;\n let majorIssues = 0;\n let minorIssues = 0;\n let infoIssues = 0;\n\n for (const node of nodes) {\n const n = node as any;\n const rec = fileIssues.get(n.id);\n if (rec) {\n n.duplicates = rec.duplicates || 0;\n // choose color by maxSeverity\n n.color = colorFor(rec.maxSeverity);\n // assign package group for boundary drawing\n n.group = builder.getPackageGroup(n.id as any) || undefined;\n // increment metadata counts by severity seen on this file\n if (rec.maxSeverity === 'critical') criticalIssues += rec.count;\n else if (rec.maxSeverity === 'major') majorIssues += rec.count;\n else if (rec.maxSeverity === 'minor') minorIssues += rec.count;\n else if (rec.maxSeverity === 'info') infoIssues += rec.count;\n } else {\n n.color = colorFor(null);\n n.group = builder.getPackageGroup(n.id as any) || undefined;\n n.duplicates = 0;\n }\n }\n\n const graph: GraphData = {\n nodes,\n edges,\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: edges.length,\n analysisTypes: [],\n criticalIssues,\n majorIssues,\n minorIssues,\n infoIssues,\n },\n };\n\n return graph;\n }\n}\n\nexport function createSampleGraph(): GraphData {\n const builder = new GraphBuilder(process.cwd());\n builder.addNode('src/components/Button.tsx', 'Button', 15);\n builder.addNode('src/utils/helpers.ts', 'helpers', 12);\n builder.addNode('src/services/api.ts', 'api', 18);\n builder.addEdge(\n 'src/components/Button.tsx',\n 'src/utils/helpers.ts',\n 'dependency'\n );\n builder.addEdge('src/utils/helpers.ts', 'src/services/api.ts', 'dependency');\n return builder.build();\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/visualizer",
3
- "version": "0.1.37",
3
+ "version": "0.1.40",
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.9.32"
52
+ "@aiready/core": "0.9.35"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@tailwindcss/vite": "^4.1.18",
@@ -63,6 +63,7 @@
63
63
  },
64
64
  "scripts": {
65
65
  "dev": "tsup --watch",
66
+ "lint": "eslint src web/src --ext .ts,.tsx,.js,.jsx",
66
67
  "dev:web": "cd web && vite",
67
68
  "dev:watch-report": "node ../scripts/watch-report.js",
68
69
  "build": "tsup && cd web && vite build",