feat: add git hooks for automated dev-alerts notifications
Implemented post-commit hooks to automatically send coordination messages to dev-alerts channel when feature specs are created or builds occur. HOOKS: - .git/hooks/post-commit (main repo) - .git/modules/projects/msp-tools/guru-connect/hooks/post-commit (GC submodule) TRIGGERS: - Feature spec creation (SPEC-NNN files) - Build events (spec/feat/fix/build commits on main) ACTIONS: - Extract spec metadata (priority, effort, overview) - Send coordination message to dev-alerts channel - Include commit hash, author, files changed DOCUMENTATION: - .claude/HOOKS.md - Full hook documentation - .claude/hooks/post-commit.template - Reusable hook template BENEFITS: - Automatic notifications for new features - Build tracking on main branch - Team awareness of spec changes - No manual message sending required Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
196
.claude/HOOKS.md
Normal file
196
.claude/HOOKS.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# Git Hooks Configuration
|
||||
|
||||
## Overview
|
||||
|
||||
Git hooks automatically send notifications to the `dev-alerts` coordination channel when feature specifications are created or significant commits are made to main branches.
|
||||
|
||||
## Installed Hooks
|
||||
|
||||
### post-commit (Main Repo)
|
||||
|
||||
**Location:** `.git/hooks/post-commit`
|
||||
|
||||
**Triggers:**
|
||||
- **Feature Spec Creation:** When a commit includes new `docs/specs/SPEC-NNN-*.md` files
|
||||
- **Build Events:** When commits with conventional commit prefixes (`spec:`, `feat:`, `fix:`, `build:`) are made to `main` branch
|
||||
|
||||
**Actions:**
|
||||
- Extracts SPEC number, priority, effort, and overview from spec file
|
||||
- Sends coordination message to `dev-alerts` channel
|
||||
- Includes commit hash, author, branch, and affected files
|
||||
|
||||
**Message Format (Feature Spec):**
|
||||
```
|
||||
Subject: [ProjectName] Feature Spec: SPEC-NNN [Feature Name]
|
||||
Body:
|
||||
- SPEC number and name
|
||||
- Priority and effort estimate
|
||||
- Overview excerpt
|
||||
- Commit hash and author
|
||||
- Link to spec file
|
||||
```
|
||||
|
||||
**Message Format (Build Event):**
|
||||
```
|
||||
Subject: [ProjectName] Build: [commit type] on main
|
||||
Body:
|
||||
- Commit hash and type
|
||||
- Files changed count
|
||||
- Branch and author
|
||||
- Full commit message
|
||||
```
|
||||
|
||||
### post-commit (GuruConnect Submodule)
|
||||
|
||||
**Location:** `.git/modules/projects/msp-tools/guru-connect/hooks/post-commit`
|
||||
|
||||
**Triggers:** Same as main repo
|
||||
**Project Key:** `guruconnect`
|
||||
**Project Name:** GuruConnect
|
||||
|
||||
### post-commit (GuruRMM Submodule)
|
||||
|
||||
**Location:** `.git/modules/projects/msp-tools/guru-rmm/hooks/post-commit`
|
||||
|
||||
**Status:** To be created when submodule is initialized
|
||||
**Project Key:** `gururmm`
|
||||
**Project Name:** GuruRMM
|
||||
|
||||
## Setup
|
||||
|
||||
### Install Hooks Manually
|
||||
|
||||
```bash
|
||||
# Main repo
|
||||
cp .claude/hooks/post-commit.template .git/hooks/post-commit
|
||||
chmod +x .git/hooks/post-commit
|
||||
|
||||
# GuruConnect submodule
|
||||
cp .claude/hooks/post-commit.template .git/modules/projects/msp-tools/guru-connect/hooks/post-commit
|
||||
chmod +x .git/modules/projects/msp-tools/guru-connect/hooks/post-commit
|
||||
|
||||
# GuruRMM submodule (when initialized)
|
||||
cp .claude/hooks/post-commit.template .git/modules/projects/msp-tools/guru-rmm/hooks/post-commit
|
||||
chmod +x .git/modules/projects/msp-tools/guru-rmm/hooks/post-commit
|
||||
```
|
||||
|
||||
### Verify Hook Installation
|
||||
|
||||
```bash
|
||||
# Check if hook exists and is executable
|
||||
ls -l .git/hooks/post-commit
|
||||
ls -l .git/modules/projects/msp-tools/guru-connect/hooks/post-commit
|
||||
|
||||
# Test manually (run from repo root after a commit)
|
||||
.git/hooks/post-commit
|
||||
```
|
||||
|
||||
## Coordination API Integration
|
||||
|
||||
Hooks send messages to the coordination API at `http://172.16.3.30:8001/api/coord/messages` with:
|
||||
|
||||
- **from_session:** `$(hostname)/claude-main`
|
||||
- **to_session:** `dev-alerts`
|
||||
- **project_key:** `guruconnect`, `gururmm`, or `claudetools`
|
||||
- **subject:** Auto-generated based on event type
|
||||
- **body:** Formatted notification with commit details
|
||||
|
||||
## Message Recipients
|
||||
|
||||
Messages sent to `dev-alerts` can be queried by any session:
|
||||
|
||||
```bash
|
||||
# Check unread dev-alerts messages
|
||||
curl -s "http://172.16.3.30:8001/api/coord/messages?to_session=dev-alerts&unread_only=true"
|
||||
|
||||
# Check all dev-alerts messages for a project
|
||||
curl -s "http://172.16.3.30:8001/api/coord/messages?to_session=dev-alerts&project_key=guruconnect"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Hook Not Firing
|
||||
|
||||
1. **Check executable permission:**
|
||||
```bash
|
||||
chmod +x .git/hooks/post-commit
|
||||
```
|
||||
|
||||
2. **Test manually:**
|
||||
```bash
|
||||
.git/hooks/post-commit
|
||||
```
|
||||
|
||||
3. **Check coordination API:**
|
||||
```bash
|
||||
curl -s http://172.16.3.30:8001/api/coord/status
|
||||
```
|
||||
|
||||
### Debug Hook Execution
|
||||
|
||||
Temporarily add debug output to hook:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -x # Enable debug mode
|
||||
# ... rest of hook code ...
|
||||
```
|
||||
|
||||
Then check git output after commit.
|
||||
|
||||
## Customization
|
||||
|
||||
### Add Custom Event Types
|
||||
|
||||
Edit the hook and add new patterns to detect:
|
||||
|
||||
```bash
|
||||
# Example: Detect documentation commits
|
||||
if echo "$COMMIT_MSG" | grep -qE '^docs:.*API'; then
|
||||
# Send custom dev-alerts message
|
||||
fi
|
||||
```
|
||||
|
||||
### Change Alert Channel
|
||||
|
||||
Replace `dev-alerts` with a different channel name:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://172.16.3.30:8001/api/coord/messages \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"from_session\": \"$SESSION_ID\",
|
||||
\"to_session\": \"build-notifications\", # Changed from dev-alerts
|
||||
...
|
||||
}"
|
||||
```
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Disable Hooks Temporarily
|
||||
|
||||
```bash
|
||||
# Rename to disable
|
||||
mv .git/hooks/post-commit .git/hooks/post-commit.disabled
|
||||
|
||||
# Re-enable
|
||||
mv .git/hooks/post-commit.disabled .git/hooks/post-commit
|
||||
```
|
||||
|
||||
### Update All Hooks
|
||||
|
||||
When the hook logic changes, update all installations:
|
||||
|
||||
```bash
|
||||
# Update template
|
||||
vim .claude/hooks/post-commit.template
|
||||
|
||||
# Reinstall to all repos
|
||||
cp .claude/hooks/post-commit.template .git/hooks/post-commit
|
||||
cp .claude/hooks/post-commit.template .git/modules/projects/msp-tools/guru-connect/hooks/post-commit
|
||||
cp .claude/hooks/post-commit.template .git/modules/projects/msp-tools/guru-rmm/hooks/post-commit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2026-05-31
|
||||
74
.claude/hooks/post-commit.template
Executable file
74
.claude/hooks/post-commit.template
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# Post-commit hook: Send dev-alerts for feature specs and significant changes
|
||||
|
||||
# Get commit info
|
||||
COMMIT_HASH=$(git rev-parse --short HEAD)
|
||||
COMMIT_MSG=$(git log -1 --pretty=%B)
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
AUTHOR=$(git log -1 --pretty=%an)
|
||||
|
||||
# Determine project from submodule path
|
||||
if git rev-parse --show-toplevel | grep -q "guru-connect"; then
|
||||
PROJECT="guruconnect"
|
||||
PROJECT_NAME="GuruConnect"
|
||||
elif git rev-parse --show-toplevel | grep -q "guru-rmm"; then
|
||||
PROJECT="gururmm"
|
||||
PROJECT_NAME="GuruRMM"
|
||||
else
|
||||
PROJECT="claudetools"
|
||||
PROJECT_NAME="ClaudeTools"
|
||||
fi
|
||||
|
||||
# Check if this is a spec commit (new SPEC-NNN file or updated roadmap)
|
||||
SPEC_FILES=$(git diff-tree --no-commit-id --name-only -r HEAD | grep -E 'docs/specs/SPEC-[0-9]+-.*\.md$')
|
||||
ROADMAP_UPDATED=$(git diff-tree --no-commit-id --name-only -r HEAD | grep -E 'FEATURE_ROADMAP\.md$')
|
||||
|
||||
if [[ -n "$SPEC_FILES" ]]; then
|
||||
# Extract SPEC number and name from first spec file
|
||||
SPEC_FILE=$(echo "$SPEC_FILES" | head -1)
|
||||
SPEC_NUM=$(echo "$SPEC_FILE" | grep -oE 'SPEC-[0-9]+')
|
||||
SPEC_NAME=$(echo "$SPEC_FILE" | sed -E 's/.*SPEC-[0-9]+-(.*)\.md$/\1/' | tr '-' ' ' | sed 's/.*/\u&/')
|
||||
|
||||
# Read spec file to extract key info
|
||||
SPEC_PATH=$(git rev-parse --show-toplevel)/"$SPEC_FILE"
|
||||
PRIORITY=$(grep -m1 "^\*\*Priority:\*\*" "$SPEC_PATH" | sed 's/.*Priority:\*\* //' | tr -d '\n')
|
||||
EFFORT=$(grep -m1 "^\*\*Estimated Effort:\*\*" "$SPEC_PATH" | sed 's/.*Estimated Effort:\*\* //' | tr -d '\n')
|
||||
OVERVIEW=$(sed -n '/^## Overview/,/^##/p' "$SPEC_PATH" | grep -v "^##" | head -5 | tr '\n' ' ')
|
||||
|
||||
# Send dev-alerts message
|
||||
SESSION_ID=$(hostname)/claude-main
|
||||
|
||||
curl -s -X POST http://172.16.3.30:8001/api/coord/messages \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"from_session\": \"$SESSION_ID\",
|
||||
\"to_session\": \"dev-alerts\",
|
||||
\"project_key\": \"$PROJECT\",
|
||||
\"subject\": \"$PROJECT_NAME Feature Spec: $SPEC_NUM $SPEC_NAME\",
|
||||
\"body\": \"New $PROJECT_NAME feature specification created.\\n\\n$SPEC_NUM: $SPEC_NAME\\nPriority: $PRIORITY | Effort: $EFFORT\\n\\nOVERVIEW:\\n$OVERVIEW\\n\\nCommit: $COMMIT_HASH on $BRANCH\\nAuthor: $AUTHOR\\n\\n🤖 Auto-generated via post-commit hook\"
|
||||
}" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Detect build/push events (commit message contains 'spec:', 'feat:', 'fix:', etc.)
|
||||
if echo "$COMMIT_MSG" | grep -qE '^(spec|feat|fix|chore|docs|build):'; then
|
||||
COMMIT_TYPE=$(echo "$COMMIT_MSG" | grep -oE '^[a-z]+:' | tr -d ':')
|
||||
|
||||
# Only send build alerts for significant commits on main branch
|
||||
if [[ "$BRANCH" == "main" ]] && [[ "$COMMIT_TYPE" =~ ^(spec|feat|fix|build)$ ]]; then
|
||||
FILES_CHANGED=$(git diff-tree --no-commit-id --name-only -r HEAD | wc -l | tr -d ' ')
|
||||
|
||||
SESSION_ID=$(hostname)/claude-main
|
||||
|
||||
curl -s -X POST http://172.16.3.30:8001/api/coord/messages \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"from_session\": \"$SESSION_ID\",
|
||||
\"to_session\": \"dev-alerts\",
|
||||
\"project_key\": \"$PROJECT\",
|
||||
\"subject\": \"$PROJECT_NAME Build: $COMMIT_TYPE on main\",
|
||||
\"body\": \"$PROJECT_NAME main branch updated.\\n\\nCOMMIT: $COMMIT_HASH\\nTYPE: $COMMIT_TYPE\\nFILES CHANGED: $FILES_CHANGED\\nBRANCH: $BRANCH\\nAUTHOR: $AUTHOR\\n\\nMESSAGE:\\n$COMMIT_MSG\\n\\n🔨 Auto-generated via post-commit hook\"
|
||||
}" > /dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user