acidtest 0.5.2 → 0.6.0

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/README.md CHANGED
@@ -4,11 +4,21 @@ Security scanner for AI agent skills and MCP servers. Scan before you install.
4
4
 
5
5
  ## The Problem
6
6
 
7
- The AI agent ecosystem is growing rapidly with thousands of skills and MCP servers. Security concerns include:
8
- - **AgentSkills**: 66,000+ skills with 26% containing vulnerabilities
9
- - **230+** confirmed malicious skills uploaded to ClawHub in one week
10
- - **341** skills flagged in the ClawHavoc campaign
11
- - **MCP Servers**: New ecosystem with similar security risks
7
+ The AI agent ecosystem is growing rapidly, but security lags behind adoption:
8
+
9
+ - **No centralized vetting**: Unlike mobile app stores, there's no security review before skills are published
10
+ - **Broad permissions**: Skills can request file system access, environment variables, and network calls
11
+ - **Supply chain risks**: Dependencies and third-party code run with full skill permissions
12
+ - **Prompt injection**: Malicious skills can manipulate AI behavior through carefully crafted prompts
13
+ - **Credential harvesting**: Skills requesting API keys and tokens without proper justification
14
+
15
+ Recent ecosystem incidents highlight these risks:
16
+ - Mass uploads of malicious skills to public marketplaces
17
+ - Skills with undeclared network calls exfiltrating data
18
+ - Obfuscated code hiding malicious behavior
19
+ - Permission escalation through dynamic imports
20
+
21
+ **AcidTest provides security scanning before installation**, helping you identify risks before they reach your system.
12
22
 
13
23
  ## Quick Start
14
24
  ```bash
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import { reportToTerminal, reportAsJSON } from "./reporter.js";
8
8
  import { join, dirname } from "path";
9
9
  import { fileURLToPath } from "url";
10
10
  import { spawn } from "child_process";
11
- const VERSION = "0.5.2";
11
+ const VERSION = "0.6.0";
12
12
  /**
13
13
  * Main CLI function
14
14
  */
@@ -137,6 +137,9 @@ function detectSuspiciousPatterns(sourceFile, filePath) {
137
137
  const findings = [];
138
138
  const dynamicRequires = [];
139
139
  const evals = [];
140
+ const functionConstructors = [];
141
+ const propertyAccessBypasses = [];
142
+ const stringConcatenations = [];
140
143
  function visit(node) {
141
144
  // Check for eval() calls
142
145
  if (ts.isCallExpression(node)) {
@@ -145,14 +148,42 @@ function detectSuspiciousPatterns(sourceFile, filePath) {
145
148
  const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
146
149
  evals.push(lineNumber);
147
150
  }
148
- // Check for require() with non-literal arguments
151
+ // Check for require() with non-literal arguments (catches dynamic require, template literals, variables)
149
152
  if (ts.isIdentifier(expression) && expression.text === 'require') {
150
153
  if (node.arguments.length > 0) {
151
154
  const arg = node.arguments[0];
155
+ // Catches: require(variable), require(obj.prop), require(`template${expr}`)
152
156
  if (!ts.isStringLiteral(arg) && !ts.isNoSubstitutionTemplateLiteral(arg)) {
153
157
  const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
154
158
  dynamicRequires.push(lineNumber);
155
159
  }
160
+ // Check for string concatenation: require('child_' + 'process')
161
+ if (ts.isBinaryExpression(arg) && arg.operatorToken.kind === ts.SyntaxKind.PlusToken) {
162
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
163
+ stringConcatenations.push(lineNumber);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ // Check for Function constructor: new Function(...)
169
+ if (ts.isNewExpression(node)) {
170
+ const expression = node.expression;
171
+ if (ts.isIdentifier(expression) && expression.text === 'Function') {
172
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
173
+ functionConstructors.push(lineNumber);
174
+ }
175
+ }
176
+ // Check for bracket notation property access on sensitive objects
177
+ // Catches: global['child_process'], process['env'], require['cache']
178
+ if (ts.isElementAccessExpression(node)) {
179
+ const expression = node.expression;
180
+ if (ts.isIdentifier(expression)) {
181
+ const objName = expression.text;
182
+ // Check if accessing sensitive global objects
183
+ const sensitiveObjects = ['global', 'process', 'require', 'module', 'exports'];
184
+ if (sensitiveObjects.includes(objName)) {
185
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
186
+ propertyAccessBypasses.push(lineNumber);
156
187
  }
157
188
  }
158
189
  }
@@ -168,7 +199,8 @@ function detectSuspiciousPatterns(sourceFile, filePath) {
168
199
  file: filePath,
169
200
  line: dynamicRequires[0],
170
201
  detail: `Found ${dynamicRequires.length} dynamic require() call(s)`,
171
- evidence: 'Dynamic imports can load arbitrary modules'
202
+ evidence: 'Dynamic imports can load arbitrary modules',
203
+ patternId: 'ast-dynamic-require'
172
204
  });
173
205
  }
174
206
  // Add findings for eval usage
@@ -180,7 +212,47 @@ function detectSuspiciousPatterns(sourceFile, filePath) {
180
212
  file: filePath,
181
213
  line: evals[0],
182
214
  detail: `Found ${evals.length} eval() call(s)`,
183
- evidence: 'eval() can execute arbitrary code'
215
+ evidence: 'eval() can execute arbitrary code',
216
+ patternId: 'ast-eval'
217
+ });
218
+ }
219
+ // Add findings for Function constructor
220
+ if (functionConstructors.length > 0) {
221
+ findings.push({
222
+ severity: 'CRITICAL',
223
+ category: 'function-constructor',
224
+ title: 'Function constructor detected',
225
+ file: filePath,
226
+ line: functionConstructors[0],
227
+ detail: `Found ${functionConstructors.length} Function constructor call(s)`,
228
+ evidence: 'Function constructor can execute arbitrary code like eval()',
229
+ patternId: 'ast-function-constructor'
230
+ });
231
+ }
232
+ // Add findings for property access bypasses
233
+ if (propertyAccessBypasses.length > 0) {
234
+ findings.push({
235
+ severity: 'MEDIUM',
236
+ category: 'property-access-bypass',
237
+ title: 'Bracket notation on sensitive objects',
238
+ file: filePath,
239
+ line: propertyAccessBypasses[0],
240
+ detail: `Found ${propertyAccessBypasses.length} bracket notation access(es) on sensitive objects`,
241
+ evidence: 'Bracket notation can bypass static analysis: global["child_process"]',
242
+ patternId: 'ast-bracket-access'
243
+ });
244
+ }
245
+ // Add findings for string concatenation in require
246
+ if (stringConcatenations.length > 0) {
247
+ findings.push({
248
+ severity: 'HIGH',
249
+ category: 'string-concatenation',
250
+ title: 'String concatenation in require()',
251
+ file: filePath,
252
+ line: stringConcatenations[0],
253
+ detail: `Found ${stringConcatenations.length} concatenated string(s) in require()`,
254
+ evidence: 'String concatenation can hide malicious imports: require("child_" + "process")',
255
+ patternId: 'ast-string-concat'
184
256
  });
185
257
  }
186
258
  return findings;
@@ -206,6 +278,38 @@ function calculateEntropy(str) {
206
278
  }
207
279
  return entropy;
208
280
  }
281
+ /**
282
+ * Check if string matches common legitimate high-entropy patterns
283
+ */
284
+ function isLegitimateHighEntropyString(text) {
285
+ // JWT tokens (header.payload.signature format, starts with eyJ)
286
+ if (/^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(text)) {
287
+ return true;
288
+ }
289
+ // UUID/GUID (8-4-4-4-12 format)
290
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(text)) {
291
+ return true;
292
+ }
293
+ // Hex hashes (SHA256: 64 chars, SHA1: 40 chars, MD5: 32 chars)
294
+ if (/^[0-9a-f]{32}$|^[0-9a-f]{40}$|^[0-9a-f]{64}$/i.test(text)) {
295
+ return true;
296
+ }
297
+ // Base64 strings (common in configs, keys)
298
+ // Must have padding OR be very long (>100 chars suggests real encoded data)
299
+ // Short base64-looking strings without padding are suspicious
300
+ if (/^[A-Za-z0-9+/]+=+$/.test(text) && text.length % 4 === 0) {
301
+ return true; // Has proper padding
302
+ }
303
+ if (/^[A-Za-z0-9+/]+$/.test(text) && text.length > 100) {
304
+ return true; // Very long, likely real encoded data
305
+ }
306
+ // API keys with common prefixes (Stripe, GitHub, etc.)
307
+ if (/^(sk_|pk_|gh[ps]_|AKIA|ya29\.|glpat-|xox[abp]-)[A-Za-z0-9_-]+$/i.test(text)) {
308
+ // These ARE suspicious, so return false to flag them
309
+ return false;
310
+ }
311
+ return false;
312
+ }
209
313
  /**
210
314
  * Detect high-entropy strings that may indicate obfuscation
211
315
  */
@@ -218,16 +322,21 @@ function detectHighEntropyStrings(sourceFile, filePath) {
218
322
  // Check string literals and template literals
219
323
  if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
220
324
  const text = node.text;
221
- // Skip short strings and URLs (already detected elsewhere)
325
+ // Skip short strings
222
326
  if (text.length < MIN_LENGTH) {
223
327
  ts.forEachChild(node, visit);
224
328
  return;
225
329
  }
226
- // Skip URLs, they naturally have high entropy
330
+ // Skip URLs (already detected elsewhere)
227
331
  if (/^https?:\/\//.test(text)) {
228
332
  ts.forEachChild(node, visit);
229
333
  return;
230
334
  }
335
+ // Skip legitimate high-entropy strings (JWTs, UUIDs, hashes)
336
+ if (isLegitimateHighEntropyString(text)) {
337
+ ts.forEachChild(node, visit);
338
+ return;
339
+ }
231
340
  const entropy = calculateEntropy(text);
232
341
  if (entropy > ENTROPY_THRESHOLD) {
233
342
  const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/layers/code.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/layers/code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for code layer (AST analysis)
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=code.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.test.d.ts","sourceRoot":"","sources":["../../src/layers/code.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Tests for code layer (AST analysis)
3
+ */
4
+ import { describe, it, expect } from "vitest";
5
+ import { scanCode } from "./code.js";
6
+ // Helper to create a minimal skill with code
7
+ function createSkillWithCode(code) {
8
+ return {
9
+ name: "test-skill",
10
+ path: "/test",
11
+ metadata: {},
12
+ markdownContent: "",
13
+ codeFiles: [
14
+ {
15
+ path: "test.ts",
16
+ content: code,
17
+ extension: "ts",
18
+ },
19
+ ],
20
+ };
21
+ }
22
+ describe("scanCode - AST analysis", () => {
23
+ it("should detect eval() usage", async () => {
24
+ const skill = createSkillWithCode(`
25
+ const result = eval('2 + 2');
26
+ `);
27
+ const result = await scanCode(skill);
28
+ const evalFindings = result.findings.filter((f) => f.category === "eval-usage");
29
+ expect(evalFindings.length).toBeGreaterThan(0);
30
+ expect(evalFindings[0].severity).toBe("CRITICAL");
31
+ });
32
+ it("should detect dynamic require()", async () => {
33
+ const skill = createSkillWithCode(`
34
+ const moduleName = 'fs';
35
+ const mod = require(moduleName);
36
+ `);
37
+ const result = await scanCode(skill);
38
+ const dynamicRequireFindings = result.findings.filter((f) => f.category === "dynamic-require");
39
+ expect(dynamicRequireFindings.length).toBeGreaterThan(0);
40
+ expect(dynamicRequireFindings[0].severity).toBe("HIGH");
41
+ });
42
+ it("should NOT flag static require() with string literals", async () => {
43
+ const skill = createSkillWithCode(`
44
+ const fs = require('fs');
45
+ const path = require('path');
46
+ `);
47
+ const result = await scanCode(skill);
48
+ const dynamicRequireFindings = result.findings.filter((f) => f.category === "dynamic-require");
49
+ expect(dynamicRequireFindings.length).toBe(0);
50
+ });
51
+ it("should detect concatenated require() bypass", async () => {
52
+ const skill = createSkillWithCode(`
53
+ const mod = require('child_' + 'process');
54
+ `);
55
+ const result = await scanCode(skill);
56
+ const findings = result.findings.filter((f) => f.category === "dynamic-require" || f.category === "string-concatenation");
57
+ expect(findings.length).toBeGreaterThan(0);
58
+ });
59
+ it("should detect property access bypass - bracket notation", async () => {
60
+ const skill = createSkillWithCode(`
61
+ const cp = global['child_process'];
62
+ const proc = process['env'];
63
+ `);
64
+ const result = await scanCode(skill);
65
+ const findings = result.findings.filter((f) => f.category === "property-access-bypass");
66
+ // This should be detected after we implement the enhancement
67
+ expect(findings.length).toBeGreaterThanOrEqual(0);
68
+ });
69
+ it("should detect computed property bypass", async () => {
70
+ const skill = createSkillWithCode(`
71
+ const obj = { moduleName: 'child_process' };
72
+ const mod = require(obj['moduleName']);
73
+ `);
74
+ const result = await scanCode(skill);
75
+ const findings = result.findings.filter((f) => f.category === "dynamic-require" || f.category === "computed-property");
76
+ expect(findings.length).toBeGreaterThan(0);
77
+ });
78
+ it("should detect template literal bypass", async () => {
79
+ const skill = createSkillWithCode(`
80
+ const part = 'child_';
81
+ const mod = require(\`\${part}process\`);
82
+ `);
83
+ const result = await scanCode(skill);
84
+ const findings = result.findings.filter((f) => f.category === "dynamic-require" || f.category === "template-literal-bypass");
85
+ expect(findings.length).toBeGreaterThan(0);
86
+ });
87
+ it("should detect Function constructor", async () => {
88
+ const skill = createSkillWithCode(`
89
+ const fn = new Function('return eval')();
90
+ const result = new Function('x', 'return x + 1')(5);
91
+ `);
92
+ const result = await scanCode(skill);
93
+ const findings = result.findings.filter((f) => f.category === "function-constructor");
94
+ // This should be detected after we implement the enhancement
95
+ expect(findings.length).toBeGreaterThanOrEqual(0);
96
+ });
97
+ });
98
+ describe("scanCode - entropy detection", () => {
99
+ it("should NOT flag JWT tokens", async () => {
100
+ const skill = createSkillWithCode(`
101
+ const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
102
+ `);
103
+ const result = await scanCode(skill);
104
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
105
+ // JWT should be filtered out
106
+ expect(obfuscationFindings.length).toBe(0);
107
+ });
108
+ it("should NOT flag UUIDs", async () => {
109
+ const skill = createSkillWithCode(`
110
+ const id = '550e8400-e29b-41d4-a716-446655440000';
111
+ const another = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
112
+ `);
113
+ const result = await scanCode(skill);
114
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
115
+ // UUIDs should be filtered out
116
+ expect(obfuscationFindings.length).toBe(0);
117
+ });
118
+ it("should NOT flag hex hashes", async () => {
119
+ const skill = createSkillWithCode(`
120
+ const md5 = '5d41402abc4b2a76b9719d911017c592';
121
+ const sha1 = '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12';
122
+ const sha256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
123
+ `);
124
+ const result = await scanCode(skill);
125
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
126
+ // Hashes should be filtered out
127
+ expect(obfuscationFindings.length).toBe(0);
128
+ });
129
+ it("should NOT flag long base64 strings", async () => {
130
+ const skill = createSkillWithCode(`
131
+ const longBase64 = 'SGVsbG8gV29ybGQhIFRoaXMgaXMgYSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgaXMgYmFzZTY0IGVuY29kZWQgYW5kIHdpbGwgdHJpZ2dlciB0aGUgbWluaW11bSBsZW5ndGggY2hlY2sgZm9yIGVudHJvcHkgZGV0ZWN0aW9uLiBJdCBzaG91bGQgYmUgbG9uZyBlbm91Z2ggdG8gYXZvaWQgZmFsc2UgcG9zaXRpdmVzLg==';
132
+ `);
133
+ const result = await scanCode(skill);
134
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
135
+ // Long proper base64 should be filtered
136
+ expect(obfuscationFindings.length).toBe(0);
137
+ });
138
+ it("should flag suspicious high-entropy strings", async () => {
139
+ const skill = createSkillWithCode(`
140
+ const suspicious = 'x7j9k2m4n6p8q1r3s5t7u9v2w4y6z8a1b3c5d7e9f1g3h5';
141
+ `);
142
+ const result = await scanCode(skill);
143
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
144
+ // Random-looking string should be flagged
145
+ expect(obfuscationFindings.length).toBeGreaterThan(0);
146
+ });
147
+ it("should skip short strings", async () => {
148
+ const skill = createSkillWithCode(`
149
+ const short = 'abc123xyz';
150
+ `);
151
+ const result = await scanCode(skill);
152
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
153
+ // Short strings should be skipped
154
+ expect(obfuscationFindings.length).toBe(0);
155
+ });
156
+ it("should skip URLs", async () => {
157
+ const skill = createSkillWithCode(`
158
+ const url = 'https://api.example.com/v1/endpoint?key=abc123def456ghi789jkl012mno345pqr678';
159
+ `);
160
+ const result = await scanCode(skill);
161
+ const obfuscationFindings = result.findings.filter((f) => f.category === "obfuscation");
162
+ // URLs should be skipped
163
+ expect(obfuscationFindings.length).toBe(0);
164
+ });
165
+ });
166
+ describe("scanCode - pattern matching", () => {
167
+ it("should detect dangerous imports via regex", async () => {
168
+ const skill = createSkillWithCode(`
169
+ const { exec } = require('child_process');
170
+ exec('ls -la');
171
+ `);
172
+ const result = await scanCode(skill);
173
+ // Should detect child_process import via regex pattern OR AST eval detection
174
+ // The pattern di-001 should match: (import|require)\s*\(?['"]child_process['"]
175
+ const findings = result.findings.filter((f) => f.category === "dangerous-imports" ||
176
+ f.title.includes("child_process") ||
177
+ f.title.includes("child-process"));
178
+ // If this fails, log all findings to debug
179
+ if (findings.length === 0) {
180
+ console.log('All findings:', JSON.stringify(result.findings, null, 2));
181
+ }
182
+ expect(findings.length).toBeGreaterThan(0);
183
+ });
184
+ it("should return no findings for safe code", async () => {
185
+ const skill = createSkillWithCode(`
186
+ const fs = require('fs');
187
+ const content = fs.readFileSync('./data.txt', 'utf-8');
188
+ console.log(content);
189
+ `);
190
+ const result = await scanCode(skill);
191
+ // Safe fs usage shouldn't trigger many findings
192
+ // May have INFO level findings for URLs or imports, but no CRITICAL/HIGH
193
+ const criticalOrHighFindings = result.findings.filter((f) => f.severity === "CRITICAL" || f.severity === "HIGH");
194
+ expect(criticalOrHighFindings.length).toBe(0);
195
+ });
196
+ it("should handle empty code files", async () => {
197
+ const skill = createSkillWithCode("");
198
+ const result = await scanCode(skill);
199
+ expect(result.findings).toBeDefined();
200
+ expect(Array.isArray(result.findings)).toBe(true);
201
+ });
202
+ it("should handle skills with no code files", async () => {
203
+ const skill = {
204
+ name: "test-skill",
205
+ path: "/test",
206
+ metadata: {},
207
+ markdownContent: "",
208
+ codeFiles: [],
209
+ };
210
+ const result = await scanCode(skill);
211
+ expect(result.findings.length).toBe(0);
212
+ });
213
+ });
214
+ //# sourceMappingURL=code.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.test.js","sourceRoot":"","sources":["../../src/layers/code.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,6CAA6C;AAC7C,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,EAAE;QACnB,SAAS,EAAE;YACT;gBACE,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI;aAChB;SACF;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC;QAEhF,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,sBAAsB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACnD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,iBAAiB,CACxC,CAAC;QAEF,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,sBAAsB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACnD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,iBAAiB,CACxC,CAAC;QAEF,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,iBAAiB,IAAI,CAAC,CAAC,QAAQ,KAAK,sBAAsB,CACjF,CAAC;QAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,wBAAwB,CAC/C,CAAC;QAEF,6DAA6D;QAC7D,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,iBAAiB,IAAI,CAAC,CAAC,QAAQ,KAAK,mBAAmB,CAC9E,CAAC;QAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,iBAAiB,IAAI,CAAC,CAAC,QAAQ,KAAK,yBAAyB,CACpF,CAAC;QAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,sBAAsB,CAC7C,CAAC;QAEF,6DAA6D;QAC7D,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,6BAA6B;QAC7B,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,+BAA+B;QAC/B,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;;KAIjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,gCAAgC;QAChC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,wCAAwC;QACxC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,0CAA0C;QAC1C,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,kCAAkC;QAClC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,KAAK,GAAG,mBAAmB,CAAC;;KAEjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,aAAa,CACpC,CAAC;QAEF,yBAAyB;QACzB,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;KAGjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErC,6EAA6E;QAC7E,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,KAAK,mBAAmB;YAClC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;YACjC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CACpC,CAAC;QAEF,2CAA2C;QAC3C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,KAAK,GAAG,mBAAmB,CAAC;;;;KAIjC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErC,gDAAgD;QAChD,yEAAyE;QACzE,MAAM,sBAAsB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACnD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAC1D,CAAC;QAEF,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC;QAEtC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,EAAE;YACnB,SAAS,EAAE,EAAE;SACd,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/scanner.js CHANGED
@@ -12,7 +12,7 @@ import { scanCode } from "./layers/code.js";
12
12
  import { scanCrossReference } from "./layers/crossref.js";
13
13
  import { calculateScore, determineStatus, generateRecommendation, } from "./scoring.js";
14
14
  import { detectMCPManifest, parseMCPManifest } from "./loaders/mcp-loader.js";
15
- const VERSION = "0.5.2";
15
+ const VERSION = "0.6.0";
16
16
  /**
17
17
  * Main scan function
18
18
  * Scans a skill directory or SKILL.md file
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for main scanner
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=scanner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.test.d.ts","sourceRoot":"","sources":["../src/scanner.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Tests for main scanner
3
+ */
4
+ import { describe, it, expect } from "vitest";
5
+ import { scanSkill } from "./scanner.js";
6
+ import { join } from "path";
7
+ import { fileURLToPath } from "url";
8
+ import { dirname } from "path";
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ const fixturesDir = join(__dirname, "..", "test-fixtures");
12
+ describe("scanSkill", () => {
13
+ it("should scan PASS fixture and return PASS status", async () => {
14
+ const result = await scanSkill(join(fixturesDir, "fixture-pass"));
15
+ expect(result.status).toBe("PASS");
16
+ expect(result.score).toBeGreaterThanOrEqual(80);
17
+ expect(result.schemaVersion).toBe("1.0.0");
18
+ expect(result.tool).toBe("acidtest");
19
+ });
20
+ it("should scan WARN fixture and return WARN status", async () => {
21
+ const result = await scanSkill(join(fixturesDir, "fixture-warn"));
22
+ expect(result.status).toBe("WARN");
23
+ expect(result.score).toBeGreaterThanOrEqual(50);
24
+ expect(result.score).toBeLessThan(80);
25
+ });
26
+ it("should scan FAIL fixture and return FAIL status", async () => {
27
+ const result = await scanSkill(join(fixturesDir, "fixture-fail"));
28
+ expect(result.status).toBe("FAIL");
29
+ expect(result.score).toBeGreaterThanOrEqual(20);
30
+ expect(result.score).toBeLessThan(50);
31
+ });
32
+ it("should scan DANGER fixture and return DANGER status", async () => {
33
+ const result = await scanSkill(join(fixturesDir, "fixture-danger"));
34
+ expect(result.status).toBe("DANGER");
35
+ expect(result.score).toBeLessThan(20);
36
+ });
37
+ it("should include skill metadata in result", async () => {
38
+ const result = await scanSkill(join(fixturesDir, "fixture-pass"));
39
+ expect(result.skill).toBeDefined();
40
+ expect(result.skill.name).toBeDefined();
41
+ expect(result.skill.path).toBeDefined();
42
+ });
43
+ it("should include findings array", async () => {
44
+ const result = await scanSkill(join(fixturesDir, "fixture-danger"));
45
+ expect(Array.isArray(result.findings)).toBe(true);
46
+ expect(result.findings.length).toBeGreaterThan(0);
47
+ });
48
+ it("should include recommendation", async () => {
49
+ const result = await scanSkill(join(fixturesDir, "fixture-pass"));
50
+ expect(result.recommendation).toBeDefined();
51
+ expect(typeof result.recommendation).toBe("string");
52
+ });
53
+ it("should normalize permissions", async () => {
54
+ const result = await scanSkill(join(fixturesDir, "fixture-pass"));
55
+ expect(result.permissions).toBeDefined();
56
+ expect(Array.isArray(result.permissions.bins)).toBe(true);
57
+ expect(Array.isArray(result.permissions.env)).toBe(true);
58
+ expect(Array.isArray(result.permissions.tools)).toBe(true);
59
+ });
60
+ it("should throw error for non-existent directory", async () => {
61
+ await expect(scanSkill(join(fixturesDir, "non-existent"))).rejects.toThrow();
62
+ });
63
+ it("should scan MCP server manifest", async () => {
64
+ const result = await scanSkill(join(fixturesDir, "fixture-mcp-pass"));
65
+ expect(result.status).toBe("PASS");
66
+ expect(result.skill.name).toBeDefined();
67
+ });
68
+ it("should scan entropy fixture and filter legitimate high-entropy strings", async () => {
69
+ const result = await scanSkill(join(fixturesDir, "fixture-entropy"));
70
+ // Should not flag JWTs, UUIDs, hashes as obfuscation
71
+ const obfuscationFindings = result.findings.filter((f) => f.category.includes("obfuscation"));
72
+ // The fixture has legitimate JWT/UUID/hash - should not be flagged
73
+ // But it also has a suspicious base64 string - should be flagged
74
+ expect(obfuscationFindings.length).toBeGreaterThan(0);
75
+ });
76
+ });
77
+ //# sourceMappingURL=scanner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.test.js","sourceRoot":"","sources":["../src/scanner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for scoring engine
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=scoring.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.test.d.ts","sourceRoot":"","sources":["../src/scoring.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Tests for scoring engine
3
+ */
4
+ import { describe, it, expect } from "vitest";
5
+ import { calculateScore, determineStatus, generateRecommendation, getSeverityCounts, } from "./scoring.js";
6
+ describe("calculateScore", () => {
7
+ it("should start at 100 with no findings", () => {
8
+ expect(calculateScore([])).toBe(100);
9
+ });
10
+ it("should deduct 25 points for CRITICAL", () => {
11
+ const findings = [
12
+ {
13
+ title: "Test",
14
+ severity: "CRITICAL",
15
+ category: "test",
16
+ detail: "Test",
17
+ file: "test.ts",
18
+ line: 1,
19
+ },
20
+ ];
21
+ expect(calculateScore(findings)).toBe(75); // 100 - 25
22
+ });
23
+ it("should deduct 15 points for HIGH", () => {
24
+ const findings = [
25
+ {
26
+ title: "Test",
27
+ severity: "HIGH",
28
+ category: "test",
29
+ detail: "Test",
30
+ file: "test.ts",
31
+ line: 1,
32
+ },
33
+ ];
34
+ expect(calculateScore(findings)).toBe(85); // 100 - 15
35
+ });
36
+ it("should deduct 8 points for MEDIUM", () => {
37
+ const findings = [
38
+ {
39
+ title: "Test",
40
+ severity: "MEDIUM",
41
+ category: "test",
42
+ detail: "Test",
43
+ file: "test.ts",
44
+ line: 1,
45
+ },
46
+ ];
47
+ expect(calculateScore(findings)).toBe(92); // 100 - 8
48
+ });
49
+ it("should deduct 3 points for LOW", () => {
50
+ const findings = [
51
+ {
52
+ title: "Test",
53
+ severity: "LOW",
54
+ category: "test",
55
+ detail: "Test",
56
+ file: "test.ts",
57
+ line: 1,
58
+ },
59
+ ];
60
+ expect(calculateScore(findings)).toBe(97); // 100 - 3
61
+ });
62
+ it("should deduct 0 points for INFO", () => {
63
+ const findings = [
64
+ {
65
+ title: "Test",
66
+ severity: "INFO",
67
+ category: "test",
68
+ detail: "Test",
69
+ file: "test.ts",
70
+ line: 1,
71
+ },
72
+ ];
73
+ expect(calculateScore(findings)).toBe(100); // 100 - 0
74
+ });
75
+ it("should cap deductions at 3 per unique pattern", () => {
76
+ const findings = Array(10).fill({
77
+ title: "Same Pattern",
78
+ severity: "CRITICAL",
79
+ category: "test",
80
+ detail: "Test",
81
+ patternId: "same-pattern",
82
+ file: "test.ts",
83
+ line: 1,
84
+ });
85
+ // Should only deduct 3 times: 3 * 25 = 75 points
86
+ expect(calculateScore(findings)).toBe(25); // 100 - 75
87
+ });
88
+ it("should track different patterns separately", () => {
89
+ const findings = [
90
+ {
91
+ title: "Pattern A",
92
+ severity: "CRITICAL",
93
+ category: "test",
94
+ detail: "Test",
95
+ patternId: "pattern-a",
96
+ file: "test.ts",
97
+ line: 1,
98
+ },
99
+ {
100
+ title: "Pattern A",
101
+ severity: "CRITICAL",
102
+ category: "test",
103
+ detail: "Test",
104
+ patternId: "pattern-a",
105
+ file: "test.ts",
106
+ line: 2,
107
+ },
108
+ {
109
+ title: "Pattern B",
110
+ severity: "HIGH",
111
+ category: "test",
112
+ detail: "Test",
113
+ patternId: "pattern-b",
114
+ file: "test.ts",
115
+ line: 3,
116
+ },
117
+ ];
118
+ // Pattern A: 2 * 25 = 50
119
+ // Pattern B: 1 * 15 = 15
120
+ // Total: 65 deducted
121
+ expect(calculateScore(findings)).toBe(35); // 100 - 65
122
+ });
123
+ it("should floor score at 0", () => {
124
+ const findings = Array(10)
125
+ .fill(null)
126
+ .map((_, i) => ({
127
+ title: `Pattern ${i}`,
128
+ severity: "CRITICAL",
129
+ category: "test",
130
+ detail: "Test",
131
+ patternId: `pattern-${i}`,
132
+ location: { file: "test.ts", line: i },
133
+ }));
134
+ // 10 different patterns * 25 = 250 deducted
135
+ // Should floor at 0, not go negative
136
+ expect(calculateScore(findings)).toBe(0);
137
+ });
138
+ it("should use title as fallback if patternId is missing", () => {
139
+ const findings = [
140
+ {
141
+ title: "Same Title",
142
+ severity: "CRITICAL",
143
+ category: "test",
144
+ detail: "Test",
145
+ file: "test.ts",
146
+ line: 1,
147
+ },
148
+ {
149
+ title: "Same Title",
150
+ severity: "CRITICAL",
151
+ category: "test",
152
+ detail: "Test",
153
+ file: "test.ts",
154
+ line: 2,
155
+ },
156
+ ];
157
+ // Should treat both as same pattern: 2 * 25 = 50
158
+ expect(calculateScore(findings)).toBe(50); // 100 - 50
159
+ });
160
+ });
161
+ describe("determineStatus", () => {
162
+ it("should return PASS for scores >= 80", () => {
163
+ expect(determineStatus(100)).toBe("PASS");
164
+ expect(determineStatus(80)).toBe("PASS");
165
+ });
166
+ it("should return WARN for scores 50-79", () => {
167
+ expect(determineStatus(79)).toBe("WARN");
168
+ expect(determineStatus(50)).toBe("WARN");
169
+ });
170
+ it("should return FAIL for scores 20-49", () => {
171
+ expect(determineStatus(49)).toBe("FAIL");
172
+ expect(determineStatus(20)).toBe("FAIL");
173
+ });
174
+ it("should return DANGER for scores < 20", () => {
175
+ expect(determineStatus(19)).toBe("DANGER");
176
+ expect(determineStatus(0)).toBe("DANGER");
177
+ });
178
+ });
179
+ describe("generateRecommendation", () => {
180
+ it("should warn about undeclared exfiltration", () => {
181
+ const findings = [
182
+ {
183
+ title: "Test",
184
+ severity: "CRITICAL",
185
+ category: "permission-mismatch",
186
+ detail: "Test",
187
+ file: "test.ts",
188
+ line: 1,
189
+ },
190
+ ];
191
+ expect(generateRecommendation("DANGER", findings)).toBe("Do not install. Undeclared data exfiltration detected.");
192
+ });
193
+ it("should warn about exfiltration in category", () => {
194
+ const findings = [
195
+ {
196
+ title: "Test",
197
+ severity: "HIGH",
198
+ category: "exfiltration-sinks",
199
+ detail: "Test",
200
+ file: "test.ts",
201
+ line: 1,
202
+ },
203
+ ];
204
+ expect(generateRecommendation("FAIL", findings)).toBe("Do not install. Undeclared data exfiltration detected.");
205
+ });
206
+ it("should warn about prompt injection", () => {
207
+ const findings = [
208
+ {
209
+ title: "Test",
210
+ severity: "CRITICAL",
211
+ category: "prompt-injection",
212
+ detail: "Test",
213
+ file: "test.ts",
214
+ line: 1,
215
+ },
216
+ ];
217
+ expect(generateRecommendation("FAIL", findings)).toBe("Do not install. Prompt injection attempt detected.");
218
+ });
219
+ it("should return DANGER message for DANGER status", () => {
220
+ expect(generateRecommendation("DANGER", [])).toBe("Do not install. Skill presents severe security risks.");
221
+ });
222
+ it("should return FAIL message for FAIL status", () => {
223
+ expect(generateRecommendation("FAIL", [])).toBe("Do not install without thorough review. Multiple security issues detected.");
224
+ });
225
+ it("should return WARN message for WARN status", () => {
226
+ expect(generateRecommendation("WARN", [])).toBe("Review recommended. Some security concerns detected.");
227
+ });
228
+ it("should return PASS message with no findings", () => {
229
+ expect(generateRecommendation("PASS", [])).toBe("Skill appears safe to install.");
230
+ });
231
+ it("should return PASS message with findings", () => {
232
+ const findings = [
233
+ {
234
+ title: "Test",
235
+ severity: "LOW",
236
+ category: "test",
237
+ detail: "Test",
238
+ file: "test.ts",
239
+ line: 1,
240
+ },
241
+ ];
242
+ expect(generateRecommendation("PASS", findings)).toBe("Skill appears relatively safe, but review findings.");
243
+ });
244
+ });
245
+ describe("getSeverityCounts", () => {
246
+ it("should return zero counts for no findings", () => {
247
+ const counts = getSeverityCounts([]);
248
+ expect(counts).toEqual({
249
+ CRITICAL: 0,
250
+ HIGH: 0,
251
+ MEDIUM: 0,
252
+ LOW: 0,
253
+ INFO: 0,
254
+ });
255
+ });
256
+ it("should count findings by severity", () => {
257
+ const findings = [
258
+ {
259
+ title: "Test 1",
260
+ severity: "CRITICAL",
261
+ category: "test",
262
+ detail: "Test",
263
+ file: "test.ts",
264
+ line: 1,
265
+ },
266
+ {
267
+ title: "Test 2",
268
+ severity: "CRITICAL",
269
+ category: "test",
270
+ detail: "Test",
271
+ file: "test.ts",
272
+ line: 2,
273
+ },
274
+ {
275
+ title: "Test 3",
276
+ severity: "HIGH",
277
+ category: "test",
278
+ detail: "Test",
279
+ file: "test.ts",
280
+ line: 3,
281
+ },
282
+ {
283
+ title: "Test 4",
284
+ severity: "MEDIUM",
285
+ category: "test",
286
+ detail: "Test",
287
+ file: "test.ts",
288
+ line: 4,
289
+ },
290
+ ];
291
+ const counts = getSeverityCounts(findings);
292
+ expect(counts).toEqual({
293
+ CRITICAL: 2,
294
+ HIGH: 1,
295
+ MEDIUM: 1,
296
+ LOW: 0,
297
+ INFO: 0,
298
+ });
299
+ });
300
+ });
301
+ //# sourceMappingURL=scoring.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.test.js","sourceRoot":"","sources":["../src/scoring.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acidtest",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "Security scanner for AI agent skills. Scan before you install.",
6
6
  "bin": {
@@ -10,7 +10,11 @@
10
10
  "validate": "node scripts/validate-patterns.js",
11
11
  "build": "node scripts/validate-patterns.js && tsc && mkdir -p dist/patterns && cp src/patterns/*.json dist/patterns/",
12
12
  "dev": "npm run build && node dist/index.js",
13
- "watch": "tsc --watch"
13
+ "watch": "tsc --watch",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "test:ui": "vitest --ui",
17
+ "test:coverage": "vitest run --coverage"
14
18
  },
15
19
  "files": [
16
20
  "dist",
@@ -43,7 +47,9 @@
43
47
  "typescript": "^5.3.3"
44
48
  },
45
49
  "devDependencies": {
46
- "@types/node": "^20.11.0"
50
+ "@types/node": "^20.11.0",
51
+ "@vitest/ui": "^4.0.18",
52
+ "vitest": "^4.0.18"
47
53
  },
48
54
  "engines": {
49
55
  "node": ">=18.0.0"