@@ -335,38 +335,81 @@ function Update-Path {
335335}
336336
337337# ============================================================================
338- # Uninstall Function (Following OpenCode Pattern )
338+ # Uninstall Function (Enhanced with File Lock Handling )
339339# ============================================================================
340340
341341function Uninstall-PersistenceAI {
342342 Write-Step " Uninstalling PersistenceAI..."
343343
344- # Stop processes
344+ # Stop processes aggressively (including child processes)
345345 $processes = Get-Process | Where-Object {
346346 ($_.ProcessName -eq " pai" ) -or
347347 ($_.ProcessName -eq " persistenceai" )
348348 } - ErrorAction SilentlyContinue
349349
350350 if ($processes ) {
351- Write-Info " Stopping running processes..."
351+ Write-Info " Stopping running processes (including child processes) ..."
352352 foreach ($proc in $processes ) {
353- Stop-Process - Id $proc.Id - Force - ErrorAction SilentlyContinue
353+ try {
354+ # Use taskkill with /T to kill process tree
355+ Start-Process - FilePath " taskkill" - ArgumentList " /F" , " /T" , " /PID" , $proc.Id - Wait - NoNewWindow - ErrorAction SilentlyContinue | Out-Null
356+ } catch {
357+ # Fallback to Stop-Process
358+ Stop-Process - Id $proc.Id - Force - ErrorAction SilentlyContinue
359+ }
354360 }
355- Start-Sleep - Seconds 2
361+ Start-Sleep - Seconds 3
356362 }
357363
358- # Remove directories (like OpenCode's fs.rm with recursive: true, force: true)
364+ # Remove directories with retry logic
359365 $dirsToRemove = @ (
360366 " $env: USERPROFILE \.persistenceai" ,
361367 " $env: USERPROFILE \.pai" ,
368+ " $env: USERPROFILE \.config\persistenceai" ,
369+ " $env: USERPROFILE \.config\pai" ,
362370 " $env: LOCALAPPDATA \persistenceai" ,
363371 " $env: LOCALAPPDATA \pai"
364372 )
365373
374+ # Also find installation directories from PATH
375+ $paiCmd = Get-Command - Name " pai" - ErrorAction SilentlyContinue
376+ $persistenceaiCmd = Get-Command - Name " persistenceai" - ErrorAction SilentlyContinue
377+
378+ if ($paiCmd ) {
379+ $binDir = Split-Path $paiCmd.Source - Parent
380+ $installDir = Split-Path $binDir - Parent
381+ if ($installDir -and $installDir -notin $dirsToRemove ) {
382+ $dirsToRemove += $installDir
383+ }
384+ }
385+
386+ if ($persistenceaiCmd ) {
387+ $binDir = Split-Path $persistenceaiCmd.Source - Parent
388+ $installDir = Split-Path $binDir - Parent
389+ if ($installDir -and $installDir -notin $dirsToRemove ) {
390+ $dirsToRemove += $installDir
391+ }
392+ }
393+
366394 foreach ($dir in $dirsToRemove ) {
367395 if (Test-Path $dir ) {
368396 Write-Info " Removing $dir ..."
369- Remove-Item - Path $dir - Recurse - Force - ErrorAction SilentlyContinue
397+ $maxRetries = 3
398+
399+ for ($i = 1 ; $i -le $maxRetries ; $i ++ ) {
400+ try {
401+ Remove-Item - Path $dir - Recurse - Force - ErrorAction Stop
402+ break
403+ } catch {
404+ if ($i -lt $maxRetries ) {
405+ Write-Warning " Attempt $i failed, retrying in 2 seconds..."
406+ Start-Sleep - Seconds 2
407+ } else {
408+ Write-Warning " Could not remove $dir after $maxRetries attempts"
409+ Write-Info " Files may be locked. Try running the standalone uninstall.ps1 script or restart your computer."
410+ }
411+ }
412+ }
370413 }
371414 }
372415
@@ -483,6 +526,23 @@ if (-not (Test-Path $exeFullPath) -or -not (Test-Path $paiExeFullPath)) {
483526try {
484527 $versionOutput = & $exeFullPath -- version 2>&1 | Select-Object - First 1
485528 Write-Success " Installed version: $versionOutput "
529+
530+ # Debug: Show final file modification times
531+ Write-Host " "
532+ Write-Host " " - NoNewline; Write-Host " Debug Information:" - ForegroundColor Cyan
533+ if (Test-Path $exeFullPath ) {
534+ $finalFile = Get-Item $exeFullPath
535+ $finalModTime = $finalFile.LastWriteTime
536+ $timeSinceFinal = (Get-Date ) - $finalModTime
537+ Write-Info " persistenceai.exe last modified: $finalModTime ($ ( [math ]::Round($timeSinceFinal.TotalMinutes , 2 )) minutes ago)"
538+ }
539+ if (Test-Path $paiExeFullPath ) {
540+ $finalPaiFile = Get-Item $paiExeFullPath
541+ $finalPaiModTime = $finalPaiFile.LastWriteTime
542+ $timeSinceFinalPai = (Get-Date ) - $finalPaiModTime
543+ Write-Info " pai.exe last modified: $finalPaiModTime ($ ( [math ]::Round($timeSinceFinalPai.TotalMinutes , 2 )) minutes ago)"
544+ }
545+ Write-Host " "
486546} catch {
487547 Write-Warning " Could not verify version"
488548}
0 commit comments