Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path Set-Location $scriptDir function Test-EnvVarLine { param( [Parameter(Mandatory = $true)][string]$FilePath, [Parameter(Mandatory = $true)][string]$Name ) if (-not (Test-Path -LiteralPath $FilePath)) { return $false } return [bool](Select-String -Path $FilePath -Pattern ("^\s*" + [regex]::Escape($Name) + "=") -Quiet) } function Resolve-PythonExecutable { $venvPython = Join-Path $scriptDir ".venv\Scripts\python.exe" if (Test-Path -LiteralPath $venvPython) { return $venvPython } $pythonCmd = Get-Command python -ErrorAction SilentlyContinue if ($null -ne $pythonCmd -and (Test-Path -LiteralPath $pythonCmd.Source)) { return $pythonCmd.Source } $candidatePyLaunchers = @() $pyFromPath = Get-Command py -ErrorAction SilentlyContinue if ($null -ne $pyFromPath -and (Test-Path -LiteralPath $pyFromPath.Source)) { $candidatePyLaunchers += $pyFromPath.Source } $candidatePyLaunchers += "C:\Windows\py.exe" if ($scriptDir -match "^[A-Za-z]:\\Users\\[^\\]+") { $repoUserHome = $Matches[0] $candidatePyLaunchers += (Join-Path $repoUserHome "AppData\Local\Programs\Python\Launcher\py.exe") } foreach ($pyLauncher in ($candidatePyLaunchers | Select-Object -Unique)) { if (-not (Test-Path -LiteralPath $pyLauncher)) { continue } try { $resolved = (& $pyLauncher -3 -c "import sys; print(sys.executable)" 2>$null | Select-Object -Last 1).Trim() if ($resolved -and (Test-Path -LiteralPath $resolved)) { return $resolved } } catch { continue } } $candidatePythonPaths = @() if ($scriptDir -match "^[A-Za-z]:\\Users\\[^\\]+") { $repoUserHome = $Matches[0] $pythonBase = Join-Path $repoUserHome "AppData\Local\Programs\Python" if (Test-Path -LiteralPath $pythonBase) { $candidatePythonPaths += (Get-ChildItem -LiteralPath $pythonBase -Directory -ErrorAction SilentlyContinue | Sort-Object Name -Descending | ForEach-Object { Join-Path $_.FullName "python.exe" }) } } $candidatePythonPaths += @( "C:\Python314\python.exe", "C:\Python313\python.exe", "C:\Python312\python.exe", "C:\Python311\python.exe", "C:\Program Files\Python314\python.exe", "C:\Program Files\Python313\python.exe", "C:\Program Files\Python312\python.exe", "C:\Program Files\Python311\python.exe" ) foreach ($candidate in ($candidatePythonPaths | Select-Object -Unique)) { if (Test-Path -LiteralPath $candidate) { return $candidate } } throw "Python was not found. Install Python 3.11+ system-wide, or create .venv in the repo root." } $pythonExe = Resolve-PythonExecutable $envFile = Join-Path $scriptDir ".env" if (-not (Test-Path -LiteralPath $envFile)) { Write-Warning ".env was not found at $envFile. Server startup may fail if required vars are missing." } else { if (-not (Test-EnvVarLine -FilePath $envFile -Name "OPENAI_API_KEY")) { Write-Warning ".env is missing OPENAI_API_KEY." } if (-not (Test-EnvVarLine -FilePath $envFile -Name "SCREENJOB_TOKEN")) { Write-Warning ".env is missing SCREENJOB_TOKEN." } } Write-Host "Starting ScreenJob backend with Python: $pythonExe" -ForegroundColor Cyan & $pythonExe main.py server