@kevinrabun/judges 3.98.0 → 3.99.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 +13 -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-auto-suppress.d.ts +5 -0
  6. package/dist/commands/finding-auto-suppress.d.ts.map +1 -0
  7. package/dist/commands/finding-auto-suppress.js +127 -0
  8. package/dist/commands/finding-auto-suppress.js.map +1 -0
  9. package/dist/commands/finding-dismiss-workflow.d.ts +5 -0
  10. package/dist/commands/finding-dismiss-workflow.d.ts.map +1 -0
  11. package/dist/commands/finding-dismiss-workflow.js +120 -0
  12. package/dist/commands/finding-dismiss-workflow.js.map +1 -0
  13. package/dist/commands/finding-reachability-check.d.ts +5 -0
  14. package/dist/commands/finding-reachability-check.d.ts.map +1 -0
  15. package/dist/commands/finding-reachability-check.js +103 -0
  16. package/dist/commands/finding-reachability-check.js.map +1 -0
  17. package/dist/commands/review-audit-export.d.ts +5 -0
  18. package/dist/commands/review-audit-export.d.ts.map +1 -0
  19. package/dist/commands/review-audit-export.js +94 -0
  20. package/dist/commands/review-audit-export.js.map +1 -0
  21. package/dist/commands/review-data-retention.d.ts +5 -0
  22. package/dist/commands/review-data-retention.d.ts.map +1 -0
  23. package/dist/commands/review-data-retention.js +120 -0
  24. package/dist/commands/review-data-retention.js.map +1 -0
  25. package/dist/commands/review-permission-model.d.ts +5 -0
  26. package/dist/commands/review-permission-model.d.ts.map +1 -0
  27. package/dist/commands/review-permission-model.js +150 -0
  28. package/dist/commands/review-permission-model.js.map +1 -0
  29. package/dist/commands/review-pipeline-status.d.ts +5 -0
  30. package/dist/commands/review-pipeline-status.d.ts.map +1 -0
  31. package/dist/commands/review-pipeline-status.js +55 -0
  32. package/dist/commands/review-pipeline-status.js.map +1 -0
  33. package/dist/commands/review-repo-onboard.d.ts +5 -0
  34. package/dist/commands/review-repo-onboard.d.ts.map +1 -0
  35. package/dist/commands/review-repo-onboard.js +115 -0
  36. package/dist/commands/review-repo-onboard.js.map +1 -0
  37. package/dist/commands/review-review-comments.d.ts +5 -0
  38. package/dist/commands/review-review-comments.d.ts.map +1 -0
  39. package/dist/commands/review-review-comments.js +85 -0
  40. package/dist/commands/review-review-comments.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-auto-suppress — Automatically suppress findings matching criteria.
