@aiready/cli 0.9.40 → 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,7 +339,17 @@ 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", "changeAmplification"],
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: {
@@ -321,7 +359,8 @@ async function scanAction(directory, options) {
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,8 +378,12 @@ 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
389
  const cliOverrides = {
@@ -350,20 +393,41 @@ async function scanAction(directory, options) {
350
393
  if (profileTools) {
351
394
  cliOverrides.tools = profileTools;
352
395
  }
353
- const baseOptions = await (0, import_core.loadMergedConfig)(resolvedDir, defaults, cliOverrides);
396
+ const baseOptions = await (0, import_core.loadMergedConfig)(
397
+ resolvedDir,
398
+ defaults,
399
+ cliOverrides
400
+ );
354
401
  let finalOptions = { ...baseOptions };
355
402
  if (baseOptions.tools.includes("patterns")) {
356
403
  const { getSmartDefaults } = await import("@aiready/pattern-detect");
357
- const patternSmartDefaults = await getSmartDefaults(resolvedDir, baseOptions);
358
- finalOptions = { ...patternSmartDefaults, ...finalOptions, ...baseOptions };
404
+ const patternSmartDefaults = await getSmartDefaults(
405
+ resolvedDir,
406
+ baseOptions
407
+ );
408
+ finalOptions = {
409
+ ...patternSmartDefaults,
410
+ ...finalOptions,
411
+ ...baseOptions
412
+ };
359
413
  }
360
414
  console.log(import_chalk2.default.cyan("\n=== AIReady Run Preview ==="));
361
- 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
+ );
362
419
  console.log(import_chalk2.default.white("Will use settings from config and defaults."));
363
420
  console.log(import_chalk2.default.white("\nGeneral settings:"));
364
- if (finalOptions.rootDir) console.log(` rootDir: ${import_chalk2.default.bold(String(finalOptions.rootDir))}`);
365
- if (finalOptions.include) console.log(` include: ${import_chalk2.default.bold(truncateArray(finalOptions.include, 6))}`);
366
- 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
+ );
367
431
  if (finalOptions["pattern-detect"] || finalOptions.minSimilarity) {
368
432
  const patternDetectConfig = finalOptions["pattern-detect"] || {
369
433
  minSimilarity: finalOptions.minSimilarity,
@@ -377,15 +441,40 @@ async function scanAction(directory, options) {
377
441
  includeTests: finalOptions.includeTests
378
442
  };
379
443
  console.log(import_chalk2.default.white("\nPattern-detect settings:"));
380
- console.log(` minSimilarity: ${import_chalk2.default.bold(patternDetectConfig.minSimilarity ?? "default")}`);
381
- console.log(` minLines: ${import_chalk2.default.bold(patternDetectConfig.minLines ?? "default")}`);
382
- if (patternDetectConfig.approx !== void 0) console.log(` approx: ${import_chalk2.default.bold(String(patternDetectConfig.approx))}`);
383
- if (patternDetectConfig.minSharedTokens !== void 0) console.log(` minSharedTokens: ${import_chalk2.default.bold(String(patternDetectConfig.minSharedTokens))}`);
384
- if (patternDetectConfig.maxCandidatesPerBlock !== void 0) console.log(` maxCandidatesPerBlock: ${import_chalk2.default.bold(String(patternDetectConfig.maxCandidatesPerBlock))}`);
385
- if (patternDetectConfig.batchSize !== void 0) console.log(` batchSize: ${import_chalk2.default.bold(String(patternDetectConfig.batchSize))}`);
386
- if (patternDetectConfig.streamResults !== void 0) console.log(` streamResults: ${import_chalk2.default.bold(String(patternDetectConfig.streamResults))}`);
387
- if (patternDetectConfig.severity !== void 0) console.log(` severity: ${import_chalk2.default.bold(String(patternDetectConfig.severity))}`);
388
- 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
+ );
389
478
  }
390
479
  if (finalOptions["context-analyzer"] || finalOptions.maxDepth) {
391
480
  const ca = finalOptions["context-analyzer"] || {
@@ -397,20 +486,42 @@ async function scanAction(directory, options) {
397
486
  };
398
487
  console.log(import_chalk2.default.white("\nContext-analyzer settings:"));
399
488
  console.log(` maxDepth: ${import_chalk2.default.bold(ca.maxDepth ?? "default")}`);
400
- console.log(` maxContextBudget: ${import_chalk2.default.bold(ca.maxContextBudget ?? "default")}`);
401
- if (ca.minCohesion !== void 0) console.log(` minCohesion: ${import_chalk2.default.bold(String(ca.minCohesion))}`);
402
- if (ca.maxFragmentation !== void 0) console.log(` maxFragmentation: ${import_chalk2.default.bold(String(ca.maxFragmentation))}`);
403
- 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
+ );
404
502
  }
405
503
  if (finalOptions.consistency) {
406
504
  const c = finalOptions.consistency;
407
505
  console.log(import_chalk2.default.white("\nConsistency settings:"));
408
- console.log(` checkNaming: ${import_chalk2.default.bold(String(c.checkNaming ?? true))}`);
409
- console.log(` checkPatterns: ${import_chalk2.default.bold(String(c.checkPatterns ?? true))}`);
410
- console.log(` checkArchitecture: ${import_chalk2.default.bold(String(c.checkArchitecture ?? false))}`);
411
- if (c.minSeverity) console.log(` minSeverity: ${import_chalk2.default.bold(c.minSeverity)}`);
412
- if (c.acceptedAbbreviations) console.log(` acceptedAbbreviations: ${import_chalk2.default.bold(truncateArray(c.acceptedAbbreviations, 8))}`);
413
- 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
+ );
414
525
  }
415
526
  console.log(import_chalk2.default.white("\nStarting analysis..."));
416
527
  const progressCallback = (event) => {
@@ -419,40 +530,62 @@ async function scanAction(directory, options) {
419
530
  try {
420
531
  if (event.tool === "patterns") {
421
532
  const pr = event.data;
422
- console.log(` Duplicate patterns: ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))}`);
423
- 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
+ );
424
539
  if (pr.duplicates && pr.duplicates.length > 0) {
425
540
  pr.duplicates.slice(0, 5).forEach((d, i) => {
426
- 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
+ );
427
544
  });
428
545
  }
429
546
  if (pr.results && pr.results.length > 0) {
430
547
  console.log(` Top files with pattern issues:`);
431
- 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
+ );
432
551
  sortedByIssues.slice(0, 5).forEach((r, i) => {
433
- 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
+ );
434
555
  });
435
556
  }
436
557
  if (pr.groups && pr.groups.length >= 0) {
437
- 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
+ );
438
561
  }
