$SHELL), and on Windows they are forced to use Git Bash (cmd.exe or PowerShell is not supported). Therefore, ensure that your hook commands are compatible with bash syntax. Windows users need to install Git for Windows. For details, see the execution details in the Hook Reference Guide..ts files and gofmt on .go files after each file edit.Event Name | Description |
PreToolUse | Runs before a tool call (can block it). |
PostToolUse | Runs after a tool call completes. |
UserPromptSubmit | Runs after a user submits a prompt and before CodeBuddy processes it. |
Notification | Runs when CodeBuddy Code sends a notification. |
Stop | Runs when CodeBuddy Code completes a response. |
SubagentStop | Runs when a subagent task completes. |
PreCompact | Runs before CodeBuddy Code is about to run a compaction operation. |
SessionStart | Runs when CodeBuddy Code starts a new session or resumes an existing session. |
SessionEnd | Runs when a CodeBuddy Code session ends. |
/hooks slash command and select the PreToolUse hook event. PreToolUse hooks run before tool calls and can block them and provide feedback to CodeBuddy on what to do differently.Bash for the matcher. You can use * to match all tools.jq -r '"\\(.tool_input.command) ~ \\(.tool_input.description // "No description")"' >> ~/.codebuddy/bash-command.log
/hooks again or check ~/.codebuddy/settings.json to view your configuration:{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "jq -r '\\"\\\\(.tool_input.command) ~ \\\\(.tool_input.description // \\"No description\\")\\"' >> ~/.codebuddy/bash-command.log"}]}]}}
ls, and then check your log file: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 dependency is available in the project.{"hooks": {"PostToolUse": [{"matcher": "Edit|Write","hooks": [{"type": "command","command": "python3 \\"$CODEBUDDY_PROJECT_DIR\\"/.codebuddy/hooks/markdown_formatter.py"}]}]}}
.codebuddy/hooks/markdown_formatter.py file with the following content:#!/usr/bin/env python3"""A Markdown formatter for CodeBuddy Code output.Fix missing language tags and spacing issues while preserving code content."""import jsonimport sysimport reimport osdef detect_language(code):"""Perform best-effort language detection from code content."""s = code.strip()# JSON detectionif re.search(r'^\\s*[{\\[]', s):try:json.loads(s)return 'json'except:pass# Python detectionif 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 detectionif re.search(r'\\b(function\\s+\\w+\\s*\\(|const\\s+\\w+\\s*=)', s) or \\re.search(r'=>|console\\.(log|error)', s):return 'javascript'# Bash detectionif 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 detectionif re.search(r'\\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\\s+', s, re.I):return 'sql'return 'text'def format_markdown(content):"""Format markdown content using language detection."""# Fix unmarked code blocksdef 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)# Fix excessive blank lines (outside code blocks only)content = re.sub(r'\\n{3,}', '\\n\\n', content)return content.rstrip() + '\\n'# Main executiontry: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) # Not a markdown fileif 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) and has the executable permission set, directly executing the .py file in a Windows Git Bash environment may fail to correctly recognize the shebang. Therefore, always explicitly use python3 in the command to invoke the Python script to ensure cross-platform compatibility.{"hooks": {"Notification": [{"matcher": "","hooks": [{"type": "command","command": "notify-send 'CodeBuddy Code' 'Awaiting your input'"}]}]}}
powershell or 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 perform an allowlist check before executing any Bash command—you can declare hooks directly in the frontmatter of SKILL.md. The scope is automatically opened and closed with the lifecycle of the forked subagent, without affecting the main session or other Skills.context: fork support frontmatter hooks. Injected (default) Skills do not have clear lifecycle boundaries, so frontmatter hooks are parsed but not registered.---name: code-reviewerdescription: Code review Skill that checks the Bash command allowlist before executioncontext: forkagent: Explorehooks:PreToolUse:- matcher: "Bash"hooks:- type: commandcommand: ${CODEBUDDY_SKILL_DIR}/scripts/check-bash.shtimeout: 5Stop: # Automatically rewritten to SubagentStop- hooks:- type: commandcommand: echo "review done at $(date)" >> ${CODEBUDDY_PROJECT_DIR}/.cbc-review.log---Please review the code involved in $ARGUMENTS...
~/.codebuddy/settings.json (disabled by default, all frontmatter hooks from non-built-in sources are silently skipped):{"allowUntrustedFrontmatterHooks": true}
matcher properly can reduce unnecessary hook executions..codebuddy/hooks/ directory in the project root to centrally manage scripts and place them under version control./hooks panel.mcp__<server>__<tool> and can be controlled in batches using regular expressions in matcher, such as mcp__github__.*.python3 your_script.py instead of executing .py files directly, because the shebang line of a Python script may not be correctly recognized in the Windows Git Bash environment.Was this page helpful?
You can also Contact sales or Submit a Ticket for help.
Help us improve! Rate your documentation experience in 5 mins.
Feedback