tndrl 0.5.0

Parallel AI dev sessions via git worktrees
<#
.SYNOPSIS
    Build and install tndrl from source on Windows.

.DESCRIPTION
    Clones the repository (if needed), builds the release binary with cargo,
    and copies it to a directory on your PATH.

.PARAMETER InstallDir
    Directory to copy the built binary into. Defaults to "$HOME\.cargo\bin"
    which is on PATH for most Rust installations.

.EXAMPLE
    .\install.ps1
    .\install.ps1 -InstallDir "C:\Tools"
#>

param(
    [string]$InstallDir = "$env:USERPROFILE\.cargo\bin"
)

$ErrorActionPreference = 'Stop'

function Write-Step([string]$msg) {
    Write-Host "=> $msg" -ForegroundColor Cyan
}

function Assert-Command([string]$cmd, [string]$hint) {
    if (-not (Get-Command $cmd -ErrorAction SilentlyContinue)) {
        Write-Host "ERROR: '$cmd' not found. $hint" -ForegroundColor Red
        exit 1
    }
}

# --- Prerequisites -----------------------------------------------------------

Write-Step "Checking prerequisites..."

Assert-Command 'git'   'Install Git from https://git-scm.com/downloads/win'
Assert-Command 'cargo' 'Install Rust from https://rustup.rs'

$rustVersion = (rustc --version) 2>&1
Write-Host "  git   : $(git --version)"
Write-Host "  rustc : $rustVersion"

# Verify minimum Rust version (1.85+ required for edition 2024)
if ($rustVersion -match '(\d+)\.(\d+)') {
    $major = [int]$Matches[1]
    $minor = [int]$Matches[2]
    if ($major -lt 1 -or ($major -eq 1 -and $minor -lt 85)) {
        Write-Host "ERROR: Rust 1.85+ required (edition 2024). Run 'rustup update'." -ForegroundColor Red
        exit 1
    }
}

# --- Clone or locate source --------------------------------------------------

$repoUrl = 'https://github.com/connor-williams/tendril.git'
$srcDir  = $null

# If we're already inside the repo, use it
if (Test-Path (Join-Path $PSScriptRoot 'Cargo.toml')) {
    $srcDir = $PSScriptRoot
    Write-Step "Using source at $srcDir"
} else {
    $cloneDir = Join-Path $env:TEMP 'tndrl-build'
    if (Test-Path $cloneDir) {
        Write-Step "Updating existing clone at $cloneDir..."
        git -C $cloneDir pull --ff-only
    } else {
        Write-Step "Cloning $repoUrl..."
        git clone $repoUrl $cloneDir
    }
    $srcDir = $cloneDir
}

# --- Build --------------------------------------------------------------------

Write-Step "Building release binary..."
cargo build --release --manifest-path (Join-Path $srcDir 'Cargo.toml')

if ($LASTEXITCODE -ne 0) {
    Write-Host "ERROR: Build failed." -ForegroundColor Red
    exit 1
}

$builtBinary = Join-Path $srcDir 'target\release\tndrl.exe'
if (-not (Test-Path $builtBinary)) {
    Write-Host "ERROR: Expected binary not found at $builtBinary" -ForegroundColor Red
    exit 1
}

# --- Install ------------------------------------------------------------------

Write-Step "Installing to $InstallDir..."

if (-not (Test-Path $InstallDir)) {
    New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
}

Copy-Item $builtBinary (Join-Path $InstallDir 'tndrl.exe') -Force

# Verify it's reachable
if (Get-Command 'tndrl' -ErrorAction SilentlyContinue) {
    $installed = (tndrl --version 2>&1) -join ''
    Write-Host ""
    Write-Host "tndrl installed successfully! ($installed)" -ForegroundColor Green
} else {
    Write-Host ""
    Write-Host "Binary copied to $InstallDir\tndrl.exe" -ForegroundColor Green
    Write-Host "WARNING: '$InstallDir' is not on your PATH." -ForegroundColor Yellow
    Write-Host "Add it with:" -ForegroundColor Yellow
    Write-Host "  [Environment]::SetEnvironmentVariable('PATH', `"$InstallDir;`$env:PATH`", 'User')" -ForegroundColor White
}