Appearance
inject-rules.sh
.claude/hooks/inject-rules.sh
UserPromptSubmit
Deterministic path-scoped rule loading. Reads the current working set (git status) and prints the .claude/rules/*.md files whose scope matches the changed paths. Claude Code adds this stdout to the model's context, so the relevant project conventions are in force whenever you're actively touching that area — reinforcing the routing table in CLAUDE.md. code-quality.md is intentionally skipped: it is always-on via CLAUDE.md, so re-injecting it here would just duplicate tokens.
Source
bash
#!/usr/bin/env bash
#
# UserPromptSubmit hook — deterministic path-scoped rule loading.
#
# Reads the current working set (git status) and prints the .claude/rules/*.md
# files whose scope matches the changed paths. Claude Code adds this stdout to
# the model's context, so the relevant project conventions are in force whenever
# you're actively touching that area — reinforcing the routing table in CLAUDE.md.
#
# code-quality.md is intentionally skipped: it is always-on via CLAUDE.md, so
# re-injecting it here would just duplicate tokens.
set -euo pipefail
cd "${CLAUDE_PROJECT_DIR:-.}" || exit 0
rules_dir=".claude/rules"
[ -d "$rules_dir" ] || exit 0
# Changed/added/renamed files (staged, unstaged, untracked). Strip the 2-char
# status + space; for renames ("old -> new") keep the new path.
files="$(git status --porcelain 2>/dev/null | sed 's/^...//' || true)"
[ -n "$files" ] || exit 0
declare -A want=()
while IFS= read -r f; do
[ -n "$f" ] || continue
f="${f##*-> }"
case "$f" in
app/Models/*|database/migrations/*)
want[database]=1; want[security]=1; want[php-laravel]=1 ;;
app/Http/Controllers/*|app/Http/Requests/*)
want[php-laravel]=1; want[security]=1; want[inertia]=1 ;;
app/*)
want[php-laravel]=1 ;;
resources/js/*)
want[frontend]=1; want[inertia]=1 ;;
resources/css/*)
want[frontend]=1 ;;
tests/*)
want[testing]=1 ;;
.claude/skills/*)
want[skills]=1 ;;
esac
done <<< "$files"
[ "${#want[@]}" -gt 0 ] || exit 0
printf '## Active project rules for your current changes (.claude/rules/)\n'
printf 'These are auto-loaded because your working set touches their scope. Follow them.\n'
for r in php-laravel database security inertia frontend testing skills; do
if [ "${want[$r]:-}" = "1" ] && [ -f "$rules_dir/$r.md" ]; then
printf '\n'
cat "$rules_dir/$r.md"
fi
done