@aiready/visualizer 0.7.4 → 0.7.5

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 CHANGED
@@ -184,12 +184,43 @@ var GraphBuilder = class _GraphBuilder {
184
184
  if (Array.isArray(toolData)) return toolData;
185
185
  return toolData.results ?? toolData.issues ?? [];
186
186
  };
187
- this.processPatterns(builder, getResults(ToolName.PatternDetect, "patterns"), rootDir, bumpIssue);
187
+ this.processPatterns(
188
+ builder,
189
+ getResults(ToolName.PatternDetect, "patterns"),
190
+ rootDir,
191
+ bumpIssue
192
+ );
188
193
  this.processDuplicates(builder, report, rootDir, fileIssues);
189
- this.processContext(builder, getResults(ToolName.ContextAnalyzer, "context"), rootDir, bumpIssue);
190
- this.processToolResults(builder, ToolName.DocDrift, "docDrift", report, bumpIssue, "Doc-Drift Issue");
191
- this.processToolResults(builder, ToolName.DependencyHealth, "dependencyHealth", report, bumpIssue, "Dependency Issue");
192
- this.processToolResults(builder, ToolName.ContractEnforcement, "contractEnforcement", report, bumpIssue, "Contract Gap");
194
+ this.processContext(
195
+ builder,
196
+ getResults(ToolName.ContextAnalyzer, "context"),
197
+ rootDir,
198
+ bumpIssue
199
+ );
200
+ this.processToolResults(
201
+ builder,
202
+ ToolName.DocDrift,
203
+ "docDrift",
204
+ report,
205
+ bumpIssue,
206
+ "Doc-Drift Issue"
207
+ );
208
+ this.processToolResults(
209
+ builder,
210
+ ToolName.DependencyHealth,
211
+ "dependencyHealth",
212
+ report,
213
+ bumpIssue,
214
+ "Dependency Issue"
215
+ );
216
+ this.processToolResults(
217
+ builder,
218
+ ToolName.ContractEnforcement,
219
+ "contractEnforcement",
220
+ report,
221
+ bumpIssue,
222
+ "Contract Gap"
223
+ );
193
224
  return this.finalizeGraph(builder, fileIssues, report);
194
225
  }
