Skip to content

Commit 0dbbda1

Browse files
committed
Normalize preset skill titles
1 parent 0d0382f commit 0dbbda1

2 files changed

Lines changed: 15 additions & 6 deletions

File tree

src/specify_cli/presets.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,14 @@ def _skill_names_for_command(cmd_name: str) -> tuple[str, str]:
600600
legacy_skill_name = f"speckit.{raw_short_name}"
601601
return modern_skill_name, legacy_skill_name
602602

603+
@staticmethod
604+
def _skill_title_from_command(cmd_name: str) -> str:
605+
"""Return a human-friendly title for a skill command name."""
606+
title_name = cmd_name
607+
if title_name.startswith("speckit."):
608+
title_name = title_name[len("speckit."):]
609+
return title_name.replace(".", " ").replace("-", " ").title()
610+
603611
def _build_extension_skill_restore_index(self) -> Dict[str, Dict[str, Any]]:
604612
"""Index extension-backed skill restore data by skill directory name."""
605613
from .extensions import ExtensionManifest, ValidationError
@@ -723,6 +731,7 @@ def _register_skills(
723731
raw_short_name = raw_short_name[len("speckit."):]
724732
short_name = raw_short_name.replace(".", "-")
725733
skill_name, legacy_skill_name = self._skill_names_for_command(cmd_name)
734+
skill_title = self._skill_title_from_command(cmd_name)
726735

727736
# Only overwrite skills that already exist under skills_dir,
728737
# including Kimi native skills when ai_skills is false.
@@ -765,7 +774,7 @@ def _register_skills(
765774
f"---\n"
766775
f"{frontmatter_text}\n"
767776
f"---\n\n"
768-
f"# Speckit {short_name.title()} Skill\n\n"
777+
f"# Speckit {skill_title} Skill\n\n"
769778
f"{body}\n"
770779
)
771780

@@ -851,11 +860,12 @@ def _unregister_skills(self, skill_names: List[str], preset_dir: Path) -> None:
851860
},
852861
}
853862
frontmatter_text = yaml.safe_dump(frontmatter_data, sort_keys=False).strip()
863+
skill_title = self._skill_title_from_command(short_name)
854864
skill_content = (
855865
f"---\n"
856866
f"{frontmatter_text}\n"
857867
f"---\n\n"
858-
f"# Speckit {short_name.title()} Skill\n\n"
868+
f"# Speckit {skill_title} Skill\n\n"
859869
f"{body}\n"
860870
)
861871
skill_file.write_text(skill_content, encoding="utf-8")
@@ -871,10 +881,7 @@ def _unregister_skills(self, skill_names: List[str], preset_dir: Path) -> None:
871881
)
872882

873883
command_name = extension_restore["command_name"]
874-
title_name = command_name
875-
if title_name.startswith("speckit."):
876-
title_name = title_name[len("speckit."):]
877-
title_name = title_name.replace(".", " ").replace("-", " ").title()
884+
title_name = self._skill_title_from_command(command_name)
878885

879886
frontmatter_data = {
880887
"name": skill_name,

tests/test_presets.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,6 +2163,7 @@ def test_extension_skill_override_matches_hyphenated_multisegment_name(self, pro
21632163
content = skill_file.read_text()
21642164
assert "preset:ext-skill-override" in content
21652165
assert "name: speckit-fakeext-cmd" in content
2166+
assert "# Speckit Fakeext Cmd Skill" in content
21662167

21672168
metadata = manager.registry.get("ext-skill-override")
21682169
assert "speckit-fakeext-cmd" in metadata.get("registered_skills", [])
@@ -2248,6 +2249,7 @@ def test_extension_skill_restored_on_preset_remove(self, project_dir, temp_dir):
22482249
assert "source: extension:fakeext" in content
22492250
assert "extension:fakeext" in content
22502251
assert '.specify/scripts/bash/setup-plan.sh --json "$ARGUMENTS"' in content
2252+
assert "# Fakeext Cmd Skill" in content
22512253

22522254
def test_preset_remove_skips_skill_dir_without_skill_file(self, project_dir, temp_dir):
22532255
"""Preset removal should not delete arbitrary directories missing SKILL.md."""

0 commit comments

Comments
 (0)