@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/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") || line.includes(".map") || line.includes(".filter") || line.includes(".forEach") || line.includes(".reduce");
169
- if (!isInLoopContext && !["x", "y", "z", "i", "j", "k", "l", "n", "m"].includes(letter)) {
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 (!ACCEPTABLE_ABBREVIATIONS.has(abbrev)) {
184
- issues.push({
185
- file,
186
- line: lineNumber,
187
- type: "abbreviation",
188
- identifier: match[1],
189
- severity: "info",
190
- suggestion: `Consider using full word instead of abbreviation '${match[1]}'`
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 > 20;
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
@@ -3,7 +3,7 @@ import {
3
3
  analyzeNaming,
4
4
  analyzePatterns,
5
5
  detectNamingConventions
6
- } from "./chunk-LUAREV6A.mjs";
6
+ } from "./chunk-TLVLM3M5.mjs";
7
7
  export {
8
8
  analyzeConsistency,
9
9
  analyzeNaming,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/consistency",
3
- "version": "0.3.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';