- Add PreToolUse hook intercepting Bash, Write, Edit - Block catastrophic commands (rm -rf /, mkfs, etc.) - Require confirmation for operations outside safe paths - Git-aware: operations in git repos are allowed - Session allowlist for user-confirmed operations - Audit logging to logs/guardrail.jsonl - Clear session allowlist on SessionEnd Config: state/guardrails.json Scripts: hooks/scripts/guardrail.py, guardrail-confirm.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
1.8 KiB
Python
Executable File
74 lines
1.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Guardrail Confirm Helper
|
|
|
|
Adds an operation to the session allowlist so it can proceed on retry.
|
|
|
|
Usage:
|
|
python3 guardrail-confirm.py "<tool>" "<operation>"
|
|
|
|
Example:
|
|
python3 guardrail-confirm.py "Bash" "rm -rf ~/Downloads/old-project"
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
HOME = Path.home()
|
|
STATE_DIR = HOME / ".claude" / "state"
|
|
SESSION_FILE = STATE_DIR / "guardrail-session.json"
|
|
|
|
|
|
def load_session():
|
|
"""Load current session allowlist."""
|
|
if not SESSION_FILE.exists():
|
|
return {"confirmed": []}
|
|
try:
|
|
with open(SESSION_FILE) as f:
|
|
return json.load(f)
|
|
except (json.JSONDecodeError, IOError):
|
|
return {"confirmed": []}
|
|
|
|
|
|
def save_session(data: dict):
|
|
"""Save session allowlist."""
|
|
STATE_DIR.mkdir(parents=True, exist_ok=True)
|
|
with open(SESSION_FILE, "w") as f:
|
|
json.dump(data, f, indent=2)
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print("Usage: guardrail-confirm.py <tool> <operation>")
|
|
print("Example: guardrail-confirm.py 'Bash' 'rm ~/Downloads/old'")
|
|
sys.exit(1)
|
|
|
|
tool = sys.argv[1]
|
|
operation = sys.argv[2]
|
|
|
|
# Load current session
|
|
session = load_session()
|
|
|
|
# Check if already confirmed
|
|
for item in session.get("confirmed", []):
|
|
if item.get("tool") == tool and item.get("operation") == operation:
|
|
print(f"Already confirmed: {tool} - {operation[:50]}...")
|
|
sys.exit(0)
|
|
|
|
# Add to allowlist
|
|
session["confirmed"].append({
|
|
"tool": tool,
|
|
"operation": operation,
|
|
"ts": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
|
})
|
|
|
|
save_session(session)
|
|
print(f"Confirmed: {tool} - {operation[:50]}...")
|
|
print("You may now retry the operation.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|