@@ -300,7 +300,13 @@ def test_empty_templates_directory(self, project_dir):
300300 empty_cmds = project_dir / ".claude" / "commands"
301301 empty_cmds .mkdir (parents = True )
302302
303- result = install_ai_skills (project_dir , "claude" )
303+ # Block the __file__ fallback so it can't find real templates
304+ fake_init = project_dir / "nowhere" / "src" / "specify_cli" / "__init__.py"
305+ fake_init .parent .mkdir (parents = True , exist_ok = True )
306+ fake_init .touch ()
307+
308+ with patch .object (specify_cli , "__file__" , str (fake_init )):
309+ result = install_ai_skills (project_dir , "claude" )
304310
305311 assert result is False
306312
@@ -353,8 +359,50 @@ def test_return_false_when_no_templates(self, project_dir):
353359 with patch .object (specify_cli , "__file__" , str (fake_init )):
354360 assert install_ai_skills (project_dir , "claude" ) is False
355361
362+ def test_non_md_commands_dir_falls_back (self , project_dir ):
363+ """When extracted commands are .toml (e.g. gemini), fall back to repo templates."""
364+ # Simulate gemini template extraction: .gemini/commands/ with .toml files only
365+ cmds_dir = project_dir / ".gemini" / "commands"
366+ cmds_dir .mkdir (parents = True )
367+ (cmds_dir / "speckit.specify.toml" ).write_text ('[command]\n name = "specify"\n ' )
368+ (cmds_dir / "speckit.plan.toml" ).write_text ('[command]\n name = "plan"\n ' )
369+
370+ # The __file__ fallback should find the real repo templates/commands/*.md
371+ result = install_ai_skills (project_dir , "gemini" )
372+
373+ assert result is True
374+ skills_dir = project_dir / ".gemini" / "skills"
375+ assert skills_dir .exists ()
376+ # Should have installed skills from the fallback .md templates
377+ skill_dirs = [d .name for d in skills_dir .iterdir () if d .is_dir ()]
378+ assert len (skill_dirs ) >= 1
379+ # .toml commands should be untouched
380+ assert (cmds_dir / "speckit.specify.toml" ).exists ()
381+
382+ @pytest .mark .parametrize ("agent_key" , list (AGENT_CONFIG .keys ()))
383+ def test_skills_install_for_all_agents (self , temp_dir , agent_key ):
384+ """install_ai_skills should produce skills for every configured agent."""
385+ proj = temp_dir / f"proj-{ agent_key } "
386+ proj .mkdir ()
387+
388+ # Place .md templates in the agent's commands directory
389+ agent_folder = AGENT_CONFIG [agent_key ]["folder" ]
390+ cmds_dir = proj / agent_folder .rstrip ("/" ) / "commands"
391+ cmds_dir .mkdir (parents = True )
392+ (cmds_dir / "specify.md" ).write_text (
393+ "---\n description: Test command\n ---\n \n # Test\n \n Body.\n "
394+ )
395+
396+ result = install_ai_skills (proj , agent_key )
397+
398+ assert result is True
399+ skills_dir = _get_skills_dir (proj , agent_key )
400+ assert skills_dir .exists ()
401+ skill_dirs = [d .name for d in skills_dir .iterdir () if d .is_dir ()]
402+ assert "speckit-specify" in skill_dirs
403+ assert (skills_dir / "speckit-specify" / "SKILL.md" ).exists ()
404+
356405
357- # ===== Command Coexistence Tests =====
358406
359407class TestCommandCoexistence :
360408 """Verify install_ai_skills never touches command files.
0 commit comments