@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/index.js CHANGED
@@ -361,7 +361,7 @@ function checkNamingConvention(name, convention, node, file, issues, context) {
361
361
  }
362
362
  }
363
363
  function checkVariableNaming(varInfo, file, issues, context) {
364
- const { name, node, line, options } = varInfo;
364
+ const { name, line, options } = varInfo;
365
365
  if (isAcceptableInContext(name, context, options)) {
366
366
  return;
367
367
  }
@@ -483,7 +483,6 @@ async function analyzeNamingGeneralized(files) {
483
483
  const conventions = parser.getNamingConventions();
484
484
  for (const exp of result.exports) {
485
485
  let pattern;
486
- const typeName = exp.type;
487
486
  if (exp.type === "class") {
488
487
  pattern = conventions.classPattern;
489
488
  } else if (exp.type === "interface" && conventions.interfacePattern) {
@@ -499,7 +498,7 @@ async function analyzeNamingGeneralized(files) {
499
498
  }
500
499
  if (pattern && !pattern.test(exp.name)) {
501
500
  issues.push({
502
- type: "poor-naming",
501
+ type: "naming-inconsistency",
503
502
  identifier: exp.name,
504
503
  file,
505
504
  line: exp.loc?.start.line || 1,
@@ -515,7 +514,7 @@ async function analyzeNamingGeneralized(files) {
515
514
  if (spec === "*" || spec === "default") continue;
516
515
  if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec)) {
517
516
  issues.push({
518
- type: "convention-mix",
517
+ type: "naming-inconsistency",
519
518
  identifier: spec,
520
519
  file,
521
520
  line: imp.loc?.start.line || 1,
@@ -541,7 +540,6 @@ async function analyzePatterns(filePaths) {
541
540
  const issues = [];
542
541
  const contents = /* @__PURE__ */ new Map();
543
542
  const tryCatchPattern = /try\s*\{/g;
544
- const catchPattern = /catch\s*\(\s*(\w+)\s*\)/g;
545
543
  const styleStats = {
546
544
  tryCatch: 0,
547
545
  thenCatch: 0,
@@ -562,7 +560,6 @@ async function analyzePatterns(filePaths) {
562
560
  void err;
563
561
  }
564
562
  }
565
- const totalFiles = filePaths.length;
566
563
  if (styleStats.tryCatch > 0 && styleStats.thenCatch > 0) {
567
564
  const dominant = styleStats.tryCatch >= styleStats.thenCatch ? "try-catch" : ".catch()";
568
565
  const minority = dominant === "try-catch" ? ".catch()" : "try-catch";
@@ -571,7 +568,7 @@ async function analyzePatterns(filePaths) {
571
568
  const c = contents.get(f) || "";
572
569
  return minority === "try-catch" ? c.match(tryCatchPattern) : c.match(/\.catch\s*\(/);
573
570
  }),
574
- type: "error-handling",
571
+ type: "pattern-inconsistency",
575
572
  description: `Mixed error handling styles: codebase primarily uses ${dominant}, but found ${minority} in some files.`,
576
573
  examples: [dominant, minority],
577
574
  severity: import_core4.Severity.Minor
@@ -584,7 +581,7 @@ async function analyzePatterns(filePaths) {
584
581
  const c = contents.get(f) || "";
585
582
  return minority === "CommonJS (require)" ? c.match(/\brequire\s*\(/) : c.match(/\bimport\b/);
586
583
  }),
587
- type: "import-style",
584
+ type: "pattern-inconsistency",
588
585
  description: `Mixed module systems: found both ESM and CommonJS.`,
589
586
  examples: ['import X from "y"', 'const X = require("y")'],
590
587
  severity: import_core4.Severity.Major
@@ -618,130 +615,126 @@ async function analyzeConsistency(options) {
618
615
  const results = [];
619
616
  const fileIssuesMap = /* @__PURE__ */ new Map();
620
617
  for (const issue of namingIssues) {
621
- if (!shouldIncludeSeverity(issue.severity, minSeverity)) {
622
- continue;
623
- }
624
- const consistencyIssue = {
625
- type: issue.type === "convention-mix" ? import_core5.IssueType.NamingInconsistency : import_core5.IssueType.NamingQuality,
626
- category: "naming",
627
- severity: getSeverityEnum(issue.severity),
628
- message: `${issue.type}: ${issue.identifier}`,
629
- location: {
630
- file: issue.file,
631
- line: issue.line,
632
- column: issue.column
633
- },
634
- suggestion: issue.suggestion
635
- };
636
- if (!fileIssuesMap.has(issue.file)) {
637
- fileIssuesMap.set(issue.file, []);
638
- }
639
- fileIssuesMap.get(issue.file).push(consistencyIssue);
618
+ if (!shouldIncludeSeverity(issue.severity, minSeverity)) continue;
619
+ const fileName = issue.fileName || issue.file || issue.filePath || "unknown";
620
+ if (!fileIssuesMap.has(fileName)) fileIssuesMap.set(fileName, []);
621
+ fileIssuesMap.get(fileName).push(issue);
640
622
  }
641
623
  for (const issue of patternIssues) {
642
- if (!shouldIncludeSeverity(issue.severity, minSeverity)) {
643
- continue;
644
- }
645
- const consistencyIssue = {
646
- type: import_core5.IssueType.PatternInconsistency,
647
- category: "patterns",
648
- severity: getSeverityEnum(issue.severity),
649
- message: issue.description,
650
- location: {
651
- file: issue.files[0] || "multiple files",
652
- line: 1
653
- },
654
- examples: issue.examples,
655
- suggestion: `Standardize ${issue.type} patterns across ${issue.files.length} files`
656
- };
657
- const firstFile = issue.files[0];
658
- if (firstFile && !fileIssuesMap.has(firstFile)) {
659
- fileIssuesMap.set(firstFile, []);
660
- }
661
- if (firstFile) {
662
- fileIssuesMap.get(firstFile).push(consistencyIssue);
663
- }
624
+ if (!shouldIncludeSeverity(issue.severity, minSeverity)) continue;
625
+ const fileName = issue.fileName || issue.file || issue.filePath || (Array.isArray(issue.files) ? issue.files[0] : "unknown");
626
+ if (!fileIssuesMap.has(fileName)) fileIssuesMap.set(fileName, []);
627
+ fileIssuesMap.get(fileName).push(issue);
664
628
  }
665
- for (const [fileName, issues] of fileIssuesMap) {
629
+ for (const [fileName, issues] of fileIssuesMap.entries()) {
666
630
  results.push({
667
631
  fileName,
668
- issues,
632
+ issues: issues.map((i) => transformToIssue(i)),
669
633
  metrics: {
670
634
  consistencyScore: calculateConsistencyScore(issues)
671
635
  }
672
636
  });
673
637
  }
674
- results.sort((fileResultA, fileResultB) => {
675
- const maxSeverityA = Math.min(
676
- ...fileResultA.issues.map((i) => {
677
- const val = getSeverityLevel(i.severity);
678
- return val === 4 ? 0 : val === 3 ? 1 : val === 2 ? 2 : 3;
679
- })
680
- );
681
- const maxSeverityB = Math.min(
682
- ...fileResultB.issues.map((i) => {
683
- const val = getSeverityLevel(i.severity);
684
- return val === 4 ? 0 : val === 3 ? 1 : val === 2 ? 2 : 3;
685
- })
638
+ const recommendations = [];
639
+ if (namingIssues.length > 0) {
640
+ recommendations.push("Standardize naming conventions across the codebase");
641
+ }
642
+ if (patternIssues.length > 0) {
643
+ recommendations.push("Consolidate repetitive implementation patterns");
644
+ }
645
+ if (results.some((r) => (r.metrics?.consistencyScore ?? 1) < 0.8)) {
646
+ recommendations.push(
647
+ "Improve cross-module consistency to reduce AI confusion"
686
648
  );
687
- if (maxSeverityA !== maxSeverityB) {
688
- return maxSeverityA - maxSeverityB;
689
- }
690
- return fileResultB.issues.length - fileResultA.issues.length;
691
- });
692
- const recommendations = generateRecommendations(namingIssues, patternIssues);
693
- const namingCountFiltered = namingIssues.filter(
694
- (i) => shouldIncludeSeverity(i.severity, minSeverity)
695
- ).length;
696
- const patternCountFiltered = patternIssues.filter(
697
- (i) => shouldIncludeSeverity(i.severity, minSeverity)
698
- ).length;
649
+ }
699
650
  return {
651
+ results,
700
652
  summary: {
701
- totalIssues: namingCountFiltered + patternCountFiltered,
702
- namingIssues: namingCountFiltered,
703
- patternIssues: patternCountFiltered,
704
- architectureIssues: 0,
705
653
  filesAnalyzed: filePaths.length,
706
- config: Object.fromEntries(
707
- Object.entries(options).filter(
708
- ([key]) => !import_core5.GLOBAL_SCAN_OPTIONS.includes(key) || key === "rootDir"
709
- )
710
- )
654
+ totalIssues: results.reduce((acc, r) => acc + r.issues.length, 0),
655
+ namingIssues: namingIssues.length,
656
+ patternIssues: patternIssues.length,
657
+ architectureIssues: 0
711
658
  },
712
- results,
713
- recommendations
659
+ recommendations,
660
+ metadata: {
661
+ toolName: "naming-consistency",
662
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
663
+ }
714
664
  };
715
665
  }
716
- function getSeverityLevel(s) {
717
- if (s === import_core5.Severity.Critical || s === "critical") return 4;
718
- if (s === import_core5.Severity.Major || s === "major") return 3;
719
- if (s === import_core5.Severity.Minor || s === "minor") return 2;
720
- if (s === import_core5.Severity.Info || s === "info") return 1;
721
- return 0;
666
+ function shouldIncludeSeverity(severity, minSeverity) {
667
+ return (0, import_core5.getSeverityLevel)(severity) >= (0, import_core5.getSeverityLevel)(minSeverity);
668
+ }
669
+ function getIssueType(type) {
670
+ if (!type) return import_core5.IssueType.NamingInconsistency;
671
+ const typeMap = {
672
+ "naming-inconsistency": import_core5.IssueType.NamingInconsistency,
673
+ "naming-quality": import_core5.IssueType.NamingQuality,
674
+ "pattern-inconsistency": import_core5.IssueType.PatternInconsistency,
675
+ "architecture-inconsistency": import_core5.IssueType.ArchitectureInconsistency,
676
+ "error-handling": import_core5.IssueType.PatternInconsistency,
677
+ "async-style": import_core5.IssueType.PatternInconsistency,
678
+ "import-style": import_core5.IssueType.PatternInconsistency,
679
+ "api-design": import_core5.IssueType.PatternInconsistency
680
+ };
681
+ return typeMap[type] || import_core5.IssueType.NamingInconsistency;
722
682
  }
723
- function getSeverityEnum(s) {
724
- const val = getSeverityLevel(s);
725
- switch (val) {
726
- case 4:
727
- return import_core5.Severity.Critical;
728
- case 3:
729
- return import_core5.Severity.Major;
730
- case 2:
731
- return import_core5.Severity.Minor;
732
- case 1:
733
- return import_core5.Severity.Info;
734
- default:
735
- return import_core5.Severity.Info;
683
+ function transformToIssue(i) {
684
+ if (i.message && i.location) {
685
+ return {
686
+ type: getIssueType(i.type),
687
+ severity: i.severity,
688
+ message: i.message,
689
+ location: i.location,
690
+ suggestion: i.suggestion
691
+ };
736
692
  }
737
- }
738
- function shouldIncludeSeverity(severity, minSeverity) {
739
- return getSeverityLevel(severity) >= getSeverityLevel(minSeverity);
693
+ if (i.identifier || i.type) {
694
+ const line = i.line || 1;
695
+ const column = i.column || 1;
696
+ return {
697
+ type: getIssueType(i.type),
698
+ severity: i.severity,
699
+ message: i.suggestion ? `Naming issue: ${i.suggestion}` : `Naming issue for '${i.identifier || "unknown"}'`,
700
+ location: {
701
+ file: i.file || i.fileName || "",
702
+ line,
703
+ column,
704
+ endLine: line,
705
+ endColumn: column + (i.identifier?.length || 10)
706
+ },
707
+ suggestion: i.suggestion
708
+ };
709
+ }
710
+ if (i.description || i.files) {
711
+ const fileName = Array.isArray(i.files) ? i.files[0] : i.file || "";
712
+ return {
713
+ type: getIssueType(i.type),
714
+ severity: i.severity,
715
+ message: i.description || "Pattern inconsistency found",
716
+ location: {
717
+ file: fileName,
718
+ line: 1,
719
+ column: 1,
720
+ endLine: 1,
721
+ endColumn: 10
722
+ },
723
+ suggestion: i.examples?.[0]
724
+ };
725
+ }
726
+ return {
727
+ type: getIssueType(i.type),
728
+ severity: i.severity,
729
+ message: i.message || "Unknown issue",
730
+ location: i.location || { file: "", line: 1, column: 1 },
731
+ suggestion: i.suggestion
732
+ };
740
733
  }
741
734
  function calculateConsistencyScore(issues) {
742
735
  let totalWeight = 0;
743
736
  for (const issue of issues) {
744
- const val = getSeverityLevel(issue.severity);
737
+ const val = (0, import_core5.getSeverityLevel)(issue.severity);
745
738
  switch (val) {
746
739
  case 4:
747
740
  totalWeight += 10;
@@ -761,55 +754,6 @@ function calculateConsistencyScore(issues) {
761
754
  }
762
755
  return Math.max(0, 1 - totalWeight / 100);
763
756
  }
764
- function generateRecommendations(namingIssues, patternIssues) {
765
- const recommendations = [];
766
- if (namingIssues.length > 0) {
767
- const conventionMixCount = namingIssues.filter(
768
- (i) => i.type === "convention-mix"
769
- ).length;
770
- if (conventionMixCount > 0) {
771
- recommendations.push(
772
- `Standardize naming conventions: Found ${conventionMixCount} snake_case variables in TypeScript/JavaScript (use camelCase)`
773
- );
774
- }
775
- const poorNamingCount = namingIssues.filter(
776
- (i) => i.type === "poor-naming"
777
- ).length;
778
- if (poorNamingCount > 0) {
779
- recommendations.push(
780
- `Improve variable naming: Found ${poorNamingCount} single-letter or unclear variable names`
781
- );
782
- }
783
- }
784
- if (patternIssues.length > 0) {
785
- const errorHandlingIssues = patternIssues.filter(
786
- (i) => i.type === "error-handling"
787
- );
788
- if (errorHandlingIssues.length > 0) {
789
- recommendations.push(
790
- "Standardize error handling strategy across the codebase (prefer try-catch with typed errors)"
791
- );
792
- }
793
- const asyncIssues = patternIssues.filter((i) => i.type === "async-style");
794
- if (asyncIssues.length > 0) {
795
- recommendations.push(
796
- "Use async/await consistently instead of mixing with promise chains or callbacks"
797
- );
798
- }
799
- const importIssues = patternIssues.filter((i) => i.type === "import-style");
800
- if (importIssues.length > 0) {
801
- recommendations.push(
802
- "Use ES modules consistently across the project (avoid mixing with CommonJS)"
803
- );
804
- }
805
- }
806
- if (recommendations.length === 0) {
807
- recommendations.push(
808
- "No major consistency issues found! Your codebase follows good practices."
809
- );
810
- }
811
- return recommendations;
812
- }
813
757
 
814
758
  // src/scoring.ts
815
759
  var import_core6 = require("@aiready/core");
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  analyzeConsistency,
3
3
  analyzeNamingAST,
4
4
  analyzePatterns
5
- } from "./chunk-UMBBTNQN.mjs";
5
+ } from "./chunk-S6BZVTWN.mjs";
6
6
 
7
7
  // src/index.ts
8
8
  import { ToolRegistry } from "@aiready/core";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/consistency",
3
- "version": "0.20.2",
3
+ "version": "0.20.4",
4
4
  "description": "Detects consistency issues in naming, patterns, and architecture that confuse AI models",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -43,7 +43,7 @@
43
43
  "@typescript-eslint/typescript-estree": "^8.53.0",
44
44
  "chalk": "^5.3.0",
45
45
  "commander": "^14.0.0",
46
- "@aiready/core": "0.23.2"
46
+ "@aiready/core": "0.23.4"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^24.0.0",