pi-lens 1.3.7 → 1.3.9
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.
|
@@ -238,6 +238,7 @@ function long(): number {
|
|
|
238
238
|
maintainabilityIndex: 75,
|
|
239
239
|
linesOfCode: 100,
|
|
240
240
|
commentLines: 10,
|
|
241
|
+
codeEntropy: 0.5,
|
|
241
242
|
};
|
|
242
243
|
|
|
243
244
|
const formatted = client.formatMetrics(metrics);
|
|
@@ -259,6 +260,7 @@ function long(): number {
|
|
|
259
260
|
maintainabilityIndex: 25,
|
|
260
261
|
linesOfCode: 500,
|
|
261
262
|
commentLines: 10,
|
|
263
|
+
codeEntropy: 0.5,
|
|
262
264
|
};
|
|
263
265
|
|
|
264
266
|
const formatted = client.formatMetrics(metrics);
|
|
@@ -34,6 +34,7 @@ export interface FileComplexity {
|
|
|
34
34
|
maintainabilityIndex: number; // 0-100
|
|
35
35
|
linesOfCode: number;
|
|
36
36
|
commentLines: number;
|
|
37
|
+
codeEntropy: number; // Shannon entropy (0-1, lower = more predictable)
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export interface FunctionMetrics {
|
|
@@ -195,6 +196,9 @@ export class ComplexityClient {
|
|
|
195
196
|
commentLines
|
|
196
197
|
);
|
|
197
198
|
|
|
199
|
+
// Code Entropy (Shannon entropy of code tokens)
|
|
200
|
+
const codeEntropy = this.calculateCodeEntropy(content);
|
|
201
|
+
|
|
198
202
|
return {
|
|
199
203
|
filePath: path.relative(process.cwd(), absolutePath),
|
|
200
204
|
maxNestingDepth,
|
|
@@ -208,6 +212,7 @@ export class ComplexityClient {
|
|
|
208
212
|
maintainabilityIndex: Math.round(maintainabilityIndex * 10) / 10,
|
|
209
213
|
linesOfCode: codeLines,
|
|
210
214
|
commentLines,
|
|
215
|
+
codeEntropy: Math.round(codeEntropy * 100) / 100,
|
|
211
216
|
};
|
|
212
217
|
} catch (err: any) {
|
|
213
218
|
this.log(`Analysis error for ${filePath}: ${err.message}`);
|
|
@@ -242,6 +247,11 @@ export class ComplexityClient {
|
|
|
242
247
|
parts.push(` Max nesting: ${metrics.maxNestingDepth} levels (consider extracting)`);
|
|
243
248
|
}
|
|
244
249
|
|
|
250
|
+
// Code entropy (in bits, >3.5 = risky AI-induced complexity)
|
|
251
|
+
if (metrics.codeEntropy > 3.5) {
|
|
252
|
+
parts.push(` Entropy: ${metrics.codeEntropy.toFixed(1)} bits (>3.5 — risky AI-induced complexity)`);
|
|
253
|
+
}
|
|
254
|
+
|
|
245
255
|
// Function length
|
|
246
256
|
if (metrics.maxFunctionLength > 50) {
|
|
247
257
|
parts.push(` Longest function: ${metrics.maxFunctionLength} lines (avg: ${metrics.avgFunctionLength})`);
|
|
@@ -491,6 +501,41 @@ export class ComplexityClient {
|
|
|
491
501
|
return totalOps * Math.log2(uniqueOps);
|
|
492
502
|
}
|
|
493
503
|
|
|
504
|
+
/**
|
|
505
|
+
* Calculate Shannon entropy of code tokens (in bits)
|
|
506
|
+
* Uses log2 for entropy measured in bits
|
|
507
|
+
* Threshold: >3.5 bits indicates risky AI-induced complexity
|
|
508
|
+
*/
|
|
509
|
+
private calculateCodeEntropy(sourceText: string): number {
|
|
510
|
+
// Tokenize by splitting on whitespace and common delimiters
|
|
511
|
+
const tokens = sourceText
|
|
512
|
+
.replace(/\/\/.*/g, "") // Remove single-line comments
|
|
513
|
+
.replace(/\/\*[\s\S]*?\*\//g, "") // Remove multi-line comments
|
|
514
|
+
.replace(/["'`][^"'`]*["'`]/g, "STR") // Normalize strings
|
|
515
|
+
.replace(/\b\d+(\.\d+)?\b/g, "NUM") // Normalize numbers
|
|
516
|
+
.split(/[\s\n\r\t,;:()[\]{}=<>!&|+\-*/%^~?]+/)
|
|
517
|
+
.filter(t => t.length > 0);
|
|
518
|
+
|
|
519
|
+
if (tokens.length === 0) return 0;
|
|
520
|
+
|
|
521
|
+
// Count token frequencies
|
|
522
|
+
const freq = new Map<string, number>();
|
|
523
|
+
for (const token of tokens) {
|
|
524
|
+
freq.set(token, (freq.get(token) || 0) + 1);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Calculate Shannon entropy in bits: H = -sum(p * log2(p))
|
|
528
|
+
let entropy = 0;
|
|
529
|
+
for (const count of freq.values()) {
|
|
530
|
+
const p = count / tokens.length;
|
|
531
|
+
if (p > 0) {
|
|
532
|
+
entropy -= p * Math.log2(p);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return entropy; // Return in bits, not normalized
|
|
537
|
+
}
|
|
538
|
+
|
|
494
539
|
private isKeyword(text: string): boolean {
|
|
495
540
|
const keywords = new Set([
|
|
496
541
|
"if", "else", "for", "while", "do", "switch", "case", "break", "continue",
|
package/package.json
CHANGED