groove-admin-claude-hooks
Install groove's Claude Code native shell hooks. These run outside the model — deterministic, unconditional — and complement groove's advisory markdown hooks (
.groove/hooks/start.md
,
end.md
).
Use
--disable
!/usr/bin/env bash
groove: Stop hook — remind about /groove-daily-end during work hours
hour
$( date +%H ) if [ -f ".groove/index.md" ] && [ " $hour " -ge 16 ] && [ " $hour " -le 21 ] ; then echo "groove: end of work hours — consider running /groove-daily-end" fi git-activity-buffer.sh
!/usr/bin/env bash
groove: PostToolUse/Bash hook — buffer git commits for memory log
input
$( cat ) command = $( echo " $input " | python3 -c "import sys,json ; d = json.load ( sys.stdin ) ; print ( d.get ( 'tool_input' , { } ) .get ( 'command' , '' ) ) " 2
/dev/null ) if echo " $command " | grep -q "git commit" ; then msg = $( echo " $command " | grep -oP '(?<=-m ")[^"]+' | head -1 ) mkdir -p .groove/.cache echo " $( date '+%Y-%m-%d %H:%M' ) | ${msg :-
} " .groove/.cache/git-activity-buffer.txt fi block-managed-paths.sh
!/usr/bin/env bash
groove: PreToolUse/Write+Edit hook — block edits to managed groove paths
input
$( cat ) path = $( echo " $input " | python3 -c "import sys,json ; d = json.load ( sys.stdin ) ; print ( d.get ( 'tool_input' , { } ) .get ( 'file_path' , '' ) ) " 2
/dev/null ) if echo " $path " | grep -qE '^(.agents/skills/groove|skills/groove)' ; then echo "groove: blocked — ' $path ' is managed by groove update. Edit under skills/ and rsync to .agents/skills/."
&2 exit 1 fi version-check.sh
!/usr/bin/env bash
groove: PostToolUse hook — check for new groove version (once per hour)
CACHE
".groove/.cache/last-version-check-ts" mkdir -p .groove/.cache now = $( date +%s ) if [ -f " $CACHE " ] ; then last = $( cat " $CACHE " ) diff = $(( now - last )) [ " $diff " -lt 3600 ] && exit 0 fi echo " $now "
" $CACHE " bash .agents/skills/groove-utilities-check/scripts/check.sh 2
/dev/null || true .claude/settings.json entries Merge these into the hooks key. Preserve all other keys. { "hooks" : { "Stop" : [ { "hooks" : [ { "type" : "command" , "command" : "bash .groove/hooks/claude/daily-end-reminder.sh" } ] } ] , "PostToolUse" : [ { "matcher" : "Bash" , "hooks" : [ { "type" : "command" , "command" : "bash .groove/hooks/claude/git-activity-buffer.sh" } ] } , { "hooks" : [ { "type" : "command" , "command" : "bash .groove/hooks/claude/version-check.sh" } ] } ] , "PreToolUse" : [ { "matcher" : "Write" , "hooks" : [ { "type" : "command" , "command" : "bash .groove/hooks/claude/block-managed-paths.sh" } ] } , { "matcher" : "Edit" , "hooks" : [ { "type" : "command" , "command" : "bash .groove/hooks/claude/block-managed-paths.sh" } ] } ] , "SessionStart" : [ { "matcher" : "startup|compact" , "hooks" : [ { "type" : "command" , "command" : "bash .agents/skills/groove-utilities-prime/scripts/groove-utilities-prime.sh" } ] } ] } } When merging: if a hooks key already exists, append groove entries to the relevant event arrays. Do not create duplicates — check if a groove command entry already exists before appending. Constraints Never overwrite non-groove entries in .claude/settings.json Never overwrite an existing script without diff + confirmation Scripts use python3 to parse JSON stdin — if python3 is absent, skip that hook and warn block-managed-paths is aggressive: if it causes false positives the user can disable it with --disable block-managed-paths After install: remind the user that hooks take effect on the next Claude Code session restart .groove/hooks/claude/ follows the git.hooks git strategy from .groove/index.md