fix(hooks): resolve worktree-local lefthook instead of path-baking shim - #127
Merged
Merged
Conversation
lefthook install bakes an absolute node_modules path into the shared .git/hooks shim. In a fresh worktree that path is stale, so the shim falls through to `mint run csjones/lefthook-plugin` — which collides with Mintlify's `mint` CLI, errors mid-run, and lets lefthook's stage_fixed stash silently revert uncommitted edits. Replace `prepare: lefthook install` with a script that writes hooks resolving each worktree's own node_modules/.bin/lefthook, skipping cleanly (exit 0, no stash, no mint) when deps aren't installed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
block-kitchen | d8bc585 | Commit Preview URL Branch Preview URL |
Jun 30 2026, 06:06 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replace
prepare: lefthook installwith a small script that installs git hooks resolving each worktree's ownnode_modules/.bin/lefthook, so a normalgit commitin a fresh worktree neither errors nor silently reverts uncommitted edits.Why
lefthook installregenerates the shared.git/hooksshim with an absolute path baked to whichever worktree last installed. In a fresh worktree (nonode_modules) that path is stale, so the shim falls through its resolution chain tomint run csjones/lefthook-plugin. That branch assumes Swift Mint, but on this machinemintis Mintlify's CLI — a name collision. It errors mid-run, and lefthook'sstage_fixedstash can leave the working tree in the reverted state, silently destroying uncommitted edits. The only workaround had beengit commit --no-verify.Confirmed live during this work: the worktree whose path was baked got cleaned up mid-session, which is exactly the trigger.
A fresh worktree has no
node_modules, so it fundamentally cannot run biome — any attempt risks the stash/revert. The fix makes that case a clean skip while keeping full enforcement everywhere deps are installed.How it works
scripts/install-hooks.mjswritespre-commit/pre-pushinto the shared common hooks dir (the one lever every worktree'score.hooksPathpoints at). Each hook resolves the worktree-local lefthook and execs it, or prints a one-line "run pnpm install" notice and exits 0 when deps are absent — never touchingmint, never stashing.lefthook.ymlstays the single source of truth for what runs.Test plan
pnpm typecheckpnpm lintpnpm testManually verified:
node_modules), globbed.jsonwith staged + unstaged edits → commit succeeds, exits 0, unstaged edit survives, no stash entry, nomintinvocation.preparewiring end-to-end: a realpnpm installran the script and installed bothpre-commitandpre-push. (This PR's own commit ran through the new hook cleanly.)Notes for reviewer
scripts/is not inpackage.jsonfiles, so it isn't shipped; registry installs don't run a dependency'sprepare, so consumers are unaffected — same exposure as the oldlefthook install.lefthookdevDependency is retained; the hooks invoke its bin directly rather than relying on its generated shim.