scripts/modules/shared/loop-functions.ps1
# strangeloop Setup - Shared Loop Functions # Version: 1.0.0 # Loop management and platform detection functions function Get-KnownLoops { <# .SYNOPSIS Returns the registry of all known strangeloop loops with their platform requirements .DESCRIPTION Central registry of all available loops and their platform requirements. This is the single source of truth for loop definitions. #> return @{ # WSL-based loops 'python-mcp-server' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Model Context Protocol server in Python' } 'python-cli' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Command-line application in Python' } 'python-semantic-kernel-agent' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Semantic Kernel agent in Python' } 'flask-linux' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Flask web application for Linux' } 'langgraph-agent' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'LangGraph agent application' } 'csharp-mcp-server' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Model Context Protocol server in C#' } 'csharp-semantic-kernel-agent' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Semantic Kernel agent in C#' } 'csharp-dotnet-aspire' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = '.NET Aspire cloud application' } # Windows-based loops 'asp-dotnet-framework-api' = @{ Platform = 'Windows'; RequiresWSL = $false; RequiresWindows = $true; Description = 'ASP.NET Framework API' } 'ads-snr-basic' = @{ Platform = 'Windows'; RequiresWSL = $false; RequiresWindows = $true; Description = 'Ads SNR basic service' } 'flask-windows' = @{ Platform = 'Windows'; RequiresWSL = $false; RequiresWindows = $true; Description = 'Flask web application for Windows' } } } function Test-LoopExists { <# .SYNOPSIS Tests if a loop name exists in the known loops registry .PARAMETER LoopName The name of the loop to validate #> param( [Parameter(Mandatory)] [string]$LoopName ) $knownLoops = Get-KnownLoops return $knownLoops.ContainsKey($LoopName) } function Get-LoopRequirements { <# .SYNOPSIS Gets platform requirements for a specific loop .PARAMETER LoopName The name of the loop to get requirements for .RETURNS Hashtable with Platform, RequiresWSL, RequiresWindows properties, or $null if loop not found #> param( [Parameter(Mandatory)] [string]$LoopName ) $knownLoops = Get-KnownLoops if ($knownLoops.ContainsKey($LoopName)) { return $knownLoops[$LoopName] } return $null } function Test-LoopAndGetRequirements { <# .SYNOPSIS Validates a loop name and returns discovery-like results .PARAMETER LoopName The name of the loop to validate .RETURNS Hashtable with discovery results if valid, $null if invalid #> param( [Parameter(Mandatory)] [string]$LoopName ) $knownLoops = Get-KnownLoops if ($knownLoops.ContainsKey($LoopName)) { $requirements = $knownLoops[$LoopName] Write-Host "✓ Pre-validated loop: $LoopName" -ForegroundColor Green Write-Host "✓ Target platform: $($requirements.Platform)" -ForegroundColor Green return @{ Success = $true SelectedLoop = $LoopName EnvironmentRequirements = @{ RequiresWSL = $requirements.RequiresWSL RequiresWindows = $requirements.RequiresWindows SelectedLoop = $LoopName Platform = $requirements.Platform } AvailableLoops = @($knownLoops.Keys) SkippedDiscovery = $true } } else { Write-Error "Loop '$LoopName' not found in the known loops registry." Write-Host "" Write-Host "Available loops:" -ForegroundColor Yellow $knownLoops.Keys | Sort-Object | ForEach-Object { $loop = $knownLoops[$_] Write-Host " • $_ (Platform: $($loop.Platform)) - $($loop.Description)" -ForegroundColor Gray } Write-Host "" Write-Host "Usage:" -ForegroundColor Yellow Write-Host " .\setup-strangeloop.ps1 -loop-name 'csharp-mcp-server' # Use correct loop name" -ForegroundColor Gray Write-Host " .\setup-strangeloop.ps1 # Interactive selection" -ForegroundColor Gray Write-Host " .\setup-strangeloop.ps1 -help # Show all options" -ForegroundColor Gray Write-Host "" return $null } } function Get-LoopsByPlatform { <# .SYNOPSIS Gets loops grouped by platform .PARAMETER Platform Optional platform filter ('Windows' or 'WSL') .RETURNS Array of loop names for the specified platform, or hashtable grouped by platform #> param( [ValidateSet('Windows', 'WSL')] [string]$Platform ) $knownLoops = Get-KnownLoops if ($Platform) { return $knownLoops.Keys | Where-Object { $knownLoops[$_].Platform -eq $Platform } } else { $platforms = @{ 'Windows' = @() 'WSL' = @() } foreach ($loopName in $knownLoops.Keys) { $loop = $knownLoops[$loopName] $platforms[$loop.Platform] += $loopName } return $platforms } } function Test-PathPlatformCompatibility { <# .SYNOPSIS Tests if a project path is compatible with a loop's platform requirements .PARAMETER ProjectPath The project path to validate .PARAMETER LoopName The loop name to check compatibility for .RETURNS Hashtable with IsCompatible, SuggestedPath, and Platform properties #> param( [Parameter(Mandatory)] [string]$ProjectPath, [Parameter(Mandatory)] [string]$LoopName ) $requirements = Get-LoopRequirements -LoopName $LoopName if (-not $requirements) { throw "Unknown loop: $LoopName" } $isWindowsPath = $ProjectPath -match '^[A-Za-z]:\\' $isWSLPath = $ProjectPath.StartsWith('/') -or $ProjectPath.Contains('/home/') $requiresWSL = $requirements.RequiresWSL $result = @{ IsCompatible = $true SuggestedPath = $ProjectPath Platform = $requirements.Platform RequiresWSL = $requiresWSL } if ($requiresWSL -and $isWindowsPath) { # WSL loop with Windows path - suggest WSL path $projectName = Split-Path $ProjectPath -Leaf $result.IsCompatible = $false try { $wslUser = & wsl -- whoami 2>$null if ($wslUser) { $result.SuggestedPath = "/home/$($wslUser.Trim())/AdsSnR_Containers/services/$projectName" } else { $result.SuggestedPath = "/home/\$USER/AdsSnR_Containers/services/$projectName" } } catch { $result.SuggestedPath = "/home/\$USER/AdsSnR_Containers/services/$projectName" } } elseif (-not $requiresWSL -and $isWSLPath) { # Windows loop with WSL path - suggest Windows path $projectName = Split-Path $ProjectPath -Leaf $result.IsCompatible = $false $result.SuggestedPath = "Q:\src\AdsSnR_Containers\services\$projectName" } return $result } |