@aiready/consistency 0.20.13 → 0.20.14

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/cli.js CHANGED
@@ -301,16 +301,22 @@ function analyzeIdentifiers(ast, filePath, context) {
301
301
  );
302
302
  }
303
303
  if (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
304
+ const isArrowParameter = node.type === "ArrowFunctionExpression";
304
305
  node.params.forEach((param) => {
305
306
  if (param.type === "Identifier") {
306
307
  scopeTracker.declareVariable(
307
308
  param.name,
308
309
  param,
309
310
  getLineNumber(param),
310
- { isParameter: true }
311
+ { isParameter: true, isArrowParameter }
311
312
  );
312
313
  } else if (param.type === "ObjectPattern") {
313
- extractDestructuredIdentifiers(param, true, scopeTracker);
314
+ extractDestructuredIdentifiers(
315
+ param,
316
+ true,
317
+ scopeTracker,
318
+ isArrowParameter
319
+ );
314
320
  }
315
321
  });
316
322
  }
@@ -357,7 +363,7 @@ function checkVariableNaming(varInfo, file, issues, context) {
357
363
  if (isAcceptableInContext(name, context, options)) {
358
364
  return;
359
365
  }
360
- if (name.length === 1 && !options.isLoopVariable) {
366
+ if (name.length === 1 && !options.isLoopVariable && !options.isArrowParameter) {
361
367
  const severity = adjustSeverity(import_core2.Severity.Minor, context, "poor-naming");
362
368
  issues.push({
363
369
  file,
@@ -457,7 +463,7 @@ var ScopeTracker = class {
457
463
  return this.variables;
458
464
  }
459
465
  };
460
- function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
466
+ function extractDestructuredIdentifiers(node, isParameter, scopeTracker, isArrowParameter = false) {
461
467
  if (node.type === "ObjectPattern") {
462
468
  node.properties.forEach((prop) => {
463
469
  if (prop.type === "Property" && prop.value.type === "Identifier") {
@@ -467,7 +473,8 @@ function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
467
473
  getLineNumber(prop.value),
468
474
  {
469
475
  isParameter,
470
- isDestructured: true
476
+ isDestructured: true,
477
+ isArrowParameter
471
478
  }
472
479
  );
473
480
  }
@@ -481,7 +488,8 @@ function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
481
488
  getLineNumber(element),
482
489
  {
483
490
  isParameter,
484
- isDestructured: true
491
+ isDestructured: true,
492
+ isArrowParameter
485
493
  }
486
494
  );
487
495
  }
@@ -554,8 +562,22 @@ async function analyzeNamingGeneralized(files) {
554
562
  } else if (exp.type === "type" && conventions.typePattern) {
555
563
  pattern = conventions.typePattern;
556
564
  } else if (exp.type === "function") {
565
+ if (/^[A-Z][a-zA-Z0-9]*$/.test(exp.name) || /^[A-Z][A-Z0-9_]*$/.test(exp.name)) {
566
+ continue;
567
+ }
557
568
  pattern = conventions.functionPattern;
558
569
  } else if (exp.type === "const") {
570
+ if ([
571
+ "handler",
572
+ "GET",
573
+ "POST",
574
+ "PUT",
575
+ "DELETE",
576
+ "PATCH",
577
+ "OPTIONS",
578
+ "HEAD"
579
+ ].includes(exp.name))
580
+ continue;
559
581
  pattern = exp.isPrimitive ? conventions.constantPattern : conventions.variablePattern;
560
582
  } else {
561
583
  pattern = conventions.variablePattern;
@@ -579,7 +601,7 @@ async function analyzeNamingGeneralized(files) {
579
601
  if (!spec || spec === "*" || spec === "default") continue;
580
602
  if (exceptions.has(spec)) continue;
581
603
  if (COMMON_ABBREVIATIONS.has(spec.toLowerCase())) continue;
582
- if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec) && !conventions.constantPattern.test(spec) && (!conventions.typePattern || !conventions.typePattern.test(spec)) && (!conventions.interfacePattern || !conventions.interfacePattern.test(spec))) {
604
+ if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec) && (!conventions.constantPattern || !conventions.constantPattern.test(spec)) && (!conventions.typePattern || !conventions.typePattern.test(spec)) && (!conventions.interfacePattern || !conventions.interfacePattern.test(spec)) && !/^[A-Z][A-Z0-9_]*$/.test(spec)) {
583
605
  issues.push({
584
606
  type: "naming-inconsistency",
585
607
  identifier: spec,
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  analyzeConsistency
4
- } from "./chunk-LSXZH6X6.mjs";
4
+ } from "./chunk-6H3JHDP7.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -309,16 +309,22 @@ function analyzeIdentifiers(ast, filePath, context) {
309
309
  );
310
310
  }
311
311
  if (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
312
+ const isArrowParameter = node.type === "ArrowFunctionExpression";
312
313
  node.params.forEach((param) => {
313
314
  if (param.type === "Identifier") {
314
315
  scopeTracker.declareVariable(
315
316
  param.name,
316
317
  param,
317
318
  getLineNumber(param),
318
- { isParameter: true }
319
+ { isParameter: true, isArrowParameter }
319
320
  );
320
321
  } else if (param.type === "ObjectPattern") {
321
- extractDestructuredIdentifiers(param, true, scopeTracker);
322
+ extractDestructuredIdentifiers(
323
+ param,
324
+ true,
325
+ scopeTracker,
326
+ isArrowParameter
327
+ );
322
328
  }
323
329
  });
324
330
  }
@@ -365,7 +371,7 @@ function checkVariableNaming(varInfo, file, issues, context) {
365
371
  if (isAcceptableInContext(name, context, options)) {
366
372
  return;
367
373
  }
368
- if (name.length === 1 && !options.isLoopVariable) {
374
+ if (name.length === 1 && !options.isLoopVariable && !options.isArrowParameter) {
369
375
  const severity = adjustSeverity(import_core2.Severity.Minor, context, "poor-naming");
370
376
  issues.push({
371
377
  file,
@@ -465,7 +471,7 @@ var ScopeTracker = class {
465
471
  return this.variables;
466
472
  }
467
473
  };
468
- function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
474
+ function extractDestructuredIdentifiers(node, isParameter, scopeTracker, isArrowParameter = false) {
469
475
  if (node.type === "ObjectPattern") {
470
476
  node.properties.forEach((prop) => {
471
477
  if (prop.type === "Property" && prop.value.type === "Identifier") {
@@ -475,7 +481,8 @@ function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
475
481
  getLineNumber(prop.value),
476
482
  {
477
483
  isParameter,
478
- isDestructured: true
484
+ isDestructured: true,
485
+ isArrowParameter
479
486
  }
480
487
  );
481
488
  }
@@ -489,7 +496,8 @@ function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
489
496
  getLineNumber(element),
490
497
  {
491
498
  isParameter,
492
- isDestructured: true
499
+ isDestructured: true,
500
+ isArrowParameter
493
501
  }
494
502
  );
495
503
  }
@@ -562,8 +570,22 @@ async function analyzeNamingGeneralized(files) {
562
570
  } else if (exp.type === "type" && conventions.typePattern) {
563
571
  pattern = conventions.typePattern;
564
572
  } else if (exp.type === "function") {
573
+ if (/^[A-Z][a-zA-Z0-9]*$/.test(exp.name) || /^[A-Z][A-Z0-9_]*$/.test(exp.name)) {
574
+ continue;
575
+ }
565
576
  pattern = conventions.functionPattern;
566
577
  } else if (exp.type === "const") {
578
+ if ([
579
+ "handler",
580
+ "GET",
581
+ "POST",
582
+ "PUT",
583
+ "DELETE",
584
+ "PATCH",
585
+ "OPTIONS",
586
+ "HEAD"
587
+ ].includes(exp.name))
588
+ continue;
567
589
  pattern = exp.isPrimitive ? conventions.constantPattern : conventions.variablePattern;
568
590
  } else {
569
591
  pattern = conventions.variablePattern;
@@ -587,7 +609,7 @@ async function analyzeNamingGeneralized(files) {
587
609
  if (!spec || spec === "*" || spec === "default") continue;
588
610
  if (exceptions.has(spec)) continue;
589
611
  if (COMMON_ABBREVIATIONS.has(spec.toLowerCase())) continue;
590
- if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec) && !conventions.constantPattern.test(spec) && (!conventions.typePattern || !conventions.typePattern.test(spec)) && (!conventions.interfacePattern || !conventions.interfacePattern.test(spec))) {
612
+ if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec) && (!conventions.constantPattern || !conventions.constantPattern.test(spec)) && (!conventions.typePattern || !conventions.typePattern.test(spec)) && (!conventions.interfacePattern || !conventions.interfacePattern.test(spec)) && !/^[A-Z][A-Z0-9_]*$/.test(spec)) {
591
613
  issues.push({
592
614
  type: "naming-inconsistency",
593
615
  identifier: spec,
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  analyzeConsistency,
3
3
  analyzeNamingAST,
4
4
  analyzePatterns
5
- } from "./chunk-LSXZH6X6.mjs";
5
+ } from "./chunk-6H3JHDP7.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.13",
3
+ "version": "0.20.14",
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.14"
46
+ "@aiready/core": "0.23.15"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^24.0.0",
@@ -68,17 +68,23 @@ function analyzeIdentifiers(
68
68
  node.type === 'FunctionExpression' ||
69
69
  node.type === 'ArrowFunctionExpression'
70
70
  ) {
71
+ const isArrowParameter = node.type === 'ArrowFunctionExpression';
71
72
  node.params.forEach((param) => {
72
73
  if (param.type === 'Identifier') {
73
74
  scopeTracker.declareVariable(
74
75
  param.name,
75
76
  param,
76
77
  getLineNumber(param),
77
- { isParameter: true }
78
+ { isParameter: true, isArrowParameter }
78
79
  );
79
80
  } else if (param.type === 'ObjectPattern') {
80
81
  // Handle destructured parameters: { id, name }
81
- extractDestructuredIdentifiers(param, true, scopeTracker);
82
+ extractDestructuredIdentifiers(
83
+ param,
84
+ true,
85
+ scopeTracker,
86
+ isArrowParameter
87
+ );
82
88
  }
83
89
  });
84
90
  }
@@ -160,7 +166,11 @@ function checkVariableNaming(
160
166
  }
161
167
 
162
168
  // 1. Single letter names
163
- if (name.length === 1 && !options.isLoopVariable) {
169
+ if (
170
+ name.length === 1 &&
171
+ !options.isLoopVariable &&
172
+ !options.isArrowParameter
173
+ ) {
164
174
  const severity = adjustSeverity(Severity.Minor, context, 'poor-naming');
165
175
  issues.push({
166
176
  file,
@@ -290,7 +300,8 @@ class ScopeTracker {
290
300
  function extractDestructuredIdentifiers(
291
301
  node: TSESTree.ObjectPattern | TSESTree.ArrayPattern,
292
302
  isParameter: boolean,
293
- scopeTracker: ScopeTracker
303
+ scopeTracker: ScopeTracker,
304
+ isArrowParameter: boolean = false
294
305
  ) {
295
306
  if (node.type === 'ObjectPattern') {
296
307
  node.properties.forEach((prop) => {
@@ -302,6 +313,7 @@ function extractDestructuredIdentifiers(
302
313
  {
303
314
  isParameter,
304
315
  isDestructured: true,
316
+ isArrowParameter,
305
317
  }
306
318
  );
307
319
  }
@@ -316,6 +328,7 @@ function extractDestructuredIdentifiers(
316
328
  {
317
329
  isParameter,
318
330
  isDestructured: true,
331
+ isArrowParameter,
319
332
  }
320
333
  );
321
334
  }
@@ -88,8 +88,30 @@ export async function analyzeNamingGeneralized(
88
88
  } else if (exp.type === 'type' && conventions.typePattern) {
89
89
  pattern = conventions.typePattern;
90
90
  } else if (exp.type === 'function') {
91
+ // Allow PascalCase (React components) or UPPER_CASE (HTTP methods) for exported functions
92
+ if (
93
+ /^[A-Z][a-zA-Z0-9]*$/.test(exp.name) ||
94
+ /^[A-Z][A-Z0-9_]*$/.test(exp.name)
95
+ ) {
96
+ continue;
97
+ }
91
98
  pattern = conventions.functionPattern;
92
99
  } else if (exp.type === 'const') {
100
+ // Exempt standard Next.js / API names
101
+ if (
102
+ [
103
+ 'handler',
104
+ 'GET',
105
+ 'POST',
106
+ 'PUT',
107
+ 'DELETE',
108
+ 'PATCH',
109
+ 'OPTIONS',
110
+ 'HEAD',
111
+ ].includes(exp.name)
112
+ )
113
+ continue;
114
+
93
115
  // Only enforce SCREAMING_SNAKE_CASE for primitive constants (strings, numbers,
94
116
  // booleans). Object literals, class instances, and tool definitions are
95
117
  // camelCase by convention (e.g. `logger`, `githubTools`, `RemediationSwarm`).
@@ -125,10 +147,12 @@ export async function analyzeNamingGeneralized(
125
147
  if (
126
148
  !conventions.variablePattern.test(spec) &&
127
149
  !conventions.classPattern.test(spec) &&
128
- !conventions.constantPattern.test(spec) &&
150
+ (!conventions.constantPattern ||
151
+ !conventions.constantPattern.test(spec)) &&
129
152
  (!conventions.typePattern || !conventions.typePattern.test(spec)) &&
130
153
  (!conventions.interfacePattern ||
131
- !conventions.interfacePattern.test(spec))
154
+ !conventions.interfacePattern.test(spec)) &&
155
+ !/^[A-Z][A-Z0-9_]*$/.test(spec)
132
156
  ) {
133
157
  // This is often a 'convention-mix' issue (e.g. importing snake_case into camelCase project)
134
158
  issues.push({