@aiready/cli 0.9.39 → 0.9.41

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
@@ -54,8 +54,14 @@ function sortBySeverity(results) {
54
54
  });
55
55
  return { ...file, issues: sortedIssues };
56
56
  }).sort((a, b) => {
57
- const aMaxSeverity = Math.max(...a.issues.map((i) => severityOrder[i.severity] || 0), 0);
58
- const bMaxSeverity = Math.max(...b.issues.map((i) => severityOrder[i.severity] || 0), 0);
57
+ const aMaxSeverity = Math.max(
58
+ ...a.issues.map((i) => severityOrder[i.severity] || 0),
59
+ 0
60
+ );
61
+ const bMaxSeverity = Math.max(
62
+ ...b.issues.map((i) => severityOrder[i.severity] || 0),
63
+ 0
64
+ );
59
65
  if (aMaxSeverity !== bMaxSeverity) {
60
66
  return bMaxSeverity - aMaxSeverity;
61
67
  }
@@ -154,7 +160,10 @@ async function analyzeUnified(options) {
154
160
  options.progressCallback({ tool: "aiSignalClarity", data: report });
155
161
  }
156
162
  result.aiSignalClarity = report;
157
- result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
163
+ result.summary.totalIssues += report.results?.reduce(
164
+ (sum, r) => sum + (r.issues?.length || 0),
165
+ 0
166
+ ) || 0;
158
167
  }
159
168
  if (tools.includes("grounding")) {
160
169
  const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
@@ -213,19 +222,28 @@ function findLatestScanReport(dirPath) {
213
222
  if (!(0, import_fs.existsSync)(aireadyDir)) {
214
223
  return null;
215
224
  }
216
- let files = (0, import_fs.readdirSync)(aireadyDir).filter((f) => f.startsWith("aiready-report-") && f.endsWith(".json"));
225
+ let files = (0, import_fs.readdirSync)(aireadyDir).filter(
226
+ (f) => f.startsWith("aiready-report-") && f.endsWith(".json")
227
+ );
217
228
  if (files.length === 0) {
218
- files = (0, import_fs.readdirSync)(aireadyDir).filter((f) => f.startsWith("aiready-scan-") && f.endsWith(".json"));
229
+ files = (0, import_fs.readdirSync)(aireadyDir).filter(
230
+ (f) => f.startsWith("aiready-scan-") && f.endsWith(".json")
231
+ );
219
232
  }
220
233
  if (files.length === 0) {
221
234
  return null;
222
235
  }
223
- const sortedFiles = files.map((f) => ({ name: f, path: (0, import_path.resolve)(aireadyDir, f), mtime: (0, import_fs.statSync)((0, import_path.resolve)(aireadyDir, f)).mtime })).sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
236
+ const sortedFiles = files.map((f) => ({
237
+ name: f,
238
+ path: (0, import_path.resolve)(aireadyDir, f),
239
+ mtime: (0, import_fs.statSync)((0, import_path.resolve)(aireadyDir, f)).mtime
240
+ })).sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
224
241
  return sortedFiles[0].path;
225
242
  }
226
- function warnIfGraphCapExceeded(report, dirPath) {
243
+ async function warnIfGraphCapExceeded(report, dirPath) {
227
244
  try {
228
- const { loadConfig: loadConfig4 } = require("@aiready/core");
245
+ const { loadConfig: loadConfig4 } = await import("@aiready/core");
246
+ void loadConfig4;
229
247
  let graphConfig = { maxNodes: 400, maxEdges: 600 };
230
248
  const configPath = (0, import_path.resolve)(dirPath, "aiready.json");
231
249
  if ((0, import_fs.existsSync)(configPath)) {
@@ -237,7 +255,8 @@ function warnIfGraphCapExceeded(report, dirPath) {
237
255
  maxEdges: rawConfig.visualizer.graph.maxEdges ?? graphConfig.maxEdges
238
256
  };
239
257
  }
240
- } catch (e) {
258
+ } catch (err) {
259
+ void err;
241
260
  }
242
261
  }
243
262
  const nodeCount = (report.context?.length || 0) + (report.patterns?.length || 0);
@@ -248,21 +267,30 @@ function warnIfGraphCapExceeded(report, dirPath) {
248
267
  }, 0) || 0;
249
268
  if (nodeCount > graphConfig.maxNodes || edgeCount > graphConfig.maxEdges) {
250
269
  console.log("");
251
- console.log(import_chalk.default.yellow(`\u26A0\uFE0F Graph may be truncated at visualization time:`));
270
+ console.log(
271
+ import_chalk.default.yellow(`\u26A0\uFE0F Graph may be truncated at visualization time:`)
272
+ );
252
273
  if (nodeCount > graphConfig.maxNodes) {
253
- console.log(import_chalk.default.dim(` \u2022 Nodes: ${nodeCount} > limit ${graphConfig.maxNodes}`));
274
+ console.log(
275
+ import_chalk.default.dim(` \u2022 Nodes: ${nodeCount} > limit ${graphConfig.maxNodes}`)
276
+ );
254
277
  }
255
278
  if (edgeCount > graphConfig.maxEdges) {
256
- console.log(import_chalk.default.dim(` \u2022 Edges: ${edgeCount} > limit ${graphConfig.maxEdges}`));
279
+ console.log(
280
+ import_chalk.default.dim(` \u2022 Edges: ${edgeCount} > limit ${graphConfig.maxEdges}`)
281
+ );
257
282
  }
258
283
  console.log(import_chalk.default.dim(` To increase limits, add to aiready.json:`));
259
284
  console.log(import_chalk.default.dim(` {`));
260
285
  console.log(import_chalk.default.dim(` "visualizer": {`));
261
- console.log(import_chalk.default.dim(` "graph": { "maxNodes": 2000, "maxEdges": 5000 }`));
286
+ console.log(
287
+ import_chalk.default.dim(` "graph": { "maxNodes": 2000, "maxEdges": 5000 }`)
288
+ );
262
289
  console.log(import_chalk.default.dim(` }`));
263
290
  console.log(import_chalk.default.dim(` }`));
264
291
  }
265
- } catch (e) {
292
+ } catch (err) {
293
+ void err;
266
294
  }
267
295
  }
