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.
- package/cli.mjs +38 -9
- package/index.mjs +4 -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('
|
|
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}"
|
|
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 {
|
|
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('
|
|
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}"
|
|
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 {
|
|
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 {
|
|
1111
|
+
try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
|
|
1101
1112
|
return null;
|
|
1102
1113
|
}
|
|
1103
1114
|
|
|
1104
1115
|
// Cleanup repo
|
|
1105
|
-
try {
|
|
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('
|
|
128
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentaudit-'));
|
|
128
129
|
try {
|
|
129
|
-
execSync(`git clone --depth 1 "${sourceUrl}" "${tmpDir}/repo"
|
|
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 {
|
|
140
|
+
try { fs.rmSync(path.dirname(repoPath), { recursive: true, force: true }); } catch {}
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
function slugFromUrl(url) {
|