How extract-summaries.ps1 Regenerates INDEX.md from Skill Frontmatter
The extract-summaries.ps1 PowerShell script performs an idempotent workflow that scans the reverse-skill repository for SKILL.md files, extracts YAML front-matter metadata, and compiles a synchronized navigation index at skills/INDEX.md capable of running in both write and CI check modes.
The reverse-skill repository organizes modular capabilities into dedicated directories, each documented by a SKILL.md file containing structured metadata. Maintaining a central index of these modules requires a reproducible, automated approach that eliminates manual editing drift. According to the reverse-skill source code, the extract-summaries.ps1 script provides a deterministic workflow that derives skills/INDEX.md directly from declared front-matter fields across the entire codebase.
Resolving Repository Paths and Layout
The script begins by establishing canonical paths relative to its execution context. In skills/scripts/extract-summaries.ps1, the script resolves $PSScriptRoot to determine its own directory, then calculates the repository root ($skillsRoot) and the target index file path ($indexPath).
# Path resolution from extract-summaries.ps1 (lines 12-15)
$scriptDir = $PSScriptRoot
$skillsRoot = Join-Path $scriptDir ".."
$indexPath = Join-Path $skillsRoot "INDEX.md"
This ensures the script operates correctly regardless of the current working directory, provided it remains within the repository structure.
Discovering SKILL.md Files via Git or Fallback
The extraction workflow prioritizes version-controlled files to ensure stability across different clones. The script first attempts to use git ls-files to list tracked SKILL.md files. If Git is unavailable, it falls back to Get-ChildItem with recursive directory traversal.
Files residing within ignored directories—specifically ops, scripts, config, tests, field-journal, and references—are explicitly excluded from indexing at lines 21-30 and 34-35 of the script. This filtering prevents build artifacts and utility directories from polluting the skill index.
Parsing YAML Front-Matter Metadata
For each discovered SKILL.md, the script reads the first 15 lines to locate YAML front-matter delimited by --- markers. The parser walks these lines in block mode, extracting the name and description fields required for index generation.
When front-matter fields are missing, the script applies default values to maintain table integrity. Multi-line descriptions are supported through block parsing logic, though content exceeding 160 characters is truncated to preserve table readability in the final INDEX.md.
Building Structured Index Rows
Each valid module contributes a structured object to a master collection. The script constructs these rows using [pscustomobject] with four properties:
- Dir – The module's directory name
- Name – The extracted front-matter name
- Desc – The truncated description (max 160 characters)
- Path – The relative path to the module
This intermediate representation enables uniform processing before final Markdown assembly.
Assembling the Markdown Document
The script utilizes a StringBuilder to construct INDEX.md with strict formatting rules. The generated document contains:
- A header identifying the file as auto-generated
- A Markdown table with columns for module and summary (摘要)
- A plain-text directory tree representation
- Routing references from
skills/config/routing.json
Pipe characters (|) within descriptions are escaped to prevent table corruption. The assembly logic appears at lines 75-88 and 92-98 of extract-summaries.ps1.
Enforcing Line Ending Consistency
To match the repository's .gitattributes policy enforcing LF line endings, the script normalizes all output before writing. It replaces Windows-style CRLF sequences with Unix-style LF characters using a regex replacement at lines 104-105:
# Line ending normalization
$newContent = $newContent -replace "`r`n", "`n"
This ensures the generated INDEX.md remains consistent across Windows, macOS, and Linux environments regardless of the execution platform.
Executing Write or Check Mode
The script supports two execution modes controlled by the -Check switch.
Write mode (default) persists the generated content to disk using UTF-8 encoding with BOM:
# Default write operation (lines 123-124)
[System.IO.File]::WriteAllText($indexPath, $newContent, [System.Text.Encoding]::UTF8)
Check mode performs drift detection suitable for CI pipelines. It compares the generated content against the existing file (ignoring CRLF differences) and exits with code 0 if identical, or code 1 if discrepancies exist, enabling automated validation that INDEX.md remains synchronized with source front-matter.
# CI validation example
pwsh -File skills/scripts/extract-summaries.ps1 -Check
Summary
- Path resolution establishes repository context using
$PSScriptRootandJoin-Pathto locate the targetskills/INDEX.md. - Git-aware discovery prefers
git ls-filesover file system scanning, excluding utility directories likescripts,tests, andconfig. - Front-matter extraction reads the first 15 lines of each
SKILL.mdto capturenameanddescriptionfields from YAML blocks. - Content normalization enforces LF line endings and truncates descriptions to 160 characters while escaping pipe characters for table safety.
- Dual execution modes support both local regeneration (write) and CI validation (check) with appropriate exit codes for automation.
Frequently Asked Questions
How does extract-summaries.ps1 handle missing front-matter fields?
The script applies default values when name or description fields are absent from a SKILL.md file's YAML front-matter. This ensures every discovered module appears in INDEX.md with complete table rows even if documentation is incomplete.
What is the difference between Write mode and Check mode?
Write mode generates and saves the new INDEX.md content to disk using UTF-8 with BOM encoding, which is the standard workflow for updating documentation. Check mode compares the generated content against the existing file without writing changes, exiting with code 1 if differences are detected, making it suitable for continuous integration pipelines to enforce documentation synchronization.
Why does the script prefer Git commands over file system scanning?
Using git ls-files ensures that only version-controlled modules are indexed, maintaining stability across different clones and preventing untracked local files from appearing in the public INDEX.md. If Git is unavailable, the script falls back to Get-ChildItem with explicit exclusion patterns for directories like ops, field-journal, and references.
How are special characters handled in the generated markdown?
Pipe characters (|) within description text are escaped to prevent corruption of the Markdown table structure. Additionally, all line endings are normalized to LF (\n) to comply with repository-wide .gitattributes policies, ensuring the file renders identically on Windows, macOS, and Linux systems.
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 →