#!/bin/bash # Skill Tracker - Tracks installed ClawHub skills for auto-recovery after updates # Location: ~/.openclaw/workspace/scripts/skill-tracker.sh STATE_SKILLS_DIR="$HOME/.openclaw/skills" WORKSPACE_SKILLS_DIR="$HOME/.openclaw/workspace/skills" TRACKER_FILE="$HOME/.openclaw/workspace/.installed-skills.json" LOG_FILE="$HOME/.openclaw/workspace/logs/skill-tracker.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # Ensure log directory exists mkdir -p "$(dirname "$LOG_FILE")" # Get list of installed skills from state directory get_state_skills() { if [ -d "$STATE_SKILLS_DIR" ]; then # List directories and symlinks (skip .json metadata files) find "$STATE_SKILLS_DIR" -maxdepth 1 -mindepth 1 \( -type d -o -type l \) -exec basename {} \; 2>/dev/null | sort fi } # Get list of workspace skills get_workspace_skills() { if [ -d "$WORKSPACE_SKILLS_DIR" ]; then find "$WORKSPACE_SKILLS_DIR" -maxdepth 1 -mindepth 1 -type d -exec basename {} \; 2>/dev/null | sort fi } # Save current state to tracker file save_state() { local state_skills=$(get_state_skills | jq -R . | jq -s .) local workspace_skills=$(get_workspace_skills | jq -R . | jq -s .) cat > "$TRACKER_FILE" </dev/null) for skill in $expected_state; do if ! echo "$state_skills" | grep -qx "$skill"; then missing_skills+=("$skill") fi done if [ ${#missing_skills[@]} -eq 0 ]; then log "All skills accounted for ✓" return 0 fi log "Found ${#missing_skills[@]} missing skill(s): ${missing_skills[*]}" # Try to reinstall each missing skill local failed=() for skill in "${missing_skills[@]}"; do log "Attempting to reinstall: $skill" if clawhub install "$skill" 2>&1 | tee -a "$LOG_FILE"; then log "✓ Reinstalled: $skill" else log "✗ Failed to reinstall: $skill" failed+=("$skill") fi done # Update tracker with new state save_state if [ ${#failed[@]} -gt 0 ]; then log "WARNING: Failed to reinstall: ${failed[*]}" return 1 fi return 0 } # Main command handler case "${1:-save}" in save) save_state ;; check) check_and_restore ;; restore) check_and_restore ;; status) if [ -f "$TRACKER_FILE" ]; then echo "=== Skill Tracker Status ===" cat "$TRACKER_FILE" | jq . echo "" echo "=== Current State Skills ===" get_state_skills | jq -R . | jq -s . else echo "No tracker file found. Run: skill-tracker.sh save" fi ;; *) echo "Usage: $0 {save|check|restore|status}" echo "" echo "Commands:" echo " save - Save current skill state to tracker file" echo " check - Check for missing skills and restore them" echo " restore - Same as check (alias)" echo " status - Show current tracker status" exit 1 ;; esac