Scan theinstalledskill directories on the current machine and generate an at-a-glance ASCII map.
Only targets installed skill directories:
- Default scan target:
- First detect the current CLI (Claude / Codex / Gemini / Qwen / Kiro / Trae / OpenCode, etc.)
- Then use the installed-skills root directory corresponding to that platform
- If detection fails, fall back to the shared install root (usually
~/.agents/skills)
- builtin/system skills (for example
~/.codex/skills) do not enter the default map - Do not scan repository source directories (such as
content/skills/) - Do not treat registry directories (such as
content/community-skills-registry/) as installable skills - Not used for requests like "help me find installable skills / registry / catalog"
Execution
1. Scan
Run the Node CLI:
node "$SKILL_DIR/scripts/skill-map.mjs"
For debugging or testing, structured JSON is available:
node "$SKILL_DIR/scripts/skill-map.mjs" --json
node "$SKILL_DIR/scripts/skill-map.mjs" --platform codex
node "$SKILL_DIR/scripts/skill-map.mjs" --json --root ~/.claude/skills --root ~/.agents/skills
JSON data fields:
instance_idnameversioninvocabledescsource_categorygroup_keyinstall_root
Where:
instance_idis a stable instance identifier, used to distinguish skills with the same name across root directoriessource_categorycomes directly from top-level frontmattercategory; when missing, output an empty stringgroup_keyis inferred solely from the token-aware rules ofname + desc, used for map groupingdescis compatible with single-line and multi-line frontmatterdescription- When
versionis missing, output- user_invocableoutputstruewhen explicitly false, outputfalsewhen missingnullinstall_rootis used to indicate which local install root the skill comes from--platform <id>is used to explicitly override the current CLI detection
2. Classify
Map grouping is fixed to use group_key, and does not directly use frontmatter category。
Purpose:
- frontmatter
categoryrepresents skill source metadata, such as repository directory classification group_keyrepresents the display semantic group in the map- The two must be separated to avoid mistaking source classifications like
developer-tools-integrationsas display classifications
The group order is fixed as follows:
◆ 认知与分析▲ 文档与表达■ 开发与实现● 工作流与集成★ 系统与维护· 未分类
Rule-driven table
| Group | Icon | Suggested group key | Example matching keywords | Description |
|---|---|---|---|---|
| Cognition and Analysis | ◆ | cognitive-analysis |
analysis, research, reading, paper, study, learn, summary, interpret |
For understanding, analysis, learning, and information distillation |
| Documentation and Expression | ▲ | document-expression |
write, document, card, slide, screenshot, theme, format, presentation |
For document generation, card-based presentation, display, and content packaging |
| Development and Implementation | ■ | development-implementation |
code, build, debug, test, refactor, lint, api, script, git |
For development, debugging, building, and engineering execution |
| Workflow and Integration | ● | workflow-integration |
workflow, sync, web, browser, fetch, search, automation, integration |
For networking, integration, automation, and collaboration processes |
| System and Maintenance | ★ | system-maintenance |
setup, install, installed, config, memory, inventory, map, deduplicate, cleanup |
For installation and configuration, skill management, maintenance, and meta-capabilities |
| Uncategorized | · | uncategorized |
No match | Fallback group when neither frontmatter nor rules can determine it |
Constraints:
- Rules must be based on token normalization and keyword matching, and must not rely on path fragments or loose substring false positives
- When it cannot be determined, uniformly classify it as
未分类 source_categorymust preserve the original value, but must not overridegroup_key
3. Render
Present it with an ASCII box diagram, maintaining a stable, repeatable layout.
╔══════════════════════════════════════════════════════════╗
║ SKILL MAP · {N} skills installed ║
╠══════════════════════════════════════════════════════════╣
║ ║
║ ◆ 认知与分析 ║
║ +----------------------+-----------------------------+ ║
║ | paper/ v4.3.0 | 论文阅读与分析 | ║
║ | plain v4.0 | 好问题与类比解释 | ║
║ +----------------------+-----------------------------+ ║
║ ║
║ · 未分类 ║
║ +----------------------+-----------------------------+ ║
║ | mystery - | 无法根据元数据判断用途 | ║
║ +----------------------+-----------------------------+ ║
╠══════════════════════════════════════════════════════════╣
║ Total: 12 Invocable: 7 Groups: 5 ║
╚══════════════════════════════════════════════════════════╝
ASCII output contract
- Groups are output in a fixed order; empty groups may be omitted, but the relative order must not change
- Within a group, skills are
name → install_root → instance_idstably sorted - The name column is left-aligned, and when
invocable = true, append after the skill name/ - When skills with the same name come from different install roots, append a root directory label in the name column to avoid them being misread as the same instance
- The version is displayed immediately after the name; if missing, display
- - The description keeps only a single-line summary; if too long, truncate it to avoid breaking the border
descWhen empty, display无描述- If no skills are scanned, still output the full border, and display in the body
No installed skills found under configured skill roots - If there is only one skill, still use the same template and do not switch to another format
- The bottom statistics line contains at least:
Total、Invocable、Unknown、Groups
4. Output
Directly output the ASCII map generated by the script:
- Do not generate files
- Do not write to disk
- Do not omit statistics
- Do not paste the raw JSON directly to the user unless the user explicitly requests it
- Do not mistakenly describe "skills installed on this machine" as an "installable catalog"
5. Similarity analysis (--analyze)
Enable when the user wantsto clean up duplicates / organize skill combinations. The script only generates suggestions,does not delete, move, or archiveany files.
node "$SKILL_DIR/scripts/skill-map.mjs" --analyze
node "$SKILL_DIR/scripts/skill-map.mjs" --analyze --json
node "$SKILL_DIR/scripts/skill-map.mjs" --analyze --min-score 0.4
Data flow:
- Scan local skill root directories in the same way as
--jsonmode - For each skill's
name + desc (+ tags), perform CJK-aware tokenization and stop-word removal - Compute Jaccard similarity pairwise
|A ∩ B| / |A ∪ B| --min-scorePairs below (default 0.30) are filtered out- Use connected components to merge high-similarity pairs into clusters (at least 2 members)
- Give a suggested action based on the highest score in the cluster:
likely-duplicate(≥ 0.75) — suspected duplicateconsider-merge(≥ 0.50) — suggest mergingreview(≥ 0.30) — manual review
JSON output contract:
| Field | Type | Description |
|---|---|---|
generated_at |
ISO-8601 UTC | Generation time |
threshold |
number | Threshold actually used |
summary.total_skills |
number | Total number of scanned skills |
summary.clusters |
number | Number of output clusters |
summary.skills_in_clusters |
number | Number of skills entering clusters |
summary.likely_duplicates / consider_merge / review |
number | Number of clusters per tier |
clusters[].id |
string | Stable cluster ID (for example c1) |
clusters[].action |
enum | likely-duplicate / consider-merge / review |
clusters[].max_score |
number | Highest Jaccard score in the cluster |
clusters[].members[] |
object | instance_id / name / display_name / install_root / group_key |
clusters[].shared_tokens |
string[] | At most 8 shared tokens, sorted by frequency |
clusters[].group_keys |
string[] | Display group keys involved by members (after deduplication) |
clusters[].rationale |
string | Explanatory text for same-group / cross-group / single-token overlap |
pairs[] |
object[] | All pairs passing the threshold, including left/right instance id / display name and shared tokens |
ASCII report output contract:
- Reuse the main map's
╔╠╚border style - Output non-empty sections in
likely-duplicate → consider-merge → revieworder - The first line of each cluster shows one member + score, the second line shows the second member + shared token summary, and additional members are listed line by line
- When there are no similar pairs, display
No similar skills detected above threshold <n> - After the bottom statistics line, append one line
Suggestions only — this tool never deletes, moves, or archives files.
Usage contract (the part handed to Claude):
- Treat script output as evidence, not as a conclusion
- For each cluster, explain to the user:What was shared / why it was judged similar / what to do (keep / merge / archive)
- Further operations may only be performed after the user explicitly agrees; this skill never proactively triggers deletion
- If the user asks "which one should be deleted", leave the decision to the user: provide the basis for comparison (version, user_invocable, install_root, associated group_key) and let the user decide
Minimum verification criteria
It is only considered complete if the following conditions are met:
scripts/skill-map.mjs --jsonCan output a valid JSON array- Every record in the JSON includes
group_key、source_category、install_root - Every record in the JSON includes a stable
instance_id - The default root directory is determined by detection from the current CLI or by a shared-root fallback, rather than being hardcoded to two paths
group_keyBased only on the token-aware rules ofname + descto infer,source_categorydoes not override itdescriptionSimultaneously compatible with single-line and multi-line frontmatter, and will not leak into other frontmatter fieldsversionwhen missing is-,user_invocablewhen missing isnull- In empty directories and single-skill scenarios, the map rendering rules still hold
- By default it can run across Windows, macOS, and Linux, without relying on bash-specific implementations
- When skills with the same name coexist across root directories, they will not be swallowed during the scanning phase
scripts/skill-map.mjs --analyze --jsonOutput thegenerated_at / threshold / summary / clusters / pairsfield--analyzeEvery cluster under it must includeid / action / max_score / members / shared_tokens / group_keys / rationale- When there are no similar pairs,
--analyzestill outputs the complete border and displaysNo similar skills detected above threshold <n>and the no-deletion promise