439
562
  if (pr.clusters && pr.clusters.length >= 0) {
440
- 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
+ );
441
566
  pr.clusters.slice(0, 3).forEach((cl, idx) => {
442
567
  const files = (cl.files || []).map((f) => f.path.split("/").pop()).join(", ");
443
- console.log(` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`);
568
+ console.log(
569
+ ` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`
570
+ );
444
571
  });
445
572
  }
446
573
  } else if (event.tool === "context") {
447
574
  const cr = event.data;
448
- 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
+ );
449
578
  cr.slice(0, 5).forEach((c, i) => {
450
579
  const msg = c.message ? ` - ${c.message}` : "";
451
- 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
+ );
452
583
  });
453
584
  } else if (event.tool === "consistency") {
454
585
  const rep = event.data;
455
- 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
+ );
456
589
  if (rep.results && rep.results.length > 0) {
457
590
  const fileMap = /* @__PURE__ */ new Map();
458
591
  rep.results.forEach((r) => {
@@ -462,68 +595,126 @@ async function scanAction(directory, options) {
462
595
  fileMap.get(file).push(issue);
463
596
  });
464
597
  });
465
- 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
+ );
466
601
  const topFiles = files.slice(0, 10);
467
602
  topFiles.forEach(([file, issues], idx) => {
468
- const counts = issues.reduce((acc, it) => {
469
- const s = (it.severity || "info").toLowerCase();
470
- acc[s] = (acc[s] || 0) + 1;
471
- return acc;
472
- }, {});
473
- 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];
474
614
  const sampleMsg = sample ? ` \u2014 ${sample.message}` : "";
475
- 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
+ );
476
618
  });
477
619
  const remaining = files.length - topFiles.length;
478
620
  if (remaining > 0) {
479
- 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
+ );
480
626
  }
481
627
  }
482
628
  } else if (event.tool === "doc-drift") {
483
629
  const dr = event.data;
484
- 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
+ );
485
633
  if (dr.rawData) {
486
- console.log(` Signature Mismatches: ${import_chalk2.default.bold(dr.rawData.outdatedComments || 0)}`);
487
- 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
+ );
488
640
  }
489
641
  } else if (event.tool === "deps-health") {
490
642
  const dr = event.data;
491
- 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
+ );
492
646
  if (dr.rawData) {
493
- console.log(` Deprecated Packages: ${import_chalk2.default.bold(dr.rawData.deprecatedPackages || 0)}`);
494
- 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
+ );
495
653
  }
496
654
  } else if (event.tool === "change-amplification" || event.tool === "changeAmplification") {
497
655
  const dr = event.data;
498
- console.log(` Coupling issues: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`);
656
+ console.log(
657
+ ` Coupling issues: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`
658
+ );
499
659
  if (dr.summary) {
500
- console.log(` Complexity Score: ${import_chalk2.default.bold(dr.summary.score || 0)}/100`);
660
+ console.log(
661
+ ` Complexity Score: ${import_chalk2.default.bold(dr.summary.score || 0)}/100`
662
+ );
501
663
  }
502
664
  }
503
665
  } catch (err) {
666
+ void err;
504
667
  }
505
668
  };
