godot-skill-discovery

Expert blueprint for GDSkills skill discovery and indexing system. Enables AI agents to find relevant skills by topic/keyword. Use when building skill libraries OR implementing search functionality. Keywords skill discovery, indexing, search, metadata, skill registry.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "godot-skill-discovery" with this command: npx skills add thedivergentai/gd-agentic-skills/thedivergentai-gd-agentic-skills-godot-skill-discovery

Skill Discovery

Skill indexing, metadata parsing, and search define efficient skill library navigation.

Available Scripts

skill_index_generator.gd

Expert skill indexer that parses SKILL.md files and generates searchable metadata.

NEVER Do in Skill Discovery

  • NEVER rely on filename for skill identificationfilesystem-advanced.md vs SKILL.md? Use frontmatter name field as source of truth, not filename.
  • NEVER skip keyword extraction — Skill without keywords? Impossible to discover via search. MUST extract from description OR maintain keyword list.
  • NEVER cache without invalidation — Skill index cached, SKILL.md updated? Stale results. Invalidate cache on file modification OR version changes.
  • NEVER use full-text search without ranking — Searching 100 skills for "input"? Returns everything. Use TF-IDF OR keyword weighting for relevance.
  • NEVER forget to handle missing frontmatter — Malformed SKILL.md without --- delimiter? Parser crash. Validate YAML frontmatter before parsing.

Skill Metadata Format

---
name: skill-name
description: Expert blueprint for X including [features]. Use when [scenarios]. Keywords topic, action, domain.
---

Indexing Pattern

# skill_indexer.gd
class_name SkillIndexer
extends RefCounted

var skill_registry: Dictionary = {}

func index_skills(skills_dir: String) -> void:
    var dir := DirAccess.open(skills_dir)
    if not dir:
        return
    
    dir.list_dir_begin()
    var file_name := dir.get_next()
    
    while file_name != "":
        if dir.current_is_dir():
            var skill_path := skills_dir.path_join(file_name).path_join("SKILL.md")
            if FileAccess.file_exists(skill_path):
                index_skill(skill_path)
        file_name = dir.get_next()

func index_skill(path: String) -> void:
    var file := FileAccess.open(path, FileAccess.READ)
    if not file:
        return
    
    var content := file.get_as_text()
    var metadata := parse_frontmatter(content)
    
    if metadata.has("name"):
        skill_registry[metadata.name] = {
            "path": path,
            "description": metadata.get("description", ""),
            "keywords": extract_keywords(metadata.get("description", ""))
        }

func parse_frontmatter(content: String) -> Dictionary:
    var lines := content.split("\n")
    if lines[0].strip_edges() != "---":
        return {}
    
    var frontmatter_lines: Array[String] = []
    for i in range(1, lines.size()):
        if lines[i].strip_edges() == "---":
            break
        frontmatter_lines.append(lines[i])
    
    var metadata := {}
    for line in frontmatter_lines:
        var parts := line.split(":", true, 1)
        if parts.size() == 2:
            metadata[parts[0].strip_edges()] = parts[1].strip_edges()
    
    return metadata

func search_skills(query: String) -> Array[Dictionary]:
    var results: Array[Dictionary] = []
    var query_lower := query.to_lower()
    
    for skill_name in skill_registry:
        var skill_data := skill_registry[skill_name]
        var relevance := 0.0
        
        # Check name match
        if skill_name.to_lower().contains(query_lower):
            relevance += 10.0
        
        # Check description match
        if skill_data.description.to_lower().contains(query_lower):
            relevance += 5.0
        
        # Check keyword match
        for keyword in skill_data.keywords:
            if keyword.to_lower() == query_lower:
                relevance += 20.0  # Exact keyword match
            elif keyword.to_lower().contains(query_lower):
                relevance += 3.0
        
        if relevance > 0:
            results.append({
                "name": skill_name,
                "relevance": relevance,
                "data": skill_data
            })
    
    # Sort by relevance
    results.sort_custom(func(a, b): return a.relevance > b.relevance)
    return results

func extract_keywords(description: String) -> Array[String]:
    var keywords: Array[String] = []
    
    # Extract from "Keywords X, Y, Z" pattern
    var keyword_marker := "Keywords "
    var keyword_index := description.find(keyword_marker)
    if keyword_index != -1:
        var keyword_section := description.substr(keyword_index + keyword_marker.length())
        var parts := keyword_section.split(".", true, 1)
        var keyword_str := parts[0] if parts.size() > 0 else keyword_section
        
        for word in keyword_str.split(","):
            keywords.append(word.strip_edges())
    
    return keywords

Best Practices

  1. Version Skill Index — Include skill version in metadata for compatibility checks
  2. Cache Aggressively — Parse SKILL.md on index build, cache results for fast search
  3. Support Fuzzy Matching — Allow typos in search (e.g., Levenshtein distance)
  4. Category Grouping — Organize skills by category for browsing (2D, 3D, Genre, etc.)

Reference

  • Related: godot-project-foundations, godot-gdscript-mastery

Related

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

godot-master

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-shaders-basics

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-ui-theming

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-particles

No summary provided by upstream source.

Repository SourceNeeds Review