Automation·terminal·MIT
Quality Gate
Complexity, test status and CRAP scores of the functions Claude edits, above the prompt.

Quality Gate measures the functions Claude changes and keeps one line above the prompt with the result: session cost, the highest cyclomatic complexity among changed functions, how many need splitting, and whether the last test run passed. It also gives Claude a set of quality instructions, a review skill and a CLI that gates each changed function’s CRAP score. Everything runs on your machine.
CRAP (Change Risk Anti-Patterns) combines a function’s cyclomatic complexity, one plus its decision points, with how much of it your tests cover: complex, poorly covered code scores high. The bar here is strict. A new function, or one whose complexity went up, must score below 6, and a function with complexity 6 or more fails at any coverage, so the fix is splitting it.
What it does
- The band reads
$<cost> · CC <max> <ok|SPLIT n> · tests <pass|fail|none>, withstalewhen files changed after the last test run. SPLIT counts new or complexity-raised functions at 6 or more. Until coverage is set up, the first report adds a reminder. - Instructions for Claude. Each session, the plugin’s quality persona goes into the system prompt, followed by a list of the repository’s top-level function names (2 KB at most) so Claude reuses what exists. By default it asks Claude to mark shortcuts in source comments;
/quality-gate markers offhas them listed at the end of the reply instead. - Review.
/quality-gate:reviewreviews the diff,/quality-gate:review repoaudits the repository with 20 findings at most, and/quality-gate:review debtreports shortcut markers and the latest receipt. It reads existing coverage reports and never runs tests unasked. - The gate. The plugin’s CLI,
bin/quality-gate.js crap, scores the functions that changed against a base branch (localdevelop,mainormasterby default). It exits 1 when a function fails and 2 when a prerequisite or measured coverage is missing, and writes a receipt to.claude/quality-gate/receipts/<head-sha>.jsonfor CI or other hooks. Settings are optional, in.claude/quality-gate/crap.json. - Reuse signals after the scores flag a new function that shares a name with one in another file, and callers left behind by a removed function. They never change the verdict.
JavaScript and TypeScript are parsed with the TypeScript compiler, Python with its standard ast module (Python 3.10 or later), and PHP and Vue with lizard, which you install yourself.
Install
Needs Claude Code 2.1.287 or later, plus Node 22.5 or later and npm.
claude plugin marketplace add Eigenwise/eigenwise-toolshed
claude plugin install quality-gate@eigenwise-toolshed
The first session installs the TypeScript parser into the plugin folder with npm, in the background; offline, the CLI tells you to run npm install --prefix <plugin root>. Then work as usual: the band appears after the first turn with edits. /quality-gate off drops the instructions and hides the band, /quality-gate status shows both switches, and the switches persist across sessions.
How it works
Nothing in the hooks module blocks a tool call or ends a turn. It watches and reports; the blocking part is the CLI’s exit code, wherever you choose to run it.
classic.PostToolUseon Edit, Write, MultiEdit and NotebookEdit notes which files changed and marks the tests stale.tool.callsees only Bash and PowerShell commands that look like a test run (npm test,pnpm test,yarn test,bun test,node --test,pytest,vitest,jest,go test,cargo test) and records pass or fail from the result.- At
turn.complete, for each working directory with edits, it runs the CLI once (quality-gate turn, 20-second timeout) to measure the changed functions against HEAD, then publishes the report to the band. Subagent worktrees are measured separately, tool calls never start a measurement, and a failed run leaves the previous report in place. session.startstarts the parser install (180-second limit) and builds the name list (10 seconds).prompt.composeadds the instructions.
The only network use is npm fetching the parser. Measurement makes no model calls, but the instructions and the name list sit in the system prompt of every request, which costs input tokens. The switches live in Claude Code’s plugin store and turn reports in session state; the live measurement writes nothing to your repository, only the CLI gate does.
Limitations
- The live measurement never runs or claims coverage, so the band reports complexity only. A full CRAP pass needs LCOV (default
coverage/lcov.info) or acoverageCommand, which runs with a 5-minute timeout and is thrown out if the sources change during the run. Older LCOV needs a sibling<lcov>.sources.jsonof source hashes captured with it, or it stays unverified. - PHP and Vue get complexity, but their coverage always stays unverified.
- Reuse signals match names by pattern: they miss nested definitions and can count a same-named call in another module.
- In organization-managed Claude Code, the instructions are added only for plugins that managed settings allow.
- The author says Ponytail’s persona contradicts this one on the test bar and the shortcut markers, and advises uninstalling Ponytail if you have both.
Similar Claude Mods
Sidequest
A local Kanban board of tickets that survive compaction, plus verified parallel work.
effortless
Picks the effort for every prompt and shows how long the prompt cache stays warm.
ripple
Effort per prompt, subagents routed to GPT, DeepSeek or Claude, and cache warnings.
fable-pin
Every subagent spawn rewritten to the Fable model, with /fable-pin on, off and status.
Popular Claude Mods
The whole directory →shared-session
Share a session by link: teammates join from their Claude Code and prompt it live.
filetree
Sidebar file tree with git status that lights up what Claude reads, edits and commits.
shunt
Shared account pool headroom and reset times from the shunt gateway, at zero token cost.
kindex-modern
Task tools backed by a Kindex store in your repo, plus repo memory on every prompt.





