Compare commits

..

2 commits

Author SHA1 Message Date
78a3104bae
also copy sibling files 2026-04-07 16:48:47 +02:00
014c3c3016
add source reference 2026-04-07 16:22:55 +02:00
2 changed files with 65 additions and 5 deletions

View file

@ -22,7 +22,7 @@ Use this skill to install another skill from a local path, a directory, or a Git
- Local `SKILL.md` file - Local `SKILL.md` file
- Local skill directory - Local skill directory
- GitHub blob URL to a `SKILL.md` file - GitHub blob URL to a `SKILL.md` file, including sibling supporting files
## Install script ## Install script
@ -50,5 +50,7 @@ The installer prompts for:
1. Source path or URL 1. Source path or URL
2. Target scope: repo or global 2. Target scope: repo or global
3. Skill name if it cannot be inferred 3. Skill name if it cannot be inferred
4. Whether to copy supporting files 4. Whether to copy supporting files for a local directory source
5. Whether to overwrite an existing install 5. Whether to overwrite an existing install
For GitHub blob URLs, supporting files in the same skill directory are downloaded automatically.

View file

@ -35,6 +35,16 @@ rewrite_github_blob_url() {
fi fi
} }
parse_github_blob_url() {
local url="$1"
if [[ "$url" =~ ^https://github\.com/([^/]+)/([^/]+)/blob/([^/]+)/(.*)$ ]]; then
printf '%s\t%s\t%s\t%s\n' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}" "${BASH_REMATCH[4]}"
return 0
fi
return 1
}
extract_skill_name() { extract_skill_name() {
local file="$1" local file="$1"
sed -n 's/^name:[[:space:]]*//p' "$file" | head -n 1 sed -n 's/^name:[[:space:]]*//p' "$file" | head -n 1
@ -46,6 +56,45 @@ download_source() {
curl -fsSL "$url" -o "$out" curl -fsSL "$url" -o "$out"
} }
list_github_contents() {
local owner="$1"
local repo="$2"
local ref="$3"
local path="$4"
curl -fsSL -H 'Accept: application/vnd.github+json' \
"https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${ref}" | \
python3 -c $'import json,sys\ndata = json.load(sys.stdin)\nitems = data if isinstance(data, list) else [data]\nfor item in items:\n print("%s\\t%s\\t%s" % (item.get("type", ""), item.get("path", ""), item.get("download_url", "")))'
}
download_github_contents() {
local owner="$1"
local repo="$2"
local ref="$3"
local path="$4"
local target_root="$5"
while IFS=$'\t' read -r item_type item_path download_url; do
[[ -z "$item_type" ]] && continue
local relative_path="${item_path#${path}/}"
local destination_path="$target_root/$relative_path"
case "$item_type" in
dir)
download_github_contents "$owner" "$repo" "$ref" "$item_path" "$target_root"
;;
file)
mkdir -p "$(dirname "$destination_path")"
download_source "$download_url" "$destination_path"
;;
*)
printf 'Skipping unsupported GitHub content type: %s (%s)\n' "$item_type" "$item_path" >&2
;;
esac
done < <(list_github_contents "$owner" "$repo" "$ref" "$path")
}
copy_skill_dir() { copy_skill_dir() {
local source_dir="$1" local source_dir="$1"
local target_dir="$2" local target_dir="$2"
@ -82,9 +131,16 @@ source_kind=""
source_path="$source_input" source_path="$source_input"
if [[ "$source_input" =~ ^https?:// ]]; then if [[ "$source_input" =~ ^https?:// ]]; then
if github_blob_parts="$(parse_github_blob_url "$source_input")"; then
source_kind="github-blob-url"
IFS=$'\t' read -r github_owner github_repo github_ref github_path <<<"$github_blob_parts"
github_skill_dir="$(dirname "$github_path")"
download_github_contents "$github_owner" "$github_repo" "$github_ref" "$github_skill_dir" "$staging_dir"
else
source_kind="url" source_kind="url"
source_path="$(rewrite_github_blob_url "$source_input")" source_path="$(rewrite_github_blob_url "$source_input")"
download_source "$source_path" "$staging_dir/SKILL.md" download_source "$source_path" "$staging_dir/SKILL.md"
fi
elif [[ -d "$source_input" ]]; then elif [[ -d "$source_input" ]]; then
source_kind="directory" source_kind="directory"
skill_file="$source_input/SKILL.md" skill_file="$source_input/SKILL.md"
@ -142,4 +198,6 @@ if [[ ! -f "$target_dir/SKILL.md" ]]; then
exit 1 exit 1
fi fi
echo "<$source_input>" >"$target_dir/source.md"
printf 'Installed %s skill to %s\n' "$skill_name" "$target_dir" printf 'Installed %s skill to %s\n' "$skill_name" "$target_dir"