-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRestore-WatchdogSession.ps1
More file actions
173 lines (137 loc) · 6.21 KB
/
Restore-WatchdogSession.ps1
File metadata and controls
173 lines (137 loc) · 6.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<#
.SYNOPSIS
Manually restore Claude Code Watchdog sessions from saved state
.DESCRIPTION
This script allows manual recovery of watchdog sessions after a crash or
unexpected shutdown. It reads the saved recovery state and attempts to
reconnect to active Claude Code sessions.
.PARAMETER Force
Force recovery even if state is older than 24 hours
.PARAMETER ProjectName
Restore only a specific project (optional)
.EXAMPLE
.\Restore-WatchdogSession.ps1
.EXAMPLE
.\Restore-WatchdogSession.ps1 -ProjectName "my-project"
.EXAMPLE
.\Restore-WatchdogSession.ps1 -Force
.NOTES
Part of the Claude Code Watchdog project
Workstream: WS05 - Project Management
Work Item: WI-3.6 - Session Recovery System
#>
[CmdletBinding()]
param(
[Parameter()]
[switch]$Force,
[Parameter()]
[string]$ProjectName
)
# Import required modules
$ScriptRoot = Split-Path -Parent $PSCommandPath
. "$ScriptRoot/src/Registry/Get-RegisteredProjects.ps1"
. "$ScriptRoot/src/Registry/Update-ProjectState.ps1"
. "$ScriptRoot/src/Detection/Find-ClaudeCodeSession.ps1"
. "$ScriptRoot/src/Logging/Write-WatchdogLog.ps1"
. "$ScriptRoot/src/Logging/Send-Notification.ps1"
function Restore-WatchdogSession {
param(
[switch]$ForceRecovery,
[string]$SpecificProject
)
$recoveryStatePath = "$HOME/.claude-automation/state/watchdog-recovery.json"
if (-not (Test-Path $recoveryStatePath)) {
Write-Host "❌ No recovery state found at: $recoveryStatePath" -ForegroundColor Red
Write-Host " Recovery state is created when watchdog shuts down normally." -ForegroundColor Gray
return
}
try {
Write-Host "🔄 Claude Code Watchdog - Session Recovery" -ForegroundColor Cyan
Write-Host "=" * 60 -ForegroundColor Gray
$recoveryState = Get-Content $recoveryStatePath -Raw | ConvertFrom-Json
# Check if recovery state is recent
$savedTime = [DateTime]::Parse($recoveryState.SavedAt)
$timeSinceSave = (Get-Date) - $savedTime
Write-Host "`n📁 Recovery state found:" -ForegroundColor Cyan
Write-Host " Saved at: $($savedTime.ToString('yyyy-MM-dd HH:mm:ss'))" -ForegroundColor Gray
Write-Host " Age: $([math]::Round($timeSinceSave.TotalHours, 1)) hours" -ForegroundColor Gray
Write-Host " Projects: $($recoveryState.Projects.Count)" -ForegroundColor Gray
if ($timeSinceSave.TotalHours -gt 24 -and -not $ForceRecovery) {
Write-Host "`n⚠️ Recovery state is older than 24 hours." -ForegroundColor Yellow
Write-Host " Use -Force to proceed anyway." -ForegroundColor Gray
return
}
Write-Host "`n🔧 Starting recovery process..." -ForegroundColor Cyan
$recoveredCount = 0
$failedCount = 0
$skippedCount = 0
foreach ($projectState in $recoveryState.Projects) {
$projectName = $projectState.ProjectName
# Skip if specific project requested and this isn't it
if ($SpecificProject -and $projectName -ne $SpecificProject) {
$skippedCount++
continue
}
try {
Write-Host "`n 📦 $projectName" -ForegroundColor White
# Check if project still registered
$projects = Get-RegisteredProjects
$project = $projects | Where-Object { $_.Name -eq $projectName }
if (-not $project) {
Write-Host " ⚠️ Project no longer registered" -ForegroundColor Yellow
$failedCount++
continue
}
# Look for active session
Write-Host " 🔍 Searching for Claude Code session..." -ForegroundColor Gray
$session = Find-ClaudeCodeSession -ProjectName $projectName
if ($session) {
Write-Host " ✅ Session found: $($session.SessionId)" -ForegroundColor Green
# Update registry with restored session
Update-RegistrySessionId -ProjectName $projectName -SessionId $session.SessionId
# Update project state
Update-ProjectState -ProjectName $projectName -StateUpdates @{
status = "Active"
lastActivity = (Get-Date).ToString("o")
sessionRecovered = $true
}
# Send notification
Send-Notification -Title "Session Recovered" `
-Message "Project '$projectName' session recovered successfully" `
-ProjectName $projectName
$recoveredCount++
}
else {
Write-Host " ❌ No active session found" -ForegroundColor Red
Write-Host " Start Claude Code and open this project to resume" -ForegroundColor Gray
$failedCount++
}
}
catch {
Write-Host " ❌ Recovery failed: $_" -ForegroundColor Red
$failedCount++
}
}
Write-Host "`n" + ("=" * 60) -ForegroundColor Gray
Write-Host "📊 Recovery Summary:" -ForegroundColor Cyan
Write-Host " ✅ Recovered: $recoveredCount" -ForegroundColor Green
Write-Host " ❌ Failed: $failedCount" -ForegroundColor Red
if ($skippedCount -gt 0) {
Write-Host " ⏭️ Skipped: $skippedCount" -ForegroundColor Gray
}
if ($recoveredCount -gt 0) {
Write-Host "`n✨ You can now start the watchdog with: .\Start-Watchdog.ps1" -ForegroundColor Cyan
}
# Clean up recovery file if all successful
if ($failedCount -eq 0 -and $recoveredCount -gt 0) {
Remove-Item $recoveryStatePath -Force -ErrorAction SilentlyContinue
Write-Verbose "Cleaned up recovery state file"
}
}
catch {
Write-Host "`n❌ Recovery error: $_" -ForegroundColor Red
Write-Host " Check the recovery state file: $recoveryStatePath" -ForegroundColor Gray
}
}
# Execute recovery
Restore-WatchdogSession -ForceRecovery:$Force -SpecificProject $ProjectName