Payload/scripts/kaden/utils/update-kaden.ps1

<#
.SYNOPSIS
    Install or update the Kaden module from PSGallery.

.DESCRIPTION
    Finds the newest Kaden release on PSGallery, including a prerelease.
    Installs it for the current user when the local copy is missing or older,
    removes older installed versions, and imports the new module into this session.

.EXAMPLE
    pwsh -NoProfile -File .\scripts\kaden\utils\update-kaden.ps1

.EXAMPLE
    Get-Help .\scripts\kaden\utils\update-kaden.ps1
#>


#Requires -Version 5.1
[CmdletBinding()]
param()

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$cliKitManifest = Join-Path $PSScriptRoot "PsCliUiKit\PsCliUiKit.psd1"
if (-not (Test-Path -LiteralPath $cliKitManifest)) {
    throw "PsCliUiKit manifest not found: $cliKitManifest"
}
Import-Module -Name $cliKitManifest -Force

# 1. Define Module Settings
$moduleName = "Kaden"
$repoName = "PSGallery"
$ok = Get-CliGlyph -Name Ok
$fail = Get-CliGlyph -Name Fail

Write-CliSection -Title "Checking for the latest version of '$moduleName' on $repoName" -Style info

# 2. Get the absolute latest version available on the gallery (Stable or Beta)
$galleryModule = Find-Module -Name $moduleName -Repository $repoName -AllVersions -AllowPrerelease |
    Sort-Object { [System.Management.Automation.SemanticVersion]$_.Version } -Descending |
    Select-Object -First 1

if (-not $galleryModule) {
    # Continue keeps this non-terminating under ErrorAction Stop so the closing line still runs.
    Write-CliStatus -State Error -Message "Could not find module '$moduleName' in the '$repoName' repository $fail"
    Write-Error "Could not find module '$moduleName' in the '$repoName' repository." -ErrorAction Continue
    Write-CliEnd
    exit 2
}

$galleryVersion = $galleryModule.Version
$gallerySemantic = [System.Management.Automation.SemanticVersion]$galleryVersion
Write-CliKeyValue -Label "Online version" -Value $galleryVersion

# 3. Check what version (if any) is currently installed.
# Get-InstalledModule without -AllVersions returns a single catalog entry, which can be an older prerelease.
$installedModules = @(Get-InstalledModule -Name $moduleName -AllVersions -ErrorAction SilentlyContinue)
$localModule = $installedModules |
    Sort-Object { [System.Management.Automation.SemanticVersion]$_.Version } -Descending |
    Select-Object -First 1
$localVersion = if ($localModule) { $localModule.Version } else { $null }

if ($localVersion) {
    Write-CliKeyValue -Label "Local version" -Value "[success]$localVersion $ok[-]"
} else {
    Write-CliKeyValue -Label "Local version" -Value "[muted]not installed $fail[-]"
}

# 4. Determine if an update or fresh install is required
$localSemantic = if ($localVersion) { [System.Management.Automation.SemanticVersion]$localVersion } else { $null }
if (-not $localSemantic -or ($localSemantic -lt $gallerySemantic)) {
    if (-not $localVersion) {
        Write-CliStatus -State Info -Message "Installing module '$moduleName' ($galleryVersion)..."
    } else {
        Write-CliStatus -State Info -Message "Updating module '$moduleName' to version $galleryVersion..."
    }

    # Perform the installation/update explicitly targeting PSGallery
    Install-Module -Name $moduleName -Repository $repoName -Scope CurrentUser -AllowPrerelease -Force -AllowClobber
} else {
    Write-CliStatus -State Success -Message "Already on the most recent version ($localVersion) $ok"
}

# 5. Clean up older versions if they exist
Write-CliSection -Title "Checking for older versions" -Style info
$allInstalled = @(Get-InstalledModule -Name $moduleName -AllVersions -ErrorAction SilentlyContinue)
$olderInstalled = @($allInstalled | Where-Object {
        ([System.Management.Automation.SemanticVersion]$_.Version) -lt $gallerySemantic
    })

if ($olderInstalled.Count -gt 0) {
    # Uninstall-Module refuses a version that is still imported in this session.
    Remove-Module -Name $moduleName -Force -ErrorAction SilentlyContinue
    foreach ($mod in $olderInstalled) {
        Uninstall-Module -Name $moduleName -RequiredVersion $mod.Version -AllowPrerelease -Force
        Write-CliStatus -State Success -Message "Removed older version $($mod.Version)"
    }
} else {
    Write-CliStatus -State Success -Message "No old versions to clean up"
}

# 6. Force import the module into the active session.
# Import-Module -Force reloads the on-disk module and leaves any other version already imported in this session.
Remove-Module -Name $moduleName -Force -ErrorAction SilentlyContinue
Write-CliSection -Title "Importing '$moduleName'" -Style info
Import-Module -Name $moduleName -Force

# 7. Verify success and display results
$activeModule = @(Get-Module -Name $moduleName)
if ($activeModule.Count -eq 0) {
    Write-CliStatus -State Error -Message "Failed to import the module after installation"
    Write-Error "Failed to import the module after installation." -ErrorAction Continue
    Write-CliEnd
    exit 2
}

Write-CliSection -Title "Verification success" -Style success
foreach ($mod in $activeModule) {
    Write-CliKeyValue -Label "Module name" -Value $mod.Name
    Write-CliKeyValue -Label "Active version" -Value $mod.Version
}

Write-CliSection -Title "Available commands" -Style subheader

# Manually write out just what is needed to get started
Write-CliList -Style Corner -Item @(
    "Get-KadenVersion"
    "Initialize-KadenRepo"
    "Repair-KadenRepo"
    "Test-KadenRepo"
    "Update-KadenRepo"
)

Write-CliSection -Title "Next step $(Get-CliGlyph -Name Prompt)" -Style subheader
Write-CliColor -Message " Initialize or update the repository with Initialize-KadenRepo or Update-KadenRepo. For example:"
Write-CliColor -Message " [Blue]PS>[-] [Yellow]Initialize-KadenRepo -Path <path-to-repo> -ProjectId '<repo-name>' -BetaInvitation <passphrase> -Stack <Node|PowerShell|Python|SQL|Polyglot|None>[-]"
Write-CliColor -Message " Use Get-Help <command-name> for more information" -Style Muted

#Write-CliColor -Message "$(Get-CliGlyph -Name GClef) [Blue]Kaden[-]"
#Write-CliColor -Message "$(Get-CliGlyph -Name FClef) [Blue]Kaden[-]"
Write-CliColor -Message " $(Get-CliGlyph -Name QuarterNote)[Blue]Kaden[-]"

#Write-CliEnd