Skip to content

Commit 3aaaa32

Browse files
committed
fix: review comments
1 parent 000eb7e commit 3aaaa32

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

src/specify_cli/__init__.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,8 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
10891089
frontmatter = yaml.safe_load(parts[1]) or {}
10901090
body = parts[2].strip()
10911091
else:
1092+
# File starts with --- but has no closing ---
1093+
console.print(f"[yellow]Warning: {command_file.name} has malformed frontmatter (no closing ---), treating as plain content[/yellow]")
10921094
frontmatter = {}
10931095
body = content
10941096
else:
@@ -1107,19 +1109,26 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
11071109
enhanced_desc = SKILL_DESCRIPTIONS.get(command_name, original_desc or f"Spec-kit workflow command: {command_name}")
11081110

11091111
# Build SKILL.md following agentskills.io spec
1110-
skill_content = f"""---
1111-
name: {skill_name}
1112-
description: {enhanced_desc}
1113-
compatibility: Requires spec-kit project structure with .specify/ directory
1114-
metadata:
1115-
author: github-spec-kit
1116-
source: templates/commands/{command_file.name}
1117-
---
1118-
1119-
# Speckit {command_name.title()} Skill
1120-
1121-
{body}
1122-
"""
1112+
# Use yaml.safe_dump to safely serialise the frontmatter and
1113+
# avoid YAML injection from descriptions containing colons,
1114+
# quotes, or newlines.
1115+
frontmatter_data = {
1116+
"name": skill_name,
1117+
"description": enhanced_desc,
1118+
"compatibility": "Requires spec-kit project structure with .specify/ directory",
1119+
"metadata": {
1120+
"author": "github-spec-kit",
1121+
"source": f"templates/commands/{command_file.name}",
1122+
},
1123+
}
1124+
frontmatter_text = yaml.safe_dump(frontmatter_data, sort_keys=False).strip()
1125+
skill_content = (
1126+
f"---\n"
1127+
f"{frontmatter_text}\n"
1128+
f"---\n\n"
1129+
f"# Speckit {command_name.title()} Skill\n\n"
1130+
f"{body}\n"
1131+
)
11231132

11241133
skill_file = skill_dir / "SKILL.md"
11251134
if skill_file.exists():
@@ -1364,7 +1373,12 @@ def init(
13641373
if agent_folder:
13651374
cmds_dir = project_path / agent_folder.rstrip("/") / "commands"
13661375
if cmds_dir.exists():
1367-
shutil.rmtree(cmds_dir)
1376+
try:
1377+
shutil.rmtree(cmds_dir)
1378+
except OSError:
1379+
# Best-effort cleanup: skills are already installed,
1380+
# so leaving stale commands is non-fatal.
1381+
console.print("[yellow]Warning: could not remove extracted commands directory[/yellow]")
13681382

13691383
if not no_git:
13701384
tracker.start("git")

tests/test_ai_skills.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,13 @@ def test_enhanced_descriptions_used_when_available(self, project_dir, templates_
258258
skill_file = project_dir / ".claude" / "skills" / "speckit-specify" / "SKILL.md"
259259
content = skill_file.read_text()
260260

261-
# Should use the enhanced description from SKILL_DESCRIPTIONS, not the template one
261+
# Parse the generated YAML to compare the description value
262+
# (yaml.safe_dump may wrap long strings across multiple lines)
263+
parts = content.split("---", 2)
264+
parsed = yaml.safe_load(parts[1])
265+
262266
if "specify" in SKILL_DESCRIPTIONS:
263-
assert SKILL_DESCRIPTIONS["specify"] in content
267+
assert parsed["description"] == SKILL_DESCRIPTIONS["specify"]
264268

265269
def test_template_without_frontmatter(self, project_dir, templates_dir):
266270
"""Templates without YAML frontmatter should still produce valid skills."""

0 commit comments

Comments
 (0)