@@ -1165,7 +1165,11 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
11651165 else :
11661166 templates_dir = project_path / commands_subdir
11671167
1168- if not templates_dir .exists () or not any (templates_dir .glob ("*.md" )):
1168+ # For Copilot, only consider speckit.*.md templates so that user-authored
1169+ # agent files don't prevent the fallback to templates/commands/.
1170+ template_glob = "speckit.*.md" if selected_ai == "copilot" else "*.md"
1171+
1172+ if not templates_dir .exists () or not any (templates_dir .glob (template_glob )):
11691173 # Fallback: try the repo-relative path (for running from source checkout)
11701174 # This also covers agents whose extracted commands are in a different
11711175 # format (e.g. gemini/tabnine use .toml, not .md).
@@ -1174,17 +1178,14 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
11741178 if fallback_dir .exists () and any (fallback_dir .glob ("*.md" )):
11751179 templates_dir = fallback_dir
11761180
1177- if not templates_dir .exists () or not any (templates_dir .glob ("*.md" )):
1181+ if not templates_dir .exists () or not any (templates_dir .glob (template_glob )):
11781182 if tracker :
11791183 tracker .error ("ai-skills" , "command templates not found" )
11801184 else :
11811185 console .print ("[yellow]Warning: command templates not found, skipping skills installation[/yellow]" )
11821186 return False
11831187
1184- if selected_ai == "copilot" :
1185- command_files = sorted (templates_dir .glob ("speckit.*.md" ))
1186- else :
1187- command_files = sorted (templates_dir .glob ("*.md" ))
1188+ command_files = sorted (templates_dir .glob (template_glob ))
11881189 if not command_files :
11891190 if tracker :
11901191 tracker .skip ("ai-skills" , "no command templates found" )
@@ -1223,11 +1224,14 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
12231224 body = content
12241225
12251226 command_name = command_file .stem
1226- # Normalize: extracted commands may be named "speckit.<cmd>.md";
1227- # strip the "speckit." prefix so skill names stay clean and
1227+ # Normalize: extracted commands may be named "speckit.<cmd>.md"
1228+ # or "speckit.<cmd>.agent.md"; strip the "speckit." prefix and
1229+ # any trailing ".agent" suffix so skill names stay clean and
12281230 # SKILL_DESCRIPTIONS lookups work.
12291231 if command_name .startswith ("speckit." ):
12301232 command_name = command_name [len ("speckit." ):]
1233+ if command_name .endswith (".agent" ):
1234+ command_name = command_name [:- len (".agent" )]
12311235 # Kimi CLI discovers skills by directory name and invokes them as
12321236 # /skill:<name> — use dot separator to match packaging convention.
12331237 if selected_ai == "kimi" :
@@ -1252,6 +1256,8 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
12521256 source_name = command_file .name
12531257 if source_name .startswith ("speckit." ):
12541258 source_name = source_name [len ("speckit." ):]
1259+ if source_name .endswith (".agent.md" ):
1260+ source_name = source_name [:- len (".agent.md" )] + ".md"
12551261
12561262 frontmatter_data = {
12571263 "name" : skill_name ,
0 commit comments