@@ -208,8 +208,8 @@ def test_skills_created_when_ai_skills_active(self, skills_project, extension_di
208208
209209 # Check that skill directories were created
210210 skill_dirs = sorted ([d .name for d in skills_dir .iterdir () if d .is_dir ()])
211- assert "speckit-test-ext. hello" in skill_dirs
212- assert "speckit-test-ext. world" in skill_dirs
211+ assert "speckit-test-ext- hello" in skill_dirs
212+ assert "speckit-test-ext- world" in skill_dirs
213213
214214 def test_skill_md_content_correct (self , skills_project , extension_dir ):
215215 """SKILL.md should have correct agentskills.io structure."""
@@ -219,13 +219,13 @@ def test_skill_md_content_correct(self, skills_project, extension_dir):
219219 extension_dir , "0.1.0" , register_commands = False
220220 )
221221
222- skill_file = skills_dir / "speckit-test-ext. hello" / "SKILL.md"
222+ skill_file = skills_dir / "speckit-test-ext- hello" / "SKILL.md"
223223 assert skill_file .exists ()
224224 content = skill_file .read_text ()
225225
226226 # Check structure
227227 assert content .startswith ("---\n " )
228- assert "name: speckit-test-ext. hello" in content
228+ assert "name: speckit-test-ext- hello" in content
229229 assert "description:" in content
230230 assert "Test hello command" in content
231231 assert "source: extension:test-ext" in content
@@ -241,15 +241,15 @@ def test_skill_md_has_parseable_yaml(self, skills_project, extension_dir):
241241 extension_dir , "0.1.0" , register_commands = False
242242 )
243243
244- skill_file = skills_dir / "speckit-test-ext. hello" / "SKILL.md"
244+ skill_file = skills_dir / "speckit-test-ext- hello" / "SKILL.md"
245245 content = skill_file .read_text ()
246246
247247 assert content .startswith ("---\n " )
248248 parts = content .split ("---" , 2 )
249249 assert len (parts ) >= 3
250250 parsed = yaml .safe_load (parts [1 ])
251251 assert isinstance (parsed , dict )
252- assert parsed ["name" ] == "speckit-test-ext. hello"
252+ assert parsed ["name" ] == "speckit-test-ext- hello"
253253 assert "description" in parsed
254254
255255 def test_no_skills_when_ai_skills_disabled (self , no_skills_project , extension_dir ):
@@ -278,7 +278,7 @@ def test_existing_skill_not_overwritten(self, skills_project, extension_dir):
278278 project_dir , skills_dir = skills_project
279279
280280 # Pre-create a custom skill
281- custom_dir = skills_dir / "speckit-test-ext. hello"
281+ custom_dir = skills_dir / "speckit-test-ext- hello"
282282 custom_dir .mkdir (parents = True )
283283 custom_content = "# My Custom Hello Skill\n User-modified content\n "
284284 (custom_dir / "SKILL.md" ).write_text (custom_content )
@@ -293,9 +293,9 @@ def test_existing_skill_not_overwritten(self, skills_project, extension_dir):
293293
294294 # But the other skill should still be created
295295 metadata = manager .registry .get (manifest .id )
296- assert "speckit-test-ext. world" in metadata ["registered_skills" ]
296+ assert "speckit-test-ext- world" in metadata ["registered_skills" ]
297297 # The pre-existing one should NOT be in registered_skills (it was skipped)
298- assert "speckit-test-ext. hello" not in metadata ["registered_skills" ]
298+ assert "speckit-test-ext- hello" not in metadata ["registered_skills" ]
299299
300300 def test_registered_skills_in_registry (self , skills_project , extension_dir ):
301301 """Registry should contain registered_skills list."""
@@ -308,11 +308,11 @@ def test_registered_skills_in_registry(self, skills_project, extension_dir):
308308 metadata = manager .registry .get (manifest .id )
309309 assert "registered_skills" in metadata
310310 assert len (metadata ["registered_skills" ]) == 2
311- assert "speckit-test-ext. hello" in metadata ["registered_skills" ]
312- assert "speckit-test-ext. world" in metadata ["registered_skills" ]
311+ assert "speckit-test-ext- hello" in metadata ["registered_skills" ]
312+ assert "speckit-test-ext- world" in metadata ["registered_skills" ]
313313
314- def test_kimi_uses_dot_notation (self , project_dir , temp_dir ):
315- """Kimi agent should use dot notation for skill names."""
314+ def test_kimi_uses_hyphenated_skill_names (self , project_dir , temp_dir ):
315+ """Kimi agent should use the same hyphenated skill names as hooks ."""
316316 _create_init_options (project_dir , ai = "kimi" , ai_skills = True )
317317 _create_skills_dir (project_dir , ai = "kimi" )
318318 ext_dir = _create_extension_dir (temp_dir , ext_id = "test-ext" )
@@ -323,9 +323,8 @@ def test_kimi_uses_dot_notation(self, project_dir, temp_dir):
323323 )
324324
325325 metadata = manager .registry .get (manifest .id )
326- # Kimi should use dots, not hyphens
327- assert "speckit.test-ext.hello" in metadata ["registered_skills" ]
328- assert "speckit.test-ext.world" in metadata ["registered_skills" ]
326+ assert "speckit-test-ext-hello" in metadata ["registered_skills" ]
327+ assert "speckit-test-ext-world" in metadata ["registered_skills" ]
329328
330329 def test_missing_command_file_skipped (self , skills_project , temp_dir ):
331330 """Commands with missing source files should be skipped gracefully."""
@@ -372,8 +371,8 @@ def test_missing_command_file_skipped(self, skills_project, temp_dir):
372371 )
373372
374373 metadata = manager .registry .get (manifest .id )
375- assert "speckit-missing-cmd-ext. exists" in metadata ["registered_skills" ]
376- assert "speckit-missing-cmd-ext. ghost" not in metadata ["registered_skills" ]
374+ assert "speckit-missing-cmd-ext- exists" in metadata ["registered_skills" ]
375+ assert "speckit-missing-cmd-ext- ghost" not in metadata ["registered_skills" ]
377376
378377
379378# ===== Extension Skill Unregistration Tests =====
@@ -390,16 +389,16 @@ def test_skills_removed_on_extension_remove(self, skills_project, extension_dir)
390389 )
391390
392391 # Verify skills exist
393- assert (skills_dir / "speckit-test-ext. hello" / "SKILL.md" ).exists ()
394- assert (skills_dir / "speckit-test-ext. world" / "SKILL.md" ).exists ()
392+ assert (skills_dir / "speckit-test-ext- hello" / "SKILL.md" ).exists ()
393+ assert (skills_dir / "speckit-test-ext- world" / "SKILL.md" ).exists ()
395394
396395 # Remove extension
397396 result = manager .remove (manifest .id , keep_config = False )
398397 assert result is True
399398
400399 # Skills should be gone
401- assert not (skills_dir / "speckit-test-ext. hello" ).exists ()
402- assert not (skills_dir / "speckit-test-ext. world" ).exists ()
400+ assert not (skills_dir / "speckit-test-ext- hello" ).exists ()
401+ assert not (skills_dir / "speckit-test-ext- world" ).exists ()
403402
404403 def test_other_skills_preserved_on_remove (self , skills_project , extension_dir ):
405404 """Non-extension skills should not be affected by extension removal."""
@@ -430,8 +429,8 @@ def test_remove_handles_already_deleted_skills(self, skills_project, extension_d
430429 )
431430
432431 # Manually delete skill dirs before calling remove
433- shutil .rmtree (skills_dir / "speckit-test-ext. hello" )
434- shutil .rmtree (skills_dir / "speckit-test-ext. world" )
432+ shutil .rmtree (skills_dir / "speckit-test-ext- hello" )
433+ shutil .rmtree (skills_dir / "speckit-test-ext- world" )
435434
436435 # Should not raise
437436 result = manager .remove (manifest .id , keep_config = False )
@@ -492,10 +491,10 @@ def test_command_without_frontmatter(self, skills_project, temp_dir):
492491 ext_dir , "0.1.0" , register_commands = False
493492 )
494493
495- skill_file = skills_dir / "speckit-nofm-ext. plain" / "SKILL.md"
494+ skill_file = skills_dir / "speckit-nofm-ext- plain" / "SKILL.md"
496495 assert skill_file .exists ()
497496 content = skill_file .read_text ()
498- assert "name: speckit-nofm-ext. plain" in content
497+ assert "name: speckit-nofm-ext- plain" in content
499498 # Fallback description when no frontmatter description
500499 assert "Extension command: speckit.nofm-ext.plain" in content
501500 assert "Body without frontmatter." in content
@@ -512,8 +511,8 @@ def test_gemini_agent_skills(self, project_dir, temp_dir):
512511 )
513512
514513 skills_dir = project_dir / ".gemini" / "skills"
515- assert (skills_dir / "speckit-test-ext. hello" / "SKILL.md" ).exists ()
516- assert (skills_dir / "speckit-test-ext. world" / "SKILL.md" ).exists ()
514+ assert (skills_dir / "speckit-test-ext- hello" / "SKILL.md" ).exists ()
515+ assert (skills_dir / "speckit-test-ext- world" / "SKILL.md" ).exists ()
517516
518517 def test_multiple_extensions_independent_skills (self , skills_project , temp_dir ):
519518 """Installing and removing different extensions should be independent."""
@@ -531,15 +530,15 @@ def test_multiple_extensions_independent_skills(self, skills_project, temp_dir):
531530 )
532531
533532 # Both should have skills
534- assert (skills_dir / "speckit-ext-a. hello" / "SKILL.md" ).exists ()
535- assert (skills_dir / "speckit-ext-b. hello" / "SKILL.md" ).exists ()
533+ assert (skills_dir / "speckit-ext-a- hello" / "SKILL.md" ).exists ()
534+ assert (skills_dir / "speckit-ext-b- hello" / "SKILL.md" ).exists ()
536535
537536 # Remove ext-a
538537 manager .remove ("ext-a" , keep_config = False )
539538
540539 # ext-a skills gone, ext-b skills preserved
541- assert not (skills_dir / "speckit-ext-a. hello" ).exists ()
542- assert (skills_dir / "speckit-ext-b. hello" / "SKILL.md" ).exists ()
540+ assert not (skills_dir / "speckit-ext-a- hello" ).exists ()
541+ assert (skills_dir / "speckit-ext-b- hello" / "SKILL.md" ).exists ()
543542
544543 def test_malformed_frontmatter_handled (self , skills_project , temp_dir ):
545544 """Commands with invalid YAML frontmatter should still produce valid skills."""
@@ -588,7 +587,7 @@ def test_malformed_frontmatter_handled(self, skills_project, temp_dir):
588587 ext_dir , "0.1.0" , register_commands = False
589588 )
590589
591- skill_file = skills_dir / "speckit-badfm-ext. broken" / "SKILL.md"
590+ skill_file = skills_dir / "speckit-badfm-ext- broken" / "SKILL.md"
592591 assert skill_file .exists ()
593592 content = skill_file .read_text ()
594593 # Fallback description since frontmatter was invalid
@@ -604,7 +603,7 @@ def test_remove_cleans_up_when_init_options_deleted(self, skills_project, extens
604603 )
605604
606605 # Verify skills exist
607- assert (skills_dir / "speckit-test-ext. hello" / "SKILL.md" ).exists ()
606+ assert (skills_dir / "speckit-test-ext- hello" / "SKILL.md" ).exists ()
608607
609608 # Delete init-options.json to simulate user change
610609 init_opts = project_dir / ".specify" / "init-options.json"
@@ -613,8 +612,8 @@ def test_remove_cleans_up_when_init_options_deleted(self, skills_project, extens
613612 # Remove should still clean up via fallback scan
614613 result = manager .remove (manifest .id , keep_config = False )
615614 assert result is True
616- assert not (skills_dir / "speckit-test-ext. hello" ).exists ()
617- assert not (skills_dir / "speckit-test-ext. world" ).exists ()
615+ assert not (skills_dir / "speckit-test-ext- hello" ).exists ()
616+ assert not (skills_dir / "speckit-test-ext- world" ).exists ()
618617
619618 def test_remove_cleans_up_when_ai_skills_toggled (self , skills_project , extension_dir ):
620619 """Skills should be cleaned up even if ai_skills is toggled to false after install."""
@@ -625,13 +624,13 @@ def test_remove_cleans_up_when_ai_skills_toggled(self, skills_project, extension
625624 )
626625
627626 # Verify skills exist
628- assert (skills_dir / "speckit-test-ext. hello" / "SKILL.md" ).exists ()
627+ assert (skills_dir / "speckit-test-ext- hello" / "SKILL.md" ).exists ()
629628
630629 # Toggle ai_skills to false
631630 _create_init_options (project_dir , ai = "claude" , ai_skills = False )
632631
633632 # Remove should still clean up via fallback scan
634633 result = manager .remove (manifest .id , keep_config = False )
635634 assert result is True
636- assert not (skills_dir / "speckit-test-ext. hello" ).exists ()
637- assert not (skills_dir / "speckit-test-ext. world" ).exists ()
635+ assert not (skills_dir / "speckit-test-ext- hello" ).exists ()
636+ assert not (skills_dir / "speckit-test-ext- world" ).exists ()
0 commit comments