-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuninstall.sh
More file actions
executable file
·293 lines (251 loc) · 8.2 KB
/
Copy pathuninstall.sh
File metadata and controls
executable file
·293 lines (251 loc) · 8.2 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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#!/bin/bash
set -euo pipefail
# AIFlow - Uninstall Script
# This script safely removes the installed command system
# Get the absolute path to the project root
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Source security library
source "$PROJECT_ROOT/scripts/common_security.sh" || {
echo "Error: Failed to load security library" >&2
exit 1
}
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Installation paths
INSTALL_DIR="$HOME/.claude/commands/project"
SCRIPTS_DIR="$HOME/.claude/commands"
BACKUP_DIR_NAME="claude-pm-backup-$(date +%Y%m%d-%H%M%S)"
BACKUP_DIR="$HOME/.claude/backups/$BACKUP_DIR_NAME"
# Cleanup function
cleanup() {
# Nothing to clean up for uninstaller
return 0
}
# Signal handler
handle_signal() {
local signal="$1"
print_status "warning" "Uninstall interrupted by signal: $signal"
log_security_event "INTERRUPT" "Uninstall interrupted" "Signal: $signal"
exit 130
}
# Set up cleanup and signal traps
setup_cleanup_trap cleanup
trap 'handle_signal INT' INT
trap 'handle_signal TERM' TERM
trap 'handle_signal HUP' HUP
echo "🗑️ AI Software Project Management System Uninstaller"
echo "===================================================="
echo ""
# Function to print colored output
print_status() {
local status=$1
local message=$2
case $status in
"success")
echo -e "${GREEN}✅ $message${NC}"
;;
"error")
echo -e "${RED}❌ $message${NC}"
;;
"warning")
echo -e "${YELLOW}⚠️ $message${NC}"
;;
"info")
echo -e "${BLUE}ℹ️ $message${NC}"
;;
esac
}
# Function to check if installation exists
check_installation() {
if [[ ! -d "$INSTALL_DIR" ]]; then
print_status "error" "Installation not found at $INSTALL_DIR"
echo ""
echo "Nothing to uninstall."
exit 0
fi
print_status "info" "Found installation at $INSTALL_DIR"
}
# Function to prompt for confirmation
confirm_uninstall() {
echo ""
print_status "warning" "This will remove all Claude PM commands and configurations"
echo ""
echo "The following will be removed:"
echo " • Commands at $INSTALL_DIR"
echo " • Scripts at $SCRIPTS_DIR/logged_secure_shell.py"
echo " • Scripts at $SCRIPTS_DIR/analyze_logs.sh"
echo ""
read -p "Do you want to create a backup before uninstalling? (y/N): " backup_choice
validate_yes_no "$backup_choice"
if [[ $? -eq 0 ]]; then
CREATE_BACKUP=true
else
CREATE_BACKUP=false
fi
echo ""
read -p "Are you sure you want to uninstall? (y/N): " confirm
validate_yes_no "$confirm"
if [[ $? -ne 0 ]]; then
print_status "info" "Uninstall cancelled"
exit 0
fi
}
# Function to create backup
create_backup() {
print_status "info" "Creating backup..."
# Create backup directory
mkdir -p "$BACKUP_DIR" || {
print_status "error" "Failed to create backup directory"
return 1
}
# Backup installation directory
if [[ -d "$INSTALL_DIR" ]]; then
cp -r "$INSTALL_DIR" "$BACKUP_DIR/project" || {
print_status "warning" "Failed to backup project directory"
}
fi
# Backup scripts
for script in logged_secure_shell.py analyze_logs.sh; do
if [[ -f "$SCRIPTS_DIR/$script" ]]; then
cp "$SCRIPTS_DIR/$script" "$BACKUP_DIR/" || {
print_status "warning" "Failed to backup $script"
}
fi
done
# Save installation info
cat > "$BACKUP_DIR/installation_info.txt" << EOF
Claude PM Backup
Created: $(date)
Installation Directory: $INSTALL_DIR
Scripts Directory: $SCRIPTS_DIR
To restore:
1. Copy project/ to $INSTALL_DIR
2. Copy scripts to $SCRIPTS_DIR
EOF
print_status "success" "Backup created at $BACKUP_DIR"
return 0
}
# Function to check for active projects
check_active_projects() {
print_status "info" "Checking for active projects..."
# Look for .project-state.json files in parent directories
local active_projects=()
# Check common project locations
for dir in "$HOME/projects" "$HOME/dev" "$HOME/workspace" "$HOME"; do
if [[ -d "$dir" ]]; then
while IFS= read -r -d '' state_file; do
local project_dir=$(dirname "$state_file")
if [[ -f "$state_file" ]]; then
active_projects+=("$project_dir")
fi
done < <(find "$dir" -maxdepth 3 -name ".project-state.json" -print0 2>/dev/null)
fi
done
if [[ ${#active_projects[@]} -gt 0 ]]; then
print_status "warning" "Found ${#active_projects[@]} active project(s):"
for project in "${active_projects[@]}"; do
echo " • $project"
done
echo ""
echo "These projects will continue to work but commands will not be available."
else
print_status "success" "No active projects found"
fi
}
# Function to remove installation
remove_installation() {
print_status "info" "Removing installation..."
local removal_errors=0
# Remove main installation directory
if [[ -d "$INSTALL_DIR" ]]; then
if safe_remove "$HOME/.claude/commands" "project"; then
print_status "success" "Removed commands directory"
else
print_status "error" "Failed to remove $INSTALL_DIR"
((removal_errors++))
fi
fi
# Remove scripts
for script in logged_secure_shell.py analyze_logs.sh; do
if [[ -f "$SCRIPTS_DIR/$script" ]]; then
if safe_remove "$SCRIPTS_DIR" "$script"; then
print_status "success" "Removed $script"
else
print_status "warning" "Failed to remove $script"
((removal_errors++))
fi
fi
done
# Clean up empty parent directory if safe
if [[ -d "$HOME/.claude/commands" ]]; then
# Only remove if directory is empty or only contains our backup directory
local remaining_files=$(find "$HOME/.claude/commands" -mindepth 1 -maxdepth 1 -not -name "backups" | wc -l)
if [[ $remaining_files -eq 0 ]]; then
rmdir "$HOME/.claude/commands" 2>/dev/null || true
fi
fi
if [[ $removal_errors -eq 0 ]]; then
print_status "success" "Uninstallation completed successfully"
return 0
else
print_status "warning" "Uninstallation completed with $removal_errors warning(s)"
return 1
fi
}
# Function to show post-uninstall message
show_completion_message() {
echo ""
echo "============================================="
print_status "success" "Uninstall completed!"
echo "============================================="
echo ""
if [[ "$CREATE_BACKUP" == true ]]; then
echo "📦 Backup Location:"
echo " $BACKUP_DIR"
echo ""
echo "To restore the installation:"
echo " 1. Copy files from backup to original locations"
echo " 2. Or reinstall using install.sh"
echo ""
fi
echo "📝 Notes:"
echo " • Existing projects will remain intact"
echo " • Git worktrees are not affected"
echo " • Sprint files in projects are preserved"
echo ""
echo "To reinstall:"
echo " ./install.sh"
echo ""
echo "Thank you for using Claude PM!"
}
# Main uninstall flow
main() {
# Check if installation exists
check_installation
# Check for active projects
check_active_projects
# Confirm uninstall
confirm_uninstall
# Create backup if requested
if [[ "$CREATE_BACKUP" == true ]]; then
if ! create_backup; then
print_status "error" "Backup failed"
read -p "Continue with uninstall anyway? (y/N): " continue_anyway
validate_yes_no "$continue_anyway"
if [[ $? -ne 0 ]]; then
print_status "info" "Uninstall cancelled"
exit 1
fi
fi
fi
# Remove installation
remove_installation
# Show completion message
show_completion_message
}
# Run main uninstall
main