psmux 0.3.1

Terminal multiplexer for Windows - tmux alternative for PowerShell and Windows Terminal
# psmux installation script for Windows
# Run as: irm https://raw.githubusercontent.com/marlocarlo/psmux/master/scripts/install.ps1 | iex
# Or locally: .\scripts\install.ps1

param(
    [string]$InstallDir = "$env:LOCALAPPDATA\psmux",
    [switch]$Force
)

$ErrorActionPreference = 'Stop'

Write-Host "psmux installer" -ForegroundColor Cyan
Write-Host "===============" -ForegroundColor Cyan

# Determine if we're installing from local build or downloading
# When run via iex, $PSScriptRoot is empty
$LocalBuild = $false
if ($PSScriptRoot -and (Test-Path "$PSScriptRoot\..\target\release\psmux.exe")) {
    $LocalBuild = $true
    $RepoRoot = Split-Path -Parent $PSScriptRoot
}

if ($LocalBuild) {
    Write-Host "Installing from local build..." -ForegroundColor Yellow
    $SourceDir = "$RepoRoot\target\release"
} else {
    Write-Host "Downloading latest release..." -ForegroundColor Yellow
    
    # Detect architecture
    $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
    switch ($arch) {
        "X64"  { $archLabel = "x64";   $assetPattern = "windows-x64" }
        "X86"  { $archLabel = "x86";   $assetPattern = "windows-x86" }
        "Arm64"{ $archLabel = "arm64"; $assetPattern = "windows-arm64" }
        default {
            Write-Host "Unsupported architecture: $arch" -ForegroundColor Red
            exit 1
        }
    }
    Write-Host "Detected architecture: $archLabel" -ForegroundColor Cyan
    
    # Get latest release info
    $ReleasesUrl = "https://api.github.com/repos/marlocarlo/psmux/releases/latest"
    try {
        $Release = Invoke-RestMethod -Uri $ReleasesUrl -Headers @{ "User-Agent" = "psmux-installer" }
        $Asset = $Release.assets | Where-Object { $_.name -match "$assetPattern.*zip" } | Select-Object -First 1
        
        # Fallback: if no arch-specific asset, try x64 (Windows on ARM can run x64 via emulation)
        if (-not $Asset -and $archLabel -eq "arm64") {
            Write-Host "No ARM64 build found, falling back to x64 (runs via emulation)..." -ForegroundColor Yellow
            $Asset = $Release.assets | Where-Object { $_.name -match "windows-x64.*zip" } | Select-Object -First 1
        }
        
        if (-not $Asset) {
            throw "No compatible release asset found for $archLabel"
        }
        
        $DownloadUrl = $Asset.browser_download_url
        $TempZip = "$env:TEMP\psmux-download.zip"
        $TempExtract = "$env:TEMP\psmux-extract"
        
        Write-Host "Downloading from: $DownloadUrl"
        Invoke-WebRequest -Uri $DownloadUrl -OutFile $TempZip
        
        # Extract
        if (Test-Path $TempExtract) { Remove-Item -Recurse -Force $TempExtract }
        Expand-Archive -Path $TempZip -DestinationPath $TempExtract -Force
        
        $SourceDir = $TempExtract
        
    } catch {
        Write-Host "Error downloading release: $_" -ForegroundColor Red
        Write-Host "Try installing from a local build instead:" -ForegroundColor Yellow
        Write-Host "  cargo build --release" -ForegroundColor White
        Write-Host "  .\scripts\install.ps1" -ForegroundColor White
        exit 1
    }
}

# Create install directory
if (-not (Test-Path $InstallDir)) {
    Write-Host "Creating install directory: $InstallDir"
    New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
}

# Copy binaries
$Binaries = @("psmux.exe", "pmux.exe", "tmux.exe")
foreach ($bin in $Binaries) {
    $src = Join-Path $SourceDir $bin
    $dst = Join-Path $InstallDir $bin
    
    if (Test-Path $src) {
        Write-Host "  Installing $bin..." -ForegroundColor Green
        Copy-Item -Path $src -Destination $dst -Force
    } else {
        Write-Host "  Warning: $bin not found" -ForegroundColor Yellow
    }
}

# Add to PATH if not already there
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($UserPath -notlike "*$InstallDir*") {
    Write-Host "Adding to PATH..." -ForegroundColor Green
    $NewPath = "$UserPath;$InstallDir"
    [Environment]::SetEnvironmentVariable("Path", $NewPath, "User")
    $env:Path = "$env:Path;$InstallDir"
    Write-Host "  Added $InstallDir to user PATH" -ForegroundColor Green
} else {
    Write-Host "Already in PATH" -ForegroundColor Gray
}

# Cleanup temp files if downloaded
if (-not $LocalBuild) {
    if (Test-Path $TempZip) { Remove-Item $TempZip -Force }
    if (Test-Path $TempExtract) { Remove-Item -Recurse -Force $TempExtract }
}

Write-Host ""
Write-Host "Installation complete!" -ForegroundColor Green
Write-Host ""
Write-Host "You can now use:" -ForegroundColor Cyan
Write-Host "  psmux    - Start/attach to terminal multiplexer"
Write-Host "  pmux     - Alias for psmux"  
Write-Host "  tmux     - tmux-compatible alias"
Write-Host ""
Write-Host "Quick start:" -ForegroundColor Cyan
Write-Host "  psmux                    # Start new session or attach to 'default'"
Write-Host "  psmux new -s mysession   # Create named session"
Write-Host "  psmux ls                 # List sessions"
Write-Host "  psmux attach -t name     # Attach to session"
Write-Host ""
Write-Host "Note: Restart your terminal or run:" -ForegroundColor Yellow
Write-Host '  $env:Path = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")'