@aiready/consistency 0.20.2 → 0.20.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.
package/dist/cli.js CHANGED
@@ -353,7 +353,7 @@ function checkNamingConvention(name, convention, node, file, issues, context) {
353
353
  }
354
354
  }
355
355
  function checkVariableNaming(varInfo, file, issues, context) {
356
- const { name, node, line, options } = varInfo;
356
+ const { name, line, options } = varInfo;
357
357
  if (isAcceptableInContext(name, context, options)) {
358
358
  return;
359
359
  }
@@ -475,7 +475,6 @@ async function analyzeNamingGeneralized(files) {
475
475
  const conventions = parser.getNamingConventions();
476
476
  for (const exp of result.exports) {
477
477
  let pattern;
478
- const typeName = exp.type;
479
478
  if (exp.type === "class") {
480
479
  pattern = conventions.classPattern;
481
480
  } else if (exp.type === "interface" && conventions.interfacePattern) {
@@ -491,7 +490,7 @@ async function analyzeNamingGeneralized(files) {
491
490
  }
492
491
  if (pattern && !pattern.test(exp.name)) {
493
492
  issues.push({
494
- type: "poor-naming",
493
+ type: "naming-inconsistency",
495
494
  identifier: exp.name,
496
495
  file,
497
496
  line: exp.loc?.start.line || 1,
@@ -507,7 +506,7 @@ async function analyzeNamingGeneralized(files) {
507
506
  if (spec === "*" || spec === "default") continue;
508
507
  if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec)) {
509
508
  issues.push({
510
- type: "convention-mix",
509
+ type: "naming-inconsistency",
511
510
  identifier: spec,
512
511
  file,
513
512
  line: imp.loc?.start.line || 1,
@@ -533,7 +532,6 @@ async function analyzePatterns(filePaths) {
533
532
  const issues = [];
534
533
  const contents = /* @__PURE__ */ new Map();
535
534
  const tryCatchPattern = /try\s*\{/g;
536
- const catchPattern = /catch\s*\(\s*(\w+)\s*\)/g;
537
535
  const styleStats = {
538
536
  tryCatch: 0,
539
537
  thenCatch: 0,
@@ -554,7 +552,6 @@ async function analyzePatterns(filePaths) {
554
552
  void err;
555
553
  }
556
554
  }
557
- const totalFiles = filePaths.length;
558
555
  if (styleStats.tryCatch > 0 && styleStats.thenCatch > 0) {
559
556
  const dominant = styleStats.tryCatch >= styleStats.thenCatch ? "try-catch" : ".catch()";
560
557
  const minority = dominant === "try-catch" ? ".catch()" : "try-catch";
@@ -563,7 +560,7 @@ async function analyzePatterns(filePaths) {
563
560
  const c = contents.get(f) || "";
564
561
  return minority === "try-catch" ? c.match(tryCatchPattern) : c.match(/\.catch\s*\(/);
565
562
  }),
566
- type: "error-handling",
563
+ type: "pattern-inconsistency",
567
564
  description: `Mixed error handling styles: codebase primarily uses ${dominant}, but found ${minority} in some files.`,
568
565
  examples: [dominant, minority],
569
566
  severity: import_core4.Severity.Minor
@@ -576,7 +573,7 @@ async function analyzePatterns(filePaths) {
576
573
  const c = contents.get(f) || "";
577
574
  return minority === "CommonJS (require)" ? c.match(/\brequire\s*\(/) : c.match(/\bimport\b/);
578
575
  }),
579
- type: "import-style",
576
+ type: "pattern-inconsistency",
580
577
  description: `Mixed module systems: found both ESM and CommonJS.`,
581
578
  examples: ['import X from "y"', 'const X = require("y")'],
582
579
  severity: import_core4.Severity.Major
@@ -610,130 +607,126 @@ async function analyzeConsistency(options) {
610
607
  const results = [];
611
608
  const fileIssuesMap = /* @__PURE__ */ new Map();
612
609
  for (const issue of namingIssues) {
613
- if (!shouldIncludeSeverity(issue.severity, minSeverity)) {
614
- continue;
615
- }
616
- const consistencyIssue = {
617
- type: issue.type === "convention-mix" ? import_core5.IssueType.NamingInconsistency : import_core5.IssueType.NamingQuality,
618
- category: "naming",
619
- severity: getSeverityEnum(issue.severity),
620
- message: `${issue.type}: ${issue.identifier}`,
621
- location: {
622
- file: issue.file,
623
- line: issue.line,
624
- column: issue.column
625
- },
626
- suggestion: issue.suggestion
627
- };
628
- if (!fileIssuesMap.has(issue.file)) {
629
- fileIssuesMap.set(issue.file, []);
630
- }
631
- fileIssuesMap.get(issue.file).push(consistencyIssue);
610
+ if (!shouldIncludeSeverity(issue.severity, minSeverity)) continue;
611
+ const fileName = issue.fileName || issue.file || issue.filePath || "unknown";
612
+ if (!fileIssuesMap.has(fileName)) fileIssuesMap.set(fileName, []);
613
+ fileIssuesMap.get(fileName).push(issue);
632
614
  }
633
615
  for (const issue of patternIssues) {
634
- if (!shouldIncludeSeverity(issue.severity, minSeverity)) {
635
- continue;
636
- }
637
- const consistencyIssue = {
638
- type: import_core5.IssueType.PatternInconsistency,
639
- category: "patterns",
640
- severity: getSeverityEnum(issue.severity),
641
- message: issue.description,
642
- location: {
643
- file: issue.files[0] || "multiple files",
644
- line: 1
645
- },
646
- examples: issue.examples,
647
- suggestion: `Standardize ${issue.type} patterns across ${issue.files.length} files`
648
- };
649
- const firstFile = issue.files[0];
650
- if (firstFile && !fileIssuesMap.has(firstFile)) {
651
- fileIssuesMap.set(firstFile, []);
652
- }
653
- if (firstFile) {
654
- fileIssuesMap.get(firstFile).push(consistencyIssue);
655
- }
616
+ if (!shouldIncludeSeverity(issue.severity, minSeverity)) continue;
617
+ const fileName = issue.fileName || issue.file || issue.filePath || (Array.isArray(issue.files) ? issue.files[0] : "unknown");
618
+ if (!fileIssuesMap.has(fileName)) fileIssuesMap.set(fileName, []);
619
+ fileIssuesMap.get(fileName).push(issue);
656
620
  }
657
- for (const [fileName, issues] of fileIssuesMap) {
621
+ for (const [fileName, issues] of fileIssuesMap.entries()) {
658
622
  results.push({
659
623
  fileName,
660
- issues,
624
+ issues: issues.map((i) => transformToIssue(i)),
661
625
  metrics: {
662
626
  consistencyScore: calculateConsistencyScore(issues)
663
627
  }
664
628
  });
665
629
  }
666
- results.sort((fileResultA, fileResultB) => {
667
- const maxSeverityA = Math.min(
668
- ...fileResultA.issues.map((i) => {
669
- const val = getSeverityLevel(i.severity);
670
- return val === 4 ? 0 : val === 3 ? 1 : val === 2 ? 2 : 3;
671
- })
672
- );
673
- const maxSeverityB = Math.min(
674
- ...fileResultB.issues.map((i) => {
675
- const val = getSeverityLevel(i.severity);
676
- return val === 4 ? 0 : val === 3 ? 1 : val === 2 ? 2 : 3;
677
- })
630
+ const recommendations = [];
631
+ if (namingIssues.length > 0) {
632
+ recommendations.push("Standardize naming conventions across the codebase");
633
+ }
634
+ if (patternIssues.length > 0) {
635
+ recommendations.push("Consolidate repetitive implementation patterns");
636
+ }
637
+ if (results.some((r) => (r.metrics?.consistencyScore ?? 1) < 0.8)) {
638
+ recommendations.push(
639
+ "Improve cross-module consistency to reduce AI confusion"
678
640
  );
679
- if (maxSeverityA !== maxSeverityB) {
680
- return maxSeverityA - maxSeverityB;
681
- }
682
- return fileResultB.issues.length - fileResultA.issues.length;
683
- });
684
- const recommendations = generateRecommendations(namingIssues, patternIssues);
685
- const namingCountFiltered = namingIssues.filter(
686
- (i) => shouldIncludeSeverity(i.severity, minSeverity)
687
- ).length;
688
- const patternCountFiltered = patternIssues.filter(
689
- (i) => shouldIncludeSeverity(i.severity, minSeverity)
690
- ).length;
641
+ }
691
642
  return {
643
+ results,
692
644
  summary: {
693
- totalIssues: namingCountFiltered + patternCountFiltered,
694
- namingIssues: namingCountFiltered,
695
- patternIssues: patternCountFiltered,
696
- architectureIssues: 0,
697
645
  filesAnalyzed: filePaths.length,
698
- config: Object.fromEntries(
699
- Object.entries(options).filter(
700
- ([key]) => !import_core5.GLOBAL_SCAN_OPTIONS.includes(key) || key === "rootDir"
701
- )
702
- )
646
+ totalIssues: results.reduce((acc, r) => acc + r.issues.length, 0),
647
+ namingIssues: namingIssues.length,
648
+ patternIssues: patternIssues.length,
649
+ architectureIssues: 0
703
650
  },
704
- results,
705
- recommendations
651
+ recommendations,
652
+ metadata: {
653
+ toolName: "naming-consistency",
654
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
655
+ }
706
656
  };
707
657
  }
708
- function getSeverityLevel(s) {
709
- if (s === import_core5.Severity.Critical || s === "critical") return 4;
710
- if (s === import_core5.Severity.Major || s === "major") return 3;
711
- if (s === import_core5.Severity.Minor || s === "minor") return 2;
712
- if (s === import_core5.Severity.Info || s === "info") return 1;
713
- return 0;
658
+ function shouldIncludeSeverity(severity, minSeverity) {
659
+ return (0, import_core5.getSeverityLevel)(severity) >= (0, import_core5.getSeverityLevel)(minSeverity);
714
660
  }
715
- function getSeverityEnum(s) {
716
- const val = getSeverityLevel(s);
717
- switch (val) {
718
- case 4:
719
- return import_core5.Severity.Critical;
720
- case 3:
721
- return import_core5.Severity.Major;
722
- case 2:
723
- return import_core5.Severity.Minor;
724
- case 1:
725
- return import_core5.Severity.Info;
726
- default:
727
- return import_core5.Severity.Info;
728
- }
661
+ function getIssueType(type) {
662
+ if (!type) return import_core5.IssueType.NamingInconsistency;
663
+ const typeMap = {
664
+ "naming-inconsistency": import_core5.IssueType.NamingInconsistency,
665
+ "naming-quality": import_core5.IssueType.NamingQuality,
666
+ "pattern-inconsistency": import_core5.IssueType.PatternInconsistency,
667
+ "architecture-inconsistency": import_core5.IssueType.ArchitectureInconsistency,
668
+ "error-handling": import_core5.IssueType.PatternInconsistency,
669
+ "async-style": import_core5.IssueType.PatternInconsistency,
670
+ "import-style": import_core5.IssueType.PatternInconsistency,
671
+ "api-design": import_core5.IssueType.PatternInconsistency
672
+ };
673
+ return typeMap[type] || import_core5.IssueType.NamingInconsistency;
729
674
  }
730
- function shouldIncludeSeverity(severity, minSeverity) {
731
- return getSeverityLevel(severity) >= getSeverityLevel(minSeverity);
675
+ function transformToIssue(i) {
676
+ if (i.message && i.location) {
677
+ return {
678
+ type: getIssueType(i.type),
679
+ severity: i.severity,
680
+ message: i.message,
681
+ location: i.location,
682
+ suggestion: i.suggestion
683
+ };
684
+ }
685
+ if (i.identifier || i.type) {
686
+ const line = i.line || 1;
687
+ const column = i.column || 1;
688
+ return {
689
+ type: getIssueType(i.type),
690
+ severity: i.severity,
691
+ message: i.suggestion ? `Naming issue: ${i.suggestion}` : `Naming issue for '${i.identifier || "unknown"}'`,
692
+ location: {
693
+ file: i.file || i.fileName || "",
694
+ line,
695
+ column,
696
+ endLine: line,
697
+ endColumn: column + (i.identifier?.length || 10)
698
+ },
699
+ suggestion: i.suggestion
700
+ };
701
+ }
702
+ if (i.description || i.files) {
703
+ const fileName = Array.isArray(i.files) ? i.files[0] : i.file || "";
704
+ return {
705
+ type: getIssueType(i.type),
706
+ severity: i.severity,
707
+ message: i.description || "Pattern inconsistency found",
708
+ location: {
709
+ file: fileName,
710
+ line: 1,
711
+ column: 1,
712
+ endLine: 1,
713
+ endColumn: 10
714
+ },
715
+ suggestion: i.examples?.[0]
716
+ };
717
+ }
718
+ return {
719
+ type: getIssueType(i.type),
720
+ severity: i.severity,
721
+ message: i.message || "Unknown issue",
722
+ location: i.location || { file: "", line: 1, column: 1 },
723
+ suggestion: i.suggestion
724
+ };
732
725
  }
733
726
  function calculateConsistencyScore(issues) {
734
727
  let totalWeight = 0;
735
728
  for (const issue of issues) {
736
- const val = getSeverityLevel(issue.severity);
729
+ const val = (0, import_core5.getSeverityLevel)(issue.severity);
737
730
  switch (val) {
738
731
  case 4:
739
732
  totalWeight += 10;
@@ -753,55 +746,6 @@ function calculateConsistencyScore(issues) {
753
746
  }
754
747
  return Math.max(0, 1 - totalWeight / 100);
755
748
  }
756
- function generateRecommendations(namingIssues, patternIssues) {
757
- const recommendations = [];
758
- if (namingIssues.length > 0) {
759
- const conventionMixCount = namingIssues.filter(
760
- (i) => i.type === "convention-mix"
761
- ).length;
762
- if (conventionMixCount > 0) {
763
- recommendations.push(
764
- `Standardize naming conventions: Found ${conventionMixCount} snake_case variables in TypeScript/JavaScript (use camelCase)`
765
- );
766
- }
767
- const poorNamingCount = namingIssues.filter(
768
- (i) => i.type === "poor-naming"
769
- ).length;
770
- if (poorNamingCount > 0) {
771
- recommendations.push(
772
- `Improve variable naming: Found ${poorNamingCount} single-letter or unclear variable names`
773
- );
774
- }
775
- }
776
- if (patternIssues.length > 0) {
777
- const errorHandlingIssues = patternIssues.filter(
778
- (i) => i.type === "error-handling"
779
- );
780
- if (errorHandlingIssues.length > 0) {
781
- recommendations.push(
782
- "Standardize error handling strategy across the codebase (prefer try-catch with typed errors)"
783
- );
784
- }
785
- const asyncIssues = patternIssues.filter((i) => i.type === "async-style");
786
- if (asyncIssues.length > 0) {
787
- recommendations.push(
788
- "Use async/await consistently instead of mixing with promise chains or callbacks"
789
- );
790
- }
791
- const importIssues = patternIssues.filter((i) => i.type === "import-style");
792
- if (importIssues.length > 0) {
793
- recommendations.push(
794
- "Use ES modules consistently across the project (avoid mixing with CommonJS)"
795
- );
796
- }
797
- }
798
- if (recommendations.length === 0) {
799
- recommendations.push(
800
- "No major consistency issues found! Your codebase follows good practices."
801
- );
802
- }
803
- return recommendations;
804
- }
805
749
 
806
750
  // src/cli.ts
807
751
  var import_chalk = __toESM(require("chalk"));
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  analyzeConsistency
4
- } from "./chunk-UMBBTNQN.mjs";
4
+ } from "./chunk-S6BZVTWN.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.d.mts CHANGED
@@ -36,7 +36,7 @@ interface NamingIssue {
36
36
  }
37
37
  interface PatternIssue {
38
38
  files: string[];
39
- type: 'error-handling' | 'async-style' | 'import-style' | 'api-design';
39
+ type: 'error-handling' | 'async-style' | 'import-style' | 'api-design' | 'pattern-inconsistency';
40
40
  description: string;
41
41
  examples: string[];
42
42
  severity: Severity;
@@ -74,6 +74,8 @@ declare function analyzeNamingAST(filePaths: string[]): Promise<NamingIssue[]>;
74
74
  /**
75
75
  * Legacy regex-based naming analyzer
76
76
  * (Used as fallback or for languages without AST support)
77
+ * @param filePaths - Array of file paths to analyze
78
+ * @returns Array of naming issues found
77
79
  */
78
80
  declare function analyzeNaming(filePaths: string[]): Promise<NamingIssue[]>;
79
81
 
package/dist/index.d.ts CHANGED
@@ -36,7 +36,7 @@ interface NamingIssue {
36
36
  }
37
37
  interface PatternIssue {
38
38
  files: string[];
39
- type: 'error-handling' | 'async-style' | 'import-style' | 'api-design';
39
+ type: 'error-handling' | 'async-style' | 'import-style' | 'api-design' | 'pattern-inconsistency';
40
40
  description: string;
41
41
  examples: string[];
42
42
  severity: Severity;
@@ -74,6 +74,8 @@ declare function analyzeNamingAST(filePaths: string[]): Promise<NamingIssue[]>;
74
74
  /**
75
75
  * Legacy regex-based naming analyzer
76
76
  * (Used as fallback or for languages without AST support)
77
+ * @param filePaths - Array of file paths to analyze
78
+ * @returns Array of naming issues found
77
79
  */
78
80
  declare function analyzeNaming(filePaths: string[]): Promise<NamingIssue[]>;
79
81