
Gardening Skills Wiki
- 9 installs
- 41 repo stars
- Updated October 9, 2025
- obra/clank
Claude Code agent workflow helper from OBRA clank repository.
About
Gardening Skills Wiki — Clank skill from OBRA repository—agent workflow reference for Claude Code power users in the Superpowers ecosystem.
- OBRA clank agent workflow.
- Install via skills.sh registry.
- Pairs with Superpowers ecosystem.
Gardening Skills Wiki by the numbers
- 9 all-time installs (skills.sh)
- +2 installs in the week ending Jul 26, 2026 (Skillselion tracking)
- Ranked #12,133 of 16,659 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 26, 2026 (Skillselion catalog sync)
npx skills add https://github.com/obra/clank --skill gardening-skills-wikiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 9 |
|---|---|
| repo stars | ★ 41 |
| Security audit | 2 / 3 scanners passed |
| Last updated | October 9, 2025 |
| Repository | obra/clank ↗ |
What it does
Claude Code agent workflow helper from OBRA clank repository.
Files
Gardening Skills Wiki
Overview
The skills wiki needs regular maintenance to stay healthy: links break, skills get orphaned, naming drifts, INDEX files fall out of sync.
Core principle: Automate health checks to maintain wiki quality without burning tokens on manual inspection.
When to Use
Run gardening after:
- Adding new skills
- Removing or renaming skills
- Reorganizing categories
- Updating cross-references
- Suspicious that links are broken
Periodic maintenance:
- Weekly during active development
- Monthly during stable periods
Quick Health Check
# Run all checks
~/.claude/skills/meta/gardening-skills-wiki/garden.sh
# Or run specific checks
~/.claude/skills/meta/gardening-skills-wiki/check-links.sh
~/.claude/skills/meta/gardening-skills-wiki/check-naming.sh
~/.claude/skills/meta/gardening-skills-wiki/check-index-coverage.sh
# Analyze search gaps (what skills are missing)
~/.claude/skills/meta/gardening-skills-wiki/analyze-search-gaps.shThe master script runs all checks and provides a health report.
What Gets Checked
1. Link Validation (check-links.sh)
Checks:
- Backtick-wrapped
@links - backticks disable resolution - Relative paths like skills/ or skills/gardening-skills-wiki/~/ - should use skills/ absolute paths
- All
skills/references resolve to existing files - Skills referenced in INDEX files exist
- Orphaned skills (not in any INDEX)
Fixes:
- Remove backticks from @ references
- Convert skills/ and skills/gardening-skills-wiki/~/ relative paths to skills/ absolute paths
- Update broken skills/ references to correct paths
- Add orphaned skills to their category INDEX
- Remove references to deleted skills
2. Naming Consistency (check-naming.sh)
Checks:
- Directory names are kebab-case
- No uppercase or underscores in directory names
- Frontmatter fields present (name, description, when_to_use, version, type)
- Skill names use active voice (not "How to...")
- Empty directories
Fixes:
- Rename directories to kebab-case
- Add missing frontmatter fields
- Remove empty directories
- Rephrase names to active voice
3. INDEX Coverage (check-index-coverage.sh)
Checks:
- All skills listed in their category INDEX
- All category INDEX files linked from main INDEX
- Skills have descriptions in INDEX entries
Fixes:
- Add missing skills to INDEX files
- Add category links to main INDEX
- Add descriptions for INDEX entries
Common Issues and Fixes
Broken Links
❌ BROKEN: skills/debugging/root-cause-tracing
Target: /path/to/skills/debugging/root-cause-tracing/SKILL.mdFix: Update the reference path - skill might have moved or been renamed.
Orphaned Skills
⚠️ ORPHANED: test-invariants/SKILL.md not in testing/INDEX.mdFix: Add to the category INDEX:
- skills/gardening-skills-wiki/test-invariants - Description of skillBacktick-Wrapped Links
❌ BACKTICKED: skills/testing/condition-based-waiting on line 31
File: getting-started/SKILL.md
Fix: Remove backticks - use bare @ referenceFix: Remove backticks:
# ❌ Bad - backticks disable link resolution
`skills/testing/condition-based-waiting`
# ✅ Good - bare @ reference
skills/testing/condition-based-waitingRelative Path Links
❌ RELATIVE: skills/testing in coding/SKILL.md
Fix: Use skills/ absolute path insteadFix: Convert to absolute path:
# ❌ Bad - relative paths are brittle
skills/testing/condition-based-waiting
# ✅ Good - absolute skills/ path
skills/testing/condition-based-waitingNaming Issues
⚠️ Mixed case: TestingPatterns (should be kebab-case)Fix: Rename directory:
cd ~/.claude/skills/testing
mv TestingPatterns testing-patterns
# Update all references to old nameMissing from INDEX
❌ NOT INDEXED: condition-based-waiting/SKILL.mdFix: Add to testing/INDEX.md:
## Available Skills
- skills/gardening-skills-wiki/condition-based-waiting - Replace timeouts with condition pollingEmpty Directories
⚠️ EMPTY: event-based-testingFix: Remove if no longer needed:
rm -rf ~/.claude/skills/event-based-testingNaming Conventions
Directory Names
- Format: kebab-case (lowercase with hyphens)
- Process skills: Use gerunds when appropriate (
creating-skills,testing-skills) - Pattern skills: Use core concept (
flatten-with-flags,test-invariants) - Avoid: Mixed case, underscores, passive voice starters ("how-to-")
Frontmatter Requirements
Required fields:
name: Human-readable namedescription: One-line summarywhen_to_use: Symptoms and situations (CSO-critical)version: Semantic version
Optional fields:
languages: Applicable languagesdependencies: Required toolscontext: Special context (e.g., "AI-assisted development")
Automation Workflow
After Adding New Skill
# 1. Create skill
mkdir -p ~/.claude/skills/category/new-skill
vim ~/.claude/skills/category/new-skill/SKILL.md
# 2. Add to category INDEX
vim ~/.claude/skills/category/INDEX.md
# 3. Run health check
~/.claude/skills/meta/gardening-skills-wiki/garden.sh
# 4. Fix any issues reportedAfter Reorganizing
# 1. Move/rename skills
mv ~/.claude/skills/old-category/skill ~/.claude/skills/new-category/
# 2. Update all references (grep for old paths)
grep -r "skills/gardening-skills-wiki/old-category/skill" ~/.claude/skills/
# 3. Run health check
~/.claude/skills/meta/gardening-skills-wiki/garden.sh
# 4. Fix broken linksPeriodic Maintenance
# Monthly: Run full health check
~/.claude/skills/meta/gardening-skills-wiki/garden.sh
# Review and fix:
# - ❌ errors (broken links, missing skills)
# - ⚠️ warnings (naming, empty dirs)The Scripts
garden.sh (Master)
Runs all health checks and provides comprehensive report.
Usage:
~/.claude/skills/meta/gardening-skills-wiki/garden.sh [skills_dir]check-links.sh
Validates all @ references and cross-links.
Checks:
- Backtick-wrapped
@links (disables resolution) - Relative paths (
skills/orskills/gardening-skills-wiki/~/) - should beskills/ @reference resolution to existing files- Skills in INDEX files exist
- Orphaned skills detection
check-naming.sh
Validates naming conventions and frontmatter.
Checks:
- Directory name format
- Frontmatter completeness
- Empty directories
check-index-coverage.sh
Validates INDEX completeness.
Checks:
- Skills listed in category INDEX
- Categories linked in main INDEX
- Descriptions present
Quick Reference
| Issue | Script | Fix |
|---|---|---|
| Backtick-wrapped links | check-links.sh | Remove backticks from @ refs |
| Relative paths | check-links.sh | Convert to skills/ absolute |
| Broken links | check-links.sh | Update @ references |
| Orphaned skills | check-links.sh | Add to INDEX |
| Naming issues | check-naming.sh | Rename directories |
| Empty dirs | check-naming.sh | Remove with rm -rf |
| Missing from INDEX | check-index-coverage.sh | Add to INDEX.md |
| No description | check-index-coverage.sh | Add to INDEX entry |
Output Symbols
- ✅ Pass - Item is correct
- ❌ Error - Must fix (broken link, missing skill)
- ⚠️ Warning - Should fix (naming, empty dir)
- ℹ️ Info - Informational (no action needed)
Integration with Workflow
Before committing skill changes:
~/.claude/skills/meta/gardening-skills-wiki/garden.sh
# Fix all ❌ errors
# Consider fixing ⚠️ warnings
git add .
git commit -m "Add/update skills"When links feel suspicious:
~/.claude/skills/meta/gardening-skills-wiki/check-links.shWhen INDEX seems incomplete:
~/.claude/skills/meta/gardening-skills-wiki/check-index-coverage.shCommon Rationalizations
| Excuse | Reality |
|---|---|
| "Will check links manually" | Automated check is faster and more thorough |
| "INDEX probably fine" | Orphaned skills happen - always verify |
| "Naming doesn't matter" | Consistency aids discovery and maintenance |
| "Empty dir harmless" | Clutter confuses future maintainers |
| "Can skip periodic checks" | Issues compound - regular maintenance prevents big cleanups |
Real-World Impact
Without gardening:
- Broken links discovered during urgent tasks
- Orphaned skills never found
- Naming drifts over time
- INDEX files fall out of sync
With gardening:
- 30-second health check catches issues early
- Automated validation prevents manual inspection
- Consistent structure aids discovery
- Wiki stays maintainable
The Bottom Line
Don't manually inspect - automate the checks.
Run garden.sh after changes and periodically. Fix ❌ errors immediately, address ⚠️ warnings when convenient.
Maintained wiki = findable skills = reusable knowledge.
#!/usr/bin/env bash
# Analyze failed skills-search queries to identify missing skills
set -euo pipefail
SKILLS_DIR="${HOME}/.claude/skills"
LOG_FILE="${SKILLS_DIR}/.search-log.jsonl"
if [[ ! -f "$LOG_FILE" ]]; then
echo "No search log found at $LOG_FILE"
exit 0
fi
echo "Skills Search Gap Analysis"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Count total searches
total=$(wc -l < "$LOG_FILE")
echo "Total searches: $total"
echo ""
# Extract and count unique queries
echo "Most common searches:"
jq -r '.query' "$LOG_FILE" 2>/dev/null | sort | uniq -c | sort -rn | head -20
echo ""
echo "Recent searches (last 10):"
tail -10 "$LOG_FILE" | jq -r '"\(.timestamp) - \(.query)"' 2>/dev/null
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "High-frequency searches indicate missing skills."
echo "Review patterns and create skills as needed."
#!/bin/bash
# Check that all skills are properly listed in INDEX files
SKILLS_DIR="${1:-$HOME/Documents/GitHub/dotfiles/.claude/skills}"
echo "## INDEX Coverage"
# For each category with an INDEX
for category_dir in "$SKILLS_DIR"/*/; do
category=$(basename "$category_dir")
# Skip if not a directory
[[ ! -d "$category_dir" ]] && continue
index_file="$category_dir/INDEX.md"
# Skip if no INDEX (meta directories might not have one)
[[ ! -f "$index_file" ]] && continue
# Find all SKILL.md files in this category
skill_count=0
indexed_count=0
missing_count=0
while IFS= read -r skill_file; do
skill_count=$((skill_count + 1))
skill_name=$(basename $(dirname "$skill_file"))
# Check if skill is referenced in INDEX
if grep -q "@$skill_name/SKILL.md" "$index_file"; then
indexed_count=$((indexed_count + 1))
else
echo " ❌ NOT INDEXED: $skill_name/SKILL.md"
missing_count=$((missing_count + 1))
fi
done < <(find "$category_dir" -mindepth 2 -type f -name "SKILL.md")
if [ $skill_count -gt 0 ] && [ $missing_count -eq 0 ]; then
echo " ✅ $category: all $skill_count skills indexed"
elif [ $missing_count -gt 0 ]; then
echo " ⚠️ $category: $missing_count/$skill_count skills missing"
fi
done
echo ""
# Verify INDEX entries have descriptions
find "$SKILLS_DIR" -type f -name "INDEX.md" | while read -r index_file; do
category=$(basename $(dirname "$index_file"))
# Extract skill references
grep -o '@[a-zA-Z0-9-]*/SKILL\.md' "$index_file" | while read -r ref; do
skill_name=${ref#@}
skill_name=${skill_name%/SKILL.md}
# Get the line with the reference
line_num=$(grep -n "$ref" "$index_file" | cut -d: -f1)
# Check if there's a description on the same line or next line
description=$(sed -n "${line_num}p" "$index_file" | sed "s|.*$ref *- *||")
if [[ -z "$description" || "$description" == *"$ref"* ]]; then
# No description on same line, check next line
next_line=$((line_num + 1))
description=$(sed -n "${next_line}p" "$index_file")
if [[ -z "$description" ]]; then
echo " ⚠️ NO DESCRIPTION: $category/INDEX.md reference to $skill_name"
fi
fi
done
done
#!/bin/bash
# Check for @ links (force-load context) and validate skill path references
SKILLS_DIR="${1:-$HOME/Documents/GitHub/dotfiles/.claude/skills}"
echo "## Links & References"
broken_refs=0
backticked_refs=0
relative_refs=0
at_links=0
while IFS= read -r file; do
# Extract @ references - must start line, be after space/paren/dash, or be standalone
# Exclude: emails, decorators, code examples with @staticmethod/@example
# First, check for backtick-wrapped @ links
grep -nE '`[^`]*@[a-zA-Z0-9._~/-]+\.(md|sh|ts|js|py)[^`]*`' "$file" | while IFS=: read -r line_num match; do
# Get actual line to check if in code block
actual_line=$(sed -n "${line_num}p" "$file")
# Skip if line is indented (code block) or in fenced code
if [[ "$actual_line" =~ ^[[:space:]]{4,} ]]; then
continue
fi
code_block_count=$(sed -n "1,${line_num}p" "$file" | grep -c '^```')
if [ $((code_block_count % 2)) -eq 1 ]; then
continue
fi
ref=$(echo "$match" | grep -o '@[a-zA-Z0-9._~/-]*\.[a-zA-Z0-9]*')
echo " ❌ BACKTICKED: $ref on line $line_num"
echo " File: $(basename $(dirname "$file"))/$(basename "$file")"
echo " Fix: Remove backticks - use bare @ reference"
backticked_refs=$((backticked_refs + 1))
done
# Check for ANY @ links to .md/.sh/.ts/.js/.py files (force-loads, burns context)
grep -nE '(^|[ \(>-])@[a-zA-Z0-9._/-]+\.(md|sh|ts|js|py)' "$file" | \
grep -v '@[a-zA-Z0-9._%+-]*@' | \
grep -v 'email.*@' | \
grep -v '`.*@.*`' | while IFS=: read -r line_num match; do
ref=$(echo "$match" | grep -o '@[a-zA-Z0-9._/-]+\.(md|sh|ts|js|py)')
ref_path="${ref#@}"
# Skip if in fenced code block
actual_line=$(sed -n "${line_num}p" "$file")
if [[ "$actual_line" =~ ^[[:space:]]{4,} ]]; then
continue
fi
code_block_count=$(sed -n "1,${line_num}p" "$file" | grep -c '^```')
if [ $((code_block_count % 2)) -eq 1 ]; then
continue
fi
# Any @ link is wrong - should use skills/path format
echo " ❌ @ LINK: $ref on line $line_num"
echo " File: $(basename $(dirname "$file"))/$(basename "$file")"
# Suggest correct format
if [[ "$ref_path" == skills/* ]]; then
# @skills/category/name/SKILL.md → skills/category/name
corrected="${ref_path#skills/}"
corrected="${corrected%/SKILL.md}"
echo " Fix: $ref → skills/$corrected"
elif [[ "$ref_path" == ../* ]]; then
echo " Fix: Convert to skills/category/skill-name format"
else
echo " Fix: Convert to skills/category/skill-name format"
fi
at_links=$((at_links + 1))
done
done < <(find "$SKILLS_DIR" -type f -name "*.md")
# Summary
total_issues=$((backticked_refs + at_links))
if [ $total_issues -eq 0 ]; then
echo " ✅ All skill references OK"
else
[ $backticked_refs -gt 0 ] && echo " ❌ $backticked_refs backticked references"
[ $at_links -gt 0 ] && echo " ❌ $at_links @ links (force-load context)"
fi
echo ""
echo "Correct format: skills/category/skill-name"
echo " ❌ Bad: @skills/path/SKILL.md (force-loads) or @../path (brittle)"
echo " ✅ Good: skills/category/skill-name (load with Read tool when needed)"
echo ""
# Verify all skills mentioned in INDEX files exist
find "$SKILLS_DIR" -type f -name "INDEX.md" | while read -r index_file; do
index_dir=$(dirname "$index_file")
# Extract skill references (format: @skill-name/SKILL.md)
grep -o '@[a-zA-Z0-9-]*/SKILL\.md' "$index_file" | while read -r skill_ref; do
skill_path="$index_dir/${skill_ref#@}"
if [[ ! -f "$skill_path" ]]; then
echo " ❌ BROKEN: $skill_ref in $(basename "$index_dir")/INDEX.md"
echo " Expected: $skill_path"
fi
done
done
echo ""
find "$SKILLS_DIR" -type f -path "*/*/SKILL.md" | while read -r skill_file; do
skill_dir=$(basename $(dirname "$skill_file"))
category_dir=$(dirname $(dirname "$skill_file"))
index_file="$category_dir/INDEX.md"
if [[ -f "$index_file" ]]; then
if ! grep -q "@$skill_dir/SKILL.md" "$index_file"; then
echo " ⚠️ ORPHANED: $skill_dir/SKILL.md not in $(basename "$category_dir")/INDEX.md"
fi
fi
done
#!/bin/bash
# Check naming consistency in skills wiki
SKILLS_DIR="${1:-$HOME/Documents/GitHub/dotfiles/.claude/skills}"
echo "## Naming & Structure"
issues=0
find "$SKILLS_DIR" -type d -mindepth 2 -maxdepth 2 | while read -r dir; do
dir_name=$(basename "$dir")
# Skip if it's an INDEX or top-level category
if [[ "$dir_name" == "INDEX.md" ]] || [[ $(dirname "$dir") == "$SKILLS_DIR" ]]; then
continue
fi
# Check for naming issues
if [[ "$dir_name" =~ [A-Z] ]]; then
echo " ⚠️ Mixed case: $dir_name (should be kebab-case)"
issues=$((issues + 1))
fi
if [[ "$dir_name" =~ _ ]]; then
echo " ⚠️ Underscore: $dir_name (should use hyphens)"
issues=$((issues + 1))
fi
# Check if name follows gerund pattern for process skills
if [[ -f "$dir/SKILL.md" ]]; then
type=$(grep "^type:" "$dir/SKILL.md" | head -1 | cut -d: -f2 | xargs)
if [[ "$type" == "technique" ]] && [[ ! "$dir_name" =~ ing$ ]] && [[ ! "$dir_name" =~ -with- ]] && [[ ! "$dir_name" =~ ^test- ]]; then
# Techniques might want -ing but not required
:
fi
fi
done
[ $issues -eq 0 ] && echo " ✅ Directory names OK" || echo " ⚠️ $issues naming issues"
echo ""
find "$SKILLS_DIR" -type d -empty | while read -r empty_dir; do
echo " ⚠️ EMPTY: $(realpath --relative-to="$SKILLS_DIR" "$empty_dir" 2>/dev/null || echo "$empty_dir")"
done
echo ""
find "$SKILLS_DIR" -type f -name "SKILL.md" | while read -r skill_file; do
skill_name=$(basename $(dirname "$skill_file"))
# Check for required fields
if ! grep -q "^name:" "$skill_file"; then
echo " ❌ MISSING 'name': $skill_name/SKILL.md"
fi
if ! grep -q "^description:" "$skill_file"; then
echo " ❌ MISSING 'description': $skill_name/SKILL.md"
fi
if ! grep -q "^when_to_use:" "$skill_file"; then
echo " ❌ MISSING 'when_to_use': $skill_name/SKILL.md"
fi
if ! grep -q "^version:" "$skill_file"; then
echo " ⚠️ MISSING 'version': $skill_name/SKILL.md"
fi
# Check for active voice in name (should not start with "How to")
name_value=$(grep "^name:" "$skill_file" | head -1 | cut -d: -f2- | xargs)
if [[ "$name_value" =~ ^How\ to ]]; then
echo " ⚠️ Passive name: $skill_name has 'How to' prefix (prefer active voice)"
fi
done
#!/bin/bash
# Master gardening script for skills wiki maintenance
SKILLS_DIR="${1:-$HOME/Documents/GitHub/dotfiles/.claude/skills}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "=== Skills Wiki Health Check ==="
echo ""
# Make scripts executable if not already
chmod +x "$SCRIPT_DIR"/*.sh 2>/dev/null
# Run all checks
bash "$SCRIPT_DIR/check-naming.sh" "$SKILLS_DIR"
echo ""
bash "$SCRIPT_DIR/check-links.sh" "$SKILLS_DIR"
echo ""
bash "$SCRIPT_DIR/check-index-coverage.sh" "$SKILLS_DIR"
echo ""
echo "=== Health Check Complete ==="
echo ""
echo "Fix: ❌ errors (broken/missing) | Consider: ⚠️ warnings | ✅ = correct"
Related skills
FAQ
Is Gardening Skills Wiki safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.