@aiready/pattern-detect 0.12.2 → 0.12.3

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.mjs CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  analyzePatterns,
4
4
  filterBySeverity,
5
5
  generateSummary
6
- } from "./chunk-CCHM2VLK.mjs";
6
+ } from "./chunk-2R7HOR5H.mjs";
7
7
 
8
8
  // src/cli.ts
9
9
  import { Command } from "commander";
@@ -13,7 +13,8 @@ import { dirname } from "path";
13
13
  import {
14
14
  loadConfig,
15
15
  mergeConfigWithDefaults,
16
- resolveOutputPath
16
+ resolveOutputPath,
17
+ Severity
17
18
  } from "@aiready/core";
18
19
  var program = new Command();
19
20
  program.name("aiready-patterns").description("Detect duplicate patterns in your codebase").version("0.1.0").addHelpText(
@@ -79,7 +80,7 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
79
80
  streamResults: true,
80
81
  include: void 0,
81
82
  exclude: void 0,
82
- minSeverity: "minor",
83
+ minSeverity: Severity.Minor,
83
84
  excludeTestFixtures: false,
84
85
  excludeTemplates: false,
85
86
  includeTests: false,
@@ -108,10 +109,10 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
108
109
  excludeTemplates: options.excludeTemplates || mergedConfig.excludeTemplates,
109
110
  includeTests: options.includeTests || mergedConfig.includeTests,
110
111
  maxResults: options.maxResults ? parseInt(options.maxResults) : mergedConfig.maxResults,
111
- groupByFilePair: options.groupByFilePair !== false && mergedConfig.groupByFilePair,
112
- createClusters: options.createClusters !== false && mergedConfig.createClusters,
113
- minClusterTokenCost: options.minClusterTokens ? parseInt(options.minClusterTokens) : mergedConfig.minClusterTokenCost,
114
- minClusterFiles: options.minClusterFiles ? parseInt(options.minClusterFiles) : mergedConfig.minClusterFiles,
112
+ groupByFilePair: options.groupBy_file_pair !== false && mergedConfig.groupByFilePair,
113
+ createClusters: options.create_clusters !== false && mergedConfig.createClusters,
114
+ minClusterTokenCost: options.min_cluster_tokens ? parseInt(options.min_cluster_tokens) : mergedConfig.minClusterTokenCost,
115
+ minClusterFiles: options.min_cluster_files ? parseInt(options.min_cluster_files) : mergedConfig.minClusterFiles,
115
116
  showRawDuplicates: options.showRawDuplicates || mergedConfig.showRawDuplicates
116
117
  };
117
118
  if (finalOptions.includeTests && finalOptions.exclude) {
@@ -232,14 +233,10 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
232
233
  chalk.bold.white(` \u{1F4E6} DUPLICATE GROUPS (${groups.length} file pairs)`)
233
234
  );
234
235
  console.log(chalk.cyan(divider) + "\n");
235
- const severityOrder = {
236
- critical: 4,
237
- major: 3,
238
- minor: 2,
239
- info: 1
240
- };
241
236
  const topGroups = groups.sort((a, b) => {
242
- const severityDiff = severityOrder[b.severity] - severityOrder[a.severity];
237
+ const bVal = getSeverityValue(b.severity);
238
+ const aVal = getSeverityValue(a.severity);
239
+ const severityDiff = bVal - aVal;
243
240
  if (severityDiff !== 0) return severityDiff;
244
241
  return b.totalTokenCost - a.totalTokenCost;
245
242
  }).slice(0, finalOptions.maxResults);
@@ -313,14 +310,10 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
313
310
  console.log(chalk.cyan("\n" + divider));
314
311
  console.log(chalk.bold.white(" TOP DUPLICATE PATTERNS"));
315
312
  console.log(chalk.cyan(divider) + "\n");
