4.7 KiB
description
| description |
|---|
| Get help with the hookify system |
Display comprehensive hookify documentation.
Hook System Overview
ECC ships a built-in Node.js runtime that reads project-local
.claude/hookify.*.local.md files. The plugin registers that runtime for
PreToolUse, PostToolUse, UserPromptSubmit, and Stop.
Event Types
bash: runs on Bash tool use; a simplepatternmatchescommandfile: runs on Write/Edit/MultiEdit/NotebookEdit; a simplepatternmatchesfile_pathstop: runs when Claude finishes a response; a simplepatternmatches the last assistant messageprompt: runs on user message submission; a simplepatternmatches the submittedpromptall: is eligible on all events; conditions whose fields are unavailable for the current event do not match
Rule File Format
Files are stored as .claude/hookify.{name}.local.md:
---
name: descriptive-name
enabled: true
event: bash|file|stop|prompt|all
action: block|warn
pattern: "regex pattern to match"
tool_matcher: Bash|Write
---
Message to display when rule triggers.
Supports multiple lines.
action is optional and defaults to warn. tool_matcher is optional and
uses exact, pipe-separated tool names or *.
Use either pattern or a non-empty conditions list, never both:
---
name: block-production-publish
enabled: true
event: bash
action: block
conditions:
- field: command
operator: contains
pattern: npm publish
- field: command
operator: not_contains
pattern: --dry-run
---
Use the release workflow instead.
All conditions must match. Supported operators are regex_match, contains,
equals, not_contains, starts_with, and ends_with.
regex_match is case-insensitive; the five literal string operators are
case-sensitive.
Condition fields:
bash:commandfile:file_path,new_text,old_text,contentprompt:user_prompt(read from Claude Code'spromptinput)stop:content(the last assistant message)all: any field above when it exists for the current event
Enforcement Semantics
- PreToolUse
blockdenies the pending tool call. - UserPromptSubmit
blockrejects the submitted prompt. - Stop
blockprevents the current stop and gives Claude the reason to continue. - PostToolUse
blockfeeds corrective context to Claude. PostToolUse cannot undo a tool that already completed. - PreToolUse, PostToolUse, and UserPromptSubmit
warnmessages reach Claude as structuredadditionalContext. - A Stop warning is a non-blocking
systemMessageshown to the user. A Stop warning does not make Claude continue; useaction: blockfor a corrective completion rule. - Hookify skips recursive Stop evaluation when Claude Code reports
stop_hook_active: true, preventing an always-matching block from creating an infinite continuation loop.
Hookify never rewrites or returns modified tool input.
Safety and Limits
The runtime only inspects direct rule files inside the current project's real
.claude/ directory. It rejects symlinked directories/files, traversal,
non-regular files, unsupported YAML structures, unknown fields, invalid
operators, and invalid event/field combinations. It does not read transcript_path;
Stop rules use the bounded last assistant message.
Every condition field in an accepted hook input is evaluated completely up to the 256 KiB input limit. A regex timeout does not discard independent literal-only rule matches.
Limits per invocation:
- 256 directory entries inspected and 64 rule files evaluated
- 64 KiB per rule and 512 KiB total rule bytes
- 512 characters per pattern, 16 conditions, and 4 KiB per message
- 256 KiB hook input and 8 KiB structured output
- one 250 ms total regular-expression deadline
Regular expressions run case-insensitively in a resource-limited worker. A malformed rule, unsafe file, invalid input, invalid regex, or worker timeout causes the affected evaluation to fail open. The hook exits successfully and returns a bounded, event-correct Hookify diagnostic instead of silently writing the warning to stderr.
Commands
/hookify [description]creates new rules and auto-analyzes the conversation when no description is given/hookify-listlists configured rules/hookify-configuretoggles rules on or off
Pattern Tips
- use JavaScript regex syntax;
regex_matchis case-insensitive while literal operators are case-sensitive - for
bash, match against the full command string - for
file, a simple pattern matches the full file path - for changed text, use a
content,new_text, orold_textcondition - keep regexes narrow even though worker isolation enforces a hard deadline
- test patterns before enabling a blocking rule