groove-admin-cursor-hooks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<!-- groove:managed — do not edit; changes will be overwritten by groove update -->
<!-- groove:managed — do not edit; changes will be overwritten by groove update -->
groove-admin-cursor-hooks
groove-admin-cursor-hooks
Install groove's Cursor native hooks. These run outside the model — deterministic, unconditional — and complement groove's advisory markdown hooks (, ).
.groove/hooks/start.mdend.mdUse to remove a specific hook. Use to show current status.
--disable <hook>--list安装groove的Cursor原生钩子。这些钩子在模型外部运行——具有确定性、无条件性——是对groove的建议性Markdown钩子(、)的补充。
.groove/hooks/start.mdend.md使用移除特定钩子。使用查看当前状态。
--disable <hook>--listOutcome
执行结果
Selected hooks are registered in and shell scripts are written to . Hooks fire automatically on Cursor lifecycle events without any model involvement.
.cursor/hooks.json.groove/hooks/cursor/选中的钩子将注册到中,同时Shell脚本会写入到目录。钩子会在Cursor生命周期事件触发时自动运行,无需模型参与。
.cursor/hooks.json.groove/hooks/cursor/Available hooks
可用钩子
| Name | Event | Matcher | What it does |
|---|---|---|---|
| | — | Runs the prime script with |
| | — | If hour is 16–21 local time and |
| | | If the command contains |
| | | If |
| | — | Checks for a new groove version once per hour; calls |
| 名称 | 事件 | 匹配器 | 功能 |
|---|---|---|---|
| | — | 运行带有 |
| | — | 如果当地时间为16-21点且存在 |
| | | 如果命令包含 |
| | | 如果 |
| | — | 每小时检查一次groove的新版本;调用 |
Steps
操作步骤
--list
--list--list
--listRead if it exists. Report which groove hooks are registered and which scripts exist in . Exit.
.cursor/hooks.json.groove/hooks/cursor/如果存在则读取该文件。报告已注册的groove钩子以及目录中存在的脚本。然后退出。
.cursor/hooks.json.groove/hooks/cursor/--disable <hook>
--disable <hook>--disable <hook>
--disable <hook>Remove the named hook's entry from (leave the script in place). Report removed / not found. Exit.
.cursor/hooks.json从中移除指定钩子的条目(保留脚本文件)。报告移除结果/未找到。然后退出。
.cursor/hooks.jsonDefault (install)
默认操作(安装)
-
Ask which hooks to enable (default: all five):
Which hooks to install? (all / comma-separated: context-reprime, daily-end-reminder, git-activity-buffer, block-managed-paths, version-check) Press enter for all. -
Readif it exists; parse as JSON (default
.cursor/hooks.json). Never discard existing non-groove entries.{"version": 1, "hooks": {}} -
Createdirectory if absent. Make each script executable (
.groove/hooks/cursor/).chmod +x -
For each selected hook: write the shell script and merge the hook entry into.
.cursor/hooks.json -
Writewith the merged result.
.cursor/hooks.json -
Report summary:
✓ context-reprime — sessionStart hook → groove-utilities-prime.sh --json ✓ daily-end-reminder — stop hook → .groove/hooks/cursor/daily-end-reminder.sh ✓ git-activity-buffer — postToolUse/Shell hook → .groove/hooks/cursor/git-activity-buffer.sh ✓ block-managed-paths — preToolUse/Write hook → .groove/hooks/cursor/block-managed-paths.sh ✓ version-check — postToolUse hook → .groove/hooks/cursor/version-check.sh ✓ .cursor/hooks.json updated
-
询问要启用哪些钩子(默认:全部五个):
Which hooks to install? (all / comma-separated: context-reprime, daily-end-reminder, git-activity-buffer, block-managed-paths, version-check) Press enter for all. -
如果存在则读取该文件;解析为JSON(默认值
.cursor/hooks.json)。绝不丢弃现有非groove条目。{"version": 1, "hooks": {}} -
如果目录不存在则创建该目录。设置每个脚本为可执行权限(
.groove/hooks/cursor/)。chmod +x -
对于每个选中的钩子:写入Shell脚本并将钩子条目合并到中。
.cursor/hooks.json -
将合并后的结果写入。
.cursor/hooks.json -
报告摘要:
✓ context-reprime — sessionStart hook → groove-utilities-prime.sh --json ✓ daily-end-reminder — stop hook → .groove/hooks/cursor/daily-end-reminder.sh ✓ git-activity-buffer — postToolUse/Shell hook → .groove/hooks/cursor/git-activity-buffer.sh ✓ block-managed-paths — preToolUse/Write hook → .groove/hooks/cursor/block-managed-paths.sh ✓ version-check — postToolUse hook → .groove/hooks/cursor/version-check.sh ✓ .cursor/hooks.json updated
Shell script templates
Shell脚本模板
Write these verbatim to . Never overwrite an existing script without showing a diff and confirming.
.groove/hooks/cursor/将这些内容原封不动写入目录。未经显示差异并确认,绝不覆盖现有脚本。
.groove/hooks/cursor/daily-end-reminder.sh
daily-end-reminder.shdaily-end-reminder.sh
daily-end-reminder.shbash
#!/usr/bin/env bashbash
#!/usr/bin/env bashgroove: stop hook — remind about /groove-daily-end during work hours
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
undefinedhour=$(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
undefinedgit-activity-buffer.sh
git-activity-buffer.shgit-activity-buffer.sh
git-activity-buffer.shbash
#!/usr/bin/env bashbash
#!/usr/bin/env bashgroove: postToolUse/Shell hook — buffer git commits for memory log
groove: postToolUse/Shell 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:-<no message>}" >> .groove/.cache/git-activity-buffer.txt
fi
undefinedinput=$(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:-<no message>}" >> .groove/.cache/git-activity-buffer.txt
fi
undefinedblock-managed-paths.sh
block-managed-paths.shblock-managed-paths.sh
block-managed-paths.shbash
#!/usr/bin/env bashbash
#!/usr/bin/env bashgroove: preToolUse/Write hook — block edits to managed groove paths
groove: preToolUse/Write 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 2
fi
undefinedinput=$(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 2
fi
undefinedversion-check.sh
version-check.shversion-check.sh
version-check.shbash
#!/usr/bin/env bashbash
#!/usr/bin/env bashgroove: postToolUse hook — check for new groove version (once per hour)
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
undefinedCACHE=".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
undefined.cursor/hooks.json
template
.cursor/hooks.json.cursor/hooks.json
模板
.cursor/hooks.jsonMerge these into the key. Preserve all other keys.
hooksjson
{
"version": 1,
"hooks": {
"sessionStart": [
{
"command": "bash .agents/skills/groove-utilities-prime/scripts/groove-utilities-prime.sh --json"
}
],
"stop": [
{
"command": "bash .groove/hooks/cursor/daily-end-reminder.sh"
}
],
"postToolUse": [
{
"matcher": "Shell",
"command": "bash .groove/hooks/cursor/git-activity-buffer.sh"
},
{
"command": "bash .groove/hooks/cursor/version-check.sh"
}
],
"preToolUse": [
{
"matcher": "Write",
"command": "bash .groove/hooks/cursor/block-managed-paths.sh"
}
]
}
}When merging: if a 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.
hooks将这些内容合并到键中。保留所有其他键。
hooksjson
{
"version": 1,
"hooks": {
"sessionStart": [
{
"command": "bash .agents/skills/groove-utilities-prime/scripts/groove-utilities-prime.sh --json"
}
],
"stop": [
{
"command": "bash .groove/hooks/cursor/daily-end-reminder.sh"
}
],
"postToolUse": [
{
"matcher": "Shell",
"command": "bash .groove/hooks/cursor/git-activity-buffer.sh"
},
{
"command": "bash .groove/hooks/cursor/version-check.sh"
}
],
"preToolUse": [
{
"matcher": "Write",
"command": "bash .groove/hooks/cursor/block-managed-paths.sh"
}
]
}
}合并时:如果键已存在,则将groove条目追加到相关事件数组中。不要创建重复项——追加前检查groove命令条目是否已存在。
hooksConstraints
约束条件
- Never overwrite non-groove entries in
.cursor/hooks.json - Never overwrite an existing script without diff + confirmation
- Scripts use to parse JSON stdin — if python3 is absent, skip that hook and warn
python3 - uses exit code 2 (Cursor's convention to block the tool use)
block-managed-paths - After install: remind the user that hooks take effect on the next Cursor session restart
- follows the
.groove/hooks/cursor/git strategy fromgit.hooks.groove/index.md - Create directory if it does not exist
.cursor/
- 绝不覆盖中的非groove条目
.cursor/hooks.json - 未经差异对比+确认,绝不覆盖现有脚本
- 脚本使用解析JSON标准输入——如果python3不存在,则跳过该钩子并发出警告
python3 - 使用退出代码2(Cursor阻止工具使用的约定)
block-managed-paths - 安装完成后:提醒用户钩子将在下次Cursor会话重启后生效
- 遵循
.groove/hooks/cursor/中的.groove/index.mdgit策略git.hooks - 如果目录不存在则创建该目录
.cursor/