506
- const results = await analyzeUnified({ ...finalOptions, progressCallback, suppressToolConfig: true });
669
+ const results = await analyzeUnified({
670
+ ...finalOptions,
671
+ progressCallback,
672
+ suppressToolConfig: true
673
+ });
507
674
  console.log(import_chalk2.default.cyan("\n=== AIReady Run Summary ==="));
508
- 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
+ );
509
679
  console.log(import_chalk2.default.cyan("\nResults summary:"));
510
- console.log(` Total issues (all tools): ${import_chalk2.default.bold(String(results.summary.totalIssues || 0))}`);
511
- if (results.duplicates) console.log(` Duplicate patterns found: ${import_chalk2.default.bold(String(results.duplicates.length || 0))}`);
512
- if (results.patterns) console.log(` Pattern files with issues: ${import_chalk2.default.bold(String(results.patterns.length || 0))}`);
513
- if (results.context) console.log(` Context issues: ${import_chalk2.default.bold(String(results.context.length || 0))}`);
514
- console.log(` Consistency issues: ${import_chalk2.default.bold(String(results.consistency?.summary?.totalIssues || 0))}`);
515
- if (results.changeAmplification) console.log(` Change amplification: ${import_chalk2.default.bold(String(results.changeAmplification.summary?.score || 0))}/100`);
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
+ );
516
702
  console.log(import_chalk2.default.cyan("===========================\n"));
517
703
  const elapsedTime = (0, import_core.getElapsedTime)(startTime);
704
+ void elapsedTime;
518
705
  let scoringResult;
519
706
  if (options.score || finalOptions.scoring?.showBreakdown) {
520
707
  const toolScores = /* @__PURE__ */ new Map();
521
708
  if (results.duplicates) {
522
709
  const { calculatePatternScore } = await import("@aiready/pattern-detect");
523
710
  try {
524
- const patternScore = calculatePatternScore(results.duplicates, results.patterns?.length || 0);
711
+ const patternScore = calculatePatternScore(
712
+ results.duplicates,
713
+ results.patterns?.length || 0
714
+ );
525
715
  toolScores.set("pattern-detect", patternScore);
526
716
  } catch (err) {
717
+ void err;
527
718
  }
528
719
  }
529
720
  if (results.context) {
@@ -533,6 +724,7 @@ async function scanAction(directory, options) {
533
724
  const contextScore = calculateContextScore(ctxSummary);
534
725
  toolScores.set("context-analyzer", contextScore);
535
726
  } catch (err) {
727
+ void err;
536
728
  }
537
729
  }
538
730
  if (results.consistency) {
@@ -540,17 +732,24 @@ async function scanAction(directory, options) {
540
732
  try {
541
733
  const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
542
734
  const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
543
- const consistencyScore = calculateConsistencyScore(issues, totalFiles);
735
+ const consistencyScore = calculateConsistencyScore(
736
+ issues,
737
+ totalFiles
738
+ );
544
739
  toolScores.set("consistency", consistencyScore);
545
740
  } catch (err) {
741
+ void err;
546
742
  }
547
743
  }
548
744
  if (results.aiSignalClarity) {
549
745
  const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
550
746
  try {
551
- const hrScore = calculateAiSignalClarityScore(results.aiSignalClarity);
747
+ const hrScore = calculateAiSignalClarityScore(
748
+ results.aiSignalClarity
749
+ );
552
750
  toolScores.set("ai-signal-clarity", hrScore);
553
751
  } catch (err) {
752
+ void err;
554
753
  }
555
754
  }
556
755
  if (results.grounding) {
@@ -559,6 +758,7 @@ async function scanAction(directory, options) {
559
758
  const agScore = calculateGroundingScore(results.grounding);
560
759
  toolScores.set("agent-grounding", agScore);
561
760
  } catch (err) {
761
+ void err;
562
762
  }
563
763
  }
564
764
  if (results.testability) {
@@ -567,6 +767,7 @@ async function scanAction(directory, options) {
567
767
  const tbScore = calculateTestabilityScore(results.testability);
568
768
  toolScores.set("testability", tbScore);
569
769
  } catch (err) {
770
+ void err;
570
771
  }
571
772
  }
572
773
  if (results.docDrift) {
@@ -575,7 +776,13 @@ async function scanAction(directory, options) {
575
776
  score: results.docDrift.summary.score,
576
777
  rawMetrics: results.docDrift.rawData,
577
778
  factors: [],
578
- 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
+ )
579
786
  });
580
787
  }
581
788
  if (results.deps) {
@@ -584,7 +791,13 @@ async function scanAction(directory, options) {
584
791
  score: results.deps.summary.score,
585
792
  rawMetrics: results.deps.rawData,
586
793
  factors: [],
587
- 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
+ )
588
801
  });
589
802
  }
