How `extract-summaries.ps1` Dynamically Generates the `SKILL.md` Index

extract-summaries.ps1 automatically builds skills/INDEX.md by recursively discovering every SKILL.md file, parsing its YAML front-matter, and assembling a sorted markdown index with zero manual maintenance required.

This PowerShell automation eliminates stale documentation in the zhaoxuya520/reverse-skill repository by ensuring the skill index always reflects the actual filesystem state. The script runs on-demand or via CI/CD to regenerate the central navigation file that both human readers and routing engines depend on.

How the Three-Phase Discovery Pipeline Works

The extract-summaries.ps1 script implements a deterministic three-stage pipeline: Discovery, Extraction, and Generation. Each phase uses native PowerShell cmdlets with no external dependencies beyond standard YAML parsing.

Phase 1: Recursive File Discovery

The script locates all skill definitions using Get-ChildItem with strict filtering:

$skillFiles = Get-ChildItem -Path "$PSScriptRoot\..\skills" -Recurse -Filter "SKILL.md"

Key parameters:

  • -Recurse traverses nested category folders like windows-ad/, wifi-wireless/, ida-reverse/
  • -Filter "SKILL.md" matches exactly—no false positives from README.md or other markdown files
  • $PSScriptRoot anchors to the script's location in skills/scripts/

Phase 2: Front-Matter Extraction

For each SKILL.md, the script extracts structured metadata using regex and ConvertFrom-Yaml:

$fileContent = Get-Content $skillFile -Raw
if ($fileContent -match '^---\s*(?<yaml>[\s\S]*?)\s*---') {
    $yamlBlock = $Matches.yaml
    $metadata  = $yamlBlock | ConvertFrom-Yaml
}

The regex '^---\s*(?<yaml>[\s\S]*?)\s*---' captures the YAML block between document start/end markers. Parsed fields typically include:

  • title — display name for the index
  • description — one-line summary
  • tags — categorical keywords for filtering
  • client — optional multi-tenant routing hints

Phase 3: Markdown Index Generation

Collected metadata is sorted and rendered into skills/INDEX.md:

$indexLines = @()
$indexLines += "# Skill Index`n"

foreach ($item in $skillData | Sort-Object Directory, Title) {
    $relPath = $item.Path.Replace("$PSScriptRoot\..\", "")
    $indexLines += "- [$($item.Title)]($relPath) – $($item.Description)"
}

$indexPath = "$PSScriptRoot\..\skills\INDEX.md"
$indexLines | Out-File -FilePath $indexPath -Encoding utf8

The Sort-Object Directory, Title operation groups skills by filesystem hierarchy before alphabetical sorting, producing intuitive navigation.

Complete Script Implementation

The full extract-summaries.ps1 orchestrates all phases in a single pipeline:


# 1. Discover all SKILL.md files

$skillFiles = Get-ChildItem -Recurse -Filter "SKILL.md"

# 2. Extract metadata from each

$skillData = foreach ($f in $skillFiles) {
    $c = Get-Content $f -Raw
    if ($c -match '^---\s*(?<yaml>[\s\S]*?)\s*---') {
        $meta = $Matches.yaml | ConvertFrom-Yaml
        [PSCustomObject]@{
            Title       = $meta.title
            Description = $meta.description
            Path        = $f.FullName
            Directory   = $f.DirectoryName
        }
    }
}

# 3. Generate and write INDEX.md

$indexPath = Join-Path $PSScriptRoot "..\skills\INDEX.md"
$skillData | Sort-Object Directory, Title |
    ForEach-Object {
        $rel = $_.Path.Replace("$PSScriptRoot\..\", "")
        "- [$($_.Title)]($rel) – $($_.Description)"
    } | Set-Content $indexPath

This implementation guarantees idempotent output: running the script twice produces identical INDEX.md if source files are unchanged.

Key Files in the Indexing System

File Purpose Path
extract-summaries.ps1 PowerShell automation script skills/scripts/extract-summaries.ps1
INDEX.md Generated markdown navigation (overwritten each run) skills/INDEX.md
**/SKILL.md Source skill definitions with YAML front-matter skills/windows-ad/SKILL.md, skills/ida-reverse/SKILL.md, etc.
routing.json Routing engine configuration consuming the index skills/config/routing.json

Runtime Characteristics and Synchronization Benefits

Deterministic regeneration prevents documentation drift common in manually-maintained repositories. Because extract-summaries.ps1 derives all output from filesystem state:

  • New skills appear in INDEX.md immediately upon adding SKILL.md
  • Renamed skills update their links automatically
  • Deleted skills disappear without orphaning references
  • Routing consistency is maintained when skills/config/routing.json references index-generated paths

Summary

  • extract-summaries.ps1 implements a three-phase pipeline: discover → extract → generate
  • Discovery uses Get-ChildItem -Recurse -Filter "SKILL.md" for precise targeting
  • Extraction parses YAML front-matter via regex capture and ConvertFrom-Yaml
  • Generation sorts by directory hierarchy and outputs UTF-8 markdown to skills/INDEX.md
  • Zero manual maintenance required—the script guarantees index synchronization with filesystem reality

Frequently Asked Questions

What happens if a SKILL.md file lacks YAML front-matter?

The regex match ^---\s*[\s\S]*?\s*--- fails, and that file is silently skipped. The script processes only well-formed skill definitions, ensuring INDEX.md contains valid, metadata-rich entries.

Does the script preserve existing INDEX.md content?

No—the script performs complete overwrite via Set-Content or Out-File. Any manual edits to skills/INDEX.md are destroyed on regeneration, which enforces single-source-of-truth from SKILL.md files.

How do directory hierarchies affect sorting?

Sort-Object Directory, Title produces grouped listings: all skills in windows-ad/ appear before wifi-wireless/, with alphabetical ordering within each group. This matches the physical repository structure for intuitive navigation.

Can the script run in CI/CD pipelines?

Yes—all operations use core PowerShell modules. The script requires no interactive prompts and exits cleanly, making it suitable for GitHub Actions, Azure Pipelines, or pre-commit hooks that validate documentation freshness.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →