# OpenFang Installer for Windows # https://openfang.sh $ErrorActionPreference = "Stop" $Repo = "RightNow-AI/openfang" $InstallDir = Join-Path $env:USERPROFILE ".openfang" $BinDir = Join-Path $InstallDir "bin" $Binary = "openfang.exe" function Write-Step($msg) { Write-Host " openfang " -ForegroundColor Cyan -NoNewline Write-Host $msg } function Write-Err($msg) { Write-Host " openfang " -ForegroundColor Cyan -NoNewline Write-Host "error: " -ForegroundColor Red -NoNewline Write-Host $msg } function Main { Write-Host "" Write-Step "Installing OpenFang for Windows..." Write-Host "" # Detect architecture $Arch = if ([Environment]::Is64BitOperatingSystem) { $cpu = (Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue).Architecture if ($cpu -eq 12) { "arm64" } else { "x64" } } else { Write-Err "32-bit systems are not supported" exit 1 } switch ($Arch) { "x64" { $Target = "x86_64-pc-windows-msvc" } "arm64" { $Target = "aarch64-pc-windows-msvc" } default { Write-Err "Unsupported architecture: $Arch" exit 1 } } $Url = "https://github.com/$Repo/releases/latest/download/openfang-$Target.zip" Write-Step "Detected: Windows $Arch -> $Target" Write-Step "Downloading from: $Url" # Create temp directory $TmpDir = Join-Path ([System.IO.Path]::GetTempPath()) ("openfang-" + [System.Guid]::NewGuid().ToString("N").Substring(0, 8)) New-Item -ItemType Directory -Path $TmpDir -Force | Out-Null $ZipPath = Join-Path $TmpDir "openfang.zip" try { # Download [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 try { Invoke-WebRequest -Uri $Url -OutFile $ZipPath -UseBasicParsing } catch { if ($_.Exception.Response.StatusCode -eq 404) { Write-Err "Release not found for $Target. Check https://github.com/$Repo/releases" } else { Write-Err "Download failed: $_" } exit 1 } # Verify download size $FileSize = (Get-Item $ZipPath).Length if ($FileSize -lt 1000) { Write-Err "Downloaded file is too small ($FileSize bytes) - likely not a valid release" exit 1 } Write-Step "Extracting..." # Extract Expand-Archive -Path $ZipPath -DestinationPath $TmpDir -Force # Find the binary $BinFile = Get-ChildItem -Path $TmpDir -Recurse -Filter $Binary | Select-Object -First 1 if (-not $BinFile) { Write-Err "Could not find $Binary in archive" exit 1 } # Install New-Item -ItemType Directory -Path $BinDir -Force | Out-Null $Dest = Join-Path $BinDir $Binary Copy-Item -Path $BinFile.FullName -Destination $Dest -Force # Verify it runs try { $Ver = & $Dest --version 2>$null Write-Step "Installed: $Ver" } catch { Write-Step "Installed to: $Dest" } # Add to user PATH $CurrentPath = [Environment]::GetEnvironmentVariable("Path", "User") if ($CurrentPath -notlike "*$BinDir*") { [Environment]::SetEnvironmentVariable("Path", "$BinDir;$CurrentPath", "User") $env:Path = "$BinDir;$env:Path" Write-Step "Added to user PATH" } Write-Host "" Write-Step "OpenFang installed successfully!" Write-Host "" Write-Step "Run: openfang init" Write-Step "Docs: https://openfang.sh/docs" Write-Host "" # Check if reachable $check = Get-Command openfang -ErrorAction SilentlyContinue if (-not $check) { Write-Step "Note: restart your terminal for PATH changes to take effect" Write-Host "" } } finally { if (Test-Path $TmpDir) { Remove-Item -Path $TmpDir -Recurse -Force -ErrorAction SilentlyContinue } } } Main