feat(install): add --force to repoint symlinks; document worktree caveat

install.sh skipped a symlink pointing at another checkout, so there was
no scripted way to take the live set over. Add a --force flag that
repoints such divergent symlinks at the invoking clone (default run still
skips, stays idempotent). Document in INSTALL.md that the plugin must be
developed in the primary clone, not a worktree, and that --force repoints.

closes #17
This commit is contained in:
2026-06-30 14:16:44 +02:00
parent eec4754c3c
commit 69034747c6
2 changed files with 27 additions and 3 deletions
+11 -1
View File
@@ -60,4 +60,14 @@ cd ~/dev/skills && git pull
Symlinks pick up the changes automatically. If new skills or Symlinks pick up the changes automatically. If new skills or
agents have been added, re-run `install.sh` to add the new agents have been added, re-run `install.sh` to add the new
symlinks (it is idempotent and will not overwrite existing symlinks (it is idempotent and will not overwrite existing
ones). ones — pass `--force` to repoint a symlink that points at a
different checkout).
## Worktrees
The symlinks target the absolute path of the clone `install.sh` was
run from. Develop this plugin only in that primary clone, never from a
git worktree: a running session loads skills, agents, and workflows
through the symlinks regardless of cwd, so worktree edits are not what
it executes (see `CLAUDE.md`). To take the live set over from a
different checkout, run `./install.sh --force` from it.
+16 -2
View File
@@ -12,10 +12,19 @@
# #
# Idempotent — existing symlinks pointing to this repo are left # Idempotent — existing symlinks pointing to this repo are left
# alone; existing entries that point elsewhere are reported and # alone; existing entries that point elsewhere are reported and
# skipped. # skipped. Pass --force to repoint such divergent symlinks at this
# clone (used to take the live set over from another checkout).
set -euo pipefail set -euo pipefail
FORCE=0
for arg in "$@"; do
case "$arg" in
--force) FORCE=1 ;;
*) echo "unknown argument: $arg (only --force is accepted)" >&2; exit 2 ;;
esac
done
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CLAUDE_SKILLS="$HOME/.claude/skills" CLAUDE_SKILLS="$HOME/.claude/skills"
@@ -34,7 +43,12 @@ link_one() {
echo "ok $dst -> $src" echo "ok $dst -> $src"
return 0 return 0
fi fi
echo "skip $dst already symlinked to $existing" if [ "$FORCE" -eq 1 ]; then
ln -sfn "$src" "$dst"
echo "relink $dst -> $src (was $existing)"
return 0
fi
echo "skip $dst already symlinked to $existing (use --force to repoint)"
return 0 return 0
fi fi
if [ -e "$dst" ]; then if [ -e "$dst" ]; then