Bug Description
Removal paths should not be derived from persisted component IDs without checking that the component is installed or owned, that the ID is a valid single path component, and that the target is the expected filesystem object.
Extension and preset removal currently lack these checks at their destructive manager operations. Extension removal can also write config backups. This is conditional hardening: reaching the reported bundle path requires coordinated project-state changes and an explicit user removal command, not an automatic trigger.
Steps to Reproduce
In an isolated temporary project, add an unsafe ID to the extension registry and a matching bundle record, then exercise the removal path using disposable targets. Inspect the paths used for deletion and config backup. Review direct preset removal with an unsafe registered ID. No reproduction should target real user files. This is a source-level finding; no destructive live reproduction was performed for this issue.
Expected Behavior
- Each removal operation checks installed or owned state using that component's existing source of truth.
- IDs used as directory names are well formed before path construction.
- An existing directory target must be a real directory, not a symlink. Invalid targets fail explicitly without deletion.
- Extension config backups cannot be redirected through a symlinked backup destination.
- Valid removals, including existing missing-target and config-preservation behavior, continue to work.
Actual Behavior
ExtensionManager.remove() and PresetManager.remove() use registry IDs to construct removal paths without an independent ID and target check at the destructive operation. Bundle removal can pass a recorded extension ID to the extension manager.
Specify CLI Version
Source checkout declares 1.0.10.dev0 in pyproject.toml.
AI Agent
Not applicable.
Operating System
Not platform-specific.
Python Version
Any supported version (>=3.11).
Error Logs
N/A; source-level finding.
Additional Context
Scope the implementation to extension and preset removal, plus an audit of integration uninstall's separately recorded file paths. Verify that workflow and step removal retain their existing ID and target guards; they do not need a new common registry check. Add isolated regression tests for invalid IDs, symlink targets, backup redirection, and valid removals. Do not prohibit symlinked project or storage parents solely as part of this ID fix.
AI Disclosure
Drafted by GitHub Copilot (model: GPT-6 Sol; interactive, autonomous AI drafting under user direction; reasoning-effort setting not available to me). The issue text was fully AI-drafted and approved by the user for filing.
Bug Description
Removal paths should not be derived from persisted component IDs without checking that the component is installed or owned, that the ID is a valid single path component, and that the target is the expected filesystem object.
Extension and preset removal currently lack these checks at their destructive manager operations. Extension removal can also write config backups. This is conditional hardening: reaching the reported bundle path requires coordinated project-state changes and an explicit user removal command, not an automatic trigger.
Steps to Reproduce
In an isolated temporary project, add an unsafe ID to the extension registry and a matching bundle record, then exercise the removal path using disposable targets. Inspect the paths used for deletion and config backup. Review direct preset removal with an unsafe registered ID. No reproduction should target real user files. This is a source-level finding; no destructive live reproduction was performed for this issue.
Expected Behavior
Actual Behavior
ExtensionManager.remove()andPresetManager.remove()use registry IDs to construct removal paths without an independent ID and target check at the destructive operation. Bundle removal can pass a recorded extension ID to the extension manager.Specify CLI Version
Source checkout declares
1.0.10.dev0inpyproject.toml.AI Agent
Not applicable.
Operating System
Not platform-specific.
Python Version
Any supported version (
>=3.11).Error Logs
N/A; source-level finding.
Additional Context
Scope the implementation to extension and preset removal, plus an audit of integration uninstall's separately recorded file paths. Verify that workflow and step removal retain their existing ID and target guards; they do not need a new common registry check. Add isolated regression tests for invalid IDs, symlink targets, backup redirection, and valid removals. Do not prohibit symlinked project or storage parents solely as part of this ID fix.
AI Disclosure
Drafted by GitHub Copilot (model: GPT-6 Sol; interactive, autonomous AI drafting under user direction; reasoning-effort setting not available to me). The issue text was fully AI-drafted and approved by the user for filing.