Skip to content

fix(extensions): roll back native outputs on failed install - #5384

Open
sx4im wants to merge 1 commit into
github:mainfrom
sx4im:fix/5379-extension-add-rollback
Open

sx4im wants to merge 1 commit into
github:mainfrom
sx4im:fix/5379-extension-add-rollback

Conversation

@sx4im

@sx4im sx4im commented Nov 11, 2026

Copy link
Copy Markdown

Fixes #5379

What broke: when extension add failed after command rendering (hook registration or the final registry write), the native SKILL.md outputs it already wrote were left behind while the extension stayed uninstalled. Only the generic route had rollback.

What changed: install_from_directory now rolls back the native route too. It unregisters the command and skill outputs the attempt wrote, removes the registry entry and hooks if they got that far, and removes the installed package while preserving any kept user config. The package cleanup is now shared with the generic rollback.

How verified: three new regression tests in tests/specify_cli/extensions/test_command_add.py, all fail before the fix and pass after: hook failure, registry-write failure, and a failed --force reinstall preserving kept config. Ran the extension, generic, and Claude integration suites (379 passed) and ruff check clean.

@sx4im
sx4im requested a review from mnriem as a code owner November 11, 2026 09:17
Copilot AI auto review requested due to automatic review settings November 11, 2026 09:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Rollback cleanup can delete pre-existing files, follow symlinks outside the project, and leave partially registered outputs behind instead of safely restoring only this attempt’s changes.

3 open issues
What changed in this PR

Extends failed extension-install rollback to native agent outputs, addressing #5379 alongside the existing generic-route cleanup.

Changes:

  • Adds native rollback for command and skill outputs, hooks, and registry entries.
  • Shares package cleanup between native and generic routes while preserving rescued user configuration.
  • Adds three regression tests covering hook failure, registry-write failure, and kept-config preservation during a failed force reinstall.
File Description
tests/​specify_cli/​extensions/​test_command_add.py Adds native rollback and configuration-preservation regression tests.
src/​specify_cli/​extensions/​__init__.py Adds native rollback and extracts shared package cleanup.

Review effort: Balanced (auto)

Comment on lines +3077 to +3079
CommandRegistrar(
self.project_root, include_generic=False
).unregister_commands(safe_commands, self.project_root)
self.project_root, include_generic=False
).unregister_commands(safe_commands, self.project_root)
self._unregister_extension_skills(registered_skills, manifest.id)
rollback_package_dir()
Comment on lines +3204 to +3206
try:
with changing_file(dest_dir, removal=True):
rollback_native_registration()

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.

[Bug]: Failed extension add leaves native SKILL.md outputs behind

2 participants