agentaudit 3.13.3 → 3.13.4

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 +95 -15
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -994,11 +994,16 @@ function fmtPct(n) {
994
994
 
995
995
  function dashboardBanner() {
996
996
  const ver = getVersion();
997
+ const inner = 35;
998
+ const line1 = ` \u25C6 AgentAudit v${ver}`;
999
+ const line2 = ` Security Registry for AI Agents`;
1000
+ const pad1 = Math.max(0, inner - line1.length);
1001
+ const pad2 = Math.max(0, inner - line2.length);
997
1002
  return [
998
- ` ${BOX.tl}${c.dim}${BOX.h.repeat(35)}${c.reset}${BOX.tr}`,
999
- ` ${BOX.v} ${c.bold}${c.cyan}◆ AgentAudit${c.reset} ${c.dim}v${ver}${c.reset}${' '.repeat(Math.max(0, 19 - ver.length))}${BOX.v}`,
1000
- ` ${BOX.v} ${c.dim}Security Registry for AI Agents${c.reset} ${BOX.v}`,
1001
- ` ${BOX.bl}${c.dim}${BOX.h.repeat(35)}${c.reset}${BOX.br}`,
1003
+ ` ${BOX.tl}${c.dim}${BOX.h.repeat(inner)}${c.reset}${BOX.tr}`,
1004
+ ` ${BOX.v}${c.bold}${c.cyan}${line1}${c.reset}${' '.repeat(pad1)}${BOX.v}`,
1005
+ ` ${BOX.v}${c.dim}${line2}${c.reset}${' '.repeat(pad2)}${BOX.v}`,
1006
+ ` ${BOX.bl}${c.dim}${BOX.h.repeat(inner)}${c.reset}${BOX.br}`,
1002
1007
  ];
1003
1008
  }
1004
1009
 
@@ -4239,7 +4244,14 @@ async function fetchDashboardData() {
4239
4244
  return { stats, leaderboard, benchmark, agent, creds };
4240
4245
  }
4241
4246
 
4242
- function renderOverviewTab(data, width) {
4247
+ const QUICK_ACTIONS = [
4248
+ { key: 'a', label: 'Audit', arg: '<url>', desc: 'Deep LLM security audit', cmd: 'audit' },
4249
+ { key: 'v', label: 'Audit --verify', arg: '<url>', desc: 'Audit + adversarial verification', cmd: 'audit-verify' },
4250
+ { key: 'r', label: 'Remote scan', arg: '<url>', desc: 'Server-side scan (no API key)', cmd: 'remote' },
4251
+ { key: 'c', label: 'Consensus', arg: '<pkg>', desc: 'Cross-model consensus view', cmd: 'consensus' },
4252
+ ];
4253
+
4254
+ function renderOverviewTab(data, width, quickActionIdx = -1) {
4243
4255
  const { stats, agent, leaderboard, creds } = data;
4244
4256
  const lines = [];
4245
4257
  const halfW = Math.min(Math.floor((width - 6) / 2), 40);
@@ -4330,14 +4342,17 @@ function renderOverviewTab(data, width) {
4330
4342
  lines.push(` ${c.dim}Local:${c.reset} ${histParts.join(` ${c.dim}│${c.reset} `)}`);
4331
4343
  }
4332
4344
 
4333
- // Quick actions
4345
+ // Quick actions (interactive)
4334
4346
  lines.push('');
4335
- lines.push(` ${c.bold}Quick Actions${c.reset}`);
4336
- lines.push(` ${c.cyan}agentaudit audit <url>${c.reset} ${c.dim}Deep LLM security audit${c.reset}`);
4337
- lines.push(` ${c.cyan}agentaudit audit <url> --verify${c.reset} ${c.dim}Audit + adversarial verification${c.reset}`);
4338
- lines.push(` ${c.cyan}agentaudit audit <url> --remote${c.reset} ${c.dim}Server-side scan (no API key)${c.reset}`);
4339
- lines.push(` ${c.cyan}agentaudit consensus <pkg>${c.reset} ${c.dim}Cross-model consensus view${c.reset}`);
4340
- lines.push(` ${c.cyan}agentaudit search <query>${c.reset} ${c.dim}Search the registry${c.reset}`);
4347
+ lines.push(` ${c.bold}Quick Actions${c.reset} ${c.dim}(press key or Enter to launch)${c.reset}`);
4348
+ for (let i = 0; i < QUICK_ACTIONS.length; i++) {
4349
+ const qa = QUICK_ACTIONS[i];
4350
+ const isSel = i === quickActionIdx;
4351
+ const pointer = isSel ? `${c.cyan}\u276F${c.reset}` : ' ';
4352
+ const keyBadge = `${c.dim}[${c.reset}${c.cyan}${qa.key}${c.reset}${c.dim}]${c.reset}`;
4353
+ const label = isSel ? `${c.bold}${c.cyan}${qa.label} ${qa.arg}${c.reset}` : `${qa.label} ${c.dim}${qa.arg}${c.reset}`;
4354
+ lines.push(` ${pointer} ${keyBadge} ${label} ${c.dim}${qa.desc}${c.reset}`);
4355
+ }
4341
4356
 
4342
4357
  return lines;
4343
4358
  }
@@ -4857,6 +4872,8 @@ async function dashboardCommand() {
4857
4872
  let activeTab = 0;
4858
4873
  let scrollOffset = 0;
4859
4874
  let running = true;
4875
+ let quickActionIdx = 0; // selected quick action on overview tab
4876
+ let pendingAction = null; // set when user triggers a quick action
4860
4877
 
4861
4878
  // Search tab state
4862
4879
  let searchQuery = '';
@@ -4922,7 +4939,7 @@ async function dashboardCommand() {
4922
4939
  let contentLines = [];
4923
4940
  switch (activeTab) {
4924
4941
  case 0:
4925
- contentLines = renderOverviewTab(data, cols);
4942
+ contentLines = renderOverviewTab(data, cols, quickActionIdx);
4926
4943
  break;
4927
4944
  case 1:
4928
4945
  contentLines = renderLeaderboardTab(data, cols);
@@ -4951,9 +4968,12 @@ async function dashboardCommand() {
4951
4968
  output += '\n';
4952
4969
  const scrollInfo = contentLines.length > availableRows ? ` ${c.dim}[${scrollOffset + 1}-${Math.min(scrollOffset + availableRows, contentLines.length)}/${contentLines.length}]${c.reset}` : '';
4953
4970
  const isSearchTab = activeTab === 4;
4971
+ const isOverviewTab = activeTab === 0;
4954
4972
  const footerHint = isSearchTab
4955
4973
  ? `${c.dim}\u2190\u2192 tab Enter=search Esc=clear q quit${c.reset}`
4956
- : `${c.dim}\u2190\u2192 tab \u2191\u2193 scroll 1-5 jump q quit${c.reset}`;
4974
+ : isOverviewTab
4975
+ ? `${c.dim}\u2190\u2192 tab \u2191\u2193 select Enter=launch a/v/r/c shortcut q quit${c.reset}`
4976
+ : `${c.dim}\u2190\u2192 tab \u2191\u2193 scroll 1-5 jump q quit${c.reset}`;
4957
4977
  output += ` ${footerHint}${scrollInfo}\n`;
4958
4978
 
4959
4979
  process.stdout.write(output);
@@ -5063,7 +5083,36 @@ async function dashboardCommand() {
5063
5083
  return;
5064
5084
  }
5065
5085
 
5066
- // Scroll
5086
+ // Overview tab: quick action navigation + launch
5087
+ if (activeTab === 0) {
5088
+ // ↑↓ / j/k move quick action cursor
5089
+ if (key === '\x1b[A' || key === 'k') {
5090
+ quickActionIdx = (quickActionIdx - 1 + QUICK_ACTIONS.length) % QUICK_ACTIONS.length;
5091
+ render();
5092
+ return;
5093
+ }
5094
+ if (key === '\x1b[B' || key === 'j') {
5095
+ quickActionIdx = (quickActionIdx + 1) % QUICK_ACTIONS.length;
5096
+ render();
5097
+ return;
5098
+ }
5099
+ // Enter: launch selected quick action
5100
+ if (key === '\r' || key === '\n') {
5101
+ pendingAction = QUICK_ACTIONS[quickActionIdx].cmd;
5102
+ cleanup();
5103
+ return;
5104
+ }
5105
+ // Letter shortcuts: a/v/r/c
5106
+ const qaMatch = QUICK_ACTIONS.find(qa => qa.key === key);
5107
+ if (qaMatch) {
5108
+ pendingAction = qaMatch.cmd;
5109
+ cleanup();
5110
+ return;
5111
+ }
5112
+ return;
5113
+ }
5114
+
5115
+ // Other tabs: scroll
5067
5116
  if (key === '\x1b[A' || key === 'k') { scrollOffset = Math.max(0, scrollOffset - 1); render(); return; }
5068
5117
  if (key === '\x1b[B' || key === 'j') { scrollOffset++; render(); return; }
5069
5118
  if (key === '\x1b[5~') { scrollOffset = Math.max(0, scrollOffset - 10); render(); return; }
@@ -5091,6 +5140,37 @@ async function dashboardCommand() {
5091
5140
  if (!running) { clearInterval(check); resolve(); }
5092
5141
  }, 100);
5093
5142
  });
5143
+
5144
+ // Handle pending quick action after dashboard exits
5145
+ if (pendingAction) {
5146
+ const qa = QUICK_ACTIONS.find(q => q.cmd === pendingAction);
5147
+ const promptLabel = qa?.arg === '<pkg>' ? 'Package name' : 'URL to audit';
5148
+ console.log();
5149
+ const input = await askQuestion(` ${c.cyan}${promptLabel}:${c.reset} `);
5150
+ if (!input) {
5151
+ console.log(` ${c.dim}Cancelled.${c.reset}`);
5152
+ return;
5153
+ }
5154
+ console.log();
5155
+ // Build argv and re-enter main()
5156
+ const newArgs = ['node', 'cli.mjs'];
5157
+ switch (pendingAction) {
5158
+ case 'audit':
5159
+ newArgs.push('audit', input);
5160
+ break;
5161
+ case 'audit-verify':
5162
+ newArgs.push('audit', input, '--verify', 'self');
5163
+ break;
5164
+ case 'remote':
5165
+ newArgs.push('audit', input, '--remote');
5166
+ break;
5167
+ case 'consensus':
5168
+ newArgs.push('consensus', input);
5169
+ break;
5170
+ }
5171
+ process.argv = newArgs;
5172
+ await main();
5173
+ }
5094
5174
  }
5095
5175
 
5096
5176
  // ── Main ────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentaudit",
3
- "version": "3.13.3",
3
+ "version": "3.13.4",
4
4
  "description": "Security scanner for AI agent packages — CLI + MCP server",
5
5
  "type": "module",
6
6
  "bin": {