@aiready/cli 0.10.3 → 0.10.6

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.
@@ -22,6 +22,9 @@ import {
22
22
  getRatingDisplay,
23
23
  parseWeightString,
24
24
  getRepoMetadata,
25
+ Severity,
26
+ IssueType,
27
+ ToolName,
25
28
  type ToolScoringOutput,
26
29
  } from '@aiready/core';
27
30
  import { analyzeUnified, scoreUnified, type ScoringResult } from '../index';
@@ -364,7 +367,7 @@ export async function scanAction(directory: string, options: ScanOptions) {
364
367
  // Count severities
365
368
  const counts = issues.reduce(
366
369
  (acc: any, it: any) => {
367
- const s = (it.severity || 'info').toLowerCase();
370
+ const s = (it.severity || Severity.Info).toLowerCase();
368
371
  acc[s] = (acc[s] || 0) + 1;
369
372
  return acc;
370
373
  },
@@ -374,12 +377,13 @@ export async function scanAction(directory: string, options: ScanOptions) {
374
377
  const sample =
375
378
  issues.find(
376
379
  (it: any) =>
377
- it.severity === 'critical' || it.severity === 'major'
380
+ it.severity === Severity.Critical ||
381
+ it.severity === Severity.Major
378
382
  ) || issues[0];
379
383
  const sampleMsg = sample ? ` — ${sample.message}` : '';
380
384
 
381
385
  console.log(
382
- ` ${idx + 1}. ${file} — ${issues.length} issue(s) (critical:${counts.critical || 0} major:${counts.major || 0} minor:${counts.minor || 0} info:${counts.info || 0})${sampleMsg}`
386
+ ` ${idx + 1}. ${file} — ${issues.length} issue(s) (critical:${counts[Severity.Critical] || 0} major:${counts[Severity.Major] || 0} minor:${counts[Severity.Minor] || 0} info:${counts[Severity.Info] || 0})${sampleMsg}`
383
387
  );
384
388
  });
385
389
 
@@ -462,30 +466,29 @@ export async function scanAction(directory: string, options: ScanOptions) {
462
466
  (finalOptions.tools || ['patterns', 'context', 'consistency']).join(', ')
463
467
  );
464
468
 
465
- // Results summary
466
469
  console.log(chalk.cyan('\nResults summary:'));
467
470
  console.log(
468
471
  ` Total issues (all tools): ${chalk.bold(String(results.summary.totalIssues || 0))}`
469
472
  );
470
- if (results.patternDetect) {
473
+ if (results[ToolName.PatternDetect]) {
471
474
  console.log(
472
- ` Duplicate patterns found: ${chalk.bold(String(results.patternDetect.duplicates?.length || 0))}`
475
+ ` Duplicate patterns found: ${chalk.bold(String(results[ToolName.PatternDetect].duplicates?.length || 0))}`
473
476
  );
474
477
  console.log(
475
- ` Pattern files with issues: ${chalk.bold(String(results.patternDetect.results.length || 0))}`
478
+ ` Pattern files with issues: ${chalk.bold(String(results[ToolName.PatternDetect].results.length || 0))}`
476
479
  );
477
480
  }
478
- if (results.contextAnalyzer)
481
+ if (results[ToolName.ContextAnalyzer])
479
482
  console.log(
480
- ` Context issues: ${chalk.bold(String(results.contextAnalyzer.results.length || 0))}`
483
+ ` Context issues: ${chalk.bold(String(results[ToolName.ContextAnalyzer].results.length || 0))}`
481
484
  );
482
- if (results.consistency)
485
+ if (results[ToolName.NamingConsistency])
483
486
  console.log(
484
- ` Consistency issues: ${chalk.bold(String(results.consistency.summary?.totalIssues || 0))}`
487
+ ` Consistency issues: ${chalk.bold(String(results[ToolName.NamingConsistency].summary?.totalIssues || 0))}`
485
488
  );
486
- if (results.changeAmplification)
489
+ if (results[ToolName.ChangeAmplification])
487
490
  console.log(
488
- ` Change amplification: ${chalk.bold(String(results.changeAmplification.summary?.score || 0))}/100`
491
+ ` Change amplification: ${chalk.bold(String(results[ToolName.ChangeAmplification].summary?.score || 0))}/100`
489
492
  );
490
493
  console.log(chalk.cyan('===========================\n'));
491
494
 
@@ -653,6 +656,114 @@ export async function scanAction(directory: string, options: ScanOptions) {
653
656
  }
654
657
  }
655
658
 
659
+ // Helper to map CLI results to UnifiedReport schema
660
+ const mapToUnifiedReport = (
661
+ res: any,
662
+ scoring: ScoringResult | undefined
663
+ ) => {
664
+ const allResults: any[] = [];
665
+ let totalFilesSet = new Set<string>();
666
+ let criticalCount = 0;
667
+ let majorCount = 0;
668
+
669
+ // Collect from all spokes and normalize to AnalysisResult
670
+ const collect = (
671
+ spokeRes: any,
672
+ defaultType: IssueType = IssueType.AiSignalClarity
673
+ ) => {
674
+ if (!spokeRes || !spokeRes.results) return;
675
+ spokeRes.results.forEach((r: any) => {
676
+ const fileName = r.fileName || r.file || 'unknown';
677
+ totalFilesSet.add(fileName);
678
+
679
+ // Enforce strict AnalysisResult schema
680
+ const normalizedResult = {
681
+ fileName,
682
+ issues: [] as any[],
683
+ metrics: r.metrics || { tokenCost: r.tokenCost || 0 },
684
+ };
685
+
686
+ if (r.issues && Array.isArray(r.issues)) {
687
+ r.issues.forEach((i: any) => {
688
+ const normalizedIssue =
689
+ typeof i === 'string'
690
+ ? {
691
+ type: defaultType,
692
+ severity: (r.severity || Severity.Info) as Severity,
693
+ message: i,
694
+ location: { file: fileName, line: 1 },
695
+ }
696
+ : {
697
+ type: i.type || defaultType,
698
+ severity: (i.severity ||
699
+ r.severity ||
700
+ Severity.Info) as Severity,
701
+ message: i.message || String(i),
702
+ location: i.location || { file: fileName, line: 1 },
703
+ suggestion: i.suggestion,
704
+ };
705
+
706
+ if (
707
+ normalizedIssue.severity === Severity.Critical ||
708
+ normalizedIssue.severity === 'critical'
709
+ )
710
+ criticalCount++;
711
+ if (
712
+ normalizedIssue.severity === Severity.Major ||
713
+ normalizedIssue.severity === 'major'
714
+ )
715
+ majorCount++;
716
+
717
+ normalizedResult.issues.push(normalizedIssue);
718
+ });
719
+ } else if (r.severity) {
720
+ // handle context-analyzer style if issues missing but severity present
721
+ const normalizedIssue = {
722
+ type: defaultType,
723
+ severity: r.severity as Severity,
724
+ message: r.message || 'General issue',
725
+ location: { file: fileName, line: 1 },
726
+ };
727
+ if (
728
+ normalizedIssue.severity === Severity.Critical ||
729
+ normalizedIssue.severity === 'critical'
730
+ )
731
+ criticalCount++;
732
+ if (
733
+ normalizedIssue.severity === Severity.Major ||
734
+ normalizedIssue.severity === 'major'
735
+ )
736
+ majorCount++;
737
+ normalizedResult.issues.push(normalizedIssue);
738
+ }
739
+
740
+ allResults.push(normalizedResult);
741
+ });
742
+ };
743
+
744
+ collect(res[ToolName.PatternDetect], IssueType.DuplicatePattern);
745
+ collect(res[ToolName.ContextAnalyzer], IssueType.ContextFragmentation);
746
+ collect(res[ToolName.NamingConsistency], IssueType.NamingInconsistency);
747
+ collect(res[ToolName.DocDrift], IssueType.DocDrift);
748
+ collect(res[ToolName.DependencyHealth], IssueType.DependencyHealth);
749
+ collect(res[ToolName.AiSignalClarity], IssueType.AiSignalClarity);
750
+ collect(res[ToolName.AgentGrounding], IssueType.AgentNavigationFailure);
751
+ collect(res[ToolName.TestabilityIndex], IssueType.LowTestability);
752
+ collect(res[ToolName.ChangeAmplification], IssueType.ChangeAmplification);
753
+
754
+ return {
755
+ ...res,
756
+ results: allResults,
757
+ summary: {
758
+ ...res.summary,
759
+ totalFiles: totalFilesSet.size,
760
+ criticalIssues: criticalCount,
761
+ majorIssues: majorCount,
762
+ },
763
+ scoring: scoring,
764
+ };
765
+ };
766
+
656
767
  // Persist JSON summary when output format is json
657
768
  const outputFormat =
658
769
  options.output || finalOptions.output?.format || 'console';
@@ -666,8 +777,7 @@ export async function scanAction(directory: string, options: ScanOptions) {
666
777
  resolvedDir
667
778
  );
668
779
  const outputData = {
669
- ...results,
670
- scoring: scoringResult,
780
+ ...mapToUnifiedReport(results, scoringResult),
671
781
  repository: repoMetadata,
672
782
  };
673
783
  handleJSONOutput(
@@ -697,8 +807,7 @@ export async function scanAction(directory: string, options: ScanOptions) {
697
807
  resolvedDir
698
808
  );
699
809
  const outputData = {
700
- ...results,
701
- scoring: scoringResult,
810
+ ...mapToUnifiedReport(results, scoringResult),
702
811
  repository: repoMetadata,
703
812
  };
704
813
 
@@ -755,10 +864,13 @@ export async function scanAction(directory: string, options: ScanOptions) {
755
864
  }
756
865
 
757
866
  // Output annotations for critical issues
758
- if (results.patternDetect) {
759
- const criticalPatterns = results.patternDetect.results.flatMap(
760
- (p: any) => p.issues.filter((i: any) => i.severity === 'critical')
867
+ if (results[ToolName.PatternDetect]) {
868
+ const criticalPatterns = results[
869
+ ToolName.PatternDetect
870
+ ].results.flatMap((p: any) =>
871
+ p.issues.filter((i: any) => i.severity === Severity.Critical)
761
872
  );
873
+
762
874
  criticalPatterns.slice(0, 10).forEach((issue: any) => {
763
875
  console.log(
764
876
  `::warning file=${issue.location?.file || 'unknown'},line=${issue.location?.line || 1}::${issue.message}`
@@ -786,25 +898,25 @@ export async function scanAction(directory: string, options: ScanOptions) {
786
898
  let criticalCount = 0;
787
899
  let majorCount = 0;
788
900
 
789
- if (results.patternDetect) {
790
- results.patternDetect.results.forEach((p: any) => {
901
+ if (results[ToolName.PatternDetect]) {
902
+ results[ToolName.PatternDetect].results.forEach((p: any) => {
791
903
  p.issues.forEach((i: any) => {
792
- if (i.severity === 'critical') criticalCount++;
793
- if (i.severity === 'major') majorCount++;
904
+ if (i.severity === Severity.Critical) criticalCount++;
905
+ if (i.severity === Severity.Major) majorCount++;
794
906
  });
795
907
  });
796
908
  }
797
- if (results.contextAnalyzer) {
798
- results.contextAnalyzer.results.forEach((c: any) => {
799
- if (c.severity === 'critical') criticalCount++;
800
- if (c.severity === 'major') majorCount++;
909
+ if (results[ToolName.ContextAnalyzer]) {
910
+ results[ToolName.ContextAnalyzer].results.forEach((c: any) => {
911
+ if (c.severity === Severity.Critical) criticalCount++;
912
+ if (c.severity === Severity.Major) majorCount++;
801
913
  });
802
914
  }
803
- if (results.consistency) {
804
- results.consistency.results.forEach((r: any) => {
915
+ if (results[ToolName.NamingConsistency]) {
916
+ results[ToolName.NamingConsistency].results.forEach((r: any) => {
805
917
  r.issues?.forEach((i: any) => {
806
- if (i.severity === 'critical') criticalCount++;
807
- if (i.severity === 'major') majorCount++;
918
+ if (i.severity === Severity.Critical) criticalCount++;
919
+ if (i.severity === Severity.Major) majorCount++;
808
920
  });
809
921
  });
810
922
  }