chore: import upstream snapshot with attribution
Component Security Validation / Security Audit (push) Has been cancelled
Deploy to Cloudflare Pages / deploy (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:38:58 +08:00
commit bb5c75ce05
8824 changed files with 1946442 additions and 0 deletions
@@ -0,0 +1,16 @@
{
"description": "Enforce conventional commit message format for all git commits. Validates commit messages follow the pattern: type(scope): description. Supported types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert. Ensures consistent commit history for changelog generation and semantic versioning.",
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/conventional-commits.py"
}
]
}
]
}
}
@@ -0,0 +1,84 @@
#!/usr/bin/env python3
import json
import sys
import re
try:
input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
sys.exit(1)
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")
# Only validate git commit commands
if tool_name != "Bash" or "git commit" not in command:
sys.exit(0)
# Extract commit message from -m flag
# Handle both -m "message" and -m 'message' formats
match = re.search(r'git commit.*?-m\s+["\']([^"\']+)["\']', command)
if not match:
# Also try heredoc format: -m "$(cat <<'EOF' ... EOF)"
heredoc_match = re.search(r'git commit.*?-m\s+"?\$\(cat\s+<<["\']?EOF["\']?\s*\n(.+?)\nEOF', command, re.DOTALL)
if heredoc_match:
commit_msg = heredoc_match.group(1).strip()
else:
sys.exit(0) # Can't extract message, allow it
else:
commit_msg = match.group(1)
# Check if message follows Conventional Commits format
# Format: type(scope)?: description
# Types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert
conventional_pattern = r'^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?:\s.+'
if not re.match(conventional_pattern, commit_msg):
reason = f"""❌ Invalid commit message format
Your message: {commit_msg}
Commit messages must follow Conventional Commits:
type(scope): description
Types:
feat: New feature
fix: Bug fix
docs: Documentation changes
style: Code style changes (formatting)
refactor: Code refactoring
perf: Performance improvements
test: Adding or updating tests
chore: Maintenance tasks
ci: CI/CD changes
build: Build system changes
revert: Revert previous commit
Examples:
✅ feat: add user authentication
✅ feat(auth): implement JWT tokens
✅ fix: resolve memory leak in parser
✅ fix(api): handle null responses
✅ docs: update API documentation
Invalid:
❌ Added new feature (no type)
❌ feat:add feature (missing space after colon)
❌ feature: add login (wrong type, use 'feat')
💡 Tip: Start your message with one of the types above followed by a colon and space."""
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": reason
}
}
print(json.dumps(output))
sys.exit(0)
# Allow the command
sys.exit(0)
@@ -0,0 +1,16 @@
{
"description": "Prevent direct pushes to protected branches (main, develop). Blocks git push commands targeting main or develop branches to enforce Git Flow workflow. Requires using feature/release/hotfix branches and pull requests instead of direct commits to protected branches.",
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/prevent-direct-push.py"
}
]
}
]
}
}
@@ -0,0 +1,86 @@
#!/usr/bin/env python3
import json
import sys
import subprocess
try:
input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
sys.exit(1)
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")
# Only validate git push commands
if tool_name != "Bash" or "git push" not in command:
sys.exit(0)
# Get current branch
try:
current_branch = subprocess.check_output(
["git", "branch", "--show-current"],
stderr=subprocess.DEVNULL,
text=True
).strip()
except:
current_branch = ""
# Check if pushing to main or develop
push_cmd = command
is_force_push = "--force" in push_cmd or "-f" in push_cmd
# Check if command or current branch targets protected branches
targets_protected = (
"origin main" in push_cmd or
"origin develop" in push_cmd or
current_branch in ["main", "develop"]
)
# Block direct push to main/develop (unless force push which is already dangerous)
if targets_protected and not is_force_push:
if current_branch in ["main", "develop"] or "origin main" in push_cmd or "origin develop" in push_cmd:
reason = f"""❌ Direct push to main/develop is not allowed!
Protected branches:
- main (production)
- develop (integration)
Git Flow workflow:
1. Create a feature branch:
/feature <name>
2. Make your changes and commit
3. Push feature branch:
git push origin feature/<name>
4. Create pull request:
gh pr create
5. After approval, merge with:
/finish
For releases:
/release <version> → PR → /finish
For hotfixes:
/hotfix <name> → PR → /finish
Current branch: {current_branch}
💡 Use feature/release/hotfix branches instead of pushing directly to main/develop."""
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": reason
}
}
print(json.dumps(output))
sys.exit(0)
# Allow the command
sys.exit(0)
@@ -0,0 +1,16 @@
{
"description": "Validate Git Flow branch naming conventions before checkout. Ensures branches follow the pattern: feature/*, release/v*.*.*, hotfix/*. Prevents creation of branches that don't follow Git Flow standards.",
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate-branch-name.py"
}
]
}
]
}
}
@@ -0,0 +1,96 @@
#!/usr/bin/env python3
import json
import sys
import re
try:
input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
sys.exit(1)
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")
# Only validate git checkout -b commands
if tool_name != "Bash" or "git checkout -b" not in command:
sys.exit(0)
# Extract branch name
match = re.search(r'git checkout -b\s+([^\s]+)', command)
if not match:
sys.exit(0)
branch_name = match.group(1)
# Allow main and develop branches
if branch_name in ["main", "develop"]:
sys.exit(0)
# Validate Git Flow naming convention
if not re.match(r'^(feature|release|hotfix)/', branch_name):
reason = f"""❌ Invalid Git Flow branch name: {branch_name}
Git Flow branches must follow these patterns:
• feature/<descriptive-name>
• release/v<MAJOR>.<MINOR>.<PATCH>
• hotfix/<descriptive-name>
Examples:
✅ feature/user-authentication
✅ release/v1.2.0
✅ hotfix/critical-security-fix
Invalid:
{branch_name} (missing Git Flow prefix)
❌ feat/something (use 'feature/' not 'feat/')
❌ fix/bug (use 'hotfix/' not 'fix/')
💡 Use Git Flow commands instead:
/feature <name> - Create feature branch
/release <version> - Create release branch
/hotfix <name> - Create hotfix branch"""
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": reason
}
}
print(json.dumps(output))
sys.exit(0)
# Validate release version format
if branch_name.startswith("release/"):
if not re.match(r'^release/v\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$', branch_name):
reason = f"""❌ Invalid release version: {branch_name}
Release branches must follow semantic versioning:
release/vMAJOR.MINOR.PATCH[-prerelease]
Valid examples:
✅ release/v1.0.0
✅ release/v2.1.3
✅ release/v1.0.0-beta.1
Invalid:
❌ release/1.0.0 (missing 'v' prefix)
❌ release/v1.0 (incomplete version)
{branch_name}
💡 Use: /release v1.2.0"""
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": reason
}
}
print(json.dumps(output))
sys.exit(0)
# Allow the command
sys.exit(0)