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.
Files changed (2) hide show
  1. package/cli.mjs +256 -44
  2. 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
- * agentaudit Discover local MCP servers
7
- * agentaudit discover [--quick|--deep] Find MCP servers in AI editors
8
- * agentaudit scan <repo-url> [--deep] Quick scan (or deep audit with --deep)
9
- * agentaudit audit <repo-url> Deep LLM-powered security audit
10
- * agentaudit lookup <name> Look up package in registry
11
- * agentaudit setup Register + configure API key
12
- *
13
- * Global flags: --json, --quiet, --no-color, --no-upload
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
- if (args[0] === '--help' || args[0] === '-h') {
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(` ${c.bold}Commands:${c.reset}`);
2092
+ for (const line of helpLines) console.log(` ${line}`);
1970
2093
  console.log();
1971
- console.log(` ${c.cyan}agentaudit${c.reset} Discover MCP servers (same as discover)`);
1972
- console.log(` ${c.cyan}agentaudit discover${c.reset} Find MCP servers in your AI editors (Cursor, Claude, VS Code, Windsurf)`);
1973
- console.log(` ${c.cyan}agentaudit discover --quick${c.reset} Discover + auto-scan all servers`);
1974
- console.log(` ${c.cyan}agentaudit discover --deep${c.reset} Discover + select servers to deep-audit`);
1975
- console.log(` ${c.cyan}agentaudit scan${c.reset} <url> [url...] Quick static scan (regex, local)`);
1976
- console.log(` ${c.cyan}agentaudit scan${c.reset} <url> ${c.dim}--deep${c.reset} Deep audit (same as audit)`);
1977
- console.log(` ${c.cyan}agentaudit audit${c.reset} <url> [url...] Deep LLM-powered security audit`);
1978
- console.log(` ${c.cyan}agentaudit lookup${c.reset} <name> Look up package in registry`);
1979
- console.log(` ${c.cyan}agentaudit model${c.reset} Configure LLM provider + model interactively`);
1980
- console.log(` ${c.cyan}agentaudit model${c.reset} <name> Set model directly (e.g. gpt-4o)`);
1981
- console.log(` ${c.cyan}agentaudit setup${c.reset} Create account / enter API key (for report uploads)`);
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}Global flags:${c.reset}`);
1984
- console.log(` ${c.dim}--json Output JSON to stdout (machine-readable)${c.reset}`);
1985
- console.log(` ${c.dim}--quiet Suppress banner and tree visualization${c.reset}`);
1986
- console.log(` ${c.dim}--no-color Disable ANSI colors (also: NO_COLOR env)${c.reset}`);
1987
- console.log(` ${c.dim}--model <name> Override LLM model for this run${c.reset}`);
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}Quick Scan${c.reset} vs ${c.bold}Deep Audit${c.reset}:`);
1991
- console.log(` ${c.dim}scan = fast regex-based static analysis (~2s)${c.reset}`);
1992
- console.log(` ${c.dim}audit = deep LLM analysis with 3-pass methodology (~30s)${c.reset}`);
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}Exit codes:${c.reset}`);
1995
- console.log(` ${c.dim}0 = clean / success 1 = findings detected 2 = error${c.reset}`);
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}Examples:${c.reset}`);
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}For deep audits,${c.reset} set an LLM API key (e.g. ${c.cyan}export OPENROUTER_API_KEY=sk-or-...${c.reset})`);
2005
- console.log(` ${c.dim}Run "agentaudit model" to configure provider + model interactively${c.reset}`);
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 --help for usage${c.reset}`);
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.10.1",
3
+ "version": "3.10.2",
4
4
  "description": "Security scanner for AI packages — MCP server + CLI",
5
5
  "type": "module",
6
6
  "bin": {