@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.
@@ -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(`[*] Agent started: ${update.data.agent}`);
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(`[+] Agent complete: ${update.data.agent} (${update.data.issueCount} issues)`);
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.addActivity("Save report requested (not implemented in TUI)");
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 "-".repeat(width);
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 "[" + "#".repeat(width) + "]";
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
- return "[" + "#".repeat(filled) + ".".repeat(empty) + "]";
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
- const icons = {
3428
- critical: "[!]",
3429
- serious: "[x]",
3430
- moderate: "[~]",
3431
- low: "[-]"
3432
- };
3433
- return icons[severity] || "[-]";
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
- const icons = {
3440
- running: "*",
3441
- done: "+",
3442
- waiting: "o"
3443
- };
3444
- return icons[status];
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 = Math.min(80, process.stdout.columns || 80);
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
- let status = "SCANNING (...)";
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
- status = "SCAN COMPLETE [OK]";
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
- status = `${status} | ALERT: CRITICAL`;
3485
- }
3486
- console.log("+" + this.line(width - 2) + "+");
3487
- console.log("| TRIE GUARDIAN" + " ".repeat(width - 35 - status.length) + status + " " + time + " |");
3488
- console.log("+" + this.line(width - 2) + "+");
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
- console.log("|" + " ".repeat(width - 2) + "|");
3505
- console.log(`| Scanning: ${current.slice(0, 40).padEnd(40)}` + " ".repeat(width - 56) + "|");
3506
- console.log(`| ${progressBar} ${percent}% (${processedFiles}/${totalFiles} files)`.padEnd(width - 1) + "|");
3507
- console.log("|" + " ".repeat(width - 2) + "|");
3508
- console.log("+" + this.line(width - 2) + "+");
3509
- console.log("| AGENTS" + " ".repeat(width - 11) + "|");
3510
- console.log("| " + this.line(width - 6) + " |");
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 status = isActive ? "analyzing" : isDone ? `done (${this.getAgentIssueCount(agent)})` : "waiting";
3520
- const entry = `${icon} ${agent.slice(0, 12).padEnd(12)} ... ${status.padEnd(15)}`;
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`.padEnd(35);
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] || " ".repeat(35);
3538
- const right = rightAgents[i] || " ".repeat(35);
3539
- console.log(`| ${left} ${right}`.slice(0, width - 1).padEnd(width - 1) + "|");
3540
- }
3541
- console.log("|" + " ".repeat(width - 2) + "|");
3542
- console.log("+" + this.line(width - 2) + "+");
3543
- console.log("| ISSUES FOUND" + " ".repeat(width - 17) + "|");
3544
- console.log("| " + this.line(width - 6) + " |");
3545
- console.log(`| [!] Critical ${issuesBySeverity.critical.toString().padStart(4)} [~] Moderate ${issuesBySeverity.moderate.toString().padStart(5)}`.padEnd(width - 1) + "|");
3546
- console.log(`| [x] Serious ${issuesBySeverity.serious.toString().padStart(4)} [-] Low ${issuesBySeverity.low.toString().padStart(5)}`.padEnd(width - 1) + "|");
3547
- console.log("|" + " ".repeat(width - 2) + "|");
3548
- console.log("+" + this.line(width - 2) + "+");
3549
- console.log("| WATCH STATUS" + " ".repeat(width - 17) + "|");
3550
- console.log("| " + this.line(width - 6) + " |");
3551
- const watchLine = this.state.watch.watching ? `Watching ${this.state.watch.directories} dirs${this.state.watch.debounceMs ? ` \u2022 debounce ${this.state.watch.debounceMs}ms` : ""}` : "Watch idle";
3552
- console.log(`| ${watchLine}`.slice(0, width - 1).padEnd(width - 1) + "|");
3553
- const lastChange = this.state.watch.lastChange ? `Last change: ${this.state.watch.lastChange}` : "Last change: --";
3554
- console.log(`| ${lastChange}`.slice(0, width - 1).padEnd(width - 1) + "|");
3555
- const recentChange = this.state.watch.recentChanges[0]?.file ? `Recent: ${this.state.watch.recentChanges[0].file}` : "";
3556
- console.log(`| ${recentChange}`.slice(0, width - 1).padEnd(width - 1) + "|");
3557
- console.log("+" + this.line(width - 2) + "+");
3558
- console.log("| ACTIVITY LOG" + " ".repeat(width - 17) + "|");
3559
- console.log("| " + this.line(width - 6) + " |");
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 line = `${entry.time} ${entry.message}`.slice(0, width - 6);
3564
- console.log(`| ${line.padEnd(width - 4)}|`);
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
- console.log("|" + " ".repeat(width - 2) + "|");
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
- console.log("|" + " ".repeat(width - 2) + "|");
3585
- console.log(`| ${processedFiles} files scanned in ${elapsed}s`.padEnd(width - 1) + "|");
3586
- console.log(`| ${completedAgents.length} agents activated`.padEnd(width - 1) + "|");
3587
- console.log("|" + " ".repeat(width - 2) + "|");
3588
- console.log("+" + this.line(width - 2) + "+");
3589
- console.log("| SUMMARY" + " ".repeat(width - 12) + "|");
3590
- console.log("| " + this.line(width - 6) + " |");
3591
- const criticalLabel = issuesBySeverity.critical > 0 ? "<- FIX NOW" : "";
3592
- console.log(`| [!] ${issuesBySeverity.critical.toString().padStart(4)} Critical issues ${criticalLabel}`.padEnd(width - 1) + "|");
3593
- console.log(`| [x] ${issuesBySeverity.serious.toString().padStart(4)} Serious issues`.padEnd(width - 1) + "|");
3594
- console.log(`| [~] ${issuesBySeverity.moderate.toString().padStart(4)} Moderate issues`.padEnd(width - 1) + "|");
3595
- console.log(`| [-] ${issuesBySeverity.low.toString().padStart(4)} Low issues`.padEnd(width - 1) + "|");
3596
- console.log("|" + " ".repeat(width - 2) + "|");
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("+" + this.line(width - 2) + "+");
3600
- console.log("| TOP CRITICAL ISSUES" + " ".repeat(width - 24) + "|");
3601
- console.log("| " + this.line(width - 6) + " |");
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 line = issue.line ? `:${issue.line}` : "";
3605
- const location = `${filename}${line}`;
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
- console.log(`| > ${description}`.slice(0, width - 1).padEnd(width - 1) + "|");
3608
- console.log(`| ${location}`.slice(0, width - 1).padEnd(width - 1) + "|");
3609
- console.log("|" + " ".repeat(width - 2) + "|");
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("+" + this.line(width - 2) + "+");
3613
- console.log("| [OK] No issues found - code looks good!".padEnd(width - 1) + "|");
3614
- console.log("|" + " ".repeat(width - 2) + "|");
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("+" + this.line(width - 2) + "+");
3617
- console.log("| ACTIVITY LOG" + " ".repeat(width - 17) + "|");
3618
- console.log("| " + this.line(width - 6) + " |");
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 line = `${entry.time} ${entry.message}`.slice(0, width - 6);
3623
- console.log(`| ${line.padEnd(width - 4)}|`);
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
- console.log("|" + " ".repeat(width - 2) + "|");
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
- console.log("| Filter: " + this.getFilterDescription().padEnd(width - 13) + "|");
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 line = `${severityIcon} ${cursor} ${description.padEnd(38)} ${location.padEnd(20)}`;
3650
- console.log(`| ${line}`.slice(0, width - 1).padEnd(width - 1) + "|");
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
- console.log("|" + " ".repeat(width - 2) + "|");
3794
+ this.renderLine("", width);
3654
3795
  }
3655
3796
  if (filteredIssues[selectedIssue]) {
3656
3797
  const selected = filteredIssues[selectedIssue];
3657
- console.log("+" + this.line(width - 2) + "+");
3658
- console.log("| SELECTED: " + selected.issue.slice(0, width - 15).padEnd(width - 15) + "|");
3659
- console.log("| " + this.line(width - 6) + " |");
3660
- console.log(`| File: ${selected.file}`.slice(0, width - 1).padEnd(width - 1) + "|");
3661
- console.log(`| Line: ${selected.line || "Unknown"} Agent: ${selected.agent}`.padEnd(width - 1) + "|");
3662
- console.log("|" + " ".repeat(width - 2) + "|");
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
- console.log("| Fix:".padEnd(width - 1) + "|");
3805
+ this.renderLine(" " + colors.success("Fix:"), width);
3665
3806
  for (const line of fixLines.slice(0, 2)) {
3666
- console.log(`| ${line}`.padEnd(width - 1) + "|");
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 agentEntries = Object.entries(this.state.agents).map(([name, meta]) => {
3675
- return {
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
- console.log("| AGENTS STATUS" + " ".repeat(width - 18) + "|");
3702
- console.log("+" + this.line(width - 2) + "+");
3703
- console.log(`| Page ${this.state.agentPage + 1} / ${Math.max(1, Math.ceil(sorted.length / pageSize))}`.padEnd(width - 1) + "|");
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
- console.log("| No agents yet".padEnd(width - 1) + "|");
3826
+ this.renderLine(" " + colors.dim("No scouts yet"), width);
3706
3827
  return;
3707
3828
  }
3708
- console.log("| Name Status Issues Duration".padEnd(width - 1) + "|");
3709
- console.log("| " + this.line(width - 6) + " |");
3710
- for (const agent of slice) {
3711
- const statusIcon = agent.status === "running" ? "*" : agent.status === "done" ? "+" : "o";
3712
- const line = `| ${statusIcon} ${agent.name.padEnd(18)} ${agent.status.padEnd(9)} ${agent.issues.toString().padStart(6)} ${agent.duration.padEnd(8)}`;
3713
- console.log(line.slice(0, width - 1).padEnd(width - 1) + "|");
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
- console.log("| FILES WITH ISSUES" + " ".repeat(width - 22) + "|");
3729
- console.log("+" + this.line(width - 2) + "+");
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
- console.log(`| ${filename.padEnd(35)} ${totalCount} issues${criticalText}`.slice(0, width - 1).padEnd(width - 1) + "|");
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
- console.log("+" + this.line(width - 2) + "+");
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(" [q] Quit [Tab] Views [j/k] Nav [n/p] Pages [w] Watch [r] Rerun");
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(" [Tab] Views [j/k] Nav [n/p] Pages [1-4] Severity [f] Filter [w] Watch [r] Rerun [q] Quit");
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
- this.state.selectedIssue = Math.min(filteredIssues.length - 1, this.state.selectedIssue + 1);
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(`Agent: ${this.state.filter.agent}`);
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
- this.rl.question("Search filter (leave empty to clear): ", (answer) => {
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
- console.log("+" + this.line(66) + "+");
3858
- console.log("| TRIE GUARDIAN - HELP" + " ".repeat(44) + "|");
3859
- console.log("+" + this.line(66) + "+");
3860
- console.log("| Navigation" + " ".repeat(54) + "|");
3861
- console.log("| Tab Switch view (overview/issues/agents/files)" + " ".repeat(8) + "|");
3862
- console.log("| up/down Navigate issues list" + " ".repeat(29) + "|");
3863
- console.log("| Enter View issue details" + " ".repeat(31) + "|");
3864
- console.log("| Filters" + " ".repeat(57) + "|");
3865
- console.log("| 1-4 Filter by severity (critical->low)" + " ".repeat(16) + "|");
3866
- console.log("| 0 Clear severity filter" + " ".repeat(28) + "|");
3867
- console.log("| f Search filter" + " ".repeat(36) + "|");
3868
- console.log("| c Clear all filters" + " ".repeat(32) + "|");
3869
- console.log("| Other" + " ".repeat(59) + "|");
3870
- console.log("| h or ? Show this help" + " ".repeat(35) + "|");
3871
- console.log("| q Quit" + " ".repeat(45) + "|");
3872
- console.log("+" + this.line(66) + "+");
3873
- console.log(" Press any key to return...");
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
- console.log("+" + this.line(66) + "+");
3884
- console.log("| ISSUE DETAILS" + " ".repeat(51) + "|");
3885
- console.log("+" + this.line(66) + "+");
3886
- console.log(`| File: ${issue.file}`.slice(0, 66).padEnd(66) + "|");
3887
- console.log(`| Line: ${issue.line || "Unknown"} Agent: ${issue.agent}`.slice(0, 66).padEnd(66) + "|");
3888
- console.log("+" + this.line(66) + "+");
3889
- console.log("| Issue" + " ".repeat(59) + "|");
3890
- const issueLines = this.wrapText(issue.issue, 62);
3891
- for (const line of issueLines.slice(0, 4)) {
3892
- console.log(`| ${line}`.padEnd(66) + "|");
3893
- }
3894
- console.log("+" + this.line(66) + "+");
3895
- console.log("| Fix" + " ".repeat(61) + "|");
3896
- const fixLines = this.wrapText(issue.fix, 62);
3897
- for (const line of fixLines.slice(0, 4)) {
3898
- console.log(`| ${line}`.padEnd(66) + "|");
3899
- }
3900
- console.log("+" + this.line(66) + "+");
3901
- console.log(" Press any key to return...");
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 colors = {
4976
+ const colors2 = {
4656
4977
  urgent: "danger",
4657
4978
  high: "warning",
4658
4979
  medium: "good",
4659
4980
  low: "#36a64f"
4660
4981
  };
4661
- return colors[priority] ?? "good";
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-E2LWAVIW.js.map
6252
+ //# sourceMappingURL=chunk-JAVEBJF4.js.map