@triedotdev/mcp 1.0.58 → 1.0.59

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.
@@ -3188,7 +3188,25 @@ var colors = {
3188
3188
  highlight: (s) => pc.bold(pc.white(s))
3189
3189
  };
3190
3190
  var stripAnsi = (s) => s.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
3191
- var visibleLength = (s) => stripAnsi(s).length;
3191
+ var visibleLength = (s) => {
3192
+ const plain = stripAnsi(s);
3193
+ let width = 0;
3194
+ for (const char of plain) {
3195
+ const code = char.codePointAt(0) || 0;
3196
+ if (code >= 127744 && code <= 129535 || // Emoji
3197
+ code >= 9728 && code <= 9983 || // Misc symbols
3198
+ code >= 9984 && code <= 10175 || // Dingbats
3199
+ code >= 65024 && code <= 65039 || // Variation selectors
3200
+ code >= 126976 && code <= 131071 || // Extended emoji
3201
+ code >= 12288 && code <= 40959 || // CJK
3202
+ code >= 44032 && code <= 55215) {
3203
+ width += 2;
3204
+ } else {
3205
+ width += 1;
3206
+ }
3207
+ }
3208
+ return width;
3209
+ };
3192
3210
  var padEnd = (s, targetWidth) => {
3193
3211
  const visible = visibleLength(s);
3194
3212
  const padding = Math.max(0, targetWidth - visible);
@@ -3207,11 +3225,18 @@ var box = {
3207
3225
  bottomT: "\u2534",
3208
3226
  cross: "\u253C"
3209
3227
  };
3228
+ var WATCH_FRAMES = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
3229
+ var SCAN_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3210
3230
  var InteractiveDashboard = class {
3211
3231
  rl;
3212
3232
  state;
3213
3233
  isActive = false;
3214
3234
  updateInterval;
3235
+ // Double-buffering to prevent flicker
3236
+ buffer = [];
3237
+ lastFrame = "";
3238
+ // Animation frame counter
3239
+ animFrame = 0;
3215
3240
  constructor() {
3216
3241
  this.rl = readline.createInterface({ input, output });
3217
3242
  this.state = {
@@ -3359,6 +3384,9 @@ var InteractiveDashboard = class {
3359
3384
  lastChange: update.data.lastChange ?? this.state.watch.lastChange,
3360
3385
  recentChanges: update.data.recentChanges ?? this.state.watch.recentChanges
3361
3386
  };
3387
+ if (update.data.watching !== void 0) {
3388
+ this.addActivity(update.data.watching ? `[*] Watch mode: ACTIVE (${update.data.directories ?? 0} dirs)` : "[*] Watch mode: OFF");
3389
+ }
3362
3390
  break;
3363
3391
  case "watch_change":
3364
3392
  const entry = { file: update.data.file, time: new Date(update.timestamp).toLocaleTimeString("en-US", { hour12: false }) };
@@ -3516,12 +3544,58 @@ var InteractiveDashboard = class {
3516
3544
  /**
3517
3545
  * Render a line with proper padding (accounts for ANSI color codes)
3518
3546
  */
3547
+ /**
3548
+ * Add a line to the render buffer (buffered output to prevent flicker)
3549
+ */
3550
+ bufferLine(line) {
3551
+ this.buffer.push(line);
3552
+ }
3519
3553
  renderLine(content, width) {
3520
3554
  const v = colors.border(box.vertical);
3521
3555
  const innerWidth = width - 2;
3522
3556
  const contentLen = visibleLength(content);
3523
- const padding = Math.max(0, innerWidth - contentLen);
3524
- console.log(v + content + " ".repeat(padding) + v);
3557
+ let displayContent = content;
3558
+ if (contentLen > innerWidth) {
3559
+ displayContent = this.truncateToWidth(content, innerWidth - 3) + "...";
3560
+ }
3561
+ const displayLen = visibleLength(displayContent);
3562
+ const padding = Math.max(0, innerWidth - displayLen);
3563
+ this.bufferLine(v + displayContent + " ".repeat(padding) + v);
3564
+ }
3565
+ /**
3566
+ * Truncate a string (with ANSI codes) to a visible width
3567
+ * Handles wide characters (emojis, CJK) that take 2 columns
3568
+ */
3569
+ truncateToWidth(str, maxWidth) {
3570
+ let visibleLen = 0;
3571
+ let result = "";
3572
+ let inEscape = false;
3573
+ for (const char of str) {
3574
+ if (char === "\x1B") {
3575
+ inEscape = true;
3576
+ result += char;
3577
+ } else if (inEscape) {
3578
+ result += char;
3579
+ if (char === "m") {
3580
+ inEscape = false;
3581
+ }
3582
+ } else {
3583
+ const code = char.codePointAt(0) || 0;
3584
+ const charWidth = code >= 127744 && code <= 129535 || // Emoji
3585
+ code >= 9728 && code <= 9983 || // Misc symbols
3586
+ code >= 9984 && code <= 10175 || // Dingbats
3587
+ code >= 65024 && code <= 65039 || // Variation selectors
3588
+ code >= 126976 && code <= 131071 || // Extended emoji
3589
+ code >= 12288 && code <= 40959 || // CJK
3590
+ code >= 44032 && code <= 55215 ? 2 : 1;
3591
+ if (visibleLen + charWidth > maxWidth) {
3592
+ break;
3593
+ }
3594
+ result += char;
3595
+ visibleLen += charWidth;
3596
+ }
3597
+ }
3598
+ return result + "\x1B[0m";
3525
3599
  }
3526
3600
  /**
3527
3601
  * Get responsive width based on terminal size
@@ -3531,10 +3605,11 @@ var InteractiveDashboard = class {
3531
3605
  return Math.max(60, Math.min(120, cols - 2));
3532
3606
  }
3533
3607
  /**
3534
- * Main render function
3608
+ * Main render function - uses double buffering to prevent flicker
3535
3609
  */
3536
3610
  render() {
3537
- process.stdout.write("\x1B[2J\x1B[3J\x1B[H\x1B[?25l");
3611
+ this.buffer = [];
3612
+ this.animFrame = (this.animFrame + 1) % 100;
3538
3613
  const width = this.getWidth();
3539
3614
  const height = Math.max(24, process.stdout.rows || 40);
3540
3615
  this.renderHeader(width);
@@ -3557,18 +3632,25 @@ var InteractiveDashboard = class {
3557
3632
  }
3558
3633
  }
3559
3634
  this.renderFooter(width);
3635
+ const frame = this.buffer.join("\n");
3636
+ if (frame !== this.lastFrame) {
3637
+ process.stdout.write("\x1B[?25l\x1B[H\x1B[2J" + frame);
3638
+ this.lastFrame = frame;
3639
+ }
3560
3640
  }
3561
3641
  /**
3562
3642
  * Render header with title and status
3563
3643
  */
3564
3644
  renderHeader(width) {
3565
3645
  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]");
3646
+ const watchSpinner = WATCH_FRAMES[this.animFrame % WATCH_FRAMES.length];
3647
+ const watchLabel = this.state.watch.watching ? colors.success(`[${watchSpinner} WATCHING]`) : colors.dim("[WATCH OFF]");
3648
+ const scanSpinner = SCAN_FRAMES[this.animFrame % SCAN_FRAMES.length];
3567
3649
  let statusText = "";
3568
3650
  if (this.state.scanComplete) {
3569
3651
  statusText = colors.success("COMPLETE") + " " + colors.success("[OK]");
3570
3652
  } else {
3571
- statusText = colors.running("SCANNING") + " " + colors.dim("(...)");
3653
+ statusText = colors.running(`${scanSpinner} SCANNING`) + " " + colors.dim("(...)");
3572
3654
  }
3573
3655
  let alertText = "";
3574
3656
  if (this.state.alerts.hasCritical) {
@@ -3583,9 +3665,9 @@ var InteractiveDashboard = class {
3583
3665
  const brandLen = visibleLength(brand);
3584
3666
  const rightLen = visibleLength(rightContent);
3585
3667
  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);
3668
+ this.bufferLine(topBorder);
3669
+ this.bufferLine(v + " " + brand + " ".repeat(gap) + rightContent + " " + v);
3670
+ this.bufferLine(midBorder);
3589
3671
  }
3590
3672
  /**
3591
3673
  * Render scanning in progress view
@@ -3606,7 +3688,7 @@ var InteractiveDashboard = class {
3606
3688
  this.renderLine(" " + colors.dim("Scanning:") + " " + colors.highlight(current.slice(0, 40)), width);
3607
3689
  this.renderLine(" " + progressBar + " " + colors.highlight(`${percent}%`) + " " + colors.dim(`(${processedFiles}/${totalFiles} files)`), width);
3608
3690
  this.renderLine("", width);
3609
- console.log(sectionBorder);
3691
+ this.bufferLine(sectionBorder);
3610
3692
  this.renderLine(" " + colors.header("SCOUTS"), width);
3611
3693
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3612
3694
  const allAgents = [.../* @__PURE__ */ new Set([...activeAgents, ...completedAgents])];
@@ -3640,7 +3722,7 @@ var InteractiveDashboard = class {
3640
3722
  this.renderLine(" " + padEnd(left, 35) + " " + right, width);
3641
3723
  }
3642
3724
  this.renderLine("", width);
3643
- console.log(sectionBorder);
3725
+ this.bufferLine(sectionBorder);
3644
3726
  this.renderLine(" " + colors.header("ISSUES FOUND"), width);
3645
3727
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3646
3728
  const criticalLine = `${colors.critical("[!]")} ${colors.critical("Critical")} ${colors.critical(issuesBySeverity.critical.toString().padStart(4))}`;
@@ -3650,16 +3732,17 @@ var InteractiveDashboard = class {
3650
3732
  this.renderLine(" " + padEnd(criticalLine, 28) + moderateLine, width);
3651
3733
  this.renderLine(" " + padEnd(seriousLine, 28) + lowLine, width);
3652
3734
  this.renderLine("", width);
3653
- console.log(sectionBorder);
3735
+ this.bufferLine(sectionBorder);
3654
3736
  this.renderLine(" " + colors.header("WATCH STATUS"), width);
3655
3737
  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");
3738
+ const watchAnim = WATCH_FRAMES[this.animFrame % WATCH_FRAMES.length];
3739
+ const watchLine = this.state.watch.watching ? colors.success(`${watchAnim} Watching ${this.state.watch.directories} dirs`) + colors.dim(this.state.watch.debounceMs ? ` \u2022 debounce ${this.state.watch.debounceMs}ms` : "") : colors.dim("Watch idle");
3657
3740
  this.renderLine(" " + watchLine, width);
3658
3741
  const lastChange = this.state.watch.lastChange ? colors.dim("Last change: ") + colors.highlight(this.state.watch.lastChange) : colors.dim("Last change: --");
3659
3742
  this.renderLine(" " + lastChange, width);
3660
3743
  const recentChange = this.state.watch.recentChanges[0]?.file ? colors.dim("Recent: ") + this.state.watch.recentChanges[0].file : "";
3661
3744
  this.renderLine(" " + recentChange, width);
3662
- console.log(sectionBorder);
3745
+ this.bufferLine(sectionBorder);
3663
3746
  this.renderLine(" " + colors.header("ACTIVITY LOG"), width);
3664
3747
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3665
3748
  const startIdx = this.state.activityPage * activityRows;
@@ -3712,7 +3795,7 @@ var InteractiveDashboard = class {
3712
3795
  this.renderLine(" " + colors.highlight(`${processedFiles}`) + colors.dim(` files scanned in ${elapsed}s`), width);
3713
3796
  this.renderLine(" " + colors.highlight(`${completedAgents.length}`) + colors.dim(" scouts activated"), width);
3714
3797
  this.renderLine("", width);
3715
- console.log(sectionBorder);
3798
+ this.bufferLine(sectionBorder);
3716
3799
  this.renderLine(" " + colors.header("SUMMARY"), width);
3717
3800
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3718
3801
  const criticalLabel = issuesBySeverity.critical > 0 ? " " + colors.alert("<- FIX NOW") : "";
@@ -3723,7 +3806,7 @@ var InteractiveDashboard = class {
3723
3806
  this.renderLine("", width);
3724
3807
  const criticalIssues = this.state.issues.filter((i) => i.severity === "critical").slice(0, 3);
3725
3808
  if (criticalIssues.length > 0) {
3726
- console.log(sectionBorder);
3809
+ this.bufferLine(sectionBorder);
3727
3810
  this.renderLine(" " + colors.critical("TOP CRITICAL ISSUES"), width);
3728
3811
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3729
3812
  for (const issue of criticalIssues) {
@@ -3736,11 +3819,11 @@ var InteractiveDashboard = class {
3736
3819
  this.renderLine("", width);
3737
3820
  }
3738
3821
  } else if (totalIssues === 0) {
3739
- console.log(sectionBorder);
3822
+ this.bufferLine(sectionBorder);
3740
3823
  this.renderLine(" " + colors.success("\u2713 No issues found - code looks good!"), width);
3741
3824
  this.renderLine("", width);
3742
3825
  }
3743
- console.log(sectionBorder);
3826
+ this.bufferLine(sectionBorder);
3744
3827
  this.renderLine(" " + colors.header("ACTIVITY LOG"), width);
3745
3828
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3746
3829
  const startIdx = this.state.activityPage * activityRows;
@@ -3765,7 +3848,7 @@ var InteractiveDashboard = class {
3765
3848
  const totalPages = Math.max(1, Math.ceil(filteredIssues.length / pageSize));
3766
3849
  const pageInfo = colors.dim(`Page ${currentPage}/${totalPages}`) + " " + colors.highlight(`${filteredIssues.length}`) + colors.dim(" issues");
3767
3850
  this.renderLine(" " + colors.dim("Filter:") + " " + this.getFilterDescription() + " " + pageInfo, width);
3768
- console.log(sectionBorder);
3851
+ this.bufferLine(sectionBorder);
3769
3852
  const startIndex = Math.floor(selectedIssue / pageSize) * pageSize;
3770
3853
  const pageIssues = filteredIssues.slice(startIndex, startIndex + pageSize);
3771
3854
  if (filteredIssues.length === 0) {
@@ -3795,7 +3878,7 @@ var InteractiveDashboard = class {
3795
3878
  }
3796
3879
  if (filteredIssues[selectedIssue]) {
3797
3880
  const selected = filteredIssues[selectedIssue];
3798
- console.log(sectionBorder);
3881
+ this.bufferLine(sectionBorder);
3799
3882
  this.renderLine(" " + colors.header("SELECTED:") + " " + colors.highlight(selected.issue.slice(0, width - 20)), width);
3800
3883
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3801
3884
  this.renderLine(" " + colors.dim("File:") + " " + selected.file.slice(0, width - 15), width);
@@ -3820,7 +3903,7 @@ var InteractiveDashboard = class {
3820
3903
  const totalPages = Math.max(1, Math.ceil(sorted.length / pageSize));
3821
3904
  const pageHint = totalPages > 1 ? " " + colors.highlight(`[n/p]`) + colors.dim(" more pages") : "";
3822
3905
  this.renderLine(" " + colors.header("SCOUT STATUS") + " " + colors.dim("(j/k navigate, Enter view issues)"), width);
3823
- console.log(sectionBorder);
3906
+ this.bufferLine(sectionBorder);
3824
3907
  this.renderLine(" " + colors.highlight(`${sorted.length}`) + colors.dim(" scouts") + " " + colors.dim(`Page ${this.state.agentPage + 1}/${totalPages}`) + pageHint, width);
3825
3908
  if (slice.length === 0) {
3826
3909
  this.renderLine(" " + colors.dim("No scouts yet"), width);
@@ -3849,7 +3932,7 @@ var InteractiveDashboard = class {
3849
3932
  const agentIssues = this.state.issues.filter((i) => i.agent === selected.name);
3850
3933
  const criticals = agentIssues.filter((i) => i.severity === "critical").length;
3851
3934
  const serious = agentIssues.filter((i) => i.severity === "serious").length;
3852
- console.log(sectionBorder);
3935
+ this.bufferLine(sectionBorder);
3853
3936
  this.renderLine(" " + colors.header("SELECTED:") + " " + colors.highlight(selected.name), width);
3854
3937
  this.renderLine(" " + colors.dim(this.line(width - 6)), width);
3855
3938
  this.renderLine(" " + colors.dim("Issues:") + " " + colors.highlight(agentIssues.length.toString()) + " total (" + colors.critical(`[!] ${criticals} critical`) + ", " + colors.serious(`[x] ${serious} serious`) + ")", width);
@@ -3870,7 +3953,7 @@ var InteractiveDashboard = class {
3870
3953
  }
3871
3954
  const sortedFiles = Array.from(fileIssues.entries()).sort((a, b) => b[1].length - a[1].length).slice(0, 15);
3872
3955
  this.renderLine(" " + colors.header("FILES WITH ISSUES"), width);
3873
- console.log(sectionBorder);
3956
+ this.bufferLine(sectionBorder);
3874
3957
  for (const [file, issues] of sortedFiles) {
3875
3958
  const filename = file.split("/").pop() || file;
3876
3959
  const criticalCount = issues.filter((i) => i.severity === "critical").length;
@@ -3888,19 +3971,19 @@ var InteractiveDashboard = class {
3888
3971
  */
3889
3972
  renderFooter(width) {
3890
3973
  const bottomBorder = colors.border(box.bottomLeft + this.line(width - 2) + box.bottomRight);
3891
- console.log(bottomBorder);
3974
+ this.bufferLine(bottomBorder);
3892
3975
  const key = (k) => colors.border("[") + colors.highlight(k) + colors.border("]");
3893
3976
  const hint = (k, desc) => key(k) + colors.dim(` ${desc}`);
3894
3977
  if (!this.state.scanComplete) {
3895
- console.log(" " + hint("q", "Quit") + " " + hint("?", "Help"));
3978
+ this.bufferLine(" " + hint("q", "Quit") + " " + hint("?", "Help"));
3896
3979
  } 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"));
3980
+ this.bufferLine(" " + hint("j/k", "Select") + " " + hint("Enter", "View issues") + " " + hint("n/p", "Pages") + " " + hint("Tab", "Views") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
3898
3981
  } 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"));
3982
+ this.bufferLine(" " + hint("b", "Back") + " " + hint("j/k", "Nav") + " " + hint("Enter", "Details") + " " + hint("1-4", "Severity") + " " + hint("f", "Search") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
3900
3983
  } 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"));
3984
+ this.bufferLine(" " + 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"));
3902
3985
  } else {
3903
- console.log(" " + hint("Tab", "Views") + " " + hint("n/p", "Pages") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
3986
+ this.bufferLine(" " + hint("Tab", "Views") + " " + hint("n/p", "Pages") + " " + hint("?", "Help") + " " + hint("q", "Quit"));
3904
3987
  }
3905
3988
  }
3906
3989
  // Helper methods
@@ -6249,4 +6332,4 @@ export {
6249
6332
  InteractiveDashboard,
6250
6333
  TrieScanTool
6251
6334
  };
6252
- //# sourceMappingURL=chunk-JAVEBJF4.js.map
6335
+ //# sourceMappingURL=chunk-3B2JBLSP.js.map