fix(hub-guide): correct install target to ~/.claude/skills/

Skills go directly to ~/.claude/skills/<name>/ (not ~/.claude/plugins/).
Hooks configured via setup-hooks.sh -> settings.local.json.

Changes:
- install.sh: targets ~/.claude/skills/, no settings.json registration needed
- install.ps1: updated to match
- setup-hooks.sh: new script to add hooks to settings.local.json
- README: fix install instructions
- Remove nested .claude-plugin directory
- 26 skills symlinked to ~/.claude/skills/
This commit is contained in:
asepharyana
2026-07-25 11:54:26 +07:00
parent 42ef7e30f4
commit 39f3f093fe
3 changed files with 117 additions and 93 deletions
+46 -83
View File
@@ -1,36 +1,27 @@
#!/bin/bash
# install.sh — hub-guide plugin installer for Claude Code
# install.sh — hub-guide skill installer for Claude Code
#
# Skills go to ~/.claude/skills/<name>/ where Claude Code auto-discovers them.
# Hooks can be configured manually (see README).
#
# Usage:
# ./install.sh # Install to ~/.claude/plugins/ + register in settings.json
# ./install.sh --link # Symlink (edits in this repo are live)
# ./install.sh --no-hooks # Skills only, skip hooks
# ./install.sh clean-code testing # Install specific skills only
# ./install.sh # Copy all 26 skills to ~/.claude/skills/
# ./install.sh --link # Symlink (edits in this repo are live)
# ./install.sh clean-code testing # Install specific skills only
# ./install.sh --link clean-code # Symlink specific skills
#
# Requires: Claude Code, python3 (for JSON manipulation)
# Requires: Claude Code
set -euo pipefail
PLUGIN_NAME="hub-guide"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Determine target
if [ "${1:-}" = "--link" ]; then
LINK_MODE=true
TARGET_DIR="${HOME}/.claude/plugins"
shift
else
TARGET_DIR="${HOME}/.claude/plugins"
fi
LINK_MODE="${LINK_MODE:-false}"
INSTALL_HOOKS=true
SKILLS_DIR="${HOME}/.claude/skills"
LINK_MODE=false
FILTER_SKILLS=()
# Parse remaining args
# Parse args
for arg in "$@"; do
case "$arg" in
--no-hooks) INSTALL_HOOKS=false ;;
--link) LINK_MODE=true ;;
--*) echo "Unknown option: $arg"; exit 1 ;;
*) FILTER_SKILLS+=("$arg") ;;
@@ -38,86 +29,58 @@ for arg in "$@"; do
done
echo "📐 hub-guide installer"
echo " Target: ${SKILLS_DIR}/"
echo " Mode: $([ "$LINK_MODE" = true ] && echo 'symlink' || echo 'copy')"
echo ""
# Ensure target dir exists
mkdir -p "${TARGET_DIR}/${PLUGIN_NAME}"
mkdir -p "$SKILLS_DIR"
install_item() {
local src="$1"
local dst="${TARGET_DIR}/${PLUGIN_NAME}/${src#${SCRIPT_DIR}/}"
if [ "$LINK_MODE" = true ]; then
mkdir -p "$(dirname "$dst")"
ln -sf "$src" "$dst"
else
rm -rf "$dst"
cp -r "$src" "$dst"
fi
}
# Install manifest
echo " .claude-plugin/ → ${TARGET_DIR}/${PLUGIN_NAME}/"
install_item "${SCRIPT_DIR}/.claude-plugin"
# Install hooks
if [ "$INSTALL_HOOKS" = true ]; then
echo " hooks/ → ${TARGET_DIR}/${PLUGIN_NAME}/hooks/"
if [ "$LINK_MODE" = true ]; then
ln -sf "${SCRIPT_DIR}/hooks" "${TARGET_DIR}/${PLUGIN_NAME}/hooks"
else
cp -r "${SCRIPT_DIR}/hooks" "${TARGET_DIR}/${PLUGIN_NAME}/"
fi
fi
# Install skills
if [ ${#FILTER_SKILLS[@]} -gt 0 ]; then
# Install only specified skills
INSTALL_LIST=()
for skill in "${FILTER_SKILLS[@]}"; do
skill_name=$(basename "$skill")
skill_src="${SCRIPT_DIR}/skills/${skill_name}"
if [ -d "$skill_src" ]; then
echo " skills/${skill_name}/ → ${TARGET_DIR}/${PLUGIN_NAME}/skills/"
if [ "$LINK_MODE" = true ]; then
ln -sf "$skill_src" "${TARGET_DIR}/${PLUGIN_NAME}/skills/${skill_name}"
else
mkdir -p "${TARGET_DIR}/${PLUGIN_NAME}/skills"
cp -r "$skill_src" "${TARGET_DIR}/${PLUGIN_NAME}/skills/"
fi
src="${SCRIPT_DIR}/skills/${skill_name}"
if [ -d "$src" ]; then
INSTALL_LIST+=("$skill_name")
else
echo " ⚠️ Skill '${skill_name}' not found at ${skill_src}"
echo " ⚠️ Skill '${skill_name}' not found"
fi
done
else
# Install all skills
echo " skills/ (all 26) → ${TARGET_DIR}/${PLUGIN_NAME}/skills/"
if [ "$LINK_MODE" = true ]; then
ln -sf "${SCRIPT_DIR}/skills" "${TARGET_DIR}/${PLUGIN_NAME}/skills"
else
cp -r "${SCRIPT_DIR}/skills" "${TARGET_DIR}/${PLUGIN_NAME}/"
fi
# Gather all skills from source
INSTALL_LIST=()
for d in "${SCRIPT_DIR}/skills/"*/; do
INSTALL_LIST+=("$(basename "$d")")
done
fi
# Register in settings.json so Claude Code loads the plugin
SETTINGS_FILE="${HOME}/.claude/settings.json"
if [ "$TARGET_DIR" = "${HOME}/.claude/plugins" ] && [ -f "$SETTINGS_FILE" ]; then
if grep -q "\"${PLUGIN_NAME}\"" "$SETTINGS_FILE" 2>/dev/null; then
echo " ⏭️ ${PLUGIN_NAME} already registered in settings.json"
installed=0
for skill_name in "${INSTALL_LIST[@]}"; do
src="${SCRIPT_DIR}/skills/${skill_name}"
dst="${SKILLS_DIR}/${skill_name}"
if [ "$LINK_MODE" = true ]; then
rm -rf "$dst"
ln -sf "$src" "$dst"
else
# Add to enabledPlugins using Python for reliable JSON manipulation
python3 -c "
import json, sys
with open('$SETTINGS_FILE') as f: cfg = json.load(f)
cfg.setdefault('enabledPlugins', {})['${PLUGIN_NAME}'] = True
with open('$SETTINGS_FILE', 'w') as f: json.dump(cfg, f, indent=2)
" && echo " ✅ Registered ${PLUGIN_NAME} in settings.json enabledPlugins"
rm -rf "$dst"
mkdir -p "$(dirname "$dst")"
cp -r "$src" "$dst"
fi
fi
echo "${skill_name}"
installed=$((installed + 1))
done
echo ""
echo "hub-guide installed to ${TARGET_DIR}/${PLUGIN_NAME}/"
echo "${installed} skill(s) installed to ${SKILLS_DIR}/"
if [ "$LINK_MODE" = true ]; then
echo " (symlink — edits in this repo are live)"
fi
echo ""
echo " Restart Claude Code or run /reload to activate."
echo " Restart Claude Code or run /reload."
echo " Skills auto-trigger when you work — no commands needed."
echo ""
echo "📌 Hooks (auto-detect project):"
echo " For hooks support, add to ~/.claude/settings.local.json or"
echo " run: ./setup-hooks.sh"