Repository navigation
fix(hooks): remove the old entry when a hook event or matcher changes - #316
Merged
Merged
Conversation
Hook entries were upserted by event and matcher, so changing a hook's `on` or `matcher` added a new capa:<id> entry and left the old one running. The database locator then pointed only at the new entry, so neither install nor capa clean removed the old one. Before placing an entry, capa now drops entries tagged with the same capa:<id> in other events (and, for Claude-like shapes, other matcher groups). An entry already in the target group stays where it is, so re-installs don't reorder the file. Antigravity is keyed by hook name and was not affected. resolveMatcher also returns "" instead of undefined when a mapping carries an explicit undefined matcherPrefix. Closes #306
Skill, plugin and hook entries pass def.version, def.ref (and repo
suffixes) to `git rev-parse --verify <ref>^{commit}`. Nothing checked
them first, so rev-parse's revision syntax (HEAD~2, main@{1}, :/text,
a..b) and option-like values reached git.
resolveRef, the only place these values reach git, now accepts only
plain tag/branch names and SHAs (letters, digits, . _ / + -, no leading
"-", no "..") and fails with a clear error otherwise. Lockfile pins
are checked the same way.
Closes #308
The capabilities-manager reference still described ${PLUGIN_DATA} as
~/.capa/plugin-data/<projectId>/<pluginId>/ that survives plugin updates.
Since #286 the folder is <slug>-<hash>, keyed by the declared source, and
it is removed when the plugin is no longer declared and by capa clean.
Match docs/README.md.
Closes #309
This was referenced Oct 14, 2026
removeTaggedElsewhere deleted every empty event array in the hooks object, including ones it never touched (a user's "Stop": [] or a Gemini disabled: []). Only delete an array this call emptied.
The allowlist rejected tags git accepts, such as changesets/lerna
monorepo tags (@scope/pkg@1.2.3), "feature#12" or unicode names, which
installed fine before. Reject what git check-ref-format rejects instead
(control characters, space, ~ ^ : ? * [ \, "..", "@{", a leading
"-", "/" or ".", and similar), which still rules out rev-parse's
revision syntax and option-like values.
The offline snapshot fast path only checked that a lockfile pin was 40
characters long before using it as a path segment, so a tampered
resolvedRef could point at another local directory. It now requires 40
hex characters; anything else falls through to resolveRef, which
rejects it.
docs(skills): correct the PLUGIN_DATA path and lifetime
fix(cache): validate git version/ref values before rev-parse
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changing a hook's
onormatcherleft the old provider entry running. capa upserted entries by event and matcher, so the newcapa:<id>entry was added next to the old one. The database locator then pointed only at the new entry, so neithercapa installnorcapa cleanremoved the old one. Closes #306.Stack 2/5: base #315, next #317.
What changed
upsertHookEntrydrops entries tagged with the samecapa:<id>that are outside the target:capa:<id>tags are matched).resolveMatchernow returns""instead ofundefinedwhen a mapping carries an explicitmatcherPrefix: undefined.Test plan
bunx tsc --noEmitChecklist
bunx tsc --noEmitpasses🤖 Generated with Claude Code