@kevinrabun/judges 3.60.0 → 3.62.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 (74) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +112 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/ai-provenance.d.ts +5 -0
  6. package/dist/commands/ai-provenance.d.ts.map +1 -0
  7. package/dist/commands/ai-provenance.js +248 -0
  8. package/dist/commands/ai-provenance.js.map +1 -0
  9. package/dist/commands/batch-review.d.ts +5 -0
  10. package/dist/commands/batch-review.d.ts.map +1 -0
  11. package/dist/commands/batch-review.js +181 -0
  12. package/dist/commands/batch-review.js.map +1 -0
  13. package/dist/commands/blame-review.d.ts +5 -0
  14. package/dist/commands/blame-review.d.ts.map +1 -0
  15. package/dist/commands/blame-review.js +270 -0
  16. package/dist/commands/blame-review.js.map +1 -0
  17. package/dist/commands/custom-rule.d.ts +5 -0
  18. package/dist/commands/custom-rule.d.ts.map +1 -0
  19. package/dist/commands/custom-rule.js +211 -0
  20. package/dist/commands/custom-rule.js.map +1 -0
  21. package/dist/commands/diff-review.d.ts +5 -0
  22. package/dist/commands/diff-review.d.ts.map +1 -0
  23. package/dist/commands/diff-review.js +191 -0
  24. package/dist/commands/diff-review.js.map +1 -0
  25. package/dist/commands/evidence-chain.d.ts +5 -0
  26. package/dist/commands/evidence-chain.d.ts.map +1 -0
  27. package/dist/commands/evidence-chain.js +310 -0
  28. package/dist/commands/evidence-chain.js.map +1 -0
  29. package/dist/commands/focus-area.d.ts +6 -0
  30. package/dist/commands/focus-area.d.ts.map +1 -0
  31. package/dist/commands/focus-area.js +193 -0
  32. package/dist/commands/focus-area.js.map +1 -0
  33. package/dist/commands/merge-verdict.d.ts +5 -0
  34. package/dist/commands/merge-verdict.d.ts.map +1 -0
  35. package/dist/commands/merge-verdict.js +288 -0
  36. package/dist/commands/merge-verdict.js.map +1 -0
  37. package/dist/commands/quick-check.d.ts +5 -0
  38. package/dist/commands/quick-check.d.ts.map +1 -0
  39. package/dist/commands/quick-check.js +174 -0
  40. package/dist/commands/quick-check.js.map +1 -0
  41. package/dist/commands/review-compare.d.ts +5 -0
  42. package/dist/commands/review-compare.d.ts.map +1 -0
  43. package/dist/commands/review-compare.js +201 -0
  44. package/dist/commands/review-compare.js.map +1 -0
  45. package/dist/commands/review-contract.d.ts +5 -0
  46. package/dist/commands/review-contract.d.ts.map +1 -0
  47. package/dist/commands/review-contract.js +200 -0
  48. package/dist/commands/review-contract.js.map +1 -0
  49. package/dist/commands/review-explain.d.ts +6 -0
  50. package/dist/commands/review-explain.d.ts.map +1 -0
  51. package/dist/commands/review-explain.js +195 -0
  52. package/dist/commands/review-explain.js.map +1 -0
  53. package/dist/commands/review-gate.d.ts +5 -0
  54. package/dist/commands/review-gate.d.ts.map +1 -0
  55. package/dist/commands/review-gate.js +213 -0
  56. package/dist/commands/review-gate.js.map +1 -0
  57. package/dist/commands/review-handoff.d.ts +5 -0
  58. package/dist/commands/review-handoff.d.ts.map +1 -0
  59. package/dist/commands/review-handoff.js +209 -0
  60. package/dist/commands/review-handoff.js.map +1 -0
  61. package/dist/commands/review-receipt.d.ts +5 -0
  62. package/dist/commands/review-receipt.d.ts.map +1 -0
  63. package/dist/commands/review-receipt.js +221 -0
  64. package/dist/commands/review-receipt.js.map +1 -0
  65. package/dist/commands/severity-tune.d.ts +5 -0
  66. package/dist/commands/severity-tune.d.ts.map +1 -0
  67. package/dist/commands/severity-tune.js +209 -0
  68. package/dist/commands/severity-tune.js.map +1 -0
  69. package/dist/commands/trend-report.d.ts +5 -0
  70. package/dist/commands/trend-report.d.ts.map +1 -0
  71. package/dist/commands/trend-report.js +149 -0
  72. package/dist/commands/trend-report.js.map +1 -0
  73. package/package.json +1 -1
  74. package/server.json +2 -2
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Focus-area — Identify high-risk areas that need the most review attention
3
+ * based on code complexity and pattern density.
4
+ */
5
+ import { readFileSync, readdirSync, statSync } from "fs";
6
+ import { join, extname, relative } from "path";
7
+ // ─── Patterns ──────────────────────────────────────────────────────────────
8
+ const RISK_PATTERNS = [
9
+ { name: "hardcoded-secret", weight: 10, regex: /(?:password|secret|api_key|token)\s*[:=]\s*["'][^"']{8,}/i },
10
+ { name: "eval-usage", weight: 10, regex: /\beval\s*\(/ },
11
+ { name: "sql-concat", weight: 10, regex: /(?:query|execute)\s*\(\s*["'`].*\+/ },
12
+ { name: "xss-risk", weight: 8, regex: /innerHTML\s*=|document\.write\s*\(/ },
13
+ { name: "command-injection", weight: 10, regex: /exec(?:Sync)?\s*\(\s*`[^`]*\$\{/ },
14
+ { name: "empty-catch", weight: 3, regex: /catch\s*\([^)]*\)\s*\{\s*\}/ },
15
+ { name: "any-type", weight: 2, regex: /:\s*any\b/ },
16
+ { name: "unsafe-regex", weight: 7, regex: /new\s+RegExp\s*\([^)]*\+/ },
17
+ { name: "nested-callback", weight: 4, regex: /\)\s*=>\s*\{[^}]*\)\s*=>\s*\{/ },
18
+ { name: "deep-nesting", weight: 5, regex: /^\s{16,}\S/ },
19
+ { name: "deprecated-api", weight: 3, regex: /new\s+Buffer\s*\(|\.substr\s*\(/ },
20
+ ];
21
+ // ─── Complexity estimation ─────────────────────────────────────────────────
22
+ function estimateComplexity(content) {
23
+ const lines = content.split("\n");
24
+ let complexity = 0;
25
+ for (const line of lines) {
26
+ // Control flow
27
+ if (/\b(?:if|else if|switch|case|while|for|catch)\b/.test(line))
28
+ complexity++;
29
+ // Logical operators
30
+ if (/&&|\|\|/.test(line))
31
+ complexity++;
32
+ // Ternary
33
+ if (/[^?][?][^?]/.test(line))
34
+ complexity += 0.5;
35
+ // Nested functions
36
+ if (/(?:function\s+\w+|=>\s*\{)/.test(line))
37
+ complexity += 0.5;
38
+ }
39
+ return Math.round(complexity);
40
+ }
41
+ // ─── Helpers ────────────────────────────────────────────────────────────────
42
+ function collectSourceFiles(dir) {
43
+ const exts = new Set([".ts", ".js", ".tsx", ".jsx", ".py", ".java", ".go", ".rs", ".cs"]);
44
+ const files = [];
45
+ const skipDirs = new Set(["node_modules", ".git", "dist", "build", "coverage"]);
46
+ function walk(d) {
47
+ let entries;
48
+ try {
49
+ entries = readdirSync(d);
50
+ }
51
+ catch {
52
+ return;
53
+ }
54
+ for (const name of entries) {
55
+ if (skipDirs.has(name))
56
+ continue;
57
+ const full = join(d, name);
58
+ try {
59
+ const st = statSync(full);
60
+ if (st.isDirectory())
61
+ walk(full);
62
+ else if (exts.has(extname(name)))
63
+ files.push(full);
64
+ }
65
+ catch {
66
+ // skip
67
+ }
68
+ }
69
+ }
70
+ walk(dir);
71
+ return files;
72
+ }
73
+ function analyzeRisk(files, baseDir) {
74
+ const fileRisks = [];
75
+ for (const filePath of files) {
76
+ let content;
77
+ try {
78
+ content = readFileSync(filePath, "utf-8");
79
+ }
80
+ catch {
81
+ continue;
82
+ }
83
+ const lines = content.split("\n");
84
+ const lineCount = lines.length;
85
+ const complexity = estimateComplexity(content);
86
+ const patternHits = new Map();
87
+ let totalWeight = 0;
88
+ for (const line of lines) {
89
+ for (const pat of RISK_PATTERNS) {
90
+ if (pat.regex.test(line)) {
91
+ totalWeight += pat.weight;
92
+ patternHits.set(pat.name, (patternHits.get(pat.name) || 0) + 1);
93
+ }
94
+ }
95
+ }
96
+ const findingCount = [...patternHits.values()].reduce((a, b) => a + b, 0);
97
+ const patternDensity = lineCount > 0 ? Math.round((findingCount / lineCount) * 1000) / 10 : 0;
98
+ // Risk score: weighted sum of complexity, pattern weight, and density
99
+ const riskScore = Math.round(complexity * 0.3 + totalWeight * 2 + patternDensity * 10);
100
+ if (riskScore > 0) {
101
+ const topPatterns = [...patternHits.entries()]
102
+ .sort((a, b) => b[1] - a[1])
103
+ .slice(0, 3)
104
+ .map(([name]) => name);
105
+ fileRisks.push({
106
+ file: relative(baseDir, filePath),
107
+ riskScore,
108
+ complexity,
109
+ patternDensity,
110
+ lineCount,
111
+ findingCount,
112
+ topPatterns,
113
+ });
114
+ }
115
+ }
116
+ fileRisks.sort((a, b) => b.riskScore - a.riskScore);
117
+ const distribution = { high: 0, medium: 0, low: 0 };
118
+ for (const fr of fileRisks) {
119
+ if (fr.riskScore >= 50)
120
+ distribution.high++;
121
+ else if (fr.riskScore >= 20)
122
+ distribution.medium++;
123
+ else
124
+ distribution.low++;
125
+ }
126
+ const summary = distribution.high > 0
127
+ ? `${distribution.high} high-risk file(s) need immediate review attention.`
128
+ : fileRisks.length > 0
129
+ ? `No critical risk areas. ${fileRisks.length} files have minor improvements available.`
130
+ : "No risk areas detected in scanned files.";
131
+ return {
132
+ filesAnalyzed: files.length,
133
+ highRiskFiles: fileRisks.slice(0, 20),
134
+ riskDistribution: distribution,
135
+ summary,
136
+ };
137
+ }
138
+ // ─── CLI ────────────────────────────────────────────────────────────────────
139
+ export function runFocusArea(argv) {
140
+ if (argv.includes("--help") || argv.includes("-h")) {
141
+ console.log(`
142
+ judges focus-area — Identify high-risk areas needing review attention
143
+
144
+ Usage:
145
+ judges focus-area [dir] Analyze risk areas
146
+ judges focus-area --top 10 Show top N files
147
+ judges focus-area --format json JSON output
148
+
149
+ Options:
150
+ [dir] Target directory (default: .)
151
+ --top <n> Number of files to show (default: 20)
152
+ --format json JSON output
153
+ --help, -h Show this help
154
+
155
+ Combines code complexity and security pattern density to rank files by
156
+ risk. Use this to prioritize review effort where it matters most.
157
+ `);
158
+ return;
159
+ }
160
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
161
+ const dir = argv.find((a) => !a.startsWith("-") &&
162
+ a !== "focus-area" &&
163
+ argv[argv.indexOf(a) - 1] !== "--format" &&
164
+ argv[argv.indexOf(a) - 1] !== "--top") || ".";
165
+ const topN = parseInt(argv.find((_a, i) => argv[i - 1] === "--top") || "20", 10);
166
+ const files = collectSourceFiles(dir);
167
+ if (files.length === 0) {
168
+ console.log("No source files found.");
169
+ return;
170
+ }
171
+ const result = analyzeRisk(files, dir);
172
+ if (format === "json") {
173
+ console.log(JSON.stringify(result, null, 2));
174
+ return;
175
+ }
176
+ console.log(`\n Focus Area Analysis\n ─────────────────────────────`);
177
+ console.log(` Files analyzed: ${result.filesAnalyzed}`);
178
+ console.log(` Risk distribution: 🔴 ${result.riskDistribution.high} high 🟡 ${result.riskDistribution.medium} medium 🟢 ${result.riskDistribution.low} low`);
179
+ console.log(`\n ${result.summary}`);
180
+ const display = result.highRiskFiles.slice(0, topN);
181
+ if (display.length > 0) {
182
+ console.log("\n Highest risk files:");
183
+ for (const fr of display) {
184
+ const icon = fr.riskScore >= 50 ? "🔴" : fr.riskScore >= 20 ? "🟡" : "🟢";
185
+ console.log(` ${icon} [${fr.riskScore}] ${fr.file} (${fr.lineCount} lines, ${fr.findingCount} findings, complexity: ${fr.complexity})`);
186
+ if (fr.topPatterns.length > 0) {
187
+ console.log(` Top patterns: ${fr.topPatterns.join(", ")}`);
188
+ }
189
+ }
190
+ }
191
+ console.log();
192
+ }
193
+ //# sourceMappingURL=focus-area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-area.js","sourceRoot":"","sources":["../../src/commands/focus-area.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Merge-verdict — single authoritative MERGE/HOLD decision with structured rationale.
3
+ */
4
+ export declare function runMergeVerdict(argv: string[]): void;
5
+ //# sourceMappingURL=merge-verdict.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-verdict.d.ts","sourceRoot":"","sources":["../../src/commands/merge-verdict.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyRH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoEpD"}
@@ -0,0 +1,288 @@
1
+ /**
2
+ * Merge-verdict — single authoritative MERGE/HOLD decision with structured rationale.
3
+ */
4
+ import { readFileSync, readdirSync, statSync } from "fs";
5
+ import { join, extname, relative } from "path";
6
+ // ─── File Collection ────────────────────────────────────────────────────────
7
+ const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".cs", ".rs"]);
8
+ function collectFiles(dir, max = 300) {
9
+ const files = [];
10
+ function walk(d) {
11
+ if (files.length >= max)
12
+ return;
13
+ let entries;
14
+ try {
15
+ entries = readdirSync(d);
16
+ }
17
+ catch {
18
+ return;
19
+ }
20
+ for (const e of entries) {
21
+ if (files.length >= max)
22
+ return;
23
+ if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
24
+ continue;
25
+ const full = join(d, e);
26
+ try {
27
+ if (statSync(full).isDirectory())
28
+ walk(full);
29
+ else if (CODE_EXTS.has(extname(full)))
30
+ files.push(full);
31
+ }
32
+ catch {
33
+ /* skip */
34
+ }
35
+ }
36
+ }
37
+ walk(dir);
38
+ return files;
39
+ }
40
+ const DIMENSION_PATTERNS = [
41
+ // Security (blocking)
42
+ {
43
+ regex: /\beval\s*\(/,
44
+ category: "Security",
45
+ title: "eval() injection",
46
+ severity: "critical",
47
+ dimension: "security",
48
+ blocking: true,
49
+ },
50
+ {
51
+ regex: /(?:password|secret|api[_-]?key)\s*[:=]\s*['"][^'"]{4,}['"]/,
52
+ category: "Security",
53
+ title: "Hardcoded credential",
54
+ severity: "critical",
55
+ dimension: "security",
56
+ blocking: true,
57
+ },
58
+ {
59
+ regex: /\.innerHTML\s*=/,
60
+ category: "Security",
61
+ title: "XSS via innerHTML",
62
+ severity: "high",
63
+ dimension: "security",
64
+ blocking: true,
65
+ },
66
+ {
67
+ regex: /(?:exec|spawn)\s*\([^)]*\+/,
68
+ category: "Security",
69
+ title: "Command injection",
70
+ severity: "critical",
71
+ dimension: "security",
72
+ blocking: true,
73
+ },
74
+ {
75
+ regex: /SELECT.*FROM.*\+\s*(?:req|input|user|param)/,
76
+ category: "Security",
77
+ title: "SQL injection",
78
+ severity: "critical",
79
+ dimension: "security",
80
+ blocking: true,
81
+ },
82
+ // Quality (non-blocking)
83
+ {
84
+ regex: /catch\s*\(\s*\w*\s*\)\s*\{\s*\}/,
85
+ category: "Quality",
86
+ title: "Empty catch block",
87
+ severity: "medium",
88
+ dimension: "quality",
89
+ blocking: false,
90
+ },
91
+ {
92
+ regex: /console\.log\s*\(/,
93
+ category: "Quality",
94
+ title: "Console statement",
95
+ severity: "low",
96
+ dimension: "quality",
97
+ blocking: false,
98
+ },
99
+ {
100
+ regex: /debugger\b/,
101
+ category: "Quality",
102
+ title: "Debugger statement",
103
+ severity: "medium",
104
+ dimension: "quality",
105
+ blocking: false,
106
+ },
107
+ {
108
+ regex: /TODO|FIXME|HACK|XXX/,
109
+ category: "Quality",
110
+ title: "Open TODO",
111
+ severity: "low",
112
+ dimension: "quality",
113
+ blocking: false,
114
+ },
115
+ // Correctness (blocking for critical)
116
+ {
117
+ regex: /new\s+Buffer\s*\(/,
118
+ category: "Correctness",
119
+ title: "Deprecated Buffer()",
120
+ severity: "high",
121
+ dimension: "correctness",
122
+ blocking: false,
123
+ },
124
+ {
125
+ regex: /process\.exit\s*\(\s*\)/,
126
+ category: "Correctness",
127
+ title: "Ungraceful exit",
128
+ severity: "medium",
129
+ dimension: "correctness",
130
+ blocking: false,
131
+ },
132
+ // Compliance
133
+ {
134
+ regex: /\/\/\s*(?:eslint|tslint|prettier)-disable/,
135
+ category: "Compliance",
136
+ title: "Linter suppression",
137
+ severity: "low",
138
+ dimension: "compliance",
139
+ blocking: false,
140
+ },
141
+ ];
142
+ // ─── Analysis ───────────────────────────────────────────────────────────────
143
+ function analyzeFile(filepath, baseDir) {
144
+ const findings = [];
145
+ let content;
146
+ try {
147
+ content = readFileSync(filepath, "utf-8");
148
+ }
149
+ catch {
150
+ return findings;
151
+ }
152
+ const lines = content.split("\n");
153
+ const rel = relative(baseDir, filepath);
154
+ for (let i = 0; i < lines.length; i++) {
155
+ const line = lines[i];
156
+ const trimmed = line.trim();
157
+ if (trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*"))
158
+ continue;
159
+ for (const pattern of DIMENSION_PATTERNS) {
160
+ if (pattern.regex.test(line)) {
161
+ findings.push({
162
+ file: rel,
163
+ line: i + 1,
164
+ severity: pattern.severity,
165
+ category: pattern.category,
166
+ title: pattern.title,
167
+ blocking: pattern.blocking,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ return findings;
173
+ }
174
+ function renderDecision(allFindings, threshold) {
175
+ const blocking = allFindings.filter((f) => f.blocking);
176
+ const accepted = allFindings.filter((f) => !f.blocking);
177
+ // Dimension scores
178
+ const dimFindings = (dim) => allFindings.filter((f) => {
179
+ const p = DIMENSION_PATTERNS.find((dp) => dp.title === f.title);
180
+ return p && p.dimension === dim;
181
+ });
182
+ const dimScore = (dim) => {
183
+ const df = dimFindings(dim);
184
+ const crits = df.filter((f) => f.severity === "critical").length;
185
+ const highs = df.filter((f) => f.severity === "high").length;
186
+ return Math.max(0, 100 -
187
+ crits * 25 -
188
+ highs * 12 -
189
+ df.filter((f) => f.severity === "medium").length * 5 -
190
+ df.filter((f) => f.severity === "low").length);
191
+ };
192
+ const dimensions = {
193
+ security: dimScore("security"),
194
+ quality: dimScore("quality"),
195
+ correctness: dimScore("correctness"),
196
+ compliance: dimScore("compliance"),
197
+ };
198
+ const riskScore = Math.round(dimensions.security * 0.4 + dimensions.quality * 0.2 + dimensions.correctness * 0.25 + dimensions.compliance * 0.15);
199
+ const decision = blocking.length > 0 || riskScore < threshold ? "HOLD" : "MERGE";
200
+ const confidence = blocking.length === 0 ? Math.min(95, riskScore) : Math.max(60, 100 - blocking.length * 10);
201
+ const rationale = [];
202
+ if (blocking.length > 0)
203
+ rationale.push(`${blocking.length} blocking finding(s) require resolution before merge`);
204
+ if (dimensions.security < 70)
205
+ rationale.push(`Security score (${dimensions.security}) is below acceptable threshold`);
206
+ if (dimensions.correctness < 70)
207
+ rationale.push(`Correctness score (${dimensions.correctness}) indicates potential bugs`);
208
+ if (accepted.length > 0)
209
+ rationale.push(`${accepted.length} non-blocking finding(s) accepted as known risks`);
210
+ if (decision === "MERGE")
211
+ rationale.push(`Risk score (${riskScore}) meets or exceeds threshold (${threshold})`);
212
+ const summary = decision === "MERGE"
213
+ ? `MERGE — Code passes review with ${accepted.length} accepted risk(s). Risk score: ${riskScore}/100.`
214
+ : `HOLD — ${blocking.length} blocking finding(s) and risk score ${riskScore}/100 (threshold: ${threshold}).`;
215
+ return {
216
+ decision,
217
+ confidence,
218
+ riskScore,
219
+ blockingFindings: blocking,
220
+ acceptedRisks: accepted,
221
+ dimensions,
222
+ rationale,
223
+ summary,
224
+ };
225
+ }
226
+ // ─── CLI ────────────────────────────────────────────────────────────────────
227
+ export function runMergeVerdict(argv) {
228
+ if (argv.includes("--help") || argv.includes("-h")) {
229
+ console.log(`
230
+ judges merge-verdict — Single authoritative MERGE/HOLD decision
231
+
232
+ Usage:
233
+ judges merge-verdict [dir]
234
+ judges merge-verdict src/ --threshold 75 --format json
235
+
236
+ Options:
237
+ [dir] Directory to scan (default: .)
238
+ --threshold <n> Minimum risk score for MERGE (default: 70)
239
+ --format json JSON output (for CI/CD integration)
240
+ --help, -h Show this help
241
+
242
+ Synthesizes security, quality, correctness, and compliance dimensions
243
+ into one MERGE or HOLD decision with structured rationale.
244
+ `);
245
+ return;
246
+ }
247
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
248
+ const threshStr = argv.find((_a, i) => argv[i - 1] === "--threshold");
249
+ const threshold = threshStr ? parseInt(threshStr, 10) : 70;
250
+ const dir = argv.find((a) => !a.startsWith("-") &&
251
+ argv.indexOf(a) > 0 &&
252
+ argv[argv.indexOf(a) - 1] !== "--format" &&
253
+ argv[argv.indexOf(a) - 1] !== "--threshold") || ".";
254
+ const files = collectFiles(dir);
255
+ const allFindings = [];
256
+ for (const f of files)
257
+ allFindings.push(...analyzeFile(f, dir));
258
+ const result = renderDecision(allFindings, threshold);
259
+ if (format === "json") {
260
+ console.log(JSON.stringify({ ...result, timestamp: new Date().toISOString() }, null, 2));
261
+ }
262
+ else {
263
+ const icon = result.decision === "MERGE" ? "✅" : "❌";
264
+ console.log(`\n ${icon} ${result.decision} (confidence: ${result.confidence}%)\n ─────────────────────────────`);
265
+ console.log(` Risk Score: ${result.riskScore}/100 (threshold: ${threshold})`);
266
+ console.log(` Security: ${result.dimensions.security}/100`);
267
+ console.log(` Quality: ${result.dimensions.quality}/100`);
268
+ console.log(` Correctness: ${result.dimensions.correctness}/100`);
269
+ console.log(` Compliance: ${result.dimensions.compliance}/100\n`);
270
+ if (result.blockingFindings.length > 0) {
271
+ console.log(` Blocking (${result.blockingFindings.length}):`);
272
+ for (const f of result.blockingFindings.slice(0, 10)) {
273
+ console.log(` 🔴 [${f.category}] ${f.title} — ${f.file}:${f.line}`);
274
+ }
275
+ console.log();
276
+ }
277
+ if (result.rationale.length > 0) {
278
+ console.log(` Rationale:`);
279
+ for (const r of result.rationale)
280
+ console.log(` → ${r}`);
281
+ console.log();
282
+ }
283
+ console.log(` ${result.summary}\n`);
284
+ if (result.decision === "HOLD")
285
+ process.exitCode = 1;
286
+ }
287
+ }
288
+ //# sourceMappingURL=merge-verdict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-verdict.js","sourceRoot":"","sources":["../../src/commands/merge-verdict.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Quick-check — sub-100ms pattern-only review for real-time save-on-type feedback.
3
+ */
4
+ export declare function runQuickCheck(argv: string[]): void;
5
+ //# sourceMappingURL=quick-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quick-check.d.ts","sourceRoot":"","sources":["../../src/commands/quick-check.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2JH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8DlD"}