diff --git a/install-skills.sh b/install-skills.sh index 9038bfe..94245da 100755 --- a/install-skills.sh +++ b/install-skills.sh @@ -116,6 +116,25 @@ read_field() { python3 -c "import json,sys; d=json.load(open('$1')); print(d.get('$2',''))" 2>/dev/null || true } +# Resolve the actual source directory to rsync from. +# If skills/ has SKILL.md at the top level, use it directly. +# If skills/ has a single subdirectory (e.g. skills/dev-test/SKILL.md), use that subdirectory. +resolve_skills_src() { + local skills_dir="$1" + if [[ -f "$skills_dir/SKILL.md" ]]; then + echo "$skills_dir" + return + fi + # Find the first subdirectory that contains SKILL.md + local sub + sub="$(find "$skills_dir" -maxdepth 2 -name 'SKILL.md' | head -1)" + if [[ -n "$sub" ]]; then + echo "$(dirname "$sub")" + return + fi + echo "$skills_dir" +} + # ── Conflict detection (has local been modified since we installed it?) ──────── has_local_modification() { # Returns 0 (true) if local target differs from repo source, 1 if identical or new @@ -193,12 +212,17 @@ install_plugin() { fi fi + # Resolve actual source (handles plugins where content sits one level deeper, + # e.g. skills/dev-test/SKILL.md instead of skills/SKILL.md) + local src_dir + src_dir="$(resolve_skills_src "$skills_dir")" + # Perform install if [[ "$install_type" == "command" ]]; then # Single-file command → ~/.claude/commands/.md - local src_md="$skills_dir/SKILL.md" + local src_md="$src_dir/SKILL.md" if [[ ! -f "$src_md" ]]; then - warn "$install_name: skills/SKILL.md not found, skipping" + warn "$install_name: SKILL.md not found, skipping" return fi @@ -219,8 +243,8 @@ install_plugin() { dry "$install_name → $dst_dir/" else mkdir -p "$dst_dir" - # rsync: copy entire skills/ directory content preserving structure - rsync -a --delete "$skills_dir/" "$dst_dir/" + # rsync resolved source (handles nested skills/ structures) + rsync -a --delete "$src_dir/" "$dst_dir/" state_set "$install_name" "$version" "$install_type" ok "$install_name → skill (v$version)" fi