#Requires -Version 5.1 <# .SYNOPSIS Install ctask to %LOCALAPPDATA%\ctask\bin on Windows. .DESCRIPTION Builds ctask from the local repo, copies the binary and status-line helpers to the install directory, and ensures the directory is on the user PATH. Does not modify workspace data. Does not modify Claude Code settings. #> [CmdletBinding()] param() Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $InstallDir = Join-Path $env:LOCALAPPDATA 'ctask\bin' # Find repo root (script lives in scripts/) $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $RepoRoot = Split-Path -Parent $ScriptDir if (-not (Test-Path (Join-Path $RepoRoot 'go.mod'))) { Write-Error "Cannot find go.mod at $RepoRoot. Run this script from the ctask repo." exit 1 } Write-Host "ctask install" -ForegroundColor Cyan Write-Host " Source: $RepoRoot" Write-Host " Target: $InstallDir" Write-Host "" # Step 1: Find Go $GoExe = Get-Command go -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source if (-not $GoExe) { # Check standard install location $defaultGo = Join-Path $env:ProgramFiles 'Go\bin\go.exe' if (Test-Path $defaultGo) { $GoExe = $defaultGo } else { Write-Error "Go not found. Install Go (winget install GoLang.Go) and ensure it is on PATH." exit 1 } } # Step 2: Build Write-Host "Building ctask..." -NoNewline Push-Location $RepoRoot try { & $GoExe build -o ctask.exe . 2>&1 | Out-Null if ($LASTEXITCODE -ne 0) { Write-Host " FAILED" -ForegroundColor Red Write-Error "Build failed. Check go build output." exit 1 } Write-Host " OK" -ForegroundColor Green } finally { Pop-Location } # Step 2: Create install directory if (-not (Test-Path $InstallDir)) { New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null Write-Host " Created $InstallDir" } # Step 3: Copy files $filesToInstall = @( @{ Src = Join-Path $RepoRoot 'ctask.exe'; Dst = Join-Path $InstallDir 'ctask.exe' } @{ Src = Join-Path $RepoRoot 'scripts\ctask-statusline.sh'; Dst = Join-Path $InstallDir 'ctask-statusline.sh' } @{ Src = Join-Path $RepoRoot 'scripts\ctask-statusline.ps1'; Dst = Join-Path $InstallDir 'ctask-statusline.ps1' } ) foreach ($f in $filesToInstall) { if (Test-Path $f.Src) { Copy-Item -Path $f.Src -Destination $f.Dst -Force Write-Host " Installed $(Split-Path -Leaf $f.Dst)" } else { Write-Warning "Source not found: $($f.Src)" } } # Step 4: Ensure install directory is on user PATH $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') if (-not $userPath) { $userPath = '' } $pathEntries = $userPath -split ';' | Where-Object { $_ -ne '' } if ($pathEntries -contains $InstallDir) { Write-Host "" Write-Host " PATH: already contains $InstallDir" -ForegroundColor DarkGray } else { $newPath = (($pathEntries + $InstallDir) | Where-Object { $_ -ne '' }) -join ';' [Environment]::SetEnvironmentVariable('Path', $newPath, 'User') # Write ownership marker so uninstall knows we added this entry $marker = Join-Path $InstallDir '.ctask-path-added' Set-Content -Path $marker -Value "PATH entry added by ctask install on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" Write-Host "" Write-Host " PATH: added $InstallDir" -ForegroundColor Green Write-Host " NOTE: Open a new terminal for PATH changes to take effect." -ForegroundColor Yellow } # Step 5: Verify $installedBinary = Join-Path $InstallDir 'ctask.exe' if (Test-Path $installedBinary) { $ver = & $installedBinary --version 2>&1 Write-Host "" Write-Host "Installed: $ver" -ForegroundColor Green } else { Write-Warning "Binary not found at $installedBinary" exit 1 } # Step 6: Clean up build artifact from repo root $repoExe = Join-Path $RepoRoot 'ctask.exe' if (Test-Path $repoExe) { Remove-Item $repoExe -Force } Write-Host "" Write-Host "Run 'ctask doctor' in a new terminal to verify setup." -ForegroundColor Cyan