agentaudit 3.12.3 → 3.12.5

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 (2) hide show
  1. package/cli.mjs +36 -24
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -2598,8 +2598,8 @@ async function callLlm(llmConfig, systemPrompt, userMessage) {
2598
2598
  const res = await fetch(llmConfig.url, {
2599
2599
  method: 'POST',
2600
2600
  headers: { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01', 'content-type': 'application/json' },
2601
- body: JSON.stringify({ model: llmConfig.model, max_tokens: 8192, system: systemPrompt, messages: [{ role: 'user', content: userMessage }] }),
2602
- signal: AbortSignal.timeout(120_000),
2601
+ body: JSON.stringify({ model: llmConfig.model, max_tokens: 16384, system: systemPrompt, messages: [{ role: 'user', content: userMessage }] }),
2602
+ signal: AbortSignal.timeout(180_000),
2603
2603
  });
2604
2604
  data = await res.json();
2605
2605
  if (data.error) {
@@ -2622,9 +2622,9 @@ async function callLlm(llmConfig, systemPrompt, userMessage) {
2622
2622
  body: JSON.stringify({
2623
2623
  systemInstruction: { parts: [{ text: systemPrompt }] },
2624
2624
  contents: [{ role: 'user', parts: [{ text: userMessage }] }],
2625
- generationConfig: { maxOutputTokens: 8192 },
2625
+ generationConfig: { maxOutputTokens: 65536, responseMimeType: 'application/json', thinkingConfig: { thinkingBudget: 8192 } },
2626
2626
  }),
2627
- signal: AbortSignal.timeout(120_000),
2627
+ signal: AbortSignal.timeout(180_000),
2628
2628
  });
2629
2629
  data = await res.json();
2630
2630
  if (data.error) {
@@ -2645,8 +2645,8 @@ async function callLlm(llmConfig, systemPrompt, userMessage) {
2645
2645
  const res = await fetch(llmConfig.url, {
2646
2646
  method: 'POST',
2647
2647
  headers,
2648
- body: JSON.stringify({ model: llmConfig.model, max_tokens: 8192, messages: [{ role: 'system', content: systemPrompt }, { role: 'user', content: userMessage }] }),
2649
- signal: AbortSignal.timeout(120_000),
2648
+ body: JSON.stringify({ model: llmConfig.model, max_tokens: 16384, messages: [{ role: 'system', content: systemPrompt }, { role: 'user', content: userMessage }] }),
2649
+ signal: AbortSignal.timeout(180_000),
2650
2650
  });
2651
2651
  data = await res.json();
2652
2652
  if (data.error) {
@@ -2802,27 +2802,39 @@ function enrichFindings(report, files, pkgInfo) {
2802
2802
 
2803
2803
  async function auditRepo(url) {
2804
2804
  const start = Date.now();
2805
- const slug = slugFromUrl(url);
2806
-
2805
+
2806
+ // Support local directories
2807
+ const isLocal = fs.existsSync(url) && fs.statSync(url).isDirectory();
2808
+ const slug = isLocal ? path.basename(url) : slugFromUrl(url);
2809
+
2807
2810
  console.log(`${icons.scan} ${c.bold}Auditing ${slug}${c.reset} ${c.dim}${url}${c.reset}`);
2808
2811
  console.log(`${icons.pipe} ${c.dim}Deep LLM-powered analysis (3-pass: UNDERSTAND → DETECT → CLASSIFY)${c.reset}`);
2809
2812
  console.log();
2810
-
2811
- // Step 1: Clone
2812
- process.stdout.write(` ${stepProgress(1, 4)} Cloning repository...`);
2813
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentaudit-'));
2814
- const repoPath = path.join(tmpDir, 'repo');
2815
- try {
2816
- safeGitClone(url, repoPath);
2813
+
2814
+ let repoPath, tmpDir = null;
2815
+
2816
+ if (isLocal) {
2817
+ // Local directory no cloning needed
2818
+ repoPath = path.resolve(url);
2819
+ process.stdout.write(` ${stepProgress(1, 4)} Reading local directory...`);
2817
2820
  console.log(` ${c.green}done${c.reset}`);
2818
- } catch (err) {
2819
- console.log(` ${c.red}failed${c.reset}`);
2820
- const msg = err.stderr?.toString().trim() || err.message?.split('\n')[0] || '';
2821
- if (msg) console.log(` ${c.dim}${msg}${c.reset}`);
2822
- console.log(` ${c.dim}Make sure git is installed and the URL is accessible.${c.reset}`);
2823
- return null;
2821
+ } else {
2822
+ // Step 1: Clone
2823
+ process.stdout.write(` ${stepProgress(1, 4)} Cloning repository...`);
2824
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentaudit-'));
2825
+ repoPath = path.join(tmpDir, 'repo');
2826
+ try {
2827
+ safeGitClone(url, repoPath);
2828
+ console.log(` ${c.green}done${c.reset}`);
2829
+ } catch (err) {
2830
+ console.log(` ${c.red}failed${c.reset}`);
2831
+ const msg = err.stderr?.toString().trim() || err.message?.split('\n')[0] || '';
2832
+ if (msg) console.log(` ${c.dim}${msg}${c.reset}`);
2833
+ console.log(` ${c.dim}Make sure git is installed and the URL is accessible.${c.reset}`);
2834
+ return null;
2835
+ }
2824
2836
  }
2825
-
2837
+
2826
2838
  // Step 2: Collect files
2827
2839
  process.stdout.write(` ${stepProgress(2, 4)} Collecting source files...`);
2828
2840
  const files = collectFiles(repoPath);
@@ -2852,8 +2864,8 @@ async function auditRepo(url) {
2852
2864
  if (KNOWN_MCP_LIBS.has(slug)) detectedType = 'library';
2853
2865
  if (KNOWN_CLI.has(slug)) detectedType = 'cli-tool';
2854
2866
 
2855
- // Cleanup repo (files in memory, provenance captured)
2856
- try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
2867
+ // Cleanup cloned repo (files in memory, provenance captured); skip for local dirs
2868
+ if (tmpDir) { try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {} }
2857
2869
 
2858
2870
  // Build prompts
2859
2871
  const systemPrompt = auditPrompt || 'You are a security auditor. Analyze the code and report findings as JSON.';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.12.3",
3
+ "version": "3.12.5",
4
4
  "description": "Security scanner for AI packages — MCP server + CLI",
5
5
  "type": "module",
6
6
  "bin": {