Installing kyberforge via the holocron marketplace caches the plugin at a specific version. After every push, the marketplace clone and plugin cache need to be refreshed manually — otherwise new skills added since the last install are invisible until the user runs `claude plugin update` manually. Adds a post-push git hook that pulls the holocron marketplace clone and updates the kyberforge cache automatically after every push, eliminating the manual refresh step. ## Implementation Notes - `scripts/git-hooks/post-push` is the canonical source; `install.sh` now copies all files in `scripts/git-hooks/` into `.git/hooks/` on fresh checkouts, making the pattern extensible for future hooks. - Hook exits 0 on all failures (warns to stderr) — a stale cache refresh never blocks a completed push. - 11 bats tests cover both the hook and the install.sh copy block, using mocked binaries and a temp-tree fixture to avoid touching real state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P87CiC58Ru2PPWYTeXtjHT
91 lines
2.7 KiB
Bash
Executable File
91 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
# shellcheck source=scripts/deploy-manifest.sh
|
|
source "$REPO_ROOT/scripts/deploy-manifest.sh"
|
|
|
|
# Collect provider skill adapters from all provider-manifest.sh files
|
|
SKILL_ADAPTERS=()
|
|
for provider_manifest in "$REPO_ROOT"/providers/*/provider-manifest.sh; do
|
|
[[ -f "$provider_manifest" ]] || continue
|
|
# shellcheck source=/dev/null
|
|
source "$provider_manifest"
|
|
done
|
|
|
|
echo "Installing from $REPO_ROOT..."
|
|
|
|
for entry in "${DEPLOY_FILES[@]}"; do
|
|
dest="$HOME/${entry##*:}"
|
|
mkdir -p "$(dirname "$dest")"
|
|
cp "$REPO_ROOT/${entry%%:*}" "$dest"
|
|
done
|
|
|
|
for entry in "${DEPLOY_EXECUTABLES[@]}"; do
|
|
dest="$HOME/${entry##*:}"
|
|
mkdir -p "$(dirname "$dest")"
|
|
cp "$REPO_ROOT/${entry%%:*}" "$dest"
|
|
chmod +x "$dest"
|
|
done
|
|
|
|
for entry in "${DEPLOY_DIRS[@]}"; do
|
|
dest="$HOME/${entry##*:}"
|
|
rm -rf "$dest"
|
|
mkdir -p "$dest"
|
|
cp -r "$REPO_ROOT/${entry%%:*}/." "$dest/"
|
|
done
|
|
|
|
# Deploy skills to canonical location — merge per-skill, never wipe the parent
|
|
# Skipped when source does not exist (marketplace architecture: skills installed via plugin)
|
|
skills_dest="$HOME/$DEPLOY_SKILLS_SRC"
|
|
skills_deployed=()
|
|
if [[ -d "$REPO_ROOT/$DEPLOY_SKILLS_SRC" ]]; then
|
|
mkdir -p "$skills_dest"
|
|
for skill_dir in "$REPO_ROOT/$DEPLOY_SKILLS_SRC"/*/; do
|
|
[[ -d "$skill_dir" ]] || continue
|
|
skill_name="$(basename "$skill_dir")"
|
|
rm -rf "${skills_dest:?}/${skill_name:?}"
|
|
cp -r "$skill_dir" "$skills_dest/$skill_name"
|
|
skills_deployed+=("$skill_name")
|
|
done
|
|
fi
|
|
|
|
# Create provider skill adapters as symlinks to the canonical skills location
|
|
for adapter in "${SKILL_ADAPTERS[@]}"; do
|
|
target="$HOME/$adapter"
|
|
if [ -L "$target" ]; then
|
|
ln -sfn "$skills_dest" "$target"
|
|
elif [ -d "$target" ]; then
|
|
echo "Warning: $target exists as a real directory — remove it and re-run install to create the skill adapter symlink."
|
|
else
|
|
ln -s "$skills_dest" "$target"
|
|
fi
|
|
done
|
|
|
|
# Install git hooks into the current repo checkout
|
|
HOOKS_SRC="$REPO_ROOT/scripts/git-hooks"
|
|
if [[ -d "$HOOKS_SRC" ]]; then
|
|
for hook_file in "$HOOKS_SRC"/*; do
|
|
[[ -f "$hook_file" ]] || continue
|
|
hook_name="$(basename "$hook_file")"
|
|
dest_hook="$REPO_ROOT/.git/hooks/$hook_name"
|
|
cp "$hook_file" "$dest_hook"
|
|
chmod +x "$dest_hook"
|
|
done
|
|
fi
|
|
|
|
echo ""
|
|
echo "Deployed:"
|
|
for entry in "${DEPLOY_FILES[@]}" "${DEPLOY_EXECUTABLES[@]}"; do
|
|
echo " ~/${entry##*:}"
|
|
done
|
|
for entry in "${DEPLOY_DIRS[@]}"; do
|
|
echo " ~/${entry##*:}/"
|
|
done
|
|
if [[ ${#skills_deployed[@]} -gt 0 ]]; then
|
|
echo " ~/$DEPLOY_SKILLS_SRC/ (skills: ${skills_deployed[*]})"
|
|
fi
|
|
for adapter in "${SKILL_ADAPTERS[@]}"; do
|
|
echo " ~/$adapter -> ~/$DEPLOY_SKILLS_SRC (symlink)"
|
|
done
|