Fix SEO skills 19-34, add global slash commands, update installer (#4)

* Fix SEO skill 34 bugs, Korean labels, and transition Ahrefs refs to our-seo-agent

P0: Fix report_aggregator.py — wrong SKILL_REGISTRY[33] mapping, missing
CATEGORY_WEIGHTS for 7 categories, and break bug in health score parsing
that exited loop even on parse failure.

P1: Remove VIEW tab references from skill 20, expand skill 32 docs,
replace Ahrefs MCP references across all 16 skills (19-28, 31-34)
with our-seo-agent CLI data source references.

P2: Fix Korean labels in executive_report.py and dashboard_generator.py,
add tenacity to base requirements, sync skill 34 base_client.py with
canonical version from skill 12.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add Claude Code slash commands for SEO skills 19-34 and fix stale paths

Create 14 new slash command files for skills 19-28, 31-34 so they
appear as /seo-* commands in Claude Code. Also fix stale directory
paths in 8 existing commands (skills 12-18, 29-30) that referenced
pre-renumbering skill directories.

Update .gitignore to track .claude/commands/ while keeping other
.claude/ files ignored.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add 8 slash commands, enhance reference-curator with depth/output options

- Add slash commands: ourdigital-brand-guide, notion-writer, notebooklm-agent,
  notebooklm-automation, notebooklm-studio, notebooklm-research,
  reference-curator, multi-agent-guide
- Add --depth (light/standard/deep/full) with Firecrawl parameter mapping
- Add --output with ~/Documents/reference-library/ default and user confirmation
- Increase --max-sources default from 10 to 100
- Rename /reference-curator-pipeline to /reference-curator
- Simplify web-crawler-orchestrator label to web-crawler in docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Convert slash command script paths to absolute for global availability

Symlinked all 39 project commands to ~/.claude/commands/ so they work
from any project directory. Converted 126 relative custom-skills/ paths
to absolute /Users/ourdigital/Projects/our-claude-skills/custom-skills/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update installer to support global slash command installation

Add symlink-based global command setup so all 39 custom skills work from
any project directory. New --commands flag for quick re-sync, updated
--validate/--update/--uninstall to handle symlinks, and expanded skill
listing to cover all 7 domains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add user guides in English and Korean for all 52 custom skills

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Andrew Yim
2026-02-24 14:37:54 +09:00
committed by GitHub
parent 397fa2aa5d
commit 2aa9d098cb
41 changed files with 2948 additions and 160 deletions

View File

@@ -7,6 +7,7 @@
# ./install.sh # Interactive install
# ./install.sh --update # Update existing installation
# ./install.sh --uninstall # Remove installation
# ./install.sh --commands # Only install/update global slash commands
# ./install.sh --help # Show help
#
@@ -23,9 +24,12 @@ NC='\033[0m' # No Color
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILLS_DIR="$(dirname "$SCRIPT_DIR")"
REPO_DIR="$(dirname "$SKILLS_DIR")"
ENV_FILE="$HOME/.env.ourdigital"
CONFIG_DIR="$HOME/.ourdigital"
VENV_DIR="$SKILLS_DIR/.venv-ourdigital"
CLAUDE_COMMANDS_DIR="$HOME/.claude/commands"
REPO_COMMANDS_DIR="$REPO_DIR/.claude/commands"
# Print banner
print_banner() {
@@ -70,6 +74,13 @@ check_prerequisites() {
missing+=("git")
fi
# Check Claude Code CLI
if command -v claude &> /dev/null; then
success "Claude Code CLI available"
else
warn "Claude Code CLI not found (slash commands require it)"
fi
# Check 1Password CLI (optional)
if command -v op &> /dev/null; then
success "1Password CLI available"
@@ -101,6 +112,92 @@ setup_directories() {
mkdir -p "$CONFIG_DIR/logs"
success "Created $CONFIG_DIR/logs/"
# Create Claude commands directory
mkdir -p "$CLAUDE_COMMANDS_DIR"
success "Created $CLAUDE_COMMANDS_DIR/"
echo ""
}
# Install global slash commands via symlinks
setup_global_commands() {
info "Setting up global slash commands..."
if [[ ! -d "$REPO_COMMANDS_DIR" ]]; then
error "Commands directory not found: $REPO_COMMANDS_DIR"
echo " Make sure you're running from the our-claude-skills repository."
return 1
fi
mkdir -p "$CLAUDE_COMMANDS_DIR"
local linked=0
local skipped=0
local updated=0
for cmd_file in "$REPO_COMMANDS_DIR"/*.md; do
[[ -f "$cmd_file" ]] || continue
local filename
filename=$(basename "$cmd_file")
local target="$CLAUDE_COMMANDS_DIR/$filename"
if [[ -L "$target" ]]; then
local current_link
current_link=$(readlink "$target")
if [[ "$current_link" == "$cmd_file" ]]; then
((skipped++))
else
rm "$target"
ln -s "$cmd_file" "$target"
((updated++))
fi
elif [[ -f "$target" ]]; then
warn "Skipping $filename (non-symlink file exists at $target)"
((skipped++))
else
ln -s "$cmd_file" "$target"
((linked++))
fi
done
[[ $linked -gt 0 ]] && success "Linked $linked new commands"
[[ $updated -gt 0 ]] && success "Updated $updated existing symlinks"
[[ $skipped -gt 0 ]] && info "Skipped $skipped (already current)"
# Count total symlinks pointing to our repo
local total
total=$(find "$CLAUDE_COMMANDS_DIR" -maxdepth 1 -type l -lname "$REPO_COMMANDS_DIR/*" 2>/dev/null | wc -l | tr -d ' ')
success "Total global commands from this repo: $total"
echo ""
}
# Remove global slash command symlinks
remove_global_commands() {
info "Removing global slash command symlinks..."
if [[ ! -d "$CLAUDE_COMMANDS_DIR" ]]; then
info "No commands directory found, nothing to remove"
return
fi
local removed=0
for link in "$CLAUDE_COMMANDS_DIR"/*.md; do
[[ -L "$link" ]] || continue
local link_target
link_target=$(readlink "$link")
if [[ "$link_target" == "$REPO_COMMANDS_DIR/"* ]]; then
rm "$link"
((removed++))
fi
done
if [[ $removed -gt 0 ]]; then
success "Removed $removed command symlinks"
else
info "No symlinks from this repo found"
fi
echo ""
}
@@ -239,7 +336,7 @@ validate_installation() {
info "Validating installation..."
local checks_passed=0
local checks_total=6
local checks_total=7
# Check directories
[[ -d "$CONFIG_DIR" ]] && ((checks_passed++)) && success "Config directory exists" || warn "Config directory missing"
@@ -255,6 +352,16 @@ validate_installation() {
# Check skills directory
[[ -d "$SKILLS_DIR/01-ourdigital-brand-guide" ]] && ((checks_passed++)) && success "Skills directory valid" || warn "Skills not found"
# Check global commands
local cmd_count
cmd_count=$(find "$CLAUDE_COMMANDS_DIR" -maxdepth 1 -type l -lname "$REPO_COMMANDS_DIR/*" 2>/dev/null | wc -l | tr -d ' ')
if [[ $cmd_count -gt 0 ]]; then
((checks_passed++))
success "Global slash commands installed ($cmd_count commands)"
else
warn "No global slash commands found (run with --commands to install)"
fi
echo ""
echo -e "${CYAN}Validation: $checks_passed/$checks_total checks passed${NC}"
echo ""
@@ -262,17 +369,97 @@ validate_installation() {
# Show installed skills
show_skills() {
info "Installed OurDigital Skills:"
info "Installed Skills:"
echo ""
for dir in "$SKILLS_DIR"/0{1,2,3,4,5,6,7,8,9}-ourdigital-* "$SKILLS_DIR"/10-ourdigital-*; do
if [[ -d "$dir" ]]; then
name=$(basename "$dir")
desc=$(grep -m1 "^name:" "$dir/desktop/SKILL.md" 2>/dev/null | cut -d':' -f2 | xargs || echo "")
echo -e " ${GREEN}${NC} $name"
local categories=(
"OurDigital Core:0{1,2,3,4,5,6,7,8,9}-ourdigital-*,10-ourdigital-*"
"SEO Tools:1{1,2,3,4,5,6,7,8,9}-seo-*,2{0,1,2,3,4,5,6,7,8,9}-seo-*,3{0,1,2,3,4}-seo-*"
"Jamie Clinic:4{0,1,2,3,4,5}-jamie-*"
"NotebookLM:5{0,1,2,3}-notebooklm-*"
"GTM/GA:6{0,1,2}-gtm-*"
"Notion:3{1,2}-notion-*"
"Reference & Multi-Agent:9{0,1}-*"
)
for category in "${categories[@]}"; do
IFS=':' read -r label patterns <<< "$category"
local count=0
local names=()
IFS=',' read -ra pattern_arr <<< "$patterns"
for pattern in "${pattern_arr[@]}"; do
for dir in "$SKILLS_DIR"/$pattern; do
if [[ -d "$dir" ]]; then
((count++))
names+=("$(basename "$dir")")
fi
done
done
if [[ $count -gt 0 ]]; then
echo -e " ${CYAN}$label${NC} ($count skills)"
for name in "${names[@]}"; do
echo -e " ${GREEN}${NC} $name"
done
echo ""
fi
done
}
# Show global command summary
show_global_commands() {
info "Global Slash Commands (available from any project):"
echo ""
if [[ ! -d "$CLAUDE_COMMANDS_DIR" ]]; then
warn "No commands directory found"
return
fi
local cmd_count=0
local categories=()
for link in "$CLAUDE_COMMANDS_DIR"/*.md; do
[[ -L "$link" ]] || continue
local link_target
link_target=$(readlink "$link")
if [[ "$link_target" == "$REPO_COMMANDS_DIR/"* ]]; then
((cmd_count++))
local name
name=$(basename "$link" .md)
categories+=("$name")
fi
done
if [[ $cmd_count -eq 0 ]]; then
warn "No commands symlinked from this repo"
return
fi
# Group by prefix
local seo=0 gtm=0 jamie=0 notebooklm=0 notion=0 ourdigital=0 other=0
for name in "${categories[@]}"; do
case "$name" in
seo-*) ((seo++)) ;;
gtm-*) ((gtm++)) ;;
jamie-*) ((jamie++)) ;;
notebooklm-*) ((notebooklm++)) ;;
notion-*) ((notion++)) ;;
ourdigital-*) ((ourdigital++)) ;;
*) ((other++)) ;;
esac
done
[[ $seo -gt 0 ]] && echo -e " ${GREEN}SEO${NC}: $seo commands (/seo-technical, /seo-keyword-strategy, ...)"
[[ $gtm -gt 0 ]] && echo -e " ${GREEN}GTM${NC}: $gtm commands (/gtm-audit, /gtm-manager)"
[[ $jamie -gt 0 ]] && echo -e " ${GREEN}Jamie${NC}: $jamie commands (/jamie-editor, /jamie-audit)"
[[ $notebooklm -gt 0 ]] && echo -e " ${GREEN}NotebookLM${NC}: $notebooklm commands (/notebooklm-agent, ...)"
[[ $notion -gt 0 ]] && echo -e " ${GREEN}Notion${NC}: $notion commands (/notion-writer, /notion-organizer)"
[[ $ourdigital -gt 0 ]] && echo -e " ${GREEN}OurDigital${NC}: $ourdigital commands (/ourdigital-research, ...)"
[[ $other -gt 0 ]] && echo -e " ${GREEN}Other${NC}: $other commands"
echo ""
echo -e " ${CYAN}Total: $cmd_count global commands${NC}"
echo ""
}
@@ -286,19 +473,20 @@ print_usage() {
echo "2. Edit credentials if needed:"
echo " nano $ENV_FILE"
echo ""
echo "3. Use skills with 'our' or 'ourdigital' prefix:"
echo " - our blog [topic]"
echo " - our research [topic]"
echo " - our 견적서"
echo "3. Use slash commands from any project (globally installed):"
echo " /seo-technical https://example.com"
echo " /reference-curator \"Claude Code best practices\""
echo " /ourdigital-research \"topic\""
echo " /notebooklm-agent"
echo ""
echo "4. Documentation:"
echo " $SKILLS_DIR/OUR_SKILL_PROJECT_PLAN_v1.1.md"
echo "4. Update commands after pulling repo changes:"
echo " ./install.sh --commands"
echo ""
}
# Uninstall
uninstall() {
warn "This will remove OurDigital configuration (not skills)."
warn "This will remove OurDigital configuration and global commands (not skill source files)."
read -p "Continue? (y/N): " -n 1 -r
echo
@@ -307,6 +495,9 @@ uninstall() {
exit 0
fi
# Remove global command symlinks
remove_global_commands
# Backup before removing
if [[ -f "$ENV_FILE" ]]; then
cp "$ENV_FILE" "$ENV_FILE.uninstall.backup"
@@ -334,16 +525,22 @@ show_help() {
echo "Options:"
echo " --help, -h Show this help message"
echo " --update, -u Update existing installation"
echo " --uninstall Remove installation (preserves skills)"
echo " --uninstall Remove installation (preserves skill source files)"
echo " --validate Only run validation checks"
echo " --commands Only install/update global slash commands"
echo " --skip-creds Skip credentials setup"
echo " --skip-venv Skip virtual environment setup"
echo ""
echo "Examples:"
echo " ./install.sh # Full interactive install"
echo " ./install.sh --update # Update existing setup"
echo " ./install.sh --commands # Just install/refresh global commands"
echo " ./install.sh --skip-creds # Install without credentials"
echo ""
echo "Global Commands:"
echo " Slash commands are symlinked to ~/.claude/commands/ so they"
echo " work from any project directory in Claude Code."
echo ""
}
# Main installation flow
@@ -351,6 +548,7 @@ main_install() {
print_banner
check_prerequisites
setup_directories
setup_global_commands
setup_environment
if [[ "$SKIP_CREDS" != true ]]; then
@@ -364,6 +562,7 @@ main_install() {
setup_config
validate_installation
show_skills
show_global_commands
print_usage
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
@@ -387,12 +586,21 @@ while [[ $# -gt 0 ]]; do
;;
--validate)
validate_installation
show_global_commands
exit 0
;;
--commands)
info "Installing/updating global slash commands..."
setup_global_commands
show_global_commands
exit 0
;;
--update|-u)
info "Updating installation..."
setup_global_commands
setup_python_env
validate_installation
show_global_commands
exit 0
;;
--skip-creds)