diff --git a/src/specify_cli/extensions/__init__.py b/src/specify_cli/extensions/__init__.py index 39235bf198..78fdf735da 100644 --- a/src/specify_cli/extensions/__init__.py +++ b/src/specify_cli/extensions/__init__.py @@ -3608,6 +3608,7 @@ def _render_hook_invocation(self, command: Any) -> str: dollar_skill_mode = is_dollar_skills_agent(selected_ai, ai_skills_enabled) kimi_skill_mode = selected_ai == "kimi" cline_mode = selected_ai == "cline" + forge_mode = selected_ai == "forge" skill_name = self._skill_name_from_command(command_id) if dollar_skill_mode and skill_name: @@ -3618,6 +3619,10 @@ def _render_hook_invocation(self, command: Any) -> str: from ..integrations.cline import format_cline_command_name return f"/{format_cline_command_name(command_id)}" + if forge_mode: + from ..integrations.forge import format_forge_command_name + + return f"/{format_forge_command_name(command_id)}" use_slash = is_slash_skills_agent(selected_ai, ai_skills_enabled) diff --git a/tests/test_extensions.py b/tests/test_extensions.py index 08831c3ae5..018ed8a3fc 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -8238,6 +8238,42 @@ def test_cline_hooks_render_extension_command(self, project_dir): assert execution["command"] == "my-extension.do-something" assert execution["invocation"] == "/speckit-my-extension-do-something" + def test_forge_hooks_render_hyphenated_invocation(self, project_dir): + """Forge projects should render /speckit-* invocations (like Cline).""" + init_options = project_dir / ".specify" / "init-options.json" + init_options.parent.mkdir(parents=True, exist_ok=True) + init_options.write_text(json.dumps({"ai": "forge"})) + + hook_executor = HookExecutor(project_dir) + execution = hook_executor.execute_hook( + { + "extension": "test-ext", + "command": "speckit.tasks", + "optional": False, + } + ) + + assert execution["command"] == "speckit.tasks" + assert execution["invocation"] == "/speckit-tasks" + + def test_forge_hooks_render_extension_command(self, project_dir): + """Forge projects should render /speckit-my-ext-cmd for extension hooks.""" + init_options = project_dir / ".specify" / "init-options.json" + init_options.parent.mkdir(parents=True, exist_ok=True) + init_options.write_text(json.dumps({"ai": "forge"})) + + hook_executor = HookExecutor(project_dir) + execution = hook_executor.execute_hook( + { + "extension": "test-ext", + "command": "my-extension.do-something", + "optional": False, + } + ) + + assert execution["command"] == "my-extension.do-something" + assert execution["invocation"] == "/speckit-my-extension-do-something" + def test_non_skill_command_keeps_slash_invocation(self, project_dir): """Custom hook commands should keep slash invocation style.""" init_options = project_dir / ".specify" / "init-options.json"