functions/public/Get-KlippyUpdate.ps1

function Get-KlippyUpdate {
    <#
    .SYNOPSIS
        Gets update status for Klipper components.

    .DESCRIPTION
        Retrieves the current version and available updates for Klipper,
        Moonraker, and other configured components.

    .PARAMETER Id
        The unique identifier of the printer.

    .PARAMETER PrinterName
        The friendly name of the printer.

    .PARAMETER InputObject
        A printer object from pipeline input.

    .PARAMETER Refresh
        Refresh update information from remote sources.

    .PARAMETER Component
        Filter by specific component name.

    .EXAMPLE
        Get-KlippyUpdate
        Gets update status for all components on the default printer.

    .EXAMPLE
        Get-KlippyUpdate -PrinterName "voronv2" -Refresh
        Refreshes and gets update status.

    .EXAMPLE
        Get-KlippyUpdate -Component "klipper"
        Gets update status for Klipper only.

    .OUTPUTS
        KlippyCLI.UpdateStatus objects.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(ParameterSetName = 'ById')]
        [ValidateNotNullOrEmpty()]
        [string]$Id,

        [Parameter(ParameterSetName = 'ByName', Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$PrinterName,

        [Parameter(ParameterSetName = 'ByObject', ValueFromPipeline = $true)]
        [PSCustomObject]$InputObject,

        [Parameter()]
        [switch]$Refresh,

        [Parameter()]
        [string]$Component
    )

    process {
        # Resolve printer
        $resolveParams = @{}
        switch ($PSCmdlet.ParameterSetName) {
            'ById' { $resolveParams['Id'] = $Id }
            'ByName' { $resolveParams['PrinterName'] = $PrinterName }
            'ByObject' { $resolveParams['InputObject'] = $InputObject }
        }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            # Optionally refresh update info
            if ($Refresh) {
                Write-Verbose "[$($printer.PrinterName)] Refreshing update information..."
                try {
                    $null = Invoke-KlippyJsonRpc -Printer $printer -Method "machine/update/refresh" -Timeout 120
                }
                catch {
                    Write-Warning "Could not refresh update info: $_"
                }
            }

            # Get update status
            $response = Invoke-KlippyJsonRpc -Printer $printer -Method "machine/update/status" -NoNormalize

            if (-not $response -or -not $response.version_info) {
                Write-Warning "No update information available. Is update_manager configured?"
                return
            }

            # Process each component
            foreach ($compName in $response.version_info.PSObject.Properties.Name) {
                # Apply component filter
                if ($Component -and $compName -notlike $Component) {
                    continue
                }

                $info = $response.version_info.$compName

                # Determine update availability
                $updateAvailable = $false
                $currentVersion = $null
                $remoteVersion = $null

                if ($info.version) {
                    $currentVersion = $info.version
                    $remoteVersion = $info.remote_version
                    if ($remoteVersion -and $currentVersion -ne $remoteVersion) {
                        $updateAvailable = $true
                    }
                }
                elseif ($info.current_hash) {
                    $currentVersion = $info.current_hash.Substring(0, 8)
                    if ($info.remote_hash) {
                        $remoteVersion = $info.remote_hash.Substring(0, 8)
                        if ($info.current_hash -ne $info.remote_hash) {
                            $updateAvailable = $true
                        }
                    }
                }

                [PSCustomObject]@{
                    PSTypeName       = 'KlippyCLI.UpdateStatus'
                    PrinterId        = $printer.Id
                    PrinterName      = $printer.PrinterName
                    Component        = $compName
                    CurrentVersion   = $currentVersion
                    RemoteVersion    = $remoteVersion
                    UpdateAvailable  = $updateAvailable
                    Channel          = $info.channel
                    Branch           = $info.branch
                    IsDirty          = $info.is_dirty
                    IsValid          = $info.is_valid
                    DetachedHead     = $info.detached
                    CommitsBehind    = $info.commits_behind
                    Warnings         = $info.warnings
                    InfoTags         = $info.info_tags
                }
            }

            # Output busy status if available
            if ($response.busy) {
                Write-Warning "Update manager is currently busy."
            }
        }
        catch {
            Write-Error "Failed to get update status from '$($printer.PrinterName)': $_"
        }
    }
}