Skip to content

fix(extensions): list commands the way the active agent registers them - #4964

Open
tkv00 wants to merge 2 commits into
github:mainfrom
tkv00:fix/extension-listing-command-names
Open

tkv00 wants to merge 2 commits into
github:mainfrom
tkv00:fix/extension-listing-command-names

Conversation

@tkv00

@tkv00 tkv00 commented Oct 15, 2026

Copy link
Copy Markdown

Description

specify extension add ("Provided commands") and specify extension info ("Commands:") list an extension's commands. Both special-cased Cline and Forge by agent key, and every other agent got the manifest's dotted name. For integrations that register hyphenated names, the listings show commands the agent does not have:

Project Listed on main Registered
--integration codex speckit.demo.hello .agents/skills/speckit-demo-hello/SKILL.md
--integration claude speckit.demo.hello .claude/skills/speckit-demo-hello/SKILL.md
--integration junie speckit.demo.hello .junie/commands/speckit-demo-hello.md
--integration copilot (skills, the default) speckit.demo.hello .github/skills/speckit-demo-hello/SKILL.md

The per-agent branches grew one agent at a time (#2508 for Cline, #3669 and #3744 for Forge). Of the 41 registered integrations (other than generic), 25 register hyphenated names, and the listings handled 2.

This change replaces both branches with one helper in extensions/_commands.py. The helper asks the active integration for its command separator in the project's mode: invoke_separator_for_mode() with the persisted ai_skills flag, the hook whose docstring names extension registration paths. It then hyphenates with ExtensionManager._skill_name_for_command, which skill registration already uses. This follows #4910, which derived the init next-steps names from the integration for the same reason.

What stays the same:

  • Cline and Forge print the same names. Manifest command names must match ^speckit\.([a-z0-9-]+)\.([a-z0-9-]+)$, and for such names their formatters and the shared helper return the same string.
  • Agents that register dotted names, such as Gemini and Copilot with --commands, keep the dotted name.
  • An unknown or unreadable ai value falls back to the manifest name, as before.

The helper relies on a - command-mode separator meaning hyphenated registration. A new registry test checks this for every registered integration other than generic (all 41 hold today).

Related: #4954 reports a similar mismatch in hook "To execute" lines for Codex. That code path is separate and is not changed here.

Testing

  • New test_extension_install_listing_matches_registered_command_names and test_extension_info_listing_matches_registered_command_names share LISTED_COMMAND_NAME_CASES (8 agent and mode cases). On main, 8 fail (claude, codex, junie and copilot-skills, for each command) and 8 pass. With the fix, all 16 pass.
  • New test_command_mode_separator_matches_registered_names in tests/integrations/test_registry.py (41 cases). It also passes on main; it guards the assumption the helper relies on.
  • tests/specify_cli/extensions, tests/integrations, tests/test_extensions.py and tests/test_installed_list_json.py show no new failures compared with main.
  • Full suite: I compared the failing tests with main in the same local environment. The branch adds no new failures. One timing-dependent workflow test failed once and passed 5 of 5 reruns.
  • CLI: I created projects with specify init --integration <codex|claude|junie|copilot|gemini> and with copilot --integration-options="--commands". For a sample extension, extension add --dev and extension info now list speckit-demo-hello for codex, claude, junie and copilot, and still list speckit.demo.hello for gemini and copilot --commands.
  • uvx ruff@0.15.0 check src tests passes.

Tests ran with the project virtualenv's python -m pytest after uv sync --extra test.

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (fill in the disclosure below)

AI disclosure: Prepared with Claude Code (model: Claude Opus 5.5) on behalf of @tkv00, running autonomously under step-by-step direction. The contributor chose the topic and the fix approach and approved each step. Claude Code found the issue, wrote the code, tests, documentation line, commit messages and this description, and ran the tests. AI generated the code, tests and text. No human reviewed the diff line by line before submission.

tkv00 and others added 2 commits October 15, 2026 09:16
`extension add` and `extension info` list an extension's commands, but
only Cline and Forge get the names they register. Claude, Codex, Junie
and Copilot in skills mode register `speckit-<ext>-<cmd>`, yet both
listings print the manifest's dotted `speckit.<ext>.<cmd>`.

Add one case table shared by both listing tests: the four agents above,
Cline and Forge (already correct), and Copilot in commands mode and
Gemini, which register dotted names and must keep them. On main the
first four cases fail for both commands.

Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both listings special-cased Cline and Forge by name, so every other
agent that registers hyphenated names (25 of 41 integrations register
them; the listings handled 2) was shown names it does not have.

Ask the active integration for its command separator in the project's
mode (`invoke_separator_for_mode` with the persisted `ai_skills` flag)
and hyphenate with the helper extension skill registration already
uses. This is the approach github#4910 took for the init next-steps banner.
Agents that register dotted names, and unknown agents, keep the
manifest name.

A registry test checks that every integration's command-mode separator
matches the names CommandRegistrar writes, since the listings now rely
on that. The extension user guide notes that listed names follow the
agent.

Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tkv00
tkv00 requested a review from mnriem as a code owner October 15, 2026 00:22

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant