@aiready/consistency 0.20.20 → 0.20.21
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/.turbo/turbo-build.log +23 -24
- package/.turbo/turbo-lint.log +4 -5
- package/.turbo/turbo-test.log +28 -35
- package/dist/chunk-CLWNLHDB.mjs +909 -0
- package/dist/cli.js +120 -43
- package/dist/cli.mjs +1 -1
- package/dist/index.js +117 -136
- package/dist/index.mjs +5 -102
- package/package.json +2 -2
- package/src/analyzer.ts +6 -26
package/dist/cli.js
CHANGED
|
@@ -27,7 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var import_commander = require("commander");
|
|
28
28
|
|
|
29
29
|
// src/analyzer.ts
|
|
30
|
-
var
|
|
30
|
+
var import_core6 = require("@aiready/core");
|
|
31
31
|
|
|
32
32
|
// src/analyzers/naming-ast.ts
|
|
33
33
|
var import_core2 = require("@aiready/core");
|
|
@@ -682,6 +682,102 @@ async function analyzePatterns(filePaths) {
|
|
|
682
682
|
return issues;
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
+
// src/scoring.ts
|
|
686
|
+
var import_core5 = require("@aiready/core");
|
|
687
|
+
function calculateConsistencyScore(issues, totalFilesAnalyzed, costConfig) {
|
|
688
|
+
void costConfig;
|
|
689
|
+
const criticalIssues = issues.filter((i) => i.severity === "critical").length;
|
|
690
|
+
const majorIssues = issues.filter((i) => i.severity === "major").length;
|
|
691
|
+
const minorIssues = issues.filter((i) => i.severity === "minor").length;
|
|
692
|
+
const totalIssues = issues.length;
|
|
693
|
+
const issuesPerFile = totalFilesAnalyzed > 0 ? totalIssues / totalFilesAnalyzed : 0;
|
|
694
|
+
const densityPenalty = Math.min(50, issuesPerFile * 15);
|
|
695
|
+
const weightedCount = criticalIssues * 10 + majorIssues * 3 + minorIssues * 0.5;
|
|
696
|
+
const avgWeightedIssuesPerFile = totalFilesAnalyzed > 0 ? weightedCount / totalFilesAnalyzed : 0;
|
|
697
|
+
const severityPenalty = Math.min(50, avgWeightedIssuesPerFile * 2);
|
|
698
|
+
const rawScore = 100 - densityPenalty - severityPenalty;
|
|
699
|
+
const score = Math.max(0, Math.min(100, Math.round(rawScore)));
|
|
700
|
+
const factors = [
|
|
701
|
+
{
|
|
702
|
+
name: "Issue Density",
|
|
703
|
+
impact: -Math.round(densityPenalty),
|
|
704
|
+
description: `${issuesPerFile.toFixed(2)} issues per file ${issuesPerFile < 1 ? "(excellent)" : issuesPerFile < 3 ? "(acceptable)" : "(high)"}`
|
|
705
|
+
}
|
|
706
|
+
];
|
|
707
|
+
if (criticalIssues > 0) {
|
|
708
|
+
const criticalImpact = Math.min(30, criticalIssues * 10);
|
|
709
|
+
factors.push({
|
|
710
|
+
name: "Critical Issues",
|
|
711
|
+
impact: -criticalImpact,
|
|
712
|
+
description: `${criticalIssues} critical consistency issue${criticalIssues > 1 ? "s" : ""} (high AI confusion risk)`
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
if (majorIssues > 0) {
|
|
716
|
+
const majorImpact = Math.min(20, Math.round(majorIssues * 3));
|
|
717
|
+
factors.push({
|
|
718
|
+
name: "Major Issues",
|
|
719
|
+
impact: -majorImpact,
|
|
720
|
+
description: `${majorIssues} major issue${majorIssues > 1 ? "s" : ""} (moderate AI confusion risk)`
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
if (minorIssues > 0 && minorIssues >= totalFilesAnalyzed) {
|
|
724
|
+
const minorImpact = -Math.round(minorIssues * 0.5);
|
|
725
|
+
factors.push({
|
|
726
|
+
name: "Minor Issues",
|
|
727
|
+
impact: minorImpact,
|
|
728
|
+
description: `${minorIssues} minor issue${minorIssues > 1 ? "s" : ""} (slight AI confusion risk)`
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
const recommendations = [];
|
|
732
|
+
if (criticalIssues > 0) {
|
|
733
|
+
const estimatedImpact = Math.min(30, criticalIssues * 10);
|
|
734
|
+
recommendations.push({
|
|
735
|
+
action: "Fix critical naming/pattern inconsistencies (highest AI confusion risk)",
|
|
736
|
+
estimatedImpact,
|
|
737
|
+
priority: "high"
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
if (majorIssues > 5) {
|
|
741
|
+
const estimatedImpact = Math.min(15, Math.round(majorIssues / 2));
|
|
742
|
+
recommendations.push({
|
|
743
|
+
action: "Standardize naming conventions across codebase",
|
|
744
|
+
estimatedImpact,
|
|
745
|
+
priority: "medium"
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
if (issuesPerFile > 3) {
|
|
749
|
+
recommendations.push({
|
|
750
|
+
action: "Establish and enforce coding style guide to reduce inconsistencies",
|
|
751
|
+
estimatedImpact: 12,
|
|
752
|
+
priority: "medium"
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
if (totalIssues > 20 && minorIssues / totalIssues > 0.7) {
|
|
756
|
+
recommendations.push({
|
|
757
|
+
action: "Enable linter/formatter to automatically fix minor style issues",
|
|
758
|
+
estimatedImpact: 8,
|
|
759
|
+
priority: "low"
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
const productivityImpact = (0, import_core5.calculateProductivityImpact)(issues);
|
|
763
|
+
return {
|
|
764
|
+
toolName: import_core5.ToolName.NamingConsistency,
|
|
765
|
+
score,
|
|
766
|
+
rawMetrics: {
|
|
767
|
+
totalIssues,
|
|
768
|
+
criticalIssues,
|
|
769
|
+
majorIssues,
|
|
770
|
+
minorIssues,
|
|
771
|
+
issuesPerFile: Math.round(issuesPerFile * 100) / 100,
|
|
772
|
+
avgWeightedIssuesPerFile: Math.round(avgWeightedIssuesPerFile * 100) / 100,
|
|
773
|
+
// Business value metrics
|
|
774
|
+
estimatedDeveloperHours: productivityImpact.totalHours
|
|
775
|
+
},
|
|
776
|
+
factors,
|
|
777
|
+
recommendations
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
|
|
685
781
|
// src/analyzer.ts
|
|
686
782
|
async function analyzeConsistency(options) {
|
|
687
783
|
const {
|
|
@@ -689,11 +785,11 @@ async function analyzeConsistency(options) {
|
|
|
689
785
|
checkPatterns = true,
|
|
690
786
|
checkArchitecture = false,
|
|
691
787
|
// Not implemented yet
|
|
692
|
-
minSeverity =
|
|
788
|
+
minSeverity = import_core6.Severity.Info,
|
|
693
789
|
...scanOptions
|
|
694
790
|
} = options;
|
|
695
791
|
void checkArchitecture;
|
|
696
|
-
const filePaths = await (0,
|
|
792
|
+
const filePaths = await (0, import_core6.scanFiles)(scanOptions);
|
|
697
793
|
let namingIssues = [];
|
|
698
794
|
if (checkNaming) {
|
|
699
795
|
namingIssues = await analyzeNamingGeneralized(filePaths);
|
|
@@ -719,11 +815,15 @@ async function analyzeConsistency(options) {
|
|
|
719
815
|
fileIssuesMap.get(fileName).push(issue);
|
|
720
816
|
}
|
|
721
817
|
for (const [fileName, issues] of fileIssuesMap.entries()) {
|
|
818
|
+
const scoreResult = calculateConsistencyScore(
|
|
819
|
+
issues,
|
|
820
|
+
filePaths.length
|
|
821
|
+
);
|
|
722
822
|
results.push({
|
|
723
823
|
fileName,
|
|
724
824
|
issues: issues.map((i) => transformToIssue(i)),
|
|
725
825
|
metrics: {
|
|
726
|
-
consistencyScore:
|
|
826
|
+
consistencyScore: scoreResult.score / 100
|
|
727
827
|
}
|
|
728
828
|
});
|
|
729
829
|
}
|
|
@@ -756,21 +856,21 @@ async function analyzeConsistency(options) {
|
|
|
756
856
|
};
|
|
757
857
|
}
|
|
758
858
|
function shouldIncludeSeverity(severity, minSeverity) {
|
|
759
|
-
return (0,
|
|
859
|
+
return (0, import_core6.getSeverityLevel)(severity) >= (0, import_core6.getSeverityLevel)(minSeverity);
|
|
760
860
|
}
|
|
761
861
|
function getIssueType(type) {
|
|
762
|
-
if (!type) return
|
|
862
|
+
if (!type) return import_core6.IssueType.NamingInconsistency;
|
|
763
863
|
const typeMap = {
|
|
764
|
-
"naming-inconsistency":
|
|
765
|
-
"naming-quality":
|
|
766
|
-
"pattern-inconsistency":
|
|
767
|
-
"architecture-inconsistency":
|
|
768
|
-
"error-handling":
|
|
769
|
-
"async-style":
|
|
770
|
-
"import-style":
|
|
771
|
-
"api-design":
|
|
864
|
+
"naming-inconsistency": import_core6.IssueType.NamingInconsistency,
|
|
865
|
+
"naming-quality": import_core6.IssueType.NamingQuality,
|
|
866
|
+
"pattern-inconsistency": import_core6.IssueType.PatternInconsistency,
|
|
867
|
+
"architecture-inconsistency": import_core6.IssueType.ArchitectureInconsistency,
|
|
868
|
+
"error-handling": import_core6.IssueType.PatternInconsistency,
|
|
869
|
+
"async-style": import_core6.IssueType.PatternInconsistency,
|
|
870
|
+
"import-style": import_core6.IssueType.PatternInconsistency,
|
|
871
|
+
"api-design": import_core6.IssueType.PatternInconsistency
|
|
772
872
|
};
|
|
773
|
-
return typeMap[type] ||
|
|
873
|
+
return typeMap[type] || import_core6.IssueType.NamingInconsistency;
|
|
774
874
|
}
|
|
775
875
|
function transformToIssue(i) {
|
|
776
876
|
if (i.message && i.location) {
|
|
@@ -823,35 +923,12 @@ function transformToIssue(i) {
|
|
|
823
923
|
suggestion: i.suggestion
|
|
824
924
|
};
|
|
825
925
|
}
|
|
826
|
-
function calculateConsistencyScore(issues) {
|
|
827
|
-
let totalWeight = 0;
|
|
828
|
-
for (const issue of issues) {
|
|
829
|
-
const val = (0, import_core5.getSeverityLevel)(issue.severity);
|
|
830
|
-
switch (val) {
|
|
831
|
-
case 4:
|
|
832
|
-
totalWeight += 10;
|
|
833
|
-
break;
|
|
834
|
-
case 3:
|
|
835
|
-
totalWeight += 5;
|
|
836
|
-
break;
|
|
837
|
-
case 2:
|
|
838
|
-
totalWeight += 2;
|
|
839
|
-
break;
|
|
840
|
-
case 1:
|
|
841
|
-
totalWeight += 1;
|
|
842
|
-
break;
|
|
843
|
-
default:
|
|
844
|
-
totalWeight += 1;
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
return Math.max(0, 1 - totalWeight / 100);
|
|
848
|
-
}
|
|
849
926
|
|
|
850
927
|
// src/cli.ts
|
|
851
928
|
var import_chalk = __toESM(require("chalk"));
|
|
852
929
|
var import_fs4 = require("fs");
|
|
853
930
|
var import_path = require("path");
|
|
854
|
-
var
|
|
931
|
+
var import_core7 = require("@aiready/core");
|
|
855
932
|
var program = new import_commander.Command();
|
|
856
933
|
program.name("aiready-consistency").description(
|
|
857
934
|
"Detect consistency patterns in naming, code structure, and architecture"
|
|
@@ -890,7 +967,7 @@ EXAMPLES:
|
|
|
890
967
|
).option("--output-file <path>", "Output file path (for json/markdown)").action(async (directory, options) => {
|
|
891
968
|
console.log(import_chalk.default.blue("\u{1F50D} Analyzing consistency...\n"));
|
|
892
969
|
const startTime = Date.now();
|
|
893
|
-
const config = await (0,
|
|
970
|
+
const config = await (0, import_core7.loadConfig)(directory);
|
|
894
971
|
const defaults = {
|
|
895
972
|
checkNaming: true,
|
|
896
973
|
checkPatterns: true,
|
|
@@ -899,7 +976,7 @@ EXAMPLES:
|
|
|
899
976
|
include: void 0,
|
|
900
977
|
exclude: void 0
|
|
901
978
|
};
|
|
902
|
-
const mergedConfig = (0,
|
|
979
|
+
const mergedConfig = (0, import_core7.mergeConfigWithDefaults)(config, defaults);
|
|
903
980
|
const finalOptions = {
|
|
904
981
|
rootDir: directory,
|
|
905
982
|
checkNaming: options.naming !== false && mergedConfig.checkNaming,
|
|
@@ -913,7 +990,7 @@ EXAMPLES:
|
|
|
913
990
|
const elapsedTime = ((Date.now() - startTime) / 1e3).toFixed(2);
|
|
914
991
|
if (options.output === "json") {
|
|
915
992
|
const output = JSON.stringify(report, null, 2);
|
|
916
|
-
const outputPath = (0,
|
|
993
|
+
const outputPath = (0, import_core7.resolveOutputPath)(
|
|
917
994
|
options.outputFile,
|
|
918
995
|
`consistency-report-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.json`,
|
|
919
996
|
directory
|
|
@@ -926,7 +1003,7 @@ EXAMPLES:
|
|
|
926
1003
|
console.log(import_chalk.default.green(`\u2713 Report saved to ${outputPath}`));
|
|
927
1004
|
} else if (options.output === "markdown") {
|
|
928
1005
|
const markdown = generateMarkdownReport(report, elapsedTime);
|
|
929
|
-
const outputPath = (0,
|
|
1006
|
+
const outputPath = (0, import_core7.resolveOutputPath)(
|
|
930
1007
|
options.outputFile,
|
|
931
1008
|
`consistency-report-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.md`,
|
|
932
1009
|
directory
|
package/dist/cli.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
analyzeNaming: () => analyzeNaming,
|
|
26
26
|
analyzeNamingAST: () => analyzeNamingAST,
|
|
27
27
|
analyzePatterns: () => analyzePatterns,
|
|
28
|
-
calculateConsistencyScore: () =>
|
|
28
|
+
calculateConsistencyScore: () => calculateConsistencyScore,
|
|
29
29
|
detectNamingConventions: () => detectNamingConventions
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -35,7 +35,7 @@ var import_core9 = require("@aiready/core");
|
|
|
35
35
|
var import_core7 = require("@aiready/core");
|
|
36
36
|
|
|
37
37
|
// src/analyzer.ts
|
|
38
|
-
var
|
|
38
|
+
var import_core6 = require("@aiready/core");
|
|
39
39
|
|
|
40
40
|
// src/analyzers/naming-ast.ts
|
|
41
41
|
var import_core2 = require("@aiready/core");
|
|
@@ -690,6 +690,102 @@ async function analyzePatterns(filePaths) {
|
|
|
690
690
|
return issues;
|
|
691
691
|
}
|
|
692
692
|
|
|
693
|
+
// src/scoring.ts
|
|
694
|
+
var import_core5 = require("@aiready/core");
|
|
695
|
+
function calculateConsistencyScore(issues, totalFilesAnalyzed, costConfig) {
|
|
696
|
+
void costConfig;
|
|
697
|
+
const criticalIssues = issues.filter((i) => i.severity === "critical").length;
|
|
698
|
+
const majorIssues = issues.filter((i) => i.severity === "major").length;
|
|
699
|
+
const minorIssues = issues.filter((i) => i.severity === "minor").length;
|
|
700
|
+
const totalIssues = issues.length;
|
|
701
|
+
const issuesPerFile = totalFilesAnalyzed > 0 ? totalIssues / totalFilesAnalyzed : 0;
|
|
702
|
+
const densityPenalty = Math.min(50, issuesPerFile * 15);
|
|
703
|
+
const weightedCount = criticalIssues * 10 + majorIssues * 3 + minorIssues * 0.5;
|
|
704
|
+
const avgWeightedIssuesPerFile = totalFilesAnalyzed > 0 ? weightedCount / totalFilesAnalyzed : 0;
|
|
705
|
+
const severityPenalty = Math.min(50, avgWeightedIssuesPerFile * 2);
|
|
706
|
+
const rawScore = 100 - densityPenalty - severityPenalty;
|
|
707
|
+
const score = Math.max(0, Math.min(100, Math.round(rawScore)));
|
|
708
|
+
const factors = [
|
|
709
|
+
{
|
|
710
|
+
name: "Issue Density",
|
|
711
|
+
impact: -Math.round(densityPenalty),
|
|
712
|
+
description: `${issuesPerFile.toFixed(2)} issues per file ${issuesPerFile < 1 ? "(excellent)" : issuesPerFile < 3 ? "(acceptable)" : "(high)"}`
|
|
713
|
+
}
|
|
714
|
+
];
|
|
715
|
+
if (criticalIssues > 0) {
|
|
716
|
+
const criticalImpact = Math.min(30, criticalIssues * 10);
|
|
717
|
+
factors.push({
|
|
718
|
+
name: "Critical Issues",
|
|
719
|
+
impact: -criticalImpact,
|
|
720
|
+
description: `${criticalIssues} critical consistency issue${criticalIssues > 1 ? "s" : ""} (high AI confusion risk)`
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
if (majorIssues > 0) {
|
|
724
|
+
const majorImpact = Math.min(20, Math.round(majorIssues * 3));
|
|
725
|
+
factors.push({
|
|
726
|
+
name: "Major Issues",
|
|
727
|
+
impact: -majorImpact,
|
|
728
|
+
description: `${majorIssues} major issue${majorIssues > 1 ? "s" : ""} (moderate AI confusion risk)`
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
if (minorIssues > 0 && minorIssues >= totalFilesAnalyzed) {
|
|
732
|
+
const minorImpact = -Math.round(minorIssues * 0.5);
|
|
733
|
+
factors.push({
|
|
734
|
+
name: "Minor Issues",
|
|
735
|
+
impact: minorImpact,
|
|
736
|
+
description: `${minorIssues} minor issue${minorIssues > 1 ? "s" : ""} (slight AI confusion risk)`
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
const recommendations = [];
|
|
740
|
+
if (criticalIssues > 0) {
|
|
741
|
+
const estimatedImpact = Math.min(30, criticalIssues * 10);
|
|
742
|
+
recommendations.push({
|
|
743
|
+
action: "Fix critical naming/pattern inconsistencies (highest AI confusion risk)",
|
|
744
|
+
estimatedImpact,
|
|
745
|
+
priority: "high"
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
if (majorIssues > 5) {
|
|
749
|
+
const estimatedImpact = Math.min(15, Math.round(majorIssues / 2));
|
|
750
|
+
recommendations.push({
|
|
751
|
+
action: "Standardize naming conventions across codebase",
|
|
752
|
+
estimatedImpact,
|
|
753
|
+
priority: "medium"
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
if (issuesPerFile > 3) {
|
|
757
|
+
recommendations.push({
|
|
758
|
+
action: "Establish and enforce coding style guide to reduce inconsistencies",
|
|
759
|
+
estimatedImpact: 12,
|
|
760
|
+
priority: "medium"
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
if (totalIssues > 20 && minorIssues / totalIssues > 0.7) {
|
|
764
|
+
recommendations.push({
|
|
765
|
+
action: "Enable linter/formatter to automatically fix minor style issues",
|
|
766
|
+
estimatedImpact: 8,
|
|
767
|
+
priority: "low"
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
const productivityImpact = (0, import_core5.calculateProductivityImpact)(issues);
|
|
771
|
+
return {
|
|
772
|
+
toolName: import_core5.ToolName.NamingConsistency,
|
|
773
|
+
score,
|
|
774
|
+
rawMetrics: {
|
|
775
|
+
totalIssues,
|
|
776
|
+
criticalIssues,
|
|
777
|
+
majorIssues,
|
|
778
|
+
minorIssues,
|
|
779
|
+
issuesPerFile: Math.round(issuesPerFile * 100) / 100,
|
|
780
|
+
avgWeightedIssuesPerFile: Math.round(avgWeightedIssuesPerFile * 100) / 100,
|
|
781
|
+
// Business value metrics
|
|
782
|
+
estimatedDeveloperHours: productivityImpact.totalHours
|
|
783
|
+
},
|
|
784
|
+
factors,
|
|
785
|
+
recommendations
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
|
|
693
789
|
// src/analyzer.ts
|
|
694
790
|
async function analyzeConsistency(options) {
|
|
695
791
|
const {
|
|
@@ -697,11 +793,11 @@ async function analyzeConsistency(options) {
|
|
|
697
793
|
checkPatterns = true,
|
|
698
794
|
checkArchitecture = false,
|
|
699
795
|
// Not implemented yet
|
|
700
|
-
minSeverity =
|
|
796
|
+
minSeverity = import_core6.Severity.Info,
|
|
701
797
|
...scanOptions
|
|
702
798
|
} = options;
|
|
703
799
|
void checkArchitecture;
|
|
704
|
-
const filePaths = await (0,
|
|
800
|
+
const filePaths = await (0, import_core6.scanFiles)(scanOptions);
|
|
705
801
|
let namingIssues = [];
|
|
706
802
|
if (checkNaming) {
|
|
707
803
|
namingIssues = await analyzeNamingGeneralized(filePaths);
|
|
@@ -727,11 +823,15 @@ async function analyzeConsistency(options) {
|
|
|
727
823
|
fileIssuesMap.get(fileName).push(issue);
|
|
728
824
|
}
|
|
729
825
|
for (const [fileName, issues] of fileIssuesMap.entries()) {
|
|
826
|
+
const scoreResult = calculateConsistencyScore(
|
|
827
|
+
issues,
|
|
828
|
+
filePaths.length
|
|
829
|
+
);
|
|
730
830
|
results.push({
|
|
731
831
|
fileName,
|
|
732
832
|
issues: issues.map((i) => transformToIssue(i)),
|
|
733
833
|
metrics: {
|
|
734
|
-
consistencyScore:
|
|
834
|
+
consistencyScore: scoreResult.score / 100
|
|
735
835
|
}
|
|
736
836
|
});
|
|
737
837
|
}
|
|
@@ -764,21 +864,21 @@ async function analyzeConsistency(options) {
|
|
|
764
864
|
};
|
|
765
865
|
}
|
|
766
866
|
function shouldIncludeSeverity(severity, minSeverity) {
|
|
767
|
-
return (0,
|
|
867
|
+
return (0, import_core6.getSeverityLevel)(severity) >= (0, import_core6.getSeverityLevel)(minSeverity);
|
|
768
868
|
}
|
|
769
869
|
function getIssueType(type) {
|
|
770
|
-
if (!type) return
|
|
870
|
+
if (!type) return import_core6.IssueType.NamingInconsistency;
|
|
771
871
|
const typeMap = {
|
|
772
|
-
"naming-inconsistency":
|
|
773
|
-
"naming-quality":
|
|
774
|
-
"pattern-inconsistency":
|
|
775
|
-
"architecture-inconsistency":
|
|
776
|
-
"error-handling":
|
|
777
|
-
"async-style":
|
|
778
|
-
"import-style":
|
|
779
|
-
"api-design":
|
|
872
|
+
"naming-inconsistency": import_core6.IssueType.NamingInconsistency,
|
|
873
|
+
"naming-quality": import_core6.IssueType.NamingQuality,
|
|
874
|
+
"pattern-inconsistency": import_core6.IssueType.PatternInconsistency,
|
|
875
|
+
"architecture-inconsistency": import_core6.IssueType.ArchitectureInconsistency,
|
|
876
|
+
"error-handling": import_core6.IssueType.PatternInconsistency,
|
|
877
|
+
"async-style": import_core6.IssueType.PatternInconsistency,
|
|
878
|
+
"import-style": import_core6.IssueType.PatternInconsistency,
|
|
879
|
+
"api-design": import_core6.IssueType.PatternInconsistency
|
|
780
880
|
};
|
|
781
|
-
return typeMap[type] ||
|
|
881
|
+
return typeMap[type] || import_core6.IssueType.NamingInconsistency;
|
|
782
882
|
}
|
|
783
883
|
function transformToIssue(i) {
|
|
784
884
|
if (i.message && i.location) {
|
|
@@ -831,125 +931,6 @@ function transformToIssue(i) {
|
|
|
831
931
|
suggestion: i.suggestion
|
|
832
932
|
};
|
|
833
933
|
}
|
|
834
|
-
function calculateConsistencyScore(issues) {
|
|
835
|
-
let totalWeight = 0;
|
|
836
|
-
for (const issue of issues) {
|
|
837
|
-
const val = (0, import_core5.getSeverityLevel)(issue.severity);
|
|
838
|
-
switch (val) {
|
|
839
|
-
case 4:
|
|
840
|
-
totalWeight += 10;
|
|
841
|
-
break;
|
|
842
|
-
case 3:
|
|
843
|
-
totalWeight += 5;
|
|
844
|
-
break;
|
|
845
|
-
case 2:
|
|
846
|
-
totalWeight += 2;
|
|
847
|
-
break;
|
|
848
|
-
case 1:
|
|
849
|
-
totalWeight += 1;
|
|
850
|
-
break;
|
|
851
|
-
default:
|
|
852
|
-
totalWeight += 1;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
return Math.max(0, 1 - totalWeight / 100);
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
// src/scoring.ts
|
|
859
|
-
var import_core6 = require("@aiready/core");
|
|
860
|
-
function calculateConsistencyScore2(issues, totalFilesAnalyzed, costConfig) {
|
|
861
|
-
void costConfig;
|
|
862
|
-
const criticalIssues = issues.filter((i) => i.severity === "critical").length;
|
|
863
|
-
const majorIssues = issues.filter((i) => i.severity === "major").length;
|
|
864
|
-
const minorIssues = issues.filter((i) => i.severity === "minor").length;
|
|
865
|
-
const totalIssues = issues.length;
|
|
866
|
-
const issuesPerFile = totalFilesAnalyzed > 0 ? totalIssues / totalFilesAnalyzed : 0;
|
|
867
|
-
const densityPenalty = Math.min(50, issuesPerFile * 15);
|
|
868
|
-
const weightedCount = criticalIssues * 10 + majorIssues * 3 + minorIssues * 0.5;
|
|
869
|
-
const avgWeightedIssuesPerFile = totalFilesAnalyzed > 0 ? weightedCount / totalFilesAnalyzed : 0;
|
|
870
|
-
const severityPenalty = Math.min(50, avgWeightedIssuesPerFile * 2);
|
|
871
|
-
const rawScore = 100 - densityPenalty - severityPenalty;
|
|
872
|
-
const score = Math.max(0, Math.min(100, Math.round(rawScore)));
|
|
873
|
-
const factors = [
|
|
874
|
-
{
|
|
875
|
-
name: "Issue Density",
|
|
876
|
-
impact: -Math.round(densityPenalty),
|
|
877
|
-
description: `${issuesPerFile.toFixed(2)} issues per file ${issuesPerFile < 1 ? "(excellent)" : issuesPerFile < 3 ? "(acceptable)" : "(high)"}`
|
|
878
|
-
}
|
|
879
|
-
];
|
|
880
|
-
if (criticalIssues > 0) {
|
|
881
|
-
const criticalImpact = Math.min(30, criticalIssues * 10);
|
|
882
|
-
factors.push({
|
|
883
|
-
name: "Critical Issues",
|
|
884
|
-
impact: -criticalImpact,
|
|
885
|
-
description: `${criticalIssues} critical consistency issue${criticalIssues > 1 ? "s" : ""} (high AI confusion risk)`
|
|
886
|
-
});
|
|
887
|
-
}
|
|
888
|
-
if (majorIssues > 0) {
|
|
889
|
-
const majorImpact = Math.min(20, Math.round(majorIssues * 3));
|
|
890
|
-
factors.push({
|
|
891
|
-
name: "Major Issues",
|
|
892
|
-
impact: -majorImpact,
|
|
893
|
-
description: `${majorIssues} major issue${majorIssues > 1 ? "s" : ""} (moderate AI confusion risk)`
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
if (minorIssues > 0 && minorIssues >= totalFilesAnalyzed) {
|
|
897
|
-
const minorImpact = -Math.round(minorIssues * 0.5);
|
|
898
|
-
factors.push({
|
|
899
|
-
name: "Minor Issues",
|
|
900
|
-
impact: minorImpact,
|
|
901
|
-
description: `${minorIssues} minor issue${minorIssues > 1 ? "s" : ""} (slight AI confusion risk)`
|
|
902
|
-
});
|
|
903
|
-
}
|
|
904
|
-
const recommendations = [];
|
|
905
|
-
if (criticalIssues > 0) {
|
|
906
|
-
const estimatedImpact = Math.min(30, criticalIssues * 10);
|
|
907
|
-
recommendations.push({
|
|
908
|
-
action: "Fix critical naming/pattern inconsistencies (highest AI confusion risk)",
|
|
909
|
-
estimatedImpact,
|
|
910
|
-
priority: "high"
|
|
911
|
-
});
|
|
912
|
-
}
|
|
913
|
-
if (majorIssues > 5) {
|
|
914
|
-
const estimatedImpact = Math.min(15, Math.round(majorIssues / 2));
|
|
915
|
-
recommendations.push({
|
|
916
|
-
action: "Standardize naming conventions across codebase",
|
|
917
|
-
estimatedImpact,
|
|
918
|
-
priority: "medium"
|
|
919
|
-
});
|
|
920
|
-
}
|
|
921
|
-
if (issuesPerFile > 3) {
|
|
922
|
-
recommendations.push({
|
|
923
|
-
action: "Establish and enforce coding style guide to reduce inconsistencies",
|
|
924
|
-
estimatedImpact: 12,
|
|
925
|
-
priority: "medium"
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
if (totalIssues > 20 && minorIssues / totalIssues > 0.7) {
|
|
929
|
-
recommendations.push({
|
|
930
|
-
action: "Enable linter/formatter to automatically fix minor style issues",
|
|
931
|
-
estimatedImpact: 8,
|
|
932
|
-
priority: "low"
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
const productivityImpact = (0, import_core6.calculateProductivityImpact)(issues);
|
|
936
|
-
return {
|
|
937
|
-
toolName: import_core6.ToolName.NamingConsistency,
|
|
938
|
-
score,
|
|
939
|
-
rawMetrics: {
|
|
940
|
-
totalIssues,
|
|
941
|
-
criticalIssues,
|
|
942
|
-
majorIssues,
|
|
943
|
-
minorIssues,
|
|
944
|
-
issuesPerFile: Math.round(issuesPerFile * 100) / 100,
|
|
945
|
-
avgWeightedIssuesPerFile: Math.round(avgWeightedIssuesPerFile * 100) / 100,
|
|
946
|
-
// Business value metrics
|
|
947
|
-
estimatedDeveloperHours: productivityImpact.totalHours
|
|
948
|
-
},
|
|
949
|
-
factors,
|
|
950
|
-
recommendations
|
|
951
|
-
};
|
|
952
|
-
}
|
|
953
934
|
|
|
954
935
|
// src/provider.ts
|
|
955
936
|
var ConsistencyProvider = (0, import_core7.createProvider)({
|
|
@@ -970,7 +951,7 @@ var ConsistencyProvider = (0, import_core7.createProvider)({
|
|
|
970
951
|
const results = output.results;
|
|
971
952
|
const allIssues = results.flatMap((r) => r.issues);
|
|
972
953
|
const totalFiles = output.summary.filesAnalyzed || results.length;
|
|
973
|
-
return
|
|
954
|
+
return calculateConsistencyScore(
|
|
974
955
|
allIssues,
|
|
975
956
|
totalFiles,
|
|
976
957
|
options.costConfig
|