functions/Get-EndjinGists.ps1

# <copyright file="Get-EndjinGists.ps1" company="Endjin Limited">
# Copyright (c) Endjin Limited. All rights reserved.
# </copyright>

<#
.SYNOPSIS
    Lists all available gists from the gist registry.
 
.DESCRIPTION
    The Get-EndjinGists function reads the gist-map configuration file and displays
    information about all available gists. By default, it outputs a human-readable
    grouped text summary. Use the -PassThru switch to return PSCustomObjects suitable
    for pipeline processing.
 
    You can optionally filter by Group and Name. Both parameters support positional
    binding, so you can write: Get-EndjinGists devcontainer ai-agent
 
.PARAMETER Group
    When specified, filters the output to only show gists in the given group.
 
.PARAMETER Name
    When specified together with Group, filters the output to only show the gist
    with the given name within that group. Requires Group to be specified.
 
.PARAMETER PassThru
    When specified, outputs PSCustomObjects instead of a grouped text summary.
 
.PARAMETER GistMapPath
    The path to a 'Gist Map' configuration file. Defaults to the configuration file
    distributed with the module (gist-map.yml).
 
.EXAMPLE
    Get-EndjinGists
 
    Displays a grouped text summary of all available gists.
 
.EXAMPLE
    Get-EndjinGists devcontainer
 
    Displays only gists in the 'devcontainer' group.
 
.EXAMPLE
    Get-EndjinGists devcontainer ai-agent
 
    Displays only the 'ai-agent' gist in the 'devcontainer' group.
 
.EXAMPLE
    Get-EndjinGists -PassThru
 
    Returns all available gists as PSCustomObjects with Group, Name, Description, Source, and Ref properties.
 
.EXAMPLE
    Get-EndjinGists -PassThru | Where-Object { $_.Group -eq 'llm-kb' }
 
    Returns only gists in the 'llm-kb' group.
 
.NOTES
    The gist-map.yml file contains the registry of all available gists organized by group.
#>

function Get-EndjinGists {
    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param (
        [Parameter(Position=0)]
        [string] $Group,

        [Parameter(Position=1)]
        [string] $Name,

        [Parameter()]
        [switch] $PassThru,

        [Parameter()]
        [ValidateScript({Test-Path $_ -PathType Leaf})]
        [string] $GistMapPath = (Join-Path $PSScriptRoot '..' 'gist-map.yml')
    )

    begin {
        Set-StrictMode -Version Latest
    }

    process {
        $gistMapContent = Get-Content -Path $GistMapPath -Raw
        $gistMap = ConvertFrom-Yaml $gistMapContent

        # Filter by Group and/or Name if specified
        if ($Name -and -not $Group) {
            Write-Warning "The -Name parameter requires -Group to be specified. Use: Get-EndjinGists -Group <group> -Name <name>"
            return
        }

        if ($Group) {
            if (-not $gistMap.ContainsKey($Group)) {
                Write-Warning "Group '$Group' not found. Use Get-EndjinGists to see available groups."
                return
            }

            if ($Name) {
                $matchingGist = $gistMap[$Group] | Where-Object { $_.name -eq $Name }
                if (-not $matchingGist) {
                    Write-Warning "Gist '$Name' not found in group '$Group'. Use Get-EndjinGists $Group to see available gists."
                    return
                }
                $gistMap = @{ $Group = @($matchingGist) }
            }
            else {
                $gistMap = @{ $Group = $gistMap[$Group] }
            }
        }

        if (!$PassThru) {
            Write-Output "Available Gists:"
            Write-Output ""
            foreach ($group in ($gistMap.Keys | Sort-Object)) {
                Write-Output "🗂️ $group"
                foreach ($gist in $gistMap[$group]) {
                    $desc = if ($gist.ContainsKey('description')) { $gist.description } else { $null }
                    $descText = if ($desc) { " - $desc" } else { "" }
                    Write-Output " 📑 $($gist.name)$descText"
                }
                Write-Output ""
            }
        }
        else {
            $gists = [System.Collections.Generic.List[PSCustomObject]]::new()
            foreach ($group in $gistMap.Keys) {
                foreach ($gist in $gistMap[$group]) {
                    $desc = if ($gist.ContainsKey('description')) { $gist.description } else { $null }
                    $gists.Add([PSCustomObject]@{
                        Group       = $group
                        Name        = $gist.name
                        Description = $desc
                        Source      = $gist.source
                        Ref         = $gist.ref
                    })
                }
            }
            return $gists
        }
    }
}
New-Alias -Name gists -Value Get-EndjinGists