aboutsummaryrefslogtreecommitdiffstats
path: root/.agents/skills/skill-improver/scripts
diff options
context:
space:
mode:
authorsillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
committersillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
commit898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch)
tree85c6ee5ad58b860144551184d4cf86b560c62b91 /.agents/skills/skill-improver/scripts
downloadwww-main.tar.gz
www-main.zip
import live www.sillylaird.ca webrootHEADmain
Diffstat (limited to '.agents/skills/skill-improver/scripts')
-rwxr-xr-x.agents/skills/skill-improver/scripts/backup-skill.sh56
-rwxr-xr-x.agents/skills/skill-improver/scripts/verify-update.sh251
2 files changed, 307 insertions, 0 deletions
diff --git a/.agents/skills/skill-improver/scripts/backup-skill.sh b/.agents/skills/skill-improver/scripts/backup-skill.sh
new file mode 100755
index 0000000..d4a5eee
--- /dev/null
+++ b/.agents/skills/skill-improver/scripts/backup-skill.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# backup-skill.sh - Backup skill files before applying updates
+# Part of skill-improver
+
+# Usage: ./backup-skill.sh <skill-path>
+# Example: ./backup-skill.sh ~/.claude/skills/git-workflow
+
+set -euo pipefail
+
+# Check if path provided
+if [ $# -eq 0 ]; then
+ echo "Usage: $0 <skill-path>"
+ echo "Example: $0 ~/.claude/skills/git-workflow"
+ exit 1
+fi
+
+SKILL_PATH="$1"
+SKILL_NAME=$(basename "$SKILL_PATH")
+TIMESTAMP=$(date +%Y%m%d-%H%M%S)
+BACKUP_DIR="$HOME/.claude/skills/backup/${SKILL_NAME}-${TIMESTAMP}"
+
+# Check if skill path exists
+if [ ! -d "$SKILL_PATH" ]; then
+ echo "Error: Skill path not found: ${SKILL_PATH}"
+ exit 1
+fi
+
+# Create backup directory
+echo "Creating backup directory: ${BACKUP_DIR}"
+mkdir -p "$BACKUP_DIR"
+
+# Copy entire skill directory
+echo "Backing up skill: ${SKILL_NAME}"
+cp -R "$SKILL_PATH"/* "$BACKUP_DIR/"
+
+# Create backup manifest
+cat > "$BACKUP_DIR/backup-manifest.txt" <<EOF
+Backup Manifest
+==============
+Skill Name: ${SKILL_NAME}
+Source Path: ${SKILL_PATH}
+Backup Date: $(date)
+Timestamp: ${TIMESTAMP}
+
+Files Backed Up:
+$(find "$BACKUP_DIR" -type f ! -name "backup-manifest.txt" | sed "s|$BACKUP_DIR/||")
+
+Restore Instructions:
+-------------------
+To restore this backup, run:
+ cp -R ${BACKUP_DIR}/* ${SKILL_PATH}/
+EOF
+
+echo "Backup complete!"
+echo "Backup location: ${BACKUP_DIR}"
+echo "Files backed up: $(find "$BACKUP_DIR" -type f ! -name "backup-manifest.txt" | wc -l)"
diff --git a/.agents/skills/skill-improver/scripts/verify-update.sh b/.agents/skills/skill-improver/scripts/verify-update.sh
new file mode 100755
index 0000000..f9c940f
--- /dev/null
+++ b/.agents/skills/skill-improver/scripts/verify-update.sh
@@ -0,0 +1,251 @@
+#!/bin/bash
+# verify-update.sh - Verify skill integrity after applying updates
+# Part of skill-improver
+
+# Usage: ./verify-update.sh <skill-path>
+# Example: ./verify-update.sh ~/.claude/skills/git-workflow
+
+set -euo pipefail
+
+# Check if path provided
+if [ $# -eq 0 ]; then
+ echo "Usage: $0 <skill-path>"
+ echo "Example: $0 ~/.claude/skills/git-workflow"
+ exit 1
+fi
+
+SKILL_PATH="$1"
+SKILL_NAME=$(basename "$SKILL_PATH")
+SKILL_FILE="${SKILL_PATH}/SKILL.md"
+
+# Verification results
+PASS=0
+FAIL=0
+WARN=0
+
+echo "================================"
+echo "Skill Update Verification"
+echo "================================"
+echo "Skill: ${SKILL_NAME}"
+echo "Path: ${SKILL_PATH}"
+echo ""
+
+# Check 1: SKILL.md exists
+echo "Check 1: SKILL.md exists"
+if [ -f "$SKILL_FILE" ]; then
+ echo "✅ PASS: SKILL.md found"
+ ((PASS++))
+else
+ echo "❌ FAIL: SKILL.md not found"
+ ((FAIL++))
+ echo ""
+ echo "Verification Summary:"
+ echo " Passed: ${PASS}"
+ echo " Failed: ${FAIL}"
+ echo " Warnings: ${WARN}"
+ exit 1
+fi
+
+echo ""
+
+# Check 2: YAML frontmatter valid
+echo "Check 2: YAML frontmatter valid"
+if command -v yq &> /dev/null; then
+ # Use yq if available for proper YAML validation
+ FRONTMAFTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$SKILL_FILE")
+ if echo "$FRONTMAFTER" | yq eval '.' > /dev/null 2>&1; then
+ echo "✅ PASS: YAML frontmatter is valid"
+ ((PASS++))
+ else
+ echo "❌ FAIL: Invalid YAML frontmatter"
+ ((FAIL++))
+ fi
+else
+ # Fallback: basic check for name and description fields
+ if grep -q "^name:" "$SKILL_FILE" && grep -q "^description:" "$SKILL_FILE"; then
+ echo "✅ PASS: YAML frontmatter has required fields (name, description)"
+ ((PASS++))
+ else
+ echo "❌ FAIL: YAML frontmatter missing required fields"
+ ((FAIL++))
+ fi
+fi
+
+echo ""
+
+# Check 3: Directory structure
+echo "Check 3: Directory structure"
+DIRS_OK=true
+
+if [ -d "${SKILL_PATH}/references" ]; then
+ echo " ✅ references/ exists"
+else
+ echo " ℹ️ references/ not found (optional)"
+ ((WARN++))
+fi
+
+if [ -d "${SKILL_PATH}/examples" ]; then
+ echo " ✅ examples/ exists"
+else
+ echo " ℹ️ examples/ not found (optional)"
+ ((WARN++))
+fi
+
+if [ -d "${SKILL_PATH}/scripts" ]; then
+ echo " ✅ scripts/ exists"
+ # Check if scripts are executable (macOS compatible)
+ SCRIPT_COUNT=$(find "${SKILL_PATH}/scripts" -type f | wc -l | tr -d ' ')
+ EXEC_COUNT=0
+ for script in "${SKILL_PATH}/scripts"/*; do
+ if [ -f "$script" ] && [ -x "$script" ]; then
+ ((EXEC_COUNT++))
+ fi
+ done
+ if [ "$SCRIPT_COUNT" -gt 0 ] && [ "$EXEC_COUNT" -eq "$SCRIPT_COUNT" ]; then
+ echo " ✅ All scripts are executable"
+ elif [ "$SCRIPT_COUNT" -gt 0 ]; then
+ echo " ⚠️ Some scripts are not executable (${EXEC_COUNT}/${SCRIPT_COUNT} executable)"
+ ((WARN++))
+ fi
+else
+ echo " ℹ️ scripts/ not found (optional)"
+fi
+
+if [ "$DIRS_OK" = true ] || [ ! -d "${SKILL_PATH}/references" ] && [ ! -d "${SKILL_PATH}/examples" ]; then
+ echo "✅ PASS: Directory structure is valid"
+ ((PASS++))
+else
+ echo "⚠️ WARN: Optional directories missing"
+fi
+
+echo ""
+
+# Check 4: SKILL.md size (progressive disclosure check)
+echo "Check 4: SKILL.md size (progressive disclosure)"
+WORD_COUNT=$(wc -w < "$SKILL_FILE" | tr -d ' ')
+
+if [ "$WORD_COUNT" -lt 3000 ]; then
+ echo "✅ PASS: SKILL.md is ${WORD_COUNT} words (good progressive disclosure)"
+ ((PASS++))
+elif [ "$WORD_COUNT" -lt 5000 ]; then
+ echo "⚠️ WARN: SKILL.md is ${WORD_COUNT} words (could be more concise)"
+ ((WARN++))
+else
+ echo "❌ FAIL: SKILL.md is ${WORD_COUNT} words (too long, should use references/)"
+ ((FAIL++))
+fi
+
+echo ""
+
+# Check 5: No broken references (basic check)
+echo "Check 5: Referenced files exist"
+BROKEN_REFS=0
+
+# Extract references from SKILL.md
+# Look for patterns like "See `references/file.md`" or "**`references/pattern.md`**"
+REF_FILES=$(grep -oE 'references/[-_a-zA-Z0-9\.]+' "$SKILL_FILE" | sort -u || true)
+
+if [ -n "$REF_FILES" ]; then
+ for ref in $REF_FILES; do
+ REF_PATH="${SKILL_PATH}/${ref}"
+ if [ -f "$REF_PATH" ]; then
+ echo " ✅ ${ref} exists"
+ else
+ echo " ❌ ${ref} referenced but not found"
+ ((BROKEN_REFS++))
+ fi
+ done
+
+ if [ "$BROKEN_REFS" -eq 0 ]; then
+ echo "✅ PASS: All referenced files exist"
+ ((PASS++))
+ else
+ echo "❌ FAIL: ${BROKEN_REFS} referenced file(s) not found"
+ ((FAIL++))
+ fi
+else
+ echo "ℹ️ No references found in SKILL.md"
+ echo "✅ PASS: No broken references"
+ ((PASS++))
+fi
+
+echo ""
+
+# Check 6: Writing style (imperative form check)
+echo "Check 6: Writing style (imperative form check)"
+SECOND_PERSON=$(grep -iE "you should|you need|you can|you must|you'll|your" "$SKILL_FILE" | wc -l | tr -d ' ')
+
+if [ "$SECOND_PERSON" -eq 0 ]; then
+ echo "✅ PASS: No second-person language found"
+ ((PASS++))
+elif [ "$SECOND_PERSON" -lt 5 ]; then
+ echo "⚠️ WARN: ${SECOND_PERSON} instance(s) of second-person language"
+ ((WARN++))
+ # Still count as pass for now
+ ((PASS++))
+else
+ echo "❌ FAIL: ${SECOND_PERSON} instances of second-person language"
+ echo " (should use imperative form)"
+ ((FAIL++))
+fi
+
+echo ""
+
+# Check 7: Description quality (basic check)
+echo "Check 7: Description quality"
+DESCRIPTION=$(grep "^description:" "$SKILL_FILE" | head -1)
+
+if [ -n "$DESCRIPTION" ]; then
+ # Check for third person
+ if echo "$DESCRIPTION" | grep -qi "this skill should be used when"; then
+ echo " ✅ Uses third-person format"
+ DESC_OK=true
+ else
+ echo " ❌ Does not use third-person format"
+ DESC_OK=false
+ fi
+
+ # Check length (100-300 characters ideal)
+ DESC_LEN=$(echo "$DESCRIPTION" | cut -d: -f2- | wc -c | tr -d ' ')
+ if [ "$DESC_LEN" -ge 100 ] && [ "$DESC_LEN" -le 300 ]; then
+ echo " ✅ Description length is ${DESC_LEN} characters (good)"
+ elif [ "$DESC_LEN" -lt 100 ]; then
+ echo " ⚠️ Description is ${DESC_LEN} characters (too short)"
+ DESC_OK=false
+ else
+ echo " ⚠️ Description is ${DESC_LEN} characters (too long)"
+ DESC_OK=false
+ fi
+
+ if [ "$DESC_OK" = true ]; then
+ echo "✅ PASS: Description quality is good"
+ ((PASS++))
+ else
+ echo "⚠️ WARN: Description could be improved"
+ ((WARN++))
+ # Still count as pass for basic check
+ ((PASS++))
+ fi
+else
+ echo "❌ FAIL: No description found in frontmatter"
+ ((FAIL++))
+fi
+
+echo ""
+echo "================================"
+echo "Verification Summary"
+echo "================================"
+echo " Passed: ${PASS}"
+echo " Failed: ${FAIL}"
+echo " Warnings: ${WARN}"
+echo ""
+
+if [ "$FAIL" -eq 0 ]; then
+ echo "✅ Verification PASSED"
+ echo " Skill structure is valid."
+ exit 0
+else
+ echo "❌ Verification FAILED"
+ echo " Please review and fix the failed checks."
+ exit 1
+fi