@aiready/consistency 0.20.5 → 0.20.7

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
@@ -413,7 +413,36 @@ function isCommonAbbreviation(name) {
413
413
  "ux",
414
414
  "api",
415
415
  "env",
416
- "url"
416
+ "url",
417
+ "req",
418
+ "res",
419
+ "err",
420
+ "ctx",
421
+ "cb",
422
+ "idx",
423
+ "src",
424
+ "dir",
425
+ "app",
426
+ "dev",
427
+ "qa",
428
+ "dto",
429
+ "dao",
430
+ "ref",
431
+ "ast",
432
+ "dom",
433
+ "log",
434
+ "msg",
435
+ "pkg",
436
+ "req",
437
+ "err",
438
+ "res",
439
+ "css",
440
+ "html",
441
+ "xml",
442
+ "jsx",
443
+ "tsx",
444
+ "ts",
445
+ "js"
417
446
  ];
418
447
  return common.includes(name.toLowerCase());
419
448
  }
@@ -463,6 +492,44 @@ function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
463
492
  // src/analyzers/naming-generalized.ts
464
493
  var import_core3 = require("@aiready/core");
465
494
  var import_fs2 = require("fs");
495
+ var COMMON_ABBREVIATIONS = /* @__PURE__ */ new Set([
496
+ "id",
497
+ "db",
498
+ "fs",
499
+ "os",
500
+ "ip",
501
+ "ui",
502
+ "ux",
503
+ "api",
504
+ "env",
505
+ "url",
506
+ "req",
507
+ "res",
508
+ "err",
509
+ "ctx",
510
+ "cb",
511
+ "idx",
512
+ "src",
513
+ "dir",
514
+ "app",
515
+ "dev",
516
+ "qa",
517
+ "dto",
518
+ "dao",
519
+ "ref",
520
+ "ast",
521
+ "dom",
522
+ "log",
523
+ "msg",
524
+ "pkg",
525
+ "css",
526
+ "html",
527
+ "xml",
528
+ "jsx",
529
+ "tsx",
530
+ "ts",
531
+ "js"
532
+ ]);
466
533
  async function analyzeNamingGeneralized(files) {
467
534
  const issues = [];
468
535
  for (const file of files) {
@@ -470,10 +537,15 @@ async function analyzeNamingGeneralized(files) {
470
537
  if (!parser) continue;
471
538
  try {
472
539
  const code = (0, import_fs2.readFileSync)(file, "utf-8");
540
+ if (!code.trim()) continue;
473
541
  await parser.initialize();
474
542
  const result = parser.parse(code, file);
475
543
  const conventions = parser.getNamingConventions();
544
+ const exceptions = new Set(conventions.exceptions || []);
476
545
  for (const exp of result.exports) {
546
+ if (!exp.name || exp.name === "default") continue;
547
+ if (exceptions.has(exp.name)) continue;
548
+ if (COMMON_ABBREVIATIONS.has(exp.name.toLowerCase())) continue;
477
549
  let pattern;
478
550
  if (exp.type === "class") {
479
551
  pattern = conventions.classPattern;
@@ -484,7 +556,7 @@ async function analyzeNamingGeneralized(files) {
484
556
  } else if (exp.type === "function") {
485
557
  pattern = conventions.functionPattern;
486
558
  } else if (exp.type === "const") {
487
- pattern = conventions.constantPattern;
559
+ pattern = exp.isPrimitive ? conventions.constantPattern : conventions.variablePattern;
488
560
  } else {
489
561
  pattern = conventions.variablePattern;
490
562
  }
@@ -495,7 +567,8 @@ async function analyzeNamingGeneralized(files) {
495
567
  file,
496
568
  line: exp.loc?.start.line || 1,
497
569
  column: exp.loc?.start.column || 0,
498
- severity: import_core3.Severity.Major,
570
+ // Recalibrate naming issues to Minor to differentiate from structural/architectural issues
571
+ severity: import_core3.Severity.Minor,
499
572
  category: "naming",
500
573
  suggestion: `Follow ${parser.language} ${exp.type} naming convention: ${pattern.toString()}`
501
574
  });
@@ -503,7 +576,9 @@ async function analyzeNamingGeneralized(files) {
503
576
  }
504
577
  for (const imp of result.imports) {
505
578
  for (const spec of imp.specifiers) {
506
- if (spec === "*" || spec === "default") continue;
579
+ if (!spec || spec === "*" || spec === "default") continue;
580
+ if (exceptions.has(spec)) continue;
581
+ if (COMMON_ABBREVIATIONS.has(spec.toLowerCase())) continue;
507
582
  if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec)) {
508
583
  issues.push({
509
584
  type: "naming-inconsistency",
@@ -511,7 +586,8 @@ async function analyzeNamingGeneralized(files) {
511
586
  file,
512
587
  line: imp.loc?.start.line || 1,
513
588
  column: imp.loc?.start.column || 0,
514
- severity: import_core3.Severity.Minor,
589
+ severity: import_core3.Severity.Info,
590
+ // Reduced from Minor to Info for imports
515
591
  category: "naming",
516
592
  suggestion: `Imported identifier '${spec}' may not follow standard conventions for this language.`
517
593
  });
@@ -519,7 +595,10 @@ async function analyzeNamingGeneralized(files) {
519
595
  }
520
596
  }
521
597
  } catch (error) {
522
- console.warn(`Consistency: Failed to analyze ${file}: ${error}`);
598
+ const errorMessage = error instanceof Error ? error.message : String(error);
599
+ console.debug(
600
+ `Consistency: Skipping unparseable file ${file}: ${errorMessage.split("\\n")[0]}`
601
+ );
523
602
  }
524
603
  }
525
604
  return issues;
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  analyzeConsistency
4
- } from "./chunk-S6BZVTWN.mjs";
4
+ } from "./chunk-TE6JYZD3.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.d.mts CHANGED
@@ -61,8 +61,12 @@ interface ConsistencyReport {
61
61
  }
62
62
 
63
63
  /**
64
- * Main consistency analyzer that orchestrates all analysis types
65
- * Supports: TypeScript, JavaScript, Python, Java, C#, Go
64
+ * Main consistency analyzer that orchestrates all analysis types.
65
+ * Supports: TypeScript, JavaScript, Python, Java, C#, Go.
66
+ *
67
+ * @param options - Configuration for consistency analysis and file scanning.
68
+ * @returns Promise resolving to the comprehensive consistency report.
69
+ * @lastUpdated 2026-03-18
66
70
  */
67
71
  declare function analyzeConsistency(options: ConsistencyOptions): Promise<ConsistencyReport>;
68
72
 
@@ -96,15 +100,13 @@ declare function detectNamingConventions(files: string[], allIssues: Array<{
96
100
  declare function analyzePatterns(filePaths: string[]): Promise<PatternIssue[]>;
97
101
 
98
102
  /**
99
- * Calculate AI Readiness Score for code consistency (0-100)
100
- *
101
- * Based on:
102
- * - Issue density (issues per file)
103
- * - Weighted severity (critical: 10pts, major: 3pts, minor: 0.5pts)
104
- * - Pattern consistency across codebase
103
+ * Calculate AI Readiness Score for code consistency (0-100).
105
104
  *
106
- * Includes business value metrics:
107
- * - Estimated developer hours to fix consistency issues
105
+ * @param issues - Array of detected consistency issues.
106
+ * @param totalFilesAnalyzed - Total number of files scanned.
107
+ * @param costConfig - Optional configuration for productivity cost calculation.
108
+ * @returns Standardized scoring output for the consistency tool.
109
+ * @lastUpdated 2026-03-18
108
110
  */
109
111
  declare function calculateConsistencyScore(issues: ConsistencyIssue[], totalFilesAnalyzed: number, costConfig?: Partial<CostConfig>): ToolScoringOutput;
110
112
 
package/dist/index.d.ts CHANGED
@@ -61,8 +61,12 @@ interface ConsistencyReport {
61
61
  }
62
62
 
63
63
  /**
64
- * Main consistency analyzer that orchestrates all analysis types
65
- * Supports: TypeScript, JavaScript, Python, Java, C#, Go
64
+ * Main consistency analyzer that orchestrates all analysis types.
65
+ * Supports: TypeScript, JavaScript, Python, Java, C#, Go.
66
+ *
67
+ * @param options - Configuration for consistency analysis and file scanning.
68
+ * @returns Promise resolving to the comprehensive consistency report.
69
+ * @lastUpdated 2026-03-18
66
70
  */
67
71
  declare function analyzeConsistency(options: ConsistencyOptions): Promise<ConsistencyReport>;
68
72
 
@@ -96,15 +100,13 @@ declare function detectNamingConventions(files: string[], allIssues: Array<{
96
100
  declare function analyzePatterns(filePaths: string[]): Promise<PatternIssue[]>;
97
101
 
98
102
  /**
99
- * Calculate AI Readiness Score for code consistency (0-100)
100
- *
101
- * Based on:
102
- * - Issue density (issues per file)
103
- * - Weighted severity (critical: 10pts, major: 3pts, minor: 0.5pts)
104
- * - Pattern consistency across codebase
103
+ * Calculate AI Readiness Score for code consistency (0-100).
105
104
  *
106
- * Includes business value metrics:
107
- * - Estimated developer hours to fix consistency issues
105
+ * @param issues - Array of detected consistency issues.
106
+ * @param totalFilesAnalyzed - Total number of files scanned.
107
+ * @param costConfig - Optional configuration for productivity cost calculation.
108
+ * @returns Standardized scoring output for the consistency tool.
109
+ * @lastUpdated 2026-03-18
108
110
  */
109
111
  declare function calculateConsistencyScore(issues: ConsistencyIssue[], totalFilesAnalyzed: number, costConfig?: Partial<CostConfig>): ToolScoringOutput;
110
112
 
package/dist/index.js CHANGED
@@ -421,7 +421,36 @@ function isCommonAbbreviation(name) {
421
421
  "ux",
422
422
  "api",
423
423
  "env",
424
- "url"
424
+ "url",
425
+ "req",
426
+ "res",
427
+ "err",
428
+ "ctx",
429
+ "cb",
430
+ "idx",
431
+ "src",
432
+ "dir",
433
+ "app",
434
+ "dev",
435
+ "qa",
436
+ "dto",
437
+ "dao",
438
+ "ref",
439
+ "ast",
440
+ "dom",
441
+ "log",
442
+ "msg",
443
+ "pkg",
444
+ "req",
445
+ "err",
446
+ "res",
447
+ "css",
448
+ "html",
449
+ "xml",
450
+ "jsx",
451
+ "tsx",
452
+ "ts",
453
+ "js"
425
454
  ];
426
455
  return common.includes(name.toLowerCase());
427
456
  }
@@ -471,6 +500,44 @@ function extractDestructuredIdentifiers(node, isParameter, scopeTracker) {
471
500
  // src/analyzers/naming-generalized.ts
472
501
  var import_core3 = require("@aiready/core");
473
502
  var import_fs2 = require("fs");
503
+ var COMMON_ABBREVIATIONS = /* @__PURE__ */ new Set([
504
+ "id",
505
+ "db",
506
+ "fs",
507
+ "os",
508
+ "ip",
509
+ "ui",
510
+ "ux",
511
+ "api",
512
+ "env",
513
+ "url",
514
+ "req",
515
+ "res",
516
+ "err",
517
+ "ctx",
518
+ "cb",
519
+ "idx",
520
+ "src",
521
+ "dir",
522
+ "app",
523
+ "dev",
524
+ "qa",
525
+ "dto",
526
+ "dao",
527
+ "ref",
528
+ "ast",
529
+ "dom",
530
+ "log",
531
+ "msg",
532
+ "pkg",
533
+ "css",
534
+ "html",
535
+ "xml",
536
+ "jsx",
537
+ "tsx",
538
+ "ts",
539
+ "js"
540
+ ]);
474
541
  async function analyzeNamingGeneralized(files) {
475
542
  const issues = [];
476
543
  for (const file of files) {
@@ -478,10 +545,15 @@ async function analyzeNamingGeneralized(files) {
478
545
  if (!parser) continue;
479
546
  try {
480
547
  const code = (0, import_fs2.readFileSync)(file, "utf-8");
548
+ if (!code.trim()) continue;
481
549
  await parser.initialize();
482
550
  const result = parser.parse(code, file);
483
551
  const conventions = parser.getNamingConventions();
552
+ const exceptions = new Set(conventions.exceptions || []);
484
553
  for (const exp of result.exports) {
554
+ if (!exp.name || exp.name === "default") continue;
555
+ if (exceptions.has(exp.name)) continue;
556
+ if (COMMON_ABBREVIATIONS.has(exp.name.toLowerCase())) continue;
485
557
  let pattern;
486
558
  if (exp.type === "class") {
487
559
  pattern = conventions.classPattern;
@@ -492,7 +564,7 @@ async function analyzeNamingGeneralized(files) {
492
564
  } else if (exp.type === "function") {
493
565
  pattern = conventions.functionPattern;
494
566
  } else if (exp.type === "const") {
495
- pattern = conventions.constantPattern;
567
+ pattern = exp.isPrimitive ? conventions.constantPattern : conventions.variablePattern;
496
568
  } else {
497
569
  pattern = conventions.variablePattern;
498
570
  }
@@ -503,7 +575,8 @@ async function analyzeNamingGeneralized(files) {
503
575
  file,
504
576
  line: exp.loc?.start.line || 1,
505
577
  column: exp.loc?.start.column || 0,
506
- severity: import_core3.Severity.Major,
578
+ // Recalibrate naming issues to Minor to differentiate from structural/architectural issues
579
+ severity: import_core3.Severity.Minor,
507
580
  category: "naming",
508
581
  suggestion: `Follow ${parser.language} ${exp.type} naming convention: ${pattern.toString()}`
509
582
  });
@@ -511,7 +584,9 @@ async function analyzeNamingGeneralized(files) {
511
584
  }
512
585
  for (const imp of result.imports) {
513
586
  for (const spec of imp.specifiers) {
514
- if (spec === "*" || spec === "default") continue;
587
+ if (!spec || spec === "*" || spec === "default") continue;
588
+ if (exceptions.has(spec)) continue;
589
+ if (COMMON_ABBREVIATIONS.has(spec.toLowerCase())) continue;
515
590
  if (!conventions.variablePattern.test(spec) && !conventions.classPattern.test(spec)) {
516
591
  issues.push({
517
592
  type: "naming-inconsistency",
@@ -519,7 +594,8 @@ async function analyzeNamingGeneralized(files) {
519
594
  file,
520
595
  line: imp.loc?.start.line || 1,
521
596
  column: imp.loc?.start.column || 0,
522
- severity: import_core3.Severity.Minor,
597
+ severity: import_core3.Severity.Info,
598
+ // Reduced from Minor to Info for imports
523
599
  category: "naming",
524
600
  suggestion: `Imported identifier '${spec}' may not follow standard conventions for this language.`
525
601
  });
@@ -527,7 +603,10 @@ async function analyzeNamingGeneralized(files) {
527
603
  }
528
604
  }
529
605
  } catch (error) {
530
- console.warn(`Consistency: Failed to analyze ${file}: ${error}`);
606
+ const errorMessage = error instanceof Error ? error.message : String(error);
607
+ console.debug(
608
+ `Consistency: Skipping unparseable file ${file}: ${errorMessage.split("\\n")[0]}`
609
+ );
531
610
  }
532
611
  }
533
612
  return issues;
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  analyzeConsistency,
3
3
  analyzeNamingAST,
4
4
  analyzePatterns
5
- } from "./chunk-S6BZVTWN.mjs";
5
+ } from "./chunk-TE6JYZD3.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.5",
3
+ "version": "0.20.7",
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.6"
46
+ "@aiready/core": "0.23.8"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^24.0.0",
package/src/analyzer.ts CHANGED
@@ -15,8 +15,12 @@ import { analyzeNamingGeneralized } from './analyzers/naming-generalized';
15
15
  import { analyzePatterns } from './analyzers/patterns';
16
16
 
17
17
  /**
18
- * Main consistency analyzer that orchestrates all analysis types
19
- * Supports: TypeScript, JavaScript, Python, Java, C#, Go
18
+ * Main consistency analyzer that orchestrates all analysis types.
19
+ * Supports: TypeScript, JavaScript, Python, Java, C#, Go.
20
+ *
21
+ * @param options - Configuration for consistency analysis and file scanning.
22
+ * @returns Promise resolving to the comprehensive consistency report.
23
+ * @lastUpdated 2026-03-18
20
24
  */
21
25
  export async function analyzeConsistency(
22
26
  options: ConsistencyOptions
@@ -126,6 +130,13 @@ export async function analyzeConsistency(
126
130
  } as unknown as ConsistencyReport;
127
131
  }
128
132
 
133
+ /**
134
+ * Check if an issue severity meets the minimum threshold.
135
+ *
136
+ * @param severity - The severity of the issue.
137
+ * @param minSeverity - The minimum severity threshold.
138
+ * @returns True if severity is greater than or equal to minSeverity.
139
+ */
129
140
  function shouldIncludeSeverity(
130
141
  severity: Severity | string,
131
142
  minSeverity: Severity | string
@@ -134,7 +145,10 @@ function shouldIncludeSeverity(
134
145
  }
135
146
 
136
147
  /**
137
- * Map string type to IssueType enum value
148
+ * Map string type to IssueType enum value.
149
+ *
150
+ * @param type - The raw issue type string.
151
+ * @returns Normalized IssueType enum.
138
152
  */
139
153
  function getIssueType(type: string | undefined): IssueType {
140
154
  if (!type) return IssueType.NamingInconsistency;
@@ -155,7 +169,10 @@ function getIssueType(type: string | undefined): IssueType {
155
169
  }
156
170
 
157
171
  /**
158
- * Transform NamingIssue or PatternIssue to the required Issue format
172
+ * Transform NamingIssue or PatternIssue to the required Issue format.
173
+ *
174
+ * @param i - The raw issue object to transform.
175
+ * @returns Standardized Issue object.
159
176
  */
160
177
  function transformToIssue(i: any): Issue {
161
178
  // If already has message and location, return as is
@@ -227,6 +227,35 @@ function isCommonAbbreviation(name: string): boolean {
227
227
  'api',
228
228
  'env',
229
229
  'url',
230
+ 'req',
231
+ 'res',
232
+ 'err',
233
+ 'ctx',
234
+ 'cb',
235
+ 'idx',
236
+ 'src',
237
+ 'dir',
238
+ 'app',
239
+ 'dev',
240
+ 'qa',
241
+ 'dto',
242
+ 'dao',
243
+ 'ref',
244
+ 'ast',
245
+ 'dom',
246
+ 'log',
247
+ 'msg',
248
+ 'pkg',
249
+ 'req',
250
+ 'err',
251
+ 'res',
252
+ 'css',
253
+ 'html',
254
+ 'xml',
255
+ 'jsx',
256
+ 'tsx',
257
+ 'ts',
258
+ 'js',
230
259
  ];
231
260
  return common.includes(name.toLowerCase());
232
261
  }
@@ -9,6 +9,46 @@ import { getParser, Severity } from '@aiready/core';
9
9
  import type { NamingIssue } from '../types';
10
10
  import { readFileSync } from 'fs';
11
11
 
12
+ // Common abbreviations to whitelist
13
+ const COMMON_ABBREVIATIONS = new Set([
14
+ 'id',
15
+ 'db',
16
+ 'fs',
17
+ 'os',
18
+ 'ip',
19
+ 'ui',
20
+ 'ux',
21
+ 'api',
22
+ 'env',
23
+ 'url',
24
+ 'req',
25
+ 'res',
26
+ 'err',
27
+ 'ctx',
28
+ 'cb',
29
+ 'idx',
30
+ 'src',
31
+ 'dir',
32
+ 'app',
33
+ 'dev',
34
+ 'qa',
35
+ 'dto',
36
+ 'dao',
37
+ 'ref',
38
+ 'ast',
39
+ 'dom',
40
+ 'log',
41
+ 'msg',
42
+ 'pkg',
43
+ 'css',
44
+ 'html',
45
+ 'xml',
46
+ 'jsx',
47
+ 'tsx',
48
+ 'ts',
49
+ 'js',
50
+ ]);
51
+
12
52
  /**
13
53
  * Analyzes naming conventions using generalized LanguageParser metadata
14
54
  */
@@ -23,13 +63,22 @@ export async function analyzeNamingGeneralized(
23
63
 
24
64
  try {
25
65
  const code = readFileSync(file, 'utf-8');
66
+ if (!code.trim()) continue; // Skip empty files
67
+
26
68
  // Ensure parser is initialized (e.g. WASM loaded)
27
69
  await parser.initialize();
28
70
  const result = parser.parse(code, file);
29
71
  const conventions = parser.getNamingConventions();
72
+ const exceptions = new Set(conventions.exceptions || []);
30
73
 
31
74
  // 1. Check Exports
32
75
  for (const exp of result.exports) {
76
+ if (!exp.name || exp.name === 'default') continue;
77
+ if (exceptions.has(exp.name)) continue;
78
+
79
+ // Skip common abbreviations
80
+ if (COMMON_ABBREVIATIONS.has(exp.name.toLowerCase())) continue;
81
+
33
82
  let pattern: RegExp | undefined;
34
83
 
35
84
  if (exp.type === 'class') {
@@ -41,7 +90,12 @@ export async function analyzeNamingGeneralized(
41
90
  } else if (exp.type === 'function') {
42
91
  pattern = conventions.functionPattern;
43
92
  } else if (exp.type === 'const') {
44
- pattern = conventions.constantPattern;
93
+ // Only enforce SCREAMING_SNAKE_CASE for primitive constants (strings, numbers,
94
+ // booleans). Object literals, class instances, and tool definitions are
95
+ // camelCase by convention (e.g. `logger`, `githubTools`, `RemediationSwarm`).
96
+ pattern = exp.isPrimitive
97
+ ? conventions.constantPattern
98
+ : conventions.variablePattern;
45
99
  } else {
46
100
  pattern = conventions.variablePattern;
47
101
  }
@@ -53,7 +107,8 @@ export async function analyzeNamingGeneralized(
53
107
  file,
54
108
  line: exp.loc?.start.line || 1,
55
109
  column: exp.loc?.start.column || 0,
56
- severity: Severity.Major,
110
+ // Recalibrate naming issues to Minor to differentiate from structural/architectural issues
111
+ severity: Severity.Minor,
57
112
  category: 'naming',
58
113
  suggestion: `Follow ${parser.language} ${exp.type} naming convention: ${pattern.toString()}`,
59
114
  });
@@ -63,7 +118,9 @@ export async function analyzeNamingGeneralized(
63
118
  // 2. Check Imports (basic check for specifier consistency)
64
119
  for (const imp of result.imports) {
65
120
  for (const spec of imp.specifiers) {
66
- if (spec === '*' || spec === 'default') continue;
121
+ if (!spec || spec === '*' || spec === 'default') continue;
122
+ if (exceptions.has(spec)) continue;
123
+ if (COMMON_ABBREVIATIONS.has(spec.toLowerCase())) continue;
67
124
 
68
125
  if (
69
126
  !conventions.variablePattern.test(spec) &&
@@ -76,7 +133,7 @@ export async function analyzeNamingGeneralized(
76
133
  file,
77
134
  line: imp.loc?.start.line || 1,
78
135
  column: imp.loc?.start.column || 0,
79
- severity: Severity.Minor,
136
+ severity: Severity.Info, // Reduced from Minor to Info for imports
80
137
  category: 'naming',
81
138
  suggestion: `Imported identifier '${spec}' may not follow standard conventions for this language.`,
82
139
  });
@@ -84,7 +141,12 @@ export async function analyzeNamingGeneralized(
84
141
  }
85
142
  }
86
143
  } catch (error) {
87
- console.warn(`Consistency: Failed to analyze ${file}: ${error}`);
144
+ // Improved error handling
145
+ const errorMessage =
146
+ error instanceof Error ? error.message : String(error);
147
+ console.debug(
148
+ `Consistency: Skipping unparseable file ${file}: ${errorMessage.split('\\n')[0]}`
149
+ );
88
150
  }
89
151
  }
90
152
 
package/src/scoring.ts CHANGED
@@ -3,15 +3,13 @@ import type { ToolScoringOutput, CostConfig } from '@aiready/core';
3
3
  import type { ConsistencyIssue } from './types';
4
4
 
5
5
  /**
6
- * Calculate AI Readiness Score for code consistency (0-100)
6
+ * Calculate AI Readiness Score for code consistency (0-100).
7
7
  *
8
- * Based on:
9
- * - Issue density (issues per file)
10
- * - Weighted severity (critical: 10pts, major: 3pts, minor: 0.5pts)
11
- * - Pattern consistency across codebase
12
- *
13
- * Includes business value metrics:
14
- * - Estimated developer hours to fix consistency issues
8
+ * @param issues - Array of detected consistency issues.
9
+ * @param totalFilesAnalyzed - Total number of files scanned.
10
+ * @param costConfig - Optional configuration for productivity cost calculation.
11
+ * @returns Standardized scoring output for the consistency tool.
12
+ * @lastUpdated 2026-03-18
15
13
  */
16
14
  export function calculateConsistencyScore(
17
15
  issues: ConsistencyIssue[],