fix(init): show hyphenated /speckit-<name> in Next Steps for Forge projects (#3642)

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-<name>`, 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) <noreply@anthropic.com>
This commit is contained in:
Ali jawwad
2026-07-22 17:46:45 +05:00
committed by GitHub
parent 735fe0c5da
commit 5674fd03a9
2 changed files with 38 additions and 0 deletions

View File

@@ -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}"

View File

@@ -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-<name>
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-<name>; 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}"
)