Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .agents/skills/usethis-prek-hook-bespoke-create/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: usethis-prek-hook-bespoke-create
description: Write bespoke prek hooks as Python scripts for custom project-specific checks
compatibility: usethis, prek, git, Python
license: MIT
metadata:
version: "1.0"
---

# Bespoke Prek Hooks

Use this skill when creating custom, project-specific prek hooks that aren't
provided by an existing third-party tool.

## Procedure

1. Create a `.py` script in the `hooks/` directory at the project root.
2. Write the hook logic in pure Python — no subprocessing.
3. Wire the hook into `.pre-commit-config.yaml` using `uv run`.
4. Assign a priority following the `usethis-prek-add-hook` skill's guidance.

## Writing the hook script

### Location and naming

Place scripts in the `hooks/` directory at the project root. Use kebab-case for
the filename with a `.py` extension (e.g., `hooks/check-skills-documented.py`).

### Script structure

Scripts should:

- Use `sys.exit(0)` for success and `sys.exit(1)` for failure.
- Print error details to stderr.
- Print a success summary to stdout.
- Accept `--fix` as an optional flag when the hook can auto-correct issues. When
`--fix` is passed, the hook should fix problems in-place and exit 0 if all
issues were resolved.
- Use `argparse` for argument parsing when flags are needed.

### Pure Python only

Hooks must use only the Python standard library. Do not subprocess external
tools — if a check requires an external tool, it should be a separate
third-party hook instead of a bespoke one.

### Performance

Hooks run on every commit, so they must be fast:

- Read only the files you need.
- Use `pathlib.Path.glob()` or `os.scandir()` instead of walking entire trees.
- Avoid importing heavy third-party libraries.
- Prefer string operations over regular expressions when a simple check suffices.

## Wiring into `.pre-commit-config.yaml`

Register the hook as a local system hook with `uv run`:

```yaml
- repo: local
hooks:
- id: <hook-id>
name: <hook-id>
entry: uv run --frozen --offline hooks/<hook-id>.py
language: system
always_run: true
pass_filenames: false
priority: 0
```

Key points:

- `entry` uses `uv run --frozen --offline` so the hook runs without network
access and with locked dependencies.
- `id` and `name` should match the script filename (without `.py`).
- Set `pass_filenames: false` since bespoke hooks typically determine their own
file targets.
- Follow the `usethis-prek-add-hook` skill for priority assignment and placement
within the file.