|
|
@@ -0,0 +1,142 @@
|
|
|
+#!/usr/bin/env bash
|
|
|
+# find-skills - Find and list skills with descriptions
|
|
|
+# Shows all skills by default, filters by pattern if provided
|
|
|
+# Searches personal superpowers first, then core (personal shadows core)
|
|
|
+
|
|
|
+set -euo pipefail
|
|
|
+
|
|
|
+# Determine directories
|
|
|
+PERSONAL_SUPERPOWERS_DIR="${PERSONAL_SUPERPOWERS_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/superpowers}"
|
|
|
+PERSONAL_SKILLS_DIR="${PERSONAL_SUPERPOWERS_DIR}/skills"
|
|
|
+
|
|
|
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
+PLUGIN_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
+CORE_SKILLS_DIR="${PLUGIN_ROOT}/skills"
|
|
|
+
|
|
|
+LOG_FILE="${PERSONAL_SUPERPOWERS_DIR}/search-log.jsonl"
|
|
|
+
|
|
|
+# Show help
|
|
|
+if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
|
|
|
+ cat <<'EOF'
|
|
|
+find-skills - Find and list skills with descriptions
|
|
|
+
|
|
|
+USAGE:
|
|
|
+ find-skills Show all skills with descriptions
|
|
|
+ find-skills PATTERN Filter skills by grep pattern
|
|
|
+ find-skills --help Show this help
|
|
|
+
|
|
|
+EXAMPLES:
|
|
|
+ find-skills # All skills
|
|
|
+ find-skills test # Skills matching "test"
|
|
|
+ find-skills 'test.*driven|TDD' # Regex pattern
|
|
|
+
|
|
|
+OUTPUT:
|
|
|
+ Each line shows: skill-path - description
|
|
|
+ Personal skills listed first, then core skills
|
|
|
+ Personal skills shadow core skills when paths match
|
|
|
+
|
|
|
+SEARCH:
|
|
|
+ Searches both skill content AND path names.
|
|
|
+ Personal skills at: ~/.config/superpowers/skills/
|
|
|
+ Core skills at: plugin installation directory
|
|
|
+EOF
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+# Get pattern (optional)
|
|
|
+PATTERN="${1:-}"
|
|
|
+
|
|
|
+# Function to extract description from SKILL.md
|
|
|
+get_description() {
|
|
|
+ local file="$1"
|
|
|
+ grep "^description:" "$file" 2>/dev/null | sed 's/description: *//' || echo ""
|
|
|
+}
|
|
|
+
|
|
|
+# Function to get relative skill path
|
|
|
+get_skill_path() {
|
|
|
+ local file="$1"
|
|
|
+ local base_dir="$2"
|
|
|
+ local rel_path="${file#$base_dir/}"
|
|
|
+ echo "${rel_path%/SKILL.md}"
|
|
|
+}
|
|
|
+
|
|
|
+# Collect all matching skills (use simple list for bash 3.2 compatibility)
|
|
|
+seen_skills_list=""
|
|
|
+results=()
|
|
|
+
|
|
|
+# If pattern provided, log the search
|
|
|
+if [[ -n "$PATTERN" ]]; then
|
|
|
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
|
+ echo "{\"timestamp\":\"$timestamp\",\"query\":\"$PATTERN\"}" >> "$LOG_FILE" 2>/dev/null || true
|
|
|
+fi
|
|
|
+
|
|
|
+# Search personal skills first
|
|
|
+if [[ -d "$PERSONAL_SKILLS_DIR" ]]; then
|
|
|
+ while IFS= read -r file; do
|
|
|
+ [[ -z "$file" ]] && continue
|
|
|
+
|
|
|
+ skill_path=$(get_skill_path "$file" "$PERSONAL_SKILLS_DIR")
|
|
|
+ description=$(get_description "$file")
|
|
|
+
|
|
|
+ seen_skills_list="${seen_skills_list}${skill_path}"$'\n'
|
|
|
+ results+=("$skill_path|$description")
|
|
|
+ done < <(
|
|
|
+ if [[ -n "$PATTERN" ]]; then
|
|
|
+ # Pattern mode: search content and paths
|
|
|
+ {
|
|
|
+ grep -E -r "$PATTERN" "$PERSONAL_SKILLS_DIR/" --include="SKILL.md" -l 2>/dev/null || true
|
|
|
+ find "$PERSONAL_SKILLS_DIR/" -name "SKILL.md" -type f 2>/dev/null | grep -E "$PATTERN" 2>/dev/null || true
|
|
|
+ } | sort -u
|
|
|
+ else
|
|
|
+ # Show all
|
|
|
+ find "$PERSONAL_SKILLS_DIR/" -name "SKILL.md" -type f 2>/dev/null || true
|
|
|
+ fi
|
|
|
+ )
|
|
|
+fi
|
|
|
+
|
|
|
+# Search core skills (only if not shadowed)
|
|
|
+while IFS= read -r file; do
|
|
|
+ [[ -z "$file" ]] && continue
|
|
|
+
|
|
|
+ skill_path=$(get_skill_path "$file" "$CORE_SKILLS_DIR")
|
|
|
+
|
|
|
+ # Skip if shadowed by personal skill
|
|
|
+ echo "$seen_skills_list" | grep -q "^${skill_path}$" && continue
|
|
|
+
|
|
|
+ description=$(get_description "$file")
|
|
|
+ results+=("$skill_path|$description")
|
|
|
+done < <(
|
|
|
+ if [[ -n "$PATTERN" ]]; then
|
|
|
+ # Pattern mode: search content and paths
|
|
|
+ {
|
|
|
+ grep -E -r "$PATTERN" "$CORE_SKILLS_DIR/" --include="SKILL.md" -l 2>/dev/null || true
|
|
|
+ find "$CORE_SKILLS_DIR/" -name "SKILL.md" -type f 2>/dev/null | grep -E "$PATTERN" 2>/dev/null || true
|
|
|
+ } | sort -u
|
|
|
+ else
|
|
|
+ # Show all
|
|
|
+ find "$CORE_SKILLS_DIR/" -name "SKILL.md" -type f 2>/dev/null || true
|
|
|
+ fi
|
|
|
+)
|
|
|
+
|
|
|
+# Check if we found anything
|
|
|
+if [[ ${#results[@]} -eq 0 ]]; then
|
|
|
+ if [[ -n "$PATTERN" ]]; then
|
|
|
+ echo "❌ No skills found matching: $PATTERN"
|
|
|
+ echo ""
|
|
|
+ echo "Search logged. If a skill should exist, consider writing it!"
|
|
|
+ else
|
|
|
+ echo "❌ No skills found"
|
|
|
+ fi
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+# Sort and display results
|
|
|
+printf "%s\n" "${results[@]}" | sort | while IFS='|' read -r skill_path description; do
|
|
|
+ if [[ -n "$description" ]]; then
|
|
|
+ echo "skills/$skill_path - $description"
|
|
|
+ else
|
|
|
+ echo "skills/$skill_path"
|
|
|
+ fi
|
|
|
+done
|
|
|
+
|
|
|
+exit 0
|