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.
- package/cli.mjs +95 -15
- 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(
|
|
999
|
-
` ${BOX.v}
|
|
1000
|
-
` ${BOX.v}
|
|
1001
|
-
` ${BOX.bl}${c.dim}${BOX.h.repeat(
|
|
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
|
-
|
|
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
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
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
|
-
:
|
|
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
|
-
//
|
|
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 ────────────────────────────────────────────────
|