Skip to content
Open
Show file tree
Hide file tree
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
102 changes: 102 additions & 0 deletions .agents/docs/hk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# hk

Git hooks and code quality checks for the yadm dotfiles repo.

## Configuration

**Main config**: `~/hk.pkl` (requires hk v1.44.1+ for yadm bare-repo support)

hk is installed globally via `hk install --global`, using Git 2.54+ config-based hooks. It runs as a
silent no-op in repos without an `hk.pkl`.

### yadm-specific settings

Two settings in `hk.pkl` are needed to make hk work cleanly in the yadm context
(`GIT_WORK_TREE=$HOME`):

- **`env { ["HK_STASH_UNTRACKED"] = "false" }`** — prevents hk from running
`git status --untracked-files=all` which would scan the entire home directory (~45s).
See [jdx/hk#860](https://github.com/jdx/hk/discussions/860).
- **`stash = "none"`** on pre-commit and fix hooks — avoids a recursive hook invocation.
`hk install --global` registers a hook on every git operation, so the internal `git stash push`
hk runs during pre-commit would re-trigger hk and cause an infinite loop. Downside: if you have
unstaged changes, auto-fixers may modify them alongside staged content.

## Running Hooks Manually

```bash
# Run all checks (all files)
yadm enter hk check --all

# Run all fixers (all files)
yadm enter hk fix --all

# Via mise tasks
mise run dotfiles:lint
mise run dotfiles:fix

# Dry-run: see what would run and why
yadm enter hk check --plan
```

## Configured Steps

| Step | Purpose |
| ------------------------------- | ---------------------------------------------- |
| trailing-whitespace | Remove trailing whitespace |
| newlines | Ensure files end with a newline |
| check-merge-conflict | Detect leftover conflict markers |
| typos | Spell checking for source code |
| gitleaks | Secret detection |
| yamllint | YAML linting |
| editorconfig-checker | EditorConfig conformance |
| shellcheck | Shell script linting (bash/sh only) |
| shfmt | Shell script formatting |
| zsh-syntax-check | Zsh syntax validation (`zsh -n`) |
| stylua | Lua formatting |
| luacheck | Lua linting |
| prettier | JSON/Markdown/YAML formatting |
| standardrb | Ruby linting/formatting |
| check-json | JSON parse validation |
| check-executables-have-shebangs | Executables must have shebangs |
| check-added-large-files | Block files over 500KB |
| no-yadm-alt-symlinks | Reject staged yadm alt symlinks |
| mise-fmt | Mise config formatting |
| renovate-config-validator | Renovate config validation |
| commitlint | Conventional commit messages (commit-msg hook) |

## CI Integration

The `hk-check` job in `.github/workflows/ci.yml` runs `hk check --all` via `jdx/mise-action`,
which installs all tools from the Linux mise config. Steps skipped in CI:

- `standardrb` — requires Ruby gems not in CI
- `renovate-config-validator` — requires npm:renovate
- `no-yadm-alt-symlinks` — requires yadm

## Bypassing Hooks

```bash
HK=0 yadm commit -m "wip" # skip all hk hooks
HK_SKIP_STEPS=typos yadm commit -m "" # skip a specific step
```

## Debugging

```bash
yadm enter hk check -v # verbose output
yadm enter hk check --plan # show what would run
yadm enter hk check --step stylua # single step
```

## Adding New Steps

Edit `~/hk.pkl`. Add to the `fast_steps` mapping — it is shared across `pre-commit`, `fix`, and
`check` hooks. Run `yadm enter hk validate` to verify syntax.

## Version Management

hk version is managed by mise (`hk = "latest"` in `~/.config/mise/conf.d/global.toml`).
When upgrading, bump the `amends` and `import` URLs in `~/hk.pkl` to match the new version.

Check current version: `hk --version`
72 changes: 0 additions & 72 deletions .agents/docs/pre-commit.md

This file was deleted.

21 changes: 20 additions & 1 deletion .config/mise/conf.d/global.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,29 @@ dua = "latest"

# ── Developer workflow ────────────────────────────────────────────────
# Git hook manager
pre-commit = "latest"
hk = "latest"
# Pkl configuration language (required by hk)
pkl = "latest"
# Utilities for working with patches (filterdiff, etc.)
"github:twaugh/patchutils" = "latest"

# ── Linting & formatting ──────────────────────────────────────────────
# Secrets scanner for git repos
"aqua:gitleaks/gitleaks" = "latest"
# Shell script linter
shellcheck = "latest"
# Shell script formatter
shfmt = "latest"
# Lua code formatter
stylua = "latest"
# Lua linter: on macOS via Homebrew; on Linux declared in linux.toml
# Spell checker for source code
typos = "latest"
# EditorConfig file format checker
"aqua:editorconfig-checker/editorconfig-checker" = "latest"
# JSON/Markdown/YAML formatter
prettier = "latest"

# ── AI tooling ────────────────────────────────────────────────────────
# Lazy-loading MCP server proxy for AI tools
"npm:lazy-mcp" = "latest"
9 changes: 3 additions & 6 deletions .config/mise/conf.d/linux.toml##os.Linux
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,9 @@ btop = "latest"
"aqua:sharkdp/hyperfine" = "latest"

# ── Linting & formatting ──────────────────────────────────────────────
# Secrets scanner for git repos
"aqua:gitleaks/gitleaks" = "latest"
# Shell script linter
shellcheck = "latest"
# Lua code formatter
stylua = "latest"
# (most linting tools declared in global.toml; luacheck only available via mise on Linux)
# Lua linter
luacheck = "latest"

# ── npm ───────────────────────────────────────────────────────────────
# Auto-generates table of contents in Markdown
Expand Down
2 changes: 1 addition & 1 deletion .config/mise/conf.d/personal.toml##class.Personal
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
cargo-binstall = "latest"
# ── Automation ────────────────────────────────────────────────────────
# Automated dependency update bot
"npm:renovate" = "43.138.0"
"npm:renovate" = "43.138.1"
8 changes: 8 additions & 0 deletions .config/mise/conf.d/tasks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ run = "~/.config/yadm/scripts/update.zsh"
description = "Run dotfile health checks"
run = "~/.config/yadm/scripts/run-checks.zsh"

[tasks."dotfiles:lint"]
description = "Run all linters on dotfiles"
run = "yadm enter hk check --all"

[tasks."dotfiles:fix"]
description = "Run all fixers on dotfiles"
run = "yadm enter hk fix --all"

# ── Git ───────────────────────────────────────────────────────────────

[tasks."git:push"]
Expand Down
2 changes: 1 addition & 1 deletion .config/opencode/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ the task needs them.
- [Mise Tasks](~/.agents/docs/mise-tasks.md) - Task automation for dotfiles
- [Neovim](~/.agents/docs/neovim.md) - Configuration structure and plugin management
- [Mise](~/.agents/docs/mise.md) - Runtime versions and CLI tools
- [Pre-commit](~/.agents/docs/pre-commit.md) - Hooks and code quality checks
- [hk](~/.agents/docs/hk.md) - Git hooks and code quality checks
- [Renovate Bot](~/.agents/docs/renovate.md) - Dependency update configuration and troubleshooting
- [Writing Style](~/.agents/docs/writing-style.md) - Pedro's tone, formatting, and MR conventions
- [GDK Dotfiles](~/.agents/docs/gdk-dotfiles.md) - Personal files synced into `$GDK_ROOT/gitlab`
Expand Down
6 changes: 6 additions & 0 deletions .config/yadm/scripts/quiet-on-success.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
# Runs a command silently; only shows output on failure
output=$("$@" 2>&1)
code=$?
[ $code -ne 0 ] && printf '%s\n' "$output"
exit $code
48 changes: 13 additions & 35 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI

on:
"on":
pull_request:
push:
branches:
Expand All @@ -14,34 +14,25 @@ concurrency:
cancel-in-progress: true

jobs:
# Job 1: Pre-commit hooks
pre-commit:
name: Pre-commit hooks
# Job 1: hk check
hk-check:
name: hk check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: "3.14"

# Cache pre-commit environments
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
- uses: jdx/mise-action@v2

# Install zsh for syntax checking
- name: Install zsh
run: sudo apt-get update && sudo apt-get install -y zsh

# Run pre-commit on all files
# Skip hooks that require tools not installed in CI (mise, ruby)
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
# Run hk check on all files
# Skip steps that require tools not available in CI (ruby, renovate, yadm)
- name: Run hk check
run: hk check --all
env:
SKIP: standardrb,renovate-config-validator
with:
extra_args: --all-files
HK_SKIP_STEPS: standardrb,renovate-config-validator,no-yadm-alt-symlinks

# Job 2: Neovim config validation
neovim-validate:
Expand Down Expand Up @@ -75,28 +66,15 @@ jobs:

echo "Neovim config validation passed"

# Job 3: Luacheck for Neovim Lua files
luacheck:
name: Luacheck (Neovim Lua)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Run luacheck
uses: nebularg/actions-luacheck@d4137dd840545b28521ed21931e06913d93c0bc1 # v1
with:
files: ".config/nvim"
args: "--config .luacheckrc --formatter plain"

# Job 4: Bootstrap script validation
# Job 3: Bootstrap script validation
bootstrap-validate:
name: Bootstrap scripts syntax
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

# Validate bash syntax for all bootstrap scripts
# Note: shellcheck runs in pre-commit job
# Note: shellcheck runs in hk-check job
- name: Bash syntax check
run: |
echo "Checking bash syntax for bootstrap scripts..."
Expand Down Expand Up @@ -124,7 +102,7 @@ jobs:

exit $EXIT_CODE

# Job 5: Secret scanning
# Job 4: Secret scanning
secret-scanning:
name: Secret scanning (Gitleaks)
runs-on: ubuntu-latest
Expand Down
Loading
Loading