File size: 2,719 Bytes
38fb424
 
5710d63
 
 
 
6389903
 
 
5710d63
6389903
3f143e9
ff2afe2
b6cd280
5710d63
 
 
 
 
 
 
b6cd280
5710d63
 
 
 
b6cd280
 
5710d63
 
 
 
 
 
 
b6cd280
5710d63
69b971b
5710d63
e8aa1e7
5710d63
 
 
 
 
e8aa1e7
5710d63
 
6389903
 
5710d63
ff2afe2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6389903
 
ff2afe2
6389903
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import "dotenv/config";

import { readFileSync, mkdirSync, writeFileSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

import { auditorAgent } from "./agents/auditor/agent.js";
import { coderAgent } from "./agents/coder/agent.js";
import { testerAgent } from "./agents/tester/agent.js";
import { logger } from "./logger.js";
import type { VulnerabilityReport, Finding } from "./agents/tester/types.js";
import { mapFindingToReport } from "./utils/mapFinding.js";
import { createEmptyFoundryProject } from "./utils/forgeSandbox.js";

const inputPath = process.argv[2];

if (!inputPath) {
  console.log("Uso: npm start -- <caminho-do-arquivo-de-requisitos>");
  console.log("Exemplo: npm start -- input/requirements.md");
  process.exit(1);
}

const requirementsText = readFileSync(resolve(inputPath), "utf-8");
console.log("Requisitos carregados de:", inputPath);

const coderResult = await coderAgent.invoke({ requirements: [requirementsText] });
console.log("======= Coder =======");

const __dirname = dirname(fileURLToPath(import.meta.url));
const outputDir = resolve(__dirname, "agents/coder/outputs");
mkdirSync(outputDir, { recursive: true });
writeFileSync(resolve(outputDir, "Contract.sol"), coderResult.contract, "utf-8");
writeFileSync(resolve(outputDir, "README.md"), requirementsText, "utf-8");
console.log("\nContrato e requisitos salvos em:", outputDir);

console.log("\n======= Auditor =======");
logger.info("Starting auditorAgent");

const auditorResult = await auditorAgent.invoke({ repoPath: outputDir });

logger.info("Agent completed");
logger.info(`Findings: ${auditorResult.findings.length}`);
for (const f of auditorResult.findings) {
  logger.info(`  [${f.severity.toUpperCase()}] ${f.title}${f.location}`);
}

if (auditorResult.findings.length > 0) {
  const finding = auditorResult.findings[0];
  const report = mapFindingToReport(finding, coderResult.contract);

  console.log("\n======= Tester =======");
  
  // Create isolated Foundry Sandbox for the End-to-End run
  const sandboxDir = resolve(__dirname, "agents/tester/temp_e2e_run");
  await createEmptyFoundryProject(sandboxDir, coderResult.contract, "Contract");
  
  // Attach sandboxDir to report metadata (so the agent knows where it is)
  report.customSandboxDir = sandboxDir;

  const testerResult = await testerAgent.invoke(
    { report }, 
    { 
      recursionLimit: 100,
      configurable: { sandboxDir }
    }
  ) as any;

  console.log("Status:", testerResult.status);
  console.log("Iterations:", testerResult.toolCallCount || 0);
} else {
  console.log("\n======= Tester =======");
  console.log("Nenhuma vulnerabilidade encontrada pelo Auditor.");
}