hk Updates & Release Notes

Follow

38 updates curated from 1 source by the Releasebot Team. Last updated: Aug 31, 2026

Get this feed:
  • Aug 30, 2026
    • Date parsed from source:
      Aug 30, 2026
    • First seen by Releasebot:
      Aug 31, 2026
    jdx logo

    hk by jdx

    v1.57.0: Faster cold starts, workspace-aware directories, and safer partial fixes

    hk ships offline Pkl validation, workspace-aware templated dirs, and smarter partial fix handling. It also adds new Go and lint builtins, including go fix, golangci-lint fmt, ls-lint, and staged gitleaks, plus fixes for Go linters, Windows shims, workspace paths, and stashing.

    This release seeds hk with an embedded Pkl package so matching-version configs validate offline on a cold cache, adds templated dir support for workspace-aware steps, and lands a new check_after_diff mechanism that lets partial fixers (like ShellCheck) apply what they can while still reporting what they cannot. It also brings several new Go and lint builtins plus a batch of correctness fixes for Go linters, gitleaks, workspace paths, Windows shims, and stashing.

    Added

    Embedded matching-version Pkl package (@sahidvelji) #1218. hk now ships the Pkl package built for its own version and seeds HK_PKL_CACHE_DIR with it before evaluating hk.pkl, so a config pinned to that version validates with no network round trip on a cold cache — a fresh clone, CI runner, new container, or upgrade. Cached content always wins over the embedded copy, and other versions are fetched as before. Set HK_PKL_EMBEDDED=0 to disable seeding. Addresses discussion #1216.

    Templated dir through Tera (@sahidvelji) #1219. A step's dir is now rendered through Tera, so a workspace-aware step can point its working directory at the workspace it was matched for instead of prefixing every command with cd {{workspace}} && .... The eight workspace-aware builtins (the Go ones plus cargo_deny) drop their cd prefix as a result. Literal dir values are unaffected.

    ["go-vet"] {
    glob = "**/*.go"
    workspace_indicator = "go.mod"
    dir = "{{workspace}}"
    check = "go vet ./..."
    }
    

    check_after_diff for partial fixers (@jdx) #1243. New opt-in step setting that reruns check on the original file batch after a check_diff patch applies, so non-fixable findings stay visible instead of being masked by a clean apply. Requires both check and check_diff to be defined. This underpins ShellCheck's new fixer and other partial fixers.

    ShellCheck autofix via check_diff (@sahidvelji) #1237. shellcheck now applies the fixes it can via --format=diff, and thanks to check_after_diff a file with both fixable and non-fixable findings is fixed and still fails on what remains. Implements proposal 2 of #1234.

    go_fix builtin (@sahidvelji) #1224. Wraps Go's go fix (the Go 1.26+ analyzer-driven modernizer) — interface{} → any, sort.Slice → slices.Sort, wg.Add/go/wg.Done → wg.Go, and more. check_diff runs go fix -diff ./... and hk applies the patch directly. Requires Go 1.26+.

    golangci_lint_fmt formatter builtin (@sahidvelji) #1244. Wraps golangci-lint fmt, the formatter half of golangci-lint, formatting only the changed files via check_diff (using fmt --diff) — separate from the existing golangci_lint builtin that runs the full linter.

    ls_lint builtin (@sahidvelji) #1238. Adds a builtin for ls-lint, which enforces directory and filename naming conventions against .ls-lint.yml. Runs once per invocation. Implements proposal 3 of #1234.

    gitleaks_staged builtin (@jdx) #1248. A new builtin that runs gitleaks git --pre-commit --staged to scan only the staged index, suited to pre-commit hooks.

    Per-step allow_failure (@jdx) #1291. Steps can report a non-zero command exit without failing the overall hook, including conditional policies via expressions such as env('KNOWN_BROKEN') == 'true'. hk's own execution and configuration errors remain blocking, and allowed failures are surfaced in structured output.

    Fixed

    Go linters that reported success on bad code (@sahidvelji) #1225. go_imports, go_lines, revive, and go_fumpt silently passed in check mode even with real findings; they now take their exit code correctly. gomod_tidy could not run outside the repo root and is now scoped like the other Go builtins.

    gitleaks scan modes (@jdx) #1248. Builtins.gitleaks now explicitly scans the repository working tree rather than silently changing behavior when {{files}} expanded to multiple paths.

    gomod_tidy now runs on .go changes (@sahidvelji) #1236. Broadened the glob to **/*.go, **/go.mod, and **/go.sum so the common drift (editing an import) is caught at commit time, and its go.mod/go.sum updates are now staged when triggered by a Go change (@jdx) #1240.

    Partial diff fixes no longer pass silently (@jdx) #1245. Enabled check_after_diff for rumdl, ryl, ryl_markdown, zizmor, and pinact_v3, so remaining violations surface after hk applies each partial patch.

    Workspace paths in literal dir steps (@jdx) #1242. {{workspace}} and {{workspace_indicator}} are now rendered relative to a literal step directory, preventing duplicated paths like ui/ui/tsconfig.json in subprojects. Addresses discussion #1233.

    Windows command shims (@jdx) #1221. Structured argv steps now resolve .cmd/.bat targets (including npm node_modules/.bin shims) via the effective PATH/PATHEXT and run them through cmd.exe with argument-boundary-preserving escaping. Fixes discussion #1220.

    Empty pathspec stashes (@jdx) #1283. Pre-commit runs no longer reset the index and leave an orphaned stash when a path-limited stash has no HEAD-to-worktree diff (e.g. mode-only staged changes). Addresses discussion #1281.

    New Contributors

    @sahidvelji made their first contribution in #1218

    Full Changelog: v1.56.1...v1.57.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    AI-assisted — Tool: Codex; model: openai/gpt-5; version: unavailable.

    Original source
  • Aug 30, 2026
    • Date parsed from source:
      Aug 30, 2026
    • First seen by Releasebot:
      Aug 30, 2026
    jdx logo

    hk by jdx

    chore: release v1.57.0 (#1223)

    hk releases v1.57.0 with new builtins and step-engine improvements, plus Go, shellcheck, Pkl, stash, and Windows path fixes. It also refreshes CLI metadata, docs, and release packaging with no runtime logic changes.

    Features

    • (builtins) add go_fix linter by @sahidvelji in #1224
    • (builtins) add ls_lint linter by @sahidvelji in #1238
    • (builtins) add golangci_lint_fmt formatter by @sahidvelji in #1244
    • (builtins) add shellcheck fix via check_diff by @sahidvelji in #1237
    • (pkl) embed the matching-version pkl package by @sahidvelji in #1218
    • (step) render dir through tera by @sahidvelji in #1219
    • (step) recheck applied diffs by @jdx in #1243
    • (step) allow configured command failures by @jdx in #1291

    Bug Fixes

    • (builtins) repair Go linters that report success on bad code by @sahidvelji in #1225
    • (builtins) broaden gomod_tidy glob to run tidy on .go changes by @sahidvelji in #1236
    • (builtins) stage gomod_tidy manifest updates by @jdx in #1240
    • (builtins) recheck partial diff fixes by @jdx in #1245
    • (builtins) correct gitleaks scan modes by @jdx in #1248
    • (stash) skip empty pathspec stashes by @jdx in #1283
    • (step) resolve Windows command shims by @jdx in #1221
    • (step) relativize workspace paths to step directory by @jdx in #1242

    Documentation

    • clarify subproject monorepo setup by @jdx in #1239
    • improve onboarding and navigation by @jdx in #1247
    • disable code ligatures by @jdx in #1264
    • publish llms.txt index by @jdx in #1272

    Security

    • add sponsor logos to readme by @jdx in #1250

    Other Changes

    • (ci) adopt mbx for Rust builds by @jdx in #1229
    • (ci) restrict trusted mbx runs to jdx by @jdx in #1254
    • (ci) isolate mbx OIDC permissions by @jdx in #1258
    • (ci) compare mbx with rust-cache by @jdx in #1267
    • (ci) adopt mbx 0.5.4 by @jdx in #1279
    • (ci) pin mr-boxington-action v1.0.1 by @jdx in #1280
    • (ci) use default Rust for cache benchmark by @jdx in #1284
    • (ci) bump mr-boxington action by @jdx in #1282
    • (ci) use server cache for dispatched benchmarks by @jdx in #1285
    • (ci) adopt mbx 0.7.0 by @jdx in #1286
    • (sponsors) replace 37signals with omacom foundation by @jdx in #1249
    • generate release notes before publishing by @jdx in #1227
    • automate generated cli versions by @jdx in #1252
    • seed mbx cache for fork PRs by @jdx in #1262
    • notarize the macOS release binary by @jdx in #1266
    • benchmark mbx against rust-cache on Linux by @jdx in #1275
    • remove pinned rust toolchain by @jdx in #1235
    • back mbx with the GitHub Actions cache alone by @jdx in #1287

    Dependency Updates

    • update rust crate pklr to v1.5.0 by @renovate[bot] in #1222
    • lock file maintenance by @renovate[bot] in #1226
    • bump usage to 6.4.0 by @jdx in #1228
    • update anthropics/claude-code-action action to v1.0.194 by @renovate[bot] in #1230
    • update jdx/mise-action action to v4.2.5 by @renovate[bot] in #1231
    • update rust crate demand to v2.1.0 by @renovate[bot] in #1241
    • update anthropics/claude-code-action action to v1.0.195 by @renovate[bot] in #1251
    • update rust crate pklr to v1.5.1 by @renovate[bot] in #1260
    • bump usage to 6.4.1 by @jdx in #1273
    • bump tak and mbx by @jdx in #1274
    • remove rust toolchain pins by @jdx in #1276

    New Contributors

    • @sahidvelji made their first contribution in #1237

    Note

    Low Risk

    Mechanical version and documentation URL updates with no runtime code changes in the diff.

    Overview

    Cuts release v1.57.0 by bumping the hk crate and CLI metadata from 1.56.1 to 1.57.0 (Cargo.toml, Cargo.lock, hk.usage.kdl, generated CLI docs).

    Adds the [1.57.0] CHANGELOG entry (features, fixes, CI/release work, and dependency updates since 1.56.1) and updates every Pkl amends / import package URL in README, docs, examples, and hk-example.pkl to point at the new GitHub release artifacts.

    No application logic changes in this diff; it packages already-merged work. Notable themes called out in the new changelog include new builtins (go_fix, ls_lint, golangci_lint_fmt, shellcheck fix), step-engine improvements (Tera dir, diff recheck, optional command failures), embedded matching-version Pkl, and assorted builtin/stash/Windows path fixes.

    Reviewed by Cursor Bugbot for commit 57fec76. Bugbot is set up for automated code reviews on this repo. Configure here.

    Co-authored-by: mise-en-dev [email protected]

    Original source
  • All of your release notes in one feed

    Join Releasebot and get updates from jdx and hundreds of other software products.

    Create account
  • Aug 23, 2026
    • Date parsed from source:
      Aug 23, 2026
    • First seen by Releasebot:
      Aug 23, 2026
    jdx logo

    hk by jdx

    v1.56.1: Maintenance release

    hk releases a small maintenance update with a documentation site layout fix and internal cleanup. It improves the docs banner and mobile layout, while keeping user-facing behavior unchanged.

    A small maintenance release with a documentation-site layout fix and internal maintenance. There are no user-facing changes to hk's behavior.

    Fixed

    Documentation site layout (@jdx) #1213. Fixed a navbar layout jump when the docs announcement banner loads after hydration, enlarged the banner dismiss target for mobile, and prevented horizontal overflow of the homepage feature cards on narrow (~320px) screens.

    Changed

    Bumped the expr-lang dependency to v2.1.0 (@renovate) #1217, and reworked the CLI parsing internals (#1211). These are internal changes with no intended effect on existing configs or commands.

    Full Changelog: v1.56.0...v1.56.1

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Aug 19, 2026
    • Date parsed from source:
      Aug 19, 2026
    • First seen by Releasebot:
      Aug 19, 2026
    jdx logo

    hk by jdx

    v1.56.0: Offline Pkl evaluation and configurable output

    hk adds a persistent Pkl package cache with offline evaluation, pinact v4 support, configurable failed-command logging, and fixes for binary files, worktree handling, annotated tags, and step conditions. It also includes a breaking change for some builtin prefixes.

    This release adds a persistent Pkl package cache with offline evaluation, pinact v4 support, a configurable failed-command output file, and a handful of fixes for binary files, builtin argument handling, worktrees, annotated tags, and step conditions.

    Added

    Persistent Pkl package cache and offline mode (@jdx) #1199. Pkl packages are now persisted (by default under the platform cache directory as pklr), so a package downloaded during any prior evaluation stays available even after hk's resolved-config cache is invalidated by a config edit, upgrade, or cache cleanup. This prevents local commits from being blocked when a registry is unreachable. Two new environment variables control the behavior: HK_PKL_CACHE_DIR overrides the cache location, and HK_PKL_OFFLINE=1 disables all network access, failing fast with the missing package URL and cache path instead of hitting the network. Both are read from the environment before hk.pkl is evaluated. Addresses discussion #1198.

    pinact v3 and v4 builtins (@risu729) #1195. The pinact and pinact_update builtins now track the latest major version (currently v4.1.1) and use the v4-native --verify-comment flag. New pinact_v3 and pinact_update_v3 alternatives are available for projects still on pinact v3, without requiring changes to step names.

    // pinact v4 (default)
    ["pinact"] = Builtins.pinact
    // pinact v3
    ["pinact"] = Builtins.pinact_v3
    

    Configurable failed-command output file (@signadou) #1204. The full output of failed commands is written to a log file whose location can now be set with HK_OUTPUT_FILE. It defaults to ~/.local/state/hk/output.log, and nested paths are created as needed. Closes #1201.

    allow_binary step option in Pkl (@jdx) #1190. The allow_binary step option is now declared in the Step schema, so configs can opt into processing binary files (which are filtered out by default). The Rust file filter already honored the flag, but there was previously no valid way to set it from hk.pkl. Addresses discussion #1189.

    Fixed

    Preserve file argument boundaries in builtins (@jdx) #1194. Around 100 additional builtins (including ruff_format) were migrated from shell-string commands to structured argv lists so file paths keep their literal argument boundaries and compose cleanly with list prefix values. Shell-dependent builtins (pipes, redirects, substitutions, loops) are intentionally left as shell strings. Relates to discussion #1174. See Breaking Changes below.

    Scoped steps in linked worktrees (@jdx) #1200. When Git supplied only GIT_DIR, nested Git commands in scoped subproject steps treated the step's subdirectory as the worktree root, misaligning index paths with filesystem paths. hk now sets GIT_WORK_TREE to the resolved repository root and preserves GIT_INDEX_FILE, so scoped steps continue to inspect the index being committed. Fixes #1138.

    Pushing annotated tags through pre-push (@jdx) #1197. Pushing an annotated tag failed because its OID identifies a tag object, which libgit2's merge-base calculation rejects. hk now peels both ends of a ref range to commits before computing merge bases and trees. Fixes discussion #1196.

    Step condition compatibility with expr v2 (@jdx) #1212. Upgrading the expression engine to expr-lang v2 would have rejected raw newlines inside quoted condition strings that v1 accepted (Pkl decodes \n before hk evaluates a condition). A compatibility layer now escapes raw CR/LF characters only inside interpreted quoted strings, leaving backtick strings, comments, and escapes untouched, so existing step and job conditions keep working.

    Breaking Changes

    Builtins migrated to structured argv in #1194 now require list-form prefixes instead of shell-string prefixes:

    prefix = List("mise", "x", "--")
    

    New Contributors

    @signadou made their first contribution in #1204

    Full Changelog: v1.55.0...v1.56.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Aug 11, 2026
    • Date parsed from source:
      Aug 11, 2026
    • First seen by Releasebot:
      Aug 13, 2026
    jdx logo

    hk by jdx

    v1.55.0: Agent-native hk

    hk ships a major agent-friendly release with an MCP server, interactive dashboard, machine-readable JSON and JSONL output, safer command effects, normalized diagnostics with SARIF export, and ready-to-paste integration snippets for popular agents and editors.

    This release turns hk into a first-class tool for coding agents, adding an MCP server, an interactive dashboard, structured and machine-readable output, command effect safety, normalized diagnostics with SARIF export, and one-command integration snippets for popular agents and editors. It also adds a Kingfisher secret-scanner builtin and fixes a couple of file-selection and command-composition bugs.

    Highlights

    A complete agent-native workflow: drive hk from anywhere with --cd/--files0-from, get machine-readable results via --format json|jsonl, gate risky steps with --safe, export findings as SARIF, and expose everything to agents over MCP with a live dashboard.

    New hk agent command tree prints ready-to-paste instruction, hook, and MCP setup snippets for Codex, Claude Code, Claude Desktop, and VS Code.

    Added

    MCP server for coding agents (@jdx) #1169. hk mcp [--root <path>] starts a STDIO-only Model Context Protocol server built on the official Rust MCP SDK. Agents can inspect projects, read effect-aware execution plans, run all-or-nothing safe checks and fixes, poll run lifecycle, cancel runs, and page through logs and captured diffs. Tools are constrained to canonical startup roots plus client-provided roots, with one active run per root and bounded output/run retention. There is no HTTP listener, hosted service, auth system, or unrestricted shell tool.

    hk mcp --root /path/to/project

    Interactive MCP dashboard (@jdx) #1170. A self-contained Preact dashboard is embedded as an MCP App resource, showing live overall and per-step activity, timing, diagnostics, searchable logs, and diffs, with cancel, rerun, and explicitly confirmed safe-fix actions. Hosts without UI support fall back to structured content plus text.

    Coding-agent integration snippets (@jdx) #1171. A read-only hk agent command prints instruction, hook, and MCP setup snippets for Codex, Claude Code, Claude Desktop, and VS Code. Generators only print to stdout — they never install hooks or edit host configuration. A new /agents documentation page describes the safe agent workflow, the dashboard, and ChatGPT Desktop tunneling.

    hk agent mcp codex # print MCP config snippet for Codex

    hk agent hooks vscode # print a VS Code hook snippet

    Agent-friendly execution scoping (@jdx) #1162. A global --cd <DIRECTORY> re-executes hk in the chosen project without mutating process cwd, and --files0-from <PATH|-> selects an exact NUL-delimited file list from a file or stdin. --files0-from conflicts with positional files, --all, --glob, --pr, ref ranges, --staged, and --unstaged; pre-push and post-rewrite reject - since those hooks read the Git hook protocol from stdin.

    Structured execution results (@jdx) #1163. A new --format human|json|jsonl flag (default human) makes hook runs emit versioned machine-readable results. json writes a single run_result document with per-step status, timing, output, and skip reasons; jsonl streams ordered lifecycle events (run_started, run_planned, step_started/step_completed, run_completed). Structured formats own stdout; progress, logs, and tracing move to stderr. The existing --json flag continues to work.

    Command effect safety with --safe (@jdx) #1166. Step commands can now declare a read, write, or destructive effect via CommandSpec (for shell, OS-specific, and argv commands). Passing --safe runs an all-or-nothing preflight that permits read/write steps and rejects destructive and unknown-effect steps before anything runs. Legacy string commands are treated as unknown effect and only require an explicit CommandSpec when --safe is used. Declared effects appear in execution plans and structured results.

    Effect classification for all builtins (@jdx) #1167. Every command across the builtin catalog (236 command fields over 144 modules) now declares an effect: read for typical linters and format checks, write for fixers and checks that compile, sync, or populate caches. No builtins are marked destructive, so builtins work under --safe out of the box. Overriding a builtin command with a bare string correctly downgrades it to unknown effect rather than inheriting the builtin's claim.

    Normalized diagnostics and SARIF export (@jdx) #1168. Steps can opt into structured diagnostics with diagnostic_format (sarif, cargo-json, eslint-json, gcc) and optional diagnostic_tool. Output is parsed into a shared diagnostic model (severity, path, range, rule, help URL, optional fix), deduplicated, and preserved alongside raw output in JSON/JSONL results. A new --sarif <PATH> flag exports a standard SARIF 2.1.0 report from check, fix, run, and hook commands regardless of the selected output format. Malformed input surfaces a parse warning and never drops the raw command output.

    Kingfisher secret-scanner builtin (@thoroc) #1160. Adds a builtin for MongoDB's Kingfisher secret scanner, installable through mise.

    Fixed

    Structured commands accept argv prefixes (@jdx) #1175. After the builtin argv migration, configs that inherited a builtin and supplied a string prefix stopped loading. prefix now accepts either a shell string (for shell commands) or an explicit argv list, so structured commands and argv builtins like Builtins.ruff can run through launchers such as mise x -- without losing argument boundaries. Argv prefixes reject file-list placeholders and can be inherited by groups; cross-mode combinations are rejected. Closes discussion #1174.

    ["ruff"] = (Builtins.ruff) {
    prefix = List("mise", "x", "--")
    }
    

    Deleted paths excluded from ref-scoped checks (@jdx) #1177. The libgit2 backend used Path::exists() to distinguish live from deleted paths, so on case-insensitive filesystems the old spelling of a case-only rename was passed to steps alongside the new one. Deleted diff deltas are now skipped, matching the shell-Git backend's --diff-filter behavior. Fixes discussion #1176.

    New Contributors

    @thoroc made their first contribution in #1160

    Full Changelog: v1.54.1...v1.55.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Similar to hk with recent updates:

  • Aug 7, 2026
    • Date parsed from source:
      Aug 7, 2026
    • First seen by Releasebot:
      Aug 9, 2026
    jdx logo

    hk by jdx

    v1.54.1: Bug fixes for stashing, Ruff, and conventional commits

    hk ships a small patch release focused on bug fixes across stashing, builtins, config error handling, and conventional commit validation, with clearer guidance for index lock conflicts and better handling for Python scripts and autosquash commits.

    A small patch release focused on bug fixes across stashing, builtins, config error handling, and conventional-commit validation.

    Fixed

    Fixer output preserved with stage=false / fail_on_fix=true (@jdx) #1145. When smart stashing was combined with disabled auto-staging, stash restoration used the post-hook index as the fixer side of its three-way merge. Since the fixer only touched the isolated worktree in that mode, restoration saw no change and silently discarded the formatter output. hk now uses worktree content as the fixer input, merges it with the user's saved unstaged edits, and leaves the original index untouched. Fixes discussion #1144.

    Ruff builtins detect extensionless Python scripts (@jdx) #1147. The ruff and ruff_format builtins previously matched files only with **/*.py and **/*.pyi globs. They now select files using hk's Python type detection, so extensionless scripts with a Python shebang are linted and formatted alongside .py and .pyi files. Fixes discussion #1146.

    Autosquash commit prefixes accepted by conventional-commit check (@smasato) #1142. hk util check-conventional-commit rejected the temporary commits created by git commit --fixup/--squash (and --fixup=amend), breaking git rebase --autosquash when check_conventional_commit was installed as a commit-msg hook. Titles starting with fixup! , squash! , or amend! are now skipped, matching commitlint's default behavior. A bang without a trailing space (fixup!chore: ...) is still validated. Requested in discussion #902.

    min_hk_version errors no longer panic (@smasato) #1143. When min_hk_version in hk.pkl was newer than the running hk, the error surfaced through a Rust panic (aborting with SIGABRT when triggered from a git hook). Config-load errors now propagate cleanly with exit code 1 and readable context instead of a backtrace.

    Clearer guidance for git index lock conflicts (@jdx) #1140. When a failed step's output references Git's index.lock, hk now prints a single end-of-run hint (suppressed with --silent) pointing to exclusive = true, depends, or separate groups, rather than leaving users with Git's generic lock error. Documentation now steers authors toward stage for hk-owned staging and exclusive for legacy commands that write the index directly. Addresses discussion #1139.

    Full Changelog: v1.54.0...v1.54.1

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jul 31, 2026
    • Date parsed from source:
      Jul 31, 2026
    • First seen by Releasebot:
      Jul 31, 2026
    jdx logo

    hk by jdx

    v1.54.0: 17% smaller, up to 31% faster

    hk releases v1.54.0 with a leaner, faster Linux binary and smarter check workflows. It adds focused diagnostics for failing files, declares command effects in usage docs, speeds mixed-line-ending and check-merge-conflict checks, and fixes noise and false errors in a few builtins.

    17% smaller, up to 31% faster

    Compared with v1.53.0, the published x86_64-unknown-linux-gnu release is substantially leaner and faster:

    Measurement
    v1.53.0
    v1.54.0
    Improvement
    Compressed archive
    8.19 MB
    7.06 MB
    13.8% smaller
    Extracted binary
    22.01 MB
    18.27 MB
    17.0% smaller
    Startup (--version)
    2.21 ms
    1.52 ms
    31.2% faster
    Builtins loading
    2.31 ms
    1.62 ms
    29.8% faster
    Config validation
    3.69 ms
    2.94 ms
    20.3% faster
    Representative check --all
    14.62 ms
    13.47 ms
    7.8% faster

    Measurements use the published release binaries with hermetic state, warm caches, shell overhead excluded, and execution pinned to one CPU. Real hook runs dominated by external linters will see a smaller overall percentage.

    This release adds an opt-in way to focus detailed check diagnostics on only the files that actually failed, teaches hk's usage spec to declare each command's effect on the world, and speeds up the mixed-line-ending and check-merge-conflict builtins along with a new PGO/BOLT-optimized Linux release binary. It also fixes noise and false errors in a couple of builtins.

    Added

    Focus checks on failing files (@jdx) #1123. A new opt-in check_failed_files step setting runs a file-listing command (check_list_files or check_diff) over the whole job first, then runs the detailed check only on the paths it reports as failing. This keeps a checker's full diagnostics available without passing every file in a large repository to the second invocation. When enabled, hk requires check plus at least one of check_diff/check_list_files (validated at hk validate time), keeps the listing failure authoritative if the focused check unexpectedly succeeds, and still applies automatic argument-limit batching to the narrowed file set. Addresses discussion #1122.

    ["my-linter"] {
    glob = List("**/*.py")
    check_list_files = "my-linter --list-failing-files {{files}}"
    check = "my-linter check {{files}}"
    fix = "my-linter fix {{files}}"
    check_failed_files = true
    }
    

    Command effect declarations (@jdx) #1121. Every hk command's usage spec now declares whether it only reads state, modifies it, or is destructive (e.g. uninstall, which removes files from .git/hooks). check, fix, run, and test are deliberately left unclassified because they execute arbitrary steps from hk.pkl — hk cannot promise what those do. Command reference pages now show an Effect line for each command.

    Fixed

    tombi-format no longer prints noise on clean runs (@jdx) #1117. tombi format printed a "file did not need formatting" summary to stderr even when nothing changed, which hk surfaced after an otherwise clean run. hk now passes --quiet to both the check and fix commands, suppressing only the summary while still showing the diff and error on failure. Fixes discussion #1116.

    oxlint no longer errors on unmatched patterns (@CallumKerson) #1119. The oxlint builtin now tolerates glob patterns that match no files, matching the behavior already used for the biome builtin.

    Performance

    Faster mixed-line-ending and check-merge-conflict (@astei) #1115. Both builtins now use the memchr crate for fast byte scanning instead of iterating byte-by-byte, with the mixed-line-ending fix path doing block copies instead of a per-byte rewrite. Benchmarks show up to ~2.5x faster checks and ~2.2x faster fixes on large files, with neutral-to-positive impact on small ones.

    PGO/BOLT-optimized Linux binary (@jdx) #1136. The x86_64-unknown-linux-gnu release artifact is now built through a profile-guided optimization and BOLT layout pipeline trained on representative Pkl/Git/check workloads. Alongside this, the release binary is stripped and slimmed (narrower Tokio/xx features, panic = "abort"), and the Tokio runtime now caps worker threads at 16.

    New Contributors

    @astei made their first contribution in #1115

    Full Changelog: v1.53.0...v1.54.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    AI-assisted — Tool: Codex; model: openai/gpt-5; version: unavailable.

    Original source
  • Jul 23, 2026
    • Date parsed from source:
      Jul 23, 2026
    • First seen by Releasebot:
      Jul 24, 2026
    jdx logo

    hk by jdx

    v1.53.0: Faster config loading and safer stashing

    hk adds a built-in cargo-deny check, speeds up config resolution and hook runs in large repos, and fixes dependency graph and stash bugs. It also hardens Git invocations against argument injection for safer, more reliable hook execution.

    This release adds a cargo-deny builtin, meaningfully speeds up config resolution and hook runs in large repos, and fixes two correctness bugs around dependency graphs and stashing. It also hardens hk's Git invocations against argument injection.

    Added

    cargo_deny builtin (@risu729) #1081. Runs cargo-deny for Rust dependency policy checks (advisories, bans, licenses, sources). It triggers on Cargo.toml, Cargo.lock, and deny.toml/.deny.toml (including .cargo/ and exceptions variants), groups executions by Cargo workspace and runs from the workspace directory, and uses --locked so checks never create or update Cargo.lock.

    ["cargo_deny"] = Builtins.cargo_deny

    Fixed

    Dependents no longer hang after a failed dependency (@jdx) #1099. With fail_fast = false, a failed step returned without marking its dependency watch channel as done, so any step with depends on it waited forever and the run hung. The failed step now signals its dependents so they can proceed. fail_fast = true behavior is unchanged. Fixes discussion #1098.

    No stashing when a hook has no steps to run (@jdx) #1106. When a hook resolved to zero steps but the worktree had unstaged or untracked changes, hk stashed them and returned early — before the restore ran — leaving a dangling stash and a stripped working tree (each retry piling on another stash). The "no steps to run" guard now runs before any side effects, so there is nothing to stash. Stash-restore failures also now report the ~/.local/state/hk/patches/*.patch backup path for manual recovery. Fixes #1105.

    Changed

    Hardened Git invocations against argument injection (@sshine) #1101. hk now passes --end-of-options before untrusted revisions in merge-base, rev-parse, ls-tree, and diff ranges, and replaces ls-remote shell interpolation with an argv invocation. This prevents repo-config-controlled refs (hk.pkl default_branch, --from-ref/--to-ref) and hyphen-prefixed branch names from being misread as options. Note: rev-parse --end-of-options requires Git 2.30+.

    Performance

    Resolved config cached in-process (@mharris-figma) #1104. Each Config::get() previously re-applied subprojects and user config, re-validated, and cloned on every call. Since hk runs one command against one project, the resolved config is now built once per process (callers still get clones). A warm-cache hk validate benchmark against a large config improved 46% (102.60 ms to 55.21 ms).

    Final status snapshot skipped outside debug logging (@mharris-figma) #1102. The final Git status scan is only used for debug diagnostics, but hk was running a full repository scan at every log level and discarding it. It's now gated behind debug logging. A no-op benchmark over a 6,156-file repo with 4,000 modified files improved ~40% on both backends (libgit2: 221 ms to 131 ms; shell Git: 223 ms to 136 ms). Status reads used for file selection, stashing, and hook behavior are unchanged.

    New Contributors

    @mharris-figma made their first contribution in #1104

    Full Changelog: v1.52.0...v1.53.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jul 21, 2026
    • Date parsed from source:
      Jul 21, 2026
    • First seen by Releasebot:
      Jul 22, 2026
    jdx logo

    hk by jdx

    v1.52.0: Monorepo subprojects and working-tree linting

    hk adds monorepo support with nested subproject configs and per-directory mise environments, plus a new --unstaged mode for linting only working-tree changes. It also brings a Markdown formatter and several correctness fixes for branch guards, empty remotes, commit scopes, and version messages.

    This release brings hk to monorepos with nested subprojects configs and per-directory mise environments, adds a --unstaged flag for linting only working-tree changes, and ships a batch of correctness fixes for branch guards, empty remotes, and conventional commit scopes.

    Added

    subprojects for monorepos (@jdx) #1094

    The root hk.pkl can list literal directories or globs, and each subproject's own hk.pkl is merged into the root run scoped to its directory. Step working directories and glob matching are relative to the subdirectory, flat step names are prefixed with <dir>: (e.g. packages/web:eslint) for --step/skip_steps, and a subproject's env applies only to its own steps. Paired with this, HK_MISE=1 now resolves mise env --json per step dir, so subproject-local tools land on PATH — including for structured argv commands.

    // hk.pkl (repo root)
    subprojects = List("frontend", "packages/*")
    
    // frontend/hk.pkl
    hooks {
      ["check"] {
        steps { ["eslint"] = (Builtins.eslint) { batch = true } }
      }
    }
    

    --unstaged flag (@jdx) #1093

    Available on hk check, hk fix, and hk run <hook>, this selects only unstaged and untracked files (excluding staged files) without stashing — the strict inverse of --staged. It's aimed at agent-stop hooks that need to lint just the files an AI agent touched in the working tree. Conflicts with --staged, --all, --files, --from-ref/--to-ref, --glob, --pr, and --stash.

    rumdl_format builtin (@risu729) #1080

    Adds a dedicated Markdown formatter using rumdl fmt --check --diff / rumdl fmt, separate from the existing rumdl linter, mirroring the linter/formatter split hk already uses for ruff, taplo, and tombi.

    ["rumdl_format"] = Builtins.rumdl_format
    

    Fixed

    Branch guard allows detached HEAD (@jdx) #1075

    The no_commit_to_branch guard treated git symbolic-ref exiting nonzero as fatal, blocking commits created during operations like interactive rebase where HEAD is detached. It now treats a detached HEAD as "not on a protected branch" while still surfacing genuine Git errors. Fixes discussion #1074.

    Pre-push works against an empty remote (@sshine) #1090

    When a pre-push hook runs before the first push, the unresolvable base ref no longer fails the run; hk falls back to listing all files at the target ref. This is @sshine's first contribution.

    hk util skips config loading (@jdx) #1078

    Builtins like trailing-whitespace shell out to hk util, and each child was loading project and user Pkl config it never used. Utility commands now run with default settings, avoiding redundant parallel evaluation that was a likely source of intermittent failures under normal concurrency. Fixes discussion #1077.

    mise formatter no longer batches (@risu729) #1079

    The builtin had batch = true even though mise fmt processes project config itself and takes no file arguments, so multiple matched files could launch duplicate whole-project jobs. It now runs once per invocation.

    Conventional commit scope validation (@LordAizen1) #1071

    check-conventional-commit now rejects empty scopes (feat(): ...) and malformed scopes with junk after the closing paren (feat(scope)(x): ...), which the previous check accepted. Valid forms like feat(scope)!: ... still pass. This is @LordAizen1's first contribution.

    min_hk_version error message (@smasato) #1070

    The running and required versions were swapped in the "version is less than the minimum required" error; the message now reports them correctly.

    New Contributors

    @sshine made their first contribution in #1090

    @LordAizen1 made their first contribution in #1071

    Full Changelog: v1.51.0...v1.52.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jul 14, 2026
    • Date parsed from source:
      Jul 14, 2026
    • First seen by Releasebot:
      Jul 16, 2026
    jdx logo

    hk by jdx

    v1.51.0: Structured argv and disjunctive selectors

    hk ships structured argv commands and match_any selectors for safer, more flexible file matching, plus a new sherif builtin for TypeScript and JavaScript monorepos. It also fixes quiet and silent output, hook argument duplication, stash lock waits, and Linux auto-batching limits.

    Two configuration expansions land in this release: shell-free argv commands with per-file argument expansion, and match_any selectors that combine globs and types with OR semantics. Alongside them, correctness fixes for --quiet/--silent, config-based hook argument forwarding, transient index locks, and Linux argument-size limits.

    Added

    Structured argv commands (@jdx) #1067. A step's check/fix/check_list_files/check_diff can now be a Command with an explicit argv list that runs a binary via PATH without a shell. Standalone {{files}} and {{workspace_files}} entries expand to one argument per file (raw paths), so names with spaces or shell metacharacters are passed literally. Auto-batching, hk test, progress output, and fix suggestions all go through shared Command rendering, and many builtins (prettier, ruff, biome, ...) have moved to structured commands. Existing string and platform Script commands are unchanged; structured commands can't be combined with shell or prefix.

    check = new Command {
    argv = List("wc", "-c", "{{files}}")
    }
    

    match_any disjunctive file selectors (@risu729) #1055. Clauses compose with OR semantics; glob and types within a clause compose with AND. match_any cannot be mixed with the top-level glob or types, and empty selectors are rejected at validation time. {{globs}} and progress text reflect the combined patterns. The shellcheck and shfmt builtins have adopted it so they also pick up extensionless shell scripts detected by shebang, without giving up their extension globs.

    ["shellcheck"] {
    match_any = List(
    new { glob = List("**/*.sh", "**/*.bash") },
    new { types = List("sh", "bash") }
    )
    check = "shellcheck {{files}}"
    }
    

    sherif builtin (@smasato) #1062. Adds sherif, the opinionated zero-config linter for TypeScript/JavaScript monorepos. check = "sherif" / fix = "sherif --fix --no-install"; sherif always scans from the repo root, so the commands take no file arguments. Globs cover **/package.json and **/pnpm-workspace.yaml; auto-suggested when "sherif" appears in package.json.

    ["sherif"] = Builtins.sherif
    

    Fixed

    --quiet and --silent really suppress output now (@smasato) #1058. Previously these flags only lowered the log level and switched progress to text mode, which streams every update on a new line rather than hiding anything. They now set ProgressOutput::Quiet so progress lines and successful-step summaries are gone; --quiet still prints failed-step summaries (essential diagnostic), --silent prints nothing but exit code. --stats is suppressed under both. Informational println!s in init/install/migrate were routed through info! so the flags apply there too. CI/non-interactive text-mode behavior is unchanged.

    Config-based hooks no longer duplicate arguments (@jdx) #1065. Git 2.54+ already appends hook arguments to hook.<name>.command, and hk was also expanding "$@", so argument-bearing hooks received every argument twice. For pre-push this meant the duplicated remote/URL were parsed as an explicit file list, which overrode push-range discovery and silently skipped file-filtered steps. hook_run_args no longer appends "$@"; legacy .git/hooks/ shims still use it via git_hook_content. Fixes discussion #1063.

    Stash waits out transient index locks (@jdx) #1060. Shell-based stash paths now resolve the worktree lock via git rev-parse --git-path index.lock and sleep with bounded backoff (up to ~775ms) before running git stash push, so a briefly held lock from another Git process no longer aborts the hook. A persistent lock still surfaces as a normal Git error after the wait window; libgit2 stash_save is unchanged. Fixes discussion #1056.

    Linux per-argument size limit respected in auto-batching (@jdx) #1066. hk passes each rendered command to the shell as one sh -c argument, and Linux limits each argument to 32 pages (~128 KiB) independently of the aggregate ARG_MAX. Batching now caps rendered commands using both the existing ARG_MAX / 2 margin and MAX_ARG_STRLEN, sizes each chunk independently so later, longer paths cannot overflow a batch, and returns a clear error when even a single-file command cannot fit. Fixes discussion #1061.

    Documentation

    Vertically center social link icons on the docs site (@smasato) #1059.

    Full Changelog: v1.50.0...v1.51.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jul 6, 2026
    • Date parsed from source:
      Jul 6, 2026
    • First seen by Releasebot:
      Jul 7, 2026
    jdx logo

    hk by jdx

    v1.50.0: Staged pre-commit, everywhere

    hk ships pre-commit correctness fixes, a new textlint builtin, and a content-addressed config cache, plus documentation updates. It now keeps pre-commit scoped to staged files, handles rename-only commits correctly, and improves config and docs accuracy.

    A cluster of pre-commit correctness fixes so hk run pre-commit (and installed hooks) really only see staged files, plus a textlint builtin, a content-addressed config cache, and a docs accuracy pass.

    Added

    textlint builtin (@smasato) #1036. Adds textlint as a batched natural-language linter for Markdown and plain text. check runs textlint {{ files }}, fix runs textlint --fix {{ files }}, and it auto-suggests when .textlintrc* or a "textlint" entry in package.json is present.

    ["textlint"] = Builtins.textlint

    Fixed

    Pre-commit is staged-only, even without stashing (@jdx) #1023. The default file selection for pre-commit steps now stays scoped to staged paths when stash = false, matching the "only what you're committing" expectation instead of also picking up unstaged and untracked matches.

    Installed global pre-commit hooks pass --staged (@jdx) #1043. hk install --global now generates pre-commit hook commands as hk run pre-commit --from-hook --staged, so an env override like HK_STASH=git can't defeat a repo-level stash = "none" policy. Local config hooks and legacy .git/hooks/ shims are unchanged. Fixes discussion #1030.

    Git string settings actually apply (@jdx) #1042. String, enum, and path settings from git config are now read via Config::get_string, which works on the live config that Repository::config() returns. Previously libgit2 rejected the borrow-returning read, so values like hk.stash silently fell back to defaults even though hk config explain listed git as their source. Fixes discussion #1031.

    Rename-only commits no longer bypass pre-commit (@smasato) #1035. Under the default libgit2 backend, git mv commits were reporting "Fetching staged files (0 files)" and skipping every step, because git2's StatusEntry::path() returns the old path for renamed entries — which no longer exists in the worktree and got filtered out. hk now resolves the new path from the head-to-index delta for INDEX_RENAMED entries. The shell-git porcelain parser is also fixed to consume the trailing original-path field on R/C records instead of misparsing it as another status entry. Regressed since rename detection was enabled in #347.

    check_first prefers check_list_files over check (@risu729) #1038. Restores the pre-#547 ordering for the fix-mode prepass: check_diff -> check_list_files -> check. For steps that define both check and check_list_files, the prepass can now narrow the subsequent fix to just the files that need writes, taking fewer write locks and keeping <JOB_FILES> scoped to files that were actually processed. Normal hk check still prefers check first — this only changes the fix-mode check_first path. Empty platform-specific scripts are also skipped when choosing the check-first command.

    Performance

    Resolved config cache shared by content (@jdx) #1044. When a hk.pkl (and all of its imports) resolves purely from local files, the resolved-config cache now keys off content instead of the absolute config path, so byte-identical configs in different directories share one cache entry. Configs that pull in remote http or package imports keep the previous path-keyed behavior since hk can't hash those.

    Changed

    tera bumped to v2 (#1028).

    Documentation

    Docs accuracy pass (@jdx) #1022. Audits the docs against src/env.rs, settings.toml, and pkl/Config.pkl and fixes the drift. Notably: HK_STASH default is documented as none (not git), patch-file is described as an alias of git, environment_variables.md is reorganized alphabetically with previously undocumented vars added (HK_CACHE, HK_CHECK, HK_CONFIG_DIR, HK_JSON, HK_PKL_BACKEND, HK_PKL_CA_CERTIFICATES, HK_PKL_HTTP_REWRITE, HK_STASH_BACKUP_COUNT, HK_TERMINAL_PROGRESS, HK_TRACE, HK_WALK_IGNORE, HK_WARNINGS, and the env aliases from settings.toml), pkl_introduction.md examples use the real Step class with valid pkl syntax, logging.md uses --plan (not the nonexistent --dry-run) and the correct info default level, and builtin counts move to 140+.

    New vector logo (@jdx) #1041. Replaces the raster hook illustration with a stroke-based "hk" wordmark whose descender curls into a fishing hook, plus a bare hook glyph for the navbar and favicons. Scales cleanly down to 16px and to monochrome.

    Full Changelog: v1.49.0...v1.50.0

    💚 Sponsor hk

    hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jul 1, 2026
    • Date parsed from source:
      Jul 1, 2026
    • First seen by Releasebot:
      Jul 3, 2026
    jdx logo

    hk by jdx

    v1.49.0: More builtins, a stash tail-deletion fix

    hk adds three new builtin linters, tighter text-only file matching, and a three-way merge fix that preserves fixer deletions during overlapping edits. It also brings a faster RuboCop server mode, a new shellharden builtin, broader ryl config detection, and updated bundled tools.

    Three new builtin linters, tighter file matching for text-only hooks, and a three-way merge fix that stops fixer tail deletions from being dropped when a worktree edit overlaps their start.

    Added

    rubocop_server builtin (@andyw8) #995. A sibling of Builtins.rubocop that passes --server to check, check_list_files, and fix, running RuboCop as a long-lived daemon for much faster repeat invocations.

    ["rubocop"] = Builtins.rubocop_server
    

    shellharden builtin (@hituzi-no-sippo) #996. Adds shellharden as a batched bash/sh linter. check runs shellharden --check (exit code 2 on suggested changes); fix runs shellharden --replace. Auto-suggested when *.sh or *.bash files are present.

    More ryl project indicators (@hituzi-no-sippo) #998. The ryl builtin now also discovers configs at .config/.ryl.toml, .config/ryl.toml, and pyproject.toml (when it contains a [tool.ryl] table), matching ryl's own upward search. The bundled ryl tool stub bumps to 0.20.0.

    Changed

    Text-only builtins use types = List("text") (@hituzi-no-sippo) #997. Replaces glob = "**/*" with a text-type filter for builtins that only make sense on text files: byte_order_marker, check_executables_have_shebangs, check_merge_conflict, detect_private_key, dprint, fix_smart_quotes, mixed_line_ending, newlines, trailing_whitespace, and typos. check_added_large_files, check_case_conflict, and check_symlinks intentionally keep the everything-matcher since they're meaningful for binaries too.

    pklr bumped to 1.1.1 (@jdx) #1018, and Renovate no longer waits out the shared release-age delay for pklr updates (#1017), so fixes in the embedded pkl evaluator land in hk sooner.

    itertools updated to 0.15 (#1014).

    Fixed

    Fixer tail deletions no longer get dropped when a worktree edit overlaps the start (@jdx) #990. In the three-way merge, a pure-deletion fixer hunk whose start was consumed by a worktree hunk was skipped entirely, causing trailing lines the fixer wanted to remove to reappear in the merged output. three_way_merge_hunks now trims such hunks to the current index and keeps the unconsumed tail. Includes a regression test for discussion #988. If you saw stash = "patch-file" restoring lines a fixer had deleted, this is the fix.

    betterleaks builtin test uses a still-detected fixture (@risu729) #1006. Since betterleaks 1.2.0, aws-access-token is a composite rule that requires a nearby secret key, so the old AWS-only fixture no longer failed the scanner. The test now uses a github-pat sample that still trips ≥1.2.0, and the bundled betterleaks stub moves to 1.5.0.

    Documentation

    Link to all sponsors (@jdx) #991.

    Clarify contribution fit in the contributing guide (@jdx) #992.

    New Contributors

    @risu729 made their first contribution in #1006

    @andyw8 made their first contribution in #995

    Full Changelog: v1.48.0...v1.49.0

    💚 Sponsor hk

    hk is developed by @jdx at en.dev — a small independent studio behind developer tools like mise, aube, hk, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at en.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jun 11, 2026
    • Date parsed from source:
      Jun 11, 2026
    • First seen by Releasebot:
      Jun 16, 2026
    jdx logo

    hk by jdx

    v1.48.0: Group inheritance and builtin polish

    hk adds inherited group defaults for child steps, a new aqua checksum builtin, broader RuboCop file matching, and a pklr validation fix for inline group configs, making lint and hook setup smoother and more consistent.

    Groups can now define defaults that child steps inherit, plus a new aqua checksum builtin, expanded RuboCop file matching, and a pklr fix for inline group configs.

    Added

    Inherit step settings from groups (@RobertDeRose) #982. A Group can now set dir, prefix, workspace_indicator, shell, stage, and exclude, and child steps inherit any field they don't define themselves. Override semantics are simple: a child value fully replaces the group value, never merges.

    local frontend = new Group {
      dir = "packages/frontend"
      prefix = "mise x --"
      steps {
        ["prettier"] = (Builtins.prettier) { batch = true }
        ["eslint"] = (Builtins.eslint) {
          dir = "different/path" // overrides the group dir
          batch = true // still inherits prefix
        }
      }
    }
    

    aqua_update_checksum builtin (@hituzi-no-sippo) #977. A fix-only step that runs aqua update-checksum --prune whenever your aqua config or checksum files change, keeping aqua-checksums.json up to date and pruning unused entries.

    Changed

    ryl and ryl_markdown switch to check_diff (@hituzi-no-sippo) #978. Both builtins now run ryl --diff for check, surfacing exactly which YAML edits the linter wants to make. They also pick up project indicators (ryl.toml, .ryl.toml, .yamllint*) so the builtins are auto-suggested, and the bundled ryl tool stub moves to 0.15.0.

    RuboCop builtin file filter mirrors RuboCop's defaults (@hituzi-no-sippo) #969. Replaces the types = List("ruby") matcher with the explicit glob list from RuboCop 1.87.0's default config, covering .rb, .gemspec, .rake, Gemfile, Rakefile, Vagrantfile, and friends, and applies RuboCop's default excludes (node_modules/, tmp/, vendor/, .git/). The bundled rubocop stub bumps to 1.87.0.

    Fixed

    pklr validation of inline new Group entries (@jdx) #983. Bumps pklr to 1.0.6, which fixes validation of Mapping<String, Step | Group> properties initialized with new Mapping<String, Step> {} — the shape used by hk's default hook config. Configs with inline new Group { ... } step entries no longer fail under the default pklr backend. Refs #981.

    New Contributors

    @RobertDeRose made their first contribution in #982

    Full Changelog: v1.47.0...v1.48.0

    💚 Sponsor hk

    hk is developed by @jdx at en.dev — a small independent studio behind developer tools like mise, aube, hk, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at en.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • Jun 9, 2026
    • Date parsed from source:
      Jun 9, 2026
    • First seen by Releasebot:
      Jun 9, 2026
    jdx logo

    hk by jdx

    v1.47.0: pklr by default, sturdier stash restores

    hk adds the embedded pklr config backend by default, removing the need for the pkl CLI, and improves reliability with stash, merge-base, and Windows batching fixes. It also adds new builtins like ryl, ryl_markdown, hk_test, and a sponsor command.

    hk now ships with the built-in pklr evaluator as the default config backend — no pkl CLI required — plus three stash, merge-base, and Windows batching fixes that close out reported regressions, and a handful of builtin improvements from @hituzi-no-sippo.

    Added

    pklr is now the default pkl backend (@jdx) #976. hk.pkl is evaluated with the embedded pklr interpreter out of the box, so the Apple pkl CLI is no longer required to use hk. The CLI backend is still available via HK_PKL_BACKEND=pkl; unrecognized values now warn and fall through to pklr. The config cache also switched from mtime comparisons to hashing file contents, so edits to imported .pkl files reliably invalidate the cache.

    # Default (no setup required)
    hk check
    # Opt back into the pkl CLI
    HK_PKL_BACKEND=pkl hk check
    

    ryl builtin gains fix and check_list_files (@hituzi-no-sippo) #967. Bumps the underlying ryl to v0.13.0 and wires in the new commands. The yamllint config dependency is dropped.

    ryl_markdown builtin (@hituzi-no-sippo) #968. Lints YAML embedded inside Markdown documents using ryl's markdown support.

    hk_test builtin (@hituzi-no-sippo) #973. Runs hk test --quiet whenever your hk configuration file changes so step-defined inline tests catch regressions automatically.

    hk sponsors command (@jdx) #961. A small no-config subcommand that prints the projects and companies sponsoring hk and the en.dev project family. Works without hk.pkl.

    Fixed

    Last-line edits of partially-staged files no longer get corrupted on restore (@ad1269) #966. The "pure tail insertion" special case in the manual stash restore had a newline-tolerant fallback that stripped the index snapshot's trailing newline before the prefix check, so a last-line edit like l3: tail → l3: tail UNSTAGED was misclassified as a tail insertion and re-emitted as fixer content + " UNSTAGED\n". The fallback now only accepts an empty remainder (the original case from #304); real last-line edits fall through to the three-way merge, which handles them correctly. The recovery patch written under the state dir also restores the trailing newline that cmd.read() strips, so git apply --check no longer fails with corrupt patch at line N. Fixes #965.

    hk check works when there is no merge base (@jdx) #975. files_between_refs previously bailed when libgit2 or git couldn't find a common ancestor (e.g. shallow clones or unrelated histories). It now falls back to a shell git merge-base, then to a direct from..to tree/shell diff. Both the libgit2 and shell-git paths use the same range logic, covered by new bats tests with HK_LIBGIT2=1 and HK_LIBGIT2=0. Refs #972.

    Auto-batching respects the cmd.exe command-line limit (@jdx) #974. auto_batch_jobs now selects a shell-specific safe length: 4095 bytes (half of Windows' ~8191-character cap) for cmd.exe, and ARG_MAX / 2 for everything else. Medium-sized {{files}} expansions that fit under Unix ARG_MAX no longer blow past the cmd limit unbatched. Fixes #971.

    git2 updated to 0.21 (#956).

    Remove singular sponsor link from docs footer (@jdx) #962.

    Documentation

    Add a sponsor footer to the docs site (@jdx) #960.

    Full Changelog: v1.46.0...v1.47.0

    💚 Sponsor hk

    hk is developed by @jdx at en.dev — a small independent studio behind developer tools like mise, aube, hk, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at en.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
  • May 27, 2026
    • Date parsed from source:
      May 27, 2026
    • First seen by Releasebot:
      May 28, 2026
    jdx logo

    hk by jdx

    v1.46.0: --staged scope, global install, and a stash trilogy

    hk releases a feature-and-fix update with staged-file hook runs, smoother global installs, new named post-checkout variables, and built-in support for oxfmt, Vite+ and improved oxlint. It also fixes several stash, merge and pre-push bugs for safer hook behavior.

    A feature-and-fix release: hooks can now target staged files without touching your worktree, hk install cooperates with global installs, and three separate stash/merge bugs that could clobber fixer output or staged deletions are fixed.

    Added

    --staged flag for hk run, check, fix, and hook subcommands (@jdx) #950. Runs hooks against the staged file set while leaving unstaged and untracked changes alone — no stash, no worktree mutation. It conflicts with --all and --stash, and forces StashMethod::None even when the hook config opts into stashing. Fixes #940.

    hk run pre-commit --staged
    hk fix --staged
    

    hk install skips when hk is configured globally (@jdx) #934. If any hook.hk-* entry exists in ~/.gitconfig, hk install is a no-op and additionally cleans up stale per-repo hooks left behind from a prior install, so the global install is the single source of truth and hk doesn't fire twice per event. Pass --force-local to install per-repo hooks anyway. This means postinstall workarounds like git config --get-regexp hook.hk- || hk install can now be replaced with a plain hk install. Closes #933.

    Named template variables for post-checkout hooks (@jdx) #951. Steps can now reference prev_head, new_head, and is_branch_checkout (a real boolean, mapped from git's 1/0 flag) instead of having to parse the combined hook_args string. docs/hooks.md documents the per-hook variables for prepare-commit-msg, commit-msg, and post-checkout.

    oxfmt builtin (@hituzi-no-sippo) #914. Adds oxfmt as a builtin formatter for JS/TS, JSON, YAML, and TOML.

    Vite+ builtin (@hituzi-no-sippo) #913. Adds Vite+ as a builtin formatter/linter for JavaScript/TypeScript.

    oxlint builtin upgrades (@hituzi-no-sippo) #911. Adds --deny-warnings so violations exit non-zero, extends the file glob to .vue, .svelte, .astro, .mjs, .cjs, .mts, and .cts, and registers oxlint config files as project indicators so the builtin is auto-suggested.

    Fixed

    pre-push ref filter was inverted (@jdx) #932. The filter was checking the local sha for all-zeros (a deletion) when the intent was to check the remote sha (a new branch). Two visible consequences:

    First push of a new branch was dropped and fell through to resolving refs/remotes/origin/HEAD, which often failed with Failed to parse reference: refs/remotes/origin/HEAD (likely the root cause of #172).

    Branch deletions were kept and triggered linting against the deleted ref.

    The filter now drops only deletions, falls back to the real remote-tracking branch (or Git::resolve_default_branch()) for new-branch pushes, and uses a new git::is_zero_sha() helper that works for both SHA-1 and SHA-256 repos.

    hk install --global now uses absolute paths (@jdx) #939. Global hook commands previously assumed hk/mise were on PATH when git invoked the hook, which broke in environments with a sanitized PATH. The installer now resolves hk (or mise) to an absolute path at install time (using ~/ when home-relative and quoting otherwise), and --mise global installs use mise x hk -- hk so the hk tool is requested explicitly. Global installs also pick hook events from the project's hk.pkl when present. Fixes #937.

    fail_on_fix no longer loses fixer output through stash = "git" (@jdx) #909. git stash show --name-only can list staged files stored in the stash commit that were not part of the unstaged set being restored, so the manual unstash could rewrite a staged-only file and discard the fixer's output that should remain visible as an unstaged diff. hk now tracks the exact path set selected for stashing and filters restore to that set. Follow-up to the fail_on_fix fix in v1.44.3.

    Staged deletions survive pop_stash (@jdx) #927. pop_stash() walked every path returned by git stash show --name-only and wrote a merged blob to disk, even for paths the user had staged for deletion with git rm. After the commit, the deleted file reappeared on disk as untracked. hk now queries git diff --cached --diff-filter=D before unstashing and skips those paths. Fixes #926.

    Fixer tail-line deletions are preserved across three-way merge (@jdx) #931. In merge.rs::diff_hunks, when the LCS walk consumed other entirely after a matching line, a pure tail deletion of base[i..n] was dropped, so three_way_merge_hunks silently copied the removed lines back in. The classic symptom: a fixer that strips trailing blank lines, applied to a file where you have an unrelated unstaged change in the middle, would have its trailing-line cleanup silently undone. Fixes #929.

    check_diff failures get accurate fix suggestions (@jdx) #949. When a step defined both check_diff and check_list_files, the "To fix, run" hint always parsed output with the list-files parser regardless of which check actually ran. hk now passes the executed command into collect_fix_suggestion and dispatches to the diff parser for check_diff output, so the suggested files match the real failure. Fixes #942.

    Full Changelog: v1.45.0...v1.46.0

    💚 Sponsor hk

    hk is developed by @jdx at en.dev — a small independent studio behind developer tools like mise, aube, hk, and more. Work on hk is funded by sponsorships.

    If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at en.dev. Sponsorships are what keep hk moving and the project independent.

    Original source
Releasebot

Curated by the Releasebot team

Releasebot is an aggregator of official product update announcements from hundreds of software vendors and thousands of sources.

Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.