
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
Quality gate for git changes — run checks and AI reviews against changed files
Quality gate for git changes — run deterministic checks and AI-powered reviews against changed files.
In AI-native workflows, agents produce large volumes of code changes. Compound guardrails — type checking, linting, testing — let agents receive automated feedback and self-correct in a tight loop. gatecheck makes this simple: run gatecheck check and it executes your configured checks, scoped to only the files that changed. Run gatecheck review to get AI-powered code reviews on the same changed files.
Designed for AI agent integration. Ships with built-in support for Claude Code hooks and Copilot CLI hooks.
pnpm add -D gatecheck
Run the interactive setup to generate a gatecheck.yaml config file:
pnpm gatecheck setup
The setup wizard walks you through:
untracked,unstaged,staged,branch:main).all).For non-interactive setup (CI, scripts):
pnpm gatecheck setup --non-interactive
gatecheck checkRun deterministic checks (lint, typecheck, test, format) against changed files.
# Run all checks with config defaults
pnpm gatecheck check
# Specify changed sources and target groups
pnpm gatecheck check --changed staged --target lint,typecheck
# Preview which checks would run
pnpm gatecheck check --dry-run
# Machine-readable output
pnpm gatecheck check --format json
Options:
| Flag | Description |
|---|---|
-c, --changed <sources> | Changed sources (comma-separated). See Changed Sources |
-t, --target <groups> | Target groups (comma-separated or "all") |
-d, --dry-run | Show which checks would run without executing |
-f, --format <format> | Output format: text (default), json, claude-code-hooks, copilot-cli-hooks |
gatecheck reviewRun AI-powered code reviews against changed files.
# Run all configured reviews
pnpm gatecheck review
# Preview review configuration
pnpm gatecheck review --dry-run
# Review changes since main branch
pnpm gatecheck review --changed branch:main
Options:
| Flag | Description |
|---|---|
-c, --changed <sources> | Changed sources (comma-separated) |
-d, --dry-run | Show review config and matched files without executing |
gatecheck setupCreate or update gatecheck.yaml interactively.
| Flag | Description |
|---|---|
--non-interactive | Skip prompts, auto-detect presets from package.json |
All configuration lives in gatecheck.yaml at your project root.
defaults:
changed: untracked,unstaged,staged,branch:main
target: all
checks:
- name: typecheck
match: '\.(m|c)?tsx?$'
group: typecheck
command: pnpm exec tsc --noEmit
- name: eslint
match: '\.(m|c)?(j|t)sx?$'
group: lint
command: pnpm exec eslint {{ ctx.CHANGED_FILES }}
reviews:
- name: claude-review
match: '.*'
exclude: '**/*.md'
vars:
prompt: |
Changed files: {{ ctx.CHANGED_FILES }}
You are a professional software architect.
Please review the changes above.
Point out any design issues, bug risks, or improvements.
command: claude --permission-mode 'auto' -p {{ vars.prompt }}
fallbacks:
- codex exec --sandbox 'workspace-write' {{ vars.prompt }}
defaults (optional)
| Field | Type | Description |
|---|---|---|
changed | string | Default changed sources (comma-separated) |
target | string | Default target groups (comma-separated or "all") |
checks[]
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Unique check identifier |
match | string | yes | Regex pattern matched against relative file paths |
exclude | string | no | Glob pattern to exclude matched files |
group | string | yes | Group name for --target filtering |
command | string | yes | Shell command to execute (supports templates) |
changedFiles.separator | string | no | Separator between file paths (default: " ") |
changedFiles.path | string | no | "relative" (default) or "absolute" |
reviews[]
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Unique review identifier |
match | string | yes | Regex pattern matched against relative file paths |
exclude | string | no | Glob pattern to exclude matched files |
vars | map | no | Template variables (can reference env, match, ctx) |
command | string | yes | Primary command to execute |
fallbacks | string[] | no | Fallback commands tried in order if primary fails |
Commands and vars support {{ scope.KEY }} template syntax.
| Scope | Description | Example |
|---|---|---|
env | Environment variables | {{ env.HOME }} |
match | Regex named capture groups | {{ match.workspace }} |
ctx | Runtime context | {{ ctx.CHANGED_FILES }} |
vars | User-defined variables | {{ vars.prompt }} |
| Variable | Available in | Description |
|---|---|---|
ctx.CHANGED_FILES | checks, reviews | Space-separated matched file paths. Shell-escaped in checks; plain in reviews |
ctx.DIFF_SUMMARY | reviews only | Full git diff output for review context |
In check commands, {{ ctx.CHANGED_FILES }} contains individually shell-escaped paths (e.g., 'src/file.ts' 'src/other.ts'), safe for direct use as shell arguments.
In review commands, {{ ctx.CHANGED_FILES }} contains plain paths (for human-readable prompts). When {{ vars.* }} values are substituted into review commands, they are automatically shell-escaped with single quotes. This means you should not manually quote {{ vars.prompt }} in your command:
# Correct — vars are auto-escaped
command: claude -p {{ vars.prompt }}
# Wrong — double-quoting breaks the command
command: claude -p '{{ vars.prompt }}'
Values for defaults.changed and the --changed CLI option:
| Value | Description |
|---|---|
untracked | New files not yet tracked by git |
unstaged | Modified but not staged |
staged | Staged for commit |
branch:<name> | Changes since branching from <name> |
sha:<sha> | Changes since a specific commit |
Multiple sources are comma-separated. Changes from all specified sources are combined and deduplicated.
Default (when not specified): unstaged,staged.
Use regex named capture groups to run commands per workspace:
checks:
- name: typecheck
match: '^packages/(?<workspace>[^/]+)/.*\.(m|c)?tsx?$'
group: typecheck
command: pnpm --filter {{ match.workspace }} typecheck
If packages/app/src/index.ts and packages/lib/src/utils.ts are both changed, the check runs once per workspace: typecheck[app] and typecheck[lib].
Use glob patterns to exclude files from matching:
reviews:
- name: review
match: '.*'
exclude: '**/*.{test,spec}.{ts,tsx,js,jsx}'
command: claude -p {{ vars.prompt }}
Add a completion check to your CLAUDE.md (or equivalent):
## Completion Criteria
Before completing the task, run and fix any errors:
```sh
pnpm gatecheck check
```
Add a Stop hook to .claude/settings.json — when any check fails, Claude is blocked from stopping:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "pnpm gatecheck check --format claude-code-hooks"
}
]
}
]
}
}
Add an agentStop hook to .github/hooks/gatecheck.json:
{
"version": 1,
"hooks": {
"agentStop": [
{
"type": "command",
"bash": "pnpm gatecheck check --format copilot-cli-hooks"
}
]
}
}
Both formats output nothing on success (agent stops normally) and { "decision": "block", "reason": "..." } on failure (agent continues fixing).
| Format | Use case |
|---|---|
text | Human-readable terminal output (default) |
json | Machine-readable structured output for CI/CD |
claude-code-hooks | Claude Code Stop hook integration |
copilot-cli-hooks | Copilot CLI agentStop hook integration |
MIT
FAQs
Quality gate for git changes — run checks and AI reviews against changed files
We found that gatecheck demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.