From 5674fd03a9d1f99136dbef0776a47a7385977e00 Mon Sep 17 00:00:00 2001 From: Ali jawwad <33836051+jawwad-ali@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:46:45 +0500 Subject: [PATCH] fix(init): show hyphenated /speckit- in Next Steps for Forge projects (#3642) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The post-init "Next Steps" panel renders recommended slash commands via the nested `_display_cmd()`. It special-cased dollar-skills agents, kimi, slash-skills agents, and cline, but not Forge. For a Forge project `_display_cmd` fell through to `return f"/speckit.{name}"`, printing `/speckit.constitution`, `/speckit.specify`, etc. Forge only registers the hyphenated form (`/speckit-`, per `format_forge_command_name` / `ForgeIntegration.build_command_invocation`, and the generated command-file tests already assert this), so the panel told Forge users to run commands that don't exist under the dotted name. Add `forge_skill_mode` alongside `cline_skill_mode` and include it in the hyphenated-slash condition, mirroring how cline (also a non-skills markdown agent with hyphenated commands) is handled. Other agents unaffected. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) --- src/specify_cli/commands/init.py | 2 ++ tests/integrations/test_integration_forge.py | 36 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/specify_cli/commands/init.py b/src/specify_cli/commands/init.py index 00cf74153..ccdd7b0a1 100644 --- a/src/specify_cli/commands/init.py +++ b/src/specify_cli/commands/init.py @@ -700,6 +700,7 @@ def register(app: typer.Typer) -> None: zed_skill_mode = selected_ai == "zed" and _is_skills_integration grok_skill_mode = selected_ai == "grok" and _is_skills_integration cline_skill_mode = selected_ai == "cline" + forge_skill_mode = selected_ai == "forge" bob_skill_mode = selected_ai == "bob" and _is_skills_integration native_skill_mode = ( codex_skill_mode @@ -776,6 +777,7 @@ def register(app: typer.Typer) -> None: if ( _is_slash_skills_agent(selected_ai, _ai_skills_enabled) or cline_skill_mode + or forge_skill_mode ): return f"/speckit-{name}" return f"/speckit.{name}" diff --git a/tests/integrations/test_integration_forge.py b/tests/integrations/test_integration_forge.py index 137c7e220..dc42f135a 100644 --- a/tests/integrations/test_integration_forge.py +++ b/tests/integrations/test_integration_forge.py @@ -475,3 +475,39 @@ class TestForgeCommandRegistrar: "Found '/speckit.specify' (dot notation) in generated Forge git.feature command body. " "Forge requires hyphen notation for ZSH compatibility." ) + + +class TestForgeInitNextSteps: + """The post-init 'Next steps' panel must show hyphenated /speckit- + commands for Forge, since Forge only registers the hyphenated form + (see the generated command-file tests above).""" + + def test_init_next_steps_show_hyphenated_commands(self, tmp_path): + import os + + from typer.testing import CliRunner + + from specify_cli import app + + project = tmp_path / "forge-nextsteps" + project.mkdir() + old_cwd = os.getcwd() + try: + os.chdir(project) + result = CliRunner().invoke( + app, + ["init", "--here", "--integration", "forge", "--ignore-agent-tools"], + catch_exceptions=False, + ) + finally: + os.chdir(old_cwd) + + assert result.exit_code == 0, f"init failed: {result.output}" + # Forge registers /speckit-; the next-steps panel must match. + assert "/speckit-plan" in result.output, ( + f"Expected /speckit-plan in next steps but got:\n{result.output}" + ) + # Must NOT show the dotted /speckit.plan form Forge can't invoke. + assert "/speckit.plan" not in result.output, ( + f"Should not show dotted /speckit.plan for Forge:\n{result.output}" + )