@triedotdev/mcp 1.0.56 → 1.0.58
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/README.md +1 -1
- package/dist/{chunk-E2LWAVIW.js → chunk-JAVEBJF4.js} +527 -203
- package/dist/chunk-JAVEBJF4.js.map +1 -0
- package/dist/cli/yolo-daemon.js +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-E2LWAVIW.js.map +0 -1
|
@@ -2753,6 +2753,8 @@ var StreamingManager = class {
|
|
|
2753
2753
|
this.emit("scan_complete", {
|
|
2754
2754
|
totalFiles: this.progress.totalFiles,
|
|
2755
2755
|
totalIssues: totalIssues.length,
|
|
2756
|
+
issues: totalIssues,
|
|
2757
|
+
// Include all issues for the dashboard
|
|
2756
2758
|
issuesBySeverity: this.progress.issuesBySeverity,
|
|
2757
2759
|
completedAgents: this.progress.completedAgents
|
|
2758
2760
|
});
|
|
@@ -2798,6 +2800,12 @@ var StreamingManager = class {
|
|
|
2798
2800
|
reportWatchChange(file) {
|
|
2799
2801
|
this.emit("watch_change", { file });
|
|
2800
2802
|
}
|
|
2803
|
+
/**
|
|
2804
|
+
* Report memory operations (saving context, learning patterns)
|
|
2805
|
+
*/
|
|
2806
|
+
reportMemory(action, details) {
|
|
2807
|
+
this.emit("memory", { action, details });
|
|
2808
|
+
}
|
|
2801
2809
|
};
|
|
2802
2810
|
function formatConsoleUpdate(update) {
|
|
2803
2811
|
if (isInteractiveMode()) {
|
|
@@ -3158,6 +3166,47 @@ var IssueAnalyzer = class {
|
|
|
3158
3166
|
// src/cli/interactive-dashboard.ts
|
|
3159
3167
|
import { stdin as input, stdout as output } from "process";
|
|
3160
3168
|
import * as readline from "readline";
|
|
3169
|
+
import pc from "picocolors";
|
|
3170
|
+
var colors = {
|
|
3171
|
+
// UI elements
|
|
3172
|
+
border: (s) => pc.cyan(s),
|
|
3173
|
+
header: (s) => pc.bold(pc.cyan(s)),
|
|
3174
|
+
brand: (s) => pc.bold(pc.cyan(s)),
|
|
3175
|
+
dim: (s) => pc.dim(s),
|
|
3176
|
+
// Severity levels
|
|
3177
|
+
critical: (s) => pc.bold(pc.red(s)),
|
|
3178
|
+
serious: (s) => pc.yellow(s),
|
|
3179
|
+
moderate: (s) => pc.blue(s),
|
|
3180
|
+
low: (s) => pc.dim(s),
|
|
3181
|
+
// Status
|
|
3182
|
+
success: (s) => pc.green(s),
|
|
3183
|
+
running: (s) => pc.yellow(s),
|
|
3184
|
+
waiting: (s) => pc.dim(s),
|
|
3185
|
+
alert: (s) => pc.bold(pc.red(s)),
|
|
3186
|
+
// Interactive
|
|
3187
|
+
selected: (s) => pc.bold(pc.magenta(s)),
|
|
3188
|
+
highlight: (s) => pc.bold(pc.white(s))
|
|
3189
|
+
};
|
|
3190
|
+
var stripAnsi = (s) => s.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
|
|
3191
|
+
var visibleLength = (s) => stripAnsi(s).length;
|
|
3192
|
+
var padEnd = (s, targetWidth) => {
|
|
3193
|
+
const visible = visibleLength(s);
|
|
3194
|
+
const padding = Math.max(0, targetWidth - visible);
|
|
3195
|
+
return s + " ".repeat(padding);
|
|
3196
|
+
};
|
|
3197
|
+
var box = {
|
|
3198
|
+
topLeft: "\u250C",
|
|
3199
|
+
topRight: "\u2510",
|
|
3200
|
+
bottomLeft: "\u2514",
|
|
3201
|
+
bottomRight: "\u2518",
|
|
3202
|
+
horizontal: "\u2500",
|
|
3203
|
+
vertical: "\u2502",
|
|
3204
|
+
leftT: "\u251C",
|
|
3205
|
+
rightT: "\u2524",
|
|
3206
|
+
topT: "\u252C",
|
|
3207
|
+
bottomT: "\u2534",
|
|
3208
|
+
cross: "\u253C"
|
|
3209
|
+
};
|
|
3161
3210
|
var InteractiveDashboard = class {
|
|
3162
3211
|
rl;
|
|
3163
3212
|
state;
|
|
@@ -3181,7 +3230,9 @@ var InteractiveDashboard = class {
|
|
|
3181
3230
|
search: ""
|
|
3182
3231
|
},
|
|
3183
3232
|
view: "overview",
|
|
3233
|
+
previousView: null,
|
|
3184
3234
|
selectedIssue: 0,
|
|
3235
|
+
selectedAgent: 0,
|
|
3185
3236
|
lastUpdate: Date.now(),
|
|
3186
3237
|
scanComplete: false,
|
|
3187
3238
|
startTime: Date.now(),
|
|
@@ -3247,7 +3298,7 @@ var InteractiveDashboard = class {
|
|
|
3247
3298
|
}
|
|
3248
3299
|
break;
|
|
3249
3300
|
case "agent_start":
|
|
3250
|
-
this.addActivity(`[*]
|
|
3301
|
+
this.addActivity(`[*] Scout started: ${update.data.agent}`);
|
|
3251
3302
|
this.state.agents[update.data.agent] = {
|
|
3252
3303
|
...this.state.agents[update.data.agent] || { issues: 0, status: "queued" },
|
|
3253
3304
|
status: "running",
|
|
@@ -3255,7 +3306,7 @@ var InteractiveDashboard = class {
|
|
|
3255
3306
|
};
|
|
3256
3307
|
break;
|
|
3257
3308
|
case "agent_complete":
|
|
3258
|
-
this.addActivity(`[+]
|
|
3309
|
+
this.addActivity(`[+] Scout complete: ${update.data.agent} (${update.data.issueCount} issues)`);
|
|
3259
3310
|
{
|
|
3260
3311
|
const prev = this.state.agents[update.data.agent];
|
|
3261
3312
|
const start = prev?.start;
|
|
@@ -3294,6 +3345,9 @@ var InteractiveDashboard = class {
|
|
|
3294
3345
|
...this.state.progress,
|
|
3295
3346
|
processedFiles: this.state.progress.totalFiles
|
|
3296
3347
|
};
|
|
3348
|
+
if (update.data.issues && Array.isArray(update.data.issues)) {
|
|
3349
|
+
this.state.issues = update.data.issues;
|
|
3350
|
+
}
|
|
3297
3351
|
const elapsed = ((Date.now() - this.state.startTime) / 1e3).toFixed(1);
|
|
3298
3352
|
this.addActivity(`=== Scan complete - ${this.state.progress.totalIssues} issues in ${elapsed}s ===`);
|
|
3299
3353
|
break;
|
|
@@ -3313,6 +3367,15 @@ var InteractiveDashboard = class {
|
|
|
3313
3367
|
this.state.watch.lastChange = entry.time;
|
|
3314
3368
|
this.addActivity(`Change detected: ${update.data.file}`);
|
|
3315
3369
|
break;
|
|
3370
|
+
case "memory":
|
|
3371
|
+
if (update.data.action === "saving") {
|
|
3372
|
+
this.addActivity(`[~] Saving to memory...`);
|
|
3373
|
+
} else if (update.data.action === "saved") {
|
|
3374
|
+
this.addActivity(`[+] Memory updated: ${update.data.details || "context saved"}`);
|
|
3375
|
+
} else if (update.data.action === "learning") {
|
|
3376
|
+
this.addActivity(`[~] Learning: ${update.data.details || "analyzing patterns"}`);
|
|
3377
|
+
}
|
|
3378
|
+
break;
|
|
3316
3379
|
}
|
|
3317
3380
|
if (this.isActive) {
|
|
3318
3381
|
this.render();
|
|
@@ -3376,15 +3439,11 @@ var InteractiveDashboard = class {
|
|
|
3376
3439
|
case "p":
|
|
3377
3440
|
this.prevPage();
|
|
3378
3441
|
break;
|
|
3379
|
-
case "r":
|
|
3380
|
-
this.addActivity("Rerun requested (press q to exit and rerun command)");
|
|
3381
|
-
break;
|
|
3382
|
-
case "w":
|
|
3383
|
-
this.state.watch.watching = !this.state.watch.watching;
|
|
3384
|
-
this.addActivity(this.state.watch.watching ? "Watch resumed" : "Watch paused (visual only)");
|
|
3385
|
-
break;
|
|
3386
3442
|
case "s":
|
|
3387
|
-
this.
|
|
3443
|
+
this.promptAgentFilter();
|
|
3444
|
+
break;
|
|
3445
|
+
case "b":
|
|
3446
|
+
this.goBack();
|
|
3388
3447
|
break;
|
|
3389
3448
|
case "h":
|
|
3390
3449
|
case "?":
|
|
@@ -3405,50 +3464,78 @@ var InteractiveDashboard = class {
|
|
|
3405
3464
|
}, 100);
|
|
3406
3465
|
}
|
|
3407
3466
|
/**
|
|
3408
|
-
* Create a horizontal line
|
|
3467
|
+
* Create a horizontal line (Unicode box-drawing)
|
|
3409
3468
|
*/
|
|
3410
3469
|
line(width = 78) {
|
|
3411
|
-
return
|
|
3470
|
+
return box.horizontal.repeat(width);
|
|
3412
3471
|
}
|
|
3413
3472
|
/**
|
|
3414
|
-
* Create progress bar
|
|
3473
|
+
* Create progress bar with color
|
|
3415
3474
|
*/
|
|
3416
3475
|
progressBar(current, total, width = 50) {
|
|
3417
|
-
if (total === 0) return "[" + "
|
|
3476
|
+
if (total === 0) return colors.dim("[" + "\u2588".repeat(width) + "]");
|
|
3418
3477
|
const progress = Math.min(1, current / total);
|
|
3419
3478
|
const filled = Math.round(width * progress);
|
|
3420
3479
|
const empty = width - filled;
|
|
3421
|
-
|
|
3480
|
+
const filledBar = colors.border("\u2588".repeat(filled));
|
|
3481
|
+
const emptyBar = colors.dim("\u2591".repeat(empty));
|
|
3482
|
+
return "[" + filledBar + emptyBar + "]";
|
|
3422
3483
|
}
|
|
3423
3484
|
/**
|
|
3424
|
-
* Get severity icon
|
|
3485
|
+
* Get severity icon with color
|
|
3425
3486
|
*/
|
|
3426
3487
|
severityIcon(severity) {
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3488
|
+
switch (severity) {
|
|
3489
|
+
case "critical":
|
|
3490
|
+
return colors.critical("[!]");
|
|
3491
|
+
case "serious":
|
|
3492
|
+
return colors.serious("[x]");
|
|
3493
|
+
case "moderate":
|
|
3494
|
+
return colors.moderate("[~]");
|
|
3495
|
+
case "low":
|
|
3496
|
+
return colors.low("[-]");
|
|
3497
|
+
default:
|
|
3498
|
+
return colors.dim("[-]");
|
|
3499
|
+
}
|
|
3434
3500
|
}
|
|
3435
3501
|
/**
|
|
3436
|
-
* Get agent status icon
|
|
3502
|
+
* Get agent status icon with color
|
|
3437
3503
|
*/
|
|
3438
3504
|
agentIcon(status) {
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3505
|
+
switch (status) {
|
|
3506
|
+
case "running":
|
|
3507
|
+
return colors.running("\u25CF");
|
|
3508
|
+
case "done":
|
|
3509
|
+
return colors.success("\u2713");
|
|
3510
|
+
case "waiting":
|
|
3511
|
+
return colors.waiting("\u25CB");
|
|
3512
|
+
default:
|
|
3513
|
+
return colors.dim("\u25CB");
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3516
|
+
/**
|
|
3517
|
+
* Render a line with proper padding (accounts for ANSI color codes)
|
|
3518
|
+
*/
|
|
3519
|
+
renderLine(content, width) {
|
|
3520
|
+
const v = colors.border(box.vertical);
|
|
3521
|
+
const innerWidth = width - 2;
|
|
3522
|
+
const contentLen = visibleLength(content);
|
|
3523
|
+
const padding = Math.max(0, innerWidth - contentLen);
|
|
3524
|
+
console.log(v + content + " ".repeat(padding) + v);
|
|
3525
|
+
}
|
|
3526
|
+
/**
|
|
3527
|
+
* Get responsive width based on terminal size
|
|
3528
|
+
*/
|
|
3529
|
+
getWidth() {
|
|
3530
|
+
const cols = process.stdout.columns || 80;
|
|
3531
|
+
return Math.max(60, Math.min(120, cols - 2));
|
|
3445
3532
|
}
|
|
3446
3533
|
/**
|
|
3447
3534
|
* Main render function
|
|
3448
3535
|
*/
|
|
3449
3536
|
render() {
|
|
3450
3537
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[H\x1B[?25l");
|
|
3451
|
-
const width =
|
|
3538
|
+
const width = this.getWidth();
|
|
3452
3539
|
const height = Math.max(24, process.stdout.rows || 40);
|
|
3453
3540
|
this.renderHeader(width);
|
|
3454
3541
|
if (!this.state.scanComplete) {
|
|
@@ -3475,17 +3562,30 @@ var InteractiveDashboard = class {
|
|
|
3475
3562
|
* Render header with title and status
|
|
3476
3563
|
*/
|
|
3477
3564
|
renderHeader(width) {
|
|
3478
|
-
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
3479
|
-
|
|
3565
|
+
const time = colors.dim((/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" }));
|
|
3566
|
+
const watchLabel = this.state.watch.watching ? colors.success("[WATCH ON]") : colors.dim("[WATCH OFF]");
|
|
3567
|
+
let statusText = "";
|
|
3480
3568
|
if (this.state.scanComplete) {
|
|
3481
|
-
|
|
3569
|
+
statusText = colors.success("COMPLETE") + " " + colors.success("[OK]");
|
|
3570
|
+
} else {
|
|
3571
|
+
statusText = colors.running("SCANNING") + " " + colors.dim("(...)");
|
|
3482
3572
|
}
|
|
3573
|
+
let alertText = "";
|
|
3483
3574
|
if (this.state.alerts.hasCritical) {
|
|
3484
|
-
|
|
3485
|
-
}
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3575
|
+
alertText = " " + colors.alert("\u2502 ALERT: CRITICAL");
|
|
3576
|
+
}
|
|
3577
|
+
const v = colors.border(box.vertical);
|
|
3578
|
+
const topBorder = colors.border(box.topLeft + this.line(width - 2) + box.topRight);
|
|
3579
|
+
const midBorder = colors.border(box.leftT + this.line(width - 2) + box.rightT);
|
|
3580
|
+
const brand = colors.brand("TRIE GUARDIAN");
|
|
3581
|
+
const rightContent = statusText + " " + watchLabel + alertText + " " + time;
|
|
3582
|
+
const innerWidth = width - 4;
|
|
3583
|
+
const brandLen = visibleLength(brand);
|
|
3584
|
+
const rightLen = visibleLength(rightContent);
|
|
3585
|
+
const gap = Math.max(2, innerWidth - brandLen - rightLen);
|
|
3586
|
+
console.log(topBorder);
|
|
3587
|
+
console.log(v + " " + brand + " ".repeat(gap) + rightContent + " " + v);
|
|
3588
|
+
console.log(midBorder);
|
|
3489
3589
|
}
|
|
3490
3590
|
/**
|
|
3491
3591
|
* Render scanning in progress view
|
|
@@ -3493,6 +3593,7 @@ var InteractiveDashboard = class {
|
|
|
3493
3593
|
renderScanningView(width, height) {
|
|
3494
3594
|
const { processedFiles, totalFiles, currentFile, activeAgents, completedAgents } = this.state.progress;
|
|
3495
3595
|
const { issuesBySeverity } = this.state.progress;
|
|
3596
|
+
const sectionBorder = colors.border(box.leftT + this.line(width - 2) + box.rightT);
|
|
3496
3597
|
const baseTotal = 21;
|
|
3497
3598
|
const variableBudget = Math.max(0, height - baseTotal);
|
|
3498
3599
|
const agentRows = Math.max(1, Math.min(4, Math.floor(variableBudget / 2)));
|
|
@@ -3501,13 +3602,13 @@ var InteractiveDashboard = class {
|
|
|
3501
3602
|
const percent = totalFiles > 0 ? Math.round(processedFiles / totalFiles * 100) : 0;
|
|
3502
3603
|
const current = currentFile ? currentFile.split("/").pop() || "" : "";
|
|
3503
3604
|
const progressBar = this.progressBar(processedFiles, totalFiles, 50);
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
console.log(
|
|
3509
|
-
|
|
3510
|
-
|
|
3605
|
+
this.renderLine("", width);
|
|
3606
|
+
this.renderLine(" " + colors.dim("Scanning:") + " " + colors.highlight(current.slice(0, 40)), width);
|
|
3607
|
+
this.renderLine(" " + progressBar + " " + colors.highlight(`${percent}%`) + " " + colors.dim(`(${processedFiles}/${totalFiles} files)`), width);
|
|
3608
|
+
this.renderLine("", width);
|
|
3609
|
+
console.log(sectionBorder);
|
|
3610
|
+
this.renderLine(" " + colors.header("SCOUTS"), width);
|
|
3611
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3511
3612
|
const allAgents = [.../* @__PURE__ */ new Set([...activeAgents, ...completedAgents])];
|
|
3512
3613
|
const waitingAgents = ["security", "privacy", "typecheck", "accessibility", "legal", "test", "moneybags", "production-ready"].filter((a) => !activeAgents.includes(a) && !completedAgents.includes(a));
|
|
3513
3614
|
const leftAgents = [];
|
|
@@ -3516,8 +3617,8 @@ var InteractiveDashboard = class {
|
|
|
3516
3617
|
const isActive = activeAgents.includes(agent);
|
|
3517
3618
|
const isDone = completedAgents.includes(agent);
|
|
3518
3619
|
const icon = isActive ? this.agentIcon("running") : isDone ? this.agentIcon("done") : this.agentIcon("waiting");
|
|
3519
|
-
const
|
|
3520
|
-
const entry = `${icon} ${agent.slice(0, 12).padEnd(12)}
|
|
3620
|
+
const statusText = isActive ? colors.running("analyzing") : isDone ? colors.success(`done (${this.getAgentIssueCount(agent)})`) : colors.waiting("waiting");
|
|
3621
|
+
const entry = `${icon} ${agent.slice(0, 12).padEnd(12)} ${colors.dim("...")} ${statusText}`;
|
|
3521
3622
|
if (i % 2 === 0) {
|
|
3522
3623
|
leftAgents.push(entry);
|
|
3523
3624
|
} else {
|
|
@@ -3525,7 +3626,7 @@ var InteractiveDashboard = class {
|
|
|
3525
3626
|
}
|
|
3526
3627
|
});
|
|
3527
3628
|
waitingAgents.slice(0, 4).forEach((agent, i) => {
|
|
3528
|
-
const entry = `${this.agentIcon("waiting")} ${agent.slice(0, 12).padEnd(12)} ... waiting
|
|
3629
|
+
const entry = `${this.agentIcon("waiting")} ${agent.slice(0, 12).padEnd(12)} ${colors.dim("...")} ${colors.waiting("waiting")}`;
|
|
3529
3630
|
if ((allAgents.length + i) % 2 === 0) {
|
|
3530
3631
|
leftAgents.push(entry);
|
|
3531
3632
|
} else {
|
|
@@ -3534,38 +3635,63 @@ var InteractiveDashboard = class {
|
|
|
3534
3635
|
});
|
|
3535
3636
|
const maxRows = Math.max(leftAgents.length, rightAgents.length, agentRows);
|
|
3536
3637
|
for (let i = 0; i < maxRows && i < agentRows; i++) {
|
|
3537
|
-
const left = leftAgents[i] || "
|
|
3538
|
-
const right = rightAgents[i] || "
|
|
3539
|
-
|
|
3540
|
-
}
|
|
3541
|
-
|
|
3542
|
-
console.log(
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
console.log(
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
const
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3638
|
+
const left = leftAgents[i] || "";
|
|
3639
|
+
const right = rightAgents[i] || "";
|
|
3640
|
+
this.renderLine(" " + padEnd(left, 35) + " " + right, width);
|
|
3641
|
+
}
|
|
3642
|
+
this.renderLine("", width);
|
|
3643
|
+
console.log(sectionBorder);
|
|
3644
|
+
this.renderLine(" " + colors.header("ISSUES FOUND"), width);
|
|
3645
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3646
|
+
const criticalLine = `${colors.critical("[!]")} ${colors.critical("Critical")} ${colors.critical(issuesBySeverity.critical.toString().padStart(4))}`;
|
|
3647
|
+
const moderateLine = `${colors.moderate("[~]")} ${colors.moderate("Moderate")} ${colors.moderate(issuesBySeverity.moderate.toString().padStart(5))}`;
|
|
3648
|
+
const seriousLine = `${colors.serious("[x]")} ${colors.serious("Serious")} ${colors.serious(issuesBySeverity.serious.toString().padStart(4))}`;
|
|
3649
|
+
const lowLine = `${colors.low("[-]")} ${colors.low("Low")} ${colors.low(issuesBySeverity.low.toString().padStart(5))}`;
|
|
3650
|
+
this.renderLine(" " + padEnd(criticalLine, 28) + moderateLine, width);
|
|
3651
|
+
this.renderLine(" " + padEnd(seriousLine, 28) + lowLine, width);
|
|
3652
|
+
this.renderLine("", width);
|
|
3653
|
+
console.log(sectionBorder);
|
|
3654
|
+
this.renderLine(" " + colors.header("WATCH STATUS"), width);
|
|
3655
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3656
|
+
const watchLine = this.state.watch.watching ? colors.success(`Watching ${this.state.watch.directories} dirs`) + colors.dim(this.state.watch.debounceMs ? ` \u2022 debounce ${this.state.watch.debounceMs}ms` : "") : colors.dim("Watch idle");
|
|
3657
|
+
this.renderLine(" " + watchLine, width);
|
|
3658
|
+
const lastChange = this.state.watch.lastChange ? colors.dim("Last change: ") + colors.highlight(this.state.watch.lastChange) : colors.dim("Last change: --");
|
|
3659
|
+
this.renderLine(" " + lastChange, width);
|
|
3660
|
+
const recentChange = this.state.watch.recentChanges[0]?.file ? colors.dim("Recent: ") + this.state.watch.recentChanges[0].file : "";
|
|
3661
|
+
this.renderLine(" " + recentChange, width);
|
|
3662
|
+
console.log(sectionBorder);
|
|
3663
|
+
this.renderLine(" " + colors.header("ACTIVITY LOG"), width);
|
|
3664
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3560
3665
|
const startIdx = this.state.activityPage * activityRows;
|
|
3561
3666
|
const recentActivity = this.state.activityLog.slice(startIdx, startIdx + activityRows);
|
|
3562
3667
|
for (const entry of recentActivity) {
|
|
3563
|
-
const
|
|
3564
|
-
|
|
3668
|
+
const logLine = colors.dim(entry.time) + " " + this.colorizeActivityMessage(entry.message);
|
|
3669
|
+
this.renderLine(" " + logLine, width);
|
|
3565
3670
|
}
|
|
3566
3671
|
for (let i = recentActivity.length; i < activityRows; i++) {
|
|
3567
|
-
|
|
3672
|
+
this.renderLine("", width);
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
/**
|
|
3676
|
+
* Colorize activity log messages based on content
|
|
3677
|
+
*/
|
|
3678
|
+
colorizeActivityMessage(message) {
|
|
3679
|
+
if (message.includes("[!]") || message.includes("CRITICAL")) {
|
|
3680
|
+
return colors.critical(message);
|
|
3681
|
+
}
|
|
3682
|
+
if (message.includes("[x]") || message.includes("SERIOUS")) {
|
|
3683
|
+
return colors.serious(message);
|
|
3568
3684
|
}
|
|
3685
|
+
if (message.includes("[+]") || message.includes("complete")) {
|
|
3686
|
+
return colors.success(message);
|
|
3687
|
+
}
|
|
3688
|
+
if (message.includes("[*]") || message.includes("started")) {
|
|
3689
|
+
return colors.running(message);
|
|
3690
|
+
}
|
|
3691
|
+
if (message.includes("===")) {
|
|
3692
|
+
return colors.header(message);
|
|
3693
|
+
}
|
|
3694
|
+
return message;
|
|
3569
3695
|
}
|
|
3570
3696
|
/**
|
|
3571
3697
|
* Get issue count for an agent
|
|
@@ -3581,49 +3707,50 @@ var InteractiveDashboard = class {
|
|
|
3581
3707
|
const { completedAgents } = this.state.progress;
|
|
3582
3708
|
const elapsed = ((Date.now() - this.state.startTime) / 1e3).toFixed(1);
|
|
3583
3709
|
const activityRows = Math.max(2, Math.min(8, Math.max(0, height - 26)));
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
console.log(
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3710
|
+
const sectionBorder = colors.border(box.leftT + this.line(width - 2) + box.rightT);
|
|
3711
|
+
this.renderLine("", width);
|
|
3712
|
+
this.renderLine(" " + colors.highlight(`${processedFiles}`) + colors.dim(` files scanned in ${elapsed}s`), width);
|
|
3713
|
+
this.renderLine(" " + colors.highlight(`${completedAgents.length}`) + colors.dim(" scouts activated"), width);
|
|
3714
|
+
this.renderLine("", width);
|
|
3715
|
+
console.log(sectionBorder);
|
|
3716
|
+
this.renderLine(" " + colors.header("SUMMARY"), width);
|
|
3717
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3718
|
+
const criticalLabel = issuesBySeverity.critical > 0 ? " " + colors.alert("<- FIX NOW") : "";
|
|
3719
|
+
this.renderLine(" " + colors.critical("[!]") + " " + colors.critical(issuesBySeverity.critical.toString().padStart(4)) + " " + colors.critical("Critical issues") + criticalLabel, width);
|
|
3720
|
+
this.renderLine(" " + colors.serious("[x]") + " " + colors.serious(issuesBySeverity.serious.toString().padStart(4)) + " " + colors.serious("Serious issues"), width);
|
|
3721
|
+
this.renderLine(" " + colors.moderate("[~]") + " " + colors.moderate(issuesBySeverity.moderate.toString().padStart(4)) + " " + colors.moderate("Moderate issues"), width);
|
|
3722
|
+
this.renderLine(" " + colors.low("[-]") + " " + colors.low(issuesBySeverity.low.toString().padStart(4)) + " " + colors.low("Low issues"), width);
|
|
3723
|
+
this.renderLine("", width);
|
|
3597
3724
|
const criticalIssues = this.state.issues.filter((i) => i.severity === "critical").slice(0, 3);
|
|
3598
3725
|
if (criticalIssues.length > 0) {
|
|
3599
|
-
console.log(
|
|
3600
|
-
|
|
3601
|
-
|
|
3726
|
+
console.log(sectionBorder);
|
|
3727
|
+
this.renderLine(" " + colors.critical("TOP CRITICAL ISSUES"), width);
|
|
3728
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3602
3729
|
for (const issue of criticalIssues) {
|
|
3603
3730
|
const filename = issue.file.split("/").pop() || issue.file;
|
|
3604
|
-
const
|
|
3605
|
-
const location = `${filename}${
|
|
3731
|
+
const lineNum = issue.line ? `:${issue.line}` : "";
|
|
3732
|
+
const location = `${filename}${lineNum}`;
|
|
3606
3733
|
const description = issue.issue.slice(0, 40) + (issue.issue.length > 40 ? "..." : "");
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3734
|
+
this.renderLine(" " + colors.critical("\u25B8") + " " + colors.critical(description), width);
|
|
3735
|
+
this.renderLine(" " + colors.dim(location), width);
|
|
3736
|
+
this.renderLine("", width);
|
|
3610
3737
|
}
|
|
3611
3738
|
} else if (totalIssues === 0) {
|
|
3612
|
-
console.log(
|
|
3613
|
-
|
|
3614
|
-
|
|
3739
|
+
console.log(sectionBorder);
|
|
3740
|
+
this.renderLine(" " + colors.success("\u2713 No issues found - code looks good!"), width);
|
|
3741
|
+
this.renderLine("", width);
|
|
3615
3742
|
}
|
|
3616
|
-
console.log(
|
|
3617
|
-
|
|
3618
|
-
|
|
3743
|
+
console.log(sectionBorder);
|
|
3744
|
+
this.renderLine(" " + colors.header("ACTIVITY LOG"), width);
|
|
3745
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3619
3746
|
const startIdx = this.state.activityPage * activityRows;
|
|
3620
3747
|
const recentActivity = this.state.activityLog.slice(startIdx, startIdx + activityRows);
|
|
3621
3748
|
for (const entry of recentActivity) {
|
|
3622
|
-
const
|
|
3623
|
-
|
|
3749
|
+
const logLine = colors.dim(entry.time) + " " + this.colorizeActivityMessage(entry.message);
|
|
3750
|
+
this.renderLine(" " + logLine, width);
|
|
3624
3751
|
}
|
|
3625
3752
|
for (let i = recentActivity.length; i < activityRows; i++) {
|
|
3626
|
-
|
|
3753
|
+
this.renderLine("", width);
|
|
3627
3754
|
}
|
|
3628
3755
|
}
|
|
3629
3756
|
/**
|
|
@@ -3632,38 +3759,52 @@ var InteractiveDashboard = class {
|
|
|
3632
3759
|
renderIssuesList(width) {
|
|
3633
3760
|
const filteredIssues = this.getFilteredIssues();
|
|
3634
3761
|
const { selectedIssue } = this.state;
|
|
3635
|
-
|
|
3636
|
-
console.log("+" + this.line(width - 2) + "+");
|
|
3762
|
+
const sectionBorder = colors.border(box.leftT + this.line(width - 2) + box.rightT);
|
|
3637
3763
|
const pageSize = 10;
|
|
3764
|
+
const currentPage = Math.floor(selectedIssue / pageSize) + 1;
|
|
3765
|
+
const totalPages = Math.max(1, Math.ceil(filteredIssues.length / pageSize));
|
|
3766
|
+
const pageInfo = colors.dim(`Page ${currentPage}/${totalPages}`) + " " + colors.highlight(`${filteredIssues.length}`) + colors.dim(" issues");
|
|
3767
|
+
this.renderLine(" " + colors.dim("Filter:") + " " + this.getFilterDescription() + " " + pageInfo, width);
|
|
3768
|
+
console.log(sectionBorder);
|
|
3638
3769
|
const startIndex = Math.floor(selectedIssue / pageSize) * pageSize;
|
|
3639
3770
|
const pageIssues = filteredIssues.slice(startIndex, startIndex + pageSize);
|
|
3771
|
+
if (filteredIssues.length === 0) {
|
|
3772
|
+
this.renderLine("", width);
|
|
3773
|
+
this.renderLine(" " + colors.dim("No issues match the current filter."), width);
|
|
3774
|
+
this.renderLine(" " + colors.dim("Press [c] to clear filters or [b] to go back."), width);
|
|
3775
|
+
this.renderLine("", width);
|
|
3776
|
+
for (let i = 0; i < pageSize - 4; i++) {
|
|
3777
|
+
this.renderLine("", width);
|
|
3778
|
+
}
|
|
3779
|
+
return;
|
|
3780
|
+
}
|
|
3640
3781
|
for (let i = 0; i < pageIssues.length; i++) {
|
|
3641
3782
|
const issue = pageIssues[i];
|
|
3642
3783
|
const globalIndex = startIndex + i;
|
|
3643
3784
|
const isSelected = globalIndex === selectedIssue;
|
|
3644
|
-
const cursor = isSelected ? "
|
|
3785
|
+
const cursor = isSelected ? colors.selected("\u25B8") : " ";
|
|
3645
3786
|
const severityIcon = this.severityIcon(issue.severity);
|
|
3646
3787
|
const filename = issue.file.split("/").pop() || issue.file;
|
|
3647
|
-
const location = `${filename}:${issue.line || "?"}
|
|
3788
|
+
const location = colors.dim(`${filename}:${issue.line || "?"}`);
|
|
3648
3789
|
const description = issue.issue.slice(0, 35) + (issue.issue.length > 35 ? "..." : "");
|
|
3649
|
-
const
|
|
3650
|
-
|
|
3790
|
+
const descText = isSelected ? colors.selected(description) : description;
|
|
3791
|
+
this.renderLine(" " + severityIcon + " " + cursor + " " + padEnd(descText, 40) + location, width);
|
|
3651
3792
|
}
|
|
3652
3793
|
for (let i = pageIssues.length; i < pageSize; i++) {
|
|
3653
|
-
|
|
3794
|
+
this.renderLine("", width);
|
|
3654
3795
|
}
|
|
3655
3796
|
if (filteredIssues[selectedIssue]) {
|
|
3656
3797
|
const selected = filteredIssues[selectedIssue];
|
|
3657
|
-
console.log(
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3798
|
+
console.log(sectionBorder);
|
|
3799
|
+
this.renderLine(" " + colors.header("SELECTED:") + " " + colors.highlight(selected.issue.slice(0, width - 20)), width);
|
|
3800
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3801
|
+
this.renderLine(" " + colors.dim("File:") + " " + selected.file.slice(0, width - 15), width);
|
|
3802
|
+
this.renderLine(" " + colors.dim("Line:") + " " + (selected.line || "Unknown") + " " + colors.dim("Scout:") + " " + selected.agent, width);
|
|
3803
|
+
this.renderLine("", width);
|
|
3663
3804
|
const fixLines = this.wrapText(selected.fix, width - 8);
|
|
3664
|
-
|
|
3805
|
+
this.renderLine(" " + colors.success("Fix:"), width);
|
|
3665
3806
|
for (const line of fixLines.slice(0, 2)) {
|
|
3666
|
-
|
|
3807
|
+
this.renderLine(" " + colors.success(line), width);
|
|
3667
3808
|
}
|
|
3668
3809
|
}
|
|
3669
3810
|
}
|
|
@@ -3671,52 +3812,55 @@ var InteractiveDashboard = class {
|
|
|
3671
3812
|
* Render agents view
|
|
3672
3813
|
*/
|
|
3673
3814
|
renderAgentsView(width) {
|
|
3674
|
-
const
|
|
3675
|
-
|
|
3676
|
-
name,
|
|
3677
|
-
status: meta.status,
|
|
3678
|
-
duration: meta.durationMs ? `${(meta.durationMs / 1e3).toFixed(1)}s` : "\u2014",
|
|
3679
|
-
issues: meta.issues ?? 0,
|
|
3680
|
-
start: meta.start,
|
|
3681
|
-
end: meta.end
|
|
3682
|
-
};
|
|
3683
|
-
});
|
|
3684
|
-
for (const name of this.state.progress.activeAgents) {
|
|
3685
|
-
if (!this.state.agents[name]) {
|
|
3686
|
-
agentEntries.push({ name, status: "running", duration: "\u2014", issues: 0, start: void 0, end: void 0 });
|
|
3687
|
-
}
|
|
3688
|
-
}
|
|
3689
|
-
for (const name of this.state.progress.completedAgents) {
|
|
3690
|
-
if (!this.state.agents[name]) {
|
|
3691
|
-
agentEntries.push({ name, status: "done", duration: "\u2014", issues: this.getAgentIssueCount(name), start: void 0, end: void 0 });
|
|
3692
|
-
}
|
|
3693
|
-
}
|
|
3694
|
-
const order = { running: 0, queued: 1, done: 2 };
|
|
3695
|
-
const sorted = agentEntries.sort((a, b) => {
|
|
3696
|
-
return order[a.status] - order[b.status] || a.name.localeCompare(b.name);
|
|
3697
|
-
});
|
|
3815
|
+
const sectionBorder = colors.border(box.leftT + this.line(width - 2) + box.rightT);
|
|
3816
|
+
const sorted = this.getSortedAgents();
|
|
3698
3817
|
const pageSize = 6;
|
|
3699
3818
|
const startIdx = this.state.agentPage * pageSize;
|
|
3700
3819
|
const slice = sorted.slice(startIdx, startIdx + pageSize);
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3820
|
+
const totalPages = Math.max(1, Math.ceil(sorted.length / pageSize));
|
|
3821
|
+
const pageHint = totalPages > 1 ? " " + colors.highlight(`[n/p]`) + colors.dim(" more pages") : "";
|
|
3822
|
+
this.renderLine(" " + colors.header("SCOUT STATUS") + " " + colors.dim("(j/k navigate, Enter view issues)"), width);
|
|
3823
|
+
console.log(sectionBorder);
|
|
3824
|
+
this.renderLine(" " + colors.highlight(`${sorted.length}`) + colors.dim(" scouts") + " " + colors.dim(`Page ${this.state.agentPage + 1}/${totalPages}`) + pageHint, width);
|
|
3704
3825
|
if (slice.length === 0) {
|
|
3705
|
-
|
|
3826
|
+
this.renderLine(" " + colors.dim("No scouts yet"), width);
|
|
3706
3827
|
return;
|
|
3707
3828
|
}
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
for (
|
|
3711
|
-
const
|
|
3712
|
-
|
|
3713
|
-
|
|
3829
|
+
this.renderLine(" " + colors.dim("Name Status Issues Duration"), width);
|
|
3830
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3831
|
+
for (let i = 0; i < slice.length; i++) {
|
|
3832
|
+
const agent = slice[i];
|
|
3833
|
+
if (!agent) continue;
|
|
3834
|
+
const globalIdx = startIdx + i;
|
|
3835
|
+
const isSelected = globalIdx === this.state.selectedAgent;
|
|
3836
|
+
const cursor = isSelected ? colors.selected("\u25B8") : " ";
|
|
3837
|
+
const statusIcon = agent.status === "running" ? this.agentIcon("running") : agent.status === "done" ? this.agentIcon("done") : this.agentIcon("waiting");
|
|
3838
|
+
const statusText = agent.status === "running" ? colors.running(agent.status.padEnd(9)) : agent.status === "done" ? colors.success(agent.status.padEnd(9)) : colors.waiting(agent.status.padEnd(9));
|
|
3839
|
+
const issueCount = agent.issues > 0 ? colors.serious(agent.issues.toString().padStart(6)) : colors.dim(agent.issues.toString().padStart(6));
|
|
3840
|
+
const duration = colors.dim(agent.duration.padEnd(8));
|
|
3841
|
+
const nameText = isSelected ? colors.selected(agent.name.padEnd(18)) : agent.name.padEnd(18);
|
|
3842
|
+
this.renderLine(" " + cursor + " " + statusIcon + " " + nameText + " " + statusText + " " + issueCount + " " + duration, width);
|
|
3843
|
+
}
|
|
3844
|
+
for (let i = slice.length; i < pageSize; i++) {
|
|
3845
|
+
this.renderLine("", width);
|
|
3846
|
+
}
|
|
3847
|
+
const selected = sorted[this.state.selectedAgent];
|
|
3848
|
+
if (selected) {
|
|
3849
|
+
const agentIssues = this.state.issues.filter((i) => i.agent === selected.name);
|
|
3850
|
+
const criticals = agentIssues.filter((i) => i.severity === "critical").length;
|
|
3851
|
+
const serious = agentIssues.filter((i) => i.severity === "serious").length;
|
|
3852
|
+
console.log(sectionBorder);
|
|
3853
|
+
this.renderLine(" " + colors.header("SELECTED:") + " " + colors.highlight(selected.name), width);
|
|
3854
|
+
this.renderLine(" " + colors.dim(this.line(width - 6)), width);
|
|
3855
|
+
this.renderLine(" " + colors.dim("Issues:") + " " + colors.highlight(agentIssues.length.toString()) + " total (" + colors.critical(`[!] ${criticals} critical`) + ", " + colors.serious(`[x] ${serious} serious`) + ")", width);
|
|
3856
|
+
this.renderLine(" " + colors.dim("Press Enter to view all issues from this scout"), width);
|
|
3714
3857
|
}
|
|
3715
3858
|
}
|
|
3716
3859
|
/**
|
|
3717
3860
|
* Render files view
|
|
3718
3861
|
*/
|
|
3719
3862
|
renderFilesView(width) {
|
|
3863
|
+
const sectionBorder = colors.border(box.leftT + this.line(width - 2) + box.rightT);
|
|
3720
3864
|
const fileIssues = /* @__PURE__ */ new Map();
|
|
3721
3865
|
for (const issue of this.state.issues) {
|
|
3722
3866
|
if (!fileIssues.has(issue.file)) {
|
|
@@ -3725,25 +3869,38 @@ var InteractiveDashboard = class {
|
|
|
3725
3869
|
fileIssues.get(issue.file).push(issue);
|
|
3726
3870
|
}
|
|
3727
3871
|
const sortedFiles = Array.from(fileIssues.entries()).sort((a, b) => b[1].length - a[1].length).slice(0, 15);
|
|
3728
|
-
|
|
3729
|
-
console.log(
|
|
3872
|
+
this.renderLine(" " + colors.header("FILES WITH ISSUES"), width);
|
|
3873
|
+
console.log(sectionBorder);
|
|
3730
3874
|
for (const [file, issues] of sortedFiles) {
|
|
3731
3875
|
const filename = file.split("/").pop() || file;
|
|
3732
3876
|
const criticalCount = issues.filter((i) => i.severity === "critical").length;
|
|
3733
3877
|
const totalCount = issues.length;
|
|
3734
|
-
const criticalText = criticalCount > 0 ? ` (${criticalCount} critical)` : "";
|
|
3735
|
-
|
|
3878
|
+
const criticalText = criticalCount > 0 ? colors.critical(` (${criticalCount} critical)`) : "";
|
|
3879
|
+
const countText = criticalCount > 0 ? colors.serious(`${totalCount} issues`) : colors.dim(`${totalCount} issues`);
|
|
3880
|
+
this.renderLine(" " + filename.padEnd(35) + " " + countText + criticalText, width);
|
|
3881
|
+
}
|
|
3882
|
+
for (let i = sortedFiles.length; i < 10; i++) {
|
|
3883
|
+
this.renderLine("", width);
|
|
3736
3884
|
}
|
|
3737
3885
|
}
|
|
3738
3886
|
/**
|
|
3739
3887
|
* Render footer with controls
|
|
3740
3888
|
*/
|
|
3741
3889
|
renderFooter(width) {
|
|
3742
|
-
|
|
3890
|
+
const bottomBorder = colors.border(box.bottomLeft + this.line(width - 2) + box.bottomRight);
|
|
3891
|
+
console.log(bottomBorder);
|
|
3892
|
+
const key = (k) => colors.border("[") + colors.highlight(k) + colors.border("]");
|
|
3893
|
+
const hint = (k, desc) => key(k) + colors.dim(` ${desc}`);
|
|
3743
3894
|
if (!this.state.scanComplete) {
|
|
3744
|
-
console.log("
|
|
3895
|
+
console.log(" " + hint("q", "Quit") + " " + hint("?", "Help"));
|
|
3896
|
+
} else if (this.state.view === "agents") {
|
|
3897
|
+
console.log(" " + hint("j/k", "Select") + " " + hint("Enter", "View issues") + " " + hint("n/p", "Pages") + " " + hint("Tab", "Views") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
|
|
3898
|
+
} else if (this.state.view === "issues" && this.state.previousView === "agents") {
|
|
3899
|
+
console.log(" " + hint("b", "Back") + " " + hint("j/k", "Nav") + " " + hint("Enter", "Details") + " " + hint("1-4", "Severity") + " " + hint("f", "Search") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
|
|
3900
|
+
} else if (this.state.view === "issues") {
|
|
3901
|
+
console.log(" " + hint("j/k", "Nav") + " " + hint("Enter", "Details") + " " + hint("1-4", "Severity") + " " + hint("f", "Search") + " " + hint("s", "Scout") + " " + hint("c", "Clear") + " " + hint("Tab", "Views") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
|
|
3745
3902
|
} else {
|
|
3746
|
-
console.log("
|
|
3903
|
+
console.log(" " + hint("Tab", "Views") + " " + hint("n/p", "Pages") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
|
|
3747
3904
|
}
|
|
3748
3905
|
}
|
|
3749
3906
|
// Helper methods
|
|
@@ -3757,13 +3914,49 @@ var InteractiveDashboard = class {
|
|
|
3757
3914
|
navigateUp() {
|
|
3758
3915
|
if (this.state.view === "issues") {
|
|
3759
3916
|
this.state.selectedIssue = Math.max(0, this.state.selectedIssue - 1);
|
|
3917
|
+
} else if (this.state.view === "agents") {
|
|
3918
|
+
this.state.selectedAgent = Math.max(0, this.state.selectedAgent - 1);
|
|
3919
|
+
const pageSize = 6;
|
|
3920
|
+
const page = Math.floor(this.state.selectedAgent / pageSize);
|
|
3921
|
+
if (page !== this.state.agentPage) {
|
|
3922
|
+
this.state.agentPage = page;
|
|
3923
|
+
}
|
|
3760
3924
|
}
|
|
3761
3925
|
}
|
|
3762
3926
|
navigateDown() {
|
|
3763
3927
|
if (this.state.view === "issues") {
|
|
3764
3928
|
const filteredIssues = this.getFilteredIssues();
|
|
3765
|
-
|
|
3929
|
+
if (filteredIssues.length > 0) {
|
|
3930
|
+
this.state.selectedIssue = Math.min(filteredIssues.length - 1, this.state.selectedIssue + 1);
|
|
3931
|
+
}
|
|
3932
|
+
} else if (this.state.view === "agents") {
|
|
3933
|
+
const agents = this.getSortedAgents();
|
|
3934
|
+
this.state.selectedAgent = Math.min(agents.length - 1, this.state.selectedAgent + 1);
|
|
3935
|
+
const pageSize = 6;
|
|
3936
|
+
const page = Math.floor(this.state.selectedAgent / pageSize);
|
|
3937
|
+
if (page !== this.state.agentPage) {
|
|
3938
|
+
this.state.agentPage = page;
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
getSortedAgents() {
|
|
3943
|
+
const agentEntries = [];
|
|
3944
|
+
for (const [name, data] of Object.entries(this.state.agents)) {
|
|
3945
|
+
const duration = data.durationMs ? `${(data.durationMs / 1e3).toFixed(1)}s` : "\u2014";
|
|
3946
|
+
agentEntries.push({ name, status: data.status, issues: data.issues, duration });
|
|
3947
|
+
}
|
|
3948
|
+
for (const name of this.state.progress.activeAgents) {
|
|
3949
|
+
if (!this.state.agents[name]) {
|
|
3950
|
+
agentEntries.push({ name, status: "running", issues: 0, duration: "\u2014" });
|
|
3951
|
+
}
|
|
3766
3952
|
}
|
|
3953
|
+
for (const name of this.state.progress.completedAgents) {
|
|
3954
|
+
if (!this.state.agents[name]) {
|
|
3955
|
+
agentEntries.push({ name, status: "done", issues: this.getAgentIssueCount(name), duration: "\u2014" });
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
const order = { running: 0, queued: 1, done: 2 };
|
|
3959
|
+
return agentEntries.sort((a, b) => (order[a.status] ?? 2) - (order[b.status] ?? 2) || a.name.localeCompare(b.name));
|
|
3767
3960
|
}
|
|
3768
3961
|
nextPage() {
|
|
3769
3962
|
if (this.state.view === "agents") {
|
|
@@ -3788,6 +3981,24 @@ var InteractiveDashboard = class {
|
|
|
3788
3981
|
if (selected) {
|
|
3789
3982
|
this.showIssueDetails(selected);
|
|
3790
3983
|
}
|
|
3984
|
+
} else if (this.state.view === "agents") {
|
|
3985
|
+
const agents = this.getSortedAgents();
|
|
3986
|
+
const selected = agents[this.state.selectedAgent];
|
|
3987
|
+
if (selected) {
|
|
3988
|
+
this.state.previousView = "agents";
|
|
3989
|
+
this.state.filter.agent = selected.name;
|
|
3990
|
+
this.state.selectedIssue = 0;
|
|
3991
|
+
this.state.view = "issues";
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
goBack() {
|
|
3996
|
+
if (this.state.previousView) {
|
|
3997
|
+
if (this.state.previousView === "agents" && this.state.filter.agent !== "all") {
|
|
3998
|
+
this.state.filter.agent = "all";
|
|
3999
|
+
}
|
|
4000
|
+
this.state.view = this.state.previousView;
|
|
4001
|
+
this.state.previousView = null;
|
|
3791
4002
|
}
|
|
3792
4003
|
}
|
|
3793
4004
|
setFilter(type, value) {
|
|
@@ -3819,7 +4030,7 @@ var InteractiveDashboard = class {
|
|
|
3819
4030
|
getFilterDescription() {
|
|
3820
4031
|
const parts = [];
|
|
3821
4032
|
if (this.state.filter.severity !== "all") parts.push(`Severity: ${this.state.filter.severity}`);
|
|
3822
|
-
if (this.state.filter.agent !== "all") parts.push(`
|
|
4033
|
+
if (this.state.filter.agent !== "all") parts.push(`Scout: ${this.state.filter.agent}`);
|
|
3823
4034
|
if (this.state.filter.search) parts.push(`Search: "${this.state.filter.search}"`);
|
|
3824
4035
|
return parts.length > 0 ? parts.join(", ") : "All issues";
|
|
3825
4036
|
}
|
|
@@ -3839,38 +4050,124 @@ var InteractiveDashboard = class {
|
|
|
3839
4050
|
return lines;
|
|
3840
4051
|
}
|
|
3841
4052
|
async promptFilter() {
|
|
4053
|
+
if (this.updateInterval) {
|
|
4054
|
+
clearInterval(this.updateInterval);
|
|
4055
|
+
this.updateInterval = void 0;
|
|
4056
|
+
}
|
|
3842
4057
|
if (input.isTTY) {
|
|
3843
4058
|
input.setRawMode(false);
|
|
3844
4059
|
}
|
|
3845
|
-
|
|
4060
|
+
const v = colors.border(box.vertical);
|
|
4061
|
+
const w = Math.max(50, Math.min(70, (process.stdout.columns || 80) - 4));
|
|
4062
|
+
const pLine = (content) => {
|
|
4063
|
+
const len = visibleLength(content);
|
|
4064
|
+
console.log(v + content + " ".repeat(Math.max(0, w - 2 - len)) + v);
|
|
4065
|
+
};
|
|
4066
|
+
process.stdout.write("\x1B[2J\x1B[H\x1B[?25h");
|
|
4067
|
+
console.log(colors.border(box.topLeft + this.line(w - 2) + box.topRight));
|
|
4068
|
+
pLine(" " + colors.header("FILTER ISSUES"));
|
|
4069
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4070
|
+
pLine(" " + colors.dim("Current filters:"));
|
|
4071
|
+
pLine(" " + colors.dim("Severity:") + " " + colors.highlight(this.state.filter.severity));
|
|
4072
|
+
pLine(" " + colors.dim("Scout:") + " " + colors.highlight(this.state.filter.agent));
|
|
4073
|
+
pLine(" " + colors.dim("Search:") + " " + colors.highlight(this.state.filter.search || "(none)"));
|
|
4074
|
+
console.log(colors.border(box.bottomLeft + this.line(w - 2) + box.bottomRight));
|
|
4075
|
+
console.log("");
|
|
4076
|
+
this.rl.question(colors.border("\u25B8 ") + "Enter search term (empty to clear): ", (answer) => {
|
|
3846
4077
|
this.state.filter.search = answer.trim();
|
|
3847
4078
|
this.state.selectedIssue = 0;
|
|
3848
4079
|
if (input.isTTY) {
|
|
3849
4080
|
input.setRawMode(true);
|
|
3850
4081
|
}
|
|
4082
|
+
this.startUpdateLoop();
|
|
4083
|
+
this.render();
|
|
4084
|
+
});
|
|
4085
|
+
}
|
|
4086
|
+
async promptAgentFilter() {
|
|
4087
|
+
if (this.updateInterval) {
|
|
4088
|
+
clearInterval(this.updateInterval);
|
|
4089
|
+
this.updateInterval = void 0;
|
|
4090
|
+
}
|
|
4091
|
+
if (input.isTTY) {
|
|
4092
|
+
input.setRawMode(false);
|
|
4093
|
+
}
|
|
4094
|
+
const agents = [.../* @__PURE__ */ new Set([
|
|
4095
|
+
...this.state.progress.completedAgents,
|
|
4096
|
+
...this.state.progress.activeAgents,
|
|
4097
|
+
...Object.keys(this.state.agents)
|
|
4098
|
+
])].sort();
|
|
4099
|
+
const v = colors.border(box.vertical);
|
|
4100
|
+
const w = Math.max(50, Math.min(70, (process.stdout.columns || 80) - 4));
|
|
4101
|
+
const pLine = (content) => {
|
|
4102
|
+
const len = visibleLength(content);
|
|
4103
|
+
console.log(v + content + " ".repeat(Math.max(0, w - 2 - len)) + v);
|
|
4104
|
+
};
|
|
4105
|
+
process.stdout.write("\x1B[2J\x1B[H\x1B[?25h");
|
|
4106
|
+
console.log(colors.border(box.topLeft + this.line(w - 2) + box.topRight));
|
|
4107
|
+
pLine(" " + colors.header("FILTER BY SCOUT"));
|
|
4108
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4109
|
+
pLine(" " + colors.dim("Current scout filter:") + " " + colors.highlight(this.state.filter.agent));
|
|
4110
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4111
|
+
pLine(" " + colors.dim("Available scouts:"));
|
|
4112
|
+
const maxScouts = w > 60 ? 12 : 8;
|
|
4113
|
+
for (const agent of agents.slice(0, maxScouts)) {
|
|
4114
|
+
pLine(" " + colors.success("\u2022") + " " + agent);
|
|
4115
|
+
}
|
|
4116
|
+
if (agents.length > maxScouts) {
|
|
4117
|
+
pLine(" " + colors.dim(`... and ${agents.length - maxScouts} more`));
|
|
4118
|
+
}
|
|
4119
|
+
console.log(colors.border(box.bottomLeft + this.line(w - 2) + box.bottomRight));
|
|
4120
|
+
console.log("");
|
|
4121
|
+
this.rl.question(colors.border("\u25B8 ") + "Enter scout name (empty for all): ", (answer) => {
|
|
4122
|
+
const trimmed = answer.trim();
|
|
4123
|
+
if (trimmed === "" || trimmed.toLowerCase() === "all") {
|
|
4124
|
+
this.state.filter.agent = "all";
|
|
4125
|
+
} else {
|
|
4126
|
+
const match = agents.find((a) => a.toLowerCase().includes(trimmed.toLowerCase()));
|
|
4127
|
+
this.state.filter.agent = match || trimmed;
|
|
4128
|
+
}
|
|
4129
|
+
this.state.selectedIssue = 0;
|
|
4130
|
+
if (input.isTTY) {
|
|
4131
|
+
input.setRawMode(true);
|
|
4132
|
+
}
|
|
4133
|
+
this.startUpdateLoop();
|
|
3851
4134
|
this.render();
|
|
3852
4135
|
});
|
|
3853
4136
|
}
|
|
3854
4137
|
showHelp() {
|
|
3855
4138
|
this.isActive = false;
|
|
3856
4139
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
console.log(
|
|
3867
|
-
|
|
3868
|
-
console.log(
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
4140
|
+
const v = colors.border(box.vertical);
|
|
4141
|
+
const w = Math.max(60, Math.min(80, (process.stdout.columns || 80) - 4));
|
|
4142
|
+
const pLine = (content) => {
|
|
4143
|
+
const len = visibleLength(content);
|
|
4144
|
+
console.log(v + content + " ".repeat(Math.max(0, w - 2 - len)) + v);
|
|
4145
|
+
};
|
|
4146
|
+
const keyLine = (key, desc) => {
|
|
4147
|
+
pLine(" " + colors.highlight(key.padEnd(10)) + " " + colors.dim(desc));
|
|
4148
|
+
};
|
|
4149
|
+
console.log(colors.border(box.topLeft + this.line(w - 2) + box.topRight));
|
|
4150
|
+
pLine(" " + colors.brand("TRIE GUARDIAN") + " " + colors.dim("-") + " " + colors.header("HELP"));
|
|
4151
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4152
|
+
pLine(" " + colors.header("Navigation"));
|
|
4153
|
+
keyLine("Tab", "Switch view (overview/issues/scouts/files)");
|
|
4154
|
+
keyLine("j/k", "Navigate up/down in lists");
|
|
4155
|
+
keyLine("n/p", "Next/previous page");
|
|
4156
|
+
keyLine("Enter", "View details / drill into scout");
|
|
4157
|
+
keyLine("b", "Go back (after drilling into scout)");
|
|
4158
|
+
pLine("");
|
|
4159
|
+
pLine(" " + colors.header("Filters"));
|
|
4160
|
+
keyLine("1-4", "Filter by severity (1=critical, 4=low)");
|
|
4161
|
+
keyLine("0", "Show all severities");
|
|
4162
|
+
keyLine("f", "Search issues by text");
|
|
4163
|
+
keyLine("s", "Filter by scout name");
|
|
4164
|
+
keyLine("c", "Clear all filters");
|
|
4165
|
+
pLine("");
|
|
4166
|
+
pLine(" " + colors.header("Other"));
|
|
4167
|
+
keyLine("h or ?", "Show this help");
|
|
4168
|
+
keyLine("q or Esc", "Quit");
|
|
4169
|
+
console.log(colors.border(box.bottomLeft + this.line(w - 2) + box.bottomRight));
|
|
4170
|
+
console.log(" " + colors.dim("Press any key to return..."));
|
|
3874
4171
|
const resume = () => {
|
|
3875
4172
|
this.isActive = true;
|
|
3876
4173
|
this.render();
|
|
@@ -3880,25 +4177,49 @@ var InteractiveDashboard = class {
|
|
|
3880
4177
|
showIssueDetails(issue) {
|
|
3881
4178
|
this.isActive = false;
|
|
3882
4179
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
4180
|
+
const v = colors.border(box.vertical);
|
|
4181
|
+
const w = Math.max(60, Math.min(100, (process.stdout.columns || 80) - 4));
|
|
4182
|
+
const severityColor = issue.severity === "critical" ? colors.critical : issue.severity === "serious" ? colors.serious : issue.severity === "moderate" ? colors.moderate : colors.low;
|
|
4183
|
+
const pLine = (content) => {
|
|
4184
|
+
const len = visibleLength(content);
|
|
4185
|
+
console.log(v + content + " ".repeat(Math.max(0, w - 2 - len)) + v);
|
|
4186
|
+
};
|
|
4187
|
+
console.log(colors.border(box.topLeft + this.line(w - 2) + box.topRight));
|
|
4188
|
+
pLine(" " + colors.header("ISSUE DETAILS") + " " + severityColor(`[${issue.severity.toUpperCase()}]`));
|
|
4189
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4190
|
+
const maxFileLen = w - 12;
|
|
4191
|
+
const filePath = issue.file.length > maxFileLen ? "..." + issue.file.slice(-(maxFileLen - 3)) : issue.file;
|
|
4192
|
+
pLine(" " + colors.dim("File:") + " " + filePath);
|
|
4193
|
+
pLine(" " + colors.dim("Line:") + " " + (issue.line || "Unknown") + " " + colors.dim("Scout:") + " " + issue.agent);
|
|
4194
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4195
|
+
pLine(" " + colors.header("Issue"));
|
|
4196
|
+
const maxIssueLines = w > 80 ? 8 : 5;
|
|
4197
|
+
const issueLines = this.wrapText(issue.issue, w - 10);
|
|
4198
|
+
for (const line of issueLines.slice(0, maxIssueLines)) {
|
|
4199
|
+
pLine(" " + severityColor(line));
|
|
4200
|
+
}
|
|
4201
|
+
if (issueLines.length > maxIssueLines) {
|
|
4202
|
+
pLine(" " + colors.dim(`... ${issueLines.length - maxIssueLines} more lines`));
|
|
4203
|
+
}
|
|
4204
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4205
|
+
pLine(" " + colors.success("Suggested Fix"));
|
|
4206
|
+
const maxFixLines = w > 80 ? 8 : 5;
|
|
4207
|
+
const fixLines = this.wrapText(issue.fix, w - 10);
|
|
4208
|
+
for (const line of fixLines.slice(0, maxFixLines)) {
|
|
4209
|
+
pLine(" " + colors.success(line));
|
|
4210
|
+
}
|
|
4211
|
+
if (fixLines.length > maxFixLines) {
|
|
4212
|
+
pLine(" " + colors.dim(`... ${fixLines.length - maxFixLines} more lines`));
|
|
4213
|
+
}
|
|
4214
|
+
if (issue.cwe || issue.owasp || issue.effort) {
|
|
4215
|
+
console.log(colors.border(box.leftT + this.line(w - 2) + box.rightT));
|
|
4216
|
+
pLine(" " + colors.header("Metadata"));
|
|
4217
|
+
if (issue.cwe) pLine(" " + colors.dim("CWE:") + " " + issue.cwe);
|
|
4218
|
+
if (issue.owasp) pLine(" " + colors.dim("OWASP:") + " " + issue.owasp);
|
|
4219
|
+
if (issue.effort) pLine(" " + colors.dim("Effort:") + " " + issue.effort);
|
|
4220
|
+
}
|
|
4221
|
+
console.log(colors.border(box.bottomLeft + this.line(w - 2) + box.bottomRight));
|
|
4222
|
+
console.log(" " + colors.dim("Press any key to return..."));
|
|
3902
4223
|
const resume = () => {
|
|
3903
4224
|
this.isActive = true;
|
|
3904
4225
|
this.render();
|
|
@@ -4652,13 +4973,13 @@ ${overdueAssignments.length} issues are overdue and require attention.`
|
|
|
4652
4973
|
* Get color for assignment priority
|
|
4653
4974
|
*/
|
|
4654
4975
|
getAssignmentColor(priority) {
|
|
4655
|
-
const
|
|
4976
|
+
const colors2 = {
|
|
4656
4977
|
urgent: "danger",
|
|
4657
4978
|
high: "warning",
|
|
4658
4979
|
medium: "good",
|
|
4659
4980
|
low: "#36a64f"
|
|
4660
4981
|
};
|
|
4661
|
-
return
|
|
4982
|
+
return colors2[priority] ?? "good";
|
|
4662
4983
|
}
|
|
4663
4984
|
/**
|
|
4664
4985
|
* Test Slack connection
|
|
@@ -5452,6 +5773,7 @@ var TrieScanTool = class {
|
|
|
5452
5773
|
await writeFile2(args.output, JSON.stringify(report, null, 2));
|
|
5453
5774
|
}
|
|
5454
5775
|
try {
|
|
5776
|
+
streamingManager?.reportMemory("saving", "scan results");
|
|
5455
5777
|
const contextSignals = {
|
|
5456
5778
|
touchesAuth: context.touchesAuth ?? false,
|
|
5457
5779
|
touchesPayments: context.touchesPayments ?? false,
|
|
@@ -5477,8 +5799,10 @@ var TrieScanTool = class {
|
|
|
5477
5799
|
}
|
|
5478
5800
|
}
|
|
5479
5801
|
await updateAgentLedger(workDir, agentResults, this.agentRegistry, userConfig);
|
|
5802
|
+
streamingManager?.reportMemory("saved", `${agentResults.length} scouts, ${allIssues.length} findings`);
|
|
5480
5803
|
} catch {
|
|
5481
5804
|
}
|
|
5805
|
+
streamingManager?.completeScan(allIssues);
|
|
5482
5806
|
return {
|
|
5483
5807
|
content: [
|
|
5484
5808
|
{
|
|
@@ -5925,4 +6249,4 @@ export {
|
|
|
5925
6249
|
InteractiveDashboard,
|
|
5926
6250
|
TrieScanTool
|
|
5927
6251
|
};
|
|
5928
|
-
//# sourceMappingURL=chunk-
|
|
6252
|
+
//# sourceMappingURL=chunk-JAVEBJF4.js.map
|