Skip to content

Commit efb7a7d

Browse files
dhilipkumarsmnriem
authored andcommitted
fix: review comments
1 parent 83f2533 commit efb7a7d

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
- **New projects**: command files are not installed when `--ai-skills` is used (skills replace commands)
2121
- **Existing repos** (`--here`): pre-existing command files are preserved — no breaking changes
2222
- `pyyaml` dependency (already present) used for YAML frontmatter parsing
23-
- **Unit tests** for `install_ai_skills`, `_get_skills_dir`, and `--ai-skills` CLI validation (26 test cases)
23+
- **Unit tests** for `install_ai_skills`, `_get_skills_dir`, and `--ai-skills` CLI validation (51 test cases covering all 18 supported agents)
2424

2525
## [0.1.0] - 2026-01-28
2626

src/specify_cli/__init__.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,8 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
10391039
tracker: Optional progress tracker.
10401040
10411041
Returns:
1042-
``True`` if at least one skill was installed, ``False`` otherwise.
1042+
``True`` if at least one skill was installed or all skills were
1043+
already present (idempotent re-run), ``False`` otherwise.
10431044
"""
10441045
# Locate command templates in the agent's extracted commands directory.
10451046
# download_and_extract_template() already placed the .md files here.
@@ -1059,7 +1060,7 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
10591060
if fallback_dir.exists() and any(fallback_dir.glob("*.md")):
10601061
templates_dir = fallback_dir
10611062

1062-
if not templates_dir.exists():
1063+
if not templates_dir.exists() or not any(templates_dir.glob("*.md")):
10631064
if tracker:
10641065
tracker.error("ai-skills", "command templates not found")
10651066
else:
@@ -1082,6 +1083,7 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
10821083
tracker.start("ai-skills")
10831084

10841085
installed_count = 0
1086+
skipped_count = 0
10851087
for command_file in command_files:
10861088
try:
10871089
content = command_file.read_text(encoding="utf-8")
@@ -1116,20 +1118,26 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
11161118
skill_dir.mkdir(parents=True, exist_ok=True)
11171119

11181120
# Select the best description available
1119-
original_desc = frontmatter.get("description", "") if frontmatter else ""
1121+
original_desc = frontmatter.get("description", "")
11201122
enhanced_desc = SKILL_DESCRIPTIONS.get(command_name, original_desc or f"Spec-kit workflow command: {command_name}")
11211123

11221124
# Build SKILL.md following agentskills.io spec
11231125
# Use yaml.safe_dump to safely serialise the frontmatter and
11241126
# avoid YAML injection from descriptions containing colons,
11251127
# quotes, or newlines.
1128+
# Normalize source filename for metadata — strip speckit. prefix
1129+
# so it matches the canonical templates/commands/<cmd>.md path.
1130+
source_name = command_file.name
1131+
if source_name.startswith("speckit."):
1132+
source_name = source_name[len("speckit."):]
1133+
11261134
frontmatter_data = {
11271135
"name": skill_name,
11281136
"description": enhanced_desc,
11291137
"compatibility": "Requires spec-kit project structure with .specify/ directory",
11301138
"metadata": {
11311139
"author": "github-spec-kit",
1132-
"source": f"templates/commands/{command_file.name}",
1140+
"source": f"templates/commands/{source_name}",
11331141
},
11341142
}
11351143
frontmatter_text = yaml.safe_dump(frontmatter_data, sort_keys=False).strip()
@@ -1144,6 +1152,7 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
11441152
skill_file = skill_dir / "SKILL.md"
11451153
if skill_file.exists():
11461154
# Do not overwrite user-customized skills on re-runs
1155+
skipped_count += 1
11471156
continue
11481157
skill_file.write_text(skill_content, encoding="utf-8")
11491158
installed_count += 1
@@ -1153,17 +1162,23 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
11531162
continue
11541163

11551164
if tracker:
1156-
if installed_count > 0:
1165+
if installed_count > 0 and skipped_count > 0:
1166+
tracker.complete("ai-skills", f"{installed_count} new + {skipped_count} existing skills in {skills_dir.relative_to(project_path)}")
1167+
elif installed_count > 0:
11571168
tracker.complete("ai-skills", f"{installed_count} skills → {skills_dir.relative_to(project_path)}")
1169+
elif skipped_count > 0:
1170+
tracker.complete("ai-skills", f"{skipped_count} skills already present")
11581171
else:
11591172
tracker.error("ai-skills", "no skills installed")
11601173
else:
11611174
if installed_count > 0:
11621175
console.print(f"[green]✓[/green] Installed {installed_count} agent skills to {skills_dir.relative_to(project_path)}/")
1176+
elif skipped_count > 0:
1177+
console.print(f"[green]✓[/green] {skipped_count} agent skills already present in {skills_dir.relative_to(project_path)}/")
11631178
else:
11641179
console.print("[yellow]No skills were installed[/yellow]")
11651180

1166-
return installed_count > 0
1181+
return installed_count > 0 or skipped_count > 0
11671182

11681183

11691184
@app.command()

0 commit comments

Comments
 (0)