Skip to content

refactor(git): consolidate hooks into single router script - #8

Merged
cblecker merged 1 commit into
mainfrom
refactor/hooks-router-pattern
Jan 30, 2026
Merged

refactor(git): consolidate hooks into single router script#8
cblecker merged 1 commit into
mainfrom
refactor/hooks-router-pattern

Conversation

@cblecker

@cblecker cblecker commented Jan 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Consolidate 8 separate jq hook entries into single router script
  • ~20x performance improvement (15-20ms vs 400ms per Bash tool use)
  • Pure jq implementation for macOS/Linux portability

Changes

  • git/scripts/git-bash-router.sh: New router script with jq helper functions
  • git/hooks/hooks.json: Reduced from 8 matchers to single Bash matcher
  • git/CLAUDE.md: Updated architecture documentation
  • git/hooks/README.md: Added Architecture section, updated Technical Notes
  • git/scripts/detect-mainline.sh: Simplified shebang and removed upstream check

Testing

  • Force push protection (deny to mainline, ask elsewhere)
  • Skill suggestions (commit, branch creation)
  • Warnings (reset --hard, clean -f, rebase onto mainline)
  • GitHub CLI suggestions

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Centralized router for all Bash/git tool invocations, providing unified pre-tool guidance and permission decisions.
  • Improvements

    • Much faster hook processing (~15–20ms vs ~400ms) and improved portability via a single jq-driven routing flow.
    • Consolidated handling of sensitive operations with clearer contextual messages.
  • Documentation

    • Expanded README and technical notes describing the router pattern, matching rules, and performance rationale.
  • Chores

    • Plugin version bumped (release metadata updated).

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 30, 2026

Copy link
Copy Markdown

Walkthrough

Consolidates multiple git-related PreToolUse hooks into a single router-based Bash hook (git-bash-router.sh) driven by a jq decision flow, simplifies mainline detection, and updates documentation to describe the router architecture and jq patterns.

Changes

Cohort / File(s) Summary
Documentation
git/CLAUDE.md, git/hooks/README.md
Rewrote hook architecture docs to describe a centralized router-based pattern, added router implementation details, jq patterns, matcher guidance, performance notes, and removed legacy per-command jq examples.
Hook Configuration
git/hooks/hooks.json
Replaced multiple per-command PreToolUse matchers (e.g., Bash(git push:*), Bash(git commit:*), Bash(git checkout -b:*), gh:*) with a single Bash matcher that invokes ${CLAUDE_PLUGIN_ROOT}/scripts/git-bash-router.sh.
Router Script
git/scripts/git-bash-router.sh
Added new Bash script that loads/derives mainline, passes it into an embedded jq decision engine, and routes git/gh command patterns to produce structured hookSpecificOutput (permission decisions, reasons, contextual messages).
Mainline Detection
git/scripts/detect-mainline.sh
Simplified detection: shebang changed to /usr/bin/env bash; prioritize CLAUDE_MAINLINE_BRANCH/origin HEAD then local fallback (mainmastermain); retains session caching via CLAUDE_ENV_FILE.
Plugin Metadata
git/.claude-plugin/plugin.json
Bumped plugin version from 0.2.2 to 0.3.0.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as "Bash tool"
  participant Hooks as "hooks.json matcher"
  participant Router as "git-bash-router.sh"
  participant Detect as "detect-mainline.sh / env"
  participant JQ as "jq decision engine"
  participant Plugin as "Plugin/Host (receives hookSpecificOutput)"

  User->>Hooks: invoke tool (e.g., git push)
  Hooks->>Router: match `Bash` -> execute router
  Router->>Detect: get mainline (env or detect-mainline.sh)
  Detect-->>Router: mainline branch
  Router->>JQ: pass tool_input + mainline as jq vars
  JQ-->>Router: hookSpecificOutput (permissionDecision / messages)
  Router->>Plugin: emit standardized hookSpecificOutput
  Plugin-->>User: enforce/notify based on output
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hopping through commits with jq in my paw,

One router now listens and minds every law,
From push, to reset, to the branch that we name,
I guide with kind prompts — no two hooks, just one frame,
🥕 Routing made simple, and that’s my small claim.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring effort: consolidating multiple hook entries into a single router script, which is the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/hooks-router-pattern

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
git/scripts/detect-mainline.sh (1)

26-29: ⚠️ Potential issue | 🟡 Minor

Potential duplicate entries when caching to env file.

If this script is called multiple times before the cache is read, it will append duplicate CLAUDE_MAINLINE_BRANCH entries to CLAUDE_ENV_FILE. While the last entry typically wins when sourcing, this could cause file growth over long sessions.

Consider checking if the variable is already defined in the file before appending, or using a more robust approach.

🛡️ Proposed fix to prevent duplicates
 # Cache for session if env file available
 if [ -n "$CLAUDE_ENV_FILE" ] && [ -f "$CLAUDE_ENV_FILE" ]; then
+  # Remove any existing entry before adding new one
+  grep -v "^export CLAUDE_MAINLINE_BRANCH=" "$CLAUDE_ENV_FILE" > "$CLAUDE_ENV_FILE.tmp" && mv "$CLAUDE_ENV_FILE.tmp" "$CLAUDE_ENV_FILE"
   echo "export CLAUDE_MAINLINE_BRANCH='$mainline'" >> "$CLAUDE_ENV_FILE"
 fi
🤖 Fix all issues with AI agents
In `@git/scripts/git-bash-router.sh`:
- Around line 68-74: The current rebase detection uses test($mainline) which
does a substring match and can false-positive (e.g., "git rebase
maintain-branch"); update the condition in the git rebase branch of the router
to use a word-boundary match (or reuse the existing pushing_mainline helper
pattern) so it only matches the exact branch name token for $mainline; locate
the elif branch that inspects $cmd and replace the test($mainline) check with a
regex/word-boundary check consistent with pushing_mainline to avoid matching
branch names that merely contain the mainline string.

Comment thread git/scripts/git-bash-router.sh
Replace 8 separate jq hook entries with a single router script pattern:
- ~20x performance improvement (15-20ms vs 400ms per Bash tool use)
- Pure jq implementation for cross-platform portability
- Simplified hooks.json maintenance
- Helper functions for reusable patterns (force flags, dry-run, mainline)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@cblecker
cblecker force-pushed the refactor/hooks-router-pattern branch from 64812b9 to 7981812 Compare January 30, 2026 20:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@git/hooks/README.md`:
- Line 14: Edit the README sentence that reads "Pure jq implementation ensures
consistent behavior across Bash 3.2 (macOS system shell) and Bash 5.3+ (modern
systems)." and remove the redundant word "system" so it reads "Pure jq
implementation ensures consistent behavior across Bash 3.2 (macOS shell) and
Bash 5.3+ (modern systems)." Keep the rest of the line unchanged.

In `@git/scripts/git-bash-router.sh`:
- Around line 68-70: The rebase check's regex currently uses "\s" + $mainline +
"(\s|$)" which fails to match remote-prefixed targets like "origin/main"; update
the test expression in the conditional that uses ($cmd | test(...)) to allow an
optional remote prefix before $mainline, e.g. "\s(?:\S+/)?" + $mainline +
"(\s|$)". Apply the same regex change consistently to the pushing_mainline
helper (the helper referenced earlier) so both checks accept remote-prefixed
branch names.

Comment thread git/hooks/README.md
Comment thread git/scripts/git-bash-router.sh
@cblecker
cblecker merged commit 382bf38 into main Jan 30, 2026
8 checks passed
@cblecker
cblecker deleted the refactor/hooks-router-pattern branch January 30, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant