Skip to content

fix: extension command registration with agy/Antigravity#1704

Open
neelneelpurk wants to merge 1 commit intogithub:mainfrom
neelneelpurk:fix/extension-command-registration-agy
Open

fix: extension command registration with agy/Antigravity#1704
neelneelpurk wants to merge 1 commit intogithub:mainfrom
neelneelpurk:fix/extension-command-registration-agy

Conversation

@neelneelpurk
Copy link

@neelneelpurk neelneelpurk commented Feb 26, 2026

Summary

Fixed extension subcommand registration issue in Agy/Antigravity

Issue

Fixes #1705

Description

Problem

Spec Kit supports AGY/Antigravity in specify init, but specify extension add does not register extension commands into .agent/workflows. The extension installs successfully, yet no new command files appear.

Steps to Reproduce

  1. Create a Spec Kit project for AGY / Antigravity
  2. Install an extension:
    specify extension add --dev /path/to/extension
  3. Check .agent/workflows.

Expected Behavior

Extension commands are written to .agent/workflows (e.g., speckit..*.md).

Actual Behavior

No new command files appear in .agent/workflows.

Specify CLI Version

0.1.6

AI Agent

Antigravity

Operating System

mac0S v26.3

Python Version

python 3.12.1

Root Cause

AGY is defined in the init agent list, but is missing from the extension command registrar list, so extension installs never target .agent/workflows.

  • AGY is present for project initialization:
    init.py(lines 240–245) define AGY with folder: ".agent/" and commands_subdir: "workflows".
  • AGY is missing from extension registration:
    extensions.py(lines 600–679) list supported agents for command registration; agy is not included.

Solution

Add the following entry for agy to CommandRegistrar.AGENT_CONFIGS in extensions.py.

"agy": {
    "dir": ".agent/workflows",
    "format": "markdown",
    "args": "$ARGUMENTS",
    "extension": ".md"
},

Testing

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

Output of uv run pytest

