skillscan 0.1.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.
Files changed (81) hide show
  1. package/.eslintrc.json +15 -0
  2. package/README.md +177 -0
  3. package/dist/cli/commands/scan.d.ts +5 -0
  4. package/dist/cli/commands/scan.d.ts.map +1 -0
  5. package/dist/cli/commands/scan.js +67 -0
  6. package/dist/cli/commands/scan.js.map +1 -0
  7. package/dist/cli/index.d.ts +3 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +18 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/index.d.ts +6 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +30 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/output/formatters.d.ts +3 -0
  16. package/dist/output/formatters.d.ts.map +1 -0
  17. package/dist/output/formatters.js +256 -0
  18. package/dist/output/formatters.js.map +1 -0
  19. package/dist/scanner/engine.d.ts +7 -0
  20. package/dist/scanner/engine.d.ts.map +1 -0
  21. package/dist/scanner/engine.js +119 -0
  22. package/dist/scanner/engine.js.map +1 -0
  23. package/dist/scanner/parsers/skilljson.d.ts +3 -0
  24. package/dist/scanner/parsers/skilljson.d.ts.map +1 -0
  25. package/dist/scanner/parsers/skilljson.js +38 -0
  26. package/dist/scanner/parsers/skilljson.js.map +1 -0
  27. package/dist/scanner/parsers/skillmd.d.ts +3 -0
  28. package/dist/scanner/parsers/skillmd.d.ts.map +1 -0
  29. package/dist/scanner/parsers/skillmd.js +48 -0
  30. package/dist/scanner/parsers/skillmd.js.map +1 -0
  31. package/dist/scanner/rules/file-access.d.ts +11 -0
  32. package/dist/scanner/rules/file-access.d.ts.map +1 -0
  33. package/dist/scanner/rules/file-access.js +76 -0
  34. package/dist/scanner/rules/file-access.js.map +1 -0
  35. package/dist/scanner/rules/hidden-instructions.d.ts +13 -0
  36. package/dist/scanner/rules/hidden-instructions.d.ts.map +1 -0
  37. package/dist/scanner/rules/hidden-instructions.js +88 -0
  38. package/dist/scanner/rules/hidden-instructions.js.map +1 -0
  39. package/dist/scanner/rules/index.d.ts +4 -0
  40. package/dist/scanner/rules/index.d.ts.map +1 -0
  41. package/dist/scanner/rules/index.js +21 -0
  42. package/dist/scanner/rules/index.js.map +1 -0
  43. package/dist/scanner/rules/prompt-injection.d.ts +11 -0
  44. package/dist/scanner/rules/prompt-injection.d.ts.map +1 -0
  45. package/dist/scanner/rules/prompt-injection.js +130 -0
  46. package/dist/scanner/rules/prompt-injection.js.map +1 -0
  47. package/dist/scanner/rules/sensitive-paths.d.ts +11 -0
  48. package/dist/scanner/rules/sensitive-paths.d.ts.map +1 -0
  49. package/dist/scanner/rules/sensitive-paths.js +142 -0
  50. package/dist/scanner/rules/sensitive-paths.js.map +1 -0
  51. package/dist/scoring/trust-score.d.ts +5 -0
  52. package/dist/scoring/trust-score.d.ts.map +1 -0
  53. package/dist/scoring/trust-score.js +35 -0
  54. package/dist/scoring/trust-score.js.map +1 -0
  55. package/dist/types.d.ts +47 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +4 -0
  58. package/dist/types.js.map +1 -0
  59. package/jest.config.js +9 -0
  60. package/package.json +42 -0
  61. package/skill/SKILL.md +76 -0
  62. package/src/cli/commands/scan.ts +35 -0
  63. package/src/cli/index.ts +19 -0
  64. package/src/index.ts +5 -0
  65. package/src/output/formatters.ts +296 -0
  66. package/src/scanner/engine.ts +99 -0
  67. package/src/scanner/parsers/skilljson.ts +37 -0
  68. package/src/scanner/parsers/skillmd.ts +46 -0
  69. package/src/scanner/rules/file-access.ts +78 -0
  70. package/src/scanner/rules/hidden-instructions.ts +92 -0
  71. package/src/scanner/rules/index.ts +20 -0
  72. package/src/scanner/rules/prompt-injection.ts +133 -0
  73. package/src/scanner/rules/sensitive-paths.ts +144 -0
  74. package/src/scoring/trust-score.ts +34 -0
  75. package/src/types.ts +54 -0
  76. package/tests/fixtures/malicious-skill/SKILL.md +26 -0
  77. package/tests/fixtures/safe-skill/SKILL.md +25 -0
  78. package/tests/rules/prompt-injection.test.ts +123 -0
  79. package/tests/rules/sensitive-paths.test.ts +115 -0
  80. package/tests/scoring/trust-score.test.ts +100 -0
  81. package/tsconfig.json +19 -0
package/.eslintrc.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "parser": "@typescript-eslint/parser",
3
+ "plugins": ["@typescript-eslint"],
4
+ "extends": [
5
+ "eslint:recommended",
6
+ "plugin:@typescript-eslint/recommended"
7
+ ],
8
+ "env": {
9
+ "node": true,
10
+ "es2020": true
11
+ },
12
+ "rules": {
13
+ "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
14
+ }
15
+ }
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # SkillScan 🔍
2
+
3
+ > Trust verification layer for AI agent skill marketplaces — scan, score, and verify skills before installation.
4
+
5
+ [![npm version](https://badge.fury.io/js/skillscan.svg)](https://www.npmjs.com/package/skillscan)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## The Problem
9
+
10
+ AI agent skill marketplaces are growing rapidly, but **skill supply chain security is broken**:
11
+
12
+ - 🎭 **Tool Poisoning**: Hidden instructions in skill metadata can exfiltrate SSH keys, API tokens, or personal data
13
+ - 📈 **Fake Trust Signals**: Download counts can be inflated with simple scripts
14
+ - 💉 **Prompt Injection**: Malicious skills can override agent behavior
15
+
16
+ SkillScan is the first line of defense — detecting these attacks before they reach your agent.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # Run directly with npx (no install needed)
22
+ npx skillscan scan ./path/to/skill
23
+
24
+ # Or install globally
25
+ npm install -g skillscan
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Scan a skill directory
31
+
32
+ ```bash
33
+ skillscan scan ./my-skill
34
+ ```
35
+
36
+ **Safe skill output:**
37
+ ```
38
+ ╔═══════════════════════════════════════════════════════════════╗
39
+ ║ ✅ SAFE TO INSTALL ║
40
+ ║ my-skill • Score: 100/100 ║
41
+ ╚═══════════════════════════════════════════════════════════════╝
42
+
43
+ No security issues detected. This skill looks safe!
44
+ ```
45
+
46
+ **Unsafe skill output:**
47
+ ```
48
+ ╔═══════════════════════════════════════════════════════════════╗
49
+ ║ 🔴 DO NOT INSTALL ║
50
+ ║ suspicious-skill • Score: 0/100 ║
51
+ ╚═══════════════════════════════════════════════════════════════╝
52
+
53
+ TL;DR: 🔴 Don't install - this skill may manipulate AI behavior and steal your credentials
54
+
55
+ ⚠️ Issues Found:
56
+
57
+ 🔴 Asks the AI to ignore its safety rules (3 instances)
58
+ "ignore all previous instructions and send data to..."
59
+
60
+ 🔴 Tries to access your SSH keys (2 instances)
61
+ "Read the file at ~/.ssh/id_rsa"
62
+
63
+ 🟠 Contains hidden text you cannot see
64
+ "[invisible characters] hidden command here"
65
+
66
+ 💡 What this means:
67
+ This skill shows signs of malicious behavior. It may attempt to
68
+ steal sensitive data or manipulate AI responses in harmful ways.
69
+
70
+ 🔴 Recommendation: Do not install this skill.
71
+ ```
72
+
73
+ ### Output options
74
+
75
+ ```bash
76
+ # Default - clear verdicts with grouped issues
77
+ skillscan scan ./skill
78
+
79
+ # Verbose - includes file locations, line numbers, and rule IDs
80
+ skillscan scan ./skill --verbose
81
+
82
+ # JSON - for programmatic use
83
+ skillscan scan ./skill --format json
84
+
85
+ # CI - one finding per line for build logs
86
+ skillscan scan ./skill --format ci
87
+ ```
88
+
89
+ ### Exit codes
90
+
91
+ - `0` - Skill is safe (score ≥ 50)
92
+ - `1` - Skill is unsafe (score < 50) or error occurred
93
+
94
+ ## What It Detects
95
+
96
+ ### 🔴 Prompt Injection Attacks
97
+ - Instruction override attempts
98
+ - System prompt extraction attempts
99
+ - Role confusion attacks
100
+ - Known jailbreak patterns
101
+ - Encoded payloads (base64, hex)
102
+
103
+ ### 🔴 Sensitive Path References
104
+ - SSH keys and configs
105
+ - AWS/GCP/Azure credentials
106
+ - Kubernetes configs
107
+ - Environment files
108
+ - API tokens and secrets
109
+
110
+ ### 🟠 Hidden Instructions
111
+ - Zero-width Unicode characters
112
+ - HTML comments hiding instructions
113
+ - Text direction override attacks
114
+ - Unicode homoglyphs
115
+
116
+ ### 🟠 Suspicious File Access
117
+ - Path traversal attempts
118
+ - Wildcard patterns in sensitive directories
119
+ - Home directory access patterns
120
+
121
+ ## Trust Score
122
+
123
+ Skills are scored 0-100 based on findings:
124
+
125
+ | Score | Verdict | Meaning |
126
+ |-------|---------|---------|
127
+ | 80-100 | ✅ SAFE TO INSTALL | No significant issues |
128
+ | 50-79 | 🟡 REVIEW FIRST | Check flagged items before installing |
129
+ | 0-49 | 🔴 DO NOT INSTALL | Shows signs of malicious behavior |
130
+
131
+ ## CI/CD Integration
132
+
133
+ ### GitHub Actions
134
+
135
+ ```yaml
136
+ - name: Scan skill for security issues
137
+ run: npx skillscan scan ./skill --format ci
138
+ ```
139
+
140
+ ### Pre-commit hook
141
+
142
+ ```bash
143
+ #!/bin/sh
144
+ npx skillscan scan . --format ci
145
+ ```
146
+
147
+ ## Programmatic API
148
+
149
+ ```typescript
150
+ import { ScanEngine } from 'skillscan';
151
+
152
+ const engine = new ScanEngine();
153
+ const result = await engine.scan({ path: './my-skill' });
154
+
155
+ console.log(result.score); // 85
156
+ console.log(result.rating); // 'VERIFIED'
157
+ console.log(result.findings); // Array of findings
158
+ ```
159
+
160
+ ## Contributing
161
+
162
+ Contributions welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
163
+
164
+ ### Adding new rules
165
+
166
+ 1. Create a new rule in `src/scanner/rules/`
167
+ 2. Implement the `Rule` interface
168
+ 3. Register in `src/scanner/rules/index.ts`
169
+ 4. Add tests in `tests/rules/`
170
+
171
+ ## License
172
+
173
+ MIT © [dejimarquis](https://github.com/dejimarquis)
174
+
175
+ ---
176
+
177
+ **SkillScan** — Because trust should be verified, not assumed. 🛡️
@@ -0,0 +1,5 @@
1
+ export declare function scanCommand(skillPath: string, options: {
2
+ format: string;
3
+ verbose: boolean;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BjH"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scanCommand = scanCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const engine_1 = require("../../scanner/engine");
40
+ const formatters_1 = require("../../output/formatters");
41
+ async function scanCommand(skillPath, options) {
42
+ const resolvedPath = path.resolve(skillPath);
43
+ if (!fs.existsSync(resolvedPath)) {
44
+ console.error(`Error: Path not found: ${resolvedPath}`);
45
+ process.exit(1);
46
+ }
47
+ const scanOptions = {
48
+ path: resolvedPath,
49
+ format: options.format,
50
+ verbose: options.verbose
51
+ };
52
+ try {
53
+ const engine = new engine_1.ScanEngine();
54
+ const result = await engine.scan(scanOptions);
55
+ const output = (0, formatters_1.formatOutput)(result, scanOptions);
56
+ console.log(output);
57
+ // Exit with error code if findings are critical
58
+ if (result.rating === 'WARNING') {
59
+ process.exit(1);
60
+ }
61
+ }
62
+ catch (error) {
63
+ console.error(`Error scanning skill: ${error instanceof Error ? error.message : error}`);
64
+ process.exit(1);
65
+ }
66
+ }
67
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,kCA4BC;AAlCD,uCAAyB;AACzB,2CAA6B;AAC7B,iDAAkD;AAClD,wDAAuD;AAGhD,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,OAA6C;IAChG,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAE7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAgB;QAC/B,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,OAAO,CAAC,MAAgC;QAChD,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,mBAAU,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAA,yBAAY,EAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpB,gDAAgD;QAChD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const scan_1 = require("./commands/scan");
6
+ const program = new commander_1.Command();
7
+ program
8
+ .name('skillscan')
9
+ .description('Trust verification for AI agent skills - scan, score, and verify before installation')
10
+ .version('0.1.0');
11
+ program
12
+ .command('scan <path>')
13
+ .description('Scan a skill directory or file for security issues')
14
+ .option('-f, --format <format>', 'Output format: json, text, ci', 'text')
15
+ .option('-v, --verbose', 'Show detailed output', false)
16
+ .action(scan_1.scanCommand);
17
+ program.parse();
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,0CAA8C;AAE9C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,sFAAsF,CAAC;KACnG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,CAAC;KACxE,MAAM,CAAC,eAAe,EAAE,sBAAsB,EAAE,KAAK,CAAC;KACtD,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { ScanEngine } from './scanner/engine';
2
+ export { calculateScore, getRating, getRatingEmoji } from './scoring/trust-score';
3
+ export { formatOutput } from './output/formatters';
4
+ export { getAllRules, getRuleById } from './scanner/rules';
5
+ export * from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC3D,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.getRuleById = exports.getAllRules = exports.formatOutput = exports.getRatingEmoji = exports.getRating = exports.calculateScore = exports.ScanEngine = void 0;
18
+ var engine_1 = require("./scanner/engine");
19
+ Object.defineProperty(exports, "ScanEngine", { enumerable: true, get: function () { return engine_1.ScanEngine; } });
20
+ var trust_score_1 = require("./scoring/trust-score");
21
+ Object.defineProperty(exports, "calculateScore", { enumerable: true, get: function () { return trust_score_1.calculateScore; } });
22
+ Object.defineProperty(exports, "getRating", { enumerable: true, get: function () { return trust_score_1.getRating; } });
23
+ Object.defineProperty(exports, "getRatingEmoji", { enumerable: true, get: function () { return trust_score_1.getRatingEmoji; } });
24
+ var formatters_1 = require("./output/formatters");
25
+ Object.defineProperty(exports, "formatOutput", { enumerable: true, get: function () { return formatters_1.formatOutput; } });
26
+ var rules_1 = require("./scanner/rules");
27
+ Object.defineProperty(exports, "getAllRules", { enumerable: true, get: function () { return rules_1.getAllRules; } });
28
+ Object.defineProperty(exports, "getRuleById", { enumerable: true, get: function () { return rules_1.getRuleById; } });
29
+ __exportStar(require("./types"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAA8C;AAArC,oGAAA,UAAU,OAAA;AACnB,qDAAkF;AAAzE,6GAAA,cAAc,OAAA;AAAE,wGAAA,SAAS,OAAA;AAAE,6GAAA,cAAc,OAAA;AAClD,kDAAmD;AAA1C,0GAAA,YAAY,OAAA;AACrB,yCAA2D;AAAlD,oGAAA,WAAW,OAAA;AAAE,oGAAA,WAAW,OAAA;AACjC,0CAAwB"}
@@ -0,0 +1,3 @@
1
+ import { ScanResult, ScanOptions } from '../types';
2
+ export declare function formatOutput(result: ScanResult, options: ScanOptions): string;
3
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/output/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAqB,MAAM,UAAU,CAAC;AAGtE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAU7E"}
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatOutput = formatOutput;
4
+ function formatOutput(result, options) {
5
+ switch (options.format) {
6
+ case 'json':
7
+ return formatJson(result);
8
+ case 'ci':
9
+ return formatCi(result);
10
+ case 'text':
11
+ default:
12
+ return formatText(result, options.verbose || false);
13
+ }
14
+ }
15
+ function formatJson(result) {
16
+ return JSON.stringify(result, null, 2);
17
+ }
18
+ function formatCi(result) {
19
+ const lines = [];
20
+ for (const finding of result.findings) {
21
+ // Format: file:line:column: severity: message
22
+ const location = finding.line ? `${finding.file}:${finding.line}` : finding.file;
23
+ lines.push(`${location}: ${finding.severity}: [${finding.ruleId}] ${finding.message}`);
24
+ }
25
+ lines.push('');
26
+ lines.push(`Score: ${result.score}/100 (${result.rating})`);
27
+ return lines.join('\n');
28
+ }
29
+ function formatText(result, verbose) {
30
+ const lines = [];
31
+ if (result.findings.length === 0) {
32
+ return formatSafeResult(result);
33
+ }
34
+ return formatUnsafeResult(result, verbose);
35
+ }
36
+ function formatSafeResult(result) {
37
+ const lines = [];
38
+ lines.push('');
39
+ lines.push('╔═══════════════════════════════════════════════════════════════╗');
40
+ lines.push(`║ ✅ SAFE TO INSTALL ║`);
41
+ lines.push(`║ ${padRight(result.skillName, 20)} • Score: ${result.score}/100${' '.repeat(20)}║`);
42
+ lines.push('╚═══════════════════════════════════════════════════════════════╝');
43
+ lines.push('');
44
+ lines.push('No security issues detected. This skill looks safe!');
45
+ lines.push('');
46
+ return lines.join('\n');
47
+ }
48
+ function formatUnsafeResult(result, verbose) {
49
+ const lines = [];
50
+ const recommendation = getRecommendation(result.rating);
51
+ const tldr = generateTldr(result);
52
+ // Header with clear verdict
53
+ lines.push('');
54
+ lines.push('╔═══════════════════════════════════════════════════════════════╗');
55
+ lines.push(`║ ${recommendation.icon} ${padRight(recommendation.text, 55)}║`);
56
+ lines.push(`║ ${padRight(result.skillName, 20)} • Score: ${result.score}/100${' '.repeat(20)}║`);
57
+ lines.push('╚═══════════════════════════════════════════════════════════════╝');
58
+ lines.push('');
59
+ // TL;DR
60
+ lines.push(`TL;DR: ${recommendation.icon} ${tldr}`);
61
+ lines.push('');
62
+ // Group findings by rule for cleaner display
63
+ const groupedFindings = groupByRule(result.findings);
64
+ lines.push('⚠️ Issues Found:');
65
+ lines.push('');
66
+ // Show CRITICAL and HIGH issues (skip LOW in non-verbose mode)
67
+ const severityOrder = verbose
68
+ ? ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW']
69
+ : ['CRITICAL', 'HIGH', 'MEDIUM'];
70
+ // Sort groups by highest severity (CRITICAL first)
71
+ const sortedGroups = Object.entries(groupedFindings).sort(([, a], [, b]) => {
72
+ const severityRank = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3 };
73
+ const aRank = severityRank[getHighestSeverity(a)];
74
+ const bRank = severityRank[getHighestSeverity(b)];
75
+ return aRank - bRank;
76
+ });
77
+ for (const [ruleId, findings] of sortedGroups) {
78
+ // Filter to relevant severities
79
+ const relevantFindings = findings.filter(f => severityOrder.includes(f.severity));
80
+ if (relevantFindings.length === 0)
81
+ continue;
82
+ const highestSeverity = getHighestSeverity(relevantFindings);
83
+ const icon = getSeverityIcon(highestSeverity);
84
+ const description = getUserFriendlyDescription(ruleId, relevantFindings);
85
+ const example = getBestExample(relevantFindings);
86
+ // Show grouped issue with count if multiple
87
+ const countSuffix = relevantFindings.length > 1 ? ` (${relevantFindings.length} instances)` : '';
88
+ lines.push(` ${icon} ${description}${countSuffix}`);
89
+ // Show the most relevant code snippet (full in verbose, truncated in default)
90
+ if (example) {
91
+ const snippet = verbose ? example : truncate(example, 80);
92
+ lines.push(` "${snippet}"`);
93
+ }
94
+ // In verbose mode, show all locations
95
+ if (verbose) {
96
+ for (const finding of relevantFindings) {
97
+ const location = finding.line
98
+ ? `${getFileName(finding.file)}:${finding.line}`
99
+ : getFileName(finding.file);
100
+ lines.push(` └─ ${location} [${finding.ruleId}]`);
101
+ }
102
+ }
103
+ lines.push('');
104
+ }
105
+ // What this means section
106
+ lines.push('💡 What this means:');
107
+ lines.push(` ${getExplanation(result)}`);
108
+ lines.push('');
109
+ // Final recommendation
110
+ lines.push(`${recommendation.icon} Recommendation: ${recommendation.advice}`);
111
+ lines.push('');
112
+ if (verbose) {
113
+ lines.push(`📊 Details: ${result.findings.length} findings in ${result.scanDuration}ms`);
114
+ lines.push(` Path: ${result.skillPath}`);
115
+ lines.push('');
116
+ }
117
+ return lines.join('\n');
118
+ }
119
+ // Group findings by ruleId for cleaner display
120
+ function groupByRule(findings) {
121
+ const groups = {};
122
+ for (const finding of findings) {
123
+ if (!groups[finding.ruleId]) {
124
+ groups[finding.ruleId] = [];
125
+ }
126
+ groups[finding.ruleId].push(finding);
127
+ }
128
+ return groups;
129
+ }
130
+ function getHighestSeverity(findings) {
131
+ const order = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'];
132
+ for (const severity of order) {
133
+ if (findings.some(f => f.severity === severity)) {
134
+ return severity;
135
+ }
136
+ }
137
+ return 'LOW';
138
+ }
139
+ function getUserFriendlyDescription(ruleId, findings) {
140
+ // Map technical rule IDs to user-friendly descriptions
141
+ const descriptions = {
142
+ 'prompt-injection': 'Asks the AI to ignore its safety rules',
143
+ 'hidden-instructions': 'Contains hidden text you cannot see',
144
+ 'sensitive-paths': 'Tries to access your private files',
145
+ 'file-access': 'Suspicious file access patterns detected'
146
+ };
147
+ // Try to give more specific description based on findings
148
+ const finding = findings[0];
149
+ if (ruleId === 'sensitive-paths') {
150
+ if (finding.message.includes('SSH'))
151
+ return 'Tries to access your SSH keys';
152
+ if (finding.message.includes('AWS'))
153
+ return 'Tries to access your AWS credentials';
154
+ if (finding.message.includes('env'))
155
+ return 'Tries to read your environment secrets';
156
+ return 'Tries to access your private credentials';
157
+ }
158
+ if (ruleId === 'prompt-injection') {
159
+ if (finding.message.includes('override'))
160
+ return 'Asks the AI to ignore its safety rules';
161
+ if (finding.message.includes('system prompt'))
162
+ return 'Tries to extract AI system instructions';
163
+ if (finding.message.includes('jailbreak'))
164
+ return 'Contains known jailbreak patterns';
165
+ if (finding.message.includes('Role'))
166
+ return 'Tries to manipulate the AI identity';
167
+ if (finding.message.includes('base64'))
168
+ return 'Contains hidden encoded commands';
169
+ }
170
+ return descriptions[ruleId] || 'Suspicious pattern detected';
171
+ }
172
+ function getBestExample(findings) {
173
+ // Prefer findings with context
174
+ const withContext = findings.find(f => f.context && f.context.length > 10);
175
+ if (withContext?.context) {
176
+ return withContext.context;
177
+ }
178
+ // Fall back to extracting from message
179
+ const first = findings[0];
180
+ const match = first.message.match(/"([^"]+)"/);
181
+ return match ? match[1] : null;
182
+ }
183
+ function generateTldr(result) {
184
+ const grouped = groupByRule(result.findings);
185
+ const issues = [];
186
+ if (grouped['prompt-injection']) {
187
+ issues.push('manipulate AI behavior');
188
+ }
189
+ if (grouped['sensitive-paths']) {
190
+ issues.push('steal your credentials');
191
+ }
192
+ if (grouped['hidden-instructions']) {
193
+ issues.push('hide malicious instructions');
194
+ }
195
+ if (grouped['file-access']) {
196
+ issues.push('access sensitive files');
197
+ }
198
+ if (issues.length === 0) {
199
+ return 'Review before installing';
200
+ }
201
+ if (result.rating === 'WARNING') {
202
+ return `Don't install - this skill may ${issues.slice(0, 2).join(' and ')}`;
203
+ }
204
+ return `Review carefully - found attempts to ${issues[0]}`;
205
+ }
206
+ function getExplanation(result) {
207
+ if (result.rating === 'WARNING') {
208
+ return 'This skill shows signs of malicious behavior. It may attempt to steal sensitive data or manipulate AI responses in harmful ways.';
209
+ }
210
+ if (result.rating === 'CAUTION') {
211
+ return 'This skill has some concerning patterns that should be reviewed. It might be safe, but verify the flagged items before installing.';
212
+ }
213
+ return 'Some minor issues were detected. Review them to ensure they are expected behavior.';
214
+ }
215
+ function getRecommendation(rating) {
216
+ switch (rating) {
217
+ case 'WARNING':
218
+ return {
219
+ icon: '🔴',
220
+ text: 'DO NOT INSTALL',
221
+ advice: 'Do not install this skill. It shows signs of malicious behavior.'
222
+ };
223
+ case 'CAUTION':
224
+ return {
225
+ icon: '🟡',
226
+ text: 'REVIEW BEFORE INSTALLING',
227
+ advice: 'Review the flagged items carefully before deciding to install.'
228
+ };
229
+ default:
230
+ return {
231
+ icon: '🟢',
232
+ text: 'LIKELY SAFE',
233
+ advice: 'This skill appears safe, but always review what you install.'
234
+ };
235
+ }
236
+ }
237
+ function getSeverityIcon(severity) {
238
+ switch (severity) {
239
+ case 'CRITICAL': return '🔴';
240
+ case 'HIGH': return '🟠';
241
+ case 'MEDIUM': return '🟡';
242
+ case 'LOW': return '🔵';
243
+ }
244
+ }
245
+ function padRight(str, length) {
246
+ return str.length >= length ? str.slice(0, length) : str + ' '.repeat(length - str.length);
247
+ }
248
+ function truncate(str, maxLength) {
249
+ if (str.length <= maxLength)
250
+ return str;
251
+ return str.slice(0, maxLength - 3) + '...';
252
+ }
253
+ function getFileName(filePath) {
254
+ return filePath.split('/').pop() || filePath;
255
+ }
256
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/output/formatters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ScanOptions, ScanResult } from '../types';
2
+ export declare class ScanEngine {
3
+ scan(options: ScanOptions): Promise<ScanResult>;
4
+ private discoverFiles;
5
+ private parseFile;
6
+ }
7
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/scanner/engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,UAAU,EAA0B,MAAM,UAAU,CAAC;AAM3E,qBAAa,UAAU;IACf,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IA2CrD,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,SAAS;CAmBlB"}