Skip to content

fix(extensions): preserve user files when removing supplemental extension skills - #5385

Open
sx4im wants to merge 1 commit into
github:mainfrom
sx4im:fix/5381-supplemental-skill-rmtree
Open

sx4im wants to merge 1 commit into
github:mainfrom
sx4im:fix/5381-supplemental-skill-rmtree

Conversation

@sx4im

@sx4im sx4im commented Nov 11, 2026

Copy link
Copy Markdown

Fixes #5381

What broke
Removing a supplemental extension skill deleted the whole skill directory with shutil.rmtree, so any files the user added after install (notes, extra references) were destroyed. The same removal ran during extension update.

What changed

  • Removal now deletes only SKILL.md, the one file the extension creates, and removes the directory only if it is empty.
  • Reinstall after removal regenerates SKILL.md next to surviving user files instead of skipping the directory.
  • A SKILL.md linked to a file outside the extension directory is now left alone in all removal paths, including update rollback.

How verified

  • Two new regression tests in tests/test_extension_skills.py: removal preserves user files, and reinstall regenerates SKILL.md beside them. Both failed before the fix and pass with it.
  • Extension and generic integration suites: 645 passed. Ruff 0.15.0 (the version CI uses) reports no issues.

…sion skills

Removing a supplemental extension skill deleted the whole skill directory with shutil.rmtree, destroying files the user added after install (notes, extra references). Only SKILL.md is created by the extension, so removal now deletes just that file and removes the directory only if it is empty, mirroring the generic branch. Reinstall after removal also regenerates SKILL.md next to surviving user files instead of skipping the directory. A SKILL.md that is a link to a file outside the extension directory is now always left alone, including on update rollback.
@sx4im
sx4im requested a review from mnriem as a code owner November 11, 2026 09:32
Copilot AI auto review requested due to automatic review settings November 11, 2026 09:32

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

Unresolved symlink-handling flaws can cause installation to write outside the skills directory and cleanup to delete an unrelated SKILL.md file.

4 open issues
What changed in this PR

Addresses #5381 by preserving user-added files when supplemental extension skills are removed or updated.

Changes:

  • Deletes only extension-owned SKILL.md files and removes skill directories only when empty.
  • Supports regenerating skills beside preserved files during forced reinstall and update, while preserving externally linked skill files during removal.
  • Adds preservation and reinstall regression tests and updates installation mocks to forward force.
File Description
tests/​test_extension_skills.py Adds Bob-specific removal and reinstall regression tests.
tests/​specify_cli/​extensions/​test_command_update.py Updates the installation mock to accept and forward force.
tests/​integrations/​test_integration_generic.py Updates generic update mocks to forward force.
src/​specify_cli/​extensions/​_command_update_transaction.py Enables forced reinstall during extension updates.
src/​specify_cli/​extensions/​__init__.py Adds selective skill cleanup, link preservation, and reinstall handling.

Review effort: Balanced (auto)

if not is_expected_dev_symlink and not force:
continue
elif skill_dir_preexists and not force:
elif skill_dir_preexists and not force and not reinstall:
Comment on lines +2252 to +2256
unlink(skill_file, missing_ok=True)
try:
skill_subdir.rmdir()
except OSError:
pass
if not is_expected_dev_symlink and not force:
continue
elif skill_dir_preexists and not force:
elif skill_dir_preexists and not force and not reinstall:
Comment on lines +2228 to 2231
if skill_file.is_symlink() and not skill_file.resolve().is_relative_to(
(self.extensions_dir / extension_id).resolve()
):
continue

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]: Removing supplemental extension skills deletes unrelated user files (rmtree)

2 participants