public/Update-Wtw.ps1

function Update-Wtw {
    <#
    .SYNOPSIS
        Update the installed wtw to the latest PowerShell Gallery release.
    .DESCRIPTION
        `wtw install` copies a source checkout into ~/.wtw/module. `wtw update`
        is the other half: it replaces whatever is in ~/.wtw/module with the
        published Gallery package, whether that copy came from the Gallery or was
        hand-installed from a checkout.

        It materialises the package into ~/.wtw/module rather than leaving it on
        PSModulePath because every loader wtw installs — the profile snippet, the
        zsh and bash wrappers, the Windows cmd shim — imports
        ~/.wtw/module/wtw.psm1 by explicit path. An `Install-Module wtw` that
        lands somewhere else updates a copy none of them ever load, which is the
        exact trap this command exists to close.

        A local build that is newer than the Gallery is a normal state for anyone
        working on wtw itself, and is reported as current, not as a problem.
    .PARAMETER Check
        Report versions and exit without changing anything.
    .PARAMETER Yes
        Skip the confirmation prompt.
    .PARAMETER Force
        Reinstall from the Gallery even when the installed version already
        matches. A plain ``wtw update`` already live-checks the Gallery; the
        24h cache is only for the background notice.
    .EXAMPLE
        wtw update
        Compare against the Gallery and offer to replace the installed copy.
    .EXAMPLE
        wtw update --check
        Show where wtw is installed from and whether it is current.
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [switch] $Check,
        [switch] $Yes,
        [switch] $Force
    )

    $installRoot = Join-Path $HOME '.wtw' 'module'
    $info = Get-WtwInstallInfo -IncludeGalleryCopies
    # Always live-check. The 24h cache is for the startup notice, not for an
    # explicit update — otherwise a just-published release looks "up to date".
    $status = Get-WtwUpdateStatus -Force

    # The version that matters is the one in ~/.wtw/module — the copy every
    # loader imports — not the checkout this command happens to be running from.
    $installed = if ($info.ModuleRoot -eq $info.InstallRoot) {
        $info
    } else {
        Get-WtwInstallInfo -ModuleRoot $installRoot
    }
    $installedPresent = Test-Path -LiteralPath (Join-Path $installRoot 'wtw.psm1') -PathType Leaf

    Write-Host ''
    Write-Host ' wtw update' -ForegroundColor Cyan
    if ($installedPresent) {
        $originLabel = switch ($installed.Flavour) {
            'Gallery' { 'PowerShell Gallery' }
            default { if ($installed.SourcePath) { "local checkout ($($installed.SourcePath))" } else { 'local checkout' } }
        }
        Write-Host (" Installed: {0} [{1}]" -f ($installed.Version ?? 'unknown'), $originLabel)
        Write-Host (" Location: {0}" -f $installRoot) -ForegroundColor DarkGray
    } else {
        Write-Host ' Installed: not installed globally' -ForegroundColor Yellow
    }

    if ($status.Status -ne 'Available' -or $null -eq $status.LatestVersion) {
        Write-Host ' Gallery: unreachable — try again when online.' -ForegroundColor Yellow
        Write-Host ''
        return
    }
    Write-Host (" Gallery: {0}" -f $status.LatestVersion)

    if ($info.Flavour -eq 'Repo') {
        Write-Host (" Running from a checkout at {0}" -f $info.ModuleRoot) -ForegroundColor DarkGray
    }

    Write-WtwShadowWarning -Info $info -Yes:$Yes -Check:$Check

    $current = $installed.Version
    $upToDate = $installedPresent -and $null -ne $current -and $status.LatestVersion -le $current

    if ($upToDate -and -not $Force) {
        # Equal, or a local build ahead of the Gallery. Neither is a problem, so
        # neither gets a warning.
        if ($status.LatestVersion -lt $current) {
            Write-Host (" {0} is newer than the published {1} — nothing to do." -f $current, $status.LatestVersion) -ForegroundColor Green
        } else {
            Write-Host ' Up to date.' -ForegroundColor Green
        }
        Write-Host ''
        return
    }

    if ($Check) {
        Write-Host (" Update available: {0} -> {1} (run: wtw update)" -f ($current ?? 'none'), $status.LatestVersion) -ForegroundColor Cyan
        Write-Host ''
        return
    }

    Write-Host ''
    if ($installed.Flavour -eq 'Manual' -and $installedPresent) {
        Write-Host ' The installed copy was hand-installed from a checkout.' -ForegroundColor Yellow
        Write-Host ' Updating replaces it with the published Gallery package.' -ForegroundColor DarkGray
        Write-Host ' To keep tracking your checkout instead, run `wtw install` from it.' -ForegroundColor DarkGray
    }

    if (-not $Yes) {
        # ${...} around the path: a bare "$installRoot?" parses the trailing
        # question mark as part of the variable name.
        $prompt = " Install wtw $($status.LatestVersion) from the PowerShell Gallery into ${installRoot}? [y/N]"
        if ((Read-Host $prompt) -notin @('y', 'Y', 'yes')) {
            Write-Host ' Cancelled.' -ForegroundColor DarkGray
            Write-Host ''
            return
        }
    }

    if (-not $PSCmdlet.ShouldProcess($installRoot, "Install wtw $($status.LatestVersion) from the PowerShell Gallery")) {
        return
    }

    $staged = Save-WtwGalleryPackage -Version $status.LatestVersion
    if (-not $staged) {
        Write-Host ''
        return
    }

    try {
        if (Install-WtwStagedModule -StagedRoot $staged -InstallRoot $installRoot) {
            Write-WtwInstallRecord -InstallRoot $installRoot -Origin 'Gallery' -Version $status.LatestVersion
            Write-Host (" wtw {0} installed to {1}" -f $status.LatestVersion, $installRoot) -ForegroundColor Green
            $modulePath = Join-Path $installRoot 'wtw.psm1'
            if (Test-Path -LiteralPath $modulePath) {
                Import-Module $modulePath -Global -Force -DisableNameChecking -Verbose:$false -Debug:$false 1>$null 4>$null 5>$null 6>$null
                Write-Host ' Reloaded the module in this session.' -ForegroundColor DarkGray
            }
        }
    } finally {
        Remove-Item -LiteralPath (Split-Path -Parent $staged) -Recurse -Force -ErrorAction SilentlyContinue
    }
    Write-Host ''
}