pi-lens 2.2.8 → 2.2.10
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/clients/secrets-scanner.js +22 -2
- package/clients/secrets-scanner.ts +29 -2
- package/commands/rate.js +16 -1
- package/commands/rate.ts +18 -1
- package/index.ts +1 -1
- package/package.json +1 -1
|
@@ -68,11 +68,31 @@ const SECRET_PATTERNS = [
|
|
|
68
68
|
message: "Possible secret in .env format",
|
|
69
69
|
},
|
|
70
70
|
];
|
|
71
|
+
/**
|
|
72
|
+
* Check if file path is a test file (should skip secrets scan)
|
|
73
|
+
*/
|
|
74
|
+
function isTestFile(filePath) {
|
|
75
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
76
|
+
return (normalized.includes(".test.") ||
|
|
77
|
+
normalized.includes(".spec.") ||
|
|
78
|
+
normalized.includes("/test/") ||
|
|
79
|
+
normalized.includes("/tests/") ||
|
|
80
|
+
normalized.includes("__tests__/") ||
|
|
81
|
+
normalized.includes("test-utils") ||
|
|
82
|
+
normalized.startsWith("test-") ||
|
|
83
|
+
normalized.includes(".fixture.") ||
|
|
84
|
+
normalized.includes(".mock."));
|
|
85
|
+
}
|
|
71
86
|
/**
|
|
72
87
|
* Scan content for potential secrets
|
|
73
|
-
* Returns findings with line numbers
|
|
88
|
+
* Returns findings with line numbers.
|
|
89
|
+
* Skips test files to avoid false positives.
|
|
74
90
|
*/
|
|
75
|
-
export function scanForSecrets(content) {
|
|
91
|
+
export function scanForSecrets(content, filePath) {
|
|
92
|
+
// Skip test files — secrets in tests are usually fake/test values
|
|
93
|
+
if (filePath && isTestFile(filePath)) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
76
96
|
const findings = [];
|
|
77
97
|
const lines = content.split("\n");
|
|
78
98
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -83,11 +83,38 @@ export interface SecretFinding {
|
|
|
83
83
|
message: string;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Check if file path is a test file (should skip secrets scan)
|
|
88
|
+
*/
|
|
89
|
+
function isTestFile(filePath: string): boolean {
|
|
90
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
91
|
+
return (
|
|
92
|
+
normalized.includes(".test.") ||
|
|
93
|
+
normalized.includes(".spec.") ||
|
|
94
|
+
normalized.includes("/test/") ||
|
|
95
|
+
normalized.includes("/tests/") ||
|
|
96
|
+
normalized.includes("__tests__/") ||
|
|
97
|
+
normalized.includes("test-utils") ||
|
|
98
|
+
normalized.startsWith("test-") ||
|
|
99
|
+
normalized.includes(".fixture.") ||
|
|
100
|
+
normalized.includes(".mock.")
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
86
104
|
/**
|
|
87
105
|
* Scan content for potential secrets
|
|
88
|
-
* Returns findings with line numbers
|
|
106
|
+
* Returns findings with line numbers.
|
|
107
|
+
* Skips test files to avoid false positives.
|
|
89
108
|
*/
|
|
90
|
-
export function scanForSecrets(
|
|
109
|
+
export function scanForSecrets(
|
|
110
|
+
content: string,
|
|
111
|
+
filePath?: string,
|
|
112
|
+
): SecretFinding[] {
|
|
113
|
+
// Skip test files — secrets in tests are usually fake/test values
|
|
114
|
+
if (filePath && isTestFile(filePath)) {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
|
|
91
118
|
const findings: SecretFinding[] = [];
|
|
92
119
|
const lines = content.split("\n");
|
|
93
120
|
|
package/commands/rate.js
CHANGED
|
@@ -69,7 +69,7 @@ export async function gatherScores(targetPath, clients) {
|
|
|
69
69
|
let securityScore = 100;
|
|
70
70
|
const securityIssues = [];
|
|
71
71
|
let secretsFound = 0;
|
|
72
|
-
// Check for secrets in source files
|
|
72
|
+
// Check for secrets in source files (skip test files)
|
|
73
73
|
const secretPatterns = [
|
|
74
74
|
{ name: "API Key (sk-)", pattern: /sk-[a-zA-Z0-9]{20,}/ },
|
|
75
75
|
{ name: "GitHub Token", pattern: /ghp_[a-zA-Z0-9]{36}/ },
|
|
@@ -81,7 +81,22 @@ export async function gatherScores(targetPath, clients) {
|
|
|
81
81
|
pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/,
|
|
82
82
|
},
|
|
83
83
|
];
|
|
84
|
+
function isTestFile(filePath) {
|
|
85
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
86
|
+
return (normalized.includes(".test.") ||
|
|
87
|
+
normalized.includes(".spec.") ||
|
|
88
|
+
normalized.includes("/test/") ||
|
|
89
|
+
normalized.includes("/tests/") ||
|
|
90
|
+
normalized.includes("__tests__/") ||
|
|
91
|
+
normalized.includes("test-utils") ||
|
|
92
|
+
normalized.startsWith("test-") ||
|
|
93
|
+
normalized.includes(".fixture.") ||
|
|
94
|
+
normalized.includes(".mock."));
|
|
95
|
+
}
|
|
84
96
|
for (const file of files.slice(0, 100)) {
|
|
97
|
+
// Skip test files
|
|
98
|
+
if (isTestFile(file))
|
|
99
|
+
continue;
|
|
85
100
|
try {
|
|
86
101
|
const content = nodeFs.readFileSync(file, "utf-8");
|
|
87
102
|
for (const line of content.split("\n")) {
|
package/commands/rate.ts
CHANGED
|
@@ -105,7 +105,7 @@ export async function gatherScores(
|
|
|
105
105
|
const securityIssues: string[] = [];
|
|
106
106
|
let secretsFound = 0;
|
|
107
107
|
|
|
108
|
-
// Check for secrets in source files
|
|
108
|
+
// Check for secrets in source files (skip test files)
|
|
109
109
|
const secretPatterns = [
|
|
110
110
|
{ name: "API Key (sk-)", pattern: /sk-[a-zA-Z0-9]{20,}/ },
|
|
111
111
|
{ name: "GitHub Token", pattern: /ghp_[a-zA-Z0-9]{36}/ },
|
|
@@ -118,7 +118,24 @@ export async function gatherScores(
|
|
|
118
118
|
},
|
|
119
119
|
];
|
|
120
120
|
|
|
121
|
+
function isTestFile(filePath: string): boolean {
|
|
122
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
123
|
+
return (
|
|
124
|
+
normalized.includes(".test.") ||
|
|
125
|
+
normalized.includes(".spec.") ||
|
|
126
|
+
normalized.includes("/test/") ||
|
|
127
|
+
normalized.includes("/tests/") ||
|
|
128
|
+
normalized.includes("__tests__/") ||
|
|
129
|
+
normalized.includes("test-utils") ||
|
|
130
|
+
normalized.startsWith("test-") ||
|
|
131
|
+
normalized.includes(".fixture.") ||
|
|
132
|
+
normalized.includes(".mock.")
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
121
136
|
for (const file of files.slice(0, 100)) {
|
|
137
|
+
// Skip test files
|
|
138
|
+
if (isTestFile(file)) continue;
|
|
122
139
|
try {
|
|
123
140
|
const content = nodeFs.readFileSync(file, "utf-8");
|
|
124
141
|
for (const line of content.split("\n")) {
|
package/index.ts
CHANGED
|
@@ -1303,7 +1303,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1303
1303
|
|
|
1304
1304
|
// --- Secrets scan (blocking - must check before other linting) ---
|
|
1305
1305
|
if (fileContent) {
|
|
1306
|
-
const secretFindings = scanForSecrets(fileContent);
|
|
1306
|
+
const secretFindings = scanForSecrets(fileContent, filePath);
|
|
1307
1307
|
if (secretFindings.length > 0) {
|
|
1308
1308
|
const secretsOutput = formatSecrets(secretFindings, filePath);
|
|
1309
1309
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lens",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Real-time code quality feedback for pi — TypeScript LSP, Biome, ast-grep, Ruff, complexity metrics, duplicate detection. Includes automated fix loop (/lens-booboo-fix) and interactive architectural refactoring (/lens-booboo-refactor) with browser-based interviews.",
|
|
6
6
|
"repository": {
|