590
803
  if (results.changeAmplification) {
@@ -593,17 +806,28 @@ async function scanAction(directory, options) {
593
806
  score: results.changeAmplification.summary.score,
594
807
  rawMetrics: results.changeAmplification.rawData,
595
808
  factors: [],
596
- recommendations: (results.changeAmplification.recommendations || []).map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
809
+ recommendations: (results.changeAmplification.recommendations || []).map((action) => ({
810
+ action,
811
+ estimatedImpact: 5,
812
+ priority: "medium"
813
+ }))
597
814
  });
598
815
  }
599
816
  const cliWeights = (0, import_core.parseWeightString)(options.weights);
600
817
  if (toolScores.size > 0) {
601
- 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
+ );
602
823
  console.log(import_chalk2.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
603
824
  console.log(` ${(0, import_core.formatScore)(scoringResult)}`);
604
825
  if (options.compareTo) {
605
826
  try {
606
- 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
+ );
607
831
  const prevReport = JSON.parse(prevReportStr);
608
832
  const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
609
833
  if (typeof prevScore === "number") {
@@ -611,23 +835,44 @@ async function scanAction(directory, options) {
611
835
  const diffStr = diff > 0 ? `+${diff}` : String(diff);
612
836
  console.log();
613
837
  if (diff > 0) {
614
- 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
+ );
615
843
  } else if (diff < 0) {
616
- 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
+ );
617
849
  } else {
618
- 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
+ );
619
855
  }
620
856
  scoringResult.trend = {
621
857
  previousScore: prevScore,
622
858
  difference: diff
623
859
  };
624
860
  } else {
625
- console.log(import_chalk2.default.yellow(`
626
- \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
+ );
627
867
  }
628
868
  } catch (e) {
629
- console.log(import_chalk2.default.yellow(`
630
- \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
+ );
631
876
  }
632
877
  }
633
878
  if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
@@ -635,7 +880,9 @@ async function scanAction(directory, options) {
635
880
  scoringResult.breakdown.forEach((tool) => {
636
881
  const rating = (0, import_core.getRating)(tool.score);
637
882
  const rd = (0, import_core.getRatingDisplay)(rating);
638
- console.log(` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`);
883
+ console.log(
884
+ ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
885
+ );
639
886
  });
640
887
  console.log();
641
888
  if (finalOptions.scoring?.showBreakdown) {
@@ -653,20 +900,33 @@ async function scanAction(directory, options) {
653
900
  if (outputFormat === "json") {
654
901
  const timestamp = getReportTimestamp();
655
902
  const defaultFilename = `aiready-report-${timestamp}.json`;
656
- const outputPath = (0, import_core.resolveOutputPath)(userOutputFile, defaultFilename, resolvedDir);
903
+ const outputPath = (0, import_core.resolveOutputPath)(
904
+ userOutputFile,
905
+ defaultFilename,
906
+ resolvedDir
907
+ );
657
908
  const outputData = { ...results, scoring: scoringResult };
658
- (0, import_core.handleJSONOutput)(outputData, outputPath, `\u2705 Report saved to ${outputPath}`);
659
- warnIfGraphCapExceeded(outputData, resolvedDir);
909
+ (0, import_core.handleJSONOutput)(
910
+ outputData,
911
+ outputPath,
912
+ `\u2705 Report saved to ${outputPath}`
913
+ );
914
+ await warnIfGraphCapExceeded(outputData, resolvedDir);
660
915
  } else {
661
916
  const timestamp = getReportTimestamp();
662
917
  const defaultFilename = `aiready-report-${timestamp}.json`;
663
- const outputPath = (0, import_core.resolveOutputPath)(userOutputFile, defaultFilename, resolvedDir);
918
+ const outputPath = (0, import_core.resolveOutputPath)(
919
+ userOutputFile,
920
+ defaultFilename,
921
+ resolvedDir
922
+ );
664
923
  const outputData = { ...results, scoring: scoringResult };
665
924
  try {
666
925
  (0, import_fs2.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
667
926
  console.log(import_chalk2.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
668
- warnIfGraphCapExceeded(outputData, resolvedDir);
927
+ await warnIfGraphCapExceeded(outputData, resolvedDir);
669
928
  } catch (err) {
929
+ void err;
670
930
  }
671
931
  }
672
932
  const isCI = options.ci || process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
@@ -684,16 +944,22 @@ async function scanAction(directory, options) {
684
944
  }
685
945
  console.log("::endgroup::");
686
946
  if (threshold && scoringResult.overall < threshold) {
687
- 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
+ );
688
950
  } else if (threshold) {
689
- 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
+ );
690
954
  }
691
955
  if (results.patterns) {
692
956
  const criticalPatterns = results.patterns.flatMap(
693
957
  (p) => p.issues.filter((i) => i.severity === "critical")
694
958
  );
695
959
  criticalPatterns.slice(0, 10).forEach((issue) => {
696
- 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
+ );
697
963
  });
698
964
  }
699
965
  }
@@ -742,16 +1008,30 @@ async function scanAction(directory, options) {
742
1008
  console.log(import_chalk2.default.red("\n\u{1F6AB} PR BLOCKED: AI Readiness Check Failed"));
743
1009
  console.log(import_chalk2.default.red(` Reason: ${failReason}`));
744
1010
  console.log(import_chalk2.default.dim("\n Remediation steps:"));
745
- 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
+ );
746
1014
  console.log(import_chalk2.default.dim(" 2. Fix the critical issues before merging"));
747
- 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
+ );
748
1020
  process.exit(1);
