Private/Show-Win32ToolkitSettings.ps1

function Show-Win32ToolkitSettings {
    <#
    .SYNOPSIS
        Settings screen (base folder, re-check). Returns the (possibly updated) base folder.
        See knowledge-base/designs/tui.md.
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param([string]$BasePath)

    while ($true) {
        # Out-SpectreHost: render without leaking the rule object into this function's output, which the
        # caller captures ($base = Show-Win32ToolkitSettings ...). A leak there makes $base an array and
        # the next 'Show-Win32ToolkitHealth -BasePath $base' fails to bind the [string] BasePath.
        Write-SpectreRule -Title 'Settings' -Color Grey | Out-SpectreHost
        Write-SpectreHost "Base folder: [blue]$(Get-SpectreEscapedText -Text $BasePath)[/]"
        $choices = @(
            [pscustomobject]@{ Key = 'basepath'; Label = 'Change the base folder' }
            [pscustomobject]@{ Key = 'testvm';   Label = 'Hyper-V test VM (backend / provision / reset / remove)' }
            [pscustomobject]@{ Key = 'update';   Label = "Update check: $(if ((Get-Win32ToolkitConfigValue -Name 'UpdateCheck' -Default 'On') -eq 'Off') { 'Off' } else { 'On' }) (toggle / check now)" }
            [pscustomobject]@{ Key = 'recheck';  Label = 'Re-run the system check' }
            [pscustomobject]@{ Key = 'back';     Label = 'Back to main menu' }
        )
        $sel = Read-SpectreSelection -Message 'Settings' -Choices $choices -ChoiceLabelProperty 'Label' -Color Blue
        switch ($sel.Key) {
            'basepath' {
                $new = Read-SpectreText -Message 'Enter the base folder for all output' -DefaultAnswer $BasePath
                if (-not [string]::IsNullOrWhiteSpace($new)) {
                    $BasePath = Get-Win32ToolkitBasePath -Set $new
                    Write-SpectreHost "[green]Saved:[/] $(Get-SpectreEscapedText -Text $BasePath)"
                }
            }
            # Out-Null so nothing this subtree emits leaks into $base (the caller captures
            # Show-Win32ToolkitSettings's output). Panels inside render via Out-SpectreHost.
            'testvm'  { Show-Win32ToolkitTestVM | Out-Null }
            'update'  {
                $now = Get-Win32ToolkitConfigValue -Name 'UpdateCheck' -Default 'On'
                $new = if ($now -eq 'Off') { 'On' } else { 'Off' }
                Set-Win32ToolkitConfigValue -Name 'UpdateCheck' -Value $new
                Write-SpectreHost "[green]Update check set to:[/] $new"
                if ($new -eq 'On') {
                    $info = Get-Win32ToolkitUpdateInfo -Force
                    if ($info -and $info.UpdateAvailable) { Show-Win32ToolkitUpdateNotice -Force }
                    elseif ($info)                        { Write-SpectreHost "[grey]You are on the latest version (v$($info.Installed)).[/]" }
                    else                                  { Write-SpectreHost '[grey]Could not check for updates right now.[/]' }
                }
            }
            'recheck' { Show-Win32ToolkitHealth -BasePath $BasePath }
            'back'    { return $BasePath }
        }
    }
}