Back to list
kennyg

hk-setup

by kennyg

A collection of skills, commands, and prompts for AI agents - installable via tome learn

0🍴 0📅 Dec 29, 2025

SKILL.md


name: hk-setup description: 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. license: MIT compatibility: Requires hk to be installed (brew install hk or mise use hk). Works with Claude Code and similar agents. metadata: author: kenny version: "1.1"

hk 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:

FileProject TypeRecommended Linters
pyproject.toml, *.pyPythonruff, ruff_format
package.json, *.tsJavaScript/TypeScriptbiome (or eslint + prettier)
go.mod, *.goGogo_fmt, golangci_lint
Cargo.toml, *.rsRustrustfmt, cargo_clippy
Package.swift, *.swiftSwiftswiftlint, swiftformat
*.sh, *.bashShellshellcheck, shfmt
DockerfileDockerhadolint
*.pklPkl configspkl

2. Check Available Tools

hk builtins  # List all built-in linters

See references/builtins.md for full catalog. Key builtins:

LanguageRecommended Builtins
Pythonruff, ruff_format
JS/TSbiome or eslint + prettier
Gogo_fmt, go_imports, golangci_lint
Rustrustfmt, cargo_clippy
Shellshellcheck, shfmt

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:

  • check_merge_conflict - Prevent committing merge conflict markers
  • detect_private_key - Prevent committing private keys
  • check_added_large_files - Warn about 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

OptionDescription
globFile patterns to match
checkCommand to run for checking
fixCommand to run for fixing (optional)
exclusiveRun in isolation (no parallel)
batchProcess files in batches
stompAllow 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

  1. Check project type (look for pyproject.toml, package.json, etc.)
  2. Check what tools are available (hk builtins, which ruff)
  3. Create appropriate hk.pkl
  4. Run hk validate && hk install
  5. Test with hk check --all
  6. Fix issues with hk fix --all

User has existing linter config

  1. Read existing config (ruff.toml, .eslintrc, etc.)
  2. Use matching hk builtins
  3. Add any custom tools as custom steps

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon