aboutsummaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-19 17:06:10 -0500
committerCraig Jennings <c@cjennings.net>2026-04-19 17:06:10 -0500
commit4957c60c9ee985628ad59344e593d20a18ca8fdb (patch)
treee8d6659dd2d7dd24126782fa83ccccffc6c6f836 /Makefile
parentab4a07b3c081609a81ee049ec9bbe6ccded09b54 (diff)
downloadrulesets-4957c60c9ee985628ad59344e593d20a18ca8fdb.tar.gz
rulesets-4957c60c9ee985628ad59344e593d20a18ca8fdb.zip
feat(hooks): add global hooks — PreCompact priorities + git/gh confirm modals
Three new machine-wide hooks installed via `make install-hooks`: - `precompact-priorities.sh` (PreCompact) — injects a priority block into the compaction prompt so the generated summary retains information most expensive to reconstruct: unanswered questions, root causes with file:line, subagent findings as primary evidence, exact numbers/IDs, A-vs-B decisions, open TODOs, classified-data handling. - `git-commit-confirm.py` (PreToolUse/Bash) — gates `git commit` behind a confirmation modal showing parsed message, staged files, diff stats, author. Parses both HEREDOC and `-m`/`--message` forms. - `gh-pr-create-confirm.py` (PreToolUse/Bash) — gates `gh pr create` behind a modal showing title, base ← head, reviewers, labels, assignees, milestone, draft flag, body (HEREDOC or quoted). Makefile: adds `install-hooks` / `uninstall-hooks` targets and extends `list` with a Hooks section. Install prints the settings.json snippet (in `hooks/settings-snippet.json`) to merge into `~/.claude/settings.json`. Also: `languages/elisp/claude/hooks/validate-el.sh` now emits JSON with `hookSpecificOutput.additionalContext` on failure (via new `fail_json()` helper) so Claude sees a structured error in context, in addition to the existing stderr output and exit 2. Patterns synthesized clean-room from fcakyon/claude-codex-settings (Apache-2.0). Each hook is original content.
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile48
1 files changed, 47 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index d37e955..1e9a1e8 100644
--- a/Makefile
+++ b/Makefile
@@ -3,12 +3,14 @@ SHELL := /bin/bash
SKILLS_DIR := $(HOME)/.claude/skills
RULES_DIR := $(HOME)/.claude/rules
+HOOKS_DIR := $(HOME)/.claude/hooks
SKILLS := c4-analyze c4-diagram debug add-tests respond-to-review review-code fix-issue security-check \
arch-design arch-decide arch-document arch-evaluate \
brainstorm codify root-cause-trace five-whys prompt-engineering \
playwright-js playwright-py frontend-design pairwise-tests \
finish-branch
RULES := $(wildcard claude-rules/*.md)
+HOOKS := $(wildcard hooks/*.sh hooks/*.py)
LANGUAGES := $(notdir $(wildcard languages/*))
# Pick target project — use PROJECT= or interactive fzf over local .git dirs.
@@ -35,7 +37,7 @@ $(if $(shell command -v pacman 2>/dev/null),sudo pacman -S --noconfirm $(1),\
$(error No supported package manager found (brew/apt-get/pacman)))))
endef
-.PHONY: help install uninstall list \
+.PHONY: help install uninstall list install-hooks uninstall-hooks \
install-lang install-elisp install-python list-languages \
diff lint deps
@@ -168,6 +170,50 @@ list: ## Show global install status
echo " - $$name"; \
fi \
done
+ @echo ""
+ @echo "Hooks:"
+ @for hook in $(HOOKS); do \
+ name=$$(basename $$hook); \
+ if [ -L "$(HOOKS_DIR)/$$name" ]; then \
+ echo " ✓ $$name (installed)"; \
+ else \
+ echo " - $$name"; \
+ fi \
+ done
+
+install-hooks: ## Symlink global hooks into ~/.claude/hooks/ + print settings.json snippet
+ @mkdir -p $(HOOKS_DIR)
+ @echo "Hooks:"
+ @for hook in $(HOOKS); do \
+ name=$$(basename $$hook); \
+ if [ -L "$(HOOKS_DIR)/$$name" ]; then \
+ echo " skip $$name (already linked)"; \
+ elif [ -e "$(HOOKS_DIR)/$$name" ]; then \
+ echo " WARN $$name exists and is not a symlink — skipping"; \
+ else \
+ ln -s "$(CURDIR)/$$hook" "$(HOOKS_DIR)/$$name"; \
+ echo " link $$name → $(HOOKS_DIR)/$$name"; \
+ fi \
+ done
+ @echo ""
+ @echo "Merge this into ~/.claude/settings.json (preserve any existing hooks arrays):"
+ @echo ""
+ @cat hooks/settings-snippet.json
+ @echo ""
+ @echo "After merging, reload Claude Code (open /hooks menu once, or restart the session)."
+
+uninstall-hooks: ## Remove global hook symlinks from ~/.claude/hooks/
+ @for hook in $(HOOKS); do \
+ name=$$(basename $$hook); \
+ if [ -L "$(HOOKS_DIR)/$$name" ]; then \
+ rm "$(HOOKS_DIR)/$$name"; \
+ echo " rm $$name"; \
+ else \
+ echo " skip $$name (not a symlink)"; \
+ fi \
+ done
+ @echo ""
+ @echo "Note: this does NOT edit ~/.claude/settings.json — remove the hook entries manually."
##@ Per-project language bundles