From 26b267c4a2e887ea79882a0ee584a7f9bb8f27a4 Mon Sep 17 00:00:00 2001 From: tw93 Date: Sun, 8 Mar 2026 15:29:25 +0800 Subject: [PATCH] fix: harden orphan cleanup and lsregister fallback --- lib/clean/apps.sh | 11 ++++++++++ lib/core/base.sh | 2 +- tests/clean_apps.bats | 47 +++++++++++++++++++++++++++++++++++++++++++ tests/optimize.bats | 18 +++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/lib/clean/apps.sh b/lib/clean/apps.sh index f1e454d..7fea0cd 100644 --- a/lib/clean/apps.sh +++ b/lib/clean/apps.sh @@ -261,6 +261,17 @@ is_claude_vm_bundle_orphaned() { return 1 fi + if [[ -e "$vm_bundle_path" ]]; then + local last_modified_epoch + last_modified_epoch=$(get_file_mtime "$vm_bundle_path") + local current_epoch + current_epoch=$(get_epoch_seconds) + local days_since_modified=$(((current_epoch - last_modified_epoch) / 86400)) + if [[ $days_since_modified -lt ${ORPHAN_AGE_THRESHOLD:-60} ]]; then + return 1 + fi + fi + if [[ -z "$ORPHAN_MDFIND_CACHE_FILE" ]]; then ORPHAN_MDFIND_CACHE_FILE=$(mktemp "${TMPDIR:-/tmp}/mole_mdfind_cache.XXXXXX") register_temp_file "$ORPHAN_MDFIND_CACHE_FILE" diff --git a/lib/core/base.sh b/lib/core/base.sh index 52c9609..be34ca8 100644 --- a/lib/core/base.sh +++ b/lib/core/base.sh @@ -61,7 +61,7 @@ get_lsregister_path() { fi done echo "" - return 1 + return 0 } # ============================================================================ diff --git a/tests/clean_apps.bats b/tests/clean_apps.bats index a974716..07659b4 100644 --- a/tests/clean_apps.bats +++ b/tests/clean_apps.bats @@ -229,6 +229,8 @@ pgrep() { } run_with_timeout() { shift; "$@"; } +get_file_mtime() { echo 0; } +get_path_size_kb() { echo 4; } safe_clean() { echo "$2" @@ -254,6 +256,51 @@ EOF [[ "$output" == *"PASS: Claude VM removed"* ]] } +@test "clean_orphaned_app_data keeps recent Claude VM bundle when Claude lookup misses" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/apps.sh" + +scan_installed_apps() { + : > "$1" +} + +mdfind() { + return 0 +} + +pgrep() { + return 1 +} + +run_with_timeout() { shift; "$@"; } +get_file_mtime() { date +%s; } + +safe_clean() { + echo "UNEXPECTED:$2" + return 1 +} + +start_section_spinner() { :; } +stop_section_spinner() { :; } + +mkdir -p "$HOME/Library/Caches" +mkdir -p "$HOME/Library/Application Support/Claude/vm_bundles/claudevm.bundle" +echo "vm data" > "$HOME/Library/Application Support/Claude/vm_bundles/claudevm.bundle/rootfs.img" + +clean_orphaned_app_data + +if [[ -d "$HOME/Library/Application Support/Claude/vm_bundles/claudevm.bundle" ]]; then + echo "PASS: Recent Claude VM kept" +fi +EOF + + [ "$status" -eq 0 ] + [[ "$output" != *"UNEXPECTED:Orphaned Claude workspace VM"* ]] + [[ "$output" == *"PASS: Recent Claude VM kept"* ]] +} + @test "clean_orphaned_app_data keeps Claude VM bundle when Claude is installed" { run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' set -euo pipefail diff --git a/tests/optimize.bats b/tests/optimize.bats index a4ef886..00a7b11 100644 --- a/tests/optimize.bats +++ b/tests/optimize.bats @@ -181,3 +181,21 @@ EOF [ "$status" -eq 1 ] [[ "$output" == *"Unknown action"* ]] } + +@test "opt_launch_services_rebuild handles missing lsregister without exiting" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/optimize/tasks.sh" +get_lsregister_path() { + echo "" + return 0 +} +opt_launch_services_rebuild +echo "survived" +EOF + + [ "$status" -eq 0 ] + [[ "$output" == *"lsregister not found"* ]] + [[ "$output" == *"survived"* ]] +}