Loading...
Loading...
Blocks destructive git and filesystem commands before execution. Prevents accidental loss of uncommitted work from git checkout --, git reset --hard, rm -rf, and similar destructive operations. Works as a Claude Code PreToolUse hook with fail-open semantics.
npx skill4agent add terraphim/terraphim-skills git-safety-guardterraphim-agent guardClaude Code PreToolUse
|
v
git_safety_guard.sh (shell wrapper)
|
v
terraphim-agent guard --json "$COMMAND"
|
v
Pattern Matching (Regex)
|
+---> SAFE_PATTERNS (allowlist) -> Allow
|
+---> DESTRUCTIVE_PATTERNS -> Block with reason
|
+---> No match -> Allow| Command Pattern | Reason |
|---|---|
| Discards uncommitted changes permanently |
| Discards uncommitted changes (except --staged) |
| Destroys all uncommitted changes |
| Can lose uncommitted changes |
| Removes untracked files permanently |
| Destroys remote history |
| Same as --force |
| Force-deletes branch without merge check |
| Recursive file deletion |
| Permanently deletes stashed changes |
| Deletes ALL stashed changes |
| Bypasses pre-commit and commit-msg hooks |
| Same as --no-verify |
| Bypasses pre-push hooks |
| Command Pattern | Why Safe |
|---|---|
| Creates new branch, doesn't modify files |
| Creates orphan branch |
| Only unstages files, doesn't discard changes |
| Preview only, no actual deletion |
| Safer force push with remote check |
| Temp directories are designed for ephemeral data |
| System temp directory |
| User's temp directory |
# Install terraphim-agent from GitHub releases (latest version)
# macOS ARM64 (Apple Silicon)
gh release download --repo terraphim/terraphim-ai \
--pattern "terraphim-agent-aarch64-apple-darwin" --dir /tmp
chmod +x /tmp/terraphim-agent-aarch64-apple-darwin
mv /tmp/terraphim-agent-aarch64-apple-darwin ~/.cargo/bin/terraphim-agent
# macOS x86_64 (Intel)
# gh release download --repo terraphim/terraphim-ai \
# --pattern "terraphim-agent-x86_64-apple-darwin" --dir /tmp
# Linux x86_64
# gh release download --repo terraphim/terraphim-ai \
# --pattern "terraphim-agent-x86_64-unknown-linux-gnu" --dir /tmp
# Note: crates.io version (cargo install terraphim_agent) is outdated (v1.0.0)
# and missing the guard command. Use GitHub releases for latest features.
# Test guard command
echo "git checkout -- file.txt" | terraphim-agent guard --json
# Output: {"decision":"block","reason":"git checkout -- discards...","command":"..."}
echo "git checkout -b new-branch" | terraphim-agent guard --json
# Output: {"decision":"allow","command":"git checkout -b new-branch"}# Copy hook script
cp .claude/hooks/git_safety_guard.sh /your/project/.claude/hooks/
# Add to .claude/settings.local.json
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": ".claude/hooks/git_safety_guard.sh"
}]
}]
}
}# Run install script with --global flag
./scripts/install-terraphim-hooks.sh --global# Check a command (JSON output)
echo "git reset --hard" | terraphim-agent guard --json
# Check a command (human output - exits with code 1 if blocked)
echo "rm -rf /home/user" | terraphim-agent guard
# Fail-open mode (always exit 0)
echo "git checkout -- ." | terraphim-agent guard --fail-open# Check if terraphim-agent is available
if command -v terraphim-agent >/dev/null 2>&1; then
echo "Guard available"
elif [ -x "./target/release/terraphim-agent" ]; then
AGENT="./target/release/terraphim-agent"
fi#!/bin/bash
# Read JSON input
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
# Only process Bash commands
[ "$TOOL_NAME" != "Bash" ] && exit 0
# Check command
RESULT=$(terraphim-agent guard --json <<< "$COMMAND")
# If blocked, output deny decision
if echo "$RESULT" | jq -e '.decision == "block"' >/dev/null; then
REASON=$(echo "$RESULT" | jq -r '.reason')
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "BLOCKED: $REASON"
}
}
EOF
fi
exit 0{
"decision": "block",
"reason": "git checkout -- discards uncommitted changes permanently. Use 'git stash' first.",
"command": "git checkout -- file.txt",
"pattern": "git\\s+checkout\\s+--\\s+"
}{
"decision": "allow",
"command": "git checkout -b new-branch"
}export TERRAPHIM_VERBOSE=1BLOCKED by git_safety_guard
Reason: git checkout -- discards uncommitted changes permanently. Use 'git stash' first.
Command: git checkout -- file.txt
If this operation is truly needed, ask the user for explicit permission and have them run the command manually.# Manual test - should be blocked
echo "git checkout -- test.txt" | terraphim-agent guard --json
# Manual test - should be allowed
echo "git checkout -b feature" | terraphim-agent guard --json
# Run unit tests
cargo test -p terraphim_agent guard_patterns
# Test hook script
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | \
.claude/hooks/git_safety_guard.sh| Issue | Solution |
|---|---|
| Hook not triggering | Check |
| Command not blocked | Verify pattern matches with |
| Agent not found | Build with |
| Permission denied | Run |
| jq not found | Install jq: |
git checkout --git fsck --lost-foundterraphim-hooksimplementationtestingdevops