@kevinrabun/judges 3.100.0 → 3.102.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 (78) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +126 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-batch-suppress.d.ts +5 -0
  6. package/dist/commands/finding-batch-suppress.d.ts.map +1 -0
  7. package/dist/commands/finding-batch-suppress.js +86 -0
  8. package/dist/commands/finding-batch-suppress.js.map +1 -0
  9. package/dist/commands/finding-dependency-link.d.ts +5 -0
  10. package/dist/commands/finding-dependency-link.d.ts.map +1 -0
  11. package/dist/commands/finding-dependency-link.js +74 -0
  12. package/dist/commands/finding-dependency-link.js.map +1 -0
  13. package/dist/commands/finding-ownership-assign.d.ts +5 -0
  14. package/dist/commands/finding-ownership-assign.d.ts.map +1 -0
  15. package/dist/commands/finding-ownership-assign.js +102 -0
  16. package/dist/commands/finding-ownership-assign.js.map +1 -0
  17. package/dist/commands/finding-recurrence-detect.d.ts +5 -0
  18. package/dist/commands/finding-recurrence-detect.d.ts.map +1 -0
  19. package/dist/commands/finding-recurrence-detect.js +78 -0
  20. package/dist/commands/finding-recurrence-detect.js.map +1 -0
  21. package/dist/commands/finding-search-index.d.ts +5 -0
  22. package/dist/commands/finding-search-index.d.ts.map +1 -0
  23. package/dist/commands/finding-search-index.js +100 -0
  24. package/dist/commands/finding-search-index.js.map +1 -0
  25. package/dist/commands/finding-severity-drift.d.ts +5 -0
  26. package/dist/commands/finding-severity-drift.d.ts.map +1 -0
  27. package/dist/commands/finding-severity-drift.js +93 -0
  28. package/dist/commands/finding-severity-drift.js.map +1 -0
  29. package/dist/commands/review-access-log.d.ts +5 -0
  30. package/dist/commands/review-access-log.d.ts.map +1 -0
  31. package/dist/commands/review-access-log.js +66 -0
  32. package/dist/commands/review-access-log.js.map +1 -0
  33. package/dist/commands/review-archive-search.d.ts +5 -0
  34. package/dist/commands/review-archive-search.d.ts.map +1 -0
  35. package/dist/commands/review-archive-search.js +71 -0
  36. package/dist/commands/review-archive-search.js.map +1 -0
  37. package/dist/commands/review-branch-policy.d.ts +5 -0
  38. package/dist/commands/review-branch-policy.d.ts.map +1 -0
  39. package/dist/commands/review-branch-policy.js +103 -0
  40. package/dist/commands/review-branch-policy.js.map +1 -0
  41. package/dist/commands/review-custom-judge-config.d.ts +5 -0
  42. package/dist/commands/review-custom-judge-config.d.ts.map +1 -0
  43. package/dist/commands/review-custom-judge-config.js +104 -0
  44. package/dist/commands/review-custom-judge-config.js.map +1 -0
  45. package/dist/commands/review-incident-link.d.ts +5 -0
  46. package/dist/commands/review-incident-link.d.ts.map +1 -0
  47. package/dist/commands/review-incident-link.js +94 -0
  48. package/dist/commands/review-incident-link.js.map +1 -0
  49. package/dist/commands/review-integration-health.d.ts +5 -0
  50. package/dist/commands/review-integration-health.d.ts.map +1 -0
  51. package/dist/commands/review-integration-health.js +85 -0
  52. package/dist/commands/review-integration-health.js.map +1 -0
  53. package/dist/commands/review-metric-export.d.ts +5 -0
  54. package/dist/commands/review-metric-export.d.ts.map +1 -0
  55. package/dist/commands/review-metric-export.js +63 -0
  56. package/dist/commands/review-metric-export.js.map +1 -0
  57. package/dist/commands/review-notification-digest.d.ts +5 -0
  58. package/dist/commands/review-notification-digest.d.ts.map +1 -0
  59. package/dist/commands/review-notification-digest.js +65 -0
  60. package/dist/commands/review-notification-digest.js.map +1 -0
  61. package/dist/commands/review-pr-comment-gen.d.ts +5 -0
  62. package/dist/commands/review-pr-comment-gen.d.ts.map +1 -0
  63. package/dist/commands/review-pr-comment-gen.js +63 -0
  64. package/dist/commands/review-pr-comment-gen.js.map +1 -0
  65. package/dist/commands/review-quality-trend.d.ts +5 -0
  66. package/dist/commands/review-quality-trend.d.ts.map +1 -0
  67. package/dist/commands/review-quality-trend.js +58 -0
  68. package/dist/commands/review-quality-trend.js.map +1 -0
  69. package/dist/commands/review-role-assignment.d.ts +5 -0
  70. package/dist/commands/review-role-assignment.d.ts.map +1 -0
  71. package/dist/commands/review-role-assignment.js +99 -0
  72. package/dist/commands/review-role-assignment.js.map +1 -0
  73. package/dist/commands/review-tag-manager.d.ts +5 -0
  74. package/dist/commands/review-tag-manager.d.ts.map +1 -0
  75. package/dist/commands/review-tag-manager.js +129 -0
  76. package/dist/commands/review-tag-manager.js.map +1 -0
  77. package/package.json +1 -1
  78. package/server.json +2 -2
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-batch-suppress — Batch suppress multiple findings at once.
3
+ */
4
+ export declare function runFindingBatchSuppress(argv: string[]): void;
5
+ //# sourceMappingURL=finding-batch-suppress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-batch-suppress.d.ts","sourceRoot":"","sources":["../../src/commands/finding-batch-suppress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA2F5D"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Finding-batch-suppress — Batch suppress multiple findings at once.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingBatchSuppress(argv) {
7
+ const storeIdx = argv.indexOf("--store");
8
+ const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-suppressions.json";
9
+ const findingsIdx = argv.indexOf("--findings");
10
+ const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
11
+ const reasonIdx = argv.indexOf("--reason");
12
+ const reason = reasonIdx >= 0 ? argv[reasonIdx + 1] : "batch suppressed";
13
+ const severityIdx = argv.indexOf("--severity");
14
+ const severity = severityIdx >= 0 ? argv[severityIdx + 1] : "";
15
+ const daysIdx = argv.indexOf("--expires-days");
16
+ const expiresDays = daysIdx >= 0 ? parseInt(argv[daysIdx + 1], 10) : 30;
17
+ const formatIdx = argv.indexOf("--format");
18
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
19
+ if (argv.includes("--help") || argv.includes("-h")) {
20
+ console.log(`
21
+ judges finding-batch-suppress — Batch suppress findings
22
+
23
+ Usage:
24
+ judges finding-batch-suppress --findings <path> [--severity <sev>] [--reason <text>] [--expires-days <n>]
25
+ judges finding-batch-suppress [--store <path>] [--format table|json]
26
+
27
+ Options:
28
+ --findings <path> Path to findings JSON to suppress
29
+ --severity <sev> Only suppress findings of this severity
30
+ --reason <text> Suppression reason (default: "batch suppressed")
31
+ --expires-days <n> Days until suppression expires (default: 30)
32
+ --store <path> Suppression store (default: .judges-suppressions.json)
33
+ --format <fmt> Output format: table (default), json
34
+ --help, -h Show this help
35
+ `);
36
+ return;
37
+ }
38
+ const store = existsSync(storePath)
39
+ ? JSON.parse(readFileSync(storePath, "utf-8"))
40
+ : { suppressions: [], lastUpdated: new Date().toISOString() };
41
+ if (findingsPath && existsSync(findingsPath)) {
42
+ const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
43
+ let filtered = findings;
44
+ if (severity) {
45
+ filtered = findings.filter((f) => f.severity === severity);
46
+ }
47
+ const now = new Date();
48
+ const expires = new Date(now.getTime() + expiresDays * 24 * 60 * 60 * 1000).toISOString();
49
+ let count = 0;
50
+ for (const f of filtered) {
51
+ const existing = store.suppressions.find((s) => s.ruleId === f.ruleId);
52
+ if (!existing) {
53
+ store.suppressions.push({
54
+ ruleId: f.ruleId,
55
+ reason,
56
+ suppressedAt: now.toISOString(),
57
+ expiresAt: expires,
58
+ });
59
+ count++;
60
+ }
61
+ }
62
+ store.lastUpdated = now.toISOString();
63
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
64
+ console.log(`Suppressed ${count} findings (expires in ${expiresDays} days).`);
65
+ return;
66
+ }
67
+ if (format === "json") {
68
+ console.log(JSON.stringify(store, null, 2));
69
+ return;
70
+ }
71
+ console.log(`\nSuppressed Findings (${store.suppressions.length})`);
72
+ console.log("═".repeat(70));
73
+ if (store.suppressions.length === 0) {
74
+ console.log(" No suppressions.");
75
+ }
76
+ else {
77
+ console.log(` ${"Rule ID".padEnd(25)} ${"Reason".padEnd(20)} ${"Suppressed".padEnd(14)} Expires`);
78
+ console.log(" " + "─".repeat(65));
79
+ for (const s of store.suppressions) {
80
+ const rsn = s.reason.length > 18 ? s.reason.slice(0, 15) + "..." : s.reason;
81
+ console.log(` ${s.ruleId.padEnd(25)} ${rsn.padEnd(20)} ${s.suppressedAt.slice(0, 10).padEnd(14)} ${s.expiresAt.slice(0, 10)}`);
82
+ }
83
+ }
84
+ console.log("═".repeat(70));
85
+ }
86
+ //# sourceMappingURL=finding-batch-suppress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-batch-suppress.js","sourceRoot":"","sources":["../../src/commands/finding-batch-suppress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAiB7D,+EAA+E;AAE/E,MAAM,UAAU,uBAAuB,CAAC,IAAc;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC;IACnF,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACzE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,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;;;;;;;;;;;;;;;CAef,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAqB,UAAU,CAAC,SAAS,CAAC;QACnD,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAsB;QACpE,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAEhE,IAAI,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAc,CAAC;QAC9E,IAAI,QAAQ,GAAG,QAAQ,CAAC;QACxB,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1F,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC;oBACtB,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,MAAM;oBACN,YAAY,EAAE,GAAG,CAAC,WAAW,EAAE;oBAC/B,SAAS,EAAE,OAAO;iBACnB,CAAC,CAAC;gBACH,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QAED,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACtC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,yBAAyB,WAAW,SAAS,CAAC,CAAC;QAC9E,OAAO;IACT,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QACnG,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAEnC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5E,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CACnH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-dependency-link — Link findings to project dependencies.
3
+ */
4
+ export declare function runFindingDependencyLink(argv: string[]): void;
5
+ //# sourceMappingURL=finding-dependency-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-dependency-link.d.ts","sourceRoot":"","sources":["../../src/commands/finding-dependency-link.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmCH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4D7D"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Finding-dependency-link — Link findings to project dependencies.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Helpers ────────────────────────────────────────────────────────────────
6
+ function linkFindings(findings, dependencies) {
7
+ return findings.map((f) => {
8
+ const desc = f.description.toLowerCase();
9
+ const rec = f.recommendation.toLowerCase();
10
+ const combined = `${desc} ${rec}`;
11
+ const matched = dependencies.find((dep) => combined.includes(dep.toLowerCase()));
12
+ return {
13
+ ruleId: f.ruleId,
14
+ title: f.title,
15
+ severity: f.severity,
16
+ linkedPackage: matched ?? "",
17
+ linkType: matched ? "direct" : "none",
18
+ };
19
+ });
20
+ }
21
+ // ─── CLI ────────────────────────────────────────────────────────────────────
22
+ export function runFindingDependencyLink(argv) {
23
+ const findingsIdx = argv.indexOf("--findings");
24
+ const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
25
+ const pkgIdx = argv.indexOf("--package-json");
26
+ const pkgPath = pkgIdx >= 0 ? argv[pkgIdx + 1] : "package.json";
27
+ const formatIdx = argv.indexOf("--format");
28
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
29
+ if (argv.includes("--help") || argv.includes("-h")) {
30
+ console.log(`
31
+ judges finding-dependency-link — Link findings to dependencies
32
+
33
+ Usage:
34
+ judges finding-dependency-link --findings <path> [--package-json <path>] [--format table|json]
35
+
36
+ Options:
37
+ --findings <path> Path to findings JSON
38
+ --package-json <path> Path to package.json (default: package.json)
39
+ --format <fmt> Output format: table (default), json
40
+ --help, -h Show this help
41
+ `);
42
+ return;
43
+ }
44
+ if (!findingsPath || !existsSync(findingsPath)) {
45
+ console.error("Provide --findings <path> to a valid findings JSON file.");
46
+ process.exitCode = 1;
47
+ return;
48
+ }
49
+ const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
50
+ let deps = [];
51
+ if (existsSync(pkgPath)) {
52
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
53
+ const dependencies = (pkg.dependencies ?? {});
54
+ const devDependencies = (pkg.devDependencies ?? {});
55
+ deps = [...Object.keys(dependencies), ...Object.keys(devDependencies)];
56
+ }
57
+ const results = linkFindings(findings, deps);
58
+ if (format === "json") {
59
+ console.log(JSON.stringify(results, null, 2));
60
+ return;
61
+ }
62
+ console.log(`\nFinding–Dependency Links (${results.length} findings)`);
63
+ console.log("═".repeat(80));
64
+ console.log(` ${"Rule ID".padEnd(25)} ${"Severity".padEnd(10)} ${"Link Type".padEnd(12)} Package`);
65
+ console.log(" " + "─".repeat(60));
66
+ for (const r of results) {
67
+ const pkg = r.linkedPackage || "—";
68
+ console.log(` ${r.ruleId.padEnd(25)} ${r.severity.padEnd(10)} ${r.linkType.padEnd(12)} ${pkg}`);
69
+ }
70
+ const linked = results.filter((r) => r.linkType !== "none").length;
71
+ console.log(`\n Linked: ${linked} | Unlinked: ${results.length - linked}`);
72
+ console.log("═".repeat(80));
73
+ }
74
+ //# sourceMappingURL=finding-dependency-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-dependency-link.js","sourceRoot":"","sources":["../../src/commands/finding-dependency-link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-ownership-assign — Assign ownership of findings to team members.
3
+ */
4
+ export declare function runFindingOwnershipAssign(argv: string[]): void;
5
+ //# sourceMappingURL=finding-ownership-assign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-ownership-assign.d.ts","sourceRoot":"","sources":["../../src/commands/finding-ownership-assign.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0G9D"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Finding-ownership-assign — Assign ownership of findings to team members.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingOwnershipAssign(argv) {
7
+ const storeIdx = argv.indexOf("--store");
8
+ const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-ownership.json";
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ const assignIdx = argv.indexOf("--assign");
12
+ const assignRule = assignIdx >= 0 ? argv[assignIdx + 1] : "";
13
+ const ownerIdx = argv.indexOf("--owner");
14
+ const ownerName = ownerIdx >= 0 ? argv[ownerIdx + 1] : "";
15
+ const findingsIdx = argv.indexOf("--findings");
16
+ const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
17
+ if (argv.includes("--help") || argv.includes("-h")) {
18
+ console.log(`
19
+ judges finding-ownership-assign — Assign finding ownership
20
+
21
+ Usage:
22
+ judges finding-ownership-assign [--store <path>] [--format table|json]
23
+ judges finding-ownership-assign --assign <ruleId> --owner <name> [--store <path>]
24
+ judges finding-ownership-assign --findings <path> --owner <name> [--store <path>]
25
+
26
+ Options:
27
+ --store <path> Ownership store (default: .judges-ownership.json)
28
+ --assign <ruleId> Assign a specific rule finding
29
+ --findings <path> Bulk assign from findings JSON
30
+ --owner <name> Owner name/email
31
+ --format <fmt> Output format: table (default), json
32
+ --help, -h Show this help
33
+ `);
34
+ return;
35
+ }
36
+ const store = existsSync(storePath)
37
+ ? JSON.parse(readFileSync(storePath, "utf-8"))
38
+ : { assignments: [], lastUpdated: new Date().toISOString() };
39
+ if (assignRule && ownerName) {
40
+ const existing = store.assignments.find((a) => a.ruleId === assignRule);
41
+ if (existing) {
42
+ existing.owner = ownerName;
43
+ existing.assignedAt = new Date().toISOString();
44
+ existing.status = "assigned";
45
+ }
46
+ else {
47
+ store.assignments.push({
48
+ ruleId: assignRule,
49
+ title: assignRule,
50
+ severity: "medium",
51
+ owner: ownerName,
52
+ assignedAt: new Date().toISOString(),
53
+ status: "assigned",
54
+ });
55
+ }
56
+ store.lastUpdated = new Date().toISOString();
57
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
58
+ console.log(`Assigned ${assignRule} to ${ownerName}.`);
59
+ return;
60
+ }
61
+ if (findingsPath && ownerName && existsSync(findingsPath)) {
62
+ const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
63
+ let count = 0;
64
+ for (const f of findings) {
65
+ const existing = store.assignments.find((a) => a.ruleId === f.ruleId);
66
+ if (!existing) {
67
+ store.assignments.push({
68
+ ruleId: f.ruleId,
69
+ title: f.title,
70
+ severity: f.severity,
71
+ owner: ownerName,
72
+ assignedAt: new Date().toISOString(),
73
+ status: "assigned",
74
+ });
75
+ count++;
76
+ }
77
+ }
78
+ store.lastUpdated = new Date().toISOString();
79
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
80
+ console.log(`Bulk assigned ${count} findings to ${ownerName}.`);
81
+ return;
82
+ }
83
+ if (format === "json") {
84
+ console.log(JSON.stringify(store, null, 2));
85
+ return;
86
+ }
87
+ console.log("\nFinding Ownership");
88
+ console.log("═".repeat(80));
89
+ if (store.assignments.length === 0) {
90
+ console.log(" No assignments yet.");
91
+ }
92
+ else {
93
+ console.log(` ${"Rule ID".padEnd(25)} ${"Severity".padEnd(10)} ${"Owner".padEnd(18)} ${"Status".padEnd(14)} Assigned`);
94
+ console.log(" " + "─".repeat(75));
95
+ for (const a of store.assignments) {
96
+ console.log(` ${a.ruleId.padEnd(25)} ${a.severity.padEnd(10)} ${a.owner.padEnd(18)} ${a.status.padEnd(14)} ${a.assignedAt.slice(0, 10)}`);
97
+ }
98
+ }
99
+ console.log(`\n Total assignments: ${store.assignments.length}`);
100
+ console.log("═".repeat(80));
101
+ }
102
+ //# sourceMappingURL=finding-ownership-assign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-ownership-assign.js","sourceRoot":"","sources":["../../src/commands/finding-ownership-assign.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-recurrence-detect — Detect recurring findings across review runs.
3
+ */
4
+ export declare function runFindingRecurrenceDetect(argv: string[]): void;
5
+ //# sourceMappingURL=finding-recurrence-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-recurrence-detect.d.ts","sourceRoot":"","sources":["../../src/commands/finding-recurrence-detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuF/D"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Finding-recurrence-detect — Detect recurring findings across review runs.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingRecurrenceDetect(argv) {
7
+ const historyIdx = argv.indexOf("--history");
8
+ const historyPath = historyIdx >= 0 ? argv[historyIdx + 1] : "";
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ const minIdx = argv.indexOf("--min-occurrences");
12
+ const minOccurrences = minIdx >= 0 ? parseInt(argv[minIdx + 1], 10) : 2;
13
+ if (argv.includes("--help") || argv.includes("-h")) {
14
+ console.log(`
15
+ judges finding-recurrence-detect — Detect recurring findings
16
+
17
+ Usage:
18
+ judges finding-recurrence-detect --history <path> [--min-occurrences <n>] [--format table|json]
19
+
20
+ Options:
21
+ --history <path> Path to history JSON (array of {timestamp, findings})
22
+ --min-occurrences <n> Minimum occurrences to report (default: 2)
23
+ --format <fmt> Output format: table (default), json
24
+ --help, -h Show this help
25
+
26
+ The history file should be an array of objects with "timestamp" and "findings" fields.
27
+ `);
28
+ return;
29
+ }
30
+ if (!historyPath || !existsSync(historyPath)) {
31
+ console.error("Provide --history <path> to a valid history JSON file.");
32
+ process.exitCode = 1;
33
+ return;
34
+ }
35
+ const history = JSON.parse(readFileSync(historyPath, "utf-8"));
36
+ const ruleMap = new Map();
37
+ for (const run of history) {
38
+ for (const f of run.findings) {
39
+ const existing = ruleMap.get(f.ruleId);
40
+ if (existing) {
41
+ existing.occurrences += 1;
42
+ existing.lastSeen = run.timestamp;
43
+ }
44
+ else {
45
+ ruleMap.set(f.ruleId, {
46
+ ruleId: f.ruleId,
47
+ title: f.title,
48
+ severity: f.severity,
49
+ occurrences: 1,
50
+ firstSeen: run.timestamp,
51
+ lastSeen: run.timestamp,
52
+ });
53
+ }
54
+ }
55
+ }
56
+ const recurring = [...ruleMap.values()]
57
+ .filter((e) => e.occurrences >= minOccurrences)
58
+ .sort((a, b) => b.occurrences - a.occurrences);
59
+ if (format === "json") {
60
+ console.log(JSON.stringify(recurring, null, 2));
61
+ return;
62
+ }
63
+ console.log(`\nRecurring Findings (min ${minOccurrences} occurrences)`);
64
+ console.log("═".repeat(80));
65
+ if (recurring.length === 0) {
66
+ console.log(" No recurring findings detected.");
67
+ }
68
+ else {
69
+ console.log(` ${"Rule ID".padEnd(25)} ${"Severity".padEnd(10)} ${"Count".padEnd(8)} ${"First Seen".padEnd(14)} Last Seen`);
70
+ console.log(" " + "─".repeat(75));
71
+ for (const r of recurring) {
72
+ console.log(` ${r.ruleId.padEnd(25)} ${r.severity.padEnd(10)} ${String(r.occurrences).padEnd(8)} ${r.firstSeen.slice(0, 10).padEnd(14)} ${r.lastSeen.slice(0, 10)}`);
73
+ }
74
+ }
75
+ console.log(`\n Recurring: ${recurring.length} | Runs analyzed: ${history.length}`);
76
+ console.log("═".repeat(80));
77
+ }
78
+ //# sourceMappingURL=finding-recurrence-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-recurrence-detect.js","sourceRoot":"","sources":["../../src/commands/finding-recurrence-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-search-index — Build and query a local search index of findings.
3
+ */
4
+ export declare function runFindingSearchIndex(argv: string[]): void;
5
+ //# sourceMappingURL=finding-search-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-search-index.d.ts","sourceRoot":"","sources":["../../src/commands/finding-search-index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwBH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4G1D"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Finding-search-index — Build and query a local search index of findings.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingSearchIndex(argv) {
7
+ const storeIdx = argv.indexOf("--store");
8
+ const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-search-index.json";
9
+ const findingsIdx = argv.indexOf("--findings");
10
+ const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
11
+ const queryIdx = argv.indexOf("--query");
12
+ const query = queryIdx >= 0 ? argv[queryIdx + 1] : "";
13
+ const formatIdx = argv.indexOf("--format");
14
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
15
+ const buildMode = argv.includes("--build");
16
+ if (argv.includes("--help") || argv.includes("-h")) {
17
+ console.log(`
18
+ judges finding-search-index — Build and search findings index
19
+
20
+ Usage:
21
+ judges finding-search-index --build --findings <path> [--store <path>]
22
+ judges finding-search-index --query <text> [--store <path>] [--format table|json]
23
+
24
+ Options:
25
+ --store <path> Index file (default: .judges-search-index.json)
26
+ --build Build/update the search index
27
+ --findings <path> Path to findings JSON (with --build)
28
+ --query <text> Search query text
29
+ --format <fmt> Output format: table (default), json
30
+ --help, -h Show this help
31
+ `);
32
+ return;
33
+ }
34
+ if (buildMode) {
35
+ if (!findingsPath || !existsSync(findingsPath)) {
36
+ console.error("Provide --findings <path> to a valid findings JSON file.");
37
+ process.exitCode = 1;
38
+ return;
39
+ }
40
+ const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
41
+ const index = existsSync(storePath)
42
+ ? JSON.parse(readFileSync(storePath, "utf-8"))
43
+ : { entries: [], lastUpdated: new Date().toISOString() };
44
+ let added = 0;
45
+ for (const f of findings) {
46
+ const exists = index.entries.some((e) => e.ruleId === f.ruleId && e.source === findingsPath);
47
+ if (!exists) {
48
+ index.entries.push({
49
+ ruleId: f.ruleId,
50
+ title: f.title,
51
+ severity: f.severity,
52
+ description: f.description,
53
+ recommendation: f.recommendation,
54
+ source: findingsPath,
55
+ indexedAt: new Date().toISOString(),
56
+ });
57
+ added++;
58
+ }
59
+ }
60
+ index.lastUpdated = new Date().toISOString();
61
+ writeFileSync(storePath, JSON.stringify(index, null, 2));
62
+ console.log(`Indexed ${added} new findings. Total: ${index.entries.length}`);
63
+ return;
64
+ }
65
+ if (!existsSync(storePath)) {
66
+ console.log(`No search index found at: ${storePath}`);
67
+ console.log("Run with --build to create one.");
68
+ return;
69
+ }
70
+ const index = JSON.parse(readFileSync(storePath, "utf-8"));
71
+ let results = index.entries;
72
+ if (query) {
73
+ const q = query.toLowerCase();
74
+ results = index.entries.filter((e) => e.ruleId.toLowerCase().includes(q) ||
75
+ e.title.toLowerCase().includes(q) ||
76
+ e.description.toLowerCase().includes(q) ||
77
+ e.recommendation.toLowerCase().includes(q));
78
+ }
79
+ if (format === "json") {
80
+ console.log(JSON.stringify(results, null, 2));
81
+ return;
82
+ }
83
+ console.log(`\nSearch Results (${results.length})`);
84
+ console.log("═".repeat(80));
85
+ if (results.length === 0) {
86
+ console.log(" No matching findings.");
87
+ }
88
+ else {
89
+ console.log(` ${"Rule ID".padEnd(25)} ${"Severity".padEnd(10)} ${"Title".padEnd(30)} Source`);
90
+ console.log(" " + "─".repeat(75));
91
+ for (const e of results) {
92
+ const title = e.title.length > 28 ? e.title.slice(0, 25) + "..." : e.title;
93
+ const source = e.source.length > 15 ? "..." + e.source.slice(-12) : e.source;
94
+ console.log(` ${e.ruleId.padEnd(25)} ${e.severity.padEnd(10)} ${title.padEnd(30)} ${source}`);
95
+ }
96
+ }
97
+ console.log(`\n Index size: ${index.entries.length} | Matched: ${results.length}`);
98
+ console.log("═".repeat(80));
99
+ }
100
+ //# sourceMappingURL=finding-search-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-search-index.js","sourceRoot":"","sources":["../../src/commands/finding-search-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-severity-drift — Detect severity changes across review runs.
3
+ */
4
+ export declare function runFindingSeverityDrift(argv: string[]): void;
5
+ //# sourceMappingURL=finding-severity-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-severity-drift.d.ts","sourceRoot":"","sources":["../../src/commands/finding-severity-drift.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqDH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoE5D"}