Claude-skill-registry hk-setup
Set up hk (git hook manager) with pre-commit hooks for any project. Detects project type (Python, JS/TS, Go, Rust, etc.) and configures appropriate linters/formatters. Use when user wants to add pre-commit hooks, set up hk, or configure linting for a project.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/hk-setup" ~/.claude/skills/majiayu000-claude-skill-registry-hk-setup && rm -rf "$T"
skills/data/hk-setup/SKILL.mdhk Setup
Configure hk git hooks with appropriate linters for any project.
When to Use This Skill
- User asks to set up pre-commit hooks
- User wants to add linting/formatting to a project
- User mentions hk, git hooks, or pre-commit
- User wants to enforce code quality on commits
Prerequisites
# Install hk (one of these) brew install hk mise use -g hk
Workflow
1. Detect Project Type
Look for these files to identify the project:
| File | Project Type | Recommended Linters |
|---|---|---|
, | Python | ruff, ruff_format |
, | JavaScript/TypeScript | biome (or eslint + prettier) |
, | Go | go_fmt, golangci_lint |
, | Rust | rustfmt, cargo_clippy |
, | Swift | swiftlint, swiftformat |
, | Shell | shellcheck, shfmt |
| Docker | hadolint |
| Pkl configs | pkl |
2. Check Available Tools
hk builtins # List all built-in linters
See references/builtins.md for full catalog. Key builtins:
| Language | Recommended Builtins |
|---|---|
| Python | , |
| JS/TS | or + |
| Go | , , |
| Rust | , |
| Shell | , |
3. Generate hk.pkl
Create
hk.pkl in project root. Always use version-pinned imports:
amends "package://github.com/jdx/hk/releases/download/v1.28.0/hk@1.28.0#/Config.pkl" import "package://github.com/jdx/hk/releases/download/v1.28.0/hk@1.28.0#/Builtins.pkl" local linters = new Mapping<String, Step> { // Add linters here based on project type } hooks { ["pre-commit"] { fix = true stash = "git" steps = linters } ["pre-push"] { steps = linters } ["fix"] { fix = true steps = linters } ["check"] { steps = linters } }
4. Install & Test
hk validate # Check config syntax hk install # Install git hooks hk check --all # Run all checks hk fix --all # Auto-fix issues
Project Templates
Python (ruff + ty)
local linters = new Mapping<String, Step> { ["ruff"] = Builtins.ruff ["ruff-format"] = Builtins.ruff_format ["ty"] { glob = "**/*.py" check = "ty check" } ["pkl"] = Builtins.pkl }
JavaScript/TypeScript (eslint + prettier)
local linters = new Mapping<String, Step> { ["eslint"] = Builtins.eslint ["prettier"] = Builtins.prettier ["pkl"] = Builtins.pkl }
JavaScript/TypeScript (biome)
Biome is a fast all-in-one linter+formatter. Use instead of eslint+prettier for new projects:
local linters = new Mapping<String, Step> { ["biome"] = Builtins.biome ["pkl"] = Builtins.pkl }
JavaScript/TypeScript (oxc)
Oxlint + oxfmt from the oxc project. Oxfmt is alpha but very fast:
local linters = new Mapping<String, Step> { ["oxlint"] = Builtins.ox_lint ["oxfmt"] { glob = "**/*.{ts,tsx,js,jsx,json,md}" check = "oxfmt --check {{files}}" fix = "oxfmt {{files}}" } ["pkl"] = Builtins.pkl }
Install:
npm install -g oxfmt
Go
local linters = new Mapping<String, Step> { ["gofmt"] = Builtins.gofmt ["goimports"] = Builtins.goimports ["golangci-lint"] = Builtins.golangci_lint ["pkl"] = Builtins.pkl }
Rust
local linters = new Mapping<String, Step> { ["rustfmt"] = Builtins.rustfmt ["clippy"] = Builtins.clippy ["pkl"] = Builtins.pkl }
Swift (swiftlint + swiftformat)
local linters = new Mapping<String, Step> { ["swiftlint"] = Builtins.swiftlint ["swiftformat"] { glob = "**/*.swift" check = "swiftformat --lint {{files}}" fix = "swiftformat {{files}}" } ["pkl"] = Builtins.pkl }
Shell
local linters = new Mapping<String, Step> { ["shellcheck"] = Builtins.shellcheck ["shfmt"] = Builtins.shfmt ["pkl"] = Builtins.pkl }
Docker
local linters = new Mapping<String, Step> { ["hadolint"] = Builtins.hadolint ["pkl"] = Builtins.pkl }
Universal Linters
These work for any project. Add them directly to your linters mapping:
local linters = new Mapping<String, Step> { // Language-specific linters... ["ruff"] = Builtins.ruff // Universal linters (add to any project) ["typos"] = Builtins.typos // Spell checker ["trailing-whitespace"] = Builtins.trailing_whitespace // Remove trailing spaces ["newlines"] = Builtins.newlines // Ensure final newline }
Note: Pkl Mappings don't support
+ concatenation. Define all linters in a single mapping.
Other useful universal builtins:
- Prevent committing merge conflict markerscheck_merge_conflict
- Prevent committing private keysdetect_private_key
- Warn about large filescheck_added_large_files
Custom Steps
For tools without builtins, define custom steps:
["my-linter"] { glob = "**/*.ext" // Files to match check = "my-tool check {{files}}" // Check command fix = "my-tool fix {{files}}" // Optional fix command }
Step Options
| Option | Description |
|---|---|
| File patterns to match |
| Command to run for checking |
| Command to run for fixing (optional) |
| Run in isolation (no parallel) |
| Process files in batches |
| Allow file modifications during check |
Environment Variables
If tools are in a venv or non-standard location:
env { ["PATH"] = ".venv/bin:\(read("env:PATH"))" }
Or better: install tools globally via brew/mise.
Troubleshooting
Tool not found
# Check if tool is in PATH which ruff # Install globally brew install ruff # or mise use -g ruff
Config validation failed
hk validate # Check Pkl syntax errors in output
Hooks not running
# Reinstall hooks hk install # Check hook files exist ls -la .git/hooks/pre-commit
Examples
User asks to add pre-commit hooks
- Check project type (look for pyproject.toml, package.json, etc.)
- Check what tools are available (
,hk builtins
)which ruff - Create appropriate hk.pkl
- Run
hk validate && hk install - Test with
hk check --all - Fix issues with
hk fix --all
User has existing linter config
- Read existing config (ruff.toml, .eslintrc, etc.)
- Use matching hk builtins
- Add any custom tools as custom steps