Skill Indexer
Scans all installed Claude Code plugins and project-level skills, extracts metadata from each SKILL.md, and generates a comprehensive skills-index.md at the root of your skills repo (referred to below as <skills-repo> — set it once, e.g. ~/Repos/claude-skills).
Skill Governance > Index Skills
Invoke This Skill When
- User says
/index-skillsor asks to "index", "catalog", "list", or "refresh" skills - User asks "what skills do I have" or "what plugins are installed"
- After installing a new plugin or creating a new skill
- After modifying a skill's description or trigger conditions
Modes
Parse the argument to determine the mode:
| Argument | Mode | Behavior |
|---|---|---|
full or no argument |
Full refresh | Rescan everything, regenerate skills-index.md from scratch |
incremental |
Incremental | Only process SKILL.md files modified since last index generation (compare file mtime against the Generated timestamp in skills-index.md) |
| Any other string | Single lookup | Find and display info for the named skill without regenerating the full index |
Scan Locations
Scan these three locations in order. You MUST complete all three before generating the index.
Location 1: Marketplace Plugins
Use Glob to find SKILL.md files:
Glob pattern: **/skills/*/SKILL.md
Path: ~/.claude/plugins/cache/claude-plugins-official/
Location 2: Custom Plugins
Use Glob to find SKILL.md files:
Glob pattern: **/skills/*/SKILL.md
Path: <skills-repo>/plugins/
Location 3: Project-Level Skills (CRITICAL — do not skip)
Glob does NOT work for this location because it cannot expand wildcards in directory paths. You MUST use Bash. Do NOT cap with a shallow -maxdepth — project skills sit at <repo>/.claude/skills/<name>/SKILL.md (several levels below your code root; adjust ~/Repos below to wherever your repos live) and some are nested deeper, so a low maxdepth silently finds nothing. Prune noise instead:
find ~/Repos \
\( -name node_modules -o -name .git -o -name .next -o -name dist -o -name build -o -name worktrees \) -prune \
-o -path "*/.claude/skills/*/SKILL.md" -type f -print 2>/dev/null
Why each prune matters: worktrees excludes ephemeral .claude/worktrees/agent-* copies (transient agent worktrees — NOT real skills, they duplicate the parent repo's skills); the rest skip dependency/build dirs. This should find every project-level skill across your repos. If it returns 0 results and you know you have project skills, something is wrong — debug before proceeding.
De-dupe by (repo, skill-name): the same skill can appear under both a repo and a nested checkout of it (e.g. ~/Repos/library/... and ~/Repos/acme-app/library/...); count it once, grouped under its top-level repo.
Derive the project name from each path (e.g., .../Repos/acme-app/.claude/skills/acme-app-ops/SKILL.md → project: acme-app, skill: acme-app-ops).
For Each SKILL.md Found
Read the file and extract from YAML frontmatter:
| Field | Source | Required |
|---|---|---|
name |
frontmatter | Yes |
description |
frontmatter | Yes |
category |
frontmatter, or infer from parent directory name | No |
parent |
frontmatter | No |
role |
frontmatter (router or absent) |
No |
disable-model-invocation |
frontmatter | No |
argument-hint |
frontmatter (indicates slash-command invocable) | No |
allowed-tools |
frontmatter | No |
| Source plugin | Derived from file path | Yes |
| Source type | marketplace, custom, or project:<repo-name> |
Yes |
| File path | Absolute path to the SKILL.md | Yes |
Also scan the body for a "## Invoke This Skill When" or "## When This Skill Applies" section and extract the first 2-3 bullet points as trigger examples.
Output Format
Write the following to <skills-repo>/skills-index.md:
# Skills Index
Generated: YYYY-MM-DDTHH:MM:SS
Total skills: N across M sources
## Marketplace Plugins
### plugin-name (marketplace-name) — version
| Skill | Type | Hidden | Slash Cmd | Description (truncated to ~80 chars) |
|---|---|---|---|---|
| skill-name | router/leaf | Yes/No | /cmd or — | First line of description... |
### [repeat for each marketplace plugin]
## Custom Plugins (your collection)
### plugin-name
| Skill | Type | Hidden | Slash Cmd | Description |
|---|---|---|---|---|
| skill-name | router/leaf | Yes/No | /cmd or — | Description... |
## Project-Level Skills
### repo-name (~/Repos/repo-name/)
| Skill | Description |
|---|---|
| skill-name | Description... |
### [repeat for each repo with skills]
## Potential Conflicts
Compare all skill descriptions pairwise. Flag pairs where:
- Both descriptions contain the same key action verbs AND domain nouns
- One skill's description is a subset of another's
- Two skills could plausibly trigger for the same user query
Format:
| Skill A | Skill B | Overlap | Severity |
|---|---|---|---|
| name-a | name-b | "Both trigger on X" | LOW/MEDIUM/HIGH |
If no conflicts detected, write: "No conflicts detected."
## Statistics
- Marketplace skills: N
- Custom skills: N
- Project-level skills: N (across M repos)
- Router skills: N
- Hidden (non-model-invocable) skills: N
- Slash-command invocable: N
After Generation
- Display a brief summary to the user (total skills found, any new conflicts detected)
- Remind the user to commit the updated
skills-index.md:cd <skills-repo> && git add skills-index.md && git commit -m "chore: refresh skills index"
Incremental Mode Details
When running in incremental mode:
- Read the current
skills-index.mdand parse theGenerated:timestamp - Use
Bashto find SKILL.md files with mtime newer than that timestamp:find <scan-location> -name "SKILL.md" -newer <skills-repo>/skills-index.md - For each modified file, re-extract metadata and update the corresponding row in the index
- Re-run conflict detection against the full index
- Update the
Generated:timestamp
Single Lookup Mode
When given a specific skill name:
- Read
<skills-repo>/skills-index.md - Search for the skill name in the index
- If found, read the full SKILL.md from the path recorded in the index
- Display: full frontmatter, description, trigger conditions, file path, any detected conflicts
- Do NOT regenerate or modify the index file
Never generate the index without all three scan locations completed; 0 results from Location 3 (project skills) means the scan is broken, not that none exist.