Lefthook v2 runs `git lfs pre-push` internally for pre-push hooks (per docs/usage/features/git-lfs.md; confirmed in internal/run/controller/ lfs.go where the internal handler invokes `git lfs pre-push <remote> <url>` with a buffered `cachedStdin`). Our manual `git-lfs:` command in lefthook.yml was a second invocation against the same remote; the duplicate is directly visible in `LEFTHOOK_VERBOSE=1` output as `[git-lfs] executing hook` (internal) followed by `[lefthook] run: git lfs pre-push` (manual). The previous fix attempt (piped: true, commit1b06804) was based on a wrong understanding of `piped`'s semantics — `piped` controls fail-fast behavior, not stdin routing or sequencing. Default lefthook behavior is already sequential per docs/configuration/parallel.md. That "fix" was placebo; incident 2 (F2 push, zero LFS objects, commit99eedb6) proved it. Phase A investigation: documentary + source confirmation that lefthook owns the LFS pre-push call. Phase B sandbox test against a filesystem remote confirmed the duplicate execution in logs but did NOT reproduce the production hang — likely because the duplicate manual call against a local remote has no LFS server to interact with. A network-y remote (Gitea over SSH/HTTPS) appears to be part of the trigger. Two mechanisms remain plausible (H1: PTY-stdin without EOF in `while read` loop per docs/configuration/use_stdin.md; H4: server-side LFS interaction on the duplicate call). Both are eliminated by the same fix: remove the manual command. LFS uploads continue to work via lefthook's internal handler (verified in sandbox post-fix). Regression coverage: scripts/test-lefthook-pre-push.sh asserts exactly one internal LFS invocation, zero manual ones, and `Uploading LFS objects: 100%` present, against a disposable sandbox. See dev-docs/ADR-LEFTHOOK-LFS-INTEGRATION.md for full context, both misconceptions to prevent regression, and the alternative-scenarios playbook if Phase E ever regresses. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
54 lines
1.5 KiB
Markdown
54 lines
1.5 KiB
Markdown
# Scripts
|
|
|
|
Repo-level helper scripts.
|
|
|
|
## Claude Project Knowledge sync
|
|
|
|
Keeps the Crewli dev-docs in Claude Project Knowledge aligned with the repo.
|
|
|
|
### One-time setup
|
|
|
|
```bash
|
|
bash scripts/install-claude-sync-hooks.sh
|
|
```
|
|
|
|
This points git at `.githooks/` and marks the hooks executable.
|
|
|
|
### Manual trigger
|
|
|
|
```bash
|
|
npm run sync:docs # regenerate .claude-sync/
|
|
npm run sync:check # verify .claude-sync/ matches dev-docs
|
|
```
|
|
|
|
The underlying script also supports `list` and `help`:
|
|
|
|
```bash
|
|
bash scripts/sync-claude-docs.sh list
|
|
bash scripts/sync-claude-docs.sh help
|
|
```
|
|
|
|
### Automatic
|
|
|
|
- `post-commit`: syncs automatically when any file in `.claude-sync.conf` is committed
|
|
- `pre-push`: warns if `.claude-sync/` is stale before pushing (non-blocking)
|
|
|
|
### After sync
|
|
|
|
Upload everything in `.claude-sync/` (including `SYNC_MANIFEST.md`) to the
|
|
Crewli Claude Project Knowledge, replacing existing versions. The manifest is
|
|
what Claude Chat uses for drift detection against the current HEAD.
|
|
|
|
## Lefthook + Git-LFS pre-push smoke test
|
|
|
|
```bash
|
|
bash scripts/test-lefthook-pre-push.sh
|
|
```
|
|
|
|
Builds a disposable sandbox, mirrors the repo's `lefthook.yml` + `.githooks/`,
|
|
and runs a push to verify (a) push completes, (b) exactly one internal LFS
|
|
invocation, (c) zero manual `git lfs pre-push` commands, (d) LFS upload
|
|
happens. Run this after touching `lefthook.yml` or the LFS configuration.
|
|
Background and what each failure mode signals:
|
|
`dev-docs/ADR-LEFTHOOK-LFS-INTEGRATION.md`.
|