スキル一覧に戻る
bacchus-labs

setup-git-hooks

by bacchus-labs

Claude Code plugin for keeping the ponies on their leads.

3🍴 1📅 2026年1月22日
GitHubで見るManusで実行

SKILL.md


name: setup-git-hooks description: Set up Git hooks for automated testing and code quality enforcement. Interactive configuration with smart project detection.

Setup Git Hooks

Skill Usage Announcement

MANDATORY: When using this skill, announce it at the start with:

Using Skill: setup-git-hooks | [brief purpose based on context]

Example:

Using Skill: setup-git-hooks | Setting up pre-commit and pre-push hooks for test enforcement

This creates an audit trail showing which skills were applied during the session.

Purpose

This skill sets up Git hooks to automatically enforce testing and code quality standards before commits and pushes. It supports two installation patterns:

  • Pattern A (Default): Hooks installed directly to .git/hooks/ with configuration in .wrangler/config/hooks-config.json
  • Pattern B: Version-controlled hooks in .wrangler/config/git-hooks/ with install script for team synchronization

When to Use

  • Setting up a new project with test enforcement
  • Adding hooks to an existing project
  • Migrating from other hook managers (Husky, pre-commit)
  • Configuring CI-like checks locally

Setup Workflow

Phase 1: Environment Verification

Step 1: Verify Git Repository

# Check if we're in a git repository
git rev-parse --show-toplevel

# Check existing hooks
ls -la .git/hooks/ 2>/dev/null | head -10

# Check for existing wrangler hooks config
[ -f .wrangler/config/hooks-config.json ] && echo "Existing config found" || echo "No existing config"

If not in a git repository, inform user and exit.

Step 2: Check for Existing Hook Managers

# Check for Husky
[ -d .husky ] && echo "Husky detected" || true
[ -f package.json ] && grep -q '"husky"' package.json && echo "Husky in package.json" || true

# Check for pre-commit framework
[ -f .pre-commit-config.yaml ] && echo "pre-commit framework detected" || true

# Check for existing custom hooks
for hook in pre-commit pre-push commit-msg; do
    [ -f .git/hooks/$hook ] && echo "Existing $hook hook found" || true
done

If existing hook manager found, ask user how to proceed:

  • Migrate from existing (backup and replace)
  • Skip setup (user will handle manually)
  • Continue anyway (may conflict)

Phase 2: Project Detection

Special Case: Empty Project or No Tests Detected

If the skill detects an empty project or no test framework:

Detection criteria:

  • No package.json, pyproject.toml, go.mod, Cargo.toml, etc.
  • No test files found (.test., _test., tests/ directory)
  • No test scripts in package.json

Graceful handling:

  1. Populate TESTING.md with placeholder content:

    TESTING.md should already exist from governance initialization. Update status section:

    **Status:** No tests configured yet
    

    If TESTING.md doesn't exist, create it from initialize-governance template first.

  2. Create stub hooks-config.json:

    {
      "version": "1.0.0",
      "createdAt": "2026-01-21T...",
      "testCommand": "",
      "note": "No tests detected. Run /wrangler:update-git-hooks after adding tests.",
      "protectedBranches": ["main", "master", "feature/*", "fix/*"],
      "skipDocsOnlyChanges": true,
      "docsPatterns": ["*.md", "docs/**/*", ".wrangler/memos/**/*"],
      "bypassEnvVar": "WRANGLER_SKIP_HOOKS",
      "setupComplete": false
    }
    

    Note: File should be created at .wrangler/config/hooks-config.json

  3. Install bypass-only hooks:

    • Hooks check setupComplete flag in config
    • If false, log message and exit 0 (allow all commits/pushes)
    • If true, run normal test enforcement
  4. Inform user:

    Git hooks installed (inactive - no tests detected)
    
    Hooks are installed but will not enforce testing until you:
    1. Add tests to your project
    2. Run: /wrangler:update-git-hooks
    
    Created:
    - .wrangler/TESTING.md (placeholder)
    - .wrangler/config/hooks-config.json (stub configuration)
    - .git/hooks/pre-commit (bypass mode)
    - .git/hooks/pre-push (bypass mode)
    

