fix(skills): use frontmatter name in skills index instead of directory name

build_skills_system_prompt() was using the skill directory name (skill_name)
when appending to skills_by_category in all three code paths (snapshot cache,
cold filesystem scan, external dirs). This meant any skill whose directory name
differed from its frontmatter `name` field would appear under the wrong name in
the system prompt, causing LLM routing failures.

The snapshot entry already stores both skill_name (dir) and frontmatter_name
(declared); switch the three tuple appends to use frontmatter_name. Also fix
the external-dir dedup set (seen_skill_names) to track frontmatter names for
consistency with the local-skill tuples now stored under frontmatter_name.

Fixes #11777

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michel Belleau
2026-04-17 23:25:11 +00:00
committed by Teknium
parent 016ae5c334
commit d465fc5869

View File

@@ -654,7 +654,7 @@ def build_skills_system_prompt(
): ):
continue continue
skills_by_category.setdefault(category, []).append( skills_by_category.setdefault(category, []).append(
(skill_name, entry.get("description", "")) (frontmatter_name, entry.get("description", ""))
) )
category_descriptions = { category_descriptions = {
str(k): str(v) str(k): str(v)
@@ -679,7 +679,7 @@ def build_skills_system_prompt(
): ):
continue continue
skills_by_category.setdefault(entry["category"], []).append( skills_by_category.setdefault(entry["category"], []).append(
(skill_name, entry["description"]) (entry["frontmatter_name"], entry["description"])
) )
# Read category-level DESCRIPTION.md files # Read category-level DESCRIPTION.md files
@@ -722,9 +722,10 @@ def build_skills_system_prompt(
continue continue
entry = _build_snapshot_entry(skill_file, ext_dir, frontmatter, desc) entry = _build_snapshot_entry(skill_file, ext_dir, frontmatter, desc)
skill_name = entry["skill_name"] skill_name = entry["skill_name"]
if skill_name in seen_skill_names: frontmatter_name = entry["frontmatter_name"]
if frontmatter_name in seen_skill_names:
continue continue
if entry["frontmatter_name"] in disabled or skill_name in disabled: if frontmatter_name in disabled or skill_name in disabled:
continue continue
if not _skill_should_show( if not _skill_should_show(
extract_skill_conditions(frontmatter), extract_skill_conditions(frontmatter),
@@ -732,9 +733,9 @@ def build_skills_system_prompt(
available_toolsets, available_toolsets,
): ):
continue continue
seen_skill_names.add(skill_name) seen_skill_names.add(frontmatter_name)
skills_by_category.setdefault(entry["category"], []).append( skills_by_category.setdefault(entry["category"], []).append(
(skill_name, entry["description"]) (frontmatter_name, entry["description"])
) )
except Exception as e: except Exception as e:
logger.debug("Error reading external skill %s: %s", skill_file, e) logger.debug("Error reading external skill %s: %s", skill_file, e)