Repository navigation
chore(hooks): chain .githooks to global co-author stripping hooks - #521
Conversation
Installs prepare-commit-msg and post-commit hooks in .githooks/ that chain to ~/.git-hooks/ so the user-level co-author stripping hooks run in this repo despite the local core.hooksPath override.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughTwo Git hook scripts are added to the ChangesGit hook delegation to global hooks
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
PR #521 added chain-to-global logic in .githooks/prepare-commit-msg and .githooks/post-commit so that AI attribution stripping always runs. But the global hooks already chain BACK to repo-local via chain_repo_hook(), creating an infinite cycle: global prepare-commit-msg -> chain_repo_hook() -> .githooks/prepare-commit-msg -> $HOME/.git-hooks/prepare-commit-msg -> chain_repo_hook() ... (repeat until SHLVL=1000) Fix: remove the chain-to-global calls. The hooks are now no-ops that document the chaining direction and provide a place for future repo-specific logic.
…aps into ThreadRecord (#524) * refactor(threadStore): extract ThreadHydrator + collapse per-thread maps into ThreadRecord Closes #522 (phases 1-4; phase 5 prefetch.ts deletion already complete). ## What - Introduce `ThreadHydrator` as a single deep module owning the full "load this thread" flow: cache lookup, RPC fetch, record commit, auxiliary fanout, and narrative prefetch. Split into `SnapshotBuilder` (pure, no IO) and `AuxiliaryHydrator` (TTL-gated permissions/tasks/plans/file-changes fanout). - Collapse ~30 parallel `Record<string, X>` maps into a canonical `ThreadRecord` keyed by threadId in a `Map<string, ThreadRecord>`. Add `thread-record.ts` (immutable patch helpers) and `thread-selectors.ts` (typed read paths). Active-thread mirrors removed. - LRU cache (`record-cache.ts`, 15-thread capacity) stores evicted `ThreadRecord` directly. `MessageCacheSnapshot` / `ThreadSnapshot` types and adapter functions deleted - cache stores canonical records, not adapters. - Delete `apps/web/src/lib/prefetch.ts` (collapsed to a single debounced call inside `prefetch-scheduler.ts`) and `apps/web/src/stores/messageCache.ts` (replaced by `record-cache.ts`). - Add `thread-store-test-utils.ts` with `applyLegacyThreadStoreSeed` shim so legacy per-thread-map seeding continues to work in tests during the migration. ## Why - Per the epic in #522: thread load and switch involved ~30 parallel maps and scattered side-effects, making both correctness and performance reasoning hard. The collapse trades surface for depth: one record-shaped state, one hydrator, one cache. ## Key changes - `threadStore.ts` shrinks from ~1490 lines of state-mutation code to ~650; most behavior delegates to `ThreadHydrator` and its sub-modules. - Restoring from cache preserves the live record's `permissions` and `lastHydratedAt` fields (auxiliary-owned). The auxiliary fanout that runs after restore refreshes them; this prevents stale cache values from clobbering in-flight async updates. - `SnapshotBuilder.build()` returns `answeredPlanMessageIds: Set<string>` (was string[]) to match the canonical `ThreadRecord` shape. ## Verification - `bun run verify`: 157 test files, 1389 tests passing. - One flaky test (`sidebar-usage-panel-tokens.test.tsx`) had a one-off hook timeout under full suite load but passes in isolation; unrelated to this refactor. * refactor(threadStore): drop applyLegacyThreadStoreSeed shim Replace the 23 test consumers of the legacy flat-seed shim with canonical resetThreadStoreForTests + patchThreadRecord helpers, then delete the shim itself. The shim was the test-side compatibility seam during the per-thread record collapse. Now that production code is on ThreadRecord and tests are migrated, the shim's flat *ByThread input shape has no callers and its inline field-mapping tables are dead weight. resetThreadStoreForTests now accepts runningThreadIds and recentlyAnsweredPlanMessageIds so single-call resets stay one expression. Net -162 lines. * fix(hooks): break infinite recursion between repo-local and global hooks PR #521 added chain-to-global logic in .githooks/prepare-commit-msg and .githooks/post-commit so that AI attribution stripping always runs. But the global hooks already chain BACK to repo-local via chain_repo_hook(), creating an infinite cycle: global prepare-commit-msg -> chain_repo_hook() -> .githooks/prepare-commit-msg -> $HOME/.git-hooks/prepare-commit-msg -> chain_repo_hook() ... (repeat until SHLVL=1000) Fix: remove the chain-to-global calls. The hooks are now no-ops that document the chaining direction and provide a place for future repo-specific logic. * chore(hooks): delete no-op repo-local commit hooks The repo-local prepare-commit-msg and post-commit hooks were left as empty placeholders after 011db21 broke the recursion loop with the global hooks. Git treats missing hook files as no-op, so the placeholders carried no behavior — just documentation. post-checkout stays: it has real .env bootstrap logic. * fix(threadHydrator): address review feedback — guards, test assertions, stale comment - Add thread-existence guard in auxiliary-hydrator permissions writeback and thread-hydrator narrative prefetch to prevent resurrecting deleted threads via patchThreadRecord - Add firstStart definedness assertion in running-session-signal idempotency test so it fails if turnStarted never recorded a start time - Fix workspace-behavior test: check workspace loading state instead of thread loading after loadWorkspaces() failure - Update stale "message-cache" comment to "record-cache" in App.tsx
What
Adds
prepare-commit-msgandpost-commithooks to.githooks/that chain to the user-level hooks at~/.git-hooks/.Why
This repo sets
core.hooksPath = .githooks, which bypasses the global~/.git-templateshooks directory. Without chaining hooks in place, the user-level co-author stripping hooks never run in this repo, and AI co-author lines leak into commits.Key changes
.githooks/prepare-commit-msg- chains to~/.git-hooks/prepare-commit-msgif executable.githooks/post-commit- chains to~/.git-hooks/post-commitif executable# --- chained-to-global-hooks ---marker)Need help on this PR? Tag
@codesmithwith what you need. Autofix is disabled.Summary by CodeRabbit