agentaudit 3.13.1 → 3.13.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.
- package/cli.mjs +72 -9
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -852,17 +852,45 @@ function padLeft(str, len) {
|
|
|
852
852
|
return diff > 0 ? ' '.repeat(diff) + str : str;
|
|
853
853
|
}
|
|
854
854
|
|
|
855
|
+
// Truncate a string with ANSI codes to maxLen visible characters
|
|
856
|
+
function truncateAnsi(str, maxLen) {
|
|
857
|
+
if (maxLen <= 0) return '';
|
|
858
|
+
let vis = 0;
|
|
859
|
+
let result = '';
|
|
860
|
+
let i = 0;
|
|
861
|
+
while (i < str.length) {
|
|
862
|
+
if (str[i] === '\x1b') {
|
|
863
|
+
const m = str.slice(i).match(/^\x1b\[[0-9;]*[a-zA-Z]/);
|
|
864
|
+
if (m) { result += m[0]; i += m[0].length; continue; }
|
|
865
|
+
}
|
|
866
|
+
if (vis >= maxLen) break;
|
|
867
|
+
result += str[i];
|
|
868
|
+
vis++;
|
|
869
|
+
i++;
|
|
870
|
+
}
|
|
871
|
+
return result + c.reset;
|
|
872
|
+
}
|
|
873
|
+
|
|
855
874
|
function drawBox(title, contentLines, width) {
|
|
856
875
|
const inner = width - 4; // 2 for "│ " + 2 for " │"
|
|
857
876
|
const totalDash = inner + 2; // total horizontal line chars between corners
|
|
858
877
|
const lines = [];
|
|
859
|
-
|
|
860
|
-
|
|
878
|
+
let titleStr = title ? ` ${title} ` : '';
|
|
879
|
+
let titleLen = visLen(titleStr);
|
|
880
|
+
// Clamp title if wider than available border space
|
|
881
|
+
if (titleLen >= totalDash - 1) {
|
|
882
|
+
const maxTitle = Math.max(1, totalDash - 4);
|
|
883
|
+
titleStr = ` ${title.slice(0, maxTitle)}… `;
|
|
884
|
+
titleLen = visLen(titleStr);
|
|
885
|
+
}
|
|
861
886
|
// Top: ╭─ Title ────────────╮ (1 dash before title + title + remaining dashes)
|
|
862
|
-
const topDash = BOX.h.repeat(Math.max(
|
|
887
|
+
const topDash = BOX.h.repeat(Math.max(0, totalDash - 1 - titleLen));
|
|
863
888
|
lines.push(` ${BOX.tl}${c.dim}${BOX.h}${c.reset}${c.bold}${titleStr}${c.reset}${c.dim}${topDash}${c.reset}${BOX.tr}`);
|
|
864
889
|
for (const line of contentLines) {
|
|
865
|
-
|
|
890
|
+
// Truncate content that exceeds box inner width
|
|
891
|
+
const vl = visLen(line);
|
|
892
|
+
const display = vl > inner ? truncateAnsi(line, inner - 1) + '…' : line;
|
|
893
|
+
lines.push(` ${BOX.v} ${padRight(display, inner + 1)}${BOX.v}`);
|
|
866
894
|
}
|
|
867
895
|
lines.push(` ${BOX.bl}${c.dim}${BOX.h.repeat(totalDash)}${c.reset}${BOX.br}`);
|
|
868
896
|
return lines;
|
|
@@ -4220,7 +4248,10 @@ function renderOverviewTab(data, width) {
|
|
|
4220
4248
|
const idx = leaderboard.findIndex(e => e.agent_name === creds.agent_name);
|
|
4221
4249
|
if (idx >= 0) rank = `#${idx + 1} of ${leaderboard.length}`;
|
|
4222
4250
|
}
|
|
4223
|
-
|
|
4251
|
+
const nameVis = visLen(creds.agent_name);
|
|
4252
|
+
const rankVis = visLen(rank);
|
|
4253
|
+
const nameGap = Math.max(1, halfW - nameVis - rankVis);
|
|
4254
|
+
profileLines.push(`${c.bold}${creds.agent_name}${c.reset}${' '.repeat(nameGap)}${c.dim}${rank}${c.reset}`);
|
|
4224
4255
|
profileLines.push(`Points ${c.bold}${fmtNum(agent.total_points)}${c.reset}`);
|
|
4225
4256
|
profileLines.push(`Audits ${c.bold}${fmtNum(agent.total_reports)}${c.reset}`);
|
|
4226
4257
|
profileLines.push(`Findings ${c.bold}${fmtNum(agent.total_findings_submitted)}${c.reset} ${c.dim}(${fmtNum(agent.total_findings_confirmed)} confirmed)${c.reset}`);
|
|
@@ -4255,6 +4286,15 @@ function renderOverviewTab(data, width) {
|
|
|
4255
4286
|
regLines.push(`${c.dim}Could not load registry stats${c.reset}`);
|
|
4256
4287
|
}
|
|
4257
4288
|
|
|
4289
|
+
// Local history stats
|
|
4290
|
+
const localHistory = loadHistory(50);
|
|
4291
|
+
const verifiedCount = localHistory.filter(h => h.verification).length;
|
|
4292
|
+
const localStats = {
|
|
4293
|
+
total: localHistory.length,
|
|
4294
|
+
verified: verifiedCount,
|
|
4295
|
+
lastAudit: localHistory[0] ? timeAgo(localHistory[0].timestamp || localHistory[0].date) : null,
|
|
4296
|
+
};
|
|
4297
|
+
|
|
4258
4298
|
const boxW = halfW + 4;
|
|
4259
4299
|
const profileBox = drawBox('Your Profile', profileLines, boxW);
|
|
4260
4300
|
const registryBox = drawBox('Registry', regLines, boxW);
|
|
@@ -4262,8 +4302,13 @@ function renderOverviewTab(data, width) {
|
|
|
4262
4302
|
// Side by side if wide enough, stacked otherwise
|
|
4263
4303
|
if (width >= boxW * 2 + 4) {
|
|
4264
4304
|
const maxLen = Math.max(profileBox.length, registryBox.length);
|
|
4265
|
-
|
|
4266
|
-
while (
|
|
4305
|
+
// Insert filler lines BEFORE the bottom border (last line), not after
|
|
4306
|
+
while (profileBox.length < maxLen) {
|
|
4307
|
+
profileBox.splice(profileBox.length - 1, 0, ` ${BOX.v} ${' '.repeat(halfW + 1)}${BOX.v}`);
|
|
4308
|
+
}
|
|
4309
|
+
while (registryBox.length < maxLen) {
|
|
4310
|
+
registryBox.splice(registryBox.length - 1, 0, ` ${BOX.v} ${' '.repeat(halfW + 1)}${BOX.v}`);
|
|
4311
|
+
}
|
|
4267
4312
|
for (let i = 0; i < maxLen; i++) {
|
|
4268
4313
|
lines.push(profileBox[i] + ' ' + registryBox[i].trimStart());
|
|
4269
4314
|
}
|
|
@@ -4271,6 +4316,24 @@ function renderOverviewTab(data, width) {
|
|
|
4271
4316
|
lines.push(...profileBox, '', ...registryBox);
|
|
4272
4317
|
}
|
|
4273
4318
|
|
|
4319
|
+
// Local history section
|
|
4320
|
+
lines.push('');
|
|
4321
|
+
if (localStats.total > 0) {
|
|
4322
|
+
const histParts = [`${c.bold}${localStats.total}${c.reset} local audits`];
|
|
4323
|
+
if (localStats.verified > 0) histParts.push(`${c.green}${localStats.verified} verified${c.reset}`);
|
|
4324
|
+
if (localStats.lastAudit) histParts.push(`${c.dim}last: ${localStats.lastAudit}${c.reset}`);
|
|
4325
|
+
lines.push(` ${c.dim}Local:${c.reset} ${histParts.join(` ${c.dim}│${c.reset} `)}`);
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4328
|
+
// Quick actions
|
|
4329
|
+
lines.push('');
|
|
4330
|
+
lines.push(` ${c.bold}Quick Actions${c.reset}`);
|
|
4331
|
+
lines.push(` ${c.cyan}agentaudit audit <url>${c.reset} ${c.dim}Deep LLM security audit${c.reset}`);
|
|
4332
|
+
lines.push(` ${c.cyan}agentaudit audit <url> --verify${c.reset} ${c.dim}Audit + adversarial verification${c.reset}`);
|
|
4333
|
+
lines.push(` ${c.cyan}agentaudit audit <url> --remote${c.reset} ${c.dim}Server-side scan (no API key)${c.reset}`);
|
|
4334
|
+
lines.push(` ${c.cyan}agentaudit consensus <pkg>${c.reset} ${c.dim}Cross-model consensus view${c.reset}`);
|
|
4335
|
+
lines.push(` ${c.cyan}agentaudit search <query>${c.reset} ${c.dim}Search the registry${c.reset}`);
|
|
4336
|
+
|
|
4274
4337
|
return lines;
|
|
4275
4338
|
}
|
|
4276
4339
|
|
|
@@ -4292,7 +4355,7 @@ function renderLeaderboardTab(data, width, opts = {}) {
|
|
|
4292
4355
|
const entry = leaderboard[i];
|
|
4293
4356
|
const name = (entry.agent_name || '').slice(0, maxNameW);
|
|
4294
4357
|
const isMe = creds && entry.agent_name === creds.agent_name;
|
|
4295
|
-
const prefix = i < 3 ? `
|
|
4358
|
+
const prefix = i < 3 ? ` ${medals[i]} ` : ` ${c.dim}#${String(i + 1).padStart(2)}${c.reset} `;
|
|
4296
4359
|
const nameStr = isMe ? `${c.green}${c.bold}${name}${c.reset}` : name;
|
|
4297
4360
|
const bar = renderBar(entry.total_points || 0, maxPts, barW);
|
|
4298
4361
|
const pts = padLeft(`${fmtNum(entry.total_points || 0)} pts`, 12);
|
|
@@ -4724,7 +4787,7 @@ async function leaderboardCommand(args) {
|
|
|
4724
4787
|
const entry = data[i];
|
|
4725
4788
|
const name = (entry.agent_name || '').slice(0, 20);
|
|
4726
4789
|
const isMe = creds && entry.agent_name === creds.agent_name;
|
|
4727
|
-
const prefix = i < 3 ? `
|
|
4790
|
+
const prefix = i < 3 ? ` ${medals[i]} ` : ` ${c.dim}#${String(i + 1).padStart(2)}${c.reset} `;
|
|
4728
4791
|
const nameStr = isMe ? `${c.green}${c.bold}${name}${c.reset}` : name;
|
|
4729
4792
|
const bar = renderBar(entry.total_points || 0, maxPts, barW);
|
|
4730
4793
|
const pts = `${fmtNum(entry.total_points || 0)} pts`;
|