@aiready/pattern-detect 0.17.8 → 0.17.12

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.
Files changed (190) hide show
  1. package/dist/analyzer-entry/index.d.mts +1 -1
  2. package/dist/analyzer-entry/index.d.ts +1 -1
  3. package/dist/analyzer-entry/index.js +370 -135
  4. package/dist/analyzer-entry/index.mjs +4 -3
  5. package/dist/chunk-2P7BQHGR.mjs +306 -0
  6. package/dist/{chunk-VGMM3L3O.mjs → chunk-3EORD7DC.mjs} +1 -1
  7. package/dist/{chunk-GREN7X5H.mjs → chunk-4PVPQMRT.mjs} +2 -2
  8. package/dist/{chunk-RS73WLNI.mjs → chunk-6VDL7TAS.mjs} +5 -113
  9. package/dist/chunk-AQIP4JGM.mjs +283 -0
  10. package/dist/{chunk-JBUZ6YHE.mjs → chunk-B4NLWKPZ.mjs} +85 -9
  11. package/dist/chunk-IPBGVPUX.mjs +143 -0
  12. package/dist/chunk-LUUJOUK5.mjs +283 -0
  13. package/dist/chunk-P3BOCGVV.mjs +498 -0
  14. package/dist/{scoring-entry.js → chunk-PHJE6A3J.mjs} +20 -37
  15. package/dist/chunk-PQXOORR4.mjs +234 -0
  16. package/dist/{chunk-GLKAGFKX.mjs → chunk-RDR75DVI.mjs} +85 -9
  17. package/dist/chunk-SXVLRPMF.mjs +143 -0
  18. package/dist/{chunk-DNZS4ESD.mjs → chunk-SY7RX5YQ.mjs} +85 -9
  19. package/dist/{context-rules-entry.js → chunk-TIBF7KST.mjs} +81 -78
  20. package/dist/chunk-WYYSQX5M.mjs +467 -0
  21. package/dist/{chunk-I6ETJC7L.mjs → chunk-X553BOMI.mjs} +56 -26
  22. package/dist/{chunk-K7BO57OO.mjs → chunk-Y6OB7K34.mjs} +80 -4
  23. package/dist/chunk-YLVV6YZ5.mjs +143 -0
  24. package/dist/chunk-ZUWPFVJV.mjs +115 -0
  25. package/dist/chunk-ZZMONVPE.mjs +467 -0
  26. package/dist/cli.js +402 -167
  27. package/dist/cli.mjs +4 -3
  28. package/dist/context-rules-entry/index.d.mts +35 -1
  29. package/dist/context-rules-entry/index.d.ts +35 -1
  30. package/dist/context-rules-entry/index.js +194 -48
  31. package/dist/context-rules-entry/index.mjs +1 -1
  32. package/dist/detector-entry/index.js +192 -46
  33. package/dist/detector-entry/index.mjs +2 -2
  34. package/dist/{analyzer-entry-BVz-HnZd.d.mts → index-B-pnXpgn.d.mts} +10 -1
  35. package/dist/{index-BwuoiCNm.d.ts → index-CWgYOKaK.d.ts} +35 -16
  36. package/dist/{index-BVz-HnZd.d.mts → index-Dl4BrGIT.d.mts} +35 -16
  37. package/dist/{analyzer-entry-BwuoiCNm.d.ts → index-DqS2e0kK.d.ts} +10 -1
  38. package/dist/index.d.mts +5 -6
  39. package/dist/index.d.ts +5 -6
  40. package/dist/index.js +467 -214
  41. package/dist/index.mjs +37 -22
  42. package/dist/scoring-entry/index.js +7 -3
  43. package/dist/scoring-entry/index.mjs +1 -1
  44. package/package.json +2 -2
  45. package/dist/analyzer-entry.d.mts +0 -100
  46. package/dist/analyzer-entry.d.ts +0 -100
  47. package/dist/analyzer-entry.js +0 -693
  48. package/dist/analyzer-entry.mjs +0 -12
  49. package/dist/chunk-262N2JB7.mjs +0 -497
  50. package/dist/chunk-2R7HOR5H.mjs +0 -777
  51. package/dist/chunk-3D7RVGHM.mjs +0 -64
  52. package/dist/chunk-3LS3E6MO.mjs +0 -508
  53. package/dist/chunk-3VRQYFW3.mjs +0 -782
  54. package/dist/chunk-3WK24ZOX.mjs +0 -860
  55. package/dist/chunk-3YYN6ZXN.mjs +0 -1038
  56. package/dist/chunk-4BPRGZRG.mjs +0 -1041
  57. package/dist/chunk-4UHDGB7U.mjs +0 -920
  58. package/dist/chunk-5LYDB7DY.mjs +0 -771
  59. package/dist/chunk-65G3HXLQ.mjs +0 -497
  60. package/dist/chunk-65UQ5J2J.mjs +0 -64
  61. package/dist/chunk-6JTVOBJX.mjs +0 -64
  62. package/dist/chunk-6OEHUI5J.mjs +0 -1045
  63. package/dist/chunk-6YUGU4P4.mjs +0 -914
  64. package/dist/chunk-7EJGNGXM.mjs +0 -771
  65. package/dist/chunk-7O2DUBSN.mjs +0 -1058
  66. package/dist/chunk-7S4AUL5S.mjs +0 -911
  67. package/dist/chunk-A76JUWER.mjs +0 -786
  68. package/dist/chunk-AJZUNNFH.mjs +0 -817
  69. package/dist/chunk-AXHGYYYZ.mjs +0 -404
  70. package/dist/chunk-BKRPSTT2.mjs +0 -64
  71. package/dist/chunk-BUBQ3W6W.mjs +0 -980
  72. package/dist/chunk-CCHM2VLK.mjs +0 -1051
  73. package/dist/chunk-CHFK6EBT.mjs +0 -419
  74. package/dist/chunk-CMT3MWWO.mjs +0 -948
  75. package/dist/chunk-CMWW24HW.mjs +0 -259
  76. package/dist/chunk-CTDBJP25.mjs +0 -1043
  77. package/dist/chunk-DGAKXYIP.mjs +0 -1041
  78. package/dist/chunk-DQSLTL7J.mjs +0 -788
  79. package/dist/chunk-DR5W7S3Z.mjs +0 -968
  80. package/dist/chunk-EFUKPMBE.mjs +0 -950
  81. package/dist/chunk-EVBFDILL.mjs +0 -927
  82. package/dist/chunk-EXORBAXR.mjs +0 -887
  83. package/dist/chunk-EZT3NZGB.mjs +0 -1057
  84. package/dist/chunk-FWUKMJEQ.mjs +0 -1133
  85. package/dist/chunk-GSJFORRO.mjs +0 -504
  86. package/dist/chunk-H4ADJYOG.mjs +0 -925
  87. package/dist/chunk-H5FB2USZ.mjs +0 -762
  88. package/dist/chunk-H73HEG7M.mjs +0 -670
  89. package/dist/chunk-HOS5Z2NC.mjs +0 -669
  90. package/dist/chunk-HXHQOQB5.mjs +0 -508
  91. package/dist/chunk-INEOYHUM.mjs +0 -911
  92. package/dist/chunk-INJ4SBTV.mjs +0 -754
  93. package/dist/chunk-J5CW6NYY.mjs +0 -64
  94. package/dist/chunk-JAFZCZAP.mjs +0 -776
  95. package/dist/chunk-JKVKOXYR.mjs +0 -407
  96. package/dist/chunk-JTHW7EYW.mjs +0 -1041
  97. package/dist/chunk-JWR3AHKO.mjs +0 -788
  98. package/dist/chunk-KC2CQMG2.mjs +0 -858
  99. package/dist/chunk-KDWGWBP5.mjs +0 -832
  100. package/dist/chunk-KPEK5REL.mjs +0 -919
  101. package/dist/chunk-KT6O2IAE.mjs +0 -861
  102. package/dist/chunk-KWMNN3TG.mjs +0 -391
  103. package/dist/chunk-LUA5FXSZ.mjs +0 -771
  104. package/dist/chunk-LYKRYBSM.mjs +0 -64
  105. package/dist/chunk-M4PQMW34.mjs +0 -480
  106. package/dist/chunk-MH6LBXZF.mjs +0 -816
  107. package/dist/chunk-MHU3CL4R.mjs +0 -64
  108. package/dist/chunk-MJWBS6SM.mjs +0 -1058
  109. package/dist/chunk-OFGMDX66.mjs +0 -402
  110. package/dist/chunk-P7B6Z4I2.mjs +0 -1043
  111. package/dist/chunk-PBCXSG7E.mjs +0 -658
  112. package/dist/chunk-PEEHSFDR.mjs +0 -1058
  113. package/dist/chunk-PSVG2NLH.mjs +0 -966
  114. package/dist/chunk-PWNQ6JZW.mjs +0 -508
  115. package/dist/chunk-QE4E3F7C.mjs +0 -410
  116. package/dist/chunk-QEP76HGK.mjs +0 -1039
  117. package/dist/chunk-QX2BQJEO.mjs +0 -1058
  118. package/dist/chunk-R2S73CVG.mjs +0 -503
  119. package/dist/chunk-RMGDSNLE.mjs +0 -770
  120. package/dist/chunk-S2KQFII2.mjs +0 -491
  121. package/dist/chunk-SLDK5PQK.mjs +0 -1129
  122. package/dist/chunk-SNSDVGWW.mjs +0 -783
  123. package/dist/chunk-SUUZMLPS.mjs +0 -391
  124. package/dist/chunk-SVCSIZ2A.mjs +0 -259
  125. package/dist/chunk-T2C6WS73.mjs +0 -670
  126. package/dist/chunk-TCG2G32F.mjs +0 -911
  127. package/dist/chunk-TGBZP7SB.mjs +0 -773
  128. package/dist/chunk-THF4RW63.mjs +0 -254
  129. package/dist/chunk-TJKDLVLN.mjs +0 -503
  130. package/dist/chunk-TXWPOVYU.mjs +0 -402
  131. package/dist/chunk-UB3CGOQ7.mjs +0 -64
  132. package/dist/chunk-UKIKN27B.mjs +0 -950
  133. package/dist/chunk-V5DP4FP6.mjs +0 -876
  134. package/dist/chunk-VRMXVYDZ.mjs +0 -419
  135. package/dist/chunk-WACZ5LFH.mjs +0 -1055
  136. package/dist/chunk-WC7CBAA7.mjs +0 -1058
  137. package/dist/chunk-WKBCNITM.mjs +0 -1072
  138. package/dist/chunk-WMOGJFME.mjs +0 -391
  139. package/dist/chunk-X4GR2N2M.mjs +0 -947
  140. package/dist/chunk-XCWY2DQY.mjs +0 -788
  141. package/dist/chunk-XJD35DS6.mjs +0 -1058
  142. package/dist/chunk-XNPID6FU.mjs +0 -391
  143. package/dist/chunk-XUUVS54V.mjs +0 -776
  144. package/dist/chunk-YCGV65F5.mjs +0 -508
  145. package/dist/chunk-YJYDBFT3.mjs +0 -780
  146. package/dist/chunk-YP3HEDQW.mjs +0 -859
  147. package/dist/chunk-YSDOUNJJ.mjs +0 -1142
  148. package/dist/chunk-Z6GBFFOV.mjs +0 -1040
  149. package/dist/cli.d.ts.map +0 -1
  150. package/dist/cli.js.map +0 -1
  151. package/dist/context-rules-entry-y2uJSngh.d.mts +0 -60
  152. package/dist/context-rules-entry-y2uJSngh.d.ts +0 -60
  153. package/dist/context-rules-entry.d.mts +0 -55
  154. package/dist/context-rules-entry.d.ts +0 -55
  155. package/dist/context-rules-entry.mjs +0 -12
  156. package/dist/context-rules.d.ts +0 -41
  157. package/dist/context-rules.d.ts.map +0 -1
  158. package/dist/context-rules.js +0 -225
  159. package/dist/context-rules.js.map +0 -1
  160. package/dist/detector-entry.d.mts +0 -14
  161. package/dist/detector-entry.d.ts +0 -14
  162. package/dist/detector-entry.js +0 -301
  163. package/dist/detector-entry.mjs +0 -7
  164. package/dist/detector.d.ts +0 -40
  165. package/dist/detector.d.ts.map +0 -1
  166. package/dist/detector.js +0 -385
  167. package/dist/detector.js.map +0 -1
  168. package/dist/extractors/python-extractor.d.ts +0 -19
  169. package/dist/extractors/python-extractor.d.ts.map +0 -1
  170. package/dist/extractors/python-extractor.js +0 -164
  171. package/dist/extractors/python-extractor.js.map +0 -1
  172. package/dist/grouping.d.ts +0 -54
  173. package/dist/grouping.d.ts.map +0 -1
  174. package/dist/grouping.js +0 -347
  175. package/dist/grouping.js.map +0 -1
  176. package/dist/index-y2uJSngh.d.mts +0 -60
  177. package/dist/index-y2uJSngh.d.ts +0 -60
  178. package/dist/index.d.ts.map +0 -1
  179. package/dist/index.js.map +0 -1
  180. package/dist/python-extractor-BGKGX6BK.mjs +0 -131
  181. package/dist/python-extractor-ELAKYK2W.mjs +0 -140
  182. package/dist/scoring-entry.d.mts +0 -23
  183. package/dist/scoring-entry.d.ts +0 -23
  184. package/dist/scoring-entry.mjs +0 -6
  185. package/dist/scoring.d.ts +0 -12
  186. package/dist/scoring.d.ts.map +0 -1
  187. package/dist/scoring.js +0 -116
  188. package/dist/scoring.js.map +0 -1
  189. package/dist/types-C4lmb2Yh.d.mts +0 -36
  190. package/dist/types-C4lmb2Yh.d.ts +0 -36
