Private/Invoke-ColorScriptProcess.ps1

function Invoke-ColorScriptProcess {
    <#
    .SYNOPSIS
        Executes a colorscript and captures its output using an isolated process
        to preserve ANSI sequences and console rendering fidelity.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$ScriptPath,

        [switch]$ForCache
    )

    $scriptName = [System.IO.Path]::GetFileNameWithoutExtension($ScriptPath)

    $result = [pscustomobject]@{
        ScriptName = $scriptName
        StdOut     = ''
        StdErr     = ''
        ExitCode   = $null
        Success    = $false
    }

    if (-not (Test-Path -LiteralPath $ScriptPath)) {
        $result.StdErr = $script:Messages.ScriptPathNotFound
        return $result
    }

    if (-not $ForCache) {
        $staticOutput = Get-StaticColorScriptOutput -ScriptPath $ScriptPath
        if ($staticOutput.Available) {
            $result.StdOut = $staticOutput.Content
            $result.ExitCode = 0
            $result.Success = $true
            return $result
        }
    }

    $executable = Get-PowerShellExecutable
    $scriptDirectory = [System.IO.Path]::GetDirectoryName($ScriptPath)
    $process = $null

    try {
        $startInfo = New-Object System.Diagnostics.ProcessStartInfo
        $startInfo.FileName = $executable

        $escapedScriptPath = $ScriptPath.Replace("'", "''")
        $escapedScriptDir = if ($scriptDirectory) { $scriptDirectory.Replace("'", "''") } else { $null }
        $commandBuilder = New-Object System.Text.StringBuilder
        $null = $commandBuilder.Append("[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ")
        if ($escapedScriptDir) {
            $null = $commandBuilder.Append("Set-Location -LiteralPath '$escapedScriptDir'; ")
        }

        # ConsoleHost spends most of the runtime parsing thousands of ANSI sequences emitted by
        # Write-Host. Shadow it inside the isolated child process so ANSI can be captured without
        # ConsoleHost rendering overhead. Literal ANSI is preserved, while ConsoleColor arguments
        # are translated to equivalent SGR sequences. The script remains process-isolated.
        $null = $commandBuilder.Append(@'
$__cseOutputBuilder = [System.Text.StringBuilder]::new();
$__cseEscape = [string][char]27;
$__cseForegroundCodes = @{
    Black = 30; DarkBlue = 34; DarkGreen = 32; DarkCyan = 36;
    DarkRed = 31; DarkMagenta = 35; DarkYellow = 33; Gray = 37;
    DarkGray = 90; Blue = 94; Green = 92; Cyan = 96;
    Red = 91; Magenta = 95; Yellow = 93; White = 97
};
$__cseBackgroundCodes = @{
    Black = 40; DarkBlue = 44; DarkGreen = 42; DarkCyan = 46;
    DarkRed = 41; DarkMagenta = 45; DarkYellow = 43; Gray = 47;
    DarkGray = 100; Blue = 104; Green = 102; Cyan = 106;
    Red = 101; Magenta = 105; Yellow = 103; White = 107
};
function Write-Host {
    param(
        [Parameter(Position = 0, ValueFromPipeline, ValueFromRemainingArguments)]
        [object[]]$Object,
        [object]$Separator = ' ',
        [switch]$NoNewline,
        [System.ConsoleColor]$ForegroundColor,
        [System.ConsoleColor]$BackgroundColor
    )
    process {
        $__cseColorCodes = @();
        if ($PSBoundParameters.ContainsKey('ForegroundColor')) {
            $__cseColorCodes += $__cseForegroundCodes[[string]$ForegroundColor];
        }
        if ($PSBoundParameters.ContainsKey('BackgroundColor')) {
            $__cseColorCodes += $__cseBackgroundCodes[[string]$BackgroundColor];
        }
        if ($__cseColorCodes.Count -gt 0) {
            $null = $__cseOutputBuilder.Append($__cseEscape).Append('[').Append([string]::Join(';', $__cseColorCodes)).Append('m');
        }
        $__cseText = if ($null -eq $Object) { '' } else { [string]::Join([string]$Separator, $Object) };
        $null = $__cseOutputBuilder.Append($__cseText);
        if ($__cseColorCodes.Count -gt 0) {
            $null = $__cseOutputBuilder.Append($__cseEscape).Append('[0m');
        }
        if (-not $NoNewline) { $null = $__cseOutputBuilder.Append([Environment]::NewLine) };
    }
};
'@
)
        $null = $commandBuilder.Append("`$__csePipelineOutput = & ([ScriptBlock]::Create([System.IO.File]::ReadAllText('$escapedScriptPath', [System.Text.Encoding]::UTF8))); ")
        $null = $commandBuilder.Append(@'
foreach ($__cseItem in $__csePipelineOutput) { $null = $__cseOutputBuilder.AppendLine([string]$__cseItem) };
[Console]::Out.Write($__cseOutputBuilder.ToString());
'@
)

        $commandText = $commandBuilder.ToString()
        $commandBytes = [System.Text.Encoding]::Unicode.GetBytes($commandText)
        $encodedCommand = [Convert]::ToBase64String($commandBytes)
        $startInfo.Arguments = "-NoLogo -NoProfile -NonInteractive -EncodedCommand $encodedCommand"
        $startInfo.UseShellExecute = $false
        $startInfo.RedirectStandardOutput = $true
        $startInfo.RedirectStandardError = $true
        $startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
        $startInfo.StandardErrorEncoding = [System.Text.Encoding]::UTF8

        if ($ForCache) {
            try {
                $startInfo.EnvironmentVariables['COLOR_SCRIPTS_ENHANCED_CACHE_BUILD'] = '1'
            }
            catch {
                Write-Verbose ("Unable to set cache build environment variable: {0}" -f $_.Exception.Message)
            }
        }

        if ($scriptDirectory) {
            $startInfo.WorkingDirectory = $scriptDirectory
        }

        $process = New-Object System.Diagnostics.Process
        $process.StartInfo = $startInfo
        $null = $process.Start()

        $output = $process.StandardOutput.ReadToEnd()
        $errorOutput = $process.StandardError.ReadToEnd()
        $process.WaitForExit()

        $result.ExitCode = $process.ExitCode
        $result.StdOut = $output
        $result.StdErr = $errorOutput
        $result.Success = ($process.ExitCode -eq 0)
    }
    catch {
        $result.StdErr = $_.Exception.Message
    }
    finally {
        if ($process) {
            $process.Dispose()
        }
    }

    return $result
}