Align the repo with the plugin and hook references - #5
Merged
Conversation
Three changes, all from reading the official references properly.
The event list no longer blocks. validate.sh knew nine events; Claude
Code ships around thirty, so a hook on PostToolUseFailure, FileChanged,
PermissionRequest or SubagentStart would have been rejected by our own
CI as "unknown". The list is now complete as of today, and an event
missing from it is a warning rather than a failure — a validator that is
one release behind should not block work it has no business blocking. A
typo still surfaces, which was the only real point.
CI now also runs Claude Code's own validator. `claude plugin validate
--strict` checks each hook manifest against the real schema and catches
what ours cannot: misspelled field names, values of the wrong type,
leftovers from another tool's manifest. The marketplace manifest is
checked without --strict, because the official validator warns about a
catalog with no plugins and that is the correct state for main until a
hook merges.
The template moves to exec form: the interpreter in `command`, the
script in `args`. That spawns the script directly instead of handing a
string to sh -c, so quoting and spaces stop being a source of bugs. The
docs recommend it whenever a path placeholder is involved. validate.sh
now understands both forms, and shell form stays supported for hooks
that genuinely need a pipe.
Also adds the manifest metadata the schema supports ($schema for editor
autocomplete, keywords, license, homepage, repository), a description
for the marketplace itself, and a README section on userConfig,
defaultEnabled, async/asyncRewake, the `if` filter and
${CLAUDE_PLUGIN_DATA}.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Three findings from reading the plugins reference and the hooks reference against what this repo actually does.
1. Our validator rejected valid hooks
validate.shknew nine hook events. Claude Code ships around thirty. A contributor opening a PR for a hook onPostToolUseFailure,PermissionRequest,FileChanged,SubagentStart,TaskCompleted,PostCompact,SetuporCwdChangedwould have been told by our own CI that the event does not exist.The list is now complete as of today, but more importantly an unknown event is a warning, not a failure. This list will go stale again, and a validator that is one release behind should not block work it has no business blocking. A typo still surfaces — verified:
FileChangedpasses clean,PostToolUzewarns and the build stays green.2. There is an official validator we were not using
It checks the manifest against the real schema and catches what ours cannot: a misspelled field name (it even suggests the intended one), a value of the wrong type, a field left over from another tool's manifest.
--strictturns warnings into errors, which is what you want before publishing.Added as a
plugin-validatejob. It is deliberately not in the ruleset's required checks yet — it installs Claude Code from npm on every run, so let it prove itself over a few PRs first, then add it.The marketplace manifest is validated without
--strict: the official validator warns about a catalog with no plugins, which is the correct state formainuntil a hook merges. It also warned that the marketplace had no description, so that is fixed too.3. Shell form was the wrong default
The template handed a string to
sh -c:{ "command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/my-new-hook.py" }Exec form spawns the script directly, no shell involved, and the docs recommend it whenever a path placeholder is in play:
{ "command": "python3", "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/my-new-hook.py"] }Quoting, spaces and
$in a path stop being the author's problem.validate.shnow understands both forms — shell form stays supported for hooks that genuinely need a pipe or&&.Also
$schema(editor autocomplete),keywords,license,homepage,repository.userConfig,defaultEnabled,async/asyncRewake, theiffilter,${CLAUDE_PLUGIN_DATA}.userConfig, not in a file inside the project. That rule exists because of a real hole, fixed separately in theproject-checksPR.Testing
./scripts/validate.shandclaude plugin validate --strictboth pass. Command-form handling was tested four ways: exec form resolves the script, shell form still resolves it, exec form without${CLAUDE_PLUGIN_ROOT}fails, and a hard-coded personal path inargsfails.🤖 Generated with Claude Code