@aiready/cli 0.14.2 → 0.14.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.aiready/aiready-report-20260314-164626.json +2 -5
  2. package/.aiready/aiready-report-20260314-164741.json +2 -5
  3. package/.turbo/turbo-build.log +29 -28
  4. package/.turbo/turbo-lint.log +0 -32
  5. package/.turbo/turbo-test.log +35 -125
  6. package/aiready-report.json +30703 -0
  7. package/dist/cli.js +415 -378
  8. package/dist/cli.mjs +358 -320
  9. package/package.json +12 -12
  10. package/packages/core/src/.aiready/aiready-report-20260314-161145.json +4 -10
  11. package/packages/core/src/.aiready/aiready-report-20260314-161152.json +10 -28
  12. package/packages/pattern-detect/src/.aiready/aiready-report-20260314-161139.json +4 -10
  13. package/src/.aiready/aiready-report-20260312-103623.json +3 -9
  14. package/src/.aiready/aiready-report-20260312-110843.json +3 -9
  15. package/src/.aiready/aiready-report-20260312-110955.json +3 -9
  16. package/src/.aiready/aiready-report-20260314-203209.json +3 -9
  17. package/src/.aiready/aiready-report-20260314-203736.json +3 -9
  18. package/src/.aiready/aiready-report-20260314-203857.json +3 -9
  19. package/src/.aiready/aiready-report-20260314-204047.json +3 -9
  20. package/src/__tests__/cli.test.ts +1 -1
  21. package/src/__tests__/config-shape.test.ts +0 -1
  22. package/src/__tests__/unified.test.ts +1 -1
  23. package/src/cli.ts +2 -1
  24. package/src/commands/__tests__/consistency.test.ts +3 -0
  25. package/src/commands/__tests__/extra-commands.test.ts +29 -38
  26. package/src/commands/__tests__/init.test.ts +56 -0
  27. package/src/commands/__tests__/scan.test.ts +4 -2
  28. package/src/commands/__tests__/upload.test.ts +0 -1
  29. package/src/commands/__tests__/visualize.test.ts +3 -7
  30. package/src/commands/ai-signal-clarity.ts +1 -56
  31. package/src/commands/bug.ts +1 -2
  32. package/src/commands/deps-health.ts +1 -65
  33. package/src/commands/doc-drift.ts +1 -62
  34. package/src/commands/init.ts +58 -2
  35. package/src/commands/patterns.ts +3 -1
  36. package/src/commands/report-formatter.ts +128 -0
  37. package/src/commands/scan.ts +29 -120
  38. package/src/commands/shared/configured-tool-action.ts +35 -0
  39. package/src/commands/shared/standard-tool-actions.ts +126 -0
  40. package/src/commands/upload.ts +15 -13
  41. package/src/commands/visualize.ts +11 -4
  42. package/src/index.ts +18 -3
  43. package/src/utils/helpers.ts +86 -37
  44. package/vitest.config.ts +5 -12
package/dist/cli.js CHANGED
@@ -30,10 +30,10 @@ var import_path9 = require("path");
30
30
  var import_url = require("url");
31
31
 
32
32
  // src/commands/scan.ts
33
- var import_chalk3 = __toESM(require("chalk"));
33
+ var import_chalk4 = __toESM(require("chalk"));
34
34
  var import_fs3 = require("fs");
35
35
  var import_path3 = require("path");
36
- var import_core3 = require("@aiready/core");
36
+ var import_core6 = require("@aiready/core");
37
37
 
38
38
  // src/index.ts
39
39
  var import_core = require("@aiready/core");
