agentaudit 3.9.29 โ†’ 3.9.31

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 +45 -4
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -147,6 +147,29 @@ function saveCredentials(data) {
147
147
  }
148
148
 
149
149
  const USER_CONFIG_FILE = path.join(USER_CRED_DIR, 'config.json');
150
+ const USER_STATS_FILE = path.join(USER_CRED_DIR, 'stats-cache.json');
151
+
152
+ function loadStatsCache() {
153
+ try { return fs.existsSync(USER_STATS_FILE) ? JSON.parse(fs.readFileSync(USER_STATS_FILE, 'utf8')) : null; } catch { return null; }
154
+ }
155
+
156
+ function saveStatsCache(stats) {
157
+ try { fs.mkdirSync(USER_CRED_DIR, { recursive: true }); fs.writeFileSync(USER_STATS_FILE, JSON.stringify({ ...stats, _ts: Date.now() })); } catch {}
158
+ }
159
+
160
+ async function refreshStatsCache(agentName) {
161
+ try {
162
+ const lbRes = await fetch(`${REGISTRY_URL}/api/leaderboard`, { signal: AbortSignal.timeout(5000) });
163
+ if (!lbRes.ok) return null;
164
+ const agents = await lbRes.json();
165
+ const idx = Array.isArray(agents) ? agents.findIndex(a => (a.agent_name || '').toLowerCase() === agentName.toLowerCase()) : -1;
166
+ if (idx < 0) return null;
167
+ const me = agents[idx];
168
+ const stats = { rank: idx + 1, total: agents.length, pts: me.total_points || 0, reports: me.total_reports || 0, official: !!me.is_official };
169
+ saveStatsCache(stats);
170
+ return stats;
171
+ } catch { return null; }
172
+ }
150
173
 
151
174
  function loadConfig() {
152
175
  try {
@@ -330,6 +353,8 @@ async function setupCommand() {
330
353
  console.log(` ${icons.safe} Registered as ${c.bold}${data.agent_name}${c.reset}`);
331
354
  console.log(` ${c.dim}Key: ${data.api_key.slice(0, 12)}...${c.reset}`);
332
355
  console.log(` ${c.dim}Saved to: ${USER_CRED_FILE}${c.reset}`);
356
+ // Initialize stats cache
357
+ refreshStatsCache(data.agent_name).catch(() => {});
333
358
  } catch (err) {
334
359
  console.log(` ${c.red}failed${c.reset}`);
335
360
  console.log(` ${c.red}${err.message}${c.reset}`);
@@ -378,13 +403,25 @@ function getVersion() {
378
403
  } catch { return '0.0.0'; }
379
404
  }
380
405
 
381
- function banner() {
406
+ async function banner() {
382
407
  if (quietMode || jsonMode) return;
383
408
  const creds = loadCredentials();
384
409
  const agentInfo = creds?.agent_name ? ` ${c.dim}ยท${c.reset} ${c.green}${creds.agent_name}${c.reset}` : '';
385
410
  console.log();
386
411
  console.log(` ๐Ÿ›ก ${c.bold}${c.cyan}AgentAudit${c.reset} ${c.dim}v${getVersion()}${c.reset}${agentInfo}`);
387
- console.log(` ${c.dim}Security scanner for AI tools${c.reset}`);
412
+ if (creds?.agent_name) {
413
+ let cached = loadStatsCache();
414
+ // Auto-fetch if no cache or cache older than 1h
415
+ if (!cached || !cached._ts || (Date.now() - cached._ts > 3600000)) {
416
+ cached = await refreshStatsCache(creds.agent_name).catch(() => null) || cached;
417
+ }
418
+ if (cached && cached.rank) {
419
+ const medal = cached.rank === 1 ? '๐Ÿฅ‡' : cached.rank === 2 ? '๐Ÿฅˆ' : cached.rank === 3 ? '๐Ÿฅ‰' : `#${cached.rank}`;
420
+ console.log(` ${c.dim}${medal} of ${cached.total} ยท ${c.reset}${c.cyan}${cached.pts}${c.reset}${c.dim} pts ยท ${cached.reports} audits${c.reset}`);
421
+ }
422
+ } else {
423
+ console.log(` ${c.dim}Security scanner for AI tools${c.reset}`);
424
+ }
388
425
  console.log();
389
426
  }
390
427
 
@@ -1695,6 +1732,8 @@ async function auditRepo(url) {
1695
1732
  const reportSlug = data?.skill_slug || data?.slug || slug;
1696
1733
  console.log(` ${c.green}done${c.reset}`);
1697
1734
  console.log(` ${c.dim}Report: ${REGISTRY_URL}/skills/${reportSlug}${c.reset}`);
1735
+ // Refresh stats cache in background
1736
+ if (creds.agent_name) refreshStatsCache(creds.agent_name).catch(() => {});
1698
1737
  } else {
1699
1738
  console.log(` ${c.yellow}failed (HTTP ${res.status})${c.reset}`);
1700
1739
  }
@@ -1840,7 +1879,7 @@ async function main() {
1840
1879
  }
1841
1880
 
1842
1881
  if (args[0] === '--help' || args[0] === '-h') {
1843
- banner();
1882
+ await banner();
1844
1883
  console.log(` ${c.bold}USAGE${c.reset}`);
1845
1884
  console.log(` ${c.cyan}agentaudit${c.reset} <command> [options]`);
1846
1885
  console.log();
@@ -1888,7 +1927,7 @@ async function main() {
1888
1927
  const command = args.length === 0 ? 'discover' : args[0];
1889
1928
  const targets = args.slice(1);
1890
1929
 
1891
- banner();
1930
+ await banner();
1892
1931
 
1893
1932
  if (command === 'setup') {
1894
1933
  await setupCommand();
@@ -1996,6 +2035,8 @@ async function main() {
1996
2035
  console.log(` ${c.bold}Your Stats:${c.reset}`);
1997
2036
  console.log(` ${medal} Rank #${rank} of ${agents.length} ${c.dim}โ”‚${c.reset} ${c.cyan}${pts}${c.reset} points ${c.dim}โ”‚${c.reset} ${reports} reports`);
1998
2037
  if (me.is_official) console.log(` ${c.green}โœ” Official Auditor${c.reset}`);
2038
+ // Update stats cache
2039
+ saveStatsCache({ rank, total: agents.length, pts, reports, official: !!me.is_official });
1999
2040
  }
2000
2041
  }
2001
2042
  } catch {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.9.29",
3
+ "version": "3.9.31",
4
4
  "description": "Security scanner for AI packages โ€” MCP server + CLI",
5
5
  "type": "module",
6
6
  "bin": {