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.
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.
/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 says | The 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.