Skip to content

Commit 4231fee

Browse files
Make uninstall reverse everything it installed, not just skills
Only skills had a branch that removed what the backup lacked. Everything else relied on restoring a prior version over the top, which works on a machine that had one and does nothing at all on a fresh install. Uninstalling a first-time install therefore left 8 agents, 14 commands, 4 hooks and 7 wrappers behind with nothing to say where they came from. Same rule, applied to the rest. A file the backup has is restored; a file it does not have was added by vstack and goes. Symlinks are still never touched. settings.json and .claude.json stay out of it on purpose. install.sh merges those rather than copying them, so no version of either belongs solely to vstack, and deleting one would take the user's own configuration with it. Found by running the lane rather than reading it, in a scratch HOME seeded with a file the installer overwrites and one it never touches. Worth recording that the first attempt to measure this read `uninstall.sh | tail` and reported exit 0 for the no --yes case. Unpiped it is 1, as documented. That is twice now that a pipe has produced a false green in this repo. .audit/ is gitignored: decision logs carry machine detail.
1 parent d19ccf3 commit 4231fee

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
.DS_Store
44
secrets.env
55
.gh-token.cache
6+
7+
# Local audit trails: decision logs carry machine detail and are not launch material.
8+
.audit/

uninstall.sh

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,35 @@ for d in "$SRC"/claude/skills/*/; do
126126
REMOVE_LIST="$REMOVE_LIST $s"
127127
done
128128

129-
if [ "$PLAN_EMPTY" = 1 ] && [ -z "$REMOVE_LIST" ]; then
129+
# Same rule, applied to everything else this repo copies in. It only ever ran for skills, so
130+
# uninstalling a fresh install left 8 agents, 14 commands, 4 hooks and 7 wrappers sitting in
131+
# ~/.claude with nothing to say where they came from: the backup held no prior version to
132+
# restore over them, and only skills had a branch that removed what the backup lacked.
133+
#
134+
# settings.json and .claude.json are deliberately not in this list. install.sh MERGES those
135+
# rather than copying them, so there is no version of them that belongs solely to vstack —
136+
# deleting either would take the user's own configuration with it. If the backup holds a prior
137+
# copy, the restore pass above already put it back.
138+
FILE_REMOVE_LIST=""
139+
plan_file_removal() { # <installed-path>
140+
tgt="$1"
141+
[ -e "$tgt" ] || return 0
142+
[ -L "$tgt" ] && return 0
143+
[ -e "$BK/files/${tgt#"$HOME"/}" ] && return 0 # backup has a prior version; restore covers it
144+
echo "remove $tgt (installed by vstack, not present in backup)"
145+
FILE_REMOVE_LIST="$FILE_REMOVE_LIST $tgt"
146+
}
147+
for f in "$SRC"/claude/hooks/*.sh; do [ -e "$f" ] && plan_file_removal "$HOME/.claude/hooks/$(basename "$f")"; done
148+
for f in "$SRC"/claude/agents/*.md; do [ -e "$f" ] && plan_file_removal "$HOME/.claude/agents/$(basename "$f")"; done
149+
for f in "$SRC"/claude/commands/*.md; do [ -e "$f" ] && plan_file_removal "$HOME/.claude/commands/$(basename "$f")"; done
150+
for f in "$SRC"/bin/*; do [ -e "$f" ] && plan_file_removal "$HOME/.config/agents/bin/$(basename "$f")"; done
151+
plan_file_removal "$HOME/.claude/CLAUDE.md"
152+
plan_file_removal "$HOME/.claude/statusline.sh"
153+
plan_file_removal "$HOME/.claude/skills/LICENSE.pstack"
154+
plan_file_removal "$HOME/.claude/skills/ATTRIBUTION.md"
155+
plan_file_removal "$HOME/.config/agents/shell/claude-parity.zsh"
156+
157+
if [ "$PLAN_EMPTY" = 1 ] && [ -z "$REMOVE_LIST" ] && [ -z "$FILE_REMOVE_LIST" ]; then
130158
echo "(backup is empty — nothing to restore)"
131159
fi
132160

@@ -167,5 +195,9 @@ for s in $REMOVE_LIST; do
167195
[ -L "$tgt" ] && continue
168196
[ -e "$tgt" ] && rm -rf "$tgt"
169197
done
198+
for tgt in $FILE_REMOVE_LIST; do
199+
[ -L "$tgt" ] && continue
200+
[ -e "$tgt" ] && rm -f "$tgt"
201+
done
170202

171203
echo "restore complete."

0 commit comments

Comments
 (0)