agentaudit 3.10.1 → 3.10.2
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 +256 -44
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* AgentAudit CLI — Security scanner for AI packages
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* Usage: agentaudit <command> [options]
|
|
6
|
+
*
|
|
7
|
+
* Commands:
|
|
8
|
+
* discover Find MCP servers in AI editors
|
|
9
|
+
* scan <url> [url...] Quick static scan (regex)
|
|
10
|
+
* audit <url> [url...] Deep LLM-powered security audit
|
|
11
|
+
* lookup <name> Look up package in registry
|
|
12
|
+
* model [name|reset] Configure LLM provider + model
|
|
13
|
+
* setup Create account / enter API key
|
|
14
|
+
* status Show current config + auth status
|
|
15
|
+
* help [command] Show help
|
|
16
|
+
*
|
|
17
|
+
* Flags: --json, --quiet, --no-color, --no-upload, --model, --export, --debug
|
|
14
18
|
*/
|
|
15
19
|
|
|
16
20
|
import fs from 'fs';
|
|
@@ -1959,53 +1963,190 @@ async function main() {
|
|
|
1959
1963
|
const modelIdx = args.indexOf('--model');
|
|
1960
1964
|
if (modelIdx !== -1) args.splice(modelIdx, 2);
|
|
1961
1965
|
|
|
1966
|
+
// Detect per-command --help BEFORE stripping (e.g. `agentaudit model --help`)
|
|
1967
|
+
const wantsHelp = args.includes('--help') || args.includes('-h');
|
|
1968
|
+
// Strip --help/-h from args for routing
|
|
1969
|
+
args = args.filter(a => a !== '--help' && a !== '-h');
|
|
1970
|
+
|
|
1962
1971
|
if (args[0] === '-v' || args[0] === '--version') {
|
|
1963
1972
|
console.log(`agentaudit ${getVersion()}`);
|
|
1964
1973
|
process.exitCode = 0; return;
|
|
1965
1974
|
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1975
|
+
|
|
1976
|
+
// Subcommand help definitions
|
|
1977
|
+
const subcommandHelp = {
|
|
1978
|
+
discover: [
|
|
1979
|
+
`${c.bold}agentaudit discover${c.reset} [options]`,
|
|
1980
|
+
``,
|
|
1981
|
+
`Find MCP servers configured in your AI editors (Cursor, Claude Desktop, VS Code, Windsurf).`,
|
|
1982
|
+
``,
|
|
1983
|
+
`${c.bold}Options:${c.reset}`,
|
|
1984
|
+
` --quick, -s Auto-scan all discovered servers (regex-based)`,
|
|
1985
|
+
` --deep, -a Interactively select servers for deep LLM audit`,
|
|
1986
|
+
``,
|
|
1987
|
+
`${c.bold}Examples:${c.reset}`,
|
|
1988
|
+
` agentaudit discover`,
|
|
1989
|
+
` agentaudit discover --quick`,
|
|
1990
|
+
` agentaudit discover --deep`,
|
|
1991
|
+
],
|
|
1992
|
+
scan: [
|
|
1993
|
+
`${c.bold}agentaudit scan${c.reset} <url> [url...] [options]`,
|
|
1994
|
+
``,
|
|
1995
|
+
`Quick regex-based static security scan (~2s). Checks for 15+ patterns`,
|
|
1996
|
+
`(command injection, eval, hardcoded secrets, path traversal, etc.)`,
|
|
1997
|
+
``,
|
|
1998
|
+
`${c.bold}Options:${c.reset}`,
|
|
1999
|
+
` --deep Run deep LLM audit instead (same as \`agentaudit audit\`)`,
|
|
2000
|
+
``,
|
|
2001
|
+
`${c.bold}Examples:${c.reset}`,
|
|
2002
|
+
` agentaudit scan https://github.com/owner/repo`,
|
|
2003
|
+
` agentaudit scan https://github.com/a/b https://github.com/c/d`,
|
|
2004
|
+
` agentaudit scan https://github.com/owner/repo --deep`,
|
|
2005
|
+
],
|
|
2006
|
+
audit: [
|
|
2007
|
+
`${c.bold}agentaudit audit${c.reset} <url> [url...] [options]`,
|
|
2008
|
+
``,
|
|
2009
|
+
`Deep LLM-powered 3-pass security audit (~30s). Requires an LLM API key.`,
|
|
2010
|
+
``,
|
|
2011
|
+
`${c.bold}Options:${c.reset}`,
|
|
2012
|
+
` --model <name> Override LLM model for this run`,
|
|
2013
|
+
` --no-upload Skip uploading report to registry`,
|
|
2014
|
+
` --export Export audit payload as markdown (for manual LLM review)`,
|
|
2015
|
+
` --debug Show raw LLM response on parse errors`,
|
|
2016
|
+
``,
|
|
2017
|
+
`${c.bold}Examples:${c.reset}`,
|
|
2018
|
+
` agentaudit audit https://github.com/owner/repo`,
|
|
2019
|
+
` agentaudit audit https://github.com/owner/repo --no-upload`,
|
|
2020
|
+
` agentaudit audit https://github.com/owner/repo --model gpt-4o`,
|
|
2021
|
+
` agentaudit audit https://github.com/owner/repo --export`,
|
|
2022
|
+
],
|
|
2023
|
+
lookup: [
|
|
2024
|
+
`${c.bold}agentaudit lookup${c.reset} <name> [options]`,
|
|
2025
|
+
``,
|
|
2026
|
+
`Look up a package in the AgentAudit registry. Shows trust score,`,
|
|
2027
|
+
`findings, confidence level, and audit history.`,
|
|
2028
|
+
``,
|
|
2029
|
+
`${c.bold}Aliases:${c.reset} lookup, check`,
|
|
2030
|
+
``,
|
|
2031
|
+
`${c.bold}Examples:${c.reset}`,
|
|
2032
|
+
` agentaudit lookup fastmcp`,
|
|
2033
|
+
` agentaudit lookup @anthropic/mcp-server-filesystem --json`,
|
|
2034
|
+
` agentaudit check fastmcp`,
|
|
2035
|
+
],
|
|
2036
|
+
check: null, // alias → lookup
|
|
2037
|
+
model: [
|
|
2038
|
+
`${c.bold}agentaudit model${c.reset} [name|reset]`,
|
|
2039
|
+
``,
|
|
2040
|
+
`Configure LLM provider and model. Interactive two-step menu when`,
|
|
2041
|
+
`called without arguments: choose provider, then choose model.`,
|
|
2042
|
+
``,
|
|
2043
|
+
`${c.bold}Usage:${c.reset}`,
|
|
2044
|
+
` agentaudit model Interactive provider + model menu`,
|
|
2045
|
+
` agentaudit model <name> Set model directly (keeps current provider)`,
|
|
2046
|
+
` agentaudit model reset Reset provider + model to defaults`,
|
|
2047
|
+
``,
|
|
2048
|
+
`${c.bold}Examples:${c.reset}`,
|
|
2049
|
+
` agentaudit model`,
|
|
2050
|
+
` agentaudit model gpt-4o`,
|
|
2051
|
+
` agentaudit model qwen/qwen3-coder`,
|
|
2052
|
+
` agentaudit model reset`,
|
|
2053
|
+
],
|
|
2054
|
+
setup: [
|
|
2055
|
+
`${c.bold}agentaudit setup${c.reset}`,
|
|
2056
|
+
``,
|
|
2057
|
+
`Create an AgentAudit account or enter an existing API key.`,
|
|
2058
|
+
`This is for uploading audit reports to the registry — not for`,
|
|
2059
|
+
`LLM provider configuration (use \`agentaudit model\` for that).`,
|
|
2060
|
+
``,
|
|
2061
|
+
`${c.bold}Examples:${c.reset}`,
|
|
2062
|
+
` agentaudit setup`,
|
|
2063
|
+
],
|
|
2064
|
+
status: [
|
|
2065
|
+
`${c.bold}agentaudit status${c.reset}`,
|
|
2066
|
+
``,
|
|
2067
|
+
`Show current configuration: active LLM provider, model, account`,
|
|
2068
|
+
`status, and which API keys are available.`,
|
|
2069
|
+
``,
|
|
2070
|
+
`${c.bold}Aliases:${c.reset} status, whoami`,
|
|
2071
|
+
``,
|
|
2072
|
+
`${c.bold}Examples:${c.reset}`,
|
|
2073
|
+
` agentaudit status`,
|
|
2074
|
+
` agentaudit status --json`,
|
|
2075
|
+
],
|
|
2076
|
+
};
|
|
2077
|
+
|
|
2078
|
+
// Show subcommand help: `agentaudit help <cmd>` or `agentaudit <cmd> --help`
|
|
2079
|
+
function showSubcommandHelp(cmd) {
|
|
2080
|
+
let helpLines = subcommandHelp[cmd];
|
|
2081
|
+
if (helpLines === null && subcommandHelp[cmd] === null) {
|
|
2082
|
+
// alias redirect
|
|
2083
|
+
const alias = cmd === 'check' ? 'lookup' : cmd;
|
|
2084
|
+
helpLines = subcommandHelp[alias];
|
|
2085
|
+
}
|
|
2086
|
+
if (!helpLines) {
|
|
2087
|
+
console.log(` ${c.red}No help available for "${cmd}"${c.reset}`);
|
|
2088
|
+
console.log(` ${c.dim}Run ${c.cyan}agentaudit help${c.dim} for available commands${c.reset}`);
|
|
2089
|
+
return;
|
|
2090
|
+
}
|
|
1968
2091
|
banner();
|
|
1969
|
-
console.log(` ${
|
|
2092
|
+
for (const line of helpLines) console.log(` ${line}`);
|
|
1970
2093
|
console.log();
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
// Handle: `agentaudit <cmd> --help` (wantsHelp + has a command)
|
|
2097
|
+
if (wantsHelp && args[0] && args[0] !== '--help' && args[0] !== '-h') {
|
|
2098
|
+
const cmd = args[0];
|
|
2099
|
+
if (subcommandHelp[cmd] !== undefined) {
|
|
2100
|
+
showSubcommandHelp(cmd);
|
|
2101
|
+
process.exitCode = 0; return;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
// Handle: `agentaudit help [cmd]`
|
|
2106
|
+
if (args[0] === 'help') {
|
|
2107
|
+
const helpCmd = args[1];
|
|
2108
|
+
if (helpCmd && subcommandHelp[helpCmd] !== undefined) {
|
|
2109
|
+
showSubcommandHelp(helpCmd);
|
|
2110
|
+
process.exitCode = 0; return;
|
|
2111
|
+
}
|
|
2112
|
+
// No subcommand or unknown → show main help
|
|
2113
|
+
wantsHelp || (args[0] = '--help'); // fall through to main help
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help' || (wantsHelp && args.length === 0)) {
|
|
2117
|
+
banner();
|
|
2118
|
+
console.log(` ${c.bold}USAGE${c.reset}`);
|
|
2119
|
+
console.log(` agentaudit <command> [options]`);
|
|
1982
2120
|
console.log();
|
|
1983
|
-
console.log(` ${c.bold}
|
|
1984
|
-
console.log(` ${c.
|
|
1985
|
-
console.log(` ${c.
|
|
1986
|
-
console.log(` ${c.
|
|
1987
|
-
console.log(` ${c.
|
|
1988
|
-
console.log(` ${c.dim}--no-upload Skip uploading report to registry${c.reset}`);
|
|
2121
|
+
console.log(` ${c.bold}SCAN & AUDIT${c.reset}`);
|
|
2122
|
+
console.log(` ${c.cyan}discover${c.reset} Find MCP servers in your AI editors`);
|
|
2123
|
+
console.log(` ${c.cyan}scan${c.reset} <url> [url...] Quick static scan (regex, ~2s)`);
|
|
2124
|
+
console.log(` ${c.cyan}audit${c.reset} <url> [url...] Deep LLM-powered security audit (~30s)`);
|
|
2125
|
+
console.log(` ${c.cyan}lookup${c.reset} <name> Look up package in registry`);
|
|
1989
2126
|
console.log();
|
|
1990
|
-
console.log(` ${c.bold}
|
|
1991
|
-
console.log(` ${c.
|
|
1992
|
-
console.log(` ${c.
|
|
2127
|
+
console.log(` ${c.bold}CONFIGURATION${c.reset}`);
|
|
2128
|
+
console.log(` ${c.cyan}model${c.reset} Configure LLM provider + model`);
|
|
2129
|
+
console.log(` ${c.cyan}setup${c.reset} Create account / enter API key`);
|
|
2130
|
+
console.log(` ${c.cyan}status${c.reset} Show current config + auth status`);
|
|
1993
2131
|
console.log();
|
|
1994
|
-
console.log(` ${c.bold}
|
|
1995
|
-
console.log(` ${c.dim}
|
|
2132
|
+
console.log(` ${c.bold}FLAGS${c.reset}`);
|
|
2133
|
+
console.log(` ${c.dim}--json Machine-readable JSON output${c.reset}`);
|
|
2134
|
+
console.log(` ${c.dim}--quiet Suppress banner${c.reset}`);
|
|
2135
|
+
console.log(` ${c.dim}--no-color Disable ANSI colors (also: NO_COLOR env)${c.reset}`);
|
|
2136
|
+
console.log(` ${c.dim}--model <name> Override LLM model for this run${c.reset}`);
|
|
2137
|
+
console.log(` ${c.dim}--no-upload Skip uploading report to registry${c.reset}`);
|
|
2138
|
+
console.log(` ${c.dim}--export Export audit payload as markdown${c.reset}`);
|
|
2139
|
+
console.log(` ${c.dim}--debug Show raw LLM response on parse errors${c.reset}`);
|
|
1996
2140
|
console.log();
|
|
1997
|
-
console.log(` ${c.bold}
|
|
1998
|
-
console.log(` agentaudit`);
|
|
2141
|
+
console.log(` ${c.bold}EXAMPLES${c.reset}`);
|
|
1999
2142
|
console.log(` agentaudit discover --quick`);
|
|
2000
2143
|
console.log(` agentaudit scan https://github.com/owner/repo`);
|
|
2001
2144
|
console.log(` agentaudit audit https://github.com/owner/repo`);
|
|
2002
2145
|
console.log(` agentaudit lookup fastmcp --json`);
|
|
2003
2146
|
console.log();
|
|
2004
|
-
console.log(` ${c.bold}
|
|
2005
|
-
console.log(`
|
|
2006
|
-
console.log();
|
|
2007
|
-
console.log(` ${c.bold}Or use as MCP server${c.reset} in Cursor/Claude ${c.dim}(no extra API key needed):${c.reset}`);
|
|
2008
|
-
console.log(` ${c.dim}{ "agentaudit": { "command": "npx", "args": ["-y", "agentaudit"] } }${c.reset}`);
|
|
2147
|
+
console.log(` ${c.bold}LEARN MORE${c.reset}`);
|
|
2148
|
+
console.log(` ${c.dim}agentaudit help <command>${c.reset} Help for a specific command`);
|
|
2149
|
+
console.log(` ${c.dim}https://agentaudit.dev${c.reset} Documentation`);
|
|
2009
2150
|
console.log();
|
|
2010
2151
|
process.exitCode = 0; return;
|
|
2011
2152
|
}
|
|
@@ -2021,6 +2162,75 @@ async function main() {
|
|
|
2021
2162
|
return;
|
|
2022
2163
|
}
|
|
2023
2164
|
|
|
2165
|
+
if (command === 'status' || command === 'whoami') {
|
|
2166
|
+
// ── Status / diagnostic overview ──
|
|
2167
|
+
const config = loadLlmConfig();
|
|
2168
|
+
const creds = loadCredentials();
|
|
2169
|
+
const resolved = resolveProvider();
|
|
2170
|
+
|
|
2171
|
+
console.log(` ${c.bold}Status${c.reset}`);
|
|
2172
|
+
console.log();
|
|
2173
|
+
|
|
2174
|
+
// Provider + Model
|
|
2175
|
+
const prefProvider = config?.preferred_provider;
|
|
2176
|
+
const prefModel = config?.llm_model;
|
|
2177
|
+
if (prefProvider && resolved) {
|
|
2178
|
+
console.log(` Provider ${c.bold}${resolved.name}${c.reset} ${c.dim}(${resolved.key})${c.reset} ${c.green}✔${c.reset}`);
|
|
2179
|
+
} else if (resolved) {
|
|
2180
|
+
console.log(` Provider ${c.bold}${resolved.name}${c.reset} ${c.dim}(auto-detected via ${resolved.key})${c.reset} ${c.green}✔${c.reset}`);
|
|
2181
|
+
} else {
|
|
2182
|
+
console.log(` Provider ${c.yellow}none${c.reset} ${c.dim}— set an API key or run ${c.cyan}agentaudit model${c.dim}${c.reset}`);
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
if (prefModel) {
|
|
2186
|
+
console.log(` Model ${c.bold}${prefModel}${c.reset} ${c.dim}(custom)${c.reset}`);
|
|
2187
|
+
} else if (resolved) {
|
|
2188
|
+
console.log(` Model ${c.dim}${resolved.model} (provider default)${c.reset}`);
|
|
2189
|
+
} else {
|
|
2190
|
+
console.log(` Model ${c.dim}—${c.reset}`);
|
|
2191
|
+
}
|
|
2192
|
+
console.log();
|
|
2193
|
+
|
|
2194
|
+
// Account / auth
|
|
2195
|
+
if (creds) {
|
|
2196
|
+
console.log(` Account ${c.bold}${creds.agent_name}${c.reset} ${c.green}✔ logged in${c.reset}`);
|
|
2197
|
+
console.log(` ${c.dim} Key: ${creds.api_key.slice(0, 12)}...${c.reset}`);
|
|
2198
|
+
} else {
|
|
2199
|
+
console.log(` Account ${c.yellow}not configured${c.reset} ${c.dim}— run ${c.cyan}agentaudit setup${c.dim} to create one${c.reset}`);
|
|
2200
|
+
}
|
|
2201
|
+
console.log();
|
|
2202
|
+
|
|
2203
|
+
// All provider keys
|
|
2204
|
+
const seen = new Set();
|
|
2205
|
+
const keyLines = [];
|
|
2206
|
+
for (const p of LLM_PROVIDERS) {
|
|
2207
|
+
if (seen.has(p.provider)) continue;
|
|
2208
|
+
seen.add(p.provider);
|
|
2209
|
+
const keys = LLM_PROVIDERS.filter(x => x.provider === p.provider);
|
|
2210
|
+
const hasKey = keys.some(x => process.env[x.key]);
|
|
2211
|
+
keyLines.push({ name: p.name, key: p.key, hasKey });
|
|
2212
|
+
}
|
|
2213
|
+
console.log(` ${c.bold}API Keys${c.reset}`);
|
|
2214
|
+
for (const k of keyLines) {
|
|
2215
|
+
const icon = k.hasKey ? `${c.green}✔${c.reset}` : `${c.dim}✗${c.reset}`;
|
|
2216
|
+
const label = k.hasKey ? k.name : `${c.dim}${k.name}${c.reset}`;
|
|
2217
|
+
console.log(` ${icon} ${label} ${c.dim}${k.key}${c.reset}`);
|
|
2218
|
+
}
|
|
2219
|
+
console.log();
|
|
2220
|
+
|
|
2221
|
+
// JSON mode
|
|
2222
|
+
if (jsonMode) {
|
|
2223
|
+
const status = {
|
|
2224
|
+
version: getVersion(),
|
|
2225
|
+
provider: resolved ? { name: resolved.name, provider: resolved.provider, key: resolved.key, model: prefModel || resolved.model } : null,
|
|
2226
|
+
account: creds ? { agent_name: creds.agent_name, has_key: true } : null,
|
|
2227
|
+
api_keys: keyLines.reduce((acc, k) => { acc[k.key] = k.hasKey; return acc; }, {}),
|
|
2228
|
+
};
|
|
2229
|
+
console.log(JSON.stringify(status, null, 2));
|
|
2230
|
+
}
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2024
2234
|
if (command === 'model') {
|
|
2025
2235
|
const newModel = targets.filter(t => !t.startsWith('--'))[0];
|
|
2026
2236
|
const config = loadLlmConfig();
|
|
@@ -2195,6 +2405,7 @@ async function main() {
|
|
|
2195
2405
|
const names = targets.filter(t => !t.startsWith('--'));
|
|
2196
2406
|
if (names.length === 0) {
|
|
2197
2407
|
console.log(` ${c.red}Error: package name required${c.reset}`);
|
|
2408
|
+
console.log(` ${c.dim}Usage: ${c.cyan}agentaudit lookup <name>${c.dim} — e.g. agentaudit lookup fastmcp${c.reset}`);
|
|
2198
2409
|
process.exitCode = 2;
|
|
2199
2410
|
return;
|
|
2200
2411
|
}
|
|
@@ -2207,7 +2418,6 @@ async function main() {
|
|
|
2207
2418
|
console.log(JSON.stringify(results.length === 1 ? (results[0] || { error: 'not_found' }) : results, null, 2));
|
|
2208
2419
|
}
|
|
2209
2420
|
process.exitCode = 0; return;
|
|
2210
|
-
return;
|
|
2211
2421
|
}
|
|
2212
2422
|
|
|
2213
2423
|
if (command === 'scan') {
|
|
@@ -2269,6 +2479,8 @@ async function main() {
|
|
|
2269
2479
|
const urls = targets.filter(t => !t.startsWith('--'));
|
|
2270
2480
|
if (urls.length === 0) {
|
|
2271
2481
|
console.log(` ${c.red}Error: at least one repository URL required${c.reset}`);
|
|
2482
|
+
console.log(` ${c.dim}Usage: ${c.cyan}agentaudit audit <url>${c.dim} — e.g. agentaudit audit https://github.com/owner/repo${c.reset}`);
|
|
2483
|
+
console.log(` ${c.dim}Tip: use ${c.cyan}agentaudit discover --deep${c.dim} to find & audit locally installed MCP servers${c.reset}`);
|
|
2272
2484
|
process.exitCode = 2;
|
|
2273
2485
|
return;
|
|
2274
2486
|
}
|
|
@@ -2283,7 +2495,7 @@ async function main() {
|
|
|
2283
2495
|
}
|
|
2284
2496
|
|
|
2285
2497
|
console.log(` ${c.red}Unknown command: ${command}${c.reset}`);
|
|
2286
|
-
console.log(` ${c.dim}Run agentaudit
|
|
2498
|
+
console.log(` ${c.dim}Run ${c.cyan}agentaudit help${c.dim} for available commands${c.reset}`);
|
|
2287
2499
|
process.exitCode = 2;
|
|
2288
2500
|
}
|
|
2289
2501
|
|