@kevinrabun/judges 3.45.0 → 3.47.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/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/adoption-report.d.ts +8 -0
- package/dist/commands/adoption-report.d.ts.map +1 -0
- package/dist/commands/adoption-report.js +219 -0
- package/dist/commands/adoption-report.js.map +1 -0
- package/dist/commands/ai-model-trust.d.ts +17 -0
- package/dist/commands/ai-model-trust.d.ts.map +1 -0
- package/dist/commands/ai-model-trust.js +235 -0
- package/dist/commands/ai-model-trust.js.map +1 -0
- package/dist/commands/ai-prompt-audit.d.ts +23 -0
- package/dist/commands/ai-prompt-audit.d.ts.map +1 -0
- package/dist/commands/ai-prompt-audit.js +255 -0
- package/dist/commands/ai-prompt-audit.js.map +1 -0
- package/dist/commands/audit-bundle.d.ts +29 -0
- package/dist/commands/audit-bundle.d.ts.map +1 -0
- package/dist/commands/audit-bundle.js +235 -0
- package/dist/commands/audit-bundle.js.map +1 -0
- package/dist/commands/code-owner-suggest.d.ts +17 -0
- package/dist/commands/code-owner-suggest.d.ts.map +1 -0
- package/dist/commands/code-owner-suggest.js +215 -0
- package/dist/commands/code-owner-suggest.js.map +1 -0
- package/dist/commands/config-drift.d.ts +25 -0
- package/dist/commands/config-drift.d.ts.map +1 -0
- package/dist/commands/config-drift.js +214 -0
- package/dist/commands/config-drift.js.map +1 -0
- package/dist/commands/cost-forecast.d.ts +19 -0
- package/dist/commands/cost-forecast.d.ts.map +1 -0
- package/dist/commands/cost-forecast.js +194 -0
- package/dist/commands/cost-forecast.js.map +1 -0
- package/dist/commands/dev-score.d.ts +37 -0
- package/dist/commands/dev-score.d.ts.map +1 -0
- package/dist/commands/dev-score.js +204 -0
- package/dist/commands/dev-score.js.map +1 -0
- package/dist/commands/generate.d.ts +8 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +404 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/learn.d.ts +27 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +289 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/model-risk.d.ts +28 -0
- package/dist/commands/model-risk.d.ts.map +1 -0
- package/dist/commands/model-risk.js +221 -0
- package/dist/commands/model-risk.js.map +1 -0
- package/dist/commands/pr-quality-gate.d.ts +29 -0
- package/dist/commands/pr-quality-gate.d.ts.map +1 -0
- package/dist/commands/pr-quality-gate.js +208 -0
- package/dist/commands/pr-quality-gate.js.map +1 -0
- package/dist/commands/reg-watch.d.ts +21 -0
- package/dist/commands/reg-watch.d.ts.map +1 -0
- package/dist/commands/reg-watch.js +220 -0
- package/dist/commands/reg-watch.js.map +1 -0
- package/dist/commands/retro.d.ts +23 -0
- package/dist/commands/retro.d.ts.map +1 -0
- package/dist/commands/retro.js +217 -0
- package/dist/commands/retro.js.map +1 -0
- package/dist/commands/team-leaderboard.d.ts +25 -0
- package/dist/commands/team-leaderboard.d.ts.map +1 -0
- package/dist/commands/team-leaderboard.js +228 -0
- package/dist/commands/team-leaderboard.js.map +1 -0
- package/dist/commands/team-rules-sync.d.ts +8 -0
- package/dist/commands/team-rules-sync.d.ts.map +1 -0
- package/dist/commands/team-rules-sync.js +251 -0
- package/dist/commands/team-rules-sync.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security incident retrospective — analyze whether Judges would have
|
|
3
|
+
* caught a specific vulnerability by running evaluation against
|
|
4
|
+
* historical code state.
|
|
5
|
+
*
|
|
6
|
+
* Uses local git history and evaluation results.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
9
|
+
import { execSync } from "child_process";
|
|
10
|
+
const RETRO_FILE = ".judges-retro.json";
|
|
11
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
12
|
+
function getFileAtCommit(file, commit) {
|
|
13
|
+
try {
|
|
14
|
+
return execSync(`git show ${commit}:${file}`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function checkSuppressions(findings) {
|
|
21
|
+
const suppressionFile = ".judges-suppressions.json";
|
|
22
|
+
if (!existsSync(suppressionFile))
|
|
23
|
+
return { suppressed: false, rules: [] };
|
|
24
|
+
try {
|
|
25
|
+
const data = JSON.parse(readFileSync(suppressionFile, "utf-8"));
|
|
26
|
+
const suppressedRules = [];
|
|
27
|
+
for (const finding of findings) {
|
|
28
|
+
const isSuppressed = (data.suppressions || []).some((s) => s.ruleId === finding.ruleId || (s.rulePrefix && finding.ruleId.startsWith(s.rulePrefix)));
|
|
29
|
+
if (isSuppressed)
|
|
30
|
+
suppressedRules.push(finding.ruleId);
|
|
31
|
+
}
|
|
32
|
+
return { suppressed: suppressedRules.length > 0, rules: suppressedRules };
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { suppressed: false, rules: [] };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function loadResultsForFile(_file) {
|
|
39
|
+
const resultsFile = ".judges-results.json";
|
|
40
|
+
if (!existsSync(resultsFile))
|
|
41
|
+
return [];
|
|
42
|
+
try {
|
|
43
|
+
const data = JSON.parse(readFileSync(resultsFile, "utf-8"));
|
|
44
|
+
const findings = Array.isArray(data) ? data : data.findings || [];
|
|
45
|
+
// Filter findings that might relate to the target file based on ruleId patterns
|
|
46
|
+
return findings;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function runRetroAnalysis(file, commit, cve) {
|
|
53
|
+
let codeContent = null;
|
|
54
|
+
if (commit) {
|
|
55
|
+
codeContent = getFileAtCommit(file, commit);
|
|
56
|
+
}
|
|
57
|
+
else if (existsSync(file)) {
|
|
58
|
+
codeContent = readFileSync(file, "utf-8");
|
|
59
|
+
}
|
|
60
|
+
if (!codeContent) {
|
|
61
|
+
return {
|
|
62
|
+
file,
|
|
63
|
+
commit,
|
|
64
|
+
cve,
|
|
65
|
+
wouldCatch: false,
|
|
66
|
+
matchingFindings: [],
|
|
67
|
+
configWouldSuppress: false,
|
|
68
|
+
analysis: `Could not read file${commit ? ` at commit ${commit}` : ""}.`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Look for vulnerability patterns in the code
|
|
72
|
+
const findings = loadResultsForFile(file);
|
|
73
|
+
// Check for common vulnerability patterns
|
|
74
|
+
const patterns = [
|
|
75
|
+
{
|
|
76
|
+
pattern: /\$\{.*\}.*(?:SELECT|INSERT|UPDATE|DELETE)/i,
|
|
77
|
+
ruleId: "SEC001",
|
|
78
|
+
title: "SQL Injection via template literal",
|
|
79
|
+
severity: "critical",
|
|
80
|
+
},
|
|
81
|
+
{ pattern: /eval\s*\(/, ruleId: "SEC002", title: "Dangerous eval() usage", severity: "critical" },
|
|
82
|
+
{
|
|
83
|
+
pattern: /(?:password|secret|key|token)\s*[:=]\s*['"][^'"]+['"]/i,
|
|
84
|
+
ruleId: "AUTH001",
|
|
85
|
+
title: "Hardcoded credentials",
|
|
86
|
+
severity: "critical",
|
|
87
|
+
},
|
|
88
|
+
{ pattern: /\.innerHTML\s*=/, ruleId: "SEC003", title: "XSS via innerHTML", severity: "high" },
|
|
89
|
+
{ pattern: /exec\s*\(.*\+/, ruleId: "INJECT001", title: "Command injection risk", severity: "critical" },
|
|
90
|
+
{ pattern: /md5|sha1[^-]|DES|RC4/i, ruleId: "CRYPTO001", title: "Weak cryptographic algorithm", severity: "high" },
|
|
91
|
+
{ pattern: /catch\s*\([^)]*\)\s*\{\s*\}/, ruleId: "ERR001", title: "Empty catch block", severity: "medium" },
|
|
92
|
+
{ pattern: /http:\/\/(?!localhost)/, ruleId: "SEC004", title: "Insecure HTTP usage", severity: "medium" },
|
|
93
|
+
{ pattern: /cors\(\s*\)/, ruleId: "SEC005", title: "Overly permissive CORS", severity: "high" },
|
|
94
|
+
{
|
|
95
|
+
pattern: /verify\s*[:=]\s*false|rejectUnauthorized\s*[:=]\s*false/i,
|
|
96
|
+
ruleId: "SEC006",
|
|
97
|
+
title: "TLS verification disabled",
|
|
98
|
+
severity: "critical",
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
const detectedFindings = [];
|
|
102
|
+
const lines = codeContent.split("\n");
|
|
103
|
+
for (const p of patterns) {
|
|
104
|
+
for (let i = 0; i < lines.length; i++) {
|
|
105
|
+
if (p.pattern.test(lines[i])) {
|
|
106
|
+
detectedFindings.push({
|
|
107
|
+
ruleId: p.ruleId,
|
|
108
|
+
title: p.title,
|
|
109
|
+
severity: p.severity,
|
|
110
|
+
description: `Pattern detected at line ${i + 1}: ${lines[i].trim().slice(0, 80)}`,
|
|
111
|
+
recommendation: `Review and remediate ${p.ruleId} finding`,
|
|
112
|
+
lineNumbers: [i + 1],
|
|
113
|
+
confidence: 0.85,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const allFindings = [...findings, ...detectedFindings];
|
|
119
|
+
const { suppressed, rules } = checkSuppressions(allFindings);
|
|
120
|
+
const analysis = allFindings.length > 0
|
|
121
|
+
? `Judges would detect ${allFindings.length} finding(s) in this file.${suppressed ? ` Warning: ${rules.length} finding(s) would be suppressed by current config.` : ""}`
|
|
122
|
+
: "Judges did not detect vulnerability patterns in this file. Consider adding a custom rule.";
|
|
123
|
+
const result = {
|
|
124
|
+
file,
|
|
125
|
+
commit,
|
|
126
|
+
cve,
|
|
127
|
+
wouldCatch: allFindings.length > 0 && !suppressed,
|
|
128
|
+
matchingFindings: allFindings,
|
|
129
|
+
configWouldSuppress: suppressed,
|
|
130
|
+
suppressedBy: suppressed ? rules : undefined,
|
|
131
|
+
analysis,
|
|
132
|
+
};
|
|
133
|
+
// Save retrospective
|
|
134
|
+
const retros = existsSync(RETRO_FILE) ? JSON.parse(readFileSync(RETRO_FILE, "utf-8")) : [];
|
|
135
|
+
retros.push(result);
|
|
136
|
+
writeFileSync(RETRO_FILE, JSON.stringify(retros, null, 2));
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
140
|
+
export function runRetro(argv) {
|
|
141
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
142
|
+
console.log(`
|
|
143
|
+
judges retro — Security incident retrospective
|
|
144
|
+
|
|
145
|
+
Usage:
|
|
146
|
+
judges retro --file src/handler.ts
|
|
147
|
+
judges retro --file src/handler.ts --commit abc123
|
|
148
|
+
judges retro --file src/handler.ts --cve CVE-2025-1234
|
|
149
|
+
judges retro --history
|
|
150
|
+
|
|
151
|
+
Options:
|
|
152
|
+
--file <path> File to analyze
|
|
153
|
+
--commit <sha> Git commit to check (reconstructs code at that point)
|
|
154
|
+
--cve <id> CVE identifier to tag the analysis
|
|
155
|
+
--history Show previous retrospectives
|
|
156
|
+
--format json JSON output
|
|
157
|
+
--help, -h Show this help
|
|
158
|
+
`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
162
|
+
// History
|
|
163
|
+
if (argv.includes("--history")) {
|
|
164
|
+
if (!existsSync(RETRO_FILE)) {
|
|
165
|
+
console.log("\n No retrospectives recorded.\n");
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const retros = JSON.parse(readFileSync(RETRO_FILE, "utf-8"));
|
|
169
|
+
if (format === "json") {
|
|
170
|
+
console.log(JSON.stringify(retros, null, 2));
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
console.log(`\n Retrospective History (${retros.length})\n ─────────────────────────`);
|
|
174
|
+
for (const r of retros) {
|
|
175
|
+
const icon = r.wouldCatch ? "✅" : "❌";
|
|
176
|
+
console.log(` ${icon} ${r.file}${r.commit ? ` @ ${r.commit.slice(0, 7)}` : ""}${r.cve ? ` (${r.cve})` : ""} — ${r.matchingFindings.length} finding(s)`);
|
|
177
|
+
}
|
|
178
|
+
console.log("");
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Run retro
|
|
183
|
+
const file = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
184
|
+
if (!file) {
|
|
185
|
+
console.error(" ❌ Provide --file. Use --help for usage.");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const commit = argv.find((_a, i) => argv[i - 1] === "--commit");
|
|
189
|
+
const cve = argv.find((_a, i) => argv[i - 1] === "--cve");
|
|
190
|
+
const result = runRetroAnalysis(file, commit || undefined, cve || undefined);
|
|
191
|
+
if (format === "json") {
|
|
192
|
+
console.log(JSON.stringify(result, null, 2));
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
const icon = result.wouldCatch ? "✅" : "❌";
|
|
196
|
+
console.log(`\n ${icon} Retrospective Analysis — ${result.file}`);
|
|
197
|
+
if (result.commit)
|
|
198
|
+
console.log(` Commit: ${result.commit}`);
|
|
199
|
+
if (result.cve)
|
|
200
|
+
console.log(` CVE: ${result.cve}`);
|
|
201
|
+
console.log(` ────────────────────────────────`);
|
|
202
|
+
console.log(` Would Judges catch this? ${result.wouldCatch ? "YES" : "NO"}`);
|
|
203
|
+
console.log(` Findings detected: ${result.matchingFindings.length}`);
|
|
204
|
+
if (result.configWouldSuppress) {
|
|
205
|
+
console.log(` ⚠️ Config would suppress: ${(result.suppressedBy || []).join(", ")}`);
|
|
206
|
+
}
|
|
207
|
+
console.log(`\n Analysis: ${result.analysis}`);
|
|
208
|
+
if (result.matchingFindings.length > 0) {
|
|
209
|
+
console.log("\n Detected Findings:");
|
|
210
|
+
for (const f of result.matchingFindings) {
|
|
211
|
+
console.log(` [${f.severity.toUpperCase()}] ${f.ruleId} — ${f.title}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
console.log("");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=retro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retro.js","sourceRoot":"","sources":["../../src/commands/retro.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team leaderboard — gamified security review engagement
|
|
3
|
+
* tracking across developers.
|
|
4
|
+
*
|
|
5
|
+
* All data stays in local .judges-leaderboard/ directory.
|
|
6
|
+
*/
|
|
7
|
+
interface DevStats {
|
|
8
|
+
author: string;
|
|
9
|
+
findingsReviewed: number;
|
|
10
|
+
findingsFixed: number;
|
|
11
|
+
criticalFixed: number;
|
|
12
|
+
scansRun: number;
|
|
13
|
+
streak: number;
|
|
14
|
+
lastActive: string;
|
|
15
|
+
badges: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function recordActivity(author: string, activity: {
|
|
18
|
+
reviewed?: number;
|
|
19
|
+
fixed?: number;
|
|
20
|
+
criticalFixed?: number;
|
|
21
|
+
scansRun?: number;
|
|
22
|
+
}): DevStats;
|
|
23
|
+
export declare function runTeamLeaderboard(argv: string[]): void;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=team-leaderboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-leaderboard.d.ts","sourceRoot":"","sources":["../../src/commands/team-leaderboard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,QAAQ;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAoDD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACzF,QAAQ,CAoCV;AAID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqIvD"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team leaderboard — gamified security review engagement
|
|
3
|
+
* tracking across developers.
|
|
4
|
+
*
|
|
5
|
+
* All data stays in local .judges-leaderboard/ directory.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
const LB_DIR = ".judges-leaderboard";
|
|
10
|
+
const LB_FILE = join(LB_DIR, "leaderboard.json");
|
|
11
|
+
// ─── Badge definitions ──────────────────────────────────────────────────────
|
|
12
|
+
function computeBadges(dev) {
|
|
13
|
+
const badges = [];
|
|
14
|
+
if (dev.scansRun >= 100)
|
|
15
|
+
badges.push("Century Scanner");
|
|
16
|
+
else if (dev.scansRun >= 50)
|
|
17
|
+
badges.push("Veteran Scanner");
|
|
18
|
+
else if (dev.scansRun >= 10)
|
|
19
|
+
badges.push("Active Scanner");
|
|
20
|
+
if (dev.criticalFixed >= 10)
|
|
21
|
+
badges.push("Critical Crusher");
|
|
22
|
+
else if (dev.criticalFixed >= 5)
|
|
23
|
+
badges.push("Bug Buster");
|
|
24
|
+
if (dev.findingsFixed >= 50)
|
|
25
|
+
badges.push("Fix Master");
|
|
26
|
+
else if (dev.findingsFixed >= 20)
|
|
27
|
+
badges.push("Fixer Upper");
|
|
28
|
+
if (dev.streak >= 30)
|
|
29
|
+
badges.push("Monthly Streak");
|
|
30
|
+
else if (dev.streak >= 7)
|
|
31
|
+
badges.push("Weekly Streak");
|
|
32
|
+
if (dev.findingsReviewed >= 100)
|
|
33
|
+
badges.push("Review Champion");
|
|
34
|
+
return badges;
|
|
35
|
+
}
|
|
36
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
37
|
+
function ensureDir() {
|
|
38
|
+
if (!existsSync(LB_DIR))
|
|
39
|
+
mkdirSync(LB_DIR, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
function loadStore() {
|
|
42
|
+
if (!existsSync(LB_FILE))
|
|
43
|
+
return { developers: [], updatedAt: new Date().toISOString() };
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(readFileSync(LB_FILE, "utf-8"));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return { developers: [], updatedAt: new Date().toISOString() };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function saveStore(store) {
|
|
52
|
+
ensureDir();
|
|
53
|
+
store.updatedAt = new Date().toISOString();
|
|
54
|
+
writeFileSync(LB_FILE, JSON.stringify(store, null, 2));
|
|
55
|
+
}
|
|
56
|
+
function sanitizeAuthor(author) {
|
|
57
|
+
return author.replace(/[^a-zA-Z0-9@._-]/g, "_").slice(0, 100);
|
|
58
|
+
}
|
|
59
|
+
export function recordActivity(author, activity) {
|
|
60
|
+
const store = loadStore();
|
|
61
|
+
const safeAuthor = sanitizeAuthor(author);
|
|
62
|
+
let dev = store.developers.find((d) => d.author === safeAuthor);
|
|
63
|
+
if (!dev) {
|
|
64
|
+
dev = {
|
|
65
|
+
author: safeAuthor,
|
|
66
|
+
findingsReviewed: 0,
|
|
67
|
+
findingsFixed: 0,
|
|
68
|
+
criticalFixed: 0,
|
|
69
|
+
scansRun: 0,
|
|
70
|
+
streak: 0,
|
|
71
|
+
lastActive: "",
|
|
72
|
+
badges: [],
|
|
73
|
+
};
|
|
74
|
+
store.developers.push(dev);
|
|
75
|
+
}
|
|
76
|
+
dev.findingsReviewed += activity.reviewed || 0;
|
|
77
|
+
dev.findingsFixed += activity.fixed || 0;
|
|
78
|
+
dev.criticalFixed += activity.criticalFixed || 0;
|
|
79
|
+
dev.scansRun += activity.scansRun || 0;
|
|
80
|
+
// Streak tracking
|
|
81
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
82
|
+
const yesterday = new Date(Date.now() - 86400000).toISOString().slice(0, 10);
|
|
83
|
+
if (dev.lastActive === yesterday || dev.lastActive === today) {
|
|
84
|
+
if (dev.lastActive !== today)
|
|
85
|
+
dev.streak++;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
dev.streak = 1;
|
|
89
|
+
}
|
|
90
|
+
dev.lastActive = today;
|
|
91
|
+
dev.badges = computeBadges(dev);
|
|
92
|
+
saveStore(store);
|
|
93
|
+
return dev;
|
|
94
|
+
}
|
|
95
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
96
|
+
export function runTeamLeaderboard(argv) {
|
|
97
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
98
|
+
console.log(`
|
|
99
|
+
judges team-leaderboard — Gamified security review engagement
|
|
100
|
+
|
|
101
|
+
Usage:
|
|
102
|
+
judges team-leaderboard
|
|
103
|
+
judges team-leaderboard --record --author "alice@co.com" --reviewed 5 --fixed 3
|
|
104
|
+
judges team-leaderboard --author "alice@co.com"
|
|
105
|
+
judges team-leaderboard --top 5
|
|
106
|
+
judges team-leaderboard --badges
|
|
107
|
+
|
|
108
|
+
Options:
|
|
109
|
+
--record Record developer activity
|
|
110
|
+
--author <email> Developer identifier
|
|
111
|
+
--reviewed <n> Findings reviewed count
|
|
112
|
+
--fixed <n> Findings fixed count
|
|
113
|
+
--critical-fixed <n> Critical findings fixed count
|
|
114
|
+
--scans <n> Scans run count
|
|
115
|
+
--top <n> Show top N developers (default: 10)
|
|
116
|
+
--badges Show badge catalog
|
|
117
|
+
--format json JSON output
|
|
118
|
+
--help, -h Show this help
|
|
119
|
+
`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
123
|
+
// Badge catalog
|
|
124
|
+
if (argv.includes("--badges")) {
|
|
125
|
+
const catalog = [
|
|
126
|
+
{ badge: "Century Scanner", requirement: "100+ scans run" },
|
|
127
|
+
{ badge: "Veteran Scanner", requirement: "50+ scans run" },
|
|
128
|
+
{ badge: "Active Scanner", requirement: "10+ scans run" },
|
|
129
|
+
{ badge: "Critical Crusher", requirement: "10+ critical findings fixed" },
|
|
130
|
+
{ badge: "Bug Buster", requirement: "5+ critical findings fixed" },
|
|
131
|
+
{ badge: "Fix Master", requirement: "50+ findings fixed" },
|
|
132
|
+
{ badge: "Fixer Upper", requirement: "20+ findings fixed" },
|
|
133
|
+
{ badge: "Monthly Streak", requirement: "30+ day activity streak" },
|
|
134
|
+
{ badge: "Weekly Streak", requirement: "7+ day activity streak" },
|
|
135
|
+
{ badge: "Review Champion", requirement: "100+ findings reviewed" },
|
|
136
|
+
];
|
|
137
|
+
if (format === "json") {
|
|
138
|
+
console.log(JSON.stringify(catalog, null, 2));
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
console.log(`\n Badge Catalog\n ──────────────────────────`);
|
|
142
|
+
for (const b of catalog) {
|
|
143
|
+
console.log(` 🏆 ${b.badge.padEnd(20)} ${b.requirement}`);
|
|
144
|
+
}
|
|
145
|
+
console.log("");
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Record activity
|
|
150
|
+
if (argv.includes("--record")) {
|
|
151
|
+
const author = argv.find((_a, i) => argv[i - 1] === "--author");
|
|
152
|
+
if (!author) {
|
|
153
|
+
console.error(" --author required for --record");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const reviewed = parseInt(argv.find((_a, i) => argv[i - 1] === "--reviewed") || "0", 10);
|
|
157
|
+
const fixed = parseInt(argv.find((_a, i) => argv[i - 1] === "--fixed") || "0", 10);
|
|
158
|
+
const criticalFixed = parseInt(argv.find((_a, i) => argv[i - 1] === "--critical-fixed") || "0", 10);
|
|
159
|
+
const scansRun = parseInt(argv.find((_a, i) => argv[i - 1] === "--scans") || "0", 10);
|
|
160
|
+
const dev = recordActivity(author, { reviewed, fixed, criticalFixed, scansRun });
|
|
161
|
+
if (format === "json") {
|
|
162
|
+
console.log(JSON.stringify(dev, null, 2));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(`\n ✅ Activity recorded for ${dev.author}`);
|
|
166
|
+
console.log(` Reviewed: ${dev.findingsReviewed} | Fixed: ${dev.findingsFixed} | Streak: ${dev.streak}`);
|
|
167
|
+
if (dev.badges.length > 0)
|
|
168
|
+
console.log(` Badges: ${dev.badges.join(", ")}`);
|
|
169
|
+
console.log("");
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// Individual stats
|
|
174
|
+
const author = argv.find((_a, i) => argv[i - 1] === "--author");
|
|
175
|
+
if (author) {
|
|
176
|
+
const store = loadStore();
|
|
177
|
+
const dev = store.developers.find((d) => d.author === sanitizeAuthor(author));
|
|
178
|
+
if (!dev) {
|
|
179
|
+
console.error(` Developer not found: ${author}`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (format === "json") {
|
|
183
|
+
console.log(JSON.stringify(dev, null, 2));
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.log(`\n Developer Stats — ${dev.author}`);
|
|
187
|
+
console.log(` ──────────────────────────`);
|
|
188
|
+
console.log(` Reviewed: ${dev.findingsReviewed}`);
|
|
189
|
+
console.log(` Fixed: ${dev.findingsFixed}`);
|
|
190
|
+
console.log(` Critical fixed: ${dev.criticalFixed}`);
|
|
191
|
+
console.log(` Scans: ${dev.scansRun}`);
|
|
192
|
+
console.log(` Streak: ${dev.streak} days`);
|
|
193
|
+
console.log(` Badges: ${dev.badges.join(", ") || "none yet"}`);
|
|
194
|
+
console.log("");
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Leaderboard
|
|
199
|
+
const topN = parseInt(argv.find((_a, i) => argv[i - 1] === "--top") || "10", 10);
|
|
200
|
+
const store = loadStore();
|
|
201
|
+
const sorted = [...store.developers].sort((a, b) => {
|
|
202
|
+
// Score: fixed * 3 + reviewed + criticalFixed * 5
|
|
203
|
+
const scoreA = a.findingsFixed * 3 + a.findingsReviewed + a.criticalFixed * 5;
|
|
204
|
+
const scoreB = b.findingsFixed * 3 + b.findingsReviewed + b.criticalFixed * 5;
|
|
205
|
+
return scoreB - scoreA;
|
|
206
|
+
});
|
|
207
|
+
const top = sorted.slice(0, topN);
|
|
208
|
+
if (format === "json") {
|
|
209
|
+
console.log(JSON.stringify(top, null, 2));
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
console.log(`\n Team Leaderboard (top ${topN})\n ──────────────────────────`);
|
|
213
|
+
if (top.length === 0) {
|
|
214
|
+
console.log(" No data yet. Record activity with --record first.");
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
top.forEach((dev, i) => {
|
|
218
|
+
const score = dev.findingsFixed * 3 + dev.findingsReviewed + dev.criticalFixed * 5;
|
|
219
|
+
const medal = i === 0 ? "🥇" : i === 1 ? "🥈" : i === 2 ? "🥉" : " ";
|
|
220
|
+
console.log(` ${medal} #${(i + 1).toString().padEnd(3)} ${dev.author.padEnd(25)} score: ${score.toString().padEnd(6)} streak: ${dev.streak}d`);
|
|
221
|
+
if (dev.badges.length)
|
|
222
|
+
console.log(` Badges: ${dev.badges.join(", ")}`);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
console.log("");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=team-leaderboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-leaderboard.js","sourceRoot":"","sources":["../../src/commands/team-leaderboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team rules sync — fast onboarding by pulling org rules from a
|
|
3
|
+
* shared config file or Git repo's .judgesrc.
|
|
4
|
+
*
|
|
5
|
+
* All config is read-only; stored locally only.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runTeamRulesSync(argv: string[]): void;
|
|
8
|
+
//# sourceMappingURL=team-rules-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-rules-sync.d.ts","sourceRoot":"","sources":["../../src/commands/team-rules-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+IH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmIrD"}
|