BountyHunter.psm1
# BountyHunter.psm1 # — Load registry from JSON $moduleJson = Join-Path $PSScriptRoot 'modules.json' if (Test-Path $moduleJson) { try { $Global:BountyModuleIndex = Get-Content $moduleJson -Raw | ConvertFrom-Json } catch { Write-Warning "Failed to parse modules.json: $_" $Global:BountyModuleIndex = @() } } else { Write-Warning "modules.json not found at $moduleJson" $Global:BountyModuleIndex = @() } # ------------------------ # 1. Discovery # ------------------------ function Get-BountyModules { [CmdletBinding()] param( [string]$Tag ) $list = $Global:BountyModuleIndex if ($Tag) { $list = $list | Where-Object { $_.Tags -contains $Tag } } $list | Select-Object Name, Description, @{n='Tags';e={($_.Tags -join ', ')}} } function Get-BountyStatus { [CmdletBinding()] param() $results = foreach ($mod in $Global:BountyModuleIndex) { # Local installation info $inst = Get-Module -ListAvailable -Name $mod.Name | Sort-Object Version -Descending | Select-Object -First 1 $instVer = if ($inst) { [version]$inst.Version } else { $null } $status = if ($inst) { '✅ Installed' } else { '❌ Missing' } # Remote gallery info try { $remote = Find-Module -Name $mod.Name -ErrorAction Stop $remoteVer = [version]$remote.Version } catch { $remoteVer = $null } $outdated = if ($instVer -and $remoteVer) { $remoteVer -gt $instVer } else { $false } [PSCustomObject]@{ Name = $mod.Name Status = $status InstalledVersion = if ($instVer) { $instVer.ToString() } else { '<none>' } LatestVersion = if ($remoteVer) { $remoteVer.ToString() } else { '<unknown>' } Outdated = if ($outdated) { '⚠️ Yes' } else { '😊 No' } } } # Output as table by default $results | Format-Table -AutoSize } |