@@ -4884,6 +4884,42 @@ def test_codex_hooks_render_dollar_skill_invocation(self, project_dir):
48844884 assert execution ["command" ] == "speckit.tasks"
48854885 assert execution ["invocation" ] == "$speckit-tasks"
48864886
4887+ @pytest .mark .parametrize (
4888+ ("ai" , "expected" ),
4889+ [
4890+ ("agy" , "$speckit-git-commit" ),
4891+ ("trae" , "$speckit-git-commit" ),
4892+ ("devin" , "/speckit-git-commit" ),
4893+ ],
4894+ )
4895+ def test_skills_hooks_render_from_legacy_init_options (self , project_dir , ai , expected ):
4896+ """Skills integrations should render native invocations without integration.json."""
4897+ init_options = project_dir / ".specify" / "init-options.json"
4898+ init_options .parent .mkdir (parents = True , exist_ok = True )
4899+ init_options .write_text (json .dumps ({"ai" : ai , "ai_skills" : True }))
4900+
4901+ hook_executor = HookExecutor (project_dir )
4902+ execution = hook_executor .execute_hook (
4903+ {
4904+ "extension" : "test-ext" ,
4905+ "command" : "speckit.git.commit" ,
4906+ "optional" : False ,
4907+ }
4908+ )
4909+
4910+ assert execution ["command" ] == "speckit.git.commit"
4911+ assert execution ["invocation" ] == expected
4912+
4913+ def test_legacy_codex_without_skills_keeps_dotted_invocation (self , project_dir ):
4914+ """Legacy Codex command-mode metadata should not be promoted during fallback."""
4915+ init_options = project_dir / ".specify" / "init-options.json"
4916+ init_options .parent .mkdir (parents = True , exist_ok = True )
4917+ init_options .write_text (json .dumps ({"ai" : "codex" , "ai_skills" : False }))
4918+
4919+ hook_executor = HookExecutor (project_dir )
4920+
4921+ assert hook_executor ._render_hook_invocation ("speckit.tasks" ) == "/speckit.tasks"
4922+
48874923 def test_cline_hooks_render_hyphenated_invocation (self , project_dir ):
48884924 """Cline projects should render /speckit-* invocations."""
48894925 init_options = project_dir / ".specify" / "init-options.json"
0 commit comments