fix: migrate extension commands on integration switch#2404
fix: migrate extension commands on integration switch#2404mnriem merged 2 commits intogithub:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes extension command/skill migration when switching integrations so extension artifacts are cleaned up for the old agent and re-registered for the new agent, keeping agent directories and the extension registry consistent.
Changes:
- Added
ExtensionManager.unregister_agent_artifacts()to remove old agent extension command files and extension-generated skills, and to update the registry accordingly. - Added
ExtensionManager.register_enabled_extensions_for_agent()to re-register all enabled extensions for the new integration, including Copilot--skillsmode behavior. - Wired both steps into
integration_switch()and added integration-switch tests covering migration, skills mode, and disabled extensions.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Calls extension cleanup before clearing metadata and re-registration after installing the target integration. |
src/specify_cli/extensions.py |
Implements agent artifact unregistration and enabled-extension re-registration logic. |
tests/integrations/test_integration_subcommand.py |
Adds regression tests ensuring artifacts migrate/clean correctly across integrations and modes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
4b9719a to
591c6a4
Compare
|
Thanks for the review! All three comments have been addressed in the latest commit:
|
There was a problem hiding this comment.
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/3 changed files
- Comments generated: 3
|
Please address Copilot feedback. If not applicable, please explain why |
591c6a4 to
fe788ab
Compare
|
Thanks for the second round of review! All three comments have been addressed:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fe788ab to
1183d35
Compare
|
Addressing the two new comments: Comment 7 (Copilot skills mode frontmatter): The concern about mode: mapping is already handled correctly. CopilotIntegration.post_process_skill_content() parses the name: field from frontmatter and converts speckit-git-feature back to speckit.git-feature format before injecting mode:. Verified locally that generated SKILL.md contains mode: speckit.git-feature. Comment 8 (Test verification): Added assertion in test_switch_migrates_copilot_skills_extension_commands to verify the generated SKILL.md contains the correct mode: field mapping. |
There was a problem hiding this comment.
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/4 changed files
- Comments generated: 2
1183d35 to
788be6e
Compare
|
Addressing the two new comments: Comment 9 (Unknown agent cleanup): Added a guard in unregister_agent_artifacts() to return early when agent_name is not present in CommandRegistrar.AGENT_CONFIGS. This prevents losing registry entries while leaving orphaned files on disk during the "unknown integration via manifest" switch path. Comment 10 (Skills directory fallback): Changed the skills_dir passed to _unregister_extension_skills() to be None when the resolved agent_skills_dir does not exist on disk. This re-enables the fallback scan of all known agent skills directories, which is important for cleaning up stale registered_skills entries created by earlier installs. |
There was a problem hiding this comment.
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/4 changed files
- Comments generated: 1
|
Please address Copilot feedback |
788be6e to
f05638c
Compare
|
Addressing the latest Copilot comment (comment #11): unregister_agent_artifacts() was unconditionally clearing registered_skills after calling _unregister_extension_skills(). However, _unregister_extension_skills() may intentionally skip deletion when it cannot verify ownership via metadata.source (e.g., corrupted/missing SKILL.md). This left skill directories on disk while removing the only registry reference needed for future cleanup. Fixed by checking which skill directories still exist after cleanup and only keeping those still-present names in the registry. Future cleanup attempts will still be able to find skipped skills. |
|
@mnriem All Copilot feedback has been addressed across multiple commits. Here's a summary of all 11 comments and their resolutions:
All 244 tests pass. Please re-review when you have a chance. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f05638c to
fed6c19
Compare
|
Addressing the two new Copilot comments (round 4): Comment 12 (Stale registry on empty registration): register_enabled_extensions_for_agent() now explicitly removes the agent entry from registered_commands when registration returns an empty list (e.g., corrupted manifest pointing at missing command files). This prevents stale metadata that later cleanup would try to remove. Comment 13 (Incorrect registry reconciliation during fallback cleanup): When skills_dir is None (fallback scan mode), we no longer use agent_skills_dir to check remaining skills. Registry reconciliation now only happens when skills_dir is explicitly set (specific directory targeted), correctly matching what _unregister_extension_skills() actually removed. All 220 tests pass (30 integration subcommand + 190 extension tests). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fed6c19 to
9b4e87a
Compare
|
Fixed comment 14: Changed registry reconciliation to check |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
When switching integrations (e.g. kimi → opencode), extension commands were not re-registered for the new agent, leaving the new agent without extension support and orphaning files in the old agent's directory. Changes: - Add ExtensionManager.unregister_agent_artifacts() to clean up old agent extension files and registry entries during switch - Add ExtensionManager.register_enabled_extensions_for_agent() to re-register all enabled extensions for the new agent - Wire both into integration_switch() after uninstall/install phases - Handle skills mode (Copilot --skills) correctly - Add tests for kimi→opencode→claude migration, Copilot skills mode, and disabled extension handling Fixes extension commands not appearing after integration switch.
9b4e87a to
f2a929d
Compare
|
Fixed: Updated the warning message to refer to "extension artifacts (commands, skills, registry entries)" instead of just "extension commands", since unregister_agent_artifacts() also removes skills and updates registry entries. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/4 changed files
- Comments generated: 0 new
|
Thank you! |
Description
When switching integrations (e.g.,
specify integration switch opencode), extension commands were not re-registered for the new agent. This caused two problems:speckit.git.featurewere absent after switching from kimi to opencode)Root Cause
Extension commands are registered during
specify extension addviaCommandRegistrar.register_commands_for_all_agents(), which writes commands for all agents that already have directories. When switching integrations later, the new agent gets a fresh directory but extensions are never re-registered.Fix
Added two new
ExtensionManagermethods:unregister_agent_artifacts(agent_name)— Called after uninstalling the old integration. Removes extension command files and skills for the old agent, and cleans up registry entries.register_enabled_extensions_for_agent(agent_name)— Called after installing the new integration. Re-registers all enabled extensions for the new agent. Correctly handles Copilot--skillsmode by detectingai_skillsin init-options and skipping command registration when skills mode is active.Wired both into
integration_switch()insrc/specify_cli/__init__.py.Testing
uv run specify --helpuv sync --extra test && uv run pytestAutomated tests added
test_switch_migrates_extension_commands: Tests kimi → opencode → claude migration, verifying extension commands appear for the new agent and are removed from the oldtest_switch_migrates_copilot_skills_extension_commands: Tests Copilot with--skillsflag to ensure extensions are installed as skills, not commandstest_switch_does_not_register_disabled_extensions: Ensures disabled extensions are not re-registered after switchManual test results
Agent: Manual CLI testing | OS/Shell: macOS/zsh
specify init . --integration kimi.kimi/skills/specify integration switch opencode.opencode/command/, old skills removedspecify integration switch claude.claude/skills/, old commands removedTest results
AI Disclosure
This fix was developed with assistance from OpenAI Codex and Kimi coding agents. AI was used for:
unregister_agent_artifactsandregister_enabled_extensions_for_agentmethodsAll changes were reviewed, tested, and validated manually before submission.