plugins/hookify/skills/writing-rules/SKILL.md
This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
npx skillsauth add anthropics/claude-code Writing Hookify RulesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Hookify rules are markdown files with YAML frontmatter that define patterns to watch for and messages to show when those patterns match. Rules are stored in .claude/hookify.{rule-name}.local.md files.
---
name: rule-identifier
enabled: true
event: bash|file|stop|prompt|all
pattern: regex-pattern-here
---
Message to show Claude when this rule triggers.
Can include markdown formatting, warnings, suggestions, etc.
name (required): Unique identifier for the rule
warn-dangerous-rm, block-console-logenabled (required): Boolean to activate/deactivate
true: Rule is activefalse: Rule is disabled (won't trigger)event (required): Which hook event to trigger on
bash: Bash tool commandsfile: Edit, Write, MultiEdit toolsstop: When agent wants to stopprompt: When user submits a promptall: All eventsaction (optional): What to do when rule matches
warn: Show message but allow operation (default)block: Prevent operation (PreToolUse) or stop session (Stop events)warnpattern (simple format): Regex pattern to match
Example:
event: bash
pattern: rm\s+-rf
For complex rules with multiple conditions:
---
name: warn-env-file-edits
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.env$
- field: new_text
operator: contains
pattern: API_KEY
---
You're adding an API key to a .env file. Ensure this file is in .gitignore!
Condition fields:
field: Which field to check
commandfile_path, new_text, old_text, contentoperator: How to match
regex_match: Regex pattern matchingcontains: Substring checkequals: Exact matchnot_contains: Substring must NOT be presentstarts_with: Prefix checkends_with: Suffix checkpattern: Pattern or string to matchAll conditions must match for rule to trigger.
The markdown content after frontmatter is shown to Claude when the rule triggers.
Good messages:
Example:
⚠️ **Console.log detected!**
You're adding console.log to production code.
**Why this matters:**
- Debug logs shouldn't ship to production
- Console.log can expose sensitive data
- Impacts browser performance
**Alternatives:**
- Use a proper logging library
- Remove before committing
- Use conditional debug builds
Match Bash command patterns:
---
event: bash
pattern: sudo\s+|rm\s+-rf|chmod\s+777
---
Dangerous command detected!
Common patterns:
rm\s+-rf, dd\s+if=, mkfssudo\s+, su\s+chmod\s+777, chown\s+rootMatch Edit/Write/MultiEdit operations:
---
event: file
pattern: console\.log\(|eval\(|innerHTML\s*=
---
Potentially problematic code pattern detected!
Match on different fields:
---
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.tsx?$
- field: new_text
operator: regex_match
pattern: console\.log\(
---
Console.log in TypeScript file!
Common patterns:
console\.log\(, debugger, print\(eval\(, innerHTML\s*=, dangerouslySetInnerHTML\.env$, credentials, \.pem$node_modules/, dist/, build/Match when agent wants to stop (completion checks):
---
event: stop
pattern: .*
---
Before stopping, verify:
- [ ] Tests were run
- [ ] Build succeeded
- [ ] Documentation updated
Use for:
Match user prompt content (advanced):
---
event: prompt
conditions:
- field: user_prompt
operator: contains
pattern: deploy to production
---
Production deployment checklist:
- [ ] Tests passing?
- [ ] Reviewed by team?
- [ ] Monitoring ready?
Literal characters: Most characters match themselves
rm matches "rm"console.log matches "console.log"Special characters need escaping:
. (any char) → \. (literal dot)( ) → \( \) (literal parens)[ ] → \[ \] (literal brackets)Common metacharacters:
\s - whitespace (space, tab, newline)\d - digit (0-9)\w - word character (a-z, A-Z, 0-9, _). - any character+ - one or more* - zero or more? - zero or one| - ORExamples:
rm\s+-rf Matches: rm -rf, rm -rf
console\.log\( Matches: console.log(
(eval|exec)\( Matches: eval( or exec(
chmod\s+777 Matches: chmod 777, chmod 777
API_KEY\s*= Matches: API_KEY=, API_KEY =
Test regex patterns before using:
python3 -c "import re; print(re.search(r'your_pattern', 'test text'))"
Or use online regex testers (regex101.com with Python flavor).
Too broad:
pattern: log # Matches "log", "login", "dialog", "catalog"
Better: console\.log\(|logger\.
Too specific:
pattern: rm -rf /tmp # Only matches exact path
Better: rm\s+-rf
Escaping issues:
"pattern" requires double backslashes \\spattern: \s works as-isLocation: All rules in .claude/ directory
Naming: .claude/hookify.{descriptive-name}.local.md
Gitignore: Add .claude/*.local.md to .gitignore
Good names:
hookify.dangerous-rm.local.mdhookify.console-log.local.mdhookify.require-tests.local.mdhookify.sensitive-files.local.mdBad names:
hookify.rule1.local.md (not descriptive)hookify.md (missing .local)danger.local.md (missing hookify prefix).claude/hookify.{name}.local.md file in project root.local.md fileTemporary: Set enabled: false in frontmatter
Permanent: Delete the .local.md file
See ${CLAUDE_PLUGIN_ROOT}/examples/ for complete examples:
dangerous-rm.local.md - Block dangerous rm commandsconsole-log-warning.local.md - Warn about console.logsensitive-files-warning.local.md - Warn about editing .env filesMinimum viable rule:
---
name: my-rule
enabled: true
event: bash
pattern: dangerous_command
---
Warning message here
Rule with conditions:
---
name: my-rule
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.ts$
- field: new_text
operator: contains
pattern: any
---
Warning message
Event types:
bash - Bash commandsfile - File editsstop - Completion checksprompt - User inputall - All eventsField options:
commandfile_path, new_text, old_text, contentuser_promptOperators:
regex_match, contains, equals, not_contains, starts_with, ends_withtools
This skill should be used when the user wants to "create a skill", "add a skill to plugin", "write a new skill", "improve skill description", "organize skill content", or needs guidance on skill structure, progressive disclosure, or skill development best practices for Claude Code plugins.
tools
This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.
tools
This skill should be used when the user asks about "plugin settings", "store plugin configuration", "user-configurable plugin", ".local.md files", "plugin state files", "read YAML frontmatter", "per-project plugin settings", or wants to make plugin behavior configurable. Documents the .claude/plugin-name.local.md pattern for storing plugin-specific configuration with YAML frontmatter and markdown content.
tools
This skill should be used when the user asks to "add MCP server", "integrate MCP", "configure MCP in plugin", "use .mcp.json", "set up Model Context Protocol", "connect external service", mentions "${CLAUDE_PLUGIN_ROOT} with MCP", or discusses MCP server types (SSE, stdio, HTTP, WebSocket). Provides comprehensive guidance for integrating Model Context Protocol servers into Claude Code plugins for external tool and service integration.