psmux 3.3.4

Terminal multiplexer for Windows - tmux alternative for PowerShell and Windows Terminal
<#
.SYNOPSIS
    Build (if needed) and run the psmux-dev Docker container with SSH key auth.

.DESCRIPTION
    - Generates an SSH keypair in ~/.ssh/psmux_docker_key (if not present)
    - Builds the psmux-dev image (if not present)
    - Starts the container with your public key injected
    - Prints the SSH command to connect

.EXAMPLE
    pwsh -File docker\Run-PsmuxDev.ps1
    pwsh -File docker\Run-PsmuxDev.ps1 -Rebuild
#>
param(
    [switch]$Rebuild
)

$ErrorActionPreference = "Stop"

$imageName     = "psmux-dev"
$containerName = "psmux-dev"
$keyPath       = Join-Path $env:USERPROFILE ".ssh\psmux_docker_key"
$pubKeyPath    = "$keyPath.pub"
$dockerDir     = $PSScriptRoot  # docker/ folder

# ── 1. Generate SSH key if missing ──
if (-not (Test-Path $keyPath)) {
    Write-Host "Generating SSH key at $keyPath ..."
    $sshDir = Split-Path $keyPath
    if (-not (Test-Path $sshDir)) { New-Item -ItemType Directory -Path $sshDir -Force | Out-Null }
    ssh-keygen -t ed25519 -f $keyPath -N "" -C "psmux-docker" -q
    Write-Host "  Key generated."
} else {
    Write-Host "Using existing SSH key: $keyPath"
}

$pubKey = (Get-Content $pubKeyPath -Raw).Trim()
Write-Host "  Public key: $($pubKey.Substring(0, [Math]::Min(60, $pubKey.Length)))..."

# ── 2. Build image if needed ──
$imageExists = docker images $imageName -q 2>$null
if (-not $imageExists -or $Rebuild) {
    Write-Host ""
    Write-Host "Building $imageName image (this takes a while on first run)..."
    docker build -t $imageName $dockerDir
    if ($LASTEXITCODE -ne 0) { throw "Docker build failed" }
}

# ── 3. Remove old container if exists ──
$existing = docker ps -aq -f "name=$containerName" 2>$null
if ($existing) {
    Write-Host "Removing existing container..."
    docker rm -f $containerName 2>$null | Out-Null
}

# ── 4. Run container with public key ──
Write-Host "Starting container..."
docker run -d `
    --name $containerName `
    --isolation=hyperv `
    -e "SSH_PUBLIC_KEY=$pubKey" `
    $imageName | Out-Null

if ($LASTEXITCODE -ne 0) { throw "Docker run failed" }

# Wait for container to initialize
Write-Host "Waiting for sshd to start..."
Start-Sleep 5

# ── 5. Get container IP ──
$containerIP = docker inspect $containerName --format "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}"
if (-not $containerIP) { throw "Could not get container IP" }

# ── 6. Print connection info ──
Write-Host ""
Write-Host "============================================" -ForegroundColor Green
Write-Host " psmux dev container is running" -ForegroundColor Green
Write-Host "============================================" -ForegroundColor Green
Write-Host ""
Write-Host " Connect:" -ForegroundColor Cyan
Write-Host "   ssh -i ~/.ssh/psmux_docker_key -p 2222 ContainerAdministrator@$containerIP"
Write-Host ""
Write-Host " Quick build:" -ForegroundColor Cyan
Write-Host "   git clone https://github.com/psmux/psmux.git"
Write-Host "   cd psmux && cargo install --path ."
Write-Host ""
Write-Host " Stop:" -ForegroundColor Cyan
Write-Host "   docker stop $containerName"
Write-Host ""
Write-Host " Restart:" -ForegroundColor Cyan
Write-Host "   docker start $containerName"
Write-Host ""
Write-Host "============================================" -ForegroundColor Green

# ── 7. Verify SSH connectivity ──
Write-Host ""
Write-Host "Testing SSH connection..."
$result = ssh -i $keyPath -o StrictHostKeyChecking=no -o UserKnownHostsFile=NUL -o ConnectTimeout=10 -p 2222 ContainerAdministrator@$containerIP "hostname" 2>$null
if ($result) {
    Write-Host "  Connected to: $result" -ForegroundColor Green
} else {
    Write-Host "  SSH not ready yet — container may still be initializing." -ForegroundColor Yellow
    Write-Host "  Try manually: ssh -i ~/.ssh/psmux_docker_key -p 2222 ContainerAdministrator@$containerIP"
}