Built-in linters
Builtins are reusable Pkl step definitions for linters, formatters, and hk’s own utilities. They supply file patterns, check and fix commands, and optimizations such as diff output.
Install the tools separately. A builtin invokes executables from your environment; it does not install them. Use your project’s package manager or mise; most entries in the catalogue list the mise use command that installs their tool, or the tool’s project page when mise can’t install it. Builtins that run only hk util commands have no Install line because they need no separate tool, except python-check-ast, which needs Python on PATH.
Use a builtin
amends "package://github.com/jdx/hk/releases/download/v2.10.0/hk@2.10.0#/Config.pkl"
import "package://github.com/jdx/hk/releases/download/v2.10.0/hk@2.10.0#/Builtins.pkl"
hooks {
["check"] {
steps {
["oxfmt"] = Builtins.oxfmt
["eslint"] = Builtins.eslint
}
}
}Builtins.oxfmt is the Pkl property name. The step name, "oxfmt", is your label for selecting the step in commands such as hk check --step oxfmt.
Keep the schema and Builtins imports on the same version. The catalogue below describes the version of the source used to build this website; an older pinned package may differ.
Customize a builtin
Amend a builtin to keep its defaults while changing specific properties:
["oxfmt"] = (Builtins.oxfmt) {
glob = List("*.js", "*.ts", "*.json")
exclude = List("**/generated/**")
batch = false
}A property assignment replaces that property. If you override glob or exclude, include every pattern you want to retain.
Use dependencies for ordering and profiles for optional checks:
["oxfmt"] = (Builtins.oxfmt) {
depends = "eslint"
}
["mypy"] = (Builtins.mypy) {
profiles = List("types")
}Run the type checker with hk check --profile types. See configuration for groups, workspaces, and command templates.
Utilities included with hk
Steps such as Builtins.trailing_whitespace, Builtins.newlines, and Builtins.check_merge_conflict invoke hk util commands. These need no separate linter executable.
Tool availability
Builtins configure how hk invokes a tool; they do not install that tool. The executable used by the builtin must be on PATH, or the step must use a prefix that resolves it.
With HK_MISE=1, hk resolves the mise environment for the step's directory, so tools declared in a subproject's mise.toml are available without a prefix. For a Node tool installed locally by aube, prefix its builtin with aube exec:
["eslint"] = (Builtins.eslint) {
prefix = List("aube", "exec")
}Use an argv list for builtins backed by structured commands. A string prefix such as "aube exec" or "mise x --" cannot be combined with those commands.
Available builtins
The following catalogue is generated from the builtin definitions. Each entry includes the exact Pkl property to use. Refer to the source definitions for additional options and tests.
.NET
dotnet-format
Pkl: Builtins.dotnet_format
Format C# and Visual Basic with the .NET SDK
- Files:
**/*.cs,**/*.vb - Install:
mise use dotnet - Check:
dotnet format --verify-no-changes --include {{files}} - Fix:
dotnet format --include {{files}} - Options:
exclusive = true
AsciiDoc
asciidoctor
Pkl: Builtins.asciidoctor
AsciiDoc syntax validator and processor
- Files:
asciidocfiles - Install:
mise use gem:asciidoctor - Check:
asciidoctor --failure-level=WARNING --out-file=/dev/null {{files}}
Build Systems
buildifier-format
Pkl: Builtins.buildifier_format
Formatter for Bazel BUILD, WORKSPACE, and Starlark files
- Files:
**/BUILD,**/BUILD.bazel,WORKSPACE,WORKSPACE.bazel,MODULE.bazel,**/*.bzl,**/*.star,**/*.sky - Install:
mise use buildifier - Check:
buildifier -mode=check {{files}} - Check (diff):
hk util format-diff {{files}} -- buildifier '-path={}' - Fix:
buildifier {{files}}
buildifier-lint
Pkl: Builtins.buildifier_lint
Linter for Bazel BUILD, WORKSPACE, and Starlark files
- Files:
**/BUILD,**/BUILD.bazel,WORKSPACE,WORKSPACE.bazel,MODULE.bazel,**/*.bzl,**/*.star,**/*.sky - Install:
mise use buildifier - Check:
buildifier -mode=check -lint=warn {{files}} - Fix:
buildifier -lint=fix {{files}}
CSS
stylelint
Pkl: Builtins.stylelint
CSS linter
- Files:
**/*.css,**/*.scss,**/*.sass,**/*.less - Install:
mise use npm:stylelint - Check:
stylelint {{files}} - Fix:
stylelint --fix {{files}}
Configuration
sort-package-json
Pkl: Builtins.sort_package_json
Sort package.json keys
- Files:
**/package.json - Install:
mise use npm:sort-package-json - Check:
sort-package-json --check {{files}} - Fix:
sort-package-json {{files}}
Data Formats
buf-format
Pkl: Builtins.buf_format
Protocol Buffers formatter
- Files:
**/*.proto - Install:
mise use buf - Check (diff):
buf format {{workspace}} --diff --exit-code - Fix:
buf format {{workspace}} --write - Options:
workspace_indicator = "buf.yaml"
buf-lint
Pkl: Builtins.buf_lint
Protocol Buffers linter
- Files:
**/*.proto - Install:
mise use buf - Check:
buf lint {{workspace}} - Options:
workspace_indicator = "buf.yaml"
dotenv-linter
Pkl: Builtins.dotenv_linter
.env file linter
- Files:
**/.env,**/.env.*,**/*.env - Check:
dotenv-linter check --skip-updates {{files}} - Fix:
dotenv-linter fix --no-backup {{files}}
jq
Pkl: Builtins.jq
JSON processor
Files:
**/*.jsonInstall:
mise use jqCheck (diff):
shfailed=0 broken=0 trap 'rm -f "$out" "$patch" "$new"' EXIT trap 'exit 2' HUP INT TERM out=$(mktemp) && patch=$(mktemp) && new=$(mktemp) || exit 2 n=0 set -- for f in {{ files }}; do n=$((n + 1)) set -- "$@" --rawfile "f$n" "$f" done # Each file's output follows \u001e, which formatted JSON never # contains, and is \u001f if jq cannot parse the file. todo=all if [ "$n" -gt 1 ] && jq -n -j -S --argjson n "$n" "$@" ' range(1; $n + 1) as $i | "\u001e", ($ARGS.named["f\($i)"] | try (fromjson | if type == "string" then tojson else . end, "\n") catch "\u001f") ' > "$new" 2>/dev/null; then todo=$(jq -n -r --argjson n "$n" --rawfile new "$new" "$@" ' ($new | split("\u001e")) as $new | [range(1; $n + 1) | select($new[.] != $ARGS.named["f\(.)"] or ($new[.] | contains("\u001f") or contains("\ufffd"))) | tostring] | " " + join(" ") + " " ' 2>/dev/null) || todo=all fi i=0 for f in {{ files }}; do i=$((i + 1)) case $todo in all | *" $i "*) ;; *) continue ;; esac if jq -S . "$f" > "$out"; then # hk runs this with `set -e`, so take diff's status through `||`. status=0 diff -u -L "a/$f" -L "b/$f" "$f" "$out" >> "$patch" || status=$? case $status in 0) ;; 1) failed=1 ;; *) broken=1 ;; esac else broken=1 fi done # When a file failed to parse or diff, print no patch: hk then runs the # fixer on every file, and the fixer reports the error. [ "$broken" = 1 ] && exit 1 cat "$patch" || exit 2 exit $failedFix:
shfailed=0 tmp= trap 'rm -f "$tmp"' EXIT trap 'exit 2' HUP INT TERM for f in {{ files }}; do # Write a copy beside the file, with its permissions, then rename it # over the file, so a failed write never truncates the original. A # file that is already formatted is left alone, links and all. tmp=$(mktemp "$f.XXXXXX") && cp -p "$f" "$tmp" && jq -S . "$f" > "$tmp" && { cmp -s "$f" "$tmp" || mv "$tmp" "$f"; } || failed=1 rm -f "$tmp" tmp= done exit $failedOptions:
batch = true
protolint
Pkl: Builtins.protolint
Protocol Buffers linter
Files:
**/*.protoCheck:
protolint lint {{files}}Fix:
sh# Windows: protolint lint -fix {{files}} 2>NUL || protolint lint {{files}} # other platforms: protolint lint -fix {{files}} 2>/dev/null || protolint lint {{files}}
sql-fluff
Pkl: Builtins.sql_fluff
SQL linter and formatter
- Files:
**/*.sql - Install:
mise use pipx:sqlfluff - Check:
sqlfluff lint {{files}} - Fix:
sqlfluff fix {{files}}
taplo
Pkl: Builtins.taplo
TOML linter
- Files:
**/*.toml - Install:
mise use taplo - Check:
taplo lint {{files}}
taplo-format
Pkl: Builtins.taplo_format
TOML formatter
Files:
**/*.tomlInstall:
mise use taploCheck:
taplo format --check --diff {{files}}Check (diff):
sh# Windows: nothing runs # other platforms: set -- for f in {{ files }}; do taplo format --check --colors never "$f" > /dev/null 2>&1 || set -- "$@" "$f" done [ $# -eq 0 ] && exit 0 hk util format-diff "$@" -- taplo format --colors never --stdin-filepath {} -Fix:
taplo format {{files}}
tombi
Pkl: Builtins.tombi
TOML linter
- Files:
**/*.toml - Install:
mise use tombi - Check:
tombi lint --quiet {{files}}
tombi-format
Pkl: Builtins.tombi_format
TOML formatter
- Files:
**/*.toml - Install:
mise use tombi - Check:
tombi format --quiet --check --diff {{files}} - Check (diff):
hk util format-diff {{files}} -- tombi format --quiet --stdin-filename '{}' - - Fix:
tombi format --quiet {{files}}
xmllint
Pkl: Builtins.xmllint
XML validator
- Files:
**/*.xml - Install: project page
- Check:
xmllint --noout {{files}}
yamlfmt
Pkl: Builtins.yamlfmt
YAML formatter
Files:
**/*.yml,**/*.yamlInstall:
mise use yamlfmtCheck:
yamlfmt -lint {{files}}Check (diff):
sh# Windows: nothing runs # other platforms: # If yamlfmt fails, print no patch: hk runs the fixer, which reports it. list=$(yamlfmt -dry -quiet {{ files }}) || exit $? set -- # After a heading, `-dry -quiet` lists the files that would change. # Anything else it lists, such as part of a name containing a newline, # prints no patch, so hk runs the fixer instead of skipping the file. # The here-document expands `$list` once; the names in it are not # expanded again, so `$(...)` in a name is just text. while IFS= read -r f; do case $f in '' | 'The following files would be formatted:') continue ;; esac if [ ! -f "$f" ]; then echo "yamlfmt listed a file that does not exist: $f" >&2 exit 1 fi set -- "$@" "$f" done <<EOF $list EOF [ $# -eq 0 ] && exit 0 hk util format-diff "$@" -- yamlfmt -inFix:
yamlfmt {{files}}
yamllint
Pkl: Builtins.yamllint
YAML linter
- Files:
**/*.yml,**/*.yaml - Install:
mise use yamllint - Check:
yamllint --strict {{files}}
yq
Pkl: Builtins.yq
YAML processor
Files:
**/*.yaml,**/*.ymlInstall:
mise use yqCheck (diff):
shfailed=0 broken=0 trap 'rm -rf "$out" "$patch" "$split"' EXIT trap 'exit 2' HUP INT TERM out=$(mktemp) && patch=$(mktemp) && split=$(mktemp -d) || exit 2 set -- for f in {{ files }}; do case $f in *.[yY][aA][mM][lL] | *.[yY][mM][lL]) set -- "$@" "$f" ;; esac done fast=0 if [ $# -gt 1 ] && YQ_SPLIT="$split/" yq -P -N -s 'strenv(YQ_SPLIT) + (file_index | tostring) + "-" + (document_index | tostring)' "$@" > /dev/null 2>&1; then fast=1 fi i=0 for f in {{ files }}; do new= case $f in *.[yY][aA][mM][lL] | *.[yY][mM][lL]) new="$split/$i-0.yml" i=$((i + 1)) ;; esac if [ "$fast" = 1 ] && [ -n "$new" ] && [ -f "$new" ] && [ ! -e "${new%-0.yml}-1.yml" ] && cmp -s "$f" "$new"; then continue fi if yq -P "$f" > "$out"; then # hk runs this with `set -e`, so take diff's status through `||`. status=0 diff -u -L "a/$f" -L "b/$f" "$f" "$out" >> "$patch" || status=$? case $status in 0) ;; 1) failed=1 ;; *) broken=1 ;; esac else broken=1 fi done # When a file failed to parse or diff, print no patch: hk then runs the # fixer on every file, and the fixer reports the error. [ "$broken" = 1 ] && exit 1 cat "$patch" || exit 2 exit $failedFix:
shfailed=0 for f in {{ files }}; do yq -iP "$f" || failed=1 done exit $failedOptions:
batch = true
EditorConfig
editorconfig-checker
Pkl: Builtins.editorconfig_checker
Validate files against EditorConfig rules
- Files:
textfiles - Install:
mise use editorconfig-checker - Check:
editorconfig-checker {{files}} - Fix:
editorconfig-checker --fix {{files}}
Elixir
mix-compile
Pkl: Builtins.mix_compile
Compile Elixir with Mix
- Files:
**/*.ex - Install:
mise use elixir - Check:
mix compile --warnings-as-errors --strict-errors {{files}} - Options:
exclude = List("deps/**/*")
mix-fmt
Pkl: Builtins.mix_fmt
Format Elixir with Mix
- Files:
**/*.ex,**/*.exs - Install:
mise use elixir - Check:
mix format --check-formatted {{files}} - Fix:
mix format {{files}} - Options:
exclude = List("deps/**/*")
mix-test
Pkl: Builtins.mix_test
Test Elixir with Mix
- Files:
**/*.ex,**/*.exs - Install:
mise use elixir - Check:
mix test --warnings-as-errors {{files}} - Options:
exclude = List("deps/**/*")
Go
err-check
Pkl: Builtins.err_check
Error handling checker
- Files:
**/*.go - Install:
mise use go:github.com/kisielk/errcheck - Check:
errcheck ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
go-fix
Pkl: Builtins.go_fix
Go modernizer (requires Go 1.26+)
- Files:
**/*.go - Install:
mise use go - Check (diff):
go fix -diff ./... - Fix:
go fix ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
go-fmt
Pkl: Builtins.go_fmt
Go formatter
Files:
**/*.goInstall:
mise use goCheck (diff):
shDIFF=$(gofmt -s -d {{files}}) if [ -n "$DIFF" ]; then echo "$DIFF" exit 1 fiCheck (list files):
shFILES=$(gofmt -s -l {{files}}) if [ -n "$FILES" ]; then echo "$FILES" exit 1 fiFix:
gofmt -s -w {{files}}
go-fumpt
Pkl: Builtins.go_fumpt
Strict Go formatter
Files:
**/*.goInstall:
mise use gofumptCheck (diff):
gofumpt -d {{files}}Check (list files):
shFILES=$(gofumpt -l {{files}}) if [ -n "$FILES" ]; then echo "$FILES" exit 1 fiFix:
gofumpt -w {{files}}
go-imports
Pkl: Builtins.go_imports
Go import management
Files:
**/*.goInstall:
mise use go:golang.org/x/tools/cmd/goimportsCheck (diff):
shDIFF=$(goimports -d {{files}}) if [ -n "$DIFF" ]; then echo "$DIFF" exit 1 fiCheck (list files):
shFILES=$(goimports -l {{files}}) if [ -n "$FILES" ]; then echo "$FILES" exit 1 fiFix:
goimports -w {{files}}
go-lines
Pkl: Builtins.go_lines
Long line fixer
- Files:
**/*.go - Install:
mise use golines - Check (diff):
hk util format-diff {{files}} -- golines - Fix:
golines -w {{files}}
go-sec
Pkl: Builtins.go_sec
Security scanner
- Files:
**/*.go - Install:
mise use aqua:securego/gosec - Check:
gosec ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
go-vet
Pkl: Builtins.go_vet
Go code vetting
- Files:
**/*.go - Install:
mise use go - Check:
go vet ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
go-vuln-check
Pkl: Builtins.go_vuln_check
Vulnerability scanner
- Files:
**/*.go - Install:
mise use go:golang.org/x/vuln/cmd/govulncheck - Check:
govulncheck ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
golangci-lint
Pkl: Builtins.golangci_lint
Go meta-linter
- Files:
**/*.go - Install:
mise use golangci-lint - Check:
golangci-lint run --fix=false ./... - Fix:
golangci-lint run --fix ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
golangci-lint-fmt
Pkl: Builtins.golangci_lint_fmt
Go formatter (part of golangci-lint)
- Files:
**/*.go - Install:
mise use golangci-lint - Check (diff):
golangci-lint fmt --diff {{files}} - Fix:
golangci-lint fmt {{files}}
gomod-tidy
Pkl: Builtins.gomod_tidy
Go module maintenance
- Files:
**/*.go,**/go.mod,**/go.sum - Install:
mise use go - Check (diff):
go mod tidy -diff - Fix:
go mod tidy - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}",stage = List("go.mod", "go.sum")
revive
Pkl: Builtins.revive
Fast Go linter
- Files:
**/*.go - Install:
mise use revive - Check:
revive -set_exit_status ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
staticcheck
Pkl: Builtins.staticcheck
Go static analysis
- Files:
**/*.go - Install:
mise use staticcheck - Check:
staticcheck ./... - Options:
workspace_indicator = "go.mod",dir = "{{workspace}}"
Infrastructure
actionlint
Pkl: Builtins.actionlint
GitHub Actions workflow linter
- Files:
.github/workflows/*.yml,.github/workflows/*.yaml - Install:
mise use actionlint - Check:
actionlint {{files}} - Options:
batch = true
ansible-lint
Pkl: Builtins.ansible_lint
Ansible playbook, role and collection linter
Files:
**/*.yml,**/*.yamlInstall:
mise use pipx:ansible-lintCheck:
ansible-lint {{files}}Fix:
sh# Windows: nothing runs # other platforms: ansible-lint --fix {{files}} || [ $? -eq 8 ]
dclint
Pkl: Builtins.dclint
Docker Compose linter
- Files:
**/compose*.yml,**/compose*.yaml,**/docker-compose*.yml,**/docker-compose*.yaml - Install:
mise use npm:dclint - Check:
dclint {{files}} - Fix:
dclint --fix {{files}} - Options:
batch = true
droast
Pkl: Builtins.droast
Dockerfile linter for security, layer hygiene, and best-practice violations
- Files:
**/Dockerfile,**/Dockerfile.*,**/*.Dockerfile,**/*.dockerfile,**/Containerfile,**/Containerfile.* - Install:
mise use github:immanuwell/dockerfile-roast - Check:
droast {{files}} - Fix:
droast --fix {{files}}
ghalint-action
Pkl: Builtins.ghalint_action
GitHub Actions action linter
- Files:
**/action.*that areyamlfiles - Install:
mise use ghalint - Check:
ghalint run-action {{files}}
ghalint-workflow
Pkl: Builtins.ghalint_workflow
GitHub Actions workflow linter
- Files:
.github/workflows/*that areyamlfiles - Install:
mise use ghalint - Check:
ghalint run
hadolint
Pkl: Builtins.hadolint
Dockerfile linter
- Files:
**/Dockerfile* - Install:
mise use hadolint - Check:
hadolint {{files}}
hclfmt
Pkl: Builtins.hclfmt
Hashicorp's hclfmt
- Files:
**/*.hcl - Install:
mise use go:github.com/hashicorp/hcl/v2/cmd/hclfmt - Fix:
hclfmt -w {{files}}
jactionlint
Pkl: Builtins.jactionlint
GitHub Actions workflow linter (jdx/jactionlint, a maintained actionlint fork)
- Files:
.github/workflows/*.y*ml,.github/actions/**/action.y*ml,.github/dependabot.y*ml - Install:
mise use jactionlint - Check:
jactionlint --format gcc {{files}} - Check (diff):
hk util sarif-diff -- jactionlint --format sarif {{files}} - Fix:
jactionlint --fix {{files}} - Options:
batch = true
kube-linter
Pkl: Builtins.kube_linter
Check Kubernetes manifests for security and reliability issues
- Files:
**/k8s/**/*.yaml,**/k8s/**/*.yml,**/kubernetes/**/*.yaml,**/kubernetes/**/*.yml,**/manifests/**/*.yaml,**/manifests/**/*.yml,**/deploy/**/*.yaml,**/deploy/**/*.yml,**/deployments/**/*.yaml,**/deployments/**/*.yml - Install:
mise use kube-linter - Check:
kube-linter lint --fail-if-no-objects-found {{files}} - Options:
exclude = List("**/templates/**", "**/values.yaml", "**/values.yml", "**/values-*.yaml", "**/values-*.yml", "**/kustomization.yaml", "**/kustomization.yml")
kubeconform
Pkl: Builtins.kubeconform
Kubernetes manifest validator
- Files:
**/k8s/**/*.yaml,**/k8s/**/*.yml,**/kubernetes/**/*.yaml,**/kubernetes/**/*.yml,**/manifests/**/*.yaml,**/manifests/**/*.yml,**/deploy/**/*.yaml,**/deploy/**/*.yml,**/deployments/**/*.yaml,**/deployments/**/*.yml - Install:
mise use kubeconform - Check:
kubeconform -summary -strict -ignore-missing-schemas {{files}} - Options:
exclude = List("**/templates/**", "**/values.yaml", "**/values.yml", "**/kustomization.yaml", "**/kustomization.yml")
mise
Pkl: Builtins.mise
mise-en-place's built-in formatter and linter
- Files:
mise.toml,mise.*.toml,.mise.toml,.mise.*.toml,mise/config.toml,mise/config.*.toml,.mise/config.toml,.mise/config.*.toml,.config/mise.toml,.config/mise.*.toml,.config/mise/config.toml,.config/mise/config.*.toml,.config/mise/mise.toml,.config/mise/mise.*.toml,.config/mise/conf.d/*.toml - Install: project page
- Check:
mise fmt --check - Fix:
mise fmt
mise-config-dir
Pkl: Builtins.mise_config_dir
mise formatter for a global config repository checked out at ~/.config/mise (e.g. mise bootstrap --adopt)
Files:
config.toml,config.*.toml,conf.d/*.toml,conf.d/*/mise.toml,conf.d/*/mise.*.tomlInstall: project page
Check:
hk util format-diff {{files}} -- mise fmt --stdinCheck (diff):
hk util format-diff {{files}} -- mise fmt --stdinFix:
shsh -c 'status=0 for f in "$@"; do tmp=$(mktemp) || exit 1 # An empty result for a non-empty file is a formatter failure, as in `hk util format-diff`. if mise fmt --stdin < "$f" > "$tmp" && { [ -s "$tmp" ] || [ ! -s "$f" ]; }; then cat "$tmp" > "$f" || status=1 else status=1 fi rm -f "$tmp" done exit $status' sh {{files}}Options:
exclude = List("conf.d/*/[!m]*.toml", "conf.d/*/m[!i]*.toml", "conf.d/*/mi[!s]*.toml", "conf.d/*/mis[!e]*.toml", "conf.d/*/mise[!.]*.toml")
packer-fmt
Pkl: Builtins.packer_fmt
Packer HCL2 template formatter
- Files:
**/*.pkr.hcl,**/*.pkrvars.hcl - Install:
mise use packer - Check:
packer fmt -check {{files}} - Check (diff):
hk util format-diff {{files}} -- packer fmt - - Fix:
packer fmt {{files}}
pinact
Pkl: Builtins.pinact
Pin GitHub Actions to commit SHA for security
- Files:
.github/workflows/*,**/action.*that areyamlfiles - Install:
mise use pinact - Check:
pinact run --verify-comment --check {{files}} - Check (diff):
hk util sarif-diff -- pinact run --verify-comment --check --format sarif {{files}} - Fix:
pinact run --verify-comment {{files}}
pinact-update
Pkl: Builtins.pinact_update
Pin GitHub Actions to update actions to latest versions
- Files:
.github/workflows/*,**/action.*that areyamlfiles - Install:
mise use pinact - Check:
pinact run --update --verify-comment --check {{files}} - Check (diff):
hk util sarif-diff -- pinact run --update --verify-comment --check --format sarif {{files}} - Fix:
pinact run --update --verify-comment {{files}}
terraform
Pkl: Builtins.terraform
Terraform formatter
- Files:
**/*.tf,**/*.tfvars,**/*.tftest.hcl - Install:
mise use terraform - Check:
terraform fmt -check {{files}} - Check (diff):
hk util format-diff {{files}} -- terraform fmt - - Fix:
terraform fmt {{files}}
terraform-docs
Pkl: Builtins.terraform_docs
Terraform module documentation generator
Files:
**/*.tf,**/*.tf.json,**/*.tofu,**/.terraform.lock.hclInstall:
mise use terraform-docsCheck:
shfor f in {{ files }}; do dirname "$f"; done | sort -u | { code=0; while IFS= read -r dir; do terraform-docs markdown table --output-check --output-file README.md --output-mode inject "$dir" || code=1 done; exit $code; }Fix:
shfor f in {{ files }}; do dirname "$f"; done | sort -u | { code=0; while IFS= read -r dir; do terraform-docs markdown table --output-file README.md --output-mode inject "$dir" || code=1 done; exit $code; }Options:
exclude = "**/.terraform/**"
terraform-validate
Pkl: Builtins.terraform_validate
Terraform configuration validator
Files:
**/*.tf,**/*.tfvars,**/*.tf.json,**/*.tofu,**/.terraform.lock.hclInstall:
mise use terraformCheck:
shfor f in {{ files }}; do dirname "$f"; done | sort -u | { code=0; while IFS= read -r dir; do terraform -chdir="$dir" validate && continue terraform -chdir="$dir" init -backend=false -input=false > /dev/null || { code=1; continue; } terraform -chdir="$dir" validate || code=1 done; exit $code; }Options:
exclude = "**/.terraform/**"
terragrunt-hcl-fmt
Pkl: Builtins.terragrunt_hcl_fmt
Terragrunt HCL formatter
Files:
**/*.hclInstall:
mise use terragruntCheck:
shset -- for f in {{ files }}; do set -- "$@" "--filter=./$f"; done if [ "$#" -eq 0 ]; then exit 0; fi terragrunt hcl fmt --check --diff "$@"Fix:
shset -- for f in {{ files }}; do set -- "$@" "--filter=./$f"; done if [ "$#" -eq 0 ]; then exit 0; fi terragrunt hcl fmt "$@"Options:
exclude = List("**/.terraform/**", "**/.terragrunt-cache/**")
terragrunt-hcl-validate
Pkl: Builtins.terragrunt_hcl_validate
Terragrunt HCL validator
Files:
**/*.hclInstall:
mise use terragruntCheck:
shset -- for f in {{ files }}; do case "$f" in */*) d="./${f%/*}" ;; *) d="." ;; esac set -- "$@" "--filter=$d" "--filter=reading=./$f" done if [ "$#" -eq 0 ]; then exit 0; fi terragrunt hcl validate --show-config-path --log-level error "$@"Options:
exclude = List("**/.terraform/**", "**/.terragrunt-cache/**")
tf-lint
Pkl: Builtins.tf_lint
Terraform linter
Files:
**/*.tf,**/*.tfvars,**/*.tofuInstall:
mise use tflintCheck:
shfor f in {{ files }}; do dirname "$f"; done | sort -u | { code=0; while IFS= read -r dir; do tflint --chdir="$dir" || code=1 done; exit $code; }Fix:
shfor f in {{ files }}; do dirname "$f"; done | sort -u | { code=0; while IFS= read -r dir; do tflint --chdir="$dir" --fix || tflint --chdir="$dir" || code=1 done; exit $code; }Options:
exclude = "**/.terraform/**"
tofu
Pkl: Builtins.tofu
OpenTofu formatter
- Files:
**/*.tf,**/*.tfvars,**/*.tftest.hcl - Install:
mise use opentofu - Check:
tofu fmt -check {{files}} - Check (diff):
hk util format-diff {{files}} -- tofu fmt - - Fix:
tofu fmt {{files}}
tofu-validate
Pkl: Builtins.tofu_validate
OpenTofu configuration validator
Files:
**/*.tf,**/*.tfvars,**/*.tf.json,**/*.tofu,**/*.tofu.json,**/.terraform.lock.hclInstall:
mise use opentofuCheck:
shfor f in {{ files }}; do dirname "$f"; done | sort -u | { code=0; while IFS= read -r dir; do tofu -chdir="$dir" validate && continue tofu -chdir="$dir" init -backend=false -input=false > /dev/null || { code=1; continue; } tofu -chdir="$dir" validate || code=1 done; exit $code; }Options:
exclude = "**/.terraform/**"
zizmor
Pkl: Builtins.zizmor
GitHub Actions security static analysis tool
- Files:
.github/workflows/*.yml,.github/workflows/*.yaml,.github/dependabot.yml,**/action.yml,**/action.yaml - Install:
mise use zizmor - Check:
zizmor --no-progress {{files}} - Fix:
zizmor --no-progress --fix {{files}}
Java
google-java-format
Pkl: Builtins.google_java_format
Google Java Format
- Files:
**/*.java - Install:
mise use google-java-format - Check:
google-java-format --dry-run --set-exit-if-changed {{files}} - Check (list files):
google-java-format --dry-run {{files}} - Fix:
google-java-format --replace {{files}}
JavaScript/TypeScript
biome
Pkl: Builtins.biome
Fast formatter and linter
- Files:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx,**/*.json - Install:
mise use biome - Check:
biome check --no-errors-on-unmatched {{files}} - Fix:
biome check --write --no-errors-on-unmatched {{files}}
deno
Pkl: Builtins.deno
Deno formatter
- Files:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Install:
mise use deno - Check:
deno fmt --check {{files}} - Fix:
deno fmt {{files}}
deno-check
Pkl: Builtins.deno_check
Deno type checker
- Files:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Install:
mise use deno - Check:
deno check {{files}}
eslint
Pkl: Builtins.eslint
Pluggable JavaScript linter
- Files:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Install:
mise use npm:eslint - Check:
eslint {{files}} - Fix:
eslint --fix {{files}} - Options:
batch = true
knip
Pkl: Builtins.knip
Find unused files, dependencies, and exports
- Files:
javascript,typescriptfiles - Install:
mise use npm:knip - Check:
knip --no-progress --directory {{workspace}} - Fix:
knip --fix --no-progress --directory {{workspace}} - Options:
workspace_indicator = "package.json"
ox-lint
Pkl: Builtins.ox_lint
Oxidation compiler linter
- Files:
**/*.js,**/*.mjs,**/*.cjs,**/*.ts,**/*.mts,**/*.cts,**/*.jsx,**/*.tsx,**/*.vue,**/*.svelte,**/*.astro - Install:
mise use oxlint - Check:
oxlint --deny-warnings {{files}} - Fix:
oxlint --deny-warnings --fix {{files}}
oxfmt
Pkl: Builtins.oxfmt
Fast Rust-powered code formatter (Prettier compatible)
- Files:
**/*.js,**/*.mjs,**/*.cjs,**/*.ts,**/*.mts,**/*.cts,**/*.jsx,**/*.tsx,**/*.mdx,**/*.vue,**/*.json,**/*.jsonc,**/*.json5,**/*.yaml,**/*.yml,**/*.toml,**/*.md,**/*.markdown,**/*.html,**/*.htm,**/*.css,**/*.scss,**/*.less,**/*.graphql,**/*.gql,**/*.handlebars,**/*.hbs - Install:
mise use oxfmt - Check:
oxfmt --check --no-error-on-unmatched-pattern {{files}} - Check (diff):
hk util format-diff {{files}} -- oxfmt --stdin-filepath '{}' - Fix:
oxfmt --write --no-error-on-unmatched-pattern {{files}} - Options:
exclude = List("**/pnpm-lock.yaml", "**/package-lock.json")
prettier
Pkl: Builtins.prettier
Opinionated code formatter
- Files:
**/*.js,**/*.jsx,**/*.mjs,**/*.cjs,**/*.ts,**/*.tsx,**/*.mts,**/*.cts,**/*.css,**/*.scss,**/*.less,**/*.html,**/*.json,**/*.json5,**/*.jsonc,**/*.yaml,**/*.yml,**/*.markdown,**/*.markdown.mdx,**/*.md,**/*.graphql,**/*.handlebars,**/*.svelte,**/*.astro,**/*.htmlangular,**/*.vue - Install:
mise use prettier - Check:
prettier --check {{files}} - Check (list files):
prettier --list-different {{files}} - Fix:
prettier --write {{files}} - Options:
batch = true
sherif
Pkl: Builtins.sherif
Opinionated, zero-config linter for TypeScript & JavaScript monorepos
- Files:
**/package.json,**/pnpm-workspace.yaml - Install:
mise use sherif - Check:
sherif - Fix:
sherif --fix --no-install
standard-js
Pkl: Builtins.standard_js
JavaScript Standard Style
- Files:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Install:
mise use npm:standard - Check:
standard {{files}} - Fix:
standard --fix {{files}}
tsc
Pkl: Builtins.tsc
TypeScript type checker
- Files:
**/*.ts,**/*.tsx - Install:
mise use npm:typescript - Check:
tsc --noEmit -p {{workspace_indicator}} - Options:
workspace_indicator = "tsconfig.json"
tsserver
Pkl: Builtins.tsserver
TypeScript language server diagnostics
- Files:
**/*.ts,**/*.tsx - Install:
mise use npm:tsc-files npm:typescript - Check:
tsc-files --noEmit {{files}}
vp-check
Pkl: Builtins.vp_check
Formats, lints, and type checks code together
- Files:
**/*.js,**/*.mjs,**/*.cjs,**/*.ts,**/*.mts,**/*.cts,**/*.jsx,**/*.tsx,**/*.mdx,**/*.vue,**/*.svelte,**/*.astro,**/*.json,**/*.jsonc,**/*.json5,**/*.yaml,**/*.yml,**/*.md,**/*.markdown,**/*.html,**/*.htm,**/*.css,**/*.scss,**/*.less,**/*.graphql,**/*.gql,**/*.handlebars,**/*.hbs,**/*.toml - Install:
mise use vp - Check:
vp check --no-error-on-unmatched-pattern {{files}} - Fix:
vp check --fix --no-error-on-unmatched-pattern {{files}} - Options:
workspace_indicator = "package.json"
vp-fmt
Pkl: Builtins.vp_fmt
Formats code with Oxfmt
- Files:
**/*.js,**/*.mjs,**/*.cjs,**/*.ts,**/*.mts,**/*.cts,**/*.jsx,**/*.tsx,**/*.mdx,**/*.vue,**/*.json,**/*.jsonc,**/*.json5,**/*.yaml,**/*.yml,**/*.toml,**/*.md,**/*.markdown,**/*.html,**/*.htm,**/*.css,**/*.scss,**/*.less,**/*.graphql,**/*.gql,**/*.handlebars,**/*.hbs - Install:
mise use vp - Check:
vp fmt --check --no-error-on-unmatched-pattern {{files}} - Check (list files):
vp fmt --list-different --no-error-on-unmatched-pattern {{files}} - Fix:
vp fmt --no-error-on-unmatched-pattern {{files}} - Options:
workspace_indicator = "package.json"
vp-lint
Pkl: Builtins.vp_lint
Lints code with OxLint
- Files:
**/*.js,**/*.mjs,**/*.cjs,**/*.ts,**/*.mts,**/*.cts,**/*.jsx,**/*.tsx,**/*.mdx,**/*.vue,**/*.svelte,**/*.astro - Install:
mise use vp - Check:
vp lint --deny-warnings --no-error-on-unmatched-pattern {{files}} - Fix:
vp lint --deny-warnings --fix --no-error-on-unmatched-pattern {{files}} - Options:
workspace_indicator = "package.json"
xo
Pkl: Builtins.xo
JavaScript/TypeScript linter with great defaults
- Files:
**/*.js,**/*.jsx,**/*.ts,**/*.tsx - Install:
mise use npm:xo - Check:
xo {{files}} - Fix:
xo --fix {{files}}
Lua
luacheck
Pkl: Builtins.luacheck
Lua linter
- Files:
luafiles - Install: project page
- Check:
luacheck {{files}}
selene
Pkl: Builtins.selene
Lua linter
- Files:
luafiles - Install:
mise use aqua:Kampfkarren/selene/light - Check:
selene {{files}}
stylua
Pkl: Builtins.stylua
Lua formatter
- Files:
luafiles - Install:
mise use stylua - Check:
stylua --check {{files}} - Check (diff):
hk util format-diff {{files}} -- stylua --stdin-filepath '{}' - - Fix:
stylua {{files}}
Markdown
contextlint
Pkl: Builtins.contextlint
Rule-based linter for structured Markdown documents
- Files:
markdownfiles - Install:
mise use npm:@contextlint/cli - Check:
contextlint {{files}} - Options:
workspace_indicator = "contextlint.config.json"
mado
Pkl: Builtins.mado
Fast Markdown linter (CommonMark/GFM)
- Files:
markdownfiles - Install:
mise use aqua:akiomik/mado - Check:
mado check {{files}}
markdown-lint
Pkl: Builtins.markdown_lint
Markdown linter
- Files:
**/*.md,**/*.markdown - Install:
mise use npm:markdownlint-cli - Check:
markdownlint {{files}} - Fix:
markdownlint --fix {{files}}
mdschema
Pkl: Builtins.mdschema
Schema-based Markdown documentation validator
- Files:
markdownfiles - Install:
mise use aqua:jackchuka/mdschema - Check:
mdschema check {{files}} - Options:
workspace_indicator = ".mdschema.yml"
rumdl
Pkl: Builtins.rumdl
Markdown linter
- Files:
**/*.md,**/*.markdown - Install:
mise use rumdl - Check:
rumdl check {{files}} - Check (diff):
rumdl check --diff {{files}} - Fix:
rumdl check --fix {{files}} - Options:
check_after_diff = true
rumdl-format
Pkl: Builtins.rumdl_format
Markdown formatter
- Files:
**/*.md,**/*.markdown - Install:
mise use rumdl - Check (diff):
rumdl fmt --check --diff {{files}} - Fix:
rumdl fmt {{files}}
ryl-markdown
Pkl: Builtins.ryl_markdown
Lint YAML embedded in Markdown (front matter + fenced yaml blocks) with ryl
- Files:
markdownfiles - Install:
mise use aqua:owenlamont/ryl - Check:
ryl check --markdown {{files}} - Check (diff):
ryl check --diff --markdown {{files}} - Check (list files):
ryl check --list-files --markdown {{files}} - Fix:
ryl check --fix --markdown {{files}} - Options:
check_after_diff = true
ryl-markdown-format
Pkl: Builtins.ryl_markdown_format
Format YAML embedded in Markdown (front matter + fenced yaml blocks) with ryl
- Files:
markdownfiles - Install:
mise use aqua:owenlamont/ryl - Check:
ryl format --check --markdown {{files}} - Check (diff):
ryl format --diff --markdown {{files}} - Fix:
ryl format --markdown {{files}}
Nix
alejandra
Pkl: Builtins.alejandra
Alternative Nix formatter
- Files:
**/*.nix - Install: project page
- Check:
alejandra --check {{files}} - Fix:
alejandra {{files}}
deadnix
Pkl: Builtins.deadnix
Scan Nix files for dead code
- Files:
**/*.nix - Install:
mise use cargo:deadnix - Check:
deadnix --fail {{files}} - Fix:
deadnix --edit {{files}}
nil
Pkl: Builtins.nil
Nix Language server
- Files:
**/*.nix - Install: project page
- Check:
nil diagnostics --deny-warnings {{files}}
nix-fmt
Pkl: Builtins.nix_fmt
Nix formatter
Files:
**/*.nixInstall: project page
Check:
sh# Windows: nothing runs # other platforms: nixfmt --check {{ files }}Fix:
sh# Windows: nothing runs # other platforms: nixfmt {{ files }}
nixf-diagnose
Pkl: Builtins.nixf_diagnose
Nix linter based on libnixf
- Files:
**/*.nix - Install: project page
- Check:
nixf-diagnose {{files}}
nixpkgs-format
Pkl: Builtins.nixpkgs_format
Nixpkgs formatter
- Files:
**/*.nix - Install: project page
- Check:
nixpkgs-fmt --check {{files}} - Fix:
nixpkgs-fmt {{files}}
Other Languages
astro
Pkl: Builtins.astro
Astro component checker
- Files:
**/*.astro - Install: project page
- Check:
astro check {{files}}
clang-format
Pkl: Builtins.clang_format
C/C++ formatter
- Files:
**/*.c,**/*.h,**/*.cpp,**/*.hpp,**/*.cc,**/*.hh,**/*.cxx,**/*.hxx - Install:
mise use pipx:clang-format - Check:
clang-format --dry-run -Werror {{files}} - Fix:
clang-format -i {{files}}
cmake-format
Pkl: Builtins.cmake_format
Source code formatter for cmake listfiles
- Files:
**/CMakeLists.txt,**/*.cmake - Install:
mise use pipx:cmakelang - Check:
cmake-format --check {{files}} - Fix:
cmake-format --in-place {{files}}
cpp-lint
Pkl: Builtins.cpp_lint
C++ style checker
- Files:
**/*.c,**/*.h,**/*.cpp,**/*.hpp,**/*.cc,**/*.hh,**/*.cxx,**/*.hxx - Install:
mise use pipx:cpplint - Check:
cpplint {{files}}
dprint
Pkl: Builtins.dprint
Pluggable code formatter
- Files:
textfiles - Install:
mise use dprint - Check:
dprint check --allow-no-files {{files}} - Check (list files):
dprint check --allow-no-files --list-different {{files}} - Fix:
dprint fmt --allow-no-files {{files}}
ktlint
Pkl: Builtins.ktlint
Kotlin linter and formatter
- Files:
**/*.kt - Install:
mise use ktlint - Check:
ktlint {{files}} - Fix:
ktlint -F {{files}}
swiftlint
Pkl: Builtins.swiftlint
Swift style and conventions
- Files:
**/*.swift - Install:
mise use swiftlint - Check:
swiftlint lint {{files}} - Fix:
swiftlint --fix {{files}}
vacuum
Pkl: Builtins.vacuum
Fast OpenAPI linter
- Files:
**/*openapi*.yaml,**/*openapi*.yml,**/*openapi*.json,**/*swagger*.yaml,**/*swagger*.yml,**/*swagger*.json - Install:
mise use vacuum - Check:
vacuum lint {{files}} - Fix:
vacuum lint --fix {{files}}
PHP
php-cs
Pkl: Builtins.php_cs
PHP coding standards
- Files:
**/*.php - Install: project page
- Check:
phpcs {{files}} - Fix:
phpcbf {{files}}
phpstan
Pkl: Builtins.phpstan
PHP static analyzer
- Files:
**/*.php - Check:
phpstan analyse --no-progress {{files}}
Package
aqua-update-checksum
Pkl: Builtins.aqua_update_checksum
create or update aqua checksums
- Files:
{aqua,.aqua}.{yml,yaml},{aqua,.aqua}/**/*.{yml,yaml},aqua-checksums.json,{aqua,.aqua}/aqua-checksums.json - Install:
mise use aqua - Fix:
aqua update-checksum --prune
Pkl
pkl
Pkl: Builtins.pkl
Pkl configuration language
- Files:
pklfiles - Install:
mise use pkl - Check:
pkl eval {{files}} >/dev/null
pkl-format
Pkl: Builtins.pkl_format
Pkl formatter
Files:
pklfilesInstall:
mise use pklCheck (list files):
pkl format --diff-name-only {{ files }}Fix:
shpkl format --write {{ files }} code=$? if [ $code -eq 11 ]; then exit 0 else exit $code fiOptions:
shell = "sh -c"
Python
black
Pkl: Builtins.black
Opinionated Python formatter
Files:
**/*.pyInstall:
mise use blackCheck:
black --check {{files}}Check (list files):
sh# Windows: nothing runs # other platforms: set -- {{ files }} out=$(black --check "$@" 2>&1) && exit 0 status=$? printf '%s\n' "$out" | while IFS= read -r line; do case "$line" in "would reformat "*) printf '%s\n' "${line#would reformat }" ;; "error: cannot format "*) # The message after the path may contain ": ", so match the inputs. for f; do case "$line" in "error: cannot format $f: "*) printf '%s\n' "$f" ;; esac done ;; esac done exit $statusFix:
black {{files}}
flake8
Pkl: Builtins.flake8
Python style guide enforcement
- Files:
**/*.py - Install:
mise use pipx:flake8 - Check:
flake8 {{files}}
isort
Pkl: Builtins.isort
Python import sorter
- Files:
**/*.py - Install:
mise use pipx:isort - Check:
isort --check-only {{files}} - Check (diff):
isort --check-only --diff {{files}} - Fix:
isort {{files}}
mypy
Pkl: Builtins.mypy
Static type checker for Python
- Files:
**/*.py,**/*.pyi - Install:
mise use pipx:mypy - Check:
mypy {{files}}
pylint
Pkl: Builtins.pylint
Python code analysis
- Files:
**/*.py - Install:
mise use pipx:pylint - Check:
pylint {{files}}
pyright
Pkl: Builtins.pyright
Static type checker for Python
- Files:
**/*.py,**/*.pyi,**/*.pyw - Check:
pyright {{files}}
python-check-ast
Pkl: Builtins.python_check_ast
Validate Python syntax by parsing the AST
- Files:
**/*.py - Install:
mise use python - Check:
hk util python-check-ast {{files}}
python-debug-statements
Pkl: Builtins.python_debug_statements
Detect debug statements in Python code
- Files:
**/*.py - Check:
hk util python-debug-statements {{files}}
ruff
Pkl: Builtins.ruff
Fast Python linter
- Files:
pythonfiles - Install:
mise use ruff - Check:
ruff check --force-exclude {{files}} - Check (diff):
ruff check --force-exclude --diff --exit-non-zero-on-fix {{ files }} && ruff check --force-exclude {{ files }} - Fix:
ruff check --force-exclude --fix {{files}} - Options:
check_after_diff = true
ruff-format
Pkl: Builtins.ruff_format
Fast Python formatter (part of ruff)
- Files:
pythonfiles - Install:
mise use ruff - Check (diff):
ruff format --quiet --force-exclude --diff {{files}} - Fix:
ruff format --quiet --force-exclude {{files}}
ty
Pkl: Builtins.ty
Fast Python type checker
- Files:
**/*.py,**/*.pyi - Install:
mise use ty - Check:
ty check {{files}}
Ruby
brakeman
Pkl: Builtins.brakeman
Security scanner for Rails
- Files:
rubyfiles - Install:
mise use gem:brakeman - Check:
brakeman -q -w2
bundle-audit
Pkl: Builtins.bundle_audit
Dependency security audit
- Files:
**/Gemfile.lock - Install:
mise use gem:bundler-audit - Check:
bundle-audit check {{files}} - Fix:
bundle-audit update
erb
Pkl: Builtins.erb
ERB template linter
- Files:
**/*.erb - Install:
mise use ruby - Check:
erb -P -x -T - {{ files }} | ruby -c
fasterer
Pkl: Builtins.fasterer
Performance suggestions
- Files:
rubyfiles - Install:
mise use gem:fasterer - Check:
fasterer {{files}}
herb-format
Pkl: Builtins.herb_format
HTML+ERB formatter (experimental)
- Files:
**/*.herb,**/*.html.herb,**/*.html,**/*.rhtml,**/*.html.erb,**/*.html+*.erb,**/*.turbo_stream.erb - Install:
mise use npm:@herb-tools/formatter - Check:
herb-format --check {{files}} - Check (diff):
hk util format-diff {{files}} -- herb-format - - Fix:
herb-format {{files}} - Options:
batch = true
herb-lint
Pkl: Builtins.herb_lint
HTML+ERB linter
- Files:
**/*.herb,**/*.html.herb,**/*.html,**/*.rhtml,**/*.html.erb,**/*.html+*.erb,**/*.turbo_stream.erb - Install:
mise use npm:@herb-tools/linter - Check:
herb-lint {{files}} - Fix:
herb-lint --fix {{files}} - Options:
batch = true
reek
Pkl: Builtins.reek
Code smell detector
- Files:
rubyfiles - Install:
mise use gem:reek - Check:
reek {{files}}
rubocop
Pkl: Builtins.rubocop
Ruby style guide
- Files:
**/*.rb,**/*.arb,**/*.axlsx,**/*.builder,**/*.gemfile,**/*.gemspec,**/*.jb,**/*.jbuilder,**/*.mspec,**/*.opal,**/*.pluginspec,**/*.podspec,**/*.rabl,**/*.rake,**/*.rbw,**/*.ru,**/*.ruby,**/*.schema,**/*.spec,**/*.thor,**/.irbrc,**/.pryrc,**/.simplecov,**/buildfile,**/Appraisals,**/Berksfile,**/Brewfile,**/Buildfile,**/Capfile,**/Dangerfile,**/Deliverfile,**/Fastfile,**/*Fastfile,**/Gemfile,**/Guardfile,**/Jarfile,**/Mavenfile,**/Podfile,**/Puppetfile,**/Rakefile,**/rakefile,**/Schemafile,**/Snapfile,**/Steepfile,**/Thorfile,**/Vagrantfile - Install:
mise use gem:rubocop - Check:
rubocop --force-exclusion {{files}} - Check (list files):
rubocop --force-exclusion --format files {{files}} - Fix:
rubocop --force-exclusion --autocorrect {{files}} - Options:
exclude = List("node_modules/**/*", "tmp/**/*", "vendor/**/*", ".git/**/*")
rubocop-server
Pkl: Builtins.rubocop_server
Ruby style guide (using RuboCop's --server mode)
- Files:
**/*.rb,**/*.arb,**/*.axlsx,**/*.builder,**/*.gemfile,**/*.gemspec,**/*.jb,**/*.jbuilder,**/*.mspec,**/*.opal,**/*.pluginspec,**/*.podspec,**/*.rabl,**/*.rake,**/*.rbw,**/*.ru,**/*.ruby,**/*.schema,**/*.spec,**/*.thor,**/.irbrc,**/.pryrc,**/.simplecov,**/buildfile,**/Appraisals,**/Berksfile,**/Brewfile,**/Buildfile,**/Capfile,**/Dangerfile,**/Deliverfile,**/Fastfile,**/*Fastfile,**/Gemfile,**/Guardfile,**/Jarfile,**/Mavenfile,**/Podfile,**/Puppetfile,**/Rakefile,**/rakefile,**/Schemafile,**/Snapfile,**/Steepfile,**/Thorfile,**/Vagrantfile - Install:
mise use gem:rubocop - Check:
rubocop --server --force-exclusion {{files}} - Check (list files):
rubocop --server --force-exclusion --format files {{files}} - Fix:
rubocop --server --force-exclusion --autocorrect {{files}} - Options:
exclude = List("node_modules/**/*", "tmp/**/*", "vendor/**/*", ".git/**/*")
sorbet
Pkl: Builtins.sorbet
Type checker for Ruby
- Files:
rubyfiles - Install:
mise use gem:sorbet - Check:
srb tc {{files}}
standard-rb
Pkl: Builtins.standard_rb
Ruby Standard Style
- Files:
rubyfiles - Install:
mise use gem:standard - Check:
standardrb --force-exclusion {{files}} - Fix:
standardrb --force-exclusion --fix {{files}}
Rust
cargo-check
Pkl: Builtins.cargo_check
Fast Rust type checking
- Files:
**/*.rs - Install:
mise use rust - Check:
cargo check --quiet - Fix:
cargo fix --allow-dirty --allow-staged --quiet
cargo-clippy
Pkl: Builtins.cargo_clippy
Rust linter
- Files:
**/*.rs - Install:
mise use rust - Check:
cargo clippy --manifest-path {{workspace_indicator}} --quiet - Fix:
cargo clippy --manifest-path {{workspace_indicator}} --fix --allow-dirty --allow-staged --quiet - Options:
workspace_indicator = "Cargo.toml"
cargo-deny
Pkl: Builtins.cargo_deny
Rust dependency linter
- Files:
**/Cargo.toml,**/Cargo.lock,**/deny.toml,**/.deny.toml,**/deny.exceptions.toml,**/.deny.exceptions.toml - Install:
mise use cargo-deny - Check:
cargo-deny --locked --workspace check - Options:
workspace_indicator = "Cargo.toml",dir = "{{workspace}}"
cargo-fmt
Pkl: Builtins.cargo_fmt
Rust code formatter
- Files:
**/*.rs,**/rustfmt.toml,**/.rustfmt.toml - Install:
mise use rust - Check:
cargo fmt --check --manifest-path {{workspace_indicator}} - Check (list files):
cargo fmt --check --manifest-path {{workspace_indicator}} -- --files-with-diff - Fix:
cargo fmt --manifest-path {{workspace_indicator}} - Options:
workspace_indicator = "Cargo.toml"
rustfmt
Pkl: Builtins.rustfmt
Rust code formatter (standalone)
- Files:
**/*.rs - Install:
mise use rust - Check:
rustfmt --check --edition 2024 {{files}} - Check (list files):
rustfmt --check --edition 2024 --files-with-diff {{files}} - Fix:
rustfmt --edition 2024 {{files}}
Secrets
betterleaks
Pkl: Builtins.betterleaks
A Better Secrets Scanner built for configurability and speed
- Files:
textfiles - Install:
mise use betterleaks - Check:
betterleaks dir --redact --verbose --no-banner {{files}}
gitleaks
Pkl: Builtins.gitleaks
Secret scanner for repository working trees
- Install:
mise use gitleaks - Check:
gitleaks dir --redact --verbose --no-banner .
kingfisher
Pkl: Builtins.kingfisher
Secret scanner with live validation and 1,000+ rules
- Files:
textfiles - Install:
mise use kingfisher - Check:
kingfisher scan {{files}} --no-update-check --no-validate --quiet
trufflehog
Pkl: Builtins.trufflehog
Secret scanner that classifies 800+ credential types
- Files:
textfiles - Check:
trufflehog filesystem {{files}} --fail --no-update --no-verification
Shell
shellcheck
Pkl: Builtins.shellcheck
Shell script analyzer
- Files:
**/*.sh,**/*.bash; orsh,bashfiles - Install:
mise use shellcheck - Check:
shellcheck {{files}} - Check (diff):
shellcheck --format=diff {{files}} - Options:
batch = true,check_after_diff = true
shellharden
Pkl: Builtins.shellharden
The corrective bash syntax highlighter
- Files:
bash,shfiles - Install:
mise use shellharden - Check:
shellharden --check {{files}} - Check (diff):
hk util format-diff --no-stdin {{files}} -- shellharden --transform '{}' - Fix:
shellharden --replace {{files}} - Options:
batch = true
shfmt
Pkl: Builtins.shfmt
Shell formatter
Files:
**/*.sh,**/*.bash,**/*.mksh,**/*.bats,**/*.zsh; orsh,bash,zshfilesInstall:
mise use shfmtCheck (diff):
shfmt -d --apply-ignore {{ files }}Check (list files):
shfiles=$(shfmt -l --apply-ignore {{ files }}) if [ -n "$files" ]; then echo "$files" exit 1 fiFix:
shfmt -w --apply-ignore {{ files }}Options:
batch = true
Special Purpose
byte-order-marker
Pkl: Builtins.byte_order_marker
Detect UTF-8 BOM
- Files:
textfiles - Check (diff):
hk util check-byte-order-marker --diff {{files}} - Fix:
hk util fix-byte-order-marker {{files}}
check-added-large-files
Pkl: Builtins.check_added_large_files
Prevent committing large files
- Files:
**/* - Check:
hk util check-added-large-files {{files}} - Options:
allow_binary = true
check-case-conflict
Pkl: Builtins.check_case_conflict
Detect case-insensitive filename conflicts
- Files:
**/* - Check:
hk util check-case-conflict {{files}} - Options:
allow_binary = true,allow_symlinks = true
check-conventional-commit
Pkl: Builtins.check_conventional_commit
Verify commit message matches conventional commits formatting
- Check:
hk util check-conventional-commit {{commit_msg_file}}
check-executables-have-shebangs
Pkl: Builtins.check_executables_have_shebangs
Verify executable files have shebang lines
- Files:
textfiles - Check:
hk util check-executables-have-shebangs {{files}}
check-merge-conflict
Pkl: Builtins.check_merge_conflict
Detect merge conflict markers
- Files:
textfiles - Check:
hk util check-merge-conflict --assume-in-merge {{files}}
check-shebang-scripts-are-executable
Pkl: Builtins.check_shebang_scripts_are_executable
Verify files with shebang lines are executable
- Files:
textfiles - Check:
hk util check-shebang-scripts-are-executable {{files}}
check-symlinks
Pkl: Builtins.check_symlinks
Detect broken symlinks
- Files:
**/* - Check:
hk util check-symlinks {{files}} - Options:
allow_symlinks = true
cocogitto-commit-msg
Pkl: Builtins.cocogitto_commit_msg
Conventional commits linter
- Install:
mise use cocogitto - Check:
cog --quiet verify --file {{commit_msg_file}}
destroyed-symlinks
Pkl: Builtins.destroyed_symlinks
Detect symlinks replaced by regular files holding their target path
- Check:
hk util destroyed-symlinks
detect-private-key
Pkl: Builtins.detect_private_key
Detect accidentally committed private keys
- Files:
textfiles - Check:
hk util detect-private-key {{files}}
fix-smart-quotes
Pkl: Builtins.fix_smart_quotes
Replace smart quotes with regular quotes
- Files:
textfiles - Check (diff):
hk util fix-smart-quotes --diff {{files}} - Fix:
hk util fix-smart-quotes {{files}}
forbid-submodules
Pkl: Builtins.forbid_submodules
Forbid git submodules in the repository
- Check:
hk util forbid-submodules
harper
Pkl: Builtins.harper
Grammar checker for prose and documentation
- Files:
textfiles - Install:
mise use harper-cli - Check:
harper-cli lint {{files}}
harper-commit-message
Pkl: Builtins.harper_commit_message
Grammar checker for commit message
- Install:
mise use harper-cli - Check:
harper-cli lint {{commit_msg_file}}
hk-test
Pkl: Builtins.hk_test
Run step-defined hk's tests
- Files:
hk.pkl,.config/hk.pkl - Check:
hk test --quiet
just-format
Pkl: Builtins.just_format
Justfile formatter
Files:
**/justfile,**/*.justInstall:
mise use justFix:
shxargs -d' ' -I {} -- just --fmt --unstable --justfile {}
ls-lint
Pkl: Builtins.ls_lint
Directory and filename naming linter
- Files:
**/* - Install:
mise use ls-lint - Check:
ls-lint - Options:
allow_binary = true,allow_symlinks = true
lychee
Pkl: Builtins.lychee
Fast, async, stream-based link checker
- Files:
textfiles - Install:
mise use lychee - Check:
lychee --no-progress {{files}}
lychee-extended
Pkl: Builtins.lychee_extended
Flint's repository-aware link check (requires flint and lychee). See https://github.com/grafana/flint/blob/main/docs/linters/lychee.md
- Files:
textfiles - Install:
mise use packslip:grafana/flint lychee - Check:
flint checker lychee --files-from -
mixed-line-ending
Pkl: Builtins.mixed_line_ending
Detect and fix mixed line endings
- Files:
textfiles - Check (diff):
hk util mixed-line-ending --diff {{files}} - Fix:
hk util mixed-line-ending --fix {{files}}
newlines
Pkl: Builtins.newlines
Ensure files end with newline
- Files:
textfiles - Check (diff):
hk util end-of-file-fixer --diff {{files}} - Fix:
hk util end-of-file-fixer --fix {{files}}
no-commit-to-branch
Pkl: Builtins.no_commit_to_branch
Prevent direct commits to protected branches
- Check:
hk util no-commit-to-branch
osv-scanner
Pkl: Builtins.osv_scanner
Vulnerability scanner for dependency lockfiles using the OSV database
- Files:
**/*.deps.json,**/*requirements*.txt,**/buildscript-gradle.lockfile,**/bun.lock,**/cabal.project.freeze,**/Cargo.lock,**/composer.lock,**/conan.lock,**/Gemfile.lock,**/gems.locked,**/go.mod,**/gradle.lockfile,**/gradle/verification-metadata.xml,**/mix.lock,**/npm-shrinkwrap.json,**/package_config.json,**/package-lock.json,**/packages.config,**/packages.lock.json,**/pdm.lock,**/Pipfile.lock,**/pnpm-lock.yaml,**/poetry.lock,**/pom.xml,**/pubspec.lock,**/pylock.toml,**/renv.lock,**/stack.yaml.lock,**/uv.lock,**/yarn.lock - Check:
osv-scanner scan source --allow-no-lockfiles {{files}}
renovate-deps
Pkl: Builtins.renovate_deps
Flint's repository-aware dependency check (requires flint and renovate). See https://github.com/grafana/flint/blob/main/docs/linters/renovate-deps.md
- Files:
**/* - Install:
mise use packslip:grafana/flint npm:renovate - Check:
flint checker renovate-deps --files-from - - Fix:
flint checker renovate-deps --fix --files-from - - Options:
stage = List(".github/renovate-tracked-deps.json")
textlint
Pkl: Builtins.textlint
Pluggable natural language linter
- Files:
**/*.md,**/*.markdown,**/*.txt - Install:
mise use npm:textlint - Check:
textlint {{files}} - Fix:
textlint --fix {{files}} - Options:
batch = true
trailing-whitespace
Pkl: Builtins.trailing_whitespace
Detect and remove trailing whitespace
- Files:
textfiles - Check (diff):
hk util trailing-whitespace --diff {{files}} - Fix:
hk util trailing-whitespace --fix {{files}}
typos
Pkl: Builtins.typos
Source code spell checker
Files:
textfilesInstall:
mise use typosCheck (diff):
shstatus=0 output=$(typos --force-exclude --diff {{files}}) || status=$? [ -z "$output" ] && exit "$status" printf "%s" "$output" exit 1Fix:
typos --force-exclude --write-changes {{ files }}
vale
Pkl: Builtins.vale
Prose linter for markup and code comments
- Files:
textfiles - Install:
mise use vale - Check:
vale sync && vale {{ files }}
Typst
tinymist
Pkl: Builtins.tinymist
Typst linter (requires tinymist 0.14.20 or newer)
Files:
**/*.typInstall:
mise use tinymistCheck:
shcode=0 for f in {{ files }}; do tinymist lint "$f" || code=$? done exit "$code"Options:
batch = true,shell = "sh -c"
typstyle
Pkl: Builtins.typstyle
Typst formatter
- Files:
**/*.typ - Install:
mise use typstyle - Check (diff):
typstyle --diff {{files}} - Fix:
typstyle --inplace {{files}}
YAML
ryl
Pkl: Builtins.ryl
Re-implementation of yamllint in Rust
- Files:
yamlfiles - Install:
mise use aqua:owenlamont/ryl - Check:
ryl check {{files}} - Check (diff):
ryl check --diff {{files}} - Check (list files):
ryl check --list-files {{files}} - Fix:
ryl check --fix {{files}} - Options:
check_after_diff = true
ryl-format
Pkl: Builtins.ryl_format
YAML formatter from ryl
- Files:
yamlfiles - Install:
mise use aqua:owenlamont/ryl - Check:
ryl format --check {{files}} - Check (diff):
ryl format --diff {{files}} - Fix:
ryl format {{files}}
Add a tool of your own
If there is no builtin, define a step with glob, check, and an optional fix command. Only enable batching if the tool can process independent subsets of files correctly.
See custom steps for a complete example, or contributing to contribute a reusable definition.
