tencent cloud

Hooks Usage Guide

Download
Focus Mode
Font Size
Last updated: 2026-09-30 18:41:46
AI-Translated
We recommend that you first read the Hook Reference Guide to learn about all events, input/output structures, and security requirements. This guide focuses on hands-on exercises and common examples to help you quickly enable the Hooks feature in your CodeBuddy Code project.
Note:
The Hook feature is currently in the Beta stage and is still being continuously refined. Please stay tuned for updates in future versions.
CodeBuddy Code hooks are user-defined shell commands that are executed at different stages of the CodeBuddy Code lifecycle. Hooks provide deterministic control over CodeBuddy Code behavior, ensuring that specific actions always occur rather than relying on the LLM to choose to execute them.
Execution Environment: Hook commands are executed on macOS/Linux using the user's default shell ($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.
For reference documentation on hooks, see the Hook Reference Guide.
Example use cases for Hooks include:
Notification: Customize how CodeBuddy Code notifies you when it is waiting for your input or permission.
Auto-formatting: Run prettier on .ts files and gofmt on .go files after each file edit.
Logging: Track and count all executed commands for compliance or debugging purposes.
Feedback: Provide automatic feedback when the code generated by CodeBuddy Code does not comply with your codebase standards.
Custom Permissions: Block modifications to production files or sensitive directories.
By encoding these rules as hooks rather than prompt instructions, you can turn suggestions into application-level code that executes as expected every time.
Note:
You must consider the security implications when adding hooks, because hooks run automatically during the agent loop using the credentials of your current environment. For example, malicious hook code may leak your data. Always review the implementation of hooks before registering them. For a complete security practices tutorial, see the security considerations in the Hook Reference Guide.

Hook Event Overview

CodeBuddy Code provides multiple hook events that run at different stages of the workflow:
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.
Each event receives different data and can control CodeBuddy's behavior in different ways.

Quick Start

In this quick start, you will add a hook to log the shell commands that CodeBuddy Code runs.

Prerequisites

Install jq to process JSON on the command line.

Step 1: Opening Hook Configuration

Run the /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.

Step 2: Adding a Matcher

Select + Add new matcher... to run your hook only when the Bash tool is called. Enter Bash for the matcher. You can use * to match all tools.

Step 3: Adding a hook

Select + Add new hook... and enter this command:
jq -r '"\\(.tool_input.command) ~ \\(.tool_input.description // "No description")"' >> ~/.codebuddy/bash-command.log

Step 4: Saving the Configuration

For the storage location, select User settings because you are logging to your home directory. This way, the hook will be applied to all projects, not just the current one. Then press Esc until you return to the REPL. Your hook is now registered!

Step 5: Verifying the hook

Run /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"
}
]
}
]
}
}

Step 6: Testing the hook

Have CodeBuddy run a simple command, such as ls, and then check your log file:
cat ~/.codebuddy/bash-command.log
You should see an entry similar to the following:
ls ~ Lists files and directories

More Examples

Code Formatting Hook

Automatically format TypeScript files after editing:
{
"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; }"
}
]
}
]
}
}
Ensure that the prettier dependency is available in the project.

Markdown Formatting Hook

Automatically fix missing language tags and formatting issues in markdown files:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python3 \\"$CODEBUDDY_PROJECT_DIR\\"/.codebuddy/hooks/markdown_formatter.py"
}
]
}
]
}
}
Create the .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 json
import sys
import re
import os

def detect_language(code):
"""Perform best-effort language detection from code content."""
s = code.strip()
# JSON detection
if re.search(r'^\\s*[{\\[]', s):
try:
json.loads(s)
return 'json'
except:
pass
# Python detection
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 detection
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 detection
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 detection
if 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 blocks
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)
# Fix excessive blank lines (outside code blocks only)
content = re.sub(r'\\n{3,}', '\\n\\n', content)
return content.rstrip() + '\\n'

# Main execution
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) # Not a markdown file
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)
Make the script executable:
chmod +x .codebuddy/hooks/markdown_formatter.py
Note:
Although the script contains a shebang line (#!/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.
This hook automatically:
Detect the programming language in unmarked code blocks.
Add appropriate language tags for syntax highlighting.
Fix excessive blank lines while preserving code content.
Process only markdown files (.md, .mdx).

Custom Notification Hook

Get desktop notifications when CodeBuddy needs input:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'CodeBuddy Code' 'Awaiting your input'"
}
]
}
]
}
}
On Windows/macOS, replace it with the notification command for powershell or osascript.

File Protection Hook

Prevent editing of sensitive files:
{
"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)\\""
}
]
}
]
}
}

Using Hooks in Skills (frontmatter)

If you want to distribute a Hook together with a specific Skill—for example, to have the 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.
Only Skills with context: fork support frontmatter hooks. Injected (default) Skills do not have clear lifecycle boundaries, so frontmatter hooks are parsed but not registered.
---
name: code-reviewer
description: Code review Skill that checks the Bash command allowlist before execution
context: fork
agent: Explore
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: ${CODEBUDDY_SKILL_DIR}/scripts/check-bash.sh
timeout: 5
Stop: # Automatically rewritten to SubagentStop
- hooks:
- type: command
command: echo "review done at $(date)" >> ${CODEBUDDY_PROJECT_DIR}/.cbc-review.log
---

Please review the code involved in $ARGUMENTS...
Before enabling: Enable the gate in ~/.codebuddy/settings.json (disabled by default, all frontmatter hooks from non-built-in sources are silently skipped):
{
"allowUntrustedFrontmatterHooks": true
}
For more detailed field semantics, security gates, and scope rules, see Skills documentation - Configuring Hooks in Skills and Hook Reference - Frontmatter Hooks.

Tutorials and Recommendations

1. Verify in small steps: Start with logging hooks and gradually add high-risk operations.
2. Control timeout: 60 seconds by default. If a script has long-running tasks, ensure timely output or split the processing.
3. Filter with matcher: Configuring matcher properly can reduce unnecessary hook executions.
4. Unified script directory: Create a .codebuddy/hooks/ directory in the project root to centrally manage scripts and place them under version control.
5. Prioritize security:
Avoid using unvalidated user input directly in hooks.
Use absolute paths for external commands to prevent PATH hijacking.
Ensure all hooks are reviewed before they are run by using the security confirmation mechanism of the /hooks panel.
6. Working with MCP tools: MCP tool names follow the format mcp__<server>__<tool> and can be controlled in batches using regular expressions in matcher, such as mcp__github__.*.
7. The panel is the authoritative entry point: Any external file modifications take effect only after confirmation in the panel. Make sure to complete this step.
8. Calling Python scripts: Always use 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.
9. Windows Compatibility: Hook commands are executed on Windows through Git Bash. Ensure that commands use bash syntax and avoid relying on syntax specific to cmd.exe or PowerShell.

Learn More

For reference documentation on hooks, see the Hook Reference Guide.
For comprehensive security practice tutorials and security guidelines, see Security Considerations in the Hook Reference Guide.
For troubleshooting steps and debugging techniques, see the Debugging section in the Hook Reference Guide.


Help and Support

Was this page helpful?

Help us improve! Rate your documentation experience in 5 mins.

Feedback