268
296
  function generateMarkdownReport(report, elapsedTime) {
@@ -311,17 +339,28 @@ async function scanAction(directory, options) {
311
339
  const resolvedDir = (0, import_path2.resolve)(process.cwd(), directory || ".");
312
340
  try {
313
341
  const defaults = {
314
- tools: ["patterns", "context", "consistency", "aiSignalClarity", "grounding", "testability", "doc-drift", "deps-health"],
342
+ tools: [
343
+ "patterns",
344
+ "context",
345
+ "consistency",
346
+ "aiSignalClarity",
347
+ "grounding",
348
+ "testability",
349
+ "doc-drift",
350
+ "deps-health",
351
+ "changeAmplification"
352
+ ],
315
353
  include: void 0,
316
354
  exclude: void 0,
317
355
  output: {
318
- format: "json",
356
+ format: "console",
319
357
  file: void 0
320
358
  }
321
359
  };
322
360
  let profileTools = options.tools ? options.tools.split(",").map((t) => {
323
361
  const tool = t.trim();
324
- if (tool === "hallucination" || tool === "hallucination-risk") return "aiSignalClarity";
362
+ if (tool === "hallucination" || tool === "hallucination-risk")
363
+ return "aiSignalClarity";
325
364
  return tool;
326
365
  }) : void 0;
327
366
  if (options.profile) {
@@ -339,28 +378,56 @@ async function scanAction(directory, options) {
339
378
  profileTools = ["context", "consistency", "grounding"];
340
379
  break;
341
380
  default:
342
- console.log(import_chalk2.default.yellow(`
343
- \u26A0\uFE0F Unknown profile '${options.profile}'. Using specified tools or defaults.`));
381
+ console.log(
382
+ import_chalk2.default.yellow(
383
+ `
384
+ \u26A0\uFE0F Unknown profile '${options.profile}'. Using specified tools or defaults.`
385
+ )
386
+ );
344
387
  }
345
388
  }
346
- const baseOptions = await (0, import_core.loadMergedConfig)(resolvedDir, defaults, {
347
- tools: profileTools,
389
+ const cliOverrides = {
348
390
  include: options.include?.split(","),
349
391
  exclude: options.exclude?.split(",")
350
- });
392
+ };
393
+ if (profileTools) {
394
+ cliOverrides.tools = profileTools;
395
+ }
396
+ const baseOptions = await (0, import_core.loadMergedConfig)(
397
+ resolvedDir,
398
+ defaults,
399
+ cliOverrides
400
+ );
351
401
  let finalOptions = { ...baseOptions };
352
402
  if (baseOptions.tools.includes("patterns")) {
353
403
  const { getSmartDefaults } = await import("@aiready/pattern-detect");
354
- const patternSmartDefaults = await getSmartDefaults(resolvedDir, baseOptions);
355
- finalOptions = { ...patternSmartDefaults, ...finalOptions, ...baseOptions };
404
+ const patternSmartDefaults = await getSmartDefaults(
405
+ resolvedDir,
406
+ baseOptions
407
+ );
408
+ finalOptions = {
409
+ ...patternSmartDefaults,
410
+ ...finalOptions,
411
+ ...baseOptions
412
+ };
356
413
  }
357
414
  console.log(import_chalk2.default.cyan("\n=== AIReady Run Preview ==="));
358
- console.log(import_chalk2.default.white("Tools to run:"), (finalOptions.tools || ["patterns", "context", "consistency"]).join(", "));
415
+ console.log(
416
+ import_chalk2.default.white("Tools to run:"),
417
+ (finalOptions.tools || ["patterns", "context", "consistency"]).join(", ")
418
+ );
359
419
  console.log(import_chalk2.default.white("Will use settings from config and defaults."));
360
420
  console.log(import_chalk2.default.white("\nGeneral settings:"));
361
- if (finalOptions.rootDir) console.log(` rootDir: ${import_chalk2.default.bold(String(finalOptions.rootDir))}`);
362
- if (finalOptions.include) console.log(` include: ${import_chalk2.default.bold(truncateArray(finalOptions.include, 6))}`);
363
- if (finalOptions.exclude) console.log(` exclude: ${import_chalk2.default.bold(truncateArray(finalOptions.exclude, 6))}`);
421
+ if (finalOptions.rootDir)
422
+ console.log(` rootDir: ${import_chalk2.default.bold(String(finalOptions.rootDir))}`);
423
+ if (finalOptions.include)
424
+ console.log(
425
+ ` include: ${import_chalk2.default.bold(truncateArray(finalOptions.include, 6))}`
426
+ );
427
+ if (finalOptions.exclude)
428
+ console.log(
429
+ ` exclude: ${import_chalk2.default.bold(truncateArray(finalOptions.exclude, 6))}`
430
+ );
364
431
  if (finalOptions["pattern-detect"] || finalOptions.minSimilarity) {
365
432
  const patternDetectConfig = finalOptions["pattern-detect"] || {
366
433
  minSimilarity: finalOptions.minSimilarity,
@@ -374,15 +441,40 @@ async function scanAction(directory, options) {
374
441
  includeTests: finalOptions.includeTests
375
442
  };
376
443
  console.log(import_chalk2.default.white("\nPattern-detect settings:"));
377
- console.log(` minSimilarity: ${import_chalk2.default.bold(patternDetectConfig.minSimilarity ?? "default")}`);
378
- console.log(` minLines: ${import_chalk2.default.bold(patternDetectConfig.minLines ?? "default")}`);
379
- if (patternDetectConfig.approx !== void 0) console.log(` approx: ${import_chalk2.default.bold(String(patternDetectConfig.approx))}`);
380
- if (patternDetectConfig.minSharedTokens !== void 0) console.log(` minSharedTokens: ${import_chalk2.default.bold(String(patternDetectConfig.minSharedTokens))}`);
381
- if (patternDetectConfig.maxCandidatesPerBlock !== void 0) console.log(` maxCandidatesPerBlock: ${import_chalk2.default.bold(String(patternDetectConfig.maxCandidatesPerBlock))}`);
382
- if (patternDetectConfig.batchSize !== void 0) console.log(` batchSize: ${import_chalk2.default.bold(String(patternDetectConfig.batchSize))}`);
383
- if (patternDetectConfig.streamResults !== void 0) console.log(` streamResults: ${import_chalk2.default.bold(String(patternDetectConfig.streamResults))}`);
384
- if (patternDetectConfig.severity !== void 0) console.log(` severity: ${import_chalk2.default.bold(String(patternDetectConfig.severity))}`);
385
- if (patternDetectConfig.includeTests !== void 0) console.log(` includeTests: ${import_chalk2.default.bold(String(patternDetectConfig.includeTests))}`);
444
+ console.log(
445
+ ` minSimilarity: ${import_chalk2.default.bold(patternDetectConfig.minSimilarity ?? "default")}`
446
+ );
447
+ console.log(
448
+ ` minLines: ${import_chalk2.default.bold(patternDetectConfig.minLines ?? "default")}`
449
+ );
450
+ if (patternDetectConfig.approx !== void 0)
451
+ console.log(
452
+ ` approx: ${import_chalk2.default.bold(String(patternDetectConfig.approx))}`
453
+ );
454
+ if (patternDetectConfig.minSharedTokens !== void 0)
455
+ console.log(
456
+ ` minSharedTokens: ${import_chalk2.default.bold(String(patternDetectConfig.minSharedTokens))}`
457
+ );
458
+ if (patternDetectConfig.maxCandidatesPerBlock !== void 0)
459
+ console.log(
460
+ ` maxCandidatesPerBlock: ${import_chalk2.default.bold(String(patternDetectConfig.maxCandidatesPerBlock))}`
461
+ );
462
+ if (patternDetectConfig.batchSize !== void 0)
463
+ console.log(
464
+ ` batchSize: ${import_chalk2.default.bold(String(patternDetectConfig.batchSize))}`
465
+ );
466
+ if (patternDetectConfig.streamResults !== void 0)
467
+ console.log(
468
+ ` streamResults: ${import_chalk2.default.bold(String(patternDetectConfig.streamResults))}`
469
+ );
470
+ if (patternDetectConfig.severity !== void 0)
471
+ console.log(
472
+ ` severity: ${import_chalk2.default.bold(String(patternDetectConfig.severity))}`
473
+ );
474
+ if (patternDetectConfig.includeTests !== void 0)
475
+ console.log(
476
+ ` includeTests: ${import_chalk2.default.bold(String(patternDetectConfig.includeTests))}`
477
+ );
386
478
  }
387
479
  if (finalOptions["context-analyzer"] || finalOptions.maxDepth) {
388
480
  const ca = finalOptions["context-analyzer"] || {
@@ -394,20 +486,42 @@ async function scanAction(directory, options) {
394
486
  };
395
487
  console.log(import_chalk2.default.white("\nContext-analyzer settings:"));
396
488
  console.log(` maxDepth: ${import_chalk2.default.bold(ca.maxDepth ?? "default")}`);
397
- console.log(` maxContextBudget: ${import_chalk2.default.bold(ca.maxContextBudget ?? "default")}`);
398
- if (ca.minCohesion !== void 0) console.log(` minCohesion: ${import_chalk2.default.bold(String(ca.minCohesion))}`);
399
- if (ca.maxFragmentation !== void 0) console.log(` maxFragmentation: ${import_chalk2.default.bold(String(ca.maxFragmentation))}`);
400
- if (ca.includeNodeModules !== void 0) console.log(` includeNodeModules: ${import_chalk2.default.bold(String(ca.includeNodeModules))}`);
489
+ console.log(
490
+ ` maxContextBudget: ${import_chalk2.default.bold(ca.maxContextBudget ?? "default")}`
491
+ );
492
+ if (ca.minCohesion !== void 0)
493
+ console.log(` minCohesion: ${import_chalk2.default.bold(String(ca.minCohesion))}`);
494
+ if (ca.maxFragmentation !== void 0)
495
+ console.log(
496
+ ` maxFragmentation: ${import_chalk2.default.bold(String(ca.maxFragmentation))}`
497
+ );
498
+ if (ca.includeNodeModules !== void 0)
499
+ console.log(
500
+ ` includeNodeModules: ${import_chalk2.default.bold(String(ca.includeNodeModules))}`
501
+ );
401
502
  }
402
503
  if (finalOptions.consistency) {
403
504
  const c = finalOptions.consistency;
404
505
  console.log(import_chalk2.default.white("\nConsistency settings:"));
405
- console.log(` checkNaming: ${import_chalk2.default.bold(String(c.checkNaming ?? true))}`);
406
- console.log(` checkPatterns: ${import_chalk2.default.bold(String(c.checkPatterns ?? true))}`);
407
- console.log(` checkArchitecture: ${import_chalk2.default.bold(String(c.checkArchitecture ?? false))}`);
408
- if (c.minSeverity) console.log(` minSeverity: ${import_chalk2.default.bold(c.minSeverity)}`);
409
- if (c.acceptedAbbreviations) console.log(` acceptedAbbreviations: ${import_chalk2.default.bold(truncateArray(c.acceptedAbbreviations, 8))}`);
410
- if (c.shortWords) console.log(` shortWords: ${import_chalk2.default.bold(truncateArray(c.shortWords, 8))}`);
506
+ console.log(
507
+ ` checkNaming: ${import_chalk2.default.bold(String(c.checkNaming ?? true))}`
508
+ );
509
+ console.log(
510
+ ` checkPatterns: ${import_chalk2.default.bold(String(c.checkPatterns ?? true))}`
511
+ );
512
+ console.log(
513
+ ` checkArchitecture: ${import_chalk2.default.bold(String(c.checkArchitecture ?? false))}`
514
+ );
515
+ if (c.minSeverity)
516
+ console.log(` minSeverity: ${import_chalk2.default.bold(c.minSeverity)}`);
517
+ if (c.acceptedAbbreviations)
518
+ console.log(
519
+ ` acceptedAbbreviations: ${import_chalk2.default.bold(truncateArray(c.acceptedAbbreviations, 8))}`
520
+ );
521
+ if (c.shortWords)
522
+ console.log(
523
+ ` shortWords: ${import_chalk2.default.bold(truncateArray(c.shortWords, 8))}`
524
+ );
411
525
  }
412
526
  console.log(import_chalk2.default.white("\nStarting analysis..."));
413
527
  const progressCallback = (event) => {
@@ -416,40 +530,62 @@ async function scanAction(directory, options) {
416
530
  try {
417
531
  if (event.tool === "patterns") {
418
532
  const pr = event.data;
419
- console.log(` Duplicate patterns: ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))}`);
420
- console.log(` Files with pattern issues: ${import_chalk2.default.bold(String(pr.results?.length || 0))}`);
533
+ console.log(
534
+ ` Duplicate patterns: ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))}`
535
+ );
536
+ console.log(
537
+ ` Files with pattern issues: ${import_chalk2.default.bold(String(pr.results?.length || 0))}`
538
+ );
421
539
  if (pr.duplicates && pr.duplicates.length > 0) {
422
540
  pr.duplicates.slice(0, 5).forEach((d, i) => {
423
- console.log(` ${i + 1}. ${d.file1.split("/").pop()} \u2194 ${d.file2.split("/").pop()} (sim=${(d.similarity * 100).toFixed(1)}%)`);
541
+ console.log(
542
+ ` ${i + 1}. ${d.file1.split("/").pop()} \u2194 ${d.file2.split("/").pop()} (sim=${(d.similarity * 100).toFixed(1)}%)`
543
+ );
424
544
  });
425
545
  }
426
546
  if (pr.results && pr.results.length > 0) {
427
547
  console.log(` Top files with pattern issues:`);
428
- const sortedByIssues = [...pr.results].sort((a, b) => (b.issues?.length || 0) - (a.issues?.length || 0));
548
+ const sortedByIssues = [...pr.results].sort(
549
+ (a, b) => (b.issues?.length || 0) - (a.issues?.length || 0)
550
+ );
429
551
  sortedByIssues.slice(0, 5).forEach((r, i) => {
430
- console.log(` ${i + 1}. ${r.fileName.split("/").pop()} - ${r.issues.length} issue(s)`);
552
+ console.log(
553
+ ` ${i + 1}. ${r.fileName.split("/").pop()} - ${r.issues.length} issue(s)`
554
+ );
431
555
  });
432
556
  }
433
557
  if (pr.groups && pr.groups.length >= 0) {
434
- console.log(` \u2705 Grouped ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))} duplicates into ${import_chalk2.default.bold(String(pr.groups.length))} file pairs`);
558
+ console.log(
559
+ ` \u2705 Grouped ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))} duplicates into ${import_chalk2.default.bold(String(pr.groups.length))} file pairs`
560
+ );
435
561
  }
436
562
  if (pr.clusters && pr.clusters.length >= 0) {
437
- console.log(` \u2705 Created ${import_chalk2.default.bold(String(pr.clusters.length))} refactor clusters`);
563
+ console.log(
564
+ ` \u2705 Created ${import_chalk2.default.bold(String(pr.clusters.length))} refactor clusters`
565
+ );
438
566
  pr.clusters.slice(0, 3).forEach((cl, idx) => {
439
567
  const files = (cl.files || []).map((f) => f.path.split("/").pop()).join(", ");
440
- console.log(` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`);
568
+ console.log(
569
+ ` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`
570
+ );
441
571
  });
442
572
  }
443
573
  } else if (event.tool === "context") {
444
574
  const cr = event.data;
445
- console.log(` Context issues found: ${import_chalk2.default.bold(String(cr.length || 0))}`);
575
+ console.log(
576
+ ` Context issues found: ${import_chalk2.default.bold(String(cr.length || 0))}`
577
+ );
446
578
  cr.slice(0, 5).forEach((c, i) => {
447
579
  const msg = c.message ? ` - ${c.message}` : "";
448
- console.log(` ${i + 1}. ${c.file} (${c.severity || "n/a"})${msg}`);
580
+ console.log(
581
+ ` ${i + 1}. ${c.file} (${c.severity || "n/a"})${msg}`
582
+ );
449
583
  });
450
584
  } else if (event.tool === "consistency") {
451
585
  const rep = event.data;
452
- console.log(` Consistency totalIssues: ${import_chalk2.default.bold(String(rep.summary?.totalIssues || 0))}`);
586
+ console.log(
587
+ ` Consistency totalIssues: ${import_chalk2.default.bold(String(rep.summary?.totalIssues || 0))}`
588
+ );
453
589
  if (rep.results && rep.results.length > 0) {
454
590
  const fileMap = /* @__PURE__ */ new Map();
455
591
  rep.results.forEach((r) => {
@@ -459,61 +595,126 @@ async function scanAction(directory, options) {
459
595
  fileMap.get(file).push(issue);
460
596
  });
461
597
  });
462
- const files = Array.from(fileMap.entries()).sort((a, b) => b[1].length - a[1].length);
598
+ const files = Array.from(fileMap.entries()).sort(
599
+ (a, b) => b[1].length - a[1].length
600
+ );
463
601
  const topFiles = files.slice(0, 10);
464
602
  topFiles.forEach(([file, issues], idx) => {
465
- const counts = issues.reduce((acc, it) => {
466
- const s = (it.severity || "info").toLowerCase();
467
- acc[s] = (acc[s] || 0) + 1;
468
- return acc;
469
- }, {});
470
- const sample = issues.find((it) => it.severity === "critical" || it.severity === "major") || issues[0];
603
+ const counts = issues.reduce(
604
+ (acc, it) => {
605
+ const s = (it.severity || "info").toLowerCase();
606
+ acc[s] = (acc[s] || 0) + 1;
607
+ return acc;
608
+ },
609
+ {}
610
+ );
611
+ const sample = issues.find(
612
+ (it) => it.severity === "critical" || it.severity === "major"
613
+ ) || issues[0];
471
614
  const sampleMsg = sample ? ` \u2014 ${sample.message}` : "";
472
- console.log(` ${idx + 1}. ${file} \u2014 ${issues.length} issue(s) (critical:${counts.critical || 0} major:${counts.major || 0} minor:${counts.minor || 0} info:${counts.info || 0})${sampleMsg}`);
615
+ console.log(
616
+ ` ${idx + 1}. ${file} \u2014 ${issues.length} issue(s) (critical:${counts.critical || 0} major:${counts.major || 0} minor:${counts.minor || 0} info:${counts.info || 0})${sampleMsg}`
617
+ );
473
618
  });
474
619
  const remaining = files.length - topFiles.length;
475
620
  if (remaining > 0) {
476
- console.log(import_chalk2.default.dim(` ... and ${remaining} more files with issues (use --output json for full details)`));
621
+ console.log(
622
+ import_chalk2.default.dim(
623
+ ` ... and ${remaining} more files with issues (use --output json for full details)`
624
+ )
625
+ );
477
626
  }
478
627
  }
479
628
  } else if (event.tool === "doc-drift") {
480
629
  const dr = event.data;
481
- console.log(` Issues found: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`);
630
+ console.log(
631
+ ` Issues found: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`
632
+ );
482
633
  if (dr.rawData) {
483
- console.log(` Signature Mismatches: ${import_chalk2.default.bold(dr.rawData.outdatedComments || 0)}`);
484
- console.log(` Undocumented Complexity: ${import_chalk2.default.bold(dr.rawData.undocumentedComplexity || 0)}`);
634
+ console.log(
635
+ ` Signature Mismatches: ${import_chalk2.default.bold(dr.rawData.outdatedComments || 0)}`
636
+ );
637
+ console.log(
638
+ ` Undocumented Complexity: ${import_chalk2.default.bold(dr.rawData.undocumentedComplexity || 0)}`
639
+ );
485
640
  }
486
641
  } else if (event.tool === "deps-health") {
487
642
  const dr = event.data;
488
- console.log(` Packages Analyzed: ${import_chalk2.default.bold(String(dr.summary?.packagesAnalyzed || 0))}`);
643
+ console.log(
644
+ ` Packages Analyzed: ${import_chalk2.default.bold(String(dr.summary?.packagesAnalyzed || 0))}`
645
+ );
489
646
  if (dr.rawData) {
490
- console.log(` Deprecated Packages: ${import_chalk2.default.bold(dr.rawData.deprecatedPackages || 0)}`);
491
- console.log(` AI Cutoff Skew Score: ${import_chalk2.default.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`);
647
+ console.log(
648
+ ` Deprecated Packages: ${import_chalk2.default.bold(dr.rawData.deprecatedPackages || 0)}`
649
+ );
650
+ console.log(
651
+ ` AI Cutoff Skew Score: ${import_chalk2.default.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`
652
+ );
653
+ }
654
+ } else if (event.tool === "change-amplification" || event.tool === "changeAmplification") {
655
+ const dr = event.data;
656
+ console.log(
657
+ ` Coupling issues: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`
658
+ );
659
+ if (dr.summary) {
660
+ console.log(
661
+ ` Complexity Score: ${import_chalk2.default.bold(dr.summary.score || 0)}/100`
662
+ );
492
663
  }
493
664
  }
494
665
  } catch (err) {
666
+ void err;
495
667
  }
496
668
  };
497
- const results = await analyzeUnified({ ...finalOptions, progressCallback, suppressToolConfig: true });
669
+ const results = await analyzeUnified({
670
+ ...finalOptions,
671
+ progressCallback,
672
+ suppressToolConfig: true
673
+ });
498
674
  console.log(import_chalk2.default.cyan("\n=== AIReady Run Summary ==="));
499
- console.log(import_chalk2.default.white("Tools run:"), (finalOptions.tools || ["patterns", "context", "consistency"]).join(", "));
675
+ console.log(
676
+ import_chalk2.default.white("Tools run:"),
677
+ (finalOptions.tools || ["patterns", "context", "consistency"]).join(", ")
678
+ );
500
679
  console.log(import_chalk2.default.cyan("\nResults summary:"));
501
- console.log(` Total issues (all tools): ${import_chalk2.default.bold(String(results.summary.totalIssues || 0))}`);
502
- if (results.duplicates) console.log(` Duplicate patterns found: ${import_chalk2.default.bold(String(results.duplicates.length || 0))}`);
503
- if (results.patterns) console.log(` Pattern files with issues: ${import_chalk2.default.bold(String(results.patterns.length || 0))}`);
504
- if (results.context) console.log(` Context issues: ${import_chalk2.default.bold(String(results.context.length || 0))}`);
505
- if (results.consistency) console.log(` Consistency issues: ${import_chalk2.default.bold(String(results.consistency.summary.totalIssues || 0))}`);
680
+ console.log(
681
+ ` Total issues (all tools): ${import_chalk2.default.bold(String(results.summary.totalIssues || 0))}`
682
+ );
683
+ if (results.duplicates)
684
+ console.log(
685
+ ` Duplicate patterns found: ${import_chalk2.default.bold(String(results.duplicates.length || 0))}`
686
+ );
687
+ if (results.patterns)
688
+ console.log(
689
+ ` Pattern files with issues: ${import_chalk2.default.bold(String(results.patterns.length || 0))}`
690
+ );
691
+ if (results.context)
692
+ console.log(
693
+ ` Context issues: ${import_chalk2.default.bold(String(results.context.length || 0))}`
694
+ );
695
+ console.log(
696
+ ` Consistency issues: ${import_chalk2.default.bold(String(results.consistency?.summary?.totalIssues || 0))}`
697
+ );
698
+ if (results.changeAmplification)
699
+ console.log(
700
+ ` Change amplification: ${import_chalk2.default.bold(String(results.changeAmplification.summary?.score || 0))}/100`
701
+ );
506
702
  console.log(import_chalk2.default.cyan("===========================\n"));
507
703
  const elapsedTime = (0, import_core.getElapsedTime)(startTime);
704
+ void elapsedTime;
508
705
  let scoringResult;
509
706
  if (options.score || finalOptions.scoring?.showBreakdown) {
510
707
  const toolScores = /* @__PURE__ */ new Map();
511
708
  if (results.duplicates) {
512
709
  const { calculatePatternScore } = await import("@aiready/pattern-detect");
513
710
  try {
514
- const patternScore = calculatePatternScore(results.duplicates, results.patterns?.length || 0);
711
+ const patternScore = calculatePatternScore(
712
+ results.duplicates,
713
+ results.patterns?.length || 0
714
+ );
515
715
  toolScores.set("pattern-detect", patternScore);
516
716
  } catch (err) {
717
+ void err;
517
718
  }
518
719
  }
519
720
  if (results.context) {
@@ -523,6 +724,7 @@ async function scanAction(directory, options) {
523
724
  const contextScore = calculateContextScore(ctxSummary);
524
725
  toolScores.set("context-analyzer", contextScore);
525
726
  } catch (err) {
727
+ void err;
526
728
  }
527
729
  }
528
730
  if (results.consistency) {
@@ -530,17 +732,24 @@ async function scanAction(directory, options) {
530
732
  try {
531
733
  const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
532
734
  const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
533
- const consistencyScore = calculateConsistencyScore(issues, totalFiles);
735
+ const consistencyScore = calculateConsistencyScore(
736
+ issues,
737
+ totalFiles
738
+ );
534
739
  toolScores.set("consistency", consistencyScore);
535
740
  } catch (err) {
741
+ void err;
536
742
  }
537
743
  }
538
744
  if (results.aiSignalClarity) {
539
- const { calculateHallucinationScore } = await import("@aiready/ai-signal-clarity");
745
+ const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
540
746
  try {
541
- const hrScore = calculateHallucinationScore(results.aiSignalClarity);
747
+ const hrScore = calculateAiSignalClarityScore(
748
+ results.aiSignalClarity
749
+ );
542
750
  toolScores.set("ai-signal-clarity", hrScore);
543
751
  } catch (err) {
752
+ void err;
544
753
  }
545
754
  }
546
755
  if (results.grounding) {
@@ -549,6 +758,7 @@ async function scanAction(directory, options) {
549
758
  const agScore = calculateGroundingScore(results.grounding);
550
759
  toolScores.set("agent-grounding", agScore);
551
760
  } catch (err) {
761
+ void err;
552
762
  }
553
763
  }
554
764
  if (results.testability) {
@@ -557,6 +767,7 @@ async function scanAction(directory, options) {
557
767
  const tbScore = calculateTestabilityScore(results.testability);
558
768
  toolScores.set("testability", tbScore);
559
769
  } catch (err) {
770
+ void err;
560
771
  }
561
772
  }
562
773
  if (results.docDrift) {
@@ -565,7 +776,13 @@ async function scanAction(directory, options) {
565
776
  score: results.docDrift.summary.score,
566
777
  rawMetrics: results.docDrift.rawData,
567
778
  factors: [],
568
- recommendations: results.docDrift.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
779
+ recommendations: (results.docDrift.recommendations || []).map(
780
+ (action) => ({
781
+ action,
782
+ estimatedImpact: 5,
783
+ priority: "medium"
784
+ })
785
+ )
569
786
  });
570
787
  }
571
788
  if (results.deps) {
@@ -574,17 +791,43 @@ async function scanAction(directory, options) {
574
791
  score: results.deps.summary.score,
575
792
  rawMetrics: results.deps.rawData,
576
793
  factors: [],
577
- recommendations: results.deps.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
794
+ recommendations: (results.deps.recommendations || []).map(
795
+ (action) => ({
796
+ action,
797
+ estimatedImpact: 5,
798
+ priority: "medium"
799
+ })
800
+ )
801
+ });
802
+ }
803
+ if (results.changeAmplification) {
804
+ toolScores.set("change-amplification", {
805
+ toolName: "change-amplification",
806
+ score: results.changeAmplification.summary.score,
807
+ rawMetrics: results.changeAmplification.rawData,
808
+ factors: [],
809
+ recommendations: (results.changeAmplification.recommendations || []).map((action) => ({
810
+ action,
811
+ estimatedImpact: 5,
812
+ priority: "medium"
813
+ }))
578
814
  });
579
815
  }
580
816
  const cliWeights = (0, import_core.parseWeightString)(options.weights);
581
817
  if (toolScores.size > 0) {
582
- scoringResult = (0, import_core.calculateOverallScore)(toolScores, finalOptions, cliWeights.size ? cliWeights : void 0);
818
+ scoringResult = (0, import_core.calculateOverallScore)(
819
+ toolScores,
820
+ finalOptions,
821
+ cliWeights.size ? cliWeights : void 0
822
+ );
583
823
  console.log(import_chalk2.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
584
824
  console.log(` ${(0, import_core.formatScore)(scoringResult)}`);
585
825
  if (options.compareTo) {
586
826
  try {
587
- const prevReportStr = (0, import_fs2.readFileSync)((0, import_path2.resolve)(process.cwd(), options.compareTo), "utf8");
827
+ const prevReportStr = (0, import_fs2.readFileSync)(
828
+ (0, import_path2.resolve)(process.cwd(), options.compareTo),
829
+ "utf8"
830
+ );
588
831
  const prevReport = JSON.parse(prevReportStr);
589
832
  const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
590
833
  if (typeof prevScore === "number") {
@@ -592,23 +835,44 @@ async function scanAction(directory, options) {
592
835
  const diffStr = diff > 0 ? `+${diff}` : String(diff);
593
836
  console.log();
594
837
  if (diff > 0) {
595
- console.log(import_chalk2.default.green(` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
838
+ console.log(
839
+ import_chalk2.default.green(
840
+ ` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
841
+ )
842
+ );
596
843
  } else if (diff < 0) {
597
- console.log(import_chalk2.default.red(` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
844
+ console.log(
845
+ import_chalk2.default.red(
846
+ ` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
847
+ )
848
+ );
598
849
  } else {
599
- console.log(import_chalk2.default.blue(` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
850
+ console.log(
851
+ import_chalk2.default.blue(
852
+ ` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
853
+ )
854
+ );
600
855
  }
601
856
  scoringResult.trend = {
602
857
  previousScore: prevScore,
603
858
  difference: diff
604
859
  };
605
860
  } else {
606
- console.log(import_chalk2.default.yellow(`
607
- \u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`));
861
+ console.log(
862
+ import_chalk2.default.yellow(
863
+ `
864
+ \u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`
865
+ )
866
+ );
608
867
  }
609
868
  } catch (e) {
610
- console.log(import_chalk2.default.yellow(`
611
- \u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`));
869
+ void e;
870
+ console.log(
871
+ import_chalk2.default.yellow(
872
+ `
873
+ \u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`
874
+ )
875
+ );
612
876
  }
613
877
  }
614
878
  if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
@@ -616,7 +880,9 @@ async function scanAction(directory, options) {
616
880
  scoringResult.breakdown.forEach((tool) => {
617
881
  const rating = (0, import_core.getRating)(tool.score);
618
882
  const rd = (0, import_core.getRatingDisplay)(rating);
619
- console.log(` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`);
883
+ console.log(
884
+ ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
885
+ );
620
886
  });
621
887
  console.log();
622
888
  if (finalOptions.scoring?.showBreakdown) {
@@ -634,10 +900,34 @@ async function scanAction(directory, options) {
634
900
  if (outputFormat === "json") {
635
901
  const timestamp = getReportTimestamp();
636
902
  const defaultFilename = `aiready-report-${timestamp}.json`;
637
- const outputPath = (0, import_core.resolveOutputPath)(userOutputFile, defaultFilename, resolvedDir);
903
+ const outputPath = (0, import_core.resolveOutputPath)(
904
+ userOutputFile,
905
+ defaultFilename,
906
+ resolvedDir
907
+ );
908
+ const outputData = { ...results, scoring: scoringResult };
909
+ (0, import_core.handleJSONOutput)(
910
+ outputData,
911
+ outputPath,
912
+ `\u2705 Report saved to ${outputPath}`
913
+ );
914
+ await warnIfGraphCapExceeded(outputData, resolvedDir);
915
+ } else {
916
+ const timestamp = getReportTimestamp();
917
+ const defaultFilename = `aiready-report-${timestamp}.json`;
918
+ const outputPath = (0, import_core.resolveOutputPath)(
919
+ userOutputFile,
920
+ defaultFilename,
921
+ resolvedDir
922
+ );
638
923
  const outputData = { ...results, scoring: scoringResult };
639
- (0, import_core.handleJSONOutput)(outputData, outputPath, `\u2705 Report saved to ${outputPath}`);
640
- warnIfGraphCapExceeded(outputData, resolvedDir);
924
+ try {
925
+ (0, import_fs2.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
926
+ console.log(import_chalk2.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
927
+ await warnIfGraphCapExceeded(outputData, resolvedDir);
928
+ } catch (err) {
929
+ void err;
930
+ }
641
931
  }
642
932
  const isCI = options.ci || process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
643
933
  if (isCI && scoringResult) {
@@ -654,16 +944,22 @@ async function scanAction(directory, options) {
654
944
  }
655
945
  console.log("::endgroup::");
656
946
  if (threshold && scoringResult.overall < threshold) {
657
- console.log(`::error::AI Readiness Score ${scoringResult.overall} is below threshold ${threshold}`);
947
+ console.log(
948
+ `::error::AI Readiness Score ${scoringResult.overall} is below threshold ${threshold}`
949
+ );
658
950
  } else if (threshold) {
659
- console.log(`::notice::AI Readiness Score: ${scoringResult.overall}/100 (threshold: ${threshold})`);
951
+ console.log(
952
+ `::notice::AI Readiness Score: ${scoringResult.overall}/100 (threshold: ${threshold})`
953
+ );
660
954
  }
661
955
  if (results.patterns) {
662
956
  const criticalPatterns = results.patterns.flatMap(
663
957
  (p) => p.issues.filter((i) => i.severity === "critical")
664
958
  );
665
959
  criticalPatterns.slice(0, 10).forEach((issue) => {
666
- console.log(`::warning file=${issue.location?.file || "unknown"},line=${issue.location?.line || 1}::${issue.message}`);
960
+ console.log(
961
+ `::warning file=${issue.location?.file || "unknown"},line=${issue.location?.line || 1}::${issue.message}`
962
+ );
667
963
  });
668
964
  }
669
965
  }
@@ -712,16 +1008,30 @@ async function scanAction(directory, options) {
712
1008
  console.log(import_chalk2.default.red("\n\u{1F6AB} PR BLOCKED: AI Readiness Check Failed"));
713
1009
  console.log(import_chalk2.default.red(` Reason: ${failReason}`));
714
1010
  console.log(import_chalk2.default.dim("\n Remediation steps:"));
715
- console.log(import_chalk2.default.dim(" 1. Run `aiready scan` locally to see detailed issues"));
1011
+ console.log(
1012
+ import_chalk2.default.dim(" 1. Run `aiready scan` locally to see detailed issues")
1013
+ );
716
1014
  console.log(import_chalk2.default.dim(" 2. Fix the critical issues before merging"));
717
- console.log(import_chalk2.default.dim(" 3. Consider upgrading to Team plan for historical tracking: https://getaiready.dev/pricing"));
1015
+ console.log(
1016
+ import_chalk2.default.dim(
1017
+ " 3. Consider upgrading to Team plan for historical tracking: https://getaiready.dev/pricing"
1018
+ )
1019
+ );
718
1020
  process.exit(1);
719
1021
  } else {
720
1022
  console.log(import_chalk2.default.green("\n\u2705 PR PASSED: AI Readiness Check"));
721
1023
  if (threshold) {
722
- console.log(import_chalk2.default.green(` Score: ${scoringResult.overall}/100 (threshold: ${threshold})`));
1024
+ console.log(
1025
+ import_chalk2.default.green(
1026
+ ` Score: ${scoringResult.overall}/100 (threshold: ${threshold})`
1027
+ )
1028
+ );
723
1029
  }
724
- console.log(import_chalk2.default.dim("\n \u{1F4A1} Track historical trends: https://getaiready.dev \u2014 Team plan $99/mo"));
1030
+ console.log(
1031
+ import_chalk2.default.dim(
1032
+ "\n \u{1F4A1} Track historical trends: https://getaiready.dev \u2014 Team plan $99/mo"
1033
+ )
1034
+ );
725
1035
  }
726
1036
  }
727
1037
  } catch (error) {
@@ -793,7 +1103,11 @@ async function patternsAction(directory, options) {
793
1103
  if (options.minSharedTokens) {
794
1104
  cliOptions.minSharedTokens = parseInt(options.minSharedTokens);
795
1105
  }
796
- const finalOptions = await (0, import_core2.loadMergedConfig)(resolvedDir, defaults, cliOptions);
1106
+ const finalOptions = await (0, import_core2.loadMergedConfig)(
1107
+ resolvedDir,
1108
+ defaults,
1109
+ cliOptions
1110
+ );
797
1111
  const { analyzePatterns: analyzePatterns2, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
798
1112
  const { results, duplicates } = await analyzePatterns2(finalOptions);
799
1113
  const elapsedTime = (0, import_core2.getElapsedTime)(startTime);
@@ -815,7 +1129,11 @@ async function patternsAction(directory, options) {
815
1129
  `aiready-report-${getReportTimestamp()}.json`,
816
1130
  resolvedDir
817
1131
  );
818
- (0, import_core2.handleJSONOutput)(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
1132
+ (0, import_core2.handleJSONOutput)(
1133
+ outputData,
1134
+ outputPath,
1135
+ `\u2705 Results saved to ${outputPath}`
1136
+ );
819
1137
  } else {
820
1138
  const terminalWidth = process.stdout.columns || 80;
821
1139
  const dividerWidth = Math.min(60, terminalWidth - 2);
@@ -823,10 +1141,22 @@ async function patternsAction(directory, options) {
823
1141
  console.log(import_chalk3.default.cyan(divider));
824
1142
  console.log(import_chalk3.default.bold.white(" PATTERN ANALYSIS SUMMARY"));
825
1143
  console.log(import_chalk3.default.cyan(divider) + "\n");
826
- console.log(import_chalk3.default.white(`\u{1F4C1} Files analyzed: ${import_chalk3.default.bold(results.length)}`));
827
- console.log(import_chalk3.default.yellow(`\u26A0 Duplicate patterns found: ${import_chalk3.default.bold(summary.totalPatterns)}`));
828
- console.log(import_chalk3.default.red(`\u{1F4B0} Token cost (wasted): ${import_chalk3.default.bold(summary.totalTokenCost.toLocaleString())}`));
829
- console.log(import_chalk3.default.gray(`\u23F1 Analysis time: ${import_chalk3.default.bold(elapsedTime + "s")}`));
1144
+ console.log(
1145
+ import_chalk3.default.white(`\u{1F4C1} Files analyzed: ${import_chalk3.default.bold(results.length)}`)
1146
+ );
1147
+ console.log(
1148
+ import_chalk3.default.yellow(
1149
+ `\u26A0 Duplicate patterns found: ${import_chalk3.default.bold(summary.totalPatterns)}`
1150
+ )
1151
+ );
1152
+ console.log(
1153
+ import_chalk3.default.red(
1154
+ `\u{1F4B0} Token cost (wasted): ${import_chalk3.default.bold(summary.totalTokenCost.toLocaleString())}`
1155
+ )
1156
+ );
1157
+ console.log(
1158
+ import_chalk3.default.gray(`\u23F1 Analysis time: ${import_chalk3.default.bold(elapsedTime + "s")}`)
1159
+ );
830
1160
  const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
831
1161
  if (sortedTypes.length > 0) {
832
1162
  console.log(import_chalk3.default.cyan("\n" + divider));
@@ -846,13 +1176,21 @@ async function patternsAction(directory, options) {
846
1176
  const severityIcon = dup.similarity > 0.95 ? "\u{1F534}" : dup.similarity > 0.9 ? "\u{1F7E1}" : "\u{1F535}";
847
1177
  const file1Name = dup.file1.split("/").pop() || dup.file1;
848
1178
  const file2Name = dup.file2.split("/").pop() || dup.file2;
849
- console.log(`${severityIcon} ${severity}: ${import_chalk3.default.bold(file1Name)} \u2194 ${import_chalk3.default.bold(file2Name)}`);
850
- console.log(` Similarity: ${import_chalk3.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk3.default.bold(dup.tokenCost.toLocaleString())} tokens each`);
851
- console.log(` Lines: ${import_chalk3.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk3.default.cyan(dup.line2 + "-" + dup.endLine2)}
852
- `);
1179
+ console.log(
1180
+ `${severityIcon} ${severity}: ${import_chalk3.default.bold(file1Name)} \u2194 ${import_chalk3.default.bold(file2Name)}`
1181
+ );
1182
+ console.log(
1183
+ ` Similarity: ${import_chalk3.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk3.default.bold(dup.tokenCost.toLocaleString())} tokens each`
1184
+ );
1185
+ console.log(
1186
+ ` Lines: ${import_chalk3.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk3.default.cyan(dup.line2 + "-" + dup.endLine2)}
1187
+ `
1188
+ );
853
1189
  });
854
1190
  } else {
855
- console.log(import_chalk3.default.green("\n\u2728 Great! No duplicate patterns detected.\n"));
1191
+ console.log(
1192
+ import_chalk3.default.green("\n\u2728 Great! No duplicate patterns detected.\n")
1193
+ );
856
1194
  }
857
1195
  if (patternScore) {
858
1196
  console.log(import_chalk3.default.cyan(divider));
@@ -892,7 +1230,7 @@ async function contextAction(directory, options) {
892
1230
  file: void 0
893
1231
  }
894
1232
  };
895
- let baseOptions = await (0, import_core3.loadMergedConfig)(resolvedDir, defaults, {
1233
+ const baseOptions = await (0, import_core3.loadMergedConfig)(resolvedDir, defaults, {
896
1234
  maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
897
1235
  maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
898
1236
  include: options.include?.split(","),
@@ -900,13 +1238,20 @@ async function contextAction(directory, options) {
900
1238
  });
901
1239
  let finalOptions = { ...baseOptions };
902
1240
  const { getSmartDefaults } = await import("@aiready/context-analyzer");
903
- const contextSmartDefaults = await getSmartDefaults(resolvedDir, baseOptions);
1241
+ const contextSmartDefaults = await getSmartDefaults(
1242
+ resolvedDir,
1243
+ baseOptions
1244
+ );
904
1245
  finalOptions = { ...contextSmartDefaults, ...finalOptions };
905
1246
  console.log("\u{1F4CB} Configuration:");
906
1247
  console.log(` Max depth: ${finalOptions.maxDepth}`);
907
1248
  console.log(` Max context budget: ${finalOptions.maxContextBudget}`);
908
- console.log(` Min cohesion: ${(finalOptions.minCohesion * 100).toFixed(1)}%`);
909
- console.log(` Max fragmentation: ${(finalOptions.maxFragmentation * 100).toFixed(1)}%`);
1249
+ console.log(
1250
+ ` Min cohesion: ${(finalOptions.minCohesion * 100).toFixed(1)}%`
1251
+ );
1252
+ console.log(
1253
+ ` Max fragmentation: ${(finalOptions.maxFragmentation * 100).toFixed(1)}%`
1254
+ );
910
1255
  console.log(` Analysis focus: ${finalOptions.focus}`);
911
1256
  console.log("");
912
1257
  const { analyzeContext: analyzeContext2, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
@@ -930,7 +1275,11 @@ async function contextAction(directory, options) {
930
1275
  `aiready-report-${getReportTimestamp()}.json`,
931
1276
  resolvedDir
932
1277
  );
933
- (0, import_core3.handleJSONOutput)(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
1278
+ (0, import_core3.handleJSONOutput)(
1279
+ outputData,
1280
+ outputPath,
1281
+ `\u2705 Results saved to ${outputPath}`
1282
+ );
934
1283
  } else {
935
1284
  const terminalWidth = process.stdout.columns || 80;
936
1285
  const dividerWidth = Math.min(60, terminalWidth - 2);
@@ -938,59 +1287,103 @@ async function contextAction(directory, options) {
938
1287
  console.log(import_chalk4.default.cyan(divider));
939
1288
  console.log(import_chalk4.default.bold.white(" CONTEXT ANALYSIS SUMMARY"));
940
1289
  console.log(import_chalk4.default.cyan(divider) + "\n");
941
- console.log(import_chalk4.default.white(`\u{1F4C1} Files analyzed: ${import_chalk4.default.bold(summary.totalFiles)}`));
942
- console.log(import_chalk4.default.white(`\u{1F4CA} Total tokens: ${import_chalk4.default.bold(summary.totalTokens.toLocaleString())}`));
943
- console.log(import_chalk4.default.yellow(`\u{1F4B0} Avg context budget: ${import_chalk4.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`));
944
- console.log(import_chalk4.default.white(`\u23F1 Analysis time: ${import_chalk4.default.bold(elapsedTime + "s")}
945
- `));
1290
+ console.log(
1291
+ import_chalk4.default.white(`\u{1F4C1} Files analyzed: ${import_chalk4.default.bold(summary.totalFiles)}`)
1292
+ );
1293
+ console.log(
1294
+ import_chalk4.default.white(
1295
+ `\u{1F4CA} Total tokens: ${import_chalk4.default.bold(summary.totalTokens.toLocaleString())}`
1296
+ )
1297
+ );
1298
+ console.log(
1299
+ import_chalk4.default.yellow(
1300
+ `\u{1F4B0} Avg context budget: ${import_chalk4.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
1301
+ )
1302
+ );
1303
+ console.log(
1304
+ import_chalk4.default.white(`\u23F1 Analysis time: ${import_chalk4.default.bold(elapsedTime + "s")}
1305
+ `)
1306
+ );
946
1307
  const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
947
1308
  if (totalIssues > 0) {
948
1309
  console.log(import_chalk4.default.bold("\u26A0\uFE0F Issues Found:\n"));
949
1310
  if (summary.criticalIssues > 0) {
950
- console.log(import_chalk4.default.red(` \u{1F534} Critical: ${import_chalk4.default.bold(summary.criticalIssues)}`));
1311
+ console.log(
1312
+ import_chalk4.default.red(` \u{1F534} Critical: ${import_chalk4.default.bold(summary.criticalIssues)}`)
1313
+ );
951
1314
  }
952
1315
  if (summary.majorIssues > 0) {
953
- console.log(import_chalk4.default.yellow(` \u{1F7E1} Major: ${import_chalk4.default.bold(summary.majorIssues)}`));
1316
+ console.log(
1317
+ import_chalk4.default.yellow(` \u{1F7E1} Major: ${import_chalk4.default.bold(summary.majorIssues)}`)
1318
+ );
954
1319
  }
955
1320
  if (summary.minorIssues > 0) {
956
- console.log(import_chalk4.default.blue(` \u{1F535} Minor: ${import_chalk4.default.bold(summary.minorIssues)}`));
1321
+ console.log(
1322
+ import_chalk4.default.blue(` \u{1F535} Minor: ${import_chalk4.default.bold(summary.minorIssues)}`)
1323
+ );
957
1324
  }
958
- console.log(import_chalk4.default.green(`
1325
+ console.log(
1326
+ import_chalk4.default.green(
1327
+ `
959
1328
  \u{1F4A1} Potential savings: ${import_chalk4.default.bold(summary.totalPotentialSavings.toLocaleString())} tokens
960
- `));
1329
+ `
1330
+ )
1331
+ );
961
1332
  } else {
962
1333
  console.log(import_chalk4.default.green("\u2705 No significant issues found!\n"));
963
1334
  }
964
1335
  if (summary.deepFiles.length > 0) {
965
1336
  console.log(import_chalk4.default.bold("\u{1F4CF} Deep Import Chains:\n"));
966
- console.log(import_chalk4.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`));
967
- console.log(import_chalk4.default.gray(` Maximum depth: ${summary.maxImportDepth}
968
- `));
1337
+ console.log(
1338
+ import_chalk4.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1339
+ );
1340
+ console.log(
1341
+ import_chalk4.default.gray(` Maximum depth: ${summary.maxImportDepth}
1342
+ `)
1343
+ );
969
1344
  summary.deepFiles.slice(0, 10).forEach((item) => {
970
1345
  const fileName = item.file.split("/").slice(-2).join("/");
971
- console.log(` ${import_chalk4.default.cyan("\u2192")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(depth: ${item.depth})`)}`);
1346
+ console.log(
1347
+ ` ${import_chalk4.default.cyan("\u2192")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(depth: ${item.depth})`)}`
1348
+ );
972
1349
  });
973
1350
  console.log();
974
1351
  }
975
1352
  if (summary.fragmentedModules.length > 0) {
976
1353
  console.log(import_chalk4.default.bold("\u{1F9E9} Fragmented Modules:\n"));
977
- console.log(import_chalk4.default.gray(` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
978
- `));
1354
+ console.log(
1355
+ import_chalk4.default.gray(
1356
+ ` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
1357
+ `
1358
+ )
1359
+ );
979
1360
  summary.fragmentedModules.slice(0, 10).forEach((module2) => {
980
- console.log(` ${import_chalk4.default.yellow("\u25CF")} ${import_chalk4.default.white(module2.domain)} - ${import_chalk4.default.dim(`${module2.files.length} files, ${(module2.fragmentationScore * 100).toFixed(0)}% scattered`)}`);
981
- console.log(import_chalk4.default.dim(` Token cost: ${module2.totalTokens.toLocaleString()}, Cohesion: ${(module2.avgCohesion * 100).toFixed(0)}%`));
1361
+ console.log(
1362
+ ` ${import_chalk4.default.yellow("\u25CF")} ${import_chalk4.default.white(module2.domain)} - ${import_chalk4.default.dim(`${module2.files.length} files, ${(module2.fragmentationScore * 100).toFixed(0)}% scattered`)}`
1363
+ );
1364
+ console.log(
1365
+ import_chalk4.default.dim(
1366
+ ` Token cost: ${module2.totalTokens.toLocaleString()}, Cohesion: ${(module2.avgCohesion * 100).toFixed(0)}%`
1367
+ )
1368
+ );
982
1369
  });
983
1370
  console.log();
984
1371
  }
985
1372
  if (summary.lowCohesionFiles.length > 0) {
986
1373
  console.log(import_chalk4.default.bold("\u{1F500} Low Cohesion Files:\n"));
987
- console.log(import_chalk4.default.gray(` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
988
- `));
1374
+ console.log(
1375
+ import_chalk4.default.gray(
1376
+ ` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
1377
+ `
1378
+ )
1379
+ );
989
1380
  summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
990
1381
  const fileName = item.file.split("/").slice(-2).join("/");
991
1382
  const scorePercent = (item.score * 100).toFixed(0);
992
1383
  const color = item.score < 0.4 ? import_chalk4.default.red : import_chalk4.default.yellow;
993
- console.log(` ${color("\u25CB")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(${scorePercent}% cohesion)`)}`);
1384
+ console.log(
1385
+ ` ${color("\u25CB")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(${scorePercent}% cohesion)`)}`
1386
+ );
994
1387
  });
995
1388
  console.log();
996
1389
  }
@@ -999,7 +1392,9 @@ async function contextAction(directory, options) {
999
1392
  summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
1000
1393
  const fileName = item.file.split("/").slice(-2).join("/");
1001
1394
  const severityColor = item.severity === "critical" ? import_chalk4.default.red : item.severity === "major" ? import_chalk4.default.yellow : import_chalk4.default.blue;
1002
- console.log(` ${severityColor("\u25CF")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`);
1395
+ console.log(
1396
+ ` ${severityColor("\u25CF")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1397
+ );
1003
1398
  });
1004
1399
  console.log();
1005
1400
  }
@@ -1050,7 +1445,10 @@ async function consistencyAction(directory, options) {
1050
1445
  let consistencyScore;
1051
1446
  if (options.score) {
1052
1447
  const issues = report.results?.flatMap((r) => r.issues) || [];
1053
- consistencyScore = calculateConsistencyScore(issues, report.summary.filesAnalyzed);
1448
+ consistencyScore = calculateConsistencyScore(
1449
+ issues,
1450
+ report.summary.filesAnalyzed
1451
+ );
1054
1452
  }
1055
1453
  const outputFormat = options.output || finalOptions.output?.format || "console";
1056
1454
  const userOutputFile = options.outputFile || finalOptions.output?.file;
@@ -1068,7 +1466,11 @@ async function consistencyAction(directory, options) {
1068
1466
  `aiready-report-${getReportTimestamp()}.json`,
1069
1467
  resolvedDir
1070
1468
  );
1071
- (0, import_core4.handleJSONOutput)(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
1469
+ (0, import_core4.handleJSONOutput)(
1470
+ outputData,
1471
+ outputPath,
1472
+ `\u2705 Results saved to ${outputPath}`
1473
+ );
1072
1474
  } else if (outputFormat === "markdown") {
1073
1475
  const markdown = generateMarkdownReport(report, elapsedTime);
1074
1476
  const outputPath = (0, import_core4.resolveOutputPath)(
@@ -1080,15 +1482,23 @@ async function consistencyAction(directory, options) {
1080
1482
  console.log(import_chalk5.default.green(`\u2705 Report saved to ${outputPath}`));
1081
1483
  } else {
1082
1484
  console.log(import_chalk5.default.bold("\n\u{1F4CA} Summary\n"));
1083
- console.log(`Files Analyzed: ${import_chalk5.default.cyan(report.summary.filesAnalyzed)}`);
1485
+ console.log(
1486
+ `Files Analyzed: ${import_chalk5.default.cyan(report.summary.filesAnalyzed)}`
1487
+ );
1084
1488
  console.log(`Total Issues: ${import_chalk5.default.yellow(report.summary.totalIssues)}`);
1085
1489
  console.log(` Naming: ${import_chalk5.default.yellow(report.summary.namingIssues)}`);
1086
1490
  console.log(` Patterns: ${import_chalk5.default.yellow(report.summary.patternIssues)}`);
1087
- console.log(` Architecture: ${import_chalk5.default.yellow(report.summary.architectureIssues || 0)}`);
1491
+ console.log(
1492
+ ` Architecture: ${import_chalk5.default.yellow(report.summary.architectureIssues || 0)}`
1493
+ );
1088
1494
  console.log(`Analysis Time: ${import_chalk5.default.gray(elapsedTime + "s")}
1089
1495
  `);
1090
1496
  if (report.summary.totalIssues === 0) {
1091
- console.log(import_chalk5.default.green("\u2728 No consistency issues found! Your codebase is well-maintained.\n"));
1497
+ console.log(
1498
+ import_chalk5.default.green(
1499
+ "\u2728 No consistency issues found! Your codebase is well-maintained.\n"
1500
+ )
1501
+ );
1092
1502
  } else {
1093
1503
  const namingResults = report.results.filter(
1094
1504
  (r) => r.issues.some((i) => i.category === "naming")
@@ -1104,10 +1514,14 @@ async function consistencyAction(directory, options) {
1104
1514
  for (const issue of result.issues) {
1105
1515
  if (shown >= 5) break;
1106
1516
  const severityColor = issue.severity === "critical" ? import_chalk5.default.red : issue.severity === "major" ? import_chalk5.default.yellow : issue.severity === "minor" ? import_chalk5.default.blue : import_chalk5.default.gray;
1107
- console.log(`${severityColor(issue.severity.toUpperCase())} ${import_chalk5.default.dim(`${issue.location.file}:${issue.location.line}`)}`);
1517
+ console.log(
1518
+ `${severityColor(issue.severity.toUpperCase())} ${import_chalk5.default.dim(`${issue.location.file}:${issue.location.line}`)}`
1519
+ );
1108
1520
  console.log(` ${issue.message}`);
1109
1521
  if (issue.suggestion) {
1110
- console.log(` ${import_chalk5.default.dim("\u2192")} ${import_chalk5.default.italic(issue.suggestion)}`);
1522
+ console.log(
1523
+ ` ${import_chalk5.default.dim("\u2192")} ${import_chalk5.default.italic(issue.suggestion)}`
1524
+ );
1111
1525
  }
1112
1526
  console.log();
1113
1527
  shown++;
@@ -1127,10 +1541,14 @@ async function consistencyAction(directory, options) {
1127
1541
  for (const issue of result.issues) {
1128
1542
  if (shown >= 5) break;
1129
1543
  const severityColor = issue.severity === "critical" ? import_chalk5.default.red : issue.severity === "major" ? import_chalk5.default.yellow : issue.severity === "minor" ? import_chalk5.default.blue : import_chalk5.default.gray;
1130
- console.log(`${severityColor(issue.severity.toUpperCase())} ${import_chalk5.default.dim(`${issue.location.file}:${issue.location.line}`)}`);
1544
+ console.log(
1545
+ `${severityColor(issue.severity.toUpperCase())} ${import_chalk5.default.dim(`${issue.location.file}:${issue.location.line}`)}`
1546
+ );
1131
1547
  console.log(` ${issue.message}`);
1132
1548
  if (issue.suggestion) {
1133
- console.log(` ${import_chalk5.default.dim("\u2192")} ${import_chalk5.default.italic(issue.suggestion)}`);
1549
+ console.log(
1550
+ ` ${import_chalk5.default.dim("\u2192")} ${import_chalk5.default.italic(issue.suggestion)}`
1551
+ );
1134
1552
  }
1135
1553
  console.log();
1136
1554
  shown++;
@@ -1176,15 +1594,21 @@ async function visualizeAction(directory, options) {
1176
1594
  const latestScan = findLatestScanReport(dirPath);
1177
1595
  if (latestScan) {
1178
1596
  reportPath = latestScan;
1179
- console.log(import_chalk6.default.dim(`Found latest report: ${latestScan.split("/").pop()}`));
1597
+ console.log(
1598
+ import_chalk6.default.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1599
+ );
1180
1600
  } else {
1181
1601
  console.error(import_chalk6.default.red("\u274C No AI readiness report found"));
1182
- console.log(import_chalk6.default.dim(`
1602
+ console.log(
1603
+ import_chalk6.default.dim(
1604
+ `
1183
1605
  Generate a report with:
1184
1606
  aiready scan --output json
1185
1607
 
1186
1608
  Or specify a custom report:
1187
- aiready visualise --report <path-to-report.json>`));
1609
+ aiready visualise --report <path-to-report.json>`
1610
+ )
1611
+ );
1188
1612
  return;
1189
1613
  }
1190
1614
  }
@@ -1202,6 +1626,7 @@ Or specify a custom report:
1202
1626
  };
1203
1627
  }
1204
1628
  } catch (e) {
1629
+ void e;
1205
1630
  }
1206
1631
  }
1207
1632
  const envVisualizerConfig = JSON.stringify(graphConfig);
@@ -1222,11 +1647,18 @@ Or specify a custom report:
1222
1647
  } else {
1223
1648
  const nodemodulesLocations = [
1224
1649
  (0, import_path6.resolve)(dirPath, "node_modules", "@aiready", "visualizer"),
1225
- (0, import_path6.resolve)(process.cwd(), "node_modules", "@aiready", "visualizer")
1650
+ (0, import_path6.resolve)(
1651
+ process.cwd(),
1652
+ "node_modules",
1653
+ "@aiready",
1654
+ "visualizer"
1655
+ )
1226
1656
  ];
1227
1657
  let currentDir = dirPath;
1228
1658
  while (currentDir !== "/" && currentDir !== ".") {
1229
- nodemodulesLocations.push((0, import_path6.resolve)(currentDir, "node_modules", "@aiready", "visualizer"));
1659
+ nodemodulesLocations.push(
1660
+ (0, import_path6.resolve)(currentDir, "node_modules", "@aiready", "visualizer")
1661
+ );
1230
1662
  const parent = (0, import_path6.resolve)(currentDir, "..");
1231
1663
  if (parent === currentDir) break;
1232
1664
  currentDir = parent;
@@ -1243,7 +1675,8 @@ Or specify a custom report:
1243
1675
  const vizPkgPath = require.resolve("@aiready/visualizer/package.json");
1244
1676
  webDir = (0, import_path6.resolve)(vizPkgPath, "..");
1245
1677
  visualizerAvailable = true;
1246
- } catch (e) {
1678
+ } catch (err) {
1679
+ void err;
1247
1680
  }
1248
1681
  }
1249
1682
  }
@@ -1271,30 +1704,46 @@ Or specify a custom report:
1271
1704
  AIREADY_REPORT_PATH: reportPath,
1272
1705
  AIREADY_VISUALIZER_CONFIG: envVisualizerConfig
1273
1706
  };
1274
- const vite = (0, import_child_process.spawn)("pnpm", ["run", "dev:web"], { cwd: spawnCwd, stdio: "inherit", shell: true, env: envForSpawn });
1707
+ const vite = (0, import_child_process.spawn)("pnpm", ["run", "dev:web"], {
1708
+ cwd: spawnCwd,
1709
+ stdio: "inherit",
1710
+ shell: true,
1711
+ env: envForSpawn
1712
+ });
1275
1713
  const onExit = () => {
1276
1714
  try {
1277
1715
  reportWatcher.close();
1278
- } catch (e) {
1716
+ } catch (err) {
1717
+ void err;
1279
1718
  }
1280
1719
  try {
1281
1720
  vite.kill();
1282
- } catch (e) {
1721
+ } catch (err) {
1722
+ void err;
1283
1723
  }
1284
1724
  process.exit(0);
1285
1725
  };
1286
1726
  process.on("SIGINT", onExit);
1287
1727
  process.on("SIGTERM", onExit);
1288
1728
  devServerStarted = true;
1729
+ void devServerStarted;
1289
1730
  return;
1290
1731
  } else {
1291
- console.log(import_chalk6.default.yellow("\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."));
1292
- console.log(import_chalk6.default.cyan(" Falling back to static HTML generation...\n"));
1732
+ console.log(
1733
+ import_chalk6.default.yellow(
1734
+ "\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."
1735
+ )
1736
+ );
1737
+ console.log(
1738
+ import_chalk6.default.cyan(" Falling back to static HTML generation...\n")
1739
+ );
1293
1740
  useDevMode = false;
1294
1741
  }
1295
1742
  } catch (err) {
1296
1743
  console.error("Failed to start dev server:", err);
1297
- console.log(import_chalk6.default.cyan(" Falling back to static HTML generation...\n"));
1744
+ console.log(
1745
+ import_chalk6.default.cyan(" Falling back to static HTML generation...\n")
1746
+ );
1298
1747
  useDevMode = false;
1299
1748
  }
1300
1749
  }
@@ -1316,20 +1765,25 @@ Or specify a custom report:
1316
1765
  const urlPath = req.url || "/";
1317
1766
  if (urlPath === "/" || urlPath === "/index.html") {
1318
1767
  const content = await fsp.readFile(outPath, "utf8");
1319
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1768
+ res.writeHead(200, {
1769
+ "Content-Type": "text/html; charset=utf-8"
1770
+ });
1320
1771
  res.end(content);
1321
1772
  return;
1322
1773
  }
1323
1774
  res.writeHead(404, { "Content-Type": "text/plain" });
1324
1775
  res.end("Not found");
1325
1776
  } catch (e) {
1777
+ void e;
1326
1778
  res.writeHead(500, { "Content-Type": "text/plain" });
1327
1779
  res.end("Server error");
1328
1780
  }
1329
1781
  });
1330
1782
  server.listen(port, () => {
1331
1783
  const addr = `http://localhost:${port}/`;
1332
- console.log(import_chalk6.default.cyan(`\u{1F310} Local visualization server running at ${addr}`));
1784
+ console.log(
1785
+ import_chalk6.default.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1786
+ );
1333
1787
  (0, import_child_process.spawn)(opener, [`"${addr}"`], { shell: true });
1334
1788
  });
1335
1789
  process.on("SIGINT", () => {
@@ -1395,19 +1849,23 @@ var getDirname = () => {
1395
1849
  if (typeof __dirname !== "undefined") return __dirname;
1396
1850
  return (0, import_path7.dirname)((0, import_url.fileURLToPath)(import_meta.url));
1397
1851
  };
1398
- var packageJson = JSON.parse((0, import_fs5.readFileSync)((0, import_path7.join)(getDirname(), "../package.json"), "utf8"));
1852
+ var packageJson = JSON.parse(
1853
+ (0, import_fs5.readFileSync)((0, import_path7.join)(getDirname(), "../package.json"), "utf8")
1854
+ );
1399
1855
  var program = new import_commander.Command();
1400
- program.name("aiready").description("AIReady - Assess and improve AI-readiness of codebases").version(packageJson.version).addHelpText("after", `
1856
+ program.name("aiready").description("AIReady - Assess and improve AI-readiness of codebases").version(packageJson.version).addHelpText(
1857
+ "after",
1858
+ `
1401
1859
  AI READINESS SCORING:
1402
1860
  Get a 0-100 score indicating how AI-ready your codebase is.
1403
1861
  Use --score flag with any analysis command for detailed breakdown.
1404
1862
 
1405
1863
  EXAMPLES:
1406
- $ aiready scan # Quick analysis of current directory
1864
+ $ aiready scan # Comprehensive analysis of current directory
1407
1865
  $ aiready scan --score # Get AI Readiness Score (0-100)
1408
1866
  $ aiready scan --tools patterns # Run only pattern detection
1409
- $ aiready patterns --similarity 0.6 # Custom similarity threshold
1410
- $ aiready scan --output json --output-file results.json
1867
+ $ npx @aiready/cli scan # Industry standard way to run standard scan
1868
+ $ aiready scan --output json # Output raw JSON for piping
1411
1869
 
1412
1870
  GETTING STARTED:
1413
1871
  1. Run 'aiready scan' to analyze your codebase
@@ -1432,23 +1890,105 @@ CONFIGURATION:
1432
1890
  VERSION: ${packageJson.version}
1433
1891
  DOCUMENTATION: https://aiready.dev/docs/cli
1434
1892
  GITHUB: https://github.com/caopengau/aiready-cli
1435
- LANDING: https://github.com/caopengau/aiready-landing`);
1436
- program.command("scan").description("Run comprehensive AI-readiness analysis (patterns + context + consistency)").argument("[directory]", "Directory to analyze", ".").option("-t, --tools <tools>", "Tools to run (comma-separated: patterns,context,consistency,doc-drift,deps-health,aiSignalClarity,grounding,testability,changeAmplification)").option("--profile <type>", "Scan profile to use (agentic, cost, security, onboarding)").option("--compare-to <path>", "Compare results against a previous AIReady report JSON").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "json").option("--output-file <path>", "Output file path (for json)").option("--no-score", "Disable calculating AI Readiness Score (enabled by default)").option("--weights <weights>", "Custom scoring weights").option("--threshold <score>", "Fail CI/CD if score below threshold (0-100)").option("--ci", "CI mode: GitHub Actions annotations, no colors, fail on threshold").option("--fail-on <level>", "Fail on issues: critical, major, any", "critical").addHelpText("after", scanHelpText).action(async (directory, options) => {
1893
+ LANDING: https://github.com/caopengau/aiready-landing`
1894
+ );
1895
+ program.command("scan").description(
1896
+ "Run comprehensive AI-readiness analysis (patterns + context + consistency)"
1897
+ ).argument("[directory]", "Directory to analyze", ".").option(
1898
+ "-t, --tools <tools>",
1899
+ "Tools to run (comma-separated: patterns,context,consistency,doc-drift,deps-health,aiSignalClarity,grounding,testability,changeAmplification)"
1900
+ ).option(
1901
+ "--profile <type>",
1902
+ "Scan profile to use (agentic, cost, security, onboarding)"
1903
+ ).option(
1904
+ "--compare-to <path>",
1905
+ "Compare results against a previous AIReady report JSON"
1906
+ ).option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option(
1907
+ "--no-score",
1908
+ "Disable calculating AI Readiness Score (enabled by default)"
1909
+ ).option("--weights <weights>", "Custom scoring weights").option("--threshold <score>", "Fail CI/CD if score below threshold (0-100)").option(
1910
+ "--ci",
1911
+ "CI mode: GitHub Actions annotations, no colors, fail on threshold"
1912
+ ).option(
1913
+ "--fail-on <level>",
1914
+ "Fail on issues: critical, major, any",
1915
+ "critical"
1916
+ ).addHelpText("after", scanHelpText).action(async (directory, options) => {
1437
1917
  await scanAction(directory, options);
1438
1918
  });
1439
- program.command("patterns").description("Detect duplicate code patterns that confuse AI models").argument("[directory]", "Directory to analyze", ".").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--max-candidates <number>", "Maximum candidates per block (performance tuning)").option("--min-shared-tokens <number>", "Minimum shared tokens for candidates (performance tuning)").option("--full-scan", "Disable smart defaults for comprehensive analysis (slower)").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option("--score", "Calculate and display AI Readiness Score for patterns (0-100)").addHelpText("after", patternsHelpText).action(async (directory, options) => {
1919
+ program.command("patterns").description("Detect duplicate code patterns that confuse AI models").argument("[directory]", "Directory to analyze", ".").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option(
1920
+ "--max-candidates <number>",
1921
+ "Maximum candidates per block (performance tuning)"
1922
+ ).option(
1923
+ "--min-shared-tokens <number>",
1924
+ "Minimum shared tokens for candidates (performance tuning)"
1925
+ ).option(
1926
+ "--full-scan",
1927
+ "Disable smart defaults for comprehensive analysis (slower)"
1928
+ ).option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option(
1929
+ "--score",
1930
+ "Calculate and display AI Readiness Score for patterns (0-100)"
1931
+ ).addHelpText("after", patternsHelpText).action(async (directory, options) => {
1440
1932
  await patternsAction(directory, options);
1441
1933
  });
1442
- program.command("context").description("Analyze context window costs and dependency fragmentation").argument("[directory]", "Directory to analyze", ".").option("--max-depth <number>", "Maximum acceptable import depth", "5").option("--max-context <number>", "Maximum acceptable context budget (tokens)", "10000").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option("--score", "Calculate and display AI Readiness Score for context (0-100)").action(async (directory, options) => {
1934
+ program.command("context").description("Analyze context window costs and dependency fragmentation").argument("[directory]", "Directory to analyze", ".").option("--max-depth <number>", "Maximum acceptable import depth", "5").option(
1935
+ "--max-context <number>",
1936
+ "Maximum acceptable context budget (tokens)",
1937
+ "10000"
1938
+ ).option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option(
1939
+ "--score",
1940
+ "Calculate and display AI Readiness Score for context (0-100)"
1941
+ ).action(async (directory, options) => {
1443
1942
  await contextAction(directory, options);
1444
1943
  });
1445
- program.command("consistency").description("Check naming conventions and architectural consistency").argument("[directory]", "Directory to analyze", ".").option("--naming", "Check naming conventions (default: true)").option("--no-naming", "Skip naming analysis").option("--patterns", "Check code patterns (default: true)").option("--no-patterns", "Skip pattern analysis").option("--min-severity <level>", "Minimum severity: info|minor|major|critical", "info").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json, markdown", "console").option("--output-file <path>", "Output file path (for json/markdown)").option("--score", "Calculate and display AI Readiness Score for consistency (0-100)").action(async (directory, options) => {
1944
+ program.command("consistency").description("Check naming conventions and architectural consistency").argument("[directory]", "Directory to analyze", ".").option("--naming", "Check naming conventions (default: true)").option("--no-naming", "Skip naming analysis").option("--patterns", "Check code patterns (default: true)").option("--no-patterns", "Skip pattern analysis").option(
1945
+ "--min-severity <level>",
1946
+ "Minimum severity: info|minor|major|critical",
1947
+ "info"
1948
+ ).option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option(
1949
+ "-o, --output <format>",
1950
+ "Output format: console, json, markdown",
1951
+ "console"
1952
+ ).option("--output-file <path>", "Output file path (for json/markdown)").option(
1953
+ "--score",
1954
+ "Calculate and display AI Readiness Score for consistency (0-100)"
1955
+ ).action(async (directory, options) => {
1446
1956
  await consistencyAction(directory, options);
1447
1957
  });
1448
- program.command("visualise").description("Alias for visualize (British spelling)").argument("[directory]", "Directory to analyze", ".").option("--report <path>", "Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)").option("-o, --output <path>", "Output HTML path (relative to directory)", "packages/visualizer/visualization.html").option("--open", "Open generated HTML in default browser").option("--serve [port]", "Start a local static server to serve the visualization (optional port number)", false).option("--dev", "Start Vite dev server (live reload) for interactive development", true).addHelpText("after", visualiseHelpText).action(async (directory, options) => {
1958
+ program.command("visualise").description("Alias for visualize (British spelling)").argument("[directory]", "Directory to analyze", ".").option(
1959
+ "--report <path>",
1960
+ "Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)"
1961
+ ).option(
1962
+ "-o, --output <path>",
1963
+ "Output HTML path (relative to directory)",
1964
+ "packages/visualizer/visualization.html"
1965
+ ).option("--open", "Open generated HTML in default browser").option(
1966
+ "--serve [port]",
1967
+ "Start a local static server to serve the visualization (optional port number)",
1968
+ false
1969
+ ).option(
1970
+ "--dev",
1971
+ "Start Vite dev server (live reload) for interactive development",
1972
+ true
1973
+ ).addHelpText("after", visualiseHelpText).action(async (directory, options) => {
1449
1974
  await visualizeAction(directory, options);
1450
1975
  });
1451
- program.command("visualize").description("Generate interactive visualization from an AIReady report").argument("[directory]", "Directory to analyze", ".").option("--report <path>", "Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)").option("-o, --output <path>", "Output HTML path (relative to directory)", "packages/visualizer/visualization.html").option("--open", "Open generated HTML in default browser").option("--serve [port]", "Start a local static server to serve the visualization (optional port number)", false).option("--dev", "Start Vite dev server (live reload) for interactive development", false).addHelpText("after", visualizeHelpText).action(async (directory, options) => {
1976
+ program.command("visualize").description("Generate interactive visualization from an AIReady report").argument("[directory]", "Directory to analyze", ".").option(
1977
+ "--report <path>",
1978
+ "Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)"
1979
+ ).option(
1980
+ "-o, --output <path>",
1981
+ "Output HTML path (relative to directory)",
1982
+ "packages/visualizer/visualization.html"
1983
+ ).option("--open", "Open generated HTML in default browser").option(
1984
+ "--serve [port]",
1985
+ "Start a local static server to serve the visualization (optional port number)",
1986
+ false
1987
+ ).option(
1988
+ "--dev",
1989
+ "Start Vite dev server (live reload) for interactive development",
1990
+ false
1991
+ ).addHelpText("after", visualizeHelpText).action(async (directory, options) => {
1452
1992
  await visualizeAction(directory, options);
1453
1993
  });
1454
1994
  program.command("change-amplification").description("Analyze graph metrics for change amplification").argument("[directory]", "Directory to analyze", ".").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {