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:
-Recursetraverses nested category folders likewindows-ad/,wifi-wireless/,ida-reverse/-Filter "SKILL.md"matches exactly—no false positives fromREADME.mdor other markdown files$PSScriptRootanchors to the script's location inskills/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.mdimmediately upon addingSKILL.md - Renamed skills update their links automatically
- Deleted skills disappear without orphaning references
- Routing consistency is maintained when
skills/config/routing.jsonreferences index-generated paths
Summary
extract-summaries.ps1implements 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →