Private/Get-GraphParityIndex.ps1

function Get-GraphParityIndex {
    <#
    .SYNOPSIS
        Loads and caches the Graph API / SDK parity presence and module-hint indexes.
    .DESCRIPTION
        Reads data/graph-parity-presence.json and data/graph-parity-module-hints.json, produced
        by scripts/sync-graph-openapi-parity.ps1, so Get-GraphParity can answer "does this
        endpoint exist in the Graph OpenAPI surface, and in which version(s)" without loading
        the full ~17 MB of raw OpenAPI source (never persisted) or the full command catalog.

        Returns $null when the parity index has not been generated yet (older catalog syncs),
        so Get-GraphParity can degrade with a clear warning instead of throwing.
    #>

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

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

    $paths = Get-GraphCatalogPath
    if (-not $paths.ParityPresencePath) {
        Write-Verbose 'GraphShell parity index (graph-parity-presence.json) not found; Get-GraphParity is unavailable until scripts/sync-graph-openapi-parity.ps1 runs.'
        return $null
    }

    Write-Verbose "Loading GraphShell parity presence index from $($paths.ParityPresencePath)"
    $presenceRaw = Get-Content -LiteralPath $paths.ParityPresencePath -Raw | ConvertFrom-Json

    $presence = [System.Collections.Generic.Dictionary[string, object]]::new([System.StringComparer]::OrdinalIgnoreCase)
    foreach ($pathProperty in $presenceRaw.presence.PSObject.Properties) {
        $methodBitmask = [System.Collections.Generic.Dictionary[string, int]]::new([System.StringComparer]::OrdinalIgnoreCase)
        foreach ($methodProperty in $pathProperty.Value.PSObject.Properties) {
            $methodBitmask[$methodProperty.Name] = [int]$methodProperty.Value
        }
        $presence[$pathProperty.Name] = $methodBitmask
    }

    $moduleHints = [System.Collections.Generic.Dictionary[string, string]]::new([System.StringComparer]::OrdinalIgnoreCase)
    if ($paths.ParityModuleHintsPath) {
        Write-Verbose "Loading GraphShell parity module hints from $($paths.ParityModuleHintsPath)"
        $hintsRaw = Get-Content -LiteralPath $paths.ParityModuleHintsPath -Raw | ConvertFrom-Json
        foreach ($hintProperty in $hintsRaw.hints.PSObject.Properties) {
            $moduleHints[$hintProperty.Name] = $hintProperty.Value
        }
    }

    $script:GraphParityIndexCache = [pscustomobject]@{
        Presence    = $presence
        ModuleHints = $moduleHints
        GeneratedAt = $presenceRaw.source.generatedAt
    }

    return $script:GraphParityIndexCache
}