Skip to content

Commit 27b0a5c

Browse files
yotsudaclaude
andcommitted
fix(streams): VT-strip dedup-known set so cmdlet ANSI output stops leaking into HOST.UI
The dedup pass that drops HostWrite lines already present in another section was comparing VT-stripped \$hostRaw against a HashSet built from the raw section sources — pipelineText etc. still carried the SGR codes from cmdlet renderers like AnsiColors.Inserted / AnsiColors.Deleted. The trim-then-Contains check then mismatched on the ANSI runs: a HostWrite line of \`: Line 3\` never matched the known entry \`: \e[31mLine 3\e[0m\`, so every coloured line a cmdlet emitted leaked into the HOST.UI section as a plain-text duplicate. Strip VT codes from each section source before populating \$known. \$hostRaw is already VT-stripped earlier in the method, so after this fix both sides of the comparison are normalised the same way and the duplicate suppression actually fires. Verified end-to-end against the deployed module: a body that runs Update-LinesInFile + a WhatIf-bearing Remove-Item now surfaces only the WhatIf message in HOST.UI; the cmdlet's coloured context / deleted / inserted / context block stays in pipelineText where it belongs and no longer echoes into the HOST.UI section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ded966a commit 27b0a5c

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

PowerShell.MCP/Resources/MCPPollingEngine.ps1

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,11 +576,23 @@ if (-not (Test-Path Variable:global:McpTimer)) {
576576
# exactly matches one of these is treated as a
577577
# render-time duplicate and dropped from
578578
# HostWrite.
579+
# VT-strip both sides before comparison.
580+
# pipelineText (and the other section sources)
581+
# carries the cmdlet's own SGR codes from
582+
# AnsiColors.* renders — Update-LinesInFile in
583+
# particular emits coloured context / inserted
584+
# / deleted lines. $hostRaw was already
585+
# VT-stripped earlier in this method. Without
586+
# also stripping the comparison set, the dedup
587+
# mismatched on the ANSI runs and let the
588+
# whole cmdlet output leak into the HOST.UI
589+
# section as plain text duplicates.
579590
$known = [System.Collections.Generic.HashSet[string]]::new(
580591
[System.StringComparer]::Ordinal)
581592
foreach ($src in @($pipelineText, $exceptionText, $infoText, $consoleOutText, $consoleErrText)) {
582593
if (-not [string]::IsNullOrEmpty($src)) {
583-
foreach ($line in $src -split "`r?`n") {
594+
$srcStripped = $src -replace $vtPattern, ""
595+
foreach ($line in $srcStripped -split "`r?`n") {
584596
$trimmed = $line.Trim()
585597
if ($trimmed) { [void]$known.Add($trimmed) }
586598
}

0 commit comments

Comments
 (0)