-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathguard.py
More file actions
51 lines (45 loc) · 1.98 KB
/
Copy pathguard.py
File metadata and controls
51 lines (45 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/env python3
"""Block `git commit` until /simplify runs. Each commit spends one /simplify.
The marker lives in the per-worktree git dir (`git rev-parse --git-dir`): /simplify reviews the
staged diff and the index is per-worktree, so the token is minted and spent in the same worktree
any session or subagent commits from. /simplify mints via the Skill tool, which only Claude Code
fires, so the commit deny is scoped to Claude Code, other harnesses that can never mint are not
blocked.
"""
import json
import os
import re
import subprocess
import sys
from pathlib import Path
data = json.load(sys.stdin)
event = data.get("hook_event_name", "")
tool_input = data.get("tool_input") or {}
def marker():
git_dir = subprocess.run(
["git", "-C", data.get("cwd") or ".", "rev-parse", "--path-format=absolute", "--git-dir"],
capture_output=True,
text=True,
).stdout.strip()
return Path(git_dir) / "simplify-guard.ok" if git_dir else None
# PostToolUse matcher scopes to the Skill tool, confirm it was /simplify
if event == "PostToolUse" and tool_input.get("skill") == "simplify" and (m := marker()):
m.touch()
elif event == "PreToolUse" and os.environ.get("CLAUDECODE") == "1":
# match a real `git commit` (not commit-graph/-tree) with quoted args stripped
bare = re.sub(r"'[^']*'|\"[^\"]*\"", "", tool_input.get("command", ""))
if re.search(r"git\s+commit(?![\w-])", bare) and (m := marker()):
if m.exists():
m.unlink() # spend the token: this commit uses up the pending /simplify
else:
print(
json.dumps(
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "simplify-guard: run /simplify on the staged diff first, then retry the commit.",
}
}
)
)