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 GistMapUrl The URL to fetch the gist-map.yml file from via HTTP. Defaults to the endjin-gists repository on GitHub. When GistMapPath is specified, remote fetching is skipped. .PARAMETER GistMapPath The path to a local 'Gist Map' configuration file. When specified, remote fetching is skipped and this file is used directly. .PARAMETER GistMapRepo A GitHub repository in 'owner/repo' format (e.g., 'endjin/endjin-gists') that hosts a gist-map file. When specified, the function constructs an HTTP URL and a vendir git source from the repo, ref, and path parameters. .PARAMETER GistMapRef The git reference (branch, tag, or commit) to use when fetching the gist-map from GistMapRepo. Defaults to 'main'. .PARAMETER GistMapRepoPath The file path within the GistMapRepo repository to the gist-map file. Defaults to '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. .EXAMPLE Get-EndjinGists -GistMapRepo "myorg/my-gists" Lists all available gists from a gist-map hosted in a different GitHub repository. .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()] [string] $GistMapUrl = $script:DefaultGistMapUrl, [Parameter()] [string] $GistMapPath, [Parameter()] [ValidatePattern('^[^/]+/[^/]+$')] [string] $GistMapRepo, [Parameter()] [string] $GistMapRef = 'main', [Parameter()] [string] $GistMapRepoPath = 'gist-map.yml', [Parameter()] [switch] $NoCache ) begin { Set-StrictMode -Version Latest } process { if ($GistMapPath) { if (-not (Test-Path $GistMapPath -PathType Leaf)) { throw "GistMapPath '$GistMapPath' does not exist." } $gistMapContent = Get-Content -Path $GistMapPath -Raw $gistMap = ConvertFrom-Yaml $gistMapContent } else { if ($GistMapRepo) { $effectiveUrl = "https://raw.githubusercontent.com/$GistMapRepo/$GistMapRef/$GistMapRepoPath" $effectiveGitSource = @{ url = "https://github.com/$GistMapRepo.git" ref = $GistMapRef path = $GistMapRepoPath } } else { $effectiveUrl = $GistMapUrl $effectiveGitSource = $script:DefaultGistMapGitSource } # Resolve the path here to ensure the ScriptRoot portion of the cache key is consistent with other scenarios (e.g. the tab completers) $gistMap = _Get-GistMapData -ScriptRoot (Resolve-Path (Join-Path $PSScriptRoot '..')).Path ` -GistMapUrl $effectiveUrl ` -GistMapGitSource $effectiveGitSource ` -NoCache:$NoCache if (-not $gistMap) { Write-Warning "Unable to load gist-map from any source." return } # Update the defaults so subsequent commands do not need to re-specify the gist-map override arguments $script:DefaultGistMapUrl = $effectiveUrl $script:DefaultGistMapGitSource = $effectiveGitSource Write-Verbose "Updating defaults:`nDefaultGistMapUrl=$script:DefaultGistMapUrl`nDefaultGistMapGitSource=$($script:DefaultGistMapGitSource | ConvertTo-Json)" } # 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 -Force |