749
1021
  } else {
750
1022
  console.log(import_chalk2.default.green("\n\u2705 PR PASSED: AI Readiness Check"));
751
1023
  if (threshold) {
752
- 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
+ );
753
1029
  }
754
- 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
+ );
755
1035
  }
756
1036
  }
757
1037
  } catch (error) {
@@ -823,7 +1103,11 @@ async function patternsAction(directory, options) {
823
1103
  if (options.minSharedTokens) {
824
1104
  cliOptions.minSharedTokens = parseInt(options.minSharedTokens);
825
1105
  }
826
- 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
+ );
827
1111
  const { analyzePatterns: analyzePatterns2, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
828
1112
  const { results, duplicates } = await analyzePatterns2(finalOptions);
829
1113
  const elapsedTime = (0, import_core2.getElapsedTime)(startTime);
@@ -845,7 +1129,11 @@ async function patternsAction(directory, options) {
845
1129
  `aiready-report-${getReportTimestamp()}.json`,
846
1130
  resolvedDir
847
1131
  );
848
- (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
+ );
849
1137
  } else {
850
1138
  const terminalWidth = process.stdout.columns || 80;
851
1139
  const dividerWidth = Math.min(60, terminalWidth - 2);
@@ -853,10 +1141,22 @@ async function patternsAction(directory, options) {
853
1141
  console.log(import_chalk3.default.cyan(divider));
854
1142
  console.log(import_chalk3.default.bold.white(" PATTERN ANALYSIS SUMMARY"));
855
1143
  console.log(import_chalk3.default.cyan(divider) + "\n");
856
- console.log(import_chalk3.default.white(`\u{1F4C1} Files analyzed: ${import_chalk3.default.bold(results.length)}`));
857
- console.log(import_chalk3.default.yellow(`\u26A0 Duplicate patterns found: ${import_chalk3.default.bold(summary.totalPatterns)}`));
858
- console.log(import_chalk3.default.red(`\u{1F4B0} Token cost (wasted): ${import_chalk3.default.bold(summary.totalTokenCost.toLocaleString())}`));
859
- 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
+ );
860
1160
  const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
861
1161
  if (sortedTypes.length > 0) {
862
1162
  console.log(import_chalk3.default.cyan("\n" + divider));
@@ -876,13 +1176,21 @@ async function patternsAction(directory, options) {
876
1176
  const severityIcon = dup.similarity > 0.95 ? "\u{1F534}" : dup.similarity > 0.9 ? "\u{1F7E1}" : "\u{1F535}";
877
1177
  const file1Name = dup.file1.split("/").pop() || dup.file1;
878
1178
  const file2Name = dup.file2.split("/").pop() || dup.file2;
879
- console.log(`${severityIcon} ${severity}: ${import_chalk3.default.bold(file1Name)} \u2194 ${import_chalk3.default.bold(file2Name)}`);
880
- console.log(` Similarity: ${import_chalk3.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk3.default.bold(dup.tokenCost.toLocaleString())} tokens each`);
881
- console.log(` Lines: ${import_chalk3.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk3.default.cyan(dup.line2 + "-" + dup.endLine2)}
882
- `);
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
+ );
883
1189
  });
884
1190
  } else {
885
- 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
+ );
886
1194
  }
887
1195
  if (patternScore) {
888
1196
  console.log(import_chalk3.default.cyan(divider));
@@ -922,7 +1230,7 @@ async function contextAction(directory, options) {
922
1230
  file: void 0
923
1231
  }
924
1232
  };
