From epieczko-betty
Validates and registers hook manifest files (YAML) in the Hook Registry for versioned hook management.
npx claudepluginhub joshuarweaver/cascade-code-general-misc-1 --plugin epieczko-bettyThis skill uses the workspace's default tool permissions.
Validates and registers hook manifest files, adding them to the Hook Registry for automatic enforcement.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Validates and registers hook manifest files, adding them to the Hook Registry for automatic enforcement.
While hook.define creates hooks on-the-fly and updates the live configuration (.claude/hooks.yaml), the hook.register skill formalizes this by validating a hook manifest and adding it to a versioned registry (/registry/hooks.json). This enables:
This skill is part of Betty's Layer 5 (Hooks/Policy) infrastructure, enabling automated governance and validation.
| Feature | hook.define | hook.register |
|---|---|---|
| Purpose | Create hooks immediately | Register hook manifests for version control |
| Output File | .claude/hooks.yaml (live config) | /registry/hooks.json (registry) |
| Use Case | Quick development, testing | Production deployment, formal tracking |
| Versioning | Not tracked | Full version history |
| Schema Validation | Basic | Comprehensive |
python skills/hook.register/hook_register.py <path_to_hook_manifest.yaml>
| Argument | Type | Required | Description |
|---|---|---|---|
| manifest_path | string | Yes | Path to the hook manifest YAML file to validate |
validate-openapi-specs)0.1.0)pattern: File pattern to match (e.g., "*.openapi.yaml", "specs/**/*.yaml")false)30000)show_errors, silent, log_only (default: show_errors)draft or active, defaults to draft)["api", "validation", "compliance"])| Event | Triggers When | Common Use Cases |
|---|---|---|
on_file_edit | File is edited in editor | Real-time syntax validation |
on_file_save | File is saved to disk | Code generation, formatting |
on_commit | Git commit attempted | Breaking change detection, linting |
on_push | Git push attempted | Full validation suite, security scans |
on_tool_use | Any tool is used | Audit logging, usage tracking |
on_agent_start | Agent begins execution | Context injection, authorization |
on_workflow_end | Workflow completes | Cleanup, notifications, reporting |
The skill performs comprehensive validation:
name, version, description, event, and command are present0.1.0)blocking is boolean, timeout is positive numberwhen.pattern is provided, ensures it's a valid string{
"ok": true,
"status": "registered",
"errors": [],
"path": "hooks/validate-openapi.yaml",
"details": {
"valid": true,
"status": "registered",
"registry_updated": true,
"manifest": {
"name": "validate-openapi-specs",
"version": "0.1.0",
"description": "Validate OpenAPI specs against Zalando guidelines",
"event": "on_file_edit",
"command": "python skills/api.validate/api_validate.py {file_path} zalando",
"when": {
"pattern": "*.openapi.yaml"
},
"blocking": true,
"timeout": 10000,
"status": "active",
"tags": ["api", "validation", "openapi"]
}
}
}
{
"ok": false,
"status": "failed",
"errors": [
"Invalid event: 'on_file_change'. Must be one of: on_file_edit, on_file_save, on_commit, on_push, on_tool_use, on_agent_start, on_workflow_end"
],
"path": "hooks/invalid-hook.yaml",
"details": {
"valid": false,
"errors": [
"Invalid event: 'on_file_change'. Must be one of: on_file_edit, on_file_save, on_commit, on_push, on_tool_use, on_agent_start, on_workflow_end"
],
"path": "hooks/invalid-hook.yaml"
}
}
Hook Manifest (hooks/validate-openapi.yaml):
name: validate-openapi-specs
version: 0.1.0
description: "Validate OpenAPI specs against Zalando guidelines on every edit"
event: on_file_edit
command: "python skills/api.validate/api_validate.py {file_path} zalando"
when:
pattern: "*.openapi.yaml"
blocking: true
timeout: 10000
status: active
tags: [api, validation, openapi, zalando]
Registration Command:
$ python skills/hook.register/hook_register.py hooks/validate-openapi.yaml
{
"ok": true,
"status": "registered",
"errors": [],
"path": "hooks/validate-openapi.yaml",
"details": {
"valid": true,
"status": "registered",
"registry_updated": true
}
}
Hook Manifest (hooks/prevent-breaking-changes.yaml):
name: prevent-breaking-changes
version: 0.1.0
description: "Block commits that introduce breaking API changes"
event: on_commit
command: "python skills/api.compatibility/check_compatibility.py {file_path} --fail_on_breaking"
when:
pattern: "specs/**/*.yaml"
blocking: true
timeout: 30000
on_failure: show_errors
status: active
tags: [api, compatibility, breaking-changes, commit-hook]
Hook Manifest (hooks/audit-tool-usage.yaml):
name: audit-tool-usage
version: 0.1.0
description: "Log all tool usage for compliance audit trail"
event: on_tool_use
command: "python skills/audit.log/log_tool_usage.py {tool_name} {timestamp}"
blocking: false
timeout: 5000
on_failure: log_only
status: active
tags: [audit, compliance, logging]
Hooks can be registered as part of a workflow:
# workflows/setup_governance.yaml
steps:
- skill: hook.register
args:
- "hooks/validate-openapi.yaml"
required: true
- skill: hook.register
args:
- "hooks/prevent-breaking-changes.yaml"
required: true
Validate hooks in continuous integration:
# .github/workflows/validate-hooks.yml
name: Validate Hooks
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Validate all hooks
run: |
for hook in hooks/*.yaml; do
python skills/hook.register/hook_register.py "$hook" || exit 1
done
Once registered, hooks can be loaded from the registry:
import json
with open('/registry/hooks.json') as f:
registry = json.load(f)
active_hooks = [h for h in registry['hooks'] if h['status'] == 'active']
| Error | Cause | Solution |
|---|---|---|
| "Missing required fields: name" | Hook manifest missing required field | Add all required fields: name, version, description, event, command |
| "Invalid event: 'X'" | Event type not recognized | Use one of the valid events: on_file_edit, on_file_save, on_commit, on_push, on_tool_use, on_agent_start, on_workflow_end |
| "command cannot be empty" | Command field is empty or whitespace | Provide a valid command string |
| "blocking must be a boolean" | blocking field is not true/false | Use boolean value: true or false (not string) |
| "timeout must be a positive number" | timeout is zero or negative | Provide positive number in milliseconds (e.g., 30000) |
| "when.pattern must be a non-empty string" | Pattern is empty or wrong type | Provide valid glob pattern (e.g., "*.yaml") |
/registry/hooks.json – Updated with new or modified hook entryThe /registry/hooks.json file has this structure:
{
"registry_version": "1.0.0",
"generated_at": "2025-10-23T12:00:00Z",
"hooks": [
{
"name": "validate-openapi-specs",
"version": "0.1.0",
"description": "Validate OpenAPI specs against Zalando guidelines",
"event": "on_file_edit",
"command": "python skills/api.validate/api_validate.py {file_path} zalando",
"when": {
"pattern": "*.openapi.yaml"
},
"blocking": true,
"timeout": 10000,
"on_failure": "show_errors",
"status": "active",
"tags": ["api", "validation", "openapi"]
}
]
}
hooks/ directory)status: draft, test them, then promote to activeblocking: true for critical validations (it will stop operations)Active – This skill is production-ready and actively used in Betty's hook infrastructure.