Repository navigation
ci: validate and test Claude Code mods, and auto-bump the pinned CLI - #1564
Merged
Merged
Conversation
Claude Code loads a hooks module only after its static analysis passes and silently skips one that fails, so a mod that cannot load passed every check here and did nothing on an adopter's machine. - check-claude-mods runs `claude plugin validate --strict` and `claude plugin test` on every plugin whose hooks/hooks.json declares `modules`, with Claude Code pinned in the prek hook env. It is in the manual stage, so commits never fetch the binary; the prek workflow runs it over the whole repo on every PR and push to main. - check-claude-mods-local runs the same check on ordinary commits with the contributor's own Claude Code, skipping when it is absent or older than the pin. - bump-hook-npm-pins.yml moves npm pins in hooks' additional_dependencies (which Dependabot never touches) three times a week, keeping a single draft PR updated in place. The cooldown is 7 days by default and 12 hours for Claude Code, which replaces a bad or vulnerable release within hours. Claude Code is a dev-only tool here: nothing from it ships in a release or a plugin. Generated-by: Claude Opus 5
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
Runs
claude plugin validate --strictandclaude plugin teston every Claude Code mod in the tree, and keeps the Claude Code version that checks them current.Claude Code loads a hooks module only after its static analysis passes, and silently skips one that fails. A mod that cannot load therefore passes every other check here and does nothing on an adopter's machine. #1552 is that case today: its module imports
node:fs, and its tests (node:test) pass under plain node. Step 3 of #1497 asked for these two commands in prek / CI;docs/when-to-use-mods.mdalready required them, with nothing enforcing it.check-claude-mods(tools/dev/check-claude-mods.sh): validates and tests every plugin whosehooks/hooks.jsondeclaresmodules. A mod with no*.test.tsfails. A no-op while the tree has no mod, which is the case onmaintoday.language: node, with@anthropic-ai/claude-codepinned inadditional_dependencies, so prek installs it like lychee's toolchain: no local install, no login, no network beyond the npm install.stages: [manual], so commits never fetch the ~220 MB binary.pre-commit.ymlruns it in a step of its own, over the whole repo, on every PR and every push tomain. Whole repo because a pin bump touches no mod file but has to re-check every mod.check-claude-mods-local: the same script on ordinary commits, with the contributor's ownclaude. It skips when Claude Code is not installed or cannot run, and when the local version is older than the pin (an older CLI may not know events a mod uses). A newer one runs. CI skips this hook; the pinned run is authoritative.bump-hook-npm-pins.yml+tools/dev/bump-hook-npm-pins.py: Dependabot'spre-commitecosystem never touchesadditional_dependencies, so this moves those npm pins to the newest stable release past the package's cooldown, never backwards. Runs Monday / Wednesday / Friday and on demand. One fixed branch and one draft PR: a later bump updates the open PR in place (fresh signed commit on currentmain, back to draft so marking it ready starts the checks), and a run matching what the PR already carries changes nothing..github/dependabot.yml; 12 hours for Claude Code. A cooldown buys time for a bad or compromised release to be withdrawn. Claude Code ships several times a day and replaces a bad release within hours, and a security problem in it is fixed by the next release, so a week-long wait would hold CI on the known-bad version rather than protect it. Adopters auto-update, so the check also has to track what they actually run.docs/when-to-use-mods.mdgains the import rule, the note on keeping a settings hook wired inhooks.jsonnext tomodules, and the CI and bump details.tools/dev/README.mdgets rows for both scripts.Claude Code is a dev-only tool here
Claude Code (
@anthropic-ai/claude-code, licensed under Anthropic's terms rather than an open-source licence) is used only as a CI and developer check for Claude Code mods. It is not a dependency of anything Magpie ships: nothing from it is bundled, vendored, or redistributed in a release, a source archive, or a plugin. The local hook uses a contributor's own install when one exists and skips otherwise, so contributing to Magpie does not require it.Type of change
.claude/skills/<name>/) — eval fixtures updated belowtools/<system>/*.md)tools/*/withpyproject.toml)docs/,README.md,CONTRIBUTING.md)projects/_template/)prek, workflows, validators)Test plan
prek run --all-filespasses.tools/dev/tests/test_bump_hook_npm_pins.py: 6 tests (cooldown, pre-releases, numeric ordering, never backwards, only exact pins inadditional_dependencies).main's tree: passes (no mods).hooks/files dropped in: fails onnode:fs(validate) andnode:test(test).claudeonPATH,claudepresent but not runnable, local older than the pin.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1, against a throwaway config dir.bump-hook-npm-pins.pyrun live against npm: moved the pin2.1.292 -> 2.1.295, the commit in this PR.bump-hook-npm-pins.ymlneedsmainand Actions to run; its first scheduled or manual run after merge is the real test.RFC-AI-0004 compliance
~/.claude.docs/when-to-use-mods.md; no skill depends on it.Linked issues
Refs #1497 (step 3). Will make #1552's CI fail until its module uses the mods API.
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5) following the guidelines
🤖 Generated with Claude Code