925
- let baseOptions = await (0, import_core3.loadMergedConfig)(resolvedDir, defaults, {
1233
+ const baseOptions = await (0, import_core3.loadMergedConfig)(resolvedDir, defaults, {
926
1234
  maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
927
1235
  maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
928
1236
  include: options.include?.split(","),
@@ -930,13 +1238,20 @@ async function contextAction(directory, options) {
930
1238
  });
931
1239
  let finalOptions = { ...baseOptions };
932
1240
  const { getSmartDefaults } = await import("@aiready/context-analyzer");
933
- const contextSmartDefaults = await getSmartDefaults(resolvedDir, baseOptions);
1241
+ const contextSmartDefaults = await getSmartDefaults(
1242
+ resolvedDir,
1243
+ baseOptions
1244
+ );
934
1245
  finalOptions = { ...contextSmartDefaults, ...finalOptions };
935
1246
  console.log("\u{1F4CB} Configuration:");
936
1247
  console.log(` Max depth: ${finalOptions.maxDepth}`);
937
1248
  console.log(` Max context budget: ${finalOptions.maxContextBudget}`);
938
- console.log(` Min cohesion: ${(finalOptions.minCohesion * 100).toFixed(1)}%`);
939
- 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
+ );
940
1255
  console.log(` Analysis focus: ${finalOptions.focus}`);
941
1256
  console.log("");
942
1257
  const { analyzeContext: analyzeContext2, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
@@ -960,7 +1275,11 @@ async function contextAction(directory, options) {
960
1275
  `aiready-report-${getReportTimestamp()}.json`,
961
1276
  resolvedDir
962
1277
  );
963
- (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
+ );
964
1283
  } else {
965
1284
  const terminalWidth = process.stdout.columns || 80;
966
1285
  const dividerWidth = Math.min(60, terminalWidth - 2);
@@ -968,59 +1287,103 @@ async function contextAction(directory, options) {
968
1287
  console.log(import_chalk4.default.cyan(divider));
969
1288
  console.log(import_chalk4.default.bold.white(" CONTEXT ANALYSIS SUMMARY"));
970
1289
  console.log(import_chalk4.default.cyan(divider) + "\n");
971
- console.log(import_chalk4.default.white(`\u{1F4C1} Files analyzed: ${import_chalk4.default.bold(summary.totalFiles)}`));
972
- console.log(import_chalk4.default.white(`\u{1F4CA} Total tokens: ${import_chalk4.default.bold(summary.totalTokens.toLocaleString())}`));
973
- console.log(import_chalk4.default.yellow(`\u{1F4B0} Avg context budget: ${import_chalk4.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`));
974
- console.log(import_chalk4.default.white(`\u23F1 Analysis time: ${import_chalk4.default.bold(elapsedTime + "s")}
975
- `));
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
+ );
976
1307
  const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
977
1308
  if (totalIssues > 0) {
978
1309
  console.log(import_chalk4.default.bold("\u26A0\uFE0F Issues Found:\n"));
979
1310
  if (summary.criticalIssues > 0) {
980
- 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
+ );
981
1314
  }
982
1315
  if (summary.majorIssues > 0) {
983
- 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
+ );
984
1319
  }
985
1320
  if (summary.minorIssues > 0) {
986
- 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
+ );
987
1324
  }
988
- console.log(import_chalk4.default.green(`
1325
+ console.log(
1326
+ import_chalk4.default.green(
1327
+ `
989
1328
  \u{1F4A1} Potential savings: ${import_chalk4.default.bold(summary.totalPotentialSavings.toLocaleString())} tokens
990
- `));
1329
+ `
1330
+ )
1331
+ );
991
1332
  } else {
992
1333
  console.log(import_chalk4.default.green("\u2705 No significant issues found!\n"));
993
1334
  }