195
226
  static processPatterns(builder, results, rootDir, bumpIssue) {
@@ -225,7 +256,11 @@ var GraphBuilder = class _GraphBuilder {
225
256
  const refs = extractReferencedPaths(issue.message);
226
257
  refs.forEach((ref) => {
227
258
  const target = path2.isAbsolute(ref) ? ref : path2.resolve(path2.dirname(file), ref);
228
- builder.addNode(target, "Referenced file", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
259
+ builder.addNode(
260
+ target,
261
+ "Referenced file",
262
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
263
+ );
229
264
  builder.addEdge(file, target, "reference");
230
265
  });
231
266
  const percMatch = (issue.message.match(/(\d+)%/) || [])[1];
@@ -234,11 +269,17 @@ var GraphBuilder = class _GraphBuilder {
234
269
  if (wantFuzzy) {
235
270
  const fileGroup = getPackageGroup(file);
236
271
  for (const [base, pathsSet] of basenameMap.entries()) {
237
- if (!issue.message.includes(base) || base === path2.basename(file)) continue;
272
+ if (!issue.message.includes(base) || base === path2.basename(file))
273
+ continue;
238
274
  for (const target of pathsSet) {
239
275
  const targetGroup = getPackageGroup(target);
240
- if (fileGroup !== targetGroup && !(perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_HIGH_THRESHOLD)) continue;
241
- builder.addNode(target, "Fuzzy match", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
276
+ if (fileGroup !== targetGroup && !(perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_HIGH_THRESHOLD))
277
+ continue;
278
+ builder.addNode(
279
+ target,
280
+ "Fuzzy match",
281
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
282
+ );
242
283
  builder.addEdge(file, target, "similarity");
243
284
  }
244
285
  }
@@ -250,8 +291,16 @@ var GraphBuilder = class _GraphBuilder {
250
291
  const patternData = report[ToolName.PatternDetect] || report.patternDetect || report.patterns || {};
251
292
  const duplicates = (Array.isArray(patternData.duplicates) ? patternData.duplicates : null) || (patternData.summary && Array.isArray(patternData.summary.duplicates) ? patternData.summary.duplicates : null) || (Array.isArray(report.duplicates) ? report.duplicates : []);
252
293
  duplicates.forEach((dup) => {
253
- builder.addNode(dup.file1, "Similarity target", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
254
- builder.addNode(dup.file2, "Similarity target", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
294
+ builder.addNode(
295
+ dup.file1,
296
+ "Similarity target",
297
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
298
+ );
299
+ builder.addNode(
300
+ dup.file2,
301
+ "Similarity target",
302
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
303
+ );
255
304
  builder.addEdge(dup.file1, dup.file2, "similarity");
256
305
  [dup.file1, dup.file2].forEach((file) => {
257
306
  const id = path2.resolve(rootDir, file);
@@ -267,7 +316,11 @@ var GraphBuilder = class _GraphBuilder {
267
316
  const normalized = normalizeAnalysisResult(ctx);
268
317
  const file = normalized.fileName;
269
318
  if (!file) return;
270
- builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, GRAPH_CONSTANTS.DEFAULT_CONTEXT_SIZE);
319
+ builder.addNode(
320
+ file,
321
+ `Deps: ${ctx.dependencyCount || 0}`,
322
+ GRAPH_CONSTANTS.DEFAULT_CONTEXT_SIZE
323
+ );
271
324
  normalized.issues.forEach((issue) => {
272
325
  bumpIssue(file, issue.severity);
273
326
  });
@@ -277,8 +330,13 @@ var GraphBuilder = class _GraphBuilder {
277
330
  const resolvedTarget = path2.resolve(builder.rootDir, resolvedRel);
278
331
  const keyA = `${resolvedFile}->${resolvedTarget}`;
279
332
  const keyB = `${resolvedTarget}->${resolvedFile}`;
280
- if (builder["edgesSet"].has(keyA) || builder["edgesSet"].has(keyB)) return;
281
- builder.addNode(resolvedRel, "Related file", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
333
+ if (builder["edgesSet"].has(keyA) || builder["edgesSet"].has(keyB))
334
+ return;
335
+ builder.addNode(
336
+ resolvedRel,
337
+ "Related file",
338
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
339
+ );
282
340
  const node = builder["nodesMap"].get(resolvedTarget);
283
341
  if (node) {
284
342
  node.size = (node.size || 1) + 2;
@@ -298,7 +356,11 @@ var GraphBuilder = class _GraphBuilder {
298
356
  ];
299
357
  for (const p of possiblePaths) {
300
358
  if (fs.existsSync(p)) {
301
- builder.addNode(p, "Dependency", GRAPH_CONSTANTS.DEFAULT_DEPENDENCY_SIZE);
359
+ builder.addNode(
360
+ p,
361
+ "Dependency",
362
+ GRAPH_CONSTANTS.DEFAULT_DEPENDENCY_SIZE
363
+ );
302
364
  builder.addEdge(file, p, "dependency");
303
365
  break;
304
366
  }
@@ -343,10 +405,14 @@ var GraphBuilder = class _GraphBuilder {
343
405
  node.duplicates = record.duplicates || 0;
344
406
  node.color = getColorForSeverity(record.maxSeverity);
345
407
  node.group = getPackageGroup(node.id);
346
- if (record.maxSeverity === Severity.Critical) criticalIssues += record.count;
347
- else if (record.maxSeverity === Severity.Major) majorIssues += record.count;
348
- else if (record.maxSeverity === Severity.Minor) minorIssues += record.count;
349
- else if (record.maxSeverity === Severity.Info) infoIssues += record.count;
408
+ if (record.maxSeverity === Severity.Critical)
409
+ criticalIssues += record.count;
410
+ else if (record.maxSeverity === Severity.Major)
411
+ majorIssues += record.count;
412
+ else if (record.maxSeverity === Severity.Minor)
413
+ minorIssues += record.count;
414
+ else if (record.maxSeverity === Severity.Info)
415
+ infoIssues += record.count;
350
416
  } else {
351
417
  node.color = getColorForSeverity(null);
352
418
  node.group = getPackageGroup(node.id);
@@ -369,7 +435,11 @@ function createSampleGraph() {
369
435
  builder.addNode("src/components/Button.tsx", "Button", 15);
370
436
  builder.addNode("src/utils/helpers.ts", "helpers", 12);
371
437
  builder.addNode("src/services/api.ts", "api", 18);
372
- builder.addEdge("src/components/Button.tsx", "src/utils/helpers.ts", "dependency");
438
+ builder.addEdge(
439
+ "src/components/Button.tsx",
440
+ "src/utils/helpers.ts",
441
+ "dependency"
442
+ );
373
443
  builder.addEdge("src/utils/helpers.ts", "src/services/api.ts", "dependency");
374
444
  return builder.build();
375
445
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/graph/utils.ts","../src/graph/builder.ts","../src/cli/index.ts"],"names":["path","file","Severity","__filename","__dirname"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Graph builder utilities\n */\n\nimport path from 'path';\nimport { Severity } from '@aiready/core';\n\n/**\n * Constants for graph building\n */\nexport const GRAPH_CONSTANTS = {\n DEFAULT_NODE_SIZE: 1,\n DEFAULT_REFERENCE_SIZE: 5,\n DEFAULT_DEPENDENCY_SIZE: 2,\n DEFAULT_CONTEXT_SIZE: 10,\n FUZZY_MATCH_THRESHOLD: 50,\n FUZZY_MATCH_HIGH_THRESHOLD: 80,\n COLORS: {\n CRITICAL: '#ff4d4f',\n MAJOR: '#ff9900',\n MINOR: '#ffd666',\n INFO: '#91d5ff',\n DEFAULT: '#97c2fc',\n },\n SEVERITY_ORDER: {\n [Severity.Critical]: 3,\n [Severity.Major]: 2,\n [Severity.Minor]: 1,\n [Severity.Info]: 0,\n } as Record<Severity, number>,\n};\n\n/**\n * Normalizes a file path relative to a root directory for labels.\n */\nexport function normalizeLabel(filePath: string, rootDir: string): string {\n try {\n return path.relative(rootDir, filePath);\n } catch {\n return filePath;\n }\n}\n\n/**\n * Extracts absolute and relative file paths from a message string.\n */\nexport function 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/**\n * Determines the package or module group for a given file path.\n */\nexport function getPackageGroup(\n fp: string | null | undefined\n): string | undefined {\n if (!fp) return undefined;\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/**\n * Ranks severity from a string or null.\n */\nexport function rankSeverity(s: string | null | undefined): 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/**\n * Returns a color string for a given severity.\n */\nexport function getColorForSeverity(sev: Severity | null): string {\n switch (sev) {\n case Severity.Critical:\n return GRAPH_CONSTANTS.COLORS.CRITICAL;\n case Severity.Major:\n return GRAPH_CONSTANTS.COLORS.MAJOR;\n case Severity.Minor:\n return GRAPH_CONSTANTS.COLORS.MINOR;\n case Severity.Info:\n return GRAPH_CONSTANTS.COLORS.INFO;\n default:\n return GRAPH_CONSTANTS.COLORS.DEFAULT;\n }\n}\n","/**\n * Graph builder - transforms AIReady analysis results into graph data\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport {\n Severity,\n UnifiedReportSchema,\n ToolName,\n normalizeAnalysisResult,\n type Issue,\n} from '@aiready/core';\nimport type { GraphData, FileNode, DependencyEdge } from '../types';\nimport {\n GRAPH_CONSTANTS,\n normalizeLabel,\n extractReferencedPaths,\n getPackageGroup,\n rankSeverity,\n getColorForSeverity,\n} from './utils';\n\n/**\n * Metadata for tracking file-level issue aggregates during graph building.\n */\ninterface FileIssueRecord {\n count: number;\n maxSeverity: Severity | null;\n duplicates: number;\n}\n\n/**\n * GraphBuilder: programmatic builder and report-based builder.\n * @lastUpdated 2026-03-27\n */\nexport class GraphBuilder {\n private readonly rootDir: string;\n private readonly nodesMap: Map<string, FileNode>;\n private readonly edges: DependencyEdge[];\n private readonly 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 /**\n * Add a new node to the graph or update an existing one.\n */\n addNode(file: string, title = '', size = GRAPH_CONSTANTS.DEFAULT_NODE_SIZE): void {\n if (!file) return;\n const id = path.resolve(this.rootDir, file);\n const existingNode = this.nodesMap.get(id);\n\n if (!existingNode) {\n const node: FileNode = {\n id,\n path: id,\n label: normalizeLabel(id, this.rootDir),\n title,\n size: size,\n };\n this.nodesMap.set(id, node);\n } else {\n if (title && (!existingNode.title || !existingNode.title.includes(title))) {\n existingNode.title = (existingNode.title ? existingNode.title + '\\n' : '') + title;\n }\n if (size > (existingNode.size ?? 0)) {\n existingNode.size = size;\n }\n }\n }\n\n /**\n * Add a directed edge between two nodes in the graph.\n */\n addEdge(from: string, to: string, type: string = 'link'): void {\n if (!from || !to) return;\n const source = path.resolve(this.rootDir, from);\n const target = path.resolve(this.rootDir, to);\n if (source === target) return;\n\n const key = `${source}->${target}`;\n if (!this.edgesSet.has(key)) {\n this.edges.push({ source, target, type: type as any });\n this.edgesSet.add(key);\n }\n }\n\n /**\n * Build the final GraphData object from collected nodes and edges.\n */\n build(): GraphData {\n const nodes = Array.from(this.nodesMap.values());\n return {\n nodes,\n edges: [...this.edges],\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: this.edges.length,\n analysisTypes: [],\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 0,\n infoIssues: 0,\n },\n truncated: {\n nodes: false,\n edges: false,\n },\n };\n }\n\n /**\n * Static helper to build graph from an AIReady report JSON.\n */\n static buildFromReport(report: any, rootDir = process.cwd()): GraphData {\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 const fileIssues = new Map<string, FileIssueRecord>();\n\n const bumpIssue = (file: string, severity?: 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 }\n const record = fileIssues.get(id)!;\n record.count += 1;\n\n if (severity) {\n if (\n !record.maxSeverity ||\n GRAPH_CONSTANTS.SEVERITY_ORDER[severity] > GRAPH_CONSTANTS.SEVERITY_ORDER[record.maxSeverity]\n ) {\n record.maxSeverity = severity;\n }\n }\n };\n\n const getResults = (toolKey: string, legacyKey?: string): any[] => {\n const camelKey = toolKey.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const toolData = report[toolKey] ?? report[camelKey] ?? (legacyKey ? report[legacyKey] : undefined);\n if (!toolData) return [];\n if (Array.isArray(toolData)) return toolData;\n return toolData.results ?? toolData.issues ?? [];\n };\n\n // 1. Process Pattern Detect\n this.processPatterns(builder, getResults(ToolName.PatternDetect, 'patterns'), rootDir, bumpIssue);\n\n // 2. Process Duplicates\n this.processDuplicates(builder, report, rootDir, fileIssues);\n\n // 3. Process Context Analyzer\n this.processContext(builder, getResults(ToolName.ContextAnalyzer, 'context'), rootDir, bumpIssue);\n\n // 4. Process Other Tools\n this.processToolResults(builder, ToolName.DocDrift, 'docDrift', report, bumpIssue, 'Doc-Drift Issue');\n this.processToolResults(builder, ToolName.DependencyHealth, 'dependencyHealth', report, bumpIssue, 'Dependency Issue');\n this.processToolResults(builder, ToolName.ContractEnforcement, 'contractEnforcement', report, bumpIssue, 'Contract Gap');\n\n return this.finalizeGraph(builder, fileIssues, report);\n }\n\n private static processPatterns(\n builder: GraphBuilder,\n results: any[],\n rootDir: string,\n bumpIssue: (file: string, sev?: Severity | null) => void\n ): void {\n const basenameMap = new Map<string, Set<string>>();\n results.forEach((p: any) => {\n const fileName = p.fileName ?? p.file;\n if (fileName) {\n const base = path.basename(fileName);\n if (!basenameMap.has(base)) basenameMap.set(base, new Set());\n basenameMap.get(base)!.add(fileName);\n }\n });\n\n results.forEach((entry: any) => {\n const normalized = normalizeAnalysisResult(entry);\n const file = normalized.fileName;\n if (!file) return;\n\n builder.addNode(\n file,\n `Issues: ${normalized.issues.length}`,\n normalized.metrics.tokenCost || GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n\n // We use entry.issues directly if available to detect unspecified severity\n const rawIssues = Array.isArray(entry.issues) ? entry.issues : [];\n if (rawIssues.length > 0) {\n rawIssues.forEach((issue: any) => {\n bumpIssue(file, rankSeverity(issue.severity));\n });\n } else {\n normalized.issues.forEach((issue: Issue) => {\n bumpIssue(file, issue.severity);\n });\n }\n\n normalized.issues.forEach((issue: Issue) => {\n const refs = extractReferencedPaths(issue.message);\n refs.forEach((ref) => {\n const target = path.isAbsolute(ref) ? ref : path.resolve(path.dirname(file), ref);\n builder.addNode(target, 'Referenced file', GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n builder.addEdge(file, target, 'reference');\n });\n\n const percMatch = (issue.message.match(/(\\d+)%/) || [])[1];\n const perc = percMatch ? parseInt(percMatch, 10) : null;\n const wantFuzzy =\n issue.type === 'duplicate-pattern' ||\n /similar/i.test(issue.message) ||\n (perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_THRESHOLD);\n\n if (wantFuzzy) {\n const fileGroup = getPackageGroup(file);\n for (const [base, pathsSet] of basenameMap.entries()) {\n if (!issue.message.includes(base) || base === path.basename(file)) continue;\n for (const target of pathsSet) {\n const targetGroup = getPackageGroup(target);\n if (fileGroup !== targetGroup && !(perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_HIGH_THRESHOLD)) continue;\n builder.addNode(target, 'Fuzzy match', GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n builder.addEdge(file, target, 'similarity');\n }\n }\n }\n });\n });\n }\n\n private static processDuplicates(\n builder: GraphBuilder,\n report: any,\n rootDir: string,\n fileIssues: Map<string, FileIssueRecord>\n ): void {\n const patternData = report[ToolName.PatternDetect] || report.patternDetect || report.patterns || {};\n const duplicates =\n (Array.isArray(patternData.duplicates) ? patternData.duplicates : null) ||\n (patternData.summary && Array.isArray(patternData.summary.duplicates) ? patternData.summary.duplicates : null) ||\n (Array.isArray(report.duplicates) ? report.duplicates : []);\n\n duplicates.forEach((dup: any) => {\n builder.addNode(dup.file1, 'Similarity target', GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n builder.addNode(dup.file2, 'Similarity target', GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n builder.addEdge(dup.file1, dup.file2, 'similarity');\n\n [dup.file1, dup.file2].forEach((file) => {\n const id = path.resolve(rootDir, file);\n if (!fileIssues.has(id)) {\n fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });\n }\n fileIssues.get(id)!.duplicates += 1;\n });\n });\n }\n\n private static processContext(\n builder: GraphBuilder,\n results: any[],\n rootDir: string,\n bumpIssue: (file: string, sev?: Severity | null) => void\n ): void {\n results.forEach((ctx: any) => {\n const normalized = normalizeAnalysisResult(ctx);\n const file = normalized.fileName;\n if (!file) return;\n\n builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, GRAPH_CONSTANTS.DEFAULT_CONTEXT_SIZE);\n\n normalized.issues.forEach((issue: Issue) => {\n bumpIssue(file, issue.severity);\n });\n\n (ctx.relatedFiles ?? []).forEach((rel: string) => {\n const resolvedRel = path.isAbsolute(rel) ? rel : path.resolve(path.dirname(file), rel);\n const resolvedFile = path.resolve(builder.rootDir, file);\n const resolvedTarget = path.resolve(builder.rootDir, resolvedRel);\n\n const keyA = `${resolvedFile}->${resolvedTarget}`;\n const keyB = `${resolvedTarget}->${resolvedFile}`;\n\n if (builder['edgesSet'].has(keyA) || builder['edgesSet'].has(keyB)) return;\n\n builder.addNode(resolvedRel, 'Related file', GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n\n const node = builder['nodesMap'].get(resolvedTarget);\n if (node) {\n node.size = (node.size || 1) + 2;\n }\n builder.addEdge(file, resolvedRel, 'related');\n });\n\n const fileDir = path.dirname(path.resolve(builder.rootDir, file));\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', GRAPH_CONSTANTS.DEFAULT_DEPENDENCY_SIZE);\n builder.addEdge(file, p, 'dependency');\n break;\n }\n }\n }\n });\n });\n }\n\n private static processToolResults(\n builder: GraphBuilder,\n toolName: ToolName,\n legacyKey: string,\n report: any,\n bumpIssue: (file: string, sev?: Severity | null) => void,\n title: string\n ): void {\n const camelKey = toolName.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const toolData = report[toolName] ?? report[camelKey] ?? report[legacyKey];\n if (!toolData) return;\n\n const results = Array.isArray(toolData) ? toolData : toolData.results ?? toolData.issues ?? [];\n results.forEach((item: any) => {\n // Support flat format where item IS the issue (seen in tests and legacy outputs)\n if (!Array.isArray(item.issues) && (item.severity || item.message)) {\n const file = item.fileName ?? item.file ?? item.location?.file;\n if (file) {\n builder.addNode(file, title, GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n bumpIssue(file, rankSeverity(item.severity));\n }\n return;\n }\n\n const normalized = normalizeAnalysisResult(item);\n const file = normalized.fileName;\n if (file) {\n builder.addNode(file, title, GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n normalized.issues.forEach((issue) => {\n bumpIssue(file, issue.severity);\n });\n }\n });\n }\n\n private static finalizeGraph(builder: GraphBuilder, fileIssues: Map<string, FileIssueRecord>, report: any): GraphData {\n const graph = builder.build();\n\n let criticalIssues = 0;\n let majorIssues = 0;\n let minorIssues = 0;\n let infoIssues = 0;\n\n graph.nodes.forEach((node) => {\n const record = fileIssues.get(node.id);\n if (record) {\n node.duplicates = record.duplicates || 0;\n node.color = getColorForSeverity(record.maxSeverity);\n node.group = getPackageGroup(node.id);\n\n if (record.maxSeverity === Severity.Critical) criticalIssues += record.count;\n else if (record.maxSeverity === Severity.Major) majorIssues += record.count;\n else if (record.maxSeverity === Severity.Minor) minorIssues += record.count;\n else if (record.maxSeverity === Severity.Info) infoIssues += record.count;\n } else {\n node.color = getColorForSeverity(null);\n node.group = getPackageGroup(node.id);\n node.duplicates = 0;\n }\n });\n\n graph.metadata = {\n ...graph.metadata,\n criticalIssues,\n majorIssues,\n minorIssues,\n infoIssues,\n tokenBudget: report.scoring?.tokenBudget,\n };\n\n return graph;\n }\n}\n\n/**\n * Create a small sample graph for demonstration or testing purposes.\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}\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/utils.ts","../src/graph/builder.ts","../src/cli/index.ts"],"names":["path","file","Severity","__filename","__dirname"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Graph builder utilities\n */\n\nimport path from 'path';\nimport { Severity } from '@aiready/core';\n\n/**\n * Constants for graph building\n */\nexport const GRAPH_CONSTANTS = {\n DEFAULT_NODE_SIZE: 1,\n DEFAULT_REFERENCE_SIZE: 5,\n DEFAULT_DEPENDENCY_SIZE: 2,\n DEFAULT_CONTEXT_SIZE: 10,\n FUZZY_MATCH_THRESHOLD: 50,\n FUZZY_MATCH_HIGH_THRESHOLD: 80,\n COLORS: {\n CRITICAL: '#ff4d4f',\n MAJOR: '#ff9900',\n MINOR: '#ffd666',\n INFO: '#91d5ff',\n DEFAULT: '#97c2fc',\n },\n SEVERITY_ORDER: {\n [Severity.Critical]: 3,\n [Severity.Major]: 2,\n [Severity.Minor]: 1,\n [Severity.Info]: 0,\n } as Record<Severity, number>,\n};\n\n/**\n * Normalizes a file path relative to a root directory for labels.\n */\nexport function normalizeLabel(filePath: string, rootDir: string): string {\n try {\n return path.relative(rootDir, filePath);\n } catch {\n return filePath;\n }\n}\n\n/**\n * Extracts absolute and relative file paths from a message string.\n */\nexport function 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/**\n * Determines the package or module group for a given file path.\n */\nexport function getPackageGroup(\n fp: string | null | undefined\n): string | undefined {\n if (!fp) return undefined;\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/**\n * Ranks severity from a string or null.\n */\nexport function rankSeverity(s: string | null | undefined): 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/**\n * Returns a color string for a given severity.\n */\nexport function getColorForSeverity(sev: Severity | null): string {\n switch (sev) {\n case Severity.Critical:\n return GRAPH_CONSTANTS.COLORS.CRITICAL;\n case Severity.Major:\n return GRAPH_CONSTANTS.COLORS.MAJOR;\n case Severity.Minor:\n return GRAPH_CONSTANTS.COLORS.MINOR;\n case Severity.Info:\n return GRAPH_CONSTANTS.COLORS.INFO;\n default:\n return GRAPH_CONSTANTS.COLORS.DEFAULT;\n }\n}\n","/**\n * Graph builder - transforms AIReady analysis results into graph data\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport {\n Severity,\n UnifiedReportSchema,\n ToolName,\n normalizeAnalysisResult,\n type Issue,\n} from '@aiready/core';\nimport type { GraphData, FileNode, DependencyEdge } from '../types';\nimport {\n GRAPH_CONSTANTS,\n normalizeLabel,\n extractReferencedPaths,\n getPackageGroup,\n rankSeverity,\n getColorForSeverity,\n} from './utils';\n\n/**\n * Metadata for tracking file-level issue aggregates during graph building.\n */\ninterface FileIssueRecord {\n count: number;\n maxSeverity: Severity | null;\n duplicates: number;\n}\n\n/**\n * GraphBuilder: programmatic builder and report-based builder.\n * @lastUpdated 2026-03-27\n */\nexport class GraphBuilder {\n private readonly rootDir: string;\n private readonly nodesMap: Map<string, FileNode>;\n private readonly edges: DependencyEdge[];\n private readonly 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 /**\n * Add a new node to the graph or update an existing one.\n */\n addNode(\n file: string,\n title = '',\n size = GRAPH_CONSTANTS.DEFAULT_NODE_SIZE\n ): void {\n if (!file) return;\n const id = path.resolve(this.rootDir, file);\n const existingNode = this.nodesMap.get(id);\n\n if (!existingNode) {\n const node: FileNode = {\n id,\n path: id,\n label: normalizeLabel(id, this.rootDir),\n title,\n size: size,\n };\n this.nodesMap.set(id, node);\n } else {\n if (\n title &&\n (!existingNode.title || !existingNode.title.includes(title))\n ) {\n existingNode.title =\n (existingNode.title ? existingNode.title + '\\n' : '') + title;\n }\n if (size > (existingNode.size ?? 0)) {\n existingNode.size = size;\n }\n }\n }\n\n /**\n * Add a directed edge between two nodes in the graph.\n */\n addEdge(from: string, to: string, type: string = 'link'): void {\n if (!from || !to) return;\n const source = path.resolve(this.rootDir, from);\n const target = path.resolve(this.rootDir, to);\n if (source === target) return;\n\n const key = `${source}->${target}`;\n if (!this.edgesSet.has(key)) {\n this.edges.push({ source, target, type: type as any });\n this.edgesSet.add(key);\n }\n }\n\n /**\n * Build the final GraphData object from collected nodes and edges.\n */\n build(): GraphData {\n const nodes = Array.from(this.nodesMap.values());\n return {\n nodes,\n edges: [...this.edges],\n clusters: [],\n issues: [],\n metadata: {\n timestamp: new Date().toISOString(),\n totalFiles: nodes.length,\n totalDependencies: this.edges.length,\n analysisTypes: [],\n criticalIssues: 0,\n majorIssues: 0,\n minorIssues: 0,\n infoIssues: 0,\n },\n truncated: {\n nodes: false,\n edges: false,\n },\n };\n }\n\n /**\n * Static helper to build graph from an AIReady report JSON.\n */\n static buildFromReport(report: any, rootDir = process.cwd()): GraphData {\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 const fileIssues = new Map<string, FileIssueRecord>();\n\n const bumpIssue = (file: string, severity?: 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 }\n const record = fileIssues.get(id)!;\n record.count += 1;\n\n if (severity) {\n if (\n !record.maxSeverity ||\n GRAPH_CONSTANTS.SEVERITY_ORDER[severity] >\n GRAPH_CONSTANTS.SEVERITY_ORDER[record.maxSeverity]\n ) {\n record.maxSeverity = severity;\n }\n }\n };\n\n const getResults = (toolKey: string, legacyKey?: string): any[] => {\n const camelKey = toolKey.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const toolData =\n report[toolKey] ??\n report[camelKey] ??\n (legacyKey ? report[legacyKey] : undefined);\n if (!toolData) return [];\n if (Array.isArray(toolData)) return toolData;\n return toolData.results ?? toolData.issues ?? [];\n };\n\n // 1. Process Pattern Detect\n this.processPatterns(\n builder,\n getResults(ToolName.PatternDetect, 'patterns'),\n rootDir,\n bumpIssue\n );\n\n // 2. Process Duplicates\n this.processDuplicates(builder, report, rootDir, fileIssues);\n\n // 3. Process Context Analyzer\n this.processContext(\n builder,\n getResults(ToolName.ContextAnalyzer, 'context'),\n rootDir,\n bumpIssue\n );\n\n // 4. Process Other Tools\n this.processToolResults(\n builder,\n ToolName.DocDrift,\n 'docDrift',\n report,\n bumpIssue,\n 'Doc-Drift Issue'\n );\n this.processToolResults(\n builder,\n ToolName.DependencyHealth,\n 'dependencyHealth',\n report,\n bumpIssue,\n 'Dependency Issue'\n );\n this.processToolResults(\n builder,\n ToolName.ContractEnforcement,\n 'contractEnforcement',\n report,\n bumpIssue,\n 'Contract Gap'\n );\n\n return this.finalizeGraph(builder, fileIssues, report);\n }\n\n private static processPatterns(\n builder: GraphBuilder,\n results: any[],\n rootDir: string,\n bumpIssue: (file: string, sev?: Severity | null) => void\n ): void {\n const basenameMap = new Map<string, Set<string>>();\n results.forEach((p: any) => {\n const fileName = p.fileName ?? p.file;\n if (fileName) {\n const base = path.basename(fileName);\n if (!basenameMap.has(base)) basenameMap.set(base, new Set());\n basenameMap.get(base)!.add(fileName);\n }\n });\n\n results.forEach((entry: any) => {\n const normalized = normalizeAnalysisResult(entry);\n const file = normalized.fileName;\n if (!file) return;\n\n builder.addNode(\n file,\n `Issues: ${normalized.issues.length}`,\n normalized.metrics.tokenCost || GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n\n // We use entry.issues directly if available to detect unspecified severity\n const rawIssues = Array.isArray(entry.issues) ? entry.issues : [];\n if (rawIssues.length > 0) {\n rawIssues.forEach((issue: any) => {\n bumpIssue(file, rankSeverity(issue.severity));\n });\n } else {\n normalized.issues.forEach((issue: Issue) => {\n bumpIssue(file, issue.severity);\n });\n }\n\n normalized.issues.forEach((issue: Issue) => {\n const refs = extractReferencedPaths(issue.message);\n refs.forEach((ref) => {\n const target = path.isAbsolute(ref)\n ? ref\n : path.resolve(path.dirname(file), ref);\n builder.addNode(\n target,\n 'Referenced file',\n GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n builder.addEdge(file, target, 'reference');\n });\n\n const percMatch = (issue.message.match(/(\\d+)%/) || [])[1];\n const perc = percMatch ? parseInt(percMatch, 10) : null;\n const wantFuzzy =\n issue.type === 'duplicate-pattern' ||\n /similar/i.test(issue.message) ||\n (perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_THRESHOLD);\n\n if (wantFuzzy) {\n const fileGroup = getPackageGroup(file);\n for (const [base, pathsSet] of basenameMap.entries()) {\n if (!issue.message.includes(base) || base === path.basename(file))\n continue;\n for (const target of pathsSet) {\n const targetGroup = getPackageGroup(target);\n if (\n fileGroup !== targetGroup &&\n !(\n perc !== null &&\n perc >= GRAPH_CONSTANTS.FUZZY_MATCH_HIGH_THRESHOLD\n )\n )\n continue;\n builder.addNode(\n target,\n 'Fuzzy match',\n GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n builder.addEdge(file, target, 'similarity');\n }\n }\n }\n });\n });\n }\n\n private static processDuplicates(\n builder: GraphBuilder,\n report: any,\n rootDir: string,\n fileIssues: Map<string, FileIssueRecord>\n ): void {\n const patternData =\n report[ToolName.PatternDetect] ||\n report.patternDetect ||\n report.patterns ||\n {};\n const duplicates =\n (Array.isArray(patternData.duplicates) ? patternData.duplicates : null) ||\n (patternData.summary && Array.isArray(patternData.summary.duplicates)\n ? patternData.summary.duplicates\n : null) ||\n (Array.isArray(report.duplicates) ? report.duplicates : []);\n\n duplicates.forEach((dup: any) => {\n builder.addNode(\n dup.file1,\n 'Similarity target',\n GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n builder.addNode(\n dup.file2,\n 'Similarity target',\n GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n builder.addEdge(dup.file1, dup.file2, 'similarity');\n\n [dup.file1, dup.file2].forEach((file) => {\n const id = path.resolve(rootDir, file);\n if (!fileIssues.has(id)) {\n fileIssues.set(id, { count: 0, maxSeverity: null, duplicates: 0 });\n }\n fileIssues.get(id)!.duplicates += 1;\n });\n });\n }\n\n private static processContext(\n builder: GraphBuilder,\n results: any[],\n rootDir: string,\n bumpIssue: (file: string, sev?: Severity | null) => void\n ): void {\n results.forEach((ctx: any) => {\n const normalized = normalizeAnalysisResult(ctx);\n const file = normalized.fileName;\n if (!file) return;\n\n builder.addNode(\n file,\n `Deps: ${ctx.dependencyCount || 0}`,\n GRAPH_CONSTANTS.DEFAULT_CONTEXT_SIZE\n );\n\n normalized.issues.forEach((issue: Issue) => {\n bumpIssue(file, issue.severity);\n });\n\n (ctx.relatedFiles ?? []).forEach((rel: string) => {\n const resolvedRel = path.isAbsolute(rel)\n ? rel\n : path.resolve(path.dirname(file), rel);\n const resolvedFile = path.resolve(builder.rootDir, file);\n const resolvedTarget = path.resolve(builder.rootDir, resolvedRel);\n\n const keyA = `${resolvedFile}->${resolvedTarget}`;\n const keyB = `${resolvedTarget}->${resolvedFile}`;\n\n if (builder['edgesSet'].has(keyA) || builder['edgesSet'].has(keyB))\n return;\n\n builder.addNode(\n resolvedRel,\n 'Related file',\n GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE\n );\n\n const node = builder['nodesMap'].get(resolvedTarget);\n if (node) {\n node.size = (node.size || 1) + 2;\n }\n builder.addEdge(file, resolvedRel, 'related');\n });\n\n const fileDir = path.dirname(path.resolve(builder.rootDir, file));\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(\n p,\n 'Dependency',\n GRAPH_CONSTANTS.DEFAULT_DEPENDENCY_SIZE\n );\n builder.addEdge(file, p, 'dependency');\n break;\n }\n }\n }\n });\n });\n }\n\n private static processToolResults(\n builder: GraphBuilder,\n toolName: ToolName,\n legacyKey: string,\n report: any,\n bumpIssue: (file: string, sev?: Severity | null) => void,\n title: string\n ): void {\n const camelKey = toolName.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const toolData = report[toolName] ?? report[camelKey] ?? report[legacyKey];\n if (!toolData) return;\n\n const results = Array.isArray(toolData)\n ? toolData\n : (toolData.results ?? toolData.issues ?? []);\n results.forEach((item: any) => {\n // Support flat format where item IS the issue (seen in tests and legacy outputs)\n if (!Array.isArray(item.issues) && (item.severity || item.message)) {\n const file = item.fileName ?? item.file ?? item.location?.file;\n if (file) {\n builder.addNode(file, title, GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n bumpIssue(file, rankSeverity(item.severity));\n }\n return;\n }\n\n const normalized = normalizeAnalysisResult(item);\n const file = normalized.fileName;\n if (file) {\n builder.addNode(file, title, GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);\n normalized.issues.forEach((issue) => {\n bumpIssue(file, issue.severity);\n });\n }\n });\n }\n\n private static finalizeGraph(\n builder: GraphBuilder,\n fileIssues: Map<string, FileIssueRecord>,\n report: any\n ): GraphData {\n const graph = builder.build();\n\n let criticalIssues = 0;\n let majorIssues = 0;\n let minorIssues = 0;\n let infoIssues = 0;\n\n graph.nodes.forEach((node) => {\n const record = fileIssues.get(node.id);\n if (record) {\n node.duplicates = record.duplicates || 0;\n node.color = getColorForSeverity(record.maxSeverity);\n node.group = getPackageGroup(node.id);\n\n if (record.maxSeverity === Severity.Critical)\n criticalIssues += record.count;\n else if (record.maxSeverity === Severity.Major)\n majorIssues += record.count;\n else if (record.maxSeverity === Severity.Minor)\n minorIssues += record.count;\n else if (record.maxSeverity === Severity.Info)\n infoIssues += record.count;\n } else {\n node.color = getColorForSeverity(null);\n node.group = getPackageGroup(node.id);\n node.duplicates = 0;\n }\n });\n\n graph.metadata = {\n ...graph.metadata,\n criticalIssues,\n majorIssues,\n minorIssues,\n infoIssues,\n tokenBudget: report.scoring?.tokenBudget,\n };\n\n return graph;\n }\n}\n\n/**\n * Create a small sample graph for demonstration or testing purposes.\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"]}
@@ -181,12 +181,43 @@ var GraphBuilder = class _GraphBuilder {
181
181
  if (Array.isArray(toolData)) return toolData;
182
182
  return toolData.results ?? toolData.issues ?? [];
183
183
  };
184
- this.processPatterns(builder, getResults(ToolName.PatternDetect, "patterns"), rootDir, bumpIssue);
184
+ this.processPatterns(
185
+ builder,
186
+ getResults(ToolName.PatternDetect, "patterns"),
187
+ rootDir,
188
+ bumpIssue
189
+ );
185
190
  this.processDuplicates(builder, report, rootDir, fileIssues);
186
- this.processContext(builder, getResults(ToolName.ContextAnalyzer, "context"), rootDir, bumpIssue);
187
- this.processToolResults(builder, ToolName.DocDrift, "docDrift", report, bumpIssue, "Doc-Drift Issue");
188
- this.processToolResults(builder, ToolName.DependencyHealth, "dependencyHealth", report, bumpIssue, "Dependency Issue");
189
- this.processToolResults(builder, ToolName.ContractEnforcement, "contractEnforcement", report, bumpIssue, "Contract Gap");
191
+ this.processContext(
192
+ builder,
193
+ getResults(ToolName.ContextAnalyzer, "context"),
194
+ rootDir,
195
+ bumpIssue
196
+ );
197
+ this.processToolResults(
198
+ builder,
199
+ ToolName.DocDrift,
200
+ "docDrift",
201
+ report,
202
+ bumpIssue,
203
+ "Doc-Drift Issue"
204
+ );
205
+ this.processToolResults(
206
+ builder,
207
+ ToolName.DependencyHealth,
208
+ "dependencyHealth",
209
+ report,
210
+ bumpIssue,
211
+ "Dependency Issue"
212
+ );
213
+ this.processToolResults(
214
+ builder,
215
+ ToolName.ContractEnforcement,
216
+ "contractEnforcement",
217
+ report,
218
+ bumpIssue,
219
+ "Contract Gap"
220
+ );
190
221
  return this.finalizeGraph(builder, fileIssues, report);
191
222
  }
192
223
  static processPatterns(builder, results, rootDir, bumpIssue) {
@@ -222,7 +253,11 @@ var GraphBuilder = class _GraphBuilder {
222
253
  const refs = extractReferencedPaths(issue.message);
223
254
  refs.forEach((ref) => {
224
255
  const target = path2.isAbsolute(ref) ? ref : path2.resolve(path2.dirname(file), ref);
225
- builder.addNode(target, "Referenced file", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
256
+ builder.addNode(
257
+ target,
258
+ "Referenced file",
259
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
260
+ );
226
261
  builder.addEdge(file, target, "reference");
227
262
  });
228
263
  const percMatch = (issue.message.match(/(\d+)%/) || [])[1];
@@ -231,11 +266,17 @@ var GraphBuilder = class _GraphBuilder {
231
266
  if (wantFuzzy) {
232
267
  const fileGroup = getPackageGroup(file);
233
268
  for (const [base, pathsSet] of basenameMap.entries()) {
234
- if (!issue.message.includes(base) || base === path2.basename(file)) continue;
269
+ if (!issue.message.includes(base) || base === path2.basename(file))
270
+ continue;
235
271
  for (const target of pathsSet) {
236
272
  const targetGroup = getPackageGroup(target);
237
- if (fileGroup !== targetGroup && !(perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_HIGH_THRESHOLD)) continue;
238
- builder.addNode(target, "Fuzzy match", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
273
+ if (fileGroup !== targetGroup && !(perc !== null && perc >= GRAPH_CONSTANTS.FUZZY_MATCH_HIGH_THRESHOLD))
274
+ continue;
275
+ builder.addNode(
276
+ target,
277
+ "Fuzzy match",
278
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
279
+ );
239
280
  builder.addEdge(file, target, "similarity");
240
281
  }
241
282
  }
@@ -247,8 +288,16 @@ var GraphBuilder = class _GraphBuilder {
247
288
  const patternData = report[ToolName.PatternDetect] || report.patternDetect || report.patterns || {};
248
289
  const duplicates = (Array.isArray(patternData.duplicates) ? patternData.duplicates : null) || (patternData.summary && Array.isArray(patternData.summary.duplicates) ? patternData.summary.duplicates : null) || (Array.isArray(report.duplicates) ? report.duplicates : []);
249
290
  duplicates.forEach((dup) => {
250
- builder.addNode(dup.file1, "Similarity target", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
251
- builder.addNode(dup.file2, "Similarity target", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
291
+ builder.addNode(
292
+ dup.file1,
293
+ "Similarity target",
294
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
295
+ );
296
+ builder.addNode(
297
+ dup.file2,
298
+ "Similarity target",
299
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
300
+ );
252
301
  builder.addEdge(dup.file1, dup.file2, "similarity");
253
302
  [dup.file1, dup.file2].forEach((file) => {
254
303
  const id = path2.resolve(rootDir, file);
@@ -264,7 +313,11 @@ var GraphBuilder = class _GraphBuilder {
264
313
  const normalized = normalizeAnalysisResult(ctx);
265
314
  const file = normalized.fileName;
266
315
  if (!file) return;
267
- builder.addNode(file, `Deps: ${ctx.dependencyCount || 0}`, GRAPH_CONSTANTS.DEFAULT_CONTEXT_SIZE);
316
+ builder.addNode(
317
+ file,
318
+ `Deps: ${ctx.dependencyCount || 0}`,
319
+ GRAPH_CONSTANTS.DEFAULT_CONTEXT_SIZE
320
+ );
268
321
  normalized.issues.forEach((issue) => {
269
322
  bumpIssue(file, issue.severity);
270
323
  });
@@ -274,8 +327,13 @@ var GraphBuilder = class _GraphBuilder {
274
327
  const resolvedTarget = path2.resolve(builder.rootDir, resolvedRel);
275
328
  const keyA = `${resolvedFile}->${resolvedTarget}`;
276
329
  const keyB = `${resolvedTarget}->${resolvedFile}`;
277
- if (builder["edgesSet"].has(keyA) || builder["edgesSet"].has(keyB)) return;
278
- builder.addNode(resolvedRel, "Related file", GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE);
330
+ if (builder["edgesSet"].has(keyA) || builder["edgesSet"].has(keyB))
331
+ return;
332
+ builder.addNode(
333
+ resolvedRel,
334
+ "Related file",
335
+ GRAPH_CONSTANTS.DEFAULT_REFERENCE_SIZE
336
+ );
279
337
  const node = builder["nodesMap"].get(resolvedTarget);
280
338
  if (node) {
281
339
  node.size = (node.size || 1) + 2;
@@ -295,7 +353,11 @@ var GraphBuilder = class _GraphBuilder {
295
353
  ];
296
354
  for (const p of possiblePaths) {
297
355
  if (fs.existsSync(p)) {
298
- builder.addNode(p, "Dependency", GRAPH_CONSTANTS.DEFAULT_DEPENDENCY_SIZE);
356
+ builder.addNode(
357
+ p,
358
+ "Dependency",
359
+ GRAPH_CONSTANTS.DEFAULT_DEPENDENCY_SIZE
360
+ );
299
361
  builder.addEdge(file, p, "dependency");
300
362
  break;
301
363
  }
@@ -340,10 +402,14 @@ var GraphBuilder = class _GraphBuilder {
340
402
  node.duplicates = record.duplicates || 0;
341
403
  node.color = getColorForSeverity(record.maxSeverity);
342
404
  node.group = getPackageGroup(node.id);
343
- if (record.maxSeverity === Severity.Critical) criticalIssues += record.count;
344
- else if (record.maxSeverity === Severity.Major) majorIssues += record.count;
345
- else if (record.maxSeverity === Severity.Minor) minorIssues += record.count;
346
- else if (record.maxSeverity === Severity.Info) infoIssues += record.count;
405
+ if (record.maxSeverity === Severity.Critical)
406
+ criticalIssues += record.count;
407
+ else if (record.maxSeverity === Severity.Major)
408
+ majorIssues += record.count;
409
+ else if (record.maxSeverity === Severity.Minor)
410
+ minorIssues += record.count;
411
+ else if (record.maxSeverity === Severity.Info)
412
+ infoIssues += record.count;
347
413
  } else {
348
414
  node.color = getColorForSeverity(null);
349
415
  node.group = getPackageGroup(node.id);
@@ -366,7 +432,11 @@ function createSampleGraph() {
366
432
  builder.addNode("src/components/Button.tsx", "Button", 15);
367
433
  builder.addNode("src/utils/helpers.ts", "helpers", 12);
368
434
  builder.addNode("src/services/api.ts", "api", 18);
369
- builder.addEdge("src/components/Button.tsx", "src/utils/helpers.ts", "dependency");
435
+ builder.addEdge(
436
+ "src/components/Button.tsx",
437
+ "src/utils/helpers.ts",
438
+ "dependency"
439
+ );
370
440
  builder.addEdge("src/utils/helpers.ts", "src/services/api.ts", "dependency");
371
441
  return builder.build();
372
442
  }