@nxuss/lemma 0.9.0 → 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 +40 -6
- 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 +302 -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 +302 -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
package/dist/cjs/mcp/tools.js
CHANGED
|
@@ -49,6 +49,38 @@ const ComplexityRouter_1 = require("../proxy/ComplexityRouter");
|
|
|
49
49
|
const ContextSqueezer_1 = require("../utils/ContextSqueezer");
|
|
50
50
|
const reportSavings_1 = require("../utils/reportSavings");
|
|
51
51
|
const utils_1 = require("./utils");
|
|
52
|
+
const PRReviewEngine_1 = require("../pr-review/PRReviewEngine");
|
|
53
|
+
const ReviewStore_1 = require("../pr-review/ReviewStore");
|
|
54
|
+
const reviewRunner_1 = require("../pr-review/reviewRunner");
|
|
55
|
+
// ── Pro License Gate ──────────────────────────────────────────────────────────
|
|
56
|
+
const LICENSE_FILE = path_1.default.join(os_1.default.homedir(), '.lemma-cache', 'license.json');
|
|
57
|
+
let _proStatusCache = null;
|
|
58
|
+
function isProUser() {
|
|
59
|
+
if (_proStatusCache !== null)
|
|
60
|
+
return _proStatusCache;
|
|
61
|
+
try {
|
|
62
|
+
if (fs_1.default.existsSync(LICENSE_FILE)) {
|
|
63
|
+
const data = JSON.parse(fs_1.default.readFileSync(LICENSE_FILE, 'utf8'));
|
|
64
|
+
_proStatusCache = !!(data.isPro || data.tier === 'pro');
|
|
65
|
+
return _proStatusCache;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
69
|
+
_proStatusCache = false;
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const PRO_GATE_MESSAGE = [
|
|
73
|
+
"🔒 Lemma MCP requires a Pro license.",
|
|
74
|
+
"",
|
|
75
|
+
"All 32 MCP tools — including The Brain, zero-token static analysis,",
|
|
76
|
+
"PreCrime predictor, Coupling Radar, and Entropy Score — are Pro features.",
|
|
77
|
+
"",
|
|
78
|
+
"✨ Activate your license:",
|
|
79
|
+
" lemma activate <your-key>",
|
|
80
|
+
"",
|
|
81
|
+
"🚀 Get Lemma Pro:",
|
|
82
|
+
" https://lemma.nxus.studio/upgrade",
|
|
83
|
+
].join("\n");
|
|
52
84
|
const toolDefinitions = [
|
|
53
85
|
{
|
|
54
86
|
name: "scrub_privacy",
|
|
@@ -442,6 +474,62 @@ const toolDefinitions = [
|
|
|
442
474
|
},
|
|
443
475
|
},
|
|
444
476
|
},
|
|
477
|
+
{
|
|
478
|
+
name: "review_diff",
|
|
479
|
+
description: "Analyze a raw git diff locally for regressions, security issues, code quality, and static analysis. Zero-cost static analysis using local TypeScript compiler API — no LLM calls. Returns score, verdict, and detailed findings with suggestions.",
|
|
480
|
+
inputSchema: {
|
|
481
|
+
type: "object",
|
|
482
|
+
properties: {
|
|
483
|
+
diff: { type: "string", description: "The git diff content to analyze" },
|
|
484
|
+
baseBranch: { type: "string", description: "Base branch for regression context", default: "main" },
|
|
485
|
+
threshold: { type: "number", description: "Quality score threshold for approval (0-100)", default: 90 },
|
|
486
|
+
},
|
|
487
|
+
required: ["diff"],
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
name: "review_pr",
|
|
492
|
+
description: "Analyze a Pull Request via GitHub, Azure DevOps, or GitLab API. Detects regressions, security issues, code quality problems, and breaking changes. Posts results as PR comments and can auto-approve if quality threshold is met. Pro license required.",
|
|
493
|
+
inputSchema: {
|
|
494
|
+
type: "object",
|
|
495
|
+
properties: {
|
|
496
|
+
platform: { type: "string", enum: ["github", "azure", "gitlab"], description: "Git platform" },
|
|
497
|
+
repo: { type: "string", description: "Full repo name (e.g., 'owner/repo' or 'org/project/repo')" },
|
|
498
|
+
prNumber: { type: "number", description: "Pull request number" },
|
|
499
|
+
autoApprove: { type: "boolean", description: "Auto-approve if score >= threshold", default: true },
|
|
500
|
+
threshold: { type: "number", description: "Quality score threshold (0-100)", default: 90 },
|
|
501
|
+
context: { type: "string", description: "Optional context from The Brain about this project" },
|
|
502
|
+
},
|
|
503
|
+
required: ["platform", "repo", "prNumber"],
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
name: "pr_status",
|
|
508
|
+
description: "Get the status and detailed results of a previously reviewed PR. Returns score, verdict, findings, and approval status.",
|
|
509
|
+
inputSchema: {
|
|
510
|
+
type: "object",
|
|
511
|
+
properties: {
|
|
512
|
+
reviewId: { type: "string", description: "Review ID returned by review_pr" },
|
|
513
|
+
repo: { type: "string", description: "Optional repo to find by PR number" },
|
|
514
|
+
prNumber: { type: "number", description: "Optional PR number to find by repo" },
|
|
515
|
+
},
|
|
516
|
+
required: [],
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
name: "generate_pr_workflow",
|
|
521
|
+
description: "Generate a CI/CD workflow file (GitHub Actions or Azure Pipelines) that runs Lemma PR Review on every pull request. Writes the file to the workspace.",
|
|
522
|
+
inputSchema: {
|
|
523
|
+
type: "object",
|
|
524
|
+
properties: {
|
|
525
|
+
platform: { type: "string", enum: ["github", "azure"], description: "CI platform" },
|
|
526
|
+
outputPath: { type: "string", description: "Output path for the workflow file", default: ".github/workflows/lemma-pr-review.yml" },
|
|
527
|
+
autoApprove: { type: "boolean", description: "Enable auto-approve in the workflow", default: true },
|
|
528
|
+
threshold: { type: "number", description: "Quality threshold for auto-approve", default: 90 },
|
|
529
|
+
},
|
|
530
|
+
required: ["platform"],
|
|
531
|
+
},
|
|
532
|
+
},
|
|
445
533
|
];
|
|
446
534
|
const toolHandlers = {
|
|
447
535
|
scrub_privacy: handleScrubPrivacy,
|
|
@@ -476,6 +564,10 @@ const toolHandlers = {
|
|
|
476
564
|
precrime_static: handlePrecrimeStatic,
|
|
477
565
|
semantic_dedup_guard: handleSemanticDedupGuard,
|
|
478
566
|
dead_export_necromancer: handleDeadExportNecromancer,
|
|
567
|
+
review_diff: handleReviewDiff,
|
|
568
|
+
review_pr: handleReviewPR,
|
|
569
|
+
pr_status: handlePRStatus,
|
|
570
|
+
generate_pr_workflow: handleGeneratePRWorkflow,
|
|
479
571
|
};
|
|
480
572
|
function setupToolsHandlers(server, onToolCall) {
|
|
481
573
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
@@ -484,6 +576,20 @@ function setupToolsHandlers(server, onToolCall) {
|
|
|
484
576
|
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
485
577
|
const { name, arguments: args } = request.params;
|
|
486
578
|
const startTime = Date.now();
|
|
579
|
+
// ── Pro License Gate ────────────────────────────────────────────────────
|
|
580
|
+
if (!isProUser()) {
|
|
581
|
+
onToolCall?.({
|
|
582
|
+
tool: name,
|
|
583
|
+
args: args || {},
|
|
584
|
+
result: "ERROR",
|
|
585
|
+
latency: Date.now() - startTime,
|
|
586
|
+
error: "Pro license required",
|
|
587
|
+
});
|
|
588
|
+
return {
|
|
589
|
+
content: [{ type: "text", text: PRO_GATE_MESSAGE }],
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
// ── End Pro Gate ────────────────────────────────────────────────────────
|
|
487
593
|
const handler = toolHandlers[name];
|
|
488
594
|
if (!handler) {
|
|
489
595
|
const latency = Date.now() - startTime;
|
|
@@ -2358,4 +2464,200 @@ async function handleDeadExportNecromancer(args) {
|
|
|
2358
2464
|
return { content: [{ type: "text", text: `Dead export necromancer failed: ${err.message}` }] };
|
|
2359
2465
|
}
|
|
2360
2466
|
}
|
|
2467
|
+
// ─── review_diff ─────────────────────────────────────────────────────────────
|
|
2468
|
+
async function handleReviewDiff(args) {
|
|
2469
|
+
const diff = args?.diff;
|
|
2470
|
+
const baseBranch = args?.baseBranch || "main";
|
|
2471
|
+
const threshold = args?.threshold || 90;
|
|
2472
|
+
if (!diff)
|
|
2473
|
+
throw new Error("diff is required");
|
|
2474
|
+
const workspaceRoot = process.cwd();
|
|
2475
|
+
try {
|
|
2476
|
+
const diffFiles = (0, PRReviewEngine_1.parseDiff)(diff);
|
|
2477
|
+
if (diffFiles.length === 0) {
|
|
2478
|
+
return { content: [{ type: "text", text: "No parseable diff files found. Ensure the input is a valid git diff output." }] };
|
|
2479
|
+
}
|
|
2480
|
+
const result = (0, PRReviewEngine_1.runAnalysis)(diffFiles, { threshold, autoApprove: false }, workspaceRoot, baseBranch);
|
|
2481
|
+
return {
|
|
2482
|
+
content: [
|
|
2483
|
+
{
|
|
2484
|
+
type: "text",
|
|
2485
|
+
text: [
|
|
2486
|
+
`# 🔍 Lemma PR Review — Local Diff Analysis`,
|
|
2487
|
+
``,
|
|
2488
|
+
`**Files analyzed:** ${diffFiles.length}`,
|
|
2489
|
+
`**Score:** ${result.score}/100 | **Verdict:** ${result.verdict}`,
|
|
2490
|
+
``,
|
|
2491
|
+
result.summary,
|
|
2492
|
+
].join("\n"),
|
|
2493
|
+
},
|
|
2494
|
+
],
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2497
|
+
catch (err) {
|
|
2498
|
+
(0, utils_1.logError)("review_diff", err);
|
|
2499
|
+
return { content: [{ type: "text", text: `PR review analysis failed: ${err.message}` }] };
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
// ─── review_pr ─────────────────────────────────────────────────────────────
|
|
2503
|
+
async function handleReviewPR(args) {
|
|
2504
|
+
const platform = args?.platform;
|
|
2505
|
+
const repo = args?.repo;
|
|
2506
|
+
const prNumber = args?.prNumber;
|
|
2507
|
+
const autoApprove = args?.autoApprove !== false;
|
|
2508
|
+
const threshold = args?.threshold || 90;
|
|
2509
|
+
if (!platform || !repo || !prNumber) {
|
|
2510
|
+
throw new Error("platform, repo, and prNumber are required");
|
|
2511
|
+
}
|
|
2512
|
+
try {
|
|
2513
|
+
const result = await (0, reviewRunner_1.runPRReview)(platform, repo, prNumber, { autoApprove, threshold });
|
|
2514
|
+
return {
|
|
2515
|
+
content: [
|
|
2516
|
+
{
|
|
2517
|
+
type: "text",
|
|
2518
|
+
text: JSON.stringify(result, null, 2),
|
|
2519
|
+
},
|
|
2520
|
+
],
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
catch (err) {
|
|
2524
|
+
(0, utils_1.logError)("review_pr", err);
|
|
2525
|
+
return { content: [{ type: "text", text: `PR review failed: ${err.message}` }] };
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
// ─── pr_status ─────────────────────────────────────────────────────────────
|
|
2529
|
+
async function handlePRStatus(args) {
|
|
2530
|
+
const reviewId = args?.reviewId;
|
|
2531
|
+
const repo = args?.repo;
|
|
2532
|
+
const prNumber = args?.prNumber;
|
|
2533
|
+
let review;
|
|
2534
|
+
if (reviewId) {
|
|
2535
|
+
review = ReviewStore_1.ReviewStore.get(reviewId);
|
|
2536
|
+
}
|
|
2537
|
+
else if (repo && prNumber) {
|
|
2538
|
+
review = ReviewStore_1.ReviewStore.findByPR(repo, prNumber);
|
|
2539
|
+
}
|
|
2540
|
+
if (!review) {
|
|
2541
|
+
const allReviews = ReviewStore_1.ReviewStore.getAll();
|
|
2542
|
+
return {
|
|
2543
|
+
content: [
|
|
2544
|
+
{
|
|
2545
|
+
type: "text",
|
|
2546
|
+
text: allReviews.length === 0
|
|
2547
|
+
? "No PR reviews found in this session."
|
|
2548
|
+
: `PR reviews in this session:\n\n${allReviews.slice(-5).map(r => `- ${r.metadata?.repo || "?"} #${r.metadata?.prNumber || "?"}: ${r.score}/100 — ${r.verdict} (${r.reviewId})`).join("\n")}`,
|
|
2549
|
+
},
|
|
2550
|
+
],
|
|
2551
|
+
};
|
|
2552
|
+
}
|
|
2553
|
+
return {
|
|
2554
|
+
content: [
|
|
2555
|
+
{
|
|
2556
|
+
type: "text",
|
|
2557
|
+
text: [
|
|
2558
|
+
`# 📋 PR Review Status`,
|
|
2559
|
+
``,
|
|
2560
|
+
`**Review ID:** ${review.reviewId}`,
|
|
2561
|
+
`**Repo:** ${review.metadata?.repo || "N/A"}`,
|
|
2562
|
+
`**PR:** #${review.metadata?.prNumber || "N/A"}`,
|
|
2563
|
+
`**Score:** ${review.score}/100`,
|
|
2564
|
+
`**Verdict:** ${review.verdict}`,
|
|
2565
|
+
`**Approved:** ${review.approved ? "✅ Yes" : "❌ No"}`,
|
|
2566
|
+
`**Timestamp:** ${review.timestamp}`,
|
|
2567
|
+
``,
|
|
2568
|
+
review.summary,
|
|
2569
|
+
].join("\n"),
|
|
2570
|
+
},
|
|
2571
|
+
],
|
|
2572
|
+
};
|
|
2573
|
+
}
|
|
2574
|
+
// ─── generate_pr_workflow ─────────────────────────────────────────────────
|
|
2575
|
+
async function handleGeneratePRWorkflow(args) {
|
|
2576
|
+
const platform = args?.platform;
|
|
2577
|
+
const outputPath = args?.outputPath || ".github/workflows/lemma-pr-review.yml";
|
|
2578
|
+
const autoApprove = args?.autoApprove !== false;
|
|
2579
|
+
const threshold = args?.threshold || 90;
|
|
2580
|
+
if (!platform)
|
|
2581
|
+
throw new Error("platform is required");
|
|
2582
|
+
if (!["github", "azure"].includes(platform)) {
|
|
2583
|
+
throw new Error("platform must be 'github' or 'azure'");
|
|
2584
|
+
}
|
|
2585
|
+
const workspaceRoot = process.cwd();
|
|
2586
|
+
const { resolved } = (0, utils_1.safeResolvePath)(workspaceRoot, outputPath);
|
|
2587
|
+
const dir = path_1.default.dirname(resolved);
|
|
2588
|
+
try {
|
|
2589
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
2590
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
2591
|
+
}
|
|
2592
|
+
const tokenName = platform === "github" ? "GITHUB_TOKEN" : "AZURE_DEVOPS_TOKEN";
|
|
2593
|
+
const yaml = platform === "github"
|
|
2594
|
+
? generateGitHubWorkflowYaml(threshold)
|
|
2595
|
+
: generateAzurePipelineYaml(threshold);
|
|
2596
|
+
fs_1.default.writeFileSync(resolved, yaml, "utf8");
|
|
2597
|
+
return {
|
|
2598
|
+
content: [
|
|
2599
|
+
{
|
|
2600
|
+
type: "text",
|
|
2601
|
+
text: `✅ Workflow file generated at \`${outputPath}\`\n\nMake sure to add your Lemma license key and ${tokenName} as secrets in your ${platform === "github" ? "GitHub repository" : "Azure Pipeline"}.`,
|
|
2602
|
+
},
|
|
2603
|
+
],
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
catch (err) {
|
|
2607
|
+
(0, utils_1.logError)("generate_pr_workflow", err);
|
|
2608
|
+
return { content: [{ type: "text", text: `Failed to generate workflow: ${err.message}` }] };
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
function generateGitHubWorkflowYaml(threshold) {
|
|
2612
|
+
return [
|
|
2613
|
+
`name: Lemma PR Review`,
|
|
2614
|
+
`on:`,
|
|
2615
|
+
` pull_request:`,
|
|
2616
|
+
` types: [opened, synchronize]`,
|
|
2617
|
+
``,
|
|
2618
|
+
`jobs:`,
|
|
2619
|
+
` lemma-review:`,
|
|
2620
|
+
` runs-on: ubuntu-latest`,
|
|
2621
|
+
` steps:`,
|
|
2622
|
+
` - uses: actions/checkout@v4`,
|
|
2623
|
+
` with:`,
|
|
2624
|
+
` fetch-depth: 0`,
|
|
2625
|
+
` - uses: actions/setup-node@v4`,
|
|
2626
|
+
` - run: npm install -g @nxuss/lemma`,
|
|
2627
|
+
` - run: lemma pr-review --threshold ${threshold}`,
|
|
2628
|
+
` env:`,
|
|
2629
|
+
` LEMMA_LICENSE_KEY: \${{ secrets.LEMMA_LICENSE_KEY }}`,
|
|
2630
|
+
` GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}`,
|
|
2631
|
+
` LEMMA_PLATFORM: github`,
|
|
2632
|
+
` LEMMA_REPO: \${{ github.repository }}`,
|
|
2633
|
+
` LEMMA_PR_NUMBER: \${{ github.event.pull_request.number }}`,
|
|
2634
|
+
].join("\n");
|
|
2635
|
+
}
|
|
2636
|
+
function generateAzurePipelineYaml(threshold) {
|
|
2637
|
+
return [
|
|
2638
|
+
`trigger: none`,
|
|
2639
|
+
`pr:`,
|
|
2640
|
+
` branches:`,
|
|
2641
|
+
` include:`,
|
|
2642
|
+
` - '*'`,
|
|
2643
|
+
``,
|
|
2644
|
+
`pool:`,
|
|
2645
|
+
` vmImage: ubuntu-latest`,
|
|
2646
|
+
``,
|
|
2647
|
+
`steps:`,
|
|
2648
|
+
` - checkout: self`,
|
|
2649
|
+
` fetchDepth: 0`,
|
|
2650
|
+
` - task: NodeTool@0`,
|
|
2651
|
+
` inputs:`,
|
|
2652
|
+
` versionSpec: '18'`,
|
|
2653
|
+
` - script: npm install -g @nxuss/lemma`,
|
|
2654
|
+
` - script: lemma pr-review --threshold ${threshold}`,
|
|
2655
|
+
` env:`,
|
|
2656
|
+
` LEMMA_LICENSE_KEY: \$(LEMMA_LICENSE_KEY)`,
|
|
2657
|
+
` LEMMA_PLATFORM: azure`,
|
|
2658
|
+
` LEMMA_REPO: \$(Build.Repository.Name)`,
|
|
2659
|
+
` LEMMA_PR_NUMBER: \$(System.PullRequest.PullRequestId)`,
|
|
2660
|
+
` AZURE_DEVOPS_TOKEN: \$(AZURE_DEVOPS_TOKEN)`,
|
|
2661
|
+
].join("\n");
|
|
2662
|
+
}
|
|
2361
2663
|
//# sourceMappingURL=tools.js.map
|