79 lines
2.5 KiB
Python
Executable File
79 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Добавляет или убирает хуки панели в ~/.claude/settings.json, не трогая остальное.
|
|
|
|
settings_hooks.py add <settings.json>
|
|
settings_hooks.py remove <settings.json>
|
|
"""
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
MARK = "agents_panel_hook"
|
|
COMMAND = 'sh "$HOME/.claude/hooks/agents_panel_hook.sh"'
|
|
EVENTS = { # событие -> matcher (None — без фильтра)
|
|
"SessionStart": None, "SessionEnd": None, "UserPromptSubmit": None, "Stop": None,
|
|
"Notification": None, "SubagentStart": None, "SubagentStop": None,
|
|
"PostModelSwitch": None, "PreToolUse": "Agent|Task",
|
|
}
|
|
|
|
|
|
def ours(hook):
|
|
return isinstance(hook, dict) and MARK in str(hook.get("command", ""))
|
|
|
|
|
|
def add(cfg):
|
|
hooks = cfg.setdefault("hooks", {})
|
|
added = []
|
|
for event, matcher in EVENTS.items():
|
|
groups = hooks.setdefault(event, [])
|
|
if any(ours(h) for g in groups for h in (g.get("hooks") or [])):
|
|
continue # уже стоит — повторная установка ничего не дублирует
|
|
group = {"hooks": [{"type": "command", "command": COMMAND}]}
|
|
if matcher:
|
|
group = {"matcher": matcher, **group}
|
|
groups.append(group)
|
|
added.append(event)
|
|
return added
|
|
|
|
|
|
def remove(cfg):
|
|
hooks = cfg.get("hooks") or {}
|
|
removed = []
|
|
for event in list(hooks):
|
|
groups = []
|
|
for g in hooks[event]:
|
|
kept = [h for h in (g.get("hooks") or []) if not ours(h)]
|
|
if len(kept) != len(g.get("hooks") or []):
|
|
removed.append(event)
|
|
if kept:
|
|
groups.append({**g, "hooks": kept})
|
|
if groups:
|
|
hooks[event] = groups
|
|
else:
|
|
del hooks[event]
|
|
if "hooks" in cfg and not cfg["hooks"]:
|
|
del cfg["hooks"]
|
|
return sorted(set(removed))
|
|
|
|
|
|
def main():
|
|
action, path = sys.argv[1], os.path.expanduser(sys.argv[2])
|
|
cfg = {}
|
|
if os.path.exists(path):
|
|
with open(path, encoding="utf-8") as f:
|
|
text = f.read().strip()
|
|
cfg = json.loads(text) if text else {}
|
|
changed = add(cfg) if action == "add" else remove(cfg)
|
|
if changed:
|
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
tmp = path + ".tmp"
|
|
with open(tmp, "w", encoding="utf-8") as f:
|
|
json.dump(cfg, f, ensure_ascii=False, indent=2)
|
|
f.write("\n")
|
|
os.replace(tmp, path)
|
|
print(", ".join(changed) if changed else "—")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|