Why this works:

  • No broken setup (hooks exist but don't fail)
  • Clear messaging about what to do next
  • Easy to activate later
  • TESTING.md always exists (no orphaned references)

Step 3: Detect Project Type

Use Bash to identify project language/framework:

# JavaScript/TypeScript
[ -f package.json ] && echo "javascript"

# Python
[ -f setup.py ] || [ -f pyproject.toml ] || [ -f requirements.txt ] && echo "python"

# Go
[ -f go.mod ] && echo "go"

# Rust
[ -f Cargo.toml ] && echo "rust"

# Java
[ -f pom.xml ] || [ -f build.gradle ] && echo "java"

Step 4: Detect Existing Test/Format/Lint Commands

For JavaScript projects:

# Read package.json scripts
cat package.json | grep -E '"(test|lint|format)"' || true

For Python projects:

# Check for common test runners
[ -f pytest.ini ] || [ -f pyproject.toml ] && grep -q pytest pyproject.toml && echo "pytest"
[ -f setup.cfg ] && grep -q flake8 setup.cfg && echo "flake8"

For Go projects:

# Go has standard commands
echo "go test ./..."
echo "go fmt ./..."

Phase 3: Interactive Configuration

Step 5: Ask User for Configuration

Use multiple AskUserQuestion calls to gather configuration:

Question 1: Installation Pattern

AskUserQuestion({
  questions: [{
    question: "Which hook installation pattern would you prefer?",
    header: "Installation Pattern",
    options: [
      {
        label: "Pattern A: Direct installation (Recommended)",
        description: "Hooks in .git/hooks/, config in .wrangler/config/hooks-config.json"
      },
      {
        label: "Pattern B: Version-controlled",
        description: "Hooks in .wrangler/config/git-hooks/, install script for team sync"
      }
    ],
    multiSelect: false
  }]
})

Question 2: Test Command

// Show detected commands as suggestions
AskUserQuestion({
  questions: [{
    question: "What command runs your full test suite?",
    header: "Test Command",
    options: [
      { label: "[detected command]", description: "Detected from project files" },
      { label: "Custom command", description: "I'll specify my own" }
    ],
    multiSelect: false
  }]
})

If "Custom command" selected, ask user to type the command.

Question 3: Unit Test Command (Optional)

AskUserQuestion({
  questions: [{
    question: "Do you have a separate command for fast unit tests? (for pre-commit)",
    header: "Unit Tests",
    options: [
      { label: "Same as full tests", description: "Use full test command" },
      { label: "[suggested fast command]", description: "Faster subset of tests" },
      { label: "Custom command", description: "I'll specify my own" },
      { label: "Skip unit tests", description: "Don't run tests in pre-commit" }
    ],
    multiSelect: false
  }]
})

Question 4: Format Command (Optional)

AskUserQuestion({
  questions: [{
    question: "What command formats your code? (auto-fix and re-stage)",
    header: "Formatter",
    options: [
      { label: "[detected command]", description: "Detected from project files" },
      { label: "Custom command", description: "I'll specify my own" },
      { label: "Skip formatting", description: "Don't auto-format in pre-commit" }
    ],
    multiSelect: false
  }]
})

Question 5: Lint Command (Optional)

AskUserQuestion({
  questions: [{
    question: "What command lints your code?",
    header: "Linter",
    options: [
      { label: "[detected command]", description: "Detected from project files" },
      { label: "Custom command", description: "I'll specify my own" },
      { label: "Skip linting", description: "Don't lint in pre-commit" }
    ],
    multiSelect: false
  }]
})

Question 6: Protected Branches

AskUserQuestion({
  questions: [{
    question: "Which branches should require full tests before push?",
    header: "Protected Branches",
    options: [
      { label: "Default (main, master, develop, release/*, hotfix/*)", description: "Standard Git Flow branches" },
      { label: "Just main/master", description: "Only primary branches" },
      { label: "Custom patterns", description: "I'll specify my own" }
    ],
    multiSelect: false
  }]
})

Question 7: Commit Message Validation (Optional)

AskUserQuestion({
  questions: [{
    question: "Enable commit message format validation?",
    header: "Commit Messages",
    options: [
      { label: "Yes - Conventional Commits", description: "feat:, fix:, docs:, etc." },
      { label: "No", description: "Allow any commit message format" }
    ],
    multiSelect: false
  }]
})

Phase 4: Configuration Generation

Step 6: Generate hooks-config.json

Create the configuration file with user's answers:

mkdir -p .wrangler/config

Use Write tool to create .wrangler/config/hooks-config.json:

{
  "$schema": "https://wrangler.dev/schemas/hooks-config.json",
  "version": "1.0.0",
  "createdAt": "[ISO timestamp]",
  "projectType": "[detected type]",
  "testCommand": "[user's test command]",
  "unitTestCommand": "[user's unit test command or null]",
  "formatCommand": "[user's format command or null]",
  "lintCommand": "[user's lint command or null]",
  "protectedBranches": ["main", "master", "develop", "release/*", "hotfix/*"],
  "skipDocsOnlyChanges": true,
  "docsPatterns": ["*.md", "*.txt", "*.rst", "docs/*", "README*", "LICENSE*", "CHANGELOG*"],
  "enableCommitMsgValidation": [true/false],
  "bypassEnvVar": "WRANGLER_SKIP_HOOKS",
  "pattern": "[A or B]"
}

Phase 5: Hook Installation

Step 7: Install Hooks (Pattern A)

If Pattern A selected:

# Backup existing hooks
if [ -f .git/hooks/pre-commit ] || [ -f .git/hooks/pre-push ]; then
    mkdir -p .git/hooks.backup
    cp .git/hooks/pre-commit .git/hooks.backup/ 2>/dev/null || true
    cp .git/hooks/pre-push .git/hooks.backup/ 2>/dev/null || true
    cp .git/hooks/commit-msg .git/hooks.backup/ 2>/dev/null || true
    echo "Existing hooks backed up to .git/hooks.backup/"
fi

Use Read tool to read template files from wrangler skills directory:

  • skills/setup-git-hooks/templates/pre-commit.template.sh
  • skills/setup-git-hooks/templates/pre-push.template.sh
  • skills/setup-git-hooks/templates/commit-msg.template.sh (if enabled)

Use string replacement to substitute placeholders:

  • {{TEST_COMMAND}} -> user's test command
  • {{UNIT_TEST_COMMAND}} -> user's unit test command
  • {{FORMAT_COMMAND}} -> user's format command
  • {{LINT_COMMAND}} -> user's lint command
  • {{PROTECTED_BRANCHES}} -> user's protected branches
  • {{DOCS_PATTERNS}} -> docs patterns

Use Write tool to save hooks to .git/hooks/:

  • .git/hooks/pre-commit
  • .git/hooks/pre-push
  • .git/hooks/commit-msg (if enabled)

Make hooks executable:

chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/pre-push
[ -f .git/hooks/commit-msg ] && chmod +x .git/hooks/commit-msg

Step 8: Install Hooks (Pattern B)

If Pattern B selected:

# Create version-controlled hooks directory
mkdir -p .wrangler/config/git-hooks

Use Write tool to save hooks to .wrangler/config/git-hooks/:

  • .wrangler/config/git-hooks/pre-commit
  • .wrangler/config/git-hooks/pre-push
  • .wrangler/config/git-hooks/commit-msg (if enabled)

Use Write tool to create install script at scripts/install-hooks.sh: (Copy from skills/setup-git-hooks/templates/install-hooks.sh)

Make files executable:

chmod +x .wrangler/config/git-hooks/pre-commit
chmod +x .wrangler/config/git-hooks/pre-push
[ -f .wrangler/config/git-hooks/commit-msg ] && chmod +x .wrangler/config/git-hooks/commit-msg
chmod +x scripts/install-hooks.sh

Run install script:

./scripts/install-hooks.sh

Phase 6: Documentation Installation

Step 9: Install PR Template

Create PR template in user's project:

mkdir -p .github

Create PR template (git hooks specific):

  • .github/pull_request_template.md (copy from skills/setup-git-hooks/templates/pull_request_template.md)

Note on other templates: Security checklist and Definition of Done templates remain in their skill directories:

  • Security checklist: skills/initialize-governance/templates/SECURITY_CHECKLIST.md
  • Definition of Done: skills/initialize-governance/templates/DEFINITION_OF_DONE.md

These are referenced directly from skills, not copied to project directories.

Step 10: Populate TESTING.md

TESTING.md is created by initialize-governance skill. This step populates it with git hooks configuration.

If .wrangler/TESTING.md doesn't exist (governance not initialized), create it from initialize-governance template with user's configuration:

# Copy template from initialize-governance
cp skills/initialize-governance/templates/TESTING.md .wrangler/TESTING.md

Then populate all placeholders with detected/configured values.

Phase 7: Verification and Summary

Step 11: Verify Installation

# Verify hooks are installed and executable
echo "=== Hook Installation Verification ==="
for hook in pre-commit pre-push commit-msg; do
    if [ -f .git/hooks/$hook ]; then
        if [ -x .git/hooks/$hook ]; then
            echo "[OK] $hook installed and executable"
        else
            echo "[WARN] $hook installed but not executable"
        fi
    else
        echo "[SKIP] $hook not installed"
    fi
done

# Verify config file
echo ""
echo "=== Configuration ==="
[ -f .wrangler/config/hooks-config.json ] && echo "[OK] hooks-config.json created" || echo "[ERROR] hooks-config.json missing"

# Show config summary
cat .wrangler/config/hooks-config.json

Step 12: Provide Summary

Display completion message to user:

## Git Hooks Setup Complete

### Hooks Installed

| Hook | Status | Purpose |
|------|--------|---------|
| pre-commit | [Installed] | Format, lint, unit tests |
| pre-push | [Installed] | Full test suite on protected branches |
| commit-msg | [Installed/Skipped] | Commit message validation |

### Configuration

- **Test Command**: `[command]`
- **Unit Tests**: `[command or "Same as full tests"]`
- **Formatter**: `[command or "Not configured"]`
- **Linter**: `[command or "Not configured"]`
- **Protected Branches**: `[patterns]`
- **Pattern**: [A/B]

### Files Created

- `.wrangler/config/hooks-config.json` - Hook configuration
- `.git/hooks/pre-commit` - Pre-commit hook
- `.git/hooks/pre-push` - Pre-push hook
[- `.git/hooks/commit-msg` - Commit message hook]
[- `.github/pull_request_template.md`]

### Important Notes

**Bypass Mechanism**:
```bash
# For TDD RED phase (writing failing test first)
WRANGLER_SKIP_HOOKS=1 git commit -m "WIP: failing test for feature X"

Note: AI agents cannot use this bypass - only humans can set environment variables.

Update Hooks: Run /wrangler:update-git-hooks to modify configuration.

Next Steps

  1. Try making a commit to verify hooks work
  2. Review TESTING.md for test documentation
  3. Share with team (if Pattern B, they run scripts/install-hooks.sh)

## Edge Cases

### Existing Hooks

If hooks already exist, offer options:
1. **Backup and replace** - Move existing to `.git/hooks.backup/`
2. **Merge** - Try to append wrangler hooks to existing (advanced)
3. **Skip** - Don't touch existing hooks

### No Test Command

If user doesn't have tests:
1. Warn that hooks won't be effective without tests
2. Offer to skip test-related hooks
3. Suggest setting up tests first

### Monorepo

For monorepos, ask:
1. Root-level hooks for all packages?
2. Package-specific test commands?

### Windows Compatibility

Hooks use bash shebang. For Windows:
1. Ensure Git Bash or WSL is available
2. Use `#!/usr/bin/env bash` shebang
3. Test path separators

## Troubleshooting

### Hooks Not Running

```bash
# Check hook is executable
ls -la .git/hooks/pre-commit

# Make executable
chmod +x .git/hooks/pre-commit

Tests Failing in Hook

# Run test command directly to debug
[test command]

# Bypass temporarily
WRANGLER_SKIP_HOOKS=1 git commit -m "debug: investigating test failure"

Slow Pre-Commit

If pre-commit takes too long:

  1. Ensure only unit tests run (not full suite)
  2. Consider test parallelization
  3. Review what's being formatted/linted
  • test-driven-development - TDD workflow with hook considerations
  • run-the-tests - Manual test execution
  • verification-before-completion - Verification workflow
  • update-git-hooks - Modify existing hook configuration
  • initialize-governance - Sets up hooks as part of governance

TDD Workflow Integration

When following TDD (Test-Driven Development):

  1. RED Phase: Write failing test

    • Use WRANGLER_SKIP_HOOKS=1 git commit -m "WIP: failing test" to commit
    • This is expected and acceptable
  2. GREEN Phase: Make test pass

    • Normal commit should now pass hooks
    • git commit -m "feat: implement feature to pass test"
  3. REFACTOR Phase: Improve code

    • All commits should pass hooks
    • git commit -m "refactor: improve code quality"

The bypass is designed for TDD RED phase and emergency fixes only.

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です