~/…/spec-kit $ uv pip install -e ".[test]" && uv run pytest
<truncated 31 lines>
tests/test_ai_skills.py::TestInstallAiSkills::test_empty_yaml_frontmatter PASSED [ 11%]
tests/test_ai_skills.py::TestInstallAiSkills::test_enhanced_descriptions_used_when_available PASSED [ 12%]
tests/test_ai_skills.py::TestInstallAiSkills::test_template_without_frontmatter PASSED [ 13%]
tests/test_ai_skills.py::TestInstallAiSkills::test_missing_templates_directory PASSED [ 14%]
tests/test_ai_skills.py::TestInstallAiSkills::test_empty_templates_directory PASSED [ 15%]
tests/test_ai_skills.py::TestInstallAiSkills::test_malformed_yaml_frontmatter PASSED [ 16%]
tests/test_ai_skills.py::TestInstallAiSkills::test_additive_does_not_overwrite_other_files PASSED [ 17%]
tests/test_ai_skills.py::TestInstallAiSkills::test_return_value PASSED   [ 18%]
tests/test_ai_skills.py::TestInstallAiSkills::test_return_false_when_no_templates PASSED [ 20%]
tests/test_ai_skills.py::TestInstallAiSkills::test_non_md_commands_dir_falls_back PASSED [ 21%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[copilot] PASSED [ 22%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[claude] PASSED [ 23%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[gemini] PASSED [ 24%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[cursor-agent] PASSED [ 25%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[qwen] PASSED [ 26%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[opencode] PASSED [ 27%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[codex] PASSED [ 28%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[windsurf] PASSED [ 29%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[kilocode] PASSED [ 30%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[auggie] PASSED [ 31%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[codebuddy] PASSED [ 32%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[qodercli] PASSED [ 33%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[roo] PASSED [ 34%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[q] PASSED [ 35%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[amp] PASSED [ 36%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[shai] PASSED [ 37%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[agy] PASSED [ 38%]
tests/test_ai_skills.py::TestInstallAiSkills::test_skills_install_for_all_agents[bob] PASSED [ 40%]
tests/test_ai_skills.py::TestCommandCoexistence::test_existing_commands_preserved_claude PASSED [ 41%]
tests/test_ai_skills.py::TestCommandCoexistence::test_existing_commands_preserved_gemini PASSED [ 42%]
tests/test_ai_skills.py::TestCommandCoexistence::test_commands_dir_not_removed PASSED [ 43%]
tests/test_ai_skills.py::TestCommandCoexistence::test_no_commands_dir_no_error PASSED [ 44%]
tests/test_ai_skills.py::TestNewProjectCommandSkip::test_new_project_commands_removed_after_skills_succeed PASSED [ 45%]
tests/test_ai_skills.py::TestNewProjectCommandSkip::test_commands_preserved_when_skills_fail PASSED [ 46%]
tests/test_ai_skills.py::TestNewProjectCommandSkip::test_here_mode_commands_preserved PASSED [ 47%]
tests/test_ai_skills.py::TestSkipIfExists::test_existing_skill_not_overwritten PASSED [ 48%]
tests/test_ai_skills.py::TestSkipIfExists::test_fresh_install_writes_all_skills PASSED [ 49%]
tests/test_ai_skills.py::TestSkillDescriptions::test_all_known_commands_have_descriptions PASSED [ 50%]
tests/test_ai_skills.py::TestCliValidation::test_ai_skills_without_ai_fails PASSED [ 51%]
tests/test_ai_skills.py::TestCliValidation::test_ai_skills_without_ai_shows_usage PASSED [ 52%]
tests/test_ai_skills.py::TestCliValidation::test_ai_skills_flag_appears_in_help PASSED [ 53%]
tests/test_ai_skills.py::TestParameterOrderingIssue::test_ai_flag_consuming_here_flag PASSED [ 54%]
tests/test_ai_skills.py::TestParameterOrderingIssue::test_ai_flag_consuming_ai_skills_flag PASSED [ 55%]
tests/test_ai_skills.py::TestParameterOrderingIssue::test_error_message_provides_hint PASSED [ 56%]
tests/test_ai_skills.py::TestParameterOrderingIssue::test_error_message_lists_available_agents PASSED [ 57%]
tests/test_ai_skills.py::TestParameterOrderingIssue::test_ai_commands_dir_consuming_flag PASSED [ 58%]
tests/test_extensions.py::TestExtensionManifest::test_valid_manifest PASSED [ 60%]
tests/test_extensions.py::TestExtensionManifest::test_missing_required_field PASSED [ 61%]
tests/test_extensions.py::TestExtensionManifest::test_invalid_extension_id PASSED [ 62%]
tests/test_extensions.py::TestExtensionManifest::test_invalid_version PASSED [ 63%]
tests/test_extensions.py::TestExtensionManifest::test_invalid_command_name PASSED [ 64%]
tests/test_extensions.py::TestExtensionManifest::test_no_commands PASSED [ 65%]
tests/test_extensions.py::TestExtensionManifest::test_manifest_hash PASSED [ 66%]
tests/test_extensions.py::TestExtensionRegistry::test_empty_registry PASSED [ 67%]
tests/test_extensions.py::TestExtensionRegistry::test_add_extension PASSED [ 68%]
tests/test_extensions.py::TestExtensionRegistry::test_remove_extension PASSED [ 69%]
tests/test_extensions.py::TestExtensionRegistry::test_registry_persistence PASSED [ 70%]
tests/test_extensions.py::TestExtensionManager::test_check_compatibility_valid PASSED [ 71%]
tests/test_extensions.py::TestExtensionManager::test_check_compatibility_invalid PASSED [ 72%]
tests/test_extensions.py::TestExtensionManager::test_install_from_directory PASSED [ 73%]
tests/test_extensions.py::TestExtensionManager::test_install_duplicate PASSED [ 74%]
tests/test_extensions.py::TestExtensionManager::test_remove_extension PASSED [ 75%]
tests/test_extensions.py::TestExtensionManager::test_remove_nonexistent PASSED [ 76%]
tests/test_extensions.py::TestExtensionManager::test_list_installed PASSED [ 77%]
tests/test_extensions.py::TestExtensionManager::test_config_backup_on_remove PASSED [ 78%]
tests/test_extensions.py::TestCommandRegistrar::test_parse_frontmatter_valid PASSED [ 80%]
tests/test_extensions.py::TestCommandRegistrar::test_parse_frontmatter_no_frontmatter PASSED [ 81%]
tests/test_extensions.py::TestCommandRegistrar::test_render_frontmatter PASSED [ 82%]
tests/test_extensions.py::TestCommandRegistrar::test_register_commands_for_claude PASSED [ 83%]
tests/test_extensions.py::TestCommandRegistrar::test_command_with_aliases PASSED [ 84%]
tests/test_extensions.py::TestVersionSatisfies::test_version_satisfies_simple PASSED [ 85%]
tests/test_extensions.py::TestVersionSatisfies::test_version_satisfies_range PASSED [ 86%]
tests/test_extensions.py::TestVersionSatisfies::test_version_satisfies_complex PASSED [ 87%]
tests/test_extensions.py::TestVersionSatisfies::test_version_satisfies_invalid PASSED [ 88%]
tests/test_extensions.py::TestIntegration::test_full_install_and_remove_workflow PASSED [ 89%]
tests/test_extensions.py::TestIntegration::test_multiple_extensions PASSED [ 90%]
tests/test_extensions.py::TestExtensionCatalog::test_catalog_initialization PASSED [ 91%]
tests/test_extensions.py::TestExtensionCatalog::test_cache_directory_creation PASSED [ 92%]
tests/test_extensions.py::TestExtensionCatalog::test_cache_expiration PASSED [ 93%]
tests/test_extensions.py::TestExtensionCatalog::test_search_all_extensions PASSED [ 94%]
tests/test_extensions.py::TestExtensionCatalog::test_search_by_query PASSED [ 95%]
tests/test_extensions.py::TestExtensionCatalog::test_search_by_tag PASSED [ 96%]
tests/test_extensions.py::TestExtensionCatalog::test_search_verified_only PASSED [ 97%]
tests/test_extensions.py::TestExtensionCatalog::test_get_extension_info PASSED [ 98%]
tests/test_extensions.py::TestExtensionCatalog::test_clear_cache PASSED  [100%]

============================== 95 passed in 1.10s ==============================

Testing with a sample project

I installed the Specifiy extension using my local build, and the extension commands were registered successfully. The screenshot is attached below.

Screenshot 2026-02-27 at 1 23 43 AM

AI Disclosure

Used Codex for debugging the Antigravity extension registration issue.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes extension command registration for AGY/Antigravity projects so that specify extension add writes extension command files into the agent’s workflow directory (aligning extension behavior with specify init support for AGY).

Changes:

  • Add an agy entry to CommandRegistrar.AGENT_CONFIGS so extension commands are emitted to .agent/workflows as Markdown .md files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +680 to +684
"agy": {
"dir": ".agent/workflows",
"format": "markdown",
"args": "$ARGUMENTS",
"extension": ".md"
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new AGY/Antigravity registration path is not covered by tests. tests/test_extensions.py currently exercises command registration only for Claude, so this change could regress without detection. Consider adding a CommandRegistrar test that creates a .agent/workflows dir and asserts commands are written there (and/or that register_commands_for_all_agents detects .agent).

Copilot uses AI. Check for mistakes.
Comment on lines +680 to +684
"agy": {
"dir": ".agent/workflows",
"format": "markdown",
"args": "$ARGUMENTS",
"extension": ".md"
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CommandRegistrar.AGENT_CONFIGS duplicates agent directory metadata that also exists in src/specify_cli/__init__.py (AGENT_CONFIG), and this drift is what caused AGY to be missed originally. To reduce future mismatches, consider deriving these paths/placeholders from a shared config or adding a validation test that ensures any agent with a commands directory configured is represented here.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback where applicable. If not please explain why

@neelneelpurk
Copy link
Author

Please address Copilot feedback where applicable. If not please explain why

I agree with the Copilot's comments.

In the current implementation, we effectively have two sources of truth:

  • AGENT_CONFIG (used during project initialization), and
  • CommandRegistrar.AGENT_CONFIGS (used during extension command registration).

But the scope of this PR was adding AGY support to extension command registration, since AGY was already supported in specify init but missing from the registrar.

So, to address the duplication properly, I’ve opened a separate PR that consolidates the configuration and removes this drift. Once that merges, it will fully resolve my issue and make sure that it doesn't happen again for any other new agent in the future.

PR #1712

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.

[Bug]: AGY projects don’t get extension commands registered

3 participants