From git-town-workflow
Tether (install/uninstall) hooks that enforce git-town over raw git commands in Claude Code. Renamed from 'hooks' to avoid.
How this skill is triggered — by the user, by Claude, or both
Slash command
/git-town-workflow:tether [install|uninstall|status][install|uninstall|status]haikuThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- ⛔⛔⛔ MANDATORY: READ THIS ENTIRE FILE BEFORE ANY ACTION ⛔⛔⛔ -->
This command installs Claude Code hooks that BLOCK forbidden raw git commands.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
| Forbidden Command | Reason | Replacement |
|---|---|---|
git checkout -b | Creates untracked branches | git town hack |
git pull | Bypasses sync workflow | git town sync |
git merge | Manual merges break flow | git town sync |
git push origin main | Direct main push dangerous | git town sync |
git branch -d | Manual branch deletion | git town delete |
git rebase | Complex, use git-town | git town sync |
| Allowed Command | Reason |
|---|---|
git add | Staging files (git-town doesn't replace) |
git commit | Creating commits (git-town doesn't replace) |
git status | Viewing status (read-only) |
git log | Viewing history (read-only) |
git diff | Viewing changes (read-only) |
git stash | Stashing changes (utility) |
git remote | Remote management (setup only) |
git config | Configuration (setup only) |
The following hook will be added to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/env bash -c 'CMD=\"$CLAUDE_TOOL_INPUT_command\"; case \"$CMD\" in \"git checkout -b\"*|\"git checkout -B\"*) echo \"BLOCKED: Use git town hack instead of git checkout -b\"; exit 1;; \"git pull\"*) echo \"BLOCKED: Use git town sync instead of git pull\"; exit 1;; \"git merge\"*) echo \"BLOCKED: Use git town sync or git town ship instead of git merge\"; exit 1;; \"git push origin main\"*|\"git push origin master\"*) echo \"BLOCKED: Use git town sync instead of pushing to main\"; exit 1;; \"git branch -d\"*|\"git branch -D\"*) echo \"BLOCKED: Use git town delete instead of git branch -d\"; exit 1;; \"git rebase\"*) echo \"BLOCKED: Use git town sync (rebase strategy) instead of git rebase\"; exit 1;; esac'"
}
]
}
]
}
}
/usr/bin/env bash -c 'cat ~/.claude/settings.json 2>/dev/null || echo "{}"'
AskUserQuestion with questions:
- question: "Install git-town enforcement hooks to block forbidden raw git commands?"
header: "Install Hooks"
options:
- label: "Yes, install hooks (Recommended)"
description: "Blocks: git checkout -b, git pull, git merge, git push main"
- label: "No, don't install"
description: "I want to use raw git commands freely"
- label: "Show what will be blocked"
description: "Display full list of blocked commands"
multiSelect: false
Read existing settings, merge hooks, write back:
/usr/bin/env bash << 'INSTALL_HOOK_EOF'
SETTINGS_FILE="$HOME/.claude/settings.json"
# Create file if doesn't exist
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo '{}' > "$SETTINGS_FILE"
fi
# Read existing settings
EXISTING=$(cat "$SETTINGS_FILE")
# Define the new hook
NEW_HOOK='{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/env bash -c '\''CMD=\"$CLAUDE_TOOL_INPUT_command\"; case \"$CMD\" in \"git checkout -b\"*|\"git checkout -B\"*) echo \"BLOCKED: Use git town hack instead of git checkout -b\"; exit 1;; \"git pull\"*) echo \"BLOCKED: Use git town sync instead of git pull\"; exit 1;; \"git merge\"*) echo \"BLOCKED: Use git town sync or git town ship instead of git merge\"; exit 1;; \"git push origin main\"*|\"git push origin master\"*) echo \"BLOCKED: Use git town sync instead of pushing to main\"; exit 1;; \"git branch -d\"*|\"git branch -D\"*) echo \"BLOCKED: Use git town delete instead of git branch -d\"; exit 1;; \"git rebase\"*) echo \"BLOCKED: Use git town sync (rebase strategy) instead of git rebase\"; exit 1;; esac'\''"
}
]
}'
# Merge using jq
echo "$EXISTING" | jq --argjson hook "$NEW_HOOK" '
.hooks.PreToolUse = ((.hooks.PreToolUse // []) + [$hook] | unique_by(.matcher + (.hooks[0].command // "")))
' > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
echo "✅ Hook installed successfully"
cat "$SETTINGS_FILE" | jq '.hooks'
INSTALL_HOOK_EOF
/usr/bin/env bash -c 'cat ~/.claude/settings.json | jq ".hooks.PreToolUse"'
AskUserQuestion with questions:
- question: "Remove git-town enforcement hooks?"
header: "Uninstall"
options:
- label: "Yes, remove hooks"
description: "Allow raw git commands again"
- label: "No, keep hooks"
description: "Keep enforcement active"
multiSelect: false
/usr/bin/env bash << 'UNINSTALL_HOOK_EOF'
SETTINGS_FILE="$HOME/.claude/settings.json"
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo "No settings file found"
exit 0
fi
# Remove git-town enforcement hook
cat "$SETTINGS_FILE" | jq '
.hooks.PreToolUse = [.hooks.PreToolUse[]? | select(.matcher != "Bash" or (.hooks[0].command | contains("git town") | not))]
' > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
echo "✅ Hook removed successfully"
UNINSTALL_HOOK_EOF
/usr/bin/env bash << 'STATUS_HOOK_EOF'
SETTINGS_FILE="$HOME/.claude/settings.json"
echo "=== GIT-TOWN ENFORCEMENT HOOK STATUS ==="
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo "❌ No settings file found"
echo " Run: /git-town-workflow:tether install"
exit 0
fi
# Check if hook exists
HOOK_EXISTS=$(cat "$SETTINGS_FILE" | jq '[.hooks.PreToolUse[]? | select(.hooks[0].command | contains("git town"))] | length')
if [[ "$HOOK_EXISTS" -gt 0 ]]; then
echo "✅ Git-town enforcement hook is ACTIVE"
echo ""
echo "Blocked commands:"
echo " - git checkout -b → use git town hack"
echo " - git pull → use git town sync"
echo " - git merge → use git town sync"
echo " - git push origin main → use git town sync"
echo " - git branch -d → use git town delete"
echo " - git rebase → use git town sync"
else
echo "❌ Git-town enforcement hook is NOT installed"
echo " Run: /git-town-workflow:tether install"
fi
STATUS_HOOK_EOF
install - Install enforcement hooksuninstall - Remove enforcement hooksstatus - Show current hook status# Install hooks
/git-town-workflow:tether install
# Check status
/git-town-workflow:tether status
# Remove hooks
/git-town-workflow:tether uninstall
| Issue | Cause | Solution |
|---|---|---|
| jq not found | jq not installed | brew install jq |
| Settings file not found | ~/.claude/ doesn't exist | Create with mkdir -p ~/.claude |
| Hook not blocking | Session not restarted | Restart Claude Code session |
| Invalid JSON error | Corrupted settings.json | Check JSON syntax or restore backup |
| Hook still active | Multiple hooks registered | Uninstall and reinstall to dedupe |
After this skill completes, reflect before closing the task:
Do NOT defer. The next invocation inherits whatever you leave behind.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
npx claudepluginhub terrylica/cc-skills --plugin git-town-workflow