fix(install): handle nested skills/ subdirectory (e.g. dev-test)
resolve_skills_src() detects when SKILL.md is one level deeper than skills/ and uses that subdirectory as rsync source instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -116,6 +116,25 @@ read_field() {
|
|||||||
python3 -c "import json,sys; d=json.load(open('$1')); print(d.get('$2',''))" 2>/dev/null || true
|
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?) ────────
|
# ── Conflict detection (has local been modified since we installed it?) ────────
|
||||||
has_local_modification() {
|
has_local_modification() {
|
||||||
# Returns 0 (true) if local target differs from repo source, 1 if identical or new
|
# Returns 0 (true) if local target differs from repo source, 1 if identical or new
|
||||||
@@ -193,12 +212,17 @@ install_plugin() {
|
|||||||
fi
|
fi
|
||||||
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
|
# Perform install
|
||||||
if [[ "$install_type" == "command" ]]; then
|
if [[ "$install_type" == "command" ]]; then
|
||||||
# Single-file command → ~/.claude/commands/<name>.md
|
# Single-file command → ~/.claude/commands/<name>.md
|
||||||
local src_md="$skills_dir/SKILL.md"
|
local src_md="$src_dir/SKILL.md"
|
||||||
if [[ ! -f "$src_md" ]]; then
|
if [[ ! -f "$src_md" ]]; then
|
||||||
warn "$install_name: skills/SKILL.md not found, skipping"
|
warn "$install_name: SKILL.md not found, skipping"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -219,8 +243,8 @@ install_plugin() {
|
|||||||
dry "$install_name → $dst_dir/"
|
dry "$install_name → $dst_dir/"
|
||||||
else
|
else
|
||||||
mkdir -p "$dst_dir"
|
mkdir -p "$dst_dir"
|
||||||
# rsync: copy entire skills/ directory content preserving structure
|
# rsync resolved source (handles nested skills/ structures)
|
||||||
rsync -a --delete "$skills_dir/" "$dst_dir/"
|
rsync -a --delete "$src_dir/" "$dst_dir/"
|
||||||
state_set "$install_name" "$version" "$install_type"
|
state_set "$install_name" "$version" "$install_type"
|
||||||
ok "$install_name → skill (v$version)"
|
ok "$install_name → skill (v$version)"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user