From 2bdeffc8ae69c8ae0957b4c88d7013eda263960b Mon Sep 17 00:00:00 2001 From: warren Date: Mon, 6 Apr 2026 17:16:47 -0400 Subject: [PATCH] feat: PowerShell uninstall script for Windows Removes only ctask-owned files from %LOCALAPPDATA%\ctask\bin. Removes PATH entry only if .ctask-path-added marker exists (ownership tracking). Cleans empty install directory. Never touches workspace data. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/uninstall.ps1 | 90 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 scripts/uninstall.ps1 diff --git a/scripts/uninstall.ps1 b/scripts/uninstall.ps1 new file mode 100644 index 0000000..715daf9 --- /dev/null +++ b/scripts/uninstall.ps1 @@ -0,0 +1,90 @@ +#Requires -Version 5.1 +<# +.SYNOPSIS + Uninstall ctask from %LOCALAPPDATA%\ctask\bin on Windows. +.DESCRIPTION + Removes ctask binary and status-line helpers from the install directory. + Removes the install directory from user PATH only if the install script + originally added it (tracked via .ctask-path-added marker). + Does NOT remove workspace data, CTASK_ROOT, or any task folders. +#> +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$InstallDir = Join-Path $env:LOCALAPPDATA 'ctask\bin' + +Write-Host "ctask uninstall" -ForegroundColor Cyan +Write-Host " Install dir: $InstallDir" +Write-Host "" + +if (-not (Test-Path $InstallDir)) { + Write-Host " Nothing to uninstall. Directory does not exist." -ForegroundColor DarkGray + exit 0 +} + +# Step 1: Remove installed files (only ctask-owned files) +$ctaskFiles = @( + 'ctask.exe', + 'ctask-statusline.sh', + 'ctask-statusline.ps1' +) + +$removedCount = 0 +foreach ($name in $ctaskFiles) { + $path = Join-Path $InstallDir $name + if (Test-Path $path) { + Remove-Item $path -Force + Write-Host " Removed $name" + $removedCount++ + } +} + +if ($removedCount -eq 0) { + Write-Host " No ctask files found in install directory." -ForegroundColor DarkGray +} + +# Step 2: Remove PATH entry only if ctask install added it (marker file exists) +$marker = Join-Path $InstallDir '.ctask-path-added' +if (Test-Path $marker) { + $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') + if (-not $userPath) { $userPath = '' } + $pathEntries = $userPath -split ';' | Where-Object { $_ -ne '' } + + if ($pathEntries -contains $InstallDir) { + $newEntries = $pathEntries | Where-Object { $_ -ne $InstallDir } + $newPath = $newEntries -join ';' + [Environment]::SetEnvironmentVariable('Path', $newPath, 'User') + Write-Host "" + Write-Host " PATH: removed $InstallDir" -ForegroundColor Green + Write-Host " NOTE: Open a new terminal for PATH changes to take effect." -ForegroundColor Yellow + } + + Remove-Item $marker -Force +} else { + Write-Host "" + Write-Host " PATH: not modified (no ownership marker found)." -ForegroundColor DarkGray + Write-Host " If you added $InstallDir to PATH manually, remove it manually." -ForegroundColor DarkGray +} + +# Step 3: Remove install directory if empty +if ((Test-Path $InstallDir) -and ((Get-ChildItem $InstallDir | Measure-Object).Count -eq 0)) { + Remove-Item $InstallDir -Force + Write-Host " Removed empty directory: $InstallDir" + # Also remove parent ctask dir if empty + $parentDir = Split-Path $InstallDir + if ((Test-Path $parentDir) -and ((Get-ChildItem $parentDir | Measure-Object).Count -eq 0)) { + Remove-Item $parentDir -Force + } +} + +# Safety reminder +Write-Host "" +Write-Host "Workspace data is untouched:" -ForegroundColor DarkGray +$root = $env:CTASK_ROOT +if (-not $root) { $root = Join-Path $env:USERPROFILE 'ai-workspaces' } +Write-Host " $root" -ForegroundColor DarkGray +Write-Host "" +Write-Host "Done." -ForegroundColor Cyan