3
+ */
4
+ export declare function runFindingAutoSuppress(argv: string[]): void;
5
+ //# sourceMappingURL=finding-auto-suppress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-auto-suppress.d.ts","sourceRoot":"","sources":["../../src/commands/finding-auto-suppress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqI3D"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Finding-auto-suppress — Automatically suppress findings matching criteria.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingAutoSuppress(argv) {
7
+ const storeIdx = argv.indexOf("--store");
8
+ const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-suppressions.json";
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ if (argv.includes("--help") || argv.includes("-h")) {
12
+ console.log(`
13
+ judges finding-auto-suppress — Automatically suppress findings
14
+
15
+ Usage:
16
+ judges finding-auto-suppress [--store <path>]
17
+ [--add-rule <id> --field <f> --pattern <p> --reason <reason>]
18
+ [--remove-rule <id>] [--apply <report> --out <path>]
19
+ [--format table|json]
20
+
21
+ Options:
22
+ --store <path> Suppression store (default: .judges-suppressions.json)
23
+ --add-rule <id> Add suppression rule
24
+ --field <f> Match field: ruleId, severity, title
25
+ --pattern <p> Match pattern (substring)
26
+ --reason <reason> Suppression reason
27
+ --remove-rule <id> Remove rule by id
28
+ --apply <report> Apply suppressions to report, output filtered findings
29
+ --out <path> Write filtered report to file
30
+ --format <fmt> Output format: table (default), json
31
+ --help, -h Show this help
32
+ `);
33
+ return;
34
+ }
35
+ let store;
36
+ if (existsSync(storePath)) {
37
+ store = JSON.parse(readFileSync(storePath, "utf-8"));
38
+ }
39
+ else {
40
+ store = { rules: [], lastUpdated: new Date().toISOString().split("T")[0] };
41
+ }
42
+ // Add rule
43
+ const addIdx = argv.indexOf("--add-rule");
44
+ if (addIdx >= 0) {
45
+ const id = argv[addIdx + 1];
46
+ const fieldIdx = argv.indexOf("--field");
47
+ const patternIdx = argv.indexOf("--pattern");
48
+ const reasonIdx = argv.indexOf("--reason");
49
+ const rule = {
50
+ id,
51
+ field: (fieldIdx >= 0 ? argv[fieldIdx + 1] : "ruleId"),
52
+ pattern: patternIdx >= 0 ? argv[patternIdx + 1] : "",
53
+ reason: reasonIdx >= 0 ? argv[reasonIdx + 1] : "",
54
+ createdAt: new Date().toISOString().split("T")[0],
55
+ };
56
+ const existingIdx = store.rules.findIndex((r) => r.id === id);
57
+ if (existingIdx >= 0) {
58
+ store.rules[existingIdx] = rule;
59
+ }
60
+ else {
61
+ store.rules.push(rule);
62
+ }
63
+ store.lastUpdated = new Date().toISOString().split("T")[0];
64
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
65
+ console.log(`Suppression rule "${id}" saved.`);
66
+ return;
67
+ }
68
+ // Remove rule
69
+ const removeIdx = argv.indexOf("--remove-rule");
70
+ if (removeIdx >= 0) {
71
+ const id = argv[removeIdx + 1];
72
+ store.rules = store.rules.filter((r) => r.id !== id);
73
+ store.lastUpdated = new Date().toISOString().split("T")[0];
74
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
75
+ console.log(`Rule "${id}" removed.`);
76
+ return;
77
+ }
78
+ // Apply suppressions to report
79
+ const applyIdx = argv.indexOf("--apply");
80
+ if (applyIdx >= 0) {
81
+ const reportPath = argv[applyIdx + 1];
82
+ if (!existsSync(reportPath)) {
83
+ console.error(`Report not found: ${reportPath}`);
84
+ process.exitCode = 1;
85
+ return;
86
+ }
87
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
88
+ const findings = report.findings ?? [];
89
+ let suppressed = 0;
90
+ const filtered = findings.filter((f) => {
91
+ for (const rule of store.rules) {
92
+ const fieldValue = String(f[rule.field] ?? "");
93
+ if (fieldValue.includes(rule.pattern)) {
94
+ suppressed++;
95
+ return false;
96
+ }
97
+ }
98
+ return true;
99
+ });
100
+ const outIdx = argv.indexOf("--out");
101
+ if (outIdx >= 0) {
102
+ const outPath = argv[outIdx + 1];
103
+ writeFileSync(outPath, JSON.stringify({ ...report, findings: filtered }, null, 2));
104
+ console.log(`Filtered report written to: ${outPath}`);
105
+ }
106
+ console.log(`Suppressed: ${suppressed} | Remaining: ${filtered.length} | Total: ${findings.length}`);
107
+ return;
108
+ }
109
+ // List rules
110
+ if (format === "json") {
111
+ console.log(JSON.stringify(store, null, 2));
112
+ return;
113
+ }
114
+ console.log(`\nSuppression Rules`);
115
+ console.log("═".repeat(65));
116
+ if (store.rules.length === 0) {
117
+ console.log(" No suppression rules. Use --add-rule to create one.");
118
+ }
119
+ else {
120
+ for (const r of store.rules) {
121
+ console.log(` ${r.id.padEnd(20)} ${r.field}:${r.pattern}`);
122
+ console.log(` Reason: ${r.reason} (${r.createdAt})`);
123
+ }
124
+ }
125
+ console.log("═".repeat(65));
126
+ }
127
+ //# sourceMappingURL=finding-auto-suppress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-auto-suppress.js","sourceRoot":"","sources":["../../src/commands/finding-auto-suppress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-dismiss-workflow — Manage finding dismissal workflows.
3
+ */
4
+ export declare function runFindingDismissWorkflow(argv: string[]): void;
5
+ //# sourceMappingURL=finding-dismiss-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-dismiss-workflow.d.ts","sourceRoot":"","sources":["../../src/commands/finding-dismiss-workflow.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8H9D"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Finding-dismiss-workflow — Manage finding dismissal workflows.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingDismissWorkflow(argv) {
7
+ const storeIdx = argv.indexOf("--store");
8
+ const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-dismissals.json";
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ if (argv.includes("--help") || argv.includes("-h")) {
12
+ console.log(`
13
+ judges finding-dismiss-workflow — Manage finding dismissals
14
+
15
+ Usage:
16
+ judges finding-dismiss-workflow [--store <path>]
17
+ [--dismiss <ruleId> --reason <r> --by <name> --note <text> --expires <date>]
18
+ [--revoke <ruleId>] [--audit] [--format table|json]
19
+
20
+ Options:
21
+ --store <path> Dismissal store (default: .judges-dismissals.json)
22
+ --dismiss <ruleId> Dismiss a finding
23
+ --reason <r> Reason: false-positive, accepted-risk, wont-fix, duplicate
24
+ --by <name> Who dismissed it
25
+ --note <text> Additional note
26
+ --expires <date> Expiry date (YYYY-MM-DD)
27
+ --revoke <ruleId> Revoke a dismissal
28
+ --audit Show audit log of all dismissals
29
+ --format <fmt> Output format: table (default), json
30
+ --help, -h Show this help
31
+ `);
32
+ return;
33
+ }
34
+ let store;
35
+ if (existsSync(storePath)) {
36
+ store = JSON.parse(readFileSync(storePath, "utf-8"));
37
+ }
38
+ else {
39
+ store = { dismissals: [], lastUpdated: new Date().toISOString().split("T")[0] };
40
+ }
41
+ // Dismiss
42
+ const dismissIdx = argv.indexOf("--dismiss");
43
+ if (dismissIdx >= 0) {
44
+ const ruleId = argv[dismissIdx + 1];
45
+ const reasonIdx = argv.indexOf("--reason");
46
+ const byIdx = argv.indexOf("--by");
47
+ const noteIdx = argv.indexOf("--note");
48
+ const expiresIdx = argv.indexOf("--expires");
49
+ const dismissal = {
50
+ ruleId,
51
+ reason: (reasonIdx >= 0 ? argv[reasonIdx + 1] : "accepted-risk"),
52
+ dismissedBy: byIdx >= 0 ? argv[byIdx + 1] : "unknown",
53
+ dismissedAt: new Date().toISOString().split("T")[0],
54
+ expiresAt: expiresIdx >= 0 ? argv[expiresIdx + 1] : "9999-12-31",
55
+ note: noteIdx >= 0 ? argv[noteIdx + 1] : "",
56
+ };
57
+ store.dismissals.push(dismissal);
58
+ store.lastUpdated = new Date().toISOString().split("T")[0];
59
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
60
+ console.log(`Dismissed: ${ruleId} (${dismissal.reason})`);
61
+ return;
62
+ }
63
+ // Revoke
64
+ const revokeIdx = argv.indexOf("--revoke");
65
+ if (revokeIdx >= 0) {
66
+ const ruleId = argv[revokeIdx + 1];
67
+ const before = store.dismissals.length;
68
+ store.dismissals = store.dismissals.filter((d) => d.ruleId !== ruleId);
69
+ store.lastUpdated = new Date().toISOString().split("T")[0];
70
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
71
+ console.log(`Revoked ${before - store.dismissals.length} dismissal(s) for: ${ruleId}`);
72
+ return;
73
+ }
74
+ // Audit log
75
+ if (argv.includes("--audit")) {
76
+ const today = new Date().toISOString().split("T")[0];
77
+ const active = store.dismissals.filter((d) => d.expiresAt >= today);
78
+ const expired = store.dismissals.filter((d) => d.expiresAt < today);
79
+ if (format === "json") {
80
+ console.log(JSON.stringify({ active, expired }, null, 2));
81
+ return;
82
+ }
83
+ console.log(`\nDismissal Audit`);
84
+ console.log("═".repeat(70));
85
+ if (active.length > 0) {
86
+ console.log(" Active:");
87
+ for (const d of active) {
88
+ console.log(` ${d.ruleId.padEnd(25)} [${d.reason}] by ${d.dismissedBy} (${d.dismissedAt})`);
89
+ if (d.note.length > 0)
90
+ console.log(` Note: ${d.note}`);
91
+ }
92
+ }
93
+ if (expired.length > 0) {
94
+ console.log(" Expired:");
95
+ for (const d of expired) {
96
+ console.log(` ${d.ruleId.padEnd(25)} [${d.reason}] expired ${d.expiresAt}`);
97
+ }
98
+ }
99
+ console.log(`\n Active: ${active.length} | Expired: ${expired.length}`);
100
+ console.log("═".repeat(70));
101
+ return;
102
+ }
103
+ // List
104
+ if (format === "json") {
105
+ console.log(JSON.stringify(store, null, 2));
106
+ return;
107
+ }
108
+ console.log(`\nDismissals`);
109
+ console.log("═".repeat(65));
110
+ if (store.dismissals.length === 0) {
111
+ console.log(" No dismissals. Use --dismiss <ruleId> to add one.");
112
+ }
113
+ else {
114
+ for (const d of store.dismissals) {
115
+ console.log(` ${d.ruleId.padEnd(25)} [${d.reason}] by ${d.dismissedBy}`);
116
+ }
117
+ }
118
+ console.log("═".repeat(65));
119
+ }
120
+ //# sourceMappingURL=finding-dismiss-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-dismiss-workflow.js","sourceRoot":"","sources":["../../src/commands/finding-dismiss-workflow.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAkB7D,+EAA+E;AAE/E,MAAM,UAAU,yBAAyB,CAAC,IAAc;IACtD,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,yBAAyB,CAAC;IACjF,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;;;;;;;;;;;;;;;;;;;CAmBf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,KAAqB,CAAC;IAC1B,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAmB,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,CAAC;IAED,UAAU;IACV,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAE7C,MAAM,SAAS,GAAc;YAC3B,MAAM;YACN,MAAM,EAAE,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAwB;YACvF,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;YACrD,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnD,SAAS,EAAE,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;YAChE,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;SAC5C,CAAC;QAEF,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,KAAK,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,SAAS;IACT,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QACvC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QACvE,KAAK,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,sBAAsB,MAAM,EAAE,CAAC,CAAC;QACvF,OAAO;IACT,CAAC;IAED,YAAY;IACZ,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;QAEpE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;gBAC/F,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,eAAe,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,OAAO;IACP,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,cAAc,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACrE,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5E,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-reachability-check — Check if findings affect reachable code paths.
3
+ */
4
+ export declare function runFindingReachabilityCheck(argv: string[]): void;
5
+ //# sourceMappingURL=finding-reachability-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-reachability-check.d.ts","sourceRoot":"","sources":["../../src/commands/finding-reachability-check.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAyGhE"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Finding-reachability-check — Check if findings affect reachable code paths.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingReachabilityCheck(argv) {
7
+ const reportIdx = argv.indexOf("--report");
8
+ const sourceIdx = argv.indexOf("--source");
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ if (argv.includes("--help") || argv.includes("-h")) {
12
+ console.log(`
13
+ judges finding-reachability-check — Check finding reachability
14
+
15
+ Usage:
16
+ judges finding-reachability-check --report <path> [--source <path>]
17
+ [--format table|json]
18
+
19
+ Options:
20
+ --report <path> Report file with findings
21
+ --source <path> Source file to check reachability against
22
+ --format <fmt> Output format: table (default), json
23
+ --help, -h Show this help
24
+
25
+ Checks if findings reference code that is reachable in the source.
26
+ `);
27
+ return;
28
+ }
29
+ if (reportIdx < 0) {
30
+ console.error("Missing --report <path>");
31
+ process.exitCode = 1;
32
+ return;
33
+ }
34
+ const reportPath = argv[reportIdx + 1];
35
+ if (!existsSync(reportPath)) {
36
+ console.error(`Report not found: ${reportPath}`);
37
+ process.exitCode = 1;
38
+ return;
39
+ }
40
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
41
+ const findings = report.findings ?? [];
42
+ let sourceLines = [];
43
+ if (sourceIdx >= 0) {
44
+ const sourcePath = argv[sourceIdx + 1];
45
+ if (existsSync(sourcePath)) {
46
+ sourceLines = readFileSync(sourcePath, "utf-8").split("\n");
47
+ }
48
+ }
49
+ const results = findings.map((f) => {
50
+ const lines = f.lineNumbers ?? [];
51
+ let reachable = true;
52
+ let reason = "assumed reachable";
53
+ if (sourceLines.length > 0 && lines.length > 0) {
54
+ // Check if the referenced lines exist and are not commented out
55
+ const referencedLine = lines[0] - 1;
56
+ if (referencedLine >= 0 && referencedLine < sourceLines.length) {
57
+ const line = sourceLines[referencedLine].trim();
58
+ if (line.startsWith("//") || line.startsWith("/*") || line.startsWith("#") || line.startsWith("*")) {
59
+ reachable = false;
60
+ reason = "line is commented out";
61
+ }
62
+ else if (line.length === 0) {
63
+ reachable = false;
64
+ reason = "line is empty";
65
+ }
66
+ else {
67
+ reason = "line exists and is active code";
68
+ }
69
+ }
70
+ else {
71
+ reachable = false;
72
+ reason = "line number out of range";
73
+ }
74
+ }
75
+ else if (lines.length === 0) {
76
+ reason = "no line reference — assumed reachable";
77
+ }
78
+ return {
79
+ ruleId: f.ruleId,
80
+ title: f.title,
81
+ severity: f.severity,
82
+ reachable,
83
+ reason,
84
+ lineNumbers: lines,
85
+ };
86
+ });
87
+ if (format === "json") {
88
+ console.log(JSON.stringify(results, null, 2));
89
+ return;
90
+ }
91
+ console.log(`\nReachability Check`);
92
+ console.log("═".repeat(70));
93
+ const reachableCount = results.filter((r) => r.reachable).length;
94
+ const unreachableCount = results.filter((r) => !r.reachable).length;
95
+ for (const r of results) {
96
+ const status = r.reachable ? "REACHABLE" : "UNREACHABLE";
97
+ const lineRef = r.lineNumbers.length > 0 ? `L${r.lineNumbers[0]}` : "N/A";
98
+ console.log(` [${status.padEnd(11)}] ${r.ruleId.padEnd(25)} ${lineRef.padEnd(8)} ${r.reason}`);
99
+ }
100
+ console.log(`\n Reachable: ${reachableCount} | Unreachable: ${unreachableCount} | Total: ${results.length}`);
101
+ console.log("═".repeat(70));
102
+ }
103
+ //# sourceMappingURL=finding-reachability-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-reachability-check.js","sourceRoot":"","sources":["../../src/commands/finding-reachability-check.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAc9C,+EAA+E;AAE/E,MAAM,UAAU,2BAA2B,CAAC,IAAc;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,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;;;;;;;;;;;;;;CAcf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA6B,CAAC;IACzF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEvC,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,WAAW,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAyB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACvD,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC;QAClC,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,IAAI,MAAM,GAAG,mBAAmB,CAAC;QAEjC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,gEAAgE;YAChE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,cAAc,IAAI,CAAC,IAAI,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnG,SAAS,GAAG,KAAK,CAAC;oBAClB,MAAM,GAAG,uBAAuB,CAAC;gBACnC,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC7B,SAAS,GAAG,KAAK,CAAC;oBAClB,MAAM,GAAG,eAAe,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,gCAAgC,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,SAAS,GAAG,KAAK,CAAC;gBAClB,MAAM,GAAG,0BAA0B,CAAC;YACtC,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,GAAG,uCAAuC,CAAC;QACnD,CAAC;QAED,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS;YACT,MAAM;YACN,WAAW,EAAE,KAAK;SACnB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAEpE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;QACzD,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAClG,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,cAAc,mBAAmB,gBAAgB,aAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9G,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-audit-export — Export audit data for external compliance tools.
3
+ */
4
+ export declare function runReviewAuditExport(argv: string[]): void;
5
+ //# sourceMappingURL=review-audit-export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-audit-export.d.ts","sourceRoot":"","sources":["../../src/commands/review-audit-export.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiGzD"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Review-audit-export — Export audit data for external compliance tools.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, readdirSync } from "fs";
5
+ import { join } from "path";
6
+ // ─── CLI ────────────────────────────────────────────────────────────────────
7
+ export function runReviewAuditExport(argv) {
8
+ const dirIdx = argv.indexOf("--dir");
9
+ const dir = dirIdx >= 0 ? argv[dirIdx + 1] : ".judges/audit";
10
+ const outIdx = argv.indexOf("--out");
11
+ const exportFormat = argv.indexOf("--export-format");
12
+ const expFmt = exportFormat >= 0 ? argv[exportFormat + 1] : "json";
13
+ const formatIdx = argv.indexOf("--format");
14
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
15
+ if (argv.includes("--help") || argv.includes("-h")) {
16
+ console.log(`
17
+ judges review-audit-export — Export audit data
18
+
19
+ Usage:
20
+ judges review-audit-export [--dir <path>] [--out <path>]
21
+ [--export-format json|csv]
22
+ [--format table|json]
23
+
24
+ Options:
25
+ --dir <path> Audit data directory (default: .judges/audit)
26
+ --out <path> Write export to file
27
+ --export-format <fmt> Export format: json (default), csv
28
+ --format <fmt> Display format: table (default), json
29
+ --help, -h Show this help
30
+ `);
31
+ return;
32
+ }
33
+ if (!existsSync(dir)) {
34
+ console.log(`Audit directory not found: ${dir}`);
35
+ console.log("No audit data to export.");
36
+ return;
37
+ }
38
+ const files = readdirSync(dir).filter((f) => f.endsWith(".json"));
39
+ const records = [];
40
+ for (const file of files) {
41
+ const content = JSON.parse(readFileSync(join(dir, file), "utf-8"));
42
+ if (Array.isArray(content)) {
43
+ records.push(...content);
44
+ }
45
+ else {
46
+ records.push(content);
47
+ }
48
+ }
49
+ records.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
50
+ const byAction = {};
51
+ for (const r of records) {
52
+ byAction[r.action] = (byAction[r.action] ?? 0) + 1;
53
+ }
54
+ const auditExport = {
55
+ exportedAt: new Date().toISOString(),
56
+ records,
57
+ summary: { total: records.length, byAction },
58
+ };
59
+ // Write to file
60
+ if (outIdx >= 0) {
61
+ const outPath = argv[outIdx + 1];
62
+ if (expFmt === "csv") {
63
+ const header = "timestamp,action,actor,detail,source";
64
+ const rows = records.map((r) => `"${r.timestamp}","${r.action}","${r.actor}","${r.detail}","${r.source}"`);
65
+ writeFileSync(outPath, [header, ...rows].join("\n"));
66
+ }
67
+ else {
68
+ writeFileSync(outPath, JSON.stringify(auditExport, null, 2));
69
+ }
70
+ console.log(`Audit exported to: ${outPath} (${expFmt}, ${records.length} records)`);
71
+ return;
72
+ }
73
+ if (format === "json") {
74
+ console.log(JSON.stringify(auditExport, null, 2));
75
+ return;
76
+ }
77
+ console.log(`\nAudit Export`);
78
+ console.log("═".repeat(70));
79
+ console.log(` Records: ${records.length}`);
80
+ if (Object.keys(byAction).length > 0) {
81
+ console.log(" By action:");
82
+ for (const [action, count] of Object.entries(byAction)) {
83
+ console.log(` ${action.padEnd(20)} ${count}`);
84
+ }
85
+ }
86
+ if (records.length > 0) {
87
+ console.log(`\n Latest records:`);
88
+ for (const r of records.slice(-5)) {
89
+ console.log(` ${r.timestamp.padEnd(22)} ${r.action.padEnd(15)} ${r.actor}`);
90
+ }
91
+ }
92
+ console.log("═".repeat(70));
93
+ }
94
+ //# sourceMappingURL=review-audit-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-audit-export.js","sourceRoot":"","sources":["../../src/commands/review-audit-export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-data-retention — Configure data retention policies for review data.
3
+ */
4
+ export declare function runReviewDataRetention(argv: string[]): void;
5
+ //# sourceMappingURL=review-data-retention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-data-retention.d.ts","sourceRoot":"","sources":["../../src/commands/review-data-retention.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2BH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmH3D"}