diff --git a/README.md b/README.md index 27d8c9b..62ba666 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,13 @@ Run manually: ~/.mosaic/bin/mosaic-link-runtime-assets ``` +Prune migrated legacy backups from runtime folders (dry-run by default): + +```bash +~/.mosaic/bin/mosaic-prune-legacy-runtime --runtime claude +~/.mosaic/bin/mosaic-prune-legacy-runtime --runtime claude --apply +``` + Opt-out during install: ```bash diff --git a/bin/mosaic-prune-legacy-runtime b/bin/mosaic-prune-legacy-runtime new file mode 100755 index 0000000..641804f --- /dev/null +++ b/bin/mosaic-prune-legacy-runtime @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.mosaic}" +RUNTIME="claude" +APPLY=0 + +usage() { + cat < Runtime to prune (default: claude) + --apply Perform deletions (default: dry-run) + -h, --help Show help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --runtime) + [[ $# -lt 2 ]] && { echo "Missing value for --runtime" >&2; exit 1; } + RUNTIME="$2" + shift 2 + ;; + --apply) + APPLY=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage >&2 + exit 1 + ;; + esac +done + +case "$RUNTIME" in + claude) + TARGET_ROOT="$HOME/.claude" + ;; + *) + echo "Unsupported runtime: $RUNTIME" >&2 + exit 1 + ;; +esac + +if [[ ! -d "$TARGET_ROOT" ]]; then + echo "[mosaic-prune] Runtime directory not found: $TARGET_ROOT" >&2 + exit 1 +fi + +mosaic_real="$(readlink -f "$MOSAIC_HOME")" +count_candidates=0 +count_deletable=0 + +while IFS= read -r -d '' bak; do + count_candidates=$((count_candidates + 1)) + + base="${bak%%.mosaic-bak-*}" + if [[ ! -L "$base" ]]; then + continue + fi + + base_real="$(readlink -f "$base" 2>/dev/null || true)" + if [[ -z "$base_real" ]]; then + continue + fi + + if [[ "$base_real" != "$mosaic_real"/* ]]; then + continue + fi + + count_deletable=$((count_deletable + 1)) + if [[ $APPLY -eq 1 ]]; then + rm -f "$bak" + echo "[mosaic-prune] deleted: $bak" + else + echo "[mosaic-prune] would delete: $bak" + fi +done < <(find "$TARGET_ROOT" -type f -name '*.mosaic-bak-*' -print0) + +if [[ $APPLY -eq 1 ]]; then + echo "[mosaic-prune] complete: deleted=$count_deletable candidates=$count_candidates runtime=$RUNTIME" +else + echo "[mosaic-prune] dry-run: deletable=$count_deletable candidates=$count_candidates runtime=$RUNTIME" + echo "[mosaic-prune] re-run with --apply to delete" +fi