@rulemetric/skills-registry 0.1.1 → 0.2.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/discovered-sources.json +2992 -0
- package/dist/discover-sources.d.ts +3 -0
- package/dist/discover-sources.d.ts.map +1 -0
- package/dist/discover-sources.js +183 -0
- package/dist/discover-sources.js.map +1 -0
- package/dist/discovered.d.ts +12 -0
- package/dist/discovered.d.ts.map +1 -0
- package/dist/discovered.js +30 -0
- package/dist/discovered.js.map +1 -0
- package/dist/fetch-registry.js +105 -4
- package/dist/fetch-registry.js.map +1 -1
- package/dist/github-fetcher.d.ts +42 -5
- package/dist/github-fetcher.d.ts.map +1 -1
- package/dist/github-fetcher.js +254 -177
- package/dist/github-fetcher.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/scoring.d.ts +19 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +104 -0
- package/dist/scoring.js.map +1 -0
- package/dist/security-scanner.d.ts +26 -0
- package/dist/security-scanner.d.ts.map +1 -0
- package/dist/security-scanner.js +290 -0
- package/dist/security-scanner.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +24 -4
package/dist/scoring.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Compute a quality score for a skill entry. */
|
|
2
|
+
export function computeQualityScore(skill) {
|
|
3
|
+
const factors = {
|
|
4
|
+
popularity: scorePopularity(skill),
|
|
5
|
+
contentQuality: scoreContentQuality(skill),
|
|
6
|
+
completeness: scoreCompleteness(skill),
|
|
7
|
+
recency: scoreRecency(skill),
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
overall: factors.popularity + factors.contentQuality + factors.completeness + factors.recency,
|
|
11
|
+
factors,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function scorePopularity(skill) {
|
|
15
|
+
const stars = skill.popularity?.stars ?? 0;
|
|
16
|
+
if (stars >= 10_000)
|
|
17
|
+
return 25;
|
|
18
|
+
if (stars >= 5_000)
|
|
19
|
+
return 20;
|
|
20
|
+
if (stars >= 1_000)
|
|
21
|
+
return 15;
|
|
22
|
+
if (stars >= 100)
|
|
23
|
+
return 10;
|
|
24
|
+
if (stars > 0)
|
|
25
|
+
return 5;
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
function scoreContentQuality(skill) {
|
|
29
|
+
const content = skill.content;
|
|
30
|
+
let score = 0;
|
|
31
|
+
// Length: ideal 200-5000 chars
|
|
32
|
+
const len = content.length;
|
|
33
|
+
if (len >= 200 && len <= 5000)
|
|
34
|
+
score += 8;
|
|
35
|
+
else if (len >= 100 && len <= 10000)
|
|
36
|
+
score += 5;
|
|
37
|
+
else if (len >= 50)
|
|
38
|
+
score += 2;
|
|
39
|
+
// Has markdown sections (## headings)
|
|
40
|
+
const sectionCount = (content.match(/^##\s/gm) ?? []).length;
|
|
41
|
+
if (sectionCount >= 3)
|
|
42
|
+
score += 7;
|
|
43
|
+
else if (sectionCount >= 1)
|
|
44
|
+
score += 4;
|
|
45
|
+
// Has code blocks
|
|
46
|
+
const codeBlocks = (content.match(/```/g) ?? []).length / 2;
|
|
47
|
+
if (codeBlocks >= 2)
|
|
48
|
+
score += 5;
|
|
49
|
+
else if (codeBlocks >= 1)
|
|
50
|
+
score += 3;
|
|
51
|
+
// Has lists (actionable content)
|
|
52
|
+
const listItems = (content.match(/^[-*]\s/gm) ?? []).length;
|
|
53
|
+
if (listItems >= 5)
|
|
54
|
+
score += 5;
|
|
55
|
+
else if (listItems >= 2)
|
|
56
|
+
score += 3;
|
|
57
|
+
return Math.min(25, score);
|
|
58
|
+
}
|
|
59
|
+
function scoreCompleteness(skill) {
|
|
60
|
+
let score = 0;
|
|
61
|
+
// Has a meaningful description (not just "Imported from...")
|
|
62
|
+
if (skill.description.length > 20 && !skill.description.startsWith('Imported'))
|
|
63
|
+
score += 7;
|
|
64
|
+
else if (skill.description.length > 10)
|
|
65
|
+
score += 3;
|
|
66
|
+
// Has tags
|
|
67
|
+
if (skill.tags.length >= 3)
|
|
68
|
+
score += 6;
|
|
69
|
+
else if (skill.tags.length >= 1)
|
|
70
|
+
score += 3;
|
|
71
|
+
// Supports multiple tools
|
|
72
|
+
if (skill.tools.length >= 3)
|
|
73
|
+
score += 5;
|
|
74
|
+
else if (skill.tools.length >= 2)
|
|
75
|
+
score += 3;
|
|
76
|
+
else
|
|
77
|
+
score += 1;
|
|
78
|
+
// Has languages specified
|
|
79
|
+
if ((skill.languages?.length ?? 0) > 0)
|
|
80
|
+
score += 4;
|
|
81
|
+
// Has frameworks specified
|
|
82
|
+
if ((skill.frameworks?.length ?? 0) > 0)
|
|
83
|
+
score += 3;
|
|
84
|
+
return Math.min(25, score);
|
|
85
|
+
}
|
|
86
|
+
function scoreRecency(skill) {
|
|
87
|
+
if (!skill.updatedAt)
|
|
88
|
+
return 0;
|
|
89
|
+
const updated = new Date(skill.updatedAt);
|
|
90
|
+
const now = new Date();
|
|
91
|
+
const daysSince = (now.getTime() - updated.getTime()) / (1000 * 60 * 60 * 24);
|
|
92
|
+
if (daysSince <= 7)
|
|
93
|
+
return 25;
|
|
94
|
+
if (daysSince <= 30)
|
|
95
|
+
return 20;
|
|
96
|
+
if (daysSince <= 90)
|
|
97
|
+
return 15;
|
|
98
|
+
if (daysSince <= 180)
|
|
99
|
+
return 10;
|
|
100
|
+
if (daysSince <= 365)
|
|
101
|
+
return 5;
|
|
102
|
+
return 2;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=scoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.js","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SkillEntry } from './types.js';
|
|
2
|
+
/** Severity levels for security findings. */
|
|
3
|
+
export type Severity = 'critical' | 'high' | 'medium' | 'low';
|
|
4
|
+
/** A single security finding in a skill. */
|
|
5
|
+
export interface SecurityFinding {
|
|
6
|
+
rule: string;
|
|
7
|
+
severity: Severity;
|
|
8
|
+
message: string;
|
|
9
|
+
/** The matched text (truncated) */
|
|
10
|
+
match: string;
|
|
11
|
+
/** Line number (1-indexed) where the match was found */
|
|
12
|
+
line: number;
|
|
13
|
+
}
|
|
14
|
+
/** Result of scanning a single skill. */
|
|
15
|
+
export interface ScanResult {
|
|
16
|
+
skillId: string;
|
|
17
|
+
passed: boolean;
|
|
18
|
+
findings: SecurityFinding[];
|
|
19
|
+
}
|
|
20
|
+
/** Scan a single skill's content for security issues. */
|
|
21
|
+
export declare function scanSkill(skill: SkillEntry): ScanResult;
|
|
22
|
+
/** Scan all skills in a registry. Returns results sorted by severity. */
|
|
23
|
+
export declare function scanRegistry(skills: SkillEntry[]): ScanResult[];
|
|
24
|
+
/** Format scan results for console output. */
|
|
25
|
+
export declare function formatScanResults(results: ScanResult[]): string;
|
|
26
|
+
//# sourceMappingURL=security-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-scanner.d.ts","sourceRoot":"","sources":["../src/security-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,6CAA6C;AAC7C,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9D,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AA8MD,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAmEvD;AAMD,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAU/D;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CA2B/D"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
const RULES = [
|
|
2
|
+
// ── Critical: Prompt Injection ──
|
|
3
|
+
{
|
|
4
|
+
id: 'prompt-injection-ignore',
|
|
5
|
+
severity: 'critical',
|
|
6
|
+
description: 'Prompt injection: instruction to ignore previous instructions',
|
|
7
|
+
patterns: [
|
|
8
|
+
/ignore\s+(all\s+)?(previous|prior|above|earlier)\s+(instructions?|rules?|prompts?|context)/i,
|
|
9
|
+
/disregard\s+(all\s+)?(previous|prior|above)\s+(instructions?|rules?)/i,
|
|
10
|
+
/forget\s+(everything|all)\s+(you|that)\s+(were|was|have)/i,
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: 'prompt-injection-roleplay',
|
|
15
|
+
severity: 'critical',
|
|
16
|
+
description: 'Prompt injection: role override or jailbreak attempt',
|
|
17
|
+
patterns: [
|
|
18
|
+
/you\s+are\s+now\s+(DAN|evil|unrestricted|unfiltered|jailbroken)/i,
|
|
19
|
+
/entering?\s+(DAN|developer|god)\s+mode/i,
|
|
20
|
+
/act\s+as\s+(if|though)\s+you\s+(have\s+no|don.?t\s+have)\s+(restrictions|filters|limits)/i,
|
|
21
|
+
/from\s+now\s+on,?\s+you\s+(will|must|should)\s+(always|never)\s+(obey|follow|listen)/i,
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'prompt-injection-system',
|
|
26
|
+
severity: 'critical',
|
|
27
|
+
description: 'Prompt injection: fake system message or hidden instruction',
|
|
28
|
+
patterns: [
|
|
29
|
+
/<\/?system[-_]?(message|prompt|instruction|reminder)>/i,
|
|
30
|
+
/\[SYSTEM\]\s*:/i,
|
|
31
|
+
/\[INST\]|\[\/INST\]/i,
|
|
32
|
+
/<<\s*SYS\s*>>|<<\s*\/SYS\s*>>/i,
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
// ── High: Dangerous Commands ──
|
|
36
|
+
{
|
|
37
|
+
id: 'dangerous-command-rm',
|
|
38
|
+
severity: 'high',
|
|
39
|
+
description: 'Dangerous shell command: recursive delete',
|
|
40
|
+
patterns: [
|
|
41
|
+
/rm\s+-[a-z]*r[a-z]*f|rm\s+-[a-z]*f[a-z]*r/i,
|
|
42
|
+
/rm\s+-rf\s+[\/~]/i,
|
|
43
|
+
/rm\s+-rf\s+\*/i,
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'dangerous-command-eval',
|
|
48
|
+
severity: 'high',
|
|
49
|
+
description: 'Dangerous command: eval/exec of remote content',
|
|
50
|
+
patterns: [
|
|
51
|
+
/curl\s+.*\|\s*(bash|sh|python|node|eval)/i,
|
|
52
|
+
/wget\s+.*\|\s*(bash|sh|python|node|eval)/i,
|
|
53
|
+
/\beval\s*\(\s*(fetch|require|import)\b/i,
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'dangerous-command-env',
|
|
58
|
+
severity: 'high',
|
|
59
|
+
description: 'Command that accesses or exfiltrates environment variables',
|
|
60
|
+
patterns: [
|
|
61
|
+
/printenv\s*\|/i,
|
|
62
|
+
/env\s*\|\s*(curl|wget|nc|ncat)/i,
|
|
63
|
+
/\$\{?\w*(SECRET|TOKEN|KEY|PASSWORD|CREDENTIAL)\w*\}?\s*.*\b(curl|wget|nc|fetch)\b/i,
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'dangerous-command-reverse-shell',
|
|
68
|
+
severity: 'critical',
|
|
69
|
+
description: 'Reverse shell or network backdoor pattern',
|
|
70
|
+
patterns: [
|
|
71
|
+
/\bnc\s+-[a-z]*e\s/i,
|
|
72
|
+
/\bncat\b.*\b-e\b/i,
|
|
73
|
+
/\/dev\/(tcp|udp)\//i,
|
|
74
|
+
/mkfifo\s+.*\bsh\b/i,
|
|
75
|
+
/bash\s+-i\s+>&?\s*\/dev\/(tcp|udp)/i,
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
// ── High: Data Exfiltration ──
|
|
79
|
+
{
|
|
80
|
+
id: 'exfil-curl-post',
|
|
81
|
+
severity: 'high',
|
|
82
|
+
description: 'Potential data exfiltration via HTTP POST',
|
|
83
|
+
patterns: [
|
|
84
|
+
/curl\s+.*-X\s*POST\s+https?:\/\/(?!localhost|127\.0\.0\.1)/i,
|
|
85
|
+
/curl\s+.*--data.*https?:\/\/(?!localhost|127\.0\.0\.1)/i,
|
|
86
|
+
/fetch\s*\(\s*['"]https?:\/\/(?!localhost).*['"].*method:\s*['"]POST['"]/i,
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'exfil-webhook',
|
|
91
|
+
severity: 'high',
|
|
92
|
+
description: 'Webhook or external callback URL',
|
|
93
|
+
patterns: [
|
|
94
|
+
/https?:\/\/[^\s]*webhook[^\s]*/i,
|
|
95
|
+
/https?:\/\/[^\s]*\.ngrok\.[^\s]*/i,
|
|
96
|
+
/https?:\/\/[^\s]*requestbin[^\s]*/i,
|
|
97
|
+
/https?:\/\/[^\s]*pipedream[^\s]*/i,
|
|
98
|
+
/https?:\/\/[^\s]*burpcollaborator[^\s]*/i,
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
// ── Medium: Suspicious Patterns ──
|
|
102
|
+
{
|
|
103
|
+
id: 'base64-blob',
|
|
104
|
+
severity: 'medium',
|
|
105
|
+
description: 'Large base64-encoded blob (potential obfuscated payload)',
|
|
106
|
+
patterns: [
|
|
107
|
+
/[A-Za-z0-9+/]{100,}={0,2}/,
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'obfuscated-code',
|
|
112
|
+
severity: 'medium',
|
|
113
|
+
description: 'Obfuscated or encoded script content',
|
|
114
|
+
patterns: [
|
|
115
|
+
/\\x[0-9a-f]{2}(\\x[0-9a-f]{2}){10,}/i,
|
|
116
|
+
/\\u[0-9a-f]{4}(\\u[0-9a-f]{4}){10,}/i,
|
|
117
|
+
/String\.fromCharCode\s*\(/i,
|
|
118
|
+
/atob\s*\(\s*['"][A-Za-z0-9+/]/i,
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: 'hidden-text',
|
|
123
|
+
severity: 'medium',
|
|
124
|
+
description: 'Hidden content via HTML comments, zero-width chars, or invisible unicode',
|
|
125
|
+
patterns: [
|
|
126
|
+
/<!--[\s\S]{50,}?-->/,
|
|
127
|
+
/[\u200B\u200C\u200D\uFEFF]{3,}/,
|
|
128
|
+
/\u2060{3,}/,
|
|
129
|
+
],
|
|
130
|
+
multiline: true,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: 'suspicious-url',
|
|
134
|
+
severity: 'medium',
|
|
135
|
+
description: 'URL pointing to non-standard domain (potential phishing or C2)',
|
|
136
|
+
patterns: [
|
|
137
|
+
/https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
|
|
138
|
+
/https?:\/\/[^\s]*\.(tk|ml|ga|cf|gq|top|xyz|pw|cc)\b/i,
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
// ── Medium: Privilege Escalation ──
|
|
142
|
+
{
|
|
143
|
+
id: 'privilege-escalation',
|
|
144
|
+
severity: 'medium',
|
|
145
|
+
description: 'Instructions to bypass safety, skip verification, or escalate permissions',
|
|
146
|
+
patterns: [
|
|
147
|
+
/--no-verify/i,
|
|
148
|
+
/--force\s+(push|delete|remove)/i,
|
|
149
|
+
/chmod\s+777/i,
|
|
150
|
+
/sudo\s+/i,
|
|
151
|
+
/disable\s+(security|auth|verification|checking|linting)/i,
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
// ── Low: Suspicious Instructions ──
|
|
155
|
+
{
|
|
156
|
+
id: 'credential-request',
|
|
157
|
+
severity: 'low',
|
|
158
|
+
description: 'Instruction requesting or handling credentials',
|
|
159
|
+
patterns: [
|
|
160
|
+
/\b(paste|enter|provide|share)\s+(your\s+)?(api[- ]?key|token|password|secret|credential)/i,
|
|
161
|
+
/hardcode\s+(the\s+)?(api[- ]?key|token|password|secret)/i,
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: 'file-system-access',
|
|
166
|
+
severity: 'low',
|
|
167
|
+
description: 'Access to sensitive system paths',
|
|
168
|
+
patterns: [
|
|
169
|
+
/\/etc\/(passwd|shadow|hosts)/,
|
|
170
|
+
/~\/\.(ssh|gnupg|aws|config)/,
|
|
171
|
+
/\$HOME\/\.(ssh|gnupg|aws)/,
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
// ── Allowlist ────────────────────────────────────────────────────────────────
|
|
176
|
+
/** Patterns that are false positives in legitimate skill content. */
|
|
177
|
+
const ALLOWLIST = [
|
|
178
|
+
// Security review checklists naturally mention these concepts
|
|
179
|
+
{ rule: 'credential-request', pattern: /checklist|review|verify|never\s+hardcode/i },
|
|
180
|
+
// Git convention skills mention --no-verify in a "don't do this" context
|
|
181
|
+
{ rule: 'privilege-escalation', pattern: /never|don.?t|avoid|anti.?pattern/i },
|
|
182
|
+
];
|
|
183
|
+
// ── Scanner ──────────────────────────────────────────────────────────────────
|
|
184
|
+
/** Scan a single skill's content for security issues. */
|
|
185
|
+
export function scanSkill(skill) {
|
|
186
|
+
const findings = [];
|
|
187
|
+
const content = skill.content;
|
|
188
|
+
const lines = content.split('\n');
|
|
189
|
+
for (const rule of RULES) {
|
|
190
|
+
if (rule.multiline) {
|
|
191
|
+
// Match against full content
|
|
192
|
+
for (const pattern of rule.patterns) {
|
|
193
|
+
const match = content.match(pattern);
|
|
194
|
+
if (match) {
|
|
195
|
+
// Check allowlist
|
|
196
|
+
const lineIdx = content.substring(0, match.index ?? 0).split('\n').length;
|
|
197
|
+
const lineText = lines[lineIdx - 1] ?? '';
|
|
198
|
+
if (isAllowlisted(rule.id, lineText))
|
|
199
|
+
continue;
|
|
200
|
+
findings.push({
|
|
201
|
+
rule: rule.id,
|
|
202
|
+
severity: rule.severity,
|
|
203
|
+
message: rule.description,
|
|
204
|
+
match: match[0].slice(0, 100),
|
|
205
|
+
line: lineIdx,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
// Match per-line
|
|
212
|
+
for (let i = 0; i < lines.length; i++) {
|
|
213
|
+
const line = lines[i];
|
|
214
|
+
// Skip content inside code blocks that are clearly examples
|
|
215
|
+
// (but still flag dangerous commands even in code blocks)
|
|
216
|
+
for (const pattern of rule.patterns) {
|
|
217
|
+
const match = line.match(pattern);
|
|
218
|
+
if (match) {
|
|
219
|
+
if (isAllowlisted(rule.id, line))
|
|
220
|
+
continue;
|
|
221
|
+
findings.push({
|
|
222
|
+
rule: rule.id,
|
|
223
|
+
severity: rule.severity,
|
|
224
|
+
message: rule.description,
|
|
225
|
+
match: match[0].slice(0, 100),
|
|
226
|
+
line: i + 1,
|
|
227
|
+
});
|
|
228
|
+
break; // One finding per rule per line
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Dedupe findings by rule+line
|
|
235
|
+
const seen = new Set();
|
|
236
|
+
const deduped = findings.filter(f => {
|
|
237
|
+
const key = `${f.rule}:${f.line}`;
|
|
238
|
+
if (seen.has(key))
|
|
239
|
+
return false;
|
|
240
|
+
seen.add(key);
|
|
241
|
+
return true;
|
|
242
|
+
});
|
|
243
|
+
const hasCritical = deduped.some(f => f.severity === 'critical');
|
|
244
|
+
const hasHigh = deduped.some(f => f.severity === 'high');
|
|
245
|
+
return {
|
|
246
|
+
skillId: skill.id,
|
|
247
|
+
passed: !hasCritical && !hasHigh,
|
|
248
|
+
findings: deduped,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function isAllowlisted(ruleId, lineText) {
|
|
252
|
+
return ALLOWLIST.some(a => a.rule === ruleId && a.pattern.test(lineText));
|
|
253
|
+
}
|
|
254
|
+
/** Scan all skills in a registry. Returns results sorted by severity. */
|
|
255
|
+
export function scanRegistry(skills) {
|
|
256
|
+
const results = skills.map(scanSkill);
|
|
257
|
+
// Sort: failed first, then by finding count
|
|
258
|
+
results.sort((a, b) => {
|
|
259
|
+
if (a.passed !== b.passed)
|
|
260
|
+
return a.passed ? 1 : -1;
|
|
261
|
+
return b.findings.length - a.findings.length;
|
|
262
|
+
});
|
|
263
|
+
return results;
|
|
264
|
+
}
|
|
265
|
+
/** Format scan results for console output. */
|
|
266
|
+
export function formatScanResults(results) {
|
|
267
|
+
const lines = [];
|
|
268
|
+
const passed = results.filter(r => r.passed).length;
|
|
269
|
+
const failed = results.filter(r => !r.passed).length;
|
|
270
|
+
const total = results.length;
|
|
271
|
+
lines.push(`\nSecurity Scan: ${total} skills scanned`);
|
|
272
|
+
lines.push(` ${passed} passed, ${failed} failed\n`);
|
|
273
|
+
for (const result of results) {
|
|
274
|
+
if (result.findings.length === 0)
|
|
275
|
+
continue;
|
|
276
|
+
const icon = result.passed ? '⚠' : '✗';
|
|
277
|
+
lines.push(`${icon} ${result.skillId}:`);
|
|
278
|
+
for (const f of result.findings) {
|
|
279
|
+
const sevLabel = f.severity.toUpperCase().padEnd(8);
|
|
280
|
+
lines.push(` [${sevLabel}] L${f.line}: ${f.message}`);
|
|
281
|
+
lines.push(` match: "${f.match}"`);
|
|
282
|
+
}
|
|
283
|
+
lines.push('');
|
|
284
|
+
}
|
|
285
|
+
if (failed > 0) {
|
|
286
|
+
lines.push(`BLOCKED: ${failed} skill(s) have critical/high findings and will not be included.`);
|
|
287
|
+
}
|
|
288
|
+
return lines.join('\n');
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=security-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-scanner.js","sourceRoot":"","sources":["../src/security-scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -31,6 +31,13 @@ export interface SkillEntry {
|
|
|
31
31
|
};
|
|
32
32
|
/** When this entry was last updated */
|
|
33
33
|
updatedAt: string;
|
|
34
|
+
/**
|
|
35
|
+
* Precomputed quality score (0-100, plus per-factor breakdown). Set during
|
|
36
|
+
* registry build by fetch-registry.ts. Optional so older registries / hand-
|
|
37
|
+
* written community submissions still validate; consumers should fall back
|
|
38
|
+
* to computing it on demand when this is absent.
|
|
39
|
+
*/
|
|
40
|
+
qualityScore?: import('./scoring.js').QualityScore;
|
|
34
41
|
}
|
|
35
42
|
/** Provenance of a skill entry. */
|
|
36
43
|
export interface SkillSource {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,MAAM,GACd,aAAa,GACb,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,CAAC;AAEhB,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,UAAU,GACV,WAAW,GACX,MAAM,GACN,UAAU,GACV,SAAS,GACT,cAAc,GACd,QAAQ,GACR,eAAe,GACf,aAAa,GACb,OAAO,CAAC;AAEZ,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,sBAAsB;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wCAAwC;IACxC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,MAAM,GACd,aAAa,GACb,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,CAAC;AAEhB,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,UAAU,GACV,WAAW,GACX,MAAM,GACN,UAAU,GACV,SAAS,GACT,cAAc,GACd,QAAQ,GACR,eAAe,GACf,aAAa,GACb,OAAO,CAAC;AAEZ,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,sBAAsB;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wCAAwC;IACxC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,cAAc,EAAE,YAAY,CAAC;CACpD;AAED,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+BAA+B;AAC/B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,6BAA6B;AAC7B,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,eAAe,EAAE,aAAa,CAAC;IAC/B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulemetric/skills-registry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
8
|
+
"dist",
|
|
9
|
+
"discovered-sources.json"
|
|
9
10
|
],
|
|
10
11
|
"type": "module",
|
|
11
12
|
"main": "./dist/index.js",
|
|
12
13
|
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./scoring": {
|
|
20
|
+
"types": "./dist/scoring.d.ts",
|
|
21
|
+
"default": "./dist/scoring.js"
|
|
22
|
+
},
|
|
23
|
+
"./types": {
|
|
24
|
+
"types": "./dist/types.d.ts",
|
|
25
|
+
"default": "./dist/types.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
13
28
|
"dependencies": {
|
|
14
|
-
"
|
|
29
|
+
"@octokit/plugin-retry": "^8.1.0",
|
|
30
|
+
"@octokit/plugin-throttling": "^11.0.3",
|
|
31
|
+
"gray-matter": "^4.0.3",
|
|
32
|
+
"octokit": "^5.0.5",
|
|
33
|
+
"p-limit": "^7.3.0"
|
|
15
34
|
},
|
|
16
35
|
"devDependencies": {
|
|
17
36
|
"@types/node": "^22.0.0",
|
|
@@ -23,6 +42,7 @@
|
|
|
23
42
|
"scripts": {
|
|
24
43
|
"build": "tsc",
|
|
25
44
|
"type-check": "tsc --noEmit",
|
|
26
|
-
"fetch": "tsx src/fetch-registry.ts"
|
|
45
|
+
"fetch": "tsx src/fetch-registry.ts",
|
|
46
|
+
"discover": "tsx src/discover-sources.ts"
|
|
27
47
|
}
|
|
28
48
|
}
|