@aiready/consistency 0.3.3 → 0.3.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/chunk-Q5XMWG33.mjs +661 -0
- package/dist/chunk-TLVLM3M5.mjs +771 -0
- package/dist/cli.js +277 -14
- package/dist/cli.mjs +1 -1
- package/dist/index.js +277 -14
- package/dist/index.mjs +1 -1
- package/package.json +13 -12
- package/src/__tests__/analyzer.test.ts +14 -1
- package/src/analyzers/naming.ts +137 -23
- package/.turbo/turbo-build.log +0 -24
- package/.turbo/turbo-test.log +0 -76
package/dist/index.js
CHANGED
|
@@ -32,12 +32,154 @@ var import_core3 = require("@aiready/core");
|
|
|
32
32
|
|
|
33
33
|
// src/analyzers/naming.ts
|
|
34
34
|
var import_core = require("@aiready/core");
|
|
35
|
+
var COMMON_SHORT_WORDS = /* @__PURE__ */ new Set([
|
|
36
|
+
// Full English words (1-3 letters)
|
|
37
|
+
"day",
|
|
38
|
+
"key",
|
|
39
|
+
"net",
|
|
40
|
+
"to",
|
|
41
|
+
"go",
|
|
42
|
+
"for",
|
|
43
|
+
"not",
|
|
44
|
+
"new",
|
|
45
|
+
"old",
|
|
46
|
+
"top",
|
|
47
|
+
"end",
|
|
48
|
+
"run",
|
|
49
|
+
"try",
|
|
50
|
+
"use",
|
|
51
|
+
"get",
|
|
52
|
+
"set",
|
|
53
|
+
"add",
|
|
54
|
+
"put",
|
|
55
|
+
"map",
|
|
56
|
+
"log",
|
|
57
|
+
"row",
|
|
58
|
+
"col",
|
|
59
|
+
"tab",
|
|
60
|
+
"box",
|
|
61
|
+
"div",
|
|
62
|
+
"nav",
|
|
63
|
+
"tag",
|
|
64
|
+
"any",
|
|
65
|
+
"all",
|
|
66
|
+
"one",
|
|
67
|
+
"two",
|
|
68
|
+
"out",
|
|
69
|
+
"off",
|
|
70
|
+
"on",
|
|
71
|
+
"yes",
|
|
72
|
+
"no",
|
|
73
|
+
"now",
|
|
74
|
+
"max",
|
|
75
|
+
"min",
|
|
76
|
+
"sum",
|
|
77
|
+
"avg",
|
|
78
|
+
"ref",
|
|
79
|
+
"src",
|
|
80
|
+
"dst",
|
|
81
|
+
"raw",
|
|
82
|
+
"def",
|
|
83
|
+
"sub",
|
|
84
|
+
"pub",
|
|
85
|
+
"pre",
|
|
86
|
+
"mid",
|
|
87
|
+
"alt",
|
|
88
|
+
"opt",
|
|
89
|
+
"tmp",
|
|
90
|
+
"ext",
|
|
91
|
+
"sep",
|
|
92
|
+
// Additional full words commonly flagged
|
|
93
|
+
"tax",
|
|
94
|
+
"cat",
|
|
95
|
+
"dog",
|
|
96
|
+
"car",
|
|
97
|
+
"bus",
|
|
98
|
+
"web",
|
|
99
|
+
"app",
|
|
100
|
+
"war",
|
|
101
|
+
"law",
|
|
102
|
+
"pay",
|
|
103
|
+
"buy",
|
|
104
|
+
"win",
|
|
105
|
+
"cut",
|
|
106
|
+
"hit",
|
|
107
|
+
"hot",
|
|
108
|
+
"pop",
|
|
109
|
+
"job",
|
|
110
|
+
"age",
|
|
111
|
+
"act",
|
|
112
|
+
"let",
|
|
113
|
+
"lot",
|
|
114
|
+
"bad",
|
|
115
|
+
"big",
|
|
116
|
+
"far",
|
|
117
|
+
"few",
|
|
118
|
+
"own",
|
|
119
|
+
"per",
|
|
120
|
+
"red",
|
|
121
|
+
"low",
|
|
122
|
+
"see",
|
|
123
|
+
"six",
|
|
124
|
+
"ten",
|
|
125
|
+
"way",
|
|
126
|
+
"who",
|
|
127
|
+
"why",
|
|
128
|
+
"yet",
|
|
129
|
+
"via",
|
|
130
|
+
"due",
|
|
131
|
+
"fee",
|
|
132
|
+
"fun",
|
|
133
|
+
"gas",
|
|
134
|
+
"gay",
|
|
135
|
+
"god",
|
|
136
|
+
"gun",
|
|
137
|
+
"guy",
|
|
138
|
+
"ice",
|
|
139
|
+
"ill",
|
|
140
|
+
"kid",
|
|
141
|
+
"mad",
|
|
142
|
+
"man",
|
|
143
|
+
"mix",
|
|
144
|
+
"mom",
|
|
145
|
+
"mrs",
|
|
146
|
+
"nor",
|
|
147
|
+
"odd",
|
|
148
|
+
"oil",
|
|
149
|
+
"pan",
|
|
150
|
+
"pet",
|
|
151
|
+
"pit",
|
|
152
|
+
"pot",
|
|
153
|
+
"pow",
|
|
154
|
+
"pro",
|
|
155
|
+
"raw",
|
|
156
|
+
"rep",
|
|
157
|
+
"rid",
|
|
158
|
+
"sad",
|
|
159
|
+
"sea",
|
|
160
|
+
"sit",
|
|
161
|
+
"sky",
|
|
162
|
+
"son",
|
|
163
|
+
"tea",
|
|
164
|
+
"tie",
|
|
165
|
+
"tip",
|
|
166
|
+
"van",
|
|
167
|
+
"war",
|
|
168
|
+
"win",
|
|
169
|
+
"won"
|
|
170
|
+
]);
|
|
35
171
|
var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
36
172
|
// Standard identifiers
|
|
37
173
|
"id",
|
|
38
174
|
"uid",
|
|
39
175
|
"gid",
|
|
40
176
|
"pid",
|
|
177
|
+
// Loop counters and iterators
|
|
178
|
+
"i",
|
|
179
|
+
"j",
|
|
180
|
+
"k",
|
|
181
|
+
"n",
|
|
182
|
+
"m",
|
|
41
183
|
// Web/Network
|
|
42
184
|
"url",
|
|
43
185
|
"uri",
|
|
@@ -55,6 +197,9 @@ var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
|
55
197
|
"rss",
|
|
56
198
|
"xhr",
|
|
57
199
|
"ajax",
|
|
200
|
+
"cors",
|
|
201
|
+
"ws",
|
|
202
|
+
"wss",
|
|
58
203
|
// Data formats
|
|
59
204
|
"json",
|
|
60
205
|
"xml",
|
|
@@ -64,12 +209,27 @@ var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
|
64
209
|
"css",
|
|
65
210
|
"svg",
|
|
66
211
|
"pdf",
|
|
212
|
+
// File types & extensions
|
|
213
|
+
"img",
|
|
214
|
+
"txt",
|
|
215
|
+
"doc",
|
|
216
|
+
"docx",
|
|
217
|
+
"xlsx",
|
|
218
|
+
"ppt",
|
|
219
|
+
"md",
|
|
220
|
+
"rst",
|
|
221
|
+
"jpg",
|
|
222
|
+
"png",
|
|
223
|
+
"gif",
|
|
67
224
|
// Databases
|
|
68
225
|
"db",
|
|
69
226
|
"sql",
|
|
70
227
|
"orm",
|
|
71
228
|
"dao",
|
|
72
229
|
"dto",
|
|
230
|
+
"ddb",
|
|
231
|
+
"rds",
|
|
232
|
+
"nosql",
|
|
73
233
|
// File system
|
|
74
234
|
"fs",
|
|
75
235
|
"dir",
|
|
@@ -86,6 +246,8 @@ var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
|
86
246
|
"cli",
|
|
87
247
|
"cmd",
|
|
88
248
|
"exe",
|
|
249
|
+
"cwd",
|
|
250
|
+
"pwd",
|
|
89
251
|
// UI/UX
|
|
90
252
|
"ui",
|
|
91
253
|
"ux",
|
|
@@ -98,6 +260,7 @@ var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
|
98
260
|
"ctx",
|
|
99
261
|
"err",
|
|
100
262
|
"msg",
|
|
263
|
+
"auth",
|
|
101
264
|
// Mathematics/Computing
|
|
102
265
|
"max",
|
|
103
266
|
"min",
|
|
@@ -115,12 +278,17 @@ var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
|
115
278
|
"var",
|
|
116
279
|
"int",
|
|
117
280
|
"num",
|
|
281
|
+
"idx",
|
|
118
282
|
// Time
|
|
119
283
|
"now",
|
|
120
284
|
"utc",
|
|
121
285
|
"tz",
|
|
122
286
|
"ms",
|
|
123
287
|
"sec",
|
|
288
|
+
"hr",
|
|
289
|
+
"min",
|
|
290
|
+
"yr",
|
|
291
|
+
"mo",
|
|
124
292
|
// Common patterns
|
|
125
293
|
"app",
|
|
126
294
|
"cfg",
|
|
@@ -140,13 +308,70 @@ var ACCEPTABLE_ABBREVIATIONS = /* @__PURE__ */ new Set([
|
|
|
140
308
|
"post",
|
|
141
309
|
"sub",
|
|
142
310
|
"pub",
|
|
311
|
+
// Programming/Framework specific
|
|
312
|
+
"ts",
|
|
313
|
+
"js",
|
|
314
|
+
"jsx",
|
|
315
|
+
"tsx",
|
|
316
|
+
"py",
|
|
317
|
+
"rb",
|
|
318
|
+
"vue",
|
|
319
|
+
"re",
|
|
320
|
+
"fn",
|
|
321
|
+
"fns",
|
|
322
|
+
"mod",
|
|
323
|
+
"opts",
|
|
324
|
+
"dev",
|
|
325
|
+
// Cloud/Infrastructure
|
|
326
|
+
"s3",
|
|
327
|
+
"ec2",
|
|
328
|
+
"sqs",
|
|
329
|
+
"sns",
|
|
330
|
+
"vpc",
|
|
331
|
+
"ami",
|
|
332
|
+
"iam",
|
|
333
|
+
"acl",
|
|
334
|
+
"elb",
|
|
335
|
+
"alb",
|
|
336
|
+
"nlb",
|
|
337
|
+
"aws",
|
|
338
|
+
// Metrics/Performance
|
|
339
|
+
"fcp",
|
|
340
|
+
"lcp",
|
|
341
|
+
"cls",
|
|
342
|
+
"ttfb",
|
|
343
|
+
"tti",
|
|
344
|
+
"fid",
|
|
345
|
+
"fps",
|
|
346
|
+
"qps",
|
|
347
|
+
"rps",
|
|
348
|
+
"tps",
|
|
349
|
+
// Testing & i18n
|
|
350
|
+
"po",
|
|
351
|
+
"e2e",
|
|
352
|
+
"a11y",
|
|
353
|
+
"i18n",
|
|
354
|
+
"l10n",
|
|
355
|
+
// Domain-specific abbreviations (context-aware)
|
|
356
|
+
"sk",
|
|
357
|
+
"fy",
|
|
358
|
+
"faq",
|
|
359
|
+
"og",
|
|
360
|
+
"seo",
|
|
361
|
+
"cta",
|
|
362
|
+
"roi",
|
|
363
|
+
"kpi",
|
|
143
364
|
// Boolean helpers (these are intentional short names)
|
|
144
365
|
"is",
|
|
145
366
|
"has",
|
|
146
367
|
"can",
|
|
147
368
|
"did",
|
|
148
369
|
"was",
|
|
149
|
-
"are"
|
|
370
|
+
"are",
|
|
371
|
+
// Date/Time context (when in date contexts)
|
|
372
|
+
"d",
|
|
373
|
+
"t",
|
|
374
|
+
"dt"
|
|
150
375
|
]);
|
|
151
376
|
async function analyzeNaming(files) {
|
|
152
377
|
const issues = [];
|
|
@@ -159,14 +384,22 @@ async function analyzeNaming(files) {
|
|
|
159
384
|
}
|
|
160
385
|
function analyzeFileNaming(file, content) {
|
|
161
386
|
const issues = [];
|
|
387
|
+
const isTestFile = file.match(/\.(test|spec)\.(ts|tsx|js|jsx)$/);
|
|
162
388
|
const lines = content.split("\n");
|
|
163
389
|
lines.forEach((line, index) => {
|
|
164
390
|
const lineNumber = index + 1;
|
|
165
391
|
const singleLetterMatches = line.matchAll(/\b(?:const|let|var)\s+([a-hm-z])\s*=/gi);
|
|
166
392
|
for (const match of singleLetterMatches) {
|
|
167
393
|
const letter = match[1].toLowerCase();
|
|
168
|
-
const isInLoopContext = line.includes("for") ||
|
|
169
|
-
|
|
394
|
+
const isInLoopContext = line.includes("for") || /\.(map|filter|forEach|reduce|find|some|every)\s*\(/.test(line) || line.includes("=>") || // Arrow function
|
|
395
|
+
/\w+\s*=>\s*/.test(line);
|
|
396
|
+
const isI18nContext = line.includes("useTranslation") || line.includes("i18n.t") || /\bt\s*\(['"]/.test(line);
|
|
397
|
+
const isArrowFunctionParam = /\(\s*[a-z]\s*(?:,\s*[a-z]\s*)*\)\s*=>/.test(line) || // (s) => or (a, b) =>
|
|
398
|
+
/[a-z]\s*=>/.test(line);
|
|
399
|
+
if (!isInLoopContext && !isI18nContext && !isArrowFunctionParam && !["x", "y", "z", "i", "j", "k", "l", "n", "m"].includes(letter)) {
|
|
400
|
+
if (isTestFile && ["a", "b", "c", "d", "e", "f", "s"].includes(letter)) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
170
403
|
issues.push({
|
|
171
404
|
file,
|
|
172
405
|
line: lineNumber,
|
|
@@ -180,16 +413,35 @@ function analyzeFileNaming(file, content) {
|
|
|
180
413
|
const abbreviationMatches = line.matchAll(/\b(?:const|let|var)\s+([a-z]{1,3})(?=[A-Z]|_|\s*=)/g);
|
|
181
414
|
for (const match of abbreviationMatches) {
|
|
182
415
|
const abbrev = match[1].toLowerCase();
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
416
|
+
if (COMMON_SHORT_WORDS.has(abbrev)) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (ACCEPTABLE_ABBREVIATIONS.has(abbrev)) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const isArrowFunctionParam = /\(\s*[a-z]\s*(?:,\s*[a-z]\s*)*\)\s*=>/.test(line) || // (s) => or (a, b) =>
|
|
423
|
+
new RegExp(`\\b${abbrev}\\s*=>`).test(line);
|
|
424
|
+
if (isArrowFunctionParam) {
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
if (abbrev.length <= 2) {
|
|
428
|
+
const isDateTimeContext = /date|time|day|hour|minute|second|timestamp/i.test(line);
|
|
429
|
+
if (isDateTimeContext && ["d", "t", "dt"].includes(abbrev)) {
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
const isUserContext = /user|auth|account/i.test(line);
|
|
433
|
+
if (isUserContext && abbrev === "u") {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
192
436
|
}
|
|
437
|
+
issues.push({
|
|
438
|
+
file,
|
|
439
|
+
line: lineNumber,
|
|
440
|
+
type: "abbreviation",
|
|
441
|
+
identifier: match[1],
|
|
442
|
+
severity: "info",
|
|
443
|
+
suggestion: `Consider using full word instead of abbreviation '${match[1]}'`
|
|
444
|
+
});
|
|
193
445
|
}
|
|
194
446
|
if (file.match(/\.(ts|tsx|js|jsx)$/)) {
|
|
195
447
|
const camelCaseVars = line.match(/\b(?:const|let|var)\s+([a-z][a-zA-Z0-9]*)\s*=/);
|
|
@@ -222,11 +474,22 @@ function analyzeFileNaming(file, content) {
|
|
|
222
474
|
const functionMatches = line.matchAll(/function\s+([a-z][a-zA-Z0-9]*)/g);
|
|
223
475
|
for (const match of functionMatches) {
|
|
224
476
|
const name = match[1];
|
|
477
|
+
const isKeyword = ["for", "if", "else", "while", "do", "switch", "case", "break", "continue", "return", "throw", "try", "catch", "finally", "with", "yield", "await"].includes(name);
|
|
478
|
+
if (isKeyword) {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
const isEntryPoint = ["main", "init", "setup", "bootstrap"].includes(name);
|
|
482
|
+
if (isEntryPoint) {
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
225
485
|
const isFactoryPattern = name.match(/(Factory|Builder|Creator|Generator)$/);
|
|
226
486
|
const isEventHandler = name.match(/^on[A-Z]/);
|
|
227
|
-
const isDescriptiveLong = name.length >
|
|
487
|
+
const isDescriptiveLong = name.length > 15;
|
|
488
|
+
const isDescriptivePattern = name.match(/^(default|total|count|sum|avg|max|min|initial|current|previous|next)\w+/) || name.match(/\w+(Count|Total|Sum|Average|List|Map|Set|Config|Settings|Options|Props)$/);
|
|
489
|
+
const capitalCount = (name.match(/[A-Z]/g) || []).length;
|
|
490
|
+
const isCompoundWord = capitalCount >= 3;
|
|
228
491
|
const hasActionVerb = name.match(/^(get|set|is|has|can|should|create|update|delete|fetch|load|save|process|handle|validate|check|find|search|filter|map|reduce|make|do|run|start|stop|build|parse|format|render|calculate|compute|generate|transform|convert|normalize|sanitize|encode|decode|compress|extract|merge|split|join|sort|compare|test|verify|ensure|apply|execute|invoke|call|emit|dispatch|trigger|listen|subscribe|unsubscribe|add|remove|clear|reset|toggle|enable|disable|open|close|connect|disconnect|send|receive|read|write|import|export|register|unregister|mount|unmount)/);
|
|
229
|
-
if (!hasActionVerb && !isFactoryPattern && !isEventHandler && !isDescriptiveLong) {
|
|
492
|
+
if (!hasActionVerb && !isFactoryPattern && !isEventHandler && !isDescriptiveLong && !isDescriptivePattern && !isCompoundWord) {
|
|
230
493
|
issues.push({
|
|
231
494
|
file,
|
|
232
495
|
line: lineNumber,
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/consistency",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.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",
|
|
@@ -15,6 +15,15 @@
|
|
|
15
15
|
"import": "./dist/index.mjs"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts",
|
|
20
|
+
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"lint": "eslint src",
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"prepublishOnly": "pnpm build",
|
|
25
|
+
"release": "pnpm build && pnpm publish --no-git-checks"
|
|
26
|
+
},
|
|
18
27
|
"keywords": [
|
|
19
28
|
"aiready",
|
|
20
29
|
"consistency",
|
|
@@ -39,9 +48,9 @@
|
|
|
39
48
|
},
|
|
40
49
|
"homepage": "https://github.com/caopengau/aiready-consistency",
|
|
41
50
|
"dependencies": {
|
|
51
|
+
"@aiready/core": "workspace:*",
|
|
42
52
|
"chalk": "^5.3.0",
|
|
43
|
-
"commander": "^12.1.0"
|
|
44
|
-
"@aiready/core": "0.7.0"
|
|
53
|
+
"commander": "^12.1.0"
|
|
45
54
|
},
|
|
46
55
|
"devDependencies": {
|
|
47
56
|
"@types/node": "^22.10.5",
|
|
@@ -51,13 +60,5 @@
|
|
|
51
60
|
},
|
|
52
61
|
"engines": {
|
|
53
62
|
"node": ">=18.0.0"
|
|
54
|
-
},
|
|
55
|
-
"scripts": {
|
|
56
|
-
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts",
|
|
57
|
-
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
58
|
-
"test": "vitest run",
|
|
59
|
-
"lint": "eslint src",
|
|
60
|
-
"clean": "rm -rf dist",
|
|
61
|
-
"release": "pnpm build && pnpm publish --no-git-checks"
|
|
62
63
|
}
|
|
63
|
-
}
|
|
64
|
+
}
|
|
@@ -49,12 +49,25 @@ const result = x + y;
|
|
|
49
49
|
const acceptableAbbreviations = [
|
|
50
50
|
'env', 'req', 'res', 'ctx', 'err', 'api', 'url', 'id',
|
|
51
51
|
'max', 'min', 'now', 'utm', 'has', 'is', 'can',
|
|
52
|
-
'db', 'fs', 'os', 'ui', 'tmp', 'src', 'dst'
|
|
52
|
+
'db', 'fs', 'os', 'ui', 'tmp', 'src', 'dst',
|
|
53
|
+
// New additions from Phase 1
|
|
54
|
+
'img', 'txt', 'doc', 'md', 'ts', 'js', 'ddb', 's3',
|
|
55
|
+
'fcp', 'lcp', 'fps', 'po', 'dto', 'e2e', 'a11y', 'i18n'
|
|
53
56
|
];
|
|
54
57
|
// These abbreviations should not trigger warnings
|
|
55
58
|
expect(acceptableAbbreviations.length).toBeGreaterThan(0);
|
|
56
59
|
});
|
|
57
60
|
|
|
61
|
+
it('should NOT flag common short English words', () => {
|
|
62
|
+
// Full words, not abbreviations - should be accepted
|
|
63
|
+
const commonWords = [
|
|
64
|
+
'day', 'key', 'net', 'to', 'go', 'for', 'not', 'new', 'old',
|
|
65
|
+
'top', 'end', 'run', 'try', 'use', 'get', 'set', 'add', 'put'
|
|
66
|
+
];
|
|
67
|
+
// These are full words and should not be flagged as abbreviations
|
|
68
|
+
expect(commonWords.length).toBeGreaterThan(0);
|
|
69
|
+
});
|
|
70
|
+
|
|
58
71
|
it('should detect snake_case in TypeScript files', () => {
|
|
59
72
|
const testCode = `
|
|
60
73
|
const user_name = 'John';
|