@kevinrabun/judges 3.87.0 → 3.88.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 (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +63 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-age-analysis.d.ts +5 -0
  6. package/dist/commands/finding-age-analysis.d.ts.map +1 -0
  7. package/dist/commands/finding-age-analysis.js +145 -0
  8. package/dist/commands/finding-age-analysis.js.map +1 -0
  9. package/dist/commands/finding-correlation.d.ts +5 -0
  10. package/dist/commands/finding-correlation.d.ts.map +1 -0
  11. package/dist/commands/finding-correlation.js +104 -0
  12. package/dist/commands/finding-correlation.js.map +1 -0
  13. package/dist/commands/finding-dependency-tree.d.ts +5 -0
  14. package/dist/commands/finding-dependency-tree.d.ts.map +1 -0
  15. package/dist/commands/finding-dependency-tree.js +117 -0
  16. package/dist/commands/finding-dependency-tree.js.map +1 -0
  17. package/dist/commands/finding-suppression-audit.d.ts +5 -0
  18. package/dist/commands/finding-suppression-audit.d.ts.map +1 -0
  19. package/dist/commands/finding-suppression-audit.js +138 -0
  20. package/dist/commands/finding-suppression-audit.js.map +1 -0
  21. package/dist/commands/review-ci-integration.d.ts +5 -0
  22. package/dist/commands/review-ci-integration.d.ts.map +1 -0
  23. package/dist/commands/review-ci-integration.js +126 -0
  24. package/dist/commands/review-ci-integration.js.map +1 -0
  25. package/dist/commands/review-comparative.d.ts +5 -0
  26. package/dist/commands/review-comparative.d.ts.map +1 -0
  27. package/dist/commands/review-comparative.js +150 -0
  28. package/dist/commands/review-comparative.js.map +1 -0
  29. package/dist/commands/review-custom-rule.d.ts +5 -0
  30. package/dist/commands/review-custom-rule.d.ts.map +1 -0
  31. package/dist/commands/review-custom-rule.js +170 -0
  32. package/dist/commands/review-custom-rule.js.map +1 -0
  33. package/dist/commands/review-notification.d.ts +5 -0
  34. package/dist/commands/review-notification.d.ts.map +1 -0
  35. package/dist/commands/review-notification.js +127 -0
  36. package/dist/commands/review-notification.js.map +1 -0
  37. package/dist/commands/review-template-export.d.ts +5 -0
  38. package/dist/commands/review-template-export.d.ts.map +1 -0
  39. package/dist/commands/review-template-export.js +147 -0
  40. package/dist/commands/review-template-export.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Review-ci-integration — Generate CI pipeline configuration for Judges.
3
+ */
4
+ import { existsSync, writeFileSync } from "fs";
5
+ // ─── Templates ──────────────────────────────────────────────────────────────
6
+ function githubActionsTemplate() {
7
+ return `name: Judges Review
8
+ on:
9
+ pull_request:
10
+ types: [opened, synchronize]
11
+
12
+ permissions:
13
+ contents: read
14
+ pull-requests: write
15
+
16
+ jobs:
17
+ review:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-node@v4
22
+ with:
23
+ node-version: '20'
24
+ - run: npm install -g @kevinrabun/judges
25
+ - run: judges eval --file \${{ github.event.pull_request.head.sha }} --format sarif --output judges-report.sarif
26
+ - uses: github/codeql-action/upload-sarif@v3
27
+ if: always()
28
+ with:
29
+ sarif_file: judges-report.sarif
30
+ `;
31
+ }
32
+ function azurePipelinesTemplate() {
33
+ return `trigger:
34
+ branches:
35
+ include:
36
+ - main
37
+ pr:
38
+ branches:
39
+ include:
40
+ - main
41
+
42
+ pool:
43
+ vmImage: 'ubuntu-latest'
44
+
45
+ steps:
46
+ - task: NodeTool@0
47
+ inputs:
48
+ versionSpec: '20.x'
49
+ - script: npm install -g @kevinrabun/judges
50
+ displayName: 'Install Judges'
51
+ - script: judges eval --format sarif --output judges-report.sarif
52
+ displayName: 'Run Judges Review'
53
+ - task: PublishBuildArtifacts@1
54
+ inputs:
55
+ pathtoPublish: judges-report.sarif
56
+ artifactName: judges-report
57
+ `;
58
+ }
59
+ function gitlabCiTemplate() {
60
+ return `judges-review:
61
+ image: node:20
62
+ stage: test
63
+ script:
64
+ - npm install -g @kevinrabun/judges
65
+ - judges eval --format sarif --output judges-report.sarif
66
+ artifacts:
67
+ reports:
68
+ sast: judges-report.sarif
69
+ paths:
70
+ - judges-report.sarif
71
+ `;
72
+ }
73
+ // ─── CLI ────────────────────────────────────────────────────────────────────
74
+ export function runReviewCiIntegration(argv) {
75
+ const platformIdx = argv.indexOf("--platform");
76
+ const outputIdx = argv.indexOf("--output");
77
+ const platform = platformIdx >= 0 ? argv[platformIdx + 1] : "github";
78
+ const outputPath = outputIdx >= 0 ? argv[outputIdx + 1] : undefined;
79
+ if (argv.includes("--help") || argv.includes("-h")) {
80
+ console.log(`
81
+ judges review-ci-integration — Generate CI pipeline configuration
82
+
83
+ Usage:
84
+ judges review-ci-integration [--platform github|azure|gitlab]
85
+ [--output <file>]
86
+
87
+ Options:
88
+ --platform <type> CI platform: github (default), azure, gitlab
89
+ --output <path> Write config to file
90
+ --help, -h Show this help
91
+ `);
92
+ return;
93
+ }
94
+ let template;
95
+ let defaultFile;
96
+ switch (platform) {
97
+ case "azure":
98
+ template = azurePipelinesTemplate();
99
+ defaultFile = "azure-pipelines.yml";
100
+ break;
101
+ case "gitlab":
102
+ template = gitlabCiTemplate();
103
+ defaultFile = ".gitlab-ci.yml";
104
+ break;
105
+ default:
106
+ template = githubActionsTemplate();
107
+ defaultFile = ".github/workflows/judges-review.yml";
108
+ break;
109
+ }
110
+ if (outputPath) {
111
+ if (existsSync(outputPath)) {
112
+ console.error(`Error: file already exists: ${outputPath}`);
113
+ console.error("Remove it first or choose a different path");
114
+ process.exitCode = 1;
115
+ return;
116
+ }
117
+ writeFileSync(outputPath, template);
118
+ console.log(`CI config written to ${outputPath}`);
119
+ return;
120
+ }
121
+ console.log(`\n# Judges CI Configuration (${platform})`);
122
+ console.log(`# Suggested file: ${defaultFile}`);
123
+ console.log("─".repeat(60));
124
+ console.log(template);
125
+ }
126
+ //# sourceMappingURL=review-ci-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-ci-integration.js","sourceRoot":"","sources":["../../src/commands/review-ci-integration.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAE/C,+EAA+E;AAE/E,SAAS,qBAAqB;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuBR,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB;IAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;CAwBR,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO;;;;;;;;;;;CAWR,CAAC;AACF,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,sBAAsB,CAAC,IAAc;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrE,MAAM,UAAU,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;CAWf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,QAAgB,CAAC;IACrB,IAAI,WAAmB,CAAC;IAExB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YACpC,WAAW,GAAG,qBAAqB,CAAC;YACpC,MAAM;QACR,KAAK,QAAQ;YACX,QAAQ,GAAG,gBAAgB,EAAE,CAAC;YAC9B,WAAW,GAAG,gBAAgB,CAAC;YAC/B,MAAM;QACR;YACE,QAAQ,GAAG,qBAAqB,EAAE,CAAC;YACnC,WAAW,GAAG,qCAAqC,CAAC;YACpD,MAAM;IACV,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;QAClD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,QAAQ,GAAG,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-comparative — Compare two verdict reports side by side.
3
+ */
4
+ export declare function runReviewComparative(argv: string[]): void;
5
+ //# sourceMappingURL=review-comparative.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-comparative.d.ts","sourceRoot":"","sources":["../../src/commands/review-comparative.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6FH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8FzD"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Review-comparative — Compare two verdict reports side by side.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Analysis ───────────────────────────────────────────────────────────────
6
+ function compareVerdicts(before, after) {
7
+ const metrics = [];
8
+ // overall verdict
9
+ metrics.push({
10
+ metric: "Overall Verdict",
11
+ before: before.overallVerdict,
12
+ after: after.overallVerdict,
13
+ change: before.overallVerdict === after.overallVerdict ? "unchanged" : "changed",
14
+ });
15
+ // score
16
+ const scoreDiff = after.overallScore - before.overallScore;
17
+ metrics.push({
18
+ metric: "Score",
19
+ before: before.overallScore,
20
+ after: after.overallScore,
21
+ change: scoreDiff > 0 ? `+${scoreDiff}` : String(scoreDiff),
22
+ });
23
+ // finding counts
24
+ metrics.push({
25
+ metric: "Total Findings",
26
+ before: before.findings.length,
27
+ after: after.findings.length,
28
+ change: String(after.findings.length - before.findings.length),
29
+ });
30
+ metrics.push({
31
+ metric: "Critical",
32
+ before: before.criticalCount,
33
+ after: after.criticalCount,
34
+ change: String(after.criticalCount - before.criticalCount),
35
+ });
36
+ metrics.push({
37
+ metric: "High",
38
+ before: before.highCount,
39
+ after: after.highCount,
40
+ change: String(after.highCount - before.highCount),
41
+ });
42
+ // finding diff
43
+ const beforeRules = new Set(before.findings.map((f) => f.ruleId));
44
+ const afterRules = new Set(after.findings.map((f) => f.ruleId));
45
+ const findings = [];
46
+ for (const f of after.findings) {
47
+ if (!beforeRules.has(f.ruleId)) {
48
+ findings.push({ ruleId: f.ruleId, title: f.title, status: "added" });
49
+ }
50
+ }
51
+ for (const f of before.findings) {
52
+ if (!afterRules.has(f.ruleId)) {
53
+ findings.push({ ruleId: f.ruleId, title: f.title, status: "removed" });
54
+ }
55
+ }
56
+ for (const f of after.findings) {
57
+ if (beforeRules.has(f.ruleId)) {
58
+ findings.push({ ruleId: f.ruleId, title: f.title, status: "unchanged" });
59
+ }
60
+ }
61
+ return { metrics, findings };
62
+ }
63
+ // ─── CLI ────────────────────────────────────────────────────────────────────
64
+ export function runReviewComparative(argv) {
65
+ const beforeIdx = argv.indexOf("--before");
66
+ const afterIdx = argv.indexOf("--after");
67
+ const formatIdx = argv.indexOf("--format");
68
+ const beforePath = beforeIdx >= 0 ? argv[beforeIdx + 1] : undefined;
69
+ const afterPath = afterIdx >= 0 ? argv[afterIdx + 1] : undefined;
70
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
71
+ if (argv.includes("--help") || argv.includes("-h")) {
72
+ console.log(`
73
+ judges review-comparative — Compare two verdict reports
74
+
75
+ Usage:
76
+ judges review-comparative --before <old.json> --after <new.json>
77
+ [--format table|json]
78
+
79
+ Options:
80
+ --before <path> Path to baseline verdict JSON (required)
81
+ --after <path> Path to new verdict JSON (required)
82
+ --format <fmt> Output format: table (default), json
83
+ --help, -h Show this help
84
+ `);
85
+ return;
86
+ }
87
+ if (!beforePath || !afterPath) {
88
+ console.error("Error: --before and --after required");
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+ if (!existsSync(beforePath)) {
93
+ console.error(`Error: not found: ${beforePath}`);
94
+ process.exitCode = 1;
95
+ return;
96
+ }
97
+ if (!existsSync(afterPath)) {
98
+ console.error(`Error: not found: ${afterPath}`);
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+ let before;
103
+ let after;
104
+ try {
105
+ before = JSON.parse(readFileSync(beforePath, "utf-8"));
106
+ }
107
+ catch {
108
+ console.error("Error: invalid JSON in before file");
109
+ process.exitCode = 1;
110
+ return;
111
+ }
112
+ try {
113
+ after = JSON.parse(readFileSync(afterPath, "utf-8"));
114
+ }
115
+ catch {
116
+ console.error("Error: invalid JSON in after file");
117
+ process.exitCode = 1;
118
+ return;
119
+ }
120
+ const result = compareVerdicts(before, after);
121
+ if (format === "json") {
122
+ console.log(JSON.stringify(result, null, 2));
123
+ return;
124
+ }
125
+ console.log(`\nComparative Review`);
126
+ console.log("═".repeat(65));
127
+ console.log(`${"Metric".padEnd(20)} ${"Before".padEnd(15)} ${"After".padEnd(15)} Change`);
128
+ console.log("─".repeat(65));
129
+ for (const m of result.metrics) {
130
+ console.log(`${m.metric.padEnd(20)} ${String(m.before).padEnd(15)} ${String(m.after).padEnd(15)} ${m.change}`);
131
+ }
132
+ const added = result.findings.filter((f) => f.status === "added");
133
+ const removed = result.findings.filter((f) => f.status === "removed");
134
+ if (added.length > 0) {
135
+ console.log(`\n New findings (+${added.length}):`);
136
+ for (const f of added) {
137
+ const title = f.title.length > 40 ? f.title.slice(0, 40) + "…" : f.title;
138
+ console.log(` + ${f.ruleId.padEnd(18)} ${title}`);
139
+ }
140
+ }
141
+ if (removed.length > 0) {
142
+ console.log(`\n Resolved findings (-${removed.length}):`);
143
+ for (const f of removed) {
144
+ const title = f.title.length > 40 ? f.title.slice(0, 40) + "…" : f.title;
145
+ console.log(` - ${f.ruleId.padEnd(18)} ${title}`);
146
+ }
147
+ }
148
+ console.log("═".repeat(65));
149
+ }
150
+ //# sourceMappingURL=review-comparative.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-comparative.js","sourceRoot":"","sources":["../../src/commands/review-comparative.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-custom-rule — Create and manage custom rules for review.
3
+ */
4
+ export declare function runReviewCustomRule(argv: string[]): void;
5
+ //# sourceMappingURL=review-custom-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-custom-rule.d.ts","sourceRoot":"","sources":["../../src/commands/review-custom-rule.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiEH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuIxD"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Review-custom-rule — Create and manage custom rules for review.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { dirname } from "path";
6
+ // ─── Helpers ────────────────────────────────────────────────────────────────
7
+ function loadConfig(configPath) {
8
+ if (!existsSync(configPath)) {
9
+ return { version: 1, rules: [] };
10
+ }
11
+ try {
12
+ return JSON.parse(readFileSync(configPath, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: 1, rules: [] };
16
+ }
17
+ }
18
+ function saveConfig(configPath, config) {
19
+ const dir = dirname(configPath);
20
+ if (!existsSync(dir)) {
21
+ mkdirSync(dir, { recursive: true });
22
+ }
23
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
24
+ }
25
+ function testRule(rule, sourceFile) {
26
+ if (!existsSync(sourceFile))
27
+ return [];
28
+ const lines = readFileSync(sourceFile, "utf-8").split("\n");
29
+ const matches = [];
30
+ try {
31
+ const regex = new RegExp(rule.pattern, "gi");
32
+ for (let i = 0; i < lines.length; i++) {
33
+ const m = lines[i].match(regex);
34
+ if (m !== null) {
35
+ matches.push({ line: i + 1, match: m[0] });
36
+ }
37
+ }
38
+ }
39
+ catch {
40
+ // invalid regex
41
+ }
42
+ return matches;
43
+ }
44
+ // ─── CLI ────────────────────────────────────────────────────────────────────
45
+ export function runReviewCustomRule(argv) {
46
+ const actionIdx = argv.indexOf("--action");
47
+ const configIdx = argv.indexOf("--config");
48
+ const idIdx = argv.indexOf("--id");
49
+ const titleIdx = argv.indexOf("--title");
50
+ const severityIdx = argv.indexOf("--severity");
51
+ const patternIdx = argv.indexOf("--pattern");
52
+ const sourceIdx = argv.indexOf("--source");
53
+ const formatIdx = argv.indexOf("--format");
54
+ const action = actionIdx >= 0 ? argv[actionIdx + 1] : "list";
55
+ const configPath = configIdx >= 0 ? argv[configIdx + 1] : ".judges-custom-rules.json";
56
+ const ruleId = idIdx >= 0 ? argv[idIdx + 1] : undefined;
57
+ const title = titleIdx >= 0 ? argv[titleIdx + 1] : undefined;
58
+ const severity = severityIdx >= 0 ? argv[severityIdx + 1] : "medium";
59
+ const pattern = patternIdx >= 0 ? argv[patternIdx + 1] : undefined;
60
+ const sourceFile = sourceIdx >= 0 ? argv[sourceIdx + 1] : undefined;
61
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
62
+ if (argv.includes("--help") || argv.includes("-h")) {
63
+ console.log(`
64
+ judges review-custom-rule — Manage custom review rules
65
+
66
+ Usage:
67
+ judges review-custom-rule --action <action> [options]
68
+
69
+ Actions:
70
+ list List custom rules (default)
71
+ add Add a new custom rule
72
+ remove Remove a custom rule
73
+ test Test a rule against a source file
74
+
75
+ Options:
76
+ --action <act> Action: list, add, remove, test
77
+ --config <path> Config file (default: .judges-custom-rules.json)
78
+ --id <id> Rule ID (for add/remove/test)
79
+ --title <title> Rule title (for add)
80
+ --severity <sev> Severity: critical, high, medium (default), low, info
81
+ --pattern <regex> Regex pattern (for add)
82
+ --source <path> Source file (for test)
83
+ --format <fmt> Output format: table (default), json
84
+ --help, -h Show this help
85
+ `);
86
+ return;
87
+ }
88
+ const config = loadConfig(configPath);
89
+ if (action === "add") {
90
+ if (!ruleId || !pattern) {
91
+ console.error("Error: --id and --pattern required for add");
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ if (config.rules.some((r) => r.id === ruleId)) {
96
+ console.error(`Error: rule ${ruleId} already exists`);
97
+ process.exitCode = 1;
98
+ return;
99
+ }
100
+ config.rules.push({
101
+ id: ruleId,
102
+ title: title || ruleId,
103
+ severity: severity,
104
+ pattern,
105
+ description: `Custom rule: ${ruleId}`,
106
+ recommendation: "Review matched code for compliance",
107
+ enabled: true,
108
+ });
109
+ saveConfig(configPath, config);
110
+ console.log(`Added rule: ${ruleId}`);
111
+ return;
112
+ }
113
+ if (action === "remove") {
114
+ if (!ruleId) {
115
+ console.error("Error: --id required for remove");
116
+ process.exitCode = 1;
117
+ return;
118
+ }
119
+ const idx = config.rules.findIndex((r) => r.id === ruleId);
120
+ if (idx < 0) {
121
+ console.error(`Error: rule ${ruleId} not found`);
122
+ process.exitCode = 1;
123
+ return;
124
+ }
125
+ config.rules.splice(idx, 1);
126
+ saveConfig(configPath, config);
127
+ console.log(`Removed rule: ${ruleId}`);
128
+ return;
129
+ }
130
+ if (action === "test") {
131
+ if (!ruleId || !sourceFile) {
132
+ console.error("Error: --id and --source required for test");
133
+ process.exitCode = 1;
134
+ return;
135
+ }
136
+ const rule = config.rules.find((r) => r.id === ruleId);
137
+ if (rule === undefined) {
138
+ console.error(`Error: rule ${ruleId} not found`);
139
+ process.exitCode = 1;
140
+ return;
141
+ }
142
+ const matches = testRule(rule, sourceFile);
143
+ if (format === "json") {
144
+ console.log(JSON.stringify({ rule: rule.id, matches }, null, 2));
145
+ return;
146
+ }
147
+ console.log(`\nTest Results: ${rule.id} (${matches.length} matches)`);
148
+ console.log("─".repeat(50));
149
+ for (const m of matches) {
150
+ console.log(` Line ${String(m.line).padEnd(6)} ${m.match}`);
151
+ }
152
+ return;
153
+ }
154
+ // default: list
155
+ if (format === "json") {
156
+ console.log(JSON.stringify(config, null, 2));
157
+ return;
158
+ }
159
+ console.log(`\nCustom Rules (${config.rules.length})`);
160
+ console.log("═".repeat(70));
161
+ console.log(`${"ID".padEnd(18)} ${"Severity".padEnd(10)} ${"Enabled".padEnd(10)} ${"Pattern".padEnd(25)} Title`);
162
+ console.log("─".repeat(70));
163
+ for (const r of config.rules) {
164
+ const pat = r.pattern.length > 23 ? r.pattern.slice(0, 23) + "…" : r.pattern;
165
+ const title2 = r.title.length > 15 ? r.title.slice(0, 15) + "…" : r.title;
166
+ console.log(`${r.id.padEnd(18)} ${r.severity.padEnd(10)} ${String(r.enabled).padEnd(10)} ${pat.padEnd(25)} ${title2}`);
167
+ }
168
+ console.log("═".repeat(70));
169
+ }
170
+ //# sourceMappingURL=review-custom-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-custom-rule.js","sourceRoot":"","sources":["../../src/commands/review-custom-rule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-notification — Configure and display review notification settings.
3
+ */
4
+ export declare function runReviewNotification(argv: string[]): void;
5
+ //# sourceMappingURL=review-notification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-notification.d.ts","sourceRoot":"","sources":["../../src/commands/review-notification.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkDH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsG1D"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Review-notification — Configure and display review notification settings.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { dirname } from "path";
6
+ // ─── Helpers ────────────────────────────────────────────────────────────────
7
+ function loadConfig(configPath) {
8
+ if (!existsSync(configPath)) {
9
+ return {
10
+ version: 1,
11
+ rules: [
12
+ { event: "critical-finding", channel: "console", enabled: true },
13
+ { event: "score-drop", channel: "console", threshold: 10, enabled: true },
14
+ { event: "review-complete", channel: "console", enabled: true },
15
+ ],
16
+ };
17
+ }
18
+ try {
19
+ return JSON.parse(readFileSync(configPath, "utf-8"));
20
+ }
21
+ catch {
22
+ return { version: 1, rules: [] };
23
+ }
24
+ }
25
+ function saveConfig(configPath, config) {
26
+ const dir = dirname(configPath);
27
+ if (!existsSync(dir)) {
28
+ mkdirSync(dir, { recursive: true });
29
+ }
30
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
31
+ }
32
+ // ─── CLI ────────────────────────────────────────────────────────────────────
33
+ export function runReviewNotification(argv) {
34
+ const actionIdx = argv.indexOf("--action");
35
+ const configIdx = argv.indexOf("--config");
36
+ const eventIdx = argv.indexOf("--event");
37
+ const channelIdx = argv.indexOf("--channel");
38
+ const thresholdIdx = argv.indexOf("--threshold");
39
+ const formatIdx = argv.indexOf("--format");
40
+ const action = actionIdx >= 0 ? argv[actionIdx + 1] : "list";
41
+ const configPath = configIdx >= 0 ? argv[configIdx + 1] : ".judges-notifications.json";
42
+ const event = eventIdx >= 0 ? argv[eventIdx + 1] : undefined;
43
+ const channel = channelIdx >= 0 ? argv[channelIdx + 1] : "console";
44
+ const threshold = thresholdIdx >= 0 ? parseInt(argv[thresholdIdx + 1], 10) : undefined;
45
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
46
+ if (argv.includes("--help") || argv.includes("-h")) {
47
+ console.log(`
48
+ judges review-notification — Manage review notifications
49
+
50
+ Usage:
51
+ judges review-notification --action <action> [options]
52
+
53
+ Actions:
54
+ list Show notification rules (default)
55
+ add Add a notification rule
56
+ remove Remove a notification rule
57
+ init Initialize default notification config
58
+
59
+ Options:
60
+ --action <act> Action: list, add, remove, init
61
+ --config <path> Config file (default: .judges-notifications.json)
62
+ --event <type> Event: critical-finding, score-drop, new-rule-violation, review-complete
63
+ --channel <type> Channel: console (default), file, webhook-url
64
+ --threshold <n> Threshold value (for score-drop events)
65
+ --format <fmt> Output format: table (default), json
66
+ --help, -h Show this help
67
+ `);
68
+ return;
69
+ }
70
+ const config = loadConfig(configPath);
71
+ if (action === "init") {
72
+ saveConfig(configPath, config);
73
+ console.log(`Notification config initialized: ${configPath}`);
74
+ return;
75
+ }
76
+ if (action === "add") {
77
+ if (!event) {
78
+ console.error("Error: --event required for add");
79
+ process.exitCode = 1;
80
+ return;
81
+ }
82
+ const newRule = {
83
+ event: event,
84
+ channel: channel,
85
+ enabled: true,
86
+ };
87
+ if (threshold !== undefined) {
88
+ newRule.threshold = threshold;
89
+ }
90
+ config.rules.push(newRule);
91
+ saveConfig(configPath, config);
92
+ console.log(`Added notification rule: ${event} → ${channel}`);
93
+ return;
94
+ }
95
+ if (action === "remove") {
96
+ if (!event) {
97
+ console.error("Error: --event required for remove");
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ const idx = config.rules.findIndex((r) => r.event === event && r.channel === channel);
102
+ if (idx < 0) {
103
+ console.error(`Error: notification rule not found: ${event} → ${channel}`);
104
+ process.exitCode = 1;
105
+ return;
106
+ }
107
+ config.rules.splice(idx, 1);
108
+ saveConfig(configPath, config);
109
+ console.log(`Removed notification rule: ${event} → ${channel}`);
110
+ return;
111
+ }
112
+ // default: list
113
+ if (format === "json") {
114
+ console.log(JSON.stringify(config, null, 2));
115
+ return;
116
+ }
117
+ console.log(`\nNotification Rules (${config.rules.length})`);
118
+ console.log("═".repeat(65));
119
+ console.log(`${"Event".padEnd(25)} ${"Channel".padEnd(15)} ${"Threshold".padEnd(12)} Enabled`);
120
+ console.log("─".repeat(65));
121
+ for (const r of config.rules) {
122
+ const thresh = r.threshold !== undefined ? String(r.threshold) : "—";
123
+ console.log(`${r.event.padEnd(25)} ${r.channel.padEnd(15)} ${thresh.padEnd(12)} ${r.enabled}`);
124
+ }
125
+ console.log("═".repeat(65));
126
+ }
127
+ //# sourceMappingURL=review-notification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-notification.js","sourceRoot":"","sources":["../../src/commands/review-notification.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAiB/B,+EAA+E;AAE/E,SAAS,UAAU,CAAC,UAAkB;IACpC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,OAAO,EAAE,CAAC;YACV,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;gBAChE,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;gBACzE,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;aAChE;SACF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACnC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,UAAkB,EAAE,MAA0B;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,qBAAqB,CAAC,IAAc;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7D,MAAM,UAAU,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC;IACvF,MAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,MAAM,OAAO,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,MAAM,SAAS,GAAG,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAE9D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;CAoBf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAEtC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACjD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAqB;YAChC,KAAK,EAAE,KAAkC;YACzC,OAAO,EAAE,OAAsC;YAC/C,OAAO,EAAE,IAAI;SACd,CAAC;QACF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAChC,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACpD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;QACtF,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,uCAAuC,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;YAC3E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5B,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,gBAAgB;IAChB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-template-export — Export review templates for reuse.
3
+ */
4
+ export declare function runReviewTemplateExport(argv: string[]): void;
5
+ //# sourceMappingURL=review-template-export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-template-export.d.ts","sourceRoot":"","sources":["../../src/commands/review-template-export.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8EH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkG5D"}