Private/Get-GraphRenameIndex.ps1

function Get-GraphRenameIndex {
    <#
    .SYNOPSIS
        Loads and caches the official cmdlet rename catalog.
    .DESCRIPTION
        Reads data/graph-command-renames.json once per session and indexes it by old and by
        new cmdlet name so Get-GraphMapping/Get-GraphDetail can enrich results with
        breaking-change rename information from the official SDK changelog.
    #>

    [CmdletBinding()]
    [OutputType([pscustomobject])]
    param(
        [switch]$Force
    )

    if (-not $Force -and $script:GraphRenameCache) {
        return $script:GraphRenameCache
    }

    $paths = Get-GraphCatalogPath
    if (-not $paths.RenamesPath) {
        throw "GraphShell could not locate graph-command-renames.json. Run scripts/sync-graph-command-index.ps1 or set `$env:GRAPHSHELL_CATALOG_PATH."
    }
    Write-Verbose "Loading GraphShell rename catalog from $($paths.RenamesPath)"

    $raw = Get-Content -LiteralPath $paths.RenamesPath -Raw
    $parsed = $raw | ConvertFrom-Json

    $byOldCmdlet = [System.Collections.Generic.Dictionary[string, object]]::new([System.StringComparer]::OrdinalIgnoreCase)
    $byNewCmdlet = [System.Collections.Generic.Dictionary[string, System.Collections.Generic.List[object]]]::new([System.StringComparer]::OrdinalIgnoreCase)

    foreach ($record in $parsed.records) {
        $byOldCmdlet[$record.oldCmdlet] = $record

        if (-not $byNewCmdlet.ContainsKey($record.newCmdlet)) {
            $byNewCmdlet[$record.newCmdlet] = [System.Collections.Generic.List[object]]::new()
        }
        $byNewCmdlet[$record.newCmdlet].Add($record)
    }

    $script:GraphRenameCache = [pscustomobject]@{
        Source      = $parsed.source
        Records     = $parsed.records
        ByOldCmdlet = $byOldCmdlet
        ByNewCmdlet = $byNewCmdlet
    }

    return $script:GraphRenameCache
}