Private/Read-KadenOperatorModelFile.ps1
|
function Read-KadenOperatorModelFile { <# .SYNOPSIS Read the operator model file without writing it. .DESCRIPTION A missing file is a skip. A file that cannot be parsed is a failure. Known host stacks are cursor, copilot, and claude. Extra fields are ignored. An empty model value is a per-stack skip. The operator file is never modified. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$LiteralPath ) $known = @('cursor', 'copilot', 'claude') if (-not (Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { return [pscustomobject]@{ Status = 'skipped' Reason = 'no operator file exists' Reports = @(New-KadenUntunedStackReport -Names $known) } } try { $raw = [System.IO.File]::ReadAllText($LiteralPath) $json = $raw | ConvertFrom-Json } catch { return [pscustomobject]@{ Status = 'failed' Reason = "operator file cannot be read or parsed: $($_.Exception.Message)" Reports = @() } } if ($null -eq $json -or $null -eq $json.PSObject.Properties['stacks']) { return [pscustomobject]@{ Status = 'failed' Reason = 'operator file cannot be read or parsed: stacks object is missing' Reports = @() } } $stacksValue = $json.stacks if ($null -eq $stacksValue -or $stacksValue -isnot [System.Management.Automation.PSCustomObject]) { return [pscustomobject]@{ Status = 'failed' Reason = 'operator file cannot be read or parsed: stacks must be an object' Reports = @() } } $reports = New-Object System.Collections.Generic.List[object] $declared = @{} foreach ($prop in @($stacksValue.PSObject.Properties)) { $declared[$prop.Name] = $prop.Value } foreach ($name in $known) { if (-not $declared.ContainsKey($name)) { $reports.Add((New-KadenStackReport -Name $name -Disposition 'untuned' -Model $null -Reason 'no operator entry - left untuned')) continue } $reports.Add((ConvertTo-KadenStackChoice -Name $name -Entry $declared[$name])) } foreach ($name in @($declared.Keys)) { if ($known -contains $name) { continue } $reports.Add((New-KadenStackReport -Name $name -Disposition 'skipped' -Model $null -Reason 'unknown host stack - left untouched')) } $reportArray = @($reports.ToArray()) $tuned = @($reportArray | Where-Object { $_.Disposition -eq 'tuned' }) $status = if ($tuned.Count -gt 0) { 'ready' } else { 'skipped' } $reason = if ($status -eq 'ready') { 'operator choices are ready to apply' } else { 'no operator entry - left untuned' } return [pscustomobject]@{ Status = $status Reason = $reason Reports = $reportArray } } |