diff --git a/server/lib/22-claude-config.sh b/server/lib/22-claude-config.sh index 19b1280..0c35e00 100755 --- a/server/lib/22-claude-config.sh +++ b/server/lib/22-claude-config.sh @@ -203,6 +203,14 @@ else info "linked $CHOOK_LINK -> $CHOOK_DST" fi +# A project dropped from the payload loses its files to rsync --delete but can +# keep its now-empty directories, and an empty entry is indistinguishable from an +# adopted project to anything reading this directory. Pruned here so that +# un-adopting a project is complete rather than half-done. -delete implies +# -depth, so nested empties go bottom-up in one pass. +[[ $PRINT_ONLY -eq 1 ]] || \ + find "$DST/project-config" -mindepth 1 -type d -empty -delete 2>/dev/null + # ---- project config links --------------------------------------------------- # Each delivered project-config/ is reached from ~/workspace/ # through a relative symlink. On the laptop laptop/adopt-project-config.sh diff --git a/verify.sh b/verify.sh index 465ca7a..61747a5 100755 --- a/verify.sh +++ b/verify.sh @@ -158,6 +158,11 @@ check "chook config resolves to the delivered file" "$HOME/.claude/chook.toml" \ echo "=== project config ===" for cfg in "$HOME"/.claude/project-config/*/; do [[ -d "$cfg" ]] || continue # no match: the glob stays literal + # A directory holding no files is not an adopted project. rsync --delete + # removes the files of an entry dropped from the payload but can leave its + # directories behind, and asserting a link for one of those reports drift for + # a project that was deliberately un-adopted. + [[ -n "$(find "$cfg" -type f -print -quit 2>/dev/null)" ]] || continue pname=$(basename "$cfg") proj="$HOME/workspace/$pname" [[ -d "$proj" ]] || continue