Private/Add-KadenWorkspaceSeed.ps1

function Add-KadenWorkspaceSeed {
    <#
    .SYNOPSIS
        Create missing doc scaffolds and Stack starter files. Never overwrite.
    .DESCRIPTION
        Copies module seed files into the child repository only when the
        destination is absent. The copy holds the update lock, re-checks that
        the destination is still absent, stages to a temp file, and moves that
        file into place without replacing an existing starter. Update does not
        call this function, so an existing starter stays child-owned.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$ChildRoot,

        [Parameter(Mandatory = $true)]
        [string]$Stack
    )

    $seedRoot = Join-Path $script:KadenModuleRoot 'Seeds'
    $transactionId = [guid]::NewGuid().ToString('N')
    $lockPath = Join-Path $ChildRoot (Join-Path '.kaden' (Join-Path 'transactions' 'update.lock'))
    Lock-KadenUpdate -LockPath $lockPath -TransactionId $transactionId
    try {
        foreach ($relative in @(Get-KadenWorkspaceSeedRelativePath -Stack $Stack)) {
            $destination = Resolve-KadenContainedPath -Root $ChildRoot -RelativePath $relative
            if (Test-Path -LiteralPath $destination) {
                continue
            }

            $packageRelative = ConvertTo-KadenGalleryRelativePath -RelativePath $relative
            $source = Resolve-KadenContainedPath -Root $seedRoot -RelativePath $packageRelative
            if (-not (Test-Path -LiteralPath $source)) {
                throw "KDN-SEED-MISSING: starter seed is not in the module ('$relative')."
            }

            $destinationDirectory = Split-Path -Parent $destination
            if (-not (Test-Path -LiteralPath $destinationDirectory)) {
                New-Item -ItemType Directory -Path $destinationDirectory -Force | Out-Null
            }

            $destination = Resolve-KadenContainedPath -Root $ChildRoot -RelativePath $relative
            if (Test-Path -LiteralPath $destination) {
                continue
            }

            $tempPath = Join-Path $destinationDirectory ('.' + [guid]::NewGuid().ToString('N') + '.kaden-seed-tmp')
            try {
                Copy-Item -LiteralPath $source -Destination $tempPath
                $destination = Resolve-KadenContainedPath -Root $ChildRoot -RelativePath $relative
                if (Test-Path -LiteralPath $destination) {
                    continue
                }
                Move-Item -LiteralPath $tempPath -Destination $destination
            }
            finally {
                if (Test-Path -LiteralPath $tempPath) {
                    Remove-Item -LiteralPath $tempPath -Force -ErrorAction SilentlyContinue
                }
            }
        }
    }
    finally {
        Remove-Item -LiteralPath $lockPath -Force -ErrorAction SilentlyContinue
    }
}