-
Notifications
You must be signed in to change notification settings - Fork 100
Add uninstall script for ClaudeBox #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This script provides a complete uninstallation process for ClaudeBox: - Removes symlink from ~/.local/bin/claudebox - Removes installation directory ~/.claudebox - Cleans up project-specific directories (.claudebox-*) - Removes Docker containers and images related to ClaudeBox - Provides user guidance on PATH configuration cleanup - Optionally removes the installer file The script uses colored output for better user experience and safely handles cases where components may already be removed. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Reviewer's GuideIntroduces a comprehensive uninstall.sh script for ClaudeBox that guides users through removal of all components with safety checks, colored output, and optional cleanup prompts. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @swhsiang - I've reviewed your changes - here's some feedback:
- Consider adding noninteractive flags like --force or --dry-run so users can preview or automate the uninstall without prompts.
- Rather than using set -e globally, wrap optional cleanup steps in their own error handlers so a single failure won’t abort the entire summary.
- Grep-matching Docker names/images may remove unrelated items—use specific Docker labels or more precise filters to target only ClaudeBox resources.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider adding noninteractive flags like --force or --dry-run so users can preview or automate the uninstall without prompts.
- Rather than using set -e globally, wrap optional cleanup steps in their own error handlers so a single failure won’t abort the entire summary.
- Grep-matching Docker names/images may remove unrelated items—use specific Docker labels or more precise filters to target only ClaudeBox resources.
## Individual Comments
### Comment 1
<location> `uninstall.sh:64` </location>
<code_context>
+# 3. Check for project-specific directories
+echo ""
+echo "Checking for project-specific ClaudeBox directories..."
+PROJECT_DIRS=$(find "$HOME" -maxdepth 1 -type d -name ".claudebox-*" 2>/dev/null || true)
+if [ -n "$PROJECT_DIRS" ]; then
+ echo "$PROJECT_DIRS" | while read -r dir; do
+ rm -rf "$dir"
+ print_success "Removed project directory: $dir"
</code_context>
<issue_to_address>
Using a pipeline with 'while read' can cause issues with variable scope in bash.
Because the 'while read' loop runs in a subshell, any changes to variables like 'REMOVED_SOMETHING' inside the loop won't affect the parent shell. Switching to a 'for' loop will ensure variable updates are retained.
</issue_to_address>
### Comment 2
<location> `uninstall.sh:82` </location>
<code_context>
+# Check if Docker is installed and running
+if command -v docker &> /dev/null && docker info &> /dev/null; then
+ # Check for containers
+ CONTAINERS=$(docker ps -a --format "{{.ID}} {{.Names}}" | grep -i claudebox | awk '{print $1}' 2>/dev/null || true)
+ if [ -n "$CONTAINERS" ]; then
+ print_warning "Found ClaudeBox Docker containers. Removing..."
+ echo "$CONTAINERS" | while read -r container; do
+ docker rm -f "$container" &>/dev/null
+ print_success "Removed container: $container"
</code_context>
<issue_to_address>
Subshell in 'while read' may prevent 'REMOVED_SOMETHING' from updating as expected.
Because the loop runs in a subshell, updates to 'REMOVED_SOMETHING' inside it won't persist. Switching to a 'for' loop will ensure variable changes are retained.
</issue_to_address>
### Comment 3
<location> `uninstall.sh:95` </location>
<code_context>
+ fi
+
+ # Check for images
+ IMAGES=$(docker images --format "{{.ID}} {{.Repository}}" | grep -i claudebox | awk '{print $1}' 2>/dev/null || true)
+ if [ -n "$IMAGES" ]; then
+ print_warning "Found ClaudeBox Docker images. Removing..."
+ echo "$IMAGES" | while read -r image; do
+ docker rmi -f "$image" &>/dev/null
+ print_success "Removed image: $image"
</code_context>
<issue_to_address>
Subshell in 'while read' may prevent 'REMOVED_SOMETHING' from updating as expected.
Consider replacing the pipeline with a 'for' loop to ensure 'REMOVED_SOMETHING' is updated in the parent shell.
</issue_to_address>
### Comment 4
<location> `uninstall.sh:113` </location>
<code_context>
+# 5. Check PATH configuration
+echo ""
+echo "Checking PATH configuration..."
+if echo "$PATH" | grep -q "$HOME/.local/bin"; then
+ print_warning "~/.local/bin is in your PATH"
+ print_info "If you added this only for ClaudeBox, you may want to remove it from:"
</code_context>
<issue_to_address>
PATH check may produce false positives if $HOME/.local/bin is a substring of another path entry.
Consider splitting PATH by ':' and comparing each entry directly to avoid matching substrings.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
echo ""
echo "Checking PATH configuration..."
if echo "$PATH" | grep -q "$HOME/.local/bin"; then
print_warning "~/.local/bin is in your PATH"
print_info "If you added this only for ClaudeBox, you may want to remove it from:"
print_info " ~/.bashrc, ~/.zshrc, or ~/.bash_profile"
else
print_info "~/.local/bin is not in your PATH"
fi
=======
echo ""
echo "Checking PATH configuration..."
PATH_HAS_LOCAL_BIN=false
IFS=':' read -ra PATH_ENTRIES <<< "$PATH"
for entry in "${PATH_ENTRIES[@]}"; do
if [ "$entry" = "$HOME/.local/bin" ]; then
PATH_HAS_LOCAL_BIN=true
break
fi
done
if [ "$PATH_HAS_LOCAL_BIN" = true ]; then
print_warning "~/.local/bin is in your PATH"
print_info "If you added this only for ClaudeBox, you may want to remove it from:"
print_info " ~/.bashrc, ~/.zshrc, or ~/.bash_profile"
else
print_info "~/.local/bin is not in your PATH"
fi
>>>>>>> REPLACE
</suggested_fix>
### Comment 5
<location> `uninstall.sh:132` </location>
<code_context>
+echo "========================================="
+
+# Optional: Ask about removing the installer file
+if [ -f "claudebox.run" ]; then
+ echo ""
+ read -p "Remove the claudebox.run installer file? (y/N): " -n 1 -r
</code_context>
<issue_to_address>
Installer file removal prompt assumes script is run from the directory containing 'claudebox.run'.
If users run the script from another directory, 'claudebox.run' may not be detected. Consider clarifying usage instructions or allowing the installer path to be specified.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
# Optional: Ask about removing the installer file
if [ -f "claudebox.run" ]; then
echo ""
read -p "Remove the claudebox.run installer file? (y/N): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -f claudebox.run
print_success "Removed claudebox.run installer"
fi
fi
=======
# Optional: Ask about removing the installer file
INSTALLER_PATH="${CLAUDEBOX_INSTALLER_PATH:-claudebox.run}"
echo ""
print_info "If you wish to remove the installer file, it will be searched at: $INSTALLER_PATH"
print_info "You can specify a custom path by setting the CLAUDEBOX_INSTALLER_PATH environment variable before running this script."
if [ -f "$INSTALLER_PATH" ]; then
echo ""
read -p "Remove the installer file at '$INSTALLER_PATH'? (y/N): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -f "$INSTALLER_PATH"
print_success "Removed installer file at $INSTALLER_PATH"
fi
fi
>>>>>>> REPLACE
</suggested_fix>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| PROJECT_DIRS=$(find "$HOME" -maxdepth 1 -type d -name ".claudebox-*" 2>/dev/null || true) | ||
| if [ -n "$PROJECT_DIRS" ]; then | ||
| echo "$PROJECT_DIRS" | while read -r dir; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Using a pipeline with 'while read' can cause issues with variable scope in bash.
Because the 'while read' loop runs in a subshell, any changes to variables like 'REMOVED_SOMETHING' inside the loop won't affect the parent shell. Switching to a 'for' loop will ensure variable updates are retained.
| CONTAINERS=$(docker ps -a --format "{{.ID}} {{.Names}}" | grep -i claudebox | awk '{print $1}' 2>/dev/null || true) | ||
| if [ -n "$CONTAINERS" ]; then | ||
| print_warning "Found ClaudeBox Docker containers. Removing..." | ||
| echo "$CONTAINERS" | while read -r container; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Subshell in 'while read' may prevent 'REMOVED_SOMETHING' from updating as expected.
Because the loop runs in a subshell, updates to 'REMOVED_SOMETHING' inside it won't persist. Switching to a 'for' loop will ensure variable changes are retained.
| IMAGES=$(docker images --format "{{.ID}} {{.Repository}}" | grep -i claudebox | awk '{print $1}' 2>/dev/null || true) | ||
| if [ -n "$IMAGES" ]; then | ||
| print_warning "Found ClaudeBox Docker images. Removing..." | ||
| echo "$IMAGES" | while read -r image; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Subshell in 'while read' may prevent 'REMOVED_SOMETHING' from updating as expected.
Consider replacing the pipeline with a 'for' loop to ensure 'REMOVED_SOMETHING' is updated in the parent shell.
| echo "" | ||
| echo "Checking PATH configuration..." | ||
| if echo "$PATH" | grep -q "$HOME/.local/bin"; then | ||
| print_warning "~/.local/bin is in your PATH" | ||
| print_info "If you added this only for ClaudeBox, you may want to remove it from:" | ||
| print_info " ~/.bashrc, ~/.zshrc, or ~/.bash_profile" | ||
| else | ||
| print_info "~/.local/bin is not in your PATH" | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): PATH check may produce false positives if $HOME/.local/bin is a substring of another path entry.
Consider splitting PATH by ':' and comparing each entry directly to avoid matching substrings.
| echo "" | |
| echo "Checking PATH configuration..." | |
| if echo "$PATH" | grep -q "$HOME/.local/bin"; then | |
| print_warning "~/.local/bin is in your PATH" | |
| print_info "If you added this only for ClaudeBox, you may want to remove it from:" | |
| print_info " ~/.bashrc, ~/.zshrc, or ~/.bash_profile" | |
| else | |
| print_info "~/.local/bin is not in your PATH" | |
| fi | |
| echo "" | |
| echo "Checking PATH configuration..." | |
| PATH_HAS_LOCAL_BIN=false | |
| IFS=':' read -ra PATH_ENTRIES <<< "$PATH" | |
| for entry in "${PATH_ENTRIES[@]}"; do | |
| if [ "$entry" = "$HOME/.local/bin" ]; then | |
| PATH_HAS_LOCAL_BIN=true | |
| break | |
| fi | |
| done | |
| if [ "$PATH_HAS_LOCAL_BIN" = true ]; then | |
| print_warning "~/.local/bin is in your PATH" | |
| print_info "If you added this only for ClaudeBox, you may want to remove it from:" | |
| print_info " ~/.bashrc, ~/.zshrc, or ~/.bash_profile" | |
| else | |
| print_info "~/.local/bin is not in your PATH" | |
| fi |
Summary
Details
This PR introduces
uninstall.sh, a complete uninstallation script that:Features
~/.local/bin/~/.claudebox.claudebox-*)User Experience
Safety
set -efor error handlingTest Plan
🤖 Generated with Claude Code
Summary by Sourcery
Introduce a comprehensive uninstall.sh script to fully remove ClaudeBox components, including symlink, installation and project-specific directories, Docker containers and images, and optionally the installer file, with user-friendly colored output and safety checks
New Features:
Enhancements: