src/Set-CciGetConfig.ps1

function Set-CciGetConfig {
<#
.SYNOPSIS
    Add, update, or remove a feed in the user's cciget configuration.
.PARAMETER Name
    Tenant short-name for the feed (e.g. 'ccidev', 'ccigen').
.PARAMETER Url
    Azure Artifacts NuGet v3 index URL.
.PARAMETER TenantId
    Entra tenant id that owns the feed (used by the Azure Artifacts Credential Provider).
.PARAMETER Description
    Optional human-readable description.
.PARAMETER Disable
    Mark the feed as disabled (kept in config but skipped by Connect-CciGet / Find-CciModule).
.PARAMETER Remove
    Remove the feed from config entirely.
.PARAMETER SetDefault
    Make this the default feed for Install-CciModule when -Tenant is omitted.
.EXAMPLE
    Set-CciGetConfig -Name ccigen -Url 'https://pkgs.dev.azure.com/.../feed-modules-ccigen/nuget/v3/index.json' -TenantId '<guid>'
#>

    [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Upsert')]
    param(
        [Parameter(Mandatory)]
        [string]$Name,

        [Parameter(ParameterSetName = 'Upsert')]
        [string]$Url,

        [Parameter(ParameterSetName = 'Upsert')]
        [string]$TenantId,

        [Parameter(ParameterSetName = 'Upsert')]
        [string]$Description,

        [Parameter(ParameterSetName = 'Upsert')]
        [switch]$Disable,

        [Parameter(ParameterSetName = 'Remove', Mandatory)]
        [switch]$Remove,

        [switch]$SetDefault
    )

    $path = _Get-CciGetConfigPath
    $dir  = Split-Path -Parent $path
    if (-not (Test-Path -LiteralPath $dir)) {
        New-Item -ItemType Directory -Path $dir -Force | Out-Null
    }

    $cfg = Get-CciGetConfig
    # ConvertFrom-Json yields PSCustomObject + Object[]; normalize to a plain
    # ArrayList so we can add/remove without rebuilding the whole thing.
    $feeds = New-Object System.Collections.ArrayList
    foreach ($f in @($cfg.feeds)) { [void]$feeds.Add($f) }

    $existing = $feeds | Where-Object { $_.name -eq $Name } | Select-Object -First 1

    if ($Remove) {
        if ($existing) {
            if ($PSCmdlet.ShouldProcess("$Name", 'Remove feed')) {
                [void]$feeds.Remove($existing)
            }
        } else {
            Write-Warning "cciget: feed '$Name' not found in config; nothing to remove."
        }
    } else {
        if ($existing) {
            if ($PSBoundParameters.ContainsKey('Url'))         { $existing.url         = $Url }
            if ($PSBoundParameters.ContainsKey('TenantId'))    { $existing.tenantId    = $TenantId }
            if ($PSBoundParameters.ContainsKey('Description')) { $existing.description = $Description }
            if ($PSBoundParameters.ContainsKey('Disable'))     { $existing.enabled     = -not $Disable.IsPresent }
        } else {
            if (-not $Url -or -not $TenantId) {
                throw "cciget: -Url and -TenantId are required when adding a new feed."
            }
            $new = [pscustomobject]@{
                name        = $Name
                url         = $Url
                tenantId    = $TenantId
                description = $Description
                enabled     = -not $Disable.IsPresent
            }
            [void]$feeds.Add($new)
        }
    }

    $defaultFeed = $cfg.defaultFeed
    if ($SetDefault) { $defaultFeed = $Name }
    # If we removed the default, fall back to first remaining enabled feed.
    if ($Remove -and $defaultFeed -eq $Name) {
        $defaultFeed = ($feeds | Where-Object { $_.enabled } | Select-Object -First 1).name
    }

    $out = [pscustomobject]@{
        defaultFeed = $defaultFeed
        feeds       = $feeds.ToArray()
    }

    if ($PSCmdlet.ShouldProcess($path, 'Write cciget config')) {
        $out | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $path -Encoding UTF8
    }

    $out
}