316
- const severityOrder = {
317
- critical: 4,
318
- major: 3,
319
- minor: 2,
320
- info: 1
321
- };
322
313
  const topDuplicates = filteredDuplicates.sort((a, b) => {
323
- const severityDiff = severityOrder[b.severity] - severityOrder[a.severity];
314
+ const bVal = getSeverityValue(b.severity);
315
+ const aVal = getSeverityValue(a.severity);
316
+ const severityDiff = bVal - aVal;
324
317
  if (severityDiff !== 0) return severityDiff;
325
318
  return b.similarity - a.similarity;
326
319
  }).slice(0, finalOptions.maxResults);
@@ -360,7 +353,7 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
360
353
  (r) => r.issues.map((issue) => ({ ...issue, file: r.fileName }))
361
354
  );
362
355
  const criticalIssues = allIssues.filter(
363
- (issue) => issue.severity === "critical"
356
+ (issue) => getSeverityValue(issue.severity) === 4
364
357
  );
365
358
  if (criticalIssues.length > 0) {
366
359
  console.log(chalk.cyan(divider));
@@ -515,12 +508,25 @@ function generateHTMLReport(summary, results) {
515
508
  </html>`;
516
509
  }
517
510
  program.parse();
511
+ function getSeverityValue(s) {
512
+ if (s === Severity.Critical || s === "critical") return 4;
513
+ if (s === Severity.Major || s === "major") return 3;
514
+ if (s === Severity.Minor || s === "minor") return 2;
515
+ if (s === Severity.Info || s === "info") return 1;
516
+ return 0;
517
+ }
518
518
  function getSeverityBadge(severity) {
519
- const badges = {
520
- critical: chalk.bgRed.white.bold(" CRITICAL "),
521
- major: chalk.bgYellow.black.bold(" MAJOR "),
522
- minor: chalk.bgBlue.white.bold(" MINOR "),
523
- info: chalk.bgCyan.black(" INFO ")
524
- };
525
- return badges[severity] || badges.info;
519
+ const val = getSeverityValue(severity);
520
+ switch (val) {
521
+ case 4:
522
+ return chalk.bgRed.white.bold(" CRITICAL ");
523
+ case 3:
524
+ return chalk.bgYellow.black.bold(" MAJOR ");
525
+ case 2:
526
+ return chalk.bgBlue.white.bold(" MINOR ");
527
+ case 1:
528
+ return chalk.bgCyan.black(" INFO ");
529
+ default:
530
+ return chalk.bgCyan.black(" INFO ");
531
+ }
526
532
  }
package/dist/index.d.mts CHANGED
@@ -1,43 +1,19 @@
1
- import { CostConfig, ToolScoringOutput, ScanOptions, AnalysisResult } from '@aiready/core';
1
+ import { Severity, CostConfig, ToolScoringOutput, ScanOptions, AnalysisResult } from '@aiready/core';
2
+ export { Severity } from '@aiready/core';
2
3
 
3
- /**
4
- * Context-aware severity detection for duplicate patterns
5
- * Identifies intentional duplication patterns and adjusts severity accordingly
6
- */
7
- type Severity = 'critical' | 'major' | 'minor' | 'info';
8
- /**
9
- * Calculate severity based on context rules and code characteristics
10
- */
11
- declare function calculateSeverity(file1: string, file2: string, code: string, similarity: number, linesOfCode: number): {
12
- severity: Severity;
13
- reason?: string;
14
- suggestion?: string;
15
- matchedRule?: string;
16
- };
17
- /**
18
- * Get a human-readable severity label with emoji
19
- */
20
- declare function getSeverityLabel(severity: Severity): string;
21
- /**
22
- * Filter duplicates by minimum severity threshold
23
- */
24
- declare function filterBySeverity<T extends {
25
- severity: Severity;
26
- }>(duplicates: T[], minSeverity: Severity): T[];
27
-
28
- type PatternType = 'function' | 'class-method' | 'api-handler' | 'validator' | 'utility' | 'component' | 'unknown';
4
+ type PatternType = 'api-handler' | 'validator' | 'utility' | 'class-method' | 'component' | 'function' | 'unknown';
29
5
  interface DuplicatePattern {
30
6
  file1: string;
31
- file2: string;
32
7
  line1: number;
33
- line2: number;
34
8
  endLine1: number;
9
+ file2: string;
10
+ line2: number;
35
11
  endLine2: number;
12
+ code1: string;
13
+ code2: string;
36
14
  similarity: number;
37
- snippet: string;
38
15
  patternType: PatternType;
39
16
  tokenCost: number;
40
- linesOfCode: number;
41
17
  severity: Severity;
42
18
  reason?: string;
43
19
  suggestion?: string;
@@ -50,34 +26,26 @@ interface FileContent {
50
26
  interface DetectionOptions {
51
27
  minSimilarity: number;
52
28
  minLines: number;
53
- batchSize?: number;
54
- approx?: boolean;
55
- minSharedTokens?: number;
56
- maxCandidatesPerBlock?: number;
57
- maxComparisons?: number;
58
- streamResults?: boolean;
29
+ batchSize: number;
30
+ approx: boolean;
31
+ minSharedTokens: number;
32
+ maxCandidatesPerBlock: number;
33
+ streamResults: boolean;
59
34
  onProgress?: (processed: number, total: number, message: string) => void;
60
35
  }
61
36
 
62
37
  /**
63
- * Detect duplicate patterns across files with enhanced analysis
64
- */
65
- declare function detectDuplicatePatterns(files: FileContent[], options: DetectionOptions): Promise<DuplicatePattern[]>;
66
-
67
- /**
68
- * Grouping and clustering utilities for duplicate patterns
69
- * Reduces noise by consolidating similar duplicates and creating refactor clusters
38
+ * Detect duplicate patterns across files
70
39
  */
40
+ declare function detectDuplicatePatterns(fileContents: FileContent[], options: DetectionOptions): Promise<DuplicatePattern[]>;
71
41
 
72
42
  interface DuplicateGroup {
73
43
  filePair: string;
74
- duplicates: DuplicatePattern[];
75
- totalTokenCost: number;
76
- averageSimilarity: number;
77
- maxSimilarity: number;
78
44
  severity: Severity;
79
- patternType: PatternType;
80
45
  occurrences: number;
46
+ totalTokenCost: number;
47
+ averageSimilarity: number;
48
+ patternTypes: Set<PatternType>;
81
49
  lineRanges: Array<{
82
50
  file1: {
83
51
  start: number;
@@ -93,13 +61,12 @@ interface RefactorCluster {
93
61
  id: string;
94
62
  name: string;
95
63
  files: string[];
96
- patternType: PatternType;
97
64
  severity: Severity;
65
+ duplicateCount: number;
98
66
  totalTokenCost: number;
99
67
  averageSimilarity: number;
100
- duplicateCount: number;
101
- suggestion: string;
102
- reason: string;
68
+ reason?: string;
69
+ suggestion?: string;
103
70
  }
104
71
 
105
72
  /**
@@ -116,6 +83,26 @@ interface RefactorCluster {
116
83
  */
117
84
  declare function calculatePatternScore(duplicates: DuplicatePattern[], totalFilesAnalyzed: number, costConfig?: Partial<CostConfig>): ToolScoringOutput;
118
85
 
86
+ /**
87
+ * Calculate severity based on context rules and code characteristics
88
+ */
89
+ declare function calculateSeverity(file1: string, file2: string, code: string, similarity: number, linesOfCode: number): {
90
+ severity: Severity;
91
+ reason?: string;
92
+ suggestion?: string;
93
+ matchedRule?: string;
94
+ };
95
+ /**
96
+ * Get a human-readable severity label with emoji
97
+ */
98
+ declare function getSeverityLabel(severity: Severity): string;
99
+ /**
100
+ * Filter duplicates by minimum severity threshold
101
+ */
102
+ declare function filterBySeverity<T extends {
103
+ severity: Severity;
104
+ }>(duplicates: T[], minSeverity: Severity): T[];
105
+
119
106
  interface PatternDetectOptions extends ScanOptions {
120
107
  minSimilarity?: number;
121
108
  minLines?: number;
@@ -164,4 +151,4 @@ declare function analyzePatterns(options: PatternDetectOptions): Promise<{
164
151
  */
165
152
  declare function generateSummary(results: AnalysisResult[]): PatternSummary;
166
153
 
167
- export { type DuplicateGroup, type DuplicatePattern, type PatternDetectOptions, type PatternSummary, type PatternType, type RefactorCluster, type Severity, analyzePatterns, calculatePatternScore, calculateSeverity, detectDuplicatePatterns, filterBySeverity, generateSummary, getSeverityLabel, getSmartDefaults };
154
+ export { type DuplicateGroup, type DuplicatePattern, type PatternDetectOptions, type PatternSummary, type PatternType, type RefactorCluster, analyzePatterns, calculatePatternScore, calculateSeverity, detectDuplicatePatterns, filterBySeverity, generateSummary, getSeverityLabel, getSmartDefaults };
package/dist/index.d.ts CHANGED
@@ -1,43 +1,19 @@
1
- import { CostConfig, ToolScoringOutput, ScanOptions, AnalysisResult } from '@aiready/core';
1
+ import { Severity, CostConfig, ToolScoringOutput, ScanOptions, AnalysisResult } from '@aiready/core';
2
+ export { Severity } from '@aiready/core';
2
3
 
3
- /**
4
- * Context-aware severity detection for duplicate patterns
5
- * Identifies intentional duplication patterns and adjusts severity accordingly
6
- */
7
- type Severity = 'critical' | 'major' | 'minor' | 'info';
8
- /**
9
- * Calculate severity based on context rules and code characteristics
10
- */
11
- declare function calculateSeverity(file1: string, file2: string, code: string, similarity: number, linesOfCode: number): {
12
- severity: Severity;
13
- reason?: string;
14
- suggestion?: string;
15
- matchedRule?: string;
16
- };
17
- /**
18
- * Get a human-readable severity label with emoji
19
- */
20
- declare function getSeverityLabel(severity: Severity): string;
21
- /**
22
- * Filter duplicates by minimum severity threshold
23
- */
24
- declare function filterBySeverity<T extends {
25
- severity: Severity;
26
- }>(duplicates: T[], minSeverity: Severity): T[];
27
-
28
- type PatternType = 'function' | 'class-method' | 'api-handler' | 'validator' | 'utility' | 'component' | 'unknown';
4
+ type PatternType = 'api-handler' | 'validator' | 'utility' | 'class-method' | 'component' | 'function' | 'unknown';
29
5
  interface DuplicatePattern {
30
6
  file1: string;
31
- file2: string;
32
7
  line1: number;
33
- line2: number;
34
8
  endLine1: number;
9
+ file2: string;
10
+ line2: number;
35
11
  endLine2: number;
12
+ code1: string;
13
+ code2: string;
36
14
  similarity: number;
37
- snippet: string;
38
15
  patternType: PatternType;
39
16
  tokenCost: number;
40
- linesOfCode: number;
41
17
  severity: Severity;
42
18
  reason?: string;
43
19
  suggestion?: string;
@@ -50,34 +26,26 @@ interface FileContent {
50
26
  interface DetectionOptions {
51
27
  minSimilarity: number;
52
28
  minLines: number;
53
- batchSize?: number;
54
- approx?: boolean;
55
- minSharedTokens?: number;
56
- maxCandidatesPerBlock?: number;
57
- maxComparisons?: number;
58
- streamResults?: boolean;
29
+ batchSize: number;
30
+ approx: boolean;
31
+ minSharedTokens: number;
32
+ maxCandidatesPerBlock: number;
33
+ streamResults: boolean;
59
34
  onProgress?: (processed: number, total: number, message: string) => void;
60
35
  }
61
36
 
62
37
  /**
63
- * Detect duplicate patterns across files with enhanced analysis
64
- */
65
- declare function detectDuplicatePatterns(files: FileContent[], options: DetectionOptions): Promise<DuplicatePattern[]>;
66
-
67
- /**
68
- * Grouping and clustering utilities for duplicate patterns
69
- * Reduces noise by consolidating similar duplicates and creating refactor clusters
38
+ * Detect duplicate patterns across files
70
39
  */
40
+ declare function detectDuplicatePatterns(fileContents: FileContent[], options: DetectionOptions): Promise<DuplicatePattern[]>;
71
41
 
72
42
  interface DuplicateGroup {
73
43
  filePair: string;
74
- duplicates: DuplicatePattern[];
75
- totalTokenCost: number;
76
- averageSimilarity: number;
77
- maxSimilarity: number;
78
44
  severity: Severity;
79
- patternType: PatternType;
80
45
  occurrences: number;
46
+ totalTokenCost: number;
47
+ averageSimilarity: number;
48
+ patternTypes: Set<PatternType>;
81
49
  lineRanges: Array<{
82
50
  file1: {
83
51
  start: number;
@@ -93,13 +61,12 @@ interface RefactorCluster {
93
61
  id: string;
94
62
  name: string;
95
63
  files: string[];
96
- patternType: PatternType;
97
64
  severity: Severity;
65
+ duplicateCount: number;
98
66
  totalTokenCost: number;
99
67
  averageSimilarity: number;
100
- duplicateCount: number;
101
- suggestion: string;
102
- reason: string;
68
+ reason?: string;
69
+ suggestion?: string;
103
70
  }
104
71
 
105
72
  /**
@@ -116,6 +83,26 @@ interface RefactorCluster {
116
83
  */
117
84
  declare function calculatePatternScore(duplicates: DuplicatePattern[], totalFilesAnalyzed: number, costConfig?: Partial<CostConfig>): ToolScoringOutput;
118
85
 
86
+ /**
87
+ * Calculate severity based on context rules and code characteristics
88
+ */
89
+ declare function calculateSeverity(file1: string, file2: string, code: string, similarity: number, linesOfCode: number): {
90
+ severity: Severity;
91
+ reason?: string;
92
+ suggestion?: string;
93
+ matchedRule?: string;
94
+ };
95
+ /**
96
+ * Get a human-readable severity label with emoji
97
+ */
98
+ declare function getSeverityLabel(severity: Severity): string;
99
+ /**
100
+ * Filter duplicates by minimum severity threshold
101
+ */
102
+ declare function filterBySeverity<T extends {
103
+ severity: Severity;
104
+ }>(duplicates: T[], minSeverity: Severity): T[];
105
+
119
106
  interface PatternDetectOptions extends ScanOptions {
120
107
  minSimilarity?: number;
121
108
  minLines?: number;
@@ -164,4 +151,4 @@ declare function analyzePatterns(options: PatternDetectOptions): Promise<{
164
151
  */
165
152
  declare function generateSummary(results: AnalysisResult[]): PatternSummary;
166
153
 
167
- export { type DuplicateGroup, type DuplicatePattern, type PatternDetectOptions, type PatternSummary, type PatternType, type RefactorCluster, type Severity, analyzePatterns, calculatePatternScore, calculateSeverity, detectDuplicatePatterns, filterBySeverity, generateSummary, getSeverityLabel, getSmartDefaults };
154
+ export { type DuplicateGroup, type DuplicatePattern, type PatternDetectOptions, type PatternSummary, type PatternType, type RefactorCluster, analyzePatterns, calculatePatternScore, calculateSeverity, detectDuplicatePatterns, filterBySeverity, generateSummary, getSeverityLabel, getSmartDefaults };