994
1335
  if (summary.deepFiles.length > 0) {
995
1336
  console.log(import_chalk4.default.bold("\u{1F4CF} Deep Import Chains:\n"));
996
- console.log(import_chalk4.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`));
997
- console.log(import_chalk4.default.gray(` Maximum depth: ${summary.maxImportDepth}
998
- `));
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
+ );
999
1344
  summary.deepFiles.slice(0, 10).forEach((item) => {
1000
1345
  const fileName = item.file.split("/").slice(-2).join("/");
1001
- 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
+ );
1002
1349
  });
1003
1350
  console.log();
1004
1351
  }
1005
1352
  if (summary.fragmentedModules.length > 0) {
1006
1353
  console.log(import_chalk4.default.bold("\u{1F9E9} Fragmented Modules:\n"));
1007
- console.log(import_chalk4.default.gray(` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
1008
- `));
1354
+ console.log(
1355
+ import_chalk4.default.gray(
1356
+ ` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
1357
+ `
1358
+ )
1359
+ );
1009
1360
  summary.fragmentedModules.slice(0, 10).forEach((module2) => {
1010
- 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`)}`);
1011
- 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
+ );
1012
1369
  });
1013
1370
  console.log();
1014
1371
  }
1015
1372
  if (summary.lowCohesionFiles.length > 0) {
1016
1373
  console.log(import_chalk4.default.bold("\u{1F500} Low Cohesion Files:\n"));
1017
- console.log(import_chalk4.default.gray(` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
1018
- `));
1374
+ console.log(
1375
+ import_chalk4.default.gray(
1376
+ ` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
1377
+ `
1378
+ )
1379
+ );
1019
1380
  summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
1020
1381
  const fileName = item.file.split("/").slice(-2).join("/");
1021
1382
  const scorePercent = (item.score * 100).toFixed(0);
1022
1383
  const color = item.score < 0.4 ? import_chalk4.default.red : import_chalk4.default.yellow;
1023
- 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
+ );
1024
1387
  });
1025
1388
  console.log();
1026
1389
  }
@@ -1029,7 +1392,9 @@ async function contextAction(directory, options) {
1029
1392
  summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
1030
1393
  const fileName = item.file.split("/").slice(-2).join("/");
1031
1394
  const severityColor = item.severity === "critical" ? import_chalk4.default.red : item.severity === "major" ? import_chalk4.default.yellow : import_chalk4.default.blue;
1032
- 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
+ );
1033
1398
  });
1034
1399
  console.log();
1035
1400
  }
@@ -1080,7 +1445,10 @@ async function consistencyAction(directory, options) {
1080
1445
  let consistencyScore;
1081
1446
  if (options.score) {
1082
1447
  const issues = report.results?.flatMap((r) => r.issues) || [];
1083
- consistencyScore = calculateConsistencyScore(issues, report.summary.filesAnalyzed);
1448
+ consistencyScore = calculateConsistencyScore(
1449
+ issues,
1450
+ report.summary.filesAnalyzed
1451
+ );
1084
1452
  }
1085
1453
  const outputFormat = options.output || finalOptions.output?.format || "console";
1086
1454
  const userOutputFile = options.outputFile || finalOptions.output?.file;
@@ -1098,7 +1466,11 @@ async function consistencyAction(directory, options) {
1098
1466
  `aiready-report-${getReportTimestamp()}.json`,
1099
1467
  resolvedDir
1100
1468
  );
1101
- (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
+ );
1102
1474
  } else if (outputFormat === "markdown") {
1103
1475
  const markdown = generateMarkdownReport(report, elapsedTime);
1104
1476
  const outputPath = (0, import_core4.resolveOutputPath)(
@@ -1110,15 +1482,23 @@ async function consistencyAction(directory, options) {
1110
1482
  console.log(import_chalk5.default.green(`\u2705 Report saved to ${outputPath}`));
1111
1483
  } else {
1112
1484
  console.log(import_chalk5.default.bold("\n\u{1F4CA} Summary\n"));
1113
- 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
+ );
1114
1488
  console.log(`Total Issues: ${import_chalk5.default.yellow(report.summary.totalIssues)}`);
1115
1489
  console.log(` Naming: ${import_chalk5.default.yellow(report.summary.namingIssues)}`);
1116
1490
  console.log(` Patterns: ${import_chalk5.default.yellow(report.summary.patternIssues)}`);
1117
- 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
+ );
1118
1494
  console.log(`Analysis Time: ${import_chalk5.default.gray(elapsedTime + "s")}
