@nxuss/lemma 0.9.1 → 0.9.2
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.
- package/README.md +17 -5
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +52 -1
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +259 -0
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/pr-review/PRReviewEngine.d.ts +4 -0
- package/dist/cjs/pr-review/PRReviewEngine.d.ts.map +1 -0
- package/dist/cjs/pr-review/PRReviewEngine.js +203 -0
- package/dist/cjs/pr-review/PRReviewEngine.js.map +1 -0
- package/dist/cjs/pr-review/ReviewStore.d.ts +9 -0
- package/dist/cjs/pr-review/ReviewStore.d.ts.map +1 -0
- package/dist/cjs/pr-review/ReviewStore.js +29 -0
- package/dist/cjs/pr-review/ReviewStore.js.map +1 -0
- package/dist/cjs/pr-review/adapters/AzureDevOpsAdapter.d.ts +18 -0
- package/dist/cjs/pr-review/adapters/AzureDevOpsAdapter.d.ts.map +1 -0
- package/dist/cjs/pr-review/adapters/AzureDevOpsAdapter.js +156 -0
- package/dist/cjs/pr-review/adapters/AzureDevOpsAdapter.js.map +1 -0
- package/dist/cjs/pr-review/adapters/GitHubAdapter.d.ts +18 -0
- package/dist/cjs/pr-review/adapters/GitHubAdapter.d.ts.map +1 -0
- package/dist/cjs/pr-review/adapters/GitHubAdapter.js +106 -0
- package/dist/cjs/pr-review/adapters/GitHubAdapter.js.map +1 -0
- package/dist/cjs/pr-review/adapters/GitLabAdapter.d.ts +19 -0
- package/dist/cjs/pr-review/adapters/GitLabAdapter.d.ts.map +1 -0
- package/dist/cjs/pr-review/adapters/GitLabAdapter.js +137 -0
- package/dist/cjs/pr-review/adapters/GitLabAdapter.js.map +1 -0
- package/dist/cjs/pr-review/adapters/GitPlatformAdapter.d.ts +14 -0
- package/dist/cjs/pr-review/adapters/GitPlatformAdapter.d.ts.map +1 -0
- package/dist/cjs/pr-review/adapters/GitPlatformAdapter.js +3 -0
- package/dist/cjs/pr-review/adapters/GitPlatformAdapter.js.map +1 -0
- package/dist/cjs/pr-review/adapters/index.d.ts +5 -0
- package/dist/cjs/pr-review/adapters/index.d.ts.map +1 -0
- package/dist/cjs/pr-review/adapters/index.js +10 -0
- package/dist/cjs/pr-review/adapters/index.js.map +1 -0
- package/dist/cjs/pr-review/analyzers/QualityGrader.d.ts +7 -0
- package/dist/cjs/pr-review/analyzers/QualityGrader.d.ts.map +1 -0
- package/dist/cjs/pr-review/analyzers/QualityGrader.js +154 -0
- package/dist/cjs/pr-review/analyzers/QualityGrader.js.map +1 -0
- package/dist/cjs/pr-review/analyzers/RegressionDetector.d.ts +7 -0
- package/dist/cjs/pr-review/analyzers/RegressionDetector.d.ts.map +1 -0
- package/dist/cjs/pr-review/analyzers/RegressionDetector.js +151 -0
- package/dist/cjs/pr-review/analyzers/RegressionDetector.js.map +1 -0
- package/dist/cjs/pr-review/analyzers/SecurityScanner.d.ts +7 -0
- package/dist/cjs/pr-review/analyzers/SecurityScanner.d.ts.map +1 -0
- package/dist/cjs/pr-review/analyzers/SecurityScanner.js +110 -0
- package/dist/cjs/pr-review/analyzers/SecurityScanner.js.map +1 -0
- package/dist/cjs/pr-review/analyzers/StaticAnalyzer.d.ts +7 -0
- package/dist/cjs/pr-review/analyzers/StaticAnalyzer.d.ts.map +1 -0
- package/dist/cjs/pr-review/analyzers/StaticAnalyzer.js +237 -0
- package/dist/cjs/pr-review/analyzers/StaticAnalyzer.js.map +1 -0
- package/dist/cjs/pr-review/analyzers/index.d.ts +9 -0
- package/dist/cjs/pr-review/analyzers/index.d.ts.map +1 -0
- package/dist/cjs/pr-review/analyzers/index.js +12 -0
- package/dist/cjs/pr-review/analyzers/index.js.map +1 -0
- package/dist/cjs/pr-review/bridge/BrainBridge.d.ts +23 -0
- package/dist/cjs/pr-review/bridge/BrainBridge.d.ts.map +1 -0
- package/dist/cjs/pr-review/bridge/BrainBridge.js +100 -0
- package/dist/cjs/pr-review/bridge/BrainBridge.js.map +1 -0
- package/dist/cjs/pr-review/bridge/index.d.ts +2 -0
- package/dist/cjs/pr-review/bridge/index.d.ts.map +1 -0
- package/dist/cjs/pr-review/bridge/index.js +6 -0
- package/dist/cjs/pr-review/bridge/index.js.map +1 -0
- package/dist/cjs/pr-review/index.d.ts +5 -0
- package/dist/cjs/pr-review/index.d.ts.map +1 -0
- package/dist/cjs/pr-review/index.js +12 -0
- package/dist/cjs/pr-review/index.js.map +1 -0
- package/dist/cjs/pr-review/reviewRunner.d.ts +25 -0
- package/dist/cjs/pr-review/reviewRunner.d.ts.map +1 -0
- package/dist/cjs/pr-review/reviewRunner.js +97 -0
- package/dist/cjs/pr-review/reviewRunner.js.map +1 -0
- package/dist/cjs/pr-review/types.d.ts +80 -0
- package/dist/cjs/pr-review/types.d.ts.map +1 -0
- package/dist/cjs/pr-review/types.js +3 -0
- package/dist/cjs/pr-review/types.js.map +1 -0
- package/dist/cjs/pr-review/webhook/WebhookServer.d.ts +3 -0
- package/dist/cjs/pr-review/webhook/WebhookServer.d.ts.map +1 -0
- package/dist/cjs/pr-review/webhook/WebhookServer.js +114 -0
- package/dist/cjs/pr-review/webhook/WebhookServer.js.map +1 -0
- package/dist/cjs/pr-review/webhook/index.d.ts +2 -0
- package/dist/cjs/pr-review/webhook/index.d.ts.map +1 -0
- package/dist/cjs/pr-review/webhook/index.js +6 -0
- package/dist/cjs/pr-review/webhook/index.js.map +1 -0
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +52 -1
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +259 -0
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/pr-review/PRReviewEngine.d.ts +4 -0
- package/dist/esm/pr-review/PRReviewEngine.d.ts.map +1 -0
- package/dist/esm/pr-review/PRReviewEngine.js +199 -0
- package/dist/esm/pr-review/PRReviewEngine.js.map +1 -0
- package/dist/esm/pr-review/ReviewStore.d.ts +9 -0
- package/dist/esm/pr-review/ReviewStore.d.ts.map +1 -0
- package/dist/esm/pr-review/ReviewStore.js +26 -0
- package/dist/esm/pr-review/ReviewStore.js.map +1 -0
- package/dist/esm/pr-review/adapters/AzureDevOpsAdapter.d.ts +18 -0
- package/dist/esm/pr-review/adapters/AzureDevOpsAdapter.d.ts.map +1 -0
- package/dist/esm/pr-review/adapters/AzureDevOpsAdapter.js +149 -0
- package/dist/esm/pr-review/adapters/AzureDevOpsAdapter.js.map +1 -0
- package/dist/esm/pr-review/adapters/GitHubAdapter.d.ts +18 -0
- package/dist/esm/pr-review/adapters/GitHubAdapter.d.ts.map +1 -0
- package/dist/esm/pr-review/adapters/GitHubAdapter.js +99 -0
- package/dist/esm/pr-review/adapters/GitHubAdapter.js.map +1 -0
- package/dist/esm/pr-review/adapters/GitLabAdapter.d.ts +19 -0
- package/dist/esm/pr-review/adapters/GitLabAdapter.d.ts.map +1 -0
- package/dist/esm/pr-review/adapters/GitLabAdapter.js +130 -0
- package/dist/esm/pr-review/adapters/GitLabAdapter.js.map +1 -0
- package/dist/esm/pr-review/adapters/GitPlatformAdapter.d.ts +14 -0
- package/dist/esm/pr-review/adapters/GitPlatformAdapter.d.ts.map +1 -0
- package/dist/esm/pr-review/adapters/GitPlatformAdapter.js +2 -0
- package/dist/esm/pr-review/adapters/GitPlatformAdapter.js.map +1 -0
- package/dist/esm/pr-review/adapters/index.d.ts +5 -0
- package/dist/esm/pr-review/adapters/index.d.ts.map +1 -0
- package/dist/esm/pr-review/adapters/index.js +4 -0
- package/dist/esm/pr-review/adapters/index.js.map +1 -0
- package/dist/esm/pr-review/analyzers/QualityGrader.d.ts +7 -0
- package/dist/esm/pr-review/analyzers/QualityGrader.d.ts.map +1 -0
- package/dist/esm/pr-review/analyzers/QualityGrader.js +151 -0
- package/dist/esm/pr-review/analyzers/QualityGrader.js.map +1 -0
- package/dist/esm/pr-review/analyzers/RegressionDetector.d.ts +7 -0
- package/dist/esm/pr-review/analyzers/RegressionDetector.d.ts.map +1 -0
- package/dist/esm/pr-review/analyzers/RegressionDetector.js +145 -0
- package/dist/esm/pr-review/analyzers/RegressionDetector.js.map +1 -0
- package/dist/esm/pr-review/analyzers/SecurityScanner.d.ts +7 -0
- package/dist/esm/pr-review/analyzers/SecurityScanner.d.ts.map +1 -0
- package/dist/esm/pr-review/analyzers/SecurityScanner.js +107 -0
- package/dist/esm/pr-review/analyzers/SecurityScanner.js.map +1 -0
- package/dist/esm/pr-review/analyzers/StaticAnalyzer.d.ts +7 -0
- package/dist/esm/pr-review/analyzers/StaticAnalyzer.d.ts.map +1 -0
- package/dist/esm/pr-review/analyzers/StaticAnalyzer.js +201 -0
- package/dist/esm/pr-review/analyzers/StaticAnalyzer.js.map +1 -0
- package/dist/esm/pr-review/analyzers/index.d.ts +9 -0
- package/dist/esm/pr-review/analyzers/index.d.ts.map +1 -0
- package/dist/esm/pr-review/analyzers/index.js +5 -0
- package/dist/esm/pr-review/analyzers/index.js.map +1 -0
- package/dist/esm/pr-review/bridge/BrainBridge.d.ts +23 -0
- package/dist/esm/pr-review/bridge/BrainBridge.d.ts.map +1 -0
- package/dist/esm/pr-review/bridge/BrainBridge.js +93 -0
- package/dist/esm/pr-review/bridge/BrainBridge.js.map +1 -0
- package/dist/esm/pr-review/bridge/index.d.ts +2 -0
- package/dist/esm/pr-review/bridge/index.d.ts.map +1 -0
- package/dist/esm/pr-review/bridge/index.js +2 -0
- package/dist/esm/pr-review/bridge/index.js.map +1 -0
- package/dist/esm/pr-review/index.d.ts +5 -0
- package/dist/esm/pr-review/index.d.ts.map +1 -0
- package/dist/esm/pr-review/index.js +3 -0
- package/dist/esm/pr-review/index.js.map +1 -0
- package/dist/esm/pr-review/reviewRunner.d.ts +25 -0
- package/dist/esm/pr-review/reviewRunner.d.ts.map +1 -0
- package/dist/esm/pr-review/reviewRunner.js +92 -0
- package/dist/esm/pr-review/reviewRunner.js.map +1 -0
- package/dist/esm/pr-review/types.d.ts +80 -0
- package/dist/esm/pr-review/types.d.ts.map +1 -0
- package/dist/esm/pr-review/types.js +2 -0
- package/dist/esm/pr-review/types.js.map +1 -0
- package/dist/esm/pr-review/webhook/WebhookServer.d.ts +3 -0
- package/dist/esm/pr-review/webhook/WebhookServer.d.ts.map +1 -0
- package/dist/esm/pr-review/webhook/WebhookServer.js +108 -0
- package/dist/esm/pr-review/webhook/WebhookServer.js.map +1 -0
- package/dist/esm/pr-review/webhook/index.d.ts +2 -0
- package/dist/esm/pr-review/webhook/index.d.ts.map +1 -0
- package/dist/esm/pr-review/webhook/index.js +2 -0
- package/dist/esm/pr-review/webhook/index.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const SECRET_PATTERNS = [
|
|
2
|
+
{ ruleId: "sec-api-key", pattern: /(?:sk-|pk-|api[_-]?key|apikey)[\s"':=]+([A-Za-z0-9_\-]{20,})/gi, label: "API key", severity: "CRITICAL" },
|
|
3
|
+
{ ruleId: "sec-password", pattern: /(?:password|passwd|pwd)[\s"':=]+([A-Za-z0-9!@#$%^&*()_+\-={}|;:',.<>?]{8,})/gi, label: "Password", severity: "CRITICAL" },
|
|
4
|
+
{ ruleId: "sec-token", pattern: /(?:token|secret|auth)[\s"':=]+([A-Za-z0-9_\-\.]{16,})/gi, label: "Token/Secret", severity: "CRITICAL" },
|
|
5
|
+
{ ruleId: "sec-private-key", pattern: /-----BEGIN\s+(RSA|EC|DSA|OPENSSH)\s+PRIVATE\s+KEY-----/, label: "Private key", severity: "CRITICAL" },
|
|
6
|
+
{ ruleId: "sec-connection-string", pattern: /(?:mongodb|postgresql|mysql|redis):\/\/[^\s"']+/gi, label: "Connection string", severity: "CRITICAL" },
|
|
7
|
+
];
|
|
8
|
+
const SQL_INJECTION_PATTERNS = [
|
|
9
|
+
{ ruleId: "sec-sql-concat", pattern: /(?:SELECT|INSERT|UPDATE|DELETE)\s+.*?["'`]\s*\+\s*(?:req\.|params|body|query|input|userInput|variable)/is, label: "SQL concatenation" },
|
|
10
|
+
{ ruleId: "sec-sql-template", pattern: /(?:query|execute|run)\s*\(\s*`[^`]*\$\{/gi, label: "SQL template injection" },
|
|
11
|
+
];
|
|
12
|
+
const CI_PATTERNS = [
|
|
13
|
+
{ ruleId: "sec-exec-user-input", pattern: /(?:exec|execSync|spawn|execFile)\s*\(\s*(?:`[^`]*\$\{|["'][^"']*["']\s*\+)/gi, label: "Command injection via exec/spawn", severity: "CRITICAL" },
|
|
14
|
+
{ ruleId: "sec-eval", pattern: /\beval\s*\(\s*(?:req\.|params|body|query|input|userInput)/gi, label: "eval() with user input", severity: "CRITICAL" },
|
|
15
|
+
];
|
|
16
|
+
const XSS_PATTERNS = [
|
|
17
|
+
{ ruleId: "sec-inner-html", pattern: /\.innerHTML\s*=\s*(?:`[^`]*\$\{|["'][^"']*["']\s*\+)/gi, label: "innerHTML assignment", severity: "HIGH" },
|
|
18
|
+
{ ruleId: "sec-dangerously-set", pattern: /dangerouslySetInnerHTML/gi, label: "dangerouslySetInnerHTML", severity: "MEDIUM" },
|
|
19
|
+
];
|
|
20
|
+
const PT_PATTERNS = [
|
|
21
|
+
{ ruleId: "sec-path-traversal", pattern: /(?:readFile|readFileSync|writeFile|writeFileSync|unlink|unlinkSync|existsSync)\s*\(\s*(?:`[^`]*\$\{|["'][^"']*["']\s*\+)/gi, label: "Path traversal risk", severity: "HIGH" },
|
|
22
|
+
];
|
|
23
|
+
const PROTO_PATTERNS = [
|
|
24
|
+
{ ruleId: "sec-proto-pollution", pattern: /\[["']__proto__["']\]|\.__proto__\s*=|Object\.assign\s*\(\s*\{\}/gi, label: "Prototype pollution", severity: "HIGH" },
|
|
25
|
+
];
|
|
26
|
+
export function analyzeSecurity(diffFiles) {
|
|
27
|
+
const findings = [];
|
|
28
|
+
let totalScore = 100;
|
|
29
|
+
for (const df of diffFiles) {
|
|
30
|
+
if (!df.content || df.status === "deleted")
|
|
31
|
+
continue;
|
|
32
|
+
const lines = df.content.split("\n");
|
|
33
|
+
const allPatterns = [
|
|
34
|
+
...SECRET_PATTERNS,
|
|
35
|
+
...CI_PATTERNS,
|
|
36
|
+
...XSS_PATTERNS,
|
|
37
|
+
...PT_PATTERNS,
|
|
38
|
+
...PROTO_PATTERNS,
|
|
39
|
+
];
|
|
40
|
+
for (const p of allPatterns) {
|
|
41
|
+
const matches = df.content.match(p.pattern);
|
|
42
|
+
if (matches) {
|
|
43
|
+
const lineNum = lines.findIndex(l => l.match(p.pattern)) + 1;
|
|
44
|
+
findings.push({
|
|
45
|
+
ruleId: p.ruleId,
|
|
46
|
+
severity: p.severity,
|
|
47
|
+
category: "security",
|
|
48
|
+
filePath: df.path,
|
|
49
|
+
line: lineNum > 0 ? lineNum : undefined,
|
|
50
|
+
message: `${p.label} detected`,
|
|
51
|
+
detail: `Security vulnerability: ${p.label} found in changed code.`,
|
|
52
|
+
suggestion: p.ruleId === "sec-api-key" ? `Remove hardcoded credentials. Use environment variables or a secrets manager.` :
|
|
53
|
+
p.ruleId === "sec-sql-concat" ? `Use parameterized queries or an ORM instead of string concatenation.` :
|
|
54
|
+
p.ruleId === "sec-exec-user-input" ? `Avoid executing user input. Use exec only with sanitized, hardcoded commands.` :
|
|
55
|
+
p.ruleId === "sec-inner-html" ? `Use textContent or safely sanitize HTML before assigning innerHTML.` :
|
|
56
|
+
`Review this code for security implications.`,
|
|
57
|
+
score: p.severity === "CRITICAL" ? -15 : -10,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const p of SQL_INJECTION_PATTERNS) {
|
|
62
|
+
const matches = df.content.match(p.pattern);
|
|
63
|
+
if (matches) {
|
|
64
|
+
const lineNum = lines.findIndex(l => l.match(p.pattern)) + 1;
|
|
65
|
+
findings.push({
|
|
66
|
+
ruleId: p.ruleId,
|
|
67
|
+
severity: "CRITICAL",
|
|
68
|
+
category: "security",
|
|
69
|
+
filePath: df.path,
|
|
70
|
+
line: lineNum > 0 ? lineNum : undefined,
|
|
71
|
+
message: `${p.label} detected`,
|
|
72
|
+
detail: `SQL injection vulnerability: building queries via string interpolation allows attackers to modify query logic.`,
|
|
73
|
+
suggestion: `Use parameterized queries (prepared statements) or an ORM. Never concatenate user input into SQL strings.`,
|
|
74
|
+
score: -15,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const routePattern = /router\.(get|post|put|delete|patch)\s*\(["'][^"']+["']\s*,/g;
|
|
79
|
+
const hasAuthMiddleware = /(?:auth|authenticate|authorize|authMiddleware|requireAuth)/.test(df.content);
|
|
80
|
+
const routeMatches = df.content.match(routePattern);
|
|
81
|
+
if (routeMatches && !hasAuthMiddleware) {
|
|
82
|
+
for (const rm of routeMatches) {
|
|
83
|
+
const isHealth = rm.includes("/health") || rm.includes("/webhook");
|
|
84
|
+
if (!isHealth) {
|
|
85
|
+
const lineNum = lines.findIndex(l => l.includes(rm.substring(0, 30))) + 1;
|
|
86
|
+
if (lineNum > 0) {
|
|
87
|
+
findings.push({
|
|
88
|
+
ruleId: "sec-no-auth",
|
|
89
|
+
severity: "HIGH",
|
|
90
|
+
category: "security",
|
|
91
|
+
filePath: df.path,
|
|
92
|
+
line: lineNum,
|
|
93
|
+
message: `New route may lack authentication middleware`,
|
|
94
|
+
detail: `Routes that handle user data or mutations should have auth middleware.`,
|
|
95
|
+
suggestion: `Add authentication middleware to this route handler.`,
|
|
96
|
+
score: -10,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const deduction = findings.reduce((sum, f) => sum + Math.abs(f.score), 0);
|
|
104
|
+
totalScore = Math.max(0, Math.min(100, totalScore - deduction));
|
|
105
|
+
return { findings, score: totalScore };
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=SecurityScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecurityScanner.js","sourceRoot":"","sources":["../../../../src/pr-review/analyzers/SecurityScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StaticAnalyzer.d.ts","sourceRoot":"","sources":["../../../../src/pr-review/analyzers/StaticAnalyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAqF7C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CA2IzE"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
function computeCyclomaticComplexity(node) {
|
|
3
|
+
let count = 1;
|
|
4
|
+
function walk(n) {
|
|
5
|
+
switch (n.kind) {
|
|
6
|
+
case ts.SyntaxKind.IfStatement:
|
|
7
|
+
case ts.SyntaxKind.WhileStatement:
|
|
8
|
+
case ts.SyntaxKind.ForStatement:
|
|
9
|
+
case ts.SyntaxKind.ForInStatement:
|
|
10
|
+
case ts.SyntaxKind.ForOfStatement:
|
|
11
|
+
case ts.SyntaxKind.CaseClause:
|
|
12
|
+
case ts.SyntaxKind.CatchClause:
|
|
13
|
+
case ts.SyntaxKind.ConditionalExpression:
|
|
14
|
+
count++;
|
|
15
|
+
break;
|
|
16
|
+
case ts.SyntaxKind.BinaryExpression: {
|
|
17
|
+
const bin = n;
|
|
18
|
+
if (bin.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
19
|
+
bin.operatorToken.kind === ts.SyntaxKind.BarBarToken ||
|
|
20
|
+
bin.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken)
|
|
21
|
+
count++;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
ts.forEachChild(n, walk);
|
|
26
|
+
}
|
|
27
|
+
walk(node);
|
|
28
|
+
return count;
|
|
29
|
+
}
|
|
30
|
+
function computeMaxNesting(node, depth = 0) {
|
|
31
|
+
const nestingNodes = new Set([
|
|
32
|
+
ts.SyntaxKind.IfStatement, ts.SyntaxKind.WhileStatement,
|
|
33
|
+
ts.SyntaxKind.ForStatement, ts.SyntaxKind.ForInStatement,
|
|
34
|
+
ts.SyntaxKind.ForOfStatement, ts.SyntaxKind.SwitchStatement,
|
|
35
|
+
ts.SyntaxKind.TryStatement, ts.SyntaxKind.Block,
|
|
36
|
+
]);
|
|
37
|
+
const isNesting = nestingNodes.has(node.kind);
|
|
38
|
+
const currentDepth = isNesting ? depth + 1 : depth;
|
|
39
|
+
let max = currentDepth;
|
|
40
|
+
ts.forEachChild(node, child => {
|
|
41
|
+
max = Math.max(max, computeMaxNesting(child, currentDepth));
|
|
42
|
+
});
|
|
43
|
+
return max;
|
|
44
|
+
}
|
|
45
|
+
const FOSSIL_PATTERNS = [
|
|
46
|
+
{
|
|
47
|
+
name: "var vs const/let",
|
|
48
|
+
fossilPattern: /\bvar\s+\w+/g,
|
|
49
|
+
modernPattern: /\b(const|let)\s+\w+/g,
|
|
50
|
+
fossilLabel: "var",
|
|
51
|
+
modernLabel: "const/let",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "require() vs ESM import",
|
|
55
|
+
fossilPattern: /\brequire\s*\(/g,
|
|
56
|
+
modernPattern: /^import\s+/gm,
|
|
57
|
+
fossilLabel: "require()",
|
|
58
|
+
modernLabel: "import",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "any vs typed generics",
|
|
62
|
+
fossilPattern: /:\s*any\b/g,
|
|
63
|
+
modernPattern: /<[A-Z]\w*>/g,
|
|
64
|
+
fossilLabel: ": any",
|
|
65
|
+
modernLabel: "generics",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "string concat vs template literals",
|
|
69
|
+
fossilPattern: /["']\s*\+\s*\w+\s*\+\s*["']/g,
|
|
70
|
+
modernPattern: /`[^`]*\$\{/g,
|
|
71
|
+
fossilLabel: "string concat",
|
|
72
|
+
modernLabel: "template literal",
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
export function analyzeStatic(diffFiles) {
|
|
76
|
+
const findings = [];
|
|
77
|
+
let totalScore = 100;
|
|
78
|
+
for (const df of diffFiles) {
|
|
79
|
+
if (!df.content || !df.path.match(/\.(ts|tsx|js|jsx)$/))
|
|
80
|
+
continue;
|
|
81
|
+
if (df.status === "deleted")
|
|
82
|
+
continue;
|
|
83
|
+
try {
|
|
84
|
+
const sourceFile = ts.createSourceFile(df.path, df.content, ts.ScriptTarget.Latest, true);
|
|
85
|
+
let functionCount = 0;
|
|
86
|
+
let totalCC = 0;
|
|
87
|
+
let maxNesting = 0;
|
|
88
|
+
let longFunctions = 0;
|
|
89
|
+
let anyCount = 0;
|
|
90
|
+
let typeAnnotations = 0;
|
|
91
|
+
function visit(node) {
|
|
92
|
+
const isFn = ts.isFunctionDeclaration(node) ||
|
|
93
|
+
ts.isMethodDeclaration(node) ||
|
|
94
|
+
ts.isArrowFunction(node) ||
|
|
95
|
+
ts.isFunctionExpression(node);
|
|
96
|
+
if (isFn) {
|
|
97
|
+
functionCount++;
|
|
98
|
+
const cc = computeCyclomaticComplexity(node);
|
|
99
|
+
const nesting = computeMaxNesting(node);
|
|
100
|
+
totalCC += cc;
|
|
101
|
+
maxNesting = Math.max(maxNesting, nesting);
|
|
102
|
+
const nameNode = node.name;
|
|
103
|
+
const fnName = nameNode ? nameNode.getText(sourceFile) : "<anonymous>";
|
|
104
|
+
const startLine = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
|
|
105
|
+
const endLine = sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line + 1;
|
|
106
|
+
const fnLines = endLine - startLine + 1;
|
|
107
|
+
if (fnLines > 50) {
|
|
108
|
+
longFunctions++;
|
|
109
|
+
findings.push({
|
|
110
|
+
ruleId: "static-fn-length",
|
|
111
|
+
severity: "MEDIUM",
|
|
112
|
+
category: "static",
|
|
113
|
+
filePath: df.path,
|
|
114
|
+
line: startLine,
|
|
115
|
+
message: `Function "${fnName}" is ${fnLines} lines long (max: 50)`,
|
|
116
|
+
detail: `Long functions are harder to test and maintain. Consider breaking it into smaller functions.`,
|
|
117
|
+
suggestion: `Extract logic into smaller helper functions (target < 30 lines each)`,
|
|
118
|
+
score: -5,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (cc > 10) {
|
|
122
|
+
findings.push({
|
|
123
|
+
ruleId: "static-cyclomatic",
|
|
124
|
+
severity: "HIGH",
|
|
125
|
+
category: "static",
|
|
126
|
+
filePath: df.path,
|
|
127
|
+
line: startLine,
|
|
128
|
+
message: `Function "${fnName}" has cyclomatic complexity of ${cc} (max: 10)`,
|
|
129
|
+
detail: `High complexity makes code hard to test and prone to bugs.`,
|
|
130
|
+
suggestion: `Reduce conditional branches, extract switch cases into separate functions, use early returns.`,
|
|
131
|
+
score: -10,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (nesting > 4) {
|
|
135
|
+
findings.push({
|
|
136
|
+
ruleId: "static-nesting",
|
|
137
|
+
severity: "MEDIUM",
|
|
138
|
+
category: "static",
|
|
139
|
+
filePath: df.path,
|
|
140
|
+
line: startLine,
|
|
141
|
+
message: `Function "${fnName}" has nesting depth of ${nesting} (max: 4)`,
|
|
142
|
+
detail: `Deep nesting reduces readability and increases cognitive load.`,
|
|
143
|
+
suggestion: `Use early returns, guard clauses, and extract nested blocks into separate functions.`,
|
|
144
|
+
score: -5,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
ts.forEachChild(node, visit);
|
|
149
|
+
}
|
|
150
|
+
visit(sourceFile);
|
|
151
|
+
const srcText = df.content;
|
|
152
|
+
anyCount = (srcText.match(/:\s*any\b/g) || []).length;
|
|
153
|
+
typeAnnotations = (srcText.match(/:\s*\w+/g) || []).length;
|
|
154
|
+
if (typeAnnotations > 0) {
|
|
155
|
+
const anyRatio = anyCount / typeAnnotations;
|
|
156
|
+
if (anyRatio > 0.3) {
|
|
157
|
+
findings.push({
|
|
158
|
+
ruleId: "static-any-ratio",
|
|
159
|
+
severity: "MEDIUM",
|
|
160
|
+
category: "static",
|
|
161
|
+
filePath: df.path,
|
|
162
|
+
message: `High ": any" usage ratio (${Math.round(anyRatio * 100)}% of type annotations)`,
|
|
163
|
+
detail: `Excessive "any" defeats TypeScript's type checking.`,
|
|
164
|
+
suggestion: `Replace "any" with proper types or generics. Use "unknown" if the type is truly uncertain.`,
|
|
165
|
+
score: -5,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
for (const fp of FOSSIL_PATTERNS) {
|
|
170
|
+
const fossilMatches = (srcText.match(fp.fossilPattern) || []).length;
|
|
171
|
+
if (fossilMatches > 0) {
|
|
172
|
+
findings.push({
|
|
173
|
+
ruleId: `static-fossil-${fp.name.replace(/\s+/g, "-")}`,
|
|
174
|
+
severity: "LOW",
|
|
175
|
+
category: "static",
|
|
176
|
+
filePath: df.path,
|
|
177
|
+
message: `Uses ${fp.fossilLabel} (${fossilMatches}x) — prefer ${fp.modernLabel}`,
|
|
178
|
+
detail: `This legacy pattern was found in new/modified code.`,
|
|
179
|
+
suggestion: `Replace ${fp.fossilLabel} with ${fp.modernLabel} for consistency with modern codebase standards.`,
|
|
180
|
+
score: -2,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
findings.push({
|
|
187
|
+
ruleId: "static-parse-error",
|
|
188
|
+
severity: "LOW",
|
|
189
|
+
category: "static",
|
|
190
|
+
filePath: df.path,
|
|
191
|
+
message: `Could not parse file for static analysis`,
|
|
192
|
+
detail: `This may indicate syntax errors or unsupported syntax.`,
|
|
193
|
+
score: -2,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const deduction = findings.reduce((sum, f) => sum + Math.abs(f.score), 0);
|
|
198
|
+
totalScore = Math.max(0, Math.min(100, totalScore - deduction));
|
|
199
|
+
return { findings, score: totalScore };
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=StaticAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StaticAnalyzer.js","sourceRoot":"","sources":["../../../../src/pr-review/analyzers/StaticAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { analyzeStatic } from "./StaticAnalyzer";
|
|
2
|
+
export type { StaticAnalysisResult } from "./StaticAnalyzer";
|
|
3
|
+
export { analyzeQuality } from "./QualityGrader";
|
|
4
|
+
export type { QualityAnalysisResult } from "./QualityGrader";
|
|
5
|
+
export { analyzeSecurity } from "./SecurityScanner";
|
|
6
|
+
export type { SecurityAnalysisResult } from "./SecurityScanner";
|
|
7
|
+
export { analyzeRegression } from "./RegressionDetector";
|
|
8
|
+
export type { RegressionAnalysisResult } from "./RegressionDetector";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pr-review/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/pr-review/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Finding } from "../types";
|
|
2
|
+
interface BrainMemory {
|
|
3
|
+
prompt: string;
|
|
4
|
+
response: string;
|
|
5
|
+
similarity: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class BrainBridge {
|
|
8
|
+
searchQuery(query: string, limit?: number): Promise<BrainMemory[]>;
|
|
9
|
+
findPriorBugs(files: string[]): Promise<Map<string, BrainMemory[]>>;
|
|
10
|
+
getContextualHints(files: string[], baseBranch: string): Promise<{
|
|
11
|
+
file: string;
|
|
12
|
+
hints: string[];
|
|
13
|
+
}[]>;
|
|
14
|
+
storeReview(reviewId: string, repo: string, prNumber: number, score: number, verdict: string, findings: Finding[], files: string[]): Promise<boolean>;
|
|
15
|
+
adjustWeightsFromHistory(files: string[], baseWeights: {
|
|
16
|
+
static: number;
|
|
17
|
+
security: number;
|
|
18
|
+
regression: number;
|
|
19
|
+
quality: number;
|
|
20
|
+
}): Promise<typeof baseWeights>;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=BrainBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrainBridge.d.ts","sourceRoot":"","sources":["../../../../src/pr-review/bridge/BrainBridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,WAAW;IAChB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAYrE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAWnE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAcrG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,OAAO,CAAC;IAyBb,wBAAwB,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACrF,OAAO,CAAC,OAAO,WAAW,CAAC;CAkC/B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { getProxyPort } from "../../mcp/utils";
|
|
3
|
+
export class BrainBridge {
|
|
4
|
+
async searchQuery(query, limit = 3) {
|
|
5
|
+
try {
|
|
6
|
+
const port = getProxyPort();
|
|
7
|
+
const res = await axios.get(`http://localhost:${port}/api/search?q=${encodeURIComponent(query)}&limit=${limit}`);
|
|
8
|
+
return (res.data.results || []).filter((r) => r.similarity >= 0.5);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async findPriorBugs(files) {
|
|
15
|
+
const results = new Map();
|
|
16
|
+
for (const file of files) {
|
|
17
|
+
const memories = await this.searchQuery(`bug ${file} error fix regression`, 2);
|
|
18
|
+
if (memories.length > 0) {
|
|
19
|
+
results.set(file, memories);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return results;
|
|
23
|
+
}
|
|
24
|
+
async getContextualHints(files, baseBranch) {
|
|
25
|
+
const hints = [];
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const memories = await this.searchQuery(`${file} ${baseBranch} architecture pattern`, 2);
|
|
28
|
+
if (memories.length > 0) {
|
|
29
|
+
hints.push({
|
|
30
|
+
file,
|
|
31
|
+
hints: memories.map(m => m.prompt.substring(0, 200)),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return hints;
|
|
36
|
+
}
|
|
37
|
+
async storeReview(reviewId, repo, prNumber, score, verdict, findings, files) {
|
|
38
|
+
try {
|
|
39
|
+
const port = getProxyPort();
|
|
40
|
+
const query = `PR #${prNumber} — ${repo}: ${files.join(", ")}`;
|
|
41
|
+
const response = JSON.stringify({
|
|
42
|
+
reviewId,
|
|
43
|
+
score,
|
|
44
|
+
verdict,
|
|
45
|
+
findingCount: findings.length,
|
|
46
|
+
criticalCount: findings.filter(f => f.severity === "CRITICAL").length,
|
|
47
|
+
highCount: findings.filter(f => f.severity === "HIGH").length,
|
|
48
|
+
files,
|
|
49
|
+
summary: findings.map(f => `[${f.severity}] ${f.filePath}:${f.line || "?"} — ${f.message}`),
|
|
50
|
+
});
|
|
51
|
+
await axios.post(`http://localhost:${port}/api/memory/store`, {
|
|
52
|
+
query,
|
|
53
|
+
response,
|
|
54
|
+
provider: "pr-review",
|
|
55
|
+
});
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async adjustWeightsFromHistory(files, baseWeights) {
|
|
63
|
+
const weights = { ...baseWeights };
|
|
64
|
+
const highRiskModules = [];
|
|
65
|
+
for (const file of files) {
|
|
66
|
+
const memories = await this.searchQuery(`high risk bug ${file}`, 2);
|
|
67
|
+
const hasBugs = memories.some(m => {
|
|
68
|
+
try {
|
|
69
|
+
const data = JSON.parse(typeof m.response === "string" ? m.response : "");
|
|
70
|
+
return data.criticalCount > 0 || data.highCount > 2;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
if (hasBugs) {
|
|
77
|
+
highRiskModules.push(file);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (highRiskModules.length > 0) {
|
|
81
|
+
weights.regression += 0.10;
|
|
82
|
+
weights.security += 0.05;
|
|
83
|
+
weights.static -= 0.05;
|
|
84
|
+
weights.quality -= 0.10;
|
|
85
|
+
const total = Object.values(weights).reduce((s, v) => s + v, 0);
|
|
86
|
+
for (const key of Object.keys(weights)) {
|
|
87
|
+
weights[key] = weights[key] / total;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return weights;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=BrainBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrainBridge.js","sourceRoot":"","sources":["../../../../src/pr-review/bridge/BrainBridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pr-review/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/pr-review/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { runAnalysis, parseDiff } from "./PRReviewEngine";
|
|
2
|
+
export type { AnalyzeResult } from "./types";
|
|
3
|
+
export { analyzeStatic, analyzeQuality, analyzeSecurity, analyzeRegression, } from "./analyzers";
|
|
4
|
+
export type { StaticAnalysisResult, QualityAnalysisResult, SecurityAnalysisResult, RegressionAnalysisResult, } from "./analyzers";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pr-review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EACL,aAAa,EACb,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/pr-review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,aAAa,EACb,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { GitPlatformAdapter } from "./adapters/GitPlatformAdapter";
|
|
2
|
+
import type { Platform, PRMetadata } from "./types";
|
|
3
|
+
export declare function getAdapter(platform: string, token: string): GitPlatformAdapter;
|
|
4
|
+
export declare function getTokenForPlatform(platform: string): string;
|
|
5
|
+
export interface PRReviewOptions {
|
|
6
|
+
autoApprove?: boolean;
|
|
7
|
+
threshold?: number;
|
|
8
|
+
context?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PRReviewOutput {
|
|
11
|
+
reviewId: string;
|
|
12
|
+
score: number;
|
|
13
|
+
verdict: string;
|
|
14
|
+
findingsCount: number;
|
|
15
|
+
approved: boolean;
|
|
16
|
+
summary: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PRReviewMeta {
|
|
19
|
+
owner: string;
|
|
20
|
+
repo: string;
|
|
21
|
+
prNumber: number;
|
|
22
|
+
metadata: PRMetadata;
|
|
23
|
+
}
|
|
24
|
+
export declare function runPRReview(platform: Platform, repo: string, prNumber: number, options?: PRReviewOptions): Promise<PRReviewOutput>;
|
|
25
|
+
//# sourceMappingURL=reviewRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewRunner.d.ts","sourceRoot":"","sources":["../../../src/pr-review/reviewRunner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIpD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAO9E;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgB5D;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAuFzB"}
|