$SHELL)执行,在 Windows 上强制使用 Git Bash 执行(不支持 cmd.exe 或 PowerShell)。因此请确保您的 hook 命令兼容 bash 语法。Windows 用户需要安装 Git for Windows。详见 Hook 参考指南 中的执行详情。.ts 文件运行 prettier,对 .go 文件运行 gofmt 等。事件名称 | 说明 |
PreToolUse | 在工具调用之前运行(可以阻止它们) |
PostToolUse | 在工具调用完成后运行 |
UserPromptSubmit | 在用户提交提示词后、CodeBuddy 处理之前运行 |
Notification | 在 CodeBuddy Code 发送通知时运行 |
Stop | 在 CodeBuddy Code 完成响应时运行 |
SubagentStop | 在子代理任务完成时运行 |
PreCompact | 在 CodeBuddy Code 即将运行压缩操作之前运行 |
SessionStart | 在 CodeBuddy Code 启动新会话或恢复现有会话时运行 |
SessionEnd | 在 CodeBuddy Code 会话结束时运行 |
/hooks 斜杠命令并选择 PreToolUse hook 事件。PreToolUse hooks 在工具调用之前运行,可以阻止它们并向 CodeBuddy 反馈应该如何做不同的操作。Bash。您可以使用 * 来匹配所有工具。jq -r '"\\(.tool_input.command) ~ \\(.tool_input.description // "No description")"' >> ~/.codebuddy/bash-command.log
/hooks 或检查 ~/.codebuddy/settings.json 以查看您的配置:{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "jq -r '\\"\\\\(.tool_input.command) ~ \\\\(.tool_input.description // \\"No description\\")\\"' >> ~/.codebuddy/bash-command.log"}]}]}}
ls,然后检查您的日志文件:cat ~/.codebuddy/bash-command.log
ls ~ Lists files and directories
{"hooks": {"PostToolUse": [{"matcher": "Edit|Write","hooks": [{"type": "command","command": "jq -r '.tool_input.file_path' | { read file_path; if echo \\"$file_path\\" | grep -q '\\\\.ts$'; then npx prettier --write \\"$file_path\\"; fi; }"}]}]}}
prettier 依赖可用。{"hooks": {"PostToolUse": [{"matcher": "Edit|Write","hooks": [{"type": "command","command": "python3 \\"$CODEBUDDY_PROJECT_DIR\\"/.codebuddy/hooks/markdown_formatter.py"}]}]}}
.codebuddy/hooks/markdown_formatter.py 文件,内容如下:#!/usr/bin/env python3"""CodeBuddy Code 输出的 Markdown 格式化器。修复缺失的语言标签和间距问题,同时保留代码内容。"""import jsonimport sysimport reimport osdef detect_language(code):"""从代码内容进行最佳努力的语言检测。"""s = code.strip()# JSON 检测if re.search(r'^\\s*[{\\[]', s):try:json.loads(s)return 'json'except:pass# Python 检测if re.search(r'^\\s*def\\s+\\w+\\s*\\(', s, re.M) or \\re.search(r'^\\s*(import|from)\\s+\\w+', s, re.M):return 'python'# JavaScript 检测if re.search(r'\\b(function\\s+\\w+\\s*\\(|const\\s+\\w+\\s*=)', s) or \\re.search(r'=>|console\\.(log|error)', s):return 'javascript'# Bash 检测if re.search(r'^#!.*\\b(bash|sh)\\b', s, re.M) or \\re.search(r'\\b(if|then|fi|for|in|do|done)\\b', s):return 'bash'# SQL 检测if re.search(r'\\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\\s+', s, re.I):return 'sql'return 'text'def format_markdown(content):"""使用语言检测格式化 markdown 内容。"""# 修复未标记的代码块def add_lang_to_fence(match):indent, info, body, closing = match.groups()if not info.strip():lang = detect_language(body)return f"{indent}```{lang}\\n{body}{closing}\\n"return match.group(0)fence_pattern = r'(?ms)^([ \\t]{0,3})```([^\\n]*)\\n(.*?)(\\n\\1```)\\s*$'content = re.sub(fence_pattern, add_lang_to_fence, content)# 修复过多的空行(仅在代码块外)content = re.sub(r'\\n{3,}', '\\n\\n', content)return content.rstrip() + '\\n'# 主执行try:input_data = json.load(sys.stdin)file_path = input_data.get('tool_input', {}).get('file_path', '')if not file_path.endswith(('.md', '.mdx')):sys.exit(0) # 不是 markdown 文件if os.path.exists(file_path):with open(file_path, 'r', encoding='utf-8') as f:content = f.read()formatted = format_markdown(content)if formatted != content:with open(file_path, 'w', encoding='utf-8') as f:f.write(formatted)print(f"✓ Fixed markdown formatting in {file_path}")except Exception as e:print(f"Error formatting markdown: {e}", file=sys.stderr)sys.exit(1)
chmod +x .codebuddy/hooks/markdown_formatter.py
#!/usr/bin/env python3)并且已设置可执行权限,但在 Windows Git Bash 环境下直接执行 .py 文件可能无法正确识别 shebang。因此建议始终在 command 中显式使用 python3 来调用 Python 脚本,确保跨平台兼容性。{"hooks": {"Notification": [{"matcher": "","hooks": [{"type": "command","command": "notify-send 'CodeBuddy Code' 'Awaiting your input'"}]}]}}
powershell 或 osascript 的通知命令。{"hooks": {"PreToolUse": [{"matcher": "Edit|Write","hooks": [{"type": "command","command": "python3 -c \\"import json, sys; data=json.load(sys.stdin); path=data.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(p in path for p in ['.env', 'package-lock.json', '.git/']) else 0)\\""}]}]}}
code-reviewer Skill 在执行任何 Bash 命令前先做白名单检查——可以直接在 SKILL.md 的 frontmatter 中声明 hooks,作用域会自动随该 fork subagent 的生命周期开闭,不影响主会话和其他 Skill。context: fork 的 Skill 支持 frontmatter hooks。注入式(默认)Skill 没有清晰的生命周期边界,frontmatter hooks 会被解析但不会注册。---name: code-reviewerdescription: 代码审查 Skill,执行前检查 Bash 命令白名单context: forkagent: Explorehooks:PreToolUse:- matcher: "Bash"hooks:- type: commandcommand: ${CODEBUDDY_SKILL_DIR}/scripts/check-bash.shtimeout: 5Stop: # 自动重写为 SubagentStop- hooks:- type: commandcommand: echo "review done at $(date)" >> ${CODEBUDDY_PROJECT_DIR}/.cbc-review.log---请审查 $ARGUMENTS 涉及的代码...
~/.codebuddy/settings.json 中开启闸门(默认关闭,所有非内置来源的 frontmatter hooks 都会被静默跳过):{"allowUntrustedFrontmatterHooks": true}
matcher 可减少无关 hook 执行次数。.codebuddy/hooks/ 目录集中管理脚本并纳入版本控制。/hooks 面板的安全确认机制,确保所有 hook 均被审核运行。mcp__<server>__<tool>,可在 matcher 中通过正则整批控制,如 mcp__github__.*。python3 your_script.py 而不是直接执行 .py 文件,因为 Windows Git Bash 环境下不一定能正确识别 Python 脚本的 shebang 行。文档反馈