-
Notifications
You must be signed in to change notification settings - Fork 0
Hooks Configuration
Status: ✅ Complete
Last Updated: December 5, 2025
This guide covers how to configure hooks in ricecoder. Hooks are defined in YAML configuration files and support a wide range of customization options.
Hooks are configured in .ricecoder/hooks.yaml in your project directory:
my-project/
├── .ricecoder/
│ └── hooks.yaml # Project-level hooks
├── src/
└── README.md
User-level hooks can be configured in ~/.ricecoder/hooks.yaml.
Hooks are loaded from multiple sources in priority order:
- Runtime: Configuration passed programmatically (highest priority)
-
Project:
.ricecoder/hooks.yaml(project-specific) -
User:
~/.ricecoder/hooks.yaml(user-level) - Built-in: Built-in hook templates and defaults (lowest priority)
Later sources override earlier ones. For example, a project-level hook with the same name as a user-level hook will override it.
hooks:
- name: "My Hook"
event: "file_modified"
action:
type: "command"
command: "echo"
args:
- "File changed"hooks:
- name: "Format on save"
description: "Automatically format files when saved"
event: "file_modified"
action:
type: "command"
command: "prettier"
args:
- "--write"
- "{{file_path}}"
timeout_ms: 5000
capture_output: true
enabled: true
tags:
- "formatting"
- "auto"
metadata:
author: "team"
version: "1.0"
condition:
expression: "file_path.endsWith('.ts')"Human-readable hook name. Used for display and identification.
name: "Format on save"Hook description explaining what it does.
description: "Automatically format TypeScript files when saved"Event type that triggers the hook. See Hooks Events Guide for available events.
event: "file_modified"Action to execute when hook is triggered. See Hooks Actions Guide for action types.
action:
type: "command"
command: "prettier"
args:
- "{{file_path}}"Whether the hook is active. Default: true.
enabled: trueTags for organizing and filtering hooks.
tags:
- "formatting"
- "auto"
- "typescript"Custom metadata for the hook.
metadata:
author: "team"
version: "1.0"
priority: "high"Condition that must be met to execute the hook. If not specified, hook always executes.
condition:
expression: "file_path.endsWith('.ts')"Execute a shell command:
action:
type: "command"
command: "prettier"
args:
- "--write"
- "{{file_path}}"
timeout_ms: 5000
capture_output: trueProperties:
-
command(required): Command to execute -
args(optional): Command arguments (supports variable substitution) -
timeout_ms(optional): Timeout in milliseconds (default: 30000) -
capture_output(optional): Capture command output (default: true)
Call a ricecoder tool with parameter binding:
action:
type: "tool_call"
tool_name: "code_formatter"
tool_path: "/usr/local/bin/prettier"
parameters:
file_path: "{{file_path}}"
output_dir: "/tmp/formatted"
style: "prettier"
timeout_ms: 10000Properties:
-
tool_name(required): Name of the tool -
tool_path(required): Path to tool executable or handler -
parameters(optional): Tool parameters (supports variable substitution) -
timeout_ms(optional): Timeout in milliseconds (default: 30000)
Send a prompt to an AI assistant:
action:
type: "ai_prompt"
prompt_template: |
Review this code change:
File: {{file_path}}
Provide feedback.
model: "gpt-4"
temperature: 0.7
max_tokens: 2000
stream: trueProperties:
-
prompt_template(required): Prompt template (supports variable substitution) -
model(optional): AI model to use (default: configured default) -
temperature(optional): Temperature for AI response (0.0-1.0, default: 0.7) -
max_tokens(optional): Maximum tokens in response (default: 2000) -
stream(optional): Stream response (default: false)
Execute multiple hooks in sequence:
action:
type: "chain"
hook_ids:
- "format-hook-id"
- "lint-hook-id"
- "test-hook-id"
pass_output: trueProperties:
-
hook_ids(required): List of hook IDs to execute in sequence -
pass_output(optional): Pass previous hook output as context (default: false)
Variables are substituted in command arguments, tool parameters, and AI prompts. Use {{variable_name}} syntax:
action:
type: "command"
command: "echo"
args:
- "File: {{file_path}}"
- "Size: {{file_size}}"Available variables depend on the event type. See Hooks Variables Guide for complete reference.
Access nested properties with dot notation:
args:
- "{{metadata.size}}"
- "{{context.user_id}}"Mix literal values with variables:
args:
- "{{file_path}}/subdir"
- "output-{{timestamp}}.txt"Execute hooks only when conditions are met:
condition:
expression: "file_path.endsWith('.ts')"Conditions are evaluated against the event context. If the condition evaluates to false, the hook is skipped.
# Only TypeScript files
condition:
expression: "file_path.endsWith('.ts')"
# Only in src directory
condition:
expression: "file_path.includes('/src/')"
# Only modified (not created)
condition:
expression: "operation_type == 'modified'"
# Only large files
condition:
expression: "file_size > 1000000"Built-in templates for common patterns:
hooks:
- name: "Format on save"
event: "file_modified"
action:
type: "command"
command: "prettier"
args:
- "--write"
- "{{file_path}}"hooks:
- name: "Pre-commit checks"
event: "git_pre_commit"
action:
type: "command"
command: "npm"
args:
- "run"
- "lint"hooks:
- name: "Post-build cleanup"
event: "build_complete"
action:
type: "command"
command: "rm"
args:
- "-rf"
- "dist/temp"hooks:
- name: "Format TypeScript"
event: "file_modified"
condition:
expression: "file_path.endsWith('.ts')"
action:
type: "command"
command: "prettier"
args:
- "--write"
- "{{file_path}}"
enabled: truehooks:
- name: "Run tests"
event: "file_modified"
condition:
expression: "file_path.includes('/src/')"
action:
type: "command"
command: "npm"
args:
- "test"
- "--"
- "{{file_path}}"
enabled: truehooks:
- name: "AI review"
event: "file_modified"
action:
type: "ai_prompt"
prompt_template: |
Review this code change:
File: {{file_path}}
Old hash: {{old_hash}}
New hash: {{new_hash}}
Provide feedback on the changes.
model: "gpt-4"
temperature: 0.7
stream: true
enabled: truehooks:
- name: "Custom formatter"
event: "file_modified"
action:
type: "tool_call"
tool_name: "custom_formatter"
tool_path: "./tools/formatter"
parameters:
file_path: "{{file_path}}"
style: "prettier"
output_dir: "/tmp/formatted"
enabled: truehooks:
- name: "Format and lint"
event: "file_modified"
action:
type: "chain"
hook_ids:
- "format-hook"
- "lint-hook"
pass_output: true
enabled: trueHooks configuration is validated when loaded. Invalid configuration will be rejected with clear error messages.
Missing required field:
Error: Hook "My Hook" is missing required field: event
Invalid event type:
Error: Hook "My Hook" has invalid event type: "unknown_event"
Invalid action type:
Error: Hook "My Hook" has invalid action type: "unknown_action"
Invalid condition:
Error: Hook "My Hook" has invalid condition expression
Configuration changes are automatically detected and reloaded without restart. When you modify .ricecoder/hooks.yaml:
- File watcher detects change
- Configuration is reloaded
- Hooks are updated
- Hook state (enabled/disabled) is preserved
If configuration is invalid, the previous configuration is kept and an error is logged.
Problem: Hooks are not loading from configuration file.
Solutions:
- Verify file path:
.ricecoder/hooks.yaml - Check file permissions (must be readable)
- Verify YAML syntax is correct
- Check logs for configuration errors
Problem: Variables like {{file_path}} are not being replaced.
Solutions:
- Verify variable name is correct (case-sensitive)
- Check event type provides the variable
- Use
ricecoder hooks inspectto see available variables - See Hooks Variables Guide for reference
Problem: Hook is configured but not executing.
Solutions:
- Verify hook is enabled:
ricecoder hooks inspect <hook-id> - Check event name matches exactly
- Verify condition expression is correct
- Check hook configuration syntax
- Hooks System Guide - Main hooks guide
- Hooks Events Guide - Available events
- Hooks Actions Guide - Action types
- Hooks Variables Guide - Variable reference
- Troubleshooting Guide - General troubleshooting
Last updated: December 5, 2025