一键导入
py-git-hooks
Set up git pre-commit hooks to run ruff, mypy, and basedpyright before commits. Use when configuring automated quality checks in git workflow.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Set up git pre-commit hooks to run ruff, mypy, and basedpyright before commits. Use when configuring automated quality checks in git workflow.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Detect and remove dead code, duplicate code, and unused imports. Consolidate similar code patterns into parametrized functions.
Orchestrate comprehensive Python refactoring - coordinates security, complexity, testing, code health, and modernization skills to systematically improve code quality.
| name | py-git-hooks |
| description | Set up git pre-commit hooks to run ruff, mypy, and basedpyright before commits. Use when configuring automated quality checks in git workflow. |
| status | stable |
Configure git pre-commit hooks using the pre-commit framework to enforce code quality before commits.
Add to [dependency-groups] dev: "pre-commit", "ruff", "mypy", "basedpyright"
Permissions: Run py-quality-setup first to configure .claude/settings.local.json with all needed tool permissions.
# Check if manual hooks exist
ls -la .git/hooks/pre-commit 2>/dev/null
# If exists and not a pre-commit managed hook, migrate it (see Migration section)
Create .pre-commit-config.yaml:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies: [] # Add type stubs as needed
- repo: local
hooks:
- id: basedpyright
name: basedpyright
entry: basedpyright
language: system
types: [python]
pass_filenames: true
# Install pre-commit to project venv
uv pip install pre-commit
# Install git hooks
pre-commit install
# Verify installation
ls -la .git/hooks/pre-commit
# Run on all files (initial validation)
pre-commit run --all-files
# Or test on staged files only
git add some_file.py
pre-commit run
Strongly recommended: Configure a Claude Code Stop hook that runs the full lint suite (ruff, mypy, basedpyright) on modified Python files before Claude returns control to the user. If any linter reports errors, Claude is blocked from stopping and must fix them first.
This replaces the older PostToolUse approach (which ran ruff after every individual edit, generating noise on intermediate states).
Install the lint gate script (symlink so updates propagate automatically):
mkdir -p ~/.claude/hooks
ln -sf ~/.claude/skills/py-git-hooks/lint-gate.py ~/.claude/hooks/lint-gate.py
Configure the Stop hook in ~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "python3 ~/.claude/hooks/lint-gate.py"
}
]
}
]
}
}
How it works:
.py files via git diff (staged, unstaged, and untracked)ruff check --fix and ruff format to silently fix trivial issues (import sorting, whitespace, style)ruff check, mypy, and basedpyright to find remaining unfixable errors{"decision": "block", "reason": "..."} — Claude sees the lint output and continues working to fix the issues{"decision": "stop"} — Claude returns to the userstop_hook_active is true in the input (meaning Claude is already retrying after a previous block), the hook allows the stop to prevent infinite loopsBenefits over PostToolUse hooks:
If the project has an existing manual .git/hooks/pre-commit script:
cp .git/hooks/pre-commit .git/hooks/pre-commit.backup
Read the existing hook to understand what checks it runs:
For each check in the manual hook, add equivalent to .pre-commit-config.yaml:
| Manual Hook Check | Pre-commit Equivalent |
|---|---|
ruff check | ruff-pre-commit repo |
black | ruff-format (ruff replaces black) |
isort | ruff with isort rules (I) |
flake8 | ruff (replaces flake8) |
mypy | mirrors-mypy repo |
basedpyright | local hook |
| Custom script | local hook with entry: ./script.sh |
pre-commit install # This overwrites .git/hooks/pre-commit
pre-commit run --all-files # Verify all checks pass
# Test that hooks work
git add .
git commit -m "test" --dry-run
# If successful, remove backup
rm .git/hooks/pre-commit.backup
Auto-fixable issues (handled by both pre-commit and the Stop hook lint gate):
Blocking issues (require Claude or manual intervention):
Bypass (use sparingly):
git commit --no-verify
For large codebases:
.mypy_cache)For monorepos:
files: pattern in hook config to limit scope- id: mypy
files: ^src/mypackage/
Hook not running:
pre-commit install --force # Reinstall hooks
Tools not found:
# Ensure tools installed in venv
uv pip install ruff mypy basedpyright
Hook too slow:
pre-commit run --verbosestages: [manual] for slow hooks, run explicitlyUpdate hook versions:
pre-commit autoupdate
If the project was previously set up with PostToolUse hooks for ruff (the older approach), migrate to the Stop hook lint gate:
grep -A 10 '"PostToolUse"' ~/.claude/settings.json
Edit ~/.claude/settings.json and remove any PostToolUse entries that match Edit|Write|MultiEdit and run ruff check. Keep any non-ruff PostToolUse hooks.
Follow Step 5 in the Setup Workflow above to install lint-gate.py and configure the Stop hook.
Make a Python edit that introduces a ruff error. Confirm that:
Claude should learn from lint gate feedback to avoid repeating the same mistakes.
After being blocked by the lint gate: note the error pattern. If the same linter rule triggers repeatedly across edits, record it in auto-memory under the lint-patterns topic. Format:
- **[rule-code]** (tool): What triggers it and how to avoid it.
Before editing Python files: consult auto-memory for known lint pitfalls in this project. Apply those lessons proactively so the lint gate passes on the first try.
This creates a cross-session feedback loop: each lint gate block teaches Claude to write cleaner code next time.
.pre-commit-config.yaml exists with ruff, mypy, basedpyright hookspre-commit install has been runpre-commit run --all-files passes~/.claude/hooks/lint-gate.py installed and executable~/.claude/settings.json--no-verify works for emergencies (git pre-commit only)Example: New project setup
1. Create venv: uv venv && source .venv/bin/activate
2. Install tools: uv pip install pre-commit ruff mypy basedpyright
3. Create .pre-commit-config.yaml with ruff, mypy, basedpyright
4. Install hooks: pre-commit install
5. Test: pre-commit run --all-files
6. Install lint-gate.py and configure Stop hook in settings.json
Example: Migrate from PostToolUse to Stop hook
1. Remove PostToolUse ruff hooks from ~/.claude/settings.json
2. Symlink lint-gate.py to ~/.claude/hooks/
3. Add Stop hook to ~/.claude/settings.json
4. Verify: make an edit with a ruff error, confirm block-on-stop behavior
Example: Migrate existing manual hook
1. Backup: cp .git/hooks/pre-commit .git/hooks/pre-commit.backup
2. Read backup to identify checks (ruff, mypy, custom scripts)
3. Create .pre-commit-config.yaml mapping each check
4. Install: pre-commit install (overwrites manual hook)
5. Verify: pre-commit run --all-files
6. Clean up: rm .git/hooks/pre-commit.backup
Example: Add to existing pre-commit config
1. Edit .pre-commit-config.yaml
2. Add basedpyright local hook
3. Run: pre-commit run --all-files
4. Commit updated config