@aiready/consistency 0.16.5 → 0.18.1
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 +9 -9
- package/.turbo/turbo-lint.log +13 -1
- package/.turbo/turbo-test.log +14 -10
- package/dist/index.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +116 -78
- package/dist/index.mjs +117 -75
- package/package.json +2 -2
- package/src/__tests__/scoring.test.ts +1 -1
- package/src/index.ts +7 -0
- package/src/provider.ts +48 -0
- package/src/scoring.ts +2 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/consistency@0.
|
|
3
|
+
> @aiready/consistency@0.18.0 build /Users/pengcao/projects/aiready/packages/consistency
|
|
4
4
|
> tsup src/index.ts src/cli.ts --format cjs,esm --dts
|
|
5
5
|
|
|
6
6
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
[34mCLI[39m Target: es2020
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mdist/cli.mjs [22m[32m8.83 KB[39m
|
|
13
12
|
[32mESM[39m [1mdist/chunk-IXBC6GVT.mjs [22m[32m24.93 KB[39m
|
|
14
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
15
|
-
[32mESM[39m
|
|
16
|
-
[
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m7.17 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/cli.mjs [22m[32m8.83 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 59ms
|
|
17
16
|
[32mCJS[39m [1mdist/cli.js [22m[32m35.81 KB[39m
|
|
18
|
-
[32mCJS[39m
|
|
17
|
+
[32mCJS[39m [1mdist/index.js [22m[32m34.41 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 59ms
|
|
19
19
|
DTS Build start
|
|
20
|
-
DTS ⚡️ Build success in
|
|
20
|
+
DTS ⚡️ Build success in 3252ms
|
|
21
21
|
DTS dist/cli.d.ts 20.00 B
|
|
22
|
-
DTS dist/index.d.ts 3.
|
|
22
|
+
DTS dist/index.d.ts 3.46 KB
|
|
23
23
|
DTS dist/cli.d.mts 20.00 B
|
|
24
|
-
DTS dist/index.d.mts 3.
|
|
24
|
+
DTS dist/index.d.mts 3.46 KB
|
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/consistency@0.
|
|
3
|
+
> @aiready/consistency@0.16.5 lint /Users/pengcao/projects/aiready/packages/consistency
|
|
4
4
|
> eslint src
|
|
5
5
|
|
|
6
|
+
[0m
|
|
7
|
+
[4m/Users/pengcao/projects/aiready/packages/consistency/src/analyzers/naming-ast.ts[24m
|
|
8
|
+
[2m7:3[22m [33mwarning[39m 'getFunctionName' is defined but never used [2m@typescript-eslint/no-unused-vars[22m
|
|
9
|
+
[2m9:3[22m [33mwarning[39m 'isCoverageContext' is defined but never used [2m@typescript-eslint/no-unused-vars[22m
|
|
10
|
+
[2m157:17[22m [33mwarning[39m 'node' is assigned a value but never used [2m@typescript-eslint/no-unused-vars[22m
|
|
11
|
+
|
|
12
|
+
[4m/Users/pengcao/projects/aiready/packages/consistency/src/analyzers/patterns.ts[24m
|
|
13
|
+
[2m16:9[22m [33mwarning[39m 'catchPattern' is assigned a value but never used [2m@typescript-eslint/no-unused-vars[22m
|
|
14
|
+
[2m42:9[22m [33mwarning[39m 'totalFiles' is assigned a value but never used [2m@typescript-eslint/no-unused-vars[22m
|
|
15
|
+
|
|
16
|
+
[33m[1m✖ 5 problems (0 errors, 5 warnings)[22m[39m
|
|
17
|
+
[0m
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/consistency@0.
|
|
3
|
+
> @aiready/consistency@0.18.0 test /Users/pengcao/projects/aiready/packages/consistency
|
|
4
4
|
> vitest run
|
|
5
5
|
|
|
6
6
|
[?25l
|
|
7
7
|
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/Users/pengcao/projects/aiready/packages/consistency[39m
|
|
8
8
|
|
|
9
|
-
[32m✓[39m dist/__tests__/scoring.test.js [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
10
|
-
[32m✓[39m src/__tests__/
|
|
11
|
-
[32m✓[39m src/__tests__/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
[32m✓[39m
|
|
9
|
+
[32m✓[39m dist/__tests__/scoring.test.js [2m([22m[2m8 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
10
|
+
[32m✓[39m src/__tests__/language-filter.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
11
|
+
[32m✓[39m src/__tests__/scoring.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
12
|
+
[90mstdout[2m | src/__tests__/contract.test.ts
|
|
13
|
+
[22m[39m[ToolRegistry#0.6903712051329124] Registering tool: naming-consistency (consistency, naming, standards)
|
|
14
|
+
|
|
15
|
+
[32m✓[39m src/__tests__/contract.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
16
|
+
[32m✓[39m dist/__tests__/language-filter.test.js [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
17
|
+
[32m✓[39m src/__tests__/analyzer.test.ts [2m([22m[2m18 tests[22m[2m)[22m[33m 461[2mms[22m[39m
|
|
18
|
+
[32m✓[39m dist/__tests__/analyzer.test.js [2m([22m[2m18 tests[22m[2m)[22m[33m 596[2mms[22m[39m
|
|
19
|
+
[33m[2m✓[22m[39m should generate relevant recommendations [33m 316[2mms[22m[39m
|
|
16
20
|
|
|
17
21
|
[2m Test Files [22m [1m[32m7 passed[39m[22m[90m (7)[39m
|
|
18
22
|
[2m Tests [22m [1m[32m59 passed[39m[22m[90m (59)[39m
|
|
19
|
-
[2m Start at [22m
|
|
20
|
-
[2m Duration [22m
|
|
23
|
+
[2m Start at [22m 10:34:41
|
|
24
|
+
[2m Duration [22m 2.37s[2m (transform 1.76s, setup 0ms, import 7.55s, tests 1.08s, environment 0ms)[22m
|
|
21
25
|
|
|
22
26
|
[?25h
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { Severity, Issue, IssueType, ScanOptions, AnalysisResult, CostConfig, ToolScoringOutput } from '@aiready/core';
|
|
1
|
+
import { ToolProvider, Severity, Issue, IssueType, ScanOptions, AnalysisResult, CostConfig, ToolScoringOutput } from '@aiready/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Consistency Tool Provider
|
|
5
|
+
*/
|
|
6
|
+
declare const ConsistencyProvider: ToolProvider;
|
|
2
7
|
|
|
3
8
|
interface ConsistencyOptions extends ScanOptions {
|
|
4
9
|
/** Check naming conventions and quality */
|
|
@@ -99,4 +104,4 @@ declare function analyzePatterns(filePaths: string[]): Promise<PatternIssue[]>;
|
|
|
99
104
|
*/
|
|
100
105
|
declare function calculateConsistencyScore(issues: ConsistencyIssue[], totalFilesAnalyzed: number, costConfig?: Partial<CostConfig>): ToolScoringOutput;
|
|
101
106
|
|
|
102
|
-
export { type ArchitectureIssue, type ConsistencyIssue, type ConsistencyOptions, type ConsistencyReport, type NamingIssue, type PatternIssue, analyzeConsistency, analyzeNaming, analyzeNamingAST, analyzePatterns, calculateConsistencyScore, detectNamingConventions };
|
|
107
|
+
export { type ArchitectureIssue, type ConsistencyIssue, type ConsistencyOptions, ConsistencyProvider, type ConsistencyReport, type NamingIssue, type PatternIssue, analyzeConsistency, analyzeNaming, analyzeNamingAST, analyzePatterns, calculateConsistencyScore, detectNamingConventions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { Severity, Issue, IssueType, ScanOptions, AnalysisResult, CostConfig, ToolScoringOutput } from '@aiready/core';
|
|
1
|
+
import { ToolProvider, Severity, Issue, IssueType, ScanOptions, AnalysisResult, CostConfig, ToolScoringOutput } from '@aiready/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Consistency Tool Provider
|
|
5
|
+
*/
|
|
6
|
+
declare const ConsistencyProvider: ToolProvider;
|
|
2
7
|
|
|
3
8
|
interface ConsistencyOptions extends ScanOptions {
|
|
4
9
|
/** Check naming conventions and quality */
|
|
@@ -99,4 +104,4 @@ declare function analyzePatterns(filePaths: string[]): Promise<PatternIssue[]>;
|
|
|
99
104
|
*/
|
|
100
105
|
declare function calculateConsistencyScore(issues: ConsistencyIssue[], totalFilesAnalyzed: number, costConfig?: Partial<CostConfig>): ToolScoringOutput;
|
|
101
106
|
|
|
102
|
-
export { type ArchitectureIssue, type ConsistencyIssue, type ConsistencyOptions, type ConsistencyReport, type NamingIssue, type PatternIssue, analyzeConsistency, analyzeNaming, analyzeNamingAST, analyzePatterns, calculateConsistencyScore, detectNamingConventions };
|
|
107
|
+
export { type ArchitectureIssue, type ConsistencyIssue, type ConsistencyOptions, ConsistencyProvider, type ConsistencyReport, type NamingIssue, type PatternIssue, analyzeConsistency, analyzeNaming, analyzeNamingAST, analyzePatterns, calculateConsistencyScore, detectNamingConventions };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ConsistencyProvider: () => ConsistencyProvider,
|
|
33
34
|
analyzeConsistency: () => analyzeConsistency,
|
|
34
35
|
analyzeNaming: () => analyzeNaming,
|
|
35
36
|
analyzeNamingAST: () => analyzeNamingAST,
|
|
@@ -38,6 +39,10 @@ __export(index_exports, {
|
|
|
38
39
|
detectNamingConventions: () => detectNamingConventions
|
|
39
40
|
});
|
|
40
41
|
module.exports = __toCommonJS(index_exports);
|
|
42
|
+
var import_core9 = require("@aiready/core");
|
|
43
|
+
|
|
44
|
+
// src/provider.ts
|
|
45
|
+
var import_core7 = require("@aiready/core");
|
|
41
46
|
|
|
42
47
|
// src/analyzer.ts
|
|
43
48
|
var import_core5 = require("@aiready/core");
|
|
@@ -866,83 +871,8 @@ function generateRecommendations(namingIssues, patternIssues) {
|
|
|
866
871
|
return recommendations;
|
|
867
872
|
}
|
|
868
873
|
|
|
869
|
-
// src/analyzers/naming.ts
|
|
870
|
-
var import_fs3 = require("fs");
|
|
871
|
-
var import_core6 = require("@aiready/core");
|
|
872
|
-
async function analyzeNaming(filePaths) {
|
|
873
|
-
const issues = [];
|
|
874
|
-
for (const filePath of filePaths) {
|
|
875
|
-
try {
|
|
876
|
-
const content = (0, import_fs3.readFileSync)(filePath, "utf-8");
|
|
877
|
-
const lines = content.split("\n");
|
|
878
|
-
lines.forEach((line, index) => {
|
|
879
|
-
const singleLetterMatch = line.match(
|
|
880
|
-
/\b(const|let|var)\s+([a-hj-km-np-zA-Z])\s*=/
|
|
881
|
-
);
|
|
882
|
-
if (singleLetterMatch) {
|
|
883
|
-
issues.push({
|
|
884
|
-
file: filePath,
|
|
885
|
-
line: index + 1,
|
|
886
|
-
type: "poor-naming",
|
|
887
|
-
identifier: singleLetterMatch[2],
|
|
888
|
-
severity: import_core6.Severity.Minor,
|
|
889
|
-
suggestion: "Use a more descriptive name than a single letter"
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
if (filePath.match(/\.(ts|tsx|js|jsx)$/)) {
|
|
893
|
-
const snakeCaseMatch = line.match(
|
|
894
|
-
/\b(const|let|var|function)\s+([a-z]+_[a-z0-9_]+)\b/
|
|
895
|
-
);
|
|
896
|
-
if (snakeCaseMatch) {
|
|
897
|
-
issues.push({
|
|
898
|
-
file: filePath,
|
|
899
|
-
line: index + 1,
|
|
900
|
-
type: "convention-mix",
|
|
901
|
-
identifier: snakeCaseMatch[2],
|
|
902
|
-
severity: import_core6.Severity.Info,
|
|
903
|
-
suggestion: "Use camelCase instead of snake_case in TypeScript/JavaScript"
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
const shortNameMatch = line.match(
|
|
908
|
-
/\b(const|let|var)\s+([a-zA-Z0-9]{2,3})\s*=/
|
|
909
|
-
);
|
|
910
|
-
if (shortNameMatch) {
|
|
911
|
-
const name = shortNameMatch[2].toLowerCase();
|
|
912
|
-
const vagueNames = ["obj", "val", "tmp", "res", "ret", "data"];
|
|
913
|
-
if (vagueNames.includes(name)) {
|
|
914
|
-
issues.push({
|
|
915
|
-
file: filePath,
|
|
916
|
-
line: index + 1,
|
|
917
|
-
type: "poor-naming",
|
|
918
|
-
identifier: name,
|
|
919
|
-
severity: import_core6.Severity.Minor,
|
|
920
|
-
suggestion: `Avoid vague names like '${name}'`
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
});
|
|
925
|
-
} catch (err) {
|
|
926
|
-
void err;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
return issues;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
// src/analyzers/naming-constants.ts
|
|
933
|
-
function detectNamingConventions(files, allIssues) {
|
|
934
|
-
const camelCaseCount = allIssues.filter(
|
|
935
|
-
(i) => i.type === "convention-mix"
|
|
936
|
-
).length;
|
|
937
|
-
const totalChecks = files.length * 10;
|
|
938
|
-
if (camelCaseCount / totalChecks > 0.3) {
|
|
939
|
-
return { dominantConvention: "mixed", conventionScore: 0.5 };
|
|
940
|
-
}
|
|
941
|
-
return { dominantConvention: "camelCase", conventionScore: 0.9 };
|
|
942
|
-
}
|
|
943
|
-
|
|
944
874
|
// src/scoring.ts
|
|
945
|
-
var
|
|
875
|
+
var import_core6 = require("@aiready/core");
|
|
946
876
|
function calculateConsistencyScore2(issues, totalFilesAnalyzed, costConfig) {
|
|
947
877
|
void costConfig;
|
|
948
878
|
const criticalIssues = issues.filter((i) => i.severity === "critical").length;
|
|
@@ -1018,9 +948,9 @@ function calculateConsistencyScore2(issues, totalFilesAnalyzed, costConfig) {
|
|
|
1018
948
|
priority: "low"
|
|
1019
949
|
});
|
|
1020
950
|
}
|
|
1021
|
-
const productivityImpact = (0,
|
|
951
|
+
const productivityImpact = (0, import_core6.calculateProductivityImpact)(issues);
|
|
1022
952
|
return {
|
|
1023
|
-
toolName:
|
|
953
|
+
toolName: import_core6.ToolName.NamingConsistency,
|
|
1024
954
|
score,
|
|
1025
955
|
rawMetrics: {
|
|
1026
956
|
totalIssues,
|
|
@@ -1036,8 +966,116 @@ function calculateConsistencyScore2(issues, totalFilesAnalyzed, costConfig) {
|
|
|
1036
966
|
recommendations
|
|
1037
967
|
};
|
|
1038
968
|
}
|
|
969
|
+
|
|
970
|
+
// src/provider.ts
|
|
971
|
+
var ConsistencyProvider = {
|
|
972
|
+
id: import_core7.ToolName.NamingConsistency,
|
|
973
|
+
alias: ["consistency", "naming", "standards"],
|
|
974
|
+
async analyze(options) {
|
|
975
|
+
const report = await analyzeConsistency(options);
|
|
976
|
+
return import_core7.SpokeOutputSchema.parse({
|
|
977
|
+
results: report.results,
|
|
978
|
+
summary: report.summary,
|
|
979
|
+
metadata: {
|
|
980
|
+
toolName: import_core7.ToolName.NamingConsistency,
|
|
981
|
+
version: "0.16.5",
|
|
982
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
},
|
|
986
|
+
score(output, options) {
|
|
987
|
+
const results = output.results;
|
|
988
|
+
const allIssues = results.flatMap((r) => r.issues);
|
|
989
|
+
const totalFiles = output.summary.filesAnalyzed || results.length;
|
|
990
|
+
return calculateConsistencyScore2(
|
|
991
|
+
allIssues,
|
|
992
|
+
totalFiles,
|
|
993
|
+
options.costConfig
|
|
994
|
+
);
|
|
995
|
+
},
|
|
996
|
+
defaultWeight: 14
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
// src/analyzers/naming.ts
|
|
1000
|
+
var import_fs3 = require("fs");
|
|
1001
|
+
var import_core8 = require("@aiready/core");
|
|
1002
|
+
async function analyzeNaming(filePaths) {
|
|
1003
|
+
const issues = [];
|
|
1004
|
+
for (const filePath of filePaths) {
|
|
1005
|
+
try {
|
|
1006
|
+
const content = (0, import_fs3.readFileSync)(filePath, "utf-8");
|
|
1007
|
+
const lines = content.split("\n");
|
|
1008
|
+
lines.forEach((line, index) => {
|
|
1009
|
+
const singleLetterMatch = line.match(
|
|
1010
|
+
/\b(const|let|var)\s+([a-hj-km-np-zA-Z])\s*=/
|
|
1011
|
+
);
|
|
1012
|
+
if (singleLetterMatch) {
|
|
1013
|
+
issues.push({
|
|
1014
|
+
file: filePath,
|
|
1015
|
+
line: index + 1,
|
|
1016
|
+
type: "poor-naming",
|
|
1017
|
+
identifier: singleLetterMatch[2],
|
|
1018
|
+
severity: import_core8.Severity.Minor,
|
|
1019
|
+
suggestion: "Use a more descriptive name than a single letter"
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
if (filePath.match(/\.(ts|tsx|js|jsx)$/)) {
|
|
1023
|
+
const snakeCaseMatch = line.match(
|
|
1024
|
+
/\b(const|let|var|function)\s+([a-z]+_[a-z0-9_]+)\b/
|
|
1025
|
+
);
|
|
1026
|
+
if (snakeCaseMatch) {
|
|
1027
|
+
issues.push({
|
|
1028
|
+
file: filePath,
|
|
1029
|
+
line: index + 1,
|
|
1030
|
+
type: "convention-mix",
|
|
1031
|
+
identifier: snakeCaseMatch[2],
|
|
1032
|
+
severity: import_core8.Severity.Info,
|
|
1033
|
+
suggestion: "Use camelCase instead of snake_case in TypeScript/JavaScript"
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const shortNameMatch = line.match(
|
|
1038
|
+
/\b(const|let|var)\s+([a-zA-Z0-9]{2,3})\s*=/
|
|
1039
|
+
);
|
|
1040
|
+
if (shortNameMatch) {
|
|
1041
|
+
const name = shortNameMatch[2].toLowerCase();
|
|
1042
|
+
const vagueNames = ["obj", "val", "tmp", "res", "ret", "data"];
|
|
1043
|
+
if (vagueNames.includes(name)) {
|
|
1044
|
+
issues.push({
|
|
1045
|
+
file: filePath,
|
|
1046
|
+
line: index + 1,
|
|
1047
|
+
type: "poor-naming",
|
|
1048
|
+
identifier: name,
|
|
1049
|
+
severity: import_core8.Severity.Minor,
|
|
1050
|
+
suggestion: `Avoid vague names like '${name}'`
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
});
|
|
1055
|
+
} catch (err) {
|
|
1056
|
+
void err;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
return issues;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
// src/analyzers/naming-constants.ts
|
|
1063
|
+
function detectNamingConventions(files, allIssues) {
|
|
1064
|
+
const camelCaseCount = allIssues.filter(
|
|
1065
|
+
(i) => i.type === "convention-mix"
|
|
1066
|
+
).length;
|
|
1067
|
+
const totalChecks = files.length * 10;
|
|
1068
|
+
if (camelCaseCount / totalChecks > 0.3) {
|
|
1069
|
+
return { dominantConvention: "mixed", conventionScore: 0.5 };
|
|
1070
|
+
}
|
|
1071
|
+
return { dominantConvention: "camelCase", conventionScore: 0.9 };
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// src/index.ts
|
|
1075
|
+
import_core9.ToolRegistry.register(ConsistencyProvider);
|
|
1039
1076
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1040
1077
|
0 && (module.exports = {
|
|
1078
|
+
ConsistencyProvider,
|
|
1041
1079
|
analyzeConsistency,
|
|
1042
1080
|
analyzeNaming,
|
|
1043
1081
|
analyzeNamingAST,
|
package/dist/index.mjs
CHANGED
|
@@ -4,83 +4,17 @@ import {
|
|
|
4
4
|
analyzePatterns
|
|
5
5
|
} from "./chunk-IXBC6GVT.mjs";
|
|
6
6
|
|
|
7
|
-
// src/
|
|
8
|
-
import {
|
|
9
|
-
import { Severity } from "@aiready/core";
|
|
10
|
-
async function analyzeNaming(filePaths) {
|
|
11
|
-
const issues = [];
|
|
12
|
-
for (const filePath of filePaths) {
|
|
13
|
-
try {
|
|
14
|
-
const content = readFileSync(filePath, "utf-8");
|
|
15
|
-
const lines = content.split("\n");
|
|
16
|
-
lines.forEach((line, index) => {
|
|
17
|
-
const singleLetterMatch = line.match(
|
|
18
|
-
/\b(const|let|var)\s+([a-hj-km-np-zA-Z])\s*=/
|
|
19
|
-
);
|
|
20
|
-
if (singleLetterMatch) {
|
|
21
|
-
issues.push({
|
|
22
|
-
file: filePath,
|
|
23
|
-
line: index + 1,
|
|
24
|
-
type: "poor-naming",
|
|
25
|
-
identifier: singleLetterMatch[2],
|
|
26
|
-
severity: Severity.Minor,
|
|
27
|
-
suggestion: "Use a more descriptive name than a single letter"
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
if (filePath.match(/\.(ts|tsx|js|jsx)$/)) {
|
|
31
|
-
const snakeCaseMatch = line.match(
|
|
32
|
-
/\b(const|let|var|function)\s+([a-z]+_[a-z0-9_]+)\b/
|
|
33
|
-
);
|
|
34
|
-
if (snakeCaseMatch) {
|
|
35
|
-
issues.push({
|
|
36
|
-
file: filePath,
|
|
37
|
-
line: index + 1,
|
|
38
|
-
type: "convention-mix",
|
|
39
|
-
identifier: snakeCaseMatch[2],
|
|
40
|
-
severity: Severity.Info,
|
|
41
|
-
suggestion: "Use camelCase instead of snake_case in TypeScript/JavaScript"
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const shortNameMatch = line.match(
|
|
46
|
-
/\b(const|let|var)\s+([a-zA-Z0-9]{2,3})\s*=/
|
|
47
|
-
);
|
|
48
|
-
if (shortNameMatch) {
|
|
49
|
-
const name = shortNameMatch[2].toLowerCase();
|
|
50
|
-
const vagueNames = ["obj", "val", "tmp", "res", "ret", "data"];
|
|
51
|
-
if (vagueNames.includes(name)) {
|
|
52
|
-
issues.push({
|
|
53
|
-
file: filePath,
|
|
54
|
-
line: index + 1,
|
|
55
|
-
type: "poor-naming",
|
|
56
|
-
identifier: name,
|
|
57
|
-
severity: Severity.Minor,
|
|
58
|
-
suggestion: `Avoid vague names like '${name}'`
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
} catch (err) {
|
|
64
|
-
void err;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return issues;
|
|
68
|
-
}
|
|
7
|
+
// src/index.ts
|
|
8
|
+
import { ToolRegistry } from "@aiready/core";
|
|
69
9
|
|
|
70
|
-
// src/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const totalChecks = files.length * 10;
|
|
76
|
-
if (camelCaseCount / totalChecks > 0.3) {
|
|
77
|
-
return { dominantConvention: "mixed", conventionScore: 0.5 };
|
|
78
|
-
}
|
|
79
|
-
return { dominantConvention: "camelCase", conventionScore: 0.9 };
|
|
80
|
-
}
|
|
10
|
+
// src/provider.ts
|
|
11
|
+
import {
|
|
12
|
+
ToolName as ToolName2,
|
|
13
|
+
SpokeOutputSchema
|
|
14
|
+
} from "@aiready/core";
|
|
81
15
|
|
|
82
16
|
// src/scoring.ts
|
|
83
|
-
import { calculateProductivityImpact } from "@aiready/core";
|
|
17
|
+
import { calculateProductivityImpact, ToolName } from "@aiready/core";
|
|
84
18
|
function calculateConsistencyScore(issues, totalFilesAnalyzed, costConfig) {
|
|
85
19
|
void costConfig;
|
|
86
20
|
const criticalIssues = issues.filter((i) => i.severity === "critical").length;
|
|
@@ -158,7 +92,7 @@ function calculateConsistencyScore(issues, totalFilesAnalyzed, costConfig) {
|
|
|
158
92
|
}
|
|
159
93
|
const productivityImpact = calculateProductivityImpact(issues);
|
|
160
94
|
return {
|
|
161
|
-
toolName:
|
|
95
|
+
toolName: ToolName.NamingConsistency,
|
|
162
96
|
score,
|
|
163
97
|
rawMetrics: {
|
|
164
98
|
totalIssues,
|
|
@@ -174,7 +108,115 @@ function calculateConsistencyScore(issues, totalFilesAnalyzed, costConfig) {
|
|
|
174
108
|
recommendations
|
|
175
109
|
};
|
|
176
110
|
}
|
|
111
|
+
|
|
112
|
+
// src/provider.ts
|
|
113
|
+
var ConsistencyProvider = {
|
|
114
|
+
id: ToolName2.NamingConsistency,
|
|
115
|
+
alias: ["consistency", "naming", "standards"],
|
|
116
|
+
async analyze(options) {
|
|
117
|
+
const report = await analyzeConsistency(options);
|
|
118
|
+
return SpokeOutputSchema.parse({
|
|
119
|
+
results: report.results,
|
|
120
|
+
summary: report.summary,
|
|
121
|
+
metadata: {
|
|
122
|
+
toolName: ToolName2.NamingConsistency,
|
|
123
|
+
version: "0.16.5",
|
|
124
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
score(output, options) {
|
|
129
|
+
const results = output.results;
|
|
130
|
+
const allIssues = results.flatMap((r) => r.issues);
|
|
131
|
+
const totalFiles = output.summary.filesAnalyzed || results.length;
|
|
132
|
+
return calculateConsistencyScore(
|
|
133
|
+
allIssues,
|
|
134
|
+
totalFiles,
|
|
135
|
+
options.costConfig
|
|
136
|
+
);
|
|
137
|
+
},
|
|
138
|
+
defaultWeight: 14
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// src/analyzers/naming.ts
|
|
142
|
+
import { readFileSync } from "fs";
|
|
143
|
+
import { Severity } from "@aiready/core";
|
|
144
|
+
async function analyzeNaming(filePaths) {
|
|
145
|
+
const issues = [];
|
|
146
|
+
for (const filePath of filePaths) {
|
|
147
|
+
try {
|
|
148
|
+
const content = readFileSync(filePath, "utf-8");
|
|
149
|
+
const lines = content.split("\n");
|
|
150
|
+
lines.forEach((line, index) => {
|
|
151
|
+
const singleLetterMatch = line.match(
|
|
152
|
+
/\b(const|let|var)\s+([a-hj-km-np-zA-Z])\s*=/
|
|
153
|
+
);
|
|
154
|
+
if (singleLetterMatch) {
|
|
155
|
+
issues.push({
|
|
156
|
+
file: filePath,
|
|
157
|
+
line: index + 1,
|
|
158
|
+
type: "poor-naming",
|
|
159
|
+
identifier: singleLetterMatch[2],
|
|
160
|
+
severity: Severity.Minor,
|
|
161
|
+
suggestion: "Use a more descriptive name than a single letter"
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (filePath.match(/\.(ts|tsx|js|jsx)$/)) {
|
|
165
|
+
const snakeCaseMatch = line.match(
|
|
166
|
+
/\b(const|let|var|function)\s+([a-z]+_[a-z0-9_]+)\b/
|
|
167
|
+
);
|
|
168
|
+
if (snakeCaseMatch) {
|
|
169
|
+
issues.push({
|
|
170
|
+
file: filePath,
|
|
171
|
+
line: index + 1,
|
|
172
|
+
type: "convention-mix",
|
|
173
|
+
identifier: snakeCaseMatch[2],
|
|
174
|
+
severity: Severity.Info,
|
|
175
|
+
suggestion: "Use camelCase instead of snake_case in TypeScript/JavaScript"
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const shortNameMatch = line.match(
|
|
180
|
+
/\b(const|let|var)\s+([a-zA-Z0-9]{2,3})\s*=/
|
|
181
|
+
);
|
|
182
|
+
if (shortNameMatch) {
|
|
183
|
+
const name = shortNameMatch[2].toLowerCase();
|
|
184
|
+
const vagueNames = ["obj", "val", "tmp", "res", "ret", "data"];
|
|
185
|
+
if (vagueNames.includes(name)) {
|
|
186
|
+
issues.push({
|
|
187
|
+
file: filePath,
|
|
188
|
+
line: index + 1,
|
|
189
|
+
type: "poor-naming",
|
|
190
|
+
identifier: name,
|
|
191
|
+
severity: Severity.Minor,
|
|
192
|
+
suggestion: `Avoid vague names like '${name}'`
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
} catch (err) {
|
|
198
|
+
void err;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return issues;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/analyzers/naming-constants.ts
|
|
205
|
+
function detectNamingConventions(files, allIssues) {
|
|
206
|
+
const camelCaseCount = allIssues.filter(
|
|
207
|
+
(i) => i.type === "convention-mix"
|
|
208
|
+
).length;
|
|
209
|
+
const totalChecks = files.length * 10;
|
|
210
|
+
if (camelCaseCount / totalChecks > 0.3) {
|
|
211
|
+
return { dominantConvention: "mixed", conventionScore: 0.5 };
|
|
212
|
+
}
|
|
213
|
+
return { dominantConvention: "camelCase", conventionScore: 0.9 };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/index.ts
|
|
217
|
+
ToolRegistry.register(ConsistencyProvider);
|
|
177
218
|
export {
|
|
219
|
+
ConsistencyProvider,
|
|
178
220
|
analyzeConsistency,
|
|
179
221
|
analyzeNaming,
|
|
180
222
|
analyzeNamingAST,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/consistency",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
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.
|
|
46
|
+
"@aiready/core": "0.21.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/node": "^24.0.0",
|
|
@@ -8,7 +8,7 @@ describe('Consistency Scoring', () => {
|
|
|
8
8
|
const result = calculateConsistencyScore([], 100);
|
|
9
9
|
|
|
10
10
|
expect(result.score).toBe(100);
|
|
11
|
-
expect(result.toolName).toBe('consistency');
|
|
11
|
+
expect(result.toolName).toBe('naming-consistency');
|
|
12
12
|
expect(result.rawMetrics.totalIssues).toBe(0);
|
|
13
13
|
expect(result.recommendations).toHaveLength(0);
|
|
14
14
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import { ToolRegistry } from '@aiready/core';
|
|
2
|
+
import { ConsistencyProvider } from './provider';
|
|
3
|
+
|
|
4
|
+
// Register with global registry
|
|
5
|
+
ToolRegistry.register(ConsistencyProvider);
|
|
6
|
+
|
|
1
7
|
export { analyzeConsistency } from './analyzer';
|
|
2
8
|
export { analyzeNamingAST } from './analyzers/naming-ast';
|
|
3
9
|
export { analyzeNaming } from './analyzers/naming'; // Legacy regex version
|
|
4
10
|
export { detectNamingConventions } from './analyzers/naming-constants';
|
|
5
11
|
export { analyzePatterns } from './analyzers/patterns';
|
|
6
12
|
export { calculateConsistencyScore } from './scoring';
|
|
13
|
+
export { ConsistencyProvider };
|
|
7
14
|
export type {
|
|
8
15
|
ConsistencyOptions,
|
|
9
16
|
ConsistencyReport,
|
package/src/provider.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ToolProvider,
|
|
3
|
+
ToolName,
|
|
4
|
+
SpokeOutput,
|
|
5
|
+
ScanOptions,
|
|
6
|
+
ToolScoringOutput,
|
|
7
|
+
AnalysisResult,
|
|
8
|
+
SpokeOutputSchema,
|
|
9
|
+
} from '@aiready/core';
|
|
10
|
+
import { analyzeConsistency } from './analyzer';
|
|
11
|
+
import { calculateConsistencyScore } from './scoring';
|
|
12
|
+
import { ConsistencyOptions, ConsistencyIssue } from './types';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Consistency Tool Provider
|
|
16
|
+
*/
|
|
17
|
+
export const ConsistencyProvider: ToolProvider = {
|
|
18
|
+
id: ToolName.NamingConsistency,
|
|
19
|
+
alias: ['consistency', 'naming', 'standards'],
|
|
20
|
+
|
|
21
|
+
async analyze(options: ScanOptions): Promise<SpokeOutput> {
|
|
22
|
+
const report = await analyzeConsistency(options as ConsistencyOptions);
|
|
23
|
+
|
|
24
|
+
return SpokeOutputSchema.parse({
|
|
25
|
+
results: report.results as AnalysisResult[],
|
|
26
|
+
summary: report.summary,
|
|
27
|
+
metadata: {
|
|
28
|
+
toolName: ToolName.NamingConsistency,
|
|
29
|
+
version: '0.16.5',
|
|
30
|
+
timestamp: new Date().toISOString(),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
score(output: SpokeOutput, options: ScanOptions): ToolScoringOutput {
|
|
36
|
+
const results = output.results as AnalysisResult[];
|
|
37
|
+
const allIssues = results.flatMap((r) => r.issues as ConsistencyIssue[]);
|
|
38
|
+
const totalFiles = (output.summary as any).filesAnalyzed || results.length;
|
|
39
|
+
|
|
40
|
+
return calculateConsistencyScore(
|
|
41
|
+
allIssues,
|
|
42
|
+
totalFiles,
|
|
43
|
+
(options as any).costConfig
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
defaultWeight: 14,
|
|
48
|
+
};
|
package/src/scoring.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { calculateProductivityImpact } from '@aiready/core';
|
|
1
|
+
import { calculateProductivityImpact, ToolName } from '@aiready/core';
|
|
2
2
|
import type { ToolScoringOutput, CostConfig } from '@aiready/core';
|
|
3
3
|
import type { ConsistencyIssue } from './types';
|
|
4
4
|
|
|
@@ -127,7 +127,7 @@ export function calculateConsistencyScore(
|
|
|
127
127
|
const productivityImpact = calculateProductivityImpact(issues);
|
|
128
128
|
|
|
129
129
|
return {
|
|
130
|
-
toolName:
|
|
130
|
+
toolName: ToolName.NamingConsistency,
|
|
131
131
|
score,
|
|
132
132
|
rawMetrics: {
|
|
133
133
|
totalIssues,
|