package/dist/detector.js DELETED
@@ -1,385 +0,0 @@
1
- import { estimateTokens } from '@aiready/core';
2
- import { calculateSeverity } from './context-rules';
3
- /**
4
- * Categorize code pattern based on content heuristics
5
- */
6
- function categorizePattern(code) {
7
- const lower = code.toLowerCase();
8
- // API handler patterns
9
- if ((lower.includes('request') && lower.includes('response')) ||
10
- lower.includes('router.') ||
11
- lower.includes('app.get') ||
12
- lower.includes('app.post') ||
13
- lower.includes('express') ||
14
- lower.includes('ctx.body')) {
15
- return 'api-handler';
16
- }
17
- // Validator patterns
18
- if (lower.includes('validate') ||
19
- lower.includes('schema') ||
20
- lower.includes('zod') ||
21
- lower.includes('yup') ||
22
- (lower.includes('if') && lower.includes('throw'))) {
23
- return 'validator';
24
- }
25
- // Component patterns (React, Vue, etc.)
26
- if (lower.includes('return (') ||
27
- lower.includes('jsx') ||
28
- lower.includes('component') ||
29
- lower.includes('props')) {
30
- return 'component';
31
- }
32
- // Class methods
33
- if (lower.includes('class ') || lower.includes('this.')) {
34
- return 'class-method';
35
- }
36
- // Utility functions (pure functions with clear input/output)
37
- if (lower.includes('return ') &&
38
- !lower.includes('this') &&
39
- !lower.includes('new ')) {
40
- return 'utility';
41
- }
42
- // Generic function
43
- if (lower.includes('function') || lower.includes('=>')) {
44
- return 'function';
45
- }
46
- return 'unknown';
47
- }
48
- /**
49
- * Extract function-like blocks from code using improved heuristics
50
- */
51
- function extractCodeBlocks(content, minLines) {
52
- const lines = content.split('\n');
53
- const blocks = [];
54
- let currentBlock = [];
55
- let blockStart = 0;
56
- let braceDepth = 0;
57
- let inFunction = false;
58
- for (let i = 0; i < lines.length; i++) {
59
- const line = lines[i];
60
- const trimmed = line.trim();
61
- // Detect function start
62
- if (!inFunction &&
63
- (trimmed.includes('function ') ||
64
- trimmed.includes('=>') ||
65
- trimmed.includes('async ') ||
66
- /^(export\s+)?(async\s+)?function\s+/.test(trimmed) ||
67
- /^(export\s+)?const\s+\w+\s*=\s*(async\s*)?\(/.test(trimmed))) {
68
- inFunction = true;
69
- blockStart = i;
70
- }
71
- // Track brace depth
72
- for (const char of line) {
73
- if (char === '{')
74
- braceDepth++;
75
- if (char === '}')
76
- braceDepth--;
77
- }
78
- if (inFunction) {
79
- currentBlock.push(line);
80
- }
81
- // When we close a function block
82
- if (inFunction && braceDepth === 0 && currentBlock.length >= minLines) {
83
- const blockContent = currentBlock.join('\n');
84
- const linesOfCode = currentBlock.filter((l) => l.trim() && !l.trim().startsWith('//')).length;
85
- blocks.push({
86
- content: blockContent,
87
- startLine: blockStart + 1,
88
- endLine: i + 1,
89
- patternType: categorizePattern(blockContent),
90
- linesOfCode,
91
- });
92
- currentBlock = [];
93
- inFunction = false;
94
- }
95
- else if (inFunction && braceDepth === 0) {
96
- // Reset if we're not accumulating enough
97
- currentBlock = [];
98
- inFunction = false;
99
- }
100
- }
101
- return blocks;
102
- }
103
- /**
104
- * Normalize code for comparison
105
- * - Remove comments
106
- * - Normalize whitespace
107
- * - Remove variable names (replace with placeholders)
108
- * - Keep structure intact
109
- */
110
- function normalizeCode(code) {
111
- // Safety check for undefined/null input
112
- if (!code) {
113
- return '';
114
- }
115
- return (code
116
- // Remove single-line comments
117
- .replace(/\/\/.*$/gm, '')
118
- // Remove multi-line comments
119
- .replace(/\/\*[\s\S]*?\*\//g, '')
120
- // Normalize string literals to generic placeholder
121
- .replace(/"[^"]*"/g, '"STR"')
122
- .replace(/'[^']*'/g, "'STR'")
123
- .replace(/`[^`]*`/g, '`STR`')
124
- // Normalize numbers
125
- .replace(/\b\d+\b/g, 'NUM')
126
- // Normalize whitespace but keep structure
127
- .replace(/\s+/g, ' ')
128
- .trim());
129
- }
130
- /**
131
- * Fast Jaccard similarity on token sets - O(N+M) instead of O(N×M)
132
- */
133
- function jaccardSimilarity(tokens1, tokens2) {
134
- const set1 = new Set(tokens1);
135
- const set2 = new Set(tokens2);
136
- let intersection = 0;
137
- for (const token of set1) {
138
- if (set2.has(token))
139
- intersection++;
140
- }
141
- const union = set1.size + set2.size - intersection;
142
- return union === 0 ? 0 : intersection / union;
143
- }
144
- /**
145
- * Detect duplicate patterns across files with enhanced analysis
146
- */
147
- export async function detectDuplicatePatterns(files, options) {
148
- const { minSimilarity, minLines, batchSize = 100, approx = true, minSharedTokens = 8, maxCandidatesPerBlock = 100, streamResults = false, } = options;
149
- const duplicates = [];
150
- // Safety limit only for --no-approx mode (O(B²) worst case)
151
- // Approximate mode has natural limits and doesn't need budget
152
- const maxComparisons = approx ? Infinity : 500000;
153
- // Extract blocks from all files
154
- const allBlocks = files.flatMap((file) => extractCodeBlocks(file.content, minLines)
155
- .filter((block) => block.content && block.content.trim().length > 0)
156
- .map((block) => ({
157
- content: block.content,
158
- startLine: block.startLine,
159
- endLine: block.endLine,
160
- file: file.file,
161
- normalized: normalizeCode(block.content),
162
- patternType: block.patternType,
163
- tokenCost: estimateTokens(block.content),
164
- linesOfCode: block.linesOfCode,
165
- })));
166
- console.log(`Extracted ${allBlocks.length} code blocks for analysis`);
167
- // Add Python blocks if present
168
- const pythonFiles = files.filter(f => f.file.toLowerCase().endsWith('.py'));
169
- if (pythonFiles.length > 0) {
170
- const { extractPythonPatterns } = await import('./extractors/python-extractor');
171
- const patterns = await extractPythonPatterns(pythonFiles.map(f => f.file));
172
- const pythonBlocks = patterns
173
- .filter((p) => p.code && p.code.trim().length > 0)
174
- .map(p => ({
175
- content: p.code,
176
- startLine: p.startLine,
177
- endLine: p.endLine,
178
- file: p.file,
179
- normalized: normalizeCode(p.code),
180
- patternType: p.type,
181
- tokenCost: estimateTokens(p.code),
182
- linesOfCode: p.endLine - p.startLine + 1,
183
- }));
184
- allBlocks.push(...pythonBlocks);
185
- console.log(`Added ${pythonBlocks.length} Python patterns`);
186
- }
187
- // Warn about --no-approx performance implications
188
- if (!approx && allBlocks.length > 500) {
189
- console.log(`⚠️ Using --no-approx mode with ${allBlocks.length} blocks may be slow (O(B²) complexity).`);
190
- console.log(` Consider using approximate mode (default) for better performance.`);
191
- }
192
- // Use minLines to control scope instead of arbitrary block limits
193
- // Tokenize blocks for candidate selection
194
- const stopwords = new Set([
195
- 'return', 'const', 'let', 'var', 'function', 'class', 'new', 'if', 'else', 'for', 'while',
196
- 'async', 'await', 'try', 'catch', 'switch', 'case', 'default', 'import', 'export', 'from',
197
- 'true', 'false', 'null', 'undefined', 'this'
198
- ]);
199
- const tokenize = (norm) => norm
200
- .split(/[\s(){}\[\];,\.]+/)
201
- .filter((t) => t && t.length >= 3 && !stopwords.has(t.toLowerCase()));
202
- const blockTokens = allBlocks.map((b) => tokenize(b.normalized));
203
- // Build inverted index token -> block ids (for approx mode)
204
- const invertedIndex = new Map();
205
- if (approx) {
206
- for (let i = 0; i < blockTokens.length; i++) {
207
- for (const tok of blockTokens[i]) {
208
- let arr = invertedIndex.get(tok);
209
- if (!arr) {
210
- arr = [];
211
- invertedIndex.set(tok, arr);
212
- }
213
- arr.push(i);
214
- }
215
- }
216
- }
217
- // Process comparisons (exact or approximate) in batches to reduce memory pressure
218
- const totalComparisons = approx
219
- ? undefined
220
- : (allBlocks.length * (allBlocks.length - 1)) / 2;
221
- if (totalComparisons !== undefined) {
222
- console.log(`Processing ${totalComparisons.toLocaleString()} comparisons in batches...`);
223
- }
224
- else {
225
- console.log(`Using approximate candidate selection to reduce comparisons...`);
226
- }
227
- let comparisonsProcessed = 0;
228
- let comparisonsBudgetExhausted = false;
229
- const startTime = Date.now();
230
- for (let i = 0; i < allBlocks.length; i++) {
231
- if (maxComparisons && comparisonsProcessed >= maxComparisons) {
232
- comparisonsBudgetExhausted = true;
233
- break;
234
- }
235
- // Progress reporting every batch
236
- if (i % batchSize === 0 && i > 0) {
237
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
238
- const duplicatesFound = duplicates.length;
239
- if (totalComparisons !== undefined) {
240
- const progress = ((comparisonsProcessed / totalComparisons) * 100).toFixed(1);
241
- const remaining = totalComparisons - comparisonsProcessed;
242
- const rate = comparisonsProcessed / parseFloat(elapsed);
243
- const eta = remaining > 0 ? (remaining / rate).toFixed(0) : 0;
244
- console.log(` ${progress}% (${comparisonsProcessed.toLocaleString()}/${totalComparisons.toLocaleString()} comparisons, ${elapsed}s elapsed, ~${eta}s remaining, ${duplicatesFound} duplicates)`);
245
- }
246
- else {
247
- console.log(` Processed ${i.toLocaleString()}/${allBlocks.length} blocks (${elapsed}s elapsed, ${duplicatesFound} duplicates)`);
248
- }
249
- // Allow garbage collection between batches
250
- await new Promise((resolve) => setImmediate(resolve));
251
- }
252
- const block1 = allBlocks[i];
253
- // Build candidate list (approx mode) - much more aggressive filtering
254
- let candidates = null;
255
- if (approx) {
256
- const counts = new Map();
257
- const block1Tokens = new Set(blockTokens[i]);
258
- const block1Size = block1Tokens.size;
259
- // Only consider tokens that are not too common (appear in < 10% of blocks)
260
- const rareTokens = blockTokens[i].filter(tok => {
261
- const blocksWithToken = invertedIndex.get(tok)?.length || 0;
262
- return blocksWithToken < allBlocks.length * 0.1; // < 10% of blocks
263
- });
264
- // Use only rare tokens for candidate selection to avoid noise from common tokens
265
- for (const tok of rareTokens) {
266
- const ids = invertedIndex.get(tok);
267
- if (!ids)
268
- continue;
269
- for (const j of ids) {
270
- if (j <= i)
271
- continue; // only forward pairs
272
- if (allBlocks[j].file === block1.file)
273
- continue; // skip same-file
274
- counts.set(j, (counts.get(j) || 0) + 1);
275
- }
276
- }
277
- // Filter candidates more aggressively:
278
- // - Must share at least minSharedTokens
279
- // - Must share at least minSharedTokens
280
- // - Must share at least 30% of the smaller block's tokens (to ensure substantial overlap)
281
- candidates = Array.from(counts.entries())
282
- .filter(([j, shared]) => {
283
- const block2Tokens = blockTokens[j];
284
- const block2Size = block2Tokens.length;
285
- const minSize = Math.min(block1Size, block2Size);
286
- const sharedPercentage = shared / minSize;
287
- return shared >= minSharedTokens && sharedPercentage >= 0.3;
288
- })
289
- .sort((a, b) => b[1] - a[1])
290
- .slice(0, Math.min(maxCandidatesPerBlock, 5)) // Even more aggressive limit
291
- .map(([j, shared]) => ({ j, shared }));
292
- }
293
- if (approx && candidates) {
294
- for (const { j } of candidates) {
295
- if (!approx && maxComparisons !== Infinity && comparisonsProcessed >= maxComparisons) {
296
- console.log(`⚠️ Comparison safety limit reached (${maxComparisons.toLocaleString()} comparisons in --no-approx mode).`);
297
- console.log(` This prevents excessive runtime on large repos. Consider using approximate mode (default) or --min-lines to reduce blocks.`);
298
- break;
299
- }
300
- comparisonsProcessed++;
301
- const block2 = allBlocks[j];
302
- // Optional: skip cross-type comparisons unless unknown
303
- // if (block1.patternType !== block2.patternType &&
304
- // block1.patternType !== 'unknown' && block2.patternType !== 'unknown') continue;
305
- const similarity = jaccardSimilarity(blockTokens[i], blockTokens[j]);
306
- if (similarity >= minSimilarity) {
307
- // Calculate context-aware severity
308
- const { severity, reason, suggestion, matchedRule } = calculateSeverity(block1.file, block2.file, block1.content, similarity, block1.linesOfCode);
309
- const duplicate = {
310
- file1: block1.file,
311
- file2: block2.file,
312
- line1: block1.startLine,
313
- line2: block2.startLine,
314
- endLine1: block1.endLine,
315
- endLine2: block2.endLine,
316
- similarity,
317
- snippet: block1.content.split('\n').slice(0, 5).join('\n') + '\n...',
318
- patternType: block1.patternType,
319
- tokenCost: block1.tokenCost + block2.tokenCost,
320
- linesOfCode: block1.linesOfCode,
321
- severity,
322
- reason,
323
- suggestion,
324
- matchedRule,
325
- };
326
- duplicates.push(duplicate);
327
- if (streamResults) {
328
- console.log(`\n ✅ Found: ${duplicate.patternType} ${Math.round(similarity * 100)}% similar`);
329
- console.log(` ${duplicate.file1}:${duplicate.line1}-${duplicate.endLine1} ⇔ ${duplicate.file2}:${duplicate.line2}-${duplicate.endLine2}`);
330
- console.log(` Token cost: ${duplicate.tokenCost.toLocaleString()}`);
331
- }
332
- }
333
- }
334
- }
335
- else {
336
- // Exact mode: compare against all subsequent blocks
337
- for (let j = i + 1; j < allBlocks.length; j++) {
338
- if (maxComparisons && comparisonsProcessed >= maxComparisons)
339
- break;
340
- comparisonsProcessed++;
341
- const block2 = allBlocks[j];
342
- // Skip comparing blocks from the same file
343
- if (block1.file === block2.file)
344
- continue;
345
- // Optional: skip cross-type comparisons unless unknown
346
- // if (block1.patternType !== block2.patternType &&
347
- // block1.patternType !== 'unknown' && block2.patternType !== 'unknown') continue;
348
- const similarity = jaccardSimilarity(blockTokens[i], blockTokens[j]);
349
- if (similarity >= minSimilarity) {
350
- // Calculate context-aware severity
351
- const { severity, reason, suggestion, matchedRule } = calculateSeverity(block1.file, block2.file, block1.content, similarity, block1.linesOfCode);
352
- const duplicate = {
353
- file1: block1.file,
354
- file2: block2.file,
355
- line1: block1.startLine,
356
- line2: block2.startLine,
357
- endLine1: block1.endLine,
358
- endLine2: block2.endLine,
359
- similarity,
360
- snippet: block1.content.split('\n').slice(0, 5).join('\n') + '\n...',
361
- patternType: block1.patternType,
362
- tokenCost: block1.tokenCost + block2.tokenCost,
363
- linesOfCode: block1.linesOfCode,
364
- severity,
365
- reason,
366
- suggestion,
367
- matchedRule,
368
- };
369
- duplicates.push(duplicate);
370
- if (streamResults) {
371
- console.log(`\n ✅ Found: ${duplicate.patternType} ${Math.round(similarity * 100)}% similar`);
372
- console.log(` ${duplicate.file1}:${duplicate.line1}-${duplicate.endLine1} ⇔ ${duplicate.file2}:${duplicate.line2}-${duplicate.endLine2}`);
373
- console.log(` Token cost: ${duplicate.tokenCost.toLocaleString()}`);
374
- }
375
- }
376
- }
377
- }
378
- }
379
- if (comparisonsBudgetExhausted) {
380
- console.log(`⚠️ Comparison budget exhausted (${maxComparisons.toLocaleString()} comparisons). Use --max-comparisons to increase.`);
381
- }
382
- // Sort by similarity descending, then by token cost
383
- return duplicates.sort((a, b) => b.similarity - a.similarity || b.tokenCost - a.tokenCost);
384
- }
385
- //# sourceMappingURL=detector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"detector.js","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- /**
2
- * Python Pattern Extractor
3
- *
4
- * Extracts functions and classes from Python code for similarity analysis
5
- */
6
- import type { CodePattern } from '../types';
7
- /**
8
- * Extract patterns from Python files
9
- */
10
- export declare function extractPythonPatterns(files: string[]): Promise<CodePattern[]>;
11
- /**
12
- * Calculate similarity between two Python patterns
13
- */
14
- export declare function calculatePythonSimilarity(pattern1: CodePattern, pattern2: CodePattern): number;
15
- /**
16
- * Detect common Python patterns that indicate duplication
17
- */
18
- export declare function detectPythonAntiPatterns(patterns: CodePattern[]): string[];
19
- //# sourceMappingURL=python-extractor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"python-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/python-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAmDnF;AAUD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,WAAW,GACpB,MAAM,CAgCR;AA4DD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAwB1E"}
@@ -1,164 +0,0 @@
1
- /**
2
- * Python Pattern Extractor
3
- *
4
- * Extracts functions and classes from Python code for similarity analysis
5
- */
6
- import { getParser } from '@aiready/core';
7
- /**
8
- * Extract patterns from Python files
9
- */
10
- export async function extractPythonPatterns(files) {
11
- const patterns = [];
12
- const parser = getParser('dummy.py');
13
- if (!parser) {
14
- console.warn('Python parser not available');
15
- return patterns;
16
- }
17
- const pythonFiles = files.filter(f => f.toLowerCase().endsWith('.py'));
18
- for (const file of pythonFiles) {
19
- try {
20
- const fs = await import('fs');
21
- const code = await fs.promises.readFile(file, 'utf-8');
22
- const result = parser.parse(code, file);
23
- // Extract function patterns
24
- for (const exp of result.exports) {
25
- if (exp.type === 'function') {
26
- patterns.push({
27
- file,
28
- name: exp.name,
29
- type: 'function',
30
- startLine: exp.loc?.start.line || 0,
31
- endLine: exp.loc?.end.line || 0,
32
- imports: exp.imports || [],
33
- dependencies: exp.dependencies || [],
34
- signature: generatePythonSignature(exp),
35
- language: 'python',
36
- });
37
- }
38
- else if (exp.type === 'class') {
39
- patterns.push({
40
- file,
41
- name: exp.name,
42
- type: 'class',
43
- startLine: exp.loc?.start.line || 0,
44
- endLine: exp.loc?.end.line || 0,
45
- imports: exp.imports || [],
46
- dependencies: exp.dependencies || [],
47
- signature: `class ${exp.name}`,
48
- language: 'python',
49
- });
50
- }
51
- }
52
- }
53
- catch (error) {
54
- console.warn(`Failed to extract patterns from ${file}:`, error);
55
- }
56
- }
57
- return patterns;
58
- }
59
- /**
60
- * Generate a signature for a Python function
61
- */
62
- function generatePythonSignature(exp) {
63
- const params = exp.parameters?.join(', ') || '';
64
- return `def ${exp.name}(${params})`;
65
- }
66
- /**
67
- * Calculate similarity between two Python patterns
68
- */
69
- export function calculatePythonSimilarity(pattern1, pattern2) {
70
- let similarity = 0;
71
- let factors = 0;
72
- // 1. Name similarity (30%)
73
- const nameSimilarity = calculateNameSimilarity(pattern1.name, pattern2.name);
74
- similarity += nameSimilarity * 0.3;
75
- factors += 0.3;
76
- // 2. Import similarity (40%)
77
- const importSimilarity = calculateImportSimilarity(pattern1.imports || [], pattern2.imports || []);
78
- similarity += importSimilarity * 0.4;
79
- factors += 0.4;
80
- // 3. Type similarity (10%)
81
- if (pattern1.type === pattern2.type) {
82
- similarity += 0.1;
83
- }
84
- factors += 0.1;
85
- // 4. Signature similarity (20%)
86
- const sigSimilarity = calculateSignatureSimilarity(pattern1.signature, pattern2.signature);
87
- similarity += sigSimilarity * 0.2;
88
- factors += 0.2;
89
- return factors > 0 ? similarity / factors : 0;
90
- }
91
- /**
92
- * Calculate name similarity using Levenshtein-based approach
93
- */
94
- function calculateNameSimilarity(name1, name2) {
95
- if (name1 === name2)
96
- return 1;
97
- // Remove common prefixes/suffixes
98
- const clean1 = name1.replace(/^(get|set|is|has|create|delete|update|fetch)_?/, '');
99
- const clean2 = name2.replace(/^(get|set|is|has|create|delete|update|fetch)_?/, '');
100
- if (clean1 === clean2)
101
- return 0.9;
102
- // Check for substring match
103
- if (clean1.includes(clean2) || clean2.includes(clean1)) {
104
- return 0.7;
105
- }
106
- // Simple character overlap
107
- const set1 = new Set(clean1.split('_'));
108
- const set2 = new Set(clean2.split('_'));
109
- const intersection = new Set([...set1].filter(x => set2.has(x)));
110
- const union = new Set([...set1, ...set2]);
111
- return intersection.size / union.size;
112
- }
113
- /**
114
- * Calculate import similarity (Jaccard index)
115
- */
116
- function calculateImportSimilarity(imports1, imports2) {
117
- if (imports1.length === 0 && imports2.length === 0)
118
- return 1;
119
- if (imports1.length === 0 || imports2.length === 0)
120
- return 0;
121
- const set1 = new Set(imports1);
122
- const set2 = new Set(imports2);
123
- const intersection = new Set([...set1].filter(x => set2.has(x)));
124
- const union = new Set([...set1, ...set2]);
125
- return intersection.size / union.size;
126
- }
127
- /**
128
- * Calculate signature similarity
129
- */
130
- function calculateSignatureSimilarity(sig1, sig2) {
131
- if (sig1 === sig2)
132
- return 1;
133
- // Extract parameter counts
134
- const params1 = (sig1.match(/\([^)]*\)/)?.[0] || '').split(',').filter(Boolean).length;
135
- const params2 = (sig2.match(/\([^)]*\)/)?.[0] || '').split(',').filter(Boolean).length;
136
- if (params1 === params2)
137
- return 0.8;
138
- if (Math.abs(params1 - params2) === 1)
139
- return 0.5;
140
- return 0;
141
- }
142
- /**
143
- * Detect common Python patterns that indicate duplication
144
- */
145
- export function detectPythonAntiPatterns(patterns) {
146
- const antiPatterns = [];
147
- // Group by similar names
148
- const nameGroups = new Map();
149
- for (const pattern of patterns) {
150
- const baseName = pattern.name.replace(/^(get|set|create|delete|update)_/, '');
151
- if (!nameGroups.has(baseName)) {
152
- nameGroups.set(baseName, []);
153
- }
154
- nameGroups.get(baseName).push(pattern);
155
- }
156
- // Check for groups with multiple similar patterns
157
- for (const [baseName, group] of nameGroups) {
158
- if (group.length >= 3) {
159
- antiPatterns.push(`Found ${group.length} functions with similar names (${baseName}): Consider consolidating`);
160
- }
161
- }
162
- return antiPatterns;
163
- }
164
- //# sourceMappingURL=python-extractor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"python-extractor.js","sourceRoot":"","sources":["../../src/extractors/python-extractor.ts"],"names":[],"mappings":"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"}
@@ -1,54 +0,0 @@
1
- /**
2
- * Grouping and clustering utilities for duplicate patterns
3
- * Reduces noise by consolidating similar duplicates and creating refactor clusters
4
- */
5
- import type { DuplicatePattern, PatternType } from './detector';
6
- import type { Severity } from './context-rules';
7
- export interface DuplicateGroup {
8
- filePair: string;
9
- duplicates: DuplicatePattern[];
10
- totalTokenCost: number;
11
- averageSimilarity: number;
12
- maxSimilarity: number;
13
- severity: Severity;
14
- patternType: PatternType;
15
- occurrences: number;
16
- lineRanges: Array<{
17
- file1: {
18
- start: number;
19
- end: number;
20
- };
21
- file2: {
22
- start: number;
23
- end: number;
24
- };
25
- }>;
26
- }
27
- export interface RefactorCluster {
28
- id: string;
29
- name: string;
30
- files: string[];
31
- patternType: PatternType;
32
- severity: Severity;
33
- totalTokenCost: number;
34
- averageSimilarity: number;
35
- duplicateCount: number;
36
- suggestion: string;
37
- reason: string;
38
- }
39
- /**
40
- * Group duplicates by file pair, consolidating similar line ranges
41
- * Reduces "80% similar entries for the same file pairs" noise
42
- */
43
- export declare function groupDuplicatesByFilePair(duplicates: DuplicatePattern[]): DuplicateGroup[];
44
- /**
45
- * Create refactor clusters for related duplicates
46
- * Groups UI patterns, components, etc. into actionable clusters
47
- */
48
- export declare function createRefactorClusters(duplicates: DuplicatePattern[]): RefactorCluster[];
49
- /**
50
- * Filter clusters by minimum impact threshold
51
- * Reduces noise from minor refactoring opportunities
52
- */
53
- export declare function filterClustersByImpact(clusters: RefactorCluster[], minTokenCost?: number, minFileCount?: number): RefactorCluster[];
54
- //# sourceMappingURL=grouping.d.ts.map