Claude Code plugin

The hook that refuses a clone or install naming a blocked repository before it runs — what it sees, what it does not, and how to install it.

The Claude Code plugin — the one hook that refuses

Everything above is advisory: the agent asks, and what it does with the answer is up to it. Claude Code has a hook mechanism, so there the answer can be enforced. The RepoGates plugin runs a PreToolUse hook before every Bash tool call, sends the command line to POST /v1/preflight — parsed on the server, never executed, with URL credentials and NAME=value assignments redacted first — and acts on the decision. It also adds the MCP server and the vetting skill.

/plugin marketplace add https://repogates.com/plugin/marketplace.json
/plugin install repogates@repogates

The plugin is published from this site and nowhere else. That marketplace file names one plugin, the zip it comes from and the zip's sha256, so what installs is exactly what we built; /plugin update picks up a new version when the file changes. Prefer a folder you can read first? Download repogates-claude-plugin.zip, unzip it, and add the folder as a local marketplace: /plugin marketplace add ./repogates-claude-plugin.

Then create a personal API token on your account page and save it from a terminal, not through an agent:

umask 077; mkdir -p ~/.config/repogates; pbpaste > ~/.config/repogates/token

Run /repogates:setup to check it: it exercises the hook against a permanently blocked canary repository without ever printing the token. On a REVIEW, /repogates:scan owner/repo scans the files before you decide — priced in credits by size, and the command asks first.

The agent check-up

/repogates:checkup inventories what this machine's AI-agent setup already has — installed plugins and their marketplaces, skills, MCP servers, hooks, permission rules — and scores it with RepoGates. It runs the repogates-checkup CLI, a wheel served from this site at a version the command pins, reads the configuration on the machine and sends RepoGates identifiers, never contents. The check-up reads; it never runs a program, never changes a file, and never blocks anything. What it reads, what leaves, the score, the exit codes and what it cannot see: the check-up page. Part of Personal, Premium and Team.

RepoGates saysThe hook does
An active malware campaign, or a finding your policy profile blocks — hidden Unicode in agent rules, a nested bare repository, any CRIT the profile does not downgrade Refuses the command, with the reason and a report link.
A finding your policy warns on — every REVIEW, and the CRITs the shipped profiles downgrade (a devcontainer, an install script); could not be assessed; the repository is a variable or a subshell; hourly cap reached; not answered in time Asks you, with the reason and what decided it. In a headless run an ask cannot be answered, so the command does not run.
PASS Adds a one-line note. Claude Code's own permission prompt still applies to the rest of the line — a PASS is never a permission.
Nothing — the line names no GitHub repository Says nothing, and no request leaves the machine.
No answer — no token, an unknown or revoked token (401), no paid plan (402), rate limited (429), the service unreachable or answering 5xx, a missing tool, an interrupted hook Asks you, naming the cause and the fix. No answer is not permission.

Lines it recognises: git clone in every URL form, git submodule add, git remote add, gh repo clone, gh release download -R, npm/pnpm/yarn/bun installs with github:, o/r or git+ specs, npx degit, pip/uv/poetry with git+ specs, go get, cargo --git, and any github.com or githubusercontent.com URL whatever the verb — curl …/raw/o/r/… | sh included — also inside bash -c, eval, sudo, chains and heredocs. Registry packages too: npm install express, pip install flask, npx, yarn add, uv add — RepoGates asks npm or PyPI which source repository the package declares and assesses that one. A package that declares none is allowed, with a note; a registry that does not answer is asked about. Direct dependencies named on the command line only; transitive dependencies and lockfiles are not resolved. The repository is assessed, not the artifact: the tarball or wheel the registry serves for the version you install is not fetched or compared with it.

What it does not cover. Anything that is not a Bash tool call: Read/Edit/Write, MCP git tools, a human at a terminal, another agent. A command whose repository is not literally on the line (git clone $REPO, git submodule update, a manifest such as package.json) — those are asked about, not allowed. The dependency tree: a named package is resolved to its own repository, the packages it pulls in are not. Sessions with hooks disabled. A hook killed at its 15-second timeout is treated by Claude Code as "proceed", which is why the hook's own network budget is 12 seconds at most. Windows is best effort. Verified against Claude Code 2.1.251 on 2026-09-07: a refusal holds in headless runs and inside subagents, and an "ask" that cannot be answered stops the command; on 2026-09-09, with the plugin installed from the public marketplace, the same refusal held under --dangerously-skip-permissions.

What it does not see. RepoGates gates downloads made through the browser. It does not see git clone, package managers or curl — outside Claude Code with the RepoGates plugin, whose hook refuses a clone or install that names a blocked repository on the command line, before it runs. The hook sees Bash tool calls in that one client and nothing else. VS Code and Docker Desktop extensions and agent skills are answered through the MCP server and the plugin, not in the browser.