1119
1495
  `);
1120
1496
  if (report.summary.totalIssues === 0) {
1121
- 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
+ );
1122
1502
  } else {
1123
1503
  const namingResults = report.results.filter(
1124
1504
  (r) => r.issues.some((i) => i.category === "naming")
@@ -1134,10 +1514,14 @@ async function consistencyAction(directory, options) {
1134
1514
  for (const issue of result.issues) {
1135
1515
  if (shown >= 5) break;
1136
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;
1137
- 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
+ );
1138
1520
  console.log(` ${issue.message}`);
1139
1521
  if (issue.suggestion) {
1140
- 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
+ );
1141
1525
  }
1142
1526
  console.log();
1143
1527
  shown++;
@@ -1157,10 +1541,14 @@ async function consistencyAction(directory, options) {
1157
1541
  for (const issue of result.issues) {
1158
1542
  if (shown >= 5) break;
1159
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;
1160
- 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
+ );
1161
1547
  console.log(` ${issue.message}`);
1162
1548
  if (issue.suggestion) {
1163
- 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
+ );
1164
1552
  }
1165
1553
  console.log();
1166
1554
  shown++;
@@ -1206,15 +1594,21 @@ async function visualizeAction(directory, options) {
1206
1594
  const latestScan = findLatestScanReport(dirPath);
1207
1595
  if (latestScan) {
1208
1596
  reportPath = latestScan;
1209
- 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
+ );
1210
1600
  } else {
1211
1601
  console.error(import_chalk6.default.red("\u274C No AI readiness report found"));
1212
- console.log(import_chalk6.default.dim(`
1602
+ console.log(
1603
+ import_chalk6.default.dim(
1604
+ `
1213
1605
  Generate a report with:
1214
1606
  aiready scan --output json
1215
1607
 
1216
1608
  Or specify a custom report:
1217
- aiready visualise --report <path-to-report.json>`));
1609
+ aiready visualise --report <path-to-report.json>`
1610
+ )
1611
+ );
1218
1612
  return;
1219
1613
  }
1220
1614
  }
@@ -1232,6 +1626,7 @@ Or specify a custom report:
1232
1626
  };
1233
1627
  }
1234
1628
  } catch (e) {
1629
+ void e;
1235
1630
  }
1236
1631
  }
1237
1632
  const envVisualizerConfig = JSON.stringify(graphConfig);
@@ -1252,11 +1647,18 @@ Or specify a custom report:
1252
1647
  } else {
1253
1648
  const nodemodulesLocations = [
1254
1649
  (0, import_path6.resolve)(dirPath, "node_modules", "@aiready", "visualizer"),
1255
- (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
+ )
1256
1656
  ];
1257
1657
  let currentDir = dirPath;
1258
1658
  while (currentDir !== "/" && currentDir !== ".") {
1259
- 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
+ );
1260
1662
  const parent = (0, import_path6.resolve)(currentDir, "..");
1261
1663
  if (parent === currentDir) break;
1262
1664
  currentDir = parent;
@@ -1273,7 +1675,8 @@ Or specify a custom report:
1273
1675
  const vizPkgPath = require.resolve("@aiready/visualizer/package.json");
1274
1676
  webDir = (0, import_path6.resolve)(vizPkgPath, "..");
1275
1677
  visualizerAvailable = true;
1276
- } catch (e) {
1678
+ } catch (err) {
1679
+ void err;
1277
1680
  }
1278
1681
  }
1279
1682
  }
@@ -1301,30 +1704,46 @@ Or specify a custom report:
1301
1704
  AIREADY_REPORT_PATH: reportPath,
1302
1705
  AIREADY_VISUALIZER_CONFIG: envVisualizerConfig
1303
1706
  };
1304
- 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
+ });
1305
1713
  const onExit = () => {
1306
1714
  try {
1307
1715
  reportWatcher.close();
1308
- } catch (e) {
1716
+ } catch (err) {
1717
+ void err;
1309
1718
  }
1310
1719
  try {
1311
1720
  vite.kill();
1312
- } catch (e) {
1721
+ } catch (err) {
1722
+ void err;
1313
1723
  }
1314
1724
  process.exit(0);
1315
1725
  };
1316
1726
  process.on("SIGINT", onExit);
1317
1727
  process.on("SIGTERM", onExit);
1318
1728
  devServerStarted = true;
1729
+ void devServerStarted;
1319
1730
  return;
1320
1731
  } else {
1321
- console.log(import_chalk6.default.yellow("\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."));
1322
- 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
+ );
1323
1740
  useDevMode = false;
1324
1741
  }
1325
1742
  } catch (err) {
1326
1743
  console.error("Failed to start dev server:", err);
1327
- 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
+ );
1328
1747
  useDevMode = false;
1329
1748
  }
1330
1749
  }
@@ -1346,20 +1765,25 @@ Or specify a custom report:
1346
1765
  const urlPath = req.url || "/";
1347
1766
  if (urlPath === "/" || urlPath === "/index.html") {
1348
1767
  const content = await fsp.readFile(outPath, "utf8");
1349
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1768
+ res.writeHead(200, {
1769
+ "Content-Type": "text/html; charset=utf-8"
1770
+ });
1350
1771
  res.end(content);
1351
1772
  return;
1352
1773
  }
1353
1774
  res.writeHead(404, { "Content-Type": "text/plain" });
1354
1775
  res.end("Not found");
1355
1776
  } catch (e) {
1777
+ void e;
1356
1778
  res.writeHead(500, { "Content-Type": "text/plain" });
1357
1779
  res.end("Server error");
1358
1780
  }
1359
1781
  });
1360
1782
  server.listen(port, () => {
1361
1783
  const addr = `http://localhost:${port}/`;
1362
- 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
+ );
1363
1787
  (0, import_child_process.spawn)(opener, [`"${addr}"`], { shell: true });
1364
1788
  });
1365
1789
  process.on("SIGINT", () => {
@@ -1425,9 +1849,13 @@ var getDirname = () => {
1425
1849
  if (typeof __dirname !== "undefined") return __dirname;
1426
1850
  return (0, import_path7.dirname)((0, import_url.fileURLToPath)(import_meta.url));
1427
1851
  };
1428
- 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
+ );
1429
1855
  var program = new import_commander.Command();
1430
- 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
+ `
1431
1859
  AI READINESS SCORING:
1432
1860
  Get a 0-100 score indicating how AI-ready your codebase is.
1433
1861
  Use --score flag with any analysis command for detailed breakdown.
@@ -1462,23 +1890,105 @@ CONFIGURATION:
1462
1890
  VERSION: ${packageJson.version}
1463
1891
  DOCUMENTATION: https://aiready.dev/docs/cli
1464
1892
  GITHUB: https://github.com/caopengau/aiready-cli
1465
- LANDING: https://github.com/caopengau/aiready-landing`);
1466
- 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", "console").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) => {
1467
1917
  await scanAction(directory, options);
1468
1918
  });
1469
- 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) => {
1470
1932
  await patternsAction(directory, options);
1471
1933
  });
1472
- 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) => {
1473
1942
  await contextAction(directory, options);
1474
1943
  });
1475
- 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) => {
1476
1956
  await consistencyAction(directory, options);
1477
1957
  });
1478
- 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) => {
1479
1974
  await visualizeAction(directory, options);
1480
1975
  });
1481
- 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) => {
1482
1992
  await visualizeAction(directory, options);
1483
1993
  });
1484
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) => {