chore(tooling): migrate .githooks to lefthook.yml

WS-3 session 1a Task 1.

Lefthook installed as root dev-dependency with postinstall = lefthook
install. The two hand-rolled scripts in .githooks/ (post-commit,
pre-push) are dispatched 1:1 from lefthook.yml: each lefthook command
shells out to the existing .githooks/<hook> script. The script bodies
are kept as the source of truth because the bash logic (merge-commit
detection, .claude-sync.conf parsing, non-blocking pre-push warning)
would be lossy to translate into a YAML run: | block.

Active hook path moved from .githooks/ to .git/hooks/ via lefthook
install (core.hooksPath unset, git falls back to its default). The
.githooks/ directory is preserved and now documented as the
implementation invoked by lefthook plus an emergency rollback target
(README added).

Smoke-tested locally: the post-commit hook fires on every commit
(verified by reverted test commit). The pre-push hook fires on every
real push with new commits — manual `lefthook run pre-push` requires
`--force` because lefthook v2 skips when {push_files} is empty (see
lefthook.yml comment).
This commit is contained in:
2026-04-29 08:39:34 +02:00
parent fc0174061e
commit ca1d37b7de
4 changed files with 192 additions and 1 deletions

42
.githooks/README.md Normal file
View File

@@ -0,0 +1,42 @@
# .githooks/
These scripts contain the actual logic for Crewli's `post-commit` and
`pre-push` hooks (Claude project-knowledge sync gate, non-blocking
sync-staleness warning).
## How they're dispatched
Until WS-3 session 1a (2026-04-29) git invoked these scripts directly
via `git config core.hooksPath .githooks`. From that session onward
they are dispatched by **lefthook**, configured in `lefthook.yml` at
the repo root. Lefthook installs its own wrapper scripts into
`.git/hooks/` and reads `lefthook.yml` to decide what to run; for
this repo the wrapper invokes the same `bash .githooks/<hook>` calls
that git used to make.
The migration is 1:1 by design — the hook implementations live here
because the bash logic (merge-commit handling, conf parsing,
non-blocking warning) is intricate enough that re-translating it
into a YAML `run: |` block would be lossy.
## Re-installing lefthook
```bash
pnpm install # postinstall script runs `lefthook install`
```
## Emergency rollback
If lefthook is broken and you need git to invoke these scripts
directly again:
```bash
git config core.hooksPath .githooks
```
To return to lefthook:
```bash
git config --unset --local core.hooksPath
pnpm exec lefthook install
```