agentaudit 3.5.0 → 3.6.0

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 (3) hide show
  1. package/cli.mjs +38 -9
  2. package/index.mjs +4 -3
  3. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -14,6 +14,7 @@
14
14
  */
15
15
 
16
16
  import fs from 'fs';
17
+ import os from 'os';
17
18
  import path from 'path';
18
19
  import { execSync } from 'child_process';
19
20
  import { createInterface } from 'readline';
@@ -573,15 +574,18 @@ async function scanRepo(url) {
573
574
  process.stdout.write(`${icons.scan} Scanning ${c.bold}${slug}${c.reset} ${c.dim}...${c.reset}`);
574
575
 
575
576
  // Clone
576
- const tmpDir = fs.mkdtempSync('/tmp/agentaudit-');
577
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentaudit-'));
577
578
  const repoPath = path.join(tmpDir, 'repo');
578
579
  try {
579
- execSync(`git clone --depth 1 "${url}" "${repoPath}" 2>/dev/null`, {
580
+ execSync(`git clone --depth 1 "${url}" "${repoPath}"`, {
580
581
  timeout: 30_000,
581
582
  stdio: 'pipe',
582
583
  });
583
584
  } catch (err) {
584
585
  process.stdout.write(` ${c.red}✖ clone failed${c.reset}\n`);
586
+ const msg = err.stderr?.toString().trim() || err.message?.split('\n')[0] || '';
587
+ if (msg) console.log(` ${c.dim}${msg}${c.reset}`);
588
+ console.log(` ${c.dim}Make sure git is installed and the URL is accessible.${c.reset}`);
585
589
  return null;
586
590
  }
587
591
 
@@ -598,7 +602,7 @@ async function scanRepo(url) {
598
602
  const registryData = await checkRegistry(slug);
599
603
 
600
604
  // Cleanup
601
- try { execSync(`rm -rf "${tmpDir}"`, { stdio: 'pipe' }); } catch {}
605
+ try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
602
606
 
603
607
  const duration = elapsed(start);
604
608
 
@@ -937,15 +941,18 @@ async function auditRepo(url) {
937
941
 
938
942
  // Step 1: Clone
939
943
  process.stdout.write(` ${c.dim}[1/4]${c.reset} Cloning repository...`);
940
- const tmpDir = fs.mkdtempSync('/tmp/agentaudit-');
944
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentaudit-'));
941
945
  const repoPath = path.join(tmpDir, 'repo');
942
946
  try {
943
- execSync(`git clone --depth 1 "${url}" "${repoPath}" 2>/dev/null`, {
947
+ execSync(`git clone --depth 1 "${url}" "${repoPath}"`, {
944
948
  timeout: 30_000, stdio: 'pipe',
945
949
  });
946
950
  console.log(` ${c.green}done${c.reset}`);
947
- } catch {
951
+ } catch (err) {
948
952
  console.log(` ${c.red}failed${c.reset}`);
953
+ const msg = err.stderr?.toString().trim() || err.message?.split('\n')[0] || '';
954
+ if (msg) console.log(` ${c.dim}${msg}${c.reset}`);
955
+ console.log(` ${c.dim}Make sure git is installed and the URL is accessible.${c.reset}`);
949
956
  return null;
950
957
  }
951
958
 
@@ -985,6 +992,10 @@ async function auditRepo(url) {
985
992
  console.log(` ${c.dim}$env:ANTHROPIC_API_KEY = "sk-ant-..."${c.reset}`);
986
993
  console.log(` ${c.dim}$env:OPENAI_API_KEY = "sk-..."${c.reset}`);
987
994
  console.log();
995
+ console.log(` ${c.dim}# Windows (CMD):${c.reset}`);
996
+ console.log(` ${c.dim}set ANTHROPIC_API_KEY=sk-ant-...${c.reset}`);
997
+ console.log(` ${c.dim}set OPENAI_API_KEY=sk-...${c.reset}`);
998
+ console.log();
988
999
  console.log(` ${c.bold}Option 2: Export for manual review${c.reset}`);
989
1000
  console.log(` ${c.cyan}agentaudit audit ${url} --export${c.reset}`);
990
1001
  console.log(` ${c.dim}Creates a markdown file you can paste into any LLM (Claude, ChatGPT, etc.)${c.reset}`);
@@ -1023,7 +1034,7 @@ async function auditRepo(url) {
1023
1034
  }
1024
1035
 
1025
1036
  // Cleanup
1026
- try { execSync(`rm -rf "${tmpDir}"`, { stdio: 'pipe' }); } catch {}
1037
+ try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
1027
1038
  return null;
1028
1039
  }
1029
1040
 
@@ -1097,12 +1108,12 @@ async function auditRepo(url) {
1097
1108
  } catch (err) {
1098
1109
  console.log(` ${c.red}failed${c.reset}`);
1099
1110
  console.log(` ${c.red}${err.message}${c.reset}`);
1100
- try { execSync(`rm -rf "${tmpDir}"`, { stdio: 'pipe' }); } catch {}
1111
+ try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
1101
1112
  return null;
1102
1113
  }
1103
1114
 
1104
1115
  // Cleanup repo
1105
- try { execSync(`rm -rf "${tmpDir}"`, { stdio: 'pipe' }); } catch {}
1116
+ try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
1106
1117
 
1107
1118
  if (!report) {
1108
1119
  console.log(` ${c.red}Could not parse LLM response as JSON${c.reset}`);
@@ -1189,6 +1200,11 @@ async function checkPackage(name) {
1189
1200
  async function main() {
1190
1201
  const args = process.argv.slice(2);
1191
1202
 
1203
+ if (args[0] === '-v' || args[0] === '--version') {
1204
+ console.log(`agentaudit ${getVersion()}`);
1205
+ process.exit(0);
1206
+ }
1207
+
1192
1208
  if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
1193
1209
  banner();
1194
1210
  console.log(` ${c.bold}Commands:${c.reset}`);
@@ -1209,6 +1225,19 @@ async function main() {
1209
1225
  console.log(` agentaudit audit https://github.com/owner/repo`);
1210
1226
  console.log(` agentaudit check fastmcp`);
1211
1227
  console.log();
1228
+ console.log(` ${c.bold}For deep audits,${c.reset} set an LLM API key:`);
1229
+ if (process.platform === 'win32') {
1230
+ console.log(` ${c.dim}PowerShell: $env:ANTHROPIC_API_KEY = "sk-ant-..."${c.reset}`);
1231
+ console.log(` ${c.dim}CMD: set ANTHROPIC_API_KEY=sk-ant-...${c.reset}`);
1232
+ console.log(` ${c.dim}(or use OPENAI_API_KEY instead)${c.reset}`);
1233
+ } else {
1234
+ console.log(` ${c.dim}export ANTHROPIC_API_KEY=sk-ant-...${c.reset} ${c.dim}(or OPENAI_API_KEY)${c.reset}`);
1235
+ }
1236
+ console.log();
1237
+ console.log(` ${c.bold}Or use as MCP server${c.reset} in Cursor/Claude ${c.dim}(no extra API key needed):${c.reset}`);
1238
+ console.log(` ${c.dim}Add to your MCP config:${c.reset}`);
1239
+ console.log(` ${c.dim}{ "agentaudit": { "command": "npx", "args": ["-y", "agentaudit"] } }${c.reset}`);
1240
+ console.log();
1212
1241
  process.exit(0);
1213
1242
  }
1214
1243
 
package/index.mjs CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  ListToolsRequestSchema,
26
26
  } from '@modelcontextprotocol/sdk/types.js';
27
27
  import fs from 'fs';
28
+ import os from 'os';
28
29
  import path from 'path';
29
30
  import { execSync } from 'child_process';
30
31
  import { fileURLToPath } from 'url';
@@ -124,9 +125,9 @@ function collectFiles(dir, basePath = '', collected = [], totalSize = { bytes: 0
124
125
  // ── Repo Helpers ────────────────────────────────────────
125
126
 
126
127
  function cloneRepo(sourceUrl) {
127
- const tmpDir = fs.mkdtempSync('/tmp/agentaudit-');
128
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentaudit-'));
128
129
  try {
129
- execSync(`git clone --depth 1 "${sourceUrl}" "${tmpDir}/repo" 2>/dev/null`, {
130
+ execSync(`git clone --depth 1 "${sourceUrl}" "${tmpDir}/repo"`, {
130
131
  timeout: 30_000, stdio: 'pipe',
131
132
  });
132
133
  return path.join(tmpDir, 'repo');
@@ -136,7 +137,7 @@ function cloneRepo(sourceUrl) {
136
137
  }
137
138
 
138
139
  function cleanupRepo(repoPath) {
139
- try { execSync(`rm -rf "${path.dirname(repoPath)}"`, { stdio: 'pipe' }); } catch {}
140
+ try { fs.rmSync(path.dirname(repoPath), { recursive: true, force: true }); } catch {}
140
141
  }
141
142
 
142
143
  function slugFromUrl(url) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "Security scanner for AI packages — MCP server + CLI",
5
5
  "type": "module",
6
6
  "bin": {