fix(hooks): preserve husky v8/v9 hook layout when copying to .beads/hooks/#3197
Open
sjsyrek wants to merge 1 commit intogastownhall:mainfrom
Open
fix(hooks): preserve husky v8/v9 hook layout when copying to .beads/hooks/#3197sjsyrek wants to merge 1 commit intogastownhall:mainfrom
sjsyrek wants to merge 1 commit intogastownhall:mainfrom
Conversation
…ooks/ (GH#3132) When beads sets core.hooksPath=.beads/hooks/ and copies hooks from a husky-managed directory, two bugs break the preserved hooks: Bug 1 (v8): Husky v8 hooks source $(dirname "$0")/_/husky.sh, but the _/ helper directory was skipped by preservePreexistingHooks (which skips directories). Fix: create a relative symlink from .beads/hooks/_/ to the original _/ directory. Bug 2 (v9): Husky v9 sets core.hooksPath=.husky/_/ where each hook is a shim that sources an "h" dispatcher. The dispatcher uses dirname(dirname($0)) to resolve user hooks in the parent .husky/ directory — this path math breaks when the shim is relocated. Fix: detect v9 shims and replace them with the actual user hook content from .husky/, then remove the now-unnecessary h dispatcher. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
Fixes #3132. When
bd initcopies hooks from a husky-managed directory into.beads/hooks/, two bugs break the preserved hooks — one loudly (every commit fails), one silently (user's lint/format hooks never run).Changes Made
fixHuskyHookLayout()incmd/bd/hooks.go— called at the end ofpreservePreexistingHooks()to handle husky-specific directory layout issues.beads/hooks/_/to the original.husky/_/helper directory. This makes$(dirname "$0")/_/husky.shresolve correctly from the new locationhdispatcher) and replaces them with the actual user hook content from.husky/. Adds a shebang if the user hook lacks one. Removes the now-unnecessaryhdispatcher from.beads/hooks/Backward Compatibility
✅ No breaking changes:
fixHuskyHookLayoutis a no-op for non-husky hook directories (early returns when_/dir andhdispatcher are absent)✅ Existing hooks preserved: All existing
TestInstallHooksBeads_Preserves*tests pass unchanged✅ Beads section injection: Works correctly with both fix paths — the user hook content is written first, then
installHooksWithOptionsinjects the beads section via markersTechnical Details
Bug 1 fix:
preservePreexistingHooksskips directories (entry.IsDir()on line 691). Rather than changing that general behavior,fixHuskyHookLayoutruns after the copy loop and creates a relative symlink specifically for the husky_/helper directory.Bug 2 fix: For husky v9,
core.hooksPath=.husky/_/. The files there are shims, not actual user hooks. Thehdispatcher resolves up viadirname(dirname($0))which breaks when relocated. Instead of rewriting the dispatcher's path math, we replace the shims entirely with the user's actual hook commands from.husky/(one directory up), which is simpler and more robust.Test plan
go test ./cmd/bd/ -run "TestInstallHooksBeads_Husky|TestFixHusky"— 3 new tests passgo test ./cmd/bd/ -run "TestInstallHooksBeads_Preserves"— existing tests passgo vet ./cmd/bd/...— cleango build ./cmd/bd/...— compilesbd initin a repo with husky v8 → verify_/symlink and hooks workbd initin a repo with husky v9 → verify user commands preserved,hremovedSize: Medium ✓
Single function addition (~75 lines) + 3 integration tests (~200 lines). Touches only
preservePreexistingHooksflow, no architectural changes.🤖 Generated with Claude Code