
create-hooks
by aaronvstory
TÂCHES prompts ported to OpenCode - Skills, agents, and slash commands for structured thinking
SKILL.md
name: create-hooks description: Expert guidance for creating, configuring, and using Opencode hooks. Use when working with hooks, setting up event listeners, validating commands, automating workflows, adding notifications, or understanding hook types.
Hooks provide programmatic control over the agent's behavior without modifying core code, enabling project-specific automation, safety checks, and workflow customization.
<quick_start>
- Create hooks config file:
- Project:
.config/opencode/hooks.json - User:
~/.config/opencode/hooks.json
- Project:
- Choose hook event (when it fires)
- Choose hook type (command or prompt)
- Configure matcher (which tools trigger it)
- Test with debug mode (if available)
.config/opencode/hooks.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "run_shell_command",
"hooks": [
{
"type": "command",
"command": "jq -r '"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")"' >> ~/.config/opencode/bash-log.txt"
}
]
}
]
}
}
This hook:
- Fires before (
PreToolUse) everyrun_shell_commandtool use - Executes a
command(not an LLM prompt) - Logs command + description to a file
</quick_start>
<hook_types>
| Event | When it fires | Can block? |
|---|---|---|
| PreToolUse | Before tool execution | Yes |
| PostToolUse | After tool execution | No |
| UserPromptSubmit | User submits a prompt | Yes |
| Stop | Agent attempts to stop | Yes |
| SubagentStop | Subagent attempts to stop | Yes |
| SessionStart | Session begins | No |
| SessionEnd | Session ends | No |
| PreCompact | Before context compaction | Yes |
| Notification | Agent needs input | No |
Blocking hooks can return "decision": "block" to prevent the action. See references/hook-types.md for detailed use cases.
</hook_types>
<hook_anatomy> <hook_type name="command"> Type: Executes a shell command
Use when:
- Simple validation (check file exists)
- Logging (append to file)
- External tools (formatters, linters)
- Desktop notifications
Input: JSON via stdin Output: JSON via stdout (optional)
{
"type": "command",
"command": "/path/to/script.sh",
"timeout": 30000
}
</hook_type>
<hook_type name="prompt"> Type: LLM evaluates a prompt
Use when:
- Complex decision logic
- Natural language validation
- Context-aware checks
- Reasoning required
Input: Prompt with $ARGUMENTS placeholder
Output: JSON with decision and reason
{
"type": "prompt",
"prompt": "Evaluate if this command is safe: $ARGUMENTS\n\nReturn JSON: {\"decision\": \"approve\" or \"block\", \"reason\": \"explanation\"}"
}
</hook_type> </hook_anatomy>
{
"matcher": "run_shell_command", // Exact match
"matcher": "write_file|replace", // Multiple tools (regex OR)
"matcher": "mcp__.*", // All MCP tools
"matcher": "mcp__memory__.*" // Specific MCP server
}
No matcher: Hook fires for all tools
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [...] // No matcher - fires on every user prompt
}
]
}
}
<input_output> Hooks receive JSON via stdin with session info, current directory, and event-specific data. Blocking hooks can return JSON to approve/block actions or modify inputs.
Example output (blocking hooks):
{
"decision": "approve" | "block",
"reason": "Why this decision was made"
}
See references/input-output-schemas.md for complete schemas for each hook type. </input_output>
<environment_variables> Available in hook commands:
| Variable | Value |
|---|---|
$OPENCODE_PROJECT_DIR | Project root directory |
$ARGUMENTS | Hook input JSON (prompt hooks only) |
Example:
{
"command": "$OPENCODE_PROJECT_DIR/.config/opencode/hooks/validate.sh"
}
</environment_variables>
<common_patterns> Desktop notification when input needed:
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Agent needs input\" with title \"Opencode\"'"
}
]
}
]
}
}
Block destructive git commands:
{
"hooks": {
"PreToolUse": [
{
"matcher": "run_shell_command",
"hooks": [
{
"type": "prompt",
"prompt": "Check if this command is destructive: $ARGUMENTS\n\nBlock if it contains: 'git push --force', 'rm -rf', 'git reset --hard'\n\nReturn: {\"decision\": \"approve\" or \"block\", \"reason\": \"explanation\"}"
}
]
}
]
}
}
Auto-format code after edits:
{
"hooks": {
"PostToolUse": [
{
"matcher": "write_file|replace",
"hooks": [
{
"type": "command",
"command": "prettier --write $OPENCODE_PROJECT_DIR",
"timeout": 10000
}
]
}
]
}
}
Add context at session start:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"SessionStart\", \"additionalContext\": \"Current sprint: Sprint 23. Focus: User authentication\"}}'"
}
]
}
]
}
}
</common_patterns>
<reference_guides> Hook types and events: references/hook-types.md
- Complete list of hook events
- When each event fires
- Input/output schemas for each
- Blocking vs non-blocking hooks
Command vs Prompt hooks: references/command-vs-prompt.md
- Decision tree: which type to use
- Command hook patterns and examples
- Prompt hook patterns and examples
- Performance considerations
Matchers and patterns: references/matchers.md
- Regex patterns for tool matching
- MCP tool matching patterns
- Multiple tool matching
- Debugging matcher issues
Input/Output schemas: references/input-output-schemas.md
- Complete schema for each hook type
- Field descriptions and types
- Hook-specific output fields
- Example JSON for each event
Working examples: references/examples.md
- Desktop notifications
- Command validation
- Auto-formatting workflows
- Logging and audit trails
- Stop logic patterns
- Session context injection
Troubleshooting: references/troubleshooting.md
- Hooks not triggering
- Command execution failures
- Prompt hook issues
- Permission problems
- Timeout handling
- Debug workflow </reference_guides>
<security_checklist> Critical safety requirements:
- Infinite loop prevention: Check
stop_hook_activeflag in Stop hooks to prevent recursive triggering - Timeout configuration: Set reasonable timeouts (default: 60s) to prevent hanging
- Permission validation: Ensure hook scripts have executable permissions (
chmod +x) - Path safety: Use absolute paths with
$OPENCODE_PROJECT_DIRto avoid path injection - JSON validation: Validate hook config with
jqbefore use to catch syntax errors - Selective blocking: Be conservative with blocking hooks to avoid workflow disruption
Testing protocol:
# Validate JSON config
jq . .config/opencode/hooks.json
</security_checklist>
<success_criteria> A working hook configuration has:
- Valid JSON in
.config/opencode/hooks.json(validated withjq) - Appropriate hook event selected for the use case
- Correct matcher pattern that matches target tools
- Command or prompt that executes without errors
- Proper output schema (decision/reason for blocking hooks)
- Tested showing expected behavior
- No infinite loops in Stop hooks (checks
stop_hook_activeflag) - Reasonable timeout set (especially for external commands)
- Executable permissions on script files if using file paths </success_criteria>
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon