agentaudit 3.9.21 → 3.9.22

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 +116 -6
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -1631,7 +1631,7 @@ async function auditRepo(url) {
1631
1631
 
1632
1632
  // ── Check command ───────────────────────────────────────
1633
1633
 
1634
- async function checkPackage(name) {
1634
+ async function checkPackage(name, { autoAudit = false } = {}) {
1635
1635
  if (!jsonMode) {
1636
1636
  console.log(`${icons.info} Looking up ${c.bold}${name}${c.reset} in registry...`);
1637
1637
  console.log();
@@ -1640,8 +1640,8 @@ async function checkPackage(name) {
1640
1640
  const data = await checkRegistry(name);
1641
1641
  if (!data) {
1642
1642
  if (!jsonMode) {
1643
- // If input looks like a URL, offer to auto-audit
1644
- if (name.includes('github.com') || name.includes('://')) {
1643
+ // Auto-audit: only when called from 'check' command AND input looks like a URL
1644
+ if (autoAudit && (name.includes('github.com') || name.includes('://'))) {
1645
1645
  console.log(` ${c.yellow}Not found in registry.${c.reset}`);
1646
1646
  console.log(` ${c.dim}Starting audit for ${name}...${c.reset}`);
1647
1647
  console.log();
@@ -1650,7 +1650,8 @@ async function checkPackage(name) {
1650
1650
  console.log(` ${c.yellow}✖ Not found${c.reset} — "${name}" hasn't been audited yet.`);
1651
1651
  console.log();
1652
1652
  console.log(` ${c.dim}Next steps:${c.reset}`);
1653
- console.log(` ${c.cyan}agentaudit audit <repo-url>${c.reset} ${c.dim}Run a deep audit yourself${c.reset}`);
1653
+ console.log(` ${c.cyan}agentaudit check <repo-url>${c.reset} ${c.dim}Auto-lookup + audit if not found${c.reset}`);
1654
+ console.log(` ${c.cyan}agentaudit audit <repo-url>${c.reset} ${c.dim}Deep LLM audit${c.reset}`);
1654
1655
  console.log(` ${c.cyan}agentaudit scan <repo-url>${c.reset} ${c.dim}Quick static check (no API key)${c.reset}`);
1655
1656
  }
1656
1657
  return null;
@@ -1774,6 +1775,7 @@ async function main() {
1774
1775
  console.log(` ${c.bold}SETUP${c.reset}`);
1775
1776
  console.log(` ${c.cyan}status${c.reset} Check providers & API keys`);
1776
1777
  console.log(` ${c.cyan}setup${c.reset} Register & configure`);
1778
+ console.log(` ${c.cyan}models${c.reset} List available LLM models`);
1777
1779
  console.log(` ${c.cyan}config set${c.reset} <key> <value> Set default provider/options`);
1778
1780
  console.log();
1779
1781
  console.log(` ${c.bold}OPTIONS${c.reset}`);
@@ -1910,6 +1912,113 @@ async function main() {
1910
1912
  return;
1911
1913
  }
1912
1914
 
1915
+ if (command === 'models') {
1916
+ const anthropicKey = process.env.ANTHROPIC_API_KEY;
1917
+ const openaiKey = process.env.OPENAI_API_KEY;
1918
+ const openrouterKey = process.env.OPENROUTER_API_KEY;
1919
+
1920
+ console.log(` ${c.bold}Available models by provider:${c.reset}`);
1921
+ console.log();
1922
+
1923
+ // Static lists for Anthropic (no list API)
1924
+ console.log(` ${c.bold}Anthropic${c.reset}${anthropicKey ? ` ${c.green}(configured)${c.reset}` : ` ${c.dim}(not configured)${c.reset}`}`);
1925
+ console.log(` ${c.dim}claude-sonnet-4-20250514${c.reset} ${c.dim}(default)${c.reset}`);
1926
+ console.log(` ${c.dim}claude-opus-4-20250514${c.reset}`);
1927
+ console.log(` ${c.dim}claude-haiku-3-20250514${c.reset}`);
1928
+ console.log();
1929
+
1930
+ // Static list for OpenAI
1931
+ console.log(` ${c.bold}OpenAI${c.reset}${openaiKey ? ` ${c.green}(configured)${c.reset}` : ` ${c.dim}(not configured)${c.reset}`}`);
1932
+ console.log(` ${c.dim}gpt-4o${c.reset} ${c.dim}(default)${c.reset}`);
1933
+ console.log(` ${c.dim}gpt-4o-mini${c.reset}`);
1934
+ console.log(` ${c.dim}gpt-4.1${c.reset}`);
1935
+ console.log(` ${c.dim}gpt-4.1-mini${c.reset}`);
1936
+ console.log(` ${c.dim}o3${c.reset}`);
1937
+ console.log(` ${c.dim}o4-mini${c.reset}`);
1938
+ console.log();
1939
+
1940
+ // OpenRouter — fetch from API
1941
+ console.log(` ${c.bold}OpenRouter${c.reset}${openrouterKey ? ` ${c.green}(configured)${c.reset}` : ` ${c.dim}(not configured)${c.reset}`}`);
1942
+ if (openrouterKey || targets.includes('--all')) {
1943
+ process.stdout.write(` ${c.dim}Fetching models...${c.reset}`);
1944
+ try {
1945
+ const res = await fetch('https://openrouter.ai/api/v1/models', {
1946
+ headers: openrouterKey ? { 'Authorization': `Bearer ${openrouterKey}` } : {},
1947
+ signal: AbortSignal.timeout(10_000),
1948
+ });
1949
+ const data = await res.json();
1950
+ const models = (data.data || [])
1951
+ .filter(m => m.id && !m.id.includes(':free') && !m.id.includes('/extended'))
1952
+ .sort((a, b) => (a.id || '').localeCompare(b.id || ''));
1953
+
1954
+ // Group by provider prefix
1955
+ const groups = {};
1956
+ for (const m of models) {
1957
+ const [prefix] = m.id.split('/');
1958
+ if (!groups[prefix]) groups[prefix] = [];
1959
+ groups[prefix].push(m);
1960
+ }
1961
+
1962
+ // Show popular ones first
1963
+ const popular = ['anthropic', 'openai', 'google', 'meta-llama', 'mistralai', 'deepseek'];
1964
+ const shown = new Set();
1965
+ process.stdout.write(`\r ${c.green}${models.length} models available${c.reset} \n`);
1966
+ console.log();
1967
+
1968
+ for (const prefix of popular) {
1969
+ if (!groups[prefix]) continue;
1970
+ shown.add(prefix);
1971
+ console.log(` ${c.bold}${prefix}${c.reset}`);
1972
+ for (const m of groups[prefix].slice(0, 5)) {
1973
+ console.log(` ${c.dim}${m.id}${c.reset}`);
1974
+ }
1975
+ if (groups[prefix].length > 5) {
1976
+ console.log(` ${c.dim}... and ${groups[prefix].length - 5} more${c.reset}`);
1977
+ }
1978
+ }
1979
+
1980
+ const otherCount = Object.keys(groups).filter(k => !shown.has(k)).length;
1981
+ if (otherCount > 0) {
1982
+ console.log();
1983
+ console.log(` ${c.dim}+ ${otherCount} more providers. Use --model=<provider/model>${c.reset}`);
1984
+ console.log(` ${c.dim}Full list: https://openrouter.ai/models${c.reset}`);
1985
+ }
1986
+ } catch (e) {
1987
+ process.stdout.write(`\r ${c.red}Failed to fetch: ${e.message}${c.reset} \n`);
1988
+ }
1989
+ } else {
1990
+ console.log(` ${c.dim}anthropic/claude-sonnet-4${c.reset} ${c.dim}(default)${c.reset}`);
1991
+ console.log(` ${c.dim}Set OPENROUTER_API_KEY to see all ${c.bold}200+${c.reset}${c.dim} models${c.reset}`);
1992
+ console.log(` ${c.dim}Or browse: https://openrouter.ai/models${c.reset}`);
1993
+ }
1994
+ console.log();
1995
+
1996
+ // Ollama
1997
+ const ollamaModel = process.env.OLLAMA_MODEL;
1998
+ const ollamaHost = process.env.OLLAMA_HOST || 'http://localhost:11434';
1999
+ console.log(` ${c.bold}Ollama${c.reset}${ollamaModel ? ` ${c.green}(configured: ${ollamaModel})${c.reset}` : ` ${c.dim}(not configured)${c.reset}`}`);
2000
+ if (ollamaModel || process.env.OLLAMA_HOST) {
2001
+ try {
2002
+ const res = await fetch(`${ollamaHost}/api/tags`, { signal: AbortSignal.timeout(5_000) });
2003
+ const data = await res.json();
2004
+ for (const m of (data.models || []).slice(0, 10)) {
2005
+ console.log(` ${c.dim}${m.name}${c.reset}`);
2006
+ }
2007
+ } catch {
2008
+ console.log(` ${c.dim}(Ollama not running at ${ollamaHost})${c.reset}`);
2009
+ }
2010
+ } else {
2011
+ console.log(` ${c.dim}Set OLLAMA_MODEL to use local models${c.reset}`);
2012
+ }
2013
+ console.log();
2014
+
2015
+ console.log(` ${c.bold}Set model:${c.reset}`);
2016
+ console.log(` ${c.cyan}agentaudit config set model <name>${c.reset}`);
2017
+ console.log(` ${c.cyan}agentaudit audit <url> --model <name>${c.reset}`);
2018
+ console.log(` ${c.dim}Or env: AGENTAUDIT_MODEL=<name>${c.reset}`);
2019
+ return;
2020
+ }
2021
+
1913
2022
  if (command === 'config') {
1914
2023
  const subCmd = targets[0];
1915
2024
  if (subCmd === 'set' && targets[1] === 'provider' && targets[2]) {
@@ -1961,8 +2070,9 @@ async function main() {
1961
2070
  return;
1962
2071
  }
1963
2072
  const results = [];
2073
+ const allowAutoAudit = command === 'check'; // only 'check' auto-audits, 'lookup' never does
1964
2074
  for (const t of names) {
1965
- const data = await checkPackage(t);
2075
+ const data = await checkPackage(t, { autoAudit: allowAutoAudit });
1966
2076
  results.push(data);
1967
2077
  }
1968
2078
  if (jsonMode) {
@@ -2033,7 +2143,7 @@ async function main() {
2033
2143
  }
2034
2144
 
2035
2145
  // Typo correction via Levenshtein distance
2036
- const knownCommands = ['discover', 'scan', 'audit', 'check', 'lookup', 'status', 'setup', 'config'];
2146
+ const knownCommands = ['discover', 'scan', 'audit', 'check', 'lookup', 'status', 'setup', 'config', 'models'];
2037
2147
  const suggestion = knownCommands
2038
2148
  .map(cmd => ({ cmd, dist: levenshtein(command, cmd) }))
2039
2149
  .filter(x => x.dist <= 3)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.9.21",
3
+ "version": "3.9.22",
4
4
  "description": "Security scanner for AI packages — MCP server + CLI",
5
5
  "type": "module",
6
6
  "bin": {