mirror of
https://github.com/github/spec-kit.git
synced 2026-08-15 14:02:04 +02:00
Preserve global skill tracking across agents in unregister_agent_artifacts
The present-directory branch of ExtensionManager.unregister_agent_artifacts()
recomputed "remaining" registered_skills only by checking whether each name
still existed under the just-cleaned agent's own directory. registered_skills
is a single flat list shared across every agent an extension was ever
activated under (skills are only ever rendered for the currently active
agent, so there's no per-agent registry key). Repro: auggie and copilot both
have mirrors for the same extension; unregister_agent_artifacts("auggie")
correctly removes auggie's own mirror, sees the names absent from auggie's
(now empty) directory, and stores an empty registered_skills list - even
though copilot's mirror is still live on disk and now untracked. A later full
remove() then reads an empty registry and leaves copilot's mirror orphaned.
Fix: after the agent-scoped cleanup, recompute remaining names with
_extension_owned_skill_names(), which scans every safe, configured agent
skills directory (not just the one just cleaned) and keeps a name only if a
marker-verified SKILL.md for this extension still exists somewhere. This is
the same helper already used for the analogous same-agent toggle-cleanup
case, so no new abstraction was introduced. Explicit per-agent cleanup,
marker ownership verification, and symlink/containment safety are unchanged.
Added regression test:
- test_unregister_agent_artifacts_preserves_tracking_for_other_agent_mirror
Assisted-by: GitHub Copilot (model: Claude Sonnet 5, autonomous)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1901,15 +1901,21 @@ class ExtensionManager:
|
||||
# When the directory does exist, _unregister_extension_skills
|
||||
# may intentionally skip deletion when ownership cannot be
|
||||
# verified (e.g., corrupted/missing SKILL.md or mismatching
|
||||
# metadata.source). Only drop registry entries for skill
|
||||
# directories that were actually removed so future cleanup
|
||||
# attempts can still find skipped ones.
|
||||
# metadata.source). A name no longer present under *this*
|
||||
# agent's directory isn't necessarily gone everywhere either
|
||||
# — registered_skills is a single flat list shared across
|
||||
# every agent this extension was ever activated under, so
|
||||
# an earlier activation under a different, still-active
|
||||
# agent may have left its own marker-verified mirror behind.
|
||||
# Recompute across every safe, supported skills directory
|
||||
# (the same helper used for the analogous toggle-cleanup
|
||||
# case) rather than just this one, or a still-existing
|
||||
# mirror elsewhere would be silently dropped from tracking
|
||||
# and orphaned on later removal (#2948).
|
||||
if agent_skills_dir.is_dir():
|
||||
remaining_skills = [
|
||||
skill_name
|
||||
for skill_name in registered_skills
|
||||
if (agent_skills_dir / skill_name).is_dir()
|
||||
]
|
||||
remaining_skills = self._extension_owned_skill_names(
|
||||
registered_skills, ext_id
|
||||
)
|
||||
if remaining_skills != registered_skills:
|
||||
updates["registered_skills"] = remaining_skills
|
||||
|
||||
|
||||
Reference in New Issue
Block a user