import * as fs from "fs";
import * as path from "path";
import { execSync } from "child_process";
import {
securityScanHandler,
analyzeComplexityHandler,
} from "../tools/quality.js";
import { checkDependenciesHandler } from "../tools/fullstack.js";
// Configuration
const REPO_ROOT = process.cwd();
async function main() {
console.log("π€ Dependabot Agent: Starting analysis...");
// 1. Identify modified files
let modifiedFiles: string[] = [];
try {
// Get files changed in the current PR/commit range
// In GitHub Actions, we might need to fetch origin/main first if checking against it
// For now, assuming HEAD vs HEAD~1 or uncommitted changes if running locally
// Adjust logic for GitHub Actions env later
const diffCommand = "git diff --name-only HEAD~1 HEAD";
modifiedFiles = execSync(diffCommand)
.toString()
.trim()
.split("\n")
.filter(Boolean);
} catch (error) {
console.error("Failed to get diff:", error);
process.exit(1);
}
console.log(`Checking ${modifiedFiles.length} modified files...`);
let report = "# π€ Code-MCP Dependabot Report\n\n";
let hasIssues = false;
// 2. Run Tools on Files
for (const file of modifiedFiles) {
if (!fs.existsSync(file)) continue; // Deleted file
const ext = path.extname(file);
if (![".ts", ".js", ".py", ".go", ".rs"].includes(ext)) continue;
console.log(`Analyzing ${file}...`);
const code = fs.readFileSync(file, "utf-8");
const language = ext.slice(1);
// Security Scan
const securityResult = securityScanHandler({
code,
language,
focus: "all",
});
const securityContent = securityResult.content[0].text;
// Complexity Scan
const complexityResult = analyzeComplexityHandler({ code, language });
const complexityContent = complexityResult.content[0].text;
if (securityContent.includes("π¨") || complexityContent.includes("β οΈ")) {
hasIssues = true;
report += `## File: \`${file}\`\n\n`;
if (securityContent.includes("π¨")) {
report += "### π Security Scan\n";
report += securityContent + "\n\n";
}
if (complexityContent.includes("β οΈ")) {
report += "### π§ Complexity Analysis\n";
report += complexityContent + "\n\n";
}
report += "---\n";
}
}
// 3. Dependency Check (Global)
if (fs.existsSync("package.json")) {
console.log("Running Dependency Audit...");
try {
execSync("npm audit --audit-level=high", { stdio: "ignore" });
report += "## π¦ Dependency Audit\n\nβ
`npm audit` passed.\n";
} catch (e) {
hasIssues = true;
report +=
"## π¦ Dependency Audit\n\nβ `npm audit` found vulnerabilities!\n";
}
}
console.log("Analysis complete.");
// Output report to a file so GitHub Actions can read it
fs.writeFileSync("dependabot-report.md", report);
if (hasIssues) {
console.log("Issues found. Check dependabot-report.md");
process.exit(1); // Fail the build to catch attention
} else {
console.log("No significant issues found.");
}
}
main().catch(console.error);