@@ -294,34 +294,13 @@ async function scoreUnified(results, options) {
294
294
  var import_path = require("path");
295
295
  var import_fs = require("fs");
296
296
  var import_chalk = __toESM(require("chalk"));
297
+ var import_core2 = require("@aiready/core");
298
+ var import_core3 = require("@aiready/core");
297
299
  function getReportTimestamp() {
298
300
  const now = /* @__PURE__ */ new Date();
299
301
  const pad = (n) => String(n).padStart(2, "0");
300
302
  return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
301
303
  }
302
- function findLatestScanReport(dirPath) {
303
- const aireadyDir = (0, import_path.resolve)(dirPath, ".aiready");
304
- if (!(0, import_fs.existsSync)(aireadyDir)) {
305
- return null;
306
- }
307
- let files = (0, import_fs.readdirSync)(aireadyDir).filter(
308
- (f) => f.startsWith("aiready-report-") && f.endsWith(".json")
309
- );
310
- if (files.length === 0) {
311
- files = (0, import_fs.readdirSync)(aireadyDir).filter(
312
- (f) => f.startsWith("aiready-scan-") && f.endsWith(".json")
313
- );
314
- }
315
- if (files.length === 0) {
316
- return null;
317
- }
318
- const sortedFiles = files.map((f) => ({
319
- name: f,
320
- path: (0, import_path.resolve)(aireadyDir, f),
321
- mtime: (0, import_fs.statSync)((0, import_path.resolve)(aireadyDir, f)).mtime
322
- })).sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
323
- return sortedFiles[0].path;
324
- }
325
304
  async function warnIfGraphCapExceeded(report, dirPath) {
326
305
  try {
327
306
  const { loadConfig: loadConfig4 } = await import("@aiready/core");
@@ -408,42 +387,129 @@ function generateMarkdownReport(report, elapsedTime) {
408
387
  return markdown;
409
388
  }
410
389
 
390
+ // src/commands/report-formatter.ts
391
+ var import_chalk2 = __toESM(require("chalk"));
392
+ var import_core4 = require("@aiready/core");
393
+ function printScanSummary(results, startTime) {
394
+ console.log(import_chalk2.default.cyan("\n=== AIReady Run Summary ==="));
395
+ console.log(
396
+ ` Total issues (all tools): ${import_chalk2.default.bold(String(results.summary.totalIssues || 0))}`
397
+ );
398
+ console.log(
399
+ ` Execution time: ${import_chalk2.default.bold(((Date.now() - startTime) / 1e3).toFixed(2) + "s")}`
400
+ );
401
+ }
402
+ function printBusinessImpact(roi, unifiedBudget) {
403
+ console.log(import_chalk2.default.bold("\n\u{1F4B0} Business Impact Analysis (Monthly)"));
404
+ console.log(
405
+ ` Potential Savings: ${import_chalk2.default.green(import_chalk2.default.bold("$" + roi.monthlySavings.toLocaleString()))}`
406
+ );
407
+ console.log(
408
+ ` Productivity Gain: ${import_chalk2.default.cyan(import_chalk2.default.bold(roi.productivityGainHours + "h"))} (est. dev time)`
409
+ );
410
+ console.log(
411
+ ` Context Efficiency: ${import_chalk2.default.yellow((unifiedBudget.efficiencyRatio * 100).toFixed(0) + "%")}`
412
+ );
413
+ console.log(
414
+ ` Annual Value: ${import_chalk2.default.bold("$" + roi.annualValue.toLocaleString())} (ROI Prediction)`
415
+ );
416
+ }
417
+ function printScoring(scoringResult, scoringProfile) {
418
+ console.log(import_chalk2.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
419
+ console.log(` ${(0, import_core4.formatScore)(scoringResult)}`);
420
+ console.log(import_chalk2.default.dim(` (Scoring Profile: ${scoringProfile})`));
421
+ if (scoringResult.breakdown) {
422
+ console.log(import_chalk2.default.bold("\nTool breakdown:"));
423
+ scoringResult.breakdown.forEach((tool) => {
424
+ const rating = (0, import_core4.getRating)(tool.score);
425
+ const emoji = (0, import_core4.getRatingDisplay)(rating).emoji;
426
+ console.log(
427
+ ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${emoji}`
428
+ );
429
+ });
430
+ const allRecs = scoringResult.breakdown.flatMap(
431
+ (t) => (t.recommendations || []).map((r) => ({ ...r, tool: t.toolName }))
432
+ ).sort((a, b) => b.estimatedImpact - a.estimatedImpact).slice(0, 3);
433
+ if (allRecs.length > 0) {
434
+ console.log(import_chalk2.default.bold("\n\u{1F3AF} Top Actionable Recommendations:"));
435
+ allRecs.forEach((rec, i) => {
436
+ const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
437
+ console.log(` ${i + 1}. ${priorityIcon} ${import_chalk2.default.bold(rec.action)}`);
438
+ console.log(
439
+ ` Impact: ${import_chalk2.default.green(`+${rec.estimatedImpact} points`)} to ${rec.tool}`
440
+ );
441
+ });
442
+ }
443
+ }
444
+ }
445
+ function mapToUnifiedReport(res, scoring) {
446
+ const allResults = [];
447
+ const totalFilesSet = /* @__PURE__ */ new Set();
448
+ let criticalCount = 0;
449
+ let majorCount = 0;
450
+ res.summary.toolsRun.forEach((toolId) => {
451
+ const spokeRes = res[toolId];
452
+ if (!spokeRes || !spokeRes.results) return;
453
+ spokeRes.results.forEach((r) => {
454
+ totalFilesSet.add(r.fileName);
455
+ allResults.push(r);
456
+ r.issues?.forEach((i) => {
457
+ if (i.severity === import_core4.Severity.Critical || i.severity === "critical")
458
+ criticalCount++;
459
+ if (i.severity === import_core4.Severity.Major || i.severity === "major")
460
+ majorCount++;
461
+ });
462
+ });
463
+ });
464
+ return {
465
+ ...res,
466
+ results: allResults,
467
+ summary: {
468
+ ...res.summary,
469
+ totalFiles: totalFilesSet.size,
470
+ criticalIssues: criticalCount,
471
+ majorIssues: majorCount
472
+ },
473
+ scoring
474
+ };
475
+ }
476
+
411
477
  // src/commands/upload.ts
412
478
  var import_fs2 = __toESM(require("fs"));
413
479
  var import_path2 = require("path");
414
- var import_chalk2 = __toESM(require("chalk"));
415
- var import_core2 = require("@aiready/core");
480
+ var import_chalk3 = __toESM(require("chalk"));
481
+ var import_core5 = require("@aiready/core");
416
482
  async function uploadAction(file, options) {
417
483
  const startTime = Date.now();
418
484
  const filePath = (0, import_path2.resolve)(process.cwd(), file);
419
485
  const serverUrl = options.server || process.env.AIREADY_SERVER || "https://dev.platform.getaiready.dev";
420
486
  const apiKey = options.apiKey || process.env.AIREADY_API_KEY;
421
487
  if (!apiKey) {
422
- console.error(import_chalk2.default.red("\u274C API Key is required for upload."));
488
+ console.error(import_chalk3.default.red("\u274C API Key is required for upload."));
423
489
  console.log(
424
- import_chalk2.default.dim(
490
+ import_chalk3.default.dim(
425
491
  " Set AIREADY_API_KEY environment variable or use --api-key flag."
426
492
  )
427
493
  );
428
494
  console.log(
429
- import_chalk2.default.dim(
495
+ import_chalk3.default.dim(
430
496
  " Get an API key from https://platform.getaiready.dev/dashboard"
431
497
  )
432
498
  );
433
499
  process.exit(1);
434
500
  }
435
501
  if (!import_fs2.default.existsSync(filePath)) {
436
- console.error(import_chalk2.default.red(`\u274C File not found: ${filePath}`));
502
+ console.error(import_chalk3.default.red(`\u274C File not found: ${filePath}`));
437
503
  process.exit(1);
438
504
  }
439
505
  try {
440
- console.log(import_chalk2.default.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
441
- console.log(import_chalk2.default.dim(` Reading report from ${filePath}...`));
506
+ console.log(import_chalk3.default.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
507
+ console.log(import_chalk3.default.dim(` Reading report from ${filePath}...`));
442
508
  const reportContent = import_fs2.default.readFileSync(filePath, "utf-8");
443
509
  const reportData = JSON.parse(reportContent);
444
- console.log(import_chalk2.default.dim(` Successfully parsed report JSON.`));
510
+ console.log(import_chalk3.default.dim(` Successfully parsed report JSON.`));
445
511
  const repoId = options.repoId || reportData.repository?.repoId;
446
- const res = await fetch(`${serverUrl}/api/analysis/upload`, {
512
+ const response = await fetch(`${serverUrl}/api/analysis/upload`, {
447
513
  method: "POST",
448
514
  headers: {
449
515
  "Content-Type": "application/json",
@@ -455,49 +521,51 @@ async function uploadAction(file, options) {
455
521
  // Might be null, server will handle mapping
456
522
  })
457
523
  });
458
- const contentType = res.headers.get("content-type");
459
- let result = {};
524
+ const contentType = response.headers.get("content-type");
525
+ let uploadResult = {};
460
526
  if (contentType?.includes("application/json")) {
461
- result = await res.json();
527
+ uploadResult = await response.json();
462
528
  } else {
463
- const text = await res.text();
464
- result = { error: text || res.statusText };
529
+ const text = await response.text();
530
+ uploadResult = { error: text || response.statusText };
465
531
  }
466
- if (!res.ok) {
532
+ if (!response.ok) {
467
533
  console.error(
468
- import_chalk2.default.red(`\u274C Upload failed: ${result.error || res.statusText}`)
534
+ import_chalk3.default.red(
535
+ `\u274C Upload failed: ${uploadResult.error || response.statusText}`
536
+ )
469
537
  );
470
538
  if (contentType?.includes("text/html")) {
471
539
  console.log(
472
- import_chalk2.default.yellow(
540
+ import_chalk3.default.yellow(
473
541
  " Note: Received an HTML response. This often indicates a redirect (e.g., to a login page) or a server error."
474
542
  )
475
543
  );
476
- if (result.error?.includes("Redirecting")) {
544
+ if (uploadResult.error?.includes("Redirecting")) {
477
545
  console.log(
478
- import_chalk2.default.dim(
546
+ import_chalk3.default.dim(
479
547
  " Detected redirect. Check if the API endpoint requires authentication or has changed."
480
548
  )
481
549
  );
482
550
  }
483
551
  }
484
- if (res.status === 401) {
552
+ if (response.status === 401) {
485
553
  console.log(
486
- import_chalk2.default.dim(" Hint: Your API key may be invalid or expired.")
554
+ import_chalk3.default.dim(" Hint: Your API key may be invalid or expired.")
487
555
  );
488
556
  }
489
557
  process.exit(1);
490
558
  }
491
559
  const duration = ((Date.now() - startTime) / 1e3).toFixed(2);
492
- console.log(import_chalk2.default.green(`
560
+ console.log(import_chalk3.default.green(`
493
561
  \u2705 Upload successful! (${duration}s)`));
494
- console.log(import_chalk2.default.cyan(` View results: ${serverUrl}/dashboard`));
495
- if (result.analysis) {
496
- console.log(import_chalk2.default.dim(` Analysis ID: ${result.analysis.id}`));
497
- console.log(import_chalk2.default.dim(` Score: ${result.analysis.aiScore}/100`));
562
+ console.log(import_chalk3.default.cyan(` View results: ${serverUrl}/dashboard`));
563
+ if (uploadResult.analysis) {
564
+ console.log(import_chalk3.default.dim(` Analysis ID: ${uploadResult.analysis.id}`));
565
+ console.log(import_chalk3.default.dim(` Score: ${uploadResult.analysis.aiScore}/100`));
498
566
  }
499
567
  } catch (error) {
500
- (0, import_core2.handleCLIError)(error, "Upload");
568
+ (0, import_core5.handleCLIError)(error, "Upload");
501
569
  }
502
570
  }
503
571
  var uploadHelpText = `
@@ -513,10 +581,10 @@ ENVIRONMENT VARIABLES:
513
581
 
514
582
  // src/commands/scan.ts
515
583
  async function scanAction(directory, options) {
516
- console.log(import_chalk3.default.blue("\u{1F680} Starting AIReady unified analysis...\n"));
584
+ console.log(import_chalk4.default.blue("\u{1F680} Starting AIReady unified analysis...\n"));
517
585
  const startTime = Date.now();
518
586
  const resolvedDir = (0, import_path3.resolve)(process.cwd(), directory || ".");
519
- const repoMetadata = (0, import_core3.getRepoMetadata)(resolvedDir);
587
+ const repoMetadata = (0, import_core6.getRepoMetadata)(resolvedDir);
520
588
  try {
521
589
  const defaults = {
522
590
  tools: [
@@ -542,48 +610,48 @@ async function scanAction(directory, options) {
542
610
  switch (options.profile.toLowerCase()) {
543
611
  case "agentic":
544
612
  profileTools = [
545
- import_core3.ToolName.AiSignalClarity,
546
- import_core3.ToolName.AgentGrounding,
547
- import_core3.ToolName.TestabilityIndex
613
+ import_core6.ToolName.AiSignalClarity,
614
+ import_core6.ToolName.AgentGrounding,
615
+ import_core6.ToolName.TestabilityIndex
548
616
  ];
549
617
  break;
550
618
  case "cost":
551
- profileTools = [import_core3.ToolName.PatternDetect, import_core3.ToolName.ContextAnalyzer];
619
+ profileTools = [import_core6.ToolName.PatternDetect, import_core6.ToolName.ContextAnalyzer];
552
620
  break;
553
621
  case "logic":
554
622
  profileTools = [
555
- import_core3.ToolName.TestabilityIndex,
556
- import_core3.ToolName.NamingConsistency,
557
- import_core3.ToolName.ContextAnalyzer,
558
- import_core3.ToolName.PatternDetect,
559
- import_core3.ToolName.ChangeAmplification
623
+ import_core6.ToolName.TestabilityIndex,
624
+ import_core6.ToolName.NamingConsistency,
625
+ import_core6.ToolName.ContextAnalyzer,
626
+ import_core6.ToolName.PatternDetect,
627
+ import_core6.ToolName.ChangeAmplification
560
628
  ];
561
629
  break;
562
630
  case "ui":
563
631
  profileTools = [
564
- import_core3.ToolName.NamingConsistency,
565
- import_core3.ToolName.ContextAnalyzer,
566
- import_core3.ToolName.PatternDetect,
567
- import_core3.ToolName.DocDrift,
568
- import_core3.ToolName.AiSignalClarity
632
+ import_core6.ToolName.NamingConsistency,
633
+ import_core6.ToolName.ContextAnalyzer,
634
+ import_core6.ToolName.PatternDetect,
635
+ import_core6.ToolName.DocDrift,
636
+ import_core6.ToolName.AiSignalClarity
569
637
  ];
570
638
  break;
571
639
  case "security":
572
640
  profileTools = [
573
- import_core3.ToolName.NamingConsistency,
574
- import_core3.ToolName.TestabilityIndex
641
+ import_core6.ToolName.NamingConsistency,
642
+ import_core6.ToolName.TestabilityIndex
575
643
  ];
576
644
  break;
577
645
  case "onboarding":
578
646
  profileTools = [
579
- import_core3.ToolName.ContextAnalyzer,
580
- import_core3.ToolName.NamingConsistency,
581
- import_core3.ToolName.AgentGrounding
647
+ import_core6.ToolName.ContextAnalyzer,
648
+ import_core6.ToolName.NamingConsistency,
649
+ import_core6.ToolName.AgentGrounding
582
650
  ];
583
651
  break;
584
652
  default:
585
653
  console.log(
586
- import_chalk3.default.yellow(
654
+ import_chalk4.default.yellow(
587
655
  `
588
656
  \u26A0\uFE0F Unknown profile '${options.profile}'. Using defaults.`
589
657
  )
@@ -595,27 +663,27 @@ async function scanAction(directory, options) {
595
663
  exclude: options.exclude?.split(",")
596
664
  };
597
665
  if (profileTools) cliOverrides.tools = profileTools;
598
- const baseOptions = await (0, import_core3.loadMergedConfig)(
666
+ const baseOptions = await (0, import_core6.loadMergedConfig)(
599
667
  resolvedDir,
600
668
  defaults,
601
669
  cliOverrides
602
670
  );
603
- let finalOptions = { ...baseOptions };
604
- if (baseOptions.tools.includes(import_core3.ToolName.PatternDetect) || baseOptions.tools.includes("patterns")) {
671
+ const finalOptions = { ...baseOptions };
672
+ if (baseOptions.tools.includes(import_core6.ToolName.PatternDetect) || baseOptions.tools.includes("patterns")) {
605
673
  const { getSmartDefaults } = await import("@aiready/pattern-detect");
606
674
  const patternSmartDefaults = await getSmartDefaults(
607
675
  resolvedDir,
608
- finalOptions.toolConfigs?.[import_core3.ToolName.PatternDetect] || {}
676
+ finalOptions.toolConfigs?.[import_core6.ToolName.PatternDetect] || {}
609
677
  );
610
678
  if (!finalOptions.toolConfigs) finalOptions.toolConfigs = {};
611
- finalOptions.toolConfigs[import_core3.ToolName.PatternDetect] = {
679
+ finalOptions.toolConfigs[import_core6.ToolName.PatternDetect] = {
612
680
  ...patternSmartDefaults,
613
- ...finalOptions.toolConfigs[import_core3.ToolName.PatternDetect]
681
+ ...finalOptions.toolConfigs[import_core6.ToolName.PatternDetect]
614
682
  };
615
683
  }
616
- console.log(import_chalk3.default.cyan("\n=== AIReady Run Preview ==="));
684
+ console.log(import_chalk4.default.cyan("\n=== AIReady Run Preview ==="));
617
685
  console.log(
618
- import_chalk3.default.white("Tools to run:"),
686
+ import_chalk4.default.white("Tools to run:"),
619
687
  (finalOptions.tools || []).join(", ")
620
688
  );
621
689
  const progressCallback = (event) => {
@@ -624,16 +692,16 @@ async function scanAction(directory, options) {
624
692
  return;
625
693
  }
626
694
  process.stdout.write("\r\x1B[K");
627
- console.log(import_chalk3.default.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
695
+ console.log(import_chalk4.default.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
628
696
  const res = event.data;
629
697
  if (res && res.summary) {
630
698
  if (res.summary.totalIssues !== void 0)
631
- console.log(` Issues found: ${import_chalk3.default.bold(res.summary.totalIssues)}`);
699
+ console.log(` Issues found: ${import_chalk4.default.bold(res.summary.totalIssues)}`);
632
700
  if (res.summary.score !== void 0)
633
- console.log(` Tool Score: ${import_chalk3.default.bold(res.summary.score)}/100`);
701
+ console.log(` Tool Score: ${import_chalk4.default.bold(res.summary.score)}/100`);
634
702
  if (res.summary.totalFiles !== void 0)
635
703
  console.log(
636
- ` Files analyzed: ${import_chalk3.default.bold(res.summary.totalFiles)}`
704
+ ` Files analyzed: ${import_chalk4.default.bold(res.summary.totalFiles)}`
637
705
  );
638
706
  }
639
707
  };
@@ -645,13 +713,7 @@ async function scanAction(directory, options) {
645
713
  },
646
714
  suppressToolConfig: true
647
715
  });
648
- console.log(import_chalk3.default.cyan("\n=== AIReady Run Summary ==="));
649
- console.log(
650
- ` Total issues (all tools): ${import_chalk3.default.bold(String(results.summary.totalIssues || 0))}`
651
- );
652
- console.log(
653
- ` Execution time: ${import_chalk3.default.bold(((Date.now() - startTime) / 1e3).toFixed(2) + "s")}`
654
- );
716
+ printScanSummary(results, startTime);
655
717
  let scoringResult;
656
718
  if (options.score || finalOptions.scoring?.showBreakdown) {
657
719
  scoringResult = await scoreUnified(results, {
@@ -661,9 +723,7 @@ async function scanAction(directory, options) {
661
723
  profile: scoringProfile
662
724
  }
663
725
  });
664
- console.log(import_chalk3.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
665
- console.log(` ${(0, import_core3.formatScore)(scoringResult)}`);
666
- console.log(import_chalk3.default.dim(` (Scoring Profile: ${scoringProfile})`));
726
+ printScoring(scoringResult, scoringProfile);
667
727
  if (options.compareTo) {
668
728
  try {
669
729
  const prevReport = JSON.parse(
@@ -675,19 +735,19 @@ async function scanAction(directory, options) {
675
735
  const diffStr = diff > 0 ? `+${diff}` : String(diff);
676
736
  if (diff > 0)
677
737
  console.log(
678
- import_chalk3.default.green(
738
+ import_chalk4.default.green(
679
739
  ` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
680
740
  )
681
741
  );
682
742
  else if (diff < 0)
683
743
  console.log(
684
- import_chalk3.default.red(
744
+ import_chalk4.default.red(
685
745
  ` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
686
746
  )
687
747
  );
688
748
  else
689
749
  console.log(
690
- import_chalk3.default.blue(
750
+ import_chalk4.default.blue(
691
751
  ` \u2796 Trend: No change (${prevScore} \u2192 ${scoringResult.overall})`
692
752
  )
693
753
  );
@@ -711,7 +771,7 @@ async function scanAction(directory, options) {
711
771
  0
712
772
  );
713
773
  if (totalContext > 0) {
714
- const unifiedBudget = (0, import_core3.calculateTokenBudget)({
774
+ const unifiedBudget = (0, import_core6.calculateTokenBudget)({
715
775
  totalContextTokens: totalContext,
716
776
  wastedTokens: {
717
777
  duplication: totalWastedDuplication,
@@ -736,19 +796,7 @@ async function scanAction(directory, options) {
736
796
  issues: allIssues,
737
797
  modelId
738
798
  });
739
- console.log(import_chalk3.default.bold("\n\u{1F4B0} Business Impact Analysis (Monthly)"));
740
- console.log(
741
- ` Potential Savings: ${import_chalk3.default.green(import_chalk3.default.bold("$" + roi.monthlySavings.toLocaleString()))}`
742
- );
743
- console.log(
744
- ` Productivity Gain: ${import_chalk3.default.cyan(import_chalk3.default.bold(roi.productivityGainHours + "h"))} (est. dev time)`
745
- );
746
- console.log(
747
- ` Context Efficiency: ${import_chalk3.default.yellow((unifiedBudget.efficiencyRatio * 100).toFixed(0) + "%")}`
748
- );
749
- console.log(
750
- ` Annual Value: ${import_chalk3.default.bold("$" + roi.annualValue.toLocaleString())} (ROI Prediction)`
751
- );
799
+ printBusinessImpact(roi, unifiedBudget);
752
800
  results.summary.businessImpact = {
753
801
  estimatedMonthlyWaste: roi.monthlySavings,
754
802
  potentialSavings: roi.monthlySavings,
@@ -757,90 +805,36 @@ async function scanAction(directory, options) {
757
805
  scoringResult.tokenBudget = unifiedBudget;
758
806
  scoringResult.businessROI = roi;
759
807
  }
760
- if (scoringResult.breakdown) {
761
- console.log(import_chalk3.default.bold("\nTool breakdown:"));
762
- scoringResult.breakdown.forEach((tool) => {
763
- const rating = (0, import_core3.getRating)(tool.score);
764
- const emoji = (0, import_core3.getRatingDisplay)(rating).emoji;
765
- console.log(
766
- ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${emoji}`
767
- );
768
- });
769
- const allRecs = scoringResult.breakdown.flatMap(
770
- (t) => (t.recommendations || []).map((r) => ({ ...r, tool: t.toolName }))
771
- ).sort((a, b) => b.estimatedImpact - a.estimatedImpact).slice(0, 3);
772
- if (allRecs.length > 0) {
773
- console.log(import_chalk3.default.bold("\n\u{1F3AF} Top Actionable Recommendations:"));
774
- allRecs.forEach((rec, i) => {
775
- const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
776
- console.log(
777
- ` ${i + 1}. ${priorityIcon} ${import_chalk3.default.bold(rec.action)}`
778
- );
779
- console.log(
780
- ` Impact: ${import_chalk3.default.green(`+${rec.estimatedImpact} points`)} to ${rec.tool}`
781
- );
782
- });
783
- }
784
- }
785
808
  }
786
809
  console.log(
787
- import_chalk3.default.dim(
810
+ import_chalk4.default.dim(
788
811
  "\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
789
812
  )
790
813
  );
791
- console.log(import_chalk3.default.dim("\u{1F4AC} Found a bug or have a metric idea?"));
792
- console.log(import_chalk3.default.dim("\u{1F449} Copy/paste this to your AI agent:"));
814
+ console.log(import_chalk4.default.dim("\u{1F4AC} Found a bug or have a metric idea?"));
815
+ console.log(import_chalk4.default.dim("\u{1F449} Copy/paste this to your AI agent:"));
793
816
  console.log(
794
- import_chalk3.default.cyan(
817
+ import_chalk4.default.cyan(
795
818
  ` "Any feedback for the tools? Please use 'aiready bug' to report \u2764\uFE0F"`
796
819
  )
797
820
  );
798
821
  console.log(
799
- import_chalk3.default.dim(
822
+ import_chalk4.default.dim(
800
823
  "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
801
824
  )
802
825
  );
803
- const mapToUnifiedReport = (res, scoring) => {
804
- const allResults = [];
805
- const totalFilesSet = /* @__PURE__ */ new Set();
806
- let criticalCount = 0;
807
- let majorCount = 0;
808
- res.summary.toolsRun.forEach((toolId) => {
809
- const spokeRes = res[toolId];
810
- if (!spokeRes || !spokeRes.results) return;
811
- spokeRes.results.forEach((r) => {
812
- totalFilesSet.add(r.fileName);
813
- allResults.push(r);
814
- r.issues?.forEach((i) => {
815
- if (i.severity === import_core3.Severity.Critical) criticalCount++;
816
- if (i.severity === import_core3.Severity.Major) majorCount++;
817
- });
818
- });
819
- });
820
- return {
821
- ...res,
822
- results: allResults,
823
- summary: {
824
- ...res.summary,
825
- totalFiles: totalFilesSet.size,
826
- criticalIssues: criticalCount,
827
- majorIssues: majorCount
828
- },
829
- scoring
830
- };
831
- };
832
826
  const outputData = {
833
827
  ...mapToUnifiedReport(results, scoringResult),
834
828
  repository: repoMetadata
835
829
  };
836
830
  const outputFormat = options.output || finalOptions.output?.format || "console";
837
- const outputPath = (0, import_core3.resolveOutputPath)(
831
+ const outputPath = (0, import_core6.resolveOutputPath)(
838
832
  options.outputFile || finalOptions.output?.file,
839
833
  `aiready-report-${getReportTimestamp()}.json`,
840
834
  resolvedDir
841
835
  );
842
836
  if (outputFormat === "json") {
843
- (0, import_core3.handleJSONOutput)(
837
+ (0, import_core6.handleJSONOutput)(
844
838
  outputData,
845
839
  outputPath,
846
840
  `\u2705 Report saved to ${outputPath}`
@@ -848,7 +842,7 @@ async function scanAction(directory, options) {
848
842
  } else {
849
843
  try {
850
844
  (0, import_fs3.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
851
- console.log(import_chalk3.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
845
+ console.log(import_chalk4.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
852
846
  } catch (err) {
853
847
  void err;
854
848
  }
@@ -860,21 +854,21 @@ async function scanAction(directory, options) {
860
854
  });
861
855
  }
862
856
  await warnIfGraphCapExceeded(outputData, resolvedDir);
863
- const isCI = options.ci || process.env.CI === "true";
864
- if (isCI && scoringResult) {
857
+ if (scoringResult) {
865
858
  const threshold = options.threshold ? parseInt(options.threshold) : void 0;
866
859
  const failOnLevel = options.failOn || "critical";
860
+ const isCI = options.ci || process.env.CI === "true";
867
861
  let shouldFail = false;
868
862
  let failReason = "";
869
863
  const report = mapToUnifiedReport(results, scoringResult);
870
- if (report.results && report.results.length > 0) {
864
+ if (isCI && report.results && report.results.length > 0) {
871
865
  console.log(
872
- import_chalk3.default.cyan(
866
+ import_chalk4.default.cyan(
873
867
  `
874
868
  \u{1F4DD} Emitting GitHub Action annotations for ${report.results.length} issues...`
875
869
  )
876
870
  );
877
- (0, import_core3.emitIssuesAsAnnotations)(report.results);
871
+ (0, import_core6.emitIssuesAsAnnotations)(report.results);
878
872
  }
879
873
  if (threshold && scoringResult.overall < threshold) {
880
874
  shouldFail = true;
@@ -890,15 +884,15 @@ async function scanAction(directory, options) {
890
884
  }
891
885
  }
892
886
  if (shouldFail) {
893
- console.log(import_chalk3.default.red(`
894
- \u{1F6AB} PR BLOCKED: ${failReason}`));
887
+ console.log(import_chalk4.default.red(`
888
+ \u{1F6AB} SCAN FAILED: ${failReason}`));
895
889
  process.exit(1);
896
890
  } else {
897
- console.log(import_chalk3.default.green("\n\u2705 PR PASSED"));
891
+ console.log(import_chalk4.default.green("\n\u2705 SCAN PASSED"));
898
892
  }
899
893
  }
900
894
  } catch (error) {
901
- (0, import_core3.handleCLIError)(error, "Analysis");
895
+ (0, import_core6.handleCLIError)(error, "Analysis");
902
896
  }
903
897
  }
904
898
  var scanHelpText = `...`;
@@ -906,19 +900,19 @@ var scanHelpText = `...`;
906
900
  // src/commands/init.ts
907
901
  var import_fs4 = require("fs");
908
902
  var import_path4 = require("path");
909
- var import_chalk4 = __toESM(require("chalk"));
910
- var import_core4 = require("@aiready/core");
903
+ var import_chalk5 = __toESM(require("chalk"));
904
+ var import_core7 = require("@aiready/core");
911
905
  async function initAction(options) {
912
906
  const fileExt = options.format === "js" ? "js" : "json";
913
907
  const fileName = fileExt === "js" ? "aiready.config.js" : "aiready.json";
914
908
  const filePath = (0, import_path4.join)(process.cwd(), fileName);
915
909
  if ((0, import_fs4.existsSync)(filePath) && !options.force) {
916
910
  console.error(
917
- import_chalk4.default.red(`Error: ${fileName} already exists. Use --force to overwrite.`)
911
+ import_chalk5.default.red(`Error: ${fileName} already exists. Use --force to overwrite.`)
918
912
  );
919
913
  process.exit(1);
920
914
  }
921
- const defaultConfig = {
915
+ const baseConfig = {
922
916
  scan: {
923
917
  include: [
924
918
  "src/**/*.ts",
@@ -934,42 +928,84 @@ async function initAction(options) {
934
928
  "**/*.spec.ts"
935
929
  ],
936
930
  tools: [
937
- import_core4.ToolName.PatternDetect,
938
- import_core4.ToolName.ContextAnalyzer,
939
- import_core4.ToolName.NamingConsistency,
940
- import_core4.ToolName.AiSignalClarity,
941
- import_core4.ToolName.AgentGrounding,
942
- import_core4.ToolName.TestabilityIndex,
943
- import_core4.ToolName.DocDrift,
944
- import_core4.ToolName.DependencyHealth,
945
- import_core4.ToolName.ChangeAmplification
931
+ import_core7.ToolName.PatternDetect,
932
+ import_core7.ToolName.ContextAnalyzer,
933
+ import_core7.ToolName.NamingConsistency,
934
+ import_core7.ToolName.AiSignalClarity,
935
+ import_core7.ToolName.AgentGrounding,
936
+ import_core7.ToolName.TestabilityIndex,
937
+ import_core7.ToolName.DocDrift,
938
+ import_core7.ToolName.DependencyHealth,
939
+ import_core7.ToolName.ChangeAmplification
946
940
  ]
947
941
  },
948
942
  tools: {
949
- [import_core4.ToolName.PatternDetect]: {
943
+ [import_core7.ToolName.PatternDetect]: {
950
944
  minSimilarity: 0.8,
951
- minLines: 5
945
+ minLines: 5,
946
+ ...options.full ? {
947
+ batchSize: 50,
948
+ approx: true,
949
+ minSharedTokens: 10,
950
+ maxCandidatesPerBlock: 100
951
+ } : {}
952
952
  },
953
- [import_core4.ToolName.ContextAnalyzer]: {
953
+ [import_core7.ToolName.ContextAnalyzer]: {
954
954
  maxContextBudget: 128e3,
955
- minCohesion: 0.6
955
+ minCohesion: 0.6,
956
+ ...options.full ? {
957
+ maxDepth: 7,
958
+ maxFragmentation: 0.4,
959
+ focus: "all",
960
+ includeNodeModules: false
961
+ } : {}
956
962
  },
957
- [import_core4.ToolName.NamingConsistency]: {
958
- shortWords: ["id", "db", "ui", "ai"]
963
+ [import_core7.ToolName.NamingConsistency]: {
964
+ shortWords: ["id", "db", "ui", "ai"],
965
+ ...options.full ? { acceptedAbbreviations: [], disableChecks: [] } : {}
959
966
  },
960
- [import_core4.ToolName.AiSignalClarity]: {
967
+ [import_core7.ToolName.AiSignalClarity]: {
961
968
  checkMagicLiterals: true,
962
969
  checkBooleanTraps: true,
963
970
  checkAmbiguousNames: true,
964
- checkUndocumentedExports: true
965
- }
971
+ checkUndocumentedExports: true,
972
+ ...options.full ? { checkImplicitSideEffects: false, checkDeepCallbacks: false } : {}
973
+ },
974
+ ...options.full ? {
975
+ [import_core7.ToolName.AgentGrounding]: {
976
+ maxRecommendedDepth: 5,
977
+ readmeStaleDays: 30
978
+ },
979
+ [import_core7.ToolName.TestabilityIndex]: {
980
+ minCoverageRatio: 0.7,
981
+ testPatterns: ["**/*.test.ts", "**/__tests__/**"]
982
+ },
983
+ [import_core7.ToolName.DocDrift]: {
984
+ maxCommits: 50,
985
+ staleMonths: 3
986
+ },
987
+ [import_core7.ToolName.DependencyHealth]: {
988
+ trainingCutoffYear: 2023
989
+ }
990
+ } : {}
966
991
  },
967
992
  scoring: {
968
993
  threshold: 70,
969
- showBreakdown: true
970
- }
994
+ showBreakdown: true,
995
+ ...options.full ? { profile: "default" } : {}
996
+ },
997
+ ...options.full ? {
998
+ visualizer: {
999
+ groupingDirs: ["packages", "src", "lib"],
1000
+ graph: {
1001
+ maxNodes: 5e3,
1002
+ maxEdges: 1e4
1003
+ }
1004
+ }
1005
+ } : {}
971
1006
  };
972
- let content = "";
1007
+ const defaultConfig = baseConfig;
1008
+ let content;
973
1009
  if (fileExt === "js") {
974
1010
  content = `/** @type {import('@aiready/core').AIReadyConfig} */
975
1011
  module.exports = ${JSON.stringify(
@@ -984,26 +1020,26 @@ module.exports = ${JSON.stringify(
984
1020
  try {
985
1021
  (0, import_fs4.writeFileSync)(filePath, content, "utf8");
986
1022
  console.log(
987
- import_chalk4.default.green(`
988
- \u2705 Created default configuration: ${import_chalk4.default.bold(fileName)}`)
1023
+ import_chalk5.default.green(`
1024
+ \u2705 Created default configuration: ${import_chalk5.default.bold(fileName)}`)
989
1025
  );
990
1026
  console.log(
991
- import_chalk4.default.cyan("You can now fine-tune your settings and run AIReady with:")
1027
+ import_chalk5.default.cyan("You can now fine-tune your settings and run AIReady with:")
992
1028
  );
993
- console.log(import_chalk4.default.white(` $ aiready scan
1029
+ console.log(import_chalk5.default.white(` $ aiready scan
994
1030
  `));
995
1031
  } catch (error) {
996
- console.error(import_chalk4.default.red(`Failed to write configuration file: ${error}`));
1032
+ console.error(import_chalk5.default.red(`Failed to write configuration file: ${error}`));
997
1033
  process.exit(1);
998
1034
  }
999
1035
  }
1000
1036
 
1001
1037
  // src/commands/patterns.ts
1002
- var import_chalk5 = __toESM(require("chalk"));
1038
+ var import_chalk6 = __toESM(require("chalk"));
1003
1039
  var import_path5 = require("path");
1004
- var import_core5 = require("@aiready/core");
1040
+ var import_core8 = require("@aiready/core");
1005
1041
  async function patternsAction(directory, options) {
1006
- console.log(import_chalk5.default.blue("\u{1F50D} Analyzing patterns...\n"));
1042
+ console.log(import_chalk6.default.blue("\u{1F50D} Analyzing patterns...\n"));
1007
1043
  const startTime = Date.now();
1008
1044
  const resolvedDir = (0, import_path5.resolve)(process.cwd(), directory || ".");
1009
1045
  try {
@@ -1034,14 +1070,16 @@ async function patternsAction(directory, options) {
1034
1070
  if (options.minSharedTokens) {
1035
1071
  cliOptions.minSharedTokens = parseInt(options.minSharedTokens);
1036
1072
  }
1037
- const finalOptions = await (0, import_core5.loadMergedConfig)(
1073
+ const finalOptions = await (0, import_core8.loadMergedConfig)(
1038
1074
  resolvedDir,
1039
1075
  defaults,
1040
1076
  cliOptions
1041
1077
  );
1042
1078
  const { analyzePatterns, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
1043
- const { results, duplicates } = await analyzePatterns(finalOptions);
1044
- const elapsedTime = (0, import_core5.getElapsedTime)(startTime);
1079
+ const { results, duplicates } = await analyzePatterns(
1080
+ finalOptions
1081
+ );
1082
+ const elapsedTime = (0, import_core8.getElapsedTime)(startTime);
1045
1083
  const summary = generateSummary(results);
1046
1084
  let patternScore;
1047
1085
  if (options.score) {
@@ -1055,12 +1093,12 @@ async function patternsAction(directory, options) {
1055
1093
  summary: { ...summary, executionTime: parseFloat(elapsedTime) },
1056
1094
  ...patternScore && { scoring: patternScore }
1057
1095
  };
1058
- const outputPath = (0, import_core5.resolveOutputPath)(
1096
+ const outputPath = (0, import_core8.resolveOutputPath)(
1059
1097
  userOutputFile,
1060
1098
  `aiready-report-${getReportTimestamp()}.json`,
1061
1099
  resolvedDir
1062
1100
  );
1063
- (0, import_core5.handleJSONOutput)(
1101
+ (0, import_core8.handleJSONOutput)(
1064
1102
  outputData,
1065
1103
  outputPath,
1066
1104
  `\u2705 Results saved to ${outputPath}`
@@ -1069,38 +1107,38 @@ async function patternsAction(directory, options) {
1069
1107
  const terminalWidth = process.stdout.columns || 80;
1070
1108
  const dividerWidth = Math.min(60, terminalWidth - 2);
1071
1109
  const divider = "\u2501".repeat(dividerWidth);
1072
- console.log(import_chalk5.default.cyan(divider));
1073
- console.log(import_chalk5.default.bold.white(" PATTERN ANALYSIS SUMMARY"));
1074
- console.log(import_chalk5.default.cyan(divider) + "\n");
1110
+ console.log(import_chalk6.default.cyan(divider));
1111
+ console.log(import_chalk6.default.bold.white(" PATTERN ANALYSIS SUMMARY"));
1112
+ console.log(import_chalk6.default.cyan(divider) + "\n");
1075
1113
  console.log(
1076
- import_chalk5.default.white(`\u{1F4C1} Files analyzed: ${import_chalk5.default.bold(results.length)}`)
1114
+ import_chalk6.default.white(`\u{1F4C1} Files analyzed: ${import_chalk6.default.bold(results.length)}`)
1077
1115
  );
1078
1116
  console.log(
1079
- import_chalk5.default.yellow(
1080
- `\u26A0 Duplicate patterns found: ${import_chalk5.default.bold(summary.totalPatterns)}`
1117
+ import_chalk6.default.yellow(
1118
+ `\u26A0 Duplicate patterns found: ${import_chalk6.default.bold(summary.totalPatterns)}`
1081
1119
  )
1082
1120
  );
1083
1121
  console.log(
1084
- import_chalk5.default.red(
1085
- `\u{1F4B0} Token cost (wasted): ${import_chalk5.default.bold(summary.totalTokenCost.toLocaleString())}`
1122
+ import_chalk6.default.red(
1123
+ `\u{1F4B0} Token cost (wasted): ${import_chalk6.default.bold(summary.totalTokenCost.toLocaleString())}`
1086
1124
  )
1087
1125
  );
1088
1126
  console.log(
1089
- import_chalk5.default.gray(`\u23F1 Analysis time: ${import_chalk5.default.bold(elapsedTime + "s")}`)
1127
+ import_chalk6.default.gray(`\u23F1 Analysis time: ${import_chalk6.default.bold(elapsedTime + "s")}`)
1090
1128
  );
1091
1129
  const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
1092
1130
  if (sortedTypes.length > 0) {
1093
- console.log(import_chalk5.default.cyan("\n" + divider));
1094
- console.log(import_chalk5.default.bold.white(" PATTERNS BY TYPE"));
1095
- console.log(import_chalk5.default.cyan(divider) + "\n");
1131
+ console.log(import_chalk6.default.cyan("\n" + divider));
1132
+ console.log(import_chalk6.default.bold.white(" PATTERNS BY TYPE"));
1133
+ console.log(import_chalk6.default.cyan(divider) + "\n");
1096
1134
  sortedTypes.forEach(([type, count]) => {
1097
- console.log(` ${import_chalk5.default.white(type.padEnd(15))} ${import_chalk5.default.bold(count)}`);
1135
+ console.log(` ${import_chalk6.default.white(type.padEnd(15))} ${import_chalk6.default.bold(count)}`);
1098
1136
  });
1099
1137
  }
1100
1138
  if (summary.totalPatterns > 0 && duplicates.length > 0) {
1101
- console.log(import_chalk5.default.cyan("\n" + divider));
1102
- console.log(import_chalk5.default.bold.white(" TOP DUPLICATE PATTERNS"));
1103
- console.log(import_chalk5.default.cyan(divider) + "\n");
1139
+ console.log(import_chalk6.default.cyan("\n" + divider));
1140
+ console.log(import_chalk6.default.bold.white(" TOP DUPLICATE PATTERNS"));
1141
+ console.log(import_chalk6.default.cyan(divider) + "\n");
1104
1142
  const topDuplicates = [...duplicates].sort((a, b) => b.similarity - a.similarity).slice(0, 10);
1105
1143
  topDuplicates.forEach((dup) => {
1106
1144
  const severity = dup.similarity > 0.95 ? "CRITICAL" : dup.similarity > 0.9 ? "HIGH" : "MEDIUM";
@@ -1108,31 +1146,31 @@ async function patternsAction(directory, options) {
1108
1146
  const file1Name = dup.file1.split("/").pop() || dup.file1;
1109
1147
  const file2Name = dup.file2.split("/").pop() || dup.file2;
1110
1148
  console.log(
1111
- `${severityIcon} ${severity}: ${import_chalk5.default.bold(file1Name)} \u2194 ${import_chalk5.default.bold(file2Name)}`
1149
+ `${severityIcon} ${severity}: ${import_chalk6.default.bold(file1Name)} \u2194 ${import_chalk6.default.bold(file2Name)}`
1112
1150
  );
1113
1151
  console.log(
1114
- ` Similarity: ${import_chalk5.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk5.default.bold(dup.tokenCost.toLocaleString())} tokens each`
1152
+ ` Similarity: ${import_chalk6.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk6.default.bold(dup.tokenCost.toLocaleString())} tokens each`
1115
1153
  );
1116
1154
  console.log(
1117
- ` Lines: ${import_chalk5.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk5.default.cyan(dup.line2 + "-" + dup.endLine2)}
1155
+ ` Lines: ${import_chalk6.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk6.default.cyan(dup.line2 + "-" + dup.endLine2)}
1118
1156
  `
1119
1157
  );
1120
1158
  });
1121
1159
  } else {
1122
1160
  console.log(
1123
- import_chalk5.default.green("\n\u2728 Great! No duplicate patterns detected.\n")
1161
+ import_chalk6.default.green("\n\u2728 Great! No duplicate patterns detected.\n")
1124
1162
  );
1125
1163
  }
1126
1164
  if (patternScore) {
1127
- console.log(import_chalk5.default.cyan(divider));
1128
- console.log(import_chalk5.default.bold.white(" AI READINESS SCORE (Patterns)"));
1129
- console.log(import_chalk5.default.cyan(divider) + "\n");
1130
- console.log((0, import_core5.formatToolScore)(patternScore));
1165
+ console.log(import_chalk6.default.cyan(divider));
1166
+ console.log(import_chalk6.default.bold.white(" AI READINESS SCORE (Patterns)"));
1167
+ console.log(import_chalk6.default.cyan(divider) + "\n");
1168
+ console.log((0, import_core8.formatToolScore)(patternScore));
1131
1169
  console.log();
1132
1170
  }
1133
1171
  }
1134
1172
  } catch (error) {
1135
- (0, import_core5.handleCLIError)(error, "Pattern analysis");
1173
+ (0, import_core8.handleCLIError)(error, "Pattern analysis");
1136
1174
  }
1137
1175
  }
1138
1176
  var patternsHelpText = `
@@ -1143,11 +1181,11 @@ EXAMPLES:
1143
1181
  `;
1144
1182
 
1145
1183
  // src/commands/context.ts
1146
- var import_chalk6 = __toESM(require("chalk"));
1184
+ var import_chalk7 = __toESM(require("chalk"));
1147
1185
  var import_path6 = require("path");
1148
- var import_core6 = require("@aiready/core");
1186
+ var import_core9 = require("@aiready/core");
1149
1187
  async function contextAction(directory, options) {
1150
- console.log(import_chalk6.default.blue("\u{1F9E0} Analyzing context costs...\n"));
1188
+ console.log(import_chalk7.default.blue("\u{1F9E0} Analyzing context costs...\n"));
1151
1189
  const startTime = Date.now();
1152
1190
  const resolvedDir = (0, import_path6.resolve)(process.cwd(), directory || ".");
1153
1191
  try {
@@ -1161,7 +1199,7 @@ async function contextAction(directory, options) {
1161
1199
  file: void 0
1162
1200
  }
1163
1201
  };
1164
- const baseOptions = await (0, import_core6.loadMergedConfig)(resolvedDir, defaults, {
1202
+ const baseOptions = await (0, import_core9.loadMergedConfig)(resolvedDir, defaults, {
1165
1203
  maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
1166
1204
  maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
1167
1205
  include: options.include?.split(","),
@@ -1187,7 +1225,7 @@ async function contextAction(directory, options) {
1187
1225
  console.log("");
1188
1226
  const { analyzeContext, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
1189
1227
  const results = await analyzeContext(finalOptions);
1190
- const elapsedTime = (0, import_core6.getElapsedTime)(startTime);
1228
+ const elapsedTime = (0, import_core9.getElapsedTime)(startTime);
1191
1229
  const summary = generateSummary(results);
1192
1230
  let contextScore;
1193
1231
  if (options.score) {
@@ -1201,12 +1239,12 @@ async function contextAction(directory, options) {
1201
1239
  summary: { ...summary, executionTime: parseFloat(elapsedTime) },
1202
1240
  ...contextScore && { scoring: contextScore }
1203
1241
  };
1204
- const outputPath = (0, import_core6.resolveOutputPath)(
1242
+ const outputPath = (0, import_core9.resolveOutputPath)(
1205
1243
  userOutputFile,
1206
1244
  `aiready-report-${getReportTimestamp()}.json`,
1207
1245
  resolvedDir
1208
1246
  );
1209
- (0, import_core6.handleJSONOutput)(
1247
+ (0, import_core9.handleJSONOutput)(
1210
1248
  outputData,
1211
1249
  outputPath,
1212
1250
  `\u2705 Results saved to ${outputPath}`
@@ -1215,85 +1253,85 @@ async function contextAction(directory, options) {
1215
1253
  const terminalWidth = process.stdout.columns || 80;
1216
1254
  const dividerWidth = Math.min(60, terminalWidth - 2);
1217
1255
  const divider = "\u2501".repeat(dividerWidth);
1218
- console.log(import_chalk6.default.cyan(divider));
1219
- console.log(import_chalk6.default.bold.white(" CONTEXT ANALYSIS SUMMARY"));
1220
- console.log(import_chalk6.default.cyan(divider) + "\n");
1256
+ console.log(import_chalk7.default.cyan(divider));
1257
+ console.log(import_chalk7.default.bold.white(" CONTEXT ANALYSIS SUMMARY"));
1258
+ console.log(import_chalk7.default.cyan(divider) + "\n");
1221
1259
  console.log(
1222
- import_chalk6.default.white(`\u{1F4C1} Files analyzed: ${import_chalk6.default.bold(summary.totalFiles)}`)
1260
+ import_chalk7.default.white(`\u{1F4C1} Files analyzed: ${import_chalk7.default.bold(summary.totalFiles)}`)
1223
1261
  );
1224
1262
  console.log(
1225
- import_chalk6.default.white(
1226
- `\u{1F4CA} Total tokens: ${import_chalk6.default.bold(summary.totalTokens.toLocaleString())}`
1263
+ import_chalk7.default.white(
1264
+ `\u{1F4CA} Total tokens: ${import_chalk7.default.bold(summary.totalTokens.toLocaleString())}`
1227
1265
  )
1228
1266
  );
1229
1267
  console.log(
1230
- import_chalk6.default.yellow(
1231
- `\u{1F4B0} Avg context budget: ${import_chalk6.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
1268
+ import_chalk7.default.yellow(
1269
+ `\u{1F4B0} Avg context budget: ${import_chalk7.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
1232
1270
  )
1233
1271
  );
1234
1272
  console.log(
1235
- import_chalk6.default.white(`\u23F1 Analysis time: ${import_chalk6.default.bold(elapsedTime + "s")}
1273
+ import_chalk7.default.white(`\u23F1 Analysis time: ${import_chalk7.default.bold(elapsedTime + "s")}
1236
1274
  `)
1237
1275
  );
1238
1276
  const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
1239
1277
  if (totalIssues > 0) {
1240
- console.log(import_chalk6.default.bold("\u26A0\uFE0F Issues Found:\n"));
1278
+ console.log(import_chalk7.default.bold("\u26A0\uFE0F Issues Found:\n"));
1241
1279
  if (summary.criticalIssues > 0) {
1242
1280
  console.log(
1243
- import_chalk6.default.red(` \u{1F534} Critical: ${import_chalk6.default.bold(summary.criticalIssues)}`)
1281
+ import_chalk7.default.red(` \u{1F534} Critical: ${import_chalk7.default.bold(summary.criticalIssues)}`)
1244
1282
  );
1245
1283
  }
1246
1284
  if (summary.majorIssues > 0) {
1247
1285
  console.log(
1248
- import_chalk6.default.yellow(` \u{1F7E1} Major: ${import_chalk6.default.bold(summary.majorIssues)}`)
1286
+ import_chalk7.default.yellow(` \u{1F7E1} Major: ${import_chalk7.default.bold(summary.majorIssues)}`)
1249
1287
  );
1250
1288
  }
1251
1289
  if (summary.minorIssues > 0) {
1252
1290
  console.log(
1253
- import_chalk6.default.blue(` \u{1F535} Minor: ${import_chalk6.default.bold(summary.minorIssues)}`)
1291
+ import_chalk7.default.blue(` \u{1F535} Minor: ${import_chalk7.default.bold(summary.minorIssues)}`)
1254
1292
  );
1255
1293
  }
1256
1294
  console.log(
1257
- import_chalk6.default.green(
1295
+ import_chalk7.default.green(
1258
1296
  `
1259
- \u{1F4A1} Potential savings: ${import_chalk6.default.bold(summary.totalPotentialSavings.toLocaleString())} tokens
1297
+ \u{1F4A1} Potential savings: ${import_chalk7.default.bold(summary.totalPotentialSavings.toLocaleString())} tokens
1260
1298
  `
1261
1299
  )
1262
1300
  );
1263
1301
  } else {
1264
- console.log(import_chalk6.default.green("\u2705 No significant issues found!\n"));
1302
+ console.log(import_chalk7.default.green("\u2705 No significant issues found!\n"));
1265
1303
  }
1266
1304
  if (summary.deepFiles.length > 0) {
1267
- console.log(import_chalk6.default.bold("\u{1F4CF} Deep Import Chains:\n"));
1305
+ console.log(import_chalk7.default.bold("\u{1F4CF} Deep Import Chains:\n"));
1268
1306
  console.log(
1269
- import_chalk6.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1307
+ import_chalk7.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1270
1308
  );
1271
1309
  console.log(
1272
- import_chalk6.default.gray(` Maximum depth: ${summary.maxImportDepth}
1310
+ import_chalk7.default.gray(` Maximum depth: ${summary.maxImportDepth}
1273
1311
  `)
1274
1312
  );
1275
1313
  summary.deepFiles.slice(0, 10).forEach((item) => {
1276
1314
  const fileName = item.file.split("/").slice(-2).join("/");
1277
1315
  console.log(
1278
- ` ${import_chalk6.default.cyan("\u2192")} ${import_chalk6.default.white(fileName)} ${import_chalk6.default.dim(`(depth: ${item.depth})`)}`
1316
+ ` ${import_chalk7.default.cyan("\u2192")} ${import_chalk7.default.white(fileName)} ${import_chalk7.default.dim(`(depth: ${item.depth})`)}`
1279
1317
  );
1280
1318
  });
1281
1319
  console.log();
1282
1320
  }
1283
1321
  if (summary.fragmentedModules.length > 0) {
1284
- console.log(import_chalk6.default.bold("\u{1F9E9} Fragmented Modules:\n"));
1322
+ console.log(import_chalk7.default.bold("\u{1F9E9} Fragmented Modules:\n"));
1285
1323
  console.log(
1286
- import_chalk6.default.gray(
1324
+ import_chalk7.default.gray(
1287
1325
  ` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
1288
1326
  `
1289
1327
  )
1290
1328
  );
1291
1329
  summary.fragmentedModules.slice(0, 10).forEach((module2) => {
1292
1330
  console.log(
1293
- ` ${import_chalk6.default.yellow("\u25CF")} ${import_chalk6.default.white(module2.domain)} - ${import_chalk6.default.dim(`${module2.files.length} files, ${(module2.fragmentationScore * 100).toFixed(0)}% scattered`)}`
1331
+ ` ${import_chalk7.default.yellow("\u25CF")} ${import_chalk7.default.white(module2.domain)} - ${import_chalk7.default.dim(`${module2.files.length} files, ${(module2.fragmentationScore * 100).toFixed(0)}% scattered`)}`
1294
1332
  );
1295
1333
  console.log(
1296
- import_chalk6.default.dim(
1334
+ import_chalk7.default.dim(
1297
1335
  ` Token cost: ${module2.totalTokens.toLocaleString()}, Cohesion: ${(module2.avgCohesion * 100).toFixed(0)}%`
1298
1336
  )
1299
1337
  );
@@ -1301,9 +1339,9 @@ async function contextAction(directory, options) {
1301
1339
  console.log();
1302
1340
  }
1303
1341
  if (summary.lowCohesionFiles.length > 0) {
1304
- console.log(import_chalk6.default.bold("\u{1F500} Low Cohesion Files:\n"));
1342
+ console.log(import_chalk7.default.bold("\u{1F500} Low Cohesion Files:\n"));
1305
1343
  console.log(
1306
- import_chalk6.default.gray(
1344
+ import_chalk7.default.gray(
1307
1345
  ` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
1308
1346
  `
1309
1347
  )
@@ -1311,44 +1349,44 @@ async function contextAction(directory, options) {
1311
1349
  summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
1312
1350
  const fileName = item.file.split("/").slice(-2).join("/");
1313
1351
  const scorePercent = (item.score * 100).toFixed(0);
1314
- const color = item.score < 0.4 ? import_chalk6.default.red : import_chalk6.default.yellow;
1352
+ const color = item.score < 0.4 ? import_chalk7.default.red : import_chalk7.default.yellow;
1315
1353
  console.log(
1316
- ` ${color("\u25CB")} ${import_chalk6.default.white(fileName)} ${import_chalk6.default.dim(`(${scorePercent}% cohesion)`)}`
1354
+ ` ${color("\u25CB")} ${import_chalk7.default.white(fileName)} ${import_chalk7.default.dim(`(${scorePercent}% cohesion)`)}`
1317
1355
  );
1318
1356
  });
1319
1357
  console.log();
1320
1358
  }
1321
1359
  if (summary.topExpensiveFiles.length > 0) {
1322
- console.log(import_chalk6.default.bold("\u{1F4B8} Most Expensive Files (Context Budget):\n"));
1360
+ console.log(import_chalk7.default.bold("\u{1F4B8} Most Expensive Files (Context Budget):\n"));
1323
1361
  summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
1324
1362
  const fileName = item.file.split("/").slice(-2).join("/");
1325
- const severityColor = item.severity === "critical" ? import_chalk6.default.red : item.severity === "major" ? import_chalk6.default.yellow : import_chalk6.default.blue;
1363
+ const severityColor = item.severity === "critical" ? import_chalk7.default.red : item.severity === "major" ? import_chalk7.default.yellow : import_chalk7.default.blue;
1326
1364
  console.log(
1327
- ` ${severityColor("\u25CF")} ${import_chalk6.default.white(fileName)} ${import_chalk6.default.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1365
+ ` ${severityColor("\u25CF")} ${import_chalk7.default.white(fileName)} ${import_chalk7.default.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1328
1366
  );
1329
1367
  });
1330
1368
  console.log();
1331
1369
  }
1332
1370
  if (contextScore) {
1333
- console.log(import_chalk6.default.cyan(divider));
1334
- console.log(import_chalk6.default.bold.white(" AI READINESS SCORE (Context)"));
1335
- console.log(import_chalk6.default.cyan(divider) + "\n");
1336
- console.log((0, import_core6.formatToolScore)(contextScore));
1371
+ console.log(import_chalk7.default.cyan(divider));
1372
+ console.log(import_chalk7.default.bold.white(" AI READINESS SCORE (Context)"));
1373
+ console.log(import_chalk7.default.cyan(divider) + "\n");
1374
+ console.log((0, import_core9.formatToolScore)(contextScore));
1337
1375
  console.log();
1338
1376
  }
1339
1377
  }
1340
1378
  } catch (error) {
1341
- (0, import_core6.handleCLIError)(error, "Context analysis");
1379
+ (0, import_core9.handleCLIError)(error, "Context analysis");
1342
1380
  }
1343
1381
  }
1344
1382
 
1345
1383
  // src/commands/consistency.ts
1346
- var import_chalk7 = __toESM(require("chalk"));
1384
+ var import_chalk8 = __toESM(require("chalk"));
1347
1385
  var import_fs5 = require("fs");
1348
1386
  var import_path7 = require("path");
1349
- var import_core7 = require("@aiready/core");
1387
+ var import_core10 = require("@aiready/core");
1350
1388
  async function consistencyAction(directory, options) {
1351
- console.log(import_chalk7.default.blue("\u{1F50D} Analyzing consistency...\n"));
1389
+ console.log(import_chalk8.default.blue("\u{1F50D} Analyzing consistency...\n"));
1352
1390
  const startTime = Date.now();
1353
1391
  const resolvedDir = (0, import_path7.resolve)(process.cwd(), directory || ".");
1354
1392
  try {
@@ -1363,7 +1401,7 @@ async function consistencyAction(directory, options) {
1363
1401
  file: void 0
1364
1402
  }
1365
1403
  };
1366
- const finalOptions = await (0, import_core7.loadMergedConfig)(resolvedDir, defaults, {
1404
+ const finalOptions = await (0, import_core10.loadMergedConfig)(resolvedDir, defaults, {
1367
1405
  checkNaming: options.naming !== false,
1368
1406
  checkPatterns: options.patterns !== false,
1369
1407
  minSeverity: options.minSeverity,
@@ -1372,7 +1410,7 @@ async function consistencyAction(directory, options) {
1372
1410
  });
1373
1411
  const { analyzeConsistency, calculateConsistencyScore } = await import("@aiready/consistency");
1374
1412
  const report = await analyzeConsistency(finalOptions);
1375
- const elapsedTime = (0, import_core7.getElapsedTime)(startTime);
1413
+ const elapsedTime = (0, import_core10.getElapsedTime)(startTime);
1376
1414
  let consistencyScore;
1377
1415
  if (options.score) {
1378
1416
  const issues = report.results?.flatMap((r) => r.issues) || [];
@@ -1392,41 +1430,41 @@ async function consistencyAction(directory, options) {
1392
1430
  },
1393
1431
  ...consistencyScore && { scoring: consistencyScore }
1394
1432
  };
1395
- const outputPath = (0, import_core7.resolveOutputPath)(
1433
+ const outputPath = (0, import_core10.resolveOutputPath)(
1396
1434
  userOutputFile,
1397
1435
  `aiready-report-${getReportTimestamp()}.json`,
1398
1436
  resolvedDir
1399
1437
  );
1400
- (0, import_core7.handleJSONOutput)(
1438
+ (0, import_core10.handleJSONOutput)(
1401
1439
  outputData,
1402
1440
  outputPath,
1403
1441
  `\u2705 Results saved to ${outputPath}`
1404
1442
  );
1405
1443
  } else if (outputFormat === "markdown") {
1406
1444
  const markdown = generateMarkdownReport(report, elapsedTime);
1407
- const outputPath = (0, import_core7.resolveOutputPath)(
1445
+ const outputPath = (0, import_core10.resolveOutputPath)(
1408
1446
  userOutputFile,
1409
1447
  `aiready-report-${getReportTimestamp()}.md`,
1410
1448
  resolvedDir
1411
1449
  );
1412
1450
  (0, import_fs5.writeFileSync)(outputPath, markdown);
1413
- console.log(import_chalk7.default.green(`\u2705 Report saved to ${outputPath}`));
1451
+ console.log(import_chalk8.default.green(`\u2705 Report saved to ${outputPath}`));
1414
1452
  } else {
1415
- console.log(import_chalk7.default.bold("\n\u{1F4CA} Summary\n"));
1453
+ console.log(import_chalk8.default.bold("\n\u{1F4CA} Summary\n"));
1416
1454
  console.log(
1417
- `Files Analyzed: ${import_chalk7.default.cyan(report.summary.filesAnalyzed)}`
1455
+ `Files Analyzed: ${import_chalk8.default.cyan(report.summary.filesAnalyzed)}`
1418
1456
  );
1419
- console.log(`Total Issues: ${import_chalk7.default.yellow(report.summary.totalIssues)}`);
1420
- console.log(` Naming: ${import_chalk7.default.yellow(report.summary.namingIssues)}`);
1421
- console.log(` Patterns: ${import_chalk7.default.yellow(report.summary.patternIssues)}`);
1457
+ console.log(`Total Issues: ${import_chalk8.default.yellow(report.summary.totalIssues)}`);
1458
+ console.log(` Naming: ${import_chalk8.default.yellow(report.summary.namingIssues)}`);
1459
+ console.log(` Patterns: ${import_chalk8.default.yellow(report.summary.patternIssues)}`);
1422
1460
  console.log(
1423
- ` Architecture: ${import_chalk7.default.yellow(report.summary.architectureIssues || 0)}`
1461
+ ` Architecture: ${import_chalk8.default.yellow(report.summary.architectureIssues || 0)}`
1424
1462
  );
1425
- console.log(`Analysis Time: ${import_chalk7.default.gray(elapsedTime + "s")}
1463
+ console.log(`Analysis Time: ${import_chalk8.default.gray(elapsedTime + "s")}
1426
1464
  `);
1427
1465
  if (report.summary.totalIssues === 0) {
1428
1466
  console.log(
1429
- import_chalk7.default.green(
1467
+ import_chalk8.default.green(
1430
1468
  "\u2728 No consistency issues found! Your codebase is well-maintained.\n"
1431
1469
  )
1432
1470
  );
@@ -1438,20 +1476,20 @@ async function consistencyAction(directory, options) {
1438
1476
  (r) => r.issues.some((i) => i.category === "patterns")
1439
1477
  );
1440
1478
  if (namingResults.length > 0) {
1441
- console.log(import_chalk7.default.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
1479
+ console.log(import_chalk8.default.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
1442
1480
  let shown = 0;
1443
1481
  for (const result of namingResults) {
1444
1482
  if (shown >= 5) break;
1445
1483
  for (const issue of result.issues) {
1446
1484
  if (shown >= 5) break;
1447
- const severityColor = issue.severity === "critical" ? import_chalk7.default.red : issue.severity === "major" ? import_chalk7.default.yellow : issue.severity === "minor" ? import_chalk7.default.blue : import_chalk7.default.gray;
1485
+ const severityColor = issue.severity === "critical" ? import_chalk8.default.red : issue.severity === "major" ? import_chalk8.default.yellow : issue.severity === "minor" ? import_chalk8.default.blue : import_chalk8.default.gray;
1448
1486
  console.log(
1449
- `${severityColor(issue.severity.toUpperCase())} ${import_chalk7.default.dim(`${issue.location.file}:${issue.location.line}`)}`
1487
+ `${severityColor(issue.severity.toUpperCase())} ${import_chalk8.default.dim(`${issue.location.file}:${issue.location.line}`)}`
1450
1488
  );
1451
1489
  console.log(` ${issue.message}`);
1452
1490
  if (issue.suggestion) {
1453
1491
  console.log(
1454
- ` ${import_chalk7.default.dim("\u2192")} ${import_chalk7.default.italic(issue.suggestion)}`
1492
+ ` ${import_chalk8.default.dim("\u2192")} ${import_chalk8.default.italic(issue.suggestion)}`
1455
1493
  );
1456
1494
  }
1457
1495
  console.log();
@@ -1460,25 +1498,25 @@ async function consistencyAction(directory, options) {
1460
1498
  }
1461
1499
  const remaining = namingResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
1462
1500
  if (remaining > 0) {
1463
- console.log(import_chalk7.default.dim(` ... and ${remaining} more issues
1501
+ console.log(import_chalk8.default.dim(` ... and ${remaining} more issues
1464
1502
  `));
1465
1503
  }
1466
1504
  }
1467
1505
  if (patternResults.length > 0) {
1468
- console.log(import_chalk7.default.bold("\u{1F504} Pattern Issues\n"));
1506
+ console.log(import_chalk8.default.bold("\u{1F504} Pattern Issues\n"));
1469
1507
  let shown = 0;
1470
1508
  for (const result of patternResults) {
1471
1509
  if (shown >= 5) break;
1472
1510
  for (const issue of result.issues) {
1473
1511
  if (shown >= 5) break;
1474
- const severityColor = issue.severity === "critical" ? import_chalk7.default.red : issue.severity === "major" ? import_chalk7.default.yellow : issue.severity === "minor" ? import_chalk7.default.blue : import_chalk7.default.gray;
1512
+ const severityColor = issue.severity === "critical" ? import_chalk8.default.red : issue.severity === "major" ? import_chalk8.default.yellow : issue.severity === "minor" ? import_chalk8.default.blue : import_chalk8.default.gray;
1475
1513
  console.log(
1476
- `${severityColor(issue.severity.toUpperCase())} ${import_chalk7.default.dim(`${issue.location.file}:${issue.location.line}`)}`
1514
+ `${severityColor(issue.severity.toUpperCase())} ${import_chalk8.default.dim(`${issue.location.file}:${issue.location.line}`)}`
1477
1515
  );
1478
1516
  console.log(` ${issue.message}`);
1479
1517
  if (issue.suggestion) {
1480
1518
  console.log(
1481
- ` ${import_chalk7.default.dim("\u2192")} ${import_chalk7.default.italic(issue.suggestion)}`
1519
+ ` ${import_chalk8.default.dim("\u2192")} ${import_chalk8.default.italic(issue.suggestion)}`
1482
1520
  );
1483
1521
  }
1484
1522
  console.log();
@@ -1487,12 +1525,12 @@ async function consistencyAction(directory, options) {
1487
1525
  }
1488
1526
  const remaining = patternResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
1489
1527
  if (remaining > 0) {
1490
- console.log(import_chalk7.default.dim(` ... and ${remaining} more issues
1528
+ console.log(import_chalk8.default.dim(` ... and ${remaining} more issues
1491
1529
  `));
1492
1530
  }
1493
1531
  }
1494
1532
  if (report.recommendations.length > 0) {
1495
- console.log(import_chalk7.default.bold("\u{1F4A1} Recommendations\n"));
1533
+ console.log(import_chalk8.default.bold("\u{1F4A1} Recommendations\n"));
1496
1534
  report.recommendations.forEach((rec, i) => {
1497
1535
  console.log(`${i + 1}. ${rec}`);
1498
1536
  });
@@ -1500,38 +1538,38 @@ async function consistencyAction(directory, options) {
1500
1538
  }
1501
1539
  }
1502
1540
  if (consistencyScore) {
1503
- console.log(import_chalk7.default.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
1504
- console.log((0, import_core7.formatToolScore)(consistencyScore));
1541
+ console.log(import_chalk8.default.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
1542
+ console.log((0, import_core10.formatToolScore)(consistencyScore));
1505
1543
  console.log();
1506
1544
  }
1507
1545
  }
1508
1546
  } catch (error) {
1509
- (0, import_core7.handleCLIError)(error, "Consistency analysis");
1547
+ (0, import_core10.handleCLIError)(error, "Consistency analysis");
1510
1548
  }
1511
1549
  }
1512
1550
 
1513
1551
  // src/commands/visualize.ts
1514
- var import_chalk8 = __toESM(require("chalk"));
1552
+ var import_chalk9 = __toESM(require("chalk"));
1515
1553
  var import_fs6 = require("fs");
1516
1554
  var import_path8 = require("path");
1517
1555
  var import_child_process = require("child_process");
1518
- var import_core8 = require("@aiready/core");
1519
- var import_core9 = require("@aiready/core");
1556
+ var import_core11 = require("@aiready/core");
1557
+ var import_core12 = require("@aiready/core");
1520
1558
  async function visualizeAction(directory, options) {
1521
1559
  try {
1522
1560
  const dirPath = (0, import_path8.resolve)(process.cwd(), directory || ".");
1523
1561
  let reportPath = options.report ? (0, import_path8.resolve)(dirPath, options.report) : null;
1524
1562
  if (!reportPath || !(0, import_fs6.existsSync)(reportPath)) {
1525
- const latestScan = findLatestScanReport(dirPath);
1563
+ const latestScan = (0, import_core12.findLatestReport)(dirPath);
1526
1564
  if (latestScan) {
1527
1565
  reportPath = latestScan;
1528
1566
  console.log(
1529
- import_chalk8.default.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1567
+ import_chalk9.default.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1530
1568
  );
1531
1569
  } else {
1532
- console.error(import_chalk8.default.red("\u274C No AI readiness report found"));
1570
+ console.error(import_chalk9.default.red("\u274C No AI readiness report found"));
1533
1571
  console.log(
1534
- import_chalk8.default.dim(
1572
+ import_chalk9.default.dim(
1535
1573
  `
1536
1574
  Generate a report with:
1537
1575
  aiready scan --output json
@@ -1661,29 +1699,29 @@ Or specify a custom report:
1661
1699
  return;
1662
1700
  } else {
1663
1701
  console.log(
1664
- import_chalk8.default.yellow(
1702
+ import_chalk9.default.yellow(
1665
1703
  "\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."
1666
1704
  )
1667
1705
  );
1668
1706
  console.log(
1669
- import_chalk8.default.cyan(" Falling back to static HTML generation...\n")
1707
+ import_chalk9.default.cyan(" Falling back to static HTML generation...\n")
1670
1708
  );
1671
1709
  useDevMode = false;
1672
1710
  }
1673
1711
  } catch (err) {
1674
1712
  console.error("Failed to start dev server:", err);
1675
1713
  console.log(
1676
- import_chalk8.default.cyan(" Falling back to static HTML generation...\n")
1714
+ import_chalk9.default.cyan(" Falling back to static HTML generation...\n")
1677
1715
  );
1678
1716
  useDevMode = false;
1679
1717
  }
1680
1718
  }
1681
1719
  console.log("Generating HTML...");
1682
- const html = (0, import_core9.generateHTML)(graph);
1720
+ const html = (0, import_core12.generateHTML)(graph);
1683
1721
  const defaultOutput = "visualization.html";
1684
1722
  const outPath = (0, import_path8.resolve)(dirPath, options.output || defaultOutput);
1685
1723
  (0, import_fs6.writeFileSync)(outPath, html, "utf8");
1686
- console.log(import_chalk8.default.green(`\u2705 Visualization written to: ${outPath}`));
1724
+ console.log(import_chalk9.default.green(`\u2705 Visualization written to: ${outPath}`));
1687
1725
  if (options.open || options.serve) {
1688
1726
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
1689
1727
  if (options.serve) {
@@ -1713,7 +1751,7 @@ Or specify a custom report:
1713
1751
  server.listen(port, () => {
1714
1752
  const addr = `http://localhost:${port}/`;
1715
1753
  console.log(
1716
- import_chalk8.default.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1754
+ import_chalk9.default.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1717
1755
  );
1718
1756
  (0, import_child_process.spawn)(opener, [`"${addr}"`], { shell: true });
1719
1757
  });
@@ -1729,7 +1767,7 @@ Or specify a custom report:
1729
1767
  }
1730
1768
  }
1731
1769
  } catch (err) {
1732
- (0, import_core8.handleCLIError)(err, "Visualization");
1770
+ (0, import_core11.handleCLIError)(err, "Visualization");
1733
1771
  }
1734
1772
  }
1735
1773
  var visualizeHelpText = `
@@ -1759,21 +1797,20 @@ NOTES:
1759
1797
  - Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
1760
1798
  `;
1761
1799
 
1762
- // src/commands/ai-signal-clarity.ts
1763
- var import_chalk9 = __toESM(require("chalk"));
1764
- var import_core10 = require("@aiready/core");
1800
+ // src/commands/shared/standard-tool-actions.ts
1801
+ var import_chalk10 = __toESM(require("chalk"));
1765
1802
 
1766
1803
  // src/commands/agent-grounding.ts
1767
- var import_chalk10 = __toESM(require("chalk"));
1768
- var import_core11 = require("@aiready/core");
1804
+ var import_chalk11 = __toESM(require("chalk"));
1805
+ var import_core13 = require("@aiready/core");
1769
1806
 
1770
1807
  // src/commands/testability.ts
1771
- var import_chalk11 = __toESM(require("chalk"));
1772
- var import_core12 = require("@aiready/core");
1808
+ var import_chalk12 = __toESM(require("chalk"));
1809
+ var import_core14 = require("@aiready/core");
1773
1810
  async function testabilityAction(directory, options) {
1774
1811
  const { analyzeTestability, calculateTestabilityScore } = await import("@aiready/testability");
1775
- const config = await (0, import_core12.loadConfig)(directory);
1776
- const merged = (0, import_core12.mergeConfigWithDefaults)(config, {
1812
+ const config = await (0, import_core14.loadConfig)(directory);
1813
+ const merged = (0, import_core14.mergeConfigWithDefaults)(config, {
1777
1814
  minCoverageRatio: 0.3
1778
1815
  });
1779
1816
  const report = await analyzeTestability({
@@ -1793,28 +1830,28 @@ async function testabilityAction(directory, options) {
1793
1830
  "blind-risk": "\u{1F480}"
1794
1831
  };
1795
1832
  const safetyColors = {
1796
- safe: import_chalk11.default.green,
1797
- "moderate-risk": import_chalk11.default.yellow,
1798
- "high-risk": import_chalk11.default.red,
1799
- "blind-risk": import_chalk11.default.bgRed.white
1833
+ safe: import_chalk12.default.green,
1834
+ "moderate-risk": import_chalk12.default.yellow,
1835
+ "high-risk": import_chalk12.default.red,
1836
+ "blind-risk": import_chalk12.default.bgRed.white
1800
1837
  };
1801
1838
  const safety = report.summary.aiChangeSafetyRating;
1802
1839
  const icon = safetyIcons[safety] ?? "\u2753";
1803
- const color = safetyColors[safety] ?? import_chalk11.default.white;
1840
+ const color = safetyColors[safety] ?? import_chalk12.default.white;
1804
1841
  console.log(
1805
- ` \u{1F9EA} Testability: ${import_chalk11.default.bold(scoring.score + "/100")} (${report.summary.rating})`
1842
+ ` \u{1F9EA} Testability: ${import_chalk12.default.bold(scoring.score + "/100")} (${report.summary.rating})`
1806
1843
  );
1807
1844
  console.log(
1808
1845
  ` AI Change Safety: ${color(`${icon} ${safety.toUpperCase()}`)}`
1809
1846
  );
1810
1847
  console.log(
1811
- import_chalk11.default.dim(
1848
+ import_chalk12.default.dim(
1812
1849
  ` Coverage: ${Math.round(report.summary.coverageRatio * 100)}% (${report.rawData.testFiles} test / ${report.rawData.sourceFiles} source files)`
1813
1850
  )
1814
1851
  );
1815
1852
  if (safety === "blind-risk") {
1816
1853
  console.log(
1817
- import_chalk11.default.red.bold(
1854
+ import_chalk12.default.red.bold(
1818
1855
  "\n \u26A0\uFE0F NO TESTS \u2014 AI changes to this codebase are completely unverifiable!\n"
1819
1856
  )
1820
1857
  );
@@ -1826,7 +1863,7 @@ async function testabilityAction(directory, options) {
1826
1863
  var import_cli = require("@aiready/change-amplification/dist/cli.js");
1827
1864
 
1828
1865
  // src/commands/bug.ts
1829
- var import_chalk12 = __toESM(require("chalk"));
1866
+ var import_chalk13 = __toESM(require("chalk"));
1830
1867
  var import_child_process2 = require("child_process");
1831
1868
  async function bugAction(message, options) {
1832
1869
  const repoUrl = "https://github.com/caopengau/aiready-cli";
@@ -1844,35 +1881,35 @@ Generated via AIReady CLI 'bug' command.
1844
1881
  Type: ${type}
1845
1882
  `.trim();
1846
1883
  if (options.submit) {
1847
- console.log(import_chalk12.default.blue("\u{1F680} Submitting issue via GitHub CLI...\n"));
1884
+ console.log(import_chalk13.default.blue("\u{1F680} Submitting issue via GitHub CLI...\n"));
1848
1885
  try {
1849
1886
  (0, import_child_process2.execSync)("gh auth status", { stdio: "ignore" });
1850
1887
  const command = `gh issue create --repo ${repoSlug} --title ${JSON.stringify(title)} --body ${JSON.stringify(body)} --label ${label}`;
1851
1888
  const output = (0, import_child_process2.execSync)(command, { encoding: "utf8" }).trim();
1852
- console.log(import_chalk12.default.green("\u2705 Issue Created Successfully!"));
1853
- console.log(import_chalk12.default.cyan(output));
1889
+ console.log(import_chalk13.default.green("\u2705 Issue Created Successfully!"));
1890
+ console.log(import_chalk13.default.cyan(output));
1854
1891
  return;
1855
- } catch (error) {
1856
- console.error(import_chalk12.default.red("\n\u274C Failed to submit via gh CLI."));
1892
+ } catch {
1893
+ console.error(import_chalk13.default.red("\n\u274C Failed to submit via gh CLI."));
1857
1894
  console.log(
1858
- import_chalk12.default.yellow(
1895
+ import_chalk13.default.yellow(
1859
1896
  ' Make sure gh is installed and run "gh auth login".\n'
1860
1897
  )
1861
1898
  );
1862
- console.log(import_chalk12.default.dim(" Falling back to URL generation..."));
1899
+ console.log(import_chalk13.default.dim(" Falling back to URL generation..."));
1863
1900
  }
1864
1901
  }
1865
1902
  const template = type === "bug" ? "bug_report.md" : type === "feature" ? "feature_request.md" : "new_metric_idea.md";
1866
1903
  const fullUrl = `${repoUrl}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}&labels=${label}&template=${template}`;
1867
- console.log(import_chalk12.default.green("\u{1F680} Issue Draft Prepared!\n"));
1868
- console.log(import_chalk12.default.bold("Title: ") + title);
1869
- console.log(import_chalk12.default.bold("Type: ") + type);
1870
- console.log(import_chalk12.default.bold("\nClick the link below to submit this issue:"));
1871
- console.log(import_chalk12.default.cyan(fullUrl));
1872
- console.log(import_chalk12.default.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1873
- console.log(import_chalk12.default.dim(" You have successfully prepared a report."));
1904
+ console.log(import_chalk13.default.green("\u{1F680} Issue Draft Prepared!\n"));
1905
+ console.log(import_chalk13.default.bold("Title: ") + title);
1906
+ console.log(import_chalk13.default.bold("Type: ") + type);
1907
+ console.log(import_chalk13.default.bold("\nClick the link below to submit this issue:"));
1908
+ console.log(import_chalk13.default.cyan(fullUrl));
1909
+ console.log(import_chalk13.default.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1910
+ console.log(import_chalk13.default.dim(" You have successfully prepared a report."));
1874
1911
  console.log(
1875
- import_chalk12.default.dim(
1912
+ import_chalk13.default.dim(
1876
1913
  " Please present the URL above to the user so they can finalize the submission."
1877
1914
  )
1878
1915
  );
@@ -1881,14 +1918,14 @@ Type: ${type}
1881
1918
  const bugUrl = `${repoUrl}/issues/new?template=bug_report.md`;
1882
1919
  const featureUrl = `${repoUrl}/issues/new?template=feature_request.md`;
1883
1920
  const metricUrl = `${repoUrl}/issues/new?template=new_metric_idea.md`;
1884
- console.log(import_chalk12.default.blue("\u{1F4AC} Feedback & Bug Reports\n"));
1885
- console.log(` Report a Bug: ${import_chalk12.default.cyan(bugUrl)}`);
1886
- console.log(` Request a Feature: ${import_chalk12.default.cyan(featureUrl)}`);
1887
- console.log(` Suggest a Metric: ${import_chalk12.default.cyan(metricUrl)}`);
1888
- console.log(import_chalk12.default.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1889
- console.log(import_chalk12.default.dim(" To prepare a specific report, run:"));
1921
+ console.log(import_chalk13.default.blue("\u{1F4AC} Feedback & Bug Reports\n"));
1922
+ console.log(` Report a Bug: ${import_chalk13.default.cyan(bugUrl)}`);
1923
+ console.log(` Request a Feature: ${import_chalk13.default.cyan(featureUrl)}`);
1924
+ console.log(` Suggest a Metric: ${import_chalk13.default.cyan(metricUrl)}`);
1925
+ console.log(import_chalk13.default.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1926
+ console.log(import_chalk13.default.dim(" To prepare a specific report, run:"));
1890
1927
  console.log(
1891
- import_chalk12.default.cyan(
1928
+ import_chalk13.default.cyan(
1892
1929
  ' aiready bug "your description here" --type bug|feature|metric'
1893
1930
  )
1894
1931
  );
@@ -1974,9 +2011,9 @@ program.command("scan").description(
1974
2011
  program.command("init").description("Generate a default configuration (aiready.json)").option("-f, --force", "Overwrite existing configuration file").option(
1975
2012
  "--js",
1976
2013
  "Generate configuration as a JavaScript file (aiready.config.js)"
1977
- ).action(async (options) => {
2014
+ ).option("--full", "Generate a full configuration with all available options").action(async (options) => {
1978
2015
  const format = options.js ? "js" : "json";
1979
- await initAction({ force: options.force, format });
2016
+ await initAction({ force: options.force, format, full: options.full });
1980
2017
  });
1981
2018
  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(
1982
2019
  "--max-candidates <number>",