@kevinrabun/judges 3.47.0 → 3.49.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 (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +112 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/audit-trail.d.ts +18 -0
  6. package/dist/commands/audit-trail.d.ts.map +1 -0
  7. package/dist/commands/audit-trail.js +155 -0
  8. package/dist/commands/audit-trail.js.map +1 -0
  9. package/dist/commands/auto-fix.d.ts +18 -0
  10. package/dist/commands/auto-fix.d.ts.map +1 -0
  11. package/dist/commands/auto-fix.js +241 -0
  12. package/dist/commands/auto-fix.js.map +1 -0
  13. package/dist/commands/dep-correlate.d.ts +9 -0
  14. package/dist/commands/dep-correlate.d.ts.map +1 -0
  15. package/dist/commands/dep-correlate.js +208 -0
  16. package/dist/commands/dep-correlate.js.map +1 -0
  17. package/dist/commands/doc-gen.d.ts +8 -0
  18. package/dist/commands/doc-gen.d.ts.map +1 -0
  19. package/dist/commands/doc-gen.js +209 -0
  20. package/dist/commands/doc-gen.js.map +1 -0
  21. package/dist/commands/incident-response.d.ts +8 -0
  22. package/dist/commands/incident-response.d.ts.map +1 -0
  23. package/dist/commands/incident-response.js +255 -0
  24. package/dist/commands/incident-response.js.map +1 -0
  25. package/dist/commands/judge-author.d.ts +8 -0
  26. package/dist/commands/judge-author.d.ts.map +1 -0
  27. package/dist/commands/judge-author.js +261 -0
  28. package/dist/commands/judge-author.js.map +1 -0
  29. package/dist/commands/learning-path.d.ts +9 -0
  30. package/dist/commands/learning-path.d.ts.map +1 -0
  31. package/dist/commands/learning-path.js +326 -0
  32. package/dist/commands/learning-path.js.map +1 -0
  33. package/dist/commands/license-scan.d.ts +9 -0
  34. package/dist/commands/license-scan.d.ts.map +1 -0
  35. package/dist/commands/license-scan.js +180 -0
  36. package/dist/commands/license-scan.js.map +1 -0
  37. package/dist/commands/org-policy.d.ts +8 -0
  38. package/dist/commands/org-policy.d.ts.map +1 -0
  39. package/dist/commands/org-policy.js +208 -0
  40. package/dist/commands/org-policy.js.map +1 -0
  41. package/dist/commands/pattern-registry.d.ts +23 -0
  42. package/dist/commands/pattern-registry.d.ts.map +1 -0
  43. package/dist/commands/pattern-registry.js +227 -0
  44. package/dist/commands/pattern-registry.js.map +1 -0
  45. package/dist/commands/perf-hotspot.d.ts +8 -0
  46. package/dist/commands/perf-hotspot.d.ts.map +1 -0
  47. package/dist/commands/perf-hotspot.js +274 -0
  48. package/dist/commands/perf-hotspot.js.map +1 -0
  49. package/dist/commands/predict.d.ts +8 -0
  50. package/dist/commands/predict.d.ts.map +1 -0
  51. package/dist/commands/predict.js +219 -0
  52. package/dist/commands/predict.js.map +1 -0
  53. package/dist/commands/risk-heatmap.d.ts +8 -0
  54. package/dist/commands/risk-heatmap.d.ts.map +1 -0
  55. package/dist/commands/risk-heatmap.js +224 -0
  56. package/dist/commands/risk-heatmap.js.map +1 -0
  57. package/dist/commands/sbom-export.d.ts +8 -0
  58. package/dist/commands/sbom-export.d.ts.map +1 -0
  59. package/dist/commands/sbom-export.js +162 -0
  60. package/dist/commands/sbom-export.js.map +1 -0
  61. package/dist/commands/security-maturity.d.ts +8 -0
  62. package/dist/commands/security-maturity.d.ts.map +1 -0
  63. package/dist/commands/security-maturity.js +313 -0
  64. package/dist/commands/security-maturity.js.map +1 -0
  65. package/dist/commands/test-correlate.d.ts +8 -0
  66. package/dist/commands/test-correlate.d.ts.map +1 -0
  67. package/dist/commands/test-correlate.js +222 -0
  68. package/dist/commands/test-correlate.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Custom judge authoring toolkit — scaffolds, validates,
3
+ * and tests new judge definitions.
4
+ *
5
+ * All data stored locally.
6
+ */
7
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from "fs";
8
+ import { join } from "path";
9
+ import { defaultRegistry } from "../judge-registry.js";
10
+ // ─── Scaffold ───────────────────────────────────────────────────────────────
11
+ function scaffoldJudge(id, opts) {
12
+ return {
13
+ id,
14
+ name: opts.name || id.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
15
+ description: `Custom judge: ${id}`,
16
+ category: opts.category || "custom",
17
+ severity: opts.severity || "medium",
18
+ rules: [
19
+ {
20
+ id: `${id}-001`,
21
+ pattern: "TODO: define pattern",
22
+ message: "TODO: describe what this rule detects",
23
+ severity: opts.severity || "medium",
24
+ },
25
+ ],
26
+ };
27
+ }
28
+ function generateJudgeFile(scaffold) {
29
+ return `/**
30
+ * ${scaffold.name}
31
+ *
32
+ * ${scaffold.description}
33
+ * Category: ${scaffold.category}
34
+ */
35
+
36
+ import type { Finding } from "../types.js";
37
+
38
+ export const judgeId = "${scaffold.id}";
39
+ export const judgeName = "${scaffold.name}";
40
+ export const judgeDescription = "${scaffold.description}";
41
+ export const judgeCategory = "${scaffold.category}";
42
+
43
+ interface Rule {
44
+ id: string;
45
+ pattern: RegExp;
46
+ message: string;
47
+ severity: string;
48
+ }
49
+
50
+ const rules: Rule[] = [
51
+ ${scaffold.rules
52
+ .map((r) => ` {
53
+ id: "${r.id}",
54
+ pattern: /${r.pattern.replace(/\//g, "\\/")}/g,
55
+ message: "${r.message}",
56
+ severity: "${r.severity}",
57
+ },`)
58
+ .join("\n")}
59
+ ];
60
+
61
+ export function evaluate(code: string, _filename: string): Finding[] {
62
+ const findings: Finding[] = [];
63
+ const lines = code.split("\\n");
64
+
65
+ for (const rule of rules) {
66
+ for (let i = 0; i < lines.length; i++) {
67
+ if (rule.pattern.test(lines[i])) {
68
+ findings.push({
69
+ ruleId: rule.id,
70
+ severity: rule.severity as Finding["severity"],
71
+ title: rule.message,
72
+ description: \`Detected by custom judge \${judgeId} at line \${i + 1}\`,
73
+ lineNumbers: [i + 1],
74
+ recommendation: "Review and fix the detected pattern",
75
+ });
76
+ rule.pattern.lastIndex = 0; // reset global regex
77
+ }
78
+ }
79
+ }
80
+
81
+ return findings;
82
+ }
83
+ `;
84
+ }
85
+ // ─── Validation ─────────────────────────────────────────────────────────────
86
+ function validateJudge(path) {
87
+ const errors = [];
88
+ const warnings = [];
89
+ if (!existsSync(path)) {
90
+ return { valid: false, errors: [`File not found: ${path}`], warnings: [] };
91
+ }
92
+ let content;
93
+ try {
94
+ content = readFileSync(path, "utf-8");
95
+ }
96
+ catch {
97
+ return { valid: false, errors: [`Cannot read file: ${path}`], warnings: [] };
98
+ }
99
+ // Check for required exports
100
+ if (!content.includes("export const judgeId"))
101
+ errors.push("Missing 'export const judgeId'");
102
+ if (!content.includes("export const judgeName"))
103
+ errors.push("Missing 'export const judgeName'");
104
+ if (!content.includes("export function evaluate"))
105
+ errors.push("Missing 'export function evaluate'");
106
+ // Check for Finding type
107
+ if (!content.includes("Finding"))
108
+ warnings.push("No reference to Finding type — ensure findings match expected shape");
109
+ // Check for severity values
110
+ const validSeverities = ["critical", "high", "medium", "low", "info"];
111
+ const sevMatches = content.match(/severity:\s*["'](\w+)["']/g) || [];
112
+ for (const m of sevMatches) {
113
+ const val = m.match(/["'](\w+)["']/)?.[1];
114
+ if (val && !validSeverities.includes(val)) {
115
+ errors.push(`Invalid severity '${val}' — must be: ${validSeverities.join(", ")}`);
116
+ }
117
+ }
118
+ // Check for rule IDs
119
+ const ruleIds = content.match(/id:\s*["']([^"']+)["']/g) || [];
120
+ if (ruleIds.length === 0)
121
+ warnings.push("No rule IDs found — each rule should have a unique id");
122
+ return { valid: errors.length === 0, errors, warnings };
123
+ }
124
+ // ─── CLI ────────────────────────────────────────────────────────────────────
125
+ const STORE = ".judges-custom";
126
+ export function runJudgeAuthor(argv) {
127
+ if (argv.includes("--help") || argv.includes("-h")) {
128
+ console.log(`
129
+ judges judge-author — Custom judge authoring toolkit
130
+
131
+ Usage:
132
+ judges judge-author --scaffold <id>
133
+ judges judge-author --validate <file>
134
+ judges judge-author --list
135
+ judges judge-author --test <file> --code <sample>
136
+
137
+ Options:
138
+ --scaffold <id> Generate a new judge scaffold
139
+ --name <name> Judge display name
140
+ --category <cat> Category (default: custom)
141
+ --severity <sev> Default severity (default: medium)
142
+ --validate <file> Validate judge file structure
143
+ --list List existing custom judges
144
+ --test <file> Test a judge against sample code
145
+ --code <sample> Sample code file to test against
146
+ --output <dir> Output directory (default: .judges-custom)
147
+ --format json JSON output
148
+ --help, -h Show this help
149
+ `);
150
+ return;
151
+ }
152
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
153
+ // List existing judges
154
+ if (argv.includes("--list")) {
155
+ const builtin = defaultRegistry.getJudges();
156
+ const customDir = STORE;
157
+ let customCount = 0;
158
+ if (existsSync(customDir)) {
159
+ try {
160
+ const { readdirSync } = require("fs");
161
+ customCount = readdirSync(customDir).filter((f) => f.endsWith(".ts") || f.endsWith(".json")).length;
162
+ }
163
+ catch {
164
+ /* skip */
165
+ }
166
+ }
167
+ if (format === "json") {
168
+ console.log(JSON.stringify({ builtin: builtin.length, custom: customCount, judges: builtin.map((j) => j.id) }, null, 2));
169
+ }
170
+ else {
171
+ console.log(`\n Judges Registry\n ──────────────────────────`);
172
+ console.log(` Built-in: ${builtin.length}`);
173
+ console.log(` Custom: ${customCount}`);
174
+ console.log(`\n Built-in judges:`);
175
+ for (const j of builtin) {
176
+ console.log(` ${j.id}`);
177
+ }
178
+ console.log("");
179
+ }
180
+ return;
181
+ }
182
+ // Scaffold
183
+ const scaffoldId = argv.find((_a, i) => argv[i - 1] === "--scaffold");
184
+ if (scaffoldId) {
185
+ const name = argv.find((_a, i) => argv[i - 1] === "--name");
186
+ const category = argv.find((_a, i) => argv[i - 1] === "--category");
187
+ const severity = argv.find((_a, i) => argv[i - 1] === "--severity");
188
+ const outputDir = argv.find((_a, i) => argv[i - 1] === "--output") || STORE;
189
+ const scaffold = scaffoldJudge(scaffoldId, {
190
+ name: name || undefined,
191
+ category: category || undefined,
192
+ severity: severity || undefined,
193
+ });
194
+ const code = generateJudgeFile(scaffold);
195
+ if (!existsSync(outputDir))
196
+ mkdirSync(outputDir, { recursive: true });
197
+ const outPath = join(outputDir, `${scaffoldId}.ts`);
198
+ writeFileSync(outPath, code);
199
+ // Also write the JSON definition
200
+ const jsonPath = join(outputDir, `${scaffoldId}.json`);
201
+ writeFileSync(jsonPath, JSON.stringify(scaffold, null, 2));
202
+ if (format === "json") {
203
+ console.log(JSON.stringify({ scaffold, files: [outPath, jsonPath] }, null, 2));
204
+ }
205
+ else {
206
+ console.log(`\n Judge Scaffolded: ${scaffoldId}\n ──────────────────────────`);
207
+ console.log(` TypeScript: ${outPath}`);
208
+ console.log(` Definition: ${jsonPath}`);
209
+ console.log(`\n Next steps:`);
210
+ console.log(` 1. Edit ${outPath} to add detection patterns`);
211
+ console.log(` 2. Validate with: judges judge-author --validate ${outPath}`);
212
+ console.log(` 3. Test with: judges judge-author --test ${outPath} --code sample.ts\n`);
213
+ }
214
+ return;
215
+ }
216
+ // Validate
217
+ const validatePath = argv.find((_a, i) => argv[i - 1] === "--validate");
218
+ if (validatePath) {
219
+ const result = validateJudge(validatePath);
220
+ if (format === "json") {
221
+ console.log(JSON.stringify(result, null, 2));
222
+ }
223
+ else {
224
+ console.log(`\n Validation: ${validatePath}`);
225
+ console.log(` Status: ${result.valid ? "✅ Valid" : "❌ Invalid"}\n ──────────────────────────`);
226
+ for (const e of result.errors)
227
+ console.log(` ❌ ${e}`);
228
+ for (const w of result.warnings)
229
+ console.log(` ⚠️ ${w}`);
230
+ if (result.valid && result.warnings.length === 0)
231
+ console.log(` All checks passed`);
232
+ console.log("");
233
+ }
234
+ return;
235
+ }
236
+ // Test
237
+ const testPath = argv.find((_a, i) => argv[i - 1] === "--test");
238
+ const codePath = argv.find((_a, i) => argv[i - 1] === "--code");
239
+ if (testPath) {
240
+ if (!codePath || !existsSync(codePath)) {
241
+ console.error(" Provide --code <file> with a sample code file to test against.");
242
+ return;
243
+ }
244
+ // Validate first
245
+ const validation = validateJudge(testPath);
246
+ if (!validation.valid) {
247
+ console.error(" Judge file has validation errors. Fix errors before testing.");
248
+ for (const e of validation.errors)
249
+ console.error(` ❌ ${e}`);
250
+ return;
251
+ }
252
+ console.log(`\n Testing ${testPath} against ${codePath}`);
253
+ console.log(` (Note: full testing requires loading the judge module at runtime)\n`);
254
+ console.log(` Validation: ✅ Passed`);
255
+ console.log(` Structure: ✅ Valid`);
256
+ console.log(`\n To run a full test, import and call the evaluate() function directly.\n`);
257
+ return;
258
+ }
259
+ console.log(" Use --scaffold, --validate, --list, or --test. Run --help for details.");
260
+ }
261
+ //# sourceMappingURL=judge-author.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge-author.js","sourceRoot":"","sources":["../../src/commands/judge-author.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Learning path — generates personalized developer learning
3
+ * modules from recurring finding patterns, tracking skill
4
+ * progression over time.
5
+ *
6
+ * All data stored locally.
7
+ */
8
+ export declare function runLearningPath(argv: string[]): void;
9
+ //# sourceMappingURL=learning-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learning-path.d.ts","sourceRoot":"","sources":["../../src/commands/learning-path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgNH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4JpD"}
@@ -0,0 +1,326 @@
1
+ /**
2
+ * Learning path — generates personalized developer learning
3
+ * modules from recurring finding patterns, tracking skill
4
+ * progression over time.
5
+ *
6
+ * All data stored locally.
7
+ */
8
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from "fs";
9
+ import { join } from "path";
10
+ // ─── Module Library ─────────────────────────────────────────────────────────
11
+ const MODULES = [
12
+ {
13
+ id: "sql-injection-101",
14
+ topic: "SQL Injection Prevention",
15
+ difficulty: "beginner",
16
+ description: "Learn to identify and prevent SQL injection vulnerabilities",
17
+ resources: [
18
+ "OWASP SQL Injection Prevention Cheat Sheet",
19
+ "Use parameterized queries instead of string concatenation",
20
+ "Apply input validation at system boundaries",
21
+ ],
22
+ exercises: [
23
+ "Refactor a string-concatenated query to use parameterized statements",
24
+ "Identify SQL injection vectors in a sample CRUD controller",
25
+ "Implement an ORM-based data access layer",
26
+ ],
27
+ prerequisites: [],
28
+ },
29
+ {
30
+ id: "xss-prevention",
31
+ topic: "Cross-Site Scripting (XSS) Prevention",
32
+ difficulty: "beginner",
33
+ description: "Understand and prevent XSS vulnerabilities in web applications",
34
+ resources: [
35
+ "OWASP XSS Prevention Cheat Sheet",
36
+ "Content Security Policy (CSP) headers",
37
+ "Output encoding for different contexts (HTML, JS, URL, CSS)",
38
+ ],
39
+ exercises: [
40
+ "Add output encoding to a template rendering user input",
41
+ "Configure CSP headers for a web application",
42
+ "Test for DOM-based XSS in a client-side application",
43
+ ],
44
+ prerequisites: [],
45
+ },
46
+ {
47
+ id: "auth-security",
48
+ topic: "Authentication & Authorization",
49
+ difficulty: "intermediate",
50
+ description: "Implement secure authentication and authorization patterns",
51
+ resources: [
52
+ "OWASP Authentication Cheat Sheet",
53
+ "JWT best practices and pitfalls",
54
+ "OAuth 2.0 and OpenID Connect fundamentals",
55
+ ],
56
+ exercises: [
57
+ "Implement rate limiting on login endpoints",
58
+ "Add proper JWT validation with signature verification",
59
+ "Design role-based access control for an API",
60
+ ],
61
+ prerequisites: ["sql-injection-101"],
62
+ },
63
+ {
64
+ id: "crypto-basics",
65
+ topic: "Cryptography Fundamentals",
66
+ difficulty: "intermediate",
67
+ description: "Use cryptographic primitives correctly",
68
+ resources: [
69
+ "OWASP Cryptographic Storage Cheat Sheet",
70
+ "Modern cipher suites and key management",
71
+ "Password hashing: bcrypt, scrypt, Argon2",
72
+ ],
73
+ exercises: [
74
+ "Replace MD5/SHA-1 with SHA-256 or better",
75
+ "Implement proper password hashing with Argon2",
76
+ "Set up encrypted-at-rest storage for sensitive data",
77
+ ],
78
+ prerequisites: [],
79
+ },
80
+ {
81
+ id: "ssrf-prevention",
82
+ topic: "Server-Side Request Forgery (SSRF)",
83
+ difficulty: "advanced",
84
+ description: "Prevent SSRF attacks in web applications",
85
+ resources: [
86
+ "OWASP SSRF Prevention Cheat Sheet",
87
+ "URL validation and allowlisting strategies",
88
+ "Network segmentation for defense in depth",
89
+ ],
90
+ exercises: [
91
+ "Implement URL validation with an allowlist",
92
+ "Block internal IP ranges in outbound requests",
93
+ "Design a secure proxy service for external API calls",
94
+ ],
95
+ prerequisites: ["auth-security"],
96
+ },
97
+ {
98
+ id: "supply-chain",
99
+ topic: "Supply Chain Security",
100
+ difficulty: "advanced",
101
+ description: "Secure the software supply chain",
102
+ resources: [
103
+ "SLSA framework for supply chain integrity",
104
+ "Dependency pinning and lock file management",
105
+ "SBOM generation and consumption",
106
+ ],
107
+ exercises: [
108
+ "Generate an SBOM with `judges sbom-export`",
109
+ "Audit dependencies with `judges dep-correlate`",
110
+ "Set up automated dependency update policies",
111
+ ],
112
+ prerequisites: ["crypto-basics"],
113
+ },
114
+ {
115
+ id: "secure-code-review",
116
+ topic: "Secure Code Review Practices",
117
+ difficulty: "intermediate",
118
+ description: "Conduct effective security-focused code reviews",
119
+ resources: [
120
+ "OWASP Code Review Guide",
121
+ "Common vulnerability patterns by language",
122
+ "Using Judges for automated security review",
123
+ ],
124
+ exercises: [
125
+ "Review a sample PR for security issues using Judges",
126
+ "Create a custom judge with `judges judge-author`",
127
+ "Build a team pattern library with `judges pattern-registry`",
128
+ ],
129
+ prerequisites: ["sql-injection-101", "xss-prevention"],
130
+ },
131
+ {
132
+ id: "incident-handling",
133
+ topic: "Security Incident Handling",
134
+ difficulty: "advanced",
135
+ description: "Respond to and manage security incidents",
136
+ resources: [
137
+ "NIST Incident Response Guide",
138
+ "Post-incident review best practices",
139
+ "Using `judges incident-response` for playbook generation",
140
+ ],
141
+ exercises: [
142
+ "Create an incident response playbook for a critical finding",
143
+ "Conduct a tabletop exercise with the team",
144
+ "Set up SLA tracking with `judges sla-track`",
145
+ ],
146
+ prerequisites: ["secure-code-review", "auth-security"],
147
+ },
148
+ ];
149
+ // ─── Analysis ───────────────────────────────────────────────────────────────
150
+ const TOPIC_PATTERNS = {
151
+ "SQL Injection Prevention": ["sql", "injection", "query", "database"],
152
+ "Cross-Site Scripting (XSS) Prevention": ["xss", "cross-site", "script", "sanitize", "encode"],
153
+ "Authentication & Authorization": ["auth", "login", "password", "token", "jwt", "session", "rbac"],
154
+ "Cryptography Fundamentals": ["crypto", "cipher", "hash", "encrypt", "md5", "sha1", "key"],
155
+ "Server-Side Request Forgery (SSRF)": ["ssrf", "request-forgery", "url", "redirect"],
156
+ "Supply Chain Security": ["dependency", "package", "npm", "supply-chain", "sbom"],
157
+ "Secure Code Review Practices": ["review", "code-quality", "pattern"],
158
+ "Security Incident Handling": ["incident", "breach", "response", "escalation"],
159
+ };
160
+ function analyzeWeaknesses(findings) {
161
+ const topicCounts = new Map();
162
+ for (const f of findings) {
163
+ const text = `${f.ruleId} ${f.title}`.toLowerCase();
164
+ for (const [topic, patterns] of Object.entries(TOPIC_PATTERNS)) {
165
+ if (patterns.some((p) => text.includes(p))) {
166
+ topicCounts.set(topic, (topicCounts.get(topic) || 0) + 1);
167
+ }
168
+ }
169
+ }
170
+ return [...topicCounts.entries()]
171
+ .map(([topic, count]) => ({ topic, findingCount: count }))
172
+ .sort((a, b) => b.findingCount - a.findingCount);
173
+ }
174
+ // ─── CLI ────────────────────────────────────────────────────────────────────
175
+ const STORE = ".judges-learning";
176
+ export function runLearningPath(argv) {
177
+ if (argv.includes("--help") || argv.includes("-h")) {
178
+ console.log(`
179
+ judges learning-path — Personalized security learning recommendations
180
+
181
+ Usage:
182
+ judges learning-path
183
+ judges learning-path --developer "alice"
184
+ judges learning-path --modules
185
+ judges learning-path --complete <module-id>
186
+
187
+ Options:
188
+ --developer <name> Developer name for personalized path
189
+ --modules List all available learning modules
190
+ --complete <id> Mark a module as completed
191
+ --reset Reset progress for developer
192
+ --format json JSON output
193
+ --help, -h Show this help
194
+ `);
195
+ return;
196
+ }
197
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
198
+ // List modules
199
+ if (argv.includes("--modules")) {
200
+ if (format === "json") {
201
+ console.log(JSON.stringify(MODULES, null, 2));
202
+ }
203
+ else {
204
+ console.log(`\n Learning Modules (${MODULES.length})\n ──────────────────────────`);
205
+ for (const m of MODULES) {
206
+ console.log(` [${m.difficulty.padEnd(12)}] ${m.id.padEnd(25)} ${m.topic}`);
207
+ }
208
+ console.log("");
209
+ }
210
+ return;
211
+ }
212
+ if (!existsSync(STORE))
213
+ mkdirSync(STORE, { recursive: true });
214
+ const devName = argv.find((_a, i) => argv[i - 1] === "--developer") || "default";
215
+ const progressPath = join(STORE, `${devName}-progress.json`);
216
+ let progress = existsSync(progressPath)
217
+ ? JSON.parse(readFileSync(progressPath, "utf-8"))
218
+ : { developer: devName, completedModules: [], weakAreas: [], skillLevel: 1, lastUpdated: new Date().toISOString() };
219
+ // Reset
220
+ if (argv.includes("--reset")) {
221
+ progress = {
222
+ developer: devName,
223
+ completedModules: [],
224
+ weakAreas: [],
225
+ skillLevel: 1,
226
+ lastUpdated: new Date().toISOString(),
227
+ };
228
+ writeFileSync(progressPath, JSON.stringify(progress, null, 2));
229
+ console.log(` Reset progress for ${devName}`);
230
+ return;
231
+ }
232
+ // Complete module
233
+ const completeId = argv.find((_a, i) => argv[i - 1] === "--complete");
234
+ if (completeId) {
235
+ const mod = MODULES.find((m) => m.id === completeId);
236
+ if (!mod) {
237
+ console.error(` Module ${completeId} not found.`);
238
+ return;
239
+ }
240
+ if (!progress.completedModules.includes(completeId)) {
241
+ progress.completedModules.push(completeId);
242
+ progress.skillLevel = Math.min(10, Math.round((progress.completedModules.length / MODULES.length) * 10));
243
+ progress.lastUpdated = new Date().toISOString();
244
+ writeFileSync(progressPath, JSON.stringify(progress, null, 2));
245
+ }
246
+ console.log(` Completed: ${mod.topic} — Skill level: ${progress.skillLevel}/10`);
247
+ return;
248
+ }
249
+ // Analyze and recommend
250
+ const findings = [];
251
+ const paths = [".judges-findings.json", "judges-report.json"];
252
+ for (const p of paths) {
253
+ if (!existsSync(p))
254
+ continue;
255
+ try {
256
+ const data = JSON.parse(readFileSync(p, "utf-8"));
257
+ if (Array.isArray(data))
258
+ findings.push(...data);
259
+ else if (data.findings)
260
+ findings.push(...data.findings);
261
+ }
262
+ catch {
263
+ /* skip */
264
+ }
265
+ }
266
+ const weakAreas = analyzeWeaknesses(findings);
267
+ progress.weakAreas = weakAreas;
268
+ progress.lastUpdated = new Date().toISOString();
269
+ writeFileSync(progressPath, JSON.stringify(progress, null, 2));
270
+ // Find recommended modules (not completed, prerequisites met)
271
+ const recommended = MODULES.filter((m) => {
272
+ if (progress.completedModules.includes(m.id))
273
+ return false;
274
+ const prereqsMet = m.prerequisites.every((p) => progress.completedModules.includes(p));
275
+ if (!prereqsMet)
276
+ return false;
277
+ // Prioritize modules matching weak areas
278
+ return true;
279
+ });
280
+ // Sort by relevance to weak areas
281
+ const sortedRecs = recommended.sort((a, b) => {
282
+ const aRelevance = weakAreas.find((w) => w.topic === a.topic)?.findingCount || 0;
283
+ const bRelevance = weakAreas.find((w) => w.topic === b.topic)?.findingCount || 0;
284
+ return bRelevance - aRelevance;
285
+ });
286
+ const report = {
287
+ recommendedModules: sortedRecs,
288
+ progress,
289
+ timestamp: new Date().toISOString(),
290
+ };
291
+ if (format === "json") {
292
+ console.log(JSON.stringify(report, null, 2));
293
+ }
294
+ else {
295
+ console.log(`\n Learning Path — ${devName}`);
296
+ console.log(` Skill Level: ${progress.skillLevel}/10 Completed: ${progress.completedModules.length}/${MODULES.length}`);
297
+ console.log(` ──────────────────────────`);
298
+ if (weakAreas.length > 0) {
299
+ console.log(`\n Weak Areas (from findings):`);
300
+ for (const w of weakAreas.slice(0, 5)) {
301
+ console.log(` ${w.topic.padEnd(35)} ${w.findingCount} findings`);
302
+ }
303
+ }
304
+ console.log(`\n Recommended Modules:`);
305
+ if (sortedRecs.length === 0) {
306
+ console.log(` 🎉 All available modules completed!`);
307
+ }
308
+ else {
309
+ for (const m of sortedRecs.slice(0, 5)) {
310
+ const relevant = weakAreas.find((w) => w.topic === m.topic);
311
+ const tag = relevant ? ` (${relevant.findingCount} findings)` : "";
312
+ console.log(` [${m.difficulty.padEnd(12)}] ${m.id}${tag}`);
313
+ console.log(` ${m.topic}`);
314
+ }
315
+ }
316
+ if (progress.completedModules.length > 0) {
317
+ console.log(`\n Completed:`);
318
+ for (const id of progress.completedModules) {
319
+ const mod = MODULES.find((m) => m.id === id);
320
+ console.log(` ✅ ${mod?.topic || id}`);
321
+ }
322
+ }
323
+ console.log("");
324
+ }
325
+ }
326
+ //# sourceMappingURL=learning-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learning-path.js","sourceRoot":"","sources":["../../src/commands/learning-path.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * License scan — scans project dependencies for license
3
+ * compatibility, flags copyleft/unknown licenses, and
4
+ * generates a license obligations report.
5
+ *
6
+ * All data from local files.
7
+ */
8
+ export declare function runLicenseScan(argv: string[]): void;
9
+ //# sourceMappingURL=license-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-scan.d.ts","sourceRoot":"","sources":["../../src/commands/license